toncorp-wallet-connect-sdk 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +55 -71
- package/dist/client.d.ts +5 -0
- package/dist/index.cjs.js +1 -1
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.esm.js +1 -1
- package/dist/index.esm.js.map +1 -1
- package/dist/index.umd.js +1 -1
- package/dist/index.umd.js.map +1 -1
- package/dist/modal.d.ts +4 -0
- package/dist/types.d.ts +10 -4
- package/package.json +2 -1
- package/registry.json +12 -0
package/README.md
CHANGED
|
@@ -8,6 +8,12 @@ Connect TonPass, OneDollar and more wallets from any DApp or website.
|
|
|
8
8
|
npm install toncorp-wallet-connect-sdk
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
+
Or via CDN:
|
|
12
|
+
|
|
13
|
+
```html
|
|
14
|
+
<script src="https://cdn.jsdelivr.net/npm/toncorp-wallet-connect-sdk@latest/dist/index.umd.js"></script>
|
|
15
|
+
```
|
|
16
|
+
|
|
11
17
|
## Usage
|
|
12
18
|
|
|
13
19
|
### Specific wallet
|
|
@@ -15,25 +21,26 @@ npm install toncorp-wallet-connect-sdk
|
|
|
15
21
|
```typescript
|
|
16
22
|
import { TonPassConnect } from 'toncorp-wallet-connect-sdk';
|
|
17
23
|
|
|
18
|
-
const wallet = new TonPassConnect({
|
|
19
|
-
appId: 'your_app_id',
|
|
20
|
-
registryUrl: 'https://api.example.com/connect/wallets',
|
|
21
|
-
});
|
|
24
|
+
const wallet = new TonPassConnect({ appId: 'your_app_id' });
|
|
22
25
|
|
|
23
26
|
const result = await wallet.connect();
|
|
24
|
-
console.log(result.
|
|
27
|
+
console.log(result.wallet); // { address: 'UQ...', chain: 'TON' }
|
|
25
28
|
console.log(result.user); // { username: 'john', avatar: '...' }
|
|
29
|
+
|
|
30
|
+
// Access via window global
|
|
31
|
+
window.tonpass.isConnected() // true
|
|
32
|
+
window.tonpass.getWallet() // same result
|
|
26
33
|
```
|
|
27
34
|
|
|
28
35
|
```typescript
|
|
29
36
|
import { OneDollarConnect } from 'toncorp-wallet-connect-sdk';
|
|
30
37
|
|
|
31
|
-
const wallet = new OneDollarConnect({
|
|
32
|
-
appId: 'your_app_id',
|
|
33
|
-
registryUrl: 'https://api.example.com/connect/wallets',
|
|
34
|
-
});
|
|
35
|
-
|
|
38
|
+
const wallet = new OneDollarConnect({ appId: 'your_app_id' });
|
|
36
39
|
const result = await wallet.connect();
|
|
40
|
+
|
|
41
|
+
// Access via window global
|
|
42
|
+
window.onedollar.isConnected()
|
|
43
|
+
window.onedollar.getWallet()
|
|
37
44
|
```
|
|
38
45
|
|
|
39
46
|
### All wallets (show picker)
|
|
@@ -43,7 +50,6 @@ import { BaseWalletConnect } from 'toncorp-wallet-connect-sdk';
|
|
|
43
50
|
|
|
44
51
|
const wallet = new BaseWalletConnect({
|
|
45
52
|
appId: 'your_app_id',
|
|
46
|
-
registryUrl: 'https://api.example.com/connect/wallets',
|
|
47
53
|
// walletId: ['tonpass', 'onedollar'], // optional filter
|
|
48
54
|
});
|
|
49
55
|
|
|
@@ -53,17 +59,21 @@ const result = await wallet.connect();
|
|
|
53
59
|
### Script tag (UMD)
|
|
54
60
|
|
|
55
61
|
```html
|
|
56
|
-
<script src="https://
|
|
62
|
+
<script src="https://cdn.jsdelivr.net/npm/toncorp-wallet-connect-sdk@latest/dist/index.umd.js"></script>
|
|
57
63
|
<script>
|
|
58
|
-
const wallet = new WalletConnectSDK.
|
|
64
|
+
const wallet = new WalletConnectSDK.OneDollarConnect({
|
|
59
65
|
appId: 'your_app_id',
|
|
60
|
-
registryUrl: 'https://api.example.com/connect/wallets',
|
|
61
66
|
});
|
|
62
67
|
|
|
63
68
|
document.getElementById('connect-btn').onclick = async () => {
|
|
64
69
|
const result = await wallet.connect();
|
|
65
70
|
console.log(result);
|
|
66
71
|
};
|
|
72
|
+
|
|
73
|
+
// Available globally after instantiation
|
|
74
|
+
// window.onedollar.isConnected()
|
|
75
|
+
// window.onedollar.getWallet()
|
|
76
|
+
// window.onedollar.disconnect()
|
|
67
77
|
</script>
|
|
68
78
|
```
|
|
69
79
|
|
|
@@ -74,7 +84,7 @@ const result = await wallet.connect();
|
|
|
74
84
|
| Option | Type | Required | Description |
|
|
75
85
|
|--------|------|----------|-------------|
|
|
76
86
|
| `appId` | `string` | Yes | Your registered app ID |
|
|
77
|
-
| `registryUrl` | `string` |
|
|
87
|
+
| `registryUrl` | `string` | No | Override wallet registry URL (defaults to CDN) |
|
|
78
88
|
| `walletId` | `string \| string[]` | No | Filter wallets (only for `BaseWalletConnect`) |
|
|
79
89
|
| `theme` | `'light' \| 'dark'` | No | Modal theme (default: `light`) |
|
|
80
90
|
|
|
@@ -83,76 +93,50 @@ const result = await wallet.connect();
|
|
|
83
93
|
| Method | Returns | Description |
|
|
84
94
|
|--------|---------|-------------|
|
|
85
95
|
| `connect()` | `Promise<ConnectResult>` | Open modal and wait for user to approve |
|
|
86
|
-
| `disconnect()` | `void` | Disconnect
|
|
96
|
+
| `disconnect()` | `void` | Disconnect, clear session and call API |
|
|
87
97
|
| `isConnected()` | `boolean` | Check connection status |
|
|
88
98
|
| `getWallet()` | `ConnectResult \| null` | Get current connection info |
|
|
89
99
|
| `on(event, cb)` | `void` | Listen to events |
|
|
90
100
|
| `off(event, cb)` | `void` | Remove listener |
|
|
91
101
|
|
|
102
|
+
### ConnectResult
|
|
103
|
+
|
|
104
|
+
```typescript
|
|
105
|
+
{
|
|
106
|
+
wallet: {
|
|
107
|
+
address: string; // friendly TON address
|
|
108
|
+
chain: string; // 'TON'
|
|
109
|
+
} | null;
|
|
110
|
+
user: {
|
|
111
|
+
username?: string;
|
|
112
|
+
avatar?: string;
|
|
113
|
+
};
|
|
114
|
+
session?: {
|
|
115
|
+
sessionToken: string;
|
|
116
|
+
walletId: string;
|
|
117
|
+
apiUrl: string;
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
```
|
|
121
|
+
|
|
92
122
|
### Events
|
|
93
123
|
|
|
94
124
|
| Event | Data | Description |
|
|
95
125
|
|-------|------|-------------|
|
|
96
126
|
| `connect` | `ConnectResult` | Connected successfully |
|
|
97
|
-
| `disconnect` |
|
|
127
|
+
| `disconnect` | - | Disconnected |
|
|
98
128
|
| `error` | `string` | Transport error |
|
|
99
|
-
| `session_expired` |
|
|
100
|
-
|
|
101
|
-
## Publish to npm
|
|
102
|
-
|
|
103
|
-
### Prerequisites
|
|
129
|
+
| `session_expired` | - | Session timed out |
|
|
104
130
|
|
|
105
|
-
|
|
106
|
-
# Login to npm (one-time)
|
|
107
|
-
npm login
|
|
108
|
-
|
|
109
|
-
# If using scoped package (@aspect-wallet), make sure the org exists on npmjs.com
|
|
110
|
-
# Or change the name in package.json to an unscoped name
|
|
111
|
-
```
|
|
112
|
-
|
|
113
|
-
### Build & Publish
|
|
114
|
-
|
|
115
|
-
```bash
|
|
116
|
-
# Navigate to SDK folder
|
|
117
|
-
cd src/blockchain/walletconnect/sdk
|
|
118
|
-
|
|
119
|
-
# Install build dependencies
|
|
120
|
-
npm install
|
|
121
|
-
|
|
122
|
-
# Build (outputs to dist/)
|
|
123
|
-
npm run build
|
|
124
|
-
|
|
125
|
-
# Check what will be published
|
|
126
|
-
npm pack --dry-run
|
|
127
|
-
|
|
128
|
-
# Publish (first time — scoped packages default to private)
|
|
129
|
-
npm publish --access public
|
|
131
|
+
### Window globals
|
|
130
132
|
|
|
131
|
-
|
|
132
|
-
# 1. Bump version first:
|
|
133
|
-
npm version patch # 0.1.0 → 0.1.1 (bug fixes)
|
|
134
|
-
npm version minor # 0.1.1 → 0.2.0 (new features)
|
|
135
|
-
npm version major # 0.2.0 → 1.0.0 (breaking changes)
|
|
136
|
-
# 2. Then publish:
|
|
137
|
-
npm publish --access public
|
|
138
|
-
```
|
|
139
|
-
|
|
140
|
-
### Verify
|
|
141
|
-
|
|
142
|
-
```bash
|
|
143
|
-
# Check the published package
|
|
144
|
-
npm info toncorp-wallet-connect-sdk
|
|
145
|
-
|
|
146
|
-
# Install in another project to test
|
|
147
|
-
npm install toncorp-wallet-connect-sdk
|
|
148
|
-
```
|
|
149
|
-
|
|
150
|
-
### CDN (auto-available after publish)
|
|
133
|
+
Each wallet instance auto-registers on `window`:
|
|
151
134
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
135
|
+
| Class | Window global |
|
|
136
|
+
|-------|--------------|
|
|
137
|
+
| `TonPassConnect` | `window.tonpass` |
|
|
138
|
+
| `OneDollarConnect` | `window.onedollar` |
|
|
139
|
+
| `BaseWalletConnect` | `window.walletconnect` |
|
|
156
140
|
|
|
157
141
|
## License
|
|
158
142
|
|
package/dist/client.d.ts
CHANGED
|
@@ -24,4 +24,9 @@ export declare class BaseWalletConnect {
|
|
|
24
24
|
private storeSession;
|
|
25
25
|
private restoreSession;
|
|
26
26
|
private removeStoredSession;
|
|
27
|
+
private registerGlobal;
|
|
28
|
+
/** Sync connect result to the specific wallet instance on window (e.g. window.onedollar) */
|
|
29
|
+
private syncToWalletInstance;
|
|
30
|
+
/** Clear all related sessions from window instances and localStorage */
|
|
31
|
+
private clearAllRelatedSessions;
|
|
27
32
|
}
|
package/dist/index.cjs.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";class e{constructor(e,t,n,s,i,o){this.apiUrl=e,this.sessionToken=t,this.onConfirmed=n,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(t=>{const n=t.replace(/^\d+/,""),s=JSON.parse(n).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 t=e.data;if("3probe"!==t)if(t.startsWith("42"))try{const e=JSON.parse(t.slice(2)),[n,s]=e;this.handleEvent(n,s)}catch{}else"2"===t&&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,t){switch(e){case"session_confirmed":this.onConfirmed(t),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,t,n,s,i,o){this.apiUrl=e,this.sessionToken=t,this.onConfirmed=n,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(/\/$/,""),t=await fetch(`${e}/connect/status?token=${this.sessionToken}`);if(!t.ok)return;const n=await t.json();switch(n.status){case"CONFIRMED":this.onConfirmed({wallets:n.wallets,user:n.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 n="__wc_modal__";class s{constructor(e,t){this.overlay=null,this.theme=e,this.onClose=t}showWalletPicker(e,t){const n=`\n <div class="wc-header">\n <h3 class="wc-title">Connect Wallet</h3>\n <button class="wc-close" data-action="close">×</button>\n </div>\n <div class="wc-body">\n <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-icon" src="${e.icon}" alt="${e.name}" />`:`<div class="wc-wallet-icon-placeholder">${e.name.charAt(0).toUpperCase()}</div>`}\n <div>\n <div class="wc-wallet-name">${e.name}</div>\n ${e.description?`<div class="wc-wallet-desc">${e.description}</div>`:""}\n </div>\n </li>`).join("")}</ul>\n </div>\n `;this.render(n),e.forEach(e=>{const n=this.overlay?.querySelector(`[data-wallet-id="${e.walletId}"]`);n?.addEventListener("click",()=>t(e))})}showConnect(e,t,n,s){const i=function(e,t=200){return`https://api.qrserver.com/v1/create-qr-code/?size=${t}x${t}&data=${encodeURIComponent(e)}`}(t),o=`\n <div class="wc-header">\n <div style="display:flex;align-items:center;gap:8px;">\n ${n?'<button class="wc-back" data-action="back">←</button>':""}\n <h3 class="wc-title">Connect ${e.name}</h3>\n </div>\n <button class="wc-close" data-action="close">×</button>\n </div>\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="${t}" target="_blank">\n Open in Telegram\n </a>\n </div>\n <div data-panel="qr" style="display:none;">\n <div class="wc-qr-container">\n <img class="wc-qr-canvas" src="${i}" width="200" height="200" alt="QR Code" />\n <div class="wc-qr-hint">Scan with your phone or from 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 `;this.render(o);const r=this.overlay?.querySelectorAll(".wc-tab"),a=this.overlay?.querySelectorAll("[data-panel]");r?.forEach(e=>{e.addEventListener("click",()=>{const t=e.dataset.tab;r.forEach(e=>e.classList.remove("active")),e.classList.add("active"),a?.forEach(e=>{e.style.display=e.dataset.panel===t?"block":"none"})})}),n&&s&&this.overlay?.querySelector('[data-action="back"]')?.addEventListener("click",s)}updateStatus(e,t=!0){const n=this.overlay?.querySelector(".wc-status");n&&(n.innerHTML=`\n ${t?'<div class="wc-spinner"></div>':""}\n <span>${e}</span>\n `)}render(e){this.destroy();const t=document.createElement("div");t.id=n,t.innerHTML=`\n <style>${function(e){const t="dark"===e?"#16213e":"#f5f5f5",n="dark"===e?"#a0a0a0":"#666666",s="dark"===e?"#2a2a4a":"#e0e0e0",i="#3b82f6";return`\n .wc-overlay {\n position: fixed; inset: 0; z-index: 99999;\n background: rgba(0,0,0,0.5); display: flex;\n align-items: center; justify-content: center;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n }\n .wc-modal {\n background: ${"dark"===e?"#1a1a2e":"#ffffff"}; border-radius: 16px; width: 380px;\n max-width: 90vw; box-shadow: 0 20px 60px rgba(0,0,0,0.3);\n overflow: hidden; color: ${"dark"===e?"#e0e0e0":"#1a1a1a"};\n }\n .wc-header {\n display: flex; align-items: center; justify-content: space-between;\n padding: 20px 24px 16px; border-bottom: 1px solid ${s};\n }\n .wc-title { font-size: 18px; font-weight: 600; margin: 0; }\n .wc-close {\n background: none; border: none; cursor: pointer;\n font-size: 20px; color: ${n}; padding: 4px 8px;\n border-radius: 8px;\n }\n .wc-close:hover { background: ${t}; }\n .wc-body { padding: 16px 24px 24px; }\n .wc-wallet-list { list-style: none; margin: 0; padding: 0; }\n .wc-wallet-item {\n display: flex; align-items: center; gap: 12px;\n padding: 12px 16px; border-radius: 12px; cursor: pointer;\n border: 1px solid ${s}; margin-bottom: 8px;\n transition: background 0.15s;\n }\n .wc-wallet-item:hover { background: ${"dark"===e?"#0f3460":"#e8f0fe"}; }\n .wc-wallet-icon {\n width: 40px; height: 40px; border-radius: 10px;\n object-fit: cover; flex-shrink: 0;\n }\n .wc-wallet-icon-placeholder {\n width: 40px; height: 40px; border-radius: 10px;\n background: ${i}; display: flex; align-items: center;\n justify-content: center; color: #fff; font-weight: 700;\n font-size: 16px; flex-shrink: 0;\n }\n .wc-wallet-name { font-size: 15px; font-weight: 500; }\n .wc-wallet-desc { font-size: 12px; color: ${n}; margin-top: 2px; }\n\n /* Connect screen (after wallet selected) */\n .wc-tabs {\n display: flex; gap: 0; margin-bottom: 20px;\n border: 1px solid ${s}; border-radius: 10px; overflow: hidden;\n }\n .wc-tab {\n flex: 1; padding: 10px; text-align: center; cursor: pointer;\n font-size: 13px; font-weight: 500; background: ${t};\n border: none; color: ${n}; transition: all 0.15s;\n }\n .wc-tab.active { background: ${i}; color: #fff; }\n .wc-deeplink-btn {\n display: block; width: 100%; padding: 14px; border: none;\n border-radius: 12px; background: ${i}; color: #fff;\n font-size: 15px; font-weight: 600; cursor: pointer;\n text-align: center; text-decoration: none;\n }\n .wc-deeplink-btn:hover { opacity: 0.9; }\n .wc-qr-container {\n display: flex; flex-direction: column; align-items: center; gap: 12px;\n }\n .wc-qr-canvas {\n border-radius: 12px; padding: 16px; background: #fff;\n }\n .wc-qr-hint { font-size: 12px; color: ${n}; text-align: center; }\n .wc-status {\n display: flex; align-items: center; justify-content: center;\n gap: 8px; padding: 16px 0 0; font-size: 13px; color: ${n};\n }\n .wc-spinner {\n width: 16px; height: 16px; border: 2px solid ${s};\n border-top-color: ${i}; border-radius: 50%;\n animation: wc-spin 0.8s linear infinite;\n }\n @keyframes wc-spin { to { transform: rotate(360deg); } }\n .wc-back {\n background: none; border: none; cursor: pointer;\n font-size: 14px; color: ${i}; padding: 0;\n display: flex; align-items: center; gap: 4px;\n }\n .wc-back:hover { text-decoration: underline; }\n `}(this.theme)}</style>\n <div class="wc-overlay">\n <div class="wc-modal">${e}</div>\n </div>\n `,document.body.appendChild(t),this.overlay=t,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(){const e=document.getElementById(n);e&&e.remove(),this.overlay=null}}class i{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,walletId:e.walletId,theme:e.theme||"light"},this.restoreSession()}async connect(){if(this.currentResult)return this.currentResult;const e=await this.fetchWallets(),t=this.filterWallets(e);if(0===t.length)throw new Error("No supported wallets available");return new Promise((e,n)=>{this.modal=new s(this.config.theme,()=>{this.cleanup(),n(new Error("User closed modal"))}),1===t.length?this.startConnect(t[0],!1,e,n):this.modal.showWalletPicker(t,t=>{this.startConnect(t,!0,e,n)})})}disconnect(){this.currentResult=null,this.removeStoredSession(),this.cleanup(),this.emit("disconnect")}isConnected(){return null!==this.currentResult}getWallet(){return this.currentResult}on(e,t){this.listeners.has(e)||this.listeners.set(e,new Set),this.listeners.get(e).add(t)}off(e,t){this.listeners.get(e)?.delete(t)}get storageKey(){const e=this.config.walletId;return`__wc_session_${Array.isArray(e)?e.sort().join("_"):e||"all"}__`}async fetchWallets(){const e=this.config.registryUrl.replace(/\/$/,""),t=await fetch(e);if(!t.ok)throw new Error("Failed to fetch wallets");return t.json()}filterWallets(e){if(!this.config.walletId)return e;const t=Array.isArray(this.config.walletId)?this.config.walletId:[this.config.walletId];return e.filter(e=>t.includes(e.walletId))}async startConnect(e,t,n,s){try{const i=await this.initSession(e);this.modal?.showConnect(e,i.deeplink,t,()=>{this.cleanup(),this.connect().then(n).catch(s)}),this.listenForConfirmation(e.apiUrl,i.sessionToken,e=>{this.currentResult=e,this.storeSession(e),this.modal?.destroy(),this.modal=null,this.emit("connect",e),n(e)},()=>{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 t=e.apiUrl.replace(/\/$/,""),n=await fetch(`${t}/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(!n.ok)throw new Error("Failed to init session");return n.json()}listenForConfirmation(n,s,i,o,r){this.wsTransport=new e(n,s,i,o,r,()=>{this.pollingTransport=new t(n,s,i,o,r,e=>this.emit("error",e)),this.pollingTransport.start()}),this.wsTransport.connect()}cleanup(){this.wsTransport?.close(),this.wsTransport=null,this.pollingTransport?.stop(),this.pollingTransport=null,this.modal?.destroy(),this.modal=null}emit(e,t){this.listeners.get(e)?.forEach(e=>e(t))}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{}}}exports.BaseWalletConnect=i,exports.OneDollarConnect=class extends i{constructor(e){super({...e,walletId:"onedollar"})}},exports.TonPassConnect=class extends i{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">✕</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">›</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">←</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">✕</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">✕</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"})}};
|
|
2
2
|
//# sourceMappingURL=index.cjs.js.map
|
package/dist/index.cjs.js.map
CHANGED
|
@@ -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({ wallets: data.wallets, 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\n// ── Styles (scoped, no conflict with host) ──\n\nfunction getStyles(theme: 'light' | 'dark'): string {\n const bg = theme === 'dark' ? '#1a1a2e' : '#ffffff';\n const bgSecondary = theme === 'dark' ? '#16213e' : '#f5f5f5';\n const text = theme === 'dark' ? '#e0e0e0' : '#1a1a1a';\n const textSecondary = theme === 'dark' ? '#a0a0a0' : '#666666';\n const border = theme === 'dark' ? '#2a2a4a' : '#e0e0e0';\n const primary = '#3b82f6';\n const hover = theme === 'dark' ? '#0f3460' : '#e8f0fe';\n\n return `\n .wc-overlay {\n position: fixed; inset: 0; z-index: 99999;\n background: rgba(0,0,0,0.5); display: flex;\n align-items: center; justify-content: center;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n }\n .wc-modal {\n background: ${bg}; border-radius: 16px; width: 380px;\n max-width: 90vw; box-shadow: 0 20px 60px rgba(0,0,0,0.3);\n overflow: hidden; color: ${text};\n }\n .wc-header {\n display: flex; align-items: center; justify-content: space-between;\n padding: 20px 24px 16px; border-bottom: 1px solid ${border};\n }\n .wc-title { font-size: 18px; font-weight: 600; margin: 0; }\n .wc-close {\n background: none; border: none; cursor: pointer;\n font-size: 20px; color: ${textSecondary}; padding: 4px 8px;\n border-radius: 8px;\n }\n .wc-close:hover { background: ${bgSecondary}; }\n .wc-body { padding: 16px 24px 24px; }\n .wc-wallet-list { list-style: none; margin: 0; padding: 0; }\n .wc-wallet-item {\n display: flex; align-items: center; gap: 12px;\n padding: 12px 16px; border-radius: 12px; cursor: pointer;\n border: 1px solid ${border}; margin-bottom: 8px;\n transition: background 0.15s;\n }\n .wc-wallet-item:hover { background: ${hover}; }\n .wc-wallet-icon {\n width: 40px; height: 40px; border-radius: 10px;\n object-fit: cover; flex-shrink: 0;\n }\n .wc-wallet-icon-placeholder {\n width: 40px; height: 40px; border-radius: 10px;\n background: ${primary}; display: flex; align-items: center;\n justify-content: center; color: #fff; font-weight: 700;\n font-size: 16px; flex-shrink: 0;\n }\n .wc-wallet-name { font-size: 15px; font-weight: 500; }\n .wc-wallet-desc { font-size: 12px; color: ${textSecondary}; margin-top: 2px; }\n\n /* Connect screen (after wallet selected) */\n .wc-tabs {\n display: flex; gap: 0; margin-bottom: 20px;\n border: 1px solid ${border}; border-radius: 10px; overflow: hidden;\n }\n .wc-tab {\n flex: 1; padding: 10px; text-align: center; cursor: pointer;\n font-size: 13px; font-weight: 500; background: ${bgSecondary};\n border: none; color: ${textSecondary}; transition: all 0.15s;\n }\n .wc-tab.active { background: ${primary}; color: #fff; }\n .wc-deeplink-btn {\n display: block; width: 100%; padding: 14px; border: none;\n border-radius: 12px; background: ${primary}; color: #fff;\n font-size: 15px; font-weight: 600; cursor: pointer;\n text-align: center; text-decoration: none;\n }\n .wc-deeplink-btn:hover { opacity: 0.9; }\n .wc-qr-container {\n display: flex; flex-direction: column; align-items: center; gap: 12px;\n }\n .wc-qr-canvas {\n border-radius: 12px; padding: 16px; background: #fff;\n }\n .wc-qr-hint { font-size: 12px; color: ${textSecondary}; text-align: center; }\n .wc-status {\n display: flex; align-items: center; justify-content: center;\n gap: 8px; padding: 16px 0 0; font-size: 13px; color: ${textSecondary};\n }\n .wc-spinner {\n width: 16px; height: 16px; border: 2px solid ${border};\n border-top-color: ${primary}; border-radius: 50%;\n animation: wc-spin 0.8s linear infinite;\n }\n @keyframes wc-spin { to { transform: rotate(360deg); } }\n .wc-back {\n background: none; border: none; cursor: pointer;\n font-size: 14px; color: ${primary}; padding: 0;\n display: flex; align-items: center; gap: 4px;\n }\n .wc-back:hover { text-decoration: underline; }\n `;\n}\n\n// ── QR Code (minimal inline generator, no external dep) ──\n\nfunction generateQRDataUrl(text: string, size = 200): string {\n // Encode as a simple QR placeholder using a public API\n // In production, replace with a bundled QR lib like 'qrcode'\n return `https://api.qrserver.com/v1/create-qr-code/?size=${size}x${size}&data=${encodeURIComponent(text)}`;\n}\n\n// ── Modal builder ──\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 // Show wallet picker (multiple wallets)\n showWalletPicker(\n wallets: WalletMeta[],\n onSelect: (wallet: WalletMeta) => void,\n ): void {\n const walletListHtml = 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-icon\" src=\"${w.icon}\" alt=\"${w.name}\" />`\n : `<div class=\"wc-wallet-icon-placeholder\">${w.name.charAt(0).toUpperCase()}</div>`\n }\n <div>\n <div class=\"wc-wallet-name\">${w.name}</div>\n ${w.description ? `<div class=\"wc-wallet-desc\">${w.description}</div>` : ''}\n </div>\n </li>`,\n )\n .join('');\n\n const html = `\n <div class=\"wc-header\">\n <h3 class=\"wc-title\">Connect Wallet</h3>\n <button class=\"wc-close\" data-action=\"close\">×</button>\n </div>\n <div class=\"wc-body\">\n <ul class=\"wc-wallet-list\">${walletListHtml}</ul>\n </div>\n `;\n\n this.render(html);\n\n // Bind wallet click\n wallets.forEach((w) => {\n const el = this.overlay?.querySelector(\n `[data-wallet-id=\"${w.walletId}\"]`,\n );\n el?.addEventListener('click', () => onSelect(w));\n });\n }\n\n // Show connect screen (deeplink + QR)\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-header\">\n <div style=\"display:flex;align-items:center;gap:8px;\">\n ${\n showBack\n ? '<button class=\"wc-back\" data-action=\"back\">←</button>'\n : ''\n }\n <h3 class=\"wc-title\">Connect ${wallet.name}</h3>\n </div>\n <button class=\"wc-close\" data-action=\"close\">×</button>\n </div>\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 Open in Telegram\n </a>\n </div>\n <div data-panel=\"qr\" style=\"display:none;\">\n <div class=\"wc-qr-container\">\n <img class=\"wc-qr-canvas\" src=\"${qrUrl}\" width=\"200\" height=\"200\" alt=\"QR Code\" />\n <div class=\"wc-qr-hint\">Scan with your phone or from 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 `;\n\n this.render(html);\n\n // Tab switching\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 // Back button\n if (showBack && onBack) {\n this.overlay\n ?.querySelector('[data-action=\"back\"]')\n ?.addEventListener('click', onBack);\n }\n }\n\n // Update status text\n updateStatus(text: string, showSpinner = true): void {\n const statusEl = this.overlay?.querySelector('.wc-status');\n if (statusEl) {\n statusEl.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 overlay = document.createElement('div');\n overlay.id = MODAL_ID;\n overlay.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(overlay);\n this.overlay = overlay;\n\n // Close button\n this.overlay\n .querySelector('[data-action=\"close\"]')\n ?.addEventListener('click', () => {\n this.onClose();\n this.destroy();\n });\n\n // Click overlay to close\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 const existing = document.getElementById(MODAL_ID);\n if (existing) {\n existing.remove();\n }\n this.overlay = null;\n }\n}\n","import type {\n WalletConnectConfig,\n WalletMeta,\n ConnectResult,\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_';\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,\n walletId: config.walletId,\n theme: config.theme || 'light',\n };\n\n this.restoreSession();\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 this.currentResult = null;\n this.removeStoredSession();\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 this.currentResult = result;\n this.storeSession(result);\n this.modal?.destroy();\n this.modal = null;\n this.emit('connect', result);\n resolve(result);\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 const onError = () => {\n this.pollingTransport = new PollingTransport(\n apiUrl,\n sessionToken,\n onConfirmed,\n onRejected,\n onExpired,\n (msg) => this.emit('error', msg),\n );\n this.pollingTransport.start();\n };\n\n this.wsTransport = new WsTransport(\n apiUrl,\n sessionToken,\n onConfirmed,\n onRejected,\n onExpired,\n onError,\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","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","wallets","user","stop","clearInterval","MODAL_ID","Modal","theme","onClose","overlay","showWalletPicker","onSelect","html","map","w","walletId","icon","name","charAt","toUpperCase","description","join","render","forEach","el","querySelector","addEventListener","showConnect","wallet","deeplink","showBack","onBack","qrUrl","size","encodeURIComponent","generateQRDataUrl","tabs","querySelectorAll","panels","tab","target","dataset","t","classList","remove","add","p","style","display","panel","updateStatus","showSpinner","statusEl","innerHTML","innerHtml","destroy","document","createElement","id","bgSecondary","textSecondary","border","primary","getStyles","appendChild","e","contains","existing","getElementById","BaseWalletConnect","config","listeners","Map","modal","wsTransport","pollingTransport","currentResult","appId","registryUrl","restoreSession","fetchWallets","filtered","filterWallets","length","Error","Promise","resolve","reject","cleanup","startConnect","disconnect","removeStoredSession","emit","isConnected","getWallet","on","cb","has","set","Set","get","off","delete","storageKey","Array","isArray","sort","url","ids","filter","includes","session","initSession","listenForConfirmation","result","storeSession","err","String","method","headers","stringify","origin","window","location","localStorage","setItem","stored","getItem","removeItem","super"],"mappings":"mBAOaA,EAKX,WAAAC,CACUC,EACAC,EACAC,EACAC,EACAC,EACAC,GALAC,KAAAN,OAAAA,EACAM,KAAAL,aAAAA,EACAK,KAAAJ,YAAAA,EACAI,KAAAH,WAAAA,EACAG,KAAAF,UAAAA,EACAE,KAAAD,QAAAA,EAVFC,KAAAC,GAAuB,KACvBD,KAAAE,eAAuD,KACvDF,KAAAG,QAAS,CASd,CAEH,OAAAC,GACEJ,KAAKG,QAAS,EACAH,KAAKN,OAChBW,QAAQ,QAAS,MACjBA,QAAQ,MAAO,IACiCL,KAAKL,aAExD,IAGEK,KAAKM,iBACP,CAAE,MACAN,KAAKD,QAAQ,8BACf,CACF,CAEQ,eAAAO,GACN,MAAMC,EAAUP,KAAKN,OAAOW,QAAQ,MAAO,IAK3CG,MAFmB,GAAGD,4CAGnBE,KAAMC,GAAQA,EAAIC,QAClBF,KAAMG,IAEL,MAAMC,EAAUD,EAAKP,QAAQ,OAAQ,IAE/BS,EADYC,KAAKC,MAAMH,GACPC,IAGhBG,EAAQ,GADCV,EAAQF,QAAQ,QAAS,sDACgCS,IAExEd,KAAKC,GAAK,IAAIiB,UAAUD,GAExBjB,KAAKC,GAAGkB,OAAS,KAEfnB,KAAKC,GAAImB,KAAK,WAGhBpB,KAAKC,GAAGoB,UAAaC,IACnB,MAAMC,EAAMD,EAAME,KAElB,GAAY,WAARD,EASJ,GAAIA,EAAIE,WAAW,MACjB,IACE,MAAMC,EAAUX,KAAKC,MAAMO,EAAII,MAAM,KAC9BC,EAAWJ,GAAQE,EAC1B1B,KAAK6B,YAAYD,EAAWJ,EAC9B,CAAE,MAEF,KAKU,MAARD,GACFvB,KAAKC,GAAImB,KAAK,UApBdpB,KAAKC,GAAImB,KAAK,MAwBlBpB,KAAKC,GAAG6B,QAAU,KACX9B,KAAKG,QACRH,KAAK+B,qBAIT/B,KAAKC,GAAG+B,QAAU,KACXhC,KAAKG,QACRH,KAAK+B,uBAIVE,MAAM,KACAjC,KAAKG,QACRH,KAAK+B,qBAGb,CAEQ,WAAAF,CAAYD,EAAmBJ,GACrC,OAAQI,GACN,IAAK,oBACH5B,KAAKJ,YAAY4B,GACjBxB,KAAKkC,QACL,MACF,IAAK,mBACHlC,KAAKH,aACLG,KAAKkC,QACL,MACF,IAAK,kBACHlC,KAAKF,YACLE,KAAKkC,QAGX,CAEQ,iBAAAH,GACF/B,KAAKG,QAAUH,KAAKE,iBACxBF,KAAKE,eAAiBiC,WAAW,KAC/BnC,KAAKE,eAAiB,KACtBF,KAAKM,mBACJ,KACL,CAEA,KAAA4B,GACElC,KAAKG,QAAS,EACVH,KAAKE,iBACPkC,aAAapC,KAAKE,gBAClBF,KAAKE,eAAiB,MAEpBF,KAAKC,KACPD,KAAKC,GAAGiC,QACRlC,KAAKC,GAAK,KAEd,QAKWoC,EAIX,WAAA5C,CACUC,EACAC,EACAC,EACAC,EACAC,EACAC,GALAC,KAAAN,OAAAA,EACAM,KAAAL,aAAAA,EACAK,KAAAJ,YAAAA,EACAI,KAAAH,WAAAA,EACAG,KAAAF,UAAAA,EACAE,KAAAD,QAAAA,EATFC,KAAAsC,MAA+C,KAC/CtC,KAAAuC,SAAU,CASf,CAEH,KAAAC,GACExC,KAAKuC,SAAU,EACfvC,KAAKyC,OACLzC,KAAKsC,MAAQI,YAAY,IAAM1C,KAAKyC,OAAQ,IAC9C,CAEQ,UAAMA,GACZ,IAAIzC,KAAKuC,QAET,IACE,MAAMhC,EAAUP,KAAKN,OAAOW,QAAQ,MAAO,IACrCK,QAAYF,MAChB,GAAGD,0BAAgCP,KAAKL,gBAE1C,IAAKe,EAAIiC,GAAI,OAEb,MAAMnB,QAAad,EAAIkC,OAEvB,OAAQpB,EAAKqB,QACX,IAAK,YACH7C,KAAKJ,YAAY,CAAEkD,QAAStB,EAAKsB,QAASC,KAAMvB,EAAKuB,OACrD/C,KAAKgD,OACL,MACF,IAAK,WACHhD,KAAKH,aACLG,KAAKgD,OACL,MACF,IAAK,UACHhD,KAAKF,YACLE,KAAKgD,OAGX,CAAE,MAEF,CACF,CAEA,IAAAA,GACEhD,KAAKuC,SAAU,EACXvC,KAAKsC,QACPW,cAAcjD,KAAKsC,OACnBtC,KAAKsC,MAAQ,KAEjB,EC3MF,MAAMY,EAAW,qBAgHJC,EAKX,WAAA1D,CAAY2D,EAAyBC,GAJ7BrD,KAAAsD,QAAiC,KAKvCtD,KAAKoD,MAAQA,EACbpD,KAAKqD,QAAUA,CACjB,CAGA,gBAAAE,CACET,EACAU,GAEA,MAiBMC,EAAO,2OAjBUX,EACpBY,IACEC,GAAM,sDACoCA,EAAEC,uBAE3CD,EAAEE,KACE,oCAAoCF,EAAEE,cAAcF,EAAEG,WACtD,2CAA2CH,EAAEG,KAAKC,OAAO,GAAGC,+EAGlCL,EAAEG,yBAC9BH,EAAEM,YAAc,+BAA+BN,EAAEM,oBAAsB,mCAI5EC,KAAK,+BAYRlE,KAAKmE,OAAOV,GAGZX,EAAQsB,QAAST,IACf,MAAMU,EAAKrE,KAAKsD,SAASgB,cACvB,oBAAoBX,EAAEC,cAExBS,GAAIE,iBAAiB,QAAS,IAAMf,EAASG,KAEjD,CAGA,WAAAa,CACEC,EACAC,EACAC,EACAC,GAEA,MAAMC,EApEV,SAA2BlE,EAAcmE,EAAO,KAG9C,MAAO,oDAAoDA,KAAQA,UAAaC,mBAAmBpE,IACrG,CAgEkBqE,CAAkBN,GAE1BjB,EAAO,8GAILkB,EACI,8DACA,8CAEyBF,EAAOX,yZAUHY,+NAMAG,uUAWzC7E,KAAKmE,OAAOV,GAGZ,MAAMwB,EAAOjF,KAAKsD,SAAS4B,iBAAiB,WACtCC,EAASnF,KAAKsD,SAAS4B,iBAAiB,gBAC9CD,GAAMb,QAASgB,IACbA,EAAIb,iBAAiB,QAAS,KAC5B,MAAMc,EAAUD,EAAoBE,QAAQF,IAC5CH,EAAKb,QAASmB,GAAMA,EAAEC,UAAUC,OAAO,WACvCL,EAAII,UAAUE,IAAI,UAClBP,GAAQf,QAASuB,IACdA,EAAkBC,MAAMC,QACtBF,EAAkBL,QAAQQ,QAAUT,EAAS,QAAU,aAM5DV,GAAYC,GACd5E,KAAKsD,SACDgB,cAAc,yBACdC,iBAAiB,QAASK,EAElC,CAGA,YAAAmB,CAAapF,EAAcqF,GAAc,GACvC,MAAMC,EAAWjG,KAAKsD,SAASgB,cAAc,cACzC2B,IACFA,EAASC,UAAY,aACjBF,EAAc,iCAAmC,qBAC3CrF,mBAGd,CAEQ,MAAAwD,CAAOgC,GACbnG,KAAKoG,UAEL,MAAM9C,EAAU+C,SAASC,cAAc,OACvChD,EAAQiD,GAAKrD,EACbI,EAAQ4C,UAAY,kBAtPxB,SAAmB9C,GACjB,MACMoD,EAAwB,SAAVpD,EAAmB,UAAY,UAE7CqD,EAA0B,SAAVrD,EAAmB,UAAY,UAC/CsD,EAAmB,SAAVtD,EAAmB,UAAY,UACxCuD,EAAU,UAGhB,MAAO,mTARc,SAAVvD,EAAmB,UAAY,kJAEnB,SAAVA,EAAmB,UAAY,2KAoBYsD,sLAK1BD,6FAGID,4RAMVE,+GA9BA,SAAVtD,EAAmB,UAAY,4PAwC3BuD,mQAK4BF,yKAKtBC,6LAI6BF,kCAC1BC,sEAEME,sJAGMA,saAWGF,8KAGiBA,oFAGRC,+BAC3BC,sPAMMA,oIAKhC,CAuJeC,CAAU5G,KAAKoD,iFAEE+C,8BAI5BE,SAASzF,KAAKiG,YAAYvD,GAC1BtD,KAAKsD,QAAUA,EAGftD,KAAKsD,QACFgB,cAAc,0BACbC,iBAAiB,QAAS,KAC1BvE,KAAKqD,UACLrD,KAAKoG,YAITpG,KAAKsD,QACFgB,cAAc,gBACbC,iBAAiB,QAAUuC,IACtBA,EAAEzB,OAAuBG,UAAUuB,SAAS,gBAC/C/G,KAAKqD,UACLrD,KAAKoG,YAGb,CAEA,OAAAA,GACE,MAAMY,EAAWX,SAASY,eAAe/D,GACrC8D,GACFA,EAASvB,SAEXzF,KAAKsD,QAAU,IACjB,QClRW4D,EAYX,WAAAzH,CAAY0H,GANJnH,KAAAoH,UAA0E,IAAIC,IAC9ErH,KAAAsH,MAAsB,KACtBtH,KAAAuH,YAAkC,KAClCvH,KAAAwH,iBAA4C,KAC5CxH,KAAAyH,cAAsC,KAG5CzH,KAAKmH,OAAS,CACZO,MAAOP,EAAOO,MACdC,YAAaR,EAAOQ,YACpB/D,SAAUuD,EAAOvD,SACjBR,MAAO+D,EAAO/D,OAAS,SAGzBpD,KAAK4H,gBACP,CAIA,aAAMxH,GACJ,GAAIJ,KAAKyH,cACP,OAAOzH,KAAKyH,cAGd,MAAM3E,QAAgB9C,KAAK6H,eACrBC,EAAW9H,KAAK+H,cAAcjF,GAEpC,GAAwB,IAApBgF,EAASE,OACX,MAAM,IAAIC,MAAM,kCAGlB,OAAO,IAAIC,QAAuB,CAACC,EAASC,KAM1CpI,KAAKsH,MAAQ,IAAInE,EAAMnD,KAAKmH,OAAO/D,MALnB,KACdpD,KAAKqI,UACLD,EAAO,IAAIH,MAAM,wBAKK,IAApBH,EAASE,OACXhI,KAAKsI,aAAaR,EAAS,IAAI,EAAOK,EAASC,GAE/CpI,KAAKsH,MAAM/D,iBAAiBuE,EAAWrD,IACrCzE,KAAKsI,aAAa7D,GAAQ,EAAM0D,EAASC,MAIjD,CAEA,UAAAG,GACEvI,KAAKyH,cAAgB,KACrBzH,KAAKwI,sBACLxI,KAAKqI,UACLrI,KAAKyI,KAAK,aACZ,CAEA,WAAAC,GACE,OAA8B,OAAvB1I,KAAKyH,aACd,CAEA,SAAAkB,GACE,OAAO3I,KAAKyH,aACd,CAEA,EAAAmB,CAAGtH,EAA+BuH,GAC3B7I,KAAKoH,UAAU0B,IAAIxH,IACtBtB,KAAKoH,UAAU2B,IAAIzH,EAAO,IAAI0H,KAEhChJ,KAAKoH,UAAU6B,IAAI3H,GAAQoE,IAAImD,EACjC,CAEA,GAAAK,CAAI5H,EAA+BuH,GACjC7I,KAAKoH,UAAU6B,IAAI3H,IAAQ6H,OAAON,EACpC,CAIA,cAAYO,GACV,MAAMxF,EAAW5D,KAAKmH,OAAOvD,SAI7B,MAAO,gBAHQyF,MAAMC,QAAQ1F,GACzBA,EAAS2F,OAAOrF,KAAK,KACrBN,GAAY,SAElB,CAEQ,kBAAMiE,GACZ,MAAM2B,EAAMxJ,KAAKmH,OAAOQ,YAAYtH,QAAQ,MAAO,IAC7CK,QAAYF,MAAMgJ,GACxB,IAAK9I,EAAIiC,GAAI,MAAM,IAAIsF,MAAM,2BAC7B,OAAOvH,EAAIkC,MACb,CAEQ,aAAAmF,CAAcjF,GACpB,IAAK9C,KAAKmH,OAAOvD,SAAU,OAAOd,EAElC,MAAM2G,EAAMJ,MAAMC,QAAQtJ,KAAKmH,OAAOvD,UAClC5D,KAAKmH,OAAOvD,SACZ,CAAC5D,KAAKmH,OAAOvD,UAEjB,OAAOd,EAAQ4G,OAAQ/F,GAAM8F,EAAIE,SAAShG,EAAEC,UAC9C,CAEQ,kBAAM0E,CACZ7D,EACAE,EACAwD,EACAC,GAEA,IACE,MAAMwB,QAAgB5J,KAAK6J,YAAYpF,GAEvCzE,KAAKsH,OAAO9C,YAAYC,EAAQmF,EAAQlF,SAAUC,EAAU,KAC1D3E,KAAKqI,UACLrI,KAAKI,UAAUK,KAAK0H,GAASlG,MAAMmG,KAGrCpI,KAAK8J,sBACHrF,EAAO/E,OACPkK,EAAQjK,aACPoK,IACC/J,KAAKyH,cAAgBsC,EACrB/J,KAAKgK,aAAaD,GAClB/J,KAAKsH,OAAOlB,UACZpG,KAAKsH,MAAQ,KACbtH,KAAKyI,KAAK,UAAWsB,GACrB5B,EAAQ4B,IAEV,KACE/J,KAAKsH,OAAOvB,aAAa,uBAAuB,GAChD5D,WAAW,KACTnC,KAAKsH,OAAOlB,UACZpG,KAAKsH,MAAQ,KACbc,EAAO,IAAIH,MAAM,iCAChB,OAEL,KACEjI,KAAKsH,OAAOvB,aAAa,mBAAmB,GAC5C/F,KAAKyI,KAAK,mBACVtG,WAAW,KACTnC,KAAKsH,OAAOlB,UACZpG,KAAKsH,MAAQ,KACbc,EAAO,IAAIH,MAAM,qBAChB,OAGT,CAAE,MAAOgC,GACPjK,KAAKsH,OAAOlB,UACZpG,KAAKsH,MAAQ,KACbc,EAAO6B,aAAehC,MAAQgC,EAAM,IAAIhC,MAAMiC,OAAOD,IACvD,CACF,CAEQ,iBAAMJ,CAAYpF,GACxB,MAAMlE,EAAUkE,EAAO/E,OAAOW,QAAQ,MAAO,IACvCK,QAAYF,MAAM,GAAGD,iBAAwB,CACjD4J,OAAQ,OACRC,QAAS,CAAE,eAAgB,oBAC3BxJ,KAAMG,KAAKsJ,UAAU,CACnB3C,MAAO1H,KAAKmH,OAAOO,MACnB9D,SAAUa,EAAOb,SACjB0G,OAA0B,oBAAXC,OAAyBA,OAAOC,SAASF,OAAS,OAGrE,IAAK5J,EAAIiC,GAAI,MAAM,IAAIsF,MAAM,0BAC7B,OAAOvH,EAAIkC,MACb,CAEQ,qBAAAkH,CACNpK,EACAC,EACAC,EACAC,EACAC,GAcAE,KAAKuH,YAAc,IAAI/H,EACrBE,EACAC,EACAC,EACAC,EACAC,EAjBc,KACdE,KAAKwH,iBAAmB,IAAInF,EAC1B3C,EACAC,EACAC,EACAC,EACAC,EACCyB,GAAQvB,KAAKyI,KAAK,QAASlH,IAE9BvB,KAAKwH,iBAAiBhF,UAWxBxC,KAAKuH,YAAYnH,SACnB,CAEQ,OAAAiI,GACNrI,KAAKuH,aAAarF,QAClBlC,KAAKuH,YAAc,KACnBvH,KAAKwH,kBAAkBxE,OACvBhD,KAAKwH,iBAAmB,KACxBxH,KAAKsH,OAAOlB,UACZpG,KAAKsH,MAAQ,IACf,CAEQ,IAAAmB,CAAKnH,EAA+BE,GAC1CxB,KAAKoH,UAAU6B,IAAI3H,IAAQ8C,QAASyE,GAAOA,EAAGrH,GAChD,CAIQ,YAAAwI,CAAaD,GACnB,IACEU,aAAaC,QAAQ1K,KAAKoJ,WAAYrI,KAAKsJ,UAAUN,GACvD,CAAE,MAEF,CACF,CAEQ,cAAAnC,GACN,IACE,MAAM+C,EAASF,aAAaG,QAAQ5K,KAAKoJ,YACrCuB,IACF3K,KAAKyH,cAAgB1G,KAAKC,MAAM2J,GAEpC,CAAE,MAEF,CACF,CAEQ,mBAAAnC,GACN,IACEiC,aAAaI,WAAW7K,KAAKoJ,WAC/B,CAAE,MAEF,CACF,uDC7PI,cAAgClC,EACpC,WAAAzH,CAAY0H,GACV2D,MAAM,IAAK3D,EAAQvD,SAAU,aAC/B,0BCHI,cAA8BsD,EAClC,WAAAzH,CAAY0H,GACV2D,MAAM,IAAK3D,EAAQvD,SAAU,WAC/B"}
|
|
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\">›</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\">✕</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\">←</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\">✕</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\">✕</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":"mBAOaA,EAKX,WAAAC,CACUC,EACAC,EACAC,EACAC,EACAC,EACAC,GALAC,KAAAN,OAAAA,EACAM,KAAAL,aAAAA,EACAK,KAAAJ,YAAAA,EACAI,KAAAH,WAAAA,EACAG,KAAAF,UAAAA,EACAE,KAAAD,QAAAA,EAVFC,KAAAC,GAAuB,KACvBD,KAAAE,eAAuD,KACvDF,KAAAG,QAAS,CASd,CAEH,OAAAC,GACEJ,KAAKG,QAAS,EACAH,KAAKN,OAChBW,QAAQ,QAAS,MACjBA,QAAQ,MAAO,IACiCL,KAAKL,aAExD,IAGEK,KAAKM,iBACP,CAAE,MACAN,KAAKD,QAAQ,8BACf,CACF,CAEQ,eAAAO,GACN,MAAMC,EAAUP,KAAKN,OAAOW,QAAQ,MAAO,IAK3CG,MAFmB,GAAGD,4CAGnBE,KAAMC,GAAQA,EAAIC,QAClBF,KAAMG,IAEL,MAAMC,EAAUD,EAAKP,QAAQ,OAAQ,IAE/BS,EADYC,KAAKC,MAAMH,GACPC,IAGhBG,EAAQ,GADCV,EAAQF,QAAQ,QAAS,sDACgCS,IAExEd,KAAKC,GAAK,IAAIiB,UAAUD,GAExBjB,KAAKC,GAAGkB,OAAS,KAEfnB,KAAKC,GAAImB,KAAK,WAGhBpB,KAAKC,GAAGoB,UAAaC,IACnB,MAAMC,EAAMD,EAAME,KAElB,GAAY,WAARD,EASJ,GAAIA,EAAIE,WAAW,MACjB,IACE,MAAMC,EAAUX,KAAKC,MAAMO,EAAII,MAAM,KAC9BC,EAAWJ,GAAQE,EAC1B1B,KAAK6B,YAAYD,EAAWJ,EAC9B,CAAE,MAEF,KAKU,MAARD,GACFvB,KAAKC,GAAImB,KAAK,UApBdpB,KAAKC,GAAImB,KAAK,MAwBlBpB,KAAKC,GAAG6B,QAAU,KACX9B,KAAKG,QACRH,KAAK+B,qBAIT/B,KAAKC,GAAG+B,QAAU,KACXhC,KAAKG,QACRH,KAAK+B,uBAIVE,MAAM,KACAjC,KAAKG,QACRH,KAAK+B,qBAGb,CAEQ,WAAAF,CAAYD,EAAmBJ,GACrC,OAAQI,GACN,IAAK,oBACH5B,KAAKJ,YAAY4B,GACjBxB,KAAKkC,QACL,MACF,IAAK,mBACHlC,KAAKH,aACLG,KAAKkC,QACL,MACF,IAAK,kBACHlC,KAAKF,YACLE,KAAKkC,QAGX,CAEQ,iBAAAH,GACF/B,KAAKG,QAAUH,KAAKE,iBACxBF,KAAKE,eAAiBiC,WAAW,KAC/BnC,KAAKE,eAAiB,KACtBF,KAAKM,mBACJ,KACL,CAEA,KAAA4B,GACElC,KAAKG,QAAS,EACVH,KAAKE,iBACPkC,aAAapC,KAAKE,gBAClBF,KAAKE,eAAiB,MAEpBF,KAAKC,KACPD,KAAKC,GAAGiC,QACRlC,KAAKC,GAAK,KAEd,QAKWoC,EAIX,WAAA5C,CACUC,EACAC,EACAC,EACAC,EACAC,EACAC,GALAC,KAAAN,OAAAA,EACAM,KAAAL,aAAAA,EACAK,KAAAJ,YAAAA,EACAI,KAAAH,WAAAA,EACAG,KAAAF,UAAAA,EACAE,KAAAD,QAAAA,EATFC,KAAAsC,MAA+C,KAC/CtC,KAAAuC,SAAU,CASf,CAEH,KAAAC,GACExC,KAAKuC,SAAU,EACfvC,KAAKyC,OACLzC,KAAKsC,MAAQI,YAAY,IAAM1C,KAAKyC,OAAQ,IAC9C,CAEQ,UAAMA,GACZ,IAAIzC,KAAKuC,QAET,IACE,MAAMhC,EAAUP,KAAKN,OAAOW,QAAQ,MAAO,IACrCK,QAAYF,MAChB,GAAGD,0BAAgCP,KAAKL,gBAE1C,IAAKe,EAAIiC,GAAI,OAEb,MAAMnB,QAAad,EAAIkC,OAEvB,OAAQpB,EAAKqB,QACX,IAAK,YACH7C,KAAKJ,YAAY,CAAEkD,OAAQtB,EAAKsB,OAAQC,KAAMvB,EAAKuB,OACnD/C,KAAKgD,OACL,MACF,IAAK,WACHhD,KAAKH,aACLG,KAAKgD,OACL,MACF,IAAK,UACHhD,KAAKF,YACLE,KAAKgD,OAGX,CAAE,MAEF,CACF,CAEA,IAAAA,GACEhD,KAAKuC,SAAU,EACXvC,KAAKsC,QACPW,cAAcjD,KAAKsC,OACnBtC,KAAKsC,MAAQ,KAEjB,EC3MF,MAAMY,EAAW,qBAmQJC,EAKX,WAAA1D,CAAY2D,EAAyBC,GAJ7BrD,KAAAsD,QAAiC,KAKvCtD,KAAKoD,MAAQA,EACbpD,KAAKqD,QAAUA,CACjB,CAEA,gBAAAE,CACEC,EACAC,GAEA,MAkCMC,EAAO,0TAlCGF,EAAQG,QAAU,EAG9B,8BAA8BH,EAC3BI,IACEC,GAAM,6DACuCA,EAAEC,yBAEhDD,EAAEE,KACE,yCAAyCF,EAAEE,cAAcF,EAAEG,WAC3D,gDAAgDH,EAAEG,KAAKC,OAAO,2DAEhCJ,EAAEG,8BAGrCE,KAAK,WACR,8BAA8BV,EAC3BI,IACEC,GAAM,wDACkCA,EAAEC,yBAE3CD,EAAEE,KACE,yCAAyCF,EAAEE,cAAcF,EAAEG,WAC3D,gDAAgDH,EAAEG,KAAKC,OAAO,yGAG/BJ,EAAEG,2BACnCH,EAAEM,YAAc,oCAAoCN,EAAEM,oBAAsB,oGAK/ED,KAAK,sFAaZlE,KAAKoE,OAAOV,GAEZF,EAAQa,QAASR,IACf7D,KAAKsD,SACDgB,cAAc,oBAAoBT,EAAEC,eACpCS,iBAAiB,QAAS,IAAMd,EAASI,KAEjD,CAEA,WAAAW,CACE1B,EACA2B,EACAC,EACAC,GAEA,MAAMC,EA9EV,SAA2BjE,EAAckE,EAAO,KAC9C,MAAO,oDAAoDA,KAAQA,UAAaC,mBAAmBnE,aACrG,CA4EkBoE,CAAkBN,GAE1Bf,EAAO,yHAILgB,EAAW,8DAAgE,iBAC3E5B,EAAOiB,KAAO,oCAAoCjB,EAAOiB,WAAa,sCACjDjB,EAAOkB,0eAWKS,86BAQnBG,qZAatB5E,KAAKoE,OAAOV,GAEZ,MAAMsB,EAAOhF,KAAKsD,SAAS2B,iBAAiB,WACtCC,EAASlF,KAAKsD,SAAS2B,iBAAiB,gBAC9CD,GAAMX,QAASc,IACbA,EAAIZ,iBAAiB,QAAS,KAC5B,MAAMa,EAAUD,EAAoBE,QAAQF,IAC5CH,EAAKX,QAASiB,GAAMA,EAAEC,UAAUC,OAAO,WACvCL,EAAII,UAAUE,IAAI,UAClBP,GAAQb,QAASqB,IACdA,EAAkBC,MAAMC,QACtBF,EAAkBL,QAAQQ,QAAUT,EAAS,QAAU,aAK5DV,GAAYC,GACd3E,KAAKsD,SACDgB,cAAc,yBACdC,iBAAiB,QAASI,EAElC,CAEA,WAAAmB,CACEhD,EACAiD,EACAhD,EACAiD,GAEA,MAEMC,EAAclD,GAAMmD,UAAY,OAChCC,EAAWF,EAAYtE,MAAM,EAAG,GAAGyE,cAMnC1C,EAAO,ylBAJMX,GAAMsD,OACrB,uCAAuCtD,EAAKsD,gBAAgBJ,QAC5D,8CAA8CE,8GAeJF,0BAClCF,EAAU,4CAA4CA,MAAYA,UAAkB,wNAShG/F,KAAKoE,OAAOV,GAEZ1D,KAAKsD,SACDgB,cAAc,yBACdC,iBAAiB,QAASyB,EAChC,CAEA,YAAAM,CAAa3F,EAAc4F,GAAc,GACvC,MAAMC,EAAKxG,KAAKsD,SAASgB,cAAc,cACnCkC,IACFA,EAAGC,UAAY,aACXF,EAAc,iCAAmC,qBAC3C5F,mBAGd,CAEQ,MAAAyD,CAAOsC,GACb1G,KAAK2G,UAEL,MAAMH,EAAKI,SAASC,cAAc,OAClCL,EAAGM,GAAK5D,EACRsD,EAAGC,UAAY,kBAtcnB,SAAmBrD,GACjB,MAAM2D,EAAmB,SAAV3D,EACT4D,EAAKD,EAAS,UAAY,UAC1BE,EAAcF,EAAS,UAAY,UACnCpG,EAAOoG,EAAS,UAAY,UAC5BG,EAAgBH,EAAS,UAAY,UACrCI,EAASJ,EAAS,UAAY,UAC9BK,EAAS,UACTC,EAAa,UAEnB,MAAO,kSAQqBN,EAAS,IAAO,mbAW3BC,8FACyCrG,+CAClBoG,EAAS,GAAM,iOAQtCI,kiBAiBAF,mFAC2BC,2EAGXC,YAAiBxG,yDAEtBuG,8iBAiBXD,mBAA6BE,sJAIUJ,EAAS,GAAM,qJAI/BM,KAAcD,mKAGhBL,EAAS,GAAM,oHAIzCG,wYAUaC,2GAIRF,mBAA6BG,2PAONC,KAAcD,0RAMLF,2DACfA,0FAIHD,kPAMNC,uFAGCvG,gDAETqG,YAAarG,6CACQoG,EAAS,GAAM,oPAObM,KAAcD,6jBAiBfL,EAAS,GAAM,oHAGdG,6LAKkBA,iFAGVC,8BACzBC,sPAQXF,yHAGevG,yHAKCoG,EAAS,OAAS,kSAUNM,KAAcD,4dAYTzG,0GAI5BsG,oOAKqBE,+IAIEE,KAAcD,mKAG/BD,qIAG4CxG,kEAEvCuG,sQAMYG,KAAcD,6RAUxD,CA8MeE,CAAUtH,KAAKoD,iFAEEsD,8BAI5BE,SAAShG,KAAK2G,YAAYf,GAC1BxG,KAAKsD,QAAUkD,EAEfxG,KAAKsD,QACFgB,cAAc,0BACbC,iBAAiB,QAAS,KAAQvE,KAAKqD,UAAWrD,KAAK2G,YAE3D3G,KAAKsD,QACFgB,cAAc,gBACbC,iBAAiB,QAAUiD,IACtBA,EAAEpC,OAAuBG,UAAUkC,SAAS,gBAC/CzH,KAAKqD,UACLrD,KAAK2G,YAGb,CAEA,OAAAA,GACEC,SAASc,eAAexE,IAAWsC,SACnCxF,KAAKsD,QAAU,IACjB,ECzdF,MAAMqE,EAAqB,sBAGdC,EAYX,WAAAnI,CAAYoI,GANJ7H,KAAA8H,UAA0E,IAAIC,IAC9E/H,KAAAgI,MAAsB,KACtBhI,KAAAiI,YAAkC,KAClCjI,KAAAkI,iBAA4C,KAC5ClI,KAAAmI,cAAsC,KAG5CnI,KAAK6H,OAAS,CACZO,MAAOP,EAAOO,MACdC,YAAaR,EAAOQ,aAjBG,+EAkBvBvE,SAAU+D,EAAO/D,SACjBV,MAAOyE,EAAOzE,OAAS,SAGzBpD,KAAKsI,iBACLtI,KAAKuI,gBACP,CAIA,aAAMnI,GACJ,GAAIJ,KAAKmI,cACP,OAAOnI,KAAKmI,cAGd,MAAM3E,QAAgBxD,KAAKwI,eACrBC,EAAWzI,KAAK0I,cAAclF,GAEpC,GAAwB,IAApBiF,EAAS9E,OACX,MAAM,IAAIgF,MAAM,kCAGlB,OAAO,IAAIC,QAAuB,CAACC,EAASC,KAM1C9I,KAAKgI,MAAQ,IAAI7E,EAAMnD,KAAK6H,OAAOzE,MALnB,KACdpD,KAAK+I,UACLD,EAAO,IAAIH,MAAM,wBAKK,IAApBF,EAAS9E,OACX3D,KAAKgJ,aAAaP,EAAS,IAAI,EAAOI,EAASC,GAE/C9I,KAAKgI,MAAMzE,iBAAiBkF,EAAW3F,IACrC9C,KAAKgJ,aAAalG,GAAQ,EAAM+F,EAASC,MAIjD,CAEA,UAAAG,GAEE,MAAMC,EAAUlJ,KAAKmI,eAAee,QACpC,GAAIA,EAAS,CACX,MAAM3I,EAAU2I,EAAQxJ,OAAOW,QAAQ,MAAO,IAC9CG,MAAM,GAAGD,gCAAuC,CAC9C4I,OAAQ,OACRC,QAAS,CAAE,eAAgB,oBAC3BxI,KAAMG,KAAKsI,UAAU,CAAE1J,aAAcuJ,EAAQvJ,iBAC5CsC,MAAM,OACX,CAGAjC,KAAKmI,cAAgB,KACrBnI,KAAKsJ,sBACLtJ,KAAKuJ,0BACLvJ,KAAK+I,UACL/I,KAAKwJ,KAAK,aACZ,CAEA,WAAAC,GACE,OAA8B,OAAvBzJ,KAAKmI,aACd,CAEA,SAAAuB,GACE,OAAO1J,KAAKmI,aACd,CAEA,EAAAwB,CAAGrI,EAA+BsI,GAC3B5J,KAAK8H,UAAU+B,IAAIvI,IACtBtB,KAAK8H,UAAUgC,IAAIxI,EAAO,IAAIyI,KAEhC/J,KAAK8H,UAAUkC,IAAI1I,GAAQmE,IAAImE,EACjC,CAEA,GAAAK,CAAI3I,EAA+BsI,GACjC5J,KAAK8H,UAAUkC,IAAI1I,IAAQ4I,OAAON,EACpC,CAIA,cAAYO,GACV,MAAMrG,EAAW9D,KAAK6H,OAAO/D,SACvBsG,EAASC,MAAMC,QAAQxG,GACzBA,EAASyG,OAAOrG,KAAK,KACrBJ,GAAY,MAChB,MAAO,GAAG6D,IAAqByC,KACjC,CAEQ,kBAAM5B,GACZ,MAAMgC,EAAMxK,KAAK6H,OAAOQ,YAAYhI,QAAQ,MAAO,IAC7CK,QAAYF,MAAMgK,GACxB,IAAK9J,EAAIiC,GAAI,MAAM,IAAIgG,MAAM,2BAC7B,OAAOjI,EAAIkC,MACb,CAEQ,aAAA8F,CAAclF,GACpB,IAAKxD,KAAK6H,OAAO/D,SAAU,OAAON,EAElC,MAAMiH,EAAMJ,MAAMC,QAAQtK,KAAK6H,OAAO/D,UAClC9D,KAAK6H,OAAO/D,SACZ,CAAC9D,KAAK6H,OAAO/D,UAEjB,OAAON,EAAQkH,OAAQ7G,GAAM4G,EAAIE,SAAS9G,EAAEC,UAC9C,CAEQ,kBAAMkF,CACZlG,EACA4B,EACAmE,EACAC,GAEA,IACE,MAAMI,QAAgBlJ,KAAK4K,YAAY9H,GAEvC9C,KAAKgI,OAAOxD,YAAY1B,EAAQoG,EAAQzE,SAAUC,EAAU,KAC1D1E,KAAK+I,UACL/I,KAAKI,UAAUK,KAAKoI,GAAS5G,MAAM6G,KAGrC9I,KAAK6K,sBACH/H,EAAOpD,OACPwJ,EAAQvJ,aACPmL,IAECA,EAAO5B,QAAU,CACfvJ,aAAcuJ,EAAQvJ,aACtBmE,SAAUhB,EAAOgB,SACjBpE,OAAQoD,EAAOpD,QAEjBM,KAAKmI,cAAgB2C,EACrB9K,KAAK+K,aAAaD,GAClB9K,KAAKgL,qBAAqBlI,EAAOgB,SAAUgH,GAC3C9K,KAAKwJ,KAAK,UAAWsB,GAGrB9K,KAAKgI,OAAOlC,YACVhD,EACAgI,EAAOhI,QAAQiD,SAAW,KAC1B+E,EAAO/H,MAAQ,KACf,KACE/C,KAAKgI,OAAOrB,UACZ3G,KAAKgI,MAAQ,KACba,EAAQiC,MAId,KACE9K,KAAKgI,OAAO1B,aAAa,uBAAuB,GAChDnE,WAAW,KACTnC,KAAKgI,OAAOrB,UACZ3G,KAAKgI,MAAQ,KACbc,EAAO,IAAIH,MAAM,iCAChB,OAEL,KACE3I,KAAKgI,OAAO1B,aAAa,mBAAmB,GAC5CtG,KAAKwJ,KAAK,mBACVrH,WAAW,KACTnC,KAAKgI,OAAOrB,UACZ3G,KAAKgI,MAAQ,KACbc,EAAO,IAAIH,MAAM,qBAChB,OAGT,CAAE,MAAOsC,GACPjL,KAAKgI,OAAOrB,UACZ3G,KAAKgI,MAAQ,KACbc,EAAOmC,aAAetC,MAAQsC,EAAM,IAAItC,MAAMuC,OAAOD,IACvD,CACF,CAEQ,iBAAML,CAAY9H,GACxB,MAAMvC,EAAUuC,EAAOpD,OAAOW,QAAQ,MAAO,IACvCK,QAAYF,MAAM,GAAGD,iBAAwB,CACjD4I,OAAQ,OACRC,QAAS,CAAE,eAAgB,oBAC3BxI,KAAMG,KAAKsI,UAAU,CACnBjB,MAAOpI,KAAK6H,OAAOO,MACnBtE,SAAUhB,EAAOgB,SACjBqH,OAA0B,oBAAXC,OAAyBA,OAAOC,SAASF,OAAS,OAGrE,IAAKzK,EAAIiC,GAAI,MAAM,IAAIgG,MAAM,0BAC7B,OAAOjI,EAAIkC,MACb,CAEQ,qBAAAiI,CACNnL,EACAC,EACAC,EACAC,EACAC,GAEA,IAAIwL,GAAW,EAEf,MAAMC,EAA4CC,GAAK,IAChDC,KACCH,IACJA,GAAW,EACXtL,KAAKiI,aAAa/F,QAClBlC,KAAKkI,kBAAkBlF,OACvBwI,KAAMC,GACP,EAEGC,EAAiBH,EAAK3L,GACtB+L,EAAgBJ,EAAK1L,GACrB+L,EAAgBL,EAAKzL,GAG3BE,KAAKkI,iBAAmB,IAAI7F,EAC1B3C,EACAC,EACA+L,EACAC,EACAC,EACCrK,GAAQvB,KAAKwJ,KAAK,QAASjI,IAE9BvB,KAAKkI,iBAAiB1F,QAGtBxC,KAAKiI,YAAc,IAAIzI,EACrBE,EACAC,EACA+L,EACAC,EACAC,EACA,QAEF5L,KAAKiI,YAAY7H,SACnB,CAEQ,OAAA2I,GACN/I,KAAKiI,aAAa/F,QAClBlC,KAAKiI,YAAc,KACnBjI,KAAKkI,kBAAkBlF,OACvBhD,KAAKkI,iBAAmB,KACxBlI,KAAKgI,OAAOrB,UACZ3G,KAAKgI,MAAQ,IACf,CAEQ,IAAAwB,CAAKlI,EAA+BE,GAC1CxB,KAAK8H,UAAUkC,IAAI1I,IAAQ+C,QAASuF,GAAOA,EAAGpI,GAChD,CAIQ,YAAAuJ,CAAaD,GACnB,IACEe,aAAaC,QAAQ9L,KAAKmK,WAAYpJ,KAAKsI,UAAUyB,GACvD,CAAE,MAEF,CACF,CAEQ,cAAAxC,GACN,IACE,MAAMyD,EAASF,aAAaG,QAAQhM,KAAKmK,YACrC4B,IACF/L,KAAKmI,cAAgBpH,KAAKC,MAAM+K,GAEpC,CAAE,MAEF,CACF,CAEQ,mBAAAzC,GACN,IACEuC,aAAaI,WAAWjM,KAAKmK,WAC/B,CAAE,MAEF,CACF,CAIQ,cAAA5B,GACN,GAAsB,oBAAX6C,OAAwB,OAEnC,MAAMtH,EAAW9D,KAAK6H,OAAO/D,SACvBoI,EAAM7B,MAAMC,QAAQxG,GACtBA,EAAS,GACTA,GAAY,gBAEfsH,OAAec,GAAOlM,IACzB,CAGQ,oBAAAgL,CAAqBlH,EAAkBgH,GAC7C,GAAsB,oBAAXM,OAAwB,OAEnC,MAAMhG,EAAUgG,OAAetH,GAC3BsB,GAAUA,IAAWpF,MAAQoF,aAAkBwC,IAChDxC,EAAe+C,cAAgB2C,EAC/B1F,EAAe2F,aAAaD,GAEjC,CAGQ,uBAAAvB,GACN,GAAsB,oBAAX6B,OAAwB,OAGnC,MAAMe,EAAO,CAAC,UAAW,YAAa,iBACtC,IAAK,MAAMD,KAAOC,EAAM,CACtB,MAAMC,EAAQhB,OAAec,GACzBE,GAAQA,IAASpM,MAAQoM,aAAgBxE,IAC1CwE,EAAajE,cAAgB,KAC7BiE,EAAa9C,sBAElB,CAGA,IACE,MAAM+C,EAAqB,GAC3B,IAAK,IAAIC,EAAI,EAAGA,EAAIT,aAAalI,OAAQ2I,IAAK,CAC5C,MAAMC,EAAIV,aAAaK,IAAII,GACvBC,GAAKA,EAAE9K,WAAWkG,IACpB0E,EAASG,KAAKD,EAElB,CACAF,EAAShI,QAASkI,GAAMV,aAAaI,WAAWM,GAClD,CAAE,MAEF,CACF,uDCjWI,cAAgC3E,EACpC,WAAAnI,CAAYoI,GACV4E,MAAM,IAAK5E,EAAQ/D,SAAU,aAC/B,0BCHI,cAA8B8D,EAClC,WAAAnI,CAAYoI,GACV4E,MAAM,IAAK5E,EAAQ/D,SAAU,WAC/B"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export { BaseWalletConnect } from './client';
|
|
2
2
|
export { TonPassConnect } from './tonpass';
|
|
3
3
|
export { OneDollarConnect } from './onedollar';
|
|
4
|
-
export type { WalletConnectConfig, WalletMeta, WalletInfo, ConnectResult, WalletConnectEventType, WalletConnectEventCallback, } from './types';
|
|
4
|
+
export type { WalletConnectConfig, WalletMeta, WalletInfo, ConnectResult, ConnectSession, WalletConnectEventType, WalletConnectEventCallback, } from './types';
|