connector-wallet/WalletAuthorizer.tsx (74 lines of code) (raw):
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { ConnectButton } from '@rainbow-me/rainbowkit';
import { useConfig, useSwitchChain, useSignMessage } from 'wagmi';
import { sha256 } from 'js-sha256';
import { useTranslation } from 'react-i18next';
import { Button } from 'react-bootstrap';
function getSearchParamValue(key: string, defaultValue: string = '') {
return location.search && new URLSearchParams(location.search.slice()).get(key) || defaultValue;
}
function WalletAuthorizer() {
const { chains } = useConfig();
const { switchChain } = useSwitchChain();
const { signMessageAsync } = useSignMessage();
const { t } = useTranslation('plugin', {
keyPrefix: 'wallet_connector.frontend',
});
return (
<ConnectButton.Custom>
{({
account,
chain,
openAccountModal,
openChainModal,
openConnectModal,
authenticationStatus,
mounted,
}) => {
const ready = mounted && authenticationStatus !== 'loading';
const connected = ready && account && chain && (!authenticationStatus || authenticationStatus === 'authenticated');
const { address } = account || { address: '' };
const handleSwitchNetwork = () => {
if (chains.length === 1) {
switchChain({ chainId: chains[0].id });
} else {
openChainModal();
}
};
const handleAuthorize = async () => {
const nonce = getSearchParamValue('nonce', sha256(address));
const signature = await signMessageAsync({ message: nonce });
location.href = `/answer/api/v1/connector/redirect/wallet?message=${nonce}&signature=${signature}&address=${address}&redirect=${getSearchParamValue('redirect')}`;
}
return (
<div>
{(() => {
let description: React.ReactNode;
let actionList: React.ReactNode;
if (!connected) {
description = <>{t('wallet_needed')}</>;
actionList = <Button onClick={() => openConnectModal()}>{t('connect_button')}</Button>;
} else if (chain.unsupported) {
description = <>{t('wrong_network')}</>;
actionList = <Button onClick={handleSwitchNetwork}>{t('switch_button')}</Button>;
} else {
const translatedArr = t('connected_wallet').split('${ADDRESS}') as React.ReactNode[];
translatedArr.splice(1, 0, <strong style={{ cursor: 'pointer' }} onClick={() => openAccountModal()}>{address.replace(address.slice(6, -4), '...')}</strong>);
description = <>{translatedArr.map((c, i) => <span key={i}>{c}</span>)}</>;
actionList = (
<>
<Button onClick={handleAuthorize}>{t('authorize_button')}</Button>
<Button variant="outline-secondary" onClick={() => openAccountModal()}>{t('disconnect_button')}</Button>
</>
);
}
return (
<>
<p>{description}</p>
<div className="d-grid gap-2">{actionList}</div>
</>
);
})()}
</div>
);
}}
</ConnectButton.Custom>
);
}
export default WalletAuthorizer;