@swype-org/react-sdk 0.1.229 → 0.1.232
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/index.cjs +1437 -1184
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +62 -42
- package/dist/index.d.ts +62 -42
- package/dist/index.js +1437 -1184
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -155,339 +155,358 @@ function useBlinkDepositAmount() {
|
|
|
155
155
|
};
|
|
156
156
|
}
|
|
157
157
|
|
|
158
|
-
//
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
if (typeof action_explicit === "function")
|
|
165
|
-
return action_explicit;
|
|
166
|
-
return (params) => actionFn(client, params);
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
// node_modules/@wagmi/core/dist/esm/version.js
|
|
170
|
-
var version = "2.22.1";
|
|
171
|
-
|
|
172
|
-
// node_modules/@wagmi/core/dist/esm/utils/getVersion.js
|
|
173
|
-
var getVersion = () => `@wagmi/core@${version}`;
|
|
174
|
-
|
|
175
|
-
// node_modules/@wagmi/core/dist/esm/errors/base.js
|
|
176
|
-
var __classPrivateFieldGet = function(receiver, state, kind, f) {
|
|
177
|
-
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
178
|
-
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
158
|
+
// src/passkey-delegation.ts
|
|
159
|
+
var PasskeyIframeBlockedError = class extends Error {
|
|
160
|
+
constructor(message = "Passkey creation is not supported in this browser context.") {
|
|
161
|
+
super(message);
|
|
162
|
+
this.name = "PasskeyIframeBlockedError";
|
|
163
|
+
}
|
|
179
164
|
};
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
165
|
+
function isInCrossOriginIframe() {
|
|
166
|
+
if (typeof window === "undefined") return false;
|
|
167
|
+
if (window.parent === window) return false;
|
|
168
|
+
try {
|
|
169
|
+
void window.parent.location.origin;
|
|
170
|
+
return false;
|
|
171
|
+
} catch {
|
|
172
|
+
return true;
|
|
185
173
|
}
|
|
186
|
-
|
|
187
|
-
|
|
174
|
+
}
|
|
175
|
+
function isSafari() {
|
|
176
|
+
if (typeof navigator === "undefined") return false;
|
|
177
|
+
const ua = navigator.userAgent;
|
|
178
|
+
return /Safari/i.test(ua) && !/Chrome|CriOS|Chromium|Edg|OPR|Firefox/i.test(ua);
|
|
179
|
+
}
|
|
180
|
+
var POPUP_RESULT_TIMEOUT_MS = 12e4;
|
|
181
|
+
var POPUP_CLOSED_POLL_MS = 500;
|
|
182
|
+
var POPUP_CLOSED_GRACE_MS = 1e3;
|
|
183
|
+
function createPasskeyViaPopup(options) {
|
|
184
|
+
return new Promise((resolve, reject) => {
|
|
185
|
+
const verificationToken = crypto.randomUUID();
|
|
186
|
+
const payload = { ...options, verificationToken };
|
|
187
|
+
const encoded = btoa(JSON.stringify(payload));
|
|
188
|
+
const popupUrl = `${window.location.origin}/passkey-register#${encoded}`;
|
|
189
|
+
const popup = window.open(popupUrl, "blink-passkey");
|
|
190
|
+
if (!popup) {
|
|
191
|
+
reject(new Error("Pop-up blocked. Please allow pop-ups for this site and try again."));
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
let settled = false;
|
|
195
|
+
const timer = setTimeout(() => {
|
|
196
|
+
cleanup();
|
|
197
|
+
reject(new Error("Passkey creation timed out. Please try again."));
|
|
198
|
+
}, POPUP_RESULT_TIMEOUT_MS);
|
|
199
|
+
const closedPoll = setInterval(() => {
|
|
200
|
+
if (popup.closed) {
|
|
201
|
+
clearInterval(closedPoll);
|
|
202
|
+
setTimeout(() => {
|
|
203
|
+
if (!settled) {
|
|
204
|
+
settled = true;
|
|
205
|
+
cleanup();
|
|
206
|
+
checkServerForPasskeyByToken(
|
|
207
|
+
options.authToken,
|
|
208
|
+
options.apiBaseUrl,
|
|
209
|
+
verificationToken
|
|
210
|
+
).then((result) => {
|
|
211
|
+
if (result) {
|
|
212
|
+
resolve(result);
|
|
213
|
+
} else {
|
|
214
|
+
reject(new Error("Passkey window was closed before completing."));
|
|
215
|
+
}
|
|
216
|
+
}).catch(() => {
|
|
217
|
+
reject(new Error("Passkey window was closed before completing."));
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
}, POPUP_CLOSED_GRACE_MS);
|
|
221
|
+
}
|
|
222
|
+
}, POPUP_CLOSED_POLL_MS);
|
|
223
|
+
function cleanup() {
|
|
224
|
+
clearTimeout(timer);
|
|
225
|
+
clearInterval(closedPoll);
|
|
226
|
+
}
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
var VERIFY_POPUP_TIMEOUT_MS = 6e4;
|
|
230
|
+
function findDevicePasskeyViaPopup(options) {
|
|
231
|
+
return new Promise((resolve, reject) => {
|
|
232
|
+
const verificationToken = crypto.randomUUID();
|
|
233
|
+
const payload = {
|
|
234
|
+
...options,
|
|
235
|
+
verificationToken
|
|
236
|
+
};
|
|
237
|
+
const encoded = btoa(JSON.stringify(payload));
|
|
238
|
+
const popupUrl = `${window.location.origin}/passkey-verify#${encoded}`;
|
|
239
|
+
const popup = window.open(popupUrl, "blink-passkey-verify");
|
|
240
|
+
if (!popup) {
|
|
241
|
+
reject(new Error("Pop-up blocked. Please allow pop-ups for this site and try again."));
|
|
242
|
+
return;
|
|
243
|
+
}
|
|
244
|
+
let settled = false;
|
|
245
|
+
const timer = setTimeout(() => {
|
|
246
|
+
cleanup();
|
|
247
|
+
resolve(null);
|
|
248
|
+
}, VERIFY_POPUP_TIMEOUT_MS);
|
|
249
|
+
const closedPoll = setInterval(() => {
|
|
250
|
+
if (popup.closed && !settled) {
|
|
251
|
+
clearInterval(closedPoll);
|
|
252
|
+
setTimeout(() => {
|
|
253
|
+
if (!settled) {
|
|
254
|
+
settled = true;
|
|
255
|
+
cleanup();
|
|
256
|
+
checkServerForPasskeyByToken(
|
|
257
|
+
options.authToken,
|
|
258
|
+
options.apiBaseUrl,
|
|
259
|
+
verificationToken
|
|
260
|
+
).then((result) => {
|
|
261
|
+
resolve(result?.credentialId ?? null);
|
|
262
|
+
}).catch(() => {
|
|
263
|
+
resolve(null);
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
}, POPUP_CLOSED_GRACE_MS);
|
|
267
|
+
}
|
|
268
|
+
}, POPUP_CLOSED_POLL_MS);
|
|
269
|
+
function cleanup() {
|
|
270
|
+
clearTimeout(timer);
|
|
271
|
+
clearInterval(closedPoll);
|
|
272
|
+
}
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
async function checkServerForPasskeyByToken(authToken, apiBaseUrl, verificationToken) {
|
|
276
|
+
if (!authToken || !apiBaseUrl) return null;
|
|
277
|
+
const res = await fetch(`${apiBaseUrl}/v1/users/config`, {
|
|
278
|
+
headers: { Authorization: `Bearer ${authToken}` }
|
|
279
|
+
});
|
|
280
|
+
if (!res.ok) return null;
|
|
281
|
+
const body = await res.json();
|
|
282
|
+
const passkeys = body.config.passkeys ?? [];
|
|
283
|
+
const matched = passkeys.find((p) => p.lastVerificationToken === verificationToken);
|
|
284
|
+
return matched ? { credentialId: matched.credentialId, publicKey: matched.publicKey } : null;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
// src/passkeyRpId.ts
|
|
288
|
+
function normalizeConfiguredDomain(value) {
|
|
289
|
+
return value.replace(/^https?:\/\//, "").replace(/\/.*$/, "").replace(/^\./, "").trim();
|
|
290
|
+
}
|
|
291
|
+
function resolveRootDomainFromHostname(hostname) {
|
|
292
|
+
const trimmedHostname = hostname.trim().toLowerCase();
|
|
293
|
+
if (!trimmedHostname) {
|
|
294
|
+
return "localhost";
|
|
188
295
|
}
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
_BaseError_instances.add(this);
|
|
192
|
-
Object.defineProperty(this, "details", {
|
|
193
|
-
enumerable: true,
|
|
194
|
-
configurable: true,
|
|
195
|
-
writable: true,
|
|
196
|
-
value: void 0
|
|
197
|
-
});
|
|
198
|
-
Object.defineProperty(this, "docsPath", {
|
|
199
|
-
enumerable: true,
|
|
200
|
-
configurable: true,
|
|
201
|
-
writable: true,
|
|
202
|
-
value: void 0
|
|
203
|
-
});
|
|
204
|
-
Object.defineProperty(this, "metaMessages", {
|
|
205
|
-
enumerable: true,
|
|
206
|
-
configurable: true,
|
|
207
|
-
writable: true,
|
|
208
|
-
value: void 0
|
|
209
|
-
});
|
|
210
|
-
Object.defineProperty(this, "shortMessage", {
|
|
211
|
-
enumerable: true,
|
|
212
|
-
configurable: true,
|
|
213
|
-
writable: true,
|
|
214
|
-
value: void 0
|
|
215
|
-
});
|
|
216
|
-
Object.defineProperty(this, "name", {
|
|
217
|
-
enumerable: true,
|
|
218
|
-
configurable: true,
|
|
219
|
-
writable: true,
|
|
220
|
-
value: "WagmiCoreError"
|
|
221
|
-
});
|
|
222
|
-
const details = options.cause instanceof _BaseError ? options.cause.details : options.cause?.message ? options.cause.message : options.details;
|
|
223
|
-
const docsPath = options.cause instanceof _BaseError ? options.cause.docsPath || options.docsPath : options.docsPath;
|
|
224
|
-
this.message = [
|
|
225
|
-
shortMessage || "An error occurred.",
|
|
226
|
-
"",
|
|
227
|
-
...options.metaMessages ? [...options.metaMessages, ""] : [],
|
|
228
|
-
...docsPath ? [
|
|
229
|
-
`Docs: ${this.docsBaseUrl}${docsPath}.html${options.docsSlug ? `#${options.docsSlug}` : ""}`
|
|
230
|
-
] : [],
|
|
231
|
-
...details ? [`Details: ${details}`] : [],
|
|
232
|
-
`Version: ${this.version}`
|
|
233
|
-
].join("\n");
|
|
234
|
-
if (options.cause)
|
|
235
|
-
this.cause = options.cause;
|
|
236
|
-
this.details = details;
|
|
237
|
-
this.docsPath = docsPath;
|
|
238
|
-
this.metaMessages = options.metaMessages;
|
|
239
|
-
this.shortMessage = shortMessage;
|
|
296
|
+
if (trimmedHostname === "localhost" || /^\d{1,3}(?:\.\d{1,3}){3}$/.test(trimmedHostname)) {
|
|
297
|
+
return trimmedHostname;
|
|
240
298
|
}
|
|
241
|
-
|
|
242
|
-
|
|
299
|
+
const parts = trimmedHostname.split(".").filter(Boolean);
|
|
300
|
+
if (parts.length < 2) {
|
|
301
|
+
return trimmedHostname;
|
|
243
302
|
}
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
if (fn?.(err))
|
|
247
|
-
return err;
|
|
248
|
-
if (err.cause)
|
|
249
|
-
return __classPrivateFieldGet(this, _BaseError_instances, "m", _BaseError_walk2).call(this, err.cause, fn);
|
|
250
|
-
return err;
|
|
251
|
-
};
|
|
303
|
+
return parts.slice(-2).join(".");
|
|
304
|
+
}
|
|
252
305
|
|
|
253
|
-
//
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
});
|
|
274
|
-
}
|
|
275
|
-
};
|
|
276
|
-
var ConnectorChainMismatchError = class extends BaseError {
|
|
277
|
-
constructor({ connectionChainId, connectorChainId }) {
|
|
278
|
-
super(`The current chain of the connector (id: ${connectorChainId}) does not match the connection's chain (id: ${connectionChainId}).`, {
|
|
279
|
-
metaMessages: [
|
|
280
|
-
`Current Chain ID: ${connectorChainId}`,
|
|
281
|
-
`Expected Chain ID: ${connectionChainId}`
|
|
282
|
-
]
|
|
283
|
-
});
|
|
284
|
-
Object.defineProperty(this, "name", {
|
|
285
|
-
enumerable: true,
|
|
286
|
-
configurable: true,
|
|
287
|
-
writable: true,
|
|
288
|
-
value: "ConnectorChainMismatchError"
|
|
289
|
-
});
|
|
290
|
-
}
|
|
291
|
-
};
|
|
292
|
-
var ConnectorUnavailableReconnectingError = class extends BaseError {
|
|
293
|
-
constructor({ connector }) {
|
|
294
|
-
super(`Connector "${connector.name}" unavailable while reconnecting.`, {
|
|
295
|
-
details: [
|
|
296
|
-
"During the reconnection step, the only connector methods guaranteed to be available are: `id`, `name`, `type`, `uid`.",
|
|
297
|
-
"All other methods are not guaranteed to be available until reconnection completes and connectors are fully restored.",
|
|
298
|
-
"This error commonly occurs for connectors that asynchronously inject after reconnection has already started."
|
|
299
|
-
].join(" ")
|
|
300
|
-
});
|
|
301
|
-
Object.defineProperty(this, "name", {
|
|
302
|
-
enumerable: true,
|
|
303
|
-
configurable: true,
|
|
304
|
-
writable: true,
|
|
305
|
-
value: "ConnectorUnavailableReconnectingError"
|
|
306
|
-
});
|
|
307
|
-
}
|
|
308
|
-
};
|
|
309
|
-
async function getConnectorClient(config, parameters = {}) {
|
|
310
|
-
const { assertChainId = true } = parameters;
|
|
311
|
-
let connection;
|
|
312
|
-
if (parameters.connector) {
|
|
313
|
-
const { connector: connector2 } = parameters;
|
|
314
|
-
if (config.state.status === "reconnecting" && !connector2.getAccounts && !connector2.getChainId)
|
|
315
|
-
throw new ConnectorUnavailableReconnectingError({ connector: connector2 });
|
|
316
|
-
const [accounts, chainId2] = await Promise.all([
|
|
317
|
-
connector2.getAccounts().catch((e) => {
|
|
318
|
-
if (parameters.account === null)
|
|
319
|
-
return [];
|
|
320
|
-
throw e;
|
|
321
|
-
}),
|
|
322
|
-
connector2.getChainId()
|
|
323
|
-
]);
|
|
324
|
-
connection = {
|
|
325
|
-
accounts,
|
|
326
|
-
chainId: chainId2,
|
|
327
|
-
connector: connector2
|
|
328
|
-
};
|
|
329
|
-
} else
|
|
330
|
-
connection = config.state.connections.get(config.state.current);
|
|
331
|
-
if (!connection)
|
|
332
|
-
throw new ConnectorNotConnectedError();
|
|
333
|
-
const chainId = parameters.chainId ?? connection.chainId;
|
|
334
|
-
const connectorChainId = await connection.connector.getChainId();
|
|
335
|
-
if (assertChainId && connectorChainId !== chainId)
|
|
336
|
-
throw new ConnectorChainMismatchError({
|
|
337
|
-
connectionChainId: chainId,
|
|
338
|
-
connectorChainId
|
|
339
|
-
});
|
|
340
|
-
const connector = connection.connector;
|
|
341
|
-
if (connector.getClient)
|
|
342
|
-
return connector.getClient({ chainId });
|
|
343
|
-
const account = parseAccount(parameters.account ?? connection.accounts[0]);
|
|
344
|
-
if (account)
|
|
345
|
-
account.address = getAddress(account.address);
|
|
346
|
-
if (parameters.account && !connection.accounts.some((x) => x.toLowerCase() === account.address.toLowerCase()))
|
|
347
|
-
throw new ConnectorAccountNotFoundError({
|
|
348
|
-
address: account.address,
|
|
349
|
-
connector
|
|
350
|
-
});
|
|
351
|
-
const chain = config.chains.find((chain2) => chain2.id === chainId);
|
|
352
|
-
const provider = await connection.connector.getProvider({ chainId });
|
|
353
|
-
return createClient({
|
|
354
|
-
account,
|
|
355
|
-
chain,
|
|
356
|
-
name: "Connector Client",
|
|
357
|
-
transport: (opts) => custom(provider)({ ...opts, retryCount: 0 })
|
|
306
|
+
// src/hooks/passkeyPublic.ts
|
|
307
|
+
function waitForDocumentFocus(timeoutMs = 5e3, intervalMs = 100) {
|
|
308
|
+
return new Promise((resolve, reject) => {
|
|
309
|
+
if (typeof document === "undefined") {
|
|
310
|
+
resolve();
|
|
311
|
+
return;
|
|
312
|
+
}
|
|
313
|
+
if (document.hasFocus()) {
|
|
314
|
+
resolve();
|
|
315
|
+
return;
|
|
316
|
+
}
|
|
317
|
+
const deadline = Date.now() + timeoutMs;
|
|
318
|
+
const timer = setInterval(() => {
|
|
319
|
+
if (document.hasFocus()) {
|
|
320
|
+
clearInterval(timer);
|
|
321
|
+
resolve();
|
|
322
|
+
} else if (Date.now() >= deadline) {
|
|
323
|
+
clearInterval(timer);
|
|
324
|
+
resolve();
|
|
325
|
+
}
|
|
326
|
+
}, intervalMs);
|
|
358
327
|
});
|
|
359
328
|
}
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
const
|
|
365
|
-
const
|
|
366
|
-
const
|
|
367
|
-
const
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
case "connected":
|
|
371
|
-
return {
|
|
372
|
-
address,
|
|
373
|
-
addresses,
|
|
374
|
-
chain,
|
|
375
|
-
chainId: connection?.chainId,
|
|
376
|
-
connector: connection?.connector,
|
|
377
|
-
isConnected: true,
|
|
378
|
-
isConnecting: false,
|
|
379
|
-
isDisconnected: false,
|
|
380
|
-
isReconnecting: false,
|
|
381
|
-
status
|
|
382
|
-
};
|
|
383
|
-
case "reconnecting":
|
|
384
|
-
return {
|
|
385
|
-
address,
|
|
386
|
-
addresses,
|
|
387
|
-
chain,
|
|
388
|
-
chainId: connection?.chainId,
|
|
389
|
-
connector: connection?.connector,
|
|
390
|
-
isConnected: !!address,
|
|
391
|
-
isConnecting: false,
|
|
392
|
-
isDisconnected: false,
|
|
393
|
-
isReconnecting: true,
|
|
394
|
-
status
|
|
395
|
-
};
|
|
396
|
-
case "connecting":
|
|
397
|
-
return {
|
|
398
|
-
address,
|
|
399
|
-
addresses,
|
|
400
|
-
chain,
|
|
401
|
-
chainId: connection?.chainId,
|
|
402
|
-
connector: connection?.connector,
|
|
403
|
-
isConnected: false,
|
|
404
|
-
isConnecting: true,
|
|
405
|
-
isDisconnected: false,
|
|
406
|
-
isReconnecting: false,
|
|
407
|
-
status
|
|
408
|
-
};
|
|
409
|
-
case "disconnected":
|
|
410
|
-
return {
|
|
411
|
-
address: void 0,
|
|
412
|
-
addresses: void 0,
|
|
413
|
-
chain: void 0,
|
|
414
|
-
chainId: void 0,
|
|
415
|
-
connector: void 0,
|
|
416
|
-
isConnected: false,
|
|
417
|
-
isConnecting: false,
|
|
418
|
-
isDisconnected: true,
|
|
419
|
-
isReconnecting: false,
|
|
420
|
-
status
|
|
421
|
-
};
|
|
329
|
+
function toBase64(buffer) {
|
|
330
|
+
return btoa(String.fromCharCode(...new Uint8Array(buffer)));
|
|
331
|
+
}
|
|
332
|
+
function base64ToBytes(value) {
|
|
333
|
+
const normalized = value.replace(/-/g, "+").replace(/_/g, "/");
|
|
334
|
+
const padded = normalized + "=".repeat((4 - normalized.length % 4) % 4);
|
|
335
|
+
const raw = atob(padded);
|
|
336
|
+
const bytes = new Uint8Array(raw.length);
|
|
337
|
+
for (let i = 0; i < raw.length; i++) {
|
|
338
|
+
bytes[i] = raw.charCodeAt(i);
|
|
422
339
|
}
|
|
340
|
+
return bytes;
|
|
423
341
|
}
|
|
424
|
-
|
|
425
|
-
const
|
|
426
|
-
|
|
342
|
+
function readEnvValue(name) {
|
|
343
|
+
const meta = import.meta;
|
|
344
|
+
const metaValue = meta.env?.[name];
|
|
345
|
+
if (typeof metaValue === "string" && metaValue.trim().length > 0) {
|
|
346
|
+
return metaValue.trim();
|
|
347
|
+
}
|
|
348
|
+
const processValue = globalThis.process?.env?.[name];
|
|
349
|
+
if (typeof processValue === "string" && processValue.trim().length > 0) {
|
|
350
|
+
return processValue.trim();
|
|
351
|
+
}
|
|
352
|
+
return void 0;
|
|
427
353
|
}
|
|
428
|
-
|
|
429
|
-
const
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
const receipt = await action({ ...rest, timeout });
|
|
433
|
-
if (receipt.status === "reverted") {
|
|
434
|
-
const action_getTransaction = getAction(client, getTransaction, "getTransaction");
|
|
435
|
-
const { from: account, ...txn } = await action_getTransaction({
|
|
436
|
-
hash: receipt.transactionHash
|
|
437
|
-
});
|
|
438
|
-
const action_call = getAction(client, call, "call");
|
|
439
|
-
const code = await action_call({
|
|
440
|
-
...txn,
|
|
441
|
-
account,
|
|
442
|
-
data: txn.input,
|
|
443
|
-
gasPrice: txn.type !== "eip1559" ? txn.gasPrice : void 0,
|
|
444
|
-
maxFeePerGas: txn.type === "eip1559" ? txn.maxFeePerGas : void 0,
|
|
445
|
-
maxPriorityFeePerGas: txn.type === "eip1559" ? txn.maxPriorityFeePerGas : void 0
|
|
446
|
-
});
|
|
447
|
-
const reason = code?.data ? hexToString(`0x${code.data.substring(138)}`) : "unknown reason";
|
|
448
|
-
throw new Error(reason);
|
|
354
|
+
function resolvePasskeyRpId() {
|
|
355
|
+
const configuredDomain = readEnvValue("VITE_DOMAIN") ?? readEnvValue("BLINK_DOMAIN");
|
|
356
|
+
if (configuredDomain) {
|
|
357
|
+
return normalizeConfiguredDomain(configuredDomain);
|
|
449
358
|
}
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
359
|
+
if (typeof window !== "undefined") {
|
|
360
|
+
return resolveRootDomainFromHostname(window.location.hostname);
|
|
361
|
+
}
|
|
362
|
+
return "localhost";
|
|
454
363
|
}
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
364
|
+
async function createPasskeyCredential(params) {
|
|
365
|
+
const challenge = new Uint8Array(32);
|
|
366
|
+
crypto.getRandomValues(challenge);
|
|
367
|
+
const rpId = resolvePasskeyRpId();
|
|
368
|
+
const publicKeyOptions = {
|
|
369
|
+
challenge,
|
|
370
|
+
rp: { name: "Blink", id: rpId },
|
|
371
|
+
user: {
|
|
372
|
+
id: new TextEncoder().encode(params.userId),
|
|
373
|
+
name: params.displayName,
|
|
374
|
+
displayName: params.displayName
|
|
375
|
+
},
|
|
376
|
+
pubKeyCredParams: [
|
|
377
|
+
{ alg: -7, type: "public-key" },
|
|
378
|
+
{ alg: -257, type: "public-key" }
|
|
379
|
+
],
|
|
380
|
+
authenticatorSelection: {
|
|
381
|
+
authenticatorAttachment: "platform",
|
|
382
|
+
residentKey: "preferred",
|
|
383
|
+
userVerification: "required"
|
|
384
|
+
},
|
|
385
|
+
timeout: 6e4
|
|
386
|
+
};
|
|
387
|
+
if (isInCrossOriginIframe()) {
|
|
388
|
+
try {
|
|
389
|
+
await waitForDocumentFocus();
|
|
390
|
+
const credential2 = await navigator.credentials.create({
|
|
391
|
+
publicKey: publicKeyOptions
|
|
392
|
+
});
|
|
393
|
+
if (!credential2) {
|
|
394
|
+
throw new Error("Passkey creation was cancelled.");
|
|
395
|
+
}
|
|
396
|
+
return extractPasskeyResult(credential2);
|
|
397
|
+
} catch (err) {
|
|
398
|
+
if (err instanceof PasskeyIframeBlockedError) throw err;
|
|
399
|
+
if (err instanceof Error && err.message === "Passkey creation was cancelled.") throw err;
|
|
400
|
+
throw new PasskeyIframeBlockedError();
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
await waitForDocumentFocus();
|
|
404
|
+
const credential = await navigator.credentials.create({
|
|
405
|
+
publicKey: publicKeyOptions
|
|
406
|
+
});
|
|
407
|
+
if (!credential) {
|
|
408
|
+
throw new Error("Passkey creation was cancelled.");
|
|
409
|
+
}
|
|
410
|
+
return extractPasskeyResult(credential);
|
|
411
|
+
}
|
|
412
|
+
function extractPasskeyResult(credential) {
|
|
413
|
+
const response = credential.response;
|
|
414
|
+
const publicKeyBytes = response.getPublicKey?.();
|
|
415
|
+
return {
|
|
416
|
+
credentialId: toBase64(credential.rawId),
|
|
417
|
+
publicKey: publicKeyBytes ? toBase64(publicKeyBytes) : ""
|
|
418
|
+
};
|
|
419
|
+
}
|
|
420
|
+
function buildPasskeyPopupOptions(params) {
|
|
421
|
+
const challenge = new Uint8Array(32);
|
|
422
|
+
crypto.getRandomValues(challenge);
|
|
423
|
+
const rpId = resolvePasskeyRpId();
|
|
424
|
+
return {
|
|
425
|
+
challenge: toBase64(challenge),
|
|
426
|
+
rpId,
|
|
427
|
+
rpName: "Blink",
|
|
428
|
+
userId: toBase64(new TextEncoder().encode(params.userId)),
|
|
429
|
+
userName: params.displayName,
|
|
430
|
+
userDisplayName: params.displayName,
|
|
431
|
+
pubKeyCredParams: [
|
|
432
|
+
{ alg: -7, type: "public-key" },
|
|
433
|
+
{ alg: -257, type: "public-key" }
|
|
434
|
+
],
|
|
435
|
+
authenticatorSelection: {
|
|
436
|
+
authenticatorAttachment: "platform",
|
|
437
|
+
residentKey: "preferred",
|
|
438
|
+
userVerification: "required"
|
|
439
|
+
},
|
|
440
|
+
timeout: 6e4,
|
|
441
|
+
authToken: params.authToken,
|
|
442
|
+
apiBaseUrl: params.apiBaseUrl
|
|
443
|
+
};
|
|
444
|
+
}
|
|
445
|
+
async function deviceHasPasskey(credentialId) {
|
|
446
|
+
const found = await findDevicePasskey([credentialId]);
|
|
447
|
+
return found != null;
|
|
448
|
+
}
|
|
449
|
+
async function findDevicePasskey(credentialIds) {
|
|
450
|
+
if (credentialIds.length === 0) return null;
|
|
451
|
+
try {
|
|
452
|
+
const challenge = new Uint8Array(32);
|
|
453
|
+
crypto.getRandomValues(challenge);
|
|
454
|
+
await waitForDocumentFocus();
|
|
455
|
+
const assertion = await navigator.credentials.get({
|
|
456
|
+
publicKey: {
|
|
457
|
+
challenge,
|
|
458
|
+
rpId: resolvePasskeyRpId(),
|
|
459
|
+
allowCredentials: credentialIds.map((id) => ({
|
|
460
|
+
type: "public-key",
|
|
461
|
+
id: base64ToBytes(id)
|
|
462
|
+
})),
|
|
463
|
+
userVerification: "discouraged",
|
|
464
|
+
timeout: 3e4
|
|
465
|
+
}
|
|
466
|
+
});
|
|
467
|
+
if (!assertion) return null;
|
|
468
|
+
return toBase64(assertion.rawId);
|
|
469
|
+
} catch {
|
|
470
|
+
return null;
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
// src/api.ts
|
|
475
|
+
var api_exports = {};
|
|
476
|
+
__export(api_exports, {
|
|
477
|
+
createAccount: () => createAccount,
|
|
478
|
+
createAccountAuthorizationSession: () => createAccountAuthorizationSession,
|
|
479
|
+
createGuestAccount: () => createGuestAccount,
|
|
480
|
+
createGuestTransfer: () => createGuestTransfer,
|
|
481
|
+
createTransfer: () => createTransfer,
|
|
482
|
+
fetchAccount: () => fetchAccount,
|
|
483
|
+
fetchAccounts: () => fetchAccounts,
|
|
484
|
+
fetchAuthorizationSession: () => fetchAuthorizationSession,
|
|
485
|
+
fetchAuthorizationSessionByToken: () => fetchAuthorizationSessionByToken,
|
|
486
|
+
fetchChains: () => fetchChains,
|
|
487
|
+
fetchGuestAccount: () => fetchGuestAccount,
|
|
488
|
+
fetchGuestTransferBalances: () => fetchGuestTransferBalances,
|
|
489
|
+
fetchMerchantPublicKey: () => fetchMerchantPublicKey,
|
|
490
|
+
fetchProviders: () => fetchProviders,
|
|
491
|
+
fetchTransfer: () => fetchTransfer,
|
|
492
|
+
fetchUserConfig: () => fetchUserConfig,
|
|
493
|
+
getGuestTransfer: () => getGuestTransfer,
|
|
494
|
+
getTransferByGuestToken: () => getTransferByGuestToken,
|
|
495
|
+
registerPasskey: () => registerPasskey,
|
|
496
|
+
reportActionCompletion: () => reportActionCompletion,
|
|
497
|
+
reportPasskeyActivity: () => reportPasskeyActivity,
|
|
498
|
+
setAccountOwner: () => setAccountOwner,
|
|
499
|
+
setTransferSender: () => setTransferSender,
|
|
500
|
+
signGuestTransfer: () => signGuestTransfer,
|
|
501
|
+
signTransfer: () => signTransfer,
|
|
502
|
+
updateUserConfig: () => updateUserConfig,
|
|
503
|
+
updateUserConfigBySession: () => updateUserConfigBySession
|
|
504
|
+
});
|
|
505
|
+
async function throwApiError(res) {
|
|
506
|
+
const body = await res.json().catch(() => null);
|
|
507
|
+
const detail = body?.error ?? body;
|
|
508
|
+
const msg = detail?.message ?? res.statusText;
|
|
509
|
+
const code = detail?.code ?? String(res.status);
|
|
491
510
|
throw new Error(`${res.status} \u2014 ${code}: ${msg}`);
|
|
492
511
|
}
|
|
493
512
|
async function fetchProviders(apiBaseUrl, token) {
|
|
@@ -643,6 +662,13 @@ async function fetchAuthorizationSession(apiBaseUrl, sessionId) {
|
|
|
643
662
|
if (!res.ok) await throwApiError(res);
|
|
644
663
|
return await res.json();
|
|
645
664
|
}
|
|
665
|
+
async function fetchAuthorizationSessionByToken(apiBaseUrl, token) {
|
|
666
|
+
const res = await fetch(
|
|
667
|
+
`${apiBaseUrl}/v1/authorization-sessions?token=${encodeURIComponent(token)}`
|
|
668
|
+
);
|
|
669
|
+
if (!res.ok) await throwApiError(res);
|
|
670
|
+
return await res.json();
|
|
671
|
+
}
|
|
646
672
|
async function registerPasskey(apiBaseUrl, token, credentialId, publicKey) {
|
|
647
673
|
const res = await fetch(`${apiBaseUrl}/v1/users/config/passkey`, {
|
|
648
674
|
method: "POST",
|
|
@@ -811,24 +837,373 @@ async function reportActionCompletion(apiBaseUrl, actionId, result) {
|
|
|
811
837
|
if (!res.ok) await throwApiError(res);
|
|
812
838
|
return await res.json();
|
|
813
839
|
}
|
|
814
|
-
|
|
815
|
-
// src/
|
|
816
|
-
function
|
|
817
|
-
|
|
840
|
+
|
|
841
|
+
// src/transferPolling.ts
|
|
842
|
+
async function pollTransferTick(params) {
|
|
843
|
+
const fetchTransfer2 = params.fetchTransfer ?? fetchTransfer;
|
|
844
|
+
const token = await params.getAccessToken();
|
|
845
|
+
if (!token) {
|
|
846
|
+
return { kind: "retry" };
|
|
847
|
+
}
|
|
848
|
+
try {
|
|
849
|
+
const transfer = await fetchTransfer2(params.apiBaseUrl, token, params.transferId);
|
|
850
|
+
return { kind: "success", transfer };
|
|
851
|
+
} catch (err) {
|
|
852
|
+
return {
|
|
853
|
+
kind: "error",
|
|
854
|
+
message: err instanceof Error ? err.message : "Polling error"
|
|
855
|
+
};
|
|
856
|
+
}
|
|
857
|
+
}
|
|
858
|
+
|
|
859
|
+
// src/hooks/useTransferPolling.ts
|
|
860
|
+
function useTransferPolling(intervalMs = 3e3) {
|
|
861
|
+
const { apiBaseUrl } = useBlinkConfig();
|
|
862
|
+
const { getAccessToken } = usePrivy();
|
|
863
|
+
const [transfer, setTransfer] = useState(null);
|
|
864
|
+
const [error, setError] = useState(null);
|
|
865
|
+
const [isPolling, setIsPolling] = useState(false);
|
|
866
|
+
const intervalRef = useRef(null);
|
|
867
|
+
const transferIdRef = useRef(null);
|
|
868
|
+
const stopPolling = useCallback(() => {
|
|
869
|
+
if (intervalRef.current) {
|
|
870
|
+
clearInterval(intervalRef.current);
|
|
871
|
+
intervalRef.current = null;
|
|
872
|
+
}
|
|
873
|
+
setIsPolling(false);
|
|
874
|
+
}, []);
|
|
875
|
+
const poll = useCallback(async () => {
|
|
876
|
+
if (!transferIdRef.current) return;
|
|
877
|
+
const result = await pollTransferTick({
|
|
878
|
+
apiBaseUrl,
|
|
879
|
+
transferId: transferIdRef.current,
|
|
880
|
+
getAccessToken
|
|
881
|
+
});
|
|
882
|
+
if (result.kind === "retry") {
|
|
883
|
+
return;
|
|
884
|
+
}
|
|
885
|
+
if (result.kind === "error") {
|
|
886
|
+
setError(result.message);
|
|
887
|
+
stopPolling();
|
|
888
|
+
return;
|
|
889
|
+
}
|
|
890
|
+
setError(null);
|
|
891
|
+
setTransfer(result.transfer);
|
|
892
|
+
if (result.transfer.status === "COMPLETED" || result.transfer.status === "FAILED") {
|
|
893
|
+
stopPolling();
|
|
894
|
+
}
|
|
895
|
+
}, [apiBaseUrl, getAccessToken, stopPolling]);
|
|
896
|
+
const startPolling = useCallback(
|
|
897
|
+
(transferId) => {
|
|
898
|
+
stopPolling();
|
|
899
|
+
transferIdRef.current = transferId;
|
|
900
|
+
setIsPolling(true);
|
|
901
|
+
setError(null);
|
|
902
|
+
poll();
|
|
903
|
+
intervalRef.current = setInterval(poll, intervalMs);
|
|
904
|
+
},
|
|
905
|
+
[poll, intervalMs, stopPolling]
|
|
906
|
+
);
|
|
907
|
+
useEffect(() => () => stopPolling(), [stopPolling]);
|
|
908
|
+
return { transfer, error, isPolling, startPolling, stopPolling };
|
|
909
|
+
}
|
|
910
|
+
|
|
911
|
+
// node_modules/@wagmi/core/dist/esm/utils/getAction.js
|
|
912
|
+
function getAction(client, actionFn, name) {
|
|
913
|
+
const action_implicit = client[actionFn.name];
|
|
914
|
+
if (typeof action_implicit === "function")
|
|
915
|
+
return action_implicit;
|
|
916
|
+
const action_explicit = client[name];
|
|
917
|
+
if (typeof action_explicit === "function")
|
|
918
|
+
return action_explicit;
|
|
919
|
+
return (params) => actionFn(client, params);
|
|
920
|
+
}
|
|
921
|
+
|
|
922
|
+
// node_modules/@wagmi/core/dist/esm/version.js
|
|
923
|
+
var version = "2.22.1";
|
|
924
|
+
|
|
925
|
+
// node_modules/@wagmi/core/dist/esm/utils/getVersion.js
|
|
926
|
+
var getVersion = () => `@wagmi/core@${version}`;
|
|
927
|
+
|
|
928
|
+
// node_modules/@wagmi/core/dist/esm/errors/base.js
|
|
929
|
+
var __classPrivateFieldGet = function(receiver, state, kind, f) {
|
|
930
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
931
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
932
|
+
};
|
|
933
|
+
var _BaseError_instances;
|
|
934
|
+
var _BaseError_walk;
|
|
935
|
+
var BaseError = class _BaseError extends Error {
|
|
936
|
+
get docsBaseUrl() {
|
|
937
|
+
return "https://wagmi.sh/core";
|
|
938
|
+
}
|
|
939
|
+
get version() {
|
|
940
|
+
return getVersion();
|
|
941
|
+
}
|
|
942
|
+
constructor(shortMessage, options = {}) {
|
|
943
|
+
super();
|
|
944
|
+
_BaseError_instances.add(this);
|
|
945
|
+
Object.defineProperty(this, "details", {
|
|
946
|
+
enumerable: true,
|
|
947
|
+
configurable: true,
|
|
948
|
+
writable: true,
|
|
949
|
+
value: void 0
|
|
950
|
+
});
|
|
951
|
+
Object.defineProperty(this, "docsPath", {
|
|
952
|
+
enumerable: true,
|
|
953
|
+
configurable: true,
|
|
954
|
+
writable: true,
|
|
955
|
+
value: void 0
|
|
956
|
+
});
|
|
957
|
+
Object.defineProperty(this, "metaMessages", {
|
|
958
|
+
enumerable: true,
|
|
959
|
+
configurable: true,
|
|
960
|
+
writable: true,
|
|
961
|
+
value: void 0
|
|
962
|
+
});
|
|
963
|
+
Object.defineProperty(this, "shortMessage", {
|
|
964
|
+
enumerable: true,
|
|
965
|
+
configurable: true,
|
|
966
|
+
writable: true,
|
|
967
|
+
value: void 0
|
|
968
|
+
});
|
|
969
|
+
Object.defineProperty(this, "name", {
|
|
970
|
+
enumerable: true,
|
|
971
|
+
configurable: true,
|
|
972
|
+
writable: true,
|
|
973
|
+
value: "WagmiCoreError"
|
|
974
|
+
});
|
|
975
|
+
const details = options.cause instanceof _BaseError ? options.cause.details : options.cause?.message ? options.cause.message : options.details;
|
|
976
|
+
const docsPath = options.cause instanceof _BaseError ? options.cause.docsPath || options.docsPath : options.docsPath;
|
|
977
|
+
this.message = [
|
|
978
|
+
shortMessage || "An error occurred.",
|
|
979
|
+
"",
|
|
980
|
+
...options.metaMessages ? [...options.metaMessages, ""] : [],
|
|
981
|
+
...docsPath ? [
|
|
982
|
+
`Docs: ${this.docsBaseUrl}${docsPath}.html${options.docsSlug ? `#${options.docsSlug}` : ""}`
|
|
983
|
+
] : [],
|
|
984
|
+
...details ? [`Details: ${details}`] : [],
|
|
985
|
+
`Version: ${this.version}`
|
|
986
|
+
].join("\n");
|
|
987
|
+
if (options.cause)
|
|
988
|
+
this.cause = options.cause;
|
|
989
|
+
this.details = details;
|
|
990
|
+
this.docsPath = docsPath;
|
|
991
|
+
this.metaMessages = options.metaMessages;
|
|
992
|
+
this.shortMessage = shortMessage;
|
|
993
|
+
}
|
|
994
|
+
walk(fn) {
|
|
995
|
+
return __classPrivateFieldGet(this, _BaseError_instances, "m", _BaseError_walk).call(this, this, fn);
|
|
996
|
+
}
|
|
997
|
+
};
|
|
998
|
+
_BaseError_instances = /* @__PURE__ */ new WeakSet(), _BaseError_walk = function _BaseError_walk2(err, fn) {
|
|
999
|
+
if (fn?.(err))
|
|
1000
|
+
return err;
|
|
1001
|
+
if (err.cause)
|
|
1002
|
+
return __classPrivateFieldGet(this, _BaseError_instances, "m", _BaseError_walk2).call(this, err.cause, fn);
|
|
1003
|
+
return err;
|
|
1004
|
+
};
|
|
1005
|
+
|
|
1006
|
+
// node_modules/@wagmi/core/dist/esm/errors/config.js
|
|
1007
|
+
var ConnectorNotConnectedError = class extends BaseError {
|
|
1008
|
+
constructor() {
|
|
1009
|
+
super("Connector not connected.");
|
|
1010
|
+
Object.defineProperty(this, "name", {
|
|
1011
|
+
enumerable: true,
|
|
1012
|
+
configurable: true,
|
|
1013
|
+
writable: true,
|
|
1014
|
+
value: "ConnectorNotConnectedError"
|
|
1015
|
+
});
|
|
1016
|
+
}
|
|
1017
|
+
};
|
|
1018
|
+
var ConnectorAccountNotFoundError = class extends BaseError {
|
|
1019
|
+
constructor({ address, connector }) {
|
|
1020
|
+
super(`Account "${address}" not found for connector "${connector.name}".`);
|
|
1021
|
+
Object.defineProperty(this, "name", {
|
|
1022
|
+
enumerable: true,
|
|
1023
|
+
configurable: true,
|
|
1024
|
+
writable: true,
|
|
1025
|
+
value: "ConnectorAccountNotFoundError"
|
|
1026
|
+
});
|
|
1027
|
+
}
|
|
1028
|
+
};
|
|
1029
|
+
var ConnectorChainMismatchError = class extends BaseError {
|
|
1030
|
+
constructor({ connectionChainId, connectorChainId }) {
|
|
1031
|
+
super(`The current chain of the connector (id: ${connectorChainId}) does not match the connection's chain (id: ${connectionChainId}).`, {
|
|
1032
|
+
metaMessages: [
|
|
1033
|
+
`Current Chain ID: ${connectorChainId}`,
|
|
1034
|
+
`Expected Chain ID: ${connectionChainId}`
|
|
1035
|
+
]
|
|
1036
|
+
});
|
|
1037
|
+
Object.defineProperty(this, "name", {
|
|
1038
|
+
enumerable: true,
|
|
1039
|
+
configurable: true,
|
|
1040
|
+
writable: true,
|
|
1041
|
+
value: "ConnectorChainMismatchError"
|
|
1042
|
+
});
|
|
1043
|
+
}
|
|
1044
|
+
};
|
|
1045
|
+
var ConnectorUnavailableReconnectingError = class extends BaseError {
|
|
1046
|
+
constructor({ connector }) {
|
|
1047
|
+
super(`Connector "${connector.name}" unavailable while reconnecting.`, {
|
|
1048
|
+
details: [
|
|
1049
|
+
"During the reconnection step, the only connector methods guaranteed to be available are: `id`, `name`, `type`, `uid`.",
|
|
1050
|
+
"All other methods are not guaranteed to be available until reconnection completes and connectors are fully restored.",
|
|
1051
|
+
"This error commonly occurs for connectors that asynchronously inject after reconnection has already started."
|
|
1052
|
+
].join(" ")
|
|
1053
|
+
});
|
|
1054
|
+
Object.defineProperty(this, "name", {
|
|
1055
|
+
enumerable: true,
|
|
1056
|
+
configurable: true,
|
|
1057
|
+
writable: true,
|
|
1058
|
+
value: "ConnectorUnavailableReconnectingError"
|
|
1059
|
+
});
|
|
1060
|
+
}
|
|
1061
|
+
};
|
|
1062
|
+
async function getConnectorClient(config, parameters = {}) {
|
|
1063
|
+
const { assertChainId = true } = parameters;
|
|
1064
|
+
let connection;
|
|
1065
|
+
if (parameters.connector) {
|
|
1066
|
+
const { connector: connector2 } = parameters;
|
|
1067
|
+
if (config.state.status === "reconnecting" && !connector2.getAccounts && !connector2.getChainId)
|
|
1068
|
+
throw new ConnectorUnavailableReconnectingError({ connector: connector2 });
|
|
1069
|
+
const [accounts, chainId2] = await Promise.all([
|
|
1070
|
+
connector2.getAccounts().catch((e) => {
|
|
1071
|
+
if (parameters.account === null)
|
|
1072
|
+
return [];
|
|
1073
|
+
throw e;
|
|
1074
|
+
}),
|
|
1075
|
+
connector2.getChainId()
|
|
1076
|
+
]);
|
|
1077
|
+
connection = {
|
|
1078
|
+
accounts,
|
|
1079
|
+
chainId: chainId2,
|
|
1080
|
+
connector: connector2
|
|
1081
|
+
};
|
|
1082
|
+
} else
|
|
1083
|
+
connection = config.state.connections.get(config.state.current);
|
|
1084
|
+
if (!connection)
|
|
1085
|
+
throw new ConnectorNotConnectedError();
|
|
1086
|
+
const chainId = parameters.chainId ?? connection.chainId;
|
|
1087
|
+
const connectorChainId = await connection.connector.getChainId();
|
|
1088
|
+
if (assertChainId && connectorChainId !== chainId)
|
|
1089
|
+
throw new ConnectorChainMismatchError({
|
|
1090
|
+
connectionChainId: chainId,
|
|
1091
|
+
connectorChainId
|
|
1092
|
+
});
|
|
1093
|
+
const connector = connection.connector;
|
|
1094
|
+
if (connector.getClient)
|
|
1095
|
+
return connector.getClient({ chainId });
|
|
1096
|
+
const account = parseAccount(parameters.account ?? connection.accounts[0]);
|
|
1097
|
+
if (account)
|
|
1098
|
+
account.address = getAddress(account.address);
|
|
1099
|
+
if (parameters.account && !connection.accounts.some((x) => x.toLowerCase() === account.address.toLowerCase()))
|
|
1100
|
+
throw new ConnectorAccountNotFoundError({
|
|
1101
|
+
address: account.address,
|
|
1102
|
+
connector
|
|
1103
|
+
});
|
|
1104
|
+
const chain = config.chains.find((chain2) => chain2.id === chainId);
|
|
1105
|
+
const provider = await connection.connector.getProvider({ chainId });
|
|
1106
|
+
return createClient({
|
|
1107
|
+
account,
|
|
1108
|
+
chain,
|
|
1109
|
+
name: "Connector Client",
|
|
1110
|
+
transport: (opts) => custom(provider)({ ...opts, retryCount: 0 })
|
|
1111
|
+
});
|
|
1112
|
+
}
|
|
1113
|
+
|
|
1114
|
+
// node_modules/@wagmi/core/dist/esm/actions/getAccount.js
|
|
1115
|
+
function getAccount(config) {
|
|
1116
|
+
const uid = config.state.current;
|
|
1117
|
+
const connection = config.state.connections.get(uid);
|
|
1118
|
+
const addresses = connection?.accounts;
|
|
1119
|
+
const address = addresses?.[0];
|
|
1120
|
+
const chain = config.chains.find((chain2) => chain2.id === connection?.chainId);
|
|
1121
|
+
const status = config.state.status;
|
|
1122
|
+
switch (status) {
|
|
1123
|
+
case "connected":
|
|
1124
|
+
return {
|
|
1125
|
+
address,
|
|
1126
|
+
addresses,
|
|
1127
|
+
chain,
|
|
1128
|
+
chainId: connection?.chainId,
|
|
1129
|
+
connector: connection?.connector,
|
|
1130
|
+
isConnected: true,
|
|
1131
|
+
isConnecting: false,
|
|
1132
|
+
isDisconnected: false,
|
|
1133
|
+
isReconnecting: false,
|
|
1134
|
+
status
|
|
1135
|
+
};
|
|
1136
|
+
case "reconnecting":
|
|
1137
|
+
return {
|
|
1138
|
+
address,
|
|
1139
|
+
addresses,
|
|
1140
|
+
chain,
|
|
1141
|
+
chainId: connection?.chainId,
|
|
1142
|
+
connector: connection?.connector,
|
|
1143
|
+
isConnected: !!address,
|
|
1144
|
+
isConnecting: false,
|
|
1145
|
+
isDisconnected: false,
|
|
1146
|
+
isReconnecting: true,
|
|
1147
|
+
status
|
|
1148
|
+
};
|
|
1149
|
+
case "connecting":
|
|
1150
|
+
return {
|
|
1151
|
+
address,
|
|
1152
|
+
addresses,
|
|
1153
|
+
chain,
|
|
1154
|
+
chainId: connection?.chainId,
|
|
1155
|
+
connector: connection?.connector,
|
|
1156
|
+
isConnected: false,
|
|
1157
|
+
isConnecting: true,
|
|
1158
|
+
isDisconnected: false,
|
|
1159
|
+
isReconnecting: false,
|
|
1160
|
+
status
|
|
1161
|
+
};
|
|
1162
|
+
case "disconnected":
|
|
1163
|
+
return {
|
|
1164
|
+
address: void 0,
|
|
1165
|
+
addresses: void 0,
|
|
1166
|
+
chain: void 0,
|
|
1167
|
+
chainId: void 0,
|
|
1168
|
+
connector: void 0,
|
|
1169
|
+
isConnected: false,
|
|
1170
|
+
isConnecting: false,
|
|
1171
|
+
isDisconnected: true,
|
|
1172
|
+
isReconnecting: false,
|
|
1173
|
+
status
|
|
1174
|
+
};
|
|
1175
|
+
}
|
|
1176
|
+
}
|
|
1177
|
+
async function getWalletClient(config, parameters = {}) {
|
|
1178
|
+
const client = await getConnectorClient(config, parameters);
|
|
1179
|
+
return client.extend(walletActions);
|
|
818
1180
|
}
|
|
819
|
-
function
|
|
820
|
-
const
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
}
|
|
824
|
-
if (
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
1181
|
+
async function waitForTransactionReceipt(config, parameters) {
|
|
1182
|
+
const { chainId, timeout = 0, ...rest } = parameters;
|
|
1183
|
+
const client = config.getClient({ chainId });
|
|
1184
|
+
const action = getAction(client, waitForTransactionReceipt$1, "waitForTransactionReceipt");
|
|
1185
|
+
const receipt = await action({ ...rest, timeout });
|
|
1186
|
+
if (receipt.status === "reverted") {
|
|
1187
|
+
const action_getTransaction = getAction(client, getTransaction, "getTransaction");
|
|
1188
|
+
const { from: account, ...txn } = await action_getTransaction({
|
|
1189
|
+
hash: receipt.transactionHash
|
|
1190
|
+
});
|
|
1191
|
+
const action_call = getAction(client, call, "call");
|
|
1192
|
+
const code = await action_call({
|
|
1193
|
+
...txn,
|
|
1194
|
+
account,
|
|
1195
|
+
data: txn.input,
|
|
1196
|
+
gasPrice: txn.type !== "eip1559" ? txn.gasPrice : void 0,
|
|
1197
|
+
maxFeePerGas: txn.type === "eip1559" ? txn.maxFeePerGas : void 0,
|
|
1198
|
+
maxPriorityFeePerGas: txn.type === "eip1559" ? txn.maxPriorityFeePerGas : void 0
|
|
1199
|
+
});
|
|
1200
|
+
const reason = code?.data ? hexToString(`0x${code.data.substring(138)}`) : "unknown reason";
|
|
1201
|
+
throw new Error(reason);
|
|
830
1202
|
}
|
|
831
|
-
return
|
|
1203
|
+
return {
|
|
1204
|
+
...receipt,
|
|
1205
|
+
chainId: client.chain.id
|
|
1206
|
+
};
|
|
832
1207
|
}
|
|
833
1208
|
var ERC_6492_MAGIC_SUFFIX = "6492649264926492649264926492649264926492649264926492649264926492";
|
|
834
1209
|
function normalizeSignature(sig) {
|
|
@@ -878,232 +1253,22 @@ function normalizeSignature(sig) {
|
|
|
878
1253
|
);
|
|
879
1254
|
}
|
|
880
1255
|
|
|
881
|
-
// src/
|
|
882
|
-
async function pollTransferTick(params) {
|
|
883
|
-
const fetchTransfer2 = params.fetchTransfer ?? fetchTransfer;
|
|
884
|
-
const token = await params.getAccessToken();
|
|
885
|
-
if (!token) {
|
|
886
|
-
return { kind: "retry" };
|
|
887
|
-
}
|
|
888
|
-
try {
|
|
889
|
-
const transfer = await fetchTransfer2(params.apiBaseUrl, token, params.transferId);
|
|
890
|
-
return { kind: "success", transfer };
|
|
891
|
-
} catch (err) {
|
|
892
|
-
return {
|
|
893
|
-
kind: "error",
|
|
894
|
-
message: err instanceof Error ? err.message : "Polling error"
|
|
895
|
-
};
|
|
896
|
-
}
|
|
897
|
-
}
|
|
898
|
-
|
|
899
|
-
// src/passkey-delegation.ts
|
|
900
|
-
var PasskeyIframeBlockedError = class extends Error {
|
|
901
|
-
constructor(message = "Passkey creation is not supported in this browser context.") {
|
|
902
|
-
super(message);
|
|
903
|
-
this.name = "PasskeyIframeBlockedError";
|
|
904
|
-
}
|
|
905
|
-
};
|
|
906
|
-
function isInCrossOriginIframe() {
|
|
907
|
-
if (typeof window === "undefined") return false;
|
|
908
|
-
if (window.parent === window) return false;
|
|
909
|
-
try {
|
|
910
|
-
void window.parent.location.origin;
|
|
911
|
-
return false;
|
|
912
|
-
} catch {
|
|
913
|
-
return true;
|
|
914
|
-
}
|
|
915
|
-
}
|
|
916
|
-
function isSafari() {
|
|
917
|
-
if (typeof navigator === "undefined") return false;
|
|
918
|
-
const ua = navigator.userAgent;
|
|
919
|
-
return /Safari/i.test(ua) && !/Chrome|CriOS|Chromium|Edg|OPR|Firefox/i.test(ua);
|
|
920
|
-
}
|
|
921
|
-
var POPUP_RESULT_TIMEOUT_MS = 12e4;
|
|
922
|
-
var POPUP_CLOSED_POLL_MS = 500;
|
|
923
|
-
var POPUP_CLOSED_GRACE_MS = 1e3;
|
|
924
|
-
function createPasskeyViaPopup(options) {
|
|
925
|
-
return new Promise((resolve, reject) => {
|
|
926
|
-
const verificationToken = crypto.randomUUID();
|
|
927
|
-
const payload = { ...options, verificationToken };
|
|
928
|
-
const encoded = btoa(JSON.stringify(payload));
|
|
929
|
-
const popupUrl = `${window.location.origin}/passkey-register#${encoded}`;
|
|
930
|
-
const popup = window.open(popupUrl, "blink-passkey");
|
|
931
|
-
if (!popup) {
|
|
932
|
-
reject(new Error("Pop-up blocked. Please allow pop-ups for this site and try again."));
|
|
933
|
-
return;
|
|
934
|
-
}
|
|
935
|
-
let settled = false;
|
|
936
|
-
const timer = setTimeout(() => {
|
|
937
|
-
cleanup();
|
|
938
|
-
reject(new Error("Passkey creation timed out. Please try again."));
|
|
939
|
-
}, POPUP_RESULT_TIMEOUT_MS);
|
|
940
|
-
const closedPoll = setInterval(() => {
|
|
941
|
-
if (popup.closed) {
|
|
942
|
-
clearInterval(closedPoll);
|
|
943
|
-
setTimeout(() => {
|
|
944
|
-
if (!settled) {
|
|
945
|
-
settled = true;
|
|
946
|
-
cleanup();
|
|
947
|
-
checkServerForPasskeyByToken(
|
|
948
|
-
options.authToken,
|
|
949
|
-
options.apiBaseUrl,
|
|
950
|
-
verificationToken
|
|
951
|
-
).then((result) => {
|
|
952
|
-
if (result) {
|
|
953
|
-
resolve(result);
|
|
954
|
-
} else {
|
|
955
|
-
reject(new Error("Passkey window was closed before completing."));
|
|
956
|
-
}
|
|
957
|
-
}).catch(() => {
|
|
958
|
-
reject(new Error("Passkey window was closed before completing."));
|
|
959
|
-
});
|
|
960
|
-
}
|
|
961
|
-
}, POPUP_CLOSED_GRACE_MS);
|
|
962
|
-
}
|
|
963
|
-
}, POPUP_CLOSED_POLL_MS);
|
|
964
|
-
function cleanup() {
|
|
965
|
-
clearTimeout(timer);
|
|
966
|
-
clearInterval(closedPoll);
|
|
967
|
-
}
|
|
968
|
-
});
|
|
969
|
-
}
|
|
970
|
-
var VERIFY_POPUP_TIMEOUT_MS = 6e4;
|
|
971
|
-
function findDevicePasskeyViaPopup(options) {
|
|
972
|
-
return new Promise((resolve, reject) => {
|
|
973
|
-
const verificationToken = crypto.randomUUID();
|
|
974
|
-
const payload = {
|
|
975
|
-
...options,
|
|
976
|
-
verificationToken
|
|
977
|
-
};
|
|
978
|
-
const encoded = btoa(JSON.stringify(payload));
|
|
979
|
-
const popupUrl = `${window.location.origin}/passkey-verify#${encoded}`;
|
|
980
|
-
const popup = window.open(popupUrl, "blink-passkey-verify");
|
|
981
|
-
if (!popup) {
|
|
982
|
-
reject(new Error("Pop-up blocked. Please allow pop-ups for this site and try again."));
|
|
983
|
-
return;
|
|
984
|
-
}
|
|
985
|
-
let settled = false;
|
|
986
|
-
const timer = setTimeout(() => {
|
|
987
|
-
cleanup();
|
|
988
|
-
resolve(null);
|
|
989
|
-
}, VERIFY_POPUP_TIMEOUT_MS);
|
|
990
|
-
const closedPoll = setInterval(() => {
|
|
991
|
-
if (popup.closed && !settled) {
|
|
992
|
-
clearInterval(closedPoll);
|
|
993
|
-
setTimeout(() => {
|
|
994
|
-
if (!settled) {
|
|
995
|
-
settled = true;
|
|
996
|
-
cleanup();
|
|
997
|
-
checkServerForPasskeyByToken(
|
|
998
|
-
options.authToken,
|
|
999
|
-
options.apiBaseUrl,
|
|
1000
|
-
verificationToken
|
|
1001
|
-
).then((result) => {
|
|
1002
|
-
resolve(result?.credentialId ?? null);
|
|
1003
|
-
}).catch(() => {
|
|
1004
|
-
resolve(null);
|
|
1005
|
-
});
|
|
1006
|
-
}
|
|
1007
|
-
}, POPUP_CLOSED_GRACE_MS);
|
|
1008
|
-
}
|
|
1009
|
-
}, POPUP_CLOSED_POLL_MS);
|
|
1010
|
-
function cleanup() {
|
|
1011
|
-
clearTimeout(timer);
|
|
1012
|
-
clearInterval(closedPoll);
|
|
1013
|
-
}
|
|
1014
|
-
});
|
|
1015
|
-
}
|
|
1016
|
-
async function checkServerForPasskeyByToken(authToken, apiBaseUrl, verificationToken) {
|
|
1017
|
-
if (!authToken || !apiBaseUrl) return null;
|
|
1018
|
-
const res = await fetch(`${apiBaseUrl}/v1/users/config`, {
|
|
1019
|
-
headers: { Authorization: `Bearer ${authToken}` }
|
|
1020
|
-
});
|
|
1021
|
-
if (!res.ok) return null;
|
|
1022
|
-
const body = await res.json();
|
|
1023
|
-
const passkeys = body.config.passkeys ?? [];
|
|
1024
|
-
const matched = passkeys.find((p) => p.lastVerificationToken === verificationToken);
|
|
1025
|
-
return matched ? { credentialId: matched.credentialId, publicKey: matched.publicKey } : null;
|
|
1026
|
-
}
|
|
1027
|
-
|
|
1028
|
-
// src/hooks.ts
|
|
1256
|
+
// src/hooks/authorizationExecutor.ts
|
|
1029
1257
|
var WALLET_CLIENT_MAX_ATTEMPTS = 25;
|
|
1030
1258
|
var WALLET_CLIENT_POLL_MS = 400;
|
|
1031
1259
|
var ACTION_POLL_INTERVAL_MS = 500;
|
|
1032
1260
|
var ACTION_POLL_MAX_RETRIES = 20;
|
|
1033
1261
|
var SIGN_PERMIT2_POLL_MS = 1e3;
|
|
1034
1262
|
var SIGN_PERMIT2_MAX_POLLS = 15;
|
|
1035
|
-
var TRANSFER_SIGN_MAX_POLLS = 60;
|
|
1036
|
-
function waitForDocumentFocus(timeoutMs = 5e3, intervalMs = 100) {
|
|
1037
|
-
return new Promise((resolve, reject) => {
|
|
1038
|
-
if (typeof document === "undefined") {
|
|
1039
|
-
resolve();
|
|
1040
|
-
return;
|
|
1041
|
-
}
|
|
1042
|
-
if (document.hasFocus()) {
|
|
1043
|
-
resolve();
|
|
1044
|
-
return;
|
|
1045
|
-
}
|
|
1046
|
-
const deadline = Date.now() + timeoutMs;
|
|
1047
|
-
const timer = setInterval(() => {
|
|
1048
|
-
if (document.hasFocus()) {
|
|
1049
|
-
clearInterval(timer);
|
|
1050
|
-
resolve();
|
|
1051
|
-
} else if (Date.now() >= deadline) {
|
|
1052
|
-
clearInterval(timer);
|
|
1053
|
-
resolve();
|
|
1054
|
-
}
|
|
1055
|
-
}, intervalMs);
|
|
1056
|
-
});
|
|
1057
|
-
}
|
|
1058
1263
|
function actionSuccess(action, message, data) {
|
|
1059
1264
|
return { actionId: action.id, type: action.type, status: "success", message, data };
|
|
1060
1265
|
}
|
|
1061
|
-
function actionError(action, message) {
|
|
1062
|
-
return { actionId: action.id, type: action.type, status: "error", message };
|
|
1063
|
-
}
|
|
1064
|
-
function isUserRejection(msg) {
|
|
1065
|
-
const lower = msg.toLowerCase();
|
|
1066
|
-
return lower.includes("rejected") || lower.includes("denied");
|
|
1067
|
-
}
|
|
1068
|
-
function hexToBytes(hex) {
|
|
1069
|
-
const clean = hex.startsWith("0x") ? hex.slice(2) : hex;
|
|
1070
|
-
const bytes = clean.match(/.{1,2}/g).map((b) => parseInt(b, 16));
|
|
1071
|
-
return new Uint8Array(bytes);
|
|
1072
|
-
}
|
|
1073
|
-
function toBase64(buffer) {
|
|
1074
|
-
return btoa(String.fromCharCode(...new Uint8Array(buffer)));
|
|
1075
|
-
}
|
|
1076
|
-
function base64ToBytes(value) {
|
|
1077
|
-
const normalized = value.replace(/-/g, "+").replace(/_/g, "/");
|
|
1078
|
-
const padded = normalized + "=".repeat((4 - normalized.length % 4) % 4);
|
|
1079
|
-
const raw = atob(padded);
|
|
1080
|
-
const bytes = new Uint8Array(raw.length);
|
|
1081
|
-
for (let i = 0; i < raw.length; i++) {
|
|
1082
|
-
bytes[i] = raw.charCodeAt(i);
|
|
1083
|
-
}
|
|
1084
|
-
return bytes;
|
|
1085
|
-
}
|
|
1086
|
-
function readEnvValue(name) {
|
|
1087
|
-
const meta = import.meta;
|
|
1088
|
-
const metaValue = meta.env?.[name];
|
|
1089
|
-
if (typeof metaValue === "string" && metaValue.trim().length > 0) {
|
|
1090
|
-
return metaValue.trim();
|
|
1091
|
-
}
|
|
1092
|
-
const processValue = globalThis.process?.env?.[name];
|
|
1093
|
-
if (typeof processValue === "string" && processValue.trim().length > 0) {
|
|
1094
|
-
return processValue.trim();
|
|
1095
|
-
}
|
|
1096
|
-
return void 0;
|
|
1266
|
+
function actionError(action, message) {
|
|
1267
|
+
return { actionId: action.id, type: action.type, status: "error", message };
|
|
1097
1268
|
}
|
|
1098
|
-
function
|
|
1099
|
-
const
|
|
1100
|
-
|
|
1101
|
-
return normalizeConfiguredDomain(configuredDomain);
|
|
1102
|
-
}
|
|
1103
|
-
if (typeof window !== "undefined") {
|
|
1104
|
-
return resolveRootDomainFromHostname(window.location.hostname);
|
|
1105
|
-
}
|
|
1106
|
-
return "localhost";
|
|
1269
|
+
function isUserRejection(msg) {
|
|
1270
|
+
const lower = msg.toLowerCase();
|
|
1271
|
+
return lower.includes("rejected") || lower.includes("denied");
|
|
1107
1272
|
}
|
|
1108
1273
|
async function waitForWalletClient(wagmiConfig2, params = {}) {
|
|
1109
1274
|
for (let i = 0; i < WALLET_CLIENT_MAX_ATTEMPTS; i++) {
|
|
@@ -1144,165 +1309,6 @@ function parseSignTypedDataPayload(typedData) {
|
|
|
1144
1309
|
function getPendingActions(session, completedIds) {
|
|
1145
1310
|
return session.actions.filter((a) => a.status === "PENDING" && !completedIds.has(a.id)).sort((a, b) => a.orderIndex - b.orderIndex);
|
|
1146
1311
|
}
|
|
1147
|
-
async function createPasskeyCredential(params) {
|
|
1148
|
-
const challenge = new Uint8Array(32);
|
|
1149
|
-
crypto.getRandomValues(challenge);
|
|
1150
|
-
const rpId = resolvePasskeyRpId();
|
|
1151
|
-
const publicKeyOptions = {
|
|
1152
|
-
challenge,
|
|
1153
|
-
rp: { name: "Blink", id: rpId },
|
|
1154
|
-
user: {
|
|
1155
|
-
id: new TextEncoder().encode(params.userId),
|
|
1156
|
-
name: params.displayName,
|
|
1157
|
-
displayName: params.displayName
|
|
1158
|
-
},
|
|
1159
|
-
pubKeyCredParams: [
|
|
1160
|
-
{ alg: -7, type: "public-key" },
|
|
1161
|
-
{ alg: -257, type: "public-key" }
|
|
1162
|
-
],
|
|
1163
|
-
authenticatorSelection: {
|
|
1164
|
-
authenticatorAttachment: "platform",
|
|
1165
|
-
residentKey: "preferred",
|
|
1166
|
-
userVerification: "required"
|
|
1167
|
-
},
|
|
1168
|
-
timeout: 6e4
|
|
1169
|
-
};
|
|
1170
|
-
if (isInCrossOriginIframe()) {
|
|
1171
|
-
try {
|
|
1172
|
-
await waitForDocumentFocus();
|
|
1173
|
-
const credential2 = await navigator.credentials.create({
|
|
1174
|
-
publicKey: publicKeyOptions
|
|
1175
|
-
});
|
|
1176
|
-
if (!credential2) {
|
|
1177
|
-
throw new Error("Passkey creation was cancelled.");
|
|
1178
|
-
}
|
|
1179
|
-
return extractPasskeyResult(credential2);
|
|
1180
|
-
} catch (err) {
|
|
1181
|
-
if (err instanceof PasskeyIframeBlockedError) throw err;
|
|
1182
|
-
if (err instanceof Error && err.message === "Passkey creation was cancelled.") throw err;
|
|
1183
|
-
throw new PasskeyIframeBlockedError();
|
|
1184
|
-
}
|
|
1185
|
-
}
|
|
1186
|
-
await waitForDocumentFocus();
|
|
1187
|
-
const credential = await navigator.credentials.create({
|
|
1188
|
-
publicKey: publicKeyOptions
|
|
1189
|
-
});
|
|
1190
|
-
if (!credential) {
|
|
1191
|
-
throw new Error("Passkey creation was cancelled.");
|
|
1192
|
-
}
|
|
1193
|
-
return extractPasskeyResult(credential);
|
|
1194
|
-
}
|
|
1195
|
-
function extractPasskeyResult(credential) {
|
|
1196
|
-
const response = credential.response;
|
|
1197
|
-
const publicKeyBytes = response.getPublicKey?.();
|
|
1198
|
-
return {
|
|
1199
|
-
credentialId: toBase64(credential.rawId),
|
|
1200
|
-
publicKey: publicKeyBytes ? toBase64(publicKeyBytes) : ""
|
|
1201
|
-
};
|
|
1202
|
-
}
|
|
1203
|
-
function buildPasskeyPopupOptions(params) {
|
|
1204
|
-
const challenge = new Uint8Array(32);
|
|
1205
|
-
crypto.getRandomValues(challenge);
|
|
1206
|
-
const rpId = resolvePasskeyRpId();
|
|
1207
|
-
return {
|
|
1208
|
-
challenge: toBase64(challenge),
|
|
1209
|
-
rpId,
|
|
1210
|
-
rpName: "Blink",
|
|
1211
|
-
userId: toBase64(new TextEncoder().encode(params.userId)),
|
|
1212
|
-
userName: params.displayName,
|
|
1213
|
-
userDisplayName: params.displayName,
|
|
1214
|
-
pubKeyCredParams: [
|
|
1215
|
-
{ alg: -7, type: "public-key" },
|
|
1216
|
-
{ alg: -257, type: "public-key" }
|
|
1217
|
-
],
|
|
1218
|
-
authenticatorSelection: {
|
|
1219
|
-
authenticatorAttachment: "platform",
|
|
1220
|
-
residentKey: "preferred",
|
|
1221
|
-
userVerification: "required"
|
|
1222
|
-
},
|
|
1223
|
-
timeout: 6e4,
|
|
1224
|
-
authToken: params.authToken,
|
|
1225
|
-
apiBaseUrl: params.apiBaseUrl
|
|
1226
|
-
};
|
|
1227
|
-
}
|
|
1228
|
-
async function deviceHasPasskey(credentialId) {
|
|
1229
|
-
const found = await findDevicePasskey([credentialId]);
|
|
1230
|
-
return found != null;
|
|
1231
|
-
}
|
|
1232
|
-
async function findDevicePasskey(credentialIds) {
|
|
1233
|
-
if (credentialIds.length === 0) return null;
|
|
1234
|
-
try {
|
|
1235
|
-
const challenge = new Uint8Array(32);
|
|
1236
|
-
crypto.getRandomValues(challenge);
|
|
1237
|
-
await waitForDocumentFocus();
|
|
1238
|
-
const assertion = await navigator.credentials.get({
|
|
1239
|
-
publicKey: {
|
|
1240
|
-
challenge,
|
|
1241
|
-
rpId: resolvePasskeyRpId(),
|
|
1242
|
-
allowCredentials: credentialIds.map((id) => ({
|
|
1243
|
-
type: "public-key",
|
|
1244
|
-
id: base64ToBytes(id)
|
|
1245
|
-
})),
|
|
1246
|
-
userVerification: "discouraged",
|
|
1247
|
-
timeout: 3e4
|
|
1248
|
-
}
|
|
1249
|
-
});
|
|
1250
|
-
if (!assertion) return null;
|
|
1251
|
-
return toBase64(assertion.rawId);
|
|
1252
|
-
} catch {
|
|
1253
|
-
return null;
|
|
1254
|
-
}
|
|
1255
|
-
}
|
|
1256
|
-
function useTransferPolling(intervalMs = 3e3) {
|
|
1257
|
-
const { apiBaseUrl } = useBlinkConfig();
|
|
1258
|
-
const { getAccessToken } = usePrivy();
|
|
1259
|
-
const [transfer, setTransfer] = useState(null);
|
|
1260
|
-
const [error, setError] = useState(null);
|
|
1261
|
-
const [isPolling, setIsPolling] = useState(false);
|
|
1262
|
-
const intervalRef = useRef(null);
|
|
1263
|
-
const transferIdRef = useRef(null);
|
|
1264
|
-
const stopPolling = useCallback(() => {
|
|
1265
|
-
if (intervalRef.current) {
|
|
1266
|
-
clearInterval(intervalRef.current);
|
|
1267
|
-
intervalRef.current = null;
|
|
1268
|
-
}
|
|
1269
|
-
setIsPolling(false);
|
|
1270
|
-
}, []);
|
|
1271
|
-
const poll = useCallback(async () => {
|
|
1272
|
-
if (!transferIdRef.current) return;
|
|
1273
|
-
const result = await pollTransferTick({
|
|
1274
|
-
apiBaseUrl,
|
|
1275
|
-
transferId: transferIdRef.current,
|
|
1276
|
-
getAccessToken
|
|
1277
|
-
});
|
|
1278
|
-
if (result.kind === "retry") {
|
|
1279
|
-
return;
|
|
1280
|
-
}
|
|
1281
|
-
if (result.kind === "error") {
|
|
1282
|
-
setError(result.message);
|
|
1283
|
-
stopPolling();
|
|
1284
|
-
return;
|
|
1285
|
-
}
|
|
1286
|
-
setError(null);
|
|
1287
|
-
setTransfer(result.transfer);
|
|
1288
|
-
if (result.transfer.status === "COMPLETED" || result.transfer.status === "FAILED") {
|
|
1289
|
-
stopPolling();
|
|
1290
|
-
}
|
|
1291
|
-
}, [apiBaseUrl, getAccessToken, stopPolling]);
|
|
1292
|
-
const startPolling = useCallback(
|
|
1293
|
-
(transferId) => {
|
|
1294
|
-
stopPolling();
|
|
1295
|
-
transferIdRef.current = transferId;
|
|
1296
|
-
setIsPolling(true);
|
|
1297
|
-
setError(null);
|
|
1298
|
-
poll();
|
|
1299
|
-
intervalRef.current = setInterval(poll, intervalMs);
|
|
1300
|
-
},
|
|
1301
|
-
[poll, intervalMs, stopPolling]
|
|
1302
|
-
);
|
|
1303
|
-
useEffect(() => () => stopPolling(), [stopPolling]);
|
|
1304
|
-
return { transfer, error, isPolling, startPolling, stopPolling };
|
|
1305
|
-
}
|
|
1306
1312
|
async function executeOpenProvider(action, wagmiConfig2, connectors, connectAsync) {
|
|
1307
1313
|
try {
|
|
1308
1314
|
const account = getAccount(wagmiConfig2);
|
|
@@ -1699,6 +1705,47 @@ function useAuthorizationExecutor(options) {
|
|
|
1699
1705
|
executeSessionById
|
|
1700
1706
|
};
|
|
1701
1707
|
}
|
|
1708
|
+
var TRANSFER_SIGN_MAX_POLLS = 60;
|
|
1709
|
+
function waitForDocumentFocus2(timeoutMs = 5e3, intervalMs = 100) {
|
|
1710
|
+
return new Promise((resolve, reject) => {
|
|
1711
|
+
if (typeof document === "undefined") {
|
|
1712
|
+
resolve();
|
|
1713
|
+
return;
|
|
1714
|
+
}
|
|
1715
|
+
if (document.hasFocus()) {
|
|
1716
|
+
resolve();
|
|
1717
|
+
return;
|
|
1718
|
+
}
|
|
1719
|
+
const deadline = Date.now() + timeoutMs;
|
|
1720
|
+
const timer = setInterval(() => {
|
|
1721
|
+
if (document.hasFocus()) {
|
|
1722
|
+
clearInterval(timer);
|
|
1723
|
+
resolve();
|
|
1724
|
+
} else if (Date.now() >= deadline) {
|
|
1725
|
+
clearInterval(timer);
|
|
1726
|
+
resolve();
|
|
1727
|
+
}
|
|
1728
|
+
}, intervalMs);
|
|
1729
|
+
});
|
|
1730
|
+
}
|
|
1731
|
+
function hexToBytes(hex) {
|
|
1732
|
+
const clean = hex.startsWith("0x") ? hex.slice(2) : hex;
|
|
1733
|
+
const bytes = clean.match(/.{1,2}/g).map((b) => parseInt(b, 16));
|
|
1734
|
+
return new Uint8Array(bytes);
|
|
1735
|
+
}
|
|
1736
|
+
function toBase642(buffer) {
|
|
1737
|
+
return btoa(String.fromCharCode(...new Uint8Array(buffer)));
|
|
1738
|
+
}
|
|
1739
|
+
function base64ToBytes2(value) {
|
|
1740
|
+
const normalized = value.replace(/-/g, "+").replace(/_/g, "/");
|
|
1741
|
+
const padded = normalized + "=".repeat((4 - normalized.length % 4) % 4);
|
|
1742
|
+
const raw = atob(padded);
|
|
1743
|
+
const bytes = new Uint8Array(raw.length);
|
|
1744
|
+
for (let i = 0; i < raw.length; i++) {
|
|
1745
|
+
bytes[i] = raw.charCodeAt(i);
|
|
1746
|
+
}
|
|
1747
|
+
return bytes;
|
|
1748
|
+
}
|
|
1702
1749
|
function useTransferSigning(pollIntervalMs = 2e3, options) {
|
|
1703
1750
|
const blinkConfig = useOptionalBlinkConfig();
|
|
1704
1751
|
const apiBaseUrl = options?.apiBaseUrl ?? blinkConfig?.apiBaseUrl;
|
|
@@ -1754,9 +1801,9 @@ function useTransferSigning(pollIntervalMs = 2e3, options) {
|
|
|
1754
1801
|
let signedUserOp;
|
|
1755
1802
|
const allowCredentials = payload.passkeyCredentialId ? [{
|
|
1756
1803
|
type: "public-key",
|
|
1757
|
-
id:
|
|
1804
|
+
id: base64ToBytes2(payload.passkeyCredentialId)
|
|
1758
1805
|
}] : void 0;
|
|
1759
|
-
await
|
|
1806
|
+
await waitForDocumentFocus2();
|
|
1760
1807
|
const assertion = await navigator.credentials.get({
|
|
1761
1808
|
publicKey: {
|
|
1762
1809
|
challenge: hashBytes,
|
|
@@ -1772,10 +1819,10 @@ function useTransferSigning(pollIntervalMs = 2e3, options) {
|
|
|
1772
1819
|
const response = assertion.response;
|
|
1773
1820
|
signedUserOp = {
|
|
1774
1821
|
...payload.userOp,
|
|
1775
|
-
credentialId:
|
|
1776
|
-
signature:
|
|
1777
|
-
authenticatorData:
|
|
1778
|
-
clientDataJSON:
|
|
1822
|
+
credentialId: toBase642(assertion.rawId),
|
|
1823
|
+
signature: toBase642(response.signature),
|
|
1824
|
+
authenticatorData: toBase642(response.authenticatorData),
|
|
1825
|
+
clientDataJSON: toBase642(response.clientDataJSON)
|
|
1779
1826
|
};
|
|
1780
1827
|
return await signTransfer(
|
|
1781
1828
|
apiBaseUrl,
|
|
@@ -1934,6 +1981,87 @@ function buildSelectSourceChoices(options) {
|
|
|
1934
1981
|
})).filter((chain) => chain.tokens.length > 0).sort((a, b) => b.balance - a.balance);
|
|
1935
1982
|
}
|
|
1936
1983
|
|
|
1984
|
+
// src/walletFlow.ts
|
|
1985
|
+
var MOBILE_USER_AGENT_PATTERN = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i;
|
|
1986
|
+
function isMobileUserAgent(userAgent) {
|
|
1987
|
+
if (!userAgent) {
|
|
1988
|
+
return false;
|
|
1989
|
+
}
|
|
1990
|
+
return MOBILE_USER_AGENT_PATTERN.test(userAgent);
|
|
1991
|
+
}
|
|
1992
|
+
function shouldUseWalletConnector(options) {
|
|
1993
|
+
return options.useWalletConnector ?? !isMobileUserAgent(options.userAgent);
|
|
1994
|
+
}
|
|
1995
|
+
|
|
1996
|
+
// src/paymentResolvePhase.ts
|
|
1997
|
+
function hasActiveWallet(accounts) {
|
|
1998
|
+
return accounts.some((a) => a.wallets.some((w) => w.status === "ACTIVE"));
|
|
1999
|
+
}
|
|
2000
|
+
function isTransferInFlight(transfer) {
|
|
2001
|
+
if (!transfer) return false;
|
|
2002
|
+
return ["CREATED", "SENDING", "SENT"].includes(transfer.status);
|
|
2003
|
+
}
|
|
2004
|
+
function resolvePhase(state) {
|
|
2005
|
+
const p = state.phase;
|
|
2006
|
+
if (p.step === "select-source" && state.transfer?.status === "COMPLETED" && state.guestPreauthorizing) {
|
|
2007
|
+
return p;
|
|
2008
|
+
}
|
|
2009
|
+
if (state.transfer?.status === "COMPLETED" && state.guestPreauthorizing) {
|
|
2010
|
+
return { step: "processing", transfer: state.transfer };
|
|
2011
|
+
}
|
|
2012
|
+
if (state.transfer?.status === "COMPLETED") {
|
|
2013
|
+
return { step: "completed", transfer: state.transfer };
|
|
2014
|
+
}
|
|
2015
|
+
if (state.transfer?.status === "FAILED") {
|
|
2016
|
+
return { step: "failed", transfer: state.transfer, error: state.error ?? "Transfer failed." };
|
|
2017
|
+
}
|
|
2018
|
+
if (state.creatingTransfer || isTransferInFlight(state.transfer)) {
|
|
2019
|
+
return { step: "processing", transfer: state.transfer };
|
|
2020
|
+
}
|
|
2021
|
+
if (p.step === "token-picker" || p.step === "one-tap-setup" || p.step === "select-source" || p.step === "confirm-sign" || p.step === "guest-token-picker") {
|
|
2022
|
+
return p;
|
|
2023
|
+
}
|
|
2024
|
+
if (p.step === "wallet-setup") return p;
|
|
2025
|
+
if (state.mobileFlow && state.deeplinkUri) {
|
|
2026
|
+
return {
|
|
2027
|
+
step: "wallet-setup",
|
|
2028
|
+
mobile: { deeplinkUri: state.deeplinkUri, providerId: state.selectedProviderId },
|
|
2029
|
+
accountId: null
|
|
2030
|
+
};
|
|
2031
|
+
}
|
|
2032
|
+
if (!state.activeCredentialId && !state.passkeyConfigLoaded) {
|
|
2033
|
+
return { step: "initializing" };
|
|
2034
|
+
}
|
|
2035
|
+
if (state.verificationTarget) {
|
|
2036
|
+
return { step: "otp-verify", target: state.verificationTarget };
|
|
2037
|
+
}
|
|
2038
|
+
if (state.loginRequested) {
|
|
2039
|
+
return { step: "login" };
|
|
2040
|
+
}
|
|
2041
|
+
if (state.passkeyConfigLoaded && !state.activeCredentialId) {
|
|
2042
|
+
if (state.knownCredentialIds.length > 0 && state.passkeyPopupNeeded) {
|
|
2043
|
+
return { step: "passkey-verify" };
|
|
2044
|
+
}
|
|
2045
|
+
return { step: "passkey-create", popupFallback: state.passkeyPopupNeeded };
|
|
2046
|
+
}
|
|
2047
|
+
if (state.loadingData && state.activeCredentialId && hasActiveWallet(state.accounts)) {
|
|
2048
|
+
return { step: "data-loading" };
|
|
2049
|
+
}
|
|
2050
|
+
if (state.isGuestFlow && state.selectedProviderId != null && !state.transfer) {
|
|
2051
|
+
return { step: "guest-token-picker" };
|
|
2052
|
+
}
|
|
2053
|
+
if (state.activeCredentialId && !hasActiveWallet(state.accounts) && !state.mobileFlow) {
|
|
2054
|
+
return { step: "wallet-picker", reason: "link" };
|
|
2055
|
+
}
|
|
2056
|
+
if (state.activeCredentialId && hasActiveWallet(state.accounts) && !state.loadingData) {
|
|
2057
|
+
return { step: "deposit" };
|
|
2058
|
+
}
|
|
2059
|
+
if (state.isGuestFlow) {
|
|
2060
|
+
return { step: "wallet-picker", reason: "guest-entry" };
|
|
2061
|
+
}
|
|
2062
|
+
return { step: "wallet-picker", reason: "entry" };
|
|
2063
|
+
}
|
|
2064
|
+
|
|
1937
2065
|
// src/paymentReducer.ts
|
|
1938
2066
|
function deriveSourceTypeAndId(state) {
|
|
1939
2067
|
if (state.selectedWalletId) {
|
|
@@ -1946,6 +2074,7 @@ function deriveSourceTypeAndId(state) {
|
|
|
1946
2074
|
}
|
|
1947
2075
|
function createInitialState(config) {
|
|
1948
2076
|
return {
|
|
2077
|
+
phase: { step: "initializing" },
|
|
1949
2078
|
error: null,
|
|
1950
2079
|
providers: [],
|
|
1951
2080
|
accounts: [],
|
|
@@ -1966,6 +2095,7 @@ function createInitialState(config) {
|
|
|
1966
2095
|
knownCredentialIds: [],
|
|
1967
2096
|
verificationTarget: null,
|
|
1968
2097
|
oneTapLimit: 100,
|
|
2098
|
+
oneTapLimitSavedDuringSetup: false,
|
|
1969
2099
|
mobileFlow: false,
|
|
1970
2100
|
deeplinkUri: null,
|
|
1971
2101
|
increasingLimit: false,
|
|
@@ -1973,12 +2103,17 @@ function createInitialState(config) {
|
|
|
1973
2103
|
guestTransferId: null,
|
|
1974
2104
|
guestSessionToken: null,
|
|
1975
2105
|
guestPreauthAccountId: null,
|
|
2106
|
+
guestPreauthSessionId: null,
|
|
1976
2107
|
activePublicKey: null,
|
|
1977
|
-
|
|
1978
|
-
|
|
2108
|
+
loginRequested: false,
|
|
2109
|
+
guestPreauthorizing: false
|
|
1979
2110
|
};
|
|
1980
2111
|
}
|
|
1981
2112
|
function paymentReducer(state, action) {
|
|
2113
|
+
const next = applyAction(state, action);
|
|
2114
|
+
return { ...next, phase: resolvePhase(next) };
|
|
2115
|
+
}
|
|
2116
|
+
function applyAction(state, action) {
|
|
1982
2117
|
switch (action.type) {
|
|
1983
2118
|
// ── Auth ──────────────────────────────────────────────────────
|
|
1984
2119
|
case "CODE_SENT":
|
|
@@ -2056,23 +2191,20 @@ function paymentReducer(state, action) {
|
|
|
2056
2191
|
selectedProviderId: action.providerId,
|
|
2057
2192
|
selectedAccountId: null,
|
|
2058
2193
|
selectedWalletId: null,
|
|
2059
|
-
selectedTokenSymbol: null
|
|
2060
|
-
userIntent: null
|
|
2194
|
+
selectedTokenSymbol: null
|
|
2061
2195
|
};
|
|
2062
2196
|
case "SELECT_ACCOUNT":
|
|
2063
2197
|
return {
|
|
2064
2198
|
...state,
|
|
2065
2199
|
selectedAccountId: action.accountId,
|
|
2066
2200
|
selectedWalletId: action.walletId,
|
|
2067
|
-
selectedTokenSymbol: null
|
|
2068
|
-
userIntent: null
|
|
2201
|
+
selectedTokenSymbol: null
|
|
2069
2202
|
};
|
|
2070
2203
|
case "SELECT_TOKEN":
|
|
2071
2204
|
return {
|
|
2072
2205
|
...state,
|
|
2073
2206
|
selectedWalletId: action.walletId,
|
|
2074
|
-
selectedTokenSymbol: action.tokenSymbol
|
|
2075
|
-
userIntent: null
|
|
2207
|
+
selectedTokenSymbol: action.tokenSymbol
|
|
2076
2208
|
};
|
|
2077
2209
|
// ── Transfer lifecycle ───────────────────────────────────────
|
|
2078
2210
|
case "PAY_STARTED":
|
|
@@ -2081,8 +2213,7 @@ function paymentReducer(state, action) {
|
|
|
2081
2213
|
error: null,
|
|
2082
2214
|
creatingTransfer: true,
|
|
2083
2215
|
deeplinkUri: null,
|
|
2084
|
-
mobileFlow: false
|
|
2085
|
-
userIntent: null
|
|
2216
|
+
mobileFlow: false
|
|
2086
2217
|
};
|
|
2087
2218
|
case "PAY_ENDED":
|
|
2088
2219
|
return { ...state, creatingTransfer: false };
|
|
@@ -2146,7 +2277,8 @@ function paymentReducer(state, action) {
|
|
|
2146
2277
|
transfer: action.transfer,
|
|
2147
2278
|
error: null,
|
|
2148
2279
|
mobileFlow: false,
|
|
2149
|
-
deeplinkUri: null
|
|
2280
|
+
deeplinkUri: null,
|
|
2281
|
+
phase: { step: "confirm-sign", transfer: action.transfer }
|
|
2150
2282
|
};
|
|
2151
2283
|
case "CLEAR_MOBILE_STATE":
|
|
2152
2284
|
return { ...state, mobileFlow: false, deeplinkUri: null };
|
|
@@ -2216,29 +2348,37 @@ function paymentReducer(state, action) {
|
|
|
2216
2348
|
case "GUEST_PREAUTH_DETECTED":
|
|
2217
2349
|
return {
|
|
2218
2350
|
...state,
|
|
2219
|
-
guestPreauthAccountId: action.accountId
|
|
2351
|
+
guestPreauthAccountId: action.accountId,
|
|
2352
|
+
guestPreauthSessionId: action.sessionId ?? state.guestPreauthSessionId
|
|
2220
2353
|
};
|
|
2354
|
+
case "GUEST_PREAUTH_BEGIN":
|
|
2355
|
+
return { ...state, guestPreauthorizing: true, error: null };
|
|
2356
|
+
case "GUEST_PREAUTH_END":
|
|
2357
|
+
return { ...state, guestPreauthorizing: false };
|
|
2221
2358
|
case "ACCOUNT_OWNER_SET":
|
|
2222
2359
|
return {
|
|
2223
2360
|
...state,
|
|
2224
2361
|
guestPreauthAccountId: null,
|
|
2362
|
+
guestPreauthSessionId: null,
|
|
2225
2363
|
activePublicKey: null,
|
|
2226
2364
|
error: null,
|
|
2227
|
-
|
|
2365
|
+
guestPreauthorizing: false,
|
|
2366
|
+
phase: { step: "one-tap-setup", action: null }
|
|
2228
2367
|
};
|
|
2229
2368
|
// ── User intent & error ──────────────────────────────────────
|
|
2230
2369
|
case "SET_USER_INTENT":
|
|
2231
|
-
return { ...state,
|
|
2370
|
+
return { ...state, phase: action.intent };
|
|
2232
2371
|
case "REQUEST_LOGIN":
|
|
2233
2372
|
return {
|
|
2234
2373
|
...state,
|
|
2235
2374
|
loginRequested: true,
|
|
2236
2375
|
transfer: null,
|
|
2237
|
-
isGuestFlow: false,
|
|
2238
2376
|
creatingTransfer: false
|
|
2239
2377
|
};
|
|
2240
2378
|
case "SET_ERROR":
|
|
2241
2379
|
return { ...state, error: action.error };
|
|
2380
|
+
case "SET_ONE_TAP_LIMIT_SAVED_DURING_SETUP":
|
|
2381
|
+
return { ...state, oneTapLimitSavedDuringSetup: action.saved };
|
|
2242
2382
|
// ── Lifecycle ────────────────────────────────────────────────
|
|
2243
2383
|
case "NEW_PAYMENT":
|
|
2244
2384
|
return {
|
|
@@ -2255,9 +2395,11 @@ function paymentReducer(state, action) {
|
|
|
2255
2395
|
guestTransferId: null,
|
|
2256
2396
|
guestSessionToken: null,
|
|
2257
2397
|
guestPreauthAccountId: null,
|
|
2398
|
+
guestPreauthSessionId: null,
|
|
2258
2399
|
activePublicKey: null,
|
|
2259
|
-
|
|
2260
|
-
|
|
2400
|
+
loginRequested: false,
|
|
2401
|
+
oneTapLimitSavedDuringSetup: false,
|
|
2402
|
+
guestPreauthorizing: false
|
|
2261
2403
|
};
|
|
2262
2404
|
case "LOGOUT":
|
|
2263
2405
|
return {
|
|
@@ -2314,97 +2456,43 @@ function maskAuthIdentifier(identifier) {
|
|
|
2314
2456
|
return `***-***-${visibleSuffix}`;
|
|
2315
2457
|
}
|
|
2316
2458
|
|
|
2317
|
-
// src/walletFlow.ts
|
|
2318
|
-
var MOBILE_USER_AGENT_PATTERN = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i;
|
|
2319
|
-
function isMobileUserAgent(userAgent) {
|
|
2320
|
-
if (!userAgent) {
|
|
2321
|
-
return false;
|
|
2322
|
-
}
|
|
2323
|
-
return MOBILE_USER_AGENT_PATTERN.test(userAgent);
|
|
2324
|
-
}
|
|
2325
|
-
function shouldUseWalletConnector(options) {
|
|
2326
|
-
return options.useWalletConnector ?? !isMobileUserAgent(options.userAgent);
|
|
2327
|
-
}
|
|
2328
|
-
|
|
2329
2459
|
// src/resolveScreen.ts
|
|
2330
|
-
function
|
|
2331
|
-
|
|
2332
|
-
|
|
2333
|
-
|
|
2334
|
-
|
|
2335
|
-
|
|
2336
|
-
|
|
2337
|
-
|
|
2338
|
-
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
|
|
2342
|
-
|
|
2343
|
-
|
|
2344
|
-
|
|
2345
|
-
|
|
2346
|
-
|
|
2347
|
-
|
|
2348
|
-
|
|
2349
|
-
|
|
2350
|
-
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
|
|
2354
|
-
|
|
2355
|
-
|
|
2356
|
-
|
|
2357
|
-
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
|
|
2361
|
-
|
|
2362
|
-
|
|
2363
|
-
|
|
2364
|
-
|
|
2365
|
-
if (isTransferTerminal(state.transfer)) {
|
|
2366
|
-
return "success";
|
|
2367
|
-
}
|
|
2368
|
-
if (state.creatingTransfer || state.transfer != null && isTransferInFlight(state.transfer)) {
|
|
2369
|
-
return "processing";
|
|
2370
|
-
}
|
|
2371
|
-
if (state.transfer?.status === "AUTHORIZED" && !state.isDesktop && !isSetupTransfer(state.transfer)) {
|
|
2372
|
-
return "confirm-sign";
|
|
2373
|
-
}
|
|
2374
|
-
if (state.pendingSelectSource != null) {
|
|
2375
|
-
return state.isDesktop ? "setup" : "select-source";
|
|
2376
|
-
}
|
|
2377
|
-
if (state.pendingOneTapSetup != null && !state.oneTapLimitAlreadySaved) {
|
|
2378
|
-
return "setup";
|
|
2379
|
-
}
|
|
2380
|
-
if (state.mobileFlow || state.inlineAuthorizationExecuting) {
|
|
2381
|
-
return state.isDesktop ? "setup-status" : "open-wallet";
|
|
2382
|
-
}
|
|
2383
|
-
if (state.isGuestFlow && state.selectedProviderId != null && !state.transfer && !state.guestSettingSender) {
|
|
2384
|
-
return "guest-token-picker";
|
|
2385
|
-
}
|
|
2386
|
-
if (state.activeCredentialId && !hasActiveWallet(state.accounts) && !state.mobileFlow || !state.authenticated && !state.isReturningUser && !state.isGuestFlow) {
|
|
2387
|
-
return "wallet-picker";
|
|
2388
|
-
}
|
|
2389
|
-
if (state.loadingData && state.activeCredentialId != null && hasActiveWallet(state.accounts)) {
|
|
2390
|
-
return "loading";
|
|
2391
|
-
}
|
|
2392
|
-
if (state.userIntent === "pick-token" && state.selectedAccount != null) {
|
|
2393
|
-
return "token-picker";
|
|
2394
|
-
}
|
|
2395
|
-
if (state.userIntent === "configure-one-tap") {
|
|
2396
|
-
return "setup";
|
|
2397
|
-
}
|
|
2398
|
-
if (state.userIntent === "switch-wallet") {
|
|
2399
|
-
return "wallet-picker";
|
|
2400
|
-
}
|
|
2401
|
-
if (state.activeCredentialId != null && hasActiveWallet(state.accounts) && !state.loadingData) {
|
|
2402
|
-
return "deposit";
|
|
2403
|
-
}
|
|
2404
|
-
if (state.isGuestFlow) {
|
|
2405
|
-
return "wallet-picker";
|
|
2460
|
+
function screenForPhase(phase) {
|
|
2461
|
+
switch (phase.step) {
|
|
2462
|
+
case "initializing":
|
|
2463
|
+
case "data-loading":
|
|
2464
|
+
return "loading";
|
|
2465
|
+
case "login":
|
|
2466
|
+
return "login";
|
|
2467
|
+
case "otp-verify":
|
|
2468
|
+
return "otp-verify";
|
|
2469
|
+
case "passkey-create":
|
|
2470
|
+
return "create-passkey";
|
|
2471
|
+
case "passkey-verify":
|
|
2472
|
+
return "verify-passkey";
|
|
2473
|
+
case "wallet-picker":
|
|
2474
|
+
return "wallet-picker";
|
|
2475
|
+
case "wallet-setup":
|
|
2476
|
+
return phase.mobile ? "open-wallet" : "setup-status";
|
|
2477
|
+
case "select-source":
|
|
2478
|
+
if (phase.skipOneTapLimit) return "select-source";
|
|
2479
|
+
return phase.isDesktop ? "setup" : "select-source";
|
|
2480
|
+
case "one-tap-setup":
|
|
2481
|
+
return "setup";
|
|
2482
|
+
case "guest-token-picker":
|
|
2483
|
+
return "guest-token-picker";
|
|
2484
|
+
case "token-picker":
|
|
2485
|
+
return "token-picker";
|
|
2486
|
+
case "deposit":
|
|
2487
|
+
return "deposit";
|
|
2488
|
+
case "processing":
|
|
2489
|
+
return "processing";
|
|
2490
|
+
case "confirm-sign":
|
|
2491
|
+
return "confirm-sign";
|
|
2492
|
+
case "completed":
|
|
2493
|
+
case "failed":
|
|
2494
|
+
return "success";
|
|
2406
2495
|
}
|
|
2407
|
-
return "wallet-picker";
|
|
2408
2496
|
}
|
|
2409
2497
|
var MUTED = "#7fa4b0";
|
|
2410
2498
|
var LOGO_SIZE = 48;
|
|
@@ -5887,85 +5975,66 @@ var DEPOSIT_SCREENS = /* @__PURE__ */ new Set([
|
|
|
5887
5975
|
"processing",
|
|
5888
5976
|
"success"
|
|
5889
5977
|
]);
|
|
5890
|
-
function getFlowPhase(screen,
|
|
5978
|
+
function getFlowPhase(screen, phase) {
|
|
5891
5979
|
if (LINK_SCREENS.has(screen)) return "link";
|
|
5892
5980
|
if (DEPOSIT_SCREENS.has(screen)) return "deposit";
|
|
5893
5981
|
if (screen === "token-picker" || screen === "select-source" || screen === "guest-token-picker") {
|
|
5894
|
-
return
|
|
5982
|
+
return phase.step === "one-tap-setup" ? "link" : "deposit";
|
|
5895
5983
|
}
|
|
5896
5984
|
return null;
|
|
5897
5985
|
}
|
|
5898
5986
|
function StepRenderer(props) {
|
|
5899
|
-
const
|
|
5900
|
-
|
|
5901
|
-
});
|
|
5902
|
-
const isReturningUser = props.state.activeCredentialId != null || typeof window !== "undefined" && window.localStorage.getItem("blink_active_credential") != null;
|
|
5903
|
-
const screenState = {
|
|
5904
|
-
privyReady: props.ready,
|
|
5905
|
-
authenticated: props.authenticated,
|
|
5906
|
-
verificationTarget: props.state.verificationTarget,
|
|
5907
|
-
activeCredentialId: props.state.activeCredentialId,
|
|
5908
|
-
knownCredentialIds: props.state.knownCredentialIds,
|
|
5909
|
-
passkeyConfigLoaded: props.state.passkeyConfigLoaded,
|
|
5910
|
-
passkeyPopupNeeded: props.state.passkeyPopupNeeded,
|
|
5911
|
-
accounts: props.state.accounts,
|
|
5912
|
-
isGuestFlow: props.state.isGuestFlow,
|
|
5913
|
-
selectedProviderId: props.state.selectedProviderId,
|
|
5914
|
-
mobileFlow: props.state.mobileFlow,
|
|
5915
|
-
inlineAuthorizationExecuting: props.inlineAuthorizationExecuting,
|
|
5916
|
-
creatingTransfer: props.state.creatingTransfer,
|
|
5917
|
-
transfer: props.state.transfer,
|
|
5918
|
-
pendingSelectSource: props.pendingSelectSource,
|
|
5919
|
-
pendingOneTapSetup: props.pendingOneTapSetup,
|
|
5920
|
-
oneTapLimitAlreadySaved: props.oneTapLimitAlreadySaved,
|
|
5921
|
-
loadingData: props.state.loadingData,
|
|
5922
|
-
isDesktop,
|
|
5923
|
-
isReturningUser,
|
|
5924
|
-
guestPreauthRedirect: props.state.guestPreauthAccountId != null,
|
|
5925
|
-
loginRequested: props.state.loginRequested,
|
|
5926
|
-
userIntent: props.state.userIntent,
|
|
5927
|
-
selectedAccount: props.selectedAccount,
|
|
5928
|
-
guestSettingSender: props.guestSettingSender
|
|
5929
|
-
};
|
|
5930
|
-
const screen = resolveScreen(screenState);
|
|
5931
|
-
const phase = getFlowPhase(screen, props.state.userIntent);
|
|
5932
|
-
return /* @__PURE__ */ jsx(FlowPhaseProvider, { phase, children: /* @__PURE__ */ jsx(StepRendererContent, { ...props, screen, isDesktop }) });
|
|
5987
|
+
const screen = screenForPhase(props.flow.state.phase);
|
|
5988
|
+
const flowPhase = getFlowPhase(screen, props.flow.state.phase);
|
|
5989
|
+
return /* @__PURE__ */ jsx(FlowPhaseProvider, { phase: flowPhase, children: /* @__PURE__ */ jsx(StepRendererContent, { ...props, screen }) });
|
|
5933
5990
|
}
|
|
5934
5991
|
function StepRendererContent({
|
|
5935
|
-
|
|
5936
|
-
|
|
5937
|
-
|
|
5938
|
-
|
|
5939
|
-
pollingError,
|
|
5940
|
-
authExecutorError,
|
|
5941
|
-
transferSigningSigning,
|
|
5942
|
-
transferSigningError,
|
|
5943
|
-
pendingConnections,
|
|
5944
|
-
depositEligibleAccounts,
|
|
5945
|
-
sourceName,
|
|
5946
|
-
maxSourceBalance,
|
|
5947
|
-
tokenCount,
|
|
5948
|
-
selectedAccount,
|
|
5949
|
-
selectedSource,
|
|
5950
|
-
selectSourceChoices,
|
|
5951
|
-
selectSourceRecommended,
|
|
5952
|
-
selectSourceAvailableBalance,
|
|
5953
|
-
guestTokenEntries,
|
|
5954
|
-
guestLoadingBalances,
|
|
5955
|
-
guestSettingSender,
|
|
5956
|
-
authInput,
|
|
5957
|
-
otpCode,
|
|
5958
|
-
selectSourceChainName,
|
|
5959
|
-
selectSourceTokenSymbol,
|
|
5960
|
-
savingOneTapLimit,
|
|
5961
|
-
merchantName,
|
|
5962
|
-
onBack,
|
|
5963
|
-
onDismiss,
|
|
5964
|
-
depositAmount,
|
|
5992
|
+
flow,
|
|
5993
|
+
remote,
|
|
5994
|
+
derived,
|
|
5995
|
+
forms,
|
|
5965
5996
|
handlers,
|
|
5966
|
-
screen
|
|
5967
|
-
isDesktop
|
|
5997
|
+
screen
|
|
5968
5998
|
}) {
|
|
5999
|
+
const {
|
|
6000
|
+
state,
|
|
6001
|
+
authenticated,
|
|
6002
|
+
activeOtpStatus,
|
|
6003
|
+
isDesktop,
|
|
6004
|
+
merchantName,
|
|
6005
|
+
onBack,
|
|
6006
|
+
onDismiss,
|
|
6007
|
+
depositAmount
|
|
6008
|
+
} = flow;
|
|
6009
|
+
const {
|
|
6010
|
+
pollingTransfer,
|
|
6011
|
+
pollingError,
|
|
6012
|
+
authExecutorError,
|
|
6013
|
+
transferSigningSigning,
|
|
6014
|
+
transferSigningError
|
|
6015
|
+
} = remote;
|
|
6016
|
+
const {
|
|
6017
|
+
pendingConnections,
|
|
6018
|
+
depositEligibleAccounts,
|
|
6019
|
+
sourceName,
|
|
6020
|
+
maxSourceBalance,
|
|
6021
|
+
tokenCount,
|
|
6022
|
+
selectedAccount,
|
|
6023
|
+
selectedSource,
|
|
6024
|
+
selectSourceChoices,
|
|
6025
|
+
selectSourceRecommended,
|
|
6026
|
+
selectSourceAvailableBalance
|
|
6027
|
+
} = derived;
|
|
6028
|
+
const {
|
|
6029
|
+
guestTokenEntries,
|
|
6030
|
+
guestLoadingBalances,
|
|
6031
|
+
guestSettingSender,
|
|
6032
|
+
authInput,
|
|
6033
|
+
otpCode,
|
|
6034
|
+
selectSourceChainName,
|
|
6035
|
+
selectSourceTokenSymbol,
|
|
6036
|
+
savingOneTapLimit
|
|
6037
|
+
} = forms;
|
|
5969
6038
|
const selectedWallet = selectedAccount?.wallets.find((w) => w.id === state.selectedWalletId);
|
|
5970
6039
|
const selectedSourceLabel = selectedSource && selectedWallet ? `${selectedSource.token.symbol} on ${selectedWallet.chain.name}` : void 0;
|
|
5971
6040
|
switch (screen) {
|
|
@@ -6038,7 +6107,7 @@ function StepRendererContent({
|
|
|
6038
6107
|
onPrepareProvider: handlers.onPrepareProvider,
|
|
6039
6108
|
onSelectProvider: handlers.onSelectProvider,
|
|
6040
6109
|
onContinueConnection: handlers.onContinueConnection,
|
|
6041
|
-
onBack: isEntryPoint ? onBack : () => handlers.
|
|
6110
|
+
onBack: isEntryPoint ? onBack : () => handlers.onSetPhase({ step: "deposit" }),
|
|
6042
6111
|
onLogout: authenticated ? handlers.onLogout : void 0,
|
|
6043
6112
|
onLogin: handlers.onLogin,
|
|
6044
6113
|
showLoginOption: isEntryPoint
|
|
@@ -6069,7 +6138,7 @@ function StepRendererContent({
|
|
|
6069
6138
|
limit: state.oneTapLimit,
|
|
6070
6139
|
tokensApproved: 0,
|
|
6071
6140
|
merchantName,
|
|
6072
|
-
onContinue: () => handlers.
|
|
6141
|
+
onContinue: () => handlers.onSetPhase({ step: "one-tap-setup", action: null }),
|
|
6073
6142
|
onLogout: handlers.onLogout,
|
|
6074
6143
|
error: state.error || authExecutorError
|
|
6075
6144
|
}
|
|
@@ -6088,7 +6157,7 @@ function StepRendererContent({
|
|
|
6088
6157
|
tokenCount: effectiveTokenCount,
|
|
6089
6158
|
sourceName,
|
|
6090
6159
|
onSetupOneTap: handlers.onSetupOneTap,
|
|
6091
|
-
onBack: () => handlers.
|
|
6160
|
+
onBack: () => handlers.onSetPhase({ step: "deposit" }),
|
|
6092
6161
|
onLogout: handlers.onLogout,
|
|
6093
6162
|
onAdvanced: handlers.onSelectToken,
|
|
6094
6163
|
selectedSourceLabel: effectiveSourceLabel,
|
|
@@ -6124,7 +6193,7 @@ function StepRendererContent({
|
|
|
6124
6193
|
processing: state.creatingTransfer,
|
|
6125
6194
|
error: state.error,
|
|
6126
6195
|
onDeposit: handlers.onPay,
|
|
6127
|
-
onSwitchWallet: () => handlers.
|
|
6196
|
+
onSwitchWallet: () => handlers.onSetPhase({ step: "wallet-picker", reason: "switch" }),
|
|
6128
6197
|
onBack: onBack ?? (() => handlers.onLogout()),
|
|
6129
6198
|
onLogout: handlers.onLogout,
|
|
6130
6199
|
onIncreaseLimit: handlers.onIncreaseLimit,
|
|
@@ -6133,7 +6202,7 @@ function StepRendererContent({
|
|
|
6133
6202
|
selectedAccountId: state.selectedAccountId,
|
|
6134
6203
|
onSelectAccount: handlers.onSelectAccount,
|
|
6135
6204
|
onAuthorizeAccount: handlers.onContinueConnection,
|
|
6136
|
-
onAddProvider: () => handlers.
|
|
6205
|
+
onAddProvider: () => handlers.onSetPhase({ step: "wallet-picker", reason: "switch" }),
|
|
6137
6206
|
onSelectToken: handlers.onSelectToken,
|
|
6138
6207
|
selectedSourceLabel,
|
|
6139
6208
|
selectedTokenSymbol: selectedSource?.token.symbol
|
|
@@ -6151,7 +6220,7 @@ function StepRendererContent({
|
|
|
6151
6220
|
chains: state.chains,
|
|
6152
6221
|
onSelectAuthorized: handlers.onSelectAuthorizedToken,
|
|
6153
6222
|
onAuthorizeToken: handlers.onAuthorizeToken,
|
|
6154
|
-
onBack: () => handlers.
|
|
6223
|
+
onBack: () => handlers.onSetPhase({ step: "deposit" }),
|
|
6155
6224
|
onLogout: handlers.onLogout,
|
|
6156
6225
|
depositAmount: depositAmount ?? void 0,
|
|
6157
6226
|
selectedTokenSymbol: selectedSource?.token.symbol,
|
|
@@ -6169,7 +6238,7 @@ function StepRendererContent({
|
|
|
6169
6238
|
depositAmount: depositAmount ?? void 0,
|
|
6170
6239
|
error: state.error,
|
|
6171
6240
|
onSelect: handlers.onSelectGuestToken,
|
|
6172
|
-
onBack: () => handlers.
|
|
6241
|
+
onBack: () => handlers.onSetPhase({ step: "wallet-picker", reason: "guest-entry" })
|
|
6173
6242
|
}
|
|
6174
6243
|
);
|
|
6175
6244
|
case "processing": {
|
|
@@ -6308,56 +6377,41 @@ var buttonStyle3 = {
|
|
|
6308
6377
|
fontFamily: "inherit",
|
|
6309
6378
|
cursor: "pointer"
|
|
6310
6379
|
};
|
|
6311
|
-
function
|
|
6380
|
+
function selectedSourceForWallet(selectedWallet, selectedTokenSymbol) {
|
|
6381
|
+
if (!selectedWallet) return null;
|
|
6382
|
+
if (selectedTokenSymbol) {
|
|
6383
|
+
return selectedWallet.sources.find((s) => s.token.symbol === selectedTokenSymbol) ?? null;
|
|
6384
|
+
}
|
|
6385
|
+
return selectedWallet.sources.find((s) => s.token.status === "AUTHORIZED") ?? selectedWallet.sources[0] ?? null;
|
|
6386
|
+
}
|
|
6387
|
+
function computeDerivedState(state) {
|
|
6312
6388
|
const { sourceType, sourceId } = deriveSourceTypeAndId(state);
|
|
6313
6389
|
const selectedAccount = state.accounts.find((a) => a.id === state.selectedAccountId);
|
|
6314
6390
|
const selectedWallet = selectedAccount?.wallets.find(
|
|
6315
6391
|
(w) => w.id === state.selectedWalletId
|
|
6316
6392
|
);
|
|
6317
|
-
const selectedSource =
|
|
6318
|
-
if (!selectedWallet) return null;
|
|
6319
|
-
if (state.selectedTokenSymbol) {
|
|
6320
|
-
return selectedWallet.sources.find(
|
|
6321
|
-
(s) => s.token.symbol === state.selectedTokenSymbol
|
|
6322
|
-
) ?? null;
|
|
6323
|
-
}
|
|
6324
|
-
return selectedWallet.sources.find((s) => s.token.status === "AUTHORIZED") ?? selectedWallet.sources[0] ?? null;
|
|
6325
|
-
}, [selectedWallet, state.selectedTokenSymbol]);
|
|
6393
|
+
const selectedSource = selectedSourceForWallet(selectedWallet, state.selectedTokenSymbol);
|
|
6326
6394
|
const sourceName = selectedAccount?.name ?? selectedWallet?.chain.name ?? "Wallet";
|
|
6327
|
-
const pendingConnections =
|
|
6328
|
-
() =>
|
|
6329
|
-
(a) => a.wallets.length > 0 && !a.wallets.some((w) => w.status === "ACTIVE")
|
|
6330
|
-
),
|
|
6331
|
-
[state.accounts]
|
|
6395
|
+
const pendingConnections = state.accounts.filter(
|
|
6396
|
+
(a) => a.wallets.length > 0 && !a.wallets.some((w) => w.status === "ACTIVE")
|
|
6332
6397
|
);
|
|
6333
|
-
const depositEligibleAccounts =
|
|
6334
|
-
|
|
6335
|
-
|
|
6336
|
-
|
|
6337
|
-
|
|
6338
|
-
|
|
6339
|
-
|
|
6340
|
-
for (const wallet of acct.wallets) {
|
|
6341
|
-
for (const source of wallet.sources) {
|
|
6342
|
-
if (source.balance.available.amount > max) {
|
|
6343
|
-
max = source.balance.available.amount;
|
|
6344
|
-
}
|
|
6398
|
+
const depositEligibleAccounts = getDepositEligibleAccounts(state.accounts);
|
|
6399
|
+
let maxSourceBalance = 0;
|
|
6400
|
+
for (const acct of state.accounts) {
|
|
6401
|
+
for (const wallet of acct.wallets) {
|
|
6402
|
+
for (const source of wallet.sources) {
|
|
6403
|
+
if (source.balance.available.amount > maxSourceBalance) {
|
|
6404
|
+
maxSourceBalance = source.balance.available.amount;
|
|
6345
6405
|
}
|
|
6346
6406
|
}
|
|
6347
6407
|
}
|
|
6348
|
-
|
|
6349
|
-
|
|
6350
|
-
const
|
|
6351
|
-
|
|
6352
|
-
|
|
6353
|
-
for (const wallet of acct.wallets) {
|
|
6354
|
-
count += wallet.sources.filter(
|
|
6355
|
-
(s) => s.balance.available.amount > 0
|
|
6356
|
-
).length;
|
|
6357
|
-
}
|
|
6408
|
+
}
|
|
6409
|
+
let tokenCount = 0;
|
|
6410
|
+
for (const acct of state.accounts) {
|
|
6411
|
+
for (const wallet of acct.wallets) {
|
|
6412
|
+
tokenCount += wallet.sources.filter((s) => s.balance.available.amount > 0).length;
|
|
6358
6413
|
}
|
|
6359
|
-
|
|
6360
|
-
}, [state.accounts]);
|
|
6414
|
+
}
|
|
6361
6415
|
return {
|
|
6362
6416
|
sourceType,
|
|
6363
6417
|
sourceId,
|
|
@@ -6371,6 +6425,9 @@ function useDerivedState(state) {
|
|
|
6371
6425
|
tokenCount
|
|
6372
6426
|
};
|
|
6373
6427
|
}
|
|
6428
|
+
function useDerivedState(state) {
|
|
6429
|
+
return useMemo(() => computeDerivedState(state), [state]);
|
|
6430
|
+
}
|
|
6374
6431
|
function useAuthHandlers(dispatch, verificationTarget) {
|
|
6375
6432
|
const {
|
|
6376
6433
|
sendCode: sendEmailCode,
|
|
@@ -6936,7 +6993,9 @@ function useProviderHandlers(deps) {
|
|
|
6936
6993
|
reauthTokenRef,
|
|
6937
6994
|
authenticated,
|
|
6938
6995
|
merchantAuthorization,
|
|
6939
|
-
destination
|
|
6996
|
+
destination,
|
|
6997
|
+
guestSessionToken,
|
|
6998
|
+
selectedProviderId
|
|
6940
6999
|
} = deps;
|
|
6941
7000
|
const wagmiConfig2 = useConfig();
|
|
6942
7001
|
const { connectAsync, connectors } = useConnect();
|
|
@@ -7249,7 +7308,7 @@ function useProviderHandlers(deps) {
|
|
|
7249
7308
|
reauthTokenRef
|
|
7250
7309
|
]);
|
|
7251
7310
|
const handleNavigateToTokenPicker = useCallback(() => {
|
|
7252
|
-
dispatch({ type: "SET_USER_INTENT", intent: "
|
|
7311
|
+
dispatch({ type: "SET_USER_INTENT", intent: { step: "token-picker" } });
|
|
7253
7312
|
}, [dispatch]);
|
|
7254
7313
|
const handleSelectAuthorizedToken = useCallback((walletId, tokenSymbol) => {
|
|
7255
7314
|
dispatch({ type: "SELECT_TOKEN", walletId, tokenSymbol });
|
|
@@ -7332,6 +7391,76 @@ function useProviderHandlers(deps) {
|
|
|
7332
7391
|
reauthSessionIdRef,
|
|
7333
7392
|
reauthTokenRef
|
|
7334
7393
|
]);
|
|
7394
|
+
const handlePreauthorize = useCallback(async () => {
|
|
7395
|
+
if (!guestSessionToken || !selectedProviderId) {
|
|
7396
|
+
dispatch({
|
|
7397
|
+
type: "SET_ERROR",
|
|
7398
|
+
error: "Missing guest session or wallet provider. Try again from the payment screen."
|
|
7399
|
+
});
|
|
7400
|
+
return;
|
|
7401
|
+
}
|
|
7402
|
+
const isMobile = !shouldUseWalletConnector({
|
|
7403
|
+
useWalletConnector: useWalletConnectorProp,
|
|
7404
|
+
userAgent: typeof navigator === "undefined" ? void 0 : navigator.userAgent
|
|
7405
|
+
});
|
|
7406
|
+
const providerName = providers.find((p) => p.id === selectedProviderId)?.name ?? "Wallet";
|
|
7407
|
+
if (!isMobile) {
|
|
7408
|
+
dispatch({ type: "GUEST_PREAUTH_BEGIN" });
|
|
7409
|
+
}
|
|
7410
|
+
try {
|
|
7411
|
+
const created = await createGuestAccount(
|
|
7412
|
+
apiBaseUrl,
|
|
7413
|
+
guestSessionToken,
|
|
7414
|
+
selectedProviderId,
|
|
7415
|
+
providerName
|
|
7416
|
+
);
|
|
7417
|
+
const session = await fetchAuthorizationSessionByToken(
|
|
7418
|
+
apiBaseUrl,
|
|
7419
|
+
created.sessionToken
|
|
7420
|
+
);
|
|
7421
|
+
if (isMobile) {
|
|
7422
|
+
handlingMobileReturnRef.current = false;
|
|
7423
|
+
mobileSetupFlowRef.current = true;
|
|
7424
|
+
setupAccountIdRef.current = created.accountId;
|
|
7425
|
+
persistMobileFlowState({
|
|
7426
|
+
accountId: created.accountId,
|
|
7427
|
+
sessionId: session.id,
|
|
7428
|
+
deeplinkUri: created.sessionUri,
|
|
7429
|
+
providerId: selectedProviderId,
|
|
7430
|
+
isSetup: true,
|
|
7431
|
+
guestSessionToken
|
|
7432
|
+
});
|
|
7433
|
+
triggerDeeplink(created.sessionUri);
|
|
7434
|
+
dispatch({ type: "MOBILE_DEEPLINK_READY", deeplinkUri: created.sessionUri });
|
|
7435
|
+
}
|
|
7436
|
+
dispatch({
|
|
7437
|
+
type: "GUEST_PREAUTH_DETECTED",
|
|
7438
|
+
accountId: created.accountId,
|
|
7439
|
+
sessionId: session.id
|
|
7440
|
+
});
|
|
7441
|
+
} catch (err) {
|
|
7442
|
+
captureException(err);
|
|
7443
|
+
if (!isMobile) {
|
|
7444
|
+
dispatch({ type: "GUEST_PREAUTH_END" });
|
|
7445
|
+
}
|
|
7446
|
+
dispatch({
|
|
7447
|
+
type: "SET_ERROR",
|
|
7448
|
+
error: err instanceof Error ? err.message : "Failed to start preauthorization"
|
|
7449
|
+
});
|
|
7450
|
+
onError?.(err instanceof Error ? err.message : "Failed to start preauthorization");
|
|
7451
|
+
}
|
|
7452
|
+
}, [
|
|
7453
|
+
guestSessionToken,
|
|
7454
|
+
selectedProviderId,
|
|
7455
|
+
providers,
|
|
7456
|
+
apiBaseUrl,
|
|
7457
|
+
dispatch,
|
|
7458
|
+
onError,
|
|
7459
|
+
useWalletConnectorProp,
|
|
7460
|
+
mobileSetupFlowRef,
|
|
7461
|
+
handlingMobileReturnRef,
|
|
7462
|
+
setupAccountIdRef
|
|
7463
|
+
]);
|
|
7335
7464
|
return {
|
|
7336
7465
|
handlePrepareProvider,
|
|
7337
7466
|
handleSelectProvider,
|
|
@@ -7340,7 +7469,8 @@ function useProviderHandlers(deps) {
|
|
|
7340
7469
|
handleIncreaseLimit,
|
|
7341
7470
|
handleNavigateToTokenPicker,
|
|
7342
7471
|
handleSelectAuthorizedToken,
|
|
7343
|
-
handleAuthorizeToken
|
|
7472
|
+
handleAuthorizeToken,
|
|
7473
|
+
handlePreauthorize
|
|
7344
7474
|
};
|
|
7345
7475
|
}
|
|
7346
7476
|
|
|
@@ -7561,7 +7691,6 @@ function useOneTapSetupHandlers(deps) {
|
|
|
7561
7691
|
selectSourceTokenSymbol
|
|
7562
7692
|
} = deps;
|
|
7563
7693
|
const [savingOneTapLimit, setSavingOneTapLimit] = useState(false);
|
|
7564
|
-
const oneTapLimitSavedDuringSetupRef = useRef(false);
|
|
7565
7694
|
const handleSetupOneTap = useCallback(async (limit) => {
|
|
7566
7695
|
setSavingOneTapLimit(true);
|
|
7567
7696
|
try {
|
|
@@ -7582,12 +7711,12 @@ function useOneTapSetupHandlers(deps) {
|
|
|
7582
7711
|
chainName = recommended?.chainName ?? choices[0]?.chainName ?? "Base";
|
|
7583
7712
|
tokenSymbol = recommended?.tokenSymbol ?? choices[0]?.tokens[0]?.tokenSymbol ?? "USDC";
|
|
7584
7713
|
}
|
|
7585
|
-
|
|
7714
|
+
dispatch({ type: "SET_ONE_TAP_LIMIT_SAVED_DURING_SETUP", saved: true });
|
|
7586
7715
|
authExecutor.resolveSelectSource({ chainName, tokenSymbol });
|
|
7587
7716
|
} else if (authExecutor.pendingOneTapSetup) {
|
|
7588
7717
|
authExecutor.resolveOneTapSetup();
|
|
7589
7718
|
}
|
|
7590
|
-
dispatch({ type: "SET_USER_INTENT", intent:
|
|
7719
|
+
dispatch({ type: "SET_USER_INTENT", intent: { step: "deposit" } });
|
|
7591
7720
|
} catch (err) {
|
|
7592
7721
|
captureException(err);
|
|
7593
7722
|
dispatch({
|
|
@@ -7600,124 +7729,63 @@ function useOneTapSetupHandlers(deps) {
|
|
|
7600
7729
|
}, [getAccessToken, apiBaseUrl, authExecutor, dispatch, selectSourceChainName, selectSourceTokenSymbol]);
|
|
7601
7730
|
return {
|
|
7602
7731
|
handleSetupOneTap,
|
|
7603
|
-
savingOneTapLimit
|
|
7604
|
-
oneTapLimitSavedDuringSetupRef
|
|
7732
|
+
savingOneTapLimit
|
|
7605
7733
|
};
|
|
7606
7734
|
}
|
|
7607
|
-
|
|
7608
|
-
// src/dataLoading.ts
|
|
7609
|
-
function resolveDataLoadAction({
|
|
7610
|
-
authenticated,
|
|
7611
|
-
accountsCount,
|
|
7612
|
-
hasActiveCredential,
|
|
7613
|
-
loading
|
|
7614
|
-
}) {
|
|
7615
|
-
if (!authenticated || accountsCount > 0 || !hasActiveCredential) {
|
|
7616
|
-
return "reset";
|
|
7617
|
-
}
|
|
7618
|
-
if (loading) {
|
|
7619
|
-
return "wait";
|
|
7620
|
-
}
|
|
7621
|
-
return "load";
|
|
7622
|
-
}
|
|
7623
|
-
|
|
7624
|
-
// src/processingStatus.ts
|
|
7625
|
-
var PROCESSING_TIMEOUT_MS = 18e4;
|
|
7626
|
-
function resolvePreferredTransfer(polledTransfer, localTransfer) {
|
|
7627
|
-
return polledTransfer ?? localTransfer;
|
|
7628
|
-
}
|
|
7629
|
-
function getTransferStatus(polledTransfer, localTransfer) {
|
|
7630
|
-
const transfer = resolvePreferredTransfer(polledTransfer, localTransfer);
|
|
7631
|
-
return transfer?.status ?? "UNKNOWN";
|
|
7632
|
-
}
|
|
7633
|
-
function hasProcessingTimedOut(processingStartedAtMs, nowMs) {
|
|
7634
|
-
if (!processingStartedAtMs) return false;
|
|
7635
|
-
return nowMs - processingStartedAtMs >= PROCESSING_TIMEOUT_MS;
|
|
7636
|
-
}
|
|
7637
|
-
var STATUS_DISPLAY_LABELS = {
|
|
7638
|
-
CREATED: "created",
|
|
7639
|
-
AUTHORIZED: "authorized",
|
|
7640
|
-
SENDING: "sending",
|
|
7641
|
-
SENT: "confirming delivery",
|
|
7642
|
-
COMPLETED: "completed",
|
|
7643
|
-
FAILED: "failed"
|
|
7644
|
-
};
|
|
7645
|
-
function getStatusDisplayLabel(status) {
|
|
7646
|
-
return STATUS_DISPLAY_LABELS[status] ?? status;
|
|
7647
|
-
}
|
|
7648
|
-
function buildProcessingTimeoutMessage(status) {
|
|
7649
|
-
const label = getStatusDisplayLabel(status);
|
|
7650
|
-
return `Payment is taking longer than expected (status: ${label}). Please try again.`;
|
|
7651
|
-
}
|
|
7652
|
-
|
|
7653
|
-
// src/hooks/usePaymentEffects.ts
|
|
7654
|
-
function usePaymentEffects(deps) {
|
|
7735
|
+
function useOtpEffects(deps) {
|
|
7655
7736
|
const {
|
|
7656
7737
|
state,
|
|
7657
7738
|
dispatch,
|
|
7658
|
-
ready,
|
|
7659
7739
|
authenticated,
|
|
7660
|
-
apiBaseUrl,
|
|
7661
|
-
depositAmount,
|
|
7662
|
-
onComplete,
|
|
7663
|
-
onError,
|
|
7664
|
-
polling,
|
|
7665
|
-
authExecutor,
|
|
7666
|
-
reloadAccounts,
|
|
7667
7740
|
activeOtpStatus,
|
|
7668
7741
|
activeOtpErrorMessage,
|
|
7669
7742
|
otpCode,
|
|
7670
|
-
handleVerifyLoginCode
|
|
7743
|
+
handleVerifyLoginCode
|
|
7744
|
+
} = deps;
|
|
7745
|
+
useEffect(() => {
|
|
7746
|
+
if (authenticated || !state.verificationTarget) return;
|
|
7747
|
+
if (activeOtpErrorMessage) dispatch({ type: "SET_ERROR", error: activeOtpErrorMessage });
|
|
7748
|
+
}, [activeOtpErrorMessage, authenticated, state.verificationTarget, dispatch]);
|
|
7749
|
+
useEffect(() => {
|
|
7750
|
+
if (state.verificationTarget && !authenticated && /^\d{6}$/.test(otpCode.trim()) && activeOtpStatus === "awaiting-code-input") {
|
|
7751
|
+
handleVerifyLoginCode();
|
|
7752
|
+
}
|
|
7753
|
+
}, [otpCode, state.verificationTarget, authenticated, activeOtpStatus, handleVerifyLoginCode]);
|
|
7754
|
+
}
|
|
7755
|
+
function usePasskeyCheckEffect(deps) {
|
|
7756
|
+
const {
|
|
7757
|
+
dispatch,
|
|
7758
|
+
ready,
|
|
7759
|
+
authenticated,
|
|
7760
|
+
apiBaseUrl,
|
|
7761
|
+
activeCredentialId,
|
|
7762
|
+
passkeyConfigLoaded,
|
|
7763
|
+
checkingPasskeyRef,
|
|
7671
7764
|
setAuthInput,
|
|
7672
7765
|
setOtpCode,
|
|
7766
|
+
polling,
|
|
7673
7767
|
mobileSetupFlowRef,
|
|
7674
7768
|
handlingMobileReturnRef,
|
|
7675
7769
|
setupAccountIdRef,
|
|
7676
7770
|
reauthSessionIdRef,
|
|
7677
7771
|
reauthTokenRef,
|
|
7678
|
-
|
|
7679
|
-
pollingTransferIdRef,
|
|
7680
|
-
processingStartedAtRef,
|
|
7681
|
-
checkingPasskeyRef,
|
|
7682
|
-
pendingSelectSourceAction,
|
|
7683
|
-
selectSourceChoices,
|
|
7684
|
-
selectSourceRecommended,
|
|
7685
|
-
setSelectSourceChainName,
|
|
7686
|
-
setSelectSourceTokenSymbol,
|
|
7687
|
-
initializedSelectSourceActionRef,
|
|
7688
|
-
oneTapLimitSavedDuringSetupRef,
|
|
7689
|
-
handleAuthorizedMobileReturn
|
|
7772
|
+
pollingTransferIdRef
|
|
7690
7773
|
} = deps;
|
|
7691
7774
|
const { getAccessToken } = usePrivy();
|
|
7692
|
-
const onCompleteRef = useRef(onComplete);
|
|
7693
|
-
onCompleteRef.current = onComplete;
|
|
7775
|
+
const onCompleteRef = useRef(deps.onComplete);
|
|
7776
|
+
onCompleteRef.current = deps.onComplete;
|
|
7694
7777
|
const getAccessTokenRef = useRef(getAccessToken);
|
|
7695
7778
|
getAccessTokenRef.current = getAccessToken;
|
|
7696
7779
|
const pollingRef = useRef(polling);
|
|
7697
7780
|
pollingRef.current = polling;
|
|
7698
|
-
const handleAuthorizedMobileReturnRef = useRef(handleAuthorizedMobileReturn);
|
|
7699
|
-
handleAuthorizedMobileReturnRef.current = handleAuthorizedMobileReturn;
|
|
7700
|
-
const lastAccountFetchRef = useRef(0);
|
|
7701
|
-
useEffect(() => {
|
|
7702
|
-
if (depositAmount != null) {
|
|
7703
|
-
dispatch({ type: "SYNC_AMOUNT", amount: depositAmount.toString() });
|
|
7704
|
-
}
|
|
7705
|
-
}, [depositAmount, dispatch]);
|
|
7706
|
-
useEffect(() => {
|
|
7707
|
-
if (authenticated || !state.verificationTarget) return;
|
|
7708
|
-
if (activeOtpErrorMessage) dispatch({ type: "SET_ERROR", error: activeOtpErrorMessage });
|
|
7709
|
-
}, [activeOtpErrorMessage, authenticated, state.verificationTarget, dispatch]);
|
|
7710
|
-
useEffect(() => {
|
|
7711
|
-
if (state.verificationTarget && !authenticated && /^\d{6}$/.test(otpCode.trim()) && activeOtpStatus === "awaiting-code-input") {
|
|
7712
|
-
handleVerifyLoginCode();
|
|
7713
|
-
}
|
|
7714
|
-
}, [otpCode, state.verificationTarget, authenticated, activeOtpStatus, handleVerifyLoginCode]);
|
|
7781
|
+
const handleAuthorizedMobileReturnRef = useRef(deps.handleAuthorizedMobileReturn);
|
|
7782
|
+
handleAuthorizedMobileReturnRef.current = deps.handleAuthorizedMobileReturn;
|
|
7715
7783
|
useEffect(() => {
|
|
7716
7784
|
if (!ready || !authenticated) {
|
|
7717
7785
|
checkingPasskeyRef.current = false;
|
|
7718
7786
|
return;
|
|
7719
7787
|
}
|
|
7720
|
-
if (
|
|
7788
|
+
if (passkeyConfigLoaded || activeCredentialId) return;
|
|
7721
7789
|
if (checkingPasskeyRef.current) return;
|
|
7722
7790
|
checkingPasskeyRef.current = true;
|
|
7723
7791
|
let cancelled = false;
|
|
@@ -7815,11 +7883,7 @@ function usePaymentEffects(deps) {
|
|
|
7815
7883
|
return;
|
|
7816
7884
|
}
|
|
7817
7885
|
if (existingTransfer.status === "AUTHORIZED") {
|
|
7818
|
-
|
|
7819
|
-
await handleAuthorizedMobileReturnRef.current(existingTransfer, true);
|
|
7820
|
-
} else {
|
|
7821
|
-
await handleAuthorizedMobileReturnRef.current(existingTransfer, false);
|
|
7822
|
-
}
|
|
7886
|
+
await handleAuthorizedMobileReturnRef.current(existingTransfer, !!persisted.isSetup);
|
|
7823
7887
|
return;
|
|
7824
7888
|
}
|
|
7825
7889
|
if (persisted.isSetup) {
|
|
@@ -7870,11 +7934,9 @@ function usePaymentEffects(deps) {
|
|
|
7870
7934
|
knownIds: allPasskeys.map((p) => p.credentialId),
|
|
7871
7935
|
oneTapLimit: config.defaultAllowance ?? void 0
|
|
7872
7936
|
});
|
|
7873
|
-
if (allPasskeys.length === 0)
|
|
7874
|
-
|
|
7875
|
-
|
|
7876
|
-
if (state.activeCredentialId && allPasskeys.some((p) => p.credentialId === state.activeCredentialId)) {
|
|
7877
|
-
await restoreState(state.activeCredentialId, token);
|
|
7937
|
+
if (allPasskeys.length === 0) return;
|
|
7938
|
+
if (activeCredentialId && allPasskeys.some((p) => p.credentialId === activeCredentialId)) {
|
|
7939
|
+
await restoreState(activeCredentialId, token);
|
|
7878
7940
|
return;
|
|
7879
7941
|
}
|
|
7880
7942
|
if (cancelled) return;
|
|
@@ -7906,7 +7968,39 @@ function usePaymentEffects(deps) {
|
|
|
7906
7968
|
cancelled = true;
|
|
7907
7969
|
checkingPasskeyRef.current = false;
|
|
7908
7970
|
};
|
|
7909
|
-
}, [ready, authenticated, apiBaseUrl,
|
|
7971
|
+
}, [ready, authenticated, apiBaseUrl, activeCredentialId, passkeyConfigLoaded]);
|
|
7972
|
+
}
|
|
7973
|
+
|
|
7974
|
+
// src/dataLoading.ts
|
|
7975
|
+
function resolveDataLoadAction({
|
|
7976
|
+
authenticated,
|
|
7977
|
+
accountsCount,
|
|
7978
|
+
hasActiveCredential,
|
|
7979
|
+
loading
|
|
7980
|
+
}) {
|
|
7981
|
+
if (!authenticated || accountsCount > 0 || !hasActiveCredential) {
|
|
7982
|
+
return "reset";
|
|
7983
|
+
}
|
|
7984
|
+
if (loading) {
|
|
7985
|
+
return "wait";
|
|
7986
|
+
}
|
|
7987
|
+
return "load";
|
|
7988
|
+
}
|
|
7989
|
+
|
|
7990
|
+
// src/hooks/useDataLoadEffect.ts
|
|
7991
|
+
function useDataLoadEffect(deps) {
|
|
7992
|
+
const {
|
|
7993
|
+
state,
|
|
7994
|
+
dispatch,
|
|
7995
|
+
authenticated,
|
|
7996
|
+
apiBaseUrl,
|
|
7997
|
+
depositAmount,
|
|
7998
|
+
loadingDataRef
|
|
7999
|
+
} = deps;
|
|
8000
|
+
const { getAccessToken } = usePrivy();
|
|
8001
|
+
const getAccessTokenRef = useRef(getAccessToken);
|
|
8002
|
+
getAccessTokenRef.current = getAccessToken;
|
|
8003
|
+
const lastAccountFetchRef = useRef(0);
|
|
7910
8004
|
useEffect(() => {
|
|
7911
8005
|
const loadAction = resolveDataLoadAction({
|
|
7912
8006
|
authenticated,
|
|
@@ -8006,6 +8100,61 @@ function usePaymentEffects(deps) {
|
|
|
8006
8100
|
cancelled = true;
|
|
8007
8101
|
};
|
|
8008
8102
|
}, [authenticated, state.providers.length, state.activeCredentialId, apiBaseUrl]);
|
|
8103
|
+
useEffect(() => {
|
|
8104
|
+
if (state.accounts.length > 0 && state.activeCredentialId && !state.loadingData && !state.transfer && authenticated && Date.now() - lastAccountFetchRef.current > 15e3) {
|
|
8105
|
+
lastAccountFetchRef.current = Date.now();
|
|
8106
|
+
deps.reloadAccounts();
|
|
8107
|
+
}
|
|
8108
|
+
}, [
|
|
8109
|
+
state.accounts.length,
|
|
8110
|
+
state.activeCredentialId,
|
|
8111
|
+
state.loadingData,
|
|
8112
|
+
state.transfer,
|
|
8113
|
+
authenticated,
|
|
8114
|
+
deps
|
|
8115
|
+
]);
|
|
8116
|
+
}
|
|
8117
|
+
|
|
8118
|
+
// src/processingStatus.ts
|
|
8119
|
+
var PROCESSING_TIMEOUT_MS = 18e4;
|
|
8120
|
+
function resolvePreferredTransfer(polledTransfer, localTransfer) {
|
|
8121
|
+
return polledTransfer ?? localTransfer;
|
|
8122
|
+
}
|
|
8123
|
+
function getTransferStatus(polledTransfer, localTransfer) {
|
|
8124
|
+
const transfer = resolvePreferredTransfer(polledTransfer, localTransfer);
|
|
8125
|
+
return transfer?.status ?? "UNKNOWN";
|
|
8126
|
+
}
|
|
8127
|
+
function hasProcessingTimedOut(processingStartedAtMs, nowMs) {
|
|
8128
|
+
if (!processingStartedAtMs) return false;
|
|
8129
|
+
return nowMs - processingStartedAtMs >= PROCESSING_TIMEOUT_MS;
|
|
8130
|
+
}
|
|
8131
|
+
var STATUS_DISPLAY_LABELS = {
|
|
8132
|
+
CREATED: "created",
|
|
8133
|
+
AUTHORIZED: "authorized",
|
|
8134
|
+
SENDING: "sending",
|
|
8135
|
+
SENT: "confirming delivery",
|
|
8136
|
+
COMPLETED: "completed",
|
|
8137
|
+
FAILED: "failed"
|
|
8138
|
+
};
|
|
8139
|
+
function getStatusDisplayLabel(status) {
|
|
8140
|
+
return STATUS_DISPLAY_LABELS[status] ?? status;
|
|
8141
|
+
}
|
|
8142
|
+
function buildProcessingTimeoutMessage(status) {
|
|
8143
|
+
const label = getStatusDisplayLabel(status);
|
|
8144
|
+
return `Payment is taking longer than expected (status: ${label}). Please try again.`;
|
|
8145
|
+
}
|
|
8146
|
+
|
|
8147
|
+
// src/hooks/useProcessingEffect.ts
|
|
8148
|
+
function useProcessingEffect(deps) {
|
|
8149
|
+
const {
|
|
8150
|
+
state,
|
|
8151
|
+
dispatch,
|
|
8152
|
+
polling,
|
|
8153
|
+
processingStartedAtRef,
|
|
8154
|
+
onComplete,
|
|
8155
|
+
onError,
|
|
8156
|
+
reloadAccounts
|
|
8157
|
+
} = deps;
|
|
8009
8158
|
useEffect(() => {
|
|
8010
8159
|
if (!polling.transfer) return;
|
|
8011
8160
|
if (polling.transfer.status === "COMPLETED") {
|
|
@@ -8018,19 +8167,6 @@ function usePaymentEffects(deps) {
|
|
|
8018
8167
|
dispatch({ type: "TRANSFER_FAILED", transfer: polling.transfer, error: "Transfer failed." });
|
|
8019
8168
|
}
|
|
8020
8169
|
}, [polling.transfer, onComplete, dispatch, reloadAccounts]);
|
|
8021
|
-
useEffect(() => {
|
|
8022
|
-
if (state.accounts.length > 0 && state.activeCredentialId && !state.loadingData && !state.transfer && authenticated && Date.now() - lastAccountFetchRef.current > 15e3) {
|
|
8023
|
-
lastAccountFetchRef.current = Date.now();
|
|
8024
|
-
reloadAccounts();
|
|
8025
|
-
}
|
|
8026
|
-
}, [
|
|
8027
|
-
state.accounts.length,
|
|
8028
|
-
state.activeCredentialId,
|
|
8029
|
-
state.loadingData,
|
|
8030
|
-
state.transfer,
|
|
8031
|
-
authenticated,
|
|
8032
|
-
reloadAccounts
|
|
8033
|
-
]);
|
|
8034
8170
|
useEffect(() => {
|
|
8035
8171
|
const isProcessing = state.creatingTransfer || state.transfer != null && ["CREATED", "SENDING", "SENT"].includes(state.transfer.status);
|
|
8036
8172
|
if (!isProcessing) {
|
|
@@ -8066,6 +8202,26 @@ function usePaymentEffects(deps) {
|
|
|
8066
8202
|
dispatch,
|
|
8067
8203
|
processingStartedAtRef
|
|
8068
8204
|
]);
|
|
8205
|
+
}
|
|
8206
|
+
function useMobilePollingEffect(deps) {
|
|
8207
|
+
const {
|
|
8208
|
+
state,
|
|
8209
|
+
dispatch,
|
|
8210
|
+
polling,
|
|
8211
|
+
mobileSetupFlowRef,
|
|
8212
|
+
handlingMobileReturnRef,
|
|
8213
|
+
setupAccountIdRef,
|
|
8214
|
+
reauthSessionIdRef,
|
|
8215
|
+
reauthTokenRef,
|
|
8216
|
+
pollingTransferIdRef,
|
|
8217
|
+
reloadAccounts,
|
|
8218
|
+
apiBaseUrl
|
|
8219
|
+
} = deps;
|
|
8220
|
+
const { getAccessToken } = usePrivy();
|
|
8221
|
+
const getAccessTokenRef = useRef(getAccessToken);
|
|
8222
|
+
getAccessTokenRef.current = getAccessToken;
|
|
8223
|
+
const handleAuthorizedMobileReturnRef = useRef(deps.handleAuthorizedMobileReturn);
|
|
8224
|
+
handleAuthorizedMobileReturnRef.current = deps.handleAuthorizedMobileReturn;
|
|
8069
8225
|
useEffect(() => {
|
|
8070
8226
|
if (!state.mobileFlow) {
|
|
8071
8227
|
handlingMobileReturnRef.current = false;
|
|
@@ -8074,8 +8230,8 @@ function usePaymentEffects(deps) {
|
|
|
8074
8230
|
if (handlingMobileReturnRef.current) return;
|
|
8075
8231
|
const polledTransfer = polling.transfer;
|
|
8076
8232
|
if (!polledTransfer || polledTransfer.status !== "AUTHORIZED") return;
|
|
8077
|
-
void
|
|
8078
|
-
}, [state.mobileFlow, polling.transfer,
|
|
8233
|
+
void handleAuthorizedMobileReturnRef.current(polledTransfer, mobileSetupFlowRef.current);
|
|
8234
|
+
}, [state.mobileFlow, polling.transfer, handlingMobileReturnRef, mobileSetupFlowRef]);
|
|
8079
8235
|
useEffect(() => {
|
|
8080
8236
|
if (!state.mobileFlow || !mobileSetupFlowRef.current) return;
|
|
8081
8237
|
if (!state.activeCredentialId || !setupAccountIdRef.current) return;
|
|
@@ -8151,14 +8307,10 @@ function usePaymentEffects(deps) {
|
|
|
8151
8307
|
poll();
|
|
8152
8308
|
const intervalId = window.setInterval(poll, POLL_INTERVAL_MS);
|
|
8153
8309
|
const handleVisibility = () => {
|
|
8154
|
-
if (document.visibilityState === "visible" && !cancelled)
|
|
8155
|
-
poll();
|
|
8156
|
-
}
|
|
8310
|
+
if (document.visibilityState === "visible" && !cancelled) poll();
|
|
8157
8311
|
};
|
|
8158
8312
|
const handlePageShow = (e) => {
|
|
8159
|
-
if (e.persisted && !cancelled)
|
|
8160
|
-
poll();
|
|
8161
|
-
}
|
|
8313
|
+
if (e.persisted && !cancelled) poll();
|
|
8162
8314
|
};
|
|
8163
8315
|
document.addEventListener("visibilitychange", handleVisibility);
|
|
8164
8316
|
window.addEventListener("pageshow", handlePageShow);
|
|
@@ -8209,6 +8361,16 @@ function usePaymentEffects(deps) {
|
|
|
8209
8361
|
handlingMobileReturnRef,
|
|
8210
8362
|
pollingTransferIdRef
|
|
8211
8363
|
]);
|
|
8364
|
+
}
|
|
8365
|
+
function useSelectSourceEffect(deps) {
|
|
8366
|
+
const {
|
|
8367
|
+
pendingSelectSourceAction,
|
|
8368
|
+
selectSourceChoices,
|
|
8369
|
+
selectSourceRecommended,
|
|
8370
|
+
setSelectSourceChainName,
|
|
8371
|
+
setSelectSourceTokenSymbol,
|
|
8372
|
+
initializedSelectSourceActionRef
|
|
8373
|
+
} = deps;
|
|
8212
8374
|
useEffect(() => {
|
|
8213
8375
|
if (!pendingSelectSourceAction) {
|
|
8214
8376
|
initializedSelectSourceActionRef.current = null;
|
|
@@ -8239,57 +8401,27 @@ function usePaymentEffects(deps) {
|
|
|
8239
8401
|
setSelectSourceTokenSymbol,
|
|
8240
8402
|
initializedSelectSourceActionRef
|
|
8241
8403
|
]);
|
|
8404
|
+
}
|
|
8405
|
+
function useOneTapAutoResolveEffect(deps) {
|
|
8406
|
+
const { authExecutor, dispatch, oneTapLimitSavedDuringSetup, reloadAccounts } = deps;
|
|
8242
8407
|
const pendingOneTapSetupAction = authExecutor.pendingOneTapSetup;
|
|
8243
8408
|
useEffect(() => {
|
|
8244
|
-
if (pendingOneTapSetupAction &&
|
|
8245
|
-
|
|
8409
|
+
if (pendingOneTapSetupAction && oneTapLimitSavedDuringSetup) {
|
|
8410
|
+
dispatch({ type: "SET_ONE_TAP_LIMIT_SAVED_DURING_SETUP", saved: false });
|
|
8246
8411
|
authExecutor.resolveOneTapSetup();
|
|
8247
8412
|
}
|
|
8248
|
-
}, [pendingOneTapSetupAction, authExecutor,
|
|
8413
|
+
}, [pendingOneTapSetupAction, authExecutor, dispatch, oneTapLimitSavedDuringSetup]);
|
|
8249
8414
|
useEffect(() => {
|
|
8250
|
-
if (pendingOneTapSetupAction && !
|
|
8415
|
+
if (pendingOneTapSetupAction && !oneTapLimitSavedDuringSetup) {
|
|
8251
8416
|
reloadAccounts();
|
|
8252
8417
|
}
|
|
8253
|
-
}, [pendingOneTapSetupAction, reloadAccounts,
|
|
8254
|
-
|
|
8255
|
-
|
|
8256
|
-
|
|
8257
|
-
|
|
8258
|
-
|
|
8259
|
-
|
|
8260
|
-
try {
|
|
8261
|
-
let result = await fetchGuestAccount(apiBaseUrl, state.guestSessionToken);
|
|
8262
|
-
if (cancelled) return;
|
|
8263
|
-
if (!result && state.selectedProviderId) {
|
|
8264
|
-
const providerName = state.providers.find((p) => p.id === state.selectedProviderId)?.name ?? "Wallet";
|
|
8265
|
-
const created = await createGuestAccount(
|
|
8266
|
-
apiBaseUrl,
|
|
8267
|
-
state.guestSessionToken,
|
|
8268
|
-
state.selectedProviderId,
|
|
8269
|
-
providerName
|
|
8270
|
-
);
|
|
8271
|
-
if (cancelled) return;
|
|
8272
|
-
result = { accountId: created.accountId, hasPasskey: false, walletAddress: null };
|
|
8273
|
-
}
|
|
8274
|
-
if (result && !result.hasPasskey) {
|
|
8275
|
-
dispatch({ type: "GUEST_PREAUTH_DETECTED", accountId: result.accountId });
|
|
8276
|
-
}
|
|
8277
|
-
} catch {
|
|
8278
|
-
}
|
|
8279
|
-
};
|
|
8280
|
-
ensureGuestAccount();
|
|
8281
|
-
return () => {
|
|
8282
|
-
cancelled = true;
|
|
8283
|
-
};
|
|
8284
|
-
}, [
|
|
8285
|
-
state.transfer,
|
|
8286
|
-
state.guestSessionToken,
|
|
8287
|
-
state.guestPreauthAccountId,
|
|
8288
|
-
state.selectedProviderId,
|
|
8289
|
-
state.providers,
|
|
8290
|
-
apiBaseUrl,
|
|
8291
|
-
dispatch
|
|
8292
|
-
]);
|
|
8418
|
+
}, [pendingOneTapSetupAction, reloadAccounts, oneTapLimitSavedDuringSetup]);
|
|
8419
|
+
}
|
|
8420
|
+
function useGuestPreauthEffect(deps) {
|
|
8421
|
+
const { state, dispatch, authenticated, apiBaseUrl, reloadAccounts } = deps;
|
|
8422
|
+
const { getAccessToken } = usePrivy();
|
|
8423
|
+
const getAccessTokenRef = useRef(getAccessToken);
|
|
8424
|
+
getAccessTokenRef.current = getAccessToken;
|
|
8293
8425
|
const settingOwnerRef = useRef(false);
|
|
8294
8426
|
useEffect(() => {
|
|
8295
8427
|
if (!state.guestPreauthAccountId) return;
|
|
@@ -8298,6 +8430,8 @@ function usePaymentEffects(deps) {
|
|
|
8298
8430
|
if (!authenticated) return;
|
|
8299
8431
|
if (!state.guestSessionToken) return;
|
|
8300
8432
|
if (settingOwnerRef.current) return;
|
|
8433
|
+
const hasActive = state.accounts.some((a) => a.wallets.some((w) => w.status === "ACTIVE"));
|
|
8434
|
+
if (!hasActive) return;
|
|
8301
8435
|
settingOwnerRef.current = true;
|
|
8302
8436
|
let cancelled = false;
|
|
8303
8437
|
const setOwner = async () => {
|
|
@@ -8335,12 +8469,73 @@ function usePaymentEffects(deps) {
|
|
|
8335
8469
|
state.activeCredentialId,
|
|
8336
8470
|
state.activePublicKey,
|
|
8337
8471
|
state.guestSessionToken,
|
|
8472
|
+
state.accounts,
|
|
8338
8473
|
authenticated,
|
|
8339
8474
|
apiBaseUrl,
|
|
8340
8475
|
dispatch,
|
|
8341
8476
|
reloadAccounts
|
|
8342
8477
|
]);
|
|
8343
8478
|
}
|
|
8479
|
+
function useGuestDesktopPreauthSessionEffect(deps) {
|
|
8480
|
+
const { state, authExecutor, reloadAccounts, dispatch, desktopGuestPreauth } = deps;
|
|
8481
|
+
const preauthExecutingRef = useRef(false);
|
|
8482
|
+
useEffect(() => {
|
|
8483
|
+
if (!desktopGuestPreauth) return;
|
|
8484
|
+
if (!state.guestPreauthorizing) return;
|
|
8485
|
+
if (!state.guestPreauthSessionId || preauthExecutingRef.current) return;
|
|
8486
|
+
preauthExecutingRef.current = true;
|
|
8487
|
+
const runPreauthSession = async () => {
|
|
8488
|
+
try {
|
|
8489
|
+
await authExecutor.executeSessionById(state.guestPreauthSessionId);
|
|
8490
|
+
await reloadAccounts();
|
|
8491
|
+
} catch {
|
|
8492
|
+
} finally {
|
|
8493
|
+
preauthExecutingRef.current = false;
|
|
8494
|
+
dispatch({ type: "GUEST_PREAUTH_END" });
|
|
8495
|
+
}
|
|
8496
|
+
};
|
|
8497
|
+
void runPreauthSession();
|
|
8498
|
+
}, [
|
|
8499
|
+
desktopGuestPreauth,
|
|
8500
|
+
state.guestPreauthorizing,
|
|
8501
|
+
state.guestPreauthSessionId,
|
|
8502
|
+
authExecutor,
|
|
8503
|
+
reloadAccounts,
|
|
8504
|
+
dispatch
|
|
8505
|
+
]);
|
|
8506
|
+
}
|
|
8507
|
+
function useGuestPreauthPhaseSyncEffect(deps) {
|
|
8508
|
+
const { state, dispatch, authExecutor, isDesktop } = deps;
|
|
8509
|
+
useEffect(() => {
|
|
8510
|
+
if (!state.guestPreauthorizing || !isDesktop) return;
|
|
8511
|
+
const pending = authExecutor.pendingSelectSource;
|
|
8512
|
+
if (pending) {
|
|
8513
|
+
const intent = {
|
|
8514
|
+
step: "select-source",
|
|
8515
|
+
action: pending,
|
|
8516
|
+
isDesktop,
|
|
8517
|
+
skipOneTapLimit: true
|
|
8518
|
+
};
|
|
8519
|
+
if (state.phase.step === "select-source") {
|
|
8520
|
+
const ph = state.phase;
|
|
8521
|
+
if (ph.skipOneTapLimit && ph.action.id === pending.id) {
|
|
8522
|
+
return;
|
|
8523
|
+
}
|
|
8524
|
+
}
|
|
8525
|
+
dispatch({ type: "SET_USER_INTENT", intent });
|
|
8526
|
+
return;
|
|
8527
|
+
}
|
|
8528
|
+
if (state.phase.step === "select-source" && state.phase.skipOneTapLimit === true) {
|
|
8529
|
+
dispatch({ type: "SET_USER_INTENT", intent: { step: "one-tap-setup", action: null } });
|
|
8530
|
+
}
|
|
8531
|
+
}, [
|
|
8532
|
+
state.guestPreauthorizing,
|
|
8533
|
+
state.phase,
|
|
8534
|
+
isDesktop,
|
|
8535
|
+
authExecutor.pendingSelectSource,
|
|
8536
|
+
dispatch
|
|
8537
|
+
]);
|
|
8538
|
+
}
|
|
8344
8539
|
function BlinkPayment(props) {
|
|
8345
8540
|
const resetKey = useRef(0);
|
|
8346
8541
|
const handleBoundaryReset = useCallback(() => {
|
|
@@ -8362,6 +8557,10 @@ function BlinkPaymentInner({
|
|
|
8362
8557
|
const { apiBaseUrl, depositAmount } = useBlinkConfig();
|
|
8363
8558
|
const { ready, authenticated, logout, getAccessToken } = usePrivy();
|
|
8364
8559
|
useLoginWithOAuth();
|
|
8560
|
+
const isDesktop = shouldUseWalletConnector({
|
|
8561
|
+
useWalletConnector: useWalletConnectorProp,
|
|
8562
|
+
userAgent: typeof navigator === "undefined" ? void 0 : navigator.userAgent
|
|
8563
|
+
});
|
|
8365
8564
|
const [state, dispatch] = useReducer(
|
|
8366
8565
|
paymentReducer,
|
|
8367
8566
|
{
|
|
@@ -8445,7 +8644,9 @@ function BlinkPaymentInner({
|
|
|
8445
8644
|
reauthTokenRef: mobileFlowRefs.reauthTokenRef,
|
|
8446
8645
|
authenticated,
|
|
8447
8646
|
merchantAuthorization,
|
|
8448
|
-
destination
|
|
8647
|
+
destination,
|
|
8648
|
+
guestSessionToken: state.guestSessionToken,
|
|
8649
|
+
selectedProviderId: state.selectedProviderId
|
|
8449
8650
|
});
|
|
8450
8651
|
const oneTapSetup = useOneTapSetupHandlers({
|
|
8451
8652
|
dispatch,
|
|
@@ -8467,13 +8668,12 @@ function BlinkPaymentInner({
|
|
|
8467
8668
|
clearMobileFlowState();
|
|
8468
8669
|
transfer.processingStartedAtRef.current = null;
|
|
8469
8670
|
transfer.pollingTransferIdRef.current = null;
|
|
8470
|
-
oneTapSetup.oneTapLimitSavedDuringSetupRef.current = false;
|
|
8471
8671
|
dispatch({
|
|
8472
8672
|
type: "NEW_PAYMENT",
|
|
8473
8673
|
depositAmount,
|
|
8474
8674
|
firstAccountId: state.accounts.length > 0 ? state.accounts[0].id : null
|
|
8475
8675
|
});
|
|
8476
|
-
}, [depositAmount, state.accounts, transfer
|
|
8676
|
+
}, [depositAmount, state.accounts, transfer]);
|
|
8477
8677
|
const handleLogout = useCallback(async () => {
|
|
8478
8678
|
try {
|
|
8479
8679
|
await logout();
|
|
@@ -8485,65 +8685,112 @@ function BlinkPaymentInner({
|
|
|
8485
8685
|
}
|
|
8486
8686
|
polling.stopPolling();
|
|
8487
8687
|
passkey.checkingPasskeyRef.current = false;
|
|
8488
|
-
oneTapSetup.oneTapLimitSavedDuringSetupRef.current = false;
|
|
8489
8688
|
auth.setAuthInput("");
|
|
8490
8689
|
auth.setOtpCode("");
|
|
8491
8690
|
dispatch({ type: "LOGOUT", depositAmount });
|
|
8492
|
-
}, [logout, polling, depositAmount, auth, passkey
|
|
8493
|
-
|
|
8691
|
+
}, [logout, polling, depositAmount, auth, passkey]);
|
|
8692
|
+
useEffect(() => {
|
|
8693
|
+
if (depositAmount != null) {
|
|
8694
|
+
dispatch({ type: "SYNC_AMOUNT", amount: depositAmount.toString() });
|
|
8695
|
+
}
|
|
8696
|
+
}, [depositAmount, dispatch]);
|
|
8697
|
+
useOtpEffects({
|
|
8494
8698
|
state,
|
|
8495
8699
|
dispatch,
|
|
8496
|
-
ready,
|
|
8497
8700
|
authenticated,
|
|
8498
|
-
apiBaseUrl,
|
|
8499
|
-
depositAmount,
|
|
8500
|
-
onComplete,
|
|
8501
|
-
onError,
|
|
8502
|
-
polling,
|
|
8503
|
-
authExecutor,
|
|
8504
|
-
reloadAccounts: transfer.reloadAccounts,
|
|
8505
8701
|
activeOtpStatus: auth.activeOtpStatus,
|
|
8506
8702
|
activeOtpErrorMessage: auth.activeOtpErrorMessage,
|
|
8507
8703
|
otpCode: auth.otpCode,
|
|
8508
8704
|
handleVerifyLoginCode: auth.handleVerifyLoginCode,
|
|
8509
8705
|
setAuthInput: auth.setAuthInput,
|
|
8706
|
+
setOtpCode: auth.setOtpCode
|
|
8707
|
+
});
|
|
8708
|
+
usePasskeyCheckEffect({
|
|
8709
|
+
dispatch,
|
|
8710
|
+
ready,
|
|
8711
|
+
authenticated,
|
|
8712
|
+
apiBaseUrl,
|
|
8713
|
+
activeCredentialId: state.activeCredentialId,
|
|
8714
|
+
passkeyConfigLoaded: state.passkeyConfigLoaded,
|
|
8715
|
+
checkingPasskeyRef: passkey.checkingPasskeyRef,
|
|
8716
|
+
setAuthInput: auth.setAuthInput,
|
|
8510
8717
|
setOtpCode: auth.setOtpCode,
|
|
8718
|
+
polling,
|
|
8511
8719
|
mobileSetupFlowRef: mobileFlowRefs.mobileSetupFlowRef,
|
|
8512
8720
|
handlingMobileReturnRef: mobileFlowRefs.handlingMobileReturnRef,
|
|
8513
8721
|
setupAccountIdRef: mobileFlowRefs.setupAccountIdRef,
|
|
8514
8722
|
reauthSessionIdRef: mobileFlowRefs.reauthSessionIdRef,
|
|
8515
8723
|
reauthTokenRef: mobileFlowRefs.reauthTokenRef,
|
|
8516
|
-
loadingDataRef: mobileFlowRefs.loadingDataRef,
|
|
8517
8724
|
pollingTransferIdRef: transfer.pollingTransferIdRef,
|
|
8725
|
+
handleAuthorizedMobileReturn: mobileFlow.handleAuthorizedMobileReturn,
|
|
8726
|
+
onComplete
|
|
8727
|
+
});
|
|
8728
|
+
useDataLoadEffect({
|
|
8729
|
+
state,
|
|
8730
|
+
dispatch,
|
|
8731
|
+
authenticated,
|
|
8732
|
+
apiBaseUrl,
|
|
8733
|
+
depositAmount,
|
|
8734
|
+
loadingDataRef: mobileFlowRefs.loadingDataRef,
|
|
8735
|
+
reloadAccounts: transfer.reloadAccounts
|
|
8736
|
+
});
|
|
8737
|
+
useProcessingEffect({
|
|
8738
|
+
state,
|
|
8739
|
+
dispatch,
|
|
8740
|
+
polling,
|
|
8518
8741
|
processingStartedAtRef: transfer.processingStartedAtRef,
|
|
8519
|
-
|
|
8742
|
+
onComplete,
|
|
8743
|
+
onError,
|
|
8744
|
+
reloadAccounts: transfer.reloadAccounts
|
|
8745
|
+
});
|
|
8746
|
+
useMobilePollingEffect({
|
|
8747
|
+
state,
|
|
8748
|
+
dispatch,
|
|
8749
|
+
polling,
|
|
8750
|
+
mobileSetupFlowRef: mobileFlowRefs.mobileSetupFlowRef,
|
|
8751
|
+
handlingMobileReturnRef: mobileFlowRefs.handlingMobileReturnRef,
|
|
8752
|
+
setupAccountIdRef: mobileFlowRefs.setupAccountIdRef,
|
|
8753
|
+
reauthSessionIdRef: mobileFlowRefs.reauthSessionIdRef,
|
|
8754
|
+
reauthTokenRef: mobileFlowRefs.reauthTokenRef,
|
|
8755
|
+
pollingTransferIdRef: transfer.pollingTransferIdRef,
|
|
8756
|
+
reloadAccounts: transfer.reloadAccounts,
|
|
8757
|
+
handleAuthorizedMobileReturn: mobileFlow.handleAuthorizedMobileReturn,
|
|
8758
|
+
apiBaseUrl
|
|
8759
|
+
});
|
|
8760
|
+
useSelectSourceEffect({
|
|
8520
8761
|
pendingSelectSourceAction: sourceSelection.pendingSelectSourceAction,
|
|
8521
8762
|
selectSourceChoices: sourceSelection.selectSourceChoices,
|
|
8522
8763
|
selectSourceRecommended: sourceSelection.selectSourceRecommended,
|
|
8523
8764
|
setSelectSourceChainName: sourceSelection.setSelectSourceChainName,
|
|
8524
8765
|
setSelectSourceTokenSymbol: sourceSelection.setSelectSourceTokenSymbol,
|
|
8525
|
-
initializedSelectSourceActionRef: sourceSelection.initializedSelectSourceActionRef
|
|
8526
|
-
oneTapLimitSavedDuringSetupRef: oneTapSetup.oneTapLimitSavedDuringSetupRef,
|
|
8527
|
-
handleAuthorizedMobileReturn: mobileFlow.handleAuthorizedMobileReturn
|
|
8766
|
+
initializedSelectSourceActionRef: sourceSelection.initializedSelectSourceActionRef
|
|
8528
8767
|
});
|
|
8529
|
-
|
|
8530
|
-
|
|
8531
|
-
|
|
8532
|
-
|
|
8533
|
-
|
|
8534
|
-
|
|
8535
|
-
|
|
8536
|
-
|
|
8537
|
-
|
|
8538
|
-
}, [
|
|
8539
|
-
state.isGuestFlow,
|
|
8540
|
-
state.selectedProviderId,
|
|
8541
|
-
state.activeCredentialId,
|
|
8542
|
-
state.transfer,
|
|
8543
|
-
state.accounts,
|
|
8768
|
+
useOneTapAutoResolveEffect({
|
|
8769
|
+
authExecutor,
|
|
8770
|
+
dispatch,
|
|
8771
|
+
oneTapLimitSavedDuringSetup: state.oneTapLimitSavedDuringSetup,
|
|
8772
|
+
reloadAccounts: transfer.reloadAccounts
|
|
8773
|
+
});
|
|
8774
|
+
useGuestPreauthEffect({
|
|
8775
|
+
state,
|
|
8776
|
+
dispatch,
|
|
8544
8777
|
authenticated,
|
|
8545
|
-
|
|
8546
|
-
|
|
8778
|
+
apiBaseUrl,
|
|
8779
|
+
reloadAccounts: transfer.reloadAccounts
|
|
8780
|
+
});
|
|
8781
|
+
useGuestPreauthPhaseSyncEffect({
|
|
8782
|
+
state,
|
|
8783
|
+
dispatch,
|
|
8784
|
+
authExecutor,
|
|
8785
|
+
isDesktop
|
|
8786
|
+
});
|
|
8787
|
+
useGuestDesktopPreauthSessionEffect({
|
|
8788
|
+
state,
|
|
8789
|
+
authExecutor,
|
|
8790
|
+
reloadAccounts: transfer.reloadAccounts,
|
|
8791
|
+
dispatch,
|
|
8792
|
+
desktopGuestPreauth: isDesktop
|
|
8793
|
+
});
|
|
8547
8794
|
const handlers = useMemo(() => ({
|
|
8548
8795
|
onSendLoginCode: auth.handleSendLoginCode,
|
|
8549
8796
|
onVerifyLoginCode: auth.handleVerifyLoginCode,
|
|
@@ -8566,7 +8813,7 @@ function BlinkPaymentInner({
|
|
|
8566
8813
|
onBackFromOpenWallet: () => dispatch({ type: "CLEAR_MOBILE_STATE" }),
|
|
8567
8814
|
onLogout: handleLogout,
|
|
8568
8815
|
onNewPayment: handleNewPayment,
|
|
8569
|
-
|
|
8816
|
+
onSetPhase: (phase) => dispatch({ type: "SET_USER_INTENT", intent: phase }),
|
|
8570
8817
|
onSetAuthInput: auth.setAuthInput,
|
|
8571
8818
|
onSetOtpCode: (code) => {
|
|
8572
8819
|
auth.setOtpCode(code);
|
|
@@ -8581,7 +8828,7 @@ function BlinkPaymentInner({
|
|
|
8581
8828
|
onAuthorizeToken: provider.handleAuthorizeToken,
|
|
8582
8829
|
onSelectGuestToken: guestTransfer.handleSelectGuestToken,
|
|
8583
8830
|
onLogin: () => dispatch({ type: "REQUEST_LOGIN" }),
|
|
8584
|
-
onPreauthorize:
|
|
8831
|
+
onPreauthorize: provider.handlePreauthorize
|
|
8585
8832
|
}), [
|
|
8586
8833
|
auth,
|
|
8587
8834
|
passkey,
|
|
@@ -8597,46 +8844,52 @@ function BlinkPaymentInner({
|
|
|
8597
8844
|
return /* @__PURE__ */ jsx(
|
|
8598
8845
|
StepRenderer,
|
|
8599
8846
|
{
|
|
8600
|
-
|
|
8601
|
-
|
|
8602
|
-
|
|
8603
|
-
|
|
8604
|
-
|
|
8605
|
-
|
|
8606
|
-
|
|
8607
|
-
|
|
8608
|
-
|
|
8609
|
-
|
|
8610
|
-
|
|
8611
|
-
|
|
8612
|
-
|
|
8613
|
-
|
|
8614
|
-
|
|
8615
|
-
|
|
8616
|
-
|
|
8617
|
-
|
|
8618
|
-
|
|
8619
|
-
|
|
8620
|
-
|
|
8621
|
-
|
|
8622
|
-
|
|
8623
|
-
|
|
8624
|
-
|
|
8625
|
-
|
|
8626
|
-
|
|
8627
|
-
|
|
8628
|
-
|
|
8629
|
-
|
|
8630
|
-
|
|
8631
|
-
|
|
8632
|
-
|
|
8633
|
-
|
|
8634
|
-
|
|
8847
|
+
flow: {
|
|
8848
|
+
state,
|
|
8849
|
+
authenticated,
|
|
8850
|
+
activeOtpStatus: auth.activeOtpStatus,
|
|
8851
|
+
isDesktop,
|
|
8852
|
+
merchantName,
|
|
8853
|
+
onBack,
|
|
8854
|
+
onDismiss,
|
|
8855
|
+
depositAmount
|
|
8856
|
+
},
|
|
8857
|
+
remote: {
|
|
8858
|
+
pollingTransfer: polling.transfer,
|
|
8859
|
+
pollingError: polling.error,
|
|
8860
|
+
authExecutorError: authExecutor.error,
|
|
8861
|
+
transferSigningSigning: transferSigning.signing,
|
|
8862
|
+
transferSigningError: transferSigning.error,
|
|
8863
|
+
pendingSelectSource: authExecutor.pendingSelectSource,
|
|
8864
|
+
pendingOneTapSetup: authExecutor.pendingOneTapSetup
|
|
8865
|
+
},
|
|
8866
|
+
derived: {
|
|
8867
|
+
pendingConnections: derived.pendingConnections,
|
|
8868
|
+
depositEligibleAccounts: derived.depositEligibleAccounts,
|
|
8869
|
+
sourceName: derived.sourceName,
|
|
8870
|
+
maxSourceBalance: derived.maxSourceBalance,
|
|
8871
|
+
tokenCount: derived.tokenCount,
|
|
8872
|
+
selectedAccount: derived.selectedAccount,
|
|
8873
|
+
selectedSource: derived.selectedSource,
|
|
8874
|
+
selectSourceChoices: sourceSelection.selectSourceChoices,
|
|
8875
|
+
selectSourceRecommended: sourceSelection.selectSourceRecommended,
|
|
8876
|
+
selectSourceAvailableBalance: sourceSelection.selectSourceAvailableBalance
|
|
8877
|
+
},
|
|
8878
|
+
forms: {
|
|
8879
|
+
authInput: auth.authInput,
|
|
8880
|
+
otpCode: auth.otpCode,
|
|
8881
|
+
selectSourceChainName: sourceSelection.selectSourceChainName,
|
|
8882
|
+
selectSourceTokenSymbol: sourceSelection.selectSourceTokenSymbol,
|
|
8883
|
+
savingOneTapLimit: oneTapSetup.savingOneTapLimit,
|
|
8884
|
+
guestTokenEntries: guestTransfer.guestTokenEntries,
|
|
8885
|
+
guestLoadingBalances: guestTransfer.loadingBalances,
|
|
8886
|
+
guestSettingSender: guestTransfer.settingSender
|
|
8887
|
+
},
|
|
8635
8888
|
handlers
|
|
8636
8889
|
}
|
|
8637
8890
|
);
|
|
8638
8891
|
}
|
|
8639
8892
|
|
|
8640
|
-
export { AdvancedSourceScreen, BLINK_LOGO, BLINK_MASCOT, BlinkLoadingScreen, BlinkPayment, BlinkProvider, FlowPhaseProvider, IconCircle, InfoBanner, OutlineButton, PasskeyIframeBlockedError, PasskeyScreen, PoweredByFooter, PrimaryButton, ScreenHeader, ScreenLayout, SelectSourceScreen, SettingsMenu, SetupScreen, Spinner, StepList, TokenPickerScreen, api_exports as blinkApi, buildPasskeyPopupOptions, createPasskeyCredential, createPasskeyViaPopup, darkTheme, deviceHasPasskey, findDevicePasskey, findDevicePasskeyViaPopup, getTheme, lightTheme, resolvePasskeyRpId,
|
|
8893
|
+
export { AdvancedSourceScreen, BLINK_LOGO, BLINK_MASCOT, BlinkLoadingScreen, BlinkPayment, BlinkProvider, FlowPhaseProvider, IconCircle, InfoBanner, OutlineButton, PasskeyIframeBlockedError, PasskeyScreen, PoweredByFooter, PrimaryButton, ScreenHeader, ScreenLayout, SelectSourceScreen, SettingsMenu, SetupScreen, Spinner, StepList, TokenPickerScreen, api_exports as blinkApi, buildPasskeyPopupOptions, createPasskeyCredential, createPasskeyViaPopup, darkTheme, deviceHasPasskey, findDevicePasskey, findDevicePasskeyViaPopup, getTheme, lightTheme, resolvePasskeyRpId, screenForPhase, useAuthorizationExecutor, useBlinkConfig, useBlinkDepositAmount, useTransferPolling, useTransferSigning };
|
|
8641
8894
|
//# sourceMappingURL=index.js.map
|
|
8642
8895
|
//# sourceMappingURL=index.js.map
|