toncorp-wallet-connect-sdk 0.1.4 → 0.1.5

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/dist/client.d.ts CHANGED
@@ -27,6 +27,6 @@ export declare class BaseWalletConnect {
27
27
  private registerGlobal;
28
28
  /** Sync connect result to the specific wallet instance on window (e.g. window.onedollar) */
29
29
  private syncToWalletInstance;
30
- /** Clear all related sessions from window instances and localStorage */
30
+ /** Clear all related sessions from all window instances and localStorage */
31
31
  private clearAllRelatedSessions;
32
32
  }
package/dist/index.cjs.js CHANGED
@@ -1,2 +1,2 @@
1
- "use strict";class e{constructor(e,n,t,s,i,o){this.apiUrl=e,this.sessionToken=n,this.onConfirmed=t,this.onRejected=s,this.onExpired=i,this.onError=o,this.ws=null,this.reconnectTimer=null,this.closed=!1}connect(){this.closed=!1;this.apiUrl.replace(/^http/,"ws").replace(/\/$/,"");this.sessionToken;try{this.connectSocketIO()}catch{this.onError("WebSocket connection failed")}}connectSocketIO(){const e=this.apiUrl.replace(/\/$/,"");fetch(`${e}/walletconnect/?EIO=4&transport=polling`).then(e=>e.text()).then(n=>{const t=n.replace(/^\d+/,""),s=JSON.parse(t).sid,i=`${e.replace(/^http/,"ws")}/walletconnect/?EIO=4&transport=websocket&sid=${s}`;this.ws=new WebSocket(i),this.ws.onopen=()=>{this.ws.send("2probe")},this.ws.onmessage=e=>{const n=e.data;if("3probe"!==n)if(n.startsWith("42"))try{const e=JSON.parse(n.slice(2)),[t,s]=e;this.handleEvent(t,s)}catch{}else"2"===n&&this.ws.send("3");else this.ws.send("5")},this.ws.onclose=()=>{this.closed||this.scheduleReconnect()},this.ws.onerror=()=>{this.closed||this.scheduleReconnect()}}).catch(()=>{this.closed||this.scheduleReconnect()})}handleEvent(e,n){switch(e){case"session_confirmed":this.onConfirmed(n),this.close();break;case"session_rejected":this.onRejected(),this.close();break;case"session_expired":this.onExpired(),this.close()}}scheduleReconnect(){this.closed||this.reconnectTimer||(this.reconnectTimer=setTimeout(()=>{this.reconnectTimer=null,this.connectSocketIO()},3e3))}close(){this.closed=!0,this.reconnectTimer&&(clearTimeout(this.reconnectTimer),this.reconnectTimer=null),this.ws&&(this.ws.close(),this.ws=null)}}class n{constructor(e,n,t,s,i,o){this.apiUrl=e,this.sessionToken=n,this.onConfirmed=t,this.onRejected=s,this.onExpired=i,this.onError=o,this.timer=null,this.stopped=!1}start(){this.stopped=!1,this.poll(),this.timer=setInterval(()=>this.poll(),2e3)}async poll(){if(!this.stopped)try{const e=this.apiUrl.replace(/\/$/,""),n=await fetch(`${e}/connect/status?token=${this.sessionToken}`);if(!n.ok)return;const t=await n.json();switch(t.status){case"CONFIRMED":this.onConfirmed({wallet:t.wallet,user:t.user}),this.stop();break;case"REJECTED":this.onRejected(),this.stop();break;case"EXPIRED":this.onExpired(),this.stop()}}catch{}}stop(){this.stopped=!0,this.timer&&(clearInterval(this.timer),this.timer=null)}}const t="__wc_modal__";class s{constructor(e,n){this.overlay=null,this.theme=e,this.onClose=n}showWalletPicker(e,n){const t=`\n <div class="wc-handle"></div>\n <div class="wc-header">\n <h3 class="wc-title">Connect your wallet</h3>\n <button class="wc-close" data-action="close">&#10005;</button>\n </div>\n <p class="wc-subtitle">Choose a wallet to connect to this app</p>\n <div class="wc-body">${e.length>=3?`<ul class="wc-wallet-grid">${e.map(e=>`\n <li class="wc-wallet-grid-item" data-wallet-id="${e.walletId}">\n ${e.icon?`<img class="wc-wallet-grid-icon" src="${e.icon}" alt="${e.name}" />`:`<div class="wc-wallet-grid-icon-placeholder">${e.name.charAt(0)}</div>`}\n <span class="wc-wallet-grid-name">${e.name}</span>\n </li>`).join("")}</ul>`:`<ul class="wc-wallet-list">${e.map(e=>`\n <li class="wc-wallet-item" data-wallet-id="${e.walletId}">\n ${e.icon?`<img class="wc-wallet-list-icon" src="${e.icon}" alt="${e.name}" />`:`<div class="wc-wallet-list-icon-placeholder">${e.name.charAt(0)}</div>`}\n <div class="wc-wallet-item-info">\n <div class="wc-wallet-item-name">${e.name}</div>\n ${e.description?`<div class="wc-wallet-item-desc">${e.description}</div>`:""}\n </div>\n <span class="wc-wallet-item-arrow">&#8250;</span>\n </li>`).join("")}</ul>`}</div>\n <div class="wc-footer">Powered by WalletConnect</div>\n `;this.render(t),e.forEach(e=>{this.overlay?.querySelector(`[data-wallet-id="${e.walletId}"]`)?.addEventListener("click",()=>n(e))})}showConnect(e,n,t,s){const i=function(e,n=220){return`https://api.qrserver.com/v1/create-qr-code/?size=${n}x${n}&data=${encodeURIComponent(e)}&margin=8`}(n),o=`\n <div class="wc-handle"></div>\n <div class="wc-header">\n <div class="wc-header-left">\n ${t?'<button class="wc-back" data-action="back">&#8592;</button>':""}\n ${e.icon?`<img class="wc-header-icon" src="${e.icon}" />`:""}\n <h3 class="wc-title">${e.name}</h3>\n </div>\n <button class="wc-close" data-action="close">&#10005;</button>\n </div>\n <p class="wc-subtitle">Approve the connection request in your wallet</p>\n <div class="wc-body">\n <div class="wc-tabs">\n <button class="wc-tab active" data-tab="mobile">Mobile</button>\n <button class="wc-tab" data-tab="qr">QR Code</button>\n </div>\n <div data-panel="mobile">\n <a class="wc-deeplink-btn" href="${n}" target="_blank">\n <svg width="20" height="20" viewBox="0 0 24 24" fill="currentColor"><path d="M11.944 0A12 12 0 1 0 24 12.056A12.01 12.01 0 0 0 11.944 0Zm4.962 7.224c.1-.002.321.023.465.14a.506.506 0 0 1 .171.325c.016.093.036.306.02.472c-.18 1.898-.962 6.502-1.36 8.627c-.168.9-.499 1.201-.82 1.23c-.696.065-1.225-.46-1.9-.902c-1.056-.693-1.653-1.124-2.678-1.8c-1.185-.78-.417-1.21.258-1.91c.177-.184 3.247-2.977 3.307-3.23c.007-.032.014-.15-.056-.212s-.174-.041-.249-.024c-.106.024-1.793 1.14-5.061 3.345c-.48.33-.913.49-1.302.48c-.428-.008-1.252-.241-1.865-.44c-.752-.245-1.349-.374-1.297-.789c.027-.216.325-.437.893-.663c3.498-1.524 5.83-2.529 6.998-3.014c3.332-1.386 4.025-1.627 4.476-1.635Z"/></svg>\n Open in Telegram\n </a>\n </div>\n <div data-panel="qr" style="display:none">\n <div class="wc-qr-container">\n <div class="wc-qr-wrap">\n <img src="${i}" width="220" height="220" alt="QR" />\n </div>\n <div class="wc-qr-hint">Scan with your phone camera or wallet app</div>\n </div>\n </div>\n <div class="wc-status">\n <div class="wc-spinner"></div>\n <span>Waiting for confirmation...</span>\n </div>\n </div>\n <div class="wc-footer">Powered by WalletConnect</div>\n `;this.render(o);const r=this.overlay?.querySelectorAll(".wc-tab"),a=this.overlay?.querySelectorAll("[data-panel]");r?.forEach(e=>{e.addEventListener("click",()=>{const n=e.dataset.tab;r.forEach(e=>e.classList.remove("active")),e.classList.add("active"),a?.forEach(e=>{e.style.display=e.dataset.panel===n?"block":"none"})})}),t&&s&&this.overlay?.querySelector('[data-action="back"]')?.addEventListener("click",s)}showSuccess(e,n,t,s){const i=t?.username||"User",o=i.slice(0,2).toUpperCase(),r=`\n <div class="wc-handle"></div>\n <div class="wc-header">\n <h3 class="wc-title">Connected</h3>\n <button class="wc-close" data-action="close">&#10005;</button>\n </div>\n <div class="wc-body">\n <div class="wc-success">\n <div class="wc-success-check"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg></div>\n <div class="wc-success-title">Connection Successful</div>\n <div class="wc-success-user">\n ${t?.avatar?`<img class="wc-success-avatar" src="${t.avatar}" alt="${i}" />`:`<div class="wc-success-avatar-placeholder">${o}</div>`}\n <div class="wc-success-user-info">\n <div class="wc-success-user-name">${i}</div>\n ${n?`<div class="wc-success-user-addr" title="${n}">${n}</div>`:""}\n </div>\n </div>\n <button class="wc-success-done" data-action="done">Done</button>\n </div>\n </div>\n <div class="wc-footer">Powered by WalletConnect</div>\n `;this.render(r),this.overlay?.querySelector('[data-action="done"]')?.addEventListener("click",s)}updateStatus(e,n=!0){const t=this.overlay?.querySelector(".wc-status");t&&(t.innerHTML=`\n ${n?'<div class="wc-spinner"></div>':""}\n <span>${e}</span>\n `)}render(e){this.destroy();const n=document.createElement("div");n.id=t,n.innerHTML=`\n <style>${function(e){const n="dark"===e,t=n?"#141414":"#ffffff",s=n?"#1e1e1e":"#f4f4f4",i=n?"#ffffff":"#141414",o=n?"#9a9a9a":"#787878",r=n?"#2a2a2a":"#e4e4e4",a="#2bea6a",c="#1db954";return`\n @keyframes wc-fadeIn { from{opacity:0} to{opacity:1} }\n @keyframes wc-slideUp {\n from{opacity:0;transform:translateY(100%)}\n to{opacity:1;transform:translateY(0)}\n }\n .wc-overlay {\n position:fixed; inset:0; z-index:99999;\n background:rgba(0,0,0,${n?.75:.45});\n display:flex; align-items:flex-end; justify-content:center;\n font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;\n backdrop-filter:blur(6px); -webkit-backdrop-filter:blur(6px);\n animation:wc-fadeIn .2s ease;\n }\n @media(min-width:480px){\n .wc-overlay{align-items:center}\n .wc-modal{border-radius:24px;max-height:85vh}\n }\n .wc-modal {\n background:${t}; width:100%; max-width:420px;\n border-radius:24px 24px 0 0; overflow:hidden; color:${i};\n box-shadow:0 -8px 40px rgba(0,0,0,${n?.5:.15});\n animation:wc-slideUp .3s cubic-bezier(.16,1,.3,1);\n max-height:90vh; overflow-y:auto;\n }\n\n /* Handle bar */\n .wc-handle {\n width:36px; height:4px; border-radius:2px;\n background:${r}; margin:10px auto 0;\n }\n\n /* Header */\n .wc-header {\n display:flex; align-items:center; justify-content:space-between;\n padding:20px 24px 0;\n }\n .wc-header-left {\n display:flex; align-items:center; gap:10px;\n }\n .wc-header-icon {\n width:32px; height:32px; border-radius:10px; object-fit:cover;\n }\n .wc-title { font-size:17px; font-weight:700; margin:0; }\n .wc-close {\n width:30px; height:30px; display:flex; align-items:center; justify-content:center;\n background:${s}; border:none; border-radius:50%;\n cursor:pointer; font-size:14px; color:${o};\n transition:all .15s;\n }\n .wc-close:hover { background:${r}; color:${i}; }\n .wc-subtitle {\n font-size:13px; color:${o}; margin:8px 24px 0;\n line-height:1.4;\n }\n\n .wc-body { padding:20px 24px 24px; }\n\n /* Grid wallet picker */\n .wc-wallet-grid {\n display:grid; grid-template-columns:repeat(4,1fr);\n gap:16px 12px; list-style:none; margin:0; padding:0;\n }\n .wc-wallet-grid-item {\n display:flex; flex-direction:column; align-items:center;\n gap:8px; cursor:pointer; padding:8px 4px; border-radius:16px;\n transition:all .15s; border:2px solid transparent;\n }\n .wc-wallet-grid-item:hover {\n background:${s}; border-color:${r};\n }\n .wc-wallet-grid-icon {\n width:56px; height:56px; border-radius:16px;\n object-fit:cover; box-shadow:0 2px 8px rgba(0,0,0,${n?.3:.08});\n }\n .wc-wallet-grid-icon-placeholder {\n width:56px; height:56px; border-radius:16px;\n background:linear-gradient(135deg,${c},${a});\n display:flex; align-items:center; justify-content:center;\n color:#fff; font-weight:800; font-size:22px;\n box-shadow:0 2px 8px rgba(0,0,0,${n?.3:.08});\n }\n .wc-wallet-grid-name {\n font-size:11px; font-weight:500; text-align:center;\n color:${o}; line-height:1.2;\n max-width:72px; overflow:hidden; text-overflow:ellipsis;\n white-space:nowrap;\n }\n\n /* List wallet picker (alternative) */\n .wc-wallet-list { list-style:none; margin:0; padding:0; }\n .wc-wallet-item {\n display:flex; align-items:center; gap:14px;\n padding:12px 16px; border-radius:16px; cursor:pointer;\n border:1.5px solid ${r}; margin-bottom:8px;\n transition:all .15s;\n }\n .wc-wallet-item:hover {\n background:${s}; border-color:${a};\n }\n .wc-wallet-list-icon {\n width:40px; height:40px; border-radius:12px; object-fit:cover;\n }\n .wc-wallet-list-icon-placeholder {\n width:40px; height:40px; border-radius:12px;\n background:linear-gradient(135deg,${c},${a});\n display:flex; align-items:center; justify-content:center;\n color:#fff; font-weight:700; font-size:16px;\n }\n .wc-wallet-item-info { flex:1; }\n .wc-wallet-item-name { font-size:14px; font-weight:600; }\n .wc-wallet-item-desc { font-size:11px; color:${o}; margin-top:1px; }\n .wc-wallet-item-arrow { color:${o}; font-size:16px; }\n\n /* Tabs */\n .wc-tabs {\n display:flex; background:${s}; border-radius:12px;\n padding:3px; margin-bottom:20px;\n }\n .wc-tab {\n flex:1; padding:10px; text-align:center; cursor:pointer;\n font-size:13px; font-weight:600; background:transparent;\n border:none; color:${o}; border-radius:10px;\n transition:all .2s;\n }\n .wc-tab:hover { color:${i}; }\n .wc-tab.active {\n background:${t}; color:${i};\n box-shadow:0 1px 4px rgba(0,0,0,${n?.3:.08});\n }\n\n /* Deeplink */\n .wc-deeplink-btn {\n display:flex; align-items:center; justify-content:center; gap:10px;\n width:100%; padding:16px; border:none; border-radius:16px;\n background:linear-gradient(135deg,${c},${a});\n color:#fff; font-size:15px; font-weight:700; cursor:pointer;\n text-decoration:none; transition:all .2s;\n box-shadow:0 4px 20px rgba(43,234,106,0.2);\n box-sizing:border-box;\n }\n .wc-deeplink-btn:hover {\n transform:translateY(-1px);\n box-shadow:0 6px 28px rgba(43,234,106,0.3);\n }\n\n /* QR */\n .wc-qr-container {\n display:flex; flex-direction:column; align-items:center; gap:16px;\n }\n .wc-qr-wrap {\n padding:16px; background:#fff; border-radius:20px;\n box-shadow:0 2px 16px rgba(0,0,0,${n?.2:.06});\n }\n .wc-qr-wrap img { display:block; border-radius:4px; }\n .wc-qr-hint { font-size:12px; color:${o}; text-align:center; }\n\n /* Status */\n .wc-status {\n display:flex; align-items:center; justify-content:center;\n gap:10px; padding:20px 0 4px; font-size:13px; color:${o};\n }\n .wc-spinner {\n width:16px; height:16px; border:2px solid ${r};\n border-top-color:${a}; border-radius:50%;\n animation:wc-spin .7s linear infinite;\n }\n @keyframes wc-spin { to{transform:rotate(360deg)} }\n\n /* Back */\n .wc-back {\n background:none; border:none; cursor:pointer; padding:0;\n color:${o}; display:flex; align-items:center;\n transition:color .15s; font-size:18px;\n }\n .wc-back:hover { color:${i}; }\n\n /* Footer */\n .wc-footer {\n text-align:center; padding:4px 0 20px;\n font-size:11px; color:${n?"#555":"#bbb"};\n }\n\n /* Success screen */\n .wc-success {\n display:flex; flex-direction:column; align-items:center;\n padding:12px 0 4px; gap:20px;\n }\n .wc-success-check {\n width:64px; height:64px; border-radius:50%;\n background:linear-gradient(135deg,${c},${a});\n display:flex; align-items:center; justify-content:center;\n box-shadow:0 4px 20px rgba(43,234,106,0.25);\n animation:wc-popIn .4s cubic-bezier(.16,1,.3,1);\n }\n @keyframes wc-popIn {\n from{transform:scale(0);opacity:0}\n 50%{transform:scale(1.15)}\n to{transform:scale(1);opacity:1}\n }\n .wc-success-check svg { width:32px; height:32px; color:#fff; }\n .wc-success-title {\n font-size:18px; font-weight:700; color:${i};\n }\n .wc-success-user {\n display:flex; align-items:center; gap:14px;\n background:${s}; border-radius:16px;\n padding:16px 18px; width:100%; box-sizing:border-box;\n }\n .wc-success-avatar {\n width:48px; height:48px; border-radius:50%; object-fit:cover;\n flex-shrink:0; border:2px solid ${r};\n }\n .wc-success-avatar-placeholder {\n width:48px; height:48px; border-radius:50%;\n background:linear-gradient(135deg,${c},${a});\n display:flex; align-items:center; justify-content:center;\n color:#fff; font-weight:700; font-size:18px; flex-shrink:0;\n border:2px solid ${r};\n }\n .wc-success-user-info { flex:1; min-width:0; }\n .wc-success-user-name { font-size:15px; font-weight:600; color:${i}; }\n .wc-success-user-addr {\n font-size:12px; color:${o}; margin-top:4px;\n font-family:'SF Mono',Monaco,Consolas,monospace;\n word-break:break-all; line-height:1.4;\n }\n .wc-success-done {\n width:100%; padding:14px; border:none; border-radius:14px;\n background:linear-gradient(135deg,${c},${a});\n color:#fff; font-size:14px; font-weight:700; cursor:pointer;\n transition:all .2s;\n box-shadow:0 4px 16px rgba(43,234,106,0.2);\n }\n .wc-success-done:hover {\n transform:translateY(-1px);\n box-shadow:0 6px 24px rgba(43,234,106,0.3);\n }\n `}(this.theme)}</style>\n <div class="wc-overlay">\n <div class="wc-modal">${e}</div>\n </div>\n `,document.body.appendChild(n),this.overlay=n,this.overlay.querySelector('[data-action="close"]')?.addEventListener("click",()=>{this.onClose(),this.destroy()}),this.overlay.querySelector(".wc-overlay")?.addEventListener("click",e=>{e.target.classList.contains("wc-overlay")&&(this.onClose(),this.destroy())})}destroy(){document.getElementById(t)?.remove(),this.overlay=null}}const i="__wc_session_";class o{constructor(e){this.listeners=new Map,this.modal=null,this.wsTransport=null,this.pollingTransport=null,this.currentResult=null,this.config={appId:e.appId,registryUrl:e.registryUrl||"https://cdn.jsdelivr.net/npm/toncorp-wallet-connect-sdk@latest/registry.json",walletId:e.walletId,theme:e.theme||"light"},this.restoreSession(),this.registerGlobal()}async connect(){if(this.currentResult)return this.currentResult;const e=await this.fetchWallets(),n=this.filterWallets(e);if(0===n.length)throw new Error("No supported wallets available");return new Promise((e,t)=>{this.modal=new s(this.config.theme,()=>{this.cleanup(),t(new Error("User closed modal"))}),1===n.length?this.startConnect(n[0],!1,e,t):this.modal.showWalletPicker(n,n=>{this.startConnect(n,!0,e,t)})})}disconnect(){const e=this.currentResult?.session;if(e){const n=e.apiUrl.replace(/\/$/,"");fetch(`${n}/connect/disconnect-by-token`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({sessionToken:e.sessionToken})}).catch(()=>{})}this.currentResult=null,this.removeStoredSession(),this.clearAllRelatedSessions(),this.cleanup(),this.emit("disconnect")}isConnected(){return null!==this.currentResult}getWallet(){return this.currentResult}on(e,n){this.listeners.has(e)||this.listeners.set(e,new Set),this.listeners.get(e).add(n)}off(e,n){this.listeners.get(e)?.delete(n)}get storageKey(){const e=this.config.walletId,n=Array.isArray(e)?e.sort().join("_"):e||"all";return`${i}${n}__`}async fetchWallets(){const e=this.config.registryUrl.replace(/\/$/,""),n=await fetch(e);if(!n.ok)throw new Error("Failed to fetch wallets");return n.json()}filterWallets(e){if(!this.config.walletId)return e;const n=Array.isArray(this.config.walletId)?this.config.walletId:[this.config.walletId];return e.filter(e=>n.includes(e.walletId))}async startConnect(e,n,t,s){try{const i=await this.initSession(e);this.modal?.showConnect(e,i.deeplink,n,()=>{this.cleanup(),this.connect().then(t).catch(s)}),this.listenForConfirmation(e.apiUrl,i.sessionToken,n=>{n.session={sessionToken:i.sessionToken,walletId:e.walletId,apiUrl:e.apiUrl},this.currentResult=n,this.storeSession(n),this.syncToWalletInstance(e.walletId,n),this.emit("connect",n),this.modal?.showSuccess(e,n.wallet?.address||null,n.user||null,()=>{this.modal?.destroy(),this.modal=null,t(n)})},()=>{this.modal?.updateStatus("Connection rejected",!1),setTimeout(()=>{this.modal?.destroy(),this.modal=null,s(new Error("Connection rejected by user"))},1500)},()=>{this.modal?.updateStatus("Session expired",!1),this.emit("session_expired"),setTimeout(()=>{this.modal?.destroy(),this.modal=null,s(new Error("Session expired"))},1500)})}catch(e){this.modal?.destroy(),this.modal=null,s(e instanceof Error?e:new Error(String(e)))}}async initSession(e){const n=e.apiUrl.replace(/\/$/,""),t=await fetch(`${n}/connect/init`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({appId:this.config.appId,walletId:e.walletId,origin:"undefined"!=typeof window?window.location.origin:""})});if(!t.ok)throw new Error("Failed to init session");return t.json()}listenForConfirmation(t,s,i,o,r){let a=!1;const c=e=>(...n)=>{a||(a=!0,this.wsTransport?.close(),this.pollingTransport?.stop(),e(...n))},l=c(i),d=c(o),p=c(r);this.pollingTransport=new n(t,s,l,d,p,e=>this.emit("error",e)),this.pollingTransport.start(),this.wsTransport=new e(t,s,l,d,p,()=>{}),this.wsTransport.connect()}cleanup(){this.wsTransport?.close(),this.wsTransport=null,this.pollingTransport?.stop(),this.pollingTransport=null,this.modal?.destroy(),this.modal=null}emit(e,n){this.listeners.get(e)?.forEach(e=>e(n))}storeSession(e){try{localStorage.setItem(this.storageKey,JSON.stringify(e))}catch{}}restoreSession(){try{const e=localStorage.getItem(this.storageKey);e&&(this.currentResult=JSON.parse(e))}catch{}}removeStoredSession(){try{localStorage.removeItem(this.storageKey)}catch{}}registerGlobal(){if("undefined"==typeof window)return;const e=this.config.walletId,n=Array.isArray(e)?e[0]:e||"walletconnect";window[n]=this}syncToWalletInstance(e,n){if("undefined"==typeof window)return;const t=window[e];t&&t!==this&&t instanceof o&&(t.currentResult=n,t.storeSession(n))}clearAllRelatedSessions(){if("undefined"==typeof window)return;const e=["tonpass","onedollar","walletconnect"];for(const n of e){const e=window[n];e&&e!==this&&e instanceof o&&(e.currentResult=null,e.removeStoredSession())}try{const e=[];for(let n=0;n<localStorage.length;n++){const t=localStorage.key(n);t&&t.startsWith(i)&&e.push(t)}e.forEach(e=>localStorage.removeItem(e))}catch{}}}exports.BaseWalletConnect=o,exports.OneDollarConnect=class extends o{constructor(e){super({...e,walletId:"onedollar"})}},exports.TonPassConnect=class extends o{constructor(e){super({...e,walletId:"tonpass"})}};
1
+ "use strict";class e{constructor(e,n,t,s,i,o){this.apiUrl=e,this.sessionToken=n,this.onConfirmed=t,this.onRejected=s,this.onExpired=i,this.onError=o,this.ws=null,this.reconnectTimer=null,this.closed=!1}connect(){this.closed=!1;this.apiUrl.replace(/^http/,"ws").replace(/\/$/,"");this.sessionToken;try{this.connectSocketIO()}catch{this.onError("WebSocket connection failed")}}connectSocketIO(){const e=this.apiUrl.replace(/\/$/,"");fetch(`${e}/walletconnect/?EIO=4&transport=polling`).then(e=>e.text()).then(n=>{const t=n.replace(/^\d+/,""),s=JSON.parse(t).sid,i=`${e.replace(/^http/,"ws")}/walletconnect/?EIO=4&transport=websocket&sid=${s}`;this.ws=new WebSocket(i),this.ws.onopen=()=>{this.ws.send("2probe")},this.ws.onmessage=e=>{const n=e.data;if("3probe"!==n)if(n.startsWith("42"))try{const e=JSON.parse(n.slice(2)),[t,s]=e;this.handleEvent(t,s)}catch{}else"2"===n&&this.ws.send("3");else this.ws.send("5")},this.ws.onclose=()=>{this.closed||this.scheduleReconnect()},this.ws.onerror=()=>{this.closed||this.scheduleReconnect()}}).catch(()=>{this.closed||this.scheduleReconnect()})}handleEvent(e,n){switch(e){case"session_confirmed":this.onConfirmed(n),this.close();break;case"session_rejected":this.onRejected(),this.close();break;case"session_expired":this.onExpired(),this.close()}}scheduleReconnect(){this.closed||this.reconnectTimer||(this.reconnectTimer=setTimeout(()=>{this.reconnectTimer=null,this.connectSocketIO()},3e3))}close(){this.closed=!0,this.reconnectTimer&&(clearTimeout(this.reconnectTimer),this.reconnectTimer=null),this.ws&&(this.ws.close(),this.ws=null)}}class n{constructor(e,n,t,s,i,o){this.apiUrl=e,this.sessionToken=n,this.onConfirmed=t,this.onRejected=s,this.onExpired=i,this.onError=o,this.timer=null,this.stopped=!1}start(){this.stopped=!1,this.poll(),this.timer=setInterval(()=>this.poll(),2e3)}async poll(){if(!this.stopped)try{const e=this.apiUrl.replace(/\/$/,""),n=await fetch(`${e}/connect/status?token=${this.sessionToken}`);if(!n.ok)return;const t=await n.json();switch(t.status){case"CONFIRMED":this.onConfirmed({wallet:t.wallet,user:t.user}),this.stop();break;case"REJECTED":this.onRejected(),this.stop();break;case"EXPIRED":this.onExpired(),this.stop()}}catch{}}stop(){this.stopped=!0,this.timer&&(clearInterval(this.timer),this.timer=null)}}const t="__wc_modal__";class s{constructor(e,n){this.overlay=null,this.theme=e,this.onClose=n}showWalletPicker(e,n){const t=`\n <div class="wc-handle"></div>\n <div class="wc-header">\n <h3 class="wc-title">Connect your wallet</h3>\n <button class="wc-close" data-action="close">&#10005;</button>\n </div>\n <p class="wc-subtitle">Choose a wallet to connect to this app</p>\n <div class="wc-body">${e.length>=3?`<ul class="wc-wallet-grid">${e.map(e=>`\n <li class="wc-wallet-grid-item" data-wallet-id="${e.walletId}">\n ${e.icon?`<img class="wc-wallet-grid-icon" src="${e.icon}" alt="${e.name}" />`:`<div class="wc-wallet-grid-icon-placeholder">${e.name.charAt(0)}</div>`}\n <span class="wc-wallet-grid-name">${e.name}</span>\n </li>`).join("")}</ul>`:`<ul class="wc-wallet-list">${e.map(e=>`\n <li class="wc-wallet-item" data-wallet-id="${e.walletId}">\n ${e.icon?`<img class="wc-wallet-list-icon" src="${e.icon}" alt="${e.name}" />`:`<div class="wc-wallet-list-icon-placeholder">${e.name.charAt(0)}</div>`}\n <div class="wc-wallet-item-info">\n <div class="wc-wallet-item-name">${e.name}</div>\n ${e.description?`<div class="wc-wallet-item-desc">${e.description}</div>`:""}\n </div>\n <span class="wc-wallet-item-arrow">&#8250;</span>\n </li>`).join("")}</ul>`}</div>\n <div class="wc-footer">Powered by WalletConnect</div>\n `;this.render(t),e.forEach(e=>{this.overlay?.querySelector(`[data-wallet-id="${e.walletId}"]`)?.addEventListener("click",()=>n(e))})}showConnect(e,n,t,s){const i=function(e,n=220){return`https://api.qrserver.com/v1/create-qr-code/?size=${n}x${n}&data=${encodeURIComponent(e)}&margin=8`}(n),o=`\n <div class="wc-handle"></div>\n <div class="wc-header">\n <div class="wc-header-left">\n ${t?'<button class="wc-back" data-action="back">&#8592;</button>':""}\n ${e.icon?`<img class="wc-header-icon" src="${e.icon}" />`:""}\n <h3 class="wc-title">${e.name}</h3>\n </div>\n <button class="wc-close" data-action="close">&#10005;</button>\n </div>\n <p class="wc-subtitle">Approve the connection request in your wallet</p>\n <div class="wc-body">\n <div class="wc-tabs">\n <button class="wc-tab active" data-tab="mobile">Mobile</button>\n <button class="wc-tab" data-tab="qr">QR Code</button>\n </div>\n <div data-panel="mobile">\n <a class="wc-deeplink-btn" href="${n}" target="_blank">\n <svg width="20" height="20" viewBox="0 0 24 24" fill="currentColor"><path d="M11.944 0A12 12 0 1 0 24 12.056A12.01 12.01 0 0 0 11.944 0Zm4.962 7.224c.1-.002.321.023.465.14a.506.506 0 0 1 .171.325c.016.093.036.306.02.472c-.18 1.898-.962 6.502-1.36 8.627c-.168.9-.499 1.201-.82 1.23c-.696.065-1.225-.46-1.9-.902c-1.056-.693-1.653-1.124-2.678-1.8c-1.185-.78-.417-1.21.258-1.91c.177-.184 3.247-2.977 3.307-3.23c.007-.032.014-.15-.056-.212s-.174-.041-.249-.024c-.106.024-1.793 1.14-5.061 3.345c-.48.33-.913.49-1.302.48c-.428-.008-1.252-.241-1.865-.44c-.752-.245-1.349-.374-1.297-.789c.027-.216.325-.437.893-.663c3.498-1.524 5.83-2.529 6.998-3.014c3.332-1.386 4.025-1.627 4.476-1.635Z"/></svg>\n Open in Telegram\n </a>\n </div>\n <div data-panel="qr" style="display:none">\n <div class="wc-qr-container">\n <div class="wc-qr-wrap">\n <img src="${i}" width="220" height="220" alt="QR" />\n </div>\n <div class="wc-qr-hint">Scan with your phone camera or wallet app</div>\n </div>\n </div>\n <div class="wc-status">\n <div class="wc-spinner"></div>\n <span>Waiting for confirmation...</span>\n </div>\n </div>\n <div class="wc-footer">Powered by WalletConnect</div>\n `;this.render(o);const r=this.overlay?.querySelectorAll(".wc-tab"),a=this.overlay?.querySelectorAll("[data-panel]");r?.forEach(e=>{e.addEventListener("click",()=>{const n=e.dataset.tab;r.forEach(e=>e.classList.remove("active")),e.classList.add("active"),a?.forEach(e=>{e.style.display=e.dataset.panel===n?"block":"none"})})}),t&&s&&this.overlay?.querySelector('[data-action="back"]')?.addEventListener("click",s)}showSuccess(e,n,t,s){const i=t?.username||"User",o=i.slice(0,2).toUpperCase(),r=`\n <div class="wc-handle"></div>\n <div class="wc-header">\n <h3 class="wc-title">Connected</h3>\n <button class="wc-close" data-action="close">&#10005;</button>\n </div>\n <div class="wc-body">\n <div class="wc-success">\n <div class="wc-success-check"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg></div>\n <div class="wc-success-title">Connection Successful</div>\n <div class="wc-success-user">\n ${t?.avatar?`<img class="wc-success-avatar" src="${t.avatar}" alt="${i}" />`:`<div class="wc-success-avatar-placeholder">${o}</div>`}\n <div class="wc-success-user-info">\n <div class="wc-success-user-name">${i}</div>\n ${n?`<div class="wc-success-user-addr" title="${n}">${n}</div>`:""}\n </div>\n </div>\n <button class="wc-success-done" data-action="done">Done</button>\n </div>\n </div>\n <div class="wc-footer">Powered by WalletConnect</div>\n `;this.render(r),this.overlay?.querySelector('[data-action="done"]')?.addEventListener("click",s)}updateStatus(e,n=!0){const t=this.overlay?.querySelector(".wc-status");t&&(t.innerHTML=`\n ${n?'<div class="wc-spinner"></div>':""}\n <span>${e}</span>\n `)}render(e){this.destroy();const n=document.createElement("div");n.id=t,n.innerHTML=`\n <style>${function(e){const n="dark"===e,t=n?"#141414":"#ffffff",s=n?"#1e1e1e":"#f4f4f4",i=n?"#ffffff":"#141414",o=n?"#9a9a9a":"#787878",r=n?"#2a2a2a":"#e4e4e4",a="#2bea6a",c="#1db954";return`\n @keyframes wc-fadeIn { from{opacity:0} to{opacity:1} }\n @keyframes wc-slideUp {\n from{opacity:0;transform:translateY(100%)}\n to{opacity:1;transform:translateY(0)}\n }\n .wc-overlay {\n position:fixed; inset:0; z-index:99999;\n background:rgba(0,0,0,${n?.75:.45});\n display:flex; align-items:flex-end; justify-content:center;\n font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;\n backdrop-filter:blur(6px); -webkit-backdrop-filter:blur(6px);\n animation:wc-fadeIn .2s ease;\n }\n @media(min-width:480px){\n .wc-overlay{align-items:center}\n .wc-modal{border-radius:24px;max-height:85vh}\n }\n .wc-modal {\n background:${t}; width:100%; max-width:420px;\n border-radius:24px 24px 0 0; overflow:hidden; color:${i};\n box-shadow:0 -8px 40px rgba(0,0,0,${n?.5:.15});\n animation:wc-slideUp .3s cubic-bezier(.16,1,.3,1);\n max-height:90vh; overflow-y:auto;\n }\n\n /* Handle bar */\n .wc-handle {\n width:36px; height:4px; border-radius:2px;\n background:${r}; margin:10px auto 0;\n }\n\n /* Header */\n .wc-header {\n display:flex; align-items:center; justify-content:space-between;\n padding:20px 24px 0;\n }\n .wc-header-left {\n display:flex; align-items:center; gap:10px;\n }\n .wc-header-icon {\n width:32px; height:32px; border-radius:10px; object-fit:cover;\n }\n .wc-title { font-size:17px; font-weight:700; margin:0; }\n .wc-close {\n width:30px; height:30px; display:flex; align-items:center; justify-content:center;\n background:${s}; border:none; border-radius:50%;\n cursor:pointer; font-size:14px; color:${o};\n transition:all .15s;\n }\n .wc-close:hover { background:${r}; color:${i}; }\n .wc-subtitle {\n font-size:13px; color:${o}; margin:8px 24px 0;\n line-height:1.4;\n }\n\n .wc-body { padding:20px 24px 24px; }\n\n /* Grid wallet picker */\n .wc-wallet-grid {\n display:grid; grid-template-columns:repeat(4,1fr);\n gap:16px 12px; list-style:none; margin:0; padding:0;\n }\n .wc-wallet-grid-item {\n display:flex; flex-direction:column; align-items:center;\n gap:8px; cursor:pointer; padding:8px 4px; border-radius:16px;\n transition:all .15s; border:2px solid transparent;\n }\n .wc-wallet-grid-item:hover {\n background:${s}; border-color:${r};\n }\n .wc-wallet-grid-icon {\n width:56px; height:56px; border-radius:16px;\n object-fit:cover; box-shadow:0 2px 8px rgba(0,0,0,${n?.3:.08});\n }\n .wc-wallet-grid-icon-placeholder {\n width:56px; height:56px; border-radius:16px;\n background:linear-gradient(135deg,${c},${a});\n display:flex; align-items:center; justify-content:center;\n color:#fff; font-weight:800; font-size:22px;\n box-shadow:0 2px 8px rgba(0,0,0,${n?.3:.08});\n }\n .wc-wallet-grid-name {\n font-size:11px; font-weight:500; text-align:center;\n color:${o}; line-height:1.2;\n max-width:72px; overflow:hidden; text-overflow:ellipsis;\n white-space:nowrap;\n }\n\n /* List wallet picker (alternative) */\n .wc-wallet-list { list-style:none; margin:0; padding:0; }\n .wc-wallet-item {\n display:flex; align-items:center; gap:14px;\n padding:12px 16px; border-radius:16px; cursor:pointer;\n border:1.5px solid ${r}; margin-bottom:8px;\n transition:all .15s;\n }\n .wc-wallet-item:hover {\n background:${s}; border-color:${a};\n }\n .wc-wallet-list-icon {\n width:40px; height:40px; border-radius:12px; object-fit:cover;\n }\n .wc-wallet-list-icon-placeholder {\n width:40px; height:40px; border-radius:12px;\n background:linear-gradient(135deg,${c},${a});\n display:flex; align-items:center; justify-content:center;\n color:#fff; font-weight:700; font-size:16px;\n }\n .wc-wallet-item-info { flex:1; }\n .wc-wallet-item-name { font-size:14px; font-weight:600; }\n .wc-wallet-item-desc { font-size:11px; color:${o}; margin-top:1px; }\n .wc-wallet-item-arrow { color:${o}; font-size:16px; }\n\n /* Tabs */\n .wc-tabs {\n display:flex; background:${s}; border-radius:12px;\n padding:3px; margin-bottom:20px;\n }\n .wc-tab {\n flex:1; padding:10px; text-align:center; cursor:pointer;\n font-size:13px; font-weight:600; background:transparent;\n border:none; color:${o}; border-radius:10px;\n transition:all .2s;\n }\n .wc-tab:hover { color:${i}; }\n .wc-tab.active {\n background:${t}; color:${i};\n box-shadow:0 1px 4px rgba(0,0,0,${n?.3:.08});\n }\n\n /* Deeplink */\n .wc-deeplink-btn {\n display:flex; align-items:center; justify-content:center; gap:10px;\n width:100%; padding:16px; border:none; border-radius:16px;\n background:linear-gradient(135deg,${c},${a});\n color:#fff; font-size:15px; font-weight:700; cursor:pointer;\n text-decoration:none; transition:all .2s;\n box-shadow:0 4px 20px rgba(43,234,106,0.2);\n box-sizing:border-box;\n }\n .wc-deeplink-btn:hover {\n transform:translateY(-1px);\n box-shadow:0 6px 28px rgba(43,234,106,0.3);\n }\n\n /* QR */\n .wc-qr-container {\n display:flex; flex-direction:column; align-items:center; gap:16px;\n }\n .wc-qr-wrap {\n padding:16px; background:#fff; border-radius:20px;\n box-shadow:0 2px 16px rgba(0,0,0,${n?.2:.06});\n }\n .wc-qr-wrap img { display:block; border-radius:4px; }\n .wc-qr-hint { font-size:12px; color:${o}; text-align:center; }\n\n /* Status */\n .wc-status {\n display:flex; align-items:center; justify-content:center;\n gap:10px; padding:20px 0 4px; font-size:13px; color:${o};\n }\n .wc-spinner {\n width:16px; height:16px; border:2px solid ${r};\n border-top-color:${a}; border-radius:50%;\n animation:wc-spin .7s linear infinite;\n }\n @keyframes wc-spin { to{transform:rotate(360deg)} }\n\n /* Back */\n .wc-back {\n background:none; border:none; cursor:pointer; padding:0;\n color:${o}; display:flex; align-items:center;\n transition:color .15s; font-size:18px;\n }\n .wc-back:hover { color:${i}; }\n\n /* Footer */\n .wc-footer {\n text-align:center; padding:4px 0 20px;\n font-size:11px; color:${n?"#555":"#bbb"};\n }\n\n /* Success screen */\n .wc-success {\n display:flex; flex-direction:column; align-items:center;\n padding:12px 0 4px; gap:20px;\n }\n .wc-success-check {\n width:64px; height:64px; border-radius:50%;\n background:linear-gradient(135deg,${c},${a});\n display:flex; align-items:center; justify-content:center;\n box-shadow:0 4px 20px rgba(43,234,106,0.25);\n animation:wc-popIn .4s cubic-bezier(.16,1,.3,1);\n }\n @keyframes wc-popIn {\n from{transform:scale(0);opacity:0}\n 50%{transform:scale(1.15)}\n to{transform:scale(1);opacity:1}\n }\n .wc-success-check svg { width:32px; height:32px; color:#fff; }\n .wc-success-title {\n font-size:18px; font-weight:700; color:${i};\n }\n .wc-success-user {\n display:flex; align-items:center; gap:14px;\n background:${s}; border-radius:16px;\n padding:16px 18px; width:100%; box-sizing:border-box;\n }\n .wc-success-avatar {\n width:48px; height:48px; border-radius:50%; object-fit:cover;\n flex-shrink:0; border:2px solid ${r};\n }\n .wc-success-avatar-placeholder {\n width:48px; height:48px; border-radius:50%;\n background:linear-gradient(135deg,${c},${a});\n display:flex; align-items:center; justify-content:center;\n color:#fff; font-weight:700; font-size:18px; flex-shrink:0;\n border:2px solid ${r};\n }\n .wc-success-user-info { flex:1; min-width:0; }\n .wc-success-user-name { font-size:15px; font-weight:600; color:${i}; }\n .wc-success-user-addr {\n font-size:12px; color:${o}; margin-top:4px;\n font-family:'SF Mono',Monaco,Consolas,monospace;\n word-break:break-all; line-height:1.4;\n }\n .wc-success-done {\n width:100%; padding:14px; border:none; border-radius:14px;\n background:linear-gradient(135deg,${c},${a});\n color:#fff; font-size:14px; font-weight:700; cursor:pointer;\n transition:all .2s;\n box-shadow:0 4px 16px rgba(43,234,106,0.2);\n }\n .wc-success-done:hover {\n transform:translateY(-1px);\n box-shadow:0 6px 24px rgba(43,234,106,0.3);\n }\n `}(this.theme)}</style>\n <div class="wc-overlay">\n <div class="wc-modal">${e}</div>\n </div>\n `,document.body.appendChild(n),this.overlay=n,this.overlay.querySelector('[data-action="close"]')?.addEventListener("click",()=>{this.onClose(),this.destroy()}),this.overlay.querySelector(".wc-overlay")?.addEventListener("click",e=>{e.target.classList.contains("wc-overlay")&&(this.onClose(),this.destroy())})}destroy(){document.getElementById(t)?.remove(),this.overlay=null}}const i="__wc_session_";class o{constructor(e){this.listeners=new Map,this.modal=null,this.wsTransport=null,this.pollingTransport=null,this.currentResult=null,this.config={appId:e.appId,registryUrl:e.registryUrl||"https://cdn.jsdelivr.net/npm/toncorp-wallet-connect-sdk@latest/registry.json",walletId:e.walletId,theme:e.theme||"light"},this.restoreSession(),this.registerGlobal()}async connect(){if(this.currentResult)return this.currentResult;const e=await this.fetchWallets(),n=this.filterWallets(e);if(0===n.length)throw new Error("No supported wallets available");return new Promise((e,t)=>{this.modal=new s(this.config.theme,()=>{this.cleanup(),t(new Error("User closed modal"))}),1===n.length?this.startConnect(n[0],!1,e,t):this.modal.showWalletPicker(n,n=>{this.startConnect(n,!0,e,t)})})}disconnect(){let e=this.currentResult?.session;if(!e&&"undefined"!=typeof window)for(const n of Object.keys(window)){const t=window[n];if(t instanceof o&&t.currentResult?.session){e=t.currentResult.session;break}}if(e){const n=e.apiUrl.replace(/\/$/,"");fetch(`${n}/connect/disconnect-by-token`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({sessionToken:e.sessionToken})}).catch(()=>{})}this.currentResult=null,this.removeStoredSession(),this.clearAllRelatedSessions(),this.cleanup(),this.emit("disconnect")}isConnected(){return null!==this.currentResult}getWallet(){return this.currentResult}on(e,n){this.listeners.has(e)||this.listeners.set(e,new Set),this.listeners.get(e).add(n)}off(e,n){this.listeners.get(e)?.delete(n)}get storageKey(){const e=this.config.walletId,n=Array.isArray(e)?e.sort().join("_"):e||"all";return`${i}${n}__`}async fetchWallets(){const e=this.config.registryUrl.replace(/\/$/,""),n=await fetch(e);if(!n.ok)throw new Error("Failed to fetch wallets");return n.json()}filterWallets(e){if(!this.config.walletId)return e;const n=Array.isArray(this.config.walletId)?this.config.walletId:[this.config.walletId];return e.filter(e=>n.includes(e.walletId))}async startConnect(e,n,t,s){try{const i=await this.initSession(e);this.modal?.showConnect(e,i.deeplink,n,()=>{this.cleanup(),this.connect().then(t).catch(s)}),this.listenForConfirmation(e.apiUrl,i.sessionToken,n=>{n.session={sessionToken:i.sessionToken,walletId:e.walletId,apiUrl:e.apiUrl},this.currentResult=n,this.storeSession(n),this.syncToWalletInstance(e.walletId,n),this.emit("connect",n),this.modal?.showSuccess(e,n.wallet?.address||null,n.user||null,()=>{this.modal?.destroy(),this.modal=null,t(n)})},()=>{this.modal?.updateStatus("Connection rejected",!1),setTimeout(()=>{this.modal?.destroy(),this.modal=null,s(new Error("Connection rejected by user"))},1500)},()=>{this.modal?.updateStatus("Session expired",!1),this.emit("session_expired"),setTimeout(()=>{this.modal?.destroy(),this.modal=null,s(new Error("Session expired"))},1500)})}catch(e){this.modal?.destroy(),this.modal=null,s(e instanceof Error?e:new Error(String(e)))}}async initSession(e){const n=e.apiUrl.replace(/\/$/,""),t=await fetch(`${n}/connect/init`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({appId:this.config.appId,walletId:e.walletId,origin:"undefined"!=typeof window?window.location.origin:""})});if(!t.ok)throw new Error("Failed to init session");return t.json()}listenForConfirmation(t,s,i,o,r){let a=!1;const c=e=>(...n)=>{a||(a=!0,this.wsTransport?.close(),this.pollingTransport?.stop(),e(...n))},l=c(i),d=c(o),p=c(r);this.pollingTransport=new n(t,s,l,d,p,e=>this.emit("error",e)),this.pollingTransport.start(),this.wsTransport=new e(t,s,l,d,p,()=>{}),this.wsTransport.connect()}cleanup(){this.wsTransport?.close(),this.wsTransport=null,this.pollingTransport?.stop(),this.pollingTransport=null,this.modal?.destroy(),this.modal=null}emit(e,n){this.listeners.get(e)?.forEach(e=>e(n))}storeSession(e){try{localStorage.setItem(this.storageKey,JSON.stringify(e))}catch{}}restoreSession(){try{const e=localStorage.getItem(this.storageKey);e&&(this.currentResult=JSON.parse(e))}catch{}}removeStoredSession(){try{localStorage.removeItem(this.storageKey)}catch{}}registerGlobal(){if("undefined"==typeof window)return;const e=this.config.walletId,n=Array.isArray(e)?e[0]:e||"walletconnect";window[n]=this}syncToWalletInstance(e,n){if("undefined"==typeof window)return;const t=window[e];t&&t!==this&&t instanceof o&&(t.currentResult=n,t.storeSession(n))}clearAllRelatedSessions(){if("undefined"!=typeof window){try{for(const e of Object.keys(window)){const n=window[e];n&&n!==this&&n instanceof o&&(n.currentResult=null,n.removeStoredSession())}}catch{}try{const e=[];for(let n=0;n<localStorage.length;n++){const t=localStorage.key(n);t&&t.startsWith(i)&&e.push(t)}e.forEach(e=>localStorage.removeItem(e))}catch{}}}}exports.BaseWalletConnect=o,exports.OneDollarConnect=class extends o{constructor(e){super({...e,walletId:"onedollar"})}},exports.TonPassConnect=class extends o{constructor(e){super({...e,walletId:"tonpass"})}};
2
2
  //# sourceMappingURL=index.cjs.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs.js","sources":["../../transport.ts","../../modal.ts","../../client.ts","../../onedollar.ts","../../tonpass.ts"],"sourcesContent":["import type { ConnectResult } from './types';\n\ntype TransportCallback = (data: ConnectResult) => void;\ntype TransportErrorCallback = (error: string) => void;\n\n// ── WebSocket Transport ──\n\nexport class WsTransport {\n private ws: WebSocket | null = null;\n private reconnectTimer: ReturnType<typeof setTimeout> | null = null;\n private closed = false;\n\n constructor(\n private apiUrl: string,\n private sessionToken: string,\n private onConfirmed: TransportCallback,\n private onRejected: () => void,\n private onExpired: () => void,\n private onError: TransportErrorCallback,\n ) {}\n\n connect(): void {\n this.closed = false;\n const wsUrl = this.apiUrl\n .replace(/^http/, 'ws')\n .replace(/\\/$/, '');\n const url = `${wsUrl}/walletconnect?sessionToken=${this.sessionToken}`;\n\n try {\n // Socket.IO uses polling upgrade — use native WS for simplicity in SDK\n // The BE gateway uses socket.io, so we connect via socket.io protocol\n this.connectSocketIO();\n } catch {\n this.onError('WebSocket connection failed');\n }\n }\n\n private connectSocketIO(): void {\n const baseUrl = this.apiUrl.replace(/\\/$/, '');\n\n // Socket.IO handshake: first GET for sid, then upgrade to WS\n const pollingUrl = `${baseUrl}/walletconnect/?EIO=4&transport=polling`;\n\n fetch(pollingUrl)\n .then((res) => res.text())\n .then((body) => {\n // Socket.IO response format: \"0{...json...}\"\n const jsonStr = body.replace(/^\\d+/, '');\n const handshake = JSON.parse(jsonStr);\n const sid = handshake.sid;\n\n const wsBase = baseUrl.replace(/^http/, 'ws');\n const wsUrl = `${wsBase}/walletconnect/?EIO=4&transport=websocket&sid=${sid}`;\n\n this.ws = new WebSocket(wsUrl);\n\n this.ws.onopen = () => {\n // Socket.IO upgrade probe\n this.ws!.send('2probe');\n };\n\n this.ws.onmessage = (event) => {\n const msg = event.data as string;\n\n if (msg === '3probe') {\n // Upgrade confirmed, send upgrade packet + join room\n this.ws!.send('5');\n // Emit connect event with sessionToken as query (already in URL)\n // Socket.IO auto-joins based on handshake query\n return;\n }\n\n // Handle Socket.IO event messages: 42[\"event_name\", {...data}]\n if (msg.startsWith('42')) {\n try {\n const payload = JSON.parse(msg.slice(2));\n const [eventName, data] = payload;\n this.handleEvent(eventName, data);\n } catch {\n // ignore malformed\n }\n return;\n }\n\n // Ping from server\n if (msg === '2') {\n this.ws!.send('3');\n }\n };\n\n this.ws.onclose = () => {\n if (!this.closed) {\n this.scheduleReconnect();\n }\n };\n\n this.ws.onerror = () => {\n if (!this.closed) {\n this.scheduleReconnect();\n }\n };\n })\n .catch(() => {\n if (!this.closed) {\n this.scheduleReconnect();\n }\n });\n }\n\n private handleEvent(eventName: string, data: any): void {\n switch (eventName) {\n case 'session_confirmed':\n this.onConfirmed(data);\n this.close();\n break;\n case 'session_rejected':\n this.onRejected();\n this.close();\n break;\n case 'session_expired':\n this.onExpired();\n this.close();\n break;\n }\n }\n\n private scheduleReconnect(): void {\n if (this.closed || this.reconnectTimer) return;\n this.reconnectTimer = setTimeout(() => {\n this.reconnectTimer = null;\n this.connectSocketIO();\n }, 3000);\n }\n\n close(): void {\n this.closed = true;\n if (this.reconnectTimer) {\n clearTimeout(this.reconnectTimer);\n this.reconnectTimer = null;\n }\n if (this.ws) {\n this.ws.close();\n this.ws = null;\n }\n }\n}\n\n// ── Long-Poll Fallback ──\n\nexport class PollingTransport {\n private timer: ReturnType<typeof setInterval> | null = null;\n private stopped = false;\n\n constructor(\n private apiUrl: string,\n private sessionToken: string,\n private onConfirmed: TransportCallback,\n private onRejected: () => void,\n private onExpired: () => void,\n private onError: TransportErrorCallback,\n ) {}\n\n start(): void {\n this.stopped = false;\n this.poll();\n this.timer = setInterval(() => this.poll(), 2000);\n }\n\n private async poll(): Promise<void> {\n if (this.stopped) return;\n\n try {\n const baseUrl = this.apiUrl.replace(/\\/$/, '');\n const res = await fetch(\n `${baseUrl}/connect/status?token=${this.sessionToken}`,\n );\n if (!res.ok) return;\n\n const data = await res.json();\n\n switch (data.status) {\n case 'CONFIRMED':\n this.onConfirmed({ wallet: data.wallet, user: data.user });\n this.stop();\n break;\n case 'REJECTED':\n this.onRejected();\n this.stop();\n break;\n case 'EXPIRED':\n this.onExpired();\n this.stop();\n break;\n }\n } catch {\n // silently retry next interval\n }\n }\n\n stop(): void {\n this.stopped = true;\n if (this.timer) {\n clearInterval(this.timer);\n this.timer = null;\n }\n }\n}\n","import type { WalletMeta } from './types';\n\nconst MODAL_ID = '__wc_modal__';\n\nfunction getStyles(theme: 'light' | 'dark'): string {\n const isDark = theme === 'dark';\n const bg = isDark ? '#141414' : '#ffffff';\n const bgSecondary = isDark ? '#1e1e1e' : '#f4f4f4';\n const text = isDark ? '#ffffff' : '#141414';\n const textSecondary = isDark ? '#9a9a9a' : '#787878';\n const border = isDark ? '#2a2a2a' : '#e4e4e4';\n const accent = '#2bea6a';\n const accentDark = '#1db954';\n\n return `\n @keyframes wc-fadeIn { from{opacity:0} to{opacity:1} }\n @keyframes wc-slideUp {\n from{opacity:0;transform:translateY(100%)}\n to{opacity:1;transform:translateY(0)}\n }\n .wc-overlay {\n position:fixed; inset:0; z-index:99999;\n background:rgba(0,0,0,${isDark ? 0.75 : 0.45});\n display:flex; align-items:flex-end; justify-content:center;\n font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;\n backdrop-filter:blur(6px); -webkit-backdrop-filter:blur(6px);\n animation:wc-fadeIn .2s ease;\n }\n @media(min-width:480px){\n .wc-overlay{align-items:center}\n .wc-modal{border-radius:24px;max-height:85vh}\n }\n .wc-modal {\n background:${bg}; width:100%; max-width:420px;\n border-radius:24px 24px 0 0; overflow:hidden; color:${text};\n box-shadow:0 -8px 40px rgba(0,0,0,${isDark ? 0.5 : 0.15});\n animation:wc-slideUp .3s cubic-bezier(.16,1,.3,1);\n max-height:90vh; overflow-y:auto;\n }\n\n /* Handle bar */\n .wc-handle {\n width:36px; height:4px; border-radius:2px;\n background:${border}; margin:10px auto 0;\n }\n\n /* Header */\n .wc-header {\n display:flex; align-items:center; justify-content:space-between;\n padding:20px 24px 0;\n }\n .wc-header-left {\n display:flex; align-items:center; gap:10px;\n }\n .wc-header-icon {\n width:32px; height:32px; border-radius:10px; object-fit:cover;\n }\n .wc-title { font-size:17px; font-weight:700; margin:0; }\n .wc-close {\n width:30px; height:30px; display:flex; align-items:center; justify-content:center;\n background:${bgSecondary}; border:none; border-radius:50%;\n cursor:pointer; font-size:14px; color:${textSecondary};\n transition:all .15s;\n }\n .wc-close:hover { background:${border}; color:${text}; }\n .wc-subtitle {\n font-size:13px; color:${textSecondary}; margin:8px 24px 0;\n line-height:1.4;\n }\n\n .wc-body { padding:20px 24px 24px; }\n\n /* Grid wallet picker */\n .wc-wallet-grid {\n display:grid; grid-template-columns:repeat(4,1fr);\n gap:16px 12px; list-style:none; margin:0; padding:0;\n }\n .wc-wallet-grid-item {\n display:flex; flex-direction:column; align-items:center;\n gap:8px; cursor:pointer; padding:8px 4px; border-radius:16px;\n transition:all .15s; border:2px solid transparent;\n }\n .wc-wallet-grid-item:hover {\n background:${bgSecondary}; border-color:${border};\n }\n .wc-wallet-grid-icon {\n width:56px; height:56px; border-radius:16px;\n object-fit:cover; box-shadow:0 2px 8px rgba(0,0,0,${isDark ? 0.3 : 0.08});\n }\n .wc-wallet-grid-icon-placeholder {\n width:56px; height:56px; border-radius:16px;\n background:linear-gradient(135deg,${accentDark},${accent});\n display:flex; align-items:center; justify-content:center;\n color:#fff; font-weight:800; font-size:22px;\n box-shadow:0 2px 8px rgba(0,0,0,${isDark ? 0.3 : 0.08});\n }\n .wc-wallet-grid-name {\n font-size:11px; font-weight:500; text-align:center;\n color:${textSecondary}; line-height:1.2;\n max-width:72px; overflow:hidden; text-overflow:ellipsis;\n white-space:nowrap;\n }\n\n /* List wallet picker (alternative) */\n .wc-wallet-list { list-style:none; margin:0; padding:0; }\n .wc-wallet-item {\n display:flex; align-items:center; gap:14px;\n padding:12px 16px; border-radius:16px; cursor:pointer;\n border:1.5px solid ${border}; margin-bottom:8px;\n transition:all .15s;\n }\n .wc-wallet-item:hover {\n background:${bgSecondary}; border-color:${accent};\n }\n .wc-wallet-list-icon {\n width:40px; height:40px; border-radius:12px; object-fit:cover;\n }\n .wc-wallet-list-icon-placeholder {\n width:40px; height:40px; border-radius:12px;\n background:linear-gradient(135deg,${accentDark},${accent});\n display:flex; align-items:center; justify-content:center;\n color:#fff; font-weight:700; font-size:16px;\n }\n .wc-wallet-item-info { flex:1; }\n .wc-wallet-item-name { font-size:14px; font-weight:600; }\n .wc-wallet-item-desc { font-size:11px; color:${textSecondary}; margin-top:1px; }\n .wc-wallet-item-arrow { color:${textSecondary}; font-size:16px; }\n\n /* Tabs */\n .wc-tabs {\n display:flex; background:${bgSecondary}; border-radius:12px;\n padding:3px; margin-bottom:20px;\n }\n .wc-tab {\n flex:1; padding:10px; text-align:center; cursor:pointer;\n font-size:13px; font-weight:600; background:transparent;\n border:none; color:${textSecondary}; border-radius:10px;\n transition:all .2s;\n }\n .wc-tab:hover { color:${text}; }\n .wc-tab.active {\n background:${bg}; color:${text};\n box-shadow:0 1px 4px rgba(0,0,0,${isDark ? 0.3 : 0.08});\n }\n\n /* Deeplink */\n .wc-deeplink-btn {\n display:flex; align-items:center; justify-content:center; gap:10px;\n width:100%; padding:16px; border:none; border-radius:16px;\n background:linear-gradient(135deg,${accentDark},${accent});\n color:#fff; font-size:15px; font-weight:700; cursor:pointer;\n text-decoration:none; transition:all .2s;\n box-shadow:0 4px 20px rgba(43,234,106,0.2);\n box-sizing:border-box;\n }\n .wc-deeplink-btn:hover {\n transform:translateY(-1px);\n box-shadow:0 6px 28px rgba(43,234,106,0.3);\n }\n\n /* QR */\n .wc-qr-container {\n display:flex; flex-direction:column; align-items:center; gap:16px;\n }\n .wc-qr-wrap {\n padding:16px; background:#fff; border-radius:20px;\n box-shadow:0 2px 16px rgba(0,0,0,${isDark ? 0.2 : 0.06});\n }\n .wc-qr-wrap img { display:block; border-radius:4px; }\n .wc-qr-hint { font-size:12px; color:${textSecondary}; text-align:center; }\n\n /* Status */\n .wc-status {\n display:flex; align-items:center; justify-content:center;\n gap:10px; padding:20px 0 4px; font-size:13px; color:${textSecondary};\n }\n .wc-spinner {\n width:16px; height:16px; border:2px solid ${border};\n border-top-color:${accent}; border-radius:50%;\n animation:wc-spin .7s linear infinite;\n }\n @keyframes wc-spin { to{transform:rotate(360deg)} }\n\n /* Back */\n .wc-back {\n background:none; border:none; cursor:pointer; padding:0;\n color:${textSecondary}; display:flex; align-items:center;\n transition:color .15s; font-size:18px;\n }\n .wc-back:hover { color:${text}; }\n\n /* Footer */\n .wc-footer {\n text-align:center; padding:4px 0 20px;\n font-size:11px; color:${isDark ? '#555' : '#bbb'};\n }\n\n /* Success screen */\n .wc-success {\n display:flex; flex-direction:column; align-items:center;\n padding:12px 0 4px; gap:20px;\n }\n .wc-success-check {\n width:64px; height:64px; border-radius:50%;\n background:linear-gradient(135deg,${accentDark},${accent});\n display:flex; align-items:center; justify-content:center;\n box-shadow:0 4px 20px rgba(43,234,106,0.25);\n animation:wc-popIn .4s cubic-bezier(.16,1,.3,1);\n }\n @keyframes wc-popIn {\n from{transform:scale(0);opacity:0}\n 50%{transform:scale(1.15)}\n to{transform:scale(1);opacity:1}\n }\n .wc-success-check svg { width:32px; height:32px; color:#fff; }\n .wc-success-title {\n font-size:18px; font-weight:700; color:${text};\n }\n .wc-success-user {\n display:flex; align-items:center; gap:14px;\n background:${bgSecondary}; border-radius:16px;\n padding:16px 18px; width:100%; box-sizing:border-box;\n }\n .wc-success-avatar {\n width:48px; height:48px; border-radius:50%; object-fit:cover;\n flex-shrink:0; border:2px solid ${border};\n }\n .wc-success-avatar-placeholder {\n width:48px; height:48px; border-radius:50%;\n background:linear-gradient(135deg,${accentDark},${accent});\n display:flex; align-items:center; justify-content:center;\n color:#fff; font-weight:700; font-size:18px; flex-shrink:0;\n border:2px solid ${border};\n }\n .wc-success-user-info { flex:1; min-width:0; }\n .wc-success-user-name { font-size:15px; font-weight:600; color:${text}; }\n .wc-success-user-addr {\n font-size:12px; color:${textSecondary}; margin-top:4px;\n font-family:'SF Mono',Monaco,Consolas,monospace;\n word-break:break-all; line-height:1.4;\n }\n .wc-success-done {\n width:100%; padding:14px; border:none; border-radius:14px;\n background:linear-gradient(135deg,${accentDark},${accent});\n color:#fff; font-size:14px; font-weight:700; cursor:pointer;\n transition:all .2s;\n box-shadow:0 4px 16px rgba(43,234,106,0.2);\n }\n .wc-success-done:hover {\n transform:translateY(-1px);\n box-shadow:0 6px 24px rgba(43,234,106,0.3);\n }\n `;\n}\n\nconst TELEGRAM_SVG = `<svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M11.944 0A12 12 0 1 0 24 12.056A12.01 12.01 0 0 0 11.944 0Zm4.962 7.224c.1-.002.321.023.465.14a.506.506 0 0 1 .171.325c.016.093.036.306.02.472c-.18 1.898-.962 6.502-1.36 8.627c-.168.9-.499 1.201-.82 1.23c-.696.065-1.225-.46-1.9-.902c-1.056-.693-1.653-1.124-2.678-1.8c-1.185-.78-.417-1.21.258-1.91c.177-.184 3.247-2.977 3.307-3.23c.007-.032.014-.15-.056-.212s-.174-.041-.249-.024c-.106.024-1.793 1.14-5.061 3.345c-.48.33-.913.49-1.302.48c-.428-.008-1.252-.241-1.865-.44c-.752-.245-1.349-.374-1.297-.789c.027-.216.325-.437.893-.663c3.498-1.524 5.83-2.529 6.998-3.014c3.332-1.386 4.025-1.627 4.476-1.635Z\"/></svg>`;\n\nfunction generateQRDataUrl(text: string, size = 220): string {\n return `https://api.qrserver.com/v1/create-qr-code/?size=${size}x${size}&data=${encodeURIComponent(text)}&margin=8`;\n}\n\nexport class Modal {\n private overlay: HTMLDivElement | null = null;\n private theme: 'light' | 'dark';\n private onClose: () => void;\n\n constructor(theme: 'light' | 'dark', onClose: () => void) {\n this.theme = theme;\n this.onClose = onClose;\n }\n\n showWalletPicker(\n wallets: WalletMeta[],\n onSelect: (wallet: WalletMeta) => void,\n ): void {\n const useGrid = wallets.length >= 3;\n\n const listHtml = useGrid\n ? `<ul class=\"wc-wallet-grid\">${wallets\n .map(\n (w) => `\n <li class=\"wc-wallet-grid-item\" data-wallet-id=\"${w.walletId}\">\n ${\n w.icon\n ? `<img class=\"wc-wallet-grid-icon\" src=\"${w.icon}\" alt=\"${w.name}\" />`\n : `<div class=\"wc-wallet-grid-icon-placeholder\">${w.name.charAt(0)}</div>`\n }\n <span class=\"wc-wallet-grid-name\">${w.name}</span>\n </li>`,\n )\n .join('')}</ul>`\n : `<ul class=\"wc-wallet-list\">${wallets\n .map(\n (w) => `\n <li class=\"wc-wallet-item\" data-wallet-id=\"${w.walletId}\">\n ${\n w.icon\n ? `<img class=\"wc-wallet-list-icon\" src=\"${w.icon}\" alt=\"${w.name}\" />`\n : `<div class=\"wc-wallet-list-icon-placeholder\">${w.name.charAt(0)}</div>`\n }\n <div class=\"wc-wallet-item-info\">\n <div class=\"wc-wallet-item-name\">${w.name}</div>\n ${w.description ? `<div class=\"wc-wallet-item-desc\">${w.description}</div>` : ''}\n </div>\n <span class=\"wc-wallet-item-arrow\">&#8250;</span>\n </li>`,\n )\n .join('')}</ul>`;\n\n const html = `\n <div class=\"wc-handle\"></div>\n <div class=\"wc-header\">\n <h3 class=\"wc-title\">Connect your wallet</h3>\n <button class=\"wc-close\" data-action=\"close\">&#10005;</button>\n </div>\n <p class=\"wc-subtitle\">Choose a wallet to connect to this app</p>\n <div class=\"wc-body\">${listHtml}</div>\n <div class=\"wc-footer\">Powered by WalletConnect</div>\n `;\n\n this.render(html);\n\n wallets.forEach((w) => {\n this.overlay\n ?.querySelector(`[data-wallet-id=\"${w.walletId}\"]`)\n ?.addEventListener('click', () => onSelect(w));\n });\n }\n\n showConnect(\n wallet: WalletMeta,\n deeplink: string,\n showBack: boolean,\n onBack?: () => void,\n ): void {\n const qrUrl = generateQRDataUrl(deeplink);\n\n const html = `\n <div class=\"wc-handle\"></div>\n <div class=\"wc-header\">\n <div class=\"wc-header-left\">\n ${showBack ? '<button class=\"wc-back\" data-action=\"back\">&#8592;</button>' : ''}\n ${wallet.icon ? `<img class=\"wc-header-icon\" src=\"${wallet.icon}\" />` : ''}\n <h3 class=\"wc-title\">${wallet.name}</h3>\n </div>\n <button class=\"wc-close\" data-action=\"close\">&#10005;</button>\n </div>\n <p class=\"wc-subtitle\">Approve the connection request in your wallet</p>\n <div class=\"wc-body\">\n <div class=\"wc-tabs\">\n <button class=\"wc-tab active\" data-tab=\"mobile\">Mobile</button>\n <button class=\"wc-tab\" data-tab=\"qr\">QR Code</button>\n </div>\n <div data-panel=\"mobile\">\n <a class=\"wc-deeplink-btn\" href=\"${deeplink}\" target=\"_blank\">\n ${TELEGRAM_SVG}\n Open in Telegram\n </a>\n </div>\n <div data-panel=\"qr\" style=\"display:none\">\n <div class=\"wc-qr-container\">\n <div class=\"wc-qr-wrap\">\n <img src=\"${qrUrl}\" width=\"220\" height=\"220\" alt=\"QR\" />\n </div>\n <div class=\"wc-qr-hint\">Scan with your phone camera or wallet app</div>\n </div>\n </div>\n <div class=\"wc-status\">\n <div class=\"wc-spinner\"></div>\n <span>Waiting for confirmation...</span>\n </div>\n </div>\n <div class=\"wc-footer\">Powered by WalletConnect</div>\n `;\n\n this.render(html);\n\n const tabs = this.overlay?.querySelectorAll('.wc-tab');\n const panels = this.overlay?.querySelectorAll('[data-panel]');\n tabs?.forEach((tab) => {\n tab.addEventListener('click', () => {\n const target = (tab as HTMLElement).dataset.tab;\n tabs.forEach((t) => t.classList.remove('active'));\n tab.classList.add('active');\n panels?.forEach((p) => {\n (p as HTMLElement).style.display =\n (p as HTMLElement).dataset.panel === target ? 'block' : 'none';\n });\n });\n });\n\n if (showBack && onBack) {\n this.overlay\n ?.querySelector('[data-action=\"back\"]')\n ?.addEventListener('click', onBack);\n }\n }\n\n showSuccess(\n wallet: WalletMeta,\n address: string | null,\n user: { username?: string; avatar?: string } | null,\n onDone: () => void,\n ): void {\n const checkSvg = `<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"/></svg>`;\n\n const displayName = user?.username || 'User';\n const initials = displayName.slice(0, 2).toUpperCase();\n\n const avatarHtml = user?.avatar\n ? `<img class=\"wc-success-avatar\" src=\"${user.avatar}\" alt=\"${displayName}\" />`\n : `<div class=\"wc-success-avatar-placeholder\">${initials}</div>`;\n\n const html = `\n <div class=\"wc-handle\"></div>\n <div class=\"wc-header\">\n <h3 class=\"wc-title\">Connected</h3>\n <button class=\"wc-close\" data-action=\"close\">&#10005;</button>\n </div>\n <div class=\"wc-body\">\n <div class=\"wc-success\">\n <div class=\"wc-success-check\">${checkSvg}</div>\n <div class=\"wc-success-title\">Connection Successful</div>\n <div class=\"wc-success-user\">\n ${avatarHtml}\n <div class=\"wc-success-user-info\">\n <div class=\"wc-success-user-name\">${displayName}</div>\n ${address ? `<div class=\"wc-success-user-addr\" title=\"${address}\">${address}</div>` : ''}\n </div>\n </div>\n <button class=\"wc-success-done\" data-action=\"done\">Done</button>\n </div>\n </div>\n <div class=\"wc-footer\">Powered by WalletConnect</div>\n `;\n\n this.render(html);\n\n this.overlay\n ?.querySelector('[data-action=\"done\"]')\n ?.addEventListener('click', onDone);\n }\n\n updateStatus(text: string, showSpinner = true): void {\n const el = this.overlay?.querySelector('.wc-status');\n if (el) {\n el.innerHTML = `\n ${showSpinner ? '<div class=\"wc-spinner\"></div>' : ''}\n <span>${text}</span>\n `;\n }\n }\n\n private render(innerHtml: string): void {\n this.destroy();\n\n const el = document.createElement('div');\n el.id = MODAL_ID;\n el.innerHTML = `\n <style>${getStyles(this.theme)}</style>\n <div class=\"wc-overlay\">\n <div class=\"wc-modal\">${innerHtml}</div>\n </div>\n `;\n\n document.body.appendChild(el);\n this.overlay = el;\n\n this.overlay\n .querySelector('[data-action=\"close\"]')\n ?.addEventListener('click', () => { this.onClose(); this.destroy(); });\n\n this.overlay\n .querySelector('.wc-overlay')\n ?.addEventListener('click', (e) => {\n if ((e.target as HTMLElement).classList.contains('wc-overlay')) {\n this.onClose();\n this.destroy();\n }\n });\n }\n\n destroy(): void {\n document.getElementById(MODAL_ID)?.remove();\n this.overlay = null;\n }\n}\n","import type {\n WalletConnectConfig,\n WalletMeta,\n ConnectResult,\n ConnectSession,\n InitSessionResponse,\n WalletConnectEventType,\n WalletConnectEventCallback,\n} from './types';\nimport { WsTransport, PollingTransport } from './transport';\nimport { Modal } from './modal';\n\nconst STORAGE_KEY_PREFIX = '__wc_session_';\nconst DEFAULT_REGISTRY_URL = 'https://cdn.jsdelivr.net/npm/toncorp-wallet-connect-sdk@latest/registry.json';\n\nexport class BaseWalletConnect {\n protected config: Required<\n Pick<WalletConnectConfig, 'appId' | 'registryUrl' | 'theme'>\n > &\n Pick<WalletConnectConfig, 'walletId'>;\n\n private listeners: Map<WalletConnectEventType, Set<WalletConnectEventCallback>> = new Map();\n private modal: Modal | null = null;\n private wsTransport: WsTransport | null = null;\n private pollingTransport: PollingTransport | null = null;\n private currentResult: ConnectResult | null = null;\n\n constructor(config: WalletConnectConfig) {\n this.config = {\n appId: config.appId,\n registryUrl: config.registryUrl || DEFAULT_REGISTRY_URL,\n walletId: config.walletId,\n theme: config.theme || 'light',\n };\n\n this.restoreSession();\n this.registerGlobal();\n }\n\n // ── Public API ──\n\n async connect(): Promise<ConnectResult> {\n if (this.currentResult) {\n return this.currentResult;\n }\n\n const wallets = await this.fetchWallets();\n const filtered = this.filterWallets(wallets);\n\n if (filtered.length === 0) {\n throw new Error('No supported wallets available');\n }\n\n return new Promise<ConnectResult>((resolve, reject) => {\n const onClose = () => {\n this.cleanup();\n reject(new Error('User closed modal'));\n };\n\n this.modal = new Modal(this.config.theme, onClose);\n\n if (filtered.length === 1) {\n this.startConnect(filtered[0], false, resolve, reject);\n } else {\n this.modal.showWalletPicker(filtered, (wallet) => {\n this.startConnect(wallet, true, resolve, reject);\n });\n }\n });\n }\n\n disconnect(): void {\n // Call disconnect API (fire-and-forget)\n const session = this.currentResult?.session;\n if (session) {\n const baseUrl = session.apiUrl.replace(/\\/$/, '');\n fetch(`${baseUrl}/connect/disconnect-by-token`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ sessionToken: session.sessionToken }),\n }).catch(() => {});\n }\n\n // Clear all localStorage keys and window instances\n this.currentResult = null;\n this.removeStoredSession();\n this.clearAllRelatedSessions();\n this.cleanup();\n this.emit('disconnect');\n }\n\n isConnected(): boolean {\n return this.currentResult !== null;\n }\n\n getWallet(): ConnectResult | null {\n return this.currentResult;\n }\n\n on(event: WalletConnectEventType, cb: WalletConnectEventCallback): void {\n if (!this.listeners.has(event)) {\n this.listeners.set(event, new Set());\n }\n this.listeners.get(event)!.add(cb);\n }\n\n off(event: WalletConnectEventType, cb: WalletConnectEventCallback): void {\n this.listeners.get(event)?.delete(cb);\n }\n\n // ── Internal ──\n\n private get storageKey(): string {\n const walletId = this.config.walletId;\n const suffix = Array.isArray(walletId)\n ? walletId.sort().join('_')\n : walletId || 'all';\n return `${STORAGE_KEY_PREFIX}${suffix}__`;\n }\n\n private async fetchWallets(): Promise<WalletMeta[]> {\n const url = this.config.registryUrl.replace(/\\/$/, '');\n const res = await fetch(url);\n if (!res.ok) throw new Error('Failed to fetch wallets');\n return res.json();\n }\n\n private filterWallets(wallets: WalletMeta[]): WalletMeta[] {\n if (!this.config.walletId) return wallets;\n\n const ids = Array.isArray(this.config.walletId)\n ? this.config.walletId\n : [this.config.walletId];\n\n return wallets.filter((w) => ids.includes(w.walletId));\n }\n\n private async startConnect(\n wallet: WalletMeta,\n showBack: boolean,\n resolve: (result: ConnectResult) => void,\n reject: (error: Error) => void,\n ): Promise<void> {\n try {\n const session = await this.initSession(wallet);\n\n this.modal?.showConnect(wallet, session.deeplink, showBack, () => {\n this.cleanup();\n this.connect().then(resolve).catch(reject);\n });\n\n this.listenForConfirmation(\n wallet.apiUrl,\n session.sessionToken,\n (result) => {\n // Attach session info for disconnect\n result.session = {\n sessionToken: session.sessionToken,\n walletId: wallet.walletId,\n apiUrl: wallet.apiUrl,\n };\n this.currentResult = result;\n this.storeSession(result);\n this.syncToWalletInstance(wallet.walletId, result);\n this.emit('connect', result);\n\n // Show success screen\n this.modal?.showSuccess(\n wallet,\n result.wallet?.address || null,\n result.user || null,\n () => {\n this.modal?.destroy();\n this.modal = null;\n resolve(result);\n },\n );\n },\n () => {\n this.modal?.updateStatus('Connection rejected', false);\n setTimeout(() => {\n this.modal?.destroy();\n this.modal = null;\n reject(new Error('Connection rejected by user'));\n }, 1500);\n },\n () => {\n this.modal?.updateStatus('Session expired', false);\n this.emit('session_expired');\n setTimeout(() => {\n this.modal?.destroy();\n this.modal = null;\n reject(new Error('Session expired'));\n }, 1500);\n },\n );\n } catch (err) {\n this.modal?.destroy();\n this.modal = null;\n reject(err instanceof Error ? err : new Error(String(err)));\n }\n }\n\n private async initSession(wallet: WalletMeta): Promise<InitSessionResponse> {\n const baseUrl = wallet.apiUrl.replace(/\\/$/, '');\n const res = await fetch(`${baseUrl}/connect/init`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n appId: this.config.appId,\n walletId: wallet.walletId,\n origin: typeof window !== 'undefined' ? window.location.origin : '',\n }),\n });\n if (!res.ok) throw new Error('Failed to init session');\n return res.json();\n }\n\n private listenForConfirmation(\n apiUrl: string,\n sessionToken: string,\n onConfirmed: (result: ConnectResult) => void,\n onRejected: () => void,\n onExpired: () => void,\n ): void {\n let resolved = false;\n\n const wrap = <T extends (...args: any[]) => void>(fn: T): T =>\n ((...args: any[]) => {\n if (resolved) return;\n resolved = true;\n this.wsTransport?.close();\n this.pollingTransport?.stop();\n fn(...args);\n }) as unknown as T;\n\n const wrappedConfirm = wrap(onConfirmed);\n const wrappedReject = wrap(onRejected);\n const wrappedExpire = wrap(onExpired);\n\n // Start polling immediately as primary transport\n this.pollingTransport = new PollingTransport(\n apiUrl,\n sessionToken,\n wrappedConfirm,\n wrappedReject,\n wrappedExpire,\n (msg) => this.emit('error', msg),\n );\n this.pollingTransport.start();\n\n // Also try WS for faster response\n this.wsTransport = new WsTransport(\n apiUrl,\n sessionToken,\n wrappedConfirm,\n wrappedReject,\n wrappedExpire,\n () => {}, // WS fail is fine, polling is running\n );\n this.wsTransport.connect();\n }\n\n private cleanup(): void {\n this.wsTransport?.close();\n this.wsTransport = null;\n this.pollingTransport?.stop();\n this.pollingTransport = null;\n this.modal?.destroy();\n this.modal = null;\n }\n\n private emit(event: WalletConnectEventType, data?: any): void {\n this.listeners.get(event)?.forEach((cb) => cb(data));\n }\n\n // ── Persistence ──\n\n private storeSession(result: ConnectResult): void {\n try {\n localStorage.setItem(this.storageKey, JSON.stringify(result));\n } catch {\n // localStorage unavailable\n }\n }\n\n private restoreSession(): void {\n try {\n const stored = localStorage.getItem(this.storageKey);\n if (stored) {\n this.currentResult = JSON.parse(stored);\n }\n } catch {\n // ignore\n }\n }\n\n private removeStoredSession(): void {\n try {\n localStorage.removeItem(this.storageKey);\n } catch {\n // ignore\n }\n }\n\n // ── Global window registration ──\n\n private registerGlobal(): void {\n if (typeof window === 'undefined') return;\n\n const walletId = this.config.walletId;\n const key = Array.isArray(walletId)\n ? walletId[0]\n : walletId || 'walletconnect';\n\n (window as any)[key] = this;\n }\n\n /** Sync connect result to the specific wallet instance on window (e.g. window.onedollar) */\n private syncToWalletInstance(walletId: string, result: ConnectResult): void {\n if (typeof window === 'undefined') return;\n\n const target = (window as any)[walletId];\n if (target && target !== this && target instanceof BaseWalletConnect) {\n (target as any).currentResult = result;\n (target as any).storeSession(result);\n }\n }\n\n /** Clear all related sessions from window instances and localStorage */\n private clearAllRelatedSessions(): void {\n if (typeof window === 'undefined') return;\n\n // Clear all known wallet instances on window\n const keys = ['tonpass', 'onedollar', 'walletconnect'];\n for (const key of keys) {\n const inst = (window as any)[key];\n if (inst && inst !== this && inst instanceof BaseWalletConnect) {\n (inst as any).currentResult = null;\n (inst as any).removeStoredSession();\n }\n }\n\n // Also clear all wc localStorage keys\n try {\n const toRemove: string[] = [];\n for (let i = 0; i < localStorage.length; i++) {\n const k = localStorage.key(i);\n if (k && k.startsWith(STORAGE_KEY_PREFIX)) {\n toRemove.push(k);\n }\n }\n toRemove.forEach((k) => localStorage.removeItem(k));\n } catch {\n // ignore\n }\n }\n}\n","import { BaseWalletConnect } from './client';\nimport type { WalletConnectConfig } from './types';\n\nexport class OneDollarConnect extends BaseWalletConnect {\n constructor(config: Omit<WalletConnectConfig, 'walletId'>) {\n super({ ...config, walletId: 'onedollar' });\n }\n}\n","import { BaseWalletConnect } from './client';\nimport type { WalletConnectConfig } from './types';\n\nexport class TonPassConnect extends BaseWalletConnect {\n constructor(config: Omit<WalletConnectConfig, 'walletId'>) {\n super({ ...config, walletId: 'tonpass' });\n }\n}\n"],"names":["WsTransport","constructor","apiUrl","sessionToken","onConfirmed","onRejected","onExpired","onError","this","ws","reconnectTimer","closed","connect","replace","connectSocketIO","baseUrl","fetch","then","res","text","body","jsonStr","sid","JSON","parse","wsUrl","WebSocket","onopen","send","onmessage","event","msg","data","startsWith","payload","slice","eventName","handleEvent","onclose","scheduleReconnect","onerror","catch","close","setTimeout","clearTimeout","PollingTransport","timer","stopped","start","poll","setInterval","ok","json","status","wallet","user","stop","clearInterval","MODAL_ID","Modal","theme","onClose","overlay","showWalletPicker","wallets","onSelect","html","length","map","w","walletId","icon","name","charAt","join","description","render","forEach","querySelector","addEventListener","showConnect","deeplink","showBack","onBack","qrUrl","size","encodeURIComponent","generateQRDataUrl","tabs","querySelectorAll","panels","tab","target","dataset","t","classList","remove","add","p","style","display","panel","showSuccess","address","onDone","displayName","username","initials","toUpperCase","avatar","updateStatus","showSpinner","el","innerHTML","innerHtml","destroy","document","createElement","id","isDark","bg","bgSecondary","textSecondary","border","accent","accentDark","getStyles","appendChild","e","contains","getElementById","STORAGE_KEY_PREFIX","BaseWalletConnect","config","listeners","Map","modal","wsTransport","pollingTransport","currentResult","appId","registryUrl","restoreSession","registerGlobal","fetchWallets","filtered","filterWallets","Error","Promise","resolve","reject","cleanup","startConnect","disconnect","session","method","headers","stringify","removeStoredSession","clearAllRelatedSessions","emit","isConnected","getWallet","on","cb","has","set","Set","get","off","delete","storageKey","suffix","Array","isArray","sort","url","ids","filter","includes","initSession","listenForConfirmation","result","storeSession","syncToWalletInstance","err","String","origin","window","location","resolved","wrap","fn","args","wrappedConfirm","wrappedReject","wrappedExpire","localStorage","setItem","stored","getItem","removeItem","key","keys","inst","toRemove","i","k","push","super"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs.js","sources":["../../transport.ts","../../modal.ts","../../client.ts","../../onedollar.ts","../../tonpass.ts"],"sourcesContent":["import type { ConnectResult } from './types';\n\ntype TransportCallback = (data: ConnectResult) => void;\ntype TransportErrorCallback = (error: string) => void;\n\n// ── WebSocket Transport ──\n\nexport class WsTransport {\n private ws: WebSocket | null = null;\n private reconnectTimer: ReturnType<typeof setTimeout> | null = null;\n private closed = false;\n\n constructor(\n private apiUrl: string,\n private sessionToken: string,\n private onConfirmed: TransportCallback,\n private onRejected: () => void,\n private onExpired: () => void,\n private onError: TransportErrorCallback,\n ) {}\n\n connect(): void {\n this.closed = false;\n const wsUrl = this.apiUrl\n .replace(/^http/, 'ws')\n .replace(/\\/$/, '');\n const url = `${wsUrl}/walletconnect?sessionToken=${this.sessionToken}`;\n\n try {\n // Socket.IO uses polling upgrade — use native WS for simplicity in SDK\n // The BE gateway uses socket.io, so we connect via socket.io protocol\n this.connectSocketIO();\n } catch {\n this.onError('WebSocket connection failed');\n }\n }\n\n private connectSocketIO(): void {\n const baseUrl = this.apiUrl.replace(/\\/$/, '');\n\n // Socket.IO handshake: first GET for sid, then upgrade to WS\n const pollingUrl = `${baseUrl}/walletconnect/?EIO=4&transport=polling`;\n\n fetch(pollingUrl)\n .then((res) => res.text())\n .then((body) => {\n // Socket.IO response format: \"0{...json...}\"\n const jsonStr = body.replace(/^\\d+/, '');\n const handshake = JSON.parse(jsonStr);\n const sid = handshake.sid;\n\n const wsBase = baseUrl.replace(/^http/, 'ws');\n const wsUrl = `${wsBase}/walletconnect/?EIO=4&transport=websocket&sid=${sid}`;\n\n this.ws = new WebSocket(wsUrl);\n\n this.ws.onopen = () => {\n // Socket.IO upgrade probe\n this.ws!.send('2probe');\n };\n\n this.ws.onmessage = (event) => {\n const msg = event.data as string;\n\n if (msg === '3probe') {\n // Upgrade confirmed, send upgrade packet + join room\n this.ws!.send('5');\n // Emit connect event with sessionToken as query (already in URL)\n // Socket.IO auto-joins based on handshake query\n return;\n }\n\n // Handle Socket.IO event messages: 42[\"event_name\", {...data}]\n if (msg.startsWith('42')) {\n try {\n const payload = JSON.parse(msg.slice(2));\n const [eventName, data] = payload;\n this.handleEvent(eventName, data);\n } catch {\n // ignore malformed\n }\n return;\n }\n\n // Ping from server\n if (msg === '2') {\n this.ws!.send('3');\n }\n };\n\n this.ws.onclose = () => {\n if (!this.closed) {\n this.scheduleReconnect();\n }\n };\n\n this.ws.onerror = () => {\n if (!this.closed) {\n this.scheduleReconnect();\n }\n };\n })\n .catch(() => {\n if (!this.closed) {\n this.scheduleReconnect();\n }\n });\n }\n\n private handleEvent(eventName: string, data: any): void {\n switch (eventName) {\n case 'session_confirmed':\n this.onConfirmed(data);\n this.close();\n break;\n case 'session_rejected':\n this.onRejected();\n this.close();\n break;\n case 'session_expired':\n this.onExpired();\n this.close();\n break;\n }\n }\n\n private scheduleReconnect(): void {\n if (this.closed || this.reconnectTimer) return;\n this.reconnectTimer = setTimeout(() => {\n this.reconnectTimer = null;\n this.connectSocketIO();\n }, 3000);\n }\n\n close(): void {\n this.closed = true;\n if (this.reconnectTimer) {\n clearTimeout(this.reconnectTimer);\n this.reconnectTimer = null;\n }\n if (this.ws) {\n this.ws.close();\n this.ws = null;\n }\n }\n}\n\n// ── Long-Poll Fallback ──\n\nexport class PollingTransport {\n private timer: ReturnType<typeof setInterval> | null = null;\n private stopped = false;\n\n constructor(\n private apiUrl: string,\n private sessionToken: string,\n private onConfirmed: TransportCallback,\n private onRejected: () => void,\n private onExpired: () => void,\n private onError: TransportErrorCallback,\n ) {}\n\n start(): void {\n this.stopped = false;\n this.poll();\n this.timer = setInterval(() => this.poll(), 2000);\n }\n\n private async poll(): Promise<void> {\n if (this.stopped) return;\n\n try {\n const baseUrl = this.apiUrl.replace(/\\/$/, '');\n const res = await fetch(\n `${baseUrl}/connect/status?token=${this.sessionToken}`,\n );\n if (!res.ok) return;\n\n const data = await res.json();\n\n switch (data.status) {\n case 'CONFIRMED':\n this.onConfirmed({ wallet: data.wallet, user: data.user });\n this.stop();\n break;\n case 'REJECTED':\n this.onRejected();\n this.stop();\n break;\n case 'EXPIRED':\n this.onExpired();\n this.stop();\n break;\n }\n } catch {\n // silently retry next interval\n }\n }\n\n stop(): void {\n this.stopped = true;\n if (this.timer) {\n clearInterval(this.timer);\n this.timer = null;\n }\n }\n}\n","import type { WalletMeta } from './types';\n\nconst MODAL_ID = '__wc_modal__';\n\nfunction getStyles(theme: 'light' | 'dark'): string {\n const isDark = theme === 'dark';\n const bg = isDark ? '#141414' : '#ffffff';\n const bgSecondary = isDark ? '#1e1e1e' : '#f4f4f4';\n const text = isDark ? '#ffffff' : '#141414';\n const textSecondary = isDark ? '#9a9a9a' : '#787878';\n const border = isDark ? '#2a2a2a' : '#e4e4e4';\n const accent = '#2bea6a';\n const accentDark = '#1db954';\n\n return `\n @keyframes wc-fadeIn { from{opacity:0} to{opacity:1} }\n @keyframes wc-slideUp {\n from{opacity:0;transform:translateY(100%)}\n to{opacity:1;transform:translateY(0)}\n }\n .wc-overlay {\n position:fixed; inset:0; z-index:99999;\n background:rgba(0,0,0,${isDark ? 0.75 : 0.45});\n display:flex; align-items:flex-end; justify-content:center;\n font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;\n backdrop-filter:blur(6px); -webkit-backdrop-filter:blur(6px);\n animation:wc-fadeIn .2s ease;\n }\n @media(min-width:480px){\n .wc-overlay{align-items:center}\n .wc-modal{border-radius:24px;max-height:85vh}\n }\n .wc-modal {\n background:${bg}; width:100%; max-width:420px;\n border-radius:24px 24px 0 0; overflow:hidden; color:${text};\n box-shadow:0 -8px 40px rgba(0,0,0,${isDark ? 0.5 : 0.15});\n animation:wc-slideUp .3s cubic-bezier(.16,1,.3,1);\n max-height:90vh; overflow-y:auto;\n }\n\n /* Handle bar */\n .wc-handle {\n width:36px; height:4px; border-radius:2px;\n background:${border}; margin:10px auto 0;\n }\n\n /* Header */\n .wc-header {\n display:flex; align-items:center; justify-content:space-between;\n padding:20px 24px 0;\n }\n .wc-header-left {\n display:flex; align-items:center; gap:10px;\n }\n .wc-header-icon {\n width:32px; height:32px; border-radius:10px; object-fit:cover;\n }\n .wc-title { font-size:17px; font-weight:700; margin:0; }\n .wc-close {\n width:30px; height:30px; display:flex; align-items:center; justify-content:center;\n background:${bgSecondary}; border:none; border-radius:50%;\n cursor:pointer; font-size:14px; color:${textSecondary};\n transition:all .15s;\n }\n .wc-close:hover { background:${border}; color:${text}; }\n .wc-subtitle {\n font-size:13px; color:${textSecondary}; margin:8px 24px 0;\n line-height:1.4;\n }\n\n .wc-body { padding:20px 24px 24px; }\n\n /* Grid wallet picker */\n .wc-wallet-grid {\n display:grid; grid-template-columns:repeat(4,1fr);\n gap:16px 12px; list-style:none; margin:0; padding:0;\n }\n .wc-wallet-grid-item {\n display:flex; flex-direction:column; align-items:center;\n gap:8px; cursor:pointer; padding:8px 4px; border-radius:16px;\n transition:all .15s; border:2px solid transparent;\n }\n .wc-wallet-grid-item:hover {\n background:${bgSecondary}; border-color:${border};\n }\n .wc-wallet-grid-icon {\n width:56px; height:56px; border-radius:16px;\n object-fit:cover; box-shadow:0 2px 8px rgba(0,0,0,${isDark ? 0.3 : 0.08});\n }\n .wc-wallet-grid-icon-placeholder {\n width:56px; height:56px; border-radius:16px;\n background:linear-gradient(135deg,${accentDark},${accent});\n display:flex; align-items:center; justify-content:center;\n color:#fff; font-weight:800; font-size:22px;\n box-shadow:0 2px 8px rgba(0,0,0,${isDark ? 0.3 : 0.08});\n }\n .wc-wallet-grid-name {\n font-size:11px; font-weight:500; text-align:center;\n color:${textSecondary}; line-height:1.2;\n max-width:72px; overflow:hidden; text-overflow:ellipsis;\n white-space:nowrap;\n }\n\n /* List wallet picker (alternative) */\n .wc-wallet-list { list-style:none; margin:0; padding:0; }\n .wc-wallet-item {\n display:flex; align-items:center; gap:14px;\n padding:12px 16px; border-radius:16px; cursor:pointer;\n border:1.5px solid ${border}; margin-bottom:8px;\n transition:all .15s;\n }\n .wc-wallet-item:hover {\n background:${bgSecondary}; border-color:${accent};\n }\n .wc-wallet-list-icon {\n width:40px; height:40px; border-radius:12px; object-fit:cover;\n }\n .wc-wallet-list-icon-placeholder {\n width:40px; height:40px; border-radius:12px;\n background:linear-gradient(135deg,${accentDark},${accent});\n display:flex; align-items:center; justify-content:center;\n color:#fff; font-weight:700; font-size:16px;\n }\n .wc-wallet-item-info { flex:1; }\n .wc-wallet-item-name { font-size:14px; font-weight:600; }\n .wc-wallet-item-desc { font-size:11px; color:${textSecondary}; margin-top:1px; }\n .wc-wallet-item-arrow { color:${textSecondary}; font-size:16px; }\n\n /* Tabs */\n .wc-tabs {\n display:flex; background:${bgSecondary}; border-radius:12px;\n padding:3px; margin-bottom:20px;\n }\n .wc-tab {\n flex:1; padding:10px; text-align:center; cursor:pointer;\n font-size:13px; font-weight:600; background:transparent;\n border:none; color:${textSecondary}; border-radius:10px;\n transition:all .2s;\n }\n .wc-tab:hover { color:${text}; }\n .wc-tab.active {\n background:${bg}; color:${text};\n box-shadow:0 1px 4px rgba(0,0,0,${isDark ? 0.3 : 0.08});\n }\n\n /* Deeplink */\n .wc-deeplink-btn {\n display:flex; align-items:center; justify-content:center; gap:10px;\n width:100%; padding:16px; border:none; border-radius:16px;\n background:linear-gradient(135deg,${accentDark},${accent});\n color:#fff; font-size:15px; font-weight:700; cursor:pointer;\n text-decoration:none; transition:all .2s;\n box-shadow:0 4px 20px rgba(43,234,106,0.2);\n box-sizing:border-box;\n }\n .wc-deeplink-btn:hover {\n transform:translateY(-1px);\n box-shadow:0 6px 28px rgba(43,234,106,0.3);\n }\n\n /* QR */\n .wc-qr-container {\n display:flex; flex-direction:column; align-items:center; gap:16px;\n }\n .wc-qr-wrap {\n padding:16px; background:#fff; border-radius:20px;\n box-shadow:0 2px 16px rgba(0,0,0,${isDark ? 0.2 : 0.06});\n }\n .wc-qr-wrap img { display:block; border-radius:4px; }\n .wc-qr-hint { font-size:12px; color:${textSecondary}; text-align:center; }\n\n /* Status */\n .wc-status {\n display:flex; align-items:center; justify-content:center;\n gap:10px; padding:20px 0 4px; font-size:13px; color:${textSecondary};\n }\n .wc-spinner {\n width:16px; height:16px; border:2px solid ${border};\n border-top-color:${accent}; border-radius:50%;\n animation:wc-spin .7s linear infinite;\n }\n @keyframes wc-spin { to{transform:rotate(360deg)} }\n\n /* Back */\n .wc-back {\n background:none; border:none; cursor:pointer; padding:0;\n color:${textSecondary}; display:flex; align-items:center;\n transition:color .15s; font-size:18px;\n }\n .wc-back:hover { color:${text}; }\n\n /* Footer */\n .wc-footer {\n text-align:center; padding:4px 0 20px;\n font-size:11px; color:${isDark ? '#555' : '#bbb'};\n }\n\n /* Success screen */\n .wc-success {\n display:flex; flex-direction:column; align-items:center;\n padding:12px 0 4px; gap:20px;\n }\n .wc-success-check {\n width:64px; height:64px; border-radius:50%;\n background:linear-gradient(135deg,${accentDark},${accent});\n display:flex; align-items:center; justify-content:center;\n box-shadow:0 4px 20px rgba(43,234,106,0.25);\n animation:wc-popIn .4s cubic-bezier(.16,1,.3,1);\n }\n @keyframes wc-popIn {\n from{transform:scale(0);opacity:0}\n 50%{transform:scale(1.15)}\n to{transform:scale(1);opacity:1}\n }\n .wc-success-check svg { width:32px; height:32px; color:#fff; }\n .wc-success-title {\n font-size:18px; font-weight:700; color:${text};\n }\n .wc-success-user {\n display:flex; align-items:center; gap:14px;\n background:${bgSecondary}; border-radius:16px;\n padding:16px 18px; width:100%; box-sizing:border-box;\n }\n .wc-success-avatar {\n width:48px; height:48px; border-radius:50%; object-fit:cover;\n flex-shrink:0; border:2px solid ${border};\n }\n .wc-success-avatar-placeholder {\n width:48px; height:48px; border-radius:50%;\n background:linear-gradient(135deg,${accentDark},${accent});\n display:flex; align-items:center; justify-content:center;\n color:#fff; font-weight:700; font-size:18px; flex-shrink:0;\n border:2px solid ${border};\n }\n .wc-success-user-info { flex:1; min-width:0; }\n .wc-success-user-name { font-size:15px; font-weight:600; color:${text}; }\n .wc-success-user-addr {\n font-size:12px; color:${textSecondary}; margin-top:4px;\n font-family:'SF Mono',Monaco,Consolas,monospace;\n word-break:break-all; line-height:1.4;\n }\n .wc-success-done {\n width:100%; padding:14px; border:none; border-radius:14px;\n background:linear-gradient(135deg,${accentDark},${accent});\n color:#fff; font-size:14px; font-weight:700; cursor:pointer;\n transition:all .2s;\n box-shadow:0 4px 16px rgba(43,234,106,0.2);\n }\n .wc-success-done:hover {\n transform:translateY(-1px);\n box-shadow:0 6px 24px rgba(43,234,106,0.3);\n }\n `;\n}\n\nconst TELEGRAM_SVG = `<svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M11.944 0A12 12 0 1 0 24 12.056A12.01 12.01 0 0 0 11.944 0Zm4.962 7.224c.1-.002.321.023.465.14a.506.506 0 0 1 .171.325c.016.093.036.306.02.472c-.18 1.898-.962 6.502-1.36 8.627c-.168.9-.499 1.201-.82 1.23c-.696.065-1.225-.46-1.9-.902c-1.056-.693-1.653-1.124-2.678-1.8c-1.185-.78-.417-1.21.258-1.91c.177-.184 3.247-2.977 3.307-3.23c.007-.032.014-.15-.056-.212s-.174-.041-.249-.024c-.106.024-1.793 1.14-5.061 3.345c-.48.33-.913.49-1.302.48c-.428-.008-1.252-.241-1.865-.44c-.752-.245-1.349-.374-1.297-.789c.027-.216.325-.437.893-.663c3.498-1.524 5.83-2.529 6.998-3.014c3.332-1.386 4.025-1.627 4.476-1.635Z\"/></svg>`;\n\nfunction generateQRDataUrl(text: string, size = 220): string {\n return `https://api.qrserver.com/v1/create-qr-code/?size=${size}x${size}&data=${encodeURIComponent(text)}&margin=8`;\n}\n\nexport class Modal {\n private overlay: HTMLDivElement | null = null;\n private theme: 'light' | 'dark';\n private onClose: () => void;\n\n constructor(theme: 'light' | 'dark', onClose: () => void) {\n this.theme = theme;\n this.onClose = onClose;\n }\n\n showWalletPicker(\n wallets: WalletMeta[],\n onSelect: (wallet: WalletMeta) => void,\n ): void {\n const useGrid = wallets.length >= 3;\n\n const listHtml = useGrid\n ? `<ul class=\"wc-wallet-grid\">${wallets\n .map(\n (w) => `\n <li class=\"wc-wallet-grid-item\" data-wallet-id=\"${w.walletId}\">\n ${\n w.icon\n ? `<img class=\"wc-wallet-grid-icon\" src=\"${w.icon}\" alt=\"${w.name}\" />`\n : `<div class=\"wc-wallet-grid-icon-placeholder\">${w.name.charAt(0)}</div>`\n }\n <span class=\"wc-wallet-grid-name\">${w.name}</span>\n </li>`,\n )\n .join('')}</ul>`\n : `<ul class=\"wc-wallet-list\">${wallets\n .map(\n (w) => `\n <li class=\"wc-wallet-item\" data-wallet-id=\"${w.walletId}\">\n ${\n w.icon\n ? `<img class=\"wc-wallet-list-icon\" src=\"${w.icon}\" alt=\"${w.name}\" />`\n : `<div class=\"wc-wallet-list-icon-placeholder\">${w.name.charAt(0)}</div>`\n }\n <div class=\"wc-wallet-item-info\">\n <div class=\"wc-wallet-item-name\">${w.name}</div>\n ${w.description ? `<div class=\"wc-wallet-item-desc\">${w.description}</div>` : ''}\n </div>\n <span class=\"wc-wallet-item-arrow\">&#8250;</span>\n </li>`,\n )\n .join('')}</ul>`;\n\n const html = `\n <div class=\"wc-handle\"></div>\n <div class=\"wc-header\">\n <h3 class=\"wc-title\">Connect your wallet</h3>\n <button class=\"wc-close\" data-action=\"close\">&#10005;</button>\n </div>\n <p class=\"wc-subtitle\">Choose a wallet to connect to this app</p>\n <div class=\"wc-body\">${listHtml}</div>\n <div class=\"wc-footer\">Powered by WalletConnect</div>\n `;\n\n this.render(html);\n\n wallets.forEach((w) => {\n this.overlay\n ?.querySelector(`[data-wallet-id=\"${w.walletId}\"]`)\n ?.addEventListener('click', () => onSelect(w));\n });\n }\n\n showConnect(\n wallet: WalletMeta,\n deeplink: string,\n showBack: boolean,\n onBack?: () => void,\n ): void {\n const qrUrl = generateQRDataUrl(deeplink);\n\n const html = `\n <div class=\"wc-handle\"></div>\n <div class=\"wc-header\">\n <div class=\"wc-header-left\">\n ${showBack ? '<button class=\"wc-back\" data-action=\"back\">&#8592;</button>' : ''}\n ${wallet.icon ? `<img class=\"wc-header-icon\" src=\"${wallet.icon}\" />` : ''}\n <h3 class=\"wc-title\">${wallet.name}</h3>\n </div>\n <button class=\"wc-close\" data-action=\"close\">&#10005;</button>\n </div>\n <p class=\"wc-subtitle\">Approve the connection request in your wallet</p>\n <div class=\"wc-body\">\n <div class=\"wc-tabs\">\n <button class=\"wc-tab active\" data-tab=\"mobile\">Mobile</button>\n <button class=\"wc-tab\" data-tab=\"qr\">QR Code</button>\n </div>\n <div data-panel=\"mobile\">\n <a class=\"wc-deeplink-btn\" href=\"${deeplink}\" target=\"_blank\">\n ${TELEGRAM_SVG}\n Open in Telegram\n </a>\n </div>\n <div data-panel=\"qr\" style=\"display:none\">\n <div class=\"wc-qr-container\">\n <div class=\"wc-qr-wrap\">\n <img src=\"${qrUrl}\" width=\"220\" height=\"220\" alt=\"QR\" />\n </div>\n <div class=\"wc-qr-hint\">Scan with your phone camera or wallet app</div>\n </div>\n </div>\n <div class=\"wc-status\">\n <div class=\"wc-spinner\"></div>\n <span>Waiting for confirmation...</span>\n </div>\n </div>\n <div class=\"wc-footer\">Powered by WalletConnect</div>\n `;\n\n this.render(html);\n\n const tabs = this.overlay?.querySelectorAll('.wc-tab');\n const panels = this.overlay?.querySelectorAll('[data-panel]');\n tabs?.forEach((tab) => {\n tab.addEventListener('click', () => {\n const target = (tab as HTMLElement).dataset.tab;\n tabs.forEach((t) => t.classList.remove('active'));\n tab.classList.add('active');\n panels?.forEach((p) => {\n (p as HTMLElement).style.display =\n (p as HTMLElement).dataset.panel === target ? 'block' : 'none';\n });\n });\n });\n\n if (showBack && onBack) {\n this.overlay\n ?.querySelector('[data-action=\"back\"]')\n ?.addEventListener('click', onBack);\n }\n }\n\n showSuccess(\n wallet: WalletMeta,\n address: string | null,\n user: { username?: string; avatar?: string } | null,\n onDone: () => void,\n ): void {\n const checkSvg = `<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"/></svg>`;\n\n const displayName = user?.username || 'User';\n const initials = displayName.slice(0, 2).toUpperCase();\n\n const avatarHtml = user?.avatar\n ? `<img class=\"wc-success-avatar\" src=\"${user.avatar}\" alt=\"${displayName}\" />`\n : `<div class=\"wc-success-avatar-placeholder\">${initials}</div>`;\n\n const html = `\n <div class=\"wc-handle\"></div>\n <div class=\"wc-header\">\n <h3 class=\"wc-title\">Connected</h3>\n <button class=\"wc-close\" data-action=\"close\">&#10005;</button>\n </div>\n <div class=\"wc-body\">\n <div class=\"wc-success\">\n <div class=\"wc-success-check\">${checkSvg}</div>\n <div class=\"wc-success-title\">Connection Successful</div>\n <div class=\"wc-success-user\">\n ${avatarHtml}\n <div class=\"wc-success-user-info\">\n <div class=\"wc-success-user-name\">${displayName}</div>\n ${address ? `<div class=\"wc-success-user-addr\" title=\"${address}\">${address}</div>` : ''}\n </div>\n </div>\n <button class=\"wc-success-done\" data-action=\"done\">Done</button>\n </div>\n </div>\n <div class=\"wc-footer\">Powered by WalletConnect</div>\n `;\n\n this.render(html);\n\n this.overlay\n ?.querySelector('[data-action=\"done\"]')\n ?.addEventListener('click', onDone);\n }\n\n updateStatus(text: string, showSpinner = true): void {\n const el = this.overlay?.querySelector('.wc-status');\n if (el) {\n el.innerHTML = `\n ${showSpinner ? '<div class=\"wc-spinner\"></div>' : ''}\n <span>${text}</span>\n `;\n }\n }\n\n private render(innerHtml: string): void {\n this.destroy();\n\n const el = document.createElement('div');\n el.id = MODAL_ID;\n el.innerHTML = `\n <style>${getStyles(this.theme)}</style>\n <div class=\"wc-overlay\">\n <div class=\"wc-modal\">${innerHtml}</div>\n </div>\n `;\n\n document.body.appendChild(el);\n this.overlay = el;\n\n this.overlay\n .querySelector('[data-action=\"close\"]')\n ?.addEventListener('click', () => { this.onClose(); this.destroy(); });\n\n this.overlay\n .querySelector('.wc-overlay')\n ?.addEventListener('click', (e) => {\n if ((e.target as HTMLElement).classList.contains('wc-overlay')) {\n this.onClose();\n this.destroy();\n }\n });\n }\n\n destroy(): void {\n document.getElementById(MODAL_ID)?.remove();\n this.overlay = null;\n }\n}\n","import type {\n WalletConnectConfig,\n WalletMeta,\n ConnectResult,\n ConnectSession,\n InitSessionResponse,\n WalletConnectEventType,\n WalletConnectEventCallback,\n} from './types';\nimport { WsTransport, PollingTransport } from './transport';\nimport { Modal } from './modal';\n\nconst STORAGE_KEY_PREFIX = '__wc_session_';\nconst DEFAULT_REGISTRY_URL = 'https://cdn.jsdelivr.net/npm/toncorp-wallet-connect-sdk@latest/registry.json';\n\nexport class BaseWalletConnect {\n protected config: Required<\n Pick<WalletConnectConfig, 'appId' | 'registryUrl' | 'theme'>\n > &\n Pick<WalletConnectConfig, 'walletId'>;\n\n private listeners: Map<WalletConnectEventType, Set<WalletConnectEventCallback>> = new Map();\n private modal: Modal | null = null;\n private wsTransport: WsTransport | null = null;\n private pollingTransport: PollingTransport | null = null;\n private currentResult: ConnectResult | null = null;\n\n constructor(config: WalletConnectConfig) {\n this.config = {\n appId: config.appId,\n registryUrl: config.registryUrl || DEFAULT_REGISTRY_URL,\n walletId: config.walletId,\n theme: config.theme || 'light',\n };\n\n this.restoreSession();\n this.registerGlobal();\n }\n\n // ── Public API ──\n\n async connect(): Promise<ConnectResult> {\n if (this.currentResult) {\n return this.currentResult;\n }\n\n const wallets = await this.fetchWallets();\n const filtered = this.filterWallets(wallets);\n\n if (filtered.length === 0) {\n throw new Error('No supported wallets available');\n }\n\n return new Promise<ConnectResult>((resolve, reject) => {\n const onClose = () => {\n this.cleanup();\n reject(new Error('User closed modal'));\n };\n\n this.modal = new Modal(this.config.theme, onClose);\n\n if (filtered.length === 1) {\n this.startConnect(filtered[0], false, resolve, reject);\n } else {\n this.modal.showWalletPicker(filtered, (wallet) => {\n this.startConnect(wallet, true, resolve, reject);\n });\n }\n });\n }\n\n disconnect(): void {\n // Find session from this instance or any other connected instance\n let session = this.currentResult?.session;\n if (!session && typeof window !== 'undefined') {\n for (const key of Object.keys(window)) {\n const inst = (window as any)[key];\n if (inst instanceof BaseWalletConnect && inst.currentResult?.session) {\n session = inst.currentResult.session;\n break;\n }\n }\n }\n\n // Call disconnect API (fire-and-forget)\n if (session) {\n const baseUrl = session.apiUrl.replace(/\\/$/, '');\n fetch(`${baseUrl}/connect/disconnect-by-token`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ sessionToken: session.sessionToken }),\n }).catch(() => {});\n }\n\n // Clear all localStorage keys and window instances\n this.currentResult = null;\n this.removeStoredSession();\n this.clearAllRelatedSessions();\n this.cleanup();\n this.emit('disconnect');\n }\n\n isConnected(): boolean {\n return this.currentResult !== null;\n }\n\n getWallet(): ConnectResult | null {\n return this.currentResult;\n }\n\n on(event: WalletConnectEventType, cb: WalletConnectEventCallback): void {\n if (!this.listeners.has(event)) {\n this.listeners.set(event, new Set());\n }\n this.listeners.get(event)!.add(cb);\n }\n\n off(event: WalletConnectEventType, cb: WalletConnectEventCallback): void {\n this.listeners.get(event)?.delete(cb);\n }\n\n // ── Internal ──\n\n private get storageKey(): string {\n const walletId = this.config.walletId;\n const suffix = Array.isArray(walletId)\n ? walletId.sort().join('_')\n : walletId || 'all';\n return `${STORAGE_KEY_PREFIX}${suffix}__`;\n }\n\n private async fetchWallets(): Promise<WalletMeta[]> {\n const url = this.config.registryUrl.replace(/\\/$/, '');\n const res = await fetch(url);\n if (!res.ok) throw new Error('Failed to fetch wallets');\n return res.json();\n }\n\n private filterWallets(wallets: WalletMeta[]): WalletMeta[] {\n if (!this.config.walletId) return wallets;\n\n const ids = Array.isArray(this.config.walletId)\n ? this.config.walletId\n : [this.config.walletId];\n\n return wallets.filter((w) => ids.includes(w.walletId));\n }\n\n private async startConnect(\n wallet: WalletMeta,\n showBack: boolean,\n resolve: (result: ConnectResult) => void,\n reject: (error: Error) => void,\n ): Promise<void> {\n try {\n const session = await this.initSession(wallet);\n\n this.modal?.showConnect(wallet, session.deeplink, showBack, () => {\n this.cleanup();\n this.connect().then(resolve).catch(reject);\n });\n\n this.listenForConfirmation(\n wallet.apiUrl,\n session.sessionToken,\n (result) => {\n // Attach session info for disconnect\n result.session = {\n sessionToken: session.sessionToken,\n walletId: wallet.walletId,\n apiUrl: wallet.apiUrl,\n };\n this.currentResult = result;\n this.storeSession(result);\n this.syncToWalletInstance(wallet.walletId, result);\n this.emit('connect', result);\n\n // Show success screen\n this.modal?.showSuccess(\n wallet,\n result.wallet?.address || null,\n result.user || null,\n () => {\n this.modal?.destroy();\n this.modal = null;\n resolve(result);\n },\n );\n },\n () => {\n this.modal?.updateStatus('Connection rejected', false);\n setTimeout(() => {\n this.modal?.destroy();\n this.modal = null;\n reject(new Error('Connection rejected by user'));\n }, 1500);\n },\n () => {\n this.modal?.updateStatus('Session expired', false);\n this.emit('session_expired');\n setTimeout(() => {\n this.modal?.destroy();\n this.modal = null;\n reject(new Error('Session expired'));\n }, 1500);\n },\n );\n } catch (err) {\n this.modal?.destroy();\n this.modal = null;\n reject(err instanceof Error ? err : new Error(String(err)));\n }\n }\n\n private async initSession(wallet: WalletMeta): Promise<InitSessionResponse> {\n const baseUrl = wallet.apiUrl.replace(/\\/$/, '');\n const res = await fetch(`${baseUrl}/connect/init`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n appId: this.config.appId,\n walletId: wallet.walletId,\n origin: typeof window !== 'undefined' ? window.location.origin : '',\n }),\n });\n if (!res.ok) throw new Error('Failed to init session');\n return res.json();\n }\n\n private listenForConfirmation(\n apiUrl: string,\n sessionToken: string,\n onConfirmed: (result: ConnectResult) => void,\n onRejected: () => void,\n onExpired: () => void,\n ): void {\n let resolved = false;\n\n const wrap = <T extends (...args: any[]) => void>(fn: T): T =>\n ((...args: any[]) => {\n if (resolved) return;\n resolved = true;\n this.wsTransport?.close();\n this.pollingTransport?.stop();\n fn(...args);\n }) as unknown as T;\n\n const wrappedConfirm = wrap(onConfirmed);\n const wrappedReject = wrap(onRejected);\n const wrappedExpire = wrap(onExpired);\n\n // Start polling immediately as primary transport\n this.pollingTransport = new PollingTransport(\n apiUrl,\n sessionToken,\n wrappedConfirm,\n wrappedReject,\n wrappedExpire,\n (msg) => this.emit('error', msg),\n );\n this.pollingTransport.start();\n\n // Also try WS for faster response\n this.wsTransport = new WsTransport(\n apiUrl,\n sessionToken,\n wrappedConfirm,\n wrappedReject,\n wrappedExpire,\n () => {}, // WS fail is fine, polling is running\n );\n this.wsTransport.connect();\n }\n\n private cleanup(): void {\n this.wsTransport?.close();\n this.wsTransport = null;\n this.pollingTransport?.stop();\n this.pollingTransport = null;\n this.modal?.destroy();\n this.modal = null;\n }\n\n private emit(event: WalletConnectEventType, data?: any): void {\n this.listeners.get(event)?.forEach((cb) => cb(data));\n }\n\n // ── Persistence ──\n\n private storeSession(result: ConnectResult): void {\n try {\n localStorage.setItem(this.storageKey, JSON.stringify(result));\n } catch {\n // localStorage unavailable\n }\n }\n\n private restoreSession(): void {\n try {\n const stored = localStorage.getItem(this.storageKey);\n if (stored) {\n this.currentResult = JSON.parse(stored);\n }\n } catch {\n // ignore\n }\n }\n\n private removeStoredSession(): void {\n try {\n localStorage.removeItem(this.storageKey);\n } catch {\n // ignore\n }\n }\n\n // ── Global window registration ──\n\n private registerGlobal(): void {\n if (typeof window === 'undefined') return;\n\n const walletId = this.config.walletId;\n const key = Array.isArray(walletId)\n ? walletId[0]\n : walletId || 'walletconnect';\n\n (window as any)[key] = this;\n }\n\n /** Sync connect result to the specific wallet instance on window (e.g. window.onedollar) */\n private syncToWalletInstance(walletId: string, result: ConnectResult): void {\n if (typeof window === 'undefined') return;\n\n const target = (window as any)[walletId];\n if (target && target !== this && target instanceof BaseWalletConnect) {\n (target as any).currentResult = result;\n (target as any).storeSession(result);\n }\n }\n\n /** Clear all related sessions from all window instances and localStorage */\n private clearAllRelatedSessions(): void {\n if (typeof window === 'undefined') return;\n\n // Find all BaseWalletConnect instances on window and clear them\n try {\n for (const key of Object.keys(window)) {\n const inst = (window as any)[key];\n if (inst && inst !== this && inst instanceof BaseWalletConnect) {\n (inst as any).currentResult = null;\n (inst as any).removeStoredSession();\n }\n }\n } catch {\n // ignore\n }\n\n // Clear all wc localStorage keys\n try {\n const toRemove: string[] = [];\n for (let i = 0; i < localStorage.length; i++) {\n const k = localStorage.key(i);\n if (k && k.startsWith(STORAGE_KEY_PREFIX)) {\n toRemove.push(k);\n }\n }\n toRemove.forEach((k) => localStorage.removeItem(k));\n } catch {\n // ignore\n }\n }\n}\n","import { BaseWalletConnect } from './client';\nimport type { WalletConnectConfig } from './types';\n\nexport class OneDollarConnect extends BaseWalletConnect {\n constructor(config: Omit<WalletConnectConfig, 'walletId'>) {\n super({ ...config, walletId: 'onedollar' });\n }\n}\n","import { BaseWalletConnect } from './client';\nimport type { WalletConnectConfig } from './types';\n\nexport class TonPassConnect extends BaseWalletConnect {\n constructor(config: Omit<WalletConnectConfig, 'walletId'>) {\n super({ ...config, walletId: 'tonpass' });\n }\n}\n"],"names":["WsTransport","constructor","apiUrl","sessionToken","onConfirmed","onRejected","onExpired","onError","this","ws","reconnectTimer","closed","connect","replace","connectSocketIO","baseUrl","fetch","then","res","text","body","jsonStr","sid","JSON","parse","wsUrl","WebSocket","onopen","send","onmessage","event","msg","data","startsWith","payload","slice","eventName","handleEvent","onclose","scheduleReconnect","onerror","catch","close","setTimeout","clearTimeout","PollingTransport","timer","stopped","start","poll","setInterval","ok","json","status","wallet","user","stop","clearInterval","MODAL_ID","Modal","theme","onClose","overlay","showWalletPicker","wallets","onSelect","html","length","map","w","walletId","icon","name","charAt","join","description","render","forEach","querySelector","addEventListener","showConnect","deeplink","showBack","onBack","qrUrl","size","encodeURIComponent","generateQRDataUrl","tabs","querySelectorAll","panels","tab","target","dataset","t","classList","remove","add","p","style","display","panel","showSuccess","address","onDone","displayName","username","initials","toUpperCase","avatar","updateStatus","showSpinner","el","innerHTML","innerHtml","destroy","document","createElement","id","isDark","bg","bgSecondary","textSecondary","border","accent","accentDark","getStyles","appendChild","e","contains","getElementById","STORAGE_KEY_PREFIX","BaseWalletConnect","config","listeners","Map","modal","wsTransport","pollingTransport","currentResult","appId","registryUrl","restoreSession","registerGlobal","fetchWallets","filtered","filterWallets","Error","Promise","resolve","reject","cleanup","startConnect","disconnect","session","window","key","Object","keys","inst","method","headers","stringify","removeStoredSession","clearAllRelatedSessions","emit","isConnected","getWallet","on","cb","has","set","Set","get","off","delete","storageKey","suffix","Array","isArray","sort","url","ids","filter","includes","initSession","listenForConfirmation","result","storeSession","syncToWalletInstance","err","String","origin","location","resolved","wrap","fn","args","wrappedConfirm","wrappedReject","wrappedExpire","localStorage","setItem","stored","getItem","removeItem","toRemove","i","k","push","super"],"mappings":"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"}
package/dist/index.esm.js CHANGED
@@ -1,2 +1,2 @@
1
- class e{constructor(e,n,t,s,i,o){this.apiUrl=e,this.sessionToken=n,this.onConfirmed=t,this.onRejected=s,this.onExpired=i,this.onError=o,this.ws=null,this.reconnectTimer=null,this.closed=!1}connect(){this.closed=!1;this.apiUrl.replace(/^http/,"ws").replace(/\/$/,"");this.sessionToken;try{this.connectSocketIO()}catch{this.onError("WebSocket connection failed")}}connectSocketIO(){const e=this.apiUrl.replace(/\/$/,"");fetch(`${e}/walletconnect/?EIO=4&transport=polling`).then(e=>e.text()).then(n=>{const t=n.replace(/^\d+/,""),s=JSON.parse(t).sid,i=`${e.replace(/^http/,"ws")}/walletconnect/?EIO=4&transport=websocket&sid=${s}`;this.ws=new WebSocket(i),this.ws.onopen=()=>{this.ws.send("2probe")},this.ws.onmessage=e=>{const n=e.data;if("3probe"!==n)if(n.startsWith("42"))try{const e=JSON.parse(n.slice(2)),[t,s]=e;this.handleEvent(t,s)}catch{}else"2"===n&&this.ws.send("3");else this.ws.send("5")},this.ws.onclose=()=>{this.closed||this.scheduleReconnect()},this.ws.onerror=()=>{this.closed||this.scheduleReconnect()}}).catch(()=>{this.closed||this.scheduleReconnect()})}handleEvent(e,n){switch(e){case"session_confirmed":this.onConfirmed(n),this.close();break;case"session_rejected":this.onRejected(),this.close();break;case"session_expired":this.onExpired(),this.close()}}scheduleReconnect(){this.closed||this.reconnectTimer||(this.reconnectTimer=setTimeout(()=>{this.reconnectTimer=null,this.connectSocketIO()},3e3))}close(){this.closed=!0,this.reconnectTimer&&(clearTimeout(this.reconnectTimer),this.reconnectTimer=null),this.ws&&(this.ws.close(),this.ws=null)}}class n{constructor(e,n,t,s,i,o){this.apiUrl=e,this.sessionToken=n,this.onConfirmed=t,this.onRejected=s,this.onExpired=i,this.onError=o,this.timer=null,this.stopped=!1}start(){this.stopped=!1,this.poll(),this.timer=setInterval(()=>this.poll(),2e3)}async poll(){if(!this.stopped)try{const e=this.apiUrl.replace(/\/$/,""),n=await fetch(`${e}/connect/status?token=${this.sessionToken}`);if(!n.ok)return;const t=await n.json();switch(t.status){case"CONFIRMED":this.onConfirmed({wallet:t.wallet,user:t.user}),this.stop();break;case"REJECTED":this.onRejected(),this.stop();break;case"EXPIRED":this.onExpired(),this.stop()}}catch{}}stop(){this.stopped=!0,this.timer&&(clearInterval(this.timer),this.timer=null)}}const t="__wc_modal__";class s{constructor(e,n){this.overlay=null,this.theme=e,this.onClose=n}showWalletPicker(e,n){const t=`\n <div class="wc-handle"></div>\n <div class="wc-header">\n <h3 class="wc-title">Connect your wallet</h3>\n <button class="wc-close" data-action="close">&#10005;</button>\n </div>\n <p class="wc-subtitle">Choose a wallet to connect to this app</p>\n <div class="wc-body">${e.length>=3?`<ul class="wc-wallet-grid">${e.map(e=>`\n <li class="wc-wallet-grid-item" data-wallet-id="${e.walletId}">\n ${e.icon?`<img class="wc-wallet-grid-icon" src="${e.icon}" alt="${e.name}" />`:`<div class="wc-wallet-grid-icon-placeholder">${e.name.charAt(0)}</div>`}\n <span class="wc-wallet-grid-name">${e.name}</span>\n </li>`).join("")}</ul>`:`<ul class="wc-wallet-list">${e.map(e=>`\n <li class="wc-wallet-item" data-wallet-id="${e.walletId}">\n ${e.icon?`<img class="wc-wallet-list-icon" src="${e.icon}" alt="${e.name}" />`:`<div class="wc-wallet-list-icon-placeholder">${e.name.charAt(0)}</div>`}\n <div class="wc-wallet-item-info">\n <div class="wc-wallet-item-name">${e.name}</div>\n ${e.description?`<div class="wc-wallet-item-desc">${e.description}</div>`:""}\n </div>\n <span class="wc-wallet-item-arrow">&#8250;</span>\n </li>`).join("")}</ul>`}</div>\n <div class="wc-footer">Powered by WalletConnect</div>\n `;this.render(t),e.forEach(e=>{this.overlay?.querySelector(`[data-wallet-id="${e.walletId}"]`)?.addEventListener("click",()=>n(e))})}showConnect(e,n,t,s){const i=function(e,n=220){return`https://api.qrserver.com/v1/create-qr-code/?size=${n}x${n}&data=${encodeURIComponent(e)}&margin=8`}(n),o=`\n <div class="wc-handle"></div>\n <div class="wc-header">\n <div class="wc-header-left">\n ${t?'<button class="wc-back" data-action="back">&#8592;</button>':""}\n ${e.icon?`<img class="wc-header-icon" src="${e.icon}" />`:""}\n <h3 class="wc-title">${e.name}</h3>\n </div>\n <button class="wc-close" data-action="close">&#10005;</button>\n </div>\n <p class="wc-subtitle">Approve the connection request in your wallet</p>\n <div class="wc-body">\n <div class="wc-tabs">\n <button class="wc-tab active" data-tab="mobile">Mobile</button>\n <button class="wc-tab" data-tab="qr">QR Code</button>\n </div>\n <div data-panel="mobile">\n <a class="wc-deeplink-btn" href="${n}" target="_blank">\n <svg width="20" height="20" viewBox="0 0 24 24" fill="currentColor"><path d="M11.944 0A12 12 0 1 0 24 12.056A12.01 12.01 0 0 0 11.944 0Zm4.962 7.224c.1-.002.321.023.465.14a.506.506 0 0 1 .171.325c.016.093.036.306.02.472c-.18 1.898-.962 6.502-1.36 8.627c-.168.9-.499 1.201-.82 1.23c-.696.065-1.225-.46-1.9-.902c-1.056-.693-1.653-1.124-2.678-1.8c-1.185-.78-.417-1.21.258-1.91c.177-.184 3.247-2.977 3.307-3.23c.007-.032.014-.15-.056-.212s-.174-.041-.249-.024c-.106.024-1.793 1.14-5.061 3.345c-.48.33-.913.49-1.302.48c-.428-.008-1.252-.241-1.865-.44c-.752-.245-1.349-.374-1.297-.789c.027-.216.325-.437.893-.663c3.498-1.524 5.83-2.529 6.998-3.014c3.332-1.386 4.025-1.627 4.476-1.635Z"/></svg>\n Open in Telegram\n </a>\n </div>\n <div data-panel="qr" style="display:none">\n <div class="wc-qr-container">\n <div class="wc-qr-wrap">\n <img src="${i}" width="220" height="220" alt="QR" />\n </div>\n <div class="wc-qr-hint">Scan with your phone camera or wallet app</div>\n </div>\n </div>\n <div class="wc-status">\n <div class="wc-spinner"></div>\n <span>Waiting for confirmation...</span>\n </div>\n </div>\n <div class="wc-footer">Powered by WalletConnect</div>\n `;this.render(o);const r=this.overlay?.querySelectorAll(".wc-tab"),a=this.overlay?.querySelectorAll("[data-panel]");r?.forEach(e=>{e.addEventListener("click",()=>{const n=e.dataset.tab;r.forEach(e=>e.classList.remove("active")),e.classList.add("active"),a?.forEach(e=>{e.style.display=e.dataset.panel===n?"block":"none"})})}),t&&s&&this.overlay?.querySelector('[data-action="back"]')?.addEventListener("click",s)}showSuccess(e,n,t,s){const i=t?.username||"User",o=i.slice(0,2).toUpperCase(),r=`\n <div class="wc-handle"></div>\n <div class="wc-header">\n <h3 class="wc-title">Connected</h3>\n <button class="wc-close" data-action="close">&#10005;</button>\n </div>\n <div class="wc-body">\n <div class="wc-success">\n <div class="wc-success-check"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg></div>\n <div class="wc-success-title">Connection Successful</div>\n <div class="wc-success-user">\n ${t?.avatar?`<img class="wc-success-avatar" src="${t.avatar}" alt="${i}" />`:`<div class="wc-success-avatar-placeholder">${o}</div>`}\n <div class="wc-success-user-info">\n <div class="wc-success-user-name">${i}</div>\n ${n?`<div class="wc-success-user-addr" title="${n}">${n}</div>`:""}\n </div>\n </div>\n <button class="wc-success-done" data-action="done">Done</button>\n </div>\n </div>\n <div class="wc-footer">Powered by WalletConnect</div>\n `;this.render(r),this.overlay?.querySelector('[data-action="done"]')?.addEventListener("click",s)}updateStatus(e,n=!0){const t=this.overlay?.querySelector(".wc-status");t&&(t.innerHTML=`\n ${n?'<div class="wc-spinner"></div>':""}\n <span>${e}</span>\n `)}render(e){this.destroy();const n=document.createElement("div");n.id=t,n.innerHTML=`\n <style>${function(e){const n="dark"===e,t=n?"#141414":"#ffffff",s=n?"#1e1e1e":"#f4f4f4",i=n?"#ffffff":"#141414",o=n?"#9a9a9a":"#787878",r=n?"#2a2a2a":"#e4e4e4",a="#2bea6a",c="#1db954";return`\n @keyframes wc-fadeIn { from{opacity:0} to{opacity:1} }\n @keyframes wc-slideUp {\n from{opacity:0;transform:translateY(100%)}\n to{opacity:1;transform:translateY(0)}\n }\n .wc-overlay {\n position:fixed; inset:0; z-index:99999;\n background:rgba(0,0,0,${n?.75:.45});\n display:flex; align-items:flex-end; justify-content:center;\n font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;\n backdrop-filter:blur(6px); -webkit-backdrop-filter:blur(6px);\n animation:wc-fadeIn .2s ease;\n }\n @media(min-width:480px){\n .wc-overlay{align-items:center}\n .wc-modal{border-radius:24px;max-height:85vh}\n }\n .wc-modal {\n background:${t}; width:100%; max-width:420px;\n border-radius:24px 24px 0 0; overflow:hidden; color:${i};\n box-shadow:0 -8px 40px rgba(0,0,0,${n?.5:.15});\n animation:wc-slideUp .3s cubic-bezier(.16,1,.3,1);\n max-height:90vh; overflow-y:auto;\n }\n\n /* Handle bar */\n .wc-handle {\n width:36px; height:4px; border-radius:2px;\n background:${r}; margin:10px auto 0;\n }\n\n /* Header */\n .wc-header {\n display:flex; align-items:center; justify-content:space-between;\n padding:20px 24px 0;\n }\n .wc-header-left {\n display:flex; align-items:center; gap:10px;\n }\n .wc-header-icon {\n width:32px; height:32px; border-radius:10px; object-fit:cover;\n }\n .wc-title { font-size:17px; font-weight:700; margin:0; }\n .wc-close {\n width:30px; height:30px; display:flex; align-items:center; justify-content:center;\n background:${s}; border:none; border-radius:50%;\n cursor:pointer; font-size:14px; color:${o};\n transition:all .15s;\n }\n .wc-close:hover { background:${r}; color:${i}; }\n .wc-subtitle {\n font-size:13px; color:${o}; margin:8px 24px 0;\n line-height:1.4;\n }\n\n .wc-body { padding:20px 24px 24px; }\n\n /* Grid wallet picker */\n .wc-wallet-grid {\n display:grid; grid-template-columns:repeat(4,1fr);\n gap:16px 12px; list-style:none; margin:0; padding:0;\n }\n .wc-wallet-grid-item {\n display:flex; flex-direction:column; align-items:center;\n gap:8px; cursor:pointer; padding:8px 4px; border-radius:16px;\n transition:all .15s; border:2px solid transparent;\n }\n .wc-wallet-grid-item:hover {\n background:${s}; border-color:${r};\n }\n .wc-wallet-grid-icon {\n width:56px; height:56px; border-radius:16px;\n object-fit:cover; box-shadow:0 2px 8px rgba(0,0,0,${n?.3:.08});\n }\n .wc-wallet-grid-icon-placeholder {\n width:56px; height:56px; border-radius:16px;\n background:linear-gradient(135deg,${c},${a});\n display:flex; align-items:center; justify-content:center;\n color:#fff; font-weight:800; font-size:22px;\n box-shadow:0 2px 8px rgba(0,0,0,${n?.3:.08});\n }\n .wc-wallet-grid-name {\n font-size:11px; font-weight:500; text-align:center;\n color:${o}; line-height:1.2;\n max-width:72px; overflow:hidden; text-overflow:ellipsis;\n white-space:nowrap;\n }\n\n /* List wallet picker (alternative) */\n .wc-wallet-list { list-style:none; margin:0; padding:0; }\n .wc-wallet-item {\n display:flex; align-items:center; gap:14px;\n padding:12px 16px; border-radius:16px; cursor:pointer;\n border:1.5px solid ${r}; margin-bottom:8px;\n transition:all .15s;\n }\n .wc-wallet-item:hover {\n background:${s}; border-color:${a};\n }\n .wc-wallet-list-icon {\n width:40px; height:40px; border-radius:12px; object-fit:cover;\n }\n .wc-wallet-list-icon-placeholder {\n width:40px; height:40px; border-radius:12px;\n background:linear-gradient(135deg,${c},${a});\n display:flex; align-items:center; justify-content:center;\n color:#fff; font-weight:700; font-size:16px;\n }\n .wc-wallet-item-info { flex:1; }\n .wc-wallet-item-name { font-size:14px; font-weight:600; }\n .wc-wallet-item-desc { font-size:11px; color:${o}; margin-top:1px; }\n .wc-wallet-item-arrow { color:${o}; font-size:16px; }\n\n /* Tabs */\n .wc-tabs {\n display:flex; background:${s}; border-radius:12px;\n padding:3px; margin-bottom:20px;\n }\n .wc-tab {\n flex:1; padding:10px; text-align:center; cursor:pointer;\n font-size:13px; font-weight:600; background:transparent;\n border:none; color:${o}; border-radius:10px;\n transition:all .2s;\n }\n .wc-tab:hover { color:${i}; }\n .wc-tab.active {\n background:${t}; color:${i};\n box-shadow:0 1px 4px rgba(0,0,0,${n?.3:.08});\n }\n\n /* Deeplink */\n .wc-deeplink-btn {\n display:flex; align-items:center; justify-content:center; gap:10px;\n width:100%; padding:16px; border:none; border-radius:16px;\n background:linear-gradient(135deg,${c},${a});\n color:#fff; font-size:15px; font-weight:700; cursor:pointer;\n text-decoration:none; transition:all .2s;\n box-shadow:0 4px 20px rgba(43,234,106,0.2);\n box-sizing:border-box;\n }\n .wc-deeplink-btn:hover {\n transform:translateY(-1px);\n box-shadow:0 6px 28px rgba(43,234,106,0.3);\n }\n\n /* QR */\n .wc-qr-container {\n display:flex; flex-direction:column; align-items:center; gap:16px;\n }\n .wc-qr-wrap {\n padding:16px; background:#fff; border-radius:20px;\n box-shadow:0 2px 16px rgba(0,0,0,${n?.2:.06});\n }\n .wc-qr-wrap img { display:block; border-radius:4px; }\n .wc-qr-hint { font-size:12px; color:${o}; text-align:center; }\n\n /* Status */\n .wc-status {\n display:flex; align-items:center; justify-content:center;\n gap:10px; padding:20px 0 4px; font-size:13px; color:${o};\n }\n .wc-spinner {\n width:16px; height:16px; border:2px solid ${r};\n border-top-color:${a}; border-radius:50%;\n animation:wc-spin .7s linear infinite;\n }\n @keyframes wc-spin { to{transform:rotate(360deg)} }\n\n /* Back */\n .wc-back {\n background:none; border:none; cursor:pointer; padding:0;\n color:${o}; display:flex; align-items:center;\n transition:color .15s; font-size:18px;\n }\n .wc-back:hover { color:${i}; }\n\n /* Footer */\n .wc-footer {\n text-align:center; padding:4px 0 20px;\n font-size:11px; color:${n?"#555":"#bbb"};\n }\n\n /* Success screen */\n .wc-success {\n display:flex; flex-direction:column; align-items:center;\n padding:12px 0 4px; gap:20px;\n }\n .wc-success-check {\n width:64px; height:64px; border-radius:50%;\n background:linear-gradient(135deg,${c},${a});\n display:flex; align-items:center; justify-content:center;\n box-shadow:0 4px 20px rgba(43,234,106,0.25);\n animation:wc-popIn .4s cubic-bezier(.16,1,.3,1);\n }\n @keyframes wc-popIn {\n from{transform:scale(0);opacity:0}\n 50%{transform:scale(1.15)}\n to{transform:scale(1);opacity:1}\n }\n .wc-success-check svg { width:32px; height:32px; color:#fff; }\n .wc-success-title {\n font-size:18px; font-weight:700; color:${i};\n }\n .wc-success-user {\n display:flex; align-items:center; gap:14px;\n background:${s}; border-radius:16px;\n padding:16px 18px; width:100%; box-sizing:border-box;\n }\n .wc-success-avatar {\n width:48px; height:48px; border-radius:50%; object-fit:cover;\n flex-shrink:0; border:2px solid ${r};\n }\n .wc-success-avatar-placeholder {\n width:48px; height:48px; border-radius:50%;\n background:linear-gradient(135deg,${c},${a});\n display:flex; align-items:center; justify-content:center;\n color:#fff; font-weight:700; font-size:18px; flex-shrink:0;\n border:2px solid ${r};\n }\n .wc-success-user-info { flex:1; min-width:0; }\n .wc-success-user-name { font-size:15px; font-weight:600; color:${i}; }\n .wc-success-user-addr {\n font-size:12px; color:${o}; margin-top:4px;\n font-family:'SF Mono',Monaco,Consolas,monospace;\n word-break:break-all; line-height:1.4;\n }\n .wc-success-done {\n width:100%; padding:14px; border:none; border-radius:14px;\n background:linear-gradient(135deg,${c},${a});\n color:#fff; font-size:14px; font-weight:700; cursor:pointer;\n transition:all .2s;\n box-shadow:0 4px 16px rgba(43,234,106,0.2);\n }\n .wc-success-done:hover {\n transform:translateY(-1px);\n box-shadow:0 6px 24px rgba(43,234,106,0.3);\n }\n `}(this.theme)}</style>\n <div class="wc-overlay">\n <div class="wc-modal">${e}</div>\n </div>\n `,document.body.appendChild(n),this.overlay=n,this.overlay.querySelector('[data-action="close"]')?.addEventListener("click",()=>{this.onClose(),this.destroy()}),this.overlay.querySelector(".wc-overlay")?.addEventListener("click",e=>{e.target.classList.contains("wc-overlay")&&(this.onClose(),this.destroy())})}destroy(){document.getElementById(t)?.remove(),this.overlay=null}}const i="__wc_session_";class o{constructor(e){this.listeners=new Map,this.modal=null,this.wsTransport=null,this.pollingTransport=null,this.currentResult=null,this.config={appId:e.appId,registryUrl:e.registryUrl||"https://cdn.jsdelivr.net/npm/toncorp-wallet-connect-sdk@latest/registry.json",walletId:e.walletId,theme:e.theme||"light"},this.restoreSession(),this.registerGlobal()}async connect(){if(this.currentResult)return this.currentResult;const e=await this.fetchWallets(),n=this.filterWallets(e);if(0===n.length)throw new Error("No supported wallets available");return new Promise((e,t)=>{this.modal=new s(this.config.theme,()=>{this.cleanup(),t(new Error("User closed modal"))}),1===n.length?this.startConnect(n[0],!1,e,t):this.modal.showWalletPicker(n,n=>{this.startConnect(n,!0,e,t)})})}disconnect(){const e=this.currentResult?.session;if(e){const n=e.apiUrl.replace(/\/$/,"");fetch(`${n}/connect/disconnect-by-token`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({sessionToken:e.sessionToken})}).catch(()=>{})}this.currentResult=null,this.removeStoredSession(),this.clearAllRelatedSessions(),this.cleanup(),this.emit("disconnect")}isConnected(){return null!==this.currentResult}getWallet(){return this.currentResult}on(e,n){this.listeners.has(e)||this.listeners.set(e,new Set),this.listeners.get(e).add(n)}off(e,n){this.listeners.get(e)?.delete(n)}get storageKey(){const e=this.config.walletId,n=Array.isArray(e)?e.sort().join("_"):e||"all";return`${i}${n}__`}async fetchWallets(){const e=this.config.registryUrl.replace(/\/$/,""),n=await fetch(e);if(!n.ok)throw new Error("Failed to fetch wallets");return n.json()}filterWallets(e){if(!this.config.walletId)return e;const n=Array.isArray(this.config.walletId)?this.config.walletId:[this.config.walletId];return e.filter(e=>n.includes(e.walletId))}async startConnect(e,n,t,s){try{const i=await this.initSession(e);this.modal?.showConnect(e,i.deeplink,n,()=>{this.cleanup(),this.connect().then(t).catch(s)}),this.listenForConfirmation(e.apiUrl,i.sessionToken,n=>{n.session={sessionToken:i.sessionToken,walletId:e.walletId,apiUrl:e.apiUrl},this.currentResult=n,this.storeSession(n),this.syncToWalletInstance(e.walletId,n),this.emit("connect",n),this.modal?.showSuccess(e,n.wallet?.address||null,n.user||null,()=>{this.modal?.destroy(),this.modal=null,t(n)})},()=>{this.modal?.updateStatus("Connection rejected",!1),setTimeout(()=>{this.modal?.destroy(),this.modal=null,s(new Error("Connection rejected by user"))},1500)},()=>{this.modal?.updateStatus("Session expired",!1),this.emit("session_expired"),setTimeout(()=>{this.modal?.destroy(),this.modal=null,s(new Error("Session expired"))},1500)})}catch(e){this.modal?.destroy(),this.modal=null,s(e instanceof Error?e:new Error(String(e)))}}async initSession(e){const n=e.apiUrl.replace(/\/$/,""),t=await fetch(`${n}/connect/init`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({appId:this.config.appId,walletId:e.walletId,origin:"undefined"!=typeof window?window.location.origin:""})});if(!t.ok)throw new Error("Failed to init session");return t.json()}listenForConfirmation(t,s,i,o,r){let a=!1;const c=e=>(...n)=>{a||(a=!0,this.wsTransport?.close(),this.pollingTransport?.stop(),e(...n))},l=c(i),d=c(o),p=c(r);this.pollingTransport=new n(t,s,l,d,p,e=>this.emit("error",e)),this.pollingTransport.start(),this.wsTransport=new e(t,s,l,d,p,()=>{}),this.wsTransport.connect()}cleanup(){this.wsTransport?.close(),this.wsTransport=null,this.pollingTransport?.stop(),this.pollingTransport=null,this.modal?.destroy(),this.modal=null}emit(e,n){this.listeners.get(e)?.forEach(e=>e(n))}storeSession(e){try{localStorage.setItem(this.storageKey,JSON.stringify(e))}catch{}}restoreSession(){try{const e=localStorage.getItem(this.storageKey);e&&(this.currentResult=JSON.parse(e))}catch{}}removeStoredSession(){try{localStorage.removeItem(this.storageKey)}catch{}}registerGlobal(){if("undefined"==typeof window)return;const e=this.config.walletId,n=Array.isArray(e)?e[0]:e||"walletconnect";window[n]=this}syncToWalletInstance(e,n){if("undefined"==typeof window)return;const t=window[e];t&&t!==this&&t instanceof o&&(t.currentResult=n,t.storeSession(n))}clearAllRelatedSessions(){if("undefined"==typeof window)return;const e=["tonpass","onedollar","walletconnect"];for(const n of e){const e=window[n];e&&e!==this&&e instanceof o&&(e.currentResult=null,e.removeStoredSession())}try{const e=[];for(let n=0;n<localStorage.length;n++){const t=localStorage.key(n);t&&t.startsWith(i)&&e.push(t)}e.forEach(e=>localStorage.removeItem(e))}catch{}}}class r extends o{constructor(e){super({...e,walletId:"tonpass"})}}class a extends o{constructor(e){super({...e,walletId:"onedollar"})}}export{o as BaseWalletConnect,a as OneDollarConnect,r as TonPassConnect};
1
+ class e{constructor(e,n,t,s,i,o){this.apiUrl=e,this.sessionToken=n,this.onConfirmed=t,this.onRejected=s,this.onExpired=i,this.onError=o,this.ws=null,this.reconnectTimer=null,this.closed=!1}connect(){this.closed=!1;this.apiUrl.replace(/^http/,"ws").replace(/\/$/,"");this.sessionToken;try{this.connectSocketIO()}catch{this.onError("WebSocket connection failed")}}connectSocketIO(){const e=this.apiUrl.replace(/\/$/,"");fetch(`${e}/walletconnect/?EIO=4&transport=polling`).then(e=>e.text()).then(n=>{const t=n.replace(/^\d+/,""),s=JSON.parse(t).sid,i=`${e.replace(/^http/,"ws")}/walletconnect/?EIO=4&transport=websocket&sid=${s}`;this.ws=new WebSocket(i),this.ws.onopen=()=>{this.ws.send("2probe")},this.ws.onmessage=e=>{const n=e.data;if("3probe"!==n)if(n.startsWith("42"))try{const e=JSON.parse(n.slice(2)),[t,s]=e;this.handleEvent(t,s)}catch{}else"2"===n&&this.ws.send("3");else this.ws.send("5")},this.ws.onclose=()=>{this.closed||this.scheduleReconnect()},this.ws.onerror=()=>{this.closed||this.scheduleReconnect()}}).catch(()=>{this.closed||this.scheduleReconnect()})}handleEvent(e,n){switch(e){case"session_confirmed":this.onConfirmed(n),this.close();break;case"session_rejected":this.onRejected(),this.close();break;case"session_expired":this.onExpired(),this.close()}}scheduleReconnect(){this.closed||this.reconnectTimer||(this.reconnectTimer=setTimeout(()=>{this.reconnectTimer=null,this.connectSocketIO()},3e3))}close(){this.closed=!0,this.reconnectTimer&&(clearTimeout(this.reconnectTimer),this.reconnectTimer=null),this.ws&&(this.ws.close(),this.ws=null)}}class n{constructor(e,n,t,s,i,o){this.apiUrl=e,this.sessionToken=n,this.onConfirmed=t,this.onRejected=s,this.onExpired=i,this.onError=o,this.timer=null,this.stopped=!1}start(){this.stopped=!1,this.poll(),this.timer=setInterval(()=>this.poll(),2e3)}async poll(){if(!this.stopped)try{const e=this.apiUrl.replace(/\/$/,""),n=await fetch(`${e}/connect/status?token=${this.sessionToken}`);if(!n.ok)return;const t=await n.json();switch(t.status){case"CONFIRMED":this.onConfirmed({wallet:t.wallet,user:t.user}),this.stop();break;case"REJECTED":this.onRejected(),this.stop();break;case"EXPIRED":this.onExpired(),this.stop()}}catch{}}stop(){this.stopped=!0,this.timer&&(clearInterval(this.timer),this.timer=null)}}const t="__wc_modal__";class s{constructor(e,n){this.overlay=null,this.theme=e,this.onClose=n}showWalletPicker(e,n){const t=`\n <div class="wc-handle"></div>\n <div class="wc-header">\n <h3 class="wc-title">Connect your wallet</h3>\n <button class="wc-close" data-action="close">&#10005;</button>\n </div>\n <p class="wc-subtitle">Choose a wallet to connect to this app</p>\n <div class="wc-body">${e.length>=3?`<ul class="wc-wallet-grid">${e.map(e=>`\n <li class="wc-wallet-grid-item" data-wallet-id="${e.walletId}">\n ${e.icon?`<img class="wc-wallet-grid-icon" src="${e.icon}" alt="${e.name}" />`:`<div class="wc-wallet-grid-icon-placeholder">${e.name.charAt(0)}</div>`}\n <span class="wc-wallet-grid-name">${e.name}</span>\n </li>`).join("")}</ul>`:`<ul class="wc-wallet-list">${e.map(e=>`\n <li class="wc-wallet-item" data-wallet-id="${e.walletId}">\n ${e.icon?`<img class="wc-wallet-list-icon" src="${e.icon}" alt="${e.name}" />`:`<div class="wc-wallet-list-icon-placeholder">${e.name.charAt(0)}</div>`}\n <div class="wc-wallet-item-info">\n <div class="wc-wallet-item-name">${e.name}</div>\n ${e.description?`<div class="wc-wallet-item-desc">${e.description}</div>`:""}\n </div>\n <span class="wc-wallet-item-arrow">&#8250;</span>\n </li>`).join("")}</ul>`}</div>\n <div class="wc-footer">Powered by WalletConnect</div>\n `;this.render(t),e.forEach(e=>{this.overlay?.querySelector(`[data-wallet-id="${e.walletId}"]`)?.addEventListener("click",()=>n(e))})}showConnect(e,n,t,s){const i=function(e,n=220){return`https://api.qrserver.com/v1/create-qr-code/?size=${n}x${n}&data=${encodeURIComponent(e)}&margin=8`}(n),o=`\n <div class="wc-handle"></div>\n <div class="wc-header">\n <div class="wc-header-left">\n ${t?'<button class="wc-back" data-action="back">&#8592;</button>':""}\n ${e.icon?`<img class="wc-header-icon" src="${e.icon}" />`:""}\n <h3 class="wc-title">${e.name}</h3>\n </div>\n <button class="wc-close" data-action="close">&#10005;</button>\n </div>\n <p class="wc-subtitle">Approve the connection request in your wallet</p>\n <div class="wc-body">\n <div class="wc-tabs">\n <button class="wc-tab active" data-tab="mobile">Mobile</button>\n <button class="wc-tab" data-tab="qr">QR Code</button>\n </div>\n <div data-panel="mobile">\n <a class="wc-deeplink-btn" href="${n}" target="_blank">\n <svg width="20" height="20" viewBox="0 0 24 24" fill="currentColor"><path d="M11.944 0A12 12 0 1 0 24 12.056A12.01 12.01 0 0 0 11.944 0Zm4.962 7.224c.1-.002.321.023.465.14a.506.506 0 0 1 .171.325c.016.093.036.306.02.472c-.18 1.898-.962 6.502-1.36 8.627c-.168.9-.499 1.201-.82 1.23c-.696.065-1.225-.46-1.9-.902c-1.056-.693-1.653-1.124-2.678-1.8c-1.185-.78-.417-1.21.258-1.91c.177-.184 3.247-2.977 3.307-3.23c.007-.032.014-.15-.056-.212s-.174-.041-.249-.024c-.106.024-1.793 1.14-5.061 3.345c-.48.33-.913.49-1.302.48c-.428-.008-1.252-.241-1.865-.44c-.752-.245-1.349-.374-1.297-.789c.027-.216.325-.437.893-.663c3.498-1.524 5.83-2.529 6.998-3.014c3.332-1.386 4.025-1.627 4.476-1.635Z"/></svg>\n Open in Telegram\n </a>\n </div>\n <div data-panel="qr" style="display:none">\n <div class="wc-qr-container">\n <div class="wc-qr-wrap">\n <img src="${i}" width="220" height="220" alt="QR" />\n </div>\n <div class="wc-qr-hint">Scan with your phone camera or wallet app</div>\n </div>\n </div>\n <div class="wc-status">\n <div class="wc-spinner"></div>\n <span>Waiting for confirmation...</span>\n </div>\n </div>\n <div class="wc-footer">Powered by WalletConnect</div>\n `;this.render(o);const r=this.overlay?.querySelectorAll(".wc-tab"),a=this.overlay?.querySelectorAll("[data-panel]");r?.forEach(e=>{e.addEventListener("click",()=>{const n=e.dataset.tab;r.forEach(e=>e.classList.remove("active")),e.classList.add("active"),a?.forEach(e=>{e.style.display=e.dataset.panel===n?"block":"none"})})}),t&&s&&this.overlay?.querySelector('[data-action="back"]')?.addEventListener("click",s)}showSuccess(e,n,t,s){const i=t?.username||"User",o=i.slice(0,2).toUpperCase(),r=`\n <div class="wc-handle"></div>\n <div class="wc-header">\n <h3 class="wc-title">Connected</h3>\n <button class="wc-close" data-action="close">&#10005;</button>\n </div>\n <div class="wc-body">\n <div class="wc-success">\n <div class="wc-success-check"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg></div>\n <div class="wc-success-title">Connection Successful</div>\n <div class="wc-success-user">\n ${t?.avatar?`<img class="wc-success-avatar" src="${t.avatar}" alt="${i}" />`:`<div class="wc-success-avatar-placeholder">${o}</div>`}\n <div class="wc-success-user-info">\n <div class="wc-success-user-name">${i}</div>\n ${n?`<div class="wc-success-user-addr" title="${n}">${n}</div>`:""}\n </div>\n </div>\n <button class="wc-success-done" data-action="done">Done</button>\n </div>\n </div>\n <div class="wc-footer">Powered by WalletConnect</div>\n `;this.render(r),this.overlay?.querySelector('[data-action="done"]')?.addEventListener("click",s)}updateStatus(e,n=!0){const t=this.overlay?.querySelector(".wc-status");t&&(t.innerHTML=`\n ${n?'<div class="wc-spinner"></div>':""}\n <span>${e}</span>\n `)}render(e){this.destroy();const n=document.createElement("div");n.id=t,n.innerHTML=`\n <style>${function(e){const n="dark"===e,t=n?"#141414":"#ffffff",s=n?"#1e1e1e":"#f4f4f4",i=n?"#ffffff":"#141414",o=n?"#9a9a9a":"#787878",r=n?"#2a2a2a":"#e4e4e4",a="#2bea6a",c="#1db954";return`\n @keyframes wc-fadeIn { from{opacity:0} to{opacity:1} }\n @keyframes wc-slideUp {\n from{opacity:0;transform:translateY(100%)}\n to{opacity:1;transform:translateY(0)}\n }\n .wc-overlay {\n position:fixed; inset:0; z-index:99999;\n background:rgba(0,0,0,${n?.75:.45});\n display:flex; align-items:flex-end; justify-content:center;\n font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;\n backdrop-filter:blur(6px); -webkit-backdrop-filter:blur(6px);\n animation:wc-fadeIn .2s ease;\n }\n @media(min-width:480px){\n .wc-overlay{align-items:center}\n .wc-modal{border-radius:24px;max-height:85vh}\n }\n .wc-modal {\n background:${t}; width:100%; max-width:420px;\n border-radius:24px 24px 0 0; overflow:hidden; color:${i};\n box-shadow:0 -8px 40px rgba(0,0,0,${n?.5:.15});\n animation:wc-slideUp .3s cubic-bezier(.16,1,.3,1);\n max-height:90vh; overflow-y:auto;\n }\n\n /* Handle bar */\n .wc-handle {\n width:36px; height:4px; border-radius:2px;\n background:${r}; margin:10px auto 0;\n }\n\n /* Header */\n .wc-header {\n display:flex; align-items:center; justify-content:space-between;\n padding:20px 24px 0;\n }\n .wc-header-left {\n display:flex; align-items:center; gap:10px;\n }\n .wc-header-icon {\n width:32px; height:32px; border-radius:10px; object-fit:cover;\n }\n .wc-title { font-size:17px; font-weight:700; margin:0; }\n .wc-close {\n width:30px; height:30px; display:flex; align-items:center; justify-content:center;\n background:${s}; border:none; border-radius:50%;\n cursor:pointer; font-size:14px; color:${o};\n transition:all .15s;\n }\n .wc-close:hover { background:${r}; color:${i}; }\n .wc-subtitle {\n font-size:13px; color:${o}; margin:8px 24px 0;\n line-height:1.4;\n }\n\n .wc-body { padding:20px 24px 24px; }\n\n /* Grid wallet picker */\n .wc-wallet-grid {\n display:grid; grid-template-columns:repeat(4,1fr);\n gap:16px 12px; list-style:none; margin:0; padding:0;\n }\n .wc-wallet-grid-item {\n display:flex; flex-direction:column; align-items:center;\n gap:8px; cursor:pointer; padding:8px 4px; border-radius:16px;\n transition:all .15s; border:2px solid transparent;\n }\n .wc-wallet-grid-item:hover {\n background:${s}; border-color:${r};\n }\n .wc-wallet-grid-icon {\n width:56px; height:56px; border-radius:16px;\n object-fit:cover; box-shadow:0 2px 8px rgba(0,0,0,${n?.3:.08});\n }\n .wc-wallet-grid-icon-placeholder {\n width:56px; height:56px; border-radius:16px;\n background:linear-gradient(135deg,${c},${a});\n display:flex; align-items:center; justify-content:center;\n color:#fff; font-weight:800; font-size:22px;\n box-shadow:0 2px 8px rgba(0,0,0,${n?.3:.08});\n }\n .wc-wallet-grid-name {\n font-size:11px; font-weight:500; text-align:center;\n color:${o}; line-height:1.2;\n max-width:72px; overflow:hidden; text-overflow:ellipsis;\n white-space:nowrap;\n }\n\n /* List wallet picker (alternative) */\n .wc-wallet-list { list-style:none; margin:0; padding:0; }\n .wc-wallet-item {\n display:flex; align-items:center; gap:14px;\n padding:12px 16px; border-radius:16px; cursor:pointer;\n border:1.5px solid ${r}; margin-bottom:8px;\n transition:all .15s;\n }\n .wc-wallet-item:hover {\n background:${s}; border-color:${a};\n }\n .wc-wallet-list-icon {\n width:40px; height:40px; border-radius:12px; object-fit:cover;\n }\n .wc-wallet-list-icon-placeholder {\n width:40px; height:40px; border-radius:12px;\n background:linear-gradient(135deg,${c},${a});\n display:flex; align-items:center; justify-content:center;\n color:#fff; font-weight:700; font-size:16px;\n }\n .wc-wallet-item-info { flex:1; }\n .wc-wallet-item-name { font-size:14px; font-weight:600; }\n .wc-wallet-item-desc { font-size:11px; color:${o}; margin-top:1px; }\n .wc-wallet-item-arrow { color:${o}; font-size:16px; }\n\n /* Tabs */\n .wc-tabs {\n display:flex; background:${s}; border-radius:12px;\n padding:3px; margin-bottom:20px;\n }\n .wc-tab {\n flex:1; padding:10px; text-align:center; cursor:pointer;\n font-size:13px; font-weight:600; background:transparent;\n border:none; color:${o}; border-radius:10px;\n transition:all .2s;\n }\n .wc-tab:hover { color:${i}; }\n .wc-tab.active {\n background:${t}; color:${i};\n box-shadow:0 1px 4px rgba(0,0,0,${n?.3:.08});\n }\n\n /* Deeplink */\n .wc-deeplink-btn {\n display:flex; align-items:center; justify-content:center; gap:10px;\n width:100%; padding:16px; border:none; border-radius:16px;\n background:linear-gradient(135deg,${c},${a});\n color:#fff; font-size:15px; font-weight:700; cursor:pointer;\n text-decoration:none; transition:all .2s;\n box-shadow:0 4px 20px rgba(43,234,106,0.2);\n box-sizing:border-box;\n }\n .wc-deeplink-btn:hover {\n transform:translateY(-1px);\n box-shadow:0 6px 28px rgba(43,234,106,0.3);\n }\n\n /* QR */\n .wc-qr-container {\n display:flex; flex-direction:column; align-items:center; gap:16px;\n }\n .wc-qr-wrap {\n padding:16px; background:#fff; border-radius:20px;\n box-shadow:0 2px 16px rgba(0,0,0,${n?.2:.06});\n }\n .wc-qr-wrap img { display:block; border-radius:4px; }\n .wc-qr-hint { font-size:12px; color:${o}; text-align:center; }\n\n /* Status */\n .wc-status {\n display:flex; align-items:center; justify-content:center;\n gap:10px; padding:20px 0 4px; font-size:13px; color:${o};\n }\n .wc-spinner {\n width:16px; height:16px; border:2px solid ${r};\n border-top-color:${a}; border-radius:50%;\n animation:wc-spin .7s linear infinite;\n }\n @keyframes wc-spin { to{transform:rotate(360deg)} }\n\n /* Back */\n .wc-back {\n background:none; border:none; cursor:pointer; padding:0;\n color:${o}; display:flex; align-items:center;\n transition:color .15s; font-size:18px;\n }\n .wc-back:hover { color:${i}; }\n\n /* Footer */\n .wc-footer {\n text-align:center; padding:4px 0 20px;\n font-size:11px; color:${n?"#555":"#bbb"};\n }\n\n /* Success screen */\n .wc-success {\n display:flex; flex-direction:column; align-items:center;\n padding:12px 0 4px; gap:20px;\n }\n .wc-success-check {\n width:64px; height:64px; border-radius:50%;\n background:linear-gradient(135deg,${c},${a});\n display:flex; align-items:center; justify-content:center;\n box-shadow:0 4px 20px rgba(43,234,106,0.25);\n animation:wc-popIn .4s cubic-bezier(.16,1,.3,1);\n }\n @keyframes wc-popIn {\n from{transform:scale(0);opacity:0}\n 50%{transform:scale(1.15)}\n to{transform:scale(1);opacity:1}\n }\n .wc-success-check svg { width:32px; height:32px; color:#fff; }\n .wc-success-title {\n font-size:18px; font-weight:700; color:${i};\n }\n .wc-success-user {\n display:flex; align-items:center; gap:14px;\n background:${s}; border-radius:16px;\n padding:16px 18px; width:100%; box-sizing:border-box;\n }\n .wc-success-avatar {\n width:48px; height:48px; border-radius:50%; object-fit:cover;\n flex-shrink:0; border:2px solid ${r};\n }\n .wc-success-avatar-placeholder {\n width:48px; height:48px; border-radius:50%;\n background:linear-gradient(135deg,${c},${a});\n display:flex; align-items:center; justify-content:center;\n color:#fff; font-weight:700; font-size:18px; flex-shrink:0;\n border:2px solid ${r};\n }\n .wc-success-user-info { flex:1; min-width:0; }\n .wc-success-user-name { font-size:15px; font-weight:600; color:${i}; }\n .wc-success-user-addr {\n font-size:12px; color:${o}; margin-top:4px;\n font-family:'SF Mono',Monaco,Consolas,monospace;\n word-break:break-all; line-height:1.4;\n }\n .wc-success-done {\n width:100%; padding:14px; border:none; border-radius:14px;\n background:linear-gradient(135deg,${c},${a});\n color:#fff; font-size:14px; font-weight:700; cursor:pointer;\n transition:all .2s;\n box-shadow:0 4px 16px rgba(43,234,106,0.2);\n }\n .wc-success-done:hover {\n transform:translateY(-1px);\n box-shadow:0 6px 24px rgba(43,234,106,0.3);\n }\n `}(this.theme)}</style>\n <div class="wc-overlay">\n <div class="wc-modal">${e}</div>\n </div>\n `,document.body.appendChild(n),this.overlay=n,this.overlay.querySelector('[data-action="close"]')?.addEventListener("click",()=>{this.onClose(),this.destroy()}),this.overlay.querySelector(".wc-overlay")?.addEventListener("click",e=>{e.target.classList.contains("wc-overlay")&&(this.onClose(),this.destroy())})}destroy(){document.getElementById(t)?.remove(),this.overlay=null}}const i="__wc_session_";class o{constructor(e){this.listeners=new Map,this.modal=null,this.wsTransport=null,this.pollingTransport=null,this.currentResult=null,this.config={appId:e.appId,registryUrl:e.registryUrl||"https://cdn.jsdelivr.net/npm/toncorp-wallet-connect-sdk@latest/registry.json",walletId:e.walletId,theme:e.theme||"light"},this.restoreSession(),this.registerGlobal()}async connect(){if(this.currentResult)return this.currentResult;const e=await this.fetchWallets(),n=this.filterWallets(e);if(0===n.length)throw new Error("No supported wallets available");return new Promise((e,t)=>{this.modal=new s(this.config.theme,()=>{this.cleanup(),t(new Error("User closed modal"))}),1===n.length?this.startConnect(n[0],!1,e,t):this.modal.showWalletPicker(n,n=>{this.startConnect(n,!0,e,t)})})}disconnect(){let e=this.currentResult?.session;if(!e&&"undefined"!=typeof window)for(const n of Object.keys(window)){const t=window[n];if(t instanceof o&&t.currentResult?.session){e=t.currentResult.session;break}}if(e){const n=e.apiUrl.replace(/\/$/,"");fetch(`${n}/connect/disconnect-by-token`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({sessionToken:e.sessionToken})}).catch(()=>{})}this.currentResult=null,this.removeStoredSession(),this.clearAllRelatedSessions(),this.cleanup(),this.emit("disconnect")}isConnected(){return null!==this.currentResult}getWallet(){return this.currentResult}on(e,n){this.listeners.has(e)||this.listeners.set(e,new Set),this.listeners.get(e).add(n)}off(e,n){this.listeners.get(e)?.delete(n)}get storageKey(){const e=this.config.walletId,n=Array.isArray(e)?e.sort().join("_"):e||"all";return`${i}${n}__`}async fetchWallets(){const e=this.config.registryUrl.replace(/\/$/,""),n=await fetch(e);if(!n.ok)throw new Error("Failed to fetch wallets");return n.json()}filterWallets(e){if(!this.config.walletId)return e;const n=Array.isArray(this.config.walletId)?this.config.walletId:[this.config.walletId];return e.filter(e=>n.includes(e.walletId))}async startConnect(e,n,t,s){try{const i=await this.initSession(e);this.modal?.showConnect(e,i.deeplink,n,()=>{this.cleanup(),this.connect().then(t).catch(s)}),this.listenForConfirmation(e.apiUrl,i.sessionToken,n=>{n.session={sessionToken:i.sessionToken,walletId:e.walletId,apiUrl:e.apiUrl},this.currentResult=n,this.storeSession(n),this.syncToWalletInstance(e.walletId,n),this.emit("connect",n),this.modal?.showSuccess(e,n.wallet?.address||null,n.user||null,()=>{this.modal?.destroy(),this.modal=null,t(n)})},()=>{this.modal?.updateStatus("Connection rejected",!1),setTimeout(()=>{this.modal?.destroy(),this.modal=null,s(new Error("Connection rejected by user"))},1500)},()=>{this.modal?.updateStatus("Session expired",!1),this.emit("session_expired"),setTimeout(()=>{this.modal?.destroy(),this.modal=null,s(new Error("Session expired"))},1500)})}catch(e){this.modal?.destroy(),this.modal=null,s(e instanceof Error?e:new Error(String(e)))}}async initSession(e){const n=e.apiUrl.replace(/\/$/,""),t=await fetch(`${n}/connect/init`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({appId:this.config.appId,walletId:e.walletId,origin:"undefined"!=typeof window?window.location.origin:""})});if(!t.ok)throw new Error("Failed to init session");return t.json()}listenForConfirmation(t,s,i,o,r){let a=!1;const c=e=>(...n)=>{a||(a=!0,this.wsTransport?.close(),this.pollingTransport?.stop(),e(...n))},l=c(i),d=c(o),p=c(r);this.pollingTransport=new n(t,s,l,d,p,e=>this.emit("error",e)),this.pollingTransport.start(),this.wsTransport=new e(t,s,l,d,p,()=>{}),this.wsTransport.connect()}cleanup(){this.wsTransport?.close(),this.wsTransport=null,this.pollingTransport?.stop(),this.pollingTransport=null,this.modal?.destroy(),this.modal=null}emit(e,n){this.listeners.get(e)?.forEach(e=>e(n))}storeSession(e){try{localStorage.setItem(this.storageKey,JSON.stringify(e))}catch{}}restoreSession(){try{const e=localStorage.getItem(this.storageKey);e&&(this.currentResult=JSON.parse(e))}catch{}}removeStoredSession(){try{localStorage.removeItem(this.storageKey)}catch{}}registerGlobal(){if("undefined"==typeof window)return;const e=this.config.walletId,n=Array.isArray(e)?e[0]:e||"walletconnect";window[n]=this}syncToWalletInstance(e,n){if("undefined"==typeof window)return;const t=window[e];t&&t!==this&&t instanceof o&&(t.currentResult=n,t.storeSession(n))}clearAllRelatedSessions(){if("undefined"!=typeof window){try{for(const e of Object.keys(window)){const n=window[e];n&&n!==this&&n instanceof o&&(n.currentResult=null,n.removeStoredSession())}}catch{}try{const e=[];for(let n=0;n<localStorage.length;n++){const t=localStorage.key(n);t&&t.startsWith(i)&&e.push(t)}e.forEach(e=>localStorage.removeItem(e))}catch{}}}}class r extends o{constructor(e){super({...e,walletId:"tonpass"})}}class a extends o{constructor(e){super({...e,walletId:"onedollar"})}}export{o as BaseWalletConnect,a as OneDollarConnect,r as TonPassConnect};
2
2
  //# sourceMappingURL=index.esm.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.esm.js","sources":["../../transport.ts","../../modal.ts","../../client.ts","../../tonpass.ts","../../onedollar.ts"],"sourcesContent":["import type { ConnectResult } from './types';\n\ntype TransportCallback = (data: ConnectResult) => void;\ntype TransportErrorCallback = (error: string) => void;\n\n// ── WebSocket Transport ──\n\nexport class WsTransport {\n private ws: WebSocket | null = null;\n private reconnectTimer: ReturnType<typeof setTimeout> | null = null;\n private closed = false;\n\n constructor(\n private apiUrl: string,\n private sessionToken: string,\n private onConfirmed: TransportCallback,\n private onRejected: () => void,\n private onExpired: () => void,\n private onError: TransportErrorCallback,\n ) {}\n\n connect(): void {\n this.closed = false;\n const wsUrl = this.apiUrl\n .replace(/^http/, 'ws')\n .replace(/\\/$/, '');\n const url = `${wsUrl}/walletconnect?sessionToken=${this.sessionToken}`;\n\n try {\n // Socket.IO uses polling upgrade — use native WS for simplicity in SDK\n // The BE gateway uses socket.io, so we connect via socket.io protocol\n this.connectSocketIO();\n } catch {\n this.onError('WebSocket connection failed');\n }\n }\n\n private connectSocketIO(): void {\n const baseUrl = this.apiUrl.replace(/\\/$/, '');\n\n // Socket.IO handshake: first GET for sid, then upgrade to WS\n const pollingUrl = `${baseUrl}/walletconnect/?EIO=4&transport=polling`;\n\n fetch(pollingUrl)\n .then((res) => res.text())\n .then((body) => {\n // Socket.IO response format: \"0{...json...}\"\n const jsonStr = body.replace(/^\\d+/, '');\n const handshake = JSON.parse(jsonStr);\n const sid = handshake.sid;\n\n const wsBase = baseUrl.replace(/^http/, 'ws');\n const wsUrl = `${wsBase}/walletconnect/?EIO=4&transport=websocket&sid=${sid}`;\n\n this.ws = new WebSocket(wsUrl);\n\n this.ws.onopen = () => {\n // Socket.IO upgrade probe\n this.ws!.send('2probe');\n };\n\n this.ws.onmessage = (event) => {\n const msg = event.data as string;\n\n if (msg === '3probe') {\n // Upgrade confirmed, send upgrade packet + join room\n this.ws!.send('5');\n // Emit connect event with sessionToken as query (already in URL)\n // Socket.IO auto-joins based on handshake query\n return;\n }\n\n // Handle Socket.IO event messages: 42[\"event_name\", {...data}]\n if (msg.startsWith('42')) {\n try {\n const payload = JSON.parse(msg.slice(2));\n const [eventName, data] = payload;\n this.handleEvent(eventName, data);\n } catch {\n // ignore malformed\n }\n return;\n }\n\n // Ping from server\n if (msg === '2') {\n this.ws!.send('3');\n }\n };\n\n this.ws.onclose = () => {\n if (!this.closed) {\n this.scheduleReconnect();\n }\n };\n\n this.ws.onerror = () => {\n if (!this.closed) {\n this.scheduleReconnect();\n }\n };\n })\n .catch(() => {\n if (!this.closed) {\n this.scheduleReconnect();\n }\n });\n }\n\n private handleEvent(eventName: string, data: any): void {\n switch (eventName) {\n case 'session_confirmed':\n this.onConfirmed(data);\n this.close();\n break;\n case 'session_rejected':\n this.onRejected();\n this.close();\n break;\n case 'session_expired':\n this.onExpired();\n this.close();\n break;\n }\n }\n\n private scheduleReconnect(): void {\n if (this.closed || this.reconnectTimer) return;\n this.reconnectTimer = setTimeout(() => {\n this.reconnectTimer = null;\n this.connectSocketIO();\n }, 3000);\n }\n\n close(): void {\n this.closed = true;\n if (this.reconnectTimer) {\n clearTimeout(this.reconnectTimer);\n this.reconnectTimer = null;\n }\n if (this.ws) {\n this.ws.close();\n this.ws = null;\n }\n }\n}\n\n// ── Long-Poll Fallback ──\n\nexport class PollingTransport {\n private timer: ReturnType<typeof setInterval> | null = null;\n private stopped = false;\n\n constructor(\n private apiUrl: string,\n private sessionToken: string,\n private onConfirmed: TransportCallback,\n private onRejected: () => void,\n private onExpired: () => void,\n private onError: TransportErrorCallback,\n ) {}\n\n start(): void {\n this.stopped = false;\n this.poll();\n this.timer = setInterval(() => this.poll(), 2000);\n }\n\n private async poll(): Promise<void> {\n if (this.stopped) return;\n\n try {\n const baseUrl = this.apiUrl.replace(/\\/$/, '');\n const res = await fetch(\n `${baseUrl}/connect/status?token=${this.sessionToken}`,\n );\n if (!res.ok) return;\n\n const data = await res.json();\n\n switch (data.status) {\n case 'CONFIRMED':\n this.onConfirmed({ wallet: data.wallet, user: data.user });\n this.stop();\n break;\n case 'REJECTED':\n this.onRejected();\n this.stop();\n break;\n case 'EXPIRED':\n this.onExpired();\n this.stop();\n break;\n }\n } catch {\n // silently retry next interval\n }\n }\n\n stop(): void {\n this.stopped = true;\n if (this.timer) {\n clearInterval(this.timer);\n this.timer = null;\n }\n }\n}\n","import type { WalletMeta } from './types';\n\nconst MODAL_ID = '__wc_modal__';\n\nfunction getStyles(theme: 'light' | 'dark'): string {\n const isDark = theme === 'dark';\n const bg = isDark ? '#141414' : '#ffffff';\n const bgSecondary = isDark ? '#1e1e1e' : '#f4f4f4';\n const text = isDark ? '#ffffff' : '#141414';\n const textSecondary = isDark ? '#9a9a9a' : '#787878';\n const border = isDark ? '#2a2a2a' : '#e4e4e4';\n const accent = '#2bea6a';\n const accentDark = '#1db954';\n\n return `\n @keyframes wc-fadeIn { from{opacity:0} to{opacity:1} }\n @keyframes wc-slideUp {\n from{opacity:0;transform:translateY(100%)}\n to{opacity:1;transform:translateY(0)}\n }\n .wc-overlay {\n position:fixed; inset:0; z-index:99999;\n background:rgba(0,0,0,${isDark ? 0.75 : 0.45});\n display:flex; align-items:flex-end; justify-content:center;\n font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;\n backdrop-filter:blur(6px); -webkit-backdrop-filter:blur(6px);\n animation:wc-fadeIn .2s ease;\n }\n @media(min-width:480px){\n .wc-overlay{align-items:center}\n .wc-modal{border-radius:24px;max-height:85vh}\n }\n .wc-modal {\n background:${bg}; width:100%; max-width:420px;\n border-radius:24px 24px 0 0; overflow:hidden; color:${text};\n box-shadow:0 -8px 40px rgba(0,0,0,${isDark ? 0.5 : 0.15});\n animation:wc-slideUp .3s cubic-bezier(.16,1,.3,1);\n max-height:90vh; overflow-y:auto;\n }\n\n /* Handle bar */\n .wc-handle {\n width:36px; height:4px; border-radius:2px;\n background:${border}; margin:10px auto 0;\n }\n\n /* Header */\n .wc-header {\n display:flex; align-items:center; justify-content:space-between;\n padding:20px 24px 0;\n }\n .wc-header-left {\n display:flex; align-items:center; gap:10px;\n }\n .wc-header-icon {\n width:32px; height:32px; border-radius:10px; object-fit:cover;\n }\n .wc-title { font-size:17px; font-weight:700; margin:0; }\n .wc-close {\n width:30px; height:30px; display:flex; align-items:center; justify-content:center;\n background:${bgSecondary}; border:none; border-radius:50%;\n cursor:pointer; font-size:14px; color:${textSecondary};\n transition:all .15s;\n }\n .wc-close:hover { background:${border}; color:${text}; }\n .wc-subtitle {\n font-size:13px; color:${textSecondary}; margin:8px 24px 0;\n line-height:1.4;\n }\n\n .wc-body { padding:20px 24px 24px; }\n\n /* Grid wallet picker */\n .wc-wallet-grid {\n display:grid; grid-template-columns:repeat(4,1fr);\n gap:16px 12px; list-style:none; margin:0; padding:0;\n }\n .wc-wallet-grid-item {\n display:flex; flex-direction:column; align-items:center;\n gap:8px; cursor:pointer; padding:8px 4px; border-radius:16px;\n transition:all .15s; border:2px solid transparent;\n }\n .wc-wallet-grid-item:hover {\n background:${bgSecondary}; border-color:${border};\n }\n .wc-wallet-grid-icon {\n width:56px; height:56px; border-radius:16px;\n object-fit:cover; box-shadow:0 2px 8px rgba(0,0,0,${isDark ? 0.3 : 0.08});\n }\n .wc-wallet-grid-icon-placeholder {\n width:56px; height:56px; border-radius:16px;\n background:linear-gradient(135deg,${accentDark},${accent});\n display:flex; align-items:center; justify-content:center;\n color:#fff; font-weight:800; font-size:22px;\n box-shadow:0 2px 8px rgba(0,0,0,${isDark ? 0.3 : 0.08});\n }\n .wc-wallet-grid-name {\n font-size:11px; font-weight:500; text-align:center;\n color:${textSecondary}; line-height:1.2;\n max-width:72px; overflow:hidden; text-overflow:ellipsis;\n white-space:nowrap;\n }\n\n /* List wallet picker (alternative) */\n .wc-wallet-list { list-style:none; margin:0; padding:0; }\n .wc-wallet-item {\n display:flex; align-items:center; gap:14px;\n padding:12px 16px; border-radius:16px; cursor:pointer;\n border:1.5px solid ${border}; margin-bottom:8px;\n transition:all .15s;\n }\n .wc-wallet-item:hover {\n background:${bgSecondary}; border-color:${accent};\n }\n .wc-wallet-list-icon {\n width:40px; height:40px; border-radius:12px; object-fit:cover;\n }\n .wc-wallet-list-icon-placeholder {\n width:40px; height:40px; border-radius:12px;\n background:linear-gradient(135deg,${accentDark},${accent});\n display:flex; align-items:center; justify-content:center;\n color:#fff; font-weight:700; font-size:16px;\n }\n .wc-wallet-item-info { flex:1; }\n .wc-wallet-item-name { font-size:14px; font-weight:600; }\n .wc-wallet-item-desc { font-size:11px; color:${textSecondary}; margin-top:1px; }\n .wc-wallet-item-arrow { color:${textSecondary}; font-size:16px; }\n\n /* Tabs */\n .wc-tabs {\n display:flex; background:${bgSecondary}; border-radius:12px;\n padding:3px; margin-bottom:20px;\n }\n .wc-tab {\n flex:1; padding:10px; text-align:center; cursor:pointer;\n font-size:13px; font-weight:600; background:transparent;\n border:none; color:${textSecondary}; border-radius:10px;\n transition:all .2s;\n }\n .wc-tab:hover { color:${text}; }\n .wc-tab.active {\n background:${bg}; color:${text};\n box-shadow:0 1px 4px rgba(0,0,0,${isDark ? 0.3 : 0.08});\n }\n\n /* Deeplink */\n .wc-deeplink-btn {\n display:flex; align-items:center; justify-content:center; gap:10px;\n width:100%; padding:16px; border:none; border-radius:16px;\n background:linear-gradient(135deg,${accentDark},${accent});\n color:#fff; font-size:15px; font-weight:700; cursor:pointer;\n text-decoration:none; transition:all .2s;\n box-shadow:0 4px 20px rgba(43,234,106,0.2);\n box-sizing:border-box;\n }\n .wc-deeplink-btn:hover {\n transform:translateY(-1px);\n box-shadow:0 6px 28px rgba(43,234,106,0.3);\n }\n\n /* QR */\n .wc-qr-container {\n display:flex; flex-direction:column; align-items:center; gap:16px;\n }\n .wc-qr-wrap {\n padding:16px; background:#fff; border-radius:20px;\n box-shadow:0 2px 16px rgba(0,0,0,${isDark ? 0.2 : 0.06});\n }\n .wc-qr-wrap img { display:block; border-radius:4px; }\n .wc-qr-hint { font-size:12px; color:${textSecondary}; text-align:center; }\n\n /* Status */\n .wc-status {\n display:flex; align-items:center; justify-content:center;\n gap:10px; padding:20px 0 4px; font-size:13px; color:${textSecondary};\n }\n .wc-spinner {\n width:16px; height:16px; border:2px solid ${border};\n border-top-color:${accent}; border-radius:50%;\n animation:wc-spin .7s linear infinite;\n }\n @keyframes wc-spin { to{transform:rotate(360deg)} }\n\n /* Back */\n .wc-back {\n background:none; border:none; cursor:pointer; padding:0;\n color:${textSecondary}; display:flex; align-items:center;\n transition:color .15s; font-size:18px;\n }\n .wc-back:hover { color:${text}; }\n\n /* Footer */\n .wc-footer {\n text-align:center; padding:4px 0 20px;\n font-size:11px; color:${isDark ? '#555' : '#bbb'};\n }\n\n /* Success screen */\n .wc-success {\n display:flex; flex-direction:column; align-items:center;\n padding:12px 0 4px; gap:20px;\n }\n .wc-success-check {\n width:64px; height:64px; border-radius:50%;\n background:linear-gradient(135deg,${accentDark},${accent});\n display:flex; align-items:center; justify-content:center;\n box-shadow:0 4px 20px rgba(43,234,106,0.25);\n animation:wc-popIn .4s cubic-bezier(.16,1,.3,1);\n }\n @keyframes wc-popIn {\n from{transform:scale(0);opacity:0}\n 50%{transform:scale(1.15)}\n to{transform:scale(1);opacity:1}\n }\n .wc-success-check svg { width:32px; height:32px; color:#fff; }\n .wc-success-title {\n font-size:18px; font-weight:700; color:${text};\n }\n .wc-success-user {\n display:flex; align-items:center; gap:14px;\n background:${bgSecondary}; border-radius:16px;\n padding:16px 18px; width:100%; box-sizing:border-box;\n }\n .wc-success-avatar {\n width:48px; height:48px; border-radius:50%; object-fit:cover;\n flex-shrink:0; border:2px solid ${border};\n }\n .wc-success-avatar-placeholder {\n width:48px; height:48px; border-radius:50%;\n background:linear-gradient(135deg,${accentDark},${accent});\n display:flex; align-items:center; justify-content:center;\n color:#fff; font-weight:700; font-size:18px; flex-shrink:0;\n border:2px solid ${border};\n }\n .wc-success-user-info { flex:1; min-width:0; }\n .wc-success-user-name { font-size:15px; font-weight:600; color:${text}; }\n .wc-success-user-addr {\n font-size:12px; color:${textSecondary}; margin-top:4px;\n font-family:'SF Mono',Monaco,Consolas,monospace;\n word-break:break-all; line-height:1.4;\n }\n .wc-success-done {\n width:100%; padding:14px; border:none; border-radius:14px;\n background:linear-gradient(135deg,${accentDark},${accent});\n color:#fff; font-size:14px; font-weight:700; cursor:pointer;\n transition:all .2s;\n box-shadow:0 4px 16px rgba(43,234,106,0.2);\n }\n .wc-success-done:hover {\n transform:translateY(-1px);\n box-shadow:0 6px 24px rgba(43,234,106,0.3);\n }\n `;\n}\n\nconst TELEGRAM_SVG = `<svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M11.944 0A12 12 0 1 0 24 12.056A12.01 12.01 0 0 0 11.944 0Zm4.962 7.224c.1-.002.321.023.465.14a.506.506 0 0 1 .171.325c.016.093.036.306.02.472c-.18 1.898-.962 6.502-1.36 8.627c-.168.9-.499 1.201-.82 1.23c-.696.065-1.225-.46-1.9-.902c-1.056-.693-1.653-1.124-2.678-1.8c-1.185-.78-.417-1.21.258-1.91c.177-.184 3.247-2.977 3.307-3.23c.007-.032.014-.15-.056-.212s-.174-.041-.249-.024c-.106.024-1.793 1.14-5.061 3.345c-.48.33-.913.49-1.302.48c-.428-.008-1.252-.241-1.865-.44c-.752-.245-1.349-.374-1.297-.789c.027-.216.325-.437.893-.663c3.498-1.524 5.83-2.529 6.998-3.014c3.332-1.386 4.025-1.627 4.476-1.635Z\"/></svg>`;\n\nfunction generateQRDataUrl(text: string, size = 220): string {\n return `https://api.qrserver.com/v1/create-qr-code/?size=${size}x${size}&data=${encodeURIComponent(text)}&margin=8`;\n}\n\nexport class Modal {\n private overlay: HTMLDivElement | null = null;\n private theme: 'light' | 'dark';\n private onClose: () => void;\n\n constructor(theme: 'light' | 'dark', onClose: () => void) {\n this.theme = theme;\n this.onClose = onClose;\n }\n\n showWalletPicker(\n wallets: WalletMeta[],\n onSelect: (wallet: WalletMeta) => void,\n ): void {\n const useGrid = wallets.length >= 3;\n\n const listHtml = useGrid\n ? `<ul class=\"wc-wallet-grid\">${wallets\n .map(\n (w) => `\n <li class=\"wc-wallet-grid-item\" data-wallet-id=\"${w.walletId}\">\n ${\n w.icon\n ? `<img class=\"wc-wallet-grid-icon\" src=\"${w.icon}\" alt=\"${w.name}\" />`\n : `<div class=\"wc-wallet-grid-icon-placeholder\">${w.name.charAt(0)}</div>`\n }\n <span class=\"wc-wallet-grid-name\">${w.name}</span>\n </li>`,\n )\n .join('')}</ul>`\n : `<ul class=\"wc-wallet-list\">${wallets\n .map(\n (w) => `\n <li class=\"wc-wallet-item\" data-wallet-id=\"${w.walletId}\">\n ${\n w.icon\n ? `<img class=\"wc-wallet-list-icon\" src=\"${w.icon}\" alt=\"${w.name}\" />`\n : `<div class=\"wc-wallet-list-icon-placeholder\">${w.name.charAt(0)}</div>`\n }\n <div class=\"wc-wallet-item-info\">\n <div class=\"wc-wallet-item-name\">${w.name}</div>\n ${w.description ? `<div class=\"wc-wallet-item-desc\">${w.description}</div>` : ''}\n </div>\n <span class=\"wc-wallet-item-arrow\">&#8250;</span>\n </li>`,\n )\n .join('')}</ul>`;\n\n const html = `\n <div class=\"wc-handle\"></div>\n <div class=\"wc-header\">\n <h3 class=\"wc-title\">Connect your wallet</h3>\n <button class=\"wc-close\" data-action=\"close\">&#10005;</button>\n </div>\n <p class=\"wc-subtitle\">Choose a wallet to connect to this app</p>\n <div class=\"wc-body\">${listHtml}</div>\n <div class=\"wc-footer\">Powered by WalletConnect</div>\n `;\n\n this.render(html);\n\n wallets.forEach((w) => {\n this.overlay\n ?.querySelector(`[data-wallet-id=\"${w.walletId}\"]`)\n ?.addEventListener('click', () => onSelect(w));\n });\n }\n\n showConnect(\n wallet: WalletMeta,\n deeplink: string,\n showBack: boolean,\n onBack?: () => void,\n ): void {\n const qrUrl = generateQRDataUrl(deeplink);\n\n const html = `\n <div class=\"wc-handle\"></div>\n <div class=\"wc-header\">\n <div class=\"wc-header-left\">\n ${showBack ? '<button class=\"wc-back\" data-action=\"back\">&#8592;</button>' : ''}\n ${wallet.icon ? `<img class=\"wc-header-icon\" src=\"${wallet.icon}\" />` : ''}\n <h3 class=\"wc-title\">${wallet.name}</h3>\n </div>\n <button class=\"wc-close\" data-action=\"close\">&#10005;</button>\n </div>\n <p class=\"wc-subtitle\">Approve the connection request in your wallet</p>\n <div class=\"wc-body\">\n <div class=\"wc-tabs\">\n <button class=\"wc-tab active\" data-tab=\"mobile\">Mobile</button>\n <button class=\"wc-tab\" data-tab=\"qr\">QR Code</button>\n </div>\n <div data-panel=\"mobile\">\n <a class=\"wc-deeplink-btn\" href=\"${deeplink}\" target=\"_blank\">\n ${TELEGRAM_SVG}\n Open in Telegram\n </a>\n </div>\n <div data-panel=\"qr\" style=\"display:none\">\n <div class=\"wc-qr-container\">\n <div class=\"wc-qr-wrap\">\n <img src=\"${qrUrl}\" width=\"220\" height=\"220\" alt=\"QR\" />\n </div>\n <div class=\"wc-qr-hint\">Scan with your phone camera or wallet app</div>\n </div>\n </div>\n <div class=\"wc-status\">\n <div class=\"wc-spinner\"></div>\n <span>Waiting for confirmation...</span>\n </div>\n </div>\n <div class=\"wc-footer\">Powered by WalletConnect</div>\n `;\n\n this.render(html);\n\n const tabs = this.overlay?.querySelectorAll('.wc-tab');\n const panels = this.overlay?.querySelectorAll('[data-panel]');\n tabs?.forEach((tab) => {\n tab.addEventListener('click', () => {\n const target = (tab as HTMLElement).dataset.tab;\n tabs.forEach((t) => t.classList.remove('active'));\n tab.classList.add('active');\n panels?.forEach((p) => {\n (p as HTMLElement).style.display =\n (p as HTMLElement).dataset.panel === target ? 'block' : 'none';\n });\n });\n });\n\n if (showBack && onBack) {\n this.overlay\n ?.querySelector('[data-action=\"back\"]')\n ?.addEventListener('click', onBack);\n }\n }\n\n showSuccess(\n wallet: WalletMeta,\n address: string | null,\n user: { username?: string; avatar?: string } | null,\n onDone: () => void,\n ): void {\n const checkSvg = `<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"/></svg>`;\n\n const displayName = user?.username || 'User';\n const initials = displayName.slice(0, 2).toUpperCase();\n\n const avatarHtml = user?.avatar\n ? `<img class=\"wc-success-avatar\" src=\"${user.avatar}\" alt=\"${displayName}\" />`\n : `<div class=\"wc-success-avatar-placeholder\">${initials}</div>`;\n\n const html = `\n <div class=\"wc-handle\"></div>\n <div class=\"wc-header\">\n <h3 class=\"wc-title\">Connected</h3>\n <button class=\"wc-close\" data-action=\"close\">&#10005;</button>\n </div>\n <div class=\"wc-body\">\n <div class=\"wc-success\">\n <div class=\"wc-success-check\">${checkSvg}</div>\n <div class=\"wc-success-title\">Connection Successful</div>\n <div class=\"wc-success-user\">\n ${avatarHtml}\n <div class=\"wc-success-user-info\">\n <div class=\"wc-success-user-name\">${displayName}</div>\n ${address ? `<div class=\"wc-success-user-addr\" title=\"${address}\">${address}</div>` : ''}\n </div>\n </div>\n <button class=\"wc-success-done\" data-action=\"done\">Done</button>\n </div>\n </div>\n <div class=\"wc-footer\">Powered by WalletConnect</div>\n `;\n\n this.render(html);\n\n this.overlay\n ?.querySelector('[data-action=\"done\"]')\n ?.addEventListener('click', onDone);\n }\n\n updateStatus(text: string, showSpinner = true): void {\n const el = this.overlay?.querySelector('.wc-status');\n if (el) {\n el.innerHTML = `\n ${showSpinner ? '<div class=\"wc-spinner\"></div>' : ''}\n <span>${text}</span>\n `;\n }\n }\n\n private render(innerHtml: string): void {\n this.destroy();\n\n const el = document.createElement('div');\n el.id = MODAL_ID;\n el.innerHTML = `\n <style>${getStyles(this.theme)}</style>\n <div class=\"wc-overlay\">\n <div class=\"wc-modal\">${innerHtml}</div>\n </div>\n `;\n\n document.body.appendChild(el);\n this.overlay = el;\n\n this.overlay\n .querySelector('[data-action=\"close\"]')\n ?.addEventListener('click', () => { this.onClose(); this.destroy(); });\n\n this.overlay\n .querySelector('.wc-overlay')\n ?.addEventListener('click', (e) => {\n if ((e.target as HTMLElement).classList.contains('wc-overlay')) {\n this.onClose();\n this.destroy();\n }\n });\n }\n\n destroy(): void {\n document.getElementById(MODAL_ID)?.remove();\n this.overlay = null;\n }\n}\n","import type {\n WalletConnectConfig,\n WalletMeta,\n ConnectResult,\n ConnectSession,\n InitSessionResponse,\n WalletConnectEventType,\n WalletConnectEventCallback,\n} from './types';\nimport { WsTransport, PollingTransport } from './transport';\nimport { Modal } from './modal';\n\nconst STORAGE_KEY_PREFIX = '__wc_session_';\nconst DEFAULT_REGISTRY_URL = 'https://cdn.jsdelivr.net/npm/toncorp-wallet-connect-sdk@latest/registry.json';\n\nexport class BaseWalletConnect {\n protected config: Required<\n Pick<WalletConnectConfig, 'appId' | 'registryUrl' | 'theme'>\n > &\n Pick<WalletConnectConfig, 'walletId'>;\n\n private listeners: Map<WalletConnectEventType, Set<WalletConnectEventCallback>> = new Map();\n private modal: Modal | null = null;\n private wsTransport: WsTransport | null = null;\n private pollingTransport: PollingTransport | null = null;\n private currentResult: ConnectResult | null = null;\n\n constructor(config: WalletConnectConfig) {\n this.config = {\n appId: config.appId,\n registryUrl: config.registryUrl || DEFAULT_REGISTRY_URL,\n walletId: config.walletId,\n theme: config.theme || 'light',\n };\n\n this.restoreSession();\n this.registerGlobal();\n }\n\n // ── Public API ──\n\n async connect(): Promise<ConnectResult> {\n if (this.currentResult) {\n return this.currentResult;\n }\n\n const wallets = await this.fetchWallets();\n const filtered = this.filterWallets(wallets);\n\n if (filtered.length === 0) {\n throw new Error('No supported wallets available');\n }\n\n return new Promise<ConnectResult>((resolve, reject) => {\n const onClose = () => {\n this.cleanup();\n reject(new Error('User closed modal'));\n };\n\n this.modal = new Modal(this.config.theme, onClose);\n\n if (filtered.length === 1) {\n this.startConnect(filtered[0], false, resolve, reject);\n } else {\n this.modal.showWalletPicker(filtered, (wallet) => {\n this.startConnect(wallet, true, resolve, reject);\n });\n }\n });\n }\n\n disconnect(): void {\n // Call disconnect API (fire-and-forget)\n const session = this.currentResult?.session;\n if (session) {\n const baseUrl = session.apiUrl.replace(/\\/$/, '');\n fetch(`${baseUrl}/connect/disconnect-by-token`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ sessionToken: session.sessionToken }),\n }).catch(() => {});\n }\n\n // Clear all localStorage keys and window instances\n this.currentResult = null;\n this.removeStoredSession();\n this.clearAllRelatedSessions();\n this.cleanup();\n this.emit('disconnect');\n }\n\n isConnected(): boolean {\n return this.currentResult !== null;\n }\n\n getWallet(): ConnectResult | null {\n return this.currentResult;\n }\n\n on(event: WalletConnectEventType, cb: WalletConnectEventCallback): void {\n if (!this.listeners.has(event)) {\n this.listeners.set(event, new Set());\n }\n this.listeners.get(event)!.add(cb);\n }\n\n off(event: WalletConnectEventType, cb: WalletConnectEventCallback): void {\n this.listeners.get(event)?.delete(cb);\n }\n\n // ── Internal ──\n\n private get storageKey(): string {\n const walletId = this.config.walletId;\n const suffix = Array.isArray(walletId)\n ? walletId.sort().join('_')\n : walletId || 'all';\n return `${STORAGE_KEY_PREFIX}${suffix}__`;\n }\n\n private async fetchWallets(): Promise<WalletMeta[]> {\n const url = this.config.registryUrl.replace(/\\/$/, '');\n const res = await fetch(url);\n if (!res.ok) throw new Error('Failed to fetch wallets');\n return res.json();\n }\n\n private filterWallets(wallets: WalletMeta[]): WalletMeta[] {\n if (!this.config.walletId) return wallets;\n\n const ids = Array.isArray(this.config.walletId)\n ? this.config.walletId\n : [this.config.walletId];\n\n return wallets.filter((w) => ids.includes(w.walletId));\n }\n\n private async startConnect(\n wallet: WalletMeta,\n showBack: boolean,\n resolve: (result: ConnectResult) => void,\n reject: (error: Error) => void,\n ): Promise<void> {\n try {\n const session = await this.initSession(wallet);\n\n this.modal?.showConnect(wallet, session.deeplink, showBack, () => {\n this.cleanup();\n this.connect().then(resolve).catch(reject);\n });\n\n this.listenForConfirmation(\n wallet.apiUrl,\n session.sessionToken,\n (result) => {\n // Attach session info for disconnect\n result.session = {\n sessionToken: session.sessionToken,\n walletId: wallet.walletId,\n apiUrl: wallet.apiUrl,\n };\n this.currentResult = result;\n this.storeSession(result);\n this.syncToWalletInstance(wallet.walletId, result);\n this.emit('connect', result);\n\n // Show success screen\n this.modal?.showSuccess(\n wallet,\n result.wallet?.address || null,\n result.user || null,\n () => {\n this.modal?.destroy();\n this.modal = null;\n resolve(result);\n },\n );\n },\n () => {\n this.modal?.updateStatus('Connection rejected', false);\n setTimeout(() => {\n this.modal?.destroy();\n this.modal = null;\n reject(new Error('Connection rejected by user'));\n }, 1500);\n },\n () => {\n this.modal?.updateStatus('Session expired', false);\n this.emit('session_expired');\n setTimeout(() => {\n this.modal?.destroy();\n this.modal = null;\n reject(new Error('Session expired'));\n }, 1500);\n },\n );\n } catch (err) {\n this.modal?.destroy();\n this.modal = null;\n reject(err instanceof Error ? err : new Error(String(err)));\n }\n }\n\n private async initSession(wallet: WalletMeta): Promise<InitSessionResponse> {\n const baseUrl = wallet.apiUrl.replace(/\\/$/, '');\n const res = await fetch(`${baseUrl}/connect/init`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n appId: this.config.appId,\n walletId: wallet.walletId,\n origin: typeof window !== 'undefined' ? window.location.origin : '',\n }),\n });\n if (!res.ok) throw new Error('Failed to init session');\n return res.json();\n }\n\n private listenForConfirmation(\n apiUrl: string,\n sessionToken: string,\n onConfirmed: (result: ConnectResult) => void,\n onRejected: () => void,\n onExpired: () => void,\n ): void {\n let resolved = false;\n\n const wrap = <T extends (...args: any[]) => void>(fn: T): T =>\n ((...args: any[]) => {\n if (resolved) return;\n resolved = true;\n this.wsTransport?.close();\n this.pollingTransport?.stop();\n fn(...args);\n }) as unknown as T;\n\n const wrappedConfirm = wrap(onConfirmed);\n const wrappedReject = wrap(onRejected);\n const wrappedExpire = wrap(onExpired);\n\n // Start polling immediately as primary transport\n this.pollingTransport = new PollingTransport(\n apiUrl,\n sessionToken,\n wrappedConfirm,\n wrappedReject,\n wrappedExpire,\n (msg) => this.emit('error', msg),\n );\n this.pollingTransport.start();\n\n // Also try WS for faster response\n this.wsTransport = new WsTransport(\n apiUrl,\n sessionToken,\n wrappedConfirm,\n wrappedReject,\n wrappedExpire,\n () => {}, // WS fail is fine, polling is running\n );\n this.wsTransport.connect();\n }\n\n private cleanup(): void {\n this.wsTransport?.close();\n this.wsTransport = null;\n this.pollingTransport?.stop();\n this.pollingTransport = null;\n this.modal?.destroy();\n this.modal = null;\n }\n\n private emit(event: WalletConnectEventType, data?: any): void {\n this.listeners.get(event)?.forEach((cb) => cb(data));\n }\n\n // ── Persistence ──\n\n private storeSession(result: ConnectResult): void {\n try {\n localStorage.setItem(this.storageKey, JSON.stringify(result));\n } catch {\n // localStorage unavailable\n }\n }\n\n private restoreSession(): void {\n try {\n const stored = localStorage.getItem(this.storageKey);\n if (stored) {\n this.currentResult = JSON.parse(stored);\n }\n } catch {\n // ignore\n }\n }\n\n private removeStoredSession(): void {\n try {\n localStorage.removeItem(this.storageKey);\n } catch {\n // ignore\n }\n }\n\n // ── Global window registration ──\n\n private registerGlobal(): void {\n if (typeof window === 'undefined') return;\n\n const walletId = this.config.walletId;\n const key = Array.isArray(walletId)\n ? walletId[0]\n : walletId || 'walletconnect';\n\n (window as any)[key] = this;\n }\n\n /** Sync connect result to the specific wallet instance on window (e.g. window.onedollar) */\n private syncToWalletInstance(walletId: string, result: ConnectResult): void {\n if (typeof window === 'undefined') return;\n\n const target = (window as any)[walletId];\n if (target && target !== this && target instanceof BaseWalletConnect) {\n (target as any).currentResult = result;\n (target as any).storeSession(result);\n }\n }\n\n /** Clear all related sessions from window instances and localStorage */\n private clearAllRelatedSessions(): void {\n if (typeof window === 'undefined') return;\n\n // Clear all known wallet instances on window\n const keys = ['tonpass', 'onedollar', 'walletconnect'];\n for (const key of keys) {\n const inst = (window as any)[key];\n if (inst && inst !== this && inst instanceof BaseWalletConnect) {\n (inst as any).currentResult = null;\n (inst as any).removeStoredSession();\n }\n }\n\n // Also clear all wc localStorage keys\n try {\n const toRemove: string[] = [];\n for (let i = 0; i < localStorage.length; i++) {\n const k = localStorage.key(i);\n if (k && k.startsWith(STORAGE_KEY_PREFIX)) {\n toRemove.push(k);\n }\n }\n toRemove.forEach((k) => localStorage.removeItem(k));\n } catch {\n // ignore\n }\n }\n}\n","import { BaseWalletConnect } from './client';\nimport type { WalletConnectConfig } from './types';\n\nexport class TonPassConnect extends BaseWalletConnect {\n constructor(config: Omit<WalletConnectConfig, 'walletId'>) {\n super({ ...config, walletId: 'tonpass' });\n }\n}\n","import { BaseWalletConnect } from './client';\nimport type { WalletConnectConfig } from './types';\n\nexport class OneDollarConnect extends BaseWalletConnect {\n constructor(config: Omit<WalletConnectConfig, 'walletId'>) {\n super({ ...config, walletId: 'onedollar' });\n }\n}\n"],"names":["WsTransport","constructor","apiUrl","sessionToken","onConfirmed","onRejected","onExpired","onError","this","ws","reconnectTimer","closed","connect","replace","connectSocketIO","baseUrl","fetch","then","res","text","body","jsonStr","sid","JSON","parse","wsUrl","WebSocket","onopen","send","onmessage","event","msg","data","startsWith","payload","slice","eventName","handleEvent","onclose","scheduleReconnect","onerror","catch","close","setTimeout","clearTimeout","PollingTransport","timer","stopped","start","poll","setInterval","ok","json","status","wallet","user","stop","clearInterval","MODAL_ID","Modal","theme","onClose","overlay","showWalletPicker","wallets","onSelect","html","length","map","w","walletId","icon","name","charAt","join","description","render","forEach","querySelector","addEventListener","showConnect","deeplink","showBack","onBack","qrUrl","size","encodeURIComponent","generateQRDataUrl","tabs","querySelectorAll","panels","tab","target","dataset","t","classList","remove","add","p","style","display","panel","showSuccess","address","onDone","displayName","username","initials","toUpperCase","avatar","updateStatus","showSpinner","el","innerHTML","innerHtml","destroy","document","createElement","id","isDark","bg","bgSecondary","textSecondary","border","accent","accentDark","getStyles","appendChild","e","contains","getElementById","STORAGE_KEY_PREFIX","BaseWalletConnect","config","listeners","Map","modal","wsTransport","pollingTransport","currentResult","appId","registryUrl","restoreSession","registerGlobal","fetchWallets","filtered","filterWallets","Error","Promise","resolve","reject","cleanup","startConnect","disconnect","session","method","headers","stringify","removeStoredSession","clearAllRelatedSessions","emit","isConnected","getWallet","on","cb","has","set","Set","get","off","delete","storageKey","suffix","Array","isArray","sort","url","ids","filter","includes","initSession","listenForConfirmation","result","storeSession","syncToWalletInstance","err","String","origin","window","location","resolved","wrap","fn","args","wrappedConfirm","wrappedReject","wrappedExpire","localStorage","setItem","stored","getItem","removeItem","key","keys","inst","toRemove","i","k","push","TonPassConnect","super","OneDollarConnect"],"mappings":"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"}
1
+ {"version":3,"file":"index.esm.js","sources":["../../transport.ts","../../modal.ts","../../client.ts","../../tonpass.ts","../../onedollar.ts"],"sourcesContent":["import type { ConnectResult } from './types';\n\ntype TransportCallback = (data: ConnectResult) => void;\ntype TransportErrorCallback = (error: string) => void;\n\n// ── WebSocket Transport ──\n\nexport class WsTransport {\n private ws: WebSocket | null = null;\n private reconnectTimer: ReturnType<typeof setTimeout> | null = null;\n private closed = false;\n\n constructor(\n private apiUrl: string,\n private sessionToken: string,\n private onConfirmed: TransportCallback,\n private onRejected: () => void,\n private onExpired: () => void,\n private onError: TransportErrorCallback,\n ) {}\n\n connect(): void {\n this.closed = false;\n const wsUrl = this.apiUrl\n .replace(/^http/, 'ws')\n .replace(/\\/$/, '');\n const url = `${wsUrl}/walletconnect?sessionToken=${this.sessionToken}`;\n\n try {\n // Socket.IO uses polling upgrade — use native WS for simplicity in SDK\n // The BE gateway uses socket.io, so we connect via socket.io protocol\n this.connectSocketIO();\n } catch {\n this.onError('WebSocket connection failed');\n }\n }\n\n private connectSocketIO(): void {\n const baseUrl = this.apiUrl.replace(/\\/$/, '');\n\n // Socket.IO handshake: first GET for sid, then upgrade to WS\n const pollingUrl = `${baseUrl}/walletconnect/?EIO=4&transport=polling`;\n\n fetch(pollingUrl)\n .then((res) => res.text())\n .then((body) => {\n // Socket.IO response format: \"0{...json...}\"\n const jsonStr = body.replace(/^\\d+/, '');\n const handshake = JSON.parse(jsonStr);\n const sid = handshake.sid;\n\n const wsBase = baseUrl.replace(/^http/, 'ws');\n const wsUrl = `${wsBase}/walletconnect/?EIO=4&transport=websocket&sid=${sid}`;\n\n this.ws = new WebSocket(wsUrl);\n\n this.ws.onopen = () => {\n // Socket.IO upgrade probe\n this.ws!.send('2probe');\n };\n\n this.ws.onmessage = (event) => {\n const msg = event.data as string;\n\n if (msg === '3probe') {\n // Upgrade confirmed, send upgrade packet + join room\n this.ws!.send('5');\n // Emit connect event with sessionToken as query (already in URL)\n // Socket.IO auto-joins based on handshake query\n return;\n }\n\n // Handle Socket.IO event messages: 42[\"event_name\", {...data}]\n if (msg.startsWith('42')) {\n try {\n const payload = JSON.parse(msg.slice(2));\n const [eventName, data] = payload;\n this.handleEvent(eventName, data);\n } catch {\n // ignore malformed\n }\n return;\n }\n\n // Ping from server\n if (msg === '2') {\n this.ws!.send('3');\n }\n };\n\n this.ws.onclose = () => {\n if (!this.closed) {\n this.scheduleReconnect();\n }\n };\n\n this.ws.onerror = () => {\n if (!this.closed) {\n this.scheduleReconnect();\n }\n };\n })\n .catch(() => {\n if (!this.closed) {\n this.scheduleReconnect();\n }\n });\n }\n\n private handleEvent(eventName: string, data: any): void {\n switch (eventName) {\n case 'session_confirmed':\n this.onConfirmed(data);\n this.close();\n break;\n case 'session_rejected':\n this.onRejected();\n this.close();\n break;\n case 'session_expired':\n this.onExpired();\n this.close();\n break;\n }\n }\n\n private scheduleReconnect(): void {\n if (this.closed || this.reconnectTimer) return;\n this.reconnectTimer = setTimeout(() => {\n this.reconnectTimer = null;\n this.connectSocketIO();\n }, 3000);\n }\n\n close(): void {\n this.closed = true;\n if (this.reconnectTimer) {\n clearTimeout(this.reconnectTimer);\n this.reconnectTimer = null;\n }\n if (this.ws) {\n this.ws.close();\n this.ws = null;\n }\n }\n}\n\n// ── Long-Poll Fallback ──\n\nexport class PollingTransport {\n private timer: ReturnType<typeof setInterval> | null = null;\n private stopped = false;\n\n constructor(\n private apiUrl: string,\n private sessionToken: string,\n private onConfirmed: TransportCallback,\n private onRejected: () => void,\n private onExpired: () => void,\n private onError: TransportErrorCallback,\n ) {}\n\n start(): void {\n this.stopped = false;\n this.poll();\n this.timer = setInterval(() => this.poll(), 2000);\n }\n\n private async poll(): Promise<void> {\n if (this.stopped) return;\n\n try {\n const baseUrl = this.apiUrl.replace(/\\/$/, '');\n const res = await fetch(\n `${baseUrl}/connect/status?token=${this.sessionToken}`,\n );\n if (!res.ok) return;\n\n const data = await res.json();\n\n switch (data.status) {\n case 'CONFIRMED':\n this.onConfirmed({ wallet: data.wallet, user: data.user });\n this.stop();\n break;\n case 'REJECTED':\n this.onRejected();\n this.stop();\n break;\n case 'EXPIRED':\n this.onExpired();\n this.stop();\n break;\n }\n } catch {\n // silently retry next interval\n }\n }\n\n stop(): void {\n this.stopped = true;\n if (this.timer) {\n clearInterval(this.timer);\n this.timer = null;\n }\n }\n}\n","import type { WalletMeta } from './types';\n\nconst MODAL_ID = '__wc_modal__';\n\nfunction getStyles(theme: 'light' | 'dark'): string {\n const isDark = theme === 'dark';\n const bg = isDark ? '#141414' : '#ffffff';\n const bgSecondary = isDark ? '#1e1e1e' : '#f4f4f4';\n const text = isDark ? '#ffffff' : '#141414';\n const textSecondary = isDark ? '#9a9a9a' : '#787878';\n const border = isDark ? '#2a2a2a' : '#e4e4e4';\n const accent = '#2bea6a';\n const accentDark = '#1db954';\n\n return `\n @keyframes wc-fadeIn { from{opacity:0} to{opacity:1} }\n @keyframes wc-slideUp {\n from{opacity:0;transform:translateY(100%)}\n to{opacity:1;transform:translateY(0)}\n }\n .wc-overlay {\n position:fixed; inset:0; z-index:99999;\n background:rgba(0,0,0,${isDark ? 0.75 : 0.45});\n display:flex; align-items:flex-end; justify-content:center;\n font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;\n backdrop-filter:blur(6px); -webkit-backdrop-filter:blur(6px);\n animation:wc-fadeIn .2s ease;\n }\n @media(min-width:480px){\n .wc-overlay{align-items:center}\n .wc-modal{border-radius:24px;max-height:85vh}\n }\n .wc-modal {\n background:${bg}; width:100%; max-width:420px;\n border-radius:24px 24px 0 0; overflow:hidden; color:${text};\n box-shadow:0 -8px 40px rgba(0,0,0,${isDark ? 0.5 : 0.15});\n animation:wc-slideUp .3s cubic-bezier(.16,1,.3,1);\n max-height:90vh; overflow-y:auto;\n }\n\n /* Handle bar */\n .wc-handle {\n width:36px; height:4px; border-radius:2px;\n background:${border}; margin:10px auto 0;\n }\n\n /* Header */\n .wc-header {\n display:flex; align-items:center; justify-content:space-between;\n padding:20px 24px 0;\n }\n .wc-header-left {\n display:flex; align-items:center; gap:10px;\n }\n .wc-header-icon {\n width:32px; height:32px; border-radius:10px; object-fit:cover;\n }\n .wc-title { font-size:17px; font-weight:700; margin:0; }\n .wc-close {\n width:30px; height:30px; display:flex; align-items:center; justify-content:center;\n background:${bgSecondary}; border:none; border-radius:50%;\n cursor:pointer; font-size:14px; color:${textSecondary};\n transition:all .15s;\n }\n .wc-close:hover { background:${border}; color:${text}; }\n .wc-subtitle {\n font-size:13px; color:${textSecondary}; margin:8px 24px 0;\n line-height:1.4;\n }\n\n .wc-body { padding:20px 24px 24px; }\n\n /* Grid wallet picker */\n .wc-wallet-grid {\n display:grid; grid-template-columns:repeat(4,1fr);\n gap:16px 12px; list-style:none; margin:0; padding:0;\n }\n .wc-wallet-grid-item {\n display:flex; flex-direction:column; align-items:center;\n gap:8px; cursor:pointer; padding:8px 4px; border-radius:16px;\n transition:all .15s; border:2px solid transparent;\n }\n .wc-wallet-grid-item:hover {\n background:${bgSecondary}; border-color:${border};\n }\n .wc-wallet-grid-icon {\n width:56px; height:56px; border-radius:16px;\n object-fit:cover; box-shadow:0 2px 8px rgba(0,0,0,${isDark ? 0.3 : 0.08});\n }\n .wc-wallet-grid-icon-placeholder {\n width:56px; height:56px; border-radius:16px;\n background:linear-gradient(135deg,${accentDark},${accent});\n display:flex; align-items:center; justify-content:center;\n color:#fff; font-weight:800; font-size:22px;\n box-shadow:0 2px 8px rgba(0,0,0,${isDark ? 0.3 : 0.08});\n }\n .wc-wallet-grid-name {\n font-size:11px; font-weight:500; text-align:center;\n color:${textSecondary}; line-height:1.2;\n max-width:72px; overflow:hidden; text-overflow:ellipsis;\n white-space:nowrap;\n }\n\n /* List wallet picker (alternative) */\n .wc-wallet-list { list-style:none; margin:0; padding:0; }\n .wc-wallet-item {\n display:flex; align-items:center; gap:14px;\n padding:12px 16px; border-radius:16px; cursor:pointer;\n border:1.5px solid ${border}; margin-bottom:8px;\n transition:all .15s;\n }\n .wc-wallet-item:hover {\n background:${bgSecondary}; border-color:${accent};\n }\n .wc-wallet-list-icon {\n width:40px; height:40px; border-radius:12px; object-fit:cover;\n }\n .wc-wallet-list-icon-placeholder {\n width:40px; height:40px; border-radius:12px;\n background:linear-gradient(135deg,${accentDark},${accent});\n display:flex; align-items:center; justify-content:center;\n color:#fff; font-weight:700; font-size:16px;\n }\n .wc-wallet-item-info { flex:1; }\n .wc-wallet-item-name { font-size:14px; font-weight:600; }\n .wc-wallet-item-desc { font-size:11px; color:${textSecondary}; margin-top:1px; }\n .wc-wallet-item-arrow { color:${textSecondary}; font-size:16px; }\n\n /* Tabs */\n .wc-tabs {\n display:flex; background:${bgSecondary}; border-radius:12px;\n padding:3px; margin-bottom:20px;\n }\n .wc-tab {\n flex:1; padding:10px; text-align:center; cursor:pointer;\n font-size:13px; font-weight:600; background:transparent;\n border:none; color:${textSecondary}; border-radius:10px;\n transition:all .2s;\n }\n .wc-tab:hover { color:${text}; }\n .wc-tab.active {\n background:${bg}; color:${text};\n box-shadow:0 1px 4px rgba(0,0,0,${isDark ? 0.3 : 0.08});\n }\n\n /* Deeplink */\n .wc-deeplink-btn {\n display:flex; align-items:center; justify-content:center; gap:10px;\n width:100%; padding:16px; border:none; border-radius:16px;\n background:linear-gradient(135deg,${accentDark},${accent});\n color:#fff; font-size:15px; font-weight:700; cursor:pointer;\n text-decoration:none; transition:all .2s;\n box-shadow:0 4px 20px rgba(43,234,106,0.2);\n box-sizing:border-box;\n }\n .wc-deeplink-btn:hover {\n transform:translateY(-1px);\n box-shadow:0 6px 28px rgba(43,234,106,0.3);\n }\n\n /* QR */\n .wc-qr-container {\n display:flex; flex-direction:column; align-items:center; gap:16px;\n }\n .wc-qr-wrap {\n padding:16px; background:#fff; border-radius:20px;\n box-shadow:0 2px 16px rgba(0,0,0,${isDark ? 0.2 : 0.06});\n }\n .wc-qr-wrap img { display:block; border-radius:4px; }\n .wc-qr-hint { font-size:12px; color:${textSecondary}; text-align:center; }\n\n /* Status */\n .wc-status {\n display:flex; align-items:center; justify-content:center;\n gap:10px; padding:20px 0 4px; font-size:13px; color:${textSecondary};\n }\n .wc-spinner {\n width:16px; height:16px; border:2px solid ${border};\n border-top-color:${accent}; border-radius:50%;\n animation:wc-spin .7s linear infinite;\n }\n @keyframes wc-spin { to{transform:rotate(360deg)} }\n\n /* Back */\n .wc-back {\n background:none; border:none; cursor:pointer; padding:0;\n color:${textSecondary}; display:flex; align-items:center;\n transition:color .15s; font-size:18px;\n }\n .wc-back:hover { color:${text}; }\n\n /* Footer */\n .wc-footer {\n text-align:center; padding:4px 0 20px;\n font-size:11px; color:${isDark ? '#555' : '#bbb'};\n }\n\n /* Success screen */\n .wc-success {\n display:flex; flex-direction:column; align-items:center;\n padding:12px 0 4px; gap:20px;\n }\n .wc-success-check {\n width:64px; height:64px; border-radius:50%;\n background:linear-gradient(135deg,${accentDark},${accent});\n display:flex; align-items:center; justify-content:center;\n box-shadow:0 4px 20px rgba(43,234,106,0.25);\n animation:wc-popIn .4s cubic-bezier(.16,1,.3,1);\n }\n @keyframes wc-popIn {\n from{transform:scale(0);opacity:0}\n 50%{transform:scale(1.15)}\n to{transform:scale(1);opacity:1}\n }\n .wc-success-check svg { width:32px; height:32px; color:#fff; }\n .wc-success-title {\n font-size:18px; font-weight:700; color:${text};\n }\n .wc-success-user {\n display:flex; align-items:center; gap:14px;\n background:${bgSecondary}; border-radius:16px;\n padding:16px 18px; width:100%; box-sizing:border-box;\n }\n .wc-success-avatar {\n width:48px; height:48px; border-radius:50%; object-fit:cover;\n flex-shrink:0; border:2px solid ${border};\n }\n .wc-success-avatar-placeholder {\n width:48px; height:48px; border-radius:50%;\n background:linear-gradient(135deg,${accentDark},${accent});\n display:flex; align-items:center; justify-content:center;\n color:#fff; font-weight:700; font-size:18px; flex-shrink:0;\n border:2px solid ${border};\n }\n .wc-success-user-info { flex:1; min-width:0; }\n .wc-success-user-name { font-size:15px; font-weight:600; color:${text}; }\n .wc-success-user-addr {\n font-size:12px; color:${textSecondary}; margin-top:4px;\n font-family:'SF Mono',Monaco,Consolas,monospace;\n word-break:break-all; line-height:1.4;\n }\n .wc-success-done {\n width:100%; padding:14px; border:none; border-radius:14px;\n background:linear-gradient(135deg,${accentDark},${accent});\n color:#fff; font-size:14px; font-weight:700; cursor:pointer;\n transition:all .2s;\n box-shadow:0 4px 16px rgba(43,234,106,0.2);\n }\n .wc-success-done:hover {\n transform:translateY(-1px);\n box-shadow:0 6px 24px rgba(43,234,106,0.3);\n }\n `;\n}\n\nconst TELEGRAM_SVG = `<svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M11.944 0A12 12 0 1 0 24 12.056A12.01 12.01 0 0 0 11.944 0Zm4.962 7.224c.1-.002.321.023.465.14a.506.506 0 0 1 .171.325c.016.093.036.306.02.472c-.18 1.898-.962 6.502-1.36 8.627c-.168.9-.499 1.201-.82 1.23c-.696.065-1.225-.46-1.9-.902c-1.056-.693-1.653-1.124-2.678-1.8c-1.185-.78-.417-1.21.258-1.91c.177-.184 3.247-2.977 3.307-3.23c.007-.032.014-.15-.056-.212s-.174-.041-.249-.024c-.106.024-1.793 1.14-5.061 3.345c-.48.33-.913.49-1.302.48c-.428-.008-1.252-.241-1.865-.44c-.752-.245-1.349-.374-1.297-.789c.027-.216.325-.437.893-.663c3.498-1.524 5.83-2.529 6.998-3.014c3.332-1.386 4.025-1.627 4.476-1.635Z\"/></svg>`;\n\nfunction generateQRDataUrl(text: string, size = 220): string {\n return `https://api.qrserver.com/v1/create-qr-code/?size=${size}x${size}&data=${encodeURIComponent(text)}&margin=8`;\n}\n\nexport class Modal {\n private overlay: HTMLDivElement | null = null;\n private theme: 'light' | 'dark';\n private onClose: () => void;\n\n constructor(theme: 'light' | 'dark', onClose: () => void) {\n this.theme = theme;\n this.onClose = onClose;\n }\n\n showWalletPicker(\n wallets: WalletMeta[],\n onSelect: (wallet: WalletMeta) => void,\n ): void {\n const useGrid = wallets.length >= 3;\n\n const listHtml = useGrid\n ? `<ul class=\"wc-wallet-grid\">${wallets\n .map(\n (w) => `\n <li class=\"wc-wallet-grid-item\" data-wallet-id=\"${w.walletId}\">\n ${\n w.icon\n ? `<img class=\"wc-wallet-grid-icon\" src=\"${w.icon}\" alt=\"${w.name}\" />`\n : `<div class=\"wc-wallet-grid-icon-placeholder\">${w.name.charAt(0)}</div>`\n }\n <span class=\"wc-wallet-grid-name\">${w.name}</span>\n </li>`,\n )\n .join('')}</ul>`\n : `<ul class=\"wc-wallet-list\">${wallets\n .map(\n (w) => `\n <li class=\"wc-wallet-item\" data-wallet-id=\"${w.walletId}\">\n ${\n w.icon\n ? `<img class=\"wc-wallet-list-icon\" src=\"${w.icon}\" alt=\"${w.name}\" />`\n : `<div class=\"wc-wallet-list-icon-placeholder\">${w.name.charAt(0)}</div>`\n }\n <div class=\"wc-wallet-item-info\">\n <div class=\"wc-wallet-item-name\">${w.name}</div>\n ${w.description ? `<div class=\"wc-wallet-item-desc\">${w.description}</div>` : ''}\n </div>\n <span class=\"wc-wallet-item-arrow\">&#8250;</span>\n </li>`,\n )\n .join('')}</ul>`;\n\n const html = `\n <div class=\"wc-handle\"></div>\n <div class=\"wc-header\">\n <h3 class=\"wc-title\">Connect your wallet</h3>\n <button class=\"wc-close\" data-action=\"close\">&#10005;</button>\n </div>\n <p class=\"wc-subtitle\">Choose a wallet to connect to this app</p>\n <div class=\"wc-body\">${listHtml}</div>\n <div class=\"wc-footer\">Powered by WalletConnect</div>\n `;\n\n this.render(html);\n\n wallets.forEach((w) => {\n this.overlay\n ?.querySelector(`[data-wallet-id=\"${w.walletId}\"]`)\n ?.addEventListener('click', () => onSelect(w));\n });\n }\n\n showConnect(\n wallet: WalletMeta,\n deeplink: string,\n showBack: boolean,\n onBack?: () => void,\n ): void {\n const qrUrl = generateQRDataUrl(deeplink);\n\n const html = `\n <div class=\"wc-handle\"></div>\n <div class=\"wc-header\">\n <div class=\"wc-header-left\">\n ${showBack ? '<button class=\"wc-back\" data-action=\"back\">&#8592;</button>' : ''}\n ${wallet.icon ? `<img class=\"wc-header-icon\" src=\"${wallet.icon}\" />` : ''}\n <h3 class=\"wc-title\">${wallet.name}</h3>\n </div>\n <button class=\"wc-close\" data-action=\"close\">&#10005;</button>\n </div>\n <p class=\"wc-subtitle\">Approve the connection request in your wallet</p>\n <div class=\"wc-body\">\n <div class=\"wc-tabs\">\n <button class=\"wc-tab active\" data-tab=\"mobile\">Mobile</button>\n <button class=\"wc-tab\" data-tab=\"qr\">QR Code</button>\n </div>\n <div data-panel=\"mobile\">\n <a class=\"wc-deeplink-btn\" href=\"${deeplink}\" target=\"_blank\">\n ${TELEGRAM_SVG}\n Open in Telegram\n </a>\n </div>\n <div data-panel=\"qr\" style=\"display:none\">\n <div class=\"wc-qr-container\">\n <div class=\"wc-qr-wrap\">\n <img src=\"${qrUrl}\" width=\"220\" height=\"220\" alt=\"QR\" />\n </div>\n <div class=\"wc-qr-hint\">Scan with your phone camera or wallet app</div>\n </div>\n </div>\n <div class=\"wc-status\">\n <div class=\"wc-spinner\"></div>\n <span>Waiting for confirmation...</span>\n </div>\n </div>\n <div class=\"wc-footer\">Powered by WalletConnect</div>\n `;\n\n this.render(html);\n\n const tabs = this.overlay?.querySelectorAll('.wc-tab');\n const panels = this.overlay?.querySelectorAll('[data-panel]');\n tabs?.forEach((tab) => {\n tab.addEventListener('click', () => {\n const target = (tab as HTMLElement).dataset.tab;\n tabs.forEach((t) => t.classList.remove('active'));\n tab.classList.add('active');\n panels?.forEach((p) => {\n (p as HTMLElement).style.display =\n (p as HTMLElement).dataset.panel === target ? 'block' : 'none';\n });\n });\n });\n\n if (showBack && onBack) {\n this.overlay\n ?.querySelector('[data-action=\"back\"]')\n ?.addEventListener('click', onBack);\n }\n }\n\n showSuccess(\n wallet: WalletMeta,\n address: string | null,\n user: { username?: string; avatar?: string } | null,\n onDone: () => void,\n ): void {\n const checkSvg = `<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"/></svg>`;\n\n const displayName = user?.username || 'User';\n const initials = displayName.slice(0, 2).toUpperCase();\n\n const avatarHtml = user?.avatar\n ? `<img class=\"wc-success-avatar\" src=\"${user.avatar}\" alt=\"${displayName}\" />`\n : `<div class=\"wc-success-avatar-placeholder\">${initials}</div>`;\n\n const html = `\n <div class=\"wc-handle\"></div>\n <div class=\"wc-header\">\n <h3 class=\"wc-title\">Connected</h3>\n <button class=\"wc-close\" data-action=\"close\">&#10005;</button>\n </div>\n <div class=\"wc-body\">\n <div class=\"wc-success\">\n <div class=\"wc-success-check\">${checkSvg}</div>\n <div class=\"wc-success-title\">Connection Successful</div>\n <div class=\"wc-success-user\">\n ${avatarHtml}\n <div class=\"wc-success-user-info\">\n <div class=\"wc-success-user-name\">${displayName}</div>\n ${address ? `<div class=\"wc-success-user-addr\" title=\"${address}\">${address}</div>` : ''}\n </div>\n </div>\n <button class=\"wc-success-done\" data-action=\"done\">Done</button>\n </div>\n </div>\n <div class=\"wc-footer\">Powered by WalletConnect</div>\n `;\n\n this.render(html);\n\n this.overlay\n ?.querySelector('[data-action=\"done\"]')\n ?.addEventListener('click', onDone);\n }\n\n updateStatus(text: string, showSpinner = true): void {\n const el = this.overlay?.querySelector('.wc-status');\n if (el) {\n el.innerHTML = `\n ${showSpinner ? '<div class=\"wc-spinner\"></div>' : ''}\n <span>${text}</span>\n `;\n }\n }\n\n private render(innerHtml: string): void {\n this.destroy();\n\n const el = document.createElement('div');\n el.id = MODAL_ID;\n el.innerHTML = `\n <style>${getStyles(this.theme)}</style>\n <div class=\"wc-overlay\">\n <div class=\"wc-modal\">${innerHtml}</div>\n </div>\n `;\n\n document.body.appendChild(el);\n this.overlay = el;\n\n this.overlay\n .querySelector('[data-action=\"close\"]')\n ?.addEventListener('click', () => { this.onClose(); this.destroy(); });\n\n this.overlay\n .querySelector('.wc-overlay')\n ?.addEventListener('click', (e) => {\n if ((e.target as HTMLElement).classList.contains('wc-overlay')) {\n this.onClose();\n this.destroy();\n }\n });\n }\n\n destroy(): void {\n document.getElementById(MODAL_ID)?.remove();\n this.overlay = null;\n }\n}\n","import type {\n WalletConnectConfig,\n WalletMeta,\n ConnectResult,\n ConnectSession,\n InitSessionResponse,\n WalletConnectEventType,\n WalletConnectEventCallback,\n} from './types';\nimport { WsTransport, PollingTransport } from './transport';\nimport { Modal } from './modal';\n\nconst STORAGE_KEY_PREFIX = '__wc_session_';\nconst DEFAULT_REGISTRY_URL = 'https://cdn.jsdelivr.net/npm/toncorp-wallet-connect-sdk@latest/registry.json';\n\nexport class BaseWalletConnect {\n protected config: Required<\n Pick<WalletConnectConfig, 'appId' | 'registryUrl' | 'theme'>\n > &\n Pick<WalletConnectConfig, 'walletId'>;\n\n private listeners: Map<WalletConnectEventType, Set<WalletConnectEventCallback>> = new Map();\n private modal: Modal | null = null;\n private wsTransport: WsTransport | null = null;\n private pollingTransport: PollingTransport | null = null;\n private currentResult: ConnectResult | null = null;\n\n constructor(config: WalletConnectConfig) {\n this.config = {\n appId: config.appId,\n registryUrl: config.registryUrl || DEFAULT_REGISTRY_URL,\n walletId: config.walletId,\n theme: config.theme || 'light',\n };\n\n this.restoreSession();\n this.registerGlobal();\n }\n\n // ── Public API ──\n\n async connect(): Promise<ConnectResult> {\n if (this.currentResult) {\n return this.currentResult;\n }\n\n const wallets = await this.fetchWallets();\n const filtered = this.filterWallets(wallets);\n\n if (filtered.length === 0) {\n throw new Error('No supported wallets available');\n }\n\n return new Promise<ConnectResult>((resolve, reject) => {\n const onClose = () => {\n this.cleanup();\n reject(new Error('User closed modal'));\n };\n\n this.modal = new Modal(this.config.theme, onClose);\n\n if (filtered.length === 1) {\n this.startConnect(filtered[0], false, resolve, reject);\n } else {\n this.modal.showWalletPicker(filtered, (wallet) => {\n this.startConnect(wallet, true, resolve, reject);\n });\n }\n });\n }\n\n disconnect(): void {\n // Find session from this instance or any other connected instance\n let session = this.currentResult?.session;\n if (!session && typeof window !== 'undefined') {\n for (const key of Object.keys(window)) {\n const inst = (window as any)[key];\n if (inst instanceof BaseWalletConnect && inst.currentResult?.session) {\n session = inst.currentResult.session;\n break;\n }\n }\n }\n\n // Call disconnect API (fire-and-forget)\n if (session) {\n const baseUrl = session.apiUrl.replace(/\\/$/, '');\n fetch(`${baseUrl}/connect/disconnect-by-token`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ sessionToken: session.sessionToken }),\n }).catch(() => {});\n }\n\n // Clear all localStorage keys and window instances\n this.currentResult = null;\n this.removeStoredSession();\n this.clearAllRelatedSessions();\n this.cleanup();\n this.emit('disconnect');\n }\n\n isConnected(): boolean {\n return this.currentResult !== null;\n }\n\n getWallet(): ConnectResult | null {\n return this.currentResult;\n }\n\n on(event: WalletConnectEventType, cb: WalletConnectEventCallback): void {\n if (!this.listeners.has(event)) {\n this.listeners.set(event, new Set());\n }\n this.listeners.get(event)!.add(cb);\n }\n\n off(event: WalletConnectEventType, cb: WalletConnectEventCallback): void {\n this.listeners.get(event)?.delete(cb);\n }\n\n // ── Internal ──\n\n private get storageKey(): string {\n const walletId = this.config.walletId;\n const suffix = Array.isArray(walletId)\n ? walletId.sort().join('_')\n : walletId || 'all';\n return `${STORAGE_KEY_PREFIX}${suffix}__`;\n }\n\n private async fetchWallets(): Promise<WalletMeta[]> {\n const url = this.config.registryUrl.replace(/\\/$/, '');\n const res = await fetch(url);\n if (!res.ok) throw new Error('Failed to fetch wallets');\n return res.json();\n }\n\n private filterWallets(wallets: WalletMeta[]): WalletMeta[] {\n if (!this.config.walletId) return wallets;\n\n const ids = Array.isArray(this.config.walletId)\n ? this.config.walletId\n : [this.config.walletId];\n\n return wallets.filter((w) => ids.includes(w.walletId));\n }\n\n private async startConnect(\n wallet: WalletMeta,\n showBack: boolean,\n resolve: (result: ConnectResult) => void,\n reject: (error: Error) => void,\n ): Promise<void> {\n try {\n const session = await this.initSession(wallet);\n\n this.modal?.showConnect(wallet, session.deeplink, showBack, () => {\n this.cleanup();\n this.connect().then(resolve).catch(reject);\n });\n\n this.listenForConfirmation(\n wallet.apiUrl,\n session.sessionToken,\n (result) => {\n // Attach session info for disconnect\n result.session = {\n sessionToken: session.sessionToken,\n walletId: wallet.walletId,\n apiUrl: wallet.apiUrl,\n };\n this.currentResult = result;\n this.storeSession(result);\n this.syncToWalletInstance(wallet.walletId, result);\n this.emit('connect', result);\n\n // Show success screen\n this.modal?.showSuccess(\n wallet,\n result.wallet?.address || null,\n result.user || null,\n () => {\n this.modal?.destroy();\n this.modal = null;\n resolve(result);\n },\n );\n },\n () => {\n this.modal?.updateStatus('Connection rejected', false);\n setTimeout(() => {\n this.modal?.destroy();\n this.modal = null;\n reject(new Error('Connection rejected by user'));\n }, 1500);\n },\n () => {\n this.modal?.updateStatus('Session expired', false);\n this.emit('session_expired');\n setTimeout(() => {\n this.modal?.destroy();\n this.modal = null;\n reject(new Error('Session expired'));\n }, 1500);\n },\n );\n } catch (err) {\n this.modal?.destroy();\n this.modal = null;\n reject(err instanceof Error ? err : new Error(String(err)));\n }\n }\n\n private async initSession(wallet: WalletMeta): Promise<InitSessionResponse> {\n const baseUrl = wallet.apiUrl.replace(/\\/$/, '');\n const res = await fetch(`${baseUrl}/connect/init`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n appId: this.config.appId,\n walletId: wallet.walletId,\n origin: typeof window !== 'undefined' ? window.location.origin : '',\n }),\n });\n if (!res.ok) throw new Error('Failed to init session');\n return res.json();\n }\n\n private listenForConfirmation(\n apiUrl: string,\n sessionToken: string,\n onConfirmed: (result: ConnectResult) => void,\n onRejected: () => void,\n onExpired: () => void,\n ): void {\n let resolved = false;\n\n const wrap = <T extends (...args: any[]) => void>(fn: T): T =>\n ((...args: any[]) => {\n if (resolved) return;\n resolved = true;\n this.wsTransport?.close();\n this.pollingTransport?.stop();\n fn(...args);\n }) as unknown as T;\n\n const wrappedConfirm = wrap(onConfirmed);\n const wrappedReject = wrap(onRejected);\n const wrappedExpire = wrap(onExpired);\n\n // Start polling immediately as primary transport\n this.pollingTransport = new PollingTransport(\n apiUrl,\n sessionToken,\n wrappedConfirm,\n wrappedReject,\n wrappedExpire,\n (msg) => this.emit('error', msg),\n );\n this.pollingTransport.start();\n\n // Also try WS for faster response\n this.wsTransport = new WsTransport(\n apiUrl,\n sessionToken,\n wrappedConfirm,\n wrappedReject,\n wrappedExpire,\n () => {}, // WS fail is fine, polling is running\n );\n this.wsTransport.connect();\n }\n\n private cleanup(): void {\n this.wsTransport?.close();\n this.wsTransport = null;\n this.pollingTransport?.stop();\n this.pollingTransport = null;\n this.modal?.destroy();\n this.modal = null;\n }\n\n private emit(event: WalletConnectEventType, data?: any): void {\n this.listeners.get(event)?.forEach((cb) => cb(data));\n }\n\n // ── Persistence ──\n\n private storeSession(result: ConnectResult): void {\n try {\n localStorage.setItem(this.storageKey, JSON.stringify(result));\n } catch {\n // localStorage unavailable\n }\n }\n\n private restoreSession(): void {\n try {\n const stored = localStorage.getItem(this.storageKey);\n if (stored) {\n this.currentResult = JSON.parse(stored);\n }\n } catch {\n // ignore\n }\n }\n\n private removeStoredSession(): void {\n try {\n localStorage.removeItem(this.storageKey);\n } catch {\n // ignore\n }\n }\n\n // ── Global window registration ──\n\n private registerGlobal(): void {\n if (typeof window === 'undefined') return;\n\n const walletId = this.config.walletId;\n const key = Array.isArray(walletId)\n ? walletId[0]\n : walletId || 'walletconnect';\n\n (window as any)[key] = this;\n }\n\n /** Sync connect result to the specific wallet instance on window (e.g. window.onedollar) */\n private syncToWalletInstance(walletId: string, result: ConnectResult): void {\n if (typeof window === 'undefined') return;\n\n const target = (window as any)[walletId];\n if (target && target !== this && target instanceof BaseWalletConnect) {\n (target as any).currentResult = result;\n (target as any).storeSession(result);\n }\n }\n\n /** Clear all related sessions from all window instances and localStorage */\n private clearAllRelatedSessions(): void {\n if (typeof window === 'undefined') return;\n\n // Find all BaseWalletConnect instances on window and clear them\n try {\n for (const key of Object.keys(window)) {\n const inst = (window as any)[key];\n if (inst && inst !== this && inst instanceof BaseWalletConnect) {\n (inst as any).currentResult = null;\n (inst as any).removeStoredSession();\n }\n }\n } catch {\n // ignore\n }\n\n // Clear all wc localStorage keys\n try {\n const toRemove: string[] = [];\n for (let i = 0; i < localStorage.length; i++) {\n const k = localStorage.key(i);\n if (k && k.startsWith(STORAGE_KEY_PREFIX)) {\n toRemove.push(k);\n }\n }\n toRemove.forEach((k) => localStorage.removeItem(k));\n } catch {\n // ignore\n }\n }\n}\n","import { BaseWalletConnect } from './client';\nimport type { WalletConnectConfig } from './types';\n\nexport class TonPassConnect extends BaseWalletConnect {\n constructor(config: Omit<WalletConnectConfig, 'walletId'>) {\n super({ ...config, walletId: 'tonpass' });\n }\n}\n","import { BaseWalletConnect } from './client';\nimport type { WalletConnectConfig } from './types';\n\nexport class OneDollarConnect extends BaseWalletConnect {\n constructor(config: Omit<WalletConnectConfig, 'walletId'>) {\n super({ ...config, walletId: 'onedollar' });\n }\n}\n"],"names":["WsTransport","constructor","apiUrl","sessionToken","onConfirmed","onRejected","onExpired","onError","this","ws","reconnectTimer","closed","connect","replace","connectSocketIO","baseUrl","fetch","then","res","text","body","jsonStr","sid","JSON","parse","wsUrl","WebSocket","onopen","send","onmessage","event","msg","data","startsWith","payload","slice","eventName","handleEvent","onclose","scheduleReconnect","onerror","catch","close","setTimeout","clearTimeout","PollingTransport","timer","stopped","start","poll","setInterval","ok","json","status","wallet","user","stop","clearInterval","MODAL_ID","Modal","theme","onClose","overlay","showWalletPicker","wallets","onSelect","html","length","map","w","walletId","icon","name","charAt","join","description","render","forEach","querySelector","addEventListener","showConnect","deeplink","showBack","onBack","qrUrl","size","encodeURIComponent","generateQRDataUrl","tabs","querySelectorAll","panels","tab","target","dataset","t","classList","remove","add","p","style","display","panel","showSuccess","address","onDone","displayName","username","initials","toUpperCase","avatar","updateStatus","showSpinner","el","innerHTML","innerHtml","destroy","document","createElement","id","isDark","bg","bgSecondary","textSecondary","border","accent","accentDark","getStyles","appendChild","e","contains","getElementById","STORAGE_KEY_PREFIX","BaseWalletConnect","config","listeners","Map","modal","wsTransport","pollingTransport","currentResult","appId","registryUrl","restoreSession","registerGlobal","fetchWallets","filtered","filterWallets","Error","Promise","resolve","reject","cleanup","startConnect","disconnect","session","window","key","Object","keys","inst","method","headers","stringify","removeStoredSession","clearAllRelatedSessions","emit","isConnected","getWallet","on","cb","has","set","Set","get","off","delete","storageKey","suffix","Array","isArray","sort","url","ids","filter","includes","initSession","listenForConfirmation","result","storeSession","syncToWalletInstance","err","String","origin","location","resolved","wrap","fn","args","wrappedConfirm","wrappedReject","wrappedExpire","localStorage","setItem","stored","getItem","removeItem","toRemove","i","k","push","TonPassConnect","super","OneDollarConnect"],"mappings":"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"}
package/dist/index.umd.js CHANGED
@@ -1,2 +1,2 @@
1
- !function(e,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports):"function"==typeof define&&define.amd?define(["exports"],n):n((e="undefined"!=typeof globalThis?globalThis:e||self).WalletConnectSDK={})}(this,function(e){"use strict";class n{constructor(e,n,t,s,i,o){this.apiUrl=e,this.sessionToken=n,this.onConfirmed=t,this.onRejected=s,this.onExpired=i,this.onError=o,this.ws=null,this.reconnectTimer=null,this.closed=!1}connect(){this.closed=!1;this.apiUrl.replace(/^http/,"ws").replace(/\/$/,"");this.sessionToken;try{this.connectSocketIO()}catch{this.onError("WebSocket connection failed")}}connectSocketIO(){const e=this.apiUrl.replace(/\/$/,"");fetch(`${e}/walletconnect/?EIO=4&transport=polling`).then(e=>e.text()).then(n=>{const t=n.replace(/^\d+/,""),s=JSON.parse(t).sid,i=`${e.replace(/^http/,"ws")}/walletconnect/?EIO=4&transport=websocket&sid=${s}`;this.ws=new WebSocket(i),this.ws.onopen=()=>{this.ws.send("2probe")},this.ws.onmessage=e=>{const n=e.data;if("3probe"!==n)if(n.startsWith("42"))try{const e=JSON.parse(n.slice(2)),[t,s]=e;this.handleEvent(t,s)}catch{}else"2"===n&&this.ws.send("3");else this.ws.send("5")},this.ws.onclose=()=>{this.closed||this.scheduleReconnect()},this.ws.onerror=()=>{this.closed||this.scheduleReconnect()}}).catch(()=>{this.closed||this.scheduleReconnect()})}handleEvent(e,n){switch(e){case"session_confirmed":this.onConfirmed(n),this.close();break;case"session_rejected":this.onRejected(),this.close();break;case"session_expired":this.onExpired(),this.close()}}scheduleReconnect(){this.closed||this.reconnectTimer||(this.reconnectTimer=setTimeout(()=>{this.reconnectTimer=null,this.connectSocketIO()},3e3))}close(){this.closed=!0,this.reconnectTimer&&(clearTimeout(this.reconnectTimer),this.reconnectTimer=null),this.ws&&(this.ws.close(),this.ws=null)}}class t{constructor(e,n,t,s,i,o){this.apiUrl=e,this.sessionToken=n,this.onConfirmed=t,this.onRejected=s,this.onExpired=i,this.onError=o,this.timer=null,this.stopped=!1}start(){this.stopped=!1,this.poll(),this.timer=setInterval(()=>this.poll(),2e3)}async poll(){if(!this.stopped)try{const e=this.apiUrl.replace(/\/$/,""),n=await fetch(`${e}/connect/status?token=${this.sessionToken}`);if(!n.ok)return;const t=await n.json();switch(t.status){case"CONFIRMED":this.onConfirmed({wallet:t.wallet,user:t.user}),this.stop();break;case"REJECTED":this.onRejected(),this.stop();break;case"EXPIRED":this.onExpired(),this.stop()}}catch{}}stop(){this.stopped=!0,this.timer&&(clearInterval(this.timer),this.timer=null)}}const s="__wc_modal__";class i{constructor(e,n){this.overlay=null,this.theme=e,this.onClose=n}showWalletPicker(e,n){const t=`\n <div class="wc-handle"></div>\n <div class="wc-header">\n <h3 class="wc-title">Connect your wallet</h3>\n <button class="wc-close" data-action="close">&#10005;</button>\n </div>\n <p class="wc-subtitle">Choose a wallet to connect to this app</p>\n <div class="wc-body">${e.length>=3?`<ul class="wc-wallet-grid">${e.map(e=>`\n <li class="wc-wallet-grid-item" data-wallet-id="${e.walletId}">\n ${e.icon?`<img class="wc-wallet-grid-icon" src="${e.icon}" alt="${e.name}" />`:`<div class="wc-wallet-grid-icon-placeholder">${e.name.charAt(0)}</div>`}\n <span class="wc-wallet-grid-name">${e.name}</span>\n </li>`).join("")}</ul>`:`<ul class="wc-wallet-list">${e.map(e=>`\n <li class="wc-wallet-item" data-wallet-id="${e.walletId}">\n ${e.icon?`<img class="wc-wallet-list-icon" src="${e.icon}" alt="${e.name}" />`:`<div class="wc-wallet-list-icon-placeholder">${e.name.charAt(0)}</div>`}\n <div class="wc-wallet-item-info">\n <div class="wc-wallet-item-name">${e.name}</div>\n ${e.description?`<div class="wc-wallet-item-desc">${e.description}</div>`:""}\n </div>\n <span class="wc-wallet-item-arrow">&#8250;</span>\n </li>`).join("")}</ul>`}</div>\n <div class="wc-footer">Powered by WalletConnect</div>\n `;this.render(t),e.forEach(e=>{this.overlay?.querySelector(`[data-wallet-id="${e.walletId}"]`)?.addEventListener("click",()=>n(e))})}showConnect(e,n,t,s){const i=function(e,n=220){return`https://api.qrserver.com/v1/create-qr-code/?size=${n}x${n}&data=${encodeURIComponent(e)}&margin=8`}(n),o=`\n <div class="wc-handle"></div>\n <div class="wc-header">\n <div class="wc-header-left">\n ${t?'<button class="wc-back" data-action="back">&#8592;</button>':""}\n ${e.icon?`<img class="wc-header-icon" src="${e.icon}" />`:""}\n <h3 class="wc-title">${e.name}</h3>\n </div>\n <button class="wc-close" data-action="close">&#10005;</button>\n </div>\n <p class="wc-subtitle">Approve the connection request in your wallet</p>\n <div class="wc-body">\n <div class="wc-tabs">\n <button class="wc-tab active" data-tab="mobile">Mobile</button>\n <button class="wc-tab" data-tab="qr">QR Code</button>\n </div>\n <div data-panel="mobile">\n <a class="wc-deeplink-btn" href="${n}" target="_blank">\n <svg width="20" height="20" viewBox="0 0 24 24" fill="currentColor"><path d="M11.944 0A12 12 0 1 0 24 12.056A12.01 12.01 0 0 0 11.944 0Zm4.962 7.224c.1-.002.321.023.465.14a.506.506 0 0 1 .171.325c.016.093.036.306.02.472c-.18 1.898-.962 6.502-1.36 8.627c-.168.9-.499 1.201-.82 1.23c-.696.065-1.225-.46-1.9-.902c-1.056-.693-1.653-1.124-2.678-1.8c-1.185-.78-.417-1.21.258-1.91c.177-.184 3.247-2.977 3.307-3.23c.007-.032.014-.15-.056-.212s-.174-.041-.249-.024c-.106.024-1.793 1.14-5.061 3.345c-.48.33-.913.49-1.302.48c-.428-.008-1.252-.241-1.865-.44c-.752-.245-1.349-.374-1.297-.789c.027-.216.325-.437.893-.663c3.498-1.524 5.83-2.529 6.998-3.014c3.332-1.386 4.025-1.627 4.476-1.635Z"/></svg>\n Open in Telegram\n </a>\n </div>\n <div data-panel="qr" style="display:none">\n <div class="wc-qr-container">\n <div class="wc-qr-wrap">\n <img src="${i}" width="220" height="220" alt="QR" />\n </div>\n <div class="wc-qr-hint">Scan with your phone camera or wallet app</div>\n </div>\n </div>\n <div class="wc-status">\n <div class="wc-spinner"></div>\n <span>Waiting for confirmation...</span>\n </div>\n </div>\n <div class="wc-footer">Powered by WalletConnect</div>\n `;this.render(o);const r=this.overlay?.querySelectorAll(".wc-tab"),a=this.overlay?.querySelectorAll("[data-panel]");r?.forEach(e=>{e.addEventListener("click",()=>{const n=e.dataset.tab;r.forEach(e=>e.classList.remove("active")),e.classList.add("active"),a?.forEach(e=>{e.style.display=e.dataset.panel===n?"block":"none"})})}),t&&s&&this.overlay?.querySelector('[data-action="back"]')?.addEventListener("click",s)}showSuccess(e,n,t,s){const i=t?.username||"User",o=i.slice(0,2).toUpperCase(),r=`\n <div class="wc-handle"></div>\n <div class="wc-header">\n <h3 class="wc-title">Connected</h3>\n <button class="wc-close" data-action="close">&#10005;</button>\n </div>\n <div class="wc-body">\n <div class="wc-success">\n <div class="wc-success-check"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg></div>\n <div class="wc-success-title">Connection Successful</div>\n <div class="wc-success-user">\n ${t?.avatar?`<img class="wc-success-avatar" src="${t.avatar}" alt="${i}" />`:`<div class="wc-success-avatar-placeholder">${o}</div>`}\n <div class="wc-success-user-info">\n <div class="wc-success-user-name">${i}</div>\n ${n?`<div class="wc-success-user-addr" title="${n}">${n}</div>`:""}\n </div>\n </div>\n <button class="wc-success-done" data-action="done">Done</button>\n </div>\n </div>\n <div class="wc-footer">Powered by WalletConnect</div>\n `;this.render(r),this.overlay?.querySelector('[data-action="done"]')?.addEventListener("click",s)}updateStatus(e,n=!0){const t=this.overlay?.querySelector(".wc-status");t&&(t.innerHTML=`\n ${n?'<div class="wc-spinner"></div>':""}\n <span>${e}</span>\n `)}render(e){this.destroy();const n=document.createElement("div");n.id=s,n.innerHTML=`\n <style>${function(e){const n="dark"===e,t=n?"#141414":"#ffffff",s=n?"#1e1e1e":"#f4f4f4",i=n?"#ffffff":"#141414",o=n?"#9a9a9a":"#787878",r=n?"#2a2a2a":"#e4e4e4",a="#2bea6a",c="#1db954";return`\n @keyframes wc-fadeIn { from{opacity:0} to{opacity:1} }\n @keyframes wc-slideUp {\n from{opacity:0;transform:translateY(100%)}\n to{opacity:1;transform:translateY(0)}\n }\n .wc-overlay {\n position:fixed; inset:0; z-index:99999;\n background:rgba(0,0,0,${n?.75:.45});\n display:flex; align-items:flex-end; justify-content:center;\n font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;\n backdrop-filter:blur(6px); -webkit-backdrop-filter:blur(6px);\n animation:wc-fadeIn .2s ease;\n }\n @media(min-width:480px){\n .wc-overlay{align-items:center}\n .wc-modal{border-radius:24px;max-height:85vh}\n }\n .wc-modal {\n background:${t}; width:100%; max-width:420px;\n border-radius:24px 24px 0 0; overflow:hidden; color:${i};\n box-shadow:0 -8px 40px rgba(0,0,0,${n?.5:.15});\n animation:wc-slideUp .3s cubic-bezier(.16,1,.3,1);\n max-height:90vh; overflow-y:auto;\n }\n\n /* Handle bar */\n .wc-handle {\n width:36px; height:4px; border-radius:2px;\n background:${r}; margin:10px auto 0;\n }\n\n /* Header */\n .wc-header {\n display:flex; align-items:center; justify-content:space-between;\n padding:20px 24px 0;\n }\n .wc-header-left {\n display:flex; align-items:center; gap:10px;\n }\n .wc-header-icon {\n width:32px; height:32px; border-radius:10px; object-fit:cover;\n }\n .wc-title { font-size:17px; font-weight:700; margin:0; }\n .wc-close {\n width:30px; height:30px; display:flex; align-items:center; justify-content:center;\n background:${s}; border:none; border-radius:50%;\n cursor:pointer; font-size:14px; color:${o};\n transition:all .15s;\n }\n .wc-close:hover { background:${r}; color:${i}; }\n .wc-subtitle {\n font-size:13px; color:${o}; margin:8px 24px 0;\n line-height:1.4;\n }\n\n .wc-body { padding:20px 24px 24px; }\n\n /* Grid wallet picker */\n .wc-wallet-grid {\n display:grid; grid-template-columns:repeat(4,1fr);\n gap:16px 12px; list-style:none; margin:0; padding:0;\n }\n .wc-wallet-grid-item {\n display:flex; flex-direction:column; align-items:center;\n gap:8px; cursor:pointer; padding:8px 4px; border-radius:16px;\n transition:all .15s; border:2px solid transparent;\n }\n .wc-wallet-grid-item:hover {\n background:${s}; border-color:${r};\n }\n .wc-wallet-grid-icon {\n width:56px; height:56px; border-radius:16px;\n object-fit:cover; box-shadow:0 2px 8px rgba(0,0,0,${n?.3:.08});\n }\n .wc-wallet-grid-icon-placeholder {\n width:56px; height:56px; border-radius:16px;\n background:linear-gradient(135deg,${c},${a});\n display:flex; align-items:center; justify-content:center;\n color:#fff; font-weight:800; font-size:22px;\n box-shadow:0 2px 8px rgba(0,0,0,${n?.3:.08});\n }\n .wc-wallet-grid-name {\n font-size:11px; font-weight:500; text-align:center;\n color:${o}; line-height:1.2;\n max-width:72px; overflow:hidden; text-overflow:ellipsis;\n white-space:nowrap;\n }\n\n /* List wallet picker (alternative) */\n .wc-wallet-list { list-style:none; margin:0; padding:0; }\n .wc-wallet-item {\n display:flex; align-items:center; gap:14px;\n padding:12px 16px; border-radius:16px; cursor:pointer;\n border:1.5px solid ${r}; margin-bottom:8px;\n transition:all .15s;\n }\n .wc-wallet-item:hover {\n background:${s}; border-color:${a};\n }\n .wc-wallet-list-icon {\n width:40px; height:40px; border-radius:12px; object-fit:cover;\n }\n .wc-wallet-list-icon-placeholder {\n width:40px; height:40px; border-radius:12px;\n background:linear-gradient(135deg,${c},${a});\n display:flex; align-items:center; justify-content:center;\n color:#fff; font-weight:700; font-size:16px;\n }\n .wc-wallet-item-info { flex:1; }\n .wc-wallet-item-name { font-size:14px; font-weight:600; }\n .wc-wallet-item-desc { font-size:11px; color:${o}; margin-top:1px; }\n .wc-wallet-item-arrow { color:${o}; font-size:16px; }\n\n /* Tabs */\n .wc-tabs {\n display:flex; background:${s}; border-radius:12px;\n padding:3px; margin-bottom:20px;\n }\n .wc-tab {\n flex:1; padding:10px; text-align:center; cursor:pointer;\n font-size:13px; font-weight:600; background:transparent;\n border:none; color:${o}; border-radius:10px;\n transition:all .2s;\n }\n .wc-tab:hover { color:${i}; }\n .wc-tab.active {\n background:${t}; color:${i};\n box-shadow:0 1px 4px rgba(0,0,0,${n?.3:.08});\n }\n\n /* Deeplink */\n .wc-deeplink-btn {\n display:flex; align-items:center; justify-content:center; gap:10px;\n width:100%; padding:16px; border:none; border-radius:16px;\n background:linear-gradient(135deg,${c},${a});\n color:#fff; font-size:15px; font-weight:700; cursor:pointer;\n text-decoration:none; transition:all .2s;\n box-shadow:0 4px 20px rgba(43,234,106,0.2);\n box-sizing:border-box;\n }\n .wc-deeplink-btn:hover {\n transform:translateY(-1px);\n box-shadow:0 6px 28px rgba(43,234,106,0.3);\n }\n\n /* QR */\n .wc-qr-container {\n display:flex; flex-direction:column; align-items:center; gap:16px;\n }\n .wc-qr-wrap {\n padding:16px; background:#fff; border-radius:20px;\n box-shadow:0 2px 16px rgba(0,0,0,${n?.2:.06});\n }\n .wc-qr-wrap img { display:block; border-radius:4px; }\n .wc-qr-hint { font-size:12px; color:${o}; text-align:center; }\n\n /* Status */\n .wc-status {\n display:flex; align-items:center; justify-content:center;\n gap:10px; padding:20px 0 4px; font-size:13px; color:${o};\n }\n .wc-spinner {\n width:16px; height:16px; border:2px solid ${r};\n border-top-color:${a}; border-radius:50%;\n animation:wc-spin .7s linear infinite;\n }\n @keyframes wc-spin { to{transform:rotate(360deg)} }\n\n /* Back */\n .wc-back {\n background:none; border:none; cursor:pointer; padding:0;\n color:${o}; display:flex; align-items:center;\n transition:color .15s; font-size:18px;\n }\n .wc-back:hover { color:${i}; }\n\n /* Footer */\n .wc-footer {\n text-align:center; padding:4px 0 20px;\n font-size:11px; color:${n?"#555":"#bbb"};\n }\n\n /* Success screen */\n .wc-success {\n display:flex; flex-direction:column; align-items:center;\n padding:12px 0 4px; gap:20px;\n }\n .wc-success-check {\n width:64px; height:64px; border-radius:50%;\n background:linear-gradient(135deg,${c},${a});\n display:flex; align-items:center; justify-content:center;\n box-shadow:0 4px 20px rgba(43,234,106,0.25);\n animation:wc-popIn .4s cubic-bezier(.16,1,.3,1);\n }\n @keyframes wc-popIn {\n from{transform:scale(0);opacity:0}\n 50%{transform:scale(1.15)}\n to{transform:scale(1);opacity:1}\n }\n .wc-success-check svg { width:32px; height:32px; color:#fff; }\n .wc-success-title {\n font-size:18px; font-weight:700; color:${i};\n }\n .wc-success-user {\n display:flex; align-items:center; gap:14px;\n background:${s}; border-radius:16px;\n padding:16px 18px; width:100%; box-sizing:border-box;\n }\n .wc-success-avatar {\n width:48px; height:48px; border-radius:50%; object-fit:cover;\n flex-shrink:0; border:2px solid ${r};\n }\n .wc-success-avatar-placeholder {\n width:48px; height:48px; border-radius:50%;\n background:linear-gradient(135deg,${c},${a});\n display:flex; align-items:center; justify-content:center;\n color:#fff; font-weight:700; font-size:18px; flex-shrink:0;\n border:2px solid ${r};\n }\n .wc-success-user-info { flex:1; min-width:0; }\n .wc-success-user-name { font-size:15px; font-weight:600; color:${i}; }\n .wc-success-user-addr {\n font-size:12px; color:${o}; margin-top:4px;\n font-family:'SF Mono',Monaco,Consolas,monospace;\n word-break:break-all; line-height:1.4;\n }\n .wc-success-done {\n width:100%; padding:14px; border:none; border-radius:14px;\n background:linear-gradient(135deg,${c},${a});\n color:#fff; font-size:14px; font-weight:700; cursor:pointer;\n transition:all .2s;\n box-shadow:0 4px 16px rgba(43,234,106,0.2);\n }\n .wc-success-done:hover {\n transform:translateY(-1px);\n box-shadow:0 6px 24px rgba(43,234,106,0.3);\n }\n `}(this.theme)}</style>\n <div class="wc-overlay">\n <div class="wc-modal">${e}</div>\n </div>\n `,document.body.appendChild(n),this.overlay=n,this.overlay.querySelector('[data-action="close"]')?.addEventListener("click",()=>{this.onClose(),this.destroy()}),this.overlay.querySelector(".wc-overlay")?.addEventListener("click",e=>{e.target.classList.contains("wc-overlay")&&(this.onClose(),this.destroy())})}destroy(){document.getElementById(s)?.remove(),this.overlay=null}}const o="__wc_session_";class r{constructor(e){this.listeners=new Map,this.modal=null,this.wsTransport=null,this.pollingTransport=null,this.currentResult=null,this.config={appId:e.appId,registryUrl:e.registryUrl||"https://cdn.jsdelivr.net/npm/toncorp-wallet-connect-sdk@latest/registry.json",walletId:e.walletId,theme:e.theme||"light"},this.restoreSession(),this.registerGlobal()}async connect(){if(this.currentResult)return this.currentResult;const e=await this.fetchWallets(),n=this.filterWallets(e);if(0===n.length)throw new Error("No supported wallets available");return new Promise((e,t)=>{this.modal=new i(this.config.theme,()=>{this.cleanup(),t(new Error("User closed modal"))}),1===n.length?this.startConnect(n[0],!1,e,t):this.modal.showWalletPicker(n,n=>{this.startConnect(n,!0,e,t)})})}disconnect(){const e=this.currentResult?.session;if(e){const n=e.apiUrl.replace(/\/$/,"");fetch(`${n}/connect/disconnect-by-token`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({sessionToken:e.sessionToken})}).catch(()=>{})}this.currentResult=null,this.removeStoredSession(),this.clearAllRelatedSessions(),this.cleanup(),this.emit("disconnect")}isConnected(){return null!==this.currentResult}getWallet(){return this.currentResult}on(e,n){this.listeners.has(e)||this.listeners.set(e,new Set),this.listeners.get(e).add(n)}off(e,n){this.listeners.get(e)?.delete(n)}get storageKey(){const e=this.config.walletId,n=Array.isArray(e)?e.sort().join("_"):e||"all";return`${o}${n}__`}async fetchWallets(){const e=this.config.registryUrl.replace(/\/$/,""),n=await fetch(e);if(!n.ok)throw new Error("Failed to fetch wallets");return n.json()}filterWallets(e){if(!this.config.walletId)return e;const n=Array.isArray(this.config.walletId)?this.config.walletId:[this.config.walletId];return e.filter(e=>n.includes(e.walletId))}async startConnect(e,n,t,s){try{const i=await this.initSession(e);this.modal?.showConnect(e,i.deeplink,n,()=>{this.cleanup(),this.connect().then(t).catch(s)}),this.listenForConfirmation(e.apiUrl,i.sessionToken,n=>{n.session={sessionToken:i.sessionToken,walletId:e.walletId,apiUrl:e.apiUrl},this.currentResult=n,this.storeSession(n),this.syncToWalletInstance(e.walletId,n),this.emit("connect",n),this.modal?.showSuccess(e,n.wallet?.address||null,n.user||null,()=>{this.modal?.destroy(),this.modal=null,t(n)})},()=>{this.modal?.updateStatus("Connection rejected",!1),setTimeout(()=>{this.modal?.destroy(),this.modal=null,s(new Error("Connection rejected by user"))},1500)},()=>{this.modal?.updateStatus("Session expired",!1),this.emit("session_expired"),setTimeout(()=>{this.modal?.destroy(),this.modal=null,s(new Error("Session expired"))},1500)})}catch(e){this.modal?.destroy(),this.modal=null,s(e instanceof Error?e:new Error(String(e)))}}async initSession(e){const n=e.apiUrl.replace(/\/$/,""),t=await fetch(`${n}/connect/init`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({appId:this.config.appId,walletId:e.walletId,origin:"undefined"!=typeof window?window.location.origin:""})});if(!t.ok)throw new Error("Failed to init session");return t.json()}listenForConfirmation(e,s,i,o,r){let a=!1;const c=e=>(...n)=>{a||(a=!0,this.wsTransport?.close(),this.pollingTransport?.stop(),e(...n))},l=c(i),d=c(o),p=c(r);this.pollingTransport=new t(e,s,l,d,p,e=>this.emit("error",e)),this.pollingTransport.start(),this.wsTransport=new n(e,s,l,d,p,()=>{}),this.wsTransport.connect()}cleanup(){this.wsTransport?.close(),this.wsTransport=null,this.pollingTransport?.stop(),this.pollingTransport=null,this.modal?.destroy(),this.modal=null}emit(e,n){this.listeners.get(e)?.forEach(e=>e(n))}storeSession(e){try{localStorage.setItem(this.storageKey,JSON.stringify(e))}catch{}}restoreSession(){try{const e=localStorage.getItem(this.storageKey);e&&(this.currentResult=JSON.parse(e))}catch{}}removeStoredSession(){try{localStorage.removeItem(this.storageKey)}catch{}}registerGlobal(){if("undefined"==typeof window)return;const e=this.config.walletId,n=Array.isArray(e)?e[0]:e||"walletconnect";window[n]=this}syncToWalletInstance(e,n){if("undefined"==typeof window)return;const t=window[e];t&&t!==this&&t instanceof r&&(t.currentResult=n,t.storeSession(n))}clearAllRelatedSessions(){if("undefined"==typeof window)return;const e=["tonpass","onedollar","walletconnect"];for(const n of e){const e=window[n];e&&e!==this&&e instanceof r&&(e.currentResult=null,e.removeStoredSession())}try{const e=[];for(let n=0;n<localStorage.length;n++){const t=localStorage.key(n);t&&t.startsWith(o)&&e.push(t)}e.forEach(e=>localStorage.removeItem(e))}catch{}}}e.BaseWalletConnect=r,e.OneDollarConnect=class extends r{constructor(e){super({...e,walletId:"onedollar"})}},e.TonPassConnect=class extends r{constructor(e){super({...e,walletId:"tonpass"})}}});
1
+ !function(e,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports):"function"==typeof define&&define.amd?define(["exports"],n):n((e="undefined"!=typeof globalThis?globalThis:e||self).WalletConnectSDK={})}(this,function(e){"use strict";class n{constructor(e,n,t,s,i,o){this.apiUrl=e,this.sessionToken=n,this.onConfirmed=t,this.onRejected=s,this.onExpired=i,this.onError=o,this.ws=null,this.reconnectTimer=null,this.closed=!1}connect(){this.closed=!1;this.apiUrl.replace(/^http/,"ws").replace(/\/$/,"");this.sessionToken;try{this.connectSocketIO()}catch{this.onError("WebSocket connection failed")}}connectSocketIO(){const e=this.apiUrl.replace(/\/$/,"");fetch(`${e}/walletconnect/?EIO=4&transport=polling`).then(e=>e.text()).then(n=>{const t=n.replace(/^\d+/,""),s=JSON.parse(t).sid,i=`${e.replace(/^http/,"ws")}/walletconnect/?EIO=4&transport=websocket&sid=${s}`;this.ws=new WebSocket(i),this.ws.onopen=()=>{this.ws.send("2probe")},this.ws.onmessage=e=>{const n=e.data;if("3probe"!==n)if(n.startsWith("42"))try{const e=JSON.parse(n.slice(2)),[t,s]=e;this.handleEvent(t,s)}catch{}else"2"===n&&this.ws.send("3");else this.ws.send("5")},this.ws.onclose=()=>{this.closed||this.scheduleReconnect()},this.ws.onerror=()=>{this.closed||this.scheduleReconnect()}}).catch(()=>{this.closed||this.scheduleReconnect()})}handleEvent(e,n){switch(e){case"session_confirmed":this.onConfirmed(n),this.close();break;case"session_rejected":this.onRejected(),this.close();break;case"session_expired":this.onExpired(),this.close()}}scheduleReconnect(){this.closed||this.reconnectTimer||(this.reconnectTimer=setTimeout(()=>{this.reconnectTimer=null,this.connectSocketIO()},3e3))}close(){this.closed=!0,this.reconnectTimer&&(clearTimeout(this.reconnectTimer),this.reconnectTimer=null),this.ws&&(this.ws.close(),this.ws=null)}}class t{constructor(e,n,t,s,i,o){this.apiUrl=e,this.sessionToken=n,this.onConfirmed=t,this.onRejected=s,this.onExpired=i,this.onError=o,this.timer=null,this.stopped=!1}start(){this.stopped=!1,this.poll(),this.timer=setInterval(()=>this.poll(),2e3)}async poll(){if(!this.stopped)try{const e=this.apiUrl.replace(/\/$/,""),n=await fetch(`${e}/connect/status?token=${this.sessionToken}`);if(!n.ok)return;const t=await n.json();switch(t.status){case"CONFIRMED":this.onConfirmed({wallet:t.wallet,user:t.user}),this.stop();break;case"REJECTED":this.onRejected(),this.stop();break;case"EXPIRED":this.onExpired(),this.stop()}}catch{}}stop(){this.stopped=!0,this.timer&&(clearInterval(this.timer),this.timer=null)}}const s="__wc_modal__";class i{constructor(e,n){this.overlay=null,this.theme=e,this.onClose=n}showWalletPicker(e,n){const t=`\n <div class="wc-handle"></div>\n <div class="wc-header">\n <h3 class="wc-title">Connect your wallet</h3>\n <button class="wc-close" data-action="close">&#10005;</button>\n </div>\n <p class="wc-subtitle">Choose a wallet to connect to this app</p>\n <div class="wc-body">${e.length>=3?`<ul class="wc-wallet-grid">${e.map(e=>`\n <li class="wc-wallet-grid-item" data-wallet-id="${e.walletId}">\n ${e.icon?`<img class="wc-wallet-grid-icon" src="${e.icon}" alt="${e.name}" />`:`<div class="wc-wallet-grid-icon-placeholder">${e.name.charAt(0)}</div>`}\n <span class="wc-wallet-grid-name">${e.name}</span>\n </li>`).join("")}</ul>`:`<ul class="wc-wallet-list">${e.map(e=>`\n <li class="wc-wallet-item" data-wallet-id="${e.walletId}">\n ${e.icon?`<img class="wc-wallet-list-icon" src="${e.icon}" alt="${e.name}" />`:`<div class="wc-wallet-list-icon-placeholder">${e.name.charAt(0)}</div>`}\n <div class="wc-wallet-item-info">\n <div class="wc-wallet-item-name">${e.name}</div>\n ${e.description?`<div class="wc-wallet-item-desc">${e.description}</div>`:""}\n </div>\n <span class="wc-wallet-item-arrow">&#8250;</span>\n </li>`).join("")}</ul>`}</div>\n <div class="wc-footer">Powered by WalletConnect</div>\n `;this.render(t),e.forEach(e=>{this.overlay?.querySelector(`[data-wallet-id="${e.walletId}"]`)?.addEventListener("click",()=>n(e))})}showConnect(e,n,t,s){const i=function(e,n=220){return`https://api.qrserver.com/v1/create-qr-code/?size=${n}x${n}&data=${encodeURIComponent(e)}&margin=8`}(n),o=`\n <div class="wc-handle"></div>\n <div class="wc-header">\n <div class="wc-header-left">\n ${t?'<button class="wc-back" data-action="back">&#8592;</button>':""}\n ${e.icon?`<img class="wc-header-icon" src="${e.icon}" />`:""}\n <h3 class="wc-title">${e.name}</h3>\n </div>\n <button class="wc-close" data-action="close">&#10005;</button>\n </div>\n <p class="wc-subtitle">Approve the connection request in your wallet</p>\n <div class="wc-body">\n <div class="wc-tabs">\n <button class="wc-tab active" data-tab="mobile">Mobile</button>\n <button class="wc-tab" data-tab="qr">QR Code</button>\n </div>\n <div data-panel="mobile">\n <a class="wc-deeplink-btn" href="${n}" target="_blank">\n <svg width="20" height="20" viewBox="0 0 24 24" fill="currentColor"><path d="M11.944 0A12 12 0 1 0 24 12.056A12.01 12.01 0 0 0 11.944 0Zm4.962 7.224c.1-.002.321.023.465.14a.506.506 0 0 1 .171.325c.016.093.036.306.02.472c-.18 1.898-.962 6.502-1.36 8.627c-.168.9-.499 1.201-.82 1.23c-.696.065-1.225-.46-1.9-.902c-1.056-.693-1.653-1.124-2.678-1.8c-1.185-.78-.417-1.21.258-1.91c.177-.184 3.247-2.977 3.307-3.23c.007-.032.014-.15-.056-.212s-.174-.041-.249-.024c-.106.024-1.793 1.14-5.061 3.345c-.48.33-.913.49-1.302.48c-.428-.008-1.252-.241-1.865-.44c-.752-.245-1.349-.374-1.297-.789c.027-.216.325-.437.893-.663c3.498-1.524 5.83-2.529 6.998-3.014c3.332-1.386 4.025-1.627 4.476-1.635Z"/></svg>\n Open in Telegram\n </a>\n </div>\n <div data-panel="qr" style="display:none">\n <div class="wc-qr-container">\n <div class="wc-qr-wrap">\n <img src="${i}" width="220" height="220" alt="QR" />\n </div>\n <div class="wc-qr-hint">Scan with your phone camera or wallet app</div>\n </div>\n </div>\n <div class="wc-status">\n <div class="wc-spinner"></div>\n <span>Waiting for confirmation...</span>\n </div>\n </div>\n <div class="wc-footer">Powered by WalletConnect</div>\n `;this.render(o);const r=this.overlay?.querySelectorAll(".wc-tab"),a=this.overlay?.querySelectorAll("[data-panel]");r?.forEach(e=>{e.addEventListener("click",()=>{const n=e.dataset.tab;r.forEach(e=>e.classList.remove("active")),e.classList.add("active"),a?.forEach(e=>{e.style.display=e.dataset.panel===n?"block":"none"})})}),t&&s&&this.overlay?.querySelector('[data-action="back"]')?.addEventListener("click",s)}showSuccess(e,n,t,s){const i=t?.username||"User",o=i.slice(0,2).toUpperCase(),r=`\n <div class="wc-handle"></div>\n <div class="wc-header">\n <h3 class="wc-title">Connected</h3>\n <button class="wc-close" data-action="close">&#10005;</button>\n </div>\n <div class="wc-body">\n <div class="wc-success">\n <div class="wc-success-check"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg></div>\n <div class="wc-success-title">Connection Successful</div>\n <div class="wc-success-user">\n ${t?.avatar?`<img class="wc-success-avatar" src="${t.avatar}" alt="${i}" />`:`<div class="wc-success-avatar-placeholder">${o}</div>`}\n <div class="wc-success-user-info">\n <div class="wc-success-user-name">${i}</div>\n ${n?`<div class="wc-success-user-addr" title="${n}">${n}</div>`:""}\n </div>\n </div>\n <button class="wc-success-done" data-action="done">Done</button>\n </div>\n </div>\n <div class="wc-footer">Powered by WalletConnect</div>\n `;this.render(r),this.overlay?.querySelector('[data-action="done"]')?.addEventListener("click",s)}updateStatus(e,n=!0){const t=this.overlay?.querySelector(".wc-status");t&&(t.innerHTML=`\n ${n?'<div class="wc-spinner"></div>':""}\n <span>${e}</span>\n `)}render(e){this.destroy();const n=document.createElement("div");n.id=s,n.innerHTML=`\n <style>${function(e){const n="dark"===e,t=n?"#141414":"#ffffff",s=n?"#1e1e1e":"#f4f4f4",i=n?"#ffffff":"#141414",o=n?"#9a9a9a":"#787878",r=n?"#2a2a2a":"#e4e4e4",a="#2bea6a",c="#1db954";return`\n @keyframes wc-fadeIn { from{opacity:0} to{opacity:1} }\n @keyframes wc-slideUp {\n from{opacity:0;transform:translateY(100%)}\n to{opacity:1;transform:translateY(0)}\n }\n .wc-overlay {\n position:fixed; inset:0; z-index:99999;\n background:rgba(0,0,0,${n?.75:.45});\n display:flex; align-items:flex-end; justify-content:center;\n font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;\n backdrop-filter:blur(6px); -webkit-backdrop-filter:blur(6px);\n animation:wc-fadeIn .2s ease;\n }\n @media(min-width:480px){\n .wc-overlay{align-items:center}\n .wc-modal{border-radius:24px;max-height:85vh}\n }\n .wc-modal {\n background:${t}; width:100%; max-width:420px;\n border-radius:24px 24px 0 0; overflow:hidden; color:${i};\n box-shadow:0 -8px 40px rgba(0,0,0,${n?.5:.15});\n animation:wc-slideUp .3s cubic-bezier(.16,1,.3,1);\n max-height:90vh; overflow-y:auto;\n }\n\n /* Handle bar */\n .wc-handle {\n width:36px; height:4px; border-radius:2px;\n background:${r}; margin:10px auto 0;\n }\n\n /* Header */\n .wc-header {\n display:flex; align-items:center; justify-content:space-between;\n padding:20px 24px 0;\n }\n .wc-header-left {\n display:flex; align-items:center; gap:10px;\n }\n .wc-header-icon {\n width:32px; height:32px; border-radius:10px; object-fit:cover;\n }\n .wc-title { font-size:17px; font-weight:700; margin:0; }\n .wc-close {\n width:30px; height:30px; display:flex; align-items:center; justify-content:center;\n background:${s}; border:none; border-radius:50%;\n cursor:pointer; font-size:14px; color:${o};\n transition:all .15s;\n }\n .wc-close:hover { background:${r}; color:${i}; }\n .wc-subtitle {\n font-size:13px; color:${o}; margin:8px 24px 0;\n line-height:1.4;\n }\n\n .wc-body { padding:20px 24px 24px; }\n\n /* Grid wallet picker */\n .wc-wallet-grid {\n display:grid; grid-template-columns:repeat(4,1fr);\n gap:16px 12px; list-style:none; margin:0; padding:0;\n }\n .wc-wallet-grid-item {\n display:flex; flex-direction:column; align-items:center;\n gap:8px; cursor:pointer; padding:8px 4px; border-radius:16px;\n transition:all .15s; border:2px solid transparent;\n }\n .wc-wallet-grid-item:hover {\n background:${s}; border-color:${r};\n }\n .wc-wallet-grid-icon {\n width:56px; height:56px; border-radius:16px;\n object-fit:cover; box-shadow:0 2px 8px rgba(0,0,0,${n?.3:.08});\n }\n .wc-wallet-grid-icon-placeholder {\n width:56px; height:56px; border-radius:16px;\n background:linear-gradient(135deg,${c},${a});\n display:flex; align-items:center; justify-content:center;\n color:#fff; font-weight:800; font-size:22px;\n box-shadow:0 2px 8px rgba(0,0,0,${n?.3:.08});\n }\n .wc-wallet-grid-name {\n font-size:11px; font-weight:500; text-align:center;\n color:${o}; line-height:1.2;\n max-width:72px; overflow:hidden; text-overflow:ellipsis;\n white-space:nowrap;\n }\n\n /* List wallet picker (alternative) */\n .wc-wallet-list { list-style:none; margin:0; padding:0; }\n .wc-wallet-item {\n display:flex; align-items:center; gap:14px;\n padding:12px 16px; border-radius:16px; cursor:pointer;\n border:1.5px solid ${r}; margin-bottom:8px;\n transition:all .15s;\n }\n .wc-wallet-item:hover {\n background:${s}; border-color:${a};\n }\n .wc-wallet-list-icon {\n width:40px; height:40px; border-radius:12px; object-fit:cover;\n }\n .wc-wallet-list-icon-placeholder {\n width:40px; height:40px; border-radius:12px;\n background:linear-gradient(135deg,${c},${a});\n display:flex; align-items:center; justify-content:center;\n color:#fff; font-weight:700; font-size:16px;\n }\n .wc-wallet-item-info { flex:1; }\n .wc-wallet-item-name { font-size:14px; font-weight:600; }\n .wc-wallet-item-desc { font-size:11px; color:${o}; margin-top:1px; }\n .wc-wallet-item-arrow { color:${o}; font-size:16px; }\n\n /* Tabs */\n .wc-tabs {\n display:flex; background:${s}; border-radius:12px;\n padding:3px; margin-bottom:20px;\n }\n .wc-tab {\n flex:1; padding:10px; text-align:center; cursor:pointer;\n font-size:13px; font-weight:600; background:transparent;\n border:none; color:${o}; border-radius:10px;\n transition:all .2s;\n }\n .wc-tab:hover { color:${i}; }\n .wc-tab.active {\n background:${t}; color:${i};\n box-shadow:0 1px 4px rgba(0,0,0,${n?.3:.08});\n }\n\n /* Deeplink */\n .wc-deeplink-btn {\n display:flex; align-items:center; justify-content:center; gap:10px;\n width:100%; padding:16px; border:none; border-radius:16px;\n background:linear-gradient(135deg,${c},${a});\n color:#fff; font-size:15px; font-weight:700; cursor:pointer;\n text-decoration:none; transition:all .2s;\n box-shadow:0 4px 20px rgba(43,234,106,0.2);\n box-sizing:border-box;\n }\n .wc-deeplink-btn:hover {\n transform:translateY(-1px);\n box-shadow:0 6px 28px rgba(43,234,106,0.3);\n }\n\n /* QR */\n .wc-qr-container {\n display:flex; flex-direction:column; align-items:center; gap:16px;\n }\n .wc-qr-wrap {\n padding:16px; background:#fff; border-radius:20px;\n box-shadow:0 2px 16px rgba(0,0,0,${n?.2:.06});\n }\n .wc-qr-wrap img { display:block; border-radius:4px; }\n .wc-qr-hint { font-size:12px; color:${o}; text-align:center; }\n\n /* Status */\n .wc-status {\n display:flex; align-items:center; justify-content:center;\n gap:10px; padding:20px 0 4px; font-size:13px; color:${o};\n }\n .wc-spinner {\n width:16px; height:16px; border:2px solid ${r};\n border-top-color:${a}; border-radius:50%;\n animation:wc-spin .7s linear infinite;\n }\n @keyframes wc-spin { to{transform:rotate(360deg)} }\n\n /* Back */\n .wc-back {\n background:none; border:none; cursor:pointer; padding:0;\n color:${o}; display:flex; align-items:center;\n transition:color .15s; font-size:18px;\n }\n .wc-back:hover { color:${i}; }\n\n /* Footer */\n .wc-footer {\n text-align:center; padding:4px 0 20px;\n font-size:11px; color:${n?"#555":"#bbb"};\n }\n\n /* Success screen */\n .wc-success {\n display:flex; flex-direction:column; align-items:center;\n padding:12px 0 4px; gap:20px;\n }\n .wc-success-check {\n width:64px; height:64px; border-radius:50%;\n background:linear-gradient(135deg,${c},${a});\n display:flex; align-items:center; justify-content:center;\n box-shadow:0 4px 20px rgba(43,234,106,0.25);\n animation:wc-popIn .4s cubic-bezier(.16,1,.3,1);\n }\n @keyframes wc-popIn {\n from{transform:scale(0);opacity:0}\n 50%{transform:scale(1.15)}\n to{transform:scale(1);opacity:1}\n }\n .wc-success-check svg { width:32px; height:32px; color:#fff; }\n .wc-success-title {\n font-size:18px; font-weight:700; color:${i};\n }\n .wc-success-user {\n display:flex; align-items:center; gap:14px;\n background:${s}; border-radius:16px;\n padding:16px 18px; width:100%; box-sizing:border-box;\n }\n .wc-success-avatar {\n width:48px; height:48px; border-radius:50%; object-fit:cover;\n flex-shrink:0; border:2px solid ${r};\n }\n .wc-success-avatar-placeholder {\n width:48px; height:48px; border-radius:50%;\n background:linear-gradient(135deg,${c},${a});\n display:flex; align-items:center; justify-content:center;\n color:#fff; font-weight:700; font-size:18px; flex-shrink:0;\n border:2px solid ${r};\n }\n .wc-success-user-info { flex:1; min-width:0; }\n .wc-success-user-name { font-size:15px; font-weight:600; color:${i}; }\n .wc-success-user-addr {\n font-size:12px; color:${o}; margin-top:4px;\n font-family:'SF Mono',Monaco,Consolas,monospace;\n word-break:break-all; line-height:1.4;\n }\n .wc-success-done {\n width:100%; padding:14px; border:none; border-radius:14px;\n background:linear-gradient(135deg,${c},${a});\n color:#fff; font-size:14px; font-weight:700; cursor:pointer;\n transition:all .2s;\n box-shadow:0 4px 16px rgba(43,234,106,0.2);\n }\n .wc-success-done:hover {\n transform:translateY(-1px);\n box-shadow:0 6px 24px rgba(43,234,106,0.3);\n }\n `}(this.theme)}</style>\n <div class="wc-overlay">\n <div class="wc-modal">${e}</div>\n </div>\n `,document.body.appendChild(n),this.overlay=n,this.overlay.querySelector('[data-action="close"]')?.addEventListener("click",()=>{this.onClose(),this.destroy()}),this.overlay.querySelector(".wc-overlay")?.addEventListener("click",e=>{e.target.classList.contains("wc-overlay")&&(this.onClose(),this.destroy())})}destroy(){document.getElementById(s)?.remove(),this.overlay=null}}const o="__wc_session_";class r{constructor(e){this.listeners=new Map,this.modal=null,this.wsTransport=null,this.pollingTransport=null,this.currentResult=null,this.config={appId:e.appId,registryUrl:e.registryUrl||"https://cdn.jsdelivr.net/npm/toncorp-wallet-connect-sdk@latest/registry.json",walletId:e.walletId,theme:e.theme||"light"},this.restoreSession(),this.registerGlobal()}async connect(){if(this.currentResult)return this.currentResult;const e=await this.fetchWallets(),n=this.filterWallets(e);if(0===n.length)throw new Error("No supported wallets available");return new Promise((e,t)=>{this.modal=new i(this.config.theme,()=>{this.cleanup(),t(new Error("User closed modal"))}),1===n.length?this.startConnect(n[0],!1,e,t):this.modal.showWalletPicker(n,n=>{this.startConnect(n,!0,e,t)})})}disconnect(){let e=this.currentResult?.session;if(!e&&"undefined"!=typeof window)for(const n of Object.keys(window)){const t=window[n];if(t instanceof r&&t.currentResult?.session){e=t.currentResult.session;break}}if(e){const n=e.apiUrl.replace(/\/$/,"");fetch(`${n}/connect/disconnect-by-token`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({sessionToken:e.sessionToken})}).catch(()=>{})}this.currentResult=null,this.removeStoredSession(),this.clearAllRelatedSessions(),this.cleanup(),this.emit("disconnect")}isConnected(){return null!==this.currentResult}getWallet(){return this.currentResult}on(e,n){this.listeners.has(e)||this.listeners.set(e,new Set),this.listeners.get(e).add(n)}off(e,n){this.listeners.get(e)?.delete(n)}get storageKey(){const e=this.config.walletId,n=Array.isArray(e)?e.sort().join("_"):e||"all";return`${o}${n}__`}async fetchWallets(){const e=this.config.registryUrl.replace(/\/$/,""),n=await fetch(e);if(!n.ok)throw new Error("Failed to fetch wallets");return n.json()}filterWallets(e){if(!this.config.walletId)return e;const n=Array.isArray(this.config.walletId)?this.config.walletId:[this.config.walletId];return e.filter(e=>n.includes(e.walletId))}async startConnect(e,n,t,s){try{const i=await this.initSession(e);this.modal?.showConnect(e,i.deeplink,n,()=>{this.cleanup(),this.connect().then(t).catch(s)}),this.listenForConfirmation(e.apiUrl,i.sessionToken,n=>{n.session={sessionToken:i.sessionToken,walletId:e.walletId,apiUrl:e.apiUrl},this.currentResult=n,this.storeSession(n),this.syncToWalletInstance(e.walletId,n),this.emit("connect",n),this.modal?.showSuccess(e,n.wallet?.address||null,n.user||null,()=>{this.modal?.destroy(),this.modal=null,t(n)})},()=>{this.modal?.updateStatus("Connection rejected",!1),setTimeout(()=>{this.modal?.destroy(),this.modal=null,s(new Error("Connection rejected by user"))},1500)},()=>{this.modal?.updateStatus("Session expired",!1),this.emit("session_expired"),setTimeout(()=>{this.modal?.destroy(),this.modal=null,s(new Error("Session expired"))},1500)})}catch(e){this.modal?.destroy(),this.modal=null,s(e instanceof Error?e:new Error(String(e)))}}async initSession(e){const n=e.apiUrl.replace(/\/$/,""),t=await fetch(`${n}/connect/init`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({appId:this.config.appId,walletId:e.walletId,origin:"undefined"!=typeof window?window.location.origin:""})});if(!t.ok)throw new Error("Failed to init session");return t.json()}listenForConfirmation(e,s,i,o,r){let a=!1;const c=e=>(...n)=>{a||(a=!0,this.wsTransport?.close(),this.pollingTransport?.stop(),e(...n))},l=c(i),d=c(o),p=c(r);this.pollingTransport=new t(e,s,l,d,p,e=>this.emit("error",e)),this.pollingTransport.start(),this.wsTransport=new n(e,s,l,d,p,()=>{}),this.wsTransport.connect()}cleanup(){this.wsTransport?.close(),this.wsTransport=null,this.pollingTransport?.stop(),this.pollingTransport=null,this.modal?.destroy(),this.modal=null}emit(e,n){this.listeners.get(e)?.forEach(e=>e(n))}storeSession(e){try{localStorage.setItem(this.storageKey,JSON.stringify(e))}catch{}}restoreSession(){try{const e=localStorage.getItem(this.storageKey);e&&(this.currentResult=JSON.parse(e))}catch{}}removeStoredSession(){try{localStorage.removeItem(this.storageKey)}catch{}}registerGlobal(){if("undefined"==typeof window)return;const e=this.config.walletId,n=Array.isArray(e)?e[0]:e||"walletconnect";window[n]=this}syncToWalletInstance(e,n){if("undefined"==typeof window)return;const t=window[e];t&&t!==this&&t instanceof r&&(t.currentResult=n,t.storeSession(n))}clearAllRelatedSessions(){if("undefined"!=typeof window){try{for(const e of Object.keys(window)){const n=window[e];n&&n!==this&&n instanceof r&&(n.currentResult=null,n.removeStoredSession())}}catch{}try{const e=[];for(let n=0;n<localStorage.length;n++){const t=localStorage.key(n);t&&t.startsWith(o)&&e.push(t)}e.forEach(e=>localStorage.removeItem(e))}catch{}}}}e.BaseWalletConnect=r,e.OneDollarConnect=class extends r{constructor(e){super({...e,walletId:"onedollar"})}},e.TonPassConnect=class extends r{constructor(e){super({...e,walletId:"tonpass"})}}});
2
2
  //# sourceMappingURL=index.umd.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.umd.js","sources":["../../transport.ts","../../modal.ts","../../client.ts","../../onedollar.ts","../../tonpass.ts"],"sourcesContent":["import type { ConnectResult } from './types';\n\ntype TransportCallback = (data: ConnectResult) => void;\ntype TransportErrorCallback = (error: string) => void;\n\n// ── WebSocket Transport ──\n\nexport class WsTransport {\n private ws: WebSocket | null = null;\n private reconnectTimer: ReturnType<typeof setTimeout> | null = null;\n private closed = false;\n\n constructor(\n private apiUrl: string,\n private sessionToken: string,\n private onConfirmed: TransportCallback,\n private onRejected: () => void,\n private onExpired: () => void,\n private onError: TransportErrorCallback,\n ) {}\n\n connect(): void {\n this.closed = false;\n const wsUrl = this.apiUrl\n .replace(/^http/, 'ws')\n .replace(/\\/$/, '');\n const url = `${wsUrl}/walletconnect?sessionToken=${this.sessionToken}`;\n\n try {\n // Socket.IO uses polling upgrade — use native WS for simplicity in SDK\n // The BE gateway uses socket.io, so we connect via socket.io protocol\n this.connectSocketIO();\n } catch {\n this.onError('WebSocket connection failed');\n }\n }\n\n private connectSocketIO(): void {\n const baseUrl = this.apiUrl.replace(/\\/$/, '');\n\n // Socket.IO handshake: first GET for sid, then upgrade to WS\n const pollingUrl = `${baseUrl}/walletconnect/?EIO=4&transport=polling`;\n\n fetch(pollingUrl)\n .then((res) => res.text())\n .then((body) => {\n // Socket.IO response format: \"0{...json...}\"\n const jsonStr = body.replace(/^\\d+/, '');\n const handshake = JSON.parse(jsonStr);\n const sid = handshake.sid;\n\n const wsBase = baseUrl.replace(/^http/, 'ws');\n const wsUrl = `${wsBase}/walletconnect/?EIO=4&transport=websocket&sid=${sid}`;\n\n this.ws = new WebSocket(wsUrl);\n\n this.ws.onopen = () => {\n // Socket.IO upgrade probe\n this.ws!.send('2probe');\n };\n\n this.ws.onmessage = (event) => {\n const msg = event.data as string;\n\n if (msg === '3probe') {\n // Upgrade confirmed, send upgrade packet + join room\n this.ws!.send('5');\n // Emit connect event with sessionToken as query (already in URL)\n // Socket.IO auto-joins based on handshake query\n return;\n }\n\n // Handle Socket.IO event messages: 42[\"event_name\", {...data}]\n if (msg.startsWith('42')) {\n try {\n const payload = JSON.parse(msg.slice(2));\n const [eventName, data] = payload;\n this.handleEvent(eventName, data);\n } catch {\n // ignore malformed\n }\n return;\n }\n\n // Ping from server\n if (msg === '2') {\n this.ws!.send('3');\n }\n };\n\n this.ws.onclose = () => {\n if (!this.closed) {\n this.scheduleReconnect();\n }\n };\n\n this.ws.onerror = () => {\n if (!this.closed) {\n this.scheduleReconnect();\n }\n };\n })\n .catch(() => {\n if (!this.closed) {\n this.scheduleReconnect();\n }\n });\n }\n\n private handleEvent(eventName: string, data: any): void {\n switch (eventName) {\n case 'session_confirmed':\n this.onConfirmed(data);\n this.close();\n break;\n case 'session_rejected':\n this.onRejected();\n this.close();\n break;\n case 'session_expired':\n this.onExpired();\n this.close();\n break;\n }\n }\n\n private scheduleReconnect(): void {\n if (this.closed || this.reconnectTimer) return;\n this.reconnectTimer = setTimeout(() => {\n this.reconnectTimer = null;\n this.connectSocketIO();\n }, 3000);\n }\n\n close(): void {\n this.closed = true;\n if (this.reconnectTimer) {\n clearTimeout(this.reconnectTimer);\n this.reconnectTimer = null;\n }\n if (this.ws) {\n this.ws.close();\n this.ws = null;\n }\n }\n}\n\n// ── Long-Poll Fallback ──\n\nexport class PollingTransport {\n private timer: ReturnType<typeof setInterval> | null = null;\n private stopped = false;\n\n constructor(\n private apiUrl: string,\n private sessionToken: string,\n private onConfirmed: TransportCallback,\n private onRejected: () => void,\n private onExpired: () => void,\n private onError: TransportErrorCallback,\n ) {}\n\n start(): void {\n this.stopped = false;\n this.poll();\n this.timer = setInterval(() => this.poll(), 2000);\n }\n\n private async poll(): Promise<void> {\n if (this.stopped) return;\n\n try {\n const baseUrl = this.apiUrl.replace(/\\/$/, '');\n const res = await fetch(\n `${baseUrl}/connect/status?token=${this.sessionToken}`,\n );\n if (!res.ok) return;\n\n const data = await res.json();\n\n switch (data.status) {\n case 'CONFIRMED':\n this.onConfirmed({ wallet: data.wallet, user: data.user });\n this.stop();\n break;\n case 'REJECTED':\n this.onRejected();\n this.stop();\n break;\n case 'EXPIRED':\n this.onExpired();\n this.stop();\n break;\n }\n } catch {\n // silently retry next interval\n }\n }\n\n stop(): void {\n this.stopped = true;\n if (this.timer) {\n clearInterval(this.timer);\n this.timer = null;\n }\n }\n}\n","import type { WalletMeta } from './types';\n\nconst MODAL_ID = '__wc_modal__';\n\nfunction getStyles(theme: 'light' | 'dark'): string {\n const isDark = theme === 'dark';\n const bg = isDark ? '#141414' : '#ffffff';\n const bgSecondary = isDark ? '#1e1e1e' : '#f4f4f4';\n const text = isDark ? '#ffffff' : '#141414';\n const textSecondary = isDark ? '#9a9a9a' : '#787878';\n const border = isDark ? '#2a2a2a' : '#e4e4e4';\n const accent = '#2bea6a';\n const accentDark = '#1db954';\n\n return `\n @keyframes wc-fadeIn { from{opacity:0} to{opacity:1} }\n @keyframes wc-slideUp {\n from{opacity:0;transform:translateY(100%)}\n to{opacity:1;transform:translateY(0)}\n }\n .wc-overlay {\n position:fixed; inset:0; z-index:99999;\n background:rgba(0,0,0,${isDark ? 0.75 : 0.45});\n display:flex; align-items:flex-end; justify-content:center;\n font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;\n backdrop-filter:blur(6px); -webkit-backdrop-filter:blur(6px);\n animation:wc-fadeIn .2s ease;\n }\n @media(min-width:480px){\n .wc-overlay{align-items:center}\n .wc-modal{border-radius:24px;max-height:85vh}\n }\n .wc-modal {\n background:${bg}; width:100%; max-width:420px;\n border-radius:24px 24px 0 0; overflow:hidden; color:${text};\n box-shadow:0 -8px 40px rgba(0,0,0,${isDark ? 0.5 : 0.15});\n animation:wc-slideUp .3s cubic-bezier(.16,1,.3,1);\n max-height:90vh; overflow-y:auto;\n }\n\n /* Handle bar */\n .wc-handle {\n width:36px; height:4px; border-radius:2px;\n background:${border}; margin:10px auto 0;\n }\n\n /* Header */\n .wc-header {\n display:flex; align-items:center; justify-content:space-between;\n padding:20px 24px 0;\n }\n .wc-header-left {\n display:flex; align-items:center; gap:10px;\n }\n .wc-header-icon {\n width:32px; height:32px; border-radius:10px; object-fit:cover;\n }\n .wc-title { font-size:17px; font-weight:700; margin:0; }\n .wc-close {\n width:30px; height:30px; display:flex; align-items:center; justify-content:center;\n background:${bgSecondary}; border:none; border-radius:50%;\n cursor:pointer; font-size:14px; color:${textSecondary};\n transition:all .15s;\n }\n .wc-close:hover { background:${border}; color:${text}; }\n .wc-subtitle {\n font-size:13px; color:${textSecondary}; margin:8px 24px 0;\n line-height:1.4;\n }\n\n .wc-body { padding:20px 24px 24px; }\n\n /* Grid wallet picker */\n .wc-wallet-grid {\n display:grid; grid-template-columns:repeat(4,1fr);\n gap:16px 12px; list-style:none; margin:0; padding:0;\n }\n .wc-wallet-grid-item {\n display:flex; flex-direction:column; align-items:center;\n gap:8px; cursor:pointer; padding:8px 4px; border-radius:16px;\n transition:all .15s; border:2px solid transparent;\n }\n .wc-wallet-grid-item:hover {\n background:${bgSecondary}; border-color:${border};\n }\n .wc-wallet-grid-icon {\n width:56px; height:56px; border-radius:16px;\n object-fit:cover; box-shadow:0 2px 8px rgba(0,0,0,${isDark ? 0.3 : 0.08});\n }\n .wc-wallet-grid-icon-placeholder {\n width:56px; height:56px; border-radius:16px;\n background:linear-gradient(135deg,${accentDark},${accent});\n display:flex; align-items:center; justify-content:center;\n color:#fff; font-weight:800; font-size:22px;\n box-shadow:0 2px 8px rgba(0,0,0,${isDark ? 0.3 : 0.08});\n }\n .wc-wallet-grid-name {\n font-size:11px; font-weight:500; text-align:center;\n color:${textSecondary}; line-height:1.2;\n max-width:72px; overflow:hidden; text-overflow:ellipsis;\n white-space:nowrap;\n }\n\n /* List wallet picker (alternative) */\n .wc-wallet-list { list-style:none; margin:0; padding:0; }\n .wc-wallet-item {\n display:flex; align-items:center; gap:14px;\n padding:12px 16px; border-radius:16px; cursor:pointer;\n border:1.5px solid ${border}; margin-bottom:8px;\n transition:all .15s;\n }\n .wc-wallet-item:hover {\n background:${bgSecondary}; border-color:${accent};\n }\n .wc-wallet-list-icon {\n width:40px; height:40px; border-radius:12px; object-fit:cover;\n }\n .wc-wallet-list-icon-placeholder {\n width:40px; height:40px; border-radius:12px;\n background:linear-gradient(135deg,${accentDark},${accent});\n display:flex; align-items:center; justify-content:center;\n color:#fff; font-weight:700; font-size:16px;\n }\n .wc-wallet-item-info { flex:1; }\n .wc-wallet-item-name { font-size:14px; font-weight:600; }\n .wc-wallet-item-desc { font-size:11px; color:${textSecondary}; margin-top:1px; }\n .wc-wallet-item-arrow { color:${textSecondary}; font-size:16px; }\n\n /* Tabs */\n .wc-tabs {\n display:flex; background:${bgSecondary}; border-radius:12px;\n padding:3px; margin-bottom:20px;\n }\n .wc-tab {\n flex:1; padding:10px; text-align:center; cursor:pointer;\n font-size:13px; font-weight:600; background:transparent;\n border:none; color:${textSecondary}; border-radius:10px;\n transition:all .2s;\n }\n .wc-tab:hover { color:${text}; }\n .wc-tab.active {\n background:${bg}; color:${text};\n box-shadow:0 1px 4px rgba(0,0,0,${isDark ? 0.3 : 0.08});\n }\n\n /* Deeplink */\n .wc-deeplink-btn {\n display:flex; align-items:center; justify-content:center; gap:10px;\n width:100%; padding:16px; border:none; border-radius:16px;\n background:linear-gradient(135deg,${accentDark},${accent});\n color:#fff; font-size:15px; font-weight:700; cursor:pointer;\n text-decoration:none; transition:all .2s;\n box-shadow:0 4px 20px rgba(43,234,106,0.2);\n box-sizing:border-box;\n }\n .wc-deeplink-btn:hover {\n transform:translateY(-1px);\n box-shadow:0 6px 28px rgba(43,234,106,0.3);\n }\n\n /* QR */\n .wc-qr-container {\n display:flex; flex-direction:column; align-items:center; gap:16px;\n }\n .wc-qr-wrap {\n padding:16px; background:#fff; border-radius:20px;\n box-shadow:0 2px 16px rgba(0,0,0,${isDark ? 0.2 : 0.06});\n }\n .wc-qr-wrap img { display:block; border-radius:4px; }\n .wc-qr-hint { font-size:12px; color:${textSecondary}; text-align:center; }\n\n /* Status */\n .wc-status {\n display:flex; align-items:center; justify-content:center;\n gap:10px; padding:20px 0 4px; font-size:13px; color:${textSecondary};\n }\n .wc-spinner {\n width:16px; height:16px; border:2px solid ${border};\n border-top-color:${accent}; border-radius:50%;\n animation:wc-spin .7s linear infinite;\n }\n @keyframes wc-spin { to{transform:rotate(360deg)} }\n\n /* Back */\n .wc-back {\n background:none; border:none; cursor:pointer; padding:0;\n color:${textSecondary}; display:flex; align-items:center;\n transition:color .15s; font-size:18px;\n }\n .wc-back:hover { color:${text}; }\n\n /* Footer */\n .wc-footer {\n text-align:center; padding:4px 0 20px;\n font-size:11px; color:${isDark ? '#555' : '#bbb'};\n }\n\n /* Success screen */\n .wc-success {\n display:flex; flex-direction:column; align-items:center;\n padding:12px 0 4px; gap:20px;\n }\n .wc-success-check {\n width:64px; height:64px; border-radius:50%;\n background:linear-gradient(135deg,${accentDark},${accent});\n display:flex; align-items:center; justify-content:center;\n box-shadow:0 4px 20px rgba(43,234,106,0.25);\n animation:wc-popIn .4s cubic-bezier(.16,1,.3,1);\n }\n @keyframes wc-popIn {\n from{transform:scale(0);opacity:0}\n 50%{transform:scale(1.15)}\n to{transform:scale(1);opacity:1}\n }\n .wc-success-check svg { width:32px; height:32px; color:#fff; }\n .wc-success-title {\n font-size:18px; font-weight:700; color:${text};\n }\n .wc-success-user {\n display:flex; align-items:center; gap:14px;\n background:${bgSecondary}; border-radius:16px;\n padding:16px 18px; width:100%; box-sizing:border-box;\n }\n .wc-success-avatar {\n width:48px; height:48px; border-radius:50%; object-fit:cover;\n flex-shrink:0; border:2px solid ${border};\n }\n .wc-success-avatar-placeholder {\n width:48px; height:48px; border-radius:50%;\n background:linear-gradient(135deg,${accentDark},${accent});\n display:flex; align-items:center; justify-content:center;\n color:#fff; font-weight:700; font-size:18px; flex-shrink:0;\n border:2px solid ${border};\n }\n .wc-success-user-info { flex:1; min-width:0; }\n .wc-success-user-name { font-size:15px; font-weight:600; color:${text}; }\n .wc-success-user-addr {\n font-size:12px; color:${textSecondary}; margin-top:4px;\n font-family:'SF Mono',Monaco,Consolas,monospace;\n word-break:break-all; line-height:1.4;\n }\n .wc-success-done {\n width:100%; padding:14px; border:none; border-radius:14px;\n background:linear-gradient(135deg,${accentDark},${accent});\n color:#fff; font-size:14px; font-weight:700; cursor:pointer;\n transition:all .2s;\n box-shadow:0 4px 16px rgba(43,234,106,0.2);\n }\n .wc-success-done:hover {\n transform:translateY(-1px);\n box-shadow:0 6px 24px rgba(43,234,106,0.3);\n }\n `;\n}\n\nconst TELEGRAM_SVG = `<svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M11.944 0A12 12 0 1 0 24 12.056A12.01 12.01 0 0 0 11.944 0Zm4.962 7.224c.1-.002.321.023.465.14a.506.506 0 0 1 .171.325c.016.093.036.306.02.472c-.18 1.898-.962 6.502-1.36 8.627c-.168.9-.499 1.201-.82 1.23c-.696.065-1.225-.46-1.9-.902c-1.056-.693-1.653-1.124-2.678-1.8c-1.185-.78-.417-1.21.258-1.91c.177-.184 3.247-2.977 3.307-3.23c.007-.032.014-.15-.056-.212s-.174-.041-.249-.024c-.106.024-1.793 1.14-5.061 3.345c-.48.33-.913.49-1.302.48c-.428-.008-1.252-.241-1.865-.44c-.752-.245-1.349-.374-1.297-.789c.027-.216.325-.437.893-.663c3.498-1.524 5.83-2.529 6.998-3.014c3.332-1.386 4.025-1.627 4.476-1.635Z\"/></svg>`;\n\nfunction generateQRDataUrl(text: string, size = 220): string {\n return `https://api.qrserver.com/v1/create-qr-code/?size=${size}x${size}&data=${encodeURIComponent(text)}&margin=8`;\n}\n\nexport class Modal {\n private overlay: HTMLDivElement | null = null;\n private theme: 'light' | 'dark';\n private onClose: () => void;\n\n constructor(theme: 'light' | 'dark', onClose: () => void) {\n this.theme = theme;\n this.onClose = onClose;\n }\n\n showWalletPicker(\n wallets: WalletMeta[],\n onSelect: (wallet: WalletMeta) => void,\n ): void {\n const useGrid = wallets.length >= 3;\n\n const listHtml = useGrid\n ? `<ul class=\"wc-wallet-grid\">${wallets\n .map(\n (w) => `\n <li class=\"wc-wallet-grid-item\" data-wallet-id=\"${w.walletId}\">\n ${\n w.icon\n ? `<img class=\"wc-wallet-grid-icon\" src=\"${w.icon}\" alt=\"${w.name}\" />`\n : `<div class=\"wc-wallet-grid-icon-placeholder\">${w.name.charAt(0)}</div>`\n }\n <span class=\"wc-wallet-grid-name\">${w.name}</span>\n </li>`,\n )\n .join('')}</ul>`\n : `<ul class=\"wc-wallet-list\">${wallets\n .map(\n (w) => `\n <li class=\"wc-wallet-item\" data-wallet-id=\"${w.walletId}\">\n ${\n w.icon\n ? `<img class=\"wc-wallet-list-icon\" src=\"${w.icon}\" alt=\"${w.name}\" />`\n : `<div class=\"wc-wallet-list-icon-placeholder\">${w.name.charAt(0)}</div>`\n }\n <div class=\"wc-wallet-item-info\">\n <div class=\"wc-wallet-item-name\">${w.name}</div>\n ${w.description ? `<div class=\"wc-wallet-item-desc\">${w.description}</div>` : ''}\n </div>\n <span class=\"wc-wallet-item-arrow\">&#8250;</span>\n </li>`,\n )\n .join('')}</ul>`;\n\n const html = `\n <div class=\"wc-handle\"></div>\n <div class=\"wc-header\">\n <h3 class=\"wc-title\">Connect your wallet</h3>\n <button class=\"wc-close\" data-action=\"close\">&#10005;</button>\n </div>\n <p class=\"wc-subtitle\">Choose a wallet to connect to this app</p>\n <div class=\"wc-body\">${listHtml}</div>\n <div class=\"wc-footer\">Powered by WalletConnect</div>\n `;\n\n this.render(html);\n\n wallets.forEach((w) => {\n this.overlay\n ?.querySelector(`[data-wallet-id=\"${w.walletId}\"]`)\n ?.addEventListener('click', () => onSelect(w));\n });\n }\n\n showConnect(\n wallet: WalletMeta,\n deeplink: string,\n showBack: boolean,\n onBack?: () => void,\n ): void {\n const qrUrl = generateQRDataUrl(deeplink);\n\n const html = `\n <div class=\"wc-handle\"></div>\n <div class=\"wc-header\">\n <div class=\"wc-header-left\">\n ${showBack ? '<button class=\"wc-back\" data-action=\"back\">&#8592;</button>' : ''}\n ${wallet.icon ? `<img class=\"wc-header-icon\" src=\"${wallet.icon}\" />` : ''}\n <h3 class=\"wc-title\">${wallet.name}</h3>\n </div>\n <button class=\"wc-close\" data-action=\"close\">&#10005;</button>\n </div>\n <p class=\"wc-subtitle\">Approve the connection request in your wallet</p>\n <div class=\"wc-body\">\n <div class=\"wc-tabs\">\n <button class=\"wc-tab active\" data-tab=\"mobile\">Mobile</button>\n <button class=\"wc-tab\" data-tab=\"qr\">QR Code</button>\n </div>\n <div data-panel=\"mobile\">\n <a class=\"wc-deeplink-btn\" href=\"${deeplink}\" target=\"_blank\">\n ${TELEGRAM_SVG}\n Open in Telegram\n </a>\n </div>\n <div data-panel=\"qr\" style=\"display:none\">\n <div class=\"wc-qr-container\">\n <div class=\"wc-qr-wrap\">\n <img src=\"${qrUrl}\" width=\"220\" height=\"220\" alt=\"QR\" />\n </div>\n <div class=\"wc-qr-hint\">Scan with your phone camera or wallet app</div>\n </div>\n </div>\n <div class=\"wc-status\">\n <div class=\"wc-spinner\"></div>\n <span>Waiting for confirmation...</span>\n </div>\n </div>\n <div class=\"wc-footer\">Powered by WalletConnect</div>\n `;\n\n this.render(html);\n\n const tabs = this.overlay?.querySelectorAll('.wc-tab');\n const panels = this.overlay?.querySelectorAll('[data-panel]');\n tabs?.forEach((tab) => {\n tab.addEventListener('click', () => {\n const target = (tab as HTMLElement).dataset.tab;\n tabs.forEach((t) => t.classList.remove('active'));\n tab.classList.add('active');\n panels?.forEach((p) => {\n (p as HTMLElement).style.display =\n (p as HTMLElement).dataset.panel === target ? 'block' : 'none';\n });\n });\n });\n\n if (showBack && onBack) {\n this.overlay\n ?.querySelector('[data-action=\"back\"]')\n ?.addEventListener('click', onBack);\n }\n }\n\n showSuccess(\n wallet: WalletMeta,\n address: string | null,\n user: { username?: string; avatar?: string } | null,\n onDone: () => void,\n ): void {\n const checkSvg = `<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"/></svg>`;\n\n const displayName = user?.username || 'User';\n const initials = displayName.slice(0, 2).toUpperCase();\n\n const avatarHtml = user?.avatar\n ? `<img class=\"wc-success-avatar\" src=\"${user.avatar}\" alt=\"${displayName}\" />`\n : `<div class=\"wc-success-avatar-placeholder\">${initials}</div>`;\n\n const html = `\n <div class=\"wc-handle\"></div>\n <div class=\"wc-header\">\n <h3 class=\"wc-title\">Connected</h3>\n <button class=\"wc-close\" data-action=\"close\">&#10005;</button>\n </div>\n <div class=\"wc-body\">\n <div class=\"wc-success\">\n <div class=\"wc-success-check\">${checkSvg}</div>\n <div class=\"wc-success-title\">Connection Successful</div>\n <div class=\"wc-success-user\">\n ${avatarHtml}\n <div class=\"wc-success-user-info\">\n <div class=\"wc-success-user-name\">${displayName}</div>\n ${address ? `<div class=\"wc-success-user-addr\" title=\"${address}\">${address}</div>` : ''}\n </div>\n </div>\n <button class=\"wc-success-done\" data-action=\"done\">Done</button>\n </div>\n </div>\n <div class=\"wc-footer\">Powered by WalletConnect</div>\n `;\n\n this.render(html);\n\n this.overlay\n ?.querySelector('[data-action=\"done\"]')\n ?.addEventListener('click', onDone);\n }\n\n updateStatus(text: string, showSpinner = true): void {\n const el = this.overlay?.querySelector('.wc-status');\n if (el) {\n el.innerHTML = `\n ${showSpinner ? '<div class=\"wc-spinner\"></div>' : ''}\n <span>${text}</span>\n `;\n }\n }\n\n private render(innerHtml: string): void {\n this.destroy();\n\n const el = document.createElement('div');\n el.id = MODAL_ID;\n el.innerHTML = `\n <style>${getStyles(this.theme)}</style>\n <div class=\"wc-overlay\">\n <div class=\"wc-modal\">${innerHtml}</div>\n </div>\n `;\n\n document.body.appendChild(el);\n this.overlay = el;\n\n this.overlay\n .querySelector('[data-action=\"close\"]')\n ?.addEventListener('click', () => { this.onClose(); this.destroy(); });\n\n this.overlay\n .querySelector('.wc-overlay')\n ?.addEventListener('click', (e) => {\n if ((e.target as HTMLElement).classList.contains('wc-overlay')) {\n this.onClose();\n this.destroy();\n }\n });\n }\n\n destroy(): void {\n document.getElementById(MODAL_ID)?.remove();\n this.overlay = null;\n }\n}\n","import type {\n WalletConnectConfig,\n WalletMeta,\n ConnectResult,\n ConnectSession,\n InitSessionResponse,\n WalletConnectEventType,\n WalletConnectEventCallback,\n} from './types';\nimport { WsTransport, PollingTransport } from './transport';\nimport { Modal } from './modal';\n\nconst STORAGE_KEY_PREFIX = '__wc_session_';\nconst DEFAULT_REGISTRY_URL = 'https://cdn.jsdelivr.net/npm/toncorp-wallet-connect-sdk@latest/registry.json';\n\nexport class BaseWalletConnect {\n protected config: Required<\n Pick<WalletConnectConfig, 'appId' | 'registryUrl' | 'theme'>\n > &\n Pick<WalletConnectConfig, 'walletId'>;\n\n private listeners: Map<WalletConnectEventType, Set<WalletConnectEventCallback>> = new Map();\n private modal: Modal | null = null;\n private wsTransport: WsTransport | null = null;\n private pollingTransport: PollingTransport | null = null;\n private currentResult: ConnectResult | null = null;\n\n constructor(config: WalletConnectConfig) {\n this.config = {\n appId: config.appId,\n registryUrl: config.registryUrl || DEFAULT_REGISTRY_URL,\n walletId: config.walletId,\n theme: config.theme || 'light',\n };\n\n this.restoreSession();\n this.registerGlobal();\n }\n\n // ── Public API ──\n\n async connect(): Promise<ConnectResult> {\n if (this.currentResult) {\n return this.currentResult;\n }\n\n const wallets = await this.fetchWallets();\n const filtered = this.filterWallets(wallets);\n\n if (filtered.length === 0) {\n throw new Error('No supported wallets available');\n }\n\n return new Promise<ConnectResult>((resolve, reject) => {\n const onClose = () => {\n this.cleanup();\n reject(new Error('User closed modal'));\n };\n\n this.modal = new Modal(this.config.theme, onClose);\n\n if (filtered.length === 1) {\n this.startConnect(filtered[0], false, resolve, reject);\n } else {\n this.modal.showWalletPicker(filtered, (wallet) => {\n this.startConnect(wallet, true, resolve, reject);\n });\n }\n });\n }\n\n disconnect(): void {\n // Call disconnect API (fire-and-forget)\n const session = this.currentResult?.session;\n if (session) {\n const baseUrl = session.apiUrl.replace(/\\/$/, '');\n fetch(`${baseUrl}/connect/disconnect-by-token`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ sessionToken: session.sessionToken }),\n }).catch(() => {});\n }\n\n // Clear all localStorage keys and window instances\n this.currentResult = null;\n this.removeStoredSession();\n this.clearAllRelatedSessions();\n this.cleanup();\n this.emit('disconnect');\n }\n\n isConnected(): boolean {\n return this.currentResult !== null;\n }\n\n getWallet(): ConnectResult | null {\n return this.currentResult;\n }\n\n on(event: WalletConnectEventType, cb: WalletConnectEventCallback): void {\n if (!this.listeners.has(event)) {\n this.listeners.set(event, new Set());\n }\n this.listeners.get(event)!.add(cb);\n }\n\n off(event: WalletConnectEventType, cb: WalletConnectEventCallback): void {\n this.listeners.get(event)?.delete(cb);\n }\n\n // ── Internal ──\n\n private get storageKey(): string {\n const walletId = this.config.walletId;\n const suffix = Array.isArray(walletId)\n ? walletId.sort().join('_')\n : walletId || 'all';\n return `${STORAGE_KEY_PREFIX}${suffix}__`;\n }\n\n private async fetchWallets(): Promise<WalletMeta[]> {\n const url = this.config.registryUrl.replace(/\\/$/, '');\n const res = await fetch(url);\n if (!res.ok) throw new Error('Failed to fetch wallets');\n return res.json();\n }\n\n private filterWallets(wallets: WalletMeta[]): WalletMeta[] {\n if (!this.config.walletId) return wallets;\n\n const ids = Array.isArray(this.config.walletId)\n ? this.config.walletId\n : [this.config.walletId];\n\n return wallets.filter((w) => ids.includes(w.walletId));\n }\n\n private async startConnect(\n wallet: WalletMeta,\n showBack: boolean,\n resolve: (result: ConnectResult) => void,\n reject: (error: Error) => void,\n ): Promise<void> {\n try {\n const session = await this.initSession(wallet);\n\n this.modal?.showConnect(wallet, session.deeplink, showBack, () => {\n this.cleanup();\n this.connect().then(resolve).catch(reject);\n });\n\n this.listenForConfirmation(\n wallet.apiUrl,\n session.sessionToken,\n (result) => {\n // Attach session info for disconnect\n result.session = {\n sessionToken: session.sessionToken,\n walletId: wallet.walletId,\n apiUrl: wallet.apiUrl,\n };\n this.currentResult = result;\n this.storeSession(result);\n this.syncToWalletInstance(wallet.walletId, result);\n this.emit('connect', result);\n\n // Show success screen\n this.modal?.showSuccess(\n wallet,\n result.wallet?.address || null,\n result.user || null,\n () => {\n this.modal?.destroy();\n this.modal = null;\n resolve(result);\n },\n );\n },\n () => {\n this.modal?.updateStatus('Connection rejected', false);\n setTimeout(() => {\n this.modal?.destroy();\n this.modal = null;\n reject(new Error('Connection rejected by user'));\n }, 1500);\n },\n () => {\n this.modal?.updateStatus('Session expired', false);\n this.emit('session_expired');\n setTimeout(() => {\n this.modal?.destroy();\n this.modal = null;\n reject(new Error('Session expired'));\n }, 1500);\n },\n );\n } catch (err) {\n this.modal?.destroy();\n this.modal = null;\n reject(err instanceof Error ? err : new Error(String(err)));\n }\n }\n\n private async initSession(wallet: WalletMeta): Promise<InitSessionResponse> {\n const baseUrl = wallet.apiUrl.replace(/\\/$/, '');\n const res = await fetch(`${baseUrl}/connect/init`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n appId: this.config.appId,\n walletId: wallet.walletId,\n origin: typeof window !== 'undefined' ? window.location.origin : '',\n }),\n });\n if (!res.ok) throw new Error('Failed to init session');\n return res.json();\n }\n\n private listenForConfirmation(\n apiUrl: string,\n sessionToken: string,\n onConfirmed: (result: ConnectResult) => void,\n onRejected: () => void,\n onExpired: () => void,\n ): void {\n let resolved = false;\n\n const wrap = <T extends (...args: any[]) => void>(fn: T): T =>\n ((...args: any[]) => {\n if (resolved) return;\n resolved = true;\n this.wsTransport?.close();\n this.pollingTransport?.stop();\n fn(...args);\n }) as unknown as T;\n\n const wrappedConfirm = wrap(onConfirmed);\n const wrappedReject = wrap(onRejected);\n const wrappedExpire = wrap(onExpired);\n\n // Start polling immediately as primary transport\n this.pollingTransport = new PollingTransport(\n apiUrl,\n sessionToken,\n wrappedConfirm,\n wrappedReject,\n wrappedExpire,\n (msg) => this.emit('error', msg),\n );\n this.pollingTransport.start();\n\n // Also try WS for faster response\n this.wsTransport = new WsTransport(\n apiUrl,\n sessionToken,\n wrappedConfirm,\n wrappedReject,\n wrappedExpire,\n () => {}, // WS fail is fine, polling is running\n );\n this.wsTransport.connect();\n }\n\n private cleanup(): void {\n this.wsTransport?.close();\n this.wsTransport = null;\n this.pollingTransport?.stop();\n this.pollingTransport = null;\n this.modal?.destroy();\n this.modal = null;\n }\n\n private emit(event: WalletConnectEventType, data?: any): void {\n this.listeners.get(event)?.forEach((cb) => cb(data));\n }\n\n // ── Persistence ──\n\n private storeSession(result: ConnectResult): void {\n try {\n localStorage.setItem(this.storageKey, JSON.stringify(result));\n } catch {\n // localStorage unavailable\n }\n }\n\n private restoreSession(): void {\n try {\n const stored = localStorage.getItem(this.storageKey);\n if (stored) {\n this.currentResult = JSON.parse(stored);\n }\n } catch {\n // ignore\n }\n }\n\n private removeStoredSession(): void {\n try {\n localStorage.removeItem(this.storageKey);\n } catch {\n // ignore\n }\n }\n\n // ── Global window registration ──\n\n private registerGlobal(): void {\n if (typeof window === 'undefined') return;\n\n const walletId = this.config.walletId;\n const key = Array.isArray(walletId)\n ? walletId[0]\n : walletId || 'walletconnect';\n\n (window as any)[key] = this;\n }\n\n /** Sync connect result to the specific wallet instance on window (e.g. window.onedollar) */\n private syncToWalletInstance(walletId: string, result: ConnectResult): void {\n if (typeof window === 'undefined') return;\n\n const target = (window as any)[walletId];\n if (target && target !== this && target instanceof BaseWalletConnect) {\n (target as any).currentResult = result;\n (target as any).storeSession(result);\n }\n }\n\n /** Clear all related sessions from window instances and localStorage */\n private clearAllRelatedSessions(): void {\n if (typeof window === 'undefined') return;\n\n // Clear all known wallet instances on window\n const keys = ['tonpass', 'onedollar', 'walletconnect'];\n for (const key of keys) {\n const inst = (window as any)[key];\n if (inst && inst !== this && inst instanceof BaseWalletConnect) {\n (inst as any).currentResult = null;\n (inst as any).removeStoredSession();\n }\n }\n\n // Also clear all wc localStorage keys\n try {\n const toRemove: string[] = [];\n for (let i = 0; i < localStorage.length; i++) {\n const k = localStorage.key(i);\n if (k && k.startsWith(STORAGE_KEY_PREFIX)) {\n toRemove.push(k);\n }\n }\n toRemove.forEach((k) => localStorage.removeItem(k));\n } catch {\n // ignore\n }\n }\n}\n","import { BaseWalletConnect } from './client';\nimport type { WalletConnectConfig } from './types';\n\nexport class OneDollarConnect extends BaseWalletConnect {\n constructor(config: Omit<WalletConnectConfig, 'walletId'>) {\n super({ ...config, walletId: 'onedollar' });\n }\n}\n","import { BaseWalletConnect } from './client';\nimport type { WalletConnectConfig } from './types';\n\nexport class TonPassConnect extends BaseWalletConnect {\n constructor(config: Omit<WalletConnectConfig, 'walletId'>) {\n super({ ...config, walletId: 'tonpass' });\n }\n}\n"],"names":["WsTransport","constructor","apiUrl","sessionToken","onConfirmed","onRejected","onExpired","onError","this","ws","reconnectTimer","closed","connect","replace","connectSocketIO","baseUrl","fetch","then","res","text","body","jsonStr","sid","JSON","parse","wsUrl","WebSocket","onopen","send","onmessage","event","msg","data","startsWith","payload","slice","eventName","handleEvent","onclose","scheduleReconnect","onerror","catch","close","setTimeout","clearTimeout","PollingTransport","timer","stopped","start","poll","setInterval","ok","json","status","wallet","user","stop","clearInterval","MODAL_ID","Modal","theme","onClose","overlay","showWalletPicker","wallets","onSelect","html","length","map","w","walletId","icon","name","charAt","join","description","render","forEach","querySelector","addEventListener","showConnect","deeplink","showBack","onBack","qrUrl","size","encodeURIComponent","generateQRDataUrl","tabs","querySelectorAll","panels","tab","target","dataset","t","classList","remove","add","p","style","display","panel","showSuccess","address","onDone","displayName","username","initials","toUpperCase","avatar","updateStatus","showSpinner","el","innerHTML","innerHtml","destroy","document","createElement","id","isDark","bg","bgSecondary","textSecondary","border","accent","accentDark","getStyles","appendChild","e","contains","getElementById","STORAGE_KEY_PREFIX","BaseWalletConnect","config","listeners","Map","modal","wsTransport","pollingTransport","currentResult","appId","registryUrl","restoreSession","registerGlobal","fetchWallets","filtered","filterWallets","Error","Promise","resolve","reject","cleanup","startConnect","disconnect","session","method","headers","stringify","removeStoredSession","clearAllRelatedSessions","emit","isConnected","getWallet","on","cb","has","set","Set","get","off","delete","storageKey","suffix","Array","isArray","sort","url","ids","filter","includes","initSession","listenForConfirmation","result","storeSession","syncToWalletInstance","err","String","origin","window","location","resolved","wrap","fn","args","wrappedConfirm","wrappedReject","wrappedExpire","localStorage","setItem","stored","getItem","removeItem","key","keys","inst","toRemove","i","k","push","super"],"mappings":"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"}
1
+ {"version":3,"file":"index.umd.js","sources":["../../transport.ts","../../modal.ts","../../client.ts","../../onedollar.ts","../../tonpass.ts"],"sourcesContent":["import type { ConnectResult } from './types';\n\ntype TransportCallback = (data: ConnectResult) => void;\ntype TransportErrorCallback = (error: string) => void;\n\n// ── WebSocket Transport ──\n\nexport class WsTransport {\n private ws: WebSocket | null = null;\n private reconnectTimer: ReturnType<typeof setTimeout> | null = null;\n private closed = false;\n\n constructor(\n private apiUrl: string,\n private sessionToken: string,\n private onConfirmed: TransportCallback,\n private onRejected: () => void,\n private onExpired: () => void,\n private onError: TransportErrorCallback,\n ) {}\n\n connect(): void {\n this.closed = false;\n const wsUrl = this.apiUrl\n .replace(/^http/, 'ws')\n .replace(/\\/$/, '');\n const url = `${wsUrl}/walletconnect?sessionToken=${this.sessionToken}`;\n\n try {\n // Socket.IO uses polling upgrade — use native WS for simplicity in SDK\n // The BE gateway uses socket.io, so we connect via socket.io protocol\n this.connectSocketIO();\n } catch {\n this.onError('WebSocket connection failed');\n }\n }\n\n private connectSocketIO(): void {\n const baseUrl = this.apiUrl.replace(/\\/$/, '');\n\n // Socket.IO handshake: first GET for sid, then upgrade to WS\n const pollingUrl = `${baseUrl}/walletconnect/?EIO=4&transport=polling`;\n\n fetch(pollingUrl)\n .then((res) => res.text())\n .then((body) => {\n // Socket.IO response format: \"0{...json...}\"\n const jsonStr = body.replace(/^\\d+/, '');\n const handshake = JSON.parse(jsonStr);\n const sid = handshake.sid;\n\n const wsBase = baseUrl.replace(/^http/, 'ws');\n const wsUrl = `${wsBase}/walletconnect/?EIO=4&transport=websocket&sid=${sid}`;\n\n this.ws = new WebSocket(wsUrl);\n\n this.ws.onopen = () => {\n // Socket.IO upgrade probe\n this.ws!.send('2probe');\n };\n\n this.ws.onmessage = (event) => {\n const msg = event.data as string;\n\n if (msg === '3probe') {\n // Upgrade confirmed, send upgrade packet + join room\n this.ws!.send('5');\n // Emit connect event with sessionToken as query (already in URL)\n // Socket.IO auto-joins based on handshake query\n return;\n }\n\n // Handle Socket.IO event messages: 42[\"event_name\", {...data}]\n if (msg.startsWith('42')) {\n try {\n const payload = JSON.parse(msg.slice(2));\n const [eventName, data] = payload;\n this.handleEvent(eventName, data);\n } catch {\n // ignore malformed\n }\n return;\n }\n\n // Ping from server\n if (msg === '2') {\n this.ws!.send('3');\n }\n };\n\n this.ws.onclose = () => {\n if (!this.closed) {\n this.scheduleReconnect();\n }\n };\n\n this.ws.onerror = () => {\n if (!this.closed) {\n this.scheduleReconnect();\n }\n };\n })\n .catch(() => {\n if (!this.closed) {\n this.scheduleReconnect();\n }\n });\n }\n\n private handleEvent(eventName: string, data: any): void {\n switch (eventName) {\n case 'session_confirmed':\n this.onConfirmed(data);\n this.close();\n break;\n case 'session_rejected':\n this.onRejected();\n this.close();\n break;\n case 'session_expired':\n this.onExpired();\n this.close();\n break;\n }\n }\n\n private scheduleReconnect(): void {\n if (this.closed || this.reconnectTimer) return;\n this.reconnectTimer = setTimeout(() => {\n this.reconnectTimer = null;\n this.connectSocketIO();\n }, 3000);\n }\n\n close(): void {\n this.closed = true;\n if (this.reconnectTimer) {\n clearTimeout(this.reconnectTimer);\n this.reconnectTimer = null;\n }\n if (this.ws) {\n this.ws.close();\n this.ws = null;\n }\n }\n}\n\n// ── Long-Poll Fallback ──\n\nexport class PollingTransport {\n private timer: ReturnType<typeof setInterval> | null = null;\n private stopped = false;\n\n constructor(\n private apiUrl: string,\n private sessionToken: string,\n private onConfirmed: TransportCallback,\n private onRejected: () => void,\n private onExpired: () => void,\n private onError: TransportErrorCallback,\n ) {}\n\n start(): void {\n this.stopped = false;\n this.poll();\n this.timer = setInterval(() => this.poll(), 2000);\n }\n\n private async poll(): Promise<void> {\n if (this.stopped) return;\n\n try {\n const baseUrl = this.apiUrl.replace(/\\/$/, '');\n const res = await fetch(\n `${baseUrl}/connect/status?token=${this.sessionToken}`,\n );\n if (!res.ok) return;\n\n const data = await res.json();\n\n switch (data.status) {\n case 'CONFIRMED':\n this.onConfirmed({ wallet: data.wallet, user: data.user });\n this.stop();\n break;\n case 'REJECTED':\n this.onRejected();\n this.stop();\n break;\n case 'EXPIRED':\n this.onExpired();\n this.stop();\n break;\n }\n } catch {\n // silently retry next interval\n }\n }\n\n stop(): void {\n this.stopped = true;\n if (this.timer) {\n clearInterval(this.timer);\n this.timer = null;\n }\n }\n}\n","import type { WalletMeta } from './types';\n\nconst MODAL_ID = '__wc_modal__';\n\nfunction getStyles(theme: 'light' | 'dark'): string {\n const isDark = theme === 'dark';\n const bg = isDark ? '#141414' : '#ffffff';\n const bgSecondary = isDark ? '#1e1e1e' : '#f4f4f4';\n const text = isDark ? '#ffffff' : '#141414';\n const textSecondary = isDark ? '#9a9a9a' : '#787878';\n const border = isDark ? '#2a2a2a' : '#e4e4e4';\n const accent = '#2bea6a';\n const accentDark = '#1db954';\n\n return `\n @keyframes wc-fadeIn { from{opacity:0} to{opacity:1} }\n @keyframes wc-slideUp {\n from{opacity:0;transform:translateY(100%)}\n to{opacity:1;transform:translateY(0)}\n }\n .wc-overlay {\n position:fixed; inset:0; z-index:99999;\n background:rgba(0,0,0,${isDark ? 0.75 : 0.45});\n display:flex; align-items:flex-end; justify-content:center;\n font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;\n backdrop-filter:blur(6px); -webkit-backdrop-filter:blur(6px);\n animation:wc-fadeIn .2s ease;\n }\n @media(min-width:480px){\n .wc-overlay{align-items:center}\n .wc-modal{border-radius:24px;max-height:85vh}\n }\n .wc-modal {\n background:${bg}; width:100%; max-width:420px;\n border-radius:24px 24px 0 0; overflow:hidden; color:${text};\n box-shadow:0 -8px 40px rgba(0,0,0,${isDark ? 0.5 : 0.15});\n animation:wc-slideUp .3s cubic-bezier(.16,1,.3,1);\n max-height:90vh; overflow-y:auto;\n }\n\n /* Handle bar */\n .wc-handle {\n width:36px; height:4px; border-radius:2px;\n background:${border}; margin:10px auto 0;\n }\n\n /* Header */\n .wc-header {\n display:flex; align-items:center; justify-content:space-between;\n padding:20px 24px 0;\n }\n .wc-header-left {\n display:flex; align-items:center; gap:10px;\n }\n .wc-header-icon {\n width:32px; height:32px; border-radius:10px; object-fit:cover;\n }\n .wc-title { font-size:17px; font-weight:700; margin:0; }\n .wc-close {\n width:30px; height:30px; display:flex; align-items:center; justify-content:center;\n background:${bgSecondary}; border:none; border-radius:50%;\n cursor:pointer; font-size:14px; color:${textSecondary};\n transition:all .15s;\n }\n .wc-close:hover { background:${border}; color:${text}; }\n .wc-subtitle {\n font-size:13px; color:${textSecondary}; margin:8px 24px 0;\n line-height:1.4;\n }\n\n .wc-body { padding:20px 24px 24px; }\n\n /* Grid wallet picker */\n .wc-wallet-grid {\n display:grid; grid-template-columns:repeat(4,1fr);\n gap:16px 12px; list-style:none; margin:0; padding:0;\n }\n .wc-wallet-grid-item {\n display:flex; flex-direction:column; align-items:center;\n gap:8px; cursor:pointer; padding:8px 4px; border-radius:16px;\n transition:all .15s; border:2px solid transparent;\n }\n .wc-wallet-grid-item:hover {\n background:${bgSecondary}; border-color:${border};\n }\n .wc-wallet-grid-icon {\n width:56px; height:56px; border-radius:16px;\n object-fit:cover; box-shadow:0 2px 8px rgba(0,0,0,${isDark ? 0.3 : 0.08});\n }\n .wc-wallet-grid-icon-placeholder {\n width:56px; height:56px; border-radius:16px;\n background:linear-gradient(135deg,${accentDark},${accent});\n display:flex; align-items:center; justify-content:center;\n color:#fff; font-weight:800; font-size:22px;\n box-shadow:0 2px 8px rgba(0,0,0,${isDark ? 0.3 : 0.08});\n }\n .wc-wallet-grid-name {\n font-size:11px; font-weight:500; text-align:center;\n color:${textSecondary}; line-height:1.2;\n max-width:72px; overflow:hidden; text-overflow:ellipsis;\n white-space:nowrap;\n }\n\n /* List wallet picker (alternative) */\n .wc-wallet-list { list-style:none; margin:0; padding:0; }\n .wc-wallet-item {\n display:flex; align-items:center; gap:14px;\n padding:12px 16px; border-radius:16px; cursor:pointer;\n border:1.5px solid ${border}; margin-bottom:8px;\n transition:all .15s;\n }\n .wc-wallet-item:hover {\n background:${bgSecondary}; border-color:${accent};\n }\n .wc-wallet-list-icon {\n width:40px; height:40px; border-radius:12px; object-fit:cover;\n }\n .wc-wallet-list-icon-placeholder {\n width:40px; height:40px; border-radius:12px;\n background:linear-gradient(135deg,${accentDark},${accent});\n display:flex; align-items:center; justify-content:center;\n color:#fff; font-weight:700; font-size:16px;\n }\n .wc-wallet-item-info { flex:1; }\n .wc-wallet-item-name { font-size:14px; font-weight:600; }\n .wc-wallet-item-desc { font-size:11px; color:${textSecondary}; margin-top:1px; }\n .wc-wallet-item-arrow { color:${textSecondary}; font-size:16px; }\n\n /* Tabs */\n .wc-tabs {\n display:flex; background:${bgSecondary}; border-radius:12px;\n padding:3px; margin-bottom:20px;\n }\n .wc-tab {\n flex:1; padding:10px; text-align:center; cursor:pointer;\n font-size:13px; font-weight:600; background:transparent;\n border:none; color:${textSecondary}; border-radius:10px;\n transition:all .2s;\n }\n .wc-tab:hover { color:${text}; }\n .wc-tab.active {\n background:${bg}; color:${text};\n box-shadow:0 1px 4px rgba(0,0,0,${isDark ? 0.3 : 0.08});\n }\n\n /* Deeplink */\n .wc-deeplink-btn {\n display:flex; align-items:center; justify-content:center; gap:10px;\n width:100%; padding:16px; border:none; border-radius:16px;\n background:linear-gradient(135deg,${accentDark},${accent});\n color:#fff; font-size:15px; font-weight:700; cursor:pointer;\n text-decoration:none; transition:all .2s;\n box-shadow:0 4px 20px rgba(43,234,106,0.2);\n box-sizing:border-box;\n }\n .wc-deeplink-btn:hover {\n transform:translateY(-1px);\n box-shadow:0 6px 28px rgba(43,234,106,0.3);\n }\n\n /* QR */\n .wc-qr-container {\n display:flex; flex-direction:column; align-items:center; gap:16px;\n }\n .wc-qr-wrap {\n padding:16px; background:#fff; border-radius:20px;\n box-shadow:0 2px 16px rgba(0,0,0,${isDark ? 0.2 : 0.06});\n }\n .wc-qr-wrap img { display:block; border-radius:4px; }\n .wc-qr-hint { font-size:12px; color:${textSecondary}; text-align:center; }\n\n /* Status */\n .wc-status {\n display:flex; align-items:center; justify-content:center;\n gap:10px; padding:20px 0 4px; font-size:13px; color:${textSecondary};\n }\n .wc-spinner {\n width:16px; height:16px; border:2px solid ${border};\n border-top-color:${accent}; border-radius:50%;\n animation:wc-spin .7s linear infinite;\n }\n @keyframes wc-spin { to{transform:rotate(360deg)} }\n\n /* Back */\n .wc-back {\n background:none; border:none; cursor:pointer; padding:0;\n color:${textSecondary}; display:flex; align-items:center;\n transition:color .15s; font-size:18px;\n }\n .wc-back:hover { color:${text}; }\n\n /* Footer */\n .wc-footer {\n text-align:center; padding:4px 0 20px;\n font-size:11px; color:${isDark ? '#555' : '#bbb'};\n }\n\n /* Success screen */\n .wc-success {\n display:flex; flex-direction:column; align-items:center;\n padding:12px 0 4px; gap:20px;\n }\n .wc-success-check {\n width:64px; height:64px; border-radius:50%;\n background:linear-gradient(135deg,${accentDark},${accent});\n display:flex; align-items:center; justify-content:center;\n box-shadow:0 4px 20px rgba(43,234,106,0.25);\n animation:wc-popIn .4s cubic-bezier(.16,1,.3,1);\n }\n @keyframes wc-popIn {\n from{transform:scale(0);opacity:0}\n 50%{transform:scale(1.15)}\n to{transform:scale(1);opacity:1}\n }\n .wc-success-check svg { width:32px; height:32px; color:#fff; }\n .wc-success-title {\n font-size:18px; font-weight:700; color:${text};\n }\n .wc-success-user {\n display:flex; align-items:center; gap:14px;\n background:${bgSecondary}; border-radius:16px;\n padding:16px 18px; width:100%; box-sizing:border-box;\n }\n .wc-success-avatar {\n width:48px; height:48px; border-radius:50%; object-fit:cover;\n flex-shrink:0; border:2px solid ${border};\n }\n .wc-success-avatar-placeholder {\n width:48px; height:48px; border-radius:50%;\n background:linear-gradient(135deg,${accentDark},${accent});\n display:flex; align-items:center; justify-content:center;\n color:#fff; font-weight:700; font-size:18px; flex-shrink:0;\n border:2px solid ${border};\n }\n .wc-success-user-info { flex:1; min-width:0; }\n .wc-success-user-name { font-size:15px; font-weight:600; color:${text}; }\n .wc-success-user-addr {\n font-size:12px; color:${textSecondary}; margin-top:4px;\n font-family:'SF Mono',Monaco,Consolas,monospace;\n word-break:break-all; line-height:1.4;\n }\n .wc-success-done {\n width:100%; padding:14px; border:none; border-radius:14px;\n background:linear-gradient(135deg,${accentDark},${accent});\n color:#fff; font-size:14px; font-weight:700; cursor:pointer;\n transition:all .2s;\n box-shadow:0 4px 16px rgba(43,234,106,0.2);\n }\n .wc-success-done:hover {\n transform:translateY(-1px);\n box-shadow:0 6px 24px rgba(43,234,106,0.3);\n }\n `;\n}\n\nconst TELEGRAM_SVG = `<svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M11.944 0A12 12 0 1 0 24 12.056A12.01 12.01 0 0 0 11.944 0Zm4.962 7.224c.1-.002.321.023.465.14a.506.506 0 0 1 .171.325c.016.093.036.306.02.472c-.18 1.898-.962 6.502-1.36 8.627c-.168.9-.499 1.201-.82 1.23c-.696.065-1.225-.46-1.9-.902c-1.056-.693-1.653-1.124-2.678-1.8c-1.185-.78-.417-1.21.258-1.91c.177-.184 3.247-2.977 3.307-3.23c.007-.032.014-.15-.056-.212s-.174-.041-.249-.024c-.106.024-1.793 1.14-5.061 3.345c-.48.33-.913.49-1.302.48c-.428-.008-1.252-.241-1.865-.44c-.752-.245-1.349-.374-1.297-.789c.027-.216.325-.437.893-.663c3.498-1.524 5.83-2.529 6.998-3.014c3.332-1.386 4.025-1.627 4.476-1.635Z\"/></svg>`;\n\nfunction generateQRDataUrl(text: string, size = 220): string {\n return `https://api.qrserver.com/v1/create-qr-code/?size=${size}x${size}&data=${encodeURIComponent(text)}&margin=8`;\n}\n\nexport class Modal {\n private overlay: HTMLDivElement | null = null;\n private theme: 'light' | 'dark';\n private onClose: () => void;\n\n constructor(theme: 'light' | 'dark', onClose: () => void) {\n this.theme = theme;\n this.onClose = onClose;\n }\n\n showWalletPicker(\n wallets: WalletMeta[],\n onSelect: (wallet: WalletMeta) => void,\n ): void {\n const useGrid = wallets.length >= 3;\n\n const listHtml = useGrid\n ? `<ul class=\"wc-wallet-grid\">${wallets\n .map(\n (w) => `\n <li class=\"wc-wallet-grid-item\" data-wallet-id=\"${w.walletId}\">\n ${\n w.icon\n ? `<img class=\"wc-wallet-grid-icon\" src=\"${w.icon}\" alt=\"${w.name}\" />`\n : `<div class=\"wc-wallet-grid-icon-placeholder\">${w.name.charAt(0)}</div>`\n }\n <span class=\"wc-wallet-grid-name\">${w.name}</span>\n </li>`,\n )\n .join('')}</ul>`\n : `<ul class=\"wc-wallet-list\">${wallets\n .map(\n (w) => `\n <li class=\"wc-wallet-item\" data-wallet-id=\"${w.walletId}\">\n ${\n w.icon\n ? `<img class=\"wc-wallet-list-icon\" src=\"${w.icon}\" alt=\"${w.name}\" />`\n : `<div class=\"wc-wallet-list-icon-placeholder\">${w.name.charAt(0)}</div>`\n }\n <div class=\"wc-wallet-item-info\">\n <div class=\"wc-wallet-item-name\">${w.name}</div>\n ${w.description ? `<div class=\"wc-wallet-item-desc\">${w.description}</div>` : ''}\n </div>\n <span class=\"wc-wallet-item-arrow\">&#8250;</span>\n </li>`,\n )\n .join('')}</ul>`;\n\n const html = `\n <div class=\"wc-handle\"></div>\n <div class=\"wc-header\">\n <h3 class=\"wc-title\">Connect your wallet</h3>\n <button class=\"wc-close\" data-action=\"close\">&#10005;</button>\n </div>\n <p class=\"wc-subtitle\">Choose a wallet to connect to this app</p>\n <div class=\"wc-body\">${listHtml}</div>\n <div class=\"wc-footer\">Powered by WalletConnect</div>\n `;\n\n this.render(html);\n\n wallets.forEach((w) => {\n this.overlay\n ?.querySelector(`[data-wallet-id=\"${w.walletId}\"]`)\n ?.addEventListener('click', () => onSelect(w));\n });\n }\n\n showConnect(\n wallet: WalletMeta,\n deeplink: string,\n showBack: boolean,\n onBack?: () => void,\n ): void {\n const qrUrl = generateQRDataUrl(deeplink);\n\n const html = `\n <div class=\"wc-handle\"></div>\n <div class=\"wc-header\">\n <div class=\"wc-header-left\">\n ${showBack ? '<button class=\"wc-back\" data-action=\"back\">&#8592;</button>' : ''}\n ${wallet.icon ? `<img class=\"wc-header-icon\" src=\"${wallet.icon}\" />` : ''}\n <h3 class=\"wc-title\">${wallet.name}</h3>\n </div>\n <button class=\"wc-close\" data-action=\"close\">&#10005;</button>\n </div>\n <p class=\"wc-subtitle\">Approve the connection request in your wallet</p>\n <div class=\"wc-body\">\n <div class=\"wc-tabs\">\n <button class=\"wc-tab active\" data-tab=\"mobile\">Mobile</button>\n <button class=\"wc-tab\" data-tab=\"qr\">QR Code</button>\n </div>\n <div data-panel=\"mobile\">\n <a class=\"wc-deeplink-btn\" href=\"${deeplink}\" target=\"_blank\">\n ${TELEGRAM_SVG}\n Open in Telegram\n </a>\n </div>\n <div data-panel=\"qr\" style=\"display:none\">\n <div class=\"wc-qr-container\">\n <div class=\"wc-qr-wrap\">\n <img src=\"${qrUrl}\" width=\"220\" height=\"220\" alt=\"QR\" />\n </div>\n <div class=\"wc-qr-hint\">Scan with your phone camera or wallet app</div>\n </div>\n </div>\n <div class=\"wc-status\">\n <div class=\"wc-spinner\"></div>\n <span>Waiting for confirmation...</span>\n </div>\n </div>\n <div class=\"wc-footer\">Powered by WalletConnect</div>\n `;\n\n this.render(html);\n\n const tabs = this.overlay?.querySelectorAll('.wc-tab');\n const panels = this.overlay?.querySelectorAll('[data-panel]');\n tabs?.forEach((tab) => {\n tab.addEventListener('click', () => {\n const target = (tab as HTMLElement).dataset.tab;\n tabs.forEach((t) => t.classList.remove('active'));\n tab.classList.add('active');\n panels?.forEach((p) => {\n (p as HTMLElement).style.display =\n (p as HTMLElement).dataset.panel === target ? 'block' : 'none';\n });\n });\n });\n\n if (showBack && onBack) {\n this.overlay\n ?.querySelector('[data-action=\"back\"]')\n ?.addEventListener('click', onBack);\n }\n }\n\n showSuccess(\n wallet: WalletMeta,\n address: string | null,\n user: { username?: string; avatar?: string } | null,\n onDone: () => void,\n ): void {\n const checkSvg = `<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"/></svg>`;\n\n const displayName = user?.username || 'User';\n const initials = displayName.slice(0, 2).toUpperCase();\n\n const avatarHtml = user?.avatar\n ? `<img class=\"wc-success-avatar\" src=\"${user.avatar}\" alt=\"${displayName}\" />`\n : `<div class=\"wc-success-avatar-placeholder\">${initials}</div>`;\n\n const html = `\n <div class=\"wc-handle\"></div>\n <div class=\"wc-header\">\n <h3 class=\"wc-title\">Connected</h3>\n <button class=\"wc-close\" data-action=\"close\">&#10005;</button>\n </div>\n <div class=\"wc-body\">\n <div class=\"wc-success\">\n <div class=\"wc-success-check\">${checkSvg}</div>\n <div class=\"wc-success-title\">Connection Successful</div>\n <div class=\"wc-success-user\">\n ${avatarHtml}\n <div class=\"wc-success-user-info\">\n <div class=\"wc-success-user-name\">${displayName}</div>\n ${address ? `<div class=\"wc-success-user-addr\" title=\"${address}\">${address}</div>` : ''}\n </div>\n </div>\n <button class=\"wc-success-done\" data-action=\"done\">Done</button>\n </div>\n </div>\n <div class=\"wc-footer\">Powered by WalletConnect</div>\n `;\n\n this.render(html);\n\n this.overlay\n ?.querySelector('[data-action=\"done\"]')\n ?.addEventListener('click', onDone);\n }\n\n updateStatus(text: string, showSpinner = true): void {\n const el = this.overlay?.querySelector('.wc-status');\n if (el) {\n el.innerHTML = `\n ${showSpinner ? '<div class=\"wc-spinner\"></div>' : ''}\n <span>${text}</span>\n `;\n }\n }\n\n private render(innerHtml: string): void {\n this.destroy();\n\n const el = document.createElement('div');\n el.id = MODAL_ID;\n el.innerHTML = `\n <style>${getStyles(this.theme)}</style>\n <div class=\"wc-overlay\">\n <div class=\"wc-modal\">${innerHtml}</div>\n </div>\n `;\n\n document.body.appendChild(el);\n this.overlay = el;\n\n this.overlay\n .querySelector('[data-action=\"close\"]')\n ?.addEventListener('click', () => { this.onClose(); this.destroy(); });\n\n this.overlay\n .querySelector('.wc-overlay')\n ?.addEventListener('click', (e) => {\n if ((e.target as HTMLElement).classList.contains('wc-overlay')) {\n this.onClose();\n this.destroy();\n }\n });\n }\n\n destroy(): void {\n document.getElementById(MODAL_ID)?.remove();\n this.overlay = null;\n }\n}\n","import type {\n WalletConnectConfig,\n WalletMeta,\n ConnectResult,\n ConnectSession,\n InitSessionResponse,\n WalletConnectEventType,\n WalletConnectEventCallback,\n} from './types';\nimport { WsTransport, PollingTransport } from './transport';\nimport { Modal } from './modal';\n\nconst STORAGE_KEY_PREFIX = '__wc_session_';\nconst DEFAULT_REGISTRY_URL = 'https://cdn.jsdelivr.net/npm/toncorp-wallet-connect-sdk@latest/registry.json';\n\nexport class BaseWalletConnect {\n protected config: Required<\n Pick<WalletConnectConfig, 'appId' | 'registryUrl' | 'theme'>\n > &\n Pick<WalletConnectConfig, 'walletId'>;\n\n private listeners: Map<WalletConnectEventType, Set<WalletConnectEventCallback>> = new Map();\n private modal: Modal | null = null;\n private wsTransport: WsTransport | null = null;\n private pollingTransport: PollingTransport | null = null;\n private currentResult: ConnectResult | null = null;\n\n constructor(config: WalletConnectConfig) {\n this.config = {\n appId: config.appId,\n registryUrl: config.registryUrl || DEFAULT_REGISTRY_URL,\n walletId: config.walletId,\n theme: config.theme || 'light',\n };\n\n this.restoreSession();\n this.registerGlobal();\n }\n\n // ── Public API ──\n\n async connect(): Promise<ConnectResult> {\n if (this.currentResult) {\n return this.currentResult;\n }\n\n const wallets = await this.fetchWallets();\n const filtered = this.filterWallets(wallets);\n\n if (filtered.length === 0) {\n throw new Error('No supported wallets available');\n }\n\n return new Promise<ConnectResult>((resolve, reject) => {\n const onClose = () => {\n this.cleanup();\n reject(new Error('User closed modal'));\n };\n\n this.modal = new Modal(this.config.theme, onClose);\n\n if (filtered.length === 1) {\n this.startConnect(filtered[0], false, resolve, reject);\n } else {\n this.modal.showWalletPicker(filtered, (wallet) => {\n this.startConnect(wallet, true, resolve, reject);\n });\n }\n });\n }\n\n disconnect(): void {\n // Find session from this instance or any other connected instance\n let session = this.currentResult?.session;\n if (!session && typeof window !== 'undefined') {\n for (const key of Object.keys(window)) {\n const inst = (window as any)[key];\n if (inst instanceof BaseWalletConnect && inst.currentResult?.session) {\n session = inst.currentResult.session;\n break;\n }\n }\n }\n\n // Call disconnect API (fire-and-forget)\n if (session) {\n const baseUrl = session.apiUrl.replace(/\\/$/, '');\n fetch(`${baseUrl}/connect/disconnect-by-token`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ sessionToken: session.sessionToken }),\n }).catch(() => {});\n }\n\n // Clear all localStorage keys and window instances\n this.currentResult = null;\n this.removeStoredSession();\n this.clearAllRelatedSessions();\n this.cleanup();\n this.emit('disconnect');\n }\n\n isConnected(): boolean {\n return this.currentResult !== null;\n }\n\n getWallet(): ConnectResult | null {\n return this.currentResult;\n }\n\n on(event: WalletConnectEventType, cb: WalletConnectEventCallback): void {\n if (!this.listeners.has(event)) {\n this.listeners.set(event, new Set());\n }\n this.listeners.get(event)!.add(cb);\n }\n\n off(event: WalletConnectEventType, cb: WalletConnectEventCallback): void {\n this.listeners.get(event)?.delete(cb);\n }\n\n // ── Internal ──\n\n private get storageKey(): string {\n const walletId = this.config.walletId;\n const suffix = Array.isArray(walletId)\n ? walletId.sort().join('_')\n : walletId || 'all';\n return `${STORAGE_KEY_PREFIX}${suffix}__`;\n }\n\n private async fetchWallets(): Promise<WalletMeta[]> {\n const url = this.config.registryUrl.replace(/\\/$/, '');\n const res = await fetch(url);\n if (!res.ok) throw new Error('Failed to fetch wallets');\n return res.json();\n }\n\n private filterWallets(wallets: WalletMeta[]): WalletMeta[] {\n if (!this.config.walletId) return wallets;\n\n const ids = Array.isArray(this.config.walletId)\n ? this.config.walletId\n : [this.config.walletId];\n\n return wallets.filter((w) => ids.includes(w.walletId));\n }\n\n private async startConnect(\n wallet: WalletMeta,\n showBack: boolean,\n resolve: (result: ConnectResult) => void,\n reject: (error: Error) => void,\n ): Promise<void> {\n try {\n const session = await this.initSession(wallet);\n\n this.modal?.showConnect(wallet, session.deeplink, showBack, () => {\n this.cleanup();\n this.connect().then(resolve).catch(reject);\n });\n\n this.listenForConfirmation(\n wallet.apiUrl,\n session.sessionToken,\n (result) => {\n // Attach session info for disconnect\n result.session = {\n sessionToken: session.sessionToken,\n walletId: wallet.walletId,\n apiUrl: wallet.apiUrl,\n };\n this.currentResult = result;\n this.storeSession(result);\n this.syncToWalletInstance(wallet.walletId, result);\n this.emit('connect', result);\n\n // Show success screen\n this.modal?.showSuccess(\n wallet,\n result.wallet?.address || null,\n result.user || null,\n () => {\n this.modal?.destroy();\n this.modal = null;\n resolve(result);\n },\n );\n },\n () => {\n this.modal?.updateStatus('Connection rejected', false);\n setTimeout(() => {\n this.modal?.destroy();\n this.modal = null;\n reject(new Error('Connection rejected by user'));\n }, 1500);\n },\n () => {\n this.modal?.updateStatus('Session expired', false);\n this.emit('session_expired');\n setTimeout(() => {\n this.modal?.destroy();\n this.modal = null;\n reject(new Error('Session expired'));\n }, 1500);\n },\n );\n } catch (err) {\n this.modal?.destroy();\n this.modal = null;\n reject(err instanceof Error ? err : new Error(String(err)));\n }\n }\n\n private async initSession(wallet: WalletMeta): Promise<InitSessionResponse> {\n const baseUrl = wallet.apiUrl.replace(/\\/$/, '');\n const res = await fetch(`${baseUrl}/connect/init`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n appId: this.config.appId,\n walletId: wallet.walletId,\n origin: typeof window !== 'undefined' ? window.location.origin : '',\n }),\n });\n if (!res.ok) throw new Error('Failed to init session');\n return res.json();\n }\n\n private listenForConfirmation(\n apiUrl: string,\n sessionToken: string,\n onConfirmed: (result: ConnectResult) => void,\n onRejected: () => void,\n onExpired: () => void,\n ): void {\n let resolved = false;\n\n const wrap = <T extends (...args: any[]) => void>(fn: T): T =>\n ((...args: any[]) => {\n if (resolved) return;\n resolved = true;\n this.wsTransport?.close();\n this.pollingTransport?.stop();\n fn(...args);\n }) as unknown as T;\n\n const wrappedConfirm = wrap(onConfirmed);\n const wrappedReject = wrap(onRejected);\n const wrappedExpire = wrap(onExpired);\n\n // Start polling immediately as primary transport\n this.pollingTransport = new PollingTransport(\n apiUrl,\n sessionToken,\n wrappedConfirm,\n wrappedReject,\n wrappedExpire,\n (msg) => this.emit('error', msg),\n );\n this.pollingTransport.start();\n\n // Also try WS for faster response\n this.wsTransport = new WsTransport(\n apiUrl,\n sessionToken,\n wrappedConfirm,\n wrappedReject,\n wrappedExpire,\n () => {}, // WS fail is fine, polling is running\n );\n this.wsTransport.connect();\n }\n\n private cleanup(): void {\n this.wsTransport?.close();\n this.wsTransport = null;\n this.pollingTransport?.stop();\n this.pollingTransport = null;\n this.modal?.destroy();\n this.modal = null;\n }\n\n private emit(event: WalletConnectEventType, data?: any): void {\n this.listeners.get(event)?.forEach((cb) => cb(data));\n }\n\n // ── Persistence ──\n\n private storeSession(result: ConnectResult): void {\n try {\n localStorage.setItem(this.storageKey, JSON.stringify(result));\n } catch {\n // localStorage unavailable\n }\n }\n\n private restoreSession(): void {\n try {\n const stored = localStorage.getItem(this.storageKey);\n if (stored) {\n this.currentResult = JSON.parse(stored);\n }\n } catch {\n // ignore\n }\n }\n\n private removeStoredSession(): void {\n try {\n localStorage.removeItem(this.storageKey);\n } catch {\n // ignore\n }\n }\n\n // ── Global window registration ──\n\n private registerGlobal(): void {\n if (typeof window === 'undefined') return;\n\n const walletId = this.config.walletId;\n const key = Array.isArray(walletId)\n ? walletId[0]\n : walletId || 'walletconnect';\n\n (window as any)[key] = this;\n }\n\n /** Sync connect result to the specific wallet instance on window (e.g. window.onedollar) */\n private syncToWalletInstance(walletId: string, result: ConnectResult): void {\n if (typeof window === 'undefined') return;\n\n const target = (window as any)[walletId];\n if (target && target !== this && target instanceof BaseWalletConnect) {\n (target as any).currentResult = result;\n (target as any).storeSession(result);\n }\n }\n\n /** Clear all related sessions from all window instances and localStorage */\n private clearAllRelatedSessions(): void {\n if (typeof window === 'undefined') return;\n\n // Find all BaseWalletConnect instances on window and clear them\n try {\n for (const key of Object.keys(window)) {\n const inst = (window as any)[key];\n if (inst && inst !== this && inst instanceof BaseWalletConnect) {\n (inst as any).currentResult = null;\n (inst as any).removeStoredSession();\n }\n }\n } catch {\n // ignore\n }\n\n // Clear all wc localStorage keys\n try {\n const toRemove: string[] = [];\n for (let i = 0; i < localStorage.length; i++) {\n const k = localStorage.key(i);\n if (k && k.startsWith(STORAGE_KEY_PREFIX)) {\n toRemove.push(k);\n }\n }\n toRemove.forEach((k) => localStorage.removeItem(k));\n } catch {\n // ignore\n }\n }\n}\n","import { BaseWalletConnect } from './client';\nimport type { WalletConnectConfig } from './types';\n\nexport class OneDollarConnect extends BaseWalletConnect {\n constructor(config: Omit<WalletConnectConfig, 'walletId'>) {\n super({ ...config, walletId: 'onedollar' });\n }\n}\n","import { BaseWalletConnect } from './client';\nimport type { WalletConnectConfig } from './types';\n\nexport class TonPassConnect extends BaseWalletConnect {\n constructor(config: Omit<WalletConnectConfig, 'walletId'>) {\n super({ ...config, walletId: 'tonpass' });\n }\n}\n"],"names":["WsTransport","constructor","apiUrl","sessionToken","onConfirmed","onRejected","onExpired","onError","this","ws","reconnectTimer","closed","connect","replace","connectSocketIO","baseUrl","fetch","then","res","text","body","jsonStr","sid","JSON","parse","wsUrl","WebSocket","onopen","send","onmessage","event","msg","data","startsWith","payload","slice","eventName","handleEvent","onclose","scheduleReconnect","onerror","catch","close","setTimeout","clearTimeout","PollingTransport","timer","stopped","start","poll","setInterval","ok","json","status","wallet","user","stop","clearInterval","MODAL_ID","Modal","theme","onClose","overlay","showWalletPicker","wallets","onSelect","html","length","map","w","walletId","icon","name","charAt","join","description","render","forEach","querySelector","addEventListener","showConnect","deeplink","showBack","onBack","qrUrl","size","encodeURIComponent","generateQRDataUrl","tabs","querySelectorAll","panels","tab","target","dataset","t","classList","remove","add","p","style","display","panel","showSuccess","address","onDone","displayName","username","initials","toUpperCase","avatar","updateStatus","showSpinner","el","innerHTML","innerHtml","destroy","document","createElement","id","isDark","bg","bgSecondary","textSecondary","border","accent","accentDark","getStyles","appendChild","e","contains","getElementById","STORAGE_KEY_PREFIX","BaseWalletConnect","config","listeners","Map","modal","wsTransport","pollingTransport","currentResult","appId","registryUrl","restoreSession","registerGlobal","fetchWallets","filtered","filterWallets","Error","Promise","resolve","reject","cleanup","startConnect","disconnect","session","window","key","Object","keys","inst","method","headers","stringify","removeStoredSession","clearAllRelatedSessions","emit","isConnected","getWallet","on","cb","has","set","Set","get","off","delete","storageKey","suffix","Array","isArray","sort","url","ids","filter","includes","initSession","listenForConfirmation","result","storeSession","syncToWalletInstance","err","String","origin","location","resolved","wrap","fn","args","wrappedConfirm","wrappedReject","wrappedExpire","localStorage","setItem","stored","getItem","removeItem","toRemove","i","k","push","super"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "toncorp-wallet-connect-sdk",
3
- "version": "0.1.4",
3
+ "version": "0.1.5",
4
4
  "description": "Wallet Connect SDK — connect TonPass, OneDollar and more wallets from any DApp",
5
5
  "author": "PlaygroundVina",
6
6
  "license": "MIT",