From cb7dfd0d10379fe50168f223f01e33049aceca54 Mon Sep 17 00:00:00 2001 From: Ashutosh Kumar Date: Wed, 14 Aug 2024 17:00:45 +0530 Subject: [PATCH] Other Code Improvements --- components/daos/index.js | 44 +++------------- components/tokens/index.js | 15 ++++-- routes/tokens.js | 3 ++ utils-eth.js | 105 +++++++++++++++++++------------------ 4 files changed, 75 insertions(+), 92 deletions(-) diff --git a/components/daos/index.js b/components/daos/index.js index 94456b0..3dbb2bb 100644 --- a/components/daos/index.js +++ b/components/daos/index.js @@ -11,6 +11,7 @@ const { getEthTokenHoldersCount, getEthCurrentBlock, getEthUserBalanceAtLevel, + getEthTokenMetadata, } = require("../../utils-eth"); const dbo = require("../../db/conn"); @@ -216,11 +217,12 @@ const updateTotalHolders = async (req, response) => { const createDAO = async (req, response) => { const { payloadBytes, publicKey, } = req.body; const network = req.body.network + + // Creating Offchain DAO on Etherlink if (network && network?.startsWith("etherlink")) { const payload = req.payloadObj; const { tokenAddress, - tokenID, symbol: tokenSymbol, network, name, @@ -230,21 +232,14 @@ const createDAO = async (req, response) => { requiredTokenOwnership, allowPublicAccess, daoContract, + decimals } = payload; - // return response.json({ - // payload, - // body:{ - // ...req.body, - // } - // }) + // const tokenData = await getEthTokenMetadata(tokenAddress, network); - // const tokenData = await getEthTokenMetadata(tokenAddress, network, tokenID); - // console.log({tokenData}) const address = publicKey const block = await getEthCurrentBlock(network); - console.log({ block }) const userBalanceAtCurrentLevel = await getEthUserBalanceAtLevel( network, address, @@ -280,38 +275,13 @@ const createDAO = async (req, response) => { tokenType: "ERC20", symbol: tokenSymbol, daoID: createdDao._id, - decimals: Number(2), - // decimals: Number(tokenData.tokenDecimals), + decimals: Number(decimals), }); + return response.json({ dao: createdDao, token: createdToken }) - // const session = await mongoose.startSession(); - // try { - // await session.withTransaction(async () => { - // const createdDao = await DaoModel.create(ethDaoData, { session }); - // const createdToken = await TokenModel.create({ - // tokenAddress, - // tokenType: "ERC20", - // symbol: tokenSymbol, - // daoID: createdDao._id, - // decimals: Number(2), - // // decimals: Number(tokenData.tokenDecimals), - // }, { session }); - // res.json({ - // dao: createdDao, - // token: createdToken - // }) - // }); - // } catch (error) { - // console.error('Transaction failed:', error); - // return response.json({ - // message: "Etherlink DAOs are not supported yet" - // }) - // } finally { - // session.endSession(); - // } } try { const values = getInputFromSigPayload(payloadBytes); diff --git a/components/tokens/index.js b/components/tokens/index.js index 41c22fe..c46536e 100644 --- a/components/tokens/index.js +++ b/components/tokens/index.js @@ -1,6 +1,8 @@ // This will help us connect to the database const dbo = require("../../db/conn"); +const TokenModel = require("../../db/models/Token.model"); const { getUserTotalVotingPowerAtReferenceBlock } = require("../../utils"); +const { getEthTokenMetadata } = require("../../utils-eth"); const ObjectId = require("mongodb").ObjectId; @@ -33,11 +35,7 @@ const getTokenById = async (req, response) => { const { id } = req.params; try { - let db_connect = dbo.getDb(); - const TokensCollection = db_connect.collection("Tokens"); - - let daoId = { daoID: ObjectId(id) }; - const result = await TokensCollection.findOne(daoId); + const result = await TokenModel.findOne({daoId: ObjectId(id)}) response.json(result); } catch (error) { console.log("error: ", error); @@ -98,8 +96,15 @@ const getVotingPowerAtLevel = async (req, response) => { } }; +const getTokenByContract = async (req, response) => { + const { network, contract } = req.query; + const token = await getEthTokenMetadata(network, contract); + response.json([token]); +} + module.exports = { addToken, getTokenById, getVotingPowerAtLevel, + getTokenByContract }; diff --git a/routes/tokens.js b/routes/tokens.js index af4e309..679f0f4 100644 --- a/routes/tokens.js +++ b/routes/tokens.js @@ -10,6 +10,7 @@ const { addToken, getTokenById, getVotingPowerAtLevel, + getTokenByContract, } = require("../components/tokens"); /** @@ -90,4 +91,6 @@ tokensRoutes .route("/network/:network/token/:address/token-id/:tokenID/voting-power") .get(catchAsync(getVotingPowerAtLevel)); +tokensRoutes.route("/token").get(catchAsync(getTokenByContract)); + module.exports = tokensRoutes; diff --git a/utils-eth.js b/utils-eth.js index 362e1ed..bd025a2 100644 --- a/utils-eth.js +++ b/utils-eth.js @@ -1,4 +1,5 @@ -const {ethers, JsonRpcProvider} = require('ethers'); +const { default: BigNumber } = require('bignumber.js'); +const { ethers, JsonRpcProvider } = require('ethers'); const tokenAbiForErc20 = [ { @@ -324,89 +325,91 @@ const tokenAbiForErc20 = [ // ⚠️ To be Fixed function _getEthProvider(network) { - return new JsonRpcProvider("https://node.ghostnet.etherlink.com"); -// return new JsonRpcProvider("https://eth-sepolia.blockscout.com"); + return new JsonRpcProvider("https://node.ghostnet.etherlink.com"); + // return new JsonRpcProvider("https://eth-sepolia.blockscout.com"); } // ⚠️ To be Implemented function verityEthSignture(signature, payloadBytes) { - return true; - try { - const values = ethers.utils.recoverMessage(payloadBytes, signature); - - // // Convert the payload bytes to a string - // const payloadString = ethers.utils.toUtf8String(payloadBytes); + return true; + try { + const values = ethers.utils.recoverMessage(payloadBytes, signature); - // // Split the string into parts - // const parts = payloadString.split(' '); + // // Convert the payload bytes to a string + // const payloadString = ethers.utils.toUtf8String(payloadBytes); - // // Extract the JSON part (assuming it's the last part) - // const jsonString = parts.slice(5).join(' '); + // // Split the string into parts + // const parts = payloadString.split(' '); - // // Parse the JSON string - // const values = JSON.parse(jsonString); + // // Extract the JSON part (assuming it's the last part) + // const jsonString = parts.slice(5).join(' '); - return values; + // // Parse the JSON string + // const values = JSON.parse(jsonString); - } catch (error) { + return values; - console.error('Error parsing Ethereum signature payload:', error); - throw new Error('Invalid Ethereum signature payload'); + } catch (error) { - } + console.error('Error parsing Ethereum signature payload:', error); + throw new Error('Invalid Ethereum signature payload'); + + } } -// ⚠️ To be Implemented +// ✅ Working async function getEthTokenMetadata(network, tokenAddress) { - const provider = _getEthProvider(network); - const tokenContract = new ethers.Contract(tokenAddress, tokenAbiForErc20, provider); - console.log({tokenContract}) -// const tokenSymbol = await tokenContract.symbol(); - // const [tokenDecimals, tokenSymbol] = await Promise.all([ -// tokenContract.decimals(), -// tokenContract.symbol() -// ]); - return { - tokenSymbol:"TEST" - }; + const provider = _getEthProvider(network); + const tokenContract = new ethers.Contract(tokenAddress, tokenAbiForErc20, provider); + const symbol = await tokenContract.symbol(); + const decimals = await tokenContract.decimals(); + const name = await tokenContract.name(); + const totalSupply = await tokenContract.totalSupply(); + + return { + name, + decimals: Number(decimals), + symbol, + totalSupply: BigNumber(totalSupply).toString(), + }; } // ✅ Working async function getEthCurrentBlock(network) { - const provider = _getEthProvider(network); - const block = await provider.getBlock('latest'); - return block.number; + const provider = _getEthProvider(network); + const block = await provider.getBlock('latest'); + return block.number; } // ✅ Working async function getEthUserBalanceAtLevel(network, walletAddress, tokenAddress, block = 0) { - if(!block) block = await getEthCurrentBlock(network); + if (!block) block = await getEthCurrentBlock(network); const provider = _getEthProvider(network); - console.log({network,walletAddress,tokenAddress,block}) + console.log({ network, walletAddress, tokenAddress, block }) const tokenContract = new ethers.Contract(tokenAddress, tokenAbiForErc20, provider); - const balance = await tokenContract.balanceOf(walletAddress,{blockTag: block}); + const balance = await tokenContract.balanceOf(walletAddress, { blockTag: block }); return balance; } async function getEthTotalSupply(network, tokenAddress, block = 0) { - if(!block) block = await getEthCurrentBlock(network); + if (!block) block = await getEthCurrentBlock(network); const provider = _getEthProvider(network); const tokenContract = new ethers.Contract(tokenAddress, tokenAbiForErc20, provider); - const totalSupply = await tokenContract.totalSupply({blockTag: block}); + const totalSupply = await tokenContract.totalSupply({ blockTag: block }); return totalSupply; } // This won't work efficiently for large block ranges, Indexer needs to be used for this async function getEthTokenHoldersCount(network, tokenAddress, block = 0) { - if(!block) block = await getEthCurrentBlock(network); + if (!block) block = await getEthCurrentBlock(network); const provider = _getEthProvider(network); const contract = new ethers.Contract(tokenAddress, tokenAbiForErc20, provider); - + const latestBlock = await provider.getBlockNumber(); const startBlock = Math.max(0, latestBlock - 999); // Ensure we don't go below block 0 const holders = new Set(); - + console.log(`Querying blocks ${startBlock} to ${latestBlock}`); const filter = contract.filters.Transfer(); @@ -429,7 +432,9 @@ async function getEthTokenHoldersCount(network, tokenAddress, block = 0) { return holders.size; } -getEthTokenHoldersCount("sepolia","0x336bfd0356f6babec084f9120901c0296db1967e").then(console.log) +getEthTokenMetadata("sepolia", "0x336bfd0356f6babec084f9120901c0296db1967e").then(console.log) + +// getEthTokenHoldersCount("sepolia","0x336bfd0356f6babec084f9120901c0296db1967e").then(console.log) // ✅ Working // getEthTotalSupply("sepoplia","0x336bfd0356f6babec084f9120901c0296db1967e").then((x)=>console.log("Total Suplpy",x)) @@ -445,10 +450,10 @@ getEthTokenHoldersCount("sepolia","0x336bfd0356f6babec084f9120901c0296db1967e"). console.log("from ETH") module.exports = { - verityEthSignture, - getEthTokenMetadata, - getEthCurrentBlock, - getEthUserBalanceAtLevel, - getEthTotalSupply, - getEthTokenHoldersCount, + verityEthSignture, + getEthTokenMetadata, + getEthCurrentBlock, + getEthUserBalanceAtLevel, + getEthTotalSupply, + getEthTokenHoldersCount, } \ No newline at end of file