@openfort/react 1.0.3 → 1.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/components/ConnectModal/ConnectWithOAuth.js +6 -3
- package/build/components/ConnectModal/ConnectWithOAuth.js.map +1 -1
- package/build/components/Openfort/types.d.ts +3 -0
- package/build/components/Pages/AssetInventory/index.js +127 -48
- package/build/components/Pages/AssetInventory/index.js.map +1 -1
- package/build/components/Pages/CreateWallet/index.js +32 -3
- package/build/components/Pages/CreateWallet/index.js.map +1 -1
- package/build/components/Pages/LoadWallets/index.js +5 -4
- package/build/components/Pages/LoadWallets/index.js.map +1 -1
- package/build/components/Pages/Loading/index.js +10 -4
- package/build/components/Pages/Loading/index.js.map +1 -1
- package/build/components/Pages/SelectToken/styles.d.ts +13 -0
- package/build/components/Pages/SelectToken/styles.js +103 -1
- package/build/components/Pages/SelectToken/styles.js.map +1 -1
- package/build/components/Pages/SendConfirmation/index.js +7 -0
- package/build/components/Pages/SendConfirmation/index.js.map +1 -1
- package/build/constants/logos.d.ts +2 -0
- package/build/constants/logos.js +58 -0
- package/build/constants/logos.js.map +1 -0
- package/build/ethereum/hooks/useEthereumWalletAssets.d.ts +25 -11
- package/build/ethereum/hooks/useEthereumWalletAssets.js +134 -14
- package/build/ethereum/hooks/useEthereumWalletAssets.js.map +1 -1
- package/build/index.d.ts +1 -1
- package/build/openfort/hooks/useEmbeddedStateMachine.js +4 -1
- package/build/openfort/hooks/useEmbeddedStateMachine.js.map +1 -1
- package/build/utils/index.d.ts +1 -1
- package/build/version.d.ts +1 -1
- package/build/version.js +1 -1
- package/package.json +1 -1
|
@@ -73,9 +73,12 @@ const ConnectWithOAuth = () => {
|
|
|
73
73
|
case states.REDIRECT: {
|
|
74
74
|
if (hasProvider)
|
|
75
75
|
return;
|
|
76
|
-
const
|
|
76
|
+
const baseURL = win.location.origin + win.location.pathname;
|
|
77
|
+
const hash = win.location.hash;
|
|
77
78
|
const queryParams = Object.fromEntries([...url.searchParams.entries()].filter(([key]) => ['openfortAuthProviderUI', 'refresh_token', 'access_token', 'player_id'].includes(key)));
|
|
78
79
|
queryParams.openfortAuthProviderUI = provider;
|
|
80
|
+
// Query params must come before the hash fragment in a valid URL
|
|
81
|
+
const redirectTo = `${baseURL}?${new URLSearchParams(queryParams).toString()}${hash}`;
|
|
79
82
|
try {
|
|
80
83
|
if (user) {
|
|
81
84
|
const authToken = await client.getAccessToken();
|
|
@@ -86,7 +89,7 @@ const ConnectWithOAuth = () => {
|
|
|
86
89
|
}
|
|
87
90
|
const linkResponse = await client.auth.initLinkOAuth({
|
|
88
91
|
provider,
|
|
89
|
-
redirectTo
|
|
92
|
+
redirectTo,
|
|
90
93
|
});
|
|
91
94
|
logger.log(linkResponse);
|
|
92
95
|
win.location.href = linkResponse;
|
|
@@ -94,7 +97,7 @@ const ConnectWithOAuth = () => {
|
|
|
94
97
|
else {
|
|
95
98
|
const r = await client.auth.initOAuth({
|
|
96
99
|
provider,
|
|
97
|
-
redirectTo
|
|
100
|
+
redirectTo,
|
|
98
101
|
});
|
|
99
102
|
logger.log(r);
|
|
100
103
|
win.location.href = r;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ConnectWithOAuth.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ConnectWithOAuth.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { motion } from 'framer-motion';
|
|
3
|
+
import { useState, useEffect, useMemo } from 'react';
|
|
2
4
|
import { formatUnits } from 'viem';
|
|
5
|
+
import { TOKEN_LOGO, symbolToColor } from '../../../constants/logos.js';
|
|
3
6
|
import { useEthereumWalletAssets } from '../../../ethereum/hooks/useEthereumWalletAssets.js';
|
|
7
|
+
import Chain from '../../Common/Chain/index.js';
|
|
4
8
|
import { ModalHeading } from '../../Common/Modal/styles.js';
|
|
5
|
-
import {
|
|
6
|
-
import { SelectTokenContent, TokenList, TokenContainer, TokenInfo, TokenSymbol, TokenBalance,
|
|
7
|
-
import { getAssetSymbol, getAssetDecimals
|
|
9
|
+
import { useOpenfort } from '../../Openfort/useOpenfort.js';
|
|
10
|
+
import { SelectTokenContent, EmptyState, ContentWrapper, ChainGroup, ChainGroupHeader, TokenPill, TokenPillSymbol, InfoLink, TokenList, TokenContainer, TokenLeftGroup, TokenInfo, TokenSymbol, TokenName, TokenBalance, TokenLogoArea, TokenLogoImg, TokenLogoFallback, ChainBadge } from '../SelectToken/styles.js';
|
|
11
|
+
import { getAssetSymbol, getAssetDecimals } from '../Send/utils.js';
|
|
8
12
|
|
|
9
13
|
const ZERO = BigInt(0);
|
|
10
14
|
const usdFormatter = new Intl.NumberFormat('en-US', {
|
|
@@ -13,53 +17,128 @@ const usdFormatter = new Intl.NumberFormat('en-US', {
|
|
|
13
17
|
minimumFractionDigits: 2,
|
|
14
18
|
maximumFractionDigits: 2,
|
|
15
19
|
});
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
20
|
+
const priceFormatter = new Intl.NumberFormat('en-US', {
|
|
21
|
+
style: 'currency',
|
|
22
|
+
currency: 'USD',
|
|
23
|
+
minimumFractionDigits: 2,
|
|
24
|
+
maximumFractionDigits: 4,
|
|
25
|
+
});
|
|
26
|
+
function getTokenLogoUrl(token) {
|
|
27
|
+
var _a;
|
|
28
|
+
const symbol = getAssetSymbol(token).toUpperCase();
|
|
29
|
+
return (_a = TOKEN_LOGO[symbol]) !== null && _a !== void 0 ? _a : null;
|
|
30
|
+
}
|
|
31
|
+
function TokenLogo({ token }) {
|
|
32
|
+
const [imgError, setImgError] = useState(false);
|
|
33
|
+
const symbol = getAssetSymbol(token);
|
|
34
|
+
const logoUrl = getTokenLogoUrl(token);
|
|
35
|
+
return (jsxs(TokenLogoArea, { children: [logoUrl && !imgError ? (jsx(TokenLogoImg, { src: logoUrl, alt: symbol, onError: () => setImgError(true) })) : (jsx(TokenLogoFallback, { "$bg": symbolToColor(symbol), children: symbol.charAt(0).toUpperCase() })), jsx(ChainBadge, { children: jsx(Chain, { id: token.chainId, unsupported: false, size: 14 }) })] }));
|
|
36
|
+
}
|
|
37
|
+
function renderTokenRow(token) {
|
|
38
|
+
var _a, _b, _c, _d;
|
|
39
|
+
const key = token.type === 'erc20' ? `${token.chainId}-${token.address}` : `${token.chainId}-native`;
|
|
40
|
+
const displaySymbol = getAssetSymbol(token);
|
|
41
|
+
const displayName = ((_a = token.metadata) === null || _a === void 0 ? void 0 : _a.name) || displaySymbol || 'Unknown Token';
|
|
42
|
+
const decimals = getAssetDecimals(token);
|
|
43
|
+
const pricePerToken = (_c = (_b = token.metadata) === null || _b === void 0 ? void 0 : _b.fiat) === null || _c === void 0 ? void 0 : _c.value;
|
|
44
|
+
let usdValue = null;
|
|
45
|
+
let balanceNum = '';
|
|
46
|
+
let priceDisplay = null;
|
|
47
|
+
const isBalanceLoaded = token.balance !== undefined;
|
|
48
|
+
const hasZeroBalance = isBalanceLoaded && ((_d = token.balance) !== null && _d !== void 0 ? _d : ZERO) <= ZERO;
|
|
49
|
+
if (hasZeroBalance)
|
|
50
|
+
return null;
|
|
51
|
+
if (isBalanceLoaded && token.balance !== undefined) {
|
|
52
|
+
const amount = parseFloat(formatUnits(token.balance, decimals));
|
|
53
|
+
if (Number.isFinite(amount)) {
|
|
54
|
+
balanceNum = `${amount.toLocaleString('en-US', { minimumFractionDigits: 0, maximumFractionDigits: 4 })} ${displaySymbol}`;
|
|
55
|
+
if (pricePerToken !== undefined) {
|
|
56
|
+
const totalUsd = amount * pricePerToken;
|
|
57
|
+
if (totalUsd >= 0.01) {
|
|
58
|
+
usdValue = usdFormatter.format(totalUsd);
|
|
59
|
+
}
|
|
60
|
+
else if (totalUsd > 0) {
|
|
61
|
+
usdValue = '<$0.01';
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
usdValue = usdFormatter.format(0);
|
|
65
|
+
}
|
|
66
|
+
priceDisplay = `@${priceFormatter.format(pricePerToken)}`;
|
|
24
67
|
}
|
|
25
|
-
return jsx(EmptyState, { children: "No supported tokens found for this network yet." });
|
|
26
68
|
}
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
};
|
|
62
|
-
|
|
69
|
+
}
|
|
70
|
+
return (jsxs(TokenContainer, { children: [jsxs(TokenLeftGroup, { children: [jsx(TokenLogo, { token: token }), jsxs(TokenInfo, { style: { textAlign: 'left' }, children: [jsx(TokenSymbol, { children: displayName }), jsx(TokenName, { children: balanceNum || 'Loading...' })] })] }), jsxs(TokenInfo, { children: [usdValue ? jsx(TokenBalance, { children: usdValue }) : null, priceDisplay ? jsx(TokenName, { style: { textAlign: 'end' }, children: priceDisplay }) : null] })] }, key));
|
|
71
|
+
}
|
|
72
|
+
const PILL_LOGO_SIZE = 16;
|
|
73
|
+
function PillLogo({ symbol }) {
|
|
74
|
+
var _a;
|
|
75
|
+
const [imgError, setImgError] = useState(false);
|
|
76
|
+
const url = (_a = TOKEN_LOGO[symbol.toUpperCase()]) !== null && _a !== void 0 ? _a : null;
|
|
77
|
+
if (!url || imgError) {
|
|
78
|
+
return (jsx("span", { style: {
|
|
79
|
+
width: PILL_LOGO_SIZE,
|
|
80
|
+
height: PILL_LOGO_SIZE,
|
|
81
|
+
borderRadius: '50%',
|
|
82
|
+
background: symbolToColor(symbol),
|
|
83
|
+
display: 'inline-flex',
|
|
84
|
+
alignItems: 'center',
|
|
85
|
+
justifyContent: 'center',
|
|
86
|
+
fontSize: 9,
|
|
87
|
+
fontWeight: 700,
|
|
88
|
+
color: '#fff',
|
|
89
|
+
flexShrink: 0,
|
|
90
|
+
}, children: symbol.charAt(0).toUpperCase() }));
|
|
91
|
+
}
|
|
92
|
+
return (jsx("img", { src: url, alt: symbol, onError: () => setImgError(true), style: {
|
|
93
|
+
width: PILL_LOGO_SIZE,
|
|
94
|
+
height: PILL_LOGO_SIZE,
|
|
95
|
+
borderRadius: '50%',
|
|
96
|
+
objectFit: 'cover',
|
|
97
|
+
flexShrink: 0,
|
|
98
|
+
} }));
|
|
99
|
+
}
|
|
100
|
+
const AssetInventory = () => {
|
|
101
|
+
var _a;
|
|
102
|
+
const { data, multiChain, isLoading: isBalancesLoading } = useEthereumWalletAssets({ multiChain: true });
|
|
103
|
+
const { triggerResize, chains } = useOpenfort();
|
|
104
|
+
const [showDetails, setShowDetails] = useState(false);
|
|
105
|
+
useEffect(() => {
|
|
106
|
+
if (!isBalancesLoading)
|
|
107
|
+
triggerResize();
|
|
108
|
+
}, [isBalancesLoading]);
|
|
109
|
+
useEffect(() => {
|
|
110
|
+
triggerResize();
|
|
111
|
+
}, [showDetails]);
|
|
112
|
+
const tokens = (_a = (multiChain ? data : null)) !== null && _a !== void 0 ? _a : [];
|
|
113
|
+
const hasBalance = tokens.some((t) => t.balance > ZERO);
|
|
114
|
+
const chainNameMap = useMemo(() => {
|
|
115
|
+
const map = new Map();
|
|
116
|
+
for (const c of chains)
|
|
117
|
+
map.set(c.id, c.name);
|
|
118
|
+
return map;
|
|
119
|
+
}, [chains]);
|
|
120
|
+
const groupedByChain = useMemo(() => {
|
|
121
|
+
var _a;
|
|
122
|
+
const groups = new Map();
|
|
123
|
+
for (const t of tokens) {
|
|
124
|
+
if (!groups.has(t.chainId))
|
|
125
|
+
groups.set(t.chainId, []);
|
|
126
|
+
groups.get(t.chainId).push({
|
|
127
|
+
symbol: getAssetSymbol(t),
|
|
128
|
+
name: ((_a = t.metadata) === null || _a === void 0 ? void 0 : _a.name) || getAssetSymbol(t),
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
return groups;
|
|
132
|
+
}, [tokens]);
|
|
133
|
+
if (isBalancesLoading) {
|
|
134
|
+
return (jsxs(SelectTokenContent, { children: [jsx(ModalHeading, { children: "Your assets" }), jsx(EmptyState, { children: "Loading balances..." })] }));
|
|
135
|
+
}
|
|
136
|
+
if (showDetails) {
|
|
137
|
+
return (jsxs(SelectTokenContent, { onBack: () => {
|
|
138
|
+
setShowDetails(false);
|
|
139
|
+
}, children: [jsx(ModalHeading, { children: "Configured assets" }), jsx(motion.div, { initial: { opacity: 0, scale: 1.1 }, animate: { opacity: 1, scale: 1 }, transition: { duration: 0.2, ease: [0.26, 0.08, 0.25, 1] }, style: { display: 'flex', flexDirection: 'column', flex: 1, minHeight: 0 }, children: jsx(ContentWrapper, { style: { overflowY: 'auto', maxHeight: 400 }, children: Array.from(groupedByChain.entries()).map(([chainId, assets]) => (jsxs(ChainGroup, { children: [jsxs(ChainGroupHeader, { children: [jsx(Chain, { id: chainId, unsupported: false, size: 18 }), chainNameMap.get(chainId) || `Chain ${chainId}`] }), assets.map((a) => (jsxs(TokenPill, { children: [jsx(PillLogo, { symbol: a.symbol }), jsx(TokenPillSymbol, { children: a.symbol }), a.name !== a.symbol && a.name] }, `${chainId}-${a.symbol}`)))] }, chainId))) }) })] }, "details"));
|
|
140
|
+
}
|
|
141
|
+
return (jsxs(SelectTokenContent, { children: [jsx(ModalHeading, { children: "Your assets" }), jsxs(ContentWrapper, { children: [jsxs(InfoLink, { type: "button", onClick: () => setShowDetails(true), children: [jsxs("svg", { role: "img", "aria-label": "Info", width: "12", height: "12", viewBox: "0 0 14 14", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [jsx("circle", { cx: "7", cy: "7", r: "6", stroke: "currentColor", strokeWidth: "1.25" }), jsx("path", { d: "M7 6.25V10", stroke: "currentColor", strokeWidth: "1.25", strokeLinecap: "round" }), jsx("circle", { cx: "7", cy: "4.25", r: "0.75", fill: "currentColor" })] }), "Only configured chains and tokens are shown"] }), jsx(TokenList, { children: hasBalance ? tokens.map(renderTokenRow) : jsx(EmptyState, { children: "No assets found" }) })] })] }, "assets"));
|
|
63
142
|
};
|
|
64
143
|
|
|
65
144
|
export { AssetInventory };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -63,13 +63,14 @@ const OtherMethod = ({ currentMethod, onChangeMethod, }) => {
|
|
|
63
63
|
};
|
|
64
64
|
const CreateWalletAutomaticRecovery = ({ onBack, logoutOnBack, }) => {
|
|
65
65
|
var _a;
|
|
66
|
-
const { embeddedState } = useOpenfortCore();
|
|
66
|
+
const { embeddedState, isLoadingAccounts } = useOpenfortCore();
|
|
67
67
|
const { setRoute, triggerResize, walletConfig } = useOpenfort();
|
|
68
68
|
const [recoveryError, setRecoveryError] = useState(null);
|
|
69
69
|
const { create } = useEthereumEmbeddedWallet();
|
|
70
70
|
const { isEnabled: isWalletRecoveryOTPEnabled, requestOTP } = useRecoveryOTP();
|
|
71
71
|
const [shouldCreateWallet, setShouldCreateWallet] = useState(false);
|
|
72
72
|
const isCreatingRef = useRef(false);
|
|
73
|
+
const hasAttemptedCreationRef = useRef(false);
|
|
73
74
|
const [needsOTP, setNeedsOTP] = useState(false);
|
|
74
75
|
const [otpResponse, setOtpResponse] = useState(null);
|
|
75
76
|
const [otpStatus, setOtpStatus] = useState('idle');
|
|
@@ -100,6 +101,10 @@ const CreateWalletAutomaticRecovery = ({ onBack, logoutOnBack, }) => {
|
|
|
100
101
|
return;
|
|
101
102
|
if (isCreatingRef.current)
|
|
102
103
|
return;
|
|
104
|
+
// Wait for the state machine's fetchEmbeddedAccounts to finish before
|
|
105
|
+
// calling create() — concurrent SDK operations corrupt shared state.
|
|
106
|
+
if (isLoadingAccounts)
|
|
107
|
+
return;
|
|
103
108
|
isCreatingRef.current = true;
|
|
104
109
|
(async () => {
|
|
105
110
|
logger.log('Creating wallet Automatic recover');
|
|
@@ -132,12 +137,18 @@ const CreateWalletAutomaticRecovery = ({ onBack, logoutOnBack, }) => {
|
|
|
132
137
|
}
|
|
133
138
|
triggerResize();
|
|
134
139
|
})();
|
|
135
|
-
}, [shouldCreateWallet, create, isWalletRecoveryOTPEnabled, requestOTP, triggerResize]);
|
|
140
|
+
}, [shouldCreateWallet, create, isWalletRecoveryOTPEnabled, requestOTP, triggerResize, isLoadingAccounts]);
|
|
136
141
|
useEffect(() => {
|
|
137
142
|
if (embeddedState !== EmbeddedState.EMBEDDED_SIGNER_NOT_CONFIGURED)
|
|
138
143
|
return;
|
|
139
144
|
if ((walletConfig === null || walletConfig === void 0 ? void 0 : walletConfig.connectOnLogin) === false)
|
|
140
145
|
return;
|
|
146
|
+
// Guard against retry loop: when create() fails the SDK cycles the
|
|
147
|
+
// embeddedState back to EMBEDDED_SIGNER_NOT_CONFIGURED which re-triggers
|
|
148
|
+
// this effect. Only attempt creation once — the user can retry manually.
|
|
149
|
+
if (hasAttemptedCreationRef.current)
|
|
150
|
+
return;
|
|
151
|
+
hasAttemptedCreationRef.current = true;
|
|
141
152
|
setShouldCreateWallet(true);
|
|
142
153
|
}, [embeddedState, walletConfig === null || walletConfig === void 0 ? void 0 : walletConfig.connectOnLogin]);
|
|
143
154
|
const handleResendClick = useCallback(() => {
|
|
@@ -160,13 +171,28 @@ const CreateWalletAutomaticRecovery = ({ onBack, logoutOnBack, }) => {
|
|
|
160
171
|
logo: (otpResponse === null || otpResponse === void 0 ? void 0 : otpResponse.sentTo) === 'phone' ? jsx(PhoneIcon, {}) : jsx(EmailIcon, {}),
|
|
161
172
|
} }), jsxs(ModalBody, { children: [jsxs(Body, { children: ["Please check ", jsx("b", { children: (otpResponse === null || otpResponse === void 0 ? void 0 : otpResponse.sentTo) === 'phone' ? otpResponse === null || otpResponse === void 0 ? void 0 : otpResponse.phone : otpResponse === null || otpResponse === void 0 ? void 0 : otpResponse.email }), " and enter your code below."] }), jsx(OtpInputStandalone, { length: 9, scale: "80%", onComplete: handleCompleteOtp, isLoading: otpStatus === 'loading', isError: otpStatus === 'error', isSuccess: otpStatus === 'success' }), jsxs(ResultContainer, { children: [otpStatus === 'success' && jsx(ModalBody, { "$valid": true, children: "Code verified successfully!" }), otpStatus === 'error' && jsx(ModalBody, { "$error": true, children: error || 'Invalid code. Please try again.' })] }), jsxs(FooterTextButton, { children: ["Didn't receive the code?", ' ', jsx(FooterButtonText, { type: "button", onClick: handleResendClick, disabled: isResendDisabled, children: sendButtonText })] })] })] }));
|
|
162
173
|
}
|
|
163
|
-
|
|
174
|
+
// When connectOnLogin is false, auto-creation is skipped — show a manual
|
|
175
|
+
// trigger instead of an infinite spinner.
|
|
176
|
+
if (!shouldCreateWallet && !isCreatingRef.current && !recoveryError) {
|
|
177
|
+
return (jsxs(PageContent, { onBack: onBack, logoutOnBack: logoutOnBack, children: [jsx(ModalHeading, { children: "Create wallet" }), jsx(ModalBody, { style: { textAlign: 'center' }, children: "Create an embedded wallet to get started." }), jsx(Button, { onClick: () => {
|
|
178
|
+
hasAttemptedCreationRef.current = false;
|
|
179
|
+
setShouldCreateWallet(true);
|
|
180
|
+
}, children: "Create wallet" })] }));
|
|
181
|
+
}
|
|
182
|
+
return (jsx(PageContent, { onBack: onBack, logoutOnBack: logoutOnBack, children: jsx(Loader, { isError: !!recoveryError, header: recoveryError ? 'Error creating wallet.' : `Creating wallet...`, description: recoveryError ? recoveryError.message : undefined, onRetry: recoveryError
|
|
183
|
+
? () => {
|
|
184
|
+
hasAttemptedCreationRef.current = false;
|
|
185
|
+
setRecoveryError(null);
|
|
186
|
+
setShouldCreateWallet(true);
|
|
187
|
+
}
|
|
188
|
+
: undefined }) }));
|
|
164
189
|
};
|
|
165
190
|
const CreateWalletPasskeyRecovery = ({ onChangeMethod, onBack, logoutOnBack, }) => {
|
|
166
191
|
const { triggerResize, setRoute, walletConfig } = useOpenfort();
|
|
167
192
|
const { create } = useEthereumEmbeddedWallet();
|
|
168
193
|
const [shouldCreateWallet, setShouldCreateWallet] = useState(false);
|
|
169
194
|
const isCreatingRef = useRef(false);
|
|
195
|
+
const hasAttemptedCreationRef = useRef(false);
|
|
170
196
|
const [recoveryError, setRecoveryError] = useState(null);
|
|
171
197
|
const { embeddedState } = useOpenfortCore();
|
|
172
198
|
useEffect(() => {
|
|
@@ -197,6 +223,9 @@ const CreateWalletPasskeyRecovery = ({ onChangeMethod, onBack, logoutOnBack, })
|
|
|
197
223
|
return;
|
|
198
224
|
if ((walletConfig === null || walletConfig === void 0 ? void 0 : walletConfig.connectOnLogin) === false)
|
|
199
225
|
return;
|
|
226
|
+
if (hasAttemptedCreationRef.current)
|
|
227
|
+
return;
|
|
228
|
+
hasAttemptedCreationRef.current = true;
|
|
200
229
|
setShouldCreateWallet(true);
|
|
201
230
|
}, [embeddedState, walletConfig === null || walletConfig === void 0 ? void 0 : walletConfig.connectOnLogin]);
|
|
202
231
|
useEffect(() => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -64,10 +64,11 @@ const LoadWallets = () => {
|
|
|
64
64
|
}
|
|
65
65
|
logger.log('User wallets loaded:', wallets.length);
|
|
66
66
|
if (wallets.length === 0) {
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
67
|
+
// Always show the create wallet page when no wallets exist.
|
|
68
|
+
// connectOnLogin only controls whether creation starts automatically
|
|
69
|
+
// (handled inside CreateWalletAutomaticRecovery), not whether the
|
|
70
|
+
// page is shown — routing to CONNECTED with 0 wallets would show a
|
|
71
|
+
// broken "Connect wallet" button aimed at external wagmi wallets.
|
|
71
72
|
setRoute(createRoute(chainType));
|
|
72
73
|
return;
|
|
73
74
|
}
|
|
@@ -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,5 @@
|
|
|
1
1
|
import { jsx } from 'react/jsx-runtime';
|
|
2
|
-
import { ChainTypeEnum } from '@openfort/openfort-js';
|
|
2
|
+
import { ChainTypeEnum, EmbeddedState } from '@openfort/openfort-js';
|
|
3
3
|
import React, { useEffect } from 'react';
|
|
4
4
|
import { useEthereumEmbeddedWallet } from '../../../ethereum/hooks/useEthereumEmbeddedWallet.js';
|
|
5
5
|
import { useOpenfortCore } from '../../../openfort/useOpenfort.js';
|
|
@@ -11,7 +11,7 @@ import { PageContent } from '../../PageContent/index.js';
|
|
|
11
11
|
|
|
12
12
|
const Loading = () => {
|
|
13
13
|
const { setRoute, walletConfig } = useOpenfort();
|
|
14
|
-
const { user, isLoadingAccounts, needsRecovery } = useOpenfortCore();
|
|
14
|
+
const { user, isLoadingAccounts, isLoading, needsRecovery, embeddedState } = useOpenfortCore();
|
|
15
15
|
const { chainType } = useOpenfortCore();
|
|
16
16
|
// Use chain-specific hooks
|
|
17
17
|
const ethereumWallet = useEthereumEmbeddedWallet();
|
|
@@ -24,7 +24,13 @@ const Loading = () => {
|
|
|
24
24
|
useEffect(() => {
|
|
25
25
|
if (isFirstFrame)
|
|
26
26
|
return;
|
|
27
|
-
|
|
27
|
+
// Wait for the SDK to settle. After storeCredentials the embedded state
|
|
28
|
+
// briefly stays UNAUTHENTICATED/NONE while the SDK processes the token.
|
|
29
|
+
// Routing to PROVIDERS here would abort the auth flow.
|
|
30
|
+
if (embeddedState === EmbeddedState.NONE || embeddedState === EmbeddedState.UNAUTHENTICATED)
|
|
31
|
+
return;
|
|
32
|
+
// Also wait while accounts or user are still loading.
|
|
33
|
+
if (isLoadingAccounts || isLoading)
|
|
28
34
|
return;
|
|
29
35
|
else if (!user)
|
|
30
36
|
setRoute(routes.PROVIDERS);
|
|
@@ -42,7 +48,7 @@ const Loading = () => {
|
|
|
42
48
|
}
|
|
43
49
|
else
|
|
44
50
|
setRoute(routes.CONNECTED);
|
|
45
|
-
}, [isLoadingAccounts, user, address, needsRecovery, isFirstFrame, retryCount]);
|
|
51
|
+
}, [embeddedState, isLoadingAccounts, isLoading, user, address, needsRecovery, isFirstFrame, retryCount]);
|
|
46
52
|
// Retry every 250ms
|
|
47
53
|
useEffect(() => {
|
|
48
54
|
const interval = setInterval(() => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -12,4 +12,17 @@ export declare const TokenInfo: import("styled-components").StyledComponent<"div
|
|
|
12
12
|
export declare const TokenSymbol: import("styled-components").StyledComponent<"span", any, {}, never>;
|
|
13
13
|
export declare const TokenName: import("styled-components").StyledComponent<"span", any, {}, never>;
|
|
14
14
|
export declare const TokenBalance: import("styled-components").StyledComponent<"span", any, {}, never>;
|
|
15
|
+
export declare const TokenLeftGroup: import("styled-components").StyledComponent<"div", any, {}, never>;
|
|
16
|
+
export declare const TokenLogoArea: import("styled-components").StyledComponent<"div", any, {}, never>;
|
|
17
|
+
export declare const TokenLogoFallback: import("styled-components").StyledComponent<"div", any, {
|
|
18
|
+
$bg: string;
|
|
19
|
+
}, never>;
|
|
20
|
+
export declare const TokenLogoImg: import("styled-components").StyledComponent<"img", any, {}, never>;
|
|
21
|
+
export declare const ChainBadge: import("styled-components").StyledComponent<"div", any, {}, never>;
|
|
15
22
|
export declare const EmptyState: import("styled-components").StyledComponent<"div", any, {}, never>;
|
|
23
|
+
export declare const InfoLink: import("styled-components").StyledComponent<"button", any, {}, never>;
|
|
24
|
+
export declare const ContentWrapper: import("styled-components").StyledComponent<"div", any, {}, never>;
|
|
25
|
+
export declare const ChainGroup: import("styled-components").StyledComponent<"div", any, {}, never>;
|
|
26
|
+
export declare const ChainGroupHeader: import("styled-components").StyledComponent<"div", any, {}, never>;
|
|
27
|
+
export declare const TokenPill: import("styled-components").StyledComponent<"div", any, {}, never>;
|
|
28
|
+
export declare const TokenPillSymbol: import("styled-components").StyledComponent<"span", any, {}, never>;
|
|
@@ -67,12 +67,114 @@ const TokenBalance = styled.span `
|
|
|
67
67
|
font-weight: 600;
|
|
68
68
|
color: var(--ck-body-color);
|
|
69
69
|
`;
|
|
70
|
+
const TokenLeftGroup = styled.div `
|
|
71
|
+
display: flex;
|
|
72
|
+
align-items: center;
|
|
73
|
+
gap: 10px;
|
|
74
|
+
min-width: 0;
|
|
75
|
+
`;
|
|
76
|
+
const TokenLogoArea = styled.div `
|
|
77
|
+
position: relative;
|
|
78
|
+
width: 40px;
|
|
79
|
+
height: 40px;
|
|
80
|
+
flex-shrink: 0;
|
|
81
|
+
`;
|
|
82
|
+
const TokenLogoFallback = styled.div `
|
|
83
|
+
width: 40px;
|
|
84
|
+
height: 40px;
|
|
85
|
+
border-radius: 50%;
|
|
86
|
+
background: ${(p) => p.$bg};
|
|
87
|
+
display: flex;
|
|
88
|
+
align-items: center;
|
|
89
|
+
justify-content: center;
|
|
90
|
+
font-size: 16px;
|
|
91
|
+
font-weight: 700;
|
|
92
|
+
color: #fff;
|
|
93
|
+
user-select: none;
|
|
94
|
+
`;
|
|
95
|
+
const TokenLogoImg = styled.img `
|
|
96
|
+
width: 40px;
|
|
97
|
+
height: 40px;
|
|
98
|
+
border-radius: 50%;
|
|
99
|
+
object-fit: cover;
|
|
100
|
+
`;
|
|
101
|
+
const ChainBadge = styled.div `
|
|
102
|
+
position: absolute;
|
|
103
|
+
bottom: -2px;
|
|
104
|
+
right: -2px;
|
|
105
|
+
width: 18px;
|
|
106
|
+
height: 18px;
|
|
107
|
+
border-radius: 50%;
|
|
108
|
+
background: var(--ck-body-background);
|
|
109
|
+
display: flex;
|
|
110
|
+
align-items: center;
|
|
111
|
+
justify-content: center;
|
|
112
|
+
box-shadow: 0 0 0 0.7px var(--ck-body-background);
|
|
113
|
+
`;
|
|
70
114
|
const EmptyState = styled.div `
|
|
71
115
|
margin-top: 28px;
|
|
72
116
|
font-size: 13px;
|
|
73
117
|
color: var(--ck-body-color-muted);
|
|
74
118
|
text-align: center;
|
|
75
119
|
`;
|
|
120
|
+
const InfoLink = styled.button `
|
|
121
|
+
all: unset;
|
|
122
|
+
display: flex;
|
|
123
|
+
align-items: center;
|
|
124
|
+
justify-content: center;
|
|
125
|
+
gap: 5px;
|
|
126
|
+
width: 100%;
|
|
127
|
+
font-size: 13px;
|
|
128
|
+
font-weight: 400;
|
|
129
|
+
color: var(--ck-body-color-muted, rgba(255, 255, 255, 0.4));
|
|
130
|
+
padding: 0 0 8px;
|
|
131
|
+
cursor: pointer;
|
|
132
|
+
transition: color 0.15s ease;
|
|
133
|
+
svg { opacity: 0.6; }
|
|
134
|
+
&:hover {
|
|
135
|
+
color: var(--ck-body-color, #fff);
|
|
136
|
+
svg { opacity: 1; }
|
|
137
|
+
}
|
|
138
|
+
`;
|
|
139
|
+
const ContentWrapper = styled.div `
|
|
140
|
+
position: relative;
|
|
141
|
+
display: flex;
|
|
142
|
+
flex-direction: column;
|
|
143
|
+
flex: 1;
|
|
144
|
+
min-height: 0;
|
|
145
|
+
`;
|
|
146
|
+
const ChainGroup = styled.div `
|
|
147
|
+
&:not(:first-child) {
|
|
148
|
+
margin-top: 16px;
|
|
149
|
+
}
|
|
150
|
+
`;
|
|
151
|
+
const ChainGroupHeader = styled.div `
|
|
152
|
+
display: flex;
|
|
153
|
+
align-items: center;
|
|
154
|
+
gap: 8px;
|
|
155
|
+
font-size: 14px;
|
|
156
|
+
font-weight: 600;
|
|
157
|
+
color: var(--ck-body-color, #fff);
|
|
158
|
+
margin-bottom: 8px;
|
|
159
|
+
`;
|
|
160
|
+
const TokenPill = styled.div `
|
|
161
|
+
display: flex;
|
|
162
|
+
align-items: center;
|
|
163
|
+
gap: 6px;
|
|
164
|
+
padding: 6px 10px;
|
|
165
|
+
border-radius: 10px;
|
|
166
|
+
background: var(--ck-body-background-secondary, rgba(255, 255, 255, 0.06));
|
|
167
|
+
font-size: 13px;
|
|
168
|
+
font-weight: 500;
|
|
169
|
+
color: var(--ck-body-color-muted, rgba(255, 255, 255, 0.6));
|
|
170
|
+
&:not(:last-child) {
|
|
171
|
+
margin-bottom: 4px;
|
|
172
|
+
}
|
|
173
|
+
`;
|
|
174
|
+
const TokenPillSymbol = styled.span `
|
|
175
|
+
color: var(--ck-body-color, #fff);
|
|
176
|
+
font-weight: 600;
|
|
177
|
+
`;
|
|
76
178
|
|
|
77
|
-
export { EmptyState, SelectTokenContent, TokenBalance, TokenButton, TokenContainer, TokenInfo, TokenList, TokenName, TokenSymbol };
|
|
179
|
+
export { ChainBadge, ChainGroup, ChainGroupHeader, ContentWrapper, EmptyState, InfoLink, SelectTokenContent, TokenBalance, TokenButton, TokenContainer, TokenInfo, TokenLeftGroup, TokenList, TokenLogoArea, TokenLogoFallback, TokenLogoImg, TokenName, TokenPill, TokenPillSymbol, TokenSymbol };
|
|
78
180
|
//# sourceMappingURL=styles.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"styles.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"styles.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -116,6 +116,7 @@ const SendConfirmation = () => {
|
|
|
116
116
|
const [isPollingBalance, setIsPollingBalance] = useState(false);
|
|
117
117
|
const originalBalanceRef = useRef(undefined);
|
|
118
118
|
const pollingIntervalRef = useRef(null);
|
|
119
|
+
const submittingRef = useRef(false);
|
|
119
120
|
// Inline transaction state management (replaces useEthereumSendTransaction + useEthereumWriteContract)
|
|
120
121
|
const [nativeTxHash, setNativeTxHash] = useState(undefined);
|
|
121
122
|
const [isNativePending, setIsNativePending] = useState(false);
|
|
@@ -255,8 +256,11 @@ const SendConfirmation = () => {
|
|
|
255
256
|
}
|
|
256
257
|
}, [isPollingBalance, currentBalance]);
|
|
257
258
|
const handleConfirm = async () => {
|
|
259
|
+
if (submittingRef.current)
|
|
260
|
+
return;
|
|
258
261
|
if (!recipientAddress || !parsedAmount || parsedAmount <= BigInt(0) || insufficientBalance)
|
|
259
262
|
return;
|
|
263
|
+
submittingRef.current = true;
|
|
260
264
|
try {
|
|
261
265
|
if (token.type === 'native') {
|
|
262
266
|
await sendTransactionAsync({
|
|
@@ -278,6 +282,9 @@ const SendConfirmation = () => {
|
|
|
278
282
|
catch (_error) {
|
|
279
283
|
// Errors are surfaced through mutation hooks
|
|
280
284
|
}
|
|
285
|
+
finally {
|
|
286
|
+
submittingRef.current = false;
|
|
287
|
+
}
|
|
281
288
|
};
|
|
282
289
|
const handleCancel = () => {
|
|
283
290
|
// Keep the current token, amount, and recipient when going back - don't reset
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
const TW = 'https://raw.githubusercontent.com/trustwallet/assets/master/blockchains';
|
|
2
|
+
// Unified symbol -> logo URL map (works for both native and ERC20)
|
|
3
|
+
const TOKEN_LOGO = {
|
|
4
|
+
// Native tokens (chain logos from Trust Wallet info/)
|
|
5
|
+
ETH: `${TW}/ethereum/info/logo.png`,
|
|
6
|
+
BNB: `${TW}/smartchain/info/logo.png`,
|
|
7
|
+
TBNB: `${TW}/smartchain/info/logo.png`,
|
|
8
|
+
MATIC: `${TW}/polygon/info/logo.png`,
|
|
9
|
+
POL: `${TW}/polygon/info/logo.png`,
|
|
10
|
+
AVAX: `${TW}/avalanchec/info/logo.png`,
|
|
11
|
+
FTM: `${TW}/fantom/info/logo.png`,
|
|
12
|
+
CELO: `${TW}/celo/info/logo.png`,
|
|
13
|
+
FIL: `${TW}/filecoin/info/logo.png`,
|
|
14
|
+
METIS: `${TW}/metis/info/logo.png`,
|
|
15
|
+
IOTX: `${TW}/iotex/info/logo.png`,
|
|
16
|
+
EVMOS: `${TW}/evmos/info/logo.png`,
|
|
17
|
+
XDAI: `${TW}/xdai/info/logo.png`,
|
|
18
|
+
FLR: `${TW}/flare/info/logo.png`,
|
|
19
|
+
TLOS: `${TW}/telos/info/logo.png`,
|
|
20
|
+
// ERC20 tokens (using mainnet Ethereum addresses)
|
|
21
|
+
USDC: `${TW}/ethereum/assets/0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48/logo.png`,
|
|
22
|
+
USDT: `${TW}/ethereum/assets/0xdAC17F958D2ee523a2206206994597C13D831ec7/logo.png`,
|
|
23
|
+
DAI: `${TW}/ethereum/assets/0x6B175474E89094C44Da98b954EedeAC495271d0F/logo.png`,
|
|
24
|
+
WETH: `${TW}/ethereum/assets/0xC02aaA39b223FE8D0A0e5c4F27eAD9083C756Cc2/logo.png`,
|
|
25
|
+
WBTC: `${TW}/ethereum/assets/0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599/logo.png`,
|
|
26
|
+
LINK: `${TW}/ethereum/assets/0x514910771AF9Ca656af840dff83E8264EcF986CA/logo.png`,
|
|
27
|
+
UNI: `${TW}/ethereum/assets/0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984/logo.png`,
|
|
28
|
+
AAVE: `${TW}/ethereum/assets/0x7Fc66500c84A76Ad7e9c93437bFc5Ac33E2DDaE9/logo.png`,
|
|
29
|
+
MKR: `${TW}/ethereum/assets/0x9f8F72aA9304c8B593d555F12eF6589cC3A579A2/logo.png`,
|
|
30
|
+
CRV: `${TW}/ethereum/assets/0xD533a949740bb3306d119CC777fa900bA034cd52/logo.png`,
|
|
31
|
+
LDO: `${TW}/ethereum/assets/0x5A98FcBEA516Cf06857215779Fd812CA3beF1B32/logo.png`,
|
|
32
|
+
SHIB: `${TW}/ethereum/assets/0x95aD61b0a150d79219dCF64E1E6Cc01f0B64C4cE/logo.png`,
|
|
33
|
+
ARB: `${TW}/arbitrum/assets/0x912CE59144191C1204E64559FE8253a0e49E6548/logo.png`,
|
|
34
|
+
OP: `${TW}/optimism/assets/0x4200000000000000000000000000000000000042/logo.png`,
|
|
35
|
+
STETH: `${TW}/ethereum/assets/0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84/logo.png`,
|
|
36
|
+
CBETH: `${TW}/ethereum/assets/0xBe9895146f7AF43049ca1c1AE358B0541Ea49704/logo.png`,
|
|
37
|
+
RETH: `${TW}/ethereum/assets/0xae78736Cd615f374D3085123A210448E74Fc6393/logo.png`,
|
|
38
|
+
GRT: `${TW}/ethereum/assets/0xc944E90C64B2c07662A292be6244BDf05Cda44a7/logo.png`,
|
|
39
|
+
SNX: `${TW}/ethereum/assets/0xC011a73ee8576Fb46F5E1c5751cA3B9Fe0af2a6F/logo.png`,
|
|
40
|
+
COMP: `${TW}/ethereum/assets/0xc00e94Cb662C3520282E6f5717214004A7f26888/logo.png`,
|
|
41
|
+
PEPE: `${TW}/ethereum/assets/0x6982508145454Ce325dDbE47a25d4ec3d2311933/logo.png`,
|
|
42
|
+
SUSHI: `${TW}/ethereum/assets/0x6B3595068778DD592e39A122f4f5a5cF09C90fE2/logo.png`,
|
|
43
|
+
DYDX: `${TW}/ethereum/assets/0x92D6C1e31e14520e676a687F0a93788B716BEff5/logo.png`,
|
|
44
|
+
BEAM: `${TW}/ethereum/assets/0x62D0A8458eD7719FDAF978fe5929C6D342B0bFcE/logo.png`,
|
|
45
|
+
EUL: `${TW}/ethereum/assets/0xd9Fcd98c322942075A5C3860693e9f4f03AAE07b/logo.png`,
|
|
46
|
+
};
|
|
47
|
+
// Deterministic color from symbol string (only used if no logo is found)
|
|
48
|
+
function symbolToColor(symbol) {
|
|
49
|
+
let hash = 0;
|
|
50
|
+
for (let i = 0; i < symbol.length; i++) {
|
|
51
|
+
hash = symbol.charCodeAt(i) + ((hash << 5) - hash);
|
|
52
|
+
}
|
|
53
|
+
const h = ((hash % 360) + 360) % 360;
|
|
54
|
+
return `hsl(${h}, 55%, 50%)`;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export { TOKEN_LOGO, symbolToColor };
|
|
58
|
+
//# sourceMappingURL=logos.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logos.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -1,29 +1,43 @@
|
|
|
1
|
-
import type { Asset } from '../../components/Openfort/types';
|
|
1
|
+
import type { Asset, MultiChainAsset } from '../../components/Openfort/types';
|
|
2
2
|
import { OpenfortError } from '../../core/errors';
|
|
3
3
|
import type { EthereumConfig } from '../../ethereum/types';
|
|
4
4
|
type UseEthereumWalletAssetsOptions = {
|
|
5
5
|
assets?: EthereumConfig['assets'];
|
|
6
|
+
/** When true, fetches assets for all configured chains and returns MultiChainAsset[]. */
|
|
7
|
+
multiChain?: boolean;
|
|
6
8
|
staleTime?: number;
|
|
7
9
|
};
|
|
10
|
+
type WalletAssetsReturnBase = {
|
|
11
|
+
isLoading: boolean;
|
|
12
|
+
isError: boolean;
|
|
13
|
+
isSuccess: boolean;
|
|
14
|
+
isIdle: boolean;
|
|
15
|
+
error: OpenfortError | undefined;
|
|
16
|
+
refetch: () => Promise<unknown>;
|
|
17
|
+
};
|
|
18
|
+
type UseEthereumWalletAssetsResult = (WalletAssetsReturnBase & {
|
|
19
|
+
multiChain: true;
|
|
20
|
+
data: readonly MultiChainAsset[] | null;
|
|
21
|
+
}) | (WalletAssetsReturnBase & {
|
|
22
|
+
multiChain: false;
|
|
23
|
+
data: readonly Asset[] | null;
|
|
24
|
+
});
|
|
8
25
|
/**
|
|
9
26
|
* Returns wallet assets (tokens, NFTs) for the connected Ethereum address.
|
|
10
27
|
* Uses ERC-7811 via Openfort's authenticated RPC proxy.
|
|
11
28
|
*
|
|
12
|
-
*
|
|
29
|
+
* When `multiChain` is true, fetches assets across all configured chains
|
|
30
|
+
* via `wallet_getAssets` and returns `MultiChainAsset[]` (assets tagged with `chainId`).
|
|
31
|
+
*
|
|
32
|
+
* @param options - Optional custom assets config, multiChain flag, and staleTime
|
|
13
33
|
* @returns assets, isLoading, error, refetch
|
|
14
34
|
*
|
|
15
35
|
* @example
|
|
16
36
|
* ```tsx
|
|
17
37
|
* const { data: assets, isLoading } = useEthereumWalletAssets()
|
|
38
|
+
* // Multi-chain:
|
|
39
|
+
* const { data, multiChain } = useEthereumWalletAssets({ multiChain: true })
|
|
18
40
|
* ```
|
|
19
41
|
*/
|
|
20
|
-
export declare const useEthereumWalletAssets: ({ assets: hookCustomAssets, staleTime, }?: UseEthereumWalletAssetsOptions) =>
|
|
21
|
-
data: readonly Asset[] | null;
|
|
22
|
-
isLoading: boolean;
|
|
23
|
-
isError: boolean;
|
|
24
|
-
isSuccess: boolean;
|
|
25
|
-
isIdle: boolean;
|
|
26
|
-
error: OpenfortError | undefined;
|
|
27
|
-
refetch: () => Promise<readonly Asset[] | undefined>;
|
|
28
|
-
};
|
|
42
|
+
export declare const useEthereumWalletAssets: ({ assets: hookCustomAssets, multiChain, staleTime, }?: UseEthereumWalletAssetsOptions) => UseEthereumWalletAssetsResult;
|
|
29
43
|
export {};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useCallback, useMemo } from 'react';
|
|
2
|
-
import { custom, createWalletClient,
|
|
2
|
+
import { numberToHex, custom, createWalletClient, formatUnits } from 'viem';
|
|
3
3
|
import { erc7811Actions } from 'viem/experimental';
|
|
4
4
|
import { useOpenfort } from '../../components/Openfort/useOpenfort.js';
|
|
5
5
|
import { OpenfortError, OpenfortReactErrorType } from '../../types.js';
|
|
@@ -8,20 +8,34 @@ import { openfortKeys } from '../../query/queryKeys.js';
|
|
|
8
8
|
import { useAsyncData } from '../../shared/hooks/useAsyncData.js';
|
|
9
9
|
import { useEthereumEmbeddedWallet } from './useEthereumEmbeddedWallet.js';
|
|
10
10
|
|
|
11
|
+
function getUsdValue(asset) {
|
|
12
|
+
var _a, _b, _c;
|
|
13
|
+
const fiat = (_a = asset.metadata) === null || _a === void 0 ? void 0 : _a.fiat;
|
|
14
|
+
if (!(fiat === null || fiat === void 0 ? void 0 : fiat.value) || asset.balance === undefined)
|
|
15
|
+
return 0;
|
|
16
|
+
const decimals = (_c = (_b = asset.metadata) === null || _b === void 0 ? void 0 : _b.decimals) !== null && _c !== void 0 ? _c : 18;
|
|
17
|
+
const amount = Number.parseFloat(formatUnits(asset.balance, decimals));
|
|
18
|
+
return Number.isFinite(amount) ? amount * fiat.value : 0;
|
|
19
|
+
}
|
|
11
20
|
/**
|
|
12
21
|
* Returns wallet assets (tokens, NFTs) for the connected Ethereum address.
|
|
13
22
|
* Uses ERC-7811 via Openfort's authenticated RPC proxy.
|
|
14
23
|
*
|
|
15
|
-
*
|
|
24
|
+
* When `multiChain` is true, fetches assets across all configured chains
|
|
25
|
+
* via `wallet_getAssets` and returns `MultiChainAsset[]` (assets tagged with `chainId`).
|
|
26
|
+
*
|
|
27
|
+
* @param options - Optional custom assets config, multiChain flag, and staleTime
|
|
16
28
|
* @returns assets, isLoading, error, refetch
|
|
17
29
|
*
|
|
18
30
|
* @example
|
|
19
31
|
* ```tsx
|
|
20
32
|
* const { data: assets, isLoading } = useEthereumWalletAssets()
|
|
33
|
+
* // Multi-chain:
|
|
34
|
+
* const { data, multiChain } = useEthereumWalletAssets({ multiChain: true })
|
|
21
35
|
* ```
|
|
22
36
|
*/
|
|
23
|
-
const useEthereumWalletAssets = ({ assets: hookCustomAssets, staleTime = 30000, } = {}) => {
|
|
24
|
-
var _a;
|
|
37
|
+
const useEthereumWalletAssets = ({ assets: hookCustomAssets, multiChain = false, staleTime = 30000, } = {}) => {
|
|
38
|
+
var _a, _b;
|
|
25
39
|
const wallet = useEthereumEmbeddedWallet();
|
|
26
40
|
const isConnected = wallet.status === 'connected';
|
|
27
41
|
const address = isConnected ? wallet.address : undefined;
|
|
@@ -29,6 +43,7 @@ const useEthereumWalletAssets = ({ assets: hookCustomAssets, staleTime = 30000,
|
|
|
29
43
|
const { walletConfig, publishableKey, overrides, thirdPartyAuth, chains } = useOpenfort();
|
|
30
44
|
const { getAccessToken } = useUser();
|
|
31
45
|
const chain = chains.find((c) => c.id === chainId);
|
|
46
|
+
const backendUrl = (overrides === null || overrides === void 0 ? void 0 : overrides.backendUrl) || 'https://api.openfort.io';
|
|
32
47
|
const buildHeaders = useCallback(async () => {
|
|
33
48
|
if (thirdPartyAuth) {
|
|
34
49
|
const accessToken = await thirdPartyAuth.getAccessToken();
|
|
@@ -51,10 +66,25 @@ const useEthereumWalletAssets = ({ assets: hookCustomAssets, staleTime = 30000,
|
|
|
51
66
|
};
|
|
52
67
|
return headers;
|
|
53
68
|
}, [publishableKey, getAccessToken, thirdPartyAuth]);
|
|
69
|
+
/** For multiChain: walletConfig.ethereum.assets as backend assetFilter format (hex chainId -> [{ address, type }]). */
|
|
70
|
+
const customAssetsMultiChain = useMemo(() => {
|
|
71
|
+
var _a;
|
|
72
|
+
if (!multiChain)
|
|
73
|
+
return undefined;
|
|
74
|
+
const configAssets = (_a = walletConfig === null || walletConfig === void 0 ? void 0 : walletConfig.ethereum) === null || _a === void 0 ? void 0 : _a.assets;
|
|
75
|
+
if (!configAssets)
|
|
76
|
+
return undefined;
|
|
77
|
+
const mapped = {};
|
|
78
|
+
for (const [cid, addresses] of Object.entries(configAssets)) {
|
|
79
|
+
const hexChainId = numberToHex(Number(cid));
|
|
80
|
+
mapped[hexChainId] = addresses.map((addr) => ({ address: addr, type: 'erc20' }));
|
|
81
|
+
}
|
|
82
|
+
return Object.keys(mapped).length > 0 ? mapped : undefined;
|
|
83
|
+
}, [multiChain, (_a = walletConfig === null || walletConfig === void 0 ? void 0 : walletConfig.ethereum) === null || _a === void 0 ? void 0 : _a.assets]);
|
|
54
84
|
const customTransport = useMemo(() => () => {
|
|
55
85
|
return custom({
|
|
56
86
|
async request({ method, params }) {
|
|
57
|
-
const res = await fetch(`${
|
|
87
|
+
const res = await fetch(`${backendUrl}/rpc`, {
|
|
58
88
|
method: 'POST',
|
|
59
89
|
headers: await buildHeaders(),
|
|
60
90
|
body: JSON.stringify({
|
|
@@ -71,7 +101,7 @@ const useEthereumWalletAssets = ({ assets: hookCustomAssets, staleTime = 30000,
|
|
|
71
101
|
return data.result;
|
|
72
102
|
},
|
|
73
103
|
});
|
|
74
|
-
}, [buildHeaders,
|
|
104
|
+
}, [buildHeaders, backendUrl]);
|
|
75
105
|
const customAssetsToFetch = useMemo(() => {
|
|
76
106
|
var _a;
|
|
77
107
|
if (!chainId)
|
|
@@ -80,11 +110,101 @@ const useEthereumWalletAssets = ({ assets: hookCustomAssets, staleTime = 30000,
|
|
|
80
110
|
const assetsFromHook = hookCustomAssets ? hookCustomAssets[chainId] || [] : [];
|
|
81
111
|
const allAssets = [...assetsFromConfig, ...assetsFromHook];
|
|
82
112
|
return allAssets;
|
|
83
|
-
}, [(
|
|
113
|
+
}, [(_b = walletConfig === null || walletConfig === void 0 ? void 0 : walletConfig.ethereum) === null || _b === void 0 ? void 0 : _b.assets, hookCustomAssets, chainId]);
|
|
84
114
|
const { data, error, isLoading, refetch } = useAsyncData({
|
|
85
|
-
queryKey:
|
|
115
|
+
queryKey: multiChain
|
|
116
|
+
? ['wallet-assets', 'multi', address, customAssetsMultiChain]
|
|
117
|
+
: [...openfortKeys.walletAssets(chainId, customAssetsToFetch, address)],
|
|
86
118
|
queryFn: async () => {
|
|
87
|
-
var _a, _b, _c, _d;
|
|
119
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q;
|
|
120
|
+
if (multiChain) {
|
|
121
|
+
if (!address) {
|
|
122
|
+
throw new OpenfortError('No wallet address available', OpenfortReactErrorType.UNEXPECTED_ERROR);
|
|
123
|
+
}
|
|
124
|
+
const headers = await buildHeaders();
|
|
125
|
+
const defaultRequest = fetch(`${backendUrl}/rpc`, {
|
|
126
|
+
method: 'POST',
|
|
127
|
+
headers,
|
|
128
|
+
body: JSON.stringify({
|
|
129
|
+
method: 'wallet_getAssets',
|
|
130
|
+
params: { account: address },
|
|
131
|
+
id: 1,
|
|
132
|
+
jsonrpc: '2.0',
|
|
133
|
+
}),
|
|
134
|
+
});
|
|
135
|
+
const customRequest = customAssetsMultiChain
|
|
136
|
+
? fetch(`${backendUrl}/rpc`, {
|
|
137
|
+
method: 'POST',
|
|
138
|
+
headers,
|
|
139
|
+
body: JSON.stringify({
|
|
140
|
+
method: 'wallet_getAssets',
|
|
141
|
+
params: { account: address, assetFilter: customAssetsMultiChain },
|
|
142
|
+
id: 2,
|
|
143
|
+
jsonrpc: '2.0',
|
|
144
|
+
}),
|
|
145
|
+
})
|
|
146
|
+
: null;
|
|
147
|
+
const responses = await Promise.all([defaultRequest, customRequest].filter(Boolean));
|
|
148
|
+
const [defaultData, customData] = await Promise.all(responses.map((r) => r.json()));
|
|
149
|
+
const result = { ...((_a = defaultData.result) !== null && _a !== void 0 ? _a : {}) };
|
|
150
|
+
if ((customData === null || customData === void 0 ? void 0 : customData.result) && typeof customData.result === 'object') {
|
|
151
|
+
for (const [chainKey, assets] of Object.entries(customData.result)) {
|
|
152
|
+
if (!Array.isArray(assets))
|
|
153
|
+
continue;
|
|
154
|
+
if (!result[chainKey]) {
|
|
155
|
+
result[chainKey] = assets;
|
|
156
|
+
}
|
|
157
|
+
else {
|
|
158
|
+
const existing = new Map(result[chainKey].map((a) => { var _a; return [(_a = a.address) !== null && _a !== void 0 ? _a : '', a]; }));
|
|
159
|
+
for (const asset of assets) {
|
|
160
|
+
existing.set((_b = asset.address) !== null && _b !== void 0 ? _b : '', asset);
|
|
161
|
+
}
|
|
162
|
+
result[chainKey] = Array.from(existing.values());
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
const allAssets = [];
|
|
167
|
+
for (const [chainIdKey, assets] of Object.entries(result)) {
|
|
168
|
+
const cid = Number(chainIdKey);
|
|
169
|
+
if (!Array.isArray(assets))
|
|
170
|
+
continue;
|
|
171
|
+
for (const a of assets) {
|
|
172
|
+
if (a.type === 'erc20') {
|
|
173
|
+
const asset = {
|
|
174
|
+
type: 'erc20',
|
|
175
|
+
address: ((_c = a.address) !== null && _c !== void 0 ? _c : '0x0'),
|
|
176
|
+
balance: BigInt((_d = a.balance) !== null && _d !== void 0 ? _d : 0),
|
|
177
|
+
metadata: {
|
|
178
|
+
name: ((_e = a.metadata) === null || _e === void 0 ? void 0 : _e.name) || 'Unknown Token',
|
|
179
|
+
symbol: ((_f = a.metadata) === null || _f === void 0 ? void 0 : _f.symbol) || 'UNKNOWN',
|
|
180
|
+
decimals: (_g = a.metadata) === null || _g === void 0 ? void 0 : _g.decimals,
|
|
181
|
+
fiat: (_h = a.metadata) === null || _h === void 0 ? void 0 : _h.fiat,
|
|
182
|
+
},
|
|
183
|
+
raw: a,
|
|
184
|
+
};
|
|
185
|
+
allAssets.push({ ...asset, chainId: cid });
|
|
186
|
+
}
|
|
187
|
+
else if (a.type === 'native') {
|
|
188
|
+
const meta = ((_j = a.metadata) !== null && _j !== void 0 ? _j : {});
|
|
189
|
+
const asset = {
|
|
190
|
+
type: 'native',
|
|
191
|
+
address: 'native',
|
|
192
|
+
balance: BigInt((_k = a.balance) !== null && _k !== void 0 ? _k : 0),
|
|
193
|
+
metadata: {
|
|
194
|
+
symbol: meta.symbol || 'ETH',
|
|
195
|
+
decimals: meta.decimals,
|
|
196
|
+
fiat: (_l = meta.fiat) !== null && _l !== void 0 ? _l : { value: 0, currency: 'USD' },
|
|
197
|
+
},
|
|
198
|
+
raw: a,
|
|
199
|
+
};
|
|
200
|
+
allAssets.push({ ...asset, chainId: cid });
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
allAssets.sort((a, b) => getUsdValue(b) - getUsdValue(a));
|
|
205
|
+
return allAssets;
|
|
206
|
+
}
|
|
207
|
+
// Single-chain path
|
|
88
208
|
if (!address || !chainId || !chain) {
|
|
89
209
|
throw new OpenfortError('Wallet not connected', OpenfortReactErrorType.UNEXPECTED_ERROR, {
|
|
90
210
|
error: new Error('Address, chainId, or chain not available'),
|
|
@@ -115,8 +235,8 @@ const useEthereumWalletAssets = ({ assets: hookCustomAssets, staleTime = 30000,
|
|
|
115
235
|
// ERC-7811 response keys may be hex (e.g. "0x14a34") or numeric depending on the RPC
|
|
116
236
|
const rawByChain = defaultAssetsRaw;
|
|
117
237
|
const customByChain = customAssets;
|
|
118
|
-
const rawChainAssets = (
|
|
119
|
-
const customChainAssets = (
|
|
238
|
+
const rawChainAssets = (_o = (_m = rawByChain[hexChainId]) !== null && _m !== void 0 ? _m : rawByChain[String(chainId)]) !== null && _o !== void 0 ? _o : [];
|
|
239
|
+
const customChainAssets = (_q = (_p = customByChain[hexChainId]) !== null && _p !== void 0 ? _p : customByChain[String(chainId)]) !== null && _q !== void 0 ? _q : [];
|
|
120
240
|
const defaultAssets = rawChainAssets.map((a) => {
|
|
121
241
|
var _a;
|
|
122
242
|
let asset;
|
|
@@ -153,7 +273,6 @@ const useEthereumWalletAssets = ({ assets: hookCustomAssets, staleTime = 30000,
|
|
|
153
273
|
const mergedAssets = [...defaultAssets];
|
|
154
274
|
const customAssetsForChain = customChainAssets.flatMap((asset) => {
|
|
155
275
|
var _a, _b;
|
|
156
|
-
// Custom assets are explicitly requested as erc20; skip if the API returns something unexpected.
|
|
157
276
|
if (asset.type !== 'erc20')
|
|
158
277
|
return [];
|
|
159
278
|
if (!((_a = walletConfig === null || walletConfig === void 0 ? void 0 : walletConfig.ethereum) === null || _a === void 0 ? void 0 : _a.assets))
|
|
@@ -178,7 +297,7 @@ const useEthereumWalletAssets = ({ assets: hookCustomAssets, staleTime = 30000,
|
|
|
178
297
|
});
|
|
179
298
|
return mergedAssets;
|
|
180
299
|
},
|
|
181
|
-
enabled: isConnected && !!chainId && !!chain && !!address,
|
|
300
|
+
enabled: multiChain ? isConnected && !!address : isConnected && !!chainId && !!chain && !!address,
|
|
182
301
|
staleTime,
|
|
183
302
|
});
|
|
184
303
|
const mappedError = useMemo(() => {
|
|
@@ -191,10 +310,11 @@ const useEthereumWalletAssets = ({ assets: hookCustomAssets, staleTime = 30000,
|
|
|
191
310
|
}, [error]);
|
|
192
311
|
return {
|
|
193
312
|
data: data !== null && data !== void 0 ? data : null,
|
|
313
|
+
multiChain,
|
|
194
314
|
isLoading,
|
|
195
315
|
isError: !!error,
|
|
196
316
|
isSuccess: !!data && !error,
|
|
197
|
-
isIdle: !isConnected || !chainId || !chain,
|
|
317
|
+
isIdle: multiChain ? !address : !isConnected || !chainId || !chain,
|
|
198
318
|
error: mappedError,
|
|
199
319
|
refetch,
|
|
200
320
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useEthereumWalletAssets.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"useEthereumWalletAssets.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
package/build/index.d.ts
CHANGED
|
@@ -44,7 +44,7 @@ export { default as Avatar } from './components/Common/Avatar';
|
|
|
44
44
|
export { default as ChainIcon } from './components/Common/Chain';
|
|
45
45
|
export { OpenfortButton } from './components/ConnectButton';
|
|
46
46
|
export { OpenfortProvider } from './components/Openfort/OpenfortProvider';
|
|
47
|
-
export type { CustomizableRoutes } from './components/Openfort/types';
|
|
47
|
+
export type { CustomizableRoutes, MultiChainAsset } from './components/Openfort/types';
|
|
48
48
|
export { LinkWalletOnSignUpOption, UIAuthProvider as AuthProvider } from './components/Openfort/types';
|
|
49
49
|
export { embeddedWalletId } from './constants/openfort';
|
|
50
50
|
export { OpenfortError, OpenfortReactErrorType, OpenfortReactErrorType as OpenfortErrorType, } from './core/errors';
|
|
@@ -35,8 +35,11 @@ function useEmbeddedStateMachine({ openfort, storeEmbeddedState, storeUser, stor
|
|
|
35
35
|
setIsConnectedWithEmbeddedSigner(false);
|
|
36
36
|
// Validate token and fetch accounts. Auto-recovery is handled by the
|
|
37
37
|
// dedicated useAutoRecovery hook (keyed on storeActiveEmbeddedAddress).
|
|
38
|
+
// Never auto-logout here: during first OAuth sign-in the user isn't in
|
|
39
|
+
// the store yet and user.get() may briefly 401/404 before the token
|
|
40
|
+
// propagates — logging out would abort the entire auth flow.
|
|
38
41
|
const doFetch = async () => {
|
|
39
|
-
updateUserRef.current(undefined,
|
|
42
|
+
updateUserRef.current(undefined, false);
|
|
40
43
|
await fetchEmbeddedAccountsRef.current();
|
|
41
44
|
};
|
|
42
45
|
doFetch().catch((err) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useEmbeddedStateMachine.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"useEmbeddedStateMachine.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
package/build/utils/index.d.ts
CHANGED
|
@@ -9,4 +9,4 @@ declare function flattenChildren(children: React.ReactNode): ReactChildArray;
|
|
|
9
9
|
export declare const isWalletConnectConnector: (connectorId?: string) => connectorId is "walletConnect";
|
|
10
10
|
export declare const isCoinbaseWalletConnector: (connectorId?: string) => connectorId is "coinbaseWalletSDK";
|
|
11
11
|
export declare const isInjectedConnector: (connectorId?: string) => connectorId is "injected";
|
|
12
|
-
export {
|
|
12
|
+
export { detectBrowser, flattenChildren, isAndroid, isMobile, nFormatter, truncateEthAddress, truncateSolanaAddress };
|
package/build/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const OPENFORT_VERSION = "1.0.
|
|
1
|
+
export declare const OPENFORT_VERSION = "1.0.5";
|
package/build/version.js
CHANGED