Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8f75d893bb | ||
|
|
c54a5d6d49 | ||
|
|
2345ef38a1 | ||
|
|
73cbb4e04e | ||
|
|
52e1dcc4b0 | ||
|
|
cc3f7d1c09 | ||
|
|
af46278539 | ||
|
|
ea58b55152 | ||
|
|
54d65bb81c | ||
|
|
e047a49bbc | ||
|
|
14316163e4 | ||
|
|
ac619a9da1 | ||
|
|
cb7f542a99 | ||
|
|
bc5569c4c9 | ||
|
|
dd087ae786 | ||
|
|
eb023ff0ff | ||
|
|
348e82293e | ||
|
|
48a48b4d70 | ||
|
|
944cea0d3d | ||
|
|
4ea2bdf53d | ||
|
|
c40f5eb549 | ||
|
|
d53e8f693e |
@@ -1,6 +0,0 @@
|
|||||||
VITE_BASE_URL=https://v4.testnet.dydx.exchange
|
|
||||||
|
|
||||||
VITE_ALCHEMY_API_KEY=FP275q327Yh7qswtZWenbPXdZZdnAFmC
|
|
||||||
|
|
||||||
VITE_WALLETCONNECT1_BRIDGE=wss://api.dydx.exchange/wc/
|
|
||||||
VITE_WALLETCONNECT2_PROJECT_ID=fbe94eaa691fa8d929561f8567062b32
|
|
||||||
@@ -4,7 +4,6 @@ VITE_ALCHEMY_API_KEY=
|
|||||||
|
|
||||||
VITE_PK_ENCRYPTION_KEY=
|
VITE_PK_ENCRYPTION_KEY=
|
||||||
|
|
||||||
VITE_WALLETCONNECT1_BRIDGE=
|
|
||||||
VITE_WALLETCONNECT2_PROJECT_ID=
|
VITE_WALLETCONNECT2_PROJECT_ID=
|
||||||
|
|
||||||
VITE_V3_TOKEN_ADDRESS=
|
VITE_V3_TOKEN_ADDRESS=
|
||||||
@@ -13,6 +13,7 @@ dist
|
|||||||
dist-ssr
|
dist-ssr
|
||||||
*.local
|
*.local
|
||||||
*.key
|
*.key
|
||||||
|
.env
|
||||||
|
|
||||||
# Editor directories and files
|
# Editor directories and files
|
||||||
.vscode/*
|
.vscode/*
|
||||||
|
|||||||
@@ -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.6.4",
|
"@dydxprotocol/v4-abacus": "^0.7.0",
|
||||||
"@dydxprotocol/v4-client-js": "^0.36.1",
|
"@dydxprotocol/v4-client-js": "^0.36.1",
|
||||||
"@dydxprotocol/v4-localization": "^0.1.24",
|
"@dydxprotocol/v4-localization": "^0.1.30",
|
||||||
"@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",
|
||||||
|
|||||||
@@ -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.6.4
|
specifier: ^0.7.0
|
||||||
version: 0.6.4
|
version: 0.7.0
|
||||||
'@dydxprotocol/v4-client-js':
|
'@dydxprotocol/v4-client-js':
|
||||||
specifier: ^0.36.1
|
specifier: ^0.36.1
|
||||||
version: 0.36.1
|
version: 0.36.1
|
||||||
'@dydxprotocol/v4-localization':
|
'@dydxprotocol/v4-localization':
|
||||||
specifier: ^0.1.24
|
specifier: ^0.1.30
|
||||||
version: 0.1.24
|
version: 0.1.30
|
||||||
'@ethersproject/providers':
|
'@ethersproject/providers':
|
||||||
specifier: ^5.7.2
|
specifier: ^5.7.2
|
||||||
version: 5.7.2
|
version: 5.7.2
|
||||||
@@ -979,8 +979,8 @@ packages:
|
|||||||
resolution: {integrity: sha512-RpfLEtTlyIxeNPGKcokS+p3BZII/Q3bYxryFRglh5H3A3T8q9fsLYm72VYAMEOOIBLEa8o93kFLiBDUWKrwXZA==}
|
resolution: {integrity: sha512-RpfLEtTlyIxeNPGKcokS+p3BZII/Q3bYxryFRglh5H3A3T8q9fsLYm72VYAMEOOIBLEa8o93kFLiBDUWKrwXZA==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/@dydxprotocol/v4-abacus@0.6.4:
|
/@dydxprotocol/v4-abacus@0.7.0:
|
||||||
resolution: {integrity: sha512-eH+/9Q/OnQtwzBwM1BJyXybFPdivGmFQWrxM71MFWGs6uIQGbZX775mpoa8deweSTyQ/QrRLRQ1mP2BPDgBQYg==}
|
resolution: {integrity: sha512-XheqfIpOODfQFG860oH0fneVgp9qQKPMDTwrvFXaM/JtKH9ekOUUO6De72EsJ7qOuxWwl1WgoALA8b4tRs0tiw==}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/@dydxprotocol/v4-client-js@0.36.1:
|
/@dydxprotocol/v4-client-js@0.36.1:
|
||||||
@@ -1010,8 +1010,8 @@ packages:
|
|||||||
- utf-8-validate
|
- utf-8-validate
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/@dydxprotocol/v4-localization@0.1.24:
|
/@dydxprotocol/v4-localization@0.1.30:
|
||||||
resolution: {integrity: sha512-zSiu8+/6BWNWZXxe73zUp/UjuLG1Cp5UuhXKtbATqqkeZyVCs01QxbBCTs1MLfgsLh02IrfhXCPHvXnzZyReEw==}
|
resolution: {integrity: sha512-xTlQuQmPz7wfGkjd07giYMAxRrolDbJE3DryJSIMB6R1MBq1wLzAcwp/iR/nELRwilRX9c44Tap0gGt+oAajiQ==}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/@dydxprotocol/v4-proto@0.2.1:
|
/@dydxprotocol/v4-proto@0.2.1:
|
||||||
|
|||||||
|
After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 193 KiB After Width: | Height: | Size: 122 KiB |
@@ -35,17 +35,21 @@
|
|||||||
"name": "v4 Dev",
|
"name": "v4 Dev",
|
||||||
"ethereumChainId": "5",
|
"ethereumChainId": "5",
|
||||||
"dydxChainId": "dydxprotocol-testnet",
|
"dydxChainId": "dydxprotocol-testnet",
|
||||||
|
"chainName": "dYdX Chain",
|
||||||
|
"chainLogo": "dydx-chain.png",
|
||||||
"isMainNet": false,
|
"isMainNet": false,
|
||||||
"tokens": {
|
"tokens": {
|
||||||
"chain": {
|
"chain": {
|
||||||
"name": "DYDX",
|
"name": "DYDX",
|
||||||
"denom": "dv4tnt",
|
"denom": "adv4tnt",
|
||||||
|
"decimals": 18,
|
||||||
"image": "/currencies/dydx.png"
|
"image": "/currencies/dydx.png"
|
||||||
},
|
},
|
||||||
"usdc": {
|
"usdc": {
|
||||||
"name": "USDC",
|
"name": "USDC",
|
||||||
"denom": "ibc/8E27BA2D5493AF5636760E354E46004562C46AB7EC0CC4C1CA14E9E20E2545B5",
|
"denom": "ibc/8E27BA2D5493AF5636760E354E46004562C46AB7EC0CC4C1CA14E9E20E2545B5",
|
||||||
"gasDenom": "uusdc",
|
"gasDenom": "uusdc",
|
||||||
|
"decimals": 6,
|
||||||
"image": "/currencies/usdc.png"
|
"image": "/currencies/usdc.png"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -75,9 +79,6 @@
|
|||||||
"description": "dYdX v4 App",
|
"description": "dYdX v4 App",
|
||||||
"iconUrl": "/logos/dydx-x.png"
|
"iconUrl": "/logos/dydx-x.png"
|
||||||
},
|
},
|
||||||
"v1": {
|
|
||||||
"bridgeUrl": "wss://api.stage.dydx.exchange/wc/"
|
|
||||||
},
|
|
||||||
"v2": {
|
"v2": {
|
||||||
"projectId": "47559b2ec96c09aed9ff2cb54a31ab0e"
|
"projectId": "47559b2ec96c09aed9ff2cb54a31ab0e"
|
||||||
}
|
}
|
||||||
@@ -94,17 +95,21 @@
|
|||||||
"name": "v4 Dev 2",
|
"name": "v4 Dev 2",
|
||||||
"ethereumChainId": "5",
|
"ethereumChainId": "5",
|
||||||
"dydxChainId": "dydxprotocol-testnet",
|
"dydxChainId": "dydxprotocol-testnet",
|
||||||
|
"chainName": "dYdX Chain",
|
||||||
|
"chainLogo": "dydx-chain.png",
|
||||||
"isMainNet": false,
|
"isMainNet": false,
|
||||||
"tokens": {
|
"tokens": {
|
||||||
"chain": {
|
"chain": {
|
||||||
"name": "DYDX",
|
"name": "DYDX",
|
||||||
"denom": "dv4tnt",
|
"denom": "adv4tnt",
|
||||||
|
"decimals": 18,
|
||||||
"image": "/currencies/dydx.png"
|
"image": "/currencies/dydx.png"
|
||||||
},
|
},
|
||||||
"usdc": {
|
"usdc": {
|
||||||
"name": "USDC",
|
"name": "USDC",
|
||||||
"denom": "ibc/8E27BA2D5493AF5636760E354E46004562C46AB7EC0CC4C1CA14E9E20E2545B5",
|
"denom": "ibc/8E27BA2D5493AF5636760E354E46004562C46AB7EC0CC4C1CA14E9E20E2545B5",
|
||||||
"gasDenom": "uusdc",
|
"gasDenom": "uusdc",
|
||||||
|
"decimals": 6,
|
||||||
"image": "/currencies/usdc.png"
|
"image": "/currencies/usdc.png"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -133,9 +138,6 @@
|
|||||||
"description": "dYdX v4 App",
|
"description": "dYdX v4 App",
|
||||||
"iconUrl": "/logos/dydx-x.png"
|
"iconUrl": "/logos/dydx-x.png"
|
||||||
},
|
},
|
||||||
"v1": {
|
|
||||||
"bridgeUrl": "wss://api.stage.dydx.exchange/wc/"
|
|
||||||
},
|
|
||||||
"v2": {
|
"v2": {
|
||||||
"projectId": "47559b2ec96c09aed9ff2cb54a31ab0e"
|
"projectId": "47559b2ec96c09aed9ff2cb54a31ab0e"
|
||||||
}
|
}
|
||||||
@@ -152,17 +154,21 @@
|
|||||||
"name": "v4 Dev 4",
|
"name": "v4 Dev 4",
|
||||||
"ethereumChainId": "5",
|
"ethereumChainId": "5",
|
||||||
"dydxChainId": "dydxprotocol-testnet",
|
"dydxChainId": "dydxprotocol-testnet",
|
||||||
|
"chainName": "dYdX Chain",
|
||||||
|
"chainLogo": "dydx-chain.png",
|
||||||
"isMainNet": false,
|
"isMainNet": false,
|
||||||
"tokens": {
|
"tokens": {
|
||||||
"chain": {
|
"chain": {
|
||||||
"name": "DYDX",
|
"name": "DYDX",
|
||||||
"denom": "dv4tnt",
|
"denom": "adv4tnt",
|
||||||
|
"decimals": 18,
|
||||||
"image": "/currencies/dydx.png"
|
"image": "/currencies/dydx.png"
|
||||||
},
|
},
|
||||||
"usdc": {
|
"usdc": {
|
||||||
"name": "USDC",
|
"name": "USDC",
|
||||||
"denom": "ibc/8E27BA2D5493AF5636760E354E46004562C46AB7EC0CC4C1CA14E9E20E2545B5",
|
"denom": "ibc/8E27BA2D5493AF5636760E354E46004562C46AB7EC0CC4C1CA14E9E20E2545B5",
|
||||||
"gasDenom": "uusdc",
|
"gasDenom": "uusdc",
|
||||||
|
"decimals": 6,
|
||||||
"image": "/currencies/usdc.png"
|
"image": "/currencies/usdc.png"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -191,9 +197,6 @@
|
|||||||
"description": "dYdX v4 App",
|
"description": "dYdX v4 App",
|
||||||
"iconUrl": "/logos/dydx-x.png"
|
"iconUrl": "/logos/dydx-x.png"
|
||||||
},
|
},
|
||||||
"v1": {
|
|
||||||
"bridgeUrl": "wss://api.stage.dydx.exchange/wc/"
|
|
||||||
},
|
|
||||||
"v2": {
|
"v2": {
|
||||||
"projectId": "47559b2ec96c09aed9ff2cb54a31ab0e"
|
"projectId": "47559b2ec96c09aed9ff2cb54a31ab0e"
|
||||||
}
|
}
|
||||||
@@ -210,17 +213,21 @@
|
|||||||
"name": "v4 Dev 5",
|
"name": "v4 Dev 5",
|
||||||
"ethereumChainId": "5",
|
"ethereumChainId": "5",
|
||||||
"dydxChainId": "dydxprotocol-testnet",
|
"dydxChainId": "dydxprotocol-testnet",
|
||||||
|
"chainName": "dYdX Chain",
|
||||||
|
"chainLogo": "dydx-chain.png",
|
||||||
"isMainNet": false,
|
"isMainNet": false,
|
||||||
"tokens": {
|
"tokens": {
|
||||||
"chain": {
|
"chain": {
|
||||||
"name": "DYDX",
|
"name": "DYDX",
|
||||||
"denom": "dv4tnt",
|
"denom": "adv4tnt",
|
||||||
|
"decimals": 18,
|
||||||
"image": "/currencies/dydx.png"
|
"image": "/currencies/dydx.png"
|
||||||
},
|
},
|
||||||
"usdc": {
|
"usdc": {
|
||||||
"name": "USDC",
|
"name": "USDC",
|
||||||
"denom": "ibc/8E27BA2D5493AF5636760E354E46004562C46AB7EC0CC4C1CA14E9E20E2545B5",
|
"denom": "ibc/8E27BA2D5493AF5636760E354E46004562C46AB7EC0CC4C1CA14E9E20E2545B5",
|
||||||
"gasDenom": "uusdc",
|
"gasDenom": "uusdc",
|
||||||
|
"decimals": 6,
|
||||||
"image": "/currencies/usdc.png"
|
"image": "/currencies/usdc.png"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -249,9 +256,6 @@
|
|||||||
"description": "dYdX v4 App",
|
"description": "dYdX v4 App",
|
||||||
"iconUrl": "/logos/dydx-x.png"
|
"iconUrl": "/logos/dydx-x.png"
|
||||||
},
|
},
|
||||||
"v1": {
|
|
||||||
"bridgeUrl": "wss://api.stage.dydx.exchange/wc/"
|
|
||||||
},
|
|
||||||
"v2": {
|
"v2": {
|
||||||
"projectId": "47559b2ec96c09aed9ff2cb54a31ab0e"
|
"projectId": "47559b2ec96c09aed9ff2cb54a31ab0e"
|
||||||
}
|
}
|
||||||
@@ -268,17 +272,21 @@
|
|||||||
"name": "v4 Staging",
|
"name": "v4 Staging",
|
||||||
"ethereumChainId": "5",
|
"ethereumChainId": "5",
|
||||||
"dydxChainId": "dydxprotocol-testnet",
|
"dydxChainId": "dydxprotocol-testnet",
|
||||||
|
"chainName": "dYdX Chain",
|
||||||
|
"chainLogo": "dydx-chain.png",
|
||||||
"isMainNet": false,
|
"isMainNet": false,
|
||||||
"tokens": {
|
"tokens": {
|
||||||
"chain": {
|
"chain": {
|
||||||
"name": "DYDX",
|
"name": "DYDX",
|
||||||
"denom": "dv4tnt",
|
"denom": "adv4tnt",
|
||||||
|
"decimals": 18,
|
||||||
"image": "/currencies/dydx.png"
|
"image": "/currencies/dydx.png"
|
||||||
},
|
},
|
||||||
"usdc": {
|
"usdc": {
|
||||||
"name": "USDC",
|
"name": "USDC",
|
||||||
"denom": "ibc/8E27BA2D5493AF5636760E354E46004562C46AB7EC0CC4C1CA14E9E20E2545B5",
|
"denom": "ibc/8E27BA2D5493AF5636760E354E46004562C46AB7EC0CC4C1CA14E9E20E2545B5",
|
||||||
"gasDenom": "uusdc",
|
"gasDenom": "uusdc",
|
||||||
|
"decimals": 6,
|
||||||
"image": "/currencies/usdc.png"
|
"image": "/currencies/usdc.png"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -311,9 +319,6 @@
|
|||||||
"description": "dYdX v4 App",
|
"description": "dYdX v4 App",
|
||||||
"iconUrl": "/logos/dydx-x.png"
|
"iconUrl": "/logos/dydx-x.png"
|
||||||
},
|
},
|
||||||
"v1": {
|
|
||||||
"bridgeUrl": "wss://api.stage.dydx.exchange/wc/"
|
|
||||||
},
|
|
||||||
"v2": {
|
"v2": {
|
||||||
"projectId": "47559b2ec96c09aed9ff2cb54a31ab0e"
|
"projectId": "47559b2ec96c09aed9ff2cb54a31ab0e"
|
||||||
}
|
}
|
||||||
@@ -330,17 +335,21 @@
|
|||||||
"name": "v4 Staging West",
|
"name": "v4 Staging West",
|
||||||
"ethereumChainId": "5",
|
"ethereumChainId": "5",
|
||||||
"dydxChainId": "dydxprotocol-testnet",
|
"dydxChainId": "dydxprotocol-testnet",
|
||||||
|
"chainName": "dYdX Chain",
|
||||||
|
"chainLogo": "dydx-chain.png",
|
||||||
"isMainNet": false,
|
"isMainNet": false,
|
||||||
"tokens": {
|
"tokens": {
|
||||||
"chain": {
|
"chain": {
|
||||||
"name": "DYDX",
|
"name": "DYDX",
|
||||||
"denom": "dv4tnt",
|
"denom": "adv4tnt",
|
||||||
|
"decimals": 18,
|
||||||
"image": "/currencies/dydx.png"
|
"image": "/currencies/dydx.png"
|
||||||
},
|
},
|
||||||
"usdc": {
|
"usdc": {
|
||||||
"name": "USDC",
|
"name": "USDC",
|
||||||
"denom": "ibc/8E27BA2D5493AF5636760E354E46004562C46AB7EC0CC4C1CA14E9E20E2545B5",
|
"denom": "ibc/8E27BA2D5493AF5636760E354E46004562C46AB7EC0CC4C1CA14E9E20E2545B5",
|
||||||
"gasDenom": "uusdc",
|
"gasDenom": "uusdc",
|
||||||
|
"decimals": 6,
|
||||||
"image": "/currencies/usdc.png"
|
"image": "/currencies/usdc.png"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -373,9 +382,6 @@
|
|||||||
"description": "dYdX v4 App",
|
"description": "dYdX v4 App",
|
||||||
"iconUrl": "/logos/dydx-x.png"
|
"iconUrl": "/logos/dydx-x.png"
|
||||||
},
|
},
|
||||||
"v1": {
|
|
||||||
"bridgeUrl": "wss://api.stage.dydx.exchange/wc/"
|
|
||||||
},
|
|
||||||
"v2": {
|
"v2": {
|
||||||
"projectId": "47559b2ec96c09aed9ff2cb54a31ab0e"
|
"projectId": "47559b2ec96c09aed9ff2cb54a31ab0e"
|
||||||
}
|
}
|
||||||
@@ -391,18 +397,22 @@
|
|||||||
"dydxprotocol-testnet": {
|
"dydxprotocol-testnet": {
|
||||||
"name": "v4 Public Testnet",
|
"name": "v4 Public Testnet",
|
||||||
"ethereumChainId": "5",
|
"ethereumChainId": "5",
|
||||||
"dydxChainId": "dydx-testnet-3",
|
"dydxChainId": "dydx-testnet-4",
|
||||||
|
"chainName": "dYdX Chain",
|
||||||
|
"chainLogo": "dydx-chain.png",
|
||||||
"isMainNet": false,
|
"isMainNet": false,
|
||||||
"tokens": {
|
"tokens": {
|
||||||
"chain": {
|
"chain": {
|
||||||
"name": "DYDX",
|
"name": "DYDX",
|
||||||
"denom": "dv4tnt",
|
"denom": "adv4tnt",
|
||||||
|
"decimals": 18,
|
||||||
"image": "/currencies/dydx.png"
|
"image": "/currencies/dydx.png"
|
||||||
},
|
},
|
||||||
"usdc": {
|
"usdc": {
|
||||||
"name": "USDC",
|
"name": "USDC",
|
||||||
"denom": "ibc/8E27BA2D5493AF5636760E354E46004562C46AB7EC0CC4C1CA14E9E20E2545B5",
|
"denom": "ibc/8E27BA2D5493AF5636760E354E46004562C46AB7EC0CC4C1CA14E9E20E2545B5",
|
||||||
"gasDenom": "uusdc",
|
"gasDenom": "uusdc",
|
||||||
|
"decimals": 6,
|
||||||
"image": "/currencies/usdc.png"
|
"image": "/currencies/usdc.png"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -437,9 +447,6 @@
|
|||||||
"description": "dYdX v4 App",
|
"description": "dYdX v4 App",
|
||||||
"iconUrl": "/logos/dydx-x.png"
|
"iconUrl": "/logos/dydx-x.png"
|
||||||
},
|
},
|
||||||
"v1": {
|
|
||||||
"bridgeUrl": "wss://api.stage.dydx.exchange/wc/"
|
|
||||||
},
|
|
||||||
"v2": {
|
"v2": {
|
||||||
"projectId": "47559b2ec96c09aed9ff2cb54a31ab0e"
|
"projectId": "47559b2ec96c09aed9ff2cb54a31ab0e"
|
||||||
}
|
}
|
||||||
@@ -448,25 +455,29 @@
|
|||||||
"callbackUrl": "/walletsegue"
|
"callbackUrl": "/walletsegue"
|
||||||
},
|
},
|
||||||
"images": "/wallets/",
|
"images": "/wallets/",
|
||||||
"signTypedDataAction": "dYdX V4 Onboarding",
|
"signTypedDataAction": "dYdX Chain Onboarding",
|
||||||
"signTypedDataDomainName": "dYdX V4"
|
"signTypedDataDomainName": "dYdX V4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dydxprotocol-testnet-dydx": {
|
"dydxprotocol-testnet-dydx": {
|
||||||
"name": "v4 Public Testnet/dYdX",
|
"name": "v4 Public Testnet/dYdX",
|
||||||
"ethereumChainId": "5",
|
"ethereumChainId": "5",
|
||||||
"dydxChainId": "dydx-testnet-3",
|
"dydxChainId": "dydx-testnet-4",
|
||||||
|
"chainName": "dYdX Chain",
|
||||||
|
"chainLogo": "dydx-chain.png",
|
||||||
"isMainNet": false,
|
"isMainNet": false,
|
||||||
"tokens": {
|
"tokens": {
|
||||||
"chain": {
|
"chain": {
|
||||||
"name": "DYDX",
|
"name": "DYDX",
|
||||||
"denom": "dv4tnt",
|
"denom": "adv4tnt",
|
||||||
|
"decimals": 18,
|
||||||
"image": "/currencies/dydx.png"
|
"image": "/currencies/dydx.png"
|
||||||
},
|
},
|
||||||
"usdc": {
|
"usdc": {
|
||||||
"name": "USDC",
|
"name": "USDC",
|
||||||
"denom": "ibc/8E27BA2D5493AF5636760E354E46004562C46AB7EC0CC4C1CA14E9E20E2545B5",
|
"denom": "ibc/8E27BA2D5493AF5636760E354E46004562C46AB7EC0CC4C1CA14E9E20E2545B5",
|
||||||
"gasDenom": "uusdc",
|
"gasDenom": "uusdc",
|
||||||
|
"decimals": 6,
|
||||||
"image": "/currencies/usdc.png"
|
"image": "/currencies/usdc.png"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -500,9 +511,6 @@
|
|||||||
"description": "dYdX v4 App",
|
"description": "dYdX v4 App",
|
||||||
"iconUrl": "/logos/dydx-x.png"
|
"iconUrl": "/logos/dydx-x.png"
|
||||||
},
|
},
|
||||||
"v1": {
|
|
||||||
"bridgeUrl": "wss://api.stage.dydx.exchange/wc/"
|
|
||||||
},
|
|
||||||
"v2": {
|
"v2": {
|
||||||
"projectId": "47559b2ec96c09aed9ff2cb54a31ab0e"
|
"projectId": "47559b2ec96c09aed9ff2cb54a31ab0e"
|
||||||
}
|
}
|
||||||
@@ -511,25 +519,29 @@
|
|||||||
"callbackUrl": "/walletsegue"
|
"callbackUrl": "/walletsegue"
|
||||||
},
|
},
|
||||||
"images": "/wallets/",
|
"images": "/wallets/",
|
||||||
"signTypedDataAction": "dYdX V4 Onboarding",
|
"signTypedDataAction": "dYdX Chain Onboarding",
|
||||||
"signTypedDataDomainName": "dYdX V4"
|
"signTypedDataDomainName": "dYdX V4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dydxprotocol-testnet-dsrv": {
|
"dydxprotocol-testnet-dsrv": {
|
||||||
"name": "v4 Public Testnet/DSRV",
|
"name": "v4 Public Testnet/DSRV",
|
||||||
"ethereumChainId": "5",
|
"ethereumChainId": "5",
|
||||||
"dydxChainId": "dydx-testnet-3",
|
"dydxChainId": "dydx-testnet-4",
|
||||||
|
"chainName": "dYdX Chain",
|
||||||
|
"chainLogo": "dydx-chain.png",
|
||||||
"isMainNet": false,
|
"isMainNet": false,
|
||||||
"tokens": {
|
"tokens": {
|
||||||
"chain": {
|
"chain": {
|
||||||
"name": "DYDX",
|
"name": "DYDX",
|
||||||
"denom": "dv4tnt",
|
"denom": "adv4tnt",
|
||||||
|
"decimals": 18,
|
||||||
"image": "/currencies/dydx.png"
|
"image": "/currencies/dydx.png"
|
||||||
},
|
},
|
||||||
"usdc": {
|
"usdc": {
|
||||||
"name": "USDC",
|
"name": "USDC",
|
||||||
"denom": "ibc/8E27BA2D5493AF5636760E354E46004562C46AB7EC0CC4C1CA14E9E20E2545B5",
|
"denom": "ibc/8E27BA2D5493AF5636760E354E46004562C46AB7EC0CC4C1CA14E9E20E2545B5",
|
||||||
"gasDenom": "uusdc",
|
"gasDenom": "uusdc",
|
||||||
|
"decimals": 6,
|
||||||
"image": "/currencies/usdc.png"
|
"image": "/currencies/usdc.png"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -563,9 +575,6 @@
|
|||||||
"description": "dYdX v4 App",
|
"description": "dYdX v4 App",
|
||||||
"iconUrl": "/logos/dydx-x.png"
|
"iconUrl": "/logos/dydx-x.png"
|
||||||
},
|
},
|
||||||
"v1": {
|
|
||||||
"bridgeUrl": "wss://api.stage.dydx.exchange/wc/"
|
|
||||||
},
|
|
||||||
"v2": {
|
"v2": {
|
||||||
"projectId": "47559b2ec96c09aed9ff2cb54a31ab0e"
|
"projectId": "47559b2ec96c09aed9ff2cb54a31ab0e"
|
||||||
}
|
}
|
||||||
@@ -574,25 +583,29 @@
|
|||||||
"callbackUrl": "/walletsegue"
|
"callbackUrl": "/walletsegue"
|
||||||
},
|
},
|
||||||
"images": "/wallets/",
|
"images": "/wallets/",
|
||||||
"signTypedDataAction": "dYdX V4 Onboarding",
|
"signTypedDataAction": "dYdX Chain Onboarding",
|
||||||
"signTypedDataDomainName": "dYdX V4"
|
"signTypedDataDomainName": "dYdX V4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dydxprotocol-testnet-nodefleet": {
|
"dydxprotocol-testnet-nodefleet": {
|
||||||
"name": "v4 Public Testnet/nodefleet",
|
"name": "v4 Public Testnet/nodefleet",
|
||||||
"ethereumChainId": "5",
|
"ethereumChainId": "5",
|
||||||
"dydxChainId": "dydx-testnet-3",
|
"dydxChainId": "dydx-testnet-4",
|
||||||
|
"chainName": "dYdX Chain",
|
||||||
|
"chainLogo": "dydx-chain.png",
|
||||||
"isMainNet": false,
|
"isMainNet": false,
|
||||||
"tokens": {
|
"tokens": {
|
||||||
"chain": {
|
"chain": {
|
||||||
"name": "DYDX",
|
"name": "DYDX",
|
||||||
"denom": "dv4tnt",
|
"denom": "adv4tnt",
|
||||||
|
"decimals": 18,
|
||||||
"image": "/currencies/dydx.png"
|
"image": "/currencies/dydx.png"
|
||||||
},
|
},
|
||||||
"usdc": {
|
"usdc": {
|
||||||
"name": "USDC",
|
"name": "USDC",
|
||||||
"denom": "ibc/8E27BA2D5493AF5636760E354E46004562C46AB7EC0CC4C1CA14E9E20E2545B5",
|
"denom": "ibc/8E27BA2D5493AF5636760E354E46004562C46AB7EC0CC4C1CA14E9E20E2545B5",
|
||||||
"gasDenom": "uusdc",
|
"gasDenom": "uusdc",
|
||||||
|
"decimals": 6,
|
||||||
"image": "/currencies/usdc.png"
|
"image": "/currencies/usdc.png"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -626,9 +639,6 @@
|
|||||||
"description": "dYdX v4 App",
|
"description": "dYdX v4 App",
|
||||||
"iconUrl": "/logos/dydx-x.png"
|
"iconUrl": "/logos/dydx-x.png"
|
||||||
},
|
},
|
||||||
"v1": {
|
|
||||||
"bridgeUrl": "wss://api.stage.dydx.exchange/wc/"
|
|
||||||
},
|
|
||||||
"v2": {
|
"v2": {
|
||||||
"projectId": "47559b2ec96c09aed9ff2cb54a31ab0e"
|
"projectId": "47559b2ec96c09aed9ff2cb54a31ab0e"
|
||||||
}
|
}
|
||||||
@@ -637,25 +647,29 @@
|
|||||||
"callbackUrl": "/walletsegue"
|
"callbackUrl": "/walletsegue"
|
||||||
},
|
},
|
||||||
"images": "/wallets/",
|
"images": "/wallets/",
|
||||||
"signTypedDataAction": "dYdX V4 Onboarding",
|
"signTypedDataAction": "dYdX Chain Onboarding",
|
||||||
"signTypedDataDomainName": "dYdX V4"
|
"signTypedDataDomainName": "dYdX V4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dydxprotocol-testnet-kingnodes": {
|
"dydxprotocol-testnet-kingnodes": {
|
||||||
"name": "v4 Public Testnet/KingNodes",
|
"name": "v4 Public Testnet/KingNodes",
|
||||||
"ethereumChainId": "5",
|
"ethereumChainId": "5",
|
||||||
"dydxChainId": "dydx-testnet-3",
|
"dydxChainId": "dydx-testnet-4",
|
||||||
|
"chainName": "dYdX Chain",
|
||||||
|
"chainLogo": "dydx-chain.png",
|
||||||
"isMainNet": false,
|
"isMainNet": false,
|
||||||
"tokens": {
|
"tokens": {
|
||||||
"chain": {
|
"chain": {
|
||||||
"name": "DYDX",
|
"name": "DYDX",
|
||||||
"denom": "dv4tnt",
|
"denom": "adv4tnt",
|
||||||
|
"decimals": 18,
|
||||||
"image": "/currencies/dydx.png"
|
"image": "/currencies/dydx.png"
|
||||||
},
|
},
|
||||||
"usdc": {
|
"usdc": {
|
||||||
"name": "USDC",
|
"name": "USDC",
|
||||||
"denom": "ibc/8E27BA2D5493AF5636760E354E46004562C46AB7EC0CC4C1CA14E9E20E2545B5",
|
"denom": "ibc/8E27BA2D5493AF5636760E354E46004562C46AB7EC0CC4C1CA14E9E20E2545B5",
|
||||||
"gasDenom": "uusdc",
|
"gasDenom": "uusdc",
|
||||||
|
"decimals": 6,
|
||||||
"image": "/currencies/usdc.png"
|
"image": "/currencies/usdc.png"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -689,9 +703,6 @@
|
|||||||
"description": "dYdX v4 App",
|
"description": "dYdX v4 App",
|
||||||
"iconUrl": "/logos/dydx-x.png"
|
"iconUrl": "/logos/dydx-x.png"
|
||||||
},
|
},
|
||||||
"v1": {
|
|
||||||
"bridgeUrl": "wss://api.stage.dydx.exchange/wc/"
|
|
||||||
},
|
|
||||||
"v2": {
|
"v2": {
|
||||||
"projectId": "47559b2ec96c09aed9ff2cb54a31ab0e"
|
"projectId": "47559b2ec96c09aed9ff2cb54a31ab0e"
|
||||||
}
|
}
|
||||||
@@ -700,25 +711,29 @@
|
|||||||
"callbackUrl": "/walletsegue"
|
"callbackUrl": "/walletsegue"
|
||||||
},
|
},
|
||||||
"images": "/wallets/",
|
"images": "/wallets/",
|
||||||
"signTypedDataAction": "dYdX V4 Onboarding",
|
"signTypedDataAction": "dYdX Chain Onboarding",
|
||||||
"signTypedDataDomainName": "dYdX V4"
|
"signTypedDataDomainName": "dYdX V4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dydxprotocol-testnet-liquify": {
|
"dydxprotocol-testnet-liquify": {
|
||||||
"name": "v4 Public Testnet/Liquify",
|
"name": "v4 Public Testnet/Liquify",
|
||||||
"ethereumChainId": "5",
|
"ethereumChainId": "5",
|
||||||
"dydxChainId": "dydx-testnet-3",
|
"dydxChainId": "dydx-testnet-4",
|
||||||
|
"chainName": "dYdX Chain",
|
||||||
|
"chainLogo": "dydx-chain.png",
|
||||||
"isMainNet": false,
|
"isMainNet": false,
|
||||||
"tokens": {
|
"tokens": {
|
||||||
"chain": {
|
"chain": {
|
||||||
"name": "DYDX",
|
"name": "DYDX",
|
||||||
"denom": "dv4tnt",
|
"denom": "adv4tnt",
|
||||||
|
"decimals": 18,
|
||||||
"image": "/currencies/dydx.png"
|
"image": "/currencies/dydx.png"
|
||||||
},
|
},
|
||||||
"usdc": {
|
"usdc": {
|
||||||
"name": "USDC",
|
"name": "USDC",
|
||||||
"denom": "ibc/8E27BA2D5493AF5636760E354E46004562C46AB7EC0CC4C1CA14E9E20E2545B5",
|
"denom": "ibc/8E27BA2D5493AF5636760E354E46004562C46AB7EC0CC4C1CA14E9E20E2545B5",
|
||||||
"gasDenom": "uusdc",
|
"gasDenom": "uusdc",
|
||||||
|
"decimals": 6,
|
||||||
"image": "/currencies/usdc.png"
|
"image": "/currencies/usdc.png"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -752,9 +767,6 @@
|
|||||||
"description": "dYdX v4 App",
|
"description": "dYdX v4 App",
|
||||||
"iconUrl": "/logos/dydx-x.png"
|
"iconUrl": "/logos/dydx-x.png"
|
||||||
},
|
},
|
||||||
"v1": {
|
|
||||||
"bridgeUrl": "wss://api.stage.dydx.exchange/wc/"
|
|
||||||
},
|
|
||||||
"v2": {
|
"v2": {
|
||||||
"projectId": "47559b2ec96c09aed9ff2cb54a31ab0e"
|
"projectId": "47559b2ec96c09aed9ff2cb54a31ab0e"
|
||||||
}
|
}
|
||||||
@@ -763,26 +775,30 @@
|
|||||||
"callbackUrl": "/walletsegue"
|
"callbackUrl": "/walletsegue"
|
||||||
},
|
},
|
||||||
"images": "/wallets/",
|
"images": "/wallets/",
|
||||||
"signTypedDataAction": "dYdX V4 Onboarding",
|
"signTypedDataAction": "dYdX Chain Onboarding",
|
||||||
"signTypedDataDomainName": "dYdX V4"
|
"signTypedDataDomainName": "dYdX V4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dydxprotocol-mainet": {
|
"dydxprotocol-mainnet": {
|
||||||
"name": "v4",
|
"name": "v4",
|
||||||
"ethereumChainId": "1",
|
"ethereumChainId": "1",
|
||||||
"dydxChainId": "[mainnet chain id]",
|
"dydxChainId": "[mainnet chain id]",
|
||||||
|
"chainName": "dYdX Chain",
|
||||||
|
"chainLogo": "dydx-chain.png",
|
||||||
"isMainNet": true,
|
"isMainNet": true,
|
||||||
"tokens": {
|
"tokens": {
|
||||||
"comment": "Change according to mainnet release",
|
"comment": "Change according to mainnet release",
|
||||||
"chain": {
|
"chain": {
|
||||||
"name": "DYDX",
|
"name": "DYDX",
|
||||||
"denom": "dv4tnt",
|
"denom": "adv4tnt",
|
||||||
|
"decimals": 18,
|
||||||
"image": "/currencies/dydx.png"
|
"image": "/currencies/dydx.png"
|
||||||
},
|
},
|
||||||
"usdc": {
|
"usdc": {
|
||||||
"name": "USDC",
|
"name": "USDC",
|
||||||
"denom": "ibc/8E27BA2D5493AF5636760E354E46004562C46AB7EC0CC4C1CA14E9E20E2545B5",
|
"denom": "ibc/8E27BA2D5493AF5636760E354E46004562C46AB7EC0CC4C1CA14E9E20E2545B5",
|
||||||
"gasDenom": "uusdc",
|
"gasDenom": "uusdc",
|
||||||
|
"decimals": 6,
|
||||||
"image": "/currencies/usdc.png"
|
"image": "/currencies/usdc.png"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -815,9 +831,6 @@
|
|||||||
"description": "[Description of the app]",
|
"description": "[Description of the app]",
|
||||||
"iconUrl": "[Relative URL of the icon URL]"
|
"iconUrl": "[Relative URL of the icon URL]"
|
||||||
},
|
},
|
||||||
"v1": {
|
|
||||||
"bridgeUrl": "[Bridge URL]"
|
|
||||||
},
|
|
||||||
"v2": {
|
"v2": {
|
||||||
"projectId": "[Project ID]"
|
"projectId": "[Project ID]"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,474 +1,464 @@
|
|||||||
[
|
[
|
||||||
{
|
{
|
||||||
"id":"c57ca95b47569778a828d19178114f4db188b89b763c899ba0be274e97267d96",
|
"id": "c57ca95b47569778a828d19178114f4db188b89b763c899ba0be274e97267d96",
|
||||||
"name":"MetaMask",
|
"name": "MetaMask",
|
||||||
"description":"",
|
"description": "",
|
||||||
"homepage":"https://metamask.io/",
|
"homepage": "https://metamask.io/",
|
||||||
"chains":[
|
"chains": [
|
||||||
"eip155:1",
|
"eip155:1",
|
||||||
"eip155:42161",
|
"eip155:42161",
|
||||||
"eip155:43114"
|
"eip155:43114"
|
||||||
],
|
],
|
||||||
"versions":[
|
"versions": [
|
||||||
"1"
|
"1"
|
||||||
],
|
],
|
||||||
"app":{
|
"app": {
|
||||||
"browser":"",
|
"browser": "",
|
||||||
"ios":"https://apps.apple.com/us/app/metamask/id1438144202",
|
"ios": "https://apps.apple.com/us/app/metamask/id1438144202",
|
||||||
"android":"https://play.google.com/store/apps/details?id=io.metamask",
|
"android": "https://play.google.com/store/apps/details?id=io.metamask",
|
||||||
"mac":"",
|
"mac": "",
|
||||||
"windows":"",
|
"windows": "",
|
||||||
"linux":""
|
"linux": ""
|
||||||
},
|
},
|
||||||
"mobile":{
|
"mobile": {
|
||||||
"native":"metamask:",
|
"native": "metamask:",
|
||||||
"universal":"https://metamask.app.link"
|
"universal": "https://metamask.app.link"
|
||||||
},
|
},
|
||||||
"desktop":{
|
"desktop": {
|
||||||
"native":"",
|
"native": "",
|
||||||
"universal":""
|
"universal": ""
|
||||||
},
|
},
|
||||||
"metadata":{
|
"metadata": {
|
||||||
"shortName":"MetaMask",
|
"shortName": "MetaMask",
|
||||||
"colors":{
|
"colors": {
|
||||||
"primary":"rgb(255, 255, 255)",
|
"primary": "rgb(255, 255, 255)",
|
||||||
"secondary":""
|
"secondary": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"config": {
|
||||||
|
"comment": "MetaMask",
|
||||||
|
"iosMinVersion": "0",
|
||||||
|
"imageUrl": "",
|
||||||
|
"encoding": "=\"#%/<>?@\\^`{|}:&",
|
||||||
|
"connections": [
|
||||||
|
{
|
||||||
|
"type": "walletConnectV2",
|
||||||
|
"native": "metamask:",
|
||||||
|
"universal": "https://metamask.app.link"
|
||||||
}
|
}
|
||||||
},
|
],
|
||||||
"config":{
|
"methods": [
|
||||||
"comment":"MetaMask",
|
"eth_sendTransaction",
|
||||||
"iosMinVersion":"0",
|
"personal_sign",
|
||||||
"imageUrl":"https://v4.testnet.dydx.exchange/wallets/metamask.png",
|
"eth_signTypedData",
|
||||||
"image":"metamask.png",
|
"wallet_addEthereumChain"
|
||||||
"encoding":"=\"#%/<>?@\\^`{|}:&",
|
]
|
||||||
"connections":[
|
},
|
||||||
{
|
"userFields": {
|
||||||
"type":"walletConnectV2",
|
"analyticEvent": "METAMASK",
|
||||||
"native":"metamask:",
|
"imageName": "metamask.png"
|
||||||
"universal":"https://metamask.app.link"
|
}
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"userFields":{
|
|
||||||
"analyticEvent":"METAMASK"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id":"coinbase-wallet",
|
"id": "coinbase-wallet",
|
||||||
"name":"Coinbase Wallet",
|
"name": "Coinbase Wallet",
|
||||||
"description":"",
|
"description": "",
|
||||||
"homepage":"https://www.coinbase.com/wallet",
|
"homepage": "https://www.coinbase.com/wallet",
|
||||||
"chains":[
|
"chains": [
|
||||||
"eip155:1"
|
"eip155:1"
|
||||||
],
|
],
|
||||||
"versions":[
|
"versions": [
|
||||||
"1"
|
"1"
|
||||||
],
|
],
|
||||||
"app":{
|
"app": {
|
||||||
"browser":"",
|
"browser": "",
|
||||||
"ios":"https://apps.apple.com/us/app/coinbase-wallet-nfts-crypto/id1278383455",
|
"ios": "https://apps.apple.com/us/app/coinbase-wallet-nfts-crypto/id1278383455",
|
||||||
"android":"https://play.google.com/store/apps/details?id=org.toshi",
|
"android": "https://play.google.com/store/apps/details?id=org.toshi",
|
||||||
"mac":"",
|
"mac": "",
|
||||||
"windows":"",
|
"windows": "",
|
||||||
"linux":""
|
"linux": ""
|
||||||
},
|
},
|
||||||
"mobile":{
|
"mobile": {
|
||||||
"native":"cbwallet:",
|
"native": "cbwallet:",
|
||||||
"universal":""
|
"universal": ""
|
||||||
},
|
},
|
||||||
"desktop":{
|
"desktop": {
|
||||||
"native":"",
|
"native": "",
|
||||||
"universal":""
|
"universal": ""
|
||||||
},
|
},
|
||||||
"metadata":{
|
"metadata": {
|
||||||
"shortName":"Coinbase",
|
"shortName": "Coinbase",
|
||||||
"colors":{
|
"colors": {
|
||||||
"primary":"rgb(255, 255, 255)",
|
"primary": "rgb(255, 255, 255)",
|
||||||
"secondary":""
|
"secondary": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"config": {
|
||||||
|
"comment": "Coinbase",
|
||||||
|
"iosMinVersion": "1.8.0",
|
||||||
|
"imageUrl": "",
|
||||||
|
"encoding": "=\"#%/<>?@\\^`{|}:&",
|
||||||
|
"connections": [
|
||||||
|
{
|
||||||
|
"type": "walletSegue",
|
||||||
|
"native": "cbwallet:",
|
||||||
|
"universal": ""
|
||||||
}
|
}
|
||||||
},
|
],
|
||||||
"config":{
|
"methods": [
|
||||||
"comment":"Coinbase",
|
"eth_sendTransaction",
|
||||||
"iosMinVersion":"1.8.0",
|
"personal_sign",
|
||||||
"imageUrl":"https://v4.testnet.dydx.exchange/wallets/coinbase-wallet.png",
|
"eth_signTypedData",
|
||||||
"image":"coinbase-wallet.png",
|
"wallet_addEthereumChain"
|
||||||
"encoding":"=\"#%/<>?@\\^`{|}:&",
|
]
|
||||||
"connections":[
|
},
|
||||||
{
|
"userFields": {
|
||||||
"type":"walletSegue",
|
"analyticEvent": "COINBASE_WALLET",
|
||||||
"native":"cbwallet:",
|
"imageName": "coinbase-wallet.png"
|
||||||
"universal":""
|
}
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"userFields":{
|
|
||||||
"analyticEvent":"COINBASE_WALLET"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id":"9d373b43ad4d2cf190fb1a774ec964a1addf406d6fd24af94ab7596e58c291b2",
|
"id": "9d373b43ad4d2cf190fb1a774ec964a1addf406d6fd24af94ab7596e58c291b2",
|
||||||
"name":"imToken",
|
"name": "imToken",
|
||||||
"description":"",
|
"description": "",
|
||||||
"homepage":"https://token.im/",
|
"homepage": "https://token.im/",
|
||||||
"chains":[
|
"chains": [
|
||||||
"eip155:1"
|
"eip155:1"
|
||||||
],
|
],
|
||||||
"versions":[
|
"versions": [
|
||||||
"1"
|
"1"
|
||||||
],
|
],
|
||||||
"app":{
|
"app": {
|
||||||
"browser":"",
|
"browser": "",
|
||||||
"ios":"https://itunes.apple.com/us/app/imtoken2/id1384798940",
|
"ios": "https://itunes.apple.com/us/app/imtoken2/id1384798940",
|
||||||
"android":"https://play.google.com/store/apps/details?id=im.token.app",
|
"android": "https://play.google.com/store/apps/details?id=im.token.app",
|
||||||
"mac":"",
|
"mac": "",
|
||||||
"windows":"",
|
"windows": "",
|
||||||
"linux":""
|
"linux": ""
|
||||||
},
|
},
|
||||||
"mobile":{
|
"mobile": {
|
||||||
"native":"imtokenv2:",
|
"native": "imtokenv2:",
|
||||||
"universal":""
|
"universal": ""
|
||||||
},
|
},
|
||||||
"desktop":{
|
"desktop": {
|
||||||
"native":"",
|
"native": "",
|
||||||
"universal":""
|
"universal": ""
|
||||||
},
|
},
|
||||||
"metadata":{
|
"metadata": {
|
||||||
"shortName":"imToken",
|
"shortName": "imToken",
|
||||||
"colors":{
|
"colors": {
|
||||||
"primary":"rgb(255, 255, 255)",
|
"primary": "rgb(255, 255, 255)",
|
||||||
"secondary":""
|
"secondary": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"config": {
|
||||||
|
"comment": "imToken",
|
||||||
|
"iosMinVersion": "0",
|
||||||
|
"imageUrl": "",
|
||||||
|
"connections": [
|
||||||
|
{
|
||||||
|
"type": "walletConnectV2",
|
||||||
|
"native": "imtokenv2:",
|
||||||
|
"universal": ""
|
||||||
}
|
}
|
||||||
},
|
],
|
||||||
"config":{
|
"methods": [
|
||||||
"comment":"imToken",
|
"eth_sendTransaction",
|
||||||
"iosMinVersion":"0",
|
"personal_sign",
|
||||||
"imageUrl":"https://v4.testnet.dydx.exchange/wallets/imtoken.png",
|
"eth_signTypedData"
|
||||||
"image":"imtoken.png",
|
]
|
||||||
"connections":[
|
},
|
||||||
{
|
"userFields": {
|
||||||
"type":"walletConnect",
|
"analyticEvent": "IMTOKEN",
|
||||||
"native":"imtokenv2:",
|
"imageName": "imtoken.png"
|
||||||
"universal":""
|
}
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"userFields":{
|
|
||||||
"analyticEvent":"IMTOKEN"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id":"4622a2b2d6af1c9844944291e5e7351a6aa24cd7b23099efac1b2fd875da31a0",
|
"id": "4622a2b2d6af1c9844944291e5e7351a6aa24cd7b23099efac1b2fd875da31a0",
|
||||||
"name":"Trust Wallet",
|
"name": "Trust Wallet",
|
||||||
"description":"",
|
"description": "",
|
||||||
"homepage":"https://trustwallet.com/",
|
"homepage": "https://trustwallet.com/",
|
||||||
"chains":[
|
"chains": [
|
||||||
"eip155:1",
|
"eip155:1",
|
||||||
"eip155:42161",
|
"eip155:42161",
|
||||||
"eip155:43114"
|
"eip155:43114"
|
||||||
],
|
],
|
||||||
"versions":[
|
"versions": [
|
||||||
"1"
|
"1"
|
||||||
],
|
],
|
||||||
"app":{
|
"app": {
|
||||||
"browser":"",
|
"browser": "",
|
||||||
"ios":"https://apps.apple.com/app/apple-store/id1288339409",
|
"ios": "https://apps.apple.com/app/apple-store/id1288339409",
|
||||||
"android":"https://play.google.com/store/apps/details?id=com.wallet.crypto.trustapp",
|
"android": "https://play.google.com/store/apps/details?id=com.wallet.crypto.trustapp",
|
||||||
"mac":"",
|
"mac": "",
|
||||||
"windows":"",
|
"windows": "",
|
||||||
"linux":""
|
"linux": ""
|
||||||
},
|
},
|
||||||
"mobile":{
|
"mobile": {
|
||||||
"native":"trust:",
|
"native": "trust:",
|
||||||
"universal":"https://link.trustwallet.com"
|
"universal": "https://link.trustwallet.com"
|
||||||
},
|
},
|
||||||
"desktop":{
|
"desktop": {
|
||||||
"native":"",
|
"native": "",
|
||||||
"universal":""
|
"universal": ""
|
||||||
},
|
},
|
||||||
"metadata":{
|
"metadata": {
|
||||||
"shortName":"Trust",
|
"shortName": "Trust",
|
||||||
"colors":{
|
"colors": {
|
||||||
"primary":"rgb(51, 117, 187)",
|
"primary": "rgb(51, 117, 187)",
|
||||||
"secondary":""
|
"secondary": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"config": {
|
||||||
|
"comment": "Trust Wallet",
|
||||||
|
"iosMinVersion": "0",
|
||||||
|
"encoding": "=\"#%/<>?@\\^`{|}:&",
|
||||||
|
"imageUrl": "",
|
||||||
|
"connections": [
|
||||||
|
{
|
||||||
|
"type": "walletConnectV2",
|
||||||
|
"native": "trust:",
|
||||||
|
"universal": "https://link.trustwallet.com"
|
||||||
}
|
}
|
||||||
},
|
],
|
||||||
"config":{
|
"methods": [
|
||||||
"comment":"Trust Wallet",
|
"eth_sendTransaction",
|
||||||
"iosMinVersion":"0",
|
"personal_sign",
|
||||||
"encoding":"=\"#%/<>?@\\^`{|}:&",
|
"eth_signTypedData"
|
||||||
"imageUrl":"https://v4.testnet.dydx.exchange/wallets/trust-wallet.png",
|
]
|
||||||
"image":"trust-wallet.png",
|
},
|
||||||
"connections":[
|
"userFields": {
|
||||||
{
|
"analyticEvent": "TRUST_WALLET",
|
||||||
"type":"walletConnectV2",
|
"imageName": "trust-wallet.png"
|
||||||
"native":"trust:",
|
}
|
||||||
"universal":"https://link.trustwallet.com"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"userFields":{
|
|
||||||
"analyticEvent":"TRUST_WALLET"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id":"Zerion",
|
"id": "Zerion",
|
||||||
"name":"Zerion",
|
"name": "Zerion",
|
||||||
"description":"",
|
"description": "",
|
||||||
"homepage":"https://zerion.io/",
|
"homepage": "https://zerion.io/",
|
||||||
"chains":[
|
"chains": [
|
||||||
"eip155:1"
|
"eip155:1"
|
||||||
],
|
],
|
||||||
"versions":[
|
"versions": [
|
||||||
"1"
|
"1"
|
||||||
],
|
],
|
||||||
"app":{
|
"app": {
|
||||||
"browser":"",
|
"browser": "",
|
||||||
"ios":"https://apps.apple.com/app/apple-store/id1456732565",
|
"ios": "https://apps.apple.com/app/apple-store/id1456732565",
|
||||||
"android":"https://play.google.com/store/apps/details?id=io.zerion.android",
|
"android": "https://play.google.com/store/apps/details?id=io.zerion.android",
|
||||||
"mac":"",
|
"mac": "",
|
||||||
"windows":"",
|
"windows": "",
|
||||||
"linux":""
|
"linux": ""
|
||||||
},
|
},
|
||||||
"mobile":{
|
"mobile": {
|
||||||
"native":"zerion:",
|
"native": "zerion:",
|
||||||
"universal":""
|
"universal": ""
|
||||||
},
|
},
|
||||||
"desktop":{
|
"desktop": {
|
||||||
"native":"",
|
"native": "",
|
||||||
"universal":""
|
"universal": ""
|
||||||
},
|
},
|
||||||
"metadata":{
|
"metadata": {
|
||||||
"shortName":"Zerion",
|
"shortName": "Zerion",
|
||||||
"colors":{
|
"colors": {
|
||||||
"primary":"rgb(51, 117, 187)",
|
"primary": "rgb(51, 117, 187)",
|
||||||
"secondary":""
|
"secondary": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"config": {
|
||||||
|
"comment": "Zerion Wallet",
|
||||||
|
"iosMinVersion": "0",
|
||||||
|
"encoding": "=\"#%/<>?@\\^`{|}:&",
|
||||||
|
"imageUrl": "",
|
||||||
|
"connections": [
|
||||||
|
{
|
||||||
|
"type": "walletConnectV2",
|
||||||
|
"native": "zerion:",
|
||||||
|
"universal": ""
|
||||||
}
|
}
|
||||||
},
|
],
|
||||||
"config":{
|
"methods": [
|
||||||
"comment":"Zerion Wallet",
|
"eth_sendTransaction",
|
||||||
"iosMinVersion":"0",
|
"personal_sign",
|
||||||
"encoding":"=\"#%/<>?@\\^`{|}:&",
|
"eth_signTypedData"
|
||||||
"imageUrl":"https://v4.testnet.dydx.exchange/wallets/zerion.png",
|
]
|
||||||
"image":"zerion.png",
|
},
|
||||||
"connections":[
|
"userFields": {
|
||||||
{
|
"analyticEvent": "ZERION",
|
||||||
"type":"walletConnectV2",
|
"imageName": "zerion.png"
|
||||||
"native":"zerion:",
|
}
|
||||||
"universal":""
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"userFields":{
|
|
||||||
"analyticEvent":"ZERION"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id":"20459438007b75f4f4acb98bf29aa3b800550309646d375da5fd4aac6c2a2c66",
|
"id": "20459438007b75f4f4acb98bf29aa3b800550309646d375da5fd4aac6c2a2c66",
|
||||||
"name":"TokenPocket",
|
"name": "TokenPocket",
|
||||||
"description":"",
|
"description": "",
|
||||||
"homepage":"https://tokenpocket.pro/",
|
"homepage": "https://tokenpocket.pro/",
|
||||||
"chains":[
|
"chains": [
|
||||||
"eip155:1"
|
"eip155:1"
|
||||||
],
|
],
|
||||||
"versions":[
|
"versions": [
|
||||||
"1"
|
"1"
|
||||||
],
|
],
|
||||||
"app":{
|
"app": {
|
||||||
"browser":"",
|
"browser": "",
|
||||||
"ios":"https://apps.apple.com/us/app/tokenpocket-trusted-wallet/id1436028697",
|
"ios": "https://apps.apple.com/us/app/tokenpocket-trusted-wallet/id1436028697",
|
||||||
"android":"https://play.google.com/store/apps/details?id=vip.mytokenpocket",
|
"android": "https://play.google.com/store/apps/details?id=vip.mytokenpocket",
|
||||||
"mac":"",
|
"mac": "",
|
||||||
"windows":"",
|
"windows": "",
|
||||||
"linux":""
|
"linux": ""
|
||||||
},
|
},
|
||||||
"mobile":{
|
"mobile": {
|
||||||
"native":"tpoutside:",
|
"native": "tpoutside:",
|
||||||
"universal":""
|
"universal": ""
|
||||||
},
|
},
|
||||||
"desktop":{
|
"desktop": {
|
||||||
"native":"",
|
"native": "",
|
||||||
"universal":""
|
"universal": ""
|
||||||
},
|
},
|
||||||
"metadata":{
|
"metadata": {
|
||||||
"shortName":"TokenPocket",
|
"shortName": "TokenPocket",
|
||||||
"colors":{
|
"colors": {
|
||||||
"primary":"rgb(41, 128, 254)",
|
"primary": "rgb(41, 128, 254)",
|
||||||
"secondary":""
|
"secondary": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"config": {
|
||||||
|
"comment": "TokenPocket",
|
||||||
|
"iosMinVersion": "0",
|
||||||
|
"imageUrl": "",
|
||||||
|
"connections": [
|
||||||
|
{
|
||||||
|
"type": "walletConnectV2",
|
||||||
|
"native": "tpoutside:",
|
||||||
|
"universal": ""
|
||||||
}
|
}
|
||||||
},
|
],
|
||||||
"config":{
|
"methods": [
|
||||||
"comment":"TokenPocket",
|
"eth_sendTransaction",
|
||||||
"iosMinVersion":"0",
|
"personal_sign",
|
||||||
"imageUrl":"https://v4.testnet.dydx.exchange/wallets/tokenpocket.png",
|
"eth_signTypedData"
|
||||||
"image":"tokenpocket.png",
|
]
|
||||||
"connections":[
|
},
|
||||||
{
|
"userFields": {
|
||||||
"type":"walletConnect",
|
"analyticEvent": "TOKEN_POCKET",
|
||||||
"native":"tpoutside:",
|
"imageName": "tokenpocket.png"
|
||||||
"universal":""
|
}
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"userFields":{
|
|
||||||
"analyticEvent":"TOKEN_POCKET"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id":"1ae92b26df02f0abca6304df07debccd18262fdf5fe82daa81593582dac9a369",
|
"id": "1ae92b26df02f0abca6304df07debccd18262fdf5fe82daa81593582dac9a369",
|
||||||
"name":"Rainbow",
|
"name": "Rainbow",
|
||||||
"description":"",
|
"description": "",
|
||||||
"homepage":"https://rainbow.me/",
|
"homepage": "https://rainbow.me/",
|
||||||
"chains":[
|
"chains": [
|
||||||
"eip155:1"
|
"eip155:1"
|
||||||
],
|
],
|
||||||
"versions":[
|
"versions": [
|
||||||
"1"
|
"1"
|
||||||
],
|
],
|
||||||
"app":{
|
"app": {
|
||||||
"browser":"",
|
"browser": "",
|
||||||
"ios":"https://apps.apple.com/us/app/rainbow-ethereum-wallet/id1457119021",
|
"ios": "https://apps.apple.com/us/app/rainbow-ethereum-wallet/id1457119021",
|
||||||
"android":"",
|
"android": "",
|
||||||
"mac":"",
|
"mac": "",
|
||||||
"windows":"",
|
"windows": "",
|
||||||
"linux":""
|
"linux": ""
|
||||||
},
|
},
|
||||||
"mobile":{
|
"mobile": {
|
||||||
"native":"rainbow:",
|
"native": "rainbow:",
|
||||||
"universal":"https://rnbwapp.com"
|
"universal": "https://rnbwapp.com"
|
||||||
},
|
},
|
||||||
"desktop":{
|
"desktop": {
|
||||||
"native":"",
|
"native": "",
|
||||||
"universal":""
|
"universal": ""
|
||||||
},
|
},
|
||||||
"metadata":{
|
"metadata": {
|
||||||
"shortName":"Rainbow",
|
"shortName": "Rainbow",
|
||||||
"colors":{
|
"colors": {
|
||||||
"primary":"rgb(0, 30, 89)",
|
"primary": "rgb(0, 30, 89)",
|
||||||
"secondary":""
|
"secondary": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"config": {
|
||||||
|
"comment": "Rainbow",
|
||||||
|
"iosMinVersion": "0",
|
||||||
|
"encoding": "=\"#%/<>?@\\^`{|}:&",
|
||||||
|
"backlinked": true,
|
||||||
|
"imageUrl": "",
|
||||||
|
"connections": [
|
||||||
|
{
|
||||||
|
"type": "walletConnectV2",
|
||||||
|
"native": "rainbow:",
|
||||||
|
"universal": "https://rnbwapp.com"
|
||||||
}
|
}
|
||||||
},
|
],
|
||||||
"config":{
|
"methods": [
|
||||||
"comment":"Rainbow",
|
"eth_sendTransaction",
|
||||||
"iosMinVersion":"0",
|
"personal_sign",
|
||||||
"encoding":"=\"#%/<>?@\\^`{|}:&",
|
"eth_signTypedData"
|
||||||
"backlinked":true,
|
]
|
||||||
"imageUrl":"https://v4.testnet.dydx.exchange/wallets/rainbow-wallet.png",
|
},
|
||||||
"image":"rainbow-wallet.png",
|
"userFields": {
|
||||||
"connections":[
|
"analyticEvent": "RAINBOW_WALLET",
|
||||||
{
|
"imageName": "rainbow-wallet.png"
|
||||||
"type":"walletConnectV2",
|
}
|
||||||
"native":"rainbow:",
|
|
||||||
"universal":"https://rnbwapp.com"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"userFields":{
|
|
||||||
"analyticEvent":"RAINBOW_WALLET"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id":"09102e7bbbd3f92001eda104abe23803181629f695e8f1b95af96d88ff7d5890",
|
"id": "09102e7bbbd3f92001eda104abe23803181629f695e8f1b95af96d88ff7d5890",
|
||||||
"name":"1inch Wallet",
|
"name": "1inch Wallet",
|
||||||
"description":"",
|
"description": "",
|
||||||
"homepage":"https://1inch.io/wallet/",
|
"homepage": "https://1inch.io/wallet/",
|
||||||
"chains":[
|
"chains": [
|
||||||
"eip155:1",
|
"eip155:1",
|
||||||
"eip155:56"
|
"eip155:56"
|
||||||
],
|
],
|
||||||
"versions":[
|
"versions": [
|
||||||
"1"
|
"1"
|
||||||
],
|
],
|
||||||
"app":{
|
"app": {
|
||||||
"browser":"",
|
"browser": "",
|
||||||
"ios":"https://apps.apple.com/us/app/1inch-defi-wallet/id1546049391",
|
"ios": "https://apps.apple.com/us/app/1inch-defi-wallet/id1546049391",
|
||||||
"android":"",
|
"android": "",
|
||||||
"mac":"",
|
"mac": "",
|
||||||
"windows":"",
|
"windows": "",
|
||||||
"linux":""
|
"linux": ""
|
||||||
},
|
},
|
||||||
"mobile":{
|
"mobile": {
|
||||||
"native":"oneinch:",
|
"native": "oneinch:",
|
||||||
"universal":"https://wallet.1inch.io"
|
"universal": "https://wallet.1inch.io"
|
||||||
},
|
},
|
||||||
"desktop":{
|
"desktop": {
|
||||||
"native":"",
|
"native": "",
|
||||||
"universal":""
|
"universal": ""
|
||||||
},
|
},
|
||||||
"metadata":{
|
"metadata": {
|
||||||
"shortName":"1inch",
|
"shortName": "1inch",
|
||||||
"colors":{
|
"colors": {
|
||||||
"primary":"rgb(31, 36, 46)",
|
"primary": "rgb(31, 36, 46)",
|
||||||
"secondary":""
|
"secondary": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"config": {
|
||||||
|
"comment": "1inch",
|
||||||
|
"iosMinVersion": "0",
|
||||||
|
"encoding": "=\"#%/<>?@\\^`{|}:&",
|
||||||
|
"imageUrl": "",
|
||||||
|
"connections": [
|
||||||
|
{
|
||||||
|
"type": "walletConnectV2",
|
||||||
|
"native": "oneinch:",
|
||||||
|
"universal": "https://wallet.1inch.io"
|
||||||
}
|
}
|
||||||
},
|
],
|
||||||
"config":{
|
"methods": [
|
||||||
"comment":"1inch",
|
"eth_sendTransaction",
|
||||||
"iosMinVersion":"0",
|
"personal_sign",
|
||||||
"encoding":"=\"#%/<>?@\\^`{|}:&",
|
"eth_signTypedData"
|
||||||
"imageUrl":"https://v4.testnet.dydx.exchange/wallets/1inch.png",
|
]
|
||||||
"image":"1inch.png",
|
},
|
||||||
"connections":[
|
"userFields": {
|
||||||
{
|
"analyticEvent": "1INCH",
|
||||||
"type":"walletConnect",
|
"imageName": "1inch.png"
|
||||||
"native":"oneinch:",
|
}
|
||||||
"universal":"https://wallet.1inch.io"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"userFields":{
|
|
||||||
"analyticEvent":"1INCH"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id":"bae74827272509a6d63ea25514d9c68ad235c14e45e183518c7ded4572a1b0c4",
|
|
||||||
"name":"Huobi Wallet",
|
|
||||||
"description":"",
|
|
||||||
"homepage":"https://huobiwallet.com/",
|
|
||||||
"chains":[
|
|
||||||
"eip155:1"
|
|
||||||
],
|
|
||||||
"versions":[
|
|
||||||
"1"
|
|
||||||
],
|
|
||||||
"app":{
|
|
||||||
"browser":"",
|
|
||||||
"ios":"https://apps.apple.com/us/app/id1433883012",
|
|
||||||
"android":"https://play.google.com/store/apps/details?id=com.huobionchainwallet.gp",
|
|
||||||
"mac":"",
|
|
||||||
"windows":"",
|
|
||||||
"linux":""
|
|
||||||
},
|
|
||||||
"mobile":{
|
|
||||||
"native":"huobiwallet:",
|
|
||||||
"universal":""
|
|
||||||
},
|
|
||||||
"desktop":{
|
|
||||||
"native":"",
|
|
||||||
"universal":""
|
|
||||||
},
|
|
||||||
"metadata":{
|
|
||||||
"shortName":"Huobi",
|
|
||||||
"colors":{
|
|
||||||
"primary":"rgb(45,101,248)",
|
|
||||||
"secondary":""
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"config":{
|
|
||||||
"comment":"Huobi",
|
|
||||||
"iosMinVersion":"0",
|
|
||||||
"encoding":"=\"#%/<>?@\\^`{|}:&",
|
|
||||||
"imageUrl":"https://v4.testnet.dydx.exchange/wallets/huobi-wallet.png",
|
|
||||||
"image":"huobi-wallet.png",
|
|
||||||
"connections":[
|
|
||||||
{
|
|
||||||
"type":"walletConnect",
|
|
||||||
"native":"huobiwallet:",
|
|
||||||
"universal":""
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"userFields":{
|
|
||||||
"analyticEvent":"HUOBI_WALLET"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
|
After Width: | Height: | Size: 9.1 KiB |
|
Before Width: | Height: | Size: 1.5 MiB After Width: | Height: | Size: 1.2 MiB |
@@ -14,6 +14,7 @@ import { DialogAreaProvider, useDialogArea } from '@/hooks/useDialogArea';
|
|||||||
import { LocaleProvider } from '@/hooks/useLocaleSeparators';
|
import { LocaleProvider } from '@/hooks/useLocaleSeparators';
|
||||||
import { NotificationsProvider } from '@/hooks/useNotifications';
|
import { NotificationsProvider } from '@/hooks/useNotifications';
|
||||||
import { LocalNotificationsProvider } from '@/hooks/useLocalNotifications';
|
import { LocalNotificationsProvider } from '@/hooks/useLocalNotifications';
|
||||||
|
import { RestrictionProvider } from '@/hooks/useRestrictions';
|
||||||
import { SubaccountProvider } from '@/hooks/useSubaccount';
|
import { SubaccountProvider } from '@/hooks/useSubaccount';
|
||||||
import { SquidProvider } from '@/hooks/useSquid';
|
import { SquidProvider } from '@/hooks/useSquid';
|
||||||
|
|
||||||
@@ -66,6 +67,7 @@ const Content = () => {
|
|||||||
<Route path=":market" element={<TradePage />} />
|
<Route path=":market" element={<TradePage />} />
|
||||||
<Route path={AppRoute.Trade} element={<TradePage />} />
|
<Route path={AppRoute.Trade} element={<TradePage />} />
|
||||||
</Route>
|
</Route>
|
||||||
|
|
||||||
<Route path={AppRoute.Markets} element={<MarketsPage />} />
|
<Route path={AppRoute.Markets} element={<MarketsPage />} />
|
||||||
<Route path={AppRoute.Rewards} element={<RewardsPage />} />
|
<Route path={AppRoute.Rewards} element={<RewardsPage />} />
|
||||||
{isTablet && (
|
{isTablet && (
|
||||||
@@ -79,6 +81,7 @@ const Content = () => {
|
|||||||
<Route element={<GuardedMobileRoute />}>
|
<Route element={<GuardedMobileRoute />}>
|
||||||
<Route path={`${AppRoute.Portfolio}/*`} element={<PortfolioPage />} />
|
<Route path={`${AppRoute.Portfolio}/*`} element={<PortfolioPage />} />
|
||||||
</Route>
|
</Route>
|
||||||
|
|
||||||
<Route path="*" element={<Navigate to={DEFAULT_TRADE_ROUTE} replace />} />
|
<Route path="*" element={<Navigate to={DEFAULT_TRADE_ROUTE} replace />} />
|
||||||
</Routes>
|
</Routes>
|
||||||
</Suspense>
|
</Suspense>
|
||||||
@@ -109,6 +112,7 @@ const providers = [
|
|||||||
wrapProvider(GrazProvider),
|
wrapProvider(GrazProvider),
|
||||||
wrapProvider(WagmiConfig, { config }),
|
wrapProvider(WagmiConfig, { config }),
|
||||||
wrapProvider(LocaleProvider),
|
wrapProvider(LocaleProvider),
|
||||||
|
wrapProvider(RestrictionProvider),
|
||||||
wrapProvider(DydxProvider),
|
wrapProvider(DydxProvider),
|
||||||
wrapProvider(AccountsProvider),
|
wrapProvider(AccountsProvider),
|
||||||
wrapProvider(SubaccountProvider),
|
wrapProvider(SubaccountProvider),
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ import {
|
|||||||
AddressConnectorIcon,
|
AddressConnectorIcon,
|
||||||
ArrowIcon,
|
ArrowIcon,
|
||||||
Bar3Icon,
|
Bar3Icon,
|
||||||
|
BellIcon,
|
||||||
|
BellStrokeIcon,
|
||||||
BoxCloseIcon,
|
BoxCloseIcon,
|
||||||
CalculatorIcon,
|
CalculatorIcon,
|
||||||
CaretIcon,
|
CaretIcon,
|
||||||
@@ -71,6 +73,8 @@ export enum IconName {
|
|||||||
AddressConnector = 'AddressConnector',
|
AddressConnector = 'AddressConnector',
|
||||||
Arrow = 'Arrow',
|
Arrow = 'Arrow',
|
||||||
Bar3 = 'Bar3',
|
Bar3 = 'Bar3',
|
||||||
|
Bell = 'Bell',
|
||||||
|
BellStroked = 'BellStroked',
|
||||||
BoxClose = 'BoxClose',
|
BoxClose = 'BoxClose',
|
||||||
Calculator = 'Calculator',
|
Calculator = 'Calculator',
|
||||||
Caret = 'Caret',
|
Caret = 'Caret',
|
||||||
@@ -137,6 +141,8 @@ const icons = {
|
|||||||
[IconName.AddressConnector]: AddressConnectorIcon,
|
[IconName.AddressConnector]: AddressConnectorIcon,
|
||||||
[IconName.Arrow]: ArrowIcon,
|
[IconName.Arrow]: ArrowIcon,
|
||||||
[IconName.Bar3]: Bar3Icon,
|
[IconName.Bar3]: Bar3Icon,
|
||||||
|
[IconName.Bell]: BellIcon,
|
||||||
|
[IconName.BellStroked]: BellStrokeIcon,
|
||||||
[IconName.BoxClose]: BoxCloseIcon,
|
[IconName.BoxClose]: BoxCloseIcon,
|
||||||
[IconName.Calculator]: CalculatorIcon,
|
[IconName.Calculator]: CalculatorIcon,
|
||||||
[IconName.Caret]: CaretIcon,
|
[IconName.Caret]: CaretIcon,
|
||||||
@@ -213,7 +219,8 @@ export const Icon = styled(
|
|||||||
iconComponent: Component = iconName && icons[iconName],
|
iconComponent: Component = iconName && icons[iconName],
|
||||||
className,
|
className,
|
||||||
...props
|
...props
|
||||||
}: ElementProps & StyleProps) => (Component ? <Component className={className} {...props} /> : null)
|
}: ElementProps & StyleProps) =>
|
||||||
|
Component ? <Component className={className} {...props} /> : null
|
||||||
)`
|
)`
|
||||||
width: 1em;
|
width: 1em;
|
||||||
height: 1em;
|
height: 1em;
|
||||||
|
|||||||
@@ -207,6 +207,16 @@ const InputStyle = css`
|
|||||||
color: var(--color-text-0);
|
color: var(--color-text-0);
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Input autofill Styles
|
||||||
|
&:-webkit-autofill,
|
||||||
|
&:-webkit-autofill:focus {
|
||||||
|
transition: background-color 600000s 0s, color 600000s 0s;
|
||||||
|
}
|
||||||
|
|
||||||
|
&[data-autocompleted] {
|
||||||
|
background-color: var(--input-backgroundColor) !important;
|
||||||
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
Styled.NumericFormat = styled(NumericFormat)`
|
Styled.NumericFormat = styled(NumericFormat)`
|
||||||
|
|||||||
@@ -59,16 +59,6 @@ export const TransactionType = Abacus.exchange.dydx.abacus.protocols.Transaction
|
|||||||
const transactionTypes = [...TransactionType.values()] as const;
|
const transactionTypes = [...TransactionType.values()] as const;
|
||||||
export type TransactionTypes = (typeof transactionTypes)[number];
|
export type TransactionTypes = (typeof transactionTypes)[number];
|
||||||
|
|
||||||
export type NetworkConfig = {
|
|
||||||
chainId: string;
|
|
||||||
indexerUrl: string;
|
|
||||||
indexerSocketUrl: string;
|
|
||||||
validatorUrl: string;
|
|
||||||
faucetUrl?: string | null;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type ConnectNetworkEvent = CustomEvent<Partial<NetworkConfig>>;
|
|
||||||
|
|
||||||
// ------ State ------
|
// ------ State ------
|
||||||
export type AbacusApiState = Abacus.exchange.dydx.abacus.state.manager.ApiState;
|
export type AbacusApiState = Abacus.exchange.dydx.abacus.state.manager.ApiState;
|
||||||
export const AbacusApiStatus = Abacus.exchange.dydx.abacus.state.manager.ApiStatus;
|
export const AbacusApiStatus = Abacus.exchange.dydx.abacus.state.manager.ApiStatus;
|
||||||
@@ -78,8 +68,13 @@ export const Changes = Abacus.exchange.dydx.abacus.state.changes.Changes;
|
|||||||
export type PerpetualStateChanges = Abacus.exchange.dydx.abacus.state.changes.StateChanges;
|
export type PerpetualStateChanges = Abacus.exchange.dydx.abacus.state.changes.StateChanges;
|
||||||
export const AsyncAbacusStateManager =
|
export const AsyncAbacusStateManager =
|
||||||
Abacus.exchange.dydx.abacus.state.manager.AsyncAbacusStateManager;
|
Abacus.exchange.dydx.abacus.state.manager.AsyncAbacusStateManager;
|
||||||
|
|
||||||
|
// ------ Parsing Errors ------ //
|
||||||
export type ParsingError = Abacus.exchange.dydx.abacus.responses.ParsingError;
|
export type ParsingError = Abacus.exchange.dydx.abacus.responses.ParsingError;
|
||||||
export type ParsingErrors = kollections.List<ParsingError>;
|
export type ParsingErrors = kollections.List<ParsingError>;
|
||||||
|
export const ParsingErrorType = Abacus.exchange.dydx.abacus.responses.ParsingErrorType;
|
||||||
|
const parsingErrorTypes = [...ParsingErrorType.values()] as const;
|
||||||
|
export type ParsingErrorTypes = (typeof parsingErrorTypes)[number];
|
||||||
|
|
||||||
// ------ Perpetuals/Markets ------ //
|
// ------ Perpetuals/Markets ------ //
|
||||||
export type PerpetualState = Abacus.exchange.dydx.abacus.output.PerpetualState;
|
export type PerpetualState = Abacus.exchange.dydx.abacus.output.PerpetualState;
|
||||||
@@ -199,6 +194,12 @@ export type RiskLevels = (typeof riskLevels)[number];
|
|||||||
// ------ Notifications ------ //
|
// ------ Notifications ------ //
|
||||||
export type AbacusNotification = Abacus.exchange.dydx.abacus.output.Notification;
|
export type AbacusNotification = Abacus.exchange.dydx.abacus.output.Notification;
|
||||||
|
|
||||||
|
// ------ Restrictions ------ //
|
||||||
|
export type UsageRestriction = Abacus.exchange.dydx.abacus.output.UsageRestriction;
|
||||||
|
export const RestrictionType = Abacus.exchange.dydx.abacus.output.Restriction;
|
||||||
|
const restrictionTypes = [...RestrictionType.values()] as const;
|
||||||
|
export type RestrictionTypes = (typeof restrictionTypes)[number];
|
||||||
|
|
||||||
// ------ Enum Conversions ------ //
|
// ------ Enum Conversions ------ //
|
||||||
type IfEquals<X, Y, A, B> = (<T>() => T extends X ? 1 : 2) extends <T>() => T extends Y ? 1 : 2
|
type IfEquals<X, Y, A, B> = (<T>() => T extends X ? 1 : 2) extends <T>() => T extends Y ? 1 : 2
|
||||||
? A
|
? A
|
||||||
@@ -256,3 +257,20 @@ export const TRADE_TYPES: Record<
|
|||||||
[AbacusOrderType.liquidation.name]: null,
|
[AbacusOrderType.liquidation.name]: null,
|
||||||
[AbacusOrderType.trailingStop.name]: null,
|
[AbacusOrderType.trailingStop.name]: null,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Custom types involving Abacus
|
||||||
|
|
||||||
|
export type NetworkConfig = Partial<{
|
||||||
|
indexerUrl: Nullable<string>;
|
||||||
|
websocketUrl: Nullable<string>;
|
||||||
|
validatorUrl: Nullable<string>;
|
||||||
|
chainId: Nullable<string>;
|
||||||
|
faucetUrl: Nullable<string>;
|
||||||
|
USDC_DENOM: Nullable<string>;
|
||||||
|
USDC_DECIMALS: Nullable<number>;
|
||||||
|
USDC_GAS_DENOM: Nullable<string>;
|
||||||
|
CHAINTOKEN_DENOM: Nullable<string>;
|
||||||
|
CHAINTOKEN_DECIMALS: Nullable<number>;
|
||||||
|
}>;
|
||||||
|
|
||||||
|
export type ConnectNetworkEvent = CustomEvent<Partial<NetworkConfig>>;
|
||||||
|
|||||||
@@ -10,7 +10,10 @@ export enum DialogTypes {
|
|||||||
MobileSignIn = 'MobileSignIn',
|
MobileSignIn = 'MobileSignIn',
|
||||||
Onboarding = 'Onboarding',
|
Onboarding = 'Onboarding',
|
||||||
OrderDetails = 'OrderDetails',
|
OrderDetails = 'OrderDetails',
|
||||||
|
RateLimit = 'RateLimit',
|
||||||
Receive = 'Receive',
|
Receive = 'Receive',
|
||||||
|
RestrictedGeo = 'RestrictedGeo',
|
||||||
|
RestrictedWallet = 'RestrictedWallet',
|
||||||
Trade = 'Trade',
|
Trade = 'Trade',
|
||||||
Transfer = 'Transfer',
|
Transfer = 'Transfer',
|
||||||
Withdraw = 'Withdraw',
|
Withdraw = 'Withdraw',
|
||||||
|
|||||||
@@ -24,6 +24,6 @@ export enum LocalStorageKey {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const LOCAL_STORAGE_VERSIONS = {
|
export const LOCAL_STORAGE_VERSIONS = {
|
||||||
[LocalStorageKey.EvmDerivedAddresses]: 'v1',
|
[LocalStorageKey.EvmDerivedAddresses]: 'v2',
|
||||||
// TODO: version all localStorage keys
|
// TODO: version all localStorage keys
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -32,7 +32,6 @@ export enum WalletConnectionType {
|
|||||||
CoinbaseWalletSdk = 'coinbaseWalletSdk',
|
CoinbaseWalletSdk = 'coinbaseWalletSdk',
|
||||||
CosmosSigner = 'CosmosSigner',
|
CosmosSigner = 'CosmosSigner',
|
||||||
InjectedEip1193 = 'injectedEip1193',
|
InjectedEip1193 = 'injectedEip1193',
|
||||||
WalletConnect1 = 'walletConnect1',
|
|
||||||
WalletConnect2 = 'walletConnect2',
|
WalletConnect2 = 'walletConnect2',
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -62,10 +61,6 @@ export const walletConnectionTypes: Record<WalletConnectionType, WalletConnectio
|
|||||||
name: 'injected EIP-1193 provider',
|
name: 'injected EIP-1193 provider',
|
||||||
wagmiConnectorId: 'injected',
|
wagmiConnectorId: 'injected',
|
||||||
},
|
},
|
||||||
[WalletConnectionType.WalletConnect1]: {
|
|
||||||
name: 'WalletConnect 1.0',
|
|
||||||
wagmiConnectorId: 'walletConnectLegacy',
|
|
||||||
},
|
|
||||||
[WalletConnectionType.WalletConnect2]: {
|
[WalletConnectionType.WalletConnect2]: {
|
||||||
name: 'WalletConnect 2.0',
|
name: 'WalletConnect 2.0',
|
||||||
wagmiConnectorId: 'walletConnect',
|
wagmiConnectorId: 'walletConnect',
|
||||||
@@ -92,19 +87,35 @@ export enum WalletType {
|
|||||||
Rainbow = 'RAINBOW_WALLET',
|
Rainbow = 'RAINBOW_WALLET',
|
||||||
TokenPocket = 'TOKEN_POCKET',
|
TokenPocket = 'TOKEN_POCKET',
|
||||||
TrustWallet = 'TRUST_WALLET',
|
TrustWallet = 'TRUST_WALLET',
|
||||||
WalletConnect = 'WALLETCONNECT',
|
|
||||||
WalletConnect2 = 'WALLETCONNECT_2',
|
WalletConnect2 = 'WALLETCONNECT_2',
|
||||||
// TestWallet = 'TEST_WALLET',
|
// TestWallet = 'TEST_WALLET',
|
||||||
OtherWallet = 'OTHER_WALLET',
|
OtherWallet = 'OTHER_WALLET',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const WALLET_CONNECT_EXPLORER_RECOMMENDED_WALLETS = {
|
||||||
|
Metamask: 'c57ca95b47569778a828d19178114f4db188b89b763c899ba0be274e97267d96',
|
||||||
|
imToken: 'ef333840daf915aafdc4a004525502d6d49d77bd9c65e0642dbaefb3c2893bef',
|
||||||
|
TokenPocket: '20459438007b75f4f4acb98bf29aa3b800550309646d375da5fd4aac6c2a2c66',
|
||||||
|
Trust: '4622a2b2d6af1c9844944291e5e7351a6aa24cd7b23099efac1b2fd875da31a0',
|
||||||
|
Rainbow: '1ae92b26df02f0abca6304df07debccd18262fdf5fe82daa81593582dac9a369',
|
||||||
|
Zerion: 'ecc4036f814562b41a5268adc86270fba1365471402006302e70169465b7ac18',
|
||||||
|
Ledger: '19177a98252e07ddfc9af2083ba8e07ef627cb6103467ffebb3f8f4205fd7927',
|
||||||
|
Fireblocks: '5864e2ced7c293ed18ac35e0db085c09ed567d67346ccb6f58a0327a75137489',
|
||||||
|
Uniswap: 'c03dfee351b6fcc421b4494ea33b9d4b92a984f87aa76d1663bb28705e95034a',
|
||||||
|
Robinhood: '8837dd9413b1d9b585ee937d27a816590248386d9dbf59f5cd3422dbbb65683e',
|
||||||
|
'1inch': 'c286eebc742a537cd1d6818363e9dc53b21759a1e8e5d9b263d0c03ec7703576',
|
||||||
|
};
|
||||||
|
|
||||||
|
export const WALLET_CONNECT_EXPLORER_RECOMMENDED_IDS = Object.values(
|
||||||
|
WALLET_CONNECT_EXPLORER_RECOMMENDED_WALLETS
|
||||||
|
);
|
||||||
|
|
||||||
type WalletConfig = {
|
type WalletConfig = {
|
||||||
type: WalletType;
|
type: WalletType;
|
||||||
stringKey: string;
|
stringKey: string;
|
||||||
icon: string;
|
icon: string;
|
||||||
connectionTypes: WalletConnectionType[];
|
connectionTypes: WalletConnectionType[];
|
||||||
matchesInjectedEip1193?: (provider: ExternalProvider & any) => boolean;
|
matchesInjectedEip1193?: (provider: ExternalProvider & any) => boolean;
|
||||||
walletconnect1Name?: string;
|
|
||||||
walletconnect2Id?: string;
|
walletconnect2Id?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -117,7 +128,6 @@ export const wallets: Record<WalletType, WalletConfig> = {
|
|||||||
WalletConnectionType.InjectedEip1193,
|
WalletConnectionType.InjectedEip1193,
|
||||||
// WalletConnectionType.CoinbaseWalletSdk,
|
// WalletConnectionType.CoinbaseWalletSdk,
|
||||||
WalletConnectionType.WalletConnect2,
|
WalletConnectionType.WalletConnect2,
|
||||||
WalletConnectionType.WalletConnect1,
|
|
||||||
],
|
],
|
||||||
matchesInjectedEip1193: (provider) =>
|
matchesInjectedEip1193: (provider) =>
|
||||||
Object.entries(wallets).every(
|
Object.entries(wallets).every(
|
||||||
@@ -131,30 +141,22 @@ export const wallets: Record<WalletType, WalletConfig> = {
|
|||||||
type: WalletType.BitKeep,
|
type: WalletType.BitKeep,
|
||||||
stringKey: STRING_KEYS.BITKEEP,
|
stringKey: STRING_KEYS.BITKEEP,
|
||||||
icon: BitkeepIcon,
|
icon: BitkeepIcon,
|
||||||
connectionTypes: [
|
connectionTypes: [WalletConnectionType.InjectedEip1193, WalletConnectionType.WalletConnect2],
|
||||||
WalletConnectionType.InjectedEip1193,
|
|
||||||
WalletConnectionType.WalletConnect2,
|
|
||||||
WalletConnectionType.WalletConnect1,
|
|
||||||
],
|
|
||||||
matchesInjectedEip1193: (provider) => provider.isBitKeep, // isBitKeepChrome, isBitEthereum
|
matchesInjectedEip1193: (provider) => provider.isBitKeep, // isBitKeepChrome, isBitEthereum
|
||||||
walletconnect1Name: 'bitkeep',
|
|
||||||
walletconnect2Id: '38f5d18bd8522c244bdd70cb4a68e0e718865155811c043f052fb9f1c51de662',
|
|
||||||
},
|
},
|
||||||
[WalletType.BitPie]: {
|
[WalletType.BitPie]: {
|
||||||
type: WalletType.BitPie,
|
type: WalletType.BitPie,
|
||||||
stringKey: STRING_KEYS.BITPIE,
|
stringKey: STRING_KEYS.BITPIE,
|
||||||
icon: BitpieIcon,
|
icon: BitpieIcon,
|
||||||
connectionTypes: [WalletConnectionType.InjectedEip1193, WalletConnectionType.WalletConnect1],
|
connectionTypes: [WalletConnectionType.InjectedEip1193],
|
||||||
matchesInjectedEip1193: (provider) => provider.isBitpie,
|
matchesInjectedEip1193: (provider) => provider.isBitpie,
|
||||||
walletconnect1Name: 'bitpie',
|
|
||||||
},
|
},
|
||||||
[WalletType.CloverWallet]: {
|
[WalletType.CloverWallet]: {
|
||||||
type: WalletType.CloverWallet,
|
type: WalletType.CloverWallet,
|
||||||
stringKey: STRING_KEYS.CLOVER_WALLET,
|
stringKey: STRING_KEYS.CLOVER_WALLET,
|
||||||
icon: CloverWalletIcon,
|
icon: CloverWalletIcon,
|
||||||
connectionTypes: [WalletConnectionType.InjectedEip1193, WalletConnectionType.WalletConnect1],
|
connectionTypes: [WalletConnectionType.InjectedEip1193],
|
||||||
matchesInjectedEip1193: (provider) => provider.isClover,
|
matchesInjectedEip1193: (provider) => provider.isClover,
|
||||||
// walletconnect1Name: 'clover',
|
|
||||||
},
|
},
|
||||||
[WalletType.CoinbaseWallet]: {
|
[WalletType.CoinbaseWallet]: {
|
||||||
type: WalletType.CoinbaseWallet,
|
type: WalletType.CoinbaseWallet,
|
||||||
@@ -163,109 +165,71 @@ export const wallets: Record<WalletType, WalletConfig> = {
|
|||||||
connectionTypes: [
|
connectionTypes: [
|
||||||
WalletConnectionType.CoinbaseWalletSdk,
|
WalletConnectionType.CoinbaseWalletSdk,
|
||||||
WalletConnectionType.InjectedEip1193,
|
WalletConnectionType.InjectedEip1193,
|
||||||
WalletConnectionType.WalletConnect1,
|
WalletConnectionType.WalletConnect2,
|
||||||
],
|
],
|
||||||
matchesInjectedEip1193: (provider) => provider.isCoinbaseWallet, // provider.selectedProvider?.isCoinbaseWallet,
|
matchesInjectedEip1193: (provider) => provider.isCoinbaseWallet, // provider.selectedProvider?.isCoinbaseWallet,
|
||||||
walletconnect1Name: 'coinbase',
|
|
||||||
},
|
},
|
||||||
[WalletType.Coin98]: {
|
[WalletType.Coin98]: {
|
||||||
type: WalletType.Coin98,
|
type: WalletType.Coin98,
|
||||||
stringKey: STRING_KEYS.COIN98,
|
stringKey: STRING_KEYS.COIN98,
|
||||||
icon: Coin98Icon,
|
icon: Coin98Icon,
|
||||||
connectionTypes: [
|
connectionTypes: [WalletConnectionType.InjectedEip1193, WalletConnectionType.WalletConnect2],
|
||||||
WalletConnectionType.InjectedEip1193,
|
|
||||||
WalletConnectionType.WalletConnect2,
|
|
||||||
WalletConnectionType.WalletConnect1,
|
|
||||||
],
|
|
||||||
matchesInjectedEip1193: (provider) => provider.isCoin98,
|
matchesInjectedEip1193: (provider) => provider.isCoin98,
|
||||||
walletconnect1Name: 'coin98',
|
|
||||||
walletconnect2Id: '2a3c89040ac3b723a1972a33a125b1db11e258a6975d3a61252cd64e6ea5ea01',
|
|
||||||
},
|
},
|
||||||
[WalletType.HuobiWallet]: {
|
[WalletType.HuobiWallet]: {
|
||||||
type: WalletType.HuobiWallet,
|
type: WalletType.HuobiWallet,
|
||||||
stringKey: STRING_KEYS.HUOBI_WALLET,
|
stringKey: STRING_KEYS.HUOBI_WALLET,
|
||||||
icon: HuobiIcon,
|
icon: HuobiIcon,
|
||||||
connectionTypes: [
|
connectionTypes: [WalletConnectionType.InjectedEip1193, WalletConnectionType.WalletConnect2],
|
||||||
WalletConnectionType.InjectedEip1193,
|
|
||||||
WalletConnectionType.WalletConnect2,
|
|
||||||
WalletConnectionType.WalletConnect1,
|
|
||||||
],
|
|
||||||
matchesInjectedEip1193: (provider) => provider.isHbWallet,
|
matchesInjectedEip1193: (provider) => provider.isHbWallet,
|
||||||
walletconnect2Id: '797c615e2c556b610c048eb35535f212c0dd58de5d03e763120e90a7d1350a77',
|
|
||||||
},
|
},
|
||||||
[WalletType.ImToken]: {
|
[WalletType.ImToken]: {
|
||||||
type: WalletType.ImToken,
|
type: WalletType.ImToken,
|
||||||
stringKey: STRING_KEYS.IMTOKEN,
|
stringKey: STRING_KEYS.IMTOKEN,
|
||||||
icon: ImTokenIcon,
|
icon: ImTokenIcon,
|
||||||
connectionTypes: [
|
connectionTypes: [WalletConnectionType.InjectedEip1193, WalletConnectionType.WalletConnect2],
|
||||||
WalletConnectionType.InjectedEip1193,
|
|
||||||
WalletConnectionType.WalletConnect2,
|
|
||||||
WalletConnectionType.WalletConnect1,
|
|
||||||
],
|
|
||||||
matchesInjectedEip1193: (provider) => provider.isImToken,
|
matchesInjectedEip1193: (provider) => provider.isImToken,
|
||||||
walletconnect1Name: 'imtoken',
|
walletconnect2Id: WALLET_CONNECT_EXPLORER_RECOMMENDED_WALLETS.imToken,
|
||||||
walletconnect2Id: 'ef333840daf915aafdc4a004525502d6d49d77bd9c65e0642dbaefb3c2893bef',
|
|
||||||
},
|
},
|
||||||
[WalletType.MathWallet]: {
|
[WalletType.MathWallet]: {
|
||||||
type: WalletType.MathWallet,
|
type: WalletType.MathWallet,
|
||||||
stringKey: STRING_KEYS.MATH_WALLET,
|
stringKey: STRING_KEYS.MATH_WALLET,
|
||||||
icon: MathWalletIcon,
|
icon: MathWalletIcon,
|
||||||
connectionTypes: [WalletConnectionType.InjectedEip1193, WalletConnectionType.WalletConnect1],
|
connectionTypes: [WalletConnectionType.InjectedEip1193],
|
||||||
matchesInjectedEip1193: (provider) => provider.isMathWallet,
|
matchesInjectedEip1193: (provider) => provider.isMathWallet,
|
||||||
walletconnect1Name: 'math',
|
|
||||||
walletconnect2Id: '7674bb4e353bf52886768a3ddc2a4562ce2f4191c80831291218ebd90f5f5e26',
|
walletconnect2Id: '7674bb4e353bf52886768a3ddc2a4562ce2f4191c80831291218ebd90f5f5e26',
|
||||||
},
|
},
|
||||||
[WalletType.MetaMask]: {
|
[WalletType.MetaMask]: {
|
||||||
type: WalletType.MetaMask,
|
type: WalletType.MetaMask,
|
||||||
stringKey: STRING_KEYS.METAMASK,
|
stringKey: STRING_KEYS.METAMASK,
|
||||||
icon: MetaMaskIcon,
|
icon: MetaMaskIcon,
|
||||||
connectionTypes: [
|
connectionTypes: [WalletConnectionType.InjectedEip1193, WalletConnectionType.WalletConnect2],
|
||||||
WalletConnectionType.InjectedEip1193,
|
|
||||||
WalletConnectionType.WalletConnect2,
|
|
||||||
WalletConnectionType.WalletConnect1,
|
|
||||||
],
|
|
||||||
matchesInjectedEip1193: isMetaMask,
|
matchesInjectedEip1193: isMetaMask,
|
||||||
walletconnect1Name: 'metamask',
|
walletconnect2Id: WALLET_CONNECT_EXPLORER_RECOMMENDED_WALLETS.Metamask,
|
||||||
walletconnect2Id: 'c57ca95b47569778a828d19178114f4db188b89b763c899ba0be274e97267d96',
|
|
||||||
},
|
},
|
||||||
[WalletType.Rainbow]: {
|
[WalletType.Rainbow]: {
|
||||||
type: WalletType.Rainbow,
|
type: WalletType.Rainbow,
|
||||||
stringKey: STRING_KEYS.RAINBOW_WALLET,
|
stringKey: STRING_KEYS.RAINBOW_WALLET,
|
||||||
icon: RainbowIcon,
|
icon: RainbowIcon,
|
||||||
connectionTypes: [
|
connectionTypes: [WalletConnectionType.InjectedEip1193, WalletConnectionType.WalletConnect2],
|
||||||
WalletConnectionType.InjectedEip1193,
|
|
||||||
WalletConnectionType.WalletConnect2,
|
|
||||||
WalletConnectionType.WalletConnect1,
|
|
||||||
],
|
|
||||||
matchesInjectedEip1193: (provider) => provider.isRainbowWallet,
|
matchesInjectedEip1193: (provider) => provider.isRainbowWallet,
|
||||||
walletconnect1Name: 'rainbow',
|
walletconnect2Id: WALLET_CONNECT_EXPLORER_RECOMMENDED_WALLETS.Rainbow,
|
||||||
walletconnect2Id: '1ae92b26df02f0abca6304df07debccd18262fdf5fe82daa81593582dac9a369',
|
|
||||||
},
|
},
|
||||||
[WalletType.TokenPocket]: {
|
[WalletType.TokenPocket]: {
|
||||||
type: WalletType.TokenPocket,
|
type: WalletType.TokenPocket,
|
||||||
stringKey: STRING_KEYS.TOKEN_POCKET,
|
stringKey: STRING_KEYS.TOKEN_POCKET,
|
||||||
icon: TokenPocketIcon,
|
icon: TokenPocketIcon,
|
||||||
connectionTypes: [
|
connectionTypes: [WalletConnectionType.InjectedEip1193, WalletConnectionType.WalletConnect2],
|
||||||
WalletConnectionType.InjectedEip1193,
|
|
||||||
WalletConnectionType.WalletConnect2,
|
|
||||||
WalletConnectionType.WalletConnect1,
|
|
||||||
],
|
|
||||||
matchesInjectedEip1193: (provider) => provider.isTokenPocket,
|
matchesInjectedEip1193: (provider) => provider.isTokenPocket,
|
||||||
walletconnect1Name: 'tokenpocket',
|
walletconnect2Id: WALLET_CONNECT_EXPLORER_RECOMMENDED_WALLETS.TokenPocket,
|
||||||
walletconnect2Id: '20459438007b75f4f4acb98bf29aa3b800550309646d375da5fd4aac6c2a2c66',
|
|
||||||
},
|
},
|
||||||
[WalletType.TrustWallet]: {
|
[WalletType.TrustWallet]: {
|
||||||
type: WalletType.TrustWallet,
|
type: WalletType.TrustWallet,
|
||||||
stringKey: STRING_KEYS.TRUST_WALLET,
|
stringKey: STRING_KEYS.TRUST_WALLET,
|
||||||
icon: TrustWalletIcon,
|
icon: TrustWalletIcon,
|
||||||
connectionTypes: [
|
connectionTypes: [WalletConnectionType.InjectedEip1193, WalletConnectionType.WalletConnect2],
|
||||||
WalletConnectionType.InjectedEip1193,
|
|
||||||
WalletConnectionType.WalletConnect2,
|
|
||||||
WalletConnectionType.WalletConnect1,
|
|
||||||
],
|
|
||||||
matchesInjectedEip1193: (provider) => provider.isTrust,
|
matchesInjectedEip1193: (provider) => provider.isTrust,
|
||||||
walletconnect1Name: 'trust',
|
walletconnect2Id: WALLET_CONNECT_EXPLORER_RECOMMENDED_WALLETS.Trust,
|
||||||
walletconnect2Id: '4622a2b2d6af1c9844944291e5e7351a6aa24cd7b23099efac1b2fd875da31a0',
|
|
||||||
},
|
},
|
||||||
[WalletType.WalletConnect2]: {
|
[WalletType.WalletConnect2]: {
|
||||||
type: WalletType.WalletConnect2,
|
type: WalletType.WalletConnect2,
|
||||||
@@ -273,12 +237,6 @@ export const wallets: Record<WalletType, WalletConfig> = {
|
|||||||
icon: WalletConnectIcon,
|
icon: WalletConnectIcon,
|
||||||
connectionTypes: [WalletConnectionType.WalletConnect2],
|
connectionTypes: [WalletConnectionType.WalletConnect2],
|
||||||
},
|
},
|
||||||
[WalletType.WalletConnect]: {
|
|
||||||
type: WalletType.WalletConnect,
|
|
||||||
stringKey: STRING_KEYS.WALLET_CONNECT,
|
|
||||||
icon: WalletConnectIcon,
|
|
||||||
connectionTypes: [WalletConnectionType.WalletConnect1],
|
|
||||||
},
|
|
||||||
[WalletType.Keplr]: {
|
[WalletType.Keplr]: {
|
||||||
type: WalletType.Keplr,
|
type: WalletType.Keplr,
|
||||||
stringKey: STRING_KEYS.KEPLR,
|
stringKey: STRING_KEYS.KEPLR,
|
||||||
@@ -344,10 +302,10 @@ export type DydxAddress = `dydx${string}`;
|
|||||||
export const DYDX_CHAIN_INFO: Parameters<typeof suggestChain>[0] = {
|
export const DYDX_CHAIN_INFO: Parameters<typeof suggestChain>[0] = {
|
||||||
rpc: 'https://dydx-testnet-archive.allthatnode.com:26657',
|
rpc: 'https://dydx-testnet-archive.allthatnode.com:26657',
|
||||||
rest: 'https://dydx-testnet-archive.allthatnode.com:1317',
|
rest: 'https://dydx-testnet-archive.allthatnode.com:1317',
|
||||||
chainId: 'dydx-testnet-3',
|
chainId: 'dydx-testnet-4',
|
||||||
chainName: 'dYdX Public Testnet',
|
chainName: 'dYdX Public Testnet',
|
||||||
chainSymbolImageUrl:
|
chainSymbolImageUrl:
|
||||||
'https://raw.githubusercontent.com/chainapsis/keplr-chain-registry/main/images/dydx-testnet-3/chain.png',
|
'https://raw.githubusercontent.com/chainapsis/keplr-chain-registry/main/images/dydx-testnet-4/chain.png',
|
||||||
bech32Config: {
|
bech32Config: {
|
||||||
bech32PrefixAccPub: 'dydxpub',
|
bech32PrefixAccPub: 'dydxpub',
|
||||||
bech32PrefixValPub: 'dydxvaloperpub',
|
bech32PrefixValPub: 'dydxvaloperpub',
|
||||||
@@ -361,26 +319,31 @@ export const DYDX_CHAIN_INFO: Parameters<typeof suggestChain>[0] = {
|
|||||||
},
|
},
|
||||||
stakeCurrency: {
|
stakeCurrency: {
|
||||||
coinDenom: 'DV4TNT',
|
coinDenom: 'DV4TNT',
|
||||||
coinDecimals: 6,
|
coinDecimals: 18,
|
||||||
coinMinimalDenom: 'dv4tnt',
|
coinMinimalDenom: 'adv4tnt',
|
||||||
},
|
},
|
||||||
currencies: [
|
currencies: [
|
||||||
{
|
{
|
||||||
coinDenom: 'DV4TNT',
|
coinDenom: 'DV4TNT',
|
||||||
coinDecimals: 6,
|
coinDecimals: 18,
|
||||||
coinMinimalDenom: 'dv4tnt',
|
coinMinimalDenom: 'adv4tnt',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
coinDenom: 'USDC',
|
coinDenom: 'USDC',
|
||||||
coinMinimalDenom: 'ibc/8E27BA2D5493AF5636760E354E46004562C46AB7EC0CC4C1CA14E9E20E2545B5',
|
|
||||||
coinDecimals: 6,
|
coinDecimals: 6,
|
||||||
|
coinMinimalDenom: 'ibc/8E27BA2D5493AF5636760E354E46004562C46AB7EC0CC4C1CA14E9E20E2545B5',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
feeCurrencies: [
|
feeCurrencies: [
|
||||||
{
|
{
|
||||||
coinDenom: 'DV4TNT',
|
coinDenom: 'DV4TNT',
|
||||||
|
coinDecimals: 18,
|
||||||
|
coinMinimalDenom: 'adv4tnt',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
coinDenom: 'USDC',
|
||||||
coinDecimals: 6,
|
coinDecimals: 6,
|
||||||
coinMinimalDenom: 'dv4tnt',
|
coinMinimalDenom: 'ibc/8E27BA2D5493AF5636760E354E46004562C46AB7EC0CC4C1CA14E9E20E2545B5',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
features: [],
|
features: [],
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import { useLocalStorage } from './useLocalStorage';
|
|||||||
import { useNow } from './useNow';
|
import { useNow } from './useNow';
|
||||||
import { useOnClickOutside } from './useOnClickOutside';
|
import { useOnClickOutside } from './useOnClickOutside';
|
||||||
import { usePageTitlePriceUpdates } from './usePageTitlePriceUpdates';
|
import { usePageTitlePriceUpdates } from './usePageTitlePriceUpdates';
|
||||||
|
import { useRestrictions } from './useRestrictions';
|
||||||
import { useShouldShowFooter } from './useShouldShowFooter';
|
import { useShouldShowFooter } from './useShouldShowFooter';
|
||||||
import { useSelectedNetwork } from './useSelectedNetwork';
|
import { useSelectedNetwork } from './useSelectedNetwork';
|
||||||
import { useStringGetter } from './useStringGetter';
|
import { useStringGetter } from './useStringGetter';
|
||||||
@@ -40,6 +41,7 @@ export {
|
|||||||
useNow,
|
useNow,
|
||||||
useOnClickOutside,
|
useOnClickOutside,
|
||||||
usePageTitlePriceUpdates,
|
usePageTitlePriceUpdates,
|
||||||
|
useRestrictions,
|
||||||
useShouldShowFooter,
|
useShouldShowFooter,
|
||||||
useSelectedNetwork,
|
useSelectedNetwork,
|
||||||
useStringGetter,
|
useStringGetter,
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ export const useTradingView = ({
|
|||||||
const marketIds = useSelector(getMarketIds, shallowEqual);
|
const marketIds = useSelector(getMarketIds, shallowEqual);
|
||||||
const selectedLocale = useSelector(getSelectedLocale);
|
const selectedLocale = useSelector(getSelectedLocale);
|
||||||
const selectedNetwork = useSelector(getSelectedNetwork);
|
const selectedNetwork = useSelector(getSelectedNetwork);
|
||||||
const { getCandlesForDatafeed } = useDydxClient();
|
const { getCandlesForDatafeed, isConnected: isClientConnected } = useDydxClient();
|
||||||
|
|
||||||
const [savedTvChartConfig, setTvChartConfig] = useLocalStorage<object | undefined>({
|
const [savedTvChartConfig, setTvChartConfig] = useLocalStorage<object | undefined>({
|
||||||
key: LocalStorageKey.TradingViewChartConfig,
|
key: LocalStorageKey.TradingViewChartConfig,
|
||||||
@@ -44,7 +44,7 @@ export const useTradingView = ({
|
|||||||
const hasMarkets = marketIds.length > 0;
|
const hasMarkets = marketIds.length > 0;
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (hasMarkets) {
|
if (hasMarkets && isClientConnected) {
|
||||||
const widgetOptions = getWidgetOptions();
|
const widgetOptions = getWidgetOptions();
|
||||||
const widgetOverrides = getWidgetOverrides(appTheme);
|
const widgetOverrides = getWidgetOverrides(appTheme);
|
||||||
const options = {
|
const options = {
|
||||||
@@ -75,7 +75,7 @@ export const useTradingView = ({
|
|||||||
tvWidgetRef.current = null;
|
tvWidgetRef.current = null;
|
||||||
setIsChartReady(false);
|
setIsChartReady(false);
|
||||||
};
|
};
|
||||||
}, [getCandlesForDatafeed, hasMarkets, selectedLocale, selectedNetwork]);
|
}, [getCandlesForDatafeed, isClientConnected, hasMarkets, selectedLocale, selectedNetwork]);
|
||||||
|
|
||||||
return { savedResolution };
|
return { savedResolution };
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -5,18 +5,20 @@ import { AES, enc } from 'crypto-js';
|
|||||||
import { LocalWallet, USDC_DENOM, type Subaccount } from '@dydxprotocol/v4-client-js';
|
import { LocalWallet, USDC_DENOM, 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 { LocalStorageKey, LOCAL_STORAGE_VERSIONS } from '@/constants/localStorage';
|
import { LocalStorageKey, LOCAL_STORAGE_VERSIONS } from '@/constants/localStorage';
|
||||||
import { DydxAddress, EvmAddress, PrivateInformation } from '@/constants/wallets';
|
import { DydxAddress, EvmAddress, PrivateInformation } from '@/constants/wallets';
|
||||||
|
|
||||||
import { setOnboardingState, setOnboardingGuard } from '@/state/account';
|
import { setOnboardingState, setOnboardingGuard } from '@/state/account';
|
||||||
|
import { forceOpenDialog } from '@/state/dialogs';
|
||||||
|
|
||||||
import abacusStateManager from '@/lib/abacus';
|
import abacusStateManager from '@/lib/abacus';
|
||||||
import { log } from '@/lib/telemetry';
|
import { log } from '@/lib/telemetry';
|
||||||
|
|
||||||
import { useLocalStorage } from './useLocalStorage';
|
|
||||||
|
|
||||||
import { useWalletConnection } from './useWalletConnection';
|
|
||||||
import { useDydxClient } from './useDydxClient';
|
import { useDydxClient } from './useDydxClient';
|
||||||
|
import { useLocalStorage } from './useLocalStorage';
|
||||||
|
import { useRestrictions } from './useRestrictions';
|
||||||
|
import { useWalletConnection } from './useWalletConnection';
|
||||||
|
|
||||||
const AccountsContext = createContext<ReturnType<typeof useAccountsContext> | undefined>(undefined);
|
const AccountsContext = createContext<ReturnType<typeof useAccountsContext> | undefined>(undefined);
|
||||||
|
|
||||||
@@ -57,7 +59,9 @@ const useAccountsContext = () => {
|
|||||||
forgetEvmSignature(previousEvmAddress);
|
forgetEvmSignature(previousEvmAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (evmAddress) abacusStateManager.setTransfersSourceAddress(evmAddress);
|
if (evmAddress) {
|
||||||
|
abacusStateManager.setTransfersSourceAddress(evmAddress);
|
||||||
|
}
|
||||||
|
|
||||||
setPreviousEvmAddress(evmAddress);
|
setPreviousEvmAddress(evmAddress);
|
||||||
}, [evmAddress]);
|
}, [evmAddress]);
|
||||||
@@ -217,7 +221,6 @@ const useAccountsContext = () => {
|
|||||||
}, [evmAddress, evmDerivedAddresses, signerWagmi, connectedDydxAddress, signerGraz]);
|
}, [evmAddress, evmDerivedAddresses, signerWagmi, connectedDydxAddress, signerGraz]);
|
||||||
|
|
||||||
// abacus
|
// abacus
|
||||||
// TODO: useAbacus({ dydxAddress })
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (dydxAddress) abacusStateManager.setAccount(localDydxWallet);
|
if (dydxAddress) abacusStateManager.setAccount(localDydxWallet);
|
||||||
else abacusStateManager.attemptDisconnectAccount();
|
else abacusStateManager.attemptDisconnectAccount();
|
||||||
@@ -258,6 +261,21 @@ const useAccountsContext = () => {
|
|||||||
);
|
);
|
||||||
}, [dydxSubaccounts]);
|
}, [dydxSubaccounts]);
|
||||||
|
|
||||||
|
// Restrictions
|
||||||
|
const { isBadActor, sanctionedAddresses } = useRestrictions();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (
|
||||||
|
dydxAddress &&
|
||||||
|
(isBadActor ||
|
||||||
|
sanctionedAddresses.has(dydxAddress) ||
|
||||||
|
(evmAddress && sanctionedAddresses.has(evmAddress)))
|
||||||
|
) {
|
||||||
|
dispatch(forceOpenDialog({ type: DialogTypes.RestrictedWallet }));
|
||||||
|
disconnect();
|
||||||
|
}
|
||||||
|
}, [isBadActor, evmAddress, dydxAddress, sanctionedAddresses]);
|
||||||
|
|
||||||
// Disconnect wallet / accounts
|
// Disconnect wallet / accounts
|
||||||
const disconnectLocalDydxWallet = () => {
|
const disconnectLocalDydxWallet = () => {
|
||||||
setLocalDydxWallet(undefined);
|
setLocalDydxWallet(undefined);
|
||||||
|
|||||||
@@ -44,6 +44,9 @@ export const useCurrentMarketId = () => {
|
|||||||
}, [validId]);
|
}, [validId]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
abacusStateManager.setMarket(marketId ?? DEFAULT_MARKETID);
|
// Check for marketIds otherwise Abacus will silently fail its isMarketValid check
|
||||||
}, [selectedNetwork, marketId]);
|
if (marketIds) {
|
||||||
|
abacusStateManager.setMarket(marketId ?? DEFAULT_MARKETID);
|
||||||
|
}
|
||||||
|
}, [selectedNetwork, marketIds, marketId]);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -2,27 +2,23 @@ import { WalletType } from '@/constants/wallets';
|
|||||||
|
|
||||||
import { isTruthy } from '@/lib/isTruthy';
|
import { isTruthy } from '@/lib/isTruthy';
|
||||||
|
|
||||||
import { useSelectedNetwork } from './useSelectedNetwork';
|
|
||||||
|
|
||||||
export const useDisplayedWallets = () => {
|
export const useDisplayedWallets = () => {
|
||||||
const { selectedNetwork } = useSelectedNetwork();
|
|
||||||
|
|
||||||
return [
|
return [
|
||||||
WalletType.MetaMask,
|
WalletType.MetaMask,
|
||||||
|
|
||||||
import.meta.env.MODE !== 'production' && WalletType.Keplr,
|
import.meta.env.MODE !== 'production' && WalletType.Keplr,
|
||||||
|
|
||||||
WalletType.WalletConnect2,
|
WalletType.WalletConnect2,
|
||||||
WalletType.WalletConnect,
|
|
||||||
|
|
||||||
WalletType.CoinbaseWallet,
|
WalletType.CoinbaseWallet,
|
||||||
|
|
||||||
WalletType.ImToken,
|
// Hide these wallet options until they can be properly tested on mainnet
|
||||||
WalletType.Rainbow,
|
// WalletType.ImToken,
|
||||||
WalletType.TrustWallet,
|
// WalletType.Rainbow,
|
||||||
WalletType.HuobiWallet,
|
// WalletType.TrustWallet,
|
||||||
WalletType.BitKeep,
|
// WalletType.HuobiWallet,
|
||||||
WalletType.Coin98,
|
// WalletType.BitKeep,
|
||||||
|
// WalletType.Coin98,
|
||||||
|
|
||||||
WalletType.OtherWallet,
|
WalletType.OtherWallet,
|
||||||
].filter(isTruthy);
|
].filter(isTruthy);
|
||||||
|
|||||||
@@ -13,12 +13,15 @@ import {
|
|||||||
|
|
||||||
import type { ResolutionString } from 'public/tradingview/charting_library';
|
import type { ResolutionString } from 'public/tradingview/charting_library';
|
||||||
|
|
||||||
import type { NetworkConfig, ConnectNetworkEvent } 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 { getSelectedNetwork } from '@/state/appSelectors';
|
import { getSelectedNetwork } from '@/state/appSelectors';
|
||||||
|
|
||||||
import { log } from '@/lib/telemetry';
|
import { log } from '@/lib/telemetry';
|
||||||
|
|
||||||
|
import { useRestrictions } from './useRestrictions';
|
||||||
|
|
||||||
type DydxContextType = ReturnType<typeof useDydxClientContext>;
|
type DydxContextType = ReturnType<typeof useDydxClientContext>;
|
||||||
const DydxContext = createContext<DydxContextType>({} as DydxContextType);
|
const DydxContext = createContext<DydxContextType>({} as DydxContextType);
|
||||||
DydxContext.displayName = 'dYdXClient';
|
DydxContext.displayName = 'dYdXClient';
|
||||||
@@ -34,7 +37,7 @@ const useDydxClientContext = () => {
|
|||||||
|
|
||||||
const selectedNetwork = useSelector(getSelectedNetwork);
|
const selectedNetwork = useSelector(getSelectedNetwork);
|
||||||
|
|
||||||
const [networkConfig, setNetworkConfig] = useState<Partial<NetworkConfig>>();
|
const [networkConfig, setNetworkConfig] = useState<NetworkConfig>();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const onConnectNetwork = (event: ConnectNetworkEvent) => setNetworkConfig(event.detail);
|
const onConnectNetwork = (event: ConnectNetworkEvent) => setNetworkConfig(event.detail);
|
||||||
@@ -54,14 +57,14 @@ const useDydxClientContext = () => {
|
|||||||
if (
|
if (
|
||||||
networkConfig?.chainId &&
|
networkConfig?.chainId &&
|
||||||
networkConfig?.indexerUrl &&
|
networkConfig?.indexerUrl &&
|
||||||
networkConfig?.indexerSocketUrl &&
|
networkConfig?.websocketUrl &&
|
||||||
networkConfig?.validatorUrl
|
networkConfig?.validatorUrl
|
||||||
) {
|
) {
|
||||||
try {
|
try {
|
||||||
const initializedClient = await CompositeClient.connect(
|
const initializedClient = await CompositeClient.connect(
|
||||||
new Network(
|
new Network(
|
||||||
selectedNetwork,
|
selectedNetwork,
|
||||||
new IndexerConfig(networkConfig.indexerUrl, networkConfig.indexerSocketUrl),
|
new IndexerConfig(networkConfig.indexerUrl, networkConfig.websocketUrl),
|
||||||
new ValidatorConfig(networkConfig.validatorUrl, networkConfig.chainId, {
|
new ValidatorConfig(networkConfig.validatorUrl, networkConfig.chainId, {
|
||||||
broadcastPollIntervalMs: 3_000,
|
broadcastPollIntervalMs: 3_000,
|
||||||
broadcastTimeoutMs: 60_000,
|
broadcastTimeoutMs: 60_000,
|
||||||
@@ -178,7 +181,27 @@ const useDydxClientContext = () => {
|
|||||||
[requestCandles]
|
[requestCandles]
|
||||||
);
|
);
|
||||||
|
|
||||||
// ------ Subacount Methods ------ //
|
const { updateSanctionedAddresses } = useRestrictions();
|
||||||
|
|
||||||
|
const screenAddresses = useCallback(
|
||||||
|
async ({ addresses }: { addresses: string[] }) => {
|
||||||
|
if (compositeClient) {
|
||||||
|
const promises = addresses.map((address) =>
|
||||||
|
compositeClient.indexerClient.utility.screen(address)
|
||||||
|
);
|
||||||
|
|
||||||
|
const results = await Promise.all(promises);
|
||||||
|
|
||||||
|
const screenedAddresses = Object.fromEntries(
|
||||||
|
addresses.map((address, index) => [address, results[index]?.restricted])
|
||||||
|
);
|
||||||
|
|
||||||
|
updateSanctionedAddresses(screenedAddresses);
|
||||||
|
return screenedAddresses;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[compositeClient]
|
||||||
|
);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
// Client initialization
|
// Client initialization
|
||||||
@@ -186,11 +209,13 @@ const useDydxClientContext = () => {
|
|||||||
networkConfig,
|
networkConfig,
|
||||||
compositeClient,
|
compositeClient,
|
||||||
faucetClient,
|
faucetClient,
|
||||||
|
isConnected: !!compositeClient,
|
||||||
|
|
||||||
// Wallet Methods
|
// Wallet Methods
|
||||||
getWalletFromEvmSignature,
|
getWalletFromEvmSignature,
|
||||||
|
|
||||||
// Public Methods
|
// Public Methods
|
||||||
getCandlesForDatafeed,
|
getCandlesForDatafeed,
|
||||||
|
screenAddresses,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import { useLocalStorage } from '@/hooks';
|
|||||||
import { initializeLocalization } from '@/state/app';
|
import { initializeLocalization } from '@/state/app';
|
||||||
|
|
||||||
import abacusStateManager from '@/lib/abacus';
|
import abacusStateManager from '@/lib/abacus';
|
||||||
|
import { validateAgainstAvailableEnvironments } from '@/lib/network';
|
||||||
|
|
||||||
export const useInitializePage = () => {
|
export const useInitializePage = () => {
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
@@ -18,6 +19,7 @@ export const useInitializePage = () => {
|
|||||||
const [localStorageNetwork] = useLocalStorage<DydxNetwork>({
|
const [localStorageNetwork] = useLocalStorage<DydxNetwork>({
|
||||||
key: LocalStorageKey.SelectedNetwork,
|
key: LocalStorageKey.SelectedNetwork,
|
||||||
defaultValue: DEFAULT_APP_ENVIRONMENT,
|
defaultValue: DEFAULT_APP_ENVIRONMENT,
|
||||||
|
validateFn: validateAgainstAvailableEnvironments,
|
||||||
});
|
});
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|||||||
@@ -4,15 +4,14 @@ import { useSelector, shallowEqual, useDispatch } from 'react-redux';
|
|||||||
import { groupBy } from 'lodash';
|
import { groupBy } from 'lodash';
|
||||||
|
|
||||||
import { AlertType } from '@/constants/alerts';
|
import { AlertType } from '@/constants/alerts';
|
||||||
import { AbacusOrderStatus, ORDER_SIDES, ORDER_STATUS_STRINGS } from '@/constants/abacus';
|
import { AbacusOrderStatus, ORDER_SIDES } from '@/constants/abacus';
|
||||||
import { DialogTypes } from '@/constants/dialogs';
|
import { DialogTypes } from '@/constants/dialogs';
|
||||||
import { STRING_KEYS } from '@/constants/localization';
|
import { STRING_KEYS, StringKey } from '@/constants/localization';
|
||||||
import { type NotificationTypeConfig, NotificationType } from '@/constants/notifications';
|
import { type NotificationTypeConfig, NotificationType } from '@/constants/notifications';
|
||||||
import { ORDER_SIDE_STRINGS, TRADE_TYPE_STRINGS, TradeTypes } from '@/constants/trade';
|
import { ORDER_SIDE_STRINGS } from '@/constants/trade';
|
||||||
|
|
||||||
import { useLocalNotifications } from '@/hooks/useLocalNotifications';
|
import { useLocalNotifications } from '@/hooks/useLocalNotifications';
|
||||||
|
|
||||||
import { AlertMessage } from '@/components/AlertMessage';
|
|
||||||
import { Icon, IconName } from '@/components/Icon';
|
import { Icon, IconName } from '@/components/Icon';
|
||||||
import { Output, OutputType } from '@/components/Output';
|
import { Output, OutputType } from '@/components/Output';
|
||||||
import { TransferStatusToast } from '@/views/TransferStatus';
|
import { TransferStatusToast } from '@/views/TransferStatus';
|
||||||
@@ -69,11 +68,11 @@ export const notificationTypes = [
|
|||||||
<OrderStatusIcon status={order.status} totalFilled={order.totalFilled ?? 0} />
|
<OrderStatusIcon status={order.status} totalFilled={order.totalFilled ?? 0} />
|
||||||
),
|
),
|
||||||
title: `${stringGetter({
|
title: `${stringGetter({
|
||||||
key: TRADE_TYPE_STRINGS[order.type.rawValue as TradeTypes].tradeTypeKey,
|
key: order.resources.typeStringKey as StringKey,
|
||||||
})} ${
|
})} ${
|
||||||
order.status === AbacusOrderStatus.open && (order?.totalFilled ?? 0) > 0
|
order.status === AbacusOrderStatus.open && (order?.totalFilled ?? 0) > 0
|
||||||
? stringGetter({ key: STRING_KEYS.PARTIALLY_FILLED })
|
? stringGetter({ key: STRING_KEYS.PARTIALLY_FILLED })
|
||||||
: stringGetter({ key: ORDER_STATUS_STRINGS[order.status.name] })
|
: stringGetter({ key: order.resources.statusStringKey as StringKey })
|
||||||
}`,
|
}`,
|
||||||
description: `${stringGetter({
|
description: `${stringGetter({
|
||||||
key: ORDER_SIDE_STRINGS[ORDER_SIDES[order.side.name]],
|
key: ORDER_SIDE_STRINGS[ORDER_SIDES[order.side.name]],
|
||||||
@@ -91,18 +90,34 @@ export const notificationTypes = [
|
|||||||
}, [orderIds]);
|
}, [orderIds]);
|
||||||
},
|
},
|
||||||
|
|
||||||
useNotificationAction: () => {
|
// useNotificationAction: () => {
|
||||||
const dispatch = useDispatch();
|
// const dispatch = useDispatch();
|
||||||
|
// const orders = useSelector(getSubaccountOrders, shallowEqual) || [];
|
||||||
|
// const ordersByOrderId = Object.fromEntries(orders.map((order) => [order.id, order]));
|
||||||
|
|
||||||
return (orderId) => {
|
// const fills = useSelector(getSubaccountFills, shallowEqual) || [];
|
||||||
dispatch(
|
// const fillsByOrderId = groupBy(fills, (fill) => fill.orderId);
|
||||||
openDialog({
|
|
||||||
type: DialogTypes.OrderDetails,
|
// return (id) => {
|
||||||
dialogProps: { orderId },
|
// if (ordersByOrderId[id]) {
|
||||||
})
|
// dispatch(
|
||||||
);
|
// openDialog({
|
||||||
};
|
// type: DialogTypes.OrderDetails,
|
||||||
},
|
// dialogProps: { orderId: id },
|
||||||
|
// })
|
||||||
|
// );
|
||||||
|
// } else if (fillsByOrderId[id]) {
|
||||||
|
// const fillId = fillsByOrderId[id][0].id;
|
||||||
|
|
||||||
|
// dispatch(
|
||||||
|
// openDialog({
|
||||||
|
// type: DialogTypes.FillDetails,
|
||||||
|
// dialogProps: { fillId },
|
||||||
|
// })
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
// };
|
||||||
|
// },
|
||||||
} as NotificationTypeConfig<string, [string, number]>,
|
} as NotificationTypeConfig<string, [string, number]>,
|
||||||
{
|
{
|
||||||
type: NotificationType.SquidTransfer,
|
type: NotificationType.SquidTransfer,
|
||||||
@@ -110,18 +125,18 @@ export const notificationTypes = [
|
|||||||
const stringGetter = useStringGetter();
|
const stringGetter = useStringGetter();
|
||||||
const { transferNotifications } = useLocalNotifications();
|
const { transferNotifications } = useLocalNotifications();
|
||||||
|
|
||||||
const getTitleStringKey = useCallback((type: 'deposit' | 'withdraw', finished: boolean) => {
|
const getTitleStringKey = useCallback((type: 'deposit' | 'withdrawal', finished: boolean) => {
|
||||||
if (type === 'deposit' && !finished) return STRING_KEYS.DEPOSIT_IN_PROGRESS;
|
if (type === 'deposit' && !finished) return STRING_KEYS.DEPOSIT_IN_PROGRESS;
|
||||||
if (type === 'deposit' && finished) return STRING_KEYS.DEPOSIT;
|
if (type === 'deposit' && finished) return STRING_KEYS.DEPOSIT;
|
||||||
if (type === 'withdraw' && !finished) return STRING_KEYS.WITHDRAW_IN_PROGRESS;
|
if (type === 'withdrawal' && !finished) return STRING_KEYS.WITHDRAW_IN_PROGRESS;
|
||||||
return STRING_KEYS.WITHDRAW;
|
return STRING_KEYS.WITHDRAW;
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
for (const transfer of transferNotifications) {
|
for (const transfer of transferNotifications) {
|
||||||
const { toChainId, status, txHash, toAmount } = transfer;
|
const { fromChainId, status, txHash, toAmount } = transfer;
|
||||||
const finished = Boolean(status) && status?.squidTransactionStatus !== 'ongoing';
|
const finished = Boolean(status) && status?.squidTransactionStatus !== 'ongoing';
|
||||||
const type = toChainId === TESTNET_CHAIN_ID ? 'deposit' : 'withdraw';
|
const type = fromChainId === TESTNET_CHAIN_ID ? 'withdrawal' : 'deposit';
|
||||||
// @ts-ignore status.errors is not in the type definition but can be returned
|
// @ts-ignore status.errors is not in the type definition but can be returned
|
||||||
const error = status?.errors?.length ? status?.errors[0] : status?.error;
|
const error = status?.errors?.length ? status?.errors[0] : status?.error;
|
||||||
|
|
||||||
@@ -138,7 +153,8 @@ export const notificationTypes = [
|
|||||||
{stringGetter({
|
{stringGetter({
|
||||||
key: STRING_KEYS.SOMETHING_WENT_WRONG_WITH_MESSAGE,
|
key: STRING_KEYS.SOMETHING_WENT_WRONG_WITH_MESSAGE,
|
||||||
params: {
|
params: {
|
||||||
ERROR_MESSAGE: error.message || stringGetter({ key: STRING_KEYS.UNKNOWN_ERROR }),
|
ERROR_MESSAGE:
|
||||||
|
error.message || stringGetter({ key: STRING_KEYS.UNKNOWN_ERROR }),
|
||||||
},
|
},
|
||||||
})}
|
})}
|
||||||
</Styled.ErrorMessage>
|
</Styled.ErrorMessage>
|
||||||
@@ -154,6 +170,7 @@ export const notificationTypes = [
|
|||||||
description: description,
|
description: description,
|
||||||
customContent: (
|
customContent: (
|
||||||
<TransferStatusToast
|
<TransferStatusToast
|
||||||
|
type={type}
|
||||||
toAmount={transfer.toAmount}
|
toAmount={transfer.toAmount}
|
||||||
triggeredAt={transfer.triggeredAt}
|
triggeredAt={transfer.triggeredAt}
|
||||||
status={transfer.status}
|
status={transfer.status}
|
||||||
@@ -162,7 +179,7 @@ export const notificationTypes = [
|
|||||||
customMenuContent: !finished && (
|
customMenuContent: !finished && (
|
||||||
<div>
|
<div>
|
||||||
{description}
|
{description}
|
||||||
<TransferStatusSteps status={transfer.status} />
|
<TransferStatusSteps status={transfer.status} type={type} />
|
||||||
</div>
|
</div>
|
||||||
),
|
),
|
||||||
toastSensitivity: 'foreground',
|
toastSensitivity: 'foreground',
|
||||||
@@ -181,8 +198,8 @@ Styled.TransferText = styled.span`
|
|||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 0.5ch;
|
gap: 0.5ch;
|
||||||
`
|
`;
|
||||||
|
|
||||||
Styled.ErrorMessage = styled.div`
|
Styled.ErrorMessage = styled.div`
|
||||||
max-width: 13rem;
|
max-width: 13rem;
|
||||||
`;
|
`;
|
||||||
|
|||||||
@@ -0,0 +1,53 @@
|
|||||||
|
import { createContext, useCallback, useContext, useEffect, useMemo, useState } from 'react';
|
||||||
|
import { shallowEqual, useDispatch, useSelector } from 'react-redux';
|
||||||
|
|
||||||
|
import { RestrictionType } from '@/constants/abacus';
|
||||||
|
import { DialogTypes } from '@/constants/dialogs';
|
||||||
|
|
||||||
|
import { getRestrictionType } from '@/state/accountSelectors';
|
||||||
|
import { forceOpenDialog } from '@/state/dialogs';
|
||||||
|
import { isTruthy } from '@/lib/isTruthy';
|
||||||
|
|
||||||
|
const useRestrictionContext = () => {
|
||||||
|
const dispatch = useDispatch();
|
||||||
|
const restrictionType = useSelector(getRestrictionType, shallowEqual);
|
||||||
|
const [sanctionedAddresses, setSanctionedAddresses] = useState<string[]>([]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (restrictionType === RestrictionType.GEO_RESTRICTED) {
|
||||||
|
dispatch(
|
||||||
|
forceOpenDialog({ type: DialogTypes.RestrictedGeo, dialogProps: { preventClose: true } })
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}, [restrictionType, dispatch]);
|
||||||
|
|
||||||
|
const updateSanctionedAddresses = useCallback(
|
||||||
|
(screenedAddresses: { [address: string]: boolean }) => {
|
||||||
|
const toAdd = Object.entries(screenedAddresses)
|
||||||
|
.filter(([, isSanctioned]) => isSanctioned)
|
||||||
|
.map(([address]) => address);
|
||||||
|
|
||||||
|
if (toAdd.length) {
|
||||||
|
setSanctionedAddresses([...sanctionedAddresses, ...toAdd]);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[sanctionedAddresses]
|
||||||
|
);
|
||||||
|
|
||||||
|
return {
|
||||||
|
isBadActor: restrictionType === RestrictionType.USER_RESTRICTED,
|
||||||
|
isGeoRestricted: restrictionType === RestrictionType.GEO_RESTRICTED,
|
||||||
|
updateSanctionedAddresses,
|
||||||
|
sanctionedAddresses: useMemo(() => new Set(sanctionedAddresses), [sanctionedAddresses]),
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
type RestrictionContextType = ReturnType<typeof useRestrictionContext>;
|
||||||
|
const RestrictionContext = createContext<RestrictionContextType>({} as RestrictionContextType);
|
||||||
|
RestrictionContext.displayName = 'Restriction';
|
||||||
|
|
||||||
|
export const RestrictionProvider = ({ ...props }) => (
|
||||||
|
<RestrictionContext.Provider value={useRestrictionContext()} {...props} />
|
||||||
|
);
|
||||||
|
|
||||||
|
export const useRestrictions = () => useContext(RestrictionContext);
|
||||||
@@ -1,13 +1,17 @@
|
|||||||
import { useCallback } from 'react';
|
import { useCallback, useEffect } 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 } from '@/constants/networks';
|
import { DEFAULT_APP_ENVIRONMENT, DydxNetwork, ENVIRONMENT_CONFIG_MAP } from '@/constants/networks';
|
||||||
|
|
||||||
import { useAccounts, useLocalStorage } from '@/hooks';
|
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';
|
||||||
|
|
||||||
export const useSelectedNetwork = (): {
|
export const useSelectedNetwork = (): {
|
||||||
switchNetwork: (network: DydxNetwork) => void;
|
switchNetwork: (network: DydxNetwork) => void;
|
||||||
@@ -20,8 +24,20 @@ export const useSelectedNetwork = (): {
|
|||||||
const [, setLocalStorageNetwork] = useLocalStorage<DydxNetwork>({
|
const [, setLocalStorageNetwork] = useLocalStorage<DydxNetwork>({
|
||||||
key: LocalStorageKey.SelectedNetwork,
|
key: LocalStorageKey.SelectedNetwork,
|
||||||
defaultValue: DEFAULT_APP_ENVIRONMENT,
|
defaultValue: DEFAULT_APP_ENVIRONMENT,
|
||||||
|
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();
|
||||||
|
|||||||
@@ -36,7 +36,6 @@ import { log } from '@/lib/telemetry';
|
|||||||
import { useAccounts } from './useAccounts';
|
import { useAccounts } from './useAccounts';
|
||||||
import { useDydxClient } from './useDydxClient';
|
import { useDydxClient } from './useDydxClient';
|
||||||
|
|
||||||
|
|
||||||
type SubaccountContextType = ReturnType<typeof useSubaccountContext>;
|
type SubaccountContextType = ReturnType<typeof useSubaccountContext>;
|
||||||
const SubaccountContext = createContext<SubaccountContextType>({} as SubaccountContextType);
|
const SubaccountContext = createContext<SubaccountContextType>({} as SubaccountContextType);
|
||||||
SubaccountContext.displayName = 'Subaccount';
|
SubaccountContext.displayName = 'Subaccount';
|
||||||
@@ -275,6 +274,7 @@ export const useSubaccountContext = ({ localDydxWallet }: { localDydxWallet?: Lo
|
|||||||
await getFaucetFunds({ dydxAddress, subaccountNumber });
|
await getFaucetFunds({ dydxAddress, subaccountNumber });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log('useSubaccount/getFaucetFunds', error);
|
log('useSubaccount/getFaucetFunds', error);
|
||||||
|
throw error;
|
||||||
}
|
}
|
||||||
}, [dydxAddress, getFaucetFunds, subaccountNumber]);
|
}, [dydxAddress, getFaucetFunds, subaccountNumber]);
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
<svg width="16" height="18" viewBox="0 0 16 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M10.3811 13.235C11.9338 13.0512 13.4593 12.6847 14.9261 12.1433C13.6839 10.7673 12.9975 8.97875 13.0003 7.125V6.54167V6.5C13.0003 5.17392 12.4735 3.90215 11.5358 2.96447C10.5981 2.02678 9.32636 1.5 8.00028 1.5C6.67419 1.5 5.40242 2.02678 4.46474 2.96447C3.52706 3.90215 3.00028 5.17392 3.00028 6.5V7.125C3.00279 8.97886 2.3161 10.7675 1.07361 12.1433C2.51778 12.6767 4.04027 13.0475 5.61944 13.235M10.3811 13.235C8.79943 13.4226 7.20112 13.4226 5.61944 13.235M10.3811 13.235C10.5012 13.6099 10.5311 14.0078 10.4683 14.3964C10.4055 14.785 10.2518 15.1533 10.0198 15.4713C9.78772 15.7893 9.48386 16.048 9.13293 16.2263C8.78201 16.4047 8.39392 16.4976 8.00028 16.4976C7.60663 16.4976 7.21854 16.4047 6.86762 16.2263C6.51669 16.048 6.21283 15.7893 5.98079 15.4713C5.74875 15.1533 5.59508 14.785 5.53229 14.3964C5.46949 14.0078 5.49936 13.6099 5.61944 13.235" stroke="currentColor" stroke-width="1.25" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.0 KiB |
@@ -1 +1 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 22 24"><path fill="currentColor" d="M11 0C8.5 0 6.101.948 4.333 2.636 2.565 4.324 1.57 6.613 1.57 9v5.379l-1.11 1.06c-.22.21-.37.477-.43.768-.061.291-.03.593.089.867s.32.508.578.673c.259.165.562.253.873.253h18.86c.31 0 .614-.088.873-.253.258-.165.46-.399.578-.673.12-.274.15-.576.09-.867a1.48 1.48 0 0 0-.43-.768l-1.111-1.06V9c0-2.387-.993-4.676-2.762-6.364C15.9.948 13.501 0 11 0Zm0 24a4.83 4.83 0 0 1-3.334-1.318 4.399 4.399 0 0 1-1.38-3.182h9.428a4.399 4.399 0 0 1-1.38 3.182A4.83 4.83 0 0 1 11 24Z"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 22 24"><path fill="currentColor" d="M11 0C8.5 0 6.101.948 4.333 2.636 2.565 4.324 1.57 6.613 1.57 9v5.379l-1.11 1.06c-.22.21-.37.477-.43.768-.061.291-.03.593.089.867s.32.508.578.673c.259.165.562.253.873.253h18.86c.31 0 .614-.088.873-.253.258-.165.46-.399.578-.673.12-.274.15-.576.09-.867a1.48 1.48 0 0 0-.43-.768l-1.111-1.06V9c0-2.387-.993-4.676-2.762-6.364C15.9.948 13.501 0 11 0Zm0 24a4.83 4.83 0 0 1-3.334-1.318 4.399 4.399 0 0 1-1.38-3.182h9.428a4.399 4.399 0 0 1-1.38 3.182A4.83 4.83 0 0 1 11 24Z"/></svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 563 B After Width: | Height: | Size: 564 B |
@@ -2,6 +2,7 @@ export { default as AddressConnectorIcon } from './address-connector.svg';
|
|||||||
export { default as ArrowIcon } from './arrow.svg';
|
export { default as ArrowIcon } from './arrow.svg';
|
||||||
export { default as Bar3Icon } from './bar3.svg';
|
export { default as Bar3Icon } from './bar3.svg';
|
||||||
export { default as BellIcon } from './bell.svg';
|
export { default as BellIcon } from './bell.svg';
|
||||||
|
export { default as BellStrokeIcon } from './bell-stroke.svg';
|
||||||
export { default as BoxCloseIcon } from './box-close.svg';
|
export { default as BoxCloseIcon } from './box-close.svg';
|
||||||
export { default as CalculatorIcon } from './calculator.svg';
|
export { default as CalculatorIcon } from './calculator.svg';
|
||||||
export { default as CaretIcon } from './caret-down.svg';
|
export { default as CaretIcon } from './caret-down.svg';
|
||||||
|
|||||||
@@ -15,9 +15,12 @@ import { ExternalNavKeplrDialog } from '@/views/dialogs/ExternalNavKeplrDialog';
|
|||||||
import { MnemonicExportDialog } from '@/views/dialogs/MnemonicExportDialog';
|
import { MnemonicExportDialog } from '@/views/dialogs/MnemonicExportDialog';
|
||||||
import { MobileSignInDialog } from '@/views/dialogs/MobileSignInDialog';
|
import { MobileSignInDialog } from '@/views/dialogs/MobileSignInDialog';
|
||||||
import { OnboardingDialog } from '@/views/dialogs/OnboardingDialog';
|
import { OnboardingDialog } from '@/views/dialogs/OnboardingDialog';
|
||||||
|
import { RateLimitDialog } from '@/views/dialogs/RateLimitDialog';
|
||||||
import { ReceiveDialog } from '@/views/dialogs/ReceiveDialog';
|
import { ReceiveDialog } from '@/views/dialogs/ReceiveDialog';
|
||||||
|
import { RestrictedGeoDialog } from '@/views/dialogs/RestrictedGeoDialog';
|
||||||
import { TradeDialog } from '@/views/dialogs/TradeDialog';
|
import { TradeDialog } from '@/views/dialogs/TradeDialog';
|
||||||
import { TransferDialog } from '@/views/dialogs/TransferDialog';
|
import { TransferDialog } from '@/views/dialogs/TransferDialog';
|
||||||
|
import { RestrictedWalletDialog } from '@/views/dialogs/RestrictedWalletDialog';
|
||||||
import { WithdrawDialog } from '@/views/dialogs/WithdrawDialog';
|
import { WithdrawDialog } from '@/views/dialogs/WithdrawDialog';
|
||||||
|
|
||||||
import { OrderDetailsDialog } from '@/views/dialogs/DetailsDialog/OrderDetailsDialog';
|
import { OrderDetailsDialog } from '@/views/dialogs/DetailsDialog/OrderDetailsDialog';
|
||||||
@@ -53,7 +56,10 @@ export const DialogManager = () => {
|
|||||||
[DialogTypes.MobileSignIn]: <MobileSignInDialog {...modalProps} />,
|
[DialogTypes.MobileSignIn]: <MobileSignInDialog {...modalProps} />,
|
||||||
[DialogTypes.Onboarding]: <OnboardingDialog {...modalProps} />,
|
[DialogTypes.Onboarding]: <OnboardingDialog {...modalProps} />,
|
||||||
[DialogTypes.OrderDetails]: <OrderDetailsDialog {...modalProps} />,
|
[DialogTypes.OrderDetails]: <OrderDetailsDialog {...modalProps} />,
|
||||||
|
[DialogTypes.RateLimit]: <RateLimitDialog {...modalProps} />,
|
||||||
[DialogTypes.Receive]: <ReceiveDialog {...modalProps} />,
|
[DialogTypes.Receive]: <ReceiveDialog {...modalProps} />,
|
||||||
|
[DialogTypes.RestrictedGeo]: <RestrictedGeoDialog {...modalProps} />,
|
||||||
|
[DialogTypes.RestrictedWallet]: <RestrictedWalletDialog {...modalProps} />,
|
||||||
[DialogTypes.Trade]: <TradeDialog {...modalProps} />,
|
[DialogTypes.Trade]: <TradeDialog {...modalProps} />,
|
||||||
[DialogTypes.Transfer]: <TransferDialog {...modalProps} />,
|
[DialogTypes.Transfer]: <TransferDialog {...modalProps} />,
|
||||||
[DialogTypes.Withdraw]: <WithdrawDialog {...modalProps} />,
|
[DialogTypes.Withdraw]: <WithdrawDialog {...modalProps} />,
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ 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 { useStringGetter } from '@/hooks';
|
||||||
import { LogoShortIcon, BellIcon } from '@/icons';
|
import { LogoShortIcon, BellStrokeIcon } from '@/icons';
|
||||||
|
|
||||||
import { Icon, IconName } from '@/components/Icon';
|
import { Icon, IconName } from '@/components/Icon';
|
||||||
import { IconButton } from '@/components/IconButton';
|
import { IconButton } from '@/components/IconButton';
|
||||||
@@ -131,7 +131,9 @@ export const HeaderDesktop = () => {
|
|||||||
<VerticalSeparator />
|
<VerticalSeparator />
|
||||||
|
|
||||||
<NotificationsMenu
|
<NotificationsMenu
|
||||||
slotTrigger={<Styled.IconButton shape={ButtonShape.Rectangle} iconComponent={BellIcon} />}
|
slotTrigger={
|
||||||
|
<Styled.IconButton shape={ButtonShape.Rectangle} iconComponent={BellStrokeIcon} />
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<VerticalSeparator />
|
<VerticalSeparator />
|
||||||
@@ -165,7 +167,7 @@ Styled.Header = styled.header`
|
|||||||
)
|
)
|
||||||
var(--border-width) 1fr var(--border-width) auto;
|
var(--border-width) 1fr var(--border-width) auto;
|
||||||
|
|
||||||
font-size: 0.9375em;
|
font-size: 0.9375rem;
|
||||||
|
|
||||||
:before {
|
:before {
|
||||||
backdrop-filter: blur(10px);
|
backdrop-filter: blur(10px);
|
||||||
@@ -214,7 +216,8 @@ Styled.NavAfter = styled.div`
|
|||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
Styled.IconButton = styled(IconButton)`
|
Styled.IconButton = styled(IconButton)<{ size?: string }>`
|
||||||
${headerMixins.button}
|
${headerMixins.button}
|
||||||
--button-border: none;
|
--button-border: none;
|
||||||
|
--button-icon-size: 1rem;
|
||||||
`;
|
`;
|
||||||
|
|||||||
@@ -61,18 +61,17 @@ class DydxChainTransactions implements AbacusDYDXChainTransactionsProtocol {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async connectNetwork(
|
async connectNetwork(
|
||||||
indexerUrl: string,
|
paramsInJson: Nullable<string>,
|
||||||
indexerSocketUrl: string,
|
|
||||||
validatorUrl: string,
|
|
||||||
chainId: string,
|
|
||||||
faucetUrl: Nullable<string> | undefined,
|
|
||||||
callback: (p0: Nullable<string>) => void
|
callback: (p0: Nullable<string>) => void
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
try {
|
try {
|
||||||
|
const parsedParams = paramsInJson ? JSON.parse(paramsInJson) : {};
|
||||||
|
const { indexerUrl, websocketUrl, validatorUrl, chainId } = parsedParams;
|
||||||
|
|
||||||
const compositeClient = await CompositeClient.connect(
|
const compositeClient = await CompositeClient.connect(
|
||||||
new Network(
|
new Network(
|
||||||
chainId,
|
chainId,
|
||||||
new IndexerConfig(indexerUrl, indexerSocketUrl),
|
new IndexerConfig(indexerUrl, websocketUrl),
|
||||||
new ValidatorConfig(validatorUrl, chainId, {
|
new ValidatorConfig(validatorUrl, chainId, {
|
||||||
broadcastPollIntervalMs: 3_000,
|
broadcastPollIntervalMs: 3_000,
|
||||||
broadcastTimeoutMs: 60_000,
|
broadcastTimeoutMs: 60_000,
|
||||||
@@ -84,13 +83,7 @@ class DydxChainTransactions implements AbacusDYDXChainTransactionsProtocol {
|
|||||||
|
|
||||||
// Dispatch custom event to notify other parts of the app that the network has been connected
|
// Dispatch custom event to notify other parts of the app that the network has been connected
|
||||||
const customEvent = new CustomEvent('abacus:connectNetwork', {
|
const customEvent = new CustomEvent('abacus:connectNetwork', {
|
||||||
detail: {
|
detail: parsedParams,
|
||||||
indexerUrl,
|
|
||||||
indexerSocketUrl,
|
|
||||||
validatorUrl,
|
|
||||||
chainId,
|
|
||||||
faucetUrl,
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
globalThis.dispatchEvent(customEvent);
|
globalThis.dispatchEvent(customEvent);
|
||||||
@@ -99,9 +92,7 @@ class DydxChainTransactions implements AbacusDYDXChainTransactionsProtocol {
|
|||||||
this.store?.dispatch(
|
this.store?.dispatch(
|
||||||
openDialog({ type: DialogTypes.ExchangeOffline, dialogProps: { preventClose: true } })
|
openDialog({ type: DialogTypes.ExchangeOffline, dialogProps: { preventClose: true } })
|
||||||
);
|
);
|
||||||
|
|
||||||
log('DydxChainTransactions/connectNetwork', error);
|
log('DydxChainTransactions/connectNetwork', error);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -251,7 +242,7 @@ class DydxChainTransactions implements AbacusDYDXChainTransactionsProtocol {
|
|||||||
const msg = compositeClient.withdrawFromSubaccountMessage(subaccountClient, amount);
|
const msg = compositeClient.withdrawFromSubaccountMessage(subaccountClient, amount);
|
||||||
|
|
||||||
resolve([msg]);
|
resolve([msg]);
|
||||||
}),
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
const parsedTx = this.parseToPrimitives(tx);
|
const parsedTx = this.parseToPrimitives(tx);
|
||||||
@@ -266,7 +257,9 @@ class DydxChainTransactions implements AbacusDYDXChainTransactionsProtocol {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async simulateTransferNativeTokenTransaction(params: HumanReadableTransferPayload): Promise<string> {
|
async simulateTransferNativeTokenTransaction(
|
||||||
|
params: HumanReadableTransferPayload
|
||||||
|
): Promise<string> {
|
||||||
if (!this.compositeClient || !this.localWallet) {
|
if (!this.compositeClient || !this.localWallet) {
|
||||||
throw new Error('Missing compositeClient or localWallet');
|
throw new Error('Missing compositeClient or localWallet');
|
||||||
}
|
}
|
||||||
@@ -289,7 +282,7 @@ class DydxChainTransactions implements AbacusDYDXChainTransactionsProtocol {
|
|||||||
|
|
||||||
resolve([msg]);
|
resolve([msg]);
|
||||||
}),
|
}),
|
||||||
GAS_PRICE_DYDX_DENOM,
|
GAS_PRICE_DYDX_DENOM
|
||||||
);
|
);
|
||||||
|
|
||||||
const parsedTx = this.parseToPrimitives(tx);
|
const parsedTx = this.parseToPrimitives(tx);
|
||||||
@@ -397,9 +390,10 @@ class DydxChainTransactions implements AbacusDYDXChainTransactionsProtocol {
|
|||||||
break;
|
break;
|
||||||
case QueryType.GetAccountBalances:
|
case QueryType.GetAccountBalances:
|
||||||
if (!this.localWallet?.address) throw new Error('Missing localWallet');
|
if (!this.localWallet?.address) throw new Error('Missing localWallet');
|
||||||
const accountBalances = await this.compositeClient?.validatorClient.get.getAccountBalances(
|
const accountBalances =
|
||||||
this.localWallet.address
|
await this.compositeClient?.validatorClient.get.getAccountBalances(
|
||||||
);
|
this.localWallet.address
|
||||||
|
);
|
||||||
const parsedAccountBalances = this.parseToPrimitives(accountBalances);
|
const parsedAccountBalances = this.parseToPrimitives(accountBalances);
|
||||||
callback(JSON.stringify(parsedAccountBalances));
|
callback(JSON.stringify(parsedAccountBalances));
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -47,6 +47,11 @@ class AbacusRest implements AbacusRestProtocol {
|
|||||||
body,
|
body,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (!url) {
|
||||||
|
callback(null, 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
fetch(url, options)
|
fetch(url, options)
|
||||||
.then(async (response) => {
|
.then(async (response) => {
|
||||||
const data = await response.text();
|
const data = await response.text();
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import {
|
|||||||
setFundingPayments,
|
setFundingPayments,
|
||||||
setHistoricalPnl,
|
setHistoricalPnl,
|
||||||
setLatestOrder,
|
setLatestOrder,
|
||||||
|
setRestrictionType,
|
||||||
setSubaccount,
|
setSubaccount,
|
||||||
setTransfers,
|
setTransfers,
|
||||||
setWallet,
|
setWallet,
|
||||||
@@ -121,6 +122,10 @@ class AbacusStateNotifier implements AbacusStateNotificationProtocol {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (changes.has(Changes.restriction)) {
|
||||||
|
dispatch(setRestrictionType(updatedState.restriction));
|
||||||
|
}
|
||||||
|
|
||||||
subaccountNumbers?.forEach((subaccountId: number) => {
|
subaccountNumbers?.forEach((subaccountId: number) => {
|
||||||
if (subaccountId !== null) {
|
if (subaccountId !== null) {
|
||||||
if (changes.has(Changes.subaccount)) {
|
if (changes.has(Changes.subaccount)) {
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
import { type DydxNetwork, ENVIRONMENT_CONFIG_MAP } from '@/constants/networks';
|
||||||
|
|
||||||
|
export const validateAgainstAvailableEnvironments = (value: DydxNetwork) =>
|
||||||
|
Object.keys(ENVIRONMENT_CONFIG_MAP).includes(value);
|
||||||
@@ -36,7 +36,15 @@ import { CoinbaseWalletConnector } from 'wagmi/connectors/coinbaseWallet';
|
|||||||
import { InjectedConnector } from 'wagmi/connectors/injected';
|
import { InjectedConnector } from 'wagmi/connectors/injected';
|
||||||
import { MetaMaskConnector } from 'wagmi/connectors/metaMask';
|
import { MetaMaskConnector } from 'wagmi/connectors/metaMask';
|
||||||
import { WalletConnectConnector } from 'wagmi/connectors/walletConnect';
|
import { WalletConnectConnector } from 'wagmi/connectors/walletConnect';
|
||||||
import { WalletConnectLegacyConnector } from 'wagmi/connectors/walletConnectLegacy';
|
|
||||||
|
import {
|
||||||
|
type WalletConnection,
|
||||||
|
WalletConnectionType,
|
||||||
|
type WalletType,
|
||||||
|
walletConnectionTypes,
|
||||||
|
wallets,
|
||||||
|
WALLET_CONNECT_EXPLORER_RECOMMENDED_IDS,
|
||||||
|
} from '@/constants/wallets';
|
||||||
|
|
||||||
// Config
|
// Config
|
||||||
|
|
||||||
@@ -87,43 +95,24 @@ const injectedConnectorOptions = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const walletconnect1ConnectorOptions = {
|
|
||||||
chains,
|
|
||||||
options: {
|
|
||||||
bridge: import.meta.env.VITE_WALLETCONNECT1_BRIDGE,
|
|
||||||
qrcode: true,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const walletconnect2ConnectorOptions: ConstructorParameters<typeof WalletConnectConnector>[0] = {
|
const walletconnect2ConnectorOptions: ConstructorParameters<typeof WalletConnectConnector>[0] = {
|
||||||
chains,
|
chains,
|
||||||
options: {
|
options: {
|
||||||
projectId: import.meta.env.VITE_WALLETCONNECT2_PROJECT_ID,
|
projectId: import.meta.env.VITE_WALLETCONNECT2_PROJECT_ID,
|
||||||
metadata: {
|
metadata: {
|
||||||
// TODO: update to local URLs/images
|
|
||||||
name: 'dYdX',
|
name: 'dYdX',
|
||||||
description: '',
|
description: '',
|
||||||
url: 'https://trade.dydx.exchange',
|
url: import.meta.env.VITE_BASE_URL,
|
||||||
icons: ['https://trade.dydx.exchange/cbw-image.png'],
|
icons: [`${import.meta.env.VITE_BASE_URL}/cbw-image.png}`],
|
||||||
},
|
},
|
||||||
showQrModal: true,
|
showQrModal: true,
|
||||||
qrModalOptions: {
|
qrModalOptions: {
|
||||||
themeMode: 'dark' as const,
|
themeMode: 'dark' as const,
|
||||||
themeVariables: {
|
themeVariables: {
|
||||||
'--w3m-accent-color': '#5973fe',
|
'--wcm-accent-color': '#5973fe',
|
||||||
'--w3m-background-color': '#5973fe',
|
'--wcm-font-family': 'var(--fontFamily-base)',
|
||||||
'--w3m-color-bg-1': 'var(--color-layer-3)',
|
|
||||||
'--w3m-color-bg-2': 'var(--color-layer-4)',
|
|
||||||
'--w3m-color-bg-3': 'var(--color-layer-5)',
|
|
||||||
'--w3m-font-family': 'var(--fontFamily-base)',
|
|
||||||
'--w3m-font-feature-settings': 'none',
|
|
||||||
'--w3m-overlay-backdrop-filter': 'blur(6px)',
|
|
||||||
// '--w3m-logo-image-url': 'https://trade.dydx.exchange/cbw-image.png',
|
|
||||||
},
|
},
|
||||||
enableExplorer: true,
|
explorerRecommendedWalletIds: WALLET_CONNECT_EXPLORER_RECOMMENDED_IDS,
|
||||||
explorerAllowList: [],
|
|
||||||
explorerDenyList: [],
|
|
||||||
chainImages: {},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@@ -133,7 +122,6 @@ const connectors = [
|
|||||||
chains,
|
chains,
|
||||||
options: {
|
options: {
|
||||||
shimDisconnect: true,
|
shimDisconnect: true,
|
||||||
shimChainChangedDisconnect: false,
|
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
new CoinbaseWalletConnector({
|
new CoinbaseWalletConnector({
|
||||||
@@ -143,7 +131,6 @@ const connectors = [
|
|||||||
reloadOnDisconnect: false,
|
reloadOnDisconnect: false,
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
new WalletConnectLegacyConnector(walletconnect1ConnectorOptions),
|
|
||||||
new WalletConnectConnector(walletconnect2ConnectorOptions),
|
new WalletConnectConnector(walletconnect2ConnectorOptions),
|
||||||
new InjectedConnector(injectedConnectorOptions),
|
new InjectedConnector(injectedConnectorOptions),
|
||||||
];
|
];
|
||||||
@@ -166,19 +153,6 @@ 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;
|
||||||
|
|
||||||
// Create a custom wagmi WalletConnectLegacyConnector with a modal showing only wallet links matching the given name
|
|
||||||
const createWalletConnect1ConnectorWithName = (walletconnect1Name: string) =>
|
|
||||||
new WalletConnectLegacyConnector({
|
|
||||||
...walletconnect1ConnectorOptions,
|
|
||||||
options: {
|
|
||||||
...walletconnect1ConnectorOptions.options,
|
|
||||||
qrcodeModalOptions: {
|
|
||||||
desktopLinks: [walletconnect1Name],
|
|
||||||
mobileLinks: [walletconnect1Name],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const createWalletConnect2ConnectorWithId = (walletconnect2Id: string) =>
|
const createWalletConnect2ConnectorWithId = (walletconnect2Id: string) =>
|
||||||
new WalletConnectConnector({
|
new WalletConnectConnector({
|
||||||
...walletconnect2ConnectorOptions,
|
...walletconnect2ConnectorOptions,
|
||||||
@@ -188,19 +162,11 @@ const createWalletConnect2ConnectorWithId = (walletconnect2Id: string) =>
|
|||||||
...walletconnect2ConnectorOptions.options.qrModalOptions,
|
...walletconnect2ConnectorOptions.options.qrModalOptions,
|
||||||
explorerRecommendedWalletIds: [walletconnect2Id],
|
explorerRecommendedWalletIds: [walletconnect2Id],
|
||||||
explorerExcludedWalletIds: 'ALL',
|
explorerExcludedWalletIds: 'ALL',
|
||||||
chainImages: {},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
// Custom connector from wallet selection
|
// Custom connector from wallet selection
|
||||||
import {
|
|
||||||
type WalletConnection,
|
|
||||||
WalletConnectionType,
|
|
||||||
type WalletType,
|
|
||||||
walletConnectionTypes,
|
|
||||||
wallets,
|
|
||||||
} from '@/constants/wallets';
|
|
||||||
|
|
||||||
export const resolveWagmiConnector = ({
|
export const resolveWagmiConnector = ({
|
||||||
walletType,
|
walletType,
|
||||||
@@ -214,9 +180,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.WalletConnect1 &&
|
|
||||||
walletConfig.walletconnect1Name
|
|
||||||
? createWalletConnect1ConnectorWithName(walletConfig.walletconnect1Name)
|
|
||||||
: walletConnection.type === WalletConnectionType.WalletConnect2 && walletConfig.walletconnect2Id
|
: walletConnection.type === WalletConnectionType.WalletConnect2 && walletConfig.walletconnect2Id
|
||||||
? createWalletConnect2ConnectorWithId(walletConfig.walletconnect2Id)
|
? createWalletConnect2ConnectorWithId(walletConfig.walletconnect2Id)
|
||||||
: connectors.find(({ id }: { id: string }) => id === walletConnectionConfig.wagmiConnectorId);
|
: connectors.find(({ id }: { id: string }) => id === walletConnectionConfig.wagmiConnectorId);
|
||||||
|
|||||||
@@ -45,12 +45,6 @@ export const getWalletConnection = ({
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case WalletConnectionType.WalletConnect1: {
|
|
||||||
return {
|
|
||||||
type: WalletConnectionType.WalletConnect1,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
case WalletConnectionType.WalletConnect2: {
|
case WalletConnectionType.WalletConnect2: {
|
||||||
return {
|
return {
|
||||||
type: WalletConnectionType.WalletConnect2,
|
type: WalletConnectionType.WalletConnect2,
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import { useMemo, useState } from 'react';
|
|||||||
import styled, { AnyStyledComponent, css } from 'styled-components';
|
import styled, { AnyStyledComponent, css } from 'styled-components';
|
||||||
import { shallowEqual, useSelector } from 'react-redux';
|
import { shallowEqual, useSelector } from 'react-redux';
|
||||||
import { TooltipContextType } from '@visx/xychart';
|
import { TooltipContextType } from '@visx/xychart';
|
||||||
|
import BigNumber from 'bignumber.js';
|
||||||
|
|
||||||
import type { Nullable } from '@/constants/abacus';
|
import type { Nullable } from '@/constants/abacus';
|
||||||
import { OnboardingState } from '@/constants/account';
|
import { OnboardingState } from '@/constants/account';
|
||||||
@@ -25,7 +26,6 @@ import { OnboardingTriggerButton } from '@/views/dialogs/OnboardingTriggerButton
|
|||||||
import { isTruthy } from '@/lib/isTruthy';
|
import { isTruthy } from '@/lib/isTruthy';
|
||||||
import { MustBigNumber } from '@/lib/numbers';
|
import { MustBigNumber } from '@/lib/numbers';
|
||||||
|
|
||||||
|
|
||||||
export const usePortfolioValues = ({
|
export const usePortfolioValues = ({
|
||||||
equity,
|
equity,
|
||||||
visibleData,
|
visibleData,
|
||||||
@@ -140,7 +140,12 @@ export const AccountDetailsAndHistory = () => {
|
|||||||
<Styled.AccountValue>
|
<Styled.AccountValue>
|
||||||
<Styled.WithLabel label={accountValueLabel}>
|
<Styled.WithLabel label={accountValueLabel}>
|
||||||
<Styled.AccountEquity>
|
<Styled.AccountEquity>
|
||||||
<Output type={OutputType.Fiat} value={accountEquity} withBaseFont />
|
<Output
|
||||||
|
type={OutputType.Fiat}
|
||||||
|
value={accountEquity}
|
||||||
|
roundingMode={BigNumber.ROUND_FLOOR}
|
||||||
|
withBaseFont
|
||||||
|
/>
|
||||||
</Styled.AccountEquity>
|
</Styled.AccountEquity>
|
||||||
<Styled.PnlDiff isPositive={MustBigNumber(pnlDiff).gte(0)}>
|
<Styled.PnlDiff isPositive={MustBigNumber(pnlDiff).gte(0)}>
|
||||||
{pnlDiff && <TriangleIndicator value={MustBigNumber(pnlDiff)} />}
|
{pnlDiff && <TriangleIndicator value={MustBigNumber(pnlDiff)} />}
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ import { configureStore } from '@reduxjs/toolkit';
|
|||||||
import abacusStateManager from '@/lib/abacus';
|
import abacusStateManager from '@/lib/abacus';
|
||||||
import appMiddleware from './appMiddleware';
|
import appMiddleware from './appMiddleware';
|
||||||
import localizationMiddleware from './localizationMiddleware';
|
import localizationMiddleware from './localizationMiddleware';
|
||||||
import routerMiddleware from './routerMiddleware';
|
|
||||||
|
|
||||||
import { accountSlice } from './account';
|
import { accountSlice } from './account';
|
||||||
import { appSlice } from './app';
|
import { appSlice } from './app';
|
||||||
@@ -13,7 +12,6 @@ import { dialogsSlice } from './dialogs';
|
|||||||
import { inputsSlice } from './inputs';
|
import { inputsSlice } from './inputs';
|
||||||
import { layoutSlice } from './layout';
|
import { layoutSlice } from './layout';
|
||||||
import { localizationSlice } from './localization';
|
import { localizationSlice } from './localization';
|
||||||
import { navigationSlice } from './navigation';
|
|
||||||
import { perpetualsSlice } from './perpetuals';
|
import { perpetualsSlice } from './perpetuals';
|
||||||
|
|
||||||
export const commandMenuSlices = [layoutSlice, localizationSlice];
|
export const commandMenuSlices = [layoutSlice, localizationSlice];
|
||||||
@@ -28,7 +26,6 @@ export const store = configureStore({
|
|||||||
inputs: inputsSlice.reducer,
|
inputs: inputsSlice.reducer,
|
||||||
layout: layoutSlice.reducer,
|
layout: layoutSlice.reducer,
|
||||||
localization: localizationSlice.reducer,
|
localization: localizationSlice.reducer,
|
||||||
navigation: navigationSlice.reducer,
|
|
||||||
perpetuals: perpetualsSlice.reducer,
|
perpetuals: perpetualsSlice.reducer,
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -38,7 +35,6 @@ export const store = configureStore({
|
|||||||
}),
|
}),
|
||||||
appMiddleware,
|
appMiddleware,
|
||||||
localizationMiddleware,
|
localizationMiddleware,
|
||||||
routerMiddleware,
|
|
||||||
],
|
],
|
||||||
|
|
||||||
devTools: process.env.NODE_ENV !== 'production',
|
devTools: process.env.NODE_ENV !== 'production',
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import type {
|
|||||||
SubaccountTransfers,
|
SubaccountTransfers,
|
||||||
HistoricalPnlPeriods,
|
HistoricalPnlPeriods,
|
||||||
SubAccountHistoricalPNLs,
|
SubAccountHistoricalPNLs,
|
||||||
|
UsageRestriction,
|
||||||
} from '@/constants/abacus';
|
} from '@/constants/abacus';
|
||||||
|
|
||||||
import { OnboardingGuard, OnboardingState } from '@/constants/account';
|
import { OnboardingGuard, OnboardingState } from '@/constants/account';
|
||||||
@@ -21,34 +22,46 @@ import { WalletType } from '@/constants/wallets';
|
|||||||
import { getLocalStorage } from '@/lib/localStorage';
|
import { getLocalStorage } from '@/lib/localStorage';
|
||||||
|
|
||||||
export type AccountState = {
|
export type AccountState = {
|
||||||
|
balances?: Record<string, AccountBalance>;
|
||||||
|
stakingBalances?: Record<string, AccountBalance>;
|
||||||
|
wallet?: Nullable<Wallet>;
|
||||||
|
walletType?: WalletType;
|
||||||
|
|
||||||
|
subaccount?: Nullable<Subaccount>;
|
||||||
fills?: SubaccountFills;
|
fills?: SubaccountFills;
|
||||||
fundingPayments?: SubaccountFundingPayments;
|
fundingPayments?: SubaccountFundingPayments;
|
||||||
transfers?: SubaccountTransfers;
|
transfers?: SubaccountTransfers;
|
||||||
|
historicalPnl?: SubAccountHistoricalPNLs;
|
||||||
|
|
||||||
|
onboardingGuards: Record<OnboardingGuard, boolean | undefined>;
|
||||||
|
onboardingState: OnboardingState;
|
||||||
|
|
||||||
clearedOrderIds?: string[];
|
clearedOrderIds?: string[];
|
||||||
hasUnseenFillUpdates: boolean;
|
hasUnseenFillUpdates: boolean;
|
||||||
hasUnseenOrderUpdates: boolean;
|
hasUnseenOrderUpdates: boolean;
|
||||||
historicalPnl?: SubAccountHistoricalPNLs;
|
|
||||||
latestOrder?: Nullable<SubaccountOrder>;
|
latestOrder?: Nullable<SubaccountOrder>;
|
||||||
onboardingGuards: Record<OnboardingGuard, boolean | undefined>;
|
|
||||||
onboardingState: OnboardingState;
|
|
||||||
subaccount?: Nullable<Subaccount>;
|
|
||||||
uncommittedOrderClientIds: number[];
|
|
||||||
wallet?: Nullable<Wallet>;
|
|
||||||
walletType?: WalletType;
|
|
||||||
historicalPnlPeriod?: HistoricalPnlPeriods;
|
historicalPnlPeriod?: HistoricalPnlPeriods;
|
||||||
balances?: Record<string, AccountBalance>;
|
uncommittedOrderClientIds: number[];
|
||||||
stakingBalances?: Record<string, AccountBalance>;
|
|
||||||
|
restriction?: Nullable<UsageRestriction>;
|
||||||
};
|
};
|
||||||
|
|
||||||
const initialState: AccountState = {
|
const initialState: AccountState = {
|
||||||
|
// Wallet
|
||||||
|
balances: undefined,
|
||||||
|
wallet: undefined,
|
||||||
|
walletType: getLocalStorage<WalletType>({
|
||||||
|
key: LocalStorageKey.OnboardingSelectedWalletType,
|
||||||
|
}),
|
||||||
|
|
||||||
|
// Subaccount
|
||||||
|
subaccount: undefined,
|
||||||
fills: undefined,
|
fills: undefined,
|
||||||
fundingPayments: undefined,
|
fundingPayments: undefined,
|
||||||
transfers: undefined,
|
transfers: undefined,
|
||||||
clearedOrderIds: undefined,
|
|
||||||
hasUnseenFillUpdates: false,
|
|
||||||
hasUnseenOrderUpdates: false,
|
|
||||||
historicalPnl: undefined,
|
historicalPnl: undefined,
|
||||||
latestOrder: undefined,
|
|
||||||
|
// Onboarding
|
||||||
onboardingGuards: {
|
onboardingGuards: {
|
||||||
[OnboardingGuard.hasAcknowledgedTerms]: Boolean(
|
[OnboardingGuard.hasAcknowledgedTerms]: Boolean(
|
||||||
getLocalStorage<boolean>({
|
getLocalStorage<boolean>({
|
||||||
@@ -59,12 +72,17 @@ const initialState: AccountState = {
|
|||||||
[OnboardingGuard.hasPreviousTransactions]: undefined,
|
[OnboardingGuard.hasPreviousTransactions]: undefined,
|
||||||
},
|
},
|
||||||
onboardingState: OnboardingState.Disconnected,
|
onboardingState: OnboardingState.Disconnected,
|
||||||
subaccount: undefined,
|
|
||||||
|
// UI
|
||||||
|
clearedOrderIds: undefined,
|
||||||
|
hasUnseenFillUpdates: false,
|
||||||
|
hasUnseenOrderUpdates: false,
|
||||||
|
latestOrder: undefined,
|
||||||
uncommittedOrderClientIds: [],
|
uncommittedOrderClientIds: [],
|
||||||
wallet: undefined,
|
historicalPnlPeriod: undefined,
|
||||||
walletType: getLocalStorage<WalletType>({
|
|
||||||
key: LocalStorageKey.OnboardingSelectedWalletType,
|
// Restriction
|
||||||
}),
|
restriction: undefined,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const accountSlice = createSlice({
|
export const accountSlice = createSlice({
|
||||||
@@ -124,6 +142,9 @@ export const accountSlice = createSlice({
|
|||||||
state.historicalPnl = action.payload;
|
state.historicalPnl = action.payload;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
setRestrictionType: (state, action: PayloadAction<Nullable<UsageRestriction>>) => {
|
||||||
|
state.restriction = action.payload;
|
||||||
|
},
|
||||||
setSubaccount: (state, action: PayloadAction<Nullable<Subaccount>>) => {
|
setSubaccount: (state, action: PayloadAction<Nullable<Subaccount>>) => {
|
||||||
const existingOrderIds = state.subaccount?.orders
|
const existingOrderIds = state.subaccount?.orders
|
||||||
? state.subaccount.orders.toArray().map((order) => order.id)
|
? state.subaccount.orders.toArray().map((order) => order.id)
|
||||||
@@ -178,6 +199,7 @@ export const {
|
|||||||
setOnboardingGuard,
|
setOnboardingGuard,
|
||||||
setOnboardingState,
|
setOnboardingState,
|
||||||
setHistoricalPnl,
|
setHistoricalPnl,
|
||||||
|
setRestrictionType,
|
||||||
setSubaccount,
|
setSubaccount,
|
||||||
setWallet,
|
setWallet,
|
||||||
viewedFills,
|
viewedFills,
|
||||||
|
|||||||
@@ -342,3 +342,13 @@ export const getBalances = (state: RootState) => state.account?.balances;
|
|||||||
* @returns user wallet staking balances
|
* @returns user wallet staking balances
|
||||||
* */
|
* */
|
||||||
export const getStakingBalances = (state: RootState) => state.account?.stakingBalances;
|
export const getStakingBalances = (state: RootState) => state.account?.stakingBalances;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns UsageRestriction of the current session
|
||||||
|
*/
|
||||||
|
export const getUsageRestriction = (state: RootState) => state.account.restriction;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns RestrictionType from the current session
|
||||||
|
*/
|
||||||
|
export const getRestrictionType = (state: RootState) => state.account.restriction?.restriction;
|
||||||
|
|||||||
@@ -2,10 +2,10 @@ import { createSlice, PayloadAction } from '@reduxjs/toolkit';
|
|||||||
|
|
||||||
import { AbacusApiState } from '@/constants/abacus';
|
import { AbacusApiState } from '@/constants/abacus';
|
||||||
import { LocalStorageKey } from '@/constants/localStorage';
|
import { LocalStorageKey } from '@/constants/localStorage';
|
||||||
|
|
||||||
import { DEFAULT_APP_ENVIRONMENT, type DydxNetwork } from '@/constants/networks';
|
import { DEFAULT_APP_ENVIRONMENT, type DydxNetwork } from '@/constants/networks';
|
||||||
|
|
||||||
import { getLocalStorage } from '@/lib/localStorage';
|
import { getLocalStorage } from '@/lib/localStorage';
|
||||||
|
import { validateAgainstAvailableEnvironments } from '@/lib/network';
|
||||||
|
|
||||||
export interface AppState {
|
export interface AppState {
|
||||||
apiState: AbacusApiState | undefined;
|
apiState: AbacusApiState | undefined;
|
||||||
@@ -19,6 +19,7 @@ const initialState: AppState = {
|
|||||||
selectedNetwork: getLocalStorage({
|
selectedNetwork: getLocalStorage({
|
||||||
key: LocalStorageKey.SelectedNetwork,
|
key: LocalStorageKey.SelectedNetwork,
|
||||||
defaultValue: DEFAULT_APP_ENVIRONMENT,
|
defaultValue: DEFAULT_APP_ENVIRONMENT,
|
||||||
|
validateFn: validateAgainstAvailableEnvironments,
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -23,39 +23,36 @@ export const dialogsSlice = createSlice({
|
|||||||
name: 'Dialogs',
|
name: 'Dialogs',
|
||||||
initialState,
|
initialState,
|
||||||
reducers: {
|
reducers: {
|
||||||
addDialogToQueue: (state: DialogsState, action: PayloadAction<DialogInfo<DialogTypes>>) => {
|
openDialog: (state: DialogsState, action: PayloadAction<DialogInfo<DialogTypes>>) => {
|
||||||
const dialogQueue = state.dialogQueue;
|
if (state.activeDialog) {
|
||||||
dialogQueue.push(action.payload);
|
state.dialogQueue.push(action.payload);
|
||||||
|
} else {
|
||||||
return {
|
state.activeDialog = action.payload;
|
||||||
...state,
|
}
|
||||||
dialogQueue,
|
},
|
||||||
};
|
closeDialog: (state: DialogsState) => {
|
||||||
|
state.activeDialog = state.dialogQueue.shift();
|
||||||
|
},
|
||||||
|
forceOpenDialog: (state: DialogsState, action: PayloadAction<DialogInfo<DialogTypes>>) => {
|
||||||
|
if (state.activeDialog) {
|
||||||
|
state.dialogQueue.unshift(state.activeDialog);
|
||||||
|
}
|
||||||
|
state.activeDialog = action.payload;
|
||||||
|
},
|
||||||
|
closeDialogInTradeBox: (state: DialogsState) => {
|
||||||
|
state.activeTradeBoxDialog = undefined;
|
||||||
},
|
},
|
||||||
closeDialog: (state: DialogsState) => ({
|
|
||||||
...state,
|
|
||||||
activeDialog: state.dialogQueue.shift(),
|
|
||||||
}),
|
|
||||||
openDialog: (state: DialogsState, action: PayloadAction<DialogInfo<DialogTypes>>) => ({
|
|
||||||
...state,
|
|
||||||
activeDialog: action.payload,
|
|
||||||
}),
|
|
||||||
closeDialogInTradeBox: (state: DialogsState) => ({
|
|
||||||
...state,
|
|
||||||
activeTradeBoxDialog: undefined,
|
|
||||||
}),
|
|
||||||
openDialogInTradeBox: (
|
openDialogInTradeBox: (
|
||||||
state: DialogsState,
|
state: DialogsState,
|
||||||
action: PayloadAction<DialogInfo<TradeBoxDialogTypes>>
|
action: PayloadAction<DialogInfo<TradeBoxDialogTypes>>
|
||||||
) => ({
|
) => {
|
||||||
...state,
|
state.activeTradeBoxDialog = action.payload;
|
||||||
activeTradeBoxDialog: action.payload,
|
},
|
||||||
}),
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export const {
|
export const {
|
||||||
addDialogToQueue,
|
forceOpenDialog,
|
||||||
closeDialog,
|
closeDialog,
|
||||||
closeDialogInTradeBox,
|
closeDialogInTradeBox,
|
||||||
openDialog,
|
openDialog,
|
||||||
|
|||||||
@@ -1,42 +0,0 @@
|
|||||||
import { createSlice } from '@reduxjs/toolkit';
|
|
||||||
|
|
||||||
export interface NavigationState {
|
|
||||||
tradeLocation: {
|
|
||||||
hash: string;
|
|
||||||
key: string;
|
|
||||||
pathname: string;
|
|
||||||
search: string;
|
|
||||||
state: any;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export const CLEAR_TRADE_LOCATION = {
|
|
||||||
hash: '',
|
|
||||||
key: '',
|
|
||||||
pathname: '',
|
|
||||||
search: '',
|
|
||||||
state: null,
|
|
||||||
};
|
|
||||||
|
|
||||||
const initialState: NavigationState = {
|
|
||||||
tradeLocation: {
|
|
||||||
hash: '',
|
|
||||||
key: '',
|
|
||||||
pathname: '',
|
|
||||||
search: '',
|
|
||||||
state: null,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
export const navigationSlice = createSlice({
|
|
||||||
name: 'Navigation',
|
|
||||||
initialState,
|
|
||||||
reducers: {
|
|
||||||
setTradeLocation: (state, { payload }) => ({
|
|
||||||
...state,
|
|
||||||
tradeLocation: payload,
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
export const { setTradeLocation } = navigationSlice.actions;
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
import type { PayloadAction } from '@reduxjs/toolkit';
|
|
||||||
|
|
||||||
import { LocalStorageKey } from '@/constants/localStorage';
|
|
||||||
|
|
||||||
import { closeDialogInTradeBox } from '@/state/dialogs';
|
|
||||||
import { setTradeLocation } from '@/state/navigation';
|
|
||||||
|
|
||||||
import abacusStateManager from '@/lib/abacus';
|
|
||||||
import { setLocalStorage } from '@/lib/localStorage';
|
|
||||||
import { getMarketIdFromLocation } from '@/lib/tradeData';
|
|
||||||
|
|
||||||
export default (store: any) => (next: any) => async (action: PayloadAction<any>) => {
|
|
||||||
next(action);
|
|
||||||
|
|
||||||
const { type, payload } = action;
|
|
||||||
|
|
||||||
switch (type) {
|
|
||||||
case setTradeLocation.type: {
|
|
||||||
const marketId = getMarketIdFromLocation(payload);
|
|
||||||
|
|
||||||
if (marketId) {
|
|
||||||
abacusStateManager.setMarket(marketId);
|
|
||||||
store.dispatch(closeDialogInTradeBox());
|
|
||||||
setLocalStorage({ key: LocalStorageKey.LastViewedMarket, value: marketId });
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
import { useCallback, useState, useMemo } from 'react';
|
import { useCallback, useState, useMemo } from 'react';
|
||||||
import styled, { type AnyStyledComponent } from 'styled-components';
|
import styled, { type AnyStyledComponent } from 'styled-components';
|
||||||
import { TESTNET_CHAIN_ID } from '@dydxprotocol/v4-client-js';
|
|
||||||
import { Root, Trigger, Content } from '@radix-ui/react-collapsible';
|
import { Root, Trigger, Content } from '@radix-ui/react-collapsible';
|
||||||
import { StatusResponse } from '@0xsquid/sdk';
|
import { StatusResponse } from '@0xsquid/sdk';
|
||||||
|
|
||||||
@@ -21,12 +20,14 @@ import { LoadingDots } from '@/components/Loading/LoadingDots';
|
|||||||
import { layoutMixins } from '@/styles/layoutMixins';
|
import { layoutMixins } from '@/styles/layoutMixins';
|
||||||
|
|
||||||
type ElementProps = {
|
type ElementProps = {
|
||||||
|
type: 'withdrawal' | 'deposit';
|
||||||
toAmount?: number;
|
toAmount?: number;
|
||||||
triggeredAt?: number;
|
triggeredAt?: number;
|
||||||
status?: StatusResponse;
|
status?: StatusResponse;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const TransferStatusToast = ({
|
export const TransferStatusToast = ({
|
||||||
|
type,
|
||||||
toAmount,
|
toAmount,
|
||||||
triggeredAt = Date.now(),
|
triggeredAt = Date.now(),
|
||||||
status,
|
status,
|
||||||
@@ -38,11 +39,6 @@ export const TransferStatusToast = ({
|
|||||||
// @ts-ignore status.errors is not in the type definition but can be returned
|
// @ts-ignore status.errors is not in the type definition but can be returned
|
||||||
const error = status?.errors?.length ? status?.errors[0] : status?.error;
|
const error = status?.errors?.length ? status?.errors[0] : status?.error;
|
||||||
|
|
||||||
const type = useMemo(
|
|
||||||
() => (status?.toChain?.chainData?.chainId === TESTNET_CHAIN_ID ? 'deposit' : 'withdrawal'),
|
|
||||||
[status]
|
|
||||||
);
|
|
||||||
|
|
||||||
const updateSecondsLeft = useCallback(() => {
|
const updateSecondsLeft = useCallback(() => {
|
||||||
const fromChainEta = (status?.fromChain?.chainData?.estimatedRouteDuration || 0) * 1000;
|
const fromChainEta = (status?.fromChain?.chainData?.estimatedRouteDuration || 0) * 1000;
|
||||||
const toChainEta = (status?.toChain?.chainData?.estimatedRouteDuration || 0) * 1000;
|
const toChainEta = (status?.toChain?.chainData?.estimatedRouteDuration || 0) * 1000;
|
||||||
@@ -69,7 +65,7 @@ export const TransferStatusToast = ({
|
|||||||
side="bottom"
|
side="bottom"
|
||||||
slotReceipt={
|
slotReceipt={
|
||||||
<Styled.Receipt>
|
<Styled.Receipt>
|
||||||
<TransferStatusSteps status={status} />
|
<TransferStatusSteps status={status} type={type} />
|
||||||
</Styled.Receipt>
|
</Styled.Receipt>
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import { useMemo } from 'react';
|
import { useMemo } from 'react';
|
||||||
import styled, { css, keyframes, type AnyStyledComponent } from 'styled-components';
|
import styled, { css, keyframes, type AnyStyledComponent } from 'styled-components';
|
||||||
import { StatusResponse } from '@0xsquid/sdk';
|
import { StatusResponse } from '@0xsquid/sdk';
|
||||||
import { TESTNET_CHAIN_ID } from '@dydxprotocol/v4-client-js';
|
|
||||||
|
|
||||||
import { useStringGetter } from '@/hooks';
|
import { useStringGetter } from '@/hooks';
|
||||||
|
|
||||||
@@ -15,6 +14,7 @@ import { STRING_KEYS } from '@/constants/localization';
|
|||||||
|
|
||||||
type ElementProps = {
|
type ElementProps = {
|
||||||
status?: StatusResponse;
|
status?: StatusResponse;
|
||||||
|
type: 'withdrawal' | 'deposit';
|
||||||
};
|
};
|
||||||
|
|
||||||
enum TransferStatusStep {
|
enum TransferStatusStep {
|
||||||
@@ -24,14 +24,13 @@ enum TransferStatusStep {
|
|||||||
Complete,
|
Complete,
|
||||||
}
|
}
|
||||||
|
|
||||||
export const TransferStatusSteps = ({ status }: ElementProps) => {
|
export const TransferStatusSteps = ({ status, type }: ElementProps) => {
|
||||||
const stringGetter = useStringGetter();
|
const stringGetter = useStringGetter();
|
||||||
|
|
||||||
const { currentStep, steps, type } = useMemo(() => {
|
const { currentStep, steps } = useMemo(() => {
|
||||||
const routeStatus = status?.routeStatus;
|
const routeStatus = status?.routeStatus;
|
||||||
const fromChain = status?.fromChain?.chainData?.chainId;
|
const fromChain = status?.fromChain?.chainData?.chainId;
|
||||||
const toChain = status?.toChain?.chainData?.chainId;
|
const toChain = status?.toChain?.chainData?.chainId;
|
||||||
const type = toChain === TESTNET_CHAIN_ID ? 'deposit' : 'withdrawal';
|
|
||||||
|
|
||||||
const steps = [
|
const steps = [
|
||||||
{
|
{
|
||||||
@@ -74,6 +73,10 @@ export const TransferStatusSteps = ({ status }: ElementProps) => {
|
|||||||
currentStep = TransferStatusStep.FromChain;
|
currentStep = TransferStatusStep.FromChain;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (status?.squidTransactionStatus === 'success') {
|
||||||
|
currentStep = TransferStatusStep.Complete;
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
currentStep,
|
currentStep,
|
||||||
steps,
|
steps,
|
||||||
|
|||||||
@@ -25,7 +25,11 @@ import { TimeSeriesChart } from '@/components/visx/TimeSeriesChart';
|
|||||||
import { AxisLabelOutput } from '@/components/visx/AxisLabelOutput';
|
import { AxisLabelOutput } from '@/components/visx/AxisLabelOutput';
|
||||||
// import { TooltipContent } from '@/components/visx/TooltipContent';
|
// import { TooltipContent } from '@/components/visx/TooltipContent';
|
||||||
|
|
||||||
import { getSubaccount, getSubaccountHistoricalPnl, getSubaccountId } from '@/state/accountSelectors';
|
import {
|
||||||
|
getSubaccount,
|
||||||
|
getSubaccountHistoricalPnl,
|
||||||
|
getSubaccountId,
|
||||||
|
} from '@/state/accountSelectors';
|
||||||
|
|
||||||
import abacusStateManager from '@/lib/abacus';
|
import abacusStateManager from '@/lib/abacus';
|
||||||
import { formatRelativeTime } from '@/lib/dateTime';
|
import { formatRelativeTime } from '@/lib/dateTime';
|
||||||
|
|||||||
@@ -27,9 +27,9 @@ export const DisconnectDialog = ({ setIsOpen }: ElementProps) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dialog isOpen setIsOpen={setIsOpen} title="Disconnect">
|
<Dialog isOpen setIsOpen={setIsOpen} title={stringGetter({ key: STRING_KEYS.DISCONNECT })}>
|
||||||
<Styled.Content>
|
<Styled.Content>
|
||||||
<p>Are you sure you want to disconnect your account?</p>
|
<p>{stringGetter({ key: STRING_KEYS.DISCONNECT_CONFIRMATION })}</p>
|
||||||
<Styled.ButtonRow>
|
<Styled.ButtonRow>
|
||||||
<Close asChild>
|
<Close asChild>
|
||||||
<Button action={ButtonAction.Destroy} onClick={disconnect}>
|
<Button action={ButtonAction.Destroy} onClick={disconnect}>
|
||||||
|
|||||||
@@ -5,6 +5,9 @@ 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';
|
||||||
|
|
||||||
@@ -29,8 +32,16 @@ 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 (activeDialog?.type === DialogTypes.ExchangeOffline && status === AbacusApiStatus.NORMAL) {
|
if (
|
||||||
|
activeDialog?.type === DialogTypes.ExchangeOffline &&
|
||||||
|
status === AbacusApiStatus.NORMAL &&
|
||||||
|
!showOfflineMessage
|
||||||
|
) {
|
||||||
dispatch(closeDialog());
|
dispatch(closeDialog());
|
||||||
}
|
}
|
||||||
}, [status, selectedNetwork]);
|
}, [status, selectedNetwork]);
|
||||||
@@ -43,7 +54,16 @@ export const ExchangeOfflineDialog = ({ preventClose, setIsOpen }: ElementProps)
|
|||||||
title={stringGetter({ key: STRING_KEYS.UNAVAILABLE })}
|
title={stringGetter({ key: STRING_KEYS.UNAVAILABLE })}
|
||||||
>
|
>
|
||||||
<Styled.Content>
|
<Styled.Content>
|
||||||
<p>{statusErrorMessage}</p>
|
{showOfflineMessage ? (
|
||||||
|
<>
|
||||||
|
<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>
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ import { useDisplayedWallets } from '@/hooks/useDisplayedWallets';
|
|||||||
import { breakpoints } from '@/styles';
|
import { breakpoints } from '@/styles';
|
||||||
import { layoutMixins } from '@/styles/layoutMixins';
|
import { layoutMixins } from '@/styles/layoutMixins';
|
||||||
|
|
||||||
const aboutWalletsLink = `https://www.dydxacademy.info/educational-video-series/onboarding-to-defi-with-dydx`;
|
const aboutWalletsLink = `https://www.dydx.academy/video/defi-wallet`;
|
||||||
|
|
||||||
export const ChooseWallet = () => {
|
export const ChooseWallet = () => {
|
||||||
const stringGetter = useStringGetter();
|
const stringGetter = useStringGetter();
|
||||||
@@ -34,7 +34,14 @@ export const ChooseWallet = () => {
|
|||||||
<Styled.AlertMessage type={AlertType.Error}>
|
<Styled.AlertMessage type={AlertType.Error}>
|
||||||
{
|
{
|
||||||
<h4>
|
<h4>
|
||||||
Couldn't connect to {stringGetter({ key: wallets[selectedWalletType].stringKey })}.
|
{stringGetter({
|
||||||
|
key: STRING_KEYS.COULD_NOT_CONNECT,
|
||||||
|
params: {
|
||||||
|
WALLET: stringGetter({
|
||||||
|
key: wallets[selectedWalletType].stringKey,
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
})}
|
||||||
</h4>
|
</h4>
|
||||||
}
|
}
|
||||||
{selectedWalletError}
|
{selectedWalletError}
|
||||||
|
|||||||
@@ -0,0 +1,42 @@
|
|||||||
|
import styled, { AnyStyledComponent } from 'styled-components';
|
||||||
|
|
||||||
|
import { STRING_KEYS } from '@/constants/localization';
|
||||||
|
import { useStringGetter } from '@/hooks';
|
||||||
|
import { layoutMixins } from '@/styles/layoutMixins';
|
||||||
|
|
||||||
|
import { Dialog } from '@/components/Dialog';
|
||||||
|
import { Icon, IconName } from '@/components/Icon';
|
||||||
|
|
||||||
|
type ElementProps = {
|
||||||
|
preventClose?: boolean;
|
||||||
|
setIsOpen?: (open: boolean) => void;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const RateLimitDialog = ({ preventClose, setIsOpen }: ElementProps) => {
|
||||||
|
const stringGetter = useStringGetter();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Dialog
|
||||||
|
isOpen
|
||||||
|
preventClose={preventClose}
|
||||||
|
setIsOpen={setIsOpen}
|
||||||
|
title={stringGetter({ key: STRING_KEYS.RATE_LIMIT_REACHED_ERROR_TITLE })}
|
||||||
|
slotIcon={<Styled.Icon iconName={IconName.Warning} />}
|
||||||
|
>
|
||||||
|
<Styled.Content>
|
||||||
|
{stringGetter({ key: STRING_KEYS.RATE_LIMIT_REACHED_ERROR_MESSAGE })}
|
||||||
|
</Styled.Content>
|
||||||
|
</Dialog>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const Styled: Record<string, AnyStyledComponent> = {};
|
||||||
|
|
||||||
|
Styled.Icon = styled(Icon)`
|
||||||
|
color: var(--color-warning);
|
||||||
|
`;
|
||||||
|
|
||||||
|
Styled.Content = styled.div`
|
||||||
|
${layoutMixins.column}
|
||||||
|
gap: 1rem;
|
||||||
|
`;
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
import styled, { AnyStyledComponent } from 'styled-components';
|
||||||
|
|
||||||
|
import { STRING_KEYS } from '@/constants/localization';
|
||||||
|
import { useStringGetter } from '@/hooks';
|
||||||
|
import { layoutMixins } from '@/styles/layoutMixins';
|
||||||
|
|
||||||
|
import { Dialog } from '@/components/Dialog';
|
||||||
|
import { Icon, IconName } from '@/components/Icon';
|
||||||
|
|
||||||
|
type ElementProps = {
|
||||||
|
preventClose?: boolean;
|
||||||
|
setIsOpen?: (open: boolean) => void;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const RestrictedGeoDialog = ({ preventClose, setIsOpen }: ElementProps) => {
|
||||||
|
const stringGetter = useStringGetter();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Dialog
|
||||||
|
isOpen
|
||||||
|
preventClose={preventClose}
|
||||||
|
setIsOpen={setIsOpen}
|
||||||
|
title={stringGetter({ key: STRING_KEYS.REGION_NOT_PERMITTED_TITLE })}
|
||||||
|
slotIcon={<Styled.Icon iconName={IconName.Warning} />}
|
||||||
|
>
|
||||||
|
<Styled.Content>
|
||||||
|
{stringGetter({ key: STRING_KEYS.REGION_NOT_PERMITTED_SUBTITLE })}
|
||||||
|
</Styled.Content>
|
||||||
|
</Dialog>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const Styled: Record<string, AnyStyledComponent> = {};
|
||||||
|
|
||||||
|
Styled.Icon = styled(Icon)`
|
||||||
|
color: var(--color-warning);
|
||||||
|
`;
|
||||||
|
|
||||||
|
Styled.Content = styled.div`
|
||||||
|
${layoutMixins.column}
|
||||||
|
gap: 1rem;
|
||||||
|
`;
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
import styled, { AnyStyledComponent } from 'styled-components';
|
||||||
|
|
||||||
|
import { STRING_KEYS } from '@/constants/localization';
|
||||||
|
import { useStringGetter } from '@/hooks';
|
||||||
|
import { layoutMixins } from '@/styles/layoutMixins';
|
||||||
|
|
||||||
|
import { Dialog } from '@/components/Dialog';
|
||||||
|
import { Icon, IconName } from '@/components/Icon';
|
||||||
|
|
||||||
|
type ElementProps = {
|
||||||
|
preventClose?: boolean;
|
||||||
|
setIsOpen?: (open: boolean) => void;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const RestrictedWalletDialog = ({ preventClose, setIsOpen }: ElementProps) => {
|
||||||
|
const stringGetter = useStringGetter();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Dialog
|
||||||
|
isOpen
|
||||||
|
preventClose={preventClose}
|
||||||
|
setIsOpen={setIsOpen}
|
||||||
|
title={stringGetter({ key: STRING_KEYS.WALLET_RESTRICTED_ERROR_TITLE })}
|
||||||
|
slotIcon={<Styled.Icon iconName={IconName.Warning} />}
|
||||||
|
>
|
||||||
|
<Styled.Content>
|
||||||
|
{stringGetter({ key: STRING_KEYS.REGION_NOT_PERMITTED_SUBTITLE })}
|
||||||
|
</Styled.Content>
|
||||||
|
</Dialog>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const Styled: Record<string, AnyStyledComponent> = {};
|
||||||
|
|
||||||
|
Styled.Icon = styled(Icon)`
|
||||||
|
color: var(--color-warning);
|
||||||
|
`;
|
||||||
|
|
||||||
|
Styled.Content = styled.div`
|
||||||
|
${layoutMixins.column}
|
||||||
|
gap: 1rem;
|
||||||
|
`;
|
||||||
@@ -10,9 +10,16 @@ import { TransferInputField, TransferInputTokenResource, TransferType } from '@/
|
|||||||
import { AlertType } from '@/constants/alerts';
|
import { AlertType } from '@/constants/alerts';
|
||||||
import { ButtonSize } from '@/constants/buttons';
|
import { ButtonSize } from '@/constants/buttons';
|
||||||
import { STRING_KEYS } from '@/constants/localization';
|
import { STRING_KEYS } from '@/constants/localization';
|
||||||
import { NumberSign, QUANTUM_MULTIPLIER } from '@/constants/numbers';
|
import { NumberSign } from '@/constants/numbers';
|
||||||
|
|
||||||
import { useDebounce, useStringGetter, useSubaccount } from '@/hooks';
|
import {
|
||||||
|
useAccounts,
|
||||||
|
useDebounce,
|
||||||
|
useDydxClient,
|
||||||
|
useRestrictions,
|
||||||
|
useStringGetter,
|
||||||
|
useSubaccount,
|
||||||
|
} from '@/hooks';
|
||||||
import { useLocalNotifications } from '@/hooks/useLocalNotifications';
|
import { useLocalNotifications } from '@/hooks/useLocalNotifications';
|
||||||
|
|
||||||
import { layoutMixins } from '@/styles/layoutMixins';
|
import { layoutMixins } from '@/styles/layoutMixins';
|
||||||
@@ -39,10 +46,11 @@ import { MustBigNumber } from '@/lib/numbers';
|
|||||||
|
|
||||||
import { TokenSelectMenu } from './TokenSelectMenu';
|
import { TokenSelectMenu } from './TokenSelectMenu';
|
||||||
import { WithdrawButtonAndReceipt } from './WithdrawForm/WithdrawButtonAndReceipt';
|
import { WithdrawButtonAndReceipt } from './WithdrawForm/WithdrawButtonAndReceipt';
|
||||||
|
import { join } from 'path';
|
||||||
|
|
||||||
export const WithdrawForm = () => {
|
export const WithdrawForm = () => {
|
||||||
const stringGetter = useStringGetter();
|
const stringGetter = useStringGetter();
|
||||||
const [error, setError] = useState<Error | null>(null);
|
const [error, setError] = useState<string>();
|
||||||
const [isLoading, setIsLoading] = useState(false);
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
|
|
||||||
const { sendSquidWithdraw } = useSubaccount();
|
const { sendSquidWithdraw } = useSubaccount();
|
||||||
@@ -71,9 +79,11 @@ export const WithdrawForm = () => {
|
|||||||
const { addTransferNotification } = useLocalNotifications();
|
const { addTransferNotification } = useLocalNotifications();
|
||||||
|
|
||||||
// Async Data
|
// Async Data
|
||||||
const debouncedAmountBN = MustBigNumber(debouncedAmount);
|
const debouncedAmountBN = useMemo(() => MustBigNumber(debouncedAmount), [debouncedAmount]);
|
||||||
const withdrawAmountBN = MustBigNumber(withdrawAmount);
|
const freeCollateralBN = useMemo(
|
||||||
const freeCollateralBN = MustBigNumber(freeCollateral?.current);
|
() => MustBigNumber(freeCollateral?.current),
|
||||||
|
[freeCollateral?.current]
|
||||||
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
abacusStateManager.setTransferValue({
|
abacusStateManager.setTransferValue({
|
||||||
@@ -105,50 +115,85 @@ export const WithdrawForm = () => {
|
|||||||
value: debouncedAmount,
|
value: debouncedAmount,
|
||||||
field: TransferInputField.usdcSize,
|
field: TransferInputField.usdcSize,
|
||||||
});
|
});
|
||||||
setError(null);
|
setError(undefined);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
setError(error);
|
setError(error.message);
|
||||||
} finally {
|
} finally {
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
setTransferValue();
|
setTransferValue();
|
||||||
}, [debouncedAmountBN.toNumber()]);
|
}, [debouncedAmountBN]);
|
||||||
|
|
||||||
|
const { screenAddresses } = useDydxClient();
|
||||||
|
const { dydxAddress } = useAccounts();
|
||||||
|
|
||||||
const onSubmit = useCallback(
|
const onSubmit = useCallback(
|
||||||
async (e: FormEvent) => {
|
async (e: FormEvent) => {
|
||||||
try {
|
try {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
if (!requestPayload?.data || !debouncedAmountBN.toNumber()) {
|
if (!requestPayload?.data || !debouncedAmountBN.toNumber() || !toAddress || !dydxAddress) {
|
||||||
throw new Error('Invalid request payload');
|
throw new Error('Invalid request payload');
|
||||||
}
|
}
|
||||||
|
|
||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
const txHash = await sendSquidWithdraw(debouncedAmountBN.toNumber(), requestPayload?.data);
|
setError(undefined);
|
||||||
|
|
||||||
if (txHash?.hash) {
|
const screenResults = await screenAddresses({
|
||||||
const hash = `0x${Buffer.from(txHash.hash).toString('hex')}`;
|
addresses: [toAddress, dydxAddress],
|
||||||
|
});
|
||||||
|
|
||||||
addTransferNotification({
|
if (screenResults?.[dydxAddress]) {
|
||||||
txHash: hash,
|
setError(
|
||||||
fromChainId: TESTNET_CHAIN_ID,
|
stringGetter({
|
||||||
toChainId: chainIdStr || undefined,
|
key: STRING_KEYS.WALLET_RESTRICTED_WITHDRAWAL_TRANSFER_ORIGINATION_ERROR_MESSAGE,
|
||||||
toAmount: debouncedAmountBN.toNumber(),
|
})
|
||||||
triggeredAt: Date.now(),
|
);
|
||||||
});
|
} else if (screenResults?.[toAddress]) {
|
||||||
abacusStateManager.clearTransferInputValues();
|
setError(
|
||||||
setWithdrawAmount('');
|
stringGetter({
|
||||||
|
key: STRING_KEYS.WALLET_RESTRICTED_WITHDRAWAL_TRANSFER_DESTINATION_ERROR_MESSAGE,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
const txHash = await sendSquidWithdraw(debouncedAmountBN.toNumber(), requestPayload.data);
|
||||||
|
if (txHash?.hash) {
|
||||||
|
const hash = `0x${Buffer.from(txHash.hash).toString('hex')}`;
|
||||||
|
addTransferNotification({
|
||||||
|
txHash: hash,
|
||||||
|
fromChainId: TESTNET_CHAIN_ID,
|
||||||
|
toChainId: chainIdStr || undefined,
|
||||||
|
toAmount: debouncedAmountBN.toNumber(),
|
||||||
|
triggeredAt: Date.now(),
|
||||||
|
});
|
||||||
|
abacusStateManager.clearTransferInputValues();
|
||||||
|
setWithdrawAmount('');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
setError(error);
|
if (error?.code === 429) {
|
||||||
|
setError(stringGetter({ key: STRING_KEYS.RATE_LIMIT_REACHED_ERROR_MESSAGE }));
|
||||||
|
} else {
|
||||||
|
setError(
|
||||||
|
error.message
|
||||||
|
? stringGetter({
|
||||||
|
key: STRING_KEYS.SOMETHING_WENT_WRONG_WITH_MESSAGE,
|
||||||
|
params: {
|
||||||
|
ERROR_MESSAGE:
|
||||||
|
error.message || stringGetter({ key: STRING_KEYS.UNKNOWN_ERROR }),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
: stringGetter({ key: STRING_KEYS.SOMETHING_WENT_WRONG })
|
||||||
|
);
|
||||||
|
}
|
||||||
} finally {
|
} finally {
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[requestPayload, debouncedAmountBN, chainIdStr]
|
[requestPayload, debouncedAmountBN, chainIdStr, toAddress, screenAddresses, stringGetter]
|
||||||
);
|
);
|
||||||
|
|
||||||
const onChangeAddress = useCallback((e: ChangeEvent<HTMLInputElement>) => {
|
const onChangeAddress = useCallback((e: ChangeEvent<HTMLInputElement>) => {
|
||||||
@@ -179,7 +224,7 @@ export const WithdrawForm = () => {
|
|||||||
|
|
||||||
const onClickMax = useCallback(() => {
|
const onClickMax = useCallback(() => {
|
||||||
setWithdrawAmount(freeCollateralBN.toString());
|
setWithdrawAmount(freeCollateralBN.toString());
|
||||||
}, [freeCollateral?.current, setWithdrawAmount]);
|
}, [freeCollateralBN, setWithdrawAmount]);
|
||||||
|
|
||||||
const onSelectChain = useCallback((chain: string) => {
|
const onSelectChain = useCallback((chain: string) => {
|
||||||
if (chain) {
|
if (chain) {
|
||||||
@@ -215,7 +260,7 @@ export const WithdrawForm = () => {
|
|||||||
value={freeCollateral?.current}
|
value={freeCollateral?.current}
|
||||||
newValue={freeCollateral?.postOrder}
|
newValue={freeCollateral?.postOrder}
|
||||||
sign={NumberSign.Negative}
|
sign={NumberSign.Negative}
|
||||||
hasInvalidNewValue={withdrawAmountBN.minus(freeCollateralBN).isNegative()}
|
hasInvalidNewValue={MustBigNumber(withdrawAmount).minus(freeCollateralBN).isNegative()}
|
||||||
withDiff={
|
withDiff={
|
||||||
Boolean(withdrawAmount) && !debouncedAmountBN.isNaN() && !debouncedAmountBN.isZero()
|
Boolean(withdrawAmount) && !debouncedAmountBN.isNaN() && !debouncedAmountBN.isZero()
|
||||||
}
|
}
|
||||||
@@ -224,18 +269,23 @@ export const WithdrawForm = () => {
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const { sanctionedAddresses } = useRestrictions();
|
||||||
|
|
||||||
const errorMessage = useMemo(() => {
|
const errorMessage = useMemo(() => {
|
||||||
if (error) {
|
if (error) {
|
||||||
return error?.message
|
return stringGetter({
|
||||||
? stringGetter({
|
key: STRING_KEYS.SOMETHING_WENT_WRONG_WITH_MESSAGE,
|
||||||
key: STRING_KEYS.SOMETHING_WENT_WRONG_WITH_MESSAGE,
|
params: { ERROR_MESSAGE: error },
|
||||||
params: { ERROR_MESSAGE: error.message },
|
});
|
||||||
})
|
|
||||||
: stringGetter({ key: STRING_KEYS.SOMETHING_WENT_WRONG });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!toAddress) return stringGetter({ key: STRING_KEYS.WITHDRAW_MUST_SPECIFY_ADDRESS });
|
if (!toAddress) return stringGetter({ key: STRING_KEYS.WITHDRAW_MUST_SPECIFY_ADDRESS });
|
||||||
|
|
||||||
|
if (sanctionedAddresses.has(toAddress))
|
||||||
|
return stringGetter({
|
||||||
|
key: STRING_KEYS.TRANSFER_INVALID_DYDX_ADDRESS,
|
||||||
|
});
|
||||||
|
|
||||||
if (debouncedAmountBN) {
|
if (debouncedAmountBN) {
|
||||||
if (!chainIdStr) {
|
if (!chainIdStr) {
|
||||||
return stringGetter({ key: STRING_KEYS.WITHDRAW_MUST_SPECIFY_CHAIN });
|
return stringGetter({ key: STRING_KEYS.WITHDRAW_MUST_SPECIFY_CHAIN });
|
||||||
@@ -249,7 +299,15 @@ export const WithdrawForm = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return undefined;
|
return undefined;
|
||||||
}, [error, freeCollateralBN, chainIdStr, debouncedAmountBN, toToken]);
|
}, [
|
||||||
|
error,
|
||||||
|
freeCollateralBN,
|
||||||
|
chainIdStr,
|
||||||
|
debouncedAmountBN,
|
||||||
|
toToken,
|
||||||
|
toAddress,
|
||||||
|
sanctionedAddresses,
|
||||||
|
]);
|
||||||
|
|
||||||
const isDisabled =
|
const isDisabled =
|
||||||
!!errorMessage ||
|
!!errorMessage ||
|
||||||
@@ -257,7 +315,8 @@ export const WithdrawForm = () => {
|
|||||||
!chainIdStr ||
|
!chainIdStr ||
|
||||||
!toAddress ||
|
!toAddress ||
|
||||||
debouncedAmountBN.isNaN() ||
|
debouncedAmountBN.isNaN() ||
|
||||||
debouncedAmountBN.isZero();
|
debouncedAmountBN.isZero() ||
|
||||||
|
isLoading;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Styled.Form onSubmit={onSubmit}>
|
<Styled.Form onSubmit={onSubmit}>
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ export const AdvancedTradeOptions = () => {
|
|||||||
const currentTradeFormConfig = useSelector(getInputTradeOptions, shallowEqual);
|
const currentTradeFormConfig = useSelector(getInputTradeOptions, shallowEqual);
|
||||||
const inputTradeData = useSelector(getInputTradeData, shallowEqual);
|
const inputTradeData = useSelector(getInputTradeData, shallowEqual);
|
||||||
|
|
||||||
const { execution, goodTil, postOnly, reduceOnly, timeInForce } = inputTradeData || {};
|
const { execution, goodTil, postOnly, reduceOnly, timeInForce, type } = inputTradeData || {};
|
||||||
|
|
||||||
const { executionOptions, needsGoodUntil, needsPostOnly, needsReduceOnly, timeInForceOptions } =
|
const { executionOptions, needsGoodUntil, needsPostOnly, needsReduceOnly, timeInForceOptions } =
|
||||||
currentTradeFormConfig || {};
|
currentTradeFormConfig || {};
|
||||||
@@ -37,6 +37,7 @@ export const AdvancedTradeOptions = () => {
|
|||||||
const { duration, unit } = goodTil || {};
|
const { duration, unit } = goodTil || {};
|
||||||
|
|
||||||
const needsExecution = executionOptions || needsPostOnly || needsReduceOnly;
|
const needsExecution = executionOptions || needsPostOnly || needsReduceOnly;
|
||||||
|
const hasTimeInForce = timeInForceOptions?.toArray()?.length;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Styled.Collapsible
|
<Styled.Collapsible
|
||||||
@@ -47,7 +48,7 @@ export const AdvancedTradeOptions = () => {
|
|||||||
>
|
>
|
||||||
<Styled.AdvancedInputsContainer>
|
<Styled.AdvancedInputsContainer>
|
||||||
<Styled.AdvancedInputsRow needsGoodUntil={needsGoodUntil}>
|
<Styled.AdvancedInputsRow needsGoodUntil={needsGoodUntil}>
|
||||||
{timeInForceOptions?.toArray() && (
|
{hasTimeInForce && (
|
||||||
<Styled.SelectMenu
|
<Styled.SelectMenu
|
||||||
value={timeInForce}
|
value={timeInForce}
|
||||||
onValueChange={(selectedTimeInForceOption: string) =>
|
onValueChange={(selectedTimeInForceOption: string) =>
|
||||||
@@ -72,7 +73,9 @@ export const AdvancedTradeOptions = () => {
|
|||||||
id="trade-good-til-time"
|
id="trade-good-til-time"
|
||||||
type={InputType.Number}
|
type={InputType.Number}
|
||||||
decimals={INTEGER_DECIMALS}
|
decimals={INTEGER_DECIMALS}
|
||||||
label={stringGetter({ key: STRING_KEYS.TIME })}
|
label={stringGetter({
|
||||||
|
key: hasTimeInForce ? STRING_KEYS.TIME : STRING_KEYS.GOOD_TIL_TIME,
|
||||||
|
})}
|
||||||
onChange={({ value }: NumberFormatValues) => {
|
onChange={({ value }: NumberFormatValues) => {
|
||||||
abacusStateManager.setTradeValue({
|
abacusStateManager.setTradeValue({
|
||||||
value: Number(value),
|
value: Number(value),
|
||||||
|
|||||||
@@ -3,8 +3,6 @@ import styled, { type AnyStyledComponent } from 'styled-components';
|
|||||||
import { type NumberFormatValues } from 'react-number-format';
|
import { type NumberFormatValues } from 'react-number-format';
|
||||||
import { shallowEqual, useSelector } from 'react-redux';
|
import { shallowEqual, useSelector } from 'react-redux';
|
||||||
import type { SyntheticInputEvent } from 'react-number-format/types/types';
|
import type { SyntheticInputEvent } from 'react-number-format/types/types';
|
||||||
import { debounce } from 'lodash';
|
|
||||||
import { StdFee } from '@cosmjs/stargate';
|
|
||||||
import { validation } from '@dydxprotocol/v4-client-js';
|
import { validation } from '@dydxprotocol/v4-client-js';
|
||||||
|
|
||||||
import { TransferInputField, TransferType } from '@/constants/abacus';
|
import { TransferInputField, TransferType } from '@/constants/abacus';
|
||||||
@@ -12,7 +10,7 @@ import { AlertType } from '@/constants/alerts';
|
|||||||
import { ButtonShape, ButtonSize } from '@/constants/buttons';
|
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, QUANTUM_MULTIPLIER } from '@/constants/numbers';
|
import { NumberSign } from '@/constants/numbers';
|
||||||
import {
|
import {
|
||||||
DYDX_CHAIN_ASSET_COIN_DENOM,
|
DYDX_CHAIN_ASSET_COIN_DENOM,
|
||||||
DYDX_CHAIN_ASSET_TAGS,
|
DYDX_CHAIN_ASSET_TAGS,
|
||||||
@@ -22,6 +20,8 @@ import {
|
|||||||
import {
|
import {
|
||||||
useAccountBalance,
|
useAccountBalance,
|
||||||
useAccounts,
|
useAccounts,
|
||||||
|
useDydxClient,
|
||||||
|
useRestrictions,
|
||||||
useSelectedNetwork,
|
useSelectedNetwork,
|
||||||
useStringGetter,
|
useStringGetter,
|
||||||
useSubaccount,
|
useSubaccount,
|
||||||
@@ -77,7 +77,7 @@ export const TransferForm = ({
|
|||||||
const [asset, setAsset] = useState<DydxChainAsset>(selectedAsset);
|
const [asset, setAsset] = useState<DydxChainAsset>(selectedAsset);
|
||||||
|
|
||||||
// Form states
|
// Form states
|
||||||
const [error, setError] = useState<Error | undefined>();
|
const [error, setError] = useState<string>();
|
||||||
const [isLoading, setIsLoading] = useState(false);
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
|
|
||||||
const balance = asset === DydxChainAsset.USDC ? freeCollateral?.current : nativeTokenBalance;
|
const balance = asset === DydxChainAsset.USDC ? freeCollateral?.current : nativeTokenBalance;
|
||||||
@@ -96,16 +96,6 @@ export const TransferForm = ({
|
|||||||
const balanceBN = MustBigNumber(balance);
|
const balanceBN = MustBigNumber(balance);
|
||||||
const newBalanceBN = MustBigNumber(newBalance);
|
const newBalanceBN = MustBigNumber(newBalance);
|
||||||
|
|
||||||
const isAddressValid = useMemo(
|
|
||||||
() =>
|
|
||||||
recipientAddress &&
|
|
||||||
dydxAddress !== recipientAddress &&
|
|
||||||
validation.isValidAddress(recipientAddress),
|
|
||||||
[recipientAddress]
|
|
||||||
);
|
|
||||||
|
|
||||||
const isAmountValid = balance && amount && amountBN.gt(0) && newBalanceBN.gte(0);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
abacusStateManager.setTransferValue({
|
abacusStateManager.setTransferValue({
|
||||||
value: TransferType.transferOut.rawValue,
|
value: TransferType.transferOut.rawValue,
|
||||||
@@ -125,6 +115,21 @@ export const TransferForm = ({
|
|||||||
});
|
});
|
||||||
}, [asset]);
|
}, [asset]);
|
||||||
|
|
||||||
|
const { sanctionedAddresses } = useRestrictions();
|
||||||
|
|
||||||
|
const isAddressValid = useMemo(
|
||||||
|
() =>
|
||||||
|
recipientAddress &&
|
||||||
|
dydxAddress !== recipientAddress &&
|
||||||
|
validation.isValidAddress(recipientAddress) &&
|
||||||
|
!sanctionedAddresses.has(recipientAddress),
|
||||||
|
[recipientAddress, sanctionedAddresses, dydxAddress]
|
||||||
|
);
|
||||||
|
|
||||||
|
const isAmountValid = balance && amount && amountBN.gt(0) && newBalanceBN.gte(0);
|
||||||
|
|
||||||
|
const { screenAddresses } = useDydxClient();
|
||||||
|
|
||||||
const onTransfer = async () => {
|
const onTransfer = async () => {
|
||||||
if (!isAmountValid || !isAddressValid || !fee) return;
|
if (!isAmountValid || !isAddressValid || !fee) return;
|
||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
@@ -136,20 +141,51 @@ export const TransferForm = ({
|
|||||||
asset === DydxChainAsset.DYDX ? amountBN.minus(fee) : amountBN
|
asset === DydxChainAsset.DYDX ? amountBN.minus(fee) : amountBN
|
||||||
).toNumber();
|
).toNumber();
|
||||||
|
|
||||||
const txResponse = await transfer(
|
const screenResults = await screenAddresses({
|
||||||
amountToTransfer,
|
addresses: [recipientAddress!, dydxAddress!],
|
||||||
recipientAddress as string,
|
});
|
||||||
DYDX_CHAIN_ASSET_COIN_DENOM[asset]
|
|
||||||
);
|
|
||||||
|
|
||||||
if (txResponse?.code === 0) {
|
if (screenResults?.[dydxAddress!]) {
|
||||||
console.log('TransferForm > txReceipt > ', txResponse?.hash);
|
setError(
|
||||||
onDone?.();
|
stringGetter({
|
||||||
|
key: STRING_KEYS.WALLET_RESTRICTED_WITHDRAWAL_TRANSFER_ORIGINATION_ERROR_MESSAGE,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
} else if (screenResults?.[recipientAddress!]) {
|
||||||
|
setError(
|
||||||
|
stringGetter({
|
||||||
|
key: STRING_KEYS.WALLET_RESTRICTED_WITHDRAWAL_TRANSFER_DESTINATION_ERROR_MESSAGE,
|
||||||
|
})
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
throw new Error(txResponse?.rawLog ?? 'Transaction did not commit.');
|
const txResponse = await transfer(
|
||||||
|
amountToTransfer,
|
||||||
|
recipientAddress as string,
|
||||||
|
DYDX_CHAIN_ASSET_COIN_DENOM[asset]
|
||||||
|
);
|
||||||
|
|
||||||
|
if (txResponse?.code === 0) {
|
||||||
|
console.log('TransferForm > txReceipt > ', txResponse?.hash);
|
||||||
|
onDone?.();
|
||||||
|
} else {
|
||||||
|
throw new Error(txResponse?.rawLog ?? 'Transaction did not commit.');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
setError(error);
|
if (error?.code === 429) {
|
||||||
|
setError(stringGetter({ key: STRING_KEYS.RATE_LIMIT_REACHED_ERROR_MESSAGE }));
|
||||||
|
} else {
|
||||||
|
setError(
|
||||||
|
error.message
|
||||||
|
? stringGetter({
|
||||||
|
key: STRING_KEYS.SOMETHING_WENT_WRONG_WITH_MESSAGE,
|
||||||
|
params: {
|
||||||
|
ERROR_MESSAGE: error.message || stringGetter({ key: STRING_KEYS.UNKNOWN_ERROR }),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
: stringGetter({ key: STRING_KEYS.SOMETHING_WENT_WRONG })
|
||||||
|
);
|
||||||
|
}
|
||||||
log('TransferForm/onTransfer', error);
|
log('TransferForm/onTransfer', error);
|
||||||
} finally {
|
} finally {
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
@@ -231,13 +267,6 @@ export const TransferForm = ({
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const addressValidationErrorMessage = stringGetter({
|
|
||||||
key:
|
|
||||||
dydxAddress === recipientAddress
|
|
||||||
? STRING_KEYS.TRANSFER_TO_YOURSELF
|
|
||||||
: STRING_KEYS.TRANSFER_INVALID_DYDX_ADDRESS,
|
|
||||||
});
|
|
||||||
|
|
||||||
const renderFormInputButton = ({
|
const renderFormInputButton = ({
|
||||||
label,
|
label,
|
||||||
isInputEmpty,
|
isInputEmpty,
|
||||||
@@ -302,7 +331,12 @@ export const TransferForm = ({
|
|||||||
|
|
||||||
{recipientAddress && !isAddressValid && (
|
{recipientAddress && !isAddressValid && (
|
||||||
<Styled.AddressValidationAlertMessage type={AlertType.Error}>
|
<Styled.AddressValidationAlertMessage type={AlertType.Error}>
|
||||||
{addressValidationErrorMessage}
|
{stringGetter({
|
||||||
|
key:
|
||||||
|
dydxAddress === recipientAddress
|
||||||
|
? STRING_KEYS.TRANSFER_TO_YOURSELF
|
||||||
|
: STRING_KEYS.TRANSFER_INVALID_DYDX_ADDRESS,
|
||||||
|
})}
|
||||||
</Styled.AddressValidationAlertMessage>
|
</Styled.AddressValidationAlertMessage>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
@@ -342,13 +376,13 @@ export const TransferForm = ({
|
|||||||
</AlertMessage>
|
</AlertMessage>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{error && <AlertMessage type={AlertType.Error}>{error.message}</AlertMessage>}
|
{error && <AlertMessage type={AlertType.Error}>{error}</AlertMessage>}
|
||||||
|
|
||||||
<Styled.Footer>
|
<Styled.Footer>
|
||||||
<TransferButtonAndReceipt
|
<TransferButtonAndReceipt
|
||||||
selectedAsset={asset}
|
selectedAsset={asset}
|
||||||
fees={fee || undefined}
|
fees={fee || undefined}
|
||||||
isDisabled={!isAmountValid || !isAddressValid || !fee}
|
isDisabled={!isAmountValid || !isAddressValid || !fee || isLoading}
|
||||||
isLoading={isLoading || Boolean(isAmountValid && isAddressValid && !fee)}
|
isLoading={isLoading || Boolean(isAmountValid && isAddressValid && !fee)}
|
||||||
/>
|
/>
|
||||||
</Styled.Footer>
|
</Styled.Footer>
|
||||||
|
|||||||
@@ -178,10 +178,11 @@ export const NotificationsMenu = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
const $UnreadIndicator = styled.div`
|
const $UnreadIndicator = styled.div`
|
||||||
width: 0.5em;
|
width: 0.5rem;
|
||||||
height: 0.5em;
|
height: 0.5rem;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
background-color: var(--color-accent);
|
background-color: var(--color-accent);
|
||||||
|
border: 1px solid var(--color-layer-2);
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const $TriggerContainer = styled.div`
|
const $TriggerContainer = styled.div`
|
||||||
@@ -192,8 +193,8 @@ const $TriggerUnreadIndicator = styled($UnreadIndicator)`
|
|||||||
place-self: center;
|
place-self: center;
|
||||||
|
|
||||||
position: relative;
|
position: relative;
|
||||||
right: -0.425em;
|
right: -0.2rem;
|
||||||
top: -0.425em;
|
top: -0.325rem;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const $Output = styled(Output)`
|
const $Output = styled(Output)`
|
||||||
|
|||||||