From c6ef67ffc9f192f3acba50f16ba9c252832acd62 Mon Sep 17 00:00:00 2001 From: Hrithik Sampson Date: Wed, 21 Aug 2024 23:34:33 +0530 Subject: [PATCH] zkEVM added to download or chain option to retrieve only zkEVM givBack Donations --- src/givethIoService.ts | 4 +- src/index.ts | 95 +++++++++++++++++++++++++++++++++++++++++- src/swagger.json | 8 ++-- src/utils.ts | 30 ++++++++++--- 4 files changed, 124 insertions(+), 13 deletions(-) diff --git a/src/givethIoService.ts b/src/givethIoService.ts index 3a188a5..860f71f 100644 --- a/src/givethIoService.ts +++ b/src/givethIoService.ts @@ -53,7 +53,7 @@ export const getEligibleDonations = async ( eligible?: boolean, disablePurpleList?: boolean, justCountListed?: boolean, - chain?: "all-other-chains" | "gnosis" + chain?: "all-other-chains" | "gnosis" | "zkEVM" }): Promise => { try { @@ -355,7 +355,7 @@ export const getDonationsReport = async (params: { niceWhitelistTokens?: string[], niceProjectSlugs?: string[], applyChainvineReferral?: boolean, - chain?: "all-other-chains" | "gnosis" + chain?: "all-other-chains" | "gnosis" | "zkEVM" }): Promise => { const { beginDate, diff --git a/src/index.ts b/src/index.ts index 1a593b7..adf8bb1 100644 --- a/src/index.ts +++ b/src/index.ts @@ -131,6 +131,13 @@ app.get(`/calculate`, chain: "all-other-chains" }); + const zkEVMDonations = await getDonationsReport({ + beginDate: startDate as string, + endDate: endDate as string, + applyChainvineReferral: true, + chain: "zkEVM" + }); + const totalDonations = await getDonationsReport({ beginDate: startDate as string, endDate: endDate as string, @@ -151,6 +158,7 @@ app.get(`/calculate`, const groupByGiverAddressForTotalDonations = _.groupBy(totalDonations, 'giverAddress') const groupByGiverAddressForOptimismDonations = _.groupBy(gnosisDonations, 'giverAddress') const groupByGiverAddressForAllOtherChainsDonations = _.groupBy(otherChainDonations, 'giverAddress') + const groupByGiverAddressForzkEVMDonations = _.groupBy(zkEVMDonations, 'giverAddress') const optimismMinimalDonations = getDonationsForSmartContractParams({ @@ -168,6 +176,11 @@ app.get(`/calculate`, groupByGiverAddress: groupByGiverAddressForTotalDonations }) + const zkEVMChainMinimalDonations = getDonationsForSmartContractParams({ + maxGivbackFactorPercentage, + groupByGiverAddress: groupByGiverAddressForzkEVMDonations + }) + const totalMinimalDonationsSortedByUsdValue = totalMinimalDonations.sort((a, b) => { return b.totalDonationsUsdValueAfterGivFactor - a.totalDonationsUsdValueAfterGivFactor }); @@ -190,6 +203,11 @@ app.get(`/calculate`, raisedValueSum }) + const zkEVMChainMinimalDonationsWithShare = convertMinimalDonationToDonationResponse({ + minimalDonationsArray: zkEVMChainMinimalDonations, + givPrice, + raisedValueSum + }) const allOtherChainsDonationsWithShare = convertMinimalDonationToDonationResponse({ minimalDonationsArray: allOtherChainsMinimalDonations, @@ -215,6 +233,7 @@ app.get(`/calculate`, // https://github.com/Giveth/givback-calculation/issues/35#issuecomment-1716106403 const optimismRelayerAddress = '0xf13e93af5e706ab3073e393e77bb2d7ce7bec01f' const gnosisRelayerAddress = '0xd0e81E3EE863318D0121501ff48C6C3e3Fd6cbc7' + const zkEVMRelayerAddress = '0x0000000000000000000000000000000000000000' const response = { raisedValueSumExcludedPurpleList: Math.ceil(raisedValueSum), givDistributed, @@ -243,6 +262,18 @@ app.get(`/calculate`, ), givbacks: allOtherChainsDonationsWithShare }, + zkEVM: { + smartContractParams: await createSmartContractCallAddBatchParams( + { + nrGIVAddress, + donationsWithShare: zkEVMChainMinimalDonationsWithShare.filter(givback => givback.givback > 0), + givRelayerAddress: zkEVMRelayerAddress, + network:'zkEVM' + }, + Number(maxAddressesPerFunctionCall) || 200 + ), + givbacks: zkEVMChainMinimalDonationsWithShare + }, niceTokens: niceDonationsWithShareFormatted, // niceRaisedValueSumExcludedPurpleList: Math.ceil(raisedValueForGivethioDonationsSum), // niceGivethioDonationsAmountForNice: Math.ceil(givethioDonationsAmountForNice), @@ -275,6 +306,20 @@ app.get(`/calculate`, res.setHeader('Content-disposition', "attachment; filename=" + fileName); res.setHeader('Content-type', 'application/json'); res.send(csv) + } else if(download === 'zkEVM'){ + console.log('zkEVM response',response.zkEVM); + const csv = parse(response.zkEVM.givbacks.map((item: DonationResponse) => { + return { + givDistributed, + givPrice, + givbackUsdValue: givPrice * item.givback, + ...item + } + })); + const fileName = `givbackReport_zkEVM_${startDate}-${endDate}.csv`; + res.setHeader('Content-disposition', "attachment; filename=" + fileName); + res.setHeader('Content-type', 'application/json'); + res.send(csv) } else if (download === 'NICE') { const csv = parse(response.niceTokens); const fileName = `givbackReport_NICE_${startDate}-${endDate}.csv`; @@ -305,8 +350,7 @@ const getEligibleAndNonEligibleDonations = async (req: Request, res: Response, e endDate: endDate as string, eligible, justCountListed: justCountListed === 'yes', - chain: chain as "all-other-chains" | "gnosis" - + chain: chain as "all-other-chains" | "gnosis" | "zkEVM" }); const donations = givethIoDonations.sort((a: FormattedDonation, b: FormattedDonation) => { @@ -637,6 +681,13 @@ app.get(`/calculate-updated`, chain: "all-other-chains" }); + const zkEVMDonations = await getDonationsReport({ + beginDate: start, + endDate: end, + applyChainvineReferral: true, + chain: "zkEVM" + }); + console.log('***new webservice donations*** new', { otherChainDonations: otherChainDonations.length, start, @@ -672,6 +723,7 @@ app.get(`/calculate-updated`, const groupByGiverAddressForTotalDonations = _.groupBy(totalDonations, 'giverAddress') const groupByGiverAddressForOptimismDonations = _.groupBy(gnosisDonations, 'giverAddress') const groupByGiverAddressForAllOtherChainsDonations = _.groupBy(otherChainDonations, 'giverAddress') + const groupByGiverAddressForzkEVMDonations = _.groupBy(zkEVMDonations, 'giverAddress') const optimismMinimalDonations = getDonationsForSmartContractParams({ @@ -684,6 +736,11 @@ app.get(`/calculate-updated`, groupByGiverAddress: groupByGiverAddressForAllOtherChainsDonations }) + const zkEVMChainMinimalDonations = getDonationsForSmartContractParams({ + maxGivbackFactorPercentage, + groupByGiverAddress: groupByGiverAddressForzkEVMDonations + }) + const totalMinimalDonations = getDonationsForSmartContractParams({ maxGivbackFactorPercentage, groupByGiverAddress: groupByGiverAddressForTotalDonations @@ -717,6 +774,13 @@ app.get(`/calculate-updated`, givPrice, raisedValueSum }) + + const zkEVMDonationsWithShare = convertMinimalDonationToDonationResponse({ + minimalDonationsArray: zkEVMChainMinimalDonations, + givPrice, + raisedValueSum + }) + console.log('**allOtherChainsDonationsWithShare**', allOtherChainsDonationsWithShare.length) console.log('**allOtherChainsMinimalDonations**', allOtherChainsMinimalDonations.length) @@ -736,6 +800,8 @@ app.get(`/calculate-updated`, const givDistributed = Math.ceil(raisedValueSumAfterGivFactor / givPrice); const optimismRelayerAddress = '0xf13e93af5e706ab3073e393e77bb2d7ce7bec01f' const gnosisRelayerAddress = '0xd0e81E3EE863318D0121501ff48C6C3e3Fd6cbc7' + // TODO : Set the relayer address for zkEVM. + const zkEVMRelayerAddress = '0x0000000000000000000000000000000000000000' const response = { start, @@ -743,6 +809,18 @@ app.get(`/calculate-updated`, raisedValueSumExcludedPurpleList: Math.ceil(raisedValueSum), givDistributed, givethioDonationsAmount: Math.ceil(totalDonationsAmount), + zkEVM: { + smartContractParams: await createSmartContractCallAddBatchParams( + { + nrGIVAddress, + donationsWithShare: zkEVMDonationsWithShare.filter(givback => givback.givback > 0), + givRelayerAddress: zkEVMRelayerAddress, + network:'gnosis' + }, + Number(maxAddressesPerFunctionCall) || 200 + ), + givbacks: zkEVMDonationsWithShare + }, gnosis: { smartContractParams: await createSmartContractCallAddBatchParams( { @@ -799,6 +877,19 @@ app.get(`/calculate-updated`, res.setHeader('Content-disposition', "attachment; filename=" + fileName); res.setHeader('Content-type', 'application/json'); res.send(csv) + } else if (download === "zkEVM") { + const csv = parse(response.zkEVM.givbacks.map((item: DonationResponse) => { + return { + givDistributed, + givPrice, + givbackUsdValue: givPrice * item.givback, + ...item + } + })); + const fileName = `givbackReport_zkEVM_${start}-${end}.csv`; + res.setHeader('Content-disposition', "attachment; filename=" + fileName); + res.setHeader('Content-type', 'application/json'); + res.send(csv) } else if (download === 'NICE') { const csv = parse(response.niceTokens); const fileName = `givbackReport_NICE_${start}-${end}.csv`; diff --git a/src/swagger.json b/src/swagger.json index 2e8d6d6..56b4ccf 100644 --- a/src/swagger.json +++ b/src/swagger.json @@ -63,7 +63,7 @@ "type": "string", "description": "If you want to see json here set no, but if you want to download a file set yes", "default": "no", - "enum": ["no", "gnosis","all-other-chains", "NICE" ], + "enum": ["no", "gnosis","all-other-chains", "NICE", "zkEVM" ], "in": "query" } ], @@ -84,7 +84,7 @@ "type": "string", "description": "For Gnosis we need to distribute on Gnosis chain so we should have different response", "default": "all-other-chains", - "enum": ["all-other-chains","gnosis"], + "enum": ["all-other-chains","gnosis","zkEVM"], "in": "query" }, { @@ -187,7 +187,7 @@ "type": "string", "description": "For Gnosis we need to distribute on Gnosis chain so we should have different response", "default": "all-other-chains", - "enum": ["all-other-chains","gnosis"], + "enum": ["all-other-chains","gnosis","zkEVM"], "in": "query" }, { @@ -400,7 +400,7 @@ "type": "string", "description": "If you want to see json here set no, but if you want to download a file set yes", "default": "no", - "enum": ["no", "gnosis","all-other-chains", "NICE" ], + "enum": ["no", "gnosis","all-other-chains", "NICE", "zkEVM"], "in": "query" } ], diff --git a/src/utils.ts b/src/utils.ts index 42a02e6..9ef6081 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -80,7 +80,7 @@ export const createSmartContractCallAddBatchParams = async (params: { nrGIVAddress: string, donationsWithShare: DonationResponse[], givRelayerAddress: string, - network : 'gnosis' | 'optimism' + network : 'gnosis' | 'optimism' | 'zkEVM' }, maxAddressesPerFunctionCall: number): Promise<{ result: string, hashParams: string @@ -210,8 +210,11 @@ const xdaiWeb3 = new Web3(xdaiWeb3NodeUrl); const optimismWeb3NodeUrl = process.env.OPTIMISM_NODE_HTTP_URL const optimismWeb3 = new Web3(optimismWeb3NodeUrl); -export const getLastNonceForWalletAddress = async (walletAddress: string, chain: 'gnosis' | 'optimism'): Promise => { - const web3Provider = chain === 'optimism' ? optimismWeb3 : xdaiWeb3 +const zkEVMWeb3NodeUrl = process.env.ZKEVM_NODE_HTTP_URL +const zkEVMWeb3 = new Web3(zkEVMWeb3NodeUrl); + +export const getLastNonceForWalletAddress = async (walletAddress: string, chain: 'gnosis' | 'optimism' | 'zkEVM'): Promise => { + const web3Provider = getWeb3Provider(chain); const userTransactionsCount = await web3Provider.eth.getTransactionCount( walletAddress ); @@ -224,6 +227,20 @@ export const getLastNonceForWalletAddress = async (walletAddress: string, chain: return Math.max(userTransactionsCount - 1, 0) } +const getWeb3Provider = (chain: 'gnosis' | 'optimism' | 'zkEVM'): any => { + let web3Provider = xdaiWeb3; + switch(chain) { + case 'optimism': + web3Provider = optimismWeb3 + break; + case 'zkEVM': + web3Provider = zkEVMWeb3; + break; + default: + web3Provider = xdaiWeb3; + } + return web3Provider; +} export const getNetworkNameById = (networkId: number): string => { switch (networkId) { @@ -262,12 +279,15 @@ export const getNetworkNameById = (networkId: number): string => { } } -export const filterRawDonationsByChain = (gqlResult: { donations: GivethIoDonation[] }, chain ?: "all-other-chains" | "gnosis"): GivethIoDonation[] => { +export const filterRawDonationsByChain = (gqlResult: { donations: GivethIoDonation[] }, chain ?: "all-other-chains" | "gnosis" | "zkEVM"): GivethIoDonation[] => { + if (chain === 'gnosis') { return gqlResult.donations.filter(donation => donation.transactionNetworkId === 100) + } else if (chain === 'zkEVM') { + return gqlResult.donations.filter(donation => donation.transactionNetworkId === 1101) } else if (chain === "all-other-chains") { // Exclude Optimism donations and return all other donations - return gqlResult.donations.filter(donation => donation.transactionNetworkId !== 100) + return gqlResult.donations.filter(donation => donation.transactionNetworkId !== 100 && donation.transactionNetworkId !== 1101) } else { return gqlResult.donations }