@swype-org/react-sdk 0.1.98 → 0.1.102
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 +173 -124
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +14 -4
- package/dist/index.d.ts +14 -4
- package/dist/index.js +173 -124
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -159,7 +159,9 @@ function useSwypeDepositAmount() {
|
|
|
159
159
|
// src/api.ts
|
|
160
160
|
var api_exports = {};
|
|
161
161
|
__export(api_exports, {
|
|
162
|
+
createAccount: () => createAccount,
|
|
162
163
|
createTransfer: () => createTransfer,
|
|
164
|
+
fetchAccount: () => fetchAccount,
|
|
163
165
|
fetchAccounts: () => fetchAccounts,
|
|
164
166
|
fetchAuthorizationSession: () => fetchAuthorizationSession,
|
|
165
167
|
fetchChains: () => fetchChains,
|
|
@@ -206,6 +208,32 @@ async function fetchAccounts(apiBaseUrl, token, credentialId) {
|
|
|
206
208
|
const data = await res.json();
|
|
207
209
|
return data.items;
|
|
208
210
|
}
|
|
211
|
+
async function fetchAccount(apiBaseUrl, token, accountId, credentialId) {
|
|
212
|
+
const params = new URLSearchParams({ credentialId });
|
|
213
|
+
const res = await fetch(`${apiBaseUrl}/v1/accounts/${accountId}?${params.toString()}`, {
|
|
214
|
+
headers: { Authorization: `Bearer ${token}` }
|
|
215
|
+
});
|
|
216
|
+
if (!res.ok) await throwApiError(res);
|
|
217
|
+
return await res.json();
|
|
218
|
+
}
|
|
219
|
+
async function createAccount(apiBaseUrl, token, params) {
|
|
220
|
+
const body = {
|
|
221
|
+
id: params.id ?? crypto.randomUUID(),
|
|
222
|
+
name: params.name,
|
|
223
|
+
credentialId: params.credentialId,
|
|
224
|
+
providerId: params.providerId
|
|
225
|
+
};
|
|
226
|
+
const res = await fetch(`${apiBaseUrl}/v1/accounts`, {
|
|
227
|
+
method: "POST",
|
|
228
|
+
headers: {
|
|
229
|
+
"Content-Type": "application/json",
|
|
230
|
+
Authorization: `Bearer ${token}`
|
|
231
|
+
},
|
|
232
|
+
body: JSON.stringify(body)
|
|
233
|
+
});
|
|
234
|
+
if (!res.ok) await throwApiError(res);
|
|
235
|
+
return await res.json();
|
|
236
|
+
}
|
|
209
237
|
async function createTransfer(apiBaseUrl, token, params) {
|
|
210
238
|
if (!params.merchantAuthorization) {
|
|
211
239
|
throw new Error("merchantAuthorization is required for transfer creation.");
|
|
@@ -1470,15 +1498,6 @@ function useAuthorizationExecutor(options) {
|
|
|
1470
1498
|
},
|
|
1471
1499
|
[apiBaseUrl, dispatchAction]
|
|
1472
1500
|
);
|
|
1473
|
-
const executeSession = react.useCallback(
|
|
1474
|
-
async (transfer) => {
|
|
1475
|
-
if (!transfer.authorizationSessions?.length) {
|
|
1476
|
-
throw new Error("No authorization sessions available.");
|
|
1477
|
-
}
|
|
1478
|
-
await executeSessionById(transfer.authorizationSessions[0].id);
|
|
1479
|
-
},
|
|
1480
|
-
[executeSessionById]
|
|
1481
|
-
);
|
|
1482
1501
|
return {
|
|
1483
1502
|
executing,
|
|
1484
1503
|
results,
|
|
@@ -1486,8 +1505,7 @@ function useAuthorizationExecutor(options) {
|
|
|
1486
1505
|
currentAction,
|
|
1487
1506
|
pendingSelectSource,
|
|
1488
1507
|
resolveSelectSource,
|
|
1489
|
-
executeSessionById
|
|
1490
|
-
executeSession
|
|
1508
|
+
executeSessionById
|
|
1491
1509
|
};
|
|
1492
1510
|
}
|
|
1493
1511
|
function useTransferSigning(pollIntervalMs = 2e3, options) {
|
|
@@ -1845,16 +1863,13 @@ function buildSelectSourceChoices(options) {
|
|
|
1845
1863
|
|
|
1846
1864
|
// src/paymentReducer.ts
|
|
1847
1865
|
function deriveSourceTypeAndId(state) {
|
|
1848
|
-
if (state.connectingNewAccount) {
|
|
1849
|
-
return { sourceType: "providerId", sourceId: state.selectedProviderId ?? "" };
|
|
1850
|
-
}
|
|
1851
1866
|
if (state.selectedWalletId) {
|
|
1852
1867
|
return { sourceType: "walletId", sourceId: state.selectedWalletId };
|
|
1853
1868
|
}
|
|
1854
1869
|
if (state.selectedAccountId) {
|
|
1855
1870
|
return { sourceType: "accountId", sourceId: state.selectedAccountId };
|
|
1856
1871
|
}
|
|
1857
|
-
return { sourceType: "
|
|
1872
|
+
return { sourceType: "accountId", sourceId: "" };
|
|
1858
1873
|
}
|
|
1859
1874
|
function createInitialState(config) {
|
|
1860
1875
|
return {
|
|
@@ -1864,10 +1879,9 @@ function createInitialState(config) {
|
|
|
1864
1879
|
accounts: [],
|
|
1865
1880
|
chains: [],
|
|
1866
1881
|
loadingData: false,
|
|
1882
|
+
selectedProviderId: null,
|
|
1867
1883
|
selectedAccountId: null,
|
|
1868
1884
|
selectedWalletId: null,
|
|
1869
|
-
selectedProviderId: null,
|
|
1870
|
-
connectingNewAccount: false,
|
|
1871
1885
|
amount: config.depositAmount != null ? config.depositAmount.toString() : "",
|
|
1872
1886
|
transfer: null,
|
|
1873
1887
|
creatingTransfer: false,
|
|
@@ -1932,8 +1946,6 @@ function paymentReducer(state, action) {
|
|
|
1932
1946
|
if (action.defaults) {
|
|
1933
1947
|
next.selectedAccountId = action.defaults.accountId;
|
|
1934
1948
|
next.selectedWalletId = action.defaults.walletId;
|
|
1935
|
-
} else if (action.fallbackProviderId && !state.connectingNewAccount) {
|
|
1936
|
-
next.selectedProviderId = action.fallbackProviderId;
|
|
1937
1949
|
}
|
|
1938
1950
|
if (action.clearMobileState) {
|
|
1939
1951
|
next.mobileFlow = false;
|
|
@@ -1955,7 +1967,6 @@ function paymentReducer(state, action) {
|
|
|
1955
1967
|
if (action.defaults) {
|
|
1956
1968
|
next.selectedAccountId = action.defaults.accountId;
|
|
1957
1969
|
next.selectedWalletId = action.defaults.walletId;
|
|
1958
|
-
next.connectingNewAccount = false;
|
|
1959
1970
|
}
|
|
1960
1971
|
return next;
|
|
1961
1972
|
}
|
|
@@ -1965,14 +1976,13 @@ function paymentReducer(state, action) {
|
|
|
1965
1976
|
...state,
|
|
1966
1977
|
selectedProviderId: action.providerId,
|
|
1967
1978
|
selectedAccountId: null,
|
|
1968
|
-
|
|
1979
|
+
selectedWalletId: null
|
|
1969
1980
|
};
|
|
1970
1981
|
case "SELECT_ACCOUNT":
|
|
1971
1982
|
return {
|
|
1972
1983
|
...state,
|
|
1973
1984
|
selectedAccountId: action.accountId,
|
|
1974
1985
|
selectedWalletId: action.walletId,
|
|
1975
|
-
connectingNewAccount: false,
|
|
1976
1986
|
step: "deposit"
|
|
1977
1987
|
};
|
|
1978
1988
|
// ── Transfer lifecycle ───────────────────────────────────────
|
|
@@ -2035,7 +2045,7 @@ function paymentReducer(state, action) {
|
|
|
2035
2045
|
case "MOBILE_SETUP_COMPLETE":
|
|
2036
2046
|
return {
|
|
2037
2047
|
...state,
|
|
2038
|
-
transfer: action.transfer,
|
|
2048
|
+
transfer: action.transfer ?? state.transfer,
|
|
2039
2049
|
error: null,
|
|
2040
2050
|
mobileFlow: false,
|
|
2041
2051
|
deeplinkUri: null,
|
|
@@ -2057,7 +2067,7 @@ function paymentReducer(state, action) {
|
|
|
2057
2067
|
...state,
|
|
2058
2068
|
mobileFlow: true,
|
|
2059
2069
|
deeplinkUri: action.deeplinkUri,
|
|
2060
|
-
selectedProviderId: action.providerId,
|
|
2070
|
+
selectedProviderId: action.providerId ?? state.selectedProviderId,
|
|
2061
2071
|
error: action.error ?? null,
|
|
2062
2072
|
step: "open-wallet"
|
|
2063
2073
|
};
|
|
@@ -2113,7 +2123,7 @@ function paymentReducer(state, action) {
|
|
|
2113
2123
|
amount: action.depositAmount != null ? action.depositAmount.toString() : "",
|
|
2114
2124
|
mobileFlow: false,
|
|
2115
2125
|
deeplinkUri: null,
|
|
2116
|
-
|
|
2126
|
+
selectedProviderId: null,
|
|
2117
2127
|
selectedWalletId: null,
|
|
2118
2128
|
selectedAccountId: action.firstAccountId
|
|
2119
2129
|
};
|
|
@@ -5131,6 +5141,7 @@ function SwypePaymentInner({
|
|
|
5131
5141
|
);
|
|
5132
5142
|
const loadingDataRef = react.useRef(false);
|
|
5133
5143
|
const pollingTransferIdRef = react.useRef(null);
|
|
5144
|
+
const setupAccountIdRef = react.useRef(null);
|
|
5134
5145
|
const mobileSetupFlowRef = react.useRef(false);
|
|
5135
5146
|
const handlingMobileReturnRef = react.useRef(false);
|
|
5136
5147
|
const processingStartedAtRef = react.useRef(null);
|
|
@@ -5263,11 +5274,11 @@ function SwypePaymentInner({
|
|
|
5263
5274
|
accounts: state.accounts,
|
|
5264
5275
|
persistedMobileFlow: loadMobileFlowState(),
|
|
5265
5276
|
mobileSetupInProgress: mobileSetupFlowRef.current,
|
|
5266
|
-
connectingNewAccount:
|
|
5277
|
+
connectingNewAccount: false
|
|
5267
5278
|
});
|
|
5268
5279
|
if (resolved.clearPersistedFlow) clearMobileFlowState();
|
|
5269
5280
|
dispatch({ type: "NAVIGATE", step: resolved.step });
|
|
5270
|
-
}, [getAccessToken, apiBaseUrl, state.accounts
|
|
5281
|
+
}, [getAccessToken, apiBaseUrl, state.accounts]);
|
|
5271
5282
|
const handleRegisterPasskey = react.useCallback(async () => {
|
|
5272
5283
|
dispatch({ type: "SET_REGISTERING_PASSKEY", value: true });
|
|
5273
5284
|
dispatch({ type: "SET_ERROR", error: null });
|
|
@@ -5312,7 +5323,7 @@ function SwypePaymentInner({
|
|
|
5312
5323
|
accounts: state.accounts,
|
|
5313
5324
|
persistedMobileFlow: loadMobileFlowState(),
|
|
5314
5325
|
mobileSetupInProgress: mobileSetupFlowRef.current,
|
|
5315
|
-
connectingNewAccount:
|
|
5326
|
+
connectingNewAccount: false
|
|
5316
5327
|
});
|
|
5317
5328
|
if (resolved.clearPersistedFlow) clearMobileFlowState();
|
|
5318
5329
|
dispatch({ type: "NAVIGATE", step: resolved.step });
|
|
@@ -5325,7 +5336,7 @@ function SwypePaymentInner({
|
|
|
5325
5336
|
} finally {
|
|
5326
5337
|
dispatch({ type: "SET_REGISTERING_PASSKEY", value: false });
|
|
5327
5338
|
}
|
|
5328
|
-
}, [user, getAccessToken, apiBaseUrl, state.accounts
|
|
5339
|
+
}, [user, getAccessToken, apiBaseUrl, state.accounts]);
|
|
5329
5340
|
const handleVerifyPasskeyViaPopup = react.useCallback(async () => {
|
|
5330
5341
|
dispatch({ type: "SET_VERIFYING_PASSKEY", value: true });
|
|
5331
5342
|
dispatch({ type: "SET_ERROR", error: null });
|
|
@@ -5349,7 +5360,7 @@ function SwypePaymentInner({
|
|
|
5349
5360
|
accounts: state.accounts,
|
|
5350
5361
|
persistedMobileFlow: loadMobileFlowState(),
|
|
5351
5362
|
mobileSetupInProgress: mobileSetupFlowRef.current,
|
|
5352
|
-
connectingNewAccount:
|
|
5363
|
+
connectingNewAccount: false
|
|
5353
5364
|
});
|
|
5354
5365
|
if (resolved.clearPersistedFlow) clearMobileFlowState();
|
|
5355
5366
|
dispatch({ type: "NAVIGATE", step: resolved.step });
|
|
@@ -5368,7 +5379,7 @@ function SwypePaymentInner({
|
|
|
5368
5379
|
} finally {
|
|
5369
5380
|
dispatch({ type: "SET_VERIFYING_PASSKEY", value: false });
|
|
5370
5381
|
}
|
|
5371
|
-
}, [state.knownCredentialIds, getAccessToken, apiBaseUrl, state.accounts
|
|
5382
|
+
}, [state.knownCredentialIds, getAccessToken, apiBaseUrl, state.accounts]);
|
|
5372
5383
|
const reloadAccounts = react.useCallback(async () => {
|
|
5373
5384
|
const token = await getAccessToken();
|
|
5374
5385
|
if (!token || !state.activeCredentialId) return;
|
|
@@ -5420,8 +5431,7 @@ function SwypePaymentInner({
|
|
|
5420
5431
|
dispatch({ type: "NAVIGATE", step: "create-passkey" });
|
|
5421
5432
|
return;
|
|
5422
5433
|
}
|
|
5423
|
-
|
|
5424
|
-
dispatch({ type: "PAY_STARTED", isSetupRedirect });
|
|
5434
|
+
dispatch({ type: "PAY_STARTED", isSetupRedirect: false });
|
|
5425
5435
|
processingStartedAtRef.current = Date.now();
|
|
5426
5436
|
try {
|
|
5427
5437
|
if (state.transfer?.status === "AUTHORIZED") {
|
|
@@ -5442,23 +5452,6 @@ function SwypePaymentInner({
|
|
|
5442
5452
|
effectiveSourceId = activeWallet.id;
|
|
5443
5453
|
}
|
|
5444
5454
|
}
|
|
5445
|
-
const isActiveWallet = effectiveSourceType === "walletId" && state.accounts.some(
|
|
5446
|
-
(a) => a.wallets.some((w) => w.id === effectiveSourceId && w.status === "ACTIVE")
|
|
5447
|
-
);
|
|
5448
|
-
if (!isActiveWallet && !isSetupRedirect) {
|
|
5449
|
-
let found = false;
|
|
5450
|
-
for (const acct of state.accounts) {
|
|
5451
|
-
for (const wallet of acct.wallets) {
|
|
5452
|
-
if (wallet.status === "ACTIVE" && wallet.sources.some((s) => s.balance.available.amount >= payAmount)) {
|
|
5453
|
-
effectiveSourceType = "walletId";
|
|
5454
|
-
effectiveSourceId = wallet.id;
|
|
5455
|
-
found = true;
|
|
5456
|
-
break;
|
|
5457
|
-
}
|
|
5458
|
-
}
|
|
5459
|
-
if (found) break;
|
|
5460
|
-
}
|
|
5461
|
-
}
|
|
5462
5455
|
const t = await createTransfer(apiBaseUrl, token, {
|
|
5463
5456
|
id: idempotencyKey,
|
|
5464
5457
|
credentialId: state.activeCredentialId,
|
|
@@ -5469,27 +5462,14 @@ function SwypePaymentInner({
|
|
|
5469
5462
|
amount: payAmount
|
|
5470
5463
|
});
|
|
5471
5464
|
dispatch({ type: "TRANSFER_CREATED", transfer: t });
|
|
5472
|
-
if (t.
|
|
5473
|
-
|
|
5474
|
-
|
|
5475
|
-
|
|
5476
|
-
|
|
5477
|
-
|
|
5478
|
-
|
|
5479
|
-
|
|
5480
|
-
polling.startPolling(t.id);
|
|
5481
|
-
dispatch({ type: "MOBILE_DEEPLINK_READY", deeplinkUri: uri });
|
|
5482
|
-
persistMobileFlowState({
|
|
5483
|
-
transferId: t.id,
|
|
5484
|
-
deeplinkUri: uri,
|
|
5485
|
-
providerId: sourceOverrides?.sourceType === "providerId" ? sourceOverrides.sourceId : state.selectedProviderId,
|
|
5486
|
-
isSetup: mobileSetupFlowRef.current
|
|
5487
|
-
});
|
|
5488
|
-
triggerDeeplink(uri);
|
|
5489
|
-
return;
|
|
5490
|
-
} else {
|
|
5491
|
-
await authExecutor.executeSession(t);
|
|
5492
|
-
}
|
|
5465
|
+
if (t.status === "COMPLETED") {
|
|
5466
|
+
dispatch({ type: "TRANSFER_COMPLETED", transfer: t });
|
|
5467
|
+
onComplete?.(t);
|
|
5468
|
+
return;
|
|
5469
|
+
}
|
|
5470
|
+
if (t.status === "FAILED") {
|
|
5471
|
+
dispatch({ type: "TRANSFER_FAILED", transfer: t, error: "Transfer failed." });
|
|
5472
|
+
return;
|
|
5493
5473
|
}
|
|
5494
5474
|
const signedTransfer = await transferSigning.signTransfer(t.id);
|
|
5495
5475
|
dispatch({ type: "TRANSFER_SIGNED", transfer: signedTransfer });
|
|
@@ -5500,7 +5480,7 @@ function SwypePaymentInner({
|
|
|
5500
5480
|
dispatch({
|
|
5501
5481
|
type: "PAY_ERROR",
|
|
5502
5482
|
error: msg,
|
|
5503
|
-
fallbackStep:
|
|
5483
|
+
fallbackStep: "deposit"
|
|
5504
5484
|
});
|
|
5505
5485
|
onError?.(msg);
|
|
5506
5486
|
} finally {
|
|
@@ -5512,15 +5492,13 @@ function SwypePaymentInner({
|
|
|
5512
5492
|
state.activeCredentialId,
|
|
5513
5493
|
state.transfer,
|
|
5514
5494
|
state.accounts,
|
|
5515
|
-
state.selectedProviderId,
|
|
5516
5495
|
destination,
|
|
5517
5496
|
apiBaseUrl,
|
|
5518
5497
|
getAccessToken,
|
|
5519
|
-
authExecutor,
|
|
5520
5498
|
transferSigning,
|
|
5521
5499
|
polling,
|
|
5522
5500
|
onError,
|
|
5523
|
-
|
|
5501
|
+
onComplete,
|
|
5524
5502
|
idempotencyKey,
|
|
5525
5503
|
merchantAuthorization
|
|
5526
5504
|
]);
|
|
@@ -5551,7 +5529,6 @@ function SwypePaymentInner({
|
|
|
5551
5529
|
}
|
|
5552
5530
|
}
|
|
5553
5531
|
const t = await createTransfer(apiBaseUrl, token, {
|
|
5554
|
-
id: idempotencyKey,
|
|
5555
5532
|
credentialId: state.activeCredentialId,
|
|
5556
5533
|
merchantAuthorization,
|
|
5557
5534
|
sourceType: effectiveSourceType,
|
|
@@ -5559,23 +5536,7 @@ function SwypePaymentInner({
|
|
|
5559
5536
|
destination,
|
|
5560
5537
|
amount: parsedAmount
|
|
5561
5538
|
});
|
|
5562
|
-
|
|
5563
|
-
const uri = t.authorizationSessions[0].uri;
|
|
5564
|
-
pollingTransferIdRef.current = t.id;
|
|
5565
|
-
mobileSetupFlowRef.current = true;
|
|
5566
|
-
handlingMobileReturnRef.current = false;
|
|
5567
|
-
polling.startPolling(t.id);
|
|
5568
|
-
dispatch({ type: "INCREASE_LIMIT_DEEPLINK", transfer: t, deeplinkUri: uri });
|
|
5569
|
-
persistMobileFlowState({
|
|
5570
|
-
transferId: t.id,
|
|
5571
|
-
deeplinkUri: uri,
|
|
5572
|
-
providerId: state.selectedProviderId,
|
|
5573
|
-
isSetup: true
|
|
5574
|
-
});
|
|
5575
|
-
triggerDeeplink(uri);
|
|
5576
|
-
} else {
|
|
5577
|
-
dispatch({ type: "TRANSFER_CREATED", transfer: t });
|
|
5578
|
-
}
|
|
5539
|
+
dispatch({ type: "TRANSFER_CREATED", transfer: t });
|
|
5579
5540
|
} catch (err) {
|
|
5580
5541
|
captureException(err);
|
|
5581
5542
|
const msg = err instanceof Error ? err.message : "Failed to increase limit";
|
|
@@ -5590,12 +5551,10 @@ function SwypePaymentInner({
|
|
|
5590
5551
|
sourceType,
|
|
5591
5552
|
state.activeCredentialId,
|
|
5592
5553
|
state.accounts,
|
|
5593
|
-
state.selectedProviderId,
|
|
5594
5554
|
apiBaseUrl,
|
|
5595
5555
|
getAccessToken,
|
|
5596
5556
|
polling,
|
|
5597
5557
|
onError,
|
|
5598
|
-
idempotencyKey,
|
|
5599
5558
|
merchantAuthorization,
|
|
5600
5559
|
destination
|
|
5601
5560
|
]);
|
|
@@ -5627,31 +5586,78 @@ function SwypePaymentInner({
|
|
|
5627
5586
|
polling.startPolling(transferIdToResume);
|
|
5628
5587
|
}
|
|
5629
5588
|
}, [handleAuthorizedMobileReturn, polling, state.transfer]);
|
|
5630
|
-
const handleSelectProvider = react.useCallback((providerId) => {
|
|
5589
|
+
const handleSelectProvider = react.useCallback(async (providerId) => {
|
|
5631
5590
|
dispatch({ type: "SELECT_PROVIDER", providerId });
|
|
5632
|
-
|
|
5633
|
-
|
|
5634
|
-
|
|
5635
|
-
|
|
5636
|
-
|
|
5637
|
-
|
|
5638
|
-
|
|
5639
|
-
|
|
5640
|
-
|
|
5641
|
-
|
|
5642
|
-
|
|
5591
|
+
if (!state.activeCredentialId) {
|
|
5592
|
+
dispatch({ type: "SET_ERROR", error: "Create a passkey on this device before continuing." });
|
|
5593
|
+
dispatch({ type: "NAVIGATE", step: "create-passkey" });
|
|
5594
|
+
return;
|
|
5595
|
+
}
|
|
5596
|
+
const provider = state.providers.find((p) => p.id === providerId);
|
|
5597
|
+
const providerName = provider?.name ?? "Wallet";
|
|
5598
|
+
dispatch({ type: "PAY_STARTED", isSetupRedirect: true });
|
|
5599
|
+
try {
|
|
5600
|
+
const token = await getAccessToken();
|
|
5601
|
+
if (!token) throw new Error("Not authenticated");
|
|
5602
|
+
const accountId = crypto.randomUUID();
|
|
5603
|
+
const account = await createAccount(apiBaseUrl, token, {
|
|
5604
|
+
id: accountId,
|
|
5605
|
+
name: providerName,
|
|
5606
|
+
credentialId: state.activeCredentialId,
|
|
5607
|
+
providerId
|
|
5608
|
+
});
|
|
5609
|
+
const session = account.authorizationSessions?.[0];
|
|
5610
|
+
if (!session) throw new Error("No authorization session returned.");
|
|
5611
|
+
const isMobile = !shouldUseWalletConnector({
|
|
5612
|
+
useWalletConnector: useWalletConnectorProp,
|
|
5613
|
+
userAgent: typeof navigator === "undefined" ? void 0 : navigator.userAgent
|
|
5614
|
+
});
|
|
5615
|
+
if (isMobile) {
|
|
5616
|
+
handlingMobileReturnRef.current = false;
|
|
5617
|
+
mobileSetupFlowRef.current = true;
|
|
5618
|
+
setupAccountIdRef.current = account.id;
|
|
5619
|
+
persistMobileFlowState({
|
|
5620
|
+
accountId: account.id,
|
|
5621
|
+
sessionId: session.id,
|
|
5622
|
+
deeplinkUri: session.uri,
|
|
5623
|
+
providerId,
|
|
5624
|
+
isSetup: true
|
|
5625
|
+
});
|
|
5626
|
+
dispatch({ type: "MOBILE_DEEPLINK_READY", deeplinkUri: session.uri });
|
|
5627
|
+
triggerDeeplink(session.uri);
|
|
5628
|
+
} else {
|
|
5629
|
+
await authExecutor.executeSessionById(session.id);
|
|
5630
|
+
await reloadAccounts();
|
|
5631
|
+
dispatch({ type: "NAVIGATE", step: "deposit" });
|
|
5632
|
+
}
|
|
5633
|
+
} catch (err) {
|
|
5634
|
+
captureException(err);
|
|
5635
|
+
const msg = err instanceof Error ? err.message : "Failed to set up wallet";
|
|
5636
|
+
dispatch({ type: "PAY_ERROR", error: msg, fallbackStep: "wallet-picker" });
|
|
5637
|
+
onError?.(msg);
|
|
5638
|
+
} finally {
|
|
5639
|
+
dispatch({ type: "PAY_ENDED" });
|
|
5643
5640
|
}
|
|
5644
|
-
}, [
|
|
5641
|
+
}, [
|
|
5642
|
+
state.activeCredentialId,
|
|
5643
|
+
state.providers,
|
|
5644
|
+
apiBaseUrl,
|
|
5645
|
+
getAccessToken,
|
|
5646
|
+
authExecutor,
|
|
5647
|
+
useWalletConnectorProp,
|
|
5648
|
+
reloadAccounts,
|
|
5649
|
+
onError
|
|
5650
|
+
]);
|
|
5645
5651
|
const handleContinueConnection = react.useCallback(
|
|
5646
5652
|
(accountId) => {
|
|
5647
5653
|
const acct = state.accounts.find((a) => a.id === accountId);
|
|
5648
|
-
|
|
5649
|
-
|
|
5650
|
-
|
|
5651
|
-
|
|
5652
|
-
}
|
|
5654
|
+
if (!acct) return;
|
|
5655
|
+
const matchedProvider = state.providers.find((p) => p.name === acct.name);
|
|
5656
|
+
if (matchedProvider) {
|
|
5657
|
+
handleSelectProvider(matchedProvider.id);
|
|
5658
|
+
}
|
|
5653
5659
|
},
|
|
5654
|
-
[state.accounts]
|
|
5660
|
+
[state.accounts, state.providers, handleSelectProvider]
|
|
5655
5661
|
);
|
|
5656
5662
|
const handleNewPayment = react.useCallback(() => {
|
|
5657
5663
|
clearMobileFlowState();
|
|
@@ -5751,7 +5757,7 @@ function SwypePaymentInner({
|
|
|
5751
5757
|
connectingNewAccount: false
|
|
5752
5758
|
});
|
|
5753
5759
|
if (resolved.clearPersistedFlow) clearMobileFlowState();
|
|
5754
|
-
if (resolved.step === "deposit" && persisted && persisted.isSetup) {
|
|
5760
|
+
if (resolved.step === "deposit" && persisted && persisted.isSetup && persisted.transferId) {
|
|
5755
5761
|
try {
|
|
5756
5762
|
const existingTransfer = await fetchTransfer(apiBaseUrl, token, persisted.transferId);
|
|
5757
5763
|
if (cancelled) return;
|
|
@@ -5762,7 +5768,12 @@ function SwypePaymentInner({
|
|
|
5762
5768
|
} catch {
|
|
5763
5769
|
}
|
|
5764
5770
|
}
|
|
5765
|
-
if (resolved.step === "open-wallet" && persisted) {
|
|
5771
|
+
if (resolved.step === "open-wallet" && persisted && persisted.accountId && !persisted.transferId) {
|
|
5772
|
+
clearMobileFlowState();
|
|
5773
|
+
dispatch({ type: "NAVIGATE", step: "deposit" });
|
|
5774
|
+
return;
|
|
5775
|
+
}
|
|
5776
|
+
if (resolved.step === "open-wallet" && persisted && persisted.transferId) {
|
|
5766
5777
|
try {
|
|
5767
5778
|
const existingTransfer = await fetchTransfer(apiBaseUrl, token, persisted.transferId);
|
|
5768
5779
|
if (cancelled) return;
|
|
@@ -5808,9 +5819,9 @@ function SwypePaymentInner({
|
|
|
5808
5819
|
providerId: persisted.providerId,
|
|
5809
5820
|
error: err instanceof Error ? err.message : "Unable to refresh wallet authorization status."
|
|
5810
5821
|
});
|
|
5811
|
-
pollingTransferIdRef.current = persisted.transferId;
|
|
5822
|
+
pollingTransferIdRef.current = persisted.transferId ?? null;
|
|
5812
5823
|
mobileSetupFlowRef.current = persisted.isSetup;
|
|
5813
|
-
pollingRef.current.startPolling(persisted.transferId);
|
|
5824
|
+
if (persisted.transferId) pollingRef.current.startPolling(persisted.transferId);
|
|
5814
5825
|
return;
|
|
5815
5826
|
}
|
|
5816
5827
|
dispatch({
|
|
@@ -5818,9 +5829,9 @@ function SwypePaymentInner({
|
|
|
5818
5829
|
deeplinkUri: persisted.deeplinkUri,
|
|
5819
5830
|
providerId: persisted.providerId
|
|
5820
5831
|
});
|
|
5821
|
-
pollingTransferIdRef.current = persisted.transferId;
|
|
5832
|
+
pollingTransferIdRef.current = persisted.transferId ?? null;
|
|
5822
5833
|
mobileSetupFlowRef.current = persisted.isSetup;
|
|
5823
|
-
pollingRef.current.startPolling(persisted.transferId);
|
|
5834
|
+
if (persisted.transferId) pollingRef.current.startPolling(persisted.transferId);
|
|
5824
5835
|
return;
|
|
5825
5836
|
}
|
|
5826
5837
|
dispatch({ type: "NAVIGATE", step: resolved.step });
|
|
@@ -5927,7 +5938,7 @@ function SwypePaymentInner({
|
|
|
5927
5938
|
accounts: accts,
|
|
5928
5939
|
persistedMobileFlow: persisted,
|
|
5929
5940
|
mobileSetupInProgress: mobileSetupFlowRef.current,
|
|
5930
|
-
connectingNewAccount:
|
|
5941
|
+
connectingNewAccount: false
|
|
5931
5942
|
});
|
|
5932
5943
|
const correctableSteps = ["deposit", "wallet-picker", "open-wallet"];
|
|
5933
5944
|
dispatch({
|
|
@@ -5936,7 +5947,6 @@ function SwypePaymentInner({
|
|
|
5936
5947
|
accounts: accts,
|
|
5937
5948
|
chains: chn,
|
|
5938
5949
|
defaults,
|
|
5939
|
-
fallbackProviderId: !defaults && prov.length > 0 ? prov[0].id : null,
|
|
5940
5950
|
resolvedStep: correctableSteps.includes(state.step) ? resolved.step : void 0,
|
|
5941
5951
|
clearMobileState: resolved.clearPersistedFlow
|
|
5942
5952
|
});
|
|
@@ -5968,8 +5978,7 @@ function SwypePaymentInner({
|
|
|
5968
5978
|
apiBaseUrl,
|
|
5969
5979
|
getAccessToken,
|
|
5970
5980
|
state.activeCredentialId,
|
|
5971
|
-
depositAmount
|
|
5972
|
-
state.connectingNewAccount
|
|
5981
|
+
depositAmount
|
|
5973
5982
|
]);
|
|
5974
5983
|
react.useEffect(() => {
|
|
5975
5984
|
if (!polling.transfer) return;
|
|
@@ -6018,6 +6027,46 @@ function SwypePaymentInner({
|
|
|
6018
6027
|
if (!polledTransfer || polledTransfer.status !== "AUTHORIZED") return;
|
|
6019
6028
|
void handleAuthorizedMobileReturn(polledTransfer, mobileSetupFlowRef.current);
|
|
6020
6029
|
}, [state.mobileFlow, polling.transfer, handleAuthorizedMobileReturn]);
|
|
6030
|
+
react.useEffect(() => {
|
|
6031
|
+
if (!state.mobileFlow || !mobileSetupFlowRef.current) return;
|
|
6032
|
+
if (state.step !== "open-wallet") return;
|
|
6033
|
+
if (!state.activeCredentialId || !setupAccountIdRef.current) return;
|
|
6034
|
+
const accountId = setupAccountIdRef.current;
|
|
6035
|
+
const credentialId = state.activeCredentialId;
|
|
6036
|
+
let cancelled = false;
|
|
6037
|
+
const POLL_INTERVAL_MS = 3e3;
|
|
6038
|
+
const poll = async () => {
|
|
6039
|
+
try {
|
|
6040
|
+
const token = await getAccessTokenRef.current();
|
|
6041
|
+
if (!token || cancelled) return;
|
|
6042
|
+
const acct = await fetchAccount(apiBaseUrl, token, accountId, credentialId);
|
|
6043
|
+
if (cancelled) return;
|
|
6044
|
+
const hasActive = acct.wallets.some((w) => w.status === "ACTIVE");
|
|
6045
|
+
if (hasActive) {
|
|
6046
|
+
cancelled = true;
|
|
6047
|
+
mobileSetupFlowRef.current = false;
|
|
6048
|
+
setupAccountIdRef.current = null;
|
|
6049
|
+
clearMobileFlowState();
|
|
6050
|
+
await reloadAccounts();
|
|
6051
|
+
dispatch({ type: "MOBILE_SETUP_COMPLETE" });
|
|
6052
|
+
}
|
|
6053
|
+
} catch {
|
|
6054
|
+
}
|
|
6055
|
+
};
|
|
6056
|
+
poll();
|
|
6057
|
+
const intervalId = window.setInterval(poll, POLL_INTERVAL_MS);
|
|
6058
|
+
const handleVisibility = () => {
|
|
6059
|
+
if (document.visibilityState === "visible" && !cancelled) {
|
|
6060
|
+
poll();
|
|
6061
|
+
}
|
|
6062
|
+
};
|
|
6063
|
+
document.addEventListener("visibilitychange", handleVisibility);
|
|
6064
|
+
return () => {
|
|
6065
|
+
cancelled = true;
|
|
6066
|
+
window.clearInterval(intervalId);
|
|
6067
|
+
document.removeEventListener("visibilitychange", handleVisibility);
|
|
6068
|
+
};
|
|
6069
|
+
}, [state.mobileFlow, state.step, state.activeCredentialId, apiBaseUrl, reloadAccounts]);
|
|
6021
6070
|
react.useEffect(() => {
|
|
6022
6071
|
if (!state.mobileFlow) return;
|
|
6023
6072
|
if (handlingMobileReturnRef.current) return;
|