Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a21558ad88 |
+2
-2
@@ -39,9 +39,9 @@
|
||||
"@cosmjs/proto-signing": "^0.31.0",
|
||||
"@cosmjs/stargate": "^0.31.0",
|
||||
"@cosmjs/tendermint-rpc": "^0.31.0",
|
||||
"@dydxprotocol/v4-abacus": "^1.0.19",
|
||||
"@dydxprotocol/v4-abacus": "^1.0.10",
|
||||
"@dydxprotocol/v4-client-js": "^1.0.0",
|
||||
"@dydxprotocol/v4-localization": "^1.0.5",
|
||||
"@dydxprotocol/v4-localization": "^1.0.0",
|
||||
"@ethersproject/providers": "^5.7.2",
|
||||
"@js-joda/core": "^5.5.3",
|
||||
"@radix-ui/react-collapsible": "^1.0.3",
|
||||
|
||||
Generated
+8
-8
@@ -27,14 +27,14 @@ dependencies:
|
||||
specifier: ^0.31.0
|
||||
version: 0.31.0
|
||||
'@dydxprotocol/v4-abacus':
|
||||
specifier: ^1.0.19
|
||||
version: 1.0.19
|
||||
specifier: ^1.0.10
|
||||
version: 1.0.10
|
||||
'@dydxprotocol/v4-client-js':
|
||||
specifier: ^1.0.0
|
||||
version: 1.0.0
|
||||
'@dydxprotocol/v4-localization':
|
||||
specifier: ^1.0.5
|
||||
version: 1.0.5
|
||||
specifier: ^1.0.0
|
||||
version: 1.0.0
|
||||
'@ethersproject/providers':
|
||||
specifier: ^5.7.2
|
||||
version: 5.7.2
|
||||
@@ -979,8 +979,8 @@ packages:
|
||||
resolution: {integrity: sha512-RpfLEtTlyIxeNPGKcokS+p3BZII/Q3bYxryFRglh5H3A3T8q9fsLYm72VYAMEOOIBLEa8o93kFLiBDUWKrwXZA==}
|
||||
dev: true
|
||||
|
||||
/@dydxprotocol/v4-abacus@1.0.19:
|
||||
resolution: {integrity: sha512-XhvSHGr503gNwHWEiOYP7M2uYeLu+Qm4szpE5w5H6hWFCanSGz6zAsTbPuyPLtt7IE1gj5z8mlL9J3tw2AZROg==}
|
||||
/@dydxprotocol/v4-abacus@1.0.10:
|
||||
resolution: {integrity: sha512-SdxI/JcyxM1ydtR9ImWujeurea3gbxj37qYnw1wz829BQiZ05uNEtll3xJCI0MjpG+01ARsxVys7SHbpjSxwOg==}
|
||||
dev: false
|
||||
|
||||
/@dydxprotocol/v4-client-js@1.0.0:
|
||||
@@ -1011,8 +1011,8 @@ packages:
|
||||
- utf-8-validate
|
||||
dev: false
|
||||
|
||||
/@dydxprotocol/v4-localization@1.0.5:
|
||||
resolution: {integrity: sha512-zZm3GFp/ORz9YjigQFVBlcWmaxYY+XEdIw8AWN5nEbsuiA2Jay+/OA7lO9+nV1J1p1T+TgLo9iczIHJsAo3IsA==}
|
||||
/@dydxprotocol/v4-localization@1.0.0:
|
||||
resolution: {integrity: sha512-U7QjOlzpfSAVEchkNDB3xYRx7okzdeYi83XsnHwI+EHa2quFm/2Y2dhrBkT5fqpZmhcwxb/vG8AZmFSToOf9hA==}
|
||||
dev: false
|
||||
|
||||
/@dydxprotocol/v4-proto@0.4.1:
|
||||
|
||||
+2
-73
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"apps": {
|
||||
"ios": {
|
||||
"iOS": {
|
||||
"scheme": "dydxv4"
|
||||
}
|
||||
},
|
||||
@@ -400,76 +400,6 @@
|
||||
"signTypedDataDomainName": "dYdX Chain"
|
||||
}
|
||||
},
|
||||
"dydxprotocol-staging-forced-update": {
|
||||
"name": "v4 Staging Forced Update",
|
||||
"ethereumChainId": "5",
|
||||
"dydxChainId": "dydxprotocol-testnet",
|
||||
"chainName": "dYdX Chain",
|
||||
"chainLogo": "dydx-chain.png",
|
||||
"isMainNet": false,
|
||||
"tokens": {
|
||||
"chain": {
|
||||
"name": "Dv4TNT",
|
||||
"denom": "adv4tnt",
|
||||
"decimals": 18,
|
||||
"image": "/currencies/dydx.png"
|
||||
},
|
||||
"usdc": {
|
||||
"name": "USDC",
|
||||
"denom": "ibc/8E27BA2D5493AF5636760E354E46004562C46AB7EC0CC4C1CA14E9E20E2545B5",
|
||||
"gasDenom": "uusdc",
|
||||
"decimals": 6,
|
||||
"image": "/currencies/usdc.png"
|
||||
}
|
||||
},
|
||||
"endpoints": {
|
||||
"indexers": [
|
||||
{
|
||||
"api": "https://indexer.v4staging.dydx.exchange",
|
||||
"socket": "wss://indexer.v4staging.dydx.exchange"
|
||||
}
|
||||
],
|
||||
"faucet": "https://faucet.v4staging.dydx.exchange",
|
||||
"validators": [
|
||||
"https://validator.v4staging.dydx.exchange"
|
||||
],
|
||||
"0xsquid": "https://testnet.api.squidrouter.com"
|
||||
},
|
||||
"links": {
|
||||
"tos": "https://dydx.exchange/v4-terms",
|
||||
"privacy": "https://dydx.exchange/privacy",
|
||||
"mintscan": "https://testnet.mintscan.io/dydx-testnet/txs/{tx_hash}",
|
||||
"documentation": "https://v4-teacher.vercel.app/",
|
||||
"community": "https://discord.com/invite/dydx",
|
||||
"feedback": "https://docs.google.com/forms/d/e/1FAIpQLSezLsWCKvAYDEb7L-2O4wOON1T56xxro9A2Azvl6IxXHP_15Q/viewform",
|
||||
"blogs": "https://www.dydx.foundation/blog"
|
||||
},
|
||||
"wallets": {
|
||||
"walletconnect": {
|
||||
"client": {
|
||||
"name": "dYdX v4",
|
||||
"description": "dYdX v4 App",
|
||||
"iconUrl": "/logos/dydx-x.png"
|
||||
},
|
||||
"v2": {
|
||||
"projectId": "47559b2ec96c09aed9ff2cb54a31ab0e"
|
||||
}
|
||||
},
|
||||
"walletSegue": {
|
||||
"callbackUrl": "/walletsegue"
|
||||
},
|
||||
"images": "/wallets/",
|
||||
"signTypedDataAction": "dYdX Chain Onboarding",
|
||||
"signTypedDataDomainName": "dYdX Chain"
|
||||
},
|
||||
"apps": {
|
||||
"ios": {
|
||||
"minimalVersion": "1.0",
|
||||
"build":40000,
|
||||
"url": "https://apps.apple.com/app/dydx/id1564787350"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dydxprotocol-staging-west": {
|
||||
"name": "v4 Staging West",
|
||||
"ethereumChainId": "5",
|
||||
@@ -963,7 +893,6 @@
|
||||
"privacy": "https://dydx.exchange/privacy",
|
||||
"statusPage": "https://status.v4testnet.dydx.exchange/",
|
||||
"mintscan": "https://testnet.mintscan.io/dydx-testnet/txs/{tx_hash}",
|
||||
"mintscanBase": "https://testnet.mintscan.io/dydx-testnet",
|
||||
"documentation": "https://docs.dydx.exchange/",
|
||||
"community": "https://discord.com/invite/dydx",
|
||||
"feedback": "https://docs.google.com/forms/d/e/1FAIpQLSezLsWCKvAYDEb7L-2O4wOON1T56xxro9A2Azvl6IxXHP_15Q/viewform",
|
||||
@@ -1104,7 +1033,7 @@
|
||||
"tos": "[HTTP link to TOS]",
|
||||
"privacy": "[HTTP link to Privacy Policy]",
|
||||
"mintscan": "[HTTP link to Mintscan, with {tx_hash} placeholder]",
|
||||
"mintscanBase": "[HTTP link to TOS mintscan base url]",
|
||||
"mintscanBase": "[HTTP link to TOS mintsacn base url]",
|
||||
"feedback": "[HTTP link to feedback form, can be null]",
|
||||
"blogs": "[HTTP link to blogs, can be null]",
|
||||
"foundation": "[HTTP link to foundation, can be null]",
|
||||
|
||||
@@ -1,18 +1,12 @@
|
||||
import environments from '../../public/configs/env.json';
|
||||
|
||||
const CURRENT_MODE = ({
|
||||
production: 'MAINNET',
|
||||
testnet: 'TESTNET',
|
||||
staging: 'DEV',
|
||||
development: 'DEV',
|
||||
}[import.meta.env.MODE] ?? 'MAINNET') as 'MAINNET' | 'TESTNET' | 'DEV';
|
||||
// TODO: Update for Mainnet deployment
|
||||
export const AVAILABLE_ENVIRONMENTS =
|
||||
import.meta.env.MODE === 'production'
|
||||
? environments.deployments.TESTNET
|
||||
: environments.deployments.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 CURRENT_ABACUS_DEPLOYMENT = import.meta.env.MODE === 'production' ? 'TESTNET' : 'DEV';
|
||||
export const ENVIRONMENT_CONFIG_MAP = environments.environments;
|
||||
export type DydxNetwork = keyof typeof ENVIRONMENT_CONFIG_MAP;
|
||||
export const DEFAULT_APP_ENVIRONMENT = AVAILABLE_ENVIRONMENTS.default as DydxNetwork;
|
||||
|
||||
@@ -42,7 +42,6 @@ const useAccountsContext = () => {
|
||||
selectedWalletError,
|
||||
evmAddress,
|
||||
signerWagmi,
|
||||
publicClientWagmi,
|
||||
dydxAddress: connectedDydxAddress,
|
||||
signerGraz,
|
||||
} = useWalletConnection();
|
||||
@@ -297,7 +296,6 @@ const useAccountsContext = () => {
|
||||
// Wallet connection (EVM)
|
||||
evmAddress,
|
||||
signerWagmi,
|
||||
publicClientWagmi,
|
||||
|
||||
// Wallet connection (Cosmos)
|
||||
signerGraz,
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { isDev } from '@/constants/networks';
|
||||
import { WalletType } from '@/constants/wallets';
|
||||
|
||||
import { isTruthy } from '@/lib/isTruthy';
|
||||
@@ -7,7 +6,7 @@ export const useDisplayedWallets = () => {
|
||||
return [
|
||||
WalletType.MetaMask,
|
||||
|
||||
isDev && WalletType.Keplr,
|
||||
import.meta.env.MODE !== 'production' && WalletType.Keplr,
|
||||
|
||||
WalletType.WalletConnect2,
|
||||
|
||||
|
||||
+60
-91
@@ -48,7 +48,7 @@ export const useSubaccount = () => useContext(SubaccountContext);
|
||||
|
||||
export const useSubaccountContext = ({ localDydxWallet }: { localDydxWallet?: LocalWallet }) => {
|
||||
const dispatch = useDispatch();
|
||||
const { usdcDenom, usdcDecimals } = useTokenConfigs();
|
||||
const { usdcDenom } = useTokenConfigs();
|
||||
const { compositeClient, faucetClient } = useDydxClient();
|
||||
|
||||
const { getFaucetFunds } = useMemo(
|
||||
@@ -79,34 +79,16 @@ export const useSubaccountContext = ({ localDydxWallet }: { localDydxWallet?: Lo
|
||||
subaccountClient: SubaccountClient;
|
||||
assetId?: number;
|
||||
amount: number;
|
||||
}) => {
|
||||
try {
|
||||
return await compositeClient?.depositToSubaccount(
|
||||
subaccountClient,
|
||||
amount.toFixed(usdcDecimals)
|
||||
);
|
||||
} catch (error) {
|
||||
log('useSubaccount/depositToSubaccount', error);
|
||||
throw error;
|
||||
}
|
||||
},
|
||||
}) => await compositeClient?.depositToSubaccount(subaccountClient, amount.toString()),
|
||||
|
||||
withdrawFromSubaccount: async ({
|
||||
subaccountClient,
|
||||
amount,
|
||||
}: {
|
||||
subaccountClient: SubaccountClient;
|
||||
amount: number;
|
||||
}) => {
|
||||
try {
|
||||
return await compositeClient?.withdrawFromSubaccount(
|
||||
subaccountClient,
|
||||
amount.toFixed(usdcDecimals)
|
||||
);
|
||||
} catch (error) {
|
||||
log('useSubaccount/withdrawFromSubaccount', error);
|
||||
throw error;
|
||||
}
|
||||
},
|
||||
}) => await compositeClient?.withdrawFromSubaccount(subaccountClient, amount.toString()),
|
||||
|
||||
transferFromSubaccountToAddress: async ({
|
||||
subaccountClient,
|
||||
assetId = 0,
|
||||
@@ -117,33 +99,27 @@ export const useSubaccountContext = ({ localDydxWallet }: { localDydxWallet?: Lo
|
||||
assetId?: number;
|
||||
amount: number;
|
||||
recipient: string;
|
||||
}) => {
|
||||
try {
|
||||
return await compositeClient?.validatorClient.post.send(
|
||||
subaccountClient?.wallet,
|
||||
() =>
|
||||
new Promise((resolve) => {
|
||||
const msg =
|
||||
compositeClient?.validatorClient.post.composer.composeMsgWithdrawFromSubaccount(
|
||||
subaccountClient.address,
|
||||
subaccountClient.subaccountNumber,
|
||||
assetId,
|
||||
Long.fromNumber(amount * QUANTUM_MULTIPLIER),
|
||||
recipient
|
||||
);
|
||||
}) =>
|
||||
await compositeClient?.validatorClient.post.send(
|
||||
subaccountClient?.wallet,
|
||||
() =>
|
||||
new Promise((resolve) => {
|
||||
const msg =
|
||||
compositeClient?.validatorClient.post.composer.composeMsgWithdrawFromSubaccount(
|
||||
subaccountClient.address,
|
||||
subaccountClient.subaccountNumber,
|
||||
assetId,
|
||||
Long.fromNumber(amount * QUANTUM_MULTIPLIER),
|
||||
recipient
|
||||
);
|
||||
|
||||
resolve([msg]);
|
||||
}),
|
||||
false,
|
||||
undefined,
|
||||
undefined,
|
||||
Method.BroadcastTxCommit
|
||||
);
|
||||
} catch (error) {
|
||||
log('useSubaccount/transferFromSubaccountToAddress', error);
|
||||
throw error;
|
||||
}
|
||||
},
|
||||
resolve([msg]);
|
||||
}),
|
||||
false,
|
||||
undefined,
|
||||
undefined,
|
||||
Method.BroadcastTxCommit
|
||||
),
|
||||
|
||||
transferNativeToken: async ({
|
||||
subaccountClient,
|
||||
@@ -153,30 +129,24 @@ export const useSubaccountContext = ({ localDydxWallet }: { localDydxWallet?: Lo
|
||||
subaccountClient: SubaccountClient;
|
||||
amount: number;
|
||||
recipient: string;
|
||||
}) => {
|
||||
try {
|
||||
return await compositeClient?.validatorClient.post.send(
|
||||
subaccountClient.wallet,
|
||||
() =>
|
||||
new Promise((resolve) => {
|
||||
const msg = compositeClient?.sendTokenMessage(
|
||||
subaccountClient.wallet,
|
||||
amount.toString(),
|
||||
recipient
|
||||
);
|
||||
}) =>
|
||||
await compositeClient?.validatorClient.post.send(
|
||||
subaccountClient.wallet,
|
||||
() =>
|
||||
new Promise((resolve) => {
|
||||
const msg = compositeClient?.sendTokenMessage(
|
||||
subaccountClient.wallet,
|
||||
amount.toString(),
|
||||
recipient,
|
||||
);
|
||||
|
||||
resolve([msg]);
|
||||
}),
|
||||
false,
|
||||
compositeClient?.validatorClient?.post.defaultDydxGasPrice,
|
||||
undefined,
|
||||
Method.BroadcastTxCommit
|
||||
);
|
||||
} catch (error) {
|
||||
log('useSubaccount/transferNativeToken', error);
|
||||
throw error;
|
||||
}
|
||||
},
|
||||
resolve([msg]);
|
||||
}),
|
||||
false,
|
||||
compositeClient?.validatorClient?.post.defaultDydxGasPrice,
|
||||
undefined,
|
||||
Method.BroadcastTxCommit
|
||||
),
|
||||
|
||||
sendSquidWithdrawFromSubaccount: async ({
|
||||
subaccountClient,
|
||||
@@ -188,27 +158,20 @@ export const useSubaccountContext = ({ localDydxWallet }: { localDydxWallet?: Lo
|
||||
payload: string;
|
||||
}) => {
|
||||
if (!compositeClient) throw new Error('client not initialized');
|
||||
try {
|
||||
const transaction = JSON.parse(payload);
|
||||
|
||||
const msg = compositeClient.withdrawFromSubaccountMessage(
|
||||
subaccountClient,
|
||||
amount.toFixed(usdcDecimals)
|
||||
);
|
||||
const ibcMsg: EncodeObject = {
|
||||
typeUrl: transaction.msgTypeUrl,
|
||||
value: transaction.msg,
|
||||
};
|
||||
const transaction = JSON.parse(payload);
|
||||
|
||||
return await compositeClient.send(
|
||||
subaccountClient.wallet,
|
||||
() => Promise.resolve([msg, ibcMsg]),
|
||||
false
|
||||
);
|
||||
} catch (error) {
|
||||
log('useSubaccount/sendSquidWithdrawFromSubaccount', error);
|
||||
throw error;
|
||||
}
|
||||
const msg = compositeClient.withdrawFromSubaccountMessage(subaccountClient, amount.toString());
|
||||
const ibcMsg: EncodeObject = {
|
||||
typeUrl: transaction.msgTypeUrl,
|
||||
value: transaction.msg,
|
||||
};
|
||||
|
||||
return await compositeClient.send(
|
||||
subaccountClient.wallet,
|
||||
() => Promise.resolve([msg, ibcMsg]),
|
||||
false
|
||||
);
|
||||
},
|
||||
}),
|
||||
[compositeClient]
|
||||
@@ -350,6 +313,11 @@ export const useSubaccountContext = ({ localDydxWallet }: { localDydxWallet?: Lo
|
||||
placeOrderParams = abacusStateManager.placeOrder(callback);
|
||||
}
|
||||
|
||||
track(AnalyticsEvent.TradePlaceOrder, {
|
||||
...placeOrderParams,
|
||||
isClosePosition,
|
||||
} as HumanReadablePlaceOrderPayload & { isClosePosition: boolean });
|
||||
|
||||
return placeOrderParams;
|
||||
},
|
||||
[subaccountClient]
|
||||
@@ -378,6 +346,7 @@ export const useSubaccountContext = ({ localDydxWallet }: { localDydxWallet?: Lo
|
||||
}) => {
|
||||
const callback = (success: boolean, parsingError?: Nullable<ParsingError>) => {
|
||||
if (success) {
|
||||
track(AnalyticsEvent.TradeCancelOrder);
|
||||
onSuccess?.();
|
||||
} else {
|
||||
onError?.({ errorStringKey: parsingError?.stringKey });
|
||||
|
||||
@@ -19,10 +19,8 @@ export const useTokenConfigs = (): {
|
||||
},
|
||||
};
|
||||
usdcDenom: string;
|
||||
usdcDecimals: number;
|
||||
usdcLabel: string;
|
||||
chainTokenDenom: string;
|
||||
chainTokenDecimals: number;
|
||||
chainTokenLabel: string;
|
||||
} => {
|
||||
const { selectedNetwork } = useSelectedNetwork();
|
||||
@@ -31,10 +29,8 @@ export const useTokenConfigs = (): {
|
||||
return {
|
||||
tokensConfigs,
|
||||
usdcDenom: tokensConfigs[DydxChainAsset.USDC].denom,
|
||||
usdcDecimals: tokensConfigs[DydxChainAsset.USDC].decimals,
|
||||
usdcLabel: tokensConfigs[DydxChainAsset.USDC].name,
|
||||
chainTokenDenom: tokensConfigs[DydxChainAsset.CHAINTOKEN].denom,
|
||||
chainTokenDecimals: tokensConfigs[DydxChainAsset.CHAINTOKEN].decimals,
|
||||
chainTokenLabel: tokensConfigs[DydxChainAsset.CHAINTOKEN].name,
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useCallback, useEffect, useState, useMemo } from 'react';
|
||||
import { useCallback, useEffect, useState } from 'react';
|
||||
import { useSelector } from 'react-redux';
|
||||
|
||||
import { LocalStorageKey } from '@/constants/localStorage';
|
||||
@@ -90,21 +90,19 @@ export const useWalletConnection = () => {
|
||||
|
||||
const selectedNetwork = useSelector(getSelectedNetwork);
|
||||
const walletConnectConfig = ENVIRONMENT_CONFIG_MAP[selectedNetwork].wallets.walletconnect;
|
||||
const wagmiConnector = useMemo(
|
||||
() =>
|
||||
walletType && walletConnectionType
|
||||
? resolveWagmiConnector({
|
||||
|
||||
const { connectAsync: connectWagmi } =
|
||||
walletType && walletConnectionType
|
||||
? useConnectWagmi({
|
||||
connector: resolveWagmiConnector({
|
||||
walletType,
|
||||
walletConnection: {
|
||||
type: walletConnectionType,
|
||||
},
|
||||
walletConnectConfig,
|
||||
})
|
||||
: undefined,
|
||||
[walletConnectConfig, walletType, walletConnectionType]
|
||||
);
|
||||
|
||||
const { connectAsync: connectWagmi } = useConnectWagmi({ connector: wagmiConnector })
|
||||
}),
|
||||
})
|
||||
: useConnectWagmi();
|
||||
const { suggestAndConnect: connectGraz } = useConnectGraz();
|
||||
|
||||
const connectWallet = useCallback(
|
||||
|
||||
@@ -3,7 +3,7 @@ import styled, { type AnyStyledComponent, css } from 'styled-components';
|
||||
import { AbacusApiStatus } from '@/constants/abacus';
|
||||
import { ButtonSize } from '@/constants/buttons';
|
||||
import { STRING_KEYS } from '@/constants/localization';
|
||||
import { ENVIRONMENT_CONFIG_MAP, isDev } from '@/constants/networks';
|
||||
import { ENVIRONMENT_CONFIG_MAP } from '@/constants/networks';
|
||||
|
||||
import { useApiState, useSelectedNetwork, useStringGetter } from '@/hooks';
|
||||
import { ChatIcon, LinkOutIcon } from '@/icons';
|
||||
@@ -75,7 +75,7 @@ export const FooterDesktop = () => {
|
||||
)}
|
||||
</Styled.Row>
|
||||
|
||||
{isDev && (
|
||||
{import.meta.env.MODE !== 'production' && (
|
||||
<Styled.Details
|
||||
withSeparators
|
||||
items={[
|
||||
|
||||
@@ -236,5 +236,4 @@ Styled.IconButton = styled(IconButton)<{ size?: string }>`
|
||||
${headerMixins.button}
|
||||
--button-border: none;
|
||||
--button-icon-size: 1rem;
|
||||
--button-padding: 0 0.5em;
|
||||
`;
|
||||
|
||||
@@ -30,7 +30,7 @@ import {
|
||||
|
||||
import { DialogTypes } from '@/constants/dialogs';
|
||||
import { UNCOMMITTED_ORDER_TIMEOUT_MS } from '@/constants/trade';
|
||||
import { ENVIRONMENT_CONFIG_MAP, DydxNetwork, isTestnet } from '@/constants/networks';
|
||||
import { QUANTUM_MULTIPLIER } from '@/constants/numbers';
|
||||
|
||||
import { RootStore } from '@/state/_store';
|
||||
import { addUncommittedOrderClientId, removeUncommittedOrderClientId } from '@/state/account';
|
||||
@@ -198,13 +198,8 @@ class DydxChainTransactions implements AbacusDYDXChainTransactionsProtocol {
|
||||
const parsedTx = this.parseToPrimitives(tx);
|
||||
const hash = parsedTx?.hash;
|
||||
|
||||
if (isTestnet) {
|
||||
console.log(
|
||||
`${
|
||||
ENVIRONMENT_CONFIG_MAP[this.compositeClient.network.getString() as DydxNetwork]?.links
|
||||
?.mintscanBase
|
||||
}/txs/${hash}`
|
||||
);
|
||||
if (import.meta.env.MODE === 'production') {
|
||||
console.log(`https://testnet.mintscan.io/dydx-testnet/txs/${hash}`);
|
||||
} else console.log(`txHash: ${hash}`);
|
||||
|
||||
return JSON.stringify(parsedTx);
|
||||
@@ -234,7 +229,7 @@ class DydxChainTransactions implements AbacusDYDXChainTransactionsProtocol {
|
||||
orderFlags,
|
||||
clobPairId,
|
||||
goodTilBlock || undefined,
|
||||
goodTilBlockTime || undefined
|
||||
goodTilBlockTime || undefined,
|
||||
);
|
||||
|
||||
const parsedTx = this.parseToPrimitives(tx);
|
||||
@@ -300,11 +295,15 @@ class DydxChainTransactions implements AbacusDYDXChainTransactionsProtocol {
|
||||
if (!this.localWallet) {
|
||||
throw new Error('Missing compositeClient or localWallet');
|
||||
}
|
||||
const msg = compositeClient?.sendTokenMessage(this.localWallet, amount, recipient);
|
||||
const msg = compositeClient?.sendTokenMessage(
|
||||
this.localWallet,
|
||||
amount,
|
||||
recipient,
|
||||
);
|
||||
|
||||
resolve([msg]);
|
||||
}),
|
||||
this.compositeClient?.validatorClient?.post.defaultDydxGasPrice
|
||||
this.compositeClient?.validatorClient?.post.defaultDydxGasPrice,
|
||||
);
|
||||
|
||||
const parsedTx = this.parseToPrimitives(tx);
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
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 {
|
||||
readTextFile(location: FileLocation, path: string): Nullable<string> {
|
||||
return null;
|
||||
|
||||
@@ -41,7 +41,7 @@ import AbacusStateNotifier from './stateNotification';
|
||||
import AbacusLocalizer from './localizer';
|
||||
import AbacusFormatter from './formatter';
|
||||
import AbacusThreading from './threading';
|
||||
import AbacusFileSystem from './filesystem';
|
||||
import AbacusFileSystem, { ENDPOINTS_PATH } from './filesystem';
|
||||
import { LocaleSeparators } from '../numbers';
|
||||
class AbacusStateManager {
|
||||
private store: RootStore | undefined;
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import type { AbacusWebsocketProtocol } from '@/constants/abacus';
|
||||
import type { TradingViewBar } from '@/constants/candles';
|
||||
import { isDev } from '@/constants/networks';
|
||||
|
||||
import {
|
||||
PING_INTERVAL_MS,
|
||||
@@ -162,13 +161,13 @@ class AbacusWebsocket implements Omit<AbacusWebsocketProtocol, '__doNotUseOrImpl
|
||||
|
||||
this.socket.onclose = (e) => {
|
||||
this.connectedCallback?.(false);
|
||||
if (!isDev) return;
|
||||
if (import.meta.env.MODE === 'production') return;
|
||||
console.warn('AbacusStateManager > WS > close > ', e);
|
||||
};
|
||||
|
||||
this.socket.onerror = (e) => {
|
||||
this.connectedCallback?.(false);
|
||||
if (!isDev) return;
|
||||
if (import.meta.env.MODE === 'production') return;
|
||||
console.error('AbacusStateManager > WS > error > ', e);
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
import { isDev } from "@/constants/networks";
|
||||
|
||||
export const log = (location: string, error: Error, metadata?: any) => {
|
||||
if (isDev) {
|
||||
if (import.meta.env.MODE !== 'production') {
|
||||
console.warn('telemetry/log:', { location, error, metadata });
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@ import type { PayloadAction } from '@reduxjs/toolkit';
|
||||
|
||||
import { AbacusApiStatus } from '@/constants/abacus';
|
||||
import { DialogTypes } from '@/constants/dialogs';
|
||||
import { isDev } from '@/constants/networks';
|
||||
|
||||
import { setApiState, setSelectedNetwork } from '@/state/app';
|
||||
import { resetPerpetualsState } from '@/state/perpetuals';
|
||||
@@ -31,7 +30,7 @@ export default (store: any) => (next: any) => async (action: PayloadAction<any>)
|
||||
store.dispatch(
|
||||
openDialog({
|
||||
type: DialogTypes.ExchangeOffline,
|
||||
dialogProps: { preventClose: !isDev },
|
||||
dialogProps: { preventClose: import.meta.env.MODE === 'production' },
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
@@ -48,15 +48,6 @@ export const getTradeInputErrors = (state: RootState) => {
|
||||
return currentInput === 'trade' ? getInputErrors(state) : [];
|
||||
};
|
||||
|
||||
/**
|
||||
* @param state
|
||||
* @returns input errors for Close position
|
||||
*/
|
||||
export const getClosePositionInputErrors = (state: RootState) => {
|
||||
const currentInput = state.inputs.current;
|
||||
return currentInput === 'closePosition' ? getInputErrors(state) : [];
|
||||
};
|
||||
|
||||
/**
|
||||
* @param state
|
||||
* @returns input errors for Transfer
|
||||
|
||||
@@ -34,7 +34,7 @@ export const TransferStatusToast = ({
|
||||
}: ElementProps) => {
|
||||
const stringGetter = useStringGetter();
|
||||
const [open, setOpen] = useState<boolean>(false);
|
||||
const [secondsLeft, setSecondsLeft] = useState<number>(0);
|
||||
const [secondsLeft, setSecondsLeft] = useState<number | undefined>();
|
||||
|
||||
// @ts-ignore status.errors is not in the type definition but can be returned
|
||||
const error = status?.errors?.length ? status?.errors[0] : status?.error;
|
||||
@@ -49,23 +49,14 @@ export const TransferStatusToast = ({
|
||||
|
||||
if (!status) return <LoadingDots size={3} />;
|
||||
|
||||
const inProgressStatusString =
|
||||
type === 'deposit'
|
||||
? secondsLeft > 0
|
||||
? STRING_KEYS.DEPOSIT_STATUS
|
||||
: STRING_KEYS.DEPOSIT_STATUS_SHORTLY
|
||||
: secondsLeft > 0
|
||||
? STRING_KEYS.WITHDRAW_STATUS
|
||||
: STRING_KEYS.WITHDRAW_STATUS_SHORTLY;
|
||||
|
||||
const statusString =
|
||||
type === 'deposit'
|
||||
? status?.squidTransactionStatus === 'success'
|
||||
? STRING_KEYS.DEPOSIT_COMPLETE
|
||||
: inProgressStatusString
|
||||
: STRING_KEYS.DEPOSIT_STATUS
|
||||
: status?.squidTransactionStatus === 'success'
|
||||
? STRING_KEYS.WITHDRAW_COMPLETE
|
||||
: inProgressStatusString;
|
||||
: STRING_KEYS.WITHDRAW_STATUS;
|
||||
|
||||
return (
|
||||
<Styled.Root open={open} onOpenChange={setOpen}>
|
||||
|
||||
@@ -2,7 +2,7 @@ import { useMemo } from 'react';
|
||||
import styled, { css, keyframes, type AnyStyledComponent } from 'styled-components';
|
||||
import { StatusResponse } from '@0xsquid/sdk';
|
||||
|
||||
import { useStringGetter, useSelectedNetwork, useURLConfigs } from '@/hooks';
|
||||
import { useStringGetter } from '@/hooks';
|
||||
|
||||
import { Link } from '@/components/Link';
|
||||
import { Icon, IconName } from '@/components/Icon';
|
||||
@@ -11,7 +11,6 @@ import { LoadingSpinner } from '@/components/Loading/LoadingSpinner';
|
||||
|
||||
import { layoutMixins } from '@/styles/layoutMixins';
|
||||
import { STRING_KEYS } from '@/constants/localization';
|
||||
import { ENVIRONMENT_CONFIG_MAP } from '@/constants/networks';
|
||||
|
||||
type ElementProps = {
|
||||
status?: StatusResponse;
|
||||
@@ -27,17 +26,12 @@ enum TransferStatusStep {
|
||||
|
||||
export const TransferStatusSteps = ({ status, type }: ElementProps) => {
|
||||
const stringGetter = useStringGetter();
|
||||
const { selectedNetwork } = useSelectedNetwork();
|
||||
const { mintscan: mintscanTxUrl } = useURLConfigs();
|
||||
const dydxChainId = ENVIRONMENT_CONFIG_MAP[selectedNetwork].dydxChainId;
|
||||
|
||||
const { currentStep, steps } = useMemo(() => {
|
||||
const routeStatus = status?.routeStatus;
|
||||
const fromChain = status?.fromChain?.chainData?.chainId;
|
||||
const toChain = status?.toChain?.chainData?.chainId;
|
||||
|
||||
const currentStatus = routeStatus?.[routeStatus?.length - 1];
|
||||
|
||||
const steps = [
|
||||
{
|
||||
label: stringGetter({
|
||||
@@ -60,15 +54,12 @@ export const TransferStatusSteps = ({ status, type }: ElementProps) => {
|
||||
},
|
||||
}),
|
||||
step: TransferStatusStep.ToChain,
|
||||
link:
|
||||
type === 'withdrawal'
|
||||
? status?.toChain?.transactionUrl
|
||||
: currentStatus?.chainId === dydxChainId && currentStatus?.txHash
|
||||
? `${mintscanTxUrl?.replace('{tx_hash}', currentStatus.txHash)}`
|
||||
: undefined,
|
||||
link: status?.toChain?.transactionUrl,
|
||||
},
|
||||
];
|
||||
|
||||
const currentStatus = routeStatus?.[routeStatus?.length - 1];
|
||||
|
||||
let currentStep = TransferStatusStep.Bridge;
|
||||
|
||||
if (!routeStatus?.length) {
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { useState } from 'react';
|
||||
import styled, { type AnyStyledComponent } from 'styled-components';
|
||||
|
||||
import { isMainnet } from '@/constants/networks';
|
||||
import { STRING_KEYS } from '@/constants/localization';
|
||||
import { useBreakpoints, useStringGetter } from '@/hooks';
|
||||
|
||||
@@ -28,22 +27,14 @@ export const DepositDialog = ({ setIsOpen }: ElementProps) => {
|
||||
isOpen
|
||||
setIsOpen={setIsOpen}
|
||||
title={stringGetter({ key: STRING_KEYS.DEPOSIT })}
|
||||
description={
|
||||
!isMainnet && showTestDeposit && 'Test funds will be sent directly to your dYdX account.'
|
||||
}
|
||||
description={showTestDeposit && 'Test funds will be sent directly to your dYdX account.'}
|
||||
placement={isMobile ? DialogPlacement.FullScreen : DialogPlacement.Default}
|
||||
>
|
||||
<Styled.Content>
|
||||
{!isMainnet && showTestDeposit ? (
|
||||
<TestnetDepositForm onDeposit={closeDialog} />
|
||||
) : (
|
||||
<DepositForm />
|
||||
)}
|
||||
{!isMainnet && (
|
||||
<Styled.TextToggle onClick={() => setShowTestDeposit(!showTestDeposit)}>
|
||||
{showTestDeposit ? 'Show deposit form (Under Construction)' : 'Show test faucet'}
|
||||
</Styled.TextToggle>
|
||||
)}
|
||||
{showTestDeposit ? <TestnetDepositForm onDeposit={closeDialog} /> : <DepositForm />}
|
||||
<Styled.TextToggle onClick={() => setShowTestDeposit(!showTestDeposit)}>
|
||||
{showTestDeposit ? 'Show deposit form (Under Construction)' : 'Show test faucet'}
|
||||
</Styled.TextToggle>
|
||||
</Styled.Content>
|
||||
</Dialog>
|
||||
);
|
||||
|
||||
@@ -5,7 +5,6 @@ import { shallowEqual, useDispatch, useSelector } from 'react-redux';
|
||||
import { AbacusApiStatus } from '@/constants/abacus';
|
||||
import { DialogTypes } from '@/constants/dialogs';
|
||||
import { STRING_KEYS } from '@/constants/localization';
|
||||
import { isDev } from '@/constants/networks';
|
||||
|
||||
import { useApiState, useStringGetter } from '@/hooks';
|
||||
import { layoutMixins } from '@/styles/layoutMixins';
|
||||
@@ -46,7 +45,7 @@ export const ExchangeOfflineDialog = ({ preventClose, setIsOpen }: ElementProps)
|
||||
>
|
||||
<Styled.Content>
|
||||
<p>{statusErrorMessage}</p>
|
||||
{isDev && <NetworkSelectMenu />}
|
||||
{import.meta.env.MODE !== 'production' && <NetworkSelectMenu />}
|
||||
</Styled.Content>
|
||||
</Dialog>
|
||||
);
|
||||
|
||||
@@ -17,6 +17,7 @@ import { useAccounts, useDebounce, useStringGetter, useSelectedNetwork } from '@
|
||||
import { useAccountBalance, CHAIN_DEFAULT_TOKEN_ADDRESS } from '@/hooks/useAccountBalance';
|
||||
import { useLocalNotifications } from '@/hooks/useLocalNotifications';
|
||||
import { NATIVE_TOKEN_ADDRESS, useSquid } from '@/hooks/useSquid';
|
||||
import { useWalletConnection } from '@/hooks/useWalletConnection';
|
||||
|
||||
import { layoutMixins } from '@/styles/layoutMixins';
|
||||
import { formMixins } from '@/styles/formMixins';
|
||||
@@ -55,7 +56,8 @@ export const DepositForm = ({ onDeposit, onError }: DepositFormProps) => {
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const { selectedNetwork } = useSelectedNetwork();
|
||||
|
||||
const { evmAddress, signerWagmi, publicClientWagmi } = useAccounts();
|
||||
const { evmAddress, signerWagmi } = useAccounts();
|
||||
const { publicClientWagmi } = useWalletConnection();
|
||||
|
||||
const { addTransferNotification } = useLocalNotifications();
|
||||
|
||||
|
||||
@@ -4,10 +4,8 @@ import { shallowEqual, useDispatch, useSelector } from 'react-redux';
|
||||
|
||||
import {
|
||||
ClosePositionInputField,
|
||||
ValidationError,
|
||||
type HumanReadablePlaceOrderPayload,
|
||||
type Nullable,
|
||||
ErrorType,
|
||||
} from '@/constants/abacus';
|
||||
import { AlertType } from '@/constants/alerts';
|
||||
import { ButtonAction, ButtonShape, ButtonSize, ButtonType } from '@/constants/buttons';
|
||||
@@ -37,14 +35,13 @@ import { PositionPreview } from '@/views/forms/TradeForm/PositionPreview';
|
||||
import { getCurrentMarketPositionData } from '@/state/accountSelectors';
|
||||
|
||||
import { getCurrentMarketAssetData } from '@/state/assetsSelectors';
|
||||
import { getClosePositionInputErrors, getInputClosePositionData } from '@/state/inputsSelectors';
|
||||
import { getInputClosePositionData } from '@/state/inputsSelectors';
|
||||
import { getCurrentMarketConfig, getCurrentMarketId } from '@/state/perpetualsSelectors';
|
||||
import { closeDialog } from '@/state/dialogs';
|
||||
import { getCurrentInput } from '@/state/inputsSelectors';
|
||||
|
||||
import abacusStateManager from '@/lib/abacus';
|
||||
import { MustBigNumber } from '@/lib/numbers';
|
||||
import { getTradeInputAlert } from '@/lib/tradeData';
|
||||
|
||||
const MAX_KEY = 'MAX';
|
||||
|
||||
@@ -84,38 +81,15 @@ export const ClosePositionForm = ({
|
||||
|
||||
const market = useSelector(getCurrentMarketId);
|
||||
const { id } = useSelector(getCurrentMarketAssetData, shallowEqual) || {};
|
||||
const { stepSizeDecimals, tickSizeDecimals } =
|
||||
useSelector(getCurrentMarketConfig, shallowEqual) || {};
|
||||
const { stepSizeDecimals } = useSelector(getCurrentMarketConfig, shallowEqual) || {};
|
||||
const { size: sizeData, summary } = useSelector(getInputClosePositionData, shallowEqual) || {};
|
||||
const { size, percent } = sizeData || {};
|
||||
const currentInput = useSelector(getCurrentInput);
|
||||
const closePositionInputErrors = useSelector(getClosePositionInputErrors, shallowEqual);
|
||||
const currentPositionData = useSelector(getCurrentMarketPositionData, shallowEqual);
|
||||
const { size: currentPositionSize } = currentPositionData || {};
|
||||
const { current: currentSize } = currentPositionSize || {};
|
||||
const currentSizeBN = MustBigNumber(currentSize).abs();
|
||||
|
||||
const hasInputErrors = closePositionInputErrors?.some(
|
||||
(error: ValidationError) => error.type !== ErrorType.warning
|
||||
);
|
||||
|
||||
const inputAlert = getTradeInputAlert({
|
||||
abacusInputErrors: closePositionInputErrors ?? [],
|
||||
stringGetter,
|
||||
stepSizeDecimals,
|
||||
tickSizeDecimals,
|
||||
});
|
||||
|
||||
let alertContent;
|
||||
let alertType = AlertType.Error;
|
||||
|
||||
if (closePositionError) {
|
||||
alertContent = closePositionError;
|
||||
} else if (inputAlert) {
|
||||
alertContent = inputAlert?.alertString;
|
||||
alertType = inputAlert?.type;
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (currentStep && currentStep !== MobilePlaceOrderSteps.EditOrder) return;
|
||||
|
||||
@@ -208,7 +182,9 @@ export const ClosePositionForm = ({
|
||||
});
|
||||
};
|
||||
|
||||
const alertMessage = alertContent && <AlertMessage type={alertType}>{alertContent}</AlertMessage>;
|
||||
const alertMessage = closePositionError && (
|
||||
<AlertMessage type={AlertType.Error}>{closePositionError}</AlertMessage>
|
||||
);
|
||||
|
||||
const inputs = (
|
||||
<Styled.InputsColumn>
|
||||
@@ -289,8 +265,8 @@ export const ClosePositionForm = ({
|
||||
|
||||
<PlaceOrderButtonAndReceipt
|
||||
isLoading={isClosingPosition}
|
||||
hasValidationErrors={hasInputErrors}
|
||||
actionStringKey={inputAlert?.actionStringKey}
|
||||
hasValidationErrors={!size}
|
||||
actionStringKey={!size ? STRING_KEYS.ENTER_AMOUNT : undefined}
|
||||
summary={summary ?? undefined}
|
||||
currentStep={currentStep}
|
||||
isClosePosition
|
||||
|
||||
@@ -7,7 +7,7 @@ import { ButtonAction } from '@/constants/buttons';
|
||||
import { DialogTypes } from '@/constants/dialogs';
|
||||
import { STRING_KEYS, StringGetterFunction } from '@/constants/localization';
|
||||
|
||||
import { useBreakpoints, useStringGetter, useURLConfigs } from '@/hooks';
|
||||
import { useBreakpoints, useStringGetter } from '@/hooks';
|
||||
|
||||
import { layoutMixins } from '@/styles/layoutMixins';
|
||||
import { tradeViewMixins } from '@/styles/tradeViewMixins';
|
||||
@@ -40,13 +40,11 @@ const getTransferHistoryTableColumnDef = ({
|
||||
key,
|
||||
stringGetter,
|
||||
width,
|
||||
mintscanTxUrl,
|
||||
}: {
|
||||
key: TransferHistoryTableColumnKey;
|
||||
isTablet?: boolean;
|
||||
stringGetter: StringGetterFunction;
|
||||
width?: ColumnSize;
|
||||
mintscanTxUrl?: string;
|
||||
}): ColumnDef<SubaccountTransfer> => ({
|
||||
width,
|
||||
...(
|
||||
@@ -100,12 +98,9 @@ const getTransferHistoryTableColumnDef = ({
|
||||
columnKey: TransferHistoryTableColumnKey.TxHash,
|
||||
getCellValue: (row) => row.transactionHash,
|
||||
label: stringGetter({ key: STRING_KEYS.TRANSACTION }),
|
||||
renderCell: ({ transactionHash }) =>
|
||||
renderCell: ({ transactionHash, resources }) =>
|
||||
transactionHash ? (
|
||||
<Styled.TxHash
|
||||
withIcon
|
||||
href={`${mintscanTxUrl?.replace('{tx_hash}', transactionHash)}`}
|
||||
>
|
||||
<Styled.TxHash withIcon href={resources.blockExplorerUrl}>
|
||||
{truncateAddress(transactionHash, '')}
|
||||
</Styled.TxHash>
|
||||
) : (
|
||||
@@ -135,7 +130,6 @@ export const TransferHistoryTable = ({
|
||||
const stringGetter = useStringGetter();
|
||||
const dispatch = useDispatch();
|
||||
const { isMobile, isTablet } = useBreakpoints();
|
||||
const { mintscan: mintscanTxUrl } = useURLConfigs();
|
||||
|
||||
const canAccountTrade = useSelector(calculateCanAccountTrade, shallowEqual);
|
||||
|
||||
@@ -152,7 +146,6 @@ export const TransferHistoryTable = ({
|
||||
isTablet,
|
||||
stringGetter,
|
||||
width: columnWidths?.[key],
|
||||
mintscanTxUrl,
|
||||
})
|
||||
)}
|
||||
slotEmpty={
|
||||
|
||||
Reference in New Issue
Block a user