diff --git a/native/account/fullscreen-siwe-panel.react.js b/native/account/fullscreen-siwe-panel.react.js
index c262abc51..65a07dede 100644
--- a/native/account/fullscreen-siwe-panel.react.js
+++ b/native/account/fullscreen-siwe-panel.react.js
@@ -1,54 +1,71 @@
// @flow
import * as React from 'react';
import { Alert, ActivityIndicator, View } from 'react-native';
+import type { SIWEResult } from 'lib/types/siwe-types.js';
+
import { useSIWEServerCall } from './siwe-hooks.js';
import SIWEPanel from './siwe-panel.react.js';
type Props = {
+onClose: () => mixed,
+closing: boolean,
};
function FullscreenSIWEPanel(props: Props): React.Node {
const [loading, setLoading] = React.useState(true);
const activity = loading ? : null;
const activityContainer = React.useMemo(
() => ({
flex: 1,
}),
[],
);
- const { onClose } = props;
+ const onCloseProp = props.onClose;
const siweServerCallParams = React.useMemo(() => {
const onServerCallFailure = () => {
Alert.alert(
'Unknown error',
'Uhh... try again?',
- [{ text: 'OK', onPress: onClose }],
+ [{ text: 'OK', onPress: onCloseProp }],
{ cancelable: false },
);
};
return { onFailure: onServerCallFailure };
- }, [onClose]);
+ }, [onCloseProp]);
const siweServerCall = useSIWEServerCall(siweServerCallParams);
+ const successRef = React.useRef(false);
+ const onSuccess = React.useCallback(
+ (result: SIWEResult) => {
+ successRef.current = true;
+ return siweServerCall(result);
+ },
+ [siweServerCall],
+ );
+
+ const onClose = React.useCallback(() => {
+ if (!successRef.current) {
+ onCloseProp();
+ }
+ }, [onCloseProp]);
+
const { closing } = props;
return (
<>
{activity}
>
);
}
export default FullscreenSIWEPanel;
diff --git a/native/account/siwe-panel.react.js b/native/account/siwe-panel.react.js
index 16bc82452..a91452962 100644
--- a/native/account/siwe-panel.react.js
+++ b/native/account/siwe-panel.react.js
@@ -1,212 +1,206 @@
// @flow
import BottomSheet from '@gorhom/bottom-sheet';
import * as React from 'react';
import { Alert } from 'react-native';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
import WebView from 'react-native-webview';
import {
getSIWENonce,
getSIWENonceActionTypes,
siweAuthActionTypes,
} from 'lib/actions/siwe-actions.js';
import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors.js';
import type { SIWEWebViewMessage, SIWEResult } from 'lib/types/siwe-types.js';
import {
useServerCall,
useDispatchActionPromise,
} from 'lib/utils/action-utils.js';
import { commCoreModule } from '../native-modules.js';
import { useSelector } from '../redux/redux-utils.js';
import { defaultLandingURLPrefix } from '../utils/url-utils.js';
const commSIWE = `${defaultLandingURLPrefix}/siwe`;
const getSIWENonceLoadingStatusSelector = createLoadingStatusSelector(
getSIWENonceActionTypes,
);
const siweAuthLoadingStatusSelector =
createLoadingStatusSelector(siweAuthActionTypes);
type Props = {
+onClosed: () => mixed,
+onClosing: () => mixed,
+onSuccessfulWalletSignature: SIWEResult => mixed,
+closing: boolean,
+setLoading: boolean => mixed,
};
function SIWEPanel(props: Props): React.Node {
const dispatchActionPromise = useDispatchActionPromise();
const getSIWENonceCall = useServerCall(getSIWENonce);
const getSIWENonceCallFailed = useSelector(
state => getSIWENonceLoadingStatusSelector(state) === 'error',
);
const { onClosing } = props;
React.useEffect(() => {
if (getSIWENonceCallFailed) {
Alert.alert(
'Unknown error',
'Uhh... try again?',
[{ text: 'OK', onPress: onClosing }],
{ cancelable: false },
);
}
}, [getSIWENonceCallFailed, onClosing]);
const siweAuthCallLoading = useSelector(
state => siweAuthLoadingStatusSelector(state) === 'loading',
);
const [nonce, setNonce] = React.useState(null);
const [primaryIdentityPublicKey, setPrimaryIdentityPublicKey] =
React.useState(null);
React.useEffect(() => {
(async () => {
dispatchActionPromise(
getSIWENonceActionTypes,
(async () => {
const response = await getSIWENonceCall();
setNonce(response);
})(),
);
await commCoreModule.initializeCryptoAccount();
const {
primaryIdentityPublicKeys: { ed25519 },
} = await commCoreModule.getUserPublicKey();
setPrimaryIdentityPublicKey(ed25519);
})();
}, [dispatchActionPromise, getSIWENonceCall]);
const [isLoading, setLoading] = React.useState(true);
const [isWalletConnectModalOpen, setWalletConnectModalOpen] =
React.useState(false);
const insets = useSafeAreaInsets();
const bottomInset = insets.bottom;
const snapPoints = React.useMemo(() => {
if (isLoading) {
return [1];
} else if (isWalletConnectModalOpen) {
return [bottomInset + 600];
} else {
return [bottomInset + 435, bottomInset + 600];
}
}, [isLoading, isWalletConnectModalOpen, bottomInset]);
const bottomSheetRef = React.useRef();
const snapToIndex = bottomSheetRef.current?.snapToIndex;
React.useEffect(() => {
// When the snapPoints change, always reset to the first one
// Without this, when we close the WalletConnect modal we don't resize
snapToIndex?.(0);
}, [snapToIndex, snapPoints]);
const closeBottomSheet = bottomSheetRef.current?.close;
const { closing, onSuccessfulWalletSignature } = props;
- const disableOnClose = React.useRef(false);
const handleMessage = React.useCallback(
async event => {
const data: SIWEWebViewMessage = JSON.parse(event.nativeEvent.data);
if (data.type === 'siwe_success') {
const { address, message, signature } = data;
if (address && signature) {
- disableOnClose.current = true;
closeBottomSheet?.();
await onSuccessfulWalletSignature({ address, message, signature });
}
} else if (data.type === 'siwe_closed') {
onClosing();
closeBottomSheet?.();
} else if (data.type === 'walletconnect_modal_update') {
setWalletConnectModalOpen(data.state === 'open');
}
},
[onSuccessfulWalletSignature, onClosing, closeBottomSheet],
);
const prevClosingRef = React.useRef();
React.useEffect(() => {
if (closing && !prevClosingRef.current) {
closeBottomSheet?.();
}
prevClosingRef.current = closing;
}, [closing, closeBottomSheet]);
const source = React.useMemo(
() => ({
uri: commSIWE,
headers: {
'siwe-nonce': nonce,
'siwe-primary-identity-public-key': primaryIdentityPublicKey,
},
}),
[nonce, primaryIdentityPublicKey],
);
const onWebViewLoaded = React.useCallback(() => {
setLoading(false);
}, []);
const backgroundStyle = React.useMemo(
() => ({
backgroundColor: '#242529',
}),
[],
);
const bottomSheetHandleIndicatorStyle = React.useMemo(
() => ({
backgroundColor: 'white',
}),
[],
);
const { onClosed } = props;
const onBottomSheetChange = React.useCallback(
(index: number) => {
- if (disableOnClose.current) {
- disableOnClose.current = false;
- return;
- }
if (index === -1) {
onClosed();
}
},
[onClosed],
);
let bottomSheet;
if (nonce && primaryIdentityPublicKey) {
bottomSheet = (
);
}
const setLoadingProp = props.setLoading;
const loading = !getSIWENonceCallFailed && (isLoading || siweAuthCallLoading);
React.useEffect(() => {
setLoadingProp(loading);
}, [setLoadingProp, loading]);
return bottomSheet;
}
export default SIWEPanel;