@swype-org/react-sdk 0.1.132 → 0.1.142
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 +1227 -919
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4 -5
- package/dist/index.d.ts +4 -5
- package/dist/index.js +1228 -920
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createContext, useRef, useState, useCallback, useMemo, useContext, useEffect, useReducer, Component } from 'react';
|
|
2
|
-
import { PrivyProvider, usePrivy, useLoginWithEmail, useLoginWithSms
|
|
2
|
+
import { PrivyProvider, usePrivy, useLoginWithOAuth, useLoginWithEmail, useLoginWithSms } from '@privy-io/react-auth';
|
|
3
3
|
import { createConfig, http, WagmiProvider, useConfig, useConnect, useSwitchChain } from 'wagmi';
|
|
4
4
|
import { mainnet, arbitrum, base, polygon, bsc } from 'wagmi/chains';
|
|
5
5
|
import { injected } from 'wagmi/connectors';
|
|
@@ -153,261 +153,6 @@ function useSwypeDepositAmount() {
|
|
|
153
153
|
};
|
|
154
154
|
}
|
|
155
155
|
|
|
156
|
-
// src/api.ts
|
|
157
|
-
var api_exports = {};
|
|
158
|
-
__export(api_exports, {
|
|
159
|
-
createAccount: () => createAccount,
|
|
160
|
-
createAccountAuthorizationSession: () => createAccountAuthorizationSession,
|
|
161
|
-
createTransfer: () => createTransfer,
|
|
162
|
-
fetchAccount: () => fetchAccount,
|
|
163
|
-
fetchAccounts: () => fetchAccounts,
|
|
164
|
-
fetchAuthorizationSession: () => fetchAuthorizationSession,
|
|
165
|
-
fetchChains: () => fetchChains,
|
|
166
|
-
fetchMerchantPublicKey: () => fetchMerchantPublicKey,
|
|
167
|
-
fetchProviders: () => fetchProviders,
|
|
168
|
-
fetchTransfer: () => fetchTransfer,
|
|
169
|
-
fetchUserConfig: () => fetchUserConfig,
|
|
170
|
-
registerPasskey: () => registerPasskey,
|
|
171
|
-
reportActionCompletion: () => reportActionCompletion,
|
|
172
|
-
reportPasskeyActivity: () => reportPasskeyActivity,
|
|
173
|
-
signTransfer: () => signTransfer,
|
|
174
|
-
updateUserConfig: () => updateUserConfig,
|
|
175
|
-
updateUserConfigBySession: () => updateUserConfigBySession
|
|
176
|
-
});
|
|
177
|
-
async function throwApiError(res) {
|
|
178
|
-
const body = await res.json().catch(() => null);
|
|
179
|
-
const detail = body?.error ?? body;
|
|
180
|
-
const msg = detail?.message ?? res.statusText;
|
|
181
|
-
const code = detail?.code ?? String(res.status);
|
|
182
|
-
throw new Error(`${res.status} \u2014 ${code}: ${msg}`);
|
|
183
|
-
}
|
|
184
|
-
async function fetchProviders(apiBaseUrl, token) {
|
|
185
|
-
const res = await fetch(`${apiBaseUrl}/v1/providers`, {
|
|
186
|
-
headers: { Authorization: `Bearer ${token}` }
|
|
187
|
-
});
|
|
188
|
-
if (!res.ok) await throwApiError(res);
|
|
189
|
-
const data = await res.json();
|
|
190
|
-
return data.items;
|
|
191
|
-
}
|
|
192
|
-
async function fetchChains(apiBaseUrl, token) {
|
|
193
|
-
const res = await fetch(`${apiBaseUrl}/v1/chains`, {
|
|
194
|
-
headers: { Authorization: `Bearer ${token}` }
|
|
195
|
-
});
|
|
196
|
-
if (!res.ok) await throwApiError(res);
|
|
197
|
-
const data = await res.json();
|
|
198
|
-
return data.items;
|
|
199
|
-
}
|
|
200
|
-
async function fetchAccounts(apiBaseUrl, token, credentialId) {
|
|
201
|
-
const params = new URLSearchParams({ credentialId });
|
|
202
|
-
const res = await fetch(`${apiBaseUrl}/v1/accounts?${params.toString()}`, {
|
|
203
|
-
headers: { Authorization: `Bearer ${token}` }
|
|
204
|
-
});
|
|
205
|
-
if (!res.ok) await throwApiError(res);
|
|
206
|
-
const data = await res.json();
|
|
207
|
-
return data.items;
|
|
208
|
-
}
|
|
209
|
-
async function fetchAccount(apiBaseUrl, token, accountId, credentialId) {
|
|
210
|
-
const params = new URLSearchParams({ credentialId });
|
|
211
|
-
const res = await fetch(`${apiBaseUrl}/v1/accounts/${accountId}?${params.toString()}`, {
|
|
212
|
-
headers: { Authorization: `Bearer ${token}` }
|
|
213
|
-
});
|
|
214
|
-
if (!res.ok) await throwApiError(res);
|
|
215
|
-
return await res.json();
|
|
216
|
-
}
|
|
217
|
-
async function createAccount(apiBaseUrl, token, params) {
|
|
218
|
-
const body = {
|
|
219
|
-
id: params.id ?? crypto.randomUUID(),
|
|
220
|
-
name: params.name,
|
|
221
|
-
credentialId: params.credentialId,
|
|
222
|
-
providerId: params.providerId
|
|
223
|
-
};
|
|
224
|
-
if (params.nickname) {
|
|
225
|
-
body.nickname = params.nickname;
|
|
226
|
-
}
|
|
227
|
-
const res = await fetch(`${apiBaseUrl}/v1/accounts`, {
|
|
228
|
-
method: "POST",
|
|
229
|
-
headers: {
|
|
230
|
-
"Content-Type": "application/json",
|
|
231
|
-
Authorization: `Bearer ${token}`
|
|
232
|
-
},
|
|
233
|
-
body: JSON.stringify(body)
|
|
234
|
-
});
|
|
235
|
-
if (!res.ok) await throwApiError(res);
|
|
236
|
-
return await res.json();
|
|
237
|
-
}
|
|
238
|
-
async function createAccountAuthorizationSession(apiBaseUrl, token, accountId, credentialId, options) {
|
|
239
|
-
const body = { credentialId };
|
|
240
|
-
if (options?.tokenAddress) body.tokenAddress = options.tokenAddress;
|
|
241
|
-
if (options?.chainId != null) body.chainId = options.chainId;
|
|
242
|
-
const res = await fetch(
|
|
243
|
-
`${apiBaseUrl}/v1/accounts/${accountId}/authorization-sessions`,
|
|
244
|
-
{
|
|
245
|
-
method: "POST",
|
|
246
|
-
headers: {
|
|
247
|
-
"Content-Type": "application/json",
|
|
248
|
-
Authorization: `Bearer ${token}`
|
|
249
|
-
},
|
|
250
|
-
body: JSON.stringify(body)
|
|
251
|
-
}
|
|
252
|
-
);
|
|
253
|
-
if (!res.ok) await throwApiError(res);
|
|
254
|
-
return await res.json();
|
|
255
|
-
}
|
|
256
|
-
async function createTransfer(apiBaseUrl, token, params) {
|
|
257
|
-
if (!params.merchantAuthorization) {
|
|
258
|
-
throw new Error("merchantAuthorization is required for transfer creation.");
|
|
259
|
-
}
|
|
260
|
-
const body = {
|
|
261
|
-
id: params.id ?? crypto.randomUUID(),
|
|
262
|
-
credentialId: params.credentialId,
|
|
263
|
-
merchantAuthorization: params.merchantAuthorization,
|
|
264
|
-
sources: [{ [params.sourceType]: params.sourceId }],
|
|
265
|
-
destinations: [
|
|
266
|
-
{
|
|
267
|
-
chainId: params.destination.chainId,
|
|
268
|
-
token: { address: params.destination.token.address },
|
|
269
|
-
address: params.destination.address
|
|
270
|
-
}
|
|
271
|
-
],
|
|
272
|
-
amount: {
|
|
273
|
-
amount: params.amount,
|
|
274
|
-
currency: params.currency ?? "USD"
|
|
275
|
-
}
|
|
276
|
-
};
|
|
277
|
-
const res = await fetch(`${apiBaseUrl}/v1/transfers`, {
|
|
278
|
-
method: "POST",
|
|
279
|
-
headers: {
|
|
280
|
-
"Content-Type": "application/json",
|
|
281
|
-
Authorization: `Bearer ${token}`
|
|
282
|
-
},
|
|
283
|
-
body: JSON.stringify(body)
|
|
284
|
-
});
|
|
285
|
-
if (!res.ok) await throwApiError(res);
|
|
286
|
-
return await res.json();
|
|
287
|
-
}
|
|
288
|
-
async function fetchMerchantPublicKey(apiBaseUrl, merchantId) {
|
|
289
|
-
const res = await fetch(
|
|
290
|
-
`${apiBaseUrl}/v1/merchants/${encodeURIComponent(merchantId)}/public-key`
|
|
291
|
-
);
|
|
292
|
-
if (!res.ok) await throwApiError(res);
|
|
293
|
-
return await res.json();
|
|
294
|
-
}
|
|
295
|
-
async function fetchTransfer(apiBaseUrl, token, transferId, authorizationSessionToken) {
|
|
296
|
-
if (!token && !authorizationSessionToken) {
|
|
297
|
-
throw new Error("Missing auth credentials for transfer fetch.");
|
|
298
|
-
}
|
|
299
|
-
const res = await fetch(`${apiBaseUrl}/v1/transfers/${transferId}`, {
|
|
300
|
-
headers: {
|
|
301
|
-
...token ? { Authorization: `Bearer ${token}` } : {},
|
|
302
|
-
...authorizationSessionToken ? { "x-authorization-session-token": authorizationSessionToken } : {}
|
|
303
|
-
}
|
|
304
|
-
});
|
|
305
|
-
if (!res.ok) await throwApiError(res);
|
|
306
|
-
return await res.json();
|
|
307
|
-
}
|
|
308
|
-
async function signTransfer(apiBaseUrl, token, transferId, signedUserOp, authorizationSessionToken) {
|
|
309
|
-
if (!token && !authorizationSessionToken) {
|
|
310
|
-
throw new Error("Missing auth credentials for transfer signing.");
|
|
311
|
-
}
|
|
312
|
-
const res = await fetch(`${apiBaseUrl}/v1/transfers/${transferId}`, {
|
|
313
|
-
method: "PATCH",
|
|
314
|
-
headers: {
|
|
315
|
-
"Content-Type": "application/json",
|
|
316
|
-
...token ? { Authorization: `Bearer ${token}` } : {},
|
|
317
|
-
...authorizationSessionToken ? { "x-authorization-session-token": authorizationSessionToken } : {}
|
|
318
|
-
},
|
|
319
|
-
body: JSON.stringify({ signedUserOp })
|
|
320
|
-
});
|
|
321
|
-
if (!res.ok) await throwApiError(res);
|
|
322
|
-
return await res.json();
|
|
323
|
-
}
|
|
324
|
-
async function fetchAuthorizationSession(apiBaseUrl, sessionId) {
|
|
325
|
-
const res = await fetch(
|
|
326
|
-
`${apiBaseUrl}/v1/authorization-sessions/${sessionId}`
|
|
327
|
-
);
|
|
328
|
-
if (!res.ok) await throwApiError(res);
|
|
329
|
-
return await res.json();
|
|
330
|
-
}
|
|
331
|
-
async function registerPasskey(apiBaseUrl, token, credentialId, publicKey) {
|
|
332
|
-
const res = await fetch(`${apiBaseUrl}/v1/users/config/passkey`, {
|
|
333
|
-
method: "POST",
|
|
334
|
-
headers: {
|
|
335
|
-
"Content-Type": "application/json",
|
|
336
|
-
Authorization: `Bearer ${token}`
|
|
337
|
-
},
|
|
338
|
-
body: JSON.stringify({ credentialId, publicKey })
|
|
339
|
-
});
|
|
340
|
-
if (!res.ok) await throwApiError(res);
|
|
341
|
-
}
|
|
342
|
-
async function reportPasskeyActivity(apiBaseUrl, token, credentialId) {
|
|
343
|
-
const res = await fetch(`${apiBaseUrl}/v1/users/config/passkey`, {
|
|
344
|
-
method: "PATCH",
|
|
345
|
-
headers: {
|
|
346
|
-
"Content-Type": "application/json",
|
|
347
|
-
Authorization: `Bearer ${token}`
|
|
348
|
-
},
|
|
349
|
-
body: JSON.stringify({ credentialId })
|
|
350
|
-
});
|
|
351
|
-
if (!res.ok) await throwApiError(res);
|
|
352
|
-
}
|
|
353
|
-
async function fetchUserConfig(apiBaseUrl, token) {
|
|
354
|
-
const res = await fetch(`${apiBaseUrl}/v1/users/config`, {
|
|
355
|
-
headers: { Authorization: `Bearer ${token}` }
|
|
356
|
-
});
|
|
357
|
-
if (!res.ok) await throwApiError(res);
|
|
358
|
-
return await res.json();
|
|
359
|
-
}
|
|
360
|
-
async function updateUserConfig(apiBaseUrl, token, config) {
|
|
361
|
-
const res = await fetch(`${apiBaseUrl}/v1/users`, {
|
|
362
|
-
method: "PATCH",
|
|
363
|
-
headers: {
|
|
364
|
-
"Content-Type": "application/json",
|
|
365
|
-
Authorization: `Bearer ${token}`
|
|
366
|
-
},
|
|
367
|
-
body: JSON.stringify({ config })
|
|
368
|
-
});
|
|
369
|
-
if (!res.ok) await throwApiError(res);
|
|
370
|
-
}
|
|
371
|
-
async function updateUserConfigBySession(apiBaseUrl, sessionId, config) {
|
|
372
|
-
const res = await fetch(
|
|
373
|
-
`${apiBaseUrl}/v1/authorization-sessions/${sessionId}/user-config`,
|
|
374
|
-
{
|
|
375
|
-
method: "PATCH",
|
|
376
|
-
headers: { "Content-Type": "application/json" },
|
|
377
|
-
body: JSON.stringify({ config })
|
|
378
|
-
}
|
|
379
|
-
);
|
|
380
|
-
if (!res.ok) await throwApiError(res);
|
|
381
|
-
}
|
|
382
|
-
async function reportActionCompletion(apiBaseUrl, actionId, result) {
|
|
383
|
-
const res = await fetch(
|
|
384
|
-
`${apiBaseUrl}/v1/authorization-actions/${actionId}`,
|
|
385
|
-
{
|
|
386
|
-
method: "PATCH",
|
|
387
|
-
headers: { "Content-Type": "application/json" },
|
|
388
|
-
body: JSON.stringify({ status: "COMPLETED", result })
|
|
389
|
-
}
|
|
390
|
-
);
|
|
391
|
-
if (!res.ok) await throwApiError(res);
|
|
392
|
-
return await res.json();
|
|
393
|
-
}
|
|
394
|
-
|
|
395
|
-
// src/sentry.ts
|
|
396
|
-
var _mod;
|
|
397
|
-
function captureException(error) {
|
|
398
|
-
if (_mod === null) return;
|
|
399
|
-
if (_mod) {
|
|
400
|
-
_mod.captureException(error);
|
|
401
|
-
return;
|
|
402
|
-
}
|
|
403
|
-
import('@sentry/react').then((m) => {
|
|
404
|
-
_mod = m;
|
|
405
|
-
m.captureException(error);
|
|
406
|
-
}).catch(() => {
|
|
407
|
-
_mod = null;
|
|
408
|
-
});
|
|
409
|
-
}
|
|
410
|
-
|
|
411
156
|
// node_modules/@wagmi/core/dist/esm/version.js
|
|
412
157
|
var version = "2.22.1";
|
|
413
158
|
|
|
@@ -668,8 +413,250 @@ async function getWalletClient(config, parameters = {}) {
|
|
|
668
413
|
return client.extend(walletActions);
|
|
669
414
|
}
|
|
670
415
|
|
|
671
|
-
// src/
|
|
672
|
-
|
|
416
|
+
// src/api.ts
|
|
417
|
+
var api_exports = {};
|
|
418
|
+
__export(api_exports, {
|
|
419
|
+
createAccount: () => createAccount,
|
|
420
|
+
createAccountAuthorizationSession: () => createAccountAuthorizationSession,
|
|
421
|
+
createTransfer: () => createTransfer,
|
|
422
|
+
fetchAccount: () => fetchAccount,
|
|
423
|
+
fetchAccounts: () => fetchAccounts,
|
|
424
|
+
fetchAuthorizationSession: () => fetchAuthorizationSession,
|
|
425
|
+
fetchChains: () => fetchChains,
|
|
426
|
+
fetchMerchantPublicKey: () => fetchMerchantPublicKey,
|
|
427
|
+
fetchProviders: () => fetchProviders,
|
|
428
|
+
fetchTransfer: () => fetchTransfer,
|
|
429
|
+
fetchUserConfig: () => fetchUserConfig,
|
|
430
|
+
registerPasskey: () => registerPasskey,
|
|
431
|
+
reportActionCompletion: () => reportActionCompletion,
|
|
432
|
+
reportPasskeyActivity: () => reportPasskeyActivity,
|
|
433
|
+
signTransfer: () => signTransfer,
|
|
434
|
+
updateUserConfig: () => updateUserConfig,
|
|
435
|
+
updateUserConfigBySession: () => updateUserConfigBySession
|
|
436
|
+
});
|
|
437
|
+
async function throwApiError(res) {
|
|
438
|
+
const body = await res.json().catch(() => null);
|
|
439
|
+
const detail = body?.error ?? body;
|
|
440
|
+
const msg = detail?.message ?? res.statusText;
|
|
441
|
+
const code = detail?.code ?? String(res.status);
|
|
442
|
+
throw new Error(`${res.status} \u2014 ${code}: ${msg}`);
|
|
443
|
+
}
|
|
444
|
+
async function fetchProviders(apiBaseUrl, token) {
|
|
445
|
+
const res = await fetch(`${apiBaseUrl}/v1/providers`, {
|
|
446
|
+
headers: { Authorization: `Bearer ${token}` }
|
|
447
|
+
});
|
|
448
|
+
if (!res.ok) await throwApiError(res);
|
|
449
|
+
const data = await res.json();
|
|
450
|
+
return data.items;
|
|
451
|
+
}
|
|
452
|
+
async function fetchChains(apiBaseUrl, token) {
|
|
453
|
+
const res = await fetch(`${apiBaseUrl}/v1/chains`, {
|
|
454
|
+
headers: { Authorization: `Bearer ${token}` }
|
|
455
|
+
});
|
|
456
|
+
if (!res.ok) await throwApiError(res);
|
|
457
|
+
const data = await res.json();
|
|
458
|
+
return data.items;
|
|
459
|
+
}
|
|
460
|
+
async function fetchAccounts(apiBaseUrl, token, credentialId) {
|
|
461
|
+
const params = new URLSearchParams({ credentialId });
|
|
462
|
+
const res = await fetch(`${apiBaseUrl}/v1/accounts?${params.toString()}`, {
|
|
463
|
+
headers: { Authorization: `Bearer ${token}` }
|
|
464
|
+
});
|
|
465
|
+
if (!res.ok) await throwApiError(res);
|
|
466
|
+
const data = await res.json();
|
|
467
|
+
return data.items;
|
|
468
|
+
}
|
|
469
|
+
async function fetchAccount(apiBaseUrl, token, accountId, credentialId) {
|
|
470
|
+
const params = new URLSearchParams({ credentialId });
|
|
471
|
+
const res = await fetch(`${apiBaseUrl}/v1/accounts/${accountId}?${params.toString()}`, {
|
|
472
|
+
headers: { Authorization: `Bearer ${token}` }
|
|
473
|
+
});
|
|
474
|
+
if (!res.ok) await throwApiError(res);
|
|
475
|
+
return await res.json();
|
|
476
|
+
}
|
|
477
|
+
async function createAccount(apiBaseUrl, token, params) {
|
|
478
|
+
const body = {
|
|
479
|
+
id: params.id ?? crypto.randomUUID(),
|
|
480
|
+
name: params.name,
|
|
481
|
+
credentialId: params.credentialId,
|
|
482
|
+
providerId: params.providerId
|
|
483
|
+
};
|
|
484
|
+
if (params.nickname) {
|
|
485
|
+
body.nickname = params.nickname;
|
|
486
|
+
}
|
|
487
|
+
const res = await fetch(`${apiBaseUrl}/v1/accounts`, {
|
|
488
|
+
method: "POST",
|
|
489
|
+
headers: {
|
|
490
|
+
"Content-Type": "application/json",
|
|
491
|
+
Authorization: `Bearer ${token}`
|
|
492
|
+
},
|
|
493
|
+
body: JSON.stringify(body)
|
|
494
|
+
});
|
|
495
|
+
if (!res.ok) await throwApiError(res);
|
|
496
|
+
return await res.json();
|
|
497
|
+
}
|
|
498
|
+
async function createAccountAuthorizationSession(apiBaseUrl, token, accountId, credentialId, options) {
|
|
499
|
+
const body = { credentialId };
|
|
500
|
+
if (options?.tokenAddress) body.tokenAddress = options.tokenAddress;
|
|
501
|
+
if (options?.chainId != null) body.chainId = options.chainId;
|
|
502
|
+
const res = await fetch(
|
|
503
|
+
`${apiBaseUrl}/v1/accounts/${accountId}/authorization-sessions`,
|
|
504
|
+
{
|
|
505
|
+
method: "POST",
|
|
506
|
+
headers: {
|
|
507
|
+
"Content-Type": "application/json",
|
|
508
|
+
Authorization: `Bearer ${token}`
|
|
509
|
+
},
|
|
510
|
+
body: JSON.stringify(body)
|
|
511
|
+
}
|
|
512
|
+
);
|
|
513
|
+
if (!res.ok) await throwApiError(res);
|
|
514
|
+
return await res.json();
|
|
515
|
+
}
|
|
516
|
+
async function createTransfer(apiBaseUrl, token, params) {
|
|
517
|
+
if (!params.merchantAuthorization) {
|
|
518
|
+
throw new Error("merchantAuthorization is required for transfer creation.");
|
|
519
|
+
}
|
|
520
|
+
const body = {
|
|
521
|
+
id: params.id ?? crypto.randomUUID(),
|
|
522
|
+
credentialId: params.credentialId,
|
|
523
|
+
merchantAuthorization: params.merchantAuthorization,
|
|
524
|
+
sources: [{
|
|
525
|
+
[params.sourceType]: params.sourceId,
|
|
526
|
+
...params.sourceTokenAddress ? { tokenAddress: params.sourceTokenAddress } : {}
|
|
527
|
+
}],
|
|
528
|
+
destinations: [
|
|
529
|
+
{
|
|
530
|
+
chainId: params.destination.chainId,
|
|
531
|
+
token: { address: params.destination.token.address },
|
|
532
|
+
address: params.destination.address
|
|
533
|
+
}
|
|
534
|
+
],
|
|
535
|
+
amount: {
|
|
536
|
+
amount: params.amount,
|
|
537
|
+
currency: params.currency ?? "USD"
|
|
538
|
+
}
|
|
539
|
+
};
|
|
540
|
+
const res = await fetch(`${apiBaseUrl}/v1/transfers`, {
|
|
541
|
+
method: "POST",
|
|
542
|
+
headers: {
|
|
543
|
+
"Content-Type": "application/json",
|
|
544
|
+
Authorization: `Bearer ${token}`
|
|
545
|
+
},
|
|
546
|
+
body: JSON.stringify(body)
|
|
547
|
+
});
|
|
548
|
+
if (!res.ok) await throwApiError(res);
|
|
549
|
+
return await res.json();
|
|
550
|
+
}
|
|
551
|
+
async function fetchMerchantPublicKey(apiBaseUrl, merchantId) {
|
|
552
|
+
const res = await fetch(
|
|
553
|
+
`${apiBaseUrl}/v1/merchants/${encodeURIComponent(merchantId)}/public-key`
|
|
554
|
+
);
|
|
555
|
+
if (!res.ok) await throwApiError(res);
|
|
556
|
+
return await res.json();
|
|
557
|
+
}
|
|
558
|
+
async function fetchTransfer(apiBaseUrl, token, transferId, authorizationSessionToken) {
|
|
559
|
+
if (!token && !authorizationSessionToken) {
|
|
560
|
+
throw new Error("Missing auth credentials for transfer fetch.");
|
|
561
|
+
}
|
|
562
|
+
const res = await fetch(`${apiBaseUrl}/v1/transfers/${transferId}`, {
|
|
563
|
+
headers: {
|
|
564
|
+
...token ? { Authorization: `Bearer ${token}` } : {},
|
|
565
|
+
...authorizationSessionToken ? { "x-authorization-session-token": authorizationSessionToken } : {}
|
|
566
|
+
}
|
|
567
|
+
});
|
|
568
|
+
if (!res.ok) await throwApiError(res);
|
|
569
|
+
return await res.json();
|
|
570
|
+
}
|
|
571
|
+
async function signTransfer(apiBaseUrl, token, transferId, signedUserOp, authorizationSessionToken) {
|
|
572
|
+
if (!token && !authorizationSessionToken) {
|
|
573
|
+
throw new Error("Missing auth credentials for transfer signing.");
|
|
574
|
+
}
|
|
575
|
+
const res = await fetch(`${apiBaseUrl}/v1/transfers/${transferId}`, {
|
|
576
|
+
method: "PATCH",
|
|
577
|
+
headers: {
|
|
578
|
+
"Content-Type": "application/json",
|
|
579
|
+
...token ? { Authorization: `Bearer ${token}` } : {},
|
|
580
|
+
...authorizationSessionToken ? { "x-authorization-session-token": authorizationSessionToken } : {}
|
|
581
|
+
},
|
|
582
|
+
body: JSON.stringify({ signedUserOp })
|
|
583
|
+
});
|
|
584
|
+
if (!res.ok) await throwApiError(res);
|
|
585
|
+
return await res.json();
|
|
586
|
+
}
|
|
587
|
+
async function fetchAuthorizationSession(apiBaseUrl, sessionId) {
|
|
588
|
+
const res = await fetch(
|
|
589
|
+
`${apiBaseUrl}/v1/authorization-sessions/${sessionId}`
|
|
590
|
+
);
|
|
591
|
+
if (!res.ok) await throwApiError(res);
|
|
592
|
+
return await res.json();
|
|
593
|
+
}
|
|
594
|
+
async function registerPasskey(apiBaseUrl, token, credentialId, publicKey) {
|
|
595
|
+
const res = await fetch(`${apiBaseUrl}/v1/users/config/passkey`, {
|
|
596
|
+
method: "POST",
|
|
597
|
+
headers: {
|
|
598
|
+
"Content-Type": "application/json",
|
|
599
|
+
Authorization: `Bearer ${token}`
|
|
600
|
+
},
|
|
601
|
+
body: JSON.stringify({ credentialId, publicKey })
|
|
602
|
+
});
|
|
603
|
+
if (!res.ok) await throwApiError(res);
|
|
604
|
+
}
|
|
605
|
+
async function reportPasskeyActivity(apiBaseUrl, token, credentialId) {
|
|
606
|
+
const res = await fetch(`${apiBaseUrl}/v1/users/config/passkey`, {
|
|
607
|
+
method: "PATCH",
|
|
608
|
+
headers: {
|
|
609
|
+
"Content-Type": "application/json",
|
|
610
|
+
Authorization: `Bearer ${token}`
|
|
611
|
+
},
|
|
612
|
+
body: JSON.stringify({ credentialId })
|
|
613
|
+
});
|
|
614
|
+
if (!res.ok) await throwApiError(res);
|
|
615
|
+
}
|
|
616
|
+
async function fetchUserConfig(apiBaseUrl, token) {
|
|
617
|
+
const res = await fetch(`${apiBaseUrl}/v1/users/config`, {
|
|
618
|
+
headers: { Authorization: `Bearer ${token}` }
|
|
619
|
+
});
|
|
620
|
+
if (!res.ok) await throwApiError(res);
|
|
621
|
+
return await res.json();
|
|
622
|
+
}
|
|
623
|
+
async function updateUserConfig(apiBaseUrl, token, config) {
|
|
624
|
+
const res = await fetch(`${apiBaseUrl}/v1/users`, {
|
|
625
|
+
method: "PATCH",
|
|
626
|
+
headers: {
|
|
627
|
+
"Content-Type": "application/json",
|
|
628
|
+
Authorization: `Bearer ${token}`
|
|
629
|
+
},
|
|
630
|
+
body: JSON.stringify({ config })
|
|
631
|
+
});
|
|
632
|
+
if (!res.ok) await throwApiError(res);
|
|
633
|
+
}
|
|
634
|
+
async function updateUserConfigBySession(apiBaseUrl, sessionId, config) {
|
|
635
|
+
const res = await fetch(
|
|
636
|
+
`${apiBaseUrl}/v1/authorization-sessions/${sessionId}/user-config`,
|
|
637
|
+
{
|
|
638
|
+
method: "PATCH",
|
|
639
|
+
headers: { "Content-Type": "application/json" },
|
|
640
|
+
body: JSON.stringify({ config })
|
|
641
|
+
}
|
|
642
|
+
);
|
|
643
|
+
if (!res.ok) await throwApiError(res);
|
|
644
|
+
}
|
|
645
|
+
async function reportActionCompletion(apiBaseUrl, actionId, result) {
|
|
646
|
+
const res = await fetch(
|
|
647
|
+
`${apiBaseUrl}/v1/authorization-actions/${actionId}`,
|
|
648
|
+
{
|
|
649
|
+
method: "PATCH",
|
|
650
|
+
headers: { "Content-Type": "application/json" },
|
|
651
|
+
body: JSON.stringify({ status: "COMPLETED", result })
|
|
652
|
+
}
|
|
653
|
+
);
|
|
654
|
+
if (!res.ok) await throwApiError(res);
|
|
655
|
+
return await res.json();
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
// src/passkeyRpId.ts
|
|
659
|
+
function normalizeConfiguredDomain(value) {
|
|
673
660
|
return value.replace(/^https?:\/\//, "").replace(/\/.*$/, "").replace(/^\./, "").trim();
|
|
674
661
|
}
|
|
675
662
|
function resolveRootDomainFromHostname(hostname) {
|
|
@@ -1653,170 +1640,6 @@ function useTransferSigning(pollIntervalMs = 2e3, options) {
|
|
|
1653
1640
|
return { signing, signPayload, error, signTransfer: signTransfer2 };
|
|
1654
1641
|
}
|
|
1655
1642
|
|
|
1656
|
-
// src/auth.ts
|
|
1657
|
-
var EMAIL_PATTERN = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
1658
|
-
var PHONE_DIGIT_PATTERN = /^\d{7,15}$/;
|
|
1659
|
-
function normalizePhoneNumber(rawValue) {
|
|
1660
|
-
const trimmed = rawValue.trim();
|
|
1661
|
-
if (!trimmed) return null;
|
|
1662
|
-
const hasExplicitCountryCode = trimmed.startsWith("+");
|
|
1663
|
-
const digits = trimmed.replace(/\D/g, "");
|
|
1664
|
-
if (!PHONE_DIGIT_PATTERN.test(digits)) return null;
|
|
1665
|
-
return hasExplicitCountryCode ? `+${digits}` : digits;
|
|
1666
|
-
}
|
|
1667
|
-
function normalizeAuthIdentifier(rawValue) {
|
|
1668
|
-
const trimmed = rawValue.trim();
|
|
1669
|
-
if (!trimmed) return null;
|
|
1670
|
-
if (EMAIL_PATTERN.test(trimmed)) {
|
|
1671
|
-
return {
|
|
1672
|
-
kind: "email",
|
|
1673
|
-
value: trimmed.toLowerCase()
|
|
1674
|
-
};
|
|
1675
|
-
}
|
|
1676
|
-
const normalizedPhoneNumber = normalizePhoneNumber(trimmed);
|
|
1677
|
-
if (normalizedPhoneNumber) {
|
|
1678
|
-
return {
|
|
1679
|
-
kind: "phone",
|
|
1680
|
-
value: normalizedPhoneNumber
|
|
1681
|
-
};
|
|
1682
|
-
}
|
|
1683
|
-
return null;
|
|
1684
|
-
}
|
|
1685
|
-
function maskAuthIdentifier(identifier) {
|
|
1686
|
-
if (identifier.kind === "email") {
|
|
1687
|
-
const [localPart, domain = ""] = identifier.value.split("@");
|
|
1688
|
-
const localPrefix = localPart.slice(0, 2);
|
|
1689
|
-
return `${localPrefix}${"*".repeat(Math.max(localPart.length - 2, 0))}@${domain}`;
|
|
1690
|
-
}
|
|
1691
|
-
const digits = identifier.value.replace(/\D/g, "");
|
|
1692
|
-
const visibleSuffix = digits.slice(-4);
|
|
1693
|
-
return `***-***-${visibleSuffix}`;
|
|
1694
|
-
}
|
|
1695
|
-
|
|
1696
|
-
// src/processingStatus.ts
|
|
1697
|
-
var PROCESSING_TIMEOUT_MS = 18e4;
|
|
1698
|
-
function resolvePreferredTransfer(polledTransfer, localTransfer) {
|
|
1699
|
-
return polledTransfer ?? localTransfer;
|
|
1700
|
-
}
|
|
1701
|
-
function getTransferStatus(polledTransfer, localTransfer) {
|
|
1702
|
-
const transfer = resolvePreferredTransfer(polledTransfer, localTransfer);
|
|
1703
|
-
return transfer?.status ?? "UNKNOWN";
|
|
1704
|
-
}
|
|
1705
|
-
function hasProcessingTimedOut(processingStartedAtMs, nowMs) {
|
|
1706
|
-
if (!processingStartedAtMs) return false;
|
|
1707
|
-
return nowMs - processingStartedAtMs >= PROCESSING_TIMEOUT_MS;
|
|
1708
|
-
}
|
|
1709
|
-
var STATUS_DISPLAY_LABELS = {
|
|
1710
|
-
CREATED: "created",
|
|
1711
|
-
AUTHORIZED: "authorized",
|
|
1712
|
-
SENDING: "sending",
|
|
1713
|
-
SENT: "confirming delivery",
|
|
1714
|
-
COMPLETED: "completed",
|
|
1715
|
-
FAILED: "failed"
|
|
1716
|
-
};
|
|
1717
|
-
function getStatusDisplayLabel(status) {
|
|
1718
|
-
return STATUS_DISPLAY_LABELS[status] ?? status;
|
|
1719
|
-
}
|
|
1720
|
-
function buildProcessingTimeoutMessage(status) {
|
|
1721
|
-
const label = getStatusDisplayLabel(status);
|
|
1722
|
-
return `Payment is taking longer than expected (status: ${label}). Please try again.`;
|
|
1723
|
-
}
|
|
1724
|
-
|
|
1725
|
-
// src/walletFlow.ts
|
|
1726
|
-
var MOBILE_USER_AGENT_PATTERN = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i;
|
|
1727
|
-
function isMobileUserAgent(userAgent) {
|
|
1728
|
-
if (!userAgent) {
|
|
1729
|
-
return false;
|
|
1730
|
-
}
|
|
1731
|
-
return MOBILE_USER_AGENT_PATTERN.test(userAgent);
|
|
1732
|
-
}
|
|
1733
|
-
function shouldUseWalletConnector(options) {
|
|
1734
|
-
return options.useWalletConnector ?? !isMobileUserAgent(options.userAgent);
|
|
1735
|
-
}
|
|
1736
|
-
|
|
1737
|
-
// src/deeplink.ts
|
|
1738
|
-
var IFRAME_CLEANUP_DELAY_MS = 3e3;
|
|
1739
|
-
var LOCATION_FALLBACK_DELAY_MS = 100;
|
|
1740
|
-
function triggerDeeplink(uri) {
|
|
1741
|
-
try {
|
|
1742
|
-
const iframe = document.createElement("iframe");
|
|
1743
|
-
iframe.style.display = "none";
|
|
1744
|
-
iframe.src = uri;
|
|
1745
|
-
document.body.appendChild(iframe);
|
|
1746
|
-
setTimeout(() => {
|
|
1747
|
-
try {
|
|
1748
|
-
document.body.removeChild(iframe);
|
|
1749
|
-
} catch {
|
|
1750
|
-
}
|
|
1751
|
-
}, IFRAME_CLEANUP_DELAY_MS);
|
|
1752
|
-
} catch {
|
|
1753
|
-
}
|
|
1754
|
-
setTimeout(() => {
|
|
1755
|
-
window.location.href = uri;
|
|
1756
|
-
}, LOCATION_FALLBACK_DELAY_MS);
|
|
1757
|
-
}
|
|
1758
|
-
|
|
1759
|
-
// src/mobileFlow.ts
|
|
1760
|
-
function hasActiveWallet(accounts) {
|
|
1761
|
-
return accounts.some((account) => account.wallets.some((wallet) => wallet.status === "ACTIVE"));
|
|
1762
|
-
}
|
|
1763
|
-
function resolvePostAuthStep(state) {
|
|
1764
|
-
if (!state.hasPasskey) {
|
|
1765
|
-
return { step: "create-passkey", clearPersistedFlow: false };
|
|
1766
|
-
}
|
|
1767
|
-
if (state.persistedMobileFlow) {
|
|
1768
|
-
if (state.persistedMobileFlow.isReauthorization) {
|
|
1769
|
-
return { step: "open-wallet", clearPersistedFlow: false };
|
|
1770
|
-
}
|
|
1771
|
-
if (state.persistedMobileFlow.isSetup && hasActiveWallet(state.accounts)) {
|
|
1772
|
-
return { step: "deposit", clearPersistedFlow: true };
|
|
1773
|
-
}
|
|
1774
|
-
return { step: "open-wallet", clearPersistedFlow: false };
|
|
1775
|
-
}
|
|
1776
|
-
if (state.mobileSetupInProgress && !hasActiveWallet(state.accounts)) {
|
|
1777
|
-
return { step: "open-wallet", clearPersistedFlow: false };
|
|
1778
|
-
}
|
|
1779
|
-
if ((state.accounts.length === 0 || !hasActiveWallet(state.accounts)) && !state.connectingNewAccount) {
|
|
1780
|
-
return { step: "wallet-picker", clearPersistedFlow: false };
|
|
1781
|
-
}
|
|
1782
|
-
return { step: "deposit", clearPersistedFlow: false };
|
|
1783
|
-
}
|
|
1784
|
-
function resolveRestoredMobileFlow(transferStatus, isSetup) {
|
|
1785
|
-
if (transferStatus === "AUTHORIZED") {
|
|
1786
|
-
return isSetup ? { kind: "resume-setup-deposit", step: "deposit", clearPersistedFlow: true } : { kind: "resume-confirm-sign", step: "confirm-sign", clearPersistedFlow: true };
|
|
1787
|
-
}
|
|
1788
|
-
if (transferStatus === "COMPLETED") {
|
|
1789
|
-
return { kind: "resume-success", step: "success", clearPersistedFlow: true };
|
|
1790
|
-
}
|
|
1791
|
-
if (transferStatus === "FAILED") {
|
|
1792
|
-
return { kind: "resume-failed", step: "success", clearPersistedFlow: true };
|
|
1793
|
-
}
|
|
1794
|
-
if (transferStatus === "SENDING" || transferStatus === "SENT") {
|
|
1795
|
-
return { kind: "resume-processing", step: "processing", clearPersistedFlow: true };
|
|
1796
|
-
}
|
|
1797
|
-
if (isSetup) {
|
|
1798
|
-
return { kind: "resume-stale-setup", step: "wallet-picker", clearPersistedFlow: true };
|
|
1799
|
-
}
|
|
1800
|
-
return { kind: "resume-open-wallet", step: "open-wallet", clearPersistedFlow: false };
|
|
1801
|
-
}
|
|
1802
|
-
|
|
1803
|
-
// src/dataLoading.ts
|
|
1804
|
-
function resolveDataLoadAction({
|
|
1805
|
-
authenticated,
|
|
1806
|
-
step,
|
|
1807
|
-
accountsCount,
|
|
1808
|
-
hasActiveCredential,
|
|
1809
|
-
loading
|
|
1810
|
-
}) {
|
|
1811
|
-
if (!authenticated || step === "login" || step === "otp-verify" || accountsCount > 0 || !hasActiveCredential) {
|
|
1812
|
-
return "reset";
|
|
1813
|
-
}
|
|
1814
|
-
if (loading) {
|
|
1815
|
-
return "wait";
|
|
1816
|
-
}
|
|
1817
|
-
return "load";
|
|
1818
|
-
}
|
|
1819
|
-
|
|
1820
1643
|
// src/paymentHelpers.ts
|
|
1821
1644
|
var ACTIVE_CREDENTIAL_STORAGE_KEY = "swype_active_credential_id";
|
|
1822
1645
|
var MOBILE_FLOW_STORAGE_KEY = "swype_mobile_flow";
|
|
@@ -2232,6 +2055,46 @@ function paymentReducer(state, action) {
|
|
|
2232
2055
|
return state;
|
|
2233
2056
|
}
|
|
2234
2057
|
}
|
|
2058
|
+
|
|
2059
|
+
// src/auth.ts
|
|
2060
|
+
var EMAIL_PATTERN = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
2061
|
+
var PHONE_DIGIT_PATTERN = /^\d{7,15}$/;
|
|
2062
|
+
function normalizePhoneNumber(rawValue) {
|
|
2063
|
+
const trimmed = rawValue.trim();
|
|
2064
|
+
if (!trimmed) return null;
|
|
2065
|
+
const hasExplicitCountryCode = trimmed.startsWith("+");
|
|
2066
|
+
const digits = trimmed.replace(/\D/g, "");
|
|
2067
|
+
if (!PHONE_DIGIT_PATTERN.test(digits)) return null;
|
|
2068
|
+
return hasExplicitCountryCode ? `+${digits}` : digits;
|
|
2069
|
+
}
|
|
2070
|
+
function normalizeAuthIdentifier(rawValue) {
|
|
2071
|
+
const trimmed = rawValue.trim();
|
|
2072
|
+
if (!trimmed) return null;
|
|
2073
|
+
if (EMAIL_PATTERN.test(trimmed)) {
|
|
2074
|
+
return {
|
|
2075
|
+
kind: "email",
|
|
2076
|
+
value: trimmed.toLowerCase()
|
|
2077
|
+
};
|
|
2078
|
+
}
|
|
2079
|
+
const normalizedPhoneNumber = normalizePhoneNumber(trimmed);
|
|
2080
|
+
if (normalizedPhoneNumber) {
|
|
2081
|
+
return {
|
|
2082
|
+
kind: "phone",
|
|
2083
|
+
value: normalizedPhoneNumber
|
|
2084
|
+
};
|
|
2085
|
+
}
|
|
2086
|
+
return null;
|
|
2087
|
+
}
|
|
2088
|
+
function maskAuthIdentifier(identifier) {
|
|
2089
|
+
if (identifier.kind === "email") {
|
|
2090
|
+
const [localPart, domain = ""] = identifier.value.split("@");
|
|
2091
|
+
const localPrefix = localPart.slice(0, 2);
|
|
2092
|
+
return `${localPrefix}${"*".repeat(Math.max(localPart.length - 2, 0))}@${domain}`;
|
|
2093
|
+
}
|
|
2094
|
+
const digits = identifier.value.replace(/\D/g, "");
|
|
2095
|
+
const visibleSuffix = digits.slice(-4);
|
|
2096
|
+
return `***-***-${visibleSuffix}`;
|
|
2097
|
+
}
|
|
2235
2098
|
var ACCENT = "#28b67a";
|
|
2236
2099
|
var BG_RING = "#d2e4ea";
|
|
2237
2100
|
function SwypeLoadingScreen() {
|
|
@@ -3857,7 +3720,7 @@ var dividerTextStyle = (color) => ({
|
|
|
3857
3720
|
color,
|
|
3858
3721
|
whiteSpace: "nowrap"
|
|
3859
3722
|
});
|
|
3860
|
-
var DEFAULT_MAX =
|
|
3723
|
+
var DEFAULT_MAX = 1e7;
|
|
3861
3724
|
var ABSOLUTE_MIN = 0.01;
|
|
3862
3725
|
function SetupScreen({
|
|
3863
3726
|
availableBalance,
|
|
@@ -3872,7 +3735,7 @@ function SetupScreen({
|
|
|
3872
3735
|
error
|
|
3873
3736
|
}) {
|
|
3874
3737
|
const { tokens } = useSwypeConfig();
|
|
3875
|
-
const effectiveMax =
|
|
3738
|
+
const effectiveMax = DEFAULT_MAX;
|
|
3876
3739
|
const effectiveMin = Math.min(ABSOLUTE_MIN, effectiveMax);
|
|
3877
3740
|
const [limit, setLimit] = useState(() => Math.min(availableBalance, effectiveMax));
|
|
3878
3741
|
const [editing, setEditing] = useState(false);
|
|
@@ -4248,7 +4111,8 @@ function DepositScreen({
|
|
|
4248
4111
|
onSelectAccount,
|
|
4249
4112
|
onAuthorizeAccount,
|
|
4250
4113
|
onAddProvider,
|
|
4251
|
-
onSelectToken
|
|
4114
|
+
onSelectToken,
|
|
4115
|
+
selectedSourceLabel
|
|
4252
4116
|
}) {
|
|
4253
4117
|
const { tokens } = useSwypeConfig();
|
|
4254
4118
|
const amount = initialAmount;
|
|
@@ -4293,7 +4157,7 @@ function DepositScreen({
|
|
|
4293
4157
|
/* @__PURE__ */ jsx("text", { x: "12", y: "16", textAnchor: "middle", fontSize: "12", fill: "#fff", fontWeight: "700", children: "$" })
|
|
4294
4158
|
] }) }),
|
|
4295
4159
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
4296
|
-
/* @__PURE__ */ jsx("div", { style: balanceLabelStyle2(tokens.textMuted), children: "Available" }),
|
|
4160
|
+
/* @__PURE__ */ jsx("div", { style: balanceLabelStyle2(tokens.textMuted), children: selectedSourceLabel ?? "Available" }),
|
|
4297
4161
|
/* @__PURE__ */ jsxs("div", { style: { ...balanceAmountStyle, color: tokens.warning }, children: [
|
|
4298
4162
|
"$",
|
|
4299
4163
|
availableBalance.toFixed(2)
|
|
@@ -4368,10 +4232,7 @@ function DepositScreen({
|
|
|
4368
4232
|
/* @__PURE__ */ jsx("text", { x: "12", y: "16", textAnchor: "middle", fontSize: "12", fill: "#fff", fontWeight: "700", children: "$" })
|
|
4369
4233
|
] }) }),
|
|
4370
4234
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
4371
|
-
/* @__PURE__ */
|
|
4372
|
-
"Paying from ",
|
|
4373
|
-
sourceName
|
|
4374
|
-
] }),
|
|
4235
|
+
/* @__PURE__ */ jsx("div", { style: balanceLabelStyle2(tokens.textMuted), children: selectedSourceLabel ?? `Paying from ${sourceName}` }),
|
|
4375
4236
|
/* @__PURE__ */ jsxs("div", { style: balanceAmountStyle, children: [
|
|
4376
4237
|
"$",
|
|
4377
4238
|
availableBalance.toLocaleString("en-US", { minimumFractionDigits: 2, maximumFractionDigits: 2 })
|
|
@@ -4725,6 +4586,7 @@ function SelectSourceScreen({
|
|
|
4725
4586
|
onChainChange,
|
|
4726
4587
|
onTokenChange,
|
|
4727
4588
|
onConfirm,
|
|
4589
|
+
onBack,
|
|
4728
4590
|
onLogout
|
|
4729
4591
|
}) {
|
|
4730
4592
|
const { tokens } = useSwypeConfig();
|
|
@@ -4743,6 +4605,7 @@ function SelectSourceScreen({
|
|
|
4743
4605
|
ScreenHeader,
|
|
4744
4606
|
{
|
|
4745
4607
|
title: "Select Source",
|
|
4608
|
+
onBack,
|
|
4746
4609
|
right: /* @__PURE__ */ jsx(SettingsMenu, { onLogout })
|
|
4747
4610
|
}
|
|
4748
4611
|
),
|
|
@@ -5165,6 +5028,28 @@ var waitHintStyle2 = (color) => ({
|
|
|
5165
5028
|
color,
|
|
5166
5029
|
margin: 0
|
|
5167
5030
|
});
|
|
5031
|
+
|
|
5032
|
+
// src/deeplink.ts
|
|
5033
|
+
var IFRAME_CLEANUP_DELAY_MS = 3e3;
|
|
5034
|
+
var LOCATION_FALLBACK_DELAY_MS = 100;
|
|
5035
|
+
function triggerDeeplink(uri) {
|
|
5036
|
+
try {
|
|
5037
|
+
const iframe = document.createElement("iframe");
|
|
5038
|
+
iframe.style.display = "none";
|
|
5039
|
+
iframe.src = uri;
|
|
5040
|
+
document.body.appendChild(iframe);
|
|
5041
|
+
setTimeout(() => {
|
|
5042
|
+
try {
|
|
5043
|
+
document.body.removeChild(iframe);
|
|
5044
|
+
} catch {
|
|
5045
|
+
}
|
|
5046
|
+
}, IFRAME_CLEANUP_DELAY_MS);
|
|
5047
|
+
} catch {
|
|
5048
|
+
}
|
|
5049
|
+
setTimeout(() => {
|
|
5050
|
+
window.location.href = uri;
|
|
5051
|
+
}, LOCATION_FALLBACK_DELAY_MS);
|
|
5052
|
+
}
|
|
5168
5053
|
function OpenWalletScreen({
|
|
5169
5054
|
walletName,
|
|
5170
5055
|
deeplinkUri,
|
|
@@ -5610,6 +5495,7 @@ function StepRenderer({
|
|
|
5610
5495
|
selectedSource,
|
|
5611
5496
|
selectSourceChoices,
|
|
5612
5497
|
selectSourceRecommended,
|
|
5498
|
+
selectSourceAvailableBalance,
|
|
5613
5499
|
authInput,
|
|
5614
5500
|
otpCode,
|
|
5615
5501
|
selectSourceChainName,
|
|
@@ -5731,17 +5617,23 @@ function StepRenderer({
|
|
|
5731
5617
|
);
|
|
5732
5618
|
}
|
|
5733
5619
|
if (step === "setup") {
|
|
5620
|
+
const selectSourceTokenCount = selectSourceChoices.reduce(
|
|
5621
|
+
(sum, chain) => sum + chain.tokens.length,
|
|
5622
|
+
0
|
|
5623
|
+
);
|
|
5624
|
+
const effectiveTokenCount = tokenCount > 0 ? tokenCount : selectSourceTokenCount;
|
|
5625
|
+
const effectiveSourceLabel = selectedSourceLabel ?? (selectSourceChainName && selectSourceTokenSymbol ? `${selectSourceTokenSymbol} on ${selectSourceChainName}` : void 0);
|
|
5734
5626
|
return /* @__PURE__ */ jsx(
|
|
5735
5627
|
SetupScreen,
|
|
5736
5628
|
{
|
|
5737
|
-
availableBalance: selectedSource ? selectedSource.balance.available.amount : selectedAccount ? selectedAccount.wallets.reduce((sum, w) => sum + w.balance.available.amount, 0) : maxSourceBalance,
|
|
5738
|
-
tokenCount,
|
|
5629
|
+
availableBalance: selectedSource ? selectedSource.balance.available.amount : selectedAccount ? selectedAccount.wallets.reduce((sum, w) => sum + w.balance.available.amount, 0) : selectSourceAvailableBalance > 0 ? selectSourceAvailableBalance : maxSourceBalance,
|
|
5630
|
+
tokenCount: effectiveTokenCount,
|
|
5739
5631
|
sourceName,
|
|
5740
5632
|
onSetupOneTap: handlers.onSetupOneTap,
|
|
5741
5633
|
onBack: () => handlers.onNavigate("deposit"),
|
|
5742
5634
|
onLogout: handlers.onLogout,
|
|
5743
5635
|
onAdvanced: handlers.onSelectToken,
|
|
5744
|
-
selectedSourceLabel,
|
|
5636
|
+
selectedSourceLabel: effectiveSourceLabel,
|
|
5745
5637
|
loading: savingOneTapLimit,
|
|
5746
5638
|
error: state.error
|
|
5747
5639
|
}
|
|
@@ -5789,7 +5681,8 @@ function StepRenderer({
|
|
|
5789
5681
|
onSelectAccount: handlers.onSelectAccount,
|
|
5790
5682
|
onAuthorizeAccount: handlers.onContinueConnection,
|
|
5791
5683
|
onAddProvider: () => handlers.onNavigate("wallet-picker"),
|
|
5792
|
-
onSelectToken: handlers.onSelectToken
|
|
5684
|
+
onSelectToken: handlers.onSelectToken,
|
|
5685
|
+
selectedSourceLabel
|
|
5793
5686
|
}
|
|
5794
5687
|
);
|
|
5795
5688
|
}
|
|
@@ -5821,6 +5714,7 @@ function StepRenderer({
|
|
|
5821
5714
|
);
|
|
5822
5715
|
}
|
|
5823
5716
|
if (step === "select-source") {
|
|
5717
|
+
const cameFromSetup = state.previousStep === "setup";
|
|
5824
5718
|
return /* @__PURE__ */ jsx(
|
|
5825
5719
|
SelectSourceScreen,
|
|
5826
5720
|
{
|
|
@@ -5830,7 +5724,8 @@ function StepRenderer({
|
|
|
5830
5724
|
recommended: selectSourceRecommended,
|
|
5831
5725
|
onChainChange: handlers.onSelectSourceChainChange,
|
|
5832
5726
|
onTokenChange: handlers.onSetSelectSourceTokenSymbol,
|
|
5833
|
-
onConfirm: handlers.onConfirmSelectSource,
|
|
5727
|
+
onConfirm: cameFromSetup ? () => handlers.onNavigate("setup") : handlers.onConfirmSelectSource,
|
|
5728
|
+
onBack: cameFromSetup ? () => handlers.onNavigate("setup") : void 0,
|
|
5834
5729
|
onLogout: handlers.onLogout
|
|
5835
5730
|
}
|
|
5836
5731
|
);
|
|
@@ -5880,12 +5775,29 @@ function StepRenderer({
|
|
|
5880
5775
|
selectedAccountId: state.selectedAccountId,
|
|
5881
5776
|
onSelectAccount: handlers.onSelectAccount,
|
|
5882
5777
|
onAuthorizeAccount: handlers.onContinueConnection,
|
|
5883
|
-
onAddProvider: () => handlers.onNavigate("wallet-picker")
|
|
5778
|
+
onAddProvider: () => handlers.onNavigate("wallet-picker"),
|
|
5779
|
+
selectedSourceLabel
|
|
5884
5780
|
}
|
|
5885
5781
|
);
|
|
5886
5782
|
}
|
|
5887
5783
|
return null;
|
|
5888
5784
|
}
|
|
5785
|
+
|
|
5786
|
+
// src/sentry.ts
|
|
5787
|
+
var _mod;
|
|
5788
|
+
function captureException(error) {
|
|
5789
|
+
if (_mod === null) return;
|
|
5790
|
+
if (_mod) {
|
|
5791
|
+
_mod.captureException(error);
|
|
5792
|
+
return;
|
|
5793
|
+
}
|
|
5794
|
+
import('@sentry/react').then((m) => {
|
|
5795
|
+
_mod = m;
|
|
5796
|
+
m.captureException(error);
|
|
5797
|
+
}).catch(() => {
|
|
5798
|
+
_mod = null;
|
|
5799
|
+
});
|
|
5800
|
+
}
|
|
5889
5801
|
var PaymentErrorBoundary = class extends Component {
|
|
5890
5802
|
constructor(props) {
|
|
5891
5803
|
super(props);
|
|
@@ -5954,78 +5866,7 @@ var buttonStyle3 = {
|
|
|
5954
5866
|
fontFamily: "inherit",
|
|
5955
5867
|
cursor: "pointer"
|
|
5956
5868
|
};
|
|
5957
|
-
function
|
|
5958
|
-
const resetKey = useRef(0);
|
|
5959
|
-
const handleBoundaryReset = useCallback(() => {
|
|
5960
|
-
resetKey.current += 1;
|
|
5961
|
-
}, []);
|
|
5962
|
-
return /* @__PURE__ */ jsx(PaymentErrorBoundary, { onReset: handleBoundaryReset, children: /* @__PURE__ */ jsx(SwypePaymentInner, { ...props }) }, resetKey.current);
|
|
5963
|
-
}
|
|
5964
|
-
function SwypePaymentInner({
|
|
5965
|
-
destination,
|
|
5966
|
-
onComplete,
|
|
5967
|
-
onError,
|
|
5968
|
-
useWalletConnector: useWalletConnectorProp,
|
|
5969
|
-
idempotencyKey,
|
|
5970
|
-
merchantAuthorization,
|
|
5971
|
-
merchantName,
|
|
5972
|
-
onBack,
|
|
5973
|
-
onDismiss,
|
|
5974
|
-
autoCloseSeconds
|
|
5975
|
-
}) {
|
|
5976
|
-
const { apiBaseUrl, depositAmount } = useSwypeConfig();
|
|
5977
|
-
const { ready, authenticated, user, logout, getAccessToken } = usePrivy();
|
|
5978
|
-
const {
|
|
5979
|
-
sendCode: sendEmailCode,
|
|
5980
|
-
loginWithCode: loginWithEmailCode,
|
|
5981
|
-
state: emailLoginState
|
|
5982
|
-
} = useLoginWithEmail();
|
|
5983
|
-
const {
|
|
5984
|
-
sendCode: sendSmsCode,
|
|
5985
|
-
loginWithCode: loginWithSmsCode,
|
|
5986
|
-
state: smsLoginState
|
|
5987
|
-
} = useLoginWithSms();
|
|
5988
|
-
useLoginWithOAuth();
|
|
5989
|
-
const [state, dispatch] = useReducer(
|
|
5990
|
-
paymentReducer,
|
|
5991
|
-
{
|
|
5992
|
-
depositAmount,
|
|
5993
|
-
passkeyPopupNeeded: isSafari() && isInCrossOriginIframe(),
|
|
5994
|
-
activeCredentialId: typeof window === "undefined" ? null : window.localStorage.getItem(ACTIVE_CREDENTIAL_STORAGE_KEY)
|
|
5995
|
-
},
|
|
5996
|
-
createInitialState
|
|
5997
|
-
);
|
|
5998
|
-
const loadingDataRef = useRef(false);
|
|
5999
|
-
const pollingTransferIdRef = useRef(null);
|
|
6000
|
-
const setupAccountIdRef = useRef(null);
|
|
6001
|
-
const mobileSetupFlowRef = useRef(false);
|
|
6002
|
-
const handlingMobileReturnRef = useRef(false);
|
|
6003
|
-
const processingStartedAtRef = useRef(null);
|
|
6004
|
-
const initializedSelectSourceActionRef = useRef(null);
|
|
6005
|
-
const preSelectSourceStepRef = useRef(null);
|
|
6006
|
-
const pendingTokenAuthRef = useRef(null);
|
|
6007
|
-
const pendingTokenSelectionRef = useRef(null);
|
|
6008
|
-
const pendingTokenAuthSessionRef = useRef(null);
|
|
6009
|
-
const reauthSessionIdRef = useRef(null);
|
|
6010
|
-
const reauthTokenRef = useRef(null);
|
|
6011
|
-
const checkingPasskeyRef = useRef(false);
|
|
6012
|
-
const onCompleteRef = useRef(onComplete);
|
|
6013
|
-
onCompleteRef.current = onComplete;
|
|
6014
|
-
const pollingRef = useRef(null);
|
|
6015
|
-
const getAccessTokenRef = useRef(getAccessToken);
|
|
6016
|
-
getAccessTokenRef.current = getAccessToken;
|
|
6017
|
-
const handleAuthorizedMobileReturnRef = useRef(
|
|
6018
|
-
null
|
|
6019
|
-
);
|
|
6020
|
-
const [authInput, setAuthInput] = useState("");
|
|
6021
|
-
const [otpCode, setOtpCode] = useState("");
|
|
6022
|
-
const [selectSourceChainName, setSelectSourceChainName] = useState("");
|
|
6023
|
-
const [selectSourceTokenSymbol, setSelectSourceTokenSymbol] = useState("");
|
|
6024
|
-
const [savingOneTapLimit, setSavingOneTapLimit] = useState(false);
|
|
6025
|
-
const authExecutor = useAuthorizationExecutor();
|
|
6026
|
-
const polling = useTransferPolling();
|
|
6027
|
-
pollingRef.current = polling;
|
|
6028
|
-
const transferSigning = useTransferSigning();
|
|
5869
|
+
function useDerivedState(state) {
|
|
6029
5870
|
const { sourceType, sourceId } = deriveSourceTypeAndId(state);
|
|
6030
5871
|
const selectedAccount = state.accounts.find((a) => a.id === state.selectedAccountId);
|
|
6031
5872
|
const selectedWallet = selectedAccount?.wallets.find(
|
|
@@ -6075,8 +5916,36 @@ function SwypePaymentInner({
|
|
|
6075
5916
|
}
|
|
6076
5917
|
return count;
|
|
6077
5918
|
}, [state.accounts]);
|
|
6078
|
-
|
|
6079
|
-
|
|
5919
|
+
return {
|
|
5920
|
+
sourceType,
|
|
5921
|
+
sourceId,
|
|
5922
|
+
selectedAccount,
|
|
5923
|
+
selectedWallet,
|
|
5924
|
+
selectedSource,
|
|
5925
|
+
sourceName,
|
|
5926
|
+
sourceAddress,
|
|
5927
|
+
sourceVerified,
|
|
5928
|
+
pendingConnections,
|
|
5929
|
+
depositEligibleAccounts,
|
|
5930
|
+
maxSourceBalance,
|
|
5931
|
+
tokenCount
|
|
5932
|
+
};
|
|
5933
|
+
}
|
|
5934
|
+
function useAuthHandlers(dispatch, verificationTarget) {
|
|
5935
|
+
const {
|
|
5936
|
+
sendCode: sendEmailCode,
|
|
5937
|
+
loginWithCode: loginWithEmailCode,
|
|
5938
|
+
state: emailLoginState
|
|
5939
|
+
} = useLoginWithEmail();
|
|
5940
|
+
const {
|
|
5941
|
+
sendCode: sendSmsCode,
|
|
5942
|
+
loginWithCode: loginWithSmsCode,
|
|
5943
|
+
state: smsLoginState
|
|
5944
|
+
} = useLoginWithSms();
|
|
5945
|
+
const [authInput, setAuthInput] = useState("");
|
|
5946
|
+
const [otpCode, setOtpCode] = useState("");
|
|
5947
|
+
const activeOtpStatus = verificationTarget?.kind === "email" ? emailLoginState.status : verificationTarget?.kind === "phone" ? smsLoginState.status : "initial";
|
|
5948
|
+
const activeOtpErrorMessage = verificationTarget?.kind === "email" && emailLoginState.status === "error" ? emailLoginState.error?.message ?? "Failed to continue with email." : verificationTarget?.kind === "phone" && smsLoginState.status === "error" ? smsLoginState.error?.message ?? "Failed to continue with phone number." : null;
|
|
6080
5949
|
const handleSendLoginCode = useCallback(async () => {
|
|
6081
5950
|
const normalizedIdentifier = normalizeAuthIdentifier(authInput);
|
|
6082
5951
|
if (!normalizedIdentifier) {
|
|
@@ -6098,9 +5967,9 @@ function SwypePaymentInner({
|
|
|
6098
5967
|
error: err instanceof Error ? err.message : "Failed to send verification code"
|
|
6099
5968
|
});
|
|
6100
5969
|
}
|
|
6101
|
-
}, [authInput, sendEmailCode, sendSmsCode]);
|
|
5970
|
+
}, [authInput, sendEmailCode, sendSmsCode, dispatch]);
|
|
6102
5971
|
const handleVerifyLoginCode = useCallback(async () => {
|
|
6103
|
-
if (!
|
|
5972
|
+
if (!verificationTarget) return;
|
|
6104
5973
|
const trimmedCode = otpCode.trim();
|
|
6105
5974
|
if (!/^\d{6}$/.test(trimmedCode)) {
|
|
6106
5975
|
dispatch({ type: "SET_ERROR", error: "Enter the 6-digit verification code." });
|
|
@@ -6108,7 +5977,7 @@ function SwypePaymentInner({
|
|
|
6108
5977
|
}
|
|
6109
5978
|
dispatch({ type: "SET_ERROR", error: null });
|
|
6110
5979
|
try {
|
|
6111
|
-
if (
|
|
5980
|
+
if (verificationTarget.kind === "email") {
|
|
6112
5981
|
await loginWithEmailCode({ code: trimmedCode });
|
|
6113
5982
|
} else {
|
|
6114
5983
|
await loginWithSmsCode({ code: trimmedCode });
|
|
@@ -6120,15 +5989,15 @@ function SwypePaymentInner({
|
|
|
6120
5989
|
error: err instanceof Error ? err.message : "Failed to verify code"
|
|
6121
5990
|
});
|
|
6122
5991
|
}
|
|
6123
|
-
}, [
|
|
5992
|
+
}, [verificationTarget, otpCode, loginWithEmailCode, loginWithSmsCode, dispatch]);
|
|
6124
5993
|
const handleResendLoginCode = useCallback(async () => {
|
|
6125
|
-
if (!
|
|
5994
|
+
if (!verificationTarget) return;
|
|
6126
5995
|
dispatch({ type: "SET_ERROR", error: null });
|
|
6127
5996
|
try {
|
|
6128
|
-
if (
|
|
6129
|
-
await sendEmailCode({ email:
|
|
5997
|
+
if (verificationTarget.kind === "email") {
|
|
5998
|
+
await sendEmailCode({ email: verificationTarget.value });
|
|
6130
5999
|
} else {
|
|
6131
|
-
await sendSmsCode({ phoneNumber:
|
|
6000
|
+
await sendSmsCode({ phoneNumber: verificationTarget.value });
|
|
6132
6001
|
}
|
|
6133
6002
|
} catch (err) {
|
|
6134
6003
|
captureException(err);
|
|
@@ -6137,7 +6006,68 @@ function SwypePaymentInner({
|
|
|
6137
6006
|
error: err instanceof Error ? err.message : "Failed to resend code"
|
|
6138
6007
|
});
|
|
6139
6008
|
}
|
|
6140
|
-
}, [
|
|
6009
|
+
}, [verificationTarget, sendEmailCode, sendSmsCode, dispatch]);
|
|
6010
|
+
return {
|
|
6011
|
+
authInput,
|
|
6012
|
+
otpCode,
|
|
6013
|
+
activeOtpStatus,
|
|
6014
|
+
activeOtpErrorMessage,
|
|
6015
|
+
setAuthInput,
|
|
6016
|
+
setOtpCode,
|
|
6017
|
+
handleSendLoginCode,
|
|
6018
|
+
handleVerifyLoginCode,
|
|
6019
|
+
handleResendLoginCode
|
|
6020
|
+
};
|
|
6021
|
+
}
|
|
6022
|
+
|
|
6023
|
+
// src/mobileFlow.ts
|
|
6024
|
+
function hasActiveWallet(accounts) {
|
|
6025
|
+
return accounts.some((account) => account.wallets.some((wallet) => wallet.status === "ACTIVE"));
|
|
6026
|
+
}
|
|
6027
|
+
function resolvePostAuthStep(state) {
|
|
6028
|
+
if (!state.hasPasskey) {
|
|
6029
|
+
return { step: "create-passkey", clearPersistedFlow: false };
|
|
6030
|
+
}
|
|
6031
|
+
if (state.persistedMobileFlow) {
|
|
6032
|
+
if (state.persistedMobileFlow.isReauthorization) {
|
|
6033
|
+
return { step: "open-wallet", clearPersistedFlow: false };
|
|
6034
|
+
}
|
|
6035
|
+
if (state.persistedMobileFlow.isSetup && hasActiveWallet(state.accounts)) {
|
|
6036
|
+
return { step: "deposit", clearPersistedFlow: true };
|
|
6037
|
+
}
|
|
6038
|
+
return { step: "open-wallet", clearPersistedFlow: false };
|
|
6039
|
+
}
|
|
6040
|
+
if (state.mobileSetupInProgress && !hasActiveWallet(state.accounts)) {
|
|
6041
|
+
return { step: "open-wallet", clearPersistedFlow: false };
|
|
6042
|
+
}
|
|
6043
|
+
if ((state.accounts.length === 0 || !hasActiveWallet(state.accounts)) && !state.connectingNewAccount) {
|
|
6044
|
+
return { step: "wallet-picker", clearPersistedFlow: false };
|
|
6045
|
+
}
|
|
6046
|
+
return { step: "deposit", clearPersistedFlow: false };
|
|
6047
|
+
}
|
|
6048
|
+
function resolveRestoredMobileFlow(transferStatus, isSetup) {
|
|
6049
|
+
if (transferStatus === "AUTHORIZED") {
|
|
6050
|
+
return isSetup ? { kind: "resume-setup-deposit", step: "deposit", clearPersistedFlow: true } : { kind: "resume-confirm-sign", step: "confirm-sign", clearPersistedFlow: true };
|
|
6051
|
+
}
|
|
6052
|
+
if (transferStatus === "COMPLETED") {
|
|
6053
|
+
return { kind: "resume-success", step: "success", clearPersistedFlow: true };
|
|
6054
|
+
}
|
|
6055
|
+
if (transferStatus === "FAILED") {
|
|
6056
|
+
return { kind: "resume-failed", step: "success", clearPersistedFlow: true };
|
|
6057
|
+
}
|
|
6058
|
+
if (transferStatus === "SENDING" || transferStatus === "SENT") {
|
|
6059
|
+
return { kind: "resume-processing", step: "processing", clearPersistedFlow: true };
|
|
6060
|
+
}
|
|
6061
|
+
if (isSetup) {
|
|
6062
|
+
return { kind: "resume-stale-setup", step: "wallet-picker", clearPersistedFlow: true };
|
|
6063
|
+
}
|
|
6064
|
+
return { kind: "resume-open-wallet", step: "open-wallet", clearPersistedFlow: false };
|
|
6065
|
+
}
|
|
6066
|
+
|
|
6067
|
+
// src/hooks/usePasskeyHandlers.ts
|
|
6068
|
+
function usePasskeyHandlers(dispatch, apiBaseUrl, accounts, knownCredentialIds, mobileSetupFlowRef) {
|
|
6069
|
+
const { user, getAccessToken } = usePrivy();
|
|
6070
|
+
const checkingPasskeyRef = useRef(false);
|
|
6141
6071
|
const completePasskeyRegistration = useCallback(async (credentialId, publicKey) => {
|
|
6142
6072
|
const token = await getAccessToken();
|
|
6143
6073
|
if (!token) throw new Error("Not authenticated");
|
|
@@ -6146,14 +6076,14 @@ function SwypePaymentInner({
|
|
|
6146
6076
|
window.localStorage.setItem(ACTIVE_CREDENTIAL_STORAGE_KEY, credentialId);
|
|
6147
6077
|
const resolved = resolvePostAuthStep({
|
|
6148
6078
|
hasPasskey: true,
|
|
6149
|
-
accounts
|
|
6079
|
+
accounts,
|
|
6150
6080
|
persistedMobileFlow: loadMobileFlowState(),
|
|
6151
6081
|
mobileSetupInProgress: mobileSetupFlowRef.current,
|
|
6152
6082
|
connectingNewAccount: false
|
|
6153
6083
|
});
|
|
6154
6084
|
if (resolved.clearPersistedFlow) clearMobileFlowState();
|
|
6155
6085
|
dispatch({ type: "NAVIGATE", step: resolved.step });
|
|
6156
|
-
}, [getAccessToken, apiBaseUrl,
|
|
6086
|
+
}, [getAccessToken, apiBaseUrl, accounts, mobileSetupFlowRef, dispatch]);
|
|
6157
6087
|
const handleRegisterPasskey = useCallback(async () => {
|
|
6158
6088
|
dispatch({ type: "SET_REGISTERING_PASSKEY", value: true });
|
|
6159
6089
|
dispatch({ type: "SET_ERROR", error: null });
|
|
@@ -6177,7 +6107,7 @@ function SwypePaymentInner({
|
|
|
6177
6107
|
} finally {
|
|
6178
6108
|
dispatch({ type: "SET_REGISTERING_PASSKEY", value: false });
|
|
6179
6109
|
}
|
|
6180
|
-
}, [user, completePasskeyRegistration]);
|
|
6110
|
+
}, [user, completePasskeyRegistration, dispatch]);
|
|
6181
6111
|
const handleCreatePasskeyViaPopup = useCallback(async () => {
|
|
6182
6112
|
dispatch({ type: "SET_REGISTERING_PASSKEY", value: true });
|
|
6183
6113
|
dispatch({ type: "SET_ERROR", error: null });
|
|
@@ -6195,7 +6125,7 @@ function SwypePaymentInner({
|
|
|
6195
6125
|
localStorage.setItem(ACTIVE_CREDENTIAL_STORAGE_KEY, credentialId);
|
|
6196
6126
|
const resolved = resolvePostAuthStep({
|
|
6197
6127
|
hasPasskey: true,
|
|
6198
|
-
accounts
|
|
6128
|
+
accounts,
|
|
6199
6129
|
persistedMobileFlow: loadMobileFlowState(),
|
|
6200
6130
|
mobileSetupInProgress: mobileSetupFlowRef.current,
|
|
6201
6131
|
connectingNewAccount: false
|
|
@@ -6211,14 +6141,14 @@ function SwypePaymentInner({
|
|
|
6211
6141
|
} finally {
|
|
6212
6142
|
dispatch({ type: "SET_REGISTERING_PASSKEY", value: false });
|
|
6213
6143
|
}
|
|
6214
|
-
}, [user, getAccessToken, apiBaseUrl,
|
|
6144
|
+
}, [user, getAccessToken, apiBaseUrl, accounts, mobileSetupFlowRef, dispatch]);
|
|
6215
6145
|
const handleVerifyPasskeyViaPopup = useCallback(async () => {
|
|
6216
6146
|
dispatch({ type: "SET_VERIFYING_PASSKEY", value: true });
|
|
6217
6147
|
dispatch({ type: "SET_ERROR", error: null });
|
|
6218
6148
|
try {
|
|
6219
6149
|
const token = await getAccessToken();
|
|
6220
6150
|
const matched = await findDevicePasskeyViaPopup({
|
|
6221
|
-
credentialIds:
|
|
6151
|
+
credentialIds: knownCredentialIds,
|
|
6222
6152
|
rpId: resolvePasskeyRpId(),
|
|
6223
6153
|
authToken: token ?? void 0,
|
|
6224
6154
|
apiBaseUrl
|
|
@@ -6232,7 +6162,7 @@ function SwypePaymentInner({
|
|
|
6232
6162
|
}
|
|
6233
6163
|
const resolved = resolvePostAuthStep({
|
|
6234
6164
|
hasPasskey: true,
|
|
6235
|
-
accounts
|
|
6165
|
+
accounts,
|
|
6236
6166
|
persistedMobileFlow: loadMobileFlowState(),
|
|
6237
6167
|
mobileSetupInProgress: mobileSetupFlowRef.current,
|
|
6238
6168
|
connectingNewAccount: false
|
|
@@ -6254,44 +6184,48 @@ function SwypePaymentInner({
|
|
|
6254
6184
|
} finally {
|
|
6255
6185
|
dispatch({ type: "SET_VERIFYING_PASSKEY", value: false });
|
|
6256
6186
|
}
|
|
6257
|
-
}, [
|
|
6187
|
+
}, [knownCredentialIds, getAccessToken, apiBaseUrl, accounts, mobileSetupFlowRef, dispatch]);
|
|
6188
|
+
return {
|
|
6189
|
+
handleRegisterPasskey,
|
|
6190
|
+
handleCreatePasskeyViaPopup,
|
|
6191
|
+
handleVerifyPasskeyViaPopup,
|
|
6192
|
+
checkingPasskeyRef
|
|
6193
|
+
};
|
|
6194
|
+
}
|
|
6195
|
+
function useTransferHandlers(deps) {
|
|
6196
|
+
const {
|
|
6197
|
+
dispatch,
|
|
6198
|
+
getAccessToken,
|
|
6199
|
+
apiBaseUrl,
|
|
6200
|
+
depositAmount,
|
|
6201
|
+
destination,
|
|
6202
|
+
idempotencyKey,
|
|
6203
|
+
merchantAuthorization,
|
|
6204
|
+
onComplete,
|
|
6205
|
+
onError,
|
|
6206
|
+
polling,
|
|
6207
|
+
transferSigning,
|
|
6208
|
+
sourceType,
|
|
6209
|
+
sourceId,
|
|
6210
|
+
sourceTokenAddress,
|
|
6211
|
+
activeCredentialId,
|
|
6212
|
+
selectedAccountId,
|
|
6213
|
+
transfer,
|
|
6214
|
+
accounts
|
|
6215
|
+
} = deps;
|
|
6216
|
+
const processingStartedAtRef = useRef(null);
|
|
6217
|
+
const pollingTransferIdRef = useRef(null);
|
|
6258
6218
|
const reloadAccounts = useCallback(async () => {
|
|
6259
6219
|
const token = await getAccessToken();
|
|
6260
|
-
if (!token || !
|
|
6220
|
+
if (!token || !activeCredentialId) return;
|
|
6261
6221
|
const [accts, prov] = await Promise.all([
|
|
6262
|
-
fetchAccounts(apiBaseUrl, token,
|
|
6222
|
+
fetchAccounts(apiBaseUrl, token, activeCredentialId),
|
|
6263
6223
|
fetchProviders(apiBaseUrl, token)
|
|
6264
6224
|
]);
|
|
6265
6225
|
const parsedAmt = depositAmount != null ? depositAmount : 0;
|
|
6266
|
-
const defaults = resolveDepositSelection(accts, parsedAmt,
|
|
6226
|
+
const defaults = resolveDepositSelection(accts, parsedAmt, selectedAccountId);
|
|
6267
6227
|
dispatch({ type: "ACCOUNTS_RELOADED", accounts: accts, providers: prov, defaults });
|
|
6268
|
-
}, [getAccessToken,
|
|
6269
|
-
const handleAuthorizedMobileReturn = useCallback(async (authorizedTransfer, isSetup) => {
|
|
6270
|
-
if (handlingMobileReturnRef.current) return;
|
|
6271
|
-
handlingMobileReturnRef.current = true;
|
|
6272
|
-
polling.stopPolling();
|
|
6273
|
-
if (isSetup) {
|
|
6274
|
-
mobileSetupFlowRef.current = false;
|
|
6275
|
-
clearMobileFlowState();
|
|
6276
|
-
try {
|
|
6277
|
-
await reloadAccounts();
|
|
6278
|
-
loadingDataRef.current = false;
|
|
6279
|
-
dispatch({ type: "MOBILE_SETUP_COMPLETE", transfer: authorizedTransfer });
|
|
6280
|
-
} catch (err) {
|
|
6281
|
-
handlingMobileReturnRef.current = false;
|
|
6282
|
-
dispatch({
|
|
6283
|
-
type: "SET_ERROR",
|
|
6284
|
-
error: err instanceof Error ? err.message : "Wallet authorized, but we could not refresh your account yet."
|
|
6285
|
-
});
|
|
6286
|
-
dispatch({ type: "NAVIGATE", step: "open-wallet" });
|
|
6287
|
-
}
|
|
6288
|
-
return;
|
|
6289
|
-
}
|
|
6290
|
-
mobileSetupFlowRef.current = false;
|
|
6291
|
-
clearMobileFlowState();
|
|
6292
|
-
dispatch({ type: "MOBILE_SIGN_READY", transfer: authorizedTransfer });
|
|
6293
|
-
}, [polling.stopPolling, reloadAccounts]);
|
|
6294
|
-
handleAuthorizedMobileReturnRef.current = handleAuthorizedMobileReturn;
|
|
6228
|
+
}, [getAccessToken, activeCredentialId, selectedAccountId, apiBaseUrl, depositAmount, dispatch]);
|
|
6295
6229
|
const handlePay = useCallback(async (payAmount, sourceOverrides) => {
|
|
6296
6230
|
if (isNaN(payAmount) || payAmount < MIN_SEND_AMOUNT_USD) {
|
|
6297
6231
|
dispatch({ type: "SET_ERROR", error: `Minimum amount is $${MIN_SEND_AMOUNT_USD.toFixed(2)}.` });
|
|
@@ -6301,7 +6235,7 @@ function SwypePaymentInner({
|
|
|
6301
6235
|
dispatch({ type: "SET_ERROR", error: "No account or provider selected." });
|
|
6302
6236
|
return;
|
|
6303
6237
|
}
|
|
6304
|
-
if (!
|
|
6238
|
+
if (!activeCredentialId) {
|
|
6305
6239
|
dispatch({ type: "SET_ERROR", error: "Create or verify a passkey on this device before continuing." });
|
|
6306
6240
|
dispatch({ type: "NAVIGATE", step: "create-passkey" });
|
|
6307
6241
|
return;
|
|
@@ -6309,10 +6243,10 @@ function SwypePaymentInner({
|
|
|
6309
6243
|
dispatch({ type: "PAY_STARTED", isSetupRedirect: false });
|
|
6310
6244
|
processingStartedAtRef.current = Date.now();
|
|
6311
6245
|
try {
|
|
6312
|
-
if (
|
|
6313
|
-
const signedTransfer2 = await transferSigning.signTransfer(
|
|
6246
|
+
if (transfer?.status === "AUTHORIZED") {
|
|
6247
|
+
const signedTransfer2 = await transferSigning.signTransfer(transfer.id);
|
|
6314
6248
|
dispatch({ type: "TRANSFER_SIGNED", transfer: signedTransfer2 });
|
|
6315
|
-
polling.startPolling(
|
|
6249
|
+
polling.startPolling(transfer.id);
|
|
6316
6250
|
return;
|
|
6317
6251
|
}
|
|
6318
6252
|
const token = await getAccessToken();
|
|
@@ -6320,7 +6254,7 @@ function SwypePaymentInner({
|
|
|
6320
6254
|
let effectiveSourceType = sourceOverrides?.sourceType ?? sourceType;
|
|
6321
6255
|
let effectiveSourceId = sourceOverrides?.sourceId ?? sourceId;
|
|
6322
6256
|
if (effectiveSourceType === "accountId") {
|
|
6323
|
-
const acct =
|
|
6257
|
+
const acct = accounts.find((a) => a.id === effectiveSourceId);
|
|
6324
6258
|
const preferredWallet = acct ? getPreferredDepositWallet(acct, payAmount) : null;
|
|
6325
6259
|
if (preferredWallet?.status === "ACTIVE") {
|
|
6326
6260
|
effectiveSourceType = "walletId";
|
|
@@ -6329,10 +6263,11 @@ function SwypePaymentInner({
|
|
|
6329
6263
|
}
|
|
6330
6264
|
const t = await createTransfer(apiBaseUrl, token, {
|
|
6331
6265
|
id: idempotencyKey,
|
|
6332
|
-
credentialId:
|
|
6266
|
+
credentialId: activeCredentialId,
|
|
6333
6267
|
merchantAuthorization,
|
|
6334
6268
|
sourceType: effectiveSourceType,
|
|
6335
6269
|
sourceId: effectiveSourceId,
|
|
6270
|
+
sourceTokenAddress,
|
|
6336
6271
|
destination,
|
|
6337
6272
|
amount: payAmount
|
|
6338
6273
|
});
|
|
@@ -6352,11 +6287,7 @@ function SwypePaymentInner({
|
|
|
6352
6287
|
} catch (err) {
|
|
6353
6288
|
captureException(err);
|
|
6354
6289
|
const msg = err instanceof Error ? err.message : "Transfer failed";
|
|
6355
|
-
dispatch({
|
|
6356
|
-
type: "PAY_ERROR",
|
|
6357
|
-
error: msg,
|
|
6358
|
-
fallbackStep: "deposit"
|
|
6359
|
-
});
|
|
6290
|
+
dispatch({ type: "PAY_ERROR", error: msg, fallbackStep: "deposit" });
|
|
6360
6291
|
onError?.(msg);
|
|
6361
6292
|
} finally {
|
|
6362
6293
|
dispatch({ type: "PAY_ENDED" });
|
|
@@ -6364,9 +6295,10 @@ function SwypePaymentInner({
|
|
|
6364
6295
|
}, [
|
|
6365
6296
|
sourceId,
|
|
6366
6297
|
sourceType,
|
|
6367
|
-
|
|
6368
|
-
|
|
6369
|
-
|
|
6298
|
+
sourceTokenAddress,
|
|
6299
|
+
activeCredentialId,
|
|
6300
|
+
transfer,
|
|
6301
|
+
accounts,
|
|
6370
6302
|
destination,
|
|
6371
6303
|
apiBaseUrl,
|
|
6372
6304
|
getAccessToken,
|
|
@@ -6375,51 +6307,222 @@ function SwypePaymentInner({
|
|
|
6375
6307
|
onError,
|
|
6376
6308
|
onComplete,
|
|
6377
6309
|
idempotencyKey,
|
|
6378
|
-
merchantAuthorization
|
|
6310
|
+
merchantAuthorization,
|
|
6311
|
+
dispatch
|
|
6379
6312
|
]);
|
|
6380
|
-
const
|
|
6381
|
-
|
|
6382
|
-
|
|
6313
|
+
const handleConfirmSign = useCallback(async () => {
|
|
6314
|
+
const t = transfer ?? polling.transfer;
|
|
6315
|
+
if (!t) return;
|
|
6316
|
+
try {
|
|
6317
|
+
const signedTransfer = await transferSigning.signTransfer(t.id);
|
|
6318
|
+
clearMobileFlowState();
|
|
6319
|
+
dispatch({ type: "CONFIRM_SIGN_SUCCESS", transfer: signedTransfer });
|
|
6320
|
+
polling.startPolling(t.id);
|
|
6321
|
+
} catch (err) {
|
|
6322
|
+
captureException(err);
|
|
6323
|
+
const msg = err instanceof Error ? err.message : "Failed to sign transfer";
|
|
6324
|
+
dispatch({ type: "SET_ERROR", error: msg });
|
|
6325
|
+
onError?.(msg);
|
|
6326
|
+
}
|
|
6327
|
+
}, [transfer, polling.transfer, polling.startPolling, transferSigning, onError, dispatch]);
|
|
6328
|
+
return {
|
|
6329
|
+
reloadAccounts,
|
|
6330
|
+
handlePay,
|
|
6331
|
+
handleConfirmSign,
|
|
6332
|
+
processingStartedAtRef,
|
|
6333
|
+
pollingTransferIdRef
|
|
6334
|
+
};
|
|
6335
|
+
}
|
|
6336
|
+
function useSourceSelectionHandlers(dispatch, authExecutor) {
|
|
6337
|
+
const [selectSourceChainName, setSelectSourceChainName] = useState("");
|
|
6338
|
+
const [selectSourceTokenSymbol, setSelectSourceTokenSymbol] = useState("");
|
|
6339
|
+
const initializedSelectSourceActionRef = useRef(null);
|
|
6340
|
+
const preSelectSourceStepRef = useRef(null);
|
|
6341
|
+
const pendingSelectSourceAction = authExecutor.pendingSelectSource;
|
|
6342
|
+
const selectSourceChoices = useMemo(() => {
|
|
6343
|
+
if (!pendingSelectSourceAction) return [];
|
|
6344
|
+
const options = pendingSelectSourceAction.metadata?.options ?? [];
|
|
6345
|
+
return buildSelectSourceChoices(options);
|
|
6346
|
+
}, [pendingSelectSourceAction]);
|
|
6347
|
+
const selectSourceRecommended = useMemo(() => {
|
|
6348
|
+
if (!pendingSelectSourceAction) return null;
|
|
6349
|
+
return pendingSelectSourceAction.metadata?.recommended ?? null;
|
|
6350
|
+
}, [pendingSelectSourceAction]);
|
|
6351
|
+
const selectSourceAvailableBalance = useMemo(() => {
|
|
6352
|
+
if (!pendingSelectSourceAction) return 0;
|
|
6353
|
+
const options = pendingSelectSourceAction.metadata?.options ?? [];
|
|
6354
|
+
const recommended = selectSourceRecommended;
|
|
6355
|
+
if (recommended) {
|
|
6356
|
+
const match = options.find(
|
|
6357
|
+
(opt) => opt.chainName === recommended.chainName && opt.tokenSymbol === recommended.tokenSymbol
|
|
6358
|
+
);
|
|
6359
|
+
if (match) return Number(match.rawBalance) / Math.pow(10, match.decimals);
|
|
6360
|
+
}
|
|
6361
|
+
let max = 0;
|
|
6362
|
+
for (const opt of options) {
|
|
6363
|
+
const bal = Number(opt.rawBalance) / Math.pow(10, opt.decimals);
|
|
6364
|
+
if (bal > max) max = bal;
|
|
6365
|
+
}
|
|
6366
|
+
return max;
|
|
6367
|
+
}, [pendingSelectSourceAction, selectSourceRecommended]);
|
|
6368
|
+
const handleSelectSourceChainChange = useCallback(
|
|
6369
|
+
(chainName) => {
|
|
6370
|
+
setSelectSourceChainName(chainName);
|
|
6371
|
+
const chain = selectSourceChoices.find((c) => c.chainName === chainName);
|
|
6372
|
+
if (!chain || chain.tokens.length === 0) return;
|
|
6373
|
+
const recommendedToken = selectSourceRecommended?.chainName === chainName ? selectSourceRecommended.tokenSymbol : null;
|
|
6374
|
+
const hasRecommended = !!recommendedToken && chain.tokens.some((t) => t.tokenSymbol === recommendedToken);
|
|
6375
|
+
setSelectSourceTokenSymbol(
|
|
6376
|
+
hasRecommended ? recommendedToken : chain.tokens[0].tokenSymbol
|
|
6377
|
+
);
|
|
6378
|
+
},
|
|
6379
|
+
[selectSourceChoices, selectSourceRecommended]
|
|
6380
|
+
);
|
|
6381
|
+
const handleConfirmSelectSource = useCallback(() => {
|
|
6382
|
+
authExecutor.resolveSelectSource({
|
|
6383
|
+
chainName: selectSourceChainName,
|
|
6384
|
+
tokenSymbol: selectSourceTokenSymbol
|
|
6385
|
+
});
|
|
6386
|
+
}, [authExecutor, selectSourceChainName, selectSourceTokenSymbol]);
|
|
6387
|
+
return {
|
|
6388
|
+
selectSourceChainName,
|
|
6389
|
+
selectSourceTokenSymbol,
|
|
6390
|
+
setSelectSourceChainName,
|
|
6391
|
+
setSelectSourceTokenSymbol,
|
|
6392
|
+
selectSourceChoices,
|
|
6393
|
+
selectSourceRecommended,
|
|
6394
|
+
selectSourceAvailableBalance,
|
|
6395
|
+
handleSelectSourceChainChange,
|
|
6396
|
+
handleConfirmSelectSource,
|
|
6397
|
+
pendingSelectSourceAction,
|
|
6398
|
+
initializedSelectSourceActionRef,
|
|
6399
|
+
preSelectSourceStepRef
|
|
6400
|
+
};
|
|
6401
|
+
}
|
|
6402
|
+
function useMobileFlowHandlers(dispatch, polling, reloadAccounts, pollingTransferIdRef, stateTransfer, refs) {
|
|
6403
|
+
const {
|
|
6404
|
+
mobileSetupFlowRef,
|
|
6405
|
+
handlingMobileReturnRef,
|
|
6406
|
+
loadingDataRef
|
|
6407
|
+
} = refs;
|
|
6408
|
+
const handleAuthorizedMobileReturn = useCallback(async (authorizedTransfer, isSetup) => {
|
|
6409
|
+
if (handlingMobileReturnRef.current) return;
|
|
6410
|
+
handlingMobileReturnRef.current = true;
|
|
6411
|
+
polling.stopPolling();
|
|
6412
|
+
if (isSetup) {
|
|
6413
|
+
mobileSetupFlowRef.current = false;
|
|
6414
|
+
clearMobileFlowState();
|
|
6415
|
+
try {
|
|
6416
|
+
await reloadAccounts();
|
|
6417
|
+
loadingDataRef.current = false;
|
|
6418
|
+
dispatch({ type: "MOBILE_SETUP_COMPLETE", transfer: authorizedTransfer });
|
|
6419
|
+
} catch (err) {
|
|
6420
|
+
handlingMobileReturnRef.current = false;
|
|
6421
|
+
dispatch({
|
|
6422
|
+
type: "SET_ERROR",
|
|
6423
|
+
error: err instanceof Error ? err.message : "Wallet authorized, but we could not refresh your account yet."
|
|
6424
|
+
});
|
|
6425
|
+
dispatch({ type: "NAVIGATE", step: "open-wallet" });
|
|
6426
|
+
}
|
|
6427
|
+
return;
|
|
6428
|
+
}
|
|
6429
|
+
mobileSetupFlowRef.current = false;
|
|
6430
|
+
clearMobileFlowState();
|
|
6431
|
+
dispatch({ type: "MOBILE_SIGN_READY", transfer: authorizedTransfer });
|
|
6432
|
+
}, [polling.stopPolling, reloadAccounts, dispatch]);
|
|
6433
|
+
const handleRetryMobileStatus = useCallback(() => {
|
|
6434
|
+
dispatch({ type: "SET_ERROR", error: null });
|
|
6435
|
+
handlingMobileReturnRef.current = false;
|
|
6436
|
+
const currentTransfer = polling.transfer ?? stateTransfer;
|
|
6437
|
+
if (currentTransfer?.status === "AUTHORIZED") {
|
|
6438
|
+
void handleAuthorizedMobileReturn(currentTransfer, mobileSetupFlowRef.current);
|
|
6383
6439
|
return;
|
|
6384
6440
|
}
|
|
6385
|
-
|
|
6441
|
+
const transferIdToResume = pollingTransferIdRef.current ?? currentTransfer?.id;
|
|
6442
|
+
if (transferIdToResume) {
|
|
6443
|
+
polling.startPolling(transferIdToResume);
|
|
6444
|
+
}
|
|
6445
|
+
}, [handleAuthorizedMobileReturn, polling, stateTransfer, pollingTransferIdRef, dispatch]);
|
|
6446
|
+
return {
|
|
6447
|
+
handleAuthorizedMobileReturn,
|
|
6448
|
+
handleRetryMobileStatus
|
|
6449
|
+
};
|
|
6450
|
+
}
|
|
6451
|
+
|
|
6452
|
+
// src/walletFlow.ts
|
|
6453
|
+
var MOBILE_USER_AGENT_PATTERN = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i;
|
|
6454
|
+
function isMobileUserAgent(userAgent) {
|
|
6455
|
+
if (!userAgent) {
|
|
6456
|
+
return false;
|
|
6457
|
+
}
|
|
6458
|
+
return MOBILE_USER_AGENT_PATTERN.test(userAgent);
|
|
6459
|
+
}
|
|
6460
|
+
function shouldUseWalletConnector(options) {
|
|
6461
|
+
return options.useWalletConnector ?? !isMobileUserAgent(options.userAgent);
|
|
6462
|
+
}
|
|
6463
|
+
|
|
6464
|
+
// src/hooks/useProviderHandlers.ts
|
|
6465
|
+
function useProviderHandlers(deps) {
|
|
6466
|
+
const {
|
|
6467
|
+
dispatch,
|
|
6468
|
+
getAccessToken,
|
|
6469
|
+
apiBaseUrl,
|
|
6470
|
+
depositAmount,
|
|
6471
|
+
useWalletConnectorProp,
|
|
6472
|
+
activeCredentialId,
|
|
6473
|
+
selectedAccountId,
|
|
6474
|
+
accounts,
|
|
6475
|
+
providers,
|
|
6476
|
+
authExecutor,
|
|
6477
|
+
reloadAccounts,
|
|
6478
|
+
onError,
|
|
6479
|
+
mobileSetupFlowRef,
|
|
6480
|
+
handlingMobileReturnRef,
|
|
6481
|
+
setupAccountIdRef,
|
|
6482
|
+
reauthSessionIdRef,
|
|
6483
|
+
reauthTokenRef
|
|
6484
|
+
} = deps;
|
|
6485
|
+
const handleSelectProvider = useCallback(async (providerId) => {
|
|
6486
|
+
dispatch({ type: "SELECT_PROVIDER", providerId });
|
|
6487
|
+
if (!activeCredentialId) {
|
|
6386
6488
|
dispatch({ type: "SET_ERROR", error: "Create or verify a passkey on this device before continuing." });
|
|
6387
6489
|
dispatch({ type: "NAVIGATE", step: "create-passkey" });
|
|
6388
6490
|
return;
|
|
6389
6491
|
}
|
|
6390
|
-
const
|
|
6391
|
-
const
|
|
6392
|
-
|
|
6393
|
-
|
|
6492
|
+
const provider = providers.find((p) => p.id === providerId);
|
|
6493
|
+
const providerName = provider?.name ?? "Wallet";
|
|
6494
|
+
const isMobile = !shouldUseWalletConnector({
|
|
6495
|
+
useWalletConnector: useWalletConnectorProp,
|
|
6496
|
+
userAgent: typeof navigator === "undefined" ? void 0 : navigator.userAgent
|
|
6497
|
+
});
|
|
6498
|
+
if (isMobile) {
|
|
6499
|
+
dispatch({ type: "PAY_STARTED", isSetupRedirect: true });
|
|
6500
|
+
} else {
|
|
6501
|
+
dispatch({ type: "PAY_STARTED", isSetupRedirect: false });
|
|
6502
|
+
dispatch({ type: "NAVIGATE", step: "setup-status" });
|
|
6394
6503
|
}
|
|
6395
|
-
dispatch({ type: "SET_ERROR", error: null });
|
|
6396
|
-
dispatch({ type: "SET_INCREASING_LIMIT", value: true });
|
|
6397
6504
|
try {
|
|
6398
6505
|
const token = await getAccessToken();
|
|
6399
6506
|
if (!token) throw new Error("Not authenticated");
|
|
6400
|
-
const
|
|
6401
|
-
|
|
6402
|
-
|
|
6403
|
-
|
|
6404
|
-
|
|
6405
|
-
|
|
6406
|
-
const isMobile = !shouldUseWalletConnector({
|
|
6407
|
-
useWalletConnector: useWalletConnectorProp,
|
|
6408
|
-
userAgent: typeof navigator === "undefined" ? void 0 : navigator.userAgent
|
|
6507
|
+
const accountId = crypto.randomUUID();
|
|
6508
|
+
const account = await createAccount(apiBaseUrl, token, {
|
|
6509
|
+
id: accountId,
|
|
6510
|
+
name: providerName,
|
|
6511
|
+
credentialId: activeCredentialId,
|
|
6512
|
+
providerId
|
|
6409
6513
|
});
|
|
6514
|
+
const session = account.authorizationSessions?.[0];
|
|
6515
|
+
if (!session) throw new Error("No authorization session returned.");
|
|
6410
6516
|
if (isMobile) {
|
|
6411
6517
|
handlingMobileReturnRef.current = false;
|
|
6412
6518
|
mobileSetupFlowRef.current = true;
|
|
6413
|
-
setupAccountIdRef.current =
|
|
6414
|
-
reauthSessionIdRef.current = session.id;
|
|
6415
|
-
reauthTokenRef.current = null;
|
|
6519
|
+
setupAccountIdRef.current = account.id;
|
|
6416
6520
|
persistMobileFlowState({
|
|
6417
|
-
accountId:
|
|
6521
|
+
accountId: account.id,
|
|
6418
6522
|
sessionId: session.id,
|
|
6419
6523
|
deeplinkUri: session.uri,
|
|
6420
|
-
providerId
|
|
6421
|
-
isSetup: true
|
|
6422
|
-
isReauthorization: true
|
|
6524
|
+
providerId,
|
|
6525
|
+
isSetup: true
|
|
6423
6526
|
});
|
|
6424
6527
|
dispatch({ type: "MOBILE_DEEPLINK_READY", deeplinkUri: session.uri });
|
|
6425
6528
|
triggerDeeplink(session.uri);
|
|
@@ -6430,57 +6533,75 @@ function SwypePaymentInner({
|
|
|
6430
6533
|
}
|
|
6431
6534
|
} catch (err) {
|
|
6432
6535
|
captureException(err);
|
|
6433
|
-
const msg = err instanceof Error ? err.message : "Failed to
|
|
6434
|
-
dispatch({ type: "
|
|
6536
|
+
const msg = err instanceof Error ? err.message : "Failed to set up wallet";
|
|
6537
|
+
dispatch({ type: "PAY_ERROR", error: msg, fallbackStep: "wallet-picker" });
|
|
6435
6538
|
onError?.(msg);
|
|
6436
6539
|
} finally {
|
|
6437
|
-
dispatch({ type: "
|
|
6540
|
+
dispatch({ type: "PAY_ENDED" });
|
|
6438
6541
|
}
|
|
6439
6542
|
}, [
|
|
6440
|
-
|
|
6441
|
-
|
|
6442
|
-
state.accounts,
|
|
6443
|
-
state.providers,
|
|
6543
|
+
activeCredentialId,
|
|
6544
|
+
providers,
|
|
6444
6545
|
apiBaseUrl,
|
|
6445
6546
|
getAccessToken,
|
|
6446
6547
|
authExecutor,
|
|
6447
6548
|
useWalletConnectorProp,
|
|
6448
6549
|
reloadAccounts,
|
|
6449
|
-
onError
|
|
6550
|
+
onError,
|
|
6551
|
+
dispatch,
|
|
6552
|
+
mobileSetupFlowRef,
|
|
6553
|
+
handlingMobileReturnRef,
|
|
6554
|
+
setupAccountIdRef
|
|
6450
6555
|
]);
|
|
6451
|
-
const
|
|
6452
|
-
|
|
6453
|
-
|
|
6454
|
-
|
|
6455
|
-
|
|
6456
|
-
|
|
6457
|
-
|
|
6458
|
-
|
|
6556
|
+
const handleContinueConnection = useCallback(
|
|
6557
|
+
(accountId) => {
|
|
6558
|
+
const acct = accounts.find((a) => a.id === accountId);
|
|
6559
|
+
if (!acct) return;
|
|
6560
|
+
const matchedProvider = providers.find((p) => p.name === acct.name);
|
|
6561
|
+
if (matchedProvider) {
|
|
6562
|
+
handleSelectProvider(matchedProvider.id);
|
|
6563
|
+
}
|
|
6564
|
+
},
|
|
6565
|
+
[accounts, providers, handleSelectProvider]
|
|
6566
|
+
);
|
|
6567
|
+
const handleSelectAccount = useCallback(
|
|
6568
|
+
(accountId) => {
|
|
6569
|
+
const acct = accounts.find((a) => a.id === accountId);
|
|
6570
|
+
if (!acct) return;
|
|
6571
|
+
const activeWallet = getPreferredDepositWallet(acct, depositAmount ?? 0);
|
|
6572
|
+
dispatch({
|
|
6573
|
+
type: "SELECT_ACCOUNT",
|
|
6574
|
+
accountId,
|
|
6575
|
+
walletId: activeWallet?.id ?? null
|
|
6576
|
+
});
|
|
6577
|
+
},
|
|
6578
|
+
[accounts, depositAmount, dispatch]
|
|
6579
|
+
);
|
|
6580
|
+
const handleIncreaseLimit = useCallback(async () => {
|
|
6581
|
+
if (!selectedAccountId) {
|
|
6459
6582
|
dispatch({ type: "SET_ERROR", error: "No account selected." });
|
|
6460
6583
|
return;
|
|
6461
6584
|
}
|
|
6462
|
-
if (!
|
|
6585
|
+
if (!activeCredentialId) {
|
|
6463
6586
|
dispatch({ type: "SET_ERROR", error: "Create or verify a passkey on this device before continuing." });
|
|
6464
6587
|
dispatch({ type: "NAVIGATE", step: "create-passkey" });
|
|
6465
6588
|
return;
|
|
6466
6589
|
}
|
|
6467
|
-
const acct =
|
|
6468
|
-
const matchedProvider = acct ?
|
|
6590
|
+
const acct = accounts.find((a) => a.id === selectedAccountId);
|
|
6591
|
+
const matchedProvider = acct ? providers.find((p) => p.name === acct.name) : void 0;
|
|
6469
6592
|
if (matchedProvider) {
|
|
6470
6593
|
dispatch({ type: "SELECT_PROVIDER", providerId: matchedProvider.id });
|
|
6471
6594
|
}
|
|
6472
6595
|
dispatch({ type: "SET_ERROR", error: null });
|
|
6473
6596
|
dispatch({ type: "SET_INCREASING_LIMIT", value: true });
|
|
6474
|
-
pendingTokenAuthRef.current = { tokenAddress, chainId, tokenSymbol, walletId: _walletId };
|
|
6475
6597
|
try {
|
|
6476
6598
|
const token = await getAccessToken();
|
|
6477
6599
|
if (!token) throw new Error("Not authenticated");
|
|
6478
6600
|
const session = await createAccountAuthorizationSession(
|
|
6479
6601
|
apiBaseUrl,
|
|
6480
6602
|
token,
|
|
6481
|
-
|
|
6482
|
-
|
|
6483
|
-
{ tokenAddress, chainId }
|
|
6603
|
+
selectedAccountId,
|
|
6604
|
+
activeCredentialId
|
|
6484
6605
|
);
|
|
6485
6606
|
const isMobile = !shouldUseWalletConnector({
|
|
6486
6607
|
useWalletConnector: useWalletConnectorProp,
|
|
@@ -6489,205 +6610,187 @@ function SwypePaymentInner({
|
|
|
6489
6610
|
if (isMobile) {
|
|
6490
6611
|
handlingMobileReturnRef.current = false;
|
|
6491
6612
|
mobileSetupFlowRef.current = true;
|
|
6492
|
-
setupAccountIdRef.current =
|
|
6613
|
+
setupAccountIdRef.current = selectedAccountId;
|
|
6493
6614
|
reauthSessionIdRef.current = session.id;
|
|
6494
|
-
reauthTokenRef.current =
|
|
6615
|
+
reauthTokenRef.current = null;
|
|
6495
6616
|
persistMobileFlowState({
|
|
6496
|
-
accountId:
|
|
6617
|
+
accountId: selectedAccountId,
|
|
6497
6618
|
sessionId: session.id,
|
|
6498
6619
|
deeplinkUri: session.uri,
|
|
6499
6620
|
providerId: matchedProvider?.id ?? null,
|
|
6500
6621
|
isSetup: true,
|
|
6501
|
-
isReauthorization: true
|
|
6502
|
-
reauthorizationToken: { walletId: _walletId, tokenSymbol }
|
|
6622
|
+
isReauthorization: true
|
|
6503
6623
|
});
|
|
6504
6624
|
dispatch({ type: "MOBILE_DEEPLINK_READY", deeplinkUri: session.uri });
|
|
6505
6625
|
triggerDeeplink(session.uri);
|
|
6506
6626
|
} else {
|
|
6507
|
-
|
|
6508
|
-
|
|
6509
|
-
|
|
6510
|
-
|
|
6511
|
-
tokenAddress,
|
|
6512
|
-
chainId
|
|
6513
|
-
};
|
|
6514
|
-
dispatch({ type: "SELECT_TOKEN", walletId: _walletId, tokenSymbol });
|
|
6515
|
-
dispatch({ type: "NAVIGATE", step: "setup" });
|
|
6627
|
+
dispatch({ type: "NAVIGATE", step: "setup-status" });
|
|
6628
|
+
await authExecutor.executeSessionById(session.id);
|
|
6629
|
+
await reloadAccounts();
|
|
6630
|
+
dispatch({ type: "NAVIGATE", step: "deposit" });
|
|
6516
6631
|
}
|
|
6517
6632
|
} catch (err) {
|
|
6518
6633
|
captureException(err);
|
|
6519
|
-
const msg = err instanceof Error ? err.message : "Failed to
|
|
6634
|
+
const msg = err instanceof Error ? err.message : "Failed to increase limit";
|
|
6520
6635
|
dispatch({ type: "SET_ERROR", error: msg });
|
|
6521
6636
|
onError?.(msg);
|
|
6522
6637
|
} finally {
|
|
6523
|
-
pendingTokenAuthRef.current = null;
|
|
6524
6638
|
dispatch({ type: "SET_INCREASING_LIMIT", value: false });
|
|
6525
6639
|
}
|
|
6526
6640
|
}, [
|
|
6527
|
-
|
|
6528
|
-
|
|
6529
|
-
|
|
6530
|
-
|
|
6641
|
+
selectedAccountId,
|
|
6642
|
+
activeCredentialId,
|
|
6643
|
+
accounts,
|
|
6644
|
+
providers,
|
|
6531
6645
|
apiBaseUrl,
|
|
6532
6646
|
getAccessToken,
|
|
6533
6647
|
authExecutor,
|
|
6534
6648
|
useWalletConnectorProp,
|
|
6535
6649
|
reloadAccounts,
|
|
6536
|
-
onError
|
|
6650
|
+
onError,
|
|
6651
|
+
dispatch,
|
|
6652
|
+
mobileSetupFlowRef,
|
|
6653
|
+
handlingMobileReturnRef,
|
|
6654
|
+
setupAccountIdRef,
|
|
6655
|
+
reauthSessionIdRef,
|
|
6656
|
+
reauthTokenRef
|
|
6537
6657
|
]);
|
|
6538
|
-
const
|
|
6539
|
-
|
|
6540
|
-
|
|
6541
|
-
|
|
6542
|
-
|
|
6543
|
-
clearMobileFlowState();
|
|
6544
|
-
dispatch({ type: "CONFIRM_SIGN_SUCCESS", transfer: signedTransfer });
|
|
6545
|
-
polling.startPolling(t.id);
|
|
6546
|
-
} catch (err) {
|
|
6547
|
-
captureException(err);
|
|
6548
|
-
const msg = err instanceof Error ? err.message : "Failed to sign transfer";
|
|
6549
|
-
dispatch({ type: "SET_ERROR", error: msg });
|
|
6550
|
-
onError?.(msg);
|
|
6658
|
+
const handleNavigateToTokenPicker = useCallback(() => {
|
|
6659
|
+
if (authExecutor.pendingSelectSource) {
|
|
6660
|
+
dispatch({ type: "NAVIGATE", step: "select-source" });
|
|
6661
|
+
} else {
|
|
6662
|
+
dispatch({ type: "NAVIGATE", step: "token-picker" });
|
|
6551
6663
|
}
|
|
6552
|
-
}, [
|
|
6553
|
-
const
|
|
6554
|
-
dispatch({ type: "
|
|
6555
|
-
|
|
6556
|
-
|
|
6557
|
-
if (
|
|
6558
|
-
|
|
6664
|
+
}, [dispatch, authExecutor.pendingSelectSource]);
|
|
6665
|
+
const handleSelectAuthorizedToken = useCallback((walletId, tokenSymbol) => {
|
|
6666
|
+
dispatch({ type: "SELECT_TOKEN", walletId, tokenSymbol });
|
|
6667
|
+
}, [dispatch]);
|
|
6668
|
+
const handleAuthorizeToken = useCallback(async (_walletId, tokenAddress, chainId, tokenSymbol) => {
|
|
6669
|
+
if (!selectedAccountId) {
|
|
6670
|
+
dispatch({ type: "SET_ERROR", error: "No account selected." });
|
|
6559
6671
|
return;
|
|
6560
6672
|
}
|
|
6561
|
-
|
|
6562
|
-
if (transferIdToResume) {
|
|
6563
|
-
polling.startPolling(transferIdToResume);
|
|
6564
|
-
}
|
|
6565
|
-
}, [handleAuthorizedMobileReturn, polling, state.transfer]);
|
|
6566
|
-
const handleSelectProvider = useCallback(async (providerId) => {
|
|
6567
|
-
dispatch({ type: "SELECT_PROVIDER", providerId });
|
|
6568
|
-
if (!state.activeCredentialId) {
|
|
6673
|
+
if (!activeCredentialId) {
|
|
6569
6674
|
dispatch({ type: "SET_ERROR", error: "Create or verify a passkey on this device before continuing." });
|
|
6570
6675
|
dispatch({ type: "NAVIGATE", step: "create-passkey" });
|
|
6571
6676
|
return;
|
|
6572
6677
|
}
|
|
6573
|
-
const
|
|
6574
|
-
const
|
|
6575
|
-
|
|
6576
|
-
|
|
6577
|
-
userAgent: typeof navigator === "undefined" ? void 0 : navigator.userAgent
|
|
6578
|
-
});
|
|
6579
|
-
if (isMobile) {
|
|
6580
|
-
dispatch({ type: "PAY_STARTED", isSetupRedirect: true });
|
|
6581
|
-
} else {
|
|
6582
|
-
dispatch({ type: "PAY_STARTED", isSetupRedirect: false });
|
|
6583
|
-
dispatch({ type: "NAVIGATE", step: "setup-status" });
|
|
6678
|
+
const acct = accounts.find((a) => a.id === selectedAccountId);
|
|
6679
|
+
const matchedProvider = acct ? providers.find((p) => p.name === acct.name) : void 0;
|
|
6680
|
+
if (matchedProvider) {
|
|
6681
|
+
dispatch({ type: "SELECT_PROVIDER", providerId: matchedProvider.id });
|
|
6584
6682
|
}
|
|
6683
|
+
dispatch({ type: "SET_ERROR", error: null });
|
|
6684
|
+
dispatch({ type: "SET_INCREASING_LIMIT", value: true });
|
|
6585
6685
|
try {
|
|
6586
6686
|
const token = await getAccessToken();
|
|
6587
6687
|
if (!token) throw new Error("Not authenticated");
|
|
6588
|
-
const
|
|
6589
|
-
|
|
6590
|
-
|
|
6591
|
-
|
|
6592
|
-
|
|
6593
|
-
|
|
6688
|
+
const session = await createAccountAuthorizationSession(
|
|
6689
|
+
apiBaseUrl,
|
|
6690
|
+
token,
|
|
6691
|
+
selectedAccountId,
|
|
6692
|
+
activeCredentialId,
|
|
6693
|
+
{ tokenAddress, chainId }
|
|
6694
|
+
);
|
|
6695
|
+
const isMobile = !shouldUseWalletConnector({
|
|
6696
|
+
useWalletConnector: useWalletConnectorProp,
|
|
6697
|
+
userAgent: typeof navigator === "undefined" ? void 0 : navigator.userAgent
|
|
6594
6698
|
});
|
|
6595
|
-
const session = account.authorizationSessions?.[0];
|
|
6596
|
-
if (!session) throw new Error("No authorization session returned.");
|
|
6597
6699
|
if (isMobile) {
|
|
6598
6700
|
handlingMobileReturnRef.current = false;
|
|
6599
6701
|
mobileSetupFlowRef.current = true;
|
|
6600
|
-
setupAccountIdRef.current =
|
|
6702
|
+
setupAccountIdRef.current = selectedAccountId;
|
|
6703
|
+
reauthSessionIdRef.current = session.id;
|
|
6704
|
+
reauthTokenRef.current = { walletId: _walletId, tokenSymbol };
|
|
6601
6705
|
persistMobileFlowState({
|
|
6602
|
-
accountId:
|
|
6706
|
+
accountId: selectedAccountId,
|
|
6603
6707
|
sessionId: session.id,
|
|
6604
6708
|
deeplinkUri: session.uri,
|
|
6605
|
-
providerId,
|
|
6606
|
-
isSetup: true
|
|
6709
|
+
providerId: matchedProvider?.id ?? null,
|
|
6710
|
+
isSetup: true,
|
|
6711
|
+
isReauthorization: true,
|
|
6712
|
+
reauthorizationToken: { walletId: _walletId, tokenSymbol }
|
|
6607
6713
|
});
|
|
6608
6714
|
dispatch({ type: "MOBILE_DEEPLINK_READY", deeplinkUri: session.uri });
|
|
6609
6715
|
triggerDeeplink(session.uri);
|
|
6610
6716
|
} else {
|
|
6717
|
+
dispatch({ type: "NAVIGATE", step: "setup-status" });
|
|
6611
6718
|
await authExecutor.executeSessionById(session.id);
|
|
6612
6719
|
await reloadAccounts();
|
|
6613
|
-
dispatch({ type: "
|
|
6720
|
+
dispatch({ type: "SELECT_TOKEN", walletId: _walletId, tokenSymbol });
|
|
6614
6721
|
}
|
|
6615
6722
|
} catch (err) {
|
|
6616
6723
|
captureException(err);
|
|
6617
|
-
const msg = err instanceof Error ? err.message : "Failed to
|
|
6618
|
-
dispatch({ type: "
|
|
6724
|
+
const msg = err instanceof Error ? err.message : "Failed to authorize token";
|
|
6725
|
+
dispatch({ type: "SET_ERROR", error: msg });
|
|
6619
6726
|
onError?.(msg);
|
|
6620
6727
|
} finally {
|
|
6621
|
-
dispatch({ type: "
|
|
6728
|
+
dispatch({ type: "SET_INCREASING_LIMIT", value: false });
|
|
6622
6729
|
}
|
|
6623
6730
|
}, [
|
|
6624
|
-
|
|
6625
|
-
|
|
6731
|
+
selectedAccountId,
|
|
6732
|
+
activeCredentialId,
|
|
6733
|
+
accounts,
|
|
6734
|
+
providers,
|
|
6626
6735
|
apiBaseUrl,
|
|
6627
6736
|
getAccessToken,
|
|
6628
6737
|
authExecutor,
|
|
6629
6738
|
useWalletConnectorProp,
|
|
6630
6739
|
reloadAccounts,
|
|
6631
|
-
onError
|
|
6740
|
+
onError,
|
|
6741
|
+
dispatch,
|
|
6742
|
+
mobileSetupFlowRef,
|
|
6743
|
+
handlingMobileReturnRef,
|
|
6744
|
+
setupAccountIdRef,
|
|
6745
|
+
reauthSessionIdRef,
|
|
6746
|
+
reauthTokenRef
|
|
6632
6747
|
]);
|
|
6633
|
-
|
|
6634
|
-
|
|
6635
|
-
|
|
6636
|
-
|
|
6637
|
-
|
|
6638
|
-
|
|
6639
|
-
|
|
6640
|
-
|
|
6641
|
-
|
|
6642
|
-
|
|
6643
|
-
|
|
6644
|
-
const
|
|
6645
|
-
|
|
6646
|
-
|
|
6647
|
-
|
|
6648
|
-
|
|
6649
|
-
|
|
6650
|
-
|
|
6651
|
-
|
|
6652
|
-
|
|
6653
|
-
|
|
6654
|
-
},
|
|
6655
|
-
[state.accounts, depositAmount]
|
|
6656
|
-
);
|
|
6748
|
+
return {
|
|
6749
|
+
handleSelectProvider,
|
|
6750
|
+
handleContinueConnection,
|
|
6751
|
+
handleSelectAccount,
|
|
6752
|
+
handleIncreaseLimit,
|
|
6753
|
+
handleNavigateToTokenPicker,
|
|
6754
|
+
handleSelectAuthorizedToken,
|
|
6755
|
+
handleAuthorizeToken
|
|
6756
|
+
};
|
|
6757
|
+
}
|
|
6758
|
+
function useOneTapSetupHandlers(deps) {
|
|
6759
|
+
const {
|
|
6760
|
+
dispatch,
|
|
6761
|
+
getAccessToken,
|
|
6762
|
+
apiBaseUrl,
|
|
6763
|
+
authExecutor,
|
|
6764
|
+
selectSourceChainName,
|
|
6765
|
+
selectSourceTokenSymbol
|
|
6766
|
+
} = deps;
|
|
6767
|
+
const [savingOneTapLimit, setSavingOneTapLimit] = useState(false);
|
|
6768
|
+
const oneTapLimitSavedDuringSetupRef = useRef(false);
|
|
6657
6769
|
const handleSetupOneTap = useCallback(async (limit) => {
|
|
6658
6770
|
setSavingOneTapLimit(true);
|
|
6659
6771
|
try {
|
|
6660
6772
|
const token = await getAccessToken();
|
|
6661
6773
|
if (!token) throw new Error("Not authenticated");
|
|
6662
6774
|
await updateUserConfig(apiBaseUrl, token, { defaultAllowance: limit });
|
|
6663
|
-
if (authExecutor.
|
|
6664
|
-
authExecutor.
|
|
6665
|
-
|
|
6666
|
-
|
|
6667
|
-
|
|
6668
|
-
|
|
6669
|
-
|
|
6670
|
-
|
|
6671
|
-
|
|
6672
|
-
|
|
6673
|
-
|
|
6674
|
-
|
|
6675
|
-
|
|
6676
|
-
try {
|
|
6677
|
-
await authExecutor.executeSessionById(pending.sessionId);
|
|
6678
|
-
await reloadAccounts();
|
|
6679
|
-
dispatch({ type: "SELECT_TOKEN", walletId: pending.walletId, tokenSymbol: pending.tokenSymbol });
|
|
6680
|
-
} catch (authErr) {
|
|
6681
|
-
captureException(authErr);
|
|
6682
|
-
dispatch({
|
|
6683
|
-
type: "SET_ERROR",
|
|
6684
|
-
error: authErr instanceof Error ? authErr.message : "Failed to authorize token"
|
|
6685
|
-
});
|
|
6686
|
-
dispatch({ type: "NAVIGATE", step: "deposit" });
|
|
6687
|
-
} finally {
|
|
6688
|
-
pendingTokenAuthRef.current = null;
|
|
6689
|
-
dispatch({ type: "SET_INCREASING_LIMIT", value: false });
|
|
6775
|
+
if (authExecutor.pendingSelectSource) {
|
|
6776
|
+
const action = authExecutor.pendingSelectSource;
|
|
6777
|
+
const recommended = action.metadata?.recommended;
|
|
6778
|
+
let chainName;
|
|
6779
|
+
let tokenSymbol;
|
|
6780
|
+
if (selectSourceChainName && selectSourceTokenSymbol) {
|
|
6781
|
+
chainName = selectSourceChainName;
|
|
6782
|
+
tokenSymbol = selectSourceTokenSymbol;
|
|
6783
|
+
} else {
|
|
6784
|
+
const options = action.metadata?.options ?? [];
|
|
6785
|
+
const choices = buildSelectSourceChoices(options);
|
|
6786
|
+
chainName = recommended?.chainName ?? choices[0]?.chainName ?? "Base";
|
|
6787
|
+
tokenSymbol = recommended?.tokenSymbol ?? choices[0]?.tokens[0]?.tokenSymbol ?? "USDC";
|
|
6690
6788
|
}
|
|
6789
|
+
oneTapLimitSavedDuringSetupRef.current = true;
|
|
6790
|
+
authExecutor.resolveSelectSource({ chainName, tokenSymbol });
|
|
6791
|
+
dispatch({ type: "NAVIGATE", step: "setup-status" });
|
|
6792
|
+
} else if (authExecutor.pendingOneTapSetup) {
|
|
6793
|
+
authExecutor.resolveOneTapSetup();
|
|
6691
6794
|
} else {
|
|
6692
6795
|
dispatch({ type: "NAVIGATE", step: "deposit" });
|
|
6693
6796
|
}
|
|
@@ -6700,76 +6803,118 @@ function SwypePaymentInner({
|
|
|
6700
6803
|
} finally {
|
|
6701
6804
|
setSavingOneTapLimit(false);
|
|
6702
6805
|
}
|
|
6703
|
-
}, [getAccessToken, apiBaseUrl, authExecutor,
|
|
6704
|
-
|
|
6705
|
-
|
|
6706
|
-
|
|
6707
|
-
|
|
6708
|
-
|
|
6709
|
-
|
|
6710
|
-
|
|
6711
|
-
|
|
6712
|
-
|
|
6713
|
-
|
|
6714
|
-
|
|
6715
|
-
|
|
6716
|
-
|
|
6717
|
-
|
|
6718
|
-
|
|
6719
|
-
|
|
6720
|
-
|
|
6721
|
-
|
|
6722
|
-
|
|
6723
|
-
|
|
6724
|
-
|
|
6725
|
-
|
|
6726
|
-
|
|
6727
|
-
|
|
6728
|
-
|
|
6729
|
-
|
|
6730
|
-
|
|
6731
|
-
|
|
6732
|
-
|
|
6733
|
-
|
|
6734
|
-
|
|
6735
|
-
|
|
6736
|
-
|
|
6737
|
-
|
|
6738
|
-
|
|
6739
|
-
|
|
6740
|
-
|
|
6741
|
-
|
|
6742
|
-
|
|
6743
|
-
|
|
6744
|
-
|
|
6745
|
-
|
|
6746
|
-
|
|
6747
|
-
|
|
6748
|
-
|
|
6749
|
-
|
|
6750
|
-
|
|
6751
|
-
|
|
6752
|
-
|
|
6753
|
-
|
|
6754
|
-
|
|
6755
|
-
|
|
6756
|
-
|
|
6757
|
-
|
|
6758
|
-
|
|
6759
|
-
|
|
6760
|
-
|
|
6761
|
-
|
|
6762
|
-
|
|
6763
|
-
|
|
6806
|
+
}, [getAccessToken, apiBaseUrl, authExecutor, dispatch, selectSourceChainName, selectSourceTokenSymbol]);
|
|
6807
|
+
return {
|
|
6808
|
+
handleSetupOneTap,
|
|
6809
|
+
savingOneTapLimit,
|
|
6810
|
+
oneTapLimitSavedDuringSetupRef
|
|
6811
|
+
};
|
|
6812
|
+
}
|
|
6813
|
+
|
|
6814
|
+
// src/dataLoading.ts
|
|
6815
|
+
function resolveDataLoadAction({
|
|
6816
|
+
authenticated,
|
|
6817
|
+
step,
|
|
6818
|
+
accountsCount,
|
|
6819
|
+
hasActiveCredential,
|
|
6820
|
+
loading
|
|
6821
|
+
}) {
|
|
6822
|
+
if (!authenticated || step === "login" || step === "otp-verify" || accountsCount > 0 || !hasActiveCredential) {
|
|
6823
|
+
return "reset";
|
|
6824
|
+
}
|
|
6825
|
+
if (loading) {
|
|
6826
|
+
return "wait";
|
|
6827
|
+
}
|
|
6828
|
+
return "load";
|
|
6829
|
+
}
|
|
6830
|
+
|
|
6831
|
+
// src/processingStatus.ts
|
|
6832
|
+
var PROCESSING_TIMEOUT_MS = 18e4;
|
|
6833
|
+
function resolvePreferredTransfer(polledTransfer, localTransfer) {
|
|
6834
|
+
return polledTransfer ?? localTransfer;
|
|
6835
|
+
}
|
|
6836
|
+
function getTransferStatus(polledTransfer, localTransfer) {
|
|
6837
|
+
const transfer = resolvePreferredTransfer(polledTransfer, localTransfer);
|
|
6838
|
+
return transfer?.status ?? "UNKNOWN";
|
|
6839
|
+
}
|
|
6840
|
+
function hasProcessingTimedOut(processingStartedAtMs, nowMs) {
|
|
6841
|
+
if (!processingStartedAtMs) return false;
|
|
6842
|
+
return nowMs - processingStartedAtMs >= PROCESSING_TIMEOUT_MS;
|
|
6843
|
+
}
|
|
6844
|
+
var STATUS_DISPLAY_LABELS = {
|
|
6845
|
+
CREATED: "created",
|
|
6846
|
+
AUTHORIZED: "authorized",
|
|
6847
|
+
SENDING: "sending",
|
|
6848
|
+
SENT: "confirming delivery",
|
|
6849
|
+
COMPLETED: "completed",
|
|
6850
|
+
FAILED: "failed"
|
|
6851
|
+
};
|
|
6852
|
+
function getStatusDisplayLabel(status) {
|
|
6853
|
+
return STATUS_DISPLAY_LABELS[status] ?? status;
|
|
6854
|
+
}
|
|
6855
|
+
function buildProcessingTimeoutMessage(status) {
|
|
6856
|
+
const label = getStatusDisplayLabel(status);
|
|
6857
|
+
return `Payment is taking longer than expected (status: ${label}). Please try again.`;
|
|
6858
|
+
}
|
|
6859
|
+
|
|
6860
|
+
// src/hooks/usePaymentEffects.ts
|
|
6861
|
+
function usePaymentEffects(deps) {
|
|
6862
|
+
const {
|
|
6863
|
+
state,
|
|
6864
|
+
dispatch,
|
|
6865
|
+
ready,
|
|
6866
|
+
authenticated,
|
|
6867
|
+
apiBaseUrl,
|
|
6868
|
+
depositAmount,
|
|
6869
|
+
useWalletConnectorProp,
|
|
6870
|
+
onComplete,
|
|
6871
|
+
onError,
|
|
6872
|
+
polling,
|
|
6873
|
+
authExecutor,
|
|
6874
|
+
reloadAccounts,
|
|
6875
|
+
activeOtpStatus,
|
|
6876
|
+
activeOtpErrorMessage,
|
|
6877
|
+
otpCode,
|
|
6878
|
+
handleVerifyLoginCode,
|
|
6879
|
+
setAuthInput,
|
|
6880
|
+
setOtpCode,
|
|
6881
|
+
mobileSetupFlowRef,
|
|
6882
|
+
handlingMobileReturnRef,
|
|
6883
|
+
setupAccountIdRef,
|
|
6884
|
+
reauthSessionIdRef,
|
|
6885
|
+
reauthTokenRef,
|
|
6886
|
+
loadingDataRef,
|
|
6887
|
+
pollingTransferIdRef,
|
|
6888
|
+
processingStartedAtRef,
|
|
6889
|
+
checkingPasskeyRef,
|
|
6890
|
+
pendingSelectSourceAction,
|
|
6891
|
+
selectSourceChoices,
|
|
6892
|
+
selectSourceRecommended,
|
|
6893
|
+
setSelectSourceChainName,
|
|
6894
|
+
setSelectSourceTokenSymbol,
|
|
6895
|
+
initializedSelectSourceActionRef,
|
|
6896
|
+
preSelectSourceStepRef,
|
|
6897
|
+
oneTapLimitSavedDuringSetupRef,
|
|
6898
|
+
handleAuthorizedMobileReturn
|
|
6899
|
+
} = deps;
|
|
6900
|
+
const { getAccessToken } = usePrivy();
|
|
6901
|
+
const onCompleteRef = useRef(onComplete);
|
|
6902
|
+
onCompleteRef.current = onComplete;
|
|
6903
|
+
const getAccessTokenRef = useRef(getAccessToken);
|
|
6904
|
+
getAccessTokenRef.current = getAccessToken;
|
|
6905
|
+
const pollingRef = useRef(polling);
|
|
6906
|
+
pollingRef.current = polling;
|
|
6907
|
+
const handleAuthorizedMobileReturnRef = useRef(handleAuthorizedMobileReturn);
|
|
6908
|
+
handleAuthorizedMobileReturnRef.current = handleAuthorizedMobileReturn;
|
|
6764
6909
|
useEffect(() => {
|
|
6765
6910
|
if (depositAmount != null) {
|
|
6766
6911
|
dispatch({ type: "SYNC_AMOUNT", amount: depositAmount.toString() });
|
|
6767
6912
|
}
|
|
6768
|
-
}, [depositAmount]);
|
|
6913
|
+
}, [depositAmount, dispatch]);
|
|
6769
6914
|
useEffect(() => {
|
|
6770
6915
|
if (authenticated || state.step !== "otp-verify") return;
|
|
6771
6916
|
if (activeOtpErrorMessage) dispatch({ type: "SET_ERROR", error: activeOtpErrorMessage });
|
|
6772
|
-
}, [activeOtpErrorMessage, authenticated, state.step]);
|
|
6917
|
+
}, [activeOtpErrorMessage, authenticated, state.step, dispatch]);
|
|
6773
6918
|
useEffect(() => {
|
|
6774
6919
|
if (state.step === "otp-verify" && /^\d{6}$/.test(otpCode.trim()) && activeOtpStatus === "awaiting-code-input") {
|
|
6775
6920
|
handleVerifyLoginCode();
|
|
@@ -6996,7 +7141,7 @@ function SwypePaymentInner({
|
|
|
6996
7141
|
const load = async () => {
|
|
6997
7142
|
dispatch({ type: "DATA_LOAD_START" });
|
|
6998
7143
|
try {
|
|
6999
|
-
const token = await
|
|
7144
|
+
const token = await getAccessTokenRef.current();
|
|
7000
7145
|
if (!token) throw new Error("Not authenticated");
|
|
7001
7146
|
const [prov, accts, chn] = await Promise.all([
|
|
7002
7147
|
fetchProviders(apiBaseUrl, token),
|
|
@@ -7050,7 +7195,6 @@ function SwypePaymentInner({
|
|
|
7050
7195
|
state.step,
|
|
7051
7196
|
state.accounts.length,
|
|
7052
7197
|
apiBaseUrl,
|
|
7053
|
-
getAccessToken,
|
|
7054
7198
|
state.activeCredentialId,
|
|
7055
7199
|
state.selectedAccountId,
|
|
7056
7200
|
depositAmount
|
|
@@ -7065,7 +7209,7 @@ function SwypePaymentInner({
|
|
|
7065
7209
|
clearMobileFlowState();
|
|
7066
7210
|
dispatch({ type: "TRANSFER_FAILED", transfer: polling.transfer, error: "Transfer failed." });
|
|
7067
7211
|
}
|
|
7068
|
-
}, [polling.transfer, onComplete]);
|
|
7212
|
+
}, [polling.transfer, onComplete, dispatch]);
|
|
7069
7213
|
useEffect(() => {
|
|
7070
7214
|
if (state.step !== "processing") {
|
|
7071
7215
|
processingStartedAtRef.current = null;
|
|
@@ -7091,7 +7235,7 @@ function SwypePaymentInner({
|
|
|
7091
7235
|
}
|
|
7092
7236
|
const timeoutId = window.setTimeout(handleTimeout, remainingMs);
|
|
7093
7237
|
return () => window.clearTimeout(timeoutId);
|
|
7094
|
-
}, [state.step, polling.transfer, state.transfer, polling.stopPolling, onError]);
|
|
7238
|
+
}, [state.step, polling.transfer, state.transfer, polling.stopPolling, onError, dispatch, processingStartedAtRef]);
|
|
7095
7239
|
useEffect(() => {
|
|
7096
7240
|
if (!state.mobileFlow) {
|
|
7097
7241
|
handlingMobileReturnRef.current = false;
|
|
@@ -7101,7 +7245,7 @@ function SwypePaymentInner({
|
|
|
7101
7245
|
const polledTransfer = polling.transfer;
|
|
7102
7246
|
if (!polledTransfer || polledTransfer.status !== "AUTHORIZED") return;
|
|
7103
7247
|
void handleAuthorizedMobileReturn(polledTransfer, mobileSetupFlowRef.current);
|
|
7104
|
-
}, [state.mobileFlow, polling.transfer, handleAuthorizedMobileReturn]);
|
|
7248
|
+
}, [state.mobileFlow, polling.transfer, handleAuthorizedMobileReturn, handlingMobileReturnRef, mobileSetupFlowRef]);
|
|
7105
7249
|
useEffect(() => {
|
|
7106
7250
|
if (!state.mobileFlow || !mobileSetupFlowRef.current) return;
|
|
7107
7251
|
if (state.step !== "open-wallet") return;
|
|
@@ -7172,7 +7316,18 @@ function SwypePaymentInner({
|
|
|
7172
7316
|
window.clearInterval(intervalId);
|
|
7173
7317
|
document.removeEventListener("visibilitychange", handleVisibility);
|
|
7174
7318
|
};
|
|
7175
|
-
}, [
|
|
7319
|
+
}, [
|
|
7320
|
+
state.mobileFlow,
|
|
7321
|
+
state.step,
|
|
7322
|
+
state.activeCredentialId,
|
|
7323
|
+
apiBaseUrl,
|
|
7324
|
+
reloadAccounts,
|
|
7325
|
+
dispatch,
|
|
7326
|
+
mobileSetupFlowRef,
|
|
7327
|
+
setupAccountIdRef,
|
|
7328
|
+
reauthSessionIdRef,
|
|
7329
|
+
reauthTokenRef
|
|
7330
|
+
]);
|
|
7176
7331
|
useEffect(() => {
|
|
7177
7332
|
if (!state.mobileFlow) return;
|
|
7178
7333
|
if (handlingMobileReturnRef.current) return;
|
|
@@ -7186,7 +7341,14 @@ function SwypePaymentInner({
|
|
|
7186
7341
|
};
|
|
7187
7342
|
document.addEventListener("visibilitychange", handleVisibility);
|
|
7188
7343
|
return () => document.removeEventListener("visibilitychange", handleVisibility);
|
|
7189
|
-
}, [
|
|
7344
|
+
}, [
|
|
7345
|
+
state.mobileFlow,
|
|
7346
|
+
state.transfer?.id,
|
|
7347
|
+
polling.isPolling,
|
|
7348
|
+
polling.startPolling,
|
|
7349
|
+
handlingMobileReturnRef,
|
|
7350
|
+
pollingTransferIdRef
|
|
7351
|
+
]);
|
|
7190
7352
|
useEffect(() => {
|
|
7191
7353
|
if (!pendingSelectSourceAction) {
|
|
7192
7354
|
initializedSelectSourceActionRef.current = null;
|
|
@@ -7195,20 +7357,6 @@ function SwypePaymentInner({
|
|
|
7195
7357
|
return;
|
|
7196
7358
|
}
|
|
7197
7359
|
if (initializedSelectSourceActionRef.current === pendingSelectSourceAction.id) return;
|
|
7198
|
-
const options = pendingSelectSourceAction.metadata?.options ?? [];
|
|
7199
|
-
if (pendingTokenAuthRef.current) {
|
|
7200
|
-
const { tokenAddress, chainId } = pendingTokenAuthRef.current;
|
|
7201
|
-
const chainIdHex = `0x${chainId.toString(16)}`;
|
|
7202
|
-
const match = options.find(
|
|
7203
|
-
(opt) => opt.tokenAddress.toLowerCase() === tokenAddress.toLowerCase() && opt.chainId.toLowerCase() === chainIdHex.toLowerCase()
|
|
7204
|
-
);
|
|
7205
|
-
if (match) {
|
|
7206
|
-
setSelectSourceChainName(match.chainName);
|
|
7207
|
-
setSelectSourceTokenSymbol(match.tokenSymbol);
|
|
7208
|
-
initializedSelectSourceActionRef.current = pendingSelectSourceAction.id;
|
|
7209
|
-
return;
|
|
7210
|
-
}
|
|
7211
|
-
}
|
|
7212
7360
|
const hasRecommended = !!selectSourceRecommended && selectSourceChoices.some(
|
|
7213
7361
|
(chain) => chain.chainName === selectSourceRecommended.chainName && chain.tokens.some((t) => t.tokenSymbol === selectSourceRecommended.tokenSymbol)
|
|
7214
7362
|
);
|
|
@@ -7223,7 +7371,14 @@ function SwypePaymentInner({
|
|
|
7223
7371
|
setSelectSourceTokenSymbol("USDC");
|
|
7224
7372
|
}
|
|
7225
7373
|
initializedSelectSourceActionRef.current = pendingSelectSourceAction.id;
|
|
7226
|
-
}, [
|
|
7374
|
+
}, [
|
|
7375
|
+
pendingSelectSourceAction,
|
|
7376
|
+
selectSourceChoices,
|
|
7377
|
+
selectSourceRecommended,
|
|
7378
|
+
setSelectSourceChainName,
|
|
7379
|
+
setSelectSourceTokenSymbol,
|
|
7380
|
+
initializedSelectSourceActionRef
|
|
7381
|
+
]);
|
|
7227
7382
|
useEffect(() => {
|
|
7228
7383
|
if (pendingSelectSourceAction && (state.step === "processing" || state.step === "open-wallet" || state.step === "setup-status")) {
|
|
7229
7384
|
const isDesktop = shouldUseWalletConnector({
|
|
@@ -7231,24 +7386,8 @@ function SwypePaymentInner({
|
|
|
7231
7386
|
userAgent: typeof navigator === "undefined" ? void 0 : navigator.userAgent
|
|
7232
7387
|
});
|
|
7233
7388
|
if (isDesktop && state.step === "setup-status") {
|
|
7234
|
-
|
|
7235
|
-
|
|
7236
|
-
let chainName;
|
|
7237
|
-
let tokenSymbol;
|
|
7238
|
-
if (pendingTokenAuthRef.current) {
|
|
7239
|
-
const { tokenAddress, chainId } = pendingTokenAuthRef.current;
|
|
7240
|
-
const chainIdHex = `0x${chainId.toString(16)}`;
|
|
7241
|
-
const match = options.find(
|
|
7242
|
-
(opt) => opt.tokenAddress.toLowerCase() === tokenAddress.toLowerCase() && opt.chainId.toLowerCase() === chainIdHex.toLowerCase()
|
|
7243
|
-
);
|
|
7244
|
-
chainName = match?.chainName ?? recommended?.chainName ?? "Base";
|
|
7245
|
-
tokenSymbol = match?.tokenSymbol ?? recommended?.tokenSymbol ?? "USDC";
|
|
7246
|
-
} else {
|
|
7247
|
-
const choices = buildSelectSourceChoices(options);
|
|
7248
|
-
chainName = recommended?.chainName ?? choices[0]?.chainName ?? "Base";
|
|
7249
|
-
tokenSymbol = recommended?.tokenSymbol ?? choices[0]?.tokens[0]?.tokenSymbol ?? "USDC";
|
|
7250
|
-
}
|
|
7251
|
-
authExecutor.resolveSelectSource({ chainName, tokenSymbol });
|
|
7389
|
+
preSelectSourceStepRef.current = state.step;
|
|
7390
|
+
dispatch({ type: "NAVIGATE", step: "setup" });
|
|
7252
7391
|
return;
|
|
7253
7392
|
}
|
|
7254
7393
|
preSelectSourceStepRef.current = state.step;
|
|
@@ -7257,75 +7396,243 @@ function SwypePaymentInner({
|
|
|
7257
7396
|
dispatch({ type: "NAVIGATE", step: preSelectSourceStepRef.current ?? "processing" });
|
|
7258
7397
|
preSelectSourceStepRef.current = null;
|
|
7259
7398
|
}
|
|
7260
|
-
}, [pendingSelectSourceAction, state.step,
|
|
7399
|
+
}, [pendingSelectSourceAction, state.step, useWalletConnectorProp, dispatch, preSelectSourceStepRef, authExecutor]);
|
|
7261
7400
|
const pendingOneTapSetupAction = authExecutor.pendingOneTapSetup;
|
|
7262
7401
|
const preOneTapSetupStepRef = useRef(null);
|
|
7263
7402
|
useEffect(() => {
|
|
7264
7403
|
if (pendingOneTapSetupAction && state.step === "setup-status") {
|
|
7265
|
-
|
|
7266
|
-
|
|
7267
|
-
|
|
7268
|
-
}
|
|
7404
|
+
if (oneTapLimitSavedDuringSetupRef.current) {
|
|
7405
|
+
oneTapLimitSavedDuringSetupRef.current = false;
|
|
7406
|
+
authExecutor.resolveOneTapSetup();
|
|
7407
|
+
} else {
|
|
7408
|
+
preOneTapSetupStepRef.current = state.step;
|
|
7409
|
+
reloadAccounts().then(() => {
|
|
7410
|
+
dispatch({ type: "NAVIGATE", step: "setup" });
|
|
7411
|
+
});
|
|
7412
|
+
}
|
|
7269
7413
|
} else if (!pendingOneTapSetupAction && state.step === "setup" && preOneTapSetupStepRef.current) {
|
|
7270
7414
|
dispatch({ type: "NAVIGATE", step: preOneTapSetupStepRef.current });
|
|
7271
7415
|
preOneTapSetupStepRef.current = null;
|
|
7272
7416
|
}
|
|
7273
|
-
}, [pendingOneTapSetupAction, state.step, reloadAccounts]);
|
|
7417
|
+
}, [pendingOneTapSetupAction, state.step, reloadAccounts, authExecutor, dispatch, oneTapLimitSavedDuringSetupRef]);
|
|
7418
|
+
}
|
|
7419
|
+
function SwypePayment(props) {
|
|
7420
|
+
const resetKey = useRef(0);
|
|
7421
|
+
const handleBoundaryReset = useCallback(() => {
|
|
7422
|
+
resetKey.current += 1;
|
|
7423
|
+
}, []);
|
|
7424
|
+
return /* @__PURE__ */ jsx(PaymentErrorBoundary, { onReset: handleBoundaryReset, children: /* @__PURE__ */ jsx(SwypePaymentInner, { ...props }) }, resetKey.current);
|
|
7425
|
+
}
|
|
7426
|
+
function SwypePaymentInner({
|
|
7427
|
+
destination,
|
|
7428
|
+
onComplete,
|
|
7429
|
+
onError,
|
|
7430
|
+
useWalletConnector: useWalletConnectorProp,
|
|
7431
|
+
idempotencyKey,
|
|
7432
|
+
merchantAuthorization,
|
|
7433
|
+
merchantName,
|
|
7434
|
+
onBack,
|
|
7435
|
+
onDismiss,
|
|
7436
|
+
autoCloseSeconds
|
|
7437
|
+
}) {
|
|
7438
|
+
const { apiBaseUrl, depositAmount } = useSwypeConfig();
|
|
7439
|
+
const { ready, authenticated, logout, getAccessToken } = usePrivy();
|
|
7440
|
+
useLoginWithOAuth();
|
|
7441
|
+
const [state, dispatch] = useReducer(
|
|
7442
|
+
paymentReducer,
|
|
7443
|
+
{
|
|
7444
|
+
depositAmount,
|
|
7445
|
+
passkeyPopupNeeded: isSafari() && isInCrossOriginIframe(),
|
|
7446
|
+
activeCredentialId: typeof window === "undefined" ? null : window.localStorage.getItem(ACTIVE_CREDENTIAL_STORAGE_KEY)
|
|
7447
|
+
},
|
|
7448
|
+
createInitialState
|
|
7449
|
+
);
|
|
7450
|
+
const authExecutor = useAuthorizationExecutor();
|
|
7451
|
+
const polling = useTransferPolling();
|
|
7452
|
+
const transferSigning = useTransferSigning();
|
|
7453
|
+
const mobileFlowRefs = {
|
|
7454
|
+
mobileSetupFlowRef: useRef(false),
|
|
7455
|
+
handlingMobileReturnRef: useRef(false),
|
|
7456
|
+
setupAccountIdRef: useRef(null),
|
|
7457
|
+
reauthSessionIdRef: useRef(null),
|
|
7458
|
+
reauthTokenRef: useRef(null),
|
|
7459
|
+
loadingDataRef: useRef(false)
|
|
7460
|
+
};
|
|
7461
|
+
const derived = useDerivedState(state);
|
|
7462
|
+
const auth = useAuthHandlers(dispatch, state.verificationTarget);
|
|
7463
|
+
const passkey = usePasskeyHandlers(
|
|
7464
|
+
dispatch,
|
|
7465
|
+
apiBaseUrl,
|
|
7466
|
+
state.accounts,
|
|
7467
|
+
state.knownCredentialIds,
|
|
7468
|
+
mobileFlowRefs.mobileSetupFlowRef
|
|
7469
|
+
);
|
|
7470
|
+
const transfer = useTransferHandlers({
|
|
7471
|
+
dispatch,
|
|
7472
|
+
getAccessToken,
|
|
7473
|
+
apiBaseUrl,
|
|
7474
|
+
depositAmount,
|
|
7475
|
+
destination,
|
|
7476
|
+
idempotencyKey,
|
|
7477
|
+
merchantAuthorization,
|
|
7478
|
+
onComplete,
|
|
7479
|
+
onError,
|
|
7480
|
+
polling,
|
|
7481
|
+
transferSigning,
|
|
7482
|
+
sourceType: derived.sourceType,
|
|
7483
|
+
sourceId: derived.sourceId,
|
|
7484
|
+
sourceTokenAddress: derived.selectedSource?.address,
|
|
7485
|
+
activeCredentialId: state.activeCredentialId,
|
|
7486
|
+
selectedAccountId: state.selectedAccountId,
|
|
7487
|
+
transfer: state.transfer,
|
|
7488
|
+
accounts: state.accounts
|
|
7489
|
+
});
|
|
7490
|
+
const mobileFlow = useMobileFlowHandlers(
|
|
7491
|
+
dispatch,
|
|
7492
|
+
polling,
|
|
7493
|
+
transfer.reloadAccounts,
|
|
7494
|
+
transfer.pollingTransferIdRef,
|
|
7495
|
+
state.transfer,
|
|
7496
|
+
mobileFlowRefs
|
|
7497
|
+
);
|
|
7498
|
+
const sourceSelection = useSourceSelectionHandlers(dispatch, authExecutor);
|
|
7499
|
+
const provider = useProviderHandlers({
|
|
7500
|
+
dispatch,
|
|
7501
|
+
getAccessToken,
|
|
7502
|
+
apiBaseUrl,
|
|
7503
|
+
depositAmount,
|
|
7504
|
+
useWalletConnectorProp,
|
|
7505
|
+
activeCredentialId: state.activeCredentialId,
|
|
7506
|
+
selectedAccountId: state.selectedAccountId,
|
|
7507
|
+
accounts: state.accounts,
|
|
7508
|
+
providers: state.providers,
|
|
7509
|
+
authExecutor,
|
|
7510
|
+
reloadAccounts: transfer.reloadAccounts,
|
|
7511
|
+
onError,
|
|
7512
|
+
mobileSetupFlowRef: mobileFlowRefs.mobileSetupFlowRef,
|
|
7513
|
+
handlingMobileReturnRef: mobileFlowRefs.handlingMobileReturnRef,
|
|
7514
|
+
setupAccountIdRef: mobileFlowRefs.setupAccountIdRef,
|
|
7515
|
+
reauthSessionIdRef: mobileFlowRefs.reauthSessionIdRef,
|
|
7516
|
+
reauthTokenRef: mobileFlowRefs.reauthTokenRef
|
|
7517
|
+
});
|
|
7518
|
+
const oneTapSetup = useOneTapSetupHandlers({
|
|
7519
|
+
dispatch,
|
|
7520
|
+
getAccessToken,
|
|
7521
|
+
apiBaseUrl,
|
|
7522
|
+
authExecutor,
|
|
7523
|
+
selectSourceChainName: sourceSelection.selectSourceChainName,
|
|
7524
|
+
selectSourceTokenSymbol: sourceSelection.selectSourceTokenSymbol
|
|
7525
|
+
});
|
|
7526
|
+
const handleNewPayment = useCallback(() => {
|
|
7527
|
+
clearMobileFlowState();
|
|
7528
|
+
transfer.processingStartedAtRef.current = null;
|
|
7529
|
+
transfer.pollingTransferIdRef.current = null;
|
|
7530
|
+
sourceSelection.preSelectSourceStepRef.current = null;
|
|
7531
|
+
oneTapSetup.oneTapLimitSavedDuringSetupRef.current = false;
|
|
7532
|
+
dispatch({
|
|
7533
|
+
type: "NEW_PAYMENT",
|
|
7534
|
+
depositAmount,
|
|
7535
|
+
firstAccountId: state.accounts.length > 0 ? state.accounts[0].id : null
|
|
7536
|
+
});
|
|
7537
|
+
}, [depositAmount, state.accounts, transfer, sourceSelection, provider, oneTapSetup]);
|
|
7538
|
+
const handleLogout = useCallback(async () => {
|
|
7539
|
+
try {
|
|
7540
|
+
await logout();
|
|
7541
|
+
} catch {
|
|
7542
|
+
}
|
|
7543
|
+
clearMobileFlowState();
|
|
7544
|
+
if (typeof window !== "undefined") {
|
|
7545
|
+
window.localStorage.removeItem(ACTIVE_CREDENTIAL_STORAGE_KEY);
|
|
7546
|
+
}
|
|
7547
|
+
polling.stopPolling();
|
|
7548
|
+
sourceSelection.preSelectSourceStepRef.current = null;
|
|
7549
|
+
passkey.checkingPasskeyRef.current = false;
|
|
7550
|
+
oneTapSetup.oneTapLimitSavedDuringSetupRef.current = false;
|
|
7551
|
+
auth.setAuthInput("");
|
|
7552
|
+
auth.setOtpCode("");
|
|
7553
|
+
dispatch({ type: "LOGOUT", depositAmount });
|
|
7554
|
+
}, [logout, polling, depositAmount, auth, sourceSelection, provider, passkey, oneTapSetup]);
|
|
7555
|
+
usePaymentEffects({
|
|
7556
|
+
state,
|
|
7557
|
+
dispatch,
|
|
7558
|
+
ready,
|
|
7559
|
+
authenticated,
|
|
7560
|
+
apiBaseUrl,
|
|
7561
|
+
depositAmount,
|
|
7562
|
+
useWalletConnectorProp,
|
|
7563
|
+
onComplete,
|
|
7564
|
+
onError,
|
|
7565
|
+
polling,
|
|
7566
|
+
authExecutor,
|
|
7567
|
+
reloadAccounts: transfer.reloadAccounts,
|
|
7568
|
+
activeOtpStatus: auth.activeOtpStatus,
|
|
7569
|
+
activeOtpErrorMessage: auth.activeOtpErrorMessage,
|
|
7570
|
+
otpCode: auth.otpCode,
|
|
7571
|
+
handleVerifyLoginCode: auth.handleVerifyLoginCode,
|
|
7572
|
+
setAuthInput: auth.setAuthInput,
|
|
7573
|
+
setOtpCode: auth.setOtpCode,
|
|
7574
|
+
mobileSetupFlowRef: mobileFlowRefs.mobileSetupFlowRef,
|
|
7575
|
+
handlingMobileReturnRef: mobileFlowRefs.handlingMobileReturnRef,
|
|
7576
|
+
setupAccountIdRef: mobileFlowRefs.setupAccountIdRef,
|
|
7577
|
+
reauthSessionIdRef: mobileFlowRefs.reauthSessionIdRef,
|
|
7578
|
+
reauthTokenRef: mobileFlowRefs.reauthTokenRef,
|
|
7579
|
+
loadingDataRef: mobileFlowRefs.loadingDataRef,
|
|
7580
|
+
pollingTransferIdRef: transfer.pollingTransferIdRef,
|
|
7581
|
+
processingStartedAtRef: transfer.processingStartedAtRef,
|
|
7582
|
+
checkingPasskeyRef: passkey.checkingPasskeyRef,
|
|
7583
|
+
pendingSelectSourceAction: sourceSelection.pendingSelectSourceAction,
|
|
7584
|
+
selectSourceChoices: sourceSelection.selectSourceChoices,
|
|
7585
|
+
selectSourceRecommended: sourceSelection.selectSourceRecommended,
|
|
7586
|
+
setSelectSourceChainName: sourceSelection.setSelectSourceChainName,
|
|
7587
|
+
setSelectSourceTokenSymbol: sourceSelection.setSelectSourceTokenSymbol,
|
|
7588
|
+
initializedSelectSourceActionRef: sourceSelection.initializedSelectSourceActionRef,
|
|
7589
|
+
preSelectSourceStepRef: sourceSelection.preSelectSourceStepRef,
|
|
7590
|
+
oneTapLimitSavedDuringSetupRef: oneTapSetup.oneTapLimitSavedDuringSetupRef,
|
|
7591
|
+
handleAuthorizedMobileReturn: mobileFlow.handleAuthorizedMobileReturn
|
|
7592
|
+
});
|
|
7274
7593
|
const handlers = useMemo(() => ({
|
|
7275
|
-
onSendLoginCode: handleSendLoginCode,
|
|
7276
|
-
onVerifyLoginCode: handleVerifyLoginCode,
|
|
7277
|
-
onResendLoginCode: handleResendLoginCode,
|
|
7594
|
+
onSendLoginCode: auth.handleSendLoginCode,
|
|
7595
|
+
onVerifyLoginCode: auth.handleVerifyLoginCode,
|
|
7596
|
+
onResendLoginCode: auth.handleResendLoginCode,
|
|
7278
7597
|
onBackFromOtp: () => {
|
|
7279
|
-
setOtpCode("");
|
|
7598
|
+
auth.setOtpCode("");
|
|
7280
7599
|
dispatch({ type: "BACK_TO_LOGIN" });
|
|
7281
7600
|
},
|
|
7282
|
-
onRegisterPasskey: handleRegisterPasskey,
|
|
7283
|
-
onCreatePasskeyViaPopup: handleCreatePasskeyViaPopup,
|
|
7284
|
-
onVerifyPasskeyViaPopup: handleVerifyPasskeyViaPopup,
|
|
7285
|
-
onSelectProvider: handleSelectProvider,
|
|
7286
|
-
onContinueConnection: handleContinueConnection,
|
|
7287
|
-
onSelectAccount: handleSelectAccount,
|
|
7288
|
-
onPay: handlePay,
|
|
7289
|
-
onIncreaseLimit: handleIncreaseLimit,
|
|
7290
|
-
onConfirmSign: handleConfirmSign,
|
|
7291
|
-
onRetryMobileStatus: handleRetryMobileStatus,
|
|
7601
|
+
onRegisterPasskey: passkey.handleRegisterPasskey,
|
|
7602
|
+
onCreatePasskeyViaPopup: passkey.handleCreatePasskeyViaPopup,
|
|
7603
|
+
onVerifyPasskeyViaPopup: passkey.handleVerifyPasskeyViaPopup,
|
|
7604
|
+
onSelectProvider: provider.handleSelectProvider,
|
|
7605
|
+
onContinueConnection: provider.handleContinueConnection,
|
|
7606
|
+
onSelectAccount: provider.handleSelectAccount,
|
|
7607
|
+
onPay: transfer.handlePay,
|
|
7608
|
+
onIncreaseLimit: provider.handleIncreaseLimit,
|
|
7609
|
+
onConfirmSign: transfer.handleConfirmSign,
|
|
7610
|
+
onRetryMobileStatus: mobileFlow.handleRetryMobileStatus,
|
|
7292
7611
|
onLogout: handleLogout,
|
|
7293
7612
|
onNewPayment: handleNewPayment,
|
|
7294
7613
|
onNavigate: (step) => dispatch({ type: "NAVIGATE", step }),
|
|
7295
|
-
onSetAuthInput: setAuthInput,
|
|
7614
|
+
onSetAuthInput: auth.setAuthInput,
|
|
7296
7615
|
onSetOtpCode: (code) => {
|
|
7297
|
-
setOtpCode(code);
|
|
7616
|
+
auth.setOtpCode(code);
|
|
7298
7617
|
dispatch({ type: "SET_ERROR", error: null });
|
|
7299
7618
|
},
|
|
7300
|
-
onSelectSourceChainChange: handleSelectSourceChainChange,
|
|
7301
|
-
onSetSelectSourceTokenSymbol: setSelectSourceTokenSymbol,
|
|
7302
|
-
onConfirmSelectSource: handleConfirmSelectSource,
|
|
7303
|
-
onSetupOneTap: handleSetupOneTap,
|
|
7304
|
-
onSelectToken: handleNavigateToTokenPicker,
|
|
7305
|
-
onSelectAuthorizedToken: handleSelectAuthorizedToken,
|
|
7306
|
-
onAuthorizeToken: handleAuthorizeToken
|
|
7619
|
+
onSelectSourceChainChange: sourceSelection.handleSelectSourceChainChange,
|
|
7620
|
+
onSetSelectSourceTokenSymbol: sourceSelection.setSelectSourceTokenSymbol,
|
|
7621
|
+
onConfirmSelectSource: sourceSelection.handleConfirmSelectSource,
|
|
7622
|
+
onSetupOneTap: oneTapSetup.handleSetupOneTap,
|
|
7623
|
+
onSelectToken: provider.handleNavigateToTokenPicker,
|
|
7624
|
+
onSelectAuthorizedToken: provider.handleSelectAuthorizedToken,
|
|
7625
|
+
onAuthorizeToken: provider.handleAuthorizeToken
|
|
7307
7626
|
}), [
|
|
7308
|
-
|
|
7309
|
-
|
|
7310
|
-
|
|
7311
|
-
|
|
7312
|
-
|
|
7313
|
-
|
|
7314
|
-
|
|
7315
|
-
handleContinueConnection,
|
|
7316
|
-
handleSelectAccount,
|
|
7317
|
-
handlePay,
|
|
7318
|
-
handleIncreaseLimit,
|
|
7319
|
-
handleConfirmSign,
|
|
7320
|
-
handleRetryMobileStatus,
|
|
7627
|
+
auth,
|
|
7628
|
+
passkey,
|
|
7629
|
+
provider,
|
|
7630
|
+
transfer,
|
|
7631
|
+
mobileFlow,
|
|
7632
|
+
sourceSelection,
|
|
7633
|
+
oneTapSetup,
|
|
7321
7634
|
handleLogout,
|
|
7322
|
-
handleNewPayment
|
|
7323
|
-
handleSelectSourceChainChange,
|
|
7324
|
-
handleConfirmSelectSource,
|
|
7325
|
-
handleSetupOneTap,
|
|
7326
|
-
handleNavigateToTokenPicker,
|
|
7327
|
-
handleSelectAuthorizedToken,
|
|
7328
|
-
handleAuthorizeToken
|
|
7635
|
+
handleNewPayment
|
|
7329
7636
|
]);
|
|
7330
7637
|
return /* @__PURE__ */ jsx(
|
|
7331
7638
|
StepRenderer,
|
|
@@ -7333,28 +7640,29 @@ function SwypePaymentInner({
|
|
|
7333
7640
|
state,
|
|
7334
7641
|
ready,
|
|
7335
7642
|
authenticated,
|
|
7336
|
-
activeOtpStatus,
|
|
7643
|
+
activeOtpStatus: auth.activeOtpStatus,
|
|
7337
7644
|
pollingTransfer: polling.transfer,
|
|
7338
7645
|
pollingError: polling.error,
|
|
7339
7646
|
authExecutorError: authExecutor.error,
|
|
7340
7647
|
transferSigningSigning: transferSigning.signing,
|
|
7341
7648
|
transferSigningError: transferSigning.error,
|
|
7342
|
-
pendingConnections,
|
|
7343
|
-
depositEligibleAccounts,
|
|
7344
|
-
sourceName,
|
|
7345
|
-
sourceAddress,
|
|
7346
|
-
sourceVerified,
|
|
7347
|
-
maxSourceBalance,
|
|
7348
|
-
tokenCount,
|
|
7349
|
-
selectedAccount,
|
|
7350
|
-
selectedSource,
|
|
7351
|
-
selectSourceChoices,
|
|
7352
|
-
selectSourceRecommended,
|
|
7353
|
-
|
|
7354
|
-
|
|
7355
|
-
|
|
7356
|
-
|
|
7357
|
-
|
|
7649
|
+
pendingConnections: derived.pendingConnections,
|
|
7650
|
+
depositEligibleAccounts: derived.depositEligibleAccounts,
|
|
7651
|
+
sourceName: derived.sourceName,
|
|
7652
|
+
sourceAddress: derived.sourceAddress,
|
|
7653
|
+
sourceVerified: derived.sourceVerified,
|
|
7654
|
+
maxSourceBalance: derived.maxSourceBalance,
|
|
7655
|
+
tokenCount: derived.tokenCount,
|
|
7656
|
+
selectedAccount: derived.selectedAccount,
|
|
7657
|
+
selectedSource: derived.selectedSource,
|
|
7658
|
+
selectSourceChoices: sourceSelection.selectSourceChoices,
|
|
7659
|
+
selectSourceRecommended: sourceSelection.selectSourceRecommended,
|
|
7660
|
+
selectSourceAvailableBalance: sourceSelection.selectSourceAvailableBalance,
|
|
7661
|
+
authInput: auth.authInput,
|
|
7662
|
+
otpCode: auth.otpCode,
|
|
7663
|
+
selectSourceChainName: sourceSelection.selectSourceChainName,
|
|
7664
|
+
selectSourceTokenSymbol: sourceSelection.selectSourceTokenSymbol,
|
|
7665
|
+
savingOneTapLimit: oneTapSetup.savingOneTapLimit,
|
|
7358
7666
|
merchantName,
|
|
7359
7667
|
onBack,
|
|
7360
7668
|
onDismiss,
|