-

+
John Doe
@@ -44,15 +88,7 @@ function Creator() {
MY LINKS
@@ -61,7 +97,7 @@ function Creator() {
Lump.Finance is a platform that allows fans to financially support their
- favorite creators without spending any money. Through the magic of Ethereum and AAVE's Lending Pools, fans
+ favorite creators without spending any money. Through the magic of Ethereum and AAVE's Lending Pools, fans
can deposit funds into a pool which generates interest to be collected by the creator. At any point fans can withdraw nearly 100% of their deposit (some is lost from Ethereum transaction fees)
and creators can withdraw the accrued interest whenever needed.
@@ -69,11 +105,13 @@ function Creator() {
diff --git a/frontend/src/components/Dapp.tsx b/frontend/src/components/Dapp.tsx
index ec64a11..1b882f8 100644
--- a/frontend/src/components/Dapp.tsx
+++ b/frontend/src/components/Dapp.tsx
@@ -6,6 +6,18 @@ import "../css/resize.css";
import Creator from './Creator';
import Loading from './Loading';
import Particles from 'react-particles-js';
+import { ethers } from "ethers";
+import contractAddress from "../contracts/contract-address.json";
+import PoolFactoryArtifact from "../contracts/PoolFactory.json";
+import PoolAritfact from "../contracts/Pool.json";
+
+
+// ethereum.window fix
+declare global {
+ interface Window {
+ ethereum:any;
+ }
+}
/**
* Home page that contains a grid of decks, a search bar,
@@ -14,6 +26,13 @@ import Particles from 'react-particles-js';
export function Dapp() {
const[creatorLoaded, setCreatorLoaded] = useState(false);
+ const[connectedAddress, setConnectedAddress] = useState
("");
+ const[initialized, setInitialized] = useState(false);
+ const[provider, setProvider] = useState(undefined);
+ const[poolFactory, setPoolFactory] = useState(new ethers.Contract(
+ contractAddress.PoolFactory,
+ PoolFactoryArtifact.abi
+ ));
// parameters for particles
const params = {
@@ -36,20 +55,99 @@ export function Dapp() {
}
}
}
- }
+ }
+
+ // set dappp data
+ async function initialize(userAddress: string) {
+
+ setConnectedAddress(userAddress);
+
+ const web3Provider = new ethers.providers.Web3Provider(window.ethereum);
+
+ // initialize provider
+ setProvider(web3Provider);
+
+ // setup PoolFactory contract
+ const contract = new ethers.Contract(
+ contractAddress.PoolFactory,
+ PoolFactoryArtifact.abi,
+ web3Provider.getSigner(0)
+ );
+
+ // When, we initialize the contract using that provider and the token's
+ // artifact. You can do this same thing with your contracts.
+ setPoolFactory(contract);
+
+ let pools = await contract.getPools();
+ // console.log(pools);
+
+ let balance = await web3Provider.getBalance(userAddress);
+ // console.log(ethers.utils.formatEther(balance.toString()) + " " + ethers.constants.EtherSymbol);
+
+ // console.log(userAddress);
+ setInitialized(true);
+ }
+
+ // check if the dapp is ready
+ function dappReady() {
+ return(false);
+ }
+
+ // connect to the users wallet
+ async function connectWallet() {
+
+ // To connect to the user's wallet, we have to run this method.
+ // It returns a promise that will resolve to the user's address.
+ const [selectedAddress] = await window.ethereum.enable();
+
+ // Once we have the address, we can initialize the application.
+
+ // First we check the network
+ // if (!this._checkNetwork()) {
+ // return;
+ // }
+
+ // setup vars
+ await initialize(selectedAddress);
+
+
+ // listen for wallet account changes to update dapp vars
+ window.ethereum.on("accountsChanged", ([newAddress]: string[]) => {
+
+ // initialize with new address
+ if (newAddress !== undefined)
+ initialize(newAddress);
+
+ });
+
+ // We reset the dapp state if the network is changed
+ window.ethereum.on("networkChanged", ([networkId]: string[]) => {
+ console.log("network changed to: ", networkId);
+ });
+
+ }
+
// run on load
useEffect(() => {
- // get decks
- // getDecks();
+ // check for wallet
+ if (window.ethereum === undefined){
+ ;
+ }
+
+
+ if (connectedAddress === "") {
+ connectWallet();
+ } else {
+ setInitialized(true);
+ }
- setCreatorLoaded(true);
- }, []);
+ }, [connectedAddress]);
- if (!creatorLoaded) {
+ if (!initialized) {
return(
@@ -59,7 +157,7 @@ export function Dapp() {
return(
);
}
diff --git a/frontend/src/components/Dapp_template.jsx b/frontend/src/components/Dapp_template.jsx
index 0c8ee3e..9b5ca7f 100644
--- a/frontend/src/components/Dapp_template.jsx
+++ b/frontend/src/components/Dapp_template.jsx
@@ -75,7 +75,6 @@ export class Dapp extends React.Component {
//
// Note that we pass it a callback that is going to be called when the user
// clicks a button. This callback just calls the _connectWallet method.
- /*
if (!this.state.selectedAddress) {
return (
;
}
- */
// If everything is loaded, we render the application.
return (
diff --git a/frontend/src/css/creator.css b/frontend/src/css/creator.css
index 52f8a7b..e4484f4 100644
--- a/frontend/src/css/creator.css
+++ b/frontend/src/css/creator.css
@@ -2,6 +2,7 @@
width: 60%;
height: auto;
background-color: #EFEFEF;
+ background: #DCDCDC;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
@@ -27,6 +28,7 @@
-ms-flex-pack: justify;
justify-content: space-between;
padding: 10px 30px;
+ font-size: 15pt;
}
.creator-header .register {
@@ -86,8 +88,10 @@
-webkit-box-pack: justify;
-ms-flex-pack: justify;
justify-content: space-between;
- padding: 10px;
- margin-bottom: 30px;
+ align-items: center;
+ padding: 20px;
+ padding-bottom: 50px;
+ background: #E5E5E5;
}
.creator-middle .middle-section {
@@ -107,10 +111,10 @@
}
.creator-middle .middle-text {
- background: #E5E5E5;
+ background: #dbdbdb;
padding: 5px;
- min-height: 170px;
- max-height: 170px;
+ min-height: 200px;
+ max-height: 200px;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
@@ -160,13 +164,17 @@
}
.creator-actions {
- height: 40px;
+ height: 80px;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: column;
+ flex-direction: column;
width: 100%;
-webkit-box-pack: justify;
-ms-flex-pack: justify;
@@ -181,12 +189,17 @@
}
.creator-actions .button-wrapper {
- -webkit-box-flex: 2;
- -ms-flex: 2;
- flex: 2;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
+ width: 100%;
+}
+
+.creator-actions .input-wrapper {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ width: 100%;
}
.creator-actions button {
@@ -224,14 +237,15 @@
-ms-flex-align: center;
align-items: center;
font-size: 11pt;
- background-color: #DEDEDE;
- color: #757575;
+ background-color: #c8c8c8;
+ color: #000;
}
.creator-actions input {
height: 100%;
border: none;
- padding-left: 20px;
- background-color: #DEDEDE;
+ padding: 0 20px;
+ background-color: #c8c8c8;
+ min-width: 70%;
}
/*# sourceMappingURL=creator.css.map */
\ No newline at end of file
diff --git a/frontend/src/css/creator.css.map b/frontend/src/css/creator.css.map
index ae76b34..150ef1e 100644
--- a/frontend/src/css/creator.css.map
+++ b/frontend/src/css/creator.css.map
@@ -1,6 +1,6 @@
{
"version": 3,
- "mappings": "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",
+ "mappings": "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",
"sources": [
"creator.scss"
],
diff --git a/frontend/src/css/creator.scss b/frontend/src/css/creator.scss
index 02ebc57..e1c762d 100644
--- a/frontend/src/css/creator.scss
+++ b/frontend/src/css/creator.scss
@@ -2,6 +2,7 @@
width: 60%;
height: auto;
background-color: #EFEFEF;
+ background: #DCDCDC;
display: flex;
flex-direction: column;
box-shadow: 5px 5px 15px 5px rgba(0,0,0,0.17);
@@ -15,6 +16,7 @@
color: white;
justify-content: space-between;
padding: 10px 30px;
+ font-size: 15pt;
.register {
color: white;
@@ -58,8 +60,10 @@
display: flex;
align-items: center;
justify-content: space-between;
- padding: 10px;
- margin-bottom: 30px;
+ align-items: center;
+ padding: 20px;
+ padding-bottom: 50px;
+ background: #E5E5E5;
.middle-section {
display: flex;
@@ -69,10 +73,10 @@
}
.middle-text {
- background: #E5E5E5;
+ background: rgb(219, 219, 219);
padding: 5px;
- min-height: 170px;
- max-height: 170px;
+ min-height: 200px;
+ max-height: 200px;
display: flex;
justify-content: center;
margin: 0 15px;
@@ -114,9 +118,10 @@
}
.creator-actions {
- height: 40px;
+ height: 80px;
display: flex;
align-items: center;
+ flex-direction: column;
width: 100%;
justify-content:space-between;
@@ -126,8 +131,13 @@
}
.button-wrapper{
- flex: 2;
display: flex;
+ width: 100%;
+ }
+
+ .input-wrapper {
+ display: flex;
+ width: 100%;
}
button{
@@ -153,14 +163,16 @@
justify-content: center;
align-items: center;
font-size: 11pt;
- background-color: #DEDEDE;
- color: #757575;
+ background-color: #c8c8c8;
+ color: #000;
}
input{
height: 100%;
+ // border: 2px solid #818181;
border: none;
- padding-left: 20px;
- background-color: #DEDEDE;
+ padding: 0 20px;
+ background-color: #c8c8c8;
+ min-width: 70%;
}
}
\ No newline at end of file