Compare commits
3
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
67e7893629 | ||
|
|
24ffb19787 | ||
|
|
1386f5cd9e |
@@ -98,11 +98,6 @@ For the "Build & Development Settings", we recommend the following:
|
|||||||
- Framework Preset: `Vite`
|
- Framework Preset: `Vite`
|
||||||
- Build Command (override): `pnpm run build`
|
- Build Command (override): `pnpm run build`
|
||||||
|
|
||||||
By default, the dev server runs in development mode and the build command runs in production mode. To override the default mode, you can pass in the `--mode` option flag. For example, if you want to build your app for testnet:
|
|
||||||
```
|
|
||||||
pnpm run build --mode testnet
|
|
||||||
```
|
|
||||||
|
|
||||||
If you wish to incorporate analytics via Amplitude and Bugsnag, you can use our scripts:
|
If you wish to incorporate analytics via Amplitude and Bugsnag, you can use our scripts:
|
||||||
`pnpm run build:inject-amplitude` and `pnpm run build:inject-bugsnag`. You will need to provide your own API keys for these services. In the Environment Variables section, name the variables as `AMPLITUDE_API_KEY` and `BUGSNAG_API_KEY` and provide the respective keys as their values.
|
`pnpm run build:inject-amplitude` and `pnpm run build:inject-bugsnag`. You will need to provide your own API keys for these services. In the Environment Variables section, name the variables as `AMPLITUDE_API_KEY` and `BUGSNAG_API_KEY` and provide the respective keys as their values.
|
||||||
|
|
||||||
|
|||||||
+1
-2
@@ -39,7 +39,7 @@
|
|||||||
"@cosmjs/proto-signing": "^0.31.0",
|
"@cosmjs/proto-signing": "^0.31.0",
|
||||||
"@cosmjs/stargate": "^0.31.0",
|
"@cosmjs/stargate": "^0.31.0",
|
||||||
"@cosmjs/tendermint-rpc": "^0.31.0",
|
"@cosmjs/tendermint-rpc": "^0.31.0",
|
||||||
"@dydxprotocol/v4-abacus": "^1.0.24",
|
"@dydxprotocol/v4-abacus": "^1.0.19",
|
||||||
"@dydxprotocol/v4-client-js": "^1.0.0",
|
"@dydxprotocol/v4-client-js": "^1.0.0",
|
||||||
"@dydxprotocol/v4-localization": "^1.0.5",
|
"@dydxprotocol/v4-localization": "^1.0.5",
|
||||||
"@ethersproject/providers": "^5.7.2",
|
"@ethersproject/providers": "^5.7.2",
|
||||||
@@ -96,7 +96,6 @@
|
|||||||
"long": "^5.2.3",
|
"long": "^5.2.3",
|
||||||
"luxon": "^3.3.0",
|
"luxon": "^3.3.0",
|
||||||
"qr-code-styling": "1.6.0-rc.1",
|
"qr-code-styling": "1.6.0-rc.1",
|
||||||
"query-string": "^8.1.0",
|
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-aria": "^3.25.0",
|
"react-aria": "^3.25.0",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
|
|||||||
Generated
+8
-7
@@ -27,8 +27,8 @@ dependencies:
|
|||||||
specifier: ^0.31.0
|
specifier: ^0.31.0
|
||||||
version: 0.31.0
|
version: 0.31.0
|
||||||
'@dydxprotocol/v4-abacus':
|
'@dydxprotocol/v4-abacus':
|
||||||
specifier: ^1.0.24
|
specifier: ^1.0.19
|
||||||
version: 1.0.24
|
version: 1.0.19
|
||||||
'@dydxprotocol/v4-client-js':
|
'@dydxprotocol/v4-client-js':
|
||||||
specifier: ^1.0.0
|
specifier: ^1.0.0
|
||||||
version: 1.0.0
|
version: 1.0.0
|
||||||
@@ -197,9 +197,6 @@ dependencies:
|
|||||||
qr-code-styling:
|
qr-code-styling:
|
||||||
specifier: 1.6.0-rc.1
|
specifier: 1.6.0-rc.1
|
||||||
version: 1.6.0-rc.1
|
version: 1.6.0-rc.1
|
||||||
query-string:
|
|
||||||
specifier: ^8.1.0
|
|
||||||
version: 8.1.0
|
|
||||||
react:
|
react:
|
||||||
specifier: ^18.2.0
|
specifier: ^18.2.0
|
||||||
version: 18.2.0
|
version: 18.2.0
|
||||||
@@ -982,8 +979,8 @@ packages:
|
|||||||
resolution: {integrity: sha512-RpfLEtTlyIxeNPGKcokS+p3BZII/Q3bYxryFRglh5H3A3T8q9fsLYm72VYAMEOOIBLEa8o93kFLiBDUWKrwXZA==}
|
resolution: {integrity: sha512-RpfLEtTlyIxeNPGKcokS+p3BZII/Q3bYxryFRglh5H3A3T8q9fsLYm72VYAMEOOIBLEa8o93kFLiBDUWKrwXZA==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/@dydxprotocol/v4-abacus@1.0.24:
|
/@dydxprotocol/v4-abacus@1.0.19:
|
||||||
resolution: {integrity: sha512-wDGSjkrc3Se6Ev7UTjPgJV7PiyzZSz2mJwOTZikLwH7W3k1iPYGQmaCd7TudFk8h2aSdlEwNsQBCf0sLoyvHaQ==}
|
resolution: {integrity: sha512-XhvSHGr503gNwHWEiOYP7M2uYeLu+Qm4szpE5w5H6hWFCanSGz6zAsTbPuyPLtt7IE1gj5z8mlL9J3tw2AZROg==}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/@dydxprotocol/v4-client-js@1.0.0:
|
/@dydxprotocol/v4-client-js@1.0.0:
|
||||||
@@ -7878,6 +7875,7 @@ packages:
|
|||||||
/decode-uri-component@0.4.1:
|
/decode-uri-component@0.4.1:
|
||||||
resolution: {integrity: sha512-+8VxcR21HhTy8nOt6jf20w0c9CADrw1O8d+VZ/YzzCt4bJ3uBjw+D1q2osAB8RnpwwaeYBxy0HyKQxD5JBMuuQ==}
|
resolution: {integrity: sha512-+8VxcR21HhTy8nOt6jf20w0c9CADrw1O8d+VZ/YzzCt4bJ3uBjw+D1q2osAB8RnpwwaeYBxy0HyKQxD5JBMuuQ==}
|
||||||
engines: {node: '>=14.16'}
|
engines: {node: '>=14.16'}
|
||||||
|
dev: true
|
||||||
|
|
||||||
/deep-eql@4.1.3:
|
/deep-eql@4.1.3:
|
||||||
resolution: {integrity: sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==}
|
resolution: {integrity: sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==}
|
||||||
@@ -8947,6 +8945,7 @@ packages:
|
|||||||
/filter-obj@5.1.0:
|
/filter-obj@5.1.0:
|
||||||
resolution: {integrity: sha512-qWeTREPoT7I0bifpPUXtxkZJ1XJzxWtfoWWkdVGqa+eCr3SHW/Ocp89o8vLvbUuQnadybJpjOKu4V+RwO6sGng==}
|
resolution: {integrity: sha512-qWeTREPoT7I0bifpPUXtxkZJ1XJzxWtfoWWkdVGqa+eCr3SHW/Ocp89o8vLvbUuQnadybJpjOKu4V+RwO6sGng==}
|
||||||
engines: {node: '>=14.16'}
|
engines: {node: '>=14.16'}
|
||||||
|
dev: true
|
||||||
|
|
||||||
/find-cache-dir@3.3.2:
|
/find-cache-dir@3.3.2:
|
||||||
resolution: {integrity: sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==}
|
resolution: {integrity: sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==}
|
||||||
@@ -11877,6 +11876,7 @@ packages:
|
|||||||
decode-uri-component: 0.4.1
|
decode-uri-component: 0.4.1
|
||||||
filter-obj: 5.1.0
|
filter-obj: 5.1.0
|
||||||
split-on-first: 3.0.0
|
split-on-first: 3.0.0
|
||||||
|
dev: true
|
||||||
|
|
||||||
/queue-microtask@1.2.3:
|
/queue-microtask@1.2.3:
|
||||||
resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
|
resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
|
||||||
@@ -12701,6 +12701,7 @@ packages:
|
|||||||
/split-on-first@3.0.0:
|
/split-on-first@3.0.0:
|
||||||
resolution: {integrity: sha512-qxQJTx2ryR0Dw0ITYyekNQWpz6f8dGd7vffGNflQQ3Iqj9NJ6qiZ7ELpZsJ/QBhIVAiDfXdag3+Gp8RvWa62AA==}
|
resolution: {integrity: sha512-qxQJTx2ryR0Dw0ITYyekNQWpz6f8dGd7vffGNflQQ3Iqj9NJ6qiZ7ELpZsJ/QBhIVAiDfXdag3+Gp8RvWa62AA==}
|
||||||
engines: {node: '>=12'}
|
engines: {node: '>=12'}
|
||||||
|
dev: true
|
||||||
|
|
||||||
/split2@4.2.0:
|
/split2@4.2.0:
|
||||||
resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==}
|
resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==}
|
||||||
|
|||||||
@@ -23,7 +23,6 @@ import { LocalNotificationsProvider } from '@/hooks/useLocalNotifications';
|
|||||||
import { RestrictionProvider } from '@/hooks/useRestrictions';
|
import { RestrictionProvider } from '@/hooks/useRestrictions';
|
||||||
import { SubaccountProvider } from '@/hooks/useSubaccount';
|
import { SubaccountProvider } from '@/hooks/useSubaccount';
|
||||||
import { SquidProvider } from '@/hooks/useSquid';
|
import { SquidProvider } from '@/hooks/useSquid';
|
||||||
import { TestFlagsProvider } from '@/hooks/useTestFlags';
|
|
||||||
|
|
||||||
import { GuardedMobileRoute } from '@/components/GuardedMobileRoute';
|
import { GuardedMobileRoute } from '@/components/GuardedMobileRoute';
|
||||||
|
|
||||||
@@ -124,7 +123,6 @@ const providers = [
|
|||||||
wrapProvider(QueryClientProvider, { client: queryClient }),
|
wrapProvider(QueryClientProvider, { client: queryClient }),
|
||||||
wrapProvider(GrazProvider),
|
wrapProvider(GrazProvider),
|
||||||
wrapProvider(WagmiConfig, { config }),
|
wrapProvider(WagmiConfig, { config }),
|
||||||
wrapProvider(TestFlagsProvider),
|
|
||||||
wrapProvider(LocaleProvider),
|
wrapProvider(LocaleProvider),
|
||||||
wrapProvider(RestrictionProvider),
|
wrapProvider(RestrictionProvider),
|
||||||
wrapProvider(DydxProvider),
|
wrapProvider(DydxProvider),
|
||||||
|
|||||||
@@ -1,46 +0,0 @@
|
|||||||
import { createContext, useContext, useEffect, useState } from 'react';
|
|
||||||
import { useLocation } from 'react-router-dom';
|
|
||||||
import queryString from 'query-string';
|
|
||||||
|
|
||||||
class TestFlags {
|
|
||||||
public queryParams: queryString.ParsedQuery<string>;
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
this.queryParams = {};
|
|
||||||
}
|
|
||||||
|
|
||||||
setQueryParams(flags: queryString.ParsedQuery<string>) {
|
|
||||||
this.queryParams = flags;
|
|
||||||
}
|
|
||||||
|
|
||||||
get displayInitializingMarkets() {
|
|
||||||
return !!this.queryParams.displayInitializingMarkets;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export const testFlags = new TestFlags();
|
|
||||||
|
|
||||||
const useTestFlagsContext = () => {
|
|
||||||
const [queryParams, setQueryParams] = useState<queryString.ParsedQuery<string>>({});
|
|
||||||
const location = useLocation();
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
const parsedQueryParams = queryString.parse(location.search.substring(-1));
|
|
||||||
testFlags.setQueryParams(parsedQueryParams);
|
|
||||||
setQueryParams(parsedQueryParams);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
return {
|
|
||||||
...queryParams,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
type TestFlagsContextType = ReturnType<typeof useTestFlagsContext>;
|
|
||||||
const TestFlagsContext = createContext<TestFlagsContextType>({} as TestFlagsContextType);
|
|
||||||
TestFlagsContext.displayName = 'TestFlags';
|
|
||||||
|
|
||||||
export const TestFlagsProvider = ({ ...props }) => (
|
|
||||||
<TestFlagsContext.Provider value={useTestFlagsContext()} {...props} />
|
|
||||||
);
|
|
||||||
|
|
||||||
export const useTestFlags = () => useContext(TestFlagsContext);
|
|
||||||
@@ -56,7 +56,12 @@ class AbacusRest implements AbacusRestProtocol {
|
|||||||
.then(async (response) => {
|
.then(async (response) => {
|
||||||
const data = await response.text();
|
const data = await response.text();
|
||||||
|
|
||||||
callback(data, response.status);
|
if (response.ok) {
|
||||||
|
callback(data, response.status);
|
||||||
|
} else {
|
||||||
|
// response not OK, call callback with null data and the status, this includes 400/500 status codes
|
||||||
|
callback(null, response.status);
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
lastSuccessfulRestRequestByOrigin[new URL(url).origin] = Date.now();
|
lastSuccessfulRestRequestByOrigin[new URL(url).origin] = Date.now();
|
||||||
|
|||||||
@@ -9,12 +9,11 @@ import {
|
|||||||
PONG_MESSAGE_TYPE,
|
PONG_MESSAGE_TYPE,
|
||||||
} from '@/constants/websocket';
|
} from '@/constants/websocket';
|
||||||
|
|
||||||
import { lastSuccessfulWebsocketRequestByOrigin } from '@/hooks/useAnalytics';
|
|
||||||
import { testFlags } from '@/hooks/useTestFlags';
|
|
||||||
|
|
||||||
import { subscriptionsByChannelId } from '@/lib/tradingView/dydxfeed/cache';
|
import { subscriptionsByChannelId } from '@/lib/tradingView/dydxfeed/cache';
|
||||||
import { mapCandle } from '@/lib/tradingView/utils';
|
import { mapCandle } from '@/lib/tradingView/utils';
|
||||||
|
|
||||||
|
import { lastSuccessfulWebsocketRequestByOrigin } from '@/hooks/useAnalytics';
|
||||||
|
|
||||||
import { log } from '../telemetry';
|
import { log } from '../telemetry';
|
||||||
|
|
||||||
const RECONNECT_INTERVAL_MS = 10_000;
|
const RECONNECT_INTERVAL_MS = 10_000;
|
||||||
@@ -145,23 +144,6 @@ class AbacusWebsocket implements Omit<AbacusWebsocketProtocol, '__doNotUseOrImpl
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'v4_markets': {
|
|
||||||
if (testFlags.displayInitializingMarkets) {
|
|
||||||
shouldProcess = false;
|
|
||||||
const { contents } = parsedMessage;
|
|
||||||
|
|
||||||
Object.keys(contents.markets ?? {}).forEach((market: any) => {
|
|
||||||
const status = contents.markets[market].status;
|
|
||||||
if (status === 'INITIALIZING') {
|
|
||||||
contents.markets[market].status = 'ONLINE';
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
this.receivedCallback?.(JSON.stringify(parsedMessage));
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default: {
|
default: {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ type ElementProps = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const DepositDialog = ({ setIsOpen }: ElementProps) => {
|
export const DepositDialog = ({ setIsOpen }: ElementProps) => {
|
||||||
const [showFaucet, setShowFaucet] = useState(!isMainnet);
|
const [showTestDeposit, setShowTestDeposit] = useState(true);
|
||||||
const stringGetter = useStringGetter();
|
const stringGetter = useStringGetter();
|
||||||
const { isMobile } = useBreakpoints();
|
const { isMobile } = useBreakpoints();
|
||||||
|
|
||||||
@@ -28,18 +28,20 @@ export const DepositDialog = ({ setIsOpen }: ElementProps) => {
|
|||||||
isOpen
|
isOpen
|
||||||
setIsOpen={setIsOpen}
|
setIsOpen={setIsOpen}
|
||||||
title={stringGetter({ key: STRING_KEYS.DEPOSIT })}
|
title={stringGetter({ key: STRING_KEYS.DEPOSIT })}
|
||||||
description={showFaucet && '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>
|
||||||
{isMainnet || !showFaucet ? (
|
{!isMainnet && showTestDeposit ? (
|
||||||
<DepositForm />
|
|
||||||
) : (
|
|
||||||
<TestnetDepositForm onDeposit={closeDialog} />
|
<TestnetDepositForm onDeposit={closeDialog} />
|
||||||
|
) : (
|
||||||
|
<DepositForm />
|
||||||
)}
|
)}
|
||||||
{!isMainnet && (
|
{!isMainnet && (
|
||||||
<Styled.TextToggle onClick={() => setShowFaucet(!showFaucet)}>
|
<Styled.TextToggle onClick={() => setShowTestDeposit(!showTestDeposit)}>
|
||||||
{showFaucet ? 'Show deposit form' : 'Show test faucet'}
|
{showTestDeposit ? 'Show deposit form (Under Construction)' : 'Show test faucet'}
|
||||||
</Styled.TextToggle>
|
</Styled.TextToggle>
|
||||||
)}
|
)}
|
||||||
</Styled.Content>
|
</Styled.Content>
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { type FormEvent, useCallback, useEffect, useMemo, useState } from 'react
|
|||||||
import styled, { type AnyStyledComponent } from 'styled-components';
|
import styled, { type AnyStyledComponent } from 'styled-components';
|
||||||
import { type NumberFormatValues } from 'react-number-format';
|
import { type NumberFormatValues } from 'react-number-format';
|
||||||
import { shallowEqual, useSelector } from 'react-redux';
|
import { shallowEqual, useSelector } from 'react-redux';
|
||||||
import { parseUnits } from 'viem';
|
import { parseUnits } from 'viem'
|
||||||
|
|
||||||
import erc20 from '@/abi/erc20.json';
|
import erc20 from '@/abi/erc20.json';
|
||||||
import { TransferInputField, TransferInputTokenResource, TransferType } from '@/constants/abacus';
|
import { TransferInputField, TransferInputTokenResource, TransferType } from '@/constants/abacus';
|
||||||
@@ -65,8 +65,6 @@ export const DepositForm = ({ onDeposit, onError }: DepositFormProps) => {
|
|||||||
chain: chainIdStr,
|
chain: chainIdStr,
|
||||||
resources,
|
resources,
|
||||||
summary,
|
summary,
|
||||||
errors: routeErrors,
|
|
||||||
errorMessage: routeErrorMessage,
|
|
||||||
} = useSelector(getTransferInputs, shallowEqual) || {};
|
} = useSelector(getTransferInputs, shallowEqual) || {};
|
||||||
const chainId = chainIdStr ? parseInt(chainIdStr) : undefined;
|
const chainId = chainIdStr ? parseInt(chainIdStr) : undefined;
|
||||||
|
|
||||||
@@ -99,7 +97,7 @@ export const DepositForm = ({ onDeposit, onError }: DepositFormProps) => {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const hasInvalidInput =
|
const hasInvalidInput =
|
||||||
debouncedAmountBN.isNaN() || debouncedAmountBN.lte(0) || debouncedAmountBN.gt(balanceBN);
|
debouncedAmountBN.isNaN() || debouncedAmountBN.lte(0) || debouncedAmountBN.gte(balanceBN);
|
||||||
|
|
||||||
abacusStateManager.setTransferValue({
|
abacusStateManager.setTransferValue({
|
||||||
value: hasInvalidInput ? 0 : debouncedAmount,
|
value: hasInvalidInput ? 0 : debouncedAmount,
|
||||||
@@ -173,8 +171,7 @@ export const DepositForm = ({ onDeposit, onError }: DepositFormProps) => {
|
|||||||
|
|
||||||
const validateTokenApproval = useCallback(async () => {
|
const validateTokenApproval = useCallback(async () => {
|
||||||
if (!signerWagmi || !publicClientWagmi) throw new Error('Missing signer');
|
if (!signerWagmi || !publicClientWagmi) throw new Error('Missing signer');
|
||||||
if (!sourceToken?.address || !sourceToken.decimals)
|
if (!sourceToken?.address || !sourceToken.decimals) throw new Error('Missing source token address');
|
||||||
throw new Error('Missing source token address');
|
|
||||||
if (!sourceChain?.rpc) throw new Error('Missing source chain rpc');
|
if (!sourceChain?.rpc) throw new Error('Missing source chain rpc');
|
||||||
if (!requestPayload?.targetAddress) throw new Error('Missing target address');
|
if (!requestPayload?.targetAddress) throw new Error('Missing target address');
|
||||||
if (!requestPayload?.value) throw new Error('Missing transaction value');
|
if (!requestPayload?.value) throw new Error('Missing transaction value');
|
||||||
@@ -184,7 +181,7 @@ export const DepositForm = ({ onDeposit, onError }: DepositFormProps) => {
|
|||||||
address: sourceToken.address as EvmAddress,
|
address: sourceToken.address as EvmAddress,
|
||||||
abi: erc20,
|
abi: erc20,
|
||||||
functionName: 'allowance',
|
functionName: 'allowance',
|
||||||
args: [evmAddress as EvmAddress, requestPayload.targetAddress as EvmAddress],
|
args: [evmAddress as EvmAddress, requestPayload.targetAddress as EvmAddress]
|
||||||
});
|
});
|
||||||
|
|
||||||
const sourceAmountBN = parseUnits(debouncedAmount, sourceToken.decimals);
|
const sourceAmountBN = parseUnits(debouncedAmount, sourceToken.decimals);
|
||||||
@@ -196,12 +193,12 @@ export const DepositForm = ({ onDeposit, onError }: DepositFormProps) => {
|
|||||||
abi: erc20,
|
abi: erc20,
|
||||||
functionName: 'approve',
|
functionName: 'approve',
|
||||||
args: [requestPayload.targetAddress as EvmAddress, sourceAmountBN],
|
args: [requestPayload.targetAddress as EvmAddress, sourceAmountBN],
|
||||||
});
|
})
|
||||||
|
|
||||||
const approveTx = await signerWagmi.writeContract(request);
|
const approveTx = await signerWagmi.writeContract(request);
|
||||||
await publicClientWagmi.waitForTransactionReceipt({
|
await publicClientWagmi.waitForTransactionReceipt({
|
||||||
hash: approveTx,
|
hash: approveTx,
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
}, [signerWagmi, sourceToken, sourceChain, requestPayload, publicClientWagmi]);
|
}, [signerWagmi, sourceToken, sourceChain, requestPayload, publicClientWagmi]);
|
||||||
|
|
||||||
@@ -231,7 +228,8 @@ export const DepositForm = ({ onDeposit, onError }: DepositFormProps) => {
|
|||||||
to: requestPayload.targetAddress as EvmAddress,
|
to: requestPayload.targetAddress as EvmAddress,
|
||||||
data: requestPayload.data as EvmAddress,
|
data: requestPayload.data as EvmAddress,
|
||||||
gasLimit: BigInt(requestPayload.gasLimit),
|
gasLimit: BigInt(requestPayload.gasLimit),
|
||||||
value: requestPayload.routeType !== 'SEND' ? BigInt(requestPayload.value) : undefined,
|
value:
|
||||||
|
requestPayload.routeType !== 'SEND' ? BigInt(requestPayload.value) : undefined,
|
||||||
};
|
};
|
||||||
const txHash = await signerWagmi.sendTransaction(tx);
|
const txHash = await signerWagmi.sendTransaction(tx);
|
||||||
|
|
||||||
@@ -289,15 +287,6 @@ export const DepositForm = ({ onDeposit, onError }: DepositFormProps) => {
|
|||||||
return parseWalletError({ error, stringGetter }).message;
|
return parseWalletError({ error, stringGetter }).message;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (routeErrors) {
|
|
||||||
return routeErrorMessage
|
|
||||||
? stringGetter({
|
|
||||||
key: STRING_KEYS.SOMETHING_WENT_WRONG_WITH_MESSAGE,
|
|
||||||
params: { ERROR_MESSAGE: routeErrorMessage },
|
|
||||||
})
|
|
||||||
: stringGetter({ key: STRING_KEYS.SOMETHING_WENT_WRONG });
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fromAmount) {
|
if (fromAmount) {
|
||||||
if (!chainId) {
|
if (!chainId) {
|
||||||
return stringGetter({ key: STRING_KEYS.MUST_SPECIFY_CHAIN });
|
return stringGetter({ key: STRING_KEYS.MUST_SPECIFY_CHAIN });
|
||||||
@@ -311,16 +300,7 @@ export const DepositForm = ({ onDeposit, onError }: DepositFormProps) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return undefined;
|
return undefined;
|
||||||
}, [
|
}, [error, balance, chainId, fromAmount, sourceToken]);
|
||||||
error,
|
|
||||||
routeErrors,
|
|
||||||
routeErrorMessage,
|
|
||||||
balance,
|
|
||||||
chainId,
|
|
||||||
fromAmount,
|
|
||||||
sourceToken,
|
|
||||||
stringGetter,
|
|
||||||
]);
|
|
||||||
|
|
||||||
const isDisabled =
|
const isDisabled =
|
||||||
Boolean(errorMessage) ||
|
Boolean(errorMessage) ||
|
||||||
|
|||||||
@@ -164,7 +164,6 @@ export const DepositButtonAndReceipt = ({
|
|||||||
label: <span>{stringGetter({ key: STRING_KEYS.SLIPPAGE })}</span>,
|
label: <span>{stringGetter({ key: STRING_KEYS.SLIPPAGE })}</span>,
|
||||||
value: (
|
value: (
|
||||||
<SlippageEditor
|
<SlippageEditor
|
||||||
disabled
|
|
||||||
slippage={slippage}
|
slippage={slippage}
|
||||||
setIsEditing={setIsEditingSlipapge}
|
setIsEditing={setIsEditingSlipapge}
|
||||||
setSlippage={setSlippage}
|
setSlippage={setSlippage}
|
||||||
|
|||||||
@@ -24,17 +24,11 @@ type ElementProps = {
|
|||||||
slippage: number;
|
slippage: number;
|
||||||
setIsEditing?: Dispatch<SetStateAction<boolean>>;
|
setIsEditing?: Dispatch<SetStateAction<boolean>>;
|
||||||
setSlippage: (slippage: number) => void;
|
setSlippage: (slippage: number) => void;
|
||||||
disabled?: boolean;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export type SlippageEditorProps = ElementProps;
|
export type SlippageEditorProps = ElementProps;
|
||||||
|
|
||||||
export const SlippageEditor = ({
|
export const SlippageEditor = ({ slippage, setIsEditing, setSlippage }: SlippageEditorProps) => {
|
||||||
disabled,
|
|
||||||
slippage,
|
|
||||||
setIsEditing,
|
|
||||||
setSlippage,
|
|
||||||
}: SlippageEditorProps) => {
|
|
||||||
const percentSlippage = slippage * 100;
|
const percentSlippage = slippage * 100;
|
||||||
const [slippageInputValue, setSlippageInputValue] = useState(percentSlippage.toString());
|
const [slippageInputValue, setSlippageInputValue] = useState(percentSlippage.toString());
|
||||||
const [editorState, setEditorState] = useState(EditorState.Viewing);
|
const [editorState, setEditorState] = useState(EditorState.Viewing);
|
||||||
@@ -86,10 +80,6 @@ export const SlippageEditor = ({
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if (disabled) {
|
|
||||||
return <Output type={OutputType.Percent} value={slippage} />;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Styled.WithConfirmationPopover
|
<Styled.WithConfirmationPopover
|
||||||
open={editorState !== EditorState.Viewing}
|
open={editorState !== EditorState.Viewing}
|
||||||
|
|||||||
@@ -44,10 +44,10 @@ import { getTransferInputs } from '@/state/inputsSelectors';
|
|||||||
|
|
||||||
import abacusStateManager from '@/lib/abacus';
|
import abacusStateManager from '@/lib/abacus';
|
||||||
import { MustBigNumber } from '@/lib/numbers';
|
import { MustBigNumber } from '@/lib/numbers';
|
||||||
import { log } from '@/lib/telemetry';
|
|
||||||
|
|
||||||
import { TokenSelectMenu } from './TokenSelectMenu';
|
import { TokenSelectMenu } from './TokenSelectMenu';
|
||||||
import { WithdrawButtonAndReceipt } from './WithdrawForm/WithdrawButtonAndReceipt';
|
import { WithdrawButtonAndReceipt } from './WithdrawForm/WithdrawButtonAndReceipt';
|
||||||
|
import { join } from 'path';
|
||||||
|
|
||||||
export const WithdrawForm = () => {
|
export const WithdrawForm = () => {
|
||||||
const stringGetter = useStringGetter();
|
const stringGetter = useStringGetter();
|
||||||
@@ -69,8 +69,6 @@ export const WithdrawForm = () => {
|
|||||||
chain: chainIdStr,
|
chain: chainIdStr,
|
||||||
address: toAddress,
|
address: toAddress,
|
||||||
resources,
|
resources,
|
||||||
errors: routeErrors,
|
|
||||||
errorMessage: routeErrorMessage,
|
|
||||||
} = useSelector(getTransferInputs, shallowEqual) || {};
|
} = useSelector(getTransferInputs, shallowEqual) || {};
|
||||||
|
|
||||||
const isValidAddress = toAddress && isAddress(toAddress);
|
const isValidAddress = toAddress && isAddress(toAddress);
|
||||||
@@ -283,15 +281,6 @@ export const WithdrawForm = () => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (routeErrors) {
|
|
||||||
return routeErrorMessage
|
|
||||||
? stringGetter({
|
|
||||||
key: STRING_KEYS.SOMETHING_WENT_WRONG_WITH_MESSAGE,
|
|
||||||
params: { ERROR_MESSAGE: routeErrorMessage },
|
|
||||||
})
|
|
||||||
: stringGetter({ key: STRING_KEYS.SOMETHING_WENT_WRONG });
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!toAddress) return stringGetter({ key: STRING_KEYS.WITHDRAW_MUST_SPECIFY_ADDRESS });
|
if (!toAddress) return stringGetter({ key: STRING_KEYS.WITHDRAW_MUST_SPECIFY_ADDRESS });
|
||||||
|
|
||||||
if (sanctionedAddresses.has(toAddress))
|
if (sanctionedAddresses.has(toAddress))
|
||||||
@@ -314,15 +303,12 @@ export const WithdrawForm = () => {
|
|||||||
return undefined;
|
return undefined;
|
||||||
}, [
|
}, [
|
||||||
error,
|
error,
|
||||||
routeErrors,
|
|
||||||
routeErrorMessage,
|
|
||||||
freeCollateralBN,
|
freeCollateralBN,
|
||||||
chainIdStr,
|
chainIdStr,
|
||||||
debouncedAmountBN,
|
debouncedAmountBN,
|
||||||
toToken,
|
toToken,
|
||||||
toAddress,
|
toAddress,
|
||||||
sanctionedAddresses,
|
sanctionedAddresses,
|
||||||
stringGetter,
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const isDisabled =
|
const isDisabled =
|
||||||
|
|||||||
@@ -147,7 +147,6 @@ export const WithdrawButtonAndReceipt = ({
|
|||||||
label: <span>{stringGetter({ key: STRING_KEYS.SLIPPAGE })}</span>,
|
label: <span>{stringGetter({ key: STRING_KEYS.SLIPPAGE })}</span>,
|
||||||
value: (
|
value: (
|
||||||
<SlippageEditor
|
<SlippageEditor
|
||||||
disabled
|
|
||||||
slippage={slippage}
|
slippage={slippage}
|
||||||
setIsEditing={setIsEditingSlipapge}
|
setIsEditing={setIsEditingSlipapge}
|
||||||
setSlippage={setSlippage}
|
setSlippage={setSlippage}
|
||||||
|
|||||||
@@ -61,53 +61,38 @@ export const TransferForm = ({
|
|||||||
const stringGetter = useStringGetter();
|
const stringGetter = useStringGetter();
|
||||||
const { freeCollateral } = useSelector(getSubaccount, shallowEqual) || {};
|
const { freeCollateral } = useSelector(getSubaccount, shallowEqual) || {};
|
||||||
const { dydxAddress } = useAccounts();
|
const { dydxAddress } = useAccounts();
|
||||||
|
const {
|
||||||
|
address: recipientAddress,
|
||||||
|
size,
|
||||||
|
fee,
|
||||||
|
} = useSelector(getTransferInputs, shallowEqual) || {};
|
||||||
const { transfer } = useSubaccount();
|
const { transfer } = useSubaccount();
|
||||||
const { nativeTokenBalance, usdcBalance } = useAccountBalance();
|
const { nativeTokenBalance, usdcBalance } = useAccountBalance();
|
||||||
const { selectedNetwork } = useSelectedNetwork();
|
const { selectedNetwork } = useSelectedNetwork();
|
||||||
const { tokensConfigs, usdcLabel, chainTokenLabel } = useTokenConfigs();
|
const { tokensConfigs, usdcLabel, chainTokenLabel } = useTokenConfigs();
|
||||||
|
|
||||||
const {
|
// User Input
|
||||||
address: recipientAddress,
|
const [asset, setAsset] = useState<DydxChainAsset>(selectedAsset);
|
||||||
size,
|
|
||||||
fee,
|
|
||||||
token,
|
|
||||||
} = useSelector(getTransferInputs, shallowEqual) || {};
|
|
||||||
|
|
||||||
// Form states
|
// Form states
|
||||||
const [error, setError] = useState<string>();
|
const [error, setError] = useState<string>();
|
||||||
const [isLoading, setIsLoading] = useState(false);
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
|
|
||||||
// temp fix: TODO: reset fees when changing token in Abacus
|
const balance = asset === DydxChainAsset.USDC ? freeCollateral?.current : nativeTokenBalance;
|
||||||
const [currentFee, setCurrentFee] = useState(fee);
|
const newBalance =
|
||||||
useEffect(() => {
|
asset === DydxChainAsset.USDC
|
||||||
setCurrentFee(fee);
|
? freeCollateral?.postOrder
|
||||||
}, [fee]);
|
: MustBigNumber(nativeTokenBalance)
|
||||||
|
.minus(size?.size ?? 0)
|
||||||
|
.toNumber();
|
||||||
|
const amount = asset === DydxChainAsset.USDC ? size?.usdcSize : size?.size;
|
||||||
|
|
||||||
const asset = (token ?? selectedAsset) as DydxChainAsset;
|
const showNotEnoughGasWarning = fee && asset === DydxChainAsset.USDC && usdcBalance < fee;
|
||||||
const isUSDCSelected = asset === DydxChainAsset.USDC;
|
|
||||||
const amount = isUSDCSelected ? size?.usdcSize : size?.size;
|
|
||||||
const showNotEnoughGasWarning = fee && isUSDCSelected && usdcBalance < fee;
|
|
||||||
const balance = isUSDCSelected ? freeCollateral?.current : nativeTokenBalance;
|
|
||||||
|
|
||||||
// BN
|
// BN
|
||||||
const newBalanceBN = isUSDCSelected
|
|
||||||
? MustBigNumber(freeCollateral?.postOrder)
|
|
||||||
: nativeTokenBalance.minus(size?.size ?? 0);
|
|
||||||
|
|
||||||
const amountBN = MustBigNumber(amount);
|
const amountBN = MustBigNumber(amount);
|
||||||
const balanceBN = MustBigNumber(balance);
|
const balanceBN = MustBigNumber(balance);
|
||||||
|
const newBalanceBN = MustBigNumber(newBalance);
|
||||||
const onChangeAsset = (asset: DydxChainAsset) => {
|
|
||||||
setError(undefined);
|
|
||||||
setCurrentFee(undefined);
|
|
||||||
|
|
||||||
if (asset) {
|
|
||||||
abacusStateManager.setTransferValue({
|
|
||||||
value: asset,
|
|
||||||
field: TransferInputField.token,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
abacusStateManager.setTransferValue({
|
abacusStateManager.setTransferValue({
|
||||||
@@ -115,13 +100,19 @@ export const TransferForm = ({
|
|||||||
field: TransferInputField.type,
|
field: TransferInputField.type,
|
||||||
});
|
});
|
||||||
|
|
||||||
onChangeAsset(selectedAsset);
|
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
abacusStateManager.clearTransferInputValues();
|
abacusStateManager.clearTransferInputValues();
|
||||||
};
|
};
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setError(undefined);
|
||||||
|
abacusStateManager.setTransferValue({
|
||||||
|
value: asset,
|
||||||
|
field: TransferInputField.token,
|
||||||
|
});
|
||||||
|
}, [asset]);
|
||||||
|
|
||||||
const { sanctionedAddresses } = useRestrictions();
|
const { sanctionedAddresses } = useRestrictions();
|
||||||
|
|
||||||
const isAddressValid = useMemo(
|
const isAddressValid = useMemo(
|
||||||
@@ -143,6 +134,11 @@ export const TransferForm = ({
|
|||||||
setError(undefined);
|
setError(undefined);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
// Subtract fees from amount if sending native tokens
|
||||||
|
const amountToTransfer = (
|
||||||
|
asset === DydxChainAsset.CHAINTOKEN ? amountBN.minus(fee) : amountBN
|
||||||
|
).toNumber();
|
||||||
|
|
||||||
const screenResults = await screenAddresses({
|
const screenResults = await screenAddresses({
|
||||||
addresses: [recipientAddress!, dydxAddress!],
|
addresses: [recipientAddress!, dydxAddress!],
|
||||||
});
|
});
|
||||||
@@ -161,9 +157,9 @@ export const TransferForm = ({
|
|||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
const txResponse = await transfer(
|
const txResponse = await transfer(
|
||||||
amountBN.toNumber(),
|
amountToTransfer,
|
||||||
recipientAddress as string,
|
recipientAddress as string,
|
||||||
tokensConfigs[asset]?.denom
|
tokensConfigs[asset].denom,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (txResponse?.code === 0) {
|
if (txResponse?.code === 0) {
|
||||||
@@ -204,7 +200,7 @@ export const TransferForm = ({
|
|||||||
const onChangeAmount = (value?: number) => {
|
const onChangeAmount = (value?: number) => {
|
||||||
abacusStateManager.setTransferValue({
|
abacusStateManager.setTransferValue({
|
||||||
value,
|
value,
|
||||||
field: isUSDCSelected ? TransferInputField.usdcSize : TransferInputField.size,
|
field: asset === DydxChainAsset.USDC ? TransferInputField.usdcSize : TransferInputField.size,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -230,7 +226,7 @@ export const TransferForm = ({
|
|||||||
value: DydxChainAsset.CHAINTOKEN,
|
value: DydxChainAsset.CHAINTOKEN,
|
||||||
label: (
|
label: (
|
||||||
<Styled.InlineRow>
|
<Styled.InlineRow>
|
||||||
<AssetIcon symbol={chainTokenLabel} />
|
{/* <AssetIcon symbol="DYDX" /> */}
|
||||||
{chainTokenLabel}
|
{chainTokenLabel}
|
||||||
</Styled.InlineRow>
|
</Styled.InlineRow>
|
||||||
),
|
),
|
||||||
@@ -253,15 +249,15 @@ export const TransferForm = ({
|
|||||||
key: 'amount',
|
key: 'amount',
|
||||||
label: (
|
label: (
|
||||||
<span>
|
<span>
|
||||||
{stringGetter({ key: STRING_KEYS.AVAILABLE })} <Tag>{tokensConfigs[asset]?.name}</Tag>
|
{stringGetter({ key: STRING_KEYS.AVAILABLE })} <Tag>{tokensConfigs[asset].name}</Tag>
|
||||||
</span>
|
</span>
|
||||||
),
|
),
|
||||||
value: (
|
value: (
|
||||||
<DiffOutput
|
<DiffOutput
|
||||||
type={OutputType.Asset}
|
type={OutputType.Asset}
|
||||||
value={balanceBN}
|
value={balanceBN.toString()}
|
||||||
|
newValue={newBalanceBN.toString()}
|
||||||
sign={NumberSign.Negative}
|
sign={NumberSign.Negative}
|
||||||
newValue={newBalanceBN}
|
|
||||||
hasInvalidNewValue={newBalanceBN.isNegative()}
|
hasInvalidNewValue={newBalanceBN.isNegative()}
|
||||||
withDiff={Boolean(amount && balance) && !amountBN.isNaN()}
|
withDiff={Boolean(amount && balance) && !amountBN.isNaN()}
|
||||||
/>
|
/>
|
||||||
@@ -344,8 +340,8 @@ export const TransferForm = ({
|
|||||||
|
|
||||||
<Styled.SelectMenu
|
<Styled.SelectMenu
|
||||||
label={stringGetter({ key: STRING_KEYS.ASSET })}
|
label={stringGetter({ key: STRING_KEYS.ASSET })}
|
||||||
value={token}
|
value={asset}
|
||||||
onValueChange={onChangeAsset}
|
onValueChange={setAsset}
|
||||||
disabled={isLoading}
|
disabled={isLoading}
|
||||||
>
|
>
|
||||||
{assetOptions.map(({ value, label }) => (
|
{assetOptions.map(({ value, label }) => (
|
||||||
@@ -359,16 +355,12 @@ export const TransferForm = ({
|
|||||||
type={InputType.Number}
|
type={InputType.Number}
|
||||||
onChange={({ floatValue }: NumberFormatValues) => onChangeAmount(floatValue)}
|
onChange={({ floatValue }: NumberFormatValues) => onChangeAmount(floatValue)}
|
||||||
value={amount ?? undefined}
|
value={amount ?? undefined}
|
||||||
slotRight={
|
slotRight={renderFormInputButton({
|
||||||
isUSDCSelected &&
|
label: stringGetter({ key: STRING_KEYS.MAX }),
|
||||||
balanceBN.gt(0) &&
|
isInputEmpty: size?.usdcSize == null,
|
||||||
renderFormInputButton({
|
onClear: () => onChangeAmount(undefined),
|
||||||
label: stringGetter({ key: STRING_KEYS.MAX }),
|
onClick: () => onChangeAmount(balanceBN.toNumber()),
|
||||||
isInputEmpty: size?.usdcSize == null,
|
})}
|
||||||
onClear: () => onChangeAmount(undefined),
|
|
||||||
onClick: () => onChangeAmount(balanceBN.toNumber()),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
disabled={isLoading}
|
disabled={isLoading}
|
||||||
/>
|
/>
|
||||||
</WithDetailsReceipt>
|
</WithDetailsReceipt>
|
||||||
@@ -377,7 +369,7 @@ export const TransferForm = ({
|
|||||||
<AlertMessage type={AlertType.Warning}>
|
<AlertMessage type={AlertType.Warning}>
|
||||||
{stringGetter({
|
{stringGetter({
|
||||||
key: STRING_KEYS.TRANSFER_INSUFFICIENT_GAS,
|
key: STRING_KEYS.TRANSFER_INSUFFICIENT_GAS,
|
||||||
params: { USDC_BALANCE: `(${usdcBalance} USDC)` },
|
params: { USDC_BALANCE: `(${usdcBalance})` },
|
||||||
})}
|
})}
|
||||||
</AlertMessage>
|
</AlertMessage>
|
||||||
)}
|
)}
|
||||||
@@ -387,9 +379,9 @@ export const TransferForm = ({
|
|||||||
<Styled.Footer>
|
<Styled.Footer>
|
||||||
<TransferButtonAndReceipt
|
<TransferButtonAndReceipt
|
||||||
selectedAsset={asset}
|
selectedAsset={asset}
|
||||||
fee={currentFee || undefined}
|
fees={fee || undefined}
|
||||||
isDisabled={!isAmountValid || !isAddressValid || !currentFee || isLoading}
|
isDisabled={!isAmountValid || !isAddressValid || !fee || isLoading}
|
||||||
isLoading={isLoading || Boolean(isAmountValid && isAddressValid && !currentFee)}
|
isLoading={isLoading || Boolean(isAmountValid && isAddressValid && !fee)}
|
||||||
/>
|
/>
|
||||||
</Styled.Footer>
|
</Styled.Footer>
|
||||||
</Styled.Form>
|
</Styled.Form>
|
||||||
|
|||||||
@@ -23,14 +23,14 @@ import { MustBigNumber } from '@/lib/numbers';
|
|||||||
|
|
||||||
type ElementProps = {
|
type ElementProps = {
|
||||||
selectedAsset: DydxChainAsset;
|
selectedAsset: DydxChainAsset;
|
||||||
fee?: number;
|
fees?: number;
|
||||||
isDisabled?: boolean;
|
isDisabled?: boolean;
|
||||||
isLoading?: boolean;
|
isLoading?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const TransferButtonAndReceipt = ({
|
export const TransferButtonAndReceipt = ({
|
||||||
selectedAsset,
|
selectedAsset,
|
||||||
fee,
|
fees,
|
||||||
isDisabled,
|
isDisabled,
|
||||||
isLoading,
|
isLoading,
|
||||||
}: ElementProps) => {
|
}: ElementProps) => {
|
||||||
@@ -47,46 +47,43 @@ export const TransferButtonAndReceipt = ({
|
|||||||
const { current: equity, postOrder: newEquity } = equityInfo || {};
|
const { current: equity, postOrder: newEquity } = equityInfo || {};
|
||||||
const { current: leverage, postOrder: newLeverage } = leverageInfo || {};
|
const { current: leverage, postOrder: newLeverage } = leverageInfo || {};
|
||||||
|
|
||||||
const isUSDCSelected = selectedAsset === DydxChainAsset.USDC;
|
// TODO(@aforaleka): add wallet balance for DYDX
|
||||||
|
const balance = selectedAsset === DydxChainAsset.USDC ? equity : nativeTokenBalance;
|
||||||
const balance = isUSDCSelected ? equity : nativeTokenBalance;
|
const newBalance =
|
||||||
const newNativeTokenBalance = nativeTokenBalance
|
selectedAsset === DydxChainAsset.USDC
|
||||||
.minus(size?.size ?? 0)
|
? newEquity
|
||||||
.minus(fee ?? 0) // show balance after fees for button receipt
|
: MustBigNumber(nativeTokenBalance)
|
||||||
.toNumber();
|
.minus(size?.size ?? 0)
|
||||||
|
.toNumber();
|
||||||
const newBalance = isUSDCSelected ? newEquity : newNativeTokenBalance;
|
|
||||||
|
|
||||||
const transferDetailItems = [
|
const transferDetailItems = [
|
||||||
{
|
{
|
||||||
key: 'fees',
|
key: 'fees',
|
||||||
label: (
|
label: (
|
||||||
<span>
|
<span>
|
||||||
{stringGetter({ key: STRING_KEYS.FEES })} <Tag>{tokensConfigs[selectedAsset]?.name}</Tag>
|
{stringGetter({ key: STRING_KEYS.FEES })} <Tag>{tokensConfigs[selectedAsset].name}</Tag>
|
||||||
</span>
|
</span>
|
||||||
),
|
),
|
||||||
value: <Output type={OutputType.Asset} value={fee} />,
|
value: <Output type={OutputType.Asset} value={fees} />,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'balance',
|
key: 'balance',
|
||||||
label: (
|
label: (
|
||||||
<span>
|
<span>
|
||||||
{stringGetter({ key: STRING_KEYS.BALANCE })}{' '}
|
{stringGetter({ key: STRING_KEYS.BALANCE })} <Tag>{tokensConfigs[selectedAsset].name}</Tag>
|
||||||
<Tag>{tokensConfigs[selectedAsset]?.name}</Tag>
|
|
||||||
</span>
|
</span>
|
||||||
),
|
),
|
||||||
value: (
|
value: (
|
||||||
<DiffOutput
|
<DiffOutput
|
||||||
type={OutputType.Asset}
|
type={OutputType.Asset}
|
||||||
value={balance}
|
value={balance}
|
||||||
sign={NumberSign.Negative}
|
|
||||||
newValue={newBalance}
|
newValue={newBalance}
|
||||||
hasInvalidNewValue={MustBigNumber(newBalance).isNegative()}
|
sign={NumberSign.Negative}
|
||||||
withDiff={newBalance !== null && !MustBigNumber(balance).eq(newBalance ?? 0)}
|
withDiff={Boolean(newBalance) && balance !== newBalance}
|
||||||
/>
|
/>
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
isUSDCSelected && {
|
selectedAsset === DydxChainAsset.USDC && {
|
||||||
key: 'leverage',
|
key: 'leverage',
|
||||||
label: <span>{stringGetter({ key: STRING_KEYS.LEVERAGE })}</span>,
|
label: <span>{stringGetter({ key: STRING_KEYS.LEVERAGE })}</span>,
|
||||||
value: (
|
value: (
|
||||||
|
|||||||
Reference in New Issue
Block a user