Skip to content
This repository has been archived by the owner on Jun 29, 2021. It is now read-only.

Commit

Permalink
Merge pull request #2 from dhedge/dev-functional
Browse files Browse the repository at this point in the history
Add ability to Invest and Withdraw
  • Loading branch information
itsermin authored Dec 4, 2020
2 parents 5494f6c + b51e739 commit 93db5fe
Show file tree
Hide file tree
Showing 30 changed files with 4,156 additions and 141 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
.firebase

# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
Expand Down
5 changes: 5 additions & 0 deletions app/.firebaserc
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"projects": {
"default": "dhedge-gnosis-app"
}
}
49 changes: 49 additions & 0 deletions app/firebase.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
{
"hosting": {
"public": "build",
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
],
"rewrites": [
{
"source": "**",
"destination": "/index.html"
}
],
"headers": [
{
"source": "/service-worker.js",
"headers": [{
"key": "Cache-Control",
"value": "no-cache"
}]},
{
"source": "/manifest.json",
"headers": [{
"key": "Access-Control-Allow-Origin",
"value": "*"
},{
"key": "Access-Control-Allow-Methods",
"value": "GET"
},{
"key": "Access-Control-Allow-Headers",
"value": "X-Requested-With, content-type, Authorization"
}]
},{
"source": "**/*.@(svg|png)",
"headers": [{
"key": "Access-Control-Allow-Origin",
"value": "*"
},{
"key": "Access-Control-Allow-Methods",
"value": "GET"
},{
"key": "Access-Control-Allow-Headers",
"value": "X-Requested-With, content-type, Authorization"
}]
}
]
}
}
10 changes: 8 additions & 2 deletions app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,15 @@
"react-dom": "^16.13.1",
"react-scripts": "3.4.3",
"styled-components": "^5.1.1",
"typescript": "~4.0.2"
"typescript": "^4.1.2",
"web3": "^1.3.0"
},
"scripts": {
"start": "react-app-rewired start",
"build": "react-app-rewired build",
"test": "react-app-rewired test",
"eject": "react-scripts eject"
"eject": "react-scripts eject",
"lint": "tslint src/**/*.ts src/**/*.tsx --fix"
},
"eslintConfig": {
"extends": [
Expand All @@ -53,5 +55,9 @@
"resolutions": {
"**/@typescript-eslint/eslint-plugin": "^4.1.1",
"**/@typescript-eslint/parser": "^4.1.1"
},
"devDependencies": {
"tslint": "^6.1.3",
"tslint-react": "^5.0.0"
}
}
Binary file modified app/public/favicon.ico
Binary file not shown.
21 changes: 16 additions & 5 deletions app/public/logo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified app/public/logo192.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified app/public/logo512.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 3 additions & 3 deletions app/public/manifest.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"short_name": "Safe App",
"name": "dHedge",
"description": "Describe your Safe App here",
"short_name": "dHEDGE",
"name": "dHEDGE",
"description": "Decentralized asset management",
"iconPath": "logo.svg",
"icons": [
{
Expand Down
12 changes: 8 additions & 4 deletions app/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,15 @@ import { Loader, Title } from "@gnosis.pm/safe-react-components";
import SafeProvider from '@rmeissner/safe-apps-react-sdk';
import GlobalStyle from "./GlobalStyle";
import StepperContainer from "containers/StepperContainer";
import { GlobalState, initialState } from 'GlobalState'
import { GlobalState } from 'GlobalState'
import { StateInterface } from 'types/state.types';

interface IProps {
initialState: StateInterface;
}

const App: React.FC = () => {
const [state, setState] = useState(initialState)
const App: React.FC<IProps> = props => {
const [state, setState] = useState(props.initialState)
return (
<ThemeProvider theme={theme}>
<GlobalStyle />
Expand All @@ -27,4 +31,4 @@ const App: React.FC = () => {
)
}

export default App
export default App
16 changes: 10 additions & 6 deletions app/src/GlobalState.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
import React, { createContext } from 'react'
import { StateInterface } from 'types/state.types';
import Web3 from 'web3'
import initSdk from '@gnosis.pm/safe-apps-sdk';

interface StateInterface {
activeStep?: number
}
const web3 = new Web3(Web3.givenProvider);
const appsSdk = initSdk();

const initialState: StateInterface = {
activeStep: 0
activeStep: 0,
web3,
appsSdk
}

const initialContext: [StateInterface, React.Dispatch<React.SetStateAction<StateInterface>>] = [{}, () => ({})]
const initialContext: [StateInterface, React.Dispatch<React.SetStateAction<StateInterface>>] = [{ web3, appsSdk }, () => ({})]

const GlobalState = createContext(initialContext)

export { GlobalState, initialState }
export { GlobalState, initialState }
20 changes: 20 additions & 0 deletions app/src/GlobalStyle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,19 @@ const GlobalStyle = createGlobalStyle`
margin-bottom: 16px;
}
.mg-b-smaller {
margin-bottom: 4px;
}
.flex-row {
display: flex;
flex direction: row;
}
.flex-end {
justify-content: flex-end;
}
.select-width {
width: 80px;
}
Expand All @@ -53,6 +61,18 @@ const GlobalStyle = createGlobalStyle`
padding: 16px;
}
.padding-16 {
padding: 16px
}
.button-link {
background: none!important;
border: none;
padding: 0!important;
text-decoration: underline;
cursor: pointer;
}
@font-face {
font-family: 'Averta';
src: local('Averta'), local('Averta Bold'),
Expand Down
91 changes: 74 additions & 17 deletions app/src/components/Invest.tsx
Original file line number Diff line number Diff line change
@@ -1,54 +1,111 @@
import React, { useContext, useState } from 'react'
import { Button, TextField, Select } from "@gnosis.pm/safe-react-components"
import React, { useContext, useState, useEffect, useCallback } from 'react'
import { Button, TextField, Select, Text } from "@gnosis.pm/safe-react-components"
import { useSafe } from '@rmeissner/safe-apps-react-sdk'
import { Transaction } from 'types/state.types'
import { GlobalState } from 'GlobalState'
import { SYNTH_ADDRESS } from 'utils/const'
import { validNum } from 'utils/fn'
import { useContracts } from 'hooks/useContracts'

const items = [
{ id: '1', label: 'sUSD' }
];

const Invest: React.FC = () => {
const Invest: React.FC = () => {
const safe = useSafe()
const [state, setState] = useContext(GlobalState)
const { web3, poolContractAddress, appsSdk } = state
const [amount, setAmount] = useState('')
const [balance, setBalance] = useState('0')
const [activeItemId, setActiveItemId] = useState('1')
const onSubmit = () => {}
const { contractSusd, contractDhedge } = useContracts()

const handleSetId = (id: string) => setActiveItemId(id)
const handleCancel = () => setState({ ...state, activeStep: 0 })
const setAmountBalance = () => setAmount(balance);

const handleSetAmount = (e: React.ChangeEvent<HTMLInputElement>) => {
if (validNum(e.target.value)) {
if (parseFloat(e.target.value) <= parseFloat(balance)) {
setAmount(e.target.value)
} else if (e.target.value === '') {
setAmount('')
} else {
setAmountBalance()
}
}
}

const getBalance = useCallback(async () => {
const susdBalance = await contractSusd.methods.balanceOf(safe.info.safeAddress).call()
setBalance(web3.utils.fromWei(susdBalance));
}, [safe, web3, contractSusd])

const onSubmit = async () => {
const txs: Transaction[] = [{
to: SYNTH_ADDRESS.mainnet.SUSD || '',
value: '0',
data: contractSusd.methods.approve(
poolContractAddress,
web3.utils.toWei(amount)
).encodeABI(),
},
{
to: poolContractAddress || '',
value: '0',
data: contractDhedge.methods.deposit(
web3.utils.toWei(amount)
).encodeABI(),
}]
appsSdk.sendTransactions(txs);
}

useEffect(() => {
getBalance()
}, [getBalance])

return (
<form noValidate autoComplete="off" onSubmit={onSubmit}>
<>
<div className = "flex-row flex-end mg-b-smaller">
<button type="button" onClick={setAmountBalance} className="button-link">
<Text size="sm">{`Balance: ${balance}`}</Text>
</button>
</div>
<div className = "flex-row">
<div className="mg-r-small select-width">
<Select
items={items}
activeItemId={activeItemId}
onItemClick={(id) => {
setActiveItemId(id);
}}
onItemClick={handleSetId}
/>
</div>
<TextField
id="standard-amount"
label="Amount"
value={amount}
onChange={(e) => setAmount(e.target.value)}
onChange={handleSetAmount}
/>
</div>
<div className="confirm-button-container">
<div className="mg-r-small">
<Button
size = "md"
<Button
size = "md"
color = "secondary"
onClick = {() => setState({ ...state, activeStep: 0 })}
onClick = {handleCancel}
>
Cancel
</Button>
</div>
<Button
size = "md"
<Button
size = "md"
color = "primary"
onClick = {() => setState({ ...state, activeStep: 0 })}
onClick = {onSubmit}
disabled = {amount === '' || amount === '0'}
>
Invest
Approve and Invest
</Button>
</div>
</form>
</>
)
}

Expand Down
Loading

0 comments on commit 93db5fe

Please sign in to comment.