├── .eslintrc.json ├── .gitignore ├── .prettierignore ├── .prettierrc.json ├── README.md ├── generate-farm-info.sh ├── generate-static.sh ├── package.json ├── public ├── favicon.ico ├── favicon.svg ├── fonts │ ├── NeueHaasGroteskDisp Pro Md.eot │ ├── NeueHaasGroteskDisp Pro Md.ttf │ ├── NeueHaasGroteskDisp Pro Md.woff │ └── NeueHaasGroteskDisp Pro Md.woff2 ├── index.html ├── manifest.json └── robots.txt ├── scripts └── remove-iframe-deny.js ├── src ├── App.js ├── App.test.js ├── assets │ ├── aav-ewhite-logo-risk.svg │ ├── aav-ewhite-logo.svg │ ├── b-icon.svg │ ├── b-protocol-icon-risk.svg │ ├── b-protocol-small-logo.svg │ ├── bp-icon-gold.svg │ ├── bprotocol.svg │ ├── circle-x-icon.svg │ ├── close.svg │ ├── coin-icons │ │ ├── AAVE.svg │ │ ├── BAT.png │ │ ├── COMP.png │ │ ├── DAI.png │ │ ├── ETH.png │ │ ├── LINK.png │ │ ├── MKR.svg │ │ ├── SUSHI.svg │ │ ├── TUSD.png │ │ ├── UNI.png │ │ ├── USDC.png │ │ ├── USDT.png │ │ ├── WBTC legacy.png │ │ ├── WBTC.png │ │ ├── YFI.svg │ │ └── ZRX.png │ ├── com-icon-bl.svg │ ├── compound-full-logo.svg │ ├── compound-logo-a-1-risk.svg │ ├── compound-logo-black.svg │ ├── compound-logo.svg │ ├── connect-your-wallet.svg │ ├── dai.svg │ ├── discord.svg │ ├── dollar-icon.svg │ ├── etherium.svg │ ├── export-icon.svg │ ├── github.svg │ ├── hundred-logo.svg │ ├── i-icon-green.svg │ ├── i-icon.svg │ ├── images │ │ ├── borrow-repay.png │ │ ├── compound-import-popup.png │ │ ├── deposit-withdraw.png │ │ ├── maker-dau.png │ │ ├── maker-migration.png │ │ ├── mobile-support.png │ │ ├── modal-header.svg │ │ └── vote.svg │ ├── linkedin.svg │ ├── liquity-logo.svg │ ├── logo-maker-black.svg │ ├── logo-maker-green.svg │ ├── logo-maker-white-risk.svg │ ├── logo-maker-white.svg │ ├── maker-dao-background.svg │ ├── medium-icon.svg │ ├── red-x-icon.svg │ ├── t-compound-logo-a-1.svg │ ├── t-logo-maker-white.svg │ ├── triangle.svg │ ├── tvl-bg.svg │ ├── tvl-graph.svg │ ├── twitter-icon.svg │ ├── v-icon-white-thick.svg │ ├── v-icon-white.svg │ ├── v-icon.svg │ ├── view-icon-opeq-bg.svg │ ├── view-icon.svg │ └── x-icon.svg ├── common │ └── constants.js ├── components │ ├── AppAlert.js │ ├── AppError.js │ ├── BorrowLimit.js │ ├── ConnectButton.js │ ├── CurrencyBox.js │ ├── CurrencyBoxHeader.js │ ├── DaiBox.js │ ├── EtheriumBox.js │ ├── FAQContent.js │ ├── FragLoader.js │ ├── GlobalStats.js │ ├── GlobalStatsEmpty.js │ ├── Header.js │ ├── Header2.js │ ├── InstaInfo.js │ ├── LeaveUs.js │ ├── LiquidationPrice.js │ ├── LoadingRing.js │ ├── ModalContainer.js │ ├── Pulser.js │ ├── RiskContent.js │ ├── Sidebar.js │ ├── TermsOfUseContent.js │ ├── Ticker.js │ ├── Tooltip.js │ ├── Tvl.js │ ├── TvlTooltip.js │ ├── action-panels │ │ ├── Borrow.js │ │ ├── Deposit.js │ │ ├── Loading.js │ │ ├── MigrationButton.js │ │ ├── Repay.js │ │ └── Withdraw.js │ ├── compound-components │ │ ├── ActionBox.js │ │ ├── ActionBoxFooter.js │ │ ├── BalanceBox.js │ │ ├── BalanceListBox.js │ │ ├── BorrowLimit.js │ │ ├── ClaimComp.js │ │ ├── CoinList.js │ │ ├── CoinListBox.js │ │ ├── CoinListHeader.js │ │ ├── CoinListItem.js │ │ ├── HeaderBorrowLimit.js │ │ ├── ImportAllowanceToggle.js │ │ ├── MigrateFromCompound.js │ │ ├── MigrateFromCompoundModal.js │ │ ├── MigrationAssetList.js │ │ ├── ProgressBar.js │ │ ├── TxInProgress.js │ │ └── Unlock.js │ ├── modals │ │ ├── BproClaimModal.js │ │ ├── ClaimCompModal.js │ │ ├── GemModal.js │ │ ├── MigrationModal.js │ │ ├── TermsAndConditionContent.js │ │ ├── TermsAndConditionsModal.js │ │ └── WalletSelectionModal.js │ └── style-components │ │ ├── AnimateNumberChange.js │ │ ├── AnimateNumericalString.js │ │ ├── BpLoader.js │ │ ├── Buttons.js │ │ ├── GreyLine.js │ │ ├── HeaderProgressBar.js │ │ ├── ModalClaimHeader.js │ │ ├── NotificationsContainer.js │ │ ├── ProgressBar.js │ │ ├── ResponsiveContainer.js │ │ ├── Tabs.js │ │ └── Toggle.js ├── containers │ ├── Compound.js │ ├── Dashboard.js │ ├── FAQ.js │ ├── FarmInfo.js │ ├── Liquity.js │ ├── LiquityLegacy.js │ ├── Risk.js │ └── Terms.js ├── index.css ├── index.js ├── lib │ ├── Actions.js │ ├── ApiHelper.js │ ├── EventBus.js │ ├── ScoreInterface.js │ ├── Utils.js │ ├── bInterface.js │ ├── compound.interface.js │ ├── compound.util.js │ ├── compoundConfig │ │ ├── abi.js │ │ ├── compUserInfoAbi.js │ │ ├── compoundImportAbi.js │ │ ├── flashImportAbi.js │ │ ├── initialState.js │ │ ├── kovanAddress.js │ │ ├── mainnetAddress.js │ │ ├── readme.md │ │ └── registryAbi.js │ ├── insta.interface.js │ ├── instaConfig │ │ ├── abi.js │ │ └── mainnetAddress.js │ ├── liquity.interface.js │ └── liquityConfig │ │ ├── abi.js │ │ └── mainnetAddress.js ├── screenSizes.js ├── scss │ ├── _animations.scss │ ├── _app.scss │ ├── _buttons.scss │ ├── _colors.scss │ ├── _currency.scss │ ├── _fonts.scss │ ├── _hamburger.scss │ ├── _layout.scss │ ├── _migrate.scss │ ├── _modal.scss │ ├── _reset.scss │ ├── _sidebar.scss │ ├── _tooltip.scss │ └── _utils.scss ├── serviceWorker.js ├── setupTests.js ├── stores │ ├── apy.store.js │ ├── bpro.store.js │ ├── compound.store.js │ ├── compoundMigration.store.js │ ├── insta.store.js │ ├── main.comp.store.js │ ├── main.hundred.store.js │ ├── main.liquity.store.js │ ├── main.store.js │ ├── maker.store.js │ ├── router.store.js │ └── user.store.js ├── style.scss └── wallets │ └── Wallets.js ├── test ├── package-lock.json ├── package.json ├── test-kovan.sh ├── test │ ├── compound.test.js │ ├── test.js │ └── testWbtc.js └── truffle-config.js ├── tests └── e2e │ ├── .eslintrc.js │ ├── specs │ ├── compound-import-spec.js │ ├── compound-spec.js │ ├── maker-gem-spec.js │ ├── maker-import-spec.js │ ├── maker-spec.js │ └── website-spec.js │ ├── test-utils.js │ └── tsconfig.json ├── workers-site ├── .cargo-ok ├── .gitignore ├── index.js ├── package-lock.json └── package.json └── yarn.lock /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "browser": true 4 | }, 5 | "extends": [ 6 | "eslint:recommended", 7 | "plugin:react/recommended" 8 | ], 9 | "parserOptions": { 10 | "ecmaFeatures": { 11 | "jsx": true 12 | }, 13 | "ecmaVersion": 12, 14 | "sourceType": "module" 15 | }, 16 | "plugins": [ 17 | "react" 18 | ], 19 | "rules": { 20 | "indent": [ 21 | "error", 22 | "tab" 23 | ], 24 | "linebreak-style": [ 25 | "error", 26 | "unix" 27 | ], 28 | "quotes": [ 29 | "error", 30 | "double" 31 | ], 32 | "semi": [ 33 | "error", 34 | "never" 35 | ] 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | /dist 14 | 15 | # misc 16 | .DS_Store 17 | .env.local 18 | .env.development.local 19 | .env.test.local 20 | .env.production.local 21 | 22 | npm-debug.log* 23 | yarn-debug.log* 24 | yarn-error.log* 25 | pacakge-lock.json 26 | API.json 27 | 28 | # test 29 | /test/node_modules 30 | /test/pacakge-lock.json 31 | /test/run-tests.bash 32 | test/ganache-kovan.sh 33 | .vscode/launch.json 34 | 35 | # CF worker site 36 | #=========================== 37 | wrangler.toml 38 | 39 | # E2E tests 40 | #=========================== 41 | .env 42 | tests/e2e/videos 43 | tests/e2e/screenshots 44 | tests/snapshot-id.txt -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | *.json 2 | *.md 3 | *html -------------------------------------------------------------------------------- /.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "trailingComma": "none", 3 | "printWidth": 100, 4 | "semi": false, 5 | "singleQuote": false, 6 | "jsxSingleQuote": false, 7 | "bracketSpacing": true, 8 | "jsxBracketSameLine": true, 9 | "requirePragma": true 10 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app). 2 | 3 | ## Available Scripts 4 | 5 | In the project directory, you can run: 6 | 7 | ### `yarn start` 8 | 9 | Runs the app in the development mode.
10 | Open [http://localhost:3000](http://localhost:3000) to view it in the browser. 11 | 12 | The page will reload if you make edits.
13 | You will also see any lint errors in the console. 14 | 15 | ### `yarn test` 16 | 17 | Launches the test runner in the interactive watch mode.
18 | See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information. 19 | 20 | ### `yarn build` 21 | 22 | Builds the app for production to the `build` folder.
23 | It correctly bundles React in production mode and optimizes the build for the best performance. 24 | 25 | The build is minified and the filenames include the hashes.
26 | Your app is ready to be deployed! 27 | 28 | See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information. 29 | 30 | ### `yarn eject` 31 | 32 | **Note: this is a one-way operation. Once you `eject`, you can’t go back!** 33 | 34 | If you aren’t satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project. 35 | 36 | Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you’re on your own. 37 | 38 | You don’t have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it. 39 | 40 | ## Learn More 41 | 42 | You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started). 43 | 44 | To learn React, check out the [React documentation](https://reactjs.org/). 45 | 46 | ### Code Splitting 47 | 48 | This section has moved here: https://facebook.github.io/create-react-app/docs/code-splitting 49 | 50 | ### Analyzing the Bundle Size 51 | 52 | This section has moved here: https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size 53 | 54 | ### Making a Progressive Web App 55 | 56 | This section has moved here: https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app 57 | 58 | ### Advanced Configuration 59 | 60 | This section has moved here: https://facebook.github.io/create-react-app/docs/advanced-configuration 61 | 62 | ### Deployment 63 | 64 | This section has moved here: https://facebook.github.io/create-react-app/docs/deployment 65 | 66 | ### `yarn build` fails to minify 67 | 68 | This section has moved here: https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify 69 | -------------------------------------------------------------------------------- /generate-farm-info.sh: -------------------------------------------------------------------------------- 1 | rsync -avr --exclude='farm-info' build/ build/farm-info -------------------------------------------------------------------------------- /generate-static.sh: -------------------------------------------------------------------------------- 1 | cd build 2 | mkdir app && cp index.html app 3 | mkdir maker && cp index.html maker 4 | mkdir compound && cp index.html compound 5 | mkdir liquity && cp index.html liquity 6 | mkdir faq && cp index.html faq 7 | mkdir risk && cp index.html risk 8 | mkdir terms && cp index.html terms 9 | mkdir farm-info && cp index.html farm-info -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bprotocol-react-client", 3 | "version": "1.0.27", 4 | "private": true, 5 | "dependencies": { 6 | "@cloudflare/kv-asset-handler": "^0.1.0", 7 | "@metamask/detect-provider": "^1.2.0", 8 | "@testing-library/jest-dom": "^4.2.4", 9 | "@testing-library/react": "^9.3.2", 10 | "@testing-library/user-event": "^7.1.2", 11 | "@walletconnect/web3-provider": "1.6.6", 12 | "axios": "^0.21.0", 13 | "detect-browser": "^5.1.1", 14 | "esm": "^3.2.25", 15 | "mobx": "^6.0.4", 16 | "mobx-react": "^7.0.5", 17 | "moment": "^2.29.1", 18 | "qs": "^6.9.4", 19 | "react": "^16.13.1", 20 | "react-device-detect": "^1.17.0", 21 | "react-dom": "^16.13.1", 22 | "react-router-dom": "^5.2.0", 23 | "react-scripts": "3.4.3", 24 | "react-spring": "^8.0.27", 25 | "react-tooltip": "^4.2.11", 26 | "styled-components": "^5.2.1", 27 | "styled-flex-component": "^3.0.5", 28 | "web3": "^1.4.0" 29 | }, 30 | "scripts": { 31 | "dev": "react-scripts start", 32 | "start": "react-scripts start", 33 | "build": "npm version patch && react-scripts build && ./generate-static.sh && node ./scripts/remove-iframe-deny.js", 34 | "build:farm-info": "npm version patch && PUBLIC_URL=/farm-info react-scripts build && ./generate-farm-info.sh && node ./scripts/remove-iframe-deny.js", 35 | "test": "react-scripts test", 36 | "test:e2e": "SECRET_WORDS=$(grep SECRET_WORDS .env | cut -d '=' -f2) NETWORK_NAME=localhost synpress run", 37 | "hardhat:proxy": "http-server --proxy $(grep RPC_URL .env | cut -d '=' -f2) --port 8545", 38 | "test:integration": "(touch tests/snapshot-id.txt & npm run hardhat:proxy & npm start & npm run test:e2e)", 39 | "eject": "react-scripts eject", 40 | "lint": "eslint ./src", 41 | "check": "prettier --check ./src", 42 | "format": "prettier --write ./src ./test" 43 | }, 44 | "eslintConfig": { 45 | "extends": "react-app" 46 | }, 47 | "browserslist": { 48 | "production": [ 49 | ">0.2%", 50 | "not dead", 51 | "not op_mini all" 52 | ], 53 | "development": [ 54 | "last 1 chrome version", 55 | "last 1 firefox version", 56 | "last 1 safari version" 57 | ] 58 | }, 59 | "devDependencies": { 60 | "@synthetixio/synpress": "https://github.com/backstop-protocol/synpress.git#4d45c96e1e8ef67a2d8c5016ec4b2d4a80557b74", 61 | "eslint": "^6.6.0", 62 | "eslint-plugin-react": "^7.22.0", 63 | "http-server": "^13.0.0", 64 | "node-sass": "^4.14.1", 65 | "prettier": "^2.2.1", 66 | "sass-loader": "^10.0.1" 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- 1 | F40D6CE7-4B76-44BF-B583-679B75EAE8C5Created with sketchtool. -------------------------------------------------------------------------------- /public/favicon.svg: -------------------------------------------------------------------------------- 1 | F40D6CE7-4B76-44BF-B583-679B75EAE8C5Created with sketchtool. -------------------------------------------------------------------------------- /public/fonts/NeueHaasGroteskDisp Pro Md.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backstop-protocol/react-client/2be166fdc7ca9ddd46369be0c67b49dd6e0973f1/public/fonts/NeueHaasGroteskDisp Pro Md.eot -------------------------------------------------------------------------------- /public/fonts/NeueHaasGroteskDisp Pro Md.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backstop-protocol/react-client/2be166fdc7ca9ddd46369be0c67b49dd6e0973f1/public/fonts/NeueHaasGroteskDisp Pro Md.ttf -------------------------------------------------------------------------------- /public/fonts/NeueHaasGroteskDisp Pro Md.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backstop-protocol/react-client/2be166fdc7ca9ddd46369be0c67b49dd6e0973f1/public/fonts/NeueHaasGroteskDisp Pro Md.woff -------------------------------------------------------------------------------- /public/fonts/NeueHaasGroteskDisp Pro Md.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backstop-protocol/react-client/2be166fdc7ca9ddd46369be0c67b49dd6e0973f1/public/fonts/NeueHaasGroteskDisp Pro Md.woff2 -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 18 | 19 | 20 | 24 | 25 | 29 | 30 | 39 | B.Protocol 40 | 41 | 42 | 43 |
44 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "b-icon.svg", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | } 10 | ], 11 | "start_url": ".", 12 | "display": "standalone", 13 | "theme_color": "#000000", 14 | "background_color": "#ffffff" 15 | } 16 | -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /scripts/remove-iframe-deny.js: -------------------------------------------------------------------------------- 1 | const { execSync } = require("child_process"); 2 | const { existsSync, readFileSync, writeFileSync } = require("fs"); 3 | 4 | const workerFile = "workers-site/index.js" 5 | 6 | const workerScript = readFileSync(workerFile, { encoding: "ascii" }) 7 | .replace(`response.headers.set("X-Frame-Options", "DENY");`, ""); 8 | 9 | writeFileSync(workerFile, workerScript); -------------------------------------------------------------------------------- /src/App.js: -------------------------------------------------------------------------------- 1 | import React, {Suspense} from "react"; 2 | import "./style.scss"; 3 | import { BrowserRouter as Router, Route, Redirect } from "react-router-dom"; 4 | import AppError from "./components/AppError"; 5 | import NotificationsContainer from "./components/style-components/NotificationsContainer"; 6 | import AppAlert from "./components/AppAlert"; 7 | import ModalContainer from "./components/ModalContainer" 8 | import Sidebar from "./components/Sidebar" 9 | import {observer} from "mobx-react" 10 | import routerStore from "./stores/router.store" 11 | import { createBrowserHistory } from "history"; 12 | import styled from "styled-components" 13 | import * as qs from "qs"; 14 | 15 | const browserHistory = createBrowserHistory(); 16 | routerStore.setRouteProps(browserHistory) 17 | 18 | 19 | const Dashboard = React.lazy(() => import("./containers/Dashboard")); 20 | const Compound = React.lazy(() => import("./containers/Compound")); 21 | const Liquity = React.lazy(() => import("./containers/Liquity")); 22 | const LiquityLegacy = React.lazy(() => import("./containers/LiquityLegacy")); 23 | const Risk = React.lazy(() => import("./containers/Risk")); 24 | const TermsOfUse = React.lazy(() => import("./containers/Terms")); 25 | const FAQ = React.lazy(() => import("./containers/FAQ")); 26 | const FarmInfo = React.lazy(() => import("./containers/FarmInfo")); 27 | 28 | function renderPage (props, PageComponent) { 29 | return ( 30 | }> 31 | 32 | 33 | ) 34 | } 35 | 36 | const App = observer(() => { 37 | const { history } = routerStore.routeProps; 38 | const {search, pathname} = history.location 39 | const params = qs.parse(search, { ignoreQueryPrefix: true }) 40 | return ( 41 |
42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | {/* Default route */} 50 | 51 | 52 | 53 | (renderPage(props, Dashboard))} /> 54 | (renderPage(props, Dashboard))} /> 55 | (renderPage(props, Compound))} /> 56 | (renderPage(props, Liquity))} /> 57 | (renderPage(props, LiquityLegacy))} /> 58 | (renderPage(props, FAQ))} /> 59 | (renderPage(props, TermsOfUse))} /> 60 | (renderPage(props, Risk))} /> 61 | (renderPage(props, FarmInfo))} /> 62 | 63 |
64 | ); 65 | }) 66 | 67 | export default App; 68 | -------------------------------------------------------------------------------- /src/App.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { render } from '@testing-library/react'; 3 | import App from './App'; 4 | 5 | test('Has "B.Protocol" in the page text', () => { 6 | const { getByText } = render(); 7 | const linkElement = getByText(/B.Protocol/i); 8 | expect(linkElement).toBeInTheDocument(); 9 | }); 10 | -------------------------------------------------------------------------------- /src/assets/aav-ewhite-logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/assets/b-icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/assets/bp-icon-gold.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /src/assets/circle-x-icon.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 | -------------------------------------------------------------------------------- /src/assets/close.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 | -------------------------------------------------------------------------------- /src/assets/coin-icons/AAVE.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/assets/coin-icons/BAT.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backstop-protocol/react-client/2be166fdc7ca9ddd46369be0c67b49dd6e0973f1/src/assets/coin-icons/BAT.png -------------------------------------------------------------------------------- /src/assets/coin-icons/COMP.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backstop-protocol/react-client/2be166fdc7ca9ddd46369be0c67b49dd6e0973f1/src/assets/coin-icons/COMP.png -------------------------------------------------------------------------------- /src/assets/coin-icons/DAI.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backstop-protocol/react-client/2be166fdc7ca9ddd46369be0c67b49dd6e0973f1/src/assets/coin-icons/DAI.png -------------------------------------------------------------------------------- /src/assets/coin-icons/ETH.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backstop-protocol/react-client/2be166fdc7ca9ddd46369be0c67b49dd6e0973f1/src/assets/coin-icons/ETH.png -------------------------------------------------------------------------------- /src/assets/coin-icons/LINK.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backstop-protocol/react-client/2be166fdc7ca9ddd46369be0c67b49dd6e0973f1/src/assets/coin-icons/LINK.png -------------------------------------------------------------------------------- /src/assets/coin-icons/MKR.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/assets/coin-icons/SUSHI.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 | -------------------------------------------------------------------------------- /src/assets/coin-icons/TUSD.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backstop-protocol/react-client/2be166fdc7ca9ddd46369be0c67b49dd6e0973f1/src/assets/coin-icons/TUSD.png -------------------------------------------------------------------------------- /src/assets/coin-icons/UNI.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backstop-protocol/react-client/2be166fdc7ca9ddd46369be0c67b49dd6e0973f1/src/assets/coin-icons/UNI.png -------------------------------------------------------------------------------- /src/assets/coin-icons/USDC.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backstop-protocol/react-client/2be166fdc7ca9ddd46369be0c67b49dd6e0973f1/src/assets/coin-icons/USDC.png -------------------------------------------------------------------------------- /src/assets/coin-icons/USDT.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backstop-protocol/react-client/2be166fdc7ca9ddd46369be0c67b49dd6e0973f1/src/assets/coin-icons/USDT.png -------------------------------------------------------------------------------- /src/assets/coin-icons/WBTC legacy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backstop-protocol/react-client/2be166fdc7ca9ddd46369be0c67b49dd6e0973f1/src/assets/coin-icons/WBTC legacy.png -------------------------------------------------------------------------------- /src/assets/coin-icons/WBTC.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backstop-protocol/react-client/2be166fdc7ca9ddd46369be0c67b49dd6e0973f1/src/assets/coin-icons/WBTC.png -------------------------------------------------------------------------------- /src/assets/coin-icons/YFI.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/assets/coin-icons/ZRX.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backstop-protocol/react-client/2be166fdc7ca9ddd46369be0c67b49dd6e0973f1/src/assets/coin-icons/ZRX.png -------------------------------------------------------------------------------- /src/assets/com-icon-bl.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/assets/compound-full-logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/assets/compound-logo-a-1-risk.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/assets/compound-logo-black.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/assets/compound-logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/assets/connect-your-wallet.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/assets/dai.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /src/assets/discord.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /src/assets/dollar-icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /src/assets/etherium.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /src/assets/export-icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/assets/github.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/assets/i-icon-green.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/assets/i-icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/assets/images/borrow-repay.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backstop-protocol/react-client/2be166fdc7ca9ddd46369be0c67b49dd6e0973f1/src/assets/images/borrow-repay.png -------------------------------------------------------------------------------- /src/assets/images/compound-import-popup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backstop-protocol/react-client/2be166fdc7ca9ddd46369be0c67b49dd6e0973f1/src/assets/images/compound-import-popup.png -------------------------------------------------------------------------------- /src/assets/images/deposit-withdraw.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backstop-protocol/react-client/2be166fdc7ca9ddd46369be0c67b49dd6e0973f1/src/assets/images/deposit-withdraw.png -------------------------------------------------------------------------------- /src/assets/images/maker-dau.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backstop-protocol/react-client/2be166fdc7ca9ddd46369be0c67b49dd6e0973f1/src/assets/images/maker-dau.png -------------------------------------------------------------------------------- /src/assets/images/maker-migration.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backstop-protocol/react-client/2be166fdc7ca9ddd46369be0c67b49dd6e0973f1/src/assets/images/maker-migration.png -------------------------------------------------------------------------------- /src/assets/images/mobile-support.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/backstop-protocol/react-client/2be166fdc7ca9ddd46369be0c67b49dd6e0973f1/src/assets/images/mobile-support.png -------------------------------------------------------------------------------- /src/assets/images/vote.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/assets/linkedin.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/assets/liquity-logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/assets/logo-maker-black.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/assets/logo-maker-green.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/assets/logo-maker-white-risk.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/assets/logo-maker-white.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/assets/maker-dao-background.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 | -------------------------------------------------------------------------------- /src/assets/medium-icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/assets/red-x-icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/assets/t-compound-logo-a-1.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/assets/t-logo-maker-white.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/assets/triangle.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/assets/tvl-bg.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /src/assets/tvl-graph.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /src/assets/twitter-icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/assets/v-icon-white-thick.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/assets/v-icon-white.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/assets/v-icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/assets/view-icon-opeq-bg.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/assets/view-icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/assets/x-icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/common/constants.js: -------------------------------------------------------------------------------- 1 | export const BP_API = "https://eth-node.b-protocol.workers.dev" 2 | export const KOVAN_BP_API = "https://kovan-node.b-protocol.workers.dev" -------------------------------------------------------------------------------- /src/components/AppAlert.js: -------------------------------------------------------------------------------- 1 | import React, {Component} from "react"; 2 | import {numm} from "../lib/Utils"; 3 | import EventBus from "../lib/EventBus"; 4 | import styled from "styled-components" 5 | import { setTimeout } from "timers"; 6 | import LoadingRing from "./LoadingRing"; 7 | 8 | const Alert = styled.div` 9 | display: flex; 10 | color: #bf8517; 11 | background-color: white; 12 | background-image: linear-gradient(rgba(251, 201, 89, 0.3), rgba(251, 201, 89, 0.3)); 13 | font-size: 12px; 14 | justify-content: center; 15 | align-items: center; 16 | height: 27px; 17 | ` 18 | 19 | const AlertActionBtn = styled.div` 20 | min-width: 80px; 21 | margin-left: 15px; 22 | padding: 0 6px; 23 | color: #bf8517; 24 | text-align: center; 25 | background-color: rgba(0, 0, 0, 0); 26 | border: 1px solid rgb(251, 201, 89); 27 | border-radius: 6px; 28 | :hover { 29 | cursor: pointer; 30 | opacity: 0.8; 31 | } 32 | ` 33 | 34 | const Overides = styled.div` 35 | min-width: 80px; 36 | margin-left: 15px; 37 | padding: 0 30px; 38 | transform: scale(0.7); 39 | .lds-ring div { 40 | border-color: #bf8517 transparent transparent transparent; 41 | } 42 | ` 43 | 44 | export default class AppAlert extends Component { 45 | 46 | constructor(props) { 47 | super(props); 48 | 49 | this.state = { 50 | alert: false, 51 | alertMessage: "", 52 | actionBtn: null, 53 | actionFn: null, 54 | waiting: null 55 | } 56 | } 57 | 58 | componentDidMount() { 59 | EventBus.$on('app-alert',(msg, actionBtn, actionFn) => { 60 | this.setState({alert: !!msg, alertMessage: msg, actionBtn, actionFn}); 61 | }); 62 | } 63 | 64 | async callActionFn(fn){ 65 | 66 | try{ 67 | this.setState({waiting: true}) 68 | await Promise.all([fn(), new Promise((resolve, reject)=> {setTimeout(resolve, 3000)})]) 69 | } catch (err){ 70 | console.error(err) 71 | } finally { 72 | this.setState({waiting: false}) 73 | } 74 | } 75 | 76 | render() { 77 | 78 | const {alert, alertMessage, actionBtn, actionFn, waiting} = this.state; 79 | 80 | return ( 81 |
82 | {alert && 83 | 84 | {alertMessage} 85 | {actionBtn && 86 |
87 | {!waiting && this.callActionFn(actionFn)}> {actionBtn} } 88 | {waiting && } 89 |
90 | } 91 |
92 | } 93 |
94 | ) 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /src/components/AppError.js: -------------------------------------------------------------------------------- 1 | import React, {Component} from "react"; 2 | import {numm} from "../lib/Utils"; 3 | import EventBus from "../lib/EventBus"; 4 | 5 | export default class AppError extends Component { 6 | 7 | constructor(props) { 8 | super(props); 9 | 10 | this.state = { 11 | error: false, 12 | errorMessage : "" 13 | } 14 | } 15 | 16 | componentDidMount() { 17 | EventBus.$on('app-error',(err) => { 18 | this.setState({error: true, errorMessage: err || "An error has occured"}); 19 | console.error(err) 20 | setTimeout(() => { 21 | this.setState({error: false}); 22 | }, 3000) 23 | }); 24 | 25 | } 26 | 27 | render() { 28 | 29 | const {error} = this.state; 30 | 31 | return ( 32 |
33 | {error &&
{this.state.errorMessage}
} 34 |
35 | ) 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/components/BorrowLimit.js: -------------------------------------------------------------------------------- 1 | import React, {Component} from "react"; 2 | import {numm} from "../lib/Utils"; 3 | import Flex, {FlexItem} from "styled-flex-component"; 4 | import LiquidationPrice from './LiquidationPrice' 5 | import styled from "styled-components" 6 | import {device} from "../screenSizes"; 7 | 8 | const Container = styled.div` 9 | width: 567px; 10 | display: flex; 11 | @media ${device.largeLaptop} { 12 | width: 414px; 13 | } 14 | ` 15 | 16 | export default class BorrowLimit extends Component { 17 | 18 | render() { 19 | 20 | const {userInfo} = this.props; 21 | const collateralToBorrowRatio = (userInfo && userInfo.bCdpInfo.maxDaiDebt?numm(userInfo.bCdpInfo.daiDebt / userInfo.bCdpInfo.maxDaiDebt * 100):0) 22 | const ratioPositionStyle = collateralToBorrowRatio > 50 ? {right: '0%'} : {left: '100%'} 23 | return ( 24 | 25 | 26 |
27 |

Borrow Limit

28 |
29 |
30 | {collateralToBorrowRatio}% 31 |
32 |
33 | 34 | 35 | 36 | 37 |
38 |
39 | 40 | 41 | 42 |
43 | ) 44 | } 45 | } -------------------------------------------------------------------------------- /src/components/ConnectButton.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @format 3 | */ 4 | import React, { Component } from "react"; 5 | import EventBus from '../lib/EventBus'; 6 | import {Link} from "react-router-dom"; 7 | import {observer} from "mobx-react" 8 | import userStore from "../stores/user.store" 9 | 10 | function increaseABit(number) { 11 | return parseInt(1.1 * Number(number)); 12 | } 13 | 14 | class ConnectButton extends Component { 15 | constructor(props) { 16 | super(props); 17 | } 18 | 19 | render() { 20 | const { loggedIn, user, connecting } = userStore 21 | if(connecting) { 22 | return null 23 | } 24 | return ( 25 |
26 | { loggedIn ? ( 27 |
28 |
29 | {user} 30 |
31 |
32 | ) : ( 33 |
34 |
35 | 36 | By using bprotocol, you agree to the{" "} 37 | 46 | Terms and Conditions 47 | 48 | 49 |
50 | 51 |
55 | Connect 56 |
57 |
58 | )} 59 |
60 | ); 61 | } 62 | } 63 | 64 | export default observer(ConnectButton) 65 | -------------------------------------------------------------------------------- /src/components/CurrencyBoxHeader.js: -------------------------------------------------------------------------------- 1 | import React, {Component} from "react"; 2 | import {observer} from "mobx-react" 3 | import styled from "styled-components" 4 | import Flex, {FlexItem} from "styled-flex-component"; 5 | import {device} from "../screenSizes"; 6 | 7 | const Container = styled.div` 8 | font-family: "NeueHaasGroteskDisp Pro Md", sans-serif; 9 | height: 40px; 10 | width: 100%; 11 | opacity: 0.28; 12 | font-size: 12px; 13 | letter-spacing: 0.6px; 14 | color: #0b0412; 15 | line-height: 1.5; 16 | padding: 0 20px; 17 | border-bottom: 1px solid rgba(151, 151, 151, 0.25); 18 | width: 100%; 19 | .asset{ 20 | width: calc(46px + 20px + 85px + 20px); 21 | } 22 | .fee{ 23 | width: 70px; 24 | margin-right: 20px; 25 | } 26 | 27 | @media ${device.largeLaptop} { 28 | font-size: 11px; 29 | .asset{ 30 | width: calc(46px + 20px + 77px + 20px); 31 | } 32 | } 33 | @media ${device.laptop} { 34 | font-size: 11px; 35 | .asset{ 36 | width: calc(40px + 7.5px + 73px + 7.5px); 37 | } 38 | .fee{ 39 | margin-right: 7.5px; 40 | } 41 | } 42 | @media ${device.mobile} { 43 | .asset{ 44 | width: calc(40px + 7.5px + 30px + 7.5px); 45 | } 46 | } 47 | ` 48 | 49 | class CurrencyBoxHeader extends Component { 50 | 51 | render () { 52 | const {showStabilityFee} = this.props 53 | return ( 54 | 55 | 56 | 57 | Asset 58 | 59 | 60 | {showStabilityFee && Stability fee} 61 | 62 | 63 | Balance 64 | 65 | 66 | 67 | ) 68 | } 69 | } 70 | 71 | export default observer(CurrencyBoxHeader) -------------------------------------------------------------------------------- /src/components/DaiBox.js: -------------------------------------------------------------------------------- 1 | import React, {Component} from "react"; 2 | import {numm} from "../lib/Utils"; 3 | import Dai from "../assets/dai.svg"; 4 | import CurrencyBox from "./CurrencyBox"; 5 | import Repay from "./action-panels/Repay"; 6 | import Borrow from "./action-panels/Borrow"; 7 | import {observer} from "mobx-react" 8 | import userStore from "../stores/user.store" 9 | 10 | class DaiBox extends Component { 11 | 12 | formatValue(userInfo) { return userInfo?numm(userInfo.bCdpInfo.daiDebt, 2):0; } 13 | calculateUSD(userInfo) { return userInfo?numm(userInfo.bCdpInfo.daiDebt, 2):0; } 14 | borrowLimit(userInfo, value, value2) { return userInfo?numm((userInfo.bCdpInfo.daiDebt+value2) / userInfo.bCdpInfo.maxDaiDebt*100, 2, 100) : 0 } 15 | 16 | render() { 17 | const {userInfo, onPanelAction, stabilityFee} = this.props; 18 | const {showConnect} = userStore 19 | 20 | return ( 21 | 24 | ) 25 | } 26 | } 27 | 28 | export default observer(DaiBox) 29 | -------------------------------------------------------------------------------- /src/components/EtheriumBox.js: -------------------------------------------------------------------------------- 1 | import React, {Component} from "react"; 2 | import {numm, symbolToDisplayDecimalPointMap as symbol2decimal} from "../lib/Utils"; 3 | import CurrencyBox from "./CurrencyBox"; 4 | import Etherium from "../assets/etherium.svg"; 5 | import Deposit from "./action-panels/Deposit"; 6 | import Withdraw from "./action-panels/Withdraw"; 7 | import {observer} from "mobx-react" 8 | import userStore from "../stores/user.store" 9 | import Web3 from "web3" 10 | const {fromWei, toWei} = Web3.utils 11 | 12 | class EtheriumBox extends Component { 13 | 14 | formatValue = (userInfo) => { 15 | if(!userInfo){ 16 | return 0 17 | } 18 | return numm(userInfo.collaeralDeposited, symbol2decimal[this.props.symbol]); 19 | } 20 | 21 | calculateUSD = (userInfo) => { 22 | if(!userInfo){ 23 | return 0 24 | } 25 | return numm(userInfo.collaeralDeposited * userInfo.miscInfo.spotPrice, symbol2decimal['USD']) 26 | } 27 | 28 | borrowLimit (userInfo, value) { 29 | return userInfo?numm(userInfo.bCdpInfo.daiDebt / value * 100, 2, 100) : 0 30 | } 31 | 32 | render() { 33 | 34 | const {userInfo, onPanelAction, onOpenPanel, symbol} = this.props; 35 | const {showConnect} = userStore 36 | 37 | return ( 38 | 41 | ) 42 | } 43 | } 44 | 45 | export default observer(EtheriumBox) -------------------------------------------------------------------------------- /src/components/FragLoader.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | export default function FragLoader() { 4 | return ( 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | ) 13 | } 14 | -------------------------------------------------------------------------------- /src/components/GlobalStatsEmpty.js: -------------------------------------------------------------------------------- 1 | import React, {Component} from "react"; 2 | import DollarIcon from "../assets/bp-icon-gold.svg"; 3 | import Pulser from "./Pulser"; 4 | import {Observer} from "mobx-react" 5 | 6 | 7 | export default class GlobalStats extends Component { 8 | 9 | constructor(props) { 10 | super(props); 11 | } 12 | 13 | render() { 14 | return ( 15 | 16 | {() => 17 |
18 |
19 |
20 | 21 | 22 |
23 |
24 |
25 |
26 |
27 | } 28 |
29 | ) 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/components/Header.js: -------------------------------------------------------------------------------- 1 | import React, {Component} from "react"; 2 | import {numm} from "../lib/Utils"; 3 | import ConnectButton from "./ConnectButton"; 4 | import GlobalStatsEmpty from "./GlobalStatsEmpty"; 5 | import BorrowLimit from "./BorrowLimit"; 6 | import Tvl from "./Tvl"; 7 | import ConnectWallet from "../assets/connect-your-wallet.svg"; 8 | import userStore from "../stores/user.store" 9 | import {observer} from "mobx-react" 10 | import mainStore from "../stores/main.store" 11 | import mainCompStore from "../stores/main.comp.store" 12 | import Tabs from "./style-components/Tabs" 13 | import makerStoreManager, {makerStoreNames} from "../stores/maker.store" 14 | import {ResponsiveWidthHeader, HeaderItemContainer} from "./style-components/ResponsiveContainer" 15 | 16 | class Header extends Component { 17 | render() { 18 | const {info, onConnect, logo} = this.props; 19 | return ( 20 |
21 | 22 |
23 | 24 |
25 | 26 | {(userStore.displayConnect || false)&&
27 | 28 |

Connect your wallet

29 | 30 |
} 31 |
32 |
33 |
34 | 35 | 36 | 37 | 38 | {info && 39 | 40 | } 41 | {!info && 42 | 43 | } 44 | 45 |
46 |
47 |
48 | 49 |
50 |
51 | ) 52 | } 53 | } 54 | 55 | export default observer(Header) 56 | -------------------------------------------------------------------------------- /src/components/Header2.js: -------------------------------------------------------------------------------- 1 | import React, {Component} from "react"; 2 | import {numm} from "../lib/Utils"; 3 | import ConnectButton from "./ConnectButton"; 4 | import GlobalStatsEmpty from "./GlobalStatsEmpty"; 5 | import BorrowLimit from "./BorrowLimit"; 6 | import Tvl from "./Tvl"; 7 | import ConnectWallet from "../assets/connect-your-wallet.svg"; 8 | import userStore from "../stores/user.store" 9 | import {observer} from "mobx-react" 10 | import HeaderBorrowLimit from "../components/compound-components/HeaderBorrowLimit" 11 | import {ResponsiveWidthHeader, HeaderItemContainer} from "./style-components/ResponsiveContainer" 12 | import mainStore from "../stores/main.store" 13 | import mainCompStore from "../stores/main.comp.store" 14 | import {Transition} from 'react-spring/renderprops' 15 | 16 | class Header2 extends Component { 17 | render() { 18 | 19 | const {info, onConnect, logo, fullPage, textLogo} = this.props; 20 | const {loggedIn} = userStore 21 | return ( 22 |
23 | 24 |
25 | {logo && } 26 | {textLogo &&

{textLogo}

} 27 |
28 | 29 | {(userStore.displayConnect || false)&&
30 | 31 |

Connect your wallet

32 | 33 |
} 34 |
35 |
36 |
37 | 38 | 39 | 40 | {!fullPage && 41 | 47 | {toggle => 48 | toggle 49 | ? props =>
50 | : props =>
51 | } 52 |
53 |
} 54 |
55 |
56 |
57 | ) 58 | } 59 | } 60 | 61 | export default observer(Header2) 62 | -------------------------------------------------------------------------------- /src/components/InstaInfo.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from "react"; 2 | import styled from "styled-components" 3 | import { TableContainer, ContentBox, Cell, ANS, Button, Title} from "../containers/FarmInfo" 4 | import Flex, {FlexItem} from "styled-flex-component" 5 | 6 | export default class InstaInfo extends Component { 7 | 8 | render() { 9 | const {bproStore, account} = this.props 10 | return ( 11 |
12 | 13 | Instadapp account 14 | 15 | 16 | {account} 17 | 18 | 19 | 20 | 21 | uBPRO-BIP4 22 | BPRO
{"(If TVL < $150m)"}
23 | BPRO
{"(If TVL > $150m)"}
24 |
25 | {/* 26 | User Reward 27 | /month 28 | /month 29 | /month 30 | */} 31 | 32 | Accumulated 33 | 34 | 35 | 36 | 37 | 38 | 39 | Claimable 40 | 41 | 42 | 43 | 44 | 45 | 46 | Wallet Balance 47 | 48 | 49 | 50 | 51 | 52 | 57 | 58 |
59 |
60 | ) 61 | } 62 | } -------------------------------------------------------------------------------- /src/components/LoadingRing.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | export default function LoadingRing() { 4 | return ( 5 |
6 | ) 7 | } 8 | -------------------------------------------------------------------------------- /src/components/ModalContainer.js: -------------------------------------------------------------------------------- 1 | import React, {Component} from "react"; 2 | import XIcon from "../assets/x-icon.svg"; 3 | import EventBus from "../lib/EventBus"; 4 | 5 | export default class ModalContainer extends Component { 6 | 7 | constructor(props) { 8 | super(props); 9 | 10 | this.state = { 11 | component : null, 12 | noWrapper : null, 13 | show: false 14 | } 15 | } 16 | 17 | componentDidMount() { 18 | EventBus.$on('show-modal', this.showModalBox.bind(this)); 19 | EventBus.$on('close-modal', this.closeModalBox.bind(this)); 20 | } 21 | 22 | showModalBox(component, noWrapper) { 23 | document.body.style.overflow = "hidden"; // ADD THIS LINE 24 | this.setState({component, noWrapper, show: true}); 25 | } 26 | 27 | closeModalBox = () => { 28 | this.setState({component:
, show: false}); 29 | document.body.style.overflow = "auto"; // ADD THIS LINE 30 | }; 31 | 32 | render() { 33 | const {component, noWrapper, show} = this.state; 34 | const cls = show ? 'modal-container active' : 'modal-container'; 35 | 36 | return ( 37 |
noWrapper ? EventBus.$emit('close-modal') : ""}> 38 | {this.state.component && !noWrapper && 39 |
40 |
EventBus.$emit('close-modal')}> 41 | 42 |
43 | {component} 44 |
45 | } 46 | {this.state.component && noWrapper && 47 |
e.stopPropagation()}> 48 | {component} 49 |
50 | } 51 |
52 | ) 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/components/Ticker.js: -------------------------------------------------------------------------------- 1 | import React, {Component} from "react"; 2 | import {observer} from "mobx-react" 3 | 4 | class Ticker extends Component { 5 | 6 | constructor(props) { 7 | super(props); 8 | 9 | this.state = { 10 | value : props.value, 11 | changes : [], 12 | } 13 | } 14 | 15 | componentDidUpdate(prevProps, prevState) { 16 | if (this.props.value && !this.state.value || this.state.value !== this.props.value) { 17 | let changes = []; 18 | if (prevState.value) { 19 | const old = prevState.value.toString(), notold = this.props.value.toString(); 20 | for (let c = 0; c < old.length; c++) { 21 | if (notold[c] !== old[c]) changes.push(c); 22 | } 23 | } 24 | if (this.props.value !== '0' && this.props.value !== '') 25 | this.setState({value : this.props.value, changes}); 26 | setTimeout(() => this.setState({changes: []}), 300); 27 | } 28 | 29 | } 30 | 31 | render() { 32 | let {value, changes} = this.state; 33 | let {primary, small} = this.props; 34 | primary = primary ? primary : 6666; 35 | 36 | value = value ? value.toString().split('') : ['0']; 37 | 38 | return ( 39 | 40 | {value.map((n, index) => ( 41 | 7 ? "s-one" : " one") : "") + 48 | (value.length > 7 49 | ? index < primary 50 | ? " s-primary" 51 | : n === "1" 52 | ? "s-one small fade-small-one" 53 | : "small" 54 | : index < primary 55 | ? " primary" 56 | : "") + 57 | (changes.indexOf(index) > -1 ? " in" : "") 58 | } 59 | > 60 | {n} 61 | 62 | ))} 63 | 64 | ); 65 | } 66 | } 67 | 68 | export default observer(Ticker) -------------------------------------------------------------------------------- /src/components/Tooltip.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | export default function Tooltip(props) { 4 | 5 | 6 | let tooltipCls = 'tooltip'; 7 | if (props.bottom) tooltipCls += ' bottom'; 8 | if (props.className) tooltipCls += ' '+props.className; 9 | 10 | return ( 11 |
12 | 13 | {props.children} 14 |
15 | ) 16 | 17 | } 18 | -------------------------------------------------------------------------------- /src/components/action-panels/Borrow.js: -------------------------------------------------------------------------------- 1 | import React, {Component} from "react"; 2 | import {validateBorrow} from "../../lib/Actions"; 3 | import Tooltip from "../Tooltip"; 4 | 5 | export default class Borrow extends Component { 6 | 7 | name = "Borrow"; 8 | action = "borrow"; 9 | actioning = "Borrowing"; 10 | 11 | constructor(props) { 12 | super(props); 13 | 14 | this.state = { 15 | val : '', 16 | invalid : false, 17 | error: '', 18 | } 19 | } 20 | 21 | validate = async (val) => { 22 | const ok = await validateBorrow(val); 23 | 24 | let error = ''; 25 | if (!ok[0]) error = ok[1]; 26 | 27 | this.setState({invalid: !ok[0], error}); 28 | return ok; 29 | }; 30 | 31 | doAction = () => { 32 | const {val} = this.state; 33 | if (!val*1) return false; 34 | 35 | this.props.onPanelAction(this.action, val, this.actioning) 36 | }; 37 | 38 | onChange = (e) => { 39 | const val = e.target.value; 40 | const res = this.props.onPanelInput(val); 41 | if (res !== false) { 42 | this.setState({val: res}); 43 | this.validate(res); 44 | } 45 | }; 46 | 47 | render() { 48 | 49 | const {invalid, error, val} = this.state; 50 | 51 | return ( 52 |
53 |

Borrow

54 |

How much DAI would you like to Borrow?

55 |
56 |
57 | 58 | {error && {error}} 59 |
60 | 61 |
62 |
63 |

Unlock DAI to continue

64 |
65 |
66 | ) 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/components/action-panels/Deposit.js: -------------------------------------------------------------------------------- 1 | import React, {Component} from "react"; 2 | import {validateDeposit, validateRepay} from "../../lib/Actions"; 3 | import Tooltip from "../Tooltip"; 4 | 5 | export default class Deposit extends Component { 6 | 7 | name = "Deposit"; 8 | action = "deposit"; 9 | actioning = "Depositing"; 10 | 11 | constructor(props) { 12 | super(props); 13 | 14 | this.state = { 15 | invalid : false, 16 | val : '', 17 | error : '', 18 | } 19 | } 20 | 21 | componentDidMount() { 22 | } 23 | 24 | validate = async (val) => { 25 | const ok = await validateDeposit(val); 26 | 27 | let error = ''; 28 | if (!ok[0]) error = ok[1]; 29 | 30 | this.setState({invalid: !ok[0], error}); 31 | return ok; 32 | }; 33 | 34 | doAction = () => { 35 | const {invalid, val} = this.state; 36 | if (invalid || !val*1) return false; 37 | 38 | this.props.onPanelAction(this.action, this.input.value, this.actioning) 39 | }; 40 | 41 | onChange = (e) => { 42 | const val = e.target.value; 43 | const res = this.props.onPanelInput(val); 44 | if (res !== false) { 45 | this.setState({val: res}); 46 | this.validate(res); 47 | } 48 | }; 49 | 50 | render() { 51 | 52 | const {invalid, val, error} = this.state; 53 | const {currency} = this.props 54 | return ( 55 |
56 |

Deposit

57 |

How much {currency} would you like to deposit?

58 |
59 |
60 | this.input = e} /> 61 | {error && {error}} 62 |
63 | 64 |
65 |
66 |

Unlock DAI to continue

67 |
68 |
69 | ) 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/components/action-panels/Loading.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from "react"; 2 | import WhiteBgViewIcon from "../../assets/view-icon.svg"; 3 | import BlacBgViewIcon from "../../assets/view-icon-opeq-bg.svg"; 4 | import BIcon from "../../assets/b-icon.svg"; 5 | import VIcon from "../../assets/v-icon.svg"; 6 | import XIcon from "../../assets/red-x-icon.svg"; 7 | import FragLoader from "../FragLoader"; 8 | import {isKovan} from "../../lib/Utils" 9 | 10 | const blackBgStyle = { 11 | color: '#647686', 12 | fill: '#647686', 13 | 'flex-direction': 'column', 14 | 'justify-content': 'space-between', 15 | height: '91px', 16 | padding: 0, 17 | } 18 | 19 | export default class Loading extends Component { 20 | 21 | render() { 22 | const kovan = isKovan() 23 | const { actioning, value, currency, completed, failed, hash, blackBg } = this.props; 24 | 25 | const icon = completed ? VIcon : (failed ? XIcon : BIcon); 26 | const resultText = completed ? 'Completed' : (failed ? 'Failed' : ''); 27 | const ViewIcon = blackBg ? BlacBgViewIcon : WhiteBgViewIcon 28 | const extraStyle = blackBg ? blackBgStyle : {} 29 | 30 | return ( 31 |
32 |

33 | {completed || failed && } 34 | {(!completed && !failed) && } 35 | 36 | {actioning} {value} {currency} {resultText}

37 | {(!failed && hash) &&
38 | 39 | View 40 | 41 | 42 |
} 43 |
44 | ) 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/components/action-panels/Withdraw.js: -------------------------------------------------------------------------------- 1 | import React, {Component} from "react"; 2 | import {validateDeposit, validateWithdraw} from "../../lib/Actions"; 3 | import Tooltip from "../Tooltip"; 4 | 5 | export default class Withdraw extends Component { 6 | 7 | name = "Withdraw"; 8 | action = "withdraw"; 9 | actioning = "Withdrawing"; 10 | 11 | constructor(props) { 12 | super(props); 13 | 14 | this.state = { 15 | val : '', 16 | invalid : false, 17 | error: '', 18 | } 19 | } 20 | 21 | validate = async (val) => { 22 | const ok = await validateWithdraw(val); 23 | 24 | let error = ''; 25 | if (!ok[0]) error = ok[1]; 26 | 27 | this.setState({invalid: !ok[0], error}); 28 | return ok; 29 | }; 30 | 31 | 32 | doAction = () => { 33 | const {invalid, val} = this.state; 34 | if (invalid || !val*1) return false; 35 | 36 | this.props.onPanelAction(this.action, this.input.value, this.actioning) 37 | }; 38 | 39 | onChange = (e) => { 40 | const val = e.target.value; 41 | const res = this.props.onPanelInput(val); 42 | if (res !== false) { 43 | this.setState({val: res}); 44 | this.validate(res); 45 | } 46 | }; 47 | 48 | setMax = () => { 49 | const {userInfo, currency} = this.props 50 | const val = (Math.floor(userInfo.collaeralDeposited * 1000000)/1000000).toString(); 51 | const res = this.props.onPanelInput(val); 52 | if (res !== false) { 53 | this.setState({val: res}); 54 | this.validate(res); 55 | } 56 | }; 57 | 58 | render() { 59 | 60 | const {invalid, val, error} = this.state; 61 | const noDaiDebt = this.props.userInfo.bCdpInfo.daiDebt === 0 62 | const {currency} = this.props 63 | return ( 64 |
65 |

Withdraw

66 |

How much {currency} would you like to withdraw?

67 |
68 |
69 | {noDaiDebt &&
Set Max
} 70 | this.input = e} /> 71 | {error && {error}} 72 |
73 | 74 |
75 |
76 | ) 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /src/components/compound-components/BalanceListBox.js: -------------------------------------------------------------------------------- 1 | import React, {Component} from "react"; 2 | import {observer} from "mobx-react" 3 | import styled from "styled-components" 4 | import CoinListHeader from "./CoinListHeader" 5 | import CoinList from "./CoinList" 6 | import compoundStore from "../../stores/compound.store" 7 | import ResponsiveWidthCol from "../style-components/ResponsiveContainer" 8 | import {device} from "../../screenSizes"; 9 | 10 | const Container = styled.div` 11 | padding-top: 50px; 12 | @media ${device.largeLaptop} { 13 | padding-top: 42.5px; 14 | } 15 | @media ${device.laptop} { 16 | padding-top: 35px; 17 | } 18 | ` 19 | 20 | class BalanceListBox extends Component { 21 | 22 | render () { 23 | const {list, type} = this.props 24 | return ( 25 | 26 | 27 | 28 | 29 | ) 30 | } 31 | } 32 | 33 | export default observer(BalanceListBox) -------------------------------------------------------------------------------- /src/components/compound-components/CoinList.js: -------------------------------------------------------------------------------- 1 | import React, {Component} from "react"; 2 | import {observer} from "mobx-react" 3 | import styled from "styled-components" 4 | import CoinListItem from "./CoinListItem" 5 | import Flex, {FlexItem} from "styled-flex-component"; 6 | import {Transition, animated} from 'react-spring/renderprops' 7 | import compoundStore from "../../stores/compound.store"; 8 | import userStore from "../../stores/user.store" 9 | 10 | class CoinList extends Component { 11 | 12 | render () { 13 | const {list: items, isInBalanceBox, type, coinStatusToShow} = this.props 14 | 15 | return ( 16 | item.symbol} 22 | from={{ opacity: 0, height: 0, zIndex: 0}} 23 | enter={{ opacity: 1 , height: "auto", zIndex: 1}} 24 | leave={{ opacity: 0, height: 0, zIndex: -1}}> 25 | {(item, state, i) => (props => 26 | 27 | 32 | ) 33 | } 34 | 35 | ) 36 | } 37 | } 38 | 39 | export default observer(CoinList) -------------------------------------------------------------------------------- /src/components/compound-components/CoinListBox.js: -------------------------------------------------------------------------------- 1 | import React, {Component} from "react"; 2 | import {observer} from "mobx-react" 3 | import styled from "styled-components" 4 | import CoinListHeader from "./CoinListHeader" 5 | import CoinList from "./CoinList" 6 | import compoundStore from "../../stores/compound.store" 7 | import ResponsiveWidthCol from "../style-components/ResponsiveContainer" 8 | import { Transition } from "react-spring/renderprops"; 9 | 10 | const Container = styled(ResponsiveWidthCol)` 11 | border-radius: 12px; 12 | box-shadow: 0 0 6px 0 rgba(0, 0, 0, 0.22); 13 | border-style: solid; 14 | border-width: 0.5px; 15 | border-image-source: linear-gradient(to bottom, rgba(255, 255, 255, 0.8), rgba(255, 255, 255, 0.4) 5%, rgba(255, 255, 255, 0) 20%, rgba(255, 255, 255, 0)); 16 | ` 17 | 18 | class CoinListBox extends Component { 19 | 20 | render () { 21 | const {list, type} = this.props 22 | const show = list.length > 0 23 | return ( 24 | 30 | {show => show && (props => 31 | 32 | 33 | 34 | 35 | )} 36 | 37 | ) 38 | } 39 | } 40 | 41 | export default observer(CoinListBox) -------------------------------------------------------------------------------- /src/components/compound-components/CoinListHeader.js: -------------------------------------------------------------------------------- 1 | import React, {Component} from "react"; 2 | import {observer} from "mobx-react" 3 | import styled from "styled-components" 4 | import Flex, {FlexItem} from "styled-flex-component"; 5 | import {device} from "../../screenSizes"; 6 | 7 | export const ClHeader = styled.div` 8 | font-family: "NeueHaasGroteskDisp Pro Md", sans-serif; 9 | padding-left: 40px; 10 | height: 45px; 11 | width: 100%; 12 | opacity: 0.28; 13 | font-size: 12px; 14 | letter-spacing: 0.6px; 15 | color: #0b0412; 16 | line-height: 1.5; 17 | @media ${device.largeLaptop} { 18 | font-size: 11px; 19 | } 20 | @media ${device.laptop} { 21 | font-size: 11px; 22 | } 23 | ` 24 | 25 | class CoinListHeader extends Component { 26 | 27 | render () { 28 | return ( 29 | 30 | 31 | 32 | Asset 33 | 34 | 35 | APY 36 | 37 | 38 | Balance 39 | 40 | 41 | 42 | ) 43 | } 44 | } 45 | 46 | export default observer(CoinListHeader) -------------------------------------------------------------------------------- /src/components/compound-components/ProgressBar.js: -------------------------------------------------------------------------------- 1 | import React, {Component} from "react"; 2 | import styled from "styled-components" 3 | 4 | const Bar = styled.div` 5 | border-radius: 4px; 6 | width: 100%; 7 | height: 4px; 8 | background-color: rgba(11, 4, 18, 0.15); 9 | ` 10 | 11 | const Marker = styled.div` 12 | transition: all 0.3s ease-in-out; 13 | border-radius: 4px 0 0 4px; 14 | width: ${({precent})=> precent}%; 15 | height 100%; 16 | background: black; 17 | ` 18 | 19 | export default (props)=> { 20 | return ( 21 | 22 | 23 | 24 | ) 25 | } -------------------------------------------------------------------------------- /src/components/compound-components/TxInProgress.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @format 3 | */ 4 | import React, {Component} from "react"; 5 | import {observer} from "mobx-react" 6 | import styled from "styled-components" 7 | import Flex, {FlexItem} from "styled-flex-component"; 8 | 9 | class TxInProgress extends Component { 10 | render () { 11 | return ( 12 |
TxInProgress
13 | ) 14 | } 15 | } 16 | 17 | export default observer(TxInProgress) -------------------------------------------------------------------------------- /src/components/compound-components/Unlock.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @format 3 | */ 4 | import React, {Component} from "react"; 5 | import {observer} from "mobx-react" 6 | import styled from "styled-components" 7 | import Flex, {FlexItem} from "styled-flex-component"; 8 | import ActionBoxFooter from "./ActionBoxFooter" 9 | import LoadingRing from "../LoadingRing"; 10 | import { depositEth } from "../../lib/compound.interface"; 11 | import {device} from "../../screenSizes"; 12 | import {ActionEnum} from "../../lib/compound.util" 13 | 14 | const Text = styled.div` 15 | font-family: "Poppins", sans-serif; 16 | font-size: 14px; 17 | font-weight: normal; 18 | font-stretch: normal; 19 | font-style: normal; 20 | line-height: normal; 21 | letter-spacing: normal; 22 | color: #0b0412; 23 | @media ${device.largeLaptop} { 24 | font-size: 13px; 25 | } 26 | @media ${device.laptop} { 27 | font-size: 13px; 28 | } 29 | ` 30 | const Container = styled.div` 31 | visibility: ${({hide})=> hide ? "hidden" : "visible"}; 32 | .tickbox{ 33 | margin: 3px 2px 0 0; 34 | } 35 | pointer-events: ${({disable})=> disable ? "none" : "auto"}; 36 | ` 37 | 38 | class Unlock extends Component{ 39 | 40 | constructor(props) { 41 | super(props); 42 | 43 | this.state = { 44 | unlocked: false, 45 | unlocking: false, 46 | } 47 | } 48 | 49 | onUnlock = async () => { 50 | try{ 51 | if(this.state.unlocked){ 52 | return 53 | } 54 | const {coin} = this.props 55 | this.setState({unlocking: true}); 56 | await coin.unlock() 57 | this.setState({ 58 | unlocked: true, 59 | unlocking: false, 60 | }) 61 | } catch (err){ 62 | this.setState({ 63 | unlocked: false, 64 | unlocking: false, 65 | }) 66 | } 67 | } 68 | 69 | render () { 70 | 71 | let {unlocking} = this.state 72 | const {coin, action} = this.props 73 | const unlocked = coin.isUnlocked() || this.state.unlocked // this is used to acount for UI delay 74 | const text = !unlocked ? `Unlock ${coin.symbol} to continue` : `${coin.symbol} is unlocked` 75 | return ( 76 | 77 | 78 | 79 | {text} 80 | 81 |
82 | {unlocking && } 83 |
84 |
85 |
86 | ) 87 | } 88 | } 89 | 90 | export default observer(Unlock) -------------------------------------------------------------------------------- /src/components/modals/MigrationModal.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from "react"; 2 | import MigrationDrawing from "../../assets/images/maker-migration.png"; 3 | import EventBus from "../../lib/EventBus"; 4 | import { migrateMakerDao } from "../../lib/Actions"; 5 | import makerStoreManager, {makerStores} from "../../stores/maker.store" 6 | 7 | export default class MigrationModal extends Component { 8 | onMigrate = async () => { 9 | const makerCollType = makerStoreManager.currentStore 10 | EventBus.$emit(`migration-started-${makerCollType}`); 11 | EventBus.$emit("close-modal"); 12 | try { 13 | await migrateMakerDao(); 14 | EventBus.$emit(`migration-completed-${makerCollType}`); 15 | setTimeout(() => { 16 | makerStores[makerCollType].getUserInfo() 17 | }, 3000) 18 | } 19 | catch (e) { 20 | EventBus.$emit(`migration-failed-${makerCollType}`); 21 | } 22 | }; 23 | 24 | render() { 25 | 26 | return ( 27 |
28 |

Import your Vault

29 |


By importing your MakerDAO Vault you give priority to B.Protocol in the liquidation process
30 |
The Vault remains under your full control, and will start accumulate a user score
31 |


Read the risks of using B.Protocol
32 |
B.Protocol does not protect you from liquidations
33 |
34 | 35 |
36 | 39 |
40 | ) 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/components/style-components/AnimateNumberChange.js: -------------------------------------------------------------------------------- 1 | import React, {Component} from "react"; 2 | import {Spring, animated, interpolate} from 'react-spring/renderprops' 3 | import {toCommmSepratedString} from "../../lib/Utils" 4 | 5 | export default class AnimateNumberChange extends Component{ 6 | 7 | constructor(props) { 8 | super(props); 9 | 10 | this.state = { 11 | from : props.val, 12 | to : props.val, 13 | } 14 | } 15 | 16 | componentDidUpdate(prevProps) { 17 | if (this.props.val !== prevProps.val) { 18 | this.setState({from: prevProps.val, to: this.props.val}) 19 | } 20 | } 21 | 22 | render () { 23 | const decimals = this.props.decimals || 2 24 | const duration = this.props.duration || 300 25 | const commas = this.props.commas || true 26 | 27 | return ( 28 | 33 | {({number}) => {number.interpolate(x=> toCommmSepratedString(parseFloat(x).toFixed(decimals)))}} 34 | 35 | ) 36 | } 37 | } -------------------------------------------------------------------------------- /src/components/style-components/AnimateNumericalString.js: -------------------------------------------------------------------------------- 1 | import React, {Component} from "react"; 2 | import {Spring, animated, interpolate} from 'react-spring/renderprops' 3 | import {toCommmSepratedString} from "../../lib/Utils" 4 | 5 | export default class AnimateNumericalString extends Component{ 6 | 7 | constructor(props) { 8 | super(props); 9 | 10 | this.state = { 11 | from : props.val, 12 | to : props.val, 13 | } 14 | } 15 | 16 | componentDidUpdate(prevProps) { 17 | if (this.props.val !== prevProps.val) { 18 | this.setState({from: prevProps.val, to: this.props.val}) 19 | } 20 | } 21 | 22 | render () { 23 | const decimals = this.props.decimals || 2 24 | const duration = this.props.duration || 300 25 | 26 | return ( 27 | 32 | {({number}) => {number.interpolate(x=> parseFloat(x).toFixed(decimals))}} 33 | 34 | ) 35 | } 36 | } -------------------------------------------------------------------------------- /src/components/style-components/BpLoader.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | export default function BpLoader(props) { 4 | const styles = { 5 | border: "none", 6 | padding: 0, 7 | flex: 0, 8 | } 9 | return ( 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | ) 19 | } 20 | -------------------------------------------------------------------------------- /src/components/style-components/Buttons.js: -------------------------------------------------------------------------------- 1 | import React, {Component} from "react"; 2 | import styled from "styled-components" 3 | import {device} from "../../screenSizes"; 4 | 5 | const SmallButtonContainer = styled.div` 6 | cursor: pointer; 7 | padding: 0 15px; 8 | height: 18px; 9 | border-radius: 5px; 10 | display: flex; 11 | align-items: center; 12 | justify-content: center; 13 | background-color: rgba(214, 242, 227, 0.4); 14 | height: 26px; 15 | span{ 16 | font-family: "NeueHaasGroteskDisp Pro Md", sans-serif; 17 | font-size: 14px; 18 | font-weight: normal; 19 | font-stretch: normal; 20 | font-style: normal; 21 | line-height: normal; 22 | letter-spacing: 0.6px; 23 | color: white; 24 | } 25 | @media ${device.largeLaptop} { 26 | height: 20px; 27 | span{ 28 | font-size: 13px; 29 | } 30 | } 31 | @media ${device.laptop} { 32 | height: 18px; 33 | span{ 34 | font-size: 12px; 35 | } 36 | } 37 | ` 38 | 39 | export const SmallButton = (props) => { 40 | return( 41 | 42 | 43 | {props.children} 44 | 45 | 46 | ) 47 | } 48 | 49 | export const ModalButton = styled.div` 50 | transition: all 0.3s ease-in-out; 51 | min-width: 218px; 52 | padding: 0 10px; 53 | height: 48px; 54 | border-radius: 4px; 55 | background-color: #12c164; 56 | display: flex; 57 | justify-content:center; 58 | align-items: center; 59 | cursor: pointer; 60 | span { 61 | transition: all 0.3s ease-in-out; 62 | font-family: "NeueHaasGroteskDisp Pro Md", sans-serif; 63 | font-size: 14px; 64 | font-weight: normal; 65 | font-stretch: normal; 66 | font-style: normal; 67 | line-height: normal; 68 | letter-spacing: 0.7px; 69 | color: white; 70 | padding: 10px; 71 | text-transform: uppercase; 72 | } 73 | &.disabled{ 74 | background-color: #cccccc; 75 | pointer-events: none; 76 | } 77 | &.done{ 78 | background-color: white; 79 | border: 2px solid #12c164; 80 | pointer-events: none; 81 | span{ 82 | color: #12c164!important; 83 | } 84 | } 85 | ` -------------------------------------------------------------------------------- /src/components/style-components/GreyLine.js: -------------------------------------------------------------------------------- 1 | import styled from "styled-components" 2 | 3 | const GreyLine = styled.div` 4 | width: 100%; 5 | height: 1px; 6 | opacity: 0.25; 7 | background: rgb(151, 151, 151); 8 | ` 9 | 10 | export default GreyLine -------------------------------------------------------------------------------- /src/components/style-components/HeaderProgressBar.js: -------------------------------------------------------------------------------- 1 | import React, {Component} from "react"; 2 | import styled from "styled-components" 3 | 4 | const Bar = styled.div` 5 | border-radius: 4px; 6 | width: 100%; 7 | height: 8px; 8 | background-color: rgba(66, 110, 85, 0.12); 9 | ` 10 | 11 | const Marker = styled.div` 12 | transition: all 0.3s ease-in-out; 13 | border-radius: 4px; 14 | width: ${({precent})=> precent}%; 15 | height 100%; 16 | background: linear-gradient(to right, rgba(37, 30, 43, 0.38) -4%, #100d13); 17 | ` 18 | 19 | export default (props)=> { 20 | return ( 21 | 22 | 23 | 24 | ) 25 | } -------------------------------------------------------------------------------- /src/components/style-components/NotificationsContainer.js: -------------------------------------------------------------------------------- 1 | import styled from "styled-components" 2 | 3 | const NotificationsContainer = styled.div` 4 | position: fixed; 5 | top: 0; 6 | left: 0; 7 | z-index: 1800; 8 | width: 100%; 9 | ` 10 | 11 | export default NotificationsContainer -------------------------------------------------------------------------------- /src/components/style-components/ProgressBar.js: -------------------------------------------------------------------------------- 1 | import React, {Component} from "react"; 2 | import styled from "styled-components" 3 | 4 | const Bar = styled.div` 5 | border-radius: 4px; 6 | width: 100%; 7 | height: 4px; 8 | background-color: rgba(11, 4, 18, 0.15); 9 | ` 10 | 11 | const Marker = styled.div` 12 | transition: all 0.3s ease-in-out; 13 | border-radius: 4px 0 0 4px; 14 | width: ${({precent})=> precent}%; 15 | height 100%; 16 | background: black; 17 | ` 18 | 19 | export default (props)=> { 20 | return ( 21 | 22 | 23 | 24 | ) 25 | } -------------------------------------------------------------------------------- /src/components/style-components/ResponsiveContainer.js: -------------------------------------------------------------------------------- 1 | import styled from "styled-components" 2 | import {device} from "../../screenSizes"; 3 | 4 | const ResponsiveWidthCol = styled.div` 5 | width: 610px; 6 | margin: 20px; 7 | @media ${device.largeLaptop} { 8 | width: 550px; 9 | margin: 10px; 10 | } 11 | @media ${device.laptop} { 12 | width: 450px; 13 | } 14 | @media ${device.tablet} { 15 | max-width: 610px; 16 | width: calc(100vw - 20px) 17 | } 18 | ` 19 | 20 | export const ResponsiveWidthHeader = styled.div` 21 | max-width: ${610 * 2 + 40}px; 22 | @media ${device.largeLaptop} { 23 | max-width: ${560 * 2 + 40}px; 24 | } 25 | @media ${device.laptop} { 26 | max-width: ${498 * 2 + 40}px; 27 | padding: 0 5px; 28 | } 29 | @media ${device.tablet} { 30 | padding: 0 15px; 31 | } 32 | ` 33 | 34 | export const HeaderItemContainer = styled.div` 35 | width: 50%; 36 | padding: 0 20px; 37 | display: flex; 38 | justify-content: center; 39 | align-items: center; 40 | min-width: 570px; 41 | min-height: 322px; 42 | @media ${device.largeLaptop} { 43 | padding: 0 10px; 44 | min-width: 430px; 45 | min-height: 257px; 46 | } 47 | @media ${device.laptop} { 48 | padding: 0 10px; 49 | min-width: 400px; 50 | min-height: 200px; 51 | } 52 | @media ${device.tablet} { 53 | padding: 0 10px; 54 | min-width: 390px; 55 | min-height: 200px; 56 | } 57 | @media ${device.mobile} { 58 | padding: 0 10px; 59 | min-width: 360px; 60 | min-height: 200px; 61 | } 62 | 63 | ` 64 | 65 | export default ResponsiveWidthCol -------------------------------------------------------------------------------- /src/components/style-components/Tabs.js: -------------------------------------------------------------------------------- 1 | import React, {Component} from "react"; 2 | import styled from "styled-components" 3 | import Flex, {FlexItem} from "styled-flex-component"; 4 | import {device} from "../../screenSizes" 5 | const Container = styled.div` 6 | position: relative; 7 | bottom: -6px; 8 | 9 | .shadow-cut{ 10 | position: relative; 11 | z-index:10; 12 | width: 100%; 13 | height: 6px; 14 | background-color: #fff; 15 | } 16 | ` 17 | 18 | const Tab = styled.div` 19 | padding: 15px 30px; 20 | font-family: "NeueHaasGroteskDisp Pro Md", sans-serif; 21 | font-size: 18px; 22 | white-space: nowrap; 23 | @media ${device.largeLaptop} { 24 | font-size: 16px; 25 | } 26 | @media ${device.mobile} { 27 | font-size: 14px; 28 | padding: 15px 20px; 29 | } 30 | 31 | font-weight: normal; 32 | font-stretch: normal; 33 | font-style: normal; 34 | line-height: normal; 35 | letter-spacing: normal; 36 | color: #0b0412; 37 | cursor: pointer; 38 | &.selected{ 39 | background-color: white; 40 | border-radius: 5px; 41 | box-shadow: 0 0 6px 0 rgb(0 0 0 / 22%); 42 | border-bottom-right-radius: 0; 43 | border-bottom-left-radius: 0; 44 | } 45 | 46 | ` 47 | 48 | export default (props)=> { 49 | const tabs = props.tabNames || [] 50 | const selected = props.selected 51 | return ( 52 | 53 | 54 | {tabs.map(tab => props.onClick(tab)} key={tab} className={selected == tab ? "selected" : ""}>{tab})} 55 | 56 |
57 | 58 | ) 59 | } -------------------------------------------------------------------------------- /src/containers/Compound.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | import React, { Component } from "react"; 4 | import logo from "../assets/compound-full-logo.svg"; 5 | import Etherium from "../assets/etherium.svg"; 6 | import Header2 from "../components/Header2"; 7 | import { doApiAction } from "../lib/Actions"; 8 | import compoundStore from "../stores/compound.store" 9 | import {observer} from "mobx-react" 10 | import styled from "styled-components" 11 | import Flex, {FlexItem} from "styled-flex-component"; 12 | import BalanceBox from "../components/compound-components/BalanceBox" 13 | import CoinListBox from "../components/compound-components/CoinListBox" 14 | import {CoinStatusEnum} from "../lib/compound.util" 15 | import {device} from "../screenSizes"; 16 | import routerStore from "../stores/router.store" 17 | 18 | const Overides = styled.div` 19 | margin-bottom: 100px; 20 | ` 21 | 22 | class Compound extends Component { 23 | 24 | constructor(props) { 25 | super(props); 26 | } 27 | 28 | componentDidMount() { 29 | routerStore.setRouteProps(this.props.history) 30 | compoundStore.getUserInfo() 31 | } 32 | 33 | getList(coinStatusToShow){ 34 | const items = compoundStore.coinList.filter(coinAddress=> { 35 | const coin = compoundStore.coinsInTx[coinAddress] || compoundStore.coinMap[coinAddress] // preserve state until tx is finished and UI is ready to dispaly new coin state 36 | if(!coin.symbol){ 37 | return false 38 | } 39 | return coin.isCoinStatus(coinStatusToShow) 40 | }) 41 | .map(coinAddress => { 42 | const coin = compoundStore.coinsInTx[coinAddress] || compoundStore.coinMap[coinAddress] 43 | return coin 44 | }) 45 | return items 46 | } 47 | 48 | render() { 49 | const { userInfo, userInfoUpdate, coinList } = compoundStore 50 | console.log("comp userInfoUpdate ", userInfoUpdate) 51 | return ( 52 | 53 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | ); 70 | } 71 | } 72 | 73 | export default observer(Compound) -------------------------------------------------------------------------------- /src/containers/Dashboard.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from "react"; 2 | import Etherium from "../assets/etherium.svg"; 3 | import Header from "../components/Header"; 4 | import EtheriumBox from "../components/EtheriumBox"; 5 | import DaiBox from "../components/DaiBox"; 6 | import { doApiAction } from "../lib/Actions"; 7 | import EventBus from "../lib/EventBus"; 8 | import logo from "../assets/logo-maker-black.svg"; 9 | import makerStoreManager, {makerStoreNames, makerStores} from "../stores/maker.store" 10 | import {observer} from "mobx-react" 11 | import routerStore from "../stores/router.store" 12 | import mainStore from "../stores/main.store" 13 | 14 | class Dashboard extends Component { 15 | 16 | constructor(props) { 17 | super(props); 18 | } 19 | 20 | componentDidMount() { 21 | routerStore.setRouteProps(this.props.history) 22 | } 23 | 24 | onAction = async (action, value, onHash) => { 25 | try { 26 | const res = await doApiAction(action, value, null, onHash); 27 | makerStoreManager.getMakerStore().getUserInfo() 28 | return res; 29 | } catch (error) { 30 | if(error.message === "GEM_MODAL_CLOSED"){ 31 | EventBus.$emit("close-action") 32 | return 33 | } 34 | EventBus.$emit("action-failed", null, action); 35 | let errorMsg = null; 36 | if(action.toString() === "repay") 37 | errorMsg = "Repay is expected to fail, likely because your DAI balance is too low (by 0.000001 DAI or less)"; 38 | EventBus.$emit("app-error", errorMsg, action); 39 | console.log(error); 40 | return false; 41 | } 42 | }; 43 | 44 | render() { 45 | const {getMakerStore, storeChanges, currentStore} = makerStoreManager 46 | const { userInfo, userInfoUpdate, symbol } = getMakerStore() 47 | console.log("userInfoUpdate ", userInfoUpdate) 48 | 49 | return ( 50 |
51 |
56 | {makerStoreNames.map(name => { 57 | return ( 58 |
59 | 64 | 71 |
72 | ) 73 | })} 74 |
75 | ); 76 | } 77 | } 78 | 79 | export default observer(Dashboard) -------------------------------------------------------------------------------- /src/containers/FAQ.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from "react"; 2 | import FAQContent from "../components/FAQContent"; 3 | import routerStore from "../stores/router.store" 4 | 5 | export default class FAQ extends Component { 6 | 7 | constructor (props) { 8 | super(props) 9 | this.state = {height:0} 10 | } 11 | 12 | componentDidMount() { 13 | routerStore.setRouteProps(this.props.history) 14 | const height = document.querySelector('.menu-item-header').clientHeight; 15 | this.setState({ height }); 16 | } 17 | 18 | render() { 19 | const { handleItemChange, history } = this.props; 20 | return ( 21 |
22 |
23 |

FAQ

24 |

25 | The following are the most common questions the B.Protocol team has been asked by new users of the protocol. 26 | It will be updated as we go forward. Get yourself educated… 27 |

28 |
29 | {/*

*/} 30 |
34 | 35 |
36 |
37 | ); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/containers/Liquity.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from "react"; 2 | import {observer} from "mobx-react" 3 | import routerStore from "../stores/router.store" 4 | 5 | class Liquity extends Component { 6 | 7 | constructor(props) { 8 | super(props); 9 | } 10 | 11 | componentDidMount() { 12 | routerStore.setRouteProps(this.props.history) 13 | } 14 | 15 | render() { 16 | return ( 17 |