diff --git a/packages/core-sdk/package.json b/packages/core-sdk/package.json index 5bbbb09e..3af853cf 100644 --- a/packages/core-sdk/package.json +++ b/packages/core-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@story-protocol/core-sdk", - "version": "1.0.0-rc.3", + "version": "1.0.0-rc.4", "description": "Story Protocol Core SDK", "main": "dist/story-protocol-core-sdk.cjs.js", "module": "dist/story-protocol-core-sdk.esm.js", diff --git a/packages/core-sdk/src/abi/generated.ts b/packages/core-sdk/src/abi/generated.ts index f6de93b8..958a71b5 100644 --- a/packages/core-sdk/src/abi/generated.ts +++ b/packages/core-sdk/src/abi/generated.ts @@ -5745,6 +5745,19 @@ export class IpAssetRegistryClient extends IpAssetRegistryReadOnlyClient { // Contract IpRoyaltyVaultImpl ============================================================= +/** + * IpRoyaltyVaultImplRevenueTokenClaimedEvent + * + * @param claimer address + * @param token address + * @param amount uint256 + */ +export type IpRoyaltyVaultImplRevenueTokenClaimedEvent = { + claimer: Address; + token: Address; + amount: bigint; +}; + /** * IpRoyaltyVaultImplRoyaltyTokensCollectedEvent * @@ -5829,6 +5842,47 @@ export class IpRoyaltyVaultImplEventClient { this.rpcClient = rpcClient; } + /** + * event RevenueTokenClaimed for contract IpRoyaltyVaultImpl + */ + public watchRevenueTokenClaimedEvent( + onLogs: (txHash: Hex, ev: Partial) => void, + ): WatchContractEventReturnType { + return this.rpcClient.watchContractEvent({ + abi: ipRoyaltyVaultImplAbi, + address: this.address, + eventName: "RevenueTokenClaimed", + onLogs: (evs) => { + evs.forEach((it) => onLogs(it.transactionHash, it.args)); + }, + }); + } + + /** + * parse tx receipt event RevenueTokenClaimed for contract IpRoyaltyVaultImpl + */ + public parseTxRevenueTokenClaimedEvent( + txReceipt: TransactionReceipt, + ): Array { + const targetLogs: Array = []; + for (const log of txReceipt.logs) { + try { + const event = decodeEventLog({ + abi: ipRoyaltyVaultImplAbi, + eventName: "RevenueTokenClaimed", + data: log.data, + topics: log.topics, + }); + if (event.eventName === "RevenueTokenClaimed") { + targetLogs.push(event.args); + } + } catch (e) { + /* empty */ + } + } + return targetLogs; + } + /** * event RoyaltyTokensCollected for contract IpRoyaltyVaultImpl */ diff --git a/packages/core-sdk/src/resources/ipAsset.ts b/packages/core-sdk/src/resources/ipAsset.ts index 1ed373e1..1deaccf8 100644 --- a/packages/core-sdk/src/resources/ipAsset.ts +++ b/packages/core-sdk/src/resources/ipAsset.ts @@ -150,14 +150,14 @@ export class IPAssetClient { try { const isChildIpIdRegistered = await this.isRegistered(request.childIpId); if (!isChildIpIdRegistered) { - throw new Error(`The child IP with id ${request.childIpId} is not registered`); + throw new Error(`The child IP with id ${request.childIpId} is not registered.`); } for (const licenseTokenId of request.licenseTokenIds) { const tokenOwnerAddress = await this.licenseTokenReadOnlyClient.ownerOf({ tokenId: BigInt(licenseTokenId), }); if (!tokenOwnerAddress) { - throw new Error(`License token id ${licenseTokenId} must be owned by the caller`); + throw new Error(`License token id ${licenseTokenId} must be owned by the caller.`); } } const txHash = await this.licensingModuleClient.registerDerivativeWithLicenseTokens({ @@ -172,7 +172,7 @@ export class IPAssetClient { return { txHash: txHash }; } } catch (error) { - handleError(error, "Failed to register derivative with license tokens."); + handleError(error, "Failed to register derivative with license tokens"); } } diff --git a/packages/core-sdk/src/resources/license.ts b/packages/core-sdk/src/resources/license.ts index cf7c4420..e837806f 100644 --- a/packages/core-sdk/src/resources/license.ts +++ b/packages/core-sdk/src/resources/license.ts @@ -47,13 +47,13 @@ export class LicenseClient { } /** * Convenient function to register a PIL non commercial social remix license to the registry - * @param request The request object that contains all data needed to register a PIL non commercial social remix license. + * @param request [Optional] The request object that contains all data needed to register a PIL non commercial social remix license. * @param request.txOptions [Optional] The transaction options. * @returns A Promise that resolves to an object containing the optional transaction hash and optional license terms Id. * @emits LicenseTermsRegistered (licenseTermsId, licenseTemplate, licenseTerms); */ public async registerNonComSocialRemixingPIL( - request: RegisterNonComSocialRemixingPILRequest, + request?: RegisterNonComSocialRemixingPILRequest, ): Promise { try { const licenseTerms: LicenseTerms = { @@ -79,7 +79,7 @@ export class LicenseClient { return { licenseTermsId: licenseTermsId.toString() }; } const txHash = await this.licenseTemplateClient.registerLicenseTerms({ terms: licenseTerms }); - if (request.txOptions?.waitForTransaction) { + if (request?.txOptions?.waitForTransaction) { const txReceipt = await this.rpcClient.waitForTransactionReceipt({ hash: txHash }); const targetLogs = this.licenseTemplateClient.parseTxLicenseTermsRegisteredEvent(txReceipt); return { txHash: txHash, licenseTermsId: targetLogs[0].licenseTermsId.toString() }; @@ -198,37 +198,41 @@ export class LicenseClient { * @returns A Promise that resolves to an object containing the transaction hash. */ public async attachLicenseTerms(request: AttachLicenseTermsRequest) { - const isRegistered = await this.ipAssetRegistryClient.isRegistered({ id: request.ipId }); - if (!isRegistered) { - throw new Error(`The IP with id ${request.ipId} is not registered`); - } - const isExisted = await this.piLicenseTemplateReadOnlyClient.exists({ - licenseTermsId: BigInt(request.licenseTermsId), - }); - if (!isExisted) { - throw new Error(`License terms id ${request.licenseTermsId} do not exist`); - } - const isAttachedLicenseTerms = - await this.licenseRegistryReadOnlyClient.hasIpAttachedLicenseTerms({ + try { + const isRegistered = await this.ipAssetRegistryClient.isRegistered({ id: request.ipId }); + if (!isRegistered) { + throw new Error(`The IP with id ${request.ipId} is not registered.`); + } + const isExisted = await this.piLicenseTemplateReadOnlyClient.exists({ + licenseTermsId: BigInt(request.licenseTermsId), + }); + if (!isExisted) { + throw new Error(`License terms id ${request.licenseTermsId} do not exist.`); + } + const isAttachedLicenseTerms = + await this.licenseRegistryReadOnlyClient.hasIpAttachedLicenseTerms({ + ipId: request.ipId, + licenseTemplate: request.licenseTemplate || this.licenseTemplateClient.address, + licenseTermsId: BigInt(request.licenseTermsId), + }); + if (isAttachedLicenseTerms) { + throw new Error( + `License terms id ${request.licenseTermsId} is already attached to the IP with id ${request.ipId}.`, + ); + } + const txHash = await this.licensingModuleClient.attachLicenseTerms({ ipId: request.ipId, licenseTemplate: request.licenseTemplate || this.licenseTemplateClient.address, licenseTermsId: BigInt(request.licenseTermsId), }); - if (isAttachedLicenseTerms) { - throw new Error( - `License terms id ${request.licenseTermsId} is already attached to the IP with id ${request.ipId}`, - ); - } - const txHash = await this.licensingModuleClient.attachLicenseTerms({ - ipId: request.ipId, - licenseTemplate: request.licenseTemplate || this.licenseTemplateClient.address, - licenseTermsId: BigInt(request.licenseTermsId), - }); - if (request.txOptions?.waitForTransaction) { - await this.rpcClient.waitForTransactionReceipt({ hash: txHash }); - return { txHash: txHash }; - } else { - return { txHash: txHash }; + if (request.txOptions?.waitForTransaction) { + await this.rpcClient.waitForTransactionReceipt({ hash: txHash }); + return { txHash: txHash }; + } else { + return { txHash: txHash }; + } + } catch (error) { + handleError(error, "Failed to attach license terms"); } } @@ -262,13 +266,13 @@ export class LicenseClient { id: request.licensorIpId, }); if (!isLicenseIpIdRegistered) { - throw new Error(`The licensor IP with id ${request.licensorIpId} is not registered`); + throw new Error(`The licensor IP with id ${request.licensorIpId} is not registered.`); } const isExisted = await this.piLicenseTemplateReadOnlyClient.exists({ licenseTermsId: BigInt(request.licenseTermsId), }); if (!isExisted) { - throw new Error(`License terms id ${request.licenseTermsId} do not exist`); + throw new Error(`License terms id ${request.licenseTermsId} do not exist.`); } const isAttachedLicenseTerms = await this.licenseRegistryReadOnlyClient.hasIpAttachedLicenseTerms({ @@ -278,7 +282,7 @@ export class LicenseClient { }); if (!isAttachedLicenseTerms) { throw new Error( - `License terms id ${request.licenseTermsId} is not attached to the IP with id ${request.licensorIpId}`, + `License terms id ${request.licenseTermsId} is not attached to the IP with id ${request.licensorIpId}.`, ); } const txHash = await this.licensingModuleClient.mintLicenseTokens({ diff --git a/packages/core-sdk/src/resources/royalty.ts b/packages/core-sdk/src/resources/royalty.ts index 0c361fe1..39026470 100644 --- a/packages/core-sdk/src/resources/royalty.ts +++ b/packages/core-sdk/src/resources/royalty.ts @@ -11,6 +11,8 @@ import { RoyaltyVaultAddress, SnapshotRequest, SnapshotResponse, + claimRevenueRequest, + claimRevenueResponse, } from "../types/resources/royalty"; import { IpAssetRegistryClient, @@ -52,7 +54,7 @@ export class RoyaltyClient { id: request.parentIpId, }); if (!isParentIpIdRegistered) { - throw new Error(`The parent IP with id ${request.parentIpId} is not registered`); + throw new Error(`The parent IP with id ${request.parentIpId} is not registered.`); } const proxyAddress = await this.getRoyaltyVaultProxyAddress(request.royaltyVaultIpId); const ipRoyaltyVault = new IpRoyaltyVaultImplClient( @@ -150,6 +152,40 @@ export class RoyaltyClient { handleError(error, "Failed to calculate claimable revenue"); } } + + /** + * Allows token holders to claim by a list of snapshot ids based on the token balance at certain snapshot + * @param request - The request object that contains all data needed to claim revenue. + * @param request.snapshotIds The list of snapshot ids. + * @param request.royaltyVaultIpId The id of the royalty vault. + * @param request.token The revenue token to claim. + * @param request.txOptions [Optional] The transaction options. + * @returns A Promise that resolves to an object containing the transaction hash and optional claimableToken if waitForTxn is set to true. + * @emits RevenueTokenClaimed (claimer, token, amount). + */ + public async claimRevenue(request: claimRevenueRequest): Promise { + try { + const proxyAddress = await this.getRoyaltyVaultProxyAddress(request.royaltyVaultIpId); + const ipRoyaltyVault = new IpRoyaltyVaultImplClient( + this.rpcClient, + this.wallet, + proxyAddress, + ); + const txHash = await ipRoyaltyVault.claimRevenueBySnapshotBatch({ + snapshotIds: request.snapshotIds.map((id) => BigInt(id)), + token: request.token, + }); + if (request.txOptions?.waitForTransaction) { + const txReceipt = await this.rpcClient.waitForTransactionReceipt({ hash: txHash }); + const targetLogs = ipRoyaltyVault.parseTxRevenueTokenClaimedEvent(txReceipt); + return { txHash, claimableToken: targetLogs[0].amount }; + } else { + return { txHash }; + } + } catch (error) { + handleError(error, "Failed to claim revenue"); + } + } /** * Snapshots the claimable revenue and royalty token amounts. * @param request - The request object that contains all data needed to snapshot. @@ -184,13 +220,13 @@ export class RoyaltyClient { id: royaltyVaultIpId, }); if (!isRoyaltyVaultIpIdRegistered) { - throw new Error(`The royalty vault IP with id ${royaltyVaultIpId} is not registered`); + throw new Error(`The royalty vault IP with id ${royaltyVaultIpId} is not registered.`); } const data = await this.royaltyPolicyLapClient.getRoyaltyData({ ipId: royaltyVaultIpId, }); if (!data[1] || data[1] === "0x") { - throw new Error(`The royalty vault IP with id ${royaltyVaultIpId} address is not set`); + throw new Error(`The royalty vault IP with id ${royaltyVaultIpId} address is not set.`); } return data[1]; } diff --git a/packages/core-sdk/src/types/resources/royalty.ts b/packages/core-sdk/src/types/resources/royalty.ts index aec46690..2303e370 100644 --- a/packages/core-sdk/src/types/resources/royalty.ts +++ b/packages/core-sdk/src/types/resources/royalty.ts @@ -67,6 +67,18 @@ export type SnapshotRequest = { txOptions?: TxOptions; }; +export type claimRevenueRequest = { + snapshotIds: string[]; + token: Hex; + royaltyVaultIpId: Hex; + txOptions?: TxOptions; +}; + +export type claimRevenueResponse = { + txHash: string; + claimableToken?: bigint; +}; + export type SnapshotResponse = { txHash: string; snapshotId?: bigint; diff --git a/packages/core-sdk/test/integration/storyTestNet/royalty.storyTest.test.ts b/packages/core-sdk/test/integration/storyTestNet/royalty.storyTest.test.ts index 40a44678..db0be8c8 100644 --- a/packages/core-sdk/test/integration/storyTestNet/royalty.storyTest.test.ts +++ b/packages/core-sdk/test/integration/storyTestNet/royalty.storyTest.test.ts @@ -15,7 +15,7 @@ import { MockERC721, MockERC20, getTokenId } from "./util"; chai.use(chaiAsPromised); const expect = chai.expect; -let startTokenId = 180; +let startTokenId = 198; let snapshotId: bigint; describe.skip("Test royalty Functions", () => { let client: StoryClient; @@ -43,7 +43,6 @@ describe.skip("Test royalty Functions", () => { let ipId1: Hex; let ipId2: Hex; const getIpId = async (): Promise => { - console.log("startTokenId", startTokenId); const tokenId = await getTokenId(startTokenId++); const response = await client.ipAsset.register({ tokenContract: MockERC721, @@ -63,7 +62,6 @@ describe.skip("Test royalty Functions", () => { waitForTransaction: true, }, }); - console.log("licenseTermsId", response.licenseTermsId); return response.licenseTermsId!; }; @@ -80,7 +78,6 @@ describe.skip("Test royalty Functions", () => { before(async () => { ipId1 = await getIpId(); ipId2 = await getIpId(); - console.log("ipId1", ipId1, "ipId2", ipId2); const licenseTermsId = await getCommercialPolicyId(); await attachLicenseTerms(ipId1, licenseTermsId); await client.ipAsset.registerDerivative({ @@ -181,7 +178,6 @@ describe.skip("Test royalty Functions", () => { expect(response.txHash).to.be.a("string").not.empty; expect(response.snapshotId).to.be.a("bigint"); snapshotId = response.snapshotId!; - console.log("snapshot", snapshotId); }); it("should not throw error when collect royalty tokens", async () => { @@ -208,5 +204,18 @@ describe.skip("Test royalty Functions", () => { }); expect(response).to.be.a("bigint"); }); + + it("should not throw error when claim revenue", async () => { + const response = await client.royalty.claimRevenue({ + royaltyVaultIpId: ipId2, + snapshotIds: [snapshotId.toString()], + token: "0xA36F2A4A02f5C215d1b3630f71A4Ff55B5492AAE", + txOptions: { + waitForTransaction: true, + }, + }); + + expect(response.claimableToken).to.be.a("bigint"); + }); }); }); diff --git a/packages/core-sdk/test/unit/resources/ipAsset.test.ts b/packages/core-sdk/test/unit/resources/ipAsset.test.ts index 987e5bc8..837fcf9b 100644 --- a/packages/core-sdk/test/unit/resources/ipAsset.test.ts +++ b/packages/core-sdk/test/unit/resources/ipAsset.test.ts @@ -2,14 +2,11 @@ import chai from "chai"; import { createMock } from "../testUtils"; import * as sinon from "sinon"; import { IPAssetClient } from "../../../src"; -import { PublicClient, WalletClient, Account, Hex } from "viem"; +import { PublicClient, WalletClient, Account } from "viem"; import chaiAsPromised from "chai-as-promised"; chai.use(chaiAsPromised); const expect = chai.expect; -const tokenContract: Hex = "0x1daAE3197Bc469Cb97B917aa460a12dD95c6627c"; -const tokenId = "3"; -const txHash: Hex = "0x129f7dd802200f096221dd89d5b086e4bd3ad6eafb378a0c75e3b04fc375f997"; describe("Test IpAssetClient", function () { let ipAssetClient: IPAssetClient; let rpcMock: PublicClient; @@ -29,72 +26,84 @@ describe("Test IpAssetClient", function () { }); describe("Test ipAssetClient.register", async function () { - const ipId = "0xd142822Dc1674154EaF4DDF38bbF7EF8f0D8ECe4"; it("should return ipId when register given tokenId have registered", async function () { - sinon.stub(ipAssetClient.ipAssetRegistryClient, "ipId").resolves(ipId); + sinon + .stub(ipAssetClient.ipAssetRegistryClient, "ipId") + .resolves("0xd142822Dc1674154EaF4DDF38bbF7EF8f0D8ECe4"); sinon.stub(ipAssetClient.ipAssetRegistryClient, "isRegistered").resolves(true); const res = await ipAssetClient.register({ - tokenContract: tokenContract, - tokenId: tokenId, - txOptions: { - waitForTransaction: false, - }, + tokenContract: "0x1daAE3197Bc469Cb97B917aa460a12dD95c6627c", + tokenId: "3", }); - expect(res.ipId).equal(ipId); + expect(res.ipId).equal("0xd142822Dc1674154EaF4DDF38bbF7EF8f0D8ECe4"); expect(res.txHash).to.be.undefined; }); it("should return txHash when register given tokenId have no registered", async function () { - sinon.stub(ipAssetClient.ipAssetRegistryClient, "ipId").resolves(ipId); + sinon + .stub(ipAssetClient.ipAssetRegistryClient, "ipId") + .resolves("0x1daAE3197Bc469Cb97B917aa460a12dD95c6627c"); sinon.stub(ipAssetClient.ipAssetRegistryClient, "isRegistered").resolves(false); - sinon.stub(ipAssetClient.ipAssetRegistryClient, "register").resolves(txHash); + sinon + .stub(ipAssetClient.ipAssetRegistryClient, "register") + .resolves("0x129f7dd802200f096221dd89d5b086e4bd3ad6eafb378a0c75e3b04fc375f997"); + const res = await ipAssetClient.register({ - tokenContract: tokenContract, - tokenId: tokenId, - txOptions: { - waitForTransaction: false, - }, + tokenContract: "0x1daAE3197Bc469Cb97B917aa460a12dD95c6627c", + tokenId: "3", }); - expect(res.txHash).equal(txHash); + expect(res.txHash).equal( + "0x129f7dd802200f096221dd89d5b086e4bd3ad6eafb378a0c75e3b04fc375f997", + ); }); it("should return ipId and txHash when register a IP and given waitForTransaction of true and tokenId is not registered ", async function () { - sinon.stub(ipAssetClient.ipAssetRegistryClient, "ipId").resolves(ipId); + sinon + .stub(ipAssetClient.ipAssetRegistryClient, "ipId") + .resolves("0xd142822Dc1674154EaF4DDF38bbF7EF8f0D8ECe4"); sinon.stub(ipAssetClient.ipAssetRegistryClient, "isRegistered").resolves(false); - sinon.stub(ipAssetClient.ipAssetRegistryClient, "register").resolves(txHash); + sinon + .stub(ipAssetClient.ipAssetRegistryClient, "register") + .resolves("0x129f7dd802200f096221dd89d5b086e4bd3ad6eafb378a0c75e3b04fc375f997"); sinon.stub(ipAssetClient.ipAssetRegistryClient, "parseTxIpRegisteredEvent").returns([ { - ipId: ipId, + ipId: "0xd142822Dc1674154EaF4DDF38bbF7EF8f0D8ECe4", chainId: 0n, - tokenContract: tokenContract, + tokenContract: "0x1daAE3197Bc469Cb97B917aa460a12dD95c6627c", tokenId: 0n, name: "", uri: "", registrationDate: 0n, }, ]); + const response = await ipAssetClient.register({ - tokenContract: tokenContract, - tokenId: tokenId, + tokenContract: "0x1daAE3197Bc469Cb97B917aa460a12dD95c6627c", + tokenId: "3", txOptions: { waitForTransaction: true, }, }); - expect(response.txHash).equal(txHash); - expect(response.ipId).equals(ipId); + + expect(response.txHash).equal( + "0x129f7dd802200f096221dd89d5b086e4bd3ad6eafb378a0c75e3b04fc375f997", + ); + expect(response.ipId).equals("0xd142822Dc1674154EaF4DDF38bbF7EF8f0D8ECe4"); }); it("should throw error when request fails", async function () { - sinon.stub(ipAssetClient.ipAssetRegistryClient, "ipId").resolves(ipId); + sinon + .stub(ipAssetClient.ipAssetRegistryClient, "ipId") + .resolves("0xd142822Dc1674154EaF4DDF38bbF7EF8f0D8ECe4"); sinon.stub(ipAssetClient.ipAssetRegistryClient, "isRegistered").resolves(false); sinon.stub(ipAssetClient.ipAssetRegistryClient, "register").throws(new Error("revert error")); try { await ipAssetClient.register({ - tokenContract: tokenContract, - tokenId: tokenId, + tokenContract: "0x1daAE3197Bc469Cb97B917aa460a12dD95c6627c", + tokenId: "3", txOptions: { waitForTransaction: true, }, @@ -111,7 +120,7 @@ describe("Test IpAssetClient", function () { try { await ipAssetClient.registerDerivative({ childIpId: "0x1daAE3197Bc469Cb97B917aa460a12dD95c6627c", - parentIpIds: ["0x1daAE3197Bc469Cb97B917aa460a12dD95c6627a"], + parentIpIds: ["0xd142822Dc1674154EaF4DDF38bbF7EF8f0D8ECe4"], licenseTermsIds: ["1"], }); } catch (err) { @@ -128,6 +137,7 @@ describe("Test IpAssetClient", function () { .resolves(true) .onCall(1) .resolves(false); + try { await ipAssetClient.registerDerivative({ childIpId: "0x1daAE3197Bc469Cb97B917aa460a12dD95c6627c", @@ -141,20 +151,18 @@ describe("Test IpAssetClient", function () { } }); - it("should throw parentIpIds not match License terms ids error when registerDerivative given parentIds'length is not equal licenseTermsIds'length", async () => { + it("should throw not match error when registerDerivative given parentIds'length is not equal licenseTermsIds'length", async () => { sinon .stub(ipAssetClient.ipAssetRegistryClient, "isRegistered") .onCall(0) .resolves(true) .onCall(1) .resolves(true); - sinon - .stub(ipAssetClient.licenseRegistryReadOnlyClient, "hasIpAttachedLicenseTerms") - .resolves(false); + try { await ipAssetClient.registerDerivative({ childIpId: "0x1daAE3197Bc469Cb97B917aa460a12dD95c6627c", - parentIpIds: ["0x1daAE3197Bc469Cb97B917aa460a12dD95c6627a"], + parentIpIds: ["0xd142822Dc1674154EaF4DDF38bbF7EF8f0D8ECe4"], licenseTermsIds: ["1", "2"], }); } catch (err) { @@ -164,22 +172,26 @@ describe("Test IpAssetClient", function () { } }); - it("should throw parentIpIds not match License terms ids error when registerDerivative given parentIds'length is not equal licenseTermsIds'length", async () => { + it("should throw not attach error when registerDerivative given licenseTermsIds is not attached parentIpIds", async () => { sinon .stub(ipAssetClient.ipAssetRegistryClient, "isRegistered") .onCall(0) .resolves(true) .onCall(1) .resolves(true); + sinon + .stub(ipAssetClient.licenseRegistryReadOnlyClient, "hasIpAttachedLicenseTerms") + .resolves(false); + try { await ipAssetClient.registerDerivative({ childIpId: "0x1daAE3197Bc469Cb97B917aa460a12dD95c6627c", - parentIpIds: ["0x1daAE3197Bc469Cb97B917aa460a12dD95c6627a"], - licenseTermsIds: ["1", "2"], + parentIpIds: ["0xd142822Dc1674154EaF4DDF38bbF7EF8f0D8ECe4"], + licenseTermsIds: ["1"], }); } catch (err) { expect((err as Error).message).equal( - "Failed to register derivative: Parent IP IDs and License terms IDs must be provided in pairs.", + "Failed to register derivative: License terms id 1 must be attached to the parent ipId 0xd142822Dc1674154EaF4DDF38bbF7EF8f0D8ECe4 before registering derivative.", ); } }); @@ -194,13 +206,19 @@ describe("Test IpAssetClient", function () { sinon .stub(ipAssetClient.licenseRegistryReadOnlyClient, "hasIpAttachedLicenseTerms") .resolves(true); - sinon.stub(ipAssetClient.licensingModuleClient, "registerDerivative").resolves(txHash); + sinon + .stub(ipAssetClient.licensingModuleClient, "registerDerivative") + .resolves("0x129f7dd802200f096221dd89d5b086e4bd3ad6eafb378a0c75e3b04fc375f997"); + const res = await ipAssetClient.registerDerivative({ childIpId: "0x1daAE3197Bc469Cb97B917aa460a12dD95c6627c", - parentIpIds: ["0x1daAE3197Bc469Cb97B917aa460a12dD95c6627a"], + parentIpIds: ["0xd142822Dc1674154EaF4DDF38bbF7EF8f0D8ECe4"], licenseTermsIds: ["1"], }); - expect(res.txHash).equal(txHash); + + expect(res.txHash).equal( + "0x129f7dd802200f096221dd89d5b086e4bd3ad6eafb378a0c75e3b04fc375f997", + ); }); it("should return txHash when registerDerivative given correct childIpId, parentIpId, licenseTermsIds and waitForTransaction of true ", async () => { @@ -213,16 +231,111 @@ describe("Test IpAssetClient", function () { sinon .stub(ipAssetClient.licenseRegistryReadOnlyClient, "hasIpAttachedLicenseTerms") .resolves(true); - sinon.stub(ipAssetClient.licensingModuleClient, "registerDerivative").resolves(txHash); + sinon + .stub(ipAssetClient.licensingModuleClient, "registerDerivative") + .resolves("0x129f7dd802200f096221dd89d5b086e4bd3ad6eafb378a0c75e3b04fc375f997"); + const res = await ipAssetClient.registerDerivative({ childIpId: "0x1daAE3197Bc469Cb97B917aa460a12dD95c6627c", - parentIpIds: ["0x1daAE3197Bc469Cb97B917aa460a12dD95c6627a"], + parentIpIds: ["0xd142822Dc1674154EaF4DDF38bbF7EF8f0D8ECe4"], licenseTermsIds: ["1"], txOptions: { waitForTransaction: true, }, }); - expect(res.txHash).equal(txHash); + + expect(res.txHash).equal( + "0x129f7dd802200f096221dd89d5b086e4bd3ad6eafb378a0c75e3b04fc375f997", + ); + }); + }); + + describe("Test ipAssetClient.registerDerivativeWithLicenseTokens", async function () { + it("should throw childIpId error when registerDerivativeWithLicenseTokens given childIpId is not registered", async () => { + sinon.stub(ipAssetClient.ipAssetRegistryClient, "isRegistered").resolves(false); + + try { + await ipAssetClient.registerDerivativeWithLicenseTokens({ + childIpId: "0xd142822Dc1674154EaF4DDF38bbF7EF8f0D8ECe4", + licenseTokenIds: ["1"], + }); + } catch (err) { + expect((err as Error).message).equal( + "Failed to register derivative with license tokens: The child IP with id 0xd142822Dc1674154EaF4DDF38bbF7EF8f0D8ECe4 is not registered.", + ); + } + }); + + it("should throw own error when registerDerivativeWithLicenseTokens given licenseTokenIds is not belongs caller", async () => { + sinon + .stub(ipAssetClient.ipAssetRegistryClient, "isRegistered") + .onCall(0) + .resolves(true) + .onCall(1) + .resolves(true); + sinon.stub(ipAssetClient.licenseTokenReadOnlyClient, "ownerOf").resolves(undefined); + + try { + await ipAssetClient.registerDerivativeWithLicenseTokens({ + childIpId: "0xd142822Dc1674154EaF4DDF38bbF7EF8f0D8ECe4", + licenseTokenIds: ["1"], + }); + } catch (err) { + expect((err as Error).message).equal( + "Failed to register derivative with license tokens: License token id 1 must be owned by the caller.", + ); + } + }); + + it("should return txHash when registerDerivativeWithLicenseTokens given correct args", async () => { + sinon + .stub(ipAssetClient.ipAssetRegistryClient, "isRegistered") + .onCall(0) + .resolves(true) + .onCall(1) + .resolves(true); + sinon + .stub(ipAssetClient.licenseTokenReadOnlyClient, "ownerOf") + .resolves("0x73fcb515cee99e4991465ef586cfe2b072ebb512"); + sinon + .stub(ipAssetClient.licensingModuleClient, "registerDerivativeWithLicenseTokens") + .resolves("0x129f7dd802200f096221dd89d5b086e4bd3ad6eafb378a0c75e3b04fc375f997"); + + const res = await ipAssetClient.registerDerivativeWithLicenseTokens({ + childIpId: "0xd142822Dc1674154EaF4DDF38bbF7EF8f0D8ECe4", + licenseTokenIds: ["1"], + }); + + expect(res.txHash).equal( + "0x129f7dd802200f096221dd89d5b086e4bd3ad6eafb378a0c75e3b04fc375f997", + ); + }); + + it("should return txHash when registerDerivativeWithLicenseTokens given correct args and waitForTransaction of true", async () => { + sinon + .stub(ipAssetClient.ipAssetRegistryClient, "isRegistered") + .onCall(0) + .resolves(true) + .onCall(1) + .resolves(true); + sinon + .stub(ipAssetClient.licenseTokenReadOnlyClient, "ownerOf") + .resolves("0x73fcb515cee99e4991465ef586cfe2b072ebb512"); + sinon + .stub(ipAssetClient.licensingModuleClient, "registerDerivativeWithLicenseTokens") + .resolves("0x129f7dd802200f096221dd89d5b086e4bd3ad6eafb378a0c75e3b04fc375f997"); + + const res = await ipAssetClient.registerDerivativeWithLicenseTokens({ + childIpId: "0xd142822Dc1674154EaF4DDF38bbF7EF8f0D8ECe4", + licenseTokenIds: ["1"], + txOptions: { + waitForTransaction: true, + }, + }); + + expect(res.txHash).equal( + "0x129f7dd802200f096221dd89d5b086e4bd3ad6eafb378a0c75e3b04fc375f997", + ); }); }); }); diff --git a/packages/core-sdk/test/unit/resources/license.test.ts b/packages/core-sdk/test/unit/resources/license.test.ts new file mode 100644 index 00000000..adb828e3 --- /dev/null +++ b/packages/core-sdk/test/unit/resources/license.test.ts @@ -0,0 +1,437 @@ +import chai from "chai"; +import { createMock } from "../testUtils"; +import * as sinon from "sinon"; +import { LicenseClient } from "../../../src"; +import { PublicClient, WalletClient, Account } from "viem"; +import chaiAsPromised from "chai-as-promised"; +chai.use(chaiAsPromised); +const expect = chai.expect; +const txHash = "0x129f7dd802200f096221dd89d5b086e4bd3ad6eafb378a0c75e3b04fc375f997"; + +describe("Test LicenseClient", function () { + let licenseClient: LicenseClient; + let rpcMock: PublicClient; + let walletMock: WalletClient; + + beforeEach(function () { + rpcMock = createMock(); + walletMock = createMock(); + const accountMock = createMock(); + accountMock.address = "0x73fcb515cee99e4991465ef586cfe2b072ebb512"; + walletMock.account = accountMock; + licenseClient = new LicenseClient(rpcMock, walletMock); + }); + + afterEach(function () { + sinon.restore(); + }); + + describe("Test licenseClient.registerNonComSocialRemixingPIL", async function () { + it("should return licenseTermsId when call registerNonComSocialRemixingPIL given licenseTermsId is registered", async function () { + sinon + .stub(licenseClient.licenseTemplateClient, "getLicenseTermsId") + .resolves({ selectedLicenseTermsId: BigInt(1) }); + + const result = await licenseClient.registerNonComSocialRemixingPIL(); + + expect(result.licenseTermsId).to.equal("1"); + }); + + it("should return txhash when call registerNonComSocialRemixingPIL given licenseTermsId is not registered", async function () { + sinon + .stub(licenseClient.licenseTemplateClient, "getLicenseTermsId") + .resolves({ selectedLicenseTermsId: BigInt(0) }); + sinon.stub(licenseClient.licenseTemplateClient, "registerLicenseTerms").resolves(txHash); + + const result = await licenseClient.registerNonComSocialRemixingPIL(); + + expect(result.txHash).to.equal(txHash); + }); + + it("should return txhash when call registerNonComSocialRemixingPIL given licenseTermsId is not registered and waitForTransaction of true", async function () { + sinon + .stub(licenseClient.licenseTemplateClient, "getLicenseTermsId") + .resolves({ selectedLicenseTermsId: BigInt(0) }); + sinon.stub(licenseClient.licenseTemplateClient, "registerLicenseTerms").resolves(txHash); + sinon + .stub(licenseClient.licenseTemplateClient, "parseTxLicenseTermsRegisteredEvent") + .returns([ + { + licenseTermsId: BigInt(1), + licenseTemplate: "0x", + licenseTerms: "0x", + }, + ]); + + const result = await licenseClient.registerNonComSocialRemixingPIL({ + txOptions: { + waitForTransaction: true, + }, + }); + + expect(result.txHash).to.equal(txHash); + expect(result.licenseTermsId).to.equal("1"); + }); + + it("should return throw error when call registerNonComSocialRemixingPIL given request fail", async function () { + sinon + .stub(licenseClient.licenseTemplateClient, "getLicenseTermsId") + .resolves({ selectedLicenseTermsId: BigInt(0) }); + sinon + .stub(licenseClient.licenseTemplateClient, "registerLicenseTerms") + .throws(new Error("request fail.")); + try { + await licenseClient.registerNonComSocialRemixingPIL({ + txOptions: { + waitForTransaction: true, + }, + }); + } catch (error) { + expect((error as Error).message).equal( + "Failed to register non commercial social remixing PIL: request fail.", + ); + } + }); + }); + + describe("Test licenseClient.registerCommercialUsePIL", async function () { + it("should return licenseTermsId when call registerCommercialUsePIL given licenseTermsId is registered", async function () { + sinon + .stub(licenseClient.licenseTemplateClient, "getLicenseTermsId") + .resolves({ selectedLicenseTermsId: BigInt(1) }); + + const result = await licenseClient.registerCommercialUsePIL({ + mintingFee: "1", + currency: "0x", + }); + + expect(result.licenseTermsId).to.equal("1"); + }); + + it("should return txhash when call registerCommercialUsePIL given licenseTermsId is not registered", async function () { + sinon + .stub(licenseClient.licenseTemplateClient, "getLicenseTermsId") + .resolves({ selectedLicenseTermsId: BigInt(0) }); + sinon.stub(licenseClient.licenseTemplateClient, "registerLicenseTerms").resolves(txHash); + + const result = await licenseClient.registerCommercialUsePIL({ + mintingFee: "1", + currency: "0x", + }); + + expect(result.txHash).to.equal(txHash); + }); + + it("should return txhash when call registerCommercialUsePIL given licenseTermsId is not registered and waitForTransaction of true", async function () { + sinon + .stub(licenseClient.licenseTemplateClient, "getLicenseTermsId") + .resolves({ selectedLicenseTermsId: BigInt(0) }); + sinon.stub(licenseClient.licenseTemplateClient, "registerLicenseTerms").resolves(txHash); + sinon + .stub(licenseClient.licenseTemplateClient, "parseTxLicenseTermsRegisteredEvent") + .returns([ + { + licenseTermsId: BigInt(1), + licenseTemplate: "0x", + licenseTerms: "0x", + }, + ]); + + const result = await licenseClient.registerCommercialUsePIL({ + mintingFee: "1", + currency: "0x", + txOptions: { + waitForTransaction: true, + }, + }); + + expect(result.txHash).to.equal(txHash); + expect(result.licenseTermsId).to.equal("1"); + }); + + it("should return throw error when call registerCommercialUsePIL given request fail", async function () { + sinon + .stub(licenseClient.licenseTemplateClient, "getLicenseTermsId") + .resolves({ selectedLicenseTermsId: BigInt(0) }); + sinon + .stub(licenseClient.licenseTemplateClient, "registerLicenseTerms") + .throws(new Error("request fail.")); + + try { + await licenseClient.registerCommercialUsePIL({ + mintingFee: "1", + currency: "0x", + }); + } catch (error) { + expect((error as Error).message).equal( + "Failed to register commercial use PIL: request fail.", + ); + } + }); + }); + + describe("Test licenseClient.registerCommercialRemixPIL", async function () { + it("should return licenseTermsId when call registerCommercialRemixPIL given licenseTermsId is registered", async function () { + sinon + .stub(licenseClient.licenseTemplateClient, "getLicenseTermsId") + .resolves({ selectedLicenseTermsId: BigInt(1) }); + + const result = await licenseClient.registerCommercialRemixPIL({ + mintingFee: "1", + commercialRevShare: 100, + currency: "0x", + }); + + expect(result.licenseTermsId).to.equal("1"); + }); + + it("should return txhash when call registerCommercialRemixPIL given licenseTermsId is not registered", async function () { + sinon + .stub(licenseClient.licenseTemplateClient, "getLicenseTermsId") + .resolves({ selectedLicenseTermsId: BigInt(0) }); + sinon.stub(licenseClient.licenseTemplateClient, "registerLicenseTerms").resolves(txHash); + + const result = await licenseClient.registerCommercialRemixPIL({ + mintingFee: "1", + commercialRevShare: 100, + currency: "0x", + }); + + expect(result.txHash).to.equal(txHash); + }); + + it("should return txhash when call registerCommercialRemixPIL given licenseTermsId is not registered and waitForTransaction of true", async function () { + sinon + .stub(licenseClient.licenseTemplateClient, "getLicenseTermsId") + .resolves({ selectedLicenseTermsId: BigInt(0) }); + sinon.stub(licenseClient.licenseTemplateClient, "registerLicenseTerms").resolves(txHash); + sinon + .stub(licenseClient.licenseTemplateClient, "parseTxLicenseTermsRegisteredEvent") + .returns([ + { + licenseTermsId: BigInt(1), + licenseTemplate: "0x", + licenseTerms: "0x", + }, + ]); + + const result = await licenseClient.registerCommercialRemixPIL({ + mintingFee: "1", + commercialRevShare: 100, + currency: "0x", + txOptions: { + waitForTransaction: true, + }, + }); + + expect(result.txHash).to.equal(txHash); + expect(result.licenseTermsId).to.equal("1"); + }); + + it("should return throw error when call registerCommercialRemixPIL given request fail", async function () { + sinon + .stub(licenseClient.licenseTemplateClient, "getLicenseTermsId") + .resolves({ selectedLicenseTermsId: BigInt(0) }); + sinon + .stub(licenseClient.licenseTemplateClient, "registerLicenseTerms") + .throws(new Error("request fail.")); + try { + await licenseClient.registerCommercialRemixPIL({ + mintingFee: "1", + commercialRevShare: 100, + currency: "0x", + }); + } catch (error) { + expect((error as Error).message).equal( + "Failed to register commercial remix PIL: request fail.", + ); + } + }); + }); + + describe("Test licenseClient.attachLicenseTerms", async function () { + it("should throw ipId is not registered when call attachLicenseTerms given ipId is not registered", async function () { + sinon.stub(licenseClient.ipAssetRegistryClient, "isRegistered").resolves(false); + + try { + await licenseClient.attachLicenseTerms({ + ipId: "0x", + licenseTermsId: "1", + }); + } catch (error) { + expect((error as Error).message).equal( + "Failed to attach license terms: The IP with id 0x is not registered.", + ); + } + }); + + it("should throw licenseTermsId error when call attachLicenseTerms given licenseTermsId is not exist", async function () { + sinon.stub(licenseClient.ipAssetRegistryClient, "isRegistered").resolves(true); + sinon.stub(licenseClient.piLicenseTemplateReadOnlyClient, "exists").resolves(false); + + try { + await licenseClient.attachLicenseTerms({ + ipId: "0x", + licenseTermsId: "1", + }); + } catch (error) { + expect((error as Error).message).equal( + "Failed to attach license terms: License terms id 1 do not exist.", + ); + } + }); + + it("should throw attached error when call attachLicenseTerms given licenseTermsId is already attached", async function () { + sinon.stub(licenseClient.ipAssetRegistryClient, "isRegistered").resolves(true); + sinon.stub(licenseClient.piLicenseTemplateReadOnlyClient, "exists").resolves(true); + sinon + .stub(licenseClient.licenseRegistryReadOnlyClient, "hasIpAttachedLicenseTerms") + .resolves(true); + + try { + await licenseClient.attachLicenseTerms({ + ipId: "0x", + licenseTermsId: "1", + }); + } catch (error) { + expect((error as Error).message).equal( + "Failed to attach license terms: License terms id 1 is already attached to the IP with id 0x.", + ); + } + }); + + it("should return txHash when call attachLicenseTerms given args is correct", async function () { + sinon.stub(licenseClient.ipAssetRegistryClient, "isRegistered").resolves(true); + sinon.stub(licenseClient.piLicenseTemplateReadOnlyClient, "exists").resolves(true); + sinon + .stub(licenseClient.licenseRegistryReadOnlyClient, "hasIpAttachedLicenseTerms") + .resolves(false); + sinon.stub(licenseClient.licensingModuleClient, "attachLicenseTerms").resolves(txHash); + + const result = await licenseClient.attachLicenseTerms({ + ipId: "0x", + licenseTermsId: "1", + }); + + expect(result.txHash).to.equal(txHash); + }); + + it("should return txHash when call attachLicenseTerms given args is correct and waitForTransaction of true", async function () { + sinon.stub(licenseClient.ipAssetRegistryClient, "isRegistered").resolves(true); + sinon.stub(licenseClient.piLicenseTemplateReadOnlyClient, "exists").resolves(true); + sinon + .stub(licenseClient.licenseRegistryReadOnlyClient, "hasIpAttachedLicenseTerms") + .resolves(false); + sinon.stub(licenseClient.licensingModuleClient, "attachLicenseTerms").resolves(txHash); + + const result = await licenseClient.attachLicenseTerms({ + ipId: "0x", + licenseTermsId: "1", + txOptions: { + waitForTransaction: true, + }, + }); + + expect(result.txHash).to.equal(txHash); + }); + }); + + describe("Test licenseClient.mintLicenseTokens", async function () { + it("should throw licensor ipId error when call mintLicenseTokens given licensorIpId is not registered", async function () { + sinon.stub(licenseClient.ipAssetRegistryClient, "isRegistered").resolves(false); + + try { + await licenseClient.mintLicenseTokens({ + licensorIpId: "0x", + licenseTermsId: "1", + }); + } catch (error) { + expect((error as Error).message).equal( + "Failed to mint license tokens: The licensor IP with id 0x is not registered.", + ); + } + }); + + it("should throw licenseTermsId error when call mintLicenseTokens given licenseTermsId is not exist", async function () { + sinon.stub(licenseClient.ipAssetRegistryClient, "isRegistered").resolves(true); + sinon.stub(licenseClient.piLicenseTemplateReadOnlyClient, "exists").resolves(false); + + try { + await licenseClient.mintLicenseTokens({ + licensorIpId: "0x", + licenseTermsId: "1", + }); + } catch (error) { + expect((error as Error).message).equal( + "Failed to mint license tokens: License terms id 1 do not exist.", + ); + } + }); + + it("should throw attached error when call mintLicenseTokens given licenseTermsId is not attached", async function () { + sinon.stub(licenseClient.ipAssetRegistryClient, "isRegistered").resolves(true); + sinon.stub(licenseClient.piLicenseTemplateReadOnlyClient, "exists").resolves(true); + sinon + .stub(licenseClient.licenseRegistryReadOnlyClient, "hasIpAttachedLicenseTerms") + .resolves(false); + + try { + await licenseClient.mintLicenseTokens({ + licensorIpId: "0x", + licenseTermsId: "1", + }); + } catch (error) { + expect((error as Error).message).equal( + "Failed to mint license tokens: License terms id 1 is not attached to the IP with id 0x.", + ); + } + }); + + it("should return txHash when call mintLicenseTokens given args is correct", async function () { + sinon.stub(licenseClient.ipAssetRegistryClient, "isRegistered").resolves(true); + sinon.stub(licenseClient.piLicenseTemplateReadOnlyClient, "exists").resolves(true); + sinon + .stub(licenseClient.licenseRegistryReadOnlyClient, "hasIpAttachedLicenseTerms") + .resolves(true); + sinon.stub(licenseClient.licensingModuleClient, "mintLicenseTokens").resolves(txHash); + + const result = await licenseClient.mintLicenseTokens({ + licensorIpId: "0x", + licenseTermsId: "1", + }); + + expect(result.txHash).to.equal(txHash); + }); + + it("should return txHash when call mintLicenseTokens given args is correct and waitForTransaction of true", async function () { + sinon.stub(licenseClient.ipAssetRegistryClient, "isRegistered").resolves(true); + sinon.stub(licenseClient.piLicenseTemplateReadOnlyClient, "exists").resolves(true); + sinon + .stub(licenseClient.licenseRegistryReadOnlyClient, "hasIpAttachedLicenseTerms") + .resolves(true); + sinon.stub(licenseClient.licensingModuleClient, "mintLicenseTokens").resolves(txHash); + sinon.stub(licenseClient.licensingModuleClient, "parseTxLicenseTokensMintedEvent").returns([ + { + caller: "0x", + licensorIpId: "0x", + licenseTemplate: "0x", + licenseTermsId: BigInt(1), + amount: BigInt(1), + receiver: "0x", + startLicenseTokenId: BigInt(1), + }, + ]); + + const result = await licenseClient.mintLicenseTokens({ + licensorIpId: "0x", + licenseTermsId: "1", + txOptions: { + waitForTransaction: true, + }, + }); + + expect(result.txHash).to.equal(txHash); + expect(result.licenseTokenId).to.equal("1"); + }); + }); +}); diff --git a/packages/core-sdk/test/unit/resources/royalty.test.ts b/packages/core-sdk/test/unit/resources/royalty.test.ts new file mode 100644 index 00000000..da5a44a6 --- /dev/null +++ b/packages/core-sdk/test/unit/resources/royalty.test.ts @@ -0,0 +1,107 @@ +import chai from "chai"; +import { createMock } from "../testUtils"; +import * as sinon from "sinon"; +import { PublicClient, WalletClient, Account } from "viem"; +import chaiAsPromised from "chai-as-promised"; +import { RoyaltyClient } from "../../../src/resources/royalty"; +import { + IpRoyaltyVaultImplClient, + RoyaltyPolicyLapGetRoyaltyDataResponse, +} from "../../../src/abi/generated"; + +chai.use(chaiAsPromised); +const expect = chai.expect; +const txHash = "0x129f7dd802200f096221dd89d5b086e4bd3ad6eafb378a0c75e3b04fc375f997"; + +describe("Test RoyaltyClient", function () { + let royaltyClient: RoyaltyClient; + let rpcMock: PublicClient; + let walletMock: WalletClient; + + beforeEach(function () { + rpcMock = createMock(); + walletMock = createMock(); + const accountMock = createMock(); + accountMock.address = "0x73fcb515cee99e4991465ef586cfe2b072ebb512"; + walletMock.account = accountMock; + royaltyClient = new RoyaltyClient(rpcMock, walletMock); + sinon.stub(); + }); + + afterEach(function () { + sinon.restore(); + }); + + describe("Test royaltyClient.collectRoyaltyTokens", async function () { + it("should throw parentIpId error when call collectRoyaltyTokens given parentIpId is not registered", async function () { + sinon.stub(royaltyClient.ipAssetRegistryClient, "isRegistered").resolves(false); + + try { + await royaltyClient.collectRoyaltyTokens({ + parentIpId: "0x73fcb515cee99e4991465ef586cfe2b072ebb512", + royaltyVaultIpId: "0x73fcb515cee99e4991465ef586cfe2b072ebb512", + }); + } catch (err) { + expect((err as Error).message).equals( + "Failed to collect royalty tokens: The parent IP with id 0x73fcb515cee99e4991465ef586cfe2b072ebb512 is not registered.", + ); + } + }); + + it("should throw royaltyVaultIpId error when call collectRoyaltyTokens given royaltyVaultIpId is not registered", async function () { + sinon + .stub(royaltyClient.ipAssetRegistryClient, "isRegistered") + .onFirstCall() + .resolves(true) + .onSecondCall() + .resolves(false); + + try { + await royaltyClient.collectRoyaltyTokens({ + parentIpId: "0x73fcb515cee99e4991465ef586cfe2b072ebb512", + royaltyVaultIpId: "0x73fcb515cee99e4991465ef586cfe2b072ebb512", + }); + } catch (err) { + expect((err as Error).message).equals( + "Failed to collect royalty tokens: The royalty vault IP with id 0x73fcb515cee99e4991465ef586cfe2b072ebb512 is not registered.", + ); + } + }); + + it("should throw royaltyVaultAddress error when call collectRoyaltyTokens given royalty vault address is empty", async function () { + sinon.stub(royaltyClient.ipAssetRegistryClient, "isRegistered").resolves(true); + sinon + .stub(royaltyClient.royaltyPolicyLapClient, "getRoyaltyData") + .resolves([] as unknown as RoyaltyPolicyLapGetRoyaltyDataResponse); + + try { + await royaltyClient.collectRoyaltyTokens({ + parentIpId: "0x73fcb515cee99e4991465ef586cfe2b072ebb512", + royaltyVaultIpId: "0x73fcb515cee99e4991465ef586cfe2b072ebb512", + }); + } catch (err) { + expect((err as Error).message).equals( + "Failed to collect royalty tokens: The royalty vault IP with id 0x73fcb515cee99e4991465ef586cfe2b072ebb512 address is not set.", + ); + } + }); + + it("should throw royaltyVaultAddress error when call collectRoyaltyTokens given royalty vault address is 0x", async function () { + sinon.stub(royaltyClient.ipAssetRegistryClient, "isRegistered").resolves(true); + sinon + .stub(royaltyClient.royaltyPolicyLapClient, "getRoyaltyData") + .resolves([true, "0x", 1, ["0x73fcb515cee99e4991465ef586cfe2b072ebb512"], [1]]); + + try { + await royaltyClient.collectRoyaltyTokens({ + parentIpId: "0x73fcb515cee99e4991465ef586cfe2b072ebb512", + royaltyVaultIpId: "0x73fcb515cee99e4991465ef586cfe2b072ebb512", + }); + } catch (err) { + expect((err as Error).message).equals( + "Failed to collect royalty tokens: The royalty vault IP with id 0x73fcb515cee99e4991465ef586cfe2b072ebb512 address is not set.", + ); + } + }); + }); +}); diff --git a/packages/wagmi-generater/wagmi.config.ts b/packages/wagmi-generater/wagmi.config.ts index 2de90882..032da8dc 100644 --- a/packages/wagmi-generater/wagmi.config.ts +++ b/packages/wagmi-generater/wagmi.config.ts @@ -130,7 +130,8 @@ export default defineConfig(async () => { "ipId", "RoyaltyTokensCollected", "snapshot", - "SnapshotCompleted" + "SnapshotCompleted", + "RevenueTokenClaimed" ], "PiLicenseTemplate": [ "getLicenseTermsId",