diff --git a/src/strategies/DonationVotingMerkleDistributionStrategy/DonationVotingMerkleDistribution.ts b/src/strategies/DonationVotingMerkleDistributionStrategy/DonationVotingMerkleDistribution.ts index 6c42c7a..446b69b 100644 --- a/src/strategies/DonationVotingMerkleDistributionStrategy/DonationVotingMerkleDistribution.ts +++ b/src/strategies/DonationVotingMerkleDistributionStrategy/DonationVotingMerkleDistribution.ts @@ -6,73 +6,120 @@ import { extractChain, getContract, } from "viem"; -import { create } from "../../Client/Client"; -import { abi } from "./donationVoting.config"; import { Allo } from "../../Allo/Allo"; +import { create } from "../../Client/Client"; import { ConstructorArgs, Metadata, TransactionData } from "../../Common/types"; +import { supportedChains } from "../../chains.config"; import { PayoutSummary, Status } from "../types"; +import { abi } from "./donationVoting.config"; import { Recipient } from "./types"; -import { supportedChains } from "../../chains.config"; export class DonationVotingMerkleDistributionStrategy { private client: PublicClient; + private contract: any; - private strategy: `0x${string}`; + private strategy: `0x${string}` | undefined; + private poolId: number; private allo: Allo; - constructor({ chain, rpc, address }: ConstructorArgs) { - const usedChain = extractChain({ - chains: supportedChains, - id: chain as any, - }); - - this.client = create(usedChain, rpc); + constructor({ chain, rpc, address, poolId }: ConstructorArgs) { + const usedChain = extractChain({ + chains: supportedChains, + id: chain as any, + }); - if (!address) - throw new Error( - "DonationVotingMerkleDistributionStrategy: No strategy address provided" - ); - this.strategy = address; + this.client = create(usedChain, rpc); this.allo = new Allo({ chain, rpc }); // to call allocate + if (address) { + this.contract = getContract({ + address: address, + abi: abi, + publicClient: this.client, + }); + this.strategy = address; + } + + this.poolId = poolId || -1; + } + + /** + * Utility functions + */ + public async getAllo(): Promise { + return this.allo; + } + + public async setPoolId(poolId: number): Promise { + this.poolId = poolId; + const strategyAddress = await this.allo.getStrategy(poolId); + this.setContract(strategyAddress as `0x${string}`); + } + + public setContract(address: `0x${string}`): void { this.contract = getContract({ address: address, - abi: abi, + abi: [], // todo: add abi publicClient: this.client, }); - this.poolId = 0; // TODO: set poolId + this.strategy = address; + } + + /** + * Validation functions + */ + private checkPoolId(): void { + if (this.poolId === -1) + throw new Error( + "MicroGrantsStrategy: No poolId provided. Please call `setPoolId` first." + ); } - // Read only functions + + private checkStrategy(): void { + if (!this.strategy) + throw new Error( + "MicroGrantsStrategy: No strategy address provided. Please call `setContract` first." + ); + } + + /** + * Read only functions + */ public async getNative(): Promise { + this.checkStrategy(); const native = await this.contract.read.NATIVE(); return native; } public async getPermit2(): Promise { + this.checkStrategy(); const permit2 = await this.contract.read.PERMIT2(); return permit2; } public async getAllocationEndTime(): Promise { + this.checkStrategy(); const endTime = await this.contract.read.allocationEndTime(); return endTime; } public async getAllocationStartTime(): Promise { + this.checkStrategy(); const startTime = await this.contract.read.allocationStartTime(); return startTime; } public async isAllowedTokens(token: string): Promise { + this.checkStrategy(); const allowed = await this.contract.read.allowedTokens(token); return allowed; @@ -85,27 +132,24 @@ export class DonationVotingMerkleDistributionStrategy { } public async getDistributionMetadata(): Promise { + this.checkStrategy(); const metadata: Metadata = await this.contract.read.distributionMetadata(); return metadata; } public async getDistributionStarted(): Promise { + this.checkStrategy(); const started = await this.contract.read.distributionStarted(); return started; } - public async getAllo(): Promise { - const allo = await this.contract.read.getAllo(); - - return allo; - } - public async getPayouts( recipientIds: string[], data: string[] ): Promise { + this.checkStrategy(); const payouts = await this.contract.read.getPayouts([recipientIds, data]); const payoutSummary: PayoutSummary[] = payouts.map((payout: any) => { @@ -119,72 +163,84 @@ export class DonationVotingMerkleDistributionStrategy { } public async getPoolAmount(): Promise { + this.checkStrategy(); const amount = await this.contract.read.getPoolAmount(); return amount; } public async getPoolId(): Promise { + this.checkStrategy(); const id = await this.contract.read.getPoolId(); return id; } public async getRecipient(recipientId: string): Promise { + this.checkStrategy(); const recipient = await this.contract.read.getRecipient([recipientId]); return recipient; } public async getRecipientStatus(recipientId: string): Promise { + this.checkStrategy(); const status = await this.contract.read.getRecipientStatus([recipientId]); return status; } public async getStrategyId(): Promise { + this.checkStrategy(); const id = await this.contract.read.getStrategyId(); return id; } public async hasBeenDistributed(index: number): Promise { + this.checkStrategy(); const distributed = await this.contract.read.hasBeenDistributed([index]); return distributed; } public async isDistributionSet(): Promise { + this.checkStrategy(); const set = await this.contract.read.isDistributionSet(); return set; } public async isPoolActive(): Promise { + this.checkStrategy(); const active = await this.contract.read.isPoolActive(); return active; } public async isValidAllocator(allocator: `0x${string}`): Promise { + this.checkStrategy(); const valid = await this.contract.read.isValidAllocator([allocator]); return valid; } public async getMerkleRoot(): Promise { + this.checkStrategy(); const root = await this.contract.read.merkleRoot(); return root; } public async metadataRequired(): Promise { + this.checkStrategy(); const required = await this.contract.read.metadataRequired(); return required; } public async recipientToStatusIndexes(recipient: string): Promise { + this.checkStrategy(); const indexes = await this.contract.read.recipientToStatusIndexes([ recipient, ]); @@ -193,35 +249,41 @@ export class DonationVotingMerkleDistributionStrategy { } public async recipientsCounter(): Promise { + this.checkStrategy(); const counter = await this.contract.read.recipientsCounter(); return counter; } public async registrationEndTime(): Promise { + this.checkStrategy(); const endTime = await this.contract.read.registrationEndTime(); return endTime; } public async registrationStartTime(): Promise { + this.checkStrategy(); const startTime = await this.contract.read.registrationStartTime(); return startTime; } public async statusesBitMap(index: number): Promise { + this.checkStrategy(); const bitMap = await this.contract.read.statusesBitMap([index]); return bitMap; } public async totalPayoutAmount(): Promise { + this.checkStrategy(); const amount = await this.contract.read.totalPayoutAmount(); return amount; } public async useRegistryAnchor(): Promise { + this.checkStrategy(); const anchor = await this.contract.read.useRegistryAnchor(); return anchor; @@ -256,7 +318,9 @@ export class DonationVotingMerkleDistributionStrategy { return this.allo.distribute(this.poolId, recipientIds, data); } - // Write functions + /** + * Write functions + */ public claim( claims: { recipientId: string; token: string }[] ): TransactionData {