@swype-org/react-sdk 0.1.116 → 0.1.123

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
@@ -811,10 +811,10 @@ function createPasskeyViaPopup(options) {
811
811
  if (result) {
812
812
  resolve(result);
813
813
  } else {
814
- reject(new Error("Passkey setup window was closed before completing."));
814
+ reject(new Error("Passkey window was closed before completing."));
815
815
  }
816
816
  }).catch(() => {
817
- reject(new Error("Passkey setup window was closed before completing."));
817
+ reject(new Error("Passkey window was closed before completing."));
818
818
  });
819
819
  }
820
820
  }, POPUP_CLOSED_GRACE_MS);
@@ -1740,6 +1740,9 @@ function resolvePostAuthStep(state) {
1740
1740
  return { step: "create-passkey", clearPersistedFlow: false };
1741
1741
  }
1742
1742
  if (state.persistedMobileFlow) {
1743
+ if (state.persistedMobileFlow.isReauthorization) {
1744
+ return { step: "open-wallet", clearPersistedFlow: false };
1745
+ }
1743
1746
  if (state.persistedMobileFlow.isSetup && hasActiveWallet(state.accounts)) {
1744
1747
  return { step: "deposit", clearPersistedFlow: true };
1745
1748
  }
@@ -1908,7 +1911,10 @@ function buildSelectSourceChoices(options) {
1908
1911
  chainChoice.tokens.push({ tokenSymbol, balance });
1909
1912
  }
1910
1913
  }
1911
- return chainChoices;
1914
+ return chainChoices.map((chain) => ({
1915
+ ...chain,
1916
+ tokens: chain.tokens.filter((t) => t.balance > 0)
1917
+ })).filter((chain) => chain.tokens.length > 0);
1912
1918
  }
1913
1919
 
1914
1920
  // src/paymentReducer.ts
@@ -2248,7 +2254,7 @@ var spinnerStyle = {
2248
2254
  };
2249
2255
  var FOOTER_CSS = `
2250
2256
  .swype-screen-footer {
2251
- padding-bottom: max(24px, env(safe-area-inset-bottom, 24px));
2257
+ padding-bottom: max(32px, env(safe-area-inset-bottom, 32px));
2252
2258
  }`;
2253
2259
  function ScreenLayout({ children, footer }) {
2254
2260
  const { tokens } = useSwypeConfig();
@@ -2271,12 +2277,16 @@ var containerStyle2 = (bg) => ({
2271
2277
  });
2272
2278
  var bodyStyle = {
2273
2279
  flex: 1,
2280
+ minHeight: 0,
2274
2281
  padding: "0 24px",
2275
2282
  display: "flex",
2276
- flexDirection: "column"
2283
+ flexDirection: "column",
2284
+ overflowY: "auto"
2277
2285
  };
2278
2286
  var footerStyle = {
2279
- padding: "16px 24px 0",
2287
+ paddingTop: 16,
2288
+ paddingLeft: 24,
2289
+ paddingRight: 24,
2280
2290
  marginTop: "auto"
2281
2291
  };
2282
2292
  function ScreenHeader({ title, right, onBack, badge }) {
@@ -3153,7 +3163,7 @@ function LoginScreen({
3153
3163
  ] }),
3154
3164
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: walletSectionStyle, children: [
3155
3165
  /* @__PURE__ */ jsxRuntime.jsx("span", { style: walletLabelStyle(tokens.textMuted), children: "Works with" }),
3156
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: walletLogosStyle, children: walletIcons.map(({ key, emoji, logo }) => logo ? /* @__PURE__ */ jsxRuntime.jsx("img", { src: logo, alt: key, style: walletLogoImgStyle }, key) : /* @__PURE__ */ jsxRuntime.jsx("span", { style: walletEmojiStyle, children: emoji }, key)) })
3166
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: walletLogosStyle, children: walletIcons.map(({ key, logo }) => /* @__PURE__ */ jsxRuntime.jsx("img", { src: logo, alt: key, style: walletLogoImgStyle }, key)) })
3157
3167
  ] }),
3158
3168
  /* @__PURE__ */ jsxRuntime.jsx(PoweredByFooter, {})
3159
3169
  ] }),
@@ -3192,11 +3202,9 @@ function LoginScreen({
3192
3202
  );
3193
3203
  }
3194
3204
  var walletIcons = [
3195
- { key: "metamask", emoji: "\u{1F98A}", logo: KNOWN_LOGOS["metamask"] },
3196
- { key: "rabby", emoji: "\u{1F430}" },
3197
- { key: "phantom", emoji: "\u25C6" },
3198
- { key: "rainbow", emoji: "\u{1F439}" },
3199
- { key: "coinbase", emoji: "\u{1F535}", logo: KNOWN_LOGOS["base"] }
3205
+ { key: "metamask", logo: KNOWN_LOGOS["metamask"] },
3206
+ { key: "base", logo: KNOWN_LOGOS["base"] },
3207
+ { key: "trust wallet", logo: KNOWN_LOGOS["trust wallet"] }
3200
3208
  ];
3201
3209
  function socialLabel(provider) {
3202
3210
  switch (provider) {
@@ -3316,10 +3324,6 @@ var walletLogosStyle = {
3316
3324
  justifyContent: "center",
3317
3325
  gap: 16
3318
3326
  };
3319
- var walletEmojiStyle = {
3320
- fontSize: "1.4rem",
3321
- lineHeight: 1
3322
- };
3323
3327
  var walletLogoImgStyle = {
3324
3328
  width: 24,
3325
3329
  height: 24,
@@ -3471,7 +3475,7 @@ var hintStyle = (color) => ({
3471
3475
  color,
3472
3476
  margin: "12px 0 0"
3473
3477
  });
3474
- function CreatePasskeyScreen({
3478
+ function PasskeyScreen({
3475
3479
  onCreatePasskey,
3476
3480
  onBack,
3477
3481
  creating,
@@ -3481,7 +3485,7 @@ function CreatePasskeyScreen({
3481
3485
  }) {
3482
3486
  const { tokens } = useSwypeConfig();
3483
3487
  const handleCreate = popupFallback && onCreatePasskeyViaPopup ? onCreatePasskeyViaPopup : onCreatePasskey;
3484
- const buttonLabel = popupFallback ? "Open passkey setup" : "Create passkey";
3488
+ const buttonLabel = popupFallback ? "Open passkey window" : "Create or verify passkey";
3485
3489
  return /* @__PURE__ */ jsxRuntime.jsxs(
3486
3490
  ScreenLayout,
3487
3491
  {
@@ -3498,8 +3502,8 @@ function CreatePasskeyScreen({
3498
3502
  /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "15", cy: "10", r: "1", fill: tokens.accent }),
3499
3503
  /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M9 14c0 1.5 1.34 2.5 3 2.5s3-1 3-2.5", stroke: tokens.accent, strokeWidth: "1.2", strokeLinecap: "round" })
3500
3504
  ] }) }),
3501
- /* @__PURE__ */ jsxRuntime.jsx("h2", { style: headingStyle3(tokens.text), children: "Create your passkey" }),
3502
- /* @__PURE__ */ jsxRuntime.jsx("p", { style: subtitleStyle3(tokens.textSecondary), children: popupFallback ? "Your browser requires a separate window for passkey setup. Tap the button below to continue." : "Use Face ID to sign in instantly \u2014 no passwords, no codes." }),
3505
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { style: headingStyle3(tokens.text), children: "Create or verify your passkey" }),
3506
+ /* @__PURE__ */ jsxRuntime.jsx("p", { style: subtitleStyle3(tokens.textSecondary), children: popupFallback ? "Your browser requires a separate window to continue. Tap the button below to continue." : "Use Face ID to sign in instantly \u2014 no passwords, no codes." }),
3503
3507
  error && /* @__PURE__ */ jsxRuntime.jsx("div", { style: errorBannerStyle2(tokens), children: error }),
3504
3508
  /* @__PURE__ */ jsxRuntime.jsx(InfoBanner, { children: "Your passkey is stored securely on your device. Swype never sees your biometric data." })
3505
3509
  ] })
@@ -3842,16 +3846,16 @@ function SetupScreen({
3842
3846
  error
3843
3847
  }) {
3844
3848
  const { tokens } = useSwypeConfig();
3845
- const effectiveMax = DEFAULT_MAX;
3849
+ const effectiveMax = Math.min(DEFAULT_MAX, availableBalance);
3846
3850
  const effectiveMin = Math.min(ABSOLUTE_MIN, effectiveMax);
3847
- const [limit, setLimit] = react.useState(() => effectiveMax);
3851
+ const [limit, setLimit] = react.useState(() => Math.min(availableBalance, effectiveMax));
3848
3852
  const [editing, setEditing] = react.useState(false);
3849
3853
  const [inputValue, setInputValue] = react.useState("");
3850
3854
  const inputRef = react.useRef(null);
3851
3855
  const startEditing = react.useCallback(() => {
3852
3856
  setInputValue(limit.toFixed(2));
3853
3857
  setEditing(true);
3854
- requestAnimationFrame(() => inputRef.current?.select());
3858
+ requestAnimationFrame(() => inputRef.current?.focus());
3855
3859
  }, [limit]);
3856
3860
  const commitEdit = react.useCallback(() => {
3857
3861
  const parsed = parseFloat(inputValue);
@@ -5141,6 +5145,7 @@ function OpenWalletScreen({
5141
5145
  loading,
5142
5146
  error,
5143
5147
  onRetryStatus,
5148
+ onBack,
5144
5149
  onLogout
5145
5150
  }) {
5146
5151
  const { tokens } = useSwypeConfig();
@@ -5171,7 +5176,7 @@ function OpenWalletScreen({
5171
5176
  /* @__PURE__ */ jsxRuntime.jsx("p", { style: hintStyle3(tokens.textMuted), children: loading ? "Preparing authorization..." : error ? "Retry the status check after returning to the browser, or reopen your wallet if needed." : "If your wallet didn't open automatically, tap the button above" })
5172
5177
  ] }),
5173
5178
  children: [
5174
- /* @__PURE__ */ jsxRuntime.jsx(ScreenHeader, { right: /* @__PURE__ */ jsxRuntime.jsx(SettingsMenu, { onLogout }) }),
5179
+ /* @__PURE__ */ jsxRuntime.jsx(ScreenHeader, { onBack, right: /* @__PURE__ */ jsxRuntime.jsx(SettingsMenu, { onLogout }) }),
5175
5180
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: contentStyle8, children: [
5176
5181
  logoSrc ? /* @__PURE__ */ jsxRuntime.jsx("img", { src: logoSrc, alt: displayName, style: logoStyle }) : /* @__PURE__ */ jsxRuntime.jsx(Spinner, { size: 48 }),
5177
5182
  /* @__PURE__ */ jsxRuntime.jsx("h2", { style: headingStyle10(tokens.text), children: loading ? "Connecting..." : `Open ${displayName}` }),
@@ -5630,7 +5635,7 @@ function StepRenderer({
5630
5635
  }
5631
5636
  if (step === "create-passkey") {
5632
5637
  return /* @__PURE__ */ jsxRuntime.jsx(
5633
- CreatePasskeyScreen,
5638
+ PasskeyScreen,
5634
5639
  {
5635
5640
  onCreatePasskey: handlers.onRegisterPasskey,
5636
5641
  onBack: handlers.onLogout,
@@ -5641,6 +5646,19 @@ function StepRenderer({
5641
5646
  }
5642
5647
  );
5643
5648
  }
5649
+ if (step === "verify-passkey") {
5650
+ return /* @__PURE__ */ jsxRuntime.jsx(
5651
+ PasskeyScreen,
5652
+ {
5653
+ onCreatePasskey: handlers.onRegisterPasskey,
5654
+ onBack: handlers.onLogout,
5655
+ creating: state.verifyingPasskeyPopup,
5656
+ error: state.error,
5657
+ popupFallback: true,
5658
+ onCreatePasskeyViaPopup: handlers.onVerifyPasskeyViaPopup
5659
+ }
5660
+ );
5661
+ }
5644
5662
  if (step === "wallet-picker") {
5645
5663
  return /* @__PURE__ */ jsxRuntime.jsx(
5646
5664
  WalletPickerScreen,
@@ -5664,6 +5682,7 @@ function StepRenderer({
5664
5682
  loading: state.creatingTransfer || !state.deeplinkUri,
5665
5683
  error: state.error || pollingError,
5666
5684
  onRetryStatus: handlers.onRetryMobileStatus,
5685
+ onBack: () => handlers.onNavigate("wallet-picker"),
5667
5686
  onLogout: handlers.onLogout
5668
5687
  }
5669
5688
  );
@@ -5954,6 +5973,8 @@ function SwypePaymentInner({
5954
5973
  const initializedSelectSourceActionRef = react.useRef(null);
5955
5974
  const preSelectSourceStepRef = react.useRef(null);
5956
5975
  const pendingTokenAuthRef = react.useRef(null);
5976
+ const reauthSessionIdRef = react.useRef(null);
5977
+ const reauthTokenRef = react.useRef(null);
5957
5978
  const checkingPasskeyRef = react.useRef(false);
5958
5979
  const onCompleteRef = react.useRef(onComplete);
5959
5980
  onCompleteRef.current = onComplete;
@@ -6247,7 +6268,7 @@ function SwypePaymentInner({
6247
6268
  return;
6248
6269
  }
6249
6270
  if (!state.activeCredentialId) {
6250
- dispatch({ type: "SET_ERROR", error: "Create a passkey on this device before continuing." });
6271
+ dispatch({ type: "SET_ERROR", error: "Create or verify a passkey on this device before continuing." });
6251
6272
  dispatch({ type: "NAVIGATE", step: "create-passkey" });
6252
6273
  return;
6253
6274
  }
@@ -6328,7 +6349,7 @@ function SwypePaymentInner({
6328
6349
  return;
6329
6350
  }
6330
6351
  if (!state.activeCredentialId) {
6331
- dispatch({ type: "SET_ERROR", error: "Create a passkey on this device before continuing." });
6352
+ dispatch({ type: "SET_ERROR", error: "Create or verify a passkey on this device before continuing." });
6332
6353
  dispatch({ type: "NAVIGATE", step: "create-passkey" });
6333
6354
  return;
6334
6355
  }
@@ -6356,12 +6377,15 @@ function SwypePaymentInner({
6356
6377
  handlingMobileReturnRef.current = false;
6357
6378
  mobileSetupFlowRef.current = true;
6358
6379
  setupAccountIdRef.current = state.selectedAccountId;
6380
+ reauthSessionIdRef.current = session.id;
6381
+ reauthTokenRef.current = null;
6359
6382
  persistMobileFlowState({
6360
6383
  accountId: state.selectedAccountId,
6361
6384
  sessionId: session.id,
6362
6385
  deeplinkUri: session.uri,
6363
6386
  providerId: matchedProvider?.id ?? null,
6364
- isSetup: true
6387
+ isSetup: true,
6388
+ isReauthorization: true
6365
6389
  });
6366
6390
  dispatch({ type: "MOBILE_DEEPLINK_READY", deeplinkUri: session.uri });
6367
6391
  triggerDeeplink(session.uri);
@@ -6402,7 +6426,7 @@ function SwypePaymentInner({
6402
6426
  return;
6403
6427
  }
6404
6428
  if (!state.activeCredentialId) {
6405
- dispatch({ type: "SET_ERROR", error: "Create a passkey on this device before continuing." });
6429
+ dispatch({ type: "SET_ERROR", error: "Create or verify a passkey on this device before continuing." });
6406
6430
  dispatch({ type: "NAVIGATE", step: "create-passkey" });
6407
6431
  return;
6408
6432
  }
@@ -6432,12 +6456,16 @@ function SwypePaymentInner({
6432
6456
  handlingMobileReturnRef.current = false;
6433
6457
  mobileSetupFlowRef.current = true;
6434
6458
  setupAccountIdRef.current = state.selectedAccountId;
6459
+ reauthSessionIdRef.current = session.id;
6460
+ reauthTokenRef.current = { walletId: _walletId, tokenSymbol };
6435
6461
  persistMobileFlowState({
6436
6462
  accountId: state.selectedAccountId,
6437
6463
  sessionId: session.id,
6438
6464
  deeplinkUri: session.uri,
6439
6465
  providerId: matchedProvider?.id ?? null,
6440
- isSetup: true
6466
+ isSetup: true,
6467
+ isReauthorization: true,
6468
+ reauthorizationToken: { walletId: _walletId, tokenSymbol }
6441
6469
  });
6442
6470
  dispatch({ type: "MOBILE_DEEPLINK_READY", deeplinkUri: session.uri });
6443
6471
  triggerDeeplink(session.uri);
@@ -6499,7 +6527,7 @@ function SwypePaymentInner({
6499
6527
  const handleSelectProvider = react.useCallback(async (providerId) => {
6500
6528
  dispatch({ type: "SELECT_PROVIDER", providerId });
6501
6529
  if (!state.activeCredentialId) {
6502
- dispatch({ type: "SET_ERROR", error: "Create a passkey on this device before continuing." });
6530
+ dispatch({ type: "SET_ERROR", error: "Create or verify a passkey on this device before continuing." });
6503
6531
  dispatch({ type: "NAVIGATE", step: "create-passkey" });
6504
6532
  return;
6505
6533
  }
@@ -6710,6 +6738,31 @@ function SwypePaymentInner({
6710
6738
  } catch {
6711
6739
  }
6712
6740
  }
6741
+ if (resolved.step === "open-wallet" && persisted && persisted.isReauthorization && persisted.sessionId) {
6742
+ try {
6743
+ const session = await fetchAuthorizationSession(apiBaseUrl, persisted.sessionId);
6744
+ if (cancelled) return;
6745
+ if (session.status === "AUTHORIZED") {
6746
+ clearMobileFlowState();
6747
+ dispatch({ type: "NAVIGATE", step: "deposit" });
6748
+ if (persisted.reauthorizationToken) {
6749
+ dispatch({ type: "SELECT_TOKEN", walletId: persisted.reauthorizationToken.walletId, tokenSymbol: persisted.reauthorizationToken.tokenSymbol });
6750
+ }
6751
+ return;
6752
+ }
6753
+ } catch {
6754
+ }
6755
+ reauthSessionIdRef.current = persisted.sessionId;
6756
+ reauthTokenRef.current = persisted.reauthorizationToken ?? null;
6757
+ mobileSetupFlowRef.current = true;
6758
+ setupAccountIdRef.current = persisted.accountId ?? null;
6759
+ dispatch({
6760
+ type: "ENTER_MOBILE_FLOW",
6761
+ deeplinkUri: persisted.deeplinkUri,
6762
+ providerId: persisted.providerId
6763
+ });
6764
+ return;
6765
+ }
6713
6766
  if (resolved.step === "open-wallet" && persisted && persisted.accountId && !persisted.transferId) {
6714
6767
  clearMobileFlowState();
6715
6768
  dispatch({ type: "NAVIGATE", step: "deposit" });
@@ -6763,6 +6816,7 @@ function SwypePaymentInner({
6763
6816
  });
6764
6817
  pollingTransferIdRef.current = persisted.transferId ?? null;
6765
6818
  mobileSetupFlowRef.current = persisted.isSetup;
6819
+ setupAccountIdRef.current = persisted.accountId ?? null;
6766
6820
  if (persisted.transferId) pollingRef.current.startPolling(persisted.transferId);
6767
6821
  return;
6768
6822
  }
@@ -6773,6 +6827,7 @@ function SwypePaymentInner({
6773
6827
  });
6774
6828
  pollingTransferIdRef.current = persisted.transferId ?? null;
6775
6829
  mobileSetupFlowRef.current = persisted.isSetup;
6830
+ setupAccountIdRef.current = persisted.accountId ?? null;
6776
6831
  if (persisted.transferId) pollingRef.current.startPolling(persisted.transferId);
6777
6832
  return;
6778
6833
  }
@@ -6977,9 +7032,36 @@ function SwypePaymentInner({
6977
7032
  if (!state.activeCredentialId || !setupAccountIdRef.current) return;
6978
7033
  const accountId = setupAccountIdRef.current;
6979
7034
  const credentialId = state.activeCredentialId;
7035
+ const isReauth = !!reauthSessionIdRef.current;
7036
+ const sessionId = reauthSessionIdRef.current;
7037
+ const tokenSelection = reauthTokenRef.current;
6980
7038
  let cancelled = false;
6981
7039
  const POLL_INTERVAL_MS = 3e3;
6982
- const poll = async () => {
7040
+ const pollReauthorization = async () => {
7041
+ try {
7042
+ if (!sessionId || cancelled) return;
7043
+ const session = await fetchAuthorizationSession(apiBaseUrl, sessionId);
7044
+ if (cancelled) return;
7045
+ if (session.status === "AUTHORIZED") {
7046
+ cancelled = true;
7047
+ mobileSetupFlowRef.current = false;
7048
+ setupAccountIdRef.current = null;
7049
+ reauthSessionIdRef.current = null;
7050
+ reauthTokenRef.current = null;
7051
+ clearMobileFlowState();
7052
+ try {
7053
+ await reloadAccounts();
7054
+ } catch {
7055
+ }
7056
+ dispatch({ type: "MOBILE_SETUP_COMPLETE" });
7057
+ if (tokenSelection) {
7058
+ dispatch({ type: "SELECT_TOKEN", walletId: tokenSelection.walletId, tokenSymbol: tokenSelection.tokenSymbol });
7059
+ }
7060
+ }
7061
+ } catch {
7062
+ }
7063
+ };
7064
+ const pollWalletActive = async () => {
6983
7065
  try {
6984
7066
  const token = await getAccessTokenRef.current();
6985
7067
  if (!token || cancelled) return;
@@ -6991,12 +7073,16 @@ function SwypePaymentInner({
6991
7073
  mobileSetupFlowRef.current = false;
6992
7074
  setupAccountIdRef.current = null;
6993
7075
  clearMobileFlowState();
6994
- await reloadAccounts();
7076
+ try {
7077
+ await reloadAccounts();
7078
+ } catch {
7079
+ }
6995
7080
  dispatch({ type: "MOBILE_SETUP_COMPLETE" });
6996
7081
  }
6997
7082
  } catch {
6998
7083
  }
6999
7084
  };
7085
+ const poll = isReauth ? pollReauthorization : pollWalletActive;
7000
7086
  poll();
7001
7087
  const intervalId = window.setInterval(poll, POLL_INTERVAL_MS);
7002
7088
  const handleVisibility = () => {
@@ -7166,11 +7252,11 @@ function SwypePaymentInner({
7166
7252
  }
7167
7253
 
7168
7254
  exports.AdvancedSourceScreen = AdvancedSourceScreen;
7169
- exports.CreatePasskeyScreen = CreatePasskeyScreen;
7170
7255
  exports.IconCircle = IconCircle;
7171
7256
  exports.InfoBanner = InfoBanner;
7172
7257
  exports.OutlineButton = OutlineButton;
7173
7258
  exports.PasskeyIframeBlockedError = PasskeyIframeBlockedError;
7259
+ exports.PasskeyScreen = PasskeyScreen;
7174
7260
  exports.PoweredByFooter = PoweredByFooter;
7175
7261
  exports.PrimaryButton = PrimaryButton;
7176
7262
  exports.ScreenHeader = ScreenHeader;