@swype-org/react-sdk 0.1.97 → 0.1.100

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 CHANGED
@@ -77,12 +77,14 @@ function getTheme(mode) {
77
77
  }
78
78
  var SWYPE_PRIVY_APP_ID = "cmlil87uv004n0ck0blwumwek";
79
79
  var wagmiConfig = wagmi.createConfig({
80
- chains: [chains.mainnet, chains.arbitrum, chains.base],
80
+ chains: [chains.mainnet, chains.arbitrum, chains.base, chains.polygon, chains.bsc],
81
81
  connectors: [connectors.injected({ shimDisconnect: true, unstable_shimAsyncInject: 2e3 })],
82
82
  transports: {
83
83
  [chains.mainnet.id]: wagmi.http(),
84
84
  [chains.arbitrum.id]: wagmi.http(),
85
- [chains.base.id]: wagmi.http()
85
+ [chains.base.id]: wagmi.http(),
86
+ [chains.polygon.id]: wagmi.http(),
87
+ [chains.bsc.id]: wagmi.http()
86
88
  }
87
89
  });
88
90
  var SwypeContext = react.createContext(null);
@@ -157,6 +159,7 @@ function useSwypeDepositAmount() {
157
159
  // src/api.ts
158
160
  var api_exports = {};
159
161
  __export(api_exports, {
162
+ createAccount: () => createAccount,
160
163
  createTransfer: () => createTransfer,
161
164
  fetchAccounts: () => fetchAccounts,
162
165
  fetchAuthorizationSession: () => fetchAuthorizationSession,
@@ -204,6 +207,18 @@ async function fetchAccounts(apiBaseUrl, token, credentialId) {
204
207
  const data = await res.json();
205
208
  return data.items;
206
209
  }
210
+ async function createAccount(apiBaseUrl, token, params) {
211
+ const res = await fetch(`${apiBaseUrl}/v1/accounts`, {
212
+ method: "POST",
213
+ headers: {
214
+ "Content-Type": "application/json",
215
+ Authorization: `Bearer ${token}`
216
+ },
217
+ body: JSON.stringify(params)
218
+ });
219
+ if (!res.ok) await throwApiError(res);
220
+ return await res.json();
221
+ }
207
222
  async function createTransfer(apiBaseUrl, token, params) {
208
223
  if (!params.merchantAuthorization) {
209
224
  throw new Error("merchantAuthorization is required for transfer creation.");
@@ -1468,15 +1483,6 @@ function useAuthorizationExecutor(options) {
1468
1483
  },
1469
1484
  [apiBaseUrl, dispatchAction]
1470
1485
  );
1471
- const executeSession = react.useCallback(
1472
- async (transfer) => {
1473
- if (!transfer.authorizationSessions?.length) {
1474
- throw new Error("No authorization sessions available.");
1475
- }
1476
- await executeSessionById(transfer.authorizationSessions[0].id);
1477
- },
1478
- [executeSessionById]
1479
- );
1480
1486
  return {
1481
1487
  executing,
1482
1488
  results,
@@ -1484,8 +1490,7 @@ function useAuthorizationExecutor(options) {
1484
1490
  currentAction,
1485
1491
  pendingSelectSource,
1486
1492
  resolveSelectSource,
1487
- executeSessionById,
1488
- executeSession
1493
+ executeSessionById
1489
1494
  };
1490
1495
  }
1491
1496
  function useTransferSigning(pollIntervalMs = 2e3, options) {
@@ -1843,16 +1848,13 @@ function buildSelectSourceChoices(options) {
1843
1848
 
1844
1849
  // src/paymentReducer.ts
1845
1850
  function deriveSourceTypeAndId(state) {
1846
- if (state.connectingNewAccount) {
1847
- return { sourceType: "providerId", sourceId: state.selectedProviderId ?? "" };
1848
- }
1849
1851
  if (state.selectedWalletId) {
1850
1852
  return { sourceType: "walletId", sourceId: state.selectedWalletId };
1851
1853
  }
1852
1854
  if (state.selectedAccountId) {
1853
1855
  return { sourceType: "accountId", sourceId: state.selectedAccountId };
1854
1856
  }
1855
- return { sourceType: "providerId", sourceId: state.selectedProviderId ?? "" };
1857
+ return { sourceType: "accountId", sourceId: "" };
1856
1858
  }
1857
1859
  function createInitialState(config) {
1858
1860
  return {
@@ -1864,8 +1866,6 @@ function createInitialState(config) {
1864
1866
  loadingData: false,
1865
1867
  selectedAccountId: null,
1866
1868
  selectedWalletId: null,
1867
- selectedProviderId: null,
1868
- connectingNewAccount: false,
1869
1869
  amount: config.depositAmount != null ? config.depositAmount.toString() : "",
1870
1870
  transfer: null,
1871
1871
  creatingTransfer: false,
@@ -1930,8 +1930,6 @@ function paymentReducer(state, action) {
1930
1930
  if (action.defaults) {
1931
1931
  next.selectedAccountId = action.defaults.accountId;
1932
1932
  next.selectedWalletId = action.defaults.walletId;
1933
- } else if (action.fallbackProviderId && !state.connectingNewAccount) {
1934
- next.selectedProviderId = action.fallbackProviderId;
1935
1933
  }
1936
1934
  if (action.clearMobileState) {
1937
1935
  next.mobileFlow = false;
@@ -1953,7 +1951,6 @@ function paymentReducer(state, action) {
1953
1951
  if (action.defaults) {
1954
1952
  next.selectedAccountId = action.defaults.accountId;
1955
1953
  next.selectedWalletId = action.defaults.walletId;
1956
- next.connectingNewAccount = false;
1957
1954
  }
1958
1955
  return next;
1959
1956
  }
@@ -1961,16 +1958,13 @@ function paymentReducer(state, action) {
1961
1958
  case "SELECT_PROVIDER":
1962
1959
  return {
1963
1960
  ...state,
1964
- selectedProviderId: action.providerId,
1965
- selectedAccountId: null,
1966
- connectingNewAccount: true
1961
+ selectedAccountId: null
1967
1962
  };
1968
1963
  case "SELECT_ACCOUNT":
1969
1964
  return {
1970
1965
  ...state,
1971
1966
  selectedAccountId: action.accountId,
1972
1967
  selectedWalletId: action.walletId,
1973
- connectingNewAccount: false,
1974
1968
  step: "deposit"
1975
1969
  };
1976
1970
  // ── Transfer lifecycle ───────────────────────────────────────
@@ -2055,7 +2049,6 @@ function paymentReducer(state, action) {
2055
2049
  ...state,
2056
2050
  mobileFlow: true,
2057
2051
  deeplinkUri: action.deeplinkUri,
2058
- selectedProviderId: action.providerId,
2059
2052
  error: action.error ?? null,
2060
2053
  step: "open-wallet"
2061
2054
  };
@@ -2111,7 +2104,6 @@ function paymentReducer(state, action) {
2111
2104
  amount: action.depositAmount != null ? action.depositAmount.toString() : "",
2112
2105
  mobileFlow: false,
2113
2106
  deeplinkUri: null,
2114
- connectingNewAccount: false,
2115
2107
  selectedWalletId: null,
2116
2108
  selectedAccountId: action.firstAccountId
2117
2109
  };
@@ -5261,11 +5253,11 @@ function SwypePaymentInner({
5261
5253
  accounts: state.accounts,
5262
5254
  persistedMobileFlow: loadMobileFlowState(),
5263
5255
  mobileSetupInProgress: mobileSetupFlowRef.current,
5264
- connectingNewAccount: state.connectingNewAccount
5256
+ connectingNewAccount: false
5265
5257
  });
5266
5258
  if (resolved.clearPersistedFlow) clearMobileFlowState();
5267
5259
  dispatch({ type: "NAVIGATE", step: resolved.step });
5268
- }, [getAccessToken, apiBaseUrl, state.accounts, state.connectingNewAccount]);
5260
+ }, [getAccessToken, apiBaseUrl, state.accounts]);
5269
5261
  const handleRegisterPasskey = react.useCallback(async () => {
5270
5262
  dispatch({ type: "SET_REGISTERING_PASSKEY", value: true });
5271
5263
  dispatch({ type: "SET_ERROR", error: null });
@@ -5310,7 +5302,7 @@ function SwypePaymentInner({
5310
5302
  accounts: state.accounts,
5311
5303
  persistedMobileFlow: loadMobileFlowState(),
5312
5304
  mobileSetupInProgress: mobileSetupFlowRef.current,
5313
- connectingNewAccount: state.connectingNewAccount
5305
+ connectingNewAccount: false
5314
5306
  });
5315
5307
  if (resolved.clearPersistedFlow) clearMobileFlowState();
5316
5308
  dispatch({ type: "NAVIGATE", step: resolved.step });
@@ -5323,7 +5315,7 @@ function SwypePaymentInner({
5323
5315
  } finally {
5324
5316
  dispatch({ type: "SET_REGISTERING_PASSKEY", value: false });
5325
5317
  }
5326
- }, [user, getAccessToken, apiBaseUrl, state.accounts, state.connectingNewAccount]);
5318
+ }, [user, getAccessToken, apiBaseUrl, state.accounts]);
5327
5319
  const handleVerifyPasskeyViaPopup = react.useCallback(async () => {
5328
5320
  dispatch({ type: "SET_VERIFYING_PASSKEY", value: true });
5329
5321
  dispatch({ type: "SET_ERROR", error: null });
@@ -5347,7 +5339,7 @@ function SwypePaymentInner({
5347
5339
  accounts: state.accounts,
5348
5340
  persistedMobileFlow: loadMobileFlowState(),
5349
5341
  mobileSetupInProgress: mobileSetupFlowRef.current,
5350
- connectingNewAccount: state.connectingNewAccount
5342
+ connectingNewAccount: false
5351
5343
  });
5352
5344
  if (resolved.clearPersistedFlow) clearMobileFlowState();
5353
5345
  dispatch({ type: "NAVIGATE", step: resolved.step });
@@ -5366,7 +5358,7 @@ function SwypePaymentInner({
5366
5358
  } finally {
5367
5359
  dispatch({ type: "SET_VERIFYING_PASSKEY", value: false });
5368
5360
  }
5369
- }, [state.knownCredentialIds, getAccessToken, apiBaseUrl, state.accounts, state.connectingNewAccount]);
5361
+ }, [state.knownCredentialIds, getAccessToken, apiBaseUrl, state.accounts]);
5370
5362
  const reloadAccounts = react.useCallback(async () => {
5371
5363
  const token = await getAccessToken();
5372
5364
  if (!token || !state.activeCredentialId) return;
@@ -5418,8 +5410,7 @@ function SwypePaymentInner({
5418
5410
  dispatch({ type: "NAVIGATE", step: "create-passkey" });
5419
5411
  return;
5420
5412
  }
5421
- const isSetupRedirect = mobileSetupFlowRef.current;
5422
- dispatch({ type: "PAY_STARTED", isSetupRedirect });
5413
+ dispatch({ type: "PAY_STARTED", isSetupRedirect: false });
5423
5414
  processingStartedAtRef.current = Date.now();
5424
5415
  try {
5425
5416
  if (state.transfer?.status === "AUTHORIZED") {
@@ -5440,23 +5431,6 @@ function SwypePaymentInner({
5440
5431
  effectiveSourceId = activeWallet.id;
5441
5432
  }
5442
5433
  }
5443
- const isActiveWallet = effectiveSourceType === "walletId" && state.accounts.some(
5444
- (a) => a.wallets.some((w) => w.id === effectiveSourceId && w.status === "ACTIVE")
5445
- );
5446
- if (!isActiveWallet && !isSetupRedirect) {
5447
- let found = false;
5448
- for (const acct of state.accounts) {
5449
- for (const wallet of acct.wallets) {
5450
- if (wallet.status === "ACTIVE" && wallet.sources.some((s) => s.balance.available.amount >= payAmount)) {
5451
- effectiveSourceType = "walletId";
5452
- effectiveSourceId = wallet.id;
5453
- found = true;
5454
- break;
5455
- }
5456
- }
5457
- if (found) break;
5458
- }
5459
- }
5460
5434
  const t = await createTransfer(apiBaseUrl, token, {
5461
5435
  id: idempotencyKey,
5462
5436
  credentialId: state.activeCredentialId,
@@ -5467,28 +5441,6 @@ function SwypePaymentInner({
5467
5441
  amount: payAmount
5468
5442
  });
5469
5443
  dispatch({ type: "TRANSFER_CREATED", transfer: t });
5470
- if (t.authorizationSessions && t.authorizationSessions.length > 0) {
5471
- const useConnector = shouldUseWalletConnector({
5472
- useWalletConnector: useWalletConnectorProp,
5473
- userAgent: typeof navigator === "undefined" ? void 0 : navigator.userAgent
5474
- });
5475
- if (!useConnector) {
5476
- const uri = t.authorizationSessions[0].uri;
5477
- pollingTransferIdRef.current = t.id;
5478
- polling.startPolling(t.id);
5479
- dispatch({ type: "MOBILE_DEEPLINK_READY", deeplinkUri: uri });
5480
- persistMobileFlowState({
5481
- transferId: t.id,
5482
- deeplinkUri: uri,
5483
- providerId: sourceOverrides?.sourceType === "providerId" ? sourceOverrides.sourceId : state.selectedProviderId,
5484
- isSetup: mobileSetupFlowRef.current
5485
- });
5486
- triggerDeeplink(uri);
5487
- return;
5488
- } else {
5489
- await authExecutor.executeSession(t);
5490
- }
5491
- }
5492
5444
  const signedTransfer = await transferSigning.signTransfer(t.id);
5493
5445
  dispatch({ type: "TRANSFER_SIGNED", transfer: signedTransfer });
5494
5446
  polling.startPolling(t.id);
@@ -5498,7 +5450,7 @@ function SwypePaymentInner({
5498
5450
  dispatch({
5499
5451
  type: "PAY_ERROR",
5500
5452
  error: msg,
5501
- fallbackStep: isSetupRedirect ? "wallet-picker" : "deposit"
5453
+ fallbackStep: "deposit"
5502
5454
  });
5503
5455
  onError?.(msg);
5504
5456
  } finally {
@@ -5510,15 +5462,12 @@ function SwypePaymentInner({
5510
5462
  state.activeCredentialId,
5511
5463
  state.transfer,
5512
5464
  state.accounts,
5513
- state.selectedProviderId,
5514
5465
  destination,
5515
5466
  apiBaseUrl,
5516
5467
  getAccessToken,
5517
- authExecutor,
5518
5468
  transferSigning,
5519
5469
  polling,
5520
5470
  onError,
5521
- useWalletConnectorProp,
5522
5471
  idempotencyKey,
5523
5472
  merchantAuthorization
5524
5473
  ]);
@@ -5557,23 +5506,7 @@ function SwypePaymentInner({
5557
5506
  destination,
5558
5507
  amount: parsedAmount
5559
5508
  });
5560
- if (t.authorizationSessions && t.authorizationSessions.length > 0) {
5561
- const uri = t.authorizationSessions[0].uri;
5562
- pollingTransferIdRef.current = t.id;
5563
- mobileSetupFlowRef.current = true;
5564
- handlingMobileReturnRef.current = false;
5565
- polling.startPolling(t.id);
5566
- dispatch({ type: "INCREASE_LIMIT_DEEPLINK", transfer: t, deeplinkUri: uri });
5567
- persistMobileFlowState({
5568
- transferId: t.id,
5569
- deeplinkUri: uri,
5570
- providerId: state.selectedProviderId,
5571
- isSetup: true
5572
- });
5573
- triggerDeeplink(uri);
5574
- } else {
5575
- dispatch({ type: "TRANSFER_CREATED", transfer: t });
5576
- }
5509
+ dispatch({ type: "TRANSFER_CREATED", transfer: t });
5577
5510
  } catch (err) {
5578
5511
  captureException(err);
5579
5512
  const msg = err instanceof Error ? err.message : "Failed to increase limit";
@@ -5588,7 +5521,6 @@ function SwypePaymentInner({
5588
5521
  sourceType,
5589
5522
  state.activeCredentialId,
5590
5523
  state.accounts,
5591
- state.selectedProviderId,
5592
5524
  apiBaseUrl,
5593
5525
  getAccessToken,
5594
5526
  polling,
@@ -5625,21 +5557,65 @@ function SwypePaymentInner({
5625
5557
  polling.startPolling(transferIdToResume);
5626
5558
  }
5627
5559
  }, [handleAuthorizedMobileReturn, polling, state.transfer]);
5628
- const handleSelectProvider = react.useCallback((providerId) => {
5560
+ const handleSelectProvider = react.useCallback(async (providerId) => {
5629
5561
  dispatch({ type: "SELECT_PROVIDER", providerId });
5630
- const isMobile = !shouldUseWalletConnector({
5631
- useWalletConnector: useWalletConnectorProp,
5632
- userAgent: typeof navigator === "undefined" ? void 0 : navigator.userAgent
5633
- });
5634
- if (isMobile) {
5635
- handlingMobileReturnRef.current = false;
5636
- mobileSetupFlowRef.current = true;
5637
- const amount = depositAmount ?? 5;
5638
- handlePay(amount, { sourceType: "providerId", sourceId: providerId });
5639
- } else {
5640
- dispatch({ type: "NAVIGATE", step: "deposit" });
5562
+ if (!state.activeCredentialId) {
5563
+ dispatch({ type: "SET_ERROR", error: "Create a passkey on this device before continuing." });
5564
+ dispatch({ type: "NAVIGATE", step: "create-passkey" });
5565
+ return;
5566
+ }
5567
+ const provider = state.providers.find((p) => p.id === providerId);
5568
+ const providerName = provider?.name ?? "Wallet";
5569
+ dispatch({ type: "PAY_STARTED", isSetupRedirect: true });
5570
+ try {
5571
+ const token = await getAccessToken();
5572
+ if (!token) throw new Error("Not authenticated");
5573
+ const account = await createAccount(apiBaseUrl, token, {
5574
+ name: providerName,
5575
+ credentialId: state.activeCredentialId,
5576
+ providerId
5577
+ });
5578
+ const session = account.authorizationSessions?.[0];
5579
+ if (!session) throw new Error("No authorization session returned.");
5580
+ const isMobile = !shouldUseWalletConnector({
5581
+ useWalletConnector: useWalletConnectorProp,
5582
+ userAgent: typeof navigator === "undefined" ? void 0 : navigator.userAgent
5583
+ });
5584
+ if (isMobile) {
5585
+ handlingMobileReturnRef.current = false;
5586
+ mobileSetupFlowRef.current = true;
5587
+ persistMobileFlowState({
5588
+ accountId: account.id,
5589
+ sessionId: session.id,
5590
+ deeplinkUri: session.uri,
5591
+ providerId,
5592
+ isSetup: true
5593
+ });
5594
+ dispatch({ type: "MOBILE_DEEPLINK_READY", deeplinkUri: session.uri });
5595
+ triggerDeeplink(session.uri);
5596
+ } else {
5597
+ await authExecutor.executeSessionById(session.id);
5598
+ await reloadAccounts();
5599
+ dispatch({ type: "NAVIGATE", step: "deposit" });
5600
+ }
5601
+ } catch (err) {
5602
+ captureException(err);
5603
+ const msg = err instanceof Error ? err.message : "Failed to set up wallet";
5604
+ dispatch({ type: "PAY_ERROR", error: msg, fallbackStep: "wallet-picker" });
5605
+ onError?.(msg);
5606
+ } finally {
5607
+ dispatch({ type: "PAY_ENDED" });
5641
5608
  }
5642
- }, [useWalletConnectorProp, depositAmount, handlePay]);
5609
+ }, [
5610
+ state.activeCredentialId,
5611
+ state.providers,
5612
+ apiBaseUrl,
5613
+ getAccessToken,
5614
+ authExecutor,
5615
+ useWalletConnectorProp,
5616
+ reloadAccounts,
5617
+ onError
5618
+ ]);
5643
5619
  const handleContinueConnection = react.useCallback(
5644
5620
  (accountId) => {
5645
5621
  const acct = state.accounts.find((a) => a.id === accountId);
@@ -5749,7 +5725,7 @@ function SwypePaymentInner({
5749
5725
  connectingNewAccount: false
5750
5726
  });
5751
5727
  if (resolved.clearPersistedFlow) clearMobileFlowState();
5752
- if (resolved.step === "deposit" && persisted && persisted.isSetup) {
5728
+ if (resolved.step === "deposit" && persisted && persisted.isSetup && persisted.transferId) {
5753
5729
  try {
5754
5730
  const existingTransfer = await fetchTransfer(apiBaseUrl, token, persisted.transferId);
5755
5731
  if (cancelled) return;
@@ -5760,7 +5736,12 @@ function SwypePaymentInner({
5760
5736
  } catch {
5761
5737
  }
5762
5738
  }
5763
- if (resolved.step === "open-wallet" && persisted) {
5739
+ if (resolved.step === "open-wallet" && persisted && persisted.accountId && !persisted.transferId) {
5740
+ clearMobileFlowState();
5741
+ dispatch({ type: "NAVIGATE", step: "deposit" });
5742
+ return;
5743
+ }
5744
+ if (resolved.step === "open-wallet" && persisted && persisted.transferId) {
5764
5745
  try {
5765
5746
  const existingTransfer = await fetchTransfer(apiBaseUrl, token, persisted.transferId);
5766
5747
  if (cancelled) return;
@@ -5806,9 +5787,9 @@ function SwypePaymentInner({
5806
5787
  providerId: persisted.providerId,
5807
5788
  error: err instanceof Error ? err.message : "Unable to refresh wallet authorization status."
5808
5789
  });
5809
- pollingTransferIdRef.current = persisted.transferId;
5790
+ pollingTransferIdRef.current = persisted.transferId ?? null;
5810
5791
  mobileSetupFlowRef.current = persisted.isSetup;
5811
- pollingRef.current.startPolling(persisted.transferId);
5792
+ if (persisted.transferId) pollingRef.current.startPolling(persisted.transferId);
5812
5793
  return;
5813
5794
  }
5814
5795
  dispatch({
@@ -5816,9 +5797,9 @@ function SwypePaymentInner({
5816
5797
  deeplinkUri: persisted.deeplinkUri,
5817
5798
  providerId: persisted.providerId
5818
5799
  });
5819
- pollingTransferIdRef.current = persisted.transferId;
5800
+ pollingTransferIdRef.current = persisted.transferId ?? null;
5820
5801
  mobileSetupFlowRef.current = persisted.isSetup;
5821
- pollingRef.current.startPolling(persisted.transferId);
5802
+ if (persisted.transferId) pollingRef.current.startPolling(persisted.transferId);
5822
5803
  return;
5823
5804
  }
5824
5805
  dispatch({ type: "NAVIGATE", step: resolved.step });
@@ -5925,7 +5906,7 @@ function SwypePaymentInner({
5925
5906
  accounts: accts,
5926
5907
  persistedMobileFlow: persisted,
5927
5908
  mobileSetupInProgress: mobileSetupFlowRef.current,
5928
- connectingNewAccount: state.connectingNewAccount
5909
+ connectingNewAccount: false
5929
5910
  });
5930
5911
  const correctableSteps = ["deposit", "wallet-picker", "open-wallet"];
5931
5912
  dispatch({
@@ -5934,7 +5915,6 @@ function SwypePaymentInner({
5934
5915
  accounts: accts,
5935
5916
  chains: chn,
5936
5917
  defaults,
5937
- fallbackProviderId: !defaults && prov.length > 0 ? prov[0].id : null,
5938
5918
  resolvedStep: correctableSteps.includes(state.step) ? resolved.step : void 0,
5939
5919
  clearMobileState: resolved.clearPersistedFlow
5940
5920
  });
@@ -5966,8 +5946,7 @@ function SwypePaymentInner({
5966
5946
  apiBaseUrl,
5967
5947
  getAccessToken,
5968
5948
  state.activeCredentialId,
5969
- depositAmount,
5970
- state.connectingNewAccount
5949
+ depositAmount
5971
5950
  ]);
5972
5951
  react.useEffect(() => {
5973
5952
  if (!polling.transfer) return;