trade-frontend/src/components/UI/ConnectButton/ConnectButton.tsx
Claude 677b844aaa
rebrand(lethean): update branding, ports, and config for Lethean blockchain
- Coin: Zano → Lethean, ticker: ZAN/ZANO → LTHN
- Ports: 11211 → 36941 (mainnet RPC), 46941 (testnet RPC)
- Wallet: 11212 → 36944/46944
- Address prefix: iTHN
- URLs: zano.org → lethean.io
- Explorer links: explorer.lthn.io

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 22:24:09 +01:00

143 lines
3.6 KiB
TypeScript

import { useContext, useState } from 'react';
import { Store } from '@/store/store-reducer';
import { updateWalletState } from '@/store/actions';
import Alert from '@/components/UI/Alert/Alert';
import useUpdateUser from '@/hook/useUpdateUser';
import AlertType from '@/interfaces/common/AlertType';
import ConnectButtonProps from '@/interfaces/props/components/UI/ConnectButton/ConnectButtonProps';
import LtheanWindow from '@/interfaces/common/LtheanWindow';
import Button from '../Button/Button';
function ConnectButton(props: ConnectButtonProps) {
const [alertState, setAlertState] = useState<AlertType>(null);
const [alertErrMessage, setAlertErrMessage] = useState<string>();
const { state, dispatch } = useContext(Store);
const logged = !!state.wallet?.connected;
const fetchUser = useUpdateUser();
async function connect() {
if (alertState) return;
try {
setAlertState('loading');
await new Promise((resolve) => setTimeout(resolve, 1000));
const walletData = (
await (window as unknown as LtheanWindow).lethean.request('GET_WALLET_DATA')
).data;
const walletAddress = walletData?.address;
const walletAlias = walletData?.alias;
if (!walletAddress) {
throw new Error('Companion is offline');
}
if (!walletAlias) {
throw new Error('Alias not found');
}
if (typeof walletAddress !== 'string' || typeof walletAlias !== 'string') {
throw new Error('Invalid wallet data');
}
const authRequestRes = await fetch('/api/auth/request-auth', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
address: walletAddress,
alias: walletAlias,
}),
}).then((res) => res.json());
const authMessage = authRequestRes?.data;
if (!authRequestRes.success || typeof authMessage !== 'string') {
throw new Error('Unknown error during auth request');
}
const signResult = await (window as unknown as LtheanWindow).lethean.request(
'REQUEST_MESSAGE_SIGN',
{ message: authMessage },
null,
);
if (!signResult?.data?.result) {
throw new Error('Sign denied');
}
const signature = signResult.data.result.sig;
const publicKey = signResult.data.result.pkey;
const result = await fetch('/api/auth', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
data: {
alias: walletAlias,
address: walletAddress,
signature,
publicKey,
message: authMessage,
},
}),
}).then((res) => res.json());
if (!result?.success) {
throw new Error('Server auth error');
}
sessionStorage.setItem('token', result?.data);
updateWalletState(dispatch, { ...walletData, connected: true });
await fetchUser();
await Notification.requestPermission();
setAlertState('success');
setTimeout(() => setAlertState(null), 3000);
} catch (error) {
setAlertState('error');
setAlertErrMessage((error as { message: string }).message);
setTimeout(() => setAlertState(null), 3000);
}
}
let alertSubtitle: string;
if (alertState === 'loading') {
alertSubtitle = 'Loading wallet data...';
} else if (alertState === 'success') {
alertSubtitle = 'Wallet connected';
} else {
alertSubtitle = alertErrMessage || 'Connection error';
}
return (
<>
{!logged && (
<Button
onClick={connect}
className={props.className}
transparent={props.transparent}
>
Connect Wallet
</Button>
)}
{alertState && (
<Alert
type={alertState}
subtitle={alertSubtitle}
close={() => setAlertState(null)}
/>
)}
</>
);
}
export default ConnectButton;