@swype-org/deposit 0.3.13 → 0.3.15
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/{chunk-7Y4RWJI3.js → chunk-MA7CVDFD.js} +518 -29
- package/dist/chunk-MA7CVDFD.js.map +1 -0
- package/dist/index.cjs +520 -26
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +160 -3
- package/dist/index.d.ts +160 -3
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/react.cjs +515 -26
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +2 -2
- package/dist/react.d.ts +2 -2
- package/dist/react.js +2 -2
- package/dist/{types-CCi4cpnQ.d.cts → types-DYsZwNXq.d.cts} +10 -3
- package/dist/{types-CCi4cpnQ.d.ts → types-DYsZwNXq.d.ts} +10 -3
- package/package.json +2 -2
- package/dist/chunk-7Y4RWJI3.js.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -90,6 +90,414 @@ function parseCloseRequest(data) {
|
|
|
90
90
|
}
|
|
91
91
|
return { type: "blink:close-request" };
|
|
92
92
|
}
|
|
93
|
+
function parseIframeReady(data) {
|
|
94
|
+
if (!data || typeof data !== "object") {
|
|
95
|
+
return null;
|
|
96
|
+
}
|
|
97
|
+
const msg = data;
|
|
98
|
+
if (msg.type !== "blink:iframe-ready") {
|
|
99
|
+
return null;
|
|
100
|
+
}
|
|
101
|
+
return { type: "blink:iframe-ready" };
|
|
102
|
+
}
|
|
103
|
+
function buildSignedPayloadMessage(merchantId, payload, signature) {
|
|
104
|
+
return {
|
|
105
|
+
type: "blink:signed-payload",
|
|
106
|
+
merchantId,
|
|
107
|
+
payload,
|
|
108
|
+
signature
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// src/walletBridge/discover.ts
|
|
113
|
+
function createWalletDiscoverer() {
|
|
114
|
+
if (typeof window === "undefined") {
|
|
115
|
+
return makeNoopHandle();
|
|
116
|
+
}
|
|
117
|
+
const registry = /* @__PURE__ */ new Map();
|
|
118
|
+
const listeners = /* @__PURE__ */ new Set();
|
|
119
|
+
let destroyed = false;
|
|
120
|
+
const onAnnounce = (event) => {
|
|
121
|
+
if (destroyed) return;
|
|
122
|
+
const detail = event.detail;
|
|
123
|
+
if (!isValidProviderDetail(detail)) {
|
|
124
|
+
console.info("[blink-bridge:parent] dropping malformed EIP-6963 announcement", {
|
|
125
|
+
rawInfo: event.detail && event.detail.info
|
|
126
|
+
});
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
const existing = registry.get(detail.info.uuid);
|
|
130
|
+
if (existing && existing.provider === detail.provider) {
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
console.info("[blink-bridge:parent] EIP-6963 announceProvider", {
|
|
134
|
+
rdns: detail.info.rdns,
|
|
135
|
+
name: detail.info.name,
|
|
136
|
+
uuid: detail.info.uuid
|
|
137
|
+
});
|
|
138
|
+
registry.set(detail.info.uuid, {
|
|
139
|
+
info: { ...detail.info },
|
|
140
|
+
provider: detail.provider
|
|
141
|
+
});
|
|
142
|
+
notify();
|
|
143
|
+
};
|
|
144
|
+
window.addEventListener("eip6963:announceProvider", onAnnounce);
|
|
145
|
+
requestProviders();
|
|
146
|
+
const RESWEEP_INTERVALS_MS = [500, 1500, 3e3, 6e3];
|
|
147
|
+
const reSweepTimers = [];
|
|
148
|
+
for (const ms of RESWEEP_INTERVALS_MS) {
|
|
149
|
+
reSweepTimers.push(
|
|
150
|
+
setTimeout(() => {
|
|
151
|
+
if (!destroyed) requestProviders();
|
|
152
|
+
}, ms)
|
|
153
|
+
);
|
|
154
|
+
}
|
|
155
|
+
function requestProviders() {
|
|
156
|
+
try {
|
|
157
|
+
window.dispatchEvent(new Event("eip6963:requestProvider"));
|
|
158
|
+
} catch {
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
function notify() {
|
|
162
|
+
const snapshot = list();
|
|
163
|
+
for (const listener of listeners) {
|
|
164
|
+
try {
|
|
165
|
+
listener(snapshot);
|
|
166
|
+
} catch {
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
function list() {
|
|
171
|
+
return [...registry.values()];
|
|
172
|
+
}
|
|
173
|
+
return {
|
|
174
|
+
list,
|
|
175
|
+
get(uuid) {
|
|
176
|
+
return registry.get(uuid)?.provider;
|
|
177
|
+
},
|
|
178
|
+
subscribe(listener) {
|
|
179
|
+
listeners.add(listener);
|
|
180
|
+
return () => {
|
|
181
|
+
listeners.delete(listener);
|
|
182
|
+
};
|
|
183
|
+
},
|
|
184
|
+
requestProviders,
|
|
185
|
+
destroy() {
|
|
186
|
+
if (destroyed) return;
|
|
187
|
+
destroyed = true;
|
|
188
|
+
window.removeEventListener("eip6963:announceProvider", onAnnounce);
|
|
189
|
+
for (const t of reSweepTimers) clearTimeout(t);
|
|
190
|
+
registry.clear();
|
|
191
|
+
listeners.clear();
|
|
192
|
+
}
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
function makeNoopHandle() {
|
|
196
|
+
return {
|
|
197
|
+
list: () => [],
|
|
198
|
+
get: () => void 0,
|
|
199
|
+
subscribe: () => () => {
|
|
200
|
+
},
|
|
201
|
+
requestProviders: () => {
|
|
202
|
+
},
|
|
203
|
+
destroy: () => {
|
|
204
|
+
}
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
function isValidProviderDetail(value) {
|
|
208
|
+
if (!value || typeof value !== "object") return false;
|
|
209
|
+
const detail = value;
|
|
210
|
+
const info = detail.info;
|
|
211
|
+
const provider = detail.provider;
|
|
212
|
+
if (!info || !provider) return false;
|
|
213
|
+
if (typeof info.uuid !== "string" || info.uuid.length === 0) return false;
|
|
214
|
+
if (typeof info.name !== "string") return false;
|
|
215
|
+
if (typeof info.rdns !== "string") return false;
|
|
216
|
+
if (typeof provider.request !== "function") return false;
|
|
217
|
+
return true;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
// src/walletBridge/protocol.ts
|
|
221
|
+
var BRIDGE_PROTOCOL_VERSION = 1;
|
|
222
|
+
var ALLOWED_RPC_METHODS = /* @__PURE__ */ new Set([
|
|
223
|
+
// Read
|
|
224
|
+
"eth_accounts",
|
|
225
|
+
"eth_blockNumber",
|
|
226
|
+
"eth_call",
|
|
227
|
+
"eth_chainId",
|
|
228
|
+
"eth_estimateGas",
|
|
229
|
+
"eth_gasPrice",
|
|
230
|
+
"eth_getBalance",
|
|
231
|
+
"eth_getCode",
|
|
232
|
+
"eth_getStorageAt",
|
|
233
|
+
"eth_getTransactionByHash",
|
|
234
|
+
"eth_getTransactionCount",
|
|
235
|
+
"eth_getTransactionReceipt",
|
|
236
|
+
"net_version",
|
|
237
|
+
"wallet_getCapabilities",
|
|
238
|
+
"wallet_getCallsStatus",
|
|
239
|
+
// Write / sign
|
|
240
|
+
"eth_requestAccounts",
|
|
241
|
+
"eth_sendTransaction",
|
|
242
|
+
"eth_sendRawTransaction",
|
|
243
|
+
"eth_sign",
|
|
244
|
+
"personal_sign",
|
|
245
|
+
"eth_signTypedData",
|
|
246
|
+
"eth_signTypedData_v3",
|
|
247
|
+
"eth_signTypedData_v4",
|
|
248
|
+
"wallet_addEthereumChain",
|
|
249
|
+
"wallet_switchEthereumChain",
|
|
250
|
+
"wallet_sendCalls",
|
|
251
|
+
"wallet_watchAsset"
|
|
252
|
+
]);
|
|
253
|
+
var FORWARDED_PROVIDER_EVENTS = [
|
|
254
|
+
"accountsChanged",
|
|
255
|
+
"chainChanged",
|
|
256
|
+
"connect",
|
|
257
|
+
"disconnect",
|
|
258
|
+
"message"
|
|
259
|
+
];
|
|
260
|
+
function parseBridgeMessage(data) {
|
|
261
|
+
if (!data || typeof data !== "object") return null;
|
|
262
|
+
const msg = data;
|
|
263
|
+
if (msg.protocolVersion !== BRIDGE_PROTOCOL_VERSION) return null;
|
|
264
|
+
switch (msg.type) {
|
|
265
|
+
case "blink:bridge-hello":
|
|
266
|
+
return msg;
|
|
267
|
+
case "blink:wallets-advertised":
|
|
268
|
+
return Array.isArray(msg.wallets) ? msg : null;
|
|
269
|
+
case "blink:rpc-request":
|
|
270
|
+
if (typeof msg.uuid !== "string" || typeof msg.id !== "string" || typeof msg.method !== "string") {
|
|
271
|
+
return null;
|
|
272
|
+
}
|
|
273
|
+
return msg;
|
|
274
|
+
case "blink:rpc-response":
|
|
275
|
+
if (typeof msg.id !== "string") return null;
|
|
276
|
+
return msg;
|
|
277
|
+
case "blink:rpc-event":
|
|
278
|
+
if (typeof msg.uuid !== "string" || typeof msg.event !== "string" || !Array.isArray(msg.args)) {
|
|
279
|
+
return null;
|
|
280
|
+
}
|
|
281
|
+
return msg;
|
|
282
|
+
case "blink:resolve-by-flag":
|
|
283
|
+
if (typeof msg.id !== "string" || !Array.isArray(msg.flags)) return null;
|
|
284
|
+
if (!msg.flags.every((f) => typeof f === "string" && f.length > 0)) return null;
|
|
285
|
+
return msg;
|
|
286
|
+
case "blink:resolve-by-flag-response":
|
|
287
|
+
if (typeof msg.id !== "string") return null;
|
|
288
|
+
if (msg.match !== null && (typeof msg.match !== "object" || !msg.match)) return null;
|
|
289
|
+
return msg;
|
|
290
|
+
default:
|
|
291
|
+
return null;
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
// src/walletBridge/rpcHost.ts
|
|
296
|
+
function attachRpcHost(options) {
|
|
297
|
+
const { iframeWindow, iframeOrigin, discoverer } = options;
|
|
298
|
+
const log = options.log ?? noopLog;
|
|
299
|
+
if (typeof window === "undefined") {
|
|
300
|
+
return { detach: () => {
|
|
301
|
+
} };
|
|
302
|
+
}
|
|
303
|
+
let detached = false;
|
|
304
|
+
const subscriptions = /* @__PURE__ */ new Map();
|
|
305
|
+
const unsubscribeFromDiscoverer = discoverer.subscribe((snapshot) => {
|
|
306
|
+
if (detached) return;
|
|
307
|
+
advertiseWallets(snapshot);
|
|
308
|
+
});
|
|
309
|
+
function postToIframe(message) {
|
|
310
|
+
if (detached) return;
|
|
311
|
+
try {
|
|
312
|
+
iframeWindow.postMessage(message, iframeOrigin);
|
|
313
|
+
} catch (err) {
|
|
314
|
+
log("postMessage to iframe failed", {
|
|
315
|
+
error: err instanceof Error ? err.message : String(err)
|
|
316
|
+
});
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
function advertiseWallets(snapshot) {
|
|
320
|
+
const wallets = snapshot.map((entry) => ({
|
|
321
|
+
uuid: entry.info.uuid,
|
|
322
|
+
rdns: entry.info.rdns,
|
|
323
|
+
name: entry.info.name,
|
|
324
|
+
icon: entry.info.icon
|
|
325
|
+
}));
|
|
326
|
+
console.info("[blink-bridge:parent] advertising wallets", wallets.map((w) => ({
|
|
327
|
+
rdns: w.rdns,
|
|
328
|
+
name: w.name
|
|
329
|
+
})));
|
|
330
|
+
const message = {
|
|
331
|
+
type: "blink:wallets-advertised",
|
|
332
|
+
protocolVersion: BRIDGE_PROTOCOL_VERSION,
|
|
333
|
+
wallets
|
|
334
|
+
};
|
|
335
|
+
postToIframe(message);
|
|
336
|
+
}
|
|
337
|
+
function ensureSubscription(uuid, provider) {
|
|
338
|
+
if (subscriptions.has(uuid)) return;
|
|
339
|
+
if (typeof provider.on !== "function") {
|
|
340
|
+
subscriptions.set(uuid, { provider, listeners: /* @__PURE__ */ new Map() });
|
|
341
|
+
return;
|
|
342
|
+
}
|
|
343
|
+
const record = { provider, listeners: /* @__PURE__ */ new Map() };
|
|
344
|
+
for (const event of FORWARDED_PROVIDER_EVENTS) {
|
|
345
|
+
const listener = (...args) => {
|
|
346
|
+
const eventMessage = {
|
|
347
|
+
type: "blink:rpc-event",
|
|
348
|
+
protocolVersion: BRIDGE_PROTOCOL_VERSION,
|
|
349
|
+
uuid,
|
|
350
|
+
event,
|
|
351
|
+
args
|
|
352
|
+
};
|
|
353
|
+
postToIframe(eventMessage);
|
|
354
|
+
};
|
|
355
|
+
try {
|
|
356
|
+
provider.on(event, listener);
|
|
357
|
+
record.listeners.set(event, listener);
|
|
358
|
+
} catch (err) {
|
|
359
|
+
log(`provider.on('${event}') threw \u2014 skipping that event`, {
|
|
360
|
+
uuid,
|
|
361
|
+
error: err instanceof Error ? err.message : String(err)
|
|
362
|
+
});
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
subscriptions.set(uuid, record);
|
|
366
|
+
}
|
|
367
|
+
function unsubscribeAll() {
|
|
368
|
+
for (const [, record] of subscriptions) {
|
|
369
|
+
const provider = record.provider;
|
|
370
|
+
if (typeof provider.removeListener !== "function") continue;
|
|
371
|
+
for (const [event, listener] of record.listeners) {
|
|
372
|
+
try {
|
|
373
|
+
provider.removeListener(event, listener);
|
|
374
|
+
} catch {
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
subscriptions.clear();
|
|
379
|
+
}
|
|
380
|
+
function sendError(id, code, message, data) {
|
|
381
|
+
const response = {
|
|
382
|
+
type: "blink:rpc-response",
|
|
383
|
+
protocolVersion: BRIDGE_PROTOCOL_VERSION,
|
|
384
|
+
id,
|
|
385
|
+
error: data === void 0 ? { code, message } : { code, message, data }
|
|
386
|
+
};
|
|
387
|
+
postToIframe(response);
|
|
388
|
+
}
|
|
389
|
+
function sendResult(id, result) {
|
|
390
|
+
const response = {
|
|
391
|
+
type: "blink:rpc-response",
|
|
392
|
+
protocolVersion: BRIDGE_PROTOCOL_VERSION,
|
|
393
|
+
id,
|
|
394
|
+
result
|
|
395
|
+
};
|
|
396
|
+
postToIframe(response);
|
|
397
|
+
}
|
|
398
|
+
const onMessage = (event) => {
|
|
399
|
+
if (detached) return;
|
|
400
|
+
if (event.source !== iframeWindow) return;
|
|
401
|
+
if (event.origin !== iframeOrigin) return;
|
|
402
|
+
const message = parseBridgeMessage(event.data);
|
|
403
|
+
if (!message) return;
|
|
404
|
+
switch (message.type) {
|
|
405
|
+
case "blink:bridge-hello": {
|
|
406
|
+
advertiseWallets(discoverer.list());
|
|
407
|
+
discoverer.requestProviders();
|
|
408
|
+
return;
|
|
409
|
+
}
|
|
410
|
+
case "blink:rpc-request": {
|
|
411
|
+
const { id, uuid, method, params } = message;
|
|
412
|
+
console.info("[blink-bridge:parent] rpc-request", { uuid, method });
|
|
413
|
+
if (!ALLOWED_RPC_METHODS.has(method)) {
|
|
414
|
+
log("rejecting non-allowlisted method", { uuid, method });
|
|
415
|
+
sendError(id, -32601, `Method not allowed: ${method}`);
|
|
416
|
+
return;
|
|
417
|
+
}
|
|
418
|
+
const provider = discoverer.get(uuid);
|
|
419
|
+
if (!provider) {
|
|
420
|
+
log("no provider for uuid", { uuid, method });
|
|
421
|
+
sendError(id, -32602, `Unknown wallet: ${uuid}`);
|
|
422
|
+
return;
|
|
423
|
+
}
|
|
424
|
+
ensureSubscription(uuid, provider);
|
|
425
|
+
provider.request({ method, params }).then((result) => {
|
|
426
|
+
console.info("[blink-bridge:parent] rpc-result", { uuid, method, ok: true });
|
|
427
|
+
sendResult(id, result);
|
|
428
|
+
}).catch((err) => {
|
|
429
|
+
const { code, message: errMessage, data } = normalizeProviderError(err);
|
|
430
|
+
console.info("[blink-bridge:parent] rpc-error", { uuid, method, code, message: errMessage });
|
|
431
|
+
sendError(id, code, errMessage, data);
|
|
432
|
+
});
|
|
433
|
+
return;
|
|
434
|
+
}
|
|
435
|
+
case "blink:resolve-by-flag": {
|
|
436
|
+
const match = resolveByFlag(discoverer.list(), message.flags, log);
|
|
437
|
+
console.info("[blink-bridge:parent] resolveByFlag", {
|
|
438
|
+
flags: message.flags,
|
|
439
|
+
match: match ? { rdns: match.rdns, flag: match.flag } : null
|
|
440
|
+
});
|
|
441
|
+
const response = {
|
|
442
|
+
type: "blink:resolve-by-flag-response",
|
|
443
|
+
protocolVersion: BRIDGE_PROTOCOL_VERSION,
|
|
444
|
+
id: message.id,
|
|
445
|
+
match
|
|
446
|
+
};
|
|
447
|
+
postToIframe(response);
|
|
448
|
+
return;
|
|
449
|
+
}
|
|
450
|
+
case "blink:wallets-advertised":
|
|
451
|
+
case "blink:rpc-response":
|
|
452
|
+
case "blink:rpc-event":
|
|
453
|
+
case "blink:resolve-by-flag-response":
|
|
454
|
+
return;
|
|
455
|
+
}
|
|
456
|
+
};
|
|
457
|
+
window.addEventListener("message", onMessage);
|
|
458
|
+
return {
|
|
459
|
+
detach() {
|
|
460
|
+
if (detached) return;
|
|
461
|
+
detached = true;
|
|
462
|
+
window.removeEventListener("message", onMessage);
|
|
463
|
+
unsubscribeFromDiscoverer();
|
|
464
|
+
unsubscribeAll();
|
|
465
|
+
}
|
|
466
|
+
};
|
|
467
|
+
}
|
|
468
|
+
function noopLog() {
|
|
469
|
+
}
|
|
470
|
+
function resolveByFlag(snapshot, flags, log) {
|
|
471
|
+
for (const flag of flags) {
|
|
472
|
+
for (const entry of snapshot) {
|
|
473
|
+
let value;
|
|
474
|
+
try {
|
|
475
|
+
value = entry.provider[flag];
|
|
476
|
+
} catch (err) {
|
|
477
|
+
log("provider threw on flag read \u2014 skipping", {
|
|
478
|
+
rdns: entry.info.rdns,
|
|
479
|
+
flag,
|
|
480
|
+
error: err instanceof Error ? err.message : String(err)
|
|
481
|
+
});
|
|
482
|
+
continue;
|
|
483
|
+
}
|
|
484
|
+
if (value) {
|
|
485
|
+
return { rdns: entry.info.rdns, uuid: entry.info.uuid, flag };
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
return null;
|
|
490
|
+
}
|
|
491
|
+
function normalizeProviderError(err) {
|
|
492
|
+
if (err && typeof err === "object") {
|
|
493
|
+
const e = err;
|
|
494
|
+
const code = typeof e.code === "number" ? e.code : -32603;
|
|
495
|
+
const message = typeof e.message === "string" ? e.message : err instanceof Error ? err.message : "Provider error";
|
|
496
|
+
const data = "data" in e ? e.data : void 0;
|
|
497
|
+
return data === void 0 ? { code, message } : { code, message, data };
|
|
498
|
+
}
|
|
499
|
+
return { code: -32603, message: typeof err === "string" ? err : "Provider error" };
|
|
500
|
+
}
|
|
93
501
|
|
|
94
502
|
// src/iframe.ts
|
|
95
503
|
var STYLE_ID = "blink-deposit-styles";
|
|
@@ -126,13 +534,26 @@ function createIframe(url, containerElement) {
|
|
|
126
534
|
const iframe = document.createElement("iframe");
|
|
127
535
|
iframe.src = url;
|
|
128
536
|
const iframeOrigin = new URL(url).origin;
|
|
129
|
-
iframe.allow = `publickey-credentials-get ${iframeOrigin}; publickey-credentials-create ${iframeOrigin}`;
|
|
537
|
+
iframe.allow = `publickey-credentials-get ${iframeOrigin}; publickey-credentials-create ${iframeOrigin}; clipboard-write ${iframeOrigin}`;
|
|
130
538
|
const handle = document.createElement("div");
|
|
131
539
|
container.appendChild(handle);
|
|
132
540
|
container.appendChild(iframe);
|
|
133
541
|
overlay.appendChild(container);
|
|
134
542
|
const mountTarget = containerElement ?? document.body;
|
|
135
543
|
mountTarget.appendChild(overlay);
|
|
544
|
+
const discoverer = createWalletDiscoverer();
|
|
545
|
+
let rpcHostHandle = null;
|
|
546
|
+
const attachBridge = () => {
|
|
547
|
+
if (rpcHostHandle) return;
|
|
548
|
+
if (!iframe.contentWindow) return;
|
|
549
|
+
rpcHostHandle = attachRpcHost({
|
|
550
|
+
iframeWindow: iframe.contentWindow,
|
|
551
|
+
iframeOrigin,
|
|
552
|
+
discoverer
|
|
553
|
+
});
|
|
554
|
+
};
|
|
555
|
+
attachBridge();
|
|
556
|
+
iframe.addEventListener("load", attachBridge);
|
|
136
557
|
const savedOverflow = document.body.style.overflow;
|
|
137
558
|
document.body.style.overflow = "hidden";
|
|
138
559
|
const onBackdropClick = (event) => {
|
|
@@ -159,6 +580,7 @@ function createIframe(url, containerElement) {
|
|
|
159
580
|
if (closed) return;
|
|
160
581
|
closed = true;
|
|
161
582
|
removeListeners();
|
|
583
|
+
detachBridge();
|
|
162
584
|
overlay.setAttribute("data-blink-closing", "");
|
|
163
585
|
let removed = false;
|
|
164
586
|
const removeOverlay = () => {
|
|
@@ -171,6 +593,14 @@ function createIframe(url, containerElement) {
|
|
|
171
593
|
container.addEventListener("animationend", removeOverlay, { once: true });
|
|
172
594
|
setTimeout(removeOverlay, CLOSE_DURATION_MS + 50);
|
|
173
595
|
}
|
|
596
|
+
function detachBridge() {
|
|
597
|
+
iframe.removeEventListener("load", attachBridge);
|
|
598
|
+
if (rpcHostHandle) {
|
|
599
|
+
rpcHostHandle.detach();
|
|
600
|
+
rpcHostHandle = null;
|
|
601
|
+
}
|
|
602
|
+
discoverer.destroy();
|
|
603
|
+
}
|
|
174
604
|
return {
|
|
175
605
|
get contentWindow() {
|
|
176
606
|
return iframe.contentWindow;
|
|
@@ -189,6 +619,7 @@ function createIframe(url, containerElement) {
|
|
|
189
619
|
if (!closed) {
|
|
190
620
|
closed = true;
|
|
191
621
|
removeListeners();
|
|
622
|
+
detachBridge();
|
|
192
623
|
overlay.remove();
|
|
193
624
|
unlockScroll();
|
|
194
625
|
}
|
|
@@ -311,8 +742,10 @@ function isValidTokenAddress(value) {
|
|
|
311
742
|
return TOKEN_ADDRESS_RE.test(value) || SOLANA_ADDRESS_RE.test(value);
|
|
312
743
|
}
|
|
313
744
|
function validateDepositRequest(request) {
|
|
314
|
-
if (
|
|
315
|
-
|
|
745
|
+
if (request.amount !== null) {
|
|
746
|
+
if (typeof request.amount !== "number" || !Number.isFinite(request.amount) || request.amount <= 0) {
|
|
747
|
+
throw new DepositError("INVALID_REQUEST", "amount must be a positive number or null.");
|
|
748
|
+
}
|
|
316
749
|
}
|
|
317
750
|
if (!Number.isInteger(request.chainId) || request.chainId <= 0) {
|
|
318
751
|
throw new DepositError("INVALID_REQUEST", "chainId must be a positive integer.");
|
|
@@ -503,30 +936,16 @@ var Deposit = class {
|
|
|
503
936
|
async runSignerFlow(request, requestId, onComplete, onError) {
|
|
504
937
|
try {
|
|
505
938
|
const webviewBaseUrl = this.config.webviewBaseUrl ?? DEFAULT_WEBVIEW_BASE_URL;
|
|
939
|
+
this.hostedOrigin = this.config.hostedFlowOrigin ?? new URL(webviewBaseUrl).origin;
|
|
506
940
|
this.log("Calling signer", {
|
|
507
941
|
signer: typeof this.config.signer === "string" ? this.config.signer : "<function>"
|
|
508
942
|
});
|
|
509
943
|
const signerRequest = buildSignerRequest(request, webviewBaseUrl);
|
|
510
|
-
const
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
)
|
|
515
|
-
this.lastSignerResponse = signerResponse;
|
|
516
|
-
this.log("Signer responded", { merchantId: signerResponse.merchantId });
|
|
517
|
-
if (this.requestId !== requestId) {
|
|
518
|
-
this.log("Request superseded after signer response");
|
|
519
|
-
return;
|
|
520
|
-
}
|
|
521
|
-
const hostedUrl = new URL(webviewBaseUrl);
|
|
522
|
-
hostedUrl.searchParams.set("merchantId", signerResponse.merchantId);
|
|
523
|
-
hostedUrl.searchParams.set("payload", signerResponse.payload);
|
|
524
|
-
hostedUrl.searchParams.set("signature", signerResponse.signature);
|
|
525
|
-
const targetUrl = hostedUrl.toString();
|
|
526
|
-
this.hostedOrigin = this.config.hostedFlowOrigin ?? hostedUrl.origin;
|
|
527
|
-
const iframeHandle = createIframe(targetUrl, this.config.containerElement);
|
|
528
|
-
this.iframe = iframeHandle;
|
|
529
|
-
iframeHandle.onClose(() => {
|
|
944
|
+
const preloadUrl = new URL(webviewBaseUrl);
|
|
945
|
+
preloadUrl.searchParams.set("preload", "true");
|
|
946
|
+
const preloadIframe = createIframe(preloadUrl.toString(), this.config.containerElement);
|
|
947
|
+
this.iframe = preloadIframe;
|
|
948
|
+
preloadIframe.onClose(() => {
|
|
530
949
|
onError(
|
|
531
950
|
new DepositError(
|
|
532
951
|
"DEPOSIT_DISMISSED",
|
|
@@ -536,9 +955,60 @@ var Deposit = class {
|
|
|
536
955
|
this.cleanup();
|
|
537
956
|
this.emit("close");
|
|
538
957
|
});
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
958
|
+
const signerPromise = callSigner(
|
|
959
|
+
this.config.signer,
|
|
960
|
+
signerRequest,
|
|
961
|
+
this.config.signerTimeoutMs
|
|
962
|
+
);
|
|
963
|
+
const iframeReadyPromise = this.waitForIframeReady(preloadIframe);
|
|
964
|
+
const [signerResponse, iframeReady] = await Promise.all([
|
|
965
|
+
signerPromise,
|
|
966
|
+
iframeReadyPromise
|
|
967
|
+
]);
|
|
968
|
+
this.lastSignerResponse = signerResponse;
|
|
969
|
+
this.log("Signer responded", { merchantId: signerResponse.merchantId });
|
|
970
|
+
if (this.requestId !== requestId || preloadIframe.isClosed()) {
|
|
971
|
+
this.log("Request superseded or iframe dismissed during signer call");
|
|
972
|
+
return;
|
|
973
|
+
}
|
|
974
|
+
if (iframeReady) {
|
|
975
|
+
const contentWindow = preloadIframe.contentWindow;
|
|
976
|
+
if (contentWindow) {
|
|
977
|
+
contentWindow.postMessage(
|
|
978
|
+
buildSignedPayloadMessage(
|
|
979
|
+
signerResponse.merchantId,
|
|
980
|
+
signerResponse.payload,
|
|
981
|
+
signerResponse.signature
|
|
982
|
+
),
|
|
983
|
+
this.hostedOrigin
|
|
984
|
+
);
|
|
985
|
+
}
|
|
986
|
+
this.startMessageListener(preloadIframe, onComplete);
|
|
987
|
+
this.setStatus("iframe-active");
|
|
988
|
+
this.log("Payload delivered via postMessage (preload path)");
|
|
989
|
+
} else {
|
|
990
|
+
preloadIframe.destroy();
|
|
991
|
+
const hostedUrl = new URL(webviewBaseUrl);
|
|
992
|
+
hostedUrl.searchParams.set("merchantId", signerResponse.merchantId);
|
|
993
|
+
hostedUrl.searchParams.set("payload", signerResponse.payload);
|
|
994
|
+
hostedUrl.searchParams.set("signature", signerResponse.signature);
|
|
995
|
+
const targetUrl = hostedUrl.toString();
|
|
996
|
+
const iframeHandle = createIframe(targetUrl, this.config.containerElement);
|
|
997
|
+
this.iframe = iframeHandle;
|
|
998
|
+
iframeHandle.onClose(() => {
|
|
999
|
+
onError(
|
|
1000
|
+
new DepositError(
|
|
1001
|
+
"DEPOSIT_DISMISSED",
|
|
1002
|
+
"The deposit was dismissed before the transfer completed."
|
|
1003
|
+
)
|
|
1004
|
+
);
|
|
1005
|
+
this.cleanup();
|
|
1006
|
+
this.emit("close");
|
|
1007
|
+
});
|
|
1008
|
+
this.startMessageListener(iframeHandle, onComplete);
|
|
1009
|
+
this.setStatus("iframe-active");
|
|
1010
|
+
this.log("Iframe opened with hosted flow (fallback path)", { url: targetUrl });
|
|
1011
|
+
}
|
|
542
1012
|
} catch (err) {
|
|
543
1013
|
if (this.requestId !== requestId) return;
|
|
544
1014
|
this.log("Signer flow failed", { error: err instanceof Error ? err.message : String(err) });
|
|
@@ -554,6 +1024,25 @@ var Deposit = class {
|
|
|
554
1024
|
}
|
|
555
1025
|
}
|
|
556
1026
|
}
|
|
1027
|
+
waitForIframeReady(iframeHandle) {
|
|
1028
|
+
return new Promise((resolve) => {
|
|
1029
|
+
const handler = (event) => {
|
|
1030
|
+
if (event.origin !== this.hostedOrigin) return;
|
|
1031
|
+
if (event.source !== iframeHandle.contentWindow) return;
|
|
1032
|
+
if (parseIframeReady(event.data)) {
|
|
1033
|
+
window.removeEventListener("message", handler);
|
|
1034
|
+
clearTimeout(timeout);
|
|
1035
|
+
resolve(true);
|
|
1036
|
+
}
|
|
1037
|
+
};
|
|
1038
|
+
window.addEventListener("message", handler);
|
|
1039
|
+
const timeout = setTimeout(() => {
|
|
1040
|
+
window.removeEventListener("message", handler);
|
|
1041
|
+
this.log("Iframe ready timeout \u2014 falling back to URL params");
|
|
1042
|
+
resolve(false);
|
|
1043
|
+
}, 2e3);
|
|
1044
|
+
});
|
|
1045
|
+
}
|
|
557
1046
|
startMessageListener(iframeHandle, onComplete) {
|
|
558
1047
|
const handler = (event) => {
|
|
559
1048
|
if (this.hostedOrigin && event.origin !== this.hostedOrigin) {
|
|
@@ -627,12 +1116,17 @@ var Checkout = Deposit;
|
|
|
627
1116
|
// src/index.ts
|
|
628
1117
|
var VERSION = "0.3.0";
|
|
629
1118
|
|
|
1119
|
+
exports.ALLOWED_RPC_METHODS = ALLOWED_RPC_METHODS;
|
|
1120
|
+
exports.BRIDGE_PROTOCOL_VERSION = BRIDGE_PROTOCOL_VERSION;
|
|
630
1121
|
exports.Checkout = Checkout;
|
|
631
1122
|
exports.CheckoutError = CheckoutError;
|
|
632
1123
|
exports.DEFAULT_WEBVIEW_BASE_URL = DEFAULT_WEBVIEW_BASE_URL;
|
|
633
1124
|
exports.Deposit = Deposit;
|
|
634
1125
|
exports.DepositError = DepositError;
|
|
635
1126
|
exports.VERSION = VERSION;
|
|
1127
|
+
exports.attachRpcHost = attachRpcHost;
|
|
1128
|
+
exports.createWalletDiscoverer = createWalletDiscoverer;
|
|
636
1129
|
exports.getDisplayMessage = getDisplayMessage;
|
|
1130
|
+
exports.parseBridgeMessage = parseBridgeMessage;
|
|
637
1131
|
//# sourceMappingURL=index.cjs.map
|
|
638
1132
|
//# sourceMappingURL=index.cjs.map
|