Skip to content

Commit

Permalink
create Royalty stream
Browse files Browse the repository at this point in the history
  • Loading branch information
ademidun committed Jun 26, 2022
1 parent 76746c6 commit 24f789b
Show file tree
Hide file tree
Showing 4 changed files with 1,235 additions and 35 deletions.
3 changes: 3 additions & 0 deletions client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"version": "0.1.0",
"private": true,
"dependencies": {
"@superfluid-finance/sdk-core": "^0.4.2",
"@testing-library/jest-dom": "^5.14.1",
"@testing-library/react": "^13.0.0",
"@testing-library/user-event": "^13.2.1",
Expand All @@ -14,9 +15,11 @@
"axios": "^0.27.2",
"bootstrap": "^5.1.3",
"ethers": "^5.6.9",
"graphql": "^16.5.0",
"ipfs-http-client": "56.0.3",
"moralis": "^1.8.0",
"react": "^18.2.0",
"react-bootstrap": "^2.4.0",
"react-dom": "^18.2.0",
"react-scripts": "5.0.1",
"typescript": "^4.4.2",
Expand Down
214 changes: 214 additions & 0 deletions client/src/components/CreateRoyaltyStream.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,214 @@
import React, { useState, useEffect } from "react";
import { Framework } from "@superfluid-finance/sdk-core";
import {
Button,
Form,
FormGroup,
FormControl,
Spinner,
Card
} from "react-bootstrap";
// import "./createFlow.css";
import { ethers } from "ethers";

// let account;

//where the Superfluid logic takes place
async function createNewFlow(recipient: any, flowRate: any) {
const provider = new ethers.providers.Web3Provider(window.ethereum);

const signer = provider.getSigner();

const chainId = await window.ethereum.request({ method: "eth_chainId" });
const sf = await Framework.create({
chainId: Number(chainId),
provider: provider
});

const DAIxContract = await sf.loadSuperToken("fDAIx");
const DAIx = DAIxContract.address;

try {
const createFlowOperation = sf.cfaV1.createFlow({
receiver: recipient,
flowRate: flowRate,
superToken: DAIx
// userData?: string
});

console.log("Creating your stream...");

const result = await createFlowOperation.exec(signer);
console.log(result);

console.log(
`Congrats - you've just created a money stream!
View Your Stream At: https://app.superfluid.finance/dashboard/${recipient}
Network: Kovan
Super Token: DAIx
Sender: 0xDCB45e4f6762C3D7C61a00e96Fb94ADb7Cf27721
Receiver: ${recipient},
FlowRate: ${flowRate}
`
);
} catch (error) {
console.log(
"Hmmm, your transaction threw an error. Make sure that this stream does not already exist, and that you've entered a valid Ethereum address!"
);
console.error(error);
}
}

export const CreateRoyaltyStream = () => {
const [recipient, setRecipient] = useState("");
const [isButtonLoading, setIsButtonLoading] = useState(false);
const [flowRate, setFlowRate] = useState("");
const [flowRateDisplay, setFlowRateDisplay] = useState("");
const [currentAccount, setCurrentAccount] = useState("");

const connectWallet = async () => {
try {
const { ethereum } = window;

if (!ethereum) {
alert("Get MetaMask!");
return;
}
const accounts = await ethereum.request({
method: "eth_requestAccounts"
});
console.log("Connected", accounts[0]);
setCurrentAccount(accounts[0]);
// let account = currentAccount;
// Setup listener! This is for the case where a user comes to our site
// and connected their wallet for the first time.
// setupEventListener()
} catch (error) {
console.log(error);
}
};

const checkIfWalletIsConnected = async () => {
const { ethereum } = window;

if (!ethereum) {
console.log("Make sure you have metamask!");
return;
} else {
console.log("We have the ethereum object", ethereum);
}

const accounts = await ethereum.request({ method: "eth_accounts" });
const chain = await window.ethereum.request({ method: "eth_chainId" });
let chainId = chain;
console.log("chain ID:", chain);
console.log("global Chain Id:", chainId);
if (accounts.length !== 0) {
const account = accounts[0];
console.log("Found an authorized account:", account);
setCurrentAccount(account);
// Setup listener! This is for the case where a user comes to our site
// and ALREADY had their wallet connected + authorized.
// setupEventListener()
} else {
console.log("No authorized account found");
}
};

useEffect(() => {
checkIfWalletIsConnected();
}, []);

function calculateFlowRate(amount: number) {
if (typeof Number(amount) !== "number" || isNaN(Number(amount)) === true) {
alert("You can only calculate a flowRate based on a number");
return;
} else if (typeof Number(amount) === "number") {
if (Number(amount) === 0) {
return 0;
}
const amountInWei = ethers.BigNumber.from(amount);
const monthlyAmount = ethers.utils.formatEther(amountInWei.toString());
const calculatedFlowRate = (monthlyAmount as any) * 3600 * 24 * 30;
return calculatedFlowRate;
}
}

function CreateButton({ isLoading, children, ...props }: { isLoading: any, children: any, onClick: any }) {
return (
<Button variant="success" className="button" {...props}>
{isButtonLoading ? <Spinner animation="border" /> : children}
</Button>
);
}

const handleRecipientChange = (e: any) => {
setRecipient(() => ([e.target.name] = e.target.value));
};

const handleFlowRateChange = (e: any) => {
setFlowRate(() => ([e.target.name] = e.target.value));
let newFlowRateDisplay = calculateFlowRate(e.target.value);
setFlowRateDisplay(newFlowRateDisplay!.toString());
};

return (
<div>
<h2>Stream Royalties</h2>
{currentAccount === "" ? (
<button id="connectWallet" className="button" onClick={connectWallet}>
Connect Wallet
</button>
) : (
<Card className="connectedWallet">
{`${currentAccount.substring(0, 4)}...${currentAccount.substring(
38
)}`}
</Card>
)}
<Form>
<FormGroup className="mb-3">
<FormControl
name="recipient"
value={recipient}
onChange={handleRecipientChange}
placeholder="Enter recipient address"
></FormControl>
</FormGroup>
<FormGroup className="mb-3">
<FormControl
name="flowRate"
value={flowRate}
onChange={handleFlowRateChange}
placeholder="Enter a flowRate in wei/second"
></FormControl>
</FormGroup>
<CreateButton
isLoading={false}
onClick={() => {
setIsButtonLoading(true);
createNewFlow(recipient, flowRate);
setTimeout(() => {
setIsButtonLoading(false);
}, 1000);
}}
>
Click to Create Your Stream
</CreateButton>
</Form>

<div className="description">
<p>
Go to the CreateFlow.js component and look at the <b>createFlow() </b>
function to see under the hood
</p>
<div className="calculation">
<p>Your flow will be equal to:</p>
<p>
<b>${flowRateDisplay !== " " ? flowRateDisplay : 0}</b> DAIx/month
</p>
</div>
</div>
</div>
);
};
11 changes: 11 additions & 0 deletions client/src/components/NFTCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import CryptoPrice from './CryptoPrice';
import CryptoPriceEdit from './CryptoPriceEdit';

import Web3Modal from 'web3modal';
import { CreateRoyaltyStream } from './CreateRoyaltyStream';

function NFTCard({nft: defaultNft}: {nft: NFTMetadata}) {

Expand All @@ -21,6 +22,8 @@ function NFTCard({nft: defaultNft}: {nft: NFTMetadata}) {
let signer: ethers.providers.JsonRpcSigner;
const [responseMessage, setResponseMessage] = useState<{[key: string]: {message: string, type: AlertProps["type"], loading?: boolean}}>({});

const [isCreateRoyaltyStream, setisCreateRoyaltyStream] = useState(false);

const activeChain = CONFIG_CHAINS[chainId!];

console.log({activeChain, chainId, CONFIG_CHAINS});
Expand Down Expand Up @@ -253,6 +256,14 @@ function NFTCard({nft: defaultNft}: {nft: NFTMetadata}) {
<Button onClick={payRoyalties} className="mb-3">
Pay Royalties
</Button>

<Button onClick={() => setisCreateRoyaltyStream(!isCreateRoyaltyStream)} className="mb-3" color='green'>
Stream Royalties
</Button>

{isCreateRoyaltyStream &&
<CreateRoyaltyStream />
}
</>
</li>
<li>
Expand Down

0 comments on commit 24f789b

Please sign in to comment.