diff --git a/package-lock.json b/package-lock.json index df02088..34da2d4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1903,6 +1903,15 @@ "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==" }, + "@superfluid-finance/js-sdk": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@superfluid-finance/js-sdk/-/js-sdk-0.4.1.tgz", + "integrity": "sha512-629ZeDtsgOv25rNf5Bny8SgdC2Nml9zHbNmNMjd8KzashKvSdTrZMund3NdtQcbhVAJDyl0kxu6YmX2L0aj4KQ==", + "requires": { + "@ethersproject/hash": "^5.0.11", + "auto-bind": "^4.0.0" + } + }, "@svgr/babel-plugin-add-jsx-attribute": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-4.2.0.tgz", @@ -3265,6 +3274,11 @@ "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==" }, + "auto-bind": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/auto-bind/-/auto-bind-4.0.0.tgz", + "integrity": "sha512-Hdw8qdNiqdJ8LqT0iK0sVzkFbzg6fhnQqqfWhBDxcHZvU75+B+ayzTy8x+k5Ix0Y92XOhOUlx74ps+bA6BeYMQ==" + }, "autoprefixer": { "version": "9.8.6", "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.8.6.tgz", @@ -3297,14 +3311,6 @@ "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==" }, - "axios": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.19.2.tgz", - "integrity": "sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA==", - "requires": { - "follow-redirects": "1.5.10" - } - }, "axobject-query": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz", diff --git a/package.json b/package.json index b1ccfe6..7916165 100755 --- a/package.json +++ b/package.json @@ -4,6 +4,7 @@ "private": true, "dependencies": { "@project/contracts": "file:contracts", + "@superfluid-finance/js-sdk": "^0.4.1", "@testing-library/jest-dom": "^4.2.4", "@testing-library/react": "^9.3.2", "@testing-library/user-event": "^7.1.2", diff --git a/src/App.js b/src/App.js index 1d26cb2..0354408 100755 --- a/src/App.js +++ b/src/App.js @@ -2,13 +2,13 @@ import React, { useRef } from "react"; import "./App.css"; import Header from "./components/Header"; import NftForm from "./components/NftForm"; +import PutForRentForm from "./components/PutForRentForm"; +import RentNft from "./components/RentNft"; +import ReturnNft from "./components/ReturnNft"; import Dropzone from "./dropzone/Dropzone"; import useWeb3Modal from "./hooks/useWeb3Modal"; - - function App() { - const [provider, loadWeb3Modal, logoutOfWeb3Modal] = useWeb3Modal(); console.log("Here"); console.log(provider); @@ -25,7 +25,14 @@ function App() {

Drag and Drop Your NFT Image

+

Mint NFT

+

Put NFT for rent

+ +

Rent an NFT

+ +

Return NFT

+
); diff --git a/src/components/PutForRentForm.js b/src/components/PutForRentForm.js new file mode 100644 index 0000000..bd2771f --- /dev/null +++ b/src/components/PutForRentForm.js @@ -0,0 +1,78 @@ +import React, { useState } from "react"; +// import { Form, Button } from "react-bootstrap"; +import { abis } from "@project/contracts"; +import { Formik, Field, Form, ErrorMessage, useField } from "formik"; +import * as Yup from "yup"; + +const Web3 = require("web3"); + +const Input: FunctionalComponent = ({ label, ...props }) => { + // useField() returns [formik.getFieldProps(), formik.getFieldMeta()] + // which we can spread on . We can use field meta to show an error + // message if the field is invalid and it has been touched (i.e. visited) + const [field, meta] = useField(props); + + return ( +
+ + + {meta.touched && meta.error ? ( +
* {meta.error}
+ ) : null} +
+ ); +}; + +const PutForRentForm = () => { + const web3 = new Web3(window.ethereum); + const config = { + erc721: "0x76E195437534620106a2Ef736F8C8491159dC640", + }; + const putForRent = async (id, price) => { + // const nftCid = await getNFTStorageClient().storeBlob(file); + console.log("hi"); + const c = new web3.eth.Contract(abis.erc721.abi, config.erc721); + + const tx = await c.methods + .putForRent(id, price) + .send({ from: window.ethereum.selectedAddress }); + + console.log(tx); + }; + + return ( + { + console.log(values); + await putForRent(values.nftId, values.price); + }} + > + {(formProps) => ( +
+ + +
+ +
+
+ )} +
+ ); +}; +export default PutForRentForm; diff --git a/src/components/RentNft.js b/src/components/RentNft.js new file mode 100644 index 0000000..b585b62 --- /dev/null +++ b/src/components/RentNft.js @@ -0,0 +1,116 @@ +import React from "react"; +// import { Form, Button } from "react-bootstrap"; +import { abis } from "@project/contracts"; +import { Formik, Form, useField } from "formik"; +import * as Yup from "yup"; +import { getSuperClient } from "../utils"; + +const Web3 = require("web3"); + +const Input: FunctionalComponent = ({ label, ...props }) => { + // useField() returns [formik.getFieldProps(), formik.getFieldMeta()] + // which we can spread on . We can use field meta to show an error + // message if the field is invalid and it has been touched (i.e. visited) + const [field, meta] = useField(props); + + return ( +
+ + + {meta.touched && meta.error ? ( +
* {meta.error}
+ ) : null} +
+ ); +}; + +const RentNft = ({ provider }) => { + const web3 = new Web3(window.ethereum); + const config = { + erc721: "0x76E195437534620106a2Ef736F8C8491159dC640", + }; + const rentNft = async (id, flowRate) => { + console.log(provider); + const superClient = await getSuperClient(provider); + console.log(superClient); + console.log("Client"); + + console.log(id, web3.utils.toWei("1")); + console.log( + "ENCODE PARAMETERS: ", + web3.eth.abi.encodeParameters( + ["uint256", "uint256"], + [id, web3.utils.toWei("1")] + ) + ); + + console.log("SENDER: ", window.ethereum.selectedAddress); + console.log("SUPERTOKEN: ", superClient.tokens.fDAIx.address); + // function getRentList() external view returns (RentInfo[] memory) + const c = new web3.eth.Contract(abis.erc721.abi, config.erc721); + const rentList = await c.methods + .getRentList() + .call({ from: window.ethereum.selectedAddress }); + const correctNFT = rentList.filter((i, element) => { + console.log(i); + console.log(element); + console.log(id); + console.log(i[0]); + console.log(i[2]); + console.log(i[0] === `${id}`); + if (i[0] === `${id}`) { + return element; + } + }); + console.log("Correct"); + console.log(correctNFT); + + const price = correctNFT[0][0]; + console.log(price); + const flowPrice = 277777777777778 * price; + console.log(flowPrice); + console.log("Flow Price"); + const flowTx = await superClient.cfa.createFlow({ + superToken: superClient.tokens.fDAIx.address, + sender: window.ethereum.selectedAddress, + receiver: config.erc721, + flowRate: `${flowPrice}`, + userData: web3.eth.abi.encodeParameters( + ["uint256", "uint256"], + [id, web3.utils.toWei("1")] + ), + }); + console.log(flowTx); + }; + + return ( + { + console.log(values); + await rentNft(values.nftId, values.flowRate); + }} + > + {(formProps) => ( +
+ +
+ +
+
+ )} +
+ ); +}; +export default RentNft; diff --git a/src/components/ReturnNft.js b/src/components/ReturnNft.js new file mode 100644 index 0000000..3821357 --- /dev/null +++ b/src/components/ReturnNft.js @@ -0,0 +1,46 @@ +import React from "react"; +// import { Form, Button } from "react-bootstrap"; +import { abis } from "@project/contracts"; +import { Formik, Form, useField } from "formik"; +import * as Yup from "yup"; +import { getSuperClient } from "../utils"; + +const Web3 = require("web3"); + +const Input: FunctionalComponent = ({ label, ...props }) => { + // useField() returns [formik.getFieldProps(), formik.getFieldMeta()] + // which we can spread on . We can use field meta to show an error + // message if the field is invalid and it has been touched (i.e. visited) + const [field, meta] = useField(props); + + return ( +
+ + + {meta.touched && meta.error ? ( +
* {meta.error}
+ ) : null} +
+ ); +}; + +const ReturnNft = ({ provider }) => { + const config = { + erc721: "0x76E195437534620106a2Ef736F8C8491159dC640", + }; + // How does this know the NFT + const returnNft = async () => { + const superClient = await getSuperClient(provider); + + const flowTx = await superClient.cfa.deleteFlow({ + superToken: superClient.tokens.fDAIx.address, + sender: window.ethereum.selectedAddress, + receiver: config.erc721, + by: window.ethereum.selectedAddress, + }); + console.log(flowTx); + }; + + return ; +}; +export default ReturnNft; diff --git a/src/utils.js b/src/utils.js new file mode 100644 index 0000000..46115f6 --- /dev/null +++ b/src/utils.js @@ -0,0 +1,11 @@ +const SuperfluidSDK = require("@superfluid-finance/js-sdk"); + +export const getSuperClient = async (provider) => { + console.log("PROVIDER: ", provider); + const sf = new SuperfluidSDK.Framework({ + ethers: provider, + tokens: ["fDAI"], + }); + await sf.initialize(); + return sf; +};