diff --git a/landing/siwe.react.js b/landing/siwe.react.js
index 74ec33eb3..7841a2658 100644
--- a/landing/siwe.react.js
+++ b/landing/siwe.react.js
@@ -1,173 +1,173 @@
// @flow
import {
useConnectModal,
getDefaultWallets,
RainbowKitProvider,
darkTheme,
useModalState,
ConnectButton,
} from '@rainbow-me/rainbowkit';
import invariant from 'invariant';
import _merge from 'lodash/fp/merge';
import * as React from 'react';
import '@rainbow-me/rainbowkit/dist/index.css';
import { useAccount, useSigner, WagmiConfig } from 'wagmi';
import type { SIWEWebViewMessage } from 'lib/types/siwe-types';
import {
getSIWEStatementForPublicKey,
siweStatementWithoutPublicKey,
siweMessageSigningExplanationStatements,
createSIWEMessage,
} from 'lib/utils/siwe-utils.js';
import { configureWagmiChains, createWagmiClient } from 'lib/utils/wagmi-utils';
import { SIWEContext } from './siwe-context.js';
import css from './siwe.css';
const { chains, provider } = configureWagmiChains(process.env.COMM_ALCHEMY_KEY);
const { connectors } = getDefaultWallets({ appName: 'comm', chains });
const wagmiClient = createWagmiClient({ connectors, provider });
function postMessageToNativeWebView(message: SIWEWebViewMessage) {
window.ReactNativeWebView?.postMessage?.(JSON.stringify(message));
}
async function signInWithEthereum(
address: string,
signer,
nonce: string,
statement: string,
) {
invariant(nonce, 'nonce must be present in signInWithEthereum');
const message = createSIWEMessage(address, statement, nonce);
const signature = await signer.signMessage(message);
postMessageToNativeWebView({
type: 'siwe_success',
address,
message,
signature,
});
}
function SIWE(): React.Node {
const { address } = useAccount();
const { data: signer } = useSigner();
const { siweNonce, siwePrimaryIdentityPublicKey } = React.useContext(
SIWEContext,
);
const onClick = React.useCallback(() => {
invariant(siweNonce, 'nonce must be present during SIWE attempt');
const statement = siwePrimaryIdentityPublicKey
? getSIWEStatementForPublicKey(siwePrimaryIdentityPublicKey)
: siweStatementWithoutPublicKey;
signInWithEthereum(address, signer, siweNonce, statement);
}, [address, signer, siweNonce, siwePrimaryIdentityPublicKey]);
const { openConnectModal } = useConnectModal();
const hasNonce = siweNonce !== null && siweNonce !== undefined;
React.useEffect(() => {
if (hasNonce && openConnectModal) {
openConnectModal();
}
}, [hasNonce, openConnectModal]);
const prevConnectModalOpen = React.useRef(false);
const modalState = useModalState();
const { connectModalOpen } = modalState;
React.useEffect(() => {
if (!connectModalOpen && prevConnectModalOpen.current && !signer) {
postMessageToNativeWebView({ type: 'siwe_closed' });
}
prevConnectModalOpen.current = connectModalOpen;
}, [connectModalOpen, signer]);
const newModalAppeared = React.useCallback(mutationList => {
for (const mutation of mutationList) {
for (const addedNode of mutation.addedNodes) {
if (
addedNode instanceof HTMLElement &&
addedNode.id === 'walletconnect-wrapper'
) {
postMessageToNativeWebView({
type: 'walletconnect_modal_update',
state: 'open',
});
}
}
for (const addedNode of mutation.removedNodes) {
if (
addedNode instanceof HTMLElement &&
addedNode.id === 'walletconnect-wrapper'
) {
postMessageToNativeWebView({
type: 'walletconnect_modal_update',
state: 'closed',
});
}
}
}
}, []);
React.useEffect(() => {
const observer = new MutationObserver(newModalAppeared);
invariant(document.body, 'document.body should be set');
observer.observe(document.body, { childList: true });
return () => {
observer.disconnect();
};
}, [newModalAppeared]);
if (!hasNonce) {
return (
Unable to proceed: nonce not found.
);
} else if (!signer) {
return null;
} else {
return (
Wallet Connected:
{siweMessageSigningExplanationStatements[0]}
{siweMessageSigningExplanationStatements[1]}
By signing up, you agree to our{' '}
Terms of Use &{' '}
Privacy Policy.
- Sign in
+ Sign in using this wallet
);
}
}
function SIWEWrapper(): React.Node {
const theme = React.useMemo(() => {
return _merge(darkTheme())({
radii: {
modal: 0,
modalMobile: 0,
},
colors: {
modalBackdrop: '#242529',
},
});
}, []);
return (
);
}
export default SIWEWrapper;
diff --git a/web/account/siwe-login-form.react.js b/web/account/siwe-login-form.react.js
index 7f146a0dd..abee22776 100644
--- a/web/account/siwe-login-form.react.js
+++ b/web/account/siwe-login-form.react.js
@@ -1,159 +1,159 @@
// @flow
import '@rainbow-me/rainbowkit/dist/index.css';
import olm from '@matrix-org/olm';
import { ConnectButton } from '@rainbow-me/rainbowkit';
import invariant from 'invariant';
import * as React from 'react';
import { useDispatch } from 'react-redux';
import { useAccount, useSigner } from 'wagmi';
import {
getSIWENonce,
getSIWENonceActionTypes,
siweAuth,
siweAuthActionTypes,
} from 'lib/actions/siwe-actions';
import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors';
import type { LogInStartingPayload } from 'lib/types/account-types.js';
import {
useDispatchActionPromise,
useServerCall,
} from 'lib/utils/action-utils';
import {
createSIWEMessage,
getSIWEStatementForPublicKey,
siweMessageSigningExplanationStatements,
} from 'lib/utils/siwe-utils.js';
import Button from '../components/button.react';
import LoadingIndicator from '../loading-indicator.react';
import { setPrimaryIdentityPublicKey } from '../redux/primary-identity-public-key-reducer';
import { useSelector } from '../redux/redux-utils';
import { webLogInExtraInfoSelector } from '../selectors/account-selectors.js';
import css from './siwe.css';
type SIWELoginFormProps = {
+cancelSIWEAuthFlow: () => void,
};
const getSIWENonceLoadingStatusSelector = createLoadingStatusSelector(
getSIWENonceActionTypes,
);
function SIWELoginForm(props: SIWELoginFormProps): React.Node {
const { address } = useAccount();
const { data: signer } = useSigner();
const dispatch = useDispatch();
const dispatchActionPromise = useDispatchActionPromise();
const getSIWENonceCall = useServerCall(getSIWENonce);
const getSIWENonceCallLoadingStatus = useSelector(
getSIWENonceLoadingStatusSelector,
);
const siweAuthCall = useServerCall(siweAuth);
const logInExtraInfo = useSelector(webLogInExtraInfoSelector);
const [siweNonce, setSIWENonce] = React.useState(null);
const siweNonceShouldBeFetched =
!siweNonce && getSIWENonceCallLoadingStatus !== 'loading';
React.useEffect(() => {
if (!siweNonceShouldBeFetched) {
return;
}
dispatchActionPromise(
getSIWENonceActionTypes,
(async () => {
const response = await getSIWENonceCall();
setSIWENonce(response);
})(),
);
}, [dispatchActionPromise, getSIWENonceCall, siweNonceShouldBeFetched]);
const primaryIdentityPublicKey = useSelector(
state => state.primaryIdentityPublicKey,
);
React.useEffect(() => {
(async () => {
await olm.init();
const account = new olm.Account();
account.create();
const { ed25519 } = JSON.parse(account.identity_keys());
dispatch({
type: setPrimaryIdentityPublicKey,
payload: ed25519,
});
})();
}, [dispatch]);
const callSIWEAuthEndpoint = React.useCallback(
(message: string, signature: string, extraInfo) =>
siweAuthCall({
message,
signature,
...extraInfo,
}),
[siweAuthCall],
);
const attemptSIWEAuth = React.useCallback(
(message: string, signature: string) => {
const extraInfo = logInExtraInfo();
dispatchActionPromise(
siweAuthActionTypes,
callSIWEAuthEndpoint(message, signature, extraInfo),
undefined,
({ calendarQuery: extraInfo.calendarQuery }: LogInStartingPayload),
);
},
[callSIWEAuthEndpoint, dispatchActionPromise, logInExtraInfo],
);
const onSignInButtonClick = React.useCallback(async () => {
invariant(signer, 'signer must be present during SIWE attempt');
invariant(siweNonce, 'nonce must be present during SIWE attempt');
invariant(
primaryIdentityPublicKey,
'primaryIdentityPublicKey must be present during SIWE attempt',
);
const statement = getSIWEStatementForPublicKey(primaryIdentityPublicKey);
const message = createSIWEMessage(address, statement, siweNonce);
const signature = await signer.signMessage(message);
attemptSIWEAuth(message, signature);
}, [address, attemptSIWEAuth, primaryIdentityPublicKey, signer, siweNonce]);
const { cancelSIWEAuthFlow } = props;
if (!siweNonce || !primaryIdentityPublicKey) {
return (
);
}
return (
{siweMessageSigningExplanationStatements[0]}
{siweMessageSigningExplanationStatements[1]}
By signing up, you agree to our{' '}
Terms of Use &{' '}
Privacy Policy.
);
}
export default SIWELoginForm;