Compare commits

..
Author SHA1 Message Date
jaredvu 8f75d893bb remove isConnected state from dydxClient 2023-10-18 09:52:17 -07:00
jaredvu c54a5d6d49 Temp remove notif onClick 2023-10-17 23:52:15 -07:00
jaredvu 2345ef38a1 Fix tradingView initial load 2023-10-17 23:50:38 -07:00
jaredvu 73cbb4e04e Fix goodTilTime string 2023-10-17 23:50:24 -07:00
jaredvu 52e1dcc4b0 Update to abacus0.7.0 2023-10-17 23:50:11 -07:00
jaredvu cc3f7d1c09 Add Notification icon w/ stroke 2023-10-17 22:00:52 -07:00
34 changed files with 232 additions and 452 deletions
+2 -10
View File
@@ -11,7 +11,6 @@
## Prerequisites
- Node.js version 18 and `pnpm` installed on your system
- Wallet Connect account
For deploying with Vercel, create an account with [Vercel](https://vercel.com/signup) if you don't have one already.
@@ -62,14 +61,7 @@ pnpm ladle
This will automatically open your default browser at `http://localhost:61000`.
## Part 3: Configuring environment
Add or modify the relevant endpoints, links and options in `/public/configs/env.json`.
You'll need to provide a Wallet Connect project id to enable onboarding and wallet connection:
- Create a project on https://cloud.walletconnect.com/app
- Copy over the project ID into this [field](https://github.com/dydxprotocol/v4-web/blob/67ecbd75b43e0c264b7b4d2d9b3d969830b0621c/public/configs/env.json#L822C33-L822C46)
## Part 4: Deploying with Vercel
## Part 3: Deploying with Vercel
### Step 1: Connect your repository to Vercel
@@ -86,7 +78,7 @@ If you wish to incorporate analytics via Amplitude and Bugsnag, you can use our
For more details, check out Vercel's [official documentation](https://vercel.com/docs).
## Part 5: Deploying to IPFS
## Part 4: Deploying to IPFS
### web3.storage: deploy to IPFS via web3.storage using the provided script
+3 -3
View File
@@ -38,9 +38,9 @@
"@cosmjs/proto-signing": "^0.31.0",
"@cosmjs/stargate": "^0.31.0",
"@cosmjs/tendermint-rpc": "^0.31.0",
"@dydxprotocol/v4-abacus": "^0.7.2",
"@dydxprotocol/v4-client-js": "^0.40.3",
"@dydxprotocol/v4-localization": "^0.1.32",
"@dydxprotocol/v4-abacus": "^0.7.0",
"@dydxprotocol/v4-client-js": "^0.36.1",
"@dydxprotocol/v4-localization": "^0.1.30",
"@ethersproject/providers": "^5.7.2",
"@js-joda/core": "^5.5.3",
"@radix-ui/react-collapsible": "^1.0.3",
+24 -25
View File
@@ -27,14 +27,14 @@ dependencies:
specifier: ^0.31.0
version: 0.31.0
'@dydxprotocol/v4-abacus':
specifier: ^0.7.2
version: 0.7.2
specifier: ^0.7.0
version: 0.7.0
'@dydxprotocol/v4-client-js':
specifier: ^0.40.3
version: 0.40.3
specifier: ^0.36.1
version: 0.36.1
'@dydxprotocol/v4-localization':
specifier: ^0.1.32
version: 0.1.32
specifier: ^0.1.30
version: 0.1.30
'@ethersproject/providers':
specifier: ^5.7.2
version: 5.7.2
@@ -645,7 +645,7 @@ packages:
/@confio/ics23@0.6.8:
resolution: {integrity: sha512-wB6uo+3A50m0sW/EWcU64xpV/8wShZ6bMTa7pF8eYsTrSkQA7oLUIJcs/wb8g4y2Oyq701BaGiO6n/ak5WXO1w==}
dependencies:
'@noble/hashes': 1.3.2
'@noble/hashes': 1.3.1
protobufjs: 6.11.4
dev: false
@@ -717,7 +717,7 @@ packages:
'@cosmjs/encoding': 0.30.1
'@cosmjs/math': 0.30.1
'@cosmjs/utils': 0.30.1
'@noble/hashes': 1.3.2
'@noble/hashes': 1.3.1
bn.js: 5.2.1
elliptic: 6.5.4
libsodium-wrappers: 0.7.11
@@ -979,12 +979,12 @@ packages:
resolution: {integrity: sha512-RpfLEtTlyIxeNPGKcokS+p3BZII/Q3bYxryFRglh5H3A3T8q9fsLYm72VYAMEOOIBLEa8o93kFLiBDUWKrwXZA==}
dev: true
/@dydxprotocol/v4-abacus@0.7.2:
resolution: {integrity: sha512-5foamomN82FH6ko3EuzwFlSoAEY6Sal8fDgvZo2RsB19Ks6SFgFDeeOcEDdfoa3DNwvl8yW0C9cfxeQ+BfU8uA==}
/@dydxprotocol/v4-abacus@0.7.0:
resolution: {integrity: sha512-XheqfIpOODfQFG860oH0fneVgp9qQKPMDTwrvFXaM/JtKH9ekOUUO6De72EsJ7qOuxWwl1WgoALA8b4tRs0tiw==}
dev: false
/@dydxprotocol/v4-client-js@0.40.3:
resolution: {integrity: sha512-nMQd6tYisKDKIbfx0BGJSYEOSt+I+t5SsaBSmlgTdso+w2rCRO9vyxS+u6MF9h4w5FsVRfhHo3e6uTWX48WpGQ==}
/@dydxprotocol/v4-client-js@0.36.1:
resolution: {integrity: sha512-KJ3MtWI61wmm+xZtXQd7/hYKIoVFG32TRdyyVaXXO8vpW9Oqd0JD8QSM/wuegkciAh5YmP/BrDzYuu77zHO6yg==}
dependencies:
'@cosmjs/amino': 0.30.1
'@cosmjs/encoding': 0.31.1
@@ -993,15 +993,14 @@ packages:
'@cosmjs/stargate': 0.30.1
'@cosmjs/tendermint-rpc': 0.30.1
'@cosmjs/utils': 0.31.1
'@dydxprotocol/v4-proto': 0.4.1
'@dydxprotocol/v4-proto': 0.2.1
'@osmonauts/lcd': 0.6.0
'@scure/bip32': 1.3.2
'@scure/bip32': 1.3.1
'@scure/bip39': 1.2.1
axios: 1.1.3
bech32: 1.1.4
bignumber.js: 9.1.1
ethereum-cryptography: 2.1.2
ethers: 6.6.1
long: 4.0.0
protobufjs: 6.11.4
ws: 8.13.0(bufferutil@4.0.7)(utf-8-validate@5.0.10)
@@ -1011,12 +1010,12 @@ packages:
- utf-8-validate
dev: false
/@dydxprotocol/v4-localization@0.1.32:
resolution: {integrity: sha512-ZtXScxgFLjUt0Ag52RyFnQe9aEl1Aky5fp+vMGOBduVkFiCEMRMkSsSgg6grMdyw/x0AbnxOTRkhYoX2MsK9Ow==}
/@dydxprotocol/v4-localization@0.1.30:
resolution: {integrity: sha512-xTlQuQmPz7wfGkjd07giYMAxRrolDbJE3DryJSIMB6R1MBq1wLzAcwp/iR/nELRwilRX9c44Tap0gGt+oAajiQ==}
dev: false
/@dydxprotocol/v4-proto@0.4.1:
resolution: {integrity: sha512-2pBkokufWcxfIpiXE6QuQOBXUe154OTp6ojCIdOPW9TFLxzchoygxXnb5dL6rAQVNj9Qbg+hhXBllutt4m99dw==}
/@dydxprotocol/v4-proto@0.2.1:
resolution: {integrity: sha512-Q5b/g331DoyMjBpO2/jtrxUX3WF5UaIKZp/unK332xuefHNFnkMYtZ05p0V71iSdO35tBdz8yt0VYP2WtUsp+w==}
dependencies:
protobufjs: 6.11.4
dev: false
@@ -4709,8 +4708,8 @@ packages:
resolution: {integrity: sha512-osvveYtyzdEVbt3OfwwXFr4P2iVBL5u1Q3q4ONBfDY/UpOuXmOlbgwc1xECEboY8wIays8Yt6onaWMUdUbfl0A==}
dependencies:
'@noble/curves': 1.1.0
'@noble/hashes': 1.3.2
'@scure/base': 1.1.3
'@noble/hashes': 1.3.1
'@scure/base': 1.1.1
dev: false
/@scure/bip32@1.3.2:
@@ -4732,7 +4731,7 @@ packages:
resolution: {integrity: sha512-Z3/Fsz1yr904dduJD0NpiyRHhRYHdcnyh73FZWiV+/qhWi83wNJ3NWolYqCEN+ZWsUz2TWwajJggcRE9r1zUYg==}
dependencies:
'@noble/hashes': 1.3.2
'@scure/base': 1.1.3
'@scure/base': 1.1.1
dev: false
/@solana/buffer-layout@4.0.1:
@@ -4746,8 +4745,8 @@ packages:
resolution: {integrity: sha512-up5VG1dK+GPhykmuMIozJZBbVqpm77vbOG6/r5dS7NBGZonwHfTLdBbsYc3rjmaQ4DpCXUa3tUc4RZHRORvZrw==}
dependencies:
'@babel/runtime': 7.22.10
'@noble/curves': 1.2.0
'@noble/hashes': 1.3.2
'@noble/curves': 1.1.0
'@noble/hashes': 1.3.1
'@solana/buffer-layout': 4.0.1
agentkeepalive: 4.5.0
bigint-buffer: 1.1.5
@@ -7145,7 +7144,7 @@ packages:
/bip39@3.1.0:
resolution: {integrity: sha512-c9kiwdk45Do5GL0vJMe7tS95VjCii65mYAH7DfWl3uW8AVzXKQVUm64i3hzVybBDMp9r7j9iNxR85+ul8MdN/A==}
dependencies:
'@noble/hashes': 1.3.2
'@noble/hashes': 1.3.1
dev: false
/bl@5.1.0:
Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

+16 -16
View File
@@ -40,7 +40,7 @@
"isMainNet": false,
"tokens": {
"chain": {
"name": "Dv4TNT",
"name": "DYDX",
"denom": "adv4tnt",
"decimals": 18,
"image": "/currencies/dydx.png"
@@ -100,7 +100,7 @@
"isMainNet": false,
"tokens": {
"chain": {
"name": "Dv4TNT",
"name": "DYDX",
"denom": "adv4tnt",
"decimals": 18,
"image": "/currencies/dydx.png"
@@ -121,7 +121,7 @@
}
],
"validators": [
"http://54.92.118.111"
"http://35.75.227.118"
],
"0xsquid": "https://testnet.api.0xsquid.com"
},
@@ -159,7 +159,7 @@
"isMainNet": false,
"tokens": {
"chain": {
"name": "Dv4TNT",
"name": "DYDX",
"denom": "adv4tnt",
"decimals": 18,
"image": "/currencies/dydx.png"
@@ -218,7 +218,7 @@
"isMainNet": false,
"tokens": {
"chain": {
"name": "Dv4TNT",
"name": "DYDX",
"denom": "adv4tnt",
"decimals": 18,
"image": "/currencies/dydx.png"
@@ -277,7 +277,7 @@
"isMainNet": false,
"tokens": {
"chain": {
"name": "Dv4TNT",
"name": "DYDX",
"denom": "adv4tnt",
"decimals": 18,
"image": "/currencies/dydx.png"
@@ -340,7 +340,7 @@
"isMainNet": false,
"tokens": {
"chain": {
"name": "Dv4TNT",
"name": "DYDX",
"denom": "adv4tnt",
"decimals": 18,
"image": "/currencies/dydx.png"
@@ -403,7 +403,7 @@
"isMainNet": false,
"tokens": {
"chain": {
"name": "Dv4TNT",
"name": "DYDX",
"denom": "adv4tnt",
"decimals": 18,
"image": "/currencies/dydx.png"
@@ -468,7 +468,7 @@
"isMainNet": false,
"tokens": {
"chain": {
"name": "Dv4TNT",
"name": "DYDX",
"denom": "adv4tnt",
"decimals": 18,
"image": "/currencies/dydx.png"
@@ -532,7 +532,7 @@
"isMainNet": false,
"tokens": {
"chain": {
"name": "Dv4TNT",
"name": "DYDX",
"denom": "adv4tnt",
"decimals": 18,
"image": "/currencies/dydx.png"
@@ -596,7 +596,7 @@
"isMainNet": false,
"tokens": {
"chain": {
"name": "Dv4TNT",
"name": "DYDX",
"denom": "adv4tnt",
"decimals": 18,
"image": "/currencies/dydx.png"
@@ -660,7 +660,7 @@
"isMainNet": false,
"tokens": {
"chain": {
"name": "Dv4TNT",
"name": "DYDX",
"denom": "adv4tnt",
"decimals": 18,
"image": "/currencies/dydx.png"
@@ -724,7 +724,7 @@
"isMainNet": false,
"tokens": {
"chain": {
"name": "Dv4TNT",
"name": "DYDX",
"denom": "adv4tnt",
"decimals": 18,
"image": "/currencies/dydx.png"
@@ -789,8 +789,8 @@
"tokens": {
"comment": "Change according to mainnet release",
"chain": {
"name": "TokenName",
"denom": "tokenDenom",
"name": "DYDX",
"denom": "adv4tnt",
"decimals": 18,
"image": "/currencies/dydx.png"
},
@@ -844,4 +844,4 @@
}
}
}
}
}
+2 -14
View File
@@ -7,13 +7,7 @@ import { GrazProvider } from 'graz';
import { AppRoute, DEFAULT_TRADE_ROUTE } from '@/constants/routes';
import {
useBreakpoints,
useTokenConfigs,
useInitializePage,
useShouldShowFooter,
useAnalytics,
} from '@/hooks';
import { useBreakpoints, useInitializePage, useShouldShowFooter, useAnalytics } from '@/hooks';
import { DydxProvider } from '@/hooks/useDydxClient';
import { AccountsProvider } from '@/hooks/useAccounts';
import { DialogAreaProvider, useDialogArea } from '@/hooks/useDialogArea';
@@ -33,8 +27,6 @@ import ProfilePage from '@/pages/Profile';
import { SettingsPage } from '@/pages/settings/Settings';
import TradePage from '@/pages/trade/Trade';
import { RewardsPage } from '@/pages/rewards/RewardsPage';
import { TermsOfUsePage } from '@/pages/TermsOfUsePage';
import { PrivacyPolicyPage } from '@/pages/PrivacyPolicyPage';
import { HeaderDesktop } from '@/layout/Header/HeaderDesktop';
import { FooterDesktop } from '@/layout/Footer/FooterDesktop';
@@ -63,7 +55,6 @@ const Content = () => {
const { isTablet, isNotTablet } = useBreakpoints();
const isShowingHeader = isNotTablet;
const isShowingFooter = useShouldShowFooter();
const { chainTokenLabel } = useTokenConfigs();
return (
<Styled.Content isShowingHeader={isShowingHeader} isShowingFooter={isShowingFooter}>
@@ -78,7 +69,7 @@ const Content = () => {
</Route>
<Route path={AppRoute.Markets} element={<MarketsPage />} />
<Route path={`/${chainTokenLabel}`} element={<RewardsPage />} />
<Route path={AppRoute.Rewards} element={<RewardsPage />} />
{isTablet && (
<>
<Route path={AppRoute.Alerts} element={<AlertsPage />} />
@@ -91,9 +82,6 @@ const Content = () => {
<Route path={`${AppRoute.Portfolio}/*`} element={<PortfolioPage />} />
</Route>
<Route path={AppRoute.Terms} element={<TermsOfUsePage />} />
<Route path={AppRoute.Privacy} element={<PrivacyPolicyPage />} />
<Route path="*" element={<Navigate to={DEFAULT_TRADE_ROUTE} replace />} />
</Routes>
</Suspense>
+1 -2
View File
@@ -7,8 +7,7 @@ export enum AppRoute {
Profile = '/profile',
Alerts = '/alerts',
Settings = '/settings',
Terms = '/terms',
Privacy = '/privacy',
Rewards = '/DV4TNT',
}
export enum PortfolioRoute {
+12 -2
View File
@@ -1,5 +1,5 @@
import type { ExternalProvider } from '@ethersproject/providers';
import { type onboarding } from '@dydxprotocol/v4-client-js';
import { USDC_DENOM, type onboarding, DYDX_DENOM } from '@dydxprotocol/v4-client-js';
import type { suggestChain } from 'graz';
import { STRING_KEYS } from '@/constants/localization';
@@ -352,5 +352,15 @@ export const DYDX_CHAIN_INFO: Parameters<typeof suggestChain>[0] = {
// TODO: export this type from abacus instead
export enum DydxChainAsset {
USDC = 'usdc',
CHAINTOKEN = 'chain',
DYDX = 'dydx',
}
export const DYDX_CHAIN_ASSET_COIN_DENOM: Record<DydxChainAsset, string> = {
[DydxChainAsset.USDC]: USDC_DENOM,
[DydxChainAsset.DYDX]: DYDX_DENOM,
};
export const DYDX_CHAIN_ASSET_TAGS: Record<DydxChainAsset, string> = {
[DydxChainAsset.USDC]: 'USDC',
[DydxChainAsset.DYDX]: 'Dv4TNT',
};
-2
View File
@@ -1,6 +1,5 @@
import { useApiState } from './useApiState';
import { useBreakpoints } from './useBreakpoints';
import { useTokenConfigs } from './useTokenConfigs';
import { useCommandMenu } from './useCommandMenu';
import { useCurrentMarketId } from './useCurrentMarketId';
import { useDebounce } from './useDebounce';
@@ -26,7 +25,6 @@ import { useSubaccount } from './useSubaccount';
export {
useApiState,
useBreakpoints,
useTokenConfigs,
useCommandMenu,
useCurrentMarketId,
useDebounce,
+12 -8
View File
@@ -5,6 +5,8 @@ import { StargateClient } from '@cosmjs/stargate';
import { useQuery } from 'react-query';
import { formatUnits } from 'viem';
import { USDC_DENOM, DYDX_DENOM } from '@dydxprotocol/v4-client-js';
import { ENVIRONMENT_CONFIG_MAP } from '@/constants/networks';
import { QUANTUM_MULTIPLIER } from '@/constants/numbers';
import { EvmAddress } from '@/constants/wallets';
@@ -16,7 +18,6 @@ import { getBalances, getStakingBalances } from '@/state/accountSelectors';
import { getSelectedNetwork } from '@/state/appSelectors';
import { useAccounts } from './useAccounts';
import { useTokenConfigs } from './useTokenConfigs';
type UseAccountBalanceProps = {
// Token Items
@@ -51,7 +52,6 @@ export const useAccountBalance = ({
const selectedNetwork = useSelector(getSelectedNetwork);
const balances = useSelector(getBalances, shallowEqual);
const { chainTokenDenom, usdcDenom } = useTokenConfigs();
const evmChainId = Number(ENVIRONMENT_CONFIG_MAP[selectedNetwork].ethereumChainId);
const stakingBalances = useSelector(getStakingBalances, shallowEqual);
@@ -93,14 +93,18 @@ export const useAccountBalance = ({
const { formatted: evmBalance } = evmQuery.data || {};
const balance = !assetSymbol ? '0' : isCosmosChain ? cosmosQuery.data : evmBalance;
const nativeTokenCoinBalance = balances?.[chainTokenDenom];
const nativeTokenBalance = MustBigNumber(nativeTokenCoinBalance?.amount);
const nativeTokenCoinBalance = balances?.[DYDX_DENOM];
const nativeTokenBalance = MustBigNumber(nativeTokenCoinBalance?.amount)
.div(QUANTUM_MULTIPLIER)
.toNumber();
const usdcCoinBalance = balances?.[usdcDenom];
const usdcBalance = MustBigNumber(usdcCoinBalance?.amount).toNumber();
const usdcCoinBalance = balances?.[USDC_DENOM];
const usdcBalance = MustBigNumber(usdcCoinBalance?.amount).div(QUANTUM_MULTIPLIER).toNumber();
const nativeStakingCoinBalanace = stakingBalances?.[chainTokenDenom];
const nativeStakingBalance = MustBigNumber(nativeStakingCoinBalanace?.amount).toNumber();
const nativeStakingCoinBalanace = stakingBalances?.[DYDX_DENOM];
const nativeStakingBalance = MustBigNumber(nativeStakingCoinBalanace?.amount)
.div(QUANTUM_MULTIPLIER)
.toNumber();
return {
balance,
+11 -2
View File
@@ -2,7 +2,7 @@ import { useCallback, useContext, createContext, useEffect, useState, useMemo }
import { useDispatch } from 'react-redux';
import { AES, enc } from 'crypto-js';
import { LocalWallet, type Subaccount } from '@dydxprotocol/v4-client-js';
import { LocalWallet, USDC_DENOM, type Subaccount } from '@dydxprotocol/v4-client-js';
import { OnboardingGuard, OnboardingState, type EvmDerivedAddresses } from '@/constants/account';
import { DialogTypes } from '@/constants/dialogs';
@@ -130,8 +130,16 @@ const useAccountsContext = () => {
// dYdX subaccounts
const [dydxSubaccounts, setDydxSubaccounts] = useState<Subaccount[] | undefined>();
const { getSubaccounts } = useMemo(
const { getAccountBalance, getSubaccounts } = useMemo(
() => ({
getAccountBalance: async ({
dydxAddress,
denom = USDC_DENOM,
}: {
dydxAddress: DydxAddress;
denom?: string;
}) => await compositeClient?.validatorClient.get.getAccountBalance(dydxAddress, denom),
getSubaccounts: async ({ dydxAddress }: { dydxAddress: DydxAddress }) => {
try {
const response = await compositeClient?.indexerClient.account.getSubaccounts(dydxAddress);
@@ -318,6 +326,7 @@ const useAccountsContext = () => {
disconnect,
// dydxClient Account methods
getAccountBalance,
getSubaccounts,
};
};
+1 -11
View File
@@ -15,8 +15,6 @@ import type { ResolutionString } from 'public/tradingview/charting_library';
import type { ConnectNetworkEvent, NetworkConfig } from '@/constants/abacus';
import { type Candle, RESOLUTION_MAP } from '@/constants/candles';
import { ENVIRONMENT_CONFIG_MAP } from '@/constants/networks';
import { DydxChainAsset } from '@/constants/wallets';
import { getSelectedNetwork } from '@/state/appSelectors';
@@ -38,7 +36,6 @@ const useDydxClientContext = () => {
// ------ Network ------ //
const selectedNetwork = useSelector(getSelectedNetwork);
const tokensConfigs = ENVIRONMENT_CONFIG_MAP[selectedNetwork].tokens;
const [networkConfig, setNetworkConfig] = useState<NetworkConfig>();
@@ -68,14 +65,7 @@ const useDydxClientContext = () => {
new Network(
selectedNetwork,
new IndexerConfig(networkConfig.indexerUrl, networkConfig.websocketUrl),
new ValidatorConfig(networkConfig.validatorUrl, networkConfig.chainId,
{
USDC_DENOM: tokensConfigs[DydxChainAsset.USDC].denom,
USDC_DECIMALS: tokensConfigs[DydxChainAsset.USDC].decimals,
USDC_GAS_DENOM: tokensConfigs[DydxChainAsset.USDC].gasDenom,
CHAINTOKEN_DENOM: tokensConfigs[DydxChainAsset.CHAINTOKEN].denom,
CHAINTOKEN_DECIMALS: tokensConfigs[DydxChainAsset.CHAINTOKEN].decimals,
}, {
new ValidatorConfig(networkConfig.validatorUrl, networkConfig.chainId, {
broadcastPollIntervalMs: 3_000,
broadcastTimeoutMs: 60_000,
})
+14 -1
View File
@@ -1,6 +1,7 @@
import { useCallback } from 'react';
import { useCallback, useEffect } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { DialogTypes } from '@/constants/dialogs';
import { LocalStorageKey } from '@/constants/localStorage';
import { DEFAULT_APP_ENVIRONMENT, DydxNetwork, ENVIRONMENT_CONFIG_MAP } from '@/constants/networks';
@@ -8,6 +9,7 @@ import { useAccounts, useLocalStorage } from '@/hooks';
import { setSelectedNetwork } from '@/state/app';
import { getSelectedNetwork } from '@/state/appSelectors';
import { openDialog } from '@/state/dialogs';
import { validateAgainstAvailableEnvironments } from '@/lib/network';
@@ -25,6 +27,17 @@ export const useSelectedNetwork = (): {
validateFn: validateAgainstAvailableEnvironments,
});
useEffect(() => {
if (
import.meta.env.MODE === 'production' &&
ENVIRONMENT_CONFIG_MAP[selectedNetwork].dydxChainId === 'dydx-testnet-4'
) {
dispatch(
openDialog({ type: DialogTypes.ExchangeOffline, dialogProps: { preventClose: true } })
);
}
}, [selectedNetwork]);
const switchNetwork = useCallback(
(network: DydxNetwork) => {
disconnect();
+17 -22
View File
@@ -3,10 +3,15 @@ import { shallowEqual, useSelector, useDispatch } from 'react-redux';
import type { Nullable } from '@dydxprotocol/v4-abacus';
import Long from 'long';
import type { IndexedTx } from '@cosmjs/stargate';
import type { EncodeObject } from '@cosmjs/proto-signing';
import type { EncodeObject, Coin } from '@cosmjs/proto-signing';
import { Method } from '@cosmjs/tendermint-rpc';
import { type LocalWallet, SubaccountClient } from '@dydxprotocol/v4-client-js';
import {
type LocalWallet,
SubaccountClient,
DYDX_DENOM,
USDC_DENOM,
} from '@dydxprotocol/v4-client-js';
import type {
AccountBalance,
@@ -29,7 +34,6 @@ import { MustBigNumber } from '@/lib/numbers';
import { log } from '@/lib/telemetry';
import { useAccounts } from './useAccounts';
import { useTokenConfigs } from './useTokenConfigs';
import { useDydxClient } from './useDydxClient';
type SubaccountContextType = ReturnType<typeof useSubaccountContext>;
@@ -48,7 +52,6 @@ export const useSubaccount = () => useContext(SubaccountContext);
export const useSubaccountContext = ({ localDydxWallet }: { localDydxWallet?: LocalWallet }) => {
const dispatch = useDispatch();
const { usdcDenom } = useTokenConfigs();
const { compositeClient, faucetClient } = useDydxClient();
const { getFaucetFunds } = useMemo(
@@ -88,7 +91,7 @@ export const useSubaccountContext = ({ localDydxWallet }: { localDydxWallet?: Lo
}: {
subaccountClient: SubaccountClient;
amount: number;
}) => await compositeClient?.withdrawFromSubaccount(subaccountClient, amount.toString()),
}) => await compositeClient?.withdrawFromSubaccount(subaccountClient, amount),
transferFromSubaccountToAddress: async ({
subaccountClient,
@@ -131,21 +134,12 @@ export const useSubaccountContext = ({ localDydxWallet }: { localDydxWallet?: Lo
amount: number;
recipient: string;
}) =>
await compositeClient?.validatorClient.post.send(
subaccountClient.wallet,
() =>
new Promise((resolve) => {
const msg = compositeClient?.sendTokenMessage(
subaccountClient.wallet,
amount.toString(),
recipient,
);
resolve([msg]);
}),
await compositeClient?.validatorClient.post.sendToken(
subaccountClient,
recipient,
DYDX_DENOM,
Long.fromNumber(amount * QUANTUM_MULTIPLIER),
false,
compositeClient?.validatorClient?.post.defaultDydxGasPrice,
undefined,
Method.BroadcastTxCommit
),
@@ -162,7 +156,7 @@ export const useSubaccountContext = ({ localDydxWallet }: { localDydxWallet?: Lo
const transaction = JSON.parse(payload);
const msg = compositeClient.withdrawFromSubaccountMessage(subaccountClient, amount.toString());
const msg = compositeClient.withdrawFromSubaccountMessage(subaccountClient, amount);
const ibcMsg: EncodeObject = {
typeUrl: transaction.msgTypeUrl,
value: transaction.msg,
@@ -216,7 +210,7 @@ export const useSubaccountContext = ({ localDydxWallet }: { localDydxWallet?: Lo
);
const balances = useSelector(getBalances, shallowEqual);
const usdcCoinBalance = balances?.[usdcDenom];
const usdcCoinBalance = balances?.[USDC_DENOM];
useEffect(() => {
if (usdcCoinBalance) {
@@ -253,7 +247,8 @@ export const useSubaccountContext = ({ localDydxWallet }: { localDydxWallet?: Lo
if (!subaccountClient) {
return;
}
return (await (coinDenom === usdcDenom
return (await (coinDenom === USDC_DENOM
? transferFromSubaccountToAddress
: transferNativeToken)({ subaccountClient, amount, recipient })) as IndexedTx;
},
-36
View File
@@ -1,36 +0,0 @@
import { ENVIRONMENT_CONFIG_MAP } from '@/constants/networks';
import { DydxChainAsset } from '@/constants/wallets';
import { useSelectedNetwork } from '@/hooks';
export const useTokenConfigs = (): {
tokensConfigs: {
[DydxChainAsset.USDC]: {
denom: string;
name: string;
decimals: number;
gasDenom?: string;
},
[DydxChainAsset.CHAINTOKEN]: {
denom: string;
name: string;
decimals: number;
gasDenom?: string;
},
};
usdcDenom: string;
usdcLabel: string;
chainTokenDenom: string;
chainTokenLabel: string;
} => {
const { selectedNetwork } = useSelectedNetwork();
const tokensConfigs = ENVIRONMENT_CONFIG_MAP[selectedNetwork].tokens;
return {
tokensConfigs,
usdcDenom: tokensConfigs[DydxChainAsset.USDC].denom,
usdcLabel: tokensConfigs[DydxChainAsset.USDC].name,
chainTokenDenom: tokensConfigs[DydxChainAsset.CHAINTOKEN].denom,
chainTokenLabel: tokensConfigs[DydxChainAsset.CHAINTOKEN].name,
};
};
+1 -10
View File
@@ -1,8 +1,6 @@
import { useCallback, useEffect, useState } from 'react';
import { useSelector } from 'react-redux';
import { LocalStorageKey } from '@/constants/localStorage';
import { ENVIRONMENT_CONFIG_MAP } from '@/constants/networks';
import {
type DydxAddress,
@@ -30,8 +28,6 @@ import {
WalletType as CosmosWalletType,
} from 'graz';
import { getSelectedNetwork } from '@/state/appSelectors';
import { resolveWagmiConnector } from '@/lib/wagmi';
import { getWalletConnection, parseWalletError } from '@/lib/wallet';
import { log } from '@/lib/telemetry';
@@ -88,9 +84,6 @@ export const useWalletConnection = () => {
// Wallet connection
const selectedNetwork = useSelector(getSelectedNetwork);
const walletConnectConfig = ENVIRONMENT_CONFIG_MAP[selectedNetwork].wallets.walletconnect;
const { connectAsync: connectWagmi } =
walletType && walletConnectionType
? useConnectWagmi({
@@ -99,7 +92,6 @@ export const useWalletConnection = () => {
walletConnection: {
type: walletConnectionType,
},
walletConnectConfig,
}),
})
: useConnectWagmi();
@@ -135,7 +127,6 @@ export const useWalletConnection = () => {
connector: resolveWagmiConnector({
walletType,
walletConnection,
walletConnectConfig,
}),
});
}
@@ -226,7 +217,7 @@ export const useWalletConnection = () => {
evmAddressWagmi,
signerWagmi,
publicClientWagmi,
// Wallet connection (Cosmos)
dydxAddress,
dydxAddressGraz,
+6 -8
View File
@@ -6,10 +6,9 @@ import { ButtonShape } from '@/constants/buttons';
import { DialogTypes } from '@/constants/dialogs';
import { STRING_KEYS } from '@/constants/localization';
import { AppRoute } from '@/constants/routes';
import { useStringGetter } from '@/hooks';
import { LogoShortIcon, BellStrokeIcon } from '@/icons';
import { useTokenConfigs, useStringGetter } from '@/hooks';
import { Icon, IconName } from '@/components/Icon';
import { IconButton } from '@/components/IconButton';
import { NavigationMenu } from '@/components/NavigationMenu';
@@ -28,7 +27,6 @@ import { layoutMixins } from '@/styles/layoutMixins';
export const HeaderDesktop = () => {
const stringGetter = useStringGetter();
const dispatch = useDispatch();
const { chainTokenLabel } = useTokenConfigs();
const navItems = [
{
@@ -45,9 +43,9 @@ export const HeaderDesktop = () => {
href: AppRoute.Trade,
},
{
value: chainTokenLabel,
label: chainTokenLabel,
href: `/${chainTokenLabel}`,
value: 'Dv4TNT',
label: 'Dv4TNT',
href: AppRoute.Rewards,
},
{
value: 'PORTFOLIO',
@@ -80,13 +78,13 @@ export const HeaderDesktop = () => {
value: 'TERMS_OF_USE',
slotBefore: <Icon iconName={IconName.File} />,
label: stringGetter({ key: STRING_KEYS.TERMS_OF_USE }),
href: AppRoute.Terms,
href: 'https://dydx.exchange/terms',
},
{
value: 'PRIVACY_POLICY',
slotBefore: <Icon iconName={IconName.Privacy} />,
label: stringGetter({ key: STRING_KEYS.PRIVACY_POLICY }),
href: AppRoute.Privacy,
href: 'https://dydx.exchange/privacy',
},
{
value: 'HELP',
+15 -36
View File
@@ -14,6 +14,8 @@ import {
OrderSide,
OrderTimeInForce,
OrderExecution,
DYDX_DENOM,
GAS_PRICE_DYDX_DENOM,
} from '@dydxprotocol/v4-client-js';
import {
@@ -64,37 +66,16 @@ class DydxChainTransactions implements AbacusDYDXChainTransactionsProtocol {
): Promise<void> {
try {
const parsedParams = paramsInJson ? JSON.parse(paramsInJson) : {};
const {
indexerUrl,
websocketUrl,
validatorUrl,
chainId,
USDC_DENOM,
USDC_DECIMALS,
USDC_GAS_DENOM,
CHAINTOKEN_DENOM,
CHAINTOKEN_DECIMALS,
} = parsedParams;
const { indexerUrl, websocketUrl, validatorUrl, chainId } = parsedParams;
const compositeClient = await CompositeClient.connect(
new Network(
chainId,
new IndexerConfig(indexerUrl, websocketUrl),
new ValidatorConfig(
validatorUrl,
chainId,
{
USDC_DENOM,
USDC_DECIMALS,
USDC_GAS_DENOM,
CHAINTOKEN_DENOM,
CHAINTOKEN_DECIMALS,
},
{
broadcastPollIntervalMs: 3_000,
broadcastTimeoutMs: 60_000,
}
)
new ValidatorConfig(validatorUrl, chainId, {
broadcastPollIntervalMs: 3_000,
broadcastTimeoutMs: 60_000,
})
)
);
@@ -223,13 +204,13 @@ class DydxChainTransactions implements AbacusDYDXChainTransactionsProtocol {
params ?? {};
try {
const tx = await this.compositeClient?.cancelRawOrder(
const tx = await this.compositeClient?.cancelOrder(
new SubaccountClient(this.localWallet, subaccountNumber),
clientId,
orderFlags,
clobPairId,
goodTilBlock || undefined,
goodTilBlockTime || undefined,
goodTilBlock ?? undefined,
goodTilBlockTime ?? undefined
);
const parsedTx = this.parseToPrimitives(tx);
@@ -292,18 +273,16 @@ class DydxChainTransactions implements AbacusDYDXChainTransactionsProtocol {
this.localWallet,
() =>
new Promise((resolve) => {
if (!this.localWallet) {
throw new Error('Missing compositeClient or localWallet');
}
const msg = compositeClient?.sendTokenMessage(
this.localWallet,
amount,
const msg = compositeClient?.validatorClient.post.composer.composeMsgSendToken(
subaccountClient.address,
recipient,
DYDX_DENOM,
Long.fromNumber(amount * QUANTUM_MULTIPLIER)
);
resolve([msg]);
}),
this.compositeClient?.validatorClient?.post.defaultDydxGasPrice,
GAS_PRICE_DYDX_DENOM
);
const parsedTx = this.parseToPrimitives(tx);
+13 -33
View File
@@ -95,28 +95,15 @@ const injectedConnectorOptions = {
},
};
type WalletConnectConfig = {
client: {
name: string;
description: string;
iconUrl: string;
};
v2: {
projectId: string;
};
};
const getWalletconnect2ConnectorOptions = (
config: WalletConnectConfig
): ConstructorParameters<typeof WalletConnectConnector>[0] => ({
const walletconnect2ConnectorOptions: ConstructorParameters<typeof WalletConnectConnector>[0] = {
chains,
options: {
projectId: config.v2.projectId,
projectId: import.meta.env.VITE_WALLETCONNECT2_PROJECT_ID,
metadata: {
name: config.client.name,
description: config.client.description,
name: 'dYdX',
description: '',
url: import.meta.env.VITE_BASE_URL,
icons: [config.client.iconUrl],
icons: [`${import.meta.env.VITE_BASE_URL}/cbw-image.png}`],
},
showQrModal: true,
qrModalOptions: {
@@ -128,9 +115,9 @@ const getWalletconnect2ConnectorOptions = (
explorerRecommendedWalletIds: WALLET_CONNECT_EXPLORER_RECOMMENDED_IDS,
},
},
});
};
const getConnectors = (walletConnectConfig: WalletConnectConfig) => [
const connectors = [
new MetaMaskConnector({
chains,
options: {
@@ -144,7 +131,7 @@ const getConnectors = (walletConnectConfig: WalletConnectConfig) => [
reloadOnDisconnect: false,
},
}),
new WalletConnectConnector(getWalletconnect2ConnectorOptions(walletConnectConfig)),
new WalletConnectConnector(walletconnect2ConnectorOptions),
new InjectedConnector(injectedConnectorOptions),
];
@@ -166,34 +153,27 @@ const createInjectedConnectorWithProvider = (provider: ExternalProvider) =>
provider as unknown as Awaited<ReturnType<InjectedConnector['getProvider']>>;
})(injectedConnectorOptions) as InjectedConnector;
const createWalletConnect2ConnectorWithId = (
walletconnectId: string,
walletConnectConfig: WalletConnectConfig
) => {
const walletconnect2ConnectorOptions = getWalletconnect2ConnectorOptions(walletConnectConfig);
return new WalletConnectConnector({
const createWalletConnect2ConnectorWithId = (walletconnect2Id: string) =>
new WalletConnectConnector({
...walletconnect2ConnectorOptions,
options: {
...walletconnect2ConnectorOptions.options,
qrModalOptions: {
...walletconnect2ConnectorOptions.options.qrModalOptions,
explorerRecommendedWalletIds: [walletconnectId],
explorerRecommendedWalletIds: [walletconnect2Id],
explorerExcludedWalletIds: 'ALL',
},
},
});
};
// Custom connector from wallet selection
export const resolveWagmiConnector = ({
walletType,
walletConnection,
walletConnectConfig,
}: {
walletType: WalletType;
walletConnection: WalletConnection;
walletConnectConfig: WalletConnectConfig;
}) => {
const walletConfig = wallets[walletType];
const walletConnectionConfig = walletConnectionTypes[walletConnection.type];
@@ -201,6 +181,6 @@ export const resolveWagmiConnector = ({
return walletConnection.type === WalletConnectionType.InjectedEip1193 && walletConnection.provider
? createInjectedConnectorWithProvider(walletConnection.provider)
: walletConnection.type === WalletConnectionType.WalletConnect2 && walletConfig.walletconnect2Id
? createWalletConnect2ConnectorWithId(walletConfig.walletconnect2Id, walletConnectConfig)
: getConnectors(walletConnectConfig).find(({ id }: { id: string }) => id === walletConnectionConfig.wagmiConnectorId);
? createWalletConnect2ConnectorWithId(walletConfig.walletconnect2Id)
: connectors.find(({ id }: { id: string }) => id === walletConnectionConfig.wagmiConnectorId);
};
-17
View File
@@ -1,17 +0,0 @@
import styled, { AnyStyledComponent } from 'styled-components';
import { articleMixins } from '@/styles/articleMixins';
export const PrivacyPolicyPage = () => (
<Styled.Article>
<header>
<h1>Privacy Policy</h1>
</header>
</Styled.Article>
);
const Styled: Record<string, AnyStyledComponent> = {};
Styled.Article = styled.article`
${articleMixins.article}
`;
-17
View File
@@ -1,17 +0,0 @@
import styled, { AnyStyledComponent } from 'styled-components';
import { articleMixins } from '@/styles/articleMixins';
export const TermsOfUsePage = () => (
<Styled.Article>
<header>
<h1>Terms of Use</h1>
</header>
</Styled.Article>
);
const Styled: Record<string, AnyStyledComponent> = {};
Styled.Article = styled.article`
${articleMixins.article}
`;
+4 -10
View File
@@ -3,7 +3,7 @@ import styled, { AnyStyledComponent } from 'styled-components';
import { shallowEqual, useDispatch, useSelector } from 'react-redux';
import { layoutMixins } from '@/styles/layoutMixins';
import { useAccountBalance, useAccounts, useTokenConfigs, useStringGetter } from '@/hooks';
import { useAccountBalance, useAccounts, useStringGetter } from '@/hooks';
import { ButtonAction, ButtonSize } from '@/constants/buttons';
import { DialogTypes } from '@/constants/dialogs';
@@ -30,7 +30,6 @@ export const DYDXBalancePanel = () => {
const { walletType } = useAccounts();
const canAccountTrade = useSelector(calculateCanAccountTrade, shallowEqual);
const { nativeTokenBalance, nativeStakingBalance } = useAccountBalance();
const { chainTokenLabel } = useTokenConfigs();
return (
<Panel
@@ -38,7 +37,7 @@ export const DYDXBalancePanel = () => {
<Styled.Header>
<Styled.Title>
{/* <AssetIcon symbol="DYDX" /> */}
{chainTokenLabel}
Dv4TNT
</Styled.Title>
<Styled.ReceiveAndTransferButtons>
{!canAccountTrade ? (
@@ -107,13 +106,7 @@ export const DYDXBalancePanel = () => {
{
key: 'totalBalance',
label: 'Total balance',
value: (
<Output
type={OutputType.Asset}
value={nativeTokenBalance + nativeStakingBalance}
tag={chainTokenLabel}
/>
),
value: <Output type={OutputType.Asset} value={nativeTokenBalance + nativeStakingBalance} tag="Dv4TNT" />,
},
]}
/>
@@ -181,6 +174,7 @@ Styled.WalletAndStakedBalance = styled(Details)`
grid-template-columns: 1fr 1fr;
gap: 0.5rem;
> div {
gap: 1rem;
-2
View File
@@ -24,8 +24,6 @@ export const dialogsSlice = createSlice({
initialState,
reducers: {
openDialog: (state: DialogsState, action: PayloadAction<DialogInfo<DialogTypes>>) => {
if (state.activeDialog?.type === action.payload.type) return;
if (state.activeDialog) {
state.dialogQueue.push(action.payload);
} else {
-53
View File
@@ -1,53 +0,0 @@
import {
css,
type FlattenInterpolation,
type FlattenSimpleInterpolation,
type ThemeProps,
} from 'styled-components';
export const articleMixins: Record<
string,
FlattenSimpleInterpolation | FlattenInterpolation<ThemeProps<any>>
> = {
article: css`
padding: 2rem;
overflow-wrap: break-word;
user-select: text;
margin: 0 auto;
width: 60rem;
max-width: 100vw;
header {
color: var(--color-text-0);
margin-bottom: 2rem;
h1 {
font: var(--font-extra-book);
color: var(--color-text-2);
}
}
h2 {
font: var(--font-large-book);
color: var(--color-text-2);
padding: 0.5rem 0;
}
h3,
strong {
font-weight: 700;
}
strong {
color: var(--color-text-2);
}
p {
padding: 0.5rem 0;
}
ul {
padding: 0.5rem 1rem;
}
`,
};
@@ -75,14 +75,16 @@ export const AccountInfoConnectedState = () => {
<Styled.Header>
<span>{stringGetter({ key: STRING_KEYS.ACCOUNT })}</span>
<Styled.TransferButtons>
<Styled.Button
state={{ isDisabled: !dydxAccounts }}
onClick={() => dispatch(openDialog({ type: DialogTypes.Withdraw }))}
shape={ButtonShape.Pill}
size={ButtonSize.XSmall}
>
{stringGetter({ key: STRING_KEYS.WITHDRAW })}
</Styled.Button>
{import.meta.env.MODE !== 'production' && (
<Styled.Button
state={{ isDisabled: !dydxAccounts }}
onClick={() => dispatch(openDialog({ type: DialogTypes.Withdraw }))}
shape={ButtonShape.Pill}
size={ButtonSize.XSmall}
>
{stringGetter({ key: STRING_KEYS.WITHDRAW })}
</Styled.Button>
)}
<Styled.Button
state={{ isDisabled: !dydxAccounts }}
onClick={() => dispatch(openDialog({ type: DialogTypes.Deposit }))}
+6 -3
View File
@@ -32,9 +32,12 @@ export const DepositDialog = ({ setIsOpen }: ElementProps) => {
>
<Styled.Content>
{showTestDeposit ? <TestnetDepositForm onDeposit={closeDialog} /> : <DepositForm />}
<Styled.TextToggle onClick={() => setShowTestDeposit(!showTestDeposit)}>
{showTestDeposit ? 'Show deposit form (Under Construction)' : 'Show test faucet'}
</Styled.TextToggle>
{/* TODO TRCL-1693 - uncomment when deposit form is ready */}
{import.meta.env.MODE !== 'production' && (
<Styled.TextToggle onClick={() => setShowTestDeposit(!showTestDeposit)}>
{showTestDeposit ? 'Show deposit form (Under Construction)' : 'Show test faucet'}
</Styled.TextToggle>
)}
</Styled.Content>
</Dialog>
);
+21 -2
View File
@@ -5,6 +5,8 @@ import { shallowEqual, useDispatch, useSelector } from 'react-redux';
import { AbacusApiStatus } from '@/constants/abacus';
import { DialogTypes } from '@/constants/dialogs';
import { STRING_KEYS } from '@/constants/localization';
import { ENVIRONMENT_CONFIG_MAP } from '@/constants/networks';
import { UNICODE } from '@/constants/unicode';
import { useApiState, useStringGetter } from '@/hooks';
import { layoutMixins } from '@/styles/layoutMixins';
@@ -30,8 +32,16 @@ export const ExchangeOfflineDialog = ({ preventClose, setIsOpen }: ElementProps)
const selectedNetwork = useSelector(getSelectedNetwork);
const activeDialog = useSelector(getActiveDialog, shallowEqual);
const showOfflineMessage =
import.meta.env.MODE === 'production' &&
ENVIRONMENT_CONFIG_MAP[selectedNetwork].dydxChainId === 'dydx-testnet-4';
useEffect(() => {
if (activeDialog?.type === DialogTypes.ExchangeOffline && status === AbacusApiStatus.NORMAL) {
if (
activeDialog?.type === DialogTypes.ExchangeOffline &&
status === AbacusApiStatus.NORMAL &&
!showOfflineMessage
) {
dispatch(closeDialog());
}
}, [status, selectedNetwork]);
@@ -44,7 +54,16 @@ export const ExchangeOfflineDialog = ({ preventClose, setIsOpen }: ElementProps)
title={stringGetter({ key: STRING_KEYS.UNAVAILABLE })}
>
<Styled.Content>
<p>{statusErrorMessage}</p>
{showOfflineMessage ? (
<>
<p>Testnet is currently offline. Please check back!</p>
<Styled.Link href="https://v4-teacher.vercel.app/testnets/schedule">
{stringGetter({ key: STRING_KEYS.LEARN_MORE })} {UNICODE.ARROW_RIGHT}
</Styled.Link>
</>
) : (
<p>{statusErrorMessage}</p>
)}
{import.meta.env.MODE !== 'production' && <NetworkSelectMenu />}
</Styled.Content>
</Dialog>
+4 -11
View File
@@ -37,7 +37,7 @@ export const OnboardingDialog = ({ setIsOpen }: ElementProps) => {
const stringGetter = useStringGetter();
const { isMobile } = useBreakpoints();
const { disconnect, walletType } = useAccounts();
const { walletType } = useAccounts();
const currentOnboardingStep = useSelector(calculateOnboardingStep);
@@ -45,17 +45,10 @@ export const OnboardingDialog = ({ setIsOpen }: ElementProps) => {
if (!currentOnboardingStep) setIsOpen?.(false);
}, [currentOnboardingStep]);
const setIsOpenFromDialog = (open: boolean) => {
if (!open && currentOnboardingStep === OnboardingSteps.AcknowledgeTerms) {
disconnect();
}
setIsOpen?.(open);
}
return (
<Styled.Dialog
isOpen={Boolean(currentOnboardingStep)}
setIsOpen={setIsOpenFromDialog}
setIsOpen={setIsOpen}
{...(currentOnboardingStep &&
{
[OnboardingSteps.ChooseWallet]: {
@@ -94,10 +87,10 @@ export const OnboardingDialog = ({ setIsOpen }: ElementProps) => {
title: stringGetter({ key: STRING_KEYS.ACKNOWLEDGE_TERMS }),
children: (
<Styled.Content>
<AcknowledgeTerms onClose={() => setIsOpenFromDialog?.(false)} />
<AcknowledgeTerms />
</Styled.Content>
),
width: '30rem',
width: '20rem',
},
[OnboardingSteps.DepositFunds]: {
title: stringGetter({ key: STRING_KEYS.DEPOSIT }),
@@ -2,21 +2,17 @@ import styled, { type AnyStyledComponent } from 'styled-components';
import { useAccounts, useStringGetter } from '@/hooks';
import { AppRoute } from '@/constants/routes';
import { STRING_KEYS } from '@/constants/localization';
import { ButtonAction } from '@/constants/buttons';
import { layoutMixins } from '@/styles/layoutMixins';
import { Button } from '@/components/Button';
import { Link } from '@/components/Link';
type ElementProps = {
onClose?: () => void;
onContinue?: () => void;
};
export const AcknowledgeTerms = ({ onClose, onContinue }: ElementProps) => {
export const AcknowledgeTerms = ({ onContinue }: ElementProps) => {
const stringGetter = useStringGetter();
const { saveHasAcknowledgedTerms } = useAccounts();
@@ -28,40 +24,26 @@ export const AcknowledgeTerms = ({ onClose, onContinue }: ElementProps) => {
return (
<>
<p>
<span>
{stringGetter({
key: STRING_KEYS.TOS_TITLE,
key: STRING_KEYS.LEGAL_UPDATES_DESCRIPTION,
params: {
TERMS_LINK: (
<Styled.Link href={`/#${AppRoute.Terms}`}>
TOU: (
<Styled.Link href="https://dydx.exchange/v4-terms">
{stringGetter({ key: STRING_KEYS.TERMS_OF_USE })}
</Styled.Link>
),
PRIVACY_POLICY_LINK: (
<Styled.Link href={`/#${AppRoute.Privacy}`}>
PRIVACY_POLICY: (
<Styled.Link href="https://dydx.exchange/privacy">
{stringGetter({ key: STRING_KEYS.PRIVACY_POLICY })}
</Styled.Link>
),
},
})}
</p>
<Styled.TOS>
<ul>
<li>{stringGetter({ key: STRING_KEYS.TOS_LINE1 })}</li>
<li>{stringGetter({ key: STRING_KEYS.TOS_LINE2 })}</li>
<li>{stringGetter({ key: STRING_KEYS.TOS_LINE3 })}</li>
<li>{stringGetter({ key: STRING_KEYS.TOS_LINE4 })}</li>
<li>{stringGetter({ key: STRING_KEYS.TOS_LINE5 })}</li>
</ul>
</Styled.TOS>
<Styled.Row>
<Styled.Button onClick={onClose} action={ButtonAction.Base}>
{stringGetter({ key: STRING_KEYS.CLOSE })}
</Styled.Button>
<Styled.Button onClick={onAcknowledgement} action={ButtonAction.Primary}>
{stringGetter({ key: STRING_KEYS.I_AGREE })}
</Styled.Button>
</Styled.Row>
</span>
<Button onClick={onAcknowledgement} action={ButtonAction.Primary}>
{stringGetter({ key: STRING_KEYS.I_AGREE })}
</Button>
</>
);
};
@@ -76,23 +58,3 @@ Styled.Link = styled(Link)`
color: var(--color-accent);
}
`;
Styled.TOS = styled.section`
background-color: var(--color-layer-4);
padding: 1rem 1rem 1rem 2rem;
border-radius: 0.875rem;
> ul {
${layoutMixins.column};
gap: 1rem;
}
`;
Styled.Row = styled.div`
${layoutMixins.row};
gap: 1rem;
`;
Styled.Button = styled(Button)`
flex-grow: 1;
`;
@@ -264,6 +264,7 @@ const Styled: Record<string, AnyStyledComponent> = {};
Styled.StatusCardsContainer = styled.div`
display: grid;
margin-top: 1rem;
gap: 1rem;
`;
+5 -7
View File
@@ -6,7 +6,7 @@ import { DydxChainAsset } from '@/constants/wallets';
import { formMixins } from '@/styles/formMixins';
import { layoutMixins } from '@/styles/layoutMixins';
import { useAccounts, useTokenConfigs, useStringGetter } from '@/hooks';
import { useAccounts, useStringGetter } from '@/hooks';
import { AssetIcon } from '@/components/AssetIcon';
import { CopyButton } from '@/components/CopyButton';
@@ -24,10 +24,9 @@ type ElementProps = {
setIsOpen: (open: boolean) => void;
};
export const ReceiveDialog = ({ selectedAsset = DydxChainAsset.CHAINTOKEN, setIsOpen }: ElementProps) => {
export const ReceiveDialog = ({ selectedAsset = DydxChainAsset.DYDX, setIsOpen }: ElementProps) => {
const stringGetter = useStringGetter();
const { dydxAddress } = useAccounts();
const { chainTokenLabel, usdcLabel } = useTokenConfigs();
const [asset, setAsset] = useState(selectedAsset);
@@ -36,17 +35,16 @@ export const ReceiveDialog = ({ selectedAsset = DydxChainAsset.CHAINTOKEN, setIs
value: DydxChainAsset.USDC,
label: (
<Styled.InlineRow>
<AssetIcon symbol="USDC" /> {usdcLabel}
<AssetIcon symbol="USDC" /> USDC
</Styled.InlineRow>
),
},
{
value: DydxChainAsset.CHAINTOKEN,
value: DydxChainAsset.DYDX,
label: (
<Styled.InlineRow>
{/* TODO: conditionally display the native token assetIcon */}
{/* <AssetIcon symbol="DYDX" /> */}
{chainTokenLabel}
Dv4TNT
</Styled.InlineRow>
),
},
+12 -10
View File
@@ -11,7 +11,11 @@ import { ButtonShape, ButtonSize } from '@/constants/buttons';
import { STRING_KEYS } from '@/constants/localization';
import { ENVIRONMENT_CONFIG_MAP } from '@/constants/networks';
import { NumberSign } from '@/constants/numbers';
import { DydxChainAsset } from '@/constants/wallets';
import {
DYDX_CHAIN_ASSET_COIN_DENOM,
DYDX_CHAIN_ASSET_TAGS,
DydxChainAsset,
} from '@/constants/wallets';
import {
useAccountBalance,
@@ -21,7 +25,6 @@ import {
useSelectedNetwork,
useStringGetter,
useSubaccount,
useTokenConfigs,
} from '@/hooks';
import { formMixins } from '@/styles/formMixins';
@@ -54,7 +57,7 @@ type TransferFormProps = {
};
export const TransferForm = ({
selectedAsset = DydxChainAsset.CHAINTOKEN,
selectedAsset = DydxChainAsset.DYDX,
onDone,
className,
}: TransferFormProps) => {
@@ -69,7 +72,6 @@ export const TransferForm = ({
const { transfer } = useSubaccount();
const { nativeTokenBalance, usdcBalance } = useAccountBalance();
const { selectedNetwork } = useSelectedNetwork();
const { tokensConfigs, usdcLabel, chainTokenLabel } = useTokenConfigs();
// User Input
const [asset, setAsset] = useState<DydxChainAsset>(selectedAsset);
@@ -136,7 +138,7 @@ export const TransferForm = ({
try {
// Subtract fees from amount if sending native tokens
const amountToTransfer = (
asset === DydxChainAsset.CHAINTOKEN ? amountBN.minus(fee) : amountBN
asset === DydxChainAsset.DYDX ? amountBN.minus(fee) : amountBN
).toNumber();
const screenResults = await screenAddresses({
@@ -159,7 +161,7 @@ export const TransferForm = ({
const txResponse = await transfer(
amountToTransfer,
recipientAddress as string,
tokensConfigs[asset].denom,
DYDX_CHAIN_ASSET_COIN_DENOM[asset]
);
if (txResponse?.code === 0) {
@@ -218,16 +220,16 @@ export const TransferForm = ({
value: DydxChainAsset.USDC,
label: (
<Styled.InlineRow>
<AssetIcon symbol="USDC" /> {usdcLabel}
<AssetIcon symbol="USDC" /> {DYDX_CHAIN_ASSET_TAGS[DydxChainAsset.USDC]}
</Styled.InlineRow>
),
},
{
value: DydxChainAsset.CHAINTOKEN,
value: DydxChainAsset.DYDX,
label: (
<Styled.InlineRow>
{/* <AssetIcon symbol="DYDX" /> */}
{chainTokenLabel}
{DYDX_CHAIN_ASSET_TAGS[DydxChainAsset.DYDX]}
</Styled.InlineRow>
),
},
@@ -249,7 +251,7 @@ export const TransferForm = ({
key: 'amount',
label: (
<span>
{stringGetter({ key: STRING_KEYS.AVAILABLE })} <Tag>{tokensConfigs[asset].name}</Tag>
{stringGetter({ key: STRING_KEYS.AVAILABLE })} <Tag>{DYDX_CHAIN_ASSET_TAGS[asset]}</Tag>
</span>
),
value: (
@@ -3,9 +3,9 @@ import { shallowEqual, useSelector } from 'react-redux';
import { ButtonAction, ButtonSize, ButtonType } from '@/constants/buttons';
import { STRING_KEYS } from '@/constants/localization';
import { NumberSign } from '@/constants/numbers';
import { DydxChainAsset } from '@/constants/wallets';
import { DYDX_CHAIN_ASSET_TAGS, DydxChainAsset } from '@/constants/wallets';
import { useAccountBalance, useTokenConfigs, useStringGetter } from '@/hooks';
import { useAccountBalance, useStringGetter } from '@/hooks';
import { Button } from '@/components/Button';
import { DiffOutput } from '@/components/DiffOutput';
@@ -37,7 +37,6 @@ export const TransferButtonAndReceipt = ({
const stringGetter = useStringGetter();
const canAccountTrade = useSelector(calculateCanAccountTrade, shallowEqual);
const { size } = useSelector(getTransferInputs, shallowEqual) || {};
const { tokensConfigs } = useTokenConfigs();
const { equity: equityInfo, leverage: leverageInfo } =
useSelector(getSubaccount, shallowEqual) || {};
@@ -61,7 +60,7 @@ export const TransferButtonAndReceipt = ({
key: 'fees',
label: (
<span>
{stringGetter({ key: STRING_KEYS.FEES })} <Tag>{tokensConfigs[selectedAsset].name}</Tag>
{stringGetter({ key: STRING_KEYS.FEES })} <Tag>{DYDX_CHAIN_ASSET_TAGS[selectedAsset]}</Tag>
</span>
),
value: <Output type={OutputType.Asset} value={fees} />,
@@ -70,7 +69,7 @@ export const TransferButtonAndReceipt = ({
key: 'balance',
label: (
<span>
{stringGetter({ key: STRING_KEYS.BALANCE })} <Tag>{tokensConfigs[selectedAsset].name}</Tag>
{stringGetter({ key: STRING_KEYS.BALANCE })} <Tag>{DYDX_CHAIN_ASSET_TAGS[selectedAsset]}</Tag>
</span>
),
value: (
+4 -17
View File
@@ -9,13 +9,7 @@ import { DialogTypes } from '@/constants/dialogs';
import { STRING_KEYS, TOOLTIP_STRING_KEYS } from '@/constants/localization';
import { DydxChainAsset, wallets } from '@/constants/wallets';
import {
useAccounts,
useBreakpoints,
useTokenConfigs,
useStringGetter,
useAccountBalance,
} from '@/hooks';
import { useAccounts, useBreakpoints, useStringGetter, useAccountBalance } from '@/hooks';
import { OnboardingTriggerButton } from '@/views/dialogs/OnboardingTriggerButton';
@@ -45,7 +39,6 @@ export const AccountMenu = () => {
const onboardingState = useSelector(getOnboardingState);
const { freeCollateral } = useSelector(getSubaccount, shallowEqual) || {};
const { nativeTokenBalance } = useAccountBalance();
const { usdcLabel, chainTokenLabel } = useTokenConfigs();
const { evmAddress, walletType, dydxAddress, hdKey } = useAccounts();
@@ -114,23 +107,17 @@ export const AccountMenu = () => {
<div>
<div>
<Styled.label>
{stringGetter({
key: STRING_KEYS.ASSET_BALANCE,
params: { ASSET: chainTokenLabel },
})}
{stringGetter({ key: STRING_KEYS.ASSET_BALANCE, params: { ASSET: 'Dv4TNT' } })}
{/* <AssetIcon symbol="DYDX" /> */}
</Styled.label>
<Styled.BalanceOutput type={OutputType.Asset} value={nativeTokenBalance} />
</div>
<AssetActions asset={DydxChainAsset.CHAINTOKEN} dispatch={dispatch} />
<AssetActions asset={DydxChainAsset.DYDX} dispatch={dispatch} />
</div>
<div>
<div>
<Styled.label>
{stringGetter({
key: STRING_KEYS.ASSET_BALANCE,
params: { ASSET: usdcLabel },
})}
{stringGetter({ key: STRING_KEYS.ASSET_BALANCE, params: { ASSET: 'USDC' } })}
<AssetIcon symbol="USDC" />
</Styled.label>
<Styled.BalanceOutput