@daimo/pay 1.8.6 → 1.9.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 +311 -112
- package/build/index.js.map +1 -1
- package/package.json +3 -3
package/build/index.js
CHANGED
|
@@ -2,7 +2,7 @@ import { http, useConnectors as useConnectors$1, useAccount, useSwitchChain, use
|
|
|
2
2
|
import { mainnet, base as base$1, polygon, optimism, arbitrum, linea, bsc, sepolia, baseSepolia, worldchain, blast, mantle } from 'wagmi/chains';
|
|
3
3
|
import { safe, injected, coinbaseWallet, walletConnect } from '@wagmi/connectors';
|
|
4
4
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
5
|
-
import { DaimoPayIntentStatus, assert, DaimoPayOrderMode, readDaimoPayOrderID, getOrderDestChainId, assertNotNull, getChainName, arbitrum as arbitrum$1, base as base$2, blast as blast$1, bsc as bsc$1, ethereum, linea as linea$1, mantle as mantle$1, optimism as optimism$1, polygon as polygon$1, worldchain as worldchain$1, solana, getAddressContraction, supportedChains, getChainExplorerTxUrl, ExternalPaymentOptions, isCCTPV1Chain, debugJson, writeDaimoPayOrderID, getOrderSourceChainId, DaimoPayEventType, getDaimoPayOrderView } from '@daimo/pay-common';
|
|
5
|
+
import { DaimoPayIntentStatus, assert, DaimoPayOrderMode, readDaimoPayOrderID, getOrderDestChainId, assertNotNull, getChainName, arbitrum as arbitrum$1, base as base$2, blast as blast$1, bsc as bsc$1, ethereum, linea as linea$1, mantle as mantle$1, optimism as optimism$1, polygon as polygon$1, worldchain as worldchain$1, solana, getAddressContraction, supportedChains, getChainExplorerTxUrl, ExternalPaymentOptions, isCCTPV1Chain, debugJson, DepositAddressPaymentOptions, writeDaimoPayOrderID, getOrderSourceChainId, DaimoPayEventType, getDaimoPayOrderView } from '@daimo/pay-common';
|
|
6
6
|
import { Buffer } from 'buffer';
|
|
7
7
|
import React, { createContext, useRef, useState, useEffect, useLayoutEffect, useMemo, useContext, useSyncExternalStore, useCallback, createElement } from 'react';
|
|
8
8
|
import styled$1, { css, keyframes, ThemeProvider } from 'styled-components';
|
|
@@ -22,7 +22,7 @@ import { VersionedTransaction } from '@solana/web3.js';
|
|
|
22
22
|
import { normalize } from 'viem/ens';
|
|
23
23
|
|
|
24
24
|
var name = "@daimo/pay";
|
|
25
|
-
var version = "1.
|
|
25
|
+
var version = "1.9.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.
|
|
64
|
+
"@daimo/pay-common": "1.9.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",
|
|
@@ -2160,7 +2160,7 @@ function useLockBodyScroll(initialLocked) {
|
|
|
2160
2160
|
useEffect(() => {
|
|
2161
2161
|
if (locked !== initialLocked)
|
|
2162
2162
|
setLocked(initialLocked);
|
|
2163
|
-
}, [initialLocked]);
|
|
2163
|
+
}, [initialLocked]); // eslint-disable-line react-hooks/exhaustive-deps
|
|
2164
2164
|
return [locked, setLocked];
|
|
2165
2165
|
}
|
|
2166
2166
|
|
|
@@ -2600,11 +2600,12 @@ async function pollFindSourcePayment(store, trpc, orderId) {
|
|
|
2600
2600
|
onResult: (found) => {
|
|
2601
2601
|
const state = store.getState();
|
|
2602
2602
|
// Check that we're still in the payment_unpaid state
|
|
2603
|
-
if (state.type !== "payment_unpaid")
|
|
2604
|
-
|
|
2605
|
-
|
|
2606
|
-
|
|
2603
|
+
if (state.type !== "payment_unpaid") {
|
|
2604
|
+
stopPolling();
|
|
2605
|
+
}
|
|
2606
|
+
else if (found) {
|
|
2607
2607
|
stopPolling();
|
|
2608
|
+
store.dispatch({ type: "payment_started", order: state.order });
|
|
2608
2609
|
}
|
|
2609
2610
|
},
|
|
2610
2611
|
onError: () => { },
|
|
@@ -2913,15 +2914,12 @@ function useFocusTrap() {
|
|
|
2913
2914
|
}
|
|
2914
2915
|
}
|
|
2915
2916
|
useEffect(() => {
|
|
2916
|
-
|
|
2917
|
-
|
|
2918
|
-
|
|
2919
|
-
|
|
2920
|
-
|
|
2921
|
-
|
|
2922
|
-
elRef.current.removeEventListener("keydown", handleFocus);
|
|
2923
|
-
}
|
|
2924
|
-
};
|
|
2917
|
+
const el = elRef.current;
|
|
2918
|
+
if (el == null)
|
|
2919
|
+
return;
|
|
2920
|
+
el.addEventListener("keydown", handleFocus);
|
|
2921
|
+
el.focus({ preventScroll: true });
|
|
2922
|
+
return () => el.removeEventListener("keydown", handleFocus);
|
|
2925
2923
|
}, []);
|
|
2926
2924
|
return elRef;
|
|
2927
2925
|
}
|
|
@@ -2931,7 +2929,7 @@ function FocusTrap(props) {
|
|
|
2931
2929
|
if (!elRef.current)
|
|
2932
2930
|
return;
|
|
2933
2931
|
elRef.current.focus({ preventScroll: true });
|
|
2934
|
-
}, []);
|
|
2932
|
+
}, []); // eslint-disable-line react-hooks/exhaustive-deps
|
|
2935
2933
|
return (jsx("div", { ref: elRef, tabIndex: 0, children: props.children }));
|
|
2936
2934
|
}
|
|
2937
2935
|
|
|
@@ -6171,9 +6169,8 @@ const About = () => {
|
|
|
6171
6169
|
const animationDuration = 600;
|
|
6172
6170
|
let interval;
|
|
6173
6171
|
useEffect(() => {
|
|
6174
|
-
//interval = setTimeout(nextSlide, autoplayDelay);
|
|
6175
6172
|
return () => clearInterval(interval);
|
|
6176
|
-
}, []);
|
|
6173
|
+
}, []); // eslint-disable-line react-hooks/exhaustive-deps
|
|
6177
6174
|
const isSwipe = () => {
|
|
6178
6175
|
if (sliderRef.current) {
|
|
6179
6176
|
const { overflow } = getComputedStyle(sliderRef.current);
|
|
@@ -6225,19 +6222,18 @@ const About = () => {
|
|
|
6225
6222
|
};
|
|
6226
6223
|
const sliderRef = useRef(null);
|
|
6227
6224
|
useEffect(() => {
|
|
6228
|
-
|
|
6225
|
+
const slider = sliderRef.current;
|
|
6226
|
+
if (slider == null)
|
|
6229
6227
|
return;
|
|
6230
|
-
|
|
6231
|
-
|
|
6232
|
-
|
|
6228
|
+
slider.addEventListener("scroll", onScroll);
|
|
6229
|
+
slider.addEventListener("touchmove", onTouchMove);
|
|
6230
|
+
slider.addEventListener("touchend", onTouchEnd);
|
|
6233
6231
|
return () => {
|
|
6234
|
-
|
|
6235
|
-
|
|
6236
|
-
|
|
6237
|
-
sliderRef.current.removeEventListener("touchmove", onTouchMove);
|
|
6238
|
-
sliderRef.current.removeEventListener("touchend", onTouchEnd);
|
|
6232
|
+
slider.removeEventListener("scroll", onScroll);
|
|
6233
|
+
slider.removeEventListener("touchmove", onTouchMove);
|
|
6234
|
+
slider.removeEventListener("touchend", onTouchEnd);
|
|
6239
6235
|
};
|
|
6240
|
-
}, [sliderRef]);
|
|
6236
|
+
}, [sliderRef.current]); // eslint-disable-line react-hooks/exhaustive-deps
|
|
6241
6237
|
const graphics = [
|
|
6242
6238
|
jsx(SlideOne, { layoutId: "graphicCircle", duration: animationDuration, ease: animationEase }, "slideOne"),
|
|
6243
6239
|
jsx(SlideTwo, { layoutId: "graphicCircle", duration: animationDuration, ease: animationEase }, "slideTwo"),
|
|
@@ -6597,7 +6593,7 @@ const useLastConnector = () => {
|
|
|
6597
6593
|
setLastConnectorId(id ?? "");
|
|
6598
6594
|
};
|
|
6599
6595
|
init();
|
|
6600
|
-
}, []);
|
|
6596
|
+
}, []); // eslint-disable-line react-hooks/exhaustive-deps
|
|
6601
6597
|
const update = (id) => {
|
|
6602
6598
|
storage?.setItem("recentConnectorId", id);
|
|
6603
6599
|
};
|
|
@@ -6818,7 +6814,7 @@ const ScrollArea = ({ children, height, backgroundColor, mobileDirection, hideBo
|
|
|
6818
6814
|
return () => {
|
|
6819
6815
|
el.removeEventListener("scroll", handleScroll);
|
|
6820
6816
|
};
|
|
6821
|
-
}, [ref.current]);
|
|
6817
|
+
}, [ref.current]); // eslint-disable-line react-hooks/exhaustive-deps
|
|
6822
6818
|
return (jsxs(ScrollContainer, { children: [jsx(ScrollAreaContainer, { ref: ref, "$mobile": isMobileFormat, "$height": height, "$backgroundColor": backgroundColor, "$mobileDirection": mobileDirection, "$hideBottomLine": hideBottomLine, "$totalItems": totalItems, children: children }), jsx(MoreIndicator, { ref: moreRef, className: "hide", onClick: () => {
|
|
6823
6819
|
if (ref.current) {
|
|
6824
6820
|
ref.current.scrollTo({
|
|
@@ -7329,7 +7325,6 @@ const BinanceSmartChain = ({ testnet, ...props }) => (jsx("svg", { ...props, "ar
|
|
|
7329
7325
|
const Solana = ({ testnet, ...props }) => (jsxs("svg", { ...props, "aria-hidden": "true", width: "44", height: "44", viewBox: "0 0 200 200", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [jsx("rect", { width: "200", height: "200", rx: "100", fill: "#121212" }), jsx("g", { clipPath: "url(#clip0_295_42)", children: jsx("path", { d: "M149.48 125.382L132.807 142.801C132.444 143.18 132.006 143.482 131.519 143.688C131.031 143.894 130.505 144 129.974 144H50.9356C50.5585 144 50.1896 143.893 49.8742 143.691C49.5588 143.49 49.3107 143.203 49.1604 142.866C49.0101 142.529 48.9641 142.157 49.028 141.795C49.092 141.432 49.2631 141.096 49.5204 140.828L66.2061 123.408C66.5676 123.031 67.0047 122.729 67.4904 122.523C67.9762 122.317 68.5002 122.21 69.0301 122.21H148.064C148.441 122.21 148.81 122.317 149.126 122.518C149.441 122.72 149.689 123.007 149.84 123.344C149.99 123.681 150.036 124.053 149.972 124.415C149.908 124.777 149.737 125.113 149.48 125.382ZM132.807 90.3032C132.444 89.9248 132.006 89.6231 131.519 89.4169C131.031 89.2108 130.505 89.1045 129.974 89.1048H50.9356C50.5585 89.1048 50.1896 89.2121 49.8742 89.4136C49.5588 89.6151 49.3107 89.9019 49.1604 90.2388C49.0101 90.5758 48.9641 90.9482 49.028 91.3103C49.092 91.6723 49.2631 92.0083 49.5204 92.277L66.2061 109.697C66.5676 110.074 67.0047 110.375 67.4904 110.581C67.9762 110.788 68.5002 110.894 69.0301 110.895H148.064C148.441 110.895 148.81 110.788 149.126 110.586C149.441 110.385 149.689 110.098 149.84 109.761C149.99 109.424 150.036 109.052 149.972 108.69C149.908 108.328 149.737 107.992 149.48 107.723L132.807 90.3032ZM50.9356 77.7905H129.974C130.505 77.7907 131.031 77.6845 131.519 77.4783C132.006 77.2721 132.444 76.9704 132.807 76.592L149.48 59.1722C149.737 58.9036 149.908 58.5676 149.972 58.2055C150.036 57.8434 149.99 57.471 149.84 57.1341C149.689 56.7971 149.441 56.5103 149.126 56.3088C148.81 56.1073 148.441 56 148.064 56H69.0301C68.5002 56.0009 67.9762 56.1077 67.4904 56.3138C67.0047 56.52 66.5676 56.8211 66.2061 57.1985L49.5247 74.6183C49.2677 74.8866 49.0966 75.2223 49.0325 75.5839C48.9684 75.9456 49.0141 76.3177 49.1639 76.6545C49.3136 76.9913 49.5611 77.2781 49.8758 77.4799C50.1905 77.6817 50.5589 77.7896 50.9356 77.7905Z", fill: "url(#paint0_linear_295_42)" }) }), jsxs("defs", { children: [jsxs("linearGradient", { id: "paint0_linear_295_42", x1: "57.5256", y1: "146.097", x2: "137.993", y2: "52.9838", gradientUnits: "userSpaceOnUse", children: [jsx("stop", { offset: "0.08", stopColor: "#9945FF" }), jsx("stop", { offset: "0.3", stopColor: "#8752F3" }), jsx("stop", { offset: "0.5", stopColor: "#5497D5" }), jsx("stop", { offset: "0.6", stopColor: "#43B4CA" }), jsx("stop", { offset: "0.72", stopColor: "#28E0B9" }), jsx("stop", { offset: "0.97", stopColor: "#19FB9B" })] }), jsx("clipPath", { id: "clip0_295_42", children: jsx("rect", { width: "101", height: "88", fill: "white", transform: "translate(49 56)" }) })] })] }));
|
|
7330
7326
|
const Bitcoin = ({ testnet, ...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", children: [jsx("path", { d: "M43.3388 27.3219C40.4005 39.1077 28.4634 46.2804 16.6762 43.3413C4.89383 40.4029 -2.27886 28.4652 0.660895 16.68C3.59789 4.89286 15.535 -2.28052 27.3187 0.657859C39.1052 3.59623 46.2772 15.5354 43.3388 27.3219Z", fill: "#F7931A" }), jsx("path", { d: "M31.6992 18.8656C32.1371 15.9382 29.9082 14.3645 26.8605 13.3147L27.8492 9.34922L25.4353 8.74765L24.4728 12.6087C23.8383 12.4505 23.1865 12.3013 22.5389 12.1535L23.5083 8.26709L21.0958 7.66553L20.1065 11.6297C19.5813 11.51 19.0657 11.3918 18.5652 11.2673L18.5679 11.255L15.239 10.4238L14.5969 13.0019C14.5969 13.0019 16.3878 13.4123 16.35 13.4378C17.3277 13.6818 17.5043 14.3288 17.4748 14.8417L16.3487 19.3592C16.416 19.3764 16.5033 19.4012 16.5996 19.4397C16.5192 19.4197 16.4332 19.3977 16.3445 19.3764L14.766 25.7048C14.6464 26.0018 14.3432 26.4473 13.6598 26.2782C13.6839 26.3133 11.9053 25.8403 11.9053 25.8403L10.707 28.6033L13.8482 29.3864C14.4326 29.5328 15.0053 29.6862 15.569 29.8305L14.5701 33.8414L16.9812 34.443L17.9705 30.4747C18.6291 30.6535 19.2685 30.8185 19.8941 30.9738L18.9082 34.9235L21.322 35.5251L22.321 31.5218C26.437 32.3007 29.5322 31.9865 30.835 28.2637C31.8848 25.2662 30.7827 23.5372 28.6171 22.4097C30.1942 22.046 31.3822 21.0085 31.6992 18.8656ZM26.184 26.5993C25.4381 29.5968 20.3912 27.9763 18.7549 27.57L20.0804 22.2563C21.7167 22.6647 26.9637 23.4732 26.184 26.5993ZM26.9307 18.8223C26.25 21.5489 22.0494 20.1636 20.6868 19.824L21.8885 15.0046C23.2512 15.3442 27.6395 15.9781 26.9307 18.8223Z", fill: "white" })] }));
|
|
7331
7327
|
const Tron = ({ testnet, ...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", children: [jsxs("g", { clipPath: "url(#clip0_450_171)", children: [jsx("path", { d: "M43.3388 27.3219C40.4005 39.1077 28.4634 46.2804 16.6762 43.3413C4.89383 40.4029 -2.27886 28.4652 0.660896 16.68C3.59789 4.89286 15.535 -2.28052 27.3187 0.65786C39.1052 3.59623 46.2772 15.5354 43.3388 27.3219Z", fill: "#FF060A" }), jsx("path", { d: "M36.3975 17.2381C35.0196 16.0232 33.1057 14.1724 31.5555 12.8625L31.4598 12.8056C31.3067 12.6917 31.1344 12.5968 30.9526 12.5303C27.2015 11.8659 9.74716 8.76218 9.41224 8.80015C9.31654 8.80964 9.22085 8.84761 9.1443 8.89507L9.05817 8.96151C8.95291 9.06591 8.86679 9.1893 8.81894 9.33167L8.7998 9.38862V9.70184V9.7493C10.7615 14.9507 18.5222 31.9785 20.0532 35.9839C20.1489 36.2591 20.3212 36.7717 20.6465 36.8001H20.7231C20.8953 36.8001 21.6417 35.8605 21.6417 35.8605C21.6417 35.8605 34.9717 20.5032 36.321 18.8707C36.4932 18.6713 36.6463 18.453 36.7803 18.2252C36.8186 18.0449 36.7994 17.8646 36.7324 17.6937C36.6655 17.5229 36.5411 17.3615 36.3975 17.2381ZM25.0484 19.032L30.7325 14.552L34.0722 17.4754L25.0484 19.032ZM22.8379 18.7378L13.0486 11.1066L28.8952 13.8876L22.8379 18.7378ZM23.7183 20.731L33.7373 19.1934L22.2829 32.3202L23.7183 20.731ZM11.7184 11.8754L22.0245 20.1805L20.5317 32.3296L11.7184 11.8754Z", fill: "white" })] }), jsx("defs", { children: jsx("clipPath", { id: "clip0_450_171", children: jsx("rect", { width: "44", height: "44", fill: "white" }) }) })] }));
|
|
7332
|
-
const Zcash = ({ testnet, ...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", children: [jsx("path", { d: "M43.3415 27.3221C40.4029 39.1078 28.4645 46.2804 16.676 43.3413C4.8924 40.403 -2.28106 28.4654 0.659014 16.6803C3.59632 4.8933 15.5347 -2.28001 27.3197 0.658341C39.1074 3.59668 46.2802 15.5357 43.3415 27.3221Z", fill: "white" }), jsx("path", { fillRule: "evenodd", clipRule: "evenodd", d: "M0 22C0 9.86741 9.86741 0 22 0C34.1326 0 44 9.86741 44 22C44 34.1326 34.1326 44 22 44C9.86741 44 0 34.1326 0 22ZM29.8475 11.7904V15.1384L20.5358 27.7681H29.8475V32.2088H23.8447V35.8885H20.1553V32.2088H14.1525V28.8607L23.4544 16.2311H14.1525V11.7904H20.1553V8.10089H23.8447V11.7904H29.8475Z", fill: "#F4B728" })] }));
|
|
7333
7328
|
const Base = ({ testnet, ...props }) => (jsx("svg", { ...props, width: "44", height: "44", viewBox: "0 0 44 44", fill: "none", xmlns: "http://www.w3.org/2000/svg", style: {
|
|
7334
7329
|
background: testnet
|
|
7335
7330
|
? "linear-gradient(180deg, #8995A9 0%, #424D5F 99.48%)"
|
|
@@ -7972,21 +7967,21 @@ function QRCode({ ecl = "M", size: sizeProp = 200, uri, clearArea = false, image
|
|
|
7972
7967
|
});
|
|
7973
7968
|
});
|
|
7974
7969
|
return dots;
|
|
7975
|
-
}, [ecl, size, uri]);
|
|
7970
|
+
}, [ecl, size, uri]); // eslint-disable-line react-hooks/exhaustive-deps
|
|
7976
7971
|
return (jsxs("svg", { height: size, width: size, viewBox: `0 0 ${size} ${size}`, style: {
|
|
7977
7972
|
width: size,
|
|
7978
7973
|
height: size,
|
|
7979
7974
|
}, children: [jsx("rect", { fill: "transparent", height: size, width: size }), dots] }));
|
|
7980
7975
|
}
|
|
7981
7976
|
|
|
7982
|
-
function CustomQRCode({ value, image, imageBackground, imagePosition = "center", tooltipMessage, }) {
|
|
7977
|
+
function CustomQRCode({ value, image, imageBackground, imagePosition = "center", tooltipMessage, contentPadding = 13, }) {
|
|
7983
7978
|
const windowSize = useWindowSize();
|
|
7984
7979
|
const Logo = windowSize.width > 920 && tooltipMessage ? (jsx(Tooltip, { xOffset: 139, yOffset: 5, delay: 0.1, message: tooltipMessage, children: image })) : (image);
|
|
7985
|
-
return (jsx(QRCodeContainer, { children: jsxs(QRCodeContent, { children: [image && (jsx(LogoContainer$3, { children: jsx(LogoIcon, { "$wcLogo": imagePosition !== "center", style: {
|
|
7980
|
+
return (jsx(QRCodeContainer, { children: jsxs(QRCodeContent, { style: { inset: contentPadding }, children: [image && (jsx(LogoContainer$3, { children: jsx(LogoIcon, { "$wcLogo": imagePosition !== "center", style: {
|
|
7986
7981
|
background: imagePosition === "center" ? imageBackground : undefined,
|
|
7987
7982
|
}, children: Logo }) })), jsx(AnimatePresence, { initial: false, children: value ? (jsx(motion.div, { initial: { opacity: 0 }, animate: { opacity: 1 }, exit: { opacity: 0, position: "absolute", inset: [0, 0] }, transition: {
|
|
7988
7983
|
duration: 0.2,
|
|
7989
|
-
}, children: jsx(QRCode, { uri: value, size: 576, ecl: "H", clearArea: !!(imagePosition === "center" && image) }) }, value)) : (jsxs(QRPlaceholder, { initial: { opacity: 0.1 }, animate: { opacity: 0.1 }, exit: { opacity: 0, position: "absolute", inset: [0, 0] }, transition: {
|
|
7984
|
+
}, children: jsx(QRCode, { uri: value, size: 576, ecl: "H", clearArea: !!(imagePosition === "center" && image), image: imagePosition === "bottom right" ? image : undefined, imageBackground: imageBackground }) }, value)) : (jsxs(QRPlaceholder, { initial: { opacity: 0.1 }, animate: { opacity: 0.1 }, exit: { opacity: 0, position: "absolute", inset: [0, 0] }, transition: {
|
|
7990
7985
|
duration: 0.2,
|
|
7991
7986
|
}, children: [jsx("span", {}), jsx("span", {}), jsx("span", {}), jsx("div", {})] })) })] }) }));
|
|
7992
7987
|
}
|
|
@@ -9184,7 +9179,7 @@ const ConnectWithInjector = ({ switchConnectMethod, forceState }) => {
|
|
|
9184
9179
|
return () => {
|
|
9185
9180
|
clearTimeout(connectTimeout);
|
|
9186
9181
|
};
|
|
9187
|
-
}, []);
|
|
9182
|
+
}, []); // eslint-disable-line react-hooks/exhaustive-deps
|
|
9188
9183
|
/** Timeout functionality if necessary
|
|
9189
9184
|
let expiryTimeout: any;
|
|
9190
9185
|
useEffect(() => {
|
|
@@ -9484,7 +9479,7 @@ function useWalletConnectUri({ enabled } = {
|
|
|
9484
9479
|
};
|
|
9485
9480
|
}
|
|
9486
9481
|
}
|
|
9487
|
-
}, [enabled, connector, isConnected]);
|
|
9482
|
+
}, [enabled, connector, isConnected]); // eslint-disable-line react-hooks/exhaustive-deps
|
|
9488
9483
|
return {
|
|
9489
9484
|
uri,
|
|
9490
9485
|
};
|
|
@@ -9598,7 +9593,7 @@ const ConnectUsing = () => {
|
|
|
9598
9593
|
};
|
|
9599
9594
|
if (status === states.INJECTOR)
|
|
9600
9595
|
checkProvider();
|
|
9601
|
-
}, []);
|
|
9596
|
+
}, []); // eslint-disable-line react-hooks/exhaustive-deps
|
|
9602
9597
|
if (!wallet)
|
|
9603
9598
|
return jsx(Alert, { children: "Connector not found" });
|
|
9604
9599
|
return (jsxs(AnimatePresence, { children: [status === states.QRCODE && (jsx(motion.div, { initial: "initial", animate: "animate", exit: "exit", variants: contentVariants$2, children: jsx(ConnectWithQRCode, { switchConnectMethod: (id) => {
|
|
@@ -10113,7 +10108,7 @@ const MultiCurrencySelectAmount = ({ selectedTokenOption, setSelectedTokenOption
|
|
|
10113
10108
|
const [continueDisabled, setContinueDisabled] = useState(true);
|
|
10114
10109
|
useEffect(() => {
|
|
10115
10110
|
triggerResize();
|
|
10116
|
-
}, [message]);
|
|
10111
|
+
}, [message]); // eslint-disable-line react-hooks/exhaustive-deps
|
|
10117
10112
|
/**
|
|
10118
10113
|
* Update the editable value and secondary value, taking into account whether
|
|
10119
10114
|
* the user is currently editing the USD value or the token value.
|
|
@@ -10250,19 +10245,17 @@ const ExternalPaymentSpinner = ({ logoURI, logoShape, }) => {
|
|
|
10250
10245
|
return (jsx(LoadingContainer$2, { children: jsx(AnimationContainer$1, { "$circle": logoShape === "circle", children: jsx(AnimatePresence, { children: optionSpinner }) }) }));
|
|
10251
10246
|
};
|
|
10252
10247
|
|
|
10253
|
-
// TODO: min amount for deposit address should come from the backend
|
|
10254
|
-
const MIN_USD_VALUE = 20;
|
|
10255
10248
|
const SelectDepositAddressAmount = () => {
|
|
10256
10249
|
const { paymentState, setRoute, triggerResize } = usePayContext();
|
|
10257
10250
|
const { selectedDepositAddressOption } = paymentState;
|
|
10258
10251
|
const maxUsdLimit = paymentState.getOrderUsdLimit();
|
|
10259
|
-
const minimumMessage = `Minimum ${formatUsd(MIN_USD_VALUE, "up")}`;
|
|
10252
|
+
// const minimumMessage = `Minimum ${formatUsd(MIN_USD_VALUE, "up")}`;
|
|
10260
10253
|
const [usdInput, setUsdInput] = useState("");
|
|
10261
|
-
const [message, setMessage] = useState(
|
|
10254
|
+
const [message, setMessage] = useState("");
|
|
10262
10255
|
const [continueDisabled, setContinueDisabled] = useState(true);
|
|
10263
10256
|
useEffect(() => {
|
|
10264
10257
|
triggerResize();
|
|
10265
|
-
}, [message]);
|
|
10258
|
+
}, [message]); // eslint-disable-line react-hooks/exhaustive-deps
|
|
10266
10259
|
if (selectedDepositAddressOption == null) {
|
|
10267
10260
|
return jsx(PageContent, {});
|
|
10268
10261
|
}
|
|
@@ -10275,10 +10268,10 @@ const SelectDepositAddressAmount = () => {
|
|
|
10275
10268
|
setMessage(`Maximum ${formatUsd(maxUsdLimit)}`);
|
|
10276
10269
|
}
|
|
10277
10270
|
else {
|
|
10278
|
-
setMessage(
|
|
10271
|
+
setMessage("");
|
|
10279
10272
|
}
|
|
10280
10273
|
const usd = Number(sanitizeNumber(value));
|
|
10281
|
-
setContinueDisabled(usd <= 0 || usd
|
|
10274
|
+
setContinueDisabled(usd <= 0 || usd > maxUsdLimit);
|
|
10282
10275
|
};
|
|
10283
10276
|
const handleKeyDown = (e) => {
|
|
10284
10277
|
if (e.key === "Enter" && !continueDisabled) {
|
|
@@ -10452,7 +10445,7 @@ const OptionsList = ({ options, isLoading, requiredSkeletons, scrollHeight = 300
|
|
|
10452
10445
|
const SkeletonOptionItem = () => {
|
|
10453
10446
|
return (jsxs(OptionButton, { type: "button", children: [jsx(SkeletonIcon, {}), jsx(SkeletonLabel, {})] }));
|
|
10454
10447
|
};
|
|
10455
|
-
const pulse = keyframes `
|
|
10448
|
+
const pulse$1 = keyframes `
|
|
10456
10449
|
0% {
|
|
10457
10450
|
opacity: 0.6;
|
|
10458
10451
|
}
|
|
@@ -10470,14 +10463,14 @@ const SkeletonIcon = styled.div `
|
|
|
10470
10463
|
height: 32px;
|
|
10471
10464
|
border-radius: 22.5%;
|
|
10472
10465
|
background-color: rgba(0, 0, 0, 0.1);
|
|
10473
|
-
animation: ${pulse} 1.5s ease-in-out infinite;
|
|
10466
|
+
animation: ${pulse$1} 1.5s ease-in-out infinite;
|
|
10474
10467
|
`;
|
|
10475
10468
|
const SkeletonLabel = styled.div `
|
|
10476
10469
|
width: 100px;
|
|
10477
10470
|
height: 16px;
|
|
10478
10471
|
border-radius: 8px;
|
|
10479
10472
|
background-color: rgba(0, 0, 0, 0.1);
|
|
10480
|
-
animation: ${pulse} 1.5s ease-in-out infinite;
|
|
10473
|
+
animation: ${pulse$1} 1.5s ease-in-out infinite;
|
|
10481
10474
|
`;
|
|
10482
10475
|
const OptionItem = ({ option }) => {
|
|
10483
10476
|
const hydratedIcons = option.icons.map((icon) => {
|
|
@@ -10637,7 +10630,7 @@ const SelectExternalAmount = () => {
|
|
|
10637
10630
|
const [continueDisabled, setContinueDisabled] = useState(true);
|
|
10638
10631
|
useEffect(() => {
|
|
10639
10632
|
triggerResize();
|
|
10640
|
-
}, [message]);
|
|
10633
|
+
}, [message]); // eslint-disable-line react-hooks/exhaustive-deps
|
|
10641
10634
|
if (selectedExternalOption == null) {
|
|
10642
10635
|
return jsx(PageContent, {});
|
|
10643
10636
|
}
|
|
@@ -10699,9 +10692,7 @@ function SelectMethod() {
|
|
|
10699
10692
|
const { connected: isSolanaConnected, wallet: solanaWallet, wallets: solanaWallets, disconnect: disconnectSolana, publicKey, } = useWallet$1();
|
|
10700
10693
|
const { setRoute, paymentState, wcWallet, log } = usePayContext();
|
|
10701
10694
|
const { disconnectAsync } = useDisconnect();
|
|
10702
|
-
const { setSelectedExternalOption, externalPaymentOptions, showSolanaPaymentMethod,
|
|
10703
|
-
const { order } = useDaimoPay();
|
|
10704
|
-
const paymentOptions = order?.metadata.payer?.paymentOptions;
|
|
10695
|
+
const { setSelectedExternalOption, externalPaymentOptions, showSolanaPaymentMethod, senderEnsName, } = paymentState;
|
|
10705
10696
|
// Decide whether to show the connected eth account, solana account, or both.
|
|
10706
10697
|
const showConnectedEth = isEthConnected;
|
|
10707
10698
|
const showConnectedSolana = isSolanaConnected && showSolanaPaymentMethod;
|
|
@@ -10764,10 +10755,6 @@ function SelectMethod() {
|
|
|
10764
10755
|
}
|
|
10765
10756
|
return connectedOptions;
|
|
10766
10757
|
};
|
|
10767
|
-
// Deposit address options, e.g. Bitcoin, Tron, Zcash, etc.
|
|
10768
|
-
// Include by default if paymentOptions not provided
|
|
10769
|
-
const showDepositAddressMethod = paymentOptions == null ||
|
|
10770
|
-
paymentOptions.includes(ExternalPaymentOptions.ExternalChains);
|
|
10771
10758
|
const connectedWalletOptions = getConnectedWalletOptions();
|
|
10772
10759
|
const unconnectedWalletOption = {
|
|
10773
10760
|
id: "unconnectedWallet",
|
|
@@ -10790,20 +10777,6 @@ function SelectMethod() {
|
|
|
10790
10777
|
options.push(solanaOption);
|
|
10791
10778
|
}
|
|
10792
10779
|
}
|
|
10793
|
-
// ZKP2P is currently only available on desktop. Check if the user is on
|
|
10794
|
-
// desktop and if any ZKP2P options are available.
|
|
10795
|
-
const zkp2pOptions = externalPaymentOptions.options.get("zkp2p") ?? [];
|
|
10796
|
-
const showZkp2pPaymentMethod = !isMobile && zkp2pOptions.length > 0;
|
|
10797
|
-
if (showZkp2pPaymentMethod) {
|
|
10798
|
-
options.push({
|
|
10799
|
-
id: "ZKP2P",
|
|
10800
|
-
title: "Pay via payment app",
|
|
10801
|
-
icons: zkp2pOptions.slice(0, 3).map((option) => option.logoURI),
|
|
10802
|
-
onClick: () => {
|
|
10803
|
-
setRoute(ROUTES.SELECT_ZKP2P);
|
|
10804
|
-
},
|
|
10805
|
-
});
|
|
10806
|
-
}
|
|
10807
10780
|
// External payment options, e.g. Binance, Coinbase, etc.
|
|
10808
10781
|
options.push(...(externalPaymentOptions.options.get("external") ?? []).map((option) => ({
|
|
10809
10782
|
id: option.id,
|
|
@@ -10822,9 +10795,21 @@ function SelectMethod() {
|
|
|
10822
10795
|
disabled: option.disabled,
|
|
10823
10796
|
subtitle: option.message,
|
|
10824
10797
|
})));
|
|
10825
|
-
|
|
10826
|
-
|
|
10827
|
-
|
|
10798
|
+
const depositAddressOption = getDepositAddressOption(setRoute);
|
|
10799
|
+
options.push(depositAddressOption);
|
|
10800
|
+
// ZKP2P is currently only available on desktop. Check if the user is on
|
|
10801
|
+
// desktop and if any ZKP2P options are available.
|
|
10802
|
+
const zkp2pOptions = externalPaymentOptions.options.get("zkp2p") ?? [];
|
|
10803
|
+
const showZkp2pPaymentMethod = !isMobile && zkp2pOptions.length > 0;
|
|
10804
|
+
if (showZkp2pPaymentMethod) {
|
|
10805
|
+
options.push({
|
|
10806
|
+
id: "ZKP2P",
|
|
10807
|
+
title: "Pay via payment app",
|
|
10808
|
+
icons: zkp2pOptions.slice(0, 2).map((option) => option.logoURI),
|
|
10809
|
+
onClick: () => {
|
|
10810
|
+
setRoute(ROUTES.SELECT_ZKP2P);
|
|
10811
|
+
},
|
|
10812
|
+
});
|
|
10828
10813
|
}
|
|
10829
10814
|
return (jsxs(PageContent, { children: [jsx(OrderHeader, {}), jsx(OptionsList, { requiredSkeletons: isMobile ? 4 : 3, isLoading: externalPaymentOptions.loading, options: externalPaymentOptions.loading ? [] : options }), jsx(PoweredByFooter, {})] }));
|
|
10830
10815
|
}
|
|
@@ -10833,11 +10818,10 @@ function getBestUnconnectedWalletIcons(connector, isMobile) {
|
|
|
10833
10818
|
const icons = [];
|
|
10834
10819
|
const strippedId = connector?.id.toLowerCase(); // some connector ids can have weird casing and or suffixes and prefixes
|
|
10835
10820
|
const [isRainbow, isTrust, isPhantom, isCoinbase] = [
|
|
10836
|
-
strippedId?.includes("rainbow
|
|
10821
|
+
strippedId?.includes("rainbow"),
|
|
10837
10822
|
strippedId?.includes("trust"),
|
|
10838
10823
|
strippedId?.includes("phantom"),
|
|
10839
10824
|
strippedId?.includes("coinbase"),
|
|
10840
|
-
strippedId?.includes("rainbow"),
|
|
10841
10825
|
];
|
|
10842
10826
|
if (isMobile) {
|
|
10843
10827
|
if (!isTrust)
|
|
@@ -10846,7 +10830,7 @@ function getBestUnconnectedWalletIcons(connector, isMobile) {
|
|
|
10846
10830
|
icons.push(jsx(Rainbow, {}));
|
|
10847
10831
|
if (!isPhantom)
|
|
10848
10832
|
icons.push(jsx(Phantom, {}));
|
|
10849
|
-
if (icons.length < 3)
|
|
10833
|
+
if (!isCoinbase && icons.length < 3)
|
|
10850
10834
|
icons.push(jsx(Coinbase, {}));
|
|
10851
10835
|
}
|
|
10852
10836
|
else {
|
|
@@ -10854,10 +10838,6 @@ function getBestUnconnectedWalletIcons(connector, isMobile) {
|
|
|
10854
10838
|
icons.push(jsx(Rainbow, {}));
|
|
10855
10839
|
if (!isPhantom)
|
|
10856
10840
|
icons.push(jsx(Phantom, {}));
|
|
10857
|
-
if (!isCoinbase)
|
|
10858
|
-
icons.push(jsx(Coinbase, {}));
|
|
10859
|
-
if (icons.length < 3)
|
|
10860
|
-
icons.push(jsx(Rabby, {}));
|
|
10861
10841
|
}
|
|
10862
10842
|
return icons;
|
|
10863
10843
|
}
|
|
@@ -10877,25 +10857,14 @@ function getSolanaOption(isIOS, isAndroid, solanaWallets, disconnectSolana, setR
|
|
|
10877
10857
|
},
|
|
10878
10858
|
};
|
|
10879
10859
|
}
|
|
10880
|
-
function getDepositAddressOption(
|
|
10881
|
-
// TODO: API should serve the subtitle and disabled
|
|
10882
|
-
const disabled = !isDepositFlow &&
|
|
10883
|
-
!depositAddressOptions.loading &&
|
|
10884
|
-
depositAddressOptions.options.length === 0;
|
|
10885
|
-
const subtitle = disabled ? "Minimum $20.00" : "Bitcoin, Tron, Zcash...";
|
|
10860
|
+
function getDepositAddressOption(setRoute) {
|
|
10886
10861
|
return {
|
|
10887
10862
|
id: "depositAddress",
|
|
10888
|
-
title: "Pay
|
|
10889
|
-
|
|
10890
|
-
icons: [
|
|
10891
|
-
jsx(Bitcoin, {}, "bitcoin"),
|
|
10892
|
-
jsx(Tron, {}, "tron"),
|
|
10893
|
-
jsx(Zcash, {}, "zcash"),
|
|
10894
|
-
],
|
|
10863
|
+
title: "Pay to address",
|
|
10864
|
+
icons: [jsx(Ethereum, {}, "eth"), jsx(Tron, {}, "tron"), jsx(Base, {}, "base")],
|
|
10895
10865
|
onClick: () => {
|
|
10896
10866
|
setRoute(ROUTES.SELECT_DEPOSIT_ADDRESS_CHAIN);
|
|
10897
10867
|
},
|
|
10898
|
-
disabled,
|
|
10899
10868
|
};
|
|
10900
10869
|
}
|
|
10901
10870
|
|
|
@@ -11272,10 +11241,10 @@ const PayWithSolanaToken = () => {
|
|
|
11272
11241
|
// Give user time to see the UI before opening
|
|
11273
11242
|
const transferTimeout = setTimeout(handleTransfer, 100);
|
|
11274
11243
|
return () => clearTimeout(transferTimeout);
|
|
11275
|
-
}, [selectedSolanaTokenOption]);
|
|
11244
|
+
}, [selectedSolanaTokenOption]); // eslint-disable-line react-hooks/exhaustive-deps
|
|
11276
11245
|
useEffect(() => {
|
|
11277
11246
|
triggerResize();
|
|
11278
|
-
}, [payState]);
|
|
11247
|
+
}, [payState]); // eslint-disable-line react-hooks/exhaustive-deps
|
|
11279
11248
|
return (jsxs(PageContent, { children: [selectedSolanaTokenOption && (jsx(TokenLogoSpinner, { token: selectedSolanaTokenOption.required.token })), jsxs(ModalContent, { style: { paddingBottom: 0 }, children: [jsx(ModalH1, { children: payState }), selectedSolanaTokenOption && (jsx(PaymentBreakdown, { paymentOption: selectedSolanaTokenOption })), payState === PayState.RequestCancelled && (jsx(Button, { onClick: handleTransfer, children: "Retry Payment" }))] })] }));
|
|
11280
11249
|
};
|
|
11281
11250
|
|
|
@@ -11288,13 +11257,55 @@ const SelectSolanaAmount = () => {
|
|
|
11288
11257
|
return (jsx(MultiCurrencySelectAmount, { selectedTokenOption: selectedSolanaTokenOption, setSelectedTokenOption: setSelectedSolanaTokenOption, nextPage: ROUTES.SOLANA_PAY_WITH_TOKEN }));
|
|
11289
11258
|
};
|
|
11290
11259
|
|
|
11291
|
-
const
|
|
11260
|
+
const CircleTimer = ({ total, size = 24, stroke = 3, currentTime, onTimeChange, children, }) => {
|
|
11261
|
+
// timestamp (ms) when timer ends
|
|
11262
|
+
const [target, setTarget] = useState(Date.now() + (currentTime ?? total) * 1000);
|
|
11263
|
+
const [left, setLeft] = useState(currentTime ?? total);
|
|
11264
|
+
// react to external currentTime updates
|
|
11265
|
+
useEffect(() => {
|
|
11266
|
+
if (currentTime !== undefined) {
|
|
11267
|
+
setTarget(Date.now() + currentTime * 1000);
|
|
11268
|
+
setLeft(currentTime);
|
|
11269
|
+
}
|
|
11270
|
+
}, [currentTime]);
|
|
11271
|
+
// interval tick
|
|
11272
|
+
useEffect(() => {
|
|
11273
|
+
const id = setInterval(() => {
|
|
11274
|
+
const secs = Math.max(0, Math.ceil((target - Date.now()) / 1000));
|
|
11275
|
+
setLeft(secs);
|
|
11276
|
+
onTimeChange?.(secs);
|
|
11277
|
+
if (secs === 0)
|
|
11278
|
+
clearInterval(id);
|
|
11279
|
+
}, 1000);
|
|
11280
|
+
return () => clearInterval(id);
|
|
11281
|
+
}, [target, onTimeChange]);
|
|
11282
|
+
const ratio = Math.round((left * 100) / total); // 0-100
|
|
11283
|
+
const radius = Math.round((size - stroke) / 2); // integer radius
|
|
11284
|
+
const circumference = Math.round((2 * 314 * radius) / 100); // 2πr, π≈3.14
|
|
11285
|
+
const dashoffset = Math.round((circumference * (100 - ratio)) / 100);
|
|
11286
|
+
// colour transition: green → orange → red
|
|
11287
|
+
const color = ratio <= 10
|
|
11288
|
+
? "var(--timer-red, #D92D20)"
|
|
11289
|
+
: ratio <= 40
|
|
11290
|
+
? "var(--timer-orange, #F79009)"
|
|
11291
|
+
: "var(--timer-green, #12D18E)";
|
|
11292
|
+
const center = Math.round(size / 2);
|
|
11293
|
+
return (jsxs("svg", { viewBox: `0 0 ${size} ${size}`, width: size, height: size, role: "img", "aria-label": `Timer: ${left}s left of ${total}s`, children: [jsx("circle", { cx: center, cy: center, r: radius, fill: "transparent", stroke: "var(--ck-body-background-secondary, #EEE)", strokeWidth: stroke }), jsx("circle", { cx: center, cy: center, r: radius, fill: "transparent", stroke: color, strokeWidth: stroke, strokeDasharray: circumference, strokeDashoffset: dashoffset, strokeLinecap: "round", style: { transition: "stroke-dashoffset 1s linear" }, transform: `rotate(-90 ${center} ${center})` }), children && (jsx("foreignObject", { x: "0", y: "0", width: size, height: size, children: jsx("div", { style: {
|
|
11294
|
+
display: "flex",
|
|
11295
|
+
alignItems: "center",
|
|
11296
|
+
justifyContent: "center",
|
|
11297
|
+
width: "100%",
|
|
11298
|
+
height: "100%",
|
|
11299
|
+
}, children: children }) }))] }));
|
|
11300
|
+
};
|
|
11301
|
+
|
|
11302
|
+
function WaitingDepositAddress() {
|
|
11292
11303
|
const context = usePayContext();
|
|
11293
11304
|
const { triggerResize, paymentState } = context;
|
|
11294
11305
|
const { payWithDepositAddress, selectedDepositAddressOption } = paymentState;
|
|
11295
11306
|
const [details, setDetails] = useState();
|
|
11296
11307
|
const [failed, setFailed] = useState(false);
|
|
11297
|
-
|
|
11308
|
+
const generateDepositAddress = () => {
|
|
11298
11309
|
if (!selectedDepositAddressOption)
|
|
11299
11310
|
return;
|
|
11300
11311
|
payWithDepositAddress(selectedDepositAddressOption.id).then((details) => {
|
|
@@ -11303,12 +11314,172 @@ const WaitingDepositAddress = () => {
|
|
|
11303
11314
|
else
|
|
11304
11315
|
setDetails(details);
|
|
11305
11316
|
});
|
|
11306
|
-
}
|
|
11317
|
+
};
|
|
11318
|
+
// TODO: load payment status, show underpayment
|
|
11319
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
11320
|
+
useEffect(generateDepositAddress, [selectedDepositAddressOption]);
|
|
11321
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
11322
|
+
useEffect(triggerResize, [details]);
|
|
11323
|
+
return (jsx(PageContent, { children: selectedDepositAddressOption == null ? null : failed ? (jsx(DepositFailed, { meta: selectedDepositAddressOption })) : (jsx(DepositAddressInfo, { meta: selectedDepositAddressOption, details: details, refresh: generateDepositAddress })) }));
|
|
11324
|
+
}
|
|
11325
|
+
function DepositAddressInfo({ meta, details, refresh, }) {
|
|
11326
|
+
const { isMobile } = useIsMobile();
|
|
11327
|
+
const [remainingS, totalS] = useCountdown(details?.expirationS);
|
|
11328
|
+
const isExpired = details?.expirationS != null && remainingS === 0;
|
|
11329
|
+
return (jsxs(ModalContent, { children: [isExpired ? (jsx(LogoWrap, { children: jsx(Button, { onClick: refresh, style: { width: 128 }, children: "Refresh" }) })) : isMobile ? (jsx(LogoWrap, { children: jsx("img", { src: meta.logoURI, width: "64px", height: "64px" }) })) : (jsx(QRWrap, { children: jsx(CustomQRCode, { value: details?.uri, contentPadding: 24, size: 200, image: jsx("img", { src: meta.logoURI, width: "100%", height: "100%" }) }) })), jsx(CopyableInfo, { meta: meta, details: details, remainingS: remainingS, totalS: totalS })] }));
|
|
11330
|
+
}
|
|
11331
|
+
const LogoWrap = styled.div `
|
|
11332
|
+
padding: 32px 0;
|
|
11333
|
+
height: 128px;
|
|
11334
|
+
display: flex;
|
|
11335
|
+
align-items: center;
|
|
11336
|
+
justify-content: center;
|
|
11337
|
+
`;
|
|
11338
|
+
const QRWrap = styled.div `
|
|
11339
|
+
margin: 0 auto;
|
|
11340
|
+
width: 280px;
|
|
11341
|
+
`;
|
|
11342
|
+
function CopyableInfo({ meta, details, remainingS, totalS, }) {
|
|
11343
|
+
const currencies = details?.suffix;
|
|
11344
|
+
const isExpired = details?.expirationS != null && remainingS === 0;
|
|
11345
|
+
return (jsxs(CopyableInfoWrapper, { children: [jsx(CopyRowOrThrobber, { title: "Send Exactly", value: details?.amount, smallText: currencies, disabled: isExpired }), jsx(CopyRowOrThrobber, { title: "Receiving Address", value: details?.address, valueText: details && getAddressContraction(details.address), disabled: isExpired }), jsx(CountdownWrap, { children: jsx(CountdownTimer, { remainingS: remainingS, totalS: totalS }) })] }));
|
|
11346
|
+
}
|
|
11347
|
+
const CopyableInfoWrapper = styled.div `
|
|
11348
|
+
display: flex;
|
|
11349
|
+
flex-direction: column;
|
|
11350
|
+
justify-content: stretch;
|
|
11351
|
+
gap: 0;
|
|
11352
|
+
margin-top: 8px;
|
|
11353
|
+
`;
|
|
11354
|
+
const CountdownWrap = styled.div `
|
|
11355
|
+
margin-top: 24px;
|
|
11356
|
+
height: 16px;
|
|
11357
|
+
`;
|
|
11358
|
+
function useCountdown(expirationS) {
|
|
11359
|
+
const [initMs] = useState(Date.now());
|
|
11360
|
+
const [ms, setMs] = useState(initMs);
|
|
11307
11361
|
useEffect(() => {
|
|
11308
|
-
|
|
11309
|
-
|
|
11310
|
-
|
|
11362
|
+
const interval = setInterval(() => setMs(Date.now()), 1000);
|
|
11363
|
+
return () => clearInterval(interval);
|
|
11364
|
+
}, []);
|
|
11365
|
+
if (expirationS == null)
|
|
11366
|
+
return [0, 0];
|
|
11367
|
+
const remainingS = Math.max(0, (expirationS - ms / 1000) | 0);
|
|
11368
|
+
const totalS = Math.max(0, (expirationS - initMs / 1000) | 0);
|
|
11369
|
+
return [remainingS, totalS];
|
|
11370
|
+
}
|
|
11371
|
+
function CountdownTimer({ remainingS, totalS, }) {
|
|
11372
|
+
if (totalS == 0)
|
|
11373
|
+
return null;
|
|
11374
|
+
if (remainingS > 3600)
|
|
11375
|
+
return null;
|
|
11376
|
+
const isExpired = remainingS === 0;
|
|
11377
|
+
return (jsx(ModalBody, { children: jsxs(CountdownRow, { children: [jsx(CircleTimer, { total: totalS, currentTime: remainingS, size: 18, stroke: 3 }), jsx("strong", { children: isExpired ? "Expired" : formatTime(remainingS) })] }) }));
|
|
11378
|
+
}
|
|
11379
|
+
const CountdownRow = styled.div `
|
|
11380
|
+
display: flex;
|
|
11381
|
+
align-items: center;
|
|
11382
|
+
justify-content: center;
|
|
11383
|
+
gap: 8px;
|
|
11384
|
+
font-variant-numeric: tabular-nums;
|
|
11385
|
+
`;
|
|
11386
|
+
const formatTime = (sec) => {
|
|
11387
|
+
const m = `${Math.floor(sec / 60)}`.padStart(2, "0");
|
|
11388
|
+
const s = `${sec % 60}`.padStart(2, "0");
|
|
11389
|
+
return `${m}:${s}`;
|
|
11311
11390
|
};
|
|
11391
|
+
function DepositFailed({ meta, }) {
|
|
11392
|
+
return (jsxs(ModalContent, { style: { marginLeft: 24, marginRight: 24 }, children: [jsxs(ModalH1, { children: [meta.id, " unavailable"] }), jsxs(ModalBody, { children: ["We're unable to process ", meta.id, " payments at this time. Please select another payment method."] }), jsx(SelectAnotherMethodButton, {})] }));
|
|
11393
|
+
}
|
|
11394
|
+
const CopyRow = styled.button `
|
|
11395
|
+
display: block;
|
|
11396
|
+
height: 64px;
|
|
11397
|
+
border-radius: 8px;
|
|
11398
|
+
padding: 8px 16px;
|
|
11399
|
+
|
|
11400
|
+
cursor: pointer;
|
|
11401
|
+
|
|
11402
|
+
display: flex;
|
|
11403
|
+
align-items: center;
|
|
11404
|
+
justify-content: space-between;
|
|
11405
|
+
|
|
11406
|
+
transition: all 100ms ease;
|
|
11407
|
+
|
|
11408
|
+
&:hover {
|
|
11409
|
+
opacity: 0.8;
|
|
11410
|
+
}
|
|
11411
|
+
|
|
11412
|
+
&:active {
|
|
11413
|
+
transform: scale(0.98);
|
|
11414
|
+
background-color: var(--ck-body-background-secondary);
|
|
11415
|
+
}
|
|
11416
|
+
|
|
11417
|
+
&:disabled {
|
|
11418
|
+
cursor: default;
|
|
11419
|
+
opacity: 0.5;
|
|
11420
|
+
transform: scale(0.98);
|
|
11421
|
+
background-color: var(--ck-body-background-secondary);
|
|
11422
|
+
}
|
|
11423
|
+
`;
|
|
11424
|
+
const LabelRow = styled.div `
|
|
11425
|
+
margin-bottom: 4px;
|
|
11426
|
+
`;
|
|
11427
|
+
const MainRow = styled.div `
|
|
11428
|
+
display: flex;
|
|
11429
|
+
align-items: center;
|
|
11430
|
+
justify-content: space-between;
|
|
11431
|
+
`;
|
|
11432
|
+
const ValueContainer = styled.div `
|
|
11433
|
+
display: flex;
|
|
11434
|
+
align-items: center;
|
|
11435
|
+
gap: 8px;
|
|
11436
|
+
`;
|
|
11437
|
+
const SmallText = styled.span `
|
|
11438
|
+
font-size: 14px;
|
|
11439
|
+
color: var(--ck-body-color-muted);
|
|
11440
|
+
`;
|
|
11441
|
+
const pulse = keyframes `
|
|
11442
|
+
0% {
|
|
11443
|
+
opacity: 0.6;
|
|
11444
|
+
}
|
|
11445
|
+
50% {
|
|
11446
|
+
opacity: 1;
|
|
11447
|
+
}
|
|
11448
|
+
100% {
|
|
11449
|
+
opacity: 0.6;
|
|
11450
|
+
}
|
|
11451
|
+
`;
|
|
11452
|
+
const Skeleton = styled.div `
|
|
11453
|
+
width: 80px;
|
|
11454
|
+
height: 16px;
|
|
11455
|
+
border-radius: 8px;
|
|
11456
|
+
background-color: rgba(0, 0, 0, 0.1);
|
|
11457
|
+
animation: ${pulse} 1.5s ease-in-out infinite;
|
|
11458
|
+
`;
|
|
11459
|
+
function CopyRowOrThrobber({ title, value, valueText, smallText, disabled, }) {
|
|
11460
|
+
const [copied, setCopied] = useState(false);
|
|
11461
|
+
const handleCopy = () => {
|
|
11462
|
+
if (disabled)
|
|
11463
|
+
return;
|
|
11464
|
+
if (!value)
|
|
11465
|
+
return;
|
|
11466
|
+
const str = value.trim();
|
|
11467
|
+
if (navigator.clipboard) {
|
|
11468
|
+
navigator.clipboard.writeText(str);
|
|
11469
|
+
}
|
|
11470
|
+
setCopied(true);
|
|
11471
|
+
setTimeout(() => setCopied(false), 1000);
|
|
11472
|
+
};
|
|
11473
|
+
if (!value) {
|
|
11474
|
+
return (jsxs(CopyRow, { children: [jsx(LabelRow, { children: jsx(ModalBody, { style: { margin: 0, textAlign: "left" }, children: title }) }), jsx(MainRow, { children: jsx(Skeleton, {}) })] }));
|
|
11475
|
+
}
|
|
11476
|
+
const displayValue = valueText || value;
|
|
11477
|
+
return (jsxs(CopyRow, { as: "button", onClick: handleCopy, disabled: disabled, children: [jsxs("div", { children: [jsx(LabelRow, { children: jsx(ModalBody, { style: { margin: 0, textAlign: "left" }, children: title }) }), jsx(MainRow, { children: jsxs(ValueContainer, { children: [jsx("span", { style: { fontWeight: 600 }, children: displayValue }), smallText && jsx(SmallText, { children: smallText })] }) })] }), jsx(CopyIconWrap, { children: jsx(CopyToClipboardIcon, { copied: copied, dark: true }) })] }));
|
|
11478
|
+
}
|
|
11479
|
+
const CopyIconWrap = styled.div `
|
|
11480
|
+
--color: var(--ck-copytoclipboard-stroke);
|
|
11481
|
+
--bg: var(--ck-body-background);
|
|
11482
|
+
`;
|
|
11312
11483
|
|
|
11313
11484
|
const WaitingExternal = () => {
|
|
11314
11485
|
const context = usePayContext();
|
|
@@ -11332,7 +11503,7 @@ const WaitingExternal = () => {
|
|
|
11332
11503
|
setExternalURL(url);
|
|
11333
11504
|
openExternalWindow(url);
|
|
11334
11505
|
});
|
|
11335
|
-
}, [selectedExternalOption]);
|
|
11506
|
+
}, [selectedExternalOption]); // eslint-disable-line react-hooks/exhaustive-deps
|
|
11336
11507
|
const openExternalWindow = (url) => {
|
|
11337
11508
|
if (isMobile || isPaymentApp) {
|
|
11338
11509
|
// on mobile: open in a new tab
|
|
@@ -11355,7 +11526,7 @@ const WaitingExternal = () => {
|
|
|
11355
11526
|
const waitingMessageLength = paymentWaitingMessage?.length;
|
|
11356
11527
|
useEffect(() => {
|
|
11357
11528
|
triggerResize();
|
|
11358
|
-
}, [waitingMessageLength, externalURL]);
|
|
11529
|
+
}, [waitingMessageLength, externalURL]); // eslint-disable-line react-hooks/exhaustive-deps
|
|
11359
11530
|
if (!selectedExternalOption) {
|
|
11360
11531
|
return jsx(PageContent, {});
|
|
11361
11532
|
}
|
|
@@ -11714,7 +11885,7 @@ function useDepositAddressOptions({ trpc, usdRequired, mode, }) {
|
|
|
11714
11885
|
if (usdRequired != null && mode != null) {
|
|
11715
11886
|
refreshDepositAddressOptions(usdRequired, mode);
|
|
11716
11887
|
}
|
|
11717
|
-
}, [usdRequired, mode]);
|
|
11888
|
+
}, [usdRequired, mode]); // eslint-disable-line react-hooks/exhaustive-deps
|
|
11718
11889
|
return { options, loading };
|
|
11719
11890
|
}
|
|
11720
11891
|
|
|
@@ -11781,7 +11952,7 @@ function useOrderUsdLimits({ trpc }) {
|
|
|
11781
11952
|
}
|
|
11782
11953
|
};
|
|
11783
11954
|
refreshOrderUsdLimits();
|
|
11784
|
-
}, []);
|
|
11955
|
+
}, []); // eslint-disable-line react-hooks/exhaustive-deps
|
|
11785
11956
|
return { limits, loading };
|
|
11786
11957
|
}
|
|
11787
11958
|
|
|
@@ -11813,7 +11984,7 @@ function useSolanaPaymentOptions({ trpc, address, usdRequired, isDepositFlow, })
|
|
|
11813
11984
|
if (address != null && usdRequired != null) {
|
|
11814
11985
|
refreshWalletPaymentOptions();
|
|
11815
11986
|
}
|
|
11816
|
-
}, [address, usdRequired, isDepositFlow]);
|
|
11987
|
+
}, [address, usdRequired, isDepositFlow]); // eslint-disable-line react-hooks/exhaustive-deps
|
|
11817
11988
|
return {
|
|
11818
11989
|
options,
|
|
11819
11990
|
isLoading,
|
|
@@ -11858,6 +12029,7 @@ function useWalletPaymentOptions({ trpc, address, usdRequired, destChainId, pref
|
|
|
11858
12029
|
if (address != null && usdRequired != null && destChainId != null) {
|
|
11859
12030
|
refreshWalletPaymentOptions();
|
|
11860
12031
|
}
|
|
12032
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
11861
12033
|
}, [
|
|
11862
12034
|
address,
|
|
11863
12035
|
usdRequired,
|
|
@@ -12061,9 +12233,36 @@ function usePaymentState({ trpc, lockPayParams, setRoute, log, redirectReturnUrl
|
|
|
12061
12233
|
return externalPaymentOptionData.url;
|
|
12062
12234
|
};
|
|
12063
12235
|
const payWithDepositAddress = async (option) => {
|
|
12064
|
-
assert(pay.paymentState == "payment_unpaid", `[PAY DEPOSIT ADDRESS] paymentState is ${pay.paymentState}, must be payment_unpaid`);
|
|
12065
12236
|
const { order: hydratedOrder } = await pay.hydrateOrder();
|
|
12066
|
-
log(`[PAY DEPOSIT ADDRESS] hydrated order: ${
|
|
12237
|
+
log(`[PAY DEPOSIT ADDRESS] hydrated order: ${debugJson(hydratedOrder)}, checking out with deposit address: ${option}`);
|
|
12238
|
+
// Special-case: USDT on Tron uses the Untron service rather than ChangeNow
|
|
12239
|
+
const payParams = currPayParams;
|
|
12240
|
+
if (option === DepositAddressPaymentOptions.TRON_USDT) {
|
|
12241
|
+
// Ensure we have an appId for auth to backend
|
|
12242
|
+
assert(payParams?.appId != null, "[PAY DEPOSIT ADDRESS] missing appId required for Tron USDT payments");
|
|
12243
|
+
// Round up to the nearest integer number of USDT to avoid fractional tokens.
|
|
12244
|
+
const usd = hydratedOrder.usdValue.toFixed(2);
|
|
12245
|
+
const amountTronUSDT = parseUnits(usd, 6);
|
|
12246
|
+
const untronResp = await trpc.untronTryCreateOrder.mutate({
|
|
12247
|
+
appId: payParams.appId,
|
|
12248
|
+
intentAddr: assertNotNull(hydratedOrder.intentAddr, `[PAY DEPOSIT ADDRESS] missing intentAddr on order ${hydratedOrder.id}`),
|
|
12249
|
+
amountTronUSDT: Number(amountTronUSDT),
|
|
12250
|
+
});
|
|
12251
|
+
if ("error" in untronResp) {
|
|
12252
|
+
log(`[PAY DEPOSIT ADDRESS] failed to create Untron order: ${untronResp.error}`);
|
|
12253
|
+
return null;
|
|
12254
|
+
}
|
|
12255
|
+
const untronOrder = untronResp.untronOrder;
|
|
12256
|
+
// Map Untron response to the generic deposit-address shape expected by the UI
|
|
12257
|
+
return {
|
|
12258
|
+
address: untronOrder.receiver,
|
|
12259
|
+
amount: usd,
|
|
12260
|
+
suffix: "USDT on Tron",
|
|
12261
|
+
uri: `tron:${untronOrder.receiver}`,
|
|
12262
|
+
expirationS: untronOrder.expiresAtS - 60,
|
|
12263
|
+
};
|
|
12264
|
+
}
|
|
12265
|
+
// Default behaviour for all other tokens via ChangeNow
|
|
12067
12266
|
const depositAddressOption = await trpc.getDepositAddressOptionData.query({
|
|
12068
12267
|
input: option,
|
|
12069
12268
|
usdRequired: hydratedOrder.destFinalCallTokenAmount.usd,
|