Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ce5b6d92d5 |
+3
-3
@@ -39,8 +39,8 @@
|
||||
"@cosmjs/proto-signing": "^0.31.0",
|
||||
"@cosmjs/stargate": "^0.31.0",
|
||||
"@cosmjs/tendermint-rpc": "^0.31.0",
|
||||
"@dydxprotocol/v4-abacus": "^1.1.24",
|
||||
"@dydxprotocol/v4-client-js": "^1.0.11",
|
||||
"@dydxprotocol/v4-abacus": "^1.1.16",
|
||||
"@dydxprotocol/v4-client-js": "^1.0.6",
|
||||
"@dydxprotocol/v4-localization": "^1.0.18",
|
||||
"@ethersproject/providers": "^5.7.2",
|
||||
"@js-joda/core": "^5.5.3",
|
||||
@@ -111,7 +111,7 @@
|
||||
"styled-components": "^5.3.11",
|
||||
"use-latest": "^1.2.1",
|
||||
"viem": "^1.12.2",
|
||||
"wagmi": "^1.4.12"
|
||||
"wagmi": "^1.4.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.22.5",
|
||||
|
||||
Generated
+119
-662
File diff suppressed because it is too large
Load Diff
@@ -1,9 +1,29 @@
|
||||
[
|
||||
{
|
||||
"chainId": "42161",
|
||||
"tokenAddress": "0xff970a61a04b1ca14834a43f5de4533ebddb5cc8",
|
||||
"name": "Arbitrum"
|
||||
},
|
||||
{
|
||||
"chainId": "43114",
|
||||
"tokenAddress": "0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E",
|
||||
"name": "Avalanche"
|
||||
},
|
||||
{
|
||||
"chainId": "8453",
|
||||
"tokenAddress": "0x66627F389ae46D881773B7131139b2411980E09E",
|
||||
"name": "Base"
|
||||
},
|
||||
{
|
||||
"chainId": "1",
|
||||
"tokenAddress": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
|
||||
"name": "Ethereum"
|
||||
},
|
||||
{
|
||||
"chainId": "10",
|
||||
"tokenAddress": "0x7F5c764cBc14f9669B88837ca1490cCa17c31607",
|
||||
"name": "OP Mainnet"
|
||||
},
|
||||
{
|
||||
"chainId": "421613",
|
||||
"tokenAddress": "0xfd064a18f3bf249cf1f87fc203e90d8f650f2d63",
|
||||
|
||||
@@ -31,12 +31,10 @@ type ElementProps<TabItemsValue> = {
|
||||
};
|
||||
|
||||
type StyleProps = {
|
||||
className?: string;
|
||||
fullWidthTabs?: boolean;
|
||||
className?: string;
|
||||
};
|
||||
|
||||
export type CollapsibleTabsProps<TabItemsValue> = ElementProps<TabItemsValue> & StyleProps;
|
||||
|
||||
export const CollapsibleTabs = <TabItemsValue extends string>({
|
||||
defaultValue,
|
||||
items,
|
||||
@@ -45,9 +43,8 @@ export const CollapsibleTabs = <TabItemsValue extends string>({
|
||||
onOpenChange,
|
||||
|
||||
fullWidthTabs,
|
||||
|
||||
className,
|
||||
}: CollapsibleTabsProps<TabItemsValue>) => {
|
||||
}: ElementProps<TabItemsValue> & StyleProps) => {
|
||||
const [value, setValue] = useState(defaultValue);
|
||||
|
||||
const currentItem = items.find((item) => item.value === value);
|
||||
@@ -89,8 +86,8 @@ export const CollapsibleTabs = <TabItemsValue extends string>({
|
||||
</Styled.Header>
|
||||
|
||||
<Styled.CollapsibleContent>
|
||||
{items.map(({ asChild, value, content }) => (
|
||||
<Styled.TabsContent key={value} asChild={asChild} value={value}>
|
||||
{items.map(({ value, content }) => (
|
||||
<Styled.TabsContent key={value} value={value}>
|
||||
{content}
|
||||
</Styled.TabsContent>
|
||||
))}
|
||||
@@ -222,6 +219,7 @@ Styled.Header = styled.header`
|
||||
|
||||
Styled.CollapsibleContent = styled(CollapsibleContent)`
|
||||
${layoutMixins.stack}
|
||||
${layoutMixins.perspectiveArea}
|
||||
|
||||
box-shadow: none;
|
||||
`;
|
||||
|
||||
@@ -198,6 +198,7 @@ Styled.InputContainer = styled.div`
|
||||
border-radius: inherit;
|
||||
|
||||
input {
|
||||
user-select: all;
|
||||
flex: 1;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
@@ -21,7 +21,6 @@ export type TabItem<TabItemsValue> = {
|
||||
content?: React.ReactNode;
|
||||
subitems?: TabItem<TabItemsValue>[];
|
||||
customTrigger?: ReactNode;
|
||||
asChild?: boolean;
|
||||
};
|
||||
|
||||
type ElementProps<TabItemsValue> = {
|
||||
@@ -42,8 +41,6 @@ type StyleProps = {
|
||||
className?: string;
|
||||
};
|
||||
|
||||
export type TabsProps<TabItemsValue> = ElementProps<TabItemsValue> & StyleProps;
|
||||
|
||||
export const Tabs = <TabItemsValue extends string>({
|
||||
defaultValue,
|
||||
value,
|
||||
@@ -110,10 +107,9 @@ export const Tabs = <TabItemsValue extends string>({
|
||||
sharedContent
|
||||
) : (
|
||||
<Styled.Stack>
|
||||
{items.map(({ asChild, value, content, forceMount }) => (
|
||||
{items.map(({ value, content, forceMount }) => (
|
||||
<Styled.Content
|
||||
key={value}
|
||||
asChild={asChild}
|
||||
value={value}
|
||||
forceMount={forceMount}
|
||||
$hide={forceMount && currentItem?.value !== value}
|
||||
@@ -246,6 +242,7 @@ Styled.Trigger = styled(Trigger)<{ $withBorders?: boolean }>`
|
||||
|
||||
Styled.Stack = styled.div`
|
||||
${layoutMixins.stack}
|
||||
${layoutMixins.perspectiveArea}
|
||||
|
||||
box-shadow: none;
|
||||
`;
|
||||
|
||||
@@ -122,15 +122,9 @@ export type NotificationDisplayData = {
|
||||
toastDuration?: number;
|
||||
};
|
||||
|
||||
export enum TransferNotificationTypes {
|
||||
Withdrawal = 'withdrawal',
|
||||
Deposit = 'deposit',
|
||||
}
|
||||
|
||||
// Notification types
|
||||
export type TransferNotifcation = {
|
||||
txHash: string;
|
||||
type?: TransferNotificationTypes;
|
||||
toChainId?: string;
|
||||
fromChainId?: string;
|
||||
toAmount?: number;
|
||||
|
||||
@@ -20,7 +20,6 @@ import {
|
||||
type NotificationTypeConfig,
|
||||
NotificationType,
|
||||
DEFAULT_TOAST_AUTO_CLOSE_MS,
|
||||
TransferNotificationTypes,
|
||||
} from '@/constants/notifications';
|
||||
|
||||
import { useSelectedNetwork, useStringGetter } from '@/hooks';
|
||||
@@ -153,20 +152,20 @@ export const notificationTypes: NotificationTypeConfig[] = [
|
||||
|
||||
useEffect(() => {
|
||||
for (const transfer of transferNotifications) {
|
||||
const { fromChainId, status, txHash, toAmount, type } = transfer;
|
||||
const { fromChainId, status, txHash, toAmount } = transfer;
|
||||
const isFinished = Boolean(status) && status?.squidTransactionStatus !== 'ongoing';
|
||||
const icon = <Icon iconName={isFinished ? IconName.Transfer : IconName.Clock} />;
|
||||
|
||||
const transferType = type ??
|
||||
const type =
|
||||
fromChainId === ENVIRONMENT_CONFIG_MAP[selectedNetwork].dydxChainId
|
||||
? TransferNotificationTypes.Withdrawal
|
||||
: TransferNotificationTypes.Deposit;
|
||||
? 'withdrawal'
|
||||
: 'deposit';
|
||||
|
||||
const title = stringGetter({
|
||||
key: {
|
||||
deposit: isFinished ? STRING_KEYS.DEPOSIT : STRING_KEYS.DEPOSIT_IN_PROGRESS,
|
||||
withdrawal: isFinished ? STRING_KEYS.WITHDRAW : STRING_KEYS.WITHDRAW_IN_PROGRESS,
|
||||
}[transferType],
|
||||
}[type],
|
||||
});
|
||||
|
||||
const toChainEta = status?.toChain?.chainData?.estimatedRouteDuration || 0;
|
||||
@@ -191,7 +190,7 @@ export const notificationTypes: NotificationTypeConfig[] = [
|
||||
slotIcon={icon}
|
||||
slotTitle={title}
|
||||
transfer={transfer}
|
||||
type={transferType}
|
||||
type={type}
|
||||
triggeredAt={transfer.triggeredAt}
|
||||
notification={notification}
|
||||
/>
|
||||
|
||||
@@ -31,7 +31,6 @@ import { log } from '@/lib/telemetry';
|
||||
import { useAccounts } from './useAccounts';
|
||||
import { useTokenConfigs } from './useTokenConfigs';
|
||||
import { useDydxClient } from './useDydxClient';
|
||||
import { hashFromTx } from '@/lib/hashfromTx';
|
||||
|
||||
type SubaccountContextType = ReturnType<typeof useSubaccountContext>;
|
||||
const SubaccountContext = createContext<SubaccountContextType>({} as SubaccountContextType);
|
||||
@@ -294,29 +293,12 @@ export const useSubaccountContext = ({ localDydxWallet }: { localDydxWallet?: Lo
|
||||
);
|
||||
|
||||
const sendSquidWithdraw = useCallback(
|
||||
async (amount: number, payload: string, isCctp?: boolean) => {
|
||||
|
||||
const cctpWithdraw = () => {
|
||||
return new Promise<string>((resolve, reject) =>
|
||||
abacusStateManager.cctpWithdraw((success, error, data) => {
|
||||
const parsedData = JSON.parse(data);
|
||||
if (success && parsedData?.code == 0) {
|
||||
resolve(parsedData?.transactionHash);
|
||||
} else {
|
||||
reject(error);
|
||||
}
|
||||
})
|
||||
)
|
||||
}
|
||||
if (isCctp) {
|
||||
return await cctpWithdraw();
|
||||
}
|
||||
|
||||
async (amount: number, payload: string) => {
|
||||
if (!subaccountClient) {
|
||||
return;
|
||||
}
|
||||
const tx = await sendSquidWithdrawFromSubaccount({ subaccountClient, amount, payload });
|
||||
return hashFromTx(tx?.hash);
|
||||
|
||||
return await sendSquidWithdrawFromSubaccount({ subaccountClient, amount, payload });
|
||||
},
|
||||
[subaccountClient, sendSquidWithdrawFromSubaccount]
|
||||
);
|
||||
|
||||
@@ -2,7 +2,6 @@ import Abacus, { type Nullable } from '@dydxprotocol/v4-abacus';
|
||||
import Long from 'long';
|
||||
import type { IndexedTx } from '@cosmjs/stargate';
|
||||
import { GAS_MULTIPLIER, encodeJson } from '@dydxprotocol/v4-client-js';
|
||||
import { EncodeObject } from '@cosmjs/proto-signing';
|
||||
|
||||
import {
|
||||
CompositeClient,
|
||||
@@ -42,7 +41,6 @@ import { openDialog } from '@/state/dialogs';
|
||||
import { StatefulOrderError } from '../errors';
|
||||
import { bytesToBigInt } from '../numbers';
|
||||
import { log } from '../telemetry';
|
||||
import { hashFromTx } from '../hashfromTx';
|
||||
|
||||
class DydxChainTransactions implements AbacusDYDXChainTransactionsProtocol {
|
||||
private compositeClient: CompositeClient | undefined;
|
||||
@@ -65,13 +63,9 @@ class DydxChainTransactions implements AbacusDYDXChainTransactionsProtocol {
|
||||
}
|
||||
|
||||
setNobleWallet(nobleWallet: LocalWallet) {
|
||||
try {
|
||||
this.nobleWallet = nobleWallet;
|
||||
if (this.nobleClient) {
|
||||
this.nobleClient.connect(nobleWallet);
|
||||
}
|
||||
} catch (e) {
|
||||
log('DydxChainTransactions/setNobleWallet', e);
|
||||
this.nobleWallet = nobleWallet;
|
||||
if (this.nobleClient) {
|
||||
this.nobleClient.connect(nobleWallet);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -118,15 +112,10 @@ class DydxChainTransactions implements AbacusDYDXChainTransactionsProtocol {
|
||||
|
||||
this.compositeClient = compositeClient;
|
||||
|
||||
try {
|
||||
if (nobleValidatorUrl) {
|
||||
this.nobleClient = new NobleClient(nobleValidatorUrl);
|
||||
if (this.nobleWallet) await this.nobleClient.connect(this.nobleWallet);
|
||||
}
|
||||
} catch (e) {
|
||||
log('DydxChainTransactions/connectNetwork/NobleClient', e);
|
||||
if (nobleValidatorUrl) {
|
||||
this.nobleClient = new NobleClient(nobleValidatorUrl);
|
||||
if (this.nobleWallet) await this.nobleClient.connect(this.nobleWallet);
|
||||
}
|
||||
|
||||
// Dispatch custom event to notify other parts of the app that the network has been connected
|
||||
const customEvent = new CustomEvent('abacus:connectNetwork', {
|
||||
detail: parsedParams,
|
||||
@@ -391,90 +380,6 @@ class DydxChainTransactions implements AbacusDYDXChainTransactionsProtocol {
|
||||
}
|
||||
}
|
||||
|
||||
async withdrawToNobleIBC(
|
||||
params: {
|
||||
subaccountNumber: number,
|
||||
amount: string,
|
||||
ibcPayload: string,
|
||||
}
|
||||
): Promise<string> {
|
||||
if (!this.compositeClient || !this.localWallet) {
|
||||
throw new Error('Missing compositeClient or localWallet');
|
||||
}
|
||||
|
||||
const { subaccountNumber, amount, ibcPayload } = params ?? {};
|
||||
const parsedIbcPayload: {
|
||||
msgTypeUrl: string,
|
||||
msg: any,
|
||||
} = ibcPayload ? JSON.parse(ibcPayload) : undefined;
|
||||
|
||||
try {
|
||||
const msg = this.compositeClient.withdrawFromSubaccountMessage(
|
||||
new SubaccountClient(this.localWallet, subaccountNumber),
|
||||
parseFloat(amount).toFixed(this.compositeClient.validatorClient.config.denoms.USDC_DECIMALS)
|
||||
);
|
||||
const ibcMsg: EncodeObject = {
|
||||
typeUrl: parsedIbcPayload.msgTypeUrl,
|
||||
value: parsedIbcPayload.msg,
|
||||
};
|
||||
|
||||
const tx = await this.compositeClient.send(
|
||||
this.localWallet,
|
||||
() => Promise.resolve([msg, ibcMsg]),
|
||||
false
|
||||
);
|
||||
|
||||
return JSON.stringify({
|
||||
txHash: hashFromTx(tx?.hash)
|
||||
});
|
||||
} catch (error) {
|
||||
log('DydxChainTransactions/withdrawToNobleIBC', error);
|
||||
|
||||
return JSON.stringify({
|
||||
error,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
async cctpWithdraw(params: {
|
||||
typeUrl: string,
|
||||
value: any,
|
||||
}): Promise<string> {
|
||||
if (!this.nobleClient?.isConnected) {
|
||||
throw new Error('Missing nobleClient or localWallet');
|
||||
}
|
||||
|
||||
try {
|
||||
const ibcMsg = {
|
||||
typeUrl: params.typeUrl, // '/circle.cctp.v1.MsgDepositForBurn',
|
||||
value: params.value,
|
||||
};
|
||||
const fee = await this.nobleClient.simulateTransaction([ibcMsg]);
|
||||
|
||||
// take out fee from amount before sweeping
|
||||
const amount = parseInt(ibcMsg.value.amount, 10) -
|
||||
Math.floor(parseInt(fee.amount[0].amount, 10) * GAS_MULTIPLIER);
|
||||
|
||||
if (amount <= 0) {
|
||||
throw new Error('noble balance does not cover fees');
|
||||
}
|
||||
|
||||
ibcMsg.value.amount = amount.toString();
|
||||
|
||||
const tx = await this.nobleClient.send([ibcMsg]);
|
||||
|
||||
const parsedTx = this.parseToPrimitives(tx);
|
||||
|
||||
return JSON.stringify(parsedTx);
|
||||
} catch (error) {
|
||||
log('DydxChainTransactions/cctpWithdraw', error);
|
||||
|
||||
return JSON.stringify({
|
||||
error,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
async transaction(
|
||||
type: TransactionTypes,
|
||||
paramsInJson: Abacus.Nullable<string>,
|
||||
@@ -509,17 +414,6 @@ class DydxChainTransactions implements AbacusDYDXChainTransactionsProtocol {
|
||||
callback(result);
|
||||
break;
|
||||
}
|
||||
case TransactionType.WithdrawToNobleIBC: {
|
||||
const result = await this.withdrawToNobleIBC(params);
|
||||
callback(result);
|
||||
break;
|
||||
}
|
||||
case TransactionType.CctpWithdraw: {
|
||||
const result = await this.cctpWithdraw(params);
|
||||
callback(result);
|
||||
break;
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -85,7 +85,7 @@ class AbacusStateManager {
|
||||
|
||||
const appConfigs = AbacusAppConfig.Companion.forWeb;
|
||||
if (!isMainnet || testFlags.withCCTP)
|
||||
appConfigs.squidVersion = AbacusAppConfig.SquidVersion.V2;
|
||||
appConfigs.squidVersion = AbacusAppConfig.SquidVersion.V2DepositOnly;
|
||||
|
||||
this.stateManager = new AsyncAbacusStateManager(
|
||||
'',
|
||||
@@ -262,14 +262,6 @@ class AbacusStateManager {
|
||||
) => void
|
||||
) => this.stateManager.cancelOrder(orderId, callback);
|
||||
|
||||
cctpWithdraw = (
|
||||
callback: (
|
||||
success: boolean,
|
||||
parsingError: Nullable<ParsingError>,
|
||||
data: string,
|
||||
) => void
|
||||
): void => this.stateManager.commitCCTPWithdraw(callback);
|
||||
|
||||
// ------ Utils ------ //
|
||||
getHistoricalPnlPeriod = (): Nullable<HistoricalPnlPeriods> =>
|
||||
this.stateManager.historicalPnlPeriod;
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
export const hashFromTx = (
|
||||
txHash: string | Uint8Array
|
||||
): string => `0x${Buffer.from(txHash).toString('hex')}`;
|
||||
+116
-131
@@ -1,7 +1,8 @@
|
||||
import { useMemo, useState } from 'react';
|
||||
import { useState } from 'react';
|
||||
import { shallowEqual, useSelector } from 'react-redux';
|
||||
import styled, { type AnyStyledComponent } from 'styled-components';
|
||||
|
||||
import { AbacusOrderStatus } from '@/constants/abacus';
|
||||
import { STRING_KEYS } from '@/constants/localization';
|
||||
|
||||
import { useBreakpoints, useStringGetter } from '@/hooks';
|
||||
@@ -27,6 +28,7 @@ import {
|
||||
getCurrentMarketTradeInfoNumbers,
|
||||
getHasUnseenFillUpdates,
|
||||
getHasUnseenOrderUpdates,
|
||||
getLatestOrderStatus,
|
||||
getTradeInfoNumbers,
|
||||
} from '@/state/accountSelectors';
|
||||
|
||||
@@ -80,142 +82,125 @@ export const HorizontalPanel = ({ isOpen = true, setIsOpen }: ElementProps) => {
|
||||
showCurrentMarket ? numOpenOrders : numTotalOpenOrders
|
||||
);
|
||||
|
||||
const tabItems = useMemo(
|
||||
() => [
|
||||
{
|
||||
asChild: true,
|
||||
value: InfoSection.Position,
|
||||
label: stringGetter({
|
||||
key: showCurrentMarket ? STRING_KEYS.POSITION : STRING_KEYS.POSITIONS,
|
||||
}),
|
||||
const tabItems = [
|
||||
{
|
||||
value: InfoSection.Position,
|
||||
label: stringGetter({
|
||||
key: showCurrentMarket ? STRING_KEYS.POSITION : STRING_KEYS.POSITIONS,
|
||||
}),
|
||||
|
||||
tag: showCurrentMarket ? null : shortenNumberForDisplay(numTotalPositions),
|
||||
tag: showCurrentMarket ? null : shortenNumberForDisplay(numTotalPositions),
|
||||
|
||||
content: showCurrentMarket ? (
|
||||
<PositionInfo showNarrowVariation={isTablet} />
|
||||
) : (
|
||||
<PositionsTable
|
||||
columnKeys={
|
||||
isTablet
|
||||
? [
|
||||
PositionsTableColumnKey.Details,
|
||||
PositionsTableColumnKey.IndexEntry,
|
||||
PositionsTableColumnKey.PnL,
|
||||
]
|
||||
: [
|
||||
PositionsTableColumnKey.Market,
|
||||
PositionsTableColumnKey.Side,
|
||||
PositionsTableColumnKey.Size,
|
||||
PositionsTableColumnKey.Leverage,
|
||||
PositionsTableColumnKey.LiquidationAndOraclePrice,
|
||||
PositionsTableColumnKey.UnrealizedPnl,
|
||||
PositionsTableColumnKey.RealizedPnl,
|
||||
PositionsTableColumnKey.AverageOpenAndClose,
|
||||
]
|
||||
}
|
||||
onNavigate={() => setView(PanelView.CurrentMarket)}
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
asChild: true,
|
||||
value: InfoSection.Orders,
|
||||
label: stringGetter({ key: STRING_KEYS.ORDERS }),
|
||||
content: showCurrentMarket ? (
|
||||
<PositionInfo showNarrowVariation={isTablet} />
|
||||
) : (
|
||||
<PositionsTable
|
||||
columnKeys={
|
||||
isTablet
|
||||
? [
|
||||
PositionsTableColumnKey.Details,
|
||||
PositionsTableColumnKey.IndexEntry,
|
||||
PositionsTableColumnKey.PnL,
|
||||
]
|
||||
: [
|
||||
PositionsTableColumnKey.Market,
|
||||
PositionsTableColumnKey.Side,
|
||||
PositionsTableColumnKey.Size,
|
||||
PositionsTableColumnKey.Leverage,
|
||||
PositionsTableColumnKey.LiquidationAndOraclePrice,
|
||||
PositionsTableColumnKey.UnrealizedPnl,
|
||||
PositionsTableColumnKey.RealizedPnl,
|
||||
PositionsTableColumnKey.AverageOpenAndClose,
|
||||
]
|
||||
}
|
||||
onNavigate={() => setView(PanelView.CurrentMarket)}
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
value: InfoSection.Orders,
|
||||
label: stringGetter({ key: STRING_KEYS.ORDERS }),
|
||||
|
||||
slotRight: isWaitingForOrderToIndex ? (
|
||||
<Styled.LoadingSpinner />
|
||||
) : (
|
||||
ordersTagNumber && (
|
||||
<Tag type={TagType.Number} isHighlighted={hasUnseenOrderUpdates}>
|
||||
{ordersTagNumber}
|
||||
</Tag>
|
||||
)
|
||||
),
|
||||
|
||||
content: (
|
||||
<OrdersTable
|
||||
currentMarket={showCurrentMarket ? currentMarketId : undefined}
|
||||
columnKeys={
|
||||
isTablet
|
||||
? [OrdersTableColumnKey.StatusFill, OrdersTableColumnKey.PriceType]
|
||||
: [
|
||||
!showCurrentMarket && OrdersTableColumnKey.Market,
|
||||
OrdersTableColumnKey.Status,
|
||||
OrdersTableColumnKey.Side,
|
||||
OrdersTableColumnKey.AmountFill,
|
||||
OrdersTableColumnKey.Price,
|
||||
OrdersTableColumnKey.Trigger,
|
||||
OrdersTableColumnKey.GoodTil,
|
||||
!isAccountViewOnly && OrdersTableColumnKey.Actions,
|
||||
].filter(isTruthy)
|
||||
}
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
asChild: true,
|
||||
value: InfoSection.Fills,
|
||||
label: stringGetter({ key: STRING_KEYS.FILLS }),
|
||||
|
||||
slotRight: fillsTagNumber && (
|
||||
<Tag type={TagType.Number} isHighlighted={hasUnseenFillUpdates}>
|
||||
{fillsTagNumber}
|
||||
slotRight: isWaitingForOrderToIndex ? (
|
||||
<Styled.LoadingSpinner />
|
||||
) : (
|
||||
ordersTagNumber && (
|
||||
<Tag type={TagType.Number} isHighlighted={hasUnseenOrderUpdates}>
|
||||
{ordersTagNumber}
|
||||
</Tag>
|
||||
),
|
||||
)
|
||||
),
|
||||
|
||||
content: (
|
||||
<FillsTable
|
||||
currentMarket={showCurrentMarket ? currentMarketId : undefined}
|
||||
columnKeys={
|
||||
isTablet
|
||||
? [
|
||||
FillsTableColumnKey.Time,
|
||||
FillsTableColumnKey.TypeAmount,
|
||||
FillsTableColumnKey.PriceFee,
|
||||
]
|
||||
: [
|
||||
!showCurrentMarket && FillsTableColumnKey.Market,
|
||||
FillsTableColumnKey.Time,
|
||||
FillsTableColumnKey.Type,
|
||||
FillsTableColumnKey.Side,
|
||||
FillsTableColumnKey.AmountTag,
|
||||
FillsTableColumnKey.Price,
|
||||
FillsTableColumnKey.TotalFee,
|
||||
FillsTableColumnKey.Liquidity,
|
||||
].filter(isTruthy)
|
||||
}
|
||||
columnWidths={{
|
||||
[FillsTableColumnKey.TypeAmount]: '100%',
|
||||
}}
|
||||
/>
|
||||
),
|
||||
},
|
||||
// TODO - TRCL-1693 - re-enable when funding payments are supported
|
||||
// {
|
||||
// value: InfoSection.Payments,
|
||||
// label: stringGetter({ key: STRING_KEYS.PAYMENTS }),
|
||||
content: (
|
||||
<OrdersTable
|
||||
currentMarket={showCurrentMarket ? currentMarketId : undefined}
|
||||
columnKeys={
|
||||
isTablet
|
||||
? [OrdersTableColumnKey.StatusFill, OrdersTableColumnKey.PriceType]
|
||||
: [
|
||||
!showCurrentMarket && OrdersTableColumnKey.Market,
|
||||
OrdersTableColumnKey.Status,
|
||||
OrdersTableColumnKey.Side,
|
||||
OrdersTableColumnKey.AmountFill,
|
||||
OrdersTableColumnKey.Price,
|
||||
OrdersTableColumnKey.Trigger,
|
||||
OrdersTableColumnKey.GoodTil,
|
||||
!isAccountViewOnly && OrdersTableColumnKey.Actions,
|
||||
].filter(isTruthy)
|
||||
}
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
value: InfoSection.Fills,
|
||||
label: stringGetter({ key: STRING_KEYS.FILLS }),
|
||||
|
||||
// tag: shortenNumberForDisplay(
|
||||
// showCurrentMarket ? numFundingPayments : numTotalFundingPayments
|
||||
// ),
|
||||
// content: (
|
||||
// <FundingPaymentsTable currentMarket={showCurrentMarket ? currentMarket?.id : undefined} />
|
||||
// ),
|
||||
// },
|
||||
],
|
||||
[
|
||||
stringGetter,
|
||||
currentMarketId,
|
||||
showCurrentMarket,
|
||||
isTablet,
|
||||
isWaitingForOrderToIndex,
|
||||
isAccountViewOnly,
|
||||
ordersTagNumber,
|
||||
fillsTagNumber,
|
||||
hasUnseenFillUpdates,
|
||||
hasUnseenOrderUpdates,
|
||||
]
|
||||
);
|
||||
slotRight: fillsTagNumber && (
|
||||
<Tag type={TagType.Number} isHighlighted={hasUnseenFillUpdates}>
|
||||
{fillsTagNumber}
|
||||
</Tag>
|
||||
),
|
||||
|
||||
content: (
|
||||
<FillsTable
|
||||
currentMarket={showCurrentMarket ? currentMarketId : undefined}
|
||||
columnKeys={
|
||||
isTablet
|
||||
? [
|
||||
FillsTableColumnKey.Time,
|
||||
FillsTableColumnKey.TypeAmount,
|
||||
FillsTableColumnKey.PriceFee,
|
||||
]
|
||||
: [
|
||||
!showCurrentMarket && FillsTableColumnKey.Market,
|
||||
FillsTableColumnKey.Time,
|
||||
FillsTableColumnKey.Type,
|
||||
FillsTableColumnKey.Side,
|
||||
FillsTableColumnKey.AmountTag,
|
||||
FillsTableColumnKey.Price,
|
||||
FillsTableColumnKey.TotalFee,
|
||||
FillsTableColumnKey.Liquidity,
|
||||
].filter(isTruthy)
|
||||
}
|
||||
columnWidths={{
|
||||
[FillsTableColumnKey.TypeAmount]: '100%',
|
||||
}}
|
||||
/>
|
||||
),
|
||||
},
|
||||
// TODO - TRCL-1693 - re-enable when funding payments are supported
|
||||
// {
|
||||
// value: InfoSection.Payments,
|
||||
// label: stringGetter({ key: STRING_KEYS.PAYMENTS }),
|
||||
|
||||
// tag: shortenNumberForDisplay(
|
||||
// showCurrentMarket ? numFundingPayments : numTotalFundingPayments
|
||||
// ),
|
||||
// content: (
|
||||
// <FundingPaymentsTable currentMarket={showCurrentMarket ? currentMarket?.id : undefined} />
|
||||
// ),
|
||||
// },
|
||||
];
|
||||
|
||||
return isTablet ? (
|
||||
<MobileTabs defaultValue={InfoSection.Position} items={tabItems} withBorders={false} />
|
||||
|
||||
@@ -877,6 +877,11 @@ export const layoutMixins: Record<
|
||||
}
|
||||
`,
|
||||
|
||||
perspectiveArea: css`
|
||||
perspective: 100rem;
|
||||
transform-style: preserve-3d;
|
||||
`,
|
||||
|
||||
absolute: css`
|
||||
position: absolute;
|
||||
top: 0;
|
||||
|
||||
@@ -63,6 +63,7 @@ Styled.AccountInfoSectionContainer = styled.div<{ showAccountInfo?: boolean }>`
|
||||
${layoutMixins.column}
|
||||
height: var(--account-info-section-height);
|
||||
min-height: var(--account-info-section-height);
|
||||
overflow-x: clip;
|
||||
|
||||
${({ showAccountInfo }) =>
|
||||
!showAccountInfo &&
|
||||
|
||||
@@ -203,6 +203,7 @@ const Styled: Record<string, AnyStyledComponent> = {};
|
||||
|
||||
Styled.Stack = styled.div`
|
||||
${layoutMixins.stack}
|
||||
${layoutMixins.perspectiveArea}
|
||||
`;
|
||||
|
||||
Styled.CornerButton = styled(Button)`
|
||||
@@ -292,14 +293,7 @@ Styled.TransferButtons = styled.div`
|
||||
|
||||
Styled.ConnectedAccountInfoContainer = styled.div<{ $showHeader?: boolean }>`
|
||||
${layoutMixins.column}
|
||||
|
||||
@media ${breakpoints.notTablet} {
|
||||
${layoutMixins.withOuterAndInnerBorders}
|
||||
}
|
||||
|
||||
@media ${breakpoints.tablet} {
|
||||
${layoutMixins.withInnerBorder}
|
||||
}
|
||||
${layoutMixins.withOuterAndInnerBorders}
|
||||
|
||||
${({ $showHeader }) =>
|
||||
$showHeader &&
|
||||
|
||||
@@ -213,8 +213,13 @@ Styled.MarketDetails = styled.div`
|
||||
`;
|
||||
|
||||
Styled.Header = styled.header`
|
||||
/* max-width: fit-content; */
|
||||
|
||||
${layoutMixins.column}
|
||||
gap: 1.25rem;
|
||||
|
||||
position: sticky;
|
||||
bottom: 3rem;
|
||||
`;
|
||||
|
||||
Styled.WrapRow = styled.div`
|
||||
|
||||
@@ -453,6 +453,13 @@ Styled.Actions = styled.footer`
|
||||
> :last-child {
|
||||
flex: 2;
|
||||
}
|
||||
|
||||
position: sticky;
|
||||
bottom: clamp(0.5rem, 7.5%, 2rem);
|
||||
|
||||
@media ${breakpoints.tablet} {
|
||||
bottom: 0;
|
||||
}
|
||||
`;
|
||||
|
||||
Styled.Output = styled(Output)<{ sign: NumberSign; smallText?: boolean; margin?: string }>`
|
||||
@@ -507,7 +514,6 @@ Styled.PositionInfo = styled.div`
|
||||
|
||||
Styled.DetachedSection = styled(DetachedSection)`
|
||||
padding: 0 1.5rem;
|
||||
position: relative;
|
||||
`;
|
||||
|
||||
Styled.DetachedScrollableSection = styled(DetachedScrollableSection)`
|
||||
|
||||
@@ -82,6 +82,7 @@ const Styled: Record<string, AnyStyledComponent> = {};
|
||||
|
||||
Styled.PriceChart = styled.div<{ isChartReady?: boolean }>`
|
||||
${layoutMixins.stack}
|
||||
${layoutMixins.perspectiveArea}
|
||||
|
||||
height: 100%;
|
||||
|
||||
|
||||
@@ -57,6 +57,7 @@ export const TokenSelectMenu = ({ selectedToken, onSelectToken }: ElementProps)
|
||||
<Tag>{type === TransferType.deposit ? 'USDC' : selectedToken?.symbol}</Tag>
|
||||
</>
|
||||
),
|
||||
tooltip: 'swap',
|
||||
},
|
||||
]}
|
||||
>
|
||||
|
||||
@@ -10,7 +10,7 @@ import { AlertType } from '@/constants/alerts';
|
||||
import { ButtonSize } from '@/constants/buttons';
|
||||
import { STRING_KEYS } from '@/constants/localization';
|
||||
import { ENVIRONMENT_CONFIG_MAP } from '@/constants/networks';
|
||||
import { NotificationStatus, TransferNotificationTypes } from '@/constants/notifications';
|
||||
import { NotificationStatus } from '@/constants/notifications';
|
||||
import { NumberSign } from '@/constants/numbers';
|
||||
|
||||
import {
|
||||
@@ -45,7 +45,6 @@ import { getTransferInputs } from '@/state/inputsSelectors';
|
||||
|
||||
import abacusStateManager from '@/lib/abacus';
|
||||
import { MustBigNumber } from '@/lib/numbers';
|
||||
import { getNobleChainId } from '@/lib/squid';
|
||||
|
||||
import { TokenSelectMenu } from './TokenSelectMenu';
|
||||
import { WithdrawButtonAndReceipt } from './WithdrawForm/WithdrawButtonAndReceipt';
|
||||
@@ -168,16 +167,16 @@ export const WithdrawForm = () => {
|
||||
})
|
||||
);
|
||||
} else {
|
||||
const txHash = await sendSquidWithdraw(debouncedAmountBN.toNumber(), requestPayload.data, isCctp);
|
||||
if (txHash) {
|
||||
const txHash = await sendSquidWithdraw(debouncedAmountBN.toNumber(), requestPayload.data);
|
||||
if (txHash?.hash) {
|
||||
const hash = `0x${Buffer.from(txHash.hash).toString('hex')}`;
|
||||
addTransferNotification({
|
||||
txHash: txHash,
|
||||
type: TransferNotificationTypes.Withdrawal,
|
||||
fromChainId: !isCctp ? ENVIRONMENT_CONFIG_MAP[selectedNetwork].dydxChainId : getNobleChainId(),
|
||||
txHash: hash,
|
||||
fromChainId: ENVIRONMENT_CONFIG_MAP[selectedNetwork].dydxChainId,
|
||||
toChainId: chainIdStr || undefined,
|
||||
toAmount: debouncedAmountBN.toNumber(),
|
||||
triggeredAt: Date.now(),
|
||||
isCctp,
|
||||
notificationStatus: NotificationStatus.Triggered,
|
||||
});
|
||||
abacusStateManager.clearTransferInputValues();
|
||||
setWithdrawAmount('');
|
||||
|
||||
@@ -12,11 +12,10 @@ import { LoadingSpinner } from '@/components/Loading/LoadingSpinner';
|
||||
import { layoutMixins } from '@/styles/layoutMixins';
|
||||
import { STRING_KEYS } from '@/constants/localization';
|
||||
import { ENVIRONMENT_CONFIG_MAP } from '@/constants/networks';
|
||||
import { TransferNotificationTypes } from '@/constants/notifications';
|
||||
|
||||
type ElementProps = {
|
||||
status?: StatusResponse;
|
||||
type: TransferNotificationTypes;
|
||||
type: 'withdrawal' | 'deposit';
|
||||
};
|
||||
|
||||
type StyleProps = {
|
||||
@@ -47,13 +46,11 @@ export const TransferStatusSteps = ({ className, status, type }: ElementProps &
|
||||
{
|
||||
label: stringGetter({
|
||||
key:
|
||||
type === TransferNotificationTypes.Deposit
|
||||
? STRING_KEYS.INITIATED_DEPOSIT
|
||||
: STRING_KEYS.INITIATED_WITHDRAWAL,
|
||||
type === 'deposit' ? STRING_KEYS.INITIATED_DEPOSIT : STRING_KEYS.INITIATED_WITHDRAWAL,
|
||||
}),
|
||||
step: TransferStatusStep.FromChain,
|
||||
link:
|
||||
type === TransferNotificationTypes.Deposit
|
||||
link:
|
||||
type === 'deposit'
|
||||
? status?.fromChain?.transactionUrl
|
||||
: routeStatus?.[0]?.chainId === dydxChainId && routeStatus[0].txHash
|
||||
? `${mintscanTxUrl?.replace('{tx_hash}', routeStatus[0].txHash.replace('0x', ''))}`
|
||||
@@ -66,20 +63,14 @@ export const TransferStatusSteps = ({ className, status, type }: ElementProps &
|
||||
},
|
||||
{
|
||||
label: stringGetter({
|
||||
key:
|
||||
type === TransferNotificationTypes.Deposit
|
||||
? STRING_KEYS.DEPOSIT_TO_CHAIN
|
||||
: STRING_KEYS.WITHDRAW_TO_CHAIN,
|
||||
key: type === 'deposit' ? STRING_KEYS.DEPOSIT_TO_CHAIN : STRING_KEYS.WITHDRAW_TO_CHAIN,
|
||||
params: {
|
||||
CHAIN:
|
||||
type === TransferNotificationTypes.Deposit
|
||||
? 'dYdX'
|
||||
: status?.toChain?.chainData?.chainName,
|
||||
CHAIN: type === 'deposit' ? 'dYdX' : status?.toChain?.chainData?.chainName,
|
||||
},
|
||||
}),
|
||||
step: TransferStatusStep.ToChain,
|
||||
link:
|
||||
type === TransferNotificationTypes.Withdrawal
|
||||
type === 'withdrawal'
|
||||
? status?.toChain?.transactionUrl
|
||||
: currentStatus?.chainId === dydxChainId && currentStatus?.txHash
|
||||
? `${mintscanTxUrl?.replace('{tx_hash}', currentStatus.txHash.replace('0x', ''))}`
|
||||
|
||||
@@ -5,7 +5,7 @@ import { useInterval, useStringGetter } from '@/hooks';
|
||||
|
||||
import { AlertType } from '@/constants/alerts';
|
||||
import { STRING_KEYS } from '@/constants/localization';
|
||||
import { TransferNotifcation, TransferNotificationTypes } from '@/constants/notifications';
|
||||
import { TransferNotifcation } from '@/constants/notifications';
|
||||
|
||||
import { formatSeconds } from '@/lib/timeUtils';
|
||||
|
||||
@@ -22,7 +22,7 @@ import { layoutMixins } from '@/styles/layoutMixins';
|
||||
import { TransferStatusSteps } from './TransferStatusSteps';
|
||||
|
||||
type ElementProps = {
|
||||
type: TransferNotificationTypes;
|
||||
type: 'withdrawal' | 'deposit';
|
||||
transfer: TransferNotifcation;
|
||||
triggeredAt?: number;
|
||||
};
|
||||
@@ -55,7 +55,7 @@ export const TransferStatusNotification = ({
|
||||
useInterval({ callback: updateSecondsLeft });
|
||||
|
||||
const inProgressStatusString =
|
||||
type === TransferNotificationTypes.Deposit
|
||||
type === 'deposit'
|
||||
? secondsLeft > 0
|
||||
? STRING_KEYS.DEPOSIT_STATUS
|
||||
: STRING_KEYS.DEPOSIT_STATUS_SHORTLY
|
||||
@@ -64,7 +64,7 @@ export const TransferStatusNotification = ({
|
||||
: STRING_KEYS.WITHDRAW_STATUS_SHORTLY;
|
||||
|
||||
const statusString =
|
||||
type === TransferNotificationTypes.Deposit
|
||||
type === 'deposit'
|
||||
? status?.squidTransactionStatus === 'success'
|
||||
? STRING_KEYS.DEPOSIT_COMPLETE
|
||||
: inProgressStatusString
|
||||
|
||||
@@ -230,7 +230,14 @@ const getOrdersTableColumnDef = ({
|
||||
label: `${stringGetter({ key: STRING_KEYS.STATUS })} / ${stringGetter({
|
||||
key: STRING_KEYS.FILL,
|
||||
})}`,
|
||||
renderCell: ({ asset, createdAtMilliseconds, size, status, totalFilled, resources }) => {
|
||||
renderCell: ({
|
||||
asset,
|
||||
createdAtMilliseconds,
|
||||
size,
|
||||
status,
|
||||
totalFilled,
|
||||
resources,
|
||||
}) => {
|
||||
const { statusIconColor, statusStringKey } = getStatusIconInfo({
|
||||
status,
|
||||
totalFilled,
|
||||
@@ -338,7 +345,9 @@ export const OrdersTable = ({
|
||||
if (hasUnseenOrderUpdates) dispatch(viewedOrders());
|
||||
}, [hasUnseenOrderUpdates]);
|
||||
|
||||
const symbol = currentMarket ? allAssets[allPerpetualMarkets[currentMarket]?.assetId]?.id : null;
|
||||
const symbol = currentMarket
|
||||
? allAssets[allPerpetualMarkets[currentMarket]?.assetId]?.symbol
|
||||
: null;
|
||||
|
||||
const ordersData = orders.map((order: SubaccountOrder) =>
|
||||
getHydratedTradingData({
|
||||
|
||||
Reference in New Issue
Block a user