toncorp-wallet-connect-sdk 0.1.1 → 0.1.3
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 +221 -53
- package/package.json +1 -1
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,75 +93,233 @@ 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` |
|
|
129
|
+
| `session_expired` | - | Session timed out |
|
|
100
130
|
|
|
101
|
-
|
|
131
|
+
### Window globals
|
|
102
132
|
|
|
103
|
-
|
|
133
|
+
Each wallet instance auto-registers on `window`:
|
|
104
134
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
135
|
+
| Class | Window global |
|
|
136
|
+
|-------|--------------|
|
|
137
|
+
| `TonPassConnect` | `window.tonpass` |
|
|
138
|
+
| `OneDollarConnect` | `window.onedollar` |
|
|
139
|
+
| `BaseWalletConnect` | `window.walletconnect` |
|
|
140
|
+
|
|
141
|
+
## Integrate into TMA Wallet App (Telegram Bot)
|
|
142
|
+
|
|
143
|
+
This section is for **wallet app developers** who want their Telegram Mini App (TMA) to support connect requests from DApps using this SDK.
|
|
108
144
|
|
|
109
|
-
|
|
110
|
-
|
|
145
|
+
### How it works
|
|
146
|
+
|
|
147
|
+
```
|
|
148
|
+
DApp (SDK) Your Backend TMA (Telegram)
|
|
149
|
+
──────────────────────────────────────────────────────────────────────
|
|
150
|
+
1. SDK calls POST /connect/init
|
|
151
|
+
← { sessionToken, deeplink }
|
|
152
|
+
|
|
153
|
+
2. User clicks deeplink / scans QR
|
|
154
|
+
────────────────────────────────────────────────→ TMA opens
|
|
155
|
+
parse startapp param
|
|
156
|
+
|
|
157
|
+
3. ← POST /connect/verify TMA sends initData
|
|
158
|
+
verify Telegram HMAC
|
|
159
|
+
→ { appId, origin }
|
|
160
|
+
|
|
161
|
+
4. TMA shows confirm UI
|
|
162
|
+
|
|
163
|
+
5. User taps Approve
|
|
164
|
+
← POST /connect/confirm TMA sends JWT + approved
|
|
165
|
+
get user wallet
|
|
166
|
+
emit WS event ──────→ SDK receives result
|
|
167
|
+
modal shows success
|
|
111
168
|
```
|
|
112
169
|
|
|
113
|
-
###
|
|
170
|
+
### Step 1: Parse `startapp` param in your TMA
|
|
114
171
|
|
|
115
|
-
|
|
116
|
-
# Navigate to SDK folder
|
|
117
|
-
cd src/blockchain/walletconnect/sdk
|
|
172
|
+
When a DApp initiates a connect request, the user is redirected to your TMA via deeplink. The `startapp` parameter contains the session token.
|
|
118
173
|
|
|
119
|
-
|
|
120
|
-
|
|
174
|
+
```typescript
|
|
175
|
+
// In your TMA (React / vanilla JS)
|
|
176
|
+
const tg = window.Telegram.WebApp;
|
|
177
|
+
const startParam = tg.initDataUnsafe?.start_param; // "sessionToken_abc123..."
|
|
178
|
+
|
|
179
|
+
if (startParam && startParam.startsWith('sessionToken_')) {
|
|
180
|
+
const sessionToken = startParam.replace('sessionToken_', '');
|
|
181
|
+
// → proceed to Step 2
|
|
182
|
+
}
|
|
183
|
+
```
|
|
121
184
|
|
|
122
|
-
|
|
123
|
-
npm run build
|
|
185
|
+
### Step 2: Verify session with your backend
|
|
124
186
|
|
|
125
|
-
|
|
126
|
-
npm pack --dry-run
|
|
187
|
+
Call your backend to verify the session and get DApp info to show the user.
|
|
127
188
|
|
|
128
|
-
|
|
129
|
-
|
|
189
|
+
```typescript
|
|
190
|
+
const response = await fetch('https://your-api.com/connect/verify', {
|
|
191
|
+
method: 'POST',
|
|
192
|
+
headers: { 'Content-Type': 'application/json' },
|
|
193
|
+
body: JSON.stringify({
|
|
194
|
+
sessionToken,
|
|
195
|
+
initData: tg.initData, // Telegram initData for HMAC verification
|
|
196
|
+
botId: 'your_bot_id',
|
|
197
|
+
}),
|
|
198
|
+
});
|
|
130
199
|
|
|
131
|
-
|
|
132
|
-
|
|
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
|
|
200
|
+
const { appId, appName, origin, walletId } = await response.json();
|
|
201
|
+
// → Show confirm UI to user
|
|
138
202
|
```
|
|
139
203
|
|
|
140
|
-
###
|
|
204
|
+
### Step 3: Show confirm popup
|
|
205
|
+
|
|
206
|
+
Display the DApp info and let the user approve or reject.
|
|
207
|
+
|
|
208
|
+
```tsx
|
|
209
|
+
// React example
|
|
210
|
+
function ConnectConfirm({ appName, origin, onApprove, onReject }) {
|
|
211
|
+
return (
|
|
212
|
+
<div className="confirm-popup">
|
|
213
|
+
<h2>{appName} wants to connect</h2>
|
|
214
|
+
<p>Origin: {origin}</p>
|
|
215
|
+
<button onClick={onApprove}>Approve</button>
|
|
216
|
+
<button onClick={onReject}>Reject</button>
|
|
217
|
+
</div>
|
|
218
|
+
);
|
|
219
|
+
}
|
|
220
|
+
```
|
|
141
221
|
|
|
142
|
-
|
|
143
|
-
# Check the published package
|
|
144
|
-
npm info toncorp-wallet-connect-sdk
|
|
222
|
+
### Step 4: Confirm or reject
|
|
145
223
|
|
|
146
|
-
|
|
147
|
-
|
|
224
|
+
When the user taps Approve/Reject, call the confirm endpoint with their JWT token.
|
|
225
|
+
|
|
226
|
+
```typescript
|
|
227
|
+
const token = 'user_jwt_token'; // from your TMA auth flow
|
|
228
|
+
|
|
229
|
+
const result = await fetch('https://your-api.com/connect/confirm', {
|
|
230
|
+
method: 'POST',
|
|
231
|
+
headers: {
|
|
232
|
+
'Content-Type': 'application/json',
|
|
233
|
+
'Authorization': `Bearer ${token}`,
|
|
234
|
+
},
|
|
235
|
+
body: JSON.stringify({
|
|
236
|
+
sessionToken,
|
|
237
|
+
approved: true, // or false to reject
|
|
238
|
+
}),
|
|
239
|
+
});
|
|
240
|
+
|
|
241
|
+
const data = await result.json();
|
|
242
|
+
// {
|
|
243
|
+
// success: true,
|
|
244
|
+
// status: 'CONFIRMED',
|
|
245
|
+
// wallet: { address: 'UQ...', chain: 'TON' },
|
|
246
|
+
// user: { username: 'john', avatar: '...' }
|
|
247
|
+
// }
|
|
248
|
+
|
|
249
|
+
// The SDK on the DApp side receives this automatically via WebSocket/polling
|
|
250
|
+
// → DApp modal shows "Connection Successful"
|
|
148
251
|
```
|
|
149
252
|
|
|
150
|
-
###
|
|
253
|
+
### Step 5: In-app QR scanner (optional)
|
|
151
254
|
|
|
255
|
+
Allow users already in your TMA to scan a QR code from a DApp to connect.
|
|
256
|
+
|
|
257
|
+
```typescript
|
|
258
|
+
// User scans QR → gets deeplink URL
|
|
259
|
+
const scannedUrl = 'https://t.me/YourBot/app?startapp=sessionToken_abc123...';
|
|
260
|
+
|
|
261
|
+
// Parse sessionToken from URL
|
|
262
|
+
const url = new URL(scannedUrl);
|
|
263
|
+
const startapp = url.searchParams.get('startapp') || '';
|
|
264
|
+
const sessionToken = startapp.replace('sessionToken_', '');
|
|
265
|
+
|
|
266
|
+
// → Same flow: verify → confirm popup → approve/reject
|
|
152
267
|
```
|
|
153
|
-
|
|
154
|
-
|
|
268
|
+
|
|
269
|
+
### Step 6: Manage connected DApps
|
|
270
|
+
|
|
271
|
+
Let users view and disconnect DApps from your TMA.
|
|
272
|
+
|
|
273
|
+
```typescript
|
|
274
|
+
// List connected DApps
|
|
275
|
+
const dapps = await fetch('https://your-api.com/connect/dapps', {
|
|
276
|
+
headers: { 'Authorization': `Bearer ${token}` },
|
|
277
|
+
}).then(r => r.json());
|
|
278
|
+
|
|
279
|
+
// Disconnect a specific DApp
|
|
280
|
+
await fetch('https://your-api.com/connect/disconnect', {
|
|
281
|
+
method: 'POST',
|
|
282
|
+
headers: {
|
|
283
|
+
'Content-Type': 'application/json',
|
|
284
|
+
'Authorization': `Bearer ${token}`,
|
|
285
|
+
},
|
|
286
|
+
body: JSON.stringify({
|
|
287
|
+
appId: 'the_app_id',
|
|
288
|
+
walletId: 'onedollar',
|
|
289
|
+
}),
|
|
290
|
+
});
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
### Backend API endpoints
|
|
294
|
+
|
|
295
|
+
Your backend needs these endpoints:
|
|
296
|
+
|
|
297
|
+
| Method | Path | Auth | Description |
|
|
298
|
+
|--------|------|------|-------------|
|
|
299
|
+
| `GET` | `/connect/wallets` | No | List supported wallets (SDK fetches this) |
|
|
300
|
+
| `POST` | `/connect/init` | No | Create connect session (SDK calls this) |
|
|
301
|
+
| `GET` | `/connect/status?token=` | No | Poll session status (SDK fallback) |
|
|
302
|
+
| `POST` | `/connect/verify` | initData | Verify session + Telegram user (TMA calls) |
|
|
303
|
+
| `POST` | `/connect/confirm` | JWT | Approve/reject session (TMA calls) |
|
|
304
|
+
| `POST` | `/connect/disconnect` | JWT | Disconnect a DApp (TMA calls) |
|
|
305
|
+
| `POST` | `/connect/disconnect-by-token` | No | Disconnect by session token (SDK calls) |
|
|
306
|
+
| `GET` | `/connect/dapps` | JWT | List connected DApps (TMA calls) |
|
|
307
|
+
|
|
308
|
+
### Register your wallet in the registry
|
|
309
|
+
|
|
310
|
+
To make your wallet available to all DApps using the SDK, add it to `registry.json`:
|
|
311
|
+
|
|
312
|
+
```json
|
|
313
|
+
{
|
|
314
|
+
"walletId": "yourwallet",
|
|
315
|
+
"name": "Your Wallet",
|
|
316
|
+
"icon": "https://your-cdn.com/icon.png",
|
|
317
|
+
"botUsername": "YourBot",
|
|
318
|
+
"appName": "app",
|
|
319
|
+
"apiUrl": "https://your-api.com",
|
|
320
|
+
"description": "Your wallet description",
|
|
321
|
+
"order": 0
|
|
322
|
+
}
|
|
155
323
|
```
|
|
156
324
|
|
|
157
325
|
## License
|