├── .editorconfig ├── .env ├── .env-cmdrc ├── .gitignore ├── .husky └── pre-commit ├── .linguirc ├── .prettierrc.json ├── .yarn └── releases │ └── yarn-3.1.0.cjs ├── .yarnrc.yml ├── README.md ├── config-overrides.js ├── netlify.toml ├── package.json ├── public ├── android-chrome-192x192.png ├── android-chrome-512x512.png ├── apple-touch-icon.png ├── arbitrum.svg ├── binance.svg ├── favicon-16x16.png ├── favicon-32x32.png ├── favicon.ico ├── favicon │ ├── android-icon-144x144.png │ ├── android-icon-192x192.png │ ├── android-icon-36x36.png │ ├── android-icon-48x48.png │ ├── android-icon-72x72.png │ ├── android-icon-96x96.png │ ├── apple-icon-114x114.png │ ├── apple-icon-120x120.png │ ├── apple-icon-144x144.png │ ├── apple-icon-152x152.png │ ├── apple-icon-180x180.png │ ├── apple-icon-57x57.png │ ├── apple-icon-60x60.png │ ├── apple-icon-72x72.png │ ├── apple-icon-76x76.png │ ├── apple-icon-precomposed.png │ ├── apple-icon.png │ ├── browserconfig.xml │ ├── favicon-16x16.png │ ├── favicon-32x32.png │ ├── favicon-96x96.png │ ├── favicon.ico │ ├── manifest.json │ ├── ms-icon-144x144.png │ ├── ms-icon-150x150.png │ ├── ms-icon-310x310.png │ └── ms-icon-70x70.png ├── index.html ├── logo.png ├── og.png ├── robots.txt └── site.webmanifest ├── src ├── App │ ├── App.js │ └── App.scss ├── __tests__ │ └── Helpers.js ├── abis │ ├── ERC721.json │ ├── GMT.json │ ├── GlpManager.json │ ├── GmxMigrator.json │ ├── MintableBaseToken.json │ ├── OrderBook.json │ ├── OrderBookReader.json │ ├── OrderExecutor.json │ ├── PositionManager.json │ ├── PositionRouter.json │ ├── Reader.json │ ├── ReaderV2.json │ ├── ReferralStorage.json │ ├── RewardReader.json │ ├── RewardRouter.json │ ├── RewardTracker.json │ ├── Router-v2.json │ ├── Router.json │ ├── Token.json │ ├── Treasury.json │ ├── UniPool.json │ ├── UniswapV2.json │ ├── Vault.json │ ├── VaultReader.json │ ├── VaultV2.json │ ├── VaultV2b.json │ ├── Vester.json │ ├── WETH.json │ ├── YieldFarm.json │ └── YieldToken.json ├── components │ ├── APRLabel │ │ └── APRLabel.js │ ├── AddressDropdown │ │ ├── AddressDropdown.css │ │ └── AddressDropdown.js │ ├── BuyInputSection │ │ ├── BuyInputSection.css │ │ └── BuyInputSection.js │ ├── Checkbox │ │ ├── Checkbox.css │ │ └── Checkbox.js │ ├── Common │ │ ├── Button.css │ │ ├── Button.tsx │ │ ├── Card.css │ │ ├── Card.js │ │ ├── ConnectWalletButton.tsx │ │ ├── Loader.css │ │ ├── Loader.js │ │ ├── Portal.js │ │ ├── SEO.js │ │ ├── SpinningLoader.css │ │ └── SpinningLoader.js │ ├── EventToast │ │ ├── AnnouncementIcon.js │ │ ├── EventToast.css │ │ ├── EventToast.js │ │ ├── EventToastContainer.js │ │ └── useEventToast.js │ ├── Exchange │ │ ├── ChartTokenSelector.css │ │ ├── ChartTokenSelector.js │ │ ├── ConfirmationBox.css │ │ ├── ConfirmationBox.js │ │ ├── ExchangeBanner.css │ │ ├── ExchangeBanner.js │ │ ├── ExchangeInfoRow.js │ │ ├── ExchangeTVChart.js │ │ ├── ExchangeWalletTokens.css │ │ ├── ExchangeWalletTokens.js │ │ ├── NoLiquidityErrorModal.tsx │ │ ├── OrderEditor.js │ │ ├── OrdersList.css │ │ ├── OrdersList.js │ │ ├── OrdersToa.css │ │ ├── OrdersToa.js │ │ ├── PositionDropdown.css │ │ ├── PositionDropdown.js │ │ ├── PositionEditor.js │ │ ├── PositionSeller.css │ │ ├── PositionSeller.js │ │ ├── PositionShare.css │ │ ├── PositionShare.js │ │ ├── PositionsList.js │ │ ├── SwapBox.css │ │ ├── SwapBox.js │ │ ├── TokenSelector.css │ │ ├── TokenSelector.js │ │ ├── TradeHistory.css │ │ └── TradeHistory.js │ ├── Footer │ │ ├── Footer.css │ │ └── Footer.js │ ├── Glp │ │ ├── GlpSwap.css │ │ ├── GlpSwap.js │ │ └── SwapErrorModal.tsx │ ├── Header │ │ ├── AppHeaderLinks.tsx │ │ ├── AppHeaderUser.tsx │ │ ├── Header.css │ │ ├── Header.tsx │ │ └── HeaderLink.tsx │ ├── InputSection │ │ ├── InputSection.css │ │ └── InputSection.js │ ├── Migration │ │ ├── Migration.css │ │ └── Migration.js │ ├── Modal │ │ ├── Modal.css │ │ ├── Modal.js │ │ └── ModalWithPortal.js │ ├── ModalViews │ │ ├── RedirectModal.css │ │ └── RedirectModal.js │ ├── NetworkDropdown │ │ ├── LanguagePopupHome.js │ │ ├── NetworkDropdown.css │ │ └── NetworkDropdown.js │ ├── Overlay │ │ ├── Overlay.css │ │ └── Overlay.js │ ├── Radio │ │ ├── Radio.css │ │ └── Radio.js │ ├── Referrals │ │ ├── AddAffiliateCode.js │ │ ├── AffiliatesStats.js │ │ ├── EmptyMessage.js │ │ ├── InfoCard.js │ │ ├── JoinReferralCode.js │ │ ├── TradersStats.js │ │ └── referralsHelper.js │ ├── StatsTooltip │ │ ├── StatsTooltip.css │ │ ├── StatsTooltip.tsx │ │ └── StatsTooltipRow.tsx │ ├── Tab │ │ ├── Tab.css │ │ └── Tab.js │ ├── ToastifyDebug │ │ └── ToastifyDebug.tsx │ ├── TokenCard │ │ ├── TokenCard.css │ │ └── TokenCard.js │ └── Tooltip │ │ ├── Tooltip.css │ │ ├── Tooltip.js │ │ └── TooltipWithPortal.js ├── config │ ├── Fees │ │ ├── FEES_42161.ts │ │ ├── FEES_43113.ts │ │ └── index.ts │ ├── backend.ts │ ├── chains.ts │ ├── contracts.ts │ ├── events.ts │ ├── localStorage.ts │ ├── subgraph.ts │ ├── tokens.ts │ └── ui.ts ├── domain │ ├── common.js │ ├── legacy.js │ ├── prices.js │ ├── referrals.js │ ├── tokens │ │ ├── approveTokens.tsx │ │ ├── index.ts │ │ ├── types.ts │ │ ├── useInfoTokens.ts │ │ └── utils.ts │ └── useTotalVolume.js ├── fonts │ ├── inter │ │ ├── inter-v12-latin-500.eot │ │ ├── inter-v12-latin-500.svg │ │ ├── inter-v12-latin-500.ttf │ │ ├── inter-v12-latin-500.woff │ │ ├── inter-v12-latin-500.woff2 │ │ ├── inter-v12-latin-regular.eot │ │ ├── inter-v12-latin-regular.svg │ │ ├── inter-v12-latin-regular.ttf │ │ ├── inter-v12-latin-regular.woff │ │ └── inter-v12-latin-regular.woff2 │ ├── relative │ │ ├── relative-book-pro.eot │ │ ├── relative-book-pro.ttf │ │ ├── relative-book-pro.woff │ │ └── relative-book-pro.woff2 │ └── roboto │ │ ├── roboto-v30-latin-500.eot │ │ ├── roboto-v30-latin-500.svg │ │ ├── roboto-v30-latin-500.ttf │ │ ├── roboto-v30-latin-500.woff │ │ ├── roboto-v30-latin-500.woff2 │ │ ├── roboto-v30-latin-regular.eot │ │ ├── roboto-v30-latin-regular.svg │ │ ├── roboto-v30-latin-regular.ttf │ │ ├── roboto-v30-latin-regular.woff │ │ └── roboto-v30-latin-regular.woff2 ├── img │ ├── Anyswap.png │ ├── Anyswap.svg │ ├── Artwork.svg │ ├── Artwork_gmx.svg │ ├── Banxa.png │ ├── DROP_DOWN.svg │ ├── Hop.png │ ├── Hop.svg │ ├── Hop_dark.png │ ├── Hop_dark.svg │ ├── Synapse.png │ ├── Synapse.svg │ ├── binance.png │ ├── bscscan.png │ ├── btn_big_arbitrum.png │ ├── btn_big_avalanche.png │ ├── btn_big_bsc.png │ ├── btn_big_purchasegmx.png │ ├── btn_big_purchasegmx.svg │ ├── buy_gmx.svg │ ├── buy_gmx_bond.svg │ ├── buy_transfer_eth.svg │ ├── coinbaseWallet.png │ ├── coingecko.png │ ├── cross.svg │ ├── flag_en.svg │ ├── flag_es.svg │ ├── flag_fr.svg │ ├── flag_ja.svg │ ├── flag_ko.svg │ ├── flag_ru.svg │ ├── flag_zh.svg │ ├── glp_icon.svg │ ├── gmx-logo-final-white-small.png │ ├── gmx-logo-final-white.png │ ├── gmx-logo-final.png │ ├── gmx-logo-glow.png │ ├── gmx-logo-with-name.svg │ ├── gmx_logo.svg │ ├── graphite-01.png │ ├── ic-communityproject.svg │ ├── ic_arbitrum_16.svg │ ├── ic_arbitrum_24.svg │ ├── ic_arbitrum_96.svg │ ├── ic_arbitrum_hover_16.svg │ ├── ic_arrowleft16.svg │ ├── ic_arrowright16.svg │ ├── ic_avalanche_16.svg │ ├── ic_avalanche_24.svg │ ├── ic_avalanche_96.svg │ ├── ic_avax_24.svg │ ├── ic_avax_30.svg │ ├── ic_avax_40.svg │ ├── ic_banxa.svg │ ├── ic_binance_logo.svg │ ├── ic_bsc.svg │ ├── ic_bsc_96.svg │ ├── ic_btc.b_24.svg │ ├── ic_btc.b_40.svg │ ├── ic_btc_24.svg │ ├── ic_btc_40.svg │ ├── ic_busd_24.svg │ ├── ic_buy_glp.svg │ ├── ic_cash.png │ ├── ic_cash.svg │ ├── ic_checked.svg │ ├── ic_coingecko_16.svg │ ├── ic_coingecko_hover_16.svg │ ├── ic_convert_down.svg │ ├── ic_copy_16.svg │ ├── ic_cost.svg │ ├── ic_dai_24.svg │ ├── ic_dai_40.svg │ ├── ic_discord.svg │ ├── ic_eth_24.svg │ ├── ic_eth_40.svg │ ├── ic_frax_24.svg │ ├── ic_frax_40.svg │ ├── ic_github.svg │ ├── ic_glp_24.svg │ ├── ic_glp_40.svg │ ├── ic_glp_custom.svg │ ├── ic_gmx.svg │ ├── ic_gmx_24.svg │ ├── ic_gmx_30.svg │ ├── ic_gmx_40.svg │ ├── ic_gmx_64.svg │ ├── ic_gmx_arbitrum.svg │ ├── ic_gmx_avax.svg │ ├── ic_gmx_big.svg │ ├── ic_gmx_custom.svg │ ├── ic_gmx_footer.svg │ ├── ic_hop.svg │ ├── ic_info.svg │ ├── ic_language24.svg │ ├── ic_link_24.svg │ ├── ic_link_40.svg │ ├── ic_liquidity.svg │ ├── ic_medium.svg │ ├── ic_menu_dots.svg │ ├── ic_metamask_16.svg │ ├── ic_metamask_hover_16.svg │ ├── ic_mim_24.svg │ ├── ic_mim_40.svg │ ├── ic_multiswap.svg │ ├── ic_new_link_16.svg │ ├── ic_olympus.svg │ ├── ic_olympus_arbitrum.svg │ ├── ic_selector_dropdowns.svg │ ├── ic_settings_16.svg │ ├── ic_settings_24.svg │ ├── ic_sign in_16.svg │ ├── ic_sign_out_16.svg │ ├── ic_simpleswaps.svg │ ├── ic_stats.svg │ ├── ic_stats_big.svg │ ├── ic_synapse.svg │ ├── ic_telegram.svg │ ├── ic_tether_24.svg │ ├── ic_tokens.svg │ ├── ic_totaluser.svg │ ├── ic_trading.svg │ ├── ic_transfer_avax.svg │ ├── ic_twitter.svg │ ├── ic_uni_24.svg │ ├── ic_uni_40.svg │ ├── ic_usdc.e_24.svg │ ├── ic_usdc.e_40.svg │ ├── ic_usdc_24.svg │ ├── ic_usdc_40.svg │ ├── ic_usdt_24.svg │ ├── ic_usdt_40.svg │ ├── ic_wallet_24.svg │ ├── ic_wavax_24.svg │ ├── ic_wavax_40.svg │ ├── ic_weth_24.svg │ ├── ic_weth_40.svg │ ├── lg_arbitrum.svg │ ├── logo_GMX.svg │ ├── logo_GMX_small.svg │ ├── long.svg │ ├── metamask-text.svg │ ├── metamask.png │ ├── page-not-found.svg │ ├── position-share-bg.png │ ├── short.svg │ ├── swap.svg │ ├── trading.jpg │ ├── wallet-connect-text.svg │ ├── walletconnect-circle-blue.svg │ ├── wave-01.png │ └── wave-02.png ├── index.tsx ├── lib │ ├── chains │ │ └── index.ts │ ├── contracts │ │ ├── callContract.tsx │ │ ├── contractFetcher.ts │ │ ├── index.ts │ │ ├── transactionErrors.ts │ │ └── utils.ts │ ├── dates.ts │ ├── downloadImage.ts │ ├── helperToast.ts │ ├── i18n.js │ ├── legacy.js │ ├── localStorage │ │ └── index.ts │ ├── numbers.ts │ ├── rpc │ │ └── index.ts │ ├── sleep.js │ ├── subgraph │ │ ├── clients.ts │ │ ├── index.ts │ │ └── utils.ts │ ├── useDebounce.js │ ├── useEffectDebugger.js │ ├── useLoadImage.js │ ├── useLockBodyScroll.ts │ ├── usePrevious.js │ ├── useRouteQuery.js │ ├── useScrollToTop.js │ └── wallets │ │ └── index.js ├── locales │ ├── en │ │ └── messages.po │ ├── es │ │ └── messages.po │ ├── fr │ │ └── messages.po │ ├── ja │ │ └── messages.po │ ├── ko │ │ └── messages.po │ ├── ru │ │ └── messages.po │ └── zh │ │ └── messages.po ├── pages │ ├── Actions │ │ ├── Actions.css │ │ └── Actions.js │ ├── BeginAccountTransfer │ │ ├── BeginAccountTransfer.css │ │ └── BeginAccountTransfer.js │ ├── Buy │ │ ├── Buy.css │ │ └── Buy.js │ ├── BuyGMX │ │ ├── BuyGMX.css │ │ └── BuyGMX.js │ ├── BuyGlp │ │ ├── BuyGlp.css │ │ └── BuyGlp.js │ ├── ClaimEsGmx │ │ ├── ClaimEsGmx.css │ │ └── ClaimEsGmx.js │ ├── CompleteAccountTransfer │ │ ├── CompleteAccountTransfer.css │ │ └── CompleteAccountTransfer.js │ ├── Dashboard │ │ ├── AssetDropdown.css │ │ ├── AssetDropdown.js │ │ ├── Dashboard.css │ │ ├── Dashboard.js │ │ ├── DashboardV1.js │ │ ├── DashboardV2.css │ │ └── DashboardV2.js │ ├── Ecosystem │ │ ├── Ecosystem.css │ │ └── Ecosystem.js │ ├── Exchange │ │ ├── Exchange.css │ │ └── Exchange.js │ ├── Home │ │ ├── Home.css │ │ └── Home.js │ ├── Jobs │ │ ├── Jobs.css │ │ └── Jobs.js │ ├── NftWallet │ │ ├── NftWallet.css │ │ └── NftWallet.js │ ├── OrdersOverview │ │ ├── OrdersOverview.css │ │ └── OrdersOverview.js │ ├── PageNotFound │ │ ├── PageNotFound.css │ │ └── PageNotFound.js │ ├── PositionsOverview │ │ ├── PositionsOverview.css │ │ └── PositionsOverview.js │ ├── Presale │ │ └── Presale.css │ ├── ReferralTerms │ │ ├── ReferralTerms.css │ │ └── ReferralTerms.js │ ├── Referrals │ │ ├── Referrals.css │ │ └── Referrals.js │ ├── SellGlp │ │ └── SellGlp.css │ ├── Stake │ │ ├── Stake.css │ │ ├── Stake.js │ │ ├── StakeV1.js │ │ ├── StakeV2.css │ │ └── StakeV2.js │ └── TermsAndConditions │ │ ├── TermsAndConditions.css │ │ └── TermsAndConditions.js ├── react-app-env.d.ts ├── reportWebVitals.js ├── styles │ ├── Font.css │ ├── Input.css │ └── Shared.css └── typings.d.ts ├── tsconfig.json └── yarn.lock /.editorconfig: -------------------------------------------------------------------------------- 1 | [*] 2 | charset = utf-8 3 | end_of_line = lf 4 | indent_size = 2 5 | indent_style = space 6 | insert_final_newline = true 7 | trim_trailing_whitespace = true 8 | 9 | [*.md] 10 | max_line_length = 0 11 | trim_trailing_whitespace = false 12 | 13 | [COMMIT_EDITMSG] 14 | max_line_length = 0 15 | -------------------------------------------------------------------------------- /.env: -------------------------------------------------------------------------------- 1 | GENERATE_SOURCEMAP=false 2 | -------------------------------------------------------------------------------- /.env-cmdrc: -------------------------------------------------------------------------------- 1 | { 2 | "development": { 3 | "REACT_APP_IS_HOME_SITE": false 4 | }, 5 | "development-home": { 6 | "REACT_APP_IS_HOME_SITE": true 7 | }, 8 | "development-app": { 9 | "REACT_APP_IS_HOME_SITE": false 10 | }, 11 | "production-home": { 12 | "REACT_APP_IS_HOME_SITE": true 13 | }, 14 | "production-app": { 15 | "REACT_APP_IS_HOME_SITE": false 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | .vscode 8 | 9 | # lingui 10 | /src/locales/**/*.js 11 | /src/locales/**/en.po 12 | /src/locales/_build/ 13 | 14 | # testing 15 | /coverage 16 | 17 | # production 18 | /build 19 | 20 | # misc 21 | .DS_Store 22 | .env.local 23 | .env.development.local 24 | .env.test.local 25 | .env.production.local 26 | 27 | npm-debug.log* 28 | yarn-debug.log* 29 | yarn-error.log* 30 | 31 | package-lock.json 32 | 33 | .yarn/* 34 | !.yarn/patches 35 | !.yarn/plugins 36 | !.yarn/releases 37 | !.yarn/sdks 38 | !.yarn/versions 39 | /.idea/ 40 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname "$0")/_/husky.sh" 3 | 4 | yarn lingui:generate 5 | yarn lint-staged 6 | yarn tscheck 7 | -------------------------------------------------------------------------------- /.linguirc: -------------------------------------------------------------------------------- 1 | { 2 | "locales": [ 3 | "en", 4 | "es", 5 | "ko", 6 | "ja", 7 | "zh", 8 | "ru", 9 | "fr" 10 | ], 11 | "sourceLocale": "en", 12 | "catalogs": [ 13 | { 14 | "path": "src/locales/{locale}/messages", 15 | "include": [ 16 | "src" 17 | ] 18 | } 19 | ], 20 | "formatOptions": { 21 | "lineNumbers": false 22 | }, 23 | "fallbackLocales": { 24 | "default": "en" 25 | }, 26 | "format": "po", 27 | "orderBy": "messageId" 28 | } 29 | -------------------------------------------------------------------------------- /.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "semi": true, 3 | "singleQuote": false, 4 | "printWidth": 120 5 | } 6 | -------------------------------------------------------------------------------- /.yarnrc.yml: -------------------------------------------------------------------------------- 1 | nodeLinker: node-modules 2 | 3 | yarnPath: .yarn/releases/yarn-3.1.0.cjs 4 | -------------------------------------------------------------------------------- /config-overrides.js: -------------------------------------------------------------------------------- 1 | const webpack = require("webpack"); 2 | const ModuleScopePlugin = require("react-dev-utils/ModuleScopePlugin"); 3 | 4 | module.exports = function override(config) { 5 | config.resolve.plugins = config.resolve.plugins.filter((plugin) => !(plugin instanceof ModuleScopePlugin)); 6 | // https://github.com/lingui/js-lingui/issues/1195 7 | // Adding loader to use for .po files to webpack 8 | const webpackLoaders = config.module.rules[0].oneOf; 9 | webpackLoaders.splice(webpackLoaders.length - 1, 0, { 10 | test: /\.po/, 11 | use: [ 12 | { 13 | loader: "@lingui/loader", 14 | }, 15 | ], 16 | }); 17 | const fallback = config.resolve.fallback || {}; 18 | Object.assign(fallback, { 19 | stream: require.resolve("stream-browserify"), 20 | http: require.resolve("stream-http"), 21 | https: require.resolve("https-browserify"), 22 | os: require.resolve("os-browserify/browser"), 23 | process: require.resolve("process"), 24 | }); 25 | config.resolve.fallback = fallback; 26 | config.resolve.alias["@uniswap/v3-sdk"] = require.resolve("@uniswap/v3-sdk/dist/index.js"); 27 | config.plugins = (config.plugins || []).concat([ 28 | new webpack.ProvidePlugin({ 29 | process: "process/browser.js", 30 | Buffer: ["buffer", "Buffer"], 31 | }), 32 | ]); 33 | return config; 34 | }; 35 | -------------------------------------------------------------------------------- /netlify.toml: -------------------------------------------------------------------------------- 1 | [build] 2 | publish="./build" 3 | base = "." 4 | 5 | [[redirects]] 6 | from = "/*" 7 | to = "/index.html" 8 | status = 200 9 | 10 | [[headers]] 11 | for = "/*" 12 | [headers.values] 13 | X-Frame-Options = "DENY" 14 | X-XSS-Protection = "1; mode=block" 15 | Referrer-Policy = "no-referrer" 16 | X-Content-Type-Options = "nosniff" 17 | Content-Security-Policy = "default-src 'self' netlify-cdp-loader.netlify.app; img-src 'self' data:; script-src 'self' 'unsafe-inline' netlify-cdp-loader.netlify.app; connect-src *; frame-src 'self' app.netlify.com; style-src 'self' 'unsafe-inline';" 18 | -------------------------------------------------------------------------------- /public/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newstable/gmx-interface/f0ccdaed8688d4d2049d366392e79b0493588109/public/android-chrome-192x192.png -------------------------------------------------------------------------------- /public/android-chrome-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newstable/gmx-interface/f0ccdaed8688d4d2049d366392e79b0493588109/public/android-chrome-512x512.png -------------------------------------------------------------------------------- /public/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newstable/gmx-interface/f0ccdaed8688d4d2049d366392e79b0493588109/public/apple-touch-icon.png -------------------------------------------------------------------------------- /public/binance.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /public/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newstable/gmx-interface/f0ccdaed8688d4d2049d366392e79b0493588109/public/favicon-16x16.png -------------------------------------------------------------------------------- /public/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newstable/gmx-interface/f0ccdaed8688d4d2049d366392e79b0493588109/public/favicon-32x32.png -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newstable/gmx-interface/f0ccdaed8688d4d2049d366392e79b0493588109/public/favicon.ico -------------------------------------------------------------------------------- /public/favicon/android-icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newstable/gmx-interface/f0ccdaed8688d4d2049d366392e79b0493588109/public/favicon/android-icon-144x144.png -------------------------------------------------------------------------------- /public/favicon/android-icon-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newstable/gmx-interface/f0ccdaed8688d4d2049d366392e79b0493588109/public/favicon/android-icon-192x192.png -------------------------------------------------------------------------------- /public/favicon/android-icon-36x36.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newstable/gmx-interface/f0ccdaed8688d4d2049d366392e79b0493588109/public/favicon/android-icon-36x36.png -------------------------------------------------------------------------------- /public/favicon/android-icon-48x48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newstable/gmx-interface/f0ccdaed8688d4d2049d366392e79b0493588109/public/favicon/android-icon-48x48.png -------------------------------------------------------------------------------- /public/favicon/android-icon-72x72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newstable/gmx-interface/f0ccdaed8688d4d2049d366392e79b0493588109/public/favicon/android-icon-72x72.png -------------------------------------------------------------------------------- /public/favicon/android-icon-96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newstable/gmx-interface/f0ccdaed8688d4d2049d366392e79b0493588109/public/favicon/android-icon-96x96.png -------------------------------------------------------------------------------- /public/favicon/apple-icon-114x114.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newstable/gmx-interface/f0ccdaed8688d4d2049d366392e79b0493588109/public/favicon/apple-icon-114x114.png -------------------------------------------------------------------------------- /public/favicon/apple-icon-120x120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newstable/gmx-interface/f0ccdaed8688d4d2049d366392e79b0493588109/public/favicon/apple-icon-120x120.png -------------------------------------------------------------------------------- /public/favicon/apple-icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newstable/gmx-interface/f0ccdaed8688d4d2049d366392e79b0493588109/public/favicon/apple-icon-144x144.png -------------------------------------------------------------------------------- /public/favicon/apple-icon-152x152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newstable/gmx-interface/f0ccdaed8688d4d2049d366392e79b0493588109/public/favicon/apple-icon-152x152.png -------------------------------------------------------------------------------- /public/favicon/apple-icon-180x180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newstable/gmx-interface/f0ccdaed8688d4d2049d366392e79b0493588109/public/favicon/apple-icon-180x180.png -------------------------------------------------------------------------------- /public/favicon/apple-icon-57x57.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newstable/gmx-interface/f0ccdaed8688d4d2049d366392e79b0493588109/public/favicon/apple-icon-57x57.png -------------------------------------------------------------------------------- /public/favicon/apple-icon-60x60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newstable/gmx-interface/f0ccdaed8688d4d2049d366392e79b0493588109/public/favicon/apple-icon-60x60.png -------------------------------------------------------------------------------- /public/favicon/apple-icon-72x72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newstable/gmx-interface/f0ccdaed8688d4d2049d366392e79b0493588109/public/favicon/apple-icon-72x72.png -------------------------------------------------------------------------------- /public/favicon/apple-icon-76x76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newstable/gmx-interface/f0ccdaed8688d4d2049d366392e79b0493588109/public/favicon/apple-icon-76x76.png -------------------------------------------------------------------------------- /public/favicon/apple-icon-precomposed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newstable/gmx-interface/f0ccdaed8688d4d2049d366392e79b0493588109/public/favicon/apple-icon-precomposed.png -------------------------------------------------------------------------------- /public/favicon/apple-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newstable/gmx-interface/f0ccdaed8688d4d2049d366392e79b0493588109/public/favicon/apple-icon.png -------------------------------------------------------------------------------- /public/favicon/browserconfig.xml: -------------------------------------------------------------------------------- 1 | 2 | #ffffff -------------------------------------------------------------------------------- /public/favicon/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newstable/gmx-interface/f0ccdaed8688d4d2049d366392e79b0493588109/public/favicon/favicon-16x16.png -------------------------------------------------------------------------------- /public/favicon/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newstable/gmx-interface/f0ccdaed8688d4d2049d366392e79b0493588109/public/favicon/favicon-32x32.png -------------------------------------------------------------------------------- /public/favicon/favicon-96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newstable/gmx-interface/f0ccdaed8688d4d2049d366392e79b0493588109/public/favicon/favicon-96x96.png -------------------------------------------------------------------------------- /public/favicon/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newstable/gmx-interface/f0ccdaed8688d4d2049d366392e79b0493588109/public/favicon/favicon.ico -------------------------------------------------------------------------------- /public/favicon/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "App", 3 | "icons": [ 4 | { 5 | "src": "\/android-icon-36x36.png", 6 | "sizes": "36x36", 7 | "type": "image\/png", 8 | "density": "0.75" 9 | }, 10 | { 11 | "src": "\/android-icon-48x48.png", 12 | "sizes": "48x48", 13 | "type": "image\/png", 14 | "density": "1.0" 15 | }, 16 | { 17 | "src": "\/android-icon-72x72.png", 18 | "sizes": "72x72", 19 | "type": "image\/png", 20 | "density": "1.5" 21 | }, 22 | { 23 | "src": "\/android-icon-96x96.png", 24 | "sizes": "96x96", 25 | "type": "image\/png", 26 | "density": "2.0" 27 | }, 28 | { 29 | "src": "\/android-icon-144x144.png", 30 | "sizes": "144x144", 31 | "type": "image\/png", 32 | "density": "3.0" 33 | }, 34 | { 35 | "src": "\/android-icon-192x192.png", 36 | "sizes": "192x192", 37 | "type": "image\/png", 38 | "density": "4.0" 39 | } 40 | ] 41 | } -------------------------------------------------------------------------------- /public/favicon/ms-icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newstable/gmx-interface/f0ccdaed8688d4d2049d366392e79b0493588109/public/favicon/ms-icon-144x144.png -------------------------------------------------------------------------------- /public/favicon/ms-icon-150x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newstable/gmx-interface/f0ccdaed8688d4d2049d366392e79b0493588109/public/favicon/ms-icon-150x150.png -------------------------------------------------------------------------------- /public/favicon/ms-icon-310x310.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newstable/gmx-interface/f0ccdaed8688d4d2049d366392e79b0493588109/public/favicon/ms-icon-310x310.png -------------------------------------------------------------------------------- /public/favicon/ms-icon-70x70.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newstable/gmx-interface/f0ccdaed8688d4d2049d366392e79b0493588109/public/favicon/ms-icon-70x70.png -------------------------------------------------------------------------------- /public/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newstable/gmx-interface/f0ccdaed8688d4d2049d366392e79b0493588109/public/logo.png -------------------------------------------------------------------------------- /public/og.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newstable/gmx-interface/f0ccdaed8688d4d2049d366392e79b0493588109/public/og.png -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /public/site.webmanifest: -------------------------------------------------------------------------------- 1 | {"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"} -------------------------------------------------------------------------------- /src/components/AddressDropdown/AddressDropdown.css: -------------------------------------------------------------------------------- 1 | .menu-items:focus-visible { 2 | border: 1px solid #262638; 3 | } 4 | .address-btn { 5 | display: inline-flex; 6 | align-items: center; 7 | justify-content: center; 8 | color: white !important; 9 | } 10 | 11 | .user-address { 12 | margin-left: 1rem; 13 | margin-right: 1rem; 14 | } 15 | 16 | .App-header-user-address:hover { 17 | background: #808aff14; 18 | } 19 | 20 | .menu-items { 21 | position: absolute; 22 | right: 0; 23 | top: 4.3rem; 24 | min-width: 15.5rem; 25 | width: 100%; 26 | transform-origin: top right; 27 | border-radius: 0.4rem; 28 | background: #16182e; 29 | border: 1px solid #32344c; 30 | list-style: none; 31 | cursor: pointer; 32 | outline: none; 33 | z-index: 1000; 34 | } 35 | .menu-item { 36 | display: flex !important; 37 | align-items: center; 38 | font-size: 1.5rem; 39 | color: #a0a3c4; 40 | padding-bottom: 1.5rem; 41 | font-size: 1.4rem; 42 | padding: 0.85rem 0.8rem; 43 | border-radius: 0.4rem; 44 | } 45 | .menu-item:hover { 46 | background: #808aff14 !important; 47 | border-radius: 0.4rem; 48 | opacity: 1; 49 | color: #eee; 50 | } 51 | .menu-item > p { 52 | margin: 0px; 53 | padding-left: 1rem; 54 | } 55 | .menu-item > a { 56 | display: inline-flex; 57 | } 58 | 59 | @media screen and (max-width: 370px) { 60 | .user-address { 61 | margin-left: 0; 62 | } 63 | .address-btn { 64 | display: flex; 65 | justify-content: space-between; 66 | } 67 | .user-avatar { 68 | display: none; 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/components/BuyInputSection/BuyInputSection.css: -------------------------------------------------------------------------------- 1 | .buy-input .InputSection-static-input { 2 | font-size: 2.325rem; 3 | } 4 | 5 | .buy-input.Exchange-swap-section { 6 | min-height: 9.2rem; 7 | display: flex; 8 | flex-direction: column; 9 | justify-content: space-between; 10 | } 11 | 12 | .buy-input .TokenSelector-box { 13 | display: flex; 14 | align-items: center; 15 | border-radius: 0.4rem; 16 | /* padding: 0.5rem 0; */ 17 | color: #ffffff; 18 | min-width: 4.65rem; 19 | font-size: 1.9rem; 20 | line-height: 2.5rem; 21 | justify-content: flex-end; 22 | } 23 | .buy-input .TokenSelector-box:hover { 24 | color: #7885ff; 25 | } 26 | 27 | .buy-input .Exchange-swap-input-container { 28 | display: flex; 29 | align-items: center; 30 | justify-content: space-between; 31 | } 32 | 33 | .buy-input .Exchange-swap-max { 34 | position: unset; 35 | color: white; 36 | font-size: 1.5rem; 37 | } 38 | 39 | .buy-input .TokenSelector-caret { 40 | margin: 0; 41 | margin-right: -0.5rem; 42 | } 43 | 44 | .buy-input .TokenSelector-box-symbol { 45 | margin-left: 0.8rem; 46 | } 47 | 48 | .buy-input .PositionEditor-token-symbol { 49 | display: flex; 50 | align-items: center; 51 | margin-left: 1.4rem; 52 | } 53 | 54 | .buy-input .PositionEditor-token-symbol img { 55 | margin-left: 0.8rem; 56 | display: none; 57 | } 58 | 59 | .buy-input .Exchange-swap-section-top { 60 | padding-bottom: 0; 61 | } 62 | 63 | .buy-input .selected-token { 64 | /* padding-top: 0.5rem; */ 65 | /* padding-bottom: 0.5rem; */ 66 | display: flex; 67 | align-items: center; 68 | } 69 | 70 | .buy-input .Exchange-swap-balance { 71 | color: white; 72 | } 73 | -------------------------------------------------------------------------------- /src/components/Checkbox/Checkbox.css: -------------------------------------------------------------------------------- 1 | .Checkbox { 2 | user-select: none; 3 | cursor: pointer; 4 | display: flex; 5 | align-items: center; 6 | } 7 | 8 | .Checkbox.disabled { 9 | cursor: default; 10 | pointer-events: none; 11 | } 12 | 13 | .Checkbox-icon-wrapper { 14 | display: inline-flex; 15 | align-items: center; 16 | } 17 | 18 | .Checkbox .Checkbox-icon { 19 | font-size: 1.25rem; 20 | color: rgba(61, 81, 255, 1); 21 | margin-right: 0.62rem; 22 | margin-bottom: 0; 23 | } 24 | 25 | .Checkbox.disabled .Checkbox-icon { 26 | color: #47509e; 27 | } 28 | 29 | .Checkbox-icon.inactive { 30 | color: rgba(255, 255, 255, 0.7); 31 | } 32 | 33 | .Checkbox-label { 34 | display: inline-block; 35 | vertical-align: middle; 36 | font-size: 1.5rem; 37 | } 38 | -------------------------------------------------------------------------------- /src/components/Checkbox/Checkbox.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | import cx from "classnames"; 4 | 5 | import "./Checkbox.css"; 6 | import { ImCheckboxUnchecked, ImCheckboxChecked } from "react-icons/im"; 7 | 8 | export default function Checkbox(props) { 9 | const { isChecked, setIsChecked, disabled, className } = props; 10 | 11 | return ( 12 |
setIsChecked(!isChecked)} 15 | > 16 | 17 | {isChecked && } 18 | {!isChecked && } 19 | 20 | {props.children} 21 |
22 | ); 23 | } 24 | -------------------------------------------------------------------------------- /src/components/Common/Button.tsx: -------------------------------------------------------------------------------- 1 | import { ReactNode } from "react"; 2 | import cx from "classnames"; 3 | import "./Button.css"; 4 | 5 | type Props = { 6 | imgSrc: string; 7 | children: ReactNode; 8 | imgName: string; 9 | href?: string; 10 | className?: string; 11 | size?: string; 12 | onClick?: () => void; 13 | }; 14 | 15 | export default function Button({ href, imgSrc, children, className, imgName, onClick, size = "lg" }: Props) { 16 | let classNames = cx("btn btn-primary btn-left", `btn-${size}`, className); 17 | if (onClick) { 18 | return ( 19 | 23 | ); 24 | } 25 | return ( 26 | 27 | {imgSrc && {imgName}} 28 | {children} 29 | 30 | ); 31 | } 32 | -------------------------------------------------------------------------------- /src/components/Common/Card.css: -------------------------------------------------------------------------------- 1 | .card { 2 | border: 1px solid #1e2136; 3 | border-radius: 0.4rem; 4 | background: #16182e; 5 | } 6 | 7 | .card-header { 8 | font-size: 1.6rem; 9 | line-height: 2.1rem; 10 | font-weight: normal; 11 | letter-spacing: 0px; 12 | color: #ffffff; 13 | display: flex; 14 | align-items: center; 15 | justify-content: space-between; 16 | margin: 1.5rem; 17 | } 18 | 19 | .card-divider { 20 | height: 1px; 21 | background: #23263b; 22 | } 23 | .card-body { 24 | padding: 1.5rem; 25 | } 26 | -------------------------------------------------------------------------------- /src/components/Common/Card.js: -------------------------------------------------------------------------------- 1 | import Tooltip from "../Tooltip/Tooltip"; 2 | import "./Card.css"; 3 | 4 | function Card({ title, children, className, tooltipText }) { 5 | return ( 6 |
7 | {tooltipText ? ( 8 | {title}
} 10 | position="left-bottom" 11 | renderContent={() => tooltipText} 12 | /> 13 | ) : ( 14 |
{title}
15 | )} 16 |
17 |
{children}
18 | 19 | ); 20 | } 21 | 22 | export default Card; 23 | -------------------------------------------------------------------------------- /src/components/Common/ConnectWalletButton.tsx: -------------------------------------------------------------------------------- 1 | import { ReactNode } from "react"; 2 | import cx from "classnames"; 3 | import "./Button.css"; 4 | 5 | type Props = { 6 | imgSrc: string; 7 | children: ReactNode; 8 | onClick: () => void; 9 | className?: string; 10 | }; 11 | 12 | export default function ConnectWalletButton({ imgSrc, children, onClick, className }: Props) { 13 | let classNames = cx("btn btn-primary btn-sm connect-wallet", className); 14 | return ( 15 | 19 | ); 20 | } 21 | -------------------------------------------------------------------------------- /src/components/Common/Loader.css: -------------------------------------------------------------------------------- 1 | @keyframes bouncing-loader { 2 | to { 3 | opacity: 0.1; 4 | transform: translate3d(0, -1.6rem, 0); 5 | } 6 | } 7 | 8 | .bouncing-loader { 9 | display: flex; 10 | justify-content: center; 11 | } 12 | 13 | .bouncing-loader > div { 14 | width: 1.6rem; 15 | height: 1.6rem; 16 | margin: 4.65rem 0.31rem; 17 | background: #8385aa; 18 | border-radius: 50%; 19 | animation: bouncing-loader 0.6s infinite alternate; 20 | } 21 | 22 | .bouncing-loader > div:nth-child(2) { 23 | animation-delay: 0.2s; 24 | } 25 | 26 | .bouncing-loader > div:nth-child(3) { 27 | animation-delay: 0.4s; 28 | } 29 | -------------------------------------------------------------------------------- /src/components/Common/Loader.js: -------------------------------------------------------------------------------- 1 | import "./Loader.css"; 2 | 3 | export default function Loader() { 4 | return ( 5 |
6 |
7 |
8 |
9 |
10 | ); 11 | } 12 | -------------------------------------------------------------------------------- /src/components/Common/Portal.js: -------------------------------------------------------------------------------- 1 | import { useEffect, useMemo } from "react"; 2 | import { createPortal } from "react-dom"; 3 | 4 | export default function Portal({ children }) { 5 | const root = document.body; 6 | 7 | const el = useMemo(() => document.createElement("div"), []); 8 | 9 | useEffect(() => { 10 | root.appendChild(el); 11 | return () => root.removeChild(el); 12 | }, [root, el]); 13 | 14 | return createPortal(children, el); 15 | } 16 | -------------------------------------------------------------------------------- /src/components/Common/SEO.js: -------------------------------------------------------------------------------- 1 | import { Helmet } from "react-helmet"; 2 | 3 | import { t } from "@lingui/macro"; 4 | 5 | function SEO(props) { 6 | const { children, ...customMeta } = props; 7 | const meta = { 8 | title: t`GMX | Decentralized Perpetual Exchange`, 9 | description: t`Trade spot or perpetual BTC, ETH, AVAX and other top cryptocurrencies with up to 30x leverage directly from your wallet on Arbitrum and Avalanche.`, 10 | image: "https://gmx.io/og.png", 11 | type: "exchange", 12 | ...customMeta, 13 | }; 14 | return ( 15 | <> 16 | 17 | {meta.title} 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | {children} 32 | 33 | ); 34 | } 35 | 36 | export default SEO; 37 | -------------------------------------------------------------------------------- /src/components/Common/SpinningLoader.css: -------------------------------------------------------------------------------- 1 | .spinning-loader { 2 | display: inline-block; 3 | font-size: 1.25rem; 4 | vertical-align: middle; 5 | } 6 | -------------------------------------------------------------------------------- /src/components/Common/SpinningLoader.js: -------------------------------------------------------------------------------- 1 | import "./SpinningLoader.css"; 2 | 3 | import { ImSpinner2 } from "react-icons/im"; 4 | 5 | function SpinningLoader({ size = "1.25rem" }) { 6 | return ; 7 | } 8 | 9 | export default SpinningLoader; 10 | -------------------------------------------------------------------------------- /src/components/EventToast/AnnouncementIcon.js: -------------------------------------------------------------------------------- 1 | function Icon({ className }) { 2 | return ( 3 | 18 | ); 19 | } 20 | 21 | export default Icon; 22 | -------------------------------------------------------------------------------- /src/components/EventToast/EventToast.js: -------------------------------------------------------------------------------- 1 | import "./EventToast.css"; 2 | import Icon from "./AnnouncementIcon"; 3 | import { MdOutlineClose } from "react-icons/md"; 4 | 5 | export default function EventToast({ event, id, onClick, t }) { 6 | return ( 7 |
8 |
9 |
10 | 11 |

{event.title}

12 |
13 | 14 |
15 |

{event.bodyText}

16 |
17 | {event.buttons.map((button) => { 18 | if (button.newTab) { 19 | return ( 20 | 21 | {button.text} 22 | 23 | ); 24 | } else { 25 | return ( 26 | 27 | {button.text} 28 | 29 | ); 30 | } 31 | })} 32 |
33 |
34 | ); 35 | } 36 | -------------------------------------------------------------------------------- /src/components/EventToast/EventToastContainer.js: -------------------------------------------------------------------------------- 1 | import { Toaster } from "react-hot-toast"; 2 | import { useWindowScroll, createBreakpoint } from "react-use"; 3 | 4 | function EventToastContainer() { 5 | let { y: scrollY } = useWindowScroll(); 6 | const useBreakpoint = createBreakpoint({ XL: 1033, L: 768, S: 350 }); 7 | const breakpoint = useBreakpoint(); 8 | return ( 9 | 60 ? "30px" : `${93 - scrollY}px`, 18 | right: breakpoint === "XL" ? "30px" : "1rem", 19 | }} 20 | toastOptions={{ 21 | duration: Infinity, 22 | }} 23 | /> 24 | ); 25 | } 26 | export default EventToastContainer; 27 | -------------------------------------------------------------------------------- /src/components/EventToast/useEventToast.js: -------------------------------------------------------------------------------- 1 | import { useLocalStorage } from "react-use"; 2 | import toast from "react-hot-toast"; 3 | import { homeEventsData, appEventsData } from "config/events"; 4 | import { useEffect } from "react"; 5 | import EventToast from "./EventToast"; 6 | import { isFuture, parse } from "date-fns"; 7 | import { isHomeSite } from "lib/legacy"; 8 | 9 | function useEventToast() { 10 | const isHome = isHomeSite(); 11 | const [visited, setVisited] = useLocalStorage("visited-announcements", []); 12 | 13 | useEffect(() => { 14 | const eventsData = isHome ? homeEventsData : appEventsData; 15 | 16 | eventsData 17 | .filter((event) => event.isActive) 18 | .filter((event) => isFuture(parse(event.validTill + ", +00", "d MMM yyyy, H:mm, x", new Date()))) 19 | .filter((event) => Array.isArray(visited) && !visited.includes(event.id)) 20 | .forEach((event) => { 21 | toast.custom( 22 | (t) => ( 23 | { 28 | toast.dismiss(event.id); 29 | visited.push(event.id); 30 | setVisited(visited); 31 | }} 32 | /> 33 | ), 34 | { 35 | id: event.id, 36 | style: {}, 37 | } 38 | ); 39 | }); 40 | }, [visited, setVisited, isHome]); 41 | } 42 | 43 | export default useEventToast; 44 | -------------------------------------------------------------------------------- /src/components/Exchange/ChartTokenSelector.css: -------------------------------------------------------------------------------- 1 | .chart-token-selector { 2 | padding-top: 0 !important; 3 | padding-bottom: 0 !important; 4 | } 5 | 6 | .chart-token-selector--current { 7 | font-size: 2.15rem; 8 | font-weight: 700; 9 | margin-right: 1rem; 10 | color: white; 11 | } 12 | 13 | .chart-token-menu-items.menu-items { 14 | width: 15.8rem; 15 | top: 6rem; 16 | right: unset; 17 | left: 0; 18 | } 19 | 20 | .chart-token-menu-items .menu-item { 21 | font-size: 1.4rem; 22 | height: 3.4rem; 23 | color: #a0a3c4; 24 | } 25 | -------------------------------------------------------------------------------- /src/components/Exchange/ConfirmationBox.css: -------------------------------------------------------------------------------- 1 | .order-list { 2 | list-style: none; 3 | padding: 0; 4 | margin: 1rem 0; 5 | } 6 | .order-list li { 7 | display: flex; 8 | justify-content: space-between; 9 | align-items: center; 10 | background: var(--dark-blue-hover); 11 | border-radius: var(--border-radius-sm); 12 | margin-bottom: 0.5rem; 13 | padding: 1rem; 14 | } 15 | .order-list li p { 16 | margin: 0; 17 | } 18 | .order-list li button { 19 | font-size: 1.4rem; 20 | background: none; 21 | border: none; 22 | color: white; 23 | opacity: 0.8; 24 | } 25 | .order-list li button:hover { 26 | opacity: 1; 27 | } 28 | 29 | .view-orders { 30 | text-decoration: underline; 31 | cursor: pointer; 32 | } 33 | -------------------------------------------------------------------------------- /src/components/Exchange/ExchangeBanner.css: -------------------------------------------------------------------------------- 1 | .ExchangeBanner { 2 | background: linear-gradient(90deg, #105461, #28156e); 3 | border-radius: 0.5rem; 4 | margin: 3rem 3.1rem 1.5rem; 5 | padding: 1.2rem 2.4rem; 6 | padding-right: 4rem; 7 | position: relative; 8 | } 9 | 10 | .ExchangeBanner-text { 11 | color: white; 12 | font-size: 1.8rem; 13 | line-height: 2.3rem; 14 | margin: 0; 15 | } 16 | 17 | .ExchangeBanner-price { 18 | color: #50d0fe; 19 | } 20 | 21 | .ExchangeBanner-link { 22 | color: white; 23 | } 24 | 25 | .ExchangeBanner-close { 26 | position: absolute; 27 | top: 1.2rem; 28 | right: 2.4rem; 29 | cursor: pointer; 30 | } 31 | 32 | @media (max-width: 700px) { 33 | .ExchangeBanner { 34 | margin: 1.5rem; 35 | margin-top: 0.8rem; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/components/Exchange/ExchangeBanner.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | import "./ExchangeBanner.css"; 4 | 5 | export default function ExchangeBanner(props) { 6 | const { hideBanner } = props; 7 | 8 | return ( 9 |
10 |

11 | Trade on GMX and win $250.000 in prizes! Live until November 30th,{" "} 12 | 18 | click here 19 | {" "} 20 | to learn more. 21 |

22 | { 25 | hideBanner(); 26 | }} 27 | > 28 | 29 | 35 | 36 | 37 |
38 | ); 39 | } 40 | -------------------------------------------------------------------------------- /src/components/Exchange/ExchangeInfoRow.js: -------------------------------------------------------------------------------- 1 | import cx from "classnames"; 2 | 3 | export default function ExchangeInfoRow(props) { 4 | const { label, children, value, isTop, isWarning } = props; 5 | 6 | return ( 7 |
8 |
{label}
9 |
{children || value}
10 |
11 | ); 12 | } 13 | -------------------------------------------------------------------------------- /src/components/Exchange/ExchangeWalletTokens.css: -------------------------------------------------------------------------------- 1 | .ExchangeWalletTokens { 2 | max-height: 100%; 3 | overflow: auto; 4 | } 5 | 6 | .ExchangeWalletTokens-token-name { 7 | margin-right: 1.5rem; 8 | } 9 | 10 | .ExchangeWalletTokens-box { 11 | display: block; 12 | cursor: pointer; 13 | border-radius: 0.6rem; 14 | text-align: right; 15 | white-space: nowrap; 16 | } 17 | 18 | .ExchangeWalletTokens-box:hover { 19 | color: #8763ff; 20 | } 21 | 22 | .ExchangeWalletTokens-token-row { 23 | cursor: pointer; 24 | padding: 0.8rem 1.5rem; 25 | } 26 | 27 | .ExchangeWalletTokens-token-row:hover { 28 | background: linear-gradient(90deg, rgba(93, 43, 255, 0.5) 0%, rgba(184, 15, 150, 0.5) 100%); 29 | } 30 | 31 | .ExchangeWalletTokens-top-row { 32 | font-size: 1.5rem; 33 | display: grid; 34 | grid-template-columns: auto auto; 35 | } 36 | 37 | .ExchangeWalletTokens-content-row { 38 | margin-top: 0.31rem; 39 | font-size: 1.4rem; 40 | opacity: 0.7; 41 | display: grid; 42 | grid-template-columns: auto auto; 43 | } 44 | -------------------------------------------------------------------------------- /src/components/Exchange/OrdersList.css: -------------------------------------------------------------------------------- 1 | .Orders-list { 2 | width: 100%; 3 | background: linear-gradient(45deg, rgba(11, 5, 55, 0.6) 0%, rgba(21, 3, 48, 0.6) 100%); 4 | font-size: 1.4rem; 5 | } 6 | 7 | .Orders-list.small { 8 | display: none; 9 | } 10 | 11 | table.Orders-list { 12 | border-collapse: collapse; 13 | border: 1px solid #1c0e6a; 14 | } 15 | 16 | table.Orders-list th, 17 | table.Orders-list td { 18 | font-weight: normal; 19 | text-align: left; 20 | padding: 1.1rem 1.5rem; 21 | } 22 | 23 | table.Orders-list tr { 24 | background: linear-gradient(90deg, rgba(57, 28, 147, 0.1) 0%, rgba(66, 24, 140, 0.1) 100%); 25 | border-bottom: 1px solid rgba(28, 14, 106, 0.5); 26 | } 27 | 28 | table.Orders-list tr:first-child { 29 | border-bottom: 1px solid rgba(28, 14, 106, 1); 30 | } 31 | 32 | table.Orders-list tr:last-child { 33 | border-bottom: 1px solid rgba(28, 14, 106, 1); 34 | } 35 | 36 | .Orders-list-item:hover { 37 | background: linear-gradient(90deg, rgba(93, 43, 255, 0.5) 0%, rgba(184, 15, 150, 0.5) 100%); 38 | } 39 | 40 | .Orders-list-item-error { 41 | color: #ff2491; 42 | } 43 | 44 | .Orders-list-item-type { 45 | width: 6rem; 46 | } 47 | 48 | table.Orders-list tr.Orders-list-header { 49 | background: none; 50 | } 51 | 52 | table.Orders-list th { 53 | opacity: 0.7; 54 | } 55 | 56 | button.Orders-list-action { 57 | font-size: 1.4rem; 58 | padding: 0; 59 | border-radius: 3px; 60 | background: none; 61 | border: none; 62 | color: #8b7fe3; 63 | opacity: 0.9; 64 | } 65 | 66 | .checkbox-inline { 67 | display: inline-flex; 68 | } 69 | 70 | button.Orders-list-action:hover { 71 | color: #d4b3f5; 72 | opacity: 1; 73 | } 74 | 75 | @media (max-width: 1000px) { 76 | .Orders-list.small { 77 | display: block; 78 | } 79 | 80 | .Orders-list.large { 81 | display: none; 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /src/components/Exchange/OrdersToa.css: -------------------------------------------------------------------------------- 1 | .Orders-toa .Modal-content { 2 | width: 36rem; 3 | font-size: 1.5rem; 4 | } 5 | 6 | .Orders-toa-accept-rules { 7 | margin-top: 0.31rem; 8 | } 9 | 10 | .Orders-toa-accept-rules .Checkbox { 11 | width: 100%; 12 | display: grid; 13 | grid-template-columns: 1fr auto; 14 | direction: rtl; 15 | font-size: 1.4rem; 16 | margin-bottom: 0.465rem; 17 | } 18 | 19 | .Orders-toa-accept-rules .Checkbox-label { 20 | margin-right: 0.8rem; 21 | } 22 | -------------------------------------------------------------------------------- /src/components/Exchange/PositionDropdown.css: -------------------------------------------------------------------------------- 1 | .PositionDropdown-dots-icon { 2 | font-size: 1rem; 3 | border: none; 4 | color: rgba(255, 255, 255, 0.7); 5 | display: inline-flex; 6 | align-items: center; 7 | margin-top: 0.3rem; 8 | background: rgba(255, 255, 255, 0); 9 | border-radius: 2rem; 10 | padding: 0.5rem; 11 | } 12 | 13 | .PositionDropdown-dots-icon:hover { 14 | color: rgba(255, 255, 255, 1); 15 | background: rgba(255, 255, 255, 0.1); 16 | } 17 | 18 | .PositionDropdown-extra-options { 19 | position: relative; 20 | } 21 | 22 | .PositionDropdown-extra-options .menu-items { 23 | top: 1rem; 24 | min-width: 15.5rem; 25 | } 26 | -------------------------------------------------------------------------------- /src/components/Exchange/PositionDropdown.js: -------------------------------------------------------------------------------- 1 | import { Menu } from "@headlessui/react"; 2 | import { Trans } from "@lingui/macro"; 3 | import { HiDotsVertical } from "react-icons/hi"; 4 | import { AiOutlineEdit } from "react-icons/ai"; 5 | import { BiSelectMultiple } from "react-icons/bi"; 6 | import { RiShareBoxFill } from "react-icons/ri"; 7 | import "./PositionDropdown.css"; 8 | 9 | function PositionDropdown({ handleEditCollateral, handleShare, handleMarketSelect }) { 10 | return ( 11 | 12 | 13 | 16 | 17 |
18 | 19 | 20 |
21 | 22 |

23 | Edit Collateral 24 |

25 |
26 |
27 | 28 |
29 | 30 |

31 | Select Market 32 |

33 |
34 |
35 | 36 |
37 | 38 |

39 | Share Position 40 |

41 |
42 |
43 |
44 |
45 |
46 | ); 47 | } 48 | 49 | export default PositionDropdown; 50 | -------------------------------------------------------------------------------- /src/components/Exchange/PositionSeller.css: -------------------------------------------------------------------------------- 1 | .PositionEditor .PositionSeller-modal .Modal-content .Modal-body { 2 | padding-right: 0.7rem; 3 | margin-right: 0.8rem; 4 | } 5 | 6 | .PositionSeller-token-selector .Modal .Modal-content { 7 | width: 38rem; 8 | } 9 | 10 | .PositionSeller-token-selector.warning .TokenSelector-box { 11 | color: rgb(247, 147, 26); 12 | } 13 | 14 | .PositionSeller-token-selector .TokenSelector-box { 15 | display: inline-flex; 16 | } 17 | 18 | .PositionSelector-selected-receive-token { 19 | white-space: normal; 20 | display: inline-flex; 21 | flex: 1; 22 | } 23 | 24 | .PositionSeller-token-selector .TokenSelector-box .TokenSelector-caret { 25 | margin-left: 0; 26 | margin-right: -2px; 27 | margin-bottom: -2px; 28 | } 29 | 30 | .PositionSeller-fee-item { 31 | margin-bottom: 4px; 32 | } 33 | 34 | .PositionSeller-fees-tooltip .Tooltip-popup { 35 | min-width: 30rem; 36 | } 37 | 38 | @media (max-width: 700px) { 39 | .PositionSeller-token-selector .Modal .Modal-content { 40 | width: 90vw; 41 | } 42 | 43 | .PositionSeller-fees-tooltip .Tooltip-popup { 44 | min-width: 30rem; 45 | } 46 | } 47 | 48 | @media (max-width: 350px) { 49 | .PositionSeller-receive-row.Exchange-info-row { 50 | display: flex; 51 | flex-direction: column; 52 | align-items: flex-start; 53 | } 54 | 55 | .Exchange-info-row.PositionSeller-receive-row .TokenSelector-box { 56 | margin-top: 8px; 57 | text-align: left; 58 | } 59 | 60 | .PositionSelector-selected-receive-token.align-right { 61 | margin-top: 8px; 62 | text-align: left; 63 | } 64 | } -------------------------------------------------------------------------------- /src/components/Exchange/SwapBox.css: -------------------------------------------------------------------------------- 1 | .SwapBox-collateral-tooltip-text { 2 | font-weight: normal; 3 | } -------------------------------------------------------------------------------- /src/components/Exchange/TradeHistory.css: -------------------------------------------------------------------------------- 1 | .TradeHistory-row { 2 | font-size: 1.4rem; 3 | padding: 1.5rem; 4 | margin-bottom: 0.8rem; 5 | } 6 | 7 | .TradeHistory-time { 8 | font-size: 1.25rem; 9 | margin-bottom: 0.155rem; 10 | } 11 | -------------------------------------------------------------------------------- /src/components/Header/HeaderLink.tsx: -------------------------------------------------------------------------------- 1 | import React, { ReactNode } from "react"; 2 | import { NavLink } from "react-router-dom"; 3 | import cx from "classnames"; 4 | import { getAppBaseUrl, getHomeUrl } from "lib/legacy"; 5 | 6 | import "./Header.css"; 7 | import { isHomeSite, shouldShowRedirectModal } from "lib/legacy"; 8 | 9 | type Props = { 10 | isHome?: boolean; 11 | isHomeLink?: boolean; 12 | className?: string; 13 | exact?: boolean; 14 | to: string; 15 | shouldShowRedirectModal?: boolean; 16 | showRedirectModal: (to: string) => void; 17 | redirectPopupTimestamp: number; 18 | children?: ReactNode; 19 | }; 20 | 21 | export function HeaderLink({ 22 | isHomeLink, 23 | className, 24 | exact, 25 | to, 26 | children, 27 | redirectPopupTimestamp, 28 | showRedirectModal, 29 | }: Props) { 30 | const isOnHomePage = window.location.pathname === "/"; 31 | const isHome = isHomeSite(); 32 | 33 | if (isHome && !(isHomeLink && !isOnHomePage)) { 34 | if (shouldShowRedirectModal(redirectPopupTimestamp)) { 35 | return ( 36 |
showRedirectModal(to)}> 37 | {children} 38 |
39 | ); 40 | } else { 41 | const baseUrl = getAppBaseUrl(); 42 | return ( 43 | 44 | {children} 45 | 46 | ); 47 | } 48 | } 49 | 50 | if (isHomeLink) { 51 | return ( 52 | 53 | {children} 54 | 55 | ); 56 | } 57 | 58 | return ( 59 | 60 | {children} 61 | 62 | ); 63 | } 64 | -------------------------------------------------------------------------------- /src/components/InputSection/InputSection.css: -------------------------------------------------------------------------------- 1 | .InputSection-static-input { 2 | font-size: 2.325rem; 3 | } 4 | -------------------------------------------------------------------------------- /src/components/InputSection/InputSection.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import cx from "classnames"; 3 | import "./InputSection.css"; 4 | import { Trans } from "@lingui/macro"; 5 | 6 | export default function InputSection(props) { 7 | const { 8 | topLeftLabel, 9 | topRightLabel, 10 | onClickTopRightLabel, 11 | inputValue, 12 | onInputValueChange, 13 | onClickMax, 14 | showMaxButton, 15 | staticInput, 16 | } = props; 17 | 18 | return ( 19 |
20 |
21 |
{topLeftLabel}
22 |
23 | {topRightLabel} 24 |
25 |
26 |
27 |
28 | {!staticInput && ( 29 | 37 | )} 38 | {staticInput &&
{inputValue}
} 39 | {showMaxButton && ( 40 |
41 | MAX 42 |
43 | )} 44 |
45 |
{props.children}
46 |
47 |
48 | ); 49 | } 50 | -------------------------------------------------------------------------------- /src/components/Migration/Migration.css: -------------------------------------------------------------------------------- 1 | .Migration-note { 2 | text-align: center; 3 | margin-bottom: 0.8rem; 4 | } 5 | 6 | .Migration-cards { 7 | display: grid; 8 | grid-template-columns: 1fr 1fr; 9 | padding: 3.1rem; 10 | grid-gap: 16rem; 11 | margin-top: 0.8rem; 12 | } 13 | 14 | .MigrationModal-info-box { 15 | margin-bottom: 1.1rem; 16 | } 17 | 18 | @media (max-width: 800px) { 19 | .Migration-cards { 20 | grid-template-columns: 1fr; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/components/Modal/ModalWithPortal.js: -------------------------------------------------------------------------------- 1 | import Portal from "../Common/Portal"; 2 | import Modal from "./Modal"; 3 | 4 | export default function ModalWithPortal(props) { 5 | return ( 6 | 7 | 8 | 9 | ); 10 | } 11 | -------------------------------------------------------------------------------- /src/components/ModalViews/RedirectModal.css: -------------------------------------------------------------------------------- 1 | .RedirectModal .Modal-content { 2 | width: 34rem; 3 | font-size: 1.5rem; 4 | line-height: 1.9rem; 5 | } 6 | 7 | .RedirectModal .Modal-body .Checkbox { 8 | align-items: flex-start; 9 | } 10 | 11 | .RedirectModal .Modal-body .Checkbox-icon-wrapper { 12 | display: block; 13 | } 14 | 15 | .RedirectModal .Modal-body .Checkbox .Checkbox-label { 16 | margin-left: 0.5rem; 17 | } 18 | 19 | @media (max-width: 700px) { 20 | .RedirectModal .Modal-content { 21 | width: 90vw; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/components/Overlay/Overlay.css: -------------------------------------------------------------------------------- 1 | .Overlay { 2 | position: absolute; 3 | top: 0; 4 | left: 0; 5 | right: 0; 6 | bottom: 0; 7 | } 8 | 9 | .Overlay-backdrop { 10 | position: absolute; 11 | z-index: 10; 12 | top: 0; 13 | bottom: 0; 14 | left: 0; 15 | right: 0; 16 | background: rgba(0, 0, 0, 0.3); 17 | backdrop-filter: blur(1rem); 18 | } 19 | 20 | .Overlay-top-bar { 21 | background: red; 22 | height: 1.5rem; 23 | padding: 1.25rem; 24 | display: grid; 25 | grid-template-columns: auto auto; 26 | background: linear-gradient(90deg, rgba(12, 9, 78, 1) 0%, rgba(45, 8, 84, 1) 100%); 27 | border-bottom: 1px solid #1f053b; 28 | } 29 | 30 | .Overlay-title { 31 | opacity: 0.8; 32 | } 33 | 34 | .Overlay-content-outer { 35 | position: relative; 36 | z-index: 20; 37 | background: linear-gradient(45deg, rgba(7, 5, 57, 1) 0%, rgba(34, 3, 66, 1) 100%); 38 | } 39 | 40 | .Overlay-close-button { 41 | text-align: right; 42 | display: inline-block; 43 | opacity: 0.7; 44 | cursor: pointer; 45 | } 46 | 47 | .Overlay-close-button:hover { 48 | opacity: 0.9; 49 | } 50 | -------------------------------------------------------------------------------- /src/components/Overlay/Overlay.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | import { FaTimes } from "react-icons/fa"; 4 | 5 | import "./Overlay.css"; 6 | 7 | export default function Overlay(props) { 8 | return ( 9 |
10 |
11 |
12 |
13 |
{props.title}
14 |
props.setIsVisible(false)}> 15 | 16 |
17 |
18 |
{props.children}
19 |
20 |
21 | ); 22 | } 23 | -------------------------------------------------------------------------------- /src/components/Radio/Radio.css: -------------------------------------------------------------------------------- 1 | .Radio-option { 2 | display: inline-block; 3 | margin-right: 3.1rem; 4 | cursor: pointer; 5 | color: #6b40ed; 6 | } 7 | 8 | .Radio-option-bubble { 9 | display: inline-block; 10 | width: 1.1rem; 11 | height: 1.1rem; 12 | border-radius: 1.5rem; 13 | vertical-align: middle; 14 | margin-right: 0.62rem; 15 | margin-bottom: 0.31rem; 16 | border: 2px solid #6b40ed; 17 | } 18 | 19 | .Radio-option-bubble-inner { 20 | display: none; 21 | background: #ff369a; 22 | width: 0.465rem; 23 | height: 0.465rem; 24 | border-radius: 1.5rem; 25 | margin-left: 0.31rem; 26 | margin-top: 0.31rem; 27 | } 28 | 29 | .Radio-option.active { 30 | color: #ff369a; 31 | } 32 | 33 | .Radio-option.active .Radio-option-bubble { 34 | border-color: #ff369a; 35 | } 36 | 37 | .Radio-option.active .Radio-option-bubble-inner { 38 | display: block; 39 | } 40 | -------------------------------------------------------------------------------- /src/components/Radio/Radio.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | import cx from "classnames"; 4 | 5 | import "./Radio.css"; 6 | 7 | export default function Radio(props) { 8 | const { options, option, setOption } = props; 9 | 10 | return ( 11 |
12 | {options.map((opt) => ( 13 |
setOption(opt)}> 14 |
15 |
16 |
17 | {opt} 18 |
19 | ))} 20 |
21 | ); 22 | } 23 | -------------------------------------------------------------------------------- /src/components/Referrals/EmptyMessage.js: -------------------------------------------------------------------------------- 1 | import Tooltip from "../Tooltip/Tooltip"; 2 | 3 | function EmptyMessage({ message = "", tooltipText }) { 4 | return ( 5 |
6 | {tooltipText ? ( 7 | {message}

} position="center-bottom" renderContent={() => tooltipText} /> 8 | ) : ( 9 |

{message}

10 | )} 11 |
12 | ); 13 | } 14 | 15 | export default EmptyMessage; 16 | -------------------------------------------------------------------------------- /src/components/Referrals/InfoCard.js: -------------------------------------------------------------------------------- 1 | import Tooltip from "../Tooltip/Tooltip"; 2 | 3 | function InfoCard({ label, data, tooltipText, toolTipPosition = "left-bottom" }) { 4 | return ( 5 |
6 |
7 |

8 | {tooltipText ? ( 9 | tooltipText} /> 10 | ) : ( 11 | label 12 | )} 13 |

14 |
{data}
15 |
16 |
17 | ); 18 | } 19 | 20 | export default InfoCard; 21 | -------------------------------------------------------------------------------- /src/components/StatsTooltip/StatsTooltip.css: -------------------------------------------------------------------------------- 1 | .Tooltip-row { 2 | display: grid; 3 | margin: 0 0 0.5rem 0; 4 | grid-template-columns: 1fr auto; 5 | } 6 | 7 | .Tooltip-row > span.label { 8 | margin-right: 0.5rem; 9 | } 10 | .Tooltip-row > .Tooltip-row-value { 11 | color: white; 12 | text-align: right; 13 | } 14 | 15 | .Tooltip-row-values { 16 | list-style: none; 17 | margin: 0; 18 | padding: 0; 19 | } 20 | 21 | .Tooltip-row-values li { 22 | padding: 0.25rem 0 0 0; 23 | text-align: right; 24 | } 25 | 26 | .Tooltip-number { 27 | color: white; 28 | } 29 | 30 | @media (max-width: 700px) { 31 | .Tooltip-row { 32 | display: block; 33 | margin-bottom: 1rem; 34 | } 35 | .Tooltip-row > span.label { 36 | display: block; 37 | } 38 | .Tooltip-row-values li { 39 | text-align: left; 40 | } 41 | .Tooltip-row > .Tooltip-row-value { 42 | text-align: left; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/components/StatsTooltip/StatsTooltip.tsx: -------------------------------------------------------------------------------- 1 | import { BigNumber } from "ethers"; 2 | import { USD_DECIMALS } from "lib/legacy"; 3 | import "./StatsTooltip.css"; 4 | import { formatAmount } from "lib/numbers"; 5 | 6 | type Props = { 7 | title: string; 8 | total?: BigNumber; 9 | avaxValue?: BigNumber; 10 | arbitrumValue?: BigNumber; 11 | showDollar?: boolean; 12 | decimalsForConversion: number; 13 | symbol: string; 14 | }; 15 | 16 | export default function StatsTooltip({ 17 | title, 18 | total, 19 | avaxValue, 20 | arbitrumValue, 21 | showDollar = true, 22 | decimalsForConversion = USD_DECIMALS, 23 | symbol, 24 | }: Props) { 25 | return ( 26 | <> 27 |

28 | {title} on Arbitrum: 29 | 30 | {showDollar && "$"} 31 | {formatAmount(arbitrumValue, decimalsForConversion, 0, true)} 32 | {!showDollar && symbol && " " + symbol} 33 | 34 |

35 |

36 | {title} on Avalanche: 37 | 38 | {showDollar && "$"} 39 | {formatAmount(avaxValue, decimalsForConversion, 0, true)} 40 | {!showDollar && symbol && " " + symbol} 41 | 42 |

43 |
44 |

45 | Total: 46 | 47 | {showDollar && "$"} 48 | {formatAmount(total, decimalsForConversion, 0, true)} 49 | {!showDollar && symbol && " " + symbol} 50 | 51 |

52 | 53 | ); 54 | } 55 | -------------------------------------------------------------------------------- /src/components/StatsTooltip/StatsTooltipRow.tsx: -------------------------------------------------------------------------------- 1 | import "./StatsTooltip.css"; 2 | type Props = { 3 | label: string; 4 | value: number | [number]; 5 | showDollar?: boolean; 6 | }; 7 | 8 | export default function StatsTooltipRow({ label, value, showDollar = true }: Props) { 9 | function renderValue() { 10 | if (Array.isArray(value)) { 11 | return ( 12 |
    13 | {value.map((v, i) => ( 14 |
  • {v}
  • 15 | ))} 16 |
17 | ); 18 | } 19 | return ( 20 | 21 | {showDollar && "$"} 22 | {value} 23 | 24 | ); 25 | } 26 | return ( 27 |
28 | {label}: 29 | {renderValue()} 30 |
31 | ); 32 | } 33 | -------------------------------------------------------------------------------- /src/components/Tab/Tab.css: -------------------------------------------------------------------------------- 1 | .Tab.block { 2 | display: grid; 3 | grid-auto-flow: column; 4 | font-size: 1.4rem; 5 | border-radius: 3px; 6 | overflow: hidden; 7 | color: rgba(255, 255, 255, 0.7); 8 | background: linear-gradient(90deg, rgba(30, 34, 61, 0.9) 0%, rgba(38, 43, 71, 0.9) 100%); 9 | box-shadow: inset 0px 0px 30px 5px rgba(255, 255, 255, 0.01); 10 | } 11 | 12 | .Tab-option-icon { 13 | margin-right: 0.465rem; 14 | opacity: 0.7; 15 | } 16 | 17 | .Tab.block .Tab-option { 18 | text-align: center; 19 | padding: 0.8rem; 20 | padding-left: 1.5rem; 21 | padding-right: 1.5rem; 22 | cursor: pointer; 23 | /* font-size: 1.5rem; */ 24 | } 25 | 26 | .Tab.block .Tab-option:hover { 27 | color: rgba(255, 255, 255, 1); 28 | background: linear-gradient(90deg, rgba(35, 57, 172, 1) 0%, rgba(43, 59, 147, 1) 100%); 29 | } 30 | 31 | .Tab.block .Tab-option.active { 32 | opacity: 1; 33 | pointer-events: none; 34 | background: linear-gradient(90deg, rgba(45, 66, 252, 1) 0%, rgba(46, 61, 205, 1) 100%); 35 | color: rgba(255, 255, 255, 1); 36 | } 37 | 38 | .Tab.block .Tab-option.active .Tab-option-icon { 39 | opacity: 1; 40 | } 41 | 42 | .Tab.inline .Tab-option { 43 | cursor: pointer; 44 | display: inline-block; 45 | margin-right: 1.5rem; 46 | font-size: 1.5rem; 47 | } 48 | 49 | .Tab.inline .Tab-option:hover { 50 | opacity: 0.8; 51 | } 52 | 53 | .Tab.inline .Tab-option.active { 54 | opacity: 1; 55 | pointer-events: none; 56 | } 57 | -------------------------------------------------------------------------------- /src/components/Tab/Tab.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | import cx from "classnames"; 4 | 5 | import "./Tab.css"; 6 | 7 | export default function Tab(props) { 8 | const { options, option, setOption, onChange, type = "block", className, optionLabels, icons } = props; 9 | const onClick = (opt) => { 10 | if (setOption) { 11 | setOption(opt); 12 | } 13 | if (onChange) { 14 | onChange(opt); 15 | } 16 | }; 17 | 18 | return ( 19 |
20 | {options.map((opt) => { 21 | const label = optionLabels && optionLabels[opt] ? optionLabels[opt] : opt; 22 | return ( 23 |
onClick(opt)} key={opt}> 24 | {icons && icons[opt] && {option}} 25 | {label} 26 |
27 | ); 28 | })} 29 |
30 | ); 31 | } 32 | -------------------------------------------------------------------------------- /src/components/ToastifyDebug/ToastifyDebug.tsx: -------------------------------------------------------------------------------- 1 | import { useState } from "react"; 2 | 3 | export function ToastifyDebug(props) { 4 | const [open, setOpen] = useState(false); 5 | return ( 6 |
7 | setOpen((old) => !old)}> 8 | {open ? "Hide error" : "Show error"} 9 | 10 | {open &&
{props.children}
} 11 |
12 | ); 13 | } 14 | -------------------------------------------------------------------------------- /src/components/TokenCard/TokenCard.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newstable/gmx-interface/f0ccdaed8688d4d2049d366392e79b0493588109/src/components/TokenCard/TokenCard.css -------------------------------------------------------------------------------- /src/config/Fees/FEES_43113.ts: -------------------------------------------------------------------------------- 1 | export const FEES_43113 = [ 2 | { to: 1641430800, feeUsd: "10" }, 3 | { to: 1641954606, feeUsd: "506934.29" }, 4 | { to: 1642557082, feeUsd: "871367.91" }, 5 | { to: 1643166266, feeUsd: "1416130.81" }, 6 | { to: 1643765429, feeUsd: "996296.58" }, 7 | { to: 1644371345, feeUsd: "869493.46" }, 8 | { to: 1644979198, feeUsd: "644299.54" }, 9 | { to: 1645579694, feeUsd: "559829.67" }, 10 | { to: 1646182633, feeUsd: "1041033.13" }, 11 | { to: 1646788780, feeUsd: "525648.29" }, 12 | { to: 1647402672, feeUsd: "491566.54" }, 13 | { to: 1648000896, feeUsd: "523412.47" }, 14 | { to: 1648611331, feeUsd: "482364.71" }, 15 | { to: 1649207157, feeUsd: "819772.21" }, 16 | { to: 1649814371, feeUsd: "536680.30" }, 17 | { to: 1650420021, feeUsd: "297644.50" }, 18 | { to: 1651028602, feeUsd: "329239.03" }, 19 | { to: 1651635172, feeUsd: "344748.08" }, 20 | { to: 1652236772, feeUsd: "809852.39" }, 21 | { to: 1652840724, feeUsd: "850963.06" }, 22 | { to: 1653430967, feeUsd: "306245.8" }, 23 | { to: 1654053714, feeUsd: "539435.12" }, 24 | { to: 1654653280, feeUsd: "840894.12" }, 25 | { to: 1655259566, feeUsd: "506009.43" }, 26 | { to: 1655866071, feeUsd: "526660.33" }, 27 | { to: 1656472723, feeUsd: "448733.62" }, 28 | { to: 1657074613, feeUsd: "392029.38" }, 29 | { to: 1657678876, feeUsd: "348157.7" }, 30 | { to: 1658283954, feeUsd: "475489.0" }, 31 | { to: 1658886078, feeUsd: "528324.14" }, 32 | { to: 1659494426, feeUsd: "411807.72" }, 33 | { to: 1660095134, feeUsd: "373497.82" }, 34 | { to: 1660698120, feeUsd: "484879.32" }, 35 | { to: 1661309954, feeUsd: "426656.64" }, 36 | { to: 1661907895, feeUsd: "494117.94" }, 37 | { to: 1662518119, feeUsd: "310085.65" }, 38 | { to: 1663124371, feeUsd: "435866.01" }, 39 | { to: 1663724917, feeUsd: "515306.4" }, 40 | { to: 1664330339, feeUsd: "296691.45" }, 41 | { to: 1664940505, feeUsd: "203684.13" }, 42 | ]; 43 | -------------------------------------------------------------------------------- /src/config/Fees/index.ts: -------------------------------------------------------------------------------- 1 | import { FEES_42161 } from "./FEES_42161"; 2 | import { FEES_43113 } from "./FEES_43113"; 3 | import { ARBITRUM, ARBITRUM_TESTNET, AVALANCHE, MAINNET } from "../chains"; 4 | 5 | const SECONDS_PER_WEEK = 604800; 6 | 7 | type FeeItem = { 8 | from: number; 9 | to: number; 10 | feeUsd: string; 11 | }; 12 | 13 | function createFeeList(data: { to: number; feeUsd: string }[]): FeeItem[] { 14 | return data.map((item) => ({ 15 | from: item.to - SECONDS_PER_WEEK, 16 | to: item.to, 17 | feeUsd: item.feeUsd, 18 | })); 19 | } 20 | 21 | const FEES = { 22 | [MAINNET]: [], 23 | [ARBITRUM]: createFeeList(FEES_42161), 24 | [ARBITRUM_TESTNET]: createFeeList(FEES_42161), 25 | [AVALANCHE]: createFeeList(FEES_43113), 26 | }; 27 | 28 | export function getFeeHistory(chainId: number): FeeItem[] { 29 | return FEES[chainId].concat([]).reverse(); 30 | } 31 | -------------------------------------------------------------------------------- /src/config/backend.ts: -------------------------------------------------------------------------------- 1 | import { ARBITRUM, ARBITRUM_TESTNET, AVALANCHE, MAINNET } from "./chains"; 2 | 3 | export const GMX_STATS_API_URL = "https://stats.gmx.io/api"; 4 | 5 | const BACKEND_URLS = { 6 | default: "https://gmx-server-mainnet.uw.r.appspot.com", 7 | 8 | [MAINNET]: "https://gambit-server-staging.uc.r.appspot.com", 9 | [ARBITRUM_TESTNET]: "https://gambit-server-devnet.uc.r.appspot.com", 10 | [ARBITRUM]: "https://gmx-server-mainnet.uw.r.appspot.com", 11 | [AVALANCHE]: "https://gmx-avax-server.uc.r.appspot.com", 12 | }; 13 | 14 | export function getServerBaseUrl(chainId: number) { 15 | if (!chainId) { 16 | throw new Error("chainId is not provided"); 17 | } 18 | 19 | if (document.location.hostname.includes("deploy-preview")) { 20 | const fromLocalStorage = localStorage.getItem("SERVER_BASE_URL"); 21 | if (fromLocalStorage) { 22 | return fromLocalStorage; 23 | } 24 | } 25 | 26 | return BACKEND_URLS[chainId] || BACKEND_URLS.default; 27 | } 28 | 29 | export function getServerUrl(chainId: number, path: string) { 30 | return `${getServerBaseUrl(chainId)}${path}`; 31 | } 32 | -------------------------------------------------------------------------------- /src/config/localStorage.ts: -------------------------------------------------------------------------------- 1 | export const SELECTED_NETWORK_LOCAL_STORAGE_KEY = "SELECTED_NETWORK"; 2 | export const WALLET_CONNECT_LOCALSTORAGE_KEY = "walletconnect"; 3 | export const WALLET_LINK_LOCALSTORAGE_PREFIX = "-walletlink"; 4 | export const SHOULD_EAGER_CONNECT_LOCALSTORAGE_KEY = "eagerconnect"; 5 | export const CURRENT_PROVIDER_LOCALSTORAGE_KEY = "currentprovider"; 6 | export const LANGUAGE_LOCALSTORAGE_KEY = "LANGUAGE_KEY"; 7 | export const SLIPPAGE_BPS_KEY = "Exchange-swap-slippage-basis-points-v3"; 8 | export const CLOSE_POSITION_RECEIVE_TOKEN_KEY = "Close-position-receive-token"; 9 | export const IS_PNL_IN_LEVERAGE_KEY = "Exchange-swap-is-pnl-in-leverage"; 10 | export const SHOW_PNL_AFTER_FEES_KEY = "Exchange-swap-show-pnl-after-fees"; 11 | export const DISABLE_ORDER_VALIDATION_KEY = "disable-order-validation"; 12 | export const SHOULD_SHOW_POSITION_LINES_KEY = "Exchange-swap-should-show-position-lines"; 13 | export const REFERRAL_CODE_KEY = "GMX-referralCode"; 14 | export const REFERRALS_SELECTED_TAB_KEY = "Referrals-selected-tab"; 15 | -------------------------------------------------------------------------------- /src/config/subgraph.ts: -------------------------------------------------------------------------------- 1 | import { ARBITRUM, AVALANCHE } from "./chains"; 2 | 3 | export const SUBGRAPH_URLS = { 4 | [ARBITRUM]: { 5 | stats: "https://api.thegraph.com/subgraphs/name/gmx-io/gmx-stats", 6 | referrals: "https://api.thegraph.com/subgraphs/name/gmx-io/gmx-arbitrum-referrals", 7 | nissohVault: "https://api.thegraph.com/subgraphs/name/nissoh/gmx-vault", 8 | }, 9 | 10 | [AVALANCHE]: { 11 | stats: "https://api.thegraph.com/subgraphs/name/gmx-io/gmx-avalanche-stats", 12 | referrals: "https://api.thegraph.com/subgraphs/name/gmx-io/gmx-avalanche-referrals", 13 | }, 14 | 15 | common: { 16 | chainLink: "https://api.thegraph.com/subgraphs/name/deividask/chainlink", 17 | }, 18 | }; 19 | -------------------------------------------------------------------------------- /src/config/ui.ts: -------------------------------------------------------------------------------- 1 | export const REDIRECT_POPUP_TIMESTAMP_KEY = "redirect-popup-timestamp"; 2 | 3 | export const IS_TOUCH = "ontouchstart" in window; 4 | 5 | export const UI_VERSION = "1.3"; 6 | 7 | export const TRIGGER_PREFIX_ABOVE = ">"; 8 | export const TRIGGER_PREFIX_BELOW = "<"; 9 | -------------------------------------------------------------------------------- /src/domain/common.js: -------------------------------------------------------------------------------- 1 | export function get1InchSwapUrl(chainId, from, to) { 2 | const rootUrl = `https://app.1inch.io/#/${chainId}/unified/swap`; 3 | if (!from && !to) return rootUrl; 4 | return `${rootUrl}/${from}/${to}`; 5 | } 6 | -------------------------------------------------------------------------------- /src/domain/tokens/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./utils"; 2 | export * from "./types"; 3 | export * from "./useInfoTokens"; 4 | export * from "./approveTokens"; 5 | -------------------------------------------------------------------------------- /src/domain/tokens/types.ts: -------------------------------------------------------------------------------- 1 | import { BigNumber } from "@ethersproject/bignumber"; 2 | 3 | export type Token = { 4 | name: string; 5 | symbol: string; 6 | baseSymbol?: string; 7 | decimals: number; 8 | address: string; 9 | coingeckoUrl?: string; 10 | imageUrl?: string; 11 | 12 | isUsdg?: boolean; 13 | isNative?: boolean; 14 | isWrapped?: boolean; 15 | isShortable?: boolean; 16 | isStable?: boolean; 17 | isTempHidden?: boolean; 18 | }; 19 | 20 | export type TokenInfo = Token & { 21 | hasMaxAvailableLong?: boolean; 22 | hasMaxAvailableShort?: boolean; 23 | 24 | usdgAmount?: BigNumber; 25 | maxUsdgAmount?: BigNumber; 26 | 27 | poolAmount?: BigNumber; 28 | bufferAmount?: BigNumber; 29 | managedAmount?: BigNumber; 30 | managedUsd?: BigNumber; 31 | availableAmount?: BigNumber; 32 | availableUsd?: BigNumber; 33 | guaranteedUsd?: BigNumber; 34 | redemptionAmount?: BigNumber; 35 | reservedAmount?: BigNumber; 36 | 37 | balance?: BigNumber; 38 | 39 | weight?: BigNumber; 40 | 41 | maxPrice?: BigNumber; 42 | maxPrimaryPrice?: BigNumber; 43 | 44 | minPrice?: BigNumber; 45 | minPrimaryPrice?: BigNumber; 46 | 47 | contractMaxPrice?: BigNumber; 48 | contractMinPrice?: BigNumber; 49 | 50 | cumulativeFundingRate?: BigNumber; 51 | fundingRate?: BigNumber; 52 | 53 | globalShortSize?: BigNumber; 54 | 55 | maxAvailableLong?: BigNumber; 56 | maxAvailableShort?: BigNumber; 57 | 58 | maxGlobalLongSize?: BigNumber; 59 | maxGlobalShortSize?: BigNumber; 60 | 61 | maxLongCapacity?: BigNumber; 62 | }; 63 | 64 | export type InfoTokens = { 65 | [key: string]: TokenInfo; 66 | }; 67 | -------------------------------------------------------------------------------- /src/domain/useTotalVolume.js: -------------------------------------------------------------------------------- 1 | import useSWR from "swr"; 2 | import { arrayURLFetcher, getTotalVolumeSum } from "lib/legacy"; 3 | import { ARBITRUM, AVALANCHE } from "config/chains"; 4 | import { getServerUrl } from "config/backend"; 5 | import { bigNumberify } from "lib/numbers"; 6 | const ACTIVE_CHAIN_IDS = [ARBITRUM, AVALANCHE]; 7 | 8 | export default function useTotalVolume() { 9 | const { data: totalVolume } = useSWR( 10 | ACTIVE_CHAIN_IDS.map((chain) => getServerUrl(chain, "/total_volume")), 11 | { 12 | fetcher: arrayURLFetcher, 13 | } 14 | ); 15 | if (totalVolume?.length > 0) { 16 | return ACTIVE_CHAIN_IDS.reduce( 17 | (acc, chainId, index) => { 18 | const sum = getTotalVolumeSum(totalVolume[index]); 19 | acc[chainId] = sum; 20 | acc.total = acc.total.add(sum); 21 | return acc; 22 | }, 23 | { total: bigNumberify(0) } 24 | ); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/fonts/inter/inter-v12-latin-500.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newstable/gmx-interface/f0ccdaed8688d4d2049d366392e79b0493588109/src/fonts/inter/inter-v12-latin-500.eot -------------------------------------------------------------------------------- /src/fonts/inter/inter-v12-latin-500.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newstable/gmx-interface/f0ccdaed8688d4d2049d366392e79b0493588109/src/fonts/inter/inter-v12-latin-500.ttf -------------------------------------------------------------------------------- /src/fonts/inter/inter-v12-latin-500.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newstable/gmx-interface/f0ccdaed8688d4d2049d366392e79b0493588109/src/fonts/inter/inter-v12-latin-500.woff -------------------------------------------------------------------------------- /src/fonts/inter/inter-v12-latin-500.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newstable/gmx-interface/f0ccdaed8688d4d2049d366392e79b0493588109/src/fonts/inter/inter-v12-latin-500.woff2 -------------------------------------------------------------------------------- /src/fonts/inter/inter-v12-latin-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newstable/gmx-interface/f0ccdaed8688d4d2049d366392e79b0493588109/src/fonts/inter/inter-v12-latin-regular.eot -------------------------------------------------------------------------------- /src/fonts/inter/inter-v12-latin-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newstable/gmx-interface/f0ccdaed8688d4d2049d366392e79b0493588109/src/fonts/inter/inter-v12-latin-regular.ttf -------------------------------------------------------------------------------- /src/fonts/inter/inter-v12-latin-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newstable/gmx-interface/f0ccdaed8688d4d2049d366392e79b0493588109/src/fonts/inter/inter-v12-latin-regular.woff -------------------------------------------------------------------------------- /src/fonts/inter/inter-v12-latin-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newstable/gmx-interface/f0ccdaed8688d4d2049d366392e79b0493588109/src/fonts/inter/inter-v12-latin-regular.woff2 -------------------------------------------------------------------------------- /src/fonts/relative/relative-book-pro.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newstable/gmx-interface/f0ccdaed8688d4d2049d366392e79b0493588109/src/fonts/relative/relative-book-pro.eot -------------------------------------------------------------------------------- /src/fonts/relative/relative-book-pro.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newstable/gmx-interface/f0ccdaed8688d4d2049d366392e79b0493588109/src/fonts/relative/relative-book-pro.ttf -------------------------------------------------------------------------------- /src/fonts/relative/relative-book-pro.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newstable/gmx-interface/f0ccdaed8688d4d2049d366392e79b0493588109/src/fonts/relative/relative-book-pro.woff -------------------------------------------------------------------------------- /src/fonts/relative/relative-book-pro.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newstable/gmx-interface/f0ccdaed8688d4d2049d366392e79b0493588109/src/fonts/relative/relative-book-pro.woff2 -------------------------------------------------------------------------------- /src/fonts/roboto/roboto-v30-latin-500.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newstable/gmx-interface/f0ccdaed8688d4d2049d366392e79b0493588109/src/fonts/roboto/roboto-v30-latin-500.eot -------------------------------------------------------------------------------- /src/fonts/roboto/roboto-v30-latin-500.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newstable/gmx-interface/f0ccdaed8688d4d2049d366392e79b0493588109/src/fonts/roboto/roboto-v30-latin-500.ttf -------------------------------------------------------------------------------- /src/fonts/roboto/roboto-v30-latin-500.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newstable/gmx-interface/f0ccdaed8688d4d2049d366392e79b0493588109/src/fonts/roboto/roboto-v30-latin-500.woff -------------------------------------------------------------------------------- /src/fonts/roboto/roboto-v30-latin-500.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newstable/gmx-interface/f0ccdaed8688d4d2049d366392e79b0493588109/src/fonts/roboto/roboto-v30-latin-500.woff2 -------------------------------------------------------------------------------- /src/fonts/roboto/roboto-v30-latin-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newstable/gmx-interface/f0ccdaed8688d4d2049d366392e79b0493588109/src/fonts/roboto/roboto-v30-latin-regular.eot -------------------------------------------------------------------------------- /src/fonts/roboto/roboto-v30-latin-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newstable/gmx-interface/f0ccdaed8688d4d2049d366392e79b0493588109/src/fonts/roboto/roboto-v30-latin-regular.ttf -------------------------------------------------------------------------------- /src/fonts/roboto/roboto-v30-latin-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newstable/gmx-interface/f0ccdaed8688d4d2049d366392e79b0493588109/src/fonts/roboto/roboto-v30-latin-regular.woff -------------------------------------------------------------------------------- /src/fonts/roboto/roboto-v30-latin-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newstable/gmx-interface/f0ccdaed8688d4d2049d366392e79b0493588109/src/fonts/roboto/roboto-v30-latin-regular.woff2 -------------------------------------------------------------------------------- /src/img/Anyswap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newstable/gmx-interface/f0ccdaed8688d4d2049d366392e79b0493588109/src/img/Anyswap.png -------------------------------------------------------------------------------- /src/img/Anyswap.svg: -------------------------------------------------------------------------------- 1 | AnySwap -------------------------------------------------------------------------------- /src/img/Artwork.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/img/Artwork_gmx.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/img/Banxa.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newstable/gmx-interface/f0ccdaed8688d4d2049d366392e79b0493588109/src/img/Banxa.png -------------------------------------------------------------------------------- /src/img/DROP_DOWN.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/img/Hop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newstable/gmx-interface/f0ccdaed8688d4d2049d366392e79b0493588109/src/img/Hop.png -------------------------------------------------------------------------------- /src/img/Hop.svg: -------------------------------------------------------------------------------- 1 | Hop.Exchange -------------------------------------------------------------------------------- /src/img/Hop_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newstable/gmx-interface/f0ccdaed8688d4d2049d366392e79b0493588109/src/img/Hop_dark.png -------------------------------------------------------------------------------- /src/img/Synapse.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newstable/gmx-interface/f0ccdaed8688d4d2049d366392e79b0493588109/src/img/Synapse.png -------------------------------------------------------------------------------- /src/img/binance.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newstable/gmx-interface/f0ccdaed8688d4d2049d366392e79b0493588109/src/img/binance.png -------------------------------------------------------------------------------- /src/img/bscscan.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newstable/gmx-interface/f0ccdaed8688d4d2049d366392e79b0493588109/src/img/bscscan.png -------------------------------------------------------------------------------- /src/img/btn_big_arbitrum.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newstable/gmx-interface/f0ccdaed8688d4d2049d366392e79b0493588109/src/img/btn_big_arbitrum.png -------------------------------------------------------------------------------- /src/img/btn_big_avalanche.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newstable/gmx-interface/f0ccdaed8688d4d2049d366392e79b0493588109/src/img/btn_big_avalanche.png -------------------------------------------------------------------------------- /src/img/btn_big_bsc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newstable/gmx-interface/f0ccdaed8688d4d2049d366392e79b0493588109/src/img/btn_big_bsc.png -------------------------------------------------------------------------------- /src/img/btn_big_purchasegmx.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newstable/gmx-interface/f0ccdaed8688d4d2049d366392e79b0493588109/src/img/btn_big_purchasegmx.png -------------------------------------------------------------------------------- /src/img/coinbaseWallet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newstable/gmx-interface/f0ccdaed8688d4d2049d366392e79b0493588109/src/img/coinbaseWallet.png -------------------------------------------------------------------------------- /src/img/coingecko.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newstable/gmx-interface/f0ccdaed8688d4d2049d366392e79b0493588109/src/img/coingecko.png -------------------------------------------------------------------------------- /src/img/cross.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/img/flag_en.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/img/flag_fr.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/img/flag_ja.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/img/flag_ko.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/img/flag_ru.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/img/flag_zh.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/img/glp_icon.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/img/gmx-logo-final-white-small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newstable/gmx-interface/f0ccdaed8688d4d2049d366392e79b0493588109/src/img/gmx-logo-final-white-small.png -------------------------------------------------------------------------------- /src/img/gmx-logo-final-white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newstable/gmx-interface/f0ccdaed8688d4d2049d366392e79b0493588109/src/img/gmx-logo-final-white.png -------------------------------------------------------------------------------- /src/img/gmx-logo-final.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newstable/gmx-interface/f0ccdaed8688d4d2049d366392e79b0493588109/src/img/gmx-logo-final.png -------------------------------------------------------------------------------- /src/img/gmx-logo-glow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newstable/gmx-interface/f0ccdaed8688d4d2049d366392e79b0493588109/src/img/gmx-logo-glow.png -------------------------------------------------------------------------------- /src/img/gmx-logo-with-name.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/img/graphite-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newstable/gmx-interface/f0ccdaed8688d4d2049d366392e79b0493588109/src/img/graphite-01.png -------------------------------------------------------------------------------- /src/img/ic_arbitrum_16.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/img/ic_arbitrum_24.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/img/ic_arbitrum_hover_16.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/img/ic_arrowleft16.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/img/ic_arrowright16.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/img/ic_avalanche_16.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/img/ic_avalanche_24.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/img/ic_avalanche_96.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/img/ic_avax_24.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/img/ic_avax_30.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/img/ic_avax_40.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/img/ic_banxa.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/img/ic_binance_logo.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/img/ic_bsc.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/img/ic_bsc_96.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/img/ic_btc.b_24.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/img/ic_btc.b_40.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/img/ic_btc_24.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/img/ic_btc_40.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/img/ic_busd_24.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/img/ic_cash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newstable/gmx-interface/f0ccdaed8688d4d2049d366392e79b0493588109/src/img/ic_cash.png -------------------------------------------------------------------------------- /src/img/ic_cash.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/img/ic_checked.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/img/ic_convert_down.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/img/ic_copy_16.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/img/ic_dai_24.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/img/ic_dai_40.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/img/ic_discord.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/img/ic_eth_24.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/img/ic_eth_40.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/img/ic_frax_24.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/img/ic_frax_40.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/img/ic_github.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/img/ic_glp_24.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/img/ic_glp_40.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/img/ic_glp_custom.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/img/ic_gmx.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/img/ic_gmx_24.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/img/ic_gmx_30.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/img/ic_gmx_40.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/img/ic_gmx_64.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/img/ic_gmx_avax.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/img/ic_gmx_big.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/img/ic_gmx_custom.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/img/ic_gmx_footer.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/img/ic_hop.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/img/ic_info.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/img/ic_language24.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/img/ic_link_24.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/img/ic_link_40.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/img/ic_liquidity.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/img/ic_medium.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/img/ic_menu_dots.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/img/ic_new_link_16.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/img/ic_olympus.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/img/ic_selector_dropdowns.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/img/ic_sign in_16.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/img/ic_sign_out_16.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/img/ic_simpleswaps.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/img/ic_stats.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/img/ic_stats_big.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/img/ic_telegram.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/img/ic_tether_24.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/img/ic_tokens.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/img/ic_totaluser.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/img/ic_trading.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/img/ic_twitter.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/img/ic_usdc.e_24.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/img/ic_usdc.e_40.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/img/ic_usdc_24.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/img/ic_usdc_40.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/img/ic_usdt_24.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/img/ic_usdt_40.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/img/ic_wallet_24.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/img/ic_wavax_24.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/img/ic_wavax_40.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/img/logo_GMX.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/img/logo_GMX_small.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/img/long.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/img/metamask.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newstable/gmx-interface/f0ccdaed8688d4d2049d366392e79b0493588109/src/img/metamask.png -------------------------------------------------------------------------------- /src/img/position-share-bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newstable/gmx-interface/f0ccdaed8688d4d2049d366392e79b0493588109/src/img/position-share-bg.png -------------------------------------------------------------------------------- /src/img/short.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/img/swap.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/img/trading.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newstable/gmx-interface/f0ccdaed8688d4d2049d366392e79b0493588109/src/img/trading.jpg -------------------------------------------------------------------------------- /src/img/walletconnect-circle-blue.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/img/wave-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newstable/gmx-interface/f0ccdaed8688d4d2049d366392e79b0493588109/src/img/wave-01.png -------------------------------------------------------------------------------- /src/img/wave-02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newstable/gmx-interface/f0ccdaed8688d4d2049d366392e79b0493588109/src/img/wave-02.png -------------------------------------------------------------------------------- /src/index.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import ReactDOM from "react-dom"; 3 | import "regenerator-runtime/runtime"; 4 | import { BrowserRouter as Router } from "react-router-dom"; 5 | import App from "./App/App"; 6 | import reportWebVitals from "./reportWebVitals"; 7 | 8 | ReactDOM.render( 9 | 10 | 11 | 12 | 13 | , 14 | document.getElementById("root") 15 | ); 16 | 17 | // If you want to start measuring performance in your app, pass a function 18 | // to log results (for example: reportWebVitals(console.info)) 19 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals 20 | reportWebVitals(); 21 | -------------------------------------------------------------------------------- /src/lib/chains/index.ts: -------------------------------------------------------------------------------- 1 | import { useWeb3React } from "@web3-react/core"; 2 | import { SELECTED_NETWORK_LOCAL_STORAGE_KEY } from "config/localStorage"; 3 | import { DEFAULT_CHAIN_ID, SUPPORTED_CHAIN_IDS } from "config/chains"; 4 | 5 | export function useChainId() { 6 | let { chainId } = useWeb3React(); 7 | 8 | if (!chainId) { 9 | const chainIdFromLocalStorage = localStorage.getItem(SELECTED_NETWORK_LOCAL_STORAGE_KEY); 10 | if (chainIdFromLocalStorage) { 11 | chainId = parseInt(chainIdFromLocalStorage); 12 | if (!chainId) { 13 | // localstorage value is invalid 14 | localStorage.removeItem(SELECTED_NETWORK_LOCAL_STORAGE_KEY); 15 | } 16 | } 17 | } 18 | 19 | if (!chainId || !SUPPORTED_CHAIN_IDS.includes(chainId)) { 20 | chainId = DEFAULT_CHAIN_ID; 21 | } 22 | 23 | return { chainId }; 24 | } 25 | -------------------------------------------------------------------------------- /src/lib/contracts/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./callContract"; 2 | export * from "./contractFetcher"; 3 | export * from "./utils"; 4 | -------------------------------------------------------------------------------- /src/lib/contracts/transactionErrors.ts: -------------------------------------------------------------------------------- 1 | export const NOT_ENOUGH_FUNDS = "NOT_ENOUGH_FUNDS"; 2 | export const USER_DENIED = "USER_DENIED"; 3 | export const SLIPPAGE = "SLIPPAGE"; 4 | export const RPC_ERROR = "RPC_ERROR"; 5 | 6 | type ErrorPattern = { msg?: string; code?: number }; 7 | 8 | const TX_ERROR_PATTERNS: { [key: string]: ErrorPattern[] } = { 9 | [NOT_ENOUGH_FUNDS]: [ 10 | { msg: "not enough funds for gas" }, 11 | { msg: "failed to execute call with revert code InsufficientGasFunds" }, 12 | ], 13 | [USER_DENIED]: [{ msg: "User denied transaction signature" }], 14 | [SLIPPAGE]: [{ msg: "Router: mark price lower than limit" }, { msg: "Router: mark price higher than limit" }], 15 | [RPC_ERROR]: [ 16 | // @see https://eips.ethereum.org/EIPS/eip-1474#error-codes 17 | { code: -32005 }, 18 | { msg: "Non-200 status code" }, 19 | { msg: "Request limit exceeded" }, 20 | { msg: "Internal JSON-RPC error" }, 21 | { msg: "Response has no error or result" }, 22 | { msg: "couldn't connect to the network" }, 23 | ], 24 | }; 25 | 26 | type TxError = { 27 | message?: string; 28 | code?: number; 29 | data?: any; 30 | }; 31 | 32 | export function extractError(ex: TxError) { 33 | if (!ex) { 34 | return []; 35 | } 36 | 37 | const message = ex.data?.message || ex.message; 38 | const code = ex.code; 39 | 40 | if (!message && !code) { 41 | return []; 42 | } 43 | 44 | for (const [type, patterns] of Object.entries(TX_ERROR_PATTERNS)) { 45 | for (const pattern of patterns) { 46 | const matchCode = pattern.code && code === pattern.code; 47 | const matchMessage = pattern.msg && message && message.includes(pattern.msg); 48 | 49 | if (matchCode || matchMessage) { 50 | return [message, type, ex.data]; 51 | } 52 | } 53 | } 54 | 55 | return [message, null, ex.data]; 56 | } 57 | -------------------------------------------------------------------------------- /src/lib/contracts/utils.ts: -------------------------------------------------------------------------------- 1 | import { Provider } from "@ethersproject/providers"; 2 | import { Contract } from "ethers"; 3 | import { GAS_PRICE_ADJUSTMENT_MAP, MAX_GAS_PRICE_MAP } from "config/chains"; 4 | import { bigNumberify } from "../numbers"; 5 | 6 | export async function setGasPrice(txnOpts: any, provider: Provider, chainId: number) { 7 | let maxGasPrice = MAX_GAS_PRICE_MAP[chainId]; 8 | const premium = GAS_PRICE_ADJUSTMENT_MAP[chainId] || bigNumberify(0); 9 | 10 | const gasPrice = await provider.getGasPrice(); 11 | 12 | if (maxGasPrice) { 13 | if (gasPrice.gt(maxGasPrice)) { 14 | maxGasPrice = gasPrice; 15 | } 16 | 17 | const feeData = await provider.getFeeData(); 18 | 19 | // the wallet provider might not return maxPriorityFeePerGas in feeData 20 | // in which case we should fallback to the usual getGasPrice flow handled below 21 | if (feeData && feeData.maxPriorityFeePerGas) { 22 | txnOpts.maxFeePerGas = maxGasPrice; 23 | txnOpts.maxPriorityFeePerGas = feeData.maxPriorityFeePerGas.add(premium); 24 | return; 25 | } 26 | } 27 | 28 | txnOpts.gasPrice = gasPrice.add(premium); 29 | return; 30 | } 31 | 32 | export async function getGasLimit(contract: Contract, method, params = [], value) { 33 | const defaultValue = bigNumberify(0); 34 | 35 | if (!value) { 36 | value = defaultValue; 37 | } 38 | 39 | let gasLimit = await contract.estimateGas[method](...params, { value }); 40 | 41 | if (gasLimit.lt(22000)) { 42 | gasLimit = bigNumberify(22000)!; 43 | } 44 | 45 | return gasLimit.mul(11000).div(10000); // add a 10% buffer 46 | } 47 | -------------------------------------------------------------------------------- /src/lib/dates.ts: -------------------------------------------------------------------------------- 1 | import { format as formatDateFn } from "date-fns"; 2 | 3 | export function formatDateTime(time: number) { 4 | return formatDateFn(time * 1000, "dd MMM yyyy, h:mm a"); 5 | } 6 | 7 | export function formatDate(time: number) { 8 | return formatDateFn(time * 1000, "dd MMM yyyy"); 9 | } 10 | 11 | export function getTimeRemaining(time: number) { 12 | const now = parseInt(String(Date.now() / 1000)); 13 | if (time < now) { 14 | return "0h 0m"; 15 | } 16 | const diff = time - now; 17 | const hours = parseInt(String(diff / (60 * 60))); 18 | const minutes = parseInt(String((diff - hours * 60 * 60) / 60)); 19 | return `${hours}h ${minutes}m`; 20 | } 21 | 22 | export function isValidTimestamp(timestamp: any) { 23 | return new Date(timestamp).getTime() > 0; 24 | } 25 | -------------------------------------------------------------------------------- /src/lib/downloadImage.ts: -------------------------------------------------------------------------------- 1 | export default async function downloadImage(dataURI: string, filename: string) { 2 | const blob = await (await fetch(dataURI)).blob(); 3 | if (typeof window.navigator.msSaveBlob !== "undefined") { 4 | // IE doesn't allow using a blob object directly as link href. 5 | // Workaround for "HTML7007: One or more blob URLs were 6 | // revoked by closing the blob for which they were created. 7 | // These URLs will no longer resolve as the data backing 8 | // the URL has been freed." 9 | window.navigator.msSaveBlob(blob, filename); 10 | return; 11 | } 12 | // Other browsers 13 | // Create a link pointing to the ObjectURL containing the blob 14 | const blobURL = window.URL.createObjectURL(blob); 15 | const tempLink = document.createElement("a"); 16 | tempLink.style.display = "none"; 17 | tempLink.href = blobURL; 18 | tempLink.setAttribute("download", filename); 19 | // Safari thinks _blank anchor are pop ups. We only want to set _blank 20 | // target if the browser does not support the HTML5 download attribute. 21 | // This allows you to download files in desktop safari if pop up blocking 22 | // is enabled. 23 | if (typeof tempLink.download === "undefined") { 24 | tempLink.setAttribute("target", "_blank"); 25 | } 26 | document.body.appendChild(tempLink); 27 | tempLink.click(); 28 | document.body.removeChild(tempLink); 29 | setTimeout(() => { 30 | // For Firefox it is necessary to delay revoking the ObjectURL 31 | window.URL.revokeObjectURL(blobURL); 32 | }, 100); 33 | } 34 | -------------------------------------------------------------------------------- /src/lib/helperToast.ts: -------------------------------------------------------------------------------- 1 | import { toast, ToastContent, ToastOptions } from "react-toastify"; 2 | 3 | export const helperToast = { 4 | success: (content: ToastContent, opts?: ToastOptions) => { 5 | toast.dismiss(); 6 | toast.success(content, opts); 7 | }, 8 | error: (content: ToastContent, opts?: ToastOptions) => { 9 | toast.dismiss(); 10 | toast.error(content, opts); 11 | }, 12 | }; 13 | -------------------------------------------------------------------------------- /src/lib/i18n.js: -------------------------------------------------------------------------------- 1 | import { i18n } from "@lingui/core"; 2 | import { en, es, zh, ko, ru, ja, fr } from "make-plural/plurals"; 3 | import { LANGUAGE_LOCALSTORAGE_KEY } from "config/localStorage"; 4 | 5 | export const locales = { 6 | en: "English", 7 | es: "Spanish", 8 | // zh: "Chinese", 9 | ko: "Korean", 10 | // ru: "Russian", 11 | ja: "Japanese", 12 | // fr: "French", 13 | }; 14 | 15 | export const defaultLocale = "en"; 16 | 17 | i18n.loadLocaleData({ 18 | en: { plurals: en }, 19 | es: { plurals: es }, 20 | zh: { plurals: zh }, 21 | ko: { plurals: ko }, 22 | ru: { plurals: ru }, 23 | ja: { plurals: ja }, 24 | fr: { plurals: fr }, 25 | }); 26 | 27 | export async function dynamicActivate(locale) { 28 | const { messages } = await import(`@lingui/loader!locales/${locale}/messages.po`); 29 | localStorage.setItem(LANGUAGE_LOCALSTORAGE_KEY, locale); 30 | i18n.load(locale, messages); 31 | i18n.activate(locale); 32 | } 33 | -------------------------------------------------------------------------------- /src/lib/localStorage/index.ts: -------------------------------------------------------------------------------- 1 | import { useLocalStorage } from "react-use"; 2 | import { useCallback } from "react"; 3 | 4 | export function useLocalStorageByChainId( 5 | chainId: number, 6 | key: string, 7 | defaultValue: T 8 | ): [T | undefined, (value: T) => void] { 9 | const [internalValue, setInternalValue] = useLocalStorage(key, {}); 10 | 11 | const setValue = useCallback( 12 | (value) => { 13 | setInternalValue((internalValue) => { 14 | if (typeof value === "function") { 15 | value = value(internalValue?.[chainId] || defaultValue); 16 | } 17 | 18 | const newInternalValue = { 19 | ...internalValue, 20 | [chainId]: value, 21 | }; 22 | return newInternalValue; 23 | }); 24 | }, 25 | [chainId, setInternalValue, defaultValue] 26 | ); 27 | 28 | let value; 29 | 30 | if (internalValue && chainId in internalValue) { 31 | value = internalValue[chainId]; 32 | } else { 33 | value = defaultValue; 34 | } 35 | 36 | return [value, setValue]; 37 | } 38 | 39 | export function useLocalStorageSerializeKey( 40 | key: string, 41 | value: T, 42 | opts?: { 43 | raw: boolean; 44 | serializer: (val: T) => string; 45 | deserializer: (value: string) => T; 46 | } 47 | ) { 48 | key = JSON.stringify(key); 49 | 50 | return useLocalStorage(key, value, opts); 51 | } 52 | -------------------------------------------------------------------------------- /src/lib/rpc/index.ts: -------------------------------------------------------------------------------- 1 | import { FALLBACK_PROVIDERS, RPC_PROVIDERS } from "config/chains"; 2 | import _ from "lodash"; 3 | import { ethers } from "ethers"; 4 | import { Web3ReactContextInterface } from "@web3-react/core/dist/types"; 5 | import { JsonRpcProvider } from "@ethersproject/providers"; 6 | 7 | export function getProvider( 8 | library: Web3ReactContextInterface["library"] | undefined, 9 | chainId: number 10 | ): JsonRpcProvider { 11 | let provider; 12 | 13 | if (library) { 14 | return library.getSigner(); 15 | } 16 | 17 | provider = _.sample(RPC_PROVIDERS[chainId]); 18 | 19 | return new ethers.providers.StaticJsonRpcProvider( 20 | provider, 21 | // @ts-ignore incorrect Network param types 22 | { chainId } 23 | ); 24 | } 25 | 26 | export function getFallbackProvider(chainId: number) { 27 | if (!FALLBACK_PROVIDERS[chainId]) { 28 | return; 29 | } 30 | 31 | const provider = _.sample(FALLBACK_PROVIDERS[chainId]); 32 | 33 | return new ethers.providers.StaticJsonRpcProvider( 34 | provider, 35 | // @ts-ignore incorrect Network param types 36 | { chainId } 37 | ); 38 | } 39 | -------------------------------------------------------------------------------- /src/lib/sleep.js: -------------------------------------------------------------------------------- 1 | export function sleep(ms) { 2 | return new Promise((resolve) => resolve(), ms); 3 | } 4 | -------------------------------------------------------------------------------- /src/lib/subgraph/clients.ts: -------------------------------------------------------------------------------- 1 | import { createClient } from "./utils"; 2 | import { SUBGRAPH_URLS } from "config/subgraph"; 3 | import { ARBITRUM, ARBITRUM_TESTNET, AVALANCHE } from "config/chains"; 4 | 5 | export const chainlinkClient = createClient(SUBGRAPH_URLS.common.chainLink); 6 | 7 | export const arbitrumGraphClient = createClient(SUBGRAPH_URLS[ARBITRUM].stats); 8 | export const arbitrumReferralsGraphClient = createClient(SUBGRAPH_URLS[ARBITRUM].referrals); 9 | export const nissohGraphClient = createClient(SUBGRAPH_URLS[ARBITRUM].nissohVault); 10 | 11 | export const avalancheGraphClient = createClient(SUBGRAPH_URLS[AVALANCHE].stats); 12 | export const avalancheReferralsGraphClient = createClient(SUBGRAPH_URLS[AVALANCHE].referrals); 13 | 14 | export function getGmxGraphClient(chainId: number) { 15 | if (chainId === ARBITRUM) { 16 | return arbitrumGraphClient; 17 | } else if (chainId === AVALANCHE) { 18 | return avalancheGraphClient; 19 | } else if (chainId === ARBITRUM_TESTNET) { 20 | return null; 21 | } 22 | 23 | throw new Error(`Unsupported chain ${chainId}`); 24 | } 25 | -------------------------------------------------------------------------------- /src/lib/subgraph/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./clients"; 2 | export * from "./utils"; 3 | -------------------------------------------------------------------------------- /src/lib/subgraph/utils.ts: -------------------------------------------------------------------------------- 1 | import { ApolloClient, InMemoryCache } from "@apollo/client"; 2 | 3 | export function createClient(uri: string) { 4 | return new ApolloClient({ 5 | uri, 6 | cache: new InMemoryCache(), 7 | }); 8 | } 9 | -------------------------------------------------------------------------------- /src/lib/useDebounce.js: -------------------------------------------------------------------------------- 1 | import { useEffect, useState } from "react"; 2 | 3 | export function useDebounce(value, delay) { 4 | // State and setters for debounced value 5 | const [debouncedValue, setDebouncedValue] = useState(value); 6 | 7 | useEffect( 8 | () => { 9 | // Update debounced value after delay 10 | const handler = setTimeout(() => { 11 | setDebouncedValue(value); 12 | }, delay); 13 | // Cancel the timeout if value changes (also on delay change or unmount) 14 | // This is how we prevent debounced value from updating if value is changed ... 15 | // .. within the delay period. Timeout gets cleared and restarted. 16 | return () => { 17 | clearTimeout(handler); 18 | }; 19 | }, 20 | [value, delay] // Only re-call effect if value or delay changes 21 | ); 22 | 23 | return debouncedValue; 24 | } 25 | -------------------------------------------------------------------------------- /src/lib/useEffectDebugger.js: -------------------------------------------------------------------------------- 1 | import { useEffect, useRef } from "react"; 2 | 3 | const usePrevious = (value, initialValue) => { 4 | const ref = useRef(initialValue); 5 | useEffect(() => { 6 | ref.current = value; 7 | }); 8 | return ref.current; 9 | }; 10 | 11 | const useEffectDebugger = (effectHook, dependencies, dependencyNames = []) => { 12 | const previousDeps = usePrevious(dependencies, []); 13 | 14 | const changedDeps = dependencies.reduce((acc, dependency, index) => { 15 | if (dependency !== previousDeps[index]) { 16 | const keyName = dependencyNames[index] || index; 17 | return { 18 | ...acc, 19 | [keyName]: { 20 | before: previousDeps[index], 21 | after: dependency, 22 | }, 23 | }; 24 | } 25 | 26 | return acc; 27 | }, {}); 28 | 29 | if (Object.keys(changedDeps).length) { 30 | console.log("[use-effect-debugger] ", changedDeps); 31 | } 32 | 33 | useEffect(effectHook, [...dependencies, effectHook]); 34 | }; 35 | 36 | export default useEffectDebugger; 37 | -------------------------------------------------------------------------------- /src/lib/useLoadImage.js: -------------------------------------------------------------------------------- 1 | import { useEffect, useState } from "react"; 2 | 3 | export default function useLoadImage(src) { 4 | const [sourceLoaded, setSourceLoaded] = useState(null); 5 | 6 | useEffect(() => { 7 | const img = new Image(); 8 | img.src = src; 9 | img.onload = () => setSourceLoaded(src); 10 | }, [src]); 11 | 12 | return sourceLoaded; 13 | } 14 | -------------------------------------------------------------------------------- /src/lib/useLockBodyScroll.ts: -------------------------------------------------------------------------------- 1 | import { disableBodyScroll, enableBodyScroll, clearAllBodyScrollLocks } from "body-scroll-lock"; 2 | import { RefObject, useEffect } from "react"; 3 | 4 | export const TOUCH_MOVE_CONTAINER_CLASS_NAME = "DiableScroll-touch-move-container"; 5 | 6 | // @see https://github.com/willmcpo/body-scroll-lock#allowtouchmove 7 | const allowTouchMoveFn = (el: HTMLElement) => { 8 | while (el && el !== document.body) { 9 | if (el.className?.includes?.(TOUCH_MOVE_CONTAINER_CLASS_NAME)) return true; 10 | 11 | el = el.parentElement as HTMLElement; 12 | } 13 | }; 14 | 15 | export default function useLockBodyScroll( 16 | ref: RefObject, 17 | isVisible: boolean, 18 | opts: { 19 | disableLock?: boolean; 20 | allowTouchMove?: boolean; 21 | } = {} 22 | ) { 23 | useEffect(() => { 24 | if (opts.disableLock) { 25 | return; 26 | } 27 | 28 | if (ref.current) { 29 | if (isVisible) { 30 | disableBodyScroll(ref.current, { 31 | allowTouchMove: opts.allowTouchMove ? allowTouchMoveFn : undefined, 32 | }); 33 | } else { 34 | enableBodyScroll(ref.current); 35 | } 36 | } 37 | 38 | return () => clearAllBodyScrollLocks(); 39 | 40 | // needs ref.current in deps, not just ref 41 | // eslint-disable-next-line react-hooks/exhaustive-deps 42 | }, [ref.current, opts.allowTouchMove, opts.disableLock, isVisible]); 43 | } 44 | -------------------------------------------------------------------------------- /src/lib/usePrevious.js: -------------------------------------------------------------------------------- 1 | import { useEffect, useRef } from "react"; 2 | 3 | export function usePrevious(value) { 4 | const ref = useRef(); 5 | useEffect(() => { 6 | ref.current = value; 7 | }); 8 | return ref.current; 9 | } 10 | -------------------------------------------------------------------------------- /src/lib/useRouteQuery.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { useLocation } from "react-router-dom"; 3 | 4 | export default function useRouteQuery() { 5 | const { search } = useLocation(); 6 | return React.useMemo(() => new URLSearchParams(search), [search]); 7 | } 8 | -------------------------------------------------------------------------------- /src/lib/useScrollToTop.js: -------------------------------------------------------------------------------- 1 | import { useEffect } from "react"; 2 | import { useHistory } from "react-router-dom"; 3 | 4 | export default function useScrollToTop() { 5 | const history = useHistory(); 6 | useEffect(() => { 7 | const unlisten = history.listen(() => { 8 | window.scrollTo(0, 0); 9 | }); 10 | return () => { 11 | unlisten(); 12 | }; 13 | }, [history]); 14 | } 15 | -------------------------------------------------------------------------------- /src/pages/Actions/Actions.css: -------------------------------------------------------------------------------- 1 | .Actions { 2 | padding: 0 3.565rem; 3 | padding-top: 3.1rem; 4 | } 5 | 6 | .Actions-section { 7 | padding-bottom: 4.65rem; 8 | } 9 | 10 | .Actions-title { 11 | margin-bottom: 1.5rem; 12 | } 13 | 14 | .Actions input { 15 | font-size: 1.5rem; 16 | padding: 0; 17 | margin-left: 0.8rem; 18 | } 19 | 20 | .Actions .PositionsList .Exchange-list-action { 21 | display: none; 22 | } 23 | 24 | .Actions .PositionsList .App-button-option { 25 | display: none; 26 | } 27 | -------------------------------------------------------------------------------- /src/pages/BeginAccountTransfer/BeginAccountTransfer.css: -------------------------------------------------------------------------------- 1 | .ValidationRow { 2 | display: grid; 3 | grid-template-columns: auto 1fr; 4 | font-size: 1.5rem; 5 | } 6 | 7 | .ValidationRow-icon-container { 8 | display: flex; 9 | justify-content: center; 10 | align-items: center; 11 | } 12 | 13 | .ValidationRow-icon { 14 | margin-right: 1.5rem; 15 | } 16 | 17 | .BeginAccountTransfer .ValidationRow { 18 | margin-bottom: 1.5rem; 19 | font-size: 1.5rem; 20 | } 21 | 22 | .BeginAccountTransfer-validations { 23 | margin-bottom: 2.325rem; 24 | } 25 | 26 | .BeginAccountTransfer .Modal .App-cta { 27 | display: block; 28 | text-align: center; 29 | font-size: 1.5rem; 30 | } 31 | -------------------------------------------------------------------------------- /src/pages/Buy/Buy.css: -------------------------------------------------------------------------------- 1 | .BuyGMXGLP { 2 | background: #101124; 3 | justify-content: space-between; 4 | } 5 | 6 | .BuyGMXGLP-container { 7 | padding: 0 0 3.1rem 0; 8 | width: 100%; 9 | } 10 | 11 | .BuyGMXGLP-container .section-title-content { 12 | justify-content: flex-start; 13 | } 14 | 15 | @media (max-width: 400px) { 16 | .BuyGMXGLP-container { 17 | padding-left: 1.6rem!important; 18 | padding-right: 1.6rem!important; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/pages/Buy/Buy.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Trans } from "@lingui/macro"; 3 | import Footer from "components/Footer/Footer"; 4 | import "./Buy.css"; 5 | import TokenCard from "components/TokenCard/TokenCard"; 6 | import buyGMXIcon from "img/buy_gmx.svg"; 7 | import SEO from "components/Common/SEO"; 8 | import { getPageTitle } from "lib/legacy"; 9 | 10 | export default function BuyGMXGLP() { 11 | return ( 12 | 13 |
14 |
15 |
16 |
17 | buyGMXIcon 18 |
19 |
20 |
21 | Buy GMX or GLP 22 |
23 |
24 |
25 | 26 |
27 |
28 |
29 |
30 | ); 31 | } 32 | -------------------------------------------------------------------------------- /src/pages/BuyGlp/BuyGlp.css: -------------------------------------------------------------------------------- 1 | .buy-glp-content { 2 | padding-top: 4.65rem; 3 | } -------------------------------------------------------------------------------- /src/pages/CompleteAccountTransfer/CompleteAccountTransfer.css: -------------------------------------------------------------------------------- 1 | .CompleteAccountTransfer .Modal .App-cta { 2 | display: block; 3 | text-align: center; 4 | } 5 | -------------------------------------------------------------------------------- /src/pages/Dashboard/AssetDropdown.css: -------------------------------------------------------------------------------- 1 | .asset-menu-items { 2 | position: absolute; 3 | border: 1px solid #32344c; 4 | border-radius: 0.4rem; 5 | background: var(--dark-blue); 6 | outline: none; 7 | z-index: 100; 8 | } 9 | 10 | .center-both { 11 | display: flex; 12 | justify-content: center; 13 | align-items: center; 14 | } 15 | 16 | .dropdown-arrow { 17 | margin-left: 0.8rem; 18 | cursor: pointer; 19 | color: white; 20 | opacity: 0.8; 21 | } 22 | .dropdown-arrow:hover { 23 | opacity: 1; 24 | } 25 | 26 | .asset-item { 27 | display: flex; 28 | align-items: center; 29 | cursor: pointer; 30 | color: #a0a3c4; 31 | text-decoration: none; 32 | padding: 0.85rem 0.8rem; 33 | } 34 | .asset-item:hover { 35 | background: var(--dark-blue-hover); 36 | color: white; 37 | border-radius: 0.4rem; 38 | } 39 | .asset-item p { 40 | margin: 0; 41 | margin-left: 0.5rem; 42 | } 43 | -------------------------------------------------------------------------------- /src/pages/Dashboard/Dashboard.css: -------------------------------------------------------------------------------- 1 | .Dashboard-fee-info { 2 | text-align: center; 3 | line-height: 2.325rem; 4 | } 5 | 6 | .Dashboard-note { 7 | text-align: center; 8 | } 9 | 10 | .Dashboard-list { 11 | display: grid; 12 | grid-template-columns: 1fr 1fr 1fr; 13 | padding: 3.1rem; 14 | grid-gap: 1.5rem; 15 | } 16 | 17 | .Dashboard-token-card .Dashboard-token-title-options { 18 | opacity: 0.5; 19 | filter: sepia(100%) hue-rotate(190deg); 20 | } 21 | 22 | .Dashboard-token-card:hover .Dashboard-token-title-options { 23 | opacity: 1; 24 | filter: none; 25 | } 26 | 27 | .Dashboard-token-title { 28 | display: grid; 29 | grid-template-columns: auto auto; 30 | } 31 | 32 | .Dashboard-token-title-options { 33 | text-align: right; 34 | } 35 | 36 | .Dashboard-token-title img { 37 | cursor: pointer; 38 | height: 18.5rem; 39 | margin-left: 0.465rem; 40 | opacity: 0.9; 41 | } 42 | 43 | .Dashboard-token-title img:hover { 44 | opacity: 1; 45 | } 46 | 47 | .Dashboard-fees { 48 | padding-bottom: 4.65rem; 49 | } 50 | 51 | @media (max-width: 700px) { 52 | .Dashboard-list { 53 | grid-template-columns: 1fr; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/pages/Dashboard/Dashboard.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | import DashboardV2 from "./DashboardV2"; 4 | 5 | export default function Dashboard(props) { 6 | return ; 7 | } 8 | -------------------------------------------------------------------------------- /src/pages/Ecosystem/Ecosystem.css: -------------------------------------------------------------------------------- 1 | .DashboardV2-projects { 2 | display: grid; 3 | grid-template-columns: 1fr 1fr; 4 | grid-gap: 1.5rem; 5 | } 6 | 7 | @media (max-width: 900px) { 8 | .DashboardV2-projects { 9 | grid-template-columns: 1fr; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/pages/Jobs/Jobs.css: -------------------------------------------------------------------------------- 1 | .jobs-page-body { 2 | /* margin: 3rem 0; */ 3 | display: grid; 4 | grid-template-columns: repeat(2, 1fr); 5 | grid-gap: 2rem; 6 | color: rgba(255, 255, 255, 0.7); 7 | } 8 | 9 | .jobs-page-body a { 10 | color: #b7b7bd; 11 | } 12 | 13 | .body-para .subheading { 14 | margin: 0; 15 | } 16 | 17 | .mt-lg { 18 | margin-top: 2rem; 19 | } 20 | 21 | .jobs-contact { 22 | line-height: 1.5; 23 | } 24 | 25 | @media (max-width: 1000px) { 26 | .jobs-page-body { 27 | grid-template-columns: 1fr; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/pages/NftWallet/NftWallet.css: -------------------------------------------------------------------------------- 1 | .NftWallet input { 2 | border: 1px solid rgba(255, 255, 255, 0.2); 3 | font-size: 1.5rem; 4 | width: 100%; 5 | box-sizing: border-box; 6 | } 7 | 8 | .NftWallet label { 9 | display: block; 10 | margin-bottom: 0.8rem; 11 | } 12 | 13 | .NftWallet-content { 14 | padding: 4.65rem; 15 | padding-top: 1.5rem; 16 | max-width: 38.75rem; 17 | } 18 | 19 | .NftWallet-row { 20 | margin-bottom: 1.5rem; 21 | } 22 | 23 | .NftWallet button { 24 | margin-top: 0.8rem; 25 | } 26 | -------------------------------------------------------------------------------- /src/pages/OrdersOverview/OrdersOverview.css: -------------------------------------------------------------------------------- 1 | .Orders-overview { 2 | font-size: 1.4rem; 3 | margin: 1.5rem 3.1rem; 4 | } 5 | 6 | .Orders-overview-stats { 7 | line-height: 1.5; 8 | } 9 | 10 | .Orders-overview-table { 11 | border-collapse: collapse; 12 | } 13 | 14 | .Orders-overview th { 15 | opacity: 0.5; 16 | font-weight: normal; 17 | text-align: left; 18 | padding: 0.8rem 1.5rem 0.8rem 0; 19 | } 20 | 21 | .Orders-overview td { 22 | border-top: 1px solid rgba(255, 255, 255, 0.1); 23 | padding: 0.8rem 1.5rem 0.8rem 0; 24 | } 25 | 26 | .Orders-overview .near { 27 | color: orange; 28 | } 29 | 30 | .Orders-overview-action { 31 | background: none; 32 | border: none; 33 | text-decoration: underline; 34 | color: #fff; 35 | } 36 | 37 | .Orders-overview-action { 38 | background: none; 39 | border: none; 40 | text-decoration: underline; 41 | color: #fff; 42 | } 43 | -------------------------------------------------------------------------------- /src/pages/PageNotFound/PageNotFound.css: -------------------------------------------------------------------------------- 1 | .page-not-found-container { 2 | display: flex; 3 | align-items: center; 4 | justify-content: center; 5 | min-height: 60vh; 6 | margin-bottom: 7rem; 7 | } 8 | 9 | .page-not-found { 10 | text-align: center; 11 | } 12 | .page-not-found img { 13 | max-width: 225px; 14 | } 15 | .go-back span { 16 | color: #a0a3c4; 17 | } 18 | .go-back a { 19 | color: white; 20 | } 21 | 22 | @media (max-width: 500px) { 23 | .page-not-found img { 24 | max-width: 200px; 25 | } 26 | .page-not-found { 27 | margin-top: 2.5rem; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/pages/PageNotFound/PageNotFound.js: -------------------------------------------------------------------------------- 1 | import SEO from "components/Common/SEO"; 2 | import Footer from "components/Footer/Footer"; 3 | import { getPageTitle } from "lib/legacy"; 4 | import "./PageNotFound.css"; 5 | 6 | import { getHomeUrl, getTradePageUrl } from "lib/legacy"; 7 | 8 | function PageNotFound() { 9 | const homeUrl = getHomeUrl(); 10 | const tradePageUrl = getTradePageUrl(); 11 | 12 | return ( 13 | 14 |
15 |
16 |
17 |

Page not found

18 |

19 | Return to 20 | Homepage or Trade 21 |

22 |
23 |
24 |
25 |
26 |
27 | ); 28 | } 29 | 30 | export default PageNotFound; 31 | -------------------------------------------------------------------------------- /src/pages/PositionsOverview/PositionsOverview.css: -------------------------------------------------------------------------------- 1 | .Positions-overview { 2 | font-size: 1.4rem; 3 | margin: 1.5rem 3.1rem; 4 | } 5 | 6 | .Positions-overview-stats { 7 | line-height: 1.5; 8 | } 9 | 10 | .Positions-overview-table { 11 | border-collapse: collapse; 12 | } 13 | 14 | .Positions-overview th { 15 | opacity: 0.5; 16 | font-weight: normal; 17 | text-align: left; 18 | padding: 0.8rem 1.5rem 0.8rem 0; 19 | } 20 | 21 | .Positions-overview td { 22 | border-top: 1px solid rgba(255, 255, 255, 0.1); 23 | padding: 0.8rem 1.5rem 0.8rem 0; 24 | } 25 | 26 | .Positions-overview .near { 27 | color: orange; 28 | } 29 | .Positions-overview .near.negative { 30 | color: #fa3c58; 31 | } 32 | -------------------------------------------------------------------------------- /src/pages/ReferralTerms/ReferralTerms.css: -------------------------------------------------------------------------------- 1 | .center { 2 | text-align: center; 3 | } 4 | .section { 5 | margin-bottom: 4.65rem; 6 | } 7 | .Page-subtitle { 8 | font-size: 2.325rem; 9 | font-weight: 500; 10 | margin: 1.5rem 0; 11 | } 12 | .content { 13 | margin-top: 4.65rem; 14 | } 15 | .body-text { 16 | margin: 0px; 17 | font-weight: 400; 18 | font-size: 1.5rem; 19 | line-height: 2.325rem; 20 | margin-bottom: 1.5rem; 21 | color: rgba(255, 255, 255, 0.7); 22 | /* color: #a0a3c4; */ 23 | } 24 | 25 | .body-title { 26 | font-weight: 500; 27 | margin-bottom: 1.5rem; 28 | font-size: 2.325rem; 29 | } 30 | -------------------------------------------------------------------------------- /src/pages/SellGlp/SellGlp.css: -------------------------------------------------------------------------------- 1 | .SellGlp-content { 2 | display: grid; 3 | grid-template-columns: 1fr 43.4rem; 4 | grid-gap: 1.5rem; 5 | margin-top: 0.8rem; 6 | padding: 3.1rem; 7 | padding-top: 1.5rem; 8 | } 9 | 10 | .SellGlp-box { 11 | padding: 1.5rem; 12 | } 13 | 14 | .SellGlp-cta { 15 | margin-top: 0.8rem; 16 | } 17 | 18 | @media (max-width: 900px) { 19 | .SellGlp-content { 20 | grid-template-columns: 1fr; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/pages/Stake/Stake.css: -------------------------------------------------------------------------------- 1 | .Stake-note { 2 | text-align: center; 3 | margin-bottom: 0.465rem; 4 | } 5 | 6 | .Stake-cards { 7 | display: grid; 8 | grid-template-columns: 1fr 1fr; 9 | padding: 3.1rem; 10 | grid-gap: 1.5rem; 11 | margin-top: 0.8rem; 12 | } 13 | 14 | .StakeModal .Modal-content { 15 | width: 31rem; 16 | } 17 | .StakeModal .Modal-body { 18 | font-size: 1.5rem; 19 | } 20 | 21 | .Stake-warning { 22 | text-align: center; 23 | margin-top: 0.465rem; 24 | } 25 | 26 | @media (max-width: 800px) { 27 | .StakeModal .Modal-content { 28 | width: auto; 29 | } 30 | .Stake-cards { 31 | grid-template-columns: 1fr; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/pages/Stake/Stake.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | import { AVALANCHE, getConstant } from "config/chains"; 4 | 5 | import StakeV1 from "./StakeV1"; 6 | import StakeV2 from "./StakeV2"; 7 | 8 | export default function Stake(props) { 9 | const chainId = AVALANCHE; 10 | const isV2 = getConstant(chainId, "v2"); 11 | return isV2 ? : ; 12 | } 13 | -------------------------------------------------------------------------------- /src/pages/Stake/StakeV2.css: -------------------------------------------------------------------------------- 1 | .StakeV2 .Page-title-section { 2 | position: relative; 3 | z-index: 2; 4 | } 5 | 6 | .VesterDepositModal-info-rows { 7 | margin-bottom: 0.8rem; 8 | } 9 | 10 | .CompoundModal-menu { 11 | margin-bottom: 0.8rem; 12 | } 13 | 14 | .CompoundModal-menu .Checkbox { 15 | margin-bottom: 0.465rem; 16 | } 17 | 18 | .StakeV2-address-input { 19 | padding: 1.5rem 3.41rem; 20 | padding-bottom: 0; 21 | } 22 | 23 | .StakeV2-buy-gmx-modal .Modal-content { 24 | max-width: 46.5rem; 25 | } 26 | 27 | .StakeV2-address-input input { 28 | box-sizing: border-box; 29 | width: 100%; 30 | font-size: 1.7rem; 31 | } 32 | 33 | .StakeV2-boost-bar { 34 | overflow: hidden; 35 | vertical-align: middle; 36 | margin-left: 0.31rem; 37 | border-radius: 2px; 38 | width: 1.5rem; 39 | height: 0.8rem; 40 | border: 1px solid rgba(255, 255, 255, 0.5); 41 | display: inline-block; 42 | position: relative; 43 | } 44 | 45 | .StakeV2-boost-icon { 46 | font-size: 1.085rem; 47 | z-index: 2; 48 | } 49 | 50 | .StakeV2-boost-bar-fill { 51 | z-index: 1; 52 | position: absolute; 53 | left: 0; 54 | top: 0; 55 | bottom: 0; 56 | background: rgba(255, 255, 255, 0.7); 57 | } 58 | 59 | .StakeV2-cards { 60 | display: grid; 61 | grid-template-columns: 1fr 1fr; 62 | grid-gap: 1.5rem; 63 | } 64 | 65 | @media (max-width: 900px) { 66 | .StakeV2-cards { 67 | grid-template-columns: 1fr; 68 | } 69 | 70 | .StakeV2-content { 71 | min-height: 100vh; 72 | } 73 | 74 | .StakeV2-total-rewards-card { 75 | grid-row: 4; 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /src/pages/TermsAndConditions/TermsAndConditions.css: -------------------------------------------------------------------------------- 1 | .center { 2 | text-align: center; 3 | } 4 | .section { 5 | margin-bottom: 4.65rem; 6 | } 7 | .Page-subtitle { 8 | font-size: 2.325rem; 9 | font-weight: 500; 10 | margin: 1.5rem 0; 11 | } 12 | .content { 13 | margin-top: 4.65rem; 14 | } 15 | .body-text { 16 | margin: 0px; 17 | font-weight: 400; 18 | font-size: 1.5rem; 19 | line-height: 2.325rem; 20 | margin-bottom: 1.5rem; 21 | color: rgba(255, 255, 255, 0.7); 22 | /* color: #a0a3c4; */ 23 | } 24 | 25 | .body-title { 26 | font-weight: 500; 27 | margin-bottom: 1.5rem; 28 | font-size: 2.325rem; 29 | } 30 | 31 | .list-style-none { 32 | list-style: none; 33 | } 34 | .list-style-none li { 35 | padding-bottom: 0; 36 | } 37 | -------------------------------------------------------------------------------- /src/react-app-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /src/reportWebVitals.js: -------------------------------------------------------------------------------- 1 | const reportWebVitals = (onPerfEntry) => { 2 | if (onPerfEntry && onPerfEntry instanceof Function) { 3 | import("web-vitals").then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => { 4 | getCLS(onPerfEntry); 5 | getFID(onPerfEntry); 6 | getFCP(onPerfEntry); 7 | getLCP(onPerfEntry); 8 | getTTFB(onPerfEntry); 9 | }); 10 | } 11 | }; 12 | 13 | export default reportWebVitals; 14 | -------------------------------------------------------------------------------- /src/styles/Input.css: -------------------------------------------------------------------------------- 1 | .input-form { 2 | max-width: 38.75rem; 3 | } 4 | 5 | .input-row { 6 | margin-bottom: 1.5rem; 7 | } 8 | 9 | .input-label { 10 | display: block; 11 | margin-bottom: 0.8rem; 12 | font-size: 1.5rem; 13 | } 14 | 15 | .text-input { 16 | border: 1px solid rgba(255, 255, 255, 0.2); 17 | font-size: 1.5rem; 18 | width: 100%; 19 | box-sizing: border-box; 20 | } 21 | -------------------------------------------------------------------------------- /src/typings.d.ts: -------------------------------------------------------------------------------- 1 | import "@web3-react"; 2 | 3 | declare global { 4 | interface Window { 5 | ethereum?: any; 6 | } 7 | interface Navigator { 8 | msSaveBlob?: (blob: any, defaultName?: string) => boolean; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "lib": [ 5 | "dom", 6 | "dom.iterable", 7 | "esnext" 8 | ], 9 | "allowJs": true, 10 | "skipLibCheck": true, 11 | "esModuleInterop": true, 12 | "allowSyntheticDefaultImports": true, 13 | "strict": false, 14 | "noImplicitAny": false, 15 | "strictNullChecks": true, 16 | "strictFunctionTypes": true, 17 | "strictBindCallApply": true, 18 | "noImplicitThis": true, 19 | "forceConsistentCasingInFileNames": true, 20 | "noFallthroughCasesInSwitch": true, 21 | "module": "esnext", 22 | "moduleResolution": "node", 23 | "resolveJsonModule": true, 24 | "isolatedModules": true, 25 | "noEmit": true, 26 | "jsx": "react-jsx", 27 | "baseUrl": "./src", 28 | }, 29 | "include": [ 30 | "src" 31 | ], 32 | } 33 | --------------------------------------------------------------------------------