UNPKG

revenue-sharing-contract

Version:

The revenue sharing contract for Mitama NFT project

222 lines (206 loc) 8.19 kB
import { OpenSeaStreamClient, Network } from '@opensea/stream-js'; import { WebSocket } from 'ws'; import { initializeApp } from "firebase/app"; import { getFirestore, Timestamp } from "firebase/firestore"; import { collection, setDoc, addDoc, getDocs, where, query, orderBy, limit } from "firebase/firestore"; import { ethers, utils } from "ethers"; import * as dotenv from "dotenv"; dotenv.config(); // import { ethers } from "hardhat"; import * as abi from "../artifacts/contracts/RevenueBuffer.sol/RevenueBuffer.json" assert { type: 'json' }; // get deployer(Admin) address of revenuBuffer contract const deployer = process.env.DEPLOYER; // deployed RevenueBuffer contract on Rinkeby const address = '0x23Cb1a2912772E413Eceb469Cd4b4F20a3FA6386'; // Provider const network = ethers.providers.getNetwork("rinkeby"); const alchemyProvider = new ethers.providers.AlchemyProvider(network, process.env.APIKEY); // Signer(deployer address derived from PRIVKEY) const signer = new ethers.Wallet(process.env.PRIVKEY, alchemyProvider); // get contract instance const RevenueBuffer = await new ethers.Contract(address, abi.default.abi, signer); const revenueBuffer = await RevenueBuffer.attach(address); const updateRequest = async (tokenId, members) => { try { // Write contract const tx = await revenueBuffer.addRequest(tokenId, members); console.log("update tx-hash:", tx.hash); await tx.wait(); // Read contract const receiveId = ethers.utils.formatEther(await revenueBuffer.receiveId()); console.log("current receiveId:", receiveId); }catch(e){ console.error(e); } } const firebaseConfig = { apiKey: "AIzaSyC0pHf0Zbw53XEJgMmZjSQUiOMlgbZ1oFU", authDomain: "mitama-solditem-history.firebaseapp.com", projectId: "mitama-solditem-history", storageBucket: "mitama-solditem-history.appspot.com", messagingSenderId: "136704517269", appId: "1:136704517269:web:5a633f81189e39dbda279c" }; // Initialize Firebase const app = initializeApp(firebaseConfig); // Initialize Cloud Firestore and get a reference to the service const db = getFirestore(app); const client = new OpenSeaStreamClient({ token: 'openseaApiKey', network: Network.TESTNET, connectOptions: { transport: WebSocket } }); const tokenLevelList = [0, 0.01, 0.5, 1.0, 3.0, 5.0]; //ETH for LevelUp of DynamicNFT const getTokenLevel = (price) => { var level; var tokenLEvelPrice; for(var i=0; i<tokenLevelList.length; i++) { if (price < tokenLevelList[i]) break; level = i +1; } return level; } const sampleEvent = { "event_type": "item_sold", "sent_at": "2022-04-25T23:32:14.486643+00:00", "payload": { "event_timestamp": "2022-04-21T16:46:46.240222+00:00", "closing_date": "2022-04-21T18:26:36.000000+00:00", "is_private": false, "listing_type": null, "item": { "nft_id":"ethereum/0x8a90cab2b38dba80c64b7734e58ee1db38b8992e/222", "permalink":"https://opensea.io/assets/0x8a90cab2b38dba80c64b7734e58ee1db38b8992e/222", "chain": { "name": "ethereum" }, "metadata": { "name": "Doodle #222", "description": "A community-driven collectibles project featuring art by Burnt Toast. Doodles come...", "image_url": "https://lh3.googleusercontent.com/R7wtoDNdmM7GhTvVjr4JGA6q60z44Hn2nIymPjAEXcjnD8oBPxQYPA1GkrCnvepPM1Sc8DlIHZql4Yucj4ger1jnWmxmuRFwIC_JRw", "animation_url": null, "metadata_url": "https://opensea.mypinata.cloud/ipfs/QmPMc4tcBsMqLRuCQtPmPe84bpSjrC3Ky7t3JWuHXYB4aS/222", }, }, "maker": { "address": "0x9e7b8c91eca1139c41eead94eeb8bc21bd2725ab" }, "payment_token": { "address": "0x7ceb23fd6bc0add59e62ac25578270cff1b9f619", "decimals": 18, "eth_price": "1", "name": "Ether", "symbol": "ETH", "usd_price": "3067.19" }, "quantity": 1, "sale_price": 100500000000000000, "taker": { "address": "0x338571a641d8c43f9e5a306300c5d89e0cb2cfaf" }, "transaction": { "hash": "0x57135fca40b927fbd741f5a21626c1c4c84e7c1036bb50d3158e2fa62a80c941", "timestamp": "2022-04-21T18:26:36.000000+00:00" } } } const parseItemSoldEvent = (event) => { const payload = event.payload; const nft_id = payload.item.nft_id.split('/')[2]; const sale_price = parseFloat(utils.formatEther(String(payload.sale_price)));//string ETH const maker_address = payload.maker.address; const taker_address = payload.taker.address; const timestamp = Timestamp.now(); return { nft_id, sale_price, maker_address, taker_address, timestamp }; }; const injectItem = async (item) => { // const item = parseItemSoldEvent(event); try { const docRef = await addDoc(collection(db, "itemSoldEvent"), item); console.log("injectItem: ", docRef.id); } catch (e) { console.error("Error injectItem: ", e); } }; const isItemPriceRaised = async (nft_id, currentPrice) => { const priceLastSold = await getItemPriceLastSold(nft_id); const lastLevel = getTokenLevel(priceLastSold); return parseFloat(currentPrice) > parseFloat(priceLastSold); } const getItemPriceLastSold = async(nft_id) => { const itemSoldRef = collection(db, "itemSoldEvent"); const q = query(itemSoldRef, where("nft_id", "==", nft_id), orderBy("sale_price", "desc"), limit(1)); try{ const querySnapshot = await getDocs(q); var sale_price; querySnapshot.forEach((doc) => { if(!doc.data()) return null; // doc.data() is never undefined for query doc snapshots console.log("pre sale_price", doc.data()["sale_price"]); sale_price = doc.data()["sale_price"]; }); return sale_price ? sale_price : null; } catch(e) { console.error("Error getItemPriceLastSold:", e); } } const getItemSoldEvents = async(nft_id) => { const itemSoldRef = collection(db, "itemSoldEvent"); // TODO: Limit(number) needs to be update to 7 const q = query(itemSoldRef, where("nft_id", "==", nft_id), orderBy("sale_price", "desc"), limit(3)); try { const querySnapshot = await getDocs(q); querySnapshot.forEach((doc) => { // doc.data() is never undefined for query doc snapshots }); } catch (e) { console.error("Error getting document: ", e); } } const getItemHolderList = async(nft_id) => { const itemSoldRef = collection(db, "itemSoldEvent"); // TODO: Limit(number) needs to be update to 7 const q = query(itemSoldRef, where("nft_id", "==", nft_id), orderBy("sale_price", "desc"), limit(7)); try { const querySnapshot = await getDocs(q); var holderAddressList= []; querySnapshot.forEach((doc) => { holderAddressList.push(doc.data()["maker_address"]); }); return holderAddressList; } catch (e) { console.error("Error getItemHolderList:", e); } } // TODO: call revenueBuffer contract // run onItemosld const main = async (event) => { const item = parseItemSoldEvent(event); const tokenId = item.nft_id; const currentPrice = item.sale_price; const makerAddress = item.maker_address; console.log("currentPrice:", currentPrice); const priceLastSold = await getItemPriceLastSold(item.nft_id); const isPriceRaised = currentPrice >= 1.1 * priceLastSold; // Buyer nees to pay for 1.1x price. console.log("level:", getTokenLevel(currentPrice), "<=", getTokenLevel(priceLastSold)); const isLevelRaised = getTokenLevel(currentPrice) > getTokenLevel(priceLastSold); console.log("isPriceRaised", isPriceRaised); if(isPriceRaised) { await injectItem(item); const holderAddressList = await getItemHolderList(item.nft_id); console.log(holderAddressList); await updateRequest(tokenId, holderAddressList); // call mint of holderPassNFT console.log("isLevelRaised", isLevelRaised); }; if(isLevelRaised) { console.log("token level up!"); const level = getTokenLevel(currentPrice); // call updateTokenLevel(uint256 tikenId, uint8 level) of MitamaNFT } } // await injectItem(parseItemSoldEvent(sampleEvent)); // await main(sampleEvent); client.onItemSold('henohenomoheji', (e) => main(e));