├── .gitignore
├── README.md
├── _redirects
├── netlify.toml
├── package-lock.json
├── package.json
├── public
├── favicon.ico
├── favicon.png
├── images
│ ├── .DS_Store
│ ├── EarnLogo.svg
│ ├── Group 3.png
│ ├── actionCardCompoundLoan.png
│ ├── actionCardDAI.png
│ ├── actionCardETHiBTC.png
│ ├── actionCardETHsBTC.png
│ ├── actionCardEth.png
│ ├── actionCardEthWbtc.png
│ ├── actionCardFulcrum.png
│ ├── actionCardKNC.png
│ ├── actionCardLong4xBTC.png
│ ├── actionCardWbtc.png
│ ├── actionCardiETHsBTC.png
│ ├── actionCardsBTCsXAU.png
│ ├── actionCardsXAU.png
│ ├── actionCardsXTZ.png
│ ├── actionCardsbtc.png
│ ├── approved.svg
│ ├── buildonethereum.png
│ ├── bzx.svg
│ ├── bzxlogo.svg
│ ├── compound 2.svg
│ ├── compound.svg
│ ├── dDAILogo.svg
│ ├── daiIcon.svg
│ ├── ddailogo.png
│ ├── discord.svg
│ ├── dydx.png
│ ├── dydx.svg
│ ├── eaBoth.png
│ ├── earn-logo.svg
│ ├── ethBG01.png
│ ├── ethBG02.jpg
│ ├── ethlong4x.png
│ ├── ethshort4x.png
│ ├── favicon16.png
│ ├── favicon32.png
│ ├── fulcrum.svg
│ ├── hamburger.svg
│ ├── icons
│ │ ├── 0x.png
│ │ ├── blackmoon.png
│ │ ├── dai.png
│ │ ├── erc20.svg
│ │ ├── eth.png
│ │ ├── eth.svg
│ │ ├── kyber.png
│ │ ├── loopring.png
│ │ ├── mana.png
│ │ └── odem.png
│ ├── kyber.svg
│ ├── little_arrow.png
│ ├── logo.svg
│ ├── maker.svg
│ ├── notificationIcon.svg
│ ├── pending.svg
│ ├── r_dai.png
│ ├── recap_CompoundDAI.png
│ ├── recap_DAI.png
│ ├── recap_ETH.png
│ ├── recap_FulcrumDAI.png
│ ├── recap_KNC.png
│ ├── recap_earhBTCETH.png
│ ├── recap_sBTC.png
│ ├── recap_sBTCiETH.png
│ ├── recap_sXAU.png
│ ├── recap_sXAUsBTC.png
│ ├── recap_sXTZ.png
│ ├── recap_wBTC.png
│ ├── rejected.svg
│ ├── synthetix.png
│ ├── telegram.svg
│ ├── uniswap.svg
│ ├── wallet.svg
│ └── winner.png
├── index.html
├── logo192.png
├── logo512.png
├── manifest.json
└── robots.txt
├── src
├── App
│ ├── global.scss
│ ├── index.js
│ └── styles.css
├── Untitled-1
├── Wallet.js
├── class
│ ├── .DS_Store
│ ├── Rx.js
│ ├── artifacts
│ │ ├── BaseRecipe.json
│ │ ├── BuyEthRecipe.json
│ │ ├── BuyPTokenRecipe.json
│ │ ├── BuySynthRecipe.json
│ │ ├── BuyTokenRecipe.json
│ │ ├── CompoundRepayRecipe.json
│ │ ├── DCA.json
│ │ ├── DDAI.json
│ │ ├── DDAIEvents.json
│ │ ├── DDAIGSNBouncer.json
│ │ ├── ICEToken.json
│ │ ├── ICToken.json
│ │ ├── IDDAI.json
│ │ ├── IKyberNetwork.json
│ │ ├── IMakerFeed.json
│ │ ├── IMoneyMarket.json
│ │ ├── IPToken.json
│ │ ├── IPriceFeed.json
│ │ ├── ISynthetix.json
│ │ ├── ISynthetixDepot.json
│ │ ├── MockCEToken.json
│ │ ├── MockCToken.json
│ │ ├── MockDai.json
│ │ ├── MockIToken.json
│ │ ├── MockKyberNetwork.json
│ │ ├── MockRecipe.json
│ │ ├── MockSnx.json
│ │ ├── MockSynthetix.json
│ │ ├── MockToken.json
│ │ └── MockUSDFeed.json
│ ├── config.js
│ ├── ddai.js
│ ├── models
│ │ └── actions.js
│ └── utils.js
├── components
│ ├── Avatar.js
│ ├── BackgroundImage.js
│ ├── BackgroundImage.scss
│ ├── CardAPR.js
│ ├── CardAction.js
│ ├── CardAmount.js
│ ├── CardEarned.js
│ ├── CardInvestmentAmount.js
│ ├── CardInvestmentToken.js
│ ├── CardOneButton.js
│ ├── CardRecap.js
│ ├── CardReward.js
│ ├── CardSelectRecipe.js
│ ├── CardSelectedRecipe.js
│ ├── CardTwoButtons.js
│ ├── CenteredColumns.js
│ ├── Clients.js
│ ├── Clients.scss
│ ├── ClientsSection.js
│ ├── ConnectW3Button.js
│ ├── Contact.js
│ ├── ContactForm.js
│ ├── ContactSection.js
│ ├── ContactSection.scss
│ ├── Conversation.js
│ ├── Footer.js
│ ├── Footer.scss
│ ├── FormField.js
│ ├── FormStatus.js
│ ├── HeroSection.js
│ ├── If.js
│ ├── InvestMoreDAI.js
│ ├── KyberWinner.js
│ ├── LinkButton.js
│ ├── Logo.js
│ ├── Navbar.js
│ ├── NavbarContainer.js
│ ├── NotificationCard.js
│ ├── NotificationDb.js
│ ├── NotificationIcon.js
│ ├── NotificationsDrawer.js
│ ├── PageHeading.js
│ ├── PrimaryButton.js
│ ├── SecondaryButton.js
│ ├── Section.js
│ ├── Section.scss
│ ├── SectionButton.js
│ ├── SectionHeader.js
│ ├── SectionHeader.scss
│ ├── SimpleSnackbar.js
│ ├── Testimonials.js
│ ├── Testimonials.scss
│ ├── TestimonialsSection.js
│ ├── TotBalance.js
│ ├── Warning.js
│ ├── Web3Button.js
│ └── index.js
├── config.js
├── containers
│ ├── ActionCardContainer.js
│ ├── CardContainer.js
│ ├── CardContainerTest.js
│ └── HeaderContainer.js
├── context
│ └── index.js
├── history.js
├── images
│ ├── actionCardEth.png
│ ├── bzx.svg
│ ├── compound.svg
│ ├── dydx.png
│ ├── dydx.svg
│ ├── earn-logo.svg
│ ├── ethBG01.png
│ ├── ethBG02.jpg
│ ├── favicon.ico
│ ├── hamburger.svg
│ ├── icons
│ │ ├── 0x.png
│ │ ├── blackmoon.png
│ │ ├── dai.png
│ │ ├── erc20.svg
│ │ ├── eth.png
│ │ ├── eth.svg
│ │ ├── kyber.png
│ │ ├── loopring.png
│ │ ├── mana.png
│ │ └── odem.png
│ ├── little_arrow.png
│ ├── logo.svg
│ ├── maker.svg
│ ├── notificationIcon.svg
│ ├── r_dai.png
│ ├── uniswap.svg
│ └── wallet.svg
├── index.css
├── index.js
├── logo.svg
├── mixpanel.js
├── pages
│ ├── deposit
│ │ └── index.js
│ ├── invest
│ │ └── index.js
│ ├── landing
│ │ └── index.js
│ ├── overview
│ │ └── index.js
│ ├── recipes
│ │ └── index.js
│ ├── test
│ │ └── index.js
│ └── withdraw
│ │ └── index.js
├── react-app-env.d.ts
├── routes.js
└── util
│ ├── analytics.js
│ ├── auth.js
│ ├── contact.js
│ └── router.js
├── tsconfig.json
└── yarn.lock
/.gitignore:
--------------------------------------------------------------------------------
1 | # OSX
2 | #
3 | .DS_Store
4 |
5 | # Xcode
6 | #
7 | build/
8 | *.pbxuser
9 | !default.pbxuser
10 | *.mode1v3
11 | !default.mode1v3
12 | *.mode2v3
13 | !default.mode2v3
14 | *.perspectivev3
15 | !default.perspectivev3
16 | xcuserdata
17 | *.xccheckout
18 | *.moved-aside
19 | DerivedData
20 | *.hmap
21 | *.ipa
22 | *.xcuserstate
23 | project.xcworkspace
24 |
25 | # Android/IntelliJ
26 | #
27 | build/
28 | .idea
29 | .gradle
30 | local.properties
31 | *.iml
32 |
33 | # node.js
34 | #
35 | node_modules/
36 | npm-debug.log
37 | yarn-error.log
38 |
39 | # BUCK
40 | buck-out/
41 | \.buckd/
42 | *.keystore
43 |
44 | # fastlane
45 | #
46 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
47 | # screenshots whenever they are needed.
48 | # For more information about the recommended setup visit:
49 | # https://docs.fastlane.tools/best-practices/source-control/
50 |
51 | */fastlane/report.xml
52 | */fastlane/Preview.html
53 | */fastlane/screenshots
54 |
--------------------------------------------------------------------------------
/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 | ### `npm 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 | ### `npm 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 | ### `npm run 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 | ### `npm run 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 |
--------------------------------------------------------------------------------
/_redirects:
--------------------------------------------------------------------------------
1 | # These rules will change if you change your site’s custom domains or HTTPS settings
2 |
3 | # Redirect default Netlify subdomain to primary domain
4 | https://ddai.netlify.com/* https://ddai.dexwallet.io/:splat 301!
5 | https://www.ddai.netlify.com/* https://ddai.dexwallet.io/:splat 301!
--------------------------------------------------------------------------------
/netlify.toml:
--------------------------------------------------------------------------------
1 | [build]
2 | functions = "functions"
3 | publish = "build"
4 | [[redirects]]
5 | from = "/*"
6 | to = "/index.html"
7 | status = 200
8 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ui",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "@material-ui/core": "^4.5.1",
7 | "@material-ui/icons": "^4.5.1",
8 | "@material/react-snackbar": "^0.15.0",
9 | "@types/jest": "24.0.18",
10 | "@types/node": "12.7.4",
11 | "@types/react": "16.9.2",
12 | "@types/react-dom": "16.9.0",
13 | "airtable": "^0.7.2",
14 | "bignumber.js": "^9.0.0",
15 | "bulma": "^0.8.0",
16 | "eth-dexcore-js": "^0.1.11",
17 | "history": "^4.10.1",
18 | "mixpanel-browser": "^2.30.1",
19 | "node-sass": "^4.13.0",
20 | "react": "^16.9.0",
21 | "react-dom": "^16.9.0",
22 | "react-rainbow-components": "^1.4.0",
23 | "react-router-dom": "^5.0.1",
24 | "react-scripts": "3.1.1",
25 | "react-text-loop": "^2.1.1",
26 | "styled-components": "^4.4.0",
27 | "typescript": "3.5.3"
28 | },
29 | "scripts": {
30 | "start": "react-scripts start",
31 | "build": "react-scripts build",
32 | "test": "react-scripts test",
33 | "eject": "react-scripts eject"
34 | },
35 | "browserslist": {
36 | "production": [
37 | ">0.2%",
38 | "not dead",
39 | "not op_mini all"
40 | ],
41 | "development": [
42 | "last 1 chrome version",
43 | "last 1 firefox version",
44 | "last 1 safari version"
45 | ]
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dexlab-io/ddai-frontend/518f8bdbafd56e29c68004093abcb8a5e038ede8/public/favicon.ico
--------------------------------------------------------------------------------
/public/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dexlab-io/ddai-frontend/518f8bdbafd56e29c68004093abcb8a5e038ede8/public/favicon.png
--------------------------------------------------------------------------------
/public/images/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dexlab-io/ddai-frontend/518f8bdbafd56e29c68004093abcb8a5e038ede8/public/images/.DS_Store
--------------------------------------------------------------------------------
/public/images/Group 3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dexlab-io/ddai-frontend/518f8bdbafd56e29c68004093abcb8a5e038ede8/public/images/Group 3.png
--------------------------------------------------------------------------------
/public/images/actionCardCompoundLoan.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dexlab-io/ddai-frontend/518f8bdbafd56e29c68004093abcb8a5e038ede8/public/images/actionCardCompoundLoan.png
--------------------------------------------------------------------------------
/public/images/actionCardDAI.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dexlab-io/ddai-frontend/518f8bdbafd56e29c68004093abcb8a5e038ede8/public/images/actionCardDAI.png
--------------------------------------------------------------------------------
/public/images/actionCardETHiBTC.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dexlab-io/ddai-frontend/518f8bdbafd56e29c68004093abcb8a5e038ede8/public/images/actionCardETHiBTC.png
--------------------------------------------------------------------------------
/public/images/actionCardETHsBTC.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dexlab-io/ddai-frontend/518f8bdbafd56e29c68004093abcb8a5e038ede8/public/images/actionCardETHsBTC.png
--------------------------------------------------------------------------------
/public/images/actionCardEth.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dexlab-io/ddai-frontend/518f8bdbafd56e29c68004093abcb8a5e038ede8/public/images/actionCardEth.png
--------------------------------------------------------------------------------
/public/images/actionCardEthWbtc.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dexlab-io/ddai-frontend/518f8bdbafd56e29c68004093abcb8a5e038ede8/public/images/actionCardEthWbtc.png
--------------------------------------------------------------------------------
/public/images/actionCardFulcrum.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dexlab-io/ddai-frontend/518f8bdbafd56e29c68004093abcb8a5e038ede8/public/images/actionCardFulcrum.png
--------------------------------------------------------------------------------
/public/images/actionCardKNC.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dexlab-io/ddai-frontend/518f8bdbafd56e29c68004093abcb8a5e038ede8/public/images/actionCardKNC.png
--------------------------------------------------------------------------------
/public/images/actionCardLong4xBTC.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dexlab-io/ddai-frontend/518f8bdbafd56e29c68004093abcb8a5e038ede8/public/images/actionCardLong4xBTC.png
--------------------------------------------------------------------------------
/public/images/actionCardWbtc.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dexlab-io/ddai-frontend/518f8bdbafd56e29c68004093abcb8a5e038ede8/public/images/actionCardWbtc.png
--------------------------------------------------------------------------------
/public/images/actionCardiETHsBTC.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dexlab-io/ddai-frontend/518f8bdbafd56e29c68004093abcb8a5e038ede8/public/images/actionCardiETHsBTC.png
--------------------------------------------------------------------------------
/public/images/actionCardsBTCsXAU.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dexlab-io/ddai-frontend/518f8bdbafd56e29c68004093abcb8a5e038ede8/public/images/actionCardsBTCsXAU.png
--------------------------------------------------------------------------------
/public/images/actionCardsXAU.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dexlab-io/ddai-frontend/518f8bdbafd56e29c68004093abcb8a5e038ede8/public/images/actionCardsXAU.png
--------------------------------------------------------------------------------
/public/images/actionCardsXTZ.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dexlab-io/ddai-frontend/518f8bdbafd56e29c68004093abcb8a5e038ede8/public/images/actionCardsXTZ.png
--------------------------------------------------------------------------------
/public/images/actionCardsbtc.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dexlab-io/ddai-frontend/518f8bdbafd56e29c68004093abcb8a5e038ede8/public/images/actionCardsbtc.png
--------------------------------------------------------------------------------
/public/images/approved.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/public/images/buildonethereum.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dexlab-io/ddai-frontend/518f8bdbafd56e29c68004093abcb8a5e038ede8/public/images/buildonethereum.png
--------------------------------------------------------------------------------
/public/images/compound 2.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/public/images/compound.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/public/images/daiIcon.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/public/images/ddailogo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dexlab-io/ddai-frontend/518f8bdbafd56e29c68004093abcb8a5e038ede8/public/images/ddailogo.png
--------------------------------------------------------------------------------
/public/images/discord.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/public/images/dydx.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dexlab-io/ddai-frontend/518f8bdbafd56e29c68004093abcb8a5e038ede8/public/images/dydx.png
--------------------------------------------------------------------------------
/public/images/dydx.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/public/images/eaBoth.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dexlab-io/ddai-frontend/518f8bdbafd56e29c68004093abcb8a5e038ede8/public/images/eaBoth.png
--------------------------------------------------------------------------------
/public/images/ethBG01.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dexlab-io/ddai-frontend/518f8bdbafd56e29c68004093abcb8a5e038ede8/public/images/ethBG01.png
--------------------------------------------------------------------------------
/public/images/ethBG02.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dexlab-io/ddai-frontend/518f8bdbafd56e29c68004093abcb8a5e038ede8/public/images/ethBG02.jpg
--------------------------------------------------------------------------------
/public/images/ethlong4x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dexlab-io/ddai-frontend/518f8bdbafd56e29c68004093abcb8a5e038ede8/public/images/ethlong4x.png
--------------------------------------------------------------------------------
/public/images/ethshort4x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dexlab-io/ddai-frontend/518f8bdbafd56e29c68004093abcb8a5e038ede8/public/images/ethshort4x.png
--------------------------------------------------------------------------------
/public/images/favicon16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dexlab-io/ddai-frontend/518f8bdbafd56e29c68004093abcb8a5e038ede8/public/images/favicon16.png
--------------------------------------------------------------------------------
/public/images/favicon32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dexlab-io/ddai-frontend/518f8bdbafd56e29c68004093abcb8a5e038ede8/public/images/favicon32.png
--------------------------------------------------------------------------------
/public/images/hamburger.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/public/images/icons/0x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dexlab-io/ddai-frontend/518f8bdbafd56e29c68004093abcb8a5e038ede8/public/images/icons/0x.png
--------------------------------------------------------------------------------
/public/images/icons/blackmoon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dexlab-io/ddai-frontend/518f8bdbafd56e29c68004093abcb8a5e038ede8/public/images/icons/blackmoon.png
--------------------------------------------------------------------------------
/public/images/icons/dai.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dexlab-io/ddai-frontend/518f8bdbafd56e29c68004093abcb8a5e038ede8/public/images/icons/dai.png
--------------------------------------------------------------------------------
/public/images/icons/eth.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dexlab-io/ddai-frontend/518f8bdbafd56e29c68004093abcb8a5e038ede8/public/images/icons/eth.png
--------------------------------------------------------------------------------
/public/images/icons/eth.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/public/images/icons/kyber.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dexlab-io/ddai-frontend/518f8bdbafd56e29c68004093abcb8a5e038ede8/public/images/icons/kyber.png
--------------------------------------------------------------------------------
/public/images/icons/loopring.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dexlab-io/ddai-frontend/518f8bdbafd56e29c68004093abcb8a5e038ede8/public/images/icons/loopring.png
--------------------------------------------------------------------------------
/public/images/icons/mana.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dexlab-io/ddai-frontend/518f8bdbafd56e29c68004093abcb8a5e038ede8/public/images/icons/mana.png
--------------------------------------------------------------------------------
/public/images/icons/odem.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dexlab-io/ddai-frontend/518f8bdbafd56e29c68004093abcb8a5e038ede8/public/images/icons/odem.png
--------------------------------------------------------------------------------
/public/images/little_arrow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dexlab-io/ddai-frontend/518f8bdbafd56e29c68004093abcb8a5e038ede8/public/images/little_arrow.png
--------------------------------------------------------------------------------
/public/images/notificationIcon.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/public/images/pending.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/public/images/r_dai.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dexlab-io/ddai-frontend/518f8bdbafd56e29c68004093abcb8a5e038ede8/public/images/r_dai.png
--------------------------------------------------------------------------------
/public/images/recap_CompoundDAI.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dexlab-io/ddai-frontend/518f8bdbafd56e29c68004093abcb8a5e038ede8/public/images/recap_CompoundDAI.png
--------------------------------------------------------------------------------
/public/images/recap_DAI.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dexlab-io/ddai-frontend/518f8bdbafd56e29c68004093abcb8a5e038ede8/public/images/recap_DAI.png
--------------------------------------------------------------------------------
/public/images/recap_ETH.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dexlab-io/ddai-frontend/518f8bdbafd56e29c68004093abcb8a5e038ede8/public/images/recap_ETH.png
--------------------------------------------------------------------------------
/public/images/recap_FulcrumDAI.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dexlab-io/ddai-frontend/518f8bdbafd56e29c68004093abcb8a5e038ede8/public/images/recap_FulcrumDAI.png
--------------------------------------------------------------------------------
/public/images/recap_KNC.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dexlab-io/ddai-frontend/518f8bdbafd56e29c68004093abcb8a5e038ede8/public/images/recap_KNC.png
--------------------------------------------------------------------------------
/public/images/recap_earhBTCETH.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dexlab-io/ddai-frontend/518f8bdbafd56e29c68004093abcb8a5e038ede8/public/images/recap_earhBTCETH.png
--------------------------------------------------------------------------------
/public/images/recap_sBTC.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dexlab-io/ddai-frontend/518f8bdbafd56e29c68004093abcb8a5e038ede8/public/images/recap_sBTC.png
--------------------------------------------------------------------------------
/public/images/recap_sBTCiETH.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dexlab-io/ddai-frontend/518f8bdbafd56e29c68004093abcb8a5e038ede8/public/images/recap_sBTCiETH.png
--------------------------------------------------------------------------------
/public/images/recap_sXAU.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dexlab-io/ddai-frontend/518f8bdbafd56e29c68004093abcb8a5e038ede8/public/images/recap_sXAU.png
--------------------------------------------------------------------------------
/public/images/recap_sXAUsBTC.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dexlab-io/ddai-frontend/518f8bdbafd56e29c68004093abcb8a5e038ede8/public/images/recap_sXAUsBTC.png
--------------------------------------------------------------------------------
/public/images/recap_sXTZ.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dexlab-io/ddai-frontend/518f8bdbafd56e29c68004093abcb8a5e038ede8/public/images/recap_sXTZ.png
--------------------------------------------------------------------------------
/public/images/recap_wBTC.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dexlab-io/ddai-frontend/518f8bdbafd56e29c68004093abcb8a5e038ede8/public/images/recap_wBTC.png
--------------------------------------------------------------------------------
/public/images/rejected.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/public/images/synthetix.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dexlab-io/ddai-frontend/518f8bdbafd56e29c68004093abcb8a5e038ede8/public/images/synthetix.png
--------------------------------------------------------------------------------
/public/images/telegram.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/public/images/wallet.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/public/images/winner.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dexlab-io/ddai-frontend/518f8bdbafd56e29c68004093abcb8a5e038ede8/public/images/winner.png
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
12 |
13 |
17 |
18 |
27 | Earn dDai - Interest with smart DeFi recipes
28 |
29 |
30 |
31 |
32 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dexlab-io/ddai-frontend/518f8bdbafd56e29c68004093abcb8a5e038ede8/public/logo192.png
--------------------------------------------------------------------------------
/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dexlab-io/ddai-frontend/518f8bdbafd56e29c68004093abcb8a5e038ede8/public/logo512.png
--------------------------------------------------------------------------------
/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 |
--------------------------------------------------------------------------------
/src/App/global.scss:
--------------------------------------------------------------------------------
1 | @charset "utf-8";
2 |
3 | // COLORS
4 | $primary: #F00093;
5 | $info: rgb(77, 77, 77);
6 | $success: #23D160;
7 | $warning: #FFDD57;
8 | $danger: #FF3860;
9 | $light: #F5F5F5;
10 | $dark: #000000;
11 |
12 | // TEXT
13 | $text: #000000;
14 | $link: #3273DC;
15 | $body-family: BlinkMacSystemFont, -apple-system, "Segoe UI", "Roboto", "Oxygen",
16 | "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue",
17 | "Helvetica", "Arial", sans-serif;
18 | $title-family: false;
19 | $button-family: false;
20 |
21 | // BREAKPOINTS
22 | $gap: 32px;
23 | $tablet: 769px;
24 | $desktop: 960px + (2 * $gap);
25 | $widescreen: 1152px + (2 * $gap);
26 | $fullhd: 1344px + (2 * $gap);
27 | $widescreen-enabled: true;
28 | $fullhd-enabled: false;
29 |
30 | // LAYOUT
31 | $section-padding: 3rem 0rem;
32 | $section-padding-medium: 6rem 0rem;
33 | $section-padding-large: 9rem 0rem;
34 |
35 | // SEE DOCS FOR MORE:
36 | // https://bit.ly/30UvE5O
37 |
38 | // IMPORT BULMA
39 | @import "~bulma/bulma.sass";
40 |
41 | // IMPORT FONT AWESOME
42 | @import url("https://use.fontawesome.com/releases/v5.10.1/css/all.css");
43 |
44 | body {
45 | background-color: #ffffff;
46 | }
47 |
48 |
--------------------------------------------------------------------------------
/src/App/index.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from "react";
2 | import { HeaderContainer } from "../components";
3 | import Routes from "../routes";
4 | import { Context, ContextDefaults } from "../context";
5 | import Wallet from '../Wallet';
6 | import "./global.scss";
7 | import "./styles.css";
8 | import history from '../history';
9 | import { Router } from "react-router-dom";
10 |
11 | import DB from '../class/models/actions';
12 |
13 | class App extends Component {
14 |
15 | constructor(props) {
16 | super(props);
17 | this.state = {
18 | context: {
19 | ...ContextDefaults,
20 | setRecipe: this.setRecipe,
21 | toggleNotificationsDrawer: this.toggleNotificationsDrawer,
22 | closeNotificationsDrawer: this.closeNotificationsDrawer,
23 | selectedRecipe: "",
24 | logs: []
25 | }
26 | }
27 | }
28 |
29 | componentDidMount() {
30 | Wallet.Rx.subscribe((action, data) => {
31 | this.refresh();
32 | });
33 |
34 | setInterval(() => {
35 | this.refresh()
36 | }, 2000);
37 | }
38 |
39 | async refresh() {
40 | if(!Wallet.ddai) return;
41 | DB.account = Wallet.getAddress();
42 |
43 | const data = await Wallet.ddai.getState();
44 | await DB.fetchAll( );
45 | this.setState((prevState) => ({
46 | context: {
47 | ...prevState.context,
48 | DDAI: data,
49 | transactions: Wallet.Rx.poolMap,
50 | logs: DB.data,
51 | // selectedRecipe: data.Recipe
52 | }
53 | }))
54 | }
55 |
56 | setRecipe = (recipe) => {
57 | this.setState((prevState) => ({
58 | context:{
59 | ...prevState.context,
60 | selectedRecipe: recipe
61 | }
62 | }))
63 | }
64 |
65 | closeNotificationsDrawer = () => {
66 | this.setState((prevState => ({
67 | context:{
68 | ...prevState.context,
69 | notificationDrawerOpen: false
70 | }
71 | })))
72 | }
73 |
74 | toggleNotificationsDrawer = () => {
75 | this.setState((prevState => ({
76 | context:{
77 | ...prevState.context,
78 | notificationDrawerOpen: !prevState.context.notificationDrawerOpen
79 | }
80 | })))
81 | }
82 |
83 | render() {
84 | return (
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 | );
96 | }
97 | }
98 | App.propTypes = {};
99 |
100 | export default App;
101 |
--------------------------------------------------------------------------------
/src/App/styles.css:
--------------------------------------------------------------------------------
1 | /* Generic CSS */
2 |
3 |
4 | body {
5 | margin: 0;
6 | padding: 0;
7 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen",
8 | "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue",
9 | sans-serif;
10 | -webkit-font-smoothing: antialiased;
11 | -moz-osx-font-smoothing: grayscale;
12 | }
13 |
14 | code {
15 | font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New",
16 | monospace;
17 | }
18 |
19 |
20 | * {
21 | -webkit-font-smoothing: antialiased;
22 | -moz-osx-font-smoothing: grayscale;
23 | text-decoration: none !important;
24 | }
25 |
26 | @import url("https://fonts.googleapis.com/css?family=Roboto+Mono:300,400,700&display=swap");
27 |
28 | :root {
29 | --almost-black: #0a0a0a;
30 | --light-black: #797979;
31 | --almost-white: #f2f2f2;
32 | --white: #ffffff;
33 | --text-big: 1.3rem;
34 | --text-medium: 1rem;
35 | --text-prettysmall: 0.9rem;
36 | --text-small: 0.8rem;
37 | --text-big-mobile: 1.1rem;
38 | --text-medium-mobile: 0.9rem;
39 | --main-font: "Roboto Mono", monospace;
40 | --font-main-button: 1rem;
41 | }
42 |
43 | html,
44 | body {
45 | margin: 0;
46 | font-family: var(--main-font);
47 | font-weight: 300;
48 | }
49 |
50 | a {
51 | color: var(--almost-black);
52 | opacity: 1;
53 | }
54 |
55 | a:hover {
56 | opacity: 0.6;
57 | }
58 |
59 | button {
60 | cursor: pointer;
61 | }
--------------------------------------------------------------------------------
/src/Untitled-1:
--------------------------------------------------------------------------------
1 | MacBook-Pro-van-Mick-3:migrations mickdegraaf$ yarn migrate:using-env
2 | yarn run v1.15.2
3 | $ USE_CONFIG=1 yarn migrate
4 | $ ts-node ./src/run.ts
5 | Starting Migrations
6 | Using DAI deployed at: 0xC4375B7De8af5a38a93548eb8453a498222C4fF2
7 | Deployed MockRep at: 0x917d6fa9af3c1b0cf75da59fbee859bcc353072c
8 | Using Fulcrum IDAI deployed at: 0xA1e58F3B1927743393b25f261471E1f2D3D9f0F6
9 | Deployed mockCDai at: 0x6b35a9136c8725547c0c6609a4b750c3cc69b0b8
10 | Deployed mockCEth at: 0x888f83ec4b084f77384a5d3782a36d4cb9665037
11 | Deployed mockCrep at: 0x33d77e422b0613cae24bf47db497c6d33221cf18
12 | Using Kyber network deployed at: 0x692f391bCc85cefCe8C237C01e1f636BbD70EA4D
13 | Deployed DDAI at: 0x9ee09f6564a5241508029f9451558dd58d3b957b
14 | Deployed CompoundRepayRecipe at: 0x4c917fcf98fe4dd9d3638e5285f4e725e3b63905
15 | Deployed MockRecipe: 0x572610cb3d00063fb59bb58807069003284228d6
16 | Deployed BuyTokenRecipe: 0xdd7abc70d52032ec0960cac6e7d9acf42f9acbfb
17 | Deployed buyPTokenRecipe: 0xfa60c27d0f894df8f1cf3b919be49099b09e6cac
18 | Deployed BuySynthRecipe: 0x12e9dab2980635b0037751679cd364b93b969de3
19 | ✨ Done in 58.79s.
20 | MacBook-Pro-van-Mick-3:migrations mickdegraaf$
--------------------------------------------------------------------------------
/src/Wallet.js:
--------------------------------------------------------------------------------
1 | import { EthereumHDWallet } from 'eth-dexcore-js';
2 | import DDAI from './class/ddai'
3 | import Rx from './class/Rx';
4 |
5 | const wallet = new EthereumHDWallet();
6 |
7 | wallet.Rx = new Rx(wallet);
8 | wallet.addPlugin('ddai', DDAI);
9 |
10 | window.Wallet = wallet;
11 |
12 |
13 | export { wallet as default }
--------------------------------------------------------------------------------
/src/class/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dexlab-io/ddai-frontend/518f8bdbafd56e29c68004093abcb8a5e038ede8/src/class/.DS_Store
--------------------------------------------------------------------------------
/src/class/Rx.js:
--------------------------------------------------------------------------------
1 | import find from 'lodash/find';
2 | import { Transaction } from 'eth-dexcore-js';
3 |
4 | class Rx {
5 |
6 | static TX_STATES = {
7 | BROADCASTED: 'Broadcasted',
8 | MINED: 'Mined',
9 | };
10 |
11 | static ACTIONS = {
12 | TX_BROADCASTED: '[TransactionPool] Tx Broadcasted',
13 | TX_MINED: '[TransactionPool] Tx Mined',
14 | };
15 |
16 | constructor(wallet) {
17 | this.W = wallet;
18 | this.poolMap = [];
19 | this.isPolling = false;
20 | this.interval = 2000;
21 | this.handle = null;
22 | this.listeners = [];
23 | }
24 |
25 | async checkPending() {
26 | console.log('Checking....', this.poolMap.filter( t => t.statusInternal !== Rx.TX_STATES.MINED ))
27 | this.poolMap
28 | // .filter( t => t.statusInternal !== Rx.TX_STATES.MINED )
29 | .forEach( async (tx, index) => {
30 | if(tx.statusInternal == Rx.TX_STATES.MINED) {
31 | return;
32 | }
33 | // We need full tx data so we both get the receipt and the tx
34 | // TODO get this data in parallel
35 | const resp = await this.W.web3.eth.getTransactionReceipt(tx.hash);
36 | const resp2 = await this.W.web3.eth.getTransaction(tx.hash);
37 | tx = {
38 | ...tx,
39 | ...resp,
40 | ...resp2
41 | };
42 | if(resp != null && resp.blockNumber > 0) {
43 | tx.statusInternal = Rx.TX_STATES.MINED;
44 | this.notify(Rx.ACTIONS.TX_MINED, tx);
45 | this.shouldStop();
46 | }
47 | this.poolMap[index] = tx;
48 | });
49 | }
50 |
51 | startPoller() {
52 | if(this.handle) return;
53 |
54 | this.checkPending();
55 | this.handle = setInterval(this.checkPending.bind(this), this.interval);
56 | }
57 |
58 | subscribe(listener) {
59 | this.listeners.push(listener);
60 |
61 | /**
62 | * Subscribe should return an unsubscribe function
63 | */
64 | return function unsubscribe() {
65 | const index = this.listeners.indexOf(listener);
66 | this.listeners.splice(index, 1);
67 | };
68 | }
69 |
70 | notify( action, tx ) {
71 | this.listeners.forEach( (l) => {
72 | l(action, tx);
73 | }, this);
74 | }
75 |
76 | shouldStop() {
77 | if(this.poolMap.filter( t => t.statusInternal !== Rx.TX_STATES.MINED ).length === 0) {
78 | clearInterval(this.handle);
79 | this.handle = null;
80 | }
81 | }
82 |
83 | get(txHash) {
84 | return find(this.poolMap, {'hash': txHash});
85 | }
86 |
87 | getAll() {
88 | return this.poolMap;
89 | }
90 |
91 | addFromModel(tx) {
92 | if(tx.hash && this.get(tx.hash)) return;
93 |
94 | tx.statusInternal = Rx.TX_STATES.BROADCASTED
95 |
96 | this.poolMap.push(tx);
97 | this.notify(Rx.ACTIONS.TX_BROADCASTED, tx);
98 |
99 | this.startPoller();
100 | }
101 |
102 | add(txHash, label="Unknown Tx") {
103 | if(this.get(txHash)) return;
104 |
105 | const tx = Transaction.build({
106 | statusInternal: Rx.TX_STATES.BROADCASTED,
107 | hash: txHash,
108 | label: label
109 | });
110 |
111 | this.poolMap.push(tx);
112 | this.notify(Rx.ACTIONS.TX_BROADCASTED, tx);
113 |
114 | this.startPoller();
115 | }
116 |
117 | async waitForTx(txHash) {
118 | return new Promise((resolve, reject) => {
119 | this.add(txHash);
120 | this.subscribe( (tx) => {
121 | if(tx.hash === txHash && tx.statusInternal === Rx.TX_STATES.MINED){
122 | resolve(tx);
123 | }
124 | })
125 | }
126 | );
127 | }
128 | }
129 |
130 | export default Rx;
--------------------------------------------------------------------------------
/src/class/artifacts/DDAIEvents.json:
--------------------------------------------------------------------------------
1 | {
2 | "schemaVersion": "2.0.0",
3 | "contractName": "DDAIEvents",
4 | "compilerOutput": {
5 | "abi": [],
6 | "evm": {
7 | "bytecode": {
8 | "linkReferences": {},
9 | "object": "0x6080604052348015600f57600080fd5b50603e80601d6000396000f3fe6080604052600080fdfea265627a7a72315820d08dfa3e2ed4df42baa0a3416ef729625e28e4ef46b118d75ac19fe92ab81bde64736f6c634300050b0032",
10 | "opcodes": "PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH1 0xF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x3E DUP1 PUSH1 0x1D PUSH1 0x0 CODECOPY PUSH1 0x0 RETURN INVALID PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x0 DUP1 REVERT INVALID LOG2 PUSH6 0x627A7A723158 KECCAK256 0xd0 DUP14 STATICCALL RETURNDATACOPY 0x2e 0xd4 0xdf TIMESTAMP 0xba LOG0 LOG3 COINBASE PUSH15 0xF729625E28E4EF46B118D75AC19FE9 0x2a 0xb8 SHL 0xde PUSH5 0x736F6C6343 STOP SDIV SIGNEXTEND STOP ORIGIN ",
11 | "sourceMap": "34:28:0:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;34:28:0;;;;;;;"
12 | }
13 | }
14 | },
15 | "sources": {
16 | "DDAI/DDAIEvents.sol": {
17 | "id": 0
18 | }
19 | },
20 | "sourceCodes": {
21 | "DDAI/DDAIEvents.sol": "pragma solidity >=0.4.21 <0.6.0;\n\ncontract DDAIEvents {\n \n}"
22 | },
23 | "sourceTreeHashHex": "0xa563113c8ecf3f21035e999d99fd50a3bd6da7683ac5d058747e231043d7a90a",
24 | "compiler": {
25 | "name": "solc",
26 | "version": "soljson-v0.5.11+commit.c082d0b4.js",
27 | "settings": {
28 | "optimizer": {
29 | "enabled": false
30 | },
31 | "outputSelection": {
32 | "*": {
33 | "*": [
34 | "abi",
35 | "evm.bytecode.object"
36 | ]
37 | }
38 | },
39 | "remappings": []
40 | }
41 | },
42 | "networks": {}
43 | }
--------------------------------------------------------------------------------
/src/class/artifacts/ICEToken.json:
--------------------------------------------------------------------------------
1 | {
2 | "schemaVersion": "2.0.0",
3 | "contractName": "ICEToken",
4 | "compilerOutput": {
5 | "abi": [
6 | {
7 | "constant": false,
8 | "inputs": [
9 | {
10 | "internalType": "address",
11 | "name": "_borrower",
12 | "type": "address"
13 | }
14 | ],
15 | "name": "repayBorrowBehalf",
16 | "outputs": [],
17 | "payable": true,
18 | "stateMutability": "payable",
19 | "type": "function"
20 | }
21 | ],
22 | "evm": {
23 | "bytecode": {
24 | "linkReferences": {},
25 | "object": "0x",
26 | "opcodes": "",
27 | "sourceMap": ""
28 | },
29 | "deployedBytecode": {
30 | "linkReferences": {},
31 | "object": "0x",
32 | "opcodes": "",
33 | "sourceMap": ""
34 | }
35 | }
36 | },
37 | "sources": {
38 | "interfaces/ICEToken.sol": {
39 | "id": 18
40 | }
41 | },
42 | "sourceCodes": {
43 | "interfaces/ICEToken.sol": "pragma solidity >=0.4.21 <0.6.0;\n\n// ICE ICE BABY Seperated this from ICToken to allow for repayBorrowBehalf.value()() without compiling errors\ninterface ICEToken {\n function repayBorrowBehalf(address _borrower) external payable;\n}"
44 | },
45 | "sourceTreeHashHex": "0xe0929c0b6e75753bfb63f657f5810d952917deb7d480d0e5ac4fcff138909c70",
46 | "compiler": {
47 | "name": "solc",
48 | "version": "soljson-v0.5.12+commit.7709ece9.js",
49 | "settings": {
50 | "optimizer": {
51 | "enabled": false
52 | },
53 | "outputSelection": {
54 | "*": {
55 | "*": [
56 | "abi",
57 | "evm.bytecode.object",
58 | "evm.bytecode.sourceMap",
59 | "evm.deployedBytecode.object",
60 | "evm.deployedBytecode.sourceMap"
61 | ]
62 | }
63 | },
64 | "remappings": [
65 | "openzeppelin-solidity=/Users/mickdegraaf/DDAI/node_modules/openzeppelin-solidity"
66 | ]
67 | }
68 | },
69 | "networks": {}
70 | }
--------------------------------------------------------------------------------
/src/class/artifacts/ICToken.json:
--------------------------------------------------------------------------------
1 | {
2 | "schemaVersion": "2.0.0",
3 | "contractName": "ICToken",
4 | "compilerOutput": {
5 | "abi": [
6 | {
7 | "constant": true,
8 | "inputs": [
9 | {
10 | "internalType": "address",
11 | "name": "_account",
12 | "type": "address"
13 | }
14 | ],
15 | "name": "borrowBalanceCurrent",
16 | "outputs": [
17 | {
18 | "internalType": "uint256",
19 | "name": "",
20 | "type": "uint256"
21 | }
22 | ],
23 | "payable": false,
24 | "stateMutability": "view",
25 | "type": "function"
26 | },
27 | {
28 | "constant": false,
29 | "inputs": [
30 | {
31 | "internalType": "address",
32 | "name": "_borrower",
33 | "type": "address"
34 | },
35 | {
36 | "internalType": "uint256",
37 | "name": "_repayAmount",
38 | "type": "uint256"
39 | }
40 | ],
41 | "name": "repayBorrowBehalf",
42 | "outputs": [
43 | {
44 | "internalType": "uint256",
45 | "name": "",
46 | "type": "uint256"
47 | }
48 | ],
49 | "payable": false,
50 | "stateMutability": "nonpayable",
51 | "type": "function"
52 | },
53 | {
54 | "constant": true,
55 | "inputs": [],
56 | "name": "underlying",
57 | "outputs": [
58 | {
59 | "internalType": "address",
60 | "name": "",
61 | "type": "address"
62 | }
63 | ],
64 | "payable": false,
65 | "stateMutability": "view",
66 | "type": "function"
67 | }
68 | ],
69 | "evm": {
70 | "bytecode": {
71 | "linkReferences": {},
72 | "object": "0x",
73 | "opcodes": "",
74 | "sourceMap": ""
75 | },
76 | "deployedBytecode": {
77 | "linkReferences": {},
78 | "object": "0x",
79 | "opcodes": "",
80 | "sourceMap": ""
81 | }
82 | }
83 | },
84 | "sources": {
85 | "interfaces/ICToken.sol": {
86 | "id": 19
87 | }
88 | },
89 | "sourceCodes": {
90 | "interfaces/ICToken.sol": "\npragma solidity >=0.4.21 <0.6.0;\n\ninterface ICToken {\n function repayBorrowBehalf(address _borrower, uint _repayAmount) external returns(uint256);\n function underlying() external view returns(address);\n function borrowBalanceCurrent(address _account) external view returns(uint256);\n}"
91 | },
92 | "sourceTreeHashHex": "0xaa32812d70b041da2cf26454799b249587f3854666fc5c80abd54953369c203a",
93 | "compiler": {
94 | "name": "solc",
95 | "version": "soljson-v0.5.12+commit.7709ece9.js",
96 | "settings": {
97 | "optimizer": {
98 | "enabled": false
99 | },
100 | "outputSelection": {
101 | "*": {
102 | "*": [
103 | "abi",
104 | "evm.bytecode.object",
105 | "evm.bytecode.sourceMap",
106 | "evm.deployedBytecode.object",
107 | "evm.deployedBytecode.sourceMap"
108 | ]
109 | }
110 | },
111 | "remappings": [
112 | "openzeppelin-solidity=/Users/mickdegraaf/DDAI/node_modules/openzeppelin-solidity"
113 | ]
114 | }
115 | },
116 | "networks": {}
117 | }
--------------------------------------------------------------------------------
/src/class/artifacts/IKyberNetwork.json:
--------------------------------------------------------------------------------
1 | {
2 | "schemaVersion": "2.0.0",
3 | "contractName": "IKyberNetwork",
4 | "compilerOutput": {
5 | "abi": [
6 | {
7 | "constant": false,
8 | "inputs": [
9 | {
10 | "internalType": "address",
11 | "name": "src",
12 | "type": "address"
13 | },
14 | {
15 | "internalType": "uint256",
16 | "name": "srcAmount",
17 | "type": "uint256"
18 | },
19 | {
20 | "internalType": "address",
21 | "name": "dest",
22 | "type": "address"
23 | },
24 | {
25 | "internalType": "address payable",
26 | "name": "destAddress",
27 | "type": "address"
28 | },
29 | {
30 | "internalType": "uint256",
31 | "name": "maxDestAmount",
32 | "type": "uint256"
33 | },
34 | {
35 | "internalType": "uint256",
36 | "name": "minConversionRate",
37 | "type": "uint256"
38 | },
39 | {
40 | "internalType": "address",
41 | "name": "walletId",
42 | "type": "address"
43 | }
44 | ],
45 | "name": "trade",
46 | "outputs": [
47 | {
48 | "internalType": "uint256",
49 | "name": "",
50 | "type": "uint256"
51 | }
52 | ],
53 | "payable": true,
54 | "stateMutability": "payable",
55 | "type": "function"
56 | }
57 | ],
58 | "evm": {
59 | "bytecode": {
60 | "linkReferences": {},
61 | "object": "0x",
62 | "opcodes": "",
63 | "sourceMap": ""
64 | },
65 | "deployedBytecode": {
66 | "linkReferences": {},
67 | "object": "0x",
68 | "opcodes": "",
69 | "sourceMap": ""
70 | }
71 | }
72 | },
73 | "sources": {
74 | "interfaces/IKyberNetwork.sol": {
75 | "id": 21
76 | }
77 | },
78 | "sourceCodes": {
79 | "interfaces/IKyberNetwork.sol": "pragma solidity >=0.4.21 <0.6.0;\n\ninterface IKyberNetwork {\n\n function trade(\n address src,\n uint srcAmount,\n address dest,\n address payable destAddress,\n uint maxDestAmount,\n uint minConversionRate,\n address walletId\n ) external payable returns(uint256);\n}"
80 | },
81 | "sourceTreeHashHex": "0x69da2b36bb0182bad32cdbfec0f1686cd5ab34d89419965d1f55acf9b688d92c",
82 | "compiler": {
83 | "name": "solc",
84 | "version": "soljson-v0.5.12+commit.7709ece9.js",
85 | "settings": {
86 | "optimizer": {
87 | "enabled": false
88 | },
89 | "outputSelection": {
90 | "*": {
91 | "*": [
92 | "abi",
93 | "evm.bytecode.object",
94 | "evm.bytecode.sourceMap",
95 | "evm.deployedBytecode.object",
96 | "evm.deployedBytecode.sourceMap"
97 | ]
98 | }
99 | },
100 | "remappings": [
101 | "openzeppelin-solidity=/Users/mickdegraaf/DDAI/node_modules/openzeppelin-solidity"
102 | ]
103 | }
104 | },
105 | "networks": {}
106 | }
--------------------------------------------------------------------------------
/src/class/artifacts/IMakerFeed.json:
--------------------------------------------------------------------------------
1 | {
2 | "schemaVersion": "2.0.0",
3 | "contractName": "IMakerFeed",
4 | "compilerOutput": {
5 | "abi": [
6 | {
7 | "constant": true,
8 | "inputs": [],
9 | "name": "read",
10 | "outputs": [
11 | {
12 | "internalType": "bytes32",
13 | "name": "",
14 | "type": "bytes32"
15 | }
16 | ],
17 | "payable": false,
18 | "stateMutability": "view",
19 | "type": "function"
20 | }
21 | ],
22 | "evm": {
23 | "bytecode": {
24 | "linkReferences": {},
25 | "object": "0x",
26 | "opcodes": "",
27 | "sourceMap": ""
28 | }
29 | }
30 | },
31 | "sources": {
32 | "interfaces/IMakerFeed.sol": {
33 | "id": 21
34 | }
35 | },
36 | "sourceCodes": {
37 | "interfaces/IMakerFeed.sol": "pragma solidity >=0.4.21 <0.6.0;\npragma experimental ABIEncoderV2;\n\ninterface IMakerFeed {\n function read() external view returns(bytes32);\n}"
38 | },
39 | "sourceTreeHashHex": "0x132393d7eddacc035ec0b10bd29d8051060a79d8bffbde0bd192349e68c31af3",
40 | "compiler": {
41 | "name": "solc",
42 | "version": "soljson-v0.5.11+commit.c082d0b4.js",
43 | "settings": {
44 | "optimizer": {
45 | "enabled": false
46 | },
47 | "outputSelection": {
48 | "*": {
49 | "*": [
50 | "abi",
51 | "evm.bytecode.object"
52 | ]
53 | }
54 | },
55 | "remappings": [
56 | "openzeppelin-solidity=/Users/mickdegraaf/DDAI/node_modules/openzeppelin-solidity"
57 | ]
58 | }
59 | },
60 | "networks": {}
61 | }
--------------------------------------------------------------------------------
/src/class/artifacts/IMoneyMarket.json:
--------------------------------------------------------------------------------
1 | {
2 | "schemaVersion": "2.0.0",
3 | "contractName": "IMoneyMarket",
4 | "compilerOutput": {
5 | "abi": [
6 | {
7 | "constant": true,
8 | "inputs": [
9 | {
10 | "internalType": "address",
11 | "name": "_owner",
12 | "type": "address"
13 | }
14 | ],
15 | "name": "assetBalanceOf",
16 | "outputs": [
17 | {
18 | "internalType": "uint256",
19 | "name": "",
20 | "type": "uint256"
21 | }
22 | ],
23 | "payable": false,
24 | "stateMutability": "view",
25 | "type": "function"
26 | },
27 | {
28 | "constant": false,
29 | "inputs": [
30 | {
31 | "internalType": "address",
32 | "name": "receiver",
33 | "type": "address"
34 | },
35 | {
36 | "internalType": "uint256",
37 | "name": "burnAmount",
38 | "type": "uint256"
39 | }
40 | ],
41 | "name": "burn",
42 | "outputs": [
43 | {
44 | "internalType": "uint256",
45 | "name": "loanAmountPaid",
46 | "type": "uint256"
47 | }
48 | ],
49 | "payable": false,
50 | "stateMutability": "nonpayable",
51 | "type": "function"
52 | },
53 | {
54 | "constant": false,
55 | "inputs": [],
56 | "name": "claimLoanToken",
57 | "outputs": [
58 | {
59 | "internalType": "uint256",
60 | "name": "claimedAmount",
61 | "type": "uint256"
62 | }
63 | ],
64 | "payable": false,
65 | "stateMutability": "nonpayable",
66 | "type": "function"
67 | },
68 | {
69 | "constant": false,
70 | "inputs": [
71 | {
72 | "internalType": "address",
73 | "name": "receiver",
74 | "type": "address"
75 | },
76 | {
77 | "internalType": "uint256",
78 | "name": "depositAmount",
79 | "type": "uint256"
80 | }
81 | ],
82 | "name": "mint",
83 | "outputs": [
84 | {
85 | "internalType": "uint256",
86 | "name": "mintAmount",
87 | "type": "uint256"
88 | }
89 | ],
90 | "payable": false,
91 | "stateMutability": "nonpayable",
92 | "type": "function"
93 | },
94 | {
95 | "constant": true,
96 | "inputs": [],
97 | "name": "supplyInterestRate",
98 | "outputs": [
99 | {
100 | "internalType": "uint256",
101 | "name": "",
102 | "type": "uint256"
103 | }
104 | ],
105 | "payable": false,
106 | "stateMutability": "view",
107 | "type": "function"
108 | },
109 | {
110 | "constant": true,
111 | "inputs": [],
112 | "name": "tokenPrice",
113 | "outputs": [
114 | {
115 | "internalType": "uint256",
116 | "name": "price",
117 | "type": "uint256"
118 | }
119 | ],
120 | "payable": false,
121 | "stateMutability": "view",
122 | "type": "function"
123 | }
124 | ],
125 | "evm": {
126 | "bytecode": {
127 | "linkReferences": {},
128 | "object": "0x",
129 | "opcodes": "",
130 | "sourceMap": ""
131 | },
132 | "deployedBytecode": {
133 | "linkReferences": {},
134 | "object": "0x",
135 | "opcodes": "",
136 | "sourceMap": ""
137 | }
138 | }
139 | },
140 | "sources": {
141 | "interfaces/IMoneyMarket.sol": {
142 | "id": 22
143 | }
144 | },
145 | "sourceCodes": {
146 | "interfaces/IMoneyMarket.sol": "pragma solidity >=0.4.21 <0.6.0;\n\ninterface IMoneyMarket {\n function mint(address receiver, uint256 depositAmount) external returns (uint256 mintAmount);\n\n function burn(\n address receiver,\n uint256 burnAmount)\n external\n returns (uint256 loanAmountPaid);\n\n function claimLoanToken()\n external\n returns (uint256 claimedAmount);\n\n // function donateAsset(\n // address tokenAddress)\n // external\n // returns (bool);\n\n function assetBalanceOf(\n address _owner)\n external\n view\n returns (uint256);\n\n function tokenPrice()\n external\n view\n returns (uint256 price);\n\n function supplyInterestRate()\n external\n view\n returns (uint256);\n}"
147 | },
148 | "sourceTreeHashHex": "0x4a31ae1f5b24e19e84f0a03d707277f4fa2aa74382575dd6c36263516e5a2626",
149 | "compiler": {
150 | "name": "solc",
151 | "version": "soljson-v0.5.12+commit.7709ece9.js",
152 | "settings": {
153 | "optimizer": {
154 | "enabled": false
155 | },
156 | "outputSelection": {
157 | "*": {
158 | "*": [
159 | "abi",
160 | "evm.bytecode.object",
161 | "evm.bytecode.sourceMap",
162 | "evm.deployedBytecode.object",
163 | "evm.deployedBytecode.sourceMap"
164 | ]
165 | }
166 | },
167 | "remappings": [
168 | "openzeppelin-solidity=/Users/mickdegraaf/DDAI/node_modules/openzeppelin-solidity"
169 | ]
170 | }
171 | },
172 | "networks": {}
173 | }
--------------------------------------------------------------------------------
/src/class/artifacts/IPToken.json:
--------------------------------------------------------------------------------
1 | {
2 | "schemaVersion": "2.0.0",
3 | "contractName": "IPToken",
4 | "compilerOutput": {
5 | "abi": [
6 | {
7 | "constant": false,
8 | "inputs": [
9 | {
10 | "internalType": "address",
11 | "name": "_receiver",
12 | "type": "address"
13 | },
14 | {
15 | "internalType": "address",
16 | "name": "_depositTokenAddress",
17 | "type": "address"
18 | },
19 | {
20 | "internalType": "uint256",
21 | "name": "_depositAmount",
22 | "type": "uint256"
23 | },
24 | {
25 | "internalType": "uint256",
26 | "name": "_maxPriceAllowed",
27 | "type": "uint256"
28 | }
29 | ],
30 | "name": "mintWithToken",
31 | "outputs": [
32 | {
33 | "internalType": "uint256",
34 | "name": "",
35 | "type": "uint256"
36 | }
37 | ],
38 | "payable": false,
39 | "stateMutability": "nonpayable",
40 | "type": "function"
41 | }
42 | ],
43 | "evm": {
44 | "bytecode": {
45 | "linkReferences": {},
46 | "object": "0x",
47 | "opcodes": "",
48 | "sourceMap": ""
49 | },
50 | "deployedBytecode": {
51 | "linkReferences": {},
52 | "object": "0x",
53 | "opcodes": "",
54 | "sourceMap": ""
55 | }
56 | }
57 | },
58 | "sources": {
59 | "interfaces/IPToken.sol": {
60 | "id": 23
61 | }
62 | },
63 | "sourceCodes": {
64 | "interfaces/IPToken.sol": "pragma solidity >=0.4.21 <0.6.0;\n\ninterface IPToken {\n\n function mintWithToken(\n address _receiver,\n address _depositTokenAddress,\n uint256 _depositAmount,\n uint256 _maxPriceAllowed\n )\n external\n returns (uint256);\n\n}"
65 | },
66 | "sourceTreeHashHex": "0xef1f44b78636632d377c9000862e131b1c53d84a00820a0b12bb698022aa4c14",
67 | "compiler": {
68 | "name": "solc",
69 | "version": "soljson-v0.5.12+commit.7709ece9.js",
70 | "settings": {
71 | "optimizer": {
72 | "enabled": false
73 | },
74 | "outputSelection": {
75 | "*": {
76 | "*": [
77 | "abi",
78 | "evm.bytecode.object",
79 | "evm.bytecode.sourceMap",
80 | "evm.deployedBytecode.object",
81 | "evm.deployedBytecode.sourceMap"
82 | ]
83 | }
84 | },
85 | "remappings": [
86 | "openzeppelin-solidity=/Users/mickdegraaf/DDAI/node_modules/openzeppelin-solidity"
87 | ]
88 | }
89 | },
90 | "networks": {}
91 | }
--------------------------------------------------------------------------------
/src/class/artifacts/IPriceFeed.json:
--------------------------------------------------------------------------------
1 | {
2 | "schemaVersion": "2.0.0",
3 | "contractName": "IPriceFeed",
4 | "compilerOutput": {
5 | "abi": [
6 | {
7 | "constant": true,
8 | "inputs": [],
9 | "name": "read",
10 | "outputs": [
11 | {
12 | "internalType": "bytes32",
13 | "name": "",
14 | "type": "bytes32"
15 | }
16 | ],
17 | "payable": false,
18 | "stateMutability": "view",
19 | "type": "function"
20 | }
21 | ],
22 | "evm": {
23 | "bytecode": {
24 | "linkReferences": {},
25 | "object": "0x",
26 | "opcodes": "",
27 | "sourceMap": ""
28 | },
29 | "deployedBytecode": {
30 | "linkReferences": {},
31 | "object": "0x",
32 | "opcodes": "",
33 | "sourceMap": ""
34 | }
35 | }
36 | },
37 | "sources": {
38 | "interfaces/IPriceFeed.sol": {
39 | "id": 24
40 | }
41 | },
42 | "sourceCodes": {
43 | "interfaces/IPriceFeed.sol": "pragma solidity >=0.4.21 <0.6.0;\n\ninterface IPriceFeed {\n function read() external view returns(bytes32);\n}"
44 | },
45 | "sourceTreeHashHex": "0x5ea133596d7534338c5d456edbe4b97c5aafcd4f7efede475e4f3b42ac5a3f4b",
46 | "compiler": {
47 | "name": "solc",
48 | "version": "soljson-v0.5.12+commit.7709ece9.js",
49 | "settings": {
50 | "optimizer": {
51 | "enabled": false
52 | },
53 | "outputSelection": {
54 | "*": {
55 | "*": [
56 | "abi",
57 | "evm.bytecode.object",
58 | "evm.bytecode.sourceMap",
59 | "evm.deployedBytecode.object",
60 | "evm.deployedBytecode.sourceMap"
61 | ]
62 | }
63 | },
64 | "remappings": [
65 | "openzeppelin-solidity=/Users/mickdegraaf/DDAI/node_modules/openzeppelin-solidity"
66 | ]
67 | }
68 | },
69 | "networks": {}
70 | }
--------------------------------------------------------------------------------
/src/class/artifacts/ISynthetix.json:
--------------------------------------------------------------------------------
1 | {
2 | "schemaVersion": "2.0.0",
3 | "contractName": "ISynthetix",
4 | "compilerOutput": {
5 | "abi": [
6 | {
7 | "constant": false,
8 | "inputs": [
9 | {
10 | "internalType": "bytes4",
11 | "name": "_sourceCurrencyKey",
12 | "type": "bytes4"
13 | },
14 | {
15 | "internalType": "uint256",
16 | "name": "_sourceAmount",
17 | "type": "uint256"
18 | },
19 | {
20 | "internalType": "bytes4",
21 | "name": "_destinationCurrencyKey",
22 | "type": "bytes4"
23 | },
24 | {
25 | "internalType": "address",
26 | "name": "_destinationAddress",
27 | "type": "address"
28 | }
29 | ],
30 | "name": "exchange",
31 | "outputs": [
32 | {
33 | "internalType": "bool",
34 | "name": "",
35 | "type": "bool"
36 | }
37 | ],
38 | "payable": false,
39 | "stateMutability": "nonpayable",
40 | "type": "function"
41 | }
42 | ],
43 | "evm": {
44 | "bytecode": {
45 | "linkReferences": {},
46 | "object": "0x",
47 | "opcodes": "",
48 | "sourceMap": ""
49 | },
50 | "deployedBytecode": {
51 | "linkReferences": {},
52 | "object": "0x",
53 | "opcodes": "",
54 | "sourceMap": ""
55 | }
56 | }
57 | },
58 | "sources": {
59 | "interfaces/ISynthetix.sol": {
60 | "id": 25
61 | }
62 | },
63 | "sourceCodes": {
64 | "interfaces/ISynthetix.sol": "pragma solidity >=0.4.21 <0.6.0;\n\ncontract ISynthetix {\n function exchange(\n bytes4 _sourceCurrencyKey,\n uint256 _sourceAmount,\n bytes4 _destinationCurrencyKey,\n address _destinationAddress\n ) external returns (bool);\n}"
65 | },
66 | "sourceTreeHashHex": "0x515c6bccbd3b7f08b98d50771520b1ddbff5af72a4d4d3c0eece2cce56e32292",
67 | "compiler": {
68 | "name": "solc",
69 | "version": "soljson-v0.5.12+commit.7709ece9.js",
70 | "settings": {
71 | "optimizer": {
72 | "enabled": false
73 | },
74 | "outputSelection": {
75 | "*": {
76 | "*": [
77 | "abi",
78 | "evm.bytecode.object",
79 | "evm.bytecode.sourceMap",
80 | "evm.deployedBytecode.object",
81 | "evm.deployedBytecode.sourceMap"
82 | ]
83 | }
84 | },
85 | "remappings": [
86 | "openzeppelin-solidity=/Users/mickdegraaf/DDAI/node_modules/openzeppelin-solidity"
87 | ]
88 | }
89 | },
90 | "networks": {}
91 | }
--------------------------------------------------------------------------------
/src/class/artifacts/ISynthetixDepot.json:
--------------------------------------------------------------------------------
1 | {
2 | "schemaVersion": "2.0.0",
3 | "contractName": "ISynthetixDepot",
4 | "compilerOutput": {
5 | "abi": [
6 | {
7 | "constant": false,
8 | "inputs": [],
9 | "name": "exchangeEtherForSynths",
10 | "outputs": [
11 | {
12 | "internalType": "uint256",
13 | "name": "",
14 | "type": "uint256"
15 | }
16 | ],
17 | "payable": true,
18 | "stateMutability": "payable",
19 | "type": "function"
20 | }
21 | ],
22 | "evm": {
23 | "bytecode": {
24 | "linkReferences": {},
25 | "object": "0x",
26 | "opcodes": "",
27 | "sourceMap": ""
28 | },
29 | "deployedBytecode": {
30 | "linkReferences": {},
31 | "object": "0x",
32 | "opcodes": "",
33 | "sourceMap": ""
34 | }
35 | }
36 | },
37 | "sources": {
38 | "interfaces/ISynthetixDepot.sol": {
39 | "id": 26
40 | }
41 | },
42 | "sourceCodes": {
43 | "interfaces/ISynthetixDepot.sol": "pragma solidity >=0.4.21 <0.6.0;\n\ninterface ISynthetixDepot {\n function exchangeEtherForSynths() external payable returns (uint256); // Returns the number of Synths (sUSD) received\n}"
44 | },
45 | "sourceTreeHashHex": "0xc108f55baf23db54adc5fe246ae7dbd7aa0362781c86c5a37a25a72ff3c7b610",
46 | "compiler": {
47 | "name": "solc",
48 | "version": "soljson-v0.5.12+commit.7709ece9.js",
49 | "settings": {
50 | "optimizer": {
51 | "enabled": false
52 | },
53 | "outputSelection": {
54 | "*": {
55 | "*": [
56 | "abi",
57 | "evm.bytecode.object",
58 | "evm.bytecode.sourceMap",
59 | "evm.deployedBytecode.object",
60 | "evm.deployedBytecode.sourceMap"
61 | ]
62 | }
63 | },
64 | "remappings": [
65 | "openzeppelin-solidity=/Users/mickdegraaf/DDAI/node_modules/openzeppelin-solidity"
66 | ]
67 | }
68 | },
69 | "networks": {}
70 | }
--------------------------------------------------------------------------------
/src/class/config.js:
--------------------------------------------------------------------------------
1 | export default {
2 | vehicles: [
3 | {label: '', component: ''}
4 | ]
5 | }
--------------------------------------------------------------------------------
/src/class/utils.js:
--------------------------------------------------------------------------------
1 | export default class U {
2 | static formatFiat = (value, separator=',', decimal='.') => {
3 | if(!value) return;
4 | try {
5 | const values = value.toString().replace(/^-/, '').split('.');
6 | const dollars = values[0];
7 | const cents = values[1];
8 | const groups = /(\d)(?=(\d{3})+\b)/g;
9 | return '#'.replace('#', `${dollars.replace(groups, '$1' + separator)}${cents ? decimal + cents : ''}`)
10 | } catch(e) {
11 | console.error(e);
12 | return value;
13 | }
14 | }
15 | }
--------------------------------------------------------------------------------
/src/components/Avatar.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | function Avatar(props) {
4 | const { image, size, alt, ...otherProps } = props;
5 |
6 | return (
7 |
8 |
9 |
10 | );
11 | }
12 |
13 | export default Avatar;
14 |
--------------------------------------------------------------------------------
/src/components/BackgroundImage.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import "./BackgroundImage.scss";
3 |
4 | function BackgroundImage(props) {
5 | return (
6 |
13 | );
14 | }
15 |
16 | export default BackgroundImage;
17 |
--------------------------------------------------------------------------------
/src/components/BackgroundImage.scss:
--------------------------------------------------------------------------------
1 | .BackgroundImage {
2 | content: "";
3 | background-image: var(--image);
4 | background-position: center center;
5 | background-size: cover;
6 | opacity: var(--opacity);
7 | top: 0;
8 | left: 0;
9 | bottom: 0;
10 | right: 0;
11 | position: absolute;
12 | z-index: 0;
13 | }
14 |
--------------------------------------------------------------------------------
/src/components/CardAPR.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import styled from "styled-components";
3 |
4 | const RowContainer = styled.span`
5 | display: flex;
6 | justify-content: space-between;
7 | width: 100%;
8 | padding: 2% 0;
9 | `;
10 | const Left = styled.span`
11 | display: flex;
12 | flex-grow: 1;
13 | text-align: left;
14 | font-weight: 700;
15 | align-items: center;
16 | `;
17 |
18 | const Right = styled.span`
19 | display: flex;
20 | flex-grow: 3;
21 | flex-direction: row-reverse;
22 | padding: 1.5% 0;
23 | align-items: center;
24 | font-weight: 700;
25 | color: #3bc5a6;
26 | `;
27 |
28 | const Rates = {
29 | currentRate: "15.2%"
30 | };
31 |
32 | const CardAPR = props => {
33 | return (
34 |
35 | APR
36 | {props.currentRate}%
37 |
38 | );
39 | };
40 |
41 | CardAPR.defaultProps = {
42 | currentRate: 0
43 | }
44 |
45 | export default CardAPR;
46 |
--------------------------------------------------------------------------------
/src/components/CardAction.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import styled from "styled-components";
3 | import PropTypes from "prop-types";
4 |
5 | const Container = styled.div`
6 | width: 47%;
7 | margin: 1%;
8 | display: flex;
9 | flex-direction: column;
10 | justify-content: space-between;
11 | align-items: center;
12 | font-size: var(--text-prettysmall);
13 | padding: 1% 2%;
14 | border-radius: 10px;
15 | background-color: #fff;
16 | border: 1px solid #827f7f;
17 | flex: 0 0 auto;
18 | min-height: 270px;
19 |
20 | @media (max-width: 800px) {
21 | width: 100%;
22 | margin: 2% 0;
23 | display: flex;
24 | flex: 0 0 auto;
25 | flex-direction: column;
26 | font-size: var(--text-prettysmall);
27 | border-radius: 10px;
28 | background-color: var(--white);
29 | height: auto;
30 | padding: 3% 3% 1% 3%;
31 |
32 | }
33 | `;
34 |
35 | const Heading = styled.h1`
36 | font-size: var(--text-big);
37 | text-align: center;
38 | margin-bottom: 10px;
39 | font-weight: 700;
40 | @media (max-width: 800px) {
41 | font-size: var(--text-big-mobile);
42 | }
43 | `;
44 |
45 | const SubHeading = styled.h2`
46 | font-size: var(--text-medium);
47 | font-weight: 300;
48 | margin-top: -10px;
49 | text-align: center;
50 | word-wrap: break-word;
51 |
52 | @media (max-width: 800px) {
53 | font-size: var(--text-medium-mobile);
54 | font-weight: 300;
55 | margin-top: -10px;
56 | }
57 | `;
58 |
59 | const BoldGreen = styled.span`
60 | font-weight: 700;
61 | color: #2edfb7;
62 | `;
63 |
64 | const ColorfulButton = styled.button`
65 | width: 100%;
66 | padding: 4% 10%;
67 | background-color: #000;
68 | color: #fff;
69 | text-align: center;
70 | font-size: var(--font-main-button);
71 | font-weight: 700;
72 | border-radius: 5px;
73 | margin: 0 0 10px 0;
74 | border: none;
75 | transition-property: background-color, color;
76 | transition-duration: 0.3s;
77 |
78 | :hover {
79 | opacity: 0.8;
80 | color: #fff;
81 | cursor: pointer;
82 | }
83 |
84 | :focus {
85 | outline: none;
86 | }
87 |
88 | :disabled {
89 | pointer-events: none;
90 | }
91 |
92 | @media (max-width: 800px) {
93 | display: flex;
94 | width: 100%;
95 | justify-content: center;
96 | margin: 2%;
97 | }
98 | `;
99 |
100 | const Image = styled.img`
101 | width: 292px;
102 | text-align: center;
103 | margin-bottom: 6%;
104 | @media (max-width: 800px) {
105 | width: 50%;
106 | }
107 | `;
108 |
109 | const CardAction = props => {
110 | return (
111 |
112 | {props.heading}
113 | {props.subheading}
114 |
115 | {
123 | if (props.disabled) {
124 | alert("Recipe disabled for this network");
125 | } else if (props.selected) {
126 | alert(`It's already selected :)`);
127 | } else {
128 | props.onPress();
129 | }
130 | }}
131 | >
132 | {props.disabled ? "DISABLED" : props.selected ? "Selected" : "Select"}
133 |
134 |
135 | );
136 | };
137 |
138 | export default CardAction;
139 |
--------------------------------------------------------------------------------
/src/components/CardAmount.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import styled from "styled-components";
3 | import { cta } from "../mixpanel";
4 |
5 |
6 | const RowContainer = styled.span`
7 | width: 100%;
8 | display: flex;
9 | justify-content: space-between;
10 | padding: 2% 0;
11 | @media (max-width: 800px) {
12 | flex-direction: column;
13 | }
14 | `;
15 | const Left = styled.span`
16 | display: flex;
17 | flex-grow: 1;
18 | text-align: left;
19 | font-weight: 700;
20 | align-items: center;
21 | `;
22 |
23 | const Right = styled.span`
24 | display: flex;
25 | flex-grow: 3;
26 | flex-direction: row-reverse;
27 | padding: 1.5% 0;
28 | align-items: center;
29 | `;
30 |
31 | const Form = styled.form`
32 | display: flex;
33 | justify-content: space-between;
34 | align-items: center;
35 | border: 1px solid #e0e0e0;
36 | border-radius: 5px;
37 | background-color: #f2f2f2;
38 | text-align: right;
39 | width: 100%;
40 |
41 | @media (max-width: 800px) {
42 | width: 80%;
43 | display: flex;
44 | flex-grow: 2;
45 | justify-content: space-between;
46 | align-items: center;
47 | border: 1px solid #e0e0e0;
48 | border-radius: 5px;
49 | background-color: #f2f2f2;
50 | text-align: right;
51 | }
52 | `;
53 |
54 | const Input = styled.input`
55 | display: flex;
56 | width: 74%;
57 | background-color: #f2f2f2;
58 | padding: 20px 15px 25px;
59 | border: none;
60 | font-size: var(--text-prettysmall);
61 |
62 | ::placeholder,
63 | ::-webkit-input-placeholder {
64 | font-family: var(--main-font);
65 | font-weight: 300;
66 | color: var(--light-black);
67 | }
68 |
69 | :focus {
70 | outline: none;
71 | }
72 |
73 | :focus::placeholder {
74 | color: transparent;
75 | }
76 | `;
77 |
78 | const ButtonMax = styled.button`
79 | display: flex;
80 | height: 30px;
81 | background: #000;
82 | color: white;
83 | font-size: var(--text-small);
84 | width: 20%;
85 | padding: 2% 3% 2% 6%;
86 | margin: 0 3% 0 1%;
87 | font-weight: 300;
88 | border-radius: 2px;
89 | transition-property: background-color;
90 | transition-duration: 0.3s;
91 |
92 | :hover {
93 | background-color: #505050;
94 | }
95 |
96 | :focus {
97 | outline: none;
98 | }
99 | `;
100 |
101 | const CardAmount = props => {
102 | return (
103 |
104 | Amount
105 |
106 |
127 |
128 |
129 | );
130 | };
131 |
132 | CardAmount.defaultProps = {
133 | onChange: () => {},
134 | maxValue: 0,
135 | amount: 0
136 | };
137 |
138 | export default CardAmount;
139 |
--------------------------------------------------------------------------------
/src/components/CardEarned.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import styled from "styled-components";
3 |
4 | const RowContainer = styled.span`
5 | display: flex;
6 | justify-content: space-between;
7 | width: 100%;
8 | padding: 2% 0;
9 | @media (max-width: 800px) {
10 | margin-top:20px;
11 | }
12 | `;
13 | const Left = styled.span`
14 | display: flex;
15 | text-align: left;
16 | font-weight: 700;
17 | align-items: center;
18 | max-width: 40%;
19 | `;
20 |
21 | const Right = styled.span`
22 | display: flex;
23 | flex-direction: row-reverse;
24 | padding: 1.5% 0;
25 | align-items: center;
26 | font-size: 18px;
27 | max-width: 50%;
28 | @media (max-width: 800px) {
29 | padding: 0;
30 | font-size: 19px;
31 | padding: 0;
32 | }
33 | `;
34 |
35 | const CardEarned = props => {
36 | return (
37 |
38 | Earned so far
39 | {parseFloat(props.investmentTokenAmount).toFixed(2)} dDAI
40 |
41 | );
42 | };
43 |
44 | CardEarned.defaultProps = {
45 | investmentTokenAmount: 0
46 | }
47 |
48 | export default CardEarned;
49 |
--------------------------------------------------------------------------------
/src/components/CardInvestmentAmount.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import styled from "styled-components";
3 |
4 | const RowContainer = styled.span`
5 | display: flex;
6 | justify-content: space-between;
7 | width: 100%;
8 | padding: 2% 0;
9 | `;
10 | const Left = styled.span`
11 | display: flex;
12 | flex-grow: 1;
13 | text-align: left;
14 | font-weight: 700;
15 | align-items: center;
16 | `;
17 |
18 | const Right = styled.span`
19 | display: flex;
20 | flex-grow: 3;
21 | flex-direction: row-reverse;
22 | padding: 1.5% 0;
23 | align-items: center;
24 | `;
25 |
26 | const CardInvestmentAmount = props => {
27 | return (
28 |
29 | Investment Amount
30 | {props.investmentTokenAmount} dDAI
31 |
32 | );
33 | };
34 |
35 | CardInvestmentAmount.defaultProps = {
36 | investmentTokenAmount: 0
37 | }
38 |
39 | export default CardInvestmentAmount;
40 |
--------------------------------------------------------------------------------
/src/components/CardInvestmentToken.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import styled from "styled-components";
3 |
4 | const RowContainer = styled.span`
5 | display: flex;
6 | justify-content: space-between;
7 | width: 100%;
8 | padding: 2% 0;
9 | `;
10 | const Left = styled.span`
11 | display: flex;
12 | flex-grow: 1;
13 | text-align: left;
14 | font-weight: 700;
15 | align-items: center;
16 | `;
17 |
18 | const Right = styled.span`
19 | display: flex;
20 | flex-grow: 3;
21 | flex-direction: row-reverse;
22 | padding: 1.5% 0;
23 | align-items: center;
24 | `;
25 |
26 | const CardInvestmentToken = props => {
27 | return (
28 |
29 | Investment Token
30 | {props.investmentTokenAmount} dDAI
31 |
32 | );
33 | };
34 |
35 | CardInvestmentToken.defaultProps = {
36 | investmentTokenAmount: 0
37 | }
38 |
39 | export default CardInvestmentToken;
40 |
--------------------------------------------------------------------------------
/src/components/CardOneButton.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import styled from "styled-components";
3 | import PropTypes from 'prop-types';
4 | import PrimaryButton from "./PrimaryButton";
5 |
6 | const RowContainer = styled.span`
7 | display: flex;
8 | justify-content: space-between;
9 | width: 100%;
10 | padding: 2% 0;
11 | `;
12 |
13 | const CardOneButton = props => {
14 | return (
15 |
16 | {props.label}
17 |
18 | );
19 | };
20 |
21 | CardOneButton.propTypes = {
22 | onPress: PropTypes.func,
23 | label: PropTypes.string
24 | };
25 |
26 | CardOneButton.defaultProps = {
27 | onPress: () => alert('Clicked'),
28 | label: 'INVEST',
29 | isDisabled: false,
30 | };
31 |
32 | export default CardOneButton;
33 |
--------------------------------------------------------------------------------
/src/components/CardRecap.js:
--------------------------------------------------------------------------------
1 | import React, { useContext } from "react";
2 | import styled from "styled-components";
3 | import { CardInvestmentToken, IF } from "../components";
4 | import CardAPR from "../components/CardAPR";
5 | import CardEarned from "../components/CardEarned";
6 | import CardInvestmentAmount from "./CardInvestmentAmount";
7 | import CardReward from "./CardReward";
8 | import CardTwoButtons from "./CardTwoButtons";
9 | import { Context } from "../context";
10 | import SecondaryButton from "./SecondaryButton";
11 | import InvestMoreDAI from "./InvestMoreDAI";
12 | import { useHistory } from "react-router-dom";
13 | import { cta } from "../mixpanel";
14 |
15 |
16 | const Center = styled.div`
17 | margin: 0 auto;
18 | `;
19 | const Container = styled.div`
20 | margin: 1% 6%;
21 | display: flex;
22 | flex-direction: column;
23 | font-size: var(--text-prettysmall);
24 | padding: 1% 2%;
25 | border-radius: 10px;
26 | border: 1px solid #827f7f;
27 | background-color: var(--white);
28 | flex: 0 0 auto;
29 |
30 | @media (max-width: 800px) {
31 | margin: 2%;
32 | padding: 1% 5%;
33 | display: flex;
34 | flex: 0 0 auto;
35 | flex-direction: column;
36 | font-size: var(--text-prettysmall);
37 | border-radius: 10px;
38 | background-color: var(--white);
39 | }
40 | `;
41 |
42 | const CardRecap = (props) => {
43 | const context = useContext(Context);
44 | const history = useHistory();
45 | const DDAI = context.DDAI;
46 |
47 | return (
48 |
49 |
50 | {
51 | cta({
52 | position: "overview",
53 | to: "/recipes",
54 | type: "button",
55 | label: "Change recipe"
56 | });
57 | history.push("/recipes")
58 | }}/>
59 |
60 |
61 |
62 | Loading ⏳
63 |
64 |
65 |
66 |
67 |
68 | {
71 | cta({
72 | position: "overview",
73 | type: "button",
74 | label: "Claim Interest"
75 | });
76 | props.onClaimInterest()
77 | }}
78 | secondButtonText="Withdraw"
79 | onSecondPress={ () => {
80 | cta({
81 | position: "overview",
82 | to: "/withdraw",
83 | type: "button",
84 | label: "Withdraw"
85 | });
86 | history.push("/withdraw")
87 | }}/>
88 |
89 | {
90 | cta({
91 | position: "overview",
92 | to: "/invest-more",
93 | type: "button",
94 | label: "Invest more DAI"
95 | });
96 | history.push("/invest-more");
97 | }} />
98 |
99 |
100 | );
101 | };
102 |
103 | export default CardRecap;
104 |
--------------------------------------------------------------------------------
/src/components/CardReward.js:
--------------------------------------------------------------------------------
1 | import React, { useContext } from "react";
2 | import styled from "styled-components";
3 | import { Link } from "react-router-dom";
4 | import { Context } from "../context";
5 | import CONF from '../config';
6 | import { cta } from "../mixpanel";
7 |
8 | const config = CONF[CONF.selectedNetwork];
9 |
10 |
11 | const RowContainer = styled.span`
12 | display: flex;
13 | justify-content: space-between;
14 | width: 100%;
15 | padding: 2% 0;
16 | @media (max-width: 800px) {
17 | }
18 | `;
19 | const Left = styled.span`
20 | display: flex;
21 | text-align: left;
22 | font-weight: 700;
23 | align-items: center;
24 | max-width: 40%;
25 | `;
26 |
27 | const Right = styled.span`
28 | display: flex;
29 | flex-direction: row-reverse;
30 | padding: 1.5% 0;
31 | align-items: center;
32 | font-size: 18px;
33 | max-width: 50%;
34 | @media (max-width: 800px) {
35 | padding: 0;
36 | font-size: 19px;
37 | padding: 0;
38 | }
39 | `;
40 |
41 | const Image = styled.img`
42 | height: 35px;
43 | `;
44 |
45 | const ButtonSmall = styled.button`
46 | padding: 3% 7%;
47 | background-color: #000;
48 | color: #fff;
49 | text-align: center;
50 | font-size: var(--font-small);
51 | font-weight: 700;
52 | border-radius: 2px;
53 | margin: 0;
54 | border: none;
55 | transition-property: background-color, color;
56 | transition-duration: 0.3s;
57 | margin-left: 2%;
58 | cursor: pointer;
59 |
60 |
61 | :hover {
62 | opacity: 0.8;
63 | color: #fff;
64 | cursor:pointer;
65 |
66 | }
67 |
68 | :focus {
69 | outline: none;
70 | }
71 |
72 | @media (max-width: 800px) {
73 | display: flex;
74 | justify-content: center;
75 | margin: 2% 0 2% 2%;
76 | }
77 | `;
78 |
79 | const CardReward = props => {
80 | const context = useContext(Context);
81 | console.log(context);
82 |
83 | return (
84 |
85 | Earning Reward in {context.selectedRecipe}
86 |
87 | {
88 | cta({
89 | position: "overview",
90 | to: "/recipes",
91 | type: "button",
92 | label: "Change recipe"
93 | });
94 | } }
95 | style={{color: "inherit"}} to="/recipes">Change
96 |
97 |
98 |
99 | );
100 | };
101 |
102 |
103 | export default CardReward;
104 |
--------------------------------------------------------------------------------
/src/components/CardSelectRecipe.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import styled from "styled-components";
3 | import CONF from '../config'
4 |
5 | const RowContainer = styled.span`
6 | width: 100%;
7 | display: flex;
8 | justify-content: space-between;
9 | padding: 2% 0;
10 | `;
11 | const Left = styled.span`
12 | display: flex;
13 | flex-grow: 1;
14 | text-align: left;
15 | font-weight: 700;
16 | align-items: center;
17 | `;
18 |
19 | const Right = styled.span`
20 | display: flex;
21 | flex-grow: 3;
22 | flex-direction: row-reverse;
23 | padding: 1.5% 0;
24 | align-items: center;
25 | `;
26 |
27 | const Form = styled.form`
28 | background-color: #f2f2f2;
29 | border: none;
30 | padding: 6% 3%;
31 | width: 100px;
32 |
33 | @media (max-width: 800px) {
34 | background-color: rgb(255, 255, 255);
35 | border: none;
36 | padding: 6% 0;
37 | max-width: 100px;
38 | }
39 | `;
40 |
41 | const Select = styled.select`
42 | border: 0px solid #f2f2f2;
43 | border-radius: 5px;
44 | background-color: #f2f2f2;
45 | text-align: right;
46 | width: 100px;
47 | font-size: var(--text-prettysmall);
48 |
49 | :focus {
50 | outline: none;
51 | }
52 | `;
53 |
54 | const Option = styled.option`
55 | background-repeat: no-repeat;
56 | background-position: cover;
57 | padding-left: 0px;
58 | `;
59 |
60 | const CardSelectRecipe = props => {
61 | return (
62 |
63 | Earning Reward
64 |
65 |
70 |
71 |
72 | );
73 | };
74 |
75 | CardSelectRecipe.defaultProps = {
76 | options: CONF[CONF.selectedNetwork].allowedOutputTokens,
77 | onChange: () => {}
78 | };
79 |
80 |
81 | export default CardSelectRecipe;
82 |
--------------------------------------------------------------------------------
/src/components/CardSelectedRecipe.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import styled from "styled-components";
3 |
4 | const RowContainer = styled.span`
5 | display: flex;
6 | justify-content: space-between;
7 | width: 100%;
8 | padding: 2% 0;
9 | `;
10 | const Left = styled.span`
11 | display: flex;
12 | flex-grow: 1;
13 | text-align: left;
14 | font-weight: 700;
15 | align-items: center;
16 | `;
17 |
18 | const Right = styled.span`
19 | display: flex;
20 | flex-grow: 3;
21 | flex-direction: row-reverse;
22 | padding: 1.5% 0;
23 | align-items: center;
24 | font-weight: 700;
25 | `;
26 |
27 | const Rates = {
28 | currentRate: "15.2%"
29 | };
30 |
31 | const CardSelectedRecipe = props => {
32 | return (
33 |
34 | Selected Recipe
35 | {props.selectedRecipe}
36 |
37 | );
38 | };
39 |
40 | CardSelectedRecipe.defaultProps = {
41 | selectedRecipe: "ETH"
42 | }
43 |
44 | export default CardSelectedRecipe;
45 |
--------------------------------------------------------------------------------
/src/components/CardTwoButtons.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import styled from "styled-components";
3 | import PrimaryButton from "./PrimaryButton";
4 |
5 | const RowContainer = styled.span`
6 | display: flex;
7 | justify-content: space-between;
8 | width: 100%;
9 | padding: 2% 0;
10 | `;
11 |
12 | const ButtonSpacer = styled.span`
13 | width: 4%;
14 | `;
15 |
16 | const CardTwoButtons = props => {
17 | return (
18 |
19 | {props.firstButtonText}
20 |
21 | {props.secondButtonText}
22 |
23 | );
24 | };
25 |
26 | export default CardTwoButtons;
27 |
--------------------------------------------------------------------------------
/src/components/CenteredColumns.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | function CenteredColumns(props) {
4 | return (
5 |
6 | {props.children}
7 |
8 | );
9 | }
10 |
11 | export default CenteredColumns;
12 |
--------------------------------------------------------------------------------
/src/components/Clients.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import "./Clients.scss";
3 |
4 | function Clients(props) {
5 | return (
6 |
7 | {props.items.map((item, index) => (
8 |
9 |
10 |

11 |
12 |
13 | ))}
14 |
15 | );
16 | }
17 |
18 | export default Clients;
19 |
--------------------------------------------------------------------------------
/src/components/Clients.scss:
--------------------------------------------------------------------------------
1 | .Clients {
2 | &__logo {
3 | margin: 0 12px;
4 | img {
5 | // Removes extra space under image
6 | vertical-align: bottom;
7 | }
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/src/components/ClientsSection.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import Section from "./Section";
3 | import SectionHeader from "./SectionHeader";
4 | import Clients from "./Clients";
5 |
6 | function ClientsSection(props) {
7 | return (
8 |
52 | );
53 | }
54 |
55 | export default ClientsSection;
56 |
--------------------------------------------------------------------------------
/src/components/ConnectW3Button.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import styled from "styled-components";
3 | import PropTypes from "prop-types";
4 | import { cta } from "../mixpanel";
5 |
6 |
7 | const Web3Button = styled.button`
8 | display: flex;
9 | flex-direction: row;
10 | align-items: center;
11 | background-color: #000;
12 | padding: 18px;
13 |
14 | /* display: inline-block;
15 | padding: 10%; */
16 | border-radius: 4px;
17 | transition-property: background-color, color;
18 | transition-duration: 0.3s;
19 | text-align: center;
20 | background: #F00093;
21 | border: solid 1px #fff;
22 | color: #fff;
23 |
24 | :hover {
25 | background-color: #000;
26 | color: #fff;
27 | }
28 |
29 | :focus {
30 | outline: none;
31 | }
32 |
33 | @media (max-width: 800px) {
34 | display: flex;
35 | justify-content: center;
36 | width: 100%;
37 | margin: 0;
38 | }
39 | `;
40 |
41 | const ConnectedMetamask = styled.span`
42 | display: flex;
43 | align-items: center;
44 | font-weight: 700;
45 | `;
46 |
47 | const ConnectW3Button = props => {
48 | return (
49 | {
50 | cta({
51 | position: "navbar",
52 | to: "Metamask",
53 | type: "button",
54 | label: "Connect Metamask"
55 | });
56 | props.onPress()
57 | }}>
58 |
59 | Connect Metamask
60 |
61 |
62 | );
63 | };
64 |
65 | ConnectW3Button.propTypes = {
66 | onPress: PropTypes.func
67 | };
68 |
69 | ConnectW3Button.defaultProps = {
70 | onPress: () => alert("Clicked")
71 | };
72 |
73 | export default ConnectW3Button;
74 |
--------------------------------------------------------------------------------
/src/components/Contact.js:
--------------------------------------------------------------------------------
1 | import React, { useState } from "react";
2 | import ContactForm from "./ContactForm";
3 | import contact from "./../util/contact.js";
4 |
5 | function Contact(props) {
6 | const [status, setStatus] = useState();
7 |
8 | const onSubmit = ({ name, email, message }) => {
9 | setStatus({ type: "pending" });
10 |
11 | contact.submit({ name, email, message }).then(() => {
12 | setStatus({
13 | type: "success",
14 | message: "Your message has been sent! We'll get back to you soon."
15 | });
16 | });
17 | };
18 | return (
19 |
26 | );
27 | }
28 |
29 | export default Contact;
30 |
--------------------------------------------------------------------------------
/src/components/ContactForm.js:
--------------------------------------------------------------------------------
1 | import React, { useState } from "react";
2 | import FormStatus from "./FormStatus";
3 | import FormField from "./FormField";
4 | import SectionButton from "./SectionButton";
5 |
6 | function ContactForm(props) {
7 | // State for input values
8 | const [name, setName] = useState("");
9 | const [email, setEmail] = useState("");
10 | const [message, setMessage] = useState("");
11 |
12 | // Whether to show errors
13 | // We set to true if they submit and there are errors.
14 | // We only show errors after they submit because
15 | // it's annoying to see errors while typing.
16 | const [showErrors, setShowErrors] = useState(false);
17 |
18 | // Error array we'll populate
19 | let errors = [];
20 |
21 | // Function for fetching error for a field
22 | const getError = field => {
23 | return errors.find(e => e.field === field);
24 | };
25 |
26 | // Function to see if field is empty
27 | const isEmpty = val => val.trim() === "";
28 |
29 | // Add error if email empty
30 | if (isEmpty(email)) {
31 | errors.push({
32 | field: "email",
33 | message: "Please enter an email"
34 | });
35 | }
36 |
37 | // Add error if message empty
38 | if (isEmpty(message)) {
39 | errors.push({
40 | field: "message",
41 | message: "Please enter a message"
42 | });
43 | }
44 |
45 | // Add error if name shown and empty
46 | if (props.showNameField) {
47 | if (isEmpty(name)) {
48 | errors.push({
49 | field: "name",
50 | message: "Please enter your name"
51 | });
52 | }
53 | }
54 |
55 | // Handle form submission
56 | const handleSubmit = e => {
57 | // If field errors then show them
58 | if (errors.length) {
59 | setShowErrors(true);
60 | } else {
61 | // Otherwise call onSubmit with form data
62 | if (props.onSubmit) {
63 | props.onSubmit({
64 | name,
65 | email,
66 | message
67 | });
68 | }
69 | }
70 | };
71 |
72 | return (
73 | <>
74 | {props.status && props.status.message && (
75 |
76 | )}
77 |
78 |
136 | >
137 | );
138 | }
139 |
140 | export default ContactForm;
141 |
--------------------------------------------------------------------------------
/src/components/ContactSection.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import Section from "./Section";
3 | import SectionHeader from "./SectionHeader";
4 | import Contact from "./Contact";
5 | import "./ContactSection.scss";
6 |
7 | function ContactSection(props) {
8 | return (
9 |
24 | );
25 | }
26 |
27 | export default ContactSection;
28 |
--------------------------------------------------------------------------------
/src/components/ContactSection.scss:
--------------------------------------------------------------------------------
1 | .ContactSection {
2 | &__container {
3 | max-width: 850px;
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/src/components/Footer.scss:
--------------------------------------------------------------------------------
1 | .FooterComponent {
2 | &__container {
3 | .menu-label {
4 | font-size: 1.275rem;
5 | font-weight: 600;
6 | text-transform: none;
7 | letter-spacing: 0;
8 | color: inherit;
9 | &.menu-label:not(:last-child) {
10 | margin-bottom: 0.6rem;
11 | }
12 | }
13 |
14 | .menu-list {
15 | margin-left: -0.75rem;
16 | //font-size: 1.1em;
17 | img {
18 | display: inline-block;
19 | vertical-align: middle;
20 | margin-right: 0.8rem;
21 | }
22 | // Slightly transparent hover background
23 | // makes it look good on any section background.
24 | a:hover {
25 | background-color: rgba(0, 0, 0, 0.05);
26 | }
27 | }
28 | }
29 |
30 | &__logo {
31 | width: 130px;
32 | }
33 |
34 | &__description {
35 | margin-top: 1rem;
36 | }
37 |
38 | &__copywrite {
39 | margin-top: 1rem;
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/components/FormField.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | function FormField(props) {
4 | return (
5 |
6 |
7 | {props.type === "textarea" && (
8 |
27 |
28 | {props.error &&
{props.error.message}
}
29 |
30 | );
31 | }
32 |
33 | export default FormField;
34 |
--------------------------------------------------------------------------------
/src/components/FormStatus.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | function FormStatus(props) {
4 | return (
5 |
12 | {props.message}
13 |
14 | );
15 | }
16 |
17 | export default FormStatus;
18 |
--------------------------------------------------------------------------------
/src/components/HeroSection.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import Section from "./Section";
3 | import SectionHeader from "./SectionHeader";
4 | import SectionButton from "./SectionButton";
5 |
6 | function HeroSection(props) {
7 | return (
8 |
9 |
10 |
16 |
17 |
22 | {props.buttonText}
23 |
24 |
25 |
26 |
27 | );
28 | }
29 |
30 | export default HeroSection;
31 |
--------------------------------------------------------------------------------
/src/components/If.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 |
3 | function IF (props) {
4 | return (
5 | <>
6 | { props.what ? props.children : null }
7 | >
8 | )
9 | }
10 |
11 | export default IF;
--------------------------------------------------------------------------------
/src/components/InvestMoreDAI.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from "react";
2 | import styled from "styled-components";
3 | import { cta } from "../mixpanel";
4 |
5 |
6 | const Container = styled.button`
7 | width: 88%;
8 | margin: 2% 6%;
9 | display: flex;
10 | flex-direction: row;
11 | justify-content: center;
12 | font-size: var(--text-prettysmall);
13 | padding: 1% 2%;
14 | border: 1px solid #827f7f;
15 | border-radius: 10px;
16 | background-color: var(--white);
17 | flex: 0 0 auto;
18 | cursor:pointer;
19 |
20 |
21 | @media (max-width: 800px) {
22 | width: 96%;
23 | margin: 0 2%;
24 | padding: 0 0;
25 | display: flex;
26 | padding: 10px 10px;
27 | flex: 0 0 auto;
28 | flex-direction: row;
29 | align-items: center;
30 | font-size: var(--text-prettysmall);
31 | border-radius: 10px;
32 | background-color: var(--white);
33 | }
34 | `;
35 |
36 | const Left = styled.span`
37 | display: flex;
38 | text-align: left;
39 | font-weight: 700;
40 | align-items: center;
41 | padding: 2% 5px;
42 | `;
43 |
44 | const Right = styled.span`
45 | display: flex;
46 | flex-direction: row;
47 | padding: 1.5% 0;
48 | align-items: center;
49 | padding: 2% 5px;
50 | `;
51 |
52 | const Image = styled.img`
53 | height: 20px;
54 | padding: 0 5px;
55 | `;
56 |
57 | const InvestMoreDAI = props => {
58 | return (
59 |
60 | {props.label}
61 |
62 |
63 |
64 |
65 |
66 |
67 | );
68 | };
69 |
70 | InvestMoreDAI.defaultProps = {
71 | label: "Invest More DAI",
72 | onPress: () => {
73 | cta({
74 | position: "conversation",
75 | to: "/invest",
76 | type: "button",
77 | label: "Invest More DAI"
78 | });
79 | }
80 | }
81 |
82 |
83 | export default InvestMoreDAI;
84 |
--------------------------------------------------------------------------------
/src/components/KyberWinner.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import styled from "styled-components";
3 |
4 | const Winner = styled.a`
5 | position: fixed;
6 | bottom: 10px;
7 | right: 10px;
8 | z-index: 9999;
9 | margin-top: 2px;
10 | width: 200px;
11 | @media (max-width: 800px) {
12 | display: none;
13 | }
14 | `;
15 |
16 | const KyberWinner = props => {
17 | return (
18 |
19 |
20 |
21 | );
22 | };
23 |
24 | export default KyberWinner;
25 |
--------------------------------------------------------------------------------
/src/components/LinkButton.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import styled from "styled-components";
3 | import PropTypes from 'prop-types';
4 | import PrimaryButton from "./PrimaryButton";
5 |
6 | const RowContainer = styled.span`
7 | display: flex;
8 | justify-content: space-between;
9 | width: 100%;
10 | padding: 0;
11 | `;
12 |
13 | const Link = styled.span`
14 | width: 100%;
15 | padding: 4% 10%;
16 | background-color: #f8e71c;
17 | color: #000;
18 | text-align: center;
19 | font-size: var(--font-main-button);
20 | font-weight: 700;
21 | border-radius: 5px;
22 | margin: 2% 0;
23 | border: none;
24 | transition-property: background-color, color;
25 | transition-duration: 0.3s;
26 |
27 | :label {
28 | color: #000;
29 | }
30 |
31 | :hover {
32 | background-color: #000;
33 | color: #f8e71c;
34 | }
35 |
36 | :focus {
37 | outline: none;
38 | }
39 |
40 | @media (max-width: 800px) {
41 | display: flex;
42 | justify-content: space-between;
43 | width: 100%;
44 | margin: 2% 0;
45 | }
46 | `;
47 |
48 |
49 | const LinkButton = props => {
50 | return (
51 |
52 |
53 |
54 | );
55 | };
56 |
57 | LinkButton.propTypes = {
58 | onPress: PropTypes.func,
59 | label: PropTypes.string
60 | };
61 |
62 | LinkButton.defaultProps = {
63 | onPress: () => alert('Clicked'),
64 | label: 'INVEST',
65 | isDisabled: false,
66 | };
67 |
68 | export default LinkButton;
69 |
--------------------------------------------------------------------------------
/src/components/Logo.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import styled from "styled-components";
3 | import { useHistory } from "react-router-dom";
4 |
5 | const LogoContainer = styled.div`
6 | display: flex;
7 | text-align: center;
8 | align-items: center;
9 | cursor: pointer;
10 | `;
11 |
12 | const Image = styled.img`
13 | height: 80px;
14 |
15 | @media (max-width: 800px) {
16 | width: 100px;
17 | }
18 | `;
19 |
20 | const Logo = props => {
21 | const history = useHistory();
22 |
23 | return (
24 |
25 | (history.push("/"))} src={`../images/logo.svg`} />
26 |
27 | );
28 | };
29 |
30 | export default Logo;
31 |
--------------------------------------------------------------------------------
/src/components/Navbar.js:
--------------------------------------------------------------------------------
1 | import React, { useState } from "react";
2 | import NavbarContainer from "./NavbarContainer";
3 | import { Link, useRouter } from "./../util/router.js";
4 | import SectionButton from "./SectionButton";
5 | import styled from "styled-components";
6 | import {link, cta} from "../mixpanel";
7 |
8 | const NavBarItem = styled.div``;
9 |
10 | const Logo = styled.img`
11 | height: 80px;
12 |
13 | @media (max-width: 1000px) {
14 | margin: 20px;
15 | }
16 | `;
17 |
18 | function Navbar(props) {
19 | const router = useRouter();
20 | const [menuOpen, setMenuOpen] = useState(false);
21 |
22 | return (
23 |
24 |
25 |
26 |
27 | link({position: 'navbar', to: '/', type: 'logo'})} to="/">
28 |
29 |
30 |
31 |
setMenuOpen(!menuOpen)}
34 | >
35 |
36 |
37 |
38 |
39 |
40 |
84 |
85 |
86 | );
87 | }
88 |
89 | export default Navbar;
90 |
--------------------------------------------------------------------------------
/src/components/NavbarContainer.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | function NavbarContainer(props) {
4 | return (
5 |
14 | );
15 | }
16 |
17 | export default NavbarContainer;
18 |
--------------------------------------------------------------------------------
/src/components/NotificationCard.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from "react";
2 | import styled from "styled-components";
3 | import PropTypes from "prop-types";
4 | import CONF from '../config';
5 |
6 | const Container = styled.div`
7 | width: 95%;
8 | margin: 1% 1%;
9 | display: flex;
10 | flex-direction: row;
11 | justify-content: flex-start;
12 | font-size: var(--text-prettysmall);
13 | padding: 1% 2%;
14 | border-radius: 10px;
15 | background-color: var(--white);
16 | flex: 0 0 auto;
17 |
18 | @media (max-width: 800px) {
19 | width: 100%;
20 | margin: 0 0%;
21 | padding: 0 5%;
22 | display: flex;
23 | flex: 0 0 auto;
24 | flex-direction: row;
25 | align-items: flex-start;
26 | font-size: var(--text-prettysmall);
27 | border-radius: 10px;
28 | background-color: var(--white);
29 | }
30 | `;
31 |
32 | const Left = styled.span`
33 | display: flex;
34 | align-items: flex-start;
35 | padding: 2% 5px;
36 | padding: 1.5% 0;
37 | `;
38 |
39 | const Right = styled.span`
40 | display: flex;
41 | flex-grow: 3;
42 | flex-direction: row;
43 | align-items: flex-start;
44 | padding: 2% 4%;
45 | text-align: left;
46 | font-weight: 700;
47 | `;
48 |
49 | const Image = styled.img`
50 | height: 23px;
51 | padding: 0 0;
52 | `;
53 |
54 | const A = styled.a`
55 | display: flex;
56 | flex-direction: row;
57 | align-items: flex-end;
58 | padding: 2% 0 2% 0;
59 | text-align: right;
60 | font-weight: 700;
61 | text-decoration: underline!important;
62 | `;
63 |
64 | const statusImages = {
65 | "pending": "../images/pending.svg",
66 | "rejected": "../images/rejected.svg",
67 | "approved": "../images/approved.svg"
68 | }
69 |
70 | const methods = {
71 | "0x40c10f19": {
72 | "name": "deposit",
73 | },
74 | "0x1e9a6950": {
75 | "name": "withdraw",
76 | },
77 | "0x21edf266": {
78 | "name": "claim interest"
79 | },
80 | "unknown": {
81 | "name": "unknown method",
82 | }
83 | }
84 |
85 | const NotificationCard = props => {
86 | let status;
87 | const { tx } = props;
88 |
89 | if(tx.status === true) {
90 | status = "approved"
91 | } else if(tx.status === false) {
92 | status = "rejected"
93 | } else {
94 | status = "pending"
95 | }
96 |
97 | let method;
98 | if(!tx.input || methods[tx.input.substring(0, 10)] == undefined){
99 | method = methods["unknown"];
100 | } else {
101 | method = methods[tx.input.substring(0, 10)];
102 | }
103 | console.log(method);
104 |
105 | let explorerURL;
106 | if(CONF.selectedNetwork == "mainnet") {
107 | explorerURL = `https://etherscan.io/tx/${tx.hash}`;
108 | } else {
109 | explorerURL = `https://${CONF.selectedNetwork}.etherscan.io/tx/${tx.hash}`;
110 | }
111 |
112 | return (
113 |
114 |
115 |
116 |
117 |
118 | Your {method.name} is {status}
119 | Etherscan
120 |
121 |
122 | );
123 | };
124 |
125 | NotificationCard.propTypes = {
126 | status: PropTypes.oneOf(["approved", "rejected", "pending"]).isRequired
127 | }
128 |
129 | export default NotificationCard;
--------------------------------------------------------------------------------
/src/components/NotificationDb.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from "react";
2 | import styled from "styled-components";
3 | import PropTypes from "prop-types";
4 | import CONF from '../config';
5 |
6 | const Container = styled.div`
7 | width: 95%;
8 | margin: 1% 1%;
9 | display: flex;
10 | flex-direction: row;
11 | justify-content: flex-start;
12 | font-size: var(--text-prettysmall);
13 | padding: 1% 2%;
14 | border-radius: 10px;
15 | background-color: var(--white);
16 | flex: 0 0 auto;
17 |
18 | @media (max-width: 800px) {
19 | width: 100%;
20 | margin: 0 0%;
21 | padding: 0 5%;
22 | display: flex;
23 | flex: 0 0 auto;
24 | flex-direction: row;
25 | align-items: flex-start;
26 | font-size: var(--text-prettysmall);
27 | border-radius: 10px;
28 | background-color: var(--white);
29 | }
30 | `;
31 |
32 | const Left = styled.span`
33 | display: flex;
34 | align-items: flex-start;
35 | padding: 2% 5px;
36 | padding: 1.5% 0;
37 | `;
38 |
39 | const Right = styled.span`
40 | display: flex;
41 | flex-grow: 3;
42 | flex-direction: row;
43 | align-items: flex-start;
44 | padding: 2% 4%;
45 | text-align: left;
46 | font-weight: 700;
47 | `;
48 |
49 | const Image = styled.img`
50 | height: 23px;
51 | padding: 0 0;
52 | `;
53 |
54 | const A = styled.a`
55 | display: flex;
56 | flex-direction: row;
57 | align-items: flex-end;
58 | padding: 2% 0 2% 0;
59 | text-align: right;
60 | font-weight: 700;
61 | text-decoration: underline!important;
62 | `;
63 |
64 | const statusImages = {
65 | "pending": "../images/pending.svg",
66 | "rejected": "../images/rejected.svg",
67 | "approved": "../images/approved.svg"
68 | }
69 |
70 | const methods = {
71 | "0x40c10f19": {
72 | "name": "deposit",
73 | },
74 | "0x1e9a6950": {
75 | "name": "withdraw",
76 | },
77 | "0x21edf266": {
78 | "name": "claim interest"
79 | },
80 | "unknown": {
81 | "name": "unknown method",
82 | }
83 | }
84 |
85 | const NotificationDB = props => {
86 | const log = props.log;
87 | let text = '';
88 |
89 | if(log.action.name === 'claim-kovan') {
90 | text = `You ${log.action.label} interest in ${log.selected_recipe}`
91 | } else if(log.action.name === 'set-recipe-kovan') {
92 | text = `You ${log.action.label} recipe to ${log.selected_recipe}`
93 | } else if(log.action.name === 'mint-kovan') {
94 | text = `You ${log.action.label} ${log.amount}Dai`
95 | } else if(log.action.name === 'burn-kovan') {
96 | text = `You ${log.action.label} ${log.amount}ÐÐai`
97 | }
98 |
99 | let explorerURL;
100 | if(CONF.selectedNetwork == "mainnet") {
101 | explorerURL = `https://etherscan.io/tx/${log.tx_hash}`;
102 | } else {
103 | explorerURL = `https://${CONF.selectedNetwork}.etherscan.io/tx/${log.tx_hash}`;
104 | }
105 |
106 | return (
107 |
108 |
109 |
110 |
111 |
112 | {text}
113 | Etherscan
114 |
115 |
116 | );
117 | };
118 |
119 | NotificationDB.defaultProps = {
120 | log: {
121 | action: {
122 | name: '',
123 | label:''
124 | }
125 | }
126 | }
127 |
128 | export default NotificationDB;
--------------------------------------------------------------------------------
/src/components/NotificationIcon.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import styled from "styled-components";
3 | import { link } from "../mixpanel";
4 |
5 |
6 | const LogoContainer = styled.div`
7 | cursor: pointer;
8 | @media (max-width: 800px) {
9 | position: absolute;
10 | top:20px;
11 | right:10px;
12 | }
13 |
14 | `;
15 |
16 | const Dot = styled.div`
17 | position: relative;
18 | top: 8px;
19 | left: 4px;
20 | color: #F8E71C;
21 | font-size: 48px;
22 | line-height: 0px;
23 | `;
24 |
25 | const Image = styled.img`
26 | height: 30px;
27 | `;
28 |
29 | const A = styled.a`
30 | `;
31 |
32 | const NotificationIcon = props => {
33 | return (
34 | {
35 | link({
36 | position: "navbar",
37 | to: "open notification drawer",
38 | type: "button",
39 | label: "Notification Icon"
40 | });
41 | props.onPress()
42 | }}>
43 | •
44 |
45 |
46 | );
47 | };
48 |
49 | export default NotificationIcon;
50 |
--------------------------------------------------------------------------------
/src/components/NotificationsDrawer.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import NotificationCard from './NotificationCard';
3 | import NotificationDB from './NotificationDb';
4 | import Drawer from '@material-ui/core/Drawer';
5 | import { Context } from '../context';
6 | import styled from "styled-components";
7 |
8 | const NoTransactionsText = styled.div`
9 | padding: 2%
10 | `;
11 |
12 |
13 | class NotificationsDrawer extends React.Component {
14 | render() {
15 | return(
16 |
17 | {this.context.logs == 0 && No transactions to track yet }
18 | {this.context.logs.map((log, index) => (
19 |
20 | ))}
21 | {/* {this.context.transactions.map((tx, index) => (
22 |
23 | ))} */}
24 |
25 | )
26 | }
27 | }
28 |
29 | NotificationsDrawer.contextType = Context;
30 |
31 | export default NotificationsDrawer;
--------------------------------------------------------------------------------
/src/components/PageHeading.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import styled from "styled-components";
3 |
4 | const PageHeadingContainer = styled.span`
5 | padding: 2% 4%;
6 | display: flex;
7 | flex-direction: column;
8 | justify-content: space-around;
9 | align-items: center;
10 | text-align: center;
11 | padding-bottom: 0px;
12 |
13 | @media (max-width: 800px) {
14 | width: 90%;
15 | padding: 2% 5%;
16 | text-align: justify;
17 | }
18 | `;
19 |
20 | const Heading = styled.h1`
21 | font-size: var(--text-big);
22 |
23 | @media (max-width: 800px) {
24 | font-size: var(--text-big-mobile);
25 | margin-bottom: 20px;
26 | }
27 | `;
28 |
29 | const SubHeading = styled.h2`
30 | font-size: var(--text-medium);
31 | font-weight: 300;
32 | margin-top: 5px;
33 |
34 | @media (max-width: 800px) {
35 | font-size: var(--text-medium-mobile);
36 | font-weight: 300;
37 |
38 | margin-bottom: 20px;
39 | }
40 | `;
41 |
42 | const PageHeading = props => {
43 | return (
44 |
45 | {props.heading}
46 | {props.subheading}
47 |
48 | );
49 | };
50 |
51 | PageHeading.defaultProps = {
52 | heading: "Invest now. Secure your principal. Get rewards in ETH or WBTC",
53 | subheading:
54 | "Smart Contract will automatically rebalance your investment between different protocols in order to maximise your returns."
55 | };
56 |
57 | export default PageHeading;
58 |
--------------------------------------------------------------------------------
/src/components/PrimaryButton.js:
--------------------------------------------------------------------------------
1 | import PropTypes from "prop-types";
2 | import React from "react";
3 | import styled from "styled-components";
4 |
5 | const ButtonMain = styled.button`
6 | width: 100%;
7 | padding: 4% 10%;
8 | background-color: #000;
9 | color: #FFF;
10 | text-align: center;
11 | font-size: var(--font-main-button);
12 | border-radius: 5px;
13 | margin: 0% 0;
14 | border: none;
15 | cursor: pointer;
16 | transition-property: background-color, color;
17 | transition-duration: 0.3s;
18 | font-weight: 700;
19 |
20 | :hover {
21 | opacity: 0.8;
22 | color: #fff;
23 | }
24 |
25 | :focus {
26 | outline: none;
27 | }
28 |
29 | @media (max-width: 800px) {
30 | display: flex;
31 | justify-content: center;
32 | width: 100%;
33 | margin: 2% 0;
34 | }
35 | `;
36 |
37 | const PrimaryButton = props => {
38 | return {props.children};
39 | };
40 |
41 | PrimaryButton.propTypes = {
42 | onPress: PropTypes.func,
43 | label: PropTypes.string
44 | };
45 |
46 | PrimaryButton.defaultProps = {
47 | onPress: () => alert("Clicked"),
48 | label: 'INVEST'
49 | };
50 |
51 | export default PrimaryButton;
52 |
--------------------------------------------------------------------------------
/src/components/SecondaryButton.js:
--------------------------------------------------------------------------------
1 | import PrimaryButton from "./PrimaryButton";
2 | import styled from "styled-components";
3 |
4 | const SecondaryButton = styled(PrimaryButton)`
5 | background-color: #f8e71c;
6 | color: #000;
7 | `
8 |
9 | export default SecondaryButton;
10 |
--------------------------------------------------------------------------------
/src/components/Section.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import BackgroundImage from "./BackgroundImage";
3 | import "./Section.scss";
4 |
5 | function Section(props) {
6 | const {
7 | color,
8 | size,
9 | backgroundImage,
10 | backgroundImageOpacity,
11 | children,
12 | // Passed to section element
13 | ...otherProps
14 | } = props;
15 |
16 | return (
17 |
25 | {backgroundImage && (
26 |
30 | )}
31 |
32 | {props.children}
33 |
34 | );
35 | }
36 |
37 | export default Section;
38 |
--------------------------------------------------------------------------------
/src/components/Section.scss:
--------------------------------------------------------------------------------
1 | .SectionComponent {
2 | margin-top: 0!important;
3 | // Add light border if two white
4 | // sections next to each other.
5 | .is-white + &.is-white {
6 | border-top: 1px solid #F0F0F0;
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/src/components/SectionButton.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | function SectionButton(props) {
4 | const {
5 | parentColor,
6 | size,
7 | state,
8 | fullWidth,
9 | // Passed to button element
10 | ...otherProps
11 | } = props;
12 |
13 | return (
14 |
39 | );
40 | }
41 |
42 | export default SectionButton;
43 |
--------------------------------------------------------------------------------
/src/components/SectionHeader.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import "./SectionHeader.scss";
3 |
4 | function SectionHeader(props) {
5 | return (
6 | <>
7 | {(props.title || props.subtitle) && (
8 |
31 | )}
32 | >
33 | );
34 | }
35 |
36 | export default SectionHeader;
37 |
--------------------------------------------------------------------------------
/src/components/SectionHeader.scss:
--------------------------------------------------------------------------------
1 | .SectionHeader {
2 | &__header {
3 | margin-bottom: 3rem;
4 |
5 | // Remove margin if nothing after header
6 | &:last-child {
7 | margin-bottom: 0;
8 | }
9 |
10 | // Added if props.centered is true
11 | &.is-centered {
12 | text-align: center;
13 | }
14 |
15 | .subtitle {
16 | max-width: 700px;
17 | // So we can have max-width but still
18 | // have alignment controlled by text-align.
19 | display: inline-block;
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/components/SimpleSnackbar.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { makeStyles } from '@material-ui/core/styles';
3 | import Button from '@material-ui/core/Button';
4 | import Snackbar from '@material-ui/core/Snackbar';
5 | import IconButton from '@material-ui/core/IconButton';
6 | import CloseIcon from '@material-ui/icons/Close';
7 | import styled from "styled-components";
8 |
9 |
10 | const useStyles = makeStyles(theme => ({
11 | close: {
12 | padding: theme.spacing(0.5),
13 | },
14 | }));
15 |
16 | export default function SimpleSnackbar() {
17 | const classes = useStyles();
18 | const [open, setOpen] = React.useState(false);
19 |
20 | const handleClick = () => {
21 | setOpen(true);
22 | };
23 |
24 | const handleClose = (event, reason) => {
25 | if (reason === 'clickaway') {
26 | return;
27 | }
28 |
29 | setOpen(false);
30 | };
31 |
32 | const Button = styled.button`
33 | border: none;
34 |
35 | :hover {
36 | opacity: 0.9;
37 | }
38 |
39 | :focus {
40 | outline: none;
41 | }
42 | `;
43 |
44 | const Dot = styled.div`
45 | position: relative;
46 | top: 6px;
47 | left: 6px;
48 | color: #F8E71C;
49 | font-size: 48px;
50 | line-height: 0px;
51 | `;
52 |
53 | const Image = styled.img`
54 | height: 30px;
55 | `;
56 |
57 | return (
58 |
59 |
63 | You successfully invested 100 DAI}
75 | action={[
76 |
83 |
84 | ,
85 | ]}
86 | />
87 |
88 |
89 | );
90 | };
91 |
92 |
93 |
--------------------------------------------------------------------------------
/src/components/Testimonials.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import CenteredColumns from "./CenteredColumns";
3 | import Avatar from "./Avatar";
4 | import "./Testimonials.scss";
5 |
6 | function Testimonials(props) {
7 | return (
8 |
9 | {props.items.map((item, index) => (
10 |
11 |
12 |
13 | "{item.quote}"
14 |
15 |
16 |
19 |
20 |
21 | {item.name}
22 |
23 |
24 | {item.company}
25 |
26 |
27 |
28 |
29 |
30 | ))}
31 |
32 | );
33 | }
34 |
35 | export default Testimonials;
36 |
--------------------------------------------------------------------------------
/src/components/Testimonials.scss:
--------------------------------------------------------------------------------
1 | .Testimonials {
2 | &__card {
3 | border-radius: 10px;
4 | padding: 25px 25px 65px 35px;
5 | font-size: 1.1rem;
6 | line-height: 1.5em;
7 | }
8 |
9 | &__author {
10 | margin-top: -40px;
11 | height: 80px;
12 | display: block;
13 | text-align: left;
14 | padding: 0 35px;
15 | position: relative;
16 | z-index: 0;
17 | }
18 |
19 | &__avatar-wrapper {
20 | position: absolute;
21 | top: 5px;
22 | right: 66%;
23 | }
24 |
25 | &__info {
26 | left: 38%;
27 | top: 9px;
28 | position: absolute;
29 | }
30 |
31 | &__company {
32 | margin-top: 13px;
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/components/TestimonialsSection.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import Section from "./Section";
3 | import SectionHeader from "./SectionHeader";
4 | import Testimonials from "./Testimonials";
5 |
6 | function TestimonialsSection(props) {
7 | return (
8 |
44 | );
45 | }
46 |
47 | export default TestimonialsSection;
48 |
--------------------------------------------------------------------------------
/src/components/TotBalance.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import styled from "styled-components";
3 |
4 | const TotBalanceContainer = styled.span`
5 | display: flex;
6 | flex-direction: row;
7 | align-items: center;
8 | background-color: #000;
9 | padding: 15px;
10 | border-radius: 4px;
11 |
12 | @media (max-width: 800px) {
13 | display: flex;
14 | justify-content: center;
15 | width: 100%;
16 | margin: 2% 0%;
17 | }
18 | `;
19 |
20 | const TotBalanceTitle = styled.span`
21 | display: flex;
22 | align-items: center;
23 | font-weight: 700;
24 | margin-right: 10px;
25 | color: #fff;
26 | `;
27 |
28 | const TotBalanceAmount = styled.span`
29 | display: flex;
30 | align-items: center;
31 | color: #fff;
32 | text-align: right;
33 | `;
34 |
35 | const OneDayChange = styled.span`
36 | margin-left: 6px;
37 | opacity: 1;
38 | color: #fff;
39 | font-size: var(--text-small);
40 | font-weight: 500;
41 | display: contents;
42 | `;
43 |
44 | const TotBalance = props => {
45 | return (
46 |
47 | {props.amount}
48 |
49 | );
50 | };
51 |
52 | TotBalance.defaultProps = {
53 | amount: "no wallet connected",
54 | OneDayChange: ""
55 | }
56 |
57 | export default TotBalance;
58 |
--------------------------------------------------------------------------------
/src/components/Warning.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import styled from "styled-components";
3 | import Config from '../config';
4 |
5 | const Container = styled.span`
6 | display: flex;
7 | flex-direction: row;
8 | justify-content: space-between;
9 | flex-wrap: nowrap;
10 | margin: 0;
11 | /* background-color: #FFDC61; */
12 | background-color: ${props => props.bg};
13 | border: 1px solid;
14 | border-color: ${props => props.border};
15 | padding: 6px 12px;
16 | border-radius: 20px;
17 | font-size: 0.8rem;
18 |
19 | @media (max-width: 800px) {
20 | padding: 10px 14px;
21 | margin: 14px 0 8px 0;
22 | font-size: 0.7rem;
23 | }
24 | `;
25 |
26 | const Content = styled.span`
27 | display: flex;
28 | flex-direction: row;
29 | flex-grow: 2;
30 | @media (max-width: 800px) {
31 | }
32 | `;
33 |
34 | const Message = styled.p`
35 |
36 | @media (max-width: 800px) {
37 |
38 | }
39 | `;
40 |
41 | const Link = styled.a`
42 | font-weight: 700;
43 | margin: 0 10px;
44 | text-decoration: underline;
45 | @media (max-width: 800px) {
46 | }
47 | `;
48 |
49 |
50 | const Close = styled.a`
51 | font-weight: 700;
52 | /* transform: rotate(45deg); */
53 | @media (max-width: 800px) {
54 | }
55 | `;
56 |
57 |
58 | class Warning extends React.Component {
59 |
60 | state = {
61 | open: true
62 | }
63 |
64 | handleClick = (e) => {
65 | this.setState({
66 | open: false
67 | });
68 | }
69 | render() {
70 | if(!this.state.open || !this.props.recipe.warning) {
71 | return (
72 | null
73 | )
74 | }
75 |
76 | const {bg, border, message, link} = this.props.recipe.warning;
77 |
78 | return (
79 |
80 |
81 | {message}
82 | Learn
83 |
84 | ✖️
85 |
86 | );
87 | }
88 |
89 | }
90 |
91 |
92 | export default Warning;
93 |
--------------------------------------------------------------------------------
/src/components/Web3Button.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import styled from "styled-components";
3 |
4 | const Web3ButtonConnected = styled.div`
5 | display: flex;
6 | flex-direction: row;
7 | justify-content: space-between;
8 | padding: 15px;
9 | background: #F00093;
10 | border: solid 1px #fff;
11 | color: #fff;
12 | border-radius: 5px;
13 |
14 |
15 | @media (max-width: 800px) {
16 | display: flex;
17 | justify-content: center;
18 | width: 100%;
19 | margin: 0;
20 | }
21 | `;
22 |
23 | const ConnectedAddress = styled.span`
24 | display: flex;
25 | align-items: center;
26 | font-weight: 700;
27 | margin-right: 10px;
28 | text-overflow: ellipsis;
29 | overflow: hidden;
30 | white-space: nowrap;
31 | max-width: 32rem;
32 |
33 | @media (max-width: 980px) {
34 | }
35 | `;
36 |
37 | const Web3Button = props => {
38 | return (
39 |
40 | {`${props.address.substring(0, 16)}...${props.address[props.address.length-1]}`} ❇️ Kovan
41 |
42 | );
43 | };
44 |
45 | Web3Button.propTypes = {
46 | address: ""
47 | };
48 |
49 | export default Web3Button;
50 |
--------------------------------------------------------------------------------
/src/components/index.js:
--------------------------------------------------------------------------------
1 | import IF from './If';
2 | import CardAmount from './CardAmount';
3 | import HeaderContainer from '../containers/HeaderContainer';
4 | import PageHeading from './PageHeading';
5 | import Logo from './Logo';
6 | import TotBalance from './TotBalance';
7 | import Web3Button from './Web3Button';
8 | import CardOneButton from './CardOneButton';
9 | import CardInvestmentToken from './CardInvestmentToken';
10 | import CardAction from './CardAction';
11 | import InvestMoreDAI from "./InvestMoreDAI";
12 | import SecondaryButton from './SecondaryButton';
13 | export {
14 | CardInvestmentToken,
15 | InvestMoreDAI,
16 | IF,
17 | CardAmount,
18 | CardAction,
19 | CardOneButton,
20 | HeaderContainer,
21 | PageHeading,
22 | Logo,
23 | TotBalance,
24 | Web3Button,
25 | SecondaryButton,
26 | }
--------------------------------------------------------------------------------
/src/containers/ActionCardContainer.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import styled from "styled-components";
3 | import { CardAction, IF, InvestMoreDAI } from "../components";
4 | import { Context } from "../context";
5 | import { withRouter } from "react-router-dom";
6 | import Wallet from "../Wallet";
7 | import DB from "../class/models/actions";
8 | import { cta, track } from "../mixpanel";
9 |
10 | import CONF from "../config";
11 | const config = CONF[CONF.selectedNetwork];
12 |
13 | const Container = styled.div`
14 | display: flex;
15 | flex-direction: row;
16 | align-items: center;
17 | justify-content: center;
18 | width: 100%;
19 | padding: 2% 4% 0 4%;
20 | overflow-x: scroll;
21 | overflow-y: hidden;
22 | flex-wrap: wrap;
23 | -webkit-overflow-scrolling: touch;
24 | @media (max-width: 800px) {
25 | padding: 2% 2% 0 2%;
26 |
27 | }
28 | `;
29 |
30 |
31 | class ActionCardContainer extends React.Component {
32 | handleRecipeSelected = key => async () => {
33 | const isLoading = this.context.DDAI.Apr == undefined;
34 | if (isLoading) {
35 | alert("Please install Metamask first");
36 | return;
37 | }
38 |
39 | this.context.setRecipe(key);
40 |
41 | if (this.context.DDAI.TotalBalance == 0 && this.context.DDAI.Stack === '0') {
42 |
43 | cta({
44 | position: "content",
45 | to: "/deposit",
46 | type: "card",
47 | recipe_key: key
48 | });
49 | this.props.history.push("/deposit");
50 | } else {
51 | cta({
52 | position: "content",
53 | to: "/overview",
54 | type: "card",
55 | recipe_key: key
56 | });
57 |
58 | const tx = await Wallet.ddai.setRecipes(key);
59 |
60 | track('Transaction Select Recipe', {
61 | recipe_key: key,
62 | ...tx
63 | });
64 |
65 | await DB.setRecipe(
66 | key,
67 | Wallet.getAddress(),
68 | tx.transactionHash,
69 | tx.status ? "approved" : "rejected"
70 | );
71 |
72 | this.props.history.push("/overview");
73 | }
74 | };
75 |
76 | componentDidMount() {
77 | this.loadSelectedRecipe();
78 | }
79 |
80 | loadSelectedRecipe = async () => {
81 | if(!Wallet.ddai) {
82 | // If Wallet.ddai is not available call this function again
83 | // TODO: Consider some "LoadingGate component" which waits till all stuff is available to keep this logic out of containers
84 | setTimeout(this.loadSelectedRecipe, 100);
85 | return;
86 | }
87 | const data = await Wallet.ddai.getState();
88 |
89 | this.context.setRecipe(data.Recipe);
90 | }
91 |
92 | goOverview() {
93 | cta({
94 | position: "content",
95 | to: "/overview",
96 | type: "button",
97 | label: "Go to overview",
98 | });
99 | this.props.history.push("/overview");
100 | }
101 |
102 | render() {
103 | const isLoading = this.context.DDAI.Apr == undefined;
104 |
105 | return (
106 |
107 | 0}>
108 | this.goOverview()}
110 | label={"Go to Overview"}
111 | />
112 |
113 |
114 | {Object.keys(config.recipes).map((key, index) => {
115 | const recipe = config.recipes[key];
116 | return (
117 |
130 | );
131 | })}
132 |
133 |
134 | );
135 | }
136 | }
137 | ActionCardContainer.contextType = Context;
138 |
139 | export default withRouter(ActionCardContainer);
140 |
--------------------------------------------------------------------------------
/src/containers/CardContainerTest.js:
--------------------------------------------------------------------------------
1 | import React ,{ Component } from "react";
2 | import styled from "styled-components";
3 |
4 | import { compareAddresses } from 'eth-dexcore-js';
5 | import find from 'lodash/find';
6 | import CardAmount from "../components/CardAmount";
7 | import CardInvestmentToken from "../components/CardInvestmentToken";
8 | import CardAPR from "../components/CardAPR";
9 | import CardOneButton from "../components/CardOneButton";
10 | import CardSelectRecipe from "../components/CardSelectRecipe";
11 | import { IF } from "../components";
12 | import Wallet from '../Wallet';
13 | import U from '../class/utils';
14 | import CONF from '../config';
15 |
16 | const config = CONF[CONF.selectedNetwork];
17 |
18 | const Container = styled.div`
19 | margin: 0 27%;
20 | display: flex;
21 | flex-direction: column;
22 | font-size: var(--text-prettysmall);
23 | padding: 1% 2%;
24 | border-radius: 10px;
25 | background-color: var(--white);
26 | flex: 0 0 auto;
27 |
28 | @media (max-width: 800px) {
29 | width: 100%;
30 | margin: 0 0%;
31 | padding: 1% 5%;
32 | display: flex;
33 | flex: 0 0 auto;
34 | flex-direction: column;
35 | font-size: var(--text-prettysmall);
36 | border-radius: 10px;
37 | background-color: var(--white);
38 | }
39 | `;
40 |
41 | class CardReceiveTokenContainerTest extends Component {
42 | state = {
43 | walletAddress: null,
44 | web3available: false,
45 | dDaiBalance: 0,
46 | APR: 0,
47 | amount: 0,
48 | balanceDAI: 0,
49 | needAllowance: false,
50 | selectedOutputToken: config.allowedOutputTokens[0].outputToken,
51 | activeRecipes: []
52 | }
53 |
54 | async componentDidMount() {
55 |
56 | Wallet.Rx.subscribe((action, data) => {
57 | this.refresh();
58 | });
59 |
60 |
61 | await Wallet.setWeb3();
62 | Wallet.Rx.notify("Connected", true);
63 |
64 | const supplyTx = await Wallet.ddai.mintAndSetRecipes(100, this.state.selectedOutputToken);
65 | await Wallet.ddai.distributeStack();
66 |
67 |
68 |
69 | setInterval(() => {
70 | this.refresh()
71 | }, 2000);
72 | }
73 |
74 | async onChangeAmount(e) {
75 | const amount = e.target.value;
76 | this.setState({
77 | amount
78 | });
79 |
80 | if(amount !== '' && Wallet.ddai) {
81 | const needAllowance = await Wallet.ddai.needAllowance(amount);
82 | this.setState({
83 | needAllowance
84 | });
85 | }
86 |
87 | }
88 |
89 | async refresh() {
90 | if(!Wallet.ddai) return;
91 |
92 | const data = await Wallet.ddai.getState();
93 |
94 | this.setState({
95 | dDaiBalanceLabel: U.formatFiat(data.Balance),
96 | dDaiBalance: data.Balance,
97 | balanceDAI: data.BalanceDAI,
98 | APR: data.Apr,
99 | activeRecipes: data.Recipes,
100 | needAllowance: data.needAllowance
101 | })
102 | }
103 |
104 | async validate() {
105 | if(!Wallet.ddai) return;
106 | this.submit();
107 | }
108 |
109 | async submit() {
110 | const supplyTx = await Wallet.ddai.mintAndSetRecipes(this.state.amount, this.state.selectedOutputToken);
111 | }
112 |
113 | async withdraw() {
114 | if(!Wallet.ddai) return;
115 | console.log('do things...');
116 | const supplyTx = await Wallet.ddai.redeem(this.state.amount);
117 | }
118 |
119 | async claim() {
120 | if(!Wallet.ddai) return;
121 | const supplyTx = await Wallet.ddai.distributeStack();
122 | }
123 |
124 | handleChangeToken(token) {
125 | this.setState({selectedOutputToken: token})
126 | }
127 |
128 | renderRecipe(r) {
129 | const tokenSymbol = find(config.allowedOutputTokens, (o) => compareAddresses(o.outputToken, (r.outputToken)) );
130 | return(
131 | One Recipe is active buying {tokenSymbol.label} for {r.benificiary}
132 | );
133 | }
134 |
135 | render() {
136 | const { dDaiBalance, activeRecipes, amount, needAllowance, balanceDAI, dDaiBalanceLabel } = this.state;
137 | const btnLabel = needAllowance ? 'ALLOW & INVEST' : 'INVEST';
138 | return (
139 |
140 | 0}>
141 | {activeRecipes.map(this.renderRecipe)}
142 |
143 |
144 | this.onChangeAmount(e)} />
145 |
146 |
147 |
148 |
149 |
150 |
151 | this.validate()} label={btnLabel} />
152 |
153 | 0}>
154 | this.withdraw()} label={'Withdraw'} />
155 |
156 |
157 | 0}>
158 | this.claim()} label={'Claim Interest'} />
159 |
160 |
161 |
162 | );
163 | }
164 | };
165 |
166 | export default CardReceiveTokenContainerTest;
167 |
--------------------------------------------------------------------------------
/src/containers/HeaderContainer.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from "react";
2 | import styled from "styled-components";
3 | import { TotBalance, Web3Button, Logo, IF } from "../components/";
4 | import ConnectW3Button from "../components/ConnectW3Button";
5 | import NotificationIcon from "../components/NotificationIcon";
6 | import U from "../class/utils";
7 | import Wallet from "../Wallet";
8 | import { withRouter } from "react-router-dom";
9 | import NotificationsDrawer from "../components/NotificationsDrawer";
10 | import { Context } from "../context";
11 |
12 | const Container = styled.div`
13 | width: 90%;
14 | margin: 0 5%;
15 | padding: 2% 0;
16 | display: flex;
17 | flex-direction: row;
18 | align-items: center;
19 | justify-content: flex-start;
20 | background-color: #fff;
21 |
22 | @media (max-width: 800px) {
23 | width: 100%;
24 | padding: 2%;
25 | margin: 0;
26 | display: flex;
27 | flex-direction: column;
28 | align-items: center;
29 | }
30 | `;
31 |
32 | const Mobilerow = styled.div`
33 | display: flex;
34 | width: 95%;
35 | margin: 0 5%
36 | flex-direction: row;
37 | align-items: center;
38 | justify-content: space-between;
39 |
40 | @media (max-width: 800px) {
41 | display: flex;
42 | flex-direction: column;
43 | justify-content: center;
44 | align-items: center;
45 | width: 100%;
46 | margin: 0 0;
47 | }
48 | `;
49 |
50 |
51 | class HeaderContainer extends Component {
52 | state = {
53 | walletAddress: null,
54 | web3available: false,
55 | amount: false
56 | };
57 |
58 | componentDidMount() {
59 | // Hacky coockie for auto login
60 | if (window.localStorage.login) {
61 | this.init();
62 | }
63 | }
64 |
65 | async init(buttonPressed) {
66 | // Checking if metamask is installed on browser and an address is active
67 | if (
68 | typeof window.ethereum === "undefined" ||
69 | typeof window.web3 === "undefined"
70 | ) {
71 | window.open("https://metamask.io", "_blank");
72 | } else {
73 | await Wallet.setWeb3();
74 |
75 | const connected = Wallet.getAddress() ? true : false;
76 | if(!connected) {
77 | window.alert(
78 | "No address is selected in Metamask, add an address to get started!"
79 | );
80 | return;
81 | }
82 |
83 |
84 | Wallet.Rx.notify("Connected", connected);
85 |
86 | this.setState({
87 | walletAddress: Wallet.getAddress(),
88 | web3available: connected
89 | });
90 |
91 | window.localStorage.login = true;
92 | }
93 | }
94 |
95 | render() {
96 | const { walletAddress, web3available } = this.state;
97 | const balance = this.context.DDAI.Balance || 0;
98 | const { pathname } = this.props.location;
99 | return pathname !== "/" ? (
100 |
101 |
102 |
103 |
112 |
113 |
114 |
115 |
116 |
117 |
118 | this.init(true)}
120 | label="Connect metamask"
121 | />
122 |
123 |
124 | {/* */}
125 |
126 |
127 |
128 | ) : null;
129 | }
130 | }
131 |
132 | HeaderContainer.contextType = Context;
133 |
134 | export default withRouter(HeaderContainer);
135 |
--------------------------------------------------------------------------------
/src/context/index.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | export const ContextDefaults = {
4 | selectedRecipe: "",
5 | DDAI: {},
6 | notificationDrawerOpen: false,
7 | transactions: [],
8 | closeNotificationsDrawer: () => {},
9 | toggleNotificationsDrawer: () => {},
10 | setRecipe: (value) => {
11 | this.selectedRecipe = value;
12 | },
13 | }
14 |
15 | export const Context = React.createContext(ContextDefaults)
--------------------------------------------------------------------------------
/src/history.js:
--------------------------------------------------------------------------------
1 | import { createBrowserHistory } from 'history';
2 |
3 | const instance = createBrowserHistory();
4 |
5 | export const navigateTo = path => instance.push(path);
6 |
7 | export default instance;
--------------------------------------------------------------------------------
/src/images/actionCardEth.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dexlab-io/ddai-frontend/518f8bdbafd56e29c68004093abcb8a5e038ede8/src/images/actionCardEth.png
--------------------------------------------------------------------------------
/src/images/dydx.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dexlab-io/ddai-frontend/518f8bdbafd56e29c68004093abcb8a5e038ede8/src/images/dydx.png
--------------------------------------------------------------------------------
/src/images/dydx.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/images/ethBG01.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dexlab-io/ddai-frontend/518f8bdbafd56e29c68004093abcb8a5e038ede8/src/images/ethBG01.png
--------------------------------------------------------------------------------
/src/images/ethBG02.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dexlab-io/ddai-frontend/518f8bdbafd56e29c68004093abcb8a5e038ede8/src/images/ethBG02.jpg
--------------------------------------------------------------------------------
/src/images/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dexlab-io/ddai-frontend/518f8bdbafd56e29c68004093abcb8a5e038ede8/src/images/favicon.ico
--------------------------------------------------------------------------------
/src/images/hamburger.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/images/icons/0x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dexlab-io/ddai-frontend/518f8bdbafd56e29c68004093abcb8a5e038ede8/src/images/icons/0x.png
--------------------------------------------------------------------------------
/src/images/icons/blackmoon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dexlab-io/ddai-frontend/518f8bdbafd56e29c68004093abcb8a5e038ede8/src/images/icons/blackmoon.png
--------------------------------------------------------------------------------
/src/images/icons/dai.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dexlab-io/ddai-frontend/518f8bdbafd56e29c68004093abcb8a5e038ede8/src/images/icons/dai.png
--------------------------------------------------------------------------------
/src/images/icons/eth.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dexlab-io/ddai-frontend/518f8bdbafd56e29c68004093abcb8a5e038ede8/src/images/icons/eth.png
--------------------------------------------------------------------------------
/src/images/icons/eth.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/images/icons/kyber.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dexlab-io/ddai-frontend/518f8bdbafd56e29c68004093abcb8a5e038ede8/src/images/icons/kyber.png
--------------------------------------------------------------------------------
/src/images/icons/loopring.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dexlab-io/ddai-frontend/518f8bdbafd56e29c68004093abcb8a5e038ede8/src/images/icons/loopring.png
--------------------------------------------------------------------------------
/src/images/icons/mana.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dexlab-io/ddai-frontend/518f8bdbafd56e29c68004093abcb8a5e038ede8/src/images/icons/mana.png
--------------------------------------------------------------------------------
/src/images/icons/odem.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dexlab-io/ddai-frontend/518f8bdbafd56e29c68004093abcb8a5e038ede8/src/images/icons/odem.png
--------------------------------------------------------------------------------
/src/images/little_arrow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dexlab-io/ddai-frontend/518f8bdbafd56e29c68004093abcb8a5e038ede8/src/images/little_arrow.png
--------------------------------------------------------------------------------
/src/images/logo.svg:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/src/images/notificationIcon.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/images/r_dai.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dexlab-io/ddai-frontend/518f8bdbafd56e29c68004093abcb8a5e038ede8/src/images/r_dai.png
--------------------------------------------------------------------------------
/src/images/wallet.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
5 | sans-serif;
6 | -webkit-font-smoothing: antialiased;
7 | -moz-osx-font-smoothing: grayscale;
8 | }
9 |
10 | code {
11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
12 | monospace;
13 | }
14 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import './index.css';
4 | import App from './App';
5 |
6 | ReactDOM.render(, document.getElementById('root'));
--------------------------------------------------------------------------------
/src/logo.svg:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/src/mixpanel.js:
--------------------------------------------------------------------------------
1 | import mixpanel from "mixpanel-browser";
2 | mixpanel.init("258c00efe344a14443b7912f828876f4", {debug: false});
3 | export default mixpanel;
4 |
5 | export const track = (event, obj) => {
6 | mixpanel.track(event, obj);
7 | }
8 |
9 | export const link = (obj) => {
10 | mixpanel.track('Click Link', obj);
11 | }
12 |
13 | export const cta = (obj) => {
14 | mixpanel.track('Click CTA', obj);
15 | }
--------------------------------------------------------------------------------
/src/pages/deposit/index.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import CardContainer from "../../containers/CardContainer";
3 |
4 |
5 | class Deposit extends React.Component {
6 |
7 | render() {
8 | return(
9 |
10 | )
11 | }
12 |
13 | }
14 |
15 | export default Deposit;
--------------------------------------------------------------------------------
/src/pages/invest/index.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import CardContainer from "../../containers/CardContainer";
3 | import {InvestMoreDAI} from "../../components";
4 | import { useHistory } from "react-router-dom";
5 | import { cta } from "../../mixpanel";
6 |
7 |
8 | const Invest = (props) => {
9 | const history = useHistory();
10 | return(
11 |
12 | {
13 | cta({
14 | position: "invest",
15 | to: "/overview",
16 | type: "button",
17 | label: "Go to Overview"
18 | });
19 | history.push("/overview")}}
20 | />
21 |
22 |
23 | )
24 | }
25 | export default Invest;
--------------------------------------------------------------------------------
/src/pages/landing/index.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import Navbar from "../../components/Navbar";
3 | import ClientsSection from "../../components/ClientsSection";
4 | import TestimonialsSection from "../../components/TestimonialsSection";
5 | import ContactSection from "../../components/ContactSection";
6 | import Footer from "../../components/Footer";
7 | import Conversation from "../../components/Conversation";
8 | import KyberWinner from "../../components/KyberWinner";
9 |
10 | function IndexPage(props) {
11 | return (
12 | <>
13 |
18 |
19 |
25 |
31 | {/* */}
39 |
46 |
47 | >
48 | );
49 | }
50 |
51 | export default IndexPage;
52 |
--------------------------------------------------------------------------------
/src/pages/overview/index.js:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import CardRecap from "../../components/CardRecap";
3 | import Wallet from "../../Wallet";
4 | import DB from '../../class/models/actions';
5 | import { async } from "q";
6 |
7 | class Overview extends React.Component {
8 | claimInterest = async () => {
9 | const tx = await Wallet.ddai.distributeStack();
10 | const selectedRecipe = await Wallet.ddai.getRecipe()
11 | DB.claim(selectedRecipe, Wallet.getAddress(), tx.transactionHash);
12 | }
13 |
14 | render() {
15 | return(
16 |
17 | )
18 | }
19 | }
20 |
21 | export default Overview;
--------------------------------------------------------------------------------
/src/pages/recipes/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { PageHeading, CardOneButton, IF } from "../../components";
3 | import ActionCardContainer from "../../containers/ActionCardContainer";
4 |
5 | class Recipes extends React.Component {
6 | componentDidMount() {
7 | window.scrollTo(0, 0);
8 | }
9 |
10 | render() {
11 | return(
12 |
16 | )
17 | }
18 |
19 | }
20 |
21 | export default Recipes;
--------------------------------------------------------------------------------
/src/pages/test/index.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import { PageHeading, CardOneButton, IF } from "../../components";
3 | import CardReceiveTokenContainerTest from "../../containers/CardContainerTest";
4 |
5 | class Test extends Component {
6 |
7 | state = {
8 | walletAddress: null,
9 | web3available: false,
10 | selectedVehicle: null,
11 | }
12 |
13 | render() {
14 | const {selectedVehicle} = this.state;
15 | return (
16 |
20 | );
21 | }
22 | }
23 |
24 | export default Test;
--------------------------------------------------------------------------------
/src/pages/withdraw/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { InvestMoreDAI } from "../../components";
3 | import CardContainer from "../../containers/CardContainer";
4 | import { useHistory } from "react-router-dom";
5 | import { cta } from "../../mixpanel";
6 |
7 |
8 |
9 | const Redeem = (props) => {
10 | const history = useHistory();
11 | return(
12 |
13 | {
14 | cta({
15 | position: "withdraw",
16 | to: "/overview",
17 | type: "button",
18 | label: "Invest more DAI"
19 | });
20 | history.push("/overview")
21 | }} />
22 | {
24 | cta({
25 | position: "withdraw",
26 | to: "/withdraw",
27 | type: "button",
28 | label: "Withdraw"
29 | });
30 | }}
31 | />
32 |
33 | )
34 | }
35 |
36 | export default Redeem;
--------------------------------------------------------------------------------
/src/react-app-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
--------------------------------------------------------------------------------
/src/routes.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import {
3 | Switch,
4 | Route,
5 | } from 'react-router-dom';
6 | import Test from './pages/test';
7 | import Recipes from './pages/recipes';
8 | import Invest from './pages/invest';
9 | import Deposit from './pages/deposit';
10 | import Overview from './pages/overview';
11 | import Withdraw from './pages/withdraw';
12 |
13 | import Landing from './pages/landing';
14 |
15 |
16 | export default function Routes() {
17 | return (
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 | );
30 | }
--------------------------------------------------------------------------------
/src/util/analytics.js:
--------------------------------------------------------------------------------
1 | import Analytics from "analytics";
2 | import googleAnalyticsPlugin from "@analytics/google-analytics";
3 | import { history } from "./router.js";
4 |
5 | // Initialize analytics and plugins
6 | // Documentation: https://getanalytics.io
7 | const analytics = Analytics({
8 | debug: process.env.NODE_ENV !== "production",
9 | plugins: [
10 | // 1) Create a Google Analytics account: https://bit.ly/2G1ZWNN
11 | // 2) Setup a property and add your trackingId below
12 | // 3) Uncomment the following code to start tracking
13 | /*
14 | googleAnalyticsPlugin({
15 | trackingId: ''
16 | })
17 | */
18 | ]
19 | });
20 |
21 | // Track initial pageview
22 | if (typeof window !== "undefined") {
23 | analytics.page();
24 | }
25 |
26 | // Track pageview on route change
27 | history.listen(() => {
28 | analytics.page();
29 | });
30 |
31 | export default analytics;
32 |
--------------------------------------------------------------------------------
/src/util/auth.js:
--------------------------------------------------------------------------------
1 | import React, { useState, useEffect, useContext, createContext } from "react";
2 | import queryString from "query-string";
3 | import fakeAuth from "fake-auth";
4 |
5 | /*
6 | Handles authentication with fakeAuth, a library for prototyping ...
7 | ... auth flows without need for a backend (everything is stored locally).
8 |
9 | [CHANGING AUTH SERVICES]: You can switch to another auth service ...
10 | ... like firebase, auth0, etc, by modifying the useProvideAuth() ...
11 | ... function below. Simply swap out the fakeAuth.function() calls for the ...
12 | ... correct ones for your given auth service.
13 | */
14 |
15 | const authContext = createContext();
16 |
17 | // Provider component that wraps your app and makes auth object ...
18 | // ... available to any child component that calls useAuth().
19 | export function ProvideAuth({ children }) {
20 | const auth = useProvideAuth();
21 | return {children};
22 | }
23 |
24 | // Hook for child components to get the auth object ...
25 | // ... update when it changes.
26 | export const useAuth = () => {
27 | return useContext(authContext);
28 | };
29 |
30 | // Provider hook that creates auth object and handles state
31 | function useProvideAuth() {
32 | const [user, setUser] = useState(null);
33 |
34 | const signin = (email, password) => {
35 | return fakeAuth.signin(email, password).then(user => {
36 | setUser(user);
37 | return user;
38 | });
39 | };
40 |
41 | const signup = (email, password) => {
42 | return fakeAuth.signup(email, password).then(user => {
43 | setUser(user);
44 | return user;
45 | });
46 | };
47 |
48 | const signout = () => {
49 | return fakeAuth.signout().then(() => {
50 | setUser(false);
51 | });
52 | };
53 |
54 | const sendPasswordResetEmail = email => {
55 | return fakeAuth.sendPasswordResetEmail(email);
56 | };
57 |
58 | const confirmPasswordReset = (password, code) => {
59 | // If no reset code passed in then fetch it automatically from current url.
60 | // [CHANGING AUTH SERVICES]: If not passing in the code as the second ...
61 | // ... arg above then make sure getFromQueryString() below has the ...
62 | // ... correct url parameter name (it might not be "code").
63 | const resetCode = code || getFromQueryString("code");
64 | return fakeAuth.confirmPasswordReset(password, resetCode);
65 | };
66 |
67 | // Subscribe to user on mount
68 | // [CHANGING AUTH SERVICES]: Not all auth services have a subscription ...
69 | // ... function so depending on your service you may need to remove ...
70 | // ... this effect and use the commented out one below.
71 | useEffect(() => {
72 | const unsubscribe = fakeAuth.onChange(user => {
73 | setUser(user);
74 | });
75 |
76 | // Call unsubscribe on cleanup
77 | return () => unsubscribe();
78 | }, []);
79 |
80 | // Fetch user on mount
81 | // [CHANGING AUTH SERVICES]: If your auth service doesn't have a subscribe ...
82 | // ... function then use this effect instead of the one above and modify ...
83 | // ... to work with your chosen auth service.
84 | /*
85 | useEffect(() => {
86 | yourAuthService.getUser().then(user => {
87 | setUser(user);
88 | });
89 | }, []);
90 | */
91 |
92 | return {
93 | user,
94 | signin,
95 | signup,
96 | signout,
97 | sendPasswordResetEmail,
98 | confirmPasswordReset
99 | };
100 | }
101 |
102 | const getFromQueryString = key => {
103 | return queryString.parse(window.location.search)[key];
104 | };
105 |
--------------------------------------------------------------------------------
/src/util/contact.js:
--------------------------------------------------------------------------------
1 | function submit(data) {
2 | return fetch("/api/contact", {
3 | method: "POST",
4 | headers: {
5 | "Content-Type": "application/json"
6 | },
7 | body: JSON.stringify(data)
8 | }).then(r => r.json());
9 | }
10 |
11 | export default { submit };
12 |
--------------------------------------------------------------------------------
/src/util/router.js:
--------------------------------------------------------------------------------
1 | /*
2 | A wrapper around React Router that adds a useRouter() hook so that any component
3 | can easily access params, location, history, and trigger navigation.
4 | Import from this file instead of react-router-dom directly.
5 | */
6 |
7 | import React, { useMemo, useEffect } from "react";
8 | import {
9 | Router as RouterOriginal,
10 | useParams,
11 | useLocation,
12 | useHistory,
13 | useRouteMatch
14 | } from "react-router-dom";
15 | import queryString from "query-string";
16 |
17 | // Use a custom history object and pass to Router so that we
18 | // can utilize history.listen() where needed (such as for pageview tracking)
19 | import { createBrowserHistory } from "history";
20 | export const history = createBrowserHistory();
21 |
22 | // Export our component
23 | // Includes custom history object and component for auto-scrolling to top
24 | export function Router({ children }) {
25 | return (
26 |
27 |
28 | {children}
29 |
30 | );
31 | }
32 |
33 | // Custom useRouter hook for getting route data and methods inside any component.
34 | // NOTE: This hook includes all React Router hooks, which can result in extra re-renders
35 | // in some cases. When needed, you can optimize performance by importing the specific hook
36 | // you need (such as useParams or useLocation) instead of this custom useRouter hook.
37 | export function useRouter() {
38 | const params = useParams();
39 | const location = useLocation();
40 | const history = useHistory();
41 | const match = useRouteMatch();
42 |
43 | // Return our custom router object
44 | // Memoize so that a new object is only returned if something changes
45 | return useMemo(() => {
46 | return {
47 | // For convenience add push(), replace(), pathname at top level
48 | push: history.push,
49 | replace: history.replace,
50 | pathname: location.pathname,
51 | // Merge params and parsed query string into single "query" object
52 | // so that they can be used interchangeably.
53 | // Example: /:topic?sort=popular -> { topic: "react", sort: "popular" }
54 | query: {
55 | ...queryString.parse(location.search), // Convert string to object
56 | ...params
57 | },
58 | // Include match, location, history objects so we have
59 | // access to extra React Router functionality if needed.
60 | match,
61 | location,
62 | history
63 | };
64 | }, [params, match, location, history]);
65 | }
66 |
67 | // Remove or customize if you need more advanced scroll behavior
68 | // and don't want to always scroll to top when location.pathname changes.
69 | function ScrollToTop() {
70 | const location = useLocation();
71 | useEffect(() => {
72 | window.scrollTo(0, 0);
73 | }, [location.pathname]);
74 | return null;
75 | }
76 |
77 | export {
78 | Route,
79 | Switch,
80 | Link,
81 | NavLink,
82 | useParams,
83 | useLocation,
84 | useHistory,
85 | useRouteMatch
86 | } from "react-router-dom";
87 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "lib": [
5 | "dom",
6 | "dom.iterable",
7 | "esnext"
8 | ],
9 | "allowJs": true,
10 | "skipLibCheck": true,
11 | "esModuleInterop": true,
12 | "allowSyntheticDefaultImports": true,
13 | "strict": false,
14 | "forceConsistentCasingInFileNames": false,
15 | "module": "esnext",
16 | "moduleResolution": "node",
17 | "resolveJsonModule": true,
18 | "isolatedModules": true,
19 | "noEmit": true,
20 | "jsx": "react"
21 | },
22 | "include": [
23 | "src"
24 | ]
25 | }
26 |
--------------------------------------------------------------------------------