@daimo/pay 1.6.5 → 1.7.0

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.js CHANGED
@@ -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.6.5";
25
+ var version = "1.7.0";
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.6.5",
64
+ "@daimo/pay-common": "1.7.0",
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",
@@ -273,18 +273,6 @@ const useConnectCallback = ({ onConnect, onDisconnect, }) => {
273
273
  });
274
274
  };
275
275
 
276
- const isWalletInstalled = (name) => {
277
- if (typeof window === "undefined")
278
- return false;
279
- const { ethereum } = window;
280
- return !!(ethereum?.[`is${name}`] ||
281
- (ethereum?.providers &&
282
- ethereum?.providers.find((provider) => provider?.[`is${name}`])));
283
- };
284
- const isFamily = () => isWalletInstalled("Family");
285
- const isRainbow = () => isWalletInstalled("Rainbow");
286
- const isZerion = () => isWalletInstalled("Zerion");
287
-
288
276
  const Mock = ({ ...props }) => (jsxs("svg", { ...props, "aria-hidden": "true", width: "44", height: "44", viewBox: "0 0 44 44", fill: "none", xmlns: "http://www.w3.org/2000/svg", style: {
289
277
  background: "linear-gradient(180deg, #8995A9 0%, #424D5F 99.48%)",
290
278
  }, children: [jsx("path", { fillRule: "evenodd", clipRule: "evenodd", d: "M20.5611 8.12948C21.0082 7.90729 21.5007 7.79167 22 7.79167C22.4993 7.79167 22.9919 7.90729 23.439 8.12948L23.4408 8.1304L33.0387 12.9293C33.577 13.197 34.031 13.61 34.3478 14.121C34.6649 14.6323 34.833 15.2218 34.8333 15.8234V27.2595C34.833 27.8611 34.6649 28.4511 34.3478 28.9624C34.031 29.4733 33.578 29.8858 33.0398 30.1535L23.4411 34.9528C22.9919 35.1775 22.4963 35.2947 21.994 35.2947C21.4918 35.2947 20.9964 35.1777 20.5472 34.9529L10.9475 30.1531L10.9452 30.1519C10.4071 29.8808 9.95535 29.4646 9.6411 28.9504C9.32739 28.437 9.16312 27.8464 9.16673 27.2448L9.16675 27.2417L10.0004 27.2475H9.16673V27.2448V15.8239C9.16705 15.2223 9.33518 14.6322 9.65222 14.121C9.96906 13.61 10.4221 13.1976 10.9604 12.9298L20.5592 8.1304L20.5611 8.12948ZM21.3031 9.62267L11.8706 14.3389L22 19.4036L32.1294 14.3389L22.697 9.62267C22.4806 9.51531 22.2416 9.45905 22 9.45905C21.7585 9.45905 21.5194 9.51534 21.3031 9.62267ZM10.8341 15.8241C10.8341 15.7785 10.8362 15.733 10.8401 15.6878L21.1663 20.8509V33.3983L11.6955 28.6629C11.4352 28.5315 11.2159 28.3297 11.0638 28.0809C10.9116 27.8318 10.8321 27.5452 10.8341 27.2533L10.8341 27.2475V15.8241ZM22.8337 33.3923L32.2967 28.6608C32.5576 28.5312 32.7772 28.3313 32.9308 28.0836C33.0844 27.836 33.1658 27.5504 33.166 27.259V15.8243C33.1659 15.7786 33.1639 15.7331 33.1599 15.6878L22.8337 20.8509V33.3923Z", fill: "url(#paint0_linear_3546_7073)" }), jsx("path", { fillRule: "evenodd", clipRule: "evenodd", d: "M10.8341 15.8241C10.8341 15.7785 10.8362 15.733 10.8401 15.6878L21.1663 20.8509V33.3983L11.6955 28.6629C11.4352 28.5315 11.2159 28.3297 11.0638 28.0809C10.9116 27.8318 10.8321 27.5452 10.8341 27.2533L10.8341 27.2475V15.8241Z", fill: "url(#paint1_linear_3546_7073)", fillOpacity: "0.3" }), jsxs("defs", { children: [jsxs("linearGradient", { id: "paint0_linear_3546_7073", x1: "22", y1: "7.79167", x2: "22", y2: "35.2947", gradientUnits: "userSpaceOnUse", children: [jsx("stop", { stopColor: "white" }), jsx("stop", { offset: "1", stopColor: "white", stopOpacity: "0.7" })] }), jsxs("linearGradient", { id: "paint1_linear_3546_7073", x1: "22", y1: "7.79167", x2: "22", y2: "35.2947", gradientUnits: "userSpaceOnUse", children: [jsx("stop", { stopColor: "white" }), jsx("stop", { offset: "1", stopColor: "white", stopOpacity: "0.7" })] })] })] }));
@@ -389,7 +377,7 @@ const OtherWallets = ({ ...props }) => {
389
377
  overflow: "hidden",
390
378
  borderRadius: "27.5%",
391
379
  };
392
- return (jsxs("div", { style: column, ...props, children: [jsxs("div", { style: row, children: [jsx("div", { style: cell, children: jsx(WalletConnect, { background: true }) }), jsx("div", { style: cell, children: !isZerion() ? jsx(Zerion, {}) : jsx(Phantom, {}) })] }), jsxs("div", { style: row, children: [jsx("div", { style: cell, children: !isFamily() ? jsx(Family, {}) : jsx(ImToken, {}) }), jsx("div", { style: cell, children: !isRainbow() ? jsx(Rainbow, {}) : jsx(Trust, {}) })] })] }));
380
+ return (jsxs("div", { style: column, ...props, children: [jsxs("div", { style: row, children: [jsx("div", { style: cell, children: jsx(Rainbow, {}) }), jsx("div", { style: cell, children: jsx(WalletConnect, { background: true }) })] }), jsxs("div", { style: row, children: [jsx("div", { style: cell, children: jsx(Family, {}) }), jsx("div", { style: cell, children: jsx(Ledger, {}) })] })] }));
393
381
  };
394
382
  const Fordefi = ({ ...props }) => (jsxs("svg", { ...props, width: "88", height: "88", viewBox: "0 0 96 96", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [jsxs("g", { clipPath: "url(#clip0_14298_75627)", children: [jsx("path", { d: "M43.5075 62.5508H6V73.5954C6 79.2046 10.5379 83.7515 16.1357 83.7515H32.9997L43.5075 62.5508Z", fill: "#7994FF" }), jsx("path", { d: "M6.00098 39.1016H76.2075L68.0567 55.4841H6.00098V39.1016Z", fill: "#486DFF" }), jsx("path", { d: "M30.6398 12H6.09766V32.0282H89.8447V12H65.3025V26.9577H60.2423V12H35.7001V26.9577H30.6398V12Z", fill: "#5CD1FA" })] }), jsx("defs", { children: jsx("clipPath", { id: "clip0_14298_75627", children: jsx("rect", { width: "84", height: "72", fill: "white", transform: "translate(6 12)" }) }) })] }));
395
383
  const SquircleIcon = ({ icon, alt, }) => {
@@ -807,10 +795,19 @@ function useExtractWcWallet({ log, connector, }) {
807
795
  localStorage.removeItem("WALLETCONNECT_DEEPLINK_CHOICE");
808
796
  }
809
797
  else {
810
- connector
811
- .getProvider()
812
- .then((p) => setWcWallet(extractWcWalletFromProvider(p, log)))
813
- .catch((e) => console.error(`[WCWALLET] err getting provider`, e));
798
+ // Check if getProvider exists and is a function before calling
799
+ if (typeof connector.getProvider === "function") {
800
+ connector
801
+ .getProvider()
802
+ .then((p) => setWcWallet(extractWcWalletFromProvider(p, log)))
803
+ .catch((e) => console.error(`[WCWALLET] err getting provider`, e));
804
+ }
805
+ else {
806
+ // Log a warning if getProvider is not available
807
+ console.warn(`[WCWALLET] connector does not have getProvider method`, connector);
808
+ // Potentially reset wcWallet state if the connector is invalid/unexpected
809
+ setWcWallet(undefined);
810
+ }
814
811
  }
815
812
  }, [connector]);
816
813
  return wcWallet;
@@ -5190,7 +5187,7 @@ const Modal = ({ open, pages, pageId, positionInside, inline, demo, onClose, onB
5190
5187
  CONNECTORNAME: walletInfo?.name,
5191
5188
  });
5192
5189
  const [state, setOpen] = useTransition({
5193
- timeout: mobile ? 160 : 160, // different animations, 10ms extra to avoid final-frame drops
5190
+ timeout: 160,
5194
5191
  preEnter: true,
5195
5192
  mountOnEnter: true,
5196
5193
  unmountOnExit: true,
@@ -6591,11 +6588,12 @@ const MoreIndicator = styled.div `
6591
6588
  `;
6592
6589
  const ScrollAreaContainer = styled.div `
6593
6590
  --bg: ${({ $backgroundColor }) => $backgroundColor || "var(--ck-body-background)"};
6594
- --fade-height: 1px;
6591
+ --fade-height-top: 1px;
6592
+ --fade-height-bottom: ${(props) => props.$hideBottomLine && props.$totalItems > 2 ? "32px" : "1px"};
6595
6593
  position: relative;
6596
6594
  z-index: 1;
6597
6595
 
6598
- ${({ $mobile, $height, $mobileDirection }) => $mobile && $mobileDirection === "horizontal"
6596
+ ${({ $mobile, $height, $mobileDirection, $hideBottomLine }) => $mobile && $mobileDirection === "horizontal"
6599
6597
  ? css `
6600
6598
  overflow-x: scroll;
6601
6599
  margin: 0 -24px;
@@ -6610,7 +6608,7 @@ const ScrollAreaContainer = styled.div `
6610
6608
  position: sticky;
6611
6609
  top: 0;
6612
6610
  bottom: 0;
6613
- width: var(--fade-height);
6611
+ width: var(--fade-height-bottom);
6614
6612
  background: var(
6615
6613
  --ck-body-divider-secondary,
6616
6614
  var(--ck-body-divider)
@@ -6641,7 +6639,7 @@ const ScrollAreaContainer = styled.div `
6641
6639
  max-height: ${$height ? `${$height}px` : "310px"};
6642
6640
  overflow-y: scroll;
6643
6641
  padding: 0 10px;
6644
- margin: calc(var(--fade-height) * -1) -16px 0 -10px;
6642
+ margin: calc(var(--fade-height-top) * -1) -16px 0 -10px;
6645
6643
 
6646
6644
  &:before,
6647
6645
  &:after {
@@ -6652,19 +6650,23 @@ const ScrollAreaContainer = styled.div `
6652
6650
  position: sticky;
6653
6651
  left: 0;
6654
6652
  right: 0;
6655
- height: var(--fade-height);
6653
+ }
6654
+ &:before {
6655
+ top: 0;
6656
+ height: var(--fade-height-top);
6656
6657
  background: var(
6657
6658
  --ck-body-divider-secondary,
6658
6659
  var(--ck-body-divider)
6659
6660
  );
6660
6661
  box-shadow: var(--ck-body-divider-box-shadow);
6661
- transition: opacity 300ms ease;
6662
- }
6663
- &:before {
6664
- top: 0;
6665
6662
  }
6666
6663
  &:after {
6667
6664
  bottom: 0;
6665
+ height: var(--fade-height-bottom);
6666
+ background: ${$hideBottomLine
6667
+ ? "linear-gradient(to bottom, transparent, var(--bg))"
6668
+ : "var(--ck-body-divider-secondary, var(--ck-body-divider))"};
6669
+ box-shadow: none;
6668
6670
  }
6669
6671
 
6670
6672
  &.scroll-start {
@@ -6700,7 +6702,7 @@ const ScrollAreaContainer = styled.div `
6700
6702
  `;
6701
6703
 
6702
6704
  const ArrowDown = () => (jsx("svg", { width: "11", height: "12", viewBox: "0 0 11 12", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: jsx("path", { d: "M5.49438 1L5.49438 11M5.49438 11L9.5 7M5.49438 11L1.5 7", stroke: "currentColor", strokeWidth: "1.75", strokeLinecap: "round", strokeLinejoin: "round" }) }));
6703
- const ScrollArea = ({ children, height, backgroundColor, mobileDirection, }) => {
6705
+ const ScrollArea = ({ children, height, backgroundColor, mobileDirection, hideBottomLine = false, totalItems, }) => {
6704
6706
  const { log } = usePayContext();
6705
6707
  const ref = useRef(null);
6706
6708
  const moreRef = useRef(null);
@@ -6743,7 +6745,7 @@ const ScrollArea = ({ children, height, backgroundColor, mobileDirection, }) =>
6743
6745
  el.removeEventListener("scroll", handleScroll);
6744
6746
  };
6745
6747
  }, [ref.current]);
6746
- return (jsxs(ScrollContainer, { children: [jsx(ScrollAreaContainer, { ref: ref, "$mobile": isMobile, "$height": height, "$backgroundColor": backgroundColor, "$mobileDirection": mobileDirection, children: children }), jsx(MoreIndicator, { ref: moreRef, className: "hide", onClick: () => {
6748
+ return (jsxs(ScrollContainer, { children: [jsx(ScrollAreaContainer, { ref: ref, "$mobile": isMobile, "$height": height, "$backgroundColor": backgroundColor, "$mobileDirection": mobileDirection, "$hideBottomLine": hideBottomLine, "$totalItems": totalItems, children: children }), jsx(MoreIndicator, { ref: moreRef, className: "hide", onClick: () => {
6747
6749
  if (ref.current) {
6748
6750
  ref.current.scrollTo({
6749
6751
  top: ref.current.scrollHeight,
@@ -10329,7 +10331,7 @@ const OptionsContainer = styled.div `
10329
10331
  `}
10330
10332
  `;
10331
10333
 
10332
- const OptionsList = ({ options, isLoading, requiredSkeletons, }) => {
10334
+ const OptionsList = ({ options, isLoading, requiredSkeletons, shortScroll, orDivider = false, }) => {
10333
10335
  const { triggerResize, log } = usePayContext();
10334
10336
  const optionsLength = options.length;
10335
10337
  useEffect(() => {
@@ -10345,7 +10347,7 @@ const OptionsList = ({ options, isLoading, requiredSkeletons, }) => {
10345
10347
  return (jsxs(OptionsContainer, { "$totalResults": options.length, children: [options.map((option) => (jsx(OptionItem, { option: option }, option.id))), isLoading &&
10346
10348
  Array.from({ length: skeletonCount }).map((_, index) => (jsx(SkeletonOptionItem, {}, index)))] }));
10347
10349
  }
10348
- return (jsx(ScrollArea, { mobileDirection: "vertical", height: 300, children: jsx(OptionsContainer, { "$totalResults": options.length, children: options.map((option) => (jsx(OptionItem, { option: option }, option.id))) }) }));
10350
+ return (jsxs(Fragment, { children: [jsx(ScrollArea, { mobileDirection: "vertical", height: shortScroll ? 225 : 300, hideBottomLine: orDivider, totalItems: options.length, children: jsx(OptionsContainer, { "$totalResults": options.length, children: options.map((option) => (jsx(OptionItem, { option: option }, option.id))) }) }), orDivider && jsx(OrDivider, {})] }));
10349
10351
  };
10350
10352
  const SkeletonOptionItem = () => {
10351
10353
  return (jsxs(OptionButton, { type: "button", children: [jsx(SkeletonIcon, {}), jsx(SkeletonLabel, {})] }));
@@ -10536,15 +10538,13 @@ function SelectMethod() {
10536
10538
  const ethWalletDisplayName = senderEnsName ?? (address ? getAddressContraction(address) : "wallet");
10537
10539
  let walletIcon;
10538
10540
  if (connector?.icon) {
10539
- log("[SELECT_METHOD] connector?.icon", connector?.icon);
10540
10541
  walletIcon = (jsx("div", { style: { borderRadius: "22.5%", overflow: "hidden" }, children: jsx("img", { src: connector.icon, alt: connector.name }) }));
10541
10542
  }
10542
10543
  else if (wcWallet?.icon) {
10543
- log("[SELECT_METHOD] wcWallet.icon", wcWallet.icon);
10544
10544
  walletIcon = (jsx("div", { style: { borderRadius: "22.5%", overflow: "hidden" }, children: typeof wcWallet.icon === "string" ? (jsx("img", { src: wcWallet.icon, alt: wcWallet.name })) : (wcWallet.icon) }));
10545
10545
  }
10546
10546
  else {
10547
- log("[SELECT_METHOD] else");
10547
+ // TODO: remove this once we have a default icon for wagmi wallets
10548
10548
  walletIcon = jsx(MetaMask, {});
10549
10549
  }
10550
10550
  const connectedEthWalletOption = {
@@ -10564,7 +10564,7 @@ function SelectMethod() {
10564
10564
  };
10565
10565
  connectedOptions.push(connectedEthWalletOption);
10566
10566
  }
10567
- if (isSolanaConnected) {
10567
+ if (isSolanaConnected && includeSolana) {
10568
10568
  const solWalletDisplayName = getAddressContraction(publicKey?.toBase58() ?? "");
10569
10569
  const connectedSolWalletOption = {
10570
10570
  id: "connectedSolanaWallet",
@@ -10652,10 +10652,10 @@ function getBestUnconnectedWalletIcons(connector) {
10652
10652
  strippedId?.includes("rainbow"),
10653
10653
  strippedId?.includes("coinbase"),
10654
10654
  ];
10655
- if (!isMetaMask)
10656
- icons.push(jsx(MetaMask, {}));
10657
10655
  if (!isRainbow)
10658
10656
  icons.push(jsx(Rainbow, {}));
10657
+ if (!isMetaMask)
10658
+ icons.push(jsx(MetaMask, {}));
10659
10659
  if (!isCoinbase)
10660
10660
  icons.push(jsx(Coinbase, {}));
10661
10661
  if (icons.length < 3)
@@ -10663,7 +10663,7 @@ function getBestUnconnectedWalletIcons(connector) {
10663
10663
  return icons;
10664
10664
  }
10665
10665
  function getSolanaOption(isOnIOS) {
10666
- const { wallets } = useWallet$1();
10666
+ const { wallets, disconnect: disconnectSolana } = useWallet$1();
10667
10667
  const { setRoute } = usePayContext();
10668
10668
  if (wallets.length === 0 && !isOnIOS)
10669
10669
  return null;
@@ -10671,7 +10671,8 @@ function getSolanaOption(isOnIOS) {
10671
10671
  id: "solana",
10672
10672
  title: "Pay on Solana",
10673
10673
  icons: [jsx(Solana, {})],
10674
- onClick: () => {
10674
+ onClick: async () => {
10675
+ await disconnectSolana();
10675
10676
  setRoute(ROUTES.SOLANA_CONNECT);
10676
10677
  },
10677
10678
  };
@@ -10695,6 +10696,80 @@ function getDepositAddressOption(depositAddressOptions) {
10695
10696
  };
10696
10697
  }
10697
10698
 
10699
+ function SelectAnotherMethodButton() {
10700
+ const { paymentState, setRoute } = usePayContext();
10701
+ const { externalPaymentOptions, daimoPayOrder } = paymentState;
10702
+ const { connector } = useAccount();
10703
+ const { disconnectAsync } = useDisconnect();
10704
+ const paymentOptions = daimoPayOrder?.metadata.payer?.paymentOptions;
10705
+ const allPaymentOptions = [
10706
+ ...externalPaymentOptions.options.map((option) => option.id),
10707
+ ...(paymentOptions ?? []),
10708
+ ].flat();
10709
+ const includeSolana = paymentOptions == null ||
10710
+ paymentOptions.includes(ExternalPaymentOptions.Solana);
10711
+ // Deposit address options, e.g. Bitcoin, Tron, Zcash, etc.
10712
+ // Include by default if paymentOptions not provided
10713
+ const includeDepositAddressOption = paymentOptions == null ||
10714
+ paymentOptions.includes(ExternalPaymentOptions.ExternalChains);
10715
+ const selectMethodOption = {
10716
+ id: "select-method",
10717
+ title: `Pay with another method`,
10718
+ icons: getBestPaymentMethodIcons(),
10719
+ onClick: () => {
10720
+ setRoute(ROUTES.SELECT_METHOD);
10721
+ },
10722
+ };
10723
+ const selectWalletOption = {
10724
+ id: "select-wallet",
10725
+ title: "Pay with another wallet",
10726
+ icons: getBestUnconnectedWalletIcons(connector),
10727
+ onClick: async () => {
10728
+ await disconnectAsync();
10729
+ setRoute(ROUTES.CONNECTORS);
10730
+ },
10731
+ };
10732
+ function getBestUnconnectedWalletIcons(connector) {
10733
+ const icons = [];
10734
+ const strippedId = connector?.id.toLowerCase(); // some connector ids can have weird casing and or suffixes and prefixes
10735
+ const [isMetaMask, isRainbow, isCoinbase] = [
10736
+ strippedId?.includes("metamask"),
10737
+ strippedId?.includes("rainbow"),
10738
+ strippedId?.includes("coinbase"),
10739
+ ];
10740
+ if (!isRainbow)
10741
+ icons.push(jsx(Rainbow, {}));
10742
+ if (!isMetaMask)
10743
+ icons.push(jsx(MetaMask, {}));
10744
+ if (!isCoinbase)
10745
+ icons.push(jsx(Coinbase, {}));
10746
+ if (icons.length < 3)
10747
+ icons.push(jsx(Rabby, {}));
10748
+ return icons;
10749
+ }
10750
+ function getBestPaymentMethodIcons() {
10751
+ let icons = externalPaymentOptions.options
10752
+ .filter((option) => option.id !== ExternalPaymentOptions.Daimo)
10753
+ .map((option) => (jsx("div", { style: { borderRadius: "22.5%", overflow: "hidden" }, children: jsx("img", { src: option.logoURI, alt: "" }) }, option.id)));
10754
+ if (icons.length < 3) {
10755
+ const additionalIcons = [];
10756
+ if (includeSolana)
10757
+ additionalIcons.push(jsx(Solana, {}));
10758
+ if (includeDepositAddressOption && additionalIcons.length < 3)
10759
+ additionalIcons.push(jsx(Bitcoin, {}));
10760
+ if (includeDepositAddressOption && additionalIcons.length < 3)
10761
+ additionalIcons.push(jsx(Tron, {}));
10762
+ if (additionalIcons.length < 3)
10763
+ additionalIcons.push(...getBestUnconnectedWalletIcons(connector));
10764
+ icons = [...icons, ...additionalIcons.slice(0, 3 - icons.length)];
10765
+ }
10766
+ return icons;
10767
+ }
10768
+ return (jsx(OptionsList, { options: allPaymentOptions.length > 0
10769
+ ? [selectMethodOption]
10770
+ : [selectWalletOption] }));
10771
+ }
10772
+
10698
10773
  const TokenChainLogo = ({ token }) => {
10699
10774
  return (jsxs(TokenChainContainer, { children: [jsx("img", { src: token.logoURI, alt: token.symbol, style: { borderRadius: 9999 } }), jsx(ChainContainer$1, { children: chainToLogo[token.chainId] })] }));
10700
10775
  };
@@ -10767,7 +10842,7 @@ function SelectToken() {
10767
10842
  justifyContent: "center",
10768
10843
  paddingTop: 16,
10769
10844
  paddingBottom: 16,
10770
- }, children: [jsx(ModalH1, { children: "Insufficient balance." }), jsx(Button, { onClick: () => setRoute(ROUTES.SELECT_METHOD), children: "Select Another Method" })] })), jsx(OptionsList, { requiredSkeletons: 4, isLoading: walletPaymentOptions.isLoading, options: optionsList })] }));
10845
+ }, children: [jsx(ModalH1, { children: "Insufficient balance." }), jsx("div", { className: "w-full mt-4", children: jsx(SelectAnotherMethodButton, {}) })] })), jsx(OptionsList, { requiredSkeletons: 4, isLoading: walletPaymentOptions.isLoading, options: optionsList, shortScroll: isMobile, orDivider: optionsList.length != 0 }), optionsList.length != 0 && (jsx("div", { className: "mt-2", children: jsx(SelectAnotherMethodButton, {}) }))] }));
10771
10846
  }
10772
10847
  function getDaimoTokenKey(token) {
10773
10848
  return `${token.chainId}-${token.token}`;
@@ -10990,7 +11065,7 @@ const SelectSolanaToken = () => {
10990
11065
  justifyContent: "center",
10991
11066
  paddingTop: 16,
10992
11067
  paddingBottom: 16,
10993
- }, children: [jsx(ModalH1, { children: "Insufficient balance." }), jsx(Button, { onClick: () => setRoute(ROUTES.SELECT_METHOD), children: "Select Another Method" })] })), jsx(OptionsList, { requiredSkeletons: 4, isLoading: solanaPaymentOptions.isLoading, options: optionsList })] }));
11068
+ }, children: [jsx(ModalH1, { children: "Insufficient balance." }), jsx(SelectAnotherMethodButton, {})] })), jsx(OptionsList, { requiredSkeletons: 4, isLoading: solanaPaymentOptions.isLoading, options: optionsList, orDivider: optionsList.length != 0 }), optionsList.length != 0 && (jsx("div", { className: "mt-2", children: jsx(SelectAnotherMethodButton, {}) }))] }));
10994
11069
  };
10995
11070
 
10996
11071
  const WaitingDepositAddress = () => {
@@ -11062,7 +11137,11 @@ const WaitingExternal = () => {
11062
11137
  const openExternalWindow = (url) => {
11063
11138
  if (selectedExternalOption?.id === "Coinbase") {
11064
11139
  //opening Coinbase onramp in a popup window in portrait mode in the center of the screen
11065
- window.open(url, "popupWindow", `width=500,height=700,left=${(window.screen.width - 500) / 2},top=${(window.screen.height - 700) / 2}`);
11140
+ const width = 500;
11141
+ const height = 700;
11142
+ const left = Math.max(0, Math.floor((window.innerWidth - width) / 2) + window.screenX);
11143
+ const top = Math.max(0, Math.floor((window.innerHeight - height) / 2) + window.screenY);
11144
+ window.open(url, "popupWindow", `width=${width},height=${height},left=${left},top=${top},scrollbars=yes`);
11066
11145
  }
11067
11146
  else {
11068
11147
  window.open(url, "_blank");
@@ -11087,15 +11166,24 @@ const DaimoPayModal = ({ mode = "auto", theme = "auto", customTheme = customThem
11087
11166
  const context = usePayContext();
11088
11167
  const paymentState = context.paymentState;
11089
11168
  const { payParams, generatePreviewOrder, isDepositFlow, setPaymentWaitingMessage, setSelectedExternalOption, setSelectedTokenOption, setSelectedSolanaTokenOption, setSelectedDepositAddressOption, } = paymentState;
11090
- const { isConnected, connector, chain, address } = useAccount();
11169
+ const { isConnected: isEthConnected, connector, chain, address, } = useAccount();
11170
+ const { connected: isSolanaConnected } = useWallet$1();
11171
+ const { daimoPayOrder } = paymentState;
11172
+ const paymentOptions = daimoPayOrder?.metadata.payer?.paymentOptions;
11173
+ // Solana payment option
11174
+ // Include by default if paymentOptions not provided
11175
+ const includeSolana = paymentOptions == null ||
11176
+ paymentOptions.includes(ExternalPaymentOptions.Solana);
11091
11177
  const chainIsSupported = useChainIsSupported(chain?.id);
11092
11178
  //if chain is unsupported we enforce a "switch chain" prompt
11093
11179
  const closeable = !(context.options?.enforceSupportedChains &&
11094
- isConnected &&
11180
+ isEthConnected &&
11095
11181
  !chainIsSupported);
11096
11182
  const showBackButton = closeable &&
11097
11183
  context.route !== ROUTES.SELECT_METHOD &&
11098
- context.route !== ROUTES.CONFIRMATION;
11184
+ context.route !== ROUTES.CONFIRMATION &&
11185
+ context.route !== ROUTES.SELECT_TOKEN &&
11186
+ context.route !== ROUTES.SOLANA_SELECT_TOKEN;
11099
11187
  const onBack = () => {
11100
11188
  const meta = { event: "click-back" };
11101
11189
  if (context.route === ROUTES.DOWNLOAD) {
@@ -11104,9 +11192,6 @@ const DaimoPayModal = ({ mode = "auto", theme = "auto", customTheme = customThem
11104
11192
  else if (context.route === ROUTES.CONNECTORS) {
11105
11193
  context.setRoute(ROUTES.SELECT_METHOD, meta);
11106
11194
  }
11107
- else if (context.route === ROUTES.SELECT_TOKEN) {
11108
- context.setRoute(ROUTES.SELECT_METHOD, meta);
11109
- }
11110
11195
  else if (context.route === ROUTES.SELECT_AMOUNT) {
11111
11196
  setSelectedTokenOption(undefined);
11112
11197
  context.setRoute(ROUTES.SELECT_TOKEN, meta);
@@ -11207,11 +11292,42 @@ const DaimoPayModal = ({ mode = "auto", theme = "auto", customTheme = customThem
11207
11292
  }
11208
11293
  context.setOpen(false, { event: "click-close" });
11209
11294
  }
11295
+ // Separate effect for initial route when modal opens
11296
+ useEffect(() => {
11297
+ if (context.open &&
11298
+ !isSolanaConnected &&
11299
+ (context.wcWallet || isEthConnected)) {
11300
+ // Only set initial route if we're at SELECT_METHOD when opening
11301
+ if (context.route === ROUTES.SELECT_METHOD) {
11302
+ context.setRoute(ROUTES.SELECT_TOKEN, {
11303
+ event: "eth_connected_on_open",
11304
+ walletId: connector?.id,
11305
+ chainId: chain?.id,
11306
+ address,
11307
+ });
11308
+ }
11309
+ }
11310
+ else if (context.open &&
11311
+ isSolanaConnected &&
11312
+ !isEthConnected &&
11313
+ context.wcWallet === undefined &&
11314
+ includeSolana) {
11315
+ console.log("solana connected on open");
11316
+ console.log("isEthConnected ", isEthConnected);
11317
+ console.log("context.wcWallet ", context.wcWallet);
11318
+ if (context.route === ROUTES.SELECT_METHOD) {
11319
+ context.setRoute(ROUTES.SOLANA_SELECT_TOKEN, {
11320
+ event: "solana_connected_on_open",
11321
+ });
11322
+ }
11323
+ }
11324
+ // If both are connected, do nothing and stay on SELECT_METHOD
11325
+ }, [context.open]);
11210
11326
  useEffect(() => {
11211
11327
  if (context.route === ROUTES.CONNECT ||
11212
11328
  context.route === ROUTES.CONNECTORS ||
11213
11329
  context.route === ROUTES.MOBILECONNECTORS) {
11214
- if (isConnected) {
11330
+ if (isEthConnected) {
11215
11331
  context.setRoute(ROUTES.SELECT_TOKEN, {
11216
11332
  event: "connected",
11217
11333
  walletId: connector?.id,
@@ -11220,7 +11336,7 @@ const DaimoPayModal = ({ mode = "auto", theme = "auto", customTheme = customThem
11220
11336
  });
11221
11337
  }
11222
11338
  }
11223
- }, [isConnected, context.route]);
11339
+ }, [isEthConnected, context.route]);
11224
11340
  useEffect(() => context.setMode(mode), [mode]);
11225
11341
  useEffect(() => context.setTheme(theme), [theme]);
11226
11342
  useEffect(() => context.setCustomTheme(customTheme), [customTheme]);