Compare commits

...
Author SHA1 Message Date
Adam Fraser d524bbebfe Merge branch 'main' into adamfraser-testnet-node-updates 2023-10-30 17:57:34 +01:00
aleka 2fe6c2bb3b reorder header, center align header, update collapse caret icons (#110) 2023-10-27 23:32:51 -04:00
aleka e6858ca917 show loading state instead of "Unavailable" for place order button (#104)
* show loading instead of unavailable for place order button
2023-10-27 17:39:12 -04:00
aleka d92b49f4fa bump packages, fix missing asset symbol (#106) 2023-10-27 16:47:34 -04:00
aleka e7da21962a add entry point to token migration (#98)
* update migrate panel

* address feedback
2023-10-27 16:14:34 -04:00
aleka b479531e34 update v4 docs link (#102) 2023-10-27 16:13:48 -04:00
Bill 0d4c5a547a Abort key derivation if second signature fails (#109) 2023-10-27 11:41:00 -07:00
Adam Fraser 7ab892e56c Add Bware to testnet node config 2023-10-27 19:34:18 +02:00
Adam Fraser 296cec98f4 Remove DSRV from Testnet node config options 2023-10-27 19:19:00 +02:00
Rui 5b235ee53f Add link to help page (#103) 2023-10-27 09:15:31 -07:00
23 changed files with 496 additions and 398 deletions
+2 -1
View File
@@ -6,4 +6,5 @@ VITE_PK_ENCRYPTION_KEY=
VITE_WALLETCONNECT2_PROJECT_ID= VITE_WALLETCONNECT2_PROJECT_ID=
VITE_V3_TOKEN_ADDRESS= VITE_V3_TOKEN_ADDRESS=
VITE_TOKEN_MIGRATION_URI=
+3 -3
View File
@@ -39,9 +39,9 @@
"@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": "^0.7.6", "@dydxprotocol/v4-abacus": "^1.0.3",
"@dydxprotocol/v4-client-js": "^0.40.3", "@dydxprotocol/v4-client-js": "^1.0.0",
"@dydxprotocol/v4-localization": "^0.1.32", "@dydxprotocol/v4-localization": "^1.0.0",
"@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-collapsible": "^1.0.3", "@radix-ui/react-collapsible": "^1.0.3",
+16 -16
View File
@@ -1,9 +1,5 @@
lockfileVersion: '6.0' lockfileVersion: '6.0'
settings:
autoInstallPeers: true
excludeLinksFromLockfile: false
dependencies: dependencies:
'@0xsquid/sdk': '@0xsquid/sdk':
specifier: ^1.10.0 specifier: ^1.10.0
@@ -27,14 +23,14 @@ dependencies:
specifier: ^0.31.0 specifier: ^0.31.0
version: 0.31.0 version: 0.31.0
'@dydxprotocol/v4-abacus': '@dydxprotocol/v4-abacus':
specifier: ^0.7.6 specifier: ^1.0.3
version: 0.7.6 version: 1.0.3
'@dydxprotocol/v4-client-js': '@dydxprotocol/v4-client-js':
specifier: ^0.40.3 specifier: ^1.0.0
version: 0.40.3 version: 1.0.0
'@dydxprotocol/v4-localization': '@dydxprotocol/v4-localization':
specifier: ^0.1.32 specifier: ^1.0.0
version: 0.1.32 version: 1.0.0
'@ethersproject/providers': '@ethersproject/providers':
specifier: ^5.7.2 specifier: ^5.7.2
version: 5.7.2 version: 5.7.2
@@ -979,12 +975,12 @@ packages:
resolution: {integrity: sha512-RpfLEtTlyIxeNPGKcokS+p3BZII/Q3bYxryFRglh5H3A3T8q9fsLYm72VYAMEOOIBLEa8o93kFLiBDUWKrwXZA==} resolution: {integrity: sha512-RpfLEtTlyIxeNPGKcokS+p3BZII/Q3bYxryFRglh5H3A3T8q9fsLYm72VYAMEOOIBLEa8o93kFLiBDUWKrwXZA==}
dev: true dev: true
/@dydxprotocol/v4-abacus@0.7.6: /@dydxprotocol/v4-abacus@1.0.3:
resolution: {integrity: sha512-FdDXRaFMfxhyrJJs0dNrb1KG6X95lPHelua1yCn/SVgzwGaAqlJczrzmdh98INntuRAgIxOu69R5mCGyekumyg==} resolution: {integrity: sha512-GuX37/DMMNSke8ZFcw52II7IVJfUgVGHqoi1Uw2cUb+hgIjjSG3OtbyRWedm5r6nqWq8BNLOexI0VVFB6OMVYg==}
dev: false dev: false
/@dydxprotocol/v4-client-js@0.40.3: /@dydxprotocol/v4-client-js@1.0.0:
resolution: {integrity: sha512-nMQd6tYisKDKIbfx0BGJSYEOSt+I+t5SsaBSmlgTdso+w2rCRO9vyxS+u6MF9h4w5FsVRfhHo3e6uTWX48WpGQ==} resolution: {integrity: sha512-ehfHO+zQy795TcJRwtiawadFHZyh4HnpJNP26hCGsIjLE5q6LLHweQHpK/1N/sXU1PBOuQwc7iaJnFop6gYauQ==}
dependencies: dependencies:
'@cosmjs/amino': 0.30.1 '@cosmjs/amino': 0.30.1
'@cosmjs/encoding': 0.31.1 '@cosmjs/encoding': 0.31.1
@@ -1011,8 +1007,8 @@ packages:
- utf-8-validate - utf-8-validate
dev: false dev: false
/@dydxprotocol/v4-localization@0.1.32: /@dydxprotocol/v4-localization@1.0.0:
resolution: {integrity: sha512-ZtXScxgFLjUt0Ag52RyFnQe9aEl1Aky5fp+vMGOBduVkFiCEMRMkSsSgg6grMdyw/x0AbnxOTRkhYoX2MsK9Ow==} resolution: {integrity: sha512-U7QjOlzpfSAVEchkNDB3xYRx7okzdeYi83XsnHwI+EHa2quFm/2Y2dhrBkT5fqpZmhcwxb/vG8AZmFSToOf9hA==}
dev: false dev: false
/@dydxprotocol/v4-proto@0.4.1: /@dydxprotocol/v4-proto@0.4.1:
@@ -14100,3 +14096,7 @@ packages:
/zwitch@2.0.4: /zwitch@2.0.4:
resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==}
dev: true dev: true
settings:
autoInstallPeers: true
excludeLinksFromLockfile: false
+80 -76
View File
@@ -22,11 +22,11 @@
"dydxprotocol-staging-west", "dydxprotocol-staging-west",
"dydxprotocol-testnet", "dydxprotocol-testnet",
"dydxprotocol-testnet-dydx", "dydxprotocol-testnet-dydx",
"dydxprotocol-testnet-dsrv",
"dydxprotocol-testnet-nodefleet", "dydxprotocol-testnet-nodefleet",
"dydxprotocol-testnet-kingnodes", "dydxprotocol-testnet-kingnodes",
"dydxprotocol-testnet-liquify", "dydxprotocol-testnet-liquify",
"dydxprotocol-testnet-polkachu" "dydxprotocol-testnet-polkachu",
"dydxprotocol-testnet-bware"
], ],
"default": "dydxprotocol-testnet" "default": "dydxprotocol-testnet"
} }
@@ -308,10 +308,11 @@
"tos": "https://dydx.exchange/v4-terms", "tos": "https://dydx.exchange/v4-terms",
"privacy": "https://dydx.exchange/privacy", "privacy": "https://dydx.exchange/privacy",
"mintscan": "https://testnet.mintscan.io/dydx-testnet/txs/{tx_hash}", "mintscan": "https://testnet.mintscan.io/dydx-testnet/txs/{tx_hash}",
"documentation": "https://v4-teacher.vercel.app/", "documentation": "https://docs.dydx.exchange/",
"community": "https://discord.com/invite/dydx", "community": "https://discord.com/invite/dydx",
"feedback": "https://docs.google.com/forms/d/e/1FAIpQLSezLsWCKvAYDEb7L-2O4wOON1T56xxro9A2Azvl6IxXHP_15Q/viewform", "feedback": "https://docs.google.com/forms/d/e/1FAIpQLSezLsWCKvAYDEb7L-2O4wOON1T56xxro9A2Azvl6IxXHP_15Q/viewform",
"blogs": "https://www.dydx.foundation/blog" "blogs": "https://www.dydx.foundation/blog",
"help": "https://help.dydx.exchange"
}, },
"wallets": { "wallets": {
"walletconnect": { "walletconnect": {
@@ -371,10 +372,11 @@
"tos": "https://dydx.exchange/v4-terms", "tos": "https://dydx.exchange/v4-terms",
"privacy": "https://dydx.exchange/privacy", "privacy": "https://dydx.exchange/privacy",
"mintscan": "https://testnet.mintscan.io/dydx-testnet/txs/{tx_hash}", "mintscan": "https://testnet.mintscan.io/dydx-testnet/txs/{tx_hash}",
"documentation": "https://v4-teacher.vercel.app/", "documentation": "https://docs.dydx.exchange/",
"community": "https://discord.com/invite/dydx", "community": "https://discord.com/invite/dydx",
"feedback": "https://docs.google.com/forms/d/e/1FAIpQLSezLsWCKvAYDEb7L-2O4wOON1T56xxro9A2Azvl6IxXHP_15Q/viewform", "feedback": "https://docs.google.com/forms/d/e/1FAIpQLSezLsWCKvAYDEb7L-2O4wOON1T56xxro9A2Azvl6IxXHP_15Q/viewform",
"blogs": "https://www.dydx.foundation/blog" "blogs": "https://www.dydx.foundation/blog",
"help": "https://help.dydx.exchange"
}, },
"wallets": { "wallets": {
"walletconnect": { "walletconnect": {
@@ -425,6 +427,7 @@
} }
], ],
"validators": [ "validators": [
"https://dydx-testnet-full-rpc.public.blastapi.io/",
"https://dydx-testnet-rpc.polkachu.com/", "https://dydx-testnet-rpc.polkachu.com/",
"https://dydx-testnet.nodefleet.org", "https://dydx-testnet.nodefleet.org",
"https://test-dydx.kingnodes.com", "https://test-dydx.kingnodes.com",
@@ -437,7 +440,7 @@
"tos": "https://dydx.exchange/v4-terms", "tos": "https://dydx.exchange/v4-terms",
"privacy": "https://dydx.exchange/privacy", "privacy": "https://dydx.exchange/privacy",
"mintscan": "https://testnet.mintscan.io/dydx-testnet/txs/{tx_hash}", "mintscan": "https://testnet.mintscan.io/dydx-testnet/txs/{tx_hash}",
"documentation": "https://v4-teacher.vercel.app/", "documentation": "https://docs.dydx.exchange/",
"community": "https://discord.com/invite/dydx", "community": "https://discord.com/invite/dydx",
"feedback": "https://docs.google.com/forms/d/e/1FAIpQLSezLsWCKvAYDEb7L-2O4wOON1T56xxro9A2Azvl6IxXHP_15Q/viewform", "feedback": "https://docs.google.com/forms/d/e/1FAIpQLSezLsWCKvAYDEb7L-2O4wOON1T56xxro9A2Azvl6IxXHP_15Q/viewform",
"blogs": "https://www.dydx.foundation/blog" "blogs": "https://www.dydx.foundation/blog"
@@ -501,71 +504,7 @@
"privacy": "https://dydx.exchange/privacy", "privacy": "https://dydx.exchange/privacy",
"statusPage": "https://status.v4testnet.dydx.exchange/", "statusPage": "https://status.v4testnet.dydx.exchange/",
"mintscan": "https://testnet.mintscan.io/dydx-testnet/txs/{tx_hash}", "mintscan": "https://testnet.mintscan.io/dydx-testnet/txs/{tx_hash}",
"documentation": "https://v4-teacher.vercel.app/", "documentation": "https://docs.dydx.exchange/",
"community": "https://discord.com/invite/dydx",
"feedback": "https://docs.google.com/forms/d/e/1FAIpQLSezLsWCKvAYDEb7L-2O4wOON1T56xxro9A2Azvl6IxXHP_15Q/viewform",
"blogs": "https://www.dydx.foundation/blog"
},
"wallets": {
"walletconnect": {
"client": {
"name": "dYdX v4",
"description": "dYdX v4 App",
"iconUrl": "/logos/dydx-x.png"
},
"v2": {
"projectId": "47559b2ec96c09aed9ff2cb54a31ab0e"
}
},
"walletSegue": {
"callbackUrl": "/walletsegue"
},
"images": "/wallets/",
"signTypedDataAction": "dYdX Chain Onboarding",
"signTypedDataDomainName": "dYdX V4"
}
},
"dydxprotocol-testnet-dsrv": {
"name": "v4 Public Testnet/DSRV",
"ethereumChainId": "5",
"dydxChainId": "dydx-testnet-4",
"chainName": "dYdX Chain",
"chainLogo": "dydx-chain.png",
"isMainNet": false,
"tokens": {
"chain": {
"name": "Dv4TNT",
"denom": "adv4tnt",
"decimals": 18,
"image": "/currencies/dydx.png"
},
"usdc": {
"name": "USDC",
"denom": "ibc/8E27BA2D5493AF5636760E354E46004562C46AB7EC0CC4C1CA14E9E20E2545B5",
"gasDenom": "uusdc",
"decimals": 6,
"image": "/currencies/usdc.png"
}
},
"endpoints": {
"indexers": [
{
"api": "https://dydx-testnet.imperator.co",
"socket": "wss://dydx-testnet.imperator.co"
}
],
"validators": [
"https://dydx-testnet-archive.allthatnode.com:26657/XZvMM41hESf8PJrEQiTzbCOMVyFca79R"
],
"0xsquid": "https://testnet.api.squidrouter.com",
"faucet": "https://faucet.v4testnet.dydx.exchange"
},
"links": {
"tos": "https://dydx.exchange/v4-terms",
"privacy": "https://dydx.exchange/privacy",
"statusPage": "https://status.v4testnet.dydx.exchange/",
"mintscan": "https://testnet.mintscan.io/dydx-testnet/txs/{tx_hash}",
"documentation": "https://v4-teacher.vercel.app/",
"community": "https://discord.com/invite/dydx", "community": "https://discord.com/invite/dydx",
"feedback": "https://docs.google.com/forms/d/e/1FAIpQLSezLsWCKvAYDEb7L-2O4wOON1T56xxro9A2Azvl6IxXHP_15Q/viewform", "feedback": "https://docs.google.com/forms/d/e/1FAIpQLSezLsWCKvAYDEb7L-2O4wOON1T56xxro9A2Azvl6IxXHP_15Q/viewform",
"blogs": "https://www.dydx.foundation/blog" "blogs": "https://www.dydx.foundation/blog"
@@ -629,7 +568,7 @@
"privacy": "https://dydx.exchange/privacy", "privacy": "https://dydx.exchange/privacy",
"statusPage": "https://status.v4testnet.dydx.exchange/", "statusPage": "https://status.v4testnet.dydx.exchange/",
"mintscan": "https://testnet.mintscan.io/dydx-testnet/txs/{tx_hash}", "mintscan": "https://testnet.mintscan.io/dydx-testnet/txs/{tx_hash}",
"documentation": "https://v4-teacher.vercel.app/", "documentation": "https://docs.dydx.exchange/",
"community": "https://discord.com/invite/dydx", "community": "https://discord.com/invite/dydx",
"feedback": "https://docs.google.com/forms/d/e/1FAIpQLSezLsWCKvAYDEb7L-2O4wOON1T56xxro9A2Azvl6IxXHP_15Q/viewform", "feedback": "https://docs.google.com/forms/d/e/1FAIpQLSezLsWCKvAYDEb7L-2O4wOON1T56xxro9A2Azvl6IxXHP_15Q/viewform",
"blogs": "https://www.dydx.foundation/blog" "blogs": "https://www.dydx.foundation/blog"
@@ -693,7 +632,7 @@
"privacy": "https://dydx.exchange/privacy", "privacy": "https://dydx.exchange/privacy",
"statusPage": "https://status.v4testnet.dydx.exchange/", "statusPage": "https://status.v4testnet.dydx.exchange/",
"mintscan": "https://testnet.mintscan.io/dydx-testnet/txs/{tx_hash}", "mintscan": "https://testnet.mintscan.io/dydx-testnet/txs/{tx_hash}",
"documentation": "https://v4-teacher.vercel.app/", "documentation": "https://docs.dydx.exchange/",
"community": "https://discord.com/invite/dydx", "community": "https://discord.com/invite/dydx",
"feedback": "https://docs.google.com/forms/d/e/1FAIpQLSezLsWCKvAYDEb7L-2O4wOON1T56xxro9A2Azvl6IxXHP_15Q/viewform", "feedback": "https://docs.google.com/forms/d/e/1FAIpQLSezLsWCKvAYDEb7L-2O4wOON1T56xxro9A2Azvl6IxXHP_15Q/viewform",
"blogs": "https://www.dydx.foundation/blog" "blogs": "https://www.dydx.foundation/blog"
@@ -757,7 +696,7 @@
"privacy": "https://dydx.exchange/privacy", "privacy": "https://dydx.exchange/privacy",
"statusPage": "https://status.v4testnet.dydx.exchange/", "statusPage": "https://status.v4testnet.dydx.exchange/",
"mintscan": "https://testnet.mintscan.io/dydx-testnet/txs/{tx_hash}", "mintscan": "https://testnet.mintscan.io/dydx-testnet/txs/{tx_hash}",
"documentation": "https://v4-teacher.vercel.app/", "documentation": "https://docs.dydx.exchange/",
"community": "https://discord.com/invite/dydx", "community": "https://discord.com/invite/dydx",
"feedback": "https://docs.google.com/forms/d/e/1FAIpQLSezLsWCKvAYDEb7L-2O4wOON1T56xxro9A2Azvl6IxXHP_15Q/viewform", "feedback": "https://docs.google.com/forms/d/e/1FAIpQLSezLsWCKvAYDEb7L-2O4wOON1T56xxro9A2Azvl6IxXHP_15Q/viewform",
"blogs": "https://www.dydx.foundation/blog" "blogs": "https://www.dydx.foundation/blog"
@@ -816,6 +755,70 @@
"0xsquid": "https://testnet.api.squidrouter.com", "0xsquid": "https://testnet.api.squidrouter.com",
"faucet": "https://faucet.v4testnet.dydx.exchange" "faucet": "https://faucet.v4testnet.dydx.exchange"
}, },
"links": {
"tos": "https://dydx.exchange/v4-terms",
"privacy": "https://dydx.exchange/privacy",
"statusPage": "https://status.v4testnet.dydx.exchange/",
"mintscan": "https://testnet.mintscan.io/dydx-testnet/txs/{tx_hash}",
"documentation": "https://docs.dydx.exchange/",
"community": "https://discord.com/invite/dydx",
"feedback": "https://docs.google.com/forms/d/e/1FAIpQLSezLsWCKvAYDEb7L-2O4wOON1T56xxro9A2Azvl6IxXHP_15Q/viewform",
"blogs": "https://www.dydx.foundation/blog"
},
"wallets": {
"walletconnect": {
"client": {
"name": "dYdX v4",
"description": "dYdX v4 App",
"iconUrl": "/logos/dydx-x.png"
},
"v2": {
"projectId": "47559b2ec96c09aed9ff2cb54a31ab0e"
}
},
"walletSegue": {
"callbackUrl": "/walletsegue"
},
"images": "/wallets/",
"signTypedDataAction": "dYdX Chain Onboarding",
"signTypedDataDomainName": "dYdX V4"
}
},
"dydxprotocol-testnet-bware": {
"name": "v4 Public Testnet/BWare",
"ethereumChainId": "5",
"dydxChainId": "dydx-testnet-4",
"chainName": "dYdX Chain",
"chainLogo": "dydx-chain.png",
"isMainNet": false,
"tokens": {
"chain": {
"name": "Dv4TNT",
"denom": "adv4tnt",
"decimals": 18,
"image": "/currencies/dydx.png"
},
"usdc": {
"name": "USDC",
"denom": "ibc/8E27BA2D5493AF5636760E354E46004562C46AB7EC0CC4C1CA14E9E20E2545B5",
"gasDenom": "uusdc",
"decimals": 6,
"image": "/currencies/usdc.png"
}
},
"endpoints": {
"indexers": [
{
"api": "https://dydx-testnet.imperator.co",
"socket": "wss://dydx-testnet.imperator.co"
}
],
"validators": [
"https://dydx-testnet-full-rpc.public.blastapi.io/"
],
"0xsquid": "https://testnet.api.squidrouter.com",
"faucet": "https://faucet.v4testnet.dydx.exchange"
},
"links": { "links": {
"tos": "https://dydx.exchange/v4-terms", "tos": "https://dydx.exchange/v4-terms",
"privacy": "https://dydx.exchange/privacy", "privacy": "https://dydx.exchange/privacy",
@@ -888,7 +891,8 @@
"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]",
"feedback": "[HTTP link to feedback form, can be null]", "feedback": "[HTTP link to feedback form, can be null]",
"blogs": "[HTTP link to blogs, can be null]" "blogs": "[HTTP link to blogs, can be null]",
"help": "[HTTP link to help page, can be null]"
}, },
"wallets": { "wallets": {
"walletconnect": { "walletconnect": {
+1 -1
View File
@@ -80,7 +80,7 @@ Styled.TriggerIcon = styled.span`
width: var(--trigger-icon-width); width: var(--trigger-icon-width);
display: inline-flex; display: inline-flex;
transition: transform 0.3s var(--ease-out-expo); transition: rotate 0.3s var(--ease-out-expo);
color: var(--trigger-icon-color); color: var(--trigger-icon-color);
${Styled.Trigger}[data-state='open'] & { ${Styled.Trigger}[data-state='open'] & {
+3
View File
@@ -40,6 +40,7 @@ import {
LockIcon, LockIcon,
LogoShortIcon, LogoShortIcon,
MenuIcon, MenuIcon,
MigrateIcon,
MintscanIcon, MintscanIcon,
OrderbookIcon, OrderbookIcon,
OrderCanceledIcon, OrderCanceledIcon,
@@ -108,6 +109,7 @@ export enum IconName {
Lock = 'Lock', Lock = 'Lock',
LogoShort = 'LogoShort', LogoShort = 'LogoShort',
Menu = 'Menu', Menu = 'Menu',
Migrate = 'Migrate',
Mintscan = 'Mintscan', Mintscan = 'Mintscan',
Onboarding = 'Onboarding', Onboarding = 'Onboarding',
Orderbook = 'OrderbookIcon', Orderbook = 'OrderbookIcon',
@@ -177,6 +179,7 @@ const icons = {
[IconName.Lock]: LockIcon, [IconName.Lock]: LockIcon,
[IconName.LogoShort]: LogoShortIcon, [IconName.LogoShort]: LogoShortIcon,
[IconName.Menu]: MenuIcon, [IconName.Menu]: MenuIcon,
[IconName.Migrate]: MigrateIcon,
[IconName.Mintscan]: MintscanIcon, [IconName.Mintscan]: MintscanIcon,
[IconName.Orderbook]: OrderbookIcon, [IconName.Orderbook]: OrderbookIcon,
[IconName.OrderCanceled]: OrderCanceledIcon, [IconName.OrderCanceled]: OrderCanceledIcon,
+3
View File
@@ -525,6 +525,9 @@ Styled.NavItem = styled(NavItem)<{ orientation: 'horizontal' | 'vertical' }>`
`; `;
Styled.Icon = styled(Icon)` Styled.Icon = styled(Icon)`
height: 0.75em;
transition: rotate 0.3s var(--ease-out-expo);
${Styled.List}[data-orientation="menu"] & { ${Styled.List}[data-orientation="menu"] & {
rotate: -0.25turn; rotate: -0.25turn;
} }
+32 -25
View File
@@ -8,6 +8,7 @@ import { layoutMixins } from '@/styles/layoutMixins';
type PanelProps = { type PanelProps = {
slotHeaderContent?: string; slotHeaderContent?: string;
slotHeader?: React.ReactNode; slotHeader?: React.ReactNode;
slotRight?: React.ReactNode;
children?: React.ReactNode; children?: React.ReactNode;
href?: string; href?: string;
onHeaderClick?: () => void; onHeaderClick?: () => void;
@@ -22,6 +23,7 @@ type PanelStyleProps = {
export const Panel = ({ export const Panel = ({
slotHeaderContent, slotHeaderContent,
slotHeader, slotHeader,
slotRight,
children, children,
href, href,
onHeaderClick, onHeaderClick,
@@ -30,55 +32,61 @@ export const Panel = ({
className, className,
}: PanelProps & PanelStyleProps) => ( }: PanelProps & PanelStyleProps) => (
<Styled.Panel onClick={onClick}> <Styled.Panel onClick={onClick}>
{href ? ( <Styled.Left>
<Link to={href}> {href ? (
{slotHeader ? ( <Link to={href}>
slotHeader {slotHeader ? (
) : ( slotHeader
) : (
<Styled.Header role="button" onClick={onHeaderClick} hasSeparator={hasSeparator}>
{slotHeaderContent}
<Styled.Icon iconName={IconName.ChevronRight} />
</Styled.Header>
)}
</Link>
) : slotHeader ? (
slotHeader
) : (
slotHeaderContent && (
<Styled.Header role="button" onClick={onHeaderClick} hasSeparator={hasSeparator}> <Styled.Header role="button" onClick={onHeaderClick} hasSeparator={hasSeparator}>
{slotHeaderContent} {slotHeaderContent}
<Styled.Icon iconName={IconName.ChevronRight} />
</Styled.Header> </Styled.Header>
)} )
</Link> )}
) : slotHeader ? ( <Styled.Content className={className}>{children}</Styled.Content>
slotHeader </Styled.Left>
) : ( {slotRight}
slotHeaderContent && (
<Styled.Header role="button" onClick={onHeaderClick} hasSeparator={hasSeparator}>
{slotHeaderContent}
</Styled.Header>
)
)}
<Styled.Content className={className}>{children}</Styled.Content>
</Styled.Panel> </Styled.Panel>
); );
const Styled: Record<string, AnyStyledComponent> = {}; const Styled: Record<string, AnyStyledComponent> = {};
Styled.Panel = styled.section` Styled.Panel = styled.section`
${layoutMixins.flexColumn} ${layoutMixins.row}
background-color: var(--color-layer-3); background-color: var(--color-layer-3);
border-radius: 0.875rem; border-radius: 0.875rem;
`; `;
Styled.Left = styled.div`
${layoutMixins.flexColumn}
width: 100%;
`;
Styled.Header = styled.header<{ hasSeparator?: boolean }>` Styled.Header = styled.header<{ hasSeparator?: boolean }>`
${layoutMixins.spacedRow} ${layoutMixins.spacedRow}
padding: 1rem 1rem;
padding: 0.875rem 1rem 0.625rem;
font-size: 0.875rem;
${({ hasSeparator }) => ${({ hasSeparator }) =>
hasSeparator && hasSeparator &&
css` css`
padding-bottom: 0.625rem;
box-shadow: 0 var(--border-width) var(--border-color); box-shadow: 0 var(--border-width) var(--border-color);
`} `}
`; `;
Styled.Icon = styled(Icon)` Styled.Icon = styled(Icon)`
color: var(--color-text-0); color: var(--color-text-0);
font-size: 0.625rem; font-size: 0.625rem;
`; `;
@@ -86,6 +94,5 @@ Styled.Content = styled.div`
${layoutMixins.scrollArea} ${layoutMixins.scrollArea}
${layoutMixins.stickyArea0} ${layoutMixins.stickyArea0}
--stickyArea0-background: transparent; --stickyArea0-background: transparent;
padding: 1rem 1rem;
padding: 0.5rem 1rem;
`; `;
+1
View File
@@ -35,6 +35,7 @@ export { default as LockIcon } from './lock.svg';
export { default as LogoShortIcon } from './logo-short'; export { default as LogoShortIcon } from './logo-short';
export { default as MarketsIcon } from './markets.svg'; export { default as MarketsIcon } from './markets.svg';
export { default as MenuIcon } from './menu.svg'; export { default as MenuIcon } from './menu.svg';
export { default as MigrateIcon } from './migrate.svg';
export { default as MintscanIcon } from './logos/mintscan.svg'; export { default as MintscanIcon } from './logos/mintscan.svg';
export { default as OrderbookIcon } from './orderbook.svg'; export { default as OrderbookIcon } from './orderbook.svg';
export { default as OverviewIcon } from './overview.svg'; export { default as OverviewIcon } from './overview.svg';
File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 694 KiB

+24 -11
View File
@@ -24,6 +24,7 @@ import { openDialog } from '@/state/dialogs';
import { headerMixins } from '@/styles/headerMixins'; import { headerMixins } from '@/styles/headerMixins';
import { layoutMixins } from '@/styles/layoutMixins'; import { layoutMixins } from '@/styles/layoutMixins';
import breakpoints from '@/styles/breakpoints';
export const HeaderDesktop = () => { export const HeaderDesktop = () => {
const stringGetter = useStringGetter(); const stringGetter = useStringGetter();
@@ -34,26 +35,26 @@ export const HeaderDesktop = () => {
{ {
group: 'navigation', group: 'navigation',
items: [ items: [
{
value: 'MARKET',
label: stringGetter({ key: STRING_KEYS.MARKET }),
href: AppRoute.Markets,
},
{ {
value: 'TRADE', value: 'TRADE',
label: stringGetter({ key: STRING_KEYS.TRADE }), label: stringGetter({ key: STRING_KEYS.TRADE }),
href: AppRoute.Trade, href: AppRoute.Trade,
}, },
{
value: chainTokenLabel,
label: chainTokenLabel,
href: `/${chainTokenLabel}`,
},
{ {
value: 'PORTFOLIO', value: 'PORTFOLIO',
label: stringGetter({ key: STRING_KEYS.PORTFOLIO }), label: stringGetter({ key: STRING_KEYS.PORTFOLIO }),
href: AppRoute.Portfolio, href: AppRoute.Portfolio,
}, },
{
value: 'MARKETS',
label: stringGetter({ key: STRING_KEYS.MARKETS }),
href: AppRoute.Markets,
},
{
value: chainTokenLabel,
label: chainTokenLabel,
href: `/${chainTokenLabel}`,
},
{ {
value: 'MORE', value: 'MORE',
label: stringGetter({ key: STRING_KEYS.MORE }), label: stringGetter({ key: STRING_KEYS.MORE }),
@@ -62,7 +63,7 @@ export const HeaderDesktop = () => {
value: 'DOCUMENTATION', value: 'DOCUMENTATION',
slotBefore: <Icon iconName={IconName.Terminal} />, slotBefore: <Icon iconName={IconName.Terminal} />,
label: stringGetter({ key: STRING_KEYS.DOCUMENTATION }), label: stringGetter({ key: STRING_KEYS.DOCUMENTATION }),
href: 'https://v4-teacher.vercel.app/', href: 'https://docs.dydx.exchange/',
}, },
{ {
value: 'MINTSCAN', value: 'MINTSCAN',
@@ -150,6 +151,7 @@ const Styled: Record<string, AnyStyledComponent> = {};
Styled.Header = styled.header` Styled.Header = styled.header`
--header-horizontal-padding-mobile: 0.5rem; --header-horizontal-padding-mobile: 0.5rem;
--trigger-height: 2.25rem;
--logo-width: 3.5rem; --logo-width: 3.5rem;
${layoutMixins.container} ${layoutMixins.container}
@@ -157,6 +159,8 @@ Styled.Header = styled.header`
${layoutMixins.scrollSnapItem} ${layoutMixins.scrollSnapItem}
backdrop-filter: none; backdrop-filter: none;
height: var(--page-currentHeaderHeight);
grid-area: Header; grid-area: Header;
display: grid; display: grid;
@@ -169,6 +173,14 @@ Styled.Header = styled.header`
) )
var(--border-width) 1fr var(--border-width) auto; var(--border-width) 1fr var(--border-width) auto;
@media ${breakpoints.tablet} {
--trigger-height: 3rem;
}
@media ${breakpoints.mobile} {
--navBefore-width: 7rem;
}
font-size: 0.9375rem; font-size: 0.9375rem;
:before { :before {
@@ -179,6 +191,7 @@ Styled.Header = styled.header`
Styled.NavigationMenu = styled(NavigationMenu)` Styled.NavigationMenu = styled(NavigationMenu)`
& { & {
--navigationMenu-height: var(--stickyArea-topHeight); --navigationMenu-height: var(--stickyArea-topHeight);
--navigationMenu-item-height: var(--trigger-height);
} }
${layoutMixins.scrollArea} ${layoutMixins.scrollArea}
+16 -8
View File
@@ -46,6 +46,8 @@ import {
WALLET_CONNECT_EXPLORER_RECOMMENDED_IDS, WALLET_CONNECT_EXPLORER_RECOMMENDED_IDS,
} from '@/constants/wallets'; } from '@/constants/wallets';
import { isTruthy } from './isTruthy';
// Config // Config
export const WAGMI_SUPPORTED_CHAINS: Chain[] = [ export const WAGMI_SUPPORTED_CHAINS: Chain[] = [
@@ -78,13 +80,17 @@ export const WAGMI_SUPPORTED_CHAINS: Chain[] = [
celoAlfajores, celoAlfajores,
]; ];
const { chains, publicClient, webSocketPublicClient } = configureChains(WAGMI_SUPPORTED_CHAINS, [ const { chains, publicClient, webSocketPublicClient } = configureChains(
// alchemyProvider({ apiKey: import.meta.env.VITE_ALCHEMY_API_KEY }), WAGMI_SUPPORTED_CHAINS,
jsonRpcProvider({ [
rpc: (chain) => ({ http: chain.rpcUrls.default.http[0] }), import.meta.env.VITE_ALCHEMY_API_KEY &&
}), alchemyProvider({ apiKey: import.meta.env.VITE_ALCHEMY_API_KEY }),
publicProvider(), jsonRpcProvider({
]); rpc: (chain) => ({ http: chain.rpcUrls.default.http[0] }),
}),
publicProvider(),
].filter(isTruthy)
);
const injectedConnectorOptions = { const injectedConnectorOptions = {
chains, chains,
@@ -202,5 +208,7 @@ export const resolveWagmiConnector = ({
? createInjectedConnectorWithProvider(walletConnection.provider) ? createInjectedConnectorWithProvider(walletConnection.provider)
: walletConnection.type === WalletConnectionType.WalletConnect2 && walletConfig.walletconnect2Id : walletConnection.type === WalletConnectionType.WalletConnect2 && walletConfig.walletconnect2Id
? createWalletConnect2ConnectorWithId(walletConfig.walletconnect2Id, walletConnectConfig) ? createWalletConnect2ConnectorWithId(walletConfig.walletconnect2Id, walletConnectConfig)
: getConnectors(walletConnectConfig).find(({ id }: { id: string }) => id === walletConnectionConfig.wagmiConnectorId); : getConnectors(walletConnectConfig).find(
({ id }: { id: string }) => id === walletConnectionConfig.wagmiConnectorId
);
}; };
+14 -10
View File
@@ -17,7 +17,7 @@ import { DialogTypes } from '@/constants/dialogs';
import { STRING_KEYS } from '@/constants/localization'; import { STRING_KEYS } from '@/constants/localization';
import { AppRoute, PortfolioRoute, HistoryRoute } from '@/constants/routes'; import { AppRoute, PortfolioRoute, HistoryRoute } from '@/constants/routes';
import { wallets, WalletType } from '@/constants/wallets'; import { wallets, WalletType } from '@/constants/wallets';
import { useAccounts, useStringGetter } from '@/hooks'; import { useAccounts, useStringGetter, useTokenConfigs } from '@/hooks';
import { getOnboardingState } from '@/state/accountSelectors'; import { getOnboardingState } from '@/state/accountSelectors';
import { openDialog } from '@/state/dialogs'; import { openDialog } from '@/state/dialogs';
@@ -37,6 +37,7 @@ const Profile = () => {
const isConnected = onboardingState !== OnboardingState.Disconnected; const isConnected = onboardingState !== OnboardingState.Disconnected;
const { evmAddress, dydxAddress, walletType } = useAccounts(); const { evmAddress, dydxAddress, walletType } = useAccounts();
const { chainTokenLabel } = useTokenConfigs();
const { data: ensName } = useEnsName({ const { data: ensName } = useEnsName({
address: evmAddress, address: evmAddress,
@@ -137,7 +138,11 @@ const Profile = () => {
layout="grid" layout="grid"
/> />
</Panel> </Panel>
<Styled.RewardsPanel header={stringGetter({ key: STRING_KEYS.REWARDS })} hasSeparator> <Styled.RewardsPanel
slotHeaderContent={stringGetter({ key: STRING_KEYS.REWARDS })}
href={`/${chainTokenLabel}`}
hasSeparator
>
<Styled.Details <Styled.Details
items={[ items={[
{ key: 'maker', label: stringGetter({ key: STRING_KEYS.YOU_WILL_EARN }), value: '-' }, { key: 'maker', label: stringGetter({ key: STRING_KEYS.YOU_WILL_EARN }), value: '-' },
@@ -149,8 +154,8 @@ const Profile = () => {
</Styled.EqualGrid> </Styled.EqualGrid>
<Styled.TablePanel <Styled.TablePanel
header={stringGetter({ key: STRING_KEYS.HISTORY })} slotHeaderContent={stringGetter({ key: STRING_KEYS.HISTORY })}
linkto={`${AppRoute.Portfolio}/${PortfolioRoute.History}/${HistoryRoute.Trades}`} href={`${AppRoute.Portfolio}/${PortfolioRoute.History}/${HistoryRoute.Trades}`}
hasSeparator hasSeparator
> >
<FillsTable <FillsTable
@@ -273,22 +278,21 @@ Styled.RewardsPanel = styled(Panel)`
`; `;
Styled.TablePanel = styled(Panel)` Styled.TablePanel = styled(Panel)`
padding: 0;
max-width: calc(100vw - 2rem); max-width: calc(100vw - 2rem);
max-height: 10rem; max-height: 10rem;
margin-top: 0.5rem;
padding: 0;
border-radius: 0.875rem;
table { table {
--tableCell-padding: 0.25rem 1rem; --tableCell-padding: 0.25rem 1rem;
--tableRow-backgroundColor: var(--color-layer-3);
background-color: transparent; background-color: var(--color-layer-3);
thead { thead {
color: var(--color-text-0); color: var(--color-text-0);
} }
tbody { tbody {
background-color: transparent;
tr { tr {
td:nth-child(2), td:nth-child(2),
td:nth-child(3) { td:nth-child(3) {
+222
View File
@@ -0,0 +1,222 @@
import styled, { AnyStyledComponent } from 'styled-components';
import { useSelector } from 'react-redux';
import { ENVIRONMENT_CONFIG_MAP } from '@/constants/networks';
import { STRING_KEYS } from '@/constants/localization';
import { ButtonAction, ButtonSize, ButtonType } from '@/constants/buttons';
import { useAccountBalance, useBreakpoints, useStringGetter } from '@/hooks';
import { layoutMixins } from '@/styles/layoutMixins';
import { Details } from '@/components/Details';
import { Panel } from '@/components/Panel';
import { Button } from '@/components/Button';
import { Link } from '@/components/Link';
import { IconName, Icon } from '@/components/Icon';
import { Output, OutputType } from '@/components/Output';
import { VerticalSeparator } from '@/components/Separator';
import { Tag } from '@/components/Tag';
import { WithReceipt } from '@/components/WithReceipt';
import { getSelectedNetwork } from '@/state/appSelectors';
import { MustBigNumber } from '@/lib/numbers';
const TOKEN_MIGRATION_LEARN_MORE_LINK =
'https://www.dydx.foundation/blog/update-on-exploring-the-future-of-dydx';
export const MigratePanel = () => {
const { isNotTablet } = useBreakpoints();
const stringGetter = useStringGetter();
const selectedNetwork = useSelector(getSelectedNetwork);
const chainId = Number(ENVIRONMENT_CONFIG_MAP[selectedNetwork].ethereumChainId);
// v3 token is only on mainnet
const { balance: tokenBalance } = useAccountBalance({
addressOrDenom: chainId === 1 ? import.meta.env.VITE_V3_TOKEN_ADDRESS : undefined,
chainId: 1,
isCosmosChain: false,
});
return isNotTablet ? (
<Styled.MigratePanel
slotHeader={<Styled.Title>{stringGetter({ key: STRING_KEYS.MIGRATE })}</Styled.Title>}
slotRight={
<Styled.MigrateAction>
<div>
<div>{stringGetter({ key: STRING_KEYS.AVAILABLE_TO_MIGRATE })}</div>
<Styled.Token type={OutputType.Asset} value={tokenBalance} />
</div>
{import.meta.env.VITE_TOKEN_MIGRATION_URI && (
<Button
action={MustBigNumber(tokenBalance).gt(0) ? ButtonAction.Primary : ButtonAction.Base}
type={ButtonType.Link}
href={import.meta.env.VITE_TOKEN_MIGRATION_URI}
slotRight={<Icon iconName={IconName.LinkOut} />}
>
{stringGetter({ key: STRING_KEYS.MIGRATE_NOW })}
</Button>
)}
</Styled.MigrateAction>
}
>
<Styled.Description>
{stringGetter({ key: STRING_KEYS.MIGRATE_DESCRIPTION })}
<Link href={TOKEN_MIGRATION_LEARN_MORE_LINK}>
{stringGetter({ key: STRING_KEYS.LEARN_MORE })}
</Link>
</Styled.Description>
</Styled.MigratePanel>
) : (
<Styled.MobileMigratePanel
slotHeader={
<Styled.MobileMigrateHeader>
<h3>
<Icon iconName={IconName.Migrate} />
{stringGetter({ key: STRING_KEYS.MIGRATE })}
</h3>
<Styled.VerticalSeparator />
<span>
{stringGetter({
key: STRING_KEYS.FROM_TO,
params: { FROM: <b>Ethereum</b>, TO: <b>dYdX Chain</b> },
})}
</span>
</Styled.MobileMigrateHeader>
}
>
<Styled.WithReceipt
slotReceipt={
<Styled.Details
items={[
{
key: 'available-to-migrate',
label: (
<Styled.InlineRow>
{stringGetter({ key: STRING_KEYS.AVAILABLE_TO_MIGRATE })}
<Tag>DYDX</Tag>
</Styled.InlineRow>
),
value: <Output type={OutputType.Asset} value={tokenBalance} />,
},
]}
/>
}
>
{import.meta.env.VITE_TOKEN_MIGRATION_URI && (
<Button
action={tokenBalance ? ButtonAction.Primary : ButtonAction.Base}
size={ButtonSize.Medium}
slotRight={<Icon iconName={IconName.LinkOut} />}
href={import.meta.env.VITE_TOKEN_MIGRATION_URI}
>
{stringGetter({ key: STRING_KEYS.MIGRATE_NOW })}
</Button>
)}
</Styled.WithReceipt>
<Styled.InlineRow>
{stringGetter({ key: STRING_KEYS.WANT_TO_LEARN })}
<Link href={TOKEN_MIGRATION_LEARN_MORE_LINK} withIcon>
{stringGetter({ key: STRING_KEYS.CLICK_HERE })}
</Link>
</Styled.InlineRow>
</Styled.MobileMigratePanel>
);
};
const Styled: Record<string, AnyStyledComponent> = {};
Styled.MigratePanel = styled(Panel)`
padding: 1rem 1.5rem;
`;
Styled.Title = styled.h3`
font: var(--font-medium-book);
color: var(--color-text-2);
padding: 1rem 1.5rem 0;
`;
Styled.MigrateAction = styled.div`
${layoutMixins.flexEqualColumns}
align-items: center;
margin-right: 1rem;
gap: 1rem;
padding: 1rem;
width: 100%;
background-color: var(--color-layer-2);
border: solid var(--border-width) var(--color-border);
border-radius: 0.75rem;
`;
Styled.Token = styled(Output)`
font: var(--font-large-book);
color: var(--color-text-2);
`;
Styled.Description = styled.div`
color: var(--color-text-0);
--link-color: var(--color-text-1);
`;
Styled.MobileMigratePanel = styled(Panel)`
${layoutMixins.flexColumn}
gap: 1rem;
align-items: center;
`;
Styled.MobileMigrateHeader = styled.div`
${layoutMixins.inlineRow}
gap: 1ch;
font: var(--font-small-book);
color: var(--color-text-0);
padding: 1rem 1.5rem 0;
h3 {
${layoutMixins.inlineRow}
font: var(--font-large-book);
color: var(--color-text-2);
svg {
font-size: 1.75rem;
}
}
span {
margin-top: 0.2rem;
b {
font-weight: var(--fontWeight-book);
color: var(--color-text-1);
}
}
`;
Styled.VerticalSeparator = styled(VerticalSeparator)`
z-index: 1;
&& {
height: 1.5rem;
}
`;
Styled.Details = styled(Details)`
padding: 0.5rem 1rem;
`;
Styled.WithReceipt = styled(WithReceipt)`
width: 100%;
`;
Styled.InlineRow = styled.div`
${layoutMixins.inlineRow}
color: var(--color-text-0);
--link-color: var(--color-text-1);
`;
+45 -234
View File
@@ -1,134 +1,49 @@
import styled, { AnyStyledComponent } from 'styled-components'; import styled, { AnyStyledComponent } from 'styled-components';
import { useDispatch, useSelector } from 'react-redux'; import { useDispatch } from 'react-redux';
import { ENVIRONMENT_CONFIG_MAP } from '@/constants/networks';
import { STRING_KEYS } from '@/constants/localization'; import { STRING_KEYS } from '@/constants/localization';
import { ButtonAction, ButtonSize, ButtonState, ButtonType } from '@/constants/buttons'; import { ButtonAction, ButtonSize } from '@/constants/buttons';
import { DialogTypes } from '@/constants/dialogs'; import { DialogTypes } from '@/constants/dialogs';
import { useAccountBalance, useBreakpoints, useStringGetter } from '@/hooks'; import { useBreakpoints, useStringGetter } from '@/hooks';
import { breakpoints } from '@/styles'; import { breakpoints } from '@/styles';
import { layoutMixins } from '@/styles/layoutMixins'; import { layoutMixins } from '@/styles/layoutMixins';
import { Details } from '@/components/Details';
import { Panel } from '@/components/Panel'; import { Panel } from '@/components/Panel';
import { IconName } from '@/components/Icon'; import { IconName } from '@/components/Icon';
import { Button } from '@/components/Button';
import { IconButton } from '@/components/IconButton'; import { IconButton } from '@/components/IconButton';
import { Link } from '@/components/Link'; import { Link } from '@/components/Link';
import { Output, OutputType } from '@/components/Output';
import { VerticalSeparator } from '@/components/Separator';
import { WithReceipt } from '@/components/WithReceipt';
import { openDialog } from '@/state/dialogs'; import { openDialog } from '@/state/dialogs';
import { getSelectedNetwork } from '@/state/appSelectors';
import { DYDXBalancePanel } from './DYDXBalancePanel'; import { DYDXBalancePanel } from './DYDXBalancePanel';
import { MigratePanel } from './MigratePanel';
// TODO: replace placeholder URL with real URLs when avaialble // TODO: consolidate help link urls to env variables
const GOVERNANCE_HELP_URL = 'https://help.dydx.exchange/'; const GOVERNANCE_HELP_URL = 'https://help.dydx.exchange/';
const STAKING_HELP_URL = 'https://help.dydx.exchange/'; const STAKING_HELP_URL =
'https://docs.dydx.community/dydx-chain-documentation/staking/how-to-stake';
export const RewardsPage = () => { export const RewardsPage = () => {
const dispatch = useDispatch(); const dispatch = useDispatch();
const stringGetter = useStringGetter(); const stringGetter = useStringGetter();
const { isTablet, isNotTablet } = useBreakpoints(); const { isTablet, isNotTablet } = useBreakpoints();
const selectedNetwork = useSelector(getSelectedNetwork); const panelArrow = (
<Styled.Arrow>
// const chainId = Number(ENVIRONMENT_CONFIG_MAP[selectedNetwork].ethereumChainId); <Styled.IconButton
action={ButtonAction.Base}
// const { balance } = useAccountBalance({ iconName={IconName.Arrow}
// addressOrDenom: import.meta.env.VITE_V3_TOKEN_ADDRESS, size={ButtonSize.Small}
// assetSymbol: 'DYDX', />
// chainId, </Styled.Arrow>
// isCosmosChain: false, );
// });
// const tokenBalance = import.meta.env.VITE_V3_TOKEN_ADDRESS ? balance : 0;
return ( return (
<Styled.Page> <Styled.Page>
{/* {isNotTablet ? ( {import.meta.env.VITE_V3_TOKEN_ADDRESS && <MigratePanel />}
<Styled.Migrate>
<Styled.TwoItemRow>
<div>
<Styled.MigrateTitle>
{stringGetter({ key: STRING_KEYS.MIGRATE })}
</Styled.MigrateTitle>
<Styled.Description>
{stringGetter({ key: STRING_KEYS.MIGRATE_DESCRIPTION })}
<Link href={MIGRATE_HELP_URL}>
{stringGetter({ key: STRING_KEYS.LEARN_MORE })} →
</Link>
</Styled.Description>
</div>
<Styled.MigrateAction>
<div>
<div>{stringGetter({ key: STRING_KEYS.AVAILABLE_TO_MIGRATE })}</div>
<div>
<Styled.Token type={OutputType.Asset} value={tokenBalance} />
</div>
</div>
<Button
action={tokenBalance ? ButtonAction.Primary : ButtonAction.Base}
// type={ButtonType.Link}
// href={BRIDGE_URL}
disabled
>
{tokenBalance
? `${stringGetter({ key: STRING_KEYS.MIGRATE_NOW })} →`
: stringGetter({ key: STRING_KEYS.NO_TOKENS_TO_MIGRATE })}
</Button>
</Styled.MigrateAction>
</Styled.TwoItemRow>
</Styled.Migrate>
) : (
<Styled.MobileMigrateCard
slotHeader={
<Styled.MobileMigrateHeader>
<h3>{stringGetter({ key: STRING_KEYS.MIGRATE })}</h3>
<VerticalSeparator />
<span>
{stringGetter({
key: STRING_KEYS.FROM_TO,
params: { FROM: <strong>Ethereum</strong>, TO: <strong>dYdX Chain</strong> },
})}
</span>
</Styled.MobileMigrateHeader>
}
>
<Styled.WithReceipt
slotReceipt={
<Styled.Details
items={[
{
key: 'available-to-migrate',
label: stringGetter({ key: STRING_KEYS.AVAILABLE_TO_MIGRATE }),
value: <Output type={OutputType.Asset} value={tokenBalance} />,
},
]}
/>
}
>
<Button
action={tokenBalance ? ButtonAction.Primary : ButtonAction.Base}
size={ButtonSize.Medium}
disabled
>
{tokenBalance
? `${stringGetter({ key: STRING_KEYS.MIGRATE_NOW })} →`
: stringGetter({ key: STRING_KEYS.NO_TOKENS_TO_MIGRATE })}
</Button>
</Styled.WithReceipt>
<Styled.LearnMore>
{stringGetter({ key: STRING_KEYS.WANT_TO_LEARN })}
<Link href={MIGRATE_HELP_URL}>{stringGetter({ key: STRING_KEYS.CLICK_HERE })}</Link>
</Styled.LearnMore>
</Styled.MobileMigrateCard>
)} */}
<Styled.PanelRow> <Styled.PanelRow>
{isTablet && ( {isTablet && (
<Styled.BalancePanelContainer> <Styled.BalancePanelContainer>
@@ -138,42 +53,28 @@ export const RewardsPage = () => {
<Styled.Panel <Styled.Panel
slotHeader={<Styled.Title>{stringGetter({ key: STRING_KEYS.GOVERNANCE })}</Styled.Title>} slotHeader={<Styled.Title>{stringGetter({ key: STRING_KEYS.GOVERNANCE })}</Styled.Title>}
slotRight={panelArrow}
onClick={() => dispatch(openDialog({ type: DialogTypes.ExternalNavKeplr }))} onClick={() => dispatch(openDialog({ type: DialogTypes.ExternalNavKeplr }))}
> >
<Styled.Row> <Styled.Description>
<Styled.Description> {stringGetter({ key: STRING_KEYS.GOVERNANCE_DESCRIPTION })}
{stringGetter({ key: STRING_KEYS.GOVERNANCE_DESCRIPTION })} <Link href={GOVERNANCE_HELP_URL} onClick={(e) => e.stopPropagation()}>
<Link href={GOVERNANCE_HELP_URL} onClick={(e) => e.stopPropagation()}> {stringGetter({ key: STRING_KEYS.LEARN_MORE })}
{stringGetter({ key: STRING_KEYS.LEARN_MORE })} </Link>
</Link> </Styled.Description>
</Styled.Description>
{/* TODO: vertically center based on Panel height */}
<Styled.IconButton
action={ButtonAction.Base}
iconName={IconName.Arrow}
size={ButtonSize.Small}
/>
</Styled.Row>
</Styled.Panel> </Styled.Panel>
<Styled.Panel <Styled.Panel
slotHeader={<Styled.Title>{stringGetter({ key: STRING_KEYS.STAKING })}</Styled.Title>} slotHeader={<Styled.Title>{stringGetter({ key: STRING_KEYS.STAKING })}</Styled.Title>}
slotRight={panelArrow}
onClick={() => dispatch(openDialog({ type: DialogTypes.ExternalNavKeplr }))} onClick={() => dispatch(openDialog({ type: DialogTypes.ExternalNavKeplr }))}
> >
<Styled.Row> <Styled.Description>
<Styled.Description> {stringGetter({ key: STRING_KEYS.STAKING_DESCRIPTION })}
{stringGetter({ key: STRING_KEYS.STAKING_DESCRIPTION })} <Link href={STAKING_HELP_URL} onClick={(e) => e.stopPropagation()}>
<Link href={STAKING_HELP_URL} onClick={(e) => e.stopPropagation()}> {stringGetter({ key: STRING_KEYS.LEARN_MORE })}
{stringGetter({ key: STRING_KEYS.LEARN_MORE })} </Link>
</Link> </Styled.Description>
</Styled.Description>
{/* TODO: vertically center based on Panel height */}
<Styled.IconButton
action={ButtonAction.Base}
iconName={IconName.Arrow}
size={ButtonSize.Small}
/>
</Styled.Row>
</Styled.Panel> </Styled.Panel>
{isNotTablet && ( {isNotTablet && (
@@ -191,61 +92,25 @@ const Styled: Record<string, AnyStyledComponent> = {};
Styled.Page = styled.div` Styled.Page = styled.div`
${layoutMixins.contentContainerPage} ${layoutMixins.contentContainerPage}
gap: 1.5rem; gap: 1.5rem;
@media ${breakpoints.tablet} {
padding: 1rem;
}
`; `;
Styled.Panel = styled(Panel)` Styled.Panel = styled(Panel)`
padding: 0 1.5rem 1rem; padding: 1rem 1.5rem;
@media ${breakpoints.tablet} {
max-width: calc(100vw - 2rem);
}
`; `;
Styled.Row = styled.div` Styled.Title = styled.h3`
${layoutMixins.spacedRow} font: var(--font-medium-book);
gap: 1rem; color: var(--color-text-2);
padding: 1rem 1.5rem 0;
align-items: center;
`; `;
Styled.Description = styled.div` Styled.Description = styled.div`
color: var(--color-text-0); color: var(--color-text-0);
--link-color: var(--color-text-1);
a {
color: var(--color-text-1);
}
`; `;
Styled.Migrate = styled.section` Styled.PanelRow = styled.div`
max-width: min(100vw, var(--content-max-width)); ${layoutMixins.spacedRow}
padding: 1.5rem;
background-color: var(--color-layer-3);
border-radius: 0.875rem;
`;
Styled.TwoItemRow = styled(Styled.Row)`
grid-template-columns: 1fr 1fr;
`;
Styled.MigrateAction = styled(Styled.TwoItemRow)`
padding: 1rem;
background-color: var(--color-layer-2);
border: solid var(--border-width) var(--color-border);
border-radius: 0.75rem;
`;
Styled.Token = styled(Output)`
font: var(--font-large-book);
`;
Styled.PanelRow = styled(Styled.Row)`
gap: 1.5rem; gap: 1.5rem;
max-width: min(100vw, var(--content-max-width)); max-width: min(100vw, var(--content-max-width));
align-items: flex-start; align-items: flex-start;
@@ -269,65 +134,11 @@ Styled.BalancePanelContainer = styled.div`
} }
`; `;
Styled.Title = styled.h3`
${layoutMixins.inlineRow}
padding: 1.25rem 1.5rem 0.5rem;
font: var(--font-medium-book);
color: var(--color-text-2);
`;
Styled.MigrateTitle = styled(Styled.Title)`
padding: 0 0 0.5rem;
`;
Styled.MobileMigrateCard = styled(Styled.Panel)`
${layoutMixins.flexColumn}
gap: 1rem;
align-items: center;
`;
Styled.MobileMigrateHeader = styled(Styled.Title)`
${layoutMixins.inlineRow}
gap: 1ch;
padding-bottom: 1rem;
font: var(--font-small-book);
color: var(--color-text-0);
h3 {
${layoutMixins.inlineRow}
font: var(--font-large-book);
color: var(--color-text-2);
svg {
font-size: 1.75rem;
}
}
span {
margin-top: 0.2rem;
b {
font-weight: var(--fontWeight-book);
color: var(--color-text-1);
}
}
`;
Styled.Details = styled(Details)`
padding: 0.5rem 1rem;
`;
Styled.WithReceipt = styled(WithReceipt)`
width: 100%;
`;
Styled.LearnMore = styled(Styled.Description)`
${layoutMixins.row}
gap: 1ch;
`;
Styled.IconButton = styled(IconButton)` Styled.IconButton = styled(IconButton)`
color: var(--color-text-0); color: var(--color-text-0);
--color-border: var(--color-layer-6);
`;
Styled.Arrow = styled.div`
padding: 1rem 1.5rem;
`; `;
+2 -2
View File
@@ -17,7 +17,7 @@ import { MustBigNumber } from '@/lib/numbers';
import { MidMarketPrice } from '@/views/MidMarketPrice'; import { MidMarketPrice } from '@/views/MidMarketPrice';
export const TradeHeaderMobile = () => { export const TradeHeaderMobile = () => {
const { name, symbol } = useSelector(getCurrentMarketAssetData, shallowEqual) ?? {}; const { name, id } = useSelector(getCurrentMarketAssetData, shallowEqual) ?? {};
const navigate = useNavigate(); const navigate = useNavigate();
const { market, priceChange24H, priceChange24HPercent } = const { market, priceChange24H, priceChange24HPercent } =
@@ -27,7 +27,7 @@ export const TradeHeaderMobile = () => {
<Styled.Header> <Styled.Header>
<BackButton onClick={() => navigate(AppRoute.Markets)} /> <BackButton onClick={() => navigate(AppRoute.Markets)} />
<Styled.MarketName> <Styled.MarketName>
<Styled.AssetIcon symbol={symbol} /> <Styled.AssetIcon symbol={id} />
<Styled.Name> <Styled.Name>
<h3>{name}</h3> <h3>{name}</h3>
<span>{market}</span> <span>{market}</span>
+1 -1
View File
@@ -168,7 +168,7 @@ Styled.TriggerIcon = styled.span`
width: 0.75em; width: 0.75em;
display: inline-flex; display: inline-flex;
transition: transform 0.3s var(--ease-out-expo); transition: rotate 0.3s var(--ease-out-expo);
${Styled.Trigger}[data-state='open'] & { ${Styled.Trigger}[data-state='open'] & {
rotate: -0.5turn; rotate: -0.5turn;
@@ -104,4 +104,5 @@ Styled.Button = styled(Button)`
Styled.IconButton = styled(IconButton)` Styled.IconButton = styled(IconButton)`
color: var(--color-text-0); color: var(--color-text-0);
--color-border: var(--color-layer-6);
`; `;
@@ -130,12 +130,14 @@ export const GenerateKeys = ({
} }
} }
} catch (error) { } catch (error) {
setStatus(EvmDerivedAccountStatus.NotDerived);
const { message } = parseWalletError({ error, stringGetter }); const { message } = parseWalletError({ error, stringGetter });
if (message) { if (message) {
track(AnalyticsEvent.OnboardingWalletIsNonDeterministic); track(AnalyticsEvent.OnboardingWalletIsNonDeterministic);
setError(message); setError(message);
} }
return;
} }
await setWalletFromEvmSignature(signature); await setWalletFromEvmSignature(signature);
+1 -1
View File
@@ -37,7 +37,7 @@ export const TradeDialog = ({ isOpen, setIsOpen, slotTrigger }: ElementProps) =>
const selectedTradeType = getSelectedTradeType(type); const selectedTradeType = getSelectedTradeType(type);
const { typeOptions } = useSelector(getInputTradeOptions, shallowEqual) ?? {}; const { typeOptions } = useSelector(getInputTradeOptions, shallowEqual) ?? {};
const allTradeTypeItems = typeOptions?.toArray()?.map(({ type, stringKey }) => ({ const allTradeTypeItems = (typeOptions?.toArray() ?? []).map(({ type, stringKey }) => ({
value: type, value: type,
label: stringGetter({ label: stringGetter({
key: stringKey as StringKey, key: stringKey as StringKey,
-1
View File
@@ -322,7 +322,6 @@ export const TradeForm = ({
summary={summary ?? undefined} summary={summary ?? undefined}
currentStep={currentStep} currentStep={currentStep}
showDeposit={inputAlert?.errorAction === TradeInputErrorAction.DEPOSIT} showDeposit={inputAlert?.errorAction === TradeInputErrorAction.DEPOSIT}
showConnectWallet={inputAlert?.errorAction === TradeInputErrorAction.CONNECT_WALLET}
/> />
</Styled.Footer> </Styled.Footer>
</Styled.TradeForm> </Styled.TradeForm>
@@ -7,9 +7,8 @@ import { DialogTypes } from '@/constants/dialogs';
import { STRING_KEYS } from '@/constants/localization'; import { STRING_KEYS } from '@/constants/localization';
import { TRADE_TYPE_STRINGS, MobilePlaceOrderSteps } from '@/constants/trade'; import { TRADE_TYPE_STRINGS, MobilePlaceOrderSteps } from '@/constants/trade';
import { useStringGetter } from '@/hooks'; import { useStringGetter, useTokenConfigs } from '@/hooks';
import { AssetIcon } from '@/components/AssetIcon';
import { Button } from '@/components/Button'; import { Button } from '@/components/Button';
import { Output, OutputType, ShowSign } from '@/components/Output'; import { Output, OutputType, ShowSign } from '@/components/Output';
import { WithDetailsReceipt } from '@/components/WithDetailsReceipt'; import { WithDetailsReceipt } from '@/components/WithDetailsReceipt';
@@ -47,6 +46,7 @@ export const PlaceOrderButtonAndReceipt = ({
}: ElementProps) => { }: ElementProps) => {
const stringGetter = useStringGetter(); const stringGetter = useStringGetter();
const dispatch = useDispatch(); const dispatch = useDispatch();
const { chainTokenLabel } = useTokenConfigs();
const canAccountTrade = useSelector(calculateCanAccountTrade); const canAccountTrade = useSelector(calculateCanAccountTrade);
const subaccountNumber = useSelector(getSubaccountId); const subaccountNumber = useSelector(getSubaccountId);
@@ -88,7 +88,14 @@ export const PlaceOrderButtonAndReceipt = ({
{/* <AssetIcon symbol="DYDX" /> */} {/* <AssetIcon symbol="DYDX" /> */}
</> </>
), ),
value: <Output type={OutputType.Asset} value={reward} useGrouping tag={reward ? "Dv4TNT" : ''} />, value: (
<Output
type={OutputType.Asset}
value={reward}
useGrouping
tag={reward ? chainTokenLabel : ''}
/>
),
tooltip: 'max-reward', tooltip: 'max-reward',
}, },
{ {
@@ -111,7 +118,7 @@ export const PlaceOrderButtonAndReceipt = ({
? actionStringKey ? actionStringKey
: STRING_KEYS.UNAVAILABLE, : STRING_KEYS.UNAVAILABLE,
buttonAction: ButtonAction.Primary, buttonAction: ButtonAction.Primary,
buttonState: { isDisabled: !shouldEnableTrade }, buttonState: { isDisabled: !shouldEnableTrade, isLoading: hasMissingData },
}, },
[MobilePlaceOrderSteps.PreviewOrder]: { [MobilePlaceOrderSteps.PreviewOrder]: {
@@ -148,7 +155,10 @@ export const PlaceOrderButtonAndReceipt = ({
const buttonState = currentStep const buttonState = currentStep
? buttonStatesPerStep[currentStep].buttonState ? buttonStatesPerStep[currentStep].buttonState
: { isDisabled: !shouldEnableTrade || isLoading, isLoading }; : {
isDisabled: !shouldEnableTrade || isLoading,
isLoading: isLoading || hasMissingData,
};
return ( return (
<WithDetailsReceipt detailItems={items}> <WithDetailsReceipt detailItems={items}>
+3 -3
View File
@@ -231,7 +231,7 @@ const getOrdersTableColumnDef = ({
key: STRING_KEYS.FILL, key: STRING_KEYS.FILL,
})}`, })}`,
renderCell: ({ renderCell: ({
asset: { symbol: assetSymbol }, asset,
createdAtMilliseconds, createdAtMilliseconds,
size, size,
status, status,
@@ -254,7 +254,7 @@ const getOrdersTableColumnDef = ({
value={createdAtMilliseconds} value={createdAtMilliseconds}
/> />
<Styled.AssetIconWithStatus> <Styled.AssetIconWithStatus>
<Styled.AssetIcon symbol={assetSymbol} /> <Styled.AssetIcon symbol={asset?.id} />
<Styled.StatusDot color={statusIconColor} /> <Styled.StatusDot color={statusIconColor} />
</Styled.AssetIconWithStatus> </Styled.AssetIconWithStatus>
</> </>
@@ -276,7 +276,7 @@ const getOrdersTableColumnDef = ({
type={OutputType.Asset} type={OutputType.Asset}
value={size} value={size}
fractionDigits={TOKEN_DECIMALS} fractionDigits={TOKEN_DECIMALS}
tag={assetSymbol} tag={asset?.id}
/> />
</Styled.InlineRow> </Styled.InlineRow>
</TableCell> </TableCell>