@tomo-inc/wallet-connect-protocol 0.0.8 → 0.0.9
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/MIGRATION.md +101 -0
- package/README.md +605 -290
- package/dist/index.cjs +111 -528
- package/dist/index.d.cts +668 -148
- package/dist/index.d.ts +668 -148
- package/dist/index.js +746 -315
- package/package.json +5 -18
- package/VANILLA_JS.md +0 -491
- package/dist/chunk-32KOSJUW.js +0 -839
- package/dist/vanilla-2_OWCFEZ.d.cts +0 -705
- package/dist/vanilla-2_OWCFEZ.d.ts +0 -705
- package/dist/vanilla.cjs +0 -828
- package/dist/vanilla.d.cts +0 -1
- package/dist/vanilla.d.ts +0 -1
- package/dist/vanilla.js +0 -1
package/README.md
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
# @tomo-inc/wallet-connect-protocol
|
|
2
2
|
|
|
3
|
-
> WalletConnect Protocol SDK for Tomo Wallet -
|
|
3
|
+
> WalletConnect Protocol SDK for Tomo Wallet - Pure JavaScript / Framework-Agnostic
|
|
4
4
|
|
|
5
5
|
## 📖 Introduction
|
|
6
6
|
|
|
7
|
-
`@tomo-inc/wallet-connect-protocol` is a lightweight WalletConnect SDK designed specifically for the Tomo Wallet ecosystem. It provides a clean API
|
|
7
|
+
`@tomo-inc/wallet-connect-protocol` is a lightweight, framework-agnostic WalletConnect SDK designed specifically for the Tomo Wallet ecosystem. It provides a clean JavaScript API for integrating WalletConnect protocol into any application, regardless of the framework you use.
|
|
8
8
|
|
|
9
9
|
### ✨ Features
|
|
10
10
|
|
|
11
|
-
- 🚀 **
|
|
11
|
+
- 🚀 **Framework-Agnostic** - Works with vanilla JavaScript, Vue, Angular, Svelte, React, or any other framework
|
|
12
12
|
- 🌐 **Multi-Chain Support** - Supports Ethereum, Solana, Aptos, Cosmos, and more
|
|
13
13
|
- 📱 **QR Code Generation** - Built-in QR code generation with multiple format support
|
|
14
14
|
- 🔗 **URI Management** - Automatic generation and management of WalletConnect URIs
|
|
15
15
|
- 📦 **TypeScript Support** - Full type definitions
|
|
16
|
-
- ⚡ **Lightweight** -
|
|
17
|
-
- 🎯 **
|
|
16
|
+
- ⚡ **Lightweight** - Minimal dependencies, no framework overhead
|
|
17
|
+
- 🎯 **Simple API** - Clean, intuitive API design
|
|
18
18
|
|
|
19
19
|
## 📦 Installation
|
|
20
20
|
|
|
@@ -29,135 +29,75 @@ npm install @tomo-inc/wallet-connect-protocol
|
|
|
29
29
|
yarn add @tomo-inc/wallet-connect-protocol
|
|
30
30
|
```
|
|
31
31
|
|
|
32
|
-
## 🎯 Framework Support
|
|
33
|
-
|
|
34
|
-
This SDK supports both **React** and **non-React** frameworks:
|
|
35
|
-
|
|
36
|
-
### React Usage (Default)
|
|
37
|
-
|
|
38
|
-
```typescript
|
|
39
|
-
import {
|
|
40
|
-
WalletConnectProvider,
|
|
41
|
-
useWalletConnect,
|
|
42
|
-
} from "@tomo-inc/wallet-connect-protocol";
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
### Pure JavaScript / Non-React Usage
|
|
46
|
-
|
|
47
|
-
For vanilla JavaScript, Vue, Angular, Svelte, or any other framework:
|
|
48
|
-
|
|
49
|
-
```typescript
|
|
50
|
-
import {
|
|
51
|
-
WalletConnectClient,
|
|
52
|
-
getAllWallets,
|
|
53
|
-
} from "@tomo-inc/wallet-connect-protocol/vanilla";
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
📖 **See [VANILLA_JS.md](./VANILLA_JS.md) for complete pure JavaScript usage guide with examples for Vue, Angular, Svelte, etc.**
|
|
57
|
-
|
|
58
32
|
## 🚀 Quick Start
|
|
59
33
|
|
|
60
34
|
### 1. Get Project ID
|
|
61
35
|
|
|
62
36
|
First, obtain a free Project ID from [WalletConnect Cloud](https://cloud.walletconnect.com).
|
|
63
37
|
|
|
64
|
-
### 2.
|
|
38
|
+
### 2. Create Client
|
|
65
39
|
|
|
66
|
-
|
|
40
|
+
```typescript
|
|
41
|
+
import { WalletConnectClient } from "@tomo-inc/wallet-connect-protocol";
|
|
67
42
|
|
|
68
|
-
|
|
69
|
-
|
|
43
|
+
const client = new WalletConnectClient({
|
|
44
|
+
projectId: "YOUR_PROJECT_ID",
|
|
45
|
+
metadata: {
|
|
46
|
+
name: "My DApp",
|
|
47
|
+
description: "My awesome decentralized application",
|
|
48
|
+
url: "https://myapp.com",
|
|
49
|
+
icons: ["https://myapp.com/icon.png"],
|
|
50
|
+
},
|
|
51
|
+
});
|
|
70
52
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
<WalletConnectProvider
|
|
74
|
-
config={{
|
|
75
|
-
projectId: "YOUR_PROJECT_ID",
|
|
76
|
-
metadata: {
|
|
77
|
-
name: "My DApp",
|
|
78
|
-
description: "My awesome decentralized application",
|
|
79
|
-
url: "https://myapp.com",
|
|
80
|
-
icons: ["https://myapp.com/icon.png"],
|
|
81
|
-
},
|
|
82
|
-
}}
|
|
83
|
-
autoInit // Auto-initialize
|
|
84
|
-
>
|
|
85
|
-
<YourApp />
|
|
86
|
-
</WalletConnectProvider>
|
|
87
|
-
);
|
|
88
|
-
}
|
|
53
|
+
// Initialize the client
|
|
54
|
+
await client.initialize();
|
|
89
55
|
```
|
|
90
56
|
|
|
91
|
-
### 3.
|
|
92
|
-
|
|
93
|
-
Use the `useWalletConnect` Hook in your components:
|
|
94
|
-
|
|
95
|
-
```tsx
|
|
96
|
-
import { useWalletConnect } from "@tomo-inc/wallet-connect-protocol";
|
|
97
|
-
import { useState } from "react";
|
|
57
|
+
### 3. Connect
|
|
98
58
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
59
|
+
```typescript
|
|
60
|
+
// Create connection and get URI
|
|
61
|
+
const uri = await client.connect();
|
|
102
62
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
// Generate QR code
|
|
109
|
-
const qr = await generateQRCode(connectionUri, {
|
|
110
|
-
width: 300,
|
|
111
|
-
margin: 4,
|
|
112
|
-
});
|
|
63
|
+
// Generate QR code
|
|
64
|
+
const qrCodeBase64 = await client.generateQRCode(uri, {
|
|
65
|
+
width: 300,
|
|
66
|
+
margin: 4,
|
|
67
|
+
});
|
|
113
68
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
}
|
|
118
|
-
};
|
|
69
|
+
// Display QR code
|
|
70
|
+
document.getElementById("qr-code").src = qrCodeBase64;
|
|
71
|
+
```
|
|
119
72
|
|
|
120
|
-
|
|
121
|
-
<div>
|
|
122
|
-
<button onClick={handleConnect}>Connect Wallet</button>
|
|
73
|
+
### 4. Listen to Events
|
|
123
74
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
75
|
+
```typescript
|
|
76
|
+
// Listen for session approval
|
|
77
|
+
client.on("session_update", (session) => {
|
|
78
|
+
console.log("Session approved:", session);
|
|
79
|
+
// Handle successful connection
|
|
80
|
+
});
|
|
130
81
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
{sessions.map((session) => (
|
|
136
|
-
<li key={session.topic}>{session.peer.metadata.name}</li>
|
|
137
|
-
))}
|
|
138
|
-
</ul>
|
|
139
|
-
</div>
|
|
140
|
-
)}
|
|
141
|
-
</div>
|
|
142
|
-
);
|
|
143
|
-
}
|
|
82
|
+
// Listen for disconnection
|
|
83
|
+
client.on("session_delete", (data) => {
|
|
84
|
+
console.log("Session disconnected:", data);
|
|
85
|
+
});
|
|
144
86
|
```
|
|
145
87
|
|
|
146
88
|
## 📚 API Documentation
|
|
147
89
|
|
|
148
|
-
###
|
|
90
|
+
### WalletConnectClient
|
|
149
91
|
|
|
150
|
-
|
|
92
|
+
Core client class providing all WalletConnect functionality.
|
|
151
93
|
|
|
152
|
-
####
|
|
94
|
+
#### Constructor
|
|
153
95
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
| `autoInit` | `boolean` | ❌ | `true` | Auto-initialize on mount |
|
|
158
|
-
| `children` | `ReactNode` | ✅ | - | Child components |
|
|
96
|
+
```typescript
|
|
97
|
+
new WalletConnectClient(config: WalletConnectConfig)
|
|
98
|
+
```
|
|
159
99
|
|
|
160
|
-
|
|
100
|
+
**WalletConnectConfig:**
|
|
161
101
|
|
|
162
102
|
```typescript
|
|
163
103
|
interface WalletConnectConfig {
|
|
@@ -172,290 +112,643 @@ interface WalletConnectConfig {
|
|
|
172
112
|
}
|
|
173
113
|
```
|
|
174
114
|
|
|
175
|
-
|
|
115
|
+
#### Methods
|
|
176
116
|
|
|
177
|
-
|
|
117
|
+
##### `initialize(): Promise<void>`
|
|
178
118
|
|
|
179
|
-
|
|
119
|
+
Initialize the WalletConnect client. Must be called before any other operations.
|
|
180
120
|
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
| `initialized` | `boolean` | Whether initialized |
|
|
185
|
-
| `connecting` | `boolean` | Whether connecting |
|
|
186
|
-
| `uri` | `string \| null` | Current connection URI |
|
|
187
|
-
| `sessions` | `SessionInfo[]` | Active sessions |
|
|
188
|
-
| `initialize` | `() => Promise<void>` | Initialize client |
|
|
189
|
-
| `connect` | `() => Promise<string>` | Create connection |
|
|
190
|
-
| `generateQRCode` | `(uri: string, options?: QRCodeOptions) => Promise<string>` | Generate QR code |
|
|
191
|
-
| `disconnect` | `(topic: string) => Promise<void>` | Disconnect session |
|
|
192
|
-
| `refreshSessions` | `() => void` | Refresh session list |
|
|
121
|
+
```typescript
|
|
122
|
+
await client.initialize();
|
|
123
|
+
```
|
|
193
124
|
|
|
194
|
-
|
|
125
|
+
##### `connect(params?: ConnectParams): Promise<string>`
|
|
195
126
|
|
|
196
|
-
|
|
127
|
+
Create a pairing connection and generate WalletConnect URI.
|
|
197
128
|
|
|
198
129
|
```typescript
|
|
199
|
-
const
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
130
|
+
const uri = await client.connect();
|
|
131
|
+
|
|
132
|
+
// With custom namespaces
|
|
133
|
+
const uri = await client.connect({
|
|
134
|
+
requiredNamespaces: {
|
|
135
|
+
eip155: {
|
|
136
|
+
methods: ["eth_sendTransaction", "personal_sign"],
|
|
137
|
+
chains: ["eip155:1"],
|
|
138
|
+
events: ["chainChanged", "accountsChanged"],
|
|
139
|
+
},
|
|
140
|
+
},
|
|
204
141
|
});
|
|
205
142
|
```
|
|
206
143
|
|
|
207
|
-
|
|
144
|
+
##### `generateQRCode(uri: string, options?: QRCodeOptions): Promise<string>`
|
|
208
145
|
|
|
209
|
-
QR code
|
|
146
|
+
Generate QR code as Base64 data URL.
|
|
210
147
|
|
|
211
148
|
```typescript
|
|
212
|
-
const
|
|
149
|
+
const qrCode = await client.generateQRCode(uri, {
|
|
213
150
|
width: 300,
|
|
214
151
|
margin: 4,
|
|
152
|
+
errorCorrectionLevel: "M",
|
|
153
|
+
color: {
|
|
154
|
+
dark: "#000000",
|
|
155
|
+
light: "#ffffff",
|
|
156
|
+
},
|
|
215
157
|
});
|
|
216
158
|
```
|
|
217
159
|
|
|
218
|
-
|
|
160
|
+
**QRCodeOptions:**
|
|
219
161
|
|
|
220
|
-
|
|
162
|
+
```typescript
|
|
163
|
+
interface QRCodeOptions {
|
|
164
|
+
width?: number; // QR code width (default: 300)
|
|
165
|
+
margin?: number; // Margin size (default: 4)
|
|
166
|
+
errorCorrectionLevel?: "L" | "M" | "Q" | "H"; // Error correction (default: 'M')
|
|
167
|
+
color?: {
|
|
168
|
+
dark?: string; // Dark color (default: '#000000')
|
|
169
|
+
light?: string; // Light color (default: '#ffffff')
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
##### `generateQRCodeToCanvas(canvas: HTMLCanvasElement, uri: string, options?: QRCodeOptions): Promise<void>`
|
|
175
|
+
|
|
176
|
+
Generate QR code directly to a canvas element.
|
|
221
177
|
|
|
222
178
|
```typescript
|
|
223
|
-
const
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
isExpired, // Whether expired
|
|
229
|
-
getAccounts, // Get accounts
|
|
230
|
-
getChains, // Get chains
|
|
231
|
-
hasSession, // Has session
|
|
232
|
-
} = useSession(topic);
|
|
179
|
+
const canvas = document.getElementById("qr-canvas") as HTMLCanvasElement;
|
|
180
|
+
await client.generateQRCodeToCanvas(canvas, uri, {
|
|
181
|
+
width: 300,
|
|
182
|
+
margin: 4,
|
|
183
|
+
});
|
|
233
184
|
```
|
|
234
185
|
|
|
235
|
-
|
|
186
|
+
##### `getActiveSessions(): SessionInfo[]`
|
|
236
187
|
|
|
237
|
-
|
|
188
|
+
Get all active WalletConnect sessions.
|
|
238
189
|
|
|
239
|
-
|
|
190
|
+
```typescript
|
|
191
|
+
const sessions = client.getActiveSessions();
|
|
192
|
+
sessions.forEach((session) => {
|
|
193
|
+
console.log("Session:", session.topic);
|
|
194
|
+
console.log("Peer:", session.peer.metadata.name);
|
|
195
|
+
console.log("Chains:", session.namespaces);
|
|
196
|
+
});
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
##### `disconnectSession(topic: string): Promise<void>`
|
|
200
|
+
|
|
201
|
+
Disconnect a specific session.
|
|
240
202
|
|
|
241
203
|
```typescript
|
|
242
|
-
|
|
243
|
-
|
|
204
|
+
await client.disconnectSession(sessionTopic);
|
|
205
|
+
```
|
|
244
206
|
|
|
245
|
-
|
|
246
|
-
const uri = await client.connect();
|
|
207
|
+
##### `sendRequest(params): Promise<any>`
|
|
247
208
|
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
209
|
+
Send JSON-RPC request to the connected wallet.
|
|
210
|
+
|
|
211
|
+
```typescript
|
|
212
|
+
const result = await client.sendRequest({
|
|
213
|
+
topic: sessionTopic,
|
|
214
|
+
chainId: "eip155:1",
|
|
215
|
+
request: {
|
|
216
|
+
method: "personal_sign",
|
|
217
|
+
params: ["0x...message", "0x...address"],
|
|
257
218
|
},
|
|
258
219
|
});
|
|
220
|
+
```
|
|
259
221
|
|
|
260
|
-
|
|
261
|
-
await client.generateQRCodeToCanvas(canvasElement, uri);
|
|
262
|
-
|
|
263
|
-
// Get active sessions
|
|
264
|
-
const sessions = client.getActiveSessions();
|
|
222
|
+
##### `on<T>(event: WalletConnectEvent, handler: EventHandler<T>): void`
|
|
265
223
|
|
|
266
|
-
|
|
267
|
-
await client.disconnectSession(topic);
|
|
224
|
+
Listen to WalletConnect events.
|
|
268
225
|
|
|
269
|
-
|
|
226
|
+
```typescript
|
|
270
227
|
client.on("session_proposal", (proposal) => {
|
|
271
|
-
console.log("Session proposal
|
|
228
|
+
console.log("Session proposal:", proposal);
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
client.on("session_update", (session) => {
|
|
232
|
+
console.log("Session updated:", session);
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
client.on("session_delete", (data) => {
|
|
236
|
+
console.log("Session deleted:", data);
|
|
272
237
|
});
|
|
273
238
|
|
|
274
239
|
client.on("display_uri", ({ uri }) => {
|
|
275
240
|
console.log("WalletConnect URI:", uri);
|
|
276
241
|
});
|
|
242
|
+
```
|
|
277
243
|
|
|
278
|
-
|
|
279
|
-
client.off("session_proposal", handler);
|
|
244
|
+
**Available Events:**
|
|
280
245
|
|
|
281
|
-
|
|
282
|
-
|
|
246
|
+
- `session_proposal` - New session proposal received
|
|
247
|
+
- `session_update` - Session updated or approved
|
|
248
|
+
- `session_delete` - Session disconnected
|
|
249
|
+
- `session_request` - Request received from wallet
|
|
250
|
+
- `display_uri` - URI generated and ready to display
|
|
251
|
+
|
|
252
|
+
##### `off<T>(event: WalletConnectEvent, handler: EventHandler<T>): void`
|
|
253
|
+
|
|
254
|
+
Remove event listener.
|
|
255
|
+
|
|
256
|
+
```typescript
|
|
257
|
+
const handler = (data) => console.log(data);
|
|
258
|
+
client.on("session_update", handler);
|
|
259
|
+
client.off("session_update", handler);
|
|
283
260
|
```
|
|
284
261
|
|
|
285
|
-
|
|
262
|
+
##### `destroy(): Promise<void>`
|
|
286
263
|
|
|
287
|
-
|
|
264
|
+
Destroy the client and clean up resources.
|
|
288
265
|
|
|
289
|
-
```
|
|
290
|
-
|
|
291
|
-
|
|
266
|
+
```typescript
|
|
267
|
+
await client.destroy();
|
|
268
|
+
```
|
|
292
269
|
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
270
|
+
##### `isInitialized(): boolean`
|
|
271
|
+
|
|
272
|
+
Check if the client is initialized.
|
|
273
|
+
|
|
274
|
+
```typescript
|
|
275
|
+
if (client.isInitialized()) {
|
|
276
|
+
// Client is ready
|
|
299
277
|
}
|
|
300
278
|
```
|
|
301
279
|
|
|
302
|
-
|
|
280
|
+
##### `getConfig(): WalletConnectConfig`
|
|
303
281
|
|
|
304
|
-
|
|
305
|
-
function QRCodeConnect() {
|
|
306
|
-
const { connect, generateQRCode } = useWalletConnect();
|
|
307
|
-
const [qr, setQr] = useState<string | null>(null);
|
|
282
|
+
Get the current configuration.
|
|
308
283
|
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
};
|
|
284
|
+
```typescript
|
|
285
|
+
const config = client.getConfig();
|
|
286
|
+
console.log("Project ID:", config.projectId);
|
|
287
|
+
```
|
|
314
288
|
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
289
|
+
## 🎯 Usage Examples
|
|
290
|
+
|
|
291
|
+
### Vanilla JavaScript
|
|
292
|
+
|
|
293
|
+
```html
|
|
294
|
+
<!DOCTYPE html>
|
|
295
|
+
<html>
|
|
296
|
+
<head>
|
|
297
|
+
<title>WalletConnect Example</title>
|
|
298
|
+
</head>
|
|
299
|
+
<body>
|
|
300
|
+
<button id="connect-btn">Connect Wallet</button>
|
|
301
|
+
<div id="qr-container" style="display: none;">
|
|
302
|
+
<h3>Scan QR Code</h3>
|
|
303
|
+
<img id="qr-code" />
|
|
319
304
|
</div>
|
|
320
|
-
|
|
321
|
-
}
|
|
322
|
-
```
|
|
305
|
+
<div id="session-info"></div>
|
|
323
306
|
|
|
324
|
-
|
|
307
|
+
<script type="module">
|
|
308
|
+
import { WalletConnectClient } from "@tomo-inc/wallet-connect-protocol";
|
|
325
309
|
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
310
|
+
const client = new WalletConnectClient({
|
|
311
|
+
projectId: "YOUR_PROJECT_ID",
|
|
312
|
+
metadata: {
|
|
313
|
+
name: "My DApp",
|
|
314
|
+
description: "Example DApp",
|
|
315
|
+
url: "https://myapp.com",
|
|
316
|
+
icons: ["https://myapp.com/icon.png"],
|
|
317
|
+
},
|
|
318
|
+
});
|
|
329
319
|
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
320
|
+
await client.initialize();
|
|
321
|
+
|
|
322
|
+
document
|
|
323
|
+
.getElementById("connect-btn")
|
|
324
|
+
.addEventListener("click", async () => {
|
|
325
|
+
const uri = await client.connect();
|
|
326
|
+
const qrCode = await client.generateQRCode(uri);
|
|
327
|
+
|
|
328
|
+
document.getElementById("qr-code").src = qrCode;
|
|
329
|
+
document.getElementById("qr-container").style.display = "block";
|
|
330
|
+
});
|
|
331
|
+
|
|
332
|
+
client.on("session_update", (session) => {
|
|
333
|
+
document.getElementById("session-info").innerHTML =
|
|
334
|
+
`Connected to: ${session.peer.metadata.name}`;
|
|
335
|
+
document.getElementById("qr-container").style.display = "none";
|
|
336
|
+
});
|
|
337
|
+
</script>
|
|
338
|
+
</body>
|
|
339
|
+
</html>
|
|
343
340
|
```
|
|
344
341
|
|
|
345
|
-
###
|
|
342
|
+
### Vue 3
|
|
346
343
|
|
|
347
|
-
|
|
344
|
+
```vue
|
|
345
|
+
<template>
|
|
346
|
+
<div>
|
|
347
|
+
<button @click="handleConnect">Connect Wallet</button>
|
|
348
|
+
<div v-if="qrCode">
|
|
349
|
+
<h3>Scan QR Code</h3>
|
|
350
|
+
<img :src="qrCode" />
|
|
351
|
+
</div>
|
|
352
|
+
<div v-if="sessions.length > 0">
|
|
353
|
+
<h3>Connected Sessions</h3>
|
|
354
|
+
<ul>
|
|
355
|
+
<li v-for="session in sessions" :key="session.topic">
|
|
356
|
+
{{ session.peer.metadata.name }}
|
|
357
|
+
<button @click="disconnect(session.topic)">Disconnect</button>
|
|
358
|
+
</li>
|
|
359
|
+
</ul>
|
|
360
|
+
</div>
|
|
361
|
+
</div>
|
|
362
|
+
</template>
|
|
348
363
|
|
|
349
|
-
|
|
364
|
+
<script setup lang="ts">
|
|
365
|
+
import { ref, onMounted, onUnmounted } from "vue";
|
|
350
366
|
import { WalletConnectClient } from "@tomo-inc/wallet-connect-protocol";
|
|
351
367
|
|
|
352
368
|
const client = new WalletConnectClient({
|
|
353
369
|
projectId: "YOUR_PROJECT_ID",
|
|
354
370
|
metadata: {
|
|
355
|
-
name: "My
|
|
356
|
-
description: "
|
|
371
|
+
name: "My Vue DApp",
|
|
372
|
+
description: "Example Vue DApp",
|
|
357
373
|
url: "https://myapp.com",
|
|
358
374
|
icons: ["https://myapp.com/icon.png"],
|
|
359
375
|
},
|
|
360
376
|
});
|
|
361
377
|
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
// Listen to events
|
|
366
|
-
client.on("session_proposal", (proposal) => {
|
|
367
|
-
console.log("Session proposal:", proposal);
|
|
368
|
-
});
|
|
378
|
+
const qrCode = ref<string | null>(null);
|
|
379
|
+
const sessions = ref<any[]>([]);
|
|
369
380
|
|
|
370
|
-
|
|
371
|
-
|
|
381
|
+
onMounted(async () => {
|
|
382
|
+
await client.initialize();
|
|
372
383
|
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
384
|
+
client.on("session_update", (session) => {
|
|
385
|
+
sessions.value = client.getActiveSessions();
|
|
386
|
+
qrCode.value = null;
|
|
387
|
+
});
|
|
388
|
+
});
|
|
376
389
|
|
|
377
|
-
|
|
390
|
+
const handleConnect = async () => {
|
|
391
|
+
const uri = await client.connect();
|
|
392
|
+
qrCode.value = await client.generateQRCode(uri);
|
|
393
|
+
};
|
|
378
394
|
|
|
379
|
-
|
|
395
|
+
const disconnect = async (topic: string) => {
|
|
396
|
+
await client.disconnectSession(topic);
|
|
397
|
+
sessions.value = client.getActiveSessions();
|
|
398
|
+
};
|
|
380
399
|
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
width: 400,
|
|
384
|
-
height: 400,
|
|
385
|
-
margin: 8,
|
|
386
|
-
errorCorrectionLevel: "H", // 'L' | 'M' | 'Q' | 'H'
|
|
387
|
-
color: {
|
|
388
|
-
dark: "#1a1a1a",
|
|
389
|
-
light: "#ffffff",
|
|
390
|
-
},
|
|
400
|
+
onUnmounted(async () => {
|
|
401
|
+
await client.destroy();
|
|
391
402
|
});
|
|
403
|
+
</script>
|
|
392
404
|
```
|
|
393
405
|
|
|
394
|
-
###
|
|
406
|
+
### Angular
|
|
395
407
|
|
|
396
|
-
```
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
</WalletConnectProvider>;
|
|
408
|
+
```typescript
|
|
409
|
+
import { Component, OnInit, OnDestroy } from "@angular/core";
|
|
410
|
+
import {
|
|
411
|
+
WalletConnectClient,
|
|
412
|
+
SessionInfo,
|
|
413
|
+
} from "@tomo-inc/wallet-connect-protocol";
|
|
403
414
|
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
415
|
+
@Component({
|
|
416
|
+
selector: "app-wallet-connect",
|
|
417
|
+
template: `
|
|
418
|
+
<button (click)="handleConnect()">Connect Wallet</button>
|
|
419
|
+
<div *ngIf="qrCode">
|
|
420
|
+
<h3>Scan QR Code</h3>
|
|
421
|
+
<img [src]="qrCode" />
|
|
422
|
+
</div>
|
|
423
|
+
<div *ngIf="sessions.length > 0">
|
|
424
|
+
<h3>Connected Sessions</h3>
|
|
425
|
+
<ul>
|
|
426
|
+
<li *ngFor="let session of sessions">
|
|
427
|
+
{{ session.peer.metadata.name }}
|
|
428
|
+
<button (click)="disconnect(session.topic)">Disconnect</button>
|
|
429
|
+
</li>
|
|
430
|
+
</ul>
|
|
431
|
+
</div>
|
|
432
|
+
`,
|
|
433
|
+
})
|
|
434
|
+
export class WalletConnectComponent implements OnInit, OnDestroy {
|
|
435
|
+
private client: WalletConnectClient;
|
|
436
|
+
qrCode: string | null = null;
|
|
437
|
+
sessions: SessionInfo[] = [];
|
|
438
|
+
|
|
439
|
+
constructor() {
|
|
440
|
+
this.client = new WalletConnectClient({
|
|
441
|
+
projectId: "YOUR_PROJECT_ID",
|
|
442
|
+
metadata: {
|
|
443
|
+
name: "My Angular DApp",
|
|
444
|
+
description: "Example Angular DApp",
|
|
445
|
+
url: "https://myapp.com",
|
|
446
|
+
icons: ["https://myapp.com/icon.png"],
|
|
447
|
+
},
|
|
448
|
+
});
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
async ngOnInit() {
|
|
452
|
+
await this.client.initialize();
|
|
453
|
+
|
|
454
|
+
this.client.on("session_update", () => {
|
|
455
|
+
this.sessions = this.client.getActiveSessions();
|
|
456
|
+
this.qrCode = null;
|
|
457
|
+
});
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
async handleConnect() {
|
|
461
|
+
const uri = await this.client.connect();
|
|
462
|
+
this.qrCode = await this.client.generateQRCode(uri);
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
async disconnect(topic: string) {
|
|
466
|
+
await this.client.disconnectSession(topic);
|
|
467
|
+
this.sessions = this.client.getActiveSessions();
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
async ngOnDestroy() {
|
|
471
|
+
await this.client.destroy();
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
```
|
|
407
475
|
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
476
|
+
### Svelte
|
|
477
|
+
|
|
478
|
+
```svelte
|
|
479
|
+
<script lang="ts">
|
|
480
|
+
import { onMount, onDestroy } from 'svelte';
|
|
481
|
+
import { WalletConnectClient } from '@tomo-inc/wallet-connect-protocol';
|
|
482
|
+
|
|
483
|
+
let client: WalletConnectClient;
|
|
484
|
+
let qrCode: string | null = null;
|
|
485
|
+
let sessions: any[] = [];
|
|
486
|
+
|
|
487
|
+
onMount(async () => {
|
|
488
|
+
client = new WalletConnectClient({
|
|
489
|
+
projectId: 'YOUR_PROJECT_ID',
|
|
490
|
+
metadata: {
|
|
491
|
+
name: 'My Svelte DApp',
|
|
492
|
+
description: 'Example Svelte DApp',
|
|
493
|
+
url: 'https://myapp.com',
|
|
494
|
+
icons: ['https://myapp.com/icon.png'],
|
|
495
|
+
},
|
|
496
|
+
});
|
|
497
|
+
|
|
498
|
+
await client.initialize();
|
|
499
|
+
|
|
500
|
+
client.on('session_update', () => {
|
|
501
|
+
sessions = client.getActiveSessions();
|
|
502
|
+
qrCode = null;
|
|
503
|
+
});
|
|
504
|
+
});
|
|
505
|
+
|
|
506
|
+
async function handleConnect() {
|
|
507
|
+
const uri = await client.connect();
|
|
508
|
+
qrCode = await client.generateQRCode(uri);
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
async function disconnect(topic: string) {
|
|
512
|
+
await client.disconnectSession(topic);
|
|
513
|
+
sessions = client.getActiveSessions();
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
onDestroy(async () => {
|
|
517
|
+
if (client) {
|
|
518
|
+
await client.destroy();
|
|
411
519
|
}
|
|
412
|
-
}
|
|
413
|
-
|
|
520
|
+
});
|
|
521
|
+
</script>
|
|
522
|
+
|
|
523
|
+
<button on:click={handleConnect}>Connect Wallet</button>
|
|
524
|
+
|
|
525
|
+
{#if qrCode}
|
|
526
|
+
<div>
|
|
527
|
+
<h3>Scan QR Code</h3>
|
|
528
|
+
<img src={qrCode} alt="WalletConnect QR Code" />
|
|
529
|
+
</div>
|
|
530
|
+
{/if}
|
|
531
|
+
|
|
532
|
+
{#if sessions.length > 0}
|
|
533
|
+
<div>
|
|
534
|
+
<h3>Connected Sessions</h3>
|
|
535
|
+
<ul>
|
|
536
|
+
{#each sessions as session}
|
|
537
|
+
<li>
|
|
538
|
+
{session.peer.metadata.name}
|
|
539
|
+
<button on:click={() => disconnect(session.topic)}>Disconnect</button>
|
|
540
|
+
</li>
|
|
541
|
+
{/each}
|
|
542
|
+
</ul>
|
|
543
|
+
</div>
|
|
544
|
+
{/if}
|
|
414
545
|
```
|
|
415
546
|
|
|
416
|
-
###
|
|
547
|
+
### React
|
|
417
548
|
|
|
418
549
|
```tsx
|
|
419
|
-
|
|
420
|
-
|
|
550
|
+
import { useEffect, useState } from "react";
|
|
551
|
+
import {
|
|
552
|
+
WalletConnectClient,
|
|
553
|
+
SessionInfo,
|
|
554
|
+
} from "@tomo-inc/wallet-connect-protocol";
|
|
421
555
|
|
|
422
|
-
|
|
423
|
-
|
|
556
|
+
function WalletConnect() {
|
|
557
|
+
const [client] = useState(
|
|
558
|
+
() =>
|
|
559
|
+
new WalletConnectClient({
|
|
560
|
+
projectId: "YOUR_PROJECT_ID",
|
|
561
|
+
metadata: {
|
|
562
|
+
name: "My React DApp",
|
|
563
|
+
description: "Example React DApp",
|
|
564
|
+
url: "https://myapp.com",
|
|
565
|
+
icons: ["https://myapp.com/icon.png"],
|
|
566
|
+
},
|
|
567
|
+
}),
|
|
568
|
+
);
|
|
424
569
|
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
570
|
+
const [qrCode, setQrCode] = useState<string | null>(null);
|
|
571
|
+
const [sessions, setSessions] = useState<SessionInfo[]>([]);
|
|
572
|
+
|
|
573
|
+
useEffect(() => {
|
|
574
|
+
client.initialize();
|
|
428
575
|
|
|
429
|
-
const
|
|
430
|
-
|
|
576
|
+
const handleSessionUpdate = () => {
|
|
577
|
+
setSessions(client.getActiveSessions());
|
|
578
|
+
setQrCode(null);
|
|
431
579
|
};
|
|
432
580
|
|
|
433
|
-
client.on("
|
|
434
|
-
client.on("session_request", handleRequest);
|
|
581
|
+
client.on("session_update", handleSessionUpdate);
|
|
435
582
|
|
|
436
583
|
return () => {
|
|
437
|
-
client.off("
|
|
438
|
-
client.
|
|
584
|
+
client.off("session_update", handleSessionUpdate);
|
|
585
|
+
client.destroy();
|
|
439
586
|
};
|
|
440
587
|
}, [client]);
|
|
441
588
|
|
|
442
|
-
|
|
589
|
+
const handleConnect = async () => {
|
|
590
|
+
const uri = await client.connect();
|
|
591
|
+
const qr = await client.generateQRCode(uri);
|
|
592
|
+
setQrCode(qr);
|
|
593
|
+
};
|
|
594
|
+
|
|
595
|
+
const disconnect = async (topic: string) => {
|
|
596
|
+
await client.disconnectSession(topic);
|
|
597
|
+
setSessions(client.getActiveSessions());
|
|
598
|
+
};
|
|
599
|
+
|
|
600
|
+
return (
|
|
601
|
+
<div>
|
|
602
|
+
<button onClick={handleConnect}>Connect Wallet</button>
|
|
603
|
+
{qrCode && (
|
|
604
|
+
<div>
|
|
605
|
+
<h3>Scan QR Code</h3>
|
|
606
|
+
<img src={qrCode} alt="WalletConnect QR Code" />
|
|
607
|
+
</div>
|
|
608
|
+
)}
|
|
609
|
+
{sessions.length > 0 && (
|
|
610
|
+
<div>
|
|
611
|
+
<h3>Connected Sessions</h3>
|
|
612
|
+
<ul>
|
|
613
|
+
{sessions.map((session) => (
|
|
614
|
+
<li key={session.topic}>
|
|
615
|
+
{session.peer.metadata.name}
|
|
616
|
+
<button onClick={() => disconnect(session.topic)}>
|
|
617
|
+
Disconnect
|
|
618
|
+
</button>
|
|
619
|
+
</li>
|
|
620
|
+
))}
|
|
621
|
+
</ul>
|
|
622
|
+
</div>
|
|
623
|
+
)}
|
|
624
|
+
</div>
|
|
625
|
+
);
|
|
443
626
|
}
|
|
444
627
|
```
|
|
445
628
|
|
|
446
|
-
##
|
|
629
|
+
## 🔧 Advanced Usage
|
|
447
630
|
|
|
448
|
-
|
|
631
|
+
### Multi-Chain Support
|
|
449
632
|
|
|
450
|
-
|
|
633
|
+
```typescript
|
|
634
|
+
import {
|
|
635
|
+
createMultiChainNamespaces,
|
|
636
|
+
EVM_CHAINS,
|
|
637
|
+
SOLANA_CHAINS,
|
|
638
|
+
} from "@tomo-inc/wallet-connect-protocol";
|
|
451
639
|
|
|
452
|
-
|
|
640
|
+
// Create multi-chain namespaces configuration
|
|
641
|
+
const namespaces = createMultiChainNamespaces({
|
|
642
|
+
evm: {
|
|
643
|
+
chains: [EVM_CHAINS.ethereum, EVM_CHAINS.polygon],
|
|
644
|
+
methods: ["eth_sendTransaction", "personal_sign"],
|
|
645
|
+
},
|
|
646
|
+
solana: {
|
|
647
|
+
chains: [SOLANA_CHAINS.mainnet],
|
|
648
|
+
methods: ["solana_signTransaction", "solana_signMessage"],
|
|
649
|
+
},
|
|
650
|
+
});
|
|
453
651
|
|
|
454
|
-
|
|
652
|
+
const uri = await client.connect({
|
|
653
|
+
requiredNamespaces: namespaces,
|
|
654
|
+
});
|
|
655
|
+
```
|
|
455
656
|
|
|
456
|
-
-
|
|
457
|
-
|
|
458
|
-
|
|
657
|
+
### SIWE (Sign-In with Ethereum)
|
|
658
|
+
|
|
659
|
+
```typescript
|
|
660
|
+
import { SiweAuth, createSiweMessage } from "@tomo-inc/wallet-connect-protocol";
|
|
661
|
+
|
|
662
|
+
const siwe = new SiweAuth({
|
|
663
|
+
domain: "myapp.com",
|
|
664
|
+
uri: "https://myapp.com",
|
|
665
|
+
statement: "Sign in to My DApp",
|
|
666
|
+
});
|
|
667
|
+
|
|
668
|
+
// Create SIWE message
|
|
669
|
+
const message = createSiweMessage({
|
|
670
|
+
domain: "myapp.com",
|
|
671
|
+
address: "0x...",
|
|
672
|
+
chainId: 1,
|
|
673
|
+
uri: "https://myapp.com",
|
|
674
|
+
statement: "Sign in to My DApp",
|
|
675
|
+
});
|
|
676
|
+
|
|
677
|
+
// Request signature from wallet
|
|
678
|
+
const signature = await client.sendRequest({
|
|
679
|
+
topic: sessionTopic,
|
|
680
|
+
chainId: "eip155:1",
|
|
681
|
+
request: {
|
|
682
|
+
method: "personal_sign",
|
|
683
|
+
params: [message, address],
|
|
684
|
+
},
|
|
685
|
+
});
|
|
686
|
+
|
|
687
|
+
// Verify signature
|
|
688
|
+
const isValid = await siwe.verify(message, signature);
|
|
689
|
+
```
|
|
690
|
+
|
|
691
|
+
### Custom QR Code Styling
|
|
692
|
+
|
|
693
|
+
```typescript
|
|
694
|
+
const qrCode = await client.generateQRCode(uri, {
|
|
695
|
+
width: 400,
|
|
696
|
+
margin: 8,
|
|
697
|
+
errorCorrectionLevel: "H",
|
|
698
|
+
color: {
|
|
699
|
+
dark: "#1a1a1a",
|
|
700
|
+
light: "#f0f0f0",
|
|
701
|
+
},
|
|
702
|
+
});
|
|
703
|
+
```
|
|
704
|
+
|
|
705
|
+
### Wallet Discovery
|
|
706
|
+
|
|
707
|
+
```typescript
|
|
708
|
+
import {
|
|
709
|
+
getAllWallets,
|
|
710
|
+
getRecommendedWallets,
|
|
711
|
+
searchWallets,
|
|
712
|
+
} from "@tomo-inc/wallet-connect-protocol";
|
|
713
|
+
|
|
714
|
+
// Get all available wallets
|
|
715
|
+
const allWallets = await getAllWallets();
|
|
716
|
+
|
|
717
|
+
// Get recommended wallets
|
|
718
|
+
const recommended = await getRecommendedWallets();
|
|
719
|
+
|
|
720
|
+
// Search for specific wallets
|
|
721
|
+
const results = await searchWallets("metamask");
|
|
722
|
+
```
|
|
723
|
+
|
|
724
|
+
## 🌐 Utility Functions
|
|
725
|
+
|
|
726
|
+
The SDK provides various utility functions:
|
|
727
|
+
|
|
728
|
+
```typescript
|
|
729
|
+
import {
|
|
730
|
+
formatAddress, // Format address: 0x1234...5678
|
|
731
|
+
isValidWalletConnectUri, // Validate WC URI
|
|
732
|
+
parseWalletConnectUri, // Parse WC URI
|
|
733
|
+
extractChainIdFromAccount, // Extract chain ID from account
|
|
734
|
+
extractAddressFromAccount, // Extract address from account
|
|
735
|
+
isSessionExpired, // Check if session expired
|
|
736
|
+
getSessionTimeRemaining, // Get remaining session time
|
|
737
|
+
generateDeepLink, // Generate wallet deep link
|
|
738
|
+
isMobile, // Check if on mobile device
|
|
739
|
+
copyToClipboard, // Copy text to clipboard
|
|
740
|
+
} from "@tomo-inc/wallet-connect-protocol";
|
|
741
|
+
|
|
742
|
+
// Example usage
|
|
743
|
+
const shortAddress = formatAddress("0x1234567890abcdef");
|
|
744
|
+
// Returns: '0x1234...cdef'
|
|
745
|
+
|
|
746
|
+
const isValid = isValidWalletConnectUri(uri);
|
|
747
|
+
// Returns: true or false
|
|
748
|
+
|
|
749
|
+
const deepLink = generateDeepLink("metamask", uri);
|
|
750
|
+
// Returns: 'metamask://wc?uri=...'
|
|
751
|
+
```
|
|
459
752
|
|
|
460
753
|
## ❓ FAQ
|
|
461
754
|
|
|
@@ -471,9 +764,9 @@ Ensure dependencies are correctly installed and the URI is a valid WalletConnect
|
|
|
471
764
|
|
|
472
765
|
Use try-catch to handle errors:
|
|
473
766
|
|
|
474
|
-
```
|
|
767
|
+
```typescript
|
|
475
768
|
try {
|
|
476
|
-
await connect();
|
|
769
|
+
await client.connect();
|
|
477
770
|
} catch (error) {
|
|
478
771
|
console.error("Connection failed:", error);
|
|
479
772
|
// Handle error, e.g., show error message
|
|
@@ -484,6 +777,28 @@ try {
|
|
|
484
777
|
|
|
485
778
|
All modern browsers (Chrome, Firefox, Safari, Edge) are supported. ES2022+ support required.
|
|
486
779
|
|
|
780
|
+
### Can I use this with React?
|
|
781
|
+
|
|
782
|
+
Yes! This SDK is framework-agnostic and works perfectly with React. See the React example above.
|
|
783
|
+
|
|
784
|
+
### How do I support multiple chains?
|
|
785
|
+
|
|
786
|
+
Use the `createMultiChainNamespaces` utility to configure support for multiple blockchain networks.
|
|
787
|
+
|
|
788
|
+
## 🤝 Contributing
|
|
789
|
+
|
|
790
|
+
Contributions are welcome! Please check our [Contributing Guide](../../CONTRIBUTING.md) for more information.
|
|
791
|
+
|
|
792
|
+
## 📄 License
|
|
793
|
+
|
|
794
|
+
MIT © [Tomo Inc.](https://tomo.inc)
|
|
795
|
+
|
|
796
|
+
## 🔗 Related Links
|
|
797
|
+
|
|
798
|
+
- [WalletConnect Official Documentation](https://docs.walletconnect.com/)
|
|
799
|
+
- [WalletConnect Cloud](https://cloud.walletconnect.com)
|
|
800
|
+
- [Tomo Wallet](https://tomo.inc)
|
|
801
|
+
|
|
487
802
|
## 📞 Support
|
|
488
803
|
|
|
489
804
|
For questions or suggestions, please [submit an issue](https://github.com/tomo-inc/tomo-wallet/issues).
|