@swype-org/react-sdk 0.1.208 → 0.2.1-betatest

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.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { createContext, useRef, useState, useCallback, useMemo, useContext, useEffect, useReducer, Component } from 'react';
2
2
  import { PrivyProvider, usePrivy, useLoginWithOAuth, useLoginWithEmail, useLoginWithSms } from '@privy-io/react-auth';
3
- import { createConfig, http, WagmiProvider, useConfig, useConnect, useSwitchChain } from 'wagmi';
3
+ import { createConfig, http, WagmiProvider, useConfig, useConnect, useSwitchChain, useAccount, useSendTransaction } from 'wagmi';
4
4
  import { mainnet, arbitrum, base, polygon, bsc } from 'wagmi/chains';
5
5
  import { injected } from 'wagmi/connectors';
6
6
  import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
@@ -418,11 +418,14 @@ var api_exports = {};
418
418
  __export(api_exports, {
419
419
  createAccount: () => createAccount,
420
420
  createAccountAuthorizationSession: () => createAccountAuthorizationSession,
421
+ createGuestTransfer: () => createGuestTransfer,
421
422
  createTransfer: () => createTransfer,
422
423
  fetchAccount: () => fetchAccount,
423
424
  fetchAccounts: () => fetchAccounts,
424
425
  fetchAuthorizationSession: () => fetchAuthorizationSession,
425
426
  fetchChains: () => fetchChains,
427
+ fetchGuestQuote: () => fetchGuestQuote,
428
+ fetchGuestTransfer: () => fetchGuestTransfer,
426
429
  fetchMerchantPublicKey: () => fetchMerchantPublicKey,
427
430
  fetchProviders: () => fetchProviders,
428
431
  fetchTransfer: () => fetchTransfer,
@@ -654,6 +657,31 @@ async function reportActionCompletion(apiBaseUrl, actionId, result) {
654
657
  if (!res.ok) await throwApiError(res);
655
658
  return await res.json();
656
659
  }
660
+ async function fetchGuestQuote(apiBaseUrl, params) {
661
+ const res = await fetch(`${apiBaseUrl}/v1/guest-transfers/quote`, {
662
+ method: "POST",
663
+ headers: { "Content-Type": "application/json" },
664
+ body: JSON.stringify(params)
665
+ });
666
+ if (!res.ok) await throwApiError(res);
667
+ return await res.json();
668
+ }
669
+ async function createGuestTransfer(apiBaseUrl, params) {
670
+ const res = await fetch(`${apiBaseUrl}/v1/guest-transfers`, {
671
+ method: "POST",
672
+ headers: { "Content-Type": "application/json" },
673
+ body: JSON.stringify(params)
674
+ });
675
+ if (!res.ok) await throwApiError(res);
676
+ return await res.json();
677
+ }
678
+ async function fetchGuestTransfer(apiBaseUrl, transferId) {
679
+ const res = await fetch(
680
+ `${apiBaseUrl}/v1/guest-transfers/${transferId}`
681
+ );
682
+ if (!res.ok) await throwApiError(res);
683
+ return await res.json();
684
+ }
657
685
 
658
686
  // src/passkeyRpId.ts
659
687
  function normalizeConfiguredDomain(value) {
@@ -1789,7 +1817,7 @@ function deriveSourceTypeAndId(state) {
1789
1817
  }
1790
1818
  function createInitialState(config) {
1791
1819
  return {
1792
- step: "login",
1820
+ step: "guest-deposit",
1793
1821
  error: null,
1794
1822
  providers: [],
1795
1823
  accounts: [],
@@ -1812,7 +1840,14 @@ function createInitialState(config) {
1812
1840
  mobileFlow: false,
1813
1841
  deeplinkUri: null,
1814
1842
  increasingLimit: false,
1815
- previousStep: null
1843
+ previousStep: null,
1844
+ isGuestFlow: true,
1845
+ guestQuote: null,
1846
+ guestOriginTxHash: null,
1847
+ guestTransferId: null,
1848
+ guestTransferComplete: false,
1849
+ guestWalletAddress: null,
1850
+ guestWalletChainId: null
1816
1851
  };
1817
1852
  }
1818
1853
  function paymentReducer(state, action) {
@@ -1952,7 +1987,7 @@ function paymentReducer(state, action) {
1952
1987
  deeplinkUri: null
1953
1988
  };
1954
1989
  case "PROCESSING_TIMEOUT":
1955
- return { ...state, error: action.error, step: "deposit" };
1990
+ return { ...state, error: action.error, step: state.isGuestFlow ? "guest-deposit" : "deposit" };
1956
1991
  case "CONFIRM_SIGN_SUCCESS":
1957
1992
  return {
1958
1993
  ...state,
@@ -2064,6 +2099,54 @@ function paymentReducer(state, action) {
2064
2099
  };
2065
2100
  case "SYNC_AMOUNT":
2066
2101
  return { ...state, amount: action.amount };
2102
+ // ── Guest flow ───────────────────────────────────────────────
2103
+ case "GUEST_WALLET_CONNECTED":
2104
+ return {
2105
+ ...state,
2106
+ guestWalletAddress: action.address,
2107
+ guestWalletChainId: action.chainId,
2108
+ step: "guest-signing",
2109
+ error: null
2110
+ };
2111
+ case "GUEST_QUOTE_RECEIVED":
2112
+ return {
2113
+ ...state,
2114
+ guestQuote: action.quote
2115
+ };
2116
+ case "GUEST_DEPOSIT_SIGNED":
2117
+ return {
2118
+ ...state,
2119
+ guestOriginTxHash: action.txHash,
2120
+ step: "processing"
2121
+ };
2122
+ case "GUEST_TRANSFER_SUBMITTED":
2123
+ return {
2124
+ ...state,
2125
+ guestTransferId: action.transferId
2126
+ };
2127
+ case "GUEST_TRANSFER_COMPLETED":
2128
+ return {
2129
+ ...state,
2130
+ guestTransferComplete: true,
2131
+ step: "success"
2132
+ };
2133
+ case "GUEST_TRANSFER_FAILED":
2134
+ return {
2135
+ ...state,
2136
+ error: action.error,
2137
+ step: "success"
2138
+ };
2139
+ case "START_SETUP_FLOW":
2140
+ return {
2141
+ ...state,
2142
+ isGuestFlow: false,
2143
+ step: "login"
2144
+ };
2145
+ case "SETUP_FLOW_COMPLETE":
2146
+ return {
2147
+ ...state,
2148
+ step: "setup-complete"
2149
+ };
2067
2150
  default:
2068
2151
  return state;
2069
2152
  }
@@ -4242,7 +4325,9 @@ function SuccessScreen({
4242
4325
  onLogout,
4243
4326
  onIncreaseLimits,
4244
4327
  onManageAccount,
4245
- autoCloseSeconds
4328
+ autoCloseSeconds,
4329
+ isGuestTransfer,
4330
+ onOfferSetup
4246
4331
  }) {
4247
4332
  const { tokens } = useSwypeConfig();
4248
4333
  const effectiveAutoClose = succeeded ? autoCloseSeconds : void 0;
@@ -4251,8 +4336,12 @@ function SuccessScreen({
4251
4336
  const handleDone = useCallback(() => {
4252
4337
  if (doneCalledRef.current) return;
4253
4338
  doneCalledRef.current = true;
4254
- onDone();
4255
- }, [onDone]);
4339
+ if (isGuestTransfer && succeeded && onOfferSetup) {
4340
+ onOfferSetup();
4341
+ } else {
4342
+ onDone();
4343
+ }
4344
+ }, [onDone, isGuestTransfer, succeeded, onOfferSetup]);
4256
4345
  useEffect(() => {
4257
4346
  if (!effectiveAutoClose || effectiveAutoClose <= 0) return;
4258
4347
  const intervalId = window.setInterval(() => {
@@ -4275,7 +4364,7 @@ function SuccessScreen({
4275
4364
  ScreenLayout,
4276
4365
  {
4277
4366
  footer: /* @__PURE__ */ jsxs(Fragment, { children: [
4278
- /* @__PURE__ */ jsx(PrimaryButton, { onClick: handleDone, children: succeeded ? "Done" : "Try again" }),
4367
+ /* @__PURE__ */ jsx(PrimaryButton, { onClick: handleDone, children: !succeeded ? "Try again" : isGuestTransfer ? "Continue" : "Done" }),
4279
4368
  effectiveAutoClose != null && effectiveAutoClose > 0 && /* @__PURE__ */ jsxs("p", { style: countdownStyle(tokens.textMuted), children: [
4280
4369
  "Returning to app in ",
4281
4370
  countdown,
@@ -5396,6 +5485,317 @@ var selectCircleSelectedStyle = (color) => ({
5396
5485
  justifyContent: "center",
5397
5486
  flexShrink: 0
5398
5487
  });
5488
+ function GuestDepositScreen({
5489
+ amount,
5490
+ currency,
5491
+ merchantName,
5492
+ onConfirm,
5493
+ onSignIn,
5494
+ onBack,
5495
+ loading,
5496
+ error
5497
+ }) {
5498
+ const { tokens } = useSwypeConfig();
5499
+ return /* @__PURE__ */ jsxs(
5500
+ ScreenLayout,
5501
+ {
5502
+ footer: /* @__PURE__ */ jsxs(Fragment, { children: [
5503
+ /* @__PURE__ */ jsx(PrimaryButton, { onClick: onConfirm, loading, children: "Confirm" }),
5504
+ /* @__PURE__ */ jsx(
5505
+ "button",
5506
+ {
5507
+ type: "button",
5508
+ onClick: onSignIn,
5509
+ style: signInStyle(tokens.textMuted),
5510
+ children: "Returning user? Sign in"
5511
+ }
5512
+ ),
5513
+ /* @__PURE__ */ jsx(PoweredByFooter, {})
5514
+ ] }),
5515
+ children: [
5516
+ /* @__PURE__ */ jsx(ScreenHeader, { onBack }),
5517
+ /* @__PURE__ */ jsxs("div", { style: contentStyle9, children: [
5518
+ /* @__PURE__ */ jsxs("div", { style: amountCircle(tokens), children: [
5519
+ /* @__PURE__ */ jsx("span", { style: currencyStyle(tokens.textSecondary), children: currency === "USD" ? "$" : currency }),
5520
+ /* @__PURE__ */ jsx("span", { style: amountStyle(tokens.text), children: amount.toFixed(2) })
5521
+ ] }),
5522
+ merchantName && /* @__PURE__ */ jsxs("p", { style: merchantStyle(tokens.textSecondary), children: [
5523
+ "to ",
5524
+ merchantName
5525
+ ] }),
5526
+ /* @__PURE__ */ jsx("p", { style: descriptionStyle(tokens.textSecondary), children: "Connect your wallet to complete this deposit. No account required." }),
5527
+ error && /* @__PURE__ */ jsx("div", { style: errorStyle3(tokens), children: error })
5528
+ ] })
5529
+ ]
5530
+ }
5531
+ );
5532
+ }
5533
+ var contentStyle9 = {
5534
+ flex: 1,
5535
+ display: "flex",
5536
+ flexDirection: "column",
5537
+ alignItems: "center",
5538
+ paddingTop: 32
5539
+ };
5540
+ var amountCircle = (tokens) => ({
5541
+ display: "flex",
5542
+ alignItems: "baseline",
5543
+ justifyContent: "center",
5544
+ gap: 4,
5545
+ padding: "24px 36px",
5546
+ background: tokens.bgInput,
5547
+ border: `1px solid ${tokens.border}`,
5548
+ borderRadius: 24,
5549
+ marginBottom: 12
5550
+ });
5551
+ var currencyStyle = (color) => ({
5552
+ fontSize: "1.5rem",
5553
+ fontWeight: 600,
5554
+ color
5555
+ });
5556
+ var amountStyle = (color) => ({
5557
+ fontSize: "2.5rem",
5558
+ fontWeight: 700,
5559
+ letterSpacing: "-0.02em",
5560
+ color
5561
+ });
5562
+ var merchantStyle = (color) => ({
5563
+ fontSize: "0.9rem",
5564
+ color,
5565
+ margin: "0 0 16px"
5566
+ });
5567
+ var descriptionStyle = (color) => ({
5568
+ fontSize: "0.88rem",
5569
+ color,
5570
+ textAlign: "center",
5571
+ lineHeight: 1.6,
5572
+ maxWidth: 300,
5573
+ margin: "0 0 20px"
5574
+ });
5575
+ var signInStyle = (color) => ({
5576
+ background: "transparent",
5577
+ border: "none",
5578
+ color,
5579
+ cursor: "pointer",
5580
+ fontFamily: "inherit",
5581
+ fontSize: "0.84rem",
5582
+ fontWeight: 500,
5583
+ display: "block",
5584
+ width: "100%",
5585
+ textAlign: "center",
5586
+ padding: "14px 0 0"
5587
+ });
5588
+ var errorStyle3 = (tokens) => ({
5589
+ width: "100%",
5590
+ padding: "12px 16px",
5591
+ background: tokens.errorBg,
5592
+ color: tokens.error,
5593
+ borderRadius: 14,
5594
+ fontSize: "0.84rem",
5595
+ lineHeight: 1.5
5596
+ });
5597
+ var PHASE_LABELS = {
5598
+ connecting: "Connecting wallet...",
5599
+ "fetching-quote": "Getting best rate...",
5600
+ approving: "Approve token access",
5601
+ signing: "Confirm deposit in your wallet",
5602
+ submitting: "Submitting transfer..."
5603
+ };
5604
+ var PHASE_DESCRIPTIONS = {
5605
+ connecting: "Please connect your wallet to continue.",
5606
+ "fetching-quote": "Finding the best route for your transfer.",
5607
+ approving: "Your wallet will ask you to approve token access for this transfer.",
5608
+ signing: "Sign the deposit transaction in your wallet to send funds.",
5609
+ submitting: "Your transaction has been signed. Submitting to the network..."
5610
+ };
5611
+ function GuestWalletScreen({
5612
+ phase,
5613
+ amount,
5614
+ currency,
5615
+ onBack,
5616
+ error,
5617
+ onRetry
5618
+ }) {
5619
+ const { tokens } = useSwypeConfig();
5620
+ return /* @__PURE__ */ jsxs(
5621
+ ScreenLayout,
5622
+ {
5623
+ footer: /* @__PURE__ */ jsxs(Fragment, { children: [
5624
+ error && onRetry && /* @__PURE__ */ jsx(PrimaryButton, { onClick: onRetry, children: "Try again" }),
5625
+ /* @__PURE__ */ jsx(PoweredByFooter, {})
5626
+ ] }),
5627
+ children: [
5628
+ /* @__PURE__ */ jsx(ScreenHeader, { onBack }),
5629
+ /* @__PURE__ */ jsxs("div", { style: contentStyle10, children: [
5630
+ !error && /* @__PURE__ */ jsx(Spinner, { size: 48 }),
5631
+ /* @__PURE__ */ jsx("h2", { style: headingStyle12(tokens.text), children: error ? "Something went wrong" : PHASE_LABELS[phase] }),
5632
+ /* @__PURE__ */ jsx("p", { style: descriptionStyle2(tokens.textSecondary), children: error ?? PHASE_DESCRIPTIONS[phase] }),
5633
+ /* @__PURE__ */ jsxs("div", { style: amountBadgeStyle(tokens), children: [
5634
+ currency === "USD" ? "$" : currency,
5635
+ amount.toFixed(2)
5636
+ ] })
5637
+ ] })
5638
+ ]
5639
+ }
5640
+ );
5641
+ }
5642
+ var contentStyle10 = {
5643
+ flex: 1,
5644
+ display: "flex",
5645
+ flexDirection: "column",
5646
+ alignItems: "center",
5647
+ justifyContent: "center",
5648
+ paddingTop: 24,
5649
+ gap: 12
5650
+ };
5651
+ var headingStyle12 = (color) => ({
5652
+ fontSize: "1.25rem",
5653
+ fontWeight: 700,
5654
+ letterSpacing: "-0.02em",
5655
+ color,
5656
+ margin: "16px 0 4px",
5657
+ textAlign: "center"
5658
+ });
5659
+ var descriptionStyle2 = (color) => ({
5660
+ fontSize: "0.88rem",
5661
+ color,
5662
+ textAlign: "center",
5663
+ lineHeight: 1.6,
5664
+ maxWidth: 300,
5665
+ margin: 0
5666
+ });
5667
+ var amountBadgeStyle = (tokens) => ({
5668
+ display: "inline-block",
5669
+ padding: "8px 20px",
5670
+ background: tokens.bgInput,
5671
+ border: `1px solid ${tokens.border}`,
5672
+ borderRadius: 999,
5673
+ fontSize: "0.95rem",
5674
+ fontWeight: 600,
5675
+ color: tokens.text,
5676
+ marginTop: 8
5677
+ });
5678
+ function OfferSetupScreen({
5679
+ amount,
5680
+ currency,
5681
+ onSetup,
5682
+ onDone
5683
+ }) {
5684
+ const { tokens } = useSwypeConfig();
5685
+ return /* @__PURE__ */ jsx(
5686
+ ScreenLayout,
5687
+ {
5688
+ footer: /* @__PURE__ */ jsxs(Fragment, { children: [
5689
+ /* @__PURE__ */ jsx(PrimaryButton, { onClick: onSetup, children: "Set up One-Tap" }),
5690
+ /* @__PURE__ */ jsx("div", { style: { marginTop: 10 }, children: /* @__PURE__ */ jsx(OutlineButton, { onClick: onDone, children: "Not now" }) }),
5691
+ /* @__PURE__ */ jsx(PoweredByFooter, {})
5692
+ ] }),
5693
+ children: /* @__PURE__ */ jsxs("div", { style: contentStyle11, children: [
5694
+ /* @__PURE__ */ jsx(IconCircle, { variant: "success", size: 64, children: /* @__PURE__ */ jsx("svg", { width: "32", height: "32", viewBox: "0 0 24 24", fill: "none", children: /* @__PURE__ */ jsx("path", { d: "M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41L9 16.17z", fill: tokens.success }) }) }),
5695
+ /* @__PURE__ */ jsxs("h2", { style: headingStyle13(tokens.text), children: [
5696
+ "$",
5697
+ amount.toFixed(2),
5698
+ " deposited"
5699
+ ] }),
5700
+ /* @__PURE__ */ jsx("p", { style: subtitleStyle10(tokens.textSecondary), children: "Your transfer is complete!" }),
5701
+ /* @__PURE__ */ jsxs("div", { style: cardStyle2(tokens), children: [
5702
+ /* @__PURE__ */ jsxs("div", { style: cardIconRow, children: [
5703
+ /* @__PURE__ */ jsx("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", children: /* @__PURE__ */ jsx("path", { d: "M13 10V3L4 14h7v7l9-11h-7z", fill: tokens.accent }) }),
5704
+ /* @__PURE__ */ jsx("strong", { style: { color: tokens.text }, children: "Enable One-Tap deposits" })
5705
+ ] }),
5706
+ /* @__PURE__ */ jsx("p", { style: cardBodyStyle(tokens.textSecondary), children: "Next time, deposit with a single tap \u2014 no wallet signing needed. Set up takes about 30 seconds." })
5707
+ ] })
5708
+ ] })
5709
+ }
5710
+ );
5711
+ }
5712
+ var contentStyle11 = {
5713
+ flex: 1,
5714
+ display: "flex",
5715
+ flexDirection: "column",
5716
+ alignItems: "center",
5717
+ paddingTop: 48
5718
+ };
5719
+ var headingStyle13 = (color) => ({
5720
+ fontSize: "1.5rem",
5721
+ fontWeight: 700,
5722
+ letterSpacing: "-0.02em",
5723
+ color,
5724
+ margin: "20px 0 4px"
5725
+ });
5726
+ var subtitleStyle10 = (color) => ({
5727
+ fontSize: "0.9rem",
5728
+ color,
5729
+ margin: "0 0 28px"
5730
+ });
5731
+ var cardStyle2 = (tokens) => ({
5732
+ width: "100%",
5733
+ padding: "18px 16px",
5734
+ background: tokens.bgInput,
5735
+ border: `1px solid ${tokens.border}`,
5736
+ borderRadius: 20
5737
+ });
5738
+ var cardIconRow = {
5739
+ display: "flex",
5740
+ alignItems: "center",
5741
+ gap: 8,
5742
+ fontSize: "0.92rem",
5743
+ marginBottom: 6
5744
+ };
5745
+ var cardBodyStyle = (color) => ({
5746
+ fontSize: "0.84rem",
5747
+ color,
5748
+ lineHeight: 1.6,
5749
+ margin: 0
5750
+ });
5751
+ function SetupCompleteScreen({ onDone }) {
5752
+ const { tokens } = useSwypeConfig();
5753
+ return /* @__PURE__ */ jsx(
5754
+ ScreenLayout,
5755
+ {
5756
+ footer: /* @__PURE__ */ jsxs(Fragment, { children: [
5757
+ /* @__PURE__ */ jsx(PrimaryButton, { onClick: onDone, children: "Done" }),
5758
+ /* @__PURE__ */ jsx(PoweredByFooter, {})
5759
+ ] }),
5760
+ children: /* @__PURE__ */ jsxs("div", { style: contentStyle12, children: [
5761
+ /* @__PURE__ */ jsx(IconCircle, { variant: "success", size: 64, children: /* @__PURE__ */ jsx("svg", { width: "32", height: "32", viewBox: "0 0 24 24", fill: "none", children: /* @__PURE__ */ jsx("path", { d: "M13 10V3L4 14h7v7l9-11h-7z", fill: tokens.accent }) }) }),
5762
+ /* @__PURE__ */ jsx("h2", { style: headingStyle14(tokens.text), children: "One-Tap deposits are ready!" }),
5763
+ /* @__PURE__ */ jsx("p", { style: subtitleStyle11(tokens.textSecondary), children: "Next time you deposit, just tap confirm \u2014 no wallet signing needed." })
5764
+ ] })
5765
+ }
5766
+ );
5767
+ }
5768
+ var contentStyle12 = {
5769
+ flex: 1,
5770
+ display: "flex",
5771
+ flexDirection: "column",
5772
+ alignItems: "center",
5773
+ justifyContent: "center",
5774
+ paddingTop: 24
5775
+ };
5776
+ var headingStyle14 = (color) => ({
5777
+ fontSize: "1.5rem",
5778
+ fontWeight: 700,
5779
+ letterSpacing: "-0.02em",
5780
+ color,
5781
+ margin: "20px 0 8px",
5782
+ textAlign: "center"
5783
+ });
5784
+ var subtitleStyle11 = (color) => ({
5785
+ fontSize: "0.9rem",
5786
+ color,
5787
+ textAlign: "center",
5788
+ lineHeight: 1.6,
5789
+ maxWidth: 300,
5790
+ margin: 0
5791
+ });
5792
+ var GUEST_STEPS = /* @__PURE__ */ new Set([
5793
+ "guest-deposit",
5794
+ "guest-connecting",
5795
+ "guest-signing",
5796
+ "offer-setup",
5797
+ "setup-complete"
5798
+ ]);
5399
5799
  var LINK_STEPS = /* @__PURE__ */ new Set([
5400
5800
  "create-passkey",
5401
5801
  "verify-passkey",
@@ -5412,6 +5812,7 @@ var DEPOSIT_STEPS = /* @__PURE__ */ new Set([
5412
5812
  "success"
5413
5813
  ]);
5414
5814
  function getFlowPhase(step, previousStep) {
5815
+ if (GUEST_STEPS.has(step)) return null;
5415
5816
  if (LINK_STEPS.has(step)) return "link";
5416
5817
  if (DEPOSIT_STEPS.has(step)) return "deposit";
5417
5818
  if (step === "token-picker" || step === "select-source") {
@@ -5461,6 +5862,57 @@ function StepRendererContent({
5461
5862
  if (!ready) {
5462
5863
  return /* @__PURE__ */ jsx(SwypeLoadingScreen, {});
5463
5864
  }
5865
+ if (step === "guest-deposit") {
5866
+ const parsedAmt = depositAmount != null ? depositAmount : 5;
5867
+ return /* @__PURE__ */ jsx(
5868
+ GuestDepositScreen,
5869
+ {
5870
+ amount: parsedAmt,
5871
+ currency: "USD",
5872
+ merchantName,
5873
+ onConfirm: handlers.onGuestConfirm,
5874
+ onSignIn: handlers.onGuestSignIn,
5875
+ onBack,
5876
+ loading: state.loadingData,
5877
+ error: state.error
5878
+ }
5879
+ );
5880
+ }
5881
+ if (step === "guest-connecting" || step === "guest-signing") {
5882
+ const parsedAmt = depositAmount != null ? depositAmount : 5;
5883
+ const phase = step === "guest-connecting" ? "connecting" : "signing";
5884
+ return /* @__PURE__ */ jsx(
5885
+ GuestWalletScreen,
5886
+ {
5887
+ phase: state.guestQuote ? step === "guest-signing" ? "signing" : "fetching-quote" : phase,
5888
+ amount: parsedAmt,
5889
+ currency: "USD",
5890
+ onBack: () => handlers.onNavigate("guest-deposit"),
5891
+ error: state.error,
5892
+ onRetry: handlers.onGuestRetry
5893
+ }
5894
+ );
5895
+ }
5896
+ if (step === "offer-setup") {
5897
+ const displayAmount = parseFloat(state.amount) || (depositAmount ?? 5);
5898
+ return /* @__PURE__ */ jsx(
5899
+ OfferSetupScreen,
5900
+ {
5901
+ amount: displayAmount,
5902
+ currency: "USD",
5903
+ onSetup: handlers.onOfferSetup,
5904
+ onDone: onDismiss ?? handlers.onNewPayment
5905
+ }
5906
+ );
5907
+ }
5908
+ if (step === "setup-complete") {
5909
+ return /* @__PURE__ */ jsx(
5910
+ SetupCompleteScreen,
5911
+ {
5912
+ onDone: onDismiss ?? handlers.onNewPayment
5913
+ }
5914
+ );
5915
+ }
5464
5916
  if (step === "login") {
5465
5917
  if (authenticated) {
5466
5918
  return /* @__PURE__ */ jsx(SwypeLoadingScreen, {});
@@ -5692,8 +6144,9 @@ function StepRendererContent({
5692
6144
  );
5693
6145
  }
5694
6146
  if (step === "success") {
5695
- const succeeded = state.transfer?.status === "COMPLETED";
5696
- const displayAmount = state.transfer?.amount?.amount ?? 0;
6147
+ const isGuest = state.isGuestFlow && state.guestTransferComplete;
6148
+ const succeeded = isGuest ? true : state.transfer?.status === "COMPLETED";
6149
+ const displayAmount = isGuest ? parseFloat(state.amount) || (depositAmount ?? 0) : state.transfer?.amount?.amount ?? 0;
5697
6150
  const displayCurrency = state.transfer?.amount?.currency ?? "USD";
5698
6151
  return /* @__PURE__ */ jsx(
5699
6152
  SuccessScreen,
@@ -5703,15 +6156,17 @@ function StepRendererContent({
5703
6156
  succeeded,
5704
6157
  error: state.error,
5705
6158
  merchantName,
5706
- sourceName,
5707
- remainingLimit: succeeded ? (() => {
6159
+ sourceName: isGuest ? void 0 : sourceName,
6160
+ remainingLimit: !isGuest && succeeded ? (() => {
5708
6161
  const limit = selectedSource != null ? selectedSource.remainingAllowance ?? null : selectedAccount?.remainingAllowance ?? null;
5709
6162
  if (limit == null) return null;
5710
6163
  return limit > displayAmount ? limit - displayAmount : 0;
5711
6164
  })() : void 0,
5712
6165
  onDone: onDismiss ?? handlers.onNewPayment,
5713
6166
  onLogout: handlers.onLogout,
5714
- autoCloseSeconds
6167
+ autoCloseSeconds: isGuest ? void 0 : autoCloseSeconds,
6168
+ isGuestTransfer: isGuest,
6169
+ onOfferSetup: () => handlers.onNavigate("offer-setup")
5715
6170
  }
5716
6171
  );
5717
6172
  }
@@ -5783,7 +6238,7 @@ var PaymentErrorBoundary = class extends Component {
5783
6238
  /* @__PURE__ */ jsx("path", { d: "M12 8v5", stroke: "#ef4444", strokeWidth: "1.5", strokeLinecap: "round" }),
5784
6239
  /* @__PURE__ */ jsx("circle", { cx: "12", cy: "16", r: "0.75", fill: "#ef4444" })
5785
6240
  ] }) }),
5786
- /* @__PURE__ */ jsx("h2", { style: headingStyle12, children: "Something went wrong" }),
6241
+ /* @__PURE__ */ jsx("h2", { style: headingStyle15, children: "Something went wrong" }),
5787
6242
  /* @__PURE__ */ jsx("p", { style: messageStyle, children: "An unexpected error occurred. Please try again." }),
5788
6243
  /* @__PURE__ */ jsx("button", { type: "button", onClick: this.handleReset, style: buttonStyle3, children: "Try again" })
5789
6244
  ] });
@@ -5803,7 +6258,7 @@ var containerStyle9 = {
5803
6258
  var iconStyle3 = {
5804
6259
  marginBottom: 20
5805
6260
  };
5806
- var headingStyle12 = {
6261
+ var headingStyle15 = {
5807
6262
  fontSize: "1.25rem",
5808
6263
  fontWeight: 700,
5809
6264
  color: "#1a1a1a",
@@ -7501,6 +7956,183 @@ function usePaymentEffects(deps) {
7501
7956
  }
7502
7957
  }, [pendingOneTapSetupAction, state.step, reloadAccounts, authExecutor, dispatch, oneTapLimitSavedDuringSetupRef]);
7503
7958
  }
7959
+ var GUEST_POLL_INTERVAL_MS = 2e3;
7960
+ var GUEST_POLL_MAX_ATTEMPTS = 150;
7961
+ function useGuestTransferHandlers(deps) {
7962
+ const {
7963
+ dispatch,
7964
+ apiBaseUrl,
7965
+ destination,
7966
+ depositAmount,
7967
+ idempotencyKey,
7968
+ merchantAuthorization,
7969
+ onComplete,
7970
+ onError,
7971
+ sourceChainId,
7972
+ sourceToken,
7973
+ destinationChainId
7974
+ } = deps;
7975
+ const { connectAsync, connectors } = useConnect();
7976
+ const { address, chainId: connectedChainId, isConnected } = useAccount();
7977
+ const { sendTransactionAsync } = useSendTransaction();
7978
+ const { switchChainAsync } = useSwitchChain();
7979
+ const guestPollingRef = useRef(false);
7980
+ const pollGuestTransfer = useCallback(async (transferId) => {
7981
+ if (guestPollingRef.current) return;
7982
+ guestPollingRef.current = true;
7983
+ try {
7984
+ for (let i = 0; i < GUEST_POLL_MAX_ATTEMPTS; i++) {
7985
+ await new Promise((r) => setTimeout(r, GUEST_POLL_INTERVAL_MS));
7986
+ if (!guestPollingRef.current) return;
7987
+ const result = await fetchGuestTransfer(apiBaseUrl, transferId);
7988
+ if (result.status === "COMPLETED") {
7989
+ dispatch({ type: "GUEST_TRANSFER_COMPLETED", transferId });
7990
+ onComplete?.(result);
7991
+ return;
7992
+ }
7993
+ if (result.status === "FAILED") {
7994
+ dispatch({ type: "GUEST_TRANSFER_FAILED", error: "Transfer failed." });
7995
+ onError?.("Transfer failed.");
7996
+ return;
7997
+ }
7998
+ }
7999
+ dispatch({ type: "GUEST_TRANSFER_FAILED", error: "Transfer timed out." });
8000
+ onError?.("Transfer timed out.");
8001
+ } finally {
8002
+ guestPollingRef.current = false;
8003
+ }
8004
+ }, [apiBaseUrl, dispatch, onComplete, onError]);
8005
+ const executeGuestFlow = useCallback(async () => {
8006
+ if (!merchantAuthorization) {
8007
+ dispatch({ type: "SET_ERROR", error: "Missing merchant authorization." });
8008
+ return;
8009
+ }
8010
+ const amount = depositAmount ?? 5;
8011
+ try {
8012
+ dispatch({ type: "NAVIGATE", step: "guest-connecting" });
8013
+ let walletAddress = address;
8014
+ let walletChainId = connectedChainId;
8015
+ if (!isConnected || !walletAddress) {
8016
+ const injected2 = connectors.find((c) => c.id === "injected" || c.id === "metaMask");
8017
+ if (!injected2) {
8018
+ dispatch({ type: "SET_ERROR", error: "No wallet found. Please install a browser wallet." });
8019
+ dispatch({ type: "NAVIGATE", step: "guest-deposit" });
8020
+ return;
8021
+ }
8022
+ const result = await connectAsync({ connector: injected2 });
8023
+ walletAddress = result.accounts[0];
8024
+ walletChainId = result.chainId;
8025
+ }
8026
+ if (!walletAddress) {
8027
+ dispatch({ type: "SET_ERROR", error: "Failed to connect wallet." });
8028
+ dispatch({ type: "NAVIGATE", step: "guest-deposit" });
8029
+ return;
8030
+ }
8031
+ dispatch({ type: "GUEST_WALLET_CONNECTED", address: walletAddress, chainId: walletChainId ?? 1 });
8032
+ const effectiveSourceChainId = sourceChainId ?? walletChainId ?? 8453;
8033
+ const effectiveDestChainId = destinationChainId ?? 8453;
8034
+ const effectiveSourceToken = sourceToken ?? destination.token.address;
8035
+ const quote = await fetchGuestQuote(apiBaseUrl, {
8036
+ merchantAuthorization,
8037
+ sourceAddress: walletAddress,
8038
+ sourceChainId: effectiveSourceChainId,
8039
+ sourceToken: effectiveSourceToken,
8040
+ destinationChainId: effectiveDestChainId,
8041
+ destinationAddress: destination.address,
8042
+ destinationToken: destination.token.address,
8043
+ amount: String(Math.round(amount * 1e6))
8044
+ });
8045
+ dispatch({ type: "GUEST_QUOTE_RECEIVED", quote });
8046
+ if (quote.steps.length === 0) {
8047
+ dispatch({ type: "SET_ERROR", error: "No bridge route available." });
8048
+ dispatch({ type: "NAVIGATE", step: "guest-deposit" });
8049
+ return;
8050
+ }
8051
+ const targetChainId = quote.steps[0].chainId;
8052
+ if (walletChainId !== targetChainId) {
8053
+ try {
8054
+ await switchChainAsync({ chainId: targetChainId });
8055
+ } catch {
8056
+ dispatch({ type: "SET_ERROR", error: `Please switch your wallet to chain ${targetChainId}.` });
8057
+ dispatch({ type: "NAVIGATE", step: "guest-deposit" });
8058
+ return;
8059
+ }
8060
+ }
8061
+ let lastTxHash;
8062
+ for (const step of quote.steps) {
8063
+ const txHash = await sendTransactionAsync({
8064
+ to: step.to,
8065
+ data: step.data || "0x",
8066
+ value: step.value ? BigInt(step.value) : 0n,
8067
+ chainId: step.chainId
8068
+ });
8069
+ lastTxHash = txHash;
8070
+ }
8071
+ if (!lastTxHash) {
8072
+ dispatch({ type: "SET_ERROR", error: "Transaction was not submitted." });
8073
+ dispatch({ type: "NAVIGATE", step: "guest-deposit" });
8074
+ return;
8075
+ }
8076
+ dispatch({ type: "GUEST_DEPOSIT_SIGNED", txHash: lastTxHash });
8077
+ const transferResult = await createGuestTransfer(apiBaseUrl, {
8078
+ id: idempotencyKey ?? crypto.randomUUID(),
8079
+ merchantAuthorization,
8080
+ requestId: quote.requestId,
8081
+ originTxHash: lastTxHash,
8082
+ sourceChainId: effectiveSourceChainId,
8083
+ sourceAddress: walletAddress,
8084
+ destinationChainId: effectiveDestChainId,
8085
+ destinationAddress: destination.address,
8086
+ destinationToken: destination.token.address,
8087
+ amount: { amount, currency: "USD" }
8088
+ });
8089
+ dispatch({ type: "GUEST_TRANSFER_SUBMITTED", transferId: transferResult.id });
8090
+ await pollGuestTransfer(transferResult.id);
8091
+ } catch (err) {
8092
+ const message = err instanceof Error ? err.message : "Transaction failed.";
8093
+ if (message.includes("rejected") || message.includes("denied") || message.includes("User rejected")) {
8094
+ dispatch({ type: "SET_ERROR", error: "Transaction was rejected." });
8095
+ dispatch({ type: "NAVIGATE", step: "guest-deposit" });
8096
+ } else {
8097
+ dispatch({ type: "SET_ERROR", error: message });
8098
+ dispatch({ type: "NAVIGATE", step: "guest-deposit" });
8099
+ }
8100
+ onError?.(message);
8101
+ }
8102
+ }, [
8103
+ address,
8104
+ apiBaseUrl,
8105
+ connectAsync,
8106
+ connectedChainId,
8107
+ connectors,
8108
+ depositAmount,
8109
+ destination,
8110
+ destinationChainId,
8111
+ dispatch,
8112
+ idempotencyKey,
8113
+ isConnected,
8114
+ merchantAuthorization,
8115
+ onComplete,
8116
+ onError,
8117
+ pollGuestTransfer,
8118
+ sendTransactionAsync,
8119
+ sourceChainId,
8120
+ sourceToken,
8121
+ switchChainAsync
8122
+ ]);
8123
+ const handleGuestConfirm = useCallback(() => {
8124
+ void executeGuestFlow();
8125
+ }, [executeGuestFlow]);
8126
+ const handleGuestRetry = useCallback(() => {
8127
+ dispatch({ type: "SET_ERROR", error: null });
8128
+ dispatch({ type: "NAVIGATE", step: "guest-deposit" });
8129
+ }, [dispatch]);
8130
+ return {
8131
+ handleGuestConfirm,
8132
+ handleGuestRetry,
8133
+ guestPollingRef
8134
+ };
8135
+ }
7504
8136
  function SwypePayment(props) {
7505
8137
  const resetKey = useRef(0);
7506
8138
  const handleBoundaryReset = useCallback(() => {
@@ -7518,7 +8150,10 @@ function SwypePaymentInner({
7518
8150
  merchantName,
7519
8151
  onBack,
7520
8152
  onDismiss,
7521
- autoCloseSeconds
8153
+ autoCloseSeconds,
8154
+ sourceChainId,
8155
+ sourceToken,
8156
+ destinationChainId
7522
8157
  }) {
7523
8158
  const { apiBaseUrl, depositAmount } = useSwypeConfig();
7524
8159
  const { ready, authenticated, logout, getAccessToken } = usePrivy();
@@ -7611,6 +8246,19 @@ function SwypePaymentInner({
7611
8246
  selectSourceChainName: sourceSelection.selectSourceChainName,
7612
8247
  selectSourceTokenSymbol: sourceSelection.selectSourceTokenSymbol
7613
8248
  });
8249
+ const guest = useGuestTransferHandlers({
8250
+ dispatch,
8251
+ apiBaseUrl,
8252
+ destination,
8253
+ depositAmount,
8254
+ idempotencyKey,
8255
+ merchantAuthorization,
8256
+ onComplete,
8257
+ onError,
8258
+ sourceChainId,
8259
+ sourceToken,
8260
+ destinationChainId
8261
+ });
7614
8262
  const handleNewPayment = useCallback(() => {
7615
8263
  clearMobileFlowState();
7616
8264
  transfer.processingStartedAtRef.current = null;
@@ -7711,7 +8359,12 @@ function SwypePaymentInner({
7711
8359
  onSetupOneTap: oneTapSetup.handleSetupOneTap,
7712
8360
  onSelectToken: provider.handleNavigateToTokenPicker,
7713
8361
  onSelectAuthorizedToken: provider.handleSelectAuthorizedToken,
7714
- onAuthorizeToken: provider.handleAuthorizeToken
8362
+ onAuthorizeToken: provider.handleAuthorizeToken,
8363
+ onGuestConfirm: guest.handleGuestConfirm,
8364
+ onGuestSignIn: () => dispatch({ type: "START_SETUP_FLOW" }),
8365
+ onGuestRetry: guest.handleGuestRetry,
8366
+ onOfferSetup: () => dispatch({ type: "START_SETUP_FLOW" }),
8367
+ onSetupComplete: () => dispatch({ type: "SETUP_FLOW_COMPLETE" })
7715
8368
  }), [
7716
8369
  auth,
7717
8370
  passkey,
@@ -7720,6 +8373,7 @@ function SwypePaymentInner({
7720
8373
  mobileFlow,
7721
8374
  sourceSelection,
7722
8375
  oneTapSetup,
8376
+ guest,
7723
8377
  handleLogout,
7724
8378
  handleNewPayment
7725
8379
  ]);
@@ -7760,6 +8414,6 @@ function SwypePaymentInner({
7760
8414
  );
7761
8415
  }
7762
8416
 
7763
- export { AdvancedSourceScreen, FlowPhaseProvider, IconCircle, InfoBanner, OutlineButton, PasskeyIframeBlockedError, PasskeyScreen, PoweredByFooter, PrimaryButton, SWYPE_LOGO, SWYPE_MASCOT, ScreenHeader, ScreenLayout, SelectSourceScreen, SettingsMenu, SetupScreen, Spinner, StepList, SwypeLoadingScreen, SwypePayment, SwypeProvider, TokenPickerScreen, buildPasskeyPopupOptions, createPasskeyCredential, createPasskeyViaPopup, darkTheme, deviceHasPasskey, findDevicePasskey, findDevicePasskeyViaPopup, getTheme, lightTheme, resolvePasskeyRpId, api_exports as swypeApi, useAuthorizationExecutor, useSwypeConfig, useSwypeDepositAmount, useTransferPolling, useTransferSigning };
8417
+ export { AdvancedSourceScreen, FlowPhaseProvider, GuestDepositScreen, GuestWalletScreen, IconCircle, InfoBanner, OfferSetupScreen, OutlineButton, PasskeyIframeBlockedError, PasskeyScreen, PoweredByFooter, PrimaryButton, SWYPE_LOGO, SWYPE_MASCOT, ScreenHeader, ScreenLayout, SelectSourceScreen, SettingsMenu, SetupCompleteScreen, SetupScreen, Spinner, StepList, SwypeLoadingScreen, SwypePayment, SwypeProvider, TokenPickerScreen, buildPasskeyPopupOptions, createPasskeyCredential, createPasskeyViaPopup, darkTheme, deviceHasPasskey, findDevicePasskey, findDevicePasskeyViaPopup, getTheme, lightTheme, resolvePasskeyRpId, api_exports as swypeApi, useAuthorizationExecutor, useSwypeConfig, useSwypeDepositAmount, useTransferPolling, useTransferSigning };
7764
8418
  //# sourceMappingURL=index.js.map
7765
8419
  //# sourceMappingURL=index.js.map