@daimo/pay 1.8.1 → 1.8.2

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/build/index.d.ts CHANGED
@@ -339,6 +339,7 @@ type WalletConfigProps = {
339
339
  shouldDeeplinkDesktop?: boolean;
340
340
  showInMobileConnectors?: boolean;
341
341
  isWcMobileConnector?: boolean;
342
+ isSolanaOnly?: boolean;
342
343
  };
343
344
 
344
345
  type TrpcClient = CreateTRPCClient<AppRouter>;
package/build/index.js CHANGED
@@ -1,18 +1,18 @@
1
1
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
2
2
  import { ExternalPaymentOptions, assert, assertNotNull, debugJson, supportedChains, ethereum, isCCTPV1Chain, getOrderDestChainId, readDaimoPayOrderID, writeDaimoPayOrderID, getChainName, DaimoPayOrderMode, arbitrum as arbitrum$1, base as base$2, blast as blast$1, bsc as bsc$1, linea as linea$1, mantle as mantle$1, optimism as optimism$1, polygon as polygon$1, worldchain as worldchain$1, getAddressContraction, DaimoPayOrderStatusDest, getChainExplorerTxUrl, DaimoPayIntentStatus, retryBackoff, DaimoPayOrderStatusSource, DaimoPayEventType, getDaimoPayOrderView } from '@daimo/pay-common';
3
3
  import { Buffer } from 'buffer';
4
- import React, { useState, useEffect, createContext, useRef, useCallback, useLayoutEffect, useMemo, createElement } from 'react';
4
+ import React, { useState, useEffect, createContext, useMemo, useRef, useCallback, useLayoutEffect, createElement } from 'react';
5
5
  import styled$1, { css, keyframes, ThemeProvider } from 'styled-components';
6
6
  import { http, useConfig, useAccountEffect, useWriteContract, useSendTransaction, useAccount, useEnsName, useConnectors as useConnectors$1, useSwitchChain, useConnect as useConnect$1, useDisconnect, useChainId, WagmiContext, createConfig, useEnsAddress, useEnsAvatar } from 'wagmi';
7
7
  import { mainnet, base as base$1, polygon, optimism, arbitrum, linea, bsc, sepolia, baseSepolia, worldchain, blast, mantle } from 'wagmi/chains';
8
8
  import { safe, injected, coinbaseWallet, walletConnect } from '@wagmi/connectors';
9
9
  import { useConnection, useWallet as useWallet$1, ConnectionProvider, WalletProvider } from '@solana/wallet-adapter-react';
10
10
  import { hexToBytes, zeroAddress, erc20Abi, getAddress, formatUnits, parseUnits } from 'viem';
11
+ import { detect } from 'detect-browser';
11
12
  import { VersionedTransaction } from '@solana/web3.js';
12
13
  import { createTRPCClient, httpBatchLink } from '@trpc/client';
13
14
  import { motion, AnimatePresence, MotionConfig } from 'framer-motion';
14
15
  import { createPortal } from 'react-dom';
15
- import { detect } from 'detect-browser';
16
16
  import { useTransition } from 'react-transition-state';
17
17
  import ResizeObserver from 'resize-observer-polyfill';
18
18
  import useMeasure from 'react-use-measure';
@@ -22,7 +22,7 @@ import { WalletSignTransactionError, WalletSendTransactionError } from '@solana/
22
22
  import { normalize } from 'viem/ens';
23
23
 
24
24
  var name = "@daimo/pay";
25
- var version = "1.8.1";
25
+ var version = "1.8.2";
26
26
  var author = "Daimo";
27
27
  var homepage = "https://pay.daimo.com";
28
28
  var license = "BSD-2-Clause license";
@@ -61,7 +61,7 @@ var keywords = [
61
61
  "crypto"
62
62
  ];
63
63
  var dependencies = {
64
- "@daimo/pay-common": "1.8.1",
64
+ "@daimo/pay-common": "1.8.2",
65
65
  "@rollup/plugin-typescript": "^12.1.2",
66
66
  "@solana/wallet-adapter-base": "^0.9.23",
67
67
  "@solana/wallet-adapter-react": "^0.15.35",
@@ -797,6 +797,7 @@ const walletConfigs = {
797
797
  const ref = encodeURIComponent(window.location.origin);
798
798
  return `https://solflare.com/ul/v1/browse/${url}?ref=${ref}`;
799
799
  },
800
+ isSolanaOnly: true,
800
801
  },
801
802
  // steak: {
802
803
  // name: "Steak",
@@ -948,7 +949,6 @@ function extractWcWalletFromProvider(p, log) {
948
949
  let deeplinkUrl;
949
950
  try {
950
951
  deeplinkUrl = JSON.parse(deeplinkJson).href;
951
- console.log(`[WCWALLET] deeplinkUrl: ${deeplinkUrl}`);
952
952
  }
953
953
  catch { }
954
954
  wallet = {
@@ -1055,6 +1055,47 @@ function useExternalPaymentOptions({ trpc, filterIds, platform, usdRequired, mod
1055
1055
  return { options, loading };
1056
1056
  }
1057
1057
 
1058
+ const detectBrowser = () => {
1059
+ const browser = detect();
1060
+ return browser?.name ?? "";
1061
+ };
1062
+ const detectOS = () => {
1063
+ const browser = detect();
1064
+ return browser?.os ?? "";
1065
+ };
1066
+ const isIOS = () => {
1067
+ const os = detectOS();
1068
+ return os.toLowerCase().includes("ios");
1069
+ };
1070
+ const isAndroid = () => {
1071
+ const os = detectOS();
1072
+ return os.toLowerCase().includes("android");
1073
+ };
1074
+ const isMobile = () => {
1075
+ const os = detectOS().toLowerCase();
1076
+ return os.includes("android") || os.includes("ios");
1077
+ };
1078
+ function flattenChildren(children) {
1079
+ const childrenArray = React.Children.toArray(children);
1080
+ return childrenArray.reduce((flatChildren, child) => {
1081
+ if (child.type === React.Fragment) {
1082
+ return flatChildren.concat(flattenChildren(child.props.children));
1083
+ }
1084
+ flatChildren.push(child);
1085
+ return flatChildren;
1086
+ }, []);
1087
+ }
1088
+ const isWalletConnectConnector = (connectorId) => connectorId === "walletConnect";
1089
+ const isCoinbaseWalletConnector = (connectorId) => connectorId === "coinbaseWalletSDK";
1090
+ const isSafeConnector = (connectorId) => connectorId === "safe";
1091
+ const isInjectedConnector = (connectorId) => connectorId === "injected";
1092
+
1093
+ function useIsMobile() {
1094
+ const isI = useMemo(isIOS, []);
1095
+ const isA = useMemo(isAndroid, []);
1096
+ return { isMobile: isI || isA, isIOS: isI, isAndroid: isA };
1097
+ }
1098
+
1058
1099
  function useOrderUsdLimits({ trpc }) {
1059
1100
  const [limits, setLimits] = useState({});
1060
1101
  const [loading, setLoading] = useState(false);
@@ -1420,6 +1461,7 @@ function usePaymentState({ trpc, lockPayParams, daimoPayOrder, setDaimoPayOrder,
1420
1461
  });
1421
1462
  return depositAddressOption;
1422
1463
  };
1464
+ const { isIOS } = useIsMobile();
1423
1465
  /// Hydrates an order to prepare for paying in an in-wallet browser via
1424
1466
  /// deeplink. Then, if wallet is specified, opens in that wallet.
1425
1467
  const payWithWallet = async (wallet, amountUsd) => {
@@ -1441,7 +1483,10 @@ function usePaymentState({ trpc, lockPayParams, daimoPayOrder, setDaimoPayOrder,
1441
1483
  assert(wallet.getDaimoPayDeeplink != null, "payWithWallet: missing deeplink");
1442
1484
  const payId = writeDaimoPayOrderID(hydratedOrder.id);
1443
1485
  const deeplink = wallet.getDaimoPayDeeplink(payId);
1444
- window.open(deeplink, "_blank");
1486
+ // if we are in IOS, we don't open the deeplink in a new window, because it will not work, the link will be opened in the page WAITING_WALLET
1487
+ if (!isIOS) {
1488
+ window.open(deeplink, "_blank");
1489
+ }
1445
1490
  setSelectedWalletDeepLink(deeplink);
1446
1491
  setRoute(ROUTES.WAITING_WALLET, {
1447
1492
  amountUsd,
@@ -2862,41 +2907,6 @@ const Portal = (props) => {
2862
2907
  return mounted ? createPortal(children, ref.current) : null;
2863
2908
  };
2864
2909
 
2865
- const detectBrowser = () => {
2866
- const browser = detect();
2867
- return browser?.name ?? "";
2868
- };
2869
- const detectOS = () => {
2870
- const browser = detect();
2871
- return browser?.os ?? "";
2872
- };
2873
- const isIOS = () => {
2874
- const os = detectOS();
2875
- return os.toLowerCase().includes("ios");
2876
- };
2877
- const isAndroid = () => {
2878
- const os = detectOS();
2879
- return os.toLowerCase().includes("android");
2880
- };
2881
- const isMobile = () => {
2882
- const os = detectOS().toLowerCase();
2883
- return os.includes("android") || os.includes("ios");
2884
- };
2885
- function flattenChildren(children) {
2886
- const childrenArray = React.Children.toArray(children);
2887
- return childrenArray.reduce((flatChildren, child) => {
2888
- if (child.type === React.Fragment) {
2889
- return flatChildren.concat(flattenChildren(child.props.children));
2890
- }
2891
- flatChildren.push(child);
2892
- return flatChildren;
2893
- }, []);
2894
- }
2895
- const isWalletConnectConnector = (connectorId) => connectorId === "walletConnect";
2896
- const isCoinbaseWalletConnector = (connectorId) => connectorId === "coinbaseWalletSDK";
2897
- const isSafeConnector = (connectorId) => connectorId === "safe";
2898
- const isInjectedConnector = (connectorId) => connectorId === "injected";
2899
-
2900
2910
  var defaultTheme = {
2901
2911
  mobileWidth: 560,
2902
2912
  };
@@ -6663,12 +6673,6 @@ styled(motion.div) `
6663
6673
  }
6664
6674
  `;
6665
6675
 
6666
- function useIsMobile() {
6667
- const isI = useMemo(isIOS, []);
6668
- const isA = useMemo(isAndroid, []);
6669
- return { isMobile: isI || isA, isIOS: isI, isAndroid: isA };
6670
- }
6671
-
6672
6676
  /**
6673
6677
  * This is a wrapper around wagmi's useConnect hook that adds some
6674
6678
  * additional functionality.
@@ -8446,6 +8450,9 @@ const MobileConnectors = () => {
8446
8450
  return false;
8447
8451
  if (!wallet.showInMobileConnectors)
8448
8452
  return false;
8453
+ // If the mobile wallet supports solana only, don't show it if we are not supporting solana has a payment method
8454
+ if (wallet.isSolanaOnly && !context.paymentState.showSolanaPaymentMethod)
8455
+ return false;
8449
8456
  return true;
8450
8457
  }) ?? [];
8451
8458
  const goToWallet = (wallet) => {
@@ -10139,6 +10146,7 @@ const Container$2 = styled.button `
10139
10146
  gap: 4px;
10140
10147
  cursor: pointer;
10141
10148
  width: fit-content;
10149
+ background: transparent;
10142
10150
  `;
10143
10151
  const IconWrapper = styled.div `
10144
10152
  opacity: ${({ $isFlipped }) => ($isFlipped ? 1 : 1)};
@@ -10169,6 +10177,7 @@ const Container$1 = styled.button `
10169
10177
  align-items: center;
10170
10178
  justify-content: center;
10171
10179
  gap: 4px;
10180
+ background: transparent;
10172
10181
  `;
10173
10182
  const InputField = styled.input `
10174
10183
  margin: 0;
@@ -10816,7 +10825,7 @@ function SelectMethod() {
10816
10825
  const { connected: isSolanaConnected, wallet: solanaWallet, wallets: solanaWallets, disconnect: disconnectSolana, publicKey, } = useWallet$1();
10817
10826
  const { setRoute, paymentState, wcWallet, log } = usePayContext();
10818
10827
  const { disconnectAsync } = useDisconnect();
10819
- const { daimoPayOrder, setSelectedExternalOption, externalPaymentOptions, showSolanaPaymentMethod, depositAddressOptions, senderEnsName, } = paymentState;
10828
+ const { setSelectedExternalOption, externalPaymentOptions, showSolanaPaymentMethod, depositAddressOptions, senderEnsName, } = paymentState;
10820
10829
  // Decide whether to show the connected eth account, solana account, or both.
10821
10830
  const showConnectedEth = isEthConnected;
10822
10831
  const showConnectedSolana = isSolanaConnected && showSolanaPaymentMethod;
@@ -11037,7 +11046,6 @@ function SelectToken() {
11037
11046
  const { isDepositFlow, walletPaymentOptions, setSelectedTokenOption } = paymentState;
11038
11047
  const { connector } = useAccount();
11039
11048
  const { connected: isSolanaConnected } = useWallet$1();
11040
- console.log("connector", connector);
11041
11049
  const optionsList = walletPaymentOptions.options?.map((option) => {
11042
11050
  const chainName = getChainName(option.balance.token.chainId);
11043
11051
  const titlePrice = isDepositFlow
@@ -11083,10 +11091,11 @@ function SelectToken() {
11083
11091
  disabled,
11084
11092
  };
11085
11093
  }) ?? [];
11086
- // IsAnotherMethodButtonVisible is true when there are token options and we are in desktop mode or in mobile mode using a wallet connect connector
11087
- const isAnotherMethodButtonVisible = (optionsList.length != 0 &&
11088
- (!isMobileFormat || isWalletConnectConnector(connector?.id))) ||
11089
- (optionsList.length == 0 && isSolanaConnected);
11094
+ // IsAnotherMethodButtonVisible is true when there are token options and we are in desktop mode or in mobile mode using a wallet connect connector or if we are connected to solana and evm in mobile mode
11095
+ const isAnotherMethodButtonVisible = optionsList.length > 0 &&
11096
+ (!isMobileFormat ||
11097
+ isWalletConnectConnector(connector?.id) ||
11098
+ isSolanaConnected);
11090
11099
  return (jsxs(PageContent, { children: [jsx(OrderHeader, { minified: true, showEth: true }), !walletPaymentOptions.isLoading && optionsList.length === 0 && (jsxs(ModalContent, { style: {
11091
11100
  display: "flex",
11092
11101
  alignItems: "center",
@@ -11352,7 +11361,9 @@ function getDaimoSolanaTokenKey(token) {
11352
11361
  const SelectSolanaToken = () => {
11353
11362
  const { paymentState, setRoute } = usePayContext();
11354
11363
  const { isDepositFlow, solanaPaymentOptions, setSelectedSolanaTokenOption } = paymentState;
11355
- const isMobileFormat = useIsMobile() || window?.innerWidth < defaultTheme.mobileWidth;
11364
+ const { isMobile } = useIsMobile();
11365
+ const isMobileFormat = isMobile || window?.innerWidth < defaultTheme.mobileWidth;
11366
+ const { isConnected: isEvmConnected } = useAccount();
11356
11367
  const optionsList = solanaPaymentOptions.options?.map((option) => {
11357
11368
  const titlePrice = isDepositFlow
11358
11369
  ? formatUsd(option.balance.usd)
@@ -11386,13 +11397,15 @@ const SelectSolanaToken = () => {
11386
11397
  disabled,
11387
11398
  };
11388
11399
  }) ?? [];
11400
+ // IsAnotherMethodButtonVisible is true when there are token options and we are in desktop mode or in mobile mode using a wallet connect connector or if we are connected to solana and evm in mobile mode
11401
+ const isAnotherMethodButtonVisible = optionsList.length > 0 && (!isMobileFormat || isEvmConnected);
11389
11402
  return (jsxs(PageContent, { children: [jsx(OrderHeader, { minified: true, showSolana: true }), !solanaPaymentOptions.isLoading && optionsList.length === 0 && (jsxs(ModalContent, { style: {
11390
11403
  display: "flex",
11391
11404
  alignItems: "center",
11392
11405
  justifyContent: "center",
11393
11406
  paddingTop: 16,
11394
11407
  paddingBottom: 16,
11395
- }, children: [jsx(ModalH1, { children: "Insufficient balance." }), jsx(SelectAnotherMethodButton, {})] })), jsx(OptionsList, { requiredSkeletons: 4, isLoading: solanaPaymentOptions.isLoading, options: optionsList, scrollHeight: isMobileFormat ? 225 : 300, orDivider: optionsList.length != 0 }), optionsList.length != 0 && jsx(SelectAnotherMethodButton, {})] }));
11408
+ }, children: [jsx(ModalH1, { children: "Insufficient balance." }), jsx(SelectAnotherMethodButton, {})] })), jsx(OptionsList, { requiredSkeletons: 4, isLoading: solanaPaymentOptions.isLoading, options: optionsList, scrollHeight: isAnotherMethodButtonVisible && isMobileFormat ? 225 : 300, orDivider: isAnotherMethodButtonVisible }), isAnotherMethodButtonVisible && jsx(SelectAnotherMethodButton, {})] }));
11396
11409
  };
11397
11410
 
11398
11411
  const WaitingDepositAddress = () => {
@@ -11548,7 +11561,7 @@ const DaimoPayModal = ({ mode, theme, customTheme, lang, }) => {
11548
11561
  const paymentState = context.paymentState;
11549
11562
  const { payParams, generatePreviewOrder, isDepositFlow, showSolanaPaymentMethod, setPaymentWaitingMessage, setSelectedExternalOption, setSelectedTokenOption, setSelectedSolanaTokenOption, setSelectedDepositAddressOption, setSelectedWallet, } = paymentState;
11550
11563
  const { isConnected: isEthConnected, connector, chain, address, } = useAccount();
11551
- useWallet$1();
11564
+ const { connected: isSolanaConnected } = useWallet$1();
11552
11565
  const chainIsSupported = useChainIsSupported(chain?.id);
11553
11566
  //if chain is unsupported we enforce a "switch chain" prompt
11554
11567
  const closeable = !(context.options?.enforceSupportedChains &&
@@ -11691,12 +11704,10 @@ const DaimoPayModal = ({ mode, theme, customTheme, lang, }) => {
11691
11704
  return;
11692
11705
  if (context.route !== ROUTES.SELECT_METHOD)
11693
11706
  return;
11694
- const canPayEth = paymentState.walletPaymentOptions.options?.some((o) => o.disabledReason == null);
11695
- const canPaySolana = paymentState.solanaPaymentOptions.options?.some((o) => o.disabledReason == null);
11696
11707
  // Skip to token selection if exactly one wallet is connected. If both
11697
11708
  // wallets are connected, stay on the SELECT_METHOD screen to allow the
11698
11709
  // user to select which wallet to use
11699
- if (canPayEth && !canPaySolana) {
11710
+ if (isEthConnected && !isSolanaConnected) {
11700
11711
  context.setRoute(ROUTES.SELECT_TOKEN, {
11701
11712
  event: "eth_connected_on_open",
11702
11713
  walletId: connector?.id,
@@ -11704,7 +11715,7 @@ const DaimoPayModal = ({ mode, theme, customTheme, lang, }) => {
11704
11715
  address,
11705
11716
  });
11706
11717
  }
11707
- else if (canPaySolana && !canPayEth) {
11718
+ else if (isSolanaConnected && !isEthConnected) {
11708
11719
  context.setRoute(ROUTES.SOLANA_SELECT_TOKEN, {
11709
11720
  event: "solana_connected_on_open",
11710
11721
  });