I have an API call that im using to get an amount of tokens in this case the comission.
import { ChainName } from '@cosmos-kit/core';
import { akash, osmosis } from '../../codegen';
import { useEffect, useState } from 'react';
const selectedChainKey = 'selected-chain';
export function useCommission(): number {
const [commission, setCommission] = useState<number>(0);
useEffect(() => {
const fetchCommission = async (chainName: ChainName): Promise<number> => {
if (chainName !== 'akash' && chainName !== 'osmosis') {
throw new Error(`Unsupported chain: ${chainName}`);
}
let client;
let denom: string;
let validatorAddress: string;
switch (chainName) {
case 'akash':
client = await akash.ClientFactory.createLCDClient({
restEndpoint: 'https://akash.api.chandrastation.com'
});
denom = 'uakt';
validatorAddress = 'akashvaloper1lxh0u07haj646pt9e0l2l4qc3d8htfx5kk698d';
break;
case 'osmosis':
client = await osmosis.ClientFactory.createLCDClient({
restEndpoint: 'https://osmosis.api.chandrastation.com'
});
denom = 'uosmo';
validatorAddress = 'osmovaloper10ymws40tepmjcu3a2wuy266ddna4ktas0zuzm4';
break;
}
const data = await client.cosmos.distribution.v1beta1.validatorCommission({
validatorAddress: validatorAddress
});
const commission = data.commission?.commission;
let amount = 0;
if (commission && commission.length > 0) {
amount = parseInt(commission.find((c: any) => c.denom === denom)?.amount || '0');
}
const roundedCommission = Math.round(Number(amount)) / 100;
const roundedAmount = Math.round(roundedCommission) / 100;
return roundedAmount / 100;
};
const onStorageChange = async () => {
const chainName = window.localStorage.getItem(selectedChainKey) as ChainName;
const commission = await fetchCommission(chainName);
setCommission(commission);
};
onStorageChange();
// Set up event listener for changes to selected chain in local storage
window.addEventListener('storage', (event) => {
if (event.key === selectedChainKey) {
onStorageChange();
}
});
return () => window.removeEventListener('storage', onStorageChange);
}, []);
return commission;
}
Im returning that commission amount to the front end here
import { SetStateAction, useEffect, useState } from 'react';
import { Box, Button, ButtonGroup, Center, Container, Flex, Heading, Link, Stack, StackDivider, Stat, StatHelpText, StatLabel, StatNumber } from '@chakra-ui/react';
import { Card, CardHeader, CardBody, CardFooter } from '@chakra-ui/react';
import { useCommission } from './queries/commission-query';
export default function DistributionBox() {
const [activeButton, setActiveButton] = useState('commission');
const [commission, setCommission] = useState<number | undefined>();
const commissionValue = useCommission();
useEffect(() => {
setCommission(commissionValue);
}, [commissionValue]);
const handleButtonClick = (button: SetStateAction<string>) => {
setActiveButton(button);
};
return (
<Container maxW="8xl" py={10} alignContent="center" pt="200px" pr="150px" >
<Flex alignItems="center" justifyContent="center">
<Card>
<CardBody alignContent="center" position="relative" >
<ButtonGroup paddingBottom="25px" justifyContent="space-between" gap='4'>
<Button colorScheme="teal" variant="outline" onClick={() => handleButtonClick('commission')}>Commission</Button>
<Button colorScheme="teal" variant="outline" onClick={() => handleButtonClick('staking')}>Staking</Button>
<Button colorScheme="teal" variant="outline" onClick={() => handleButtonClick('unjail')}>Unjail</Button>
</ButtonGroup>
<Box bgSize='450px'>
{activeButton === 'commission' && (
<Card minWidth="600px" padding='40px' pb="40px">
<CardHeader>
<Heading size='lg'>Claim your commission</Heading>
</CardHeader>
<CardBody>
<Stack divider={<StackDivider />} spacing='4'>
<Box>
<Heading size='xs' textTransform='uppercase'>
Claimmable Amount
</Heading>
<Stat>
<StatNumber>{commission}</StatNumber>
<StatHelpText>OSMO</StatHelpText>
</Stat>
</Box>
<Box>
<Heading size='xs' textTransform='uppercase'>
Validator Address
</Heading>
<text>
Chandra Station
(osmovaloper69420abc123easyasdoreme69)
</text>
</Box>
<Box>
<Button colorScheme="teal" variant="outline" alignContent="center" >
Sign
</Button>
</Box>
</Stack>
</CardBody>
</Card>
)}
{activeButton === 'staking' && (
<Card minWidth="600px" padding='40px' pb="40px">
<CardHeader>
<Heading size='lg'>Claim your staking rewards</Heading>
</CardHeader>
<CardBody>
<Stack divider={<StackDivider />} spacing='4'>
<Box>
<Heading size='xs' textTransform='uppercase'>
Claimmable Amount
</Heading>
<Stat>
<StatNumber>120</StatNumber>
<StatHelpText>OSMO</StatHelpText>
</Stat>
</Box>
<Box>
<Heading size='xs' textTransform='uppercase'>
Validator Address
</Heading>
<text>
Claiming from all your delegations.
</text>
</Box>
<Box>
<Button colorScheme="teal" variant="outline" alignContent="center" >
Sign
</Button>
</Box>
</Stack>
</CardBody>
</Card>
)}
{activeButton === 'unjail' && (
<Card minWidth="600px" padding='40px' pb="40px">
<CardHeader>
<Heading size='lg'>Unjail your Validator</Heading>
</CardHeader>
<CardBody>
<Stack divider={<StackDivider />} spacing='4'>
<Box>
<Heading size='xs' textTransform='uppercase'>
Jail Duration
</Heading>
<Stat>
<StatNumber>1,200</StatNumber>
<StatHelpText>Blocks</StatHelpText>
</Stat>
</Box>
<Box>
<Heading size='xs' textTransform='uppercase'>
Validator Address
</Heading>
<text>
Chandra Station
(osmovaloper69420abc123easyasdoreme69)
</text>
</Box>
<Box>
<Button colorScheme="teal" variant="outline" alignContent="center" >
Sign
</Button>
</Box>
</Stack>
</CardBody>
</Card>
)}
</Box>
</CardBody>
</Card>
</Flex>
</Container>
);
}
In the API call im storing the selected chain from a different component to query either akash or osmosis and it fills the variables i need from the query. The only issue is, when i switch between those two chains the amount doesnt change untill i refresh the page.
Heres the link to my repo
If you have any other tips about how im handling the routing etc please feel free to share :) I am n00b.
Ive tried using useeffect to store the variables and reload them
ive tried using window.localstorage
Update
I was looking at other similar problems and found that adding a visbility changer renders the changes when i change tabs. So the call is functioning properly its just the onstoragechange thats not working
I know i can set it to an interval but i think thats a bad solution, im starting to feel like my inexperince with the DOM router (or not even using it) could be the cause? I have a distribution-box.tsx file that exports the distribution div box and info and a distribution page that imports the function and renders it. Feel like thats a little unorthodox.
Code I added
const handleVisibilityChange = async () => {
if (!document.hidden) {
const chainName = window.localStorage.getItem(selectedChainKey) as ChainName;
const newcommission = await fetchCommission(chainName);
setCommission(newcommission);
}
};
```