@swype-org/react-sdk 0.1.69 → 0.1.70

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
@@ -1618,6 +1618,9 @@ function resolvePostAuthStep(state) {
1618
1618
  }
1619
1619
  return { step: "open-wallet", clearPersistedFlow: false };
1620
1620
  }
1621
+ if (state.mobileSetupInProgress && !hasActiveWallet(state.accounts)) {
1622
+ return { step: "open-wallet", clearPersistedFlow: false };
1623
+ }
1621
1624
  if ((state.accounts.length === 0 || !hasActiveWallet(state.accounts)) && !state.connectingNewAccount) {
1622
1625
  return { step: "wallet-picker", clearPersistedFlow: false };
1623
1626
  }
@@ -1633,6 +1636,9 @@ function resolveRestoredMobileFlow(transferStatus, isSetup) {
1633
1636
  if (transferStatus === "FAILED") {
1634
1637
  return { kind: "resume-failed", step: "success", clearPersistedFlow: true };
1635
1638
  }
1639
+ if (transferStatus === "SENDING" || transferStatus === "SENT") {
1640
+ return { kind: "resume-processing", step: "processing", clearPersistedFlow: true };
1641
+ }
1636
1642
  if (isSetup) {
1637
1643
  return { kind: "resume-stale-setup", step: "wallet-picker", clearPersistedFlow: true };
1638
1644
  }
@@ -3424,6 +3430,8 @@ var outlineBtnWrapStyle = {
3424
3430
  function SuccessScreen({
3425
3431
  amount,
3426
3432
  currency,
3433
+ succeeded,
3434
+ error,
3427
3435
  merchantName,
3428
3436
  sourceName,
3429
3437
  remainingLimit,
@@ -3434,7 +3442,8 @@ function SuccessScreen({
3434
3442
  autoCloseSeconds
3435
3443
  }) {
3436
3444
  const { tokens } = useSwypeConfig();
3437
- const [countdown, setCountdown] = react.useState(autoCloseSeconds ?? 0);
3445
+ const effectiveAutoClose = succeeded ? autoCloseSeconds : void 0;
3446
+ const [countdown, setCountdown] = react.useState(effectiveAutoClose ?? 0);
3438
3447
  const doneCalledRef = react.useRef(false);
3439
3448
  const handleDone = react.useCallback(() => {
3440
3449
  if (doneCalledRef.current) return;
@@ -3442,7 +3451,7 @@ function SuccessScreen({
3442
3451
  onDone();
3443
3452
  }, [onDone]);
3444
3453
  react.useEffect(() => {
3445
- if (!autoCloseSeconds || autoCloseSeconds <= 0) return;
3454
+ if (!effectiveAutoClose || effectiveAutoClose <= 0) return;
3446
3455
  const intervalId = window.setInterval(() => {
3447
3456
  setCountdown((prev) => {
3448
3457
  if (prev <= 1) {
@@ -3453,18 +3462,18 @@ function SuccessScreen({
3453
3462
  });
3454
3463
  }, 1e3);
3455
3464
  return () => window.clearInterval(intervalId);
3456
- }, [autoCloseSeconds]);
3465
+ }, [effectiveAutoClose]);
3457
3466
  react.useEffect(() => {
3458
- if (autoCloseSeconds && countdown === 0) {
3467
+ if (effectiveAutoClose && countdown === 0) {
3459
3468
  handleDone();
3460
3469
  }
3461
- }, [autoCloseSeconds, countdown, handleDone]);
3470
+ }, [effectiveAutoClose, countdown, handleDone]);
3462
3471
  return /* @__PURE__ */ jsxRuntime.jsxs(
3463
3472
  ScreenLayout,
3464
3473
  {
3465
3474
  footer: /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3466
- /* @__PURE__ */ jsxRuntime.jsx(PrimaryButton, { onClick: handleDone, children: "Done" }),
3467
- autoCloseSeconds != null && autoCloseSeconds > 0 && /* @__PURE__ */ jsxRuntime.jsxs("p", { style: countdownStyle(tokens.textMuted), children: [
3475
+ /* @__PURE__ */ jsxRuntime.jsx(PrimaryButton, { onClick: handleDone, children: succeeded ? "Done" : "Try again" }),
3476
+ effectiveAutoClose != null && effectiveAutoClose > 0 && /* @__PURE__ */ jsxRuntime.jsxs("p", { style: countdownStyle(tokens.textMuted), children: [
3468
3477
  "Returning to app in ",
3469
3478
  countdown,
3470
3479
  "s\u2026"
@@ -3480,26 +3489,32 @@ function SuccessScreen({
3480
3489
  }
3481
3490
  ),
3482
3491
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: contentStyle4, children: [
3483
- /* @__PURE__ */ jsxRuntime.jsx(IconCircle, { variant: "success", size: 64, children: /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "32", height: "32", viewBox: "0 0 24 24", fill: "none", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41L9 16.17z", fill: tokens.success }) }) }),
3484
- /* @__PURE__ */ jsxRuntime.jsxs("h2", { style: headingStyle6(tokens.text), children: [
3485
- "$",
3486
- amount.toFixed(2),
3487
- " deposited"
3488
- ] }),
3489
- merchantName && /* @__PURE__ */ jsxRuntime.jsxs("p", { style: subtitleStyle6(tokens.textSecondary), children: [
3490
- "to ",
3491
- merchantName
3492
+ succeeded ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3493
+ /* @__PURE__ */ jsxRuntime.jsx(IconCircle, { variant: "success", size: 64, children: /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "32", height: "32", viewBox: "0 0 24 24", fill: "none", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41L9 16.17z", fill: tokens.success }) }) }),
3494
+ /* @__PURE__ */ jsxRuntime.jsxs("h2", { style: headingStyle6(tokens.text), children: [
3495
+ "$",
3496
+ amount.toFixed(2),
3497
+ " deposited"
3498
+ ] }),
3499
+ merchantName && /* @__PURE__ */ jsxRuntime.jsxs("p", { style: subtitleStyle6(tokens.textSecondary), children: [
3500
+ "to ",
3501
+ merchantName
3502
+ ] })
3503
+ ] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3504
+ /* @__PURE__ */ jsxRuntime.jsx(IconCircle, { variant: "error", size: 64, children: /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "32", height: "32", viewBox: "0 0 24 24", fill: "none", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-2h2v2zm0-4h-2V7h2v6z", fill: tokens.error }) }) }),
3505
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { style: headingStyle6(tokens.text), children: "Transfer failed" }),
3506
+ error && /* @__PURE__ */ jsxRuntime.jsx("p", { style: subtitleStyle6(tokens.error), children: error })
3492
3507
  ] }),
3493
3508
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: summaryCardStyle(tokens), children: [
3494
3509
  sourceName && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: summaryRowStyle, children: [
3495
3510
  /* @__PURE__ */ jsxRuntime.jsx("span", { style: summaryLabelStyle(tokens.textMuted), children: "From" }),
3496
3511
  /* @__PURE__ */ jsxRuntime.jsx("span", { style: summaryValueStyle(tokens.text), children: sourceName })
3497
3512
  ] }),
3498
- /* @__PURE__ */ jsxRuntime.jsxs("div", { style: summaryRowStyle, children: [
3513
+ succeeded && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: summaryRowStyle, children: [
3499
3514
  /* @__PURE__ */ jsxRuntime.jsx("span", { style: summaryLabelStyle(tokens.textMuted), children: "Time" }),
3500
3515
  /* @__PURE__ */ jsxRuntime.jsx("span", { style: summaryValueStyle(tokens.text), children: "just now" })
3501
3516
  ] }),
3502
- remainingLimit != null && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: summaryRowStyle, children: [
3517
+ succeeded && remainingLimit != null && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: summaryRowStyle, children: [
3503
3518
  /* @__PURE__ */ jsxRuntime.jsx("span", { style: summaryLabelStyle(tokens.textMuted), children: "Remaining limit" }),
3504
3519
  /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { ...summaryValueStyle(tokens.text), color: tokens.accent }, children: [
3505
3520
  "$",
@@ -3507,7 +3522,7 @@ function SuccessScreen({
3507
3522
  ] })
3508
3523
  ] })
3509
3524
  ] }),
3510
- onIncreaseLimits && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: upsellCardStyle(tokens), children: [
3525
+ succeeded && onIncreaseLimits && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: upsellCardStyle(tokens), children: [
3511
3526
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: upsellHeaderStyle, children: [
3512
3527
  /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", style: { marginRight: 6 }, children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M7 14l5-5 5 5", stroke: tokens.accent, strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) }),
3513
3528
  /* @__PURE__ */ jsxRuntime.jsx("strong", { children: "Want higher limits?" })
@@ -3989,12 +4004,11 @@ var radioDotStyle2 = (color) => ({
3989
4004
  borderRadius: "50%",
3990
4005
  background: color
3991
4006
  });
3992
- var STEP_LABELS = ["Creating transfer", "Verifying", "Sent", "Done"];
4007
+ var STEP_LABELS = ["Creating transfer", "Verifying", "Sent"];
3993
4008
  var PHASE_ACTIVE_INDEX = {
3994
4009
  creating: 0,
3995
4010
  verifying: 1,
3996
- sent: 2,
3997
- done: 4
4011
+ sent: 2
3998
4012
  };
3999
4013
  function buildSteps(phase) {
4000
4014
  const activeIdx = PHASE_ACTIVE_INDEX[phase];
@@ -4649,6 +4663,7 @@ function SwypePaymentInner({
4649
4663
  hasPasskey: true,
4650
4664
  accounts: accts,
4651
4665
  persistedMobileFlow: persisted,
4666
+ mobileSetupInProgress: false,
4652
4667
  connectingNewAccount: false
4653
4668
  });
4654
4669
  if (resolved.clearPersistedFlow) {
@@ -4689,6 +4704,16 @@ function SwypePaymentInner({
4689
4704
  setStep("success");
4690
4705
  return;
4691
4706
  }
4707
+ if (mobileResolution.kind === "resume-processing") {
4708
+ clearMobileFlowState();
4709
+ setMobileFlow(false);
4710
+ setDeeplinkUri(null);
4711
+ setTransfer(existingTransfer);
4712
+ setError(null);
4713
+ setStep("processing");
4714
+ polling.startPolling(existingTransfer.id);
4715
+ return;
4716
+ }
4692
4717
  if (mobileResolution.kind === "resume-stale-setup") {
4693
4718
  clearMobileFlowState();
4694
4719
  if (!cancelled) setStep("wallet-picker");
@@ -5185,6 +5210,7 @@ function SwypePaymentInner({
5185
5210
  processingStartedAtRef.current = null;
5186
5211
  pollingTransferIdRef.current = null;
5187
5212
  mobileSigningTransferIdRef.current = null;
5213
+ preSelectSourceStepRef.current = null;
5188
5214
  setConnectingNewAccount(false);
5189
5215
  setSelectedWalletId(null);
5190
5216
  if (accounts.length > 0) setSelectedAccountId(accounts[0].id);
@@ -5215,6 +5241,7 @@ function SwypePaymentInner({
5215
5241
  setAmount(depositAmount != null ? depositAmount.toString() : "");
5216
5242
  setMobileFlow(false);
5217
5243
  setDeeplinkUri(null);
5244
+ preSelectSourceStepRef.current = null;
5218
5245
  resetHeadlessLogin();
5219
5246
  }, [logout, polling, depositAmount, resetHeadlessLogin]);
5220
5247
  const handleConfirmSign = react.useCallback(async () => {
@@ -5225,12 +5252,13 @@ function SwypePaymentInner({
5225
5252
  setTransfer(signedTransfer);
5226
5253
  clearMobileFlowState();
5227
5254
  setStep("processing");
5255
+ polling.startPolling(t.id);
5228
5256
  } catch (err) {
5229
5257
  const msg = err instanceof Error ? err.message : "Failed to sign transfer";
5230
5258
  setError(msg);
5231
5259
  onError?.(msg);
5232
5260
  }
5233
- }, [transfer, polling.transfer, transferSigning, onError]);
5261
+ }, [transfer, polling.transfer, polling.startPolling, transferSigning, onError]);
5234
5262
  if (!ready) {
5235
5263
  return /* @__PURE__ */ jsxRuntime.jsx(ScreenLayout, { children: /* @__PURE__ */ jsxRuntime.jsx("div", { style: { textAlign: "center", padding: "48px 0", flex: 1, display: "flex", alignItems: "center", justifyContent: "center" }, children: /* @__PURE__ */ jsxRuntime.jsx(Spinner, { label: "Initializing..." }) }) });
5236
5264
  }
@@ -5355,7 +5383,7 @@ function SwypePaymentInner({
5355
5383
  }
5356
5384
  if (step === "processing") {
5357
5385
  const polledStatus = polling.transfer?.status;
5358
- const transferPhase = creatingTransfer ? "creating" : mobileFlow || authExecutor.executing || transferSigning.signing ? "verifying" : polledStatus === "SENDING" || polledStatus === "SENT" || polling.isPolling ? "sent" : "creating";
5386
+ const transferPhase = creatingTransfer ? "creating" : polledStatus === "SENDING" || polledStatus === "SENT" ? "sent" : "verifying";
5359
5387
  return /* @__PURE__ */ jsxRuntime.jsx(
5360
5388
  TransferStatusScreen,
5361
5389
  {
@@ -5386,7 +5414,7 @@ function SwypePaymentInner({
5386
5414
  );
5387
5415
  }
5388
5416
  if (step === "success") {
5389
- transfer?.status === "COMPLETED";
5417
+ const succeeded = transfer?.status === "COMPLETED";
5390
5418
  const displayAmount = transfer?.amount?.amount ?? 0;
5391
5419
  const displayCurrency = transfer?.amount?.currency ?? "USD";
5392
5420
  return /* @__PURE__ */ jsxRuntime.jsx(
@@ -5394,12 +5422,14 @@ function SwypePaymentInner({
5394
5422
  {
5395
5423
  amount: displayAmount,
5396
5424
  currency: displayCurrency,
5425
+ succeeded,
5426
+ error,
5397
5427
  merchantName,
5398
5428
  sourceName,
5399
- remainingLimit: (() => {
5429
+ remainingLimit: succeeded ? (() => {
5400
5430
  const limit = selectedAccount?.remainingAllowance ?? oneTapLimit;
5401
5431
  return limit > displayAmount ? limit - displayAmount : 0;
5402
- })(),
5432
+ })() : void 0,
5403
5433
  onDone: onDismiss ?? handleNewPayment,
5404
5434
  onLogout: handleLogout,
5405
5435
  autoCloseSeconds