@daimo/pay 1.7.3 → 1.7.5
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 +22 -16
- package/build/index.js +247 -190
- package/build/index.js.map +1 -1
- package/package.json +4 -3
package/build/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
2
|
-
import { ExternalPaymentOptions, assert, assertNotNull, debugJson, supportedChains, ethereum, readDaimoPayOrderID, getChainName, arbitrum as arbitrum$1, base as base$2, blast as blast$1, bsc as bsc$1, linea as linea$1, mantle as mantle$1, optimism as optimism$1, polygon as polygon$1, worldchain as worldchain$1, getAddressContraction, writeDaimoPayOrderID, DaimoPayOrderMode, DaimoPayOrderStatusDest, getChainExplorerTxUrl, DaimoPayIntentStatus, retryBackoff, DaimoPayOrderStatusSource, getDaimoPayOrderView } from '@daimo/pay-common';
|
|
2
|
+
import { ExternalPaymentOptions, assert, assertNotNull, debugJson, supportedChains, ethereum, isCCTPV1Chain, getOrderDestChainId, readDaimoPayOrderID, getChainName, arbitrum as arbitrum$1, base as base$2, blast as blast$1, bsc as bsc$1, linea as linea$1, mantle as mantle$1, optimism as optimism$1, polygon as polygon$1, worldchain as worldchain$1, getAddressContraction, writeDaimoPayOrderID, DaimoPayOrderMode, DaimoPayOrderStatusDest, getChainExplorerTxUrl, DaimoPayIntentStatus, retryBackoff, DaimoPayOrderStatusSource, getDaimoPayOrderView } from '@daimo/pay-common';
|
|
3
3
|
import { Buffer } from 'buffer';
|
|
4
|
-
import React, { useState, useEffect, createContext,
|
|
4
|
+
import React, { useState, useEffect, createContext, useRef, useCallback, useLayoutEffect, useMemo, createElement } from 'react';
|
|
5
5
|
import styled$1, { css, keyframes, ThemeProvider } from 'styled-components';
|
|
6
6
|
import { http, useConfig, useAccountEffect, useWriteContract, useSendTransaction, useAccount, useEnsName, useConnectors as useConnectors$1, useSwitchChain, useConnect as useConnect$1, useDisconnect, useChainId, WagmiContext, createConfig, useEnsAddress, useEnsAvatar } from 'wagmi';
|
|
7
7
|
import { mainnet, base as base$1, polygon, optimism, arbitrum, linea, bsc, sepolia, baseSepolia, worldchain, blast, mantle } from 'wagmi/chains';
|
|
@@ -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.5";
|
|
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.5",
|
|
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",
|
|
@@ -94,6 +94,7 @@ var devDependencies = {
|
|
|
94
94
|
"@types/react-dom": "^18.2.18",
|
|
95
95
|
"@types/rollup-plugin-peer-deps-external": "^2.2.5",
|
|
96
96
|
"@types/styled-components": "^5.1.25",
|
|
97
|
+
"eslint-plugin-react-hooks": "^5.2.0",
|
|
97
98
|
rollup: "^3.29.5",
|
|
98
99
|
"rollup-plugin-dts": "^6.1.1",
|
|
99
100
|
"rollup-plugin-peer-deps-external": "^2.2.4",
|
|
@@ -244,14 +245,6 @@ const defaultConfig = ({ appName = "Daimo Pay", appIcon, appDescription, appUrl,
|
|
|
244
245
|
return config;
|
|
245
246
|
};
|
|
246
247
|
|
|
247
|
-
/** Determines whether the current wagmi configuration supports a given chain. */
|
|
248
|
-
function useChainIsSupported(chainId) {
|
|
249
|
-
const { chains } = useConfig();
|
|
250
|
-
if (!chainId)
|
|
251
|
-
return false;
|
|
252
|
-
return chains.some((x) => x.id === chainId);
|
|
253
|
-
}
|
|
254
|
-
|
|
255
248
|
/** Returns currently configured wagmi chains. */
|
|
256
249
|
function useChains() {
|
|
257
250
|
const wagmi = useConfig();
|
|
@@ -377,7 +370,7 @@ const OtherWallets = ({ ...props }) => {
|
|
|
377
370
|
overflow: "hidden",
|
|
378
371
|
borderRadius: "27.5%",
|
|
379
372
|
};
|
|
380
|
-
return (jsxs("div", { style: column, ...props, children: [jsxs("div", { style: row, children: [jsx("div", { style: cell, children: jsx(
|
|
373
|
+
return (jsxs("div", { style: column, ...props, children: [jsxs("div", { style: row, children: [jsx("div", { style: cell, children: jsx(Zerion, {}) }), jsx("div", { style: cell, children: jsx(WalletConnect, { background: true }) })] }), jsxs("div", { style: row, children: [jsx("div", { style: cell, children: jsx(Family, {}) }), jsx("div", { style: cell, children: jsx(Ledger, {}) })] })] }));
|
|
381
374
|
};
|
|
382
375
|
const Fordefi = ({ ...props }) => (jsxs("svg", { ...props, width: "88", height: "88", viewBox: "0 0 96 96", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [jsxs("g", { clipPath: "url(#clip0_14298_75627)", children: [jsx("path", { d: "M43.5075 62.5508H6V73.5954C6 79.2046 10.5379 83.7515 16.1357 83.7515H32.9997L43.5075 62.5508Z", fill: "#7994FF" }), jsx("path", { d: "M6.00098 39.1016H76.2075L68.0567 55.4841H6.00098V39.1016Z", fill: "#486DFF" }), jsx("path", { d: "M30.6398 12H6.09766V32.0282H89.8447V12H65.3025V26.9577H60.2423V12H35.7001V26.9577H30.6398V12Z", fill: "#5CD1FA" })] }), jsx("defs", { children: jsx("clipPath", { id: "clip0_14298_75627", children: jsx("rect", { width: "84", height: "72", fill: "white", transform: "translate(6 12)" }) }) })] }));
|
|
383
376
|
const SquircleIcon = ({ icon, alt, }) => {
|
|
@@ -580,11 +573,12 @@ const walletConfigs = {
|
|
|
580
573
|
edge: "https://rainbow.me/extension?utm_source=daimopay",
|
|
581
574
|
brave: "https://rainbow.me/extension?utm_source=daimopay",
|
|
582
575
|
},
|
|
583
|
-
showInMobileConnectors:
|
|
576
|
+
showInMobileConnectors: false,
|
|
584
577
|
isWcMobileConnector: false,
|
|
585
578
|
getWalletConnectDeeplink: (uri) => {
|
|
586
|
-
return `
|
|
579
|
+
return `rainbow://wc?uri=${encodeURIComponent(uri)}&connector=daimopay`;
|
|
587
580
|
},
|
|
581
|
+
walletDeepLink: "rainbow://",
|
|
588
582
|
},
|
|
589
583
|
"io.rabby": {
|
|
590
584
|
name: "Rabby Wallet",
|
|
@@ -732,7 +726,7 @@ const walletConfigs = {
|
|
|
732
726
|
getWalletConnectDeeplink: (uri) => {
|
|
733
727
|
return `https://app.zerion.io/wc?uri=${encodeURIComponent(uri)}`;
|
|
734
728
|
},
|
|
735
|
-
showInMobileConnectors:
|
|
729
|
+
showInMobileConnectors: true,
|
|
736
730
|
},
|
|
737
731
|
slope: {
|
|
738
732
|
name: "Slope",
|
|
@@ -838,51 +832,10 @@ function extractWcWalletFromProvider(p, log) {
|
|
|
838
832
|
isWcMobileConnector: true,
|
|
839
833
|
};
|
|
840
834
|
}
|
|
841
|
-
log(`[WCWALLET] name: ${name} wcWallet: ${wallet?.name} isWcMobileConnector: ${wallet?.isWcMobileConnector} provider:
|
|
835
|
+
log(`[WCWALLET] name: ${name} wcWallet: ${wallet?.name} isWcMobileConnector: ${wallet?.isWcMobileConnector} provider: `, p);
|
|
842
836
|
return wallet;
|
|
843
837
|
}
|
|
844
838
|
|
|
845
|
-
function useGoogleFont(font) {
|
|
846
|
-
useEffect(() => {
|
|
847
|
-
if (!font)
|
|
848
|
-
return;
|
|
849
|
-
font = font.replace(/ /g, "+");
|
|
850
|
-
const googleapis = document.createElement("link");
|
|
851
|
-
googleapis.href = `https://fonts.googleapis.com`;
|
|
852
|
-
googleapis.rel = "preconnect";
|
|
853
|
-
const gstatic = document.createElement("link");
|
|
854
|
-
gstatic.href = `https://fonts.gstatic.com`;
|
|
855
|
-
gstatic.rel = "preconnect";
|
|
856
|
-
gstatic.crossOrigin = "true";
|
|
857
|
-
const link = document.createElement("link");
|
|
858
|
-
link.href = `https://fonts.googleapis.com/css2?family=${font}:wght@400;500;600&display=swap`;
|
|
859
|
-
link.rel = "stylesheet";
|
|
860
|
-
document.head.appendChild(googleapis);
|
|
861
|
-
document.head.appendChild(gstatic);
|
|
862
|
-
document.head.appendChild(link);
|
|
863
|
-
return () => {
|
|
864
|
-
try {
|
|
865
|
-
document.head.removeChild(googleapis);
|
|
866
|
-
document.head.removeChild(gstatic);
|
|
867
|
-
document.head.removeChild(link);
|
|
868
|
-
}
|
|
869
|
-
catch { }
|
|
870
|
-
};
|
|
871
|
-
}, [font]);
|
|
872
|
-
}
|
|
873
|
-
// TODO: This could be dynamic if theming wasn't set up as css variables
|
|
874
|
-
function useThemeFont(theme) {
|
|
875
|
-
const themeFonts = {
|
|
876
|
-
web95: "Lato",
|
|
877
|
-
retro: "Nunito",
|
|
878
|
-
midnight: "Inter",
|
|
879
|
-
minimal: "Inter",
|
|
880
|
-
rounded: "Nunito",
|
|
881
|
-
};
|
|
882
|
-
const font = themeFonts[theme] ?? null;
|
|
883
|
-
useGoogleFont(font ?? "");
|
|
884
|
-
}
|
|
885
|
-
|
|
886
839
|
/** Daimo Pay internal context. */
|
|
887
840
|
const usePayContext = () => {
|
|
888
841
|
const context = React.useContext(PayContext);
|
|
@@ -1174,7 +1127,7 @@ function useWalletPaymentOptions({ trpc, address, usdRequired, destChainId, pref
|
|
|
1174
1127
|
};
|
|
1175
1128
|
}
|
|
1176
1129
|
|
|
1177
|
-
function usePaymentState({ trpc, daimoPayOrder, setDaimoPayOrder,
|
|
1130
|
+
function usePaymentState({ trpc, lockPayParams, daimoPayOrder, setDaimoPayOrder, setRoute, log, redirectReturnUrl, }) {
|
|
1178
1131
|
// Browser state.
|
|
1179
1132
|
const [platform, setPlatform] = useState();
|
|
1180
1133
|
useEffect(() => {
|
|
@@ -1189,12 +1142,22 @@ function usePaymentState({ trpc, daimoPayOrder, setDaimoPayOrder, setOpen, log,
|
|
|
1189
1142
|
// Solana wallet state.
|
|
1190
1143
|
const solanaWallet = useWallet$1();
|
|
1191
1144
|
const solanaPubKey = solanaWallet.publicKey?.toBase58();
|
|
1192
|
-
//
|
|
1145
|
+
// TODO: backend should determine whether to show solana payment method
|
|
1146
|
+
const paymentOptions = daimoPayOrder?.metadata.payer?.paymentOptions;
|
|
1147
|
+
// Include by default if paymentOptions not provided. Solana bridging is only
|
|
1148
|
+
// supported on CCTP v1 chains.
|
|
1149
|
+
const showSolanaPaymentMethod = (paymentOptions == null ||
|
|
1150
|
+
paymentOptions.includes(ExternalPaymentOptions.Solana)) &&
|
|
1151
|
+
daimoPayOrder != null &&
|
|
1152
|
+
isCCTPV1Chain(getOrderDestChainId(daimoPayOrder));
|
|
1153
|
+
// Refs the survive re-renders and stores any updated param values while
|
|
1154
|
+
// lockPayParams is true
|
|
1155
|
+
const latestPayParamsRef = useRef();
|
|
1156
|
+
const latestPayIdRef = useRef();
|
|
1157
|
+
// Current pay params to do processing off of
|
|
1193
1158
|
const [payParams, setPayParamsState] = useState();
|
|
1194
1159
|
const [paymentWaitingMessage, setPaymentWaitingMessage] = useState();
|
|
1195
1160
|
const [isDepositFlow, setIsDepositFlow] = useState(false);
|
|
1196
|
-
// Payment UI config.
|
|
1197
|
-
const [modalOptions, setModalOptions] = useState({});
|
|
1198
1161
|
// UI state. Selection for external payment (Binance, etc) vs wallet payment.
|
|
1199
1162
|
const externalPaymentOptions = useExternalPaymentOptions({
|
|
1200
1163
|
trpc,
|
|
@@ -1332,16 +1295,16 @@ function usePaymentState({ trpc, daimoPayOrder, setDaimoPayOrder, setOpen, log,
|
|
|
1332
1295
|
else {
|
|
1333
1296
|
log(`[CHECKOUT] IGNORING refreshOrder, wrong ID: ${order.id} vs ${daimoPayOrder.id}`);
|
|
1334
1297
|
}
|
|
1335
|
-
}, [daimoPayOrder
|
|
1298
|
+
}, [daimoPayOrder, trpc, setDaimoPayOrder, log]);
|
|
1336
1299
|
/** User picked a different deposit amount. */
|
|
1337
1300
|
const setChosenUsd = (usd) => {
|
|
1338
1301
|
assert(!!daimoPayOrder, "[SET CHOSEN USD] daimoPayOrder cannot be null");
|
|
1339
1302
|
const token = daimoPayOrder.destFinalCallTokenAmount.token;
|
|
1340
|
-
const tokenUnits = (usd / token.
|
|
1303
|
+
const tokenUnits = (usd / token.priceFromUsd).toString();
|
|
1341
1304
|
const tokenAmount = parseUnits(tokenUnits, token.decimals);
|
|
1342
1305
|
// TODO: remove amount from destFinalCall, it is redundant with
|
|
1343
1306
|
// destFinalCallTokenAmount. Here, we only modify one and not the other.
|
|
1344
|
-
log(`[CHECKOUT]
|
|
1307
|
+
log(`[CHECKOUT] chose USD amount $${usd} = ${tokenUnits} ${token.symbol}`);
|
|
1345
1308
|
setDaimoPayOrder({
|
|
1346
1309
|
...daimoPayOrder,
|
|
1347
1310
|
destFinalCallTokenAmount: {
|
|
@@ -1352,7 +1315,8 @@ function usePaymentState({ trpc, daimoPayOrder, setDaimoPayOrder, setOpen, log,
|
|
|
1352
1315
|
});
|
|
1353
1316
|
};
|
|
1354
1317
|
const setPayId = useCallback(async (payId) => {
|
|
1355
|
-
|
|
1318
|
+
latestPayIdRef.current = payId;
|
|
1319
|
+
if (lockPayParams || !payId)
|
|
1356
1320
|
return;
|
|
1357
1321
|
const id = readDaimoPayOrderID(payId).toString();
|
|
1358
1322
|
if (daimoPayOrder && BigInt(id) == daimoPayOrder.id) {
|
|
@@ -1366,15 +1330,19 @@ function usePaymentState({ trpc, daimoPayOrder, setDaimoPayOrder, setOpen, log,
|
|
|
1366
1330
|
}
|
|
1367
1331
|
log(`[CHECKOUT] setPayId: fetched order: ${JSON.stringify(order)}`);
|
|
1368
1332
|
setDaimoPayOrder(order);
|
|
1369
|
-
}, [daimoPayOrder]);
|
|
1333
|
+
}, [daimoPayOrder, lockPayParams, trpc, log, setDaimoPayOrder]);
|
|
1370
1334
|
/** Called whenever params change. */
|
|
1371
1335
|
const setPayParams = async (payParams) => {
|
|
1336
|
+
latestPayParamsRef.current = payParams;
|
|
1337
|
+
if (lockPayParams)
|
|
1338
|
+
return;
|
|
1372
1339
|
assert(payParams != null, "[SET PAY PARAMS] payParams cannot be null");
|
|
1340
|
+
console.log("[SET PAY PARAMS] setting payParams");
|
|
1373
1341
|
setPayParamsState(payParams);
|
|
1374
1342
|
setIsDepositFlow(payParams.toUnits == null);
|
|
1375
1343
|
generatePreviewOrder(payParams);
|
|
1376
1344
|
};
|
|
1377
|
-
const generatePreviewOrder = async (payParams) => {
|
|
1345
|
+
const generatePreviewOrder = useCallback(async (payParams) => {
|
|
1378
1346
|
// toUnits is undefined if and only if we're in deposit flow.
|
|
1379
1347
|
// Set dummy value for deposit flow, since user can edit the amount.
|
|
1380
1348
|
const toUnits = payParams.toUnits == null ? "0" : payParams.toUnits;
|
|
@@ -1402,13 +1370,28 @@ function usePaymentState({ trpc, daimoPayOrder, setDaimoPayOrder, setOpen, log,
|
|
|
1402
1370
|
});
|
|
1403
1371
|
log(`[CHECKOUT] generated preview: ${JSON.stringify(orderPreview)}`);
|
|
1404
1372
|
setDaimoPayOrder(orderPreview);
|
|
1405
|
-
};
|
|
1406
|
-
const
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1373
|
+
}, [trpc, log, setDaimoPayOrder]);
|
|
1374
|
+
const resetOrder = useCallback(() => {
|
|
1375
|
+
// Clear the old order & UI
|
|
1376
|
+
setDaimoPayOrder(undefined);
|
|
1377
|
+
setRoute(ROUTES.SELECT_METHOD);
|
|
1378
|
+
// Prefer an explicit payId, otherwise use the queued payParams
|
|
1379
|
+
if (latestPayIdRef.current) {
|
|
1380
|
+
setPayId(latestPayIdRef.current);
|
|
1381
|
+
latestPayIdRef.current = undefined;
|
|
1382
|
+
}
|
|
1383
|
+
else if (latestPayParamsRef.current) {
|
|
1384
|
+
const p = latestPayParamsRef.current;
|
|
1385
|
+
setPayParamsState(p);
|
|
1386
|
+
generatePreviewOrder(p);
|
|
1410
1387
|
}
|
|
1411
|
-
}
|
|
1388
|
+
}, [
|
|
1389
|
+
setDaimoPayOrder,
|
|
1390
|
+
setRoute,
|
|
1391
|
+
setPayId,
|
|
1392
|
+
setPayParamsState,
|
|
1393
|
+
generatePreviewOrder,
|
|
1394
|
+
]);
|
|
1412
1395
|
return {
|
|
1413
1396
|
setPayId,
|
|
1414
1397
|
payParams,
|
|
@@ -1416,18 +1399,18 @@ function usePaymentState({ trpc, daimoPayOrder, setDaimoPayOrder, setOpen, log,
|
|
|
1416
1399
|
generatePreviewOrder,
|
|
1417
1400
|
daimoPayOrder,
|
|
1418
1401
|
isDepositFlow,
|
|
1419
|
-
modalOptions,
|
|
1420
|
-
setModalOptions,
|
|
1421
1402
|
paymentWaitingMessage,
|
|
1422
1403
|
selectedExternalOption,
|
|
1423
1404
|
selectedTokenOption,
|
|
1424
1405
|
selectedSolanaTokenOption,
|
|
1425
1406
|
externalPaymentOptions,
|
|
1407
|
+
showSolanaPaymentMethod,
|
|
1426
1408
|
walletPaymentOptions,
|
|
1427
1409
|
solanaPaymentOptions,
|
|
1428
1410
|
depositAddressOptions,
|
|
1429
1411
|
selectedDepositAddressOption,
|
|
1430
1412
|
getOrderUsdLimit,
|
|
1413
|
+
resetOrder,
|
|
1431
1414
|
setPaymentWaitingMessage,
|
|
1432
1415
|
setSelectedExternalOption,
|
|
1433
1416
|
setSelectedTokenOption,
|
|
@@ -1439,7 +1422,6 @@ function usePaymentState({ trpc, daimoPayOrder, setDaimoPayOrder, setOpen, log,
|
|
|
1439
1422
|
payWithDepositAddress,
|
|
1440
1423
|
payWithSolanaToken,
|
|
1441
1424
|
refreshOrder,
|
|
1442
|
-
onSuccess,
|
|
1443
1425
|
senderEnsName: senderEnsName ?? undefined,
|
|
1444
1426
|
};
|
|
1445
1427
|
}
|
|
@@ -4887,9 +4869,39 @@ const useWallet = (id) => {
|
|
|
4887
4869
|
return null;
|
|
4888
4870
|
return wallet;
|
|
4889
4871
|
};
|
|
4890
|
-
const useWallets = () => {
|
|
4872
|
+
const useWallets = (isMobile) => {
|
|
4891
4873
|
const connectors = useConnectors();
|
|
4892
4874
|
const context = usePayContext();
|
|
4875
|
+
if (isMobile) {
|
|
4876
|
+
const mobileWallets = [];
|
|
4877
|
+
// Add Rainbow first
|
|
4878
|
+
mobileWallets.push({
|
|
4879
|
+
id: "me.rainbow",
|
|
4880
|
+
...walletConfigs["me.rainbow"],
|
|
4881
|
+
});
|
|
4882
|
+
// Add MetaMask second
|
|
4883
|
+
const metaMaskConnector = connectors.find((c) => c.id === "metaMask");
|
|
4884
|
+
if (metaMaskConnector) {
|
|
4885
|
+
mobileWallets.push({
|
|
4886
|
+
id: metaMaskConnector.id,
|
|
4887
|
+
connector: metaMaskConnector,
|
|
4888
|
+
...walletConfigs["metaMask, metaMask-io, io.metamask, io.metamask.mobile, metaMaskSDK"],
|
|
4889
|
+
});
|
|
4890
|
+
}
|
|
4891
|
+
// Add WalletConnect and other wallets
|
|
4892
|
+
connectors.forEach((connector) => {
|
|
4893
|
+
if (connector.id === "metaMask")
|
|
4894
|
+
return;
|
|
4895
|
+
if (isCoinbaseWalletConnector(connector.id))
|
|
4896
|
+
return;
|
|
4897
|
+
mobileWallets.push({
|
|
4898
|
+
id: connector.id,
|
|
4899
|
+
connector,
|
|
4900
|
+
...walletConfigs[connector.id],
|
|
4901
|
+
});
|
|
4902
|
+
});
|
|
4903
|
+
return mobileWallets;
|
|
4904
|
+
}
|
|
4893
4905
|
const wallets = connectors.map((connector) => {
|
|
4894
4906
|
// use overrides
|
|
4895
4907
|
const walletId = Object.keys(walletConfigs).find(
|
|
@@ -4944,8 +4956,8 @@ const useWallets = () => {
|
|
|
4944
4956
|
self.find((w) => w.id === "farcaster")))
|
|
4945
4957
|
// order by isInstalled injected connectors first
|
|
4946
4958
|
.sort((a, b) => {
|
|
4947
|
-
const AisInstalled = a.isInstalled && isInjectedConnector(a.connector
|
|
4948
|
-
const BisInstalled = b.isInstalled && isInjectedConnector(b.connector
|
|
4959
|
+
const AisInstalled = a.isInstalled && isInjectedConnector(a.connector?.type);
|
|
4960
|
+
const BisInstalled = b.isInstalled && isInjectedConnector(b.connector?.type);
|
|
4949
4961
|
if (AisInstalled && !BisInstalled)
|
|
4950
4962
|
return -1;
|
|
4951
4963
|
if (!AisInstalled && BisInstalled)
|
|
@@ -6845,6 +6857,14 @@ function useWalletConnectUri({ enabled } = {
|
|
|
6845
6857
|
};
|
|
6846
6858
|
}
|
|
6847
6859
|
|
|
6860
|
+
/** Determines whether the current wagmi configuration supports a given chain. */
|
|
6861
|
+
function useChainIsSupported(chainId) {
|
|
6862
|
+
const { chains } = useConfig();
|
|
6863
|
+
if (!chainId)
|
|
6864
|
+
return false;
|
|
6865
|
+
return chains.some((x) => x.id === chainId);
|
|
6866
|
+
}
|
|
6867
|
+
|
|
6848
6868
|
const Web3Context = React.createContext({
|
|
6849
6869
|
connect: {
|
|
6850
6870
|
getUri: () => "",
|
|
@@ -7246,15 +7266,15 @@ const ConnectorsContainer = styled.div `
|
|
|
7246
7266
|
const ConnectorList = () => {
|
|
7247
7267
|
const context = usePayContext();
|
|
7248
7268
|
const { isMobile } = useIsMobile();
|
|
7249
|
-
const wallets = useWallets();
|
|
7269
|
+
const wallets = useWallets(isMobile);
|
|
7250
7270
|
const { lastConnectorId } = useLastConnector();
|
|
7251
7271
|
const walletsToDisplay = context.options?.hideRecentBadge || lastConnectorId === "walletConnect" // do not hoist walletconnect to top of list
|
|
7252
7272
|
? wallets
|
|
7253
7273
|
: [
|
|
7254
7274
|
// move last used wallet to top of list
|
|
7255
7275
|
// using .filter and spread to avoid mutating original array order with .sort
|
|
7256
|
-
...wallets.filter((wallet) => lastConnectorId === wallet.connector
|
|
7257
|
-
...wallets.filter((wallet) => lastConnectorId !== wallet.connector
|
|
7276
|
+
...wallets.filter((wallet) => lastConnectorId === wallet.connector?.id),
|
|
7277
|
+
...wallets.filter((wallet) => lastConnectorId !== wallet.connector?.id),
|
|
7258
7278
|
];
|
|
7259
7279
|
return (jsxs(ScrollArea, { mobileDirection: "horizontal", children: [walletsToDisplay.length === 0 && (jsx(Alert, { error: true, children: "No connectors found in ConnectKit config." })), walletsToDisplay.length > 0 && (jsx(ConnectorsContainer, { "$mobile": isMobile, "$totalResults": walletsToDisplay.length, children: walletsToDisplay.map((wallet) => (jsx(ConnectorItem, { wallet: wallet, isRecent: wallet.id === lastConnectorId }, wallet.id))) }))] }));
|
|
7260
7280
|
};
|
|
@@ -7271,7 +7291,7 @@ const ConnectorItem = ({ wallet, isRecent, }) => {
|
|
|
7271
7291
|
const redirectToMoreWallets = isMobile && isWalletConnectConnector(wallet.id);
|
|
7272
7292
|
// Safari requires opening popup on user gesture, so we connect immediately here
|
|
7273
7293
|
const shouldConnectImmediately = (detectBrowser() === "safari" || detectBrowser() === "ios") &&
|
|
7274
|
-
isCoinbaseWalletConnector(wallet.connector
|
|
7294
|
+
isCoinbaseWalletConnector(wallet.connector?.id);
|
|
7275
7295
|
if (redirectToMoreWallets || shouldConnectImmediately)
|
|
7276
7296
|
deeplink = undefined; // mobile redirects to more wallets page
|
|
7277
7297
|
return (jsxs(ConnectorButton, { type: "button", as: deeplink ? "a" : undefined, href: deeplink ? deeplink : undefined, disabled: context.route !== ROUTES.CONNECTORS, onClick: deeplink
|
|
@@ -8225,7 +8245,7 @@ const MobileConnectors = () => {
|
|
|
8225
8245
|
// filter out installed wallets
|
|
8226
8246
|
const walletsIdsToDisplay = Object.keys(walletConfigs).filter((walletId) => {
|
|
8227
8247
|
const wallet = walletConfigs[walletId];
|
|
8228
|
-
if (wallets.find((w) => w.connector
|
|
8248
|
+
if (wallets.find((w) => w.connector?.id === walletId))
|
|
8229
8249
|
return false;
|
|
8230
8250
|
if (!wallet.getWalletConnectDeeplink)
|
|
8231
8251
|
return false;
|
|
@@ -9357,7 +9377,7 @@ const ConnectWithInjector = ({ switchConnectMethod, forceState }) => {
|
|
|
9357
9377
|
return (jsx(PageContent, { children: jsxs(Container$4, { children: [jsx(ModalHeading, { children: "Invalid State" }), jsx(ModalContent, { children: jsx(Alert, { children: "No connectors match the id given. This state should never happen." }) })] }) }));
|
|
9358
9378
|
}
|
|
9359
9379
|
// TODO: Make this more generic
|
|
9360
|
-
if (isWalletConnectConnector(wallet?.connector
|
|
9380
|
+
if (isWalletConnectConnector(wallet?.connector?.id)) {
|
|
9361
9381
|
return (jsx(PageContent, { children: jsxs(Container$4, { children: [jsx(ModalHeading, { children: "Invalid State" }), jsx(ModalContent, { children: jsx(Alert, { children: "WalletConnect does not have an injection flow. This state should never happen." }) })] }) }));
|
|
9362
9382
|
}
|
|
9363
9383
|
return (jsx(PageContent, { children: jsxs(Container$4, { children: [jsx(ConnectingContainer, { children: jsxs(ConnectingAnimation, { "$shake": status === states$1.FAILED || status === states$1.REJECTED, "$circle": walletInfo.iconShape === "circle", children: [jsx(AnimatePresence, { children: (status === states$1.FAILED || status === states$1.REJECTED) && (jsx(RetryButton, { "aria-label": "Retry", initial: { opacity: 0, scale: 0.8 }, animate: { opacity: 1, scale: 1 }, exit: { opacity: 0, scale: 0.8 }, whileTap: { scale: 0.9 }, transition: { duration: 0.1 }, onClick: runConnect, children: jsx(RetryIconContainer, { children: jsx(Tooltip, { open: showTryAgainTooltip &&
|
|
@@ -9369,9 +9389,9 @@ const ConnectWithInjector = ({ switchConnectMethod, forceState }) => {
|
|
|
9369
9389
|
transform: "scale(1.14)",
|
|
9370
9390
|
position: "relative",
|
|
9371
9391
|
width: "100%",
|
|
9372
|
-
}, children: walletInfo.icon })) : (jsx(Fragment, { children: walletInfo.icon })), loading: status === states$1.CONNECTING }))] }) }), jsx(ModalContentContainer, { children: jsxs(AnimatePresence, { initial: false, children: [status === states$1.FAILED && (jsx(Content, { initial: "initial", animate: "animate", exit: "exit", variants: contentVariants$1, children: jsxs(ModalContent, { children: [jsxs(ModalH1, { "$error": true, children: [jsx(AlertIcon, {}), locales.injectionScreen_failed_h1] }), jsx(ModalBody, { children: locales.injectionScreen_failed_p })] }) }, states$1.FAILED)), status === states$1.REJECTED && (jsx(Content, { initial: "initial", animate: "animate", exit: "exit", variants: contentVariants$1, children: jsxs(ModalContent, { style: { paddingBottom: 28 }, children: [jsx(ModalH1, { children: locales.injectionScreen_rejected_h1 }), jsx(ModalBody, { children: locales.injectionScreen_rejected_p })] }) }, states$1.REJECTED)), (status === states$1.CONNECTING || status === states$1.EXPIRING) && (jsx(Content, { initial: "initial", animate: "animate", exit: "exit", variants: contentVariants$1, children: jsxs(ModalContent, { style: { paddingBottom: 28 }, children: [jsx(ModalH1, { children: wallet.connector
|
|
9392
|
+
}, children: walletInfo.icon })) : (jsx(Fragment, { children: walletInfo.icon })), loading: status === states$1.CONNECTING }))] }) }), jsx(ModalContentContainer, { children: jsxs(AnimatePresence, { initial: false, children: [status === states$1.FAILED && (jsx(Content, { initial: "initial", animate: "animate", exit: "exit", variants: contentVariants$1, children: jsxs(ModalContent, { children: [jsxs(ModalH1, { "$error": true, children: [jsx(AlertIcon, {}), locales.injectionScreen_failed_h1] }), jsx(ModalBody, { children: locales.injectionScreen_failed_p })] }) }, states$1.FAILED)), status === states$1.REJECTED && (jsx(Content, { initial: "initial", animate: "animate", exit: "exit", variants: contentVariants$1, children: jsxs(ModalContent, { style: { paddingBottom: 28 }, children: [jsx(ModalH1, { children: locales.injectionScreen_rejected_h1 }), jsx(ModalBody, { children: locales.injectionScreen_rejected_p })] }) }, states$1.REJECTED)), (status === states$1.CONNECTING || status === states$1.EXPIRING) && (jsx(Content, { initial: "initial", animate: "animate", exit: "exit", variants: contentVariants$1, children: jsxs(ModalContent, { style: { paddingBottom: 28 }, children: [jsx(ModalH1, { children: wallet.connector?.id === "injected"
|
|
9373
9393
|
? locales.injectionScreen_connecting_injected_h1
|
|
9374
|
-
: locales.injectionScreen_connecting_h1 }), jsx(ModalBody, { children: wallet.connector
|
|
9394
|
+
: locales.injectionScreen_connecting_h1 }), jsx(ModalBody, { children: wallet.connector?.id === "injected"
|
|
9375
9395
|
? locales.injectionScreen_connecting_injected_p
|
|
9376
9396
|
: locales.injectionScreen_connecting_p }), jsxs(Button, { icon: jsx(ExternalLinkIcon, {}), onClick: runConnect, children: ["Connect ", walletInfo.name] })] }) }, states$1.CONNECTING)), status === states$1.CONNECTED && (jsx(Content, { initial: "initial", animate: "animate", exit: "exit", variants: contentVariants$1, children: jsxs(ModalContent, { children: [jsxs(ModalH1, { "$valid": true, children: [jsx(TickIcon, {}), " ", locales.injectionScreen_connected_h1] }), jsx(ModalBody, { children: locales.injectionScreen_connected_p })] }) }, states$1.CONNECTED)), status === states$1.NOTCONNECTED && (jsx(Content, { initial: "initial", animate: "animate", exit: "exit", variants: contentVariants$1, children: jsxs(ModalContent, { children: [jsx(ModalH1, { children: locales.injectionScreen_notconnected_h1 }), jsx(ModalBody, { children: locales.injectionScreen_notconnected_p })] }) }, states$1.NOTCONNECTED)), status === states$1.UNAVAILABLE && (jsx(Content, { initial: "initial", animate: "animate", exit: "exit", variants: contentVariants$1, children: !extensionUrl ? (jsxs(Fragment, { children: [jsxs(ModalContent, { style: { paddingBottom: 12 }, children: [jsx(ModalH1, { children: locales.injectionScreen_unavailable_h1 }), jsx(ModalBody, { children: locales.injectionScreen_unavailable_p })] }), !wallet.isInstalled && suggestedExtension && (jsxs(Button, { href: suggestedExtension?.url, icon: jsx(BrowserIcon, { browser: suggestedExtension?.name }), children: ["Install on ", suggestedExtension?.label] }))] })) : (jsxs(Fragment, { children: [jsxs(ModalContent, { style: { paddingBottom: 18 }, children: [jsx(ModalH1, { children: locales.injectionScreen_install_h1 }), jsx(ModalBody, { children: locales.injectionScreen_install_p })] }), !wallet.isInstalled && extensionUrl && (jsx(Button, { href: extensionUrl, icon: jsx(BrowserIcon, {}), children: locales.installTheExtension }))] })) }, states$1.UNAVAILABLE))] }) })] }) }));
|
|
9377
9397
|
};
|
|
@@ -9459,7 +9479,7 @@ const ConnectUsing = () => {
|
|
|
9459
9479
|
useEffect(() => {
|
|
9460
9480
|
// if no provider, change to qrcode
|
|
9461
9481
|
const checkProvider = async () => {
|
|
9462
|
-
const res = await wallet?.connector
|
|
9482
|
+
const res = await wallet?.connector?.getProvider();
|
|
9463
9483
|
if (!res) {
|
|
9464
9484
|
setStatus(states.QRCODE);
|
|
9465
9485
|
setTimeout(context.triggerResize, 10); // delay required here for modal to resize
|
|
@@ -9566,20 +9586,17 @@ const Underline = styled(motion.span) `
|
|
|
9566
9586
|
`;
|
|
9567
9587
|
|
|
9568
9588
|
const Confirmation = () => {
|
|
9569
|
-
const { paymentState, confirmationMessage } = usePayContext();
|
|
9589
|
+
const { paymentState, confirmationMessage, onSuccess } = usePayContext();
|
|
9570
9590
|
const { daimoPayOrder } = paymentState;
|
|
9571
|
-
const { done, txURL } = (() => {
|
|
9591
|
+
const { done, txURL } = useMemo(() => {
|
|
9572
9592
|
if (daimoPayOrder && daimoPayOrder.mode === DaimoPayOrderMode.HYDRATED) {
|
|
9573
|
-
// Frontends are optimistic, assume submits will be successful
|
|
9574
9593
|
const { destStatus } = daimoPayOrder;
|
|
9575
|
-
if (destStatus === DaimoPayOrderStatusDest.
|
|
9576
|
-
destStatus === DaimoPayOrderStatusDest.FAST_FINISHED ||
|
|
9594
|
+
if (destStatus === DaimoPayOrderStatusDest.FAST_FINISHED ||
|
|
9577
9595
|
destStatus === DaimoPayOrderStatusDest.CLAIM_SUCCESSFUL) {
|
|
9578
9596
|
const txHash = daimoPayOrder.destFastFinishTxHash ?? daimoPayOrder.destClaimTxHash;
|
|
9579
|
-
const
|
|
9597
|
+
const destChainId = getOrderDestChainId(daimoPayOrder);
|
|
9580
9598
|
assert(txHash != null, `[CONFIRMATION] dest status: ${destStatus}, but missing txHash`);
|
|
9581
|
-
const txURL = getChainExplorerTxUrl(
|
|
9582
|
-
paymentState.onSuccess({ txHash, txURL });
|
|
9599
|
+
const txURL = getChainExplorerTxUrl(destChainId, txHash);
|
|
9583
9600
|
return {
|
|
9584
9601
|
done: true,
|
|
9585
9602
|
txURL,
|
|
@@ -9590,7 +9607,12 @@ const Confirmation = () => {
|
|
|
9590
9607
|
done: false,
|
|
9591
9608
|
txURL: undefined,
|
|
9592
9609
|
};
|
|
9593
|
-
})
|
|
9610
|
+
}, [daimoPayOrder]);
|
|
9611
|
+
useEffect(() => {
|
|
9612
|
+
if (done) {
|
|
9613
|
+
onSuccess();
|
|
9614
|
+
}
|
|
9615
|
+
}, [done, onSuccess]);
|
|
9594
9616
|
return (jsx(PageContent, { style: {
|
|
9595
9617
|
display: "flex",
|
|
9596
9618
|
justifyContent: "center",
|
|
@@ -9634,8 +9656,6 @@ const Link = styled.a `
|
|
|
9634
9656
|
`;
|
|
9635
9657
|
const SuccessIcon = styled(TickIcon) `
|
|
9636
9658
|
color: var(--ck-body-color-valid);
|
|
9637
|
-
|
|
9638
|
-
transform: scale(0.5);
|
|
9639
9659
|
transition: all 0.2s ease-in-out;
|
|
9640
9660
|
position: absolute;
|
|
9641
9661
|
opacity: ${(props) => (props.$status ? 1 : 0)};
|
|
@@ -9646,7 +9666,6 @@ const Spinner$1 = styled(LoadingCircleIcon) `
|
|
|
9646
9666
|
transition: all 0.2s ease-in-out;
|
|
9647
9667
|
animation: rotateSpinner 400ms linear infinite;
|
|
9648
9668
|
opacity: ${(props) => (props.$status ? 0 : 1)};
|
|
9649
|
-
transform: ${(props) => (props.$status ? "scale(0.5)" : "scale(1)")};
|
|
9650
9669
|
|
|
9651
9670
|
@keyframes rotateSpinner {
|
|
9652
9671
|
0% {
|
|
@@ -9761,8 +9780,8 @@ const ChainLogoContainer = styled(motion.div) `
|
|
|
9761
9780
|
}
|
|
9762
9781
|
`;
|
|
9763
9782
|
|
|
9764
|
-
const TokenLogoSpinner = ({ token
|
|
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:
|
|
9783
|
+
const TokenLogoSpinner = ({ token }) => {
|
|
9784
|
+
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: false, unavailable: false }, "CircleSpinner")] }) }) }));
|
|
9766
9785
|
};
|
|
9767
9786
|
|
|
9768
9787
|
var PayState$1;
|
|
@@ -9869,12 +9888,12 @@ const PayWithToken = () => {
|
|
|
9869
9888
|
if (selectedTokenOption == null) {
|
|
9870
9889
|
return jsx(PageContent, {});
|
|
9871
9890
|
}
|
|
9872
|
-
return (jsxs(PageContent, { children: [jsx(TokenLogoSpinner, { token: selectedTokenOption.required.token }), jsxs(ModalContent, { style: { paddingBottom: 0 }, "$preserveDisplay": true, children: [jsx(ModalH1, { children: payState }), jsx(PaymentBreakdown, { paymentOption: selectedTokenOption }), payState === PayState$1.RequestingPayment && wcWallet && isMobile && (
|
|
9891
|
+
return (jsxs(PageContent, { children: [jsx(TokenLogoSpinner, { token: selectedTokenOption.required.token }), jsxs(ModalContent, { style: { paddingBottom: 0 }, "$preserveDisplay": true, children: [jsx(ModalH1, { children: payState }), jsx(PaymentBreakdown, { paymentOption: selectedTokenOption }), payState === PayState$1.RequestingPayment && wcWallet && isMobile && (jsx(Button, { icon: jsx(ExternalLinkIcon, {}), onClick: wcWallet.isWcMobileConnector
|
|
9873
9892
|
? () => handleTransfer(selectedTokenOption)
|
|
9874
9893
|
: undefined, href: wcWallet.isWcMobileConnector
|
|
9875
9894
|
? undefined
|
|
9876
9895
|
: wcWallet.walletDeepLink ||
|
|
9877
|
-
wcWallet.getWalletConnectDeeplink?.(""), children:
|
|
9896
|
+
wcWallet.getWalletConnectDeeplink?.(""), children: "Tap Here to Pay" })), payState === PayState$1.RequestCancelled && (jsx(Button, { onClick: () => handleTransfer(selectedTokenOption), children: "Retry Payment" }))] })] }));
|
|
9878
9897
|
};
|
|
9879
9898
|
|
|
9880
9899
|
/**
|
|
@@ -10087,7 +10106,7 @@ const MultiCurrencySelectAmount = ({ selectedTokenOption, setSelectedTokenOption
|
|
|
10087
10106
|
tokenSymbol: balanceToken.symbol,
|
|
10088
10107
|
});
|
|
10089
10108
|
};
|
|
10090
|
-
return (jsxs(PageContent, { children: [jsx(TokenLogoSpinner, { token: balanceToken
|
|
10109
|
+
return (jsxs(PageContent, { children: [jsx(TokenLogoSpinner, { token: balanceToken }), jsxs(ModalContent, { "$preserveDisplay": true, children: [jsxs(AmountInputContainer$2, { children: [jsx(MaxButton, { style: { visibility: "hidden" }, children: "Max" }), jsx(AmountInputField, { value: isEditingUsd ? usdValue : tokenValue, onChange: handleAmountChange, currency: isEditingUsd ? "$" : balanceToken.symbol, onKeyDown: handleKeyDown }), jsx(MaxButton, { onClick: handleMax, children: "Max" })] }), balanceToken.fiatISO !== "USD" && (jsx(SwitchContainer, { children: jsx(SwitchButton, { onClick: handleSwitchCurrency, children: jsx(SecondaryAmount, { children: isEditingUsd
|
|
10091
10110
|
? `${tokenValue} ${balanceToken.symbol}`
|
|
10092
10111
|
: `$${usdValue}` }) }) })), message && jsx(ModalBody, { children: message }), jsx(Button, { onClick: handleContinue, disabled: continueDisabled, children: "Continue" })] })] }));
|
|
10093
10112
|
};
|
|
@@ -10135,13 +10154,13 @@ const SelectAmount = () => {
|
|
|
10135
10154
|
return (jsx(MultiCurrencySelectAmount, { selectedTokenOption: selectedTokenOption, setSelectedTokenOption: setSelectedTokenOption, nextPage: ROUTES.PAY_WITH_TOKEN }));
|
|
10136
10155
|
};
|
|
10137
10156
|
|
|
10138
|
-
const ExternalPaymentSpinner = ({ logoURI, logoShape,
|
|
10157
|
+
const ExternalPaymentSpinner = ({ logoURI, logoShape, }) => {
|
|
10139
10158
|
const optionSpinner = (() => {
|
|
10140
10159
|
if (logoShape === "circle") {
|
|
10141
|
-
return (jsx(CircleSpinner, { logo: jsx("img", { src: logoURI }), loading:
|
|
10160
|
+
return (jsx(CircleSpinner, { logo: jsx("img", { src: logoURI }), loading: false, unavailable: false }));
|
|
10142
10161
|
}
|
|
10143
10162
|
else {
|
|
10144
|
-
return
|
|
10163
|
+
return jsx(SquircleSpinner, { logo: jsx("img", { src: logoURI }), loading: false });
|
|
10145
10164
|
}
|
|
10146
10165
|
})();
|
|
10147
10166
|
return (jsx(LoadingContainer$2, { children: jsx(AnimationContainer$1, { "$circle": logoShape === "circle", children: jsx(AnimatePresence, { children: optionSpinner }) }) }));
|
|
@@ -10187,7 +10206,7 @@ const SelectDepositAddressAmount = () => {
|
|
|
10187
10206
|
paymentState.setChosenUsd(amountUsd);
|
|
10188
10207
|
setRoute(ROUTES.WAITING_DEPOSIT_ADDRESS, { amountUsd });
|
|
10189
10208
|
};
|
|
10190
|
-
return (jsxs(PageContent, { children: [jsx(ExternalPaymentSpinner, { logoURI: selectedDepositAddressOption.logoURI, logoShape: "circle"
|
|
10209
|
+
return (jsxs(PageContent, { children: [jsx(ExternalPaymentSpinner, { logoURI: selectedDepositAddressOption.logoURI, logoShape: "circle" }), jsxs(ModalContent, { "$preserveDisplay": true, children: [jsx(AmountInputContainer$1, { children: jsx(AmountInputField, { value: usdInput, onChange: handleAmountChange, onKeyDown: handleKeyDown }) }), message && jsx(ModalBody, { children: message }), jsx(Button, { onClick: handleContinue, disabled: continueDisabled, children: "Continue" })] })] }));
|
|
10191
10210
|
};
|
|
10192
10211
|
const AmountInputContainer$1 = styled.div `
|
|
10193
10212
|
display: flex;
|
|
@@ -10449,7 +10468,7 @@ const IconStackItem = styled(motion.div) `
|
|
|
10449
10468
|
border-radius: 22.5%;
|
|
10450
10469
|
`;
|
|
10451
10470
|
|
|
10452
|
-
const OptionsContainer = styled
|
|
10471
|
+
const OptionsContainer = styled.div `
|
|
10453
10472
|
width: 100%;
|
|
10454
10473
|
margin-top: 1rem;
|
|
10455
10474
|
`;
|
|
@@ -10598,7 +10617,7 @@ const SelectExternalAmount = () => {
|
|
|
10598
10617
|
paymentState.setChosenUsd(amountUsd);
|
|
10599
10618
|
setRoute(ROUTES.WAITING_EXTERNAL, { amountUsd });
|
|
10600
10619
|
};
|
|
10601
|
-
return (jsxs(PageContent, { children: [jsx(ExternalPaymentSpinner, { logoURI: selectedExternalOption.logoURI, logoShape: selectedExternalOption.logoShape
|
|
10620
|
+
return (jsxs(PageContent, { children: [jsx(ExternalPaymentSpinner, { logoURI: selectedExternalOption.logoURI, logoShape: selectedExternalOption.logoShape }), jsxs(ModalContent, { "$preserveDisplay": true, children: [jsx(AmountInputContainer, { children: jsx(AmountInputField, { value: usdInput, onChange: handleAmountChange, onKeyDown: handleKeyDown }) }), message && jsx(ModalBody, { children: message }), jsx(Button, { onClick: handleContinue, disabled: continueDisabled, children: "Continue" })] })] }));
|
|
10602
10621
|
};
|
|
10603
10622
|
const AmountInputContainer = styled.div `
|
|
10604
10623
|
display: flex;
|
|
@@ -10630,7 +10649,7 @@ function SelectMethod() {
|
|
|
10630
10649
|
const { connected: isSolanaConnected, wallet: solanaWallet, publicKey, } = useWallet$1();
|
|
10631
10650
|
const { setRoute, paymentState, wcWallet, log } = usePayContext();
|
|
10632
10651
|
const { disconnectAsync } = useDisconnect();
|
|
10633
|
-
const { daimoPayOrder, setSelectedExternalOption, externalPaymentOptions, depositAddressOptions, senderEnsName, } = paymentState;
|
|
10652
|
+
const { daimoPayOrder, setSelectedExternalOption, externalPaymentOptions, showSolanaPaymentMethod, depositAddressOptions, senderEnsName, } = paymentState;
|
|
10634
10653
|
const paymentOptions = daimoPayOrder?.metadata.payer?.paymentOptions;
|
|
10635
10654
|
const getConnectedWalletOptions = () => {
|
|
10636
10655
|
const showChainLogo = isEthConnected && isSolanaConnected;
|
|
@@ -10665,7 +10684,7 @@ function SelectMethod() {
|
|
|
10665
10684
|
};
|
|
10666
10685
|
connectedOptions.push(connectedEthWalletOption);
|
|
10667
10686
|
}
|
|
10668
|
-
if (isSolanaConnected &&
|
|
10687
|
+
if (isSolanaConnected && showSolanaPaymentMethod) {
|
|
10669
10688
|
const solWalletDisplayName = getAddressContraction(publicKey?.toBase58() ?? "");
|
|
10670
10689
|
const connectedSolWalletOption = {
|
|
10671
10690
|
id: "connectedSolanaWallet",
|
|
@@ -10690,13 +10709,9 @@ function SelectMethod() {
|
|
|
10690
10709
|
}
|
|
10691
10710
|
return connectedOptions;
|
|
10692
10711
|
};
|
|
10693
|
-
// Solana payment option
|
|
10694
|
-
// Include by default if paymentOptions not provided
|
|
10695
|
-
const includeSolana = paymentOptions == null ||
|
|
10696
|
-
paymentOptions.includes(ExternalPaymentOptions.Solana);
|
|
10697
10712
|
// Deposit address options, e.g. Bitcoin, Tron, Zcash, etc.
|
|
10698
10713
|
// Include by default if paymentOptions not provided
|
|
10699
|
-
const
|
|
10714
|
+
const showDepositAddressMethod = paymentOptions == null ||
|
|
10700
10715
|
paymentOptions.includes(ExternalPaymentOptions.ExternalChains);
|
|
10701
10716
|
const connectedWalletOptions = getConnectedWalletOptions();
|
|
10702
10717
|
const unconnectedWalletOption = {
|
|
@@ -10714,7 +10729,7 @@ function SelectMethod() {
|
|
|
10714
10729
|
options.push(...connectedWalletOptions);
|
|
10715
10730
|
options.push(unconnectedWalletOption);
|
|
10716
10731
|
log(`[SELECT_METHOD] loading: ${externalPaymentOptions.loading}, options: ${JSON.stringify(externalPaymentOptions.options)}`);
|
|
10717
|
-
if (
|
|
10732
|
+
if (showSolanaPaymentMethod) {
|
|
10718
10733
|
const solanaOption = getSolanaOption(isIOS);
|
|
10719
10734
|
if (solanaOption) {
|
|
10720
10735
|
options.push(solanaOption);
|
|
@@ -10738,7 +10753,7 @@ function SelectMethod() {
|
|
|
10738
10753
|
disabled: option.disabled,
|
|
10739
10754
|
subtitle: option.message,
|
|
10740
10755
|
})));
|
|
10741
|
-
if (
|
|
10756
|
+
if (showDepositAddressMethod) {
|
|
10742
10757
|
const depositAddressOption = getDepositAddressOption(depositAddressOptions);
|
|
10743
10758
|
options.push(depositAddressOption);
|
|
10744
10759
|
}
|
|
@@ -10998,7 +11013,7 @@ var PayState;
|
|
|
10998
11013
|
})(PayState || (PayState = {}));
|
|
10999
11014
|
const PayWithSolanaToken = () => {
|
|
11000
11015
|
const { triggerResize, paymentState, setRoute } = usePayContext();
|
|
11001
|
-
const {
|
|
11016
|
+
const { selectedSolanaTokenOption, payWithSolanaToken } = paymentState;
|
|
11002
11017
|
const [payState, setPayState] = useState(PayState.RequestingPayment);
|
|
11003
11018
|
const handleTransfer = async () => {
|
|
11004
11019
|
try {
|
|
@@ -11135,6 +11150,7 @@ const WaitingExternal = () => {
|
|
|
11135
11150
|
const context = usePayContext();
|
|
11136
11151
|
const { triggerResize, paymentState, setRoute } = context;
|
|
11137
11152
|
const trpc = context.trpc;
|
|
11153
|
+
const { isMobile } = useIsMobile();
|
|
11138
11154
|
const { selectedExternalOption, payWithExternal, paymentWaitingMessage, daimoPayOrder, } = paymentState;
|
|
11139
11155
|
const [externalURL, setExternalURL] = useState(null);
|
|
11140
11156
|
useEffect(() => {
|
|
@@ -11160,17 +11176,19 @@ const WaitingExternal = () => {
|
|
|
11160
11176
|
});
|
|
11161
11177
|
}, [selectedExternalOption]);
|
|
11162
11178
|
const openExternalWindow = (url) => {
|
|
11163
|
-
if (
|
|
11164
|
-
//
|
|
11179
|
+
if (isMobile) {
|
|
11180
|
+
// on mobile: open in a new tab
|
|
11181
|
+
window.open(url, "_blank");
|
|
11182
|
+
}
|
|
11183
|
+
else {
|
|
11184
|
+
// on desktop: open in a popup window in
|
|
11185
|
+
// portrait mode in the center of the screen
|
|
11165
11186
|
const width = 500;
|
|
11166
11187
|
const height = 700;
|
|
11167
11188
|
const left = Math.max(0, Math.floor((window.innerWidth - width) / 2) + window.screenX);
|
|
11168
11189
|
const top = Math.max(0, Math.floor((window.innerHeight - height) / 2) + window.screenY);
|
|
11169
11190
|
window.open(url, "popupWindow", `width=${width},height=${height},left=${left},top=${top},scrollbars=yes`);
|
|
11170
11191
|
}
|
|
11171
|
-
else {
|
|
11172
|
-
window.open(url, "_blank");
|
|
11173
|
-
}
|
|
11174
11192
|
};
|
|
11175
11193
|
const waitingMessageLength = paymentWaitingMessage?.length;
|
|
11176
11194
|
useEffect(() => {
|
|
@@ -11186,18 +11204,18 @@ const WaitingExternal = () => {
|
|
|
11186
11204
|
}, children: selectedExternalOption.cta })] }));
|
|
11187
11205
|
};
|
|
11188
11206
|
|
|
11189
|
-
const
|
|
11190
|
-
const DaimoPayModal = ({ mode = "auto", theme = "auto", customTheme = customThemeDefault, lang = "en-US", }) => {
|
|
11207
|
+
const DaimoPayModal = ({ mode, theme, customTheme, lang, }) => {
|
|
11191
11208
|
const context = usePayContext();
|
|
11209
|
+
const { setMode, setTheme, setCustomTheme, setLang } = context;
|
|
11192
11210
|
const paymentState = context.paymentState;
|
|
11193
|
-
const { payParams, generatePreviewOrder, isDepositFlow, setPaymentWaitingMessage, setSelectedExternalOption, setSelectedTokenOption, setSelectedSolanaTokenOption, setSelectedDepositAddressOption, } = paymentState;
|
|
11211
|
+
const { payParams, generatePreviewOrder, isDepositFlow, showSolanaPaymentMethod, setPaymentWaitingMessage, setSelectedExternalOption, setSelectedTokenOption, setSelectedSolanaTokenOption, setSelectedDepositAddressOption, } = paymentState;
|
|
11194
11212
|
const { isConnected: isEthConnected, connector, chain, address, } = useAccount();
|
|
11195
11213
|
const { connected: isSolanaConnected } = useWallet$1();
|
|
11196
11214
|
const { daimoPayOrder } = paymentState;
|
|
11197
11215
|
const paymentOptions = daimoPayOrder?.metadata.payer?.paymentOptions;
|
|
11198
11216
|
// Solana payment option
|
|
11199
11217
|
// Include by default if paymentOptions not provided
|
|
11200
|
-
|
|
11218
|
+
paymentOptions == null ||
|
|
11201
11219
|
paymentOptions.includes(ExternalPaymentOptions.Solana);
|
|
11202
11220
|
const chainIsSupported = useChainIsSupported(chain?.id);
|
|
11203
11221
|
//if chain is unsupported we enforce a "switch chain" prompt
|
|
@@ -11317,34 +11335,46 @@ const DaimoPayModal = ({ mode = "auto", theme = "auto", customTheme = customThem
|
|
|
11317
11335
|
}
|
|
11318
11336
|
context.setOpen(false, { event: "click-close" });
|
|
11319
11337
|
}
|
|
11320
|
-
//
|
|
11338
|
+
// If the user has a wallet already connected upon opening the modal, go
|
|
11339
|
+
// straight to the select token screen
|
|
11321
11340
|
useEffect(() => {
|
|
11322
|
-
if (context.open
|
|
11323
|
-
|
|
11324
|
-
|
|
11325
|
-
|
|
11326
|
-
|
|
11327
|
-
|
|
11328
|
-
|
|
11329
|
-
|
|
11330
|
-
|
|
11331
|
-
|
|
11332
|
-
|
|
11333
|
-
|
|
11341
|
+
if (!context.open)
|
|
11342
|
+
return;
|
|
11343
|
+
if (context.route !== ROUTES.SELECT_METHOD)
|
|
11344
|
+
return;
|
|
11345
|
+
const ethMethodAvailable = context.wcWallet != null || isEthConnected;
|
|
11346
|
+
const solanaMethodAvailable = isSolanaConnected && showSolanaPaymentMethod;
|
|
11347
|
+
// Skip to token selection if exactly one wallet is connected. If both
|
|
11348
|
+
// wallets are connected, stay on the SELECT_METHOD screen to allow the
|
|
11349
|
+
// user to select which wallet to use
|
|
11350
|
+
if (ethMethodAvailable && !solanaMethodAvailable) {
|
|
11351
|
+
context.setRoute(ROUTES.SELECT_TOKEN, {
|
|
11352
|
+
event: "eth_connected_on_open",
|
|
11353
|
+
walletId: connector?.id,
|
|
11354
|
+
chainId: chain?.id,
|
|
11355
|
+
address,
|
|
11356
|
+
});
|
|
11334
11357
|
}
|
|
11335
|
-
else if (
|
|
11336
|
-
|
|
11337
|
-
|
|
11338
|
-
|
|
11339
|
-
includeSolana) {
|
|
11340
|
-
if (context.route === ROUTES.SELECT_METHOD) {
|
|
11341
|
-
context.setRoute(ROUTES.SOLANA_SELECT_TOKEN, {
|
|
11342
|
-
event: "solana_connected_on_open",
|
|
11343
|
-
});
|
|
11344
|
-
}
|
|
11358
|
+
else if (solanaMethodAvailable && !ethMethodAvailable) {
|
|
11359
|
+
context.setRoute(ROUTES.SOLANA_SELECT_TOKEN, {
|
|
11360
|
+
event: "solana_connected_on_open",
|
|
11361
|
+
});
|
|
11345
11362
|
}
|
|
11346
|
-
//
|
|
11347
|
-
|
|
11363
|
+
// Don't include context.route in the dependency array otherwise the user
|
|
11364
|
+
// can't go back from the select token screen to the select method screen
|
|
11365
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
11366
|
+
}, [
|
|
11367
|
+
context.open,
|
|
11368
|
+
context.wcWallet,
|
|
11369
|
+
isEthConnected,
|
|
11370
|
+
isSolanaConnected,
|
|
11371
|
+
showSolanaPaymentMethod,
|
|
11372
|
+
address,
|
|
11373
|
+
chain?.id,
|
|
11374
|
+
connector?.id,
|
|
11375
|
+
]);
|
|
11376
|
+
// If we're on the connect page and the user successfully connects their
|
|
11377
|
+
// wallet, go to the select token page
|
|
11348
11378
|
useEffect(() => {
|
|
11349
11379
|
if (context.route === ROUTES.CONNECT ||
|
|
11350
11380
|
context.route === ROUTES.CONNECTORS ||
|
|
@@ -11358,11 +11388,12 @@ const DaimoPayModal = ({ mode = "auto", theme = "auto", customTheme = customThem
|
|
|
11358
11388
|
});
|
|
11359
11389
|
}
|
|
11360
11390
|
}
|
|
11361
|
-
|
|
11362
|
-
|
|
11363
|
-
useEffect(() =>
|
|
11364
|
-
useEffect(() =>
|
|
11365
|
-
useEffect(() =>
|
|
11391
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
11392
|
+
}, [isEthConnected, context.route, connector?.id, chain?.id, address]);
|
|
11393
|
+
useEffect(() => setMode(mode), [mode, setMode]);
|
|
11394
|
+
useEffect(() => setTheme(theme), [theme, setTheme]);
|
|
11395
|
+
useEffect(() => setCustomTheme(customTheme), [customTheme, setCustomTheme]);
|
|
11396
|
+
useEffect(() => setLang(lang), [lang, setLang]);
|
|
11366
11397
|
/* When pulling data into WalletConnect, it prioritises the og:title tag over the title tag */
|
|
11367
11398
|
useEffect(() => {
|
|
11368
11399
|
const appName = getAppName();
|
|
@@ -11466,7 +11497,10 @@ const DaimoPayProviderWithoutSolana = ({ children, theme = "auto", mode = "auto"
|
|
|
11466
11497
|
onCloseRef.current = fn;
|
|
11467
11498
|
}, []);
|
|
11468
11499
|
const [open, setOpenState] = useState(false);
|
|
11500
|
+
const [lockPayParams, setLockPayParams] = useState(false);
|
|
11501
|
+
const [paymentCompleted, setPaymentCompleted] = useState(false);
|
|
11469
11502
|
const [route, setRouteState] = useState(ROUTES.SELECT_METHOD);
|
|
11503
|
+
const [modalOptions, setModalOptions] = useState();
|
|
11470
11504
|
// Daimo Pay context
|
|
11471
11505
|
const [daimoPayOrder, setDaimoPayOrderInner] = useState();
|
|
11472
11506
|
const [pendingConnectorId, setPendingConnectorId] = useState(undefined);
|
|
@@ -11477,22 +11511,46 @@ const DaimoPayProviderWithoutSolana = ({ children, theme = "auto", mode = "auto"
|
|
|
11477
11511
|
const [errorMessage, setErrorMessage] = useState("");
|
|
11478
11512
|
const [confirmationMessage, setConfirmationMessage] = useState(undefined);
|
|
11479
11513
|
const [redirectReturnUrl, setRedirectReturnUrl] = useState(undefined);
|
|
11480
|
-
const log = debugMode ? console.log : () => { };
|
|
11514
|
+
const log = useMemo(() => (debugMode ? console.log : () => { }), [debugMode]);
|
|
11481
11515
|
// Connect to the Daimo Pay TRPC API
|
|
11482
|
-
const trpc = useMemo(() => createTrpcClient(payApiUrl, sessionId), [payApiUrl]);
|
|
11516
|
+
const trpc = useMemo(() => createTrpcClient(payApiUrl, sessionId), [payApiUrl, sessionId]);
|
|
11483
11517
|
const [resize, onResize] = useState(0);
|
|
11484
11518
|
const setOpen = useCallback((open, meta) => {
|
|
11485
11519
|
setOpenState(open);
|
|
11520
|
+
// Lock pay params starting from the first time the modal is opened to
|
|
11521
|
+
// prevent the daimo pay order from changing from under the user
|
|
11522
|
+
if (open) {
|
|
11523
|
+
setLockPayParams(true);
|
|
11524
|
+
}
|
|
11525
|
+
// Reset payment state on close if resetOnSuccess is true
|
|
11526
|
+
if (!open && paymentCompleted && modalOptions?.resetOnSuccess) {
|
|
11527
|
+
setPaymentCompleted(false);
|
|
11528
|
+
setLockPayParams(false);
|
|
11529
|
+
paymentState.resetOrder();
|
|
11530
|
+
}
|
|
11531
|
+
// Log the open/close event
|
|
11486
11532
|
trpc.nav.mutate({
|
|
11487
11533
|
action: open ? "navOpenPay" : "navClosePay",
|
|
11488
11534
|
orderId: daimoPayOrder?.id?.toString(),
|
|
11489
11535
|
data: meta ?? {},
|
|
11490
11536
|
});
|
|
11537
|
+
// Run the onOpen and onClose callbacks
|
|
11491
11538
|
if (open)
|
|
11492
11539
|
onOpenRef.current?.();
|
|
11493
11540
|
else
|
|
11494
11541
|
onCloseRef.current?.();
|
|
11495
|
-
},
|
|
11542
|
+
},
|
|
11543
|
+
// We don't have good caching on paymentState, so don't include it as a dep
|
|
11544
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
11545
|
+
[trpc, daimoPayOrder?.id, modalOptions?.resetOnSuccess, paymentCompleted]);
|
|
11546
|
+
// Callback when a payment is successfully completed (regardless of whether
|
|
11547
|
+
// the final call succeeded or bounced)
|
|
11548
|
+
const onSuccess = useCallback(() => {
|
|
11549
|
+
if (modalOptions?.closeOnSuccess) {
|
|
11550
|
+
setTimeout(() => setOpen(false, { event: "wait-success" }), 1000);
|
|
11551
|
+
}
|
|
11552
|
+
setPaymentCompleted(true);
|
|
11553
|
+
}, [modalOptions?.closeOnSuccess, setOpen, setPaymentCompleted]);
|
|
11496
11554
|
const setRoute = useCallback((route, data) => {
|
|
11497
11555
|
const action = route.replace("daimoPay", "");
|
|
11498
11556
|
log(`[SET ROUTE] ${action} ${daimoPayOrder?.id} ${debugJson(data ?? {})}`);
|
|
@@ -11503,23 +11561,11 @@ const DaimoPayProviderWithoutSolana = ({ children, theme = "auto", mode = "auto"
|
|
|
11503
11561
|
});
|
|
11504
11562
|
setRouteState(route);
|
|
11505
11563
|
}, [trpc, daimoPayOrder?.id, log]);
|
|
11506
|
-
// Include Google Font that is needed for a themes
|
|
11507
|
-
if (opts.embedGoogleFonts)
|
|
11508
|
-
useThemeFont(ckTheme);
|
|
11509
11564
|
// Other Configuration
|
|
11510
11565
|
useEffect(() => setTheme(theme), [theme]);
|
|
11511
11566
|
useEffect(() => setLang(opts.language || "en-US"), [opts.language]);
|
|
11512
11567
|
useEffect(() => setErrorMessage(null), [route, open]);
|
|
11513
|
-
|
|
11514
|
-
const { chain, isConnected, connector } = useAccount();
|
|
11515
|
-
const isChainSupported = useChainIsSupported(chain?.id);
|
|
11516
|
-
useEffect(() => {
|
|
11517
|
-
if (isConnected && opts.enforceSupportedChains && !isChainSupported) {
|
|
11518
|
-
setOpen(true);
|
|
11519
|
-
if (route !== ROUTES.SWITCHNETWORKS)
|
|
11520
|
-
setRoute(ROUTES.SWITCHNETWORKS);
|
|
11521
|
-
}
|
|
11522
|
-
}, [isConnected, isChainSupported, chain, route, open]);
|
|
11568
|
+
const { connector } = useAccount();
|
|
11523
11569
|
// Single source of truth for the currently-connected wallet is the connector
|
|
11524
11570
|
// exposed by wagmi. See useAccount(). We watch this connector and use it to
|
|
11525
11571
|
// extract the current WalletConnect wallet, if any.
|
|
@@ -11530,6 +11576,10 @@ const DaimoPayProviderWithoutSolana = ({ children, theme = "auto", mode = "auto"
|
|
|
11530
11576
|
// set refresh context when payment status changes; done via setDaimoPayOrder.
|
|
11531
11577
|
const setDaimoPayOrder = useCallback((order) => {
|
|
11532
11578
|
setDaimoPayOrderInner(order);
|
|
11579
|
+
if (order == null) {
|
|
11580
|
+
log(`[PAY] setDaimoPayOrder: reset`);
|
|
11581
|
+
return;
|
|
11582
|
+
}
|
|
11533
11583
|
let extra = `> $${order.destFinalCallTokenAmount.usd.toFixed(2)} to ${order.destFinalCallTokenAmount.token.chainId} ${order.destFinalCall.to}`;
|
|
11534
11584
|
if (order.mode === DaimoPayOrderMode.HYDRATED) {
|
|
11535
11585
|
extra += ` via ${order.intentAddr} ${order.sourceStatus} ${order.intentStatus}`;
|
|
@@ -11538,9 +11588,10 @@ const DaimoPayProviderWithoutSolana = ({ children, theme = "auto", mode = "auto"
|
|
|
11538
11588
|
}, [log]);
|
|
11539
11589
|
const paymentState = usePaymentState({
|
|
11540
11590
|
trpc,
|
|
11591
|
+
lockPayParams,
|
|
11541
11592
|
daimoPayOrder,
|
|
11542
11593
|
setDaimoPayOrder,
|
|
11543
|
-
|
|
11594
|
+
setRoute,
|
|
11544
11595
|
log,
|
|
11545
11596
|
redirectReturnUrl,
|
|
11546
11597
|
});
|
|
@@ -11564,11 +11615,13 @@ const DaimoPayProviderWithoutSolana = ({ children, theme = "auto", mode = "auto"
|
|
|
11564
11615
|
log(`[PAY] polling in ${intervalMs}ms`);
|
|
11565
11616
|
const timeout = setTimeout(() => retryBackoff("refreshOrder", () => paymentState.refreshOrder()), intervalMs);
|
|
11566
11617
|
return () => clearTimeout(timeout);
|
|
11567
|
-
|
|
11618
|
+
// We don't have good caching on paymentState, so don't include it as a dep
|
|
11619
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
11620
|
+
}, [daimoPayOrder, log]);
|
|
11568
11621
|
const showPayment = async (modalOptions) => {
|
|
11569
11622
|
const id = daimoPayOrder?.id;
|
|
11570
11623
|
log(`[PAY] showing payment ${debugJson({ id, modalOptions })}`);
|
|
11571
|
-
|
|
11624
|
+
setModalOptions(modalOptions);
|
|
11572
11625
|
setOpen(true);
|
|
11573
11626
|
if (daimoPayOrder &&
|
|
11574
11627
|
daimoPayOrder.mode === DaimoPayOrderMode.HYDRATED &&
|
|
@@ -11608,6 +11661,7 @@ const DaimoPayProviderWithoutSolana = ({ children, theme = "auto", mode = "auto"
|
|
|
11608
11661
|
// Other configuration
|
|
11609
11662
|
options: opts,
|
|
11610
11663
|
errorMessage,
|
|
11664
|
+
onSuccess,
|
|
11611
11665
|
confirmationMessage,
|
|
11612
11666
|
setConfirmationMessage,
|
|
11613
11667
|
redirectReturnUrl,
|
|
@@ -11891,6 +11945,7 @@ function DaimoPayButtonCustom(props) {
|
|
|
11891
11945
|
else if (payParams != null) {
|
|
11892
11946
|
paymentState.setPayParams(payParams);
|
|
11893
11947
|
}
|
|
11948
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
11894
11949
|
}, [payId, JSON.stringify(payParams || {})]);
|
|
11895
11950
|
// Set the confirmation message
|
|
11896
11951
|
const { setConfirmationMessage } = context;
|
|
@@ -11922,30 +11977,32 @@ function DaimoPayButtonCustom(props) {
|
|
|
11922
11977
|
const intentStatus = order?.intentStatus;
|
|
11923
11978
|
const hydOrder = order?.mode === DaimoPayOrderMode.HYDRATED ? order : null;
|
|
11924
11979
|
// Functions to show and hide the modal
|
|
11925
|
-
const { children, closeOnSuccess } = props;
|
|
11926
|
-
const
|
|
11927
|
-
const show = () => {
|
|
11980
|
+
const { children, closeOnSuccess, resetOnSuccess } = props;
|
|
11981
|
+
const show = useCallback(() => {
|
|
11928
11982
|
if (paymentState.daimoPayOrder == null)
|
|
11929
11983
|
return;
|
|
11984
|
+
const modalOptions = { closeOnSuccess, resetOnSuccess };
|
|
11930
11985
|
context.showPayment(modalOptions);
|
|
11931
|
-
};
|
|
11932
|
-
const hide = () => context.setOpen(false);
|
|
11986
|
+
}, [context, paymentState.daimoPayOrder, closeOnSuccess, resetOnSuccess]);
|
|
11987
|
+
const hide = useCallback(() => context.setOpen(false), [context]);
|
|
11933
11988
|
// Emit event handlers when payment status changes
|
|
11989
|
+
const sentStart = useRef(false);
|
|
11934
11990
|
useEffect(() => {
|
|
11935
11991
|
if (hydOrder == null)
|
|
11936
11992
|
return;
|
|
11937
11993
|
if (intentStatus === DaimoPayIntentStatus.UNPAID)
|
|
11938
11994
|
return;
|
|
11939
|
-
if (
|
|
11995
|
+
if (!sentStart.current && hydOrder.sourceTokenAmount) {
|
|
11996
|
+
sentStart.current = true;
|
|
11940
11997
|
onPaymentStarted?.({
|
|
11941
11998
|
type: DaimoPayIntentStatus.STARTED,
|
|
11942
11999
|
paymentId: writeDaimoPayOrderID(hydOrder.id),
|
|
11943
|
-
chainId: hydOrder.
|
|
11944
|
-
txHash:
|
|
12000
|
+
chainId: hydOrder.sourceTokenAmount?.token.chainId,
|
|
12001
|
+
txHash: hydOrder.sourceInitiateTxHash ?? null,
|
|
11945
12002
|
payment: getDaimoPayOrderView(hydOrder),
|
|
11946
12003
|
});
|
|
11947
12004
|
}
|
|
11948
|
-
|
|
12005
|
+
if (intentStatus === DaimoPayIntentStatus.COMPLETED ||
|
|
11949
12006
|
intentStatus === DaimoPayIntentStatus.BOUNCED) {
|
|
11950
12007
|
const event = {
|
|
11951
12008
|
type: intentStatus,
|
|
@@ -11961,7 +12018,7 @@ function DaimoPayButtonCustom(props) {
|
|
|
11961
12018
|
onPaymentBounced?.(event);
|
|
11962
12019
|
}
|
|
11963
12020
|
}
|
|
11964
|
-
}, [hydOrder?.id, intentStatus]);
|
|
12021
|
+
}, [hydOrder?.id, intentStatus, hydOrder?.sourceTokenAmount?.token.chainId]);
|
|
11965
12022
|
// Open the modal by default if the defaultOpen prop is true
|
|
11966
12023
|
useEffect(() => {
|
|
11967
12024
|
if (props.defaultOpen && order != null) {
|