@openfort/react 1.0.0 → 1.0.2
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/components/ConnectModal/index.js +3 -6
- package/build/components/ConnectModal/index.js.map +1 -1
- package/build/components/Openfort/OpenfortProvider.js +8 -6
- package/build/components/Openfort/OpenfortProvider.js.map +1 -1
- package/build/components/Pages/CreateWallet/index.js +34 -14
- package/build/components/Pages/CreateWallet/index.js.map +1 -1
- package/build/components/Pages/LoadWallets/index.js +7 -4
- package/build/components/Pages/LoadWallets/index.js.map +1 -1
- package/build/components/Pages/Send/index.js +1 -2
- package/build/components/Pages/Send/index.js.map +1 -1
- package/build/constants/openfort.d.ts +3 -0
- package/build/constants/openfort.js +5 -1
- package/build/constants/openfort.js.map +1 -1
- package/build/ethereum/hooks/useEthereumEmbeddedWallet.js +4 -3
- package/build/ethereum/hooks/useEthereumEmbeddedWallet.js.map +1 -1
- package/build/hooks/openfort/auth/useConnectToWalletPostAuth.js +5 -4
- package/build/hooks/openfort/auth/useConnectToWalletPostAuth.js.map +1 -1
- package/build/solana/hooks/utils.d.ts +0 -1
- package/build/solana/hooks/utils.js +2 -10
- package/build/solana/hooks/utils.js.map +1 -1
- package/build/version.d.ts +1 -1
- package/build/version.js +1 -1
- package/package.json +1 -1
- package/build/components/Pages/Send/SolanaSend.d.ts +0 -1
- package/build/components/Pages/Send/SolanaSend.js +0 -93
- package/build/components/Pages/Send/SolanaSend.js.map +0 -1
- package/build/components/Pages/SolanaSendConfirmation/index.d.ts +0 -1
- package/build/components/Pages/SolanaSendConfirmation/index.js +0 -152
- package/build/components/Pages/SolanaSendConfirmation/index.js.map +0 -1
- package/build/components/Pages/SolanaWallets/index.d.ts +0 -1
- package/build/components/Pages/SolanaWallets/index.js +0 -36
- package/build/components/Pages/SolanaWallets/index.js.map +0 -1
- package/build/shared/utils/validation.d.ts +0 -15
- package/build/shared/utils/validation.js +0 -27
- package/build/shared/utils/validation.js.map +0 -1
- package/build/solana/constants.d.ts +0 -21
- package/build/solana/constants.js +0 -24
- package/build/solana/constants.js.map +0 -1
- package/build/solana/utils/transfer.d.ts +0 -9
- package/build/solana/utils/transfer.js +0 -20
- package/build/solana/utils/transfer.js.map +0 -1
package/build/assets/icons.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
2
2
|
|
|
3
3
|
const SendIcon = ({ ...props }) => (jsxs("svg", { "aria-hidden": "true", width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg", ...props, children: [jsx("path", { d: "M5 19L19 5", stroke: "currentColor", strokeWidth: "1.75", strokeLinecap: "round", strokeLinejoin: "round" }), jsx("path", { d: "M9 5H19V15", stroke: "currentColor", strokeWidth: "1.75", strokeLinecap: "round", strokeLinejoin: "round" })] }));
|
|
4
4
|
const ReceiveIcon = ({ ...props }) => (jsxs("svg", { "aria-hidden": "true", width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg", ...props, children: [jsx("path", { d: "M19 5L5 19", stroke: "currentColor", strokeWidth: "1.75", strokeLinecap: "round", strokeLinejoin: "round" }), jsx("path", { d: "M15 19H5V9", stroke: "currentColor", strokeWidth: "1.75", strokeLinecap: "round", strokeLinejoin: "round" })] }));
|
|
@@ -44,11 +44,8 @@ import RemoveLinkedProvider from '../Pages/RemoveLinkedProvider/index.js';
|
|
|
44
44
|
import SelectToken from '../Pages/SelectToken/index.js';
|
|
45
45
|
import SelectWalletToRecover from '../Pages/SelectWalletToRecover/index.js';
|
|
46
46
|
import Send from '../Pages/Send/index.js';
|
|
47
|
-
import { SolanaSend } from '../Pages/Send/SolanaSend.js';
|
|
48
47
|
import SendConfirmation from '../Pages/SendConfirmation/index.js';
|
|
49
48
|
import SocialProviders from '../Pages/SocialProviders/index.js';
|
|
50
|
-
import SolanaSendConfirmation from '../Pages/SolanaSendConfirmation/index.js';
|
|
51
|
-
import SolanaWallets from '../Pages/SolanaWallets/index.js';
|
|
52
49
|
import ConnectUsing from './ConnectUsing.js';
|
|
53
50
|
import ConnectWithMobile from './ConnectWithMobile.js';
|
|
54
51
|
|
|
@@ -112,10 +109,10 @@ const CHAIN_PREFIXED_PAGES = {
|
|
|
112
109
|
'sol:connected': jsx(Connected, {}),
|
|
113
110
|
'sol:createWallet': jsx(CreateWallet, {}),
|
|
114
111
|
'sol:recoverWallet': jsx(RecoverPage, {}),
|
|
115
|
-
'sol:send':
|
|
116
|
-
'sol:sendConfirmation':
|
|
112
|
+
// 'sol:send': <SolanaSend />,
|
|
113
|
+
// 'sol:sendConfirmation': <SolanaSendConfirmation />,
|
|
117
114
|
'sol:receive': jsx(Receive, {}),
|
|
118
|
-
'sol:wallets':
|
|
115
|
+
// 'sol:wallets': <SolanaWallets />,
|
|
119
116
|
},
|
|
120
117
|
};
|
|
121
118
|
const DEFAULT_CONNECTED_ROUTE = {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -9,12 +9,14 @@ import { CoreOpenfortProvider } from '../../openfort/CoreOpenfortProvider.js';
|
|
|
9
9
|
import { logger } from '../../utils/logger.js';
|
|
10
10
|
import { buildChainFromConfig } from '../../utils/rpc.js';
|
|
11
11
|
import { isFamily } from '../../utils/wallets.js';
|
|
12
|
-
import { EmbeddedWalletWagmiSync } from '../../wagmi/useEmbeddedWalletWagmiSync.js';
|
|
13
12
|
import { OpenfortContext, UIContext } from './context.js';
|
|
14
13
|
import { UIAuthProvider, routes, defaultSendFormState, defaultBuyFormState, notStoredInHistoryRoutes } from './types.js';
|
|
15
14
|
|
|
16
|
-
const SolanaContextProvider = lazy(() => import('../../solana/SolanaContext.js').then((m) => ({ default: m.SolanaContextProvider })));
|
|
17
|
-
const
|
|
15
|
+
const SolanaContextProvider = lazy(() => import(/* @vite-ignore */ '../../solana/SolanaContext.js').then((m) => ({ default: m.SolanaContextProvider })));
|
|
16
|
+
const LazyEmbeddedWalletWagmiSync = lazy(() => import(/* @vite-ignore */ '../../wagmi/useEmbeddedWalletWagmiSync.js').then((m) => ({
|
|
17
|
+
default: m.EmbeddedWalletWagmiSync,
|
|
18
|
+
})));
|
|
19
|
+
const LazyConnectKitModal = lazy(() => import(/* @vite-ignore */ '../ConnectModal/index.js'));
|
|
18
20
|
let openfortProviderWarnedNoWagmi = false;
|
|
19
21
|
/**
|
|
20
22
|
* Root provider for Openfort. Wrap your app with this to enable connect modal, auth, and wallet features.
|
|
@@ -92,8 +94,8 @@ const OpenfortProvider = ({ children, uiConfig, onConnect, onDisconnect, debugMo
|
|
|
92
94
|
defaultMethod: allowAutomaticRecovery ? RecoveryMethod.AUTOMATIC : RecoveryMethod.PASSWORD,
|
|
93
95
|
},
|
|
94
96
|
authProviders: hasWagmi
|
|
95
|
-
? [UIAuthProvider.GUEST, UIAuthProvider.EMAIL_OTP, UIAuthProvider.WALLET]
|
|
96
|
-
: [UIAuthProvider.GUEST, UIAuthProvider.EMAIL_OTP],
|
|
97
|
+
? [UIAuthProvider.GUEST, UIAuthProvider.EMAIL_OTP, UIAuthProvider.WALLET, UIAuthProvider.GOOGLE]
|
|
98
|
+
: [UIAuthProvider.GUEST, UIAuthProvider.EMAIL_OTP, UIAuthProvider.GOOGLE],
|
|
97
99
|
}), [allowAutomaticRecovery, hasWagmi]);
|
|
98
100
|
const safeUiConfig = useMemo(() => {
|
|
99
101
|
var _a, _b, _c, _d, _e;
|
|
@@ -318,7 +320,7 @@ const OpenfortProvider = ({ children, uiConfig, onConnect, onDisconnect, debugMo
|
|
|
318
320
|
setBuyForm,
|
|
319
321
|
triggerResize,
|
|
320
322
|
]);
|
|
321
|
-
const innerChildren = (jsxs(Fragment, { children: [hasWagmi && jsx(
|
|
323
|
+
const innerChildren = (jsxs(Fragment, { children: [hasWagmi && (jsx(Suspense, { fallback: null, children: jsx(LazyEmbeddedWalletWagmiSync, {}) })), debugModeOptions.debugRoutes && (jsx("pre", { style: {
|
|
322
324
|
position: 'absolute',
|
|
323
325
|
top: 0,
|
|
324
326
|
left: 0,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OpenfortProvider.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"OpenfortProvider.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
2
2
|
import { ChainTypeEnum, RecoveryMethod, EmbeddedState } from '@openfort/openfort-js';
|
|
3
3
|
import { motion } from 'framer-motion';
|
|
4
|
-
import { useEffect, useState, useCallback, useMemo } from 'react';
|
|
4
|
+
import { useEffect, useState, useRef, useCallback, useMemo } from 'react';
|
|
5
5
|
import { PlusIcon, PhoneIcon, EmailIcon, FingerPrintIcon, KeyIcon, ShieldIcon, LockIcon } from '../../../assets/icons.js';
|
|
6
6
|
import Logos from '../../../assets/logos.js';
|
|
7
7
|
import { OpenfortError } from '../../../types.js';
|
|
@@ -64,15 +64,17 @@ const OtherMethod = ({ currentMethod, onChangeMethod, }) => {
|
|
|
64
64
|
const CreateWalletAutomaticRecovery = ({ onBack, logoutOnBack, }) => {
|
|
65
65
|
var _a;
|
|
66
66
|
const { embeddedState } = useOpenfortCore();
|
|
67
|
-
const { setRoute, triggerResize } = useOpenfort();
|
|
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
|
+
const isCreatingRef = useRef(false);
|
|
72
73
|
const [needsOTP, setNeedsOTP] = useState(false);
|
|
73
74
|
const [otpResponse, setOtpResponse] = useState(null);
|
|
74
75
|
const [otpStatus, setOtpStatus] = useState('idle');
|
|
75
76
|
const [error, setError] = useState(false);
|
|
77
|
+
const [canSendOtp, setCanSendOtp] = useState(true);
|
|
76
78
|
const handleCompleteOtp = async (otp) => {
|
|
77
79
|
setOtpStatus('loading');
|
|
78
80
|
try {
|
|
@@ -96,13 +98,18 @@ const CreateWalletAutomaticRecovery = ({ onBack, logoutOnBack, }) => {
|
|
|
96
98
|
useEffect(() => {
|
|
97
99
|
if (!shouldCreateWallet)
|
|
98
100
|
return;
|
|
101
|
+
if (isCreatingRef.current)
|
|
102
|
+
return;
|
|
103
|
+
isCreatingRef.current = true;
|
|
99
104
|
(async () => {
|
|
100
105
|
logger.log('Creating wallet Automatic recover');
|
|
101
106
|
try {
|
|
102
107
|
await create({ recoveryMethod: RecoveryMethod.AUTOMATIC });
|
|
108
|
+
setShouldCreateWallet(false);
|
|
103
109
|
setRoute(routes.CONNECTED_SUCCESS);
|
|
104
110
|
}
|
|
105
111
|
catch (err) {
|
|
112
|
+
setShouldCreateWallet(false);
|
|
106
113
|
const { error, isOTPRequired } = handleOtpRecoveryError(err, isWalletRecoveryOTPEnabled);
|
|
107
114
|
if (isOTPRequired && isWalletRecoveryOTPEnabled) {
|
|
108
115
|
try {
|
|
@@ -120,15 +127,19 @@ const CreateWalletAutomaticRecovery = ({ onBack, logoutOnBack, }) => {
|
|
|
120
127
|
setRecoveryError(error);
|
|
121
128
|
}
|
|
122
129
|
}
|
|
130
|
+
finally {
|
|
131
|
+
isCreatingRef.current = false;
|
|
132
|
+
}
|
|
123
133
|
triggerResize();
|
|
124
134
|
})();
|
|
125
135
|
}, [shouldCreateWallet, create, isWalletRecoveryOTPEnabled, requestOTP, triggerResize]);
|
|
126
|
-
const [canSendOtp, setCanSendOtp] = useState(true);
|
|
127
136
|
useEffect(() => {
|
|
128
|
-
if (embeddedState
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
137
|
+
if (embeddedState !== EmbeddedState.EMBEDDED_SIGNER_NOT_CONFIGURED)
|
|
138
|
+
return;
|
|
139
|
+
if ((walletConfig === null || walletConfig === void 0 ? void 0 : walletConfig.connectOnLogin) === false)
|
|
140
|
+
return;
|
|
141
|
+
setShouldCreateWallet(true);
|
|
142
|
+
}, [embeddedState, walletConfig === null || walletConfig === void 0 ? void 0 : walletConfig.connectOnLogin]);
|
|
132
143
|
const handleResendClick = useCallback(() => {
|
|
133
144
|
setOtpStatus('send-otp');
|
|
134
145
|
setCanSendOtp(false);
|
|
@@ -152,18 +163,23 @@ const CreateWalletAutomaticRecovery = ({ onBack, logoutOnBack, }) => {
|
|
|
152
163
|
return (jsx(PageContent, { onBack: onBack, logoutOnBack: logoutOnBack, children: jsx(Loader, { isError: !!recoveryError, header: recoveryError ? 'Error creating wallet.' : `Creating wallet...`, description: recoveryError ? recoveryError.message : undefined }) }));
|
|
153
164
|
};
|
|
154
165
|
const CreateWalletPasskeyRecovery = ({ onChangeMethod, onBack, logoutOnBack, }) => {
|
|
155
|
-
const { triggerResize, setRoute } = useOpenfort();
|
|
166
|
+
const { triggerResize, setRoute, walletConfig } = useOpenfort();
|
|
156
167
|
const { create } = useEthereumEmbeddedWallet();
|
|
157
168
|
const [shouldCreateWallet, setShouldCreateWallet] = useState(false);
|
|
169
|
+
const isCreatingRef = useRef(false);
|
|
158
170
|
const [recoveryError, setRecoveryError] = useState(null);
|
|
159
171
|
const { embeddedState } = useOpenfortCore();
|
|
160
172
|
useEffect(() => {
|
|
161
173
|
if (!shouldCreateWallet)
|
|
162
174
|
return;
|
|
175
|
+
if (isCreatingRef.current)
|
|
176
|
+
return;
|
|
177
|
+
isCreatingRef.current = true;
|
|
163
178
|
(async () => {
|
|
164
179
|
logger.log('Creating wallet passkey recovery');
|
|
165
180
|
try {
|
|
166
181
|
await create({ recoveryMethod: RecoveryMethod.PASSKEY });
|
|
182
|
+
setShouldCreateWallet(false);
|
|
167
183
|
setRoute(routes.CONNECTED_SUCCESS);
|
|
168
184
|
}
|
|
169
185
|
catch (err) {
|
|
@@ -171,13 +187,18 @@ const CreateWalletPasskeyRecovery = ({ onChangeMethod, onBack, logoutOnBack, })
|
|
|
171
187
|
setRecoveryError(new Error('Failed to create wallet'));
|
|
172
188
|
setShouldCreateWallet(false);
|
|
173
189
|
}
|
|
190
|
+
finally {
|
|
191
|
+
isCreatingRef.current = false;
|
|
192
|
+
}
|
|
174
193
|
})();
|
|
175
194
|
}, [shouldCreateWallet, create]);
|
|
176
195
|
useEffect(() => {
|
|
177
|
-
if (embeddedState
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
196
|
+
if (embeddedState !== EmbeddedState.EMBEDDED_SIGNER_NOT_CONFIGURED)
|
|
197
|
+
return;
|
|
198
|
+
if ((walletConfig === null || walletConfig === void 0 ? void 0 : walletConfig.connectOnLogin) === false)
|
|
199
|
+
return;
|
|
200
|
+
setShouldCreateWallet(true);
|
|
201
|
+
}, [embeddedState, walletConfig === null || walletConfig === void 0 ? void 0 : walletConfig.connectOnLogin]);
|
|
181
202
|
useEffect(() => {
|
|
182
203
|
if (recoveryError)
|
|
183
204
|
triggerResize();
|
|
@@ -269,8 +290,7 @@ const CreateOrConnectWallet = () => {
|
|
|
269
290
|
};
|
|
270
291
|
const EthereumCreateWallet = () => {
|
|
271
292
|
const { uiConfig, walletConfig, setRoute } = useOpenfort();
|
|
272
|
-
const { user } = useOpenfortCore();
|
|
273
|
-
const { chainType } = useOpenfortCore();
|
|
293
|
+
const { user, chainType } = useOpenfortCore();
|
|
274
294
|
// Use chain-specific hooks
|
|
275
295
|
const ethereumWallet = useEthereumEmbeddedWallet();
|
|
276
296
|
const solanaWallet = useSolanaEmbeddedWallet();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -29,9 +29,8 @@ const errorForChainRegistry = {
|
|
|
29
29
|
}),
|
|
30
30
|
};
|
|
31
31
|
const LoadWallets = () => {
|
|
32
|
-
const { chainType } = useOpenfortCore();
|
|
33
|
-
const {
|
|
34
|
-
const { triggerResize, setRoute, setConnector } = useOpenfort();
|
|
32
|
+
const { chainType, user } = useOpenfortCore();
|
|
33
|
+
const { triggerResize, setRoute, setConnector, walletConfig } = useOpenfort();
|
|
35
34
|
const ethereumWallet = useEthereumEmbeddedWallet();
|
|
36
35
|
const solanaWallet = useSolanaEmbeddedWallet();
|
|
37
36
|
const embeddedWallet = chainType === ChainTypeEnum.EVM ? ethereumWallet : solanaWallet;
|
|
@@ -62,6 +61,10 @@ const LoadWallets = () => {
|
|
|
62
61
|
}
|
|
63
62
|
logger.log('User wallets loaded:', wallets.length);
|
|
64
63
|
if (wallets.length === 0) {
|
|
64
|
+
if ((walletConfig === null || walletConfig === void 0 ? void 0 : walletConfig.connectOnLogin) === false) {
|
|
65
|
+
setRoute(routes.CONNECTED);
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
65
68
|
setRoute(createRoute(chainType));
|
|
66
69
|
return;
|
|
67
70
|
}
|
|
@@ -80,7 +83,7 @@ const LoadWallets = () => {
|
|
|
80
83
|
return;
|
|
81
84
|
}
|
|
82
85
|
setRoute(routes.SELECT_WALLET_TO_RECOVER);
|
|
83
|
-
}, [loadingUX, isLoadingWallets, wallets, user, chainType, setRoute, setConnector]);
|
|
86
|
+
}, [loadingUX, isLoadingWallets, wallets, user, chainType, setRoute, setConnector, walletConfig]);
|
|
84
87
|
const { isError: isErrorFromChain, message: errorMessageFromChain } = errorForChainRegistry[chainType](errorWallets);
|
|
85
88
|
const isError = !user || isErrorFromChain;
|
|
86
89
|
const errorMessage = !user ? undefined : errorMessageFromChain;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -2,11 +2,10 @@ import { jsx } from 'react/jsx-runtime';
|
|
|
2
2
|
import { ChainTypeEnum } from '@openfort/openfort-js';
|
|
3
3
|
import { useOpenfortCore } from '../../../openfort/useOpenfort.js';
|
|
4
4
|
import { EthereumSend } from './EthereumSend.js';
|
|
5
|
-
import { SolanaSend } from './SolanaSend.js';
|
|
6
5
|
|
|
7
6
|
const SEND_REGISTRY = {
|
|
8
7
|
[ChainTypeEnum.EVM]: EthereumSend,
|
|
9
|
-
[ChainTypeEnum.SVM]: SolanaSend,
|
|
8
|
+
// [ChainTypeEnum.SVM]: SolanaSend,
|
|
10
9
|
};
|
|
11
10
|
const Send = () => {
|
|
12
11
|
const { chainType } = useOpenfortCore();
|
|
@@ -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,8 @@
|
|
|
1
|
+
import { AccountTypeEnum } from '@openfort/openfort-js';
|
|
1
2
|
/**
|
|
2
3
|
* Identifier for the Openfort embedded wallet connector.
|
|
3
4
|
* Used when identifying the embedded wallet in connector lists.
|
|
4
5
|
*/
|
|
5
6
|
export declare const embeddedWalletId = "xyz.openfort";
|
|
7
|
+
/** Default account type when none is specified in walletConfig or create options. */
|
|
8
|
+
export declare const DEFAULT_ACCOUNT_TYPE = AccountTypeEnum.EOA;
|
|
@@ -1,8 +1,12 @@
|
|
|
1
|
+
import { AccountTypeEnum } from '@openfort/openfort-js';
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
* Identifier for the Openfort embedded wallet connector.
|
|
3
5
|
* Used when identifying the embedded wallet in connector lists.
|
|
4
6
|
*/
|
|
5
7
|
const embeddedWalletId = 'xyz.openfort';
|
|
8
|
+
/** Default account type when none is specified in walletConfig or create options. */
|
|
9
|
+
const DEFAULT_ACCOUNT_TYPE = AccountTypeEnum.EOA;
|
|
6
10
|
|
|
7
|
-
export { embeddedWalletId };
|
|
11
|
+
export { DEFAULT_ACCOUNT_TYPE, embeddedWalletId };
|
|
8
12
|
//# sourceMappingURL=openfort.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"openfort.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"openfort.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;"}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { ChainTypeEnum,
|
|
1
|
+
import { ChainTypeEnum, EmbeddedState, RecoveryMethod } from '@openfort/openfort-js';
|
|
2
2
|
import { useRef, useState, useMemo, useCallback, useEffect } from 'react';
|
|
3
3
|
import { baseSepolia } from 'viem/chains';
|
|
4
4
|
import { useOpenfort } from '../../components/Openfort/useOpenfort.js';
|
|
5
|
+
import { DEFAULT_ACCOUNT_TYPE } from '../../constants/openfort.js';
|
|
5
6
|
import { useConnectionStrategy } from '../../core/ConnectionStrategyContext.js';
|
|
6
7
|
import { OpenfortError, OpenfortReactErrorType } from '../../types.js';
|
|
7
8
|
import { useOpenfortCore } from '../../openfort/useOpenfort.js';
|
|
@@ -131,11 +132,11 @@ function useEthereumEmbeddedWallet(options) {
|
|
|
131
132
|
},
|
|
132
133
|
});
|
|
133
134
|
// Determine account type (use createOptions, then walletConfig, else default to Smart Account)
|
|
134
|
-
const accountType = (_c = (_a = createOptions === null || createOptions === void 0 ? void 0 : createOptions.accountType) !== null && _a !== void 0 ? _a : (_b = walletConfig === null || walletConfig === void 0 ? void 0 : walletConfig.ethereum) === null || _b === void 0 ? void 0 : _b.accountType) !== null && _c !== void 0 ? _c :
|
|
135
|
+
const accountType = (_c = (_a = createOptions === null || createOptions === void 0 ? void 0 : createOptions.accountType) !== null && _a !== void 0 ? _a : (_b = walletConfig === null || walletConfig === void 0 ? void 0 : walletConfig.ethereum) === null || _b === void 0 ? void 0 : _b.accountType) !== null && _c !== void 0 ? _c : DEFAULT_ACCOUNT_TYPE;
|
|
135
136
|
const account = await client.embeddedWallet.create({
|
|
136
137
|
chainType: ChainTypeEnum.EVM,
|
|
137
138
|
accountType,
|
|
138
|
-
...(accountType !==
|
|
139
|
+
...(accountType !== DEFAULT_ACCOUNT_TYPE && { chainId: (_d = createOptions === null || createOptions === void 0 ? void 0 : createOptions.chainId) !== null && _d !== void 0 ? _d : creationChainId }),
|
|
139
140
|
recoveryParams,
|
|
140
141
|
});
|
|
141
142
|
await updateEmbeddedAccounts({ silent: true });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useEthereumEmbeddedWallet.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"useEthereumEmbeddedWallet.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ChainTypeEnum, RecoveryMethod, EmbeddedState } from '@openfort/openfort-js';
|
|
2
2
|
import { useCallback } from 'react';
|
|
3
3
|
import { useOpenfort } from '../../../components/Openfort/useOpenfort.js';
|
|
4
|
+
import { DEFAULT_ACCOUNT_TYPE } from '../../../constants/openfort.js';
|
|
4
5
|
import { useOpenfortCore } from '../../../openfort/useOpenfort.js';
|
|
5
6
|
import { buildRecoveryParams } from '../../../shared/utils/recovery.js';
|
|
6
7
|
import { logger } from '../../../utils/logger.js';
|
|
@@ -54,11 +55,11 @@ const useConnectToWalletPostAuth = () => {
|
|
|
54
55
|
getAccessToken: () => client.getAccessToken(),
|
|
55
56
|
getUserId: async () => { var _a; return (_a = (await client.user.get())) === null || _a === void 0 ? void 0 : _a.id; },
|
|
56
57
|
});
|
|
57
|
-
const accountType = (_c = (_b = walletConfig === null || walletConfig === void 0 ? void 0 : walletConfig.ethereum) === null || _b === void 0 ? void 0 : _b.accountType) !== null && _c !== void 0 ? _c :
|
|
58
|
+
const accountType = (_c = (_b = walletConfig === null || walletConfig === void 0 ? void 0 : walletConfig.ethereum) === null || _b === void 0 ? void 0 : _b.accountType) !== null && _c !== void 0 ? _c : DEFAULT_ACCOUNT_TYPE;
|
|
58
59
|
const account = await client.embeddedWallet.create({
|
|
59
60
|
chainType,
|
|
60
|
-
accountType: chainType === ChainTypeEnum.EVM ? accountType :
|
|
61
|
-
...(chainType === ChainTypeEnum.EVM && accountType !==
|
|
61
|
+
accountType: chainType === ChainTypeEnum.EVM ? accountType : DEFAULT_ACCOUNT_TYPE,
|
|
62
|
+
...(chainType === ChainTypeEnum.EVM && accountType !== DEFAULT_ACCOUNT_TYPE && { chainId }),
|
|
62
63
|
recoveryParams,
|
|
63
64
|
});
|
|
64
65
|
await updateEmbeddedAccounts({ silent: true });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useConnectToWalletPostAuth.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"useConnectToWalletPostAuth.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -1,12 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
function solToLamports(sol) {
|
|
4
|
-
// Use toFixed(9) to avoid scientific notation (e.g. 1e-9) for small values
|
|
5
|
-
const str = sol.toFixed(9);
|
|
6
|
-
const [whole = '0', frac = ''] = str.split('.');
|
|
7
|
-
const padded = frac.slice(0, 9);
|
|
8
|
-
return BigInt(whole) * LAMPORTS_PER_SOL + BigInt(padded);
|
|
9
|
-
}
|
|
1
|
+
const LAMPORTS_PER_SOL = BigInt(1000000000);
|
|
10
2
|
function formatSol(lamports, decimals = 4) {
|
|
11
3
|
const whole = lamports / LAMPORTS_PER_SOL;
|
|
12
4
|
const remainder = lamports % LAMPORTS_PER_SOL;
|
|
@@ -14,5 +6,5 @@ function formatSol(lamports, decimals = 4) {
|
|
|
14
6
|
return `${whole}.${fracStr}`.replace(new RegExp(`(\\d*\\.\\d{${decimals}})\\d*`), '$1');
|
|
15
7
|
}
|
|
16
8
|
|
|
17
|
-
export { formatSol
|
|
9
|
+
export { formatSol };
|
|
18
10
|
//# sourceMappingURL=utils.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"utils.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;"}
|
package/build/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const OPENFORT_VERSION = "1.0.
|
|
1
|
+
export declare const OPENFORT_VERSION = "1.0.2";
|
package/build/version.js
CHANGED
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare function SolanaSend(): import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
2
|
-
import { useCallback } from 'react';
|
|
3
|
-
import { fetchSolanaBalance } from '../../../hooks/useBalance.js';
|
|
4
|
-
import { useAsyncData } from '../../../shared/hooks/useAsyncData.js';
|
|
5
|
-
import { isValidSolanaAddress } from '../../../shared/utils/validation.js';
|
|
6
|
-
import { BASE_FEE_LAMPORTS, RENT_EXEMPT_MINIMUM_LAMPORTS } from '../../../solana/constants.js';
|
|
7
|
-
import { useSolanaEmbeddedWallet } from '../../../solana/hooks/useSolanaEmbeddedWallet.js';
|
|
8
|
-
import { solToLamports, formatSol } from '../../../solana/hooks/utils.js';
|
|
9
|
-
import { useSolanaContext } from '../../../solana/SolanaContext.js';
|
|
10
|
-
import { logger } from '../../../utils/logger.js';
|
|
11
|
-
import Button from '../../Common/Button/index.js';
|
|
12
|
-
import Input from '../../Common/Input/index.js';
|
|
13
|
-
import { ModalHeading } from '../../Common/Modal/styles.js';
|
|
14
|
-
import { routes } from '../../Openfort/types.js';
|
|
15
|
-
import { useOpenfort } from '../../Openfort/useOpenfort.js';
|
|
16
|
-
import { PageContent } from '../../PageContent/index.js';
|
|
17
|
-
import { Form, Field, FieldLabel, AmountInputWrapper, MaxButton, HelperText, ErrorText } from './styles.js';
|
|
18
|
-
import { sanitizeForParsing, sanitizeAmountInput } from './utils.js';
|
|
19
|
-
|
|
20
|
-
const RENT_EXEMPT_LAMPORTS = RENT_EXEMPT_MINIMUM_LAMPORTS;
|
|
21
|
-
function SolanaSend() {
|
|
22
|
-
var _a, _b, _c;
|
|
23
|
-
const { rpcUrl } = useSolanaContext();
|
|
24
|
-
const { sendForm, setSendForm, setRoute } = useOpenfort();
|
|
25
|
-
const wallet = useSolanaEmbeddedWallet();
|
|
26
|
-
const recipient = sendForm.recipient;
|
|
27
|
-
const amount = sendForm.amount;
|
|
28
|
-
const walletAddress = wallet.status === 'connected' ? (_a = wallet.activeWallet) === null || _a === void 0 ? void 0 : _a.address : undefined;
|
|
29
|
-
const provider = wallet.status === 'connected' ? wallet.provider : null;
|
|
30
|
-
const balanceResult = useAsyncData({
|
|
31
|
-
queryKey: ['solana-balance', walletAddress, rpcUrl],
|
|
32
|
-
queryFn: async () => {
|
|
33
|
-
if (!walletAddress || !rpcUrl)
|
|
34
|
-
return null;
|
|
35
|
-
try {
|
|
36
|
-
const result = await fetchSolanaBalance(walletAddress, rpcUrl, 'confirmed');
|
|
37
|
-
return { value: result.value };
|
|
38
|
-
}
|
|
39
|
-
catch (error) {
|
|
40
|
-
logger.error('Failed to fetch Solana balance:', error);
|
|
41
|
-
return null;
|
|
42
|
-
}
|
|
43
|
-
},
|
|
44
|
-
enabled: Boolean(walletAddress && rpcUrl),
|
|
45
|
-
});
|
|
46
|
-
const balanceLamports = (_c = (_b = balanceResult.data) === null || _b === void 0 ? void 0 : _b.value) !== null && _c !== void 0 ? _c : BigInt(0);
|
|
47
|
-
const recipientValid = recipient.length > 0 && isValidSolanaAddress(recipient);
|
|
48
|
-
const amountNum = amount === '' || amount === '.' ? null : parseFloat(amount);
|
|
49
|
-
const amountLamports = amountNum !== null && !Number.isNaN(amountNum) && amountNum > 0 ? solToLamports(amountNum) : null;
|
|
50
|
-
const insufficientBalance = amountLamports !== null && balanceLamports !== undefined ? amountLamports > balanceLamports : false;
|
|
51
|
-
const belowRentExempt = amountLamports !== null && balanceLamports !== undefined
|
|
52
|
-
? balanceLamports - amountLamports < RENT_EXEMPT_LAMPORTS
|
|
53
|
-
: false;
|
|
54
|
-
const hasAmount = amountLamports !== null && amountLamports > BigInt(0);
|
|
55
|
-
const amountValid = hasAmount && !insufficientBalance && !belowRentExempt;
|
|
56
|
-
const maxLamports = balanceLamports > BASE_FEE_LAMPORTS ? balanceLamports - BASE_FEE_LAMPORTS - RENT_EXEMPT_LAMPORTS : BigInt(0);
|
|
57
|
-
const maxLamportsSafe = maxLamports > BigInt(0) ? maxLamports : BigInt(0);
|
|
58
|
-
const canProceed = recipientValid && amountValid && !!provider;
|
|
59
|
-
const handleMax = useCallback(() => {
|
|
60
|
-
if (maxLamportsSafe <= BigInt(0))
|
|
61
|
-
return;
|
|
62
|
-
setSendForm((prev) => ({ ...prev, amount: formatSol(maxLamportsSafe, 9) }));
|
|
63
|
-
}, [maxLamportsSafe, setSendForm]);
|
|
64
|
-
const handleSubmit = (event) => {
|
|
65
|
-
event.preventDefault();
|
|
66
|
-
if (!canProceed || !amountLamports || amountLamports <= BigInt(0))
|
|
67
|
-
return;
|
|
68
|
-
const normalized = sanitizeForParsing(amount);
|
|
69
|
-
if (!normalized)
|
|
70
|
-
return;
|
|
71
|
-
setSendForm((prev) => ({
|
|
72
|
-
...prev,
|
|
73
|
-
amount: normalized,
|
|
74
|
-
recipient,
|
|
75
|
-
asset: prev.asset,
|
|
76
|
-
}));
|
|
77
|
-
setRoute(routes.SOL_SEND_CONFIRMATION);
|
|
78
|
-
};
|
|
79
|
-
const handleRecipientChange = (e) => {
|
|
80
|
-
setSendForm((prev) => ({ ...prev, recipient: e.target.value }));
|
|
81
|
-
};
|
|
82
|
-
const handleAmountChange = (e) => {
|
|
83
|
-
const raw = sanitizeAmountInput(e.target.value);
|
|
84
|
-
if (raw === '' || /^[0-9]*\.?[0-9]*$/.test(raw)) {
|
|
85
|
-
setSendForm((prev) => ({ ...prev, amount: raw }));
|
|
86
|
-
}
|
|
87
|
-
};
|
|
88
|
-
const availableLabel = balanceResult.data != null ? formatSol(balanceLamports) : '--';
|
|
89
|
-
return (jsxs(PageContent, { onBack: routes.SOL_CONNECTED, children: [jsx(ModalHeading, { children: "Send SOL" }), jsxs(Form, { onSubmit: handleSubmit, children: [jsxs(Field, { children: [jsx(FieldLabel, { children: "Amount" }), jsxs(AmountInputWrapper, { children: [jsx(Input, { placeholder: "0.00", value: amount, onChange: handleAmountChange, inputMode: "decimal", autoComplete: "off", style: { paddingRight: '86px' } }), jsx(MaxButton, { type: "button", onClick: handleMax, disabled: maxLamportsSafe <= BigInt(0), children: "Max" })] }), jsxs(HelperText, { children: ["Available: ", availableLabel, " SOL"] }), amount && amountNum !== null && Number.isNaN(amountNum) && jsx(ErrorText, { children: "Enter a valid amount." }), insufficientBalance && jsx(ErrorText, { children: "Insufficient balance for this transfer." }), belowRentExempt && jsx(ErrorText, { children: "Leave enough for rent-exempt minimum (~0.00089 SOL)." })] }), jsxs(Field, { children: [jsx(FieldLabel, { children: "Recipient address" }), jsx(Input, { placeholder: "Base58 address...", value: recipient, onChange: handleRecipientChange, autoComplete: "off" }), recipient && !recipientValid && jsx(ErrorText, { children: "Enter a valid Solana address." })] }), jsx(Button, { variant: "primary", disabled: !canProceed, type: "submit", children: "Review transfer" })] })] }));
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
export { SolanaSend };
|
|
93
|
-
//# sourceMappingURL=SolanaSend.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"SolanaSend.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export default function SolanaSendConfirmation(): import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,152 +0,0 @@
|
|
|
1
|
-
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
2
|
-
import { ChainTypeEnum } from '@openfort/openfort-js';
|
|
3
|
-
import { createSolanaRpc, address, pipe, createTransactionMessage, setTransactionMessageFeePayer, setTransactionMessageLifetimeUsingBlockhash, appendTransactionMessageInstruction, compileTransaction, getBase64EncodedWireTransaction, getBase58Encoder } from '@solana/kit';
|
|
4
|
-
import { useState, useRef, useCallback, useEffect } from 'react';
|
|
5
|
-
import { TickIcon } from '../../../assets/icons.js';
|
|
6
|
-
import { OpenfortError, OpenfortReactErrorType } from '../../../types.js';
|
|
7
|
-
import { invalidateBalance } from '../../../hooks/useBalance.js';
|
|
8
|
-
import { getExplorerUrl } from '../../../shared/utils/explorer.js';
|
|
9
|
-
import { BASE_FEE_LAMPORTS } from '../../../solana/constants.js';
|
|
10
|
-
import { useSolanaEmbeddedWallet } from '../../../solana/hooks/useSolanaEmbeddedWallet.js';
|
|
11
|
-
import { solToLamports, formatSol } from '../../../solana/hooks/utils.js';
|
|
12
|
-
import { useSolanaContext } from '../../../solana/SolanaContext.js';
|
|
13
|
-
import { createTransferSolInstruction } from '../../../solana/utils/transfer.js';
|
|
14
|
-
import 'detect-browser';
|
|
15
|
-
import { truncateSolanaAddress } from '../../../utils/format.js';
|
|
16
|
-
import Button from '../../Common/Button/index.js';
|
|
17
|
-
import { CopyText } from '../../Common/CopyToClipboard/CopyText.js';
|
|
18
|
-
import Loader from '../../Common/Loading/index.js';
|
|
19
|
-
import { ModalHeading, ModalBody } from '../../Common/Modal/styles.js';
|
|
20
|
-
import { routes } from '../../Openfort/types.js';
|
|
21
|
-
import { useOpenfort } from '../../Openfort/useOpenfort.js';
|
|
22
|
-
import { PageContent } from '../../PageContent/index.js';
|
|
23
|
-
import { sanitizeForParsing } from '../Send/utils.js';
|
|
24
|
-
import { ButtonRow, SummaryList, SummaryItem, SummaryLabel, AmountValue, AddressValue, FeesValue, CheckIconWrapper, ErrorContainer, ErrorTitle, ErrorMessage } from '../SendConfirmation/styles.js';
|
|
25
|
-
|
|
26
|
-
const CONFIRM_POLL_MS = 500;
|
|
27
|
-
const CONFIRM_TIMEOUT_MS = 60000;
|
|
28
|
-
async function waitForConfirmation(rpcUrl, signature) {
|
|
29
|
-
var _a, _b;
|
|
30
|
-
const deadline = Date.now() + CONFIRM_TIMEOUT_MS;
|
|
31
|
-
while (Date.now() < deadline) {
|
|
32
|
-
const res = await fetch(rpcUrl, {
|
|
33
|
-
method: 'POST',
|
|
34
|
-
headers: { 'Content-Type': 'application/json' },
|
|
35
|
-
body: JSON.stringify({
|
|
36
|
-
jsonrpc: '2.0',
|
|
37
|
-
id: 1,
|
|
38
|
-
method: 'getSignatureStatuses',
|
|
39
|
-
params: [[signature], { searchTransactionHistory: true }],
|
|
40
|
-
}),
|
|
41
|
-
});
|
|
42
|
-
const data = await res.json();
|
|
43
|
-
const status = (_b = (_a = data.result) === null || _a === void 0 ? void 0 : _a.value) === null || _b === void 0 ? void 0 : _b[0];
|
|
44
|
-
if (status === null || status === void 0 ? void 0 : status.err)
|
|
45
|
-
throw new Error(typeof status.err === 'object' ? JSON.stringify(status.err) : String(status.err));
|
|
46
|
-
if ((status === null || status === void 0 ? void 0 : status.confirmationStatus) === 'confirmed' || (status === null || status === void 0 ? void 0 : status.confirmationStatus) === 'finalized')
|
|
47
|
-
return;
|
|
48
|
-
await new Promise((r) => setTimeout(r, CONFIRM_POLL_MS));
|
|
49
|
-
}
|
|
50
|
-
throw new OpenfortError('Transaction confirmation timed out', OpenfortReactErrorType.UNEXPECTED_ERROR);
|
|
51
|
-
}
|
|
52
|
-
const ED25519_SIGNATURE_LENGTH = 64;
|
|
53
|
-
function decodeSignatureToBytes(signature) {
|
|
54
|
-
const encoded = getBase58Encoder().encode(signature);
|
|
55
|
-
let bytes = new Uint8Array(encoded);
|
|
56
|
-
if (bytes.length === ED25519_SIGNATURE_LENGTH + 1) {
|
|
57
|
-
bytes = bytes.slice(0, ED25519_SIGNATURE_LENGTH);
|
|
58
|
-
}
|
|
59
|
-
if (bytes.length === ED25519_SIGNATURE_LENGTH)
|
|
60
|
-
return bytes;
|
|
61
|
-
throw new OpenfortError(`Invalid signature: expected ${ED25519_SIGNATURE_LENGTH} bytes, got ${bytes.length}.`, OpenfortReactErrorType.CONFIGURATION_ERROR);
|
|
62
|
-
}
|
|
63
|
-
function SolanaSendConfirmation() {
|
|
64
|
-
var _a;
|
|
65
|
-
const { rpcUrl, cluster } = useSolanaContext();
|
|
66
|
-
const { sendForm, setRoute, triggerResize } = useOpenfort();
|
|
67
|
-
const wallet = useSolanaEmbeddedWallet();
|
|
68
|
-
const walletAddress = wallet.status === 'connected' ? (_a = wallet.activeWallet) === null || _a === void 0 ? void 0 : _a.address : undefined;
|
|
69
|
-
const provider = wallet.status === 'connected' ? wallet.provider : null;
|
|
70
|
-
const [txStatus, setTxStatus] = useState('idle');
|
|
71
|
-
const [txSignature, setTxSignature] = useState(null);
|
|
72
|
-
const [errorMessage, setErrorMessage] = useState(null);
|
|
73
|
-
const confirmAbortRef = useRef(null);
|
|
74
|
-
const normalisedAmount = sanitizeForParsing(sendForm.amount);
|
|
75
|
-
const parsedAmount = normalisedAmount && !Number.isNaN(parseFloat(normalisedAmount)) && parseFloat(normalisedAmount) > 0
|
|
76
|
-
? solToLamports(parseFloat(normalisedAmount))
|
|
77
|
-
: null;
|
|
78
|
-
const recipient = sendForm.recipient.trim();
|
|
79
|
-
const isSponsored = false;
|
|
80
|
-
const canProceed = !!provider &&
|
|
81
|
-
!!walletAddress &&
|
|
82
|
-
!!recipient &&
|
|
83
|
-
parsedAmount !== null &&
|
|
84
|
-
parsedAmount > BigInt(0) &&
|
|
85
|
-
txStatus === 'idle';
|
|
86
|
-
const handleConfirm = useCallback(async () => {
|
|
87
|
-
var _a;
|
|
88
|
-
if (!canProceed || !provider || !walletAddress || !parsedAmount || parsedAmount <= BigInt(0))
|
|
89
|
-
return;
|
|
90
|
-
setErrorMessage(null);
|
|
91
|
-
setTxStatus('signing');
|
|
92
|
-
try {
|
|
93
|
-
const rpc = createSolanaRpc(rpcUrl);
|
|
94
|
-
const { value: blockhash } = await rpc.getLatestBlockhash().send();
|
|
95
|
-
const fromAddress = address(walletAddress);
|
|
96
|
-
const transferInstruction = createTransferSolInstruction(walletAddress, recipient, parsedAmount);
|
|
97
|
-
const message = pipe(createTransactionMessage({ version: 0 }), (msg) => setTransactionMessageFeePayer(fromAddress, msg), (msg) => setTransactionMessageLifetimeUsingBlockhash(blockhash, msg), (msg) => appendTransactionMessageInstruction(transferInstruction, msg));
|
|
98
|
-
const compiled = compileTransaction(message);
|
|
99
|
-
const signed = await provider.signTransaction({ messageBytes: compiled.messageBytes });
|
|
100
|
-
const signatureBytes = decodeSignatureToBytes(signed.signature);
|
|
101
|
-
const signedTransaction = {
|
|
102
|
-
messageBytes: compiled.messageBytes,
|
|
103
|
-
signatures: { ...compiled.signatures, [fromAddress]: signatureBytes },
|
|
104
|
-
};
|
|
105
|
-
const encodedWire = getBase64EncodedWireTransaction(signedTransaction);
|
|
106
|
-
setTxStatus('sending');
|
|
107
|
-
await rpc
|
|
108
|
-
.sendTransaction(encodedWire, {
|
|
109
|
-
encoding: 'base64',
|
|
110
|
-
preflightCommitment: 'confirmed',
|
|
111
|
-
skipPreflight: false,
|
|
112
|
-
})
|
|
113
|
-
.send();
|
|
114
|
-
(_a = confirmAbortRef.current) === null || _a === void 0 ? void 0 : _a.abort();
|
|
115
|
-
const confirmController = new AbortController();
|
|
116
|
-
confirmAbortRef.current = confirmController;
|
|
117
|
-
await waitForConfirmation(rpcUrl, signed.signature);
|
|
118
|
-
setTxSignature(signed.signature);
|
|
119
|
-
setTxStatus('confirmed');
|
|
120
|
-
invalidateBalance();
|
|
121
|
-
}
|
|
122
|
-
catch (err) {
|
|
123
|
-
if (err instanceof DOMException && err.name === 'AbortError')
|
|
124
|
-
return;
|
|
125
|
-
setTxStatus('error');
|
|
126
|
-
const msg = err instanceof OpenfortError ? err.message : err instanceof Error ? err.message : String(err);
|
|
127
|
-
setErrorMessage(msg || 'Transaction failed');
|
|
128
|
-
}
|
|
129
|
-
}, [canProceed, provider, walletAddress, parsedAmount, recipient, rpcUrl]);
|
|
130
|
-
useEffect(() => {
|
|
131
|
-
return () => {
|
|
132
|
-
var _a;
|
|
133
|
-
(_a = confirmAbortRef.current) === null || _a === void 0 ? void 0 : _a.abort();
|
|
134
|
-
};
|
|
135
|
-
}, []);
|
|
136
|
-
useEffect(() => {
|
|
137
|
-
setTimeout(triggerResize, 10);
|
|
138
|
-
}, [txStatus, errorMessage, triggerResize]);
|
|
139
|
-
const feeDisplay = `~${formatSol(BASE_FEE_LAMPORTS, 6)} SOL`;
|
|
140
|
-
const explorerUrl = txSignature && cluster ? getExplorerUrl(ChainTypeEnum.SVM, { txHash: txSignature, cluster }) : undefined;
|
|
141
|
-
const handleOpenBlockExplorer = () => {
|
|
142
|
-
if (explorerUrl)
|
|
143
|
-
window.open(explorerUrl, '_blank', 'noopener,noreferrer');
|
|
144
|
-
};
|
|
145
|
-
if (txStatus === 'confirmed') {
|
|
146
|
-
return (jsxs(PageContent, { onBack: routes.SOL_CONNECTED, children: [jsx(Loader, { isSuccess: true, header: "Transfer Sent", description: `${normalisedAmount || '0'} SOL sent successfully` }), jsxs(ButtonRow, { children: [jsx(Button, { variant: "primary", onClick: handleOpenBlockExplorer, children: "View on Explorer" }), jsx(Button, { variant: "secondary", onClick: () => setRoute(routes.SOL_CONNECTED), children: "Back to profile" })] })] }));
|
|
147
|
-
}
|
|
148
|
-
return (jsxs(PageContent, { onBack: routes.SOL_SEND, children: [jsx(ModalHeading, { children: "Confirm transfer" }), jsx(ModalBody, { children: "Review the transaction details before sending." }), jsxs(SummaryList, { children: [jsxs(SummaryItem, { children: [jsx(SummaryLabel, { children: "Sending" }), jsxs(AmountValue, { children: [normalisedAmount || '0', " SOL"] })] }), jsxs(SummaryItem, { children: [jsx(SummaryLabel, { children: "From" }), jsx(AddressValue, { children: walletAddress ? (jsx(CopyText, { size: "1rem", value: walletAddress, children: truncateSolanaAddress(walletAddress) })) : ('--') })] }), jsxs(SummaryItem, { children: [jsx(SummaryLabel, { children: "To" }), jsx(AddressValue, { children: recipient ? (jsx(CopyText, { size: "1rem", value: recipient, children: truncateSolanaAddress(recipient) })) : ('--') })] }), jsxs(SummaryItem, { children: [jsx(SummaryLabel, { children: "Network fee" }), jsxs(FeesValue, { "$completed": isSponsored, children: [feeDisplay, jsx(CheckIconWrapper, { children: jsx(TickIcon, {}) })] })] }), isSponsored ] }), errorMessage && (jsxs(ErrorContainer, { children: [jsx(ErrorTitle, { children: "Transaction failed" }), jsx(ErrorMessage, { children: errorMessage })] })), jsxs(ButtonRow, { children: [jsxs(Button, { variant: "primary", onClick: handleConfirm, disabled: !canProceed, waiting: txStatus === 'signing' || txStatus === 'sending', children: [txStatus === 'idle' && 'Confirm', txStatus === 'signing' && 'Signing...', txStatus === 'sending' && 'Sending...', txStatus === 'error' && 'Try again'] }), jsx(Button, { variant: "secondary", onClick: () => setRoute(routes.SOL_SEND), disabled: txStatus !== 'idle', children: "Cancel" })] })] }));
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
export { SolanaSendConfirmation as default };
|
|
152
|
-
//# sourceMappingURL=index.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export default function SolanaWallets(): import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
2
|
-
import { ChainTypeEnum } from '@openfort/openfort-js';
|
|
3
|
-
import { PlusIcon } from '../../../assets/icons.js';
|
|
4
|
-
import { toSolanaUserWallet } from '../../../hooks/openfort/walletTypes.js';
|
|
5
|
-
import { useOpenfortCore } from '../../../openfort/useOpenfort.js';
|
|
6
|
-
import { useSolanaEmbeddedWallet } from '../../../solana/hooks/useSolanaEmbeddedWallet.js';
|
|
7
|
-
import Button from '../../Common/Button/index.js';
|
|
8
|
-
import { ModalHeading, ModalBody } from '../../Common/Modal/styles.js';
|
|
9
|
-
import { WalletRecoveryIcon } from '../../Common/WalletRecoveryIcon/index.js';
|
|
10
|
-
import { recoverRoute } from '../../Openfort/routeHelpers.js';
|
|
11
|
-
import { routes } from '../../Openfort/types.js';
|
|
12
|
-
import { useOpenfort } from '../../Openfort/useOpenfort.js';
|
|
13
|
-
import { PageContent } from '../../PageContent/index.js';
|
|
14
|
-
import { ProvidersButton, ProviderIcon, ProviderLabel } from '../Providers/styles.js';
|
|
15
|
-
|
|
16
|
-
function WalletRow({ wallet }) {
|
|
17
|
-
const { setRoute } = useOpenfort();
|
|
18
|
-
const { chainType } = useOpenfortCore();
|
|
19
|
-
const display = wallet.address.length > 12 ? `${wallet.address.slice(0, 4)}...${wallet.address.slice(-4)}` : wallet.address;
|
|
20
|
-
const handleClick = () => {
|
|
21
|
-
const walletForRoute = toSolanaUserWallet(wallet);
|
|
22
|
-
setRoute(recoverRoute(chainType, walletForRoute));
|
|
23
|
-
};
|
|
24
|
-
return (jsx(ProvidersButton, { children: jsxs(Button, { onClick: handleClick, children: [jsx(ProviderLabel, { children: display }), jsx(ProviderIcon, { children: jsx(WalletRecoveryIcon, { recovery: wallet.recoveryMethod }) })] }) }));
|
|
25
|
-
}
|
|
26
|
-
function SolanaWallets() {
|
|
27
|
-
var _a;
|
|
28
|
-
const { setRoute } = useOpenfort();
|
|
29
|
-
const embeddedWallet = useSolanaEmbeddedWallet();
|
|
30
|
-
const wallets = (_a = embeddedWallet.wallets) !== null && _a !== void 0 ? _a : [];
|
|
31
|
-
const solanaWallets = wallets.filter((w) => w.chainType === ChainTypeEnum.SVM);
|
|
32
|
-
return (jsxs(PageContent, { onBack: routes.SOL_CONNECTED, children: [jsx(ModalHeading, { children: "Solana Wallets" }), jsxs(ModalBody, { children: [solanaWallets.map((wallet) => (jsx(WalletRow, { wallet: wallet }, wallet.id))), jsx(ProvidersButton, { children: jsx(Button, { onClick: () => setRoute(routes.SOL_CREATE_WALLET), icon: jsx(ProviderIcon, { children: jsx(PlusIcon, {}) }), children: jsx(ProviderLabel, { children: "Create new wallet" }) }) })] })] }));
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export { SolanaWallets as default };
|
|
36
|
-
//# sourceMappingURL=index.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Address validation utilities (dependency-free).
|
|
3
|
-
*
|
|
4
|
-
* openfort-js does not export address validation. The solana-sample example
|
|
5
|
-
* (openfort-js/examples/apps/solana-sample) uses @solana/kit's address() in a
|
|
6
|
-
* try/catch for Solana. We keep this shared util dependency-free so that
|
|
7
|
-
* consumers that don't use @solana/kit (e.g. EVM-only apps) don't pull it in.
|
|
8
|
-
* For stricter Solana validation when @solana/kit is available, use
|
|
9
|
-
* address(addr) from '@solana/kit' in a try/catch. React-native package has no
|
|
10
|
-
* shared address validation (no Send UI with recipient field in the repo).
|
|
11
|
-
*/
|
|
12
|
-
/**
|
|
13
|
-
* Validates a Solana address (Base58, 32–44 characters).
|
|
14
|
-
*/
|
|
15
|
-
export declare function isValidSolanaAddress(address: string): boolean;
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Address validation utilities (dependency-free).
|
|
3
|
-
*
|
|
4
|
-
* openfort-js does not export address validation. The solana-sample example
|
|
5
|
-
* (openfort-js/examples/apps/solana-sample) uses @solana/kit's address() in a
|
|
6
|
-
* try/catch for Solana. We keep this shared util dependency-free so that
|
|
7
|
-
* consumers that don't use @solana/kit (e.g. EVM-only apps) don't pull it in.
|
|
8
|
-
* For stricter Solana validation when @solana/kit is available, use
|
|
9
|
-
* address(addr) from '@solana/kit' in a try/catch. React-native package has no
|
|
10
|
-
* shared address validation (no Send UI with recipient field in the repo).
|
|
11
|
-
*/
|
|
12
|
-
const BASE58_ALPHABET = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz';
|
|
13
|
-
function isValidBase58Character(c) {
|
|
14
|
-
return BASE58_ALPHABET.includes(c);
|
|
15
|
-
}
|
|
16
|
-
/**
|
|
17
|
-
* Validates a Solana address (Base58, 32–44 characters).
|
|
18
|
-
*/
|
|
19
|
-
function isValidSolanaAddress(address) {
|
|
20
|
-
if (typeof address !== 'string' || address.length < 32 || address.length > 44) {
|
|
21
|
-
return false;
|
|
22
|
-
}
|
|
23
|
-
return address.split('').every(isValidBase58Character);
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export { isValidSolanaAddress };
|
|
27
|
-
//# sourceMappingURL=validation.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"validation.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
/** System Program's Transfer instruction index (SystemInstruction enum variant 2). */
|
|
2
|
-
export declare const TRANSFER_INSTRUCTION_INDEX = 2;
|
|
3
|
-
export declare const LAMPORTS_PER_SOL: bigint;
|
|
4
|
-
/**
|
|
5
|
-
* Solana System Program address.
|
|
6
|
-
* Not exported by @solana/kit v5 directly — defined here as a typed constant.
|
|
7
|
-
* Source: https://docs.solana.com/developing/runtime-facilities/programs#system-program
|
|
8
|
-
*/
|
|
9
|
-
export declare const SYSTEM_PROGRAM_ADDRESS = "11111111111111111111111111111111";
|
|
10
|
-
/**
|
|
11
|
-
* Base fee per signature (5,000 lamports). Does NOT include priority fees,
|
|
12
|
-
* which should be estimated dynamically via getPriorityFeeEstimate.
|
|
13
|
-
* See https://helius.dev/blog/solana-fees-in-theory-and-practice
|
|
14
|
-
*/
|
|
15
|
-
export declare const BASE_FEE_LAMPORTS: bigint;
|
|
16
|
-
/**
|
|
17
|
-
* Rent-exempt minimum for a zero-data system account (0 bytes of data).
|
|
18
|
-
* Derived from (128 + 0) bytes * 3,480 lamports/byte-year * 2 years = 890,880 lamports.
|
|
19
|
-
* For accounts with data, use getMinimumBalanceForRentExemption RPC call instead.
|
|
20
|
-
*/
|
|
21
|
-
export declare const RENT_EXEMPT_MINIMUM_LAMPORTS: bigint;
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
/** System Program's Transfer instruction index (SystemInstruction enum variant 2). */
|
|
2
|
-
const TRANSFER_INSTRUCTION_INDEX = 2;
|
|
3
|
-
const LAMPORTS_PER_SOL = BigInt(1000000000);
|
|
4
|
-
/**
|
|
5
|
-
* Solana System Program address.
|
|
6
|
-
* Not exported by @solana/kit v5 directly — defined here as a typed constant.
|
|
7
|
-
* Source: https://docs.solana.com/developing/runtime-facilities/programs#system-program
|
|
8
|
-
*/
|
|
9
|
-
const SYSTEM_PROGRAM_ADDRESS = '11111111111111111111111111111111';
|
|
10
|
-
/**
|
|
11
|
-
* Base fee per signature (5,000 lamports). Does NOT include priority fees,
|
|
12
|
-
* which should be estimated dynamically via getPriorityFeeEstimate.
|
|
13
|
-
* See https://helius.dev/blog/solana-fees-in-theory-and-practice
|
|
14
|
-
*/
|
|
15
|
-
const BASE_FEE_LAMPORTS = BigInt(5000);
|
|
16
|
-
/**
|
|
17
|
-
* Rent-exempt minimum for a zero-data system account (0 bytes of data).
|
|
18
|
-
* Derived from (128 + 0) bytes * 3,480 lamports/byte-year * 2 years = 890,880 lamports.
|
|
19
|
-
* For accounts with data, use getMinimumBalanceForRentExemption RPC call instead.
|
|
20
|
-
*/
|
|
21
|
-
const RENT_EXEMPT_MINIMUM_LAMPORTS = BigInt(890880);
|
|
22
|
-
|
|
23
|
-
export { BASE_FEE_LAMPORTS, LAMPORTS_PER_SOL, RENT_EXEMPT_MINIMUM_LAMPORTS, SYSTEM_PROGRAM_ADDRESS, TRANSFER_INSTRUCTION_INDEX };
|
|
24
|
-
//# sourceMappingURL=constants.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"constants.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import { AccountRole, address } from '@solana/kit';
|
|
2
|
-
export declare function createTransferSolInstruction(from: string, to: string, lamports: bigint): {
|
|
3
|
-
programAddress: ReturnType<typeof address>;
|
|
4
|
-
data: Uint8Array;
|
|
5
|
-
accounts: Array<{
|
|
6
|
-
address: ReturnType<typeof address>;
|
|
7
|
-
role: AccountRole;
|
|
8
|
-
}>;
|
|
9
|
-
};
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import { address, AccountRole } from '@solana/kit';
|
|
2
|
-
import { TRANSFER_INSTRUCTION_INDEX, SYSTEM_PROGRAM_ADDRESS } from '../constants.js';
|
|
3
|
-
|
|
4
|
-
function createTransferSolInstruction(from, to, lamports) {
|
|
5
|
-
const data = new Uint8Array(12);
|
|
6
|
-
const view = new DataView(data.buffer);
|
|
7
|
-
view.setUint32(0, TRANSFER_INSTRUCTION_INDEX, true);
|
|
8
|
-
view.setBigUint64(4, lamports, true);
|
|
9
|
-
return {
|
|
10
|
-
programAddress: address(SYSTEM_PROGRAM_ADDRESS),
|
|
11
|
-
data,
|
|
12
|
-
accounts: [
|
|
13
|
-
{ address: address(from), role: AccountRole.WRITABLE_SIGNER },
|
|
14
|
-
{ address: address(to), role: AccountRole.WRITABLE },
|
|
15
|
-
],
|
|
16
|
-
};
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export { createTransferSolInstruction };
|
|
20
|
-
//# sourceMappingURL=transfer.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"transfer.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;"}
|