Compare commits
10
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e1e817ea92 | ||
|
|
4b85ec7df0 | ||
|
|
051bdda73a | ||
|
|
27b79957d4 | ||
|
|
4bacc901dc | ||
|
|
82d32a91a9 | ||
|
|
2a794f9459 | ||
|
|
5c26a0c270 | ||
|
|
e4991cc31d | ||
|
|
da908c826a |
@@ -11,6 +11,7 @@
|
|||||||
## Prerequisites
|
## Prerequisites
|
||||||
|
|
||||||
- Node.js version 18 and `pnpm` installed on your system
|
- Node.js version 18 and `pnpm` installed on your system
|
||||||
|
- Wallet Connect account
|
||||||
|
|
||||||
For deploying with Vercel, create an account with [Vercel](https://vercel.com/signup) if you don't have one already.
|
For deploying with Vercel, create an account with [Vercel](https://vercel.com/signup) if you don't have one already.
|
||||||
|
|
||||||
@@ -61,7 +62,14 @@ pnpm ladle
|
|||||||
|
|
||||||
This will automatically open your default browser at `http://localhost:61000`.
|
This will automatically open your default browser at `http://localhost:61000`.
|
||||||
|
|
||||||
## Part 3: Deploying with Vercel
|
## Part 3: Configuring environment
|
||||||
|
|
||||||
|
Add or modify the relevant endpoints, links and options in `/public/configs/env.json`.
|
||||||
|
You'll need to provide a Wallet Connect project id to enable onboarding and wallet connection:
|
||||||
|
- Create a project on https://cloud.walletconnect.com/app
|
||||||
|
- Copy over the project ID into this [field](https://github.com/dydxprotocol/v4-web/blob/67ecbd75b43e0c264b7b4d2d9b3d969830b0621c/public/configs/env.json#L822C33-L822C46)
|
||||||
|
|
||||||
|
## Part 4: Deploying with Vercel
|
||||||
|
|
||||||
### Step 1: Connect your repository to Vercel
|
### Step 1: Connect your repository to Vercel
|
||||||
|
|
||||||
@@ -78,7 +86,7 @@ If you wish to incorporate analytics via Amplitude and Bugsnag, you can use our
|
|||||||
|
|
||||||
For more details, check out Vercel's [official documentation](https://vercel.com/docs).
|
For more details, check out Vercel's [official documentation](https://vercel.com/docs).
|
||||||
|
|
||||||
## Part 4: Deploying to IPFS
|
## Part 5: Deploying to IPFS
|
||||||
|
|
||||||
### web3.storage: deploy to IPFS via web3.storage using the provided script
|
### web3.storage: deploy to IPFS via web3.storage using the provided script
|
||||||
|
|
||||||
|
|||||||
+3
-3
@@ -38,9 +38,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.0",
|
"@dydxprotocol/v4-abacus": "^0.7.2",
|
||||||
"@dydxprotocol/v4-client-js": "^0.36.1",
|
"@dydxprotocol/v4-client-js": "^0.40.3",
|
||||||
"@dydxprotocol/v4-localization": "^0.1.30",
|
"@dydxprotocol/v4-localization": "^0.1.32",
|
||||||
"@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",
|
||||||
|
|||||||
Generated
+25
-24
@@ -27,14 +27,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.0
|
specifier: ^0.7.2
|
||||||
version: 0.7.0
|
version: 0.7.2
|
||||||
'@dydxprotocol/v4-client-js':
|
'@dydxprotocol/v4-client-js':
|
||||||
specifier: ^0.36.1
|
specifier: ^0.40.3
|
||||||
version: 0.36.1
|
version: 0.40.3
|
||||||
'@dydxprotocol/v4-localization':
|
'@dydxprotocol/v4-localization':
|
||||||
specifier: ^0.1.30
|
specifier: ^0.1.32
|
||||||
version: 0.1.30
|
version: 0.1.32
|
||||||
'@ethersproject/providers':
|
'@ethersproject/providers':
|
||||||
specifier: ^5.7.2
|
specifier: ^5.7.2
|
||||||
version: 5.7.2
|
version: 5.7.2
|
||||||
@@ -645,7 +645,7 @@ packages:
|
|||||||
/@confio/ics23@0.6.8:
|
/@confio/ics23@0.6.8:
|
||||||
resolution: {integrity: sha512-wB6uo+3A50m0sW/EWcU64xpV/8wShZ6bMTa7pF8eYsTrSkQA7oLUIJcs/wb8g4y2Oyq701BaGiO6n/ak5WXO1w==}
|
resolution: {integrity: sha512-wB6uo+3A50m0sW/EWcU64xpV/8wShZ6bMTa7pF8eYsTrSkQA7oLUIJcs/wb8g4y2Oyq701BaGiO6n/ak5WXO1w==}
|
||||||
dependencies:
|
dependencies:
|
||||||
'@noble/hashes': 1.3.1
|
'@noble/hashes': 1.3.2
|
||||||
protobufjs: 6.11.4
|
protobufjs: 6.11.4
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
@@ -717,7 +717,7 @@ packages:
|
|||||||
'@cosmjs/encoding': 0.30.1
|
'@cosmjs/encoding': 0.30.1
|
||||||
'@cosmjs/math': 0.30.1
|
'@cosmjs/math': 0.30.1
|
||||||
'@cosmjs/utils': 0.30.1
|
'@cosmjs/utils': 0.30.1
|
||||||
'@noble/hashes': 1.3.1
|
'@noble/hashes': 1.3.2
|
||||||
bn.js: 5.2.1
|
bn.js: 5.2.1
|
||||||
elliptic: 6.5.4
|
elliptic: 6.5.4
|
||||||
libsodium-wrappers: 0.7.11
|
libsodium-wrappers: 0.7.11
|
||||||
@@ -979,12 +979,12 @@ packages:
|
|||||||
resolution: {integrity: sha512-RpfLEtTlyIxeNPGKcokS+p3BZII/Q3bYxryFRglh5H3A3T8q9fsLYm72VYAMEOOIBLEa8o93kFLiBDUWKrwXZA==}
|
resolution: {integrity: sha512-RpfLEtTlyIxeNPGKcokS+p3BZII/Q3bYxryFRglh5H3A3T8q9fsLYm72VYAMEOOIBLEa8o93kFLiBDUWKrwXZA==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/@dydxprotocol/v4-abacus@0.7.0:
|
/@dydxprotocol/v4-abacus@0.7.2:
|
||||||
resolution: {integrity: sha512-XheqfIpOODfQFG860oH0fneVgp9qQKPMDTwrvFXaM/JtKH9ekOUUO6De72EsJ7qOuxWwl1WgoALA8b4tRs0tiw==}
|
resolution: {integrity: sha512-5foamomN82FH6ko3EuzwFlSoAEY6Sal8fDgvZo2RsB19Ks6SFgFDeeOcEDdfoa3DNwvl8yW0C9cfxeQ+BfU8uA==}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/@dydxprotocol/v4-client-js@0.36.1:
|
/@dydxprotocol/v4-client-js@0.40.3:
|
||||||
resolution: {integrity: sha512-KJ3MtWI61wmm+xZtXQd7/hYKIoVFG32TRdyyVaXXO8vpW9Oqd0JD8QSM/wuegkciAh5YmP/BrDzYuu77zHO6yg==}
|
resolution: {integrity: sha512-nMQd6tYisKDKIbfx0BGJSYEOSt+I+t5SsaBSmlgTdso+w2rCRO9vyxS+u6MF9h4w5FsVRfhHo3e6uTWX48WpGQ==}
|
||||||
dependencies:
|
dependencies:
|
||||||
'@cosmjs/amino': 0.30.1
|
'@cosmjs/amino': 0.30.1
|
||||||
'@cosmjs/encoding': 0.31.1
|
'@cosmjs/encoding': 0.31.1
|
||||||
@@ -993,14 +993,15 @@ packages:
|
|||||||
'@cosmjs/stargate': 0.30.1
|
'@cosmjs/stargate': 0.30.1
|
||||||
'@cosmjs/tendermint-rpc': 0.30.1
|
'@cosmjs/tendermint-rpc': 0.30.1
|
||||||
'@cosmjs/utils': 0.31.1
|
'@cosmjs/utils': 0.31.1
|
||||||
'@dydxprotocol/v4-proto': 0.2.1
|
'@dydxprotocol/v4-proto': 0.4.1
|
||||||
'@osmonauts/lcd': 0.6.0
|
'@osmonauts/lcd': 0.6.0
|
||||||
'@scure/bip32': 1.3.1
|
'@scure/bip32': 1.3.2
|
||||||
'@scure/bip39': 1.2.1
|
'@scure/bip39': 1.2.1
|
||||||
axios: 1.1.3
|
axios: 1.1.3
|
||||||
bech32: 1.1.4
|
bech32: 1.1.4
|
||||||
bignumber.js: 9.1.1
|
bignumber.js: 9.1.1
|
||||||
ethereum-cryptography: 2.1.2
|
ethereum-cryptography: 2.1.2
|
||||||
|
ethers: 6.6.1
|
||||||
long: 4.0.0
|
long: 4.0.0
|
||||||
protobufjs: 6.11.4
|
protobufjs: 6.11.4
|
||||||
ws: 8.13.0(bufferutil@4.0.7)(utf-8-validate@5.0.10)
|
ws: 8.13.0(bufferutil@4.0.7)(utf-8-validate@5.0.10)
|
||||||
@@ -1010,12 +1011,12 @@ packages:
|
|||||||
- utf-8-validate
|
- utf-8-validate
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/@dydxprotocol/v4-localization@0.1.30:
|
/@dydxprotocol/v4-localization@0.1.32:
|
||||||
resolution: {integrity: sha512-xTlQuQmPz7wfGkjd07giYMAxRrolDbJE3DryJSIMB6R1MBq1wLzAcwp/iR/nELRwilRX9c44Tap0gGt+oAajiQ==}
|
resolution: {integrity: sha512-ZtXScxgFLjUt0Ag52RyFnQe9aEl1Aky5fp+vMGOBduVkFiCEMRMkSsSgg6grMdyw/x0AbnxOTRkhYoX2MsK9Ow==}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/@dydxprotocol/v4-proto@0.2.1:
|
/@dydxprotocol/v4-proto@0.4.1:
|
||||||
resolution: {integrity: sha512-Q5b/g331DoyMjBpO2/jtrxUX3WF5UaIKZp/unK332xuefHNFnkMYtZ05p0V71iSdO35tBdz8yt0VYP2WtUsp+w==}
|
resolution: {integrity: sha512-2pBkokufWcxfIpiXE6QuQOBXUe154OTp6ojCIdOPW9TFLxzchoygxXnb5dL6rAQVNj9Qbg+hhXBllutt4m99dw==}
|
||||||
dependencies:
|
dependencies:
|
||||||
protobufjs: 6.11.4
|
protobufjs: 6.11.4
|
||||||
dev: false
|
dev: false
|
||||||
@@ -4708,8 +4709,8 @@ packages:
|
|||||||
resolution: {integrity: sha512-osvveYtyzdEVbt3OfwwXFr4P2iVBL5u1Q3q4ONBfDY/UpOuXmOlbgwc1xECEboY8wIays8Yt6onaWMUdUbfl0A==}
|
resolution: {integrity: sha512-osvveYtyzdEVbt3OfwwXFr4P2iVBL5u1Q3q4ONBfDY/UpOuXmOlbgwc1xECEboY8wIays8Yt6onaWMUdUbfl0A==}
|
||||||
dependencies:
|
dependencies:
|
||||||
'@noble/curves': 1.1.0
|
'@noble/curves': 1.1.0
|
||||||
'@noble/hashes': 1.3.1
|
'@noble/hashes': 1.3.2
|
||||||
'@scure/base': 1.1.1
|
'@scure/base': 1.1.3
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/@scure/bip32@1.3.2:
|
/@scure/bip32@1.3.2:
|
||||||
@@ -4731,7 +4732,7 @@ packages:
|
|||||||
resolution: {integrity: sha512-Z3/Fsz1yr904dduJD0NpiyRHhRYHdcnyh73FZWiV+/qhWi83wNJ3NWolYqCEN+ZWsUz2TWwajJggcRE9r1zUYg==}
|
resolution: {integrity: sha512-Z3/Fsz1yr904dduJD0NpiyRHhRYHdcnyh73FZWiV+/qhWi83wNJ3NWolYqCEN+ZWsUz2TWwajJggcRE9r1zUYg==}
|
||||||
dependencies:
|
dependencies:
|
||||||
'@noble/hashes': 1.3.2
|
'@noble/hashes': 1.3.2
|
||||||
'@scure/base': 1.1.1
|
'@scure/base': 1.1.3
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/@solana/buffer-layout@4.0.1:
|
/@solana/buffer-layout@4.0.1:
|
||||||
@@ -4745,8 +4746,8 @@ packages:
|
|||||||
resolution: {integrity: sha512-up5VG1dK+GPhykmuMIozJZBbVqpm77vbOG6/r5dS7NBGZonwHfTLdBbsYc3rjmaQ4DpCXUa3tUc4RZHRORvZrw==}
|
resolution: {integrity: sha512-up5VG1dK+GPhykmuMIozJZBbVqpm77vbOG6/r5dS7NBGZonwHfTLdBbsYc3rjmaQ4DpCXUa3tUc4RZHRORvZrw==}
|
||||||
dependencies:
|
dependencies:
|
||||||
'@babel/runtime': 7.22.10
|
'@babel/runtime': 7.22.10
|
||||||
'@noble/curves': 1.1.0
|
'@noble/curves': 1.2.0
|
||||||
'@noble/hashes': 1.3.1
|
'@noble/hashes': 1.3.2
|
||||||
'@solana/buffer-layout': 4.0.1
|
'@solana/buffer-layout': 4.0.1
|
||||||
agentkeepalive: 4.5.0
|
agentkeepalive: 4.5.0
|
||||||
bigint-buffer: 1.1.5
|
bigint-buffer: 1.1.5
|
||||||
@@ -7144,7 +7145,7 @@ packages:
|
|||||||
/bip39@3.1.0:
|
/bip39@3.1.0:
|
||||||
resolution: {integrity: sha512-c9kiwdk45Do5GL0vJMe7tS95VjCii65mYAH7DfWl3uW8AVzXKQVUm64i3hzVybBDMp9r7j9iNxR85+ul8MdN/A==}
|
resolution: {integrity: sha512-c9kiwdk45Do5GL0vJMe7tS95VjCii65mYAH7DfWl3uW8AVzXKQVUm64i3hzVybBDMp9r7j9iNxR85+ul8MdN/A==}
|
||||||
dependencies:
|
dependencies:
|
||||||
'@noble/hashes': 1.3.1
|
'@noble/hashes': 1.3.2
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/bl@5.1.0:
|
/bl@5.1.0:
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 16 KiB |
+16
-16
@@ -40,7 +40,7 @@
|
|||||||
"isMainNet": false,
|
"isMainNet": false,
|
||||||
"tokens": {
|
"tokens": {
|
||||||
"chain": {
|
"chain": {
|
||||||
"name": "DYDX",
|
"name": "Dv4TNT",
|
||||||
"denom": "adv4tnt",
|
"denom": "adv4tnt",
|
||||||
"decimals": 18,
|
"decimals": 18,
|
||||||
"image": "/currencies/dydx.png"
|
"image": "/currencies/dydx.png"
|
||||||
@@ -100,7 +100,7 @@
|
|||||||
"isMainNet": false,
|
"isMainNet": false,
|
||||||
"tokens": {
|
"tokens": {
|
||||||
"chain": {
|
"chain": {
|
||||||
"name": "DYDX",
|
"name": "Dv4TNT",
|
||||||
"denom": "adv4tnt",
|
"denom": "adv4tnt",
|
||||||
"decimals": 18,
|
"decimals": 18,
|
||||||
"image": "/currencies/dydx.png"
|
"image": "/currencies/dydx.png"
|
||||||
@@ -121,7 +121,7 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"validators": [
|
"validators": [
|
||||||
"http://35.75.227.118"
|
"http://54.92.118.111"
|
||||||
],
|
],
|
||||||
"0xsquid": "https://testnet.api.0xsquid.com"
|
"0xsquid": "https://testnet.api.0xsquid.com"
|
||||||
},
|
},
|
||||||
@@ -159,7 +159,7 @@
|
|||||||
"isMainNet": false,
|
"isMainNet": false,
|
||||||
"tokens": {
|
"tokens": {
|
||||||
"chain": {
|
"chain": {
|
||||||
"name": "DYDX",
|
"name": "Dv4TNT",
|
||||||
"denom": "adv4tnt",
|
"denom": "adv4tnt",
|
||||||
"decimals": 18,
|
"decimals": 18,
|
||||||
"image": "/currencies/dydx.png"
|
"image": "/currencies/dydx.png"
|
||||||
@@ -218,7 +218,7 @@
|
|||||||
"isMainNet": false,
|
"isMainNet": false,
|
||||||
"tokens": {
|
"tokens": {
|
||||||
"chain": {
|
"chain": {
|
||||||
"name": "DYDX",
|
"name": "Dv4TNT",
|
||||||
"denom": "adv4tnt",
|
"denom": "adv4tnt",
|
||||||
"decimals": 18,
|
"decimals": 18,
|
||||||
"image": "/currencies/dydx.png"
|
"image": "/currencies/dydx.png"
|
||||||
@@ -277,7 +277,7 @@
|
|||||||
"isMainNet": false,
|
"isMainNet": false,
|
||||||
"tokens": {
|
"tokens": {
|
||||||
"chain": {
|
"chain": {
|
||||||
"name": "DYDX",
|
"name": "Dv4TNT",
|
||||||
"denom": "adv4tnt",
|
"denom": "adv4tnt",
|
||||||
"decimals": 18,
|
"decimals": 18,
|
||||||
"image": "/currencies/dydx.png"
|
"image": "/currencies/dydx.png"
|
||||||
@@ -340,7 +340,7 @@
|
|||||||
"isMainNet": false,
|
"isMainNet": false,
|
||||||
"tokens": {
|
"tokens": {
|
||||||
"chain": {
|
"chain": {
|
||||||
"name": "DYDX",
|
"name": "Dv4TNT",
|
||||||
"denom": "adv4tnt",
|
"denom": "adv4tnt",
|
||||||
"decimals": 18,
|
"decimals": 18,
|
||||||
"image": "/currencies/dydx.png"
|
"image": "/currencies/dydx.png"
|
||||||
@@ -403,7 +403,7 @@
|
|||||||
"isMainNet": false,
|
"isMainNet": false,
|
||||||
"tokens": {
|
"tokens": {
|
||||||
"chain": {
|
"chain": {
|
||||||
"name": "DYDX",
|
"name": "Dv4TNT",
|
||||||
"denom": "adv4tnt",
|
"denom": "adv4tnt",
|
||||||
"decimals": 18,
|
"decimals": 18,
|
||||||
"image": "/currencies/dydx.png"
|
"image": "/currencies/dydx.png"
|
||||||
@@ -468,7 +468,7 @@
|
|||||||
"isMainNet": false,
|
"isMainNet": false,
|
||||||
"tokens": {
|
"tokens": {
|
||||||
"chain": {
|
"chain": {
|
||||||
"name": "DYDX",
|
"name": "Dv4TNT",
|
||||||
"denom": "adv4tnt",
|
"denom": "adv4tnt",
|
||||||
"decimals": 18,
|
"decimals": 18,
|
||||||
"image": "/currencies/dydx.png"
|
"image": "/currencies/dydx.png"
|
||||||
@@ -532,7 +532,7 @@
|
|||||||
"isMainNet": false,
|
"isMainNet": false,
|
||||||
"tokens": {
|
"tokens": {
|
||||||
"chain": {
|
"chain": {
|
||||||
"name": "DYDX",
|
"name": "Dv4TNT",
|
||||||
"denom": "adv4tnt",
|
"denom": "adv4tnt",
|
||||||
"decimals": 18,
|
"decimals": 18,
|
||||||
"image": "/currencies/dydx.png"
|
"image": "/currencies/dydx.png"
|
||||||
@@ -596,7 +596,7 @@
|
|||||||
"isMainNet": false,
|
"isMainNet": false,
|
||||||
"tokens": {
|
"tokens": {
|
||||||
"chain": {
|
"chain": {
|
||||||
"name": "DYDX",
|
"name": "Dv4TNT",
|
||||||
"denom": "adv4tnt",
|
"denom": "adv4tnt",
|
||||||
"decimals": 18,
|
"decimals": 18,
|
||||||
"image": "/currencies/dydx.png"
|
"image": "/currencies/dydx.png"
|
||||||
@@ -660,7 +660,7 @@
|
|||||||
"isMainNet": false,
|
"isMainNet": false,
|
||||||
"tokens": {
|
"tokens": {
|
||||||
"chain": {
|
"chain": {
|
||||||
"name": "DYDX",
|
"name": "Dv4TNT",
|
||||||
"denom": "adv4tnt",
|
"denom": "adv4tnt",
|
||||||
"decimals": 18,
|
"decimals": 18,
|
||||||
"image": "/currencies/dydx.png"
|
"image": "/currencies/dydx.png"
|
||||||
@@ -724,7 +724,7 @@
|
|||||||
"isMainNet": false,
|
"isMainNet": false,
|
||||||
"tokens": {
|
"tokens": {
|
||||||
"chain": {
|
"chain": {
|
||||||
"name": "DYDX",
|
"name": "Dv4TNT",
|
||||||
"denom": "adv4tnt",
|
"denom": "adv4tnt",
|
||||||
"decimals": 18,
|
"decimals": 18,
|
||||||
"image": "/currencies/dydx.png"
|
"image": "/currencies/dydx.png"
|
||||||
@@ -789,8 +789,8 @@
|
|||||||
"tokens": {
|
"tokens": {
|
||||||
"comment": "Change according to mainnet release",
|
"comment": "Change according to mainnet release",
|
||||||
"chain": {
|
"chain": {
|
||||||
"name": "DYDX",
|
"name": "TokenName",
|
||||||
"denom": "adv4tnt",
|
"denom": "tokenDenom",
|
||||||
"decimals": 18,
|
"decimals": 18,
|
||||||
"image": "/currencies/dydx.png"
|
"image": "/currencies/dydx.png"
|
||||||
},
|
},
|
||||||
@@ -844,4 +844,4 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+14
-2
@@ -7,7 +7,13 @@ import { GrazProvider } from 'graz';
|
|||||||
|
|
||||||
import { AppRoute, DEFAULT_TRADE_ROUTE } from '@/constants/routes';
|
import { AppRoute, DEFAULT_TRADE_ROUTE } from '@/constants/routes';
|
||||||
|
|
||||||
import { useBreakpoints, useInitializePage, useShouldShowFooter, useAnalytics } from '@/hooks';
|
import {
|
||||||
|
useBreakpoints,
|
||||||
|
useTokenConfigs,
|
||||||
|
useInitializePage,
|
||||||
|
useShouldShowFooter,
|
||||||
|
useAnalytics,
|
||||||
|
} from '@/hooks';
|
||||||
import { DydxProvider } from '@/hooks/useDydxClient';
|
import { DydxProvider } from '@/hooks/useDydxClient';
|
||||||
import { AccountsProvider } from '@/hooks/useAccounts';
|
import { AccountsProvider } from '@/hooks/useAccounts';
|
||||||
import { DialogAreaProvider, useDialogArea } from '@/hooks/useDialogArea';
|
import { DialogAreaProvider, useDialogArea } from '@/hooks/useDialogArea';
|
||||||
@@ -27,6 +33,8 @@ import ProfilePage from '@/pages/Profile';
|
|||||||
import { SettingsPage } from '@/pages/settings/Settings';
|
import { SettingsPage } from '@/pages/settings/Settings';
|
||||||
import TradePage from '@/pages/trade/Trade';
|
import TradePage from '@/pages/trade/Trade';
|
||||||
import { RewardsPage } from '@/pages/rewards/RewardsPage';
|
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';
|
||||||
@@ -55,6 +63,7 @@ const Content = () => {
|
|||||||
const { isTablet, isNotTablet } = useBreakpoints();
|
const { isTablet, isNotTablet } = useBreakpoints();
|
||||||
const isShowingHeader = isNotTablet;
|
const isShowingHeader = isNotTablet;
|
||||||
const isShowingFooter = useShouldShowFooter();
|
const isShowingFooter = useShouldShowFooter();
|
||||||
|
const { chainTokenLabel } = useTokenConfigs();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Styled.Content isShowingHeader={isShowingHeader} isShowingFooter={isShowingFooter}>
|
<Styled.Content isShowingHeader={isShowingHeader} isShowingFooter={isShowingFooter}>
|
||||||
@@ -69,7 +78,7 @@ const Content = () => {
|
|||||||
</Route>
|
</Route>
|
||||||
|
|
||||||
<Route path={AppRoute.Markets} element={<MarketsPage />} />
|
<Route path={AppRoute.Markets} element={<MarketsPage />} />
|
||||||
<Route path={AppRoute.Rewards} element={<RewardsPage />} />
|
<Route path={`/${chainTokenLabel}`} element={<RewardsPage />} />
|
||||||
{isTablet && (
|
{isTablet && (
|
||||||
<>
|
<>
|
||||||
<Route path={AppRoute.Alerts} element={<AlertsPage />} />
|
<Route path={AppRoute.Alerts} element={<AlertsPage />} />
|
||||||
@@ -82,6 +91,9 @@ const Content = () => {
|
|||||||
<Route path={`${AppRoute.Portfolio}/*`} element={<PortfolioPage />} />
|
<Route path={`${AppRoute.Portfolio}/*`} element={<PortfolioPage />} />
|
||||||
</Route>
|
</Route>
|
||||||
|
|
||||||
|
<Route path={AppRoute.Terms} element={<TermsOfUsePage />} />
|
||||||
|
<Route path={AppRoute.Privacy} element={<PrivacyPolicyPage />} />
|
||||||
|
|
||||||
<Route path="*" element={<Navigate to={DEFAULT_TRADE_ROUTE} replace />} />
|
<Route path="*" element={<Navigate to={DEFAULT_TRADE_ROUTE} replace />} />
|
||||||
</Routes>
|
</Routes>
|
||||||
</Suspense>
|
</Suspense>
|
||||||
|
|||||||
@@ -7,7 +7,8 @@ export enum AppRoute {
|
|||||||
Profile = '/profile',
|
Profile = '/profile',
|
||||||
Alerts = '/alerts',
|
Alerts = '/alerts',
|
||||||
Settings = '/settings',
|
Settings = '/settings',
|
||||||
Rewards = '/DV4TNT',
|
Terms = '/terms',
|
||||||
|
Privacy = '/privacy',
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum PortfolioRoute {
|
export enum PortfolioRoute {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import type { ExternalProvider } from '@ethersproject/providers';
|
import type { ExternalProvider } from '@ethersproject/providers';
|
||||||
import { USDC_DENOM, type onboarding, DYDX_DENOM } from '@dydxprotocol/v4-client-js';
|
import { type onboarding } from '@dydxprotocol/v4-client-js';
|
||||||
import type { suggestChain } from 'graz';
|
import type { suggestChain } from 'graz';
|
||||||
|
|
||||||
import { STRING_KEYS } from '@/constants/localization';
|
import { STRING_KEYS } from '@/constants/localization';
|
||||||
@@ -352,15 +352,5 @@ export const DYDX_CHAIN_INFO: Parameters<typeof suggestChain>[0] = {
|
|||||||
// TODO: export this type from abacus instead
|
// TODO: export this type from abacus instead
|
||||||
export enum DydxChainAsset {
|
export enum DydxChainAsset {
|
||||||
USDC = 'usdc',
|
USDC = 'usdc',
|
||||||
DYDX = 'dydx',
|
CHAINTOKEN = 'chain',
|
||||||
}
|
}
|
||||||
|
|
||||||
export const DYDX_CHAIN_ASSET_COIN_DENOM: Record<DydxChainAsset, string> = {
|
|
||||||
[DydxChainAsset.USDC]: USDC_DENOM,
|
|
||||||
[DydxChainAsset.DYDX]: DYDX_DENOM,
|
|
||||||
};
|
|
||||||
|
|
||||||
export const DYDX_CHAIN_ASSET_TAGS: Record<DydxChainAsset, string> = {
|
|
||||||
[DydxChainAsset.USDC]: 'USDC',
|
|
||||||
[DydxChainAsset.DYDX]: 'Dv4TNT',
|
|
||||||
};
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { useApiState } from './useApiState';
|
import { useApiState } from './useApiState';
|
||||||
import { useBreakpoints } from './useBreakpoints';
|
import { useBreakpoints } from './useBreakpoints';
|
||||||
|
import { useTokenConfigs } from './useTokenConfigs';
|
||||||
import { useCommandMenu } from './useCommandMenu';
|
import { useCommandMenu } from './useCommandMenu';
|
||||||
import { useCurrentMarketId } from './useCurrentMarketId';
|
import { useCurrentMarketId } from './useCurrentMarketId';
|
||||||
import { useDebounce } from './useDebounce';
|
import { useDebounce } from './useDebounce';
|
||||||
@@ -25,6 +26,7 @@ import { useSubaccount } from './useSubaccount';
|
|||||||
export {
|
export {
|
||||||
useApiState,
|
useApiState,
|
||||||
useBreakpoints,
|
useBreakpoints,
|
||||||
|
useTokenConfigs,
|
||||||
useCommandMenu,
|
useCommandMenu,
|
||||||
useCurrentMarketId,
|
useCurrentMarketId,
|
||||||
useDebounce,
|
useDebounce,
|
||||||
|
|||||||
@@ -5,8 +5,6 @@ import { StargateClient } from '@cosmjs/stargate';
|
|||||||
import { useQuery } from 'react-query';
|
import { useQuery } from 'react-query';
|
||||||
import { formatUnits } from 'viem';
|
import { formatUnits } from 'viem';
|
||||||
|
|
||||||
import { USDC_DENOM, DYDX_DENOM } from '@dydxprotocol/v4-client-js';
|
|
||||||
|
|
||||||
import { ENVIRONMENT_CONFIG_MAP } from '@/constants/networks';
|
import { ENVIRONMENT_CONFIG_MAP } from '@/constants/networks';
|
||||||
import { QUANTUM_MULTIPLIER } from '@/constants/numbers';
|
import { QUANTUM_MULTIPLIER } from '@/constants/numbers';
|
||||||
import { EvmAddress } from '@/constants/wallets';
|
import { EvmAddress } from '@/constants/wallets';
|
||||||
@@ -18,6 +16,7 @@ import { getBalances, getStakingBalances } from '@/state/accountSelectors';
|
|||||||
import { getSelectedNetwork } from '@/state/appSelectors';
|
import { getSelectedNetwork } from '@/state/appSelectors';
|
||||||
|
|
||||||
import { useAccounts } from './useAccounts';
|
import { useAccounts } from './useAccounts';
|
||||||
|
import { useTokenConfigs } from './useTokenConfigs';
|
||||||
|
|
||||||
type UseAccountBalanceProps = {
|
type UseAccountBalanceProps = {
|
||||||
// Token Items
|
// Token Items
|
||||||
@@ -52,6 +51,7 @@ export const useAccountBalance = ({
|
|||||||
|
|
||||||
const selectedNetwork = useSelector(getSelectedNetwork);
|
const selectedNetwork = useSelector(getSelectedNetwork);
|
||||||
const balances = useSelector(getBalances, shallowEqual);
|
const balances = useSelector(getBalances, shallowEqual);
|
||||||
|
const { chainTokenDenom, usdcDenom } = useTokenConfigs();
|
||||||
const evmChainId = Number(ENVIRONMENT_CONFIG_MAP[selectedNetwork].ethereumChainId);
|
const evmChainId = Number(ENVIRONMENT_CONFIG_MAP[selectedNetwork].ethereumChainId);
|
||||||
const stakingBalances = useSelector(getStakingBalances, shallowEqual);
|
const stakingBalances = useSelector(getStakingBalances, shallowEqual);
|
||||||
|
|
||||||
@@ -93,18 +93,14 @@ export const useAccountBalance = ({
|
|||||||
const { formatted: evmBalance } = evmQuery.data || {};
|
const { formatted: evmBalance } = evmQuery.data || {};
|
||||||
const balance = !assetSymbol ? '0' : isCosmosChain ? cosmosQuery.data : evmBalance;
|
const balance = !assetSymbol ? '0' : isCosmosChain ? cosmosQuery.data : evmBalance;
|
||||||
|
|
||||||
const nativeTokenCoinBalance = balances?.[DYDX_DENOM];
|
const nativeTokenCoinBalance = balances?.[chainTokenDenom];
|
||||||
const nativeTokenBalance = MustBigNumber(nativeTokenCoinBalance?.amount)
|
const nativeTokenBalance = MustBigNumber(nativeTokenCoinBalance?.amount);
|
||||||
.div(QUANTUM_MULTIPLIER)
|
|
||||||
.toNumber();
|
|
||||||
|
|
||||||
const usdcCoinBalance = balances?.[USDC_DENOM];
|
const usdcCoinBalance = balances?.[usdcDenom];
|
||||||
const usdcBalance = MustBigNumber(usdcCoinBalance?.amount).div(QUANTUM_MULTIPLIER).toNumber();
|
const usdcBalance = MustBigNumber(usdcCoinBalance?.amount).toNumber();
|
||||||
|
|
||||||
const nativeStakingCoinBalanace = stakingBalances?.[DYDX_DENOM];
|
const nativeStakingCoinBalanace = stakingBalances?.[chainTokenDenom];
|
||||||
const nativeStakingBalance = MustBigNumber(nativeStakingCoinBalanace?.amount)
|
const nativeStakingBalance = MustBigNumber(nativeStakingCoinBalanace?.amount).toNumber();
|
||||||
.div(QUANTUM_MULTIPLIER)
|
|
||||||
.toNumber();
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
balance,
|
balance,
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { useCallback, useContext, createContext, useEffect, useState, useMemo }
|
|||||||
|
|
||||||
import { useDispatch } from 'react-redux';
|
import { useDispatch } from 'react-redux';
|
||||||
import { AES, enc } from 'crypto-js';
|
import { AES, enc } from 'crypto-js';
|
||||||
import { LocalWallet, USDC_DENOM, type Subaccount } from '@dydxprotocol/v4-client-js';
|
import { LocalWallet, type Subaccount } from '@dydxprotocol/v4-client-js';
|
||||||
|
|
||||||
import { OnboardingGuard, OnboardingState, type EvmDerivedAddresses } from '@/constants/account';
|
import { OnboardingGuard, OnboardingState, type EvmDerivedAddresses } from '@/constants/account';
|
||||||
import { DialogTypes } from '@/constants/dialogs';
|
import { DialogTypes } from '@/constants/dialogs';
|
||||||
@@ -130,16 +130,8 @@ const useAccountsContext = () => {
|
|||||||
// dYdX subaccounts
|
// dYdX subaccounts
|
||||||
const [dydxSubaccounts, setDydxSubaccounts] = useState<Subaccount[] | undefined>();
|
const [dydxSubaccounts, setDydxSubaccounts] = useState<Subaccount[] | undefined>();
|
||||||
|
|
||||||
const { getAccountBalance, getSubaccounts } = useMemo(
|
const { getSubaccounts } = useMemo(
|
||||||
() => ({
|
() => ({
|
||||||
getAccountBalance: async ({
|
|
||||||
dydxAddress,
|
|
||||||
denom = USDC_DENOM,
|
|
||||||
}: {
|
|
||||||
dydxAddress: DydxAddress;
|
|
||||||
denom?: string;
|
|
||||||
}) => await compositeClient?.validatorClient.get.getAccountBalance(dydxAddress, denom),
|
|
||||||
|
|
||||||
getSubaccounts: async ({ dydxAddress }: { dydxAddress: DydxAddress }) => {
|
getSubaccounts: async ({ dydxAddress }: { dydxAddress: DydxAddress }) => {
|
||||||
try {
|
try {
|
||||||
const response = await compositeClient?.indexerClient.account.getSubaccounts(dydxAddress);
|
const response = await compositeClient?.indexerClient.account.getSubaccounts(dydxAddress);
|
||||||
@@ -326,7 +318,6 @@ const useAccountsContext = () => {
|
|||||||
disconnect,
|
disconnect,
|
||||||
|
|
||||||
// dydxClient Account methods
|
// dydxClient Account methods
|
||||||
getAccountBalance,
|
|
||||||
getSubaccounts,
|
getSubaccounts,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -15,6 +15,8 @@ import type { ResolutionString } from 'public/tradingview/charting_library';
|
|||||||
|
|
||||||
import type { ConnectNetworkEvent, NetworkConfig } from '@/constants/abacus';
|
import type { ConnectNetworkEvent, NetworkConfig } from '@/constants/abacus';
|
||||||
import { type Candle, RESOLUTION_MAP } from '@/constants/candles';
|
import { type Candle, RESOLUTION_MAP } from '@/constants/candles';
|
||||||
|
import { ENVIRONMENT_CONFIG_MAP } from '@/constants/networks';
|
||||||
|
import { DydxChainAsset } from '@/constants/wallets';
|
||||||
|
|
||||||
import { getSelectedNetwork } from '@/state/appSelectors';
|
import { getSelectedNetwork } from '@/state/appSelectors';
|
||||||
|
|
||||||
@@ -36,6 +38,7 @@ const useDydxClientContext = () => {
|
|||||||
// ------ Network ------ //
|
// ------ Network ------ //
|
||||||
|
|
||||||
const selectedNetwork = useSelector(getSelectedNetwork);
|
const selectedNetwork = useSelector(getSelectedNetwork);
|
||||||
|
const tokensConfigs = ENVIRONMENT_CONFIG_MAP[selectedNetwork].tokens;
|
||||||
|
|
||||||
const [networkConfig, setNetworkConfig] = useState<NetworkConfig>();
|
const [networkConfig, setNetworkConfig] = useState<NetworkConfig>();
|
||||||
|
|
||||||
@@ -65,7 +68,14 @@ const useDydxClientContext = () => {
|
|||||||
new Network(
|
new Network(
|
||||||
selectedNetwork,
|
selectedNetwork,
|
||||||
new IndexerConfig(networkConfig.indexerUrl, networkConfig.websocketUrl),
|
new IndexerConfig(networkConfig.indexerUrl, networkConfig.websocketUrl),
|
||||||
new ValidatorConfig(networkConfig.validatorUrl, networkConfig.chainId, {
|
new ValidatorConfig(networkConfig.validatorUrl, networkConfig.chainId,
|
||||||
|
{
|
||||||
|
USDC_DENOM: tokensConfigs[DydxChainAsset.USDC].denom,
|
||||||
|
USDC_DECIMALS: tokensConfigs[DydxChainAsset.USDC].decimals,
|
||||||
|
USDC_GAS_DENOM: tokensConfigs[DydxChainAsset.USDC].gasDenom,
|
||||||
|
CHAINTOKEN_DENOM: tokensConfigs[DydxChainAsset.CHAINTOKEN].denom,
|
||||||
|
CHAINTOKEN_DECIMALS: tokensConfigs[DydxChainAsset.CHAINTOKEN].decimals,
|
||||||
|
}, {
|
||||||
broadcastPollIntervalMs: 3_000,
|
broadcastPollIntervalMs: 3_000,
|
||||||
broadcastTimeoutMs: 60_000,
|
broadcastTimeoutMs: 60_000,
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import { useCallback, useEffect } from 'react';
|
import { useCallback } from 'react';
|
||||||
import { useDispatch, useSelector } from 'react-redux';
|
import { useDispatch, useSelector } from 'react-redux';
|
||||||
|
|
||||||
import { DialogTypes } from '@/constants/dialogs';
|
|
||||||
import { LocalStorageKey } from '@/constants/localStorage';
|
import { LocalStorageKey } from '@/constants/localStorage';
|
||||||
import { DEFAULT_APP_ENVIRONMENT, DydxNetwork, ENVIRONMENT_CONFIG_MAP } from '@/constants/networks';
|
import { DEFAULT_APP_ENVIRONMENT, DydxNetwork, ENVIRONMENT_CONFIG_MAP } from '@/constants/networks';
|
||||||
|
|
||||||
@@ -9,7 +8,6 @@ import { useAccounts, useLocalStorage } from '@/hooks';
|
|||||||
|
|
||||||
import { setSelectedNetwork } from '@/state/app';
|
import { setSelectedNetwork } from '@/state/app';
|
||||||
import { getSelectedNetwork } from '@/state/appSelectors';
|
import { getSelectedNetwork } from '@/state/appSelectors';
|
||||||
import { openDialog } from '@/state/dialogs';
|
|
||||||
|
|
||||||
import { validateAgainstAvailableEnvironments } from '@/lib/network';
|
import { validateAgainstAvailableEnvironments } from '@/lib/network';
|
||||||
|
|
||||||
@@ -27,17 +25,6 @@ export const useSelectedNetwork = (): {
|
|||||||
validateFn: validateAgainstAvailableEnvironments,
|
validateFn: validateAgainstAvailableEnvironments,
|
||||||
});
|
});
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (
|
|
||||||
import.meta.env.MODE === 'production' &&
|
|
||||||
ENVIRONMENT_CONFIG_MAP[selectedNetwork].dydxChainId === 'dydx-testnet-4'
|
|
||||||
) {
|
|
||||||
dispatch(
|
|
||||||
openDialog({ type: DialogTypes.ExchangeOffline, dialogProps: { preventClose: true } })
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}, [selectedNetwork]);
|
|
||||||
|
|
||||||
const switchNetwork = useCallback(
|
const switchNetwork = useCallback(
|
||||||
(network: DydxNetwork) => {
|
(network: DydxNetwork) => {
|
||||||
disconnect();
|
disconnect();
|
||||||
|
|||||||
+22
-17
@@ -3,15 +3,10 @@ import { shallowEqual, useSelector, useDispatch } from 'react-redux';
|
|||||||
import type { Nullable } from '@dydxprotocol/v4-abacus';
|
import type { Nullable } from '@dydxprotocol/v4-abacus';
|
||||||
import Long from 'long';
|
import Long from 'long';
|
||||||
import type { IndexedTx } from '@cosmjs/stargate';
|
import type { IndexedTx } from '@cosmjs/stargate';
|
||||||
import type { EncodeObject, Coin } from '@cosmjs/proto-signing';
|
import type { EncodeObject } from '@cosmjs/proto-signing';
|
||||||
import { Method } from '@cosmjs/tendermint-rpc';
|
import { Method } from '@cosmjs/tendermint-rpc';
|
||||||
|
|
||||||
import {
|
import { type LocalWallet, SubaccountClient } from '@dydxprotocol/v4-client-js';
|
||||||
type LocalWallet,
|
|
||||||
SubaccountClient,
|
|
||||||
DYDX_DENOM,
|
|
||||||
USDC_DENOM,
|
|
||||||
} from '@dydxprotocol/v4-client-js';
|
|
||||||
|
|
||||||
import type {
|
import type {
|
||||||
AccountBalance,
|
AccountBalance,
|
||||||
@@ -34,6 +29,7 @@ import { MustBigNumber } from '@/lib/numbers';
|
|||||||
import { log } from '@/lib/telemetry';
|
import { log } from '@/lib/telemetry';
|
||||||
|
|
||||||
import { useAccounts } from './useAccounts';
|
import { useAccounts } from './useAccounts';
|
||||||
|
import { useTokenConfigs } from './useTokenConfigs';
|
||||||
import { useDydxClient } from './useDydxClient';
|
import { useDydxClient } from './useDydxClient';
|
||||||
|
|
||||||
type SubaccountContextType = ReturnType<typeof useSubaccountContext>;
|
type SubaccountContextType = ReturnType<typeof useSubaccountContext>;
|
||||||
@@ -52,6 +48,7 @@ export const useSubaccount = () => useContext(SubaccountContext);
|
|||||||
|
|
||||||
export const useSubaccountContext = ({ localDydxWallet }: { localDydxWallet?: LocalWallet }) => {
|
export const useSubaccountContext = ({ localDydxWallet }: { localDydxWallet?: LocalWallet }) => {
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
|
const { usdcDenom } = useTokenConfigs();
|
||||||
const { compositeClient, faucetClient } = useDydxClient();
|
const { compositeClient, faucetClient } = useDydxClient();
|
||||||
|
|
||||||
const { getFaucetFunds } = useMemo(
|
const { getFaucetFunds } = useMemo(
|
||||||
@@ -91,7 +88,7 @@ export const useSubaccountContext = ({ localDydxWallet }: { localDydxWallet?: Lo
|
|||||||
}: {
|
}: {
|
||||||
subaccountClient: SubaccountClient;
|
subaccountClient: SubaccountClient;
|
||||||
amount: number;
|
amount: number;
|
||||||
}) => await compositeClient?.withdrawFromSubaccount(subaccountClient, amount),
|
}) => await compositeClient?.withdrawFromSubaccount(subaccountClient, amount.toString()),
|
||||||
|
|
||||||
transferFromSubaccountToAddress: async ({
|
transferFromSubaccountToAddress: async ({
|
||||||
subaccountClient,
|
subaccountClient,
|
||||||
@@ -134,12 +131,21 @@ export const useSubaccountContext = ({ localDydxWallet }: { localDydxWallet?: Lo
|
|||||||
amount: number;
|
amount: number;
|
||||||
recipient: string;
|
recipient: string;
|
||||||
}) =>
|
}) =>
|
||||||
await compositeClient?.validatorClient.post.sendToken(
|
await compositeClient?.validatorClient.post.send(
|
||||||
subaccountClient,
|
subaccountClient.wallet,
|
||||||
recipient,
|
() =>
|
||||||
DYDX_DENOM,
|
new Promise((resolve) => {
|
||||||
Long.fromNumber(amount * QUANTUM_MULTIPLIER),
|
const msg = compositeClient?.sendTokenMessage(
|
||||||
|
subaccountClient.wallet,
|
||||||
|
amount.toString(),
|
||||||
|
recipient,
|
||||||
|
);
|
||||||
|
|
||||||
|
resolve([msg]);
|
||||||
|
}),
|
||||||
false,
|
false,
|
||||||
|
compositeClient?.validatorClient?.post.defaultDydxGasPrice,
|
||||||
|
undefined,
|
||||||
Method.BroadcastTxCommit
|
Method.BroadcastTxCommit
|
||||||
),
|
),
|
||||||
|
|
||||||
@@ -156,7 +162,7 @@ export const useSubaccountContext = ({ localDydxWallet }: { localDydxWallet?: Lo
|
|||||||
|
|
||||||
const transaction = JSON.parse(payload);
|
const transaction = JSON.parse(payload);
|
||||||
|
|
||||||
const msg = compositeClient.withdrawFromSubaccountMessage(subaccountClient, amount);
|
const msg = compositeClient.withdrawFromSubaccountMessage(subaccountClient, amount.toString());
|
||||||
const ibcMsg: EncodeObject = {
|
const ibcMsg: EncodeObject = {
|
||||||
typeUrl: transaction.msgTypeUrl,
|
typeUrl: transaction.msgTypeUrl,
|
||||||
value: transaction.msg,
|
value: transaction.msg,
|
||||||
@@ -210,7 +216,7 @@ export const useSubaccountContext = ({ localDydxWallet }: { localDydxWallet?: Lo
|
|||||||
);
|
);
|
||||||
|
|
||||||
const balances = useSelector(getBalances, shallowEqual);
|
const balances = useSelector(getBalances, shallowEqual);
|
||||||
const usdcCoinBalance = balances?.[USDC_DENOM];
|
const usdcCoinBalance = balances?.[usdcDenom];
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (usdcCoinBalance) {
|
if (usdcCoinBalance) {
|
||||||
@@ -247,8 +253,7 @@ export const useSubaccountContext = ({ localDydxWallet }: { localDydxWallet?: Lo
|
|||||||
if (!subaccountClient) {
|
if (!subaccountClient) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
return (await (coinDenom === usdcDenom
|
||||||
return (await (coinDenom === USDC_DENOM
|
|
||||||
? transferFromSubaccountToAddress
|
? transferFromSubaccountToAddress
|
||||||
: transferNativeToken)({ subaccountClient, amount, recipient })) as IndexedTx;
|
: transferNativeToken)({ subaccountClient, amount, recipient })) as IndexedTx;
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -0,0 +1,36 @@
|
|||||||
|
import { ENVIRONMENT_CONFIG_MAP } from '@/constants/networks';
|
||||||
|
import { DydxChainAsset } from '@/constants/wallets';
|
||||||
|
|
||||||
|
import { useSelectedNetwork } from '@/hooks';
|
||||||
|
|
||||||
|
export const useTokenConfigs = (): {
|
||||||
|
tokensConfigs: {
|
||||||
|
[DydxChainAsset.USDC]: {
|
||||||
|
denom: string;
|
||||||
|
name: string;
|
||||||
|
decimals: number;
|
||||||
|
gasDenom?: string;
|
||||||
|
},
|
||||||
|
[DydxChainAsset.CHAINTOKEN]: {
|
||||||
|
denom: string;
|
||||||
|
name: string;
|
||||||
|
decimals: number;
|
||||||
|
gasDenom?: string;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
usdcDenom: string;
|
||||||
|
usdcLabel: string;
|
||||||
|
chainTokenDenom: string;
|
||||||
|
chainTokenLabel: string;
|
||||||
|
} => {
|
||||||
|
const { selectedNetwork } = useSelectedNetwork();
|
||||||
|
const tokensConfigs = ENVIRONMENT_CONFIG_MAP[selectedNetwork].tokens;
|
||||||
|
|
||||||
|
return {
|
||||||
|
tokensConfigs,
|
||||||
|
usdcDenom: tokensConfigs[DydxChainAsset.USDC].denom,
|
||||||
|
usdcLabel: tokensConfigs[DydxChainAsset.USDC].name,
|
||||||
|
chainTokenDenom: tokensConfigs[DydxChainAsset.CHAINTOKEN].denom,
|
||||||
|
chainTokenLabel: tokensConfigs[DydxChainAsset.CHAINTOKEN].name,
|
||||||
|
};
|
||||||
|
};
|
||||||
@@ -1,6 +1,8 @@
|
|||||||
import { useCallback, useEffect, useState } from 'react';
|
import { useCallback, useEffect, useState } from 'react';
|
||||||
|
import { useSelector } from 'react-redux';
|
||||||
|
|
||||||
import { LocalStorageKey } from '@/constants/localStorage';
|
import { LocalStorageKey } from '@/constants/localStorage';
|
||||||
|
import { ENVIRONMENT_CONFIG_MAP } from '@/constants/networks';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
type DydxAddress,
|
type DydxAddress,
|
||||||
@@ -28,6 +30,8 @@ import {
|
|||||||
WalletType as CosmosWalletType,
|
WalletType as CosmosWalletType,
|
||||||
} from 'graz';
|
} from 'graz';
|
||||||
|
|
||||||
|
import { getSelectedNetwork } from '@/state/appSelectors';
|
||||||
|
|
||||||
import { resolveWagmiConnector } from '@/lib/wagmi';
|
import { resolveWagmiConnector } from '@/lib/wagmi';
|
||||||
import { getWalletConnection, parseWalletError } from '@/lib/wallet';
|
import { getWalletConnection, parseWalletError } from '@/lib/wallet';
|
||||||
import { log } from '@/lib/telemetry';
|
import { log } from '@/lib/telemetry';
|
||||||
@@ -84,6 +88,9 @@ export const useWalletConnection = () => {
|
|||||||
|
|
||||||
// Wallet connection
|
// Wallet connection
|
||||||
|
|
||||||
|
const selectedNetwork = useSelector(getSelectedNetwork);
|
||||||
|
const walletConnectConfig = ENVIRONMENT_CONFIG_MAP[selectedNetwork].wallets.walletconnect;
|
||||||
|
|
||||||
const { connectAsync: connectWagmi } =
|
const { connectAsync: connectWagmi } =
|
||||||
walletType && walletConnectionType
|
walletType && walletConnectionType
|
||||||
? useConnectWagmi({
|
? useConnectWagmi({
|
||||||
@@ -92,6 +99,7 @@ export const useWalletConnection = () => {
|
|||||||
walletConnection: {
|
walletConnection: {
|
||||||
type: walletConnectionType,
|
type: walletConnectionType,
|
||||||
},
|
},
|
||||||
|
walletConnectConfig,
|
||||||
}),
|
}),
|
||||||
})
|
})
|
||||||
: useConnectWagmi();
|
: useConnectWagmi();
|
||||||
@@ -127,6 +135,7 @@ export const useWalletConnection = () => {
|
|||||||
connector: resolveWagmiConnector({
|
connector: resolveWagmiConnector({
|
||||||
walletType,
|
walletType,
|
||||||
walletConnection,
|
walletConnection,
|
||||||
|
walletConnectConfig,
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -217,7 +226,7 @@ export const useWalletConnection = () => {
|
|||||||
evmAddressWagmi,
|
evmAddressWagmi,
|
||||||
signerWagmi,
|
signerWagmi,
|
||||||
publicClientWagmi,
|
publicClientWagmi,
|
||||||
|
|
||||||
// Wallet connection (Cosmos)
|
// Wallet connection (Cosmos)
|
||||||
dydxAddress,
|
dydxAddress,
|
||||||
dydxAddressGraz,
|
dydxAddressGraz,
|
||||||
|
|||||||
@@ -6,9 +6,10 @@ import { ButtonShape } 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 { AppRoute } from '@/constants/routes';
|
import { AppRoute } from '@/constants/routes';
|
||||||
import { useStringGetter } from '@/hooks';
|
|
||||||
import { LogoShortIcon, BellStrokeIcon } from '@/icons';
|
import { LogoShortIcon, BellStrokeIcon } from '@/icons';
|
||||||
|
|
||||||
|
import { useTokenConfigs, useStringGetter } from '@/hooks';
|
||||||
|
|
||||||
import { Icon, IconName } from '@/components/Icon';
|
import { Icon, IconName } from '@/components/Icon';
|
||||||
import { IconButton } from '@/components/IconButton';
|
import { IconButton } from '@/components/IconButton';
|
||||||
import { NavigationMenu } from '@/components/NavigationMenu';
|
import { NavigationMenu } from '@/components/NavigationMenu';
|
||||||
@@ -27,6 +28,7 @@ import { layoutMixins } from '@/styles/layoutMixins';
|
|||||||
export const HeaderDesktop = () => {
|
export const HeaderDesktop = () => {
|
||||||
const stringGetter = useStringGetter();
|
const stringGetter = useStringGetter();
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
|
const { chainTokenLabel } = useTokenConfigs();
|
||||||
|
|
||||||
const navItems = [
|
const navItems = [
|
||||||
{
|
{
|
||||||
@@ -43,9 +45,9 @@ export const HeaderDesktop = () => {
|
|||||||
href: AppRoute.Trade,
|
href: AppRoute.Trade,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: 'Dv4TNT',
|
value: chainTokenLabel,
|
||||||
label: 'Dv4TNT',
|
label: chainTokenLabel,
|
||||||
href: AppRoute.Rewards,
|
href: `/${chainTokenLabel}`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: 'PORTFOLIO',
|
value: 'PORTFOLIO',
|
||||||
@@ -78,13 +80,13 @@ export const HeaderDesktop = () => {
|
|||||||
value: 'TERMS_OF_USE',
|
value: 'TERMS_OF_USE',
|
||||||
slotBefore: <Icon iconName={IconName.File} />,
|
slotBefore: <Icon iconName={IconName.File} />,
|
||||||
label: stringGetter({ key: STRING_KEYS.TERMS_OF_USE }),
|
label: stringGetter({ key: STRING_KEYS.TERMS_OF_USE }),
|
||||||
href: 'https://dydx.exchange/terms',
|
href: AppRoute.Terms,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: 'PRIVACY_POLICY',
|
value: 'PRIVACY_POLICY',
|
||||||
slotBefore: <Icon iconName={IconName.Privacy} />,
|
slotBefore: <Icon iconName={IconName.Privacy} />,
|
||||||
label: stringGetter({ key: STRING_KEYS.PRIVACY_POLICY }),
|
label: stringGetter({ key: STRING_KEYS.PRIVACY_POLICY }),
|
||||||
href: 'https://dydx.exchange/privacy',
|
href: AppRoute.Privacy,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: 'HELP',
|
value: 'HELP',
|
||||||
|
|||||||
@@ -14,8 +14,6 @@ import {
|
|||||||
OrderSide,
|
OrderSide,
|
||||||
OrderTimeInForce,
|
OrderTimeInForce,
|
||||||
OrderExecution,
|
OrderExecution,
|
||||||
DYDX_DENOM,
|
|
||||||
GAS_PRICE_DYDX_DENOM,
|
|
||||||
} from '@dydxprotocol/v4-client-js';
|
} from '@dydxprotocol/v4-client-js';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@@ -66,16 +64,37 @@ class DydxChainTransactions implements AbacusDYDXChainTransactionsProtocol {
|
|||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
try {
|
try {
|
||||||
const parsedParams = paramsInJson ? JSON.parse(paramsInJson) : {};
|
const parsedParams = paramsInJson ? JSON.parse(paramsInJson) : {};
|
||||||
const { indexerUrl, websocketUrl, validatorUrl, chainId } = parsedParams;
|
const {
|
||||||
|
indexerUrl,
|
||||||
|
websocketUrl,
|
||||||
|
validatorUrl,
|
||||||
|
chainId,
|
||||||
|
USDC_DENOM,
|
||||||
|
USDC_DECIMALS,
|
||||||
|
USDC_GAS_DENOM,
|
||||||
|
CHAINTOKEN_DENOM,
|
||||||
|
CHAINTOKEN_DECIMALS,
|
||||||
|
} = parsedParams;
|
||||||
|
|
||||||
const compositeClient = await CompositeClient.connect(
|
const compositeClient = await CompositeClient.connect(
|
||||||
new Network(
|
new Network(
|
||||||
chainId,
|
chainId,
|
||||||
new IndexerConfig(indexerUrl, websocketUrl),
|
new IndexerConfig(indexerUrl, websocketUrl),
|
||||||
new ValidatorConfig(validatorUrl, chainId, {
|
new ValidatorConfig(
|
||||||
broadcastPollIntervalMs: 3_000,
|
validatorUrl,
|
||||||
broadcastTimeoutMs: 60_000,
|
chainId,
|
||||||
})
|
{
|
||||||
|
USDC_DENOM,
|
||||||
|
USDC_DECIMALS,
|
||||||
|
USDC_GAS_DENOM,
|
||||||
|
CHAINTOKEN_DENOM,
|
||||||
|
CHAINTOKEN_DECIMALS,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
broadcastPollIntervalMs: 3_000,
|
||||||
|
broadcastTimeoutMs: 60_000,
|
||||||
|
}
|
||||||
|
)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -204,13 +223,13 @@ class DydxChainTransactions implements AbacusDYDXChainTransactionsProtocol {
|
|||||||
params ?? {};
|
params ?? {};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const tx = await this.compositeClient?.cancelOrder(
|
const tx = await this.compositeClient?.cancelRawOrder(
|
||||||
new SubaccountClient(this.localWallet, subaccountNumber),
|
new SubaccountClient(this.localWallet, subaccountNumber),
|
||||||
clientId,
|
clientId,
|
||||||
orderFlags,
|
orderFlags,
|
||||||
clobPairId,
|
clobPairId,
|
||||||
goodTilBlock ?? undefined,
|
goodTilBlock || undefined,
|
||||||
goodTilBlockTime ?? undefined
|
goodTilBlockTime || undefined,
|
||||||
);
|
);
|
||||||
|
|
||||||
const parsedTx = this.parseToPrimitives(tx);
|
const parsedTx = this.parseToPrimitives(tx);
|
||||||
@@ -273,16 +292,18 @@ class DydxChainTransactions implements AbacusDYDXChainTransactionsProtocol {
|
|||||||
this.localWallet,
|
this.localWallet,
|
||||||
() =>
|
() =>
|
||||||
new Promise((resolve) => {
|
new Promise((resolve) => {
|
||||||
const msg = compositeClient?.validatorClient.post.composer.composeMsgSendToken(
|
if (!this.localWallet) {
|
||||||
subaccountClient.address,
|
throw new Error('Missing compositeClient or localWallet');
|
||||||
|
}
|
||||||
|
const msg = compositeClient?.sendTokenMessage(
|
||||||
|
this.localWallet,
|
||||||
|
amount,
|
||||||
recipient,
|
recipient,
|
||||||
DYDX_DENOM,
|
|
||||||
Long.fromNumber(amount * QUANTUM_MULTIPLIER)
|
|
||||||
);
|
);
|
||||||
|
|
||||||
resolve([msg]);
|
resolve([msg]);
|
||||||
}),
|
}),
|
||||||
GAS_PRICE_DYDX_DENOM
|
this.compositeClient?.validatorClient?.post.defaultDydxGasPrice,
|
||||||
);
|
);
|
||||||
|
|
||||||
const parsedTx = this.parseToPrimitives(tx);
|
const parsedTx = this.parseToPrimitives(tx);
|
||||||
|
|||||||
+33
-13
@@ -95,15 +95,28 @@ const injectedConnectorOptions = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const walletconnect2ConnectorOptions: ConstructorParameters<typeof WalletConnectConnector>[0] = {
|
type WalletConnectConfig = {
|
||||||
|
client: {
|
||||||
|
name: string;
|
||||||
|
description: string;
|
||||||
|
iconUrl: string;
|
||||||
|
};
|
||||||
|
v2: {
|
||||||
|
projectId: string;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const getWalletconnect2ConnectorOptions = (
|
||||||
|
config: WalletConnectConfig
|
||||||
|
): ConstructorParameters<typeof WalletConnectConnector>[0] => ({
|
||||||
chains,
|
chains,
|
||||||
options: {
|
options: {
|
||||||
projectId: import.meta.env.VITE_WALLETCONNECT2_PROJECT_ID,
|
projectId: config.v2.projectId,
|
||||||
metadata: {
|
metadata: {
|
||||||
name: 'dYdX',
|
name: config.client.name,
|
||||||
description: '',
|
description: config.client.description,
|
||||||
url: import.meta.env.VITE_BASE_URL,
|
url: import.meta.env.VITE_BASE_URL,
|
||||||
icons: [`${import.meta.env.VITE_BASE_URL}/cbw-image.png}`],
|
icons: [config.client.iconUrl],
|
||||||
},
|
},
|
||||||
showQrModal: true,
|
showQrModal: true,
|
||||||
qrModalOptions: {
|
qrModalOptions: {
|
||||||
@@ -115,9 +128,9 @@ const walletconnect2ConnectorOptions: ConstructorParameters<typeof WalletConnect
|
|||||||
explorerRecommendedWalletIds: WALLET_CONNECT_EXPLORER_RECOMMENDED_IDS,
|
explorerRecommendedWalletIds: WALLET_CONNECT_EXPLORER_RECOMMENDED_IDS,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
});
|
||||||
|
|
||||||
const connectors = [
|
const getConnectors = (walletConnectConfig: WalletConnectConfig) => [
|
||||||
new MetaMaskConnector({
|
new MetaMaskConnector({
|
||||||
chains,
|
chains,
|
||||||
options: {
|
options: {
|
||||||
@@ -131,7 +144,7 @@ const connectors = [
|
|||||||
reloadOnDisconnect: false,
|
reloadOnDisconnect: false,
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
new WalletConnectConnector(walletconnect2ConnectorOptions),
|
new WalletConnectConnector(getWalletconnect2ConnectorOptions(walletConnectConfig)),
|
||||||
new InjectedConnector(injectedConnectorOptions),
|
new InjectedConnector(injectedConnectorOptions),
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -153,27 +166,34 @@ const createInjectedConnectorWithProvider = (provider: ExternalProvider) =>
|
|||||||
provider as unknown as Awaited<ReturnType<InjectedConnector['getProvider']>>;
|
provider as unknown as Awaited<ReturnType<InjectedConnector['getProvider']>>;
|
||||||
})(injectedConnectorOptions) as InjectedConnector;
|
})(injectedConnectorOptions) as InjectedConnector;
|
||||||
|
|
||||||
const createWalletConnect2ConnectorWithId = (walletconnect2Id: string) =>
|
const createWalletConnect2ConnectorWithId = (
|
||||||
new WalletConnectConnector({
|
walletconnectId: string,
|
||||||
|
walletConnectConfig: WalletConnectConfig
|
||||||
|
) => {
|
||||||
|
const walletconnect2ConnectorOptions = getWalletconnect2ConnectorOptions(walletConnectConfig);
|
||||||
|
return new WalletConnectConnector({
|
||||||
...walletconnect2ConnectorOptions,
|
...walletconnect2ConnectorOptions,
|
||||||
options: {
|
options: {
|
||||||
...walletconnect2ConnectorOptions.options,
|
...walletconnect2ConnectorOptions.options,
|
||||||
qrModalOptions: {
|
qrModalOptions: {
|
||||||
...walletconnect2ConnectorOptions.options.qrModalOptions,
|
...walletconnect2ConnectorOptions.options.qrModalOptions,
|
||||||
explorerRecommendedWalletIds: [walletconnect2Id],
|
explorerRecommendedWalletIds: [walletconnectId],
|
||||||
explorerExcludedWalletIds: 'ALL',
|
explorerExcludedWalletIds: 'ALL',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
};
|
||||||
|
|
||||||
// Custom connector from wallet selection
|
// Custom connector from wallet selection
|
||||||
|
|
||||||
export const resolveWagmiConnector = ({
|
export const resolveWagmiConnector = ({
|
||||||
walletType,
|
walletType,
|
||||||
walletConnection,
|
walletConnection,
|
||||||
|
walletConnectConfig,
|
||||||
}: {
|
}: {
|
||||||
walletType: WalletType;
|
walletType: WalletType;
|
||||||
walletConnection: WalletConnection;
|
walletConnection: WalletConnection;
|
||||||
|
walletConnectConfig: WalletConnectConfig;
|
||||||
}) => {
|
}) => {
|
||||||
const walletConfig = wallets[walletType];
|
const walletConfig = wallets[walletType];
|
||||||
const walletConnectionConfig = walletConnectionTypes[walletConnection.type];
|
const walletConnectionConfig = walletConnectionTypes[walletConnection.type];
|
||||||
@@ -181,6 +201,6 @@ export const resolveWagmiConnector = ({
|
|||||||
return walletConnection.type === WalletConnectionType.InjectedEip1193 && walletConnection.provider
|
return walletConnection.type === WalletConnectionType.InjectedEip1193 && walletConnection.provider
|
||||||
? createInjectedConnectorWithProvider(walletConnection.provider)
|
? createInjectedConnectorWithProvider(walletConnection.provider)
|
||||||
: walletConnection.type === WalletConnectionType.WalletConnect2 && walletConfig.walletconnect2Id
|
: walletConnection.type === WalletConnectionType.WalletConnect2 && walletConfig.walletconnect2Id
|
||||||
? createWalletConnect2ConnectorWithId(walletConfig.walletconnect2Id)
|
? createWalletConnect2ConnectorWithId(walletConfig.walletconnect2Id, walletConnectConfig)
|
||||||
: connectors.find(({ id }: { id: string }) => id === walletConnectionConfig.wagmiConnectorId);
|
: getConnectors(walletConnectConfig).find(({ id }: { id: string }) => id === walletConnectionConfig.wagmiConnectorId);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
import styled, { AnyStyledComponent } from 'styled-components';
|
||||||
|
|
||||||
|
import { articleMixins } from '@/styles/articleMixins';
|
||||||
|
|
||||||
|
export const PrivacyPolicyPage = () => (
|
||||||
|
<Styled.Article>
|
||||||
|
<header>
|
||||||
|
<h1>Privacy Policy</h1>
|
||||||
|
</header>
|
||||||
|
</Styled.Article>
|
||||||
|
);
|
||||||
|
|
||||||
|
const Styled: Record<string, AnyStyledComponent> = {};
|
||||||
|
|
||||||
|
Styled.Article = styled.article`
|
||||||
|
${articleMixins.article}
|
||||||
|
`;
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
import styled, { AnyStyledComponent } from 'styled-components';
|
||||||
|
|
||||||
|
import { articleMixins } from '@/styles/articleMixins';
|
||||||
|
|
||||||
|
export const TermsOfUsePage = () => (
|
||||||
|
<Styled.Article>
|
||||||
|
<header>
|
||||||
|
<h1>Terms of Use</h1>
|
||||||
|
</header>
|
||||||
|
</Styled.Article>
|
||||||
|
);
|
||||||
|
|
||||||
|
const Styled: Record<string, AnyStyledComponent> = {};
|
||||||
|
|
||||||
|
Styled.Article = styled.article`
|
||||||
|
${articleMixins.article}
|
||||||
|
`;
|
||||||
@@ -3,7 +3,7 @@ import styled, { AnyStyledComponent } from 'styled-components';
|
|||||||
import { shallowEqual, useDispatch, useSelector } from 'react-redux';
|
import { shallowEqual, useDispatch, useSelector } from 'react-redux';
|
||||||
|
|
||||||
import { layoutMixins } from '@/styles/layoutMixins';
|
import { layoutMixins } from '@/styles/layoutMixins';
|
||||||
import { useAccountBalance, useAccounts, useStringGetter } from '@/hooks';
|
import { useAccountBalance, useAccounts, useTokenConfigs, useStringGetter } from '@/hooks';
|
||||||
|
|
||||||
import { ButtonAction, ButtonSize } from '@/constants/buttons';
|
import { ButtonAction, ButtonSize } from '@/constants/buttons';
|
||||||
import { DialogTypes } from '@/constants/dialogs';
|
import { DialogTypes } from '@/constants/dialogs';
|
||||||
@@ -30,6 +30,7 @@ export const DYDXBalancePanel = () => {
|
|||||||
const { walletType } = useAccounts();
|
const { walletType } = useAccounts();
|
||||||
const canAccountTrade = useSelector(calculateCanAccountTrade, shallowEqual);
|
const canAccountTrade = useSelector(calculateCanAccountTrade, shallowEqual);
|
||||||
const { nativeTokenBalance, nativeStakingBalance } = useAccountBalance();
|
const { nativeTokenBalance, nativeStakingBalance } = useAccountBalance();
|
||||||
|
const { chainTokenLabel } = useTokenConfigs();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Panel
|
<Panel
|
||||||
@@ -37,7 +38,7 @@ export const DYDXBalancePanel = () => {
|
|||||||
<Styled.Header>
|
<Styled.Header>
|
||||||
<Styled.Title>
|
<Styled.Title>
|
||||||
{/* <AssetIcon symbol="DYDX" /> */}
|
{/* <AssetIcon symbol="DYDX" /> */}
|
||||||
Dv4TNT
|
{chainTokenLabel}
|
||||||
</Styled.Title>
|
</Styled.Title>
|
||||||
<Styled.ReceiveAndTransferButtons>
|
<Styled.ReceiveAndTransferButtons>
|
||||||
{!canAccountTrade ? (
|
{!canAccountTrade ? (
|
||||||
@@ -106,7 +107,13 @@ export const DYDXBalancePanel = () => {
|
|||||||
{
|
{
|
||||||
key: 'totalBalance',
|
key: 'totalBalance',
|
||||||
label: 'Total balance',
|
label: 'Total balance',
|
||||||
value: <Output type={OutputType.Asset} value={nativeTokenBalance + nativeStakingBalance} tag="Dv4TNT" />,
|
value: (
|
||||||
|
<Output
|
||||||
|
type={OutputType.Asset}
|
||||||
|
value={nativeTokenBalance + nativeStakingBalance}
|
||||||
|
tag={chainTokenLabel}
|
||||||
|
/>
|
||||||
|
),
|
||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
@@ -174,7 +181,6 @@ Styled.WalletAndStakedBalance = styled(Details)`
|
|||||||
grid-template-columns: 1fr 1fr;
|
grid-template-columns: 1fr 1fr;
|
||||||
gap: 0.5rem;
|
gap: 0.5rem;
|
||||||
|
|
||||||
|
|
||||||
> div {
|
> div {
|
||||||
gap: 1rem;
|
gap: 1rem;
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,8 @@ export const dialogsSlice = createSlice({
|
|||||||
initialState,
|
initialState,
|
||||||
reducers: {
|
reducers: {
|
||||||
openDialog: (state: DialogsState, action: PayloadAction<DialogInfo<DialogTypes>>) => {
|
openDialog: (state: DialogsState, action: PayloadAction<DialogInfo<DialogTypes>>) => {
|
||||||
|
if (state.activeDialog?.type === action.payload.type) return;
|
||||||
|
|
||||||
if (state.activeDialog) {
|
if (state.activeDialog) {
|
||||||
state.dialogQueue.push(action.payload);
|
state.dialogQueue.push(action.payload);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -0,0 +1,53 @@
|
|||||||
|
import {
|
||||||
|
css,
|
||||||
|
type FlattenInterpolation,
|
||||||
|
type FlattenSimpleInterpolation,
|
||||||
|
type ThemeProps,
|
||||||
|
} from 'styled-components';
|
||||||
|
|
||||||
|
export const articleMixins: Record<
|
||||||
|
string,
|
||||||
|
FlattenSimpleInterpolation | FlattenInterpolation<ThemeProps<any>>
|
||||||
|
> = {
|
||||||
|
article: css`
|
||||||
|
padding: 2rem;
|
||||||
|
overflow-wrap: break-word;
|
||||||
|
user-select: text;
|
||||||
|
margin: 0 auto;
|
||||||
|
width: 60rem;
|
||||||
|
max-width: 100vw;
|
||||||
|
|
||||||
|
header {
|
||||||
|
color: var(--color-text-0);
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font: var(--font-extra-book);
|
||||||
|
color: var(--color-text-2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
font: var(--font-large-book);
|
||||||
|
color: var(--color-text-2);
|
||||||
|
padding: 0.5rem 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
h3,
|
||||||
|
strong {
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
strong {
|
||||||
|
color: var(--color-text-2);
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
padding: 0.5rem 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
padding: 0.5rem 1rem;
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
};
|
||||||
@@ -75,16 +75,14 @@ export const AccountInfoConnectedState = () => {
|
|||||||
<Styled.Header>
|
<Styled.Header>
|
||||||
<span>{stringGetter({ key: STRING_KEYS.ACCOUNT })}</span>
|
<span>{stringGetter({ key: STRING_KEYS.ACCOUNT })}</span>
|
||||||
<Styled.TransferButtons>
|
<Styled.TransferButtons>
|
||||||
{import.meta.env.MODE !== 'production' && (
|
<Styled.Button
|
||||||
<Styled.Button
|
state={{ isDisabled: !dydxAccounts }}
|
||||||
state={{ isDisabled: !dydxAccounts }}
|
onClick={() => dispatch(openDialog({ type: DialogTypes.Withdraw }))}
|
||||||
onClick={() => dispatch(openDialog({ type: DialogTypes.Withdraw }))}
|
shape={ButtonShape.Pill}
|
||||||
shape={ButtonShape.Pill}
|
size={ButtonSize.XSmall}
|
||||||
size={ButtonSize.XSmall}
|
>
|
||||||
>
|
{stringGetter({ key: STRING_KEYS.WITHDRAW })}
|
||||||
{stringGetter({ key: STRING_KEYS.WITHDRAW })}
|
</Styled.Button>
|
||||||
</Styled.Button>
|
|
||||||
)}
|
|
||||||
<Styled.Button
|
<Styled.Button
|
||||||
state={{ isDisabled: !dydxAccounts }}
|
state={{ isDisabled: !dydxAccounts }}
|
||||||
onClick={() => dispatch(openDialog({ type: DialogTypes.Deposit }))}
|
onClick={() => dispatch(openDialog({ type: DialogTypes.Deposit }))}
|
||||||
|
|||||||
@@ -32,12 +32,9 @@ export const DepositDialog = ({ setIsOpen }: ElementProps) => {
|
|||||||
>
|
>
|
||||||
<Styled.Content>
|
<Styled.Content>
|
||||||
{showTestDeposit ? <TestnetDepositForm onDeposit={closeDialog} /> : <DepositForm />}
|
{showTestDeposit ? <TestnetDepositForm onDeposit={closeDialog} /> : <DepositForm />}
|
||||||
{/* TODO TRCL-1693 - uncomment when deposit form is ready */}
|
<Styled.TextToggle onClick={() => setShowTestDeposit(!showTestDeposit)}>
|
||||||
{import.meta.env.MODE !== 'production' && (
|
{showTestDeposit ? 'Show deposit form (Under Construction)' : 'Show test faucet'}
|
||||||
<Styled.TextToggle onClick={() => setShowTestDeposit(!showTestDeposit)}>
|
</Styled.TextToggle>
|
||||||
{showTestDeposit ? 'Show deposit form (Under Construction)' : 'Show test faucet'}
|
|
||||||
</Styled.TextToggle>
|
|
||||||
)}
|
|
||||||
</Styled.Content>
|
</Styled.Content>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -5,8 +5,6 @@ import { shallowEqual, useDispatch, useSelector } from 'react-redux';
|
|||||||
import { AbacusApiStatus } from '@/constants/abacus';
|
import { AbacusApiStatus } from '@/constants/abacus';
|
||||||
import { DialogTypes } from '@/constants/dialogs';
|
import { DialogTypes } from '@/constants/dialogs';
|
||||||
import { STRING_KEYS } from '@/constants/localization';
|
import { STRING_KEYS } from '@/constants/localization';
|
||||||
import { ENVIRONMENT_CONFIG_MAP } from '@/constants/networks';
|
|
||||||
import { UNICODE } from '@/constants/unicode';
|
|
||||||
|
|
||||||
import { useApiState, useStringGetter } from '@/hooks';
|
import { useApiState, useStringGetter } from '@/hooks';
|
||||||
import { layoutMixins } from '@/styles/layoutMixins';
|
import { layoutMixins } from '@/styles/layoutMixins';
|
||||||
@@ -32,16 +30,8 @@ export const ExchangeOfflineDialog = ({ preventClose, setIsOpen }: ElementProps)
|
|||||||
const selectedNetwork = useSelector(getSelectedNetwork);
|
const selectedNetwork = useSelector(getSelectedNetwork);
|
||||||
const activeDialog = useSelector(getActiveDialog, shallowEqual);
|
const activeDialog = useSelector(getActiveDialog, shallowEqual);
|
||||||
|
|
||||||
const showOfflineMessage =
|
|
||||||
import.meta.env.MODE === 'production' &&
|
|
||||||
ENVIRONMENT_CONFIG_MAP[selectedNetwork].dydxChainId === 'dydx-testnet-4';
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (
|
if (activeDialog?.type === DialogTypes.ExchangeOffline && status === AbacusApiStatus.NORMAL) {
|
||||||
activeDialog?.type === DialogTypes.ExchangeOffline &&
|
|
||||||
status === AbacusApiStatus.NORMAL &&
|
|
||||||
!showOfflineMessage
|
|
||||||
) {
|
|
||||||
dispatch(closeDialog());
|
dispatch(closeDialog());
|
||||||
}
|
}
|
||||||
}, [status, selectedNetwork]);
|
}, [status, selectedNetwork]);
|
||||||
@@ -54,16 +44,7 @@ export const ExchangeOfflineDialog = ({ preventClose, setIsOpen }: ElementProps)
|
|||||||
title={stringGetter({ key: STRING_KEYS.UNAVAILABLE })}
|
title={stringGetter({ key: STRING_KEYS.UNAVAILABLE })}
|
||||||
>
|
>
|
||||||
<Styled.Content>
|
<Styled.Content>
|
||||||
{showOfflineMessage ? (
|
<p>{statusErrorMessage}</p>
|
||||||
<>
|
|
||||||
<p>Testnet is currently offline. Please check back!</p>
|
|
||||||
<Styled.Link href="https://v4-teacher.vercel.app/testnets/schedule">
|
|
||||||
{stringGetter({ key: STRING_KEYS.LEARN_MORE })} {UNICODE.ARROW_RIGHT}
|
|
||||||
</Styled.Link>
|
|
||||||
</>
|
|
||||||
) : (
|
|
||||||
<p>{statusErrorMessage}</p>
|
|
||||||
)}
|
|
||||||
{import.meta.env.MODE !== 'production' && <NetworkSelectMenu />}
|
{import.meta.env.MODE !== 'production' && <NetworkSelectMenu />}
|
||||||
</Styled.Content>
|
</Styled.Content>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ export const OnboardingDialog = ({ setIsOpen }: ElementProps) => {
|
|||||||
const stringGetter = useStringGetter();
|
const stringGetter = useStringGetter();
|
||||||
const { isMobile } = useBreakpoints();
|
const { isMobile } = useBreakpoints();
|
||||||
|
|
||||||
const { walletType } = useAccounts();
|
const { disconnect, walletType } = useAccounts();
|
||||||
|
|
||||||
const currentOnboardingStep = useSelector(calculateOnboardingStep);
|
const currentOnboardingStep = useSelector(calculateOnboardingStep);
|
||||||
|
|
||||||
@@ -45,10 +45,17 @@ export const OnboardingDialog = ({ setIsOpen }: ElementProps) => {
|
|||||||
if (!currentOnboardingStep) setIsOpen?.(false);
|
if (!currentOnboardingStep) setIsOpen?.(false);
|
||||||
}, [currentOnboardingStep]);
|
}, [currentOnboardingStep]);
|
||||||
|
|
||||||
|
const setIsOpenFromDialog = (open: boolean) => {
|
||||||
|
if (!open && currentOnboardingStep === OnboardingSteps.AcknowledgeTerms) {
|
||||||
|
disconnect();
|
||||||
|
}
|
||||||
|
setIsOpen?.(open);
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Styled.Dialog
|
<Styled.Dialog
|
||||||
isOpen={Boolean(currentOnboardingStep)}
|
isOpen={Boolean(currentOnboardingStep)}
|
||||||
setIsOpen={setIsOpen}
|
setIsOpen={setIsOpenFromDialog}
|
||||||
{...(currentOnboardingStep &&
|
{...(currentOnboardingStep &&
|
||||||
{
|
{
|
||||||
[OnboardingSteps.ChooseWallet]: {
|
[OnboardingSteps.ChooseWallet]: {
|
||||||
@@ -87,10 +94,10 @@ export const OnboardingDialog = ({ setIsOpen }: ElementProps) => {
|
|||||||
title: stringGetter({ key: STRING_KEYS.ACKNOWLEDGE_TERMS }),
|
title: stringGetter({ key: STRING_KEYS.ACKNOWLEDGE_TERMS }),
|
||||||
children: (
|
children: (
|
||||||
<Styled.Content>
|
<Styled.Content>
|
||||||
<AcknowledgeTerms />
|
<AcknowledgeTerms onClose={() => setIsOpenFromDialog?.(false)} />
|
||||||
</Styled.Content>
|
</Styled.Content>
|
||||||
),
|
),
|
||||||
width: '20rem',
|
width: '30rem',
|
||||||
},
|
},
|
||||||
[OnboardingSteps.DepositFunds]: {
|
[OnboardingSteps.DepositFunds]: {
|
||||||
title: stringGetter({ key: STRING_KEYS.DEPOSIT }),
|
title: stringGetter({ key: STRING_KEYS.DEPOSIT }),
|
||||||
|
|||||||
@@ -2,17 +2,21 @@ import styled, { type AnyStyledComponent } from 'styled-components';
|
|||||||
|
|
||||||
import { useAccounts, useStringGetter } from '@/hooks';
|
import { useAccounts, useStringGetter } from '@/hooks';
|
||||||
|
|
||||||
|
import { AppRoute } from '@/constants/routes';
|
||||||
import { STRING_KEYS } from '@/constants/localization';
|
import { STRING_KEYS } from '@/constants/localization';
|
||||||
import { ButtonAction } from '@/constants/buttons';
|
import { ButtonAction } from '@/constants/buttons';
|
||||||
|
|
||||||
|
import { layoutMixins } from '@/styles/layoutMixins';
|
||||||
|
|
||||||
import { Button } from '@/components/Button';
|
import { Button } from '@/components/Button';
|
||||||
import { Link } from '@/components/Link';
|
import { Link } from '@/components/Link';
|
||||||
|
|
||||||
type ElementProps = {
|
type ElementProps = {
|
||||||
|
onClose?: () => void;
|
||||||
onContinue?: () => void;
|
onContinue?: () => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const AcknowledgeTerms = ({ onContinue }: ElementProps) => {
|
export const AcknowledgeTerms = ({ onClose, onContinue }: ElementProps) => {
|
||||||
const stringGetter = useStringGetter();
|
const stringGetter = useStringGetter();
|
||||||
|
|
||||||
const { saveHasAcknowledgedTerms } = useAccounts();
|
const { saveHasAcknowledgedTerms } = useAccounts();
|
||||||
@@ -24,26 +28,40 @@ export const AcknowledgeTerms = ({ onContinue }: ElementProps) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<span>
|
<p>
|
||||||
{stringGetter({
|
{stringGetter({
|
||||||
key: STRING_KEYS.LEGAL_UPDATES_DESCRIPTION,
|
key: STRING_KEYS.TOS_TITLE,
|
||||||
params: {
|
params: {
|
||||||
TOU: (
|
TERMS_LINK: (
|
||||||
<Styled.Link href="https://dydx.exchange/v4-terms">
|
<Styled.Link href={`/#${AppRoute.Terms}`}>
|
||||||
{stringGetter({ key: STRING_KEYS.TERMS_OF_USE })}
|
{stringGetter({ key: STRING_KEYS.TERMS_OF_USE })}
|
||||||
</Styled.Link>
|
</Styled.Link>
|
||||||
),
|
),
|
||||||
PRIVACY_POLICY: (
|
PRIVACY_POLICY_LINK: (
|
||||||
<Styled.Link href="https://dydx.exchange/privacy">
|
<Styled.Link href={`/#${AppRoute.Privacy}`}>
|
||||||
{stringGetter({ key: STRING_KEYS.PRIVACY_POLICY })}
|
{stringGetter({ key: STRING_KEYS.PRIVACY_POLICY })}
|
||||||
</Styled.Link>
|
</Styled.Link>
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
})}
|
})}
|
||||||
</span>
|
</p>
|
||||||
<Button onClick={onAcknowledgement} action={ButtonAction.Primary}>
|
<Styled.TOS>
|
||||||
{stringGetter({ key: STRING_KEYS.I_AGREE })}
|
<ul>
|
||||||
</Button>
|
<li>{stringGetter({ key: STRING_KEYS.TOS_LINE1 })}</li>
|
||||||
|
<li>{stringGetter({ key: STRING_KEYS.TOS_LINE2 })}</li>
|
||||||
|
<li>{stringGetter({ key: STRING_KEYS.TOS_LINE3 })}</li>
|
||||||
|
<li>{stringGetter({ key: STRING_KEYS.TOS_LINE4 })}</li>
|
||||||
|
<li>{stringGetter({ key: STRING_KEYS.TOS_LINE5 })}</li>
|
||||||
|
</ul>
|
||||||
|
</Styled.TOS>
|
||||||
|
<Styled.Row>
|
||||||
|
<Styled.Button onClick={onClose} action={ButtonAction.Base}>
|
||||||
|
{stringGetter({ key: STRING_KEYS.CLOSE })}
|
||||||
|
</Styled.Button>
|
||||||
|
<Styled.Button onClick={onAcknowledgement} action={ButtonAction.Primary}>
|
||||||
|
{stringGetter({ key: STRING_KEYS.I_AGREE })}
|
||||||
|
</Styled.Button>
|
||||||
|
</Styled.Row>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
@@ -58,3 +76,23 @@ Styled.Link = styled(Link)`
|
|||||||
color: var(--color-accent);
|
color: var(--color-accent);
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
Styled.TOS = styled.section`
|
||||||
|
background-color: var(--color-layer-4);
|
||||||
|
padding: 1rem 1rem 1rem 2rem;
|
||||||
|
border-radius: 0.875rem;
|
||||||
|
> ul {
|
||||||
|
${layoutMixins.column};
|
||||||
|
gap: 1rem;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
Styled.Row = styled.div`
|
||||||
|
${layoutMixins.row};
|
||||||
|
|
||||||
|
gap: 1rem;
|
||||||
|
`;
|
||||||
|
|
||||||
|
Styled.Button = styled(Button)`
|
||||||
|
flex-grow: 1;
|
||||||
|
`;
|
||||||
|
|||||||
@@ -264,7 +264,6 @@ const Styled: Record<string, AnyStyledComponent> = {};
|
|||||||
|
|
||||||
Styled.StatusCardsContainer = styled.div`
|
Styled.StatusCardsContainer = styled.div`
|
||||||
display: grid;
|
display: grid;
|
||||||
margin-top: 1rem;
|
|
||||||
gap: 1rem;
|
gap: 1rem;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import { DydxChainAsset } from '@/constants/wallets';
|
|||||||
|
|
||||||
import { formMixins } from '@/styles/formMixins';
|
import { formMixins } from '@/styles/formMixins';
|
||||||
import { layoutMixins } from '@/styles/layoutMixins';
|
import { layoutMixins } from '@/styles/layoutMixins';
|
||||||
import { useAccounts, useStringGetter } from '@/hooks';
|
import { useAccounts, useTokenConfigs, useStringGetter } from '@/hooks';
|
||||||
|
|
||||||
import { AssetIcon } from '@/components/AssetIcon';
|
import { AssetIcon } from '@/components/AssetIcon';
|
||||||
import { CopyButton } from '@/components/CopyButton';
|
import { CopyButton } from '@/components/CopyButton';
|
||||||
@@ -24,9 +24,10 @@ type ElementProps = {
|
|||||||
setIsOpen: (open: boolean) => void;
|
setIsOpen: (open: boolean) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const ReceiveDialog = ({ selectedAsset = DydxChainAsset.DYDX, setIsOpen }: ElementProps) => {
|
export const ReceiveDialog = ({ selectedAsset = DydxChainAsset.CHAINTOKEN, setIsOpen }: ElementProps) => {
|
||||||
const stringGetter = useStringGetter();
|
const stringGetter = useStringGetter();
|
||||||
const { dydxAddress } = useAccounts();
|
const { dydxAddress } = useAccounts();
|
||||||
|
const { chainTokenLabel, usdcLabel } = useTokenConfigs();
|
||||||
|
|
||||||
const [asset, setAsset] = useState(selectedAsset);
|
const [asset, setAsset] = useState(selectedAsset);
|
||||||
|
|
||||||
@@ -35,16 +36,17 @@ export const ReceiveDialog = ({ selectedAsset = DydxChainAsset.DYDX, setIsOpen }
|
|||||||
value: DydxChainAsset.USDC,
|
value: DydxChainAsset.USDC,
|
||||||
label: (
|
label: (
|
||||||
<Styled.InlineRow>
|
<Styled.InlineRow>
|
||||||
<AssetIcon symbol="USDC" /> USDC
|
<AssetIcon symbol="USDC" /> {usdcLabel}
|
||||||
</Styled.InlineRow>
|
</Styled.InlineRow>
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: DydxChainAsset.DYDX,
|
value: DydxChainAsset.CHAINTOKEN,
|
||||||
label: (
|
label: (
|
||||||
<Styled.InlineRow>
|
<Styled.InlineRow>
|
||||||
|
{/* TODO: conditionally display the native token assetIcon */}
|
||||||
{/* <AssetIcon symbol="DYDX" /> */}
|
{/* <AssetIcon symbol="DYDX" /> */}
|
||||||
Dv4TNT
|
{chainTokenLabel}
|
||||||
</Styled.InlineRow>
|
</Styled.InlineRow>
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -11,11 +11,7 @@ import { ButtonShape, ButtonSize } from '@/constants/buttons';
|
|||||||
import { STRING_KEYS } from '@/constants/localization';
|
import { STRING_KEYS } from '@/constants/localization';
|
||||||
import { ENVIRONMENT_CONFIG_MAP } from '@/constants/networks';
|
import { ENVIRONMENT_CONFIG_MAP } from '@/constants/networks';
|
||||||
import { NumberSign } from '@/constants/numbers';
|
import { NumberSign } from '@/constants/numbers';
|
||||||
import {
|
import { DydxChainAsset } from '@/constants/wallets';
|
||||||
DYDX_CHAIN_ASSET_COIN_DENOM,
|
|
||||||
DYDX_CHAIN_ASSET_TAGS,
|
|
||||||
DydxChainAsset,
|
|
||||||
} from '@/constants/wallets';
|
|
||||||
|
|
||||||
import {
|
import {
|
||||||
useAccountBalance,
|
useAccountBalance,
|
||||||
@@ -25,6 +21,7 @@ import {
|
|||||||
useSelectedNetwork,
|
useSelectedNetwork,
|
||||||
useStringGetter,
|
useStringGetter,
|
||||||
useSubaccount,
|
useSubaccount,
|
||||||
|
useTokenConfigs,
|
||||||
} from '@/hooks';
|
} from '@/hooks';
|
||||||
|
|
||||||
import { formMixins } from '@/styles/formMixins';
|
import { formMixins } from '@/styles/formMixins';
|
||||||
@@ -57,7 +54,7 @@ type TransferFormProps = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const TransferForm = ({
|
export const TransferForm = ({
|
||||||
selectedAsset = DydxChainAsset.DYDX,
|
selectedAsset = DydxChainAsset.CHAINTOKEN,
|
||||||
onDone,
|
onDone,
|
||||||
className,
|
className,
|
||||||
}: TransferFormProps) => {
|
}: TransferFormProps) => {
|
||||||
@@ -72,6 +69,7 @@ export const TransferForm = ({
|
|||||||
const { transfer } = useSubaccount();
|
const { transfer } = useSubaccount();
|
||||||
const { nativeTokenBalance, usdcBalance } = useAccountBalance();
|
const { nativeTokenBalance, usdcBalance } = useAccountBalance();
|
||||||
const { selectedNetwork } = useSelectedNetwork();
|
const { selectedNetwork } = useSelectedNetwork();
|
||||||
|
const { tokensConfigs, usdcLabel, chainTokenLabel } = useTokenConfigs();
|
||||||
|
|
||||||
// User Input
|
// User Input
|
||||||
const [asset, setAsset] = useState<DydxChainAsset>(selectedAsset);
|
const [asset, setAsset] = useState<DydxChainAsset>(selectedAsset);
|
||||||
@@ -138,7 +136,7 @@ export const TransferForm = ({
|
|||||||
try {
|
try {
|
||||||
// Subtract fees from amount if sending native tokens
|
// Subtract fees from amount if sending native tokens
|
||||||
const amountToTransfer = (
|
const amountToTransfer = (
|
||||||
asset === DydxChainAsset.DYDX ? amountBN.minus(fee) : amountBN
|
asset === DydxChainAsset.CHAINTOKEN ? amountBN.minus(fee) : amountBN
|
||||||
).toNumber();
|
).toNumber();
|
||||||
|
|
||||||
const screenResults = await screenAddresses({
|
const screenResults = await screenAddresses({
|
||||||
@@ -161,7 +159,7 @@ export const TransferForm = ({
|
|||||||
const txResponse = await transfer(
|
const txResponse = await transfer(
|
||||||
amountToTransfer,
|
amountToTransfer,
|
||||||
recipientAddress as string,
|
recipientAddress as string,
|
||||||
DYDX_CHAIN_ASSET_COIN_DENOM[asset]
|
tokensConfigs[asset].denom,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (txResponse?.code === 0) {
|
if (txResponse?.code === 0) {
|
||||||
@@ -220,16 +218,16 @@ export const TransferForm = ({
|
|||||||
value: DydxChainAsset.USDC,
|
value: DydxChainAsset.USDC,
|
||||||
label: (
|
label: (
|
||||||
<Styled.InlineRow>
|
<Styled.InlineRow>
|
||||||
<AssetIcon symbol="USDC" /> {DYDX_CHAIN_ASSET_TAGS[DydxChainAsset.USDC]}
|
<AssetIcon symbol="USDC" /> {usdcLabel}
|
||||||
</Styled.InlineRow>
|
</Styled.InlineRow>
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: DydxChainAsset.DYDX,
|
value: DydxChainAsset.CHAINTOKEN,
|
||||||
label: (
|
label: (
|
||||||
<Styled.InlineRow>
|
<Styled.InlineRow>
|
||||||
{/* <AssetIcon symbol="DYDX" /> */}
|
{/* <AssetIcon symbol="DYDX" /> */}
|
||||||
{DYDX_CHAIN_ASSET_TAGS[DydxChainAsset.DYDX]}
|
{chainTokenLabel}
|
||||||
</Styled.InlineRow>
|
</Styled.InlineRow>
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
@@ -251,7 +249,7 @@ export const TransferForm = ({
|
|||||||
key: 'amount',
|
key: 'amount',
|
||||||
label: (
|
label: (
|
||||||
<span>
|
<span>
|
||||||
{stringGetter({ key: STRING_KEYS.AVAILABLE })} <Tag>{DYDX_CHAIN_ASSET_TAGS[asset]}</Tag>
|
{stringGetter({ key: STRING_KEYS.AVAILABLE })} <Tag>{tokensConfigs[asset].name}</Tag>
|
||||||
</span>
|
</span>
|
||||||
),
|
),
|
||||||
value: (
|
value: (
|
||||||
|
|||||||
@@ -3,9 +3,9 @@ import { shallowEqual, useSelector } from 'react-redux';
|
|||||||
import { ButtonAction, ButtonSize, ButtonType } from '@/constants/buttons';
|
import { ButtonAction, ButtonSize, ButtonType } from '@/constants/buttons';
|
||||||
import { STRING_KEYS } from '@/constants/localization';
|
import { STRING_KEYS } from '@/constants/localization';
|
||||||
import { NumberSign } from '@/constants/numbers';
|
import { NumberSign } from '@/constants/numbers';
|
||||||
import { DYDX_CHAIN_ASSET_TAGS, DydxChainAsset } from '@/constants/wallets';
|
import { DydxChainAsset } from '@/constants/wallets';
|
||||||
|
|
||||||
import { useAccountBalance, useStringGetter } from '@/hooks';
|
import { useAccountBalance, useTokenConfigs, useStringGetter } from '@/hooks';
|
||||||
|
|
||||||
import { Button } from '@/components/Button';
|
import { Button } from '@/components/Button';
|
||||||
import { DiffOutput } from '@/components/DiffOutput';
|
import { DiffOutput } from '@/components/DiffOutput';
|
||||||
@@ -37,6 +37,7 @@ export const TransferButtonAndReceipt = ({
|
|||||||
const stringGetter = useStringGetter();
|
const stringGetter = useStringGetter();
|
||||||
const canAccountTrade = useSelector(calculateCanAccountTrade, shallowEqual);
|
const canAccountTrade = useSelector(calculateCanAccountTrade, shallowEqual);
|
||||||
const { size } = useSelector(getTransferInputs, shallowEqual) || {};
|
const { size } = useSelector(getTransferInputs, shallowEqual) || {};
|
||||||
|
const { tokensConfigs } = useTokenConfigs();
|
||||||
|
|
||||||
const { equity: equityInfo, leverage: leverageInfo } =
|
const { equity: equityInfo, leverage: leverageInfo } =
|
||||||
useSelector(getSubaccount, shallowEqual) || {};
|
useSelector(getSubaccount, shallowEqual) || {};
|
||||||
@@ -60,7 +61,7 @@ export const TransferButtonAndReceipt = ({
|
|||||||
key: 'fees',
|
key: 'fees',
|
||||||
label: (
|
label: (
|
||||||
<span>
|
<span>
|
||||||
{stringGetter({ key: STRING_KEYS.FEES })} <Tag>{DYDX_CHAIN_ASSET_TAGS[selectedAsset]}</Tag>
|
{stringGetter({ key: STRING_KEYS.FEES })} <Tag>{tokensConfigs[selectedAsset].name}</Tag>
|
||||||
</span>
|
</span>
|
||||||
),
|
),
|
||||||
value: <Output type={OutputType.Asset} value={fees} />,
|
value: <Output type={OutputType.Asset} value={fees} />,
|
||||||
@@ -69,7 +70,7 @@ export const TransferButtonAndReceipt = ({
|
|||||||
key: 'balance',
|
key: 'balance',
|
||||||
label: (
|
label: (
|
||||||
<span>
|
<span>
|
||||||
{stringGetter({ key: STRING_KEYS.BALANCE })} <Tag>{DYDX_CHAIN_ASSET_TAGS[selectedAsset]}</Tag>
|
{stringGetter({ key: STRING_KEYS.BALANCE })} <Tag>{tokensConfigs[selectedAsset].name}</Tag>
|
||||||
</span>
|
</span>
|
||||||
),
|
),
|
||||||
value: (
|
value: (
|
||||||
|
|||||||
@@ -9,7 +9,13 @@ import { DialogTypes } from '@/constants/dialogs';
|
|||||||
import { STRING_KEYS, TOOLTIP_STRING_KEYS } from '@/constants/localization';
|
import { STRING_KEYS, TOOLTIP_STRING_KEYS } from '@/constants/localization';
|
||||||
import { DydxChainAsset, wallets } from '@/constants/wallets';
|
import { DydxChainAsset, wallets } from '@/constants/wallets';
|
||||||
|
|
||||||
import { useAccounts, useBreakpoints, useStringGetter, useAccountBalance } from '@/hooks';
|
import {
|
||||||
|
useAccounts,
|
||||||
|
useBreakpoints,
|
||||||
|
useTokenConfigs,
|
||||||
|
useStringGetter,
|
||||||
|
useAccountBalance,
|
||||||
|
} from '@/hooks';
|
||||||
|
|
||||||
import { OnboardingTriggerButton } from '@/views/dialogs/OnboardingTriggerButton';
|
import { OnboardingTriggerButton } from '@/views/dialogs/OnboardingTriggerButton';
|
||||||
|
|
||||||
@@ -39,6 +45,7 @@ export const AccountMenu = () => {
|
|||||||
const onboardingState = useSelector(getOnboardingState);
|
const onboardingState = useSelector(getOnboardingState);
|
||||||
const { freeCollateral } = useSelector(getSubaccount, shallowEqual) || {};
|
const { freeCollateral } = useSelector(getSubaccount, shallowEqual) || {};
|
||||||
const { nativeTokenBalance } = useAccountBalance();
|
const { nativeTokenBalance } = useAccountBalance();
|
||||||
|
const { usdcLabel, chainTokenLabel } = useTokenConfigs();
|
||||||
|
|
||||||
const { evmAddress, walletType, dydxAddress, hdKey } = useAccounts();
|
const { evmAddress, walletType, dydxAddress, hdKey } = useAccounts();
|
||||||
|
|
||||||
@@ -107,17 +114,23 @@ export const AccountMenu = () => {
|
|||||||
<div>
|
<div>
|
||||||
<div>
|
<div>
|
||||||
<Styled.label>
|
<Styled.label>
|
||||||
{stringGetter({ key: STRING_KEYS.ASSET_BALANCE, params: { ASSET: 'Dv4TNT' } })}
|
{stringGetter({
|
||||||
|
key: STRING_KEYS.ASSET_BALANCE,
|
||||||
|
params: { ASSET: chainTokenLabel },
|
||||||
|
})}
|
||||||
{/* <AssetIcon symbol="DYDX" /> */}
|
{/* <AssetIcon symbol="DYDX" /> */}
|
||||||
</Styled.label>
|
</Styled.label>
|
||||||
<Styled.BalanceOutput type={OutputType.Asset} value={nativeTokenBalance} />
|
<Styled.BalanceOutput type={OutputType.Asset} value={nativeTokenBalance} />
|
||||||
</div>
|
</div>
|
||||||
<AssetActions asset={DydxChainAsset.DYDX} dispatch={dispatch} />
|
<AssetActions asset={DydxChainAsset.CHAINTOKEN} dispatch={dispatch} />
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<div>
|
<div>
|
||||||
<Styled.label>
|
<Styled.label>
|
||||||
{stringGetter({ key: STRING_KEYS.ASSET_BALANCE, params: { ASSET: 'USDC' } })}
|
{stringGetter({
|
||||||
|
key: STRING_KEYS.ASSET_BALANCE,
|
||||||
|
params: { ASSET: usdcLabel },
|
||||||
|
})}
|
||||||
<AssetIcon symbol="USDC" />
|
<AssetIcon symbol="USDC" />
|
||||||
</Styled.label>
|
</Styled.label>
|
||||||
<Styled.BalanceOutput
|
<Styled.BalanceOutput
|
||||||
|
|||||||
Reference in New Issue
Block a user