@openfort/react 1.1.3 → 1.2.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/icons.js +1 -1
- package/build/assets/logos.d.ts +12 -0
- package/build/assets/logos.js +7 -0
- package/build/assets/logos.js.map +1 -1
- package/build/components/Common/CopyToClipboard/CopyIconButton.d.ts +3 -1
- package/build/components/Common/CopyToClipboard/CopyIconButton.js +4 -4
- package/build/components/Common/CustomQRCode/index.d.ts +1 -1
- package/build/components/Common/CustomQRCode/index.js +3 -3
- package/build/components/Common/CustomQRCode/styles.d.ts +1 -0
- package/build/components/Common/CustomQRCode/styles.js +4 -4
- package/build/components/Common/CustomQRCode/types.d.ts +2 -0
- package/build/components/Common/Modal/styles.js +4 -1
- package/build/components/Common/Modal/styles.js.map +1 -1
- package/build/components/ConnectModal/index.js +14 -2
- package/build/components/ConnectModal/index.js.map +1 -1
- package/build/components/Openfort/OpenfortProvider.js +4 -1
- package/build/components/Openfort/OpenfortProvider.js.map +1 -1
- package/build/components/Openfort/types.d.ts +86 -0
- package/build/components/Openfort/types.js +22 -1
- package/build/components/Openfort/types.js.map +1 -1
- package/build/components/Pages/AssetInventory/SolanaAssetInventory.d.ts +6 -0
- package/build/components/Pages/AssetInventory/SolanaAssetInventory.js +42 -0
- package/build/components/Pages/AssetInventory/SolanaAssetInventory.js.map +1 -0
- package/build/components/Pages/Buy/index.js +3 -2
- package/build/components/Pages/Buy/index.js.map +1 -1
- package/build/components/Pages/BuySelectProvider/index.js +1 -1
- package/build/components/Pages/Connected/EthereumConnected.js +8 -32
- package/build/components/Pages/Connected/EthereumConnected.js.map +1 -1
- package/build/components/Pages/Connected/SolanaConnected.js +9 -4
- package/build/components/Pages/Connected/SolanaConnected.js.map +1 -1
- package/build/components/Pages/Deposit/AddressPageLink.d.ts +7 -0
- package/build/components/Pages/Deposit/AddressPageLink.js +17 -0
- package/build/components/Pages/Deposit/AddressPageLink.js.map +1 -0
- package/build/components/Pages/Deposit/AssetChainLogo.d.ts +9 -0
- package/build/components/Pages/Deposit/AssetChainLogo.js +24 -0
- package/build/components/Pages/Deposit/AssetChainLogo.js.map +1 -0
- package/build/components/Pages/Deposit/DepositAddressBlock.d.ts +21 -0
- package/build/components/Pages/Deposit/DepositAddressBlock.js +28 -0
- package/build/components/Pages/Deposit/DepositAddressBlock.js.map +1 -0
- package/build/components/Pages/Deposit/DepositProgress.d.ts +15 -0
- package/build/components/Pages/Deposit/DepositProgress.js +110 -0
- package/build/components/Pages/Deposit/DepositProgress.js.map +1 -0
- package/build/components/Pages/Deposit/DepositStatus.d.ts +9 -0
- package/build/components/Pages/Deposit/DepositStatus.js +43 -0
- package/build/components/Pages/Deposit/DepositStatus.js.map +1 -0
- package/build/components/Pages/Deposit/DepositSuccess.d.ts +6 -0
- package/build/components/Pages/Deposit/DepositSuccess.js +24 -0
- package/build/components/Pages/Deposit/DepositSuccess.js.map +1 -0
- package/build/components/Pages/Deposit/Details.d.ts +12 -0
- package/build/components/Pages/Deposit/Details.js +40 -0
- package/build/components/Pages/Deposit/Details.js.map +1 -0
- package/build/components/Pages/Deposit/LogoSelect.d.ts +12 -0
- package/build/components/Pages/Deposit/LogoSelect.js +95 -0
- package/build/components/Pages/Deposit/LogoSelect.js.map +1 -0
- package/build/components/Pages/Deposit/OrDivider.d.ts +2 -0
- package/build/components/Pages/Deposit/OrDivider.js +10 -0
- package/build/components/Pages/Deposit/OrDivider.js.map +1 -0
- package/build/components/Pages/Deposit/RouteSelectors.d.ts +13 -0
- package/build/components/Pages/Deposit/RouteSelectors.js +19 -0
- package/build/components/Pages/Deposit/RouteSelectors.js.map +1 -0
- package/build/components/Pages/Deposit/cexChains.d.ts +9 -0
- package/build/components/Pages/Deposit/cexChains.js +23 -0
- package/build/components/Pages/Deposit/cexChains.js.map +1 -0
- package/build/components/Pages/Deposit/formStyles.d.ts +24 -0
- package/build/components/Pages/Deposit/formStyles.js +83 -0
- package/build/components/Pages/Deposit/formStyles.js.map +1 -0
- package/build/components/Pages/Deposit/index.d.ts +7 -0
- package/build/components/Pages/Deposit/index.js +100 -0
- package/build/components/Pages/Deposit/index.js.map +1 -0
- package/build/components/Pages/Deposit/paymentOptions.d.ts +49 -0
- package/build/components/Pages/Deposit/paymentOptions.js +63 -0
- package/build/components/Pages/Deposit/paymentOptions.js.map +1 -0
- package/build/components/Pages/Deposit/sources.d.ts +17 -0
- package/build/components/Pages/Deposit/sources.js +22 -0
- package/build/components/Pages/Deposit/sources.js.map +1 -0
- package/build/components/Pages/Deposit/styles.d.ts +25 -0
- package/build/components/Pages/Deposit/styles.js +167 -0
- package/build/components/Pages/Deposit/styles.js.map +1 -0
- package/build/components/Pages/Deposit/useDepositRoute.d.ts +35 -0
- package/build/components/Pages/Deposit/useDepositRoute.js +107 -0
- package/build/components/Pages/Deposit/useDepositRoute.js.map +1 -0
- package/build/components/Pages/Deposit/useFundingTarget.d.ts +13 -0
- package/build/components/Pages/Deposit/useFundingTarget.js +27 -0
- package/build/components/Pages/Deposit/useFundingTarget.js.map +1 -0
- package/build/components/Pages/DepositCex/index.d.ts +11 -0
- package/build/components/Pages/DepositCex/index.js +230 -0
- package/build/components/Pages/DepositCex/index.js.map +1 -0
- package/build/components/Pages/DepositCrypto/index.d.ts +8 -0
- package/build/components/Pages/DepositCrypto/index.js +31 -0
- package/build/components/Pages/DepositCrypto/index.js.map +1 -0
- package/build/components/Pages/DepositWallet/DepositWalletDesktop.d.ts +17 -0
- package/build/components/Pages/DepositWallet/DepositWalletDesktop.js +148 -0
- package/build/components/Pages/DepositWallet/DepositWalletDesktop.js.map +1 -0
- package/build/components/Pages/DepositWallet/index.d.ts +9 -0
- package/build/components/Pages/DepositWallet/index.js +102 -0
- package/build/components/Pages/DepositWallet/index.js.map +1 -0
- package/build/components/Pages/DepositWallet/walletDeeplinks.d.ts +48 -0
- package/build/components/Pages/DepositWallet/walletDeeplinks.js +107 -0
- package/build/components/Pages/DepositWallet/walletDeeplinks.js.map +1 -0
- package/build/components/Pages/ExportKey/index.js +10 -2
- package/build/components/Pages/ExportKey/index.js.map +1 -1
- package/build/components/Pages/NoAssetsAvailable/index.js +5 -21
- package/build/components/Pages/NoAssetsAvailable/index.js.map +1 -1
- package/build/components/Pages/SelectToken/styles.js +1 -1
- package/build/components/Pages/Send/SolanaSend.d.ts +1 -0
- package/build/components/Pages/Send/SolanaSend.js +88 -0
- package/build/components/Pages/Send/SolanaSend.js.map +1 -0
- package/build/components/Pages/Send/index.d.ts +2 -1
- package/build/components/Pages/Send/index.js +0 -1
- package/build/components/Pages/Send/index.js.map +1 -1
- package/build/components/Pages/SendConfirmation/EstimatedFees.js +5 -3
- package/build/components/Pages/SendConfirmation/EstimatedFees.js.map +1 -1
- package/build/components/Pages/SendConfirmation/SolanaSendConfirmation.d.ts +1 -0
- package/build/components/Pages/SendConfirmation/SolanaSendConfirmation.js +77 -0
- package/build/components/Pages/SendConfirmation/SolanaSendConfirmation.js.map +1 -0
- package/build/components/Pages/SendConfirmation/index.js +4 -3
- package/build/components/Pages/SendConfirmation/index.js.map +1 -1
- package/build/components/Pages/SendConfirmation/styles.d.ts +5 -0
- package/build/components/Pages/SendConfirmation/styles.js +39 -1
- package/build/components/Pages/SendConfirmation/styles.js.map +1 -1
- package/build/constants/logos.js +1 -0
- package/build/constants/logos.js.map +1 -1
- package/build/ethereum/hooks/useEthereumWalletAssets.js +212 -95
- package/build/ethereum/hooks/useEthereumWalletAssets.js.map +1 -1
- package/build/hooks/openfort/fundingClient.d.ts +34 -0
- package/build/hooks/openfort/fundingClient.js +60 -0
- package/build/hooks/openfort/fundingClient.js.map +1 -0
- package/build/hooks/openfort/useFunding.d.ts +159 -0
- package/build/hooks/openfort/useFunding.js +204 -0
- package/build/hooks/openfort/useFunding.js.map +1 -0
- package/build/hooks/openfort/useFundingChains.d.ts +49 -0
- package/build/hooks/openfort/useFundingChains.js +102 -0
- package/build/hooks/openfort/useFundingChains.js.map +1 -0
- package/build/hooks/useBalance.js +6 -1
- package/build/hooks/useBalance.js.map +1 -1
- package/build/index.d.ts +4 -1
- package/build/index.js +2 -1
- package/build/index.js.map +1 -1
- package/build/shared/hooks/useAsyncData.d.ts +11 -0
- package/build/shared/hooks/useAsyncData.js +60 -13
- package/build/shared/hooks/useAsyncData.js.map +1 -1
- package/build/solana/hooks/useSolanaWalletAssets.d.ts +24 -0
- package/build/solana/hooks/useSolanaWalletAssets.js +86 -0
- package/build/solana/hooks/useSolanaWalletAssets.js.map +1 -0
- package/build/solana/transfer.d.ts +32 -0
- package/build/solana/transfer.js +125 -0
- package/build/solana/transfer.js.map +1 -0
- package/build/utils/index.d.ts +2 -1
- package/build/utils/index.js +1 -1
- package/build/version.d.ts +1 -1
- package/build/version.js +1 -1
- package/build/wagmi/defaultConnectors.js +5 -1
- package/build/wagmi/defaultConnectors.js.map +1 -1
- package/package.json +10 -2
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import { keyframes } from 'styled-components';
|
|
2
|
+
import styled from '../../../styles/styled/index.js';
|
|
3
|
+
|
|
4
|
+
/** Sizes to the content so short method lists don't leave a cut-looking gap. */
|
|
5
|
+
const DepositContent = styled.div `
|
|
6
|
+
display: flex;
|
|
7
|
+
flex-direction: column;
|
|
8
|
+
`;
|
|
9
|
+
const pulse = keyframes `
|
|
10
|
+
0%, 100% { opacity: 1; }
|
|
11
|
+
50% { opacity: 0.45; }
|
|
12
|
+
`;
|
|
13
|
+
/** Separates the chain/currency step (above) from the action buttons (below). */
|
|
14
|
+
const StepDivider = styled.div `
|
|
15
|
+
margin-top: 20px;
|
|
16
|
+
padding-top: 14px;
|
|
17
|
+
border-top: 1px solid var(--ck-body-divider, #ededed);
|
|
18
|
+
font-size: 11px;
|
|
19
|
+
font-weight: 600;
|
|
20
|
+
text-transform: uppercase;
|
|
21
|
+
letter-spacing: 0.4px;
|
|
22
|
+
color: var(--ck-body-color-muted, #6b7280);
|
|
23
|
+
`;
|
|
24
|
+
/** Sizes a brand logo (svg/img) to 20px for use inside wallet/exchange buttons. */
|
|
25
|
+
const ButtonLogo = styled.span `
|
|
26
|
+
display: inline-flex;
|
|
27
|
+
align-items: center;
|
|
28
|
+
justify-content: center;
|
|
29
|
+
flex-shrink: 0;
|
|
30
|
+
|
|
31
|
+
svg,
|
|
32
|
+
img {
|
|
33
|
+
width: 20px;
|
|
34
|
+
height: 20px;
|
|
35
|
+
border-radius: 50%;
|
|
36
|
+
}
|
|
37
|
+
`;
|
|
38
|
+
/** Loading placeholder block. */
|
|
39
|
+
const Skeleton = styled.div `
|
|
40
|
+
width: ${(p) => { var _a; return (_a = p.$w) !== null && _a !== void 0 ? _a : '100%'; }};
|
|
41
|
+
height: ${(p) => { var _a; return (_a = p.$h) !== null && _a !== void 0 ? _a : '16px'; }};
|
|
42
|
+
border-radius: ${(p) => { var _a; return (_a = p.$r) !== null && _a !== void 0 ? _a : '8px'; }};
|
|
43
|
+
background: var(--ck-body-divider, #ededed);
|
|
44
|
+
animation: ${pulse} 1.4s ease-in-out infinite;
|
|
45
|
+
`;
|
|
46
|
+
const OptionList = styled.div `
|
|
47
|
+
display: flex;
|
|
48
|
+
flex-direction: column;
|
|
49
|
+
gap: 8px;
|
|
50
|
+
margin-top: 12px;
|
|
51
|
+
`;
|
|
52
|
+
const OptionButton = styled.button `
|
|
53
|
+
display: flex;
|
|
54
|
+
align-items: center;
|
|
55
|
+
justify-content: space-between;
|
|
56
|
+
width: 100%;
|
|
57
|
+
min-height: 52px;
|
|
58
|
+
box-sizing: border-box;
|
|
59
|
+
padding: 10px 14px;
|
|
60
|
+
border-radius: var(--ck-secondary-button-border-radius);
|
|
61
|
+
border: 1px solid var(--ck-body-divider);
|
|
62
|
+
background: var(--ck-secondary-button-background);
|
|
63
|
+
color: var(--ck-body-color);
|
|
64
|
+
cursor: pointer;
|
|
65
|
+
transition: background 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;
|
|
66
|
+
text-align: left;
|
|
67
|
+
|
|
68
|
+
&:hover:not(:disabled) {
|
|
69
|
+
background: var(--ck-secondary-button-hover-background);
|
|
70
|
+
border-color: var(--ck-body-color-muted);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
&:disabled {
|
|
74
|
+
opacity: 0.5;
|
|
75
|
+
cursor: not-allowed;
|
|
76
|
+
}
|
|
77
|
+
`;
|
|
78
|
+
/** Left group: action icon badge + the title/subtitle text. */
|
|
79
|
+
const OptionLeft = styled.div `
|
|
80
|
+
display: flex;
|
|
81
|
+
align-items: center;
|
|
82
|
+
gap: 12px;
|
|
83
|
+
min-width: 0;
|
|
84
|
+
`;
|
|
85
|
+
/** Holds the per-action icon on the left of each row (no background). */
|
|
86
|
+
const OptionIconBadge = styled.div `
|
|
87
|
+
flex-shrink: 0;
|
|
88
|
+
width: 28px;
|
|
89
|
+
height: 28px;
|
|
90
|
+
display: flex;
|
|
91
|
+
align-items: center;
|
|
92
|
+
justify-content: center;
|
|
93
|
+
color: var(--ck-body-color, #1a1a2e);
|
|
94
|
+
`;
|
|
95
|
+
/** Overlapping strip of token/wallet/exchange logos on the right of each row. */
|
|
96
|
+
const LogoCluster = styled.div `
|
|
97
|
+
display: flex;
|
|
98
|
+
flex-shrink: 0;
|
|
99
|
+
align-items: center;
|
|
100
|
+
padding-left: 2px;
|
|
101
|
+
|
|
102
|
+
img,
|
|
103
|
+
svg {
|
|
104
|
+
width: 18px;
|
|
105
|
+
height: 18px;
|
|
106
|
+
border-radius: 50%;
|
|
107
|
+
margin-left: -7px;
|
|
108
|
+
border: 1.5px solid var(--ck-secondary-button-background, #fff);
|
|
109
|
+
background: var(--ck-body-background, #fff);
|
|
110
|
+
object-fit: cover;
|
|
111
|
+
box-sizing: content-box;
|
|
112
|
+
}
|
|
113
|
+
img:first-child,
|
|
114
|
+
svg:first-child {
|
|
115
|
+
margin-left: 0;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
@media (max-width: 420px) {
|
|
119
|
+
padding-left: 2px;
|
|
120
|
+
img,
|
|
121
|
+
svg {
|
|
122
|
+
width: 16px;
|
|
123
|
+
height: 16px;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
`;
|
|
127
|
+
const OptionInfo = styled.div `
|
|
128
|
+
display: flex;
|
|
129
|
+
flex-direction: column;
|
|
130
|
+
gap: 4px;
|
|
131
|
+
overflow: hidden;
|
|
132
|
+
`;
|
|
133
|
+
const OptionTitle = styled.span `
|
|
134
|
+
font-size: 14px;
|
|
135
|
+
font-weight: 600;
|
|
136
|
+
color: var(--ck-body-color);
|
|
137
|
+
|
|
138
|
+
@media (max-width: 420px) {
|
|
139
|
+
font-size: 13px;
|
|
140
|
+
}
|
|
141
|
+
`;
|
|
142
|
+
const OptionSubtitle = styled.span `
|
|
143
|
+
font-size: 11px;
|
|
144
|
+
font-weight: 500;
|
|
145
|
+
color: var(--ck-body-color-muted);
|
|
146
|
+
white-space: nowrap;
|
|
147
|
+
overflow: hidden;
|
|
148
|
+
text-overflow: clip;
|
|
149
|
+
|
|
150
|
+
@media (max-width: 420px) {
|
|
151
|
+
font-size: 10px;
|
|
152
|
+
}
|
|
153
|
+
`;
|
|
154
|
+
/** Sized, centered wrapper so the QR (which sizes off its parent width) renders. */
|
|
155
|
+
const QRWrapper = styled.div `
|
|
156
|
+
display: block;
|
|
157
|
+
margin: 14px auto;
|
|
158
|
+
width: 100%;
|
|
159
|
+
max-width: 300px;
|
|
160
|
+
|
|
161
|
+
> div {
|
|
162
|
+
width: 100%;
|
|
163
|
+
}
|
|
164
|
+
`;
|
|
165
|
+
|
|
166
|
+
export { ButtonLogo, DepositContent, LogoCluster, OptionButton, OptionIconBadge, OptionInfo, OptionLeft, OptionList, OptionSubtitle, OptionTitle, QRWrapper, Skeleton, StepDivider };
|
|
167
|
+
//# sourceMappingURL=styles.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"styles.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { type FundingChain, type FundingCurrency } from '../../../hooks/openfort/useFundingChains';
|
|
2
|
+
/** Which rail the route feeds: self-custody wallet send vs exchange withdrawal. */
|
|
3
|
+
type DepositRouteKind = 'crypto' | 'cex';
|
|
4
|
+
/**
|
|
5
|
+
* Shared state for a deposit route: the source chain/currency selection (sourced
|
|
6
|
+
* live from Relay via {@link useFundingChains}) plus the resolved deposit
|
|
7
|
+
* address. Both the "from wallet"/"from exchange" tabs and the standalone "from
|
|
8
|
+
* address" page build on this — they differ only in the lead buttons.
|
|
9
|
+
*/
|
|
10
|
+
export declare function useDepositRoute(kind: DepositRouteKind): {
|
|
11
|
+
chains: FundingChain[];
|
|
12
|
+
chainsLoading: boolean;
|
|
13
|
+
chain: string;
|
|
14
|
+
setChain: import("react").Dispatch<import("react").SetStateAction<string>>;
|
|
15
|
+
currency: string;
|
|
16
|
+
setCurrency: import("react").Dispatch<import("react").SetStateAction<string>>;
|
|
17
|
+
currencies: FundingCurrency[];
|
|
18
|
+
activeChain: FundingChain;
|
|
19
|
+
activeCurrency: FundingCurrency;
|
|
20
|
+
address: string | undefined;
|
|
21
|
+
target: {
|
|
22
|
+
chain: string;
|
|
23
|
+
currency: string;
|
|
24
|
+
address?: string;
|
|
25
|
+
};
|
|
26
|
+
pm: import("../../../hooks/openfort/useFunding").PaymentMethod | null;
|
|
27
|
+
receiverAddress: string | null;
|
|
28
|
+
sameChain: boolean;
|
|
29
|
+
status: import("../../../hooks/openfort/useFunding").SessionStatus | "idle";
|
|
30
|
+
loading: boolean;
|
|
31
|
+
error: Error | null;
|
|
32
|
+
isAvailable: boolean;
|
|
33
|
+
payLink: (params: import("../../../hooks/openfort/useFunding").PayLinkParams) => Promise<string>;
|
|
34
|
+
};
|
|
35
|
+
export {};
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { ChainTypeEnum } from '@openfort/openfort-js';
|
|
2
|
+
import { useState, useRef, useEffect } from 'react';
|
|
3
|
+
import { useEthereumEmbeddedWallet } from '../../../ethereum/hooks/useEthereumEmbeddedWallet.js';
|
|
4
|
+
import { useFunding } from '../../../hooks/openfort/useFunding.js';
|
|
5
|
+
import { useFundingChains, nominalUnits } from '../../../hooks/openfort/useFundingChains.js';
|
|
6
|
+
import { useOpenfortCore } from '../../../openfort/useOpenfort.js';
|
|
7
|
+
import { useSolanaEmbeddedWallet } from '../../../solana/hooks/useSolanaEmbeddedWallet.js';
|
|
8
|
+
import { logger } from '../../../utils/logger.js';
|
|
9
|
+
import { isCexDeliverable } from './cexChains.js';
|
|
10
|
+
import { isSolana } from './sources.js';
|
|
11
|
+
import { useFundingTarget } from './useFundingTarget.js';
|
|
12
|
+
|
|
13
|
+
function paymentMethodFor(chain, currency) {
|
|
14
|
+
const source = { chain, currency: currency.address, amount: nominalUnits(currency.decimals, currency.native) };
|
|
15
|
+
// A CEX withdrawal is just an on-chain send to the Relay deposit address — the
|
|
16
|
+
// funding API has no separate 'cex' type, so every source resolves to evm/solana.
|
|
17
|
+
return { type: isSolana(chain) ? 'solana' : 'evm', source };
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Shared state for a deposit route: the source chain/currency selection (sourced
|
|
21
|
+
* live from Relay via {@link useFundingChains}) plus the resolved deposit
|
|
22
|
+
* address. Both the "from wallet"/"from exchange" tabs and the standalone "from
|
|
23
|
+
* address" page build on this — they differ only in the lead buttons.
|
|
24
|
+
*/
|
|
25
|
+
function useDepositRoute(kind) {
|
|
26
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
27
|
+
const { chainType } = useOpenfortCore();
|
|
28
|
+
const ethWallet = useEthereumEmbeddedWallet();
|
|
29
|
+
const solWallet = useSolanaEmbeddedWallet();
|
|
30
|
+
// Funds land in the active chain's embedded wallet (EVM or Solana).
|
|
31
|
+
const wallet = chainType === ChainTypeEnum.SVM ? solWallet : ethWallet;
|
|
32
|
+
const { session, status, error, loading, isAvailable, fund, payLink, reset } = useFunding();
|
|
33
|
+
const { chains: allChains, loading: chainsLoading } = useFundingChains();
|
|
34
|
+
const target = useFundingTarget();
|
|
35
|
+
// Drop the destination chain — funding is cross-chain; same-chain is a plain
|
|
36
|
+
// transfer with no Relay route, so it shouldn't appear as a source option.
|
|
37
|
+
const sourceChains = allChains.filter((c) => c.id !== target.chain);
|
|
38
|
+
// The CEX rail rides Coinbase Onramp, which only delivers to a fixed set of EVM
|
|
39
|
+
// chains — offer those as the pay-with sources.
|
|
40
|
+
const chains = kind === 'cex' ? sourceChains.filter((c) => isCexDeliverable(c.id)) : sourceChains;
|
|
41
|
+
// Where funds land: the active embedded wallet (the Relay deposit recipient).
|
|
42
|
+
const address = wallet.status === 'connected' ? wallet.address : undefined;
|
|
43
|
+
const [chainId, setChainId] = useState('');
|
|
44
|
+
const [currencySymbol, setCurrencySymbol] = useState('');
|
|
45
|
+
const lastKey = useRef('');
|
|
46
|
+
// Derive the active selection, falling back to the first available chain/currency
|
|
47
|
+
// so the picker is valid before the user touches it and as chains load in.
|
|
48
|
+
const activeChain = (_a = chains.find((c) => c.id === chainId)) !== null && _a !== void 0 ? _a : chains[0];
|
|
49
|
+
const currencies = (_b = activeChain === null || activeChain === void 0 ? void 0 : activeChain.currencies) !== null && _b !== void 0 ? _b : [];
|
|
50
|
+
const activeCurrency = (_c = currencies.find((c) => c.symbol === currencySymbol)) !== null && _c !== void 0 ? _c : currencies[0];
|
|
51
|
+
const chain = (_d = activeChain === null || activeChain === void 0 ? void 0 : activeChain.id) !== null && _d !== void 0 ? _d : target.chain;
|
|
52
|
+
const sameChain = chain === target.chain;
|
|
53
|
+
const receiverAddress = sameChain
|
|
54
|
+
? (address !== null && address !== void 0 ? address : null)
|
|
55
|
+
: ((_f = (_e = session === null || session === void 0 ? void 0 : session.paymentMethod) === null || _e === void 0 ? void 0 : _e.receiverAddress) !== null && _f !== void 0 ? _f : null);
|
|
56
|
+
const pm = (_g = session === null || session === void 0 ? void 0 : session.paymentMethod) !== null && _g !== void 0 ? _g : null;
|
|
57
|
+
useEffect(() => {
|
|
58
|
+
if (!address || !isAvailable || !activeChain || !activeCurrency)
|
|
59
|
+
return;
|
|
60
|
+
if (sameChain) {
|
|
61
|
+
lastKey.current = '';
|
|
62
|
+
reset();
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
const key = `${kind}:${activeChain.id}:${activeCurrency.symbol}`;
|
|
66
|
+
if (lastKey.current === key)
|
|
67
|
+
return;
|
|
68
|
+
lastKey.current = key;
|
|
69
|
+
logger.log('[funding:route] resolved', {
|
|
70
|
+
kind,
|
|
71
|
+
sourceChain: activeChain.id,
|
|
72
|
+
currency: activeCurrency.symbol,
|
|
73
|
+
destChain: target.chain,
|
|
74
|
+
});
|
|
75
|
+
fund({ chain: target.chain, currency: target.currency, address }, paymentMethodFor(activeChain.id, activeCurrency)).catch(() => { });
|
|
76
|
+
}, [address, activeChain, activeCurrency, isAvailable, sameChain, fund, reset, target.chain, target.currency, kind]);
|
|
77
|
+
// Surface an empty source list (e.g. no Coinbase-deliverable chains) for diagnosis.
|
|
78
|
+
useEffect(() => {
|
|
79
|
+
if (!isAvailable || chainsLoading || chains.length > 0)
|
|
80
|
+
return;
|
|
81
|
+
logger.warn('[funding:route] no source chains available', { kind, destChain: target.chain });
|
|
82
|
+
}, [isAvailable, chainsLoading, chains.length, kind, target.chain]);
|
|
83
|
+
return {
|
|
84
|
+
chains,
|
|
85
|
+
chainsLoading,
|
|
86
|
+
chain,
|
|
87
|
+
setChain: setChainId,
|
|
88
|
+
currency: (_h = activeCurrency === null || activeCurrency === void 0 ? void 0 : activeCurrency.symbol) !== null && _h !== void 0 ? _h : '',
|
|
89
|
+
setCurrency: setCurrencySymbol,
|
|
90
|
+
currencies,
|
|
91
|
+
activeChain,
|
|
92
|
+
activeCurrency,
|
|
93
|
+
address,
|
|
94
|
+
target,
|
|
95
|
+
pm,
|
|
96
|
+
receiverAddress,
|
|
97
|
+
sameChain,
|
|
98
|
+
status,
|
|
99
|
+
loading,
|
|
100
|
+
error,
|
|
101
|
+
isAvailable,
|
|
102
|
+
payLink,
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export { useDepositRoute };
|
|
107
|
+
//# sourceMappingURL=useDepositRoute.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useDepositRoute.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The destination route Deposit-hub funding settles into. Integrators override the
|
|
3
|
+
* chain and currency via `uiConfig.funding.{targetChain,targetCurrency}`; both
|
|
4
|
+
* default to USDC on the active chain type (Base for EVM, Solana mainnet for SVM)
|
|
5
|
+
* so the flow works with zero configuration. `address` is the optional integrator
|
|
6
|
+
* override (`uiConfig.funding.targetAddress`); when unset, callers fall back to the
|
|
7
|
+
* active embedded wallet for the destination chain family.
|
|
8
|
+
*/
|
|
9
|
+
export declare function useFundingTarget(): {
|
|
10
|
+
chain: string;
|
|
11
|
+
currency: string;
|
|
12
|
+
address?: string;
|
|
13
|
+
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { ChainTypeEnum } from '@openfort/openfort-js';
|
|
2
|
+
import { useOpenfortCore } from '../../../openfort/useOpenfort.js';
|
|
3
|
+
import { useOpenfort } from '../../Openfort/useOpenfort.js';
|
|
4
|
+
import { DEST_CHAIN_SOL, DEST_CHAIN, DEST_USDC_SOL, DEST_USDC } from './sources.js';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* The destination route Deposit-hub funding settles into. Integrators override the
|
|
8
|
+
* chain and currency via `uiConfig.funding.{targetChain,targetCurrency}`; both
|
|
9
|
+
* default to USDC on the active chain type (Base for EVM, Solana mainnet for SVM)
|
|
10
|
+
* so the flow works with zero configuration. `address` is the optional integrator
|
|
11
|
+
* override (`uiConfig.funding.targetAddress`); when unset, callers fall back to the
|
|
12
|
+
* active embedded wallet for the destination chain family.
|
|
13
|
+
*/
|
|
14
|
+
function useFundingTarget() {
|
|
15
|
+
var _a, _b, _c, _d, _e;
|
|
16
|
+
const { uiConfig } = useOpenfort();
|
|
17
|
+
const { chainType } = useOpenfortCore();
|
|
18
|
+
const isSolana = chainType === ChainTypeEnum.SVM;
|
|
19
|
+
return {
|
|
20
|
+
chain: (_b = (_a = uiConfig.funding) === null || _a === void 0 ? void 0 : _a.targetChain) !== null && _b !== void 0 ? _b : (isSolana ? DEST_CHAIN_SOL : DEST_CHAIN),
|
|
21
|
+
currency: (_d = (_c = uiConfig.funding) === null || _c === void 0 ? void 0 : _c.targetCurrency) !== null && _d !== void 0 ? _d : (isSolana ? DEST_USDC_SOL : DEST_USDC),
|
|
22
|
+
address: (_e = uiConfig.funding) === null || _e === void 0 ? void 0 : _e.targetAddress,
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export { useFundingTarget };
|
|
27
|
+
//# sourceMappingURL=useFundingTarget.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useFundingTarget.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Transfer from Exchange — the user enters an amount; "Open Coinbase" hands off to
|
|
3
|
+
* a hosted Coinbase pay-link that delivers to the embedded wallet on the
|
|
4
|
+
* destination chain. The destination (chain + currency + address) is bound to a
|
|
5
|
+
* funding session created up-front, so the client can't redirect the funds — only
|
|
6
|
+
* the amount is chosen here. After hand-off the bound session is polled until it
|
|
7
|
+
* settles (advanced by the Coinbase webhook on the backend), driving the
|
|
8
|
+
* success / failed screen. No Relay routing; Binance is gated until its rail lands.
|
|
9
|
+
*/
|
|
10
|
+
declare const DepositCex: () => import("react/jsx-runtime").JSX.Element;
|
|
11
|
+
export default DepositCex;
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
2
|
+
import { ChainTypeEnum } from '@openfort/openfort-js';
|
|
3
|
+
import { useState, useRef, useEffect, useMemo } from 'react';
|
|
4
|
+
import Logos from '../../../assets/logos.js';
|
|
5
|
+
import { useEthereumEmbeddedWallet } from '../../../ethereum/hooks/useEthereumEmbeddedWallet.js';
|
|
6
|
+
import { useFunding } from '../../../hooks/openfort/useFunding.js';
|
|
7
|
+
import { useFundingChains } from '../../../hooks/openfort/useFundingChains.js';
|
|
8
|
+
import { invalidateBalance } from '../../../hooks/useBalance.js';
|
|
9
|
+
import { useOpenfortCore } from '../../../openfort/useOpenfort.js';
|
|
10
|
+
import { logger } from '../../../utils/logger.js';
|
|
11
|
+
import { ModalHeading, ModalBody } from '../../Common/Modal/styles.js';
|
|
12
|
+
import { routes } from '../../Openfort/types.js';
|
|
13
|
+
import { useOpenfort } from '../../Openfort/useOpenfort.js';
|
|
14
|
+
import { PageContent } from '../../PageContent/index.js';
|
|
15
|
+
import { Section, SectionLabel, AmountCard, CurrencySymbol, AmountInput, PresetList, PresetButton } from '../Buy/styles.js';
|
|
16
|
+
import { isCexDeliverable, CEX_CHAIN_NAMES } from '../Deposit/cexChains.js';
|
|
17
|
+
import { isDepositFlowActive, DepositProgress } from '../Deposit/DepositProgress.js';
|
|
18
|
+
import { DepositStatus } from '../Deposit/DepositStatus.js';
|
|
19
|
+
import { walletListBtn } from '../Deposit/formStyles.js';
|
|
20
|
+
import { DEST_USDC } from '../Deposit/sources.js';
|
|
21
|
+
import { StepDivider, ButtonLogo } from '../Deposit/styles.js';
|
|
22
|
+
import { useFundingTarget } from '../Deposit/useFundingTarget.js';
|
|
23
|
+
import { sanitizeForParsing, sanitizeAmountInput } from '../Send/utils.js';
|
|
24
|
+
|
|
25
|
+
/** Exchange rails. Binance is gated until its rail lands. */
|
|
26
|
+
const EXCHANGES = [
|
|
27
|
+
{ id: 'coinbase', comingSoon: false },
|
|
28
|
+
{ id: 'binance', comingSoon: true },
|
|
29
|
+
];
|
|
30
|
+
/** Exchange brand logos keyed by exchange id. */
|
|
31
|
+
const EXCHANGE_LOGO = {
|
|
32
|
+
coinbase: jsx(Logos.Coinbase, { background: true }),
|
|
33
|
+
binance: jsx(Logos.Binance, {}),
|
|
34
|
+
};
|
|
35
|
+
/** Coinbase Onramp minimum (USD, ≈ USDC units); enforced client-side for UX. */
|
|
36
|
+
const MIN_AMOUNT = 5;
|
|
37
|
+
const PRESETS = [10, 25, 50];
|
|
38
|
+
function titleCase(s) {
|
|
39
|
+
return s.charAt(0).toUpperCase() + s.slice(1);
|
|
40
|
+
}
|
|
41
|
+
const helperText = { fontSize: 12, color: 'var(--ck-body-color-muted, #6b7280)' };
|
|
42
|
+
const errorHelper = { fontSize: 12, color: '#dc2626' };
|
|
43
|
+
const destinationRow = { display: 'flex', alignItems: 'center', gap: 6, ...helperText };
|
|
44
|
+
const destinationLogo = { width: 14, height: 14, borderRadius: '50%' };
|
|
45
|
+
const hideBrokenLogo = (e) => {
|
|
46
|
+
e.currentTarget.style.display = 'none';
|
|
47
|
+
};
|
|
48
|
+
/**
|
|
49
|
+
* Transfer from Exchange — the user enters an amount; "Open Coinbase" hands off to
|
|
50
|
+
* a hosted Coinbase pay-link that delivers to the embedded wallet on the
|
|
51
|
+
* destination chain. The destination (chain + currency + address) is bound to a
|
|
52
|
+
* funding session created up-front, so the client can't redirect the funds — only
|
|
53
|
+
* the amount is chosen here. After hand-off the bound session is polled until it
|
|
54
|
+
* settles (advanced by the Coinbase webhook on the backend), driving the
|
|
55
|
+
* success / failed screen. No Relay routing; Binance is gated until its rail lands.
|
|
56
|
+
*/
|
|
57
|
+
const DepositCex = () => {
|
|
58
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
59
|
+
const { triggerResize } = useOpenfort();
|
|
60
|
+
const target = useFundingTarget();
|
|
61
|
+
// CEX (Coinbase pay-link + session) is served by the Openfort API, not the
|
|
62
|
+
// standalone funding service — resolve this rail's base URL from the API backend.
|
|
63
|
+
const { isAvailable, createSession, track, payLink, status } = useFunding({ useBackendUrl: true });
|
|
64
|
+
const wallet = useEthereumEmbeddedWallet();
|
|
65
|
+
const { embeddedAccounts } = useOpenfortCore();
|
|
66
|
+
const { chains } = useFundingChains();
|
|
67
|
+
const [amount, setAmount] = useState(String(MIN_AMOUNT));
|
|
68
|
+
const [pressedPreset, setPressedPreset] = useState(null);
|
|
69
|
+
const [session, setSession] = useState(null);
|
|
70
|
+
const [error, setError] = useState(null);
|
|
71
|
+
const [opened, setOpened] = useState(false);
|
|
72
|
+
// Resolve the destination by chain family: EVM targets use the EVM embedded
|
|
73
|
+
// wallet, Solana targets the Solana (SVM) embedded account — never cross families
|
|
74
|
+
// (an EVM address on a Solana target would be rejected / mis-delivered). Accounts
|
|
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
|
+
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 = (_b = target.address) !== null && _b !== void 0 ? _b : (isEvmTarget ? wallet.address : solanaAddress);
|
|
79
|
+
const chainSupported = isCexDeliverable(target.chain);
|
|
80
|
+
// Resolve the destination asset + chain for the "Arrives as …" line. The live
|
|
81
|
+
// chain list is curated for source selection, so the destination may be absent;
|
|
82
|
+
// only claim a symbol we resolved, or USDC for the zero-config default.
|
|
83
|
+
const destChain = chains.find((c) => c.id === target.chain);
|
|
84
|
+
const destChainName = (_d = (_c = destChain === null || destChain === void 0 ? void 0 : destChain.name) !== null && _c !== void 0 ? _c : CEX_CHAIN_NAMES[target.chain]) !== null && _d !== void 0 ? _d : target.chain;
|
|
85
|
+
const destAsset = destChain === null || destChain === void 0 ? void 0 : destChain.currencies.find((c) => c.address.toLowerCase() === target.currency.toLowerCase());
|
|
86
|
+
const isDefaultUsdc = target.currency.toLowerCase() === DEST_USDC.toLowerCase();
|
|
87
|
+
const destAssetLabel = (_e = destAsset === null || destAsset === void 0 ? void 0 : destAsset.symbol) !== null && _e !== void 0 ? _e : (isDefaultUsdc ? 'USDC' : null);
|
|
88
|
+
const destAssetLogo = (_f = destAsset === null || destAsset === void 0 ? void 0 : destAsset.logo) !== null && _f !== void 0 ? _f : null;
|
|
89
|
+
const destChainLogo = (_g = destChain === null || destChain === void 0 ? void 0 : destChain.logo) !== null && _g !== void 0 ? _g : null;
|
|
90
|
+
// Mint the destination-bound session up-front (per target wallet), so the click
|
|
91
|
+
// that opens Coinbase is a single fast pay-link call and stays popup-safe.
|
|
92
|
+
//
|
|
93
|
+
// `createSession` is held in a ref and kept OUT of the effect deps: its identity
|
|
94
|
+
// churns whenever the core client re-memoizes (e.g. during Solana recovery
|
|
95
|
+
// retries, which re-render rapidly). If it were a dep, a churn mid-flight would
|
|
96
|
+
// re-run the effect, fire its cleanup (`cancelled = true`), then early-return on
|
|
97
|
+
// the unchanged sessionKey — so the in-flight create resolves but its result is
|
|
98
|
+
// dropped and never retried, stranding the page on "Preparing…". The effect must
|
|
99
|
+
// only re-run on a genuine destination change.
|
|
100
|
+
const sessionKey = useRef('');
|
|
101
|
+
const createSessionRef = useRef(createSession);
|
|
102
|
+
createSessionRef.current = createSession;
|
|
103
|
+
useEffect(() => {
|
|
104
|
+
if (!isAvailable || !address || !chainSupported)
|
|
105
|
+
return;
|
|
106
|
+
const key = `${target.chain}|${target.currency}|${address}`;
|
|
107
|
+
if (sessionKey.current === key)
|
|
108
|
+
return;
|
|
109
|
+
sessionKey.current = key;
|
|
110
|
+
let cancelled = false;
|
|
111
|
+
setSession(null);
|
|
112
|
+
setError(null);
|
|
113
|
+
createSessionRef
|
|
114
|
+
.current({ chain: target.chain, currency: target.currency, address })
|
|
115
|
+
.then((s) => {
|
|
116
|
+
if (!cancelled)
|
|
117
|
+
setSession({ id: s.id, clientSecret: s.clientSecret });
|
|
118
|
+
})
|
|
119
|
+
.catch((e) => {
|
|
120
|
+
if (!cancelled)
|
|
121
|
+
setError(e instanceof Error ? e : new Error(String(e)));
|
|
122
|
+
});
|
|
123
|
+
return () => {
|
|
124
|
+
cancelled = true;
|
|
125
|
+
// Clear the key so a genuine destination change re-creates the session;
|
|
126
|
+
// without this the guard above would block the retry after this cancel.
|
|
127
|
+
sessionKey.current = '';
|
|
128
|
+
};
|
|
129
|
+
}, [isAvailable, address, chainSupported, target.chain, target.currency]);
|
|
130
|
+
const fiatAmount = useMemo(() => {
|
|
131
|
+
const normalized = sanitizeForParsing(sanitizeAmountInput(amount));
|
|
132
|
+
if (!normalized)
|
|
133
|
+
return null;
|
|
134
|
+
const numeric = Number(normalized);
|
|
135
|
+
return Number.isFinite(numeric) ? numeric : null;
|
|
136
|
+
}, [amount]);
|
|
137
|
+
const amountValid = fiatAmount !== null && fiatAmount >= MIN_AMOUNT;
|
|
138
|
+
const amountTooLow = fiatAmount !== null && fiatAmount < MIN_AMOUNT;
|
|
139
|
+
const infraReady = isAvailable && chainSupported && Boolean(session) && !error;
|
|
140
|
+
const payReady = infraReady && amountValid;
|
|
141
|
+
// Resize when a block that changes the modal's height toggles.
|
|
142
|
+
useEffect(() => {
|
|
143
|
+
triggerResize();
|
|
144
|
+
}, [isAvailable, chainSupported, session, error, opened, amountTooLow, triggerResize]);
|
|
145
|
+
// Once the bound session settles, refresh balances so delivered funds show
|
|
146
|
+
// without a manual reload.
|
|
147
|
+
useEffect(() => {
|
|
148
|
+
if (status === 'succeeded')
|
|
149
|
+
invalidateBalance();
|
|
150
|
+
}, [status]);
|
|
151
|
+
const handleAmountChange = (event) => {
|
|
152
|
+
const raw = sanitizeAmountInput(event.target.value);
|
|
153
|
+
if (raw === '' || /^[0-9]*\.?[0-9]*$/.test(raw)) {
|
|
154
|
+
setPressedPreset(null);
|
|
155
|
+
setAmount(raw);
|
|
156
|
+
}
|
|
157
|
+
};
|
|
158
|
+
const handleAmountBlur = () => {
|
|
159
|
+
const normalized = sanitizeForParsing(sanitizeAmountInput(amount));
|
|
160
|
+
if (!normalized)
|
|
161
|
+
return;
|
|
162
|
+
const numeric = Number(normalized);
|
|
163
|
+
if (Number.isFinite(numeric) && numeric > 0)
|
|
164
|
+
setAmount(numeric.toFixed(2));
|
|
165
|
+
};
|
|
166
|
+
const handlePreset = (value) => {
|
|
167
|
+
setPressedPreset(value);
|
|
168
|
+
setAmount(value.toFixed(2));
|
|
169
|
+
};
|
|
170
|
+
const openExchange = () => {
|
|
171
|
+
if (!session || fiatAmount === null || !amountValid)
|
|
172
|
+
return;
|
|
173
|
+
// Open the tab up-front (sync) so the popup blocker permits it. Passing
|
|
174
|
+
// `noopener` makes window.open return null, leaving the tab stuck on
|
|
175
|
+
// about:blank — keep the handle and sever the opener link manually instead.
|
|
176
|
+
const w = window.open('about:blank', '_blank');
|
|
177
|
+
if (w)
|
|
178
|
+
w.opener = null;
|
|
179
|
+
logger.log('[funding:cex] open pay-link', { sessionId: session.id, amount: fiatAmount, asset: destAssetLabel });
|
|
180
|
+
void payLink({
|
|
181
|
+
sessionId: session.id,
|
|
182
|
+
clientSecret: session.clientSecret,
|
|
183
|
+
amount: String(fiatAmount),
|
|
184
|
+
...(destAssetLabel ? { asset: destAssetLabel } : {}),
|
|
185
|
+
})
|
|
186
|
+
.then((url) => {
|
|
187
|
+
if (!url) {
|
|
188
|
+
w === null || w === void 0 ? void 0 : w.close(); // no URL resolved — don't strand the popup on "undefined"
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
191
|
+
if (w)
|
|
192
|
+
w.location.href = url;
|
|
193
|
+
else
|
|
194
|
+
window.location.assign(url); // popup blocked — fall back to this tab
|
|
195
|
+
setOpened(true);
|
|
196
|
+
// Watch the destination-bound session settle so the modal can show the
|
|
197
|
+
// success / failed outcome instead of stranding the user on the form.
|
|
198
|
+
if (session)
|
|
199
|
+
void track({ id: session.id, clientSecret: session.clientSecret }).catch(() => { });
|
|
200
|
+
})
|
|
201
|
+
.catch((e) => {
|
|
202
|
+
w === null || w === void 0 ? void 0 : w.close();
|
|
203
|
+
setError(e instanceof Error ? e : new Error(String(e)));
|
|
204
|
+
});
|
|
205
|
+
};
|
|
206
|
+
// Once the deposit lands, the session-status flow takes over the modal with the
|
|
207
|
+
// success / refunded / expired screen (shared with the crypto rail).
|
|
208
|
+
if (isDepositFlowActive(status))
|
|
209
|
+
return jsx(DepositProgress, { status: status });
|
|
210
|
+
return (jsxs(PageContent, { onBack: routes.DEPOSIT, children: [jsx(ModalHeading, { children: "Transfer from Exchange" }), jsxs(Section, { children: [jsx(SectionLabel, { children: "Amount" }), jsxs(AmountCard, { children: [jsx(CurrencySymbol, { children: "$" }), jsx(AmountInput, { value: amount, onChange: handleAmountChange, onBlur: handleAmountBlur, placeholder: "0.00", inputMode: "decimal", autoComplete: "off" })] }), jsx(PresetList, { children: PRESETS.map((preset) => (jsxs(PresetButton, { type: "button", "$active": pressedPreset === preset, onClick: () => handlePreset(preset), children: ["$", preset] }, preset))) }), amountTooLow ? (jsxs("span", { style: errorHelper, children: ["Enter at least $", MIN_AMOUNT, ".00 \u2014 the Coinbase minimum."] })) : (jsxs("span", { style: helperText, children: ["Minimum $", MIN_AMOUNT, ".00"] })), chainSupported && (jsxs("span", { style: destinationRow, children: [destAssetLogo && jsx("img", { src: destAssetLogo, alt: "", style: destinationLogo, onError: hideBrokenLogo }), destChainLogo && jsx("img", { src: destChainLogo, alt: "", style: destinationLogo, onError: hideBrokenLogo })] }))] }), !isAvailable && jsx(ModalBody, { children: "Funding isn't available right now." }), isAvailable && !chainSupported && jsxs(ModalBody, { children: ["Coinbase can't deliver to ", destChainName, " yet."] }), error && jsx(ModalBody, { style: { color: '#dc2626' }, children: error.message }), jsx(StepDivider, { children: "Then open an exchange" }), jsx("div", { style: { display: 'flex', flexDirection: 'column', gap: 8, marginTop: 12 }, children: EXCHANGES.map((ex) => ex.comingSoon ? (jsxs("button", { type: "button", disabled: true, style: {
|
|
211
|
+
...walletListBtn,
|
|
212
|
+
display: 'flex',
|
|
213
|
+
alignItems: 'center',
|
|
214
|
+
gap: 8,
|
|
215
|
+
opacity: 0.55,
|
|
216
|
+
cursor: 'not-allowed',
|
|
217
|
+
}, children: [jsx(ButtonLogo, { children: EXCHANGE_LOGO[ex.id] }), jsx("span", { children: titleCase(ex.id) }), jsx("span", { style: { marginLeft: 'auto', fontSize: 11, fontWeight: 600 }, children: "Coming soon" })] }, ex.id)) : (jsxs("button", { type: "button", disabled: !payReady, style: {
|
|
218
|
+
...walletListBtn,
|
|
219
|
+
display: 'flex',
|
|
220
|
+
alignItems: 'center',
|
|
221
|
+
justifyContent: 'center',
|
|
222
|
+
gap: 8,
|
|
223
|
+
opacity: payReady ? 1 : 0.55,
|
|
224
|
+
cursor: payReady ? 'pointer' : 'not-allowed',
|
|
225
|
+
}, onClick: openExchange, children: [jsx(ButtonLogo, { children: EXCHANGE_LOGO[ex.id] }), infraReady ? `Open ${titleCase(ex.id)} ↗` : 'Preparing…'] }, ex.id))) }), opened &&
|
|
226
|
+
(status === 'waiting_payment' ? (jsx(DepositStatus, { status: status })) : (jsx(ModalBody, { style: { marginTop: 12 }, children: "Finish in the Coinbase tab \u2014 we'll confirm here once your funds arrive." })))] }));
|
|
227
|
+
};
|
|
228
|
+
|
|
229
|
+
export { DepositCex as default };
|
|
230
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Transfer from address — choose a source chain + token and send to the deposit
|
|
3
|
+
* address / QR that appears. Same-chain is a plain transfer to the wallet;
|
|
4
|
+
* cross-chain routes bridge via Relay. Wallet deeplinks live on the separate
|
|
5
|
+
* "Transfer from wallet" tab.
|
|
6
|
+
*/
|
|
7
|
+
declare const DepositCrypto: () => import("react/jsx-runtime").JSX.Element;
|
|
8
|
+
export default DepositCrypto;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
2
|
+
import { useEffect } from 'react';
|
|
3
|
+
import { ModalHeading, ModalBody } from '../../Common/Modal/styles.js';
|
|
4
|
+
import { routes } from '../../Openfort/types.js';
|
|
5
|
+
import { useOpenfort } from '../../Openfort/useOpenfort.js';
|
|
6
|
+
import { PageContent } from '../../PageContent/index.js';
|
|
7
|
+
import { DepositAddressBlock } from '../Deposit/DepositAddressBlock.js';
|
|
8
|
+
import { isDepositFlowActive, DepositProgress } from '../Deposit/DepositProgress.js';
|
|
9
|
+
import { RouteSelectors } from '../Deposit/RouteSelectors.js';
|
|
10
|
+
import { useDepositRoute } from '../Deposit/useDepositRoute.js';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Transfer from address — choose a source chain + token and send to the deposit
|
|
14
|
+
* address / QR that appears. Same-chain is a plain transfer to the wallet;
|
|
15
|
+
* cross-chain routes bridge via Relay. Wallet deeplinks live on the separate
|
|
16
|
+
* "Transfer from wallet" tab.
|
|
17
|
+
*/
|
|
18
|
+
const DepositCrypto = () => {
|
|
19
|
+
var _a, _b, _c, _d;
|
|
20
|
+
const { triggerResize } = useOpenfort();
|
|
21
|
+
const route = useDepositRoute('crypto');
|
|
22
|
+
useEffect(() => {
|
|
23
|
+
triggerResize();
|
|
24
|
+
}, [route.receiverAddress, route.loading, route.status, triggerResize]);
|
|
25
|
+
if (isDepositFlowActive(route.status))
|
|
26
|
+
return jsx(DepositProgress, { status: route.status });
|
|
27
|
+
return (jsxs(PageContent, { onBack: routes.DEPOSIT, children: [jsx(ModalHeading, { children: "Transfer from address" }), 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: (_b = (_a = route.activeCurrency) === null || _a === void 0 ? void 0 : _a.logo) !== null && _b !== void 0 ? _b : null, chainLogo: (_d = (_c = route.activeChain) === null || _c === void 0 ? void 0 : _c.logo) !== null && _d !== void 0 ? _d : null, receiverAddress: route.receiverAddress, pm: route.pm, sourceCurrency: route.activeCurrency ? { symbol: route.activeCurrency.symbol, decimals: route.activeCurrency.decimals } : null, sameChain: route.sameChain, loading: route.loading, status: route.status }), route.error && jsx(ModalBody, { style: { color: '#dc2626', marginTop: 12 }, children: route.error.message })] }));
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
export { DepositCrypto as default };
|
|
31
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|