@openfort/react 1.2.0 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/assets/logos.d.ts +3 -0
- package/build/assets/logos.js +2 -0
- package/build/assets/logos.js.map +1 -1
- package/build/components/Common/Modal/styles.js +3 -0
- package/build/components/Common/Modal/styles.js.map +1 -1
- package/build/components/Common/ScrollArea/index.d.ts +5 -1
- package/build/components/Common/ScrollArea/index.js +2 -2
- package/build/components/Common/ScrollArea/styles.d.ts +4 -1
- package/build/components/Common/ScrollArea/styles.js +19 -4
- package/build/components/Common/ScrollArea/styles.js.map +1 -1
- package/build/components/Common/SolanaChain/index.d.ts +8 -0
- package/build/components/Common/SolanaChain/index.js +40 -0
- package/build/components/Common/SolanaChain/index.js.map +1 -0
- package/build/components/ConnectModal/index.js +17 -5
- package/build/components/ConnectModal/index.js.map +1 -1
- package/build/components/Openfort/types.d.ts +17 -11
- package/build/components/Openfort/types.js +1 -0
- package/build/components/Openfort/types.js.map +1 -1
- package/build/components/PageContent/index.d.ts +2 -1
- package/build/components/PageContent/index.js +2 -2
- package/build/components/Pages/Buy/coinbaseApi.d.ts +1 -1
- package/build/components/Pages/Buy/coinbaseApi.js +2 -13
- package/build/components/Pages/Buy/coinbaseApi.js.map +1 -1
- package/build/components/Pages/Buy/evmCurrencies.d.ts +11 -0
- package/build/components/Pages/Buy/evmCurrencies.js +27 -0
- package/build/components/Pages/Buy/evmCurrencies.js.map +1 -0
- package/build/components/Pages/Buy/index.js +8 -1
- package/build/components/Pages/Buy/index.js.map +1 -1
- package/build/components/Pages/Buy/onrampApi.d.ts +8 -1
- package/build/components/Pages/Buy/onrampApi.js +24 -14
- package/build/components/Pages/Buy/onrampApi.js.map +1 -1
- package/build/components/Pages/Buy/solanaCurrencies.d.ts +9 -0
- package/build/components/Pages/Buy/solanaCurrencies.js +25 -0
- package/build/components/Pages/Buy/solanaCurrencies.js.map +1 -0
- package/build/components/Pages/Buy/stripeApi.d.ts +1 -1
- package/build/components/Pages/Buy/stripeApi.js +2 -13
- package/build/components/Pages/Buy/stripeApi.js.map +1 -1
- package/build/components/Pages/BuyComplete/index.js +7 -1
- package/build/components/Pages/BuyComplete/index.js.map +1 -1
- package/build/components/Pages/BuyProcessing/index.js +9 -5
- package/build/components/Pages/BuyProcessing/index.js.map +1 -1
- package/build/components/Pages/BuyProviderSelect/styles.d.ts +2 -1
- package/build/components/Pages/BuySelectProvider/index.js +10 -5
- package/build/components/Pages/BuySelectProvider/index.js.map +1 -1
- package/build/components/Pages/Connected/EthereumConnected.js +7 -3
- package/build/components/Pages/Connected/EthereumConnected.js.map +1 -1
- package/build/components/Pages/Connected/SolanaConnected.js +3 -2
- package/build/components/Pages/Connected/SolanaConnected.js.map +1 -1
- package/build/components/Pages/Deposit/AssetChainLogo.d.ts +5 -2
- package/build/components/Pages/Deposit/AssetChainLogo.js +21 -4
- package/build/components/Pages/Deposit/AssetChainLogo.js.map +1 -1
- package/build/components/Pages/Deposit/DepositAddressBlock.js +1 -1
- package/build/components/Pages/Deposit/DepositProgress.js +3 -2
- package/build/components/Pages/Deposit/DepositProgress.js.map +1 -1
- package/build/components/Pages/Deposit/DepositSuccess.js +2 -1
- package/build/components/Pages/Deposit/DepositSuccess.js.map +1 -1
- package/build/components/Pages/Deposit/RouteSelectors.js +11 -1
- package/build/components/Pages/Deposit/RouteSelectors.js.map +1 -1
- package/build/components/Pages/Deposit/SameChainDepositStatus.d.ts +7 -0
- package/build/components/Pages/Deposit/SameChainDepositStatus.js +34 -0
- package/build/components/Pages/Deposit/SameChainDepositStatus.js.map +1 -0
- package/build/components/Pages/Deposit/SameChainDepositSuccess.d.ts +11 -0
- package/build/components/Pages/Deposit/SameChainDepositSuccess.js +30 -0
- package/build/components/Pages/Deposit/SameChainDepositSuccess.js.map +1 -0
- package/build/components/Pages/Deposit/TestnetNotice.d.ts +10 -0
- package/build/components/Pages/Deposit/TestnetNotice.js +131 -0
- package/build/components/Pages/Deposit/TestnetNotice.js.map +1 -0
- package/build/components/Pages/Deposit/UnsupportedNetworkNotice.d.ts +12 -0
- package/build/components/Pages/Deposit/UnsupportedNetworkNotice.js +111 -0
- package/build/components/Pages/Deposit/UnsupportedNetworkNotice.js.map +1 -0
- package/build/components/Pages/Deposit/index.js +35 -5
- package/build/components/Pages/Deposit/index.js.map +1 -1
- package/build/components/Pages/Deposit/paymentOptions.d.ts +6 -0
- package/build/components/Pages/Deposit/paymentOptions.js +10 -4
- package/build/components/Pages/Deposit/paymentOptions.js.map +1 -1
- package/build/components/Pages/Deposit/useDepositRoute.d.ts +2 -1
- package/build/components/Pages/Deposit/useDepositRoute.js +36 -13
- package/build/components/Pages/Deposit/useDepositRoute.js.map +1 -1
- package/build/components/Pages/Deposit/useFundingTarget.d.ts +2 -4
- package/build/components/Pages/Deposit/useFundingTarget.js +3 -5
- package/build/components/Pages/Deposit/useFundingTarget.js.map +1 -1
- package/build/components/Pages/Deposit/useSameChainArrival.d.ts +19 -0
- package/build/components/Pages/Deposit/useSameChainArrival.js +86 -0
- package/build/components/Pages/Deposit/useSameChainArrival.js.map +1 -0
- package/build/components/Pages/DepositCex/index.js +7 -8
- package/build/components/Pages/DepositCex/index.js.map +1 -1
- package/build/components/Pages/DepositCrypto/index.js +26 -3
- package/build/components/Pages/DepositCrypto/index.js.map +1 -1
- package/build/components/Pages/DepositWallet/DepositWalletDesktop.d.ts +4 -1
- package/build/components/Pages/DepositWallet/DepositWalletDesktop.js +19 -27
- package/build/components/Pages/DepositWallet/DepositWalletDesktop.js.map +1 -1
- package/build/components/Pages/DepositWallet/index.d.ts +5 -5
- package/build/components/Pages/DepositWallet/index.js +82 -39
- package/build/components/Pages/DepositWallet/index.js.map +1 -1
- package/build/components/Pages/DepositWallet/walletDeeplinks.d.ts +6 -4
- package/build/components/Pages/DepositWallet/walletDeeplinks.js +3 -1
- package/build/components/Pages/DepositWallet/walletDeeplinks.js.map +1 -1
- package/build/components/Pages/SelectToken/SolanaSelectToken.d.ts +1 -0
- package/build/components/Pages/SelectToken/SolanaSelectToken.js +50 -0
- package/build/components/Pages/SelectToken/SolanaSelectToken.js.map +1 -0
- package/build/components/Pages/SelectToken/index.js +13 -2
- package/build/components/Pages/SelectToken/index.js.map +1 -1
- package/build/components/Pages/SelectToken/styles.d.ts +2 -1
- package/build/components/Pages/Send/SolanaSend.js +32 -31
- package/build/components/Pages/Send/SolanaSend.js.map +1 -1
- package/build/components/Pages/Send/utils.js +4 -1
- package/build/components/Pages/Send/utils.js.map +1 -1
- package/build/components/Pages/SendConfirmation/SolanaSendConfirmation.js +57 -13
- package/build/components/Pages/SendConfirmation/SolanaSendConfirmation.js.map +1 -1
- package/build/components/Pages/SendConfirmation/index.js +1 -1
- package/build/components/Pages/SendConfirmation/styles.d.ts +0 -5
- package/build/components/Pages/SendConfirmation/styles.js +1 -39
- package/build/components/Pages/SendConfirmation/styles.js.map +1 -1
- package/build/constants/chainConfigs.js +32 -32
- package/build/constants/logos.d.ts +4 -0
- package/build/constants/logos.js +25 -1
- package/build/constants/logos.js.map +1 -1
- package/build/ethereum/hooks/useEthereumWalletAssets.js +39 -3
- package/build/ethereum/hooks/useEthereumWalletAssets.js.map +1 -1
- package/build/hooks/openfort/useFunding.js +7 -7
- package/build/hooks/openfort/useFundingChains.d.ts +6 -0
- package/build/hooks/openfort/useFundingChains.js +22 -10
- package/build/hooks/openfort/useFundingChains.js.map +1 -1
- package/build/shared/hooks/useAsyncData.js +15 -2
- package/build/shared/hooks/useAsyncData.js.map +1 -1
- package/build/shared/utils/explorer.js +6 -4
- package/build/shared/utils/explorer.js.map +1 -1
- package/build/solana/transfer.d.ts +35 -6
- package/build/solana/transfer.js +112 -18
- package/build/solana/transfer.js.map +1 -1
- package/build/solana/types.d.ts +8 -0
- package/build/utils/validation.d.ts +9 -0
- package/build/utils/validation.js +14 -1
- package/build/utils/validation.js.map +1 -1
- package/build/version.d.ts +1 -1
- package/build/version.js +1 -1
- package/build/wagmi/components/ChainSelect/index.js +3 -2
- package/build/wagmi/components/ChainSelect/index.js.map +1 -1
- package/build/wagmi/components/ChainSelectList/index.js +3 -2
- package/build/wagmi/components/ChainSelectList/index.js.map +1 -1
- package/build/wagmi/components/SwitchNetworks/index.js +3 -2
- package/build/wagmi/components/SwitchNetworks/index.js.map +1 -1
- package/build/wagmi/useSwitchChainFiltered.d.ts +199 -0
- package/build/wagmi/useSwitchChainFiltered.js +53 -0
- package/build/wagmi/useSwitchChainFiltered.js.map +1 -0
- package/package.json +5 -1
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { useState, useRef, useEffect } from 'react';
|
|
2
|
+
import { createPublicClient, http } from 'viem';
|
|
3
|
+
import { invalidateBalance } from '../../../hooks/useBalance.js';
|
|
4
|
+
import { getDefaultEthereumRpcUrl } from '../../../utils/rpc.js';
|
|
5
|
+
import { useOpenfort } from '../../Openfort/useOpenfort.js';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Backoff schedule (ms) for the waiting poll: brisk at first, easing off so a
|
|
9
|
+
* long wait doesn't hammer the RPC. The last entry is the steady-state cap.
|
|
10
|
+
*/
|
|
11
|
+
const POLL_BACKOFF_MS = [2000, 2000, 3000, 5000, 8000, 12000, 20000];
|
|
12
|
+
/**
|
|
13
|
+
* Watches a wallet's native balance and reports when it increases past the first
|
|
14
|
+
* observed value — i.e. a same-chain deposit landed. Same-chain "transfer from
|
|
15
|
+
* address" has no rail session to poll (the deposit address is the wallet
|
|
16
|
+
* itself), so arrival is read straight from the chain RPC.
|
|
17
|
+
*
|
|
18
|
+
* Self-contained single timeout chain (no shared query cache), so it can't fan
|
|
19
|
+
* out into a request storm: one read in flight at a time, with an interval that
|
|
20
|
+
* grows on each tick and resets to brisk when the user returns to the tab (the
|
|
21
|
+
* moment a deposit was likely just made). On arrival, cached balances are
|
|
22
|
+
* invalidated so the asset list refreshes, and polling stops.
|
|
23
|
+
*/
|
|
24
|
+
function useSameChainArrival({ address, chainId, enabled, }) {
|
|
25
|
+
var _a, _b, _c;
|
|
26
|
+
const { walletConfig } = useOpenfort();
|
|
27
|
+
const rpcUrl = (_c = (_b = (_a = walletConfig === null || walletConfig === void 0 ? void 0 : walletConfig.ethereum) === null || _a === void 0 ? void 0 : _a.rpcUrls) === null || _b === void 0 ? void 0 : _b[chainId]) !== null && _c !== void 0 ? _c : getDefaultEthereumRpcUrl(chainId);
|
|
28
|
+
const [arrived, setArrived] = useState(false);
|
|
29
|
+
const baselineRef = useRef(null);
|
|
30
|
+
useEffect(() => {
|
|
31
|
+
if (!enabled || !address)
|
|
32
|
+
return;
|
|
33
|
+
const client = createPublicClient({ transport: http(rpcUrl) });
|
|
34
|
+
let cancelled = false;
|
|
35
|
+
let timer = null;
|
|
36
|
+
let step = 0;
|
|
37
|
+
baselineRef.current = null;
|
|
38
|
+
const read = async () => {
|
|
39
|
+
try {
|
|
40
|
+
const balance = await client.getBalance({ address: address });
|
|
41
|
+
if (cancelled)
|
|
42
|
+
return;
|
|
43
|
+
if (baselineRef.current === null) {
|
|
44
|
+
baselineRef.current = balance;
|
|
45
|
+
}
|
|
46
|
+
else if (balance > baselineRef.current) {
|
|
47
|
+
setArrived(true);
|
|
48
|
+
invalidateBalance();
|
|
49
|
+
return; // deposit landed — stop polling
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
// transient RPC error — keep polling on the same schedule
|
|
54
|
+
}
|
|
55
|
+
if (cancelled)
|
|
56
|
+
return;
|
|
57
|
+
const delay = POLL_BACKOFF_MS[Math.min(step, POLL_BACKOFF_MS.length - 1)];
|
|
58
|
+
step += 1;
|
|
59
|
+
timer = setTimeout(read, delay);
|
|
60
|
+
};
|
|
61
|
+
// Re-check immediately when the user returns to the tab (deposit likely just
|
|
62
|
+
// made), and reset the schedule back to brisk.
|
|
63
|
+
const onReturn = () => {
|
|
64
|
+
if (cancelled || document.visibilityState !== 'visible')
|
|
65
|
+
return;
|
|
66
|
+
if (timer)
|
|
67
|
+
clearTimeout(timer);
|
|
68
|
+
step = 0;
|
|
69
|
+
read();
|
|
70
|
+
};
|
|
71
|
+
read();
|
|
72
|
+
document.addEventListener('visibilitychange', onReturn);
|
|
73
|
+
window.addEventListener('focus', onReturn);
|
|
74
|
+
return () => {
|
|
75
|
+
cancelled = true;
|
|
76
|
+
if (timer)
|
|
77
|
+
clearTimeout(timer);
|
|
78
|
+
document.removeEventListener('visibilitychange', onReturn);
|
|
79
|
+
window.removeEventListener('focus', onReturn);
|
|
80
|
+
};
|
|
81
|
+
}, [enabled, address, chainId, rpcUrl]);
|
|
82
|
+
return { arrived };
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export { useSameChainArrival };
|
|
86
|
+
//# sourceMappingURL=useSameChainArrival.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useSameChainArrival.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -17,7 +17,7 @@ import { isCexDeliverable, CEX_CHAIN_NAMES } from '../Deposit/cexChains.js';
|
|
|
17
17
|
import { isDepositFlowActive, DepositProgress } from '../Deposit/DepositProgress.js';
|
|
18
18
|
import { DepositStatus } from '../Deposit/DepositStatus.js';
|
|
19
19
|
import { walletListBtn } from '../Deposit/formStyles.js';
|
|
20
|
-
import { DEST_USDC } from '../Deposit/sources.js';
|
|
20
|
+
import { isSolana, DEST_USDC } from '../Deposit/sources.js';
|
|
21
21
|
import { StepDivider, ButtonLogo } from '../Deposit/styles.js';
|
|
22
22
|
import { useFundingTarget } from '../Deposit/useFundingTarget.js';
|
|
23
23
|
import { sanitizeForParsing, sanitizeAmountInput } from '../Send/utils.js';
|
|
@@ -55,7 +55,7 @@ const hideBrokenLogo = (e) => {
|
|
|
55
55
|
* success / failed screen. No Relay routing; Binance is gated until its rail lands.
|
|
56
56
|
*/
|
|
57
57
|
const DepositCex = () => {
|
|
58
|
-
var _a, _b, _c, _d, _e, _f
|
|
58
|
+
var _a, _b, _c, _d, _e, _f;
|
|
59
59
|
const { triggerResize } = useOpenfort();
|
|
60
60
|
const target = useFundingTarget();
|
|
61
61
|
// CEX (Coinbase pay-link + session) is served by the Openfort API, not the
|
|
@@ -73,20 +73,19 @@ const DepositCex = () => {
|
|
|
73
73
|
// wallet, Solana targets the Solana (SVM) embedded account — never cross families
|
|
74
74
|
// (an EVM address on a Solana target would be rejected / mis-delivered). Accounts
|
|
75
75
|
// come from the core store so EVM-only apps don't need the Solana React context.
|
|
76
|
-
const isEvmTarget = target.chain.startsWith('eip155:');
|
|
77
76
|
const solanaAddress = (_a = embeddedAccounts === null || embeddedAccounts === void 0 ? void 0 : embeddedAccounts.find((acc) => acc.chainType === ChainTypeEnum.SVM)) === null || _a === void 0 ? void 0 : _a.address;
|
|
78
|
-
const address = (
|
|
77
|
+
const address = isSolana(target.chain) ? solanaAddress : wallet.address;
|
|
79
78
|
const chainSupported = isCexDeliverable(target.chain);
|
|
80
79
|
// Resolve the destination asset + chain for the "Arrives as …" line. The live
|
|
81
80
|
// chain list is curated for source selection, so the destination may be absent;
|
|
82
81
|
// only claim a symbol we resolved, or USDC for the zero-config default.
|
|
83
82
|
const destChain = chains.find((c) => c.id === target.chain);
|
|
84
|
-
const destChainName = (
|
|
83
|
+
const destChainName = (_c = (_b = destChain === null || destChain === void 0 ? void 0 : destChain.name) !== null && _b !== void 0 ? _b : CEX_CHAIN_NAMES[target.chain]) !== null && _c !== void 0 ? _c : target.chain;
|
|
85
84
|
const destAsset = destChain === null || destChain === void 0 ? void 0 : destChain.currencies.find((c) => c.address.toLowerCase() === target.currency.toLowerCase());
|
|
86
85
|
const isDefaultUsdc = target.currency.toLowerCase() === DEST_USDC.toLowerCase();
|
|
87
|
-
const destAssetLabel = (
|
|
88
|
-
const destAssetLogo = (
|
|
89
|
-
const destChainLogo = (
|
|
86
|
+
const destAssetLabel = (_d = destAsset === null || destAsset === void 0 ? void 0 : destAsset.symbol) !== null && _d !== void 0 ? _d : (isDefaultUsdc ? 'USDC' : null);
|
|
87
|
+
const destAssetLogo = (_e = destAsset === null || destAsset === void 0 ? void 0 : destAsset.logo) !== null && _e !== void 0 ? _e : null;
|
|
88
|
+
const destChainLogo = (_f = destChain === null || destChain === void 0 ? void 0 : destChain.logo) !== null && _f !== void 0 ? _f : null;
|
|
90
89
|
// Mint the destination-bound session up-front (per target wallet), so the click
|
|
91
90
|
// that opens Coinbase is a single fast pay-link call and stays popup-safe.
|
|
92
91
|
//
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
1
|
+
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
2
2
|
import { useEffect } from 'react';
|
|
3
|
+
import { currencyLogoUrl, chainLogoUrl } from '../../../constants/logos.js';
|
|
3
4
|
import { ModalHeading, ModalBody } from '../../Common/Modal/styles.js';
|
|
4
5
|
import { routes } from '../../Openfort/types.js';
|
|
5
6
|
import { useOpenfort } from '../../Openfort/useOpenfort.js';
|
|
@@ -7,7 +8,14 @@ import { PageContent } from '../../PageContent/index.js';
|
|
|
7
8
|
import { DepositAddressBlock } from '../Deposit/DepositAddressBlock.js';
|
|
8
9
|
import { isDepositFlowActive, DepositProgress } from '../Deposit/DepositProgress.js';
|
|
9
10
|
import { RouteSelectors } from '../Deposit/RouteSelectors.js';
|
|
11
|
+
import { SameChainDepositStatus } from '../Deposit/SameChainDepositStatus.js';
|
|
12
|
+
import { SameChainDepositSuccess } from '../Deposit/SameChainDepositSuccess.js';
|
|
13
|
+
import { isSolana } from '../Deposit/sources.js';
|
|
14
|
+
import { TestnetNotice } from '../Deposit/TestnetNotice.js';
|
|
15
|
+
import { UnsupportedNetworkNotice } from '../Deposit/UnsupportedNetworkNotice.js';
|
|
10
16
|
import { useDepositRoute } from '../Deposit/useDepositRoute.js';
|
|
17
|
+
import { useSameChainArrival } from '../Deposit/useSameChainArrival.js';
|
|
18
|
+
import { caipToChainId } from '../DepositWallet/walletDeeplinks.js';
|
|
11
19
|
|
|
12
20
|
/**
|
|
13
21
|
* Transfer from address — choose a source chain + token and send to the deposit
|
|
@@ -16,15 +24,30 @@ import { useDepositRoute } from '../Deposit/useDepositRoute.js';
|
|
|
16
24
|
* "Transfer from wallet" tab.
|
|
17
25
|
*/
|
|
18
26
|
const DepositCrypto = () => {
|
|
19
|
-
var _a, _b, _c, _d;
|
|
27
|
+
var _a, _b, _c, _d, _e;
|
|
20
28
|
const { triggerResize } = useOpenfort();
|
|
21
29
|
const route = useDepositRoute('crypto');
|
|
22
30
|
useEffect(() => {
|
|
23
31
|
triggerResize();
|
|
24
32
|
}, [route.receiverAddress, route.loading, route.status, triggerResize]);
|
|
33
|
+
// Same-chain "transfer from address" lands in the wallet itself, so there's no
|
|
34
|
+
// rail session — watch the native balance directly and swap to the success
|
|
35
|
+
// screen once the deposit arrives.
|
|
36
|
+
const sameChainEnabled = route.sameChain && !!route.receiverAddress && !isSolana(route.target.chain);
|
|
37
|
+
const sameChainAddress = (_a = route.receiverAddress) !== null && _a !== void 0 ? _a : '';
|
|
38
|
+
const sameChainId = Number(route.target.chain.split(':')[1]);
|
|
39
|
+
const { arrived } = useSameChainArrival({
|
|
40
|
+
address: sameChainAddress,
|
|
41
|
+
chainId: sameChainId,
|
|
42
|
+
enabled: sameChainEnabled,
|
|
43
|
+
});
|
|
25
44
|
if (isDepositFlowActive(route.status))
|
|
26
45
|
return jsx(DepositProgress, { status: route.status });
|
|
27
|
-
|
|
46
|
+
if (sameChainEnabled && arrived)
|
|
47
|
+
return jsx(SameChainDepositSuccess, { address: sameChainAddress, chainId: sameChainId });
|
|
48
|
+
return (jsxs(PageContent, { onBack: routes.DEPOSIT, children: [jsx(ModalHeading, { children: "Transfer from address" }), jsx(TestnetNotice, {}), route.targetUnsupported ? (jsx(UnsupportedNetworkNotice, { targetChain: route.target.chain, railChains: route.railChains })) : (jsxs(Fragment, { children: [jsx(RouteSelectors, { chains: route.chains, chain: route.chain, currency: route.currency, chainLabel: "Supported chain", onChainChange: route.setChain, onCurrencyChange: route.setCurrency }), !route.isAvailable && jsx(ModalBody, { children: "Funding isn't available right now." }), jsx(DepositAddressBlock, { assetLogo: currencyLogoUrl((_b = route.activeCurrency) === null || _b === void 0 ? void 0 : _b.symbol, (_c = route.activeCurrency) === null || _c === void 0 ? void 0 : _c.logo), chainLogo: chainLogoUrl(caipToChainId((_d = route.activeChain) === null || _d === void 0 ? void 0 : _d.id), (_e = route.activeChain) === null || _e === void 0 ? void 0 : _e.logo), receiverAddress: route.receiverAddress, pm: route.pm, sourceCurrency: route.activeCurrency
|
|
49
|
+
? { symbol: route.activeCurrency.symbol, decimals: route.activeCurrency.decimals }
|
|
50
|
+
: null, sameChain: route.sameChain, loading: route.loading, status: route.status }), sameChainEnabled && jsx(SameChainDepositStatus, {}), route.error && jsx(ModalBody, { style: { color: '#dc2626', marginTop: 12 }, children: route.error.message })] }))] }));
|
|
28
51
|
};
|
|
29
52
|
|
|
30
53
|
export { DepositCrypto as default };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -5,6 +5,9 @@ type Props = {
|
|
|
5
5
|
activeChain: FundingChain | undefined;
|
|
6
6
|
activeCurrency: FundingCurrency | undefined;
|
|
7
7
|
loading: boolean;
|
|
8
|
+
/** Amount to send, in the source token's units. Owned by the parent so the
|
|
9
|
+
* amount input + presets are shared with the mobile (deeplink) path. */
|
|
10
|
+
amount: string;
|
|
8
11
|
};
|
|
9
12
|
/**
|
|
10
13
|
* Desktop "transfer from wallet": send the source token to the Relay deposit
|
|
@@ -13,5 +16,5 @@ type Props = {
|
|
|
13
16
|
* Openfort embedded account (that one is the destination, not the source).
|
|
14
17
|
* Once the deposit lands, the funding session's status polling drives progress.
|
|
15
18
|
*/
|
|
16
|
-
export declare function DepositWalletDesktop({ receiverAddress, activeChain, activeCurrency, loading }: Props): import("react/jsx-runtime").JSX.Element | null;
|
|
19
|
+
export declare function DepositWalletDesktop({ receiverAddress, activeChain, activeCurrency, loading, amount }: Props): import("react/jsx-runtime").JSX.Element | null;
|
|
17
20
|
export {};
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
2
|
-
import { useState } from 'react';
|
|
2
|
+
import { useState, useEffect } from 'react';
|
|
3
3
|
import { parseUnits, formatUnits, encodeFunctionData, erc20Abi } from 'viem';
|
|
4
4
|
import { WalletIcon } from '../../../assets/icons.js';
|
|
5
5
|
import Logos from '../../../assets/logos.js';
|
|
6
6
|
import { useEthereumBridge } from '../../../ethereum/OpenfortEthereumBridgeContext.js';
|
|
7
7
|
import { ModalBody } from '../../Common/Modal/styles.js';
|
|
8
|
+
import { ScrollArea } from '../../Common/ScrollArea/index.js';
|
|
9
|
+
import { useOpenfort } from '../../Openfort/useOpenfort.js';
|
|
8
10
|
import { DepositStatus } from '../Deposit/DepositStatus.js';
|
|
9
11
|
import { walletListBtn } from '../Deposit/formStyles.js';
|
|
10
12
|
import { ButtonLogo } from '../Deposit/styles.js';
|
|
@@ -39,22 +41,6 @@ function walletErrorMessage(e) {
|
|
|
39
41
|
}
|
|
40
42
|
return typeof e === 'string' ? e : 'Transaction failed';
|
|
41
43
|
}
|
|
42
|
-
/** Keep only digits and a single decimal point. */
|
|
43
|
-
function sanitizeAmount(v) {
|
|
44
|
-
const cleaned = v.replace(/[^0-9.]/g, '');
|
|
45
|
-
const [whole, ...rest] = cleaned.split('.');
|
|
46
|
-
return rest.length ? `${whole}.${rest.join('')}` : cleaned;
|
|
47
|
-
}
|
|
48
|
-
const inputStyle = {
|
|
49
|
-
width: '100%',
|
|
50
|
-
padding: '12px 14px',
|
|
51
|
-
borderRadius: 12,
|
|
52
|
-
border: '1px solid var(--ck-body-divider, #e4e4e7)',
|
|
53
|
-
background: 'var(--ck-body-background-secondary, #fafafa)',
|
|
54
|
-
color: 'var(--ck-body-color, #111)',
|
|
55
|
-
fontSize: 16,
|
|
56
|
-
outline: 'none',
|
|
57
|
-
};
|
|
58
44
|
/**
|
|
59
45
|
* Desktop "transfer from wallet": send the source token to the Relay deposit
|
|
60
46
|
* address straight from the user's EXTERNAL browser-extension wallet
|
|
@@ -62,12 +48,18 @@ const inputStyle = {
|
|
|
62
48
|
* Openfort embedded account (that one is the destination, not the source).
|
|
63
49
|
* Once the deposit lands, the funding session's status polling drives progress.
|
|
64
50
|
*/
|
|
65
|
-
function DepositWalletDesktop({ receiverAddress, activeChain, activeCurrency, loading }) {
|
|
51
|
+
function DepositWalletDesktop({ receiverAddress, activeChain, activeCurrency, loading, amount }) {
|
|
66
52
|
const bridge = useEthereumBridge();
|
|
67
|
-
const
|
|
53
|
+
const { triggerResize } = useOpenfort();
|
|
68
54
|
const [busyId, setBusyId] = useState(null);
|
|
69
55
|
const [error, setError] = useState(null);
|
|
70
56
|
const [sent, setSent] = useState(false);
|
|
57
|
+
// Grow the modal when the busy / error / sent feedback toggles, so the "Confirm
|
|
58
|
+
// in your wallet…" and insufficient-balance messages are revealed instead of
|
|
59
|
+
// clipped below the fold (which reads as "nothing happened" after a click).
|
|
60
|
+
useEffect(() => {
|
|
61
|
+
triggerResize();
|
|
62
|
+
}, [busyId, error, sent, triggerResize]);
|
|
71
63
|
if (!bridge)
|
|
72
64
|
return null; // EVM-only (no wagmi) — nothing to send through
|
|
73
65
|
// bridge.connectors already excludes the Openfort embedded connector, so these
|
|
@@ -134,14 +126,14 @@ function DepositWalletDesktop({ receiverAddress, activeChain, activeCurrency, lo
|
|
|
134
126
|
setBusyId(null);
|
|
135
127
|
}
|
|
136
128
|
};
|
|
137
|
-
return (jsxs("div", { style: { display: 'flex', flexDirection: 'column', gap: 10,
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
129
|
+
return (jsxs("div", { style: { display: 'flex', flexDirection: 'column', gap: 10, flex: '1 1 auto', minHeight: 0 }, children: [connectors.length === 0 && jsx(ModalBody, { children: "No browser wallet detected. Install MetaMask or Rabby." }), connectors.length > 0 && (jsx(ScrollArea, { fill: true, children: jsx("div", { style: { display: 'flex', flexDirection: 'column', gap: 10 }, children: connectors.map((c) => (jsxs("button", { type: "button", disabled: !amountValid || busyId !== null || loading, style: {
|
|
130
|
+
...walletListBtn,
|
|
131
|
+
display: 'flex',
|
|
132
|
+
alignItems: 'center',
|
|
133
|
+
justifyContent: 'flex-start',
|
|
134
|
+
gap: 10,
|
|
135
|
+
opacity: !amountValid || busyId !== null ? 0.55 : 1,
|
|
136
|
+
}, onClick: () => sendVia(c), children: [jsx(ButtonLogo, { children: brandLogo(c) }), jsx("span", { children: busyId === c.id ? 'Confirm in your wallet…' : `Send via ${c.name}` })] }, c.id))) }) })), sent && jsx(DepositStatus, { status: "waiting_payment" }), error && jsx(ModalBody, { style: { color: '#dc2626' }, children: error })] }));
|
|
145
137
|
}
|
|
146
138
|
|
|
147
139
|
export { DepositWalletDesktop };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DepositWalletDesktop.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"DepositWalletDesktop.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Transfer from wallet.
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* from
|
|
6
|
-
*
|
|
2
|
+
* Transfer from wallet. Pick a source chain/token and an amount, then choose the
|
|
3
|
+
* wallet to send from. On mobile that's open-dApp deeplinks into the wallet app's
|
|
4
|
+
* in-app browser (address/chain/token/amount prefilled); on desktop it's a direct
|
|
5
|
+
* send from a browser-extension wallet. The manual deposit-address / QR path stays
|
|
6
|
+
* available below.
|
|
7
7
|
*/
|
|
8
8
|
declare const DepositWallet: () => import("react/jsx-runtime").JSX.Element;
|
|
9
9
|
export default DepositWallet;
|
|
@@ -2,21 +2,56 @@ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
|
2
2
|
import { useState, useEffect } from 'react';
|
|
3
3
|
import { parseUnits } from 'viem';
|
|
4
4
|
import Logos from '../../../assets/logos.js';
|
|
5
|
+
import { useEthereumBridge } from '../../../ethereum/OpenfortEthereumBridgeContext.js';
|
|
5
6
|
import useIsMobile from '../../../hooks/useIsMobile.js';
|
|
7
|
+
import styled from '../../../styles/styled/index.js';
|
|
6
8
|
import { isIOS } from '../../../utils/index.js';
|
|
7
9
|
import { ModalHeading, ModalBody } from '../../Common/Modal/styles.js';
|
|
10
|
+
import { ScrollArea } from '../../Common/ScrollArea/index.js';
|
|
8
11
|
import { routes } from '../../Openfort/types.js';
|
|
9
12
|
import { useOpenfort } from '../../Openfort/useOpenfort.js';
|
|
10
13
|
import { PageContent } from '../../PageContent/index.js';
|
|
14
|
+
import { Section, SectionLabel, AmountCard, CurrencySymbol, AmountInput, PresetList, PresetButton } from '../Buy/styles.js';
|
|
11
15
|
import { AddressPageLink } from '../Deposit/AddressPageLink.js';
|
|
12
16
|
import { isDepositFlowActive, DepositProgress } from '../Deposit/DepositProgress.js';
|
|
13
17
|
import { walletListBtn } from '../Deposit/formStyles.js';
|
|
14
18
|
import { RouteSelectors } from '../Deposit/RouteSelectors.js';
|
|
19
|
+
import { isSolana } from '../Deposit/sources.js';
|
|
15
20
|
import { StepDivider, Skeleton, ButtonLogo } from '../Deposit/styles.js';
|
|
21
|
+
import { TestnetNotice } from '../Deposit/TestnetNotice.js';
|
|
22
|
+
import { UnsupportedNetworkNotice } from '../Deposit/UnsupportedNetworkNotice.js';
|
|
16
23
|
import { useDepositRoute } from '../Deposit/useDepositRoute.js';
|
|
24
|
+
import { sanitizeAmountInput } from '../Send/utils.js';
|
|
17
25
|
import { DepositWalletDesktop } from './DepositWalletDesktop.js';
|
|
18
26
|
import { OPENFORT_DEPOSIT_PAGE_URL, caipToChainId, buildDepositPageUrl, buildOpenDappLinks } from './walletDeeplinks.js';
|
|
19
27
|
|
|
28
|
+
// Flex column capped at the modal viewport so the page never overflows
|
|
29
|
+
// InnerContainer (which caps at 88vh and would otherwise scroll the footer off
|
|
30
|
+
// screen). The 112px accounts for the chrome wrapping this element inside the
|
|
31
|
+
// measured PageContents: PageContentStyle's 48px top padding + PageContents'
|
|
32
|
+
// 29px/24px padding (~101px), plus a small safety margin. The providers region
|
|
33
|
+
// is the only part that shrinks/scrolls, which keeps the footer visible.
|
|
34
|
+
const Layout = styled.div `
|
|
35
|
+
display: flex;
|
|
36
|
+
flex-direction: column;
|
|
37
|
+
min-height: 0;
|
|
38
|
+
max-height: calc(88vh - 112px);
|
|
39
|
+
`;
|
|
40
|
+
const TopFixed = styled.div `
|
|
41
|
+
flex-shrink: 0;
|
|
42
|
+
`;
|
|
43
|
+
// Grows to fill the space between the fixed top and footer; its ScrollArea
|
|
44
|
+
// scrolls internally when the wallet list is taller than the available room.
|
|
45
|
+
const ProvidersRegion = styled.div `
|
|
46
|
+
display: flex;
|
|
47
|
+
flex-direction: column;
|
|
48
|
+
flex: 1 1 auto;
|
|
49
|
+
min-height: 0;
|
|
50
|
+
margin-top: 14px;
|
|
51
|
+
`;
|
|
52
|
+
const FixedFooter = styled.div `
|
|
53
|
+
flex-shrink: 0;
|
|
54
|
+
`;
|
|
20
55
|
/** Wallet-app brand logos keyed by the deeplink `app` id. */
|
|
21
56
|
const WALLET_LOGO = {
|
|
22
57
|
metamask: jsx(Logos.MetaMask, { background: true }),
|
|
@@ -26,58 +61,66 @@ const WALLET_LOGO = {
|
|
|
26
61
|
rainbow: jsx(Logos.Rainbow, { round: true }),
|
|
27
62
|
rabby: jsx(Logos.Rabby, {}),
|
|
28
63
|
};
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
padding: '12px 14px',
|
|
32
|
-
borderRadius: 12,
|
|
33
|
-
border: '1px solid var(--ck-body-divider, #e4e4e7)',
|
|
34
|
-
background: 'var(--ck-body-background-secondary, #fafafa)',
|
|
35
|
-
color: 'var(--ck-body-color, #111)',
|
|
36
|
-
fontSize: 16,
|
|
37
|
-
outline: 'none',
|
|
38
|
-
marginTop: 14,
|
|
39
|
-
};
|
|
40
|
-
/** Keep only digits and a single decimal point. */
|
|
41
|
-
function sanitizeAmount(v) {
|
|
42
|
-
const cleaned = v.replace(/[^0-9.]/g, '');
|
|
43
|
-
const [whole, ...rest] = cleaned.split('.');
|
|
44
|
-
return rest.length ? `${whole}.${rest.join('')}` : cleaned;
|
|
45
|
-
}
|
|
64
|
+
/** Preset deposit amounts, in the selected source token's units. */
|
|
65
|
+
const PRESETS = [10, 25, 50];
|
|
46
66
|
/**
|
|
47
|
-
* Transfer from wallet.
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
* from
|
|
51
|
-
*
|
|
67
|
+
* Transfer from wallet. Pick a source chain/token and an amount, then choose the
|
|
68
|
+
* wallet to send from. On mobile that's open-dApp deeplinks into the wallet app's
|
|
69
|
+
* in-app browser (address/chain/token/amount prefilled); on desktop it's a direct
|
|
70
|
+
* send from a browser-extension wallet. The manual deposit-address / QR path stays
|
|
71
|
+
* available below.
|
|
52
72
|
*/
|
|
53
73
|
const DepositWallet = () => {
|
|
54
|
-
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
74
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
|
|
55
75
|
const { triggerResize, uiConfig } = useOpenfort();
|
|
56
76
|
const isMobile = useIsMobile();
|
|
57
77
|
const route = useDepositRoute('crypto');
|
|
58
|
-
|
|
78
|
+
// The desktop send path goes through the wagmi bridge (browser-extension wallets).
|
|
79
|
+
// In Solana-only mode there's no wagmi provider, so fall back to the open-dApp
|
|
80
|
+
// deeplinks for EVM sources too — otherwise the wallet list renders empty.
|
|
81
|
+
const bridge = useEthereumBridge();
|
|
82
|
+
// Prefill a sensible default so the wallet deeplinks are immediately actionable
|
|
83
|
+
// (the funding deposit-address mint uses a fixed nominal amount regardless).
|
|
84
|
+
const [amount, setAmount] = useState('1');
|
|
85
|
+
const [pressedPreset, setPressedPreset] = useState(null);
|
|
59
86
|
const depositPageUrl = (_b = (_a = uiConfig.funding) === null || _a === void 0 ? void 0 : _a.depositPageUrl) !== null && _b !== void 0 ? _b : OPENFORT_DEPOSIT_PAGE_URL;
|
|
60
|
-
|
|
87
|
+
// Solana sources have no numeric chain id and no desktop EVM-extension send, so
|
|
88
|
+
// they route through the deeplink (Phantom) on every platform instead of the
|
|
89
|
+
// wagmi-bridge desktop path.
|
|
90
|
+
const isSolanaSrc = isSolana((_d = (_c = route.activeChain) === null || _c === void 0 ? void 0 : _c.id) !== null && _d !== void 0 ? _d : '');
|
|
91
|
+
const srcChainId = caipToChainId((_e = route.activeChain) === null || _e === void 0 ? void 0 : _e.id);
|
|
61
92
|
const amountValid = Number.parseFloat(amount) > 0;
|
|
93
|
+
const handleAmountChange = (event) => {
|
|
94
|
+
const raw = sanitizeAmountInput(event.target.value);
|
|
95
|
+
if (raw === '' || /^[0-9]*\.?[0-9]*$/.test(raw)) {
|
|
96
|
+
setPressedPreset(null);
|
|
97
|
+
setAmount(raw);
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
const handlePreset = (value) => {
|
|
101
|
+
setPressedPreset(value);
|
|
102
|
+
setAmount(String(value));
|
|
103
|
+
};
|
|
62
104
|
// Open-dApp deeplinks: prefer backend-provided ones; otherwise build them from
|
|
63
105
|
// the hosted deposit page URL (if the integrator configured one) carrying the
|
|
64
106
|
// resolved transfer params. The hosted page sends via the wallet's injected
|
|
65
107
|
// provider, so no backend wiring is required for the link itself.
|
|
66
|
-
const pageUrl = depositPageUrl && route.receiverAddress && route.activeCurrency && srcChainId
|
|
108
|
+
const pageUrl = depositPageUrl && route.receiverAddress && route.activeCurrency && (isSolanaSrc || srcChainId)
|
|
67
109
|
? buildDepositPageUrl(depositPageUrl, {
|
|
110
|
+
vm: isSolanaSrc ? 'svm' : 'evm',
|
|
68
111
|
to: route.receiverAddress,
|
|
69
|
-
chainId: srcChainId,
|
|
112
|
+
chainId: isSolanaSrc ? undefined : srcChainId,
|
|
70
113
|
token: route.activeCurrency.native ? undefined : route.activeCurrency.address,
|
|
71
114
|
decimals: route.activeCurrency.decimals,
|
|
72
115
|
symbol: route.activeCurrency.symbol,
|
|
73
|
-
chain: (
|
|
116
|
+
chain: (_f = route.activeChain) === null || _f === void 0 ? void 0 : _f.name,
|
|
74
117
|
amount: amountValid ? parseUnits(amount, route.activeCurrency.decimals).toString() : undefined,
|
|
75
118
|
})
|
|
76
119
|
: null;
|
|
77
|
-
const allDeeplinks = ((
|
|
120
|
+
const allDeeplinks = ((_h = (_g = route.pm) === null || _g === void 0 ? void 0 : _g.deeplinks) === null || _h === void 0 ? void 0 : _h.length)
|
|
78
121
|
? route.pm.deeplinks
|
|
79
122
|
: pageUrl
|
|
80
|
-
? buildOpenDappLinks(pageUrl, (
|
|
123
|
+
? buildOpenDappLinks(pageUrl, (_k = (_j = route.activeChain) === null || _j === void 0 ? void 0 : _j.vmType) !== null && _k !== void 0 ? _k : 'evm')
|
|
81
124
|
: [];
|
|
82
125
|
// Trust's in-app dApp browser was removed on iOS (Apple, 2021) — the link
|
|
83
126
|
// dead-ends there, so hide it on iOS while keeping it on Android.
|
|
@@ -87,15 +130,15 @@ const DepositWallet = () => {
|
|
|
87
130
|
}, [route.receiverAddress, route.loading, route.status, deeplinks.length, triggerResize]);
|
|
88
131
|
if (isDepositFlowActive(route.status))
|
|
89
132
|
return jsx(DepositProgress, { status: route.status });
|
|
90
|
-
return (jsxs(PageContent, { onBack: routes.DEPOSIT, children: [jsx(ModalHeading, { children: "Transfer from wallet" }), jsx(RouteSelectors, { chains: route.chains, chain: route.chain, currency: route.currency, chainLabel: "Supported chain", onChainChange: route.setChain, onCurrencyChange: route.setCurrency }), !route.isAvailable && jsx(ModalBody, { children: "Funding isn't available right now." }), jsx(
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
133
|
+
return (jsxs(PageContent, { onBack: routes.DEPOSIT, children: [jsx(ModalHeading, { children: "Transfer from wallet" }), jsx(TestnetNotice, {}), route.targetUnsupported && (jsx(UnsupportedNetworkNotice, { targetChain: route.target.chain, railChains: route.railChains })), !route.targetUnsupported && (jsxs(Layout, { children: [jsxs(TopFixed, { children: [jsx(RouteSelectors, { chains: route.chains, chain: route.chain, currency: route.currency, chainLabel: "Supported chain", onChainChange: route.setChain, onCurrencyChange: route.setCurrency }), !route.isAvailable && jsx(ModalBody, { children: "Funding isn't available right now." }), jsxs(Section, { children: [jsx(SectionLabel, { children: "Amount" }), jsxs(AmountCard, { children: [jsx(CurrencySymbol, { children: (_m = (_l = route.activeCurrency) === null || _l === void 0 ? void 0 : _l.symbol) !== null && _m !== void 0 ? _m : '' }), jsx(AmountInput, { value: amount, onChange: handleAmountChange, placeholder: "0.00", inputMode: "decimal", autoComplete: "off" })] }), jsx(PresetList, { children: PRESETS.map((preset) => (jsx(PresetButton, { type: "button", "$active": pressedPreset === preset, onClick: () => handlePreset(preset), children: preset }, preset))) })] }), jsx(StepDivider, { children: "Then select the wallet you want to use" })] }), jsx(ProvidersRegion, { children: isMobile || isSolanaSrc || !bridge ? (jsxs(Fragment, { children: [!depositPageUrl && (jsx(ModalBody, { style: { marginTop: 12 }, children: "Use a deposit address below to fund from your wallet." })), route.loading && !route.pm && (jsxs("div", { style: { display: 'flex', flexDirection: 'column', gap: 8 }, children: [jsx(Skeleton, { "$h": "44px", "$r": "10px" }), jsx(Skeleton, { "$h": "44px", "$r": "10px" }), jsx(Skeleton, { "$h": "44px", "$r": "10px" })] })), deeplinks.length > 0 && (jsx(ScrollArea, { fill: true, children: jsx("div", { style: { display: 'flex', flexDirection: 'column', gap: 8 }, children: deeplinks.map((d) => (jsxs("a", { href: amountValid ? d.url : undefined, "aria-disabled": !amountValid, target: "_blank", rel: "noreferrer", style: {
|
|
134
|
+
...walletListBtn,
|
|
135
|
+
display: 'flex',
|
|
136
|
+
alignItems: 'center',
|
|
137
|
+
justifyContent: 'center',
|
|
138
|
+
gap: 8,
|
|
139
|
+
opacity: amountValid ? 1 : 0.55,
|
|
140
|
+
pointerEvents: amountValid ? 'auto' : 'none',
|
|
141
|
+
}, children: [WALLET_LOGO[d.app] && jsx(ButtonLogo, { children: WALLET_LOGO[d.app] }), d.label, " \u2197"] }, d.app))) }) }))] })) : (jsx(DepositWalletDesktop, { receiverAddress: route.receiverAddress, activeChain: route.activeChain, activeCurrency: route.activeCurrency, loading: route.loading, amount: amount })) }), jsxs(FixedFooter, { children: [jsx(AddressPageLink, { label: "Or send to a deposit address" }), route.error && jsx(ModalBody, { style: { color: '#dc2626', marginTop: 12 }, children: route.error.message })] })] }))] }));
|
|
99
142
|
};
|
|
100
143
|
|
|
101
144
|
export { DepositWallet as default };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -23,11 +23,13 @@ export type VmType = 'evm' | 'svm';
|
|
|
23
23
|
*/
|
|
24
24
|
export declare const OPENFORT_DEPOSIT_PAGE_URL = "https://deposit.openfort.io";
|
|
25
25
|
type DepositPageParams = {
|
|
26
|
-
/**
|
|
26
|
+
/** Source VM family. `evm` drives a window.ethereum send; `svm` a Solana Pay request. */
|
|
27
|
+
vm: VmType;
|
|
28
|
+
/** Relay deposit address the source funds go to (0x for EVM, base58 for Solana). */
|
|
27
29
|
to: string;
|
|
28
|
-
/** Numeric source chain id (e.g. 42161). */
|
|
29
|
-
chainId
|
|
30
|
-
/** ERC-20 contract, or empty/undefined for the chain's native token. */
|
|
30
|
+
/** Numeric source chain id (e.g. 42161). EVM only. */
|
|
31
|
+
chainId?: number;
|
|
32
|
+
/** ERC-20 contract / SPL mint, or empty/undefined for the chain's native token. */
|
|
31
33
|
token?: string;
|
|
32
34
|
decimals: number;
|
|
33
35
|
symbol: string;
|
|
@@ -19,8 +19,10 @@ const OPENFORT_DEPOSIT_PAGE_URL = 'https://deposit.openfort.io';
|
|
|
19
19
|
/** Build the deposit "send" page URL with the transfer params encoded. */
|
|
20
20
|
function buildDepositPageUrl(baseUrl, p) {
|
|
21
21
|
const url = new URL(baseUrl);
|
|
22
|
+
url.searchParams.set('vm', p.vm);
|
|
22
23
|
url.searchParams.set('to', p.to);
|
|
23
|
-
|
|
24
|
+
if (p.vm === 'evm' && p.chainId !== undefined)
|
|
25
|
+
url.searchParams.set('chainId', String(p.chainId));
|
|
24
26
|
if (p.token)
|
|
25
27
|
url.searchParams.set('token', p.token);
|
|
26
28
|
url.searchParams.set('decimals', String(p.decimals));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"walletDeeplinks.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"walletDeeplinks.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const SolanaSelectToken: () => import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { useEffect, useState } from 'react';
|
|
3
|
+
import { formatUnits } from 'viem';
|
|
4
|
+
import { TOKEN_LOGO, symbolToColor } from '../../../constants/logos.js';
|
|
5
|
+
import { useSolanaWalletAssets } from '../../../solana/hooks/useSolanaWalletAssets.js';
|
|
6
|
+
import { ModalHeading } from '../../Common/Modal/styles.js';
|
|
7
|
+
import { routes } from '../../Openfort/types.js';
|
|
8
|
+
import { useOpenfort } from '../../Openfort/useOpenfort.js';
|
|
9
|
+
import { SelectTokenContent, EmptyState, TokenList, TokenButton, TokenLeftGroup, TokenInfo, TokenSymbol, TokenName, TokenBalance, TokenLogoArea, TokenLogoImg, TokenLogoFallback } from './styles.js';
|
|
10
|
+
|
|
11
|
+
const ZERO = BigInt(0);
|
|
12
|
+
function SolanaTokenLogo({ symbol }) {
|
|
13
|
+
var _a;
|
|
14
|
+
const [imgError, setImgError] = useState(false);
|
|
15
|
+
const url = (_a = TOKEN_LOGO[symbol.toUpperCase()]) !== null && _a !== void 0 ? _a : null;
|
|
16
|
+
return (jsx(TokenLogoArea, { children: url && !imgError ? (jsx(TokenLogoImg, { src: url, alt: symbol, onError: () => setImgError(true) })) : (jsx(TokenLogoFallback, { "$bg": symbolToColor(symbol), children: symbol.charAt(0).toUpperCase() })) }));
|
|
17
|
+
}
|
|
18
|
+
const SolanaSelectToken = () => {
|
|
19
|
+
const { setSendForm, setRoute, triggerResize } = useOpenfort();
|
|
20
|
+
const { data, isLoading } = useSolanaWalletAssets();
|
|
21
|
+
const tokens = (data !== null && data !== void 0 ? data : []).filter((t) => t.amount > ZERO);
|
|
22
|
+
useEffect(() => {
|
|
23
|
+
if (!isLoading)
|
|
24
|
+
triggerResize();
|
|
25
|
+
}, [isLoading, triggerResize]);
|
|
26
|
+
const handleSelect = (token) => {
|
|
27
|
+
const asset = token.isNative
|
|
28
|
+
? {
|
|
29
|
+
type: 'native',
|
|
30
|
+
balance: token.amount,
|
|
31
|
+
metadata: { symbol: 'SOL', decimals: token.decimals, fiat: { value: 0, currency: 'USD' } },
|
|
32
|
+
}
|
|
33
|
+
: {
|
|
34
|
+
type: 'spl',
|
|
35
|
+
address: token.mint,
|
|
36
|
+
balance: token.amount,
|
|
37
|
+
metadata: { symbol: token.symbol, name: token.name, decimals: token.decimals },
|
|
38
|
+
};
|
|
39
|
+
setSendForm((prev) => ({ ...prev, asset, amount: '' }));
|
|
40
|
+
setRoute(routes.SOL_SEND);
|
|
41
|
+
};
|
|
42
|
+
return (jsxs(SelectTokenContent, { onBack: routes.SOL_SEND, children: [jsx(ModalHeading, { children: "Select asset" }), tokens.length === 0 ? (jsx(EmptyState, { children: isLoading ? 'Loading balances…' : 'No assets found' })) : (jsx(TokenList, { children: tokens.map((token) => {
|
|
43
|
+
const amount = Number(formatUnits(token.amount, token.decimals));
|
|
44
|
+
const balanceStr = `${amount.toLocaleString('en-US', { maximumFractionDigits: 4 })} ${token.symbol}`;
|
|
45
|
+
return (jsxs(TokenButton, { type: "button", onClick: () => handleSelect(token), children: [jsxs(TokenLeftGroup, { children: [jsx(SolanaTokenLogo, { symbol: token.symbol }), jsxs(TokenInfo, { style: { textAlign: 'left' }, children: [jsx(TokenSymbol, { children: token.name }), jsx(TokenName, { children: token.symbol })] })] }), jsx(TokenBalance, { children: balanceStr })] }, token.mint));
|
|
46
|
+
}) }))] }));
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
export { SolanaSelectToken };
|
|
50
|
+
//# sourceMappingURL=SolanaSelectToken.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SolanaSelectToken.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|