diff --git a/packages/web3/src/ContractTypes.ts b/packages/web3/src/ContractTypes.ts index f980e2389..c58103eba 100644 --- a/packages/web3/src/ContractTypes.ts +++ b/packages/web3/src/ContractTypes.ts @@ -188,7 +188,10 @@ export type MembershipInfo = Pick< MembershipInfoStruct, 'maxSupply' | 'currency' | 'feeRecipient' | 'price' | 'duration' | 'pricingModule' > & - TotalSupplyInfo + TotalSupplyInfo & { + prepaidSupply: number + remainingFreeSupply: number + } export type TotalSupplyInfo = Pick diff --git a/packages/web3/src/ISpaceDapp.ts b/packages/web3/src/ISpaceDapp.ts index 3dffb1f07..14a3d21fb 100644 --- a/packages/web3/src/ISpaceDapp.ts +++ b/packages/web3/src/ISpaceDapp.ts @@ -269,7 +269,11 @@ export interface ISpaceDapp { ) => Promise getSpace(spaceId: string): Space | undefined getSpaceMembershipTokenAddress: (spaceId: string) => Promise - getJoinSpacePrice: (spaceId: string) => Promise + getJoinSpacePriceDetails: (spaceId: string) => Promise<{ + price: ethers.BigNumber + prepaidSupply: ethers.BigNumber + remainingFreeSupply: ethers.BigNumber + }> joinSpace: ( spaceId: string, recipient: string, @@ -312,4 +316,5 @@ export interface ISpaceDapp { receiver: string, abortController?: AbortController, ) => Promise<{ issued: true; tokenId: string } | { issued: false; tokenId: undefined }> + getMembershipFreeAllocation: (spaceId: string) => Promise } diff --git a/packages/web3/src/v3/PlatformRequirements.ts b/packages/web3/src/v3/PlatformRequirements.ts index 84254f2d6..222e4bf88 100644 --- a/packages/web3/src/v3/PlatformRequirements.ts +++ b/packages/web3/src/v3/PlatformRequirements.ts @@ -13,6 +13,10 @@ export class PlatformRequirements extends BaseContractShim { + public async getJoinSpacePriceDetails(spaceId: string): Promise<{ + price: ethers.BigNumber + prepaidSupply: ethers.BigNumber + remainingFreeSupply: ethers.BigNumber + }> { const space = this.getSpace(spaceId) if (!space) { throw new Error(`Space with spaceId "${spaceId}" is not found.`) } const prepaidSupply = await space.Prepay.read.prepaidMembershipSupply() + const membershipPrice = await space.Membership.read.getMembershipPrice() + const freeAllocation = await this.getMembershipFreeAllocation(spaceId) + const totalSupply = await space.ERC721A.read.totalSupply() + // totalSupply = number of memberships minted + // freeAllocation = number of memberships that are free to mint, set during space creation + // prepaidSupply = number of additional prepaid memberships + const remainingFreeSupply = totalSupply.lt(freeAllocation) + ? freeAllocation.add(prepaidSupply).sub(totalSupply) + : prepaidSupply + + return { + price: prepaidSupply.gt(0) ? ethers.BigNumber.from(0) : membershipPrice, + prepaidSupply, + remainingFreeSupply, + } + } - if (prepaidSupply.gt(0)) { - return ethers.BigNumber.from(0) + public async getMembershipFreeAllocation(spaceId: string) { + const space = this.getSpace(spaceId) + if (!space) { + throw new Error(`Space with spaceId "${spaceId}" is not found.`) } - return space.Membership.read.getMembershipPrice() + return space.Membership.read.getMembershipFreeAllocation() } public async joinSpace( @@ -1365,26 +1388,36 @@ export class SpaceDapp implements ISpaceDapp { if (!space) { throw new Error(`Space with spaceId "${spaceId}" is not found.`) } - const [price, limit, currency, feeRecipient, duration, totalSupply, pricingModule] = - await Promise.all([ - this.getJoinSpacePrice(spaceId), - space.Membership.read.getMembershipLimit(), - space.Membership.read.getMembershipCurrency(), - space.Ownable.read.owner(), - space.Membership.read.getMembershipDuration(), - space.ERC721A.read.totalSupply(), - space.Membership.read.getMembershipPricingModule(), - ]) + const [ + joinSpacePriceDetails, + limit, + currency, + feeRecipient, + duration, + totalSupply, + pricingModule, + ] = await Promise.all([ + this.getJoinSpacePriceDetails(spaceId), + space.Membership.read.getMembershipLimit(), + space.Membership.read.getMembershipCurrency(), + space.Ownable.read.owner(), + space.Membership.read.getMembershipDuration(), + space.ERC721A.read.totalSupply(), + space.Membership.read.getMembershipPricingModule(), + ]) + const { price, prepaidSupply, remainingFreeSupply } = joinSpacePriceDetails return { - price: price, // keep as BigNumber (wei) + price, // keep as BigNumber (wei) maxSupply: limit.toNumber(), currency: currency, feeRecipient: feeRecipient, duration: duration.toNumber(), totalSupply: totalSupply.toNumber(), pricingModule: pricingModule, - } + prepaidSupply: prepaidSupply.toNumber(), + remainingFreeSupply: remainingFreeSupply.toNumber(), + } satisfies MembershipInfo } public getWalletLink(): WalletLink {