@daimo/pay 1.2.0 → 1.3.1
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 +21 -19
- package/build/package.json.js +3 -3
- package/build/src/components/Common/AmountInput/index.js +5 -1
- package/build/src/components/Common/AmountInput/index.js.map +1 -1
- package/build/src/components/DaimoPay.js +42 -12
- package/build/src/components/DaimoPay.js.map +1 -1
- package/build/src/components/DaimoPayButton/index.js +31 -24
- package/build/src/components/DaimoPayButton/index.js.map +1 -1
- package/build/src/components/DaimoPayModal/index.js +31 -25
- package/build/src/components/DaimoPayModal/index.js.map +1 -1
- package/build/src/components/Pages/Confirmation/index.js +1 -1
- package/build/src/components/Pages/PayWithToken/index.js +1 -1
- package/build/src/components/Pages/SelectDepositAddressAmount/index.js +3 -2
- package/build/src/components/Pages/SelectDepositAddressAmount/index.js.map +1 -1
- package/build/src/components/Pages/SelectDepositAddressChain/index.js +3 -2
- package/build/src/components/Pages/SelectDepositAddressChain/index.js.map +1 -1
- package/build/src/components/Pages/SelectExternalAmount/index.js +3 -2
- package/build/src/components/Pages/SelectExternalAmount/index.js.map +1 -1
- package/build/src/components/Pages/SelectMethod/index.js +10 -4
- package/build/src/components/Pages/SelectMethod/index.js.map +1 -1
- package/build/src/components/Pages/SelectToken/index.js +7 -2
- package/build/src/components/Pages/SelectToken/index.js.map +1 -1
- package/build/src/components/Pages/Solana/ConnectSolana/index.js +5 -2
- package/build/src/components/Pages/Solana/ConnectSolana/index.js.map +1 -1
- package/build/src/components/Pages/Solana/ConnectorSolana/index.js +5 -1
- package/build/src/components/Pages/Solana/ConnectorSolana/index.js.map +1 -1
- package/build/src/components/Pages/Solana/PayWithSolanaToken/index.js +4 -33
- package/build/src/components/Pages/Solana/PayWithSolanaToken/index.js.map +1 -1
- package/build/src/components/Pages/Solana/SelectSolanaToken/index.js +7 -2
- package/build/src/components/Pages/Solana/SelectSolanaToken/index.js.map +1 -1
- package/build/src/components/Pages/WaitingDepositAddress/index.js +1 -1
- package/build/src/components/Pages/WaitingExternal/index.js +1 -1
- package/build/src/hooks/useDaimoPayStatus.js +3 -16
- package/build/src/hooks/useDaimoPayStatus.js.map +1 -1
- package/build/src/hooks/usePayWithSolanaToken.js +4 -3
- package/build/src/hooks/usePayWithSolanaToken.js.map +1 -1
- package/build/src/hooks/usePayWithToken.js +7 -8
- package/build/src/hooks/usePayWithToken.js.map +1 -1
- package/build/src/hooks/usePaymentState.js +27 -20
- package/build/src/hooks/usePaymentState.js.map +1 -1
- package/build/src/index.js +1 -2
- package/build/src/index.js.map +1 -1
- package/build/src/utils/exports.js +1 -8
- package/build/src/utils/exports.js.map +1 -1
- package/build/src/utils/trpc.js +2 -1
- package/build/src/utils/trpc.js.map +1 -1
- package/package.json +4 -4
- package/build/src/hooks/useModal.js +0 -35
- package/build/src/hooks/useModal.js.map +0 -1
|
@@ -34,11 +34,16 @@ const SelectToken = () => {
|
|
|
34
34
|
],
|
|
35
35
|
onClick: () => {
|
|
36
36
|
setSelectedTokenOption(option);
|
|
37
|
+
const meta = {
|
|
38
|
+
event: "click-token",
|
|
39
|
+
tokenSymbol: option.balance.token.symbol,
|
|
40
|
+
chainId: option.balance.token.chainId,
|
|
41
|
+
};
|
|
37
42
|
if (isDepositFlow) {
|
|
38
|
-
setRoute(ROUTES.SELECT_AMOUNT);
|
|
43
|
+
setRoute(ROUTES.SELECT_AMOUNT, meta);
|
|
39
44
|
}
|
|
40
45
|
else {
|
|
41
|
-
setRoute(ROUTES.PAY_WITH_TOKEN);
|
|
46
|
+
setRoute(ROUTES.PAY_WITH_TOKEN, meta);
|
|
42
47
|
}
|
|
43
48
|
},
|
|
44
49
|
disabled,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -20,7 +20,10 @@ const ConnectSolana = () => {
|
|
|
20
20
|
if (solanaWallets.connected) {
|
|
21
21
|
await solanaWallets.disconnect();
|
|
22
22
|
}
|
|
23
|
-
setRoute(ROUTES.SOLANA_CONNECTOR
|
|
23
|
+
setRoute(ROUTES.SOLANA_CONNECTOR, {
|
|
24
|
+
event: "click-solana-wallet",
|
|
25
|
+
walletName: wallet.adapter.name,
|
|
26
|
+
});
|
|
24
27
|
},
|
|
25
28
|
}));
|
|
26
29
|
return (jsxs(PageContent, { children: [jsx(OrderHeader, { minified: true }), solanaWallets.wallets.length === 0 && (jsxs(ModalContent, { style: {
|
|
@@ -29,7 +32,7 @@ const ConnectSolana = () => {
|
|
|
29
32
|
justifyContent: "center",
|
|
30
33
|
paddingTop: 16,
|
|
31
34
|
paddingBottom: 16,
|
|
32
|
-
}, children: [jsx(ModalH1, { children: "No Solana wallets detected." }), jsx(Button, { onClick: () => setRoute(ROUTES.SELECT_METHOD), children: "Select Another Method" })] })), jsx(OptionsList, { options: options })] }));
|
|
35
|
+
}, children: [jsx(ModalH1, { children: "No Solana wallets detected." }), jsx(Button, { onClick: () => setRoute(ROUTES.SELECT_METHOD, { event: "click-select-another" }), children: "Select Another Method" })] })), jsx(OptionsList, { options: options })] }));
|
|
33
36
|
};
|
|
34
37
|
const SquircleIcon = ({ icon, alt }) => (jsx("div", { style: { borderRadius: "22.5%", overflow: "hidden" }, children: jsx("img", { src: icon, alt: alt }) }));
|
|
35
38
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -20,7 +20,11 @@ const ConnectSolana = () => {
|
|
|
20
20
|
useEffect(() => {
|
|
21
21
|
if (isConnected) {
|
|
22
22
|
// Wait so user can see it's connected
|
|
23
|
-
|
|
23
|
+
const meta = {
|
|
24
|
+
event: "wait-solana-connected",
|
|
25
|
+
walletName: solanaWallets.wallet?.adapter.name,
|
|
26
|
+
};
|
|
27
|
+
setTimeout(() => setRoute(ROUTES.SOLANA_SELECT_TOKEN, meta), 500);
|
|
24
28
|
}
|
|
25
29
|
}, [isConnected]);
|
|
26
30
|
if (!solanaConnector)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -4,9 +4,6 @@ import { usePayContext, ROUTES } from '../../../DaimoPay.js';
|
|
|
4
4
|
import { WalletSignTransactionError, WalletSendTransactionError } from '@solana/wallet-adapter-base';
|
|
5
5
|
import { PageContent, ModalContent, ModalH1 } from '../../../Common/Modal/styles.js';
|
|
6
6
|
import { assert } from '@daimo/common';
|
|
7
|
-
import { motion } from 'framer-motion';
|
|
8
|
-
import { css } from 'styled-components';
|
|
9
|
-
import styled from '../../../../styles/styled/index.js';
|
|
10
7
|
import Button from '../../../Common/Button/index.js';
|
|
11
8
|
import PaymentBreakdown from '../../../Common/PaymentBreakdown/index.js';
|
|
12
9
|
import TokenLogoSpinner from '../../../Spinners/TokenLogoSpinner/index.js';
|
|
@@ -25,11 +22,11 @@ const PayWithSolanaToken = () => {
|
|
|
25
22
|
const handleTransfer = async () => {
|
|
26
23
|
try {
|
|
27
24
|
setPayState(PayState.RequestingPayment);
|
|
28
|
-
assert(!!selectedSolanaTokenOption, "No token option selected");
|
|
25
|
+
assert(!!selectedSolanaTokenOption, "[PAY SOLANA] No token option selected");
|
|
29
26
|
await payWithSolanaToken(selectedSolanaTokenOption.required.token.token);
|
|
30
27
|
setPayState(PayState.RequestSuccessful);
|
|
31
28
|
setTimeout(() => {
|
|
32
|
-
setRoute(ROUTES.CONFIRMATION);
|
|
29
|
+
setRoute(ROUTES.CONFIRMATION, { event: "wait-pay-with-solana" });
|
|
33
30
|
}, 200);
|
|
34
31
|
}
|
|
35
32
|
catch (error) {
|
|
@@ -55,37 +52,11 @@ const PayWithSolanaToken = () => {
|
|
|
55
52
|
triggerResize();
|
|
56
53
|
}, [payState]);
|
|
57
54
|
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" })), payState === PayState.RequestFailed && (jsx(Button, { onClick: () => {
|
|
58
|
-
assert(payParams != null, "payParams cannot be null in deposit flow");
|
|
55
|
+
assert(payParams != null, "[PAY SOLANA] payParams cannot be null in deposit flow");
|
|
59
56
|
generatePreviewOrder(payParams);
|
|
60
|
-
setRoute(ROUTES.SELECT_METHOD);
|
|
57
|
+
setRoute(ROUTES.SELECT_METHOD, { event: "click-select-another" });
|
|
61
58
|
}, children: "Select Another Method" }))] })] }));
|
|
62
59
|
};
|
|
63
|
-
styled(motion.div) `
|
|
64
|
-
display: flex;
|
|
65
|
-
align-items: center;
|
|
66
|
-
justify-content: center;
|
|
67
|
-
margin: 10px auto 16px;
|
|
68
|
-
height: 120px;
|
|
69
|
-
`;
|
|
70
|
-
styled(motion.div) `
|
|
71
|
-
user-select: none;
|
|
72
|
-
position: relative;
|
|
73
|
-
--spinner-error-opacity: 0;
|
|
74
|
-
&:before {
|
|
75
|
-
content: "";
|
|
76
|
-
position: absolute;
|
|
77
|
-
inset: 1px;
|
|
78
|
-
opacity: 0;
|
|
79
|
-
background: var(--ck-body-color-danger);
|
|
80
|
-
${(props) => props.$circle &&
|
|
81
|
-
css `
|
|
82
|
-
inset: -5px;
|
|
83
|
-
border-radius: 50%;
|
|
84
|
-
background: none;
|
|
85
|
-
box-shadow: inset 0 0 0 3.5px var(--ck-body-color-danger);
|
|
86
|
-
`}
|
|
87
|
-
}
|
|
88
|
-
`;
|
|
89
60
|
|
|
90
61
|
export { PayWithSolanaToken as default };
|
|
91
62
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -31,11 +31,16 @@ const SelectSolanaToken = () => {
|
|
|
31
31
|
],
|
|
32
32
|
onClick: () => {
|
|
33
33
|
setSelectedSolanaTokenOption(option);
|
|
34
|
+
const meta = {
|
|
35
|
+
event: "click-solana-token",
|
|
36
|
+
tokenSymbol: option.balance.token.symbol,
|
|
37
|
+
chainId: option.balance.token.chainId,
|
|
38
|
+
};
|
|
34
39
|
if (isDepositFlow) {
|
|
35
|
-
setRoute(ROUTES.SOLANA_SELECT_AMOUNT);
|
|
40
|
+
setRoute(ROUTES.SOLANA_SELECT_AMOUNT, meta);
|
|
36
41
|
}
|
|
37
42
|
else {
|
|
38
|
-
setRoute(ROUTES.SOLANA_PAY_WITH_TOKEN);
|
|
43
|
+
setRoute(ROUTES.SOLANA_PAY_WITH_TOKEN, meta);
|
|
39
44
|
}
|
|
40
45
|
},
|
|
41
46
|
disabled,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -44,7 +44,7 @@ const WaitingDepositAddress = () => {
|
|
|
44
44
|
useEffect(() => {
|
|
45
45
|
triggerResize();
|
|
46
46
|
}, [details]);
|
|
47
|
-
return (jsx(PageContent, { children: failed ? (jsxs(ModalContent, { style: { marginLeft: 24, marginRight: 24 }, children: [jsxs(ModalH1, { children: [selectedDepositAddressOption?.id, " unavailable"] }), jsxs(ModalBody, { children: ["We're unable to process ", selectedDepositAddressOption?.id, " payments at this time. Please select another payment method."] }), jsx(Button, { onClick: () => setRoute(ROUTES.SELECT_METHOD), children: "Select Another Method" })] })) : (jsxs(ModalContent, { children: [jsx(CustomQRCode, { value: details?.uri, image: jsx("img", { src: selectedDepositAddressOption?.logoURI, width: "100%", height: "100%" }), tooltipMessage: jsxs(Fragment, { children: [jsx(ScanIconWithLogos, { logo: jsx("img", { src: selectedDepositAddressOption?.logoURI }) }), jsxs("span", { children: ["Use a ", selectedDepositAddressOption?.id, " wallet to scan"] })] }) }), details && (jsxs(Fragment, { children: [jsx(OrDivider, {}), jsxs(ModalBody, { children: ["Send exactly ", details.amount, " ", details.suffix, " to", " ", getAddressContraction(details.address), " and return to this page. Confirmation should appear in a few minutes."] }), jsx(CopyToClipboard, { variant: "button", string: details.address, children: "Copy Address" }), jsx(CopyToClipboard, { variant: "left", string: details.amount, children: "Copy Amount" })] }))] })) }));
|
|
47
|
+
return (jsx(PageContent, { children: failed ? (jsxs(ModalContent, { style: { marginLeft: 24, marginRight: 24 }, children: [jsxs(ModalH1, { children: [selectedDepositAddressOption?.id, " unavailable"] }), jsxs(ModalBody, { children: ["We're unable to process ", selectedDepositAddressOption?.id, " payments at this time. Please select another payment method."] }), jsx(Button, { onClick: () => setRoute(ROUTES.SELECT_METHOD, { event: "click-select-another" }), children: "Select Another Method" })] })) : (jsxs(ModalContent, { children: [jsx(CustomQRCode, { value: details?.uri, image: jsx("img", { src: selectedDepositAddressOption?.logoURI, width: "100%", height: "100%" }), tooltipMessage: jsxs(Fragment, { children: [jsx(ScanIconWithLogos, { logo: jsx("img", { src: selectedDepositAddressOption?.logoURI }) }), jsxs("span", { children: ["Use a ", selectedDepositAddressOption?.id, " wallet to scan"] })] }) }), details && (jsxs(Fragment, { children: [jsx(OrDivider, {}), jsxs(ModalBody, { children: ["Send exactly ", details.amount, " ", details.suffix, " to", " ", getAddressContraction(details.address), " and return to this page. Confirmation should appear in a few minutes."] }), jsx(CopyToClipboard, { variant: "button", string: details.address, children: "Copy Address" }), jsx(CopyToClipboard, { variant: "left", string: details.amount, children: "Copy Amount" })] }))] })) }));
|
|
48
48
|
};
|
|
49
49
|
|
|
50
50
|
export { WaitingDepositAddress as default };
|
|
@@ -20,7 +20,7 @@ const WaitingExternal = () => {
|
|
|
20
20
|
orderId: daimoPayOrder.id.toString(),
|
|
21
21
|
});
|
|
22
22
|
if (found) {
|
|
23
|
-
setRoute(ROUTES.CONFIRMATION);
|
|
23
|
+
setRoute(ROUTES.CONFIRMATION, { event: "found-source-payment" });
|
|
24
24
|
}
|
|
25
25
|
};
|
|
26
26
|
const interval = setInterval(checkForSourcePayment, 1000);
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { writeDaimoPayOrderID
|
|
1
|
+
import { writeDaimoPayOrderID } from '@daimo/common';
|
|
2
2
|
import { usePayContext } from '../components/DaimoPay.js';
|
|
3
3
|
|
|
4
4
|
/** Returns the current payment, or undefined if there is none.
|
|
5
5
|
*
|
|
6
6
|
* Status values:
|
|
7
|
-
* - `
|
|
7
|
+
* - `payment_unpaid` - the user has not paid yet
|
|
8
8
|
* - `payment_started` - the user has paid & payment is in progress. This status
|
|
9
9
|
* typically lasts a few seconds.
|
|
10
10
|
* - `payment_completed` - the final call or transfer succeeded
|
|
@@ -17,20 +17,7 @@ function useDaimoPayStatus() {
|
|
|
17
17
|
return undefined;
|
|
18
18
|
const order = paymentState.daimoPayOrder;
|
|
19
19
|
const paymentId = writeDaimoPayOrderID(order.id);
|
|
20
|
-
|
|
21
|
-
if (order.intentStatus !== DaimoPayIntentStatus.PENDING) {
|
|
22
|
-
if (order.intentStatus === DaimoPayIntentStatus.SUCCESSFUL) {
|
|
23
|
-
return { paymentId, status: "payment_completed" };
|
|
24
|
-
}
|
|
25
|
-
else {
|
|
26
|
-
return { paymentId, status: "payment_bounced" };
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
else if (order.sourceStatus !== DaimoPayOrderStatusSource.WAITING_PAYMENT) {
|
|
30
|
-
return { paymentId, status: "payment_started" };
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
return { paymentId, status: "payment_pending" };
|
|
20
|
+
return { paymentId, status: order.intentStatus };
|
|
34
21
|
}
|
|
35
22
|
|
|
36
23
|
export { useDaimoPayStatus };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useDaimoPayStatus.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"useDaimoPayStatus.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -7,8 +7,9 @@ function usePayWithSolanaToken({ trpc, daimoPayOrder, setDaimoPayOrder, createOr
|
|
|
7
7
|
const { connection } = useConnection();
|
|
8
8
|
const wallet = useWallet();
|
|
9
9
|
const payWithSolanaToken = async (inputToken) => {
|
|
10
|
-
assert(!!wallet.publicKey, "No wallet connected");
|
|
11
|
-
assert(!!
|
|
10
|
+
assert(!!wallet.publicKey, "[PAY SOLANA] No wallet connected");
|
|
11
|
+
assert(!!daimoPayOrder, "[PAY SOLANA] daimoPayOrder cannot be null");
|
|
12
|
+
assert(!!platform, "[PAY SOLANA] platform cannot be null");
|
|
12
13
|
const orderId = daimoPayOrder.id;
|
|
13
14
|
const { hydratedOrder } = await createOrHydrate({
|
|
14
15
|
order: daimoPayOrder,
|
|
@@ -18,7 +19,7 @@ function usePayWithSolanaToken({ trpc, daimoPayOrder, setDaimoPayOrder, createOr
|
|
|
18
19
|
try {
|
|
19
20
|
const serializedTx = await trpc.getSolanaSwapAndBurnTx.query({
|
|
20
21
|
orderId: orderId.toString(),
|
|
21
|
-
userPublicKey: assertNotNull(wallet.publicKey).toString(),
|
|
22
|
+
userPublicKey: assertNotNull(wallet.publicKey, "[PAY SOLANA] wallet.publicKey cannot be null").toString(),
|
|
22
23
|
inputTokenMint: inputToken,
|
|
23
24
|
});
|
|
24
25
|
const tx = VersionedTransaction.deserialize(hexToBytes(serializedTx));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"usePayWithSolanaToken.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"usePayWithSolanaToken.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -7,12 +7,14 @@ function usePayWithToken({ trpc, senderAddr, daimoPayOrder, setDaimoPayOrder, cr
|
|
|
7
7
|
const { sendTransactionAsync } = useSendTransaction();
|
|
8
8
|
/** Commit to a token + amount = initiate payment. */
|
|
9
9
|
const payWithToken = async (tokenAmount) => {
|
|
10
|
-
assert(!!daimoPayOrder
|
|
10
|
+
assert(!!daimoPayOrder, "[PAY TOKEN] daimoPayOrder cannot be null");
|
|
11
|
+
assert(!!platform, "[PAY TOKEN] platform cannot be null");
|
|
11
12
|
const { hydratedOrder } = await createOrHydrate({
|
|
12
13
|
order: daimoPayOrder,
|
|
13
14
|
refundAddress: senderAddr,
|
|
14
15
|
});
|
|
15
|
-
log(`[CHECKOUT]
|
|
16
|
+
log(`[CHECKOUT] hydrated order: ${JSON.stringify(hydratedOrder)}, checking out with ${tokenAmount.token.token}`);
|
|
17
|
+
setDaimoPayOrder(hydratedOrder);
|
|
16
18
|
const txHash = await (async () => {
|
|
17
19
|
try {
|
|
18
20
|
if (tokenAmount.token.token === zeroAddress) {
|
|
@@ -31,23 +33,20 @@ function usePayWithToken({ trpc, senderAddr, daimoPayOrder, setDaimoPayOrder, cr
|
|
|
31
33
|
}
|
|
32
34
|
}
|
|
33
35
|
catch (e) {
|
|
34
|
-
console.error(`[CHECKOUT]
|
|
35
|
-
setDaimoPayOrder(hydratedOrder);
|
|
36
|
+
console.error(`[CHECKOUT] error sending token: ${e}`);
|
|
36
37
|
throw e;
|
|
37
38
|
}
|
|
38
|
-
finally {
|
|
39
|
-
setDaimoPayOrder(hydratedOrder);
|
|
40
|
-
}
|
|
41
39
|
})();
|
|
42
40
|
if (txHash) {
|
|
43
41
|
await trpc.processSourcePayment.mutate({
|
|
44
42
|
orderId: daimoPayOrder.id.toString(),
|
|
45
43
|
sourceInitiateTxHash: txHash,
|
|
46
44
|
sourceChainId: tokenAmount.token.chainId,
|
|
47
|
-
sourceFulfillerAddr: assertNotNull(senderAddr),
|
|
45
|
+
sourceFulfillerAddr: assertNotNull(senderAddr, `[PAY TOKEN] senderAddr cannot be null on order ${daimoPayOrder.id}`),
|
|
48
46
|
sourceToken: tokenAmount.token.token,
|
|
49
47
|
sourceAmount: tokenAmount.amount,
|
|
50
48
|
});
|
|
49
|
+
// TODO: update order immediately, do not wait for polling.
|
|
51
50
|
}
|
|
52
51
|
};
|
|
53
52
|
return { payWithToken };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"usePayWithToken.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"usePayWithToken.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -4,7 +4,6 @@ import { useWallet } from '@solana/wallet-adapter-react';
|
|
|
4
4
|
import { useState, useEffect, useCallback } from 'react';
|
|
5
5
|
import { parseUnits, formatUnits } from 'viem';
|
|
6
6
|
import { useAccount, useEnsName } from 'wagmi';
|
|
7
|
-
import { generatePayId } from '../utils/exports.js';
|
|
8
7
|
import { detectPlatform } from '../utils/platform.js';
|
|
9
8
|
import { useDepositAddressOptions } from './useDepositAddressOptions.js';
|
|
10
9
|
import { useExternalPaymentOptions } from './useExternalPaymentOptions.js';
|
|
@@ -67,9 +66,9 @@ function usePaymentState({ trpc, daimoPayOrder, setDaimoPayOrder, setOpen, log,
|
|
|
67
66
|
const chainOrderUsdLimits = useOrderUsdLimits({ trpc });
|
|
68
67
|
/** Create a new order or hydrate an existing one. */
|
|
69
68
|
const createOrHydrate = async ({ order, refundAddress, externalPaymentOption, }) => {
|
|
70
|
-
assert(!!platform, "missing platform");
|
|
69
|
+
assert(!!platform, "[CREATE/HYDRATE] missing platform");
|
|
71
70
|
if (payParams == null) {
|
|
72
|
-
log(`[
|
|
71
|
+
log(`[CREATE/HYDRATE] hydrating existing order ${order.id}`);
|
|
73
72
|
return await trpc.hydrateOrder.query({
|
|
74
73
|
id: order.id.toString(),
|
|
75
74
|
chosenFinalTokenAmount: order.destFinalCallTokenAmount.amount,
|
|
@@ -78,7 +77,7 @@ function usePaymentState({ trpc, daimoPayOrder, setDaimoPayOrder, setOpen, log,
|
|
|
78
77
|
externalPaymentOption,
|
|
79
78
|
});
|
|
80
79
|
}
|
|
81
|
-
log(`[
|
|
80
|
+
log(`[CREATE/HYDRATE] creating+hydrating new order ${order.id}`);
|
|
82
81
|
// Update units, if isDepositFlow then the user may have changed the amount.
|
|
83
82
|
const toUnits = formatUnits(BigInt(order.destFinalCallTokenAmount.amount), order.destFinalCallTokenAmount.token.decimals);
|
|
84
83
|
return await trpc.createOrder.mutate({
|
|
@@ -88,6 +87,7 @@ function usePaymentState({ trpc, daimoPayOrder, setDaimoPayOrder, setOpen, log,
|
|
|
88
87
|
id: order.id.toString(),
|
|
89
88
|
toUnits,
|
|
90
89
|
metadata: order.metadata,
|
|
90
|
+
userMetadata: payParams.metadata,
|
|
91
91
|
isAmountEditable: isDepositFlow,
|
|
92
92
|
},
|
|
93
93
|
platform,
|
|
@@ -127,28 +127,29 @@ function usePaymentState({ trpc, daimoPayOrder, setDaimoPayOrder, setOpen, log,
|
|
|
127
127
|
: DEFAULT_USD_LIMIT;
|
|
128
128
|
};
|
|
129
129
|
const payWithExternal = async (option) => {
|
|
130
|
-
assert(!!daimoPayOrder
|
|
130
|
+
assert(!!daimoPayOrder, "[PAY EXTERNAL] daimoPayOrder cannot be null");
|
|
131
|
+
assert(!!platform, "[PAY EXTERNAL] platform cannot be null");
|
|
131
132
|
const { hydratedOrder, externalPaymentOptionData } = await createOrHydrate({
|
|
132
133
|
order: daimoPayOrder,
|
|
133
134
|
externalPaymentOption: option,
|
|
134
135
|
});
|
|
135
|
-
assert(!!externalPaymentOptionData, "missing externalPaymentOptionData");
|
|
136
|
-
log(`[
|
|
136
|
+
assert(!!externalPaymentOptionData, "[PAY EXTERNAL] missing externalPaymentOptionData");
|
|
137
|
+
log(`[PAY EXTERNAL] hydrated order: ${JSON.stringify(hydratedOrder)}, checking out with external payment: ${option}`);
|
|
137
138
|
setPaymentWaitingMessage(externalPaymentOptionData.waitingMessage);
|
|
138
139
|
setDaimoPayOrder(hydratedOrder);
|
|
139
140
|
return externalPaymentOptionData.url;
|
|
140
141
|
};
|
|
141
142
|
const payWithDepositAddress = async (option) => {
|
|
142
|
-
assert(!!daimoPayOrder);
|
|
143
|
+
assert(!!daimoPayOrder, "[PAY DEPOSIT ADDRESS] missing daimoPayOrder");
|
|
143
144
|
const { hydratedOrder } = await createOrHydrate({
|
|
144
145
|
order: daimoPayOrder,
|
|
145
146
|
});
|
|
146
147
|
setDaimoPayOrder(hydratedOrder);
|
|
147
|
-
log(`[
|
|
148
|
+
log(`[PAY DEPOSIT ADDRESS] hydrated order: ${JSON.stringify(hydratedOrder)}, checking out with deposit address: ${option}`);
|
|
148
149
|
const depositAddressOption = await trpc.getDepositAddressOptionData.query({
|
|
149
150
|
input: option,
|
|
150
151
|
usdRequired: daimoPayOrder.destFinalCallTokenAmount.usd,
|
|
151
|
-
toAddress: assertNotNull(hydratedOrder.intentAddr),
|
|
152
|
+
toAddress: assertNotNull(hydratedOrder.intentAddr, `[PAY DEPOSIT ADDRESS] missing intentAddr on order ${hydratedOrder.id}`),
|
|
152
153
|
});
|
|
153
154
|
return depositAddressOption;
|
|
154
155
|
};
|
|
@@ -161,17 +162,22 @@ function usePaymentState({ trpc, daimoPayOrder, setDaimoPayOrder, setOpen, log,
|
|
|
161
162
|
});
|
|
162
163
|
// Don't overwrite the order if a new order was generated.
|
|
163
164
|
if (daimoPayOrder == null || order.id === daimoPayOrder.id) {
|
|
165
|
+
log(`[CHECKOUT] refreshed order: ${order.id}`);
|
|
164
166
|
setDaimoPayOrder(order);
|
|
165
167
|
}
|
|
168
|
+
else {
|
|
169
|
+
log(`[CHECKOUT] IGNORING refreshOrder, wrong ID: ${order.id} vs ${daimoPayOrder.id}`);
|
|
170
|
+
}
|
|
166
171
|
}, [daimoPayOrder?.id]);
|
|
167
172
|
/** User picked a different deposit amount. */
|
|
168
173
|
const setChosenUsd = (usd) => {
|
|
169
|
-
|
|
170
|
-
assert(!!daimoPayOrder);
|
|
174
|
+
assert(!!daimoPayOrder, "[SET CHOSEN USD] daimoPayOrder cannot be null");
|
|
171
175
|
const token = daimoPayOrder.destFinalCallTokenAmount.token;
|
|
172
|
-
const
|
|
176
|
+
const tokenUnits = (usd / token.usd).toString();
|
|
177
|
+
const tokenAmount = parseUnits(tokenUnits, token.decimals);
|
|
173
178
|
// TODO: remove amount from destFinalCall, it is redundant with
|
|
174
179
|
// destFinalCallTokenAmount. Here, we only modify one and not the other.
|
|
180
|
+
log(`[CHECKOUT] setting chosen USD amount to $${usd} = ${tokenUnits} ${token.symbol}`);
|
|
175
181
|
setDaimoPayOrder({
|
|
176
182
|
...daimoPayOrder,
|
|
177
183
|
destFinalCallTokenAmount: {
|
|
@@ -191,27 +197,25 @@ function usePaymentState({ trpc, daimoPayOrder, setDaimoPayOrder, setOpen, log,
|
|
|
191
197
|
}
|
|
192
198
|
const { order } = await trpc.getOrder.query({ id });
|
|
193
199
|
if (!order) {
|
|
194
|
-
console.error(`[CHECKOUT]
|
|
200
|
+
console.error(`[CHECKOUT] setPayId: no order found for ${payId}`);
|
|
195
201
|
return;
|
|
196
202
|
}
|
|
197
|
-
log(`[CHECKOUT] fetched order: ${JSON.stringify(order)}`);
|
|
203
|
+
log(`[CHECKOUT] setPayId: fetched order: ${JSON.stringify(order)}`);
|
|
198
204
|
setDaimoPayOrder(order);
|
|
199
205
|
}, [daimoPayOrder]);
|
|
200
206
|
/** Called whenever params change. */
|
|
201
207
|
const setPayParams = async (payParams) => {
|
|
202
|
-
assert(payParams != null);
|
|
208
|
+
assert(payParams != null, "[SET PAY PARAMS] payParams cannot be null");
|
|
203
209
|
setPayParamsState(payParams);
|
|
204
210
|
setIsDepositFlow(payParams.toUnits == null);
|
|
205
211
|
generatePreviewOrder(payParams);
|
|
206
212
|
};
|
|
207
213
|
const generatePreviewOrder = async (payParams) => {
|
|
208
|
-
const newPayId = generatePayId();
|
|
209
|
-
const newId = readDaimoPayOrderID(newPayId).toString();
|
|
210
214
|
// toUnits is undefined if and only if we're in deposit flow.
|
|
211
215
|
// Set dummy value for deposit flow, since user can edit the amount.
|
|
212
216
|
const toUnits = payParams.toUnits == null ? "0" : payParams.toUnits;
|
|
213
217
|
const orderPreview = await trpc.previewOrder.query({
|
|
214
|
-
|
|
218
|
+
appId: payParams.appId,
|
|
215
219
|
toChain: payParams.toChain,
|
|
216
220
|
toToken: payParams.toToken,
|
|
217
221
|
toUnits,
|
|
@@ -227,13 +231,16 @@ function usePaymentState({ trpc, daimoPayOrder, setDaimoPayOrder, setOpen, log,
|
|
|
227
231
|
preferredTokens: payParams.preferredTokens,
|
|
228
232
|
},
|
|
229
233
|
},
|
|
234
|
+
externalId: payParams.externalId,
|
|
235
|
+
userMetadata: payParams.metadata,
|
|
230
236
|
});
|
|
237
|
+
log(`[CHECKOUT] generated preview: ${JSON.stringify(orderPreview)}`);
|
|
231
238
|
setDaimoPayOrder(orderPreview);
|
|
232
239
|
};
|
|
233
240
|
const onSuccess = ({ txHash, txURL }) => {
|
|
234
241
|
if (modalOptions?.closeOnSuccess) {
|
|
235
242
|
log(`[CHECKOUT] transaction succeeded, closing: ${txHash} ${txURL}`);
|
|
236
|
-
setTimeout(() => setOpen(false), 1000);
|
|
243
|
+
setTimeout(() => setOpen(false, { event: "wait-success" }), 1000);
|
|
237
244
|
}
|
|
238
245
|
};
|
|
239
246
|
return {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"usePaymentState.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"usePaymentState.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
package/build/src/index.js
CHANGED
|
@@ -3,9 +3,8 @@ export { Context as DaimoPayContext, DaimoPayProvider, usePayContext } from './c
|
|
|
3
3
|
export { default as getDefaultConfig } from './defaultConfig.js';
|
|
4
4
|
export { DaimoPayButton } from './components/DaimoPayButton/index.js';
|
|
5
5
|
export { useDaimoPayStatus } from './hooks/useDaimoPayStatus.js';
|
|
6
|
-
export { useModal as useDaimoPayModal } from './hooks/useModal.js';
|
|
7
6
|
export { default as Avatar } from './components/Common/Avatar/index.js';
|
|
8
7
|
export { default as ChainIcon } from './components/Common/Chain/index.js';
|
|
9
8
|
export { wallets } from './wallets/index.js';
|
|
10
|
-
export { daimoPayVersion,
|
|
9
|
+
export { daimoPayVersion, supportedChainIds } from './utils/exports.js';
|
|
11
10
|
//# sourceMappingURL=index.js.map
|
package/build/src/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;"}
|
|
@@ -1,17 +1,10 @@
|
|
|
1
|
-
import { writeDaimoPayOrderID } from '@daimo/common';
|
|
2
1
|
import { getDAv2Chains } from '@daimo/contract';
|
|
3
|
-
import { bytesToBigInt } from 'viem';
|
|
4
2
|
import packageJson from '../../package.json.js';
|
|
5
3
|
|
|
6
4
|
// Exported utilities, useful for @daimo/pay users.
|
|
7
5
|
const daimoPayVersion = packageJson.version;
|
|
8
|
-
/** Generates a globally-unique payId. */
|
|
9
|
-
function generatePayId() {
|
|
10
|
-
const id = bytesToBigInt(crypto.getRandomValues(new Uint8Array(32)));
|
|
11
|
-
return writeDaimoPayOrderID(id);
|
|
12
|
-
}
|
|
13
6
|
/** Chain ids supported by Daimo Pay. */
|
|
14
7
|
const supportedChainIds = new Set([...getDAv2Chains(false), ...getDAv2Chains(true)].map((c) => c.chainId));
|
|
15
8
|
|
|
16
|
-
export { daimoPayVersion,
|
|
9
|
+
export { daimoPayVersion, supportedChainIds };
|
|
17
10
|
//# sourceMappingURL=exports.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"exports.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"exports.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;"}
|
package/build/src/utils/trpc.js
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import { createTRPCClient, httpBatchLink } from '@trpc/client';
|
|
2
2
|
import { daimoPayVersion } from './exports.js';
|
|
3
3
|
|
|
4
|
-
function createTrpcClient(apiUrl) {
|
|
4
|
+
function createTrpcClient(apiUrl, sessionId) {
|
|
5
5
|
return createTRPCClient({
|
|
6
6
|
links: [
|
|
7
7
|
httpBatchLink({
|
|
8
8
|
url: apiUrl,
|
|
9
9
|
headers: {
|
|
10
10
|
"x-pay-version": daimoPayVersion,
|
|
11
|
+
"x-session-id": sessionId,
|
|
11
12
|
},
|
|
12
13
|
}),
|
|
13
14
|
],
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"trpc.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"trpc.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@daimo/pay",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.3.1",
|
|
5
5
|
"author": "Daimo",
|
|
6
6
|
"homepage": "https://pay.daimo.com",
|
|
7
7
|
"license": "BSD-2-Clause license",
|
|
@@ -40,8 +40,8 @@
|
|
|
40
40
|
"crypto"
|
|
41
41
|
],
|
|
42
42
|
"dependencies": {
|
|
43
|
-
"@daimo/common": "1.
|
|
44
|
-
"@daimo/contract": "1.
|
|
43
|
+
"@daimo/common": "1.3.1",
|
|
44
|
+
"@daimo/contract": "1.3.1",
|
|
45
45
|
"@solana/wallet-adapter-base": "^0.9.23",
|
|
46
46
|
"@solana/wallet-adapter-react": "^0.15.35",
|
|
47
47
|
"@solana/web3.js": "^1.95.4",
|
|
@@ -79,4 +79,4 @@
|
|
|
79
79
|
"rollup-plugin-visualizer": "^5.5.4",
|
|
80
80
|
"typescript-plugin-styled-components": "^3.0.0"
|
|
81
81
|
}
|
|
82
|
-
}
|
|
82
|
+
}
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import { usePayContext, ROUTES } from '../components/DaimoPay.js';
|
|
2
|
-
import { useConnectCallback } from './useConnectCallback.js';
|
|
3
|
-
|
|
4
|
-
/** Opens and closes the payment modal. */
|
|
5
|
-
const useModal = ({ onConnect, onDisconnect } = {}) => {
|
|
6
|
-
const context = usePayContext();
|
|
7
|
-
useConnectCallback({
|
|
8
|
-
onConnect,
|
|
9
|
-
onDisconnect,
|
|
10
|
-
});
|
|
11
|
-
const close = () => {
|
|
12
|
-
context.setOpen(false);
|
|
13
|
-
};
|
|
14
|
-
const open = () => {
|
|
15
|
-
context.setOpen(true);
|
|
16
|
-
};
|
|
17
|
-
const gotoAndOpen = (route) => {
|
|
18
|
-
context.setRoute(route);
|
|
19
|
-
open();
|
|
20
|
-
};
|
|
21
|
-
return {
|
|
22
|
-
open: context.open,
|
|
23
|
-
setOpen: (show) => {
|
|
24
|
-
if (show) {
|
|
25
|
-
gotoAndOpen(ROUTES.SELECT_METHOD);
|
|
26
|
-
}
|
|
27
|
-
else {
|
|
28
|
-
close();
|
|
29
|
-
}
|
|
30
|
-
},
|
|
31
|
-
};
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
export { useModal };
|
|
35
|
-
//# sourceMappingURL=useModal.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"useModal.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|