@openfort/react 1.0.4 → 1.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/components/ConnectModal/ConnectWithOAuth.js +6 -3
- package/build/components/ConnectModal/ConnectWithOAuth.js.map +1 -1
- package/build/components/Pages/BuyProcessing/index.js +10 -4
- package/build/components/Pages/BuyProcessing/index.js.map +1 -1
- package/build/components/Pages/BuySelectProvider/index.js +0 -2
- package/build/components/Pages/BuySelectProvider/index.js.map +1 -1
- package/build/components/Pages/CreateWallet/index.js +32 -3
- package/build/components/Pages/CreateWallet/index.js.map +1 -1
- package/build/components/Pages/LoadWallets/index.js +5 -4
- package/build/components/Pages/LoadWallets/index.js.map +1 -1
- package/build/components/Pages/Loading/index.js +10 -4
- package/build/components/Pages/Loading/index.js.map +1 -1
- package/build/openfort/hooks/useEmbeddedStateMachine.js +4 -1
- package/build/openfort/hooks/useEmbeddedStateMachine.js.map +1 -1
- package/build/version.d.ts +1 -1
- package/build/version.js +1 -1
- package/package.json +1 -1
|
@@ -73,9 +73,12 @@ const ConnectWithOAuth = () => {
|
|
|
73
73
|
case states.REDIRECT: {
|
|
74
74
|
if (hasProvider)
|
|
75
75
|
return;
|
|
76
|
-
const
|
|
76
|
+
const baseURL = win.location.origin + win.location.pathname;
|
|
77
|
+
const hash = win.location.hash;
|
|
77
78
|
const queryParams = Object.fromEntries([...url.searchParams.entries()].filter(([key]) => ['openfortAuthProviderUI', 'refresh_token', 'access_token', 'player_id'].includes(key)));
|
|
78
79
|
queryParams.openfortAuthProviderUI = provider;
|
|
80
|
+
// Query params must come before the hash fragment in a valid URL
|
|
81
|
+
const redirectTo = `${baseURL}?${new URLSearchParams(queryParams).toString()}${hash}`;
|
|
79
82
|
try {
|
|
80
83
|
if (user) {
|
|
81
84
|
const authToken = await client.getAccessToken();
|
|
@@ -86,7 +89,7 @@ const ConnectWithOAuth = () => {
|
|
|
86
89
|
}
|
|
87
90
|
const linkResponse = await client.auth.initLinkOAuth({
|
|
88
91
|
provider,
|
|
89
|
-
redirectTo
|
|
92
|
+
redirectTo,
|
|
90
93
|
});
|
|
91
94
|
logger.log(linkResponse);
|
|
92
95
|
win.location.href = linkResponse;
|
|
@@ -94,7 +97,7 @@ const ConnectWithOAuth = () => {
|
|
|
94
97
|
else {
|
|
95
98
|
const r = await client.auth.initOAuth({
|
|
96
99
|
provider,
|
|
97
|
-
redirectTo
|
|
100
|
+
redirectTo,
|
|
98
101
|
});
|
|
99
102
|
logger.log(r);
|
|
100
103
|
win.location.href = r;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ConnectWithOAuth.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ConnectWithOAuth.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
2
2
|
import { ChainTypeEnum } from '@openfort/openfort-js';
|
|
3
|
-
import { useState, useMemo, useEffect } from 'react';
|
|
3
|
+
import { useState, useMemo, useRef, useEffect } from 'react';
|
|
4
4
|
import Logos from '../../../assets/logos.js';
|
|
5
5
|
import { useEthereumEmbeddedWallet } from '../../../ethereum/hooks/useEthereumEmbeddedWallet.js';
|
|
6
6
|
import { useEthereumWalletAssets } from '../../../ethereum/hooks/useEthereumWalletAssets.js';
|
|
@@ -44,10 +44,16 @@ const BuyProcessing = () => {
|
|
|
44
44
|
return null;
|
|
45
45
|
return numeric;
|
|
46
46
|
}, [buyForm.amount]);
|
|
47
|
-
// Create session and open popup
|
|
47
|
+
// Create session and open popup once wallet is ready
|
|
48
|
+
const sessionStartedRef = useRef(false);
|
|
48
49
|
useEffect(() => {
|
|
50
|
+
if (!address || !chainId)
|
|
51
|
+
return;
|
|
52
|
+
if (sessionStartedRef.current)
|
|
53
|
+
return;
|
|
54
|
+
sessionStartedRef.current = true;
|
|
49
55
|
const createSessionAndOpenPopup = async () => {
|
|
50
|
-
if (!
|
|
56
|
+
if (!fiatAmount || fiatAmount <= 0) {
|
|
51
57
|
setRoute(routes.BUY_SELECT_PROVIDER);
|
|
52
58
|
return;
|
|
53
59
|
}
|
|
@@ -123,7 +129,7 @@ const BuyProcessing = () => {
|
|
|
123
129
|
}
|
|
124
130
|
};
|
|
125
131
|
createSessionAndOpenPopup();
|
|
126
|
-
}, []); //
|
|
132
|
+
}, [address, chainId]); // Run when wallet becomes ready
|
|
127
133
|
// Trigger resize on mount and when state changes
|
|
128
134
|
useEffect(() => {
|
|
129
135
|
triggerResize();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -132,8 +132,6 @@ const BuySelectProvider = () => {
|
|
|
132
132
|
}));
|
|
133
133
|
};
|
|
134
134
|
const handleContinue = () => {
|
|
135
|
-
// Just navigate to the processing screen
|
|
136
|
-
// The processing screen will handle session creation and popup
|
|
137
135
|
setRoute(routes.BUY_PROCESSING);
|
|
138
136
|
};
|
|
139
137
|
const handleBack = () => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -63,13 +63,14 @@ const OtherMethod = ({ currentMethod, onChangeMethod, }) => {
|
|
|
63
63
|
};
|
|
64
64
|
const CreateWalletAutomaticRecovery = ({ onBack, logoutOnBack, }) => {
|
|
65
65
|
var _a;
|
|
66
|
-
const { embeddedState } = useOpenfortCore();
|
|
66
|
+
const { embeddedState, isLoadingAccounts } = useOpenfortCore();
|
|
67
67
|
const { setRoute, triggerResize, walletConfig } = useOpenfort();
|
|
68
68
|
const [recoveryError, setRecoveryError] = useState(null);
|
|
69
69
|
const { create } = useEthereumEmbeddedWallet();
|
|
70
70
|
const { isEnabled: isWalletRecoveryOTPEnabled, requestOTP } = useRecoveryOTP();
|
|
71
71
|
const [shouldCreateWallet, setShouldCreateWallet] = useState(false);
|
|
72
72
|
const isCreatingRef = useRef(false);
|
|
73
|
+
const hasAttemptedCreationRef = useRef(false);
|
|
73
74
|
const [needsOTP, setNeedsOTP] = useState(false);
|
|
74
75
|
const [otpResponse, setOtpResponse] = useState(null);
|
|
75
76
|
const [otpStatus, setOtpStatus] = useState('idle');
|
|
@@ -100,6 +101,10 @@ const CreateWalletAutomaticRecovery = ({ onBack, logoutOnBack, }) => {
|
|
|
100
101
|
return;
|
|
101
102
|
if (isCreatingRef.current)
|
|
102
103
|
return;
|
|
104
|
+
// Wait for the state machine's fetchEmbeddedAccounts to finish before
|
|
105
|
+
// calling create() — concurrent SDK operations corrupt shared state.
|
|
106
|
+
if (isLoadingAccounts)
|
|
107
|
+
return;
|
|
103
108
|
isCreatingRef.current = true;
|
|
104
109
|
(async () => {
|
|
105
110
|
logger.log('Creating wallet Automatic recover');
|
|
@@ -132,12 +137,18 @@ const CreateWalletAutomaticRecovery = ({ onBack, logoutOnBack, }) => {
|
|
|
132
137
|
}
|
|
133
138
|
triggerResize();
|
|
134
139
|
})();
|
|
135
|
-
}, [shouldCreateWallet, create, isWalletRecoveryOTPEnabled, requestOTP, triggerResize]);
|
|
140
|
+
}, [shouldCreateWallet, create, isWalletRecoveryOTPEnabled, requestOTP, triggerResize, isLoadingAccounts]);
|
|
136
141
|
useEffect(() => {
|
|
137
142
|
if (embeddedState !== EmbeddedState.EMBEDDED_SIGNER_NOT_CONFIGURED)
|
|
138
143
|
return;
|
|
139
144
|
if ((walletConfig === null || walletConfig === void 0 ? void 0 : walletConfig.connectOnLogin) === false)
|
|
140
145
|
return;
|
|
146
|
+
// Guard against retry loop: when create() fails the SDK cycles the
|
|
147
|
+
// embeddedState back to EMBEDDED_SIGNER_NOT_CONFIGURED which re-triggers
|
|
148
|
+
// this effect. Only attempt creation once — the user can retry manually.
|
|
149
|
+
if (hasAttemptedCreationRef.current)
|
|
150
|
+
return;
|
|
151
|
+
hasAttemptedCreationRef.current = true;
|
|
141
152
|
setShouldCreateWallet(true);
|
|
142
153
|
}, [embeddedState, walletConfig === null || walletConfig === void 0 ? void 0 : walletConfig.connectOnLogin]);
|
|
143
154
|
const handleResendClick = useCallback(() => {
|
|
@@ -160,13 +171,28 @@ const CreateWalletAutomaticRecovery = ({ onBack, logoutOnBack, }) => {
|
|
|
160
171
|
logo: (otpResponse === null || otpResponse === void 0 ? void 0 : otpResponse.sentTo) === 'phone' ? jsx(PhoneIcon, {}) : jsx(EmailIcon, {}),
|
|
161
172
|
} }), jsxs(ModalBody, { children: [jsxs(Body, { children: ["Please check ", jsx("b", { children: (otpResponse === null || otpResponse === void 0 ? void 0 : otpResponse.sentTo) === 'phone' ? otpResponse === null || otpResponse === void 0 ? void 0 : otpResponse.phone : otpResponse === null || otpResponse === void 0 ? void 0 : otpResponse.email }), " and enter your code below."] }), jsx(OtpInputStandalone, { length: 9, scale: "80%", onComplete: handleCompleteOtp, isLoading: otpStatus === 'loading', isError: otpStatus === 'error', isSuccess: otpStatus === 'success' }), jsxs(ResultContainer, { children: [otpStatus === 'success' && jsx(ModalBody, { "$valid": true, children: "Code verified successfully!" }), otpStatus === 'error' && jsx(ModalBody, { "$error": true, children: error || 'Invalid code. Please try again.' })] }), jsxs(FooterTextButton, { children: ["Didn't receive the code?", ' ', jsx(FooterButtonText, { type: "button", onClick: handleResendClick, disabled: isResendDisabled, children: sendButtonText })] })] })] }));
|
|
162
173
|
}
|
|
163
|
-
|
|
174
|
+
// When connectOnLogin is false, auto-creation is skipped — show a manual
|
|
175
|
+
// trigger instead of an infinite spinner.
|
|
176
|
+
if (!shouldCreateWallet && !isCreatingRef.current && !recoveryError) {
|
|
177
|
+
return (jsxs(PageContent, { onBack: onBack, logoutOnBack: logoutOnBack, children: [jsx(ModalHeading, { children: "Create wallet" }), jsx(ModalBody, { style: { textAlign: 'center' }, children: "Create an embedded wallet to get started." }), jsx(Button, { onClick: () => {
|
|
178
|
+
hasAttemptedCreationRef.current = false;
|
|
179
|
+
setShouldCreateWallet(true);
|
|
180
|
+
}, children: "Create wallet" })] }));
|
|
181
|
+
}
|
|
182
|
+
return (jsx(PageContent, { onBack: onBack, logoutOnBack: logoutOnBack, children: jsx(Loader, { isError: !!recoveryError, header: recoveryError ? 'Error creating wallet.' : `Creating wallet...`, description: recoveryError ? recoveryError.message : undefined, onRetry: recoveryError
|
|
183
|
+
? () => {
|
|
184
|
+
hasAttemptedCreationRef.current = false;
|
|
185
|
+
setRecoveryError(null);
|
|
186
|
+
setShouldCreateWallet(true);
|
|
187
|
+
}
|
|
188
|
+
: undefined }) }));
|
|
164
189
|
};
|
|
165
190
|
const CreateWalletPasskeyRecovery = ({ onChangeMethod, onBack, logoutOnBack, }) => {
|
|
166
191
|
const { triggerResize, setRoute, walletConfig } = useOpenfort();
|
|
167
192
|
const { create } = useEthereumEmbeddedWallet();
|
|
168
193
|
const [shouldCreateWallet, setShouldCreateWallet] = useState(false);
|
|
169
194
|
const isCreatingRef = useRef(false);
|
|
195
|
+
const hasAttemptedCreationRef = useRef(false);
|
|
170
196
|
const [recoveryError, setRecoveryError] = useState(null);
|
|
171
197
|
const { embeddedState } = useOpenfortCore();
|
|
172
198
|
useEffect(() => {
|
|
@@ -197,6 +223,9 @@ const CreateWalletPasskeyRecovery = ({ onChangeMethod, onBack, logoutOnBack, })
|
|
|
197
223
|
return;
|
|
198
224
|
if ((walletConfig === null || walletConfig === void 0 ? void 0 : walletConfig.connectOnLogin) === false)
|
|
199
225
|
return;
|
|
226
|
+
if (hasAttemptedCreationRef.current)
|
|
227
|
+
return;
|
|
228
|
+
hasAttemptedCreationRef.current = true;
|
|
200
229
|
setShouldCreateWallet(true);
|
|
201
230
|
}, [embeddedState, walletConfig === null || walletConfig === void 0 ? void 0 : walletConfig.connectOnLogin]);
|
|
202
231
|
useEffect(() => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -64,10 +64,11 @@ const LoadWallets = () => {
|
|
|
64
64
|
}
|
|
65
65
|
logger.log('User wallets loaded:', wallets.length);
|
|
66
66
|
if (wallets.length === 0) {
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
67
|
+
// Always show the create wallet page when no wallets exist.
|
|
68
|
+
// connectOnLogin only controls whether creation starts automatically
|
|
69
|
+
// (handled inside CreateWalletAutomaticRecovery), not whether the
|
|
70
|
+
// page is shown — routing to CONNECTED with 0 wallets would show a
|
|
71
|
+
// broken "Connect wallet" button aimed at external wagmi wallets.
|
|
71
72
|
setRoute(createRoute(chainType));
|
|
72
73
|
return;
|
|
73
74
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx } from 'react/jsx-runtime';
|
|
2
|
-
import { ChainTypeEnum } from '@openfort/openfort-js';
|
|
2
|
+
import { ChainTypeEnum, EmbeddedState } from '@openfort/openfort-js';
|
|
3
3
|
import React, { useEffect } from 'react';
|
|
4
4
|
import { useEthereumEmbeddedWallet } from '../../../ethereum/hooks/useEthereumEmbeddedWallet.js';
|
|
5
5
|
import { useOpenfortCore } from '../../../openfort/useOpenfort.js';
|
|
@@ -11,7 +11,7 @@ import { PageContent } from '../../PageContent/index.js';
|
|
|
11
11
|
|
|
12
12
|
const Loading = () => {
|
|
13
13
|
const { setRoute, walletConfig } = useOpenfort();
|
|
14
|
-
const { user, isLoadingAccounts, needsRecovery } = useOpenfortCore();
|
|
14
|
+
const { user, isLoadingAccounts, isLoading, needsRecovery, embeddedState } = useOpenfortCore();
|
|
15
15
|
const { chainType } = useOpenfortCore();
|
|
16
16
|
// Use chain-specific hooks
|
|
17
17
|
const ethereumWallet = useEthereumEmbeddedWallet();
|
|
@@ -24,7 +24,13 @@ const Loading = () => {
|
|
|
24
24
|
useEffect(() => {
|
|
25
25
|
if (isFirstFrame)
|
|
26
26
|
return;
|
|
27
|
-
|
|
27
|
+
// Wait for the SDK to settle. After storeCredentials the embedded state
|
|
28
|
+
// briefly stays UNAUTHENTICATED/NONE while the SDK processes the token.
|
|
29
|
+
// Routing to PROVIDERS here would abort the auth flow.
|
|
30
|
+
if (embeddedState === EmbeddedState.NONE || embeddedState === EmbeddedState.UNAUTHENTICATED)
|
|
31
|
+
return;
|
|
32
|
+
// Also wait while accounts or user are still loading.
|
|
33
|
+
if (isLoadingAccounts || isLoading)
|
|
28
34
|
return;
|
|
29
35
|
else if (!user)
|
|
30
36
|
setRoute(routes.PROVIDERS);
|
|
@@ -42,7 +48,7 @@ const Loading = () => {
|
|
|
42
48
|
}
|
|
43
49
|
else
|
|
44
50
|
setRoute(routes.CONNECTED);
|
|
45
|
-
}, [isLoadingAccounts, user, address, needsRecovery, isFirstFrame, retryCount]);
|
|
51
|
+
}, [embeddedState, isLoadingAccounts, isLoading, user, address, needsRecovery, isFirstFrame, retryCount]);
|
|
46
52
|
// Retry every 250ms
|
|
47
53
|
useEffect(() => {
|
|
48
54
|
const interval = setInterval(() => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -35,8 +35,11 @@ function useEmbeddedStateMachine({ openfort, storeEmbeddedState, storeUser, stor
|
|
|
35
35
|
setIsConnectedWithEmbeddedSigner(false);
|
|
36
36
|
// Validate token and fetch accounts. Auto-recovery is handled by the
|
|
37
37
|
// dedicated useAutoRecovery hook (keyed on storeActiveEmbeddedAddress).
|
|
38
|
+
// Never auto-logout here: during first OAuth sign-in the user isn't in
|
|
39
|
+
// the store yet and user.get() may briefly 401/404 before the token
|
|
40
|
+
// propagates — logging out would abort the entire auth flow.
|
|
38
41
|
const doFetch = async () => {
|
|
39
|
-
updateUserRef.current(undefined,
|
|
42
|
+
updateUserRef.current(undefined, false);
|
|
40
43
|
await fetchEmbeddedAccountsRef.current();
|
|
41
44
|
};
|
|
42
45
|
doFetch().catch((err) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useEmbeddedStateMachine.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"useEmbeddedStateMachine.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
package/build/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const OPENFORT_VERSION = "1.0.
|
|
1
|
+
export declare const OPENFORT_VERSION = "1.0.6";
|
package/build/version.js
CHANGED