create wallet context + wallet components
create wallet context using cosmoskit + include nymclient + create wallet components
This commit is contained in:
@@ -1,78 +0,0 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { useChain } from '@cosmos-kit/react';
|
||||
import { Box, Button, Typography, IconButton, Stack } from '@mui/material';
|
||||
import CloseIcon from '@mui/icons-material/Close';
|
||||
import { TokenSVG } from '../icons/TokenSVG';
|
||||
import { ElipsSVG } from '../icons/ElipsSVG';
|
||||
import { trimAddress } from '../utils';
|
||||
import { unymToNym } from '../utils/currency';
|
||||
import { useIsMobile } from '../hooks/useIsMobile';
|
||||
|
||||
export const ConnectKeplrWallet = () => {
|
||||
const { connect, disconnect, wallet, address, getCosmWasmClient, isWalletConnected, isWalletConnecting } =
|
||||
useChain('nyx');
|
||||
const isMobile = useIsMobile(1200);
|
||||
|
||||
const [balance, setBalance] = useState<{
|
||||
status: 'loading' | 'success';
|
||||
data?: string;
|
||||
}>({ status: 'loading', data: undefined });
|
||||
|
||||
useEffect(() => {
|
||||
const getBalance = async (walletAddress: string) => {
|
||||
setBalance({ status: 'loading', data: undefined });
|
||||
|
||||
const account = await getCosmWasmClient();
|
||||
const uNYMBalance = await account.getBalance(walletAddress, 'unym');
|
||||
const NYMBalance = unymToNym(uNYMBalance.amount);
|
||||
|
||||
setBalance({ status: 'success', data: NYMBalance });
|
||||
};
|
||||
|
||||
if (address) {
|
||||
getBalance(address);
|
||||
}
|
||||
}, [address, getCosmWasmClient]);
|
||||
|
||||
const getGlobalbutton = () => {
|
||||
if (isWalletConnecting) {
|
||||
return <Button onClick={() => connect()}>{`Connecting ${wallet?.prettyName}`}</Button>;
|
||||
}
|
||||
if (isWalletConnected) {
|
||||
return (
|
||||
<Stack direction="row" spacing={1}>
|
||||
{!isMobile && (
|
||||
<Box display="flex" alignItems="center" gap={1}>
|
||||
<TokenSVG />
|
||||
<Typography variant="body1" fontWeight={600}>
|
||||
{balance.data} NYM
|
||||
</Typography>
|
||||
</Box>
|
||||
)}{' '}
|
||||
<Box display="flex" alignItems="center" gap={1}>
|
||||
<ElipsSVG />
|
||||
<Typography variant="body1" fontWeight={600}>
|
||||
{trimAddress(address, 7)}
|
||||
</Typography>
|
||||
</Box>
|
||||
<IconButton
|
||||
size="small"
|
||||
onClick={async () => {
|
||||
await disconnect();
|
||||
}}
|
||||
>
|
||||
<CloseIcon fontSize="small" sx={{ color: 'white' }} />
|
||||
</IconButton>
|
||||
</Stack>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Button variant="outlined" onClick={() => connect()}>
|
||||
Connect {isMobile ? '' : ' Wallet'}
|
||||
</Button>
|
||||
);
|
||||
};
|
||||
|
||||
return <Box>{getGlobalbutton()}</Box>;
|
||||
};
|
||||
@@ -0,0 +1,43 @@
|
||||
import React from 'react';
|
||||
import { Button, IconButton, Stack, CircularProgress } from '@mui/material';
|
||||
import CloseIcon from '@mui/icons-material/Close';
|
||||
import { useIsMobile } from '@src/hooks/useIsMobile';
|
||||
import { useWalletContext } from '@src/context/wallet';
|
||||
import { WalletAddress, WalletBalance } from '@src/components/Wallet';
|
||||
|
||||
export const ConnectKeplrWallet = () => {
|
||||
const { connectWallet, disconnectWallet, isWalletConnected, isWalletConnecting } = useWalletContext();
|
||||
const isMobile = useIsMobile(1200);
|
||||
|
||||
if (!connectWallet || !disconnectWallet) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (isWalletConnected) {
|
||||
return (
|
||||
<Stack direction="row" spacing={1}>
|
||||
<WalletBalance />
|
||||
<WalletAddress />
|
||||
<IconButton
|
||||
size="small"
|
||||
onClick={async () => {
|
||||
await disconnectWallet();
|
||||
}}
|
||||
>
|
||||
<CloseIcon fontSize="small" sx={{ color: 'white' }} />
|
||||
</IconButton>
|
||||
</Stack>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Button
|
||||
variant="outlined"
|
||||
onClick={() => connectWallet()}
|
||||
disabled={isWalletConnecting}
|
||||
endIcon={isWalletConnecting && <CircularProgress size={14} color="inherit" />}
|
||||
>
|
||||
Connect {isMobile ? '' : ' Wallet'}
|
||||
</Button>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,20 @@
|
||||
import React from 'react';
|
||||
import { Box, Typography } from '@mui/material';
|
||||
import { ElipsSVG } from '@src/icons/ElipsSVG';
|
||||
import { trimAddress } from '@src/utils';
|
||||
import { useWalletContext } from '@src/context/wallet';
|
||||
|
||||
export const WalletAddress = () => {
|
||||
const { address } = useWalletContext();
|
||||
|
||||
const displayAddress = trimAddress(address, 7);
|
||||
|
||||
return (
|
||||
<Box display="flex" alignItems="center" gap={0.5}>
|
||||
<ElipsSVG />
|
||||
<Typography variant="body1" fontWeight={600}>
|
||||
{displayAddress}
|
||||
</Typography>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,25 @@
|
||||
import React from 'react';
|
||||
import { Box, Typography } from '@mui/material';
|
||||
import { useWalletContext } from '@src/context/wallet';
|
||||
import { useIsMobile } from '@src/hooks';
|
||||
import { TokenSVG } from '@src/icons/TokenSVG';
|
||||
|
||||
export const WalletBalance = () => {
|
||||
const { balance } = useWalletContext();
|
||||
const isMobile = useIsMobile(1200);
|
||||
|
||||
const showBalance = !isMobile && balance.status === 'success';
|
||||
|
||||
if (!showBalance) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<Box display="flex" alignItems="center" gap={1}>
|
||||
<TokenSVG />
|
||||
<Typography variant="body1" fontWeight={600}>
|
||||
{balance.data} NYM
|
||||
</Typography>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
@@ -2,10 +2,11 @@ import React from 'react';
|
||||
import { ChainProvider } from '@cosmos-kit/react';
|
||||
import { wallets as keplr } from '@cosmos-kit/keplr';
|
||||
import { wallets as ledger } from '@cosmos-kit/ledger';
|
||||
import { wallets as cosmosstation } from '@cosmos-kit/cosmostation';
|
||||
import { assets, chains } from 'chain-registry';
|
||||
|
||||
const CosmosKitProvider = ({ children }: { children: React.ReactNode }) => (
|
||||
<ChainProvider chains={chains} assetLists={assets} wallets={[...keplr, ...ledger]}>
|
||||
<ChainProvider chains={chains} assetLists={assets} wallets={[...keplr, ...ledger, ...cosmosstation]}>
|
||||
{children}
|
||||
</ChainProvider>
|
||||
);
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
import React, { createContext, useContext, useEffect, useMemo, useState } from 'react';
|
||||
import { useChain } from '@cosmos-kit/react';
|
||||
import { Wallet } from '@cosmos-kit/core';
|
||||
|
||||
import { unymToNym } from '@src/utils/currency';
|
||||
import { useNymClient } from '@src/hooks';
|
||||
import { MixnetClient, MixnetQueryClient } from '@nymproject/contract-clients/Mixnet.client';
|
||||
|
||||
interface WalletState {
|
||||
balance: { status: 'loading' | 'success'; data?: string };
|
||||
address?: string;
|
||||
isWalletConnected: boolean;
|
||||
isWalletConnecting: boolean;
|
||||
wallet?: Wallet;
|
||||
nymClient?: MixnetClient;
|
||||
nymQueryClient?: MixnetQueryClient;
|
||||
connectWallet: () => Promise<void>;
|
||||
disconnectWallet: () => Promise<void>;
|
||||
}
|
||||
|
||||
export const WalletContext = createContext<WalletState>({
|
||||
address: undefined,
|
||||
balance: { status: 'loading', data: undefined },
|
||||
isWalletConnected: false,
|
||||
isWalletConnecting: false,
|
||||
nymClient: undefined,
|
||||
nymQueryClient: undefined,
|
||||
connectWallet: async () => {
|
||||
throw new Error('Please connect your wallet');
|
||||
},
|
||||
disconnectWallet: async () => {
|
||||
throw new Error('Please connect your wallet');
|
||||
},
|
||||
});
|
||||
|
||||
export const WalletProvider = ({ children }: { children: React.ReactNode }) => {
|
||||
const [balance, setBalance] = useState<WalletState['balance']>({ status: 'loading', data: undefined });
|
||||
|
||||
const { connect, disconnect, wallet, address, isWalletConnected, isWalletConnecting, getCosmWasmClient } =
|
||||
useChain('nyx');
|
||||
|
||||
const { nymClient, nymQueryClient } = useNymClient(address);
|
||||
|
||||
const getBalance = async (walletAddress: string) => {
|
||||
const account = await getCosmWasmClient();
|
||||
const uNYMBalance = await account.getBalance(walletAddress, 'unym');
|
||||
const NYMBalance = unymToNym(uNYMBalance.amount);
|
||||
|
||||
return NYMBalance;
|
||||
};
|
||||
|
||||
const init = async (walletAddress: string) => {
|
||||
const walletBalance = await getBalance(walletAddress);
|
||||
setBalance({ status: 'success', data: walletBalance });
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (isWalletConnected && address) {
|
||||
init(address);
|
||||
}
|
||||
}, [address, isWalletConnected]);
|
||||
|
||||
const handleConnectWallet = async () => {
|
||||
await connect();
|
||||
};
|
||||
|
||||
const handleDisconnectWallet = async () => {
|
||||
await disconnect();
|
||||
setBalance({ status: 'loading', data: undefined });
|
||||
};
|
||||
|
||||
const contextValue: WalletState = useMemo(
|
||||
() => ({
|
||||
address,
|
||||
balance,
|
||||
wallet,
|
||||
isWalletConnected,
|
||||
isWalletConnecting,
|
||||
nymClient,
|
||||
nymQueryClient,
|
||||
connectWallet: handleConnectWallet,
|
||||
disconnectWallet: handleDisconnectWallet,
|
||||
}),
|
||||
[address, balance, wallet, isWalletConnected, isWalletConnecting, nymClient, nymQueryClient],
|
||||
);
|
||||
|
||||
return <WalletContext.Provider value={contextValue}>{children}</WalletContext.Provider>;
|
||||
};
|
||||
|
||||
export const useWalletContext = () => useContext(WalletContext);
|
||||
@@ -0,0 +1,31 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import { useChain } from '@cosmos-kit/react';
|
||||
import { contracts } from '@nymproject/contract-clients';
|
||||
import { MixnetClient, MixnetQueryClient } from '@nymproject/contract-clients/Mixnet.client';
|
||||
import { NYM_MIXNET_CONTRACT } from '@src/api/constants';
|
||||
|
||||
export const useNymClient = (address?: string) => {
|
||||
const [nymClient, setNymClient] = useState<MixnetClient>();
|
||||
const [nymQueryClient, setNymQueryClient] = useState<MixnetQueryClient>();
|
||||
|
||||
const { getCosmWasmClient, getSigningCosmWasmClient } = useChain('nyx');
|
||||
|
||||
useEffect(() => {
|
||||
if (address) {
|
||||
const init = async () => {
|
||||
const cosmWasmSigningClient = await getSigningCosmWasmClient();
|
||||
const cosmWasmClient = await getCosmWasmClient();
|
||||
|
||||
const client = new contracts.Mixnet.MixnetClient(cosmWasmSigningClient as any, address, NYM_MIXNET_CONTRACT);
|
||||
const queryClient = new contracts.Mixnet.MixnetQueryClient(cosmWasmClient as any, NYM_MIXNET_CONTRACT);
|
||||
|
||||
setNymClient(client);
|
||||
setNymQueryClient(queryClient);
|
||||
};
|
||||
|
||||
init();
|
||||
}
|
||||
}, [address, getCosmWasmClient, getSigningCosmWasmClient]);
|
||||
|
||||
return { nymClient, nymQueryClient };
|
||||
};
|
||||
Reference in New Issue
Block a user