Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
da4fc821c8 | ||
|
|
b638ec1ad6 | ||
|
|
f7a1cfc67e | ||
|
|
d66a776ad2 | ||
|
|
e3e00f4f1e | ||
|
|
9ea578b8e4 | ||
|
|
f47fda45bf | ||
|
|
a7addda930 | ||
|
|
b839cf695e | ||
|
|
c9b8f1d59b | ||
|
|
91c04956d6 | ||
|
|
3a3f817501 | ||
|
|
5fb2f278da | ||
|
|
bd788f22e8 | ||
|
|
1a41ccaf2a | ||
|
|
26b426c9e9 | ||
|
|
994ba832f6 | ||
|
|
597456a0d1 | ||
|
|
3b75e60bd2 | ||
|
|
e453977299 | ||
|
|
dbc34599a6 | ||
|
|
f762e9bfac | ||
|
|
ed3c336cc0 | ||
|
|
b4f9f03bdc | ||
|
|
44ed52d5e2 | ||
|
|
42595a3667 | ||
|
|
2fc55bbe9f | ||
|
|
97452d7785 | ||
|
|
2704baf378 | ||
|
|
453d7c545e | ||
|
|
f79c062808 | ||
|
|
7d30c80320 | ||
|
|
1c1d602bf3 | ||
|
|
23a96c1c20 | ||
|
|
d81e6b3a2c | ||
|
|
732114a8de | ||
|
|
2c220233e3 | ||
|
|
8187e3615b | ||
|
|
c5888c2d5c | ||
|
|
793b522487 | ||
|
|
13d6610492 | ||
|
|
9cbb9fc2c6 | ||
|
|
91f5b89eb6 | ||
|
|
41cc531700 | ||
|
|
5aeb01f968 | ||
|
|
c9596de9c3 | ||
|
|
cc8c724f09 | ||
|
|
ac07abea07 | ||
|
|
54e81cca80 | ||
|
|
0ed1f33808 | ||
|
|
48e67f5681 | ||
|
|
da1ac0d087 | ||
|
|
17fce5417a | ||
|
|
b86a346be3 | ||
|
|
5cecc40a1c | ||
|
|
7134fa541d | ||
|
|
cd30c9c7d9 | ||
|
|
414e38afec | ||
|
|
e93850484b | ||
|
|
521b6d6135 | ||
|
|
94772bf4dc | ||
|
|
149f21e7e0 | ||
|
|
0a3ef3a7ab | ||
|
|
fef9935883 | ||
|
|
c7a5b706e1 | ||
|
|
f304bb069a | ||
|
|
ad6aa1af49 | ||
|
|
55b2c3fb4a | ||
|
|
83bcde00eb | ||
|
|
e8024b9337 | ||
|
|
8280e512bc |
@@ -8,7 +8,14 @@ VITE_V3_TOKEN_ADDRESS=
|
||||
VITE_TOKEN_MIGRATION_URI=
|
||||
|
||||
AMPLITUDE_API_KEY=
|
||||
AMPLITUDE_SERVER_URL=
|
||||
BUGSNAG_API_KEY=
|
||||
IOS_APP_ID=
|
||||
INTERCOM_APP_ID=
|
||||
STATUS_PAGE_SCRIPT_URI=
|
||||
|
||||
SMARTBANNER_APP_NAME=
|
||||
SMARTBANNER_ORG_NAME=
|
||||
SMARTBANNER_ICON_URL=
|
||||
SMARTBANNER_APPSTORE_URL=
|
||||
SMARTBANNER_GOOGLEPLAY_URL=
|
||||
|
||||
@@ -39,6 +39,7 @@ jobs:
|
||||
pnpm run build:inject-amplitude
|
||||
pnpm run build:inject-bugsnag
|
||||
pnpm run build:inject-statuspage
|
||||
pnpm run build:inject-smartbanner
|
||||
sh scripts/inject-app-deeplinks.sh
|
||||
|
||||
- name: Upload to IPFS via web3.storage
|
||||
|
||||
@@ -2,74 +2,132 @@ import '@/polyfills';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { Provider } from 'react-redux';
|
||||
import styled from 'styled-components';
|
||||
import { WagmiConfig } from 'wagmi';
|
||||
import { GrazProvider } from 'graz';
|
||||
import { QueryClient, QueryClientProvider } from 'react-query';
|
||||
|
||||
import { store } from '@/state/_store';
|
||||
import { SupportedLocales } from '@/constants/localization';
|
||||
|
||||
import { AccountsProvider } from '@/hooks/useAccounts';
|
||||
import { AppThemeAndColorModeProvider } from '@/hooks/useAppThemeAndColorMode';
|
||||
import { DydxProvider } from '@/hooks/useDydxClient';
|
||||
import { DialogAreaProvider } from '@/hooks/useDialogArea';
|
||||
import { LocaleProvider } from '@/hooks/useLocaleSeparators';
|
||||
import { PotentialMarketsProvider } from '@/hooks/usePotentialMarkets';
|
||||
import { RestrictionProvider } from '@/hooks/useRestrictions';
|
||||
import { SubaccountProvider } from '@/hooks/useSubaccount';
|
||||
|
||||
import { GlobalStyle } from '@/styles/globalStyle';
|
||||
|
||||
import { SelectMenu, SelectItem } from '@/components/SelectMenu';
|
||||
|
||||
import { setLocaleLoaded } from '@/state/localization';
|
||||
import {
|
||||
AppTheme,
|
||||
AppThemeSystemSetting,
|
||||
AppColorMode,
|
||||
setAppThemeSetting,
|
||||
setAppColorMode,
|
||||
} from '@/state/configs';
|
||||
|
||||
import { setLocaleLoaded, setSelectedLocale } from '@/state/localization';
|
||||
import { store } from '@/state/_store';
|
||||
|
||||
import { config } from '@/lib/wagmi';
|
||||
|
||||
import '@/index.css';
|
||||
import './ladle.css';
|
||||
|
||||
const queryClient = new QueryClient();
|
||||
|
||||
const wrapProvider = (Component: React.ComponentType<any>, props?: any) => {
|
||||
// eslint-disable-next-line react/display-name
|
||||
return ({ children }: { children: React.ReactNode }) => (
|
||||
<Component {...props}>{children}</Component>
|
||||
);
|
||||
};
|
||||
|
||||
const providers = [
|
||||
wrapProvider(QueryClientProvider, { client: queryClient }),
|
||||
wrapProvider(GrazProvider),
|
||||
wrapProvider(WagmiConfig, { config }),
|
||||
wrapProvider(LocaleProvider),
|
||||
wrapProvider(RestrictionProvider),
|
||||
wrapProvider(DydxProvider),
|
||||
wrapProvider(AccountsProvider),
|
||||
wrapProvider(SubaccountProvider),
|
||||
wrapProvider(DialogAreaProvider),
|
||||
wrapProvider(PotentialMarketsProvider),
|
||||
wrapProvider(AppThemeAndColorModeProvider),
|
||||
];
|
||||
|
||||
export const StoryWrapper: React.FC<{ children: React.ReactNode }> = ({ children }) => {
|
||||
const [theme, setTheme] = useState('Default theme');
|
||||
const [theme, setTheme] = useState(AppTheme.Classic);
|
||||
const [colorMode, setColorMode] = useState(AppColorMode.GreenUp);
|
||||
|
||||
useEffect(() => {
|
||||
switch (theme) {
|
||||
case 'Dark theme': {
|
||||
document?.documentElement?.classList.remove('theme-light');
|
||||
document?.documentElement?.classList.add('theme-dark');
|
||||
break;
|
||||
}
|
||||
case 'Light theme': {
|
||||
document?.documentElement?.classList.remove('theme-dark');
|
||||
document?.documentElement?.classList.add('theme-light');
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
document?.documentElement?.classList.remove('theme-dark', 'theme-light');
|
||||
break;
|
||||
}
|
||||
}
|
||||
}, [theme]);
|
||||
store.dispatch(setAppThemeSetting(theme));
|
||||
store.dispatch(setAppColorMode(colorMode));
|
||||
}, [theme, colorMode]);
|
||||
|
||||
useEffect(() => {
|
||||
store.dispatch(setSelectedLocale({ locale: SupportedLocales.EN }));
|
||||
store.dispatch(setLocaleLoaded(true));
|
||||
}, []);
|
||||
|
||||
const content = [...providers].reverse().reduce(
|
||||
(children, Provider) => {
|
||||
return <Provider>{children}</Provider>;
|
||||
},
|
||||
<StoryContent>
|
||||
<GlobalStyle />
|
||||
{children}
|
||||
</StoryContent>
|
||||
);
|
||||
|
||||
return (
|
||||
<Provider store={store}>
|
||||
<StoryHeader>
|
||||
<h4>Active Theme:</h4>
|
||||
<SelectMenu
|
||||
value={theme}
|
||||
onValueChange={setTheme}
|
||||
>
|
||||
<SelectMenu value={theme} onValueChange={setTheme}>
|
||||
{[
|
||||
{
|
||||
value: 'Default theme',
|
||||
value: AppTheme.Classic,
|
||||
label: 'Default theme',
|
||||
},
|
||||
{
|
||||
value: 'Dark theme',
|
||||
value: AppThemeSystemSetting.System,
|
||||
label: 'System theme',
|
||||
},
|
||||
{
|
||||
value: AppTheme.Dark,
|
||||
label: 'Dark theme',
|
||||
},
|
||||
{
|
||||
value: 'Light theme',
|
||||
value: AppTheme.Light,
|
||||
label: 'Light theme',
|
||||
},
|
||||
].map(({ value, label }) => (
|
||||
<SelectItem
|
||||
key={value}
|
||||
value={value}
|
||||
label={label}
|
||||
/>
|
||||
<SelectItem key={value} value={value} label={label} />
|
||||
))}
|
||||
</SelectMenu>
|
||||
<h4>Active Color Mode:</h4>
|
||||
<SelectMenu value={colorMode} onValueChange={setColorMode}>
|
||||
{[
|
||||
{
|
||||
value: AppColorMode.GreenUp,
|
||||
label: 'Green up',
|
||||
},
|
||||
{
|
||||
value: AppColorMode.RedUp,
|
||||
label: 'Red up',
|
||||
},
|
||||
].map(({ value, label }) => (
|
||||
<SelectItem key={value} value={value} label={label} />
|
||||
))}
|
||||
</SelectMenu>
|
||||
</StoryHeader>
|
||||
<hr />
|
||||
<StoryContent>{children}</StoryContent>
|
||||
{content}
|
||||
</Provider>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -78,11 +78,12 @@ Set environment variables via `.env`.
|
||||
- `VITE_V3_TOKEN_ADDRESS` (optional): Address of the V3 $DYDX token.
|
||||
- `VITE_TOKEN_MIGRATION_URI` (optional): The URL of the token migration website.
|
||||
- `AMPLITUDE_API_KEY` (optional): Amplitude API key for enabling Amplitude; used with `pnpm run build:inject-amplitude`.
|
||||
- `AMPLITUDE_SERVER_URL` (optional): Custom Amplitude server URL
|
||||
- `BUGSNAG_API_KEY` (optional): API key for enabling Bugsnag; used with `pnpm run build:inject-bugsnag`.
|
||||
- `IOS_APP_ID` (optional): iOS app ID used for enabling deep linking to the iOS app; used with `pnpm run build:inject-app-deeplinks`.
|
||||
- `INTERCOM_APP_ID` (optional): Used for enabling Intercom; utilized with `pnpm run build:inject-intercom`.
|
||||
- `STATUS_PAGE_SCRIPT_URI` (optional): Used for enabling the status page; used with `pnpm run build:inject-statuspage`.
|
||||
|
||||
- `SMARTBANNER_APP_NAME`, `SMARTBANNER_ORG_NAME`, `SMARTBANNER_ICON_URL`, `SMARTBANNER_APPSTORE_URL` (optional): Used for enabling the smart app banner; used with `pnpm run build:inject-smartbanner`.
|
||||
|
||||
# Deployments
|
||||
|
||||
@@ -106,6 +107,9 @@ pnpm run build --mode testnet
|
||||
If you wish to incorporate analytics via Amplitude and Bugsnag, you can use our scripts:
|
||||
`pnpm run build:inject-amplitude` and `pnpm run build:inject-bugsnag`. You will need to provide your own API keys for these services. In the Environment Variables section, name the variables as `AMPLITUDE_API_KEY` and `BUGSNAG_API_KEY` and provide the respective keys as their values.
|
||||
|
||||
If you wish to incorporate smart banner for iOS and/or Android apps, you can use our scripts:
|
||||
`pnpm run build:inject-smartbanner`. You will need to provide your own app configurations for these services. In the Environment Variables section, name the variables as `SMARTBANNER_APP_NAME`, `SMARTBANNER_ORG_NAME`, `SMARTBANNER_ICON_URL` and `SMARTBANNER_APPSTORE_URL` or `SMARTBANNER_GOOGLEPLAY_URL` and provide the respective values.
|
||||
|
||||
For more details, check out Vercel's [official documentation](https://vercel.com/docs).
|
||||
|
||||
## Deploying to IPFS
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
"build:inject-bugsnag": "node scripts/inject-bugsnag.js",
|
||||
"build:inject-intercom": "node scripts/inject-intercom.js",
|
||||
"build:inject-statuspage": "node scripts/inject-statuspage.js",
|
||||
"build:inject-smartbanner": "node scripts/inject-smartbanner.js",
|
||||
"deploy:ipfs": "node scripts/upload-ipfs.js --verbose",
|
||||
"deploy:update-ipns": "node scripts/update-ipns.js",
|
||||
"deploy:update-dnslink": "node scripts/update-dnslink.js",
|
||||
@@ -33,15 +34,15 @@
|
||||
"packageManager": "pnpm@8.6.6",
|
||||
"dependencies": {
|
||||
"@0xsquid/sdk": "^1.10.0",
|
||||
"@cosmjs/amino": "^0.31.0",
|
||||
"@cosmjs/crypto": "^0.31.0",
|
||||
"@cosmjs/encoding": "^0.31.0",
|
||||
"@cosmjs/proto-signing": "^0.31.0",
|
||||
"@cosmjs/stargate": "^0.31.0",
|
||||
"@cosmjs/tendermint-rpc": "^0.31.0",
|
||||
"@dydxprotocol/v4-abacus": "^1.1.33",
|
||||
"@dydxprotocol/v4-client-js": "^1.0.11",
|
||||
"@dydxprotocol/v4-localization": "^1.1.6",
|
||||
"@cosmjs/amino": "^0.32.1",
|
||||
"@cosmjs/crypto": "^0.32.1",
|
||||
"@cosmjs/encoding": "^0.32.1",
|
||||
"@cosmjs/proto-signing": "^0.32.1",
|
||||
"@cosmjs/stargate": "^0.32.1",
|
||||
"@cosmjs/tendermint-rpc": "^0.32.1",
|
||||
"@dydxprotocol/v4-abacus": "^1.4.2",
|
||||
"@dydxprotocol/v4-client-js": "^1.0.20",
|
||||
"@dydxprotocol/v4-localization": "^1.1.30",
|
||||
"@ethersproject/providers": "^5.7.2",
|
||||
"@js-joda/core": "^5.5.3",
|
||||
"@radix-ui/react-accordion": "^1.1.2",
|
||||
@@ -92,6 +93,7 @@
|
||||
"buffer": "^6.0.3",
|
||||
"cmdk": "^0.2.0",
|
||||
"color": "^4.2.3",
|
||||
"cosmjs-types": "^0.9.0",
|
||||
"crypto-js": "^4.1.1",
|
||||
"ethers": "^6.6.1",
|
||||
"graz": "^0.0.43",
|
||||
@@ -116,7 +118,7 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.22.5",
|
||||
"@ladle/react": "^2.15.0",
|
||||
"@ladle/react": "^4.0.2",
|
||||
"@types/color": "^3.0.3",
|
||||
"@types/crypto-js": "^4.1.1",
|
||||
"@types/luxon": "^3.3.0",
|
||||
@@ -155,5 +157,10 @@
|
||||
"vitest": "^0.32.2",
|
||||
"w3name": "^1.0.8",
|
||||
"web3.storage": "^4.5.4"
|
||||
},
|
||||
"pnpm": {
|
||||
"overrides": {
|
||||
"follow-redirects": "1.15.3"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
[
|
||||
{
|
||||
"relation": ["delegate_permission/common.handle_all_urls"],
|
||||
"target": {
|
||||
"namespace": "android_app",
|
||||
"package_name": "exchange.dydx.trading.debug",
|
||||
"sha256_cert_fingerprints": [
|
||||
"8A:9C:CC:49:B0:35:9A:91:67:CB:98:B0:B5:87:92:5F:9E:B7:EF:CE:A0:47:57:85:A4:35:3E:0C:E1:56:9E:A2"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"relation": ["delegate_permission/common.handle_all_urls"],
|
||||
"target": {
|
||||
"namespace": "android_app",
|
||||
"package_name": "exchange.dydx.trading",
|
||||
"sha256_cert_fingerprints": [
|
||||
"B2:2D:CC:27:9D:52:05:98:63:C9:7B:34:36:70:A3:8E:00:31:28:08:2D:2E:70:76:C9:31:AE:F9:55:21:15:A5"
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
|
Before Width: | Height: | Size: 122 KiB |
@@ -0,0 +1,19 @@
|
||||
<svg width="120" height="97" viewBox="0 0 120 97" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect y="8" width="120" height="1" fill="currentColor"/>
|
||||
<rect y="18" width="120" height="1" fill="currentColor"/>
|
||||
<rect y="28" width="120" height="1" fill="currentColor"/>
|
||||
<rect y="38" width="120" height="1" fill="currentColor"/>
|
||||
<rect y="48" width="120" height="1" fill="currentColor"/>
|
||||
<rect y="58" width="120" height="1" fill="currentColor"/>
|
||||
<rect y="68" width="120" height="1" fill="currentColor"/>
|
||||
<rect y="78" width="120" height="1" fill="currentColor"/>
|
||||
<rect y="88" width="120" height="1" fill="currentColor"/>
|
||||
<rect x="18" width="1" height="97" fill="currentColor"/>
|
||||
<rect x="32" width="1" height="97" fill="currentColor"/>
|
||||
<rect x="46" width="1" height="97" fill="currentColor"/>
|
||||
<rect x="60" width="1" height="97" fill="currentColor"/>
|
||||
<rect x="74" width="1" height="97" fill="currentColor"/>
|
||||
<rect x="88" width="1" height="97" fill="currentColor"/>
|
||||
<rect x="102" width="1" height="97" fill="currentColor"/>
|
||||
<path d="M0 0H120V97H0V0Z" fill="url(#paint0_radial_314_37586)"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
@@ -0,0 +1,20 @@
|
||||
<svg width="90" height="39" viewBox="0 0 90 39" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect y="31.2344" width="2.57142" height="7.71427" fill="#3ED9A4"/>
|
||||
<rect x="5.14258" y="28.6648" width="2.57142" height="5.14284" fill="#E45555"/>
|
||||
<rect x="25.7139" y="26.0923" width="2.57142" height="10.2857" fill="#E45555"/>
|
||||
<rect x="51.4283" y="28.6648" width="2.57142" height="5.14284" fill="#E45555"/>
|
||||
<rect x="56.5712" y="31.2344" width="2.57142" height="5.14284" fill="#E45555"/>
|
||||
<rect x="77.1426" y="18.3767" width="2.57142" height="5.14284" fill="#E45555"/>
|
||||
<rect x="41.1427" y="23.5198" width="2.57142" height="5.14284" fill="#E45555"/>
|
||||
<rect x="10.2856" y="28.6648" width="2.57142" height="10.2857" fill="#3ED9A4"/>
|
||||
<rect x="61.7143" y="23.5198" width="2.57142" height="10.2857" fill="#3ED9A4"/>
|
||||
<rect x="66.8569" y="20.9492" width="2.57142" height="5.14284" fill="#3ED9A4"/>
|
||||
<rect x="71.9997" y="13.2346" width="2.57142" height="7.71427" fill="#3ED9A4"/>
|
||||
<rect x="82.2856" y="10.6631" width="2.57142" height="10.2857" fill="#3ED9A4"/>
|
||||
<rect x="87.4287" y="0.37793" width="2.57142" height="15.4285" fill="#3ED9A4"/>
|
||||
<rect x="15.4284" y="26.0923" width="2.57142" height="5.14284" fill="#3ED9A4"/>
|
||||
<rect x="20.5714" y="23.5198" width="2.57142" height="5.14284" fill="#3ED9A4"/>
|
||||
<rect x="30.857" y="31.2344" width="2.57142" height="5.14284" fill="#3ED9A4"/>
|
||||
<rect x="35.9999" y="26.0923" width="2.57142" height="5.14284" fill="#3ED9A4"/>
|
||||
<rect x="46.2853" y="26.0923" width="2.57142" height="2.57142" fill="#3ED9A4"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.5 KiB |
|
After Width: | Height: | Size: 2.2 MiB |
|
After Width: | Height: | Size: 2.1 MiB |
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"apps": {
|
||||
"ios": {
|
||||
"scheme": "dydxv4"
|
||||
"scheme": "dydx-t-v4"
|
||||
}
|
||||
},
|
||||
"deployments": {
|
||||
@@ -11,6 +11,13 @@
|
||||
],
|
||||
"default": "dydxprotocol-mainnet"
|
||||
},
|
||||
"TESTFLIGHT": {
|
||||
"environments": [
|
||||
"dydxprotocol-mainnet",
|
||||
"dydxprotocol-testnet"
|
||||
],
|
||||
"default": "dydxprotocol-mainnet"
|
||||
},
|
||||
"TESTNET": {
|
||||
"environments": [
|
||||
"dydxprotocol-testnet"
|
||||
@@ -39,7 +46,7 @@
|
||||
"environments": {
|
||||
"dydxprotocol-dev": {
|
||||
"name": "v4 Dev",
|
||||
"ethereumChainId": "5",
|
||||
"ethereumChainId": "11155111",
|
||||
"dydxChainId": "dydxprotocol-testnet",
|
||||
"chainName": "dYdX Chain",
|
||||
"chainLogo": "/dydx-chain.png",
|
||||
@@ -81,14 +88,15 @@
|
||||
"blogs": "https://www.dydx.foundation/blog",
|
||||
"foundation": "https://www.dydx.foundation",
|
||||
"help": "https://help.dydx.exchange/",
|
||||
"initialMarginFractionLearnMore": "https://help.dydx.exchange/articles/5232637-maximum-position-sizes",
|
||||
"reduceOnlyLearnMore": "https://help.dydx.exchange/articles/6345793-reduce-only-orders",
|
||||
"mintscanBase": "https://testnet.mintscan.io/dydx-testnet",
|
||||
"documentation": "https://docs.dydx.exchange/",
|
||||
"community": "https://discord.com/invite/dydx",
|
||||
"governanceLearnMore": "https://help.dydx.exchange",
|
||||
"newMarketProposalLearnMore": "https://dydx.exchange/blog/new-market-proposals",
|
||||
"stakingLearnMore": "https://help.dydx.exchange",
|
||||
"keplrDashboard": "https://testnet.keplr.app/",
|
||||
"strideZoneApp": "https://testnet.stride.zone",
|
||||
"accountExportLearnMore": "https://help.dydx.exchange/en/articles/8565867-secret-phrase-on-dydx-chain",
|
||||
"walletLearnMore": "https://www.dydx.academy/video/defi-wallet"
|
||||
},
|
||||
@@ -109,11 +117,21 @@
|
||||
"images": "/wallets/",
|
||||
"signTypedDataAction": "dYdX Chain Onboarding",
|
||||
"signTypedDataDomainName": "dYdX Chain"
|
||||
},
|
||||
"governance": {
|
||||
"newMarketProposal": {
|
||||
"initialDepositAmount": 10000000,
|
||||
"delayBlocks": 900,
|
||||
"newMarketsMethodology": "https://docs.google.com/spreadsheets/d/1zjkV9R7R_7KMItuzqzvKGwefSBRfE-ZNAx1LH55OcqY/edit?usp=sharing"
|
||||
}
|
||||
},
|
||||
"featureFlags": {
|
||||
"reduceOnlySupported": true
|
||||
}
|
||||
},
|
||||
"dydxprotocol-dev-2": {
|
||||
"name": "v4 Dev 2",
|
||||
"ethereumChainId": "5",
|
||||
"ethereumChainId": "11155111",
|
||||
"dydxChainId": "dydxprotocol-testnet",
|
||||
"chainName": "dYdX Chain",
|
||||
"chainLogo": "/dydx-chain.png",
|
||||
@@ -154,14 +172,15 @@
|
||||
"blogs": "https://www.dydx.foundation/blog",
|
||||
"foundation": "https://www.dydx.foundation",
|
||||
"help": "https://help.dydx.exchange/",
|
||||
"initialMarginFractionLearnMore": "https://help.dydx.exchange/articles/5232637-maximum-position-sizes",
|
||||
"reduceOnlyLearnMore": "https://help.dydx.exchange/articles/6345793-reduce-only-orders",
|
||||
"mintscanBase": "https://testnet.mintscan.io/dydx-testnet",
|
||||
"documentation": "https://docs.dydx.exchange/",
|
||||
"community": "https://discord.com/invite/dydx",
|
||||
"governanceLearnMore": "https://help.dydx.exchange",
|
||||
"newMarketProposalLearnMore": "https://dydx.exchange/blog/new-market-proposals",
|
||||
"stakingLearnMore": "https://help.dydx.exchange",
|
||||
"keplrDashboard": "https://testnet.keplr.app/",
|
||||
"strideZoneApp": "https://testnet.stride.zone",
|
||||
"accountExportLearnMore": "https://help.dydx.exchange/en/articles/8565867-secret-phrase-on-dydx-chain",
|
||||
"walletLearnMore": "https://www.dydx.academy/video/defi-wallet"
|
||||
},
|
||||
@@ -182,11 +201,21 @@
|
||||
"images": "/wallets/",
|
||||
"signTypedDataAction": "dYdX Chain Onboarding",
|
||||
"signTypedDataDomainName": "dYdX Chain"
|
||||
},
|
||||
"governance": {
|
||||
"newMarketProposal": {
|
||||
"initialDepositAmount": 10000000,
|
||||
"delayBlocks": 900,
|
||||
"newMarketsMethodology": "https://docs.google.com/spreadsheets/d/1zjkV9R7R_7KMItuzqzvKGwefSBRfE-ZNAx1LH55OcqY/edit?usp=sharing"
|
||||
}
|
||||
},
|
||||
"featureFlags": {
|
||||
"reduceOnlySupported": true
|
||||
}
|
||||
},
|
||||
"dydxprotocol-dev-4": {
|
||||
"name": "v4 Dev 4",
|
||||
"ethereumChainId": "5",
|
||||
"ethereumChainId": "11155111",
|
||||
"dydxChainId": "dydxprotocol-testnet",
|
||||
"chainName": "dYdX Chain",
|
||||
"chainLogo": "/dydx-chain.png",
|
||||
@@ -215,10 +244,11 @@
|
||||
}
|
||||
],
|
||||
"validators": [
|
||||
"http://validator.v4dev4.dydx.exchange"
|
||||
"https://validator.v4dev4.dydx.exchange"
|
||||
],
|
||||
"0xsquid": "https://testnet.api.0xsquid.com",
|
||||
"nobleValidator": "https://noble-testnet-rpc.polkachu.com/"
|
||||
"nobleValidator": "https://noble-testnet-rpc.polkachu.com/",
|
||||
"faucet": "https://faucet.v4dev4.dydx.exchange"
|
||||
},
|
||||
"links": {
|
||||
"tos": "https://dydx.exchange/v4-terms",
|
||||
@@ -227,14 +257,15 @@
|
||||
"blogs": "https://www.dydx.foundation/blog",
|
||||
"foundation": "https://www.dydx.foundation",
|
||||
"help": "https://help.dydx.exchange/",
|
||||
"initialMarginFractionLearnMore": "https://help.dydx.exchange/articles/5232637-maximum-position-sizes",
|
||||
"reduceOnlyLearnMore": "https://help.dydx.exchange/articles/6345793-reduce-only-orders",
|
||||
"mintscanBase": "https://testnet.mintscan.io/dydx-testnet",
|
||||
"documentation": "https://docs.dydx.exchange/",
|
||||
"community": "https://discord.com/invite/dydx",
|
||||
"governanceLearnMore": "https://help.dydx.exchange",
|
||||
"newMarketProposalLearnMore": "https://dydx.exchange/blog/new-market-proposals",
|
||||
"stakingLearnMore": "https://help.dydx.exchange",
|
||||
"keplrDashboard": "https://testnet.keplr.app/",
|
||||
"strideZoneApp": "https://testnet.stride.zone",
|
||||
"accountExportLearnMore": "https://help.dydx.exchange/en/articles/8565867-secret-phrase-on-dydx-chain",
|
||||
"walletLearnMore": "https://www.dydx.academy/video/defi-wallet"
|
||||
},
|
||||
@@ -255,11 +286,21 @@
|
||||
"images": "/wallets/",
|
||||
"signTypedDataAction": "dYdX Chain Onboarding",
|
||||
"signTypedDataDomainName": "dYdX Chain"
|
||||
},
|
||||
"governance": {
|
||||
"newMarketProposal": {
|
||||
"initialDepositAmount": 10000000,
|
||||
"delayBlocks": 900,
|
||||
"newMarketsMethodology": "https://docs.google.com/spreadsheets/d/1zjkV9R7R_7KMItuzqzvKGwefSBRfE-ZNAx1LH55OcqY/edit?usp=sharing"
|
||||
}
|
||||
},
|
||||
"featureFlags": {
|
||||
"reduceOnlySupported": true
|
||||
}
|
||||
},
|
||||
"dydxprotocol-dev-5": {
|
||||
"name": "v4 Dev 5",
|
||||
"ethereumChainId": "5",
|
||||
"ethereumChainId": "11155111",
|
||||
"dydxChainId": "dydxprotocol-testnet",
|
||||
"chainName": "dYdX Chain",
|
||||
"chainLogo": "/dydx-chain.png",
|
||||
@@ -300,14 +341,15 @@
|
||||
"blogs": "https://www.dydx.foundation/blog",
|
||||
"foundation": "https://www.dydx.foundation",
|
||||
"help": "https://help.dydx.exchange/",
|
||||
"initialMarginFractionLearnMore": "https://help.dydx.exchange/articles/5232637-maximum-position-sizes",
|
||||
"reduceOnlyLearnMore": "https://help.dydx.exchange/articles/6345793-reduce-only-orders",
|
||||
"mintscanBase": "https://testnet.mintscan.io/dydx-testnet",
|
||||
"documentation": "https://docs.dydx.exchange/",
|
||||
"community": "https://discord.com/invite/dydx",
|
||||
"governanceLearnMore": "https://help.dydx.exchange",
|
||||
"newMarketProposalLearnMore": "https://dydx.exchange/blog/new-market-proposals",
|
||||
"stakingLearnMore": "https://help.dydx.exchange",
|
||||
"keplrDashboard": "https://testnet.keplr.app/",
|
||||
"strideZoneApp": "https://testnet.stride.zone",
|
||||
"accountExportLearnMore": "https://help.dydx.exchange/en/articles/8565867-secret-phrase-on-dydx-chain",
|
||||
"walletLearnMore": "https://www.dydx.academy/video/defi-wallet"
|
||||
},
|
||||
@@ -328,11 +370,21 @@
|
||||
"images": "/wallets/",
|
||||
"signTypedDataAction": "dYdX Chain Onboarding",
|
||||
"signTypedDataDomainName": "dYdX Chain"
|
||||
},
|
||||
"governance": {
|
||||
"newMarketProposal": {
|
||||
"initialDepositAmount": 10000000,
|
||||
"delayBlocks": 900,
|
||||
"newMarketsMethodology": "https://docs.google.com/spreadsheets/d/1zjkV9R7R_7KMItuzqzvKGwefSBRfE-ZNAx1LH55OcqY/edit?usp=sharing"
|
||||
}
|
||||
},
|
||||
"featureFlags": {
|
||||
"reduceOnlySupported": true
|
||||
}
|
||||
},
|
||||
"dydxprotocol-staging": {
|
||||
"name": "v4 Staging",
|
||||
"ethereumChainId": "5",
|
||||
"ethereumChainId": "11155111",
|
||||
"dydxChainId": "dydxprotocol-testnet",
|
||||
"chainName": "dYdX Chain",
|
||||
"chainLogo": "/dydx-chain.png",
|
||||
@@ -377,12 +429,13 @@
|
||||
"blogs": "https://www.dydx.foundation/blog",
|
||||
"help": "https://help.dydx.exchange",
|
||||
"foundation": "https://www.dydx.foundation",
|
||||
"initialMarginFractionLearnMore": "https://help.dydx.exchange/articles/5232637-maximum-position-sizes",
|
||||
"reduceOnlyLearnMore": "https://help.dydx.exchange/articles/6345793-reduce-only-orders",
|
||||
"mintscanBase": "https://testnet.mintscan.io/dydx-testnet",
|
||||
"governanceLearnMore": "https://help.dydx.exchange",
|
||||
"newMarketProposalLearnMore": "https://dydx.exchange/blog/new-market-proposals",
|
||||
"stakingLearnMore": "https://help.dydx.exchange",
|
||||
"keplrDashboard": "https://testnet.keplr.app/",
|
||||
"strideZoneApp": "https://testnet.stride.zone",
|
||||
"accountExportLearnMore": "https://help.dydx.exchange/en/articles/8565867-secret-phrase-on-dydx-chain",
|
||||
"walletLearnMore": "https://www.dydx.academy/video/defi-wallet"
|
||||
},
|
||||
@@ -403,11 +456,21 @@
|
||||
"images": "/wallets/",
|
||||
"signTypedDataAction": "dYdX Chain Onboarding",
|
||||
"signTypedDataDomainName": "dYdX Chain"
|
||||
},
|
||||
"governance": {
|
||||
"newMarketProposal": {
|
||||
"initialDepositAmount": 10000000,
|
||||
"delayBlocks": 900,
|
||||
"newMarketsMethodology": "https://docs.google.com/spreadsheets/d/1zjkV9R7R_7KMItuzqzvKGwefSBRfE-ZNAx1LH55OcqY/edit?usp=sharing"
|
||||
}
|
||||
},
|
||||
"featureFlags": {
|
||||
"reduceOnlySupported": true
|
||||
}
|
||||
},
|
||||
"dydxprotocol-staging-forced-update": {
|
||||
"name": "v4 Staging Forced Update",
|
||||
"ethereumChainId": "5",
|
||||
"ethereumChainId": "11155111",
|
||||
"dydxChainId": "dydxprotocol-testnet",
|
||||
"chainName": "dYdX Chain",
|
||||
"chainLogo": "/dydx-chain.png",
|
||||
@@ -450,7 +513,8 @@
|
||||
"documentation": "https://v4-teacher.vercel.app/",
|
||||
"community": "https://discord.com/invite/dydx",
|
||||
"feedback": "https://docs.google.com/forms/d/e/1FAIpQLSezLsWCKvAYDEb7L-2O4wOON1T56xxro9A2Azvl6IxXHP_15Q/viewform",
|
||||
"blogs": "https://www.dydx.foundation/blog"
|
||||
"blogs": "https://www.dydx.foundation/blog",
|
||||
"newMarketProposalLearnMore": "https://dydx.exchange/blog/new-market-proposals"
|
||||
},
|
||||
"wallets": {
|
||||
"walletconnect": {
|
||||
@@ -473,14 +537,24 @@
|
||||
"apps": {
|
||||
"ios": {
|
||||
"minimalVersion": "1.0",
|
||||
"build":40000,
|
||||
"build": 40000,
|
||||
"url": "https://apps.apple.com/app/dydx/id1564787350"
|
||||
}
|
||||
},
|
||||
"governance": {
|
||||
"newMarketProposal": {
|
||||
"initialDepositAmount": 10000000,
|
||||
"delayBlocks": 900,
|
||||
"newMarketsMethodology": "https://docs.google.com/spreadsheets/d/1zjkV9R7R_7KMItuzqzvKGwefSBRfE-ZNAx1LH55OcqY/edit?usp=sharing"
|
||||
}
|
||||
},
|
||||
"featureFlags": {
|
||||
"reduceOnlySupported": true
|
||||
}
|
||||
},
|
||||
"dydxprotocol-staging-west": {
|
||||
"name": "v4 Staging West",
|
||||
"ethereumChainId": "5",
|
||||
"ethereumChainId": "11155111",
|
||||
"dydxChainId": "dydxprotocol-testnet",
|
||||
"chainName": "dYdX Chain",
|
||||
"chainLogo": "/dydx-chain.png",
|
||||
@@ -525,12 +599,13 @@
|
||||
"blogs": "https://www.dydx.foundation/blog",
|
||||
"help": "https://help.dydx.exchange",
|
||||
"foundation": "https://www.dydx.foundation",
|
||||
"initialMarginFractionLearnMore": "https://help.dydx.exchange/articles/5232637-maximum-position-sizes",
|
||||
"reduceOnlyLearnMore": "https://help.dydx.exchange/articles/6345793-reduce-only-orders",
|
||||
"mintscanBase": "https://testnet.mintscan.io/dydx-testnet",
|
||||
"governanceLearnMore": "https://help.dydx.exchange",
|
||||
"newMarketProposalLearnMore": "https://dydx.exchange/blog/new-market-proposals",
|
||||
"stakingLearnMore": "https://help.dydx.exchange",
|
||||
"keplrDashboard": "https://testnet.keplr.app/",
|
||||
"strideZoneApp": "https://testnet.stride.zone",
|
||||
"accountExportLearnMore": "https://help.dydx.exchange/en/articles/8565867-secret-phrase-on-dydx-chain",
|
||||
"walletLearnMore": "https://www.dydx.academy/video/defi-wallet"
|
||||
},
|
||||
@@ -551,11 +626,21 @@
|
||||
"images": "/wallets/",
|
||||
"signTypedDataAction": "dYdX Chain Onboarding",
|
||||
"signTypedDataDomainName": "dYdX Chain"
|
||||
},
|
||||
"governance": {
|
||||
"newMarketProposal": {
|
||||
"initialDepositAmount": 10000000,
|
||||
"delayBlocks": 900,
|
||||
"newMarketsMethodology": "https://docs.google.com/spreadsheets/d/1zjkV9R7R_7KMItuzqzvKGwefSBRfE-ZNAx1LH55OcqY/edit?usp=sharing"
|
||||
}
|
||||
},
|
||||
"featureFlags": {
|
||||
"reduceOnlySupported": true
|
||||
}
|
||||
},
|
||||
"dydxprotocol-testnet": {
|
||||
"name": "v4 Public Testnet",
|
||||
"ethereumChainId": "5",
|
||||
"ethereumChainId": "11155111",
|
||||
"dydxChainId": "dydx-testnet-4",
|
||||
"chainName": "dYdX Chain",
|
||||
"chainLogo": "/dydx-chain.png",
|
||||
@@ -604,12 +689,13 @@
|
||||
"blogs": "https://www.dydx.foundation/blog",
|
||||
"foundation": "https://www.dydx.foundation",
|
||||
"help": "https://help.dydx.exchange/",
|
||||
"initialMarginFractionLearnMore": "https://help.dydx.exchange/articles/5232637-maximum-position-sizes",
|
||||
"reduceOnlyLearnMore": "https://help.dydx.exchange/articles/6345793-reduce-only-orders",
|
||||
"mintscanBase": "https://testnet.mintscan.io/dydx-testnet",
|
||||
"governanceLearnMore": "https://help.dydx.exchange",
|
||||
"newMarketProposalLearnMore": "https://dydx.exchange/blog/new-market-proposals",
|
||||
"stakingLearnMore": "https://help.dydx.exchange",
|
||||
"keplrDashboard": "https://testnet.keplr.app/",
|
||||
"strideZoneApp": "https://testnet.stride.zone",
|
||||
"accountExportLearnMore": "https://help.dydx.exchange/en/articles/8565867-secret-phrase-on-dydx-chain",
|
||||
"walletLearnMore": "https://www.dydx.academy/video/defi-wallet"
|
||||
},
|
||||
@@ -630,11 +716,21 @@
|
||||
"images": "/wallets/",
|
||||
"signTypedDataAction": "dYdX Chain Onboarding",
|
||||
"signTypedDataDomainName": "dYdX V4"
|
||||
},
|
||||
"governance": {
|
||||
"newMarketProposal": {
|
||||
"initialDepositAmount": 10000000,
|
||||
"delayBlocks": 900,
|
||||
"newMarketsMethodology": "https://docs.google.com/spreadsheets/d/1zjkV9R7R_7KMItuzqzvKGwefSBRfE-ZNAx1LH55OcqY/edit?usp=sharing"
|
||||
}
|
||||
},
|
||||
"featureFlags": {
|
||||
"reduceOnlySupported": false
|
||||
}
|
||||
},
|
||||
"dydxprotocol-testnet-dydx": {
|
||||
"name": "v4 Public Testnet/dYdX",
|
||||
"ethereumChainId": "5",
|
||||
"ethereumChainId": "11155111",
|
||||
"dydxChainId": "dydx-testnet-4",
|
||||
"chainName": "dYdX Chain",
|
||||
"chainLogo": "/dydx-chain.png",
|
||||
@@ -680,12 +776,13 @@
|
||||
"blogs": "https://www.dydx.foundation/blog",
|
||||
"foundation": "https://www.dydx.foundation",
|
||||
"help": "https://help.dydx.exchange/",
|
||||
"initialMarginFractionLearnMore": "https://help.dydx.exchange/articles/5232637-maximum-position-sizes",
|
||||
"reduceOnlyLearnMore": "https://help.dydx.exchange/articles/6345793-reduce-only-orders",
|
||||
"mintscanBase": "https://testnet.mintscan.io/dydx-testnet",
|
||||
"governanceLearnMore": "https://help.dydx.exchange",
|
||||
"newMarketProposalLearnMore": "https://dydx.exchange/blog/new-market-proposals",
|
||||
"stakingLearnMore": "https://help.dydx.exchange",
|
||||
"keplrDashboard": "https://testnet.keplr.app/",
|
||||
"strideZoneApp": "https://testnet.stride.zone",
|
||||
"accountExportLearnMore": "https://help.dydx.exchange/en/articles/8565867-secret-phrase-on-dydx-chain",
|
||||
"walletLearnMore": "https://www.dydx.academy/video/defi-wallet"
|
||||
},
|
||||
@@ -706,11 +803,21 @@
|
||||
"images": "/wallets/",
|
||||
"signTypedDataAction": "dYdX Chain Onboarding",
|
||||
"signTypedDataDomainName": "dYdX V4"
|
||||
},
|
||||
"governance": {
|
||||
"newMarketProposal": {
|
||||
"initialDepositAmount": 10000000,
|
||||
"delayBlocks": 900,
|
||||
"newMarketsMethodology": "https://docs.google.com/spreadsheets/d/1zjkV9R7R_7KMItuzqzvKGwefSBRfE-ZNAx1LH55OcqY/edit?usp=sharing"
|
||||
}
|
||||
},
|
||||
"featureFlags": {
|
||||
"reduceOnlySupported": false
|
||||
}
|
||||
},
|
||||
"dydxprotocol-testnet-nodefleet": {
|
||||
"name": "v4 Public Testnet/nodefleet",
|
||||
"ethereumChainId": "5",
|
||||
"ethereumChainId": "11155111",
|
||||
"dydxChainId": "dydx-testnet-4",
|
||||
"chainName": "dYdX Chain",
|
||||
"chainLogo": "/dydx-chain.png",
|
||||
@@ -756,12 +863,13 @@
|
||||
"blogs": "https://www.dydx.foundation/blog",
|
||||
"foundation": "https://www.dydx.foundation",
|
||||
"help": "https://help.dydx.exchange/",
|
||||
"initialMarginFractionLearnMore": "https://help.dydx.exchange/articles/5232637-maximum-position-sizes",
|
||||
"reduceOnlyLearnMore": "https://help.dydx.exchange/articles/6345793-reduce-only-orders",
|
||||
"mintscanBase": "https://testnet.mintscan.io/dydx-testnet",
|
||||
"governanceLearnMore": "https://help.dydx.exchange",
|
||||
"newMarketProposalLearnMore": "https://dydx.exchange/blog/new-market-proposals",
|
||||
"stakingLearnMore": "https://help.dydx.exchange",
|
||||
"keplrDashboard": "https://testnet.keplr.app/",
|
||||
"strideZoneApp": "https://testnet.stride.zone",
|
||||
"accountExportLearnMore": "https://help.dydx.exchange/en/articles/8565867-secret-phrase-on-dydx-chain",
|
||||
"walletLearnMore": "https://www.dydx.academy/video/defi-wallet"
|
||||
},
|
||||
@@ -782,11 +890,21 @@
|
||||
"images": "/wallets/",
|
||||
"signTypedDataAction": "dYdX Chain Onboarding",
|
||||
"signTypedDataDomainName": "dYdX V4"
|
||||
},
|
||||
"governance": {
|
||||
"newMarketProposal": {
|
||||
"initialDepositAmount": 10000000,
|
||||
"delayBlocks": 900,
|
||||
"newMarketsMethodology": "https://docs.google.com/spreadsheets/d/1zjkV9R7R_7KMItuzqzvKGwefSBRfE-ZNAx1LH55OcqY/edit?usp=sharing"
|
||||
}
|
||||
},
|
||||
"featureFlags": {
|
||||
"reduceOnlySupported": false
|
||||
}
|
||||
},
|
||||
"dydxprotocol-testnet-kingnodes": {
|
||||
"name": "v4 Public Testnet/KingNodes",
|
||||
"ethereumChainId": "5",
|
||||
"ethereumChainId": "11155111",
|
||||
"dydxChainId": "dydx-testnet-4",
|
||||
"chainName": "dYdX Chain",
|
||||
"chainLogo": "/dydx-chain.png",
|
||||
@@ -832,12 +950,13 @@
|
||||
"blogs": "https://www.dydx.foundation/blog",
|
||||
"foundation": "https://www.dydx.foundation",
|
||||
"help": "https://help.dydx.exchange/",
|
||||
"initialMarginFractionLearnMore": "https://help.dydx.exchange/articles/5232637-maximum-position-sizes",
|
||||
"reduceOnlyLearnMore": "https://help.dydx.exchange/articles/6345793-reduce-only-orders",
|
||||
"mintscanBase": "https://testnet.mintscan.io/dydx-testnet",
|
||||
"governanceLearnMore": "https://help.dydx.exchange",
|
||||
"newMarketProposalLearnMore": "https://dydx.exchange/blog/new-market-proposals",
|
||||
"stakingLearnMore": "https://help.dydx.exchange",
|
||||
"keplrDashboard": "https://testnet.keplr.app/",
|
||||
"strideZoneApp": "https://testnet.stride.zone",
|
||||
"accountExportLearnMore": "https://help.dydx.exchange/en/articles/8565867-secret-phrase-on-dydx-chain",
|
||||
"walletLearnMore": "https://www.dydx.academy/video/defi-wallet"
|
||||
},
|
||||
@@ -858,11 +977,21 @@
|
||||
"images": "/wallets/",
|
||||
"signTypedDataAction": "dYdX Chain Onboarding",
|
||||
"signTypedDataDomainName": "dYdX V4"
|
||||
},
|
||||
"governance": {
|
||||
"newMarketProposal": {
|
||||
"initialDepositAmount": 10000000,
|
||||
"delayBlocks": 900,
|
||||
"newMarketsMethodology": "https://docs.google.com/spreadsheets/d/1zjkV9R7R_7KMItuzqzvKGwefSBRfE-ZNAx1LH55OcqY/edit?usp=sharing"
|
||||
}
|
||||
},
|
||||
"featureFlags": {
|
||||
"reduceOnlySupported": false
|
||||
}
|
||||
},
|
||||
"dydxprotocol-testnet-liquify": {
|
||||
"name": "v4 Public Testnet/Liquify",
|
||||
"ethereumChainId": "5",
|
||||
"ethereumChainId": "11155111",
|
||||
"dydxChainId": "dydx-testnet-4",
|
||||
"chainName": "dYdX Chain",
|
||||
"chainLogo": "/dydx-chain.png",
|
||||
@@ -908,12 +1037,13 @@
|
||||
"blogs": "https://www.dydx.foundation/blog",
|
||||
"foundation": "https://www.dydx.foundation",
|
||||
"help": "https://help.dydx.exchange/",
|
||||
"initialMarginFractionLearnMore": "https://help.dydx.exchange/articles/5232637-maximum-position-sizes",
|
||||
"reduceOnlyLearnMore": "https://help.dydx.exchange/articles/6345793-reduce-only-orders",
|
||||
"mintscanBase": "https://testnet.mintscan.io/dydx-testnet",
|
||||
"governanceLearnMore": "https://help.dydx.exchange",
|
||||
"newMarketProposalLearnMore": "https://dydx.exchange/blog/new-market-proposals",
|
||||
"stakingLearnMore": "https://help.dydx.exchange",
|
||||
"keplrDashboard": "https://testnet.keplr.app/",
|
||||
"strideZoneApp": "https://testnet.stride.zone",
|
||||
"accountExportLearnMore": "https://help.dydx.exchange/en/articles/8565867-secret-phrase-on-dydx-chain",
|
||||
"walletLearnMore": "https://www.dydx.academy/video/defi-wallet"
|
||||
},
|
||||
@@ -934,11 +1064,21 @@
|
||||
"images": "/wallets/",
|
||||
"signTypedDataAction": "dYdX Chain Onboarding",
|
||||
"signTypedDataDomainName": "dYdX V4"
|
||||
},
|
||||
"governance": {
|
||||
"newMarketProposal": {
|
||||
"initialDepositAmount": 10000000,
|
||||
"delayBlocks": 900,
|
||||
"newMarketsMethodology": "https://docs.google.com/spreadsheets/d/1zjkV9R7R_7KMItuzqzvKGwefSBRfE-ZNAx1LH55OcqY/edit?usp=sharing"
|
||||
}
|
||||
},
|
||||
"featureFlags": {
|
||||
"reduceOnlySupported": false
|
||||
}
|
||||
},
|
||||
"dydxprotocol-testnet-polkachu": {
|
||||
"name": "v4 Public Testnet/Polkahcu",
|
||||
"ethereumChainId": "5",
|
||||
"ethereumChainId": "11155111",
|
||||
"dydxChainId": "dydx-testnet-4",
|
||||
"chainName": "dYdX Chain",
|
||||
"chainLogo": "/dydx-chain.png",
|
||||
@@ -982,7 +1122,8 @@
|
||||
"documentation": "https://docs.dydx.exchange/",
|
||||
"community": "https://discord.com/invite/dydx",
|
||||
"feedback": "https://docs.google.com/forms/d/e/1FAIpQLSezLsWCKvAYDEb7L-2O4wOON1T56xxro9A2Azvl6IxXHP_15Q/viewform",
|
||||
"blogs": "https://www.dydx.foundation/blog"
|
||||
"blogs": "https://www.dydx.foundation/blog",
|
||||
"newMarketProposalLearnMore": "https://dydx.exchange/blog/new-market-proposals"
|
||||
},
|
||||
"wallets": {
|
||||
"walletconnect": {
|
||||
@@ -1001,11 +1142,21 @@
|
||||
"images": "/wallets/",
|
||||
"signTypedDataAction": "dYdX Chain Onboarding",
|
||||
"signTypedDataDomainName": "dYdX V4"
|
||||
},
|
||||
"governance": {
|
||||
"newMarketProposal": {
|
||||
"initialDepositAmount": 10000000,
|
||||
"delayBlocks": 900,
|
||||
"newMarketsMethodology": "https://docs.google.com/spreadsheets/d/1zjkV9R7R_7KMItuzqzvKGwefSBRfE-ZNAx1LH55OcqY/edit?usp=sharing"
|
||||
}
|
||||
},
|
||||
"featureFlags": {
|
||||
"reduceOnlySupported": false
|
||||
}
|
||||
},
|
||||
"dydxprotocol-testnet-bware": {
|
||||
"name": "v4 Public Testnet/BWare",
|
||||
"ethereumChainId": "5",
|
||||
"ethereumChainId": "11155111",
|
||||
"dydxChainId": "dydx-testnet-4",
|
||||
"chainName": "dYdX Chain",
|
||||
"chainLogo": "/dydx-chain.png",
|
||||
@@ -1051,12 +1202,13 @@
|
||||
"blogs": "https://www.dydx.foundation/blog",
|
||||
"foundation": "https://www.dydx.foundation",
|
||||
"help": "https://help.dydx.exchange/",
|
||||
"initialMarginFractionLearnmore": "https://help.dydx.exchange/articles/5232637-maximum-position-sizes",
|
||||
"reduceOnlyLearnmore": "https://help.dydx.exchange/articles/6345793-reduce-only-orders",
|
||||
"mintscanBase": "https://testnet.mintscan.io/dydx-testnet",
|
||||
"governanceLearnmore": "https://help.dydx.exchange",
|
||||
"newMarketProposalLearnMore": "https://dydx.exchange/blog/new-market-proposals",
|
||||
"stakingLearnmore": "https://help.dydx.exchange",
|
||||
"keplrDashboard": "https://testnet.keplr.app/",
|
||||
"strideZoneApp": "https://testnet.stride.zone",
|
||||
"accountExportLearnmore": "https://help.dydx.exchange",
|
||||
"walletLearnmore": "https://www.dydx.academy/video/defi-wallet"
|
||||
},
|
||||
@@ -1077,6 +1229,16 @@
|
||||
"images": "/wallets/",
|
||||
"signTypedDataAction": "dYdX Chain Onboarding",
|
||||
"signTypedDataDomainName": "dYdX V4"
|
||||
},
|
||||
"governance": {
|
||||
"newMarketProposal": {
|
||||
"initialDepositAmount": 10000000,
|
||||
"delayBlocks": 900,
|
||||
"newMarketsMethodology": "https://docs.google.com/spreadsheets/d/1zjkV9R7R_7KMItuzqzvKGwefSBRfE-ZNAx1LH55OcqY/edit?usp=sharing"
|
||||
}
|
||||
},
|
||||
"featureFlags": {
|
||||
"reduceOnlySupported": false
|
||||
}
|
||||
},
|
||||
"dydxprotocol-mainnet": {
|
||||
@@ -1125,14 +1287,15 @@
|
||||
"feedback": "[HTTP link to feedback form, can be null]",
|
||||
"blogs": "[HTTP link to blogs, can be null]",
|
||||
"foundation": "[HTTP link to foundation, can be null]",
|
||||
"initialMarginFractionLearnMore": "[HTTP link to initial margin fraction learn more, can be null]",
|
||||
"reduceOnlyLearnMore": "[HTTP link to reduce-only learn more, can be null]",
|
||||
"documentation": "[HTTP link to documentation, can be null]",
|
||||
"community": "[HTTP link to community, can be null]",
|
||||
"help": "[HTTP link to help page, can be null]",
|
||||
"governanceLearnMore": "[HTTP link to governance learn more, can be null]",
|
||||
"newMarketProposalLearnMore": "[HTTP link to new market proposal learn more, can be null]",
|
||||
"stakingLearnMore": "[HTTP link to staking learn more, can be null]",
|
||||
"keplrDashboard": "[HTTP link to keplr dashboard, can be null]",
|
||||
"strideZoneApp": "[HTTP link to stride zone app, can be null]",
|
||||
"accountExportLearnMore": "[HTTP link to account export learn more, can be null]",
|
||||
"walletLearnMore": "[HTTP link to wallet learn more, can be null]"
|
||||
},
|
||||
@@ -1153,6 +1316,16 @@
|
||||
"images": "[Relative URL for wallet images]",
|
||||
"signTypedDataAction": "dYdX Chain Onboarding",
|
||||
"signTypedDataDomainName": "dYdX Chain"
|
||||
},
|
||||
"governance": {
|
||||
"newMarketProposal": {
|
||||
"initialDepositAmount": 0,
|
||||
"delayBlocks": 0,
|
||||
"newMarketsMethodology": "[URL to spreadsheet or document that explains methodology]"
|
||||
}
|
||||
},
|
||||
"featureFlags": {
|
||||
"reduceOnlySupported": false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
[
|
||||
{
|
||||
"name": "coinbase",
|
||||
"label": "Coinbase",
|
||||
"icon": "/exchanges/coinbase.png",
|
||||
"depositType": "noble"
|
||||
}
|
||||
]
|
||||
@@ -69,6 +69,13 @@
|
||||
"whitepaperLink": "https://bitcoincash.org/",
|
||||
"coinMarketCapsLink": "https://coinmarketcap.com/currencies/bitcoin-cash/"
|
||||
},
|
||||
"BONK-USD": {
|
||||
"name": "BONK COIN",
|
||||
"tags": [],
|
||||
"websiteLink": "https://bonkcoin.com/",
|
||||
"whitepaperLink": "https://bonkcoin.com/",
|
||||
"coinMarketCapsLink": "https://coinmarketcap.com/currencies/bonk1/"
|
||||
},
|
||||
"BLUR-USD": {
|
||||
"name": "Blur",
|
||||
"tags": [],
|
||||
@@ -76,6 +83,14 @@
|
||||
"whitepaperLink": "https://docs.blur.foundation/",
|
||||
"coinMarketCapsLink": "https://coinmarketcap.com/currencies/blur-token/"
|
||||
},
|
||||
"BNB-USD":{
|
||||
"name": "BNB",
|
||||
"tags": ["Layer 1"],
|
||||
"websiteLink": "https://www.bnbchain.org/en",
|
||||
"whitepaperLink": "https://www.exodus.com/assets/docs/binance-coin-whitepaper.pdf",
|
||||
"coinMarketCapsLink": "https://coinmarketcap.com/currencies/bnb/"
|
||||
|
||||
},
|
||||
"CELO-USD": {
|
||||
"name": "Celo",
|
||||
"tags": [],
|
||||
@@ -118,6 +133,13 @@
|
||||
"whitepaperLink": "https://polkadot.network/PolkaDotPaper.pdf",
|
||||
"coinMarketCapsLink": "https://coinmarketcap.com/currencies/polkadot-new/"
|
||||
},
|
||||
"DYM-USD": {
|
||||
"name": "Dymension",
|
||||
"tags": [],
|
||||
"websiteLink": "https://dymension.xyz/",
|
||||
"whitepaperLink": "https://docs.dymension.xyz/dymension-litepaper/dymension-litepaper-index",
|
||||
"coinMarketCapsLink": "https://coinmarketcap.com/currencies/dymension/"
|
||||
},
|
||||
"ENJ-USD": {
|
||||
"name": "Enjin",
|
||||
"tags": [],
|
||||
@@ -169,6 +191,13 @@
|
||||
"whitepaperLink": "https://dfinity.org/whitepaper.pdf",
|
||||
"coinMarketCapsLink": "https://coinmarketcap.com/currencies/internet-computer/"
|
||||
},
|
||||
"JUP-USD": {
|
||||
"name": "Jupiter",
|
||||
"tags": ["Defi"],
|
||||
"websiteLink": "https://station.jup.ag/",
|
||||
"whitepaperLink": "https://station.jup.ag/blog/green-paper",
|
||||
"coinMarketCapsLink": "https://coinmarketcap.com/currencies/jupiter-ag/"
|
||||
},
|
||||
"LDO-USD": {
|
||||
"name": "Lido DAO",
|
||||
"tags": ["Defi"],
|
||||
@@ -350,6 +379,13 @@
|
||||
"whitepaperLink": "https://z.cash/technology/",
|
||||
"coinMarketCapsLink": "https://coinmarketcap.com/currencies/zcash/"
|
||||
},
|
||||
"ZETA-USD": {
|
||||
"name": "ZetaChain",
|
||||
"tags": ["Layer 1"],
|
||||
"websiteLink": "https://www.zetachain.com/",
|
||||
"whitepaperLink": "https://www.zetachain.com/whitepaper.pdf",
|
||||
"coinMarketCapsLink": "https://coinmarketcap.com/currencies/zetachain/"
|
||||
},
|
||||
"ZRX-USD": {
|
||||
"name": "0x",
|
||||
"tags": ["Defi"],
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
This file identifies parameters for the optimal performance of various assets with the dYdX v4 open source software ("dYdX Chain"). For information on which assets are likely to be best compatible with dYdX Chain and how likely software compatibility and optimal parameters are assessed, please review the documentation [here](https://docs.dydx.trade/governance/proposing_a_new_market#example-proposal-json). Users considering using the permissionless markets function of the dYdX Chain are encouraged to consult qualified legal counsel to ensure compliance with the laws of their jurisdiction. The information herein does not constitute and should not be relied on as an endorsement or recommendation for any specific market, or investment, legal, or any other form of professional advice. Use of the v4 software is prohibited in the United States, Canada, and sanctioned jurisdictions as described in the [v4 Terms of Use](https://dydx.exchange/v4-terms).
|
||||
@@ -0,0 +1,608 @@
|
||||
{
|
||||
"1INCH": [
|
||||
{ "exchangeName": "Binance", "ticker": "1INCHUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "CoinbasePro", "ticker": "1INCH-USD" },
|
||||
{ "exchangeName": "Gate", "ticker": "1INCH_USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Kucoin", "ticker": "1INCH-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Okx", "ticker": "1INCH-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Mexc", "ticker": "1INCH_USDT", "adjustByMarket": "USDT-USD" }
|
||||
],
|
||||
"AAVE": [
|
||||
{ "exchangeName": "Binance", "ticker": "AAVEUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "CoinbasePro", "ticker": "AAVE-USD" },
|
||||
{ "exchangeName": "Huobi", "ticker": "aaveusdt", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Kraken", "ticker": "AAVEUSD" },
|
||||
{ "exchangeName": "Kucoin", "ticker": "AAVE-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Okx", "ticker": "AAVE-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Mexc", "ticker": "AAVE_USDT", "adjustByMarket": "USDT-USD" }
|
||||
],
|
||||
"ADA": [
|
||||
{ "exchangeName": "Binance", "ticker": "ADAUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Bitstamp", "ticker": "ADA/USD" },
|
||||
{ "exchangeName": "Bybit", "ticker": "ADAUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "CoinbasePro", "ticker": "ADA-USD" },
|
||||
{ "exchangeName": "Huobi", "ticker": "adausdt", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Kraken", "ticker": "ADAUSD" },
|
||||
{ "exchangeName": "Kucoin", "ticker": "ADA-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Okx", "ticker": "ADA-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Mexc", "ticker": "ADA_USDT", "adjustByMarket": "USDT-USD" }
|
||||
],
|
||||
"AGIX": [
|
||||
{ "exchangeName": "Binance", "ticker": "AGIXUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Bybit", "ticker": "AGIXUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Gate", "ticker": "AGIX_USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Kucoin", "ticker": "AGIX-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Okx", "ticker": "AGIX-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Mexc", "ticker": "AGIX_USDT", "adjustByMarket": "USDT-USD" }
|
||||
],
|
||||
"ALGO": [
|
||||
{ "exchangeName": "Binance", "ticker": "ALGOUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "CoinbasePro", "ticker": "ALGO-USD" },
|
||||
{ "exchangeName": "Kraken", "ticker": "ALGOUSD" },
|
||||
{ "exchangeName": "Kucoin", "ticker": "ALGO-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Okx", "ticker": "ALGO-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Mexc", "ticker": "ALGO_USDT", "adjustByMarket": "USDT-USD" }
|
||||
],
|
||||
"APE": [
|
||||
{ "exchangeName": "Binance", "ticker": "APEUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "CoinbasePro", "ticker": "APE-USD" },
|
||||
{ "exchangeName": "Gate", "ticker": "APE_USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Kraken", "ticker": "APEUSD" },
|
||||
{ "exchangeName": "Kucoin", "ticker": "APE-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Okx", "ticker": "APE-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Mexc", "ticker": "APE_USDT", "adjustByMarket": "USDT-USD" }
|
||||
],
|
||||
"APT": [
|
||||
{ "exchangeName": "Binance", "ticker": "APTUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Bybit", "ticker": "APTUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "CoinbasePro", "ticker": "APT-USD" },
|
||||
{ "exchangeName": "Gate", "ticker": "APT_USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Huobi", "ticker": "aptusdt", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Kraken", "ticker": "APTUSD" },
|
||||
{ "exchangeName": "Kucoin", "ticker": "APT-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Okx", "ticker": "APT-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Mexc", "ticker": "APT_USDT", "adjustByMarket": "USDT-USD" }
|
||||
],
|
||||
"ARB": [
|
||||
{ "exchangeName": "Binance", "ticker": "ARBUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Bybit", "ticker": "ARBUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "CoinbasePro", "ticker": "ARB-USD" },
|
||||
{ "exchangeName": "Huobi", "ticker": "arbusdt", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Kraken", "ticker": "ARBUSD" },
|
||||
{ "exchangeName": "Kucoin", "ticker": "ARB-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Okx", "ticker": "ARB-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Mexc", "ticker": "ARB_USDT", "adjustByMarket": "USDT-USD" }
|
||||
],
|
||||
"ATOM": [
|
||||
{ "exchangeName": "Binance", "ticker": "ATOMUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Bybit", "ticker": "ATOMUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "CoinbasePro", "ticker": "ATOM-USD" },
|
||||
{ "exchangeName": "Gate", "ticker": "ATOM_USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Kraken", "ticker": "ATOMUSD" },
|
||||
{ "exchangeName": "Kucoin", "ticker": "ATOM-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Okx", "ticker": "ATOM-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Mexc", "ticker": "ATOM_USDT", "adjustByMarket": "USDT-USD" }
|
||||
],
|
||||
"AVAX": [
|
||||
{ "exchangeName": "Binance", "ticker": "AVAXUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Bitstamp", "ticker": "AVAX/USD" },
|
||||
{ "exchangeName": "Bybit", "ticker": "AVAXUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "CoinbasePro", "ticker": "AVAX-USD" },
|
||||
{ "exchangeName": "Huobi", "ticker": "avaxusdt", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Kraken", "ticker": "AVAXUSD" },
|
||||
{ "exchangeName": "Kucoin", "ticker": "AVAX-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Okx", "ticker": "AVAX-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Mexc", "ticker": "AVAX_USDT", "adjustByMarket": "USDT-USD" }
|
||||
],
|
||||
"BCH": [
|
||||
{ "exchangeName": "Binance", "ticker": "BCHUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Bitstamp", "ticker": "BCH/USD" },
|
||||
{ "exchangeName": "Bybit", "ticker": "BCHUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "CoinbasePro", "ticker": "BCH-USD" },
|
||||
{ "exchangeName": "Huobi", "ticker": "bchusdt", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Kraken", "ticker": "BCHUSD" },
|
||||
{ "exchangeName": "Kucoin", "ticker": "BCH-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Okx", "ticker": "BCH-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Mexc", "ticker": "BCH_USDT", "adjustByMarket": "USDT-USD" }
|
||||
],
|
||||
"BLUR": [
|
||||
{ "exchangeName": "Binance", "ticker": "BLURUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Bybit", "ticker": "BLURUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "CoinbasePro", "ticker": "BLUR-USD" },
|
||||
{ "exchangeName": "Kraken", "ticker": "BLURUSD" },
|
||||
{ "exchangeName": "Kucoin", "ticker": "BLUR-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Okx", "ticker": "BLUR-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Mexc", "ticker": "BLUR_USDT", "adjustByMarket": "USDT-USD" }
|
||||
],
|
||||
"BNB": [
|
||||
{ "exchangeName": "Binance", "ticker": "BNBUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Bybit", "ticker": "BNBUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Gate", "ticker": "BNB_USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Kucoin", "ticker": "BNB-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Okx", "ticker": "BNB-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Mexc", "ticker": "BNB_USDT", "adjustByMarket": "USDT-USD" }
|
||||
],
|
||||
"BONK": [
|
||||
{ "exchangeName": "Binance", "ticker": "BONKUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Bybit", "ticker": "BONKUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "CoinbasePro", "ticker": "BONK-USD" },
|
||||
{ "exchangeName": "Kucoin", "ticker": "BONK-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Okx", "ticker": "BONK-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Mexc", "ticker": "BONK_USDT", "adjustByMarket": "USDT-USD" }
|
||||
],
|
||||
"BTC": [
|
||||
{ "exchangeName": "Binance", "ticker": "BTCUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Bitstamp", "ticker": "BTC/USD" },
|
||||
{ "exchangeName": "Bybit", "ticker": "BTCUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "CoinbasePro", "ticker": "BTC-USD" },
|
||||
{ "exchangeName": "Huobi", "ticker": "btcusdt", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Kraken", "ticker": "BTCUSD" },
|
||||
{ "exchangeName": "Kucoin", "ticker": "BTC-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Okx", "ticker": "BTC-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Mexc", "ticker": "BTC_USDT", "adjustByMarket": "USDT-USD" }
|
||||
],
|
||||
"CHZ": [
|
||||
{ "exchangeName": "Binance", "ticker": "CHZUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "CoinbasePro", "ticker": "CHZ-USD" },
|
||||
{ "exchangeName": "Kraken", "ticker": "CHZUSD" },
|
||||
{ "exchangeName": "Kucoin", "ticker": "CHZ-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Okx", "ticker": "CHZ-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Mexc", "ticker": "CHZ_USDT", "adjustByMarket": "USDT-USD" }
|
||||
],
|
||||
"CRV": [
|
||||
{ "exchangeName": "Binance", "ticker": "CRVUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "CoinbasePro", "ticker": "CRV-USD" },
|
||||
{ "exchangeName": "Kraken", "ticker": "CRVUSD" },
|
||||
{ "exchangeName": "Kucoin", "ticker": "CRV-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Okx", "ticker": "CRV-USDT", "adjustByMarket": "USDT-USD" }
|
||||
],
|
||||
"DOGE": [
|
||||
{ "exchangeName": "Binance", "ticker": "DOGEUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Bybit", "ticker": "DOGEUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "CoinbasePro", "ticker": "DOGE-USD" },
|
||||
{ "exchangeName": "Huobi", "ticker": "dogeusdt", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Kraken", "ticker": "DOGEUSD" },
|
||||
{ "exchangeName": "Kucoin", "ticker": "DOGE-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Okx", "ticker": "DOGE-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Mexc", "ticker": "DOGE_USDT", "adjustByMarket": "USDT-USD" }
|
||||
],
|
||||
"DOT": [
|
||||
{ "exchangeName": "Binance", "ticker": "DOTUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Bybit", "ticker": "DOTUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "CoinbasePro", "ticker": "DOT-USD" },
|
||||
{ "exchangeName": "Huobi", "ticker": "dotusdt", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Kraken", "ticker": "DOTUSD" },
|
||||
{ "exchangeName": "Kucoin", "ticker": "DOT-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Okx", "ticker": "DOT-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Mexc", "ticker": "DOT_USDT", "adjustByMarket": "USDT-USD" }
|
||||
],
|
||||
"DYM": [
|
||||
{ "exchangeName": "Binance", "ticker": "DYMUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Bybit", "ticker": "DYMUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Gate", "ticker": "DYM_USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Kucoin", "ticker": "DYM-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Mexc", "ticker": "DYM_USDT", "adjustByMarket": "USDT-USD" }
|
||||
],
|
||||
"ENS": [
|
||||
{ "exchangeName": "Binance", "ticker": "ENSUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "CoinbasePro", "ticker": "ENS-USD" },
|
||||
{ "exchangeName": "Gate", "ticker": "ENS_USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Kucoin", "ticker": "ENS-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Okx", "ticker": "ENS-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Mexc", "ticker": "ENS_USDT", "adjustByMarket": "USDT-USD" }
|
||||
],
|
||||
"EOS": [
|
||||
{ "exchangeName": "Binance", "ticker": "EOSUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Bybit", "ticker": "EOSUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "CoinbasePro", "ticker": "EOS-USD" },
|
||||
{ "exchangeName": "Gate", "ticker": "EOS_USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Kraken", "ticker": "EOSUSD" },
|
||||
{ "exchangeName": "Kucoin", "ticker": "EOS-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Okx", "ticker": "EOS-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Mexc", "ticker": "EOS_USDT", "adjustByMarket": "USDT-USD" }
|
||||
],
|
||||
"ETC": [
|
||||
{ "exchangeName": "Binance", "ticker": "ETCUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Bybit", "ticker": "ETCUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "CoinbasePro", "ticker": "ETC-USD" },
|
||||
{ "exchangeName": "Huobi", "ticker": "etcusdt", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Kraken", "ticker": "ETCUSD" },
|
||||
{ "exchangeName": "Kucoin", "ticker": "ETC-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Okx", "ticker": "ETC-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Mexc", "ticker": "ETC_USDT", "adjustByMarket": "USDT-USD" }
|
||||
],
|
||||
"ETH": [
|
||||
{ "exchangeName": "Binance", "ticker": "ETHUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Bitstamp", "ticker": "ETH/USD" },
|
||||
{ "exchangeName": "Bybit", "ticker": "ETHUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "CoinbasePro", "ticker": "ETH-USD" },
|
||||
{ "exchangeName": "Huobi", "ticker": "ethusdt", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Kraken", "ticker": "ETHUSD" },
|
||||
{ "exchangeName": "Kucoin", "ticker": "ETH-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Okx", "ticker": "ETH-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Mexc", "ticker": "ETH_USDT", "adjustByMarket": "USDT-USD" }
|
||||
],
|
||||
"FET": [
|
||||
{ "exchangeName": "Binance", "ticker": "FETUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "CoinbasePro", "ticker": "FET-USD" },
|
||||
{ "exchangeName": "Kraken", "ticker": "FETUSD" },
|
||||
{ "exchangeName": "Kucoin", "ticker": "FET-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Okx", "ticker": "FET-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Mexc", "ticker": "FET_USDT", "adjustByMarket": "USDT-USD" }
|
||||
],
|
||||
"FIL": [
|
||||
{ "exchangeName": "Binance", "ticker": "FILUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Bybit", "ticker": "FILUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "CoinbasePro", "ticker": "FIL-USD" },
|
||||
{ "exchangeName": "Huobi", "ticker": "filusdt", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Kraken", "ticker": "FILUSD" },
|
||||
{ "exchangeName": "Kucoin", "ticker": "FIL-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Okx", "ticker": "FIL-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Mexc", "ticker": "FIL_USDT", "adjustByMarket": "USDT-USD" }
|
||||
],
|
||||
"FTM": [
|
||||
{ "exchangeName": "Binance", "ticker": "FTMUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Bybit", "ticker": "FTMUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Kraken", "ticker": "FTMUSD" },
|
||||
{ "exchangeName": "Kucoin", "ticker": "FTM-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Okx", "ticker": "FTM-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Mexc", "ticker": "FTM_USDT", "adjustByMarket": "USDT-USD" }
|
||||
],
|
||||
"GALA": [
|
||||
{ "exchangeName": "Binance", "ticker": "GALAUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Bybit", "ticker": "GALAUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Gate", "ticker": "GALA_USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Kraken", "ticker": "GALAUSD" },
|
||||
{ "exchangeName": "Okx", "ticker": "GALA-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Mexc", "ticker": "GALA_USDT", "adjustByMarket": "USDT-USD" }
|
||||
],
|
||||
"GMT": [
|
||||
{ "exchangeName": "Binance", "ticker": "GMTUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Bybit", "ticker": "GMTUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "CoinbasePro", "ticker": "GMT-USD" },
|
||||
{ "exchangeName": "Gate", "ticker": "GMT_USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Kucoin", "ticker": "GMT-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Okx", "ticker": "GMT-USDT", "adjustByMarket": "USDT-USD" }
|
||||
],
|
||||
"GRT": [
|
||||
{ "exchangeName": "Binance", "ticker": "GRTUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "CoinbasePro", "ticker": "GRT-USD" },
|
||||
{ "exchangeName": "Gate", "ticker": "GRT_USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Kraken", "ticker": "GRTUSD" },
|
||||
{ "exchangeName": "Kucoin", "ticker": "GRT-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Okx", "ticker": "GRT-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Mexc", "ticker": "GRT_USDT", "adjustByMarket": "USDT-USD" }
|
||||
],
|
||||
"HBAR": [
|
||||
{ "exchangeName": "Binance", "ticker": "HBARUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Bybit", "ticker": "HBARUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "CoinbasePro", "ticker": "HBAR-USD" },
|
||||
{ "exchangeName": "Kucoin", "ticker": "HBAR-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Okx", "ticker": "HBAR-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Mexc", "ticker": "HBAR_USDT", "adjustByMarket": "USDT-USD" }
|
||||
],
|
||||
"ICP": [
|
||||
{ "exchangeName": "Binance", "ticker": "ICPUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Bybit", "ticker": "ICPUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "CoinbasePro", "ticker": "ICP-USD" },
|
||||
{ "exchangeName": "Kraken", "ticker": "ICPUSD" },
|
||||
{ "exchangeName": "Kucoin", "ticker": "ICP-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Okx", "ticker": "ICP-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Mexc", "ticker": "ICP_USDT", "adjustByMarket": "USDT-USD" }
|
||||
],
|
||||
"IMX": [
|
||||
{ "exchangeName": "Binance", "ticker": "IMXUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "CoinbasePro", "ticker": "IMX-USD" },
|
||||
{ "exchangeName": "Kraken", "ticker": "IMXUSD" },
|
||||
{ "exchangeName": "Kucoin", "ticker": "IMX-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Okx", "ticker": "IMX-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Mexc", "ticker": "IMX_USDT", "adjustByMarket": "USDT-USD" }
|
||||
],
|
||||
"INJ": [
|
||||
{ "exchangeName": "Binance", "ticker": "INJUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Bybit", "ticker": "INJUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "CoinbasePro", "ticker": "INJ-USD" },
|
||||
{ "exchangeName": "Kraken", "ticker": "INJUSD" },
|
||||
{ "exchangeName": "Kucoin", "ticker": "INJ-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Okx", "ticker": "INJ-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Mexc", "ticker": "INJ_USDT", "adjustByMarket": "USDT-USD" }
|
||||
],
|
||||
"JTO": [
|
||||
{ "exchangeName": "Binance", "ticker": "JTOUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Bybit", "ticker": "JTOUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "CoinbasePro", "ticker": "JTO-USD" },
|
||||
{ "exchangeName": "Kucoin", "ticker": "JTO-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Okx", "ticker": "JTO-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Mexc", "ticker": "JTO_USDT", "adjustByMarket": "USDT-USD" }
|
||||
],
|
||||
"JUP": [
|
||||
{ "exchangeName": "Binance", "ticker": "JUPUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Bybit", "ticker": "JUPUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Gate", "ticker": "JUP_USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Okx", "ticker": "JUP-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Mexc", "ticker": "JUP_USDT", "adjustByMarket": "USDT-USD" }
|
||||
],
|
||||
"KAVA": [
|
||||
{ "exchangeName": "Binance", "ticker": "KAVAUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Bybit", "ticker": "KAVAUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "CoinbasePro", "ticker": "KAVA-USD" },
|
||||
{ "exchangeName": "Gate", "ticker": "KAVA_USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Kraken", "ticker": "KAVAUSD" },
|
||||
{ "exchangeName": "Kucoin", "ticker": "KAVA-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Mexc", "ticker": "KAVA_USDT", "adjustByMarket": "USDT-USD" }
|
||||
],
|
||||
"LDO": [
|
||||
{ "exchangeName": "Binance", "ticker": "LDOUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Bybit", "ticker": "LDOUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "CoinbasePro", "ticker": "LDO-USD" },
|
||||
{ "exchangeName": "Kraken", "ticker": "LDOUSD" },
|
||||
{ "exchangeName": "Kucoin", "ticker": "LDO-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Okx", "ticker": "LDO-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Mexc", "ticker": "LDO_USDT", "adjustByMarket": "USDT-USD" }
|
||||
],
|
||||
"LINK": [
|
||||
{ "exchangeName": "Binance", "ticker": "LINKUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Bitstamp", "ticker": "LINK/USD" },
|
||||
{ "exchangeName": "Bybit", "ticker": "LINKUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "CoinbasePro", "ticker": "LINK-USD" },
|
||||
{ "exchangeName": "Kraken", "ticker": "LINKUSD" },
|
||||
{ "exchangeName": "Kucoin", "ticker": "LINK-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Okx", "ticker": "LINK-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Mexc", "ticker": "LINK_USDT", "adjustByMarket": "USDT-USD" }
|
||||
],
|
||||
"LTC": [
|
||||
{ "exchangeName": "Binance", "ticker": "LTCUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Bitstamp", "ticker": "LTC/USD" },
|
||||
{ "exchangeName": "Bybit", "ticker": "LTCUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "CoinbasePro", "ticker": "LTC-USD" },
|
||||
{ "exchangeName": "Huobi", "ticker": "ltcusdt", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Kraken", "ticker": "LTCUSD" },
|
||||
{ "exchangeName": "Kucoin", "ticker": "LTC-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Okx", "ticker": "LTC-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Mexc", "ticker": "LTC_USDT", "adjustByMarket": "USDT-USD" }
|
||||
],
|
||||
"MANA": [
|
||||
{ "exchangeName": "Binance", "ticker": "MANAUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "CoinbasePro", "ticker": "MANA-USD" },
|
||||
{ "exchangeName": "Gate", "ticker": "MANA_USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Kraken", "ticker": "MANAUSD" },
|
||||
{ "exchangeName": "Kucoin", "ticker": "MANA-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Okx", "ticker": "MANA-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Mexc", "ticker": "MANA_USDT", "adjustByMarket": "USDT-USD" }
|
||||
],
|
||||
"MASK": [
|
||||
{ "exchangeName": "Binance", "ticker": "MASKUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Bybit", "ticker": "MASKUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "CoinbasePro", "ticker": "MASK-USD" },
|
||||
{ "exchangeName": "Gate", "ticker": "MASK_USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Huobi", "ticker": "maskusdt", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Kucoin", "ticker": "MASK-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Okx", "ticker": "MASK-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Mexc", "ticker": "MASK_USDT", "adjustByMarket": "USDT-USD" }
|
||||
],
|
||||
"MATIC": [
|
||||
{ "exchangeName": "Binance", "ticker": "MATICUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Bitstamp", "ticker": "MATIC/USD" },
|
||||
{ "exchangeName": "Bybit", "ticker": "MATICUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "CoinbasePro", "ticker": "MATIC-USD" },
|
||||
{ "exchangeName": "Huobi", "ticker": "maticusdt", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Kraken", "ticker": "MATICUSD" },
|
||||
{ "exchangeName": "Kucoin", "ticker": "MATIC-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Okx", "ticker": "MATIC-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Mexc", "ticker": "MATIC_USDT", "adjustByMarket": "USDT-USD" }
|
||||
],
|
||||
"MINA": [
|
||||
{ "exchangeName": "Binance", "ticker": "MINAUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "CoinbasePro", "ticker": "MINA-USD" },
|
||||
{ "exchangeName": "Gate", "ticker": "MINA_USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Kraken", "ticker": "MINAUSD" },
|
||||
{ "exchangeName": "Okx", "ticker": "MINA-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Mexc", "ticker": "MINA_USDT", "adjustByMarket": "USDT-USD" }
|
||||
],
|
||||
"MKR": [
|
||||
{ "exchangeName": "Binance", "ticker": "MKRUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "CoinbasePro", "ticker": "MKR-USD" },
|
||||
{ "exchangeName": "Kraken", "ticker": "MKRUSD" },
|
||||
{ "exchangeName": "Kucoin", "ticker": "MKR-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Okx", "ticker": "MKR-USDT", "adjustByMarket": "USDT-USD" }
|
||||
],
|
||||
"NEAR": [
|
||||
{ "exchangeName": "Binance", "ticker": "NEARUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Bybit", "ticker": "NEARUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "CoinbasePro", "ticker": "NEAR-USD" },
|
||||
{ "exchangeName": "Huobi", "ticker": "nearusdt", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Kraken", "ticker": "NEARUSD" },
|
||||
{ "exchangeName": "Kucoin", "ticker": "NEAR-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Okx", "ticker": "NEAR-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Mexc", "ticker": "NEAR_USDT", "adjustByMarket": "USDT-USD" }
|
||||
],
|
||||
"OP": [
|
||||
{ "exchangeName": "Binance", "ticker": "OPUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Bybit", "ticker": "OPUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "CoinbasePro", "ticker": "OP-USD" },
|
||||
{ "exchangeName": "Gate", "ticker": "OP_USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Kraken", "ticker": "OPUSD" },
|
||||
{ "exchangeName": "Kucoin", "ticker": "OP-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Okx", "ticker": "OP-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Mexc", "ticker": "OP_USDT", "adjustByMarket": "USDT-USD" }
|
||||
],
|
||||
"ORDI": [
|
||||
{ "exchangeName": "Binance", "ticker": "ORDIUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Bybit", "ticker": "ORDIUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Gate", "ticker": "ORDI_USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Huobi", "ticker": "ordiusdt", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Kucoin", "ticker": "ORDI-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Okx", "ticker": "ORDI-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Mexc", "ticker": "ORDI_USDT", "adjustByMarket": "USDT-USD" }
|
||||
],
|
||||
"PEPE": [
|
||||
{ "exchangeName": "Binance", "ticker": "PEPEUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Bybit", "ticker": "PEPEUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Kraken", "ticker": "PEPEUSD" },
|
||||
{ "exchangeName": "Kucoin", "ticker": "PEPE-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Okx", "ticker": "PEPE-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Mexc", "ticker": "PEPE_USDT", "adjustByMarket": "USDT-USD" }
|
||||
],
|
||||
"PYTH": [
|
||||
{ "exchangeName": "Binance", "ticker": "PYTHUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Bybit", "ticker": "PYTHUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Gate", "ticker": "PYTH_USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Kucoin", "ticker": "PYTH-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Okx", "ticker": "PYTH-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Mexc", "ticker": "PYTH_USDT", "adjustByMarket": "USDT-USD" }
|
||||
],
|
||||
"RNDR": [
|
||||
{ "exchangeName": "Binance", "ticker": "RNDRUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "CoinbasePro", "ticker": "RNDR-USD" },
|
||||
{ "exchangeName": "Kraken", "ticker": "RNDRUSD" },
|
||||
{ "exchangeName": "Kucoin", "ticker": "RNDR-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Okx", "ticker": "RNDR-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Mexc", "ticker": "RNDR_USDT", "adjustByMarket": "USDT-USD" }
|
||||
],
|
||||
"RUNE": [
|
||||
{ "exchangeName": "Binance", "ticker": "RUNEUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Gate", "ticker": "RUNE_USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Kraken", "ticker": "RUNEUSD" },
|
||||
{ "exchangeName": "Kucoin", "ticker": "RUNE-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Mexc", "ticker": "RUNE_USDT", "adjustByMarket": "USDT-USD" }
|
||||
],
|
||||
"SAND": [
|
||||
{ "exchangeName": "Binance", "ticker": "SANDUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "CoinbasePro", "ticker": "SAND-USD" },
|
||||
{ "exchangeName": "Gate", "ticker": "SAND_USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Kucoin", "ticker": "SAND-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Okx", "ticker": "SAND-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Mexc", "ticker": "SAND_USDT", "adjustByMarket": "USDT-USD" }
|
||||
],
|
||||
"SEI": [
|
||||
{ "exchangeName": "Binance", "ticker": "SEIUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Bybit", "ticker": "SEIUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "CoinbasePro", "ticker": "SEI-USD" },
|
||||
{ "exchangeName": "Huobi", "ticker": "seiusdt", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Kraken", "ticker": "SEIUSD" },
|
||||
{ "exchangeName": "Kucoin", "ticker": "SEI-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Mexc", "ticker": "SEI_USDT", "adjustByMarket": "USDT-USD" }
|
||||
],
|
||||
"SHIB": [
|
||||
{ "exchangeName": "Binance", "ticker": "SHIBUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Bybit", "ticker": "SHIBUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "CoinbasePro", "ticker": "SHIB-USD" },
|
||||
{ "exchangeName": "Huobi", "ticker": "shibusdt", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Kraken", "ticker": "SHIBUSD" },
|
||||
{ "exchangeName": "Kucoin", "ticker": "SHIB-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Okx", "ticker": "SHIB-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Mexc", "ticker": "SHIB_USDT", "adjustByMarket": "USDT-USD" }
|
||||
],
|
||||
"SNX": [
|
||||
{ "exchangeName": "Binance", "ticker": "SNXUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Bybit", "ticker": "SNXUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "CoinbasePro", "ticker": "SNX-USD" },
|
||||
{ "exchangeName": "Kraken", "ticker": "SNXUSD" },
|
||||
{ "exchangeName": "Kucoin", "ticker": "SNX-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Okx", "ticker": "SNX-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Mexc", "ticker": "SNX_USDT", "adjustByMarket": "USDT-USD" }
|
||||
],
|
||||
"SOL": [
|
||||
{ "exchangeName": "Binance", "ticker": "SOLUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Bitstamp", "ticker": "SOL/USD" },
|
||||
{ "exchangeName": "Bybit", "ticker": "SOLUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "CoinbasePro", "ticker": "SOL-USD" },
|
||||
{ "exchangeName": "Huobi", "ticker": "solusdt", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Kraken", "ticker": "SOLUSD" },
|
||||
{ "exchangeName": "Kucoin", "ticker": "SOL-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Okx", "ticker": "SOL-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Mexc", "ticker": "SOL_USDT", "adjustByMarket": "USDT-USD" }
|
||||
],
|
||||
"STX": [
|
||||
{ "exchangeName": "Binance", "ticker": "STXUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Bybit", "ticker": "STXUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "CoinbasePro", "ticker": "STX-USD" },
|
||||
{ "exchangeName": "Gate", "ticker": "STX_USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Kraken", "ticker": "STXUSD" },
|
||||
{ "exchangeName": "Kucoin", "ticker": "STX-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Okx", "ticker": "STX-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Mexc", "ticker": "STX_USDT", "adjustByMarket": "USDT-USD" }
|
||||
],
|
||||
"SUI": [
|
||||
{ "exchangeName": "Binance", "ticker": "SUIUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Bybit", "ticker": "SUIUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "CoinbasePro", "ticker": "SUI-USD" },
|
||||
{ "exchangeName": "Huobi", "ticker": "suiusdt", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Kraken", "ticker": "SUIUSD" },
|
||||
{ "exchangeName": "Kucoin", "ticker": "SUI-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Okx", "ticker": "SUI-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Mexc", "ticker": "SUI_USDT", "adjustByMarket": "USDT-USD" }
|
||||
],
|
||||
"TIA": [
|
||||
{ "exchangeName": "Binance", "ticker": "TIAUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Bybit", "ticker": "TIAUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "CoinbasePro", "ticker": "TIA-USD" },
|
||||
{ "exchangeName": "Kraken", "ticker": "TIAUSD" },
|
||||
{ "exchangeName": "Kucoin", "ticker": "TIA-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Okx", "ticker": "TIA-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Mexc", "ticker": "TIA_USDT", "adjustByMarket": "USDT-USD" }
|
||||
],
|
||||
"TRX": [
|
||||
{ "exchangeName": "Binance", "ticker": "TRXUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Bybit", "ticker": "TRXUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Gate", "ticker": "TRX_USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Huobi", "ticker": "trxusdt", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Kraken", "ticker": "TRXUSD" },
|
||||
{ "exchangeName": "Kucoin", "ticker": "TRX-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Okx", "ticker": "TRX-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Mexc", "ticker": "TRX_USDT", "adjustByMarket": "USDT-USD" }
|
||||
],
|
||||
"UNI": [
|
||||
{ "exchangeName": "Binance", "ticker": "UNIUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Bybit", "ticker": "UNIUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "CoinbasePro", "ticker": "UNI-USD" },
|
||||
{ "exchangeName": "Kraken", "ticker": "UNIUSD" },
|
||||
{ "exchangeName": "Kucoin", "ticker": "UNI-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Okx", "ticker": "UNI-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Mexc", "ticker": "UNI_USDT", "adjustByMarket": "USDT-USD" }
|
||||
],
|
||||
"WLD": [
|
||||
{ "exchangeName": "Binance", "ticker": "WLDUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Bybit", "ticker": "WLDUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Gate", "ticker": "WLD_USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Kucoin", "ticker": "WLD-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Okx", "ticker": "WLD-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Mexc", "ticker": "WLD_USDT", "adjustByMarket": "USDT-USD" }
|
||||
],
|
||||
"WOO": [
|
||||
{ "exchangeName": "Binance", "ticker": "WOOUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Gate", "ticker": "WOO_USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Kucoin", "ticker": "WOO-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Okx", "ticker": "WOO-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Mexc", "ticker": "WOO_USDT", "adjustByMarket": "USDT-USD" }
|
||||
],
|
||||
"XLM": [
|
||||
{ "exchangeName": "Binance", "ticker": "XLMUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Bitstamp", "ticker": "XLM/USD" },
|
||||
{ "exchangeName": "Bybit", "ticker": "XLMUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "CoinbasePro", "ticker": "XLM-USD" },
|
||||
{ "exchangeName": "Kraken", "ticker": "XLMUSD" },
|
||||
{ "exchangeName": "Kucoin", "ticker": "XLM-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Okx", "ticker": "XLM-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Mexc", "ticker": "XLM_USDT", "adjustByMarket": "USDT-USD" }
|
||||
],
|
||||
"XRP": [
|
||||
{ "exchangeName": "Binance", "ticker": "XRPUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Bitstamp", "ticker": "XRP/USD" },
|
||||
{ "exchangeName": "Bybit", "ticker": "XRPUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "CoinbasePro", "ticker": "XRP-USD" },
|
||||
{ "exchangeName": "Huobi", "ticker": "xrpusdt", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Kraken", "ticker": "XRPUSD" },
|
||||
{ "exchangeName": "Kucoin", "ticker": "XRP-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Okx", "ticker": "XRP-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Mexc", "ticker": "XRP_USDT", "adjustByMarket": "USDT-USD" }
|
||||
],
|
||||
"ZETA": [
|
||||
{ "exchangeName": "Bybit", "ticker": "ZETAUSDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "CoinbasePro", "ticker": "ZETA-USD" },
|
||||
{ "exchangeName": "Gate", "ticker": "ZETA_USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Kucoin", "ticker": "ZETA-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Okx", "ticker": "ZETA-USDT", "adjustByMarket": "USDT-USD" },
|
||||
{ "exchangeName": "Mexc", "ticker": "ZETA_USDT", "adjustByMarket": "USDT-USD" }
|
||||
]
|
||||
}
|
||||
|
After Width: | Height: | Size: 56 KiB |
|
After Width: | Height: | Size: 109 KiB |
|
After Width: | Height: | Size: 31 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 15 KiB |
@@ -0,0 +1,230 @@
|
||||
<svg width="254" height="77" viewBox="0 0 254 77" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g id="Group 1258">
|
||||
<g id="Ellipse 9" opacity="0.4" filter="url(#filter0_f_20300_14972)">
|
||||
<ellipse cx="86.5425" cy="-3.91219" rx="116.542" ry="20.0878" fill="#7774FF"/>
|
||||
</g>
|
||||
<g id="Ellipse 10" opacity="0.3" filter="url(#filter1_f_20300_14972)">
|
||||
<circle cx="74.5734" cy="4.63007" r="1.00507" fill="#9A9AFF"/>
|
||||
</g>
|
||||
<g id="Ellipse 12" opacity="0.3" filter="url(#filter2_f_20300_14972)">
|
||||
<circle cx="82.1105" cy="7.64179" r="1.00507" fill="#9A9AFF"/>
|
||||
</g>
|
||||
<g id="Ellipse 22" opacity="0.3" filter="url(#filter3_f_20300_14972)">
|
||||
<circle cx="116.785" cy="4.63007" r="1.00507" fill="#9A9AFF"/>
|
||||
</g>
|
||||
<g id="Ellipse 11" opacity="0.3" filter="url(#filter4_f_20300_14972)">
|
||||
<circle cx="64.774" cy="8.90488" r="0.502536" fill="#9A9AFF"/>
|
||||
</g>
|
||||
<g id="Ellipse 18" opacity="0.3" filter="url(#filter5_f_20300_14972)">
|
||||
<circle cx="96.4322" cy="3.87363" r="0.502536" fill="#9A9AFF"/>
|
||||
</g>
|
||||
<g id="Ellipse 20" opacity="0.3" filter="url(#filter6_f_20300_14972)">
|
||||
<circle cx="76.0807" cy="14.9361" r="0.502536" fill="#9A9AFF"/>
|
||||
</g>
|
||||
<g id="Ellipse 21" opacity="0.3" filter="url(#filter7_f_20300_14972)">
|
||||
<circle cx="104.725" cy="4.87754" r="0.502536" fill="#9A9AFF"/>
|
||||
</g>
|
||||
<g id="Ellipse 23" opacity="0.3" filter="url(#filter8_f_20300_14972)">
|
||||
<circle cx="114.021" cy="7.13925" r="0.502536" fill="#9A9AFF"/>
|
||||
</g>
|
||||
<g id="Ellipse 24" opacity="0.3" filter="url(#filter9_f_20300_14972)">
|
||||
<circle cx="109.75" cy="15.4361" r="0.502536" fill="#9A9AFF"/>
|
||||
</g>
|
||||
<g id="Ellipse 25" opacity="0.3" filter="url(#filter10_f_20300_14972)">
|
||||
<circle cx="119.801" cy="12.6705" r="0.502536" fill="#9A9AFF"/>
|
||||
</g>
|
||||
<g id="Ellipse 27" opacity="0.3" filter="url(#filter11_f_20300_14972)">
|
||||
<circle cx="94.0885" cy="11.0182" r="0.502536" fill="#9A9AFF"/>
|
||||
</g>
|
||||
<g id="Ellipse 30" opacity="0.3" filter="url(#filter12_f_20300_14972)">
|
||||
<circle cx="154.475" cy="11.6666" r="0.502536" fill="#9A9AFF"/>
|
||||
</g>
|
||||
<g id="Ellipse 29" opacity="0.3" filter="url(#filter13_f_20300_14972)">
|
||||
<circle cx="146.435" cy="8.90488" r="0.502536" fill="#9A9AFF"/>
|
||||
</g>
|
||||
<g id="Ellipse 15" opacity="0.3" filter="url(#filter14_f_20300_14972)">
|
||||
<circle cx="24.0103" cy="4.44785" r="0.502536" fill="#9A9AFF"/>
|
||||
</g>
|
||||
<g id="Ellipse 33" opacity="0.3" filter="url(#filter15_f_20300_14972)">
|
||||
<circle cx="-1.05899" cy="13.6783" r="0.502536" fill="#9A9AFF"/>
|
||||
</g>
|
||||
<g id="Ellipse 16" opacity="0.3" filter="url(#filter16_f_20300_14972)">
|
||||
<circle cx="17.441" cy="16.4908" r="0.502536" fill="#9A9AFF"/>
|
||||
</g>
|
||||
<g id="Ellipse 35" opacity="0.3" filter="url(#filter17_f_20300_14972)">
|
||||
<circle cx="36.0553" cy="6.63535" r="0.502536" fill="#9A9AFF"/>
|
||||
</g>
|
||||
<g id="Ellipse 32" opacity="0.3" filter="url(#filter18_f_20300_14972)">
|
||||
<circle cx="10.8707" cy="14.2994" r="0.502536" fill="#9A9AFF"/>
|
||||
</g>
|
||||
<g id="Ellipse 13" opacity="0.3" filter="url(#filter19_f_20300_14972)">
|
||||
<circle cx="55.7274" cy="9.65615" r="0.753803" fill="#9A9AFF"/>
|
||||
</g>
|
||||
<g id="Ellipse 19" opacity="0.3" filter="url(#filter20_f_20300_14972)">
|
||||
<circle cx="87.3886" cy="20.7108" r="0.753803" fill="#9A9AFF"/>
|
||||
</g>
|
||||
<g id="Ellipse 26" opacity="0.3" filter="url(#filter21_f_20300_14972)">
|
||||
<circle cx="123.82" cy="15.1874" r="0.753803" fill="#9A9AFF"/>
|
||||
</g>
|
||||
<g id="Ellipse 36" opacity="0.3" filter="url(#filter22_f_20300_14972)">
|
||||
<circle cx="134.876" cy="14.4335" r="0.753803" fill="#9A9AFF"/>
|
||||
</g>
|
||||
<g id="Ellipse 28" opacity="0.3" filter="url(#filter23_f_20300_14972)">
|
||||
<circle cx="129.6" cy="6.38662" r="0.753803" fill="#9A9AFF"/>
|
||||
</g>
|
||||
<g id="Ellipse 14" opacity="0.3" filter="url(#filter24_f_20300_14972)">
|
||||
<circle cx="41.6571" cy="14.9335" r="0.753803" fill="#9A9AFF"/>
|
||||
</g>
|
||||
<g id="Ellipse 31" opacity="0.3" filter="url(#filter25_f_20300_14972)">
|
||||
<circle cx="4.21767" cy="17.9491" r="0.753803" fill="#9A9AFF"/>
|
||||
</g>
|
||||
<g id="Ellipse 34" opacity="0.3" filter="url(#filter26_f_20300_14972)">
|
||||
<circle cx="12.2177" cy="6.88662" r="0.753803" fill="#9A9AFF"/>
|
||||
</g>
|
||||
<g id="Ellipse 17" opacity="0.3" filter="url(#filter27_f_20300_14972)">
|
||||
<circle cx="50.2001" cy="3.6249" r="0.753803" fill="#9A9AFF"/>
|
||||
</g>
|
||||
</g>
|
||||
<defs>
|
||||
<filter id="filter0_f_20300_14972" x="-94" y="-88" width="361.085" height="168.176" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
|
||||
<feGaussianBlur stdDeviation="32" result="effect1_foregroundBlur_20300_14972"/>
|
||||
</filter>
|
||||
<filter id="filter1_f_20300_14972" x="72.5633" y="2.61993" width="4.01991" height="4.02186" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
|
||||
<feGaussianBlur stdDeviation="0.502536" result="effect1_foregroundBlur_20300_14972"/>
|
||||
</filter>
|
||||
<filter id="filter2_f_20300_14972" x="80.6029" y="6.13418" width="3.01484" height="3.01679" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
|
||||
<feGaussianBlur stdDeviation="0.251268" result="effect1_foregroundBlur_20300_14972"/>
|
||||
</filter>
|
||||
<filter id="filter3_f_20300_14972" x="115.278" y="3.12246" width="3.01484" height="3.01679" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
|
||||
<feGaussianBlur stdDeviation="0.251268" result="effect1_foregroundBlur_20300_14972"/>
|
||||
</filter>
|
||||
<filter id="filter4_f_20300_14972" x="63.2664" y="7.39727" width="3.01502" height="3.01405" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
|
||||
<feGaussianBlur stdDeviation="0.502536" result="effect1_foregroundBlur_20300_14972"/>
|
||||
</filter>
|
||||
<filter id="filter5_f_20300_14972" x="94.9246" y="2.36602" width="3.01502" height="3.01405" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
|
||||
<feGaussianBlur stdDeviation="0.502536" result="effect1_foregroundBlur_20300_14972"/>
|
||||
</filter>
|
||||
<filter id="filter6_f_20300_14972" x="74.5731" y="13.4285" width="3.01502" height="3.01405" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
|
||||
<feGaussianBlur stdDeviation="0.502536" result="effect1_foregroundBlur_20300_14972"/>
|
||||
</filter>
|
||||
<filter id="filter7_f_20300_14972" x="103.218" y="3.36993" width="3.01502" height="3.01405" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
|
||||
<feGaussianBlur stdDeviation="0.502536" result="effect1_foregroundBlur_20300_14972"/>
|
||||
</filter>
|
||||
<filter id="filter8_f_20300_14972" x="112.513" y="5.63165" width="3.01502" height="3.01405" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
|
||||
<feGaussianBlur stdDeviation="0.502536" result="effect1_foregroundBlur_20300_14972"/>
|
||||
</filter>
|
||||
<filter id="filter9_f_20300_14972" x="108.242" y="13.9285" width="3.01502" height="3.01405" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
|
||||
<feGaussianBlur stdDeviation="0.502536" result="effect1_foregroundBlur_20300_14972"/>
|
||||
</filter>
|
||||
<filter id="filter10_f_20300_14972" x="118.294" y="11.1629" width="3.01502" height="3.01405" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
|
||||
<feGaussianBlur stdDeviation="0.502536" result="effect1_foregroundBlur_20300_14972"/>
|
||||
</filter>
|
||||
<filter id="filter11_f_20300_14972" x="92.5809" y="9.51055" width="3.01502" height="3.01405" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
|
||||
<feGaussianBlur stdDeviation="0.502536" result="effect1_foregroundBlur_20300_14972"/>
|
||||
</filter>
|
||||
<filter id="filter12_f_20300_14972" x="153.47" y="10.6615" width="2.00995" height="2.00898" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
|
||||
<feGaussianBlur stdDeviation="0.251268" result="effect1_foregroundBlur_20300_14972"/>
|
||||
</filter>
|
||||
<filter id="filter13_f_20300_14972" x="144.928" y="7.39727" width="3.01502" height="3.01405" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
|
||||
<feGaussianBlur stdDeviation="0.502536" result="effect1_foregroundBlur_20300_14972"/>
|
||||
</filter>
|
||||
<filter id="filter14_f_20300_14972" x="22.5027" y="2.94024" width="3.01502" height="3.01405" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
|
||||
<feGaussianBlur stdDeviation="0.502536" result="effect1_foregroundBlur_20300_14972"/>
|
||||
</filter>
|
||||
<filter id="filter15_f_20300_14972" x="-2.56659" y="12.1707" width="3.01502" height="3.01405" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
|
||||
<feGaussianBlur stdDeviation="0.502536" result="effect1_foregroundBlur_20300_14972"/>
|
||||
</filter>
|
||||
<filter id="filter16_f_20300_14972" x="15.9334" y="14.9832" width="3.01502" height="3.01405" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
|
||||
<feGaussianBlur stdDeviation="0.502536" result="effect1_foregroundBlur_20300_14972"/>
|
||||
</filter>
|
||||
<filter id="filter17_f_20300_14972" x="35.0502" y="5.63028" width="2.00995" height="2.00898" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
|
||||
<feGaussianBlur stdDeviation="0.251268" result="effect1_foregroundBlur_20300_14972"/>
|
||||
</filter>
|
||||
<filter id="filter18_f_20300_14972" x="9.86563" y="13.2943" width="2.00995" height="2.00898" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
|
||||
<feGaussianBlur stdDeviation="0.251268" result="effect1_foregroundBlur_20300_14972"/>
|
||||
</filter>
|
||||
<filter id="filter19_f_20300_14972" x="53.9686" y="7.89727" width="3.51795" height="3.51795" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
|
||||
<feGaussianBlur stdDeviation="0.502536" result="effect1_foregroundBlur_20300_14972"/>
|
||||
</filter>
|
||||
<filter id="filter20_f_20300_14972" x="85.6297" y="18.952" width="3.51795" height="3.51795" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
|
||||
<feGaussianBlur stdDeviation="0.502536" result="effect1_foregroundBlur_20300_14972"/>
|
||||
</filter>
|
||||
<filter id="filter21_f_20300_14972" x="122.061" y="13.4285" width="3.51795" height="3.51795" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
|
||||
<feGaussianBlur stdDeviation="0.502536" result="effect1_foregroundBlur_20300_14972"/>
|
||||
</filter>
|
||||
<filter id="filter22_f_20300_14972" x="133.117" y="12.6746" width="3.51795" height="3.51795" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
|
||||
<feGaussianBlur stdDeviation="0.502536" result="effect1_foregroundBlur_20300_14972"/>
|
||||
</filter>
|
||||
<filter id="filter23_f_20300_14972" x="127.842" y="4.62774" width="3.51795" height="3.51795" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
|
||||
<feGaussianBlur stdDeviation="0.502536" result="effect1_foregroundBlur_20300_14972"/>
|
||||
</filter>
|
||||
<filter id="filter24_f_20300_14972" x="39.8982" y="13.1746" width="3.51795" height="3.51795" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
|
||||
<feGaussianBlur stdDeviation="0.502536" result="effect1_foregroundBlur_20300_14972"/>
|
||||
</filter>
|
||||
<filter id="filter25_f_20300_14972" x="2.4588" y="16.1902" width="3.51795" height="3.51795" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
|
||||
<feGaussianBlur stdDeviation="0.502536" result="effect1_foregroundBlur_20300_14972"/>
|
||||
</filter>
|
||||
<filter id="filter26_f_20300_14972" x="10.4588" y="5.12774" width="3.51795" height="3.51795" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
|
||||
<feGaussianBlur stdDeviation="0.502536" result="effect1_foregroundBlur_20300_14972"/>
|
||||
</filter>
|
||||
<filter id="filter27_f_20300_14972" x="48.4412" y="1.86602" width="3.51795" height="3.51795" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
|
||||
<feGaussianBlur stdDeviation="0.502536" result="effect1_foregroundBlur_20300_14972"/>
|
||||
</filter>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 2.9 KiB |
|
Before Width: | Height: | Size: 9.6 KiB |
@@ -0,0 +1,15 @@
|
||||
<!-- Smartbanner: Configure the mobile app -->
|
||||
<meta name="smartbanner:title" content="SMARTBANNER_APP_NAME">
|
||||
<meta name="smartbanner:author" content="SMARTBANNER_ORG_NAME">
|
||||
<meta name="smartbanner:icon-apple" content="SMARTBANNER_ICON_URL">
|
||||
<meta name="smartbanner:icon-google" content="SMARTBANNER_ICON_URL">
|
||||
<!-- Smartbanner: The rest of the configurations can be kept as is -->
|
||||
<meta name="smartbanner:price" content="FREE">
|
||||
<meta name="smartbanner:price-suffix-apple" content=" - On the App Store">
|
||||
<meta name="smartbanner:price-suffix-google" content=" - In Google Play">
|
||||
<meta name="smartbanner:button" content="VIEW">
|
||||
<meta name="smartbanner:close-label" content="Close">
|
||||
<meta name="smartbanner:exclude-user-agent-regex" content="^.*(Windows NT|Intel Mac OS X).*$">
|
||||
<script src="https://cdn.jsdelivr.net/npm/smartbanner.js@1.22.0/dist/smartbanner.min.js"></script>
|
||||
<link href="https://cdn.jsdelivr.net/npm/smartbanner.js@1.22.0/dist/smartbanner.min.css" rel="stylesheet">
|
||||
<!-- Smartbanner: End configuration -->
|
||||
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 17 KiB |
@@ -36,3 +36,17 @@ Customize Intercom Messenger by adding logo and brand colors
|
||||
3. Add API key in Github > Secrets and Variables > Actions as `INTERCOM_APP_ID`
|
||||
4. In your deploy scripts add `pnpm run build:inject-intercom` after your pnpm build / vite build command.
|
||||
5. If you are using with the Amplitude deployment scripts, your build command may look like the following: `pnpm build && pnpm run build:inject-amplitude && pnpm run build:inject-intercom`
|
||||
|
||||
### Smartbanner
|
||||
Smartbanner to show download links to iOS and/or Android native apps on mobile devices.
|
||||
|
||||
<b>To use with dydxprotocol/v4-web:</b>
|
||||
1. iOS app App Store link or Android app Google Play link.
|
||||
2. Add configurations in Github > Secrets and Variables > Actions as
|
||||
`SMARTBANNER_APP_NAME` for app name
|
||||
`SMARTBANNER_ORG_NAME` for organization name
|
||||
`SMARTBANNER_ICON_URL` for icon image
|
||||
`SMARTBANNER_APPSTORE_URL` for iOS App Store link
|
||||
`SMARTBANNER_GOOGLEPLAY_URL` for Android Google Play link
|
||||
3. In your deploy scripts add `pnpm run build:inject-smartbanner` after your pnpm build / vite build command.
|
||||
4. If you are using with the Amplitude deployment scripts, your build command may look like the following: `pnpm build && pnpm run build:inject-smartbanner`
|
||||
|
||||
@@ -3,12 +3,13 @@ import path from 'path';
|
||||
import { fileURLToPath } from 'url';
|
||||
|
||||
const AMPLITUDE_API_KEY = process.env.AMPLITUDE_API_KEY;
|
||||
const AMPLITUDE_SERVER_URL = process.env.AMPLITUDE_SERVER_URL;
|
||||
|
||||
const currentPath = fileURLToPath(import.meta.url);
|
||||
const projectRoot = path.dirname(currentPath);
|
||||
const htmlFilePath = path.resolve(projectRoot, '../dist/index.html');
|
||||
|
||||
if(AMPLITUDE_API_KEY){
|
||||
if (AMPLITUDE_API_KEY) {
|
||||
try {
|
||||
const html = await fs.readFile(htmlFilePath, 'utf-8');
|
||||
|
||||
@@ -18,8 +19,34 @@ if(AMPLITUDE_API_KEY){
|
||||
`;
|
||||
|
||||
const amplitudeListenerScript = `<script type="module">
|
||||
!function(){var e="${AMPLITUDE_API_KEY}";e&&(globalThis.amplitude.init(e),globalThis.amplitude.setOptOut(!1),globalThis.addEventListener("dydx:track",function(e){var t=e.detail.eventType,d=e.detail.eventData;globalThis.amplitude.track(t,d)}),globalThis.addEventListener("dydx:identify",function(e){var t=e.detail.property,d=e.detail.propertyValue;if("walletAddress"===t)globalThis.amplitude.setUserId(d);else{var i=new globalThis.amplitude.Identify;i.set(t,d),globalThis.amplitude.identify(i)}}),console.log("Amplitude enabled."))}();
|
||||
</script>`;
|
||||
!(function () {
|
||||
var e = "${AMPLITUDE_API_KEY}";
|
||||
e &&
|
||||
(globalThis.amplitude.init(e${
|
||||
AMPLITUDE_SERVER_URL
|
||||
? `, undefined, {
|
||||
serverUrl: "${AMPLITUDE_SERVER_URL}"
|
||||
}`
|
||||
: ''
|
||||
}),
|
||||
globalThis.amplitude.setOptOut(!1),
|
||||
globalThis.addEventListener("dydx:track", function (e) {
|
||||
var t = e.detail.eventType,
|
||||
d = e.detail.eventData;
|
||||
globalThis.amplitude.track(t, d);
|
||||
}),
|
||||
globalThis.addEventListener("dydx:identify", function (e) {
|
||||
var t = e.detail.property,
|
||||
d = e.detail.propertyValue;
|
||||
if ("walletAddress" === t) globalThis.amplitude.setUserId(d);
|
||||
else {
|
||||
var i = new globalThis.amplitude.Identify();
|
||||
i.set(t, d), globalThis.amplitude.identify(i);
|
||||
}
|
||||
}),
|
||||
console.log("Amplitude enabled."));
|
||||
})();
|
||||
</script>`;
|
||||
|
||||
const injectedHtml = html.replace(
|
||||
'<div id="root"></div>',
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
/* eslint-disable no-console */
|
||||
import fs from 'fs/promises';
|
||||
import path from 'path';
|
||||
import { fileURLToPath } from 'url';
|
||||
|
||||
const SMARTBANNER_APP_NAME = process.env.SMARTBANNER_APP_NAME;
|
||||
const SMARTBANNER_ORG_NAME = process.env.SMARTBANNER_ORG_NAME;
|
||||
const SMARTBANNER_ICON_URL = process.env.SMARTBANNER_ICON_URL;
|
||||
const SMARTBANNER_APPSTORE_URL = process.env.SMARTBANNER_APPSTORE_URL;
|
||||
const SMARTBANNER_GOOGLEPLAY_URL = process.env.SMARTBANNER_GOOGLEPLAY_URL;
|
||||
|
||||
const currentPath = fileURLToPath(import.meta.url);
|
||||
const projectRoot = path.dirname(currentPath);
|
||||
const htmlFilePath = path.resolve(projectRoot, '../dist/index.html');
|
||||
const smartbannerFilePath = path.resolve(projectRoot, '../dist/smartbanner.html');
|
||||
|
||||
if (
|
||||
SMARTBANNER_APP_NAME &&
|
||||
SMARTBANNER_ORG_NAME &&
|
||||
SMARTBANNER_ICON_URL &&
|
||||
(SMARTBANNER_APPSTORE_URL || SMARTBANNER_GOOGLEPLAY_URL)
|
||||
) {
|
||||
try {
|
||||
const html = await fs.readFile(htmlFilePath, 'utf-8');
|
||||
let smartbanner = await fs.readFile(smartbannerFilePath, 'utf-8');
|
||||
smartbanner = smartbanner
|
||||
.replace('SMARTBANNER_APP_NAME', SMARTBANNER_APP_NAME)
|
||||
.replace('SMARTBANNER_ORG_NAME', SMARTBANNER_ORG_NAME)
|
||||
.replace('SMARTBANNER_ICON_URL', SMARTBANNER_ICON_URL)
|
||||
.replace('SMARTBANNER_ICON_URL', SMARTBANNER_ICON_URL);
|
||||
|
||||
/* hardcoded injection depending on whether the app is available on App Store and/or Google Play */
|
||||
|
||||
if (SMARTBANNER_APPSTORE_URL) {
|
||||
smartbanner = `\t<meta name="smartbanner:button-url-apple" content="${SMARTBANNER_APPSTORE_URL}">\n` + smartbanner;
|
||||
}
|
||||
if (SMARTBANNER_GOOGLEPLAY_URL) {
|
||||
smartbanner = `\t<meta name="smartbanner:button-url-google" content="${SMARTBANNER_GOOGLEPLAY_URL}">\n` + smartbanner;
|
||||
}
|
||||
if (SMARTBANNER_APPSTORE_URL) {
|
||||
if (SMARTBANNER_GOOGLEPLAY_URL) {
|
||||
smartbanner = `\t<meta name="smartbanner:enabled-platforms" content="android,ios">\n` + smartbanner;
|
||||
} else {
|
||||
smartbanner = `\t<meta name="smartbanner:enabled-platforms" content="ios">\n` + smartbanner;
|
||||
}
|
||||
} else {
|
||||
if (SMARTBANNER_GOOGLEPLAY_URL) {
|
||||
smartbanner = `\t<meta name="smartbanner:enabled-platforms" content="android">\n` + smartbanner;
|
||||
}
|
||||
}
|
||||
|
||||
const injectedHtml = html.replace('</head>', `${smartbanner}\n</head>`);
|
||||
|
||||
await fs.writeFile(htmlFilePath, injectedHtml, 'utf-8');
|
||||
|
||||
console.log('Smartbanner scripts successfully injected.');
|
||||
} catch (err) {
|
||||
console.error('Error injecting Smartbanner scripts:', err);
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,7 @@ import { WagmiConfig } from 'wagmi';
|
||||
import { QueryClient, QueryClientProvider } from 'react-query';
|
||||
import { GrazProvider } from 'graz';
|
||||
|
||||
import { AppRoute, DEFAULT_TRADE_ROUTE } from '@/constants/routes';
|
||||
import { AppRoute, DEFAULT_TRADE_ROUTE, MarketsRoute } from '@/constants/routes';
|
||||
|
||||
import {
|
||||
useBreakpoints,
|
||||
@@ -16,10 +16,12 @@ import {
|
||||
} from '@/hooks';
|
||||
import { DydxProvider } from '@/hooks/useDydxClient';
|
||||
import { AccountsProvider } from '@/hooks/useAccounts';
|
||||
import { AppThemeAndColorModeProvider } from '@/hooks/useAppThemeAndColorMode';
|
||||
import { DialogAreaProvider, useDialogArea } from '@/hooks/useDialogArea';
|
||||
import { LocaleProvider } from '@/hooks/useLocaleSeparators';
|
||||
import { NotificationsProvider } from '@/hooks/useNotifications';
|
||||
import { LocalNotificationsProvider } from '@/hooks/useLocalNotifications';
|
||||
import { PotentialMarketsProvider } from '@/hooks/usePotentialMarkets';
|
||||
import { RestrictionProvider } from '@/hooks/useRestrictions';
|
||||
import { SubaccountProvider } from '@/hooks/useSubaccount';
|
||||
|
||||
@@ -35,6 +37,7 @@ import { GlobalCommandDialog } from '@/views/dialogs/GlobalCommandDialog';
|
||||
import { config } from '@/lib/wagmi';
|
||||
|
||||
import { breakpoints } from '@/styles';
|
||||
import { GlobalStyle } from '@/styles/globalStyle';
|
||||
import { layoutMixins } from '@/styles/layoutMixins';
|
||||
import { LoadingSpace } from './components/Loading/LoadingSpinner';
|
||||
|
||||
@@ -42,15 +45,16 @@ import '@/styles/constants.css';
|
||||
import '@/styles/fonts.css';
|
||||
import '@/styles/web3modal.css';
|
||||
|
||||
const NewMarket = lazy(() => import('@/pages/markets/NewMarket'));
|
||||
const MarketsPage = lazy(() => import('@/pages/markets/Markets'));
|
||||
const PortfolioPage = lazy(() => import('@/pages/portfolio/Portfolio'));
|
||||
const AlertsPage = lazy(() => import('@/pages/AlertsPage'));
|
||||
const ProfilePage = lazy(() => import('@/pages/Profile'));
|
||||
const SettingsPage = lazy(() => import('@/pages/settings/Settings'));
|
||||
const TradePage = lazy(() => import('@/pages/trade/Trade'));
|
||||
const RewardsPage = lazy(() => import('@/pages/rewards/RewardsPage'));
|
||||
const TermsOfUsePage = lazy(() => import('@/pages/TermsOfUsePage'));
|
||||
const PrivacyPolicyPage = lazy(() => import('@/pages/PrivacyPolicyPage'));
|
||||
const TokenPage = lazy(() => import('@/pages/token/Token'));
|
||||
|
||||
const queryClient = new QueryClient();
|
||||
|
||||
@@ -66,49 +70,55 @@ const Content = () => {
|
||||
const { chainTokenLabel } = useTokenConfigs();
|
||||
|
||||
return (
|
||||
<Styled.Content isShowingHeader={isShowingHeader} isShowingFooter={isShowingFooter}>
|
||||
{isNotTablet && <HeaderDesktop />}
|
||||
<>
|
||||
<GlobalStyle />
|
||||
<Styled.Content isShowingHeader={isShowingHeader} isShowingFooter={isShowingFooter}>
|
||||
{isNotTablet && <HeaderDesktop />}
|
||||
|
||||
<Styled.Main>
|
||||
<Suspense fallback={<LoadingSpace id="main" />}>
|
||||
<Routes>
|
||||
<Route path={AppRoute.Trade}>
|
||||
<Route path=":market" element={<TradePage />} />
|
||||
<Route path={AppRoute.Trade} element={<TradePage />} />
|
||||
</Route>
|
||||
<Styled.Main>
|
||||
<Suspense fallback={<LoadingSpace id="main" />}>
|
||||
<Routes>
|
||||
<Route path={AppRoute.Trade}>
|
||||
<Route path=":market" element={<TradePage />} />
|
||||
<Route path={AppRoute.Trade} element={<TradePage />} />
|
||||
</Route>
|
||||
|
||||
<Route path={AppRoute.Markets} element={<MarketsPage />} />
|
||||
<Route path={`/${chainTokenLabel}`} element={<RewardsPage />} />
|
||||
{isTablet && (
|
||||
<>
|
||||
<Route path={AppRoute.Alerts} element={<AlertsPage />} />
|
||||
<Route path={AppRoute.Profile} element={<ProfilePage />} />
|
||||
<Route path={`${AppRoute.Settings}/*`} element={<SettingsPage />} />
|
||||
</>
|
||||
)}
|
||||
<Route path={AppRoute.Markets}>
|
||||
<Route path={MarketsRoute.New} element={<NewMarket />} />
|
||||
<Route path={AppRoute.Markets} element={<MarketsPage />} />
|
||||
</Route>
|
||||
<Route path={`/${chainTokenLabel}/*`} element={<TokenPage />} />
|
||||
{isTablet && (
|
||||
<>
|
||||
<Route path={AppRoute.Alerts} element={<AlertsPage />} />
|
||||
<Route path={AppRoute.Profile} element={<ProfilePage />} />
|
||||
<Route path={`${AppRoute.Settings}/*`} element={<SettingsPage />} />
|
||||
</>
|
||||
)}
|
||||
|
||||
<Route element={<GuardedMobileRoute />}>
|
||||
<Route path={`${AppRoute.Portfolio}/*`} element={<PortfolioPage />} />
|
||||
</Route>
|
||||
<Route element={<GuardedMobileRoute />}>
|
||||
<Route path={`${AppRoute.Portfolio}/*`} element={<PortfolioPage />} />
|
||||
</Route>
|
||||
|
||||
<Route path={AppRoute.Terms} element={<TermsOfUsePage />} />
|
||||
<Route path={AppRoute.Privacy} element={<PrivacyPolicyPage />} />
|
||||
<Route path={AppRoute.Terms} element={<TermsOfUsePage />} />
|
||||
<Route path={AppRoute.Privacy} element={<PrivacyPolicyPage />} />
|
||||
|
||||
<Route path="*" element={<Navigate to={DEFAULT_TRADE_ROUTE} replace />} />
|
||||
</Routes>
|
||||
</Suspense>
|
||||
</Styled.Main>
|
||||
<Route path="*" element={<Navigate to={DEFAULT_TRADE_ROUTE} replace />} />
|
||||
</Routes>
|
||||
</Suspense>
|
||||
</Styled.Main>
|
||||
|
||||
{isTablet ? <FooterMobile /> : <FooterDesktop />}
|
||||
{isTablet ? <FooterMobile /> : <FooterDesktop />}
|
||||
|
||||
<Styled.NotificationsToastArea />
|
||||
<Styled.NotificationsToastArea />
|
||||
|
||||
<Styled.DialogArea ref={setDialogArea}>
|
||||
<DialogManager />
|
||||
</Styled.DialogArea>
|
||||
<Styled.DialogArea ref={setDialogArea}>
|
||||
<DialogManager />
|
||||
</Styled.DialogArea>
|
||||
|
||||
<GlobalCommandDialog />
|
||||
</Styled.Content>
|
||||
<GlobalCommandDialog />
|
||||
</Styled.Content>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -131,6 +141,8 @@ const providers = [
|
||||
wrapProvider(LocalNotificationsProvider),
|
||||
wrapProvider(NotificationsProvider),
|
||||
wrapProvider(DialogAreaProvider),
|
||||
wrapProvider(PotentialMarketsProvider),
|
||||
wrapProvider(AppThemeAndColorModeProvider),
|
||||
];
|
||||
|
||||
const App = () => {
|
||||
@@ -195,6 +207,7 @@ Styled.Content = styled.div<{ isShowingHeader: boolean; isShowingFooter: boolean
|
||||
|
||||
Styled.Main = styled.main`
|
||||
${layoutMixins.contentSectionAttached}
|
||||
box-shadow: none;
|
||||
|
||||
grid-area: Main;
|
||||
|
||||
|
||||
@@ -85,7 +85,7 @@ Styled.Trigger = styled(Trigger)`
|
||||
&:hover {
|
||||
${Styled.Icon} {
|
||||
color: var(--color-text-2);
|
||||
filter: brightness(1.1);
|
||||
filter: brightness(var(--hover-filter-base));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -40,9 +40,6 @@ const AlertContainer = styled.div<StyleProps>`
|
||||
case AlertType.Info: {
|
||||
return css`
|
||||
--alert-accent-color: var(--color-text-1);
|
||||
|
||||
--alert-default-background-opacity: 0.133; // Relative
|
||||
// --alert-background: var(--color-layer-6); // Absolute
|
||||
`;
|
||||
}
|
||||
case AlertType.Success: {
|
||||
|
||||
@@ -16,6 +16,8 @@ const assetIcons = {
|
||||
AVAX: '/currencies/avax.png',
|
||||
BCH: '/currencies/bch.png',
|
||||
BLUR: '/currencies/blur.png',
|
||||
BNB: '/currencies/bnb.png',
|
||||
BONK: '/currencies/bonk.png',
|
||||
BTC: '/currencies/btc.png',
|
||||
CELO: '/currencies/celo.png',
|
||||
COMP: '/currencies/comp.png',
|
||||
@@ -24,12 +26,14 @@ const assetIcons = {
|
||||
DOGE: '/currencies/doge.png',
|
||||
DOT: '/currencies/dot.png',
|
||||
DYDX: '/currencies/dydx.png',
|
||||
DYM: '/currencies/dym.png',
|
||||
ENJ: '/currencies/enj.png',
|
||||
EOS: '/currencies/eos.png',
|
||||
ETC: '/currencies/etc.png',
|
||||
ETH: '/currencies/eth.png',
|
||||
FIL: '/currencies/fil.png',
|
||||
ICP: '/currencies/icp.png',
|
||||
JUP: '/currencies/jup.png',
|
||||
LDO: '/currencies/ldo.png',
|
||||
LINK: '/currencies/link.png',
|
||||
LTC: '/currencies/ltc.png',
|
||||
@@ -60,6 +64,7 @@ const assetIcons = {
|
||||
XTZ: '/currencies/xtz.png',
|
||||
YFI: '/currencies/yfi.png',
|
||||
ZEC: '/currencies/zec.png',
|
||||
ZETA: '/currencies/zeta.png',
|
||||
ZRX: '/currencies/zrx.png',
|
||||
} as const;
|
||||
|
||||
|
||||
@@ -134,8 +134,8 @@ const ButtonStyle = css<StyleProps>`
|
||||
|
||||
--button-textColor: var(--color-text-0);
|
||||
--button-backgroundColor: transparent;
|
||||
--button-active-filter: brightness(0.9);
|
||||
--button-hover-filter: brightness(1.1);
|
||||
--button-active-filter: brightness(var(--active-filter));
|
||||
--button-hover-filter: brightness(var(--hover-filter-base));
|
||||
--button-hover-textColor: var(--button-textColor);
|
||||
|
||||
--button-radius: 0.5em;
|
||||
|
||||
@@ -89,9 +89,10 @@ const buttonActionVariants = {
|
||||
--button-border: solid var(--border-width) var(--color-border);
|
||||
`,
|
||||
[ButtonAction.Primary]: css`
|
||||
--button-textColor: var(--color-text-2);
|
||||
--button-textColor: var(--color-text-button);
|
||||
--button-backgroundColor: var(--color-accent);
|
||||
--button-border: solid var(--border-width) var(--color-border-white);
|
||||
--button-hover-filter: brightness(var(--hover-filter-variant));
|
||||
`,
|
||||
|
||||
[ButtonAction.Secondary]: css`
|
||||
@@ -101,15 +102,17 @@ const buttonActionVariants = {
|
||||
`,
|
||||
|
||||
[ButtonAction.Create]: css`
|
||||
--button-textColor: var(--color-text-2);
|
||||
--button-backgroundColor: var(--color-positive);
|
||||
--button-textColor: var(--color-text-button);
|
||||
--button-backgroundColor: var(--color-green);
|
||||
--button-border: solid var(--border-width) var(--color-border-white);
|
||||
--button-hover-filter: brightness(var(--hover-filter-variant));
|
||||
`,
|
||||
|
||||
[ButtonAction.Destroy]: css`
|
||||
--button-textColor: var(--color-text-2);
|
||||
--button-backgroundColor: var(--color-negative);
|
||||
--button-textColor: var(--color-text-button);
|
||||
--button-backgroundColor: var(--color-red);
|
||||
--button-border: solid var(--border-width) var(--color-border-white);
|
||||
--button-hover-filter: brightness(var(--hover-filter-variant));
|
||||
`,
|
||||
|
||||
[ButtonAction.Navigation]: css`
|
||||
@@ -119,9 +122,10 @@ const buttonActionVariants = {
|
||||
`,
|
||||
|
||||
[ButtonAction.Reset]: css`
|
||||
--button-textColor: var(--color-negative);
|
||||
--button-textColor: var(--color-red);
|
||||
--button-backgroundColor: var(--color-layer-3);
|
||||
--button-border: solid var(--border-width) var(--color-border-red);
|
||||
--button-hover-filter: brightness(var(--hover-filter-variant));
|
||||
`,
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
import { forwardRef } from 'react';
|
||||
|
||||
type CanvasProps = {
|
||||
className?: string;
|
||||
width: number | string;
|
||||
height: number | string;
|
||||
};
|
||||
|
||||
export const Canvas = forwardRef<HTMLCanvasElement, CanvasProps>(
|
||||
({ className, width, height }, canvasRef) => (
|
||||
<canvas ref={canvasRef} className={className} width={width} height={height} />
|
||||
)
|
||||
);
|
||||
@@ -5,7 +5,7 @@ import { Checkbox, CheckboxProps } from '@/components/Checkbox';
|
||||
|
||||
import { StoryWrapper } from '.ladle/components';
|
||||
|
||||
export const Checkboxes: Story<CheckboxProps> = (args) => {
|
||||
export const CheckboxStory: Story<CheckboxProps> = (args) => {
|
||||
const [isChecked, setIsChecked] = useState(false);
|
||||
|
||||
return (
|
||||
@@ -21,4 +21,12 @@ export const Checkboxes: Story<CheckboxProps> = (args) => {
|
||||
);
|
||||
};
|
||||
|
||||
Checkboxes.args = {};
|
||||
CheckboxStory.args = {};
|
||||
|
||||
CheckboxStory.argTypes = {
|
||||
disabled: {
|
||||
options: [true, false],
|
||||
control: { type: 'select' },
|
||||
defaultValue: false,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import styled, { type AnyStyledComponent } from 'styled-components';
|
||||
import styled, { css, type AnyStyledComponent } from 'styled-components';
|
||||
import { Root, Indicator } from '@radix-ui/react-checkbox';
|
||||
import { CheckIcon } from '@radix-ui/react-icons';
|
||||
|
||||
@@ -9,6 +9,7 @@ type ElementProps = {
|
||||
onCheckedChange: (checked: boolean) => void;
|
||||
id?: string;
|
||||
label?: React.ReactNode;
|
||||
disabled?: boolean;
|
||||
};
|
||||
|
||||
type StyleProps = {
|
||||
@@ -23,14 +24,25 @@ export const Checkbox: React.FC<CheckboxProps> = ({
|
||||
onCheckedChange,
|
||||
id,
|
||||
label,
|
||||
disabled,
|
||||
}) => (
|
||||
<Styled.Container>
|
||||
<Styled.Root className={className} checked={checked} onCheckedChange={onCheckedChange} id={id}>
|
||||
<Styled.Root
|
||||
className={className}
|
||||
checked={checked}
|
||||
disabled={disabled}
|
||||
onCheckedChange={onCheckedChange}
|
||||
id={id}
|
||||
>
|
||||
<Styled.Indicator>
|
||||
<CheckIcon />
|
||||
</Styled.Indicator>
|
||||
</Styled.Root>
|
||||
{label && <label htmlFor={id}>{label}</label>}
|
||||
{label && (
|
||||
<Styled.Label disabled={disabled} htmlFor={id}>
|
||||
{label}
|
||||
</Styled.Label>
|
||||
)}
|
||||
</Styled.Container>
|
||||
);
|
||||
|
||||
@@ -40,25 +52,27 @@ Styled.Container = styled.div`
|
||||
${layoutMixins.row}
|
||||
gap: 1ch;
|
||||
font: var(--font-small-book);
|
||||
|
||||
label {
|
||||
cursor: pointer;
|
||||
}
|
||||
`;
|
||||
|
||||
Styled.Root = styled(Root)`
|
||||
--checkbox-backgroundColor: var(--color-layer-0);
|
||||
--checkbox-borderColor: var(--color-border);
|
||||
|
||||
min-width: 1.25rem;
|
||||
height: 1.25rem;
|
||||
|
||||
border-radius: 0.375rem;
|
||||
border: var(--border-width) solid var(--color-border);
|
||||
border: var(--border-width) solid var(--checkbox-borderColor);
|
||||
background-color: var(--checkbox-backgroundColor);
|
||||
|
||||
&[data-state='checked'] {
|
||||
--checkbox-backgroundColor: var(--color-accent);
|
||||
}
|
||||
|
||||
&[data-disabled] {
|
||||
cursor: not-allowed;
|
||||
--checkbox-backgroundColor: var(--color-layer-1);
|
||||
}
|
||||
`;
|
||||
|
||||
Styled.Indicator = styled(Indicator)`
|
||||
@@ -66,5 +80,17 @@ Styled.Indicator = styled(Indicator)`
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
color: var(--color-text-button);
|
||||
`;
|
||||
|
||||
Styled.Label = styled.label<{ disabled?: boolean }>`
|
||||
cursor: pointer;
|
||||
color: var(--color-text-2);
|
||||
|
||||
${({ disabled }) =>
|
||||
disabled &&
|
||||
css`
|
||||
cursor: not-allowed;
|
||||
color: var(--color-text-0);
|
||||
`}
|
||||
`;
|
||||
|
||||
@@ -50,10 +50,11 @@ export const ComboboxMenu = <MenuItemValue extends string, MenuGroupValue extend
|
||||
label={title}
|
||||
// value={highlightedCommand}
|
||||
// onValueChange={setHighlightedCommand}
|
||||
filter={(value: string, search: string) => {
|
||||
if (value.replace(/ /g, '').includes(search.replace(/ /g, ''))) return 1;
|
||||
return 0;
|
||||
}}
|
||||
filter={(value: string, search: string) =>
|
||||
value.replace(/ /g, '').toLowerCase().includes(search.replace(/ /g, '').toLowerCase())
|
||||
? 1
|
||||
: 0
|
||||
}
|
||||
className={className}
|
||||
$withStickyLayout={withStickyLayout}
|
||||
>
|
||||
|
||||
@@ -11,6 +11,5 @@ export const DetachedScrollableSection = styled.section`
|
||||
|
||||
export const AttachedExpandingSection = styled.section`
|
||||
${layoutMixins.contentSectionAttached}
|
||||
${layoutMixins.expandingColumnWithHeader}
|
||||
gap: var(--border-width);
|
||||
`;
|
||||
|
||||
@@ -6,6 +6,7 @@ import { layoutMixins } from '@/styles/layoutMixins';
|
||||
type ElementProps = {
|
||||
title: string;
|
||||
subtitle?: React.ReactNode;
|
||||
slotLeft?: React.ReactNode;
|
||||
slotRight?: React.ReactNode;
|
||||
};
|
||||
|
||||
@@ -16,14 +17,16 @@ type StyleProps = {
|
||||
export const ContentSectionHeader = ({
|
||||
title,
|
||||
subtitle,
|
||||
slotLeft,
|
||||
slotRight,
|
||||
className,
|
||||
}: ElementProps & StyleProps) => (
|
||||
<Styled.ContentSectionHeader className={className}>
|
||||
<div>
|
||||
{slotLeft}
|
||||
<Styled.Header>
|
||||
{title && <h3>{title}</h3>}
|
||||
{subtitle && <p>{subtitle}</p>}
|
||||
</div>
|
||||
</Styled.Header>
|
||||
{slotRight}
|
||||
</Styled.ContentSectionHeader>
|
||||
);
|
||||
@@ -40,9 +43,15 @@ Styled.ContentSectionHeader = styled.header<StyleProps>`
|
||||
|
||||
padding: 1rem var(--header-horizontal-padding);
|
||||
|
||||
> div {
|
||||
${layoutMixins.column}
|
||||
@media ${breakpoints.tablet} {
|
||||
flex-wrap: wrap;
|
||||
--header-horizontal-padding: 1.25rem;
|
||||
}
|
||||
`;
|
||||
|
||||
Styled.Header = styled.div`
|
||||
${layoutMixins.column}
|
||||
flex: 1;
|
||||
|
||||
h3 {
|
||||
color: var(--color-text-2);
|
||||
@@ -54,9 +63,4 @@ Styled.ContentSectionHeader = styled.header<StyleProps>`
|
||||
font: var(--font-small-book);
|
||||
margin-top: 0.25rem;
|
||||
}
|
||||
|
||||
@media ${breakpoints.tablet} {
|
||||
flex-wrap: wrap;
|
||||
--header-horizontal-padding: 1.25rem;
|
||||
}
|
||||
`;
|
||||
|
||||
@@ -77,7 +77,7 @@ Styled.InlineRow = styled.div<{ copied: boolean }>`
|
||||
`
|
||||
: css`
|
||||
&:hover {
|
||||
filter: brightness(1.1);
|
||||
filter: brightness(var(--hover-filter-base));
|
||||
text-decoration: underline;
|
||||
}
|
||||
`}
|
||||
@@ -87,7 +87,7 @@ Styled.Icon = styled(Icon)<{ copied: boolean }>`
|
||||
${({ copied }) =>
|
||||
copied &&
|
||||
css`
|
||||
color: var(--color-positive);
|
||||
color: var(--color-success);
|
||||
`}
|
||||
`;
|
||||
|
||||
@@ -96,7 +96,7 @@ Styled.IconButton = styled(IconButton)<{ copied: boolean }>`
|
||||
copied &&
|
||||
css`
|
||||
svg {
|
||||
color: var(--color-positive);
|
||||
color: var(--color-success);
|
||||
}
|
||||
`}
|
||||
`;
|
||||
|
||||
@@ -7,35 +7,50 @@ import { StoryWrapper } from '.ladle/components';
|
||||
import styled, { type AnyStyledComponent } from 'styled-components';
|
||||
import { layoutMixins } from '@/styles/layoutMixins';
|
||||
|
||||
export const DetailsStory: Story<Parameters<typeof Details>> = () => (
|
||||
export const DetailsStory: Story<Parameters<typeof Details>[0]> = (args) => (
|
||||
<StoryWrapper>
|
||||
<Styled.Resizable>
|
||||
<Details
|
||||
items={[
|
||||
{
|
||||
key: 'item-1',
|
||||
label: 'Item 1',
|
||||
tooltip: 'leverage',
|
||||
value: 'Value 1',
|
||||
},
|
||||
{
|
||||
key: 'item-2',
|
||||
label: 'Really really really long item name 2',
|
||||
tooltip: 'liquidation-price',
|
||||
value: 'Value 2',
|
||||
},
|
||||
{
|
||||
key: 'item-3',
|
||||
label: 'Item 3',
|
||||
tooltip: 'realized-pnl',
|
||||
value: 'Value 3',
|
||||
},
|
||||
]}
|
||||
/>
|
||||
<Details {...args} />
|
||||
</Styled.Resizable>
|
||||
</StoryWrapper>
|
||||
);
|
||||
|
||||
DetailsStory.args = {
|
||||
items: [
|
||||
{
|
||||
key: 'item-1',
|
||||
label: 'Item 1',
|
||||
tooltip: 'leverage',
|
||||
value: 'Value 1',
|
||||
},
|
||||
{
|
||||
key: 'item-2',
|
||||
label: 'Really really really long item name 2',
|
||||
tooltip: 'liquidation-price',
|
||||
value: 'Value 2',
|
||||
},
|
||||
{
|
||||
key: 'item-3',
|
||||
label: 'Item 3',
|
||||
tooltip: 'realized-pnl',
|
||||
value: 'Value 3',
|
||||
},
|
||||
],
|
||||
showSubitems: false,
|
||||
isLoading: false,
|
||||
withOverflow: false,
|
||||
withSeparators: false,
|
||||
};
|
||||
|
||||
DetailsStory.argTypes = {
|
||||
justifyItems: { options: ['start', 'end'], control: { type: 'select' }, defaultValue: 'start' },
|
||||
layout: {
|
||||
options: ['column', 'row', 'rowColumns', 'grid', 'stackColumn'],
|
||||
control: { type: 'select' },
|
||||
defaultValue: 'column',
|
||||
},
|
||||
};
|
||||
|
||||
const Styled: Record<string, AnyStyledComponent> = {};
|
||||
|
||||
Styled.Resizable = styled.section`
|
||||
|
||||
@@ -133,6 +133,7 @@ const detailsLayoutVariants = {
|
||||
row: css`
|
||||
${layoutMixins.row}
|
||||
align-self: stretch;
|
||||
white-space: nowrap;
|
||||
`,
|
||||
|
||||
rowColumns: css`
|
||||
@@ -159,12 +160,16 @@ const itemLayoutVariants: Record<string, FlattenInterpolation<ThemeProps<any>>>
|
||||
|
||||
${layoutMixins.spacedRow}
|
||||
gap: 0.5rem;
|
||||
align-items: start;
|
||||
padding: 0.5rem 0;
|
||||
|
||||
min-height: var(--details-item-height);
|
||||
|
||||
> :last-child {
|
||||
align-self: stretch;
|
||||
> :first-child > abbr {
|
||||
min-width: auto;
|
||||
}
|
||||
|
||||
> :last-child {
|
||||
${layoutMixins.row}
|
||||
${layoutMixins.stickyRight}
|
||||
|
||||
@@ -217,8 +222,6 @@ Styled.Details = styled.dl<{
|
||||
--details-grid-numColumns: 2;
|
||||
|
||||
${({ layout }) => layout && detailsLayoutVariants[layout]}
|
||||
|
||||
white-space: nowrap;
|
||||
`;
|
||||
|
||||
Styled.Item = styled.div<{
|
||||
@@ -231,7 +234,7 @@ Styled.Item = styled.div<{
|
||||
${({ justifyItems }) =>
|
||||
justifyItems === 'end' &&
|
||||
css`
|
||||
&:nth-child(even) {
|
||||
> :nth-child(even) {
|
||||
justify-items: end;
|
||||
text-align: end;
|
||||
}
|
||||
@@ -243,6 +246,7 @@ Styled.Item = styled.div<{
|
||||
{
|
||||
column: css`
|
||||
&:not(:hover) > :first-child {
|
||||
white-space: nowrap;
|
||||
overflow-x: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ export const DetailsDialog = ({ slotIcon, title, items, slotFooter, setIsOpen }:
|
||||
placement={isTablet ? DialogPlacement.Default : DialogPlacement.Sidebar}
|
||||
>
|
||||
<Styled.Content>
|
||||
<Styled.Details withSeparators items={items} />
|
||||
<Styled.Details withSeparators justifyItems="end" items={items} />
|
||||
|
||||
<Styled.Footer>{slotFooter}</Styled.Footer>
|
||||
</Styled.Content>
|
||||
|
||||
@@ -14,7 +14,7 @@ export const DiffArrowStory: Story<DiffArrowProps> = (args) => (
|
||||
|
||||
DiffArrowStory.argTypes = {
|
||||
direction: {
|
||||
options: ['left', 'right'],
|
||||
options: ['left', 'right', 'up', 'down'],
|
||||
control: { type: 'select' },
|
||||
defaultValue: 'right',
|
||||
},
|
||||
|
||||
@@ -10,7 +10,7 @@ type ElementProps = {
|
||||
|
||||
type StyleProps = {
|
||||
className?: string;
|
||||
direction?: 'right' | 'left';
|
||||
direction?: 'right' | 'left' | 'up' | 'down';
|
||||
};
|
||||
|
||||
export type DiffArrowProps = ElementProps & StyleProps;
|
||||
@@ -57,5 +57,11 @@ Styled.DiffArrowContainer = styled.span<DiffArrowProps>`
|
||||
left: css`
|
||||
transform: scaleX(-1);
|
||||
`,
|
||||
up: css`
|
||||
transform: rotate(-90deg);
|
||||
`,
|
||||
down: css`
|
||||
transform: rotate(90deg);
|
||||
`,
|
||||
}[direction || 'right'])}
|
||||
`;
|
||||
|
||||
@@ -75,7 +75,7 @@ Styled.DiffValue = styled.div<{ hasInvalidNewValue?: boolean }>`
|
||||
${({ hasInvalidNewValue }) =>
|
||||
hasInvalidNewValue &&
|
||||
css`
|
||||
color: var(--color-negative);
|
||||
color: var(--color-error);
|
||||
`}
|
||||
`;
|
||||
|
||||
|
||||
@@ -35,8 +35,8 @@ export const DropdownHeaderMenu = <MenuItemValue extends string>({
|
||||
<Root>
|
||||
<Styled.Trigger className={className} asChild>
|
||||
<div>
|
||||
{children}
|
||||
<Styled.DropdownIconButton iconName={IconName.Caret} isToggle />
|
||||
{children}
|
||||
<Styled.DropdownIconButton iconName={IconName.Caret} isToggle />
|
||||
</div>
|
||||
</Styled.Trigger>
|
||||
<Portal>
|
||||
@@ -87,7 +87,7 @@ Styled.Trigger = styled(Trigger)`
|
||||
outline: none;
|
||||
|
||||
:hover {
|
||||
filter: brightness(1.1);
|
||||
filter: brightness(var(--hover-filter-base));
|
||||
}
|
||||
`;
|
||||
|
||||
|
||||
@@ -4,38 +4,43 @@ import { DropdownMenu } from '@/components/DropdownMenu';
|
||||
|
||||
import { StoryWrapper } from '.ladle/components';
|
||||
|
||||
export const DropdownMenuStory: Story<Parameters<typeof DropdownMenu>> = (args) => {
|
||||
const exampleItems = [
|
||||
{
|
||||
value: '1',
|
||||
label: 'Item 1',
|
||||
onSelect: () => alert('Item 1 action'),
|
||||
},
|
||||
{
|
||||
value: '2',
|
||||
label: 'Item 2',
|
||||
onSelect: () => alert('Item 2 action'),
|
||||
},
|
||||
{
|
||||
value: '3',
|
||||
label: 'Item 3',
|
||||
onSelect: () => alert('Item 3 action'),
|
||||
},
|
||||
];
|
||||
|
||||
export const DropdownMenuStory: Story<Parameters<typeof DropdownMenu>[0]> = (args) => {
|
||||
return (
|
||||
<StoryWrapper>
|
||||
<DropdownMenu
|
||||
{...args}
|
||||
items={exampleItems}
|
||||
>
|
||||
<DropdownMenu {...args}>
|
||||
<span>Menu</span>
|
||||
</DropdownMenu>
|
||||
</StoryWrapper>
|
||||
);
|
||||
};
|
||||
|
||||
DropdownMenuStory.args = {};
|
||||
DropdownMenuStory.args = {
|
||||
items: [
|
||||
{
|
||||
value: '0',
|
||||
label: 'Item 0',
|
||||
onSelect: () => alert('Item 0 action'),
|
||||
},
|
||||
{
|
||||
value: '1',
|
||||
label: 'Item 1 (accent)',
|
||||
onSelect: () => alert('Item 1 action'),
|
||||
highlightColor: 'accent',
|
||||
},
|
||||
{
|
||||
value: '2',
|
||||
label: 'Item 2 (create)',
|
||||
onSelect: () => alert('Item 2 action'),
|
||||
highlightColor: 'create',
|
||||
},
|
||||
{
|
||||
value: '3',
|
||||
label: 'Item 3 (destroy)',
|
||||
onSelect: () => alert('Item 3 action'),
|
||||
highlightColor: 'destroy',
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
DropdownMenuStory.argTypes = {
|
||||
align: {
|
||||
|
||||
@@ -13,7 +13,7 @@ export type DropdownMenuItem<T> = {
|
||||
label: React.ReactNode;
|
||||
onSelect?: () => void;
|
||||
separator?: boolean;
|
||||
highlightColor?: 'accent' | 'positive' | 'negative';
|
||||
highlightColor?: 'accent' | 'create' | 'destroy';
|
||||
};
|
||||
|
||||
type StyleProps = {
|
||||
@@ -82,7 +82,7 @@ Styled.Separator = styled(Separator)`
|
||||
margin: 0.25rem 1rem;
|
||||
`;
|
||||
|
||||
Styled.Item = styled(Item)<{ $highlightColor: 'accent' | 'positive' | 'negative' }>`
|
||||
Styled.Item = styled(Item)<{ $highlightColor: 'accent' | 'create' | 'destroy' }>`
|
||||
${popoverMixins.item}
|
||||
--item-font-size: var(--dropdownMenu-item-font-size);
|
||||
${({ $highlightColor }) =>
|
||||
@@ -90,11 +90,11 @@ Styled.Item = styled(Item)<{ $highlightColor: 'accent' | 'positive' | 'negative'
|
||||
['accent']: `
|
||||
--item-highlighted-textColor: var(--color-accent);
|
||||
`,
|
||||
['positive']: `
|
||||
--item-highlighted-textColor: var(--color-positive);
|
||||
['create']: `
|
||||
--item-highlighted-textColor: var(--color-green);
|
||||
`,
|
||||
['negative']: `
|
||||
--item-highlighted-textColor: var(--color-negative);
|
||||
['destroy']: `
|
||||
--item-highlighted-textColor: var(--color-red);
|
||||
`,
|
||||
}[$highlightColor])}
|
||||
|
||||
|
||||
@@ -28,21 +28,22 @@ const exampleItems = [
|
||||
},
|
||||
];
|
||||
|
||||
export const DropdownSelectMenuStory: Story<Parameters<typeof DropdownSelectMenu>> = (args) => {
|
||||
export const DropdownSelectMenuStory: Story<
|
||||
Pick<Parameters<typeof DropdownSelectMenu>[0], 'items' | 'align' | 'sideOffset' | 'disabled'>
|
||||
> = (args) => {
|
||||
const [item, setItem] = useState(exampleItems[0].value);
|
||||
return (
|
||||
<StoryWrapper>
|
||||
<DropdownSelectMenu
|
||||
items={exampleItems}
|
||||
value={item}
|
||||
onValueChange={(value) => setItem(value)}
|
||||
{...args}
|
||||
/>
|
||||
<DropdownSelectMenu value={item} onValueChange={(value) => setItem(value)} {...args} />
|
||||
</StoryWrapper>
|
||||
);
|
||||
};
|
||||
|
||||
DropdownSelectMenuStory.args = {};
|
||||
DropdownSelectMenuStory.args = {
|
||||
items: exampleItems,
|
||||
sideOffset: 1,
|
||||
disabled: false,
|
||||
};
|
||||
|
||||
DropdownSelectMenuStory.argTypes = {
|
||||
align: {
|
||||
|
||||
@@ -32,7 +32,7 @@ export const FormInput = forwardRef<HTMLInputElement, FormInputProps>(
|
||||
isValidationAttached={validationConfig?.attached}
|
||||
>
|
||||
<Styled.InputContainer hasSlotRight={!!slotRight}>
|
||||
<Styled.WithLabel label={label} inputID={id}>
|
||||
<Styled.WithLabel label={label} inputID={id} disabled={otherProps?.disabled}>
|
||||
<Input ref={ref} id={id} {...otherProps} />
|
||||
</Styled.WithLabel>
|
||||
{slotRight}
|
||||
@@ -85,11 +85,11 @@ Styled.InputContainer = styled.div<{ hasSlotRight?: boolean }>`
|
||||
`}
|
||||
`;
|
||||
|
||||
Styled.WithLabel = styled(WithLabel)`
|
||||
Styled.WithLabel = styled(WithLabel)<{ disabled?: boolean }>`
|
||||
${formMixins.inputLabel}
|
||||
|
||||
label {
|
||||
cursor: text;
|
||||
${({ disabled }) => !disabled && 'cursor: text;'}
|
||||
padding: var(--form-input-paddingY) var(--form-input-paddingX) 0;
|
||||
}
|
||||
`;
|
||||
|
||||
@@ -4,7 +4,7 @@ import { Icon, IconName } from '@/components/Icon';
|
||||
|
||||
import { StoryWrapper } from '.ladle/components';
|
||||
|
||||
export const IconStory: Story<Parameters<typeof Icon>> = (args) => {
|
||||
export const IconStory: Story<Parameters<typeof Icon>[0]> = (args) => {
|
||||
return (
|
||||
<StoryWrapper>
|
||||
<Icon {...args} />
|
||||
|
||||
@@ -13,6 +13,7 @@ import {
|
||||
CaretIcon,
|
||||
CautionCircleStrokeIcon,
|
||||
CautionCircleIcon,
|
||||
ChaosLabsIcon,
|
||||
ChatIcon,
|
||||
CheckIcon,
|
||||
CheckCircleIcon,
|
||||
@@ -24,7 +25,7 @@ import {
|
||||
CoinsIcon,
|
||||
CommentIcon,
|
||||
CopyIcon,
|
||||
CubeIcon,
|
||||
CurrencySignIcon,
|
||||
DepositIcon,
|
||||
DepthChartIcon,
|
||||
DiscordIcon,
|
||||
@@ -35,6 +36,7 @@ import {
|
||||
FundingChartIcon,
|
||||
GearIcon,
|
||||
GiftboxIcon,
|
||||
GovernanceIcon,
|
||||
HelpCircleIcon,
|
||||
HideIcon,
|
||||
HistoryIcon,
|
||||
@@ -45,6 +47,7 @@ import {
|
||||
MenuIcon,
|
||||
MigrateIcon,
|
||||
MintscanIcon,
|
||||
MoonIcon,
|
||||
OrderbookIcon,
|
||||
OrderCanceledIcon,
|
||||
OrderFilledIcon,
|
||||
@@ -60,13 +63,16 @@ import {
|
||||
PriceChartIcon,
|
||||
PrivacyIcon,
|
||||
QrIcon,
|
||||
RewardStarIcon,
|
||||
SearchIcon,
|
||||
SendIcon,
|
||||
ShareIcon,
|
||||
ShowIcon,
|
||||
TogglesMenuIcon,
|
||||
StarIcon,
|
||||
SunIcon,
|
||||
TerminalIcon,
|
||||
TokenIcon,
|
||||
TradeIcon,
|
||||
TransferIcon,
|
||||
TriangleIcon,
|
||||
@@ -88,6 +94,7 @@ export enum IconName {
|
||||
Caret = 'Caret',
|
||||
CautionCircle = 'CautionCircle',
|
||||
CautionCircleStroked = 'CautionCircleStroked',
|
||||
ChaosLabs = 'ChaosLabs',
|
||||
Chat = 'Chat',
|
||||
Check = 'Check',
|
||||
CheckCircle = 'CheckCircle',
|
||||
@@ -99,7 +106,7 @@ export enum IconName {
|
||||
Coins = 'Coins',
|
||||
Comment = 'Comment',
|
||||
Copy = 'Copy',
|
||||
Cube = 'Cube',
|
||||
CurrencySign = 'CurrencySign',
|
||||
Deposit = 'Deposit',
|
||||
DepthChart = 'DepthChart',
|
||||
Discord = 'Discord',
|
||||
@@ -110,6 +117,7 @@ export enum IconName {
|
||||
FundingChart = 'FundingChart',
|
||||
Gear = 'Gear',
|
||||
Giftbox = 'Giftbox',
|
||||
Governance = 'Governance',
|
||||
HelpCircle = 'HelpCircle',
|
||||
Hide = 'Hide',
|
||||
History = 'History',
|
||||
@@ -120,6 +128,7 @@ export enum IconName {
|
||||
Menu = 'Menu',
|
||||
Migrate = 'Migrate',
|
||||
Mintscan = 'Mintscan',
|
||||
Moon = 'Moon',
|
||||
Onboarding = 'Onboarding',
|
||||
Orderbook = 'OrderbookIcon',
|
||||
OrderCanceled = 'OrderCanceled',
|
||||
@@ -136,13 +145,16 @@ export enum IconName {
|
||||
PriceChart = 'PriceChart',
|
||||
Privacy = 'Privacy',
|
||||
Qr = 'Qr',
|
||||
RewardStar = 'RewardStar',
|
||||
Search = 'Search',
|
||||
Send = 'Send',
|
||||
Share = 'Share',
|
||||
Show = 'Show',
|
||||
Star = 'Star',
|
||||
Sun = 'Sun',
|
||||
Terminal = 'Terminal',
|
||||
TogglesMenu = 'TogglesMenu',
|
||||
Token = 'Token',
|
||||
Trade = 'Trade',
|
||||
Transfer = 'Transfer',
|
||||
Triangle = 'Triangle',
|
||||
@@ -164,6 +176,7 @@ const icons = {
|
||||
[IconName.Caret]: CaretIcon,
|
||||
[IconName.CautionCircle]: CautionCircleIcon,
|
||||
[IconName.CautionCircleStroked]: CautionCircleStrokeIcon,
|
||||
[IconName.ChaosLabs]: ChaosLabsIcon,
|
||||
[IconName.Chat]: ChatIcon,
|
||||
[IconName.Check]: CheckIcon,
|
||||
[IconName.CheckCircle]: CheckCircleIcon,
|
||||
@@ -175,7 +188,7 @@ const icons = {
|
||||
[IconName.Coins]: CoinsIcon,
|
||||
[IconName.Comment]: CommentIcon,
|
||||
[IconName.Copy]: CopyIcon,
|
||||
[IconName.Cube]: CubeIcon,
|
||||
[IconName.CurrencySign]: CurrencySignIcon,
|
||||
[IconName.Deposit]: DepositIcon,
|
||||
[IconName.DepthChart]: DepthChartIcon,
|
||||
[IconName.Discord]: DiscordIcon,
|
||||
@@ -186,6 +199,7 @@ const icons = {
|
||||
[IconName.FundingChart]: FundingChartIcon,
|
||||
[IconName.Gear]: GearIcon,
|
||||
[IconName.Giftbox]: GiftboxIcon,
|
||||
[IconName.Governance]: GovernanceIcon,
|
||||
[IconName.HelpCircle]: HelpCircleIcon,
|
||||
[IconName.Hide]: HideIcon,
|
||||
[IconName.History]: HistoryIcon,
|
||||
@@ -196,6 +210,7 @@ const icons = {
|
||||
[IconName.Menu]: MenuIcon,
|
||||
[IconName.Migrate]: MigrateIcon,
|
||||
[IconName.Mintscan]: MintscanIcon,
|
||||
[IconName.Moon]: MoonIcon,
|
||||
[IconName.Orderbook]: OrderbookIcon,
|
||||
[IconName.OrderCanceled]: OrderCanceledIcon,
|
||||
[IconName.OrderFilled]: OrderFilledIcon,
|
||||
@@ -211,13 +226,16 @@ const icons = {
|
||||
[IconName.PriceChart]: PriceChartIcon,
|
||||
[IconName.Privacy]: PrivacyIcon,
|
||||
[IconName.Qr]: QrIcon,
|
||||
[IconName.RewardStar]: RewardStarIcon,
|
||||
[IconName.Search]: SearchIcon,
|
||||
[IconName.Send]: SendIcon,
|
||||
[IconName.Share]: ShareIcon,
|
||||
[IconName.Show]: ShowIcon,
|
||||
[IconName.Star]: StarIcon,
|
||||
[IconName.Sun]: SunIcon,
|
||||
[IconName.Terminal]: TerminalIcon,
|
||||
[IconName.TogglesMenu]: TogglesMenuIcon,
|
||||
[IconName.Token]: TokenIcon,
|
||||
[IconName.Trade]: TradeIcon,
|
||||
[IconName.Transfer]: TransferIcon,
|
||||
[IconName.Triangle]: TriangleIcon,
|
||||
|
||||
@@ -6,7 +6,7 @@ import { Link } from '@/components/Link';
|
||||
import { StoryWrapper } from '.ladle/components';
|
||||
import { layoutMixins } from '@/styles/layoutMixins';
|
||||
|
||||
export const LinkStory: Story<Parameters<typeof Link>> = (args) => {
|
||||
export const LinkStory: Story<Parameters<typeof Link>[0]> = (args) => {
|
||||
return (
|
||||
<StoryWrapper>
|
||||
<Styled.Container>
|
||||
|
||||
@@ -11,6 +11,7 @@ export const LoadingSpinner: React.FC<{
|
||||
return (
|
||||
<Styled.Spinner className={className}>
|
||||
<Styled.LoadingSpinnerSvg
|
||||
id={id}
|
||||
width="38"
|
||||
height="38"
|
||||
viewBox="0 0 38 38"
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import styled, { type AnyStyledComponent } from 'styled-components';
|
||||
|
||||
import { RiskLevels } from '@/constants/abacus';
|
||||
import { UsageColorFromRiskLevel } from '@/styles/colors';
|
||||
|
||||
import { Ring } from '@/components/Ring';
|
||||
|
||||
import { abacusHelper } from '@/lib/abacus';
|
||||
import { UsageColorFromRiskLevel } from '@/lib/styles';
|
||||
|
||||
type ElementProps = {
|
||||
value: number;
|
||||
|
||||
@@ -5,8 +5,24 @@ import { HashRouter } from 'react-router-dom';
|
||||
|
||||
import { StoryWrapper } from '.ladle/components';
|
||||
|
||||
export const NavigationMenuStory: Story<Parameters<typeof NavigationMenu>> = (args) => {
|
||||
const exampleItems = [
|
||||
export const NavigationMenuStory: Story<
|
||||
Pick<Parameters<typeof NavigationMenu>[0], 'items' | 'orientation' | 'submenuPlacement'>
|
||||
> = (args) => {
|
||||
return (
|
||||
<StoryWrapper>
|
||||
<HashRouter
|
||||
children={
|
||||
<NavigationMenu {...args}>
|
||||
<span>Menu</span>
|
||||
</NavigationMenu>
|
||||
}
|
||||
/>
|
||||
</StoryWrapper>
|
||||
);
|
||||
};
|
||||
|
||||
NavigationMenuStory.args = {
|
||||
items: [
|
||||
{
|
||||
group: 'navigation',
|
||||
groupLabel: 'Views',
|
||||
@@ -93,23 +109,9 @@ export const NavigationMenuStory: Story<Parameters<typeof NavigationMenu>> = (ar
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<StoryWrapper>
|
||||
<HashRouter
|
||||
children={
|
||||
<NavigationMenu {...args} items={exampleItems}>
|
||||
<span>Menu</span>
|
||||
</NavigationMenu>
|
||||
}
|
||||
/>
|
||||
</StoryWrapper>
|
||||
);
|
||||
],
|
||||
};
|
||||
|
||||
NavigationMenuStory.args = {};
|
||||
|
||||
NavigationMenuStory.argTypes = {
|
||||
orientation: {
|
||||
options: ['vertical', 'horizontal'],
|
||||
|
||||
@@ -65,6 +65,9 @@ type ElementProps = {
|
||||
resolution?: number;
|
||||
stripRelativeWords?: boolean;
|
||||
};
|
||||
timeOptions?: {
|
||||
useUTC?: boolean;
|
||||
};
|
||||
tag?: React.ReactNode;
|
||||
withParentheses?: boolean;
|
||||
locale?: string;
|
||||
@@ -89,6 +92,7 @@ export const Output = ({
|
||||
relativeTimeFormatOptions = {
|
||||
format: 'singleCharacter',
|
||||
},
|
||||
timeOptions,
|
||||
tag,
|
||||
withParentheses,
|
||||
locale = navigator.language || 'en-US',
|
||||
@@ -116,6 +120,7 @@ export const Output = ({
|
||||
{value?.toString() ?? null}
|
||||
|
||||
{tag && <Tag>{tag}</Tag>}
|
||||
{slotRight}
|
||||
</Styled.Text>
|
||||
);
|
||||
}
|
||||
@@ -165,16 +170,21 @@ export const Output = ({
|
||||
if ((typeof value !== 'string' && typeof value !== 'number') || !value) return null;
|
||||
const date = new Date(value);
|
||||
const dateString = {
|
||||
[OutputType.Date]: date.toLocaleString(selectedLocale, { dateStyle: 'medium' }),
|
||||
[OutputType.Date]: date.toLocaleString(selectedLocale, {
|
||||
dateStyle: 'medium',
|
||||
timeZone: timeOptions?.useUTC ? 'UTC' : undefined,
|
||||
}),
|
||||
[OutputType.DateTime]: date.toLocaleString(selectedLocale, {
|
||||
dateStyle: 'short',
|
||||
timeStyle: 'short',
|
||||
timeZone: timeOptions?.useUTC ? 'UTC' : undefined,
|
||||
}),
|
||||
[OutputType.Time]: date.toLocaleString(selectedLocale, {
|
||||
hour12: false,
|
||||
hour: '2-digit',
|
||||
minute: '2-digit',
|
||||
second: '2-digit',
|
||||
timeZone: timeOptions?.useUTC ? 'UTC' : undefined,
|
||||
}),
|
||||
}[type];
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import type { Story } from '@ladle/react';
|
||||
|
||||
import { Panel } from '@/components/Panel';
|
||||
import { Panel, PanelProps } from '@/components/Panel';
|
||||
|
||||
import { StoryWrapper } from '.ladle/components';
|
||||
|
||||
export const PanelStory: Story<{ slotHeader: React.ReactNode, children?: React.ReactNode }> = (args) => {
|
||||
export const PanelStory: Story<PanelProps> = (args) => {
|
||||
return (
|
||||
<StoryWrapper>
|
||||
<Panel {...args} />
|
||||
@@ -13,6 +13,8 @@ export const PanelStory: Story<{ slotHeader: React.ReactNode, children?: React.R
|
||||
};
|
||||
|
||||
PanelStory.args = {
|
||||
slotHeader: 'Header',
|
||||
slotHeaderContent: 'Header',
|
||||
children: 'Content',
|
||||
slotRight: '1️⃣',
|
||||
hasSeparator: true,
|
||||
};
|
||||
|
||||
@@ -6,8 +6,8 @@ import { Icon, IconName } from '@/components/Icon';
|
||||
import { layoutMixins } from '@/styles/layoutMixins';
|
||||
import { breakpoints } from '@/styles';
|
||||
|
||||
type PanelProps = {
|
||||
slotHeaderContent?: string;
|
||||
type ElementProps = {
|
||||
slotHeaderContent?: React.ReactNode;
|
||||
slotHeader?: React.ReactNode;
|
||||
slotRight?: React.ReactNode;
|
||||
children?: React.ReactNode;
|
||||
@@ -16,11 +16,13 @@ type PanelProps = {
|
||||
onClick?: () => void;
|
||||
};
|
||||
|
||||
type PanelStyleProps = {
|
||||
type StyleProps = {
|
||||
className?: string;
|
||||
hasSeparator?: boolean;
|
||||
};
|
||||
|
||||
export type PanelProps = ElementProps & StyleProps;
|
||||
|
||||
export const Panel = ({
|
||||
slotHeaderContent,
|
||||
slotHeader,
|
||||
@@ -31,7 +33,7 @@ export const Panel = ({
|
||||
onClick,
|
||||
hasSeparator,
|
||||
className,
|
||||
}: PanelProps & PanelStyleProps) => (
|
||||
}: PanelProps) => (
|
||||
<Styled.Panel onClick={onClick} className={className}>
|
||||
<Styled.Left>
|
||||
{href ? (
|
||||
|
||||
@@ -11,6 +11,7 @@ type ElementProps = {
|
||||
};
|
||||
|
||||
type StyleProps = {
|
||||
className?: string;
|
||||
hasLogo?: boolean;
|
||||
size?: number;
|
||||
};
|
||||
@@ -18,7 +19,7 @@ type StyleProps = {
|
||||
const DARK_LOGO_MARK_URL = '/logos/logo-mark-dark.svg';
|
||||
const LIGHT_LOGO_MARK_URL = '/logos/logo-mark-light.svg';
|
||||
|
||||
export const QrCode = ({ value, hasLogo, size = 300 }: ElementProps & StyleProps) => {
|
||||
export const QrCode = ({ className, value, hasLogo, size = 300 }: ElementProps & StyleProps) => {
|
||||
const ref = useRef<HTMLDivElement>(null);
|
||||
const appTheme: AppTheme = useSelector(getAppTheme);
|
||||
|
||||
@@ -74,7 +75,7 @@ export const QrCode = ({ value, hasLogo, size = 300 }: ElementProps & StyleProps
|
||||
}
|
||||
}, [appTheme, hasLogo]);
|
||||
|
||||
return <Styled.QrCode ref={ref} />;
|
||||
return <Styled.QrCode className={className} ref={ref} />;
|
||||
};
|
||||
|
||||
const Styled: Record<string, AnyStyledComponent> = {};
|
||||
|
||||
@@ -7,7 +7,7 @@ import { StoryWrapper } from '.ladle/components';
|
||||
import { layoutMixins } from '@/styles/layoutMixins';
|
||||
import { InputType } from './Input';
|
||||
|
||||
export const SearchInputStory: Story<Parameters<typeof SearchInput>> = (args) => (
|
||||
export const SearchInputStory: Story<Parameters<typeof SearchInput>[0]> = (args) => (
|
||||
<StoryWrapper>
|
||||
<Styled.Container>
|
||||
<SearchInput placeholder="Search something..." type={InputType.Search} />
|
||||
|
||||
@@ -6,7 +6,7 @@ import { SearchSelectMenu } from '@/components/SearchSelectMenu';
|
||||
|
||||
import { StoryWrapper } from '.ladle/components';
|
||||
|
||||
export const SearchSelectMenuStory: Story<Parameters<typeof SearchSelectMenu>> = (args) => {
|
||||
export const SearchSelectMenuStory: Story<Parameters<typeof SearchSelectMenu>[0]> = (args) => {
|
||||
const [selectedItem, setSelectedItem] = useState<string>();
|
||||
|
||||
const exampleItems = [
|
||||
@@ -24,10 +24,7 @@ export const SearchSelectMenuStory: Story<Parameters<typeof SearchSelectMenu>> =
|
||||
return (
|
||||
<StoryWrapper>
|
||||
<Container>
|
||||
<SearchSelectMenu
|
||||
{...args}
|
||||
items={exampleItems}
|
||||
>
|
||||
<SearchSelectMenu {...args} items={exampleItems}>
|
||||
{!selectedItem ? <span>Search and Select</span> : <span>{selectedItem}</span>}
|
||||
</SearchSelectMenu>
|
||||
</Container>
|
||||
|
||||
@@ -26,7 +26,7 @@ const exampleItems: { value: string; label: string }[] = [
|
||||
},
|
||||
];
|
||||
|
||||
export const SelectMenuStory: Story<Parameters<typeof SelectMenu>> = (args) => {
|
||||
export const SelectMenuStory: Story<Parameters<typeof SelectMenu>[0]> = (args) => {
|
||||
const [value, setValue] = useState(exampleItems[0].value);
|
||||
const [value2, setValue2] = useState(exampleItems[2].value);
|
||||
|
||||
|
||||
@@ -33,17 +33,20 @@ import {
|
||||
|
||||
import { useAsyncList } from 'react-stately';
|
||||
|
||||
import { useBreakpoints } from '@/hooks';
|
||||
import { useBreakpoints, useStringGetter } from '@/hooks';
|
||||
import { MediaQueryKeys } from '@/hooks/useBreakpoints';
|
||||
|
||||
import { Checkbox } from '@/components/Checkbox';
|
||||
|
||||
import { breakpoints } from '@/styles';
|
||||
import { layoutMixins } from '@/styles/layoutMixins';
|
||||
import { CaretIcon } from '@/icons';
|
||||
|
||||
import { STRING_KEYS } from '@/constants/localization';
|
||||
|
||||
import { MustBigNumber } from '@/lib/numbers';
|
||||
|
||||
import { Icon, IconName } from './Icon';
|
||||
import { Tag } from './Tag';
|
||||
import { MustBigNumber } from '@/lib/numbers';
|
||||
import { Button } from './Button';
|
||||
|
||||
export { TableCell } from './Table/TableCell';
|
||||
export { TableColumnHeader } from './Table/TableColumnHeader';
|
||||
@@ -80,7 +83,7 @@ export type ColumnDef<TableRowData extends object> = {
|
||||
width?: ColumnSize;
|
||||
};
|
||||
|
||||
type ElementProps<TableRowData extends object | CustomRowConfig, TableRowKey extends Key> = {
|
||||
export type ElementProps<TableRowData extends object | CustomRowConfig, TableRowKey extends Key> = {
|
||||
label?: string;
|
||||
columns: ColumnDef<TableRowData>[];
|
||||
data: TableRowData[];
|
||||
@@ -92,6 +95,10 @@ type ElementProps<TableRowData extends object | CustomRowConfig, TableRowKey ext
|
||||
selectionBehavior?: 'replace' | 'toggle';
|
||||
onRowAction?: (key: TableRowKey, row: TableRowData) => void;
|
||||
slotEmpty?: React.ReactNode;
|
||||
viewMoreConfig?: {
|
||||
initialNumRowsToShow: number;
|
||||
numRowsPerPage?: number;
|
||||
};
|
||||
// collection: TableCollection<string>;
|
||||
// children: React.ReactNode;
|
||||
};
|
||||
@@ -121,6 +128,7 @@ export const Table = <TableRowData extends object, TableRowKey extends Key>({
|
||||
selectionMode = 'single',
|
||||
selectionBehavior = 'toggle',
|
||||
slotEmpty,
|
||||
viewMoreConfig,
|
||||
// shouldRowRender,
|
||||
|
||||
// collection,
|
||||
@@ -136,6 +144,18 @@ export const Table = <TableRowData extends object, TableRowKey extends Key>({
|
||||
style,
|
||||
}: ElementProps<TableRowData, TableRowKey> & StyleProps) => {
|
||||
const [selectedKeys, setSelectedKeys] = useState(new Set<TableRowKey>());
|
||||
const [numRowsToShow, setNumRowsToShow] = useState(viewMoreConfig?.initialNumRowsToShow);
|
||||
const enableViewMore = viewMoreConfig !== undefined;
|
||||
|
||||
const onViewMoreClick = () => {
|
||||
if (!viewMoreConfig) return;
|
||||
const { numRowsPerPage } = viewMoreConfig;
|
||||
if (numRowsPerPage) {
|
||||
setNumRowsToShow((prev) => (prev ?? 0) + numRowsPerPage);
|
||||
} else {
|
||||
setNumRowsToShow(data.length);
|
||||
}
|
||||
};
|
||||
|
||||
const currentBreakpoints = useBreakpoints();
|
||||
const shownColumns = columns.filter(
|
||||
@@ -209,6 +229,10 @@ export const Table = <TableRowData extends object, TableRowKey extends Key>({
|
||||
onRowAction &&
|
||||
((key: TableRowKey) => onRowAction(key, data.find((row) => getRowKey(row) === key)!))
|
||||
}
|
||||
numColumns={shownColumns.length}
|
||||
onViewMoreClick={
|
||||
enableViewMore && numRowsToShow! < data.length ? onViewMoreClick : undefined
|
||||
}
|
||||
// shouldRowRender={shouldRowRender}
|
||||
hideHeader={hideHeader}
|
||||
withGradientCardRows={withGradientCardRows}
|
||||
@@ -233,7 +257,7 @@ export const Table = <TableRowData extends object, TableRowKey extends Key>({
|
||||
)}
|
||||
</TableHeader>
|
||||
|
||||
<TableBody items={list.items}>
|
||||
<TableBody items={enableViewMore ? list.items.slice(0, numRowsToShow) : list.items}>
|
||||
{(item) => (
|
||||
<Row key={getRowKey(item)}>
|
||||
{(columnKey) => (
|
||||
@@ -267,6 +291,8 @@ const TableRoot = <TableRowData extends object | CustomRowConfig, TableRowKey ex
|
||||
onRowAction?: (key: TableRowKey) => void;
|
||||
// shouldRowRender?: (prevRowData: object, currentRowData: object) => boolean;
|
||||
children: CollectionChildren<TableRowData>;
|
||||
numColumns: number;
|
||||
onViewMoreClick?: () => void;
|
||||
|
||||
hideHeader?: boolean;
|
||||
withGradientCardRows?: boolean;
|
||||
@@ -276,7 +302,7 @@ const TableRoot = <TableRowData extends object | CustomRowConfig, TableRowKey ex
|
||||
withScrollSnapColumns?: boolean;
|
||||
withScrollSnapRows?: boolean;
|
||||
}) => {
|
||||
const { selectionMode, selectionBehavior } = props;
|
||||
const { selectionMode, selectionBehavior, numColumns, onViewMoreClick } = props;
|
||||
|
||||
const state = useTableState<TableRowData>({
|
||||
...props,
|
||||
@@ -337,6 +363,7 @@ const TableRoot = <TableRowData extends object | CustomRowConfig, TableRowKey ex
|
||||
<TableBodyRowGroup
|
||||
withGradientCardRows={props.withGradientCardRows}
|
||||
withInnerBorders={props.withInnerBorders}
|
||||
withOuterBorder={props.withOuterBorder}
|
||||
>
|
||||
{/* {Array.from(collection.getChildren!(collection.body.key), (row) => */}
|
||||
{[...collection.body.childNodes].map((row) =>
|
||||
@@ -382,6 +409,9 @@ const TableRoot = <TableRowData extends object | CustomRowConfig, TableRowKey ex
|
||||
</TableRow>
|
||||
)
|
||||
)}
|
||||
{onViewMoreClick ? (
|
||||
<ViewMoreRow colSpan={numColumns} onClick={onViewMoreClick} />
|
||||
) : undefined}
|
||||
</TableBodyRowGroup>
|
||||
</Styled.Table>
|
||||
);
|
||||
@@ -415,6 +445,7 @@ const TableBodyRowGroup = ({
|
||||
children,
|
||||
withGradientCardRows,
|
||||
withInnerBorders,
|
||||
withOuterBorder,
|
||||
}: { children: React.ReactNode } & StyleProps) => {
|
||||
const { rowGroupProps } = useTableRowGroup();
|
||||
|
||||
@@ -423,6 +454,7 @@ const TableBodyRowGroup = ({
|
||||
{...rowGroupProps}
|
||||
withGradientCardRows={withGradientCardRows}
|
||||
withInnerBorders={withInnerBorders}
|
||||
withOuterBorder={withOuterBorder}
|
||||
>
|
||||
{children}
|
||||
</Styled.Tbody>
|
||||
@@ -489,6 +521,23 @@ const TableColumnHeader = <TableRowData extends object>({
|
||||
);
|
||||
};
|
||||
|
||||
export const ViewMoreRow = ({ colSpan, onClick }: { colSpan: number; onClick: () => void }) => {
|
||||
const stringGetter = useStringGetter();
|
||||
return (
|
||||
<Styled.ViewMoreTr key="viewmore">
|
||||
<Styled.Td
|
||||
colSpan={colSpan}
|
||||
onMouseDown={(e: MouseEvent) => e.preventDefault()}
|
||||
onPointerDown={(e: MouseEvent) => e.preventDefault()}
|
||||
>
|
||||
<Styled.ViewMoreButton slotRight={<CaretIcon />} onClick={onClick}>
|
||||
{stringGetter({ key: STRING_KEYS.VIEW_MORE })}
|
||||
</Styled.ViewMoreButton>
|
||||
</Styled.Td>
|
||||
</Styled.ViewMoreTr>
|
||||
);
|
||||
};
|
||||
|
||||
export const TableRow = <TableRowData extends object>({
|
||||
item,
|
||||
children,
|
||||
@@ -635,6 +684,8 @@ Styled.TableWrapper = styled.div<{
|
||||
--table-lastColumn-cell-align: end; // start | center | end | var(--table-cell-align)
|
||||
--tableCell-padding: 0 1rem;
|
||||
|
||||
--tableViewMore-borderColor: inherit;
|
||||
|
||||
// Rules
|
||||
|
||||
flex: 1;
|
||||
@@ -660,7 +711,7 @@ Styled.Empty = styled.div<{ withOuterBorder: boolean }>`
|
||||
|
||||
justify-items: center;
|
||||
align-content: center;
|
||||
padding: 2rem;
|
||||
padding: 4rem;
|
||||
gap: 0.75em;
|
||||
|
||||
color: var(--color-text-0);
|
||||
@@ -744,7 +795,7 @@ Styled.Tr = styled.tr<{
|
||||
&:focus-visible,
|
||||
&:focus-within {
|
||||
--tableRow-currentBackgroundColor: var(--tableRow-hover-backgroundColor);
|
||||
filter: brightness(1.1);
|
||||
filter: brightness(var(--hover-filter-base));
|
||||
}
|
||||
`};
|
||||
|
||||
@@ -868,6 +919,18 @@ Styled.Tbody = styled.tbody<StyleProps>`
|
||||
--stickyArea2-paddingLeft: var(--border-width);
|
||||
--stickyArea2-paddingRight: var(--border-width);
|
||||
|
||||
tr:first-of-type {
|
||||
box-shadow: 0 calc(var(--border-width)) 0 0 var(--border-color);
|
||||
}
|
||||
`}
|
||||
|
||||
${({ withOuterBorder }) =>
|
||||
withOuterBorder &&
|
||||
css`
|
||||
tr:last-of-type:not(:only-of-type) {
|
||||
box-shadow: 0 calc(-1 * var(--border-width)) 0 0 var(--border-color);
|
||||
}
|
||||
|
||||
tr:first-of-type {
|
||||
box-shadow: none;
|
||||
}
|
||||
@@ -922,3 +985,19 @@ Styled.Row = styled.div`
|
||||
${layoutMixins.inlineRow}
|
||||
padding: var(--tableCell-padding);
|
||||
`;
|
||||
|
||||
Styled.ViewMoreButton = styled(Button)`
|
||||
--button-backgroundColor: var(--color-layer-2);
|
||||
--button-textColor: var(--color-text-1);
|
||||
|
||||
width: 100%;
|
||||
|
||||
svg {
|
||||
width: 0.675rem;
|
||||
margin-left: 0.5ch;
|
||||
}
|
||||
`;
|
||||
|
||||
Styled.ViewMoreTr = styled(Styled.Tr)`
|
||||
--border-color: var(--tableViewMore-borderColor);
|
||||
`;
|
||||
|
||||
@@ -13,29 +13,11 @@ enum TabItem {
|
||||
Item3 = 'Item3',
|
||||
}
|
||||
|
||||
const TabItems = [
|
||||
{
|
||||
value: TabItem.Item1,
|
||||
label: 'Item 1',
|
||||
content: <div>Item 1 Content</div>,
|
||||
},
|
||||
{
|
||||
value: TabItem.Item2,
|
||||
label: 'Item 2',
|
||||
content: <div>Item 2 Content</div>,
|
||||
},
|
||||
{
|
||||
value: TabItem.Item3,
|
||||
label: 'Item 3',
|
||||
content: <div>Item 3 Content</div>,
|
||||
},
|
||||
];
|
||||
|
||||
export const TabsStory: Story<Parameters<typeof Tabs>> = (args) => {
|
||||
export const TabsStory: Story<Parameters<typeof Tabs>[0]> = (args) => {
|
||||
return (
|
||||
<StoryWrapper>
|
||||
<Styled.Container>
|
||||
<Tabs items={TabItems} {...args} />
|
||||
<Tabs {...args} />
|
||||
</Styled.Container>
|
||||
</StoryWrapper>
|
||||
);
|
||||
@@ -43,6 +25,23 @@ export const TabsStory: Story<Parameters<typeof Tabs>> = (args) => {
|
||||
|
||||
TabsStory.args = {
|
||||
fullWidthTabs: false,
|
||||
items: [
|
||||
{
|
||||
value: TabItem.Item1,
|
||||
label: 'Item 1',
|
||||
content: <div>Item 1 Content</div>,
|
||||
},
|
||||
{
|
||||
value: TabItem.Item2,
|
||||
label: 'Item 2',
|
||||
content: <div>Item 2 Content</div>,
|
||||
},
|
||||
{
|
||||
value: TabItem.Item3,
|
||||
label: 'Item 3',
|
||||
content: <div>Item 3 Content</div>,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
TabsStory.argTypes = {
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import type { Story } from '@ladle/react';
|
||||
|
||||
import { Tag } from '@/components/Tag';
|
||||
import { Tag, TagSign, TagSize, TagType } from '@/components/Tag';
|
||||
|
||||
import { StoryWrapper } from '.ladle/components';
|
||||
|
||||
export const TagStory: Story<Parameters<typeof Tag>> = (args) => {
|
||||
export const TagStory: Story<Parameters<typeof Tag>[0]> = (args) => {
|
||||
return (
|
||||
<StoryWrapper>
|
||||
<Tag {...args} />
|
||||
@@ -14,4 +14,28 @@ export const TagStory: Story<Parameters<typeof Tag>> = (args) => {
|
||||
|
||||
TagStory.args = {
|
||||
children: 'USDC',
|
||||
isHighlighted: false,
|
||||
};
|
||||
|
||||
TagStory.argTypes = {
|
||||
size: {
|
||||
options: Object.values(TagSize),
|
||||
control: { type: 'select' },
|
||||
defaultValue: TagSize.Small,
|
||||
},
|
||||
type: {
|
||||
options: [...Object.values(TagType), undefined],
|
||||
control: { type: 'select' },
|
||||
defaultValue: undefined,
|
||||
},
|
||||
sign: {
|
||||
options: [...Object.values(TagSign), undefined],
|
||||
control: { type: 'select' },
|
||||
defaultValue: undefined,
|
||||
},
|
||||
isHighlighted: {
|
||||
options: [true, false],
|
||||
control: { type: 'select' },
|
||||
defaultValue: false,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
import styled, { css } from 'styled-components';
|
||||
|
||||
export enum TagSize {
|
||||
Small,
|
||||
Medium,
|
||||
Small = 'Small',
|
||||
Medium = 'Medium',
|
||||
}
|
||||
|
||||
export enum TagType {
|
||||
Asset,
|
||||
Side,
|
||||
Number,
|
||||
Asset = 'Asset',
|
||||
Side = 'Side',
|
||||
Number = 'Number',
|
||||
}
|
||||
|
||||
export enum TagSign {
|
||||
Positive,
|
||||
Negative,
|
||||
Neutral,
|
||||
Positive = 'Positive',
|
||||
Negative = 'Negative',
|
||||
Neutral = 'Neutral',
|
||||
}
|
||||
|
||||
type StyleProps = {
|
||||
@@ -76,5 +76,6 @@ export const Tag = styled.span<StyleProps>`
|
||||
isHighlighted &&
|
||||
css`
|
||||
background-color: var(--color-accent);
|
||||
color: var(--color-text-button);
|
||||
`}
|
||||
`;
|
||||
|
||||
@@ -8,6 +8,7 @@ import { Button, type ButtonStateConfig, type ButtonProps } from '@/components/B
|
||||
|
||||
type ElementProps = {
|
||||
timeoutInSeconds: number;
|
||||
slotFinal?: ReactNode;
|
||||
} & ButtonProps;
|
||||
|
||||
export type TimeoutButtonProps = ElementProps;
|
||||
@@ -15,6 +16,7 @@ export type TimeoutButtonProps = ElementProps;
|
||||
export const TimeoutButton = ({
|
||||
children,
|
||||
timeoutInSeconds,
|
||||
slotFinal,
|
||||
...otherProps
|
||||
}: TimeoutButtonProps) => {
|
||||
const [timeoutDeadline] = useState(Date.now() + timeoutInSeconds * 1000);
|
||||
@@ -23,6 +25,8 @@ export const TimeoutButton = ({
|
||||
|
||||
const secondsLeft = Math.max(0, (timeoutDeadline - now) / 1000);
|
||||
|
||||
if (slotFinal && secondsLeft <= 0) return slotFinal;
|
||||
|
||||
return (
|
||||
<Button
|
||||
{...otherProps}
|
||||
|
||||
@@ -27,9 +27,8 @@ export const ToastArea = ({ swipeDirection, children, className }: ToastAreaProp
|
||||
const $ToastArea = styled.aside`
|
||||
// Params
|
||||
--toasts-gap: 0.5rem;
|
||||
|
||||
|
||||
// Rules
|
||||
${layoutMixins.scrollArea}
|
||||
z-index: 1;
|
||||
|
||||
pointer-events: none;
|
||||
|
||||
@@ -5,7 +5,7 @@ import { ButtonShape, ButtonSize } from '@/constants/buttons';
|
||||
import { StoryWrapper } from '.ladle/components';
|
||||
import { ToggleButton } from './ToggleButton';
|
||||
|
||||
export const ToggleButtonStory: Story<Parameters<typeof ToggleButton>> = (args) => (
|
||||
export const ToggleButtonStory: Story<Parameters<typeof ToggleButton>[0]> = (args) => (
|
||||
<StoryWrapper>
|
||||
<ToggleButton {...args}>Toggle me</ToggleButton>
|
||||
</StoryWrapper>
|
||||
|
||||
@@ -21,16 +21,22 @@ const ToggleGroupItems = [
|
||||
},
|
||||
];
|
||||
|
||||
export const ToggleGroupStory: Story<Parameters<typeof ToggleGroup>> = (args) => {
|
||||
export const ToggleGroupStory: Story<
|
||||
Pick<Parameters<typeof ToggleGroup>[0], 'items' | 'size' | 'shape'>
|
||||
> = (args) => {
|
||||
const [value, setValue] = useState('0');
|
||||
|
||||
return (
|
||||
<StoryWrapper>
|
||||
<ToggleGroup items={ToggleGroupItems} value={value} onValueChange={setValue} {...args} />
|
||||
<ToggleGroup value={value} onValueChange={setValue} {...args} />
|
||||
</StoryWrapper>
|
||||
);
|
||||
};
|
||||
|
||||
ToggleGroupStory.args = {
|
||||
items: ToggleGroupItems,
|
||||
};
|
||||
|
||||
ToggleGroupStory.argTypes = {
|
||||
size: {
|
||||
options: Object.values(ButtonSize),
|
||||
|
||||
@@ -2,9 +2,9 @@ import styled, { type AnyStyledComponent } from 'styled-components';
|
||||
|
||||
import { type RiskLevels } from '@/constants/abacus';
|
||||
|
||||
import { UsageColorFromRiskLevel } from '@/styles/colors';
|
||||
|
||||
import { abacusHelper } from '@/lib/abacus';
|
||||
import { UsageColorFromRiskLevel } from '@/lib/styles';
|
||||
|
||||
type ElementProps = {
|
||||
value: number;
|
||||
};
|
||||
|
||||
@@ -117,7 +117,7 @@ Styled.ConfirmButton = styled(Styled.IconButton)`
|
||||
--button-backgroundColor: hsla(203, 25%, 19%, 1);
|
||||
|
||||
svg {
|
||||
color: var(--color-positive);
|
||||
color: var(--color-green);
|
||||
}
|
||||
`;
|
||||
|
||||
@@ -125,7 +125,7 @@ Styled.CancelButton = styled(Styled.IconButton)`
|
||||
--button-backgroundColor: hsla(296, 16%, 18%, 1);
|
||||
|
||||
svg {
|
||||
color: var(--color-negative);
|
||||
color: var(--color-red);
|
||||
width: 0.8em;
|
||||
height: 0.8em;
|
||||
|
||||
|
||||
@@ -40,5 +40,5 @@ Styled.Details = styled(Details)`
|
||||
|
||||
padding: 0.375rem 0.75rem 0.25rem;
|
||||
|
||||
font-size: 0.8125em;
|
||||
font-size: var(--details-item-fontSize, 0.8125em);
|
||||
`;
|
||||
|
||||
@@ -9,7 +9,7 @@ import { StoryWrapper } from '.ladle/components';
|
||||
import styled, { type AnyStyledComponent } from 'styled-components';
|
||||
import { layoutMixins } from '@/styles/layoutMixins';
|
||||
|
||||
export const WithLabelStory: Story<Parameters<typeof WithLabel>> = (args) => {
|
||||
export const WithLabelStory: Story<Parameters<typeof WithLabel>[0]> = (args) => {
|
||||
const [firstName, setFirstName] = useState('');
|
||||
const [lastName, setLastName] = useState('');
|
||||
|
||||
|
||||
@@ -3,32 +3,29 @@ import type { Story } from '@ladle/react';
|
||||
import { Button } from '@/components/Button';
|
||||
|
||||
import { WithReceipt } from '@/components/WithReceipt';
|
||||
import { type DetailsItem } from './Details';
|
||||
|
||||
import { StoryWrapper } from '.ladle/components';
|
||||
|
||||
const items: DetailsItem[] = [
|
||||
{
|
||||
key: 'item-1',
|
||||
label: 'Item 1',
|
||||
value: 'Value 1',
|
||||
},
|
||||
{
|
||||
key: 'item-2',
|
||||
label: 'Item 2',
|
||||
value: 'Value 2',
|
||||
},
|
||||
{
|
||||
key: 'item-3',
|
||||
label: 'Item 3',
|
||||
value: 'Value 3',
|
||||
},
|
||||
];
|
||||
|
||||
export const WithReceiptStory: Story<Parameters<WithReceipt>> = (args) => (
|
||||
export const WithReceiptStory: Story<Omit<Parameters<typeof WithReceipt>[0], 'slotReceipt'>> = (
|
||||
args
|
||||
) => (
|
||||
<StoryWrapper>
|
||||
<div style={{ width: 200 }}>
|
||||
<WithReceipt {...args}>
|
||||
<WithReceipt
|
||||
slotReceipt={
|
||||
<div
|
||||
style={{
|
||||
padding: '1rem',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
}}
|
||||
>
|
||||
Receipt Content
|
||||
</div>
|
||||
}
|
||||
{...args}
|
||||
>
|
||||
<Button>Hello there</Button>
|
||||
</WithReceipt>
|
||||
</div>
|
||||
@@ -36,7 +33,7 @@ export const WithReceiptStory: Story<Parameters<WithReceipt>> = (args) => (
|
||||
);
|
||||
|
||||
WithReceiptStory.args = {
|
||||
items,
|
||||
hideReceipt: false,
|
||||
};
|
||||
|
||||
WithReceiptStory.argTypes = {
|
||||
|
||||
@@ -106,8 +106,6 @@ Styled.Container = styled.div`
|
||||
--stickyArea1-leftGap: var(--border-width);
|
||||
min-height: var(--stickyArea-height);
|
||||
|
||||
${layoutMixins.withOuterAndInnerBorders}
|
||||
|
||||
display: grid;
|
||||
grid-template: var(--withSidebar-gridTemplate);
|
||||
`;
|
||||
@@ -120,6 +118,7 @@ Styled.Side = styled.aside`
|
||||
${layoutMixins.sticky}
|
||||
max-height: var(--stickyArea-height);
|
||||
backdrop-filter: none;
|
||||
background-color: var(--color-layer-2);
|
||||
|
||||
${layoutMixins.stack}
|
||||
`;
|
||||
|
||||
@@ -6,7 +6,7 @@ import { tooltipStrings } from '@/constants/tooltips';
|
||||
|
||||
import { StoryWrapper } from '.ladle/components';
|
||||
|
||||
export const Tooltip: Story<Parameters<typeof WithTooltip>> = (args) => {
|
||||
export const Tooltip: Story<Parameters<typeof WithTooltip>[0]> = (args) => {
|
||||
return (
|
||||
<StoryWrapper>
|
||||
<WithTooltip {...args}>
|
||||
|
||||
@@ -110,12 +110,7 @@ Styled.Abbr = styled.abbr`
|
||||
|
||||
Styled.Content = styled(Content)`
|
||||
--tooltip-backgroundColor: var(--color-layer-4);
|
||||
--tooltip-backgroundColor: hsl(
|
||||
var(--layer-base-hue),
|
||||
var(--layer-base-saturation),
|
||||
calc(var(--layer-base-lightness) + 4%),
|
||||
0.66
|
||||
);
|
||||
--tooltip-backgroundColor: ${({ theme }) => theme.tooltipBackground};
|
||||
|
||||
${popoverMixins.popover}
|
||||
--popover-backgroundColor: var(--tooltip-backgroundColor);
|
||||
|
||||
@@ -27,12 +27,7 @@ Styled.TooltipContent = styled.aside<{ accentColor?: string }>`
|
||||
|
||||
${popoverMixins.popover}
|
||||
--popover-radius: 0.5rem;
|
||||
--popover-background-color: hsl(
|
||||
var(--layer-base-hue),
|
||||
var(--layer-base-saturation),
|
||||
calc(var(--layer-base-lightness)),
|
||||
0.9
|
||||
);
|
||||
--popover-background-color: ${({ theme }) => theme.popoverBackground};
|
||||
--popover-backdrop-filter: saturate(120%) blur(12px);
|
||||
|
||||
display: grid;
|
||||
|
||||
@@ -1,26 +1,33 @@
|
||||
import React, { useContext, useState } from 'react';
|
||||
import React, { PropsWithChildren, useContext, useState } from 'react';
|
||||
|
||||
import { Point } from '@visx/point';
|
||||
import { localPoint } from '@visx/event';
|
||||
import { XYChart, DataContext } from '@visx/xychart';
|
||||
import { XYChart, DataContext, type EventHandlerParams } from '@visx/xychart';
|
||||
import { getScaleBandwidth } from '@/components/visx/getScaleBandwidth';
|
||||
|
||||
export const XYChartWithPointerEvents = ({
|
||||
onPointerMove, onPointerUp, onPointerPressedChange, ...props
|
||||
onPointerMove,
|
||||
onPointerUp,
|
||||
onPointerPressedChange,
|
||||
...props
|
||||
}: {
|
||||
onPointerMove?: (point: Point) => void;
|
||||
onPointerUp?: (point: Point) => void;
|
||||
onPointerMove?: (point: Point | EventHandlerParams<object>) => void;
|
||||
onPointerUp?: (point: Point | EventHandlerParams<object>) => void;
|
||||
onPointerPressedChange?: (isPointerPressed: boolean) => void;
|
||||
} & React.PropsWithChildren<Parameters<typeof XYChart>>) => {
|
||||
} & PropsWithChildren<Parameters<typeof XYChart>[0]>) => {
|
||||
const { xScale, yScale } = useContext(DataContext);
|
||||
|
||||
const [lastPointerMoveEvent, setLastPointerMoveEvent] = useState<React.PointerEvent>();
|
||||
|
||||
const pointerContainerPosition = lastPointerMoveEvent ? localPoint(lastPointerMoveEvent) : null;
|
||||
|
||||
const pointerChartPosition = xScale && yScale && pointerContainerPosition &&
|
||||
const pointerChartPosition =
|
||||
xScale &&
|
||||
yScale &&
|
||||
pointerContainerPosition &&
|
||||
new Point({
|
||||
// @ts-expect-error invert supposedly doesn't exist on AxisScale
|
||||
x: xScale.invert(pointerContainerPosition?.x - getScaleBandwidth(xScale) / 2),
|
||||
// @ts-expect-error invert supposedly doesn't exist on AxisScale
|
||||
y: yScale.invert(pointerContainerPosition?.y - getScaleBandwidth(yScale) / 2),
|
||||
});
|
||||
|
||||
@@ -29,15 +36,13 @@ export const XYChartWithPointerEvents = ({
|
||||
{...props}
|
||||
onPointerMove={({ event }) => {
|
||||
setLastPointerMoveEvent(event as React.PointerEvent);
|
||||
if (pointerChartPosition)
|
||||
onPointerMove?.(pointerChartPosition);
|
||||
if (pointerChartPosition) onPointerMove?.(pointerChartPosition);
|
||||
}}
|
||||
onPointerOut={() => setLastPointerMoveEvent(undefined)}
|
||||
onPointerDown={() => onPointerPressedChange?.(true)}
|
||||
onPointerUp={() => {
|
||||
onPointerPressedChange?.(false);
|
||||
if (pointerChartPosition)
|
||||
onPointerUp?.(pointerChartPosition);
|
||||
if (pointerChartPosition) onPointerUp?.(pointerChartPosition);
|
||||
}}
|
||||
>
|
||||
{props.children}
|
||||
|
||||
@@ -119,6 +119,13 @@ export const InputSelectionOption = Abacus.exchange.dydx.abacus.output.input.Sel
|
||||
// ------ Wallet ------ //
|
||||
export type Wallet = Abacus.exchange.dydx.abacus.output.Wallet;
|
||||
export type AccountBalance = Abacus.exchange.dydx.abacus.output.AccountBalance;
|
||||
export type TradingRewards = Abacus.exchange.dydx.abacus.output.TradingRewards;
|
||||
export type HistoricalTradingReward = Abacus.exchange.dydx.abacus.output.HistoricalTradingReward;
|
||||
export const HistoricalTradingRewardsPeriod =
|
||||
Abacus.exchange.dydx.abacus.state.manager.HistoricalTradingRewardsPeriod;
|
||||
const historicalTradingRewardsPeriod = [...HistoricalTradingRewardsPeriod.values()] as const;
|
||||
export type HistoricalTradingRewardsPeriods = (typeof historicalTradingRewardsPeriod)[number];
|
||||
|
||||
export type Subaccount = Abacus.exchange.dydx.abacus.output.Subaccount;
|
||||
export type SubaccountPosition = Abacus.exchange.dydx.abacus.output.SubaccountPosition;
|
||||
export type SubaccountOrder = Abacus.exchange.dydx.abacus.output.SubaccountOrder;
|
||||
@@ -142,7 +149,7 @@ const historicalPnlPeriod = [...HistoricalPnlPeriod.values()] as const;
|
||||
export type HistoricalPnlPeriods = (typeof historicalPnlPeriod)[number];
|
||||
|
||||
// ------ Transfer Items ------ //
|
||||
export const TransferInputField = Abacus.exchange.dydx.abacus.state.modal.TransferInputField;
|
||||
export const TransferInputField = Abacus.exchange.dydx.abacus.state.model.TransferInputField;
|
||||
const transferInputFields = [...TransferInputField.values()] as const;
|
||||
export type TransferInputFields = (typeof transferInputFields)[number];
|
||||
|
||||
@@ -151,7 +158,7 @@ const transferTypes = [...TransferType.values()] as const;
|
||||
export type TransferTypes = (typeof transferTypes)[number];
|
||||
|
||||
// ------ Trade Items ------ //
|
||||
export const TradeInputField = Abacus.exchange.dydx.abacus.state.modal.TradeInputField;
|
||||
export const TradeInputField = Abacus.exchange.dydx.abacus.state.model.TradeInputField;
|
||||
const tradeInputFields = [...TradeInputField.values()] as const;
|
||||
export type TradeInputFields = (typeof tradeInputFields)[number];
|
||||
|
||||
@@ -162,7 +169,7 @@ export type TradeState<T> = {
|
||||
};
|
||||
|
||||
export const ClosePositionInputField =
|
||||
Abacus.exchange.dydx.abacus.state.modal.ClosePositionInputField;
|
||||
Abacus.exchange.dydx.abacus.state.model.ClosePositionInputField;
|
||||
|
||||
const closePositionInputFields = [...ClosePositionInputField.values()] as const;
|
||||
export type ClosePositionInputFields = (typeof closePositionInputFields)[number];
|
||||
@@ -202,6 +209,9 @@ export const RestrictionType = Abacus.exchange.dydx.abacus.output.Restriction;
|
||||
const restrictionTypes = [...RestrictionType.values()] as const;
|
||||
export type RestrictionTypes = (typeof restrictionTypes)[number];
|
||||
|
||||
// ------ Api data ------ //
|
||||
export const ApiData = Abacus.exchange.dydx.abacus.state.manager.ApiData;
|
||||
|
||||
// ------ Enum Conversions ------ //
|
||||
type IfEquals<X, Y, A, B> = (<T>() => T extends X ? 1 : 2) extends <T>() => T extends Y ? 1 : 2
|
||||
? A
|
||||
@@ -236,6 +246,15 @@ export const HISTORICAL_PNL_PERIODS: Record<
|
||||
[HistoricalPnlPeriod.Period90d.name]: HistoricalPnlPeriod.Period90d,
|
||||
};
|
||||
|
||||
export const HISTORICAL_TRADING_REWARDS_PERIODS: Record<
|
||||
KotlinIrEnumValues<typeof HistoricalTradingRewardsPeriod>,
|
||||
HistoricalTradingRewardsPeriods
|
||||
> = {
|
||||
[HistoricalTradingRewardsPeriod.MONTHLY.name]: HistoricalTradingRewardsPeriod.MONTHLY,
|
||||
[HistoricalTradingRewardsPeriod.WEEKLY.name]: HistoricalTradingRewardsPeriod.WEEKLY,
|
||||
[HistoricalTradingRewardsPeriod.DAILY.name]: HistoricalTradingRewardsPeriod.DAILY,
|
||||
};
|
||||
|
||||
export const ORDER_STATUS_STRINGS: Record<KotlinIrEnumValues<typeof AbacusOrderStatus>, string> = {
|
||||
[AbacusOrderStatus.open.name]: STRING_KEYS.OPEN_STATUS,
|
||||
[AbacusOrderStatus.open.rawValue]: STRING_KEYS.OPEN_STATUS,
|
||||
@@ -282,13 +301,22 @@ export const TRADE_TYPES: Record<
|
||||
[AbacusOrderType.takeProfitMarket.rawValue]: TradeTypes.TAKE_PROFIT_MARKET,
|
||||
|
||||
[AbacusOrderType.liquidated.name]: null,
|
||||
[AbacusOrderType.liquidation.name]: null,
|
||||
[AbacusOrderType.liquidated.rawValue]: null,
|
||||
|
||||
[AbacusOrderType.liquidation.name]: null,
|
||||
[AbacusOrderType.liquidation.rawValue]: null,
|
||||
|
||||
[AbacusOrderType.trailingStop.name]: null,
|
||||
[AbacusOrderType.trailingStop.rawValue]: null,
|
||||
|
||||
[AbacusOrderType.offsetting.name]: null,
|
||||
[AbacusOrderType.offsetting.rawValue]: null,
|
||||
|
||||
[AbacusOrderType.deleveraged.name]: null,
|
||||
[AbacusOrderType.deleveraged.rawValue]: null,
|
||||
|
||||
[AbacusOrderType.finalSettlement.name]: null,
|
||||
[AbacusOrderType.finalSettlement.rawValue]: null,
|
||||
};
|
||||
|
||||
// Custom types involving Abacus
|
||||
@@ -307,3 +335,9 @@ export type NetworkConfig = Partial<{
|
||||
}>;
|
||||
|
||||
export type ConnectNetworkEvent = CustomEvent<Partial<NetworkConfig>>;
|
||||
|
||||
export type PerpetualMarketOrderbookLevel = OrderbookLine & {
|
||||
side?: 'ask' | 'bid';
|
||||
mine: number;
|
||||
key: string;
|
||||
};
|
||||
|
||||
@@ -96,6 +96,7 @@ export type AnalyticsEventData<T extends AnalyticsEvent> =
|
||||
elapsedTime?: number;
|
||||
blockHeight?: number;
|
||||
indexerBlockHeight?: number;
|
||||
trailingBlocks?: number;
|
||||
}
|
||||
: // Navigation
|
||||
T extends AnalyticsEvent.NavigatePage
|
||||
@@ -172,3 +173,5 @@ export type AnalyticsEventData<T extends AnalyticsEvent> =
|
||||
validatorUrl: string;
|
||||
}
|
||||
: never;
|
||||
|
||||
export const DEFAULT_TRANSACTION_MEMO = 'dYdX Frontend (web)';
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
import { OrderSide } from '@dydxprotocol/v4-client-js';
|
||||
import { FundingDirection } from './markets';
|
||||
|
||||
// ------ Depth Chart ------ //
|
||||
export enum DepthChartSeries {
|
||||
Asks = 'Asks',
|
||||
Bids = 'Bids',
|
||||
MidMarket = 'MidMarket',
|
||||
}
|
||||
|
||||
export type DepthChartDatum = {
|
||||
size: number;
|
||||
price: number;
|
||||
depth: number;
|
||||
seriesKey: DepthChartSeries;
|
||||
};
|
||||
|
||||
export type DepthChartPoint = {
|
||||
side: OrderSide;
|
||||
price: number;
|
||||
size: number;
|
||||
};
|
||||
|
||||
export const SERIES_KEY_FOR_ORDER_SIDE = {
|
||||
[OrderSide.BUY]: DepthChartSeries.Bids,
|
||||
[OrderSide.SELL]: DepthChartSeries.Asks,
|
||||
};
|
||||
|
||||
// ------ Funding Chart ------ //
|
||||
export enum FundingRateResolution {
|
||||
OneHour = 'OneHour',
|
||||
EightHour = 'EightHour',
|
||||
Annualized = 'Annualized',
|
||||
}
|
||||
|
||||
export type FundingChartDatum = {
|
||||
time: number;
|
||||
fundingRate: number;
|
||||
direction: FundingDirection;
|
||||
};
|
||||
@@ -2,8 +2,10 @@ export enum DialogTypes {
|
||||
ClosePosition = 'ClosePosition',
|
||||
Deposit = 'Deposit',
|
||||
DisconnectWallet = 'DisconnectWallet',
|
||||
DisplaySettings = 'DisplaySettings',
|
||||
ExchangeOffline = 'ExchangeOffline',
|
||||
ExternalLink = 'ExternalLink',
|
||||
ExternalNavStride = 'ExternalNavStride',
|
||||
FillDetails = 'FillDetails',
|
||||
Help = 'Help',
|
||||
ExternalNavKeplr = 'ExternalNavKeplr',
|
||||
@@ -19,6 +21,8 @@ export enum DialogTypes {
|
||||
Transfer = 'Transfer',
|
||||
Withdraw = 'Withdraw',
|
||||
ManageFunds = 'ManageFunds',
|
||||
NewMarketMessageDetails = 'NewMarketMessageDetails',
|
||||
NewMarketAgreement = 'NewMarketAgreement',
|
||||
}
|
||||
|
||||
export enum TradeBoxDialogTypes {
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
/**
|
||||
* Temporary Indexer types
|
||||
* remove when Indexer type lib is available through @dydxprotocol/v4-client-js
|
||||
*/
|
||||
export type PerpetualMarketResponse = {
|
||||
clobPairId: string;
|
||||
ticker: string;
|
||||
status: string;
|
||||
oraclePrice: string;
|
||||
priceChange24H: string;
|
||||
volume24H: string;
|
||||
trades24H: number;
|
||||
nextFundingRate: string;
|
||||
initialMarginFraction: string;
|
||||
maintenanceMarginFraction: string;
|
||||
openInterest: string;
|
||||
atomicResolution: number;
|
||||
quantumConversionExponent: number;
|
||||
tickSize: string;
|
||||
stepSize: string;
|
||||
stepBaseQuantums: number;
|
||||
subticksPerTick: number;
|
||||
};
|
||||
@@ -20,6 +20,7 @@ export enum LocalStorageKey {
|
||||
SelectedLocale = 'dydx.SelectedLocale',
|
||||
SelectedNetwork = 'dydx.SelectedNetwork',
|
||||
SelectedTheme = 'dydx.SelectedTheme',
|
||||
SelectedColorMode = 'dydx.SelectedColorMode',
|
||||
SelectedTradeLayout = 'dydx.SelectedTradeLayout',
|
||||
TradingViewChartConfig = 'dydx.TradingViewChartConfig',
|
||||
HasSeenLaunchIncentives = 'dydx.HasSeenLaunchIncentives',
|
||||
|
||||
@@ -95,7 +95,7 @@ export type TooltipStrings = {
|
||||
stringParams?: any;
|
||||
urlConfigs?: LinksConfigs;
|
||||
}) => {
|
||||
title: string;
|
||||
title?: string;
|
||||
body: string;
|
||||
learnMoreLink?: string;
|
||||
};
|
||||
|
||||
@@ -25,4 +25,5 @@ export const DEFAULT_MARKETID = 'ETH-USD';
|
||||
export enum FundingDirection {
|
||||
ToShort = 'ToShort',
|
||||
ToLong = 'ToLong',
|
||||
None = 'None',
|
||||
}
|
||||
|
||||
@@ -87,6 +87,8 @@ export type NotificationDisplayData = {
|
||||
slotTitleLeft?: React.ReactNode;
|
||||
slotTitleRight?: React.ReactNode;
|
||||
|
||||
groupKey: string; // Grouping key toast notification stacking
|
||||
|
||||
// Overrides title/body for Notification in NotificationMenu
|
||||
renderCustomBody?: ({
|
||||
isToast,
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
/**
|
||||
* @description Orderbook display constants
|
||||
*/
|
||||
export const ORDERBOOK_MAX_ROWS_PER_SIDE = 30;
|
||||
export const ORDERBOOK_ANIMATION_DURATION = 400;
|
||||
|
||||
/**
|
||||
* @description Orderbook pixel constants
|
||||
* @note ORDERBOOK_ROW_HEIGHT should be a divisor of ORDERBOOK_HEIGHT so that we do not have a partial row at the bottom
|
||||
* @note To change the Orderbook width, --orderbook-trades-width and ORDERBOOK_WIDTH must be changed to the same value
|
||||
*/
|
||||
export const ORDERBOOK_HEIGHT = 800;
|
||||
export const ORDERBOOK_WIDTH = 300;
|
||||
export const ORDERBOOK_ROW_HEIGHT = 24;
|
||||
export const ORDERBOOK_ROW_PADDING_RIGHT = 8;
|
||||
@@ -0,0 +1,25 @@
|
||||
export type ExchangeConfigItem = {
|
||||
exchangeName: string;
|
||||
ticker: string;
|
||||
adjustByMarket?: string;
|
||||
};
|
||||
|
||||
export type PotentialMarketItem = {
|
||||
baseAsset: string;
|
||||
referencePrice: string;
|
||||
numOracles: number;
|
||||
liquidityTier: number;
|
||||
assetName: string;
|
||||
p: number;
|
||||
atomicResolution: number;
|
||||
minExchanges: number;
|
||||
minPriceChangePpm: number;
|
||||
priceExponent: number;
|
||||
stepBaseQuantum: number;
|
||||
ticksizeExponent: number;
|
||||
subticksPerTick: number;
|
||||
minOrderSize: number;
|
||||
quantumConversionExponent: number;
|
||||
};
|
||||
|
||||
export const NUM_ORACLES_TO_QUALIFY_AS_SAFE = 6;
|
||||
@@ -11,6 +11,10 @@ export enum AppRoute {
|
||||
Privacy = '/privacy',
|
||||
}
|
||||
|
||||
export enum MarketsRoute {
|
||||
New = 'new',
|
||||
}
|
||||
|
||||
export enum PortfolioRoute {
|
||||
Fees = 'fees',
|
||||
History = 'history',
|
||||
@@ -25,6 +29,12 @@ export enum HistoryRoute {
|
||||
Payments = 'payments',
|
||||
}
|
||||
|
||||
export enum TokenRoute {
|
||||
TradingRewards = 'trading-rewards',
|
||||
StakingRewards = 'staking-rewards',
|
||||
Governance = 'governance',
|
||||
}
|
||||
|
||||
export enum MobileSettingsRoute {
|
||||
Language = 'language',
|
||||
Notifications = 'notifications',
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
export enum ColorToken {
|
||||
Black = '#000000',
|
||||
White = '#FFFFFF',
|
||||
|
||||
LightGray0 = '#FAFAFA',
|
||||
LightGray1 = '#F7F8FA',
|
||||
LightGray2 = '#FAFAFD',
|
||||
LightGray3 = '#F5F5F5',
|
||||
LightGray4 = '#EDF0F2',
|
||||
LightGray5 = '#EDEDED',
|
||||
LightGray6 = '#E9ECEE',
|
||||
LightGray7 = '#E6E6E6',
|
||||
LightGray8 = '#DBDBDB',
|
||||
LightGray9 = '#D5DADF',
|
||||
LightGray10 = '#D1D9E0',
|
||||
|
||||
MediumGray0 = '#CACACE',
|
||||
MediumGray1 = '#C2CBD3',
|
||||
|
||||
DarkGray0 = '#888891',
|
||||
DarkGray1 = '#737373',
|
||||
DarkGray2 = '#56565C',
|
||||
DarkGray3 = '#4B4B4B',
|
||||
DarkGray4 = '#494950',
|
||||
DarkGray5 = '#3B3B3F',
|
||||
DarkGray6 = '#303033',
|
||||
DarkGray7 = '#313135',
|
||||
DarkGray8 = '#292929',
|
||||
DarkGray9 = '#23232F',
|
||||
DarkGray10 = '#212124',
|
||||
DarkGray11 = '#18181B',
|
||||
DarkGray12 = '#181818',
|
||||
DarkGray13 = '#0C0C0D',
|
||||
|
||||
GrayBlue0 = '#464659',
|
||||
GrayBlue1 = '#38384D',
|
||||
GrayBlue2 = '#303045',
|
||||
GrayBlue3 = '#29293D',
|
||||
GrayBlue4 = '#212131',
|
||||
GrayBlue5 = '#181825',
|
||||
GrayBlue6 = '#101018',
|
||||
GrayBlue7 = '#08080C',
|
||||
|
||||
GrayPurple0 = '#DFDADF',
|
||||
GrayPurple1 = '#C8C7D8',
|
||||
GrayPurple2 = '#807E98',
|
||||
|
||||
Purple0 = '#7774FF',
|
||||
Purple1 = '#6966FF',
|
||||
|
||||
Green0 = '#1AFFB9',
|
||||
Green1 = '#3ED9A4',
|
||||
Green2 = '#2CCC98',
|
||||
Green3 = '#3EB68A',
|
||||
|
||||
Yellow0 = '#FFCC48',
|
||||
Yellow1 = '#FFB647',
|
||||
|
||||
Red0 = '#FF5C5C',
|
||||
Red1 = '#E76565',
|
||||
Red2 = '#E45555',
|
||||
}
|
||||
|
||||
/** Maps opacity to corresponding hex value */
|
||||
export enum OpacityToken {
|
||||
Opacity16 = '29',
|
||||
Opacity20 = '33',
|
||||
Opacity66 = 'A8',
|
||||
Opacity90 = 'E6',
|
||||
}
|
||||
|
||||
export enum BrightnessFilterToken {
|
||||
Darken10 = '0.9',
|
||||
Darken5 = '0.95',
|
||||
Lighten10 = '1.1',
|
||||
}
|
||||