Skip to content

Commit

Permalink
chore: get osmosis USDC balance
Browse files Browse the repository at this point in the history
  • Loading branch information
Ryz0nd committed Jul 9, 2024
1 parent b8c77c1 commit 4164952
Show file tree
Hide file tree
Showing 7 changed files with 107 additions and 47 deletions.
39 changes: 30 additions & 9 deletions src/hooks/useAccountBalance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,19 @@ import { getBalances, getStakingBalances } from '@/state/accountSelectors';
import { useAppSelector } from '@/state/appTypes';

import { MustBigNumber } from '@/lib/numbers';
import { getNobleChainId, getOsmosisChainId } from '@/lib/squid';

import { useAccounts } from './useAccounts';
import { useEndpointsConfig } from './useEndpointsConfig';
import { useEnvConfig } from './useEnvConfig';
import { useTokenConfigs } from './useTokenConfigs';

type UseAccountBalanceProps = {
// Token Items
addressOrDenom?: string;
decimals?: number;

// Chain Items
chainId?: string | number;
rpc?: string;

isCosmosChain?: boolean;
cosmosAddress?: string;
Expand All @@ -39,17 +39,16 @@ export const CHAIN_DEFAULT_TOKEN_ADDRESS = '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeee
export const useAccountBalance = ({
addressOrDenom,
chainId,
decimals = 0,
rpc,
isCosmosChain,
cosmosAddress,
}: UseAccountBalanceProps = {}) => {
const { evmAddress, dydxAddress } = useAccounts();

const balances = useAppSelector(getBalances, shallowEqual);
const { chainTokenDenom, usdcDenom } = useTokenConfigs();
const { chainTokenDenom, usdcDenom, usdcDecimals } = useTokenConfigs();
const evmChainId = Number(useEnvConfig('ethereumChainId'));
const stakingBalances = useAppSelector(getStakingBalances, shallowEqual);
const { nobleValidator, osmosisValidator } = useEndpointsConfig();

const evmQuery = useBalanceWagmi({
enabled: Boolean(!isCosmosChain && addressOrDenom?.startsWith('0x')),
Expand All @@ -61,18 +60,40 @@ export const useAccountBalance = ({
});

const cosmosQueryFn = useCallback(async () => {
if (dydxAddress && cosmosAddress && rpc && addressOrDenom) {
if (dydxAddress && cosmosAddress && addressOrDenom) {
const nobleChainId = getNobleChainId();
const osmosisChainId = getOsmosisChainId();
const rpc = (() => {
if (chainId === nobleChainId) {
return nobleValidator;
}
if (chainId === osmosisChainId) {
return osmosisValidator;
}
return undefined;
})();

if (!rpc) return undefined;

const client = await StargateClient.connect(rpc);
const balanceAsCoin = await client.getBalance(cosmosAddress, addressOrDenom);
await client.disconnect();

return formatUnits(BigInt(balanceAsCoin.amount), decimals);
return formatUnits(BigInt(balanceAsCoin.amount), usdcDecimals);
}
return undefined;
}, [addressOrDenom, cosmosAddress, decimals, dydxAddress, rpc]);
}, [
dydxAddress,
cosmosAddress,
addressOrDenom,
usdcDecimals,
chainId,
nobleValidator,
osmosisValidator,
]);

const cosmosQuery = useQuery({
enabled: Boolean(isCosmosChain && dydxAddress && cosmosAddress && rpc && addressOrDenom),
enabled: Boolean(isCosmosChain && dydxAddress && cosmosAddress && addressOrDenom),
queryKey: ['accountBalances', chainId, cosmosAddress, addressOrDenom],
queryFn: cosmosQueryFn,
refetchOnWindowFocus: false,
Expand Down
2 changes: 2 additions & 0 deletions src/hooks/useEndpointsConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ interface EndpointsConfig {
'0xsquid': string;
skip: string;
nobleValidator: string;
osmosisValidator: string;
faucet?: string;
stakingAPR?: string;
}
Expand All @@ -26,6 +27,7 @@ export const useEndpointsConfig = () => {
'0xsquid': endpointsConfig['0xsquid'],
skip: endpointsConfig.skip,
nobleValidator: endpointsConfig.nobleValidator,
osmosisValidator: endpointsConfig.osmosisValidator,
faucet: endpointsConfig.faucet,
stakingAPR: endpointsConfig.stakingAPR,
};
Expand Down
5 changes: 2 additions & 3 deletions src/hooks/useWalletConnection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ import { useLocalStorage } from '@/hooks/useLocalStorage';
import { getSelectedDydxChainId } from '@/state/appSelectors';
import { useAppSelector } from '@/state/appTypes';

import { getNobleChainId } from '@/lib/squid';
import { SUPPORTED_COSMOS_CHAINS } from '@/lib/graz';
import { log } from '@/lib/telemetry';
import { testFlags } from '@/lib/testFlags';
import { resolveWagmiConnector } from '@/lib/wagmi';
Expand Down Expand Up @@ -61,7 +61,6 @@ export const useWalletConnection = () => {
}, [evmAddressWagmi]);

// Cosmos wallet connection
const nobleChainId = getNobleChainId();
const [dydxAddress, saveDydxAddress] = useLocalStorage<DydxAddress | undefined>({
key: LocalStorageKey.DydxAddress,
defaultValue: undefined,
Expand Down Expand Up @@ -170,7 +169,7 @@ export const useWalletConnection = () => {

if (!isConnectedGraz) {
await connectGraz({
chainId: [selectedDydxChainId, nobleChainId],
chainId: SUPPORTED_COSMOS_CHAINS,
walletType: cosmosWalletType,
});
}
Expand Down
34 changes: 24 additions & 10 deletions src/lib/graz.ts
Original file line number Diff line number Diff line change
@@ -1,28 +1,42 @@
import { BECH32_PREFIX, NOBLE_BECH32_PREFIX } from '@dydxprotocol/v4-client-js';
import { type ConfigureGrazArgs } from 'graz';

import { isMainnet } from '@/constants/networks';
import { LocalStorageKey } from '@/constants/localStorage';
import { DEFAULT_APP_ENVIRONMENT, ENVIRONMENT_CONFIG_MAP } from '@/constants/networks';

import { getLocalStorage } from './localStorage';
import { validateAgainstAvailableEnvironments } from './network';
import { getNobleChainId, getOsmosisChainId } from './squid';

const selectedNetwork = getLocalStorage({
key: LocalStorageKey.SelectedNetwork,
defaultValue: DEFAULT_APP_ENVIRONMENT,
validateFn: validateAgainstAvailableEnvironments,
});
const dydxChainId = ENVIRONMENT_CONFIG_MAP[selectedNetwork].dydxChainId;
const osmosisChainId = getOsmosisChainId();
const nobleChainId = getNobleChainId();

export const SUPPORTED_COSMOS_CHAINS = [dydxChainId, osmosisChainId, nobleChainId];

export const config: ConfigureGrazArgs = {
walletDefaultOptions: {
// sign: {
// preferNoSetFee: true,
// preferNoSetMemo: true,
// },
},
// walletDefaultOptions: {
// sign: {
// preferNoSetFee: true,
// preferNoSetMemo: true,
// },
// },
chains: [
// dYdX
{
chainId: isMainnet ? 'dydx-mainnet-1' : 'dydx-testnet-4',
chainId: dydxChainId,
bech32Config: {
bech32PrefixAccAddr: BECH32_PREFIX,
},
},
// Noble
{ chainId: getNobleChainId(), bech32Config: { bech32PrefixAccAddr: NOBLE_BECH32_PREFIX } },
{ chainId: nobleChainId, bech32Config: { bech32PrefixAccAddr: NOBLE_BECH32_PREFIX } },
// Osmosis
{ chainId: getOsmosisChainId(), bech32Config: { bech32PrefixAccAddr: 'osmo' } },
{ chainId: osmosisChainId, bech32Config: { bech32PrefixAccAddr: 'osmo' } },
] as ConfigureGrazArgs['chains'],
};
66 changes: 47 additions & 19 deletions src/views/forms/AccountManagementForms/DepositForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { useCallback, useEffect, useMemo, useState, type FormEvent } from 'react

import { GasPrice } from '@cosmjs/stargate';
import { NobleClient } from '@dydxprotocol/v4-client-js';
import { useAccount as useAccountGraz } from 'graz';
import Long from 'long';
import { type NumberFormatValues } from 'react-number-format';
import { shallowEqual, useDispatch } from 'react-redux';
Expand Down Expand Up @@ -61,11 +62,13 @@ import { getTransferInputs } from '@/state/inputsSelectors';

import abacusStateManager from '@/lib/abacus';
import { track } from '@/lib/analytics';
import { SUPPORTED_COSMOS_CHAINS } from '@/lib/graz';
import { MustBigNumber } from '@/lib/numbers';
import {
NATIVE_TOKEN_ADDRESS,
fetchSkipRoute,
getNobleChainId,
getOsmosisChainId,
isTransferOperation,
} from '@/lib/squid';
import { log } from '@/lib/telemetry';
Expand Down Expand Up @@ -118,6 +121,7 @@ export const DepositForm = ({ onDeposit, onError }: DepositFormProps) => {
// eslint-disable-next-line radix
const chainId = chainIdStr && !isKeplrWallet ? parseInt(chainIdStr) : chainIdStr ?? undefined;
const nobleChainId = getNobleChainId();
const osmosisChainId = getOsmosisChainId();

// User inputs
const sourceToken = useMemo(
Expand All @@ -136,14 +140,27 @@ export const DepositForm = ({ onDeposit, onError }: DepositFormProps) => {

const { usdcLabel, usdcDecimals, usdcGasDenom, usdcDenom } = useTokenConfigs();
const { nobleValidator, skip } = useEndpointsConfig();

const { data: accounts } = useAccountGraz({
chainId: SUPPORTED_COSMOS_CHAINS,
multiChain: true,
});
const cosmosAddress = (() => {
if (chainId === osmosisChainId) {
return accounts?.[osmosisChainId]?.bech32Address;
}
if (chainId === nobleChainId) {
return accounts?.[nobleChainId]?.bech32Address;
}
return undefined;
})();

// Async Data
const { balance } = useAccountBalance({
addressOrDenom: sourceToken?.address || CHAIN_DEFAULT_TOKEN_ADDRESS,
chainId,
isCosmosChain: isKeplrWallet,
cosmosAddress: isKeplrWallet ? nobleAddress : undefined,
rpc: isKeplrWallet ? nobleValidator : undefined,
decimals: isKeplrWallet ? usdcDecimals : undefined,
cosmosAddress,
});
// BN
const debouncedAmountBN = MustBigNumber(debouncedAmount);
Expand Down Expand Up @@ -204,23 +221,34 @@ export const DepositForm = ({ onDeposit, onError }: DepositFormProps) => {
}
}, [nobleAddress, nobleChainId, walletType]);

const onSelectNetwork = useCallback((name: string, type: 'chain' | 'exchange') => {
if (name) {
abacusStateManager.clearTransferInputValues();
setFromAmount('');
if (type === 'chain') {
abacusStateManager.setTransferValue({
field: TransferInputField.chain,
value: name,
});
} else {
abacusStateManager.setTransferValue({
field: TransferInputField.exchange,
value: name,
});
const onSelectNetwork = useCallback(
(name: string, type: 'chain' | 'exchange') => {
if (name) {
abacusStateManager.clearTransferInputValues();
setFromAmount('');
if (type === 'chain') {
abacusStateManager.setTransferValue({
field: TransferInputField.chain,
value: name,
});
if (name === osmosisChainId) {
const usdcIBCDenom =
'ibc/DE6792CF9E521F6AD6E9A4BDF6225C9571A3B74ACC0A529F92BC5122A39D2E58';
abacusStateManager.setTransferValue({
field: TransferInputField.token,
value: usdcIBCDenom,
});
}
} else {
abacusStateManager.setTransferValue({
field: TransferInputField.exchange,
value: name,
});
}
}
}
}, []);
},
[osmosisChainId]
);

const onSelectToken = useCallback((selectedToken: TransferInputTokenResource) => {
if (selectedToken) {
Expand Down
7 changes: 2 additions & 5 deletions src/views/forms/AccountManagementForms/SourceSelectMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ import { SearchSelectMenu } from '@/components/SearchSelectMenu';
import { useAppSelector } from '@/state/appTypes';
import { getTransferInputs } from '@/state/inputsSelectors';

import { SUPPORTED_COSMOS_CHAINS } from '@/lib/graz';
import { isTruthy } from '@/lib/isTruthy';
import { getNobleChainId, getOsmosisChainId } from '@/lib/squid';

import cctpTokens from '../../../../public/configs/cctp.json';

Expand Down Expand Up @@ -76,9 +76,6 @@ export const SourceSelectMenu = ({
// withdrawals SourceSelectMenu is half width size so we must throw the decorator text
// in the description prop (renders below the item label) instead of in the slotAfter
const lowestFeesDecoratorProp = type === TransferType.deposit ? 'slotAfter' : 'description';
const osmosisChainId = getOsmosisChainId();
const nobleChainId = getNobleChainId();
const supportedCosmosChains = [osmosisChainId, nobleChainId];

const chainItems = Object.values(chains)
.map((chain) => ({
Expand All @@ -105,7 +102,7 @@ export const SourceSelectMenu = ({
}))
.filter((chain) => {
if (!isNotKeplrWallet) {
return supportedCosmosChains.includes(chain.value);
return SUPPORTED_COSMOS_CHAINS.includes(chain.value);
}
// if deposit and CCTPDepositOnly enabled, only return cctp tokens
if (type === TransferType.deposit && CCTPDepositOnly) {
Expand Down
1 change: 0 additions & 1 deletion src/views/forms/AccountManagementForms/TokenSelectMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ export const TokenSelectMenu = ({ selectedToken, onSelectToken, isExchange }: El
value: token.type,
label: token.stringKey,
onSelect: () => {
console.log('d', resources?.tokenResources);
const newSelectedToken = resources?.tokenResources?.get(token.type);
if (newSelectedToken) {
onSelectToken(newSelectedToken);
Expand Down

0 comments on commit 4164952

Please sign in to comment.