@swype-org/react-sdk 0.1.100 → 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 CHANGED
@@ -161,6 +161,7 @@ var api_exports = {};
161
161
  __export(api_exports, {
162
162
  createAccount: () => createAccount,
163
163
  createTransfer: () => createTransfer,
164
+ fetchAccount: () => fetchAccount,
164
165
  fetchAccounts: () => fetchAccounts,
165
166
  fetchAuthorizationSession: () => fetchAuthorizationSession,
166
167
  fetchChains: () => fetchChains,
@@ -207,14 +208,28 @@ async function fetchAccounts(apiBaseUrl, token, credentialId) {
207
208
  const data = await res.json();
208
209
  return data.items;
209
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
+ }
210
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
+ };
211
226
  const res = await fetch(`${apiBaseUrl}/v1/accounts`, {
212
227
  method: "POST",
213
228
  headers: {
214
229
  "Content-Type": "application/json",
215
230
  Authorization: `Bearer ${token}`
216
231
  },
217
- body: JSON.stringify(params)
232
+ body: JSON.stringify(body)
218
233
  });
219
234
  if (!res.ok) await throwApiError(res);
220
235
  return await res.json();
@@ -1864,6 +1879,7 @@ 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
1885
  amount: config.depositAmount != null ? config.depositAmount.toString() : "",
@@ -1958,7 +1974,9 @@ function paymentReducer(state, action) {
1958
1974
  case "SELECT_PROVIDER":
1959
1975
  return {
1960
1976
  ...state,
1961
- selectedAccountId: null
1977
+ selectedProviderId: action.providerId,
1978
+ selectedAccountId: null,
1979
+ selectedWalletId: null
1962
1980
  };
1963
1981
  case "SELECT_ACCOUNT":
1964
1982
  return {
@@ -2027,7 +2045,7 @@ function paymentReducer(state, action) {
2027
2045
  case "MOBILE_SETUP_COMPLETE":
2028
2046
  return {
2029
2047
  ...state,
2030
- transfer: action.transfer,
2048
+ transfer: action.transfer ?? state.transfer,
2031
2049
  error: null,
2032
2050
  mobileFlow: false,
2033
2051
  deeplinkUri: null,
@@ -2049,6 +2067,7 @@ function paymentReducer(state, action) {
2049
2067
  ...state,
2050
2068
  mobileFlow: true,
2051
2069
  deeplinkUri: action.deeplinkUri,
2070
+ selectedProviderId: action.providerId ?? state.selectedProviderId,
2052
2071
  error: action.error ?? null,
2053
2072
  step: "open-wallet"
2054
2073
  };
@@ -2104,6 +2123,7 @@ function paymentReducer(state, action) {
2104
2123
  amount: action.depositAmount != null ? action.depositAmount.toString() : "",
2105
2124
  mobileFlow: false,
2106
2125
  deeplinkUri: null,
2126
+ selectedProviderId: null,
2107
2127
  selectedWalletId: null,
2108
2128
  selectedAccountId: action.firstAccountId
2109
2129
  };
@@ -5121,6 +5141,7 @@ function SwypePaymentInner({
5121
5141
  );
5122
5142
  const loadingDataRef = react.useRef(false);
5123
5143
  const pollingTransferIdRef = react.useRef(null);
5144
+ const setupAccountIdRef = react.useRef(null);
5124
5145
  const mobileSetupFlowRef = react.useRef(false);
5125
5146
  const handlingMobileReturnRef = react.useRef(false);
5126
5147
  const processingStartedAtRef = react.useRef(null);
@@ -5441,6 +5462,15 @@ function SwypePaymentInner({
5441
5462
  amount: payAmount
5442
5463
  });
5443
5464
  dispatch({ type: "TRANSFER_CREATED", transfer: t });
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;
5473
+ }
5444
5474
  const signedTransfer = await transferSigning.signTransfer(t.id);
5445
5475
  dispatch({ type: "TRANSFER_SIGNED", transfer: signedTransfer });
5446
5476
  polling.startPolling(t.id);
@@ -5468,6 +5498,7 @@ function SwypePaymentInner({
5468
5498
  transferSigning,
5469
5499
  polling,
5470
5500
  onError,
5501
+ onComplete,
5471
5502
  idempotencyKey,
5472
5503
  merchantAuthorization
5473
5504
  ]);
@@ -5498,7 +5529,6 @@ function SwypePaymentInner({
5498
5529
  }
5499
5530
  }
5500
5531
  const t = await createTransfer(apiBaseUrl, token, {
5501
- id: idempotencyKey,
5502
5532
  credentialId: state.activeCredentialId,
5503
5533
  merchantAuthorization,
5504
5534
  sourceType: effectiveSourceType,
@@ -5525,7 +5555,6 @@ function SwypePaymentInner({
5525
5555
  getAccessToken,
5526
5556
  polling,
5527
5557
  onError,
5528
- idempotencyKey,
5529
5558
  merchantAuthorization,
5530
5559
  destination
5531
5560
  ]);
@@ -5570,7 +5599,9 @@ function SwypePaymentInner({
5570
5599
  try {
5571
5600
  const token = await getAccessToken();
5572
5601
  if (!token) throw new Error("Not authenticated");
5602
+ const accountId = crypto.randomUUID();
5573
5603
  const account = await createAccount(apiBaseUrl, token, {
5604
+ id: accountId,
5574
5605
  name: providerName,
5575
5606
  credentialId: state.activeCredentialId,
5576
5607
  providerId
@@ -5584,6 +5615,7 @@ function SwypePaymentInner({
5584
5615
  if (isMobile) {
5585
5616
  handlingMobileReturnRef.current = false;
5586
5617
  mobileSetupFlowRef.current = true;
5618
+ setupAccountIdRef.current = account.id;
5587
5619
  persistMobileFlowState({
5588
5620
  accountId: account.id,
5589
5621
  sessionId: session.id,
@@ -5619,13 +5651,13 @@ function SwypePaymentInner({
5619
5651
  const handleContinueConnection = react.useCallback(
5620
5652
  (accountId) => {
5621
5653
  const acct = state.accounts.find((a) => a.id === accountId);
5622
- dispatch({
5623
- type: "SELECT_ACCOUNT",
5624
- accountId,
5625
- walletId: acct?.wallets[0]?.id ?? null
5626
- });
5654
+ if (!acct) return;
5655
+ const matchedProvider = state.providers.find((p) => p.name === acct.name);
5656
+ if (matchedProvider) {
5657
+ handleSelectProvider(matchedProvider.id);
5658
+ }
5627
5659
  },
5628
- [state.accounts]
5660
+ [state.accounts, state.providers, handleSelectProvider]
5629
5661
  );
5630
5662
  const handleNewPayment = react.useCallback(() => {
5631
5663
  clearMobileFlowState();
@@ -5995,6 +6027,46 @@ function SwypePaymentInner({
5995
6027
  if (!polledTransfer || polledTransfer.status !== "AUTHORIZED") return;
5996
6028
  void handleAuthorizedMobileReturn(polledTransfer, mobileSetupFlowRef.current);
5997
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]);
5998
6070
  react.useEffect(() => {
5999
6071
  if (!state.mobileFlow) return;
6000
6072
  if (handlingMobileReturnRef.current) return;