UNPKG

@allo-team/allo-v2-sdk

Version:
611 lines (476 loc) 14.1 kB
import { Chain, PublicClient, Transport, encodeAbiParameters, encodeFunctionData, extractChain, getContract, parseAbiParameters, } from "viem"; import { Allo } from "../../Allo/Allo"; import { ConstructorArgs, DeployParams, Metadata, PayoutSummary, Recipient, Status, TransactionData, } from "../../types"; import { supportedChains } from "../../chains.config"; import { create } from "../../Client/Client"; import { abi as superfluidAbi, bytecode as superfluidBytecode, } from "./superfluid.config"; import { AllocationSuperlfuid, InitializeParamsSuperFluid, RegisterDataSuperfluid, ReviewRecipientDataSuperfluid, } from "./types"; import { abi as alloAbi } from "../../Allo/allo.config"; export class SQFSuperFluidStrategy { private client: PublicClient<Transport, Chain>; private contract: any; private strategy: `0x${string}` | undefined; private poolId: bigint; private allo: Allo; constructor({ chain, rpc, address, poolId }: ConstructorArgs) { const usedChain = extractChain({ chains: supportedChains, id: chain as any, }); this.client = create(usedChain, rpc); this.allo = new Allo({ chain, rpc }); if (address) { this.contract = getContract({ address: address, abi: superfluidAbi, client: { public: this.client, } }); this.strategy = address; } this.poolId = poolId || BigInt(-1); } public async setPoolId(poolId: bigint): Promise<void> { 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: superfluidAbi, client: { public: this.client, } }); this.strategy = address; } private checkPoolId(): void { if (this.poolId === BigInt(-1)) throw new Error( "SQFSuperfluidStrategy: No poolId provided. Please call `setPoolId` first.", ); } private checkStrategy(): void { if (!this.strategy) throw new Error( "SQFSuperfluidStrategy: No strategy address provided. Please call `setContract` first.", ); } // Init and Deploy public async getInitializeData( params: InitializeParamsSuperFluid, ): Promise<`0x${string}`> { const encoded: `0x${string}` = encodeAbiParameters( parseAbiParameters( "bool, bool, address, address, address, uint64, uint64, uint64, uint64, uint256, uint256", ), [ params.useRegistryAnchor, params.metadataRequired, params.passportDecoder, params.superfluidHost, params.allocationSuperToken, params.registrationStartTime, params.registrationEndTime, params.allocationStartTime, params.allocationEndTime, params.minPassportScore, params.initialSuperAppBalance, ], ); return encoded; } public getDeployParams(): DeployParams { const constructorArgs: `0x${string}` = encodeAbiParameters( parseAbiParameters("address, string"), [this.allo.address(), "SQFSuperfluidv1"], ); const constructorArgsNo0x = constructorArgs.slice(2); // create the proper bytecode const bytecode = superfluidBytecode; const abi = superfluidAbi; return { abi: abi, bytecode: (bytecode + constructorArgsNo0x) as unknown as `0x${string}`, }; } // Getters public async getNative(): Promise<string> { this.checkStrategy(); const native = await this.contract.read.NATIVE(); return native; } public async getAllocationEndTime(): Promise<bigint> { this.checkStrategy(); const endTime = await this.contract.read.allocationEndTime(); return endTime; } public async getAllocationStartTime(): Promise<bigint> { this.checkStrategy(); const startTime = await this.contract.read.allocationStartTime(); return startTime; } public async getRegistrationEndTime(): Promise<bigint> { this.checkStrategy(); const endTime = await this.contract.read.registrationEndTime(); return endTime; } public async getRegistrationStartTime(): Promise<bigint> { this.checkStrategy(); const startTime = await this.contract.read.registrationStartTime(); return startTime; } public async getAllo(): Promise<Allo> { return this.allo; } public async getPayouts(recipientIds: string[]): Promise<PayoutSummary[]> { this.checkStrategy(); const emptyData = Array(recipientIds.length).fill("0x"); const payouts = await this.contract.read.getPayouts([ recipientIds, emptyData, ]); const payoutSummary: PayoutSummary[] = payouts.map((payout: any) => { this.checkStrategy(); return { address: payout.recipientAddress, amount: payout.amount, }; }); return payoutSummary; } public async getPoolAmount(): Promise<bigint> { this.checkStrategy(); const amount = await this.contract.read.getPoolAmount(); return amount; } public async getPoolId(): Promise<bigint> { this.checkStrategy(); const poolId = await this.contract.read.getPoolId(); return poolId; } public async getRecipient(recipientId: string): Promise<Recipient> { this.checkStrategy(); const recipient = await this.contract.read.getRecipient([recipientId]); return recipient; } public async getRecipientStatus(recipientId: string): Promise<Status> { this.checkStrategy(); const status = await this.contract.read.getRecipientStatus([recipientId]); return status; } public async getStrategyId(): Promise<string> { this.checkStrategy(); const id = await this.contract.read.getStrategyId(); return id; } public async isPoolActive(): Promise<boolean> { this.checkStrategy(); const active = await this.contract.read.isPoolActive(); return active; } public async isValidAllocator(allocatorAddress: string): Promise<boolean> { this.checkStrategy(); const valid = await this.contract.read.isValidAllocator([allocatorAddress]); return valid; } public async useRegistryAnchor(): Promise<boolean> { this.checkStrategy(); const useRegistryAnchor = await this.contract.read.useRegistryAnchor(); return useRegistryAnchor; } public getInitialSuperAppBalance(): Promise<bigint> { this.checkStrategy(); return this.contract.read.initialSuperAppBalance(); } public getSuperfluidHost(): Promise<`0x${string}`> { this.checkStrategy(); return this.contract.read.superfluidHost(); } public getAllocationSuperToken(): Promise<`0x${string}`> { this.checkStrategy(); return this.contract.read.allocationSuperToken(); } public getPoolSuperToken(): Promise<`0x${string}`> { this.checkStrategy(); return this.contract.read.poolSuperToken(); } public getGdaPool(): Promise<`0x${string}`> { this.checkStrategy(); return this.contract.read.gdaPool(); } public getPassportDecoder(): Promise<`0x${string}`> { this.checkStrategy(); return this.contract.read.passportDecoder(); } public getMinPassportScore(): Promise<bigint> { this.checkStrategy(); return this.contract.read.minPassportScore(); } public getMetadataRequired(): Promise<boolean> { this.checkStrategy(); return this.contract.read.metadataRequired(); } public getRegistry(): Promise<`0x${string}`> { this.checkStrategy(); return this.contract.read.registry(); } public getRecipientIdBySuperApp( superApp: `0x${string}`, ): Promise<`0x${string}`> { this.checkStrategy(); return this.contract.read.superApps([superApp]); } public getTotalUnitsByRecipient(recipientId: `0x${string}`): Promise<bigint> { this.checkStrategy(); return this.contract.read.totalUnitsByRecipient([recipientId]); } public getRecipientFlowRate(recipientId: `0x${string}`): Promise<bigint> { this.checkStrategy(); return this.contract.read.recipientFlowRate([recipientId]); } public getSuperApp(recipientId: `0x${string}`): Promise<`0x${string}`> { this.checkStrategy(); return this.contract.read.getSuperApp([recipientId]); } // Write functions public getUpdatePoolTimestampsData( registrationStartTime: bigint, registrationEndTime: bigint, allocationStartTime: bigint, allocationEndTime: bigint, ): TransactionData { this.checkStrategy(); const encodedData = encodeFunctionData({ abi: superfluidAbi, functionName: "updatePoolTimestamps", args: [ registrationStartTime, registrationEndTime, allocationStartTime, allocationEndTime, ], }); return { to: this.strategy!, data: encodedData, value: "0", }; } public getUpdateMinPassportScoreData( minPassportScore: bigint, ): TransactionData { this.checkStrategy(); const encodedData = encodeFunctionData({ abi: superfluidAbi, functionName: "updateMinPassportScore", args: [minPassportScore], }); return { to: this.strategy!, data: encodedData, value: "0", }; } public getRegisterRecipientData(data: { registryAnchor: `0x${string}`; recipientAddress: `0x${string}`; metadata: Metadata; }): TransactionData { this.checkPoolId(); const encoded: `0x${string}` = encodeAbiParameters( parseAbiParameters("address, address, (uint256, string)"), [ data.registryAnchor, data.recipientAddress, [data.metadata.protocol, data.metadata.pointer], ], ); const encodedData = encodeFunctionData({ abi: alloAbi, functionName: "registerRecipient", args: [this.poolId, encoded], }); return { to: this.allo.address(), data: encodedData, value: "0", }; } public getBatchRegisterRecipientData( data: RegisterDataSuperfluid[], ): TransactionData { this.checkPoolId(); const encodedParams: `0x${string}`[] = []; data.forEach((registerData) => { const encoded: `0x${string}` = encodeAbiParameters( parseAbiParameters("address, address, (uint256, string)"), [ registerData.registryAnchor, registerData.recipientAddress, [registerData.metadata.protocol, registerData.metadata.pointer], ], ); encodedParams.push(encoded); }); const poolIds: bigint[] = Array(encodedParams.length).fill(this.poolId); const encodedData = encodeFunctionData({ abi: alloAbi, functionName: "batchRegisterRecipient", args: [poolIds, encodedParams], }); return { to: this.allo.address(), data: encodedData, value: "0", }; } public getDistributeData(flowRate: bigint): TransactionData { this.checkPoolId(); const encoded: `0x${string}` = encodeAbiParameters( parseAbiParameters("int96"), [flowRate], ); const encodedData = encodeFunctionData({ abi: alloAbi, functionName: "distribute", args: [this.poolId, [], encoded], }); return { to: this.strategy!, data: encodedData, value: "0", }; } public getAllocationData( recipientId: `0x${string}`, flowRate: bigint, ): TransactionData { this.checkPoolId(); const encoded: `0x${string}` = encodeAbiParameters( parseAbiParameters("address, int96"), [recipientId, flowRate], ); const encodedData = encodeFunctionData({ abi: alloAbi, functionName: "allocate", args: [this.poolId, encoded], }); return { to: this.allo.address(), data: encodedData, value: "0", }; } public getBatchAllocationData( allocations: AllocationSuperlfuid[], ): TransactionData { this.checkPoolId(); const encodedParams: `0x${string}`[] = []; allocations.forEach((allocation) => { const encoded: `0x${string}` = encodeAbiParameters( parseAbiParameters("address, int96"), [allocation.recipientId, allocation.flowRate], ); encodedParams.push(encoded); }); const poolIds: bigint[] = Array(encodedParams.length).fill(this.poolId); const encodedData = encodeFunctionData({ abi: alloAbi, functionName: "batchAllocate", args: [poolIds, encodedParams], }); return { to: this.allo.address(), data: encodedData, value: "0", }; } public getReviewRecipientData( data: ReviewRecipientDataSuperfluid[], ): TransactionData { this.checkStrategy(); const recipientIds = data.map((recipient) => recipient.recipientId); const statuses = data.map((recipient) => recipient.recipientStatus); const encodedData = encodeFunctionData({ abi: superfluidAbi, functionName: "reviewRecipients", args: [recipientIds, statuses], }); return { to: this.strategy!, data: encodedData, value: "0", }; } public getCancelRecipientsData( recipientIds: `0x${string}`[], ): TransactionData { this.checkStrategy(); const encodedData = encodeFunctionData({ abi: superfluidAbi, functionName: "cancelRecipients", args: [recipientIds], }); return { to: this.strategy!, data: encodedData, value: "0", }; } public getWithdrawData( token: `0x${string}`, amount: bigint, ): TransactionData { this.checkStrategy(); const encodedData = encodeFunctionData({ abi: superfluidAbi, functionName: "withdraw", args: [token, amount], }); return { to: this.strategy!, data: encodedData, value: "0", }; } public getCloseStream(): TransactionData { this.checkStrategy(); const encodedData = encodeFunctionData({ abi: superfluidAbi, functionName: "closeStream", }); return { to: this.strategy!, data: encodedData, value: "0", }; } }