@daimo/pay 1.7.2 → 1.7.3
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 +12 -0
- package/build/index.js +66 -30
- package/build/index.js.map +1 -1
- package/package.json +2 -2
package/build/index.d.ts
CHANGED
|
@@ -228,6 +228,10 @@ type PayButtonPaymentProps = {
|
|
|
228
228
|
* Developer metadata. E.g. correlation ID.
|
|
229
229
|
* */
|
|
230
230
|
metadata?: DaimoPayUserMetadata;
|
|
231
|
+
/**
|
|
232
|
+
* The address to refund to if the payment bounces or a refund is requested.
|
|
233
|
+
*/
|
|
234
|
+
refundAddress?: Address;
|
|
231
235
|
} | {
|
|
232
236
|
/** The payment ID, generated via the Daimo Pay API. Replaces params above. */
|
|
233
237
|
payId: string;
|
|
@@ -239,6 +243,10 @@ type PayButtonCommonProps = PayButtonPaymentProps & {
|
|
|
239
243
|
onPaymentCompleted?: (event: DaimoPayCompletedEvent) => void;
|
|
240
244
|
/** Called when destination call reverts and funds are refunded */
|
|
241
245
|
onPaymentBounced?: (event: DaimoPayBouncedEvent) => void;
|
|
246
|
+
/** Called when the modal is opened. */
|
|
247
|
+
onOpen?: () => void;
|
|
248
|
+
/** Called when the modal is closed. */
|
|
249
|
+
onClose?: () => void;
|
|
242
250
|
/** Automatically close the modal after a successful payment. */
|
|
243
251
|
closeOnSuccess?: boolean;
|
|
244
252
|
/** Open the modal by default. */
|
|
@@ -453,6 +461,8 @@ interface PayParams {
|
|
|
453
461
|
externalId?: string;
|
|
454
462
|
/** Developer metadata. E.g. correlation ID. */
|
|
455
463
|
metadata?: DaimoPayUserMetadata;
|
|
464
|
+
/** The address to refund to if the payment bounces or a refund is requested. */
|
|
465
|
+
refundAddress?: Address;
|
|
456
466
|
}
|
|
457
467
|
/** Creates (or loads) a payment and manages the corresponding modal. */
|
|
458
468
|
interface PaymentState {
|
|
@@ -507,6 +517,8 @@ type PayContextValue = {
|
|
|
507
517
|
setCustomTheme: React$1.Dispatch<React$1.SetStateAction<CustomTheme | undefined>>;
|
|
508
518
|
lang: Languages$1;
|
|
509
519
|
setLang: React$1.Dispatch<React$1.SetStateAction<Languages$1>>;
|
|
520
|
+
setOnOpen: (fn?: () => void) => void;
|
|
521
|
+
setOnClose: (fn?: () => void) => void;
|
|
510
522
|
open: boolean;
|
|
511
523
|
setOpen: (open: boolean, meta?: Record<string, any>) => void;
|
|
512
524
|
route: string;
|
package/build/index.js
CHANGED
|
@@ -7,7 +7,7 @@ import { http, useConfig, useAccountEffect, useWriteContract, useSendTransaction
|
|
|
7
7
|
import { mainnet, base as base$1, polygon, optimism, arbitrum, linea, bsc, sepolia, baseSepolia, worldchain, blast, mantle } from 'wagmi/chains';
|
|
8
8
|
import { safe, injected, coinbaseWallet, walletConnect } from '@wagmi/connectors';
|
|
9
9
|
import { useConnection, useWallet as useWallet$1, ConnectionProvider, WalletProvider } from '@solana/wallet-adapter-react';
|
|
10
|
-
import { hexToBytes, zeroAddress, erc20Abi, getAddress,
|
|
10
|
+
import { hexToBytes, zeroAddress, erc20Abi, getAddress, formatUnits, parseUnits } from 'viem';
|
|
11
11
|
import { VersionedTransaction } from '@solana/web3.js';
|
|
12
12
|
import { createTRPCClient, httpBatchLink } from '@trpc/client';
|
|
13
13
|
import { motion, AnimatePresence, MotionConfig } from 'framer-motion';
|
|
@@ -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.7.
|
|
25
|
+
var version = "1.7.3";
|
|
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.7.
|
|
64
|
+
"@daimo/pay-common": "1.7.3",
|
|
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",
|
|
@@ -997,7 +997,7 @@ function useOrderUsdLimits({ trpc }) {
|
|
|
997
997
|
return { limits, loading };
|
|
998
998
|
}
|
|
999
999
|
|
|
1000
|
-
function usePayWithSolanaToken({ trpc, daimoPayOrder, setDaimoPayOrder, createOrHydrate, log, }) {
|
|
1000
|
+
function usePayWithSolanaToken({ trpc, refundAddress, daimoPayOrder, setDaimoPayOrder, createOrHydrate, log, }) {
|
|
1001
1001
|
const { connection } = useConnection();
|
|
1002
1002
|
const wallet = useWallet$1();
|
|
1003
1003
|
const payWithSolanaToken = async (inputToken) => {
|
|
@@ -1006,6 +1006,7 @@ function usePayWithSolanaToken({ trpc, daimoPayOrder, setDaimoPayOrder, createOr
|
|
|
1006
1006
|
const orderId = daimoPayOrder.id;
|
|
1007
1007
|
const { hydratedOrder } = await createOrHydrate({
|
|
1008
1008
|
order: daimoPayOrder,
|
|
1009
|
+
refundAddress,
|
|
1009
1010
|
});
|
|
1010
1011
|
log(`[CHECKOUT] Hydrated order: ${JSON.stringify(hydratedOrder)}, checking out with Solana ${inputToken}`);
|
|
1011
1012
|
const txHash = await (async () => {
|
|
@@ -1040,7 +1041,7 @@ function usePayWithSolanaToken({ trpc, daimoPayOrder, setDaimoPayOrder, createOr
|
|
|
1040
1041
|
return { payWithSolanaToken };
|
|
1041
1042
|
}
|
|
1042
1043
|
|
|
1043
|
-
function usePayWithToken({ trpc, senderAddr, daimoPayOrder, setDaimoPayOrder, createOrHydrate, log, }) {
|
|
1044
|
+
function usePayWithToken({ trpc, senderAddr, refundAddress, daimoPayOrder, setDaimoPayOrder, createOrHydrate, log, }) {
|
|
1044
1045
|
const { writeContractAsync } = useWriteContract();
|
|
1045
1046
|
const { sendTransactionAsync } = useSendTransaction();
|
|
1046
1047
|
/** Commit to a token + amount = initiate payment. */
|
|
@@ -1051,7 +1052,8 @@ function usePayWithToken({ trpc, senderAddr, daimoPayOrder, setDaimoPayOrder, cr
|
|
|
1051
1052
|
const paymentAmount = BigInt(required.amount) + BigInt(fees.amount);
|
|
1052
1053
|
const { hydratedOrder } = await createOrHydrate({
|
|
1053
1054
|
order: daimoPayOrder,
|
|
1054
|
-
|
|
1055
|
+
// Use the developer-provided refund address. Default to the sender.
|
|
1056
|
+
refundAddress: refundAddress ?? senderAddr,
|
|
1055
1057
|
});
|
|
1056
1058
|
log(`[PAY TOKEN] hydrated order: ${JSON.stringify(hydratedOrder)}, paying ${paymentAmount} of token ${required.token.token}`);
|
|
1057
1059
|
setDaimoPayOrder(hydratedOrder);
|
|
@@ -1260,6 +1262,7 @@ function usePaymentState({ trpc, daimoPayOrder, setDaimoPayOrder, setOpen, log,
|
|
|
1260
1262
|
const { payWithToken } = usePayWithToken({
|
|
1261
1263
|
trpc,
|
|
1262
1264
|
senderAddr,
|
|
1265
|
+
refundAddress: payParams?.refundAddress,
|
|
1263
1266
|
daimoPayOrder,
|
|
1264
1267
|
setDaimoPayOrder,
|
|
1265
1268
|
createOrHydrate,
|
|
@@ -1267,6 +1270,7 @@ function usePaymentState({ trpc, daimoPayOrder, setDaimoPayOrder, setOpen, log,
|
|
|
1267
1270
|
});
|
|
1268
1271
|
const { payWithSolanaToken } = usePayWithSolanaToken({
|
|
1269
1272
|
trpc,
|
|
1273
|
+
refundAddress: payParams?.refundAddress,
|
|
1270
1274
|
daimoPayOrder,
|
|
1271
1275
|
setDaimoPayOrder,
|
|
1272
1276
|
createOrHydrate,
|
|
@@ -1394,6 +1398,7 @@ function usePaymentState({ trpc, daimoPayOrder, setDaimoPayOrder, setOpen, log,
|
|
|
1394
1398
|
},
|
|
1395
1399
|
externalId: payParams.externalId,
|
|
1396
1400
|
userMetadata: payParams.metadata,
|
|
1401
|
+
refundAddress: payParams.refundAddress,
|
|
1397
1402
|
});
|
|
1398
1403
|
log(`[CHECKOUT] generated preview: ${JSON.stringify(orderPreview)}`);
|
|
1399
1404
|
setDaimoPayOrder(orderPreview);
|
|
@@ -9757,7 +9762,7 @@ const ChainLogoContainer = styled(motion.div) `
|
|
|
9757
9762
|
`;
|
|
9758
9763
|
|
|
9759
9764
|
const TokenLogoSpinner = ({ token, showSpinner = true, }) => {
|
|
9760
|
-
return (jsx(LoadingContainer$2, { children: jsx(AnimationContainer$1, { "$circle": true, children: jsxs(AnimatePresence, { children: [chainToLogo[token.chainId] && (jsx(ChainLogoContainer, { children: chainToLogo[token.chainId] }, "ChainLogoContainer")), jsx(CircleSpinner, { logo: jsx("img", { src: token.logoURI, alt: token.symbol }
|
|
9765
|
+
return (jsx(LoadingContainer$2, { children: jsx(AnimationContainer$1, { "$circle": true, children: jsxs(AnimatePresence, { children: [chainToLogo[token.chainId] && (jsx(ChainLogoContainer, { children: chainToLogo[token.chainId] }, "ChainLogoContainer")), jsx(CircleSpinner, { logo: jsx("img", { src: token.logoURI, alt: token.symbol }), loading: showSpinner, unavailable: false }, "CircleSpinner")] }) }) }));
|
|
9761
9766
|
};
|
|
9762
9767
|
|
|
9763
9768
|
var PayState$1;
|
|
@@ -11452,18 +11457,43 @@ const DaimoPayProviderWithoutSolana = ({ children, theme = "auto", mode = "auto"
|
|
|
11452
11457
|
const [ckMode, setMode] = useState(mode);
|
|
11453
11458
|
const [ckCustomTheme, setCustomTheme] = useState(customTheme ?? {});
|
|
11454
11459
|
const [ckLang, setLang] = useState("en-US");
|
|
11460
|
+
const onOpenRef = useRef();
|
|
11461
|
+
const onCloseRef = useRef();
|
|
11462
|
+
const setOnOpen = useCallback((fn) => {
|
|
11463
|
+
onOpenRef.current = fn;
|
|
11464
|
+
}, []);
|
|
11465
|
+
const setOnClose = useCallback((fn) => {
|
|
11466
|
+
onCloseRef.current = fn;
|
|
11467
|
+
}, []);
|
|
11455
11468
|
const [open, setOpenState] = useState(false);
|
|
11456
|
-
const
|
|
11469
|
+
const [route, setRouteState] = useState(ROUTES.SELECT_METHOD);
|
|
11470
|
+
// Daimo Pay context
|
|
11471
|
+
const [daimoPayOrder, setDaimoPayOrderInner] = useState();
|
|
11472
|
+
const [pendingConnectorId, setPendingConnectorId] = useState(undefined);
|
|
11473
|
+
// Track sessions. Each generates separate intent IDs unless using externalId.
|
|
11474
|
+
const [sessionId] = useState(() => crypto.randomUUID().replaceAll("-", ""));
|
|
11475
|
+
const [solanaConnector, setSolanaConnector] = useState();
|
|
11476
|
+
// Other configuration
|
|
11477
|
+
const [errorMessage, setErrorMessage] = useState("");
|
|
11478
|
+
const [confirmationMessage, setConfirmationMessage] = useState(undefined);
|
|
11479
|
+
const [redirectReturnUrl, setRedirectReturnUrl] = useState(undefined);
|
|
11480
|
+
const log = debugMode ? console.log : () => { };
|
|
11481
|
+
// Connect to the Daimo Pay TRPC API
|
|
11482
|
+
const trpc = useMemo(() => createTrpcClient(payApiUrl, sessionId), [payApiUrl]);
|
|
11483
|
+
const [resize, onResize] = useState(0);
|
|
11484
|
+
const setOpen = useCallback((open, meta) => {
|
|
11457
11485
|
setOpenState(open);
|
|
11458
11486
|
trpc.nav.mutate({
|
|
11459
11487
|
action: open ? "navOpenPay" : "navClosePay",
|
|
11460
11488
|
orderId: daimoPayOrder?.id?.toString(),
|
|
11461
11489
|
data: meta ?? {},
|
|
11462
11490
|
});
|
|
11463
|
-
|
|
11464
|
-
|
|
11465
|
-
|
|
11466
|
-
|
|
11491
|
+
if (open)
|
|
11492
|
+
onOpenRef.current?.();
|
|
11493
|
+
else
|
|
11494
|
+
onCloseRef.current?.();
|
|
11495
|
+
}, [trpc, daimoPayOrder?.id]);
|
|
11496
|
+
const setRoute = useCallback((route, data) => {
|
|
11467
11497
|
const action = route.replace("daimoPay", "");
|
|
11468
11498
|
log(`[SET ROUTE] ${action} ${daimoPayOrder?.id} ${debugJson(data ?? {})}`);
|
|
11469
11499
|
trpc.nav.mutate({
|
|
@@ -11472,15 +11502,10 @@ const DaimoPayProviderWithoutSolana = ({ children, theme = "auto", mode = "auto"
|
|
|
11472
11502
|
data: data ?? {},
|
|
11473
11503
|
});
|
|
11474
11504
|
setRouteState(route);
|
|
11475
|
-
};
|
|
11476
|
-
const [errorMessage, setErrorMessage] = useState("");
|
|
11477
|
-
const [confirmationMessage, setConfirmationMessage] = useState(undefined);
|
|
11478
|
-
const [redirectReturnUrl, setRedirectReturnUrl] = useState(undefined);
|
|
11479
|
-
const [resize, onResize] = useState(0);
|
|
11480
|
-
const [pendingConnectorId, setPendingConnectorId] = useState(undefined);
|
|
11505
|
+
}, [trpc, daimoPayOrder?.id, log]);
|
|
11481
11506
|
// Include Google Font that is needed for a themes
|
|
11482
11507
|
if (opts.embedGoogleFonts)
|
|
11483
|
-
useThemeFont(
|
|
11508
|
+
useThemeFont(ckTheme);
|
|
11484
11509
|
// Other Configuration
|
|
11485
11510
|
useEffect(() => setTheme(theme), [theme]);
|
|
11486
11511
|
useEffect(() => setLang(opts.language || "en-US"), [opts.language]);
|
|
@@ -11491,23 +11516,18 @@ const DaimoPayProviderWithoutSolana = ({ children, theme = "auto", mode = "auto"
|
|
|
11491
11516
|
useEffect(() => {
|
|
11492
11517
|
if (isConnected && opts.enforceSupportedChains && !isChainSupported) {
|
|
11493
11518
|
setOpen(true);
|
|
11494
|
-
|
|
11519
|
+
if (route !== ROUTES.SWITCHNETWORKS)
|
|
11520
|
+
setRoute(ROUTES.SWITCHNETWORKS);
|
|
11495
11521
|
}
|
|
11496
11522
|
}, [isConnected, isChainSupported, chain, route, open]);
|
|
11497
|
-
const log = debugMode ? console.log : () => { };
|
|
11498
|
-
// Track sessions. Each generates separate intent IDs unless using externalId.
|
|
11499
|
-
const [sessionId] = useState(() => crypto.randomUUID().replaceAll("-", ""));
|
|
11500
11523
|
// Single source of truth for the currently-connected wallet is the connector
|
|
11501
11524
|
// exposed by wagmi. See useAccount(). We watch this connector and use it to
|
|
11502
11525
|
// extract the current WalletConnect wallet, if any.
|
|
11503
11526
|
const wcWallet = useExtractWcWallet({ connector, log });
|
|
11504
|
-
// Connect to the Daimo Pay TRPC API
|
|
11505
|
-
const trpc = useMemo(() => createTrpcClient(payApiUrl, sessionId), [payApiUrl]);
|
|
11506
11527
|
// PaymentInfo is a second, inner context object containing a DaimoPayOrder
|
|
11507
11528
|
// plus all associated status and callbacks. In order for useContext() and
|
|
11508
11529
|
// downstream hooks like useDaimoPayStatus() to work correctly, we must set
|
|
11509
11530
|
// set refresh context when payment status changes; done via setDaimoPayOrder.
|
|
11510
|
-
const [daimoPayOrder, setDaimoPayOrderInner] = useState();
|
|
11511
11531
|
const setDaimoPayOrder = useCallback((order) => {
|
|
11512
11532
|
setDaimoPayOrderInner(order);
|
|
11513
11533
|
let extra = `> $${order.destFinalCallTokenAmount.usd.toFixed(2)} to ${order.destFinalCallTokenAmount.token.chainId} ${order.destFinalCall.to}`;
|
|
@@ -11515,7 +11535,7 @@ const DaimoPayProviderWithoutSolana = ({ children, theme = "auto", mode = "auto"
|
|
|
11515
11535
|
extra += ` via ${order.intentAddr} ${order.sourceStatus} ${order.intentStatus}`;
|
|
11516
11536
|
}
|
|
11517
11537
|
log(`[PAY] setDaimoPayOrder: ${order.id} ${extra}`);
|
|
11518
|
-
}, [
|
|
11538
|
+
}, [log]);
|
|
11519
11539
|
const paymentState = usePaymentState({
|
|
11520
11540
|
trpc,
|
|
11521
11541
|
daimoPayOrder,
|
|
@@ -11546,7 +11566,6 @@ const DaimoPayProviderWithoutSolana = ({ children, theme = "auto", mode = "auto"
|
|
|
11546
11566
|
return () => clearTimeout(timeout);
|
|
11547
11567
|
}, [daimoPayOrder]);
|
|
11548
11568
|
const showPayment = async (modalOptions) => {
|
|
11549
|
-
const { daimoPayOrder } = paymentState;
|
|
11550
11569
|
const id = daimoPayOrder?.id;
|
|
11551
11570
|
log(`[PAY] showing payment ${debugJson({ id, modalOptions })}`);
|
|
11552
11571
|
paymentState.setModalOptions(modalOptions);
|
|
@@ -11572,6 +11591,8 @@ const DaimoPayProviderWithoutSolana = ({ children, theme = "auto", mode = "auto"
|
|
|
11572
11591
|
setCustomTheme,
|
|
11573
11592
|
lang: ckLang,
|
|
11574
11593
|
setLang,
|
|
11594
|
+
setOnOpen,
|
|
11595
|
+
setOnClose,
|
|
11575
11596
|
open,
|
|
11576
11597
|
setOpen,
|
|
11577
11598
|
route,
|
|
@@ -11857,10 +11878,12 @@ function DaimoPayButtonCustom(props) {
|
|
|
11857
11878
|
evmChains: props.evmChains,
|
|
11858
11879
|
externalId: props.externalId,
|
|
11859
11880
|
metadata: props.metadata,
|
|
11881
|
+
refundAddress: props.refundAddress,
|
|
11860
11882
|
}
|
|
11861
11883
|
: null;
|
|
11862
11884
|
let payId = "payId" in props ? props.payId : null;
|
|
11863
11885
|
const { paymentState } = context;
|
|
11886
|
+
// Set the payId or payParams
|
|
11864
11887
|
useEffect(() => {
|
|
11865
11888
|
if (payId != null) {
|
|
11866
11889
|
paymentState.setPayId(payId);
|
|
@@ -11869,18 +11892,30 @@ function DaimoPayButtonCustom(props) {
|
|
|
11869
11892
|
paymentState.setPayParams(payParams);
|
|
11870
11893
|
}
|
|
11871
11894
|
}, [payId, JSON.stringify(payParams || {})]);
|
|
11895
|
+
// Set the confirmation message
|
|
11872
11896
|
const { setConfirmationMessage } = context;
|
|
11873
11897
|
useEffect(() => {
|
|
11874
11898
|
if (props.confirmationMessage) {
|
|
11875
11899
|
setConfirmationMessage(props.confirmationMessage);
|
|
11876
11900
|
}
|
|
11877
11901
|
}, [props.confirmationMessage, setConfirmationMessage]);
|
|
11902
|
+
// Set the redirect return url
|
|
11878
11903
|
const { setRedirectReturnUrl } = context;
|
|
11879
11904
|
useEffect(() => {
|
|
11880
11905
|
if (props.redirectReturnUrl) {
|
|
11881
11906
|
setRedirectReturnUrl(props.redirectReturnUrl);
|
|
11882
11907
|
}
|
|
11883
11908
|
}, [props.redirectReturnUrl, setRedirectReturnUrl]);
|
|
11909
|
+
// Set the onOpen and onClose callbacks
|
|
11910
|
+
const { setOnOpen, setOnClose } = context;
|
|
11911
|
+
useEffect(() => {
|
|
11912
|
+
setOnOpen(props.onOpen);
|
|
11913
|
+
return () => setOnOpen(undefined);
|
|
11914
|
+
}, [props.onOpen, setOnOpen]);
|
|
11915
|
+
useEffect(() => {
|
|
11916
|
+
setOnClose(props.onClose);
|
|
11917
|
+
return () => setOnClose(undefined);
|
|
11918
|
+
}, [props.onClose, setOnClose]);
|
|
11884
11919
|
// Payment events: call these three event handlers.
|
|
11885
11920
|
const { onPaymentStarted, onPaymentCompleted, onPaymentBounced } = props;
|
|
11886
11921
|
const order = paymentState.daimoPayOrder;
|
|
@@ -11927,11 +11962,12 @@ function DaimoPayButtonCustom(props) {
|
|
|
11927
11962
|
}
|
|
11928
11963
|
}
|
|
11929
11964
|
}, [hydOrder?.id, intentStatus]);
|
|
11965
|
+
// Open the modal by default if the defaultOpen prop is true
|
|
11930
11966
|
useEffect(() => {
|
|
11931
|
-
if (props.defaultOpen) {
|
|
11967
|
+
if (props.defaultOpen && order != null) {
|
|
11932
11968
|
show();
|
|
11933
11969
|
}
|
|
11934
|
-
}, [order != null]);
|
|
11970
|
+
}, [order != null, props.defaultOpen]);
|
|
11935
11971
|
// Validation
|
|
11936
11972
|
if ((payId == null) == (payParams == null)) {
|
|
11937
11973
|
throw new Error("Must specify either payId or appId, not both");
|