@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.
Files changed (42) hide show
  1. package/build/assets/icons.js +1 -1
  2. package/build/components/ConnectModal/index.js +3 -6
  3. package/build/components/ConnectModal/index.js.map +1 -1
  4. package/build/components/Openfort/OpenfortProvider.js +8 -6
  5. package/build/components/Openfort/OpenfortProvider.js.map +1 -1
  6. package/build/components/Pages/CreateWallet/index.js +34 -14
  7. package/build/components/Pages/CreateWallet/index.js.map +1 -1
  8. package/build/components/Pages/LoadWallets/index.js +7 -4
  9. package/build/components/Pages/LoadWallets/index.js.map +1 -1
  10. package/build/components/Pages/Send/index.js +1 -2
  11. package/build/components/Pages/Send/index.js.map +1 -1
  12. package/build/constants/openfort.d.ts +3 -0
  13. package/build/constants/openfort.js +5 -1
  14. package/build/constants/openfort.js.map +1 -1
  15. package/build/ethereum/hooks/useEthereumEmbeddedWallet.js +4 -3
  16. package/build/ethereum/hooks/useEthereumEmbeddedWallet.js.map +1 -1
  17. package/build/hooks/openfort/auth/useConnectToWalletPostAuth.js +5 -4
  18. package/build/hooks/openfort/auth/useConnectToWalletPostAuth.js.map +1 -1
  19. package/build/solana/hooks/utils.d.ts +0 -1
  20. package/build/solana/hooks/utils.js +2 -10
  21. package/build/solana/hooks/utils.js.map +1 -1
  22. package/build/version.d.ts +1 -1
  23. package/build/version.js +1 -1
  24. package/package.json +1 -1
  25. package/build/components/Pages/Send/SolanaSend.d.ts +0 -1
  26. package/build/components/Pages/Send/SolanaSend.js +0 -93
  27. package/build/components/Pages/Send/SolanaSend.js.map +0 -1
  28. package/build/components/Pages/SolanaSendConfirmation/index.d.ts +0 -1
  29. package/build/components/Pages/SolanaSendConfirmation/index.js +0 -152
  30. package/build/components/Pages/SolanaSendConfirmation/index.js.map +0 -1
  31. package/build/components/Pages/SolanaWallets/index.d.ts +0 -1
  32. package/build/components/Pages/SolanaWallets/index.js +0 -36
  33. package/build/components/Pages/SolanaWallets/index.js.map +0 -1
  34. package/build/shared/utils/validation.d.ts +0 -15
  35. package/build/shared/utils/validation.js +0 -27
  36. package/build/shared/utils/validation.js.map +0 -1
  37. package/build/solana/constants.d.ts +0 -21
  38. package/build/solana/constants.js +0 -24
  39. package/build/solana/constants.js.map +0 -1
  40. package/build/solana/utils/transfer.d.ts +0 -9
  41. package/build/solana/utils/transfer.js +0 -20
  42. package/build/solana/utils/transfer.js.map +0 -1
@@ -1,4 +1,4 @@
1
- import { jsx, jsxs } from 'react/jsx-runtime';
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': jsx(SolanaSend, {}),
116
- 'sol:sendConfirmation': jsx(SolanaSendConfirmation, {}),
112
+ // 'sol:send': <SolanaSend />,
113
+ // 'sol:sendConfirmation': <SolanaSendConfirmation />,
117
114
  'sol:receive': jsx(Receive, {}),
118
- 'sol:wallets': jsx(SolanaWallets, {}),
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 LazyConnectKitModal = lazy(() => import('../ConnectModal/index.js'));
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(EmbeddedWalletWagmiSync, {}), debugModeOptions.debugRoutes && (jsx("pre", { style: {
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 === EmbeddedState.EMBEDDED_SIGNER_NOT_CONFIGURED) {
129
- setShouldCreateWallet(true);
130
- }
131
- }, [embeddedState]);
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 === EmbeddedState.EMBEDDED_SIGNER_NOT_CONFIGURED) {
178
- setShouldCreateWallet(true);
179
- }
180
- }, [embeddedState]);
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 { user } = useOpenfortCore();
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, AccountTypeEnum, EmbeddedState, RecoveryMethod } from '@openfort/openfort-js';
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 : AccountTypeEnum.SMART_ACCOUNT;
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 !== AccountTypeEnum.EOA && { chainId: (_d = createOptions === null || createOptions === void 0 ? void 0 : createOptions.chainId) !== null && _d !== void 0 ? _d : creationChainId }),
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 { AccountTypeEnum, ChainTypeEnum, RecoveryMethod, EmbeddedState } from '@openfort/openfort-js';
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 : AccountTypeEnum.SMART_ACCOUNT;
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 : AccountTypeEnum.EOA,
61
- ...(chainType === ChainTypeEnum.EVM && accountType !== AccountTypeEnum.EOA && { chainId }),
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,2 +1 @@
1
- export declare function solToLamports(sol: number): bigint;
2
1
  export declare function formatSol(lamports: bigint, decimals?: number): string;
@@ -1,12 +1,4 @@
1
- import { LAMPORTS_PER_SOL } from '../constants.js';
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, solToLamports };
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":";;;;;;;;;;"}
@@ -1 +1 @@
1
- export declare const OPENFORT_VERSION = "1.0.0";
1
+ export declare const OPENFORT_VERSION = "1.0.2";
package/build/version.js CHANGED
@@ -1,4 +1,4 @@
1
- const OPENFORT_VERSION = '1.0.0';
1
+ const OPENFORT_VERSION = '1.0.2';
2
2
 
3
3
  export { OPENFORT_VERSION };
4
4
  //# sourceMappingURL=version.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openfort/react",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "author": "Openfort (https://www.openfort.io)",
5
5
  "license": "BSD-2-Clause license",
6
6
  "description": "The easiest way to integrate Openfort to your project.",
@@ -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":";;;;;;;;;;;;;;;;;;;;"}