Compare commits

..
Author SHA1 Message Date
Bill He 514a2d3ab3 use decimals: 2023-11-06 17:35:57 -08:00
Bill He c58d94e477 Fix decimal overflow bug 2023-11-06 17:26:27 -08:00
5 changed files with 102 additions and 66 deletions
+2 -4
View File
@@ -7,11 +7,9 @@ import { AlertType } from '@/constants/alerts';
import { AbacusOrderStatus, ORDER_SIDES } from '@/constants/abacus'; import { AbacusOrderStatus, ORDER_SIDES } from '@/constants/abacus';
import { DialogTypes } from '@/constants/dialogs'; import { DialogTypes } from '@/constants/dialogs';
import { STRING_KEYS, StringKey } from '@/constants/localization'; import { STRING_KEYS, StringKey } from '@/constants/localization';
import { ENVIRONMENT_CONFIG_MAP } from '@/constants/networks';
import { type NotificationTypeConfig, NotificationType } from '@/constants/notifications'; import { type NotificationTypeConfig, NotificationType } from '@/constants/notifications';
import { ORDER_SIDE_STRINGS } from '@/constants/trade'; import { ORDER_SIDE_STRINGS } from '@/constants/trade';
import { useSelectedNetwork } from '@/hooks';
import { useLocalNotifications } from '@/hooks/useLocalNotifications'; import { useLocalNotifications } from '@/hooks/useLocalNotifications';
import { Icon, IconName } from '@/components/Icon'; import { Icon, IconName } from '@/components/Icon';
@@ -25,6 +23,7 @@ import { OrderStatusIcon } from '@/views/OrderStatusIcon';
import { useStringGetter } from './useStringGetter'; import { useStringGetter } from './useStringGetter';
import { TransferStatusSteps } from '@/views/TransferStatusSteps'; import { TransferStatusSteps } from '@/views/TransferStatusSteps';
import { TESTNET_CHAIN_ID } from '@dydxprotocol/v4-client-js';
export const notificationTypes = [ export const notificationTypes = [
{ {
@@ -125,7 +124,6 @@ export const notificationTypes = [
useTrigger: ({ trigger }) => { useTrigger: ({ trigger }) => {
const stringGetter = useStringGetter(); const stringGetter = useStringGetter();
const { transferNotifications } = useLocalNotifications(); const { transferNotifications } = useLocalNotifications();
const { selectedNetwork } = useSelectedNetwork();
const getTitleStringKey = useCallback((type: 'deposit' | 'withdrawal', finished: boolean) => { const getTitleStringKey = useCallback((type: 'deposit' | 'withdrawal', finished: boolean) => {
if (type === 'deposit' && !finished) return STRING_KEYS.DEPOSIT_IN_PROGRESS; if (type === 'deposit' && !finished) return STRING_KEYS.DEPOSIT_IN_PROGRESS;
@@ -138,7 +136,7 @@ export const notificationTypes = [
for (const transfer of transferNotifications) { for (const transfer of transferNotifications) {
const { fromChainId, status, txHash, toAmount } = transfer; const { fromChainId, status, txHash, toAmount } = transfer;
const finished = Boolean(status) && status?.squidTransactionStatus !== 'ongoing'; const finished = Boolean(status) && status?.squidTransactionStatus !== 'ongoing';
const type = fromChainId === ENVIRONMENT_CONFIG_MAP[selectedNetwork].dydxChainId ? 'withdrawal' : 'deposit'; const type = fromChainId === TESTNET_CHAIN_ID ? 'withdrawal' : 'deposit';
// @ts-ignore status.errors is not in the type definition but can be returned // @ts-ignore status.errors is not in the type definition but can be returned
const error = status?.errors?.length ? status?.errors[0] : status?.error; const error = status?.errors?.length ? status?.errors[0] : status?.error;
+91 -54
View File
@@ -48,7 +48,7 @@ export const useSubaccount = () => useContext(SubaccountContext);
export const useSubaccountContext = ({ localDydxWallet }: { localDydxWallet?: LocalWallet }) => { export const useSubaccountContext = ({ localDydxWallet }: { localDydxWallet?: LocalWallet }) => {
const dispatch = useDispatch(); const dispatch = useDispatch();
const { usdcDenom } = useTokenConfigs(); const { usdcDenom, usdcDecimals } = useTokenConfigs();
const { compositeClient, faucetClient } = useDydxClient(); const { compositeClient, faucetClient } = useDydxClient();
const { getFaucetFunds } = useMemo( const { getFaucetFunds } = useMemo(
@@ -79,16 +79,34 @@ export const useSubaccountContext = ({ localDydxWallet }: { localDydxWallet?: Lo
subaccountClient: SubaccountClient; subaccountClient: SubaccountClient;
assetId?: number; assetId?: number;
amount: number; amount: number;
}) => await compositeClient?.depositToSubaccount(subaccountClient, amount.toString()), }) => {
try {
return await compositeClient?.depositToSubaccount(
subaccountClient,
amount.toFixed(usdcDecimals)
);
} catch (error) {
log('useSubaccount/depositToSubaccount', error);
throw error;
}
},
withdrawFromSubaccount: async ({ withdrawFromSubaccount: async ({
subaccountClient, subaccountClient,
amount, amount,
}: { }: {
subaccountClient: SubaccountClient; subaccountClient: SubaccountClient;
amount: number; amount: number;
}) => await compositeClient?.withdrawFromSubaccount(subaccountClient, amount.toString()), }) => {
try {
return await compositeClient?.withdrawFromSubaccount(
subaccountClient,
amount.toFixed(usdcDecimals)
);
} catch (error) {
log('useSubaccount/withdrawFromSubaccount', error);
throw error;
}
},
transferFromSubaccountToAddress: async ({ transferFromSubaccountToAddress: async ({
subaccountClient, subaccountClient,
assetId = 0, assetId = 0,
@@ -99,27 +117,33 @@ export const useSubaccountContext = ({ localDydxWallet }: { localDydxWallet?: Lo
assetId?: number; assetId?: number;
amount: number; amount: number;
recipient: string; recipient: string;
}) => }) => {
await compositeClient?.validatorClient.post.send( try {
subaccountClient?.wallet, return await compositeClient?.validatorClient.post.send(
() => subaccountClient?.wallet,
new Promise((resolve) => { () =>
const msg = new Promise((resolve) => {
compositeClient?.validatorClient.post.composer.composeMsgWithdrawFromSubaccount( const msg =
subaccountClient.address, compositeClient?.validatorClient.post.composer.composeMsgWithdrawFromSubaccount(
subaccountClient.subaccountNumber, subaccountClient.address,
assetId, subaccountClient.subaccountNumber,
Long.fromNumber(amount * QUANTUM_MULTIPLIER), assetId,
recipient Long.fromNumber(amount * QUANTUM_MULTIPLIER),
); recipient
);
resolve([msg]); resolve([msg]);
}), }),
false, false,
undefined, undefined,
undefined, undefined,
Method.BroadcastTxCommit Method.BroadcastTxCommit
), );
} catch (error) {
log('useSubaccount/transferFromSubaccountToAddress', error);
throw error;
}
},
transferNativeToken: async ({ transferNativeToken: async ({
subaccountClient, subaccountClient,
@@ -129,24 +153,30 @@ export const useSubaccountContext = ({ localDydxWallet }: { localDydxWallet?: Lo
subaccountClient: SubaccountClient; subaccountClient: SubaccountClient;
amount: number; amount: number;
recipient: string; recipient: string;
}) => }) => {
await compositeClient?.validatorClient.post.send( try {
subaccountClient.wallet, return await compositeClient?.validatorClient.post.send(
() => subaccountClient.wallet,
new Promise((resolve) => { () =>
const msg = compositeClient?.sendTokenMessage( new Promise((resolve) => {
subaccountClient.wallet, const msg = compositeClient?.sendTokenMessage(
amount.toString(), subaccountClient.wallet,
recipient, amount.toString(),
); recipient
);
resolve([msg]); resolve([msg]);
}), }),
false, false,
compositeClient?.validatorClient?.post.defaultDydxGasPrice, compositeClient?.validatorClient?.post.defaultDydxGasPrice,
undefined, undefined,
Method.BroadcastTxCommit Method.BroadcastTxCommit
), );
} catch (error) {
log('useSubaccount/transferNativeToken', error);
throw error;
}
},
sendSquidWithdrawFromSubaccount: async ({ sendSquidWithdrawFromSubaccount: async ({
subaccountClient, subaccountClient,
@@ -158,20 +188,27 @@ export const useSubaccountContext = ({ localDydxWallet }: { localDydxWallet?: Lo
payload: string; payload: string;
}) => { }) => {
if (!compositeClient) throw new Error('client not initialized'); if (!compositeClient) throw new Error('client not initialized');
try {
const transaction = JSON.parse(payload);
const transaction = JSON.parse(payload); const msg = compositeClient.withdrawFromSubaccountMessage(
subaccountClient,
amount.toFixed(usdcDecimals)
);
const ibcMsg: EncodeObject = {
typeUrl: transaction.msgTypeUrl,
value: transaction.msg,
};
const msg = compositeClient.withdrawFromSubaccountMessage(subaccountClient, amount.toString()); return await compositeClient.send(
const ibcMsg: EncodeObject = { subaccountClient.wallet,
typeUrl: transaction.msgTypeUrl, () => Promise.resolve([msg, ibcMsg]),
value: transaction.msg, false
}; );
} catch (error) {
return await compositeClient.send( log('useSubaccount/sendSquidWithdrawFromSubaccount', error);
subaccountClient.wallet, throw error;
() => Promise.resolve([msg, ibcMsg]), }
false
);
}, },
}), }),
[compositeClient] [compositeClient]
+4
View File
@@ -19,8 +19,10 @@ export const useTokenConfigs = (): {
}, },
}; };
usdcDenom: string; usdcDenom: string;
usdcDecimals: number;
usdcLabel: string; usdcLabel: string;
chainTokenDenom: string; chainTokenDenom: string;
chainTokenDecimals: number;
chainTokenLabel: string; chainTokenLabel: string;
} => { } => {
const { selectedNetwork } = useSelectedNetwork(); const { selectedNetwork } = useSelectedNetwork();
@@ -29,8 +31,10 @@ export const useTokenConfigs = (): {
return { return {
tokensConfigs, tokensConfigs,
usdcDenom: tokensConfigs[DydxChainAsset.USDC].denom, usdcDenom: tokensConfigs[DydxChainAsset.USDC].denom,
usdcDecimals: tokensConfigs[DydxChainAsset.USDC].decimals,
usdcLabel: tokensConfigs[DydxChainAsset.USDC].name, usdcLabel: tokensConfigs[DydxChainAsset.USDC].name,
chainTokenDenom: tokensConfigs[DydxChainAsset.CHAINTOKEN].denom, chainTokenDenom: tokensConfigs[DydxChainAsset.CHAINTOKEN].denom,
chainTokenDecimals: tokensConfigs[DydxChainAsset.CHAINTOKEN].decimals,
chainTokenLabel: tokensConfigs[DydxChainAsset.CHAINTOKEN].name, chainTokenLabel: tokensConfigs[DydxChainAsset.CHAINTOKEN].name,
}; };
}; };
@@ -2,6 +2,7 @@ import { type FormEvent, useCallback, useEffect, useMemo, useState } from 'react
import styled, { type AnyStyledComponent } from 'styled-components'; import styled, { type AnyStyledComponent } from 'styled-components';
import { type NumberFormatValues } from 'react-number-format'; import { type NumberFormatValues } from 'react-number-format';
import { shallowEqual, useSelector } from 'react-redux'; import { shallowEqual, useSelector } from 'react-redux';
import { TESTNET_CHAIN_ID } from '@dydxprotocol/v4-client-js';
import { parseUnits } from 'viem' import { parseUnits } from 'viem'
import erc20 from '@/abi/erc20.json'; import erc20 from '@/abi/erc20.json';
@@ -9,11 +10,10 @@ import { TransferInputField, TransferInputTokenResource, TransferType } from '@/
import { AlertType } from '@/constants/alerts'; import { AlertType } from '@/constants/alerts';
import { ButtonSize } from '@/constants/buttons'; import { ButtonSize } from '@/constants/buttons';
import { STRING_KEYS } from '@/constants/localization'; import { STRING_KEYS } from '@/constants/localization';
import { ENVIRONMENT_CONFIG_MAP } from '@/constants/networks';
import { NumberSign } from '@/constants/numbers'; import { NumberSign } from '@/constants/numbers';
import type { EvmAddress } from '@/constants/wallets'; import type { EvmAddress } from '@/constants/wallets';
import { useAccounts, useDebounce, useStringGetter, useSelectedNetwork } from '@/hooks'; import { useAccounts, useDebounce, useStringGetter } from '@/hooks';
import { useAccountBalance, CHAIN_DEFAULT_TOKEN_ADDRESS } from '@/hooks/useAccountBalance'; import { useAccountBalance, CHAIN_DEFAULT_TOKEN_ADDRESS } from '@/hooks/useAccountBalance';
import { useLocalNotifications } from '@/hooks/useLocalNotifications'; import { useLocalNotifications } from '@/hooks/useLocalNotifications';
import { NATIVE_TOKEN_ADDRESS, useSquid } from '@/hooks/useSquid'; import { NATIVE_TOKEN_ADDRESS, useSquid } from '@/hooks/useSquid';
@@ -54,7 +54,6 @@ export const DepositForm = ({ onDeposit, onError }: DepositFormProps) => {
const stringGetter = useStringGetter(); const stringGetter = useStringGetter();
const [error, setError] = useState<Error | null>(null); const [error, setError] = useState<Error | null>(null);
const [isLoading, setIsLoading] = useState(false); const [isLoading, setIsLoading] = useState(false);
const { selectedNetwork } = useSelectedNetwork();
const { evmAddress, signerWagmi } = useAccounts(); const { evmAddress, signerWagmi } = useAccounts();
const { publicClientWagmi } = useWalletConnection(); const { publicClientWagmi } = useWalletConnection();
@@ -240,7 +239,7 @@ export const DepositForm = ({ onDeposit, onError }: DepositFormProps) => {
if (txHash) { if (txHash) {
addTransferNotification({ addTransferNotification({
txHash: txHash, txHash: txHash,
toChainId: ENVIRONMENT_CONFIG_MAP[selectedNetwork].dydxChainId, toChainId: TESTNET_CHAIN_ID,
fromChainId: chainIdStr || undefined, fromChainId: chainIdStr || undefined,
toAmount: summary?.usdcSize || undefined, toAmount: summary?.usdcSize || undefined,
triggeredAt: Date.now(), triggeredAt: Date.now(),
@@ -3,13 +3,13 @@ import type { ChangeEvent, FormEvent } from 'react';
import styled, { type AnyStyledComponent } from 'styled-components'; import styled, { type AnyStyledComponent } from 'styled-components';
import type { NumberFormatValues } from 'react-number-format'; import type { NumberFormatValues } from 'react-number-format';
import { shallowEqual, useSelector } from 'react-redux'; import { shallowEqual, useSelector } from 'react-redux';
import { TESTNET_CHAIN_ID } from '@dydxprotocol/v4-client-js';
import { isAddress } from 'viem'; import { isAddress } from 'viem';
import { TransferInputField, TransferInputTokenResource, TransferType } from '@/constants/abacus'; import { TransferInputField, TransferInputTokenResource, TransferType } from '@/constants/abacus';
import { AlertType } from '@/constants/alerts'; import { AlertType } from '@/constants/alerts';
import { ButtonSize } from '@/constants/buttons'; import { ButtonSize } from '@/constants/buttons';
import { STRING_KEYS } from '@/constants/localization'; import { STRING_KEYS } from '@/constants/localization';
import { ENVIRONMENT_CONFIG_MAP } from '@/constants/networks';
import { NumberSign } from '@/constants/numbers'; import { NumberSign } from '@/constants/numbers';
import { import {
@@ -17,7 +17,6 @@ import {
useDebounce, useDebounce,
useDydxClient, useDydxClient,
useRestrictions, useRestrictions,
useSelectedNetwork,
useStringGetter, useStringGetter,
useSubaccount, useSubaccount,
} from '@/hooks'; } from '@/hooks';
@@ -53,7 +52,6 @@ export const WithdrawForm = () => {
const stringGetter = useStringGetter(); const stringGetter = useStringGetter();
const [error, setError] = useState<string>(); const [error, setError] = useState<string>();
const [isLoading, setIsLoading] = useState(false); const [isLoading, setIsLoading] = useState(false);
const { selectedNetwork } = useSelectedNetwork();
const { sendSquidWithdraw } = useSubaccount(); const { sendSquidWithdraw } = useSubaccount();
const { freeCollateral } = useSelector(getSubaccount, shallowEqual) || {}; const { freeCollateral } = useSelector(getSubaccount, shallowEqual) || {};
@@ -166,7 +164,7 @@ export const WithdrawForm = () => {
const hash = `0x${Buffer.from(txHash.hash).toString('hex')}`; const hash = `0x${Buffer.from(txHash.hash).toString('hex')}`;
addTransferNotification({ addTransferNotification({
txHash: hash, txHash: hash,
fromChainId: ENVIRONMENT_CONFIG_MAP[selectedNetwork].dydxChainId, fromChainId: TESTNET_CHAIN_ID,
toChainId: chainIdStr || undefined, toChainId: chainIdStr || undefined,
toAmount: debouncedAmountBN.toNumber(), toAmount: debouncedAmountBN.toNumber(),
triggeredAt: Date.now(), triggeredAt: Date.now(),