Compare commits

..
Author SHA1 Message Date
Bill He ca6b266bb2 bump abacus 2023-12-15 14:18:52 -08:00
45 changed files with 1107 additions and 1368 deletions
+2 -3
View File
@@ -39,12 +39,11 @@
"@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.1.32", "@dydxprotocol/v4-abacus": "^1.1.24",
"@dydxprotocol/v4-client-js": "^1.0.11", "@dydxprotocol/v4-client-js": "^1.0.11",
"@dydxprotocol/v4-localization": "^1.1.5", "@dydxprotocol/v4-localization": "^1.0.18",
"@ethersproject/providers": "^5.7.2", "@ethersproject/providers": "^5.7.2",
"@js-joda/core": "^5.5.3", "@js-joda/core": "^5.5.3",
"@radix-ui/react-accordion": "^1.1.2",
"@radix-ui/react-checkbox": "^1.0.4", "@radix-ui/react-checkbox": "^1.0.4",
"@radix-ui/react-collapsible": "^1.0.3", "@radix-ui/react-collapsible": "^1.0.3",
"@radix-ui/react-dialog": "^1.0.4", "@radix-ui/react-dialog": "^1.0.4",
+298 -369
View File
File diff suppressed because it is too large Load Diff
+29
View File
@@ -4,9 +4,38 @@
"tokenAddress": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", "tokenAddress": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
"name": "Ethereum" "name": "Ethereum"
}, },
{
"chainId": "421613",
"tokenAddress": "0xfd064a18f3bf249cf1f87fc203e90d8f650f2d63",
"name": "Arbitrum Goerli"
},
{
"chainId": "43113",
"tokenAddress": "0x5425890298aed601595a70AB815c96711a31Bc65",
"name": "Avalanche Fuji"
},
{
"chainId": "84531",
"tokenAddress": "0xf175520c52418dfe19c8098071a252da48cd1c19",
"name": "Base Goerli"
},
{ {
"chainId": "5", "chainId": "5",
"tokenAddress": "0x07865c6E87B9F70255377e024ace6630C1Eaa37F", "tokenAddress": "0x07865c6E87B9F70255377e024ace6630C1Eaa37F",
"name": "Ethereum Goerli" "name": "Ethereum Goerli"
},
{
"chainId": "grand-1",
"tokenAddress": "uusdc",
"name": "Noble Testnet"
},
{
"chainId": "420",
"tokenAddress": "0xe05606174bac4a6364b31bd0eca4bf4dd368f8c6",
"name": "OP Goerli"
},
{
"chainId": "103",
"name": "Solana Devnet"
} }
] ]
-16
View File
@@ -1,16 +0,0 @@
{
"tradingRewardsFAQs": [
{
"questionLocalizationKey": "APP.TRADING_REWARDS.FAQ_WHO_IS_ELIGIBLE_QUESTION",
"answerLocalizationKey": "APP.TRADING_REWARDS.FAQ_WHO_IS_ELIGIBLE_ANSWER"
},
{
"questionLocalizationKey": "APP.TRADING_REWARDS.FAQ_HOW_DO_TRADING_REWARDS_WORK_QUESTION",
"answerLocalizationKey": "APP.TRADING_REWARDS.FAQ_HOW_DO_TRADING_REWARDS_WORK_ANSWER"
},
{
"questionLocalizationKey": "APP.TRADING_REWARDS.FAQ_HOW_DO_I_CLAIM_MY_REWARDS_QUESTION",
"answerLocalizationKey": "APP.TRADING_REWARDS.FAQ_HOW_DO_I_CLAIM_MY_REWARDS_ANSWER"
}
]
}
+12 -12
View File
@@ -89,7 +89,7 @@
"governanceLearnMore": "https://help.dydx.exchange", "governanceLearnMore": "https://help.dydx.exchange",
"stakingLearnMore": "https://help.dydx.exchange", "stakingLearnMore": "https://help.dydx.exchange",
"keplrDashboard": "https://testnet.keplr.app/", "keplrDashboard": "https://testnet.keplr.app/",
"accountExportLearnMore": "https://help.dydx.exchange/en/articles/8565867-secret-phrase-on-dydx-chain", "accountExportLearnMore": "https://help.dydx.exchange",
"walletLearnMore": "https://www.dydx.academy/video/defi-wallet" "walletLearnMore": "https://www.dydx.academy/video/defi-wallet"
}, },
"wallets": { "wallets": {
@@ -162,7 +162,7 @@
"governanceLearnMore": "https://help.dydx.exchange", "governanceLearnMore": "https://help.dydx.exchange",
"stakingLearnMore": "https://help.dydx.exchange", "stakingLearnMore": "https://help.dydx.exchange",
"keplrDashboard": "https://testnet.keplr.app/", "keplrDashboard": "https://testnet.keplr.app/",
"accountExportLearnMore": "https://help.dydx.exchange/en/articles/8565867-secret-phrase-on-dydx-chain", "accountExportLearnMore": "https://help.dydx.exchange",
"walletLearnMore": "https://www.dydx.academy/video/defi-wallet" "walletLearnMore": "https://www.dydx.academy/video/defi-wallet"
}, },
"wallets": { "wallets": {
@@ -235,7 +235,7 @@
"governanceLearnMore": "https://help.dydx.exchange", "governanceLearnMore": "https://help.dydx.exchange",
"stakingLearnMore": "https://help.dydx.exchange", "stakingLearnMore": "https://help.dydx.exchange",
"keplrDashboard": "https://testnet.keplr.app/", "keplrDashboard": "https://testnet.keplr.app/",
"accountExportLearnMore": "https://help.dydx.exchange/en/articles/8565867-secret-phrase-on-dydx-chain", "accountExportLearnMore": "https://help.dydx.exchange",
"walletLearnMore": "https://www.dydx.academy/video/defi-wallet" "walletLearnMore": "https://www.dydx.academy/video/defi-wallet"
}, },
"wallets": { "wallets": {
@@ -308,7 +308,7 @@
"governanceLearnMore": "https://help.dydx.exchange", "governanceLearnMore": "https://help.dydx.exchange",
"stakingLearnMore": "https://help.dydx.exchange", "stakingLearnMore": "https://help.dydx.exchange",
"keplrDashboard": "https://testnet.keplr.app/", "keplrDashboard": "https://testnet.keplr.app/",
"accountExportLearnMore": "https://help.dydx.exchange/en/articles/8565867-secret-phrase-on-dydx-chain", "accountExportLearnMore": "https://help.dydx.exchange",
"walletLearnMore": "https://www.dydx.academy/video/defi-wallet" "walletLearnMore": "https://www.dydx.academy/video/defi-wallet"
}, },
"wallets": { "wallets": {
@@ -383,7 +383,7 @@
"governanceLearnMore": "https://help.dydx.exchange", "governanceLearnMore": "https://help.dydx.exchange",
"stakingLearnMore": "https://help.dydx.exchange", "stakingLearnMore": "https://help.dydx.exchange",
"keplrDashboard": "https://testnet.keplr.app/", "keplrDashboard": "https://testnet.keplr.app/",
"accountExportLearnMore": "https://help.dydx.exchange/en/articles/8565867-secret-phrase-on-dydx-chain", "accountExportLearnMore": "https://help.dydx.exchange",
"walletLearnMore": "https://www.dydx.academy/video/defi-wallet" "walletLearnMore": "https://www.dydx.academy/video/defi-wallet"
}, },
"wallets": { "wallets": {
@@ -531,7 +531,7 @@
"governanceLearnMore": "https://help.dydx.exchange", "governanceLearnMore": "https://help.dydx.exchange",
"stakingLearnMore": "https://help.dydx.exchange", "stakingLearnMore": "https://help.dydx.exchange",
"keplrDashboard": "https://testnet.keplr.app/", "keplrDashboard": "https://testnet.keplr.app/",
"accountExportLearnMore": "https://help.dydx.exchange/en/articles/8565867-secret-phrase-on-dydx-chain", "accountExportLearnMore": "https://help.dydx.exchange",
"walletLearnMore": "https://www.dydx.academy/video/defi-wallet" "walletLearnMore": "https://www.dydx.academy/video/defi-wallet"
}, },
"wallets": { "wallets": {
@@ -610,7 +610,7 @@
"governanceLearnMore": "https://help.dydx.exchange", "governanceLearnMore": "https://help.dydx.exchange",
"stakingLearnMore": "https://help.dydx.exchange", "stakingLearnMore": "https://help.dydx.exchange",
"keplrDashboard": "https://testnet.keplr.app/", "keplrDashboard": "https://testnet.keplr.app/",
"accountExportLearnMore": "https://help.dydx.exchange/en/articles/8565867-secret-phrase-on-dydx-chain", "accountExportLearnMore": "https://help.dydx.exchange",
"walletLearnMore": "https://www.dydx.academy/video/defi-wallet" "walletLearnMore": "https://www.dydx.academy/video/defi-wallet"
}, },
"wallets": { "wallets": {
@@ -686,7 +686,7 @@
"governanceLearnMore": "https://help.dydx.exchange", "governanceLearnMore": "https://help.dydx.exchange",
"stakingLearnMore": "https://help.dydx.exchange", "stakingLearnMore": "https://help.dydx.exchange",
"keplrDashboard": "https://testnet.keplr.app/", "keplrDashboard": "https://testnet.keplr.app/",
"accountExportLearnMore": "https://help.dydx.exchange/en/articles/8565867-secret-phrase-on-dydx-chain", "accountExportLearnMore": "https://help.dydx.exchange",
"walletLearnMore": "https://www.dydx.academy/video/defi-wallet" "walletLearnMore": "https://www.dydx.academy/video/defi-wallet"
}, },
"wallets": { "wallets": {
@@ -762,7 +762,7 @@
"governanceLearnMore": "https://help.dydx.exchange", "governanceLearnMore": "https://help.dydx.exchange",
"stakingLearnMore": "https://help.dydx.exchange", "stakingLearnMore": "https://help.dydx.exchange",
"keplrDashboard": "https://testnet.keplr.app/", "keplrDashboard": "https://testnet.keplr.app/",
"accountExportLearnMore": "https://help.dydx.exchange/en/articles/8565867-secret-phrase-on-dydx-chain", "accountExportLearnMore": "https://help.dydx.exchange",
"walletLearnMore": "https://www.dydx.academy/video/defi-wallet" "walletLearnMore": "https://www.dydx.academy/video/defi-wallet"
}, },
"wallets": { "wallets": {
@@ -838,7 +838,7 @@
"governanceLearnMore": "https://help.dydx.exchange", "governanceLearnMore": "https://help.dydx.exchange",
"stakingLearnMore": "https://help.dydx.exchange", "stakingLearnMore": "https://help.dydx.exchange",
"keplrDashboard": "https://testnet.keplr.app/", "keplrDashboard": "https://testnet.keplr.app/",
"accountExportLearnMore": "https://help.dydx.exchange/en/articles/8565867-secret-phrase-on-dydx-chain", "accountExportLearnMore": "https://help.dydx.exchange",
"walletLearnMore": "https://www.dydx.academy/video/defi-wallet" "walletLearnMore": "https://www.dydx.academy/video/defi-wallet"
}, },
"wallets": { "wallets": {
@@ -914,7 +914,7 @@
"governanceLearnMore": "https://help.dydx.exchange", "governanceLearnMore": "https://help.dydx.exchange",
"stakingLearnMore": "https://help.dydx.exchange", "stakingLearnMore": "https://help.dydx.exchange",
"keplrDashboard": "https://testnet.keplr.app/", "keplrDashboard": "https://testnet.keplr.app/",
"accountExportLearnMore": "https://help.dydx.exchange/en/articles/8565867-secret-phrase-on-dydx-chain", "accountExportLearnMore": "https://help.dydx.exchange",
"walletLearnMore": "https://www.dydx.academy/video/defi-wallet" "walletLearnMore": "https://www.dydx.academy/video/defi-wallet"
}, },
"wallets": { "wallets": {
@@ -1126,7 +1126,7 @@
"blogs": "[HTTP link to blogs, can be null]", "blogs": "[HTTP link to blogs, can be null]",
"foundation": "[HTTP link to foundation, can be null]", "foundation": "[HTTP link to foundation, can be null]",
"initialMarginFractionLearnMore": "[HTTP link to initial margin fraction learn more, can be null]", "initialMarginFractionLearnMore": "[HTTP link to initial margin fraction learn more, can be null]",
"reduceOnlyLearnMore": "[HTTP link to reduce-only learn more, can be null]", "reduceOnlyLearnMore": "https://help.dydx.exchange/articles/6345793-reduce-only-orders",
"documentation": "[HTTP link to documentation, can be null]", "documentation": "[HTTP link to documentation, can be null]",
"community": "[HTTP link to community, can be null]", "community": "[HTTP link to community, can be null]",
"help": "[HTTP link to help page, can be null]", "help": "[HTTP link to help page, can be null]",
+453 -359
View File
@@ -1,360 +1,454 @@
{ {
"1INCH-USD": { "1INCH-USD":{
"name": "1inch", "name":"1inch",
"tags": ["Defi"], "tags":[
"websiteLink": "https://1inch.io/", "Defi"
"whitepaperLink": "https://github.com/1inch", ],
"coinMarketCapsLink": "https://coinmarketcap.com/currencies/1inch/" "websiteLink":"https://1inch.io/",
}, "whitepaperLink":"https://github.com/1inch",
"AAVE-USD": { "coinMarketCapsLink":"https://coinmarketcap.com/currencies/1inch/"
"name": "Aave", },
"tags": ["Defi"], "AAVE-USD":{
"websiteLink": "https://aave.com/", "name":"Aave",
"whitepaperLink": "https://github.com/aave/protocol-v2/blob/master/aave-v2-whitepaper.pdf", "tags":[
"coinMarketCapsLink": "https://coinmarketcap.com/currencies/aave/" "Defi"
}, ],
"ADA-USD": { "websiteLink":"https://aave.com/",
"name": "Cardano", "whitepaperLink":"https://github.com/aave/protocol-v2/blob/master/aave-v2-whitepaper.pdf",
"tags": ["Layer 1"], "coinMarketCapsLink":"https://coinmarketcap.com/currencies/aave/"
"websiteLink": "https://cardano.org/", },
"whitepaperLink": "https://why.cardano.org/en/introduction/motivation/", "ADA-USD":{
"coinMarketCapsLink": "https://coinmarketcap.com/currencies/cardano/" "name":"Cardano",
}, "tags":[
"ALGO-USD": { "Layer 1"
"name": "Algorand", ],
"tags": ["Layer 1"], "websiteLink":"https://cardano.org/",
"websiteLink": "https://algorand.com/", "whitepaperLink":"https://why.cardano.org/en/introduction/motivation/",
"whitepaperLink": "https://algorand.com/technology/white-papers", "coinMarketCapsLink":"https://coinmarketcap.com/currencies/cardano/"
"coinMarketCapsLink": "https://coinmarketcap.com/currencies/algorand/" },
}, "ALGO-USD":{
"APE-USD": { "name":"Algorand",
"name": "ApeCoin", "tags":[
"tags": [], "Layer 1"
"websiteLink": "https://apecoin.com/", ],
"whitepaperLink": "https://apecoin.com/about", "websiteLink":"https://algorand.com/",
"coinMarketCapsLink": "https://coinmarketcap.com/currencies/apecoin-ape/" "whitepaperLink":"https://algorand.com/technology/white-papers",
}, "coinMarketCapsLink":"https://coinmarketcap.com/currencies/algorand/"
"APT-USD": { },
"name": "Aptos", "APE-USD":{
"tags": ["Layer 1"], "name":"ApeCoin",
"websiteLink": "https://aptoslabs.com/", "tags":[
"whitepaperLink": "https://aptos.dev/aptos-white-paper/",
"coinMarketCapsLink": "https://coinmarketcap.com/currencies/aptos/" ],
}, "websiteLink":"https://apecoin.com/",
"ARB-USD": { "whitepaperLink":"https://apecoin.com/about",
"name": "Arbitrum", "coinMarketCapsLink":"https://coinmarketcap.com/currencies/apecoin-ape/"
"tags": [], },
"websiteLink": "https://arbitrum.io/", "APT-USD":{
"whitepaperLink": "https://github.com/OffchainLabs/nitro", "name":"Aptos",
"coinMarketCapsLink": "https://coinmarketcap.com/currencies/arbitrum/" "tags":[
}, "Layer 1"
"ATOM-USD": { ],
"name": "Cosmos", "websiteLink":"https://aptoslabs.com/",
"tags": ["Layer 1"], "whitepaperLink":"https://aptos.dev/aptos-white-paper/",
"websiteLink": "https://cosmos.network/", "coinMarketCapsLink":"https://coinmarketcap.com/currencies/aptos/"
"whitepaperLink": "https://v1.cosmos.network/resources/whitepaper", },
"coinMarketCapsLink": "https://coinmarketcap.com/currencies/cosmos/" "ARB-USD":{
}, "name":"Arbitrum",
"AVAX-USD": { "tags":[
"name": "Avalanche",
"tags": ["Layer 1"], ],
"websiteLink": "https://www.avalabs.org/", "websiteLink":"https://arbitrum.io/",
"whitepaperLink": "https://assets.website-files.com/5d80307810123f5ffbb34d6e/6008d7bbf8b10d1eb01e7e16_Avalanche%20Platform%20Whitepaper.pdf", "whitepaperLink":"https://github.com/OffchainLabs/nitro",
"coinMarketCapsLink": "https://coinmarketcap.com/currencies/avalanche/" "coinMarketCapsLink":"https://coinmarketcap.com/currencies/arbitrum/"
}, },
"BCH-USD": { "ATOM-USD":{
"name": "Bitcoin Cash", "name":"Cosmos",
"tags": ["Layer 1"], "tags":[
"websiteLink": "https://bitcoincash.org/", "Layer 1"
"whitepaperLink": "https://bitcoincash.org/", ],
"coinMarketCapsLink": "https://coinmarketcap.com/currencies/bitcoin-cash/" "websiteLink":"https://cosmos.network/",
}, "whitepaperLink":"https://v1.cosmos.network/resources/whitepaper",
"BLUR-USD": { "coinMarketCapsLink":"https://coinmarketcap.com/currencies/cosmos/"
"name": "Blur", },
"tags": [], "AVAX-USD":{
"websiteLink": "https://blur.io/", "name":"Avalanche",
"whitepaperLink": "https://docs.blur.foundation/", "tags":[
"coinMarketCapsLink": "https://coinmarketcap.com/currencies/blur-token/" "Layer 1"
}, ],
"CELO-USD": { "websiteLink":"https://www.avalabs.org/",
"name": "Celo", "whitepaperLink":"https://assets.website-files.com/5d80307810123f5ffbb34d6e/6008d7bbf8b10d1eb01e7e16_Avalanche%20Platform%20Whitepaper.pdf",
"tags": [], "coinMarketCapsLink":"https://coinmarketcap.com/currencies/avalanche/"
"websiteLink": "https://celo.org", },
"whitepaperLink": "https://docs.celo.org", "BCH-USD":{
"coinMarketCapsLink": "https://coinmarketcap.com/currencies/celo/" "name":"Bitcoin Cash",
}, "tags":[
"BTC-USD": { "Layer 1"
"name": "Bitcoin", ],
"tags": ["Layer 1"], "websiteLink":"https://bitcoincash.org/",
"websiteLink": "https://bitcoin.org/", "whitepaperLink":"https://bitcoincash.org/",
"whitepaperLink": "https://bitcoin.org/bitcoin.pdf", "coinMarketCapsLink":"https://coinmarketcap.com/currencies/bitcoin-cash/"
"coinMarketCapsLink": "https://coinmarketcap.com/currencies/bitcoin/" },
}, "BLUR-USD":{
"COMP-USD": { "name":"Blur",
"name": "Compound", "tags":[
"tags": ["Defi"],
"websiteLink": "https://compound.finance/", ],
"whitepaperLink": "https://compound.finance/documents/Compound.Whitepaper.pdf", "websiteLink":"https://blur.io/",
"coinMarketCapsLink": "https://coinmarketcap.com/currencies/compound/" "whitepaperLink":"https://docs.blur.foundation/",
}, "coinMarketCapsLink":"https://coinmarketcap.com/currencies/blur-token/"
"CRV-USD": { },
"name": "Curve", "CELO-USD":{
"tags": ["Governance"], "name":"Celo",
"websiteLink": "https://curve.fi/", "tags":[
"whitepaperLink": "https://curve.fi/whitepaper",
"coinMarketCapsLink": "https://coinmarketcap.com/currencies/curve-dao-token/" ],
}, "websiteLink":"https://celo.org",
"DOGE-USD": { "whitepaperLink":"https://docs.celo.org",
"name": "Dogecoin", "coinMarketCapsLink":"https://coinmarketcap.com/currencies/celo/"
"tags": ["Layer 1"], },
"websiteLink": "https://dogecoin.com/", "BTC-USD":{
"whitepaperLink": "https://github.com/dogecoin/dogecoin", "name":"Bitcoin",
"coinMarketCapsLink": "https://coinmarketcap.com/currencies/dogecoin/" "tags":[
}, "Layer 1"
"DOT-USD": { ],
"name": "Polkadot", "websiteLink":"https://bitcoin.org/",
"tags": ["Layer 1"], "whitepaperLink":"https://bitcoin.org/bitcoin.pdf",
"websiteLink": "https://polkadot.network/", "coinMarketCapsLink":"https://coinmarketcap.com/currencies/bitcoin/"
"whitepaperLink": "https://polkadot.network/PolkaDotPaper.pdf", },
"coinMarketCapsLink": "https://coinmarketcap.com/currencies/polkadot-new/" "COMP-USD":{
}, "name":"Compound",
"ENJ-USD": { "tags":[
"name": "Enjin", "Defi"
"tags": [], ],
"websiteLink": "https://enjin.io/", "websiteLink":"https://compound.finance/",
"whitepaperLink": "https://cdn.enjin.io/downloads/whitepapers/enjin-coin/en.pdf/", "whitepaperLink":"https://compound.finance/documents/Compound.Whitepaper.pdf",
"coinMarketCapsLink": "https://coinmarketcap.com/currencies/enjin-coin/" "coinMarketCapsLink":"https://coinmarketcap.com/currencies/compound/"
}, },
"EOS-USD": { "CRV-USD":{
"name": "EOS", "name":"Curve",
"tags": ["Layer 1"], "tags":[
"websiteLink": "https://eos.io/", "Governance"
"whitepaperLink": "https://github.com/EOSIO/Documentation/blob/master/TechnicalWhitePaper.md", ],
"coinMarketCapsLink": "https://coinmarketcap.com/currencies/eos/" "websiteLink":"https://curve.fi/",
}, "whitepaperLink":"https://curve.fi/whitepaper",
"ETC-USD": { "coinMarketCapsLink":"https://coinmarketcap.com/currencies/curve-dao-token/"
"name": "Ethereum Classic", },
"tags": ["Layer 1"], "DOGE-USD":{
"websiteLink": "https://ethereumclassic.org/", "name":"Dogecoin",
"whitepaperLink": "https://ethereumclassic.org/why-classic", "tags":[
"coinMarketCapsLink": "https://coinmarketcap.com/currencies/ethereum-classic/" "Layer 1"
}, ],
"ETH-USD": { "websiteLink":"https://dogecoin.com/",
"name": "Ethereum", "whitepaperLink":"https://github.com/dogecoin/dogecoin",
"tags": ["Layer 1"], "coinMarketCapsLink":"https://coinmarketcap.com/currencies/dogecoin/"
"websiteLink": "https://ethereum.org/", },
"whitepaperLink": "https://ethereum.org/whitepaper/", "DOT-USD":{
"coinMarketCapsLink": "https://coinmarketcap.com/currencies/ethereum/", "name":"Polkadot",
"displayStepSize": "0.001", "tags":[
"displayTickSize": "0.1" "Layer 1"
}, ],
"FIL-USD": { "websiteLink":"https://polkadot.network/",
"name": "Filecoin", "whitepaperLink":"https://polkadot.network/PolkaDotPaper.pdf",
"tags": ["Layer 1"], "coinMarketCapsLink":"https://coinmarketcap.com/currencies/polkadot-new/"
"websiteLink": "https://filecoin.io/", },
"whitepaperLink": "https://filecoin.io/filecoin.pdf", "ENJ-USD":{
"coinMarketCapsLink": "https://coinmarketcap.com/currencies/filecoin/" "name":"Enjin",
}, "tags":[
"HNT-USD": {
"name": "Helium", ],
"tags": ["Layer 1"], "websiteLink":"https://enjin.io/",
"websiteLink": "https://www.helium.com", "whitepaperLink":"https://cdn.enjin.io/downloads/whitepapers/enjin-coin/en.pdf/",
"whitepaperLink": "http://whitepaper.helium.com", "coinMarketCapsLink":"https://coinmarketcap.com/currencies/enjin-coin/"
"coinMarketCapsLink": "https://coinmarketcap.com/currencies/helium/" },
}, "EOS-USD":{
"ICP-USD": { "name":"EOS",
"name": "Internet Computer", "tags":[
"tags": ["Layer 1"], "Layer 1"
"websiteLink": "https://dfinity.org", ],
"whitepaperLink": "https://dfinity.org/whitepaper.pdf", "websiteLink":"https://eos.io/",
"coinMarketCapsLink": "https://coinmarketcap.com/currencies/internet-computer/" "whitepaperLink":"https://github.com/EOSIO/Documentation/blob/master/TechnicalWhitePaper.md",
}, "coinMarketCapsLink":"https://coinmarketcap.com/currencies/eos/"
"LDO-USD": { },
"name": "Lido DAO", "ETC-USD":{
"tags": ["Defi"], "name":"Ethereum Classic",
"websiteLink": "https://lido.fi/", "tags":[
"whitepaperLink": "https://lido.fi/static/Lido:Ethereum-Liquid-Staking.pdf", "Layer 1"
"coinMarketCapsLink": "https://coinmarketcap.com/currencies/lido-dao/" ],
}, "websiteLink":"https://ethereumclassic.org/",
"LINK-USD": { "whitepaperLink":"https://ethereumclassic.org/why-classic",
"name": "Chainlink", "coinMarketCapsLink":"https://coinmarketcap.com/currencies/ethereum-classic/"
"tags": ["Defi"], },
"websiteLink": "https://chain.link/", "ETH-USD":{
"whitepaperLink": "https://link.smartcontract.com/whitepaper", "name":"Ethereum",
"coinMarketCapsLink": "https://coinmarketcap.com/currencies/chainlink/" "tags":[
}, "Layer 1"
"LTC-USD": { ],
"name": "Litecoin", "websiteLink":"https://ethereum.org/",
"tags": ["Layer 1"], "whitepaperLink":"https://ethereum.org/whitepaper/",
"websiteLink": "https://litecoin.org/", "coinMarketCapsLink":"https://coinmarketcap.com/currencies/ethereum/",
"whitepaperLink": "https://litecoin.info/index.php/Main_Page", "displayStepSize":"0.001",
"coinMarketCapsLink": "https://coinmarketcap.com/currencies/litecoin/" "displayTickSize":"0.1"
}, },
"MATIC-USD": { "FIL-USD":{
"name": "Polygon", "name":"Filecoin",
"tags": ["Layer 2"], "tags":[
"websiteLink": "https://polygon.technology/", "Layer 1"
"whitepaperLink": "https://polygon.technology/lightpaper-polygon.pdf", ],
"coinMarketCapsLink": "https://coinmarketcap.com/currencies/polygon/" "websiteLink":"https://filecoin.io/",
}, "whitepaperLink":"https://filecoin.io/filecoin.pdf",
"MKR-USD": { "coinMarketCapsLink":"https://coinmarketcap.com/currencies/filecoin/"
"name": "Maker", },
"tags": ["Governance"], "HNT-USD":{
"websiteLink": "https://makerdao.com", "name":"Helium",
"whitepaperLink": "https://makerdao.com/whitepaper", "tags":[
"coinMarketCapsLink": "https://coinmarketcap.com/currencies/maker/" "Layer 1"
}, ],
"NEAR-USD": { "websiteLink":"https://www.helium.com",
"name": "NEAR Protocol", "whitepaperLink":"http://whitepaper.helium.com",
"tags": ["Layer 1"], "coinMarketCapsLink":"https://coinmarketcap.com/currencies/helium/"
"websiteLink": "https://near.org", },
"whitepaperLink": "https://near.org/papers/the-official-near-white-paper/", "ICP-USD":{
"coinMarketCapsLink": "https://coinmarketcap.com/currencies/near-protocol/" "name":"Internet Computer",
}, "tags":[
"OP-USD": { "Layer 1"
"name": "Optimism", ],
"tags": [], "websiteLink":"https://dfinity.org",
"websiteLink": "https://www.optimism.io/", "whitepaperLink":"https://dfinity.org/whitepaper.pdf",
"whitepaperLink": "https://github.com/ethereum-optimism", "coinMarketCapsLink":"https://coinmarketcap.com/currencies/internet-computer/"
"coinMarketCapsLink": "https://coinmarketcap.com/currencies/optimism-ethereum/" },
}, "LDO-USD":{
"PEPE-USD": { "name":"Lido DAO",
"name": "Pepe", "tags":[
"tags": [], "Defi"
"websiteLink": "https://www.pepe.vip/", ],
"coinMarketCapsLink": "https://coinmarketcap.com/currencies/pepe/" "websiteLink":"https://lido.fi/",
}, "whitepaperLink":"https://lido.fi/static/Lido:Ethereum-Liquid-Staking.pdf",
"RUNE-USD": { "coinMarketCapsLink":"https://coinmarketcap.com/currencies/lido-dao/"
"name": "THORChain", },
"tags": ["Layer 1"], "LINK-USD":{
"websiteLink": "https://thorchain.org", "name":"Chainlink",
"whitepaperLink": "https://whitepaper.io/document/709/thorchain-whitepaper", "tags":[
"coinMarketCapsLink": "https://coinmarketcap.com/currencies/thorchain/" "Defi"
}, ],
"SEI-USD": { "websiteLink":"https://chain.link/",
"name": "Sei", "whitepaperLink":"https://link.smartcontract.com/whitepaper",
"tags": ["Layer 1", "Defi"], "coinMarketCapsLink":"https://coinmarketcap.com/currencies/chainlink/"
"websiteLink": "https://www.sei.io/", },
"whitepaperLink": "https://github.com/sei-protocol/sei-chain/blob/3c9576fee3494ce039df684624f918dd8066ba3f/whitepaper/Sei_Whitepaper.pdf", "LTC-USD":{
"coinMarketCapsLink": "https://coinmarketcap.com/currencies/sei/" "name":"Litecoin",
}, "tags":[
"SHIB-USD": { "Layer 1"
"name": "Shiba Inu", ],
"tags": [], "websiteLink":"https://litecoin.org/",
"websiteLink": "https://shibatoken.com/", "whitepaperLink":"https://litecoin.info/index.php/Main_Page",
"whitepaperLink": "https://docs.shibatoken.com/", "coinMarketCapsLink":"https://coinmarketcap.com/currencies/litecoin/"
"coinMarketCapsLink": "https://coinmarketcap.com/currencies/shiba-inu/" },
}, "MATIC-USD":{
"SNX-USD": { "name":"Polygon",
"name": "Synthetix", "tags":[
"tags": ["Defi"], "Layer 2"
"websiteLink": "https://synthetix.io/", ],
"whitepaperLink": "https://docs.synthetix.io/litepaper", "websiteLink":"https://polygon.technology/",
"coinMarketCapsLink": "https://coinmarketcap.com/currencies/synthetix-network-token/" "whitepaperLink":"https://polygon.technology/lightpaper-polygon.pdf",
}, "coinMarketCapsLink":"https://coinmarketcap.com/currencies/polygon/"
"SOL-USD": { },
"name": "Solana", "MKR-USD":{
"tags": ["Layer 1"], "name":"Maker",
"websiteLink": "https://solana.com/", "tags":[
"whitepaperLink": "https://solana.com/solana-whitepaper.pdf", "Governance"
"coinMarketCapsLink": "https://coinmarketcap.com/currencies/solana/" ],
}, "websiteLink":"https://makerdao.com",
"SUI-USD": { "whitepaperLink":"https://makerdao.com/whitepaper",
"name": "Sui", "coinMarketCapsLink":"https://coinmarketcap.com/currencies/maker/"
"tags": ["Layer 1"], },
"websiteLink": "https://sui.io/", "NEAR-USD":{
"whitepaperLink": "https://github.com/MystenLabs", "name":"NEAR Protocol",
"coinMarketCapsLink": "https://coinmarketcap.com/currencies/sui/" "tags":[
}, "Layer 1"
"SUSHI-USD": { ],
"name": "Sushi", "websiteLink":"https://near.org",
"tags": ["Defi"], "whitepaperLink":"https://near.org/papers/the-official-near-white-paper/",
"websiteLink": "https://sushi.com/", "coinMarketCapsLink":"https://coinmarketcap.com/currencies/near-protocol/"
"whitepaperLink": "https://docs.sushi.com/", },
"coinMarketCapsLink": "https://coinmarketcap.com/currencies/sushiswap/" "OP-USD":{
}, "name":"Optimism",
"TIA-USD": { "tags":[
"name": "Celestia",
"tags": ["Layer 1"], ],
"websiteLink": "https://celestia.org/", "websiteLink":"https://www.optimism.io/",
"whitepaperLink": "https://arxiv.org/pdf/1905.09274.pdf", "whitepaperLink":"https://github.com/ethereum-optimism",
"coinMarketCapsLink": "https://coinmarketcap.com/currencies/celestia/" "coinMarketCapsLink":"https://coinmarketcap.com/currencies/optimism-ethereum/"
}, },
"TRX-USD": { "PEPE-USD":{
"name": "TRON", "name":"Pepe",
"tags": ["Defi"], "tags":[
"websiteLink": "https://tron.network/",
"whitepaperLink": "https://tron.network/static/doc/white_paper_v_2_0.pdf", ],
"coinMarketCapsLink": "https://coinmarketcap.com/currencies/tron/" "websiteLink":"https://www.pepe.vip/",
}, "coinMarketCapsLink":"https://coinmarketcap.com/currencies/pepe/"
"UMA-USD": { },
"name": "UMA", "RUNE-USD":{
"tags": ["Defi"], "name":"THORChain",
"websiteLink": "https://umaproject.org/", "tags":[
"whitepaperLink": "https://github.com/UMAprotocol/whitepaper", "Layer 1"
"coinMarketCapsLink": "https://coinmarketcap.com/currencies/uma/" ],
}, "websiteLink":"https://thorchain.org",
"UNI-USD": { "whitepaperLink":"https://whitepaper.io/document/709/thorchain-whitepaper",
"name": "Uniswap", "coinMarketCapsLink":"https://coinmarketcap.com/currencies/thorchain/"
"tags": ["Defi"], },
"websiteLink": "https://uniswap.org/", "SEI-USD":{
"whitepaperLink": "https://uniswap.org/whitepaper-v3.pdf", "name":"Sei",
"coinMarketCapsLink": "https://coinmarketcap.com/currencies/uniswap/" "tags":[
}, "Layer 1",
"WLD-USD": { "Defi"
"name": "Worldcoin", ],
"tags": [], "websiteLink":"https://www.sei.io/",
"websiteLink": "https://worldcoin.org/", "whitepaperLink":"https://github.com/sei-protocol/sei-chain/blob/3c9576fee3494ce039df684624f918dd8066ba3f/whitepaper/Sei_Whitepaper.pdf",
"whitepaperLink": "https://whitepaper.worldcoin.org/", "coinMarketCapsLink":"https://coinmarketcap.com/currencies/sei/"
"coinMarketCapsLink": "https://coinmarketcap.com/currencies/worldcoin-org/" },
}, "SHIB-USD":{
"XLM-USD": { "name":"Shiba Inu",
"name": "Stellar", "tags":[
"tags": ["Layer 1"],
"websiteLink": "https://www.stellar.org/", ],
"whitepaperLink": "https://www.stellar.org/papers/stellar-consensus-protocol", "websiteLink":"https://shibatoken.com/",
"coinMarketCapsLink": "https://coinmarketcap.com/currencies/stellar/" "whitepaperLink":"https://docs.shibatoken.com/",
}, "coinMarketCapsLink":"https://coinmarketcap.com/currencies/shiba-inu/"
"XMR-USD": { },
"name": "Monero", "SNX-USD":{
"tags": ["Layer 1"], "name":"Synthetix",
"websiteLink": "https://www.getmonero.org/", "tags":[
"whitepaperLink": "https://www.getmonero.org/resources/research-lab/", "Defi"
"coinMarketCapsLink": "https://coinmarketcap.com/currencies/monero/" ],
}, "websiteLink":"https://synthetix.io/",
"XRP-USD": { "whitepaperLink":"https://docs.synthetix.io/litepaper",
"name": "Ripple", "coinMarketCapsLink":"https://coinmarketcap.com/currencies/synthetix-network-token/"
"tags": ["Layer 1"], },
"websiteLink": "https://ripple.com/currency/", "SOL-USD":{
"whitepaperLink": "https://github.com/ripple", "name":"Solana",
"coinMarketCapsLink": "https://coinmarketcap.com/currencies/xrp/" "tags":[
}, "Layer 1"
"XTZ-USD": { ],
"name": "Tezos", "websiteLink":"https://solana.com/",
"tags": ["Layer 1"], "whitepaperLink":"https://solana.com/solana-whitepaper.pdf",
"websiteLink": "https://tezos.com", "coinMarketCapsLink":"https://coinmarketcap.com/currencies/solana/"
"whitepaperLink": "https://tezos.com/whitepaper.pdf", },
"coinMarketCapsLink": "https://coinmarketcap.com/currencies/tezos/" "SUI-USD":{
}, "name":"Sui",
"YFI-USD": { "tags":[
"name": "Yearn", "Layer 1"
"tags": ["Defi"], ],
"websiteLink": "https://yearn.finance/", "websiteLink":"https://sui.io/",
"whitepaperLink": "https://docs.yearn.finance/", "whitepaperLink":"https://github.com/MystenLabs",
"coinMarketCapsLink": "https://coinmarketcap.com/currencies/yearn-finance/" "coinMarketCapsLink":"https://coinmarketcap.com/currencies/sui/"
}, },
"ZEC-USD": { "SUSHI-USD":{
"name": "Zcash", "name":"Sushi",
"tags": ["Layer 1"], "tags":[
"websiteLink": "https://z.cash/", "Defi"
"whitepaperLink": "https://z.cash/technology/", ],
"coinMarketCapsLink": "https://coinmarketcap.com/currencies/zcash/" "websiteLink":"https://sushi.com/",
}, "whitepaperLink":"https://docs.sushi.com/",
"ZRX-USD": { "coinMarketCapsLink":"https://coinmarketcap.com/currencies/sushiswap/"
"name": "0x", },
"tags": ["Defi"], "TRX-USD":{
"websiteLink": "https://0x.org/", "name":"TRON",
"whitepaperLink": "https://0x.org/pdfs/0x_white_paper.pdf", "tags":[
"coinMarketCapsLink": "https://coinmarketcap.com/currencies/0x/" "Defi"
} ],
} "websiteLink":"https://tron.network/",
"whitepaperLink":"https://tron.network/static/doc/white_paper_v_2_0.pdf",
"coinMarketCapsLink":"https://coinmarketcap.com/currencies/tron/"
},
"UMA-USD":{
"name":"UMA",
"tags":[
"Defi"
],
"websiteLink":"https://umaproject.org/",
"whitepaperLink":"https://github.com/UMAprotocol/whitepaper",
"coinMarketCapsLink":"https://coinmarketcap.com/currencies/uma/"
},
"UNI-USD":{
"name":"Uniswap",
"tags":[
"Defi"
],
"websiteLink":"https://uniswap.org/",
"whitepaperLink":"https://uniswap.org/whitepaper-v3.pdf",
"coinMarketCapsLink":"https://coinmarketcap.com/currencies/uniswap/"
},
"WLD-USD":{
"name":"Worldcoin",
"tags":[
],
"websiteLink":"https://worldcoin.org/",
"whitepaperLink":"https://whitepaper.worldcoin.org/",
"coinMarketCapsLink":"https://coinmarketcap.com/currencies/worldcoin-org/"
},
"XLM-USD":{
"name":"Stellar",
"tags":[
"Layer 1"
],
"websiteLink":"https://www.stellar.org/",
"whitepaperLink":"https://www.stellar.org/papers/stellar-consensus-protocol",
"coinMarketCapsLink":"https://coinmarketcap.com/currencies/stellar/"
},
"XMR-USD":{
"name":"Monero",
"tags":[
"Layer 1"
],
"websiteLink":"https://www.getmonero.org/",
"whitepaperLink":"https://www.getmonero.org/resources/research-lab/",
"coinMarketCapsLink":"https://coinmarketcap.com/currencies/monero/"
},
"XRP-USD":{
"name":"Ripple",
"tags":[
"Layer 1"
],
"websiteLink":"https://ripple.com/currency/",
"whitepaperLink":"https://github.com/ripple",
"coinMarketCapsLink":"https://coinmarketcap.com/currencies/xrp/"
},
"XTZ-USD":{
"name":"Tezos",
"tags":[
"Layer 1"
],
"websiteLink":"https://tezos.com",
"whitepaperLink":"https://tezos.com/whitepaper.pdf",
"coinMarketCapsLink":"https://coinmarketcap.com/currencies/tezos/"
},
"YFI-USD":{
"name":"Yearn",
"tags":[
"Defi"
],
"websiteLink":"https://yearn.finance/",
"whitepaperLink":"https://docs.yearn.finance/",
"coinMarketCapsLink":"https://coinmarketcap.com/currencies/yearn-finance/"
},
"ZEC-USD":{
"name":"Zcash",
"tags":[
"Layer 1"
],
"websiteLink":"https://z.cash/",
"whitepaperLink":"https://z.cash/technology/",
"coinMarketCapsLink":"https://coinmarketcap.com/currencies/zcash/"
},
"ZRX-USD":{
"name":"0x",
"tags":[
"Defi"
],
"websiteLink":"https://0x.org/",
"whitepaperLink":"https://0x.org/pdfs/0x_white_paper.pdf",
"coinMarketCapsLink":"https://coinmarketcap.com/currencies/0x/"
}
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

+12 -13
View File
@@ -1,4 +1,4 @@
import { lazy, Suspense } from 'react'; import { Suspense } from 'react';
import { Navigate, Route, Routes } from 'react-router-dom'; import { Navigate, Route, Routes } from 'react-router-dom';
import styled, { AnyStyledComponent, css } from 'styled-components'; import styled, { AnyStyledComponent, css } from 'styled-components';
import { WagmiConfig } from 'wagmi'; import { WagmiConfig } from 'wagmi';
@@ -25,6 +25,16 @@ import { SubaccountProvider } from '@/hooks/useSubaccount';
import { GuardedMobileRoute } from '@/components/GuardedMobileRoute'; import { GuardedMobileRoute } from '@/components/GuardedMobileRoute';
import MarketsPage from '@/pages/markets/Markets';
import PortfolioPage from '@/pages/portfolio/Portfolio';
import { AlertsPage } from '@/pages/AlertsPage';
import ProfilePage from '@/pages/Profile';
import { SettingsPage } from '@/pages/settings/Settings';
import TradePage from '@/pages/trade/Trade';
import { RewardsPage } from '@/pages/rewards/RewardsPage';
import { TermsOfUsePage } from '@/pages/TermsOfUsePage';
import { PrivacyPolicyPage } from '@/pages/PrivacyPolicyPage';
import { HeaderDesktop } from '@/layout/Header/HeaderDesktop'; import { HeaderDesktop } from '@/layout/Header/HeaderDesktop';
import { FooterDesktop } from '@/layout/Footer/FooterDesktop'; import { FooterDesktop } from '@/layout/Footer/FooterDesktop';
import { FooterMobile } from '@/layout/Footer/FooterMobile'; import { FooterMobile } from '@/layout/Footer/FooterMobile';
@@ -36,22 +46,11 @@ import { config } from '@/lib/wagmi';
import { breakpoints } from '@/styles'; import { breakpoints } from '@/styles';
import { layoutMixins } from '@/styles/layoutMixins'; import { layoutMixins } from '@/styles/layoutMixins';
import { LoadingSpace } from './components/Loading/LoadingSpinner';
import '@/styles/constants.css'; import '@/styles/constants.css';
import '@/styles/fonts.css'; import '@/styles/fonts.css';
import '@/styles/web3modal.css'; import '@/styles/web3modal.css';
const MarketsPage = lazy(() => import('@/pages/markets/Markets'));
const PortfolioPage = lazy(() => import('@/pages/portfolio/Portfolio'));
const AlertsPage = lazy(() => import('@/pages/AlertsPage'));
const ProfilePage = lazy(() => import('@/pages/Profile'));
const SettingsPage = lazy(() => import('@/pages/settings/Settings'));
const TradePage = lazy(() => import('@/pages/trade/Trade'));
const RewardsPage = lazy(() => import('@/pages/rewards/RewardsPage'));
const TermsOfUsePage = lazy(() => import('@/pages/TermsOfUsePage'));
const PrivacyPolicyPage = lazy(() => import('@/pages/PrivacyPolicyPage'));
const queryClient = new QueryClient(); const queryClient = new QueryClient();
const Content = () => { const Content = () => {
@@ -70,7 +69,7 @@ const Content = () => {
{isNotTablet && <HeaderDesktop />} {isNotTablet && <HeaderDesktop />}
<Styled.Main> <Styled.Main>
<Suspense fallback={<LoadingSpace id="main" />}> <Suspense fallback={null}>
<Routes> <Routes>
<Route path={AppRoute.Trade}> <Route path={AppRoute.Trade}>
<Route path=":market" element={<TradePage />} /> <Route path=":market" element={<TradePage />} />
-119
View File
@@ -1,119 +0,0 @@
import styled, { keyframes, type AnyStyledComponent } from 'styled-components';
import { Root, Item, Header, Trigger, Content } from '@radix-ui/react-accordion';
import { layoutMixins } from '@/styles/layoutMixins';
import { PlusIcon } from '@/icons';
export type AccordionItem = {
header: React.ReactNode;
content: React.ReactNode;
};
type AccordionProps = {
items: AccordionItem[];
className?: string;
};
export const Accordion = ({ items, className }: AccordionProps) => (
<Styled.Root className={className} type="single" collapsible>
{items.map(({ header, content }, idx) => (
<Styled.Item key={idx} value={idx.toString()}>
<Header>
<Styled.Trigger>
{header}
<Styled.Icon>
<PlusIcon />
</Styled.Icon>
</Styled.Trigger>
</Header>
<Styled.Content>{content}</Styled.Content>
</Styled.Item>
))}
</Styled.Root>
);
const Styled: Record<string, AnyStyledComponent> = {};
Styled.Root = styled(Root)`
> *:not(:last-child) {
border-bottom: var(--border-width) solid var(--border-color);
}
`;
Styled.Item = styled(Item)``;
Styled.Icon = styled.div`
display: inline-flex;
justify-content: center;
align-items: center;
width: 2.25rem;
height: 2.25rem;
--color-border: var(--color-layer-6);
color: var(--color-text-1);
background-color: var(--color-layer-5);
border: solid var(--border-width) var(--color-border);
border-radius: 50%;
font: var(--font-small-book);
svg {
height: 1.125em;
width: 1.125em;
}
`;
Styled.Trigger = styled(Trigger)`
${layoutMixins.spacedRow}
width: 100%;
padding: 1rem 0.75rem;
color: var(--color-text-1);
text-align: start;
&:hover {
${Styled.Icon} {
color: var(--color-text-2);
filter: brightness(1.1);
}
}
svg {
color: var(--color-text-0);
transition: transform 0.3s var(--ease-out-expo);
}
&[data-state='open'] svg {
transform: rotate(45deg);
}
`;
Styled.Content = styled(Content)`
overflow: hidden;
margin: 0 0.75rem 1rem;
color: var(--color-text-0);
&[data-state='open'] {
animation: ${keyframes`
from {
height: 0;
}
to {
height: var(--radix-accordion-content-height);
}
`} 0.3s var(--ease-out-expo);
}
&[data-state='closed'] {
animation: ${keyframes`
from {
height: var(--radix-accordion-content-height);
}
to {
height: 0;
}
`} 0.1s var(--ease-in-expo);
}
`;
+2 -8
View File
@@ -45,7 +45,6 @@ const assetIcons = {
SOL: '/currencies/sol.png', SOL: '/currencies/sol.png',
SUI: '/currencies/sui.png', SUI: '/currencies/sui.png',
SUSHI: '/currencies/sushi.png', SUSHI: '/currencies/sushi.png',
TIA: '/currencies/tia.png',
TRX: '/currencies/trx.png', TRX: '/currencies/trx.png',
UMA: '/currencies/uma.png', UMA: '/currencies/uma.png',
UNI: '/currencies/uni.png', UNI: '/currencies/uni.png',
@@ -72,13 +71,8 @@ export const AssetIcon = ({
}: { }: {
symbol?: Nullable<string>; symbol?: Nullable<string>;
className?: string; className?: string;
}) => ( }) =>
<Styled.Img isAssetSymbol(symbol) ? <Styled.Img src={assetIcons[symbol]} className={className} /> : null;
src={isAssetSymbol(symbol) ? assetIcons[symbol] : '/currencies/unavailable.png'}
className={className}
alt={symbol}
/>
);
const Styled: Record<string, AnyStyledComponent> = {}; const Styled: Record<string, AnyStyledComponent> = {};
-3
View File
@@ -55,7 +55,6 @@ import {
OverviewIcon, OverviewIcon,
PencilIcon, PencilIcon,
PlayIcon, PlayIcon,
PlusIcon,
PositionsIcon, PositionsIcon,
PriceChartIcon, PriceChartIcon,
PrivacyIcon, PrivacyIcon,
@@ -131,7 +130,6 @@ export enum IconName {
Overview = 'Overview', Overview = 'Overview',
Pencil = 'Pencil', Pencil = 'Pencil',
Play = 'Play', Play = 'Play',
Plus = 'Plus',
Positions = 'Positions', Positions = 'Positions',
PriceChart = 'PriceChart', PriceChart = 'PriceChart',
Privacy = 'Privacy', Privacy = 'Privacy',
@@ -206,7 +204,6 @@ const icons = {
[IconName.Overview]: OverviewIcon, [IconName.Overview]: OverviewIcon,
[IconName.Pencil]: PencilIcon, [IconName.Pencil]: PencilIcon,
[IconName.Play]: PlayIcon, [IconName.Play]: PlayIcon,
[IconName.Plus]: PlusIcon,
[IconName.Positions]: PositionsIcon, [IconName.Positions]: PositionsIcon,
[IconName.PriceChart]: PriceChartIcon, [IconName.PriceChart]: PriceChartIcon,
[IconName.Privacy]: PrivacyIcon, [IconName.Privacy]: PrivacyIcon,
+4 -2
View File
@@ -43,7 +43,6 @@ import { layoutMixins } from '@/styles/layoutMixins';
import { Icon, IconName } from './Icon'; import { Icon, IconName } from './Icon';
import { Tag } from './Tag'; import { Tag } from './Tag';
import { MustBigNumber } from '@/lib/numbers';
export { TableCell } from './Table/TableCell'; export { TableCell } from './Table/TableCell';
export { TableColumnHeader } from './Table/TableColumnHeader'; export { TableColumnHeader } from './Table/TableColumnHeader';
@@ -162,7 +161,10 @@ export const Table = <TableRowData extends object, TableRowKey extends Key>({
? // String ? // String
collator.compare(first as string, second as string) collator.compare(first as string, second as string)
: // Number : // Number
MustBigNumber(first).comparedTo(MustBigNumber(second))) * Math.sign(
(parseInt(first as string) || (first as number)) -
(parseInt(second as string) || (second as number))
)) *
// Flip the direction if descending order is specified. // Flip the direction if descending order is specified.
(sortDirection === 'descending' ? -1 : 1) (sortDirection === 'descending' ? -1 : 1)
); );
+36
View File
@@ -26,3 +26,39 @@ export enum FundingDirection {
ToShort = 'ToShort', ToShort = 'ToShort',
ToLong = 'ToLong', ToLong = 'ToLong',
} }
export const MARKETS_TO_DISPLAY = [
'BTC-USD',
'ETH-USD',
'LINK-USD',
'SOL-USD',
'MATIC-USD',
'ATOM-USD',
'AVAX-USD',
'APE-USD',
'XRP-USD',
'UNI-USD',
'ADA-USD',
'TRX-USD',
'OP-USD',
'MKR-USD',
'DOGE-USD',
'SHIB-USD',
'COMP-USD',
'LDO-USD',
'NEAR-USD',
'APT-USD',
'SUI-USD',
'DOT-USD',
'ETC-USD',
'ARB-USD',
'CRV-USD',
'BLUR-USD',
'FIL-USD',
'XLM-USD',
'PEPE-USD',
'WLD-USD',
'SEI-USD',
'LTC-USD',
'BCH-USD',
];
-5
View File
@@ -10,7 +10,6 @@ export const LEVERAGE_DECIMALS = 2;
export const TOKEN_DECIMALS = 4; export const TOKEN_DECIMALS = 4;
export const LARGE_TOKEN_DECIMALS = 2; export const LARGE_TOKEN_DECIMALS = 2;
export const FEE_DECIMALS = 3; export const FEE_DECIMALS = 3;
export const FUNDING_DECIMALS = 6;
export const QUANTUM_MULTIPLIER = 1_000_000; export const QUANTUM_MULTIPLIER = 1_000_000;
@@ -19,7 +18,3 @@ export enum NumberSign {
Negative = 'Negative', Negative = 'Negative',
Neutral = 'Neutral', Neutral = 'Neutral',
} }
// Deposit/Withdraw
export const MAX_CCTP_TRANSFER_AMOUNT = 1_000_000;
export const MAX_PRICE_IMPACT = 0.02; // 2%
-4
View File
@@ -1,10 +1,6 @@
import { type TooltipStrings, TOOLTIP_STRING_KEYS } from '@/constants/localization'; import { type TooltipStrings, TOOLTIP_STRING_KEYS } from '@/constants/localization';
export const depositTooltips: TooltipStrings = { export const depositTooltips: TooltipStrings = {
'minimum-deposit-amount': ({ stringGetter }) => ({
title: stringGetter({ key: TOOLTIP_STRING_KEYS.MINIMUM_DEPOSIT_AMOUNT_TITLE }),
body: stringGetter({ key: TOOLTIP_STRING_KEYS.MINIMUM_DEPOSIT_AMOUNT_BODY }),
}),
swap: ({ stringGetter }) => ({ swap: ({ stringGetter }) => ({
title: stringGetter({ key: TOOLTIP_STRING_KEYS.SWAP_TITLE }), title: stringGetter({ key: TOOLTIP_STRING_KEYS.SWAP_TITLE }),
body: stringGetter({ key: TOOLTIP_STRING_KEYS.SWAP_BODY }), body: stringGetter({ key: TOOLTIP_STRING_KEYS.SWAP_BODY }),
-4
View File
@@ -5,10 +5,6 @@ export const withdrawTooltips: TooltipStrings = {
title: stringGetter({ key: TOOLTIP_STRING_KEYS.FAST_WITHDRAW_FEE_TITLE }), title: stringGetter({ key: TOOLTIP_STRING_KEYS.FAST_WITHDRAW_FEE_TITLE }),
body: stringGetter({ key: TOOLTIP_STRING_KEYS.FAST_WITHDRAW_FEE_BODY }), body: stringGetter({ key: TOOLTIP_STRING_KEYS.FAST_WITHDRAW_FEE_BODY }),
}), }),
'minimum-amount-received': ({ stringGetter }) => ({
title: stringGetter({ key: TOOLTIP_STRING_KEYS.MINIMUM_AMOUNT_RECEIVED_TITLE }),
body: stringGetter({ key: TOOLTIP_STRING_KEYS.MINIMUM_AMOUNT_RECEIVED_BODY }),
}),
'withdraw-types': ({ stringGetter }) => ({ 'withdraw-types': ({ stringGetter }) => ({
title: stringGetter({ key: TOOLTIP_STRING_KEYS.WITHDRAW_TYPES_TITLE }), title: stringGetter({ key: TOOLTIP_STRING_KEYS.WITHDRAW_TYPES_TITLE }),
body: stringGetter({ key: TOOLTIP_STRING_KEYS.WITHDRAW_TYPES_BODY }), body: stringGetter({ key: TOOLTIP_STRING_KEYS.WITHDRAW_TYPES_BODY }),
+11 -28
View File
@@ -5,15 +5,16 @@ import { useMatch, useNavigate } from 'react-router-dom';
import { LocalStorageKey } from '@/constants/localStorage'; import { LocalStorageKey } from '@/constants/localStorage';
import { DEFAULT_MARKETID } from '@/constants/markets'; import { DEFAULT_MARKETID } from '@/constants/markets';
import { AppRoute } from '@/constants/routes'; import { AppRoute } from '@/constants/routes';
import { useLocalStorage } from '@/hooks/useLocalStorage';
import { getSelectedNetwork } from '@/state/appSelectors'; import { getSelectedNetwork } from '@/state/appSelectors';
import { closeDialogInTradeBox } from '@/state/dialogs'; import { closeDialogInTradeBox } from '@/state/dialogs';
import { setCurrentMarketId } from '@/state/perpetuals'; import { setCurrentMarketId } from '@/state/perpetuals';
import { getMarketIds } from '@/state/perpetualsSelectors';
import abacusStateManager from '@/lib/abacus'; import abacusStateManager from '@/lib/abacus';
import { useLocalStorage } from './useLocalStorage';
import { getMarketIds } from '@/state/perpetualsSelectors';
export const useCurrentMarketId = () => { export const useCurrentMarketId = () => {
const navigate = useNavigate(); const navigate = useNavigate();
const match = useMatch(`/${AppRoute.Trade}/:marketId`); const match = useMatch(`/${AppRoute.Trade}/:marketId`);
@@ -32,35 +33,17 @@ export const useCurrentMarketId = () => {
if (marketIds.length === 0) return marketId ?? lastViewedMarket; if (marketIds.length === 0) return marketId ?? lastViewedMarket;
if (!marketIds.includes(marketId ?? lastViewedMarket)) return DEFAULT_MARKETID; if (!marketIds.includes(marketId ?? lastViewedMarket)) return DEFAULT_MARKETID;
return marketId ?? lastViewedMarket; return marketId ?? lastViewedMarket;
}, [hasMarketIds, marketId]); }, [marketIds, marketId]);
useEffect(() => { useEffect(() => {
// If v4_markets has not been subscribed to yet or marketId is not specified, default to validId setLastViewedMarket(validId);
if (!hasMarketIds || !marketId) { dispatch(setCurrentMarketId(validId));
setLastViewedMarket(validId); dispatch(closeDialogInTradeBox());
dispatch(setCurrentMarketId(validId));
dispatch(closeDialogInTradeBox());
if (validId !== marketId) { navigate(`${AppRoute.Trade}/${validId}`, {
navigate(`${AppRoute.Trade}/${validId}`, { replace: true,
replace: true, });
}); }, [validId]);
}
} else {
// If v4_markets has been subscribed to, check if marketId is valid
if (!marketIds.includes(marketId)) {
// If marketId is not valid (i.e. final settlement), navigate to markets page
navigate(AppRoute.Markets, {
replace: true,
});
} else {
// If marketId is valid, set currentMarketId
setLastViewedMarket(marketId);
dispatch(setCurrentMarketId(marketId));
dispatch(closeDialogInTradeBox());
}
}
}, [hasMarketIds, marketId]);
useEffect(() => { useEffect(() => {
// Check for marketIds otherwise Abacus will silently fail its isMarketValid check // Check for marketIds otherwise Abacus will silently fail its isMarketValid check
+11 -2
View File
@@ -1,7 +1,14 @@
import { useMemo } from 'react'; import { useMemo } from 'react';
import { useSelector, shallowEqual } from 'react-redux'; import { useSelector, shallowEqual } from 'react-redux';
import { MarketFilters, MARKET_FILTER_LABELS, type MarketData } from '@/constants/markets'; import {
MarketFilters,
MARKET_FILTER_LABELS,
type MarketData,
MARKETS_TO_DISPLAY,
} from '@/constants/markets';
import { testFlags } from '@/lib/testFlags';
import { getAssets } from '@/state/assetsSelectors'; import { getAssets } from '@/state/assetsSelectors';
import { getPerpetualMarkets } from '@/state/perpetualsSelectors'; import { getPerpetualMarkets } from '@/state/perpetualsSelectors';
@@ -42,7 +49,9 @@ export const useMarketsData = (
}, [allPerpetualMarkets, allAssets]); }, [allPerpetualMarkets, allAssets]);
const filteredMarkets = useMemo(() => { const filteredMarkets = useMemo(() => {
const filtered = markets.filter(filterFunctions[filter]); const filtered = markets
.filter(filterFunctions[filter])
.filter(({ id }) => (testFlags.displayAllMarkets ? true : MARKETS_TO_DISPLAY.includes(id)));
if (searchFilter) { if (searchFilter) {
return filtered.filter( return filtered.filter(
+2 -2
View File
@@ -157,8 +157,8 @@ export const notificationTypes: NotificationTypeConfig[] = [
const isFinished = Boolean(status) && status?.squidTransactionStatus !== 'ongoing'; const isFinished = Boolean(status) && status?.squidTransactionStatus !== 'ongoing';
const icon = <Icon iconName={isFinished ? IconName.Transfer : IconName.Clock} />; const icon = <Icon iconName={isFinished ? IconName.Transfer : IconName.Clock} />;
const transferType = const transferType = type ??
type ?? fromChainId === ENVIRONMENT_CONFIG_MAP[selectedNetwork].dydxChainId fromChainId === ENVIRONMENT_CONFIG_MAP[selectedNetwork].dydxChainId
? TransferNotificationTypes.Withdrawal ? TransferNotificationTypes.Withdrawal
: TransferNotificationTypes.Deposit; : TransferNotificationTypes.Deposit;
-1
View File
@@ -44,7 +44,6 @@ export { default as OrderbookIcon } from './orderbook.svg';
export { default as OverviewIcon } from './overview.svg'; export { default as OverviewIcon } from './overview.svg';
export { default as PencilIcon } from './pencil.svg'; export { default as PencilIcon } from './pencil.svg';
export { default as PlayIcon } from './play.svg'; export { default as PlayIcon } from './play.svg';
export { default as PlusIcon } from './plus.svg';
export { default as PortfolioIcon } from './portfolio.svg'; export { default as PortfolioIcon } from './portfolio.svg';
export { default as PositionsIcon } from './positions.svg'; export { default as PositionsIcon } from './positions.svg';
export { default as PriceChartIcon } from './price-chart.svg'; export { default as PriceChartIcon } from './price-chart.svg';
-1
View File
@@ -1 +0,0 @@
<svg fill="none" height="12" viewBox="0 0 12 12" width="12" xmlns="http://www.w3.org/2000/svg"><path d="m6.75.75c0-.198912-.07902-.389678-.21967-.53033-.14065-.1406525-.33142-.21967-.53033-.21967s-.38968.0790175-.53033.21967c-.14065.140652-.21967.331418-.21967.53033v4.5h-4.5c-.198912 0-.389678.07902-.53033.21967-.1406525.14065-.21967.33142-.21967.53033s.0790175.38968.21967.53033c.140652.14065.331418.21967.53033.21967h4.5v4.5c0 .1989.07902.3897.21967.5303.14065.1407.33142.2197.53033.2197s.38968-.079.53033-.2197c.14065-.1406.21967-.3314.21967-.5303v-4.5h4.5c.1989 0 .3897-.07902.5303-.21967.1407-.14065.2197-.33142.2197-.53033s-.079-.38968-.2197-.53033c-.1406-.14065-.3314-.21967-.5303-.21967h-4.5z" fill="currentColor"/></svg>

Before

Width:  |  Height:  |  Size: 731 B

+33 -25
View File
@@ -212,8 +212,8 @@ class DydxChainTransactions implements AbacusDYDXChainTransactionsProtocol {
timeInForce as OrderTimeInForce, timeInForce as OrderTimeInForce,
goodTilTimeInSeconds ?? 0, goodTilTimeInSeconds ?? 0,
execution as OrderExecution, execution as OrderExecution,
postOnly ?? undefined, postOnly,
reduceOnly ?? undefined, reduceOnly,
triggerPrice ?? undefined triggerPrice ?? undefined
); );
@@ -351,7 +351,12 @@ class DydxChainTransactions implements AbacusDYDXChainTransactionsProtocol {
} }
} }
async sendNobleIBC(params: { msgTypeUrl: string; msg: any }): Promise<string> { async sendNobleIBC(
params: {
msgTypeUrl: string,
msg: any,
}
): Promise<string> {
if (!this.nobleClient?.isConnected) { if (!this.nobleClient?.isConnected) {
throw new Error('Missing nobleClient or localWallet'); throw new Error('Missing nobleClient or localWallet');
} }
@@ -362,16 +367,15 @@ class DydxChainTransactions implements AbacusDYDXChainTransactionsProtocol {
value: params.msg, value: params.msg,
}; };
const fee = await this.nobleClient.simulateTransaction([ibcMsg]); const fee = await this.nobleClient.simulateTransaction([ibcMsg]);
// take out fee from amount before sweeping // take out fee from amount before sweeping
const amount = const amount = parseInt(ibcMsg.value.token.amount, 10) -
parseInt(ibcMsg.value.token.amount, 10) -
Math.floor(parseInt(fee.amount[0].amount, 10) * GAS_MULTIPLIER); Math.floor(parseInt(fee.amount[0].amount, 10) * GAS_MULTIPLIER);
if (amount <= 0) { if (amount <= 0) {
throw new Error('noble balance does not cover fees'); throw new Error('noble balance does not cover fees');
} }
ibcMsg.value.token.amount = amount.toString(); ibcMsg.value.token.amount = amount.toString();
const tx = await this.nobleClient.send([ibcMsg]); const tx = await this.nobleClient.send([ibcMsg]);
@@ -387,21 +391,23 @@ class DydxChainTransactions implements AbacusDYDXChainTransactionsProtocol {
} }
} }
async withdrawToNobleIBC(params: { async withdrawToNobleIBC(
subaccountNumber: number; params: {
amount: string; subaccountNumber: number,
ibcPayload: string; amount: string,
}): Promise<string> { ibcPayload: string,
}
): Promise<string> {
if (!this.compositeClient || !this.localWallet) { if (!this.compositeClient || !this.localWallet) {
throw new Error('Missing compositeClient or localWallet'); throw new Error('Missing compositeClient or localWallet');
} }
const { subaccountNumber, amount, ibcPayload } = params ?? {}; const { subaccountNumber, amount, ibcPayload } = params ?? {};
const parsedIbcPayload: { const parsedIbcPayload: {
msgTypeUrl: string; msgTypeUrl: string,
msg: any; msg: any,
} = ibcPayload ? JSON.parse(atob(ibcPayload)) : undefined; } = ibcPayload ? JSON.parse(ibcPayload) : undefined;
try { try {
const msg = this.compositeClient.withdrawFromSubaccountMessage( const msg = this.compositeClient.withdrawFromSubaccountMessage(
new SubaccountClient(this.localWallet, subaccountNumber), new SubaccountClient(this.localWallet, subaccountNumber),
@@ -419,7 +425,7 @@ class DydxChainTransactions implements AbacusDYDXChainTransactionsProtocol {
); );
return JSON.stringify({ return JSON.stringify({
txHash: hashFromTx(tx?.hash), txHash: hashFromTx(tx?.hash)
}); });
} catch (error) { } catch (error) {
log('DydxChainTransactions/withdrawToNobleIBC', error); log('DydxChainTransactions/withdrawToNobleIBC', error);
@@ -430,7 +436,10 @@ class DydxChainTransactions implements AbacusDYDXChainTransactionsProtocol {
} }
} }
async cctpWithdraw(params: { typeUrl: string; value: any }): Promise<string> { async cctpWithdraw(params: {
typeUrl: string,
value: any,
}): Promise<string> {
if (!this.nobleClient?.isConnected) { if (!this.nobleClient?.isConnected) {
throw new Error('Missing nobleClient or localWallet'); throw new Error('Missing nobleClient or localWallet');
} }
@@ -441,18 +450,17 @@ class DydxChainTransactions implements AbacusDYDXChainTransactionsProtocol {
value: params.value, value: params.value,
}; };
const fee = await this.nobleClient.simulateTransaction([ibcMsg]); const fee = await this.nobleClient.simulateTransaction([ibcMsg]);
// take out fee from amount before sweeping // take out fee from amount before sweeping
const amount = const amount = parseInt(ibcMsg.value.amount, 10) -
parseInt(ibcMsg.value.amount, 10) -
Math.floor(parseInt(fee.amount[0].amount, 10) * GAS_MULTIPLIER); Math.floor(parseInt(fee.amount[0].amount, 10) * GAS_MULTIPLIER);
if (amount <= 0) { if (amount <= 0) {
throw new Error('noble balance does not cover fees'); throw new Error('noble balance does not cover fees');
} }
ibcMsg.value.amount = amount.toString(); ibcMsg.value.amount = amount.toString();
const tx = await this.nobleClient.send([ibcMsg]); const tx = await this.nobleClient.send([ibcMsg]);
const parsedTx = this.parseToPrimitives(tx); const parsedTx = this.parseToPrimitives(tx);
+2 -1
View File
@@ -84,7 +84,8 @@ class AbacusStateManager {
); );
const appConfigs = AbacusAppConfig.Companion.forWeb; const appConfigs = AbacusAppConfig.Companion.forWeb;
appConfigs.squidVersion = AbacusAppConfig.SquidVersion.V2; if (!isMainnet || testFlags.withCCTP)
appConfigs.squidVersion = AbacusAppConfig.SquidVersion.V2;
this.stateManager = new AsyncAbacusStateManager( this.stateManager = new AsyncAbacusStateManager(
'', '',
+6 -2
View File
@@ -5,13 +5,13 @@ class TestFlags {
this.queryParams = {}; this.queryParams = {};
const hash = window.location.hash; const hash = window.location.hash;
const queryIndex = hash.indexOf('?'); const queryIndex = hash.indexOf('?');
if (queryIndex === -1) return; if (queryIndex === -1) return
const queryParamsString = hash.substring(queryIndex + 1); const queryParamsString = hash.substring(queryIndex + 1);
const params = new URLSearchParams(queryParamsString); const params = new URLSearchParams(queryParamsString);
for (const [key, value] of params) { for (const [key, value] of params) {
this.queryParams[key] = value; this.queryParams[key] = value;
} }
} }
@@ -19,6 +19,10 @@ class TestFlags {
return !!this.queryParams.displayInitializingMarkets; return !!this.queryParams.displayInitializingMarkets;
} }
get displayAllMarkets() {
return !!this.queryParams.displayAllMarkets;
}
get withCCTP() { get withCCTP() {
return !!this.queryParams.withCCTP; return !!this.queryParams.withCCTP;
} }
+1 -1
View File
@@ -146,7 +146,7 @@ const getConnectors = (walletConnectConfig: WalletConnectConfig) => [
new CoinbaseWalletConnector({ new CoinbaseWalletConnector({
chains, chains,
options: { options: {
appName: 'dYdX', appName: 'wagmi',
reloadOnDisconnect: false, reloadOnDisconnect: false,
}, },
}), }),
+1 -3
View File
@@ -1,6 +1,4 @@
import { DialogPlacement } from '@/components/Dialog'; import { DialogPlacement } from '@/components/Dialog';
import { NotificationsMenu } from '@/views/menus/NotificationsMenu'; import { NotificationsMenu } from '@/views/menus/NotificationsMenu';
const AlertsPage = () => <NotificationsMenu placement={DialogPlacement.Inline} />; export const AlertsPage = () => <NotificationsMenu placement={DialogPlacement.Inline} />;
export default AlertsPage;
+1 -3
View File
@@ -2,7 +2,7 @@ import styled, { AnyStyledComponent } from 'styled-components';
import { articleMixins } from '@/styles/articleMixins'; import { articleMixins } from '@/styles/articleMixins';
const PrivacyPolicyPage = () => ( export const PrivacyPolicyPage = () => (
<Styled.Article> <Styled.Article>
<header> <header>
<h1>Privacy Policy</h1> <h1>Privacy Policy</h1>
@@ -10,8 +10,6 @@ const PrivacyPolicyPage = () => (
</Styled.Article> </Styled.Article>
); );
export default PrivacyPolicyPage;
const Styled: Record<string, AnyStyledComponent> = {}; const Styled: Record<string, AnyStyledComponent> = {};
Styled.Article = styled.article` Styled.Article = styled.article`
+1 -3
View File
@@ -2,7 +2,7 @@ import styled, { AnyStyledComponent } from 'styled-components';
import { articleMixins } from '@/styles/articleMixins'; import { articleMixins } from '@/styles/articleMixins';
const TermsOfUsePage = () => ( export const TermsOfUsePage = () => (
<Styled.Article> <Styled.Article>
<header> <header>
<h1>Sample Terms of Use</h1> <h1>Sample Terms of Use</h1>
@@ -1076,8 +1076,6 @@ const TermsOfUsePage = () => (
</Styled.Article> </Styled.Article>
); );
export default TermsOfUsePage;
const Styled: Record<string, AnyStyledComponent> = {}; const Styled: Record<string, AnyStyledComponent> = {};
Styled.Article = styled.article` Styled.Article = styled.article`
+53 -58
View File
@@ -1,20 +1,17 @@
import { lazy, Suspense } from 'react';
import { shallowEqual, useDispatch, useSelector } from 'react-redux'; import { shallowEqual, useDispatch, useSelector } from 'react-redux';
import styled, { type AnyStyledComponent } from 'styled-components'; import styled, { type AnyStyledComponent } from 'styled-components';
import { Navigate, Route, Routes } from 'react-router-dom'; import { Navigate, Route, Routes } from 'react-router-dom';
import { OnboardingState } from '@/constants/account'; import { OnboardingState } from '@/constants/account';
import { ButtonAction } from '@/constants/buttons';
import { DialogTypes } from '@/constants/dialogs'; import { DialogTypes } from '@/constants/dialogs';
import { STRING_KEYS } from '@/constants/localization'; import { STRING_KEYS } from '@/constants/localization';
import { HistoryRoute, PortfolioRoute } from '@/constants/routes'; import { HistoryRoute, PortfolioRoute } from '@/constants/routes';
import { useAccountBalance, useBreakpoints, useDocumentTitle, useStringGetter } from '@/hooks'; import { useAccountBalance, useBreakpoints, useDocumentTitle, useStringGetter } from '@/hooks';
import { layoutMixins } from '@/styles/layoutMixins';
import { FillsTable, FillsTableColumnKey } from '@/views/tables/FillsTable'; import { FillsTable, FillsTableColumnKey } from '@/views/tables/FillsTable';
import { FundingPaymentsTable } from '@/views/tables/FundingPaymentsTable'; import { FundingPaymentsTable } from '@/views/tables/FundingPaymentsTable';
import { TransferHistoryTable } from '@/views/tables/TransferHistoryTable'; import { TransferHistoryTable } from '@/views/tables/TransferHistoryTable';
import { Button } from '@/components/Button';
import { Icon, IconName } from '@/components/Icon'; import { Icon, IconName } from '@/components/Icon';
import { NavigationMenu } from '@/components/NavigationMenu'; import { NavigationMenu } from '@/components/NavigationMenu';
import { WithSidebar } from '@/components/WithSidebar'; import { WithSidebar } from '@/components/WithSidebar';
@@ -23,15 +20,15 @@ import { getOnboardingState, getSubaccount } from '@/state/accountSelectors';
import { openDialog } from '@/state/dialogs'; import { openDialog } from '@/state/dialogs';
import { PortfolioNavMobile } from './PortfolioNavMobile'; import { PortfolioNavMobile } from './PortfolioNavMobile';
import { LoadingSpace } from '@/components/Loading/LoadingSpinner'; import { Overview } from './Overview';
import { Positions } from './Positions';
import { Orders } from './Orders';
import { Fees } from './Fees';
import { History } from './History';
const Overview = lazy(() => import('./Overview').then((module) => ({ default: module.Overview }))); import { layoutMixins } from '@/styles/layoutMixins';
const Positions = lazy(() => import { Button } from '@/components/Button';
import('./Positions').then((module) => ({ default: module.Positions })) import { ButtonAction } from '@/constants/buttons';
);
const Orders = lazy(() => import('./Orders').then((module) => ({ default: module.Orders })));
const Fees = lazy(() => import('./Fees').then((module) => ({ default: module.Fees })));
const History = lazy(() => import('./History').then((module) => ({ default: module.History })));
export default () => { export default () => {
const dispatch = useDispatch(); const dispatch = useDispatch();
@@ -47,51 +44,49 @@ export default () => {
useDocumentTitle(stringGetter({ key: STRING_KEYS.PORTFOLIO })); useDocumentTitle(stringGetter({ key: STRING_KEYS.PORTFOLIO }));
const routesComponent = ( const routesComponent = (
<Suspense fallback={<LoadingSpace id="portfolio" />}> <Routes>
<Routes> <Route path={PortfolioRoute.Overview} element={<Overview />} />
<Route path={PortfolioRoute.Overview} element={<Overview />} /> <Route path={PortfolioRoute.Positions} element={<Positions />} />
<Route path={PortfolioRoute.Positions} element={<Positions />} /> <Route path={PortfolioRoute.Orders} element={<Orders />} />
<Route path={PortfolioRoute.Orders} element={<Orders />} /> <Route path={PortfolioRoute.Fees} element={<Fees />} />
<Route path={PortfolioRoute.Fees} element={<Fees />} /> <Route path={PortfolioRoute.History} element={<History />}>
<Route path={PortfolioRoute.History} element={<History />}> <Route index path="*" element={<Navigate to={HistoryRoute.Trades} />} />
<Route index path="*" element={<Navigate to={HistoryRoute.Trades} />} /> <Route
<Route path={HistoryRoute.Trades}
path={HistoryRoute.Trades} element={
element={ <FillsTable
<FillsTable columnKeys={
columnKeys={ isTablet
isTablet ? [
? [ FillsTableColumnKey.Time,
FillsTableColumnKey.Time, FillsTableColumnKey.TypeAmount,
FillsTableColumnKey.TypeAmount, FillsTableColumnKey.PriceFee,
FillsTableColumnKey.PriceFee, ]
] : [
: [ FillsTableColumnKey.Time,
FillsTableColumnKey.Time, FillsTableColumnKey.Market,
FillsTableColumnKey.Market, FillsTableColumnKey.Side,
FillsTableColumnKey.Side, FillsTableColumnKey.AmountPrice,
FillsTableColumnKey.AmountPrice, FillsTableColumnKey.TotalFee,
FillsTableColumnKey.TotalFee, FillsTableColumnKey.Type,
FillsTableColumnKey.Type, FillsTableColumnKey.Liquidity,
FillsTableColumnKey.Liquidity, ]
] }
} withOuterBorder={isNotTablet}
withOuterBorder={isNotTablet} />
/> }
} />
/> <Route
<Route path={HistoryRoute.Transfers}
path={HistoryRoute.Transfers} element={<TransferHistoryTable withOuterBorder={isNotTablet} />}
element={<TransferHistoryTable withOuterBorder={isNotTablet} />} />
/> <Route
<Route path={HistoryRoute.Payments}
path={HistoryRoute.Payments} element={<FundingPaymentsTable withOuterBorder={isNotTablet} />}
element={<FundingPaymentsTable withOuterBorder={isNotTablet} />} />
/> </Route>
</Route> <Route path="*" element={<Navigate to={PortfolioRoute.Overview} replace />} />
<Route path="*" element={<Navigate to={PortfolioRoute.Overview} replace />} /> </Routes>
</Routes>
</Suspense>
); );
return isTablet ? ( return isTablet ? (
@@ -196,7 +191,7 @@ Styled.SideBar = styled.div`
Styled.Footer = styled.div` Styled.Footer = styled.div`
${layoutMixins.row} ${layoutMixins.row}
flex-wrap: wrap; flex-wrap: wrap;
padding: 1rem; padding: 1rem;
gap: 0.5rem; gap: 0.5rem;
-80
View File
@@ -1,80 +0,0 @@
import styled, { AnyStyledComponent } from 'styled-components';
import { STRING_KEYS } from '@/constants/localization';
import { layoutMixins } from '@/styles/layoutMixins';
import { useStringGetter } from '@/hooks';
import { Accordion } from '@/components/Accordion';
import { Link } from '@/components/Link';
import { Panel } from '@/components/Panel';
const REWARDS_LEARN_MORE_LINK = ''; // to be configured
export const RewardsHelpPanel = () => {
const stringGetter = useStringGetter();
return (
<Styled.HelpCard
slotHeader={
<Styled.Header>
<h3>{stringGetter({ key: STRING_KEYS.HELP })}</h3>
{REWARDS_LEARN_MORE_LINK && (
<Link withIcon href={REWARDS_LEARN_MORE_LINK}>
{stringGetter({ key: STRING_KEYS.LEARN_MORE })}
</Link>
)}
</Styled.Header>
}
>
<Accordion
items={[
{
header: 'Who is eligible for trading rewards?',
content: 'All traders are eligible for trading rewards.',
},
{
header: 'How do trading rewards work?',
content:
'Immediately after each fill, trading rewards are sent directly to the traders dYdX Chain address, based on the amount of fees paid by the trader.',
},
{
header: 'How do I claim my rewards?',
content:
'Each block, trading rewards are automatically sent directly to the traders dYdX Chain address.',
},
]}
/>
</Styled.HelpCard>
);
};
const Styled: Record<string, AnyStyledComponent> = {};
Styled.HelpCard = styled(Panel)`
--panel-content-paddingY: 0;
width: 100%;
height: max-content;
padding: 0;
gap: 0;
text-align: start;
`;
Styled.Header = styled.div`
${layoutMixins.spacedRow}
gap: 1ch;
padding: 1.25rem 1.5rem;
border-bottom: var(--border-width) solid var(--border-color);
font: var(--font-small-book);
h3 {
font: var(--font-medium-book);
color: var(--color-text-2);
}
`;
Styled.Link = styled(Link)`
display: inline-flex;
`;
+1 -3
View File
@@ -21,7 +21,7 @@ import { DYDXBalancePanel } from './DYDXBalancePanel';
import { MigratePanel } from './MigratePanel'; import { MigratePanel } from './MigratePanel';
import { LaunchIncentivesPanel } from './LaunchIncentivesPanel'; import { LaunchIncentivesPanel } from './LaunchIncentivesPanel';
const RewardsPage = () => { export const RewardsPage = () => {
const dispatch = useDispatch(); const dispatch = useDispatch();
const stringGetter = useStringGetter(); const stringGetter = useStringGetter();
const { governanceLearnMore, stakingLearnMore } = useURLConfigs(); const { governanceLearnMore, stakingLearnMore } = useURLConfigs();
@@ -84,8 +84,6 @@ const RewardsPage = () => {
); );
}; };
export default RewardsPage;
const Styled: Record<string, AnyStyledComponent> = {}; const Styled: Record<string, AnyStyledComponent> = {};
Styled.Page = styled.div` Styled.Page = styled.div`
+1 -3
View File
@@ -25,7 +25,7 @@ import { useNetworks } from '@/views/menus/useNetworks';
import { SettingsHeader } from './SettingsHeader'; import { SettingsHeader } from './SettingsHeader';
import { ComingSoonSpace } from '@/components/ComingSoon'; import { ComingSoonSpace } from '@/components/ComingSoon';
const SettingsPage = () => { export const SettingsPage = () => {
const stringGetter = useStringGetter(); const stringGetter = useStringGetter();
const { pathname } = useLocation(); const { pathname } = useLocation();
const dispatch = useDispatch(); const dispatch = useDispatch();
@@ -105,5 +105,3 @@ const SettingsPage = () => {
</> </>
); );
}; };
export default SettingsPage;
+1
View File
@@ -83,6 +83,7 @@ export const HorizontalPanel = ({ isOpen = true, setIsOpen }: ElementProps) => {
const tabItems = useMemo( const tabItems = useMemo(
() => [ () => [
{ {
asChild: true,
value: InfoSection.Position, value: InfoSection.Position,
label: stringGetter({ label: stringGetter({
key: showCurrentMarket ? STRING_KEYS.POSITION : STRING_KEYS.POSITIONS, key: showCurrentMarket ? STRING_KEYS.POSITION : STRING_KEYS.POSITIONS,
+3
View File
@@ -2,7 +2,9 @@ import styled, { type AnyStyledComponent } from 'styled-components';
import { shallowEqual, useSelector } from 'react-redux'; import { shallowEqual, useSelector } from 'react-redux';
import { STRING_KEYS } from '@/constants/localization'; import { STRING_KEYS } from '@/constants/localization';
import { MARKETS_TO_DISPLAY } from '@/constants/markets';
import { useBreakpoints, useStringGetter } from '@/hooks'; import { useBreakpoints, useStringGetter } from '@/hooks';
import { testFlags } from '@/lib/testFlags';
import { breakpoints } from '@/styles'; import { breakpoints } from '@/styles';
import { layoutMixins } from '@/styles/layoutMixins'; import { layoutMixins } from '@/styles/layoutMixins';
@@ -32,6 +34,7 @@ export const ExchangeBillboards: React.FC<ExchangeBillboardsProps> = ({
Object.values(perpetualMarkets) Object.values(perpetualMarkets)
.filter(Boolean) .filter(Boolean)
.filter(({ id }) => (testFlags.displayAllMarkets ? true : MARKETS_TO_DISPLAY.includes(id)))
.forEach(({ oraclePrice, perpetual }) => { .forEach(({ oraclePrice, perpetual }) => {
const { volume24H, trades24H, openInterest = 0 } = perpetual || {}; const { volume24H, trades24H, openInterest = 0 } = perpetual || {};
volume24HUSDC += volume24H ?? 0; volume24HUSDC += volume24H ?? 0;
@@ -94,7 +94,7 @@ export const FillDetailsDialog = ({ fillId, setIsOpen }: ElementProps) => {
return ( return (
<DetailsDialog <DetailsDialog
slotIcon={<Styled.AssetIcon symbol={asset?.id} />} slotIcon={<Styled.AssetIcon symbol={asset.id} />}
title={resources.typeStringKey && stringGetter({ key: resources.typeStringKey })} title={resources.typeStringKey && stringGetter({ key: resources.typeStringKey })}
items={detailItems} items={detailItems}
setIsOpen={setIsOpen} setIsOpen={setIsOpen}
@@ -194,7 +194,7 @@ export const OrderDetailsDialog = ({ orderId, setIsOpen }: ElementProps) => {
return ( return (
<DetailsDialog <DetailsDialog
slotIcon={<Styled.AssetIcon symbol={asset?.id} />} slotIcon={<Styled.AssetIcon symbol={asset.id} />}
title={!resources.typeStringKey ? '' : stringGetter({ key: resources.typeStringKey })} title={!resources.typeStringKey ? '' : stringGetter({ key: resources.typeStringKey })}
slotFooter={ slotFooter={
isAccountViewOnly ? null : isOrderStatusClearable(status) ? ( isAccountViewOnly ? null : isOrderStatusClearable(status) ? (
+1 -5
View File
@@ -8,7 +8,6 @@ import { ComboboxDialogMenu } from '@/components/ComboboxDialogMenu';
import { Icon, IconName } from '@/components/Icon'; import { Icon, IconName } from '@/components/Icon';
import { isTruthy } from '@/lib/isTruthy'; import { isTruthy } from '@/lib/isTruthy';
import { breakpoints } from '@/styles';
type ElementProps = { type ElementProps = {
setIsOpen: (open: boolean) => void; setIsOpen: (open: boolean) => void;
@@ -73,11 +72,8 @@ export const HelpDialog = ({ setIsOpen }: ElementProps) => {
const Styled: Record<string, AnyStyledComponent> = {}; const Styled: Record<string, AnyStyledComponent> = {};
Styled.ComboboxDialogMenu = styled(ComboboxDialogMenu)` Styled.ComboboxDialogMenu = styled(ComboboxDialogMenu)`
--dialog-width: var(--dialog-small-width);
--dialog-content-paddingTop: 1rem; --dialog-content-paddingTop: 1rem;
--dialog-content-paddingBottom: 1rem; --dialog-content-paddingBottom: 1rem;
--comboxDialogMenu-item-gap: 1rem; --comboxDialogMenu-item-gap: 1rem;
@media ${breakpoints.notMobile} {
--dialog-width: var(--dialog-small-width);
}
`; `;
@@ -18,7 +18,11 @@ type ElementProps = {
onSelectChain: (chain: string) => void; onSelectChain: (chain: string) => void;
}; };
export const ChainSelectMenu = ({ label, selectedChain, onSelectChain }: ElementProps) => { export const ChainSelectMenu = ({
label,
selectedChain,
onSelectChain,
}: ElementProps) => {
const stringGetter = useStringGetter(); const stringGetter = useStringGetter();
const { type, depositOptions, withdrawalOptions, resources } = const { type, depositOptions, withdrawalOptions, resources } =
useSelector(getTransferInputs, shallowEqual) || {}; useSelector(getTransferInputs, shallowEqual) || {};
@@ -34,7 +38,7 @@ export const ChainSelectMenu = ({ label, selectedChain, onSelectChain }: Element
slotBefore: <Styled.Img src={chain.iconUrl} alt="" />, slotBefore: <Styled.Img src={chain.iconUrl} alt="" />,
})); }));
const selectedOption = chains.find((item) => item.type === selectedChain); const selectedOption = chains.find((item) => item.type === selectedChain);
return ( return (
<SearchSelectMenu <SearchSelectMenu
@@ -77,4 +81,4 @@ Styled.ChainRow = styled.div`
gap: 0.5rem; gap: 0.5rem;
color: var(--color-text-2); color: var(--color-text-2);
font: var(--font-base-book); font: var(--font-base-book);
`; `;
@@ -10,8 +10,9 @@ import { TransferInputField, TransferInputTokenResource, TransferType } from '@/
import { AlertType } from '@/constants/alerts'; import { AlertType } from '@/constants/alerts';
import { ButtonSize } from '@/constants/buttons'; import { ButtonSize } from '@/constants/buttons';
import { STRING_KEYS } from '@/constants/localization'; import { STRING_KEYS } from '@/constants/localization';
import { ENVIRONMENT_CONFIG_MAP, isMainnet } from '@/constants/networks'; import { ENVIRONMENT_CONFIG_MAP } from '@/constants/networks';
import { MAX_CCTP_TRANSFER_AMOUNT, MAX_PRICE_IMPACT, NumberSign } from '@/constants/numbers'; import { NotificationStatus } from '@/constants/notifications';
import { NumberSign } from '@/constants/numbers';
import type { EvmAddress } from '@/constants/wallets'; import type { EvmAddress } from '@/constants/wallets';
import { useAccounts, useDebounce, useStringGetter, useSelectedNetwork } from '@/hooks'; import { useAccounts, useDebounce, useStringGetter, useSelectedNetwork } from '@/hooks';
@@ -252,9 +253,7 @@ export const DepositForm = ({ onDeposit, onError }: DepositFormProps) => {
if (txHash) { if (txHash) {
addTransferNotification({ addTransferNotification({
txHash: txHash, txHash: txHash,
toChainId: !isCctp toChainId: !isCctp ? ENVIRONMENT_CONFIG_MAP[selectedNetwork].dydxChainId : getNobleChainId(),
? ENVIRONMENT_CONFIG_MAP[selectedNetwork].dydxChainId
: getNobleChainId(),
fromChainId: chainIdStr || undefined, fromChainId: chainIdStr || undefined,
toAmount: summary?.usdcSize || undefined, toAmount: summary?.usdcSize || undefined,
triggeredAt: Date.now(), triggeredAt: Date.now(),
@@ -325,21 +324,6 @@ export const DepositForm = ({ onDeposit, onError }: DepositFormProps) => {
return stringGetter({ key: STRING_KEYS.DEPOSIT_MORE_THAN_BALANCE }); return stringGetter({ key: STRING_KEYS.DEPOSIT_MORE_THAN_BALANCE });
} }
if (isCctp) {
if (MustBigNumber(debouncedAmountBN).gte(MAX_CCTP_TRANSFER_AMOUNT)) {
return stringGetter({
key: STRING_KEYS.MAX_CCTP_TRANSFER_LIMIT_EXCEEDED,
params: {
MAX_CCTP_TRANSFER_AMOUNT: MAX_CCTP_TRANSFER_AMOUNT,
},
});
}
}
if (isMainnet && MustBigNumber(summary?.aggregatePriceImpact).gte(MAX_PRICE_IMPACT)) {
return stringGetter({ key: STRING_KEYS.PRICE_IMPACT_TOO_HIGH });
}
return undefined; return undefined;
}, [ }, [
error, error,
@@ -350,7 +334,6 @@ export const DepositForm = ({ onDeposit, onError }: DepositFormProps) => {
fromAmount, fromAmount,
sourceToken, sourceToken,
stringGetter, stringGetter,
summary,
]); ]);
const isDisabled = const isDisabled =
@@ -1,16 +1,21 @@
import { type Dispatch, type ReactNode, type SetStateAction, useState, useMemo } from 'react'; import { type Dispatch, type SetStateAction, useState, type ReactNode } from 'react';
import styled, { type AnyStyledComponent } from 'styled-components'; import styled, { type AnyStyledComponent } from 'styled-components';
import { shallowEqual, useSelector } from 'react-redux'; import { shallowEqual, useSelector } from 'react-redux';
import type { RouteData } from '@0xsquid/sdk'; import type { RouteData } from '@0xsquid/sdk';
import { formatUnits } from 'viem';
import { ButtonAction, ButtonShape, ButtonSize, ButtonType } from '@/constants/buttons'; import {
ButtonAction,
ButtonShape,
ButtonSize,
ButtonState,
ButtonType,
} from '@/constants/buttons';
import { TransferInputTokenResource } from '@/constants/abacus'; import { TransferInputTokenResource } from '@/constants/abacus';
import { STRING_KEYS } from '@/constants/localization'; import { STRING_KEYS } from '@/constants/localization';
import { NumberSign, TOKEN_DECIMALS } from '@/constants/numbers'; import { NumberSign } from '@/constants/numbers';
import { useStringGetter, useTokenConfigs } from '@/hooks'; import { useStringGetter } from '@/hooks';
import { useMatchingEvmNetwork } from '@/hooks/useMatchingEvmNetwork'; import { useMatchingEvmNetwork } from '@/hooks/useMatchingEvmNetwork';
import { layoutMixins } from '@/styles/layoutMixins'; import { layoutMixins } from '@/styles/layoutMixins';
@@ -29,7 +34,6 @@ import { calculateCanAccountTrade } from '@/state/accountCalculators';
import { getSubaccountBuyingPower, getSubaccountEquity } from '@/state/accountSelectors'; import { getSubaccountBuyingPower, getSubaccountEquity } from '@/state/accountSelectors';
import { getTransferInputs } from '@/state/inputsSelectors'; import { getTransferInputs } from '@/state/inputsSelectors';
import { isTruthy } from '@/lib/isTruthy';
import { MustBigNumber } from '@/lib/numbers'; import { MustBigNumber } from '@/lib/numbers';
import { SlippageEditor } from '../SlippageEditor'; import { SlippageEditor } from '../SlippageEditor';
@@ -79,8 +83,7 @@ export const DepositButtonAndReceipt = ({
const { current: buyingPower, postOrder: newBuyingPower } = const { current: buyingPower, postOrder: newBuyingPower } =
useSelector(getSubaccountBuyingPower, shallowEqual) || {}; useSelector(getSubaccountBuyingPower, shallowEqual) || {};
const { isCctp, summary, requestPayload } = useSelector(getTransferInputs, shallowEqual) || {}; const { summary, requestPayload } = useSelector(getTransferInputs, shallowEqual) || {};
const { usdcDecimals, usdcLabel } = useTokenConfigs();
const feeSubitems: DetailsItem[] = []; const feeSubitems: DetailsItem[] = [];
@@ -95,7 +98,7 @@ export const DepositButtonAndReceipt = ({
if (typeof summary?.bridgeFee === 'number') { if (typeof summary?.bridgeFee === 'number') {
feeSubitems.push({ feeSubitems.push({
key: 'bridge-fees', key: 'bridge-fees',
label: <span>{stringGetter({ key: STRING_KEYS.BRIDGE_FEE })}</span>, label: <span>Bridge Fee</span>,
value: <Output type={OutputType.Fiat} value={summary?.bridgeFee} />, value: <Output type={OutputType.Fiat} value={summary?.bridgeFee} />,
}); });
} }
@@ -108,68 +111,12 @@ export const DepositButtonAndReceipt = ({
const totalFees = (summary?.bridgeFee || 0) + (summary?.gasFee || 0); const totalFees = (summary?.bridgeFee || 0) + (summary?.gasFee || 0);
const { toAmount, toAmountMin } = useMemo(() => {
if (isCctp) {
return {
toAmount: summary?.toAmount,
toAmountMin: summary?.toAmountMin,
};
} else {
return {
toAmount: summary?.toAmount && formatUnits(BigInt(summary.toAmount), usdcDecimals),
toAmountMin: summary?.toAmountMin && formatUnits(BigInt(summary.toAmountMin), usdcDecimals),
};
}
}, [isCctp, summary]);
const submitButtonReceipt = [ const submitButtonReceipt = [
{
key: 'expected-deposit-amount',
label: (
<span>
{stringGetter({ key: STRING_KEYS.EXPECTED_DEPOSIT_AMOUNT })} <Tag>{usdcLabel}</Tag>
</span>
),
value: <Output type={OutputType.Fiat} fractionDigits={TOKEN_DECIMALS} value={toAmount} />,
subitems: [
{
key: 'minimum-deposit-amount',
label: (
<span>
{stringGetter({ key: STRING_KEYS.MINIMUM_DEPOSIT_AMOUNT })} <Tag>{usdcLabel}</Tag>
</span>
),
value: (
<Output type={OutputType.Fiat} fractionDigits={TOKEN_DECIMALS} value={toAmountMin} />
),
tooltip: 'minimum-deposit-amount',
},
],
},
{
key: 'exchange-rate',
label: <span>{stringGetter({ key: STRING_KEYS.EXCHANGE_RATE })}</span>,
value:
typeof summary?.exchangeRate === 'number' ? (
<Styled.ExchangeRate>
<Output
type={OutputType.Asset}
value={1}
fractionDigits={0}
tag={sourceToken?.symbol}
/>
=
<Output type={OutputType.Asset} value={summary?.exchangeRate} tag={usdcLabel} />
</Styled.ExchangeRate>
) : (
<Output type={OutputType.Asset} />
),
},
{ {
key: 'equity', key: 'equity',
label: ( label: (
<span> <span>
{stringGetter({ key: STRING_KEYS.EQUITY })} <Tag>{usdcLabel}</Tag> {stringGetter({ key: STRING_KEYS.EQUITY })} <Tag>USDC</Tag>
</span> </span>
), ),
value: ( value: (
@@ -186,7 +133,7 @@ export const DepositButtonAndReceipt = ({
key: 'buying-power', key: 'buying-power',
label: ( label: (
<span> <span>
{stringGetter({ key: STRING_KEYS.BUYING_POWER })} <Tag>{usdcLabel}</Tag> {stringGetter({ key: STRING_KEYS.BUYING_POWER })} <Tag>USDC</Tag>
</span> </span>
), ),
value: ( value: (
@@ -199,7 +146,18 @@ export const DepositButtonAndReceipt = ({
/> />
), ),
}, },
!isCctp && { {
key: 'exchange-rate',
label: <span>{stringGetter({ key: STRING_KEYS.EXCHANGE_RATE })}</span>,
value: typeof summary?.exchangeRate === 'number' && (
<Styled.ExchangeRate>
<Output type={OutputType.Asset} value={1} fractionDigits={0} tag={sourceToken?.symbol} />
=
<Output type={OutputType.Asset} value={summary?.exchangeRate} tag="USDC" />
</Styled.ExchangeRate>
),
},
{
key: 'total-fees', key: 'total-fees',
label: <span>{stringGetter({ key: STRING_KEYS.TOTAL_FEES })}</span>, label: <span>{stringGetter({ key: STRING_KEYS.TOTAL_FEES })}</span>,
value: <Output type={OutputType.Fiat} value={totalFees} />, value: <Output type={OutputType.Fiat} value={totalFees} />,
@@ -207,7 +165,7 @@ export const DepositButtonAndReceipt = ({
}, },
{ {
key: 'slippage', key: 'slippage',
label: <span>{stringGetter({ key: STRING_KEYS.MAX_SLIPPAGE })}</span>, label: <span>{stringGetter({ key: STRING_KEYS.SLIPPAGE })}</span>,
value: ( value: (
<SlippageEditor <SlippageEditor
disabled disabled
@@ -220,26 +178,22 @@ export const DepositButtonAndReceipt = ({
{ {
key: 'estimatedRouteDuration', key: 'estimatedRouteDuration',
label: <span>{stringGetter({ key: STRING_KEYS.ESTIMATED_TIME })}</span>, label: <span>{stringGetter({ key: STRING_KEYS.ESTIMATED_TIME })}</span>,
value: ( value: typeof summary?.estimatedRouteDuration === 'number' && (
<Output <Output
type={OutputType.Text} type={OutputType.Text}
value={ value={stringGetter({
typeof summary?.estimatedRouteDuration === 'number' key: STRING_KEYS.X_MINUTES_LOWERCASED,
? stringGetter({ params: {
key: STRING_KEYS.X_MINUTES_LOWERCASED, X:
params: { summary?.estimatedRouteDuration < 60
X: ? '< 1'
summary?.estimatedRouteDuration < 60 : Math.round(summary?.estimatedRouteDuration / 60),
? '< 1' },
: Math.round(summary?.estimatedRouteDuration / 60), })}
},
})
: null
}
/> />
), ),
}, },
].filter(isTruthy); ];
const isFormValid = !isDisabled && !isEditingSlippage; const isFormValid = !isDisabled && !isEditingSlippage;
@@ -9,9 +9,9 @@ import { TransferInputField, TransferInputTokenResource, TransferType } from '@/
import { AlertType } from '@/constants/alerts'; import { AlertType } from '@/constants/alerts';
import { ButtonSize } from '@/constants/buttons'; import { ButtonSize } from '@/constants/buttons';
import { STRING_KEYS } from '@/constants/localization'; import { STRING_KEYS } from '@/constants/localization';
import { ENVIRONMENT_CONFIG_MAP, isMainnet } from '@/constants/networks'; import { ENVIRONMENT_CONFIG_MAP } from '@/constants/networks';
import { TransferNotificationTypes } from '@/constants/notifications'; import { NotificationStatus, TransferNotificationTypes } from '@/constants/notifications';
import { MAX_CCTP_TRANSFER_AMOUNT, MAX_PRICE_IMPACT, NumberSign } from '@/constants/numbers'; import { NumberSign } from '@/constants/numbers';
import { import {
useAccounts, useAccounts,
@@ -67,8 +67,7 @@ export const WithdrawForm = () => {
resources, resources,
errors: routeErrors, errors: routeErrors,
errorMessage: routeErrorMessage, errorMessage: routeErrorMessage,
isCctp, isCctp
summary,
} = useSelector(getTransferInputs, shallowEqual) || {}; } = useSelector(getTransferInputs, shallowEqual) || {};
// User input // User input
@@ -76,6 +75,7 @@ export const WithdrawForm = () => {
const [slippage, setSlippage] = useState(isCctp ? 0 : 0.01); // 0.1% slippage const [slippage, setSlippage] = useState(isCctp ? 0 : 0.01); // 0.1% slippage
const debouncedAmount = useDebounce<string>(withdrawAmount, 500); const debouncedAmount = useDebounce<string>(withdrawAmount, 500);
const isValidAddress = toAddress && isAddress(toAddress); const isValidAddress = toAddress && isAddress(toAddress);
const toToken = useMemo( const toToken = useMemo(
@@ -168,18 +168,12 @@ export const WithdrawForm = () => {
}) })
); );
} else { } else {
const txHash = await sendSquidWithdraw( const txHash = await sendSquidWithdraw(debouncedAmountBN.toNumber(), requestPayload.data, isCctp);
debouncedAmountBN.toNumber(),
requestPayload.data,
isCctp
);
if (txHash) { if (txHash) {
addTransferNotification({ addTransferNotification({
txHash: txHash, txHash: txHash,
type: TransferNotificationTypes.Withdrawal, type: TransferNotificationTypes.Withdrawal,
fromChainId: !isCctp fromChainId: !isCctp ? ENVIRONMENT_CONFIG_MAP[selectedNetwork].dydxChainId : getNobleChainId(),
? ENVIRONMENT_CONFIG_MAP[selectedNetwork].dydxChainId
: getNobleChainId(),
toChainId: chainIdStr || undefined, toChainId: chainIdStr || undefined,
toAmount: debouncedAmountBN.toNumber(), toAmount: debouncedAmountBN.toNumber(),
triggeredAt: Date.now(), triggeredAt: Date.now(),
@@ -289,7 +283,10 @@ export const WithdrawForm = () => {
const errorMessage = useMemo(() => { const errorMessage = useMemo(() => {
if (error) { if (error) {
return error; return stringGetter({
key: STRING_KEYS.SOMETHING_WENT_WRONG_WITH_MESSAGE,
params: { ERROR_MESSAGE: error },
});
} }
if (routeErrors) { if (routeErrors) {
@@ -320,21 +317,6 @@ export const WithdrawForm = () => {
return stringGetter({ key: STRING_KEYS.WITHDRAW_MORE_THAN_FREE }); return stringGetter({ key: STRING_KEYS.WITHDRAW_MORE_THAN_FREE });
} }
if (isCctp) {
if (MustBigNumber(debouncedAmountBN).gte(MAX_CCTP_TRANSFER_AMOUNT)) {
return stringGetter({
key: STRING_KEYS.MAX_CCTP_TRANSFER_LIMIT_EXCEEDED,
params: {
MAX_CCTP_TRANSFER_AMOUNT: MAX_CCTP_TRANSFER_AMOUNT,
},
});
}
}
if (isMainnet && MustBigNumber(summary?.aggregatePriceImpact).gte(MAX_PRICE_IMPACT)) {
return stringGetter({ key: STRING_KEYS.PRICE_IMPACT_TOO_HIGH });
}
return undefined; return undefined;
}, [ }, [
error, error,
@@ -347,7 +329,6 @@ export const WithdrawForm = () => {
toAddress, toAddress,
sanctionedAddresses, sanctionedAddresses,
stringGetter, stringGetter,
summary,
]); ]);
const isDisabled = const isDisabled =
@@ -1,4 +1,4 @@
import { useMemo, useState } from 'react'; import { useState } from 'react';
import { shallowEqual, useSelector } from 'react-redux'; import { shallowEqual, useSelector } from 'react-redux';
import styled, { type AnyStyledComponent } from 'styled-components'; import styled, { type AnyStyledComponent } from 'styled-components';
import { formatUnits } from 'viem'; import { formatUnits } from 'viem';
@@ -6,11 +6,14 @@ import { formatUnits } from 'viem';
import { TransferInputTokenResource } from '@/constants/abacus'; import { TransferInputTokenResource } from '@/constants/abacus';
import { ButtonAction, ButtonShape, ButtonSize, ButtonType } from '@/constants/buttons'; import { ButtonAction, ButtonShape, ButtonSize, ButtonType } from '@/constants/buttons';
import { STRING_KEYS } from '@/constants/localization'; import { STRING_KEYS } from '@/constants/localization';
import { NumberSign, TOKEN_DECIMALS } from '@/constants/numbers'; import { NumberSign } from '@/constants/numbers';
import { formatSeconds } from '@/lib/timeUtils';
import { layoutMixins } from '@/styles/layoutMixins'; import { layoutMixins } from '@/styles/layoutMixins';
import { useStringGetter, useTokenConfigs } from '@/hooks'; import { useStringGetter } from '@/hooks';
import { useAccountBalance } from '@/hooks/useAccountBalance';
import { Button } from '@/components/Button'; import { Button } from '@/components/Button';
@@ -55,9 +58,13 @@ export const WithdrawButtonAndReceipt = ({
const stringGetter = useStringGetter(); const stringGetter = useStringGetter();
const { leverage } = useSelector(getSubaccount, shallowEqual) || {}; const { leverage } = useSelector(getSubaccount, shallowEqual) || {};
const { isCctp, summary, requestPayload } = useSelector(getTransferInputs, shallowEqual) || {}; const { summary, requestPayload } = useSelector(getTransferInputs, shallowEqual) || {};
const canAccountTrade = useSelector(calculateCanAccountTrade, shallowEqual); const canAccountTrade = useSelector(calculateCanAccountTrade, shallowEqual);
const { usdcLabel } = useTokenConfigs();
const toAmount =
summary?.toAmount &&
withdrawToken?.decimals &&
formatUnits(BigInt(summary.toAmount), withdrawToken?.decimals);
const feeSubitems: DetailsItem[] = []; const feeSubitems: DetailsItem[] = [];
@@ -82,29 +89,9 @@ export const WithdrawButtonAndReceipt = ({
const showSubitemsToggle = showFeeBreakdown const showSubitemsToggle = showFeeBreakdown
? stringGetter({ key: STRING_KEYS.HIDE_ALL_DETAILS }) ? stringGetter({ key: STRING_KEYS.HIDE_ALL_DETAILS })
: stringGetter({ key: STRING_KEYS.SHOW_ALL_DETAILS }); : stringGetter({ key: STRING_KEYS.SHOW_ALL_DETAILS });
const totalFees = (summary?.bridgeFee || 0) + (summary?.gasFee || 0); const totalFees = (summary?.bridgeFee || 0) + (summary?.gasFee || 0);
const { toAmount, toAmountMin } = useMemo(() => {
if (isCctp) {
return {
toAmount: summary?.toAmount,
toAmountMin: summary?.toAmountMin,
};
} else {
return {
toAmount:
summary?.toAmount &&
withdrawToken?.decimals &&
formatUnits(BigInt(summary.toAmount), withdrawToken.decimals),
toAmountMin:
summary?.toAmountMin &&
withdrawToken?.decimals &&
formatUnits(BigInt(summary.toAmountMin), withdrawToken.decimals),
};
}
}, [isCctp, summary, withdrawToken]);
const submitButtonReceipt = [ const submitButtonReceipt = [
{ {
key: 'total-fees', key: 'total-fees',
@@ -113,72 +100,20 @@ export const WithdrawButtonAndReceipt = ({
subitems: feeSubitems, subitems: feeSubitems,
}, },
{ {
key: 'exchange-rate', key: 'wallet',
label: <span>{stringGetter({ key: STRING_KEYS.EXCHANGE_RATE })}</span>,
value: withdrawToken && typeof summary?.exchangeRate === 'number' && (
<Styled.ExchangeRate>
<Output type={OutputType.Asset} value={1} fractionDigits={0} tag={usdcLabel} />
=
<Output
type={OutputType.Asset}
value={summary?.exchangeRate}
tag={withdrawToken?.symbol}
/>
</Styled.ExchangeRate>
),
},
{
key: 'estimated-route-duration',
label: <span>{stringGetter({ key: STRING_KEYS.ESTIMATED_TIME })}</span>,
value: typeof summary?.estimatedRouteDuration === 'number' && (
<Output
type={OutputType.Text}
value={stringGetter({
key: STRING_KEYS.X_MINUTES_LOWERCASED,
params: {
X:
summary?.estimatedRouteDuration < 60
? '< 1'
: Math.round(summary?.estimatedRouteDuration / 60),
},
})}
/>
),
},
{
key: 'expected-amount-received',
label: ( label: (
<span> <span>
{stringGetter({ key: STRING_KEYS.EXPECTED_AMOUNT_RECEIVED })}{' '} {stringGetter({ key: STRING_KEYS.AMOUNT_RECEIVED })}{' '}
{withdrawToken && <Tag>{withdrawToken?.symbol}</Tag>} {withdrawToken && <Tag>{withdrawToken?.symbol}</Tag>}
</span> </span>
), ),
value: <Output type={OutputType.Asset} value={toAmount} fractionDigits={TOKEN_DECIMALS} />,
subitems: [
{
key: 'minimum-amount-received',
label: (
<span>
{stringGetter({ key: STRING_KEYS.MINIMUM_AMOUNT_RECEIVED })}{' '}
{withdrawToken && <Tag>{withdrawToken?.symbol}</Tag>}
</span>
),
value: (
<Output type={OutputType.Asset} value={toAmountMin} fractionDigits={TOKEN_DECIMALS} />
),
tooltip: 'minimum-amount-received',
},
],
},
{
key: 'slippage',
label: <span>{stringGetter({ key: STRING_KEYS.MAX_SLIPPAGE })}</span>,
value: ( value: (
<SlippageEditor <Styled.DiffOutput
disabled type={OutputType.Asset}
slippage={slippage} value={'0'}
setIsEditing={setIsEditingSlipapge} newValue={toAmount}
setSlippage={setSlippage} sign={NumberSign.Positive}
withDiff={Boolean(toAmount)}
/> />
), ),
}, },
@@ -195,6 +130,51 @@ export const WithdrawButtonAndReceipt = ({
/> />
), ),
}, },
{
key: 'exchange-rate',
label: <span>{stringGetter({ key: STRING_KEYS.EXCHANGE_RATE })}</span>,
value: withdrawToken && typeof summary?.exchangeRate === 'number' && (
<Styled.ExchangeRate>
<Output type={OutputType.Asset} value={1} fractionDigits={0} tag="USDC" />
=
<Output
type={OutputType.Asset}
value={summary?.exchangeRate}
tag={withdrawToken?.symbol}
/>
</Styled.ExchangeRate>
),
},
{
key: 'slippage',
label: <span>{stringGetter({ key: STRING_KEYS.SLIPPAGE })}</span>,
value: (
<SlippageEditor
disabled
slippage={slippage}
setIsEditing={setIsEditingSlipapge}
setSlippage={setSlippage}
/>
),
},
{
key: 'estimatedRouteDuration',
label: <span>{stringGetter({ key: STRING_KEYS.ESTIMATED_TIME })}</span>,
value: typeof summary?.estimatedRouteDuration === 'number' && (
<Output
type={OutputType.Text}
value={stringGetter({
key: STRING_KEYS.X_MINUTES_LOWERCASED,
params: {
X:
summary?.estimatedRouteDuration < 60
? '< 1'
: Math.round(summary?.estimatedRouteDuration / 60),
},
})}
/>
),
},
]; ];
const isFormValid = !isDisabled && !isEditingSlippage; const isFormValid = !isDisabled && !isEditingSlippage;
+2 -3
View File
@@ -4,7 +4,7 @@ import { useNavigate } from 'react-router-dom';
import { STRING_KEYS } from '@/constants/localization'; import { STRING_KEYS } from '@/constants/localization';
import { MarketFilters, type MarketData } from '@/constants/markets'; import { MarketFilters, type MarketData } from '@/constants/markets';
import { FUNDING_DECIMALS, LARGE_TOKEN_DECIMALS } from '@/constants/numbers'; import { LARGE_TOKEN_DECIMALS } from '@/constants/numbers';
import { AppRoute } from '@/constants/routes'; import { AppRoute } from '@/constants/routes';
import { useBreakpoints, useStringGetter } from '@/hooks'; import { useBreakpoints, useStringGetter } from '@/hooks';
@@ -128,8 +128,7 @@ export const MarketsTable = ({ className }: { className?: string }) => {
label: stringGetter({ key: STRING_KEYS.FUNDING_RATE_1H_SHORT }), label: stringGetter({ key: STRING_KEYS.FUNDING_RATE_1H_SHORT }),
renderCell: (row) => ( renderCell: (row) => (
<Styled.Output <Styled.Output
type={OutputType.Percent} type={OutputType.SmallPercent}
fractionDigits={FUNDING_DECIMALS}
value={row.nextFundingRate} value={row.nextFundingRate}
isPositive={MustBigNumber(row.nextFundingRate).gt(0)} isPositive={MustBigNumber(row.nextFundingRate).gt(0)}
isNegative={MustBigNumber(row.nextFundingRate).isNegative()} isNegative={MustBigNumber(row.nextFundingRate).isNegative()}
-1
View File
@@ -366,7 +366,6 @@ Styled.InlineRow = styled.div`
Styled.AssetIcon = styled(AssetIcon)` Styled.AssetIcon = styled(AssetIcon)`
${layoutMixins.inlineRow} ${layoutMixins.inlineRow}
min-width: unset;
font-size: 2.25rem; font-size: 2.25rem;
`; `;