Compare commits

..
Author SHA1 Message Date
Aleka Cheung e70d98c01e import order nit 2024-02-15 13:14:18 -05:00
Aleka Cheung 191e492647 util function for getting mintscan link 2024-02-15 10:38:39 -05:00
Aleka Cheung 3f601d28ef use selector for chain id instead 2024-02-15 10:13:48 -05:00
Aleka Cheung de5dddad10 bump abacus to 1.4.5 2024-02-14 13:58:58 -05:00
Aleka Cheung bf645125a9 use new config path 2024-02-14 13:55:06 -05:00
Aleka Cheung 99395b34c5 bump abacus + use new env config format 2024-02-14 13:38:58 -05:00
60 changed files with 177 additions and 600 deletions
-40
View File
@@ -1,40 +0,0 @@
name: Workflow for Release
on:
push:
tags:
- 'release/v*'
- 'hotfix/v*'
jobs:
sync-release-branch:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v2
- name: Setup Git
run: |
git config user.name "github-actions"
git config user.email "actions@github.com"
- name: Fetch all history
run: git fetch --unshallow || git fetch --all
- name: Determine Tag Type
id: tagtype
run: |
if [[ ${{ github.ref }} == refs/tags/release/v* ]]; then
echo "::set-output name=type::release"
elif [[ ${{ github.ref }} == refs/tags/hotfix/v* ]]; then
echo "::set-output name=type::hotfix"
fi
- name: Check out the release branch
run: |
git checkout release || git checkout -b release
- name: Sync release branch to tag
run: |
git reset --hard ${{ github.ref }}
git push -f origin release
-1
View File
@@ -1,2 +1 @@
node_modules/ node_modules/
public/
+2 -2
View File
@@ -40,9 +40,9 @@
"@cosmjs/proto-signing": "^0.32.1", "@cosmjs/proto-signing": "^0.32.1",
"@cosmjs/stargate": "^0.32.1", "@cosmjs/stargate": "^0.32.1",
"@cosmjs/tendermint-rpc": "^0.32.1", "@cosmjs/tendermint-rpc": "^0.32.1",
"@dydxprotocol/v4-abacus": "^1.4.9", "@dydxprotocol/v4-abacus": "^1.4.5",
"@dydxprotocol/v4-client-js": "^1.0.20", "@dydxprotocol/v4-client-js": "^1.0.20",
"@dydxprotocol/v4-localization": "^1.1.34", "@dydxprotocol/v4-localization": "^1.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-accordion": "^1.1.2", "@radix-ui/react-accordion": "^1.1.2",
+12 -12
View File
@@ -1,9 +1,5 @@
lockfileVersion: '6.0' lockfileVersion: '6.0'
settings:
autoInstallPeers: true
excludeLinksFromLockfile: false
overrides: overrides:
follow-redirects: 1.15.3 follow-redirects: 1.15.3
@@ -30,14 +26,14 @@ dependencies:
specifier: ^0.32.1 specifier: ^0.32.1
version: 0.32.2 version: 0.32.2
'@dydxprotocol/v4-abacus': '@dydxprotocol/v4-abacus':
specifier: ^1.4.9 specifier: ^1.4.5
version: 1.4.9 version: 1.4.5
'@dydxprotocol/v4-client-js': '@dydxprotocol/v4-client-js':
specifier: ^1.0.20 specifier: ^1.0.20
version: 1.0.20 version: 1.0.20
'@dydxprotocol/v4-localization': '@dydxprotocol/v4-localization':
specifier: ^1.1.34 specifier: ^1.1.30
version: 1.1.34 version: 1.1.30
'@ethersproject/providers': '@ethersproject/providers':
specifier: ^5.7.2 specifier: ^5.7.2
version: 5.7.2 version: 5.7.2
@@ -1290,8 +1286,8 @@ packages:
resolution: {integrity: sha512-Gg5t+eR7vPJMAmhkFt6CZrzPd0EKpAslWwk5rFVYZpJsM8JG5KT9XQ99hgNM3Ov6ScNoIWbXkpX27F6A9cXR4Q==} resolution: {integrity: sha512-Gg5t+eR7vPJMAmhkFt6CZrzPd0EKpAslWwk5rFVYZpJsM8JG5KT9XQ99hgNM3Ov6ScNoIWbXkpX27F6A9cXR4Q==}
dev: false dev: false
/@dydxprotocol/v4-abacus@1.4.9: /@dydxprotocol/v4-abacus@1.4.5:
resolution: {integrity: sha512-OnrD5Db7AGSxyQE+gWRmkBuXbkZMfSEDB+v2s+ft0zgd4D5j/WTZkk1RG0fn8ISV4AffoN5T24jBWxLfqVlmZw==} resolution: {integrity: sha512-LhJmpIaUkHCsSiHx+jdk+59euvGp2E+gGFelpfmOYpH1+enZgEXDQvWsgHSFEQxYP3mRiGG4uo+ZYNGdvffg7g==}
dev: false dev: false
/@dydxprotocol/v4-client-js@1.0.20: /@dydxprotocol/v4-client-js@1.0.20:
@@ -1323,8 +1319,8 @@ packages:
- utf-8-validate - utf-8-validate
dev: false dev: false
/@dydxprotocol/v4-localization@1.1.34: /@dydxprotocol/v4-localization@1.1.30:
resolution: {integrity: sha512-I7zivjv8gS+6b9n7/wh7PY9QEUDIIyLx9ugZ5K6ybar0xT/06yupOVdVE6iLivQ/IAsVi/RFHkD8bQd0DWCetg==} resolution: {integrity: sha512-TZfWWRSOxcjLHs972wlJVVHkE7+DVqAUnGZSs24HYHsPtUkPhZiNXMOA2Vk9YddQxumhM79xIRH0cmJSe5DDUg==}
dev: false dev: false
/@dydxprotocol/v4-proto@4.0.0-dev.0: /@dydxprotocol/v4-proto@4.0.0-dev.0:
@@ -16053,3 +16049,7 @@ packages:
/zwitch@2.0.4: /zwitch@2.0.4:
resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==}
dev: true dev: true
settings:
autoInstallPeers: true
excludeLinksFromLockfile: false
-10
View File
@@ -8,15 +8,5 @@
"chainId": "5", "chainId": "5",
"tokenAddress": "0x07865c6E87B9F70255377e024ace6630C1Eaa37F", "tokenAddress": "0x07865c6E87B9F70255377e024ace6630C1Eaa37F",
"name": "Ethereum Goerli" "name": "Ethereum Goerli"
},
{
"chainId": "43114",
"tokenAddress": "0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E",
"name": "Avalanche"
},
{
"chainId": "10",
"tokenAddress": "0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85",
"name": "optimism"
} }
] ]
+1 -162
View File
@@ -20,13 +20,6 @@
"whitepaperLink": "https://why.cardano.org/en/introduction/motivation/", "whitepaperLink": "https://why.cardano.org/en/introduction/motivation/",
"coinMarketCapsLink": "https://coinmarketcap.com/currencies/cardano/" "coinMarketCapsLink": "https://coinmarketcap.com/currencies/cardano/"
}, },
"AGIX-USD": {
"name": "SingularityNET",
"tags": ["AI"],
"websiteLink": "https://public.singularitynet.io/whitepaper.pdf",
"whitepaperLink": "https://public.singularitynet.io/whitepaper.pdf",
"coinMarketCapsLink": "https://coinmarketcap.com/currencies/singularitynet/"
},
"ALGO-USD": { "ALGO-USD": {
"name": "Algorand", "name": "Algorand",
"tags": ["Layer 1"], "tags": ["Layer 1"],
@@ -85,7 +78,7 @@
}, },
"BLUR-USD": { "BLUR-USD": {
"name": "Blur", "name": "Blur",
"tags": ["NFT"], "tags": [],
"websiteLink": "https://blur.io/", "websiteLink": "https://blur.io/",
"whitepaperLink": "https://docs.blur.foundation/", "whitepaperLink": "https://docs.blur.foundation/",
"coinMarketCapsLink": "https://coinmarketcap.com/currencies/blur-token/" "coinMarketCapsLink": "https://coinmarketcap.com/currencies/blur-token/"
@@ -98,13 +91,6 @@
"coinMarketCapsLink": "https://coinmarketcap.com/currencies/bnb/" "coinMarketCapsLink": "https://coinmarketcap.com/currencies/bnb/"
}, },
"CHZ-USD": {
"name": "Chiliz",
"tags": ["Layer 1"],
"websiteLink": "https://www.chiliz.com/",
"whitepaperLink": "https://www.chiliz.com/docs/litepaper-v1.1-20230703.pdf",
"coinMarketCapsLink": "https://coinmarketcap.com/currencies/chiliz/"
},
"CELO-USD": { "CELO-USD": {
"name": "Celo", "name": "Celo",
"tags": [], "tags": [],
@@ -161,13 +147,6 @@
"whitepaperLink": "https://cdn.enjin.io/downloads/whitepapers/enjin-coin/en.pdf/", "whitepaperLink": "https://cdn.enjin.io/downloads/whitepapers/enjin-coin/en.pdf/",
"coinMarketCapsLink": "https://coinmarketcap.com/currencies/enjin-coin/" "coinMarketCapsLink": "https://coinmarketcap.com/currencies/enjin-coin/"
}, },
"ENS-USD": {
"name": "Ethereum Name Service",
"tags": [],
"websiteLink": "https://coinmarketcap.com/currencies/ethereum-name-service/",
"whitepaperLink": "https://docs.ens.domains/",
"coinMarketCapsLink": "https://coinmarketcap.com/currencies/ethereum-name-service/"
},
"EOS-USD": { "EOS-USD": {
"name": "EOS", "name": "EOS",
"tags": ["Layer 1"], "tags": ["Layer 1"],
@@ -191,13 +170,6 @@
"displayStepSize": "0.001", "displayStepSize": "0.001",
"displayTickSize": "0.1" "displayTickSize": "0.1"
}, },
"FET-USD": {
"name": "Fetch.ai",
"tags": ["AI"],
"websiteLink": "https://fetch.ai/",
"whitepaperLink": "https://www.dropbox.com/s/gxptsecwdl3jjtn/David%20Minarsch%20-%202021-04-26%2010.34.17%20-%20paper_21_finalversion.pdf?e=1&dl=0",
"coinMarketCapsLink": "https://coinmarketcap.com/currencies/fetch/"
},
"FIL-USD": { "FIL-USD": {
"name": "Filecoin", "name": "Filecoin",
"tags": ["Layer 1"], "tags": ["Layer 1"],
@@ -205,34 +177,6 @@
"whitepaperLink": "https://filecoin.io/filecoin.pdf", "whitepaperLink": "https://filecoin.io/filecoin.pdf",
"coinMarketCapsLink": "https://coinmarketcap.com/currencies/filecoin/" "coinMarketCapsLink": "https://coinmarketcap.com/currencies/filecoin/"
}, },
"FTM-USD": {
"name": "Fantom",
"tags": [],
"websiteLink": "https://fantom.foundation/",
"whitepaperLink": "https://fantom.foundation/_next/static/media/wp_fantom_v1.6.39329cdc5d0ee59684cbc6f228516383.pdf",
"coinMarketCapsLink": "https://coinmarketcap.com/currencies/fantom/"
},
"GALA-USD": {
"name": "Gala",
"tags": ["Gaming", "Layer 1"],
"websiteLink": "https://gala.com/",
"whitepaperLink": "https://galahackathon.com/v1.0.0/pdf/sdk-documentation.pdf",
"coinMarketCapsLink": "https://coinmarketcap.com/currencies/gala/"
},
"GMT-USD": {
"name": "GMT",
"tags": ["Gaming"],
"websiteLink": "https://stepn.com/",
"whitepaperLink/": "https://whitepaper.stepn.com/",
"coinMarketCapsLink": "https://coinmarketcap.com/currencies/green-metaverse-token/"
},
"GRT-USD": {
"name": "The Graph",
"tags": [],
"websiteLink": "https://thegraph.com/",
"whitepaperLink/": "https://github.com/graphprotocol/research/blob/master/papers/whitepaper/the-graph-whitepaper.pdf",
"coinMarketCapsLink": "https://coinmarketcap.com/currencies/the-graph/"
},
"HNT-USD": { "HNT-USD": {
"name": "Helium", "name": "Helium",
"tags": ["Layer 1"], "tags": ["Layer 1"],
@@ -240,13 +184,6 @@
"whitepaperLink": "http://whitepaper.helium.com", "whitepaperLink": "http://whitepaper.helium.com",
"coinMarketCapsLink": "https://coinmarketcap.com/currencies/helium/" "coinMarketCapsLink": "https://coinmarketcap.com/currencies/helium/"
}, },
"HBAR-USD": {
"name": "Hedera",
"tags": [],
"websiteLink": "https://hedera.com/",
"whitepaperLink/": "https://files.hedera.com/hh_whitepaper_v2.2-20230918.pdf",
"coinMarketCapsLink": "https://coinmarketcap.com/currencies/hedera/"
},
"ICP-USD": { "ICP-USD": {
"name": "Internet Computer", "name": "Internet Computer",
"tags": ["Layer 1"], "tags": ["Layer 1"],
@@ -254,27 +191,6 @@
"whitepaperLink": "https://dfinity.org/whitepaper.pdf", "whitepaperLink": "https://dfinity.org/whitepaper.pdf",
"coinMarketCapsLink": "https://coinmarketcap.com/currencies/internet-computer/" "coinMarketCapsLink": "https://coinmarketcap.com/currencies/internet-computer/"
}, },
"IMX-USD": {
"name": "Immutable X",
"tags": ["Gaming", "Layer 2", "NFT"],
"websiteLink": "https://www.immutable.com/",
"whitepaperLink": "https://assets.website-files.com/646557ee455c3e16e4a9bcb3/6499367de527dd82ab7475a3_Immutable%20Whitepaper%20Update%202023%20(3).pdf",
"coinMarketCapsLink": "https://coinmarketcap.com/currencies/immutable-x/"
},
"INJ-USD": {
"name": "Injective",
"tags": ["Layer 1", "Defi"],
"websiteLink": "https://injective.com/",
"whitepaperLink": "https://docs.injective.network/intro/01_overview.html",
"coinMarketCapsLink": "https://coinmarketcap.com/currencies/injective/"
},
"JTO-USD": {
"name": "Jito",
"tags": ["Defi"],
"websiteLink": "https://www.jito.network/",
"whitepaperLink": "https://github.com/jito-foundation",
"coinMarketCapsLink": "https://coinmarketcap.com/currencies/jito/"
},
"JUP-USD": { "JUP-USD": {
"name": "Jupiter", "name": "Jupiter",
"tags": ["Defi"], "tags": ["Defi"],
@@ -282,13 +198,6 @@
"whitepaperLink": "https://station.jup.ag/blog/green-paper", "whitepaperLink": "https://station.jup.ag/blog/green-paper",
"coinMarketCapsLink": "https://coinmarketcap.com/currencies/jupiter-ag/" "coinMarketCapsLink": "https://coinmarketcap.com/currencies/jupiter-ag/"
}, },
"KAVA-USD": {
"name": "Kava",
"tags": ["Layer 1"],
"websiteLink": "https://www.kava.io/",
"whitepaperLink": "https://docsend.com/view/gwbwpc3",
"coinMarketCapsLink": "https://coinmarketcap.com/currencies/kava/"
},
"LDO-USD": { "LDO-USD": {
"name": "Lido DAO", "name": "Lido DAO",
"tags": ["Defi"], "tags": ["Defi"],
@@ -310,20 +219,6 @@
"whitepaperLink": "https://litecoin.info/index.php/Main_Page", "whitepaperLink": "https://litecoin.info/index.php/Main_Page",
"coinMarketCapsLink": "https://coinmarketcap.com/currencies/litecoin/" "coinMarketCapsLink": "https://coinmarketcap.com/currencies/litecoin/"
}, },
"MANA-USD": {
"name": "Decentraland",
"tags": ["AR/VR"],
"websiteLink": "https://decentraland.org/",
"whitepaperLink": "https://decentraland.org/whitepaper.pdf",
"coinMarketCapsLink": "https://coinmarketcap.com/currencies/decentraland/"
},
"MASK-USD": {
"name": "Mask Network",
"tags": [],
"websiteLink": "https://mask.io/",
"whitepaperLink": "https://masknetwork.medium.com/introducing-mask-network-maskbook-the-future-of-the-internet-5a973d874edd",
"coinMarketCapsLink": "https://coinmarketcap.com/currencies/mask-network/"
},
"MATIC-USD": { "MATIC-USD": {
"name": "Polygon", "name": "Polygon",
"tags": ["Layer 2"], "tags": ["Layer 2"],
@@ -331,13 +226,6 @@
"whitepaperLink": "https://polygon.technology/lightpaper-polygon.pdf", "whitepaperLink": "https://polygon.technology/lightpaper-polygon.pdf",
"coinMarketCapsLink": "https://coinmarketcap.com/currencies/polygon/" "coinMarketCapsLink": "https://coinmarketcap.com/currencies/polygon/"
}, },
"MINA-USD": {
"name": "Mina",
"tags": ["Layer 1"],
"websiteLink": "https://minaprotocol.com/",
"whitepaperLink": "https://docs.minaprotocol.com/assets/economicsWhitepaper.pdf",
"coinMarketCapsLink": "https://coinmarketcap.com/currencies/mina/"
},
"MKR-USD": { "MKR-USD": {
"name": "Maker", "name": "Maker",
"tags": ["Governance"], "tags": ["Governance"],
@@ -352,13 +240,6 @@
"whitepaperLink": "https://near.org/papers/the-official-near-white-paper/", "whitepaperLink": "https://near.org/papers/the-official-near-white-paper/",
"coinMarketCapsLink": "https://coinmarketcap.com/currencies/near-protocol/" "coinMarketCapsLink": "https://coinmarketcap.com/currencies/near-protocol/"
}, },
"ORDI-USD": {
"name": "Ordinals",
"tags": ["NFT"],
"websiteLink": "https://ordinals.com/",
"whitepaperLink": "https://rodarmor.com/blog/",
"coinMarketCapsLink": "https://coinmarketcap.com/currencies/ordi/"
},
"OP-USD": { "OP-USD": {
"name": "Optimism", "name": "Optimism",
"tags": [], "tags": [],
@@ -372,20 +253,6 @@
"websiteLink": "https://www.pepe.vip/", "websiteLink": "https://www.pepe.vip/",
"coinMarketCapsLink": "https://coinmarketcap.com/currencies/pepe/" "coinMarketCapsLink": "https://coinmarketcap.com/currencies/pepe/"
}, },
"PYTH-USD": {
"name": "Pyth Network",
"tags": [],
"websiteLink": "https://pyth.network/",
"whitepaperLink": "https://pyth.network/whitepaper_v2.pdf",
"coinMarketCapsLink": "https://coinmarketcap.com/currencies/pyth-network/"
},
"RNDR-USD": {
"name": "Render Token",
"tags": ["AI"],
"websiteLink": "https://rendernetwork.com/",
"whitepaperLink": "https://renderfoundation.com/whitepaper",
"coinMarketCapsLink": "https://coinmarketcap.com/currencies/render/"
},
"RUNE-USD": { "RUNE-USD": {
"name": "THORChain", "name": "THORChain",
"tags": ["Layer 1"], "tags": ["Layer 1"],
@@ -393,13 +260,6 @@
"whitepaperLink": "https://whitepaper.io/document/709/thorchain-whitepaper", "whitepaperLink": "https://whitepaper.io/document/709/thorchain-whitepaper",
"coinMarketCapsLink": "https://coinmarketcap.com/currencies/thorchain/" "coinMarketCapsLink": "https://coinmarketcap.com/currencies/thorchain/"
}, },
"SAND-USD": {
"name": "The Sandbox",
"tags": ["Gaming"],
"websiteLink": "https://www.sandbox.game/en/",
"whitepaperLink": "https://installers.sandbox.game/The_Sandbox_Whitepaper_2020.pdf",
"coinMarketCapsLink": "https://coinmarketcap.com/currencies/the-sandbox/"
},
"SEI-USD": { "SEI-USD": {
"name": "Sei", "name": "Sei",
"tags": ["Layer 1", "Defi"], "tags": ["Layer 1", "Defi"],
@@ -428,20 +288,6 @@
"whitepaperLink": "https://solana.com/solana-whitepaper.pdf", "whitepaperLink": "https://solana.com/solana-whitepaper.pdf",
"coinMarketCapsLink": "https://coinmarketcap.com/currencies/solana/" "coinMarketCapsLink": "https://coinmarketcap.com/currencies/solana/"
}, },
"STRK-USD": {
"name": "Starknet",
"tags": ["Layer 2"],
"websiteLink": "https://www.starknet.io/en",
"whitepaperLink": "https://docs.starknet.io/documentation/",
"coinMarketCapsLink": "https://coinmarketcap.com/currencies/starknet-token/"
},
"STX-USD": {
"name": "Stacks",
"tags": ["Layer 2"],
"websiteLink": "https://www.stacks.co/",
"whitepaperLink": "https://gaia.blockstack.org/hub/1AxyPunHHAHiEffXWESKfbvmBpGQv138Fp/stacks.pdf",
"coinMarketCapsLink": "https://coinmarketcap.com/currencies/stacks/"
},
"SUI-USD": { "SUI-USD": {
"name": "Sui", "name": "Sui",
"tags": ["Layer 1"], "tags": ["Layer 1"],
@@ -491,13 +337,6 @@
"whitepaperLink": "https://whitepaper.worldcoin.org/", "whitepaperLink": "https://whitepaper.worldcoin.org/",
"coinMarketCapsLink": "https://coinmarketcap.com/currencies/worldcoin-org/" "coinMarketCapsLink": "https://coinmarketcap.com/currencies/worldcoin-org/"
}, },
"WOO-USD": {
"name": "WOO Network",
"tags": ["Defi"],
"websiteLink": "https://woo.org/",
"whitepaperLink": "https://woo.org/Litepaper.pdf",
"coinMarketCapsLink": "https://coinmarketcap.com/currencies/wootrade/"
},
"XLM-USD": { "XLM-USD": {
"name": "Stellar", "name": "Stellar",
"tags": ["Layer 1"], "tags": ["Layer 1"],
@@ -513,14 +513,6 @@
{ "exchangeName": "Okx", "ticker": "SOL-USDT", "adjustByMarket": "USDT-USD" }, { "exchangeName": "Okx", "ticker": "SOL-USDT", "adjustByMarket": "USDT-USD" },
{ "exchangeName": "Mexc", "ticker": "SOL_USDT", "adjustByMarket": "USDT-USD" } { "exchangeName": "Mexc", "ticker": "SOL_USDT", "adjustByMarket": "USDT-USD" }
], ],
"STRK": [
{ "exchangeName": "Binance", "ticker": "STRKUSDT", "adjustByMarket": "USDT-USD" },
{ "exchangeName": "Bybit", "ticker": "STRKUSDT", "adjustByMarket": "USDT-USD" },
{ "exchangeName": "Kraken", "ticker": "STRKUSD" },
{ "exchangeName": "Kucoin", "ticker": "STRK-USDT", "adjustByMarket": "USDT-USD" },
{ "exchangeName": "Okx", "ticker": "STRK-USDT", "adjustByMarket": "USDT-USD" },
{ "exchangeName": "Gate", "ticker": "STRK_USDT", "adjustByMarket": "USDT-USD" }
],
"STX": [ "STX": [
{ "exchangeName": "Binance", "ticker": "STXUSDT", "adjustByMarket": "USDT-USD" }, { "exchangeName": "Binance", "ticker": "STXUSDT", "adjustByMarket": "USDT-USD" },
{ "exchangeName": "Bybit", "ticker": "STXUSDT", "adjustByMarket": "USDT-USD" }, { "exchangeName": "Bybit", "ticker": "STXUSDT", "adjustByMarket": "USDT-USD" },
+12 -29
View File
@@ -274,7 +274,7 @@
{ {
"baseAsset": "CRV", "baseAsset": "CRV",
"referencePrice": 0.48346754113361784, "referencePrice": 0.48346754113361784,
"numOracles": 6, "numOracles": 5,
"liquidityTier": 2, "liquidityTier": 2,
"assetName": "Curve DAO Token", "assetName": "Curve DAO Token",
"p": -1.0, "p": -1.0,
@@ -325,7 +325,7 @@
{ {
"baseAsset": "DYM", "baseAsset": "DYM",
"referencePrice": 5.544949130771594, "referencePrice": 5.544949130771594,
"numOracles": 6, "numOracles": 5,
"liquidityTier": 2, "liquidityTier": 2,
"assetName": "Dymension", "assetName": "Dymension",
"p": 0.0, "p": 0.0,
@@ -412,7 +412,7 @@
"referencePrice": 0.5560893147613742, "referencePrice": 0.5560893147613742,
"numOracles": 6, "numOracles": 6,
"liquidityTier": 2, "liquidityTier": 2,
"assetName": "Fetch.ai", "assetName": "Fetch AI",
"p": -1.0, "p": -1.0,
"atomicResolution": -5.0, "atomicResolution": -5.0,
"minExchanges": 3, "minExchanges": 3,
@@ -480,7 +480,7 @@
"referencePrice": 0.20404992804891367, "referencePrice": 0.20404992804891367,
"numOracles": 6, "numOracles": 6,
"liquidityTier": 2, "liquidityTier": 2,
"assetName": "GMT", "assetName": "STEPN",
"p": -1.0, "p": -1.0,
"atomicResolution": -5.0, "atomicResolution": -5.0,
"minExchanges": 3, "minExchanges": 3,
@@ -514,7 +514,7 @@
"referencePrice": 0.07686278766140874, "referencePrice": 0.07686278766140874,
"numOracles": 6, "numOracles": 6,
"liquidityTier": 2, "liquidityTier": 2,
"assetName": "Hedera", "assetName": "Hedera Hashgraph",
"p": -2.0, "p": -2.0,
"atomicResolution": -4.0, "atomicResolution": -4.0,
"minExchanges": 3, "minExchanges": 3,
@@ -565,7 +565,7 @@
"referencePrice": 33.427379051845875, "referencePrice": 33.427379051845875,
"numOracles": 7, "numOracles": 7,
"liquidityTier": 2, "liquidityTier": 2,
"assetName": "Injective", "assetName": "Injective Protocol",
"p": 1.0, "p": 1.0,
"atomicResolution": -7.0, "atomicResolution": -7.0,
"minExchanges": 3, "minExchanges": 3,
@@ -597,7 +597,7 @@
{ {
"baseAsset": "JUP", "baseAsset": "JUP",
"referencePrice": 0.4339790660244292, "referencePrice": 0.4339790660244292,
"numOracles": 6, "numOracles": 5,
"liquidityTier": 2, "liquidityTier": 2,
"assetName": "Jupiter", "assetName": "Jupiter",
"p": -1.0, "p": -1.0,
@@ -750,7 +750,7 @@
{ {
"baseAsset": "MKR", "baseAsset": "MKR",
"referencePrice": 1943.1865605831852, "referencePrice": 1943.1865605831852,
"numOracles": 6, "numOracles": 5,
"liquidityTier": 2, "liquidityTier": 2,
"assetName": "Maker", "assetName": "Maker",
"p": 3.0, "p": 3.0,
@@ -869,7 +869,7 @@
{ {
"baseAsset": "RUNE", "baseAsset": "RUNE",
"referencePrice": 3.7264809096406806, "referencePrice": 3.7264809096406806,
"numOracles": 6, "numOracles": 5,
"liquidityTier": 2, "liquidityTier": 2,
"assetName": "Thorchain", "assetName": "Thorchain",
"p": 0.0, "p": 0.0,
@@ -888,7 +888,7 @@
"referencePrice": 0.37297439115035663, "referencePrice": 0.37297439115035663,
"numOracles": 6, "numOracles": 6,
"liquidityTier": 2, "liquidityTier": 2,
"assetName": "The Sandbox", "assetName": "SAND",
"p": -1.0, "p": -1.0,
"atomicResolution": -5.0, "atomicResolution": -5.0,
"minExchanges": 3, "minExchanges": 3,
@@ -968,23 +968,6 @@
"minOrderSize": 1000000, "minOrderSize": 1000000,
"quantumConversionExponent": -9 "quantumConversionExponent": -9
}, },
{
"baseAsset": "STRK",
"referencePrice": 2.05,
"numOracles": 6,
"liquidityTier": 2,
"assetName": "Starknet",
"p": 0.0,
"atomicResolution": -6.0,
"minExchanges": 3,
"minPriceChangePpm": 4000,
"priceExponent": -9.0,
"stepBaseQuantum": 1000000,
"ticksizeExponent": -3,
"subticksPerTick": 1000000,
"minOrderSize": 1000000,
"quantumConversionExponent": -9
},
{ {
"baseAsset": "STX", "baseAsset": "STX",
"referencePrice": 1.5144048703611412, "referencePrice": 1.5144048703611412,
@@ -1090,9 +1073,9 @@
{ {
"baseAsset": "WOO", "baseAsset": "WOO",
"referencePrice": 0.2944897275608197, "referencePrice": 0.2944897275608197,
"numOracles": 6, "numOracles": 5,
"liquidityTier": 2, "liquidityTier": 2,
"assetName": "WOO Network", "assetName": "Wootrade Network",
"p": -1.0, "p": -1.0,
"atomicResolution": -5.0, "atomicResolution": -5.0,
"minExchanges": 3, "minExchanges": 3,
Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 348 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 110 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 106 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 89 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 117 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 96 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 107 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -14,7 +14,7 @@ if (AMPLITUDE_API_KEY) {
const html = await fs.readFile(htmlFilePath, 'utf-8'); const html = await fs.readFile(htmlFilePath, 'utf-8');
const amplitudeCdnScript = `<script type="text/javascript"> const amplitudeCdnScript = `<script type="text/javascript">
!function(){"use strict";!function(e,t){var n=e.amplitude||{_q:[],_iq:{}};if(n.invoked)e.console&&console.error&&console.error("Amplitude snippet has been loaded.");else{var r=function(e,t){e.prototype[t]=function(){return this._q.push({name:t,args:Array.prototype.slice.call(arguments,0)}),this}},s=function(e,t,n){return function(r){e._q.push({name:t,args:Array.prototype.slice.call(n,0),resolve:r})}},o=function(e,t,n){e[t]=function(){if(n)return{promise:new Promise(s(e,t,Array.prototype.slice.call(arguments)))}}},i=function(e){for(var t=0;t<m.length;t++)o(e,m[t],!1);for(var n=0;n<g.length;n++)o(e,g[n],!0)};n.invoked=!0;var u=t.createElement("script");u.type="text/javascript",u.integrity="sha384-BVo5ZjsjH373rWbcjz9Qjb2L6BgLwLADcZtZZPu3nMl8+7LPDhi1NcUEf0Ate41Y",u.crossOrigin="anonymous",u.async=!0,u.src="/libs/amplitude-analytics-browser-2.0.0-min.js",u.onload=function(){e.amplitude.runQueuedFunctions||console.log("[Amplitude] Error: could not load SDK")};var a=t.getElementsByTagName("script")[0];a.parentNode.insertBefore(u,a);for(var c=function(){return this._q=[],this},p=["add","append","clearAll","prepend","set","setOnce","unset","preInsert","postInsert","remove","getUserProperties"],l=0;l<p.length;l++)r(c,p[l]);n.Identify=c;for(var d=function(){return this._q=[],this},f=["getEventProperties","setProductId","setQuantity","setPrice","setRevenue","setRevenueType","setEventProperties"],v=0;v<f.length;v++)r(d,f[v]);n.Revenue=d;var m=["getDeviceId","setDeviceId","getSessionId","setSessionId","getUserId","setUserId","setOptOut","setTransport","reset","extendSession"],g=["init","add","remove","track","logEvent","identify","groupIdentify","setGroup","revenue","flush"];i(n),n.createInstance=function(e){return n._iq[e]={_q:[]},i(n._iq[e]),n._iq[e]},e.amplitude=n}}(window,document)}(); !function(){"use strict";!function(e,t){var n=e.amplitude||{_q:[],_iq:{}};if(n.invoked)e.console&&console.error&&console.error("Amplitude snippet has been loaded.");else{var r=function(e,t){e.prototype[t]=function(){return this._q.push({name:t,args:Array.prototype.slice.call(arguments,0)}),this}},s=function(e,t,n){return function(r){e._q.push({name:t,args:Array.prototype.slice.call(n,0),resolve:r})}},o=function(e,t,n){e[t]=function(){if(n)return{promise:new Promise(s(e,t,Array.prototype.slice.call(arguments)))}}},i=function(e){for(var t=0;t<m.length;t++)o(e,m[t],!1);for(var n=0;n<g.length;n++)o(e,g[n],!0)};n.invoked=!0;var u=t.createElement("script");u.type="text/javascript",u.integrity="sha384-x0ik2D45ZDEEEpYpEuDpmj05fY91P7EOZkgdKmq4dKL/ZAVcufJ+nULFtGn0HIZE",u.crossOrigin="anonymous",u.async=!0,u.src="https://cdn.amplitude.com/libs/analytics-browser-2.0.0-min.js.gz",u.onload=function(){e.amplitude.runQueuedFunctions||console.log("[Amplitude] Error: could not load SDK")};var a=t.getElementsByTagName("script")[0];a.parentNode.insertBefore(u,a);for(var c=function(){return this._q=[],this},p=["add","append","clearAll","prepend","set","setOnce","unset","preInsert","postInsert","remove","getUserProperties"],l=0;l<p.length;l++)r(c,p[l]);n.Identify=c;for(var d=function(){return this._q=[],this},f=["getEventProperties","setProductId","setQuantity","setPrice","setRevenue","setRevenueType","setEventProperties"],v=0;v<f.length;v++)r(d,f[v]);n.Revenue=d;var m=["getDeviceId","setDeviceId","getSessionId","setSessionId","getUserId","setUserId","setOptOut","setTransport","reset","extendSession"],g=["init","add","remove","track","logEvent","identify","groupIdentify","setGroup","revenue","flush"];i(n),n.createInstance=function(e){return n._iq[e]={_q:[]},i(n._iq[e]),n._iq[e]},e.amplitude=n}}(window,document)}();
</script> </script>
`; `;
-22
View File
@@ -8,7 +8,6 @@ const assetIcons = {
'1INCH': '/currencies/1inch.png', '1INCH': '/currencies/1inch.png',
AAVE: '/currencies/aave.png', AAVE: '/currencies/aave.png',
ADA: '/currencies/ada.png', ADA: '/currencies/ada.png',
AGIX: '/currencies/agix.png',
ALGO: '/currencies/algo.png', ALGO: '/currencies/algo.png',
APE: '/currencies/ape.png', APE: '/currencies/ape.png',
APT: '/currencies/apt.png', APT: '/currencies/apt.png',
@@ -21,7 +20,6 @@ const assetIcons = {
BONK: '/currencies/bonk.png', BONK: '/currencies/bonk.png',
BTC: '/currencies/btc.png', BTC: '/currencies/btc.png',
CELO: '/currencies/celo.png', CELO: '/currencies/celo.png',
CHZ: '/currencies/chz.png',
COMP: '/currencies/comp.png', COMP: '/currencies/comp.png',
CRV: '/currencies/crv.png', CRV: '/currencies/crv.png',
DAI: '/currencies/dai.png', DAI: '/currencies/dai.png',
@@ -30,44 +28,25 @@ const assetIcons = {
DYDX: '/currencies/dydx.png', DYDX: '/currencies/dydx.png',
DYM: '/currencies/dym.png', DYM: '/currencies/dym.png',
ENJ: '/currencies/enj.png', ENJ: '/currencies/enj.png',
ENS: '/currencies/ens.png',
EOS: '/currencies/eos.png', EOS: '/currencies/eos.png',
ETC: '/currencies/etc.png', ETC: '/currencies/etc.png',
ETH: '/currencies/eth.png', ETH: '/currencies/eth.png',
FET: '/currencies/fet.png',
FIL: '/currencies/fil.png', FIL: '/currencies/fil.png',
FTM: '/currencies/ftm.png',
GALA: "/currencies/gala.png",
GMT: "/currencies/gmt.png",
GRT: "/currencies/grt.png",
HBAR: "/currencies/hbar.png",
ICP: '/currencies/icp.png', ICP: '/currencies/icp.png',
IMX: '/currencies/imx.png',
INJ: '/currencies/inj.png',
JTO: '/currencies/jto.png',
JUP: '/currencies/jup.png', JUP: '/currencies/jup.png',
KAVA: '/currencies/kava.png',
LDO: '/currencies/ldo.png', LDO: '/currencies/ldo.png',
LINK: '/currencies/link.png', LINK: '/currencies/link.png',
LTC: '/currencies/ltc.png', LTC: '/currencies/ltc.png',
MANA: '/currencies/mana.png',
MATIC: '/currencies/matic.png', MATIC: '/currencies/matic.png',
MASK: '/currencies/mask.png',
MINA: '/currencies/mina.png',
MKR: '/currencies/mkr.png', MKR: '/currencies/mkr.png',
NEAR: '/currencies/near.png', NEAR: '/currencies/near.png',
ORDI: "/currencies/ordi.png",
OP: '/currencies/op.png', OP: '/currencies/op.png',
PEPE: '/currencies/pepe.png', PEPE: '/currencies/pepe.png',
PYTH: '/currencies/pyth.png',
RNDR: '/currencies/rndr.png',
RUNE: '/currencies/rune.png', RUNE: '/currencies/rune.png',
SAND: '/currencies/sand.png',
SEI: '/currencies/sei.png', SEI: '/currencies/sei.png',
SHIB: '/currencies/shib.png', SHIB: '/currencies/shib.png',
SNX: '/currencies/snx.png', SNX: '/currencies/snx.png',
SOL: '/currencies/sol.png', SOL: '/currencies/sol.png',
STX: '/currencies/stx.png',
SUI: '/currencies/sui.png', SUI: '/currencies/sui.png',
SUSHI: '/currencies/sushi.png', SUSHI: '/currencies/sushi.png',
TIA: '/currencies/tia.png', TIA: '/currencies/tia.png',
@@ -78,7 +57,6 @@ const assetIcons = {
USDT: '/currencies/usdt.png', USDT: '/currencies/usdt.png',
WBTC: '/currencies/wbtc.png', WBTC: '/currencies/wbtc.png',
WETH: '/currencies/weth.png', WETH: '/currencies/weth.png',
WOO: '/currencies/woo.png',
WLD: '/currencies/wld.png', WLD: '/currencies/wld.png',
XLM: '/currencies/xlm.png', XLM: '/currencies/xlm.png',
XMR: '/currencies/xmr.png', XMR: '/currencies/xmr.png',
+3 -5
View File
@@ -39,7 +39,7 @@ export const SearchSelectMenu = ({
disabled, disabled,
label, label,
items, items,
withSearch = true, withSearch,
withReceiptItems, withReceiptItems,
}: SearchSelectMenuProps) => { }: SearchSelectMenuProps) => {
const [open, setOpen] = useState(false); const [open, setOpen] = useState(false);
@@ -77,7 +77,6 @@ export const SearchSelectMenu = ({
withSearch={withSearch} withSearch={withSearch}
onItemSelected={() => setOpen(false)} onItemSelected={() => setOpen(false)}
withStickyLayout withStickyLayout
$withSearch={withSearch}
/> />
</Styled.Popover> </Styled.Popover>
</Styled.WithDetailsReceipt> </Styled.WithDetailsReceipt>
@@ -128,7 +127,7 @@ Styled.Popover = styled(Popover)`
box-shadow: none; box-shadow: none;
`; `;
Styled.ComboboxMenu = styled(ComboboxMenu)<{ $withSearch?: boolean }>` Styled.ComboboxMenu = styled(ComboboxMenu)`
${layoutMixins.withInnerHorizontalBorders} ${layoutMixins.withInnerHorizontalBorders}
--comboboxMenu-backgroundColor: var(--color-layer-4); --comboboxMenu-backgroundColor: var(--color-layer-4);
@@ -141,8 +140,7 @@ Styled.ComboboxMenu = styled(ComboboxMenu)<{ $withSearch?: boolean }>`
--comboboxMenu-item-checked-textColor: var(--color-text-2); --comboboxMenu-item-checked-textColor: var(--color-text-2);
--comboboxMenu-item-highlighted-textColor: var(--color-text-2); --comboboxMenu-item-highlighted-textColor: var(--color-text-2);
--stickyArea1-topHeight: ${({ $withSearch }) => --stickyArea1-topHeight: var(--form-input-height);
!$withSearch ? '0' : 'var(--form-input-height)'};
input:focus-visible { input:focus-visible {
outline: none; outline: none;
-5
View File
@@ -33,9 +33,4 @@ TagStory.argTypes = {
control: { type: 'select' }, control: { type: 'select' },
defaultValue: undefined, defaultValue: undefined,
}, },
isHighlighted: {
options: [true, false],
control: { type: 'select' },
defaultValue: false,
},
}; };
-1
View File
@@ -76,6 +76,5 @@ export const Tag = styled.span<StyleProps>`
isHighlighted && isHighlighted &&
css` css`
background-color: var(--color-accent); background-color: var(--color-accent);
color: var(--color-text-button);
`} `}
`; `;
+1 -8
View File
@@ -1,4 +1,4 @@
import { type ReactNode, useState, useEffect } from 'react'; import { type ReactNode, useState } from 'react';
import { ButtonAction, ButtonState } from '@/constants/buttons'; import { ButtonAction, ButtonState } from '@/constants/buttons';
import { STRING_KEYS } from '@/constants/localization'; import { STRING_KEYS } from '@/constants/localization';
@@ -8,7 +8,6 @@ import { Button, type ButtonStateConfig, type ButtonProps } from '@/components/B
type ElementProps = { type ElementProps = {
timeoutInSeconds: number; timeoutInSeconds: number;
onTimeOut?: () => void;
slotFinal?: ReactNode; slotFinal?: ReactNode;
} & ButtonProps; } & ButtonProps;
@@ -17,7 +16,6 @@ export type TimeoutButtonProps = ElementProps;
export const TimeoutButton = ({ export const TimeoutButton = ({
children, children,
timeoutInSeconds, timeoutInSeconds,
onTimeOut,
slotFinal, slotFinal,
...otherProps ...otherProps
}: TimeoutButtonProps) => { }: TimeoutButtonProps) => {
@@ -27,11 +25,6 @@ export const TimeoutButton = ({
const secondsLeft = Math.max(0, (timeoutDeadline - now) / 1000); const secondsLeft = Math.max(0, (timeoutDeadline - now) / 1000);
useEffect(() => {
if (secondsLeft > 0) return;
onTimeOut?.();
}, [secondsLeft]);
if (slotFinal && secondsLeft <= 0) return slotFinal; if (slotFinal && secondsLeft <= 0) return slotFinal;
return ( return (
+2 -10
View File
@@ -144,17 +144,9 @@ export type AnalyticsEventData<T extends AnalyticsEvent> =
validatorUrl: string; validatorUrl: string;
} }
: T extends AnalyticsEvent.TransferDeposit : T extends AnalyticsEvent.TransferDeposit
? { ? {}
chainId?: string;
tokenAddress?: string;
tokenSymbol?: string;
}
: T extends AnalyticsEvent.TransferWithdraw : T extends AnalyticsEvent.TransferWithdraw
? { ? {}
chainId?: string;
tokenAddress?: string;
tokenSymbol?: string;
}
: // Trading : // Trading
T extends AnalyticsEvent.TradeOrderTypeSelected T extends AnalyticsEvent.TradeOrderTypeSelected
? { ? {
-1
View File
@@ -140,7 +140,6 @@ export type TransferNotifcation = {
isCctp?: boolean; isCctp?: boolean;
errorCount?: number; errorCount?: number;
status?: StatusResponse; status?: StatusResponse;
isExchange?: boolean;
}; };
/** /**
-1
View File
@@ -22,5 +22,4 @@ export enum NumberSign {
// Deposit/Withdraw // Deposit/Withdraw
export const MAX_CCTP_TRANSFER_AMOUNT = 1_000_000; export const MAX_CCTP_TRANSFER_AMOUNT = 1_000_000;
export const MIN_CCTP_TRANSFER_AMOUNT = 10;
export const MAX_PRICE_IMPACT = 0.02; // 2% export const MAX_PRICE_IMPACT = 0.02; // 2%
@@ -27,26 +27,19 @@ export const useChartMarketAndResolution = ({
const dispatch = useDispatch(); const dispatch = useDispatch();
const currentMarketId: string = useSelector(getCurrentMarketId) || DEFAULT_MARKETID; const currentMarketId: string = useSelector(getCurrentMarketId) || DEFAULT_MARKETID;
const selectedResolution: string = const selectedResolution: string =
useSelector(getSelectedResolutionForMarket(currentMarketId)) || DEFAULT_RESOLUTION; useSelector(getSelectedResolutionForMarket(currentMarketId)) || DEFAULT_RESOLUTION;
const chart = isWidgetReady ? tvWidget?.chart() : undefined; const chart = isWidgetReady ? tvWidget?.chart() : undefined;
const chartResolution = chart?.resolution?.(); const chartResolution = chart?.resolution?.();
/**
* @description Hook to handle changing markets - intentionally should avoid triggering on change of resolutions.
*/
useEffect(() => { useEffect(() => {
if (currentMarketId && isWidgetReady) { if (currentMarketId && isWidgetReady) {
const resolution = savedResolution || selectedResolution; const resolution = savedResolution || selectedResolution;
tvWidget?.setSymbol(currentMarketId, resolution as ResolutionString, () => {}); tvWidget?.setSymbol(currentMarketId, resolution as ResolutionString, () => {});
} }
}, [currentMarketId, isWidgetReady]); }, [currentMarketId, isWidgetReady, savedResolution, selectedResolution]);
/**
* @description Hook to handle changing chart resolution
*/
useEffect(() => { useEffect(() => {
if (chartResolution) { if (chartResolution) {
if (chartResolution !== selectedResolution) { if (chartResolution !== selectedResolution) {
+3 -9
View File
@@ -82,30 +82,24 @@ const useLocalNotificationsContext = () => {
isCctp, isCctp,
errorCount, errorCount,
status: currentStatus, status: currentStatus,
isExchange,
} = transferNotification; } = transferNotification;
const hasErrors =
// @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
// also error can some time come back as an empty object so we need to ignore for that // also error can some time come back as an empty object so we need to ignore for that
!!currentStatus?.errors || const hasErrors = !!currentStatus?.errors ||
(currentStatus?.error && Object.keys(currentStatus.error).length !== 0); (currentStatus?.error && Object.keys(currentStatus.error).length !== 0);
if ( if (
!isExchange &&
!hasErrors && !hasErrors &&
(!currentStatus?.squidTransactionStatus || (!currentStatus?.squidTransactionStatus ||
currentStatus?.squidTransactionStatus === 'ongoing') currentStatus?.squidTransactionStatus === 'ongoing')
) { ) {
try { try {
const status = await fetchSquidStatus( const status = await fetchSquidStatus({
{
transactionId: txHash, transactionId: txHash,
toChainId, toChainId,
fromChainId, fromChainId,
}, }, isCctp);
isCctp
);
if (status) { if (status) {
transferNotification.status = status; transferNotification.status = status;
+2 -3
View File
@@ -179,9 +179,8 @@ export const notificationTypes: NotificationTypeConfig[] = [
useEffect(() => { useEffect(() => {
for (const transfer of transferNotifications) { for (const transfer of transferNotifications) {
const { fromChainId, status, txHash, toAmount, type, isExchange } = transfer; const { fromChainId, status, txHash, toAmount, type } = transfer;
const isFinished = const isFinished = Boolean(status) && status?.squidTransactionStatus !== 'ongoing';
(Boolean(status) && status?.squidTransactionStatus !== 'ongoing') || isExchange;
const icon = <Icon iconName={isFinished ? IconName.Transfer : IconName.Clock} />; const icon = <Icon iconName={isFinished ? IconName.Transfer : IconName.Clock} />;
const transferType = const transferType =
+7 -6
View File
@@ -34,7 +34,7 @@ import {
import { DEFAULT_TRANSACTION_MEMO } from '@/constants/analytics'; import { DEFAULT_TRANSACTION_MEMO } from '@/constants/analytics';
import { DialogTypes } from '@/constants/dialogs'; import { DialogTypes } from '@/constants/dialogs';
import { UNCOMMITTED_ORDER_TIMEOUT_MS } from '@/constants/trade'; import { UNCOMMITTED_ORDER_TIMEOUT_MS } from '@/constants/trade';
import { DydxChainId, isTestnet } from '@/constants/networks'; import { DydxNetwork, isTestnet } from '@/constants/networks';
import { RootStore } from '@/state/_store'; import { RootStore } from '@/state/_store';
import { addUncommittedOrderClientId, removeUncommittedOrderClientId } from '@/state/account'; import { addUncommittedOrderClientId, removeUncommittedOrderClientId } from '@/state/account';
@@ -44,10 +44,7 @@ import { StatefulOrderError } from '../errors';
import { bytesToBigInt } from '../numbers'; import { bytesToBigInt } from '../numbers';
import { log } from '../telemetry'; import { log } from '../telemetry';
import { hashFromTx, getMintscanTxLink } from '../txUtils'; import { hashFromTx, getMintscanTxLink } from '../txUtils';
import { getDydxChainIdFromNetwork } from '../network';
(BigInt.prototype as any).toJSON = function () {
return this.toString();
};
class DydxChainTransactions implements AbacusDYDXChainTransactionsProtocol { class DydxChainTransactions implements AbacusDYDXChainTransactionsProtocol {
private compositeClient: CompositeClient | undefined; private compositeClient: CompositeClient | undefined;
@@ -242,7 +239,10 @@ class DydxChainTransactions implements AbacusDYDXChainTransactionsProtocol {
if (isTestnet) { if (isTestnet) {
console.log( console.log(
getMintscanTxLink(this.compositeClient.network.getString() as DydxChainId, hash) getMintscanTxLink(
getDydxChainIdFromNetwork(this.compositeClient.network.getString() as DydxNetwork),
hash
)
); );
} else console.log(`txHash: ${hash}`); } else console.log(`txHash: ${hash}`);
@@ -538,6 +538,7 @@ class DydxChainTransactions implements AbacusDYDXChainTransactionsProtocol {
const result = await this.cctpWithdraw(params); const result = await this.cctpWithdraw(params);
callback(result); callback(result);
break; break;
break;
} }
default: { default: {
break; break;
-19
View File
@@ -25,22 +25,3 @@ export function convertBech32Address({
}): string { }): string {
return toBech32(bech32Prefix, fromHex(toHex(fromBech32(address).data))); return toBech32(bech32Prefix, fromHex(toHex(fromBech32(address).data)));
} }
/**
* Validates a Cosmos address with a specific prefix.
* @param {string} address The Cosmos address to validate.
* @param {string} prefix The expected prefix for the address.
* @returns {boolean} True if the address is valid and matches the prefix, false otherwise.
*/
export function validateCosmosAddress(address: string, prefix: string) {
try {
// Decode the address to verify its structure and prefix
const { prefix: decodedPrefix } = fromBech32(address);
// Check if the decoded address has the expected prefix
return decodedPrefix === prefix;
} catch (error) {
// If decoding fails, the address is not valid
return false;
}
}
+4
View File
@@ -2,3 +2,7 @@ import { type DydxNetwork, ENVIRONMENT_CONFIG_MAP, type DydxChainId } from '@/co
export const validateAgainstAvailableEnvironments = (value: DydxNetwork) => export const validateAgainstAvailableEnvironments = (value: DydxNetwork) =>
Object.keys(ENVIRONMENT_CONFIG_MAP).includes(value); Object.keys(ENVIRONMENT_CONFIG_MAP).includes(value);
export const getDydxChainIdFromNetwork = (network: DydxNetwork) => {
return ENVIRONMENT_CONFIG_MAP[network].dydxChainId as DydxChainId;
};
+3 -3
View File
@@ -31,13 +31,13 @@ export const fetchSquidStatus = async (
const response = await fetch(url, { const response = await fetch(url, {
headers: { headers: {
'x-integrator-id': integratorId || 'dYdX-api', "x-integrator-id": integratorId || 'dYdX-api'
}, },
}); });
if (!response.ok) { if (!response.ok) {
const error = await response.json(); const error = await response.json();
throw error; throw new Error(error);
} }
return response.json(); return response.json();
@@ -45,4 +45,4 @@ export const fetchSquidStatus = async (
export const getNobleChainId = () => { export const getNobleChainId = () => {
return isMainnet ? 'noble-1' : 'grand-1'; return isMainnet ? 'noble-1' : 'grand-1';
}; }
-4
View File
@@ -26,10 +26,6 @@ class TestFlags {
get showTradingRewards() { get showTradingRewards() {
return !!this.queryParams.tradingrewards; return !!this.queryParams.tradingrewards;
} }
get showCexWithdrawal() {
return !!this.queryParams.cexwithdrawal;
}
} }
export const testFlags = new TestFlags(); export const testFlags = new TestFlags();
@@ -26,6 +26,8 @@ import { openDialog } from '@/state/dialogs';
import { log } from '@/lib/telemetry'; import { log } from '@/lib/telemetry';
const SEASON_NUMBER = 2;
export const LaunchIncentivesPanel = ({ className }: { className?: string }) => { export const LaunchIncentivesPanel = ({ className }: { className?: string }) => {
const { isNotTablet } = useBreakpoints(); const { isNotTablet } = useBreakpoints();
const dispatch = useDispatch(); const dispatch = useDispatch();
@@ -72,38 +74,14 @@ const EstimatedRewards = () => {
const stringGetter = useStringGetter(); const stringGetter = useStringGetter();
const { dydxAddress } = useAccounts(); const { dydxAddress } = useAccounts();
const { data: seasonNumber } = useQuery({
queryKey: 'chaos_labs_season_number',
queryFn: async () => {
const resp = await fetch('https://cloud.chaoslabs.co/query/ccar-perpetuals', {
method: 'POST',
headers: {
'apollographql-client-name': 'dydx-v4',
'content-type': 'application/json',
protocol: 'dydx-v4',
},
body: JSON.stringify({
operationName: 'TradingSeasons',
variables: {},
query: `query TradingSeasons {
tradingSeasons {
label
}
}`,
}),
});
const seasons = (await resp.json())?.data?.tradingSeasons;
return seasons && seasons.length > 0 ? seasons[seasons.length - 1].label : undefined;
},
onError: (error: Error) => log('LaunchIncentives/fetchSeasonNumber', error),
});
const { data, isLoading } = useQuery({ const { data, isLoading } = useQuery({
enabled: !!dydxAddress, enabled: !!dydxAddress,
queryKey: `launch_incentives_rewards_${dydxAddress ?? ''}`, queryKey: `launch_incentives_rewards_${dydxAddress ?? ''}_${SEASON_NUMBER}`,
queryFn: async () => { queryFn: async () => {
if (!dydxAddress) return undefined; if (!dydxAddress) return undefined;
const resp = await fetch(`https://cloud.chaoslabs.co/query/api/dydx/points/${dydxAddress}`); const resp = await fetch(
`https://cloud.chaoslabs.co/query/api/dydx/points/${dydxAddress}?n=${SEASON_NUMBER}`
);
return (await resp.json())?.incentivePoints; return (await resp.json())?.incentivePoints;
}, },
onError: (error: Error) => log('LaunchIncentives/fetchPoints', error), onError: (error: Error) => log('LaunchIncentives/fetchPoints', error),
@@ -114,14 +92,12 @@ const EstimatedRewards = () => {
<Styled.EstimatedRewardsCardContent> <Styled.EstimatedRewardsCardContent>
<div> <div>
<span>{stringGetter({ key: STRING_KEYS.ESTIMATED_REWARDS })}</span> <span>{stringGetter({ key: STRING_KEYS.ESTIMATED_REWARDS })}</span>
{seasonNumber !== undefined && (
<Styled.Season> <Styled.Season>
{stringGetter({ {stringGetter({
key: STRING_KEYS.LAUNCH_INCENTIVES_SEASON_NUM, key: STRING_KEYS.LAUNCH_INCENTIVES_SEASON_NUM,
params: { SEASON_NUMBER: seasonNumber }, params: { SEASON_NUMBER },
})} })}
</Styled.Season> </Styled.Season>
)}
</div> </div>
<Styled.Points> <Styled.Points>
+3 -1
View File
@@ -13,6 +13,8 @@ export const DepositDialog = ({ setIsOpen }: ElementProps) => {
const stringGetter = useStringGetter(); const stringGetter = useStringGetter();
const { isMobile } = useBreakpoints(); const { isMobile } = useBreakpoints();
const closeDialog = () => setIsOpen?.(false);
return ( return (
<Dialog <Dialog
isOpen isOpen
@@ -20,7 +22,7 @@ export const DepositDialog = ({ setIsOpen }: ElementProps) => {
title={stringGetter({ key: STRING_KEYS.DEPOSIT })} title={stringGetter({ key: STRING_KEYS.DEPOSIT })}
placement={isMobile ? DialogPlacement.FullScreen : DialogPlacement.Default} placement={isMobile ? DialogPlacement.FullScreen : DialogPlacement.Default}
> >
<DepositDialogContent /> <DepositDialogContent onDeposit={closeDialog} />
</Dialog> </Dialog>
); );
}; };
@@ -2,7 +2,6 @@ import { useEffect, useState } from 'react';
import styled, { type AnyStyledComponent } from 'styled-components'; import styled, { type AnyStyledComponent } from 'styled-components';
import { TransferInputField, TransferType } from '@/constants/abacus'; import { TransferInputField, TransferType } from '@/constants/abacus';
import { AnalyticsEvent } from '@/constants/analytics';
import { isMainnet } from '@/constants/networks'; import { isMainnet } from '@/constants/networks';
import { layoutMixins } from '@/styles/layoutMixins'; import { layoutMixins } from '@/styles/layoutMixins';
@@ -10,7 +9,6 @@ import { DepositForm } from '@/views/forms/AccountManagementForms/DepositForm';
import { TestnetDepositForm } from '@/views/forms/AccountManagementForms/TestnetDepositForm'; import { TestnetDepositForm } from '@/views/forms/AccountManagementForms/TestnetDepositForm';
import abacusStateManager from '@/lib/abacus'; import abacusStateManager from '@/lib/abacus';
import { track } from '@/lib/analytics';
type ElementProps = { type ElementProps = {
onDeposit?: () => void; onDeposit?: () => void;
@@ -36,19 +34,9 @@ export const DepositDialogContent = ({ onDeposit }: ElementProps) => {
return ( return (
<Styled.Content> <Styled.Content>
{isMainnet || !showFaucet ? ( {isMainnet || !showFaucet ? (
<DepositForm <DepositForm onDeposit={onDeposit} />
onDeposit={(event) => {
track(AnalyticsEvent.TransferDeposit, event);
onDeposit?.();
}}
/>
) : ( ) : (
<TestnetDepositForm <TestnetDepositForm onDeposit={onDeposit} />
onDeposit={() => {
track(AnalyticsEvent.TransferFaucet);
onDeposit?.();
}}
/>
)} )}
{!isMainnet && ( {!isMainnet && (
<Styled.TextToggle onClick={() => setShowFaucet(!showFaucet)}> <Styled.TextToggle onClick={() => setShowFaucet(!showFaucet)}>
+2 -2
View File
@@ -105,8 +105,8 @@ export const OnboardingDialog = ({ setIsOpen }: ElementProps) => {
<Styled.Content> <Styled.Content>
{isMainnet ? ( {isMainnet ? (
<DepositForm <DepositForm
onDeposit={(event) => { onDeposit={() => {
track(AnalyticsEvent.TransferDeposit, event); track(AnalyticsEvent.TransferDeposit);
}} }}
/> />
) : ( ) : (
@@ -7,7 +7,6 @@ import { Abi, parseUnits } from 'viem';
import erc20 from '@/abi/erc20.json'; import erc20 from '@/abi/erc20.json';
import erc20_usdt from '@/abi/erc20_usdt.json'; import erc20_usdt from '@/abi/erc20_usdt.json';
import { TransferInputField, TransferInputTokenResource, TransferType } from '@/constants/abacus'; import { TransferInputField, TransferInputTokenResource, TransferType } from '@/constants/abacus';
import { AnalyticsEvent, AnalyticsEventData } from '@/constants/analytics';
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';
@@ -49,7 +48,7 @@ import { DepositButtonAndReceipt } from './DepositForm/DepositButtonAndReceipt';
import { NobleDeposit } from '../NobleDeposit'; import { NobleDeposit } from '../NobleDeposit';
type DepositFormProps = { type DepositFormProps = {
onDeposit?: (event?: AnalyticsEventData<AnalyticsEvent.TransferDeposit>) => void; onDeposit?: () => void;
onError?: () => void; onError?: () => void;
}; };
@@ -133,7 +132,7 @@ export const DepositForm = ({ onDeposit, onError }: DepositFormProps) => {
if (error) onError?.(); if (error) onError?.();
}, [error]); }, [error]);
const onSelectNetwork = useCallback((name: string, type: 'chain' | 'exchange') => { const onSelectChain = useCallback((name: string, type: 'chain' | 'exchange') => {
if (name) { if (name) {
abacusStateManager.clearTransferInputValues(); abacusStateManager.clearTransferInputValues();
setFromAmount(''); setFromAmount('');
@@ -259,6 +258,8 @@ export const DepositForm = ({ onDeposit, onError }: DepositFormProps) => {
}; };
const txHash = await signerWagmi.sendTransaction(tx); const txHash = await signerWagmi.sendTransaction(tx);
onDeposit?.();
if (txHash) { if (txHash) {
addTransferNotification({ addTransferNotification({
txHash: txHash, txHash: txHash,
@@ -270,12 +271,6 @@ export const DepositForm = ({ onDeposit, onError }: DepositFormProps) => {
}); });
abacusStateManager.clearTransferInputValues(); abacusStateManager.clearTransferInputValues();
setFromAmount(''); setFromAmount('');
onDeposit?.({
chainId: chainIdStr || undefined,
tokenAddress: sourceToken?.address || undefined,
tokenSymbol: sourceToken?.symbol || undefined,
});
} }
} catch (error) { } catch (error) {
log('DepositForm/onSubmit', error); log('DepositForm/onSubmit', error);
@@ -284,7 +279,7 @@ export const DepositForm = ({ onDeposit, onError }: DepositFormProps) => {
setIsLoading(false); setIsLoading(false);
} }
}, },
[requestPayload, signerWagmi, chainId, sourceToken, sourceChain] [requestPayload, signerWagmi, chainId]
); );
const amountInputReceipt = [ const amountInputReceipt = [
@@ -383,7 +378,7 @@ export const DepositForm = ({ onDeposit, onError }: DepositFormProps) => {
<SourceSelectMenu <SourceSelectMenu
selectedChain={chainIdStr || undefined} selectedChain={chainIdStr || undefined}
selectedExchange={exchange || undefined} selectedExchange={exchange || undefined}
onSelect={onSelectNetwork} onSelect={onSelectChain}
/> />
{exchange && nobleAddress ? ( {exchange && nobleAddress ? (
<NobleDeposit /> <NobleDeposit />
@@ -14,7 +14,6 @@ import { popoverMixins } from '@/styles/popoverMixins';
import { getTransferInputs } from '@/state/inputsSelectors'; import { getTransferInputs } from '@/state/inputsSelectors';
import { isTruthy } from '@/lib/isTruthy'; import { isTruthy } from '@/lib/isTruthy';
import { testFlags } from '@/lib/testFlags';
type ElementProps = { type ElementProps = {
label?: string; label?: string;
@@ -63,8 +62,7 @@ export const SourceSelectMenu = ({
return ( return (
<SearchSelectMenu <SearchSelectMenu
items={[ items={[
exchangeItems.length > 0 && exchangeItems.length > 0 && {
(testFlags.showCexWithdrawal || type === TransferType.deposit) && {
group: 'exchanges', group: 'exchanges',
groupLabel: stringGetter({ key: STRING_KEYS.EXCHANGES }), groupLabel: stringGetter({ key: STRING_KEYS.EXCHANGES }),
items: exchangeItems, items: exchangeItems,
@@ -17,10 +17,9 @@ import { getTransferInputs } from '@/state/inputsSelectors';
type ElementProps = { type ElementProps = {
selectedToken?: TransferInputTokenResource; selectedToken?: TransferInputTokenResource;
onSelectToken: (token: TransferInputTokenResource) => void; onSelectToken: (token: TransferInputTokenResource) => void;
isExchange?: boolean;
}; };
export const TokenSelectMenu = ({ selectedToken, onSelectToken, isExchange }: ElementProps) => { export const TokenSelectMenu = ({ selectedToken, onSelectToken }: ElementProps) => {
const stringGetter = useStringGetter(); const stringGetter = useStringGetter();
const { type, depositOptions, withdrawalOptions, resources } = const { type, depositOptions, withdrawalOptions, resources } =
useSelector(getTransferInputs, shallowEqual) || {}; useSelector(getTransferInputs, shallowEqual) || {};
@@ -48,10 +47,7 @@ export const TokenSelectMenu = ({ selectedToken, onSelectToken, isExchange }: El
}, },
]} ]}
label={stringGetter({ key: STRING_KEYS.ASSET })} label={stringGetter({ key: STRING_KEYS.ASSET })}
withSearch={!isExchange} withReceiptItems={[
withReceiptItems={
!isExchange
? [
{ {
key: 'swap', key: 'swap',
label: stringGetter({ key: STRING_KEYS.SWAP }), label: stringGetter({ key: STRING_KEYS.SWAP }),
@@ -63,9 +59,7 @@ export const TokenSelectMenu = ({ selectedToken, onSelectToken, isExchange }: El
</> </>
), ),
}, },
] ]}
: undefined
}
> >
<Styled.AssetRow> <Styled.AssetRow>
{selectedToken ? ( {selectedToken ? (
@@ -7,17 +7,11 @@ import { isAddress } from 'viem';
import { TransferInputField, TransferInputTokenResource, TransferType } from '@/constants/abacus'; import { TransferInputField, TransferInputTokenResource, TransferType } from '@/constants/abacus';
import { AlertType } from '@/constants/alerts'; import { AlertType } from '@/constants/alerts';
import { AnalyticsEvent } from '@/constants/analytics';
import { ButtonSize } from '@/constants/buttons'; import { ButtonSize } from '@/constants/buttons';
import { STRING_KEYS } from '@/constants/localization'; import { STRING_KEYS } from '@/constants/localization';
import { isMainnet } from '@/constants/networks'; import { isMainnet } from '@/constants/networks';
import { TransferNotificationTypes } from '@/constants/notifications'; import { TransferNotificationTypes } from '@/constants/notifications';
import { import { MAX_CCTP_TRANSFER_AMOUNT, MAX_PRICE_IMPACT, NumberSign } from '@/constants/numbers';
MAX_CCTP_TRANSFER_AMOUNT,
MAX_PRICE_IMPACT,
MIN_CCTP_TRANSFER_AMOUNT,
NumberSign,
} from '@/constants/numbers';
import { import {
useAccounts, useAccounts,
@@ -56,8 +50,6 @@ import { getNobleChainId } from '@/lib/squid';
import { TokenSelectMenu } from './TokenSelectMenu'; import { TokenSelectMenu } from './TokenSelectMenu';
import { WithdrawButtonAndReceipt } from './WithdrawForm/WithdrawButtonAndReceipt'; import { WithdrawButtonAndReceipt } from './WithdrawForm/WithdrawButtonAndReceipt';
import { validateCosmosAddress } from '@/lib/addressUtils';
import { track } from '@/lib/analytics';
export const WithdrawForm = () => { export const WithdrawForm = () => {
const stringGetter = useStringGetter(); const stringGetter = useStringGetter();
@@ -71,7 +63,6 @@ export const WithdrawForm = () => {
const { const {
requestPayload, requestPayload,
token, token,
exchange,
chain: chainIdStr, chain: chainIdStr,
address: toAddress, address: toAddress,
resources, resources,
@@ -183,27 +174,18 @@ export const WithdrawForm = () => {
requestPayload.data, requestPayload.data,
isCctp isCctp
); );
const nobleChainId = getNobleChainId(); if (txHash) {
const toChainId = Boolean(exchange) ? nobleChainId : chainIdStr || undefined;
if (txHash && toChainId) {
addTransferNotification({ addTransferNotification({
txHash: txHash, txHash: txHash,
type: TransferNotificationTypes.Withdrawal, type: TransferNotificationTypes.Withdrawal,
fromChainId: !isCctp ? selectedDydxChainId : nobleChainId, fromChainId: !isCctp ? selectedDydxChainId : getNobleChainId(),
toChainId, toChainId: chainIdStr || undefined,
toAmount: debouncedAmountBN.toNumber(), toAmount: debouncedAmountBN.toNumber(),
triggeredAt: Date.now(), triggeredAt: Date.now(),
isCctp, isCctp,
isExchange: Boolean(exchange),
}); });
abacusStateManager.clearTransferInputValues(); abacusStateManager.clearTransferInputValues();
setWithdrawAmount(''); setWithdrawAmount('');
track(AnalyticsEvent.TransferWithdraw, {
chainId: toChainId,
tokenAddress: toToken?.address || undefined,
tokenSymbol: toToken?.symbol || undefined,
});
} }
} }
} catch (error) { } catch (error) {
@@ -226,17 +208,7 @@ export const WithdrawForm = () => {
setIsLoading(false); setIsLoading(false);
} }
}, },
[ [requestPayload, debouncedAmountBN, chainIdStr, toAddress, screenAddresses, stringGetter]
requestPayload,
debouncedAmountBN,
chainIdStr,
toAddress,
selectedDydxChainId,
exchange,
toToken,
screenAddresses,
stringGetter,
]
); );
const onChangeAddress = useCallback((e: ChangeEvent<HTMLInputElement>) => { const onChangeAddress = useCallback((e: ChangeEvent<HTMLInputElement>) => {
@@ -269,20 +241,13 @@ export const WithdrawForm = () => {
setWithdrawAmount(freeCollateralBN.toString()); setWithdrawAmount(freeCollateralBN.toString());
}, [freeCollateralBN, setWithdrawAmount]); }, [freeCollateralBN, setWithdrawAmount]);
const onSelectNetwork = useCallback((name: string, type: 'chain' | 'exchange') => { const onSelectChain = useCallback((chain: string) => {
if (name) { if (chain) {
setWithdrawAmount('');
if (type === 'chain') {
abacusStateManager.setTransferValue({ abacusStateManager.setTransferValue({
field: TransferInputField.chain, field: TransferInputField.chain,
value: name, value: chain,
}); });
} else { setWithdrawAmount('');
abacusStateManager.setTransferValue({
field: TransferInputField.exchange,
value: name,
});
}
} }
}, []); }, []);
@@ -343,7 +308,7 @@ export const WithdrawForm = () => {
}); });
if (debouncedAmountBN) { if (debouncedAmountBN) {
if (!chainIdStr && !exchange) { if (!chainIdStr) {
return stringGetter({ key: STRING_KEYS.WITHDRAW_MUST_SPECIFY_CHAIN }); return stringGetter({ key: STRING_KEYS.WITHDRAW_MUST_SPECIFY_CHAIN });
} else if (!toToken) { } else if (!toToken) {
return stringGetter({ key: STRING_KEYS.WITHDRAW_MUST_SPECIFY_ASSET }); return stringGetter({ key: STRING_KEYS.WITHDRAW_MUST_SPECIFY_ASSET });
@@ -363,12 +328,6 @@ export const WithdrawForm = () => {
}, },
}); });
} }
if (
!debouncedAmountBN.isZero() &&
MustBigNumber(debouncedAmountBN).lte(MIN_CCTP_TRANSFER_AMOUNT)
) {
return 'Amount must be greater than 10 USDC';
}
} }
if (isMainnet && MustBigNumber(summary?.aggregatePriceImpact).gte(MAX_PRICE_IMPACT)) { if (isMainnet && MustBigNumber(summary?.aggregatePriceImpact).gte(MAX_PRICE_IMPACT)) {
@@ -390,19 +349,14 @@ export const WithdrawForm = () => {
summary, summary,
]); ]);
const isInvalidNobleAddress = Boolean(
exchange && toAddress && !validateCosmosAddress(toAddress, 'noble')
);
const isDisabled = const isDisabled =
!!errorMessage || !!errorMessage ||
!toToken || !toToken ||
(!chainIdStr && !exchange) || !chainIdStr ||
!toAddress || !toAddress ||
debouncedAmountBN.isNaN() || debouncedAmountBN.isNaN() ||
debouncedAmountBN.isZero() || debouncedAmountBN.isZero() ||
isLoading || isLoading;
isInvalidNobleAddress;
return ( return (
<Styled.Form onSubmit={onSubmit}> <Styled.Form onSubmit={onSubmit}>
@@ -420,21 +374,12 @@ export const WithdrawForm = () => {
} }
/> />
<SourceSelectMenu <SourceSelectMenu
selectedExchange={exchange || undefined} label={stringGetter({ key: STRING_KEYS.NETWORK })}
selectedChain={chainIdStr || undefined} selectedChain={chainIdStr || undefined}
onSelect={onSelectNetwork} onSelect={onSelectChain}
/> />
</Styled.DestinationRow> </Styled.DestinationRow>
{isInvalidNobleAddress && ( <TokenSelectMenu selectedToken={toToken || undefined} onSelectToken={onSelectToken} />
<AlertMessage type={AlertType.Error}>
{stringGetter({ key: STRING_KEYS.NOBLE_ADDRESS_VALIDATION })}
</AlertMessage>
)}
<TokenSelectMenu
selectedToken={toToken || undefined}
onSelectToken={onSelectToken}
isExchange={Boolean(exchange)}
/>
<Styled.WithDetailsReceipt side="bottom" detailItems={amountInputReceipt}> <Styled.WithDetailsReceipt side="bottom" detailItems={amountInputReceipt}>
<FormInput <FormInput
type={InputType.Number} type={InputType.Number}
@@ -27,8 +27,6 @@ import { calculateCanAccountTrade } from '@/state/accountCalculators';
import { getSubaccount } from '@/state/accountSelectors'; import { getSubaccount } from '@/state/accountSelectors';
import { getTransferInputs } from '@/state/inputsSelectors'; import { getTransferInputs } from '@/state/inputsSelectors';
import { isTruthy } from '@/lib/isTruthy';
import { SlippageEditor } from '../SlippageEditor'; import { SlippageEditor } from '../SlippageEditor';
type ElementProps = { type ElementProps = {
@@ -57,7 +55,7 @@ export const WithdrawButtonAndReceipt = ({
const stringGetter = useStringGetter(); const stringGetter = useStringGetter();
const { leverage } = useSelector(getSubaccount, shallowEqual) || {}; const { leverage } = useSelector(getSubaccount, shallowEqual) || {};
const { summary, requestPayload, exchange } = useSelector(getTransferInputs, shallowEqual) || {}; const { summary, requestPayload } = useSelector(getTransferInputs, shallowEqual) || {};
const canAccountTrade = useSelector(calculateCanAccountTrade, shallowEqual); const canAccountTrade = useSelector(calculateCanAccountTrade, shallowEqual);
const { usdcLabel } = useTokenConfigs(); const { usdcLabel } = useTokenConfigs();
@@ -94,7 +92,7 @@ export const WithdrawButtonAndReceipt = ({
value: <Output type={OutputType.Fiat} value={totalFees} />, value: <Output type={OutputType.Fiat} value={totalFees} />,
subitems: feeSubitems, subitems: feeSubitems,
}, },
!exchange && { {
key: 'exchange-rate', key: 'exchange-rate',
label: <span>{stringGetter({ key: STRING_KEYS.EXCHANGE_RATE })}</span>, label: <span>{stringGetter({ key: STRING_KEYS.EXCHANGE_RATE })}</span>,
value: withdrawToken && typeof summary?.exchangeRate === 'number' && ( value: withdrawToken && typeof summary?.exchangeRate === 'number' && (
@@ -135,9 +133,7 @@ export const WithdrawButtonAndReceipt = ({
{withdrawToken && <Tag>{withdrawToken?.symbol}</Tag>} {withdrawToken && <Tag>{withdrawToken?.symbol}</Tag>}
</span> </span>
), ),
value: ( value: <Output type={OutputType.Asset} value={summary?.toAmount} fractionDigits={TOKEN_DECIMALS} />,
<Output type={OutputType.Asset} value={summary?.toAmount} fractionDigits={TOKEN_DECIMALS} />
),
subitems: [ subitems: [
{ {
key: 'minimum-amount-received', key: 'minimum-amount-received',
@@ -148,17 +144,13 @@ export const WithdrawButtonAndReceipt = ({
</span> </span>
), ),
value: ( value: (
<Output <Output type={OutputType.Asset} value={summary?.toAmountMin} fractionDigits={TOKEN_DECIMALS} />
type={OutputType.Asset}
value={summary?.toAmountMin}
fractionDigits={TOKEN_DECIMALS}
/>
), ),
tooltip: 'minimum-amount-received', tooltip: 'minimum-amount-received',
}, },
], ],
}, },
!exchange && { {
key: 'slippage', key: 'slippage',
label: <span>{stringGetter({ key: STRING_KEYS.MAX_SLIPPAGE })}</span>, label: <span>{stringGetter({ key: STRING_KEYS.MAX_SLIPPAGE })}</span>,
value: ( value: (
@@ -183,7 +175,7 @@ export const WithdrawButtonAndReceipt = ({
/> />
), ),
}, },
].filter(isTruthy); ];
const isFormValid = !isDisabled && !isEditingSlippage; const isFormValid = !isDisabled && !isEditingSlippage;
+31 -25
View File
@@ -1,5 +1,5 @@
import { useState } from 'react'; import { useState } from 'react';
import styled, { type AnyStyledComponent, css } from 'styled-components'; import styled, { type AnyStyledComponent } from 'styled-components';
import { OpacityToken } from '@/constants/styles/base'; import { OpacityToken } from '@/constants/styles/base';
import { STRING_KEYS } from '@/constants/localization'; import { STRING_KEYS } from '@/constants/localization';
@@ -10,6 +10,7 @@ import { useAccounts, useStringGetter } from '@/hooks';
import { CopyButton } from '@/components/CopyButton'; import { CopyButton } from '@/components/CopyButton';
import { QrCode } from '@/components/QrCode'; import { QrCode } from '@/components/QrCode';
import { Checkbox } from '@/components/Checkbox'; import { Checkbox } from '@/components/Checkbox';
import { Icon, IconName } from '@/components/Icon';
import { TimeoutButton } from '@/components/TimeoutButton'; import { TimeoutButton } from '@/components/TimeoutButton';
import { WithDetailsReceipt } from '@/components/WithDetailsReceipt'; import { WithDetailsReceipt } from '@/components/WithDetailsReceipt';
import { WithReceipt } from '@/components/WithReceipt'; import { WithReceipt } from '@/components/WithReceipt';
@@ -18,7 +19,6 @@ import { generateFadedColorVariant } from '@/lib/styles';
export const NobleDeposit = () => { export const NobleDeposit = () => {
const [hasAcknowledged, setHasAcknowledged] = useState(false); const [hasAcknowledged, setHasAcknowledged] = useState(false);
const [hasTimedout, setHasTimedout] = useState(false);
const stringGetter = useStringGetter(); const stringGetter = useStringGetter();
const { nobleAddress } = useAccounts(); const { nobleAddress } = useAccounts();
@@ -30,21 +30,23 @@ export const NobleDeposit = () => {
{ {
key: 'nobleAddress', key: 'nobleAddress',
label: stringGetter({ key: STRING_KEYS.NOBLE_ADDRESS }), label: stringGetter({ key: STRING_KEYS.NOBLE_ADDRESS }),
value: value: nobleAddress,
hasAcknowledged && hasTimedout
? nobleAddress
: stringGetter({ key: STRING_KEYS.ACKNOWLEDGE_TO_REVEAL }),
}, },
]} ]}
> >
<Styled.QrCode <Styled.QrCodeContainer>
hasLogo <Styled.QrCode size={432} value={nobleAddress || ''} />
size={432} </Styled.QrCodeContainer>
value={nobleAddress || ''}
blurred={!hasAcknowledged || !hasTimedout}
/>
</WithDetailsReceipt> </WithDetailsReceipt>
<Styled.WaitingSpan>
<Styled.CautionIconContainer>
<Icon iconName={IconName.CautionCircleStroked} />
</Styled.CautionIconContainer>
<p>{stringGetter({ key: STRING_KEYS.NOBLE_WARNING })}</p>
</Styled.WaitingSpan>
<Styled.WithReceipt <Styled.WithReceipt
slotReceipt={ slotReceipt={
<Styled.CheckboxContainer> <Styled.CheckboxContainer>
@@ -61,12 +63,7 @@ export const NobleDeposit = () => {
> >
<TimeoutButton <TimeoutButton
timeoutInSeconds={8} timeoutInSeconds={8}
onTimeOut={() => setHasTimedout(true)} slotFinal={<CopyButton state={{ isDisabled: !hasAcknowledged }} value={nobleAddress} />}
slotFinal={
<CopyButton state={{ isDisabled: !hasAcknowledged }} value={nobleAddress}>
{!hasAcknowledged ? stringGetter({ key: STRING_KEYS.ACKNOWLEDGE_RISKS }) : undefined}
</CopyButton>
}
/> />
</Styled.WithReceipt> </Styled.WithReceipt>
</> </>
@@ -85,14 +82,23 @@ Styled.WithReceipt = styled(WithReceipt)`
--withReceipt-backgroundColor: var(--color-layer-2); --withReceipt-backgroundColor: var(--color-layer-2);
`; `;
Styled.QrCode = styled(QrCode)<{ blurred: boolean }>` Styled.QrCodeContainer = styled.div`
border-radius: 0.5em; display: flex;
justify-content: center;
${({ blurred }) => padding: 0.5rem;
blurred &&
css` background-color: var(--color-layer-2);
filter: blur(8px); border-radius: 0.5rem;
`} `;
Styled.QrCode = styled(QrCode)`
max-height: 20rem;
width: fit-content;
svg {
max-height: 20rem;
}
`; `;
Styled.CheckboxContainer = styled.div` Styled.CheckboxContainer = styled.div`
@@ -40,7 +40,7 @@ export const TransferStatusNotification = ({
const stringGetter = useStringGetter(); const stringGetter = useStringGetter();
const [open, setOpen] = useState<boolean>(false); const [open, setOpen] = useState<boolean>(false);
const [secondsLeft, setSecondsLeft] = useState<number>(0); const [secondsLeft, setSecondsLeft] = useState<number>(0);
const { fromChainId, status, txHash, toAmount, isExchange } = transfer; const { fromChainId, status, txHash, toAmount } = transfer;
// @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;
@@ -54,8 +54,6 @@ export const TransferStatusNotification = ({
useInterval({ callback: updateSecondsLeft }); useInterval({ callback: updateSecondsLeft });
const isComplete = status?.squidTransactionStatus === 'success' || isExchange;
const inProgressStatusString = const inProgressStatusString =
type === TransferNotificationTypes.Deposit type === TransferNotificationTypes.Deposit
? secondsLeft > 0 ? secondsLeft > 0
@@ -67,10 +65,10 @@ export const TransferStatusNotification = ({
const statusString = const statusString =
type === TransferNotificationTypes.Deposit type === TransferNotificationTypes.Deposit
? isComplete ? status?.squidTransactionStatus === 'success'
? STRING_KEYS.DEPOSIT_COMPLETE ? STRING_KEYS.DEPOSIT_COMPLETE
: inProgressStatusString : inProgressStatusString
: isComplete : status?.squidTransactionStatus === 'success'
? STRING_KEYS.WITHDRAW_COMPLETE ? STRING_KEYS.WITHDRAW_COMPLETE
: inProgressStatusString; : inProgressStatusString;
@@ -110,12 +108,12 @@ export const TransferStatusNotification = ({
slotIcon={isToast && slotIcon} slotIcon={isToast && slotIcon}
slotTitle={slotTitle} slotTitle={slotTitle}
slotCustomContent={ slotCustomContent={
!status && !isExchange ? ( !status ? (
<LoadingDots size={3} /> <LoadingDots size={3} />
) : ( ) : (
<Styled.BridgingStatus> <Styled.BridgingStatus>
{content} {content}
{!isToast && !isComplete && !hasError && ( {!isToast && status?.squidTransactionStatus !== 'success' && !hasError && (
<Styled.TransferStatusSteps status={status} type={type} /> <Styled.TransferStatusSteps status={status} type={type} />
)} )}
</Styled.BridgingStatus> </Styled.BridgingStatus>