├── .dockerignore
├── .github
└── workflows
│ └── docker-image.yml
├── .gitignore
├── .husky
└── pre-commit
├── .prettierrc
├── Dockerfile
├── LICENSE
├── README.md
├── banner.png
├── docker-compose.yml
├── example.env
├── index.html
├── package-lock.json
├── package.json
├── postcss.config.js
├── public
├── PriceIdsString.txt
├── _headers
├── favicon.svg
├── fonts
│ └── runddisplay
│ │ ├── runddisplay-black.woff
│ │ ├── runddisplay-bold.woff
│ │ ├── runddisplay-extrabold.woff
│ │ ├── runddisplay-light.woff
│ │ ├── runddisplay-medium.woff
│ │ ├── runddisplay-regular.woff
│ │ ├── runddisplay-semibold.woff
│ │ └── runddisplay-thin.woff
├── img
│ └── assets
│ │ ├── abusd.svg
│ │ ├── adai.svg
│ │ ├── adm.svg
│ │ ├── afrax.svg
│ │ ├── akt.svg
│ │ ├── alink.svg
│ │ ├── alter.svg
│ │ ├── amber.jpg
│ │ ├── ampkuji.svg
│ │ ├── ampluna.svg
│ │ ├── ampwhale.svg
│ │ ├── andr.png
│ │ ├── archway.svg
│ │ ├── atom.svg
│ │ ├── atom_datom_lp.svg
│ │ ├── atom_statom_lp.svg
│ │ ├── auni.svg
│ │ ├── axl.svg
│ │ ├── binj.png
│ │ ├── bkuji.png
│ │ ├── bld.svg
│ │ ├── bluna.png
│ │ ├── butt.png
│ │ ├── celestia.svg
│ │ ├── cheq.svg
│ │ ├── cmdx.svg
│ │ ├── cmst.svg
│ │ ├── composable.svg
│ │ ├── coreum.svg
│ │ ├── cre.svg
│ │ ├── datom.svg
│ │ ├── deposit.svg
│ │ ├── dot.svg
│ │ ├── dshd.svg
│ │ ├── dvpn.svg
│ │ ├── dydx.svg
│ │ ├── dymension.svg
│ │ ├── eclip.svg
│ │ ├── evmos.svg
│ │ ├── fina.png
│ │ ├── fina.webp
│ │ ├── flix.svg
│ │ ├── grav.svg
│ │ ├── harbor.svg
│ │ ├── huahua.svg
│ │ ├── ibc-black.svg
│ │ ├── inj.svg
│ │ ├── ist.svg
│ │ ├── jkl.svg
│ │ ├── juno.svg
│ │ ├── kava.svg
│ │ ├── keplr.svg
│ │ ├── ksm.svg
│ │ ├── kuji.svg
│ │ ├── leap.svg
│ │ ├── luna.png
│ │ ├── luna2.svg
│ │ ├── lvn.svg
│ │ ├── migaloo.svg
│ │ ├── milktia.svg
│ │ ├── mnta.svg
│ │ ├── noble.svg
│ │ ├── nolus.svg
│ │ ├── nstk.svg
│ │ ├── ntrn.svg
│ │ ├── nyx.png
│ │ ├── orai.svg
│ │ ├── osmo.svg
│ │ ├── page.png
│ │ ├── pica.svg
│ │ ├── pstake.svg
│ │ ├── qatom.svg
│ │ ├── qck.svg
│ │ ├── robots.txt
│ │ ├── rowan.svg
│ │ ├── saga.svg
│ │ ├── scrt-white.svg
│ │ ├── scrt.svg
│ │ ├── shd.svg
│ │ ├── shill.svg
│ │ ├── silk.svg
│ │ ├── stars.svg
│ │ ├── starshell.svg
│ │ ├── statom.svg
│ │ ├── stinj.svg
│ │ ├── stjuno.svg
│ │ ├── stkatom.svg
│ │ ├── stkd-scrt.svg
│ │ ├── stkdydx.svg
│ │ ├── stluna.svg
│ │ ├── stosmo.svg
│ │ ├── stride.svg
│ │ ├── sttia.svg
│ │ ├── swth.svg
│ │ ├── syn.png
│ │ ├── umee.svg
│ │ ├── usdc.svg
│ │ ├── usdt.svg
│ │ ├── usk.svg
│ │ ├── wbnb.svg
│ │ ├── wbtc.svg
│ │ ├── weth.svg
│ │ ├── wsteth.svg
│ │ ├── xprt.svg
│ │ └── xrp.svg
├── robots.txt
└── sitemap.xml
├── src
├── App.tsx
├── assets
│ └── scss
│ │ ├── components
│ │ ├── _fonts.scss
│ │ └── fonts
│ │ │ └── _runddisplay.scss
│ │ └── index.scss
├── components
│ ├── BalanceUI.tsx
│ ├── FeeGrant
│ │ ├── FeeGrant.tsx
│ │ └── components
│ │ │ └── ActionableStatus.tsx
│ ├── FeedbackButton.tsx
│ ├── FloatingCTAButton.scss
│ ├── FloatingCTAButton.tsx
│ ├── Footer.tsx
│ ├── Header.tsx
│ ├── Navigation.tsx
│ ├── PercentagePicker.tsx
│ ├── Settings
│ │ └── Settings.tsx
│ ├── Title.tsx
│ ├── UI
│ │ ├── Badge
│ │ │ └── Badge.tsx
│ │ ├── Button
│ │ │ └── Button.tsx
│ │ └── Modal
│ │ │ └── Modal.tsx
│ └── Wallet
│ │ ├── ManageBalances
│ │ ├── Balances.scss
│ │ └── ManageBalances.tsx
│ │ ├── StatusDot.tsx
│ │ └── Wallet.tsx
├── context
│ ├── APIContext.tsx
│ ├── ConnectWalletModal.tsx
│ └── ThemeContext.tsx
├── custom.d.ts
├── hooks
│ └── useClickOutside.tsx
├── layouts
│ └── DefaultLayout.tsx
├── pages
│ ├── analytics
│ │ ├── Analytics.tsx
│ │ └── components
│ │ │ ├── AccountsChart.tsx
│ │ │ ├── ContractsChart.tsx
│ │ │ ├── RelayerChartTotal.tsx
│ │ │ ├── RelayerChartWithChainSlider.tsx
│ │ │ ├── RelayerChartWithDateSlider.tsx
│ │ │ ├── RelayerChartWithProviderSlider.tsx
│ │ │ ├── TransactionsChart.tsx
│ │ │ ├── UnbondingsChart.tsx
│ │ │ ├── ValidatorsChart.tsx
│ │ │ └── WeeklyContractsChart.tsx
│ ├── apps
│ │ ├── Apps.tsx
│ │ └── components
│ │ │ ├── FilterTag.tsx
│ │ │ ├── SkeletonLoaders
│ │ │ ├── SkeletonLoader.tsx
│ │ │ └── SkeletonLoaders.tsx
│ │ │ └── tile
│ │ │ ├── AppTile.tsx
│ │ │ └── Tag.tsx
│ ├── bridge
│ │ ├── Bridge.tsx
│ │ ├── SquidModal.tsx
│ │ ├── SwingModal.tsx
│ │ ├── SwingModal_Dark.scss
│ │ └── SwingModal_Light.scss
│ ├── dashboard
│ │ ├── Dashboard.tsx
│ │ └── components
│ │ │ ├── CurrentPrice.tsx
│ │ │ ├── HexTile.tsx
│ │ │ ├── MiniTile.tsx
│ │ │ ├── PriceVolTVLChart
│ │ │ ├── PriceVolumeTVL.tsx
│ │ │ └── components
│ │ │ │ ├── RangeSwitch.tsx
│ │ │ │ └── TypeSwitch.tsx
│ │ │ ├── QuadTile.tsx
│ │ │ ├── SocialMedia.tsx
│ │ │ └── StakingChart.tsx
│ ├── get-scrt
│ │ └── GetScrt.tsx
│ ├── ibc
│ │ ├── Ibc.tsx
│ │ └── components
│ │ │ ├── AddressInfo.tsx
│ │ │ ├── BridgingFees.tsx
│ │ │ ├── IbcForm.tsx
│ │ │ ├── IbcSelect.tsx
│ │ │ └── ibcSchema.ts
│ ├── portfolio
│ │ ├── Portfolio.tsx
│ │ └── components
│ │ │ ├── AddressQR.tsx
│ │ │ ├── BalanceChart.tsx
│ │ │ └── BalanceItem.tsx
│ ├── powertools
│ │ ├── Powertools.tsx
│ │ └── components
│ │ │ ├── ApiStatusIcon.tsx
│ │ │ ├── Message.tsx
│ │ │ └── Messages.tsx
│ ├── send
│ │ ├── Send.tsx
│ │ ├── components
│ │ │ └── SendForm.tsx
│ │ └── sendSchema.ts
│ ├── staking
│ │ ├── Staking.tsx
│ │ └── components
│ │ │ ├── ClaimRewardsModal.tsx
│ │ │ ├── ManageAutoRestakeModal.tsx
│ │ │ ├── MyValidatorsItem.tsx
│ │ │ ├── NoScrtWarning.tsx
│ │ │ ├── RestakeValidatorItem.tsx
│ │ │ ├── StakingStats
│ │ │ ├── AvailableBalance.tsx
│ │ │ ├── ClaimableRewards.tsx
│ │ │ ├── StakingAmount.tsx
│ │ │ └── StakingStats.tsx
│ │ │ ├── ValidatorItem.tsx
│ │ │ ├── ValidatorModal.tsx
│ │ │ └── validatorModalComponents
│ │ │ ├── RedelegateForm.tsx
│ │ │ ├── StakingForm.tsx
│ │ │ └── UndelegateForm.tsx
│ └── wrap
│ │ ├── Wrap.tsx
│ │ └── components
│ │ ├── FeeGrantInfoModal.tsx
│ │ ├── SCRTUnwrapWarning.tsx
│ │ ├── WrapForm.tsx
│ │ └── wrap.scss
├── services
│ ├── ibc.service.ts
│ ├── notification.service.ts
│ ├── send.service.ts
│ ├── staking.service.ts
│ ├── wallet.service.ts
│ └── wrap.service.ts
├── store
│ ├── TokenPrices.ts
│ ├── UserPreferences.ts
│ └── secretNetworkClient.ts
├── types
│ ├── ApiStatus.ts
│ ├── Currency.ts
│ ├── FeeGrantStatus.ts
│ ├── GetBalanceError.ts
│ ├── IbcMode.ts
│ ├── MessageType.ts
│ ├── NotificationType.ts
│ ├── Nullable.ts
│ ├── StakingView.ts
│ ├── Theme.ts
│ ├── TokenBalances.ts
│ ├── Validator.ts
│ ├── ValidatorRestakeStatus.ts
│ ├── WalletAPIType.ts
│ └── WrappingMode.ts
└── utils
│ ├── commons.ts
│ ├── config.ts
│ ├── env.d.ts
│ ├── tokens.ts
│ ├── useHoverOutside.ts
│ └── vite-env.d.ts
├── tailwind.config.ts
├── tsconfig.json
├── vite-plugin-whip-003.ts
└── vite.config.ts
/.dockerignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | dist
3 | build
4 | .vscode/launch.json
5 | .DS_Store
--------------------------------------------------------------------------------
/.github/workflows/docker-image.yml:
--------------------------------------------------------------------------------
1 | name: Docker Image CI
2 |
3 | permissions:
4 | contents: read
5 |
6 | on:
7 | push:
8 | branches: ["master"]
9 | pull_request:
10 | branches: ["master"]
11 |
12 | jobs:
13 | build:
14 | runs-on: ubuntu-latest
15 |
16 | steps:
17 | - uses: actions/checkout@v3
18 | - name: Build the Docker image
19 | run: docker build . --file Dockerfile --tag my-image-name:$(date +%s)
20 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # General
2 | dist
3 | build
4 | .vscode/launch.json
5 |
6 | # Dependency directories
7 | node_modules/
8 | jspm_packages/
9 |
10 | # Optional npm cache directory
11 | .npm
12 |
13 | # dotenv environment variable files
14 | .env
15 | .env.test
16 |
17 | # OS generated files
18 | .DS_Store*
19 | ehthumbs.db
20 | Icon?
21 | Thumbs.db
--------------------------------------------------------------------------------
/.husky/pre-commit:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 | . "$(dirname -- "$0")/_/husky.sh"
3 |
4 | npx lint-staged
5 |
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "semi": false,
3 | "arrowParens": "always",
4 | "singleQuote": true,
5 | "trailingComma": "none",
6 | "endOfLine": "auto",
7 | "printWidth": 120,
8 | "useTabs": false,
9 | "tabWidth": 2
10 | }
11 |
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:20-alpine
2 | WORKDIR /app
3 | COPY package.json .
4 | COPY package-lock.json .
5 | RUN npm install
6 | COPY . .
7 | EXPOSE 3000
8 | CMD ["npm", "start"]
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2023 SCRT Labs
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | 
2 |
3 | # Secret Dashboard
4 |
5 | Secret Dashboard is an entry point for new users into Secret Network. Features include a Dashboard UI for Secret Network data, IBC Transfer to and from Secret, a Wrap/Unwrap interface, a list of all active Secret dApps, a link collection to useful secret tools and more.
6 |
7 | ## System Requirements
8 |
9 | - [Node.js 20 LTS](https://nodejs.org/)
10 |
11 | ## Setup
12 |
13 | After verifying the system requirements you should be able to run a few commands to get everything set up:
14 |
15 | ```
16 | git clone https://github.com/scrtlabs/dash.scrt.network.git
17 | cd dash.scrt.network
18 | npm install
19 | ```
20 |
21 | ## Running the app
22 |
23 | ### The good ol' classic way
24 |
25 | To get the app up and running, run:
26 |
27 | ```
28 | npm run start
29 | ```
30 |
31 | The App runs on port 3000.
32 |
33 | ### Docker
34 |
35 | To get the app up and running inside Docker, run:
36 |
37 | ```
38 | docker compose up
39 | ```
40 |
41 | The App runs on port 3000. For further information check the `Dockerfile` and the `docker-compose.yml`.
42 |
43 | ## License
44 |
45 | Developed by [Secret Saturn](https://x.com/Secret_Saturn_) and [Secret Jupiter](https://x.com/secretjupiter_)
46 |
47 | Licensed under the [MIT license](https://github.com/scrtlabs/dash.scrt.network/blob/master/LICENSE.md)
48 |
--------------------------------------------------------------------------------
/banner.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/scrtlabs/dash.scrt.network/c828f76d2aeece4190dbc47606a2779a4d05e998/banner.png
--------------------------------------------------------------------------------
/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: "3.8"
2 | services:
3 | dashboard_react_app:
4 | container_name: dashboard_frontend2
5 | build: ./
6 | ports:
7 | - "3000:3000"
8 | stdin_open: true
9 | tty: true
10 | environment:
11 | - CHOKIDAR_USEPOLLING=true
12 |
--------------------------------------------------------------------------------
/example.env:
--------------------------------------------------------------------------------
1 | # Mixpanel
2 | VITE_MIXPANEL_ENABLED=false
3 | VITE_MIXPANEL_PROJECT_TOKEN=
4 |
5 | # Overrides debug mode in user settings
6 | VITE_DEBUG_MODE=false
7 |
8 |
9 | # Transak
10 | TRANSAK_API_KEY=
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Secret Dashboard
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
18 |
19 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "secret_dashboard",
3 | "description": "An entry point for new users into Secret Network",
4 | "version": "1.0.0",
5 | "scripts": {
6 | "start": "vite --host",
7 | "dev": "vite --host",
8 | "build": "tsc && vite build",
9 | "preview": "vite preview",
10 | "prepare": "husky install"
11 | },
12 | "dependencies": {
13 | "@axelar-network/axelarjs-sdk": "^0.17.2",
14 | "@buf/evmos_evmos.bufbuild_es": "^2.2.3-20240408103001-f65bdd0ffeff.1",
15 | "@cosmjs/stargate": "^0.33.0",
16 | "@emotion/styled": "^11.14.0",
17 | "@evmos/proto": "^0.2.1",
18 | "@evmos/transactions": "^0.3.2",
19 | "@floating-ui/react": "^0.27.5",
20 | "@fortawesome/free-brands-svg-icons": "^6.7.2",
21 | "@fortawesome/free-solid-svg-icons": "^6.7.2",
22 | "@fortawesome/react-fontawesome": "^0.2.2",
23 | "@mui/material": "5.16.7",
24 | "@shadeprotocol/shadejs": "^1.7.0",
25 | "@skip-go/client": "^0.16.17",
26 | "@swing.xyz/ui": "^0.67.5",
27 | "@vitejs/plugin-react": "^4.3.4",
28 | "autoprefixer": "^10.4.21",
29 | "bignumber.js": "^9.1.2",
30 | "chart.js": "^4.4.8",
31 | "formik": "^2.4.6",
32 | "long": "^5.3.1",
33 | "mixpanel-browser": "^2.61.1",
34 | "query-string": "^9.1.1",
35 | "react": "18.3.1",
36 | "react-chartjs-2": "^5.3.0",
37 | "react-copy-to-clipboard": "5.1.0",
38 | "react-dom": "18.3.1",
39 | "react-helmet-async": "^1.3.0",
40 | "react-hot-toast": "^2.5.1",
41 | "react-qrcode-logo": "^3.0.0",
42 | "react-router-dom": "^6.28.1",
43 | "react-select": "^5.9.0",
44 | "secretjs": "1.15.1",
45 | "tailwindcss": "^3.4.17",
46 | "vite": "5.4.19",
47 | "vite-tsconfig-paths": "^4.3.2",
48 | "yup": "^1.4.0",
49 | "zustand": "^4.4.6"
50 | },
51 | "devDependencies": {
52 | "@keplr-wallet/types": "^0.12.196",
53 | "@types/mixpanel-browser": "^2.51.0",
54 | "@types/react": "^18.3.18",
55 | "@types/react-copy-to-clipboard": "5.0.7",
56 | "@types/react-dom": "^18.3.5",
57 | "husky": "^9.1.7",
58 | "lint-staged": "^15.4.3",
59 | "prettier": "3.5.3",
60 | "typescript": "^5.6.3"
61 | },
62 | "overrides": {
63 | "protobufjs": "^7.4.0",
64 | "elliptic": "6.6.1",
65 | "axios": "1.8.2",
66 | "esbuild": "0.25.1",
67 | "ws": "8.18.1",
68 | "secretjs": "1.15.1",
69 | "@babel/runtime": "7.26.10",
70 | "vite": "5.4.19"
71 | },
72 | "private": true,
73 | "lint-staged": {
74 | "**/*": "prettier --write --ignore-unknown"
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/postcss.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: {
3 | tailwindcss: {},
4 | autoprefixer: {},
5 | },
6 | };
7 |
--------------------------------------------------------------------------------
/public/PriceIdsString.txt:
--------------------------------------------------------------------------------
1 | secret,akash-network,,eris-staked-kuji,eris-amplified-luna,eris-amplified-whale,andromeda-2,archway,cosmos,,,agoric,,cheqd-network,comdex,composite,cosmos,polkadot,sentinel,dydx,dymension,eclipse-fi,omniflix-network,graviton,harbor-2,chihuahua-token,injective-protocol,inter-stable-token,jackal-protocol,juno-network,kava,kujira,kusama,nolus,unstake-fi,neutron-3,nym,terra-luna-2,levana-protocol,milkyway-staked-tia,mantadao,oraichain-token,osmosis,page,picasso,pstake-finance,qatom,quicksilver,kujira,usd-coin,saga-2,stargaze,stride-staked-atom,stride-staked-injective,stride-staked-juno,stkatom,,stride-staked-luna,stride-staked-osmo,stride,stride-staked-tia,switcheo,,celestia,umee,tether,bitcoin,white-whale,wrapped-steth,persistence,alter,,,amberdao,shade-protocol,fina,shade-protocol,,sienna,silk-bcec1136-561c-4706-a42c-8b67d0d7f7d2,stkd-scrt,usd-coin,axelar,ethereum,bridged-wrapped-steth-axelar,bitcoin,binancecoin,busd,dai,chainlink,uniswap,tether,frax
--------------------------------------------------------------------------------
/public/_headers:
--------------------------------------------------------------------------------
1 | /*
2 | X-Frame-Options: SAMEORIGIN
3 | Content-Security-Policy: frame-ancestors 'self'
--------------------------------------------------------------------------------
/public/favicon.svg:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
--------------------------------------------------------------------------------
/public/fonts/runddisplay/runddisplay-black.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/scrtlabs/dash.scrt.network/c828f76d2aeece4190dbc47606a2779a4d05e998/public/fonts/runddisplay/runddisplay-black.woff
--------------------------------------------------------------------------------
/public/fonts/runddisplay/runddisplay-bold.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/scrtlabs/dash.scrt.network/c828f76d2aeece4190dbc47606a2779a4d05e998/public/fonts/runddisplay/runddisplay-bold.woff
--------------------------------------------------------------------------------
/public/fonts/runddisplay/runddisplay-extrabold.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/scrtlabs/dash.scrt.network/c828f76d2aeece4190dbc47606a2779a4d05e998/public/fonts/runddisplay/runddisplay-extrabold.woff
--------------------------------------------------------------------------------
/public/fonts/runddisplay/runddisplay-light.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/scrtlabs/dash.scrt.network/c828f76d2aeece4190dbc47606a2779a4d05e998/public/fonts/runddisplay/runddisplay-light.woff
--------------------------------------------------------------------------------
/public/fonts/runddisplay/runddisplay-medium.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/scrtlabs/dash.scrt.network/c828f76d2aeece4190dbc47606a2779a4d05e998/public/fonts/runddisplay/runddisplay-medium.woff
--------------------------------------------------------------------------------
/public/fonts/runddisplay/runddisplay-regular.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/scrtlabs/dash.scrt.network/c828f76d2aeece4190dbc47606a2779a4d05e998/public/fonts/runddisplay/runddisplay-regular.woff
--------------------------------------------------------------------------------
/public/fonts/runddisplay/runddisplay-semibold.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/scrtlabs/dash.scrt.network/c828f76d2aeece4190dbc47606a2779a4d05e998/public/fonts/runddisplay/runddisplay-semibold.woff
--------------------------------------------------------------------------------
/public/fonts/runddisplay/runddisplay-thin.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/scrtlabs/dash.scrt.network/c828f76d2aeece4190dbc47606a2779a4d05e998/public/fonts/runddisplay/runddisplay-thin.woff
--------------------------------------------------------------------------------
/public/img/assets/abusd.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/public/img/assets/adai.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/public/img/assets/adm.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
8 |
9 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/public/img/assets/afrax.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
11 |
12 |
13 |
14 |
15 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/public/img/assets/akt.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/public/img/assets/alink.svg:
--------------------------------------------------------------------------------
1 | Asset 1
--------------------------------------------------------------------------------
/public/img/assets/amber.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/scrtlabs/dash.scrt.network/c828f76d2aeece4190dbc47606a2779a4d05e998/public/img/assets/amber.jpg
--------------------------------------------------------------------------------
/public/img/assets/ampluna.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
17 |
19 |
20 |
--------------------------------------------------------------------------------
/public/img/assets/andr.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/scrtlabs/dash.scrt.network/c828f76d2aeece4190dbc47606a2779a4d05e998/public/img/assets/andr.png
--------------------------------------------------------------------------------
/public/img/assets/archway.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/public/img/assets/axl.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/public/img/assets/binj.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/scrtlabs/dash.scrt.network/c828f76d2aeece4190dbc47606a2779a4d05e998/public/img/assets/binj.png
--------------------------------------------------------------------------------
/public/img/assets/bkuji.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/scrtlabs/dash.scrt.network/c828f76d2aeece4190dbc47606a2779a4d05e998/public/img/assets/bkuji.png
--------------------------------------------------------------------------------
/public/img/assets/bld.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/public/img/assets/bluna.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/scrtlabs/dash.scrt.network/c828f76d2aeece4190dbc47606a2779a4d05e998/public/img/assets/bluna.png
--------------------------------------------------------------------------------
/public/img/assets/butt.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/scrtlabs/dash.scrt.network/c828f76d2aeece4190dbc47606a2779a4d05e998/public/img/assets/butt.png
--------------------------------------------------------------------------------
/public/img/assets/cmdx.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/public/img/assets/cmst.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/public/img/assets/coreum.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/public/img/assets/cre.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/public/img/assets/deposit.svg:
--------------------------------------------------------------------------------
1 |
2 |
4 |
7 |
8 |
10 |
15 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/public/img/assets/dot.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/public/img/assets/dshd.svg:
--------------------------------------------------------------------------------
1 |
8 |
12 |
13 |
17 |
23 |
27 |
33 |
34 |
35 |
43 |
44 |
48 |
49 |
57 |
58 |
62 |
66 |
67 |
75 |
76 |
80 |
84 |
85 |
86 |
92 |
93 |
94 |
95 |
--------------------------------------------------------------------------------
/public/img/assets/dvpn.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/public/img/assets/dydx.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/public/img/assets/eclip.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/public/img/assets/evmos.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/public/img/assets/fina.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/scrtlabs/dash.scrt.network/c828f76d2aeece4190dbc47606a2779a4d05e998/public/img/assets/fina.png
--------------------------------------------------------------------------------
/public/img/assets/fina.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/scrtlabs/dash.scrt.network/c828f76d2aeece4190dbc47606a2779a4d05e998/public/img/assets/fina.webp
--------------------------------------------------------------------------------
/public/img/assets/harbor.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/public/img/assets/ibc-black.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/public/img/assets/inj.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/public/img/assets/juno.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/public/img/assets/kava.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/public/img/assets/keplr.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Artboard Copy 6@960w
5 | Created with Sketch.
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/public/img/assets/ksm.svg:
--------------------------------------------------------------------------------
1 | kusama-ksm-logo
--------------------------------------------------------------------------------
/public/img/assets/leap.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/public/img/assets/luna.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/scrtlabs/dash.scrt.network/c828f76d2aeece4190dbc47606a2779a4d05e998/public/img/assets/luna.png
--------------------------------------------------------------------------------
/public/img/assets/luna2.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/img/assets/migaloo.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/public/img/assets/mnta.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
12 |
--------------------------------------------------------------------------------
/public/img/assets/nolus.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/public/img/assets/nstk.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/img/assets/ntrn.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/public/img/assets/nyx.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/scrtlabs/dash.scrt.network/c828f76d2aeece4190dbc47606a2779a4d05e998/public/img/assets/nyx.png
--------------------------------------------------------------------------------
/public/img/assets/orai.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/public/img/assets/page.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/scrtlabs/dash.scrt.network/c828f76d2aeece4190dbc47606a2779a4d05e998/public/img/assets/page.png
--------------------------------------------------------------------------------
/public/img/assets/pica.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/public/img/assets/pstake.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/public/img/assets/robots.txt:
--------------------------------------------------------------------------------
1 | User-Agent: *
2 |
3 | User-agent: facebookexternalhit
4 | Disallow:
5 |
6 | User-agent: Twitterbot
7 | Disallow:
--------------------------------------------------------------------------------
/public/img/assets/rowan.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/public/img/assets/saga.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/public/img/assets/scrt-white.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/public/img/assets/scrt.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/public/img/assets/shd.svg:
--------------------------------------------------------------------------------
1 |
8 |
12 |
16 |
20 |
24 |
32 |
33 |
37 |
41 |
42 |
50 |
51 |
55 |
59 |
60 |
68 |
69 |
73 |
77 |
78 |
86 |
87 |
91 |
95 |
96 |
97 |
--------------------------------------------------------------------------------
/public/img/assets/silk.svg:
--------------------------------------------------------------------------------
1 |
8 |
12 |
16 |
24 |
25 |
29 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/public/img/assets/stars.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/public/img/assets/statom.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/public/img/assets/stinj.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/public/img/assets/stjuno.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/public/img/assets/stkdydx.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/public/img/assets/stluna.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/public/img/assets/stride.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/public/img/assets/syn.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/scrtlabs/dash.scrt.network/c828f76d2aeece4190dbc47606a2779a4d05e998/public/img/assets/syn.png
--------------------------------------------------------------------------------
/public/img/assets/usdc.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/public/img/assets/usdt.svg:
--------------------------------------------------------------------------------
1 | tether-usdt-logo
--------------------------------------------------------------------------------
/public/img/assets/usk.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/img/assets/wbnb.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
6 |
8 |
11 |
15 |
16 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/public/img/assets/wsteth.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/public/img/assets/xprt.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/public/img/assets/xrp.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/public/robots.txt:
--------------------------------------------------------------------------------
1 | User-agent: *
2 | Allow: /
--------------------------------------------------------------------------------
/public/sitemap.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | https://dash.scrt.network/
5 |
6 |
7 | https://dash.scrt.network/ibc
8 |
9 |
10 | https://dash.scrt.network/wrap
11 |
12 |
13 | https://dash.scrt.network/bridge
14 |
15 |
16 | https://dash.scrt.network/restake
17 |
18 |
19 | https://dash.scrt.network/apps
20 |
21 |
--------------------------------------------------------------------------------
/src/assets/scss/components/_fonts.scss:
--------------------------------------------------------------------------------
1 | @use './fonts/runddisplay';
2 |
--------------------------------------------------------------------------------
/src/assets/scss/components/fonts/_runddisplay.scss:
--------------------------------------------------------------------------------
1 | @font-face {
2 | font-family: 'RundDisplay';
3 | font-style: normal;
4 | font-weight: 400;
5 | src: url('/fonts/runddisplay/runddisplay-regular.woff') format('woff');
6 | }
7 |
8 | @font-face {
9 | font-family: 'RundDisplay';
10 | font-style: normal;
11 | font-weight: 100;
12 | src: url('/fonts/runddisplay/runddisplay-thin.woff') format('woff');
13 | }
14 |
15 | @font-face {
16 | font-family: 'RundDisplay';
17 | font-style: normal;
18 | font-weight: 300;
19 | src: url('/fonts/runddisplay/runddisplay-light.woff') format('woff');
20 | }
21 |
22 | @font-face {
23 | font-family: 'RundDisplay';
24 | font-style: normal;
25 | font-weight: 500;
26 | src: url('/fonts/runddisplay/runddisplay-medium.woff') format('woff');
27 | }
28 |
29 | @font-face {
30 | font-family: 'RundDisplay';
31 | font-style: normal;
32 | font-weight: 600;
33 | src: url('/fonts/runddisplay/runddisplay-semibold.woff') format('woff');
34 | }
35 |
36 | @font-face {
37 | font-family: 'RundDisplay';
38 | font-style: normal;
39 | font-weight: 700;
40 | src: url('/fonts/runddisplay/runddisplay-bold.woff') format('woff');
41 | }
42 |
43 | @font-face {
44 | font-family: 'RundDisplay';
45 | font-style: normal;
46 | font-weight: 800;
47 | src: url('/fonts/runddisplay/runddisplay-extrabold.woff') format('woff');
48 | }
49 |
50 | @font-face {
51 | font-family: 'RundDisplay';
52 | font-style: normal;
53 | font-weight: 900;
54 | src: url('/fonts/runddisplay/runddisplay-black.woff') format('woff');
55 | }
56 |
--------------------------------------------------------------------------------
/src/components/FeeGrant/FeeGrant.tsx:
--------------------------------------------------------------------------------
1 | import { faInfoCircle } from '@fortawesome/free-solid-svg-icons'
2 | import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
3 | import Tooltip from '@mui/material/Tooltip'
4 | import ActionableStatus from './components/ActionableStatus'
5 |
6 | export default function FeeGrant() {
7 | return (
8 |
9 |
10 |
15 |
16 | Fee Grant
17 |
18 |
19 |
20 |
21 |
22 |
23 |
26 |
27 | )
28 | }
29 |
--------------------------------------------------------------------------------
/src/components/FeeGrant/components/ActionableStatus.tsx:
--------------------------------------------------------------------------------
1 | import { useState } from 'react'
2 | import { faCheckCircle, faXmarkCircle } from '@fortawesome/free-solid-svg-icons'
3 | import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
4 | import Button from 'components/UI/Button/Button'
5 | import { useSecretNetworkClientStore } from 'store/secretNetworkClient'
6 | import toast from 'react-hot-toast'
7 | import { NotificationService } from 'services/notification.service'
8 |
9 | export default function ActionableStatus() {
10 | const { feeGrantStatus, requestFeeGrant, isConnected } = useSecretNetworkClientStore()
11 |
12 | const [isLoading, setIsLoading] = useState(false)
13 |
14 | async function handleRequestFeeGrant() {
15 | setIsLoading(true)
16 | const toastId = NotificationService.notify(`Requesting Fee Grant...`, 'loading')
17 |
18 | try {
19 | const res = requestFeeGrant()
20 |
21 | res
22 | .then(() => {
23 | NotificationService.notify(`Request for Fee Grant successful`, 'success', toastId)
24 | })
25 | .catch((error) => {
26 | NotificationService.notify(`Request for Fee Grant failed: ${error}`, 'error', toastId)
27 | })
28 | } catch (error: any) {
29 | console.error(error)
30 | NotificationService.notify(`Request for Fee Grant failed: ${error}`, 'error', toastId)
31 | }
32 | setIsLoading(false)
33 | }
34 |
35 | if (isLoading) {
36 | return (
37 |
38 |
44 |
45 |
50 |
51 |
Requesting...
52 |
53 | )
54 | }
55 |
56 | // Untouched
57 | if (feeGrantStatus === 'untouched') {
58 | return (
59 |
66 | Request Fee Grant
67 |
68 | )
69 | }
70 |
71 | // Success
72 | if (feeGrantStatus === 'success') {
73 | return (
74 |
75 |
76 | Fee Granted
77 |
78 | )
79 | }
80 |
81 | // Fail
82 | if (feeGrantStatus === 'fail') {
83 | return (
84 |
85 |
86 | Request failed
87 |
88 | )
89 | }
90 | }
91 |
--------------------------------------------------------------------------------
/src/components/FeedbackButton.tsx:
--------------------------------------------------------------------------------
1 | import './FloatingCTAButton.scss'
2 |
3 | interface Props {
4 | url: string
5 | }
6 |
7 | function FeedbackButton(props: Props) {
8 | return (
9 |
18 | )
19 | }
20 |
21 | export default FeedbackButton
22 |
--------------------------------------------------------------------------------
/src/components/FloatingCTAButton.scss:
--------------------------------------------------------------------------------
1 | @-webkit-keyframes textFadeIn {
2 | from {
3 | opacity: 0;
4 | -webkit-transform: translate3d(-100%, 0, 0);
5 | transform: translate3d(-100%, 0, 0);
6 | }
7 |
8 | to {
9 | opacity: 1;
10 | -webkit-transform: translate3d(0, 0, 0);
11 | transform: translate3d(0, 0, 0);
12 | }
13 | }
14 | @keyframes textFadeIn {
15 | from {
16 | opacity: 0;
17 | -webkit-transform: translate3d(-100%, 0, 0);
18 | transform: translate3d(-100%, 0, 0);
19 | }
20 |
21 | to {
22 | opacity: 1;
23 | -webkit-transform: translate3d(0, 0, 0);
24 | transform: translate3d(0, 0, 0);
25 | }
26 | }
27 |
28 | .floatingCTAButton {
29 | position: fixed;
30 | bottom: 20px;
31 | right: 20px;
32 | z-index: 40;
33 | overflow: hidden;
34 | color: #fff;
35 | border-radius: 9999px;
36 | display: flex;
37 | flex-direction: row;
38 | align-items: center;
39 | padding: 0.5rem;
40 |
41 | .icon-circle {
42 | width: 1.75rem;
43 | height: 1.75rem;
44 | font-size: 1.5rem;
45 | margin: 0.5rem;
46 | display: inline-block;
47 | z-index: 5000 !important;
48 | transition: padding-right 350ms ease;
49 | flex: 0 1 auto;
50 | }
51 |
52 | .cta-text {
53 | flex: 0 1 auto;
54 | visibility: hidden;
55 | padding: 0;
56 | width: 0;
57 | height: 0;
58 | z-index: 1;
59 | transition: padding 350ms ease-in-out;
60 | }
61 |
62 | &:hover {
63 | .icon-circle {
64 | }
65 | .cta-text {
66 | visibility: visible;
67 | padding: 0 1.25rem 0 0.25rem;
68 | width: inherit;
69 | height: inherit;
70 |
71 | animation: textFadeIn;
72 | animation-duration: 350ms;
73 | }
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/src/components/FloatingCTAButton.tsx:
--------------------------------------------------------------------------------
1 | import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
2 | import { faComment } from '@fortawesome/free-solid-svg-icons'
3 | import './FloatingCTAButton.scss'
4 | import { Link } from 'react-router-dom'
5 |
6 | interface Props {
7 | url: string
8 | text: string
9 | }
10 |
11 | function FloatingCTAButton(props: Props) {
12 | return (
13 |
14 |
15 |
16 | {props.text}
17 |
18 |
19 | )
20 | }
21 |
22 | export default FloatingCTAButton
23 |
--------------------------------------------------------------------------------
/src/components/Header.tsx:
--------------------------------------------------------------------------------
1 | import Title from './Title'
2 |
3 | interface Props {
4 | title: string
5 | description?: string
6 | }
7 |
8 | const Header = (props: Props) => {
9 | return (
10 | <>
11 | {/* Title */}
12 |
13 | {/* Description */}
14 | {props.description && (
15 |
16 | {props.description}
17 |
18 | )}
19 | >
20 | )
21 | }
22 |
23 | export default Header
24 |
--------------------------------------------------------------------------------
/src/components/PercentagePicker.tsx:
--------------------------------------------------------------------------------
1 | interface Props {
2 | setAmountByPercentage: (percentage: number) => void
3 | disabled?: boolean
4 | }
5 |
6 | export default function PercentagePicker(props: Props) {
7 | return (
8 |
9 | props.setAmountByPercentage(25)}
12 | className="bg-gray-300 dark:bg-neutral-800 py-1.5 px-2.5 rounded-l-lg enabled:hover:bg-gray-400 enabled:dark:hover:bg-neutral-600 transition"
13 | disabled={props.disabled}
14 | >
15 | 25%
16 |
17 | props.setAmountByPercentage(50)}
20 | className="bg-gray-300 dark:bg-neutral-800 py-1.5 px-2.5 enabled:hover:bg-gray-400 enabled:dark:hover:bg-neutral-600 transition"
21 | disabled={props.disabled}
22 | >
23 | 50%
24 |
25 | props.setAmountByPercentage(75)}
28 | className="bg-gray-300 dark:bg-neutral-800 py-1.5 px-2.5 enabled:hover:bg-gray-400 enabled:dark:hover:bg-neutral-600 transition"
29 | disabled={props.disabled}
30 | >
31 | 75%
32 |
33 | props.setAmountByPercentage(100)}
36 | className="bg-gray-300 dark:bg-neutral-800 py-1.5 px-2.5 rounded-r-lg enabled:hover:bg-gray-400 enabled:dark:hover:bg-neutral-600 transition"
37 | disabled={props.disabled}
38 | >
39 | 100%
40 |
41 |
42 | )
43 | }
44 |
--------------------------------------------------------------------------------
/src/components/Title.tsx:
--------------------------------------------------------------------------------
1 | import Tooltip from '@mui/material/Tooltip'
2 | import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
3 | import { faInfoCircle } from '@fortawesome/free-solid-svg-icons'
4 |
5 | interface IProps {
6 | title: string
7 | tooltip?: string
8 | className?: string
9 | }
10 |
11 | export default function Title(props: IProps) {
12 | function TitleContent() {
13 | return (
14 |
15 |
{props.title}
16 | {props.tooltip ? (
17 |
18 |
19 |
20 | ) : null}
21 |
22 | )
23 | }
24 |
25 | if (props.tooltip) {
26 | return (
27 |
28 |
29 |
30 |
31 |
32 | )
33 | } else {
34 | return
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/components/UI/Badge/Badge.tsx:
--------------------------------------------------------------------------------
1 | type Color = 'primary' | 'dark' | 'red' | 'green' | 'yellow' | 'indigo' | 'purple' | 'pink'
2 |
3 | type Size = 'default' | 'large'
4 |
5 | type Props = {
6 | color?: Color
7 | size?: Size
8 | bordered?: boolean
9 | pill?: boolean
10 | children: React.ReactNode
11 | }
12 |
13 | const colorClasses: Record = {
14 | primary: 'bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-300',
15 | dark: 'bg-gray-100 text-gray-800 dark:bg-gray-700 dark:text-gray-300',
16 | red: 'bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-300',
17 | green: 'bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-300',
18 | yellow: 'bg-yellow-100 text-yellow-800 dark:bg-yellow-900 dark:text-yellow-300',
19 | indigo: 'bg-indigo-100 text-indigo-800 dark:bg-indigo-900 dark:text-indigo-300"',
20 | purple: 'bg-purple-100 text-purple-800 dark:bg-purple-900 dark:text-purple-300',
21 | pink: 'bg-pink-100 text-pink-800 dark:bg-pink-900 dark:text-pink-300'
22 | }
23 |
24 | const borderClasses: Record = {
25 | primary: 'border border-blue-400 dark:bg-gray-700 dark:text-blue-400',
26 | dark: 'border border-dark-500 dark:bg-gray-700 dark:text-gray-400',
27 | red: 'border border-red-400 dark:bg-gray-700 dark:text-red-400',
28 | green: 'border border-green-400 dark:bg-gray-700 dark:text-green-400',
29 | yellow: 'border border-yellow-300 dark:bg-gray-700 dark:text-yellow-300',
30 | indigo: 'border border-indigo-400 dark:bg-gray-700 dark:text-indigo-400',
31 | purple: 'border border-purple-400 dark:bg-gray-700 dark:text-purple-400',
32 | pink: 'border border-pink-400 dark:bg-gray-700 dark:text-pink-400'
33 | }
34 |
35 | const sizeClasses: Record = {
36 | default: 'text-xs',
37 | large: 'text-sm'
38 | }
39 |
40 | function Badge(props: Props) {
41 | return (
42 |
51 | {props.children}
52 |
53 | )
54 | }
55 |
56 | export default Badge
57 |
--------------------------------------------------------------------------------
/src/components/UI/Button/Button.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 |
3 | type Type = 'button' | 'submit' | 'reset'
4 | type Size = 'default' | 'large' | 'small'
5 | type Color = 'primary' | 'secondary' | 'red' | 'blue' | 'emerald' | 'yellow'
6 |
7 | const colorClasses: Record = {
8 | primary:
9 | 'enabled:bg-sky-500 dark:enabled:bg-sky-600 enabled:hover:bg-sky-600 dark:enabled:hover:bg-sky-700 enabled:text-white disabled:bg-neutral-600 disabled:text-neutral-400 enabled:ring-sky-500/40 dark:enabled:ring-sky-600/40',
10 | secondary:
11 | 'enabled:bg-gray-500 dark:enabled:bg-gray-600 enabled:hover:bg-gray-600 dark:enabled:hover:bg-gray-700 enabled:text-white disabled:bg-neutral-600 disabled:text-neutral-400 enabled:ring-gray-500/40 dark:enabled:ring-gray-600/40',
12 | red: 'enabled:bg-red-500 dark:enabled:bg-red-600 enabled:hover:bg-red-600 dark:enabled:hover:bg-red-700 enabled:text-white disabled:bg-neutral-600 disabled:text-neutral-400 enabled:ring-red-500/40 dark:enabled:ring-red-600/40',
13 | blue: 'enabled:bg-blue-500 dark:enabled:bg-blue-600 enabled:hover:bg-blue-600 dark:enabled:hover:bg-blue-700 enabled:text-white disabled:bg-neutral-600 disabled:text-neutral-400 enabled:ring-blue-500/40 dark:enabled:ring-blue-600/40',
14 | emerald:
15 | 'enabled:bg-emerald-500 dark:enabled:bg-emerald-600 enabled:hover:bg-emerald-600 dark:enabled:hover:bg-emerald-700 enabled:text-white disabled:bg-neutral-600 disabled:text-neutral-400 enabled:ring-emerald-500/40 dark:enabled:ring-emerald-600/40',
16 | yellow:
17 | 'enabled:bg-yellow-500 dark:enabled:bg-yellow-600 enabled:hover:bg-yellow-600 dark:enabled:hover:bg-yellow-700 enabled:text-black disabled:bg-neutral-600 disabled:text-neutral-400 enabled:ring-yellow-500/40 dark:enabled:ring-yellow-600/40'
18 | }
19 |
20 | const sizeClasses: Record = {
21 | default: 'py-2 px-4 text-sm',
22 | large: 'py-3 px-4 text-sm',
23 | small: 'py-1.5 px-2 text-xs'
24 | }
25 |
26 | interface Props {
27 | children?: React.ReactNode
28 | type?: Type
29 | onClick?: (event: React.MouseEvent) => void
30 | color?: Color
31 | size?: Size
32 | disabled?: boolean
33 | className?: string
34 | }
35 |
36 | export default function Button(props: Props) {
37 | return (
38 |
48 | <>{props.children}>
49 |
50 | )
51 | }
52 |
--------------------------------------------------------------------------------
/src/components/Wallet/ManageBalances/Balances.scss:
--------------------------------------------------------------------------------
1 | .balance-item div {
2 | &:first-of-type {
3 | @apply rounded-t-lg;
4 | }
5 | &:last-of-type {
6 | @apply rounded-b-lg;
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/src/components/Wallet/ManageBalances/ManageBalances.tsx:
--------------------------------------------------------------------------------
1 | import { useState } from 'react'
2 | import { Token } from 'utils/config'
3 | import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
4 | import { faMagnifyingGlass } from '@fortawesome/free-solid-svg-icons'
5 | import './Balances.scss'
6 | import { SendService } from 'services/send.service'
7 | import BalanceItem from 'pages/portfolio/components/BalanceItem'
8 |
9 | export const ManageBalances = () => {
10 | const [searchQuery, setSearchQuery] = useState('')
11 |
12 | const tokens = SendService.getSupportedTokens()
13 |
14 | const displayedAssets = tokens.filter(
15 | (token: Token) =>
16 | token.name?.toLowerCase().includes(searchQuery?.toLowerCase()) ||
17 | ('s' + token.name)?.toLowerCase().includes(searchQuery?.toLowerCase()) ||
18 | token.description?.toLowerCase().includes(searchQuery?.toLowerCase())
19 | )
20 |
21 | return (
22 | <>
23 | {/* All Balances */}
24 |
25 | {/* Search */}
26 |
27 |
28 |
29 |
30 |
31 |
setSearchQuery(e.target.value)}
34 | type="text"
35 | id="search"
36 | className="block w-full sm:w-72 p-2.5 pl-10 text-sm rounded-lg text-neutral-800 dark:text-white bg-white dark:bg-neutral-800 placeholder-neutral-600 dark:placeholder-neutral-400 border border-neutral-300 dark:border-neutral-700 focus:outline-none focus:ring-2 focus:ring-cyan-500 dark:focus:ring-cyan-500"
37 | placeholder="Search Asset"
38 | />
39 |
40 |
41 |
42 |
43 |
44 | {tokens
45 | ? displayedAssets.map((token: Token, i: number) => )
46 | : [...Array(10)].map((_, index) => )}
47 |
48 | >
49 | )
50 | }
51 |
--------------------------------------------------------------------------------
/src/components/Wallet/StatusDot.tsx:
--------------------------------------------------------------------------------
1 | type Status = 'connected' | 'disconnected'
2 |
3 | type Props = {
4 | status: Status
5 | }
6 |
7 | function StatusDot(props: Props) {
8 | if (props.status === 'connected') {
9 | return (
10 |
11 |
12 |
13 |
14 | )
15 | }
16 |
17 | return
18 | }
19 |
20 | export default StatusDot
21 |
--------------------------------------------------------------------------------
/src/context/ThemeContext.tsx:
--------------------------------------------------------------------------------
1 | import { createContext, useEffect, useState } from 'react'
2 | import { useUserPreferencesStore } from 'store/UserPreferences'
3 | import { Theme } from 'types/Theme'
4 |
5 | const ThemeContext = createContext(null)
6 |
7 | const ThemeContextProvider = ({ children }: any) => {
8 | // the value that will be given to the context
9 | const { theme } = useUserPreferencesStore()
10 |
11 | function setThemeClassToBody(theme: Theme) {
12 | if (theme === 'light') {
13 | document.body.classList.remove('dark')
14 | } else if (theme === 'dark') {
15 | document.body.classList.add('dark')
16 | }
17 | }
18 |
19 | // always save option to localStorage
20 | useEffect(() => {
21 | if (theme !== null) {
22 | setThemeClassToBody(theme)
23 | }
24 | }, [theme])
25 |
26 | return {children}
27 | }
28 |
29 | export { ThemeContext, ThemeContextProvider }
30 |
--------------------------------------------------------------------------------
/src/custom.d.ts:
--------------------------------------------------------------------------------
1 | interface Window {
2 | leap?: any
3 | keplr?: any
4 | wallet?: any
5 | }
6 |
--------------------------------------------------------------------------------
/src/hooks/useClickOutside.tsx:
--------------------------------------------------------------------------------
1 | import { useEffect } from 'react'
2 |
3 | const useClickOutside = (ref: any, handler: any) => {
4 | useEffect(() => {
5 | const listener = (event: any) => {
6 | if (!ref.current || ref.current.contains(event.target)) {
7 | return
8 | }
9 | handler(event)
10 | }
11 | document.addEventListener('mousedown', listener)
12 | document.addEventListener('touchstart', listener)
13 | return () => {
14 | document.removeEventListener('mousedown', listener)
15 | document.removeEventListener('touchstart', listener)
16 | }
17 | }, [ref, handler])
18 | }
19 |
20 | export default useClickOutside
21 |
--------------------------------------------------------------------------------
/src/pages/apps/components/FilterTag.tsx:
--------------------------------------------------------------------------------
1 | interface Props {
2 | name: string
3 | toggleTagFilter: any
4 | isTagInFilterList: (name: string) => string
5 | }
6 |
7 | const FilterTag = (props: Props) => {
8 | return (
9 | props.toggleTagFilter(props.name)}
11 | className={
12 | 'inline-block text-sm px-1.5 py-0.5 rounded-md overflow-hidden transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-cyan-500 dark:focus-visible:ring-cyan-500' +
13 | (props.isTagInFilterList(props.name)
14 | ? ' text-white dark:text-white font-semibold bg-gradient-to-r from-cyan-600 to-purple-600 hover:from-cyan-500 hover:to-purple-500'
15 | : ' bg-white dark:bg-neutral-800 hover:bg-gray-200 dark:hover:bg-neutral-700 font-medium')
16 | }
17 | >
18 | {props.name}
19 |
20 | )
21 | }
22 |
23 | export default FilterTag
24 |
--------------------------------------------------------------------------------
/src/pages/apps/components/SkeletonLoaders/SkeletonLoader.tsx:
--------------------------------------------------------------------------------
1 | export default function SkeletonLoader() {
2 | return (
3 |
6 | )
7 | }
8 |
--------------------------------------------------------------------------------
/src/pages/apps/components/SkeletonLoaders/SkeletonLoaders.tsx:
--------------------------------------------------------------------------------
1 | import SkeletonLoader from './SkeletonLoader'
2 |
3 | interface Props {
4 | amount?: number
5 | }
6 |
7 | /**
8 | * Render multiple SkeletonLoader components based on the specified amount.
9 | *
10 | * @param {number} [amount=20] - The number of SkeletonLoaders to render. Default is 20.
11 | *
12 | * @remarks
13 | * This function is intended for use in the /apps context.
14 | *
15 | * @example
16 | * ```tsx
17 | *
18 | * ```
19 | */
20 | export default function SkeletonLoaders({ amount = 20 }: Props) {
21 | return (
22 | <>
23 | {Array.from({ length: amount }).map((_, index) => (
24 |
25 | ))}
26 | >
27 | )
28 | }
29 |
--------------------------------------------------------------------------------
/src/pages/apps/components/tile/AppTile.tsx:
--------------------------------------------------------------------------------
1 | import Tag from './Tag'
2 | import mixpanel from 'mixpanel-browser'
3 |
4 | interface Props {
5 | name: string
6 | description: string
7 | image?: string
8 | tags?: string[]
9 | url?: string
10 | }
11 |
12 | const AppTile = (props: Props) => {
13 | const handleClick = () => {
14 | if (import.meta.env.VITE_MIXPANEL_ENABLED === 'true') {
15 | mixpanel.init(import.meta.env.VITE_MIXPANEL_PROJECT_TOKEN, {
16 | debug: false
17 | })
18 | mixpanel.identify('Dashboard-App')
19 | mixpanel.track('dApp opened', {
20 | 'dApp name': props.name
21 | })
22 | }
23 | }
24 |
25 | return (
26 |
32 |
33 | {/* Image */}
34 | {props.image && (
35 |
36 |
41 |
42 | )}
43 | {/* Name */}
44 |
{props.name}
45 |
46 | {/* Description */}
47 |
{props.description}
48 |
49 | {/* Tags */}
50 | {props.tags?.length! > 0 && (
51 |
52 | {props.tags?.map((tag) => )}
53 |
54 | )}
55 |
56 |
57 | )
58 | }
59 |
60 | export default AppTile
61 |
--------------------------------------------------------------------------------
/src/pages/apps/components/tile/Tag.tsx:
--------------------------------------------------------------------------------
1 | import Badge from 'components/UI/Badge/Badge'
2 |
3 | interface Props {
4 | name: string
5 | }
6 | const Tag = (props: Props) => {
7 | return (
8 | <>
9 | {props.name}
10 | >
11 | )
12 | }
13 |
14 | export default Tag
15 |
--------------------------------------------------------------------------------
/src/pages/bridge/SwingModal.tsx:
--------------------------------------------------------------------------------
1 | import { faXmark } from '@fortawesome/free-solid-svg-icons'
2 | import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
3 | import { Theme } from 'types/Theme'
4 | import { Swap } from '@swing.xyz/ui'
5 | import { useEffect } from 'react'
6 |
7 | interface Props {
8 | open: boolean
9 | onClose: any
10 | theme: Theme
11 | secretAddress: string
12 | }
13 |
14 | const SwingModal = (props: Props) => {
15 | if (!props.open) return null
16 |
17 | useEffect(() => {
18 | if (props.theme === 'light') {
19 | import('./SwingModal_Light.scss')
20 | } else {
21 | import('./SwingModal_Dark.scss')
22 | }
23 | }, [props.theme])
24 | return (
25 | <>
26 | {/* Outer */}
27 |
31 | {/* Inner */}
32 |
33 |
34 |
{
37 | e.stopPropagation()
38 | }}
39 | >
40 | {/* Close Button */}
41 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 | >
53 | )
54 | }
55 |
56 | export default SwingModal
57 |
--------------------------------------------------------------------------------
/src/pages/dashboard/components/CurrentPrice.tsx:
--------------------------------------------------------------------------------
1 | import { faArrowUpRightFromSquare } from '@fortawesome/free-solid-svg-icons'
2 | import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
3 | import { toCurrencyString, trackMixPanelEvent } from 'utils/commons'
4 | import { Link } from 'react-router-dom'
5 | import { useUserPreferencesStore } from 'store/UserPreferences'
6 |
7 | interface Props {
8 | price?: number
9 | }
10 |
11 | export default function CurrentPrice(props: Props) {
12 | const { currency } = useUserPreferencesStore()
13 | return (
14 |
15 |
16 |
17 |
Current Price
18 |
19 | {props.price ? (
20 | <>{toCurrencyString(props.price, currency)}>
21 | ) : (
22 |
23 | )}
24 |
25 |
26 |
27 |
28 | {
32 | trackMixPanelEvent('Clicked buy SCRT on current price')
33 | }}
34 | >
35 | Get SCRT
36 |
37 |
38 |
39 |
40 | )
41 | }
42 |
--------------------------------------------------------------------------------
/src/pages/dashboard/components/MiniTile.tsx:
--------------------------------------------------------------------------------
1 | interface Props {
2 | name: string
3 | value?: string
4 | }
5 |
6 | export default function MiniTile(props: Props) {
7 | return (
8 | <>
9 |
10 |
11 |
{props.name}
12 |
13 | {props.value ? (
14 | <>{props.value}>
15 | ) : (
16 |
17 | )}
18 |
19 |
20 |
21 | >
22 | )
23 | }
24 |
--------------------------------------------------------------------------------
/src/pages/dashboard/components/PriceVolTVLChart/components/RangeSwitch.tsx:
--------------------------------------------------------------------------------
1 | import { useContext } from 'react'
2 | import { PriceVolumeHistoryContext } from '../PriceVolumeTVL'
3 |
4 | function RangeSwitch() {
5 | const { chartType, chartRange, setChartRange } = useContext(PriceVolumeHistoryContext)
6 |
7 | return (
8 | <>
9 | {chartType !== 'TVL' && (
10 | <>
11 | setChartRange('Day')}
13 | type="button"
14 | className={
15 | 'py-1.5 px-3 text-xs font-semibold rounded-l-lg bg-neutral-100 dark:bg-neutral-700 ' +
16 | (chartRange === 'Day'
17 | ? ' cursor-default bg-neutral-300 dark:bg-cyan-500/20 text-black dark:text-cyan-200 font-semibold'
18 | : ' text-neutral-800 dark:text-neutral-200 hover:bg-neutral-300 dark:hover:bg-neutral-700 focus:bg-neutral-500 dark:focus:bg-neutral-500')
19 | }
20 | >
21 | Day
22 |
23 | setChartRange('Month')}
25 | type="button"
26 | className={
27 | 'py-1.5 px-3 text-xs font-semibold bg-neutral-100 dark:bg-neutral-700' +
28 | (chartRange === 'Month'
29 | ? ' cursor-default bg-neutral-300 dark:bg-cyan-500/20 text-black dark:text-cyan-200 font-semibold'
30 | : ' text-neutral-800 dark:text-neutral-200 hover:bg-neutral-300 dark:hover:bg-neutral-700 focus:bg-neutral-500 dark:focus:bg-neutral-500')
31 | }
32 | >
33 | Month
34 |
35 | setChartRange('Year')}
37 | type="button"
38 | className={
39 | 'py-1.5 px-3 text-xs font-semibold rounded-r-lg bg-neutral-100 dark:bg-neutral-700' +
40 | (chartRange === 'Year'
41 | ? ' cursor-default bg-neutral-300 dark:bg-cyan-500/20 text-black dark:text-cyan-200 font-semibold'
42 | : ' text-neutral-800 dark:text-neutral-200 hover:bg-neutral-300 dark:hover:bg-neutral-700 focus:bg-neutral-500 dark:focus:bg-neutral-500')
43 | }
44 | >
45 | Year
46 |
47 | >
48 | )}
49 |
50 | {chartType === 'TVL' && (
51 | <>
52 | setChartRange('Year')}
54 | type="button"
55 | className={
56 | 'py-1.5 px-3 text-xs font-semibold rounded-lg bg-neutral-100 dark:bg-neutral-900' +
57 | (chartRange === 'Year'
58 | ? ' cursor-default bg-neutral-300 dark:bg-cyan-500/20 text-black dark:text-cyan-200 font-semibold'
59 | : ' text-neutral-800 dark:text-neutral-200 hover:bg-neutral-300 dark:hover:bg-neutral-700 focus:bg-neutral-500 dark:focus:bg-neutral-500')
60 | }
61 | >
62 | Year
63 |
64 | >
65 | )}
66 | >
67 | )
68 | }
69 |
70 | export default RangeSwitch
71 |
--------------------------------------------------------------------------------
/src/pages/dashboard/components/PriceVolTVLChart/components/TypeSwitch.tsx:
--------------------------------------------------------------------------------
1 | import { useContext } from 'react'
2 | import { PriceVolumeHistoryContext } from '../PriceVolumeTVL'
3 |
4 | function TypeSwitch() {
5 | const { chartType, setChartType } = useContext(PriceVolumeHistoryContext)
6 |
7 | return (
8 | <>
9 |
10 | setChartType('Price')}
12 | type="button"
13 | className={
14 | 'py-1.5 px-3 text-xs font-semibold rounded-l-lg bg-neutral-100 dark:bg-neutral-700' +
15 | (chartType === 'Price'
16 | ? ' cursor-default bg-neutral-300 dark:bg-cyan-500/20 text-black dark:text-cyan-200 font-semibold'
17 | : ' text-neutral-800 dark:text-neutral-200 hover:bg-neutral-300 dark:hover:bg-neutral-700 focus:bg-neutral-500 dark:focus:bg-neutral-500')
18 | }
19 | >
20 | Price
21 |
22 | setChartType('Volume')}
24 | type="button"
25 | className={
26 | 'py-1.5 px-3 text-xs font-semibold bg-neutral-100 dark:bg-neutral-700' +
27 | (chartType === 'Volume'
28 | ? ' cursor-default bg-neutral-300 dark:bg-cyan-500/20 text-black dark:text-cyan-200 font-semibold'
29 | : ' text-neutral-800 dark:text-neutral-200 hover:bg-neutral-300 dark:hover:bg-neutral-700 focus:bg-neutral-500 dark:focus:bg-neutral-500')
30 | }
31 | >
32 | Volume
33 |
34 | setChartType('TVL')}
36 | type="button"
37 | className={
38 | 'py-1.5 px-3 text-xs font-semibold rounded-r-lg bg-neutral-100 dark:bg-neutral-700' +
39 | (chartType === 'TVL'
40 | ? ' cursor-default bg-neutral-300 dark:bg-cyan-500/20 text-black dark:text-cyan-200 font-semibold'
41 | : ' text-neutral-800 dark:text-neutral-200 hover:bg-neutral-300 dark:hover:bg-neutral-700 focus:bg-neutral-500 dark:focus:bg-neutral-500')
42 | }
43 | >
44 | TVL
45 |
46 |
47 | >
48 | )
49 | }
50 |
51 | export default TypeSwitch
52 |
--------------------------------------------------------------------------------
/src/pages/dashboard/components/QuadTile.tsx:
--------------------------------------------------------------------------------
1 | interface Item {
2 | key: string
3 | value: string
4 | }
5 |
6 | interface Props {
7 | item1?: Item
8 | item2?: Item
9 | item3?: Item
10 | item4?: Item
11 | }
12 |
13 | export default function QuadTile(props: Props) {
14 | return (
15 | <>
16 |
17 |
18 |
19 | {/* First Item */}
20 |
21 |
22 |
23 | {props.item1?.key}
24 |
25 |
26 | {props.item1?.value ? (
27 | <>{props.item1.value}>
28 | ) : (
29 |
30 | )}
31 |
32 |
33 |
34 | {/* Second Item */}
35 |
36 |
37 |
38 | {props.item2?.key}
39 |
40 |
41 | {props.item2?.value ? (
42 | <>{props.item2?.value}>
43 | ) : (
44 |
45 | )}
46 |
47 |
48 |
49 |
50 |
51 | {/* Third Item */}
52 |
53 |
54 |
55 | {props.item3?.key}
56 |
57 |
58 | {props.item3?.value ? (
59 | <>{props.item3.value}>
60 | ) : (
61 |
62 | )}
63 |
64 |
65 |
66 | {/* Fourth Item */}
67 |
68 |
69 |
70 | {props.item4?.key}
71 |
72 |
73 | {props.item4?.value ? (
74 | <>{props.item4.value}>
75 | ) : (
76 |
77 | )}
78 |
79 |
80 |
81 |
82 |
83 |
84 | >
85 | )
86 | }
87 |
--------------------------------------------------------------------------------
/src/pages/dashboard/components/SocialMedia.tsx:
--------------------------------------------------------------------------------
1 | import { faDiscord, faTelegram, faTwitter } from '@fortawesome/free-brands-svg-icons'
2 | import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
3 | import { trackMixPanelEvent } from 'utils/commons'
4 |
5 | export default function SocialMedia() {
6 | return (
7 | <>
8 |
9 |
25 |
26 |
42 |
43 |
59 |
60 | >
61 | )
62 | }
63 |
--------------------------------------------------------------------------------
/src/pages/ibc/components/IbcSelect.tsx:
--------------------------------------------------------------------------------
1 | interface IProps {
2 | imgSrc: string
3 | altText: string
4 | optionName: string
5 | }
6 |
7 | export default function IbcSelect(props: IProps) {
8 | return (
9 |
10 |
11 |
{props.optionName}
12 |
13 | )
14 | }
15 |
--------------------------------------------------------------------------------
/src/pages/ibc/components/ibcSchema.ts:
--------------------------------------------------------------------------------
1 | import * as yup from 'yup'
2 | import { isIbcMode } from 'types/IbcMode'
3 | import { chains } from 'utils/config'
4 |
5 | export const ibcSchema = yup.object().shape({
6 | amount: yup
7 | .number()
8 | .typeError('Please enter a valid amount')
9 | .required('Please enter a valid amount')
10 | .test('min-amount', 'Please enter a valid amount', function (value) {
11 | const { token } = this.parent
12 | if (token && typeof token.decimals === 'number') {
13 | const minAmount = Math.pow(10, -token.decimals)
14 | if (value < minAmount) {
15 | return this.createError({
16 | message: `Please enter an amount of at least ${minAmount}`
17 | })
18 | }
19 | }
20 | return true
21 | }),
22 | token: yup.mixed().required('Token is required'),
23 | chain: yup
24 | .mixed()
25 | .required('Please select a chain')
26 | .test('isValidChain', 'Please select a valid chain', (chainValue: any) =>
27 | Object.values(chains).some((chain) => chain.chain_name === chainValue.chain_name)
28 | ),
29 | ibcMode: yup
30 | .string()
31 | .required('Please pick an IBC Mode')
32 | .test('isIbcMode', 'Invalid IBC Mode', (value) => isIbcMode(value))
33 | })
34 |
--------------------------------------------------------------------------------
/src/pages/powertools/components/ApiStatusIcon.tsx:
--------------------------------------------------------------------------------
1 | import Tooltip from '@mui/material/Tooltip'
2 | import React from 'react'
3 | import { ApiStatus } from 'types/ApiStatus'
4 |
5 | type Props = {
6 | apiStatus?: ApiStatus
7 | }
8 |
9 | function ApiStatusIcon({ apiStatus = 'loading', ...props }: Props) {
10 | const colorClass: Record = {
11 | online: 'bg-emerald-500',
12 | offline: 'bg-rose-500',
13 | loading: '',
14 | unknown: 'bg-neutral-500'
15 | }
16 |
17 | const tooltipText: Record = {
18 | online: 'Online',
19 | offline: 'Offline',
20 | loading: 'Loading',
21 | unknown: 'Unknown'
22 | }
23 |
24 | return (
25 | <>
26 |
27 |
28 | {apiStatus === 'loading' ? (
29 |
30 |
36 |
37 |
42 |
43 |
44 | ) : (
45 |
46 | )}
47 |
48 |
49 | >
50 | )
51 | }
52 |
53 | export default ApiStatusIcon
54 |
--------------------------------------------------------------------------------
/src/pages/send/Send.tsx:
--------------------------------------------------------------------------------
1 | import { useEffect } from 'react'
2 | import { sendPageTitle, sendPageDescription, sendJsonLdSchema } from 'utils/commons'
3 | import Title from 'components/Title'
4 | import { Helmet } from 'react-helmet-async'
5 | import mixpanel from 'mixpanel-browser'
6 | import { useSecretNetworkClientStore } from 'store/secretNetworkClient'
7 | import SendForm from './components/SendForm'
8 |
9 | export function Send() {
10 | const { isConnected, setIsConnectWalletModalOpen, setIsGetWalletModalOpen } = useSecretNetworkClientStore()
11 |
12 | useEffect(() => {
13 | if (import.meta.env.VITE_MIXPANEL_ENABLED === 'true') {
14 | mixpanel.init(import.meta.env.VITE_MIXPANEL_PROJECT_TOKEN, {
15 | debug: false
16 | })
17 | mixpanel.identify('Dashboard-App')
18 | mixpanel.track('Open Wrap Tab')
19 | }
20 | }, [])
21 |
22 | return (
23 | <>
24 |
25 | {sendPageTitle}
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 | {/* */}
38 |
39 |
40 |
41 | {/* */}
42 |
43 |
44 |
45 |
46 |
47 | {/* Title*/}
48 |
49 | {/* Content */}
50 |
51 |
52 |
53 |
54 | >
55 | )
56 | }
57 |
--------------------------------------------------------------------------------
/src/pages/send/sendSchema.ts:
--------------------------------------------------------------------------------
1 | import * as yup from 'yup'
2 | import { validateAddress } from 'secretjs'
3 |
4 | export const sendSchema = yup.object().shape({
5 | amount: yup
6 | .number()
7 | .typeError('Please enter a valid amount')
8 | .required('Please enter a valid amount')
9 | .test('min-amount', 'Please enter a valid amount', function (value) {
10 | const { token } = this.parent
11 | if (token && typeof token.decimals === 'number') {
12 | const minAmount = Math.pow(10, -token.decimals)
13 | if (value < minAmount) {
14 | return this.createError({
15 | message: `Please enter an amount of at least ${minAmount}`
16 | })
17 | }
18 | }
19 | return true
20 | }),
21 | token: yup.mixed().required('Token is required'),
22 | recipient: yup
23 | .string()
24 | .required('Add a recipient')
25 | .test('isValidAddress', 'Please enter a valid recipient', (value) => {
26 | if (!value) return false
27 | return validateAddress(value).isValid
28 | }),
29 | memo: yup.string().max(255, 'Memo too long')
30 | })
31 |
--------------------------------------------------------------------------------
/src/pages/staking/components/ClaimRewardsModal.tsx:
--------------------------------------------------------------------------------
1 | import { useContext, useState } from 'react'
2 | import { StakingContext } from 'pages/staking/Staking'
3 | import FeeGrant from '../../../components/FeeGrant/FeeGrant'
4 | import { useSecretNetworkClientStore } from 'store/secretNetworkClient'
5 | import Modal from 'components/UI/Modal/Modal'
6 | import { StakingService } from 'services/staking.service'
7 | import Button from 'components/UI/Button/Button'
8 | import { tokens } from 'utils/config'
9 |
10 | interface Props {
11 | open: boolean
12 | onClose: any
13 | }
14 |
15 | export default function ClaimRewardsModal(props: Props) {
16 | const { secretNetworkClient, feeGrantStatus } = useSecretNetworkClientStore()
17 |
18 | const { delegatorDelegations, totalPendingRewards } = useContext(StakingContext)
19 |
20 | if (!props.open) return null
21 |
22 | async function handleClaimRewards() {
23 | await StakingService.performClaimStakingRewards({
24 | delegatorDelegations: delegatorDelegations,
25 | secretNetworkClient: secretNetworkClient,
26 | feeGrantStatus: feeGrantStatus
27 | })
28 | }
29 |
30 | return (
31 | <>
32 |
38 | {/* Body */}
39 |
40 |
41 |
Claimable Amount
42 |
43 | {totalPendingRewards}
44 | {` SCRT`}
45 |
46 |
47 |
48 |
49 |
50 |
51 | Claim Rewards
52 |
53 |
54 |
55 | >
56 | )
57 | }
58 | function getBalance(arg0: any, arg1: boolean) {
59 | throw new Error('Function not implemented.')
60 | }
61 |
--------------------------------------------------------------------------------
/src/pages/staking/components/NoScrtWarning.tsx:
--------------------------------------------------------------------------------
1 | import { faArrowUpRightFromSquare, faInfoCircle } from '@fortawesome/free-solid-svg-icons'
2 | import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
3 |
4 | function NoScrtWarning() {
5 | return (
6 | <>
7 |
8 |
9 |
10 |
11 |
12 |
13 | {`You do not have any SCRT for Staking`}
14 |
15 |
34 |
35 |
36 |
37 |
38 | >
39 | )
40 | }
41 |
42 | export default NoScrtWarning
43 |
--------------------------------------------------------------------------------
/src/pages/staking/components/StakingStats/AvailableBalance.tsx:
--------------------------------------------------------------------------------
1 | import BigNumber from 'bignumber.js'
2 | import { APIContext } from 'context/APIContext'
3 | import { useContext, useEffect, useState } from 'react'
4 | import { useTokenPricesStore } from 'store/TokenPrices'
5 | import { useUserPreferencesStore } from 'store/UserPreferences'
6 | import { useSecretNetworkClientStore } from 'store/secretNetworkClient'
7 | import { toCurrencyString } from 'utils/commons'
8 | import { tokens } from 'utils/config'
9 | import { scrtToken } from 'utils/tokens'
10 |
11 | function AvailableBalance() {
12 | const { getBalance } = useSecretNetworkClientStore()
13 |
14 | const scrtBalance = getBalance(
15 | tokens.find((token) => token.name === 'SCRT'),
16 | false
17 | )
18 |
19 | const { currency } = useUserPreferencesStore()
20 | const { convertCurrency } = useContext(APIContext)
21 |
22 | const { getValuePrice, priceMapping } = useTokenPricesStore()
23 |
24 | const [availableBalanceInCurrency, setAvailableBalanceInCurrency] = useState('')
25 |
26 | useEffect(() => {
27 | if (priceMapping !== null && scrtBalance !== null) {
28 | const valuePrice = getValuePrice(scrtToken, BigNumber(scrtBalance))
29 | if (valuePrice) {
30 | const priceInCurrency = convertCurrency('USD', valuePrice, currency)
31 | if (priceInCurrency !== null) {
32 | setAvailableBalanceInCurrency(toCurrencyString(priceInCurrency, currency))
33 | }
34 | }
35 | }
36 | }, [priceMapping, scrtBalance])
37 |
38 | return (
39 |
40 |
Available Balance
41 |
42 |
43 | {scrtBalance !== null ? (
44 | <>{new BigNumber(scrtBalance).dividedBy(`1e${scrtToken.decimals}`).toNumber()}>
45 | ) : (
46 |
49 | )}
50 |
51 |
SCRT
52 |
53 |
54 | {availableBalanceInCurrency ? (
55 | <>{availableBalanceInCurrency}>
56 | ) : (
57 |
60 | )}
61 |
62 |
63 | )
64 | }
65 |
66 | export default AvailableBalance
67 |
--------------------------------------------------------------------------------
/src/pages/staking/components/StakingStats/ClaimableRewards.tsx:
--------------------------------------------------------------------------------
1 | import BigNumber from 'bignumber.js'
2 | import Button from 'components/UI/Button/Button'
3 | import { APIContext } from 'context/APIContext'
4 | import { StakingContext } from 'pages/staking/Staking'
5 | import { useContext, useEffect, useState } from 'react'
6 | import { useTokenPricesStore } from 'store/TokenPrices'
7 | import { useUserPreferencesStore } from 'store/UserPreferences'
8 | import { toCurrencyString } from 'utils/commons'
9 | import { scrtToken } from 'utils/tokens'
10 |
11 | function ClaimableRewards() {
12 | const { setIsClaimRewardsModalOpen, totalPendingRewards } = useContext(StakingContext)
13 | const { convertCurrency } = useContext(APIContext)
14 | const { getValuePrice, priceMapping } = useTokenPricesStore()
15 | const { currency } = useUserPreferencesStore()
16 |
17 | const [claimableRewardsInCurrency, setClaimableRewardsInCurrency] = useState('')
18 |
19 | useEffect(() => {
20 | if (priceMapping !== null && totalPendingRewards !== null) {
21 | const valuePrice = getValuePrice(
22 | scrtToken,
23 | BigNumber(totalPendingRewards).multipliedBy(`1e${scrtToken.decimals}`)
24 | )
25 | if (valuePrice) {
26 | const priceInCurrency = convertCurrency('USD', valuePrice, currency)
27 | if (priceInCurrency !== null) {
28 | setClaimableRewardsInCurrency(toCurrencyString(priceInCurrency, currency))
29 | }
30 | setClaimableRewardsInCurrency(toCurrencyString(valuePrice, currency))
31 | }
32 | }
33 | }, [priceMapping, totalPendingRewards])
34 |
35 | function openClaimRewardsModal() {
36 | setIsClaimRewardsModalOpen(true)
37 | }
38 |
39 | return (
40 |
41 |
42 |
Claimable Rewards
43 |
44 | {totalPendingRewards !== null ? (
45 | <>
46 |
{totalPendingRewards}
47 |
SCRT
48 | >
49 | ) : (
50 |
53 | )}
54 |
55 |
56 | {claimableRewardsInCurrency ? (
57 | <>{claimableRewardsInCurrency}>
58 | ) : (
59 |
62 | )}
63 |
64 |
65 |
66 |
67 | Claim
68 |
69 |
70 |
71 | )
72 | }
73 |
74 | export default ClaimableRewards
75 |
--------------------------------------------------------------------------------
/src/pages/staking/components/StakingStats/StakingAmount.tsx:
--------------------------------------------------------------------------------
1 | import BigNumber from 'bignumber.js'
2 | import { APIContext } from 'context/APIContext'
3 | import { StakingContext } from 'pages/staking/Staking'
4 | import { useContext, useEffect, useState } from 'react'
5 | import { useTokenPricesStore } from 'store/TokenPrices'
6 | import { useUserPreferencesStore } from 'store/UserPreferences'
7 | import { Nullable } from 'types/Nullable'
8 | import { toCurrencyString } from 'utils/commons'
9 | import { scrtToken } from 'utils/tokens'
10 |
11 | type Props = {
12 | stakedAmount?: Nullable
13 | }
14 |
15 | function StakingAmount(props: Props) {
16 | const { convertCurrency } = useContext(APIContext)
17 | const { getValuePrice, priceMapping } = useTokenPricesStore()
18 | const { currency } = useUserPreferencesStore()
19 | const [stakedAmountInCurrency, setStakedAmountInCurrency] = useState('')
20 |
21 | useEffect(() => {
22 | if (priceMapping !== null && props.stakedAmount !== null) {
23 | const valuePrice = getValuePrice(scrtToken, BigNumber(props.stakedAmount).multipliedBy(`1e${scrtToken.decimals}`))
24 | if (valuePrice) {
25 | const priceInCurrency = convertCurrency('USD', valuePrice, currency)
26 | if (priceInCurrency !== null) {
27 | setStakedAmountInCurrency(toCurrencyString(priceInCurrency, currency))
28 | }
29 | }
30 | }
31 | }, [priceMapping, props.stakedAmount])
32 |
33 | return (
34 |
35 |
Total Staked
36 |
37 | {props.stakedAmount !== null ? (
38 | <>
39 |
{props.stakedAmount}
40 |
SCRT
41 | >
42 | ) : (
43 |
46 | )}
47 |
48 |
49 | {stakedAmountInCurrency ? (
50 | <>{stakedAmountInCurrency}>
51 | ) : (
52 |
55 | )}
56 |
57 |
58 | )
59 | }
60 |
61 | export default StakingAmount
62 |
--------------------------------------------------------------------------------
/src/pages/staking/components/StakingStats/StakingStats.tsx:
--------------------------------------------------------------------------------
1 | import { useContext } from 'react'
2 | import StakingAmount from './StakingAmount'
3 | import AvailableBalance from './AvailableBalance'
4 | import ClaimableRewards from './ClaimableRewards'
5 | import { StakingContext } from 'pages/staking/Staking'
6 |
7 | function StakingStats() {
8 | const { getTotalAmountStaked } = useContext(StakingContext)
9 |
10 | const stakedAmount = getTotalAmountStaked() || null
11 |
12 | return (
13 |
14 |
15 | {/* Total Staked */}
16 |
17 |
18 |
19 |
20 | {/* Available Balance */}
21 |
24 |
25 | {/* Claimable Rewards */}
26 |
27 |
28 |
29 |
30 |
31 | )
32 | }
33 |
34 | export default StakingStats
35 |
--------------------------------------------------------------------------------
/src/pages/wrap/Wrap.tsx:
--------------------------------------------------------------------------------
1 | import { useEffect, useState, useContext, createContext } from 'react'
2 | import { Token, tokens } from 'utils/config'
3 | import { wrapPageTitle, wrapPageDescription, wrapJsonLdSchema } from 'utils/commons'
4 | import { Helmet } from 'react-helmet-async'
5 | import FeeGrantInfoModal from './components/FeeGrantInfoModal'
6 | import mixpanel from 'mixpanel-browser'
7 | import { WrappingMode, isWrappingMode } from 'types/WrappingMode'
8 | import { useSecretNetworkClientStore } from 'store/secretNetworkClient'
9 | import Title from 'components/Title'
10 | import WrapForm from './components/WrapForm'
11 | import SCRTUnwrapWarning from './components/SCRTUnwrapWarning'
12 |
13 | export function Wrap() {
14 | const { getBalance } = useSecretNetworkClientStore()
15 | const scrtBalance = getBalance(
16 | tokens.find((token) => token.name === 'SCRT'),
17 | false
18 | )
19 |
20 | useEffect(() => {
21 | if (import.meta.env.VITE_MIXPANEL_ENABLED === 'true') {
22 | mixpanel.init(import.meta.env.VITE_MIXPANEL_PROJECT_TOKEN, {
23 | debug: false
24 | })
25 | mixpanel.identify('Dashboard-App')
26 | mixpanel.track('Open Wrap Tab')
27 | }
28 | }, [])
29 |
30 | const infoMsg = `Converting publicly visible tokens into its privacy-preserving equivalent Secret Token and vice versa. These tokens are not publicly visible and require a viewing key.`
31 |
32 | const [isFeeGrantInfoModalOpen, setIsFeeGrantInfoModalOpen] = useState(false)
33 |
34 | return (
35 | <>
36 |
37 | {wrapPageTitle}
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 | {/* */}
50 |
51 |
52 |
53 | {/* */}
54 |
55 |
56 |
57 |
58 | {
61 | setIsFeeGrantInfoModalOpen(false)
62 | document.body.classList.remove('overflow-hidden')
63 | }}
64 | />
65 |
66 | {/* Content */}
67 |
68 | {/* Title: Secret Wrap / Secret Unwrap */}
69 |
70 | {Number(scrtBalance) === 0 && scrtBalance !== null ?
: null}
71 | {/* Content */}
72 |
73 |
74 |
75 |
76 | >
77 | )
78 | }
79 |
--------------------------------------------------------------------------------
/src/pages/wrap/components/FeeGrantInfoModal.tsx:
--------------------------------------------------------------------------------
1 | import { faInfoCircle, faXmark } from '@fortawesome/free-solid-svg-icons'
2 | import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
3 | import { useEffect } from 'react'
4 |
5 | interface Props {
6 | open?: boolean
7 | onClose?: any
8 | }
9 |
10 | const FeeGrantInfoModal = (props: Props) => {
11 | // disable body scroll on open
12 | useEffect(() => {
13 | if (props.open) {
14 | document.body.classList.add('overflow-hidden')
15 | } else {
16 | document.body.classList.remove('overflow-hidden')
17 | }
18 | }, [props.open])
19 |
20 | if (!props.open) return null
21 |
22 | return (
23 |
24 |
25 |
26 |
{
29 | e.stopPropagation()
30 | }}
31 | >
32 | {/* Header */}
33 |
34 |
38 |
39 |
40 |
41 |
42 | {/* Header */}
43 |
44 |
45 |
46 | Fee Grant Feature
47 |
48 |
49 | Lorem, ipsum dolor sit amet consectetur adipisicing elit. Corrupti, ducimus? Modi inventore, deleniti
50 | culpa quasi quis reiciendis sint, consectetur voluptate eaque ea aliquam rerum natus vel nostrum, quod
51 | praesentium quidem!
52 |
53 |
57 | Close
58 |
59 |
60 |
61 | {/* Body */}
62 |
63 |
64 |
65 |
66 |
67 | )
68 | }
69 |
70 | export default FeeGrantInfoModal
71 |
--------------------------------------------------------------------------------
/src/pages/wrap/components/SCRTUnwrapWarning.tsx:
--------------------------------------------------------------------------------
1 | import { faTriangleExclamation } from '@fortawesome/free-solid-svg-icons'
2 | import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
3 |
4 | function SCRTUnwrapWarning() {
5 | return (
6 |
20 | )
21 | }
22 |
23 | export default SCRTUnwrapWarning
24 |
--------------------------------------------------------------------------------
/src/pages/wrap/components/wrap.scss:
--------------------------------------------------------------------------------
1 | .no-spinner::-webkit-inner-spin-button,
2 | .no-spinner::-webkit-outer-spin-button {
3 | -webkit-appearance: none;
4 | margin: 0;
5 | }
6 |
7 | .no-spinner {
8 | -moz-appearance: textfield;
9 | }
10 |
--------------------------------------------------------------------------------
/src/services/notification.service.ts:
--------------------------------------------------------------------------------
1 | import toast from 'react-hot-toast'
2 | import { NotificationType } from 'types/NotificationType'
3 |
4 | function notify(notification: string, type: NotificationType, toastId: string = null) {
5 | // Define an options object for toast, if toastId is provided
6 | const options = {
7 | id: toastId || undefined,
8 | duration: type === 'success' ? 10000 : Infinity,
9 | onClick: () => {
10 | toast.dismiss()
11 | },
12 | style: {
13 | maxWidth: '35vw',
14 | whiteSpace: 'pre-wrap' as any,
15 | wordBreak: 'break-word' as any
16 | },
17 | position: 'bottom-right' as any
18 | }
19 |
20 | switch (type) {
21 | case 'error':
22 | return toast.error(notification, options)
23 |
24 | case 'loading':
25 | return toast.loading(notification, options)
26 |
27 | case 'success':
28 | return toast.success(notification, options)
29 |
30 | default:
31 | return null
32 | }
33 | }
34 |
35 | export const NotificationService = {
36 | notify
37 | }
38 |
--------------------------------------------------------------------------------
/src/services/send.service.ts:
--------------------------------------------------------------------------------
1 | import BigNumber from 'bignumber.js'
2 | import { BroadcastMode, MsgExecuteContract, MsgSend, SecretNetworkClient } from 'secretjs'
3 | import { FeeGrantStatus } from 'types/FeeGrantStatus'
4 | import { Nullable } from 'types/Nullable'
5 | import { allTokens, faucetAddress, queryTxResult, randomPadding } from 'utils/commons'
6 | import { Token, tokens } from 'utils/config'
7 |
8 | function getSupportedTokens() {
9 | return [allTokens[0]].concat(
10 | allTokens.map((token: Token) => (token.name === 'SCRT' ? { ...token, address: 'native' } : token))
11 | )
12 | }
13 |
14 | interface IBaseProps {
15 | amount: string
16 | recipient: string
17 | memo?: string
18 | secretNetworkClient: SecretNetworkClient
19 | feeGrantStatus: FeeGrantStatus
20 | }
21 |
22 | interface IPropsToken extends IBaseProps {
23 | token: Token
24 | }
25 |
26 | // Main function to perform the sending
27 | async function performSending(props: IPropsToken): Promise {
28 | let token = props.token
29 |
30 | if (!token) {
31 | console.error('token', token)
32 | throw new Error('Token not found')
33 | }
34 |
35 | const baseAmount = props.amount
36 | const amount = new BigNumber(Number(baseAmount)).multipliedBy(`1e${token.decimals}`).toFixed(0, BigNumber.ROUND_DOWN)
37 |
38 | if (amount === 'NaN') {
39 | console.error('NaN amount', baseAmount)
40 | throw new Error('Amount is not a valid number')
41 | }
42 |
43 | // Broadcast the transaction
44 | const broadcastResult = await props.secretNetworkClient.tx.broadcast(
45 | [
46 | token.address === 'native'
47 | ? new MsgSend({
48 | from_address: props.secretNetworkClient?.address,
49 | to_address: props.recipient,
50 | amount: [
51 | {
52 | amount: amount,
53 | denom: 'uscrt'
54 | }
55 | ]
56 | })
57 | : new MsgExecuteContract({
58 | sender: props.secretNetworkClient?.address,
59 | contract_address: token.address,
60 | code_hash: token.code_hash,
61 | sent_funds: [],
62 | msg: {
63 | transfer: {
64 | recipient: props.recipient,
65 | amount: amount,
66 | padding: randomPadding()
67 | }
68 | }
69 | })
70 | ],
71 | {
72 | gasLimit: 150_000,
73 | gasPriceInFeeDenom: 0.25,
74 | feeDenom: 'uscrt',
75 | feeGranter: props.feeGrantStatus === 'success' ? faucetAddress : '',
76 | broadcastMode: BroadcastMode.Sync,
77 | memo: props.memo,
78 | waitForCommit: false
79 | }
80 | )
81 |
82 | // Poll the LCD for the transaction result every 10 seconds, 10 retries
83 | await queryTxResult(props.secretNetworkClient, broadcastResult.transactionHash, 6000, 10)
84 | .catch((error: any) => {
85 | console.error(error)
86 | throw error
87 | })
88 | .then((tx: any) => {
89 | if (tx) {
90 | if (tx.code === 0) {
91 | return 'success'
92 | } else {
93 | console.error(tx.rawLog)
94 | throw new Error(tx.rawLog)
95 | }
96 | }
97 | })
98 | return
99 | }
100 |
101 | export const SendService = {
102 | performSending,
103 | getSupportedTokens
104 | }
105 |
--------------------------------------------------------------------------------
/src/services/staking.service.ts:
--------------------------------------------------------------------------------
1 | import { BroadcastMode, MsgWithdrawDelegatorReward, SecretNetworkClient } from 'secretjs'
2 | import { FeeGrantStatus } from 'types/FeeGrantStatus'
3 | import { faucetAddress, queryTxResult } from 'utils/commons'
4 | import { NotificationService } from './notification.service'
5 |
6 | interface Props {
7 | delegatorDelegations: any
8 | secretNetworkClient: SecretNetworkClient
9 | feeGrantStatus: FeeGrantStatus
10 | }
11 |
12 | /**
13 | * Attempts to perform staking via secret.js API
14 | *
15 | * @param {TProps} props
16 | * @returns {Promise<{success: boolean, errorMsg: Nullable}>} A promise that resolves to an object containing:
17 | * - `success`: A boolean indicating whether the wrapping operation was successful.
18 | * - `errorMsg`: A string containing an error message if something went wrong, or null if there were no errors.
19 | * @async
20 | */
21 |
22 | const performClaimStakingRewards = async (props: Props) => {
23 | const toastId = NotificationService.notify(`Claiming Staking Rewards`, 'loading')
24 |
25 | try {
26 | const txs = props.delegatorDelegations.map((delegation: any) => {
27 | return new MsgWithdrawDelegatorReward({
28 | delegator_address: props.secretNetworkClient.address,
29 | validator_address: delegation?.delegation?.validator_address
30 | })
31 | })
32 |
33 | const broadcastResult = await props.secretNetworkClient.tx.broadcast(txs, {
34 | gasLimit: 100_000 * txs.length,
35 | gasPriceInFeeDenom: 0.25,
36 | feeDenom: 'uscrt',
37 | feeGranter: props.feeGrantStatus === 'success' ? faucetAddress : '',
38 | broadcastMode: BroadcastMode.Sync,
39 | waitForCommit: false
40 | })
41 |
42 | // Poll the LCD for the transaction result every 10 seconds, 10 retries
43 | await queryTxResult(props.secretNetworkClient, broadcastResult.transactionHash, 6000, 10)
44 | .catch((error: any) => {
45 | console.error(error)
46 | if (error?.tx?.rawLog) {
47 | NotificationService.notify(`Claiming staking rewards failed: ${error.tx.rawLog}`, 'error', toastId)
48 | } else {
49 | NotificationService.notify(`Claiming staking rewards failed: ${error.message}`, 'error', toastId)
50 | }
51 | })
52 | .then((tx: any) => {
53 | if (tx) {
54 | if (tx.code === 0) {
55 | NotificationService.notify(`Claimed staking rewards successfully`, 'success', toastId)
56 | } else {
57 | NotificationService.notify(`Claiming staking rewards failed: ${tx.rawLog}`, 'error', toastId)
58 | }
59 | }
60 | })
61 | } catch (e: any) {
62 | console.error(e)
63 | }
64 | }
65 |
66 | export const StakingService = {
67 | performClaimStakingRewards
68 | }
69 |
--------------------------------------------------------------------------------
/src/store/TokenPrices.ts:
--------------------------------------------------------------------------------
1 | import BigNumber from 'bignumber.js'
2 | import { Nullable } from 'types/Nullable'
3 | import { allTokens, toCurrencyString } from 'utils/commons'
4 | import { Token, tokens } from 'utils/config'
5 | import { create } from 'zustand'
6 |
7 | export interface CoinPrice {
8 | coingecko_id: string
9 | priceUsd: number
10 | }
11 |
12 | interface TokenPricesState {
13 | priceMapping: Map
14 | init: () => void
15 | isInitialized: boolean
16 | getPrice: (token: Token) => Nullable
17 | getValuePrice: (token: Token, amount: BigNumber) => Nullable
18 | }
19 |
20 | export const useTokenPricesStore = create()((set, get) => ({
21 | priceMapping: null,
22 | isInitialized: false,
23 | init: () => {
24 | let prices: CoinPrice[]
25 |
26 | /*let coinGeckoIdsString: string = allTokens.map((token) => token.coingecko_id).join(',')
27 | console.log(coinGeckoIdsString)*/
28 |
29 | // fetch(`https://api.coingecko.com/api/v3/simple/price?ids=${coinGeckoIdsString}&vs_currencies=USD`)
30 | fetch(`https://priceapibuffer.secretsaturn.net/getPrices`)
31 | .then((resp) => resp.json())
32 | .then((result: { [coingecko_id: string]: { usd: number } }) => {
33 | const formattedPrices = Object.entries(result).map(([coingecko_id, { usd }]) => ({
34 | coingecko_id,
35 | priceUsd: usd
36 | }))
37 | prices = formattedPrices
38 | const priceMapping = new Map()
39 | allTokens.forEach((token: Token) => {
40 | priceMapping.set(token, prices.find((price: any) => price.coingecko_id === token.coingecko_id)?.priceUsd)
41 | })
42 |
43 | set({
44 | priceMapping: priceMapping
45 | })
46 | })
47 | .catch((error) => {
48 | console.error(error)
49 | const priceMapping = new Map()
50 | tokens.forEach((token: Token) => {
51 | priceMapping.set(token, undefined)
52 | })
53 | set({
54 | priceMapping: priceMapping
55 | })
56 | })
57 | set({
58 | priceMapping: new Map(),
59 | isInitialized: true
60 | })
61 | },
62 | getPrice: (token: Token) => {
63 | if (!get().isInitialized) {
64 | get().init()
65 | }
66 | const tokenPrice = get().priceMapping.get(token)
67 | if (tokenPrice !== undefined) {
68 | return toCurrencyString(tokenPrice)
69 | }
70 | return null
71 | },
72 | getValuePrice: (token: Token, amount: BigNumber = new BigNumber(1)): Nullable => {
73 | if (!get().isInitialized) {
74 | get().init()
75 | }
76 | const tokenPrice = get().priceMapping.get(token)
77 | if (tokenPrice !== undefined) {
78 | const result = new BigNumber(tokenPrice).multipliedBy(amount).dividedBy(`1e${token.decimals}`)
79 | return Number(result)
80 | }
81 | return null
82 | }
83 | }))
84 |
--------------------------------------------------------------------------------
/src/store/UserPreferences.ts:
--------------------------------------------------------------------------------
1 | import { Currency } from 'types/Currency'
2 | import { Theme } from 'types/Theme'
3 | import { create } from 'zustand'
4 | import { persist } from 'zustand/middleware'
5 |
6 | interface UserPreferencesState {
7 | theme: Theme
8 | debugMode: boolean
9 | currency: Currency
10 | }
11 |
12 | interface UserPreferencesActions {
13 | setTheme: (theme: UserPreferencesState['theme']) => void
14 | setDebugMode: (debugMode: boolean) => void
15 | setCurrency: (currency: UserPreferencesState['currency']) => void
16 | }
17 |
18 | type UserPreferencesStore = UserPreferencesState & UserPreferencesActions
19 |
20 | export const useUserPreferencesStore = create()(
21 | persist(
22 | (set, get) => ({
23 | // Default preferences
24 | theme: 'dark',
25 | debugMode: false,
26 | currency: 'USD',
27 |
28 | // Actions to update preferences
29 | setTheme: (theme: Theme) => set(() => ({ theme })),
30 | setDebugMode: (debugMode: boolean) => set(() => ({ debugMode })),
31 | setCurrency: (currency: Currency) => set(() => ({ currency }))
32 | }),
33 | {
34 | name: 'user-preferences',
35 | getStorage: () => localStorage
36 | }
37 | )
38 | )
39 |
--------------------------------------------------------------------------------
/src/types/ApiStatus.ts:
--------------------------------------------------------------------------------
1 | export type ApiStatus = 'online' | 'offline' | 'loading' | 'unknown'
2 |
3 | export function isApiStatus(x: any): boolean {
4 | return x === 'online' || x === 'offline' || x === 'loading' || x === 'unknown'
5 | }
6 |
--------------------------------------------------------------------------------
/src/types/Currency.ts:
--------------------------------------------------------------------------------
1 | import { Nullable } from './Nullable'
2 |
3 | export type Currency = 'USD' | 'EUR' | 'JPY' | 'GBP' | 'AUD' | 'CAD' | 'CHF'
4 |
5 | export function isCurrency(x: any): boolean {
6 | return x === 'USD' || x === 'EUR' || x === 'JPY' || x === 'GBP' || x === 'AUD' || x === 'CAD' || x === 'CHF'
7 | }
8 |
--------------------------------------------------------------------------------
/src/types/FeeGrantStatus.ts:
--------------------------------------------------------------------------------
1 | export type FeeGrantStatus = 'success' | 'fail' | 'untouched'
2 |
3 | export function isFeeGrantStatus(x: any): boolean {
4 | return x === 'success' || x === 'fail' || x === 'untouched'
5 | }
6 |
--------------------------------------------------------------------------------
/src/types/GetBalanceError.ts:
--------------------------------------------------------------------------------
1 | export type GetBalanceError = 'viewingKeyError' | 'GenericFetchError'
2 |
3 | export function isGetBalanceError(x: String): boolean {
4 | return x === 'viewingKeyError' || x === 'GenericFetchError'
5 | }
6 |
--------------------------------------------------------------------------------
/src/types/IbcMode.ts:
--------------------------------------------------------------------------------
1 | export type IbcMode = 'deposit' | 'withdrawal'
2 |
3 | export function isIbcMode(x: String): boolean {
4 | return x === 'deposit' || x === 'withdrawal'
5 | }
6 |
--------------------------------------------------------------------------------
/src/types/MessageType.ts:
--------------------------------------------------------------------------------
1 | export type MessageType =
2 | | 'MultiSend'
3 | | 'Send'
4 | | 'ExecuteContract'
5 | | 'InstantiateContract'
6 | | 'FundCommunityPool'
7 | | 'SetAutoRestake'
8 | | 'SetWithdrawAddress'
9 | | 'WithdrawDelegatorReward'
10 | | 'WithdrawValidatorCommission'
11 | | 'Deposit'
12 | | 'Vote'
13 | | 'VoteWeighted'
14 | | 'Transfer'
15 | | 'Unjail'
16 | | 'BeginRedelegate'
17 | | 'CreateValidator'
18 | | 'Delegate'
19 | | 'EditValidator'
20 | | 'Undelegate'
21 | | 'CreateVestingAccount'
22 |
23 | export function isMessageType(x: String): boolean {
24 | return (
25 | x === 'MultiSend' ||
26 | x === 'Send' ||
27 | x === 'ExecuteContract' ||
28 | x === 'InstantiateContract' ||
29 | x === 'FundCommunityPool' ||
30 | x === 'SetAutoRestake' ||
31 | x === 'SetWithdrawAddress' ||
32 | x === 'WithdrawDelegatorReward' ||
33 | x === 'WithdrawValidatorCommission' ||
34 | x === 'Deposit' ||
35 | x === 'Vote' ||
36 | x === 'VoteWeighted' ||
37 | x === 'Transfer' ||
38 | x === 'Unjail' ||
39 | x === 'BeginRedelegate' ||
40 | x === 'CreateValidator' ||
41 | x === 'Delegate' ||
42 | x === 'EditValidator' ||
43 | x === 'Undelegate' ||
44 | x === 'CreateVestingAccount'
45 | )
46 | }
47 |
--------------------------------------------------------------------------------
/src/types/NotificationType.ts:
--------------------------------------------------------------------------------
1 | export type NotificationType = 'success' | 'error' | 'loading'
2 |
3 | export function isNotificationType(x: String): boolean {
4 | return x === 'success' || x === 'error' || x === 'loading'
5 | }
6 |
--------------------------------------------------------------------------------
/src/types/Nullable.ts:
--------------------------------------------------------------------------------
1 | export type Nullable = X | null
2 |
--------------------------------------------------------------------------------
/src/types/StakingView.ts:
--------------------------------------------------------------------------------
1 | export type StakingView = 'delegate' | 'redelegate' | 'undelegate'
2 |
3 | export const isStakingView = (x: string) => {
4 | return x === 'delegate' || x === 'redelegate' || x === 'undelegate'
5 | }
6 |
--------------------------------------------------------------------------------
/src/types/Theme.ts:
--------------------------------------------------------------------------------
1 | export type Theme = 'light' | 'dark'
2 |
3 | export function isTheme(x: String): boolean {
4 | return x === 'light' || x === 'dark'
5 | }
6 |
--------------------------------------------------------------------------------
/src/types/TokenBalances.ts:
--------------------------------------------------------------------------------
1 | import BigNumber from 'bignumber.js'
2 | import { Nullable } from './Nullable'
3 | import { GetBalanceError } from './GetBalanceError'
4 |
5 | export type TokenBalances = {
6 | balance: Nullable
7 | secretBalance?: Nullable
8 | }
9 |
--------------------------------------------------------------------------------
/src/types/Validator.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Represents a dummy type for better code readability.
3 | * @typedef {Object.} Validator
4 | */
5 |
6 | export type Validator = {
7 | [prop: string]: any
8 | }
9 |
--------------------------------------------------------------------------------
/src/types/ValidatorRestakeStatus.ts:
--------------------------------------------------------------------------------
1 | export type ValidatorRestakeStatus = {
2 | validatorAddress: string
3 | autoRestake: boolean
4 | stakedAmount: string
5 | }
6 |
--------------------------------------------------------------------------------
/src/types/WalletAPIType.ts:
--------------------------------------------------------------------------------
1 | export type WalletAPIType = 'keplr' | 'leap'
2 |
3 | export function isWalletAPIType(x: String): boolean {
4 | return x === 'keplr' || x === 'leap'
5 | }
6 |
--------------------------------------------------------------------------------
/src/types/WrappingMode.ts:
--------------------------------------------------------------------------------
1 | export type WrappingMode = 'wrap' | 'unwrap'
2 |
3 | export function isWrappingMode(x: String): boolean {
4 | return x === 'wrap' || x === 'unwrap'
5 | }
6 |
--------------------------------------------------------------------------------
/src/utils/env.d.ts:
--------------------------------------------------------------------------------
1 | interface ImportMeta {
2 | readonly env: ImportMetaEnv
3 | }
4 |
--------------------------------------------------------------------------------
/src/utils/tokens.ts:
--------------------------------------------------------------------------------
1 | import { Token, tokens } from './config'
2 |
3 | export const scrtToken: Token = tokens.find((token) => token.name === 'SCRT')
4 |
--------------------------------------------------------------------------------
/src/utils/useHoverOutside.ts:
--------------------------------------------------------------------------------
1 | import { useEffect } from 'react'
2 |
3 | export function useHoverOutside(ref: any, handler: any) {
4 | useEffect(() => {
5 | const listener = (event: any) => {
6 | if (!ref.current || ref.current.contains(event.target)) {
7 | return
8 | }
9 | handler(event)
10 | }
11 | document.addEventListener('mouseover', listener)
12 | document.addEventListener('touchstart', listener)
13 | return () => {
14 | document.removeEventListener('mouseover', listener)
15 | document.removeEventListener('touchstart', listener)
16 | }
17 | }, [ref, handler])
18 | }
19 |
--------------------------------------------------------------------------------
/src/utils/vite-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ESNext",
4 | "lib": ["DOM", "DOM.Iterable", "ESNext"],
5 | "allowJs": false,
6 | "skipLibCheck": true,
7 | "esModuleInterop": false,
8 | "allowSyntheticDefaultImports": true,
9 | "strict": true,
10 | "strictNullChecks": false,
11 | "forceConsistentCasingInFileNames": true,
12 | "module": "ESNext",
13 | "moduleResolution": "Node",
14 | "resolveJsonModule": true,
15 | "isolatedModules": true,
16 | "noEmit": true,
17 | "jsx": "react-jsx",
18 | "baseUrl": "src"
19 | },
20 | "include": ["src"]
21 | }
22 |
--------------------------------------------------------------------------------
/vite-plugin-whip-003.ts:
--------------------------------------------------------------------------------
1 | import { Plugin } from 'vite'
2 |
3 | export function whip003(): Plugin {
4 | return {
5 | name: 'build-tokens',
6 | async buildStart(options) {
7 | const { chains, tokens, snips } = await import('./src/utils/config')
8 |
9 | const whip003 = {
10 | chains: {},
11 | contracts: {}
12 | }
13 |
14 | // add chain definitions
15 | for (const chain of Object.values(chains)) {
16 | whip003.chains[chain.chain_id] = {
17 | namespace: 'cosmos',
18 | reference: chain.chain_id,
19 | label: chain.chain_name,
20 | bech32s: chain.bech32_prefix
21 | }
22 | }
23 |
24 | // add IBC tokens
25 | for (const token of Object.values(tokens)) {
26 | whip003.contracts[token.name] = {
27 | chain: 'cosmos:secret-4',
28 | address: token.address,
29 | label:
30 | 1 === token.withdrawals.length
31 | ? token.deposits[0].chain_name
32 | : 'SCRT' === token.name
33 | ? 'Secret Network'
34 | : token.name,
35 | interfaces: {
36 | snip20: {
37 | symbol: token.name,
38 | decimals: token.decimals,
39 | coingeckoId: token.coingecko_id
40 | }
41 | }
42 | }
43 | }
44 |
45 | // add IBC tokens
46 | for (const token of Object.values(tokens)) {
47 | whip003.contracts[token.name] = {
48 | chain: 'cosmos:secret-4',
49 | address: token.address,
50 | label:
51 | 1 === token.withdrawals.length
52 | ? token.deposits[0].chain_name
53 | : 'SCRT' === token.name
54 | ? 'Secret Network'
55 | : token.name,
56 | interfaces: {
57 | snip20: {
58 | symbol: token.name,
59 | decimals: token.decimals,
60 | coingeckoId: token.coingecko_id
61 | }
62 | }
63 | }
64 | }
65 |
66 | // add SNIPs
67 | for (const snip of Object.values(snips)) {
68 | whip003.contracts[snip.name] = {
69 | chain: 'cosmos:secret-4',
70 | address: snip.address,
71 | label: snip.coingecko_id
72 | ? snip.coingecko_id.replace(/-/g, ' ').replace(/\b[a-z]/g, (s) => s.toUpperCase())
73 | : snip.name,
74 | interfaces: {
75 | snip20: {
76 | symbol: snip.name,
77 | decimals: snip.decimals,
78 | coingeckoId: snip.coingecko_id
79 | }
80 | }
81 | }
82 | }
83 |
84 | // emit the whip-003 JSON definition
85 | this.emitFile({
86 | type: 'asset',
87 | fileName: 'whip-003.json',
88 | source: JSON.stringify(whip003, null, '\t')
89 | })
90 | }
91 | }
92 | }
93 |
--------------------------------------------------------------------------------
/vite.config.ts:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'vite'
2 | import react from '@vitejs/plugin-react'
3 | import tsconfigPaths from 'vite-tsconfig-paths'
4 | import { whip003 } from './vite-plugin-whip-003'
5 |
6 | export default defineConfig({
7 | plugins: [
8 | { ...react() },
9 | { ...tsconfigPaths() },
10 | {
11 | ...whip003(),
12 | apply: 'build'
13 | }
14 | ],
15 | server: {
16 | host: true,
17 | port: 3000
18 | },
19 | resolve: {
20 | alias: [
21 | {
22 | find: '@buf/evmos_evmos.bufbuild_es/evmos/vesting/v1/tx_pb.js',
23 | replacement: '@buf/evmos_evmos.bufbuild_es/evmos/vesting/v2/tx_pb.js'
24 | },
25 | {
26 | find: '@buf/evmos_evmos.bufbuild_es/evmos/revenue/v1/tx_pb.js',
27 | replacement: '@evmos/proto/dist/proto/evmos/revenue/v1/tx.js'
28 | }
29 | ]
30 | },
31 | build: {
32 | minify: 'esbuild'
33 | }
34 | })
35 |
--------------------------------------------------------------------------------