Compare commits
5
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
45e1b874fd | ||
|
|
8d5bf1a721 | ||
|
|
7f3d57b46a | ||
|
|
c292c84c2c | ||
|
|
2d37ff676b |
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"apps": {
|
"apps": {
|
||||||
"iOS": {
|
"ios": {
|
||||||
"scheme": "dydxv4"
|
"scheme": "dydxv4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -893,6 +893,7 @@
|
|||||||
"privacy": "https://dydx.exchange/privacy",
|
"privacy": "https://dydx.exchange/privacy",
|
||||||
"statusPage": "https://status.v4testnet.dydx.exchange/",
|
"statusPage": "https://status.v4testnet.dydx.exchange/",
|
||||||
"mintscan": "https://testnet.mintscan.io/dydx-testnet/txs/{tx_hash}",
|
"mintscan": "https://testnet.mintscan.io/dydx-testnet/txs/{tx_hash}",
|
||||||
|
"mintscanBase": "https://testnet.mintscan.io/dydx-testnet",
|
||||||
"documentation": "https://docs.dydx.exchange/",
|
"documentation": "https://docs.dydx.exchange/",
|
||||||
"community": "https://discord.com/invite/dydx",
|
"community": "https://discord.com/invite/dydx",
|
||||||
"feedback": "https://docs.google.com/forms/d/e/1FAIpQLSezLsWCKvAYDEb7L-2O4wOON1T56xxro9A2Azvl6IxXHP_15Q/viewform",
|
"feedback": "https://docs.google.com/forms/d/e/1FAIpQLSezLsWCKvAYDEb7L-2O4wOON1T56xxro9A2Azvl6IxXHP_15Q/viewform",
|
||||||
@@ -1033,7 +1034,7 @@
|
|||||||
"tos": "[HTTP link to TOS]",
|
"tos": "[HTTP link to TOS]",
|
||||||
"privacy": "[HTTP link to Privacy Policy]",
|
"privacy": "[HTTP link to Privacy Policy]",
|
||||||
"mintscan": "[HTTP link to Mintscan, with {tx_hash} placeholder]",
|
"mintscan": "[HTTP link to Mintscan, with {tx_hash} placeholder]",
|
||||||
"mintscanBase": "[HTTP link to TOS mintsacn base url]",
|
"mintscanBase": "[HTTP link to TOS mintscan base url]",
|
||||||
"feedback": "[HTTP link to feedback form, can be null]",
|
"feedback": "[HTTP link to feedback form, can be null]",
|
||||||
"blogs": "[HTTP link to blogs, can be null]",
|
"blogs": "[HTTP link to blogs, can be null]",
|
||||||
"foundation": "[HTTP link to foundation, can be null]",
|
"foundation": "[HTTP link to foundation, can be null]",
|
||||||
|
|||||||
@@ -1,12 +1,18 @@
|
|||||||
import environments from '../../public/configs/env.json';
|
import environments from '../../public/configs/env.json';
|
||||||
|
|
||||||
// TODO: Update for Mainnet deployment
|
const CURRENT_MODE = ({
|
||||||
export const AVAILABLE_ENVIRONMENTS =
|
production: 'MAINNET',
|
||||||
import.meta.env.MODE === 'production'
|
testnet: 'TESTNET',
|
||||||
? environments.deployments.TESTNET
|
staging: 'DEV',
|
||||||
: environments.deployments.DEV;
|
development: 'DEV',
|
||||||
|
}[import.meta.env.MODE] ?? 'MAINNET') as 'MAINNET' | 'TESTNET' | 'DEV';
|
||||||
|
|
||||||
export const CURRENT_ABACUS_DEPLOYMENT = import.meta.env.MODE === 'production' ? 'TESTNET' : 'DEV';
|
export const isMainnet = CURRENT_MODE === 'MAINNET';
|
||||||
|
export const isTestnet = CURRENT_MODE === 'TESTNET';
|
||||||
|
export const isDev = CURRENT_MODE === 'DEV';
|
||||||
|
|
||||||
|
export const AVAILABLE_ENVIRONMENTS = environments.deployments[CURRENT_MODE];
|
||||||
|
export const CURRENT_ABACUS_DEPLOYMENT = CURRENT_MODE;
|
||||||
export const ENVIRONMENT_CONFIG_MAP = environments.environments;
|
export const ENVIRONMENT_CONFIG_MAP = environments.environments;
|
||||||
export type DydxNetwork = keyof typeof ENVIRONMENT_CONFIG_MAP;
|
export type DydxNetwork = keyof typeof ENVIRONMENT_CONFIG_MAP;
|
||||||
export const DEFAULT_APP_ENVIRONMENT = AVAILABLE_ENVIRONMENTS.default as DydxNetwork;
|
export const DEFAULT_APP_ENVIRONMENT = AVAILABLE_ENVIRONMENTS.default as DydxNetwork;
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { isDev } from '@/constants/networks';
|
||||||
import { WalletType } from '@/constants/wallets';
|
import { WalletType } from '@/constants/wallets';
|
||||||
|
|
||||||
import { isTruthy } from '@/lib/isTruthy';
|
import { isTruthy } from '@/lib/isTruthy';
|
||||||
@@ -6,7 +7,7 @@ export const useDisplayedWallets = () => {
|
|||||||
return [
|
return [
|
||||||
WalletType.MetaMask,
|
WalletType.MetaMask,
|
||||||
|
|
||||||
import.meta.env.MODE !== 'production' && WalletType.Keplr,
|
isDev && WalletType.Keplr,
|
||||||
|
|
||||||
WalletType.WalletConnect2,
|
WalletType.WalletConnect2,
|
||||||
|
|
||||||
|
|||||||
@@ -7,9 +7,11 @@ 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';
|
||||||
@@ -23,7 +25,6 @@ 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 = [
|
||||||
{
|
{
|
||||||
@@ -124,6 +125,7 @@ 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;
|
||||||
@@ -136,7 +138,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 === TESTNET_CHAIN_ID ? 'withdrawal' : 'deposit';
|
const type = fromChainId === ENVIRONMENT_CONFIG_MAP[selectedNetwork].dydxChainId ? '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
-60
@@ -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]
|
||||||
@@ -313,11 +350,6 @@ export const useSubaccountContext = ({ localDydxWallet }: { localDydxWallet?: Lo
|
|||||||
placeOrderParams = abacusStateManager.placeOrder(callback);
|
placeOrderParams = abacusStateManager.placeOrder(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
track(AnalyticsEvent.TradePlaceOrder, {
|
|
||||||
...placeOrderParams,
|
|
||||||
isClosePosition,
|
|
||||||
} as HumanReadablePlaceOrderPayload & { isClosePosition: boolean });
|
|
||||||
|
|
||||||
return placeOrderParams;
|
return placeOrderParams;
|
||||||
},
|
},
|
||||||
[subaccountClient]
|
[subaccountClient]
|
||||||
@@ -346,7 +378,6 @@ export const useSubaccountContext = ({ localDydxWallet }: { localDydxWallet?: Lo
|
|||||||
}) => {
|
}) => {
|
||||||
const callback = (success: boolean, parsingError?: Nullable<ParsingError>) => {
|
const callback = (success: boolean, parsingError?: Nullable<ParsingError>) => {
|
||||||
if (success) {
|
if (success) {
|
||||||
track(AnalyticsEvent.TradeCancelOrder);
|
|
||||||
onSuccess?.();
|
onSuccess?.();
|
||||||
} else {
|
} else {
|
||||||
onError?.({ errorStringKey: parsingError?.stringKey });
|
onError?.({ errorStringKey: parsingError?.stringKey });
|
||||||
|
|||||||
@@ -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,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import styled, { type AnyStyledComponent, css } from 'styled-components';
|
|||||||
import { AbacusApiStatus } from '@/constants/abacus';
|
import { AbacusApiStatus } from '@/constants/abacus';
|
||||||
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 { ENVIRONMENT_CONFIG_MAP, isDev } from '@/constants/networks';
|
||||||
|
|
||||||
import { useApiState, useSelectedNetwork, useStringGetter } from '@/hooks';
|
import { useApiState, useSelectedNetwork, useStringGetter } from '@/hooks';
|
||||||
import { ChatIcon, LinkOutIcon } from '@/icons';
|
import { ChatIcon, LinkOutIcon } from '@/icons';
|
||||||
@@ -75,7 +75,7 @@ export const FooterDesktop = () => {
|
|||||||
)}
|
)}
|
||||||
</Styled.Row>
|
</Styled.Row>
|
||||||
|
|
||||||
{import.meta.env.MODE !== 'production' && (
|
{isDev && (
|
||||||
<Styled.Details
|
<Styled.Details
|
||||||
withSeparators
|
withSeparators
|
||||||
items={[
|
items={[
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ import {
|
|||||||
|
|
||||||
import { DialogTypes } from '@/constants/dialogs';
|
import { DialogTypes } from '@/constants/dialogs';
|
||||||
import { UNCOMMITTED_ORDER_TIMEOUT_MS } from '@/constants/trade';
|
import { UNCOMMITTED_ORDER_TIMEOUT_MS } from '@/constants/trade';
|
||||||
import { QUANTUM_MULTIPLIER } from '@/constants/numbers';
|
import { ENVIRONMENT_CONFIG_MAP, DydxNetwork, isTestnet } from '@/constants/networks';
|
||||||
|
|
||||||
import { RootStore } from '@/state/_store';
|
import { RootStore } from '@/state/_store';
|
||||||
import { addUncommittedOrderClientId, removeUncommittedOrderClientId } from '@/state/account';
|
import { addUncommittedOrderClientId, removeUncommittedOrderClientId } from '@/state/account';
|
||||||
@@ -198,8 +198,13 @@ class DydxChainTransactions implements AbacusDYDXChainTransactionsProtocol {
|
|||||||
const parsedTx = this.parseToPrimitives(tx);
|
const parsedTx = this.parseToPrimitives(tx);
|
||||||
const hash = parsedTx?.hash;
|
const hash = parsedTx?.hash;
|
||||||
|
|
||||||
if (import.meta.env.MODE === 'production') {
|
if (isTestnet) {
|
||||||
console.log(`https://testnet.mintscan.io/dydx-testnet/txs/${hash}`);
|
console.log(
|
||||||
|
`${
|
||||||
|
ENVIRONMENT_CONFIG_MAP[this.compositeClient.network.getString() as DydxNetwork]?.links
|
||||||
|
?.mintscanBase
|
||||||
|
}/txs/${hash}`
|
||||||
|
);
|
||||||
} else console.log(`txHash: ${hash}`);
|
} else console.log(`txHash: ${hash}`);
|
||||||
|
|
||||||
return JSON.stringify(parsedTx);
|
return JSON.stringify(parsedTx);
|
||||||
@@ -229,7 +234,7 @@ class DydxChainTransactions implements AbacusDYDXChainTransactionsProtocol {
|
|||||||
orderFlags,
|
orderFlags,
|
||||||
clobPairId,
|
clobPairId,
|
||||||
goodTilBlock || undefined,
|
goodTilBlock || undefined,
|
||||||
goodTilBlockTime || undefined,
|
goodTilBlockTime || undefined
|
||||||
);
|
);
|
||||||
|
|
||||||
const parsedTx = this.parseToPrimitives(tx);
|
const parsedTx = this.parseToPrimitives(tx);
|
||||||
@@ -295,15 +300,11 @@ class DydxChainTransactions implements AbacusDYDXChainTransactionsProtocol {
|
|||||||
if (!this.localWallet) {
|
if (!this.localWallet) {
|
||||||
throw new Error('Missing compositeClient or localWallet');
|
throw new Error('Missing compositeClient or localWallet');
|
||||||
}
|
}
|
||||||
const msg = compositeClient?.sendTokenMessage(
|
const msg = compositeClient?.sendTokenMessage(this.localWallet, amount, recipient);
|
||||||
this.localWallet,
|
|
||||||
amount,
|
|
||||||
recipient,
|
|
||||||
);
|
|
||||||
|
|
||||||
resolve([msg]);
|
resolve([msg]);
|
||||||
}),
|
}),
|
||||||
this.compositeClient?.validatorClient?.post.defaultDydxGasPrice,
|
this.compositeClient?.validatorClient?.post.defaultDydxGasPrice
|
||||||
);
|
);
|
||||||
|
|
||||||
const parsedTx = this.parseToPrimitives(tx);
|
const parsedTx = this.parseToPrimitives(tx);
|
||||||
|
|||||||
@@ -1,10 +1,5 @@
|
|||||||
import type { AbacusFileSystemProtocol, FileLocation, Nullable } from '@/constants/abacus';
|
import type { AbacusFileSystemProtocol, FileLocation, Nullable } from '@/constants/abacus';
|
||||||
|
|
||||||
export const ENDPOINTS_PATH =
|
|
||||||
import.meta.env.MODE === 'production'
|
|
||||||
? 'config/prod/endpoints.json'
|
|
||||||
: 'config/staging/dev_endpoints.json';
|
|
||||||
|
|
||||||
class AbacusFileSystem implements AbacusFileSystemProtocol {
|
class AbacusFileSystem implements AbacusFileSystemProtocol {
|
||||||
readTextFile(location: FileLocation, path: string): Nullable<string> {
|
readTextFile(location: FileLocation, path: string): Nullable<string> {
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ import AbacusStateNotifier from './stateNotification';
|
|||||||
import AbacusLocalizer from './localizer';
|
import AbacusLocalizer from './localizer';
|
||||||
import AbacusFormatter from './formatter';
|
import AbacusFormatter from './formatter';
|
||||||
import AbacusThreading from './threading';
|
import AbacusThreading from './threading';
|
||||||
import AbacusFileSystem, { ENDPOINTS_PATH } from './filesystem';
|
import AbacusFileSystem from './filesystem';
|
||||||
import { LocaleSeparators } from '../numbers';
|
import { LocaleSeparators } from '../numbers';
|
||||||
class AbacusStateManager {
|
class AbacusStateManager {
|
||||||
private store: RootStore | undefined;
|
private store: RootStore | undefined;
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import type { AbacusWebsocketProtocol } from '@/constants/abacus';
|
import type { AbacusWebsocketProtocol } from '@/constants/abacus';
|
||||||
import type { TradingViewBar } from '@/constants/candles';
|
import type { TradingViewBar } from '@/constants/candles';
|
||||||
|
import { isDev } from '@/constants/networks';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
PING_INTERVAL_MS,
|
PING_INTERVAL_MS,
|
||||||
@@ -161,13 +162,13 @@ class AbacusWebsocket implements Omit<AbacusWebsocketProtocol, '__doNotUseOrImpl
|
|||||||
|
|
||||||
this.socket.onclose = (e) => {
|
this.socket.onclose = (e) => {
|
||||||
this.connectedCallback?.(false);
|
this.connectedCallback?.(false);
|
||||||
if (import.meta.env.MODE === 'production') return;
|
if (!isDev) return;
|
||||||
console.warn('AbacusStateManager > WS > close > ', e);
|
console.warn('AbacusStateManager > WS > close > ', e);
|
||||||
};
|
};
|
||||||
|
|
||||||
this.socket.onerror = (e) => {
|
this.socket.onerror = (e) => {
|
||||||
this.connectedCallback?.(false);
|
this.connectedCallback?.(false);
|
||||||
if (import.meta.env.MODE === 'production') return;
|
if (!isDev) return;
|
||||||
console.error('AbacusStateManager > WS > error > ', e);
|
console.error('AbacusStateManager > WS > error > ', e);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
|
import { isDev } from "@/constants/networks";
|
||||||
|
|
||||||
export const log = (location: string, error: Error, metadata?: any) => {
|
export const log = (location: string, error: Error, metadata?: any) => {
|
||||||
if (import.meta.env.MODE !== 'production') {
|
if (isDev) {
|
||||||
console.warn('telemetry/log:', { location, error, metadata });
|
console.warn('telemetry/log:', { location, error, metadata });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import type { PayloadAction } from '@reduxjs/toolkit';
|
|||||||
|
|
||||||
import { AbacusApiStatus } from '@/constants/abacus';
|
import { AbacusApiStatus } from '@/constants/abacus';
|
||||||
import { DialogTypes } from '@/constants/dialogs';
|
import { DialogTypes } from '@/constants/dialogs';
|
||||||
|
import { isDev } from '@/constants/networks';
|
||||||
|
|
||||||
import { setApiState, setSelectedNetwork } from '@/state/app';
|
import { setApiState, setSelectedNetwork } from '@/state/app';
|
||||||
import { resetPerpetualsState } from '@/state/perpetuals';
|
import { resetPerpetualsState } from '@/state/perpetuals';
|
||||||
@@ -30,7 +31,7 @@ export default (store: any) => (next: any) => async (action: PayloadAction<any>)
|
|||||||
store.dispatch(
|
store.dispatch(
|
||||||
openDialog({
|
openDialog({
|
||||||
type: DialogTypes.ExchangeOffline,
|
type: DialogTypes.ExchangeOffline,
|
||||||
dialogProps: { preventClose: import.meta.env.MODE === 'production' },
|
dialogProps: { preventClose: !isDev },
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import styled, { type AnyStyledComponent } from 'styled-components';
|
import styled, { type AnyStyledComponent } from 'styled-components';
|
||||||
|
|
||||||
|
import { isMainnet } from '@/constants/networks';
|
||||||
import { STRING_KEYS } from '@/constants/localization';
|
import { STRING_KEYS } from '@/constants/localization';
|
||||||
import { useBreakpoints, useStringGetter } from '@/hooks';
|
import { useBreakpoints, useStringGetter } from '@/hooks';
|
||||||
|
|
||||||
@@ -27,14 +28,22 @@ export const DepositDialog = ({ setIsOpen }: ElementProps) => {
|
|||||||
isOpen
|
isOpen
|
||||||
setIsOpen={setIsOpen}
|
setIsOpen={setIsOpen}
|
||||||
title={stringGetter({ key: STRING_KEYS.DEPOSIT })}
|
title={stringGetter({ key: STRING_KEYS.DEPOSIT })}
|
||||||
description={showTestDeposit && 'Test funds will be sent directly to your dYdX account.'}
|
description={
|
||||||
|
!isMainnet && showTestDeposit && 'Test funds will be sent directly to your dYdX account.'
|
||||||
|
}
|
||||||
placement={isMobile ? DialogPlacement.FullScreen : DialogPlacement.Default}
|
placement={isMobile ? DialogPlacement.FullScreen : DialogPlacement.Default}
|
||||||
>
|
>
|
||||||
<Styled.Content>
|
<Styled.Content>
|
||||||
{showTestDeposit ? <TestnetDepositForm onDeposit={closeDialog} /> : <DepositForm />}
|
{!isMainnet && showTestDeposit ? (
|
||||||
<Styled.TextToggle onClick={() => setShowTestDeposit(!showTestDeposit)}>
|
<TestnetDepositForm onDeposit={closeDialog} />
|
||||||
{showTestDeposit ? 'Show deposit form (Under Construction)' : 'Show test faucet'}
|
) : (
|
||||||
</Styled.TextToggle>
|
<DepositForm />
|
||||||
|
)}
|
||||||
|
{!isMainnet && (
|
||||||
|
<Styled.TextToggle onClick={() => setShowTestDeposit(!showTestDeposit)}>
|
||||||
|
{showTestDeposit ? 'Show deposit form (Under Construction)' : 'Show test faucet'}
|
||||||
|
</Styled.TextToggle>
|
||||||
|
)}
|
||||||
</Styled.Content>
|
</Styled.Content>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import { shallowEqual, useDispatch, useSelector } from 'react-redux';
|
|||||||
import { AbacusApiStatus } from '@/constants/abacus';
|
import { AbacusApiStatus } from '@/constants/abacus';
|
||||||
import { DialogTypes } from '@/constants/dialogs';
|
import { DialogTypes } from '@/constants/dialogs';
|
||||||
import { STRING_KEYS } from '@/constants/localization';
|
import { STRING_KEYS } from '@/constants/localization';
|
||||||
|
import { isDev } from '@/constants/networks';
|
||||||
|
|
||||||
import { useApiState, useStringGetter } from '@/hooks';
|
import { useApiState, useStringGetter } from '@/hooks';
|
||||||
import { layoutMixins } from '@/styles/layoutMixins';
|
import { layoutMixins } from '@/styles/layoutMixins';
|
||||||
@@ -45,7 +46,7 @@ export const ExchangeOfflineDialog = ({ preventClose, setIsOpen }: ElementProps)
|
|||||||
>
|
>
|
||||||
<Styled.Content>
|
<Styled.Content>
|
||||||
<p>{statusErrorMessage}</p>
|
<p>{statusErrorMessage}</p>
|
||||||
{import.meta.env.MODE !== 'production' && <NetworkSelectMenu />}
|
{isDev && <NetworkSelectMenu />}
|
||||||
</Styled.Content>
|
</Styled.Content>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ 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';
|
||||||
@@ -10,10 +9,11 @@ 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 } from '@/hooks';
|
import { useAccounts, useDebounce, useStringGetter, useSelectedNetwork } 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,6 +54,7 @@ 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();
|
||||||
@@ -239,7 +240,7 @@ export const DepositForm = ({ onDeposit, onError }: DepositFormProps) => {
|
|||||||
if (txHash) {
|
if (txHash) {
|
||||||
addTransferNotification({
|
addTransferNotification({
|
||||||
txHash: txHash,
|
txHash: txHash,
|
||||||
toChainId: TESTNET_CHAIN_ID,
|
toChainId: ENVIRONMENT_CONFIG_MAP[selectedNetwork].dydxChainId,
|
||||||
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,6 +17,7 @@ import {
|
|||||||
useDebounce,
|
useDebounce,
|
||||||
useDydxClient,
|
useDydxClient,
|
||||||
useRestrictions,
|
useRestrictions,
|
||||||
|
useSelectedNetwork,
|
||||||
useStringGetter,
|
useStringGetter,
|
||||||
useSubaccount,
|
useSubaccount,
|
||||||
} from '@/hooks';
|
} from '@/hooks';
|
||||||
@@ -52,6 +53,7 @@ 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) || {};
|
||||||
@@ -164,7 +166,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: TESTNET_CHAIN_ID,
|
fromChainId: ENVIRONMENT_CONFIG_MAP[selectedNetwork].dydxChainId,
|
||||||
toChainId: chainIdStr || undefined,
|
toChainId: chainIdStr || undefined,
|
||||||
toAmount: debouncedAmountBN.toNumber(),
|
toAmount: debouncedAmountBN.toNumber(),
|
||||||
triggeredAt: Date.now(),
|
triggeredAt: Date.now(),
|
||||||
|
|||||||
Reference in New Issue
Block a user