thirdweb 5.105.19 → 5.105.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/pay/buyWithCrypto/getQuote.js +8 -8
- package/dist/cjs/pay/buyWithCrypto/getQuote.js.map +1 -1
- package/dist/cjs/pay/buyWithCrypto/getTransfer.js +4 -4
- package/dist/cjs/pay/buyWithCrypto/getTransfer.js.map +1 -1
- package/dist/cjs/pay/buyWithFiat/getQuote.js +3 -3
- package/dist/cjs/pay/buyWithFiat/getQuote.js.map +1 -1
- package/dist/cjs/react/core/hooks/usePaymentMethods.js +2 -2
- package/dist/cjs/react/core/hooks/usePaymentMethods.js.map +1 -1
- package/dist/cjs/react/core/hooks/wallets/useConnect.js +10 -1
- package/dist/cjs/react/core/hooks/wallets/useConnect.js.map +1 -1
- package/dist/cjs/version.js +1 -1
- package/dist/cjs/wallets/create-wallet.js +62 -13
- package/dist/cjs/wallets/create-wallet.js.map +1 -1
- package/dist/cjs/wallets/in-app/core/wallet/in-app-core.js +3 -3
- package/dist/cjs/wallets/in-app/core/wallet/in-app-core.js.map +1 -1
- package/dist/cjs/wallets/in-app/web/in-app.js +18 -0
- package/dist/cjs/wallets/in-app/web/in-app.js.map +1 -1
- package/dist/cjs/wallets/smart/index.js +2 -2
- package/dist/cjs/wallets/smart/index.js.map +1 -1
- package/dist/cjs/wallets/smart/lib/signing.js +26 -95
- package/dist/cjs/wallets/smart/lib/signing.js.map +1 -1
- package/dist/cjs/wallets/smart/smart-wallet.js +1 -1
- package/dist/cjs/wallets/smart/smart-wallet.js.map +1 -1
- package/dist/cjs/wallets/wallet-connect/qr-overlay.js +231 -0
- package/dist/cjs/wallets/wallet-connect/qr-overlay.js.map +1 -0
- package/dist/esm/pay/buyWithCrypto/getQuote.js +8 -8
- package/dist/esm/pay/buyWithCrypto/getQuote.js.map +1 -1
- package/dist/esm/pay/buyWithCrypto/getTransfer.js +4 -4
- package/dist/esm/pay/buyWithCrypto/getTransfer.js.map +1 -1
- package/dist/esm/pay/buyWithFiat/getQuote.js +3 -3
- package/dist/esm/pay/buyWithFiat/getQuote.js.map +1 -1
- package/dist/esm/react/core/hooks/usePaymentMethods.js +2 -2
- package/dist/esm/react/core/hooks/usePaymentMethods.js.map +1 -1
- package/dist/esm/react/core/hooks/wallets/useConnect.js +10 -1
- package/dist/esm/react/core/hooks/wallets/useConnect.js.map +1 -1
- package/dist/esm/version.js +1 -1
- package/dist/esm/wallets/create-wallet.js +62 -13
- package/dist/esm/wallets/create-wallet.js.map +1 -1
- package/dist/esm/wallets/in-app/core/wallet/in-app-core.js +3 -3
- package/dist/esm/wallets/in-app/core/wallet/in-app-core.js.map +1 -1
- package/dist/esm/wallets/in-app/web/in-app.js +18 -0
- package/dist/esm/wallets/in-app/web/in-app.js.map +1 -1
- package/dist/esm/wallets/smart/index.js +2 -2
- package/dist/esm/wallets/smart/index.js.map +1 -1
- package/dist/esm/wallets/smart/lib/signing.js +27 -96
- package/dist/esm/wallets/smart/lib/signing.js.map +1 -1
- package/dist/esm/wallets/smart/smart-wallet.js +1 -1
- package/dist/esm/wallets/smart/smart-wallet.js.map +1 -1
- package/dist/esm/wallets/wallet-connect/qr-overlay.js +228 -0
- package/dist/esm/wallets/wallet-connect/qr-overlay.js.map +1 -0
- package/dist/types/react/core/hooks/wallets/useConnect.d.ts +1 -0
- package/dist/types/react/core/hooks/wallets/useConnect.d.ts.map +1 -1
- package/dist/types/version.d.ts +1 -1
- package/dist/types/wallets/create-wallet.d.ts.map +1 -1
- package/dist/types/wallets/in-app/web/in-app.d.ts +18 -0
- package/dist/types/wallets/in-app/web/in-app.d.ts.map +1 -1
- package/dist/types/wallets/smart/lib/signing.d.ts +2 -3
- package/dist/types/wallets/smart/lib/signing.d.ts.map +1 -1
- package/dist/types/wallets/wallet-connect/qr-overlay.d.ts +58 -0
- package/dist/types/wallets/wallet-connect/qr-overlay.d.ts.map +1 -0
- package/dist/types/wallets/wallet-connect/types.d.ts +13 -0
- package/dist/types/wallets/wallet-connect/types.d.ts.map +1 -1
- package/package.json +5 -3
- package/src/pay/buyWithCrypto/getQuote.ts +8 -8
- package/src/pay/buyWithCrypto/getTransfer.ts +4 -4
- package/src/pay/buyWithFiat/getQuote.ts +3 -3
- package/src/react/core/hooks/usePaymentMethods.ts +2 -2
- package/src/react/core/hooks/wallets/useConnect.ts +11 -1
- package/src/version.ts +1 -1
- package/src/wallets/create-wallet.ts +85 -24
- package/src/wallets/in-app/core/wallet/in-app-core.ts +4 -4
- package/src/wallets/in-app/web/in-app.ts +18 -0
- package/src/wallets/smart/index.ts +2 -2
- package/src/wallets/smart/lib/signing.ts +34 -121
- package/src/wallets/smart/smart-wallet-integration.test.ts +1 -76
- package/src/wallets/smart/smart-wallet.ts +1 -1
- package/src/wallets/wallet-connect/qr-overlay.ts +322 -0
- package/src/wallets/wallet-connect/types.ts +13 -0
|
@@ -0,0 +1,322 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vanilla JavaScript QR Code overlay utility for WalletConnect URIs
|
|
3
|
+
* Works in any browser context without requiring React or other frameworks
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
interface QROverlayOptions {
|
|
7
|
+
/**
|
|
8
|
+
* Custom styles to apply to the overlay
|
|
9
|
+
*/
|
|
10
|
+
overlayStyles?: Partial<CSSStyleDeclaration>;
|
|
11
|
+
/**
|
|
12
|
+
* Custom styles to apply to the modal container
|
|
13
|
+
*/
|
|
14
|
+
modalStyles?: Partial<CSSStyleDeclaration>;
|
|
15
|
+
/**
|
|
16
|
+
* QR code size in pixels
|
|
17
|
+
*/
|
|
18
|
+
qrSize?: number;
|
|
19
|
+
/**
|
|
20
|
+
* Show close button
|
|
21
|
+
*/
|
|
22
|
+
showCloseButton?: boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Custom close button text
|
|
25
|
+
*/
|
|
26
|
+
closeButtonText?: string;
|
|
27
|
+
/**
|
|
28
|
+
* Theme preference
|
|
29
|
+
*/
|
|
30
|
+
theme?: "light" | "dark";
|
|
31
|
+
/**
|
|
32
|
+
* Custom container element to append the overlay to
|
|
33
|
+
*/
|
|
34
|
+
container?: HTMLElement;
|
|
35
|
+
/**
|
|
36
|
+
* Callback called when user cancels the overlay (closes without connecting)
|
|
37
|
+
*/
|
|
38
|
+
onCancel?: () => void;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export interface QROverlay {
|
|
42
|
+
/**
|
|
43
|
+
* Remove the overlay from the DOM
|
|
44
|
+
*/
|
|
45
|
+
destroy: () => void;
|
|
46
|
+
/**
|
|
47
|
+
* Hide the overlay (without removing from DOM)
|
|
48
|
+
*/
|
|
49
|
+
hide: () => void;
|
|
50
|
+
/**
|
|
51
|
+
* Show the overlay
|
|
52
|
+
*/
|
|
53
|
+
show: () => void;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Creates a QR code overlay for the given WalletConnect URI
|
|
58
|
+
*/
|
|
59
|
+
export function createQROverlay(
|
|
60
|
+
uri: string,
|
|
61
|
+
options: QROverlayOptions = {},
|
|
62
|
+
): QROverlay {
|
|
63
|
+
const {
|
|
64
|
+
qrSize = 280,
|
|
65
|
+
showCloseButton = true,
|
|
66
|
+
closeButtonText = "×",
|
|
67
|
+
theme = "light",
|
|
68
|
+
container = document.body,
|
|
69
|
+
onCancel,
|
|
70
|
+
} = options;
|
|
71
|
+
|
|
72
|
+
// Create overlay backdrop
|
|
73
|
+
const overlay = document.createElement("div");
|
|
74
|
+
overlay.style.cssText = `
|
|
75
|
+
position: fixed;
|
|
76
|
+
inset: 0;
|
|
77
|
+
background-color: ${theme === "dark" ? "rgba(0, 0, 0, 0.8)" : "rgba(0, 0, 0, 0.5)"};
|
|
78
|
+
backdrop-filter: blur(10px);
|
|
79
|
+
z-index: 9999;
|
|
80
|
+
display: flex;
|
|
81
|
+
align-items: center;
|
|
82
|
+
justify-content: center;
|
|
83
|
+
animation: fadeIn 300ms ease-out;
|
|
84
|
+
`;
|
|
85
|
+
|
|
86
|
+
// Apply custom overlay styles
|
|
87
|
+
if (options.overlayStyles) {
|
|
88
|
+
Object.assign(overlay.style, options.overlayStyles);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// Create modal container
|
|
92
|
+
const modal = document.createElement("div");
|
|
93
|
+
modal.style.cssText = `
|
|
94
|
+
background: ${theme === "dark" ? "#1f1f1f" : "#ffffff"};
|
|
95
|
+
border-radius: 16px;
|
|
96
|
+
padding: 24px;
|
|
97
|
+
box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
|
|
98
|
+
max-width: 90vw;
|
|
99
|
+
max-height: 90vh;
|
|
100
|
+
position: relative;
|
|
101
|
+
animation: scaleIn 300ms ease-out;
|
|
102
|
+
`;
|
|
103
|
+
|
|
104
|
+
// Apply custom modal styles
|
|
105
|
+
if (options.modalStyles) {
|
|
106
|
+
Object.assign(modal.style, options.modalStyles);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// Create close button
|
|
110
|
+
if (showCloseButton) {
|
|
111
|
+
const closeButton = document.createElement("button");
|
|
112
|
+
closeButton.textContent = closeButtonText;
|
|
113
|
+
closeButton.style.cssText = `
|
|
114
|
+
position: absolute;
|
|
115
|
+
top: 16px;
|
|
116
|
+
right: 16px;
|
|
117
|
+
background: none;
|
|
118
|
+
border: none;
|
|
119
|
+
font-size: 24px;
|
|
120
|
+
cursor: pointer;
|
|
121
|
+
color: ${theme === "dark" ? "#ffffff" : "#000000"};
|
|
122
|
+
width: 32px;
|
|
123
|
+
height: 32px;
|
|
124
|
+
display: flex;
|
|
125
|
+
align-items: center;
|
|
126
|
+
justify-content: center;
|
|
127
|
+
border-radius: 8px;
|
|
128
|
+
transition: background-color 0.2s;
|
|
129
|
+
`;
|
|
130
|
+
|
|
131
|
+
closeButton.addEventListener("mouseenter", () => {
|
|
132
|
+
closeButton.style.backgroundColor =
|
|
133
|
+
theme === "dark" ? "rgba(255, 255, 255, 0.1)" : "rgba(0, 0, 0, 0.1)";
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
closeButton.addEventListener("mouseleave", () => {
|
|
137
|
+
closeButton.style.backgroundColor = "transparent";
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
closeButton.addEventListener("click", () => {
|
|
141
|
+
destroyOverlay(true);
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
modal.appendChild(closeButton);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// Create QR code container
|
|
148
|
+
const qrContainer = document.createElement("div");
|
|
149
|
+
qrContainer.style.cssText = `
|
|
150
|
+
display: flex;
|
|
151
|
+
flex-direction: column;
|
|
152
|
+
align-items: center;
|
|
153
|
+
gap: 16px;
|
|
154
|
+
`;
|
|
155
|
+
|
|
156
|
+
// Create title
|
|
157
|
+
const title = document.createElement("h3");
|
|
158
|
+
title.textContent = "Scan to Connect";
|
|
159
|
+
title.style.cssText = `
|
|
160
|
+
margin: 0;
|
|
161
|
+
font-size: 18px;
|
|
162
|
+
font-weight: 600;
|
|
163
|
+
color: ${theme === "dark" ? "#ffffff" : "#000000"};
|
|
164
|
+
text-align: center;
|
|
165
|
+
`;
|
|
166
|
+
|
|
167
|
+
// Create QR code canvas
|
|
168
|
+
const qrCanvas = document.createElement("canvas");
|
|
169
|
+
qrCanvas.width = qrSize;
|
|
170
|
+
qrCanvas.height = qrSize;
|
|
171
|
+
qrCanvas.style.cssText = `
|
|
172
|
+
border: 1px solid ${theme === "dark" ? "#333333" : "#e5e5e5"};
|
|
173
|
+
border-radius: 12px;
|
|
174
|
+
`;
|
|
175
|
+
|
|
176
|
+
// Generate QR code
|
|
177
|
+
generateQRCode(uri, qrCanvas, qrSize).catch(console.error);
|
|
178
|
+
|
|
179
|
+
// Create copy button for the URI
|
|
180
|
+
const copyButton = document.createElement("button");
|
|
181
|
+
copyButton.textContent = "Copy URI";
|
|
182
|
+
copyButton.style.cssText = `
|
|
183
|
+
background: ${theme === "dark" ? "#333333" : "#f5f5f5"};
|
|
184
|
+
border: 1px solid ${theme === "dark" ? "#444444" : "#e5e5e5"};
|
|
185
|
+
color: ${theme === "dark" ? "#ffffff" : "#000000"};
|
|
186
|
+
padding: 8px 16px;
|
|
187
|
+
border-radius: 8px;
|
|
188
|
+
cursor: pointer;
|
|
189
|
+
font-size: 14px;
|
|
190
|
+
transition: background-color 0.2s;
|
|
191
|
+
`;
|
|
192
|
+
|
|
193
|
+
copyButton.addEventListener("click", async () => {
|
|
194
|
+
try {
|
|
195
|
+
await navigator.clipboard.writeText(uri);
|
|
196
|
+
const originalText = copyButton.textContent;
|
|
197
|
+
copyButton.textContent = "Copied!";
|
|
198
|
+
setTimeout(() => {
|
|
199
|
+
copyButton.textContent = originalText;
|
|
200
|
+
}, 2000);
|
|
201
|
+
} catch (err) {
|
|
202
|
+
console.error("Failed to copy URI:", err);
|
|
203
|
+
}
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
// Assemble the modal
|
|
207
|
+
qrContainer.appendChild(title);
|
|
208
|
+
qrContainer.appendChild(qrCanvas);
|
|
209
|
+
qrContainer.appendChild(copyButton);
|
|
210
|
+
modal.appendChild(qrContainer);
|
|
211
|
+
overlay.appendChild(modal);
|
|
212
|
+
|
|
213
|
+
// Add CSS animations
|
|
214
|
+
const style = document.createElement("style");
|
|
215
|
+
style.textContent = `
|
|
216
|
+
@keyframes fadeIn {
|
|
217
|
+
from { opacity: 0; }
|
|
218
|
+
to { opacity: 1; }
|
|
219
|
+
}
|
|
220
|
+
@keyframes fadeOut {
|
|
221
|
+
from { opacity: 1; }
|
|
222
|
+
to { opacity: 0; }
|
|
223
|
+
}
|
|
224
|
+
@keyframes scaleIn {
|
|
225
|
+
from { transform: scale(0.9); opacity: 0; }
|
|
226
|
+
to { transform: scale(1); opacity: 1; }
|
|
227
|
+
}
|
|
228
|
+
@keyframes scaleOut {
|
|
229
|
+
from { transform: scale(1); opacity: 1; }
|
|
230
|
+
to { transform: scale(0.9); opacity: 0; }
|
|
231
|
+
}
|
|
232
|
+
`;
|
|
233
|
+
document.head.appendChild(style);
|
|
234
|
+
|
|
235
|
+
// Event handlers
|
|
236
|
+
const handleEscapeKey = (event: KeyboardEvent) => {
|
|
237
|
+
if (event.key === "Escape") {
|
|
238
|
+
destroyOverlay(true);
|
|
239
|
+
}
|
|
240
|
+
};
|
|
241
|
+
|
|
242
|
+
const handleOverlayClick = (event: MouseEvent) => {
|
|
243
|
+
if (event.target === overlay) {
|
|
244
|
+
destroyOverlay(true);
|
|
245
|
+
}
|
|
246
|
+
};
|
|
247
|
+
|
|
248
|
+
// Add event listeners
|
|
249
|
+
document.addEventListener("keydown", handleEscapeKey);
|
|
250
|
+
overlay.addEventListener("click", handleOverlayClick);
|
|
251
|
+
|
|
252
|
+
// Append to container
|
|
253
|
+
container.appendChild(overlay);
|
|
254
|
+
|
|
255
|
+
function destroyOverlay(userInitiated = false) {
|
|
256
|
+
document.removeEventListener("keydown", handleEscapeKey);
|
|
257
|
+
overlay.removeEventListener("click", handleOverlayClick);
|
|
258
|
+
|
|
259
|
+
// Call onCancel callback only if user initiated the close action
|
|
260
|
+
if (userInitiated && onCancel) {
|
|
261
|
+
onCancel();
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
// Animate both overlay and modal out
|
|
265
|
+
overlay.style.animation = "fadeOut 200ms ease-in";
|
|
266
|
+
modal.style.animation = "scaleOut 200ms ease-in";
|
|
267
|
+
|
|
268
|
+
const cleanup = () => {
|
|
269
|
+
if (overlay.parentNode) {
|
|
270
|
+
overlay.parentNode.removeChild(overlay);
|
|
271
|
+
}
|
|
272
|
+
if (style.parentNode) {
|
|
273
|
+
style.parentNode.removeChild(style);
|
|
274
|
+
}
|
|
275
|
+
};
|
|
276
|
+
|
|
277
|
+
overlay.addEventListener("animationend", cleanup, { once: true });
|
|
278
|
+
|
|
279
|
+
// Fallback cleanup in case animation doesn't fire
|
|
280
|
+
setTimeout(cleanup, 250);
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
function hideOverlay() {
|
|
284
|
+
overlay.style.display = "none";
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
function showOverlay() {
|
|
288
|
+
overlay.style.display = "flex";
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
return {
|
|
292
|
+
destroy: () => destroyOverlay(false), // Programmatic cleanup, don't call onCancel
|
|
293
|
+
hide: hideOverlay,
|
|
294
|
+
show: showOverlay,
|
|
295
|
+
};
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
/**
|
|
299
|
+
* QR code generator that tries to use a real QR library if available,
|
|
300
|
+
* otherwise falls back to a placeholder
|
|
301
|
+
*/
|
|
302
|
+
async function generateQRCode(
|
|
303
|
+
text: string,
|
|
304
|
+
canvas: HTMLCanvasElement,
|
|
305
|
+
size: number,
|
|
306
|
+
) {
|
|
307
|
+
const ctx = canvas.getContext("2d");
|
|
308
|
+
if (!ctx) return;
|
|
309
|
+
|
|
310
|
+
// Try to dynamically import a QR code library if available
|
|
311
|
+
// This allows the overlay to work with or without a QR code dependency
|
|
312
|
+
const { toCanvas } = await import("qrcode");
|
|
313
|
+
await toCanvas(canvas, text, {
|
|
314
|
+
width: size,
|
|
315
|
+
margin: 2,
|
|
316
|
+
color: {
|
|
317
|
+
dark: "#000000",
|
|
318
|
+
light: "#ffffff",
|
|
319
|
+
},
|
|
320
|
+
});
|
|
321
|
+
return;
|
|
322
|
+
}
|
|
@@ -157,6 +157,19 @@ export type WCConnectOptions = {
|
|
|
157
157
|
* ```
|
|
158
158
|
*/
|
|
159
159
|
onDisplayUri?: (_uri: string) => void;
|
|
160
|
+
/**
|
|
161
|
+
* Callback that gets called when the user cancels the connection process (e.g., closes the QR modal).
|
|
162
|
+
* This is only called for user-initiated cancellations, not for programmatic cleanup.
|
|
163
|
+
*
|
|
164
|
+
* ```tsx
|
|
165
|
+
* await wallet.connect({
|
|
166
|
+
* onCancel: () => {
|
|
167
|
+
* console.log("User cancelled wallet connection");
|
|
168
|
+
* }
|
|
169
|
+
* })
|
|
170
|
+
* ```
|
|
171
|
+
*/
|
|
172
|
+
onCancel?: () => void;
|
|
160
173
|
}
|
|
161
174
|
>;
|
|
162
175
|
};
|