diff --git a/config/abi.ts b/config/abi.ts new file mode 100644 index 0000000..e31a7fd --- /dev/null +++ b/config/abi.ts @@ -0,0 +1,387 @@ +export const accessControllerAbi = [ + { + type: "constructor", + inputs: [ + { name: "ipAccountRegistry", internalType: "address", type: "address" }, + { name: "moduleRegistry", internalType: "address", type: "address" }, + ], + stateMutability: "nonpayable", + }, + { + type: "error", + inputs: [ + { name: "signer", internalType: "address", type: "address" }, + { name: "to", internalType: "address", type: "address" }, + ], + name: "AccessController__BothCallerAndRecipientAreNotRegisteredModule", + }, + { + type: "error", + inputs: [], + name: "AccessController__CallerIsNotIPAccountOrOwner", + }, + { + type: "error", + inputs: [{ name: "ipAccount", internalType: "address", type: "address" }], + name: "AccessController__IPAccountIsNotValid", + }, + { + type: "error", + inputs: [], + name: "AccessController__IPAccountIsZeroAddress", + }, + { + type: "error", + inputs: [ + { name: "ipAccount", internalType: "address", type: "address" }, + { name: "signer", internalType: "address", type: "address" }, + { name: "to", internalType: "address", type: "address" }, + { name: "func", internalType: "bytes4", type: "bytes4" }, + ], + name: "AccessController__PermissionDenied", + }, + { type: "error", inputs: [], name: "AccessController__PermissionIsNotValid" }, + { type: "error", inputs: [], name: "AccessController__SignerIsZeroAddress" }, + { + type: "error", + inputs: [], + name: "AccessController__ToAndFuncAreZeroAddressShouldCallSetAllPermissions", + }, + { type: "error", inputs: [], name: "AccessController__ZeroAccessManager" }, + { + type: "error", + inputs: [], + name: "AccessController__ZeroIPAccountRegistry", + }, + { type: "error", inputs: [], name: "AccessController__ZeroModuleRegistry" }, + { + type: "error", + inputs: [{ name: "authority", internalType: "address", type: "address" }], + name: "AccessManagedInvalidAuthority", + }, + { + type: "error", + inputs: [ + { name: "caller", internalType: "address", type: "address" }, + { name: "delay", internalType: "uint32", type: "uint32" }, + ], + name: "AccessManagedRequiredDelay", + }, + { + type: "error", + inputs: [{ name: "caller", internalType: "address", type: "address" }], + name: "AccessManagedUnauthorized", + }, + { + type: "error", + inputs: [{ name: "target", internalType: "address", type: "address" }], + name: "AddressEmptyCode", + }, + { + type: "error", + inputs: [{ name: "implementation", internalType: "address", type: "address" }], + name: "ERC1967InvalidImplementation", + }, + { type: "error", inputs: [], name: "ERC1967NonPayable" }, + { type: "error", inputs: [], name: "EnforcedPause" }, + { type: "error", inputs: [], name: "ExpectedPause" }, + { type: "error", inputs: [], name: "FailedInnerCall" }, + { type: "error", inputs: [], name: "InvalidInitialization" }, + { type: "error", inputs: [], name: "NotInitializing" }, + { type: "error", inputs: [], name: "UUPSUnauthorizedCallContext" }, + { + type: "error", + inputs: [{ name: "slot", internalType: "bytes32", type: "bytes32" }], + name: "UUPSUnsupportedProxiableUUID", + }, + { + type: "event", + anonymous: false, + inputs: [ + { + name: "authority", + internalType: "address", + type: "address", + indexed: false, + }, + ], + name: "AuthorityUpdated", + }, + { + type: "event", + anonymous: false, + inputs: [ + { + name: "version", + internalType: "uint64", + type: "uint64", + indexed: false, + }, + ], + name: "Initialized", + }, + { + type: "event", + anonymous: false, + inputs: [ + { + name: "account", + internalType: "address", + type: "address", + indexed: false, + }, + ], + name: "Paused", + }, + { + type: "event", + anonymous: false, + inputs: [ + { + name: "ipAccountOwner", + internalType: "address", + type: "address", + indexed: false, + }, + { + name: "ipAccount", + internalType: "address", + type: "address", + indexed: true, + }, + { + name: "signer", + internalType: "address", + type: "address", + indexed: true, + }, + { name: "to", internalType: "address", type: "address", indexed: true }, + { name: "func", internalType: "bytes4", type: "bytes4", indexed: false }, + { + name: "permission", + internalType: "uint8", + type: "uint8", + indexed: false, + }, + ], + name: "PermissionSet", + }, + { + type: "event", + anonymous: false, + inputs: [ + { + name: "account", + internalType: "address", + type: "address", + indexed: false, + }, + ], + name: "Unpaused", + }, + { + type: "event", + anonymous: false, + inputs: [ + { + name: "implementation", + internalType: "address", + type: "address", + indexed: true, + }, + ], + name: "Upgraded", + }, + { + type: "function", + inputs: [], + name: "IP_ACCOUNT_REGISTRY", + outputs: [ + { + name: "", + internalType: "contract IIPAccountRegistry", + type: "address", + }, + ], + stateMutability: "view", + }, + { + type: "function", + inputs: [], + name: "MODULE_REGISTRY", + outputs: [{ name: "", internalType: "contract IModuleRegistry", type: "address" }], + stateMutability: "view", + }, + { + type: "function", + inputs: [], + name: "UPGRADE_INTERFACE_VERSION", + outputs: [{ name: "", internalType: "string", type: "string" }], + stateMutability: "view", + }, + { + type: "function", + inputs: [{ name: "accessManager", internalType: "address", type: "address" }], + name: "__ProtocolPausable_init", + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "function", + inputs: [], + name: "authority", + outputs: [{ name: "", internalType: "address", type: "address" }], + stateMutability: "view", + }, + { + type: "function", + inputs: [ + { name: "ipAccount", internalType: "address", type: "address" }, + { name: "signer", internalType: "address", type: "address" }, + { name: "to", internalType: "address", type: "address" }, + { name: "func", internalType: "bytes4", type: "bytes4" }, + ], + name: "checkPermission", + outputs: [], + stateMutability: "view", + }, + { + type: "function", + inputs: [ + { name: "ipAccount", internalType: "address", type: "address" }, + { name: "signer", internalType: "address", type: "address" }, + { name: "to", internalType: "address", type: "address" }, + { name: "func", internalType: "bytes4", type: "bytes4" }, + ], + name: "getPermission", + outputs: [{ name: "", internalType: "uint8", type: "uint8" }], + stateMutability: "view", + }, + { + type: "function", + inputs: [{ name: "accessManager", internalType: "address", type: "address" }], + name: "initialize", + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "function", + inputs: [], + name: "isConsumingScheduledOp", + outputs: [{ name: "", internalType: "bytes4", type: "bytes4" }], + stateMutability: "view", + }, + { + type: "function", + inputs: [], + name: "pause", + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "function", + inputs: [], + name: "paused", + outputs: [{ name: "", internalType: "bool", type: "bool" }], + stateMutability: "view", + }, + { + type: "function", + inputs: [], + name: "proxiableUUID", + outputs: [{ name: "", internalType: "bytes32", type: "bytes32" }], + stateMutability: "view", + }, + { + type: "function", + inputs: [ + { name: "ipAccount", internalType: "address", type: "address" }, + { name: "signer", internalType: "address", type: "address" }, + { name: "permission", internalType: "uint8", type: "uint8" }, + ], + name: "setAllPermissions", + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "function", + inputs: [{ name: "newAuthority", internalType: "address", type: "address" }], + name: "setAuthority", + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "function", + inputs: [ + { + name: "permissions", + internalType: "struct AccessPermission.Permission[]", + type: "tuple[]", + components: [ + { name: "ipAccount", internalType: "address", type: "address" }, + { name: "signer", internalType: "address", type: "address" }, + { name: "to", internalType: "address", type: "address" }, + { name: "func", internalType: "bytes4", type: "bytes4" }, + { name: "permission", internalType: "uint8", type: "uint8" }, + ], + }, + ], + name: "setBatchPermissions", + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "function", + inputs: [ + { name: "ipAccount", internalType: "address", type: "address" }, + { name: "signer", internalType: "address", type: "address" }, + { name: "to", internalType: "address", type: "address" }, + { name: "func", internalType: "bytes4", type: "bytes4" }, + { name: "permission", internalType: "uint8", type: "uint8" }, + ], + name: "setPermission", + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "function", + inputs: [], + name: "unpause", + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "function", + inputs: [ + { name: "newImplementation", internalType: "address", type: "address" }, + { name: "data", internalType: "bytes", type: "bytes" }, + ], + name: "upgradeToAndCall", + outputs: [], + stateMutability: "payable", + }, +] as const; + +export const transferLicenseTokenAbi = { + inputs: [ + { internalType: "address", name: "from", type: "address" }, + { internalType: "address", name: "to", type: "address" }, + { internalType: "uint256", name: "tokenId", type: "uint256" } + ], + name: "transferFrom", + outputs: [], + stateMutability: "nonpayable", + type: "function", +}; + +export const getLicenseTokenOwnerAbi = { + inputs: [ + { internalType: 'uint256', name: 'tokenId', type: 'uint256' } + ], + name: 'ownerOf', + outputs: [ + { internalType: 'address', name: 'address', type: 'address' } + ], + stateMutability: 'view', + type: 'function' +}; diff --git a/config/config.ts b/config/config.ts index 4c39712..73eb9b1 100644 --- a/config/config.ts +++ b/config/config.ts @@ -6,6 +6,7 @@ import { SupportedChainIds } from "@story-protocol/core-sdk/dist/declarations/sr const TEST_ENV = process.env.TEST_ENV as SupportedChainIds; export let licensingModuleAddress: Hex; +export let licenseTokenAddress: Hex; export let nftContractAddress: Hex; export let royaltyPolicyAddress: Hex; export let royaltyPolicyLAPAddress: Hex; @@ -15,10 +16,13 @@ export let arbitrationPolicyAddress: Hex; export let disputeModuleAddress: Hex; export let ipAssetRegistryAddress: Hex; export let rpcProviderUrl: string; +export let chainId: number; if (String(TEST_ENV) === "sepolia") { + chainId = 11155111; rpcProviderUrl = process.env.SEPOLIA_RPC_PROVIDER_URL as string; licensingModuleAddress = process.env.SEPOLIA_LICENSING_MODULE_ADDRESS as Hex; + licenseTokenAddress = process.env.SEPOLIA_LICENSE_TOKEN_ADDRESS as Hex; nftContractAddress = process.env.SEPOLIA_MOCK_ERC721_ADDRESS as Hex; royaltyPolicyAddress = process.env.SEPOLIA_ROYALTY_POLICY_ADDRESS as Hex; royaltyPolicyLAPAddress = process.env.SEPOLIA_ROYALTY_POLICY_LAP_ADDRESS as Hex; diff --git a/package.json b/package.json index 5fe2cb4..3bc2bd8 100644 --- a/package.json +++ b/package.json @@ -4,20 +4,21 @@ "description": "", "main": "index.js", "scripts": { - "test:sepolia:smoke": "env TEST_ENV='sepolia' mocha -r ts-node/register -r mocha-steps --grep '\\[smoke\\]' './test/**/**/*.test.ts' --timeout 240000 --reporter mochawesome", - "test:story:smoke": "env TEST_ENV='storyTestnet' mocha -r ts-node/register -r mocha-steps --grep '\\[smoke\\]' './test/**/**/*.test.ts' --timeout 240000 --reporter mochawesome", - "test:sepolia:e2e": "env TEST_ENV='sepolia' mocha -r ts-node/register -r mocha-steps './test/**/e2e/*.test.ts' --timeout 240000 --reporter mochawesome", - "test:story:e2e": "env TEST_ENV='storyTestnet' mocha -r ts-node/register -r mocha-steps './test/**/e2e/*.test.ts' --timeout 240000 --reporter mochawesome", - "test:sepolia": "env TEST_ENV='sepolia' mocha -r ts-node/register -r mocha-steps './test/**/**/**.test.ts' --timeout 240000 --reporter mochawesome", - "test:story": "env TEST_ENV='storyTestnet' mocha -r ts-node/register -r mocha-steps './test/**/**/*.test.ts' --timeout 240000 --reporter mochawesome", - "open:report": "open mochawesome-report/mochawesome.html" + "test:sepolia:smoke": "env TEST_ENV='sepolia' mocha -r ts-node/register -r mocha-steps --grep '\\[smoke\\]' './test/**/**/*.test.ts' --timeout 240000 --reporter mochawesome --reporter-options reportDir='test-reports',reportFilename='[status]_[datetime]_sdk-test-report',timestamp='mm-dd-yyyy_HHMMss',reportTitle='SDK Test Report'", + "test:story:smoke": "env TEST_ENV='storyTestnet' mocha -r ts-node/register -r mocha-steps --grep '\\[smoke\\]' './test/**/**/*.test.ts' --timeout 240000 --reporter mochawesome --reporter-options reportDir='test-reports',reportFilename='[status]_[datetime]_sdk-test-report',timestamp='mm-dd-yyyy_HHMMss',reportTitle='SDK Test Report'", + "test:sepolia:e2e": "env TEST_ENV='sepolia' mocha -r ts-node/register -r mocha-steps './test/**/e2e/*.test.ts' --timeout 240000 --reporter mochawesome --reporter-options reportDir='test-reports',reportFilename='[status]_[datetime]_sdk-test-report',timestamp='mm-dd-yyyy_HHMMss',reportTitle='SDK Test Report'", + "test:story:e2e": "env TEST_ENV='storyTestnet' mocha -r ts-node/register -r mocha-steps './test/**/e2e/*.test.ts' --timeout 240000 --reporter mochawesome --reporter-options reportDir='test-reports',reportFilename='[status]_[datetime]_sdk-test-report',timestamp='mm-dd-yyyy_HHMMss',reportTitle='SDK Test Report'", + "test:sepolia": "env TEST_ENV='sepolia' mocha -r ts-node/register -r mocha-steps './test/**/**/**.test.ts' --timeout 240000 --reporter mochawesome --reporter-options reportDir='test-reports',reportFilename='[status]_[datetime]_sdk-test-report',timestamp='mm-dd-yyyy_HHMMss',reportTitle='SDK Test Report'", + "test:story": "env TEST_ENV='storyTestnet' mocha -r ts-node/register -r mocha-steps './test/**/**/*.test.ts' --timeout 240000 --reporter mochawesome --reporter-options reportDir='test-reports',reportFilename='[status]_[datetime]_sdk-test-report',timestamp='mm-dd-yyyy_HHMMss',reportTitle='SDK Test Report'", + "open:report": "open test-reports/*.html", + "test:sepolia:open:report": "rm -rf test-reports && npm run test:sepolia && npm run open:report" }, "repository": { "type": "git", "url": "https://github.com/storyprotocol/sdk-e2e-tests.git" }, "dependencies": { - "@story-protocol/core-sdk": "1.0.0-rc.12", + "@story-protocol/core-sdk": "1.0.0-rc.14", "viem": "^2.8.12" }, "devDependencies": { diff --git a/test/e2e/derivativeIP.comRemixPIL.test.ts b/test/e2e/derivativeIP.comRemixPIL.test.ts index 4f2b825..7675e6c 100644 --- a/test/e2e/derivativeIP.comRemixPIL.test.ts +++ b/test/e2e/derivativeIP.comRemixPIL.test.ts @@ -1,7 +1,7 @@ -import { privateKeyA, privateKeyB, privateKeyC, accountA, accountB, accountC, nftContractAddress } from '../../config/config' -import { checkMintResult, mintNFTWithRetry } from '../../utils/utils' -import { registerIpAsset, attachLicenseTerms, mintLicenseTokens, registerDerivative, registerDerivativeWithLicenseTokens } from '../../utils/sdkUtils' -import { expect } from 'chai' +import { privateKeyA, privateKeyB, privateKeyC, accountA, accountB, accountC, nftContractAddress } from '../../config/config'; +import { checkMintResult, mintNFTWithRetry } from '../../utils/utils'; +import { registerIpAsset, attachLicenseTerms, mintLicenseTokens, registerDerivative, registerDerivativeWithLicenseTokens } from '../../utils/sdkUtils'; +import { expect } from 'chai'; import chai from 'chai'; import chaiAsPromised from 'chai-as-promised'; @@ -21,558 +21,557 @@ let licenseTokenIdB: string; const waitForTransaction: boolean = true; -describe('SDK E2E Test', function () { - describe("Register Derivative IP Asset with Commercial Remix PIL", function () { - describe("[smoke]Register a derivative IP asset with/without license tokens", async function () { - step("Mint a NFT to Wallet A and get a tokenId (tokenIdA)", async function () { - tokenIdA = await mintNFTWithRetry(privateKeyA); - checkMintResult(tokenIdA); +describe("SDK E2E Test - Register Derivative IP Asset with Commercial Remix PIL", function () { + describe("@smoke Register a derivative IP asset with/without license tokens", async function () { + step("Mint a NFT to Wallet A and get a tokenId (tokenIdA)", async function () { + tokenIdA = await mintNFTWithRetry(privateKeyA); + checkMintResult(tokenIdA); - expect(tokenIdA).not.empty; - }); - - step("Wallet A register an IP Asset with tokenIdA and get an ipId (ipIdA)", async function () { - const response = await expect( - registerIpAsset("A", nftContractAddress, tokenIdA, waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.ipId).to.be.a("string").and.not.empty; + expect(tokenIdA).not.empty; + }); - ipIdA = response.ipId; - }); + step("Wallet A register an IP Asset with tokenIdA and get an ipId (ipIdA)", async function () { + const response = await expect( + registerIpAsset("A", nftContractAddress, tokenIdA, waitForTransaction) + ).to.not.be.rejected; - step("Wallet A attach comRemixLicenseTermsId1(commercial remix PIL) to ipIdA", async function () { - const response = await expect( - attachLicenseTerms("A", ipIdA, comRemixLicenseTermsId1, waitForTransaction) - ).to.not.be.rejected; + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; - expect(response.txHash).to.be.a("string").and.not.empty; - }); + ipIdA = response.ipId; + }); - step("Wallet A mint a license token with the receiverAddress set as Wallet B, get a licenseTokenId (licenseTokenIdA)", async function () { - const response = await expect( - mintLicenseTokens("A", ipIdA, comRemixLicenseTermsId1, 2, accountB.address, waitForTransaction) - ).to.not.be.rejected; + step("Wallet A attach comRemixLicenseTermsId1(commercial remix PIL) to ipIdA", async function () { + const response = await expect( + attachLicenseTerms("A", ipIdA, comRemixLicenseTermsId1, waitForTransaction) + ).to.not.be.rejected; - expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.licenseTokenId).to.be.a("bigint").and.to.be.ok; + expect(response.txHash).to.be.a("string").and.not.empty; + }); - licenseTokenIdA = response.licenseTokenId; - }); + step("Wallet A mint a license token with the receiverAddress set as Wallet B, get a licenseTokenId (licenseTokenIdA)", async function () { + const response = await expect( + mintLicenseTokens("A", ipIdA, comRemixLicenseTermsId1, 2, accountB.address, waitForTransaction) + ).to.not.be.rejected; - step("Mint a NFT to Wallet B and get a tokenId (tokenIdB)", async function () { - tokenIdB = await mintNFTWithRetry(privateKeyB); - checkMintResult(tokenIdB); + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.licenseTokenIds).to.be.a("array").and.to.have.lengthOf(2); - expect(tokenIdB).not.empty; - }); + licenseTokenIdA= response.licenseTokenIds[0]; + }); - step("Wallet B register an IP Asset with tokenIdB and get an ipId (ipIdB)", async function () { - const response = await expect( - registerIpAsset("B", nftContractAddress, tokenIdB, waitForTransaction) - ).to.not.be.rejected; + step("Mint a NFT to Wallet B and get a tokenId (tokenIdB)", async function () { + tokenIdB = await mintNFTWithRetry(privateKeyB); + checkMintResult(tokenIdB); - expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.ipId).to.be.a("string").and.not.empty; + expect(tokenIdB).not.empty; + }); - ipIdB = response.ipId; - }); + step("Wallet B register an IP Asset with tokenIdB and get an ipId (ipIdB)", async function () { + const response = await expect( + registerIpAsset("B", nftContractAddress, tokenIdB, waitForTransaction) + ).to.not.be.rejected; - step("Wallet B can register a derivative IP asset with licenseTokenIdA", async function () { - const response = await expect( - registerDerivativeWithLicenseTokens("B", ipIdB, [licenseTokenIdA], waitForTransaction) - ).to.not.be.rejected; + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; - expect(response.txHash).to.be.a("string").and.not.empty; - }); + ipIdB = response.ipId; + }); - step("Mint a NFT to WalletC and get a tokenId(tokenIdC)", async function () { - tokenIdC = await mintNFTWithRetry(privateKeyC); - checkMintResult(tokenIdC); + step("Wallet B can register a derivative IP asset with licenseTokenIdA", async function () { + const response = await expect( + registerDerivativeWithLicenseTokens("B", ipIdB, [licenseTokenIdA], waitForTransaction) + ).to.not.be.rejected; - expect(tokenIdC).not.empty; - }); + expect(response.txHash).to.be.a("string").and.not.empty; + }); - step("Wallet C register an IP Asset with tokenIdC and get an ipId (ipIdC)", async function () { - const response = await expect( - registerIpAsset("C", nftContractAddress, tokenIdC, waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.ipId).to.be.a("string").and.not.empty; + step("Mint a NFT to WalletC and get a tokenId(tokenIdC)", async function () { + tokenIdC = await mintNFTWithRetry(privateKeyC); + checkMintResult(tokenIdC); - ipIdC = response.ipId; - }) + expect(tokenIdC).not.empty; + }); - // licenseTokenIdA set the Wallet B's address as receiverAddress, Wallet C can NOT register a derivative IP asset with licenseTokenIdA - step("Wallet C can NOT register a derivative IP asset with licenseTokenIdA", async function () { - const response = await expect( - registerDerivativeWithLicenseTokens("C", ipIdC, [licenseTokenIdA], waitForTransaction) - ).to.be.rejectedWith("Failed to register derivative with license tokens: The contract function \"ownerOf\" reverted."); - }); + step("Wallet C register an IP Asset with tokenIdC and get an ipId (ipIdC)", async function () { + const response = await expect( + registerIpAsset("C", nftContractAddress, tokenIdC, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdC = response.ipId; + }) + + // licenseTokenIdA set the Wallet B's address as receiverAddress, Wallet C can NOT register a derivative IP asset with licenseTokenIdA + step("Wallet C can NOT register a derivative IP asset with licenseTokenIdA", async function () { + const response = await expect( + registerDerivativeWithLicenseTokens("C", ipIdC, [licenseTokenIdA], waitForTransaction) + ).to.be.rejectedWith("Failed to register derivative with license tokens: The contract function \"ownerOf\" reverted."); + }); - step("Wallet C can register a derivative IP asset without licenseTokenId", async function () { - const response = await expect( - registerDerivative("C", ipIdC, [ipIdA], [comRemixLicenseTermsId1], waitForTransaction) - ).to.not.be.rejected; + step("Wallet C can register a derivative IP asset without licenseTokenId", async function () { + const response = await expect( + registerDerivative("C", ipIdC, [ipIdA], [comRemixLicenseTermsId1], waitForTransaction) + ).to.not.be.rejected; - expect(response.txHash).to.be.a("string").and.not.empty; - }); + expect(response.txHash).to.be.a("string").and.not.empty; }); + }); - describe('Register a derivative IP asset with multiple parent IP assets', async function () { - step("Mint a NFT to Wallet A and get a tokenId (tokenIdA)", async function () { - tokenIdA = await mintNFTWithRetry(privateKeyA); - checkMintResult(tokenIdA); + describe('Register a derivative IP asset with multiple parent IP assets', async function () { + step("Mint a NFT to Wallet A and get a tokenId (tokenIdA)", async function () { + tokenIdA = await mintNFTWithRetry(privateKeyA); + checkMintResult(tokenIdA); - expect(tokenIdA).not.empty; - }); + expect(tokenIdA).not.empty; + }); - step("Wallet A register an IP Asset with tokenIdA and get an ipId (ipIdA)", async function () { - const response = await expect( - registerIpAsset("A", nftContractAddress, tokenIdA, waitForTransaction) - ).to.not.be.rejected; + step("Wallet A register an IP Asset with tokenIdA and get an ipId (ipIdA)", async function () { + const response = await expect( + registerIpAsset("A", nftContractAddress, tokenIdA, waitForTransaction) + ).to.not.be.rejected; - expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.ipId).to.be.a("string").and.not.empty; + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; - ipIdA = response.ipId; - }); + ipIdA = response.ipId; + }); - step("Wallet A attach comRemixLicenseTermsId1(commercial remix PIL) to ipIdA", async function () { - const response = await expect( - attachLicenseTerms("A", ipIdA, comRemixLicenseTermsId1, waitForTransaction) - ).to.not.be.rejected; + step("Wallet A attach comRemixLicenseTermsId1(commercial remix PIL) to ipIdA", async function () { + const response = await expect( + attachLicenseTerms("A", ipIdA, comRemixLicenseTermsId1, waitForTransaction) + ).to.not.be.rejected; - expect(response.txHash).to.be.a("string").and.not.empty; - }); + expect(response.txHash).to.be.a("string").and.not.empty; + }); - step("Mint a NFT to WalletB, get a tokenId (tokenidB)", async function () { - tokenIdB = await mintNFTWithRetry(privateKeyB); - checkMintResult(tokenIdB); + step("Mint a NFT to WalletB, get a tokenId (tokenidB)", async function () { + tokenIdB = await mintNFTWithRetry(privateKeyB); + checkMintResult(tokenIdB); - expect(tokenIdB).not.empty; - }); + expect(tokenIdB).not.empty; + }); - step("Wallet B register an IP Asset with tokenIdB and get an ipId (ipIdB)", async function () { - const response = await expect( - registerIpAsset("B", nftContractAddress, tokenIdB, waitForTransaction) - ).to.not.be.rejected; + step("Wallet B register an IP Asset with tokenIdB and get an ipId (ipIdB)", async function () { + const response = await expect( + registerIpAsset("B", nftContractAddress, tokenIdB, waitForTransaction) + ).to.not.be.rejected; - expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.ipId).to.be.a("string").and.not.empty; + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; - ipIdB = response.ipId; - }); + ipIdB = response.ipId; + }); - step("Wallet B attach comRemixLicenseTermsId1(commercial remix PIL) to ipIdA", async function () { - const response = await expect( - attachLicenseTerms("B", ipIdB, comRemixLicenseTermsId1, waitForTransaction) - ).to.not.be.rejected; + step("Wallet B attach comRemixLicenseTermsId1(commercial remix PIL) to ipIdA", async function () { + const response = await expect( + attachLicenseTerms("B", ipIdB, comRemixLicenseTermsId1, waitForTransaction) + ).to.not.be.rejected; - expect(response.txHash).to.be.a("string").and.not.empty; - }); + expect(response.txHash).to.be.a("string").and.not.empty; + }); - step("Mint a NFT to WalletC, get a tokenId (tokenidC)", async function () { - tokenIdC = await mintNFTWithRetry(privateKeyC); - checkMintResult(tokenIdC); + step("Mint a NFT to WalletC, get a tokenId (tokenidC)", async function () { + tokenIdC = await mintNFTWithRetry(privateKeyC); + checkMintResult(tokenIdC); - expect(tokenIdC).not.empty; - }); + expect(tokenIdC).not.empty; + }); - step("Wallet C register an IP Asset with tokenIdC and get an ipId (ipIdC)", async function () { - const response = await expect( - registerIpAsset("C", nftContractAddress, tokenIdC, waitForTransaction) - ).to.not.be.rejected; + step("Wallet C register an IP Asset with tokenIdC and get an ipId (ipIdC)", async function () { + const response = await expect( + registerIpAsset("C", nftContractAddress, tokenIdC, waitForTransaction) + ).to.not.be.rejected; - expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.ipId).to.be.a("string").and.not.empty; + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; - ipIdC = response.ipId; - }); + ipIdC = response.ipId; + }); - step("Wallet C can register a derivative IP asset with multiple parent IP assets", async function () { - const response = await expect( - registerDerivative("C", ipIdC, [ipIdA, ipIdB], [comRemixLicenseTermsId1, comRemixLicenseTermsId1], waitForTransaction) - ).to.not.be.rejected; + step("Wallet C can register a derivative IP asset with multiple parent IP assets", async function () { + const response = await expect( + registerDerivative("C", ipIdC, [ipIdA, ipIdB], [comRemixLicenseTermsId1, comRemixLicenseTermsId1], waitForTransaction) + ).to.not.be.rejected; - expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.txHash).to.be.a("string").and.not.empty;             }); - }); + }); - describe("Register a derivative IP assets with multiple license tokens", async function () { - step("Mint a NFT to Wallet A and get a tokenId (tokenIdA)", async function () { - tokenIdA = await mintNFTWithRetry(privateKeyA); - checkMintResult(tokenIdA); + describe("Register a derivative IP assets with multiple license tokens", async function () { + step("Mint a NFT to Wallet A and get a tokenId (tokenIdA)", async function () { + tokenIdA = await mintNFTWithRetry(privateKeyA); + checkMintResult(tokenIdA); - expect(tokenIdA).not.empty; - }); + expect(tokenIdA).not.empty; + }); - step("Wallet A register an IP Asset with tokenIdA, get an ipId (ipIdA)", async function () { - const response = await expect( - registerIpAsset("A", nftContractAddress, tokenIdA, waitForTransaction) - ).to.not.be.rejected; + step("Wallet A register an IP Asset with tokenIdA, get an ipId (ipIdA)", async function () { + const response = await expect( + registerIpAsset("A", nftContractAddress, tokenIdA, waitForTransaction) + ).to.not.be.rejected; - expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.ipId).to.be.a("string").and.not.empty; + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; - ipIdA = response.ipId; - }); + ipIdA = response.ipId; + }); - step("Wallet A attach comRemixLicenseTermsId1(commercial remix PIL) to ipIdA", async function () { - const response = await expect( - attachLicenseTerms("A", ipIdA, comRemixLicenseTermsId1, waitForTransaction) - ).to.not.be.rejected; + step("Wallet A attach comRemixLicenseTermsId1(commercial remix PIL) to ipIdA", async function () { + const response = await expect( + attachLicenseTerms("A", ipIdA, comRemixLicenseTermsId1, waitForTransaction) + ).to.not.be.rejected; - expect(response.txHash).to.be.a("string").and.not.empty; - }); + expect(response.txHash).to.be.a("string").and.not.empty; + }); - step("Wallet A mint a license token with the receiverAddress set as Wallet B, get a licenseId (licenseTokenIdA)", async function () { - const response = await expect( - mintLicenseTokens("A", ipIdA, comRemixLicenseTermsId1, 2, accountC.address, waitForTransaction) - ).to.not.be.rejected; + step("Wallet A mint a license token with the receiverAddress set as Wallet B, get a licenseId (licenseTokenIdA)", async function () { + const response = await expect( + mintLicenseTokens("A", ipIdA, comRemixLicenseTermsId1, 2, accountC.address, waitForTransaction) + ).to.not.be.rejected; - expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.licenseTokenId).to.be.a("bigint").and.to.be.ok; + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.licenseTokenIds).to.be.a("array").and.to.have.lengthOf(2); - licenseTokenIdA = response.licenseTokenId; - }); + licenseTokenIdA = response.licenseTokenIds[0]; + }); - step("Mint a NFT to WalletB, get a tokenId (tokenIdB)", async function () { - tokenIdB = await mintNFTWithRetry(privateKeyB); - checkMintResult(tokenIdB); + step("Mint a NFT to WalletB, get a tokenId (tokenIdB)", async function () { + tokenIdB = await mintNFTWithRetry(privateKeyB); + checkMintResult(tokenIdB); - expect(tokenIdB).not.empty; - }); + expect(tokenIdB).not.empty; + }); - step("Wallet B register an IP Asset with tokenIdB, get an ipId (ipIdB)", async function () { - const response = await expect( - registerIpAsset("B", nftContractAddress, tokenIdB, waitForTransaction) - ).to.not.be.rejected; + step("Wallet B register an IP Asset with tokenIdB, get an ipId (ipIdB)", async function () { + const response = await expect( + registerIpAsset("B", nftContractAddress, tokenIdB, waitForTransaction) + ).to.not.be.rejected; - expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.ipId).to.be.a("string").and.not.empty; + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; - ipIdB = response.ipId; - }); + ipIdB = response.ipId; + }); - step("Wallet B attach comRemixLicenseTermsId1(commercial remix PIL) to ipIdB", async function () { - const response = await expect( - attachLicenseTerms("B", ipIdB, comRemixLicenseTermsId1, waitForTransaction) - ).to.not.be.rejected; + step("Wallet B attach comRemixLicenseTermsId1(commercial remix PIL) to ipIdB", async function () { + const response = await expect( + attachLicenseTerms("B", ipIdB, comRemixLicenseTermsId1, waitForTransaction) + ).to.not.be.rejected; - expect(response.txHash).to.be.a("string").and.not.empty; - }); + expect(response.txHash).to.be.a("string").and.not.empty; + }); - step("Wallet B mint a license token with the receiverAddress set as Wallet C, get a licenseTokenId (licenseTokenIdB)", async function () { - const response = await expect( - mintLicenseTokens("B", ipIdB, comRemixLicenseTermsId1, 2, accountC.address, waitForTransaction) - ).to.not.be.rejected; + step("Wallet B mint a license token with the receiverAddress set as Wallet C, get a licenseTokenId (licenseTokenIdB)", async function () { + const response = await expect( + mintLicenseTokens("B", ipIdB, comRemixLicenseTermsId1, 2, accountC.address, waitForTransaction) + ).to.not.be.rejected; - expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.licenseTokenId).to.be.a("bigint").and.to.be.ok; + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.licenseTokenIds).to.be.a("array").and.to.have.lengthOf(2); - licenseTokenIdB = response.licenseTokenId; - }); + licenseTokenIdB = response.licenseTokenIds[0]; + }); - step("Mint a NFT to WalletC, get a tokenId (tokenIdC)", async function () { - tokenIdC = await mintNFTWithRetry(privateKeyC); - checkMintResult(tokenIdC); + step("Mint a NFT to WalletC, get a tokenId (tokenIdC)", async function () { + tokenIdC = await mintNFTWithRetry(privateKeyC); + checkMintResult(tokenIdC); - expect(tokenIdC).not.empty; - }); + expect(tokenIdC).not.empty; + }); - step("Wallet C register an IP Asset with tokenIdC, get an ipId (ipIdC)", async function () { - const response = await expect( - registerIpAsset("C", nftContractAddress, tokenIdC, waitForTransaction) - ).to.not.be.rejected; + step("Wallet C register an IP Asset with tokenIdC, get an ipId (ipIdC)", async function () { + const response = await expect( + registerIpAsset("C", nftContractAddress, tokenIdC, waitForTransaction) + ).to.not.be.rejected; - expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.ipId).to.be.a("string").and.not.empty; + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; - ipIdC = response.ipId; - }); + ipIdC = response.ipId; + }); - step("ipIdC can link to ipIdA and ipIdB as their derivative IP Asset", async function () { - const response = await expect( - registerDerivativeWithLicenseTokens("C", ipIdC, [licenseTokenIdA, licenseTokenIdB], waitForTransaction) - ).to.not.be.rejected; + step("ipIdC can link to ipIdA and ipIdB as their derivative IP Asset", async function () { + const response = await expect( + registerDerivativeWithLicenseTokens("C", ipIdC, [licenseTokenIdA, licenseTokenIdB], waitForTransaction) + ).to.not.be.rejected; - expect(response.txHash).to.be.a("string").and.not.empty; - }); + expect(response.txHash).to.be.a("string").and.not.empty; }); + }); - describe("Register a derivative IP assets with multiple license tokens, the sender is not licensee", async function () { - step("Mint a NFT to Wallet A and get a tokenId (tokenIdA)", async function () { - tokenIdA = await mintNFTWithRetry(privateKeyA); - checkMintResult(tokenIdA); + describe("Register a derivative IP assets with multiple license tokens, the sender is not licensee", async function () { + step("Mint a NFT to Wallet A and get a tokenId (tokenIdA)", async function () { + tokenIdA = await mintNFTWithRetry(privateKeyA); + checkMintResult(tokenIdA); - expect(tokenIdA).not.empty; - }); + expect(tokenIdA).not.empty; + }); - step("Wallet A register an IP Asset with tokenIdA, get an ipId (ipIdA)", async function () { - const response = await expect( - registerIpAsset("A", nftContractAddress, tokenIdA, waitForTransaction) - ).to.not.be.rejected; + step("Wallet A register an IP Asset with tokenIdA, get an ipId (ipIdA)", async function () { + const response = await expect( + registerIpAsset("A", nftContractAddress, tokenIdA, waitForTransaction) + ).to.not.be.rejected; - expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.ipId).to.be.a("string").and.not.empty; + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; - ipIdA = response.ipId; - }); + ipIdA = response.ipId; + }); - step("Wallet A attach comRemixLicenseTermsId1(commercial remix PIL) to ipIdA", async function () { - const response = await expect( - attachLicenseTerms("A", ipIdA, comRemixLicenseTermsId1, waitForTransaction) - ).to.not.be.rejected; + step("Wallet A attach comRemixLicenseTermsId1(commercial remix PIL) to ipIdA", async function () { + const response = await expect( + attachLicenseTerms("A", ipIdA, comRemixLicenseTermsId1, waitForTransaction) + ).to.not.be.rejected; - expect(response.txHash).to.be.a("string").and.not.empty; - }); + expect(response.txHash).to.be.a("string").and.not.empty; + }); - step("Wallet A mint a license token with the receiverAddress set as Wallet B, get a licenseId (licenseTokenIdA)", async function () { - const response = await expect( - mintLicenseTokens("A", ipIdA, comRemixLicenseTermsId1, 2, accountB.address, waitForTransaction) - ).to.not.be.rejected; + step("Wallet A mint a license token with the receiverAddress set as Wallet B, get a licenseId (licenseTokenIdA)", async function () { + const response = await expect( + mintLicenseTokens("A", ipIdA, comRemixLicenseTermsId1, 2, accountB.address, waitForTransaction) + ).to.not.be.rejected; - expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.licenseTokenId).to.be.a("bigint").and.to.be.ok; + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.licenseTokenIds).to.be.a("array").and.to.have.lengthOf(2); - licenseTokenIdA = response.licenseTokenId; - }); + licenseTokenIdA = response.licenseTokenIds[0]; + }); - step("Mint a NFT to WalletB, get a tokenId (tokenIdB)", async function () { - tokenIdB = await mintNFTWithRetry(privateKeyB); - checkMintResult(tokenIdB); + step("Mint a NFT to WalletB, get a tokenId (tokenIdB)", async function () { + tokenIdB = await mintNFTWithRetry(privateKeyB); + checkMintResult(tokenIdB); - expect(tokenIdB).not.empty; - }); + expect(tokenIdB).not.empty; + }); - step("Wallet B register an IP Asset with tokenIdB, get an ipId (ipIdB)", async function () { - const response = await expect( - registerIpAsset("B", nftContractAddress, tokenIdB, waitForTransaction) - ).to.not.be.rejected; + step("Wallet B register an IP Asset with tokenIdB, get an ipId (ipIdB)", async function () { + const response = await expect( + registerIpAsset("B", nftContractAddress, tokenIdB, waitForTransaction) + ).to.not.be.rejected; - expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.ipId).to.be.a("string").and.not.empty; + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; - ipIdB = response.ipId; - }); + ipIdB = response.ipId; + }); - step("Wallet B attach comRemixLicenseTermsId1(commercial remix PIL) to ipIdB", async function () { - const response = await expect( - attachLicenseTerms("B", ipIdB, comRemixLicenseTermsId1, waitForTransaction) - ).to.not.be.rejected; + step("Wallet B attach comRemixLicenseTermsId1(commercial remix PIL) to ipIdB", async function () { + const response = await expect( + attachLicenseTerms("B", ipIdB, comRemixLicenseTermsId1, waitForTransaction) + ).to.not.be.rejected; - expect(response.txHash).to.be.a("string").and.not.empty; - }); + expect(response.txHash).to.be.a("string").and.not.empty; + }); - step("Wallet B mint a license token with the receiverAddress set as Wallet C, get a licenseTokenId (licenseTokenIdB)", async function () { - const response = await expect( - mintLicenseTokens("B", ipIdB, comRemixLicenseTermsId1, 2, accountC.address, waitForTransaction) - ).to.not.be.rejected; + step("Wallet B mint a license token with the receiverAddress set as Wallet C, get a licenseTokenId (licenseTokenIdB)", async function () { + const response = await expect( + mintLicenseTokens("B", ipIdB, comRemixLicenseTermsId1, 2, accountC.address, waitForTransaction) + ).to.not.be.rejected; - expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.licenseTokenId).to.be.a("bigint").and.to.be.ok; + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.licenseTokenIds).to.be.a("array").and.to.have.lengthOf(2); - licenseTokenIdB = response.licenseTokenId; - }); + licenseTokenIdB = response.licenseTokenIds[0]; + }); - step("Mint a NFT to WalletC, get a tokenId (tokenIdC)", async function () { - tokenIdC = await mintNFTWithRetry(privateKeyC); - checkMintResult(tokenIdC); + step("Mint a NFT to WalletC, get a tokenId (tokenIdC)", async function () { + tokenIdC = await mintNFTWithRetry(privateKeyC); + checkMintResult(tokenIdC); - expect(tokenIdC).not.empty; - }); + expect(tokenIdC).not.empty; + }); - step("Wallet C register an IP Asset with tokenIdC, get an ipId (ipIdC)", async function () { - const response = await expect( - registerIpAsset("C", nftContractAddress, tokenIdC, waitForTransaction) - ).to.not.be.rejected; + step("Wallet C register an IP Asset with tokenIdC, get an ipId (ipIdC)", async function () { + const response = await expect( + registerIpAsset("C", nftContractAddress, tokenIdC, waitForTransaction) + ).to.not.be.rejected; - expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.ipId).to.be.a("string").and.not.empty; + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; - ipIdC = response.ipId; - }); + ipIdC = response.ipId; + }); - // Wallet C is not the licensee of licenseTokenIdA - step("Wallet C can NOT register derivative IP asset with licenseTokenIdA", async function () { - const response = await expect( - registerDerivativeWithLicenseTokens("C", ipIdC, [licenseTokenIdA, licenseTokenIdB], waitForTransaction) - ).to.be.rejectedWith("Failed to register derivative with license tokens: The contract function \"registerDerivativeWithLicenseTokens\" reverted with the following signature:"); - }); + // Wallet C is not the licensee of licenseTokenIdA + step("Wallet C can NOT register derivative IP asset with licenseTokenIdA", async function () { + const response = await expect( + registerDerivativeWithLicenseTokens("C", ipIdC, [licenseTokenIdA, licenseTokenIdB], waitForTransaction) + ).to.be.rejectedWith("Failed to register derivative with license tokens: The contract function \"registerDerivativeWithLicenseTokens\" reverted with the following signature:"); }); + }); - describe("Register multiple derivative IP assets with license token, registered amount larger than mint amount of license token", async function () { - step("Mint a NFT to Wallet A and get a tokenId (tokenIdA)", async function () { - tokenIdA = await mintNFTWithRetry(privateKeyA); - checkMintResult(tokenIdA); + describe("Register multiple derivative IP assets with license token, registered amount larger than mint amount of license token", async function () { + step("Mint a NFT to Wallet A and get a tokenId (tokenIdA)", async function () { + tokenIdA = await mintNFTWithRetry(privateKeyA); + checkMintResult(tokenIdA); - expect(tokenIdA).not.empty; - }); + expect(tokenIdA).not.empty; + }); - step("Wallet A register an IP Asset with tokenIdA and get an ipId (ipIdA)", async function () { - const response = await expect( - registerIpAsset("A", nftContractAddress, tokenIdA, waitForTransaction) - ).to.not.be.rejected; + step("Wallet A register an IP Asset with tokenIdA and get an ipId (ipIdA)", async function () { + const response = await expect( + registerIpAsset("A", nftContractAddress, tokenIdA, waitForTransaction) + ).to.not.be.rejected; - expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.ipId).to.be.a("string").and.not.empty; + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; - ipIdA = response.ipId; - }); + ipIdA = response.ipId; + }); - step("Wallet A attach comRemixLicenseTermsId1(commercial remix PIL) to ipIdA", async function () { - const response = await expect( - attachLicenseTerms("A", ipIdA, comRemixLicenseTermsId1, waitForTransaction) - ).to.not.be.rejected; + step("Wallet A attach comRemixLicenseTermsId1(commercial remix PIL) to ipIdA", async function () { + const response = await expect( + attachLicenseTerms("A", ipIdA, comRemixLicenseTermsId1, waitForTransaction) + ).to.not.be.rejected; - expect(response.txHash).to.be.a("string").and.not.empty; - }); + expect(response.txHash).to.be.a("string").and.not.empty; + }); - step("Wallet A mint a license token with ipIdA and get a licenseTokenId (licenseTokenIdA)", async function () { - const response = await expect( - mintLicenseTokens("A", ipIdA, comRemixLicenseTermsId1, 1, accountB.address, waitForTransaction) - ).to.not.be.rejected; + step("Wallet A mint a license token with ipIdA and get a licenseTokenId (licenseTokenIdA)", async function () { + const response = await expect( + mintLicenseTokens("A", ipIdA, comRemixLicenseTermsId1, 1, accountB.address, waitForTransaction) + ).to.not.be.rejected; - expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.licenseTokenId).to.be.a("bigint").and.to.be.ok; + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.licenseTokenIds).to.be.a("array").and.to.have.lengthOf(1); - licenseTokenIdA = response.licenseTokenId; - }); + licenseTokenIdA = response.licenseTokenIds[0]; + }); - step("Mint a NFT to WalletB and get a tokenId (tokenIdB)", async function () { - tokenIdB = await mintNFTWithRetry(privateKeyB); - checkMintResult(tokenIdB); + step("Mint a NFT to WalletB and get a tokenId (tokenIdB)", async function () { + tokenIdB = await mintNFTWithRetry(privateKeyB); + checkMintResult(tokenIdB); - expect(tokenIdB).not.empty; - }); + expect(tokenIdB).not.empty; + }); - step("Wallet B register an IP Asset with tokenIdB and get an ipId (ipIdB)", async function () { - const response = await expect( - registerIpAsset("B", nftContractAddress, tokenIdB, waitForTransaction) - ).to.not.be.rejected; + step("Wallet B register an IP Asset with tokenIdB and get an ipId (ipIdB)", async function () { + const response = await expect( + registerIpAsset("B", nftContractAddress, tokenIdB, waitForTransaction) + ).to.not.be.rejected; - expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.ipId).to.be.a("string").and.not.empty; + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; - ipIdB = response.ipId; - }); + ipIdB = response.ipId; + }); - step("Wallet B can register a derivative IP asset with licenseTokenIdA", async function () { - const response = await expect( - registerDerivativeWithLicenseTokens("B", ipIdB, [licenseTokenIdA], waitForTransaction) - ).to.not.be.rejected; + step("Wallet B can register a derivative IP asset with licenseTokenIdA", async function () { + const response = await expect( + registerDerivativeWithLicenseTokens("B", ipIdB, [licenseTokenIdA], waitForTransaction) + ).to.not.be.rejected; - expect(response.txHash).to.be.a("string").and.not.empty; - }); + expect(response.txHash).to.be.a("string").and.not.empty; + }); - step("Mint a NFT to WalletB and get a tokenId (tokenIdB)", async function () { - tokenIdC = await mintNFTWithRetry(privateKeyB); - checkMintResult(tokenIdC); + step("Mint a NFT to WalletB and get a tokenId (tokenIdB)", async function () { + tokenIdC = await mintNFTWithRetry(privateKeyB); + checkMintResult(tokenIdC); - expect(tokenIdC).not.empty; - }); + expect(tokenIdC).not.empty; + }); - step("Wallet B register a root IP Asset with tokenIdC, get an ipId (ipIdC)", async function () { - const response = await expect( - registerIpAsset("B", nftContractAddress, tokenIdC, waitForTransaction) - ).to.not.be.rejected; + step("Wallet B register a root IP Asset with tokenIdC, get an ipId (ipIdC)", async function () { + const response = await expect( + registerIpAsset("B", nftContractAddress, tokenIdC, waitForTransaction) + ).to.not.be.rejected; - expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.ipId).to.be.a("string").and.not.empty; + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; - ipIdC = response.ipId; - }); + ipIdC = response.ipId; + }); - step("Wallet B can NOT register a derivative IP asset with licenseTokenIdA, no more license token", async function () { - const response = await expect( - registerDerivativeWithLicenseTokens("B", ipIdC, [licenseTokenIdA], waitForTransaction) - ).to.be.rejectedWith("Failed to register derivative with license tokens: The contract function \"ownerOf\" reverted."); - }); + step("Wallet B can NOT register a derivative IP asset with licenseTokenIdA, no more license token", async function () { + const response = await expect( + registerDerivativeWithLicenseTokens("B", ipIdC, [licenseTokenIdA], waitForTransaction) + ).to.be.rejectedWith("Failed to register derivative with license tokens: The contract function \"ownerOf\" reverted."); }); + }); - describe("Register derivative IP asset with an IP that already has license", async function () { - step("Mint a NFT to Wallet A and get a tokenId (tokenIdA)", async function () { - tokenIdA = await mintNFTWithRetry(privateKeyA); - checkMintResult(tokenIdA); + describe("Register derivative IP asset with an IP that already has license", async function () { + step("Mint a NFT to Wallet A and get a tokenId (tokenIdA)", async function () { + tokenIdA = await mintNFTWithRetry(privateKeyA); + checkMintResult(tokenIdA); - expect(tokenIdA).not.empty; - }); + expect(tokenIdA).not.empty; + }); - step("Wallet A register an IP Asset with tokenIdA and get an ipId (ipIdA)", async function () { - const response = await expect( - registerIpAsset("A", nftContractAddress, tokenIdA, waitForTransaction) - ).to.not.be.rejected; + step("Wallet A register an IP Asset with tokenIdA and get an ipId (ipIdA)", async function () { + const response = await expect( + registerIpAsset("A", nftContractAddress, tokenIdA, waitForTransaction) + ).to.not.be.rejected; - expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.ipId).to.be.a("string").and.not.empty; + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; - ipIdA = response.ipId; - }); + ipIdA = response.ipId; + }); - step("Wallet A attach comRemixLicenseTermsId1(commercial remix PIL) to ipIdA", async function () { - const response = await expect( - attachLicenseTerms("A", ipIdA, comRemixLicenseTermsId1, waitForTransaction) - ).to.not.be.rejected; + step("Wallet A attach comRemixLicenseTermsId1(commercial remix PIL) to ipIdA", async function () { + const response = await expect( + attachLicenseTerms("A", ipIdA, comRemixLicenseTermsId1, waitForTransaction) + ).to.not.be.rejected; - expect(response.txHash).to.be.a("string").and.not.empty; - }); + expect(response.txHash).to.be.a("string").and.not.empty; + }); - step("Wallet A mint a license token with ipIdA and get a licenseTokenId (licenseTokenIdA)", async function () { - const response = await expect( - mintLicenseTokens("A", ipIdA, comRemixLicenseTermsId1, 1, accountB.address, waitForTransaction) - ).to.not.be.rejected; + step("Wallet A mint a license token with ipIdA and get a licenseTokenId (licenseTokenIdA)", async function () { + const response = await expect( + mintLicenseTokens("A", ipIdA, comRemixLicenseTermsId1, 1, accountB.address, waitForTransaction) + ).to.not.be.rejected; - expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.licenseTokenId).to.be.a("bigint").and.to.be.ok; + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.licenseTokenIds).to.be.a("array").and.to.have.lengthOf(1); - licenseTokenIdA = response.licenseTokenId; - }); + licenseTokenIdA= response.licenseTokenIds[0]; + }); - step("Mint a NFT to WalletB and get a tokenId (tokenIdB)", async function () { - tokenIdB = await mintNFTWithRetry(privateKeyB); - checkMintResult(tokenIdB); - - expect(tokenIdB).not.empty; - }); + step("Mint a NFT to WalletB and get a tokenId (tokenIdB)", async function () { + tokenIdB = await mintNFTWithRetry(privateKeyB); + checkMintResult(tokenIdB); + + expect(tokenIdB).not.empty; + }); - step("Wallet B register an IP Asset with tokenIdB and get an ipId (ipIdB)", async function () { - const response = await expect( - registerIpAsset("B", nftContractAddress, tokenIdB, waitForTransaction) - ).to.not.be.rejected; + step("Wallet B register an IP Asset with tokenIdB and get an ipId (ipIdB)", async function () { + const response = await expect( + registerIpAsset("B", nftContractAddress, tokenIdB, waitForTransaction) + ).to.not.be.rejected; - expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.ipId).to.be.a("string").and.not.empty; + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; - ipIdB = response.ipId; - }); + ipIdB = response.ipId; + }); - step("Wallet B attach comRemixLicenseTermsId1(commercial remix PIL) to ipIdA", async function () { - const response = await expect( - attachLicenseTerms("B", ipIdB, comRemixLicenseTermsId1, waitForTransaction) - ).to.not.be.rejected; + step("Wallet B attach comRemixLicenseTermsId1(commercial remix PIL) to ipIdA", async function () { + const response = await expect( + attachLicenseTerms("B", ipIdB, comRemixLicenseTermsId1, waitForTransaction) + ).to.not.be.rejected; - expect(response.txHash).to.be.a("string").and.not.empty; - }); + expect(response.txHash).to.be.a("string").and.not.empty; + }); - step("Wallet B mint a license token with ipIdB and get a licenseTokenId (licenseTokenIdB)", async function () { - const response = await expect( - mintLicenseTokens("B", ipIdB, comRemixLicenseTermsId1, 1, accountA.address, waitForTransaction) - ).to.not.be.rejected; + step("Wallet B mint a license token with ipIdB and get a licenseTokenId (licenseTokenIdB)", async function () { + const response = await expect( + mintLicenseTokens("B", ipIdB, comRemixLicenseTermsId1, 1, accountA.address, waitForTransaction) + ).to.not.be.rejected; - expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.licenseTokenId).to.be.a("bigint").and.to.be.ok; + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.licenseTokenIds).to.be.a("array").and.to.have.lengthOf(1); - licenseTokenIdB = response.licenseTokenId; - }); + licenseTokenIdB = response.licenseTokenIds[0]; + }); - step("Wallet B can NOT register a derivative IP asset with ipIdB, LicenseRegistry__DerivativeIpAlreadyHasLicense(address)", async function () { - const response = await expect( - registerDerivativeWithLicenseTokens("B", ipIdB, [licenseTokenIdA], waitForTransaction) - ).to.be.rejectedWith("Failed to register derivative with license tokens: The contract function \"registerDerivativeWithLicenseTokens\" reverted with the following signature:", "0x650aa4f5"); - }); + step("Wallet B can NOT register a derivative IP asset with ipIdB, LicenseRegistry__DerivativeIpAlreadyHasLicense(address)", async function () { + const response = await expect( + registerDerivativeWithLicenseTokens("B", ipIdB, [licenseTokenIdA], waitForTransaction) + ).to.be.rejectedWith("Failed to register derivative with license tokens: The contract function \"registerDerivativeWithLicenseTokens\" reverted with the following signature:", "0x650aa4f5"); }); }); }); + diff --git a/test/e2e/derivativeIP.comUsePIL.test.ts b/test/e2e/derivativeIP.comUsePIL.test.ts index 7acaace..5a73590 100644 --- a/test/e2e/derivativeIP.comUsePIL.test.ts +++ b/test/e2e/derivativeIP.comUsePIL.test.ts @@ -21,575 +21,573 @@ let licenseTokenIdB: string; const waitForTransaction: boolean = true; -describe('SDK E2E Test', function () { - describe("Register Derivative IP Asset with Commercial Use PIL", function () { - describe("[smoke]Register a derivative IP asset with/without license tokens", async function () { - step("Mint a NFT to Wallet A and get a tokenId (tokenIdA)", async function () { - tokenIdA = await mintNFTWithRetry(privateKeyA); - if (tokenIdA === '') { - throw new Error('Unable to mint NFT'); - }; - expect(tokenIdA).not.empty; - }); - - step("Wallet A register an IP Asset with tokenIdA and get an ipId (ipIdA)", async function () { - const response = await expect( - registerIpAsset("A", nftContractAddress, tokenIdA, waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.ipId).to.be.a("string").and.not.empty; - - ipIdA = response.ipId; - }); - - step("Wallet A attach comUseLicenseTermsId1(commercial use PIL) to ipIdA", async function () { - const response = await expect( - attachLicenseTerms("A", ipIdA, comUseLicenseTermsId1, waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - }); - - step("Wallet A mint a license token with the receiverAddress set as Wallet B, get a licenseTokenId (licenseTokenIdA)", async function () { - const response = await expect( - mintLicenseTokens("A", ipIdA, comUseLicenseTermsId1, 2, accountB.address, waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.licenseTokenId).to.be.a("bigint").and.to.be.ok; - - licenseTokenIdA = response.licenseTokenId; - }); - - step("Mint a NFT to Wallet B and get a tokenId (tokenIdB)", async function () { - tokenIdB = await mintNFTWithRetry(privateKeyB); - if (tokenIdB === '') { - throw new Error('Unable to mint NFT'); - }; - expect(tokenIdB).not.empty; - }); - - step("Wallet B register an IP Asset with tokenIdB and get an ipId (ipIdB)", async function () { - const response = await expect( - registerIpAsset("B", nftContractAddress, tokenIdB, waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.ipId).to.be.a("string").and.not.empty; - - ipIdB = response.ipId; - }); - - step("Wallet B can register a derivative IP asset with licenseTokenIdA", async function () { - const response = await expect( - registerDerivativeWithLicenseTokens("B", ipIdB, [licenseTokenIdA], waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - }); - - step("Mint a NFT to WalletC and get a tokenId(tokenIdC)", async function () { - tokenIdC = await mintNFTWithRetry(privateKeyC); - if (tokenIdC === '') { - throw new Error('Unable to mint NFT'); - } - expect(tokenIdC).not.empty; - }); - - step("Wallet C register an IP Asset with tokenIdC and get an ipId (ipIdC)", async function () { - const response = await expect( - registerIpAsset("C", nftContractAddress, tokenIdC, waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.ipId).to.be.a("string").and.not.empty; - - ipIdC = response.ipId; - }) - - // licenseTokenIdA set the Wallet B's address as receiverAddress, Wallet C can NOT register a derivative IP asset with licenseTokenIdA - step("Wallet C can NOT register a derivative IP asset with licenseTokenIdA", async function () { - const response = await expect( - registerDerivativeWithLicenseTokens("C", ipIdC, [licenseTokenIdA], waitForTransaction) - ).to.be.rejectedWith("Failed to register derivative with license tokens: The contract function \"ownerOf\" reverted."); - }); - - step("Wallet C can register a derivative IP asset without licenseTokenId", async function () { - const response = await expect( - registerDerivative("C", ipIdC, [ipIdA], [comUseLicenseTermsId1], waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - }); - }); - - describe('Register a derivative IP asset with multiple parent IP assets', async function () { - step("Mint a NFT to Wallet A and get a tokenId (tokenIdA)", async function () { - tokenIdA = await mintNFTWithRetry(privateKeyA); - if (tokenIdA === "") { - throw new Error("Unable to mint NFT"); - }; - expect(tokenIdA).not.empty; - }); - - step("Wallet A register an IP Asset with tokenIdA and get an ipId (ipIdA)", async function () { - const response = await expect( - registerIpAsset("A", nftContractAddress, tokenIdA, waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.ipId).to.be.a("string").and.not.empty; - - ipIdA = response.ipId; - }); - - step("Wallet A attach comUseLicenseTermsId1(commercial use PIL) to ipIdA", async function () { - const response = await expect( - attachLicenseTerms("A", ipIdA, comUseLicenseTermsId1, waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - }); - - step("Mint a NFT to WalletB, get a tokenId (tokenidB)", async function () { - tokenIdB = await mintNFTWithRetry(privateKeyB); - if (tokenIdB === '') { - throw new Error('Unable to mint NFT'); - }; - expect(tokenIdB).not.empty; - }); - - step("Wallet B register an IP Asset with tokenIdB and get an ipId (ipIdB)", async function () { - const response = await expect( - registerIpAsset("B", nftContractAddress, tokenIdB, waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.ipId).to.be.a("string").and.not.empty; - - ipIdB = response.ipId; - }); - - step("Wallet B attach comUseLicenseTermsId1(commercial use PIL) to ipIdA", async function () { - const response = await expect( - attachLicenseTerms("B", ipIdB, comUseLicenseTermsId1, waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - }); - - step("Mint a NFT to WalletC, get a tokenId (tokenidC)", async function () { - tokenIdC = await mintNFTWithRetry(privateKeyC); - if (tokenIdC === '') { - throw new Error('Unable to mint NFT'); - }; - expect(tokenIdC).not.empty; - }); - - step("Wallet C register an IP Asset with tokenIdC and get an ipId (ipIdC)", async function () { - const response = await expect( - registerIpAsset("C", nftContractAddress, tokenIdC, waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.ipId).to.be.a("string").and.not.empty; - - ipIdC = response.ipId; - }); - - step("Wallet C can register a derivative IP asset with multiple parent IP assets (ipIdA, ipIdB)", async function () { - const response = await expect( - registerDerivative("C", ipIdC, [ipIdA, ipIdB], [comUseLicenseTermsId1, comUseLicenseTermsId1], waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; +describe("SDK E2E Test - Register Derivative IP Asset with Commercial Use PIL", function () { + describe("[smoke]Register a derivative IP asset with/without license tokens", async function () { + step("Mint a NFT to Wallet A and get a tokenId (tokenIdA)", async function () { + tokenIdA = await mintNFTWithRetry(privateKeyA); + if (tokenIdA === '') { + throw new Error('Unable to mint NFT'); + }; + expect(tokenIdA).not.empty; + }); + + step("Wallet A register an IP Asset with tokenIdA and get an ipId (ipIdA)", async function () { + const response = await expect( + registerIpAsset("A", nftContractAddress, tokenIdA, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdA = response.ipId; + }); + + step("Wallet A attach comUseLicenseTermsId1(commercial use PIL) to ipIdA", async function () { + const response = await expect( + attachLicenseTerms("A", ipIdA, comUseLicenseTermsId1, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + + step("Wallet A mint a license token with the receiverAddress set as Wallet B, get a licenseTokenId (licenseTokenIdA)", async function () { + const response = await expect( + mintLicenseTokens("A", ipIdA, comUseLicenseTermsId1, 2, accountB.address, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.licenseTokenIds).to.be.a("array").and.to.have.lengthOf(2); + + licenseTokenIdA = response.licenseTokenIds[0]; + }); + + step("Mint a NFT to Wallet B and get a tokenId (tokenIdB)", async function () { + tokenIdB = await mintNFTWithRetry(privateKeyB); + if (tokenIdB === '') { + throw new Error('Unable to mint NFT'); + }; + expect(tokenIdB).not.empty; + }); + + step("Wallet B register an IP Asset with tokenIdB and get an ipId (ipIdB)", async function () { + const response = await expect( + registerIpAsset("B", nftContractAddress, tokenIdB, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdB = response.ipId; + }); + + step("Wallet B can register a derivative IP asset with licenseTokenIdA", async function () { + const response = await expect( + registerDerivativeWithLicenseTokens("B", ipIdB, [licenseTokenIdA], waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + + step("Mint a NFT to WalletC and get a tokenId(tokenIdC)", async function () { + tokenIdC = await mintNFTWithRetry(privateKeyC); + if (tokenIdC === '') { + throw new Error('Unable to mint NFT'); + } + expect(tokenIdC).not.empty; + }); + + step("Wallet C register an IP Asset with tokenIdC and get an ipId (ipIdC)", async function () { + const response = await expect( + registerIpAsset("C", nftContractAddress, tokenIdC, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdC = response.ipId; + }) + + // licenseTokenIdA set the Wallet B's address as receiverAddress, Wallet C can NOT register a derivative IP asset with licenseTokenIdA + step("Wallet C can NOT register a derivative IP asset with licenseTokenIdA", async function () { + const response = await expect( + registerDerivativeWithLicenseTokens("C", ipIdC, [licenseTokenIdA], waitForTransaction) + ).to.be.rejectedWith("Failed to register derivative with license tokens: The contract function \"ownerOf\" reverted."); + }); + + step("Wallet C can register a derivative IP asset without licenseTokenId", async function () { + const response = await expect( + registerDerivative("C", ipIdC, [ipIdA], [comUseLicenseTermsId1], waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + }); + + describe('Register a derivative IP asset with multiple parent IP assets', async function () { + step("Mint a NFT to Wallet A and get a tokenId (tokenIdA)", async function () { + tokenIdA = await mintNFTWithRetry(privateKeyA); + if (tokenIdA === "") { + throw new Error("Unable to mint NFT"); + }; + expect(tokenIdA).not.empty; + }); + + step("Wallet A register an IP Asset with tokenIdA and get an ipId (ipIdA)", async function () { + const response = await expect( + registerIpAsset("A", nftContractAddress, tokenIdA, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdA = response.ipId; + }); + + step("Wallet A attach comUseLicenseTermsId1(commercial use PIL) to ipIdA", async function () { + const response = await expect( + attachLicenseTerms("A", ipIdA, comUseLicenseTermsId1, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + + step("Mint a NFT to WalletB, get a tokenId (tokenidB)", async function () { + tokenIdB = await mintNFTWithRetry(privateKeyB); + if (tokenIdB === '') { + throw new Error('Unable to mint NFT'); + }; + expect(tokenIdB).not.empty; + }); + + step("Wallet B register an IP Asset with tokenIdB and get an ipId (ipIdB)", async function () { + const response = await expect( + registerIpAsset("B", nftContractAddress, tokenIdB, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdB = response.ipId; + }); + + step("Wallet B attach comUseLicenseTermsId1(commercial use PIL) to ipIdA", async function () { + const response = await expect( + attachLicenseTerms("B", ipIdB, comUseLicenseTermsId1, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + + step("Mint a NFT to WalletC, get a tokenId (tokenidC)", async function () { + tokenIdC = await mintNFTWithRetry(privateKeyC); + if (tokenIdC === '') { + throw new Error('Unable to mint NFT'); + }; + expect(tokenIdC).not.empty; + }); + + step("Wallet C register an IP Asset with tokenIdC and get an ipId (ipIdC)", async function () { + const response = await expect( + registerIpAsset("C", nftContractAddress, tokenIdC, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdC = response.ipId; + }); + + step("Wallet C can register a derivative IP asset with multiple parent IP assets (ipIdA, ipIdB)", async function () { + const response = await expect( + registerDerivative("C", ipIdC, [ipIdA, ipIdB], [comUseLicenseTermsId1, comUseLicenseTermsId1], waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty;             }); + }); + + describe("Register a derivative IP assets with multiple license tokens", async function () { + step("Mint a NFT to Wallet A and get a tokenId (tokenIdA)", async function () { + tokenIdA = await mintNFTWithRetry(privateKeyA); + if (tokenIdA === "") { + throw new Error("Unable to mint NFT"); + }; + expect(tokenIdA).not.empty; + }); + + step("Wallet A register an IP Asset with tokenIdA, get an ipId (ipIdA)", async function () { + const response = await expect( + registerIpAsset("A", nftContractAddress, tokenIdA, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdA = response.ipId; + }); + + step("Wallet A attach comUseLicenseTermsId1(commercial use PIL) to ipIdA", async function () { + const response = await expect( + attachLicenseTerms("A", ipIdA, comUseLicenseTermsId1, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + + step("Wallet A mint a license token with the receiverAddress set as Wallet B, get a licenseId (licenseTokenIdA)", async function () { + const response = await expect( + mintLicenseTokens("A", ipIdA, comUseLicenseTermsId1, 2, accountC.address, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.licenseTokenIds).to.be.a("array").and.to.have.lengthOf(2); + + licenseTokenIdA= response.licenseTokenIds[0]; + }); + + step("Mint a NFT to WalletB, get a tokenId (tokenIdB)", async function () { + tokenIdB = await mintNFTWithRetry(privateKeyB); + if (tokenIdB === "") { + throw new Error("Unable to mint NFT"); + } + expect(tokenIdB).not.empty; + }); + + step("Wallet B register an IP Asset with tokenIdB, get an ipId (ipIdB)", async function () { + const response = await expect( + registerIpAsset("B", nftContractAddress, tokenIdB, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdB = response.ipId; + }); + + step("Wallet B attach comUseLicenseTermsId1(commercial use PIL) to ipIdB", async function () { + const response = await expect( + attachLicenseTerms("B", ipIdB, comUseLicenseTermsId1, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + + step("Wallet B mint a license token with the receiverAddress set as Wallet C, get a licenseTokenId (licenseTokenIdB)", async function () { + const response = await expect( + mintLicenseTokens("B", ipIdB, comUseLicenseTermsId1, 2, accountC.address, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.licenseTokenIds).to.be.a("array").and.to.have.lengthOf(2); + + licenseTokenIdB = response.licenseTokenIds[0]; + }); + + step("Mint a NFT to WalletC, get a tokenId (tokenIdC)", async function () { + tokenIdC = await mintNFTWithRetry(privateKeyC); + if (tokenIdC === "") { + throw new Error("Unable to mint NFT"); + } + expect(tokenIdC).not.empty; + }); + + step("Wallet C register an IP Asset with tokenIdC, get an ipId (ipIdC)", async function () { + const response = await expect( + registerIpAsset("C", nftContractAddress, tokenIdC, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdC = response.ipId; + }); + + step("Wallet C can register a derivative IP asset with multiple license tokens (licenseTokenIdA, licenseTokenIdB)", async function () { + const response = await expect( + registerDerivativeWithLicenseTokens("C", ipIdC, [licenseTokenIdA, licenseTokenIdB], waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + }); + + describe("Register a derivative IP assets with multiple license tokens, the sender is not licensee", async function () { + step("Mint a NFT to Wallet A and get a tokenId (tokenIdA)", async function () { + tokenIdA = await mintNFTWithRetry(privateKeyA); + if (tokenIdA === "") { + throw new Error("Unable to mint NFT"); + }; + expect(tokenIdA).not.empty; + }); + + step("Wallet A register an IP Asset with tokenIdA, get an ipId (ipIdA)", async function () { + const response = await expect( + registerIpAsset("A", nftContractAddress, tokenIdA, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdA = response.ipId; + }); + + step("Wallet A attach comUseLicenseTermsId1(commercial use PIL) to ipIdA", async function () { + const response = await expect( + attachLicenseTerms("A", ipIdA, comUseLicenseTermsId1, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + + step("Wallet A mint a license token with the receiverAddress set as Wallet B, get a licenseId (licenseTokenIdA)", async function () { + const response = await expect( + mintLicenseTokens("A", ipIdA, comUseLicenseTermsId1, 2, accountB.address, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.licenseTokenIds).to.be.a("array").and.to.have.lengthOf(2); + + licenseTokenIdA = response.licenseTokenIds[0]; + }); + + step("Mint a NFT to WalletB, get a tokenId (tokenIdB)", async function () { + tokenIdB = await mintNFTWithRetry(privateKeyB); + if (tokenIdB === "") { + throw new Error("Unable to mint NFT"); + } + expect(tokenIdB).not.empty; + }); + + step("Wallet B register an IP Asset with tokenIdB, get an ipId (ipIdB)", async function () { + const response = await expect( + registerIpAsset("B", nftContractAddress, tokenIdB, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdB = response.ipId; + }); + + step("Wallet B attach comUseLicenseTermsId1(commercial use PIL) to ipIdB", async function () { + const response = await expect( + attachLicenseTerms("B", ipIdB, comUseLicenseTermsId1, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + + step("Wallet B mint a license token with the receiverAddress set as Wallet C, get a licenseTokenId (licenseTokenIdB)", async function () { + const response = await expect( + mintLicenseTokens("B", ipIdB, comUseLicenseTermsId1, 2, accountC.address, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.licenseTokenIds).to.be.a("array").and.to.have.lengthOf(2); + + licenseTokenIdB = response.licenseTokenIds[0]; + }); + + step("Mint a NFT to WalletC, get a tokenId (tokenIdC)", async function () { + tokenIdC = await mintNFTWithRetry(privateKeyC); + if (tokenIdC === "") { + throw new Error("Unable to mint NFT"); + } + expect(tokenIdC).not.empty; + }); + + step("Wallet C register an IP Asset with tokenIdC, get an ipId (ipIdC)", async function () { + const response = await expect( + registerIpAsset("C", nftContractAddress, tokenIdC, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdC = response.ipId; + }); + + // Wallet C is not the licensee of licenseTokenIdA + step("Wallet C can NOT register derivative IP asset with licenseTokenIdA", async function () { + const response = await expect( + registerDerivativeWithLicenseTokens("C", ipIdC, [licenseTokenIdA, licenseTokenIdB], waitForTransaction) + ).to.be.rejectedWith("Failed to register derivative with license tokens: The contract function \"registerDerivativeWithLicenseTokens\" reverted with the following signature:"); + }); + }); + + describe("Register multiple derivative IP assets with license token, registered amount larger than mint amount of license token", async function () { + step("Mint a NFT to Wallet A and get a tokenId (tokenIdA)", async function () { + tokenIdA = await mintNFTWithRetry(privateKeyA); + if (tokenIdA === "") { + throw new Error("Unable to mint NFT"); + } + expect(tokenIdA).not.empty; + }); + + step("Wallet A register an IP Asset with tokenIdA and get an ipId (ipIdA)", async function () { + const response = await expect( + registerIpAsset("A", nftContractAddress, tokenIdA, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdA = response.ipId; + }); + + step("Wallet A attach comUseLicenseTermsId1(commercial use PIL) to ipIdA", async function () { + const response = await expect( + attachLicenseTerms("A", ipIdA, comUseLicenseTermsId1, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; }); - describe("Register a derivative IP assets with multiple license tokens", async function () { - step("Mint a NFT to Wallet A and get a tokenId (tokenIdA)", async function () { - tokenIdA = await mintNFTWithRetry(privateKeyA); - if (tokenIdA === "") { - throw new Error("Unable to mint NFT"); - }; - expect(tokenIdA).not.empty; - }); + step("Wallet A mint a license token with ipIdA and get a licenseTokenId (licenseTokenIdA)", async function () { + const response = await expect( + mintLicenseTokens("A", ipIdA, comUseLicenseTermsId1, 1, accountB.address, waitForTransaction) + ).to.not.be.rejected; - step("Wallet A register an IP Asset with tokenIdA, get an ipId (ipIdA)", async function () { - const response = await expect( - registerIpAsset("A", nftContractAddress, tokenIdA, waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.ipId).to.be.a("string").and.not.empty; - - ipIdA = response.ipId; - }); - - step("Wallet A attach comUseLicenseTermsId1(commercial use PIL) to ipIdA", async function () { - const response = await expect( - attachLicenseTerms("A", ipIdA, comUseLicenseTermsId1, waitForTransaction) - ).to.not.be.rejected; + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.licenseTokenIds).to.be.a("array").and.to.have.lengthOf(1); - expect(response.txHash).to.be.a("string").and.not.empty; - }); - - step("Wallet A mint a license token with the receiverAddress set as Wallet B, get a licenseId (licenseTokenIdA)", async function () { - const response = await expect( - mintLicenseTokens("A", ipIdA, comUseLicenseTermsId1, 2, accountC.address, waitForTransaction) - ).to.not.be.rejected; + licenseTokenIdA = response.licenseTokenIds[0]; + }); + + step("Mint a NFT to WalletB and get a tokenId (tokenIdB)", async function () { + tokenIdB = await mintNFTWithRetry(privateKeyB); + if (tokenIdB === "") { + throw new Error("Unable to mint NFT"); + } + expect(tokenIdB).not.empty; + }); + + step("Wallet B register an IP Asset with tokenIdB and get an ipId (ipIdB)", async function () { + const response = await expect( + registerIpAsset("B", nftContractAddress, tokenIdB, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdB = response.ipId; + }); + + step("Wallet B can register a derivative IP asset with licenseTokenIdA", async function () { + const response = await expect( + registerDerivativeWithLicenseTokens("B", ipIdB, [licenseTokenIdA], waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + + step("Mint a NFT to WalletB and get a tokenId (tokenIdB)", async function () { + tokenIdC = await mintNFTWithRetry(privateKeyB); + if (tokenIdC === "") { + throw new Error("Unable to mint NFT"); + } + expect(tokenIdC).not.empty; + }); + + step("Wallet B register a root IP Asset with tokenIdC, get an ipId (ipIdC)", async function () { + const response = await expect( + registerIpAsset("B", nftContractAddress, tokenIdC, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdC = response.ipId; + }); + + step("Wallet B can NOT register a derivative IP asset with licenseTokenIdA, no more license token", async function () { + const response = await expect( + registerDerivativeWithLicenseTokens("B", ipIdC, [licenseTokenIdA], waitForTransaction) + ).to.be.rejectedWith("Failed to register derivative with license tokens: The contract function \"ownerOf\" reverted."); + }); + }); + + describe("Register derivative IP asset with an IP that already has license", async function () { + step("Mint a NFT to Wallet A and get a tokenId (tokenIdA)", async function () { + tokenIdA = await mintNFTWithRetry(privateKeyA); + if (tokenIdA === "") { + throw new Error("Unable to mint NFT"); + } + expect(tokenIdA).not.empty; + }); + + step("Wallet A register an IP Asset with tokenIdA and get an ipId (ipIdA)", async function () { + const response = await expect( + registerIpAsset("A", nftContractAddress, tokenIdA, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdA = response.ipId; + }); + + step("Wallet A attach comUseLicenseTermsId1(commercial use PIL) to ipIdA", async function () { + const response = await expect( + attachLicenseTerms("A", ipIdA, comUseLicenseTermsId1, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + + step("Wallet A mint a license token with ipIdA and get a licenseTokenId (licenseTokenIdA)", async function () { + const response = await expect( + mintLicenseTokens("A", ipIdA, comUseLicenseTermsId1, 1, accountB.address, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.licenseTokenIds).to.be.a("array").and.to.have.lengthOf(1); + + licenseTokenIdA = response.licenseTokenIds[0]; + }); + + step("Mint a NFT to WalletB and get a tokenId (tokenIdB)", async function () { + tokenIdB = await mintNFTWithRetry(privateKeyB); + if (tokenIdB === "") { + throw new Error("Unable to mint NFT"); + } + expect(tokenIdB).not.empty; + }); + + step("Wallet B register an IP Asset with tokenIdB and get an ipId (ipIdB)", async function () { + const response = await expect( + registerIpAsset("B", nftContractAddress, tokenIdB, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdB = response.ipId; + }); + + step("Wallet B attach comUseLicenseTermsId1(commercial use PIL) to ipIdB", async function () { + const response = await expect( + attachLicenseTerms("B", ipIdB, comUseLicenseTermsId1, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + + step("Wallet B mint a license token with ipIdB and get a licenseTokenId (licenseTokenIdB)", async function () { + const response = await expect( + mintLicenseTokens("B", ipIdB, comUseLicenseTermsId1, 1, accountA.address, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.licenseTokenIds).to.be.a("array").and.to.have.lengthOf(1); + + licenseTokenIdB = response.licenseTokenIds[0]; + }); - expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.licenseTokenId).to.be.a("bigint").and.to.be.ok; - - licenseTokenIdA = response.licenseTokenId; - }); - - step("Mint a NFT to WalletB, get a tokenId (tokenIdB)", async function () { - tokenIdB = await mintNFTWithRetry(privateKeyB); - if (tokenIdB === "") { - throw new Error("Unable to mint NFT"); - } - expect(tokenIdB).not.empty; - }); - - step("Wallet B register an IP Asset with tokenIdB, get an ipId (ipIdB)", async function () { - const response = await expect( - registerIpAsset("B", nftContractAddress, tokenIdB, waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.ipId).to.be.a("string").and.not.empty; - - ipIdB = response.ipId; - }); - - step("Wallet B attach comUseLicenseTermsId1(commercial use PIL) to ipIdB", async function () { - const response = await expect( - attachLicenseTerms("B", ipIdB, comUseLicenseTermsId1, waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - }); - - step("Wallet B mint a license token with the receiverAddress set as Wallet C, get a licenseTokenId (licenseTokenIdB)", async function () { - const response = await expect( - mintLicenseTokens("B", ipIdB, comUseLicenseTermsId1, 2, accountC.address, waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.licenseTokenId).to.be.a("bigint").and.to.be.ok; - - licenseTokenIdB = response.licenseTokenId; - }); - - step("Mint a NFT to WalletC, get a tokenId (tokenIdC)", async function () { - tokenIdC = await mintNFTWithRetry(privateKeyC); - if (tokenIdC === "") { - throw new Error("Unable to mint NFT"); - } - expect(tokenIdC).not.empty; - }); - - step("Wallet C register an IP Asset with tokenIdC, get an ipId (ipIdC)", async function () { - const response = await expect( - registerIpAsset("C", nftContractAddress, tokenIdC, waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.ipId).to.be.a("string").and.not.empty; - - ipIdC = response.ipId; - }); - - step("Wallet C can register a derivative IP asset with multiple license tokens (licenseTokenIdA, licenseTokenIdB)", async function () { - const response = await expect( - registerDerivativeWithLicenseTokens("C", ipIdC, [licenseTokenIdA, licenseTokenIdB], waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - }); - }); - - describe("Register a derivative IP assets with multiple license tokens, the sender is not licensee", async function () { - step("Mint a NFT to Wallet A and get a tokenId (tokenIdA)", async function () { - tokenIdA = await mintNFTWithRetry(privateKeyA); - if (tokenIdA === "") { - throw new Error("Unable to mint NFT"); - }; - expect(tokenIdA).not.empty; - }); - - step("Wallet A register an IP Asset with tokenIdA, get an ipId (ipIdA)", async function () { - const response = await expect( - registerIpAsset("A", nftContractAddress, tokenIdA, waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.ipId).to.be.a("string").and.not.empty; - - ipIdA = response.ipId; - }); - - step("Wallet A attach comUseLicenseTermsId1(commercial use PIL) to ipIdA", async function () { - const response = await expect( - attachLicenseTerms("A", ipIdA, comUseLicenseTermsId1, waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - }); - - step("Wallet A mint a license token with the receiverAddress set as Wallet B, get a licenseId (licenseTokenIdA)", async function () { - const response = await expect( - mintLicenseTokens("A", ipIdA, comUseLicenseTermsId1, 2, accountB.address, waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.licenseTokenId).to.be.a("bigint").and.to.be.ok; - - licenseTokenIdA = response.licenseTokenId; - }); - - step("Mint a NFT to WalletB, get a tokenId (tokenIdB)", async function () { - tokenIdB = await mintNFTWithRetry(privateKeyB); - if (tokenIdB === "") { - throw new Error("Unable to mint NFT"); - } - expect(tokenIdB).not.empty; - }); - - step("Wallet B register an IP Asset with tokenIdB, get an ipId (ipIdB)", async function () { - const response = await expect( - registerIpAsset("B", nftContractAddress, tokenIdB, waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.ipId).to.be.a("string").and.not.empty; - - ipIdB = response.ipId; - }); - - step("Wallet B attach comUseLicenseTermsId1(commercial use PIL) to ipIdB", async function () { - const response = await expect( - attachLicenseTerms("B", ipIdB, comUseLicenseTermsId1, waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - }); - - step("Wallet B mint a license token with the receiverAddress set as Wallet C, get a licenseTokenId (licenseTokenIdB)", async function () { - const response = await expect( - mintLicenseTokens("B", ipIdB, comUseLicenseTermsId1, 2, accountC.address, waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.licenseTokenId).to.be.a("bigint").and.to.be.ok; - - licenseTokenIdB = response.licenseTokenId; - }); - - step("Mint a NFT to WalletC, get a tokenId (tokenIdC)", async function () { - tokenIdC = await mintNFTWithRetry(privateKeyC); - if (tokenIdC === "") { - throw new Error("Unable to mint NFT"); - } - expect(tokenIdC).not.empty; - }); - - step("Wallet C register an IP Asset with tokenIdC, get an ipId (ipIdC)", async function () { - const response = await expect( - registerIpAsset("C", nftContractAddress, tokenIdC, waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.ipId).to.be.a("string").and.not.empty; - - ipIdC = response.ipId; - }); - - // Wallet C is not the licensee of licenseTokenIdA - step("Wallet C can NOT register derivative IP asset with licenseTokenIdA", async function () { - const response = await expect( - registerDerivativeWithLicenseTokens("C", ipIdC, [licenseTokenIdA, licenseTokenIdB], waitForTransaction) - ).to.be.rejectedWith("Failed to register derivative with license tokens: The contract function \"registerDerivativeWithLicenseTokens\" reverted with the following signature:"); - }); - }); - - describe("Register multiple derivative IP assets with license token, registered amount larger than mint amount of license token", async function () { - step("Mint a NFT to Wallet A and get a tokenId (tokenIdA)", async function () { - tokenIdA = await mintNFTWithRetry(privateKeyA); - if (tokenIdA === "") { - throw new Error("Unable to mint NFT"); - } - expect(tokenIdA).not.empty; - }); - - step("Wallet A register an IP Asset with tokenIdA and get an ipId (ipIdA)", async function () { - const response = await expect( - registerIpAsset("A", nftContractAddress, tokenIdA, waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.ipId).to.be.a("string").and.not.empty; - - ipIdA = response.ipId; - }); - - step("Wallet A attach comUseLicenseTermsId1(commercial use PIL) to ipIdA", async function () { - const response = await expect( - attachLicenseTerms("A", ipIdA, comUseLicenseTermsId1, waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - }); - - step("Wallet A mint a license token with ipIdA and get a licenseTokenId (licenseTokenIdA)", async function () { - const response = await expect( - mintLicenseTokens("A", ipIdA, comUseLicenseTermsId1, 1, accountB.address, waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.licenseTokenId).to.be.a("bigint").and.to.be.ok; - - licenseTokenIdA = response.licenseTokenId; - }); - - step("Mint a NFT to WalletB and get a tokenId (tokenIdB)", async function () { - tokenIdB = await mintNFTWithRetry(privateKeyB); - if (tokenIdB === "") { - throw new Error("Unable to mint NFT"); - } - expect(tokenIdB).not.empty; - }); - - step("Wallet B register an IP Asset with tokenIdB and get an ipId (ipIdB)", async function () { - const response = await expect( - registerIpAsset("B", nftContractAddress, tokenIdB, waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.ipId).to.be.a("string").and.not.empty; - - ipIdB = response.ipId; - }); - - step("Wallet B can register a derivative IP asset with licenseTokenIdA", async function () { - const response = await expect( - registerDerivativeWithLicenseTokens("B", ipIdB, [licenseTokenIdA], waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - }); - - step("Mint a NFT to WalletB and get a tokenId (tokenIdB)", async function () { - tokenIdC = await mintNFTWithRetry(privateKeyB); - if (tokenIdC === "") { - throw new Error("Unable to mint NFT"); - } - expect(tokenIdC).not.empty; - }); - - step("Wallet B register a root IP Asset with tokenIdC, get an ipId (ipIdC)", async function () { - const response = await expect( - registerIpAsset("B", nftContractAddress, tokenIdC, waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.ipId).to.be.a("string").and.not.empty; - - ipIdC = response.ipId; - }); - - step("Wallet B can NOT register a derivative IP asset with licenseTokenIdA, no more license token", async function () { - const response = await expect( - registerDerivativeWithLicenseTokens("B", ipIdC, [licenseTokenIdA], waitForTransaction) - ).to.be.rejectedWith("Failed to register derivative with license tokens: The contract function \"ownerOf\" reverted."); - }); - }); - - describe("Register derivative IP asset with an IP that already has license", async function () { - step("Mint a NFT to Wallet A and get a tokenId (tokenIdA)", async function () { - tokenIdA = await mintNFTWithRetry(privateKeyA); - if (tokenIdA === "") { - throw new Error("Unable to mint NFT"); - } - expect(tokenIdA).not.empty; - }); - - step("Wallet A register an IP Asset with tokenIdA and get an ipId (ipIdA)", async function () { - const response = await expect( - registerIpAsset("A", nftContractAddress, tokenIdA, waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.ipId).to.be.a("string").and.not.empty; - - ipIdA = response.ipId; - }); - - step("Wallet A attach comUseLicenseTermsId1(commercial use PIL) to ipIdA", async function () { - const response = await expect( - attachLicenseTerms("A", ipIdA, comUseLicenseTermsId1, waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - }); - - step("Wallet A mint a license token with ipIdA and get a licenseTokenId (licenseTokenIdA)", async function () { - const response = await expect( - mintLicenseTokens("A", ipIdA, comUseLicenseTermsId1, 1, accountB.address, waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.licenseTokenId).to.be.a("bigint").and.to.be.ok; - - licenseTokenIdA = response.licenseTokenId; - }); - - step("Mint a NFT to WalletB and get a tokenId (tokenIdB)", async function () { - tokenIdB = await mintNFTWithRetry(privateKeyB); - if (tokenIdB === "") { - throw new Error("Unable to mint NFT"); - } - expect(tokenIdB).not.empty; - }); - - step("Wallet B register an IP Asset with tokenIdB and get an ipId (ipIdB)", async function () { - const response = await expect( - registerIpAsset("B", nftContractAddress, tokenIdB, waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.ipId).to.be.a("string").and.not.empty; - - ipIdB = response.ipId; - }); - - step("Wallet B attach comUseLicenseTermsId1(commercial use PIL) to ipIdB", async function () { - const response = await expect( - attachLicenseTerms("B", ipIdB, comUseLicenseTermsId1, waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - }); - - step("Wallet B mint a license token with ipIdB and get a licenseTokenId (licenseTokenIdB)", async function () { - const response = await expect( - mintLicenseTokens("B", ipIdB, comUseLicenseTermsId1, 1, accountA.address, waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.licenseTokenId).to.be.a("bigint").and.to.be.ok; - - licenseTokenIdB = response.licenseTokenId; - }); - - step("Wallet B can NOT register a derivative IP asset with ipIdB, LicenseRegistry__DerivativeIpAlreadyHasLicense(address)", async function () { - const response = await expect( - registerDerivativeWithLicenseTokens("B", ipIdB, [licenseTokenIdA], waitForTransaction) - ).to.be.rejectedWith("Failed to register derivative with license tokens: The contract function \"registerDerivativeWithLicenseTokens\" reverted with the following signature:", "0x650aa4f5"); - }); + step("Wallet B can NOT register a derivative IP asset with ipIdB, LicenseRegistry__DerivativeIpAlreadyHasLicense(address)", async function () { + const response = await expect( + registerDerivativeWithLicenseTokens("B", ipIdB, [licenseTokenIdA], waitForTransaction) + ).to.be.rejectedWith("Failed to register derivative with license tokens: The contract function \"registerDerivativeWithLicenseTokens\" reverted with the following signature:", "0x650aa4f5"); }); }); }); diff --git a/test/e2e/derivativeIP.nonComPIL.test.ts b/test/e2e/derivativeIP.nonComPIL.test.ts index dbd6f8f..90f4219 100644 --- a/test/e2e/derivativeIP.nonComPIL.test.ts +++ b/test/e2e/derivativeIP.nonComPIL.test.ts @@ -21,575 +21,573 @@ let licenseTokenIdB: string; const waitForTransaction: boolean = true; -describe('SDK E2E Test', function () { - describe("Register Derivative IP Asset with Non-Commercial Social Remixing PIL", function () { - describe("[smoke]Register a derivative IP asset with/without license tokens", async function () { - step("Mint a NFT to Wallet A and get a tokenId (tokenIdA)", async function () { - tokenIdA = await mintNFTWithRetry(privateKeyA); - if (tokenIdA === '') { - throw new Error('Unable to mint NFT'); - }; - expect(tokenIdA).not.empty; - }); - - step("Wallet A register an IP Asset with tokenIdA and get an ipId (ipIdA)", async function () { - const response = await expect( - registerIpAsset("A", nftContractAddress, tokenIdA, waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.ipId).to.be.a("string").and.not.empty; - - ipIdA = response.ipId; - }); - - step("Wallet A attach nonComLicenseTermsId(non-commercial social remixing PIL) to ipIdA", async function () { - const response = await expect( - attachLicenseTerms("A", ipIdA, nonComLicenseTermsId, waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - }); - - step("Wallet A mint a license token with the receiverAddress set as Wallet B, get a licenseTokenId (licenseTokenIdA)", async function () { - const response = await expect( - mintLicenseTokens("A", ipIdA, nonComLicenseTermsId, 2, accountB.address, waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.licenseTokenId).to.be.a("bigint").and.to.be.ok; - - licenseTokenIdA = response.licenseTokenId; - }); - - step("Mint a NFT to Wallet B and get a tokenId (tokenIdB)", async function () { - tokenIdB = await mintNFTWithRetry(privateKeyB); - if (tokenIdB === '') { - throw new Error('Unable to mint NFT'); - }; - expect(tokenIdB).not.empty; - }); - - step("Wallet B register an IP Asset with tokenIdB and get an ipId (ipIdB)", async function () { - const response = await expect( - registerIpAsset("B", nftContractAddress, tokenIdB, waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.ipId).to.be.a("string").and.not.empty; - - ipIdB = response.ipId; - }); - - step("Wallet B can register a derivative IP asset with licenseTokenIdA", async function () { - const response = await expect( - registerDerivativeWithLicenseTokens("B", ipIdB, [licenseTokenIdA], waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - }); - - step("Mint a NFT to WalletC and get a tokenId(tokenIdC)", async function () { - tokenIdC = await mintNFTWithRetry(privateKeyC); - if (tokenIdC === '') { - throw new Error('Unable to mint NFT'); - } - expect(tokenIdC).not.empty; - }); - - step("Wallet C register an IP Asset with tokenIdC and get an ipId (ipIdC)", async function () { - const response = await expect( - registerIpAsset("C", nftContractAddress, tokenIdC, waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.ipId).to.be.a("string").and.not.empty; - - ipIdC = response.ipId; - }) - - // licenseTokenIdA set the Wallet B's address as receiverAddress, Wallet C can NOT register a derivative IP asset with licenseTokenIdA - step("Wallet C can NOT register a derivative IP asset with licenseTokenIdA", async function () { - const response = await expect( - registerDerivativeWithLicenseTokens("C", ipIdC, [licenseTokenIdA], waitForTransaction) - ).to.be.rejectedWith("Failed to register derivative with license tokens: The contract function \"ownerOf\" reverted."); - }); - - step("Wallet C can register a derivative IP asset without licenseTokenId", async function () { - const response = await expect( - registerDerivative("C", ipIdC, [ipIdA], [nonComLicenseTermsId], waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - }); - }); - - describe('Register a derivative IP asset with multiple parent IP assets', async function () { - step("Mint a NFT to Wallet A and get a tokenId (tokenIdA)", async function () { - tokenIdA = await mintNFTWithRetry(privateKeyA); - if (tokenIdA === "") { - throw new Error("Unable to mint NFT"); - }; - expect(tokenIdA).not.empty; - }); - - step("Wallet A register an IP Asset with tokenIdA and get an ipId (ipIdA)", async function () { - const response = await expect( - registerIpAsset("A", nftContractAddress, tokenIdA, waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.ipId).to.be.a("string").and.not.empty; - - ipIdA = response.ipId; - }); - - step("Wallet A attach nonComLicenseTermsId(non-commercial social remixing PIL) to ipIdA", async function () { - const response = await expect( - attachLicenseTerms("A", ipIdA, nonComLicenseTermsId, waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - }); - - step("Mint a NFT to WalletB, get a tokenId (tokenidB)", async function () { - tokenIdB = await mintNFTWithRetry(privateKeyB); - if (tokenIdB === '') { - throw new Error('Unable to mint NFT'); - }; - expect(tokenIdB).not.empty; - }); - - step("Wallet B register an IP Asset with tokenIdB and get an ipId (ipIdB)", async function () { - const response = await expect( - registerIpAsset("B", nftContractAddress, tokenIdB, waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.ipId).to.be.a("string").and.not.empty; - - ipIdB = response.ipId; - }); - - step("Wallet B attach nonComLicenseTermsId(non-commercial social remixing PIL) to ipIdA", async function () { - const response = await expect( - attachLicenseTerms("B", ipIdB, nonComLicenseTermsId, waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - }); - - step("Mint a NFT to WalletC, get a tokenId (tokenidC)", async function () { - tokenIdC = await mintNFTWithRetry(privateKeyC); - if (tokenIdC === '') { - throw new Error('Unable to mint NFT'); - }; - expect(tokenIdC).not.empty; - }); - - step("Wallet C register an IP Asset with tokenIdC and get an ipId (ipIdC)", async function () { - const response = await expect( - registerIpAsset("C", nftContractAddress, tokenIdC, waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.ipId).to.be.a("string").and.not.empty; - - ipIdC = response.ipId; - }); - - step("Wallet C can register a derivative IP asset with multiple parent IP assets", async function () { - const response = await expect( - registerDerivative("C", ipIdC, [ipIdA, ipIdB], [nonComLicenseTermsId, nonComLicenseTermsId], waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; +describe("SDK E2E Test - Register Derivative IP Asset with Non-Commercial Social Remixing PIL", function () { + describe("[smoke]Register a derivative IP asset with/without license tokens", async function () { + step("Mint a NFT to Wallet A and get a tokenId (tokenIdA)", async function () { + tokenIdA = await mintNFTWithRetry(privateKeyA); + if (tokenIdA === '') { + throw new Error('Unable to mint NFT'); + }; + expect(tokenIdA).not.empty; + }); + + step("Wallet A register an IP Asset with tokenIdA and get an ipId (ipIdA)", async function () { + const response = await expect( + registerIpAsset("A", nftContractAddress, tokenIdA, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdA = response.ipId; + }); + + step("Wallet A attach nonComLicenseTermsId(non-commercial social remixing PIL) to ipIdA", async function () { + const response = await expect( + attachLicenseTerms("A", ipIdA, nonComLicenseTermsId, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + + step("Wallet A mint a license token with the receiverAddress set as Wallet B, get a licenseTokenId (licenseTokenIdA)", async function () { + const response = await expect( + mintLicenseTokens("A", ipIdA, nonComLicenseTermsId, 2, accountB.address, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.licenseTokenIds).to.be.a("array").and.to.have.lengthOf(2); + + licenseTokenIdA = response.licenseTokenIds[0]; + }); + + step("Mint a NFT to Wallet B and get a tokenId (tokenIdB)", async function () { + tokenIdB = await mintNFTWithRetry(privateKeyB); + if (tokenIdB === '') { + throw new Error('Unable to mint NFT'); + }; + expect(tokenIdB).not.empty; + }); + + step("Wallet B register an IP Asset with tokenIdB and get an ipId (ipIdB)", async function () { + const response = await expect( + registerIpAsset("B", nftContractAddress, tokenIdB, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdB = response.ipId; + }); + + step("Wallet B can register a derivative IP asset with licenseTokenIdA", async function () { + const response = await expect( + registerDerivativeWithLicenseTokens("B", ipIdB, [licenseTokenIdA], waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + + step("Mint a NFT to WalletC and get a tokenId(tokenIdC)", async function () { + tokenIdC = await mintNFTWithRetry(privateKeyC); + if (tokenIdC === '') { + throw new Error('Unable to mint NFT'); + } + expect(tokenIdC).not.empty; + }); + + step("Wallet C register an IP Asset with tokenIdC and get an ipId (ipIdC)", async function () { + const response = await expect( + registerIpAsset("C", nftContractAddress, tokenIdC, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdC = response.ipId; + }) + + // licenseTokenIdA set the Wallet B's address as receiverAddress, Wallet C can NOT register a derivative IP asset with licenseTokenIdA + step("Wallet C can NOT register a derivative IP asset with licenseTokenIdA", async function () { + const response = await expect( + registerDerivativeWithLicenseTokens("C", ipIdC, [licenseTokenIdA], waitForTransaction) + ).to.be.rejectedWith("Failed to register derivative with license tokens: The contract function \"ownerOf\" reverted."); + }); + + step("Wallet C can register a derivative IP asset without licenseTokenId", async function () { + const response = await expect( + registerDerivative("C", ipIdC, [ipIdA], [nonComLicenseTermsId], waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + }); + + describe('Register a derivative IP asset with multiple parent IP assets', async function () { + step("Mint a NFT to Wallet A and get a tokenId (tokenIdA)", async function () { + tokenIdA = await mintNFTWithRetry(privateKeyA); + if (tokenIdA === "") { + throw new Error("Unable to mint NFT"); + }; + expect(tokenIdA).not.empty; + }); + + step("Wallet A register an IP Asset with tokenIdA and get an ipId (ipIdA)", async function () { + const response = await expect( + registerIpAsset("A", nftContractAddress, tokenIdA, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdA = response.ipId; + }); + + step("Wallet A attach nonComLicenseTermsId(non-commercial social remixing PIL) to ipIdA", async function () { + const response = await expect( + attachLicenseTerms("A", ipIdA, nonComLicenseTermsId, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + + step("Mint a NFT to WalletB, get a tokenId (tokenidB)", async function () { + tokenIdB = await mintNFTWithRetry(privateKeyB); + if (tokenIdB === '') { + throw new Error('Unable to mint NFT'); + }; + expect(tokenIdB).not.empty; + }); + + step("Wallet B register an IP Asset with tokenIdB and get an ipId (ipIdB)", async function () { + const response = await expect( + registerIpAsset("B", nftContractAddress, tokenIdB, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdB = response.ipId; + }); + + step("Wallet B attach nonComLicenseTermsId(non-commercial social remixing PIL) to ipIdA", async function () { + const response = await expect( + attachLicenseTerms("B", ipIdB, nonComLicenseTermsId, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + + step("Mint a NFT to WalletC, get a tokenId (tokenidC)", async function () { + tokenIdC = await mintNFTWithRetry(privateKeyC); + if (tokenIdC === '') { + throw new Error('Unable to mint NFT'); + }; + expect(tokenIdC).not.empty; + }); + + step("Wallet C register an IP Asset with tokenIdC and get an ipId (ipIdC)", async function () { + const response = await expect( + registerIpAsset("C", nftContractAddress, tokenIdC, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdC = response.ipId; + }); + + step("Wallet C can register a derivative IP asset with multiple parent IP assets", async function () { + const response = await expect( + registerDerivative("C", ipIdC, [ipIdA, ipIdB], [nonComLicenseTermsId, nonComLicenseTermsId], waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty;             }); + }); + + describe("Register a derivative IP assets with multiple license tokens", async function () { + step("Mint a NFT to Wallet A and get a tokenId (tokenIdA)", async function () { + tokenIdA = await mintNFTWithRetry(privateKeyA); + if (tokenIdA === "") { + throw new Error("Unable to mint NFT"); + }; + expect(tokenIdA).not.empty; + }); + + step("Wallet A register an IP Asset with tokenIdA, get an ipId (ipIdA)", async function () { + const response = await expect( + registerIpAsset("A", nftContractAddress, tokenIdA, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdA = response.ipId; + }); + + step("Wallet A attach nonComLicenseTermsId(non-commercial social remixing PIL) to ipIdA", async function () { + const response = await expect( + attachLicenseTerms("A", ipIdA, nonComLicenseTermsId, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + + step("Wallet A mint a license token with the receiverAddress set as Wallet B, get a licenseId (licenseTokenIdA)", async function () { + const response = await expect( + mintLicenseTokens("A", ipIdA, nonComLicenseTermsId, 2, accountC.address, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.licenseTokenIds).to.be.a("array").and.to.have.lengthOf(2); + + licenseTokenIdA = response.licenseTokenIds[0]; + }); + + step("Mint a NFT to WalletB, get a tokenId (tokenIdB)", async function () { + tokenIdB = await mintNFTWithRetry(privateKeyB); + if (tokenIdB === "") { + throw new Error("Unable to mint NFT"); + } + expect(tokenIdB).not.empty; + }); + + step("Wallet B register an IP Asset with tokenIdB, get an ipId (ipIdB)", async function () { + const response = await expect( + registerIpAsset("B", nftContractAddress, tokenIdB, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdB = response.ipId; + }); + + step("Wallet B attach nonComLicenseTermsId(non-commercial social remixing PIL) to ipIdB", async function () { + const response = await expect( + attachLicenseTerms("B", ipIdB, nonComLicenseTermsId, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + + step("Wallet B mint a license token with the receiverAddress set as Wallet C, get a licenseTokenId (licenseTokenIdB)", async function () { + const response = await expect( + mintLicenseTokens("B", ipIdB, nonComLicenseTermsId, 2, accountC.address, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.licenseTokenIds).to.be.a("array").and.to.have.lengthOf(2); + + licenseTokenIdB = response.licenseTokenIds[0]; + }); + + step("Mint a NFT to WalletC, get a tokenId (tokenIdC)", async function () { + tokenIdC = await mintNFTWithRetry(privateKeyC); + if (tokenIdC === "") { + throw new Error("Unable to mint NFT"); + } + expect(tokenIdC).not.empty; + }); + + step("Wallet C register an IP Asset with tokenIdC, get an ipId (ipIdC)", async function () { + const response = await expect( + registerIpAsset("C", nftContractAddress, tokenIdC, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdC = response.ipId; + }); + + step("ipIdC can link to ipIdA and ipIdB as their derivative IP Asset", async function () { + const response = await expect( + registerDerivativeWithLicenseTokens("C", ipIdC, [licenseTokenIdA, licenseTokenIdB], waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + }); + + describe("Register a derivative IP assets with multiple license tokens, the sender is not licensee", async function () { + step("Mint a NFT to Wallet A and get a tokenId (tokenIdA)", async function () { + tokenIdA = await mintNFTWithRetry(privateKeyA); + if (tokenIdA === "") { + throw new Error("Unable to mint NFT"); + }; + expect(tokenIdA).not.empty; + }); + + step("Wallet A register an IP Asset with tokenIdA, get an ipId (ipIdA)", async function () { + const response = await expect( + registerIpAsset("A", nftContractAddress, tokenIdA, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdA = response.ipId; + }); + + step("Wallet A attach nonComLicenseTermsId(non-commercial social remixing PIL) to ipIdA", async function () { + const response = await expect( + attachLicenseTerms("A", ipIdA, nonComLicenseTermsId, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + + step("Wallet A mint a license token with the receiverAddress set as Wallet B, get a licenseId (licenseTokenIdA)", async function () { + const response = await expect( + mintLicenseTokens("A", ipIdA, nonComLicenseTermsId, 2, accountB.address, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.licenseTokenIds).to.be.a("array").and.to.have.lengthOf(2); + + licenseTokenIdA = response.licenseTokenIds[0]; + }); + + step("Mint a NFT to WalletB, get a tokenId (tokenIdB)", async function () { + tokenIdB = await mintNFTWithRetry(privateKeyB); + if (tokenIdB === "") { + throw new Error("Unable to mint NFT"); + } + expect(tokenIdB).not.empty; + }); + + step("Wallet B register an IP Asset with tokenIdB, get an ipId (ipIdB)", async function () { + const response = await expect( + registerIpAsset("B", nftContractAddress, tokenIdB, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdB = response.ipId; + }); + + step("Wallet B attach nonComLicenseTermsId(non-commercial social remixing PIL) to ipIdB", async function () { + const response = await expect( + attachLicenseTerms("B", ipIdB, nonComLicenseTermsId, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + + step("Wallet B mint a license token with the receiverAddress set as Wallet C, get a licenseTokenId (licenseTokenIdB)", async function () { + const response = await expect( + mintLicenseTokens("B", ipIdB, nonComLicenseTermsId, 2, accountC.address, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.licenseTokenIds).to.be.a("array").and.to.have.lengthOf(2); + + licenseTokenIdB = response.licenseTokenIds[0]; + }); + + step("Mint a NFT to WalletC, get a tokenId (tokenIdC)", async function () { + tokenIdC = await mintNFTWithRetry(privateKeyC); + if (tokenIdC === "") { + throw new Error("Unable to mint NFT"); + } + expect(tokenIdC).not.empty; + }); + + step("Wallet C register an IP Asset with tokenIdC, get an ipId (ipIdC)", async function () { + const response = await expect( + registerIpAsset("C", nftContractAddress, tokenIdC, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdC = response.ipId; + }); + + // Wallet C is not the licensee of licenseTokenIdA + step("Wallet C can NOT register derivative IP asset with licenseTokenIdA", async function () { + const response = await expect( + registerDerivativeWithLicenseTokens("C", ipIdC, [licenseTokenIdA, licenseTokenIdB], waitForTransaction) + ).to.be.rejectedWith("Failed to register derivative with license tokens: The contract function \"registerDerivativeWithLicenseTokens\" reverted with the following signature:"); + }); + }); + + describe("Register multiple derivative IP assets with license token, registered amount larger than mint amount of license token", async function () { + step("Mint a NFT to Wallet A and get a tokenId (tokenIdA)", async function () { + tokenIdA = await mintNFTWithRetry(privateKeyA); + if (tokenIdA === "") { + throw new Error("Unable to mint NFT"); + } + expect(tokenIdA).not.empty; + }); + + step("Wallet A register an IP Asset with tokenIdA and get an ipId (ipIdA)", async function () { + const response = await expect( + registerIpAsset("A", nftContractAddress, tokenIdA, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdA = response.ipId; + }); + + step("Wallet A attach nonComLicenseTermsId(non-commercial social remixing PIL) to ipIdA", async function () { + const response = await expect( + attachLicenseTerms("A", ipIdA, nonComLicenseTermsId, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; }); - describe("Register a derivative IP assets with multiple license tokens", async function () { - step("Mint a NFT to Wallet A and get a tokenId (tokenIdA)", async function () { - tokenIdA = await mintNFTWithRetry(privateKeyA); - if (tokenIdA === "") { - throw new Error("Unable to mint NFT"); - }; - expect(tokenIdA).not.empty; - }); + step("Wallet A mint a license token with ipIdA and get a licenseTokenId (licenseTokenIdA)", async function () { + const response = await expect( + mintLicenseTokens("A", ipIdA, nonComLicenseTermsId, 1, accountB.address, waitForTransaction) + ).to.not.be.rejected; - step("Wallet A register an IP Asset with tokenIdA, get an ipId (ipIdA)", async function () { - const response = await expect( - registerIpAsset("A", nftContractAddress, tokenIdA, waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.ipId).to.be.a("string").and.not.empty; - - ipIdA = response.ipId; - }); - - step("Wallet A attach nonComLicenseTermsId(non-commercial social remixing PIL) to ipIdA", async function () { - const response = await expect( - attachLicenseTerms("A", ipIdA, nonComLicenseTermsId, waitForTransaction) - ).to.not.be.rejected; + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.licenseTokenIds).to.be.a("array").and.to.have.lengthOf(1); - expect(response.txHash).to.be.a("string").and.not.empty; - }); - - step("Wallet A mint a license token with the receiverAddress set as Wallet B, get a licenseId (licenseTokenIdA)", async function () { - const response = await expect( - mintLicenseTokens("A", ipIdA, nonComLicenseTermsId, 2, accountC.address, waitForTransaction) - ).to.not.be.rejected; + licenseTokenIdA = response.licenseTokenIds[0]; + }); + + step("Mint a NFT to WalletB and get a tokenId (tokenIdB)", async function () { + tokenIdB = await mintNFTWithRetry(privateKeyB); + if (tokenIdB === "") { + throw new Error("Unable to mint NFT"); + } + expect(tokenIdB).not.empty; + }); + + step("Wallet B register an IP Asset with tokenIdB and get an ipId (ipIdB)", async function () { + const response = await expect( + registerIpAsset("B", nftContractAddress, tokenIdB, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdB = response.ipId; + }); + + step("Wallet B can register a derivative IP asset with licenseTokenIdA", async function () { + const response = await expect( + registerDerivativeWithLicenseTokens("B", ipIdB, [licenseTokenIdA], waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + + step("Mint a NFT to WalletB and get a tokenId (tokenIdB)", async function () { + tokenIdC = await mintNFTWithRetry(privateKeyB); + if (tokenIdC === "") { + throw new Error("Unable to mint NFT"); + } + expect(tokenIdC).not.empty; + }); + + step("Wallet B register a root IP Asset with tokenIdC, get an ipId (ipIdC)", async function () { + const response = await expect( + registerIpAsset("B", nftContractAddress, tokenIdC, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdC = response.ipId; + }); + + step("Wallet B can NOT register a derivative IP asset with licenseTokenIdA, no more license token", async function () { + const response = await expect( + registerDerivativeWithLicenseTokens("B", ipIdC, [licenseTokenIdA], waitForTransaction) + ).to.be.rejectedWith("Failed to register derivative with license tokens: The contract function \"ownerOf\" reverted."); + }); + }); + + describe("Register derivative IP asset with an IP that already has license", async function () { + step("Mint a NFT to Wallet A and get a tokenId (tokenIdA)", async function () { + tokenIdA = await mintNFTWithRetry(privateKeyA); + if (tokenIdA === "") { + throw new Error("Unable to mint NFT"); + } + expect(tokenIdA).not.empty; + }); + + step("Wallet A register an IP Asset with tokenIdA and get an ipId (ipIdA)", async function () { + const response = await expect( + registerIpAsset("A", nftContractAddress, tokenIdA, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdA = response.ipId; + }); + + step("Wallet A attach nonComLicenseTermsId(non-commercial social remixing PIL) to ipIdA", async function () { + const response = await expect( + attachLicenseTerms("A", ipIdA, nonComLicenseTermsId, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + + step("Wallet A mint a license token with ipIdA and get a licenseTokenId (licenseTokenIdA)", async function () { + const response = await expect( + mintLicenseTokens("A", ipIdA, nonComLicenseTermsId, 1, accountB.address, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.licenseTokenIds).to.be.a("array").and.to.have.lengthOf(1); + + licenseTokenIdA = response.licenseTokenIds[0]; + }); + + step("Mint a NFT to WalletB and get a tokenId (tokenIdB)", async function () { + tokenIdB = await mintNFTWithRetry(privateKeyB); + if (tokenIdB === "") { + throw new Error("Unable to mint NFT"); + } + expect(tokenIdB).not.empty; + }); + + step("Wallet B register an IP Asset with tokenIdB and get an ipId (ipIdB)", async function () { + const response = await expect( + registerIpAsset("B", nftContractAddress, tokenIdB, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdB = response.ipId; + }); + + step("Wallet B attach nonComLicenseTermsId(non-commercial social remixing PIL) to ipIdA", async function () { + const response = await expect( + attachLicenseTerms("B", ipIdB, nonComLicenseTermsId, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + + step("Wallet B mint a license token with ipIdB and get a licenseTokenId (licenseTokenIdB)", async function () { + const response = await expect( + mintLicenseTokens("B", ipIdB, nonComLicenseTermsId, 1, accountA.address, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.licenseTokenIds).to.be.a("array").and.to.have.lengthOf(1); + + licenseTokenIdB = response.licenseTokenIds[0]; + }); - expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.licenseTokenId).to.be.a("bigint").and.to.be.ok; - - licenseTokenIdA = response.licenseTokenId; - }); - - step("Mint a NFT to WalletB, get a tokenId (tokenIdB)", async function () { - tokenIdB = await mintNFTWithRetry(privateKeyB); - if (tokenIdB === "") { - throw new Error("Unable to mint NFT"); - } - expect(tokenIdB).not.empty; - }); - - step("Wallet B register an IP Asset with tokenIdB, get an ipId (ipIdB)", async function () { - const response = await expect( - registerIpAsset("B", nftContractAddress, tokenIdB, waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.ipId).to.be.a("string").and.not.empty; - - ipIdB = response.ipId; - }); - - step("Wallet B attach nonComLicenseTermsId(non-commercial social remixing PIL) to ipIdB", async function () { - const response = await expect( - attachLicenseTerms("B", ipIdB, nonComLicenseTermsId, waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - }); - - step("Wallet B mint a license token with the receiverAddress set as Wallet C, get a licenseTokenId (licenseTokenIdB)", async function () { - const response = await expect( - mintLicenseTokens("B", ipIdB, nonComLicenseTermsId, 2, accountC.address, waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.licenseTokenId).to.be.a("bigint").and.to.be.ok; - - licenseTokenIdB = response.licenseTokenId; - }); - - step("Mint a NFT to WalletC, get a tokenId (tokenIdC)", async function () { - tokenIdC = await mintNFTWithRetry(privateKeyC); - if (tokenIdC === "") { - throw new Error("Unable to mint NFT"); - } - expect(tokenIdC).not.empty; - }); - - step("Wallet C register an IP Asset with tokenIdC, get an ipId (ipIdC)", async function () { - const response = await expect( - registerIpAsset("C", nftContractAddress, tokenIdC, waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.ipId).to.be.a("string").and.not.empty; - - ipIdC = response.ipId; - }); - - step("ipIdC can link to ipIdA and ipIdB as their derivative IP Asset", async function () { - const response = await expect( - registerDerivativeWithLicenseTokens("C", ipIdC, [licenseTokenIdA, licenseTokenIdB], waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - }); - }); - - describe("Register a derivative IP assets with multiple license tokens, the sender is not licensee", async function () { - step("Mint a NFT to Wallet A and get a tokenId (tokenIdA)", async function () { - tokenIdA = await mintNFTWithRetry(privateKeyA); - if (tokenIdA === "") { - throw new Error("Unable to mint NFT"); - }; - expect(tokenIdA).not.empty; - }); - - step("Wallet A register an IP Asset with tokenIdA, get an ipId (ipIdA)", async function () { - const response = await expect( - registerIpAsset("A", nftContractAddress, tokenIdA, waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.ipId).to.be.a("string").and.not.empty; - - ipIdA = response.ipId; - }); - - step("Wallet A attach nonComLicenseTermsId(non-commercial social remixing PIL) to ipIdA", async function () { - const response = await expect( - attachLicenseTerms("A", ipIdA, nonComLicenseTermsId, waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - }); - - step("Wallet A mint a license token with the receiverAddress set as Wallet B, get a licenseId (licenseTokenIdA)", async function () { - const response = await expect( - mintLicenseTokens("A", ipIdA, nonComLicenseTermsId, 2, accountB.address, waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.licenseTokenId).to.be.a("bigint").and.to.be.ok; - - licenseTokenIdA = response.licenseTokenId; - }); - - step("Mint a NFT to WalletB, get a tokenId (tokenIdB)", async function () { - tokenIdB = await mintNFTWithRetry(privateKeyB); - if (tokenIdB === "") { - throw new Error("Unable to mint NFT"); - } - expect(tokenIdB).not.empty; - }); - - step("Wallet B register an IP Asset with tokenIdB, get an ipId (ipIdB)", async function () { - const response = await expect( - registerIpAsset("B", nftContractAddress, tokenIdB, waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.ipId).to.be.a("string").and.not.empty; - - ipIdB = response.ipId; - }); - - step("Wallet B attach nonComLicenseTermsId(non-commercial social remixing PIL) to ipIdB", async function () { - const response = await expect( - attachLicenseTerms("B", ipIdB, nonComLicenseTermsId, waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - }); - - step("Wallet B mint a license token with the receiverAddress set as Wallet C, get a licenseTokenId (licenseTokenIdB)", async function () { - const response = await expect( - mintLicenseTokens("B", ipIdB, nonComLicenseTermsId, 2, accountC.address, waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.licenseTokenId).to.be.a("bigint").and.to.be.ok; - - licenseTokenIdB = response.licenseTokenId; - }); - - step("Mint a NFT to WalletC, get a tokenId (tokenIdC)", async function () { - tokenIdC = await mintNFTWithRetry(privateKeyC); - if (tokenIdC === "") { - throw new Error("Unable to mint NFT"); - } - expect(tokenIdC).not.empty; - }); - - step("Wallet C register an IP Asset with tokenIdC, get an ipId (ipIdC)", async function () { - const response = await expect( - registerIpAsset("C", nftContractAddress, tokenIdC, waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.ipId).to.be.a("string").and.not.empty; - - ipIdC = response.ipId; - }); - - // Wallet C is not the licensee of licenseTokenIdA - step("Wallet C can NOT register derivative IP asset with licenseTokenIdA", async function () { - const response = await expect( - registerDerivativeWithLicenseTokens("C", ipIdC, [licenseTokenIdA, licenseTokenIdB], waitForTransaction) - ).to.be.rejectedWith("Failed to register derivative with license tokens: The contract function \"registerDerivativeWithLicenseTokens\" reverted with the following signature:"); - }); - }); - - describe("Register multiple derivative IP assets with license token, registered amount larger than mint amount of license token", async function () { - step("Mint a NFT to Wallet A and get a tokenId (tokenIdA)", async function () { - tokenIdA = await mintNFTWithRetry(privateKeyA); - if (tokenIdA === "") { - throw new Error("Unable to mint NFT"); - } - expect(tokenIdA).not.empty; - }); - - step("Wallet A register an IP Asset with tokenIdA and get an ipId (ipIdA)", async function () { - const response = await expect( - registerIpAsset("A", nftContractAddress, tokenIdA, waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.ipId).to.be.a("string").and.not.empty; - - ipIdA = response.ipId; - }); - - step("Wallet A attach nonComLicenseTermsId(non-commercial social remixing PIL) to ipIdA", async function () { - const response = await expect( - attachLicenseTerms("A", ipIdA, nonComLicenseTermsId, waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - }); - - step("Wallet A mint a license token with ipIdA and get a licenseTokenId (licenseTokenIdA)", async function () { - const response = await expect( - mintLicenseTokens("A", ipIdA, nonComLicenseTermsId, 1, accountB.address, waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.licenseTokenId).to.be.a("bigint").and.to.be.ok; - - licenseTokenIdA = response.licenseTokenId; - }); - - step("Mint a NFT to WalletB and get a tokenId (tokenIdB)", async function () { - tokenIdB = await mintNFTWithRetry(privateKeyB); - if (tokenIdB === "") { - throw new Error("Unable to mint NFT"); - } - expect(tokenIdB).not.empty; - }); - - step("Wallet B register an IP Asset with tokenIdB and get an ipId (ipIdB)", async function () { - const response = await expect( - registerIpAsset("B", nftContractAddress, tokenIdB, waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.ipId).to.be.a("string").and.not.empty; - - ipIdB = response.ipId; - }); - - step("Wallet B can register a derivative IP asset with licenseTokenIdA", async function () { - const response = await expect( - registerDerivativeWithLicenseTokens("B", ipIdB, [licenseTokenIdA], waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - }); - - step("Mint a NFT to WalletB and get a tokenId (tokenIdB)", async function () { - tokenIdC = await mintNFTWithRetry(privateKeyB); - if (tokenIdC === "") { - throw new Error("Unable to mint NFT"); - } - expect(tokenIdC).not.empty; - }); - - step("Wallet B register a root IP Asset with tokenIdC, get an ipId (ipIdC)", async function () { - const response = await expect( - registerIpAsset("B", nftContractAddress, tokenIdC, waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.ipId).to.be.a("string").and.not.empty; - - ipIdC = response.ipId; - }); - - step("Wallet B can NOT register a derivative IP asset with licenseTokenIdA, no more license token", async function () { - const response = await expect( - registerDerivativeWithLicenseTokens("B", ipIdC, [licenseTokenIdA], waitForTransaction) - ).to.be.rejectedWith("Failed to register derivative with license tokens: The contract function \"ownerOf\" reverted."); - }); - }); - - describe("Register derivative IP asset with an IP that already has license", async function () { - step("Mint a NFT to Wallet A and get a tokenId (tokenIdA)", async function () { - tokenIdA = await mintNFTWithRetry(privateKeyA); - if (tokenIdA === "") { - throw new Error("Unable to mint NFT"); - } - expect(tokenIdA).not.empty; - }); - - step("Wallet A register an IP Asset with tokenIdA and get an ipId (ipIdA)", async function () { - const response = await expect( - registerIpAsset("A", nftContractAddress, tokenIdA, waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.ipId).to.be.a("string").and.not.empty; - - ipIdA = response.ipId; - }); - - step("Wallet A attach nonComLicenseTermsId(non-commercial social remixing PIL) to ipIdA", async function () { - const response = await expect( - attachLicenseTerms("A", ipIdA, nonComLicenseTermsId, waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - }); - - step("Wallet A mint a license token with ipIdA and get a licenseTokenId (licenseTokenIdA)", async function () { - const response = await expect( - mintLicenseTokens("A", ipIdA, nonComLicenseTermsId, 1, accountB.address, waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.licenseTokenId).to.be.a("bigint").and.to.be.ok; - - licenseTokenIdA = response.licenseTokenId; - }); - - step("Mint a NFT to WalletB and get a tokenId (tokenIdB)", async function () { - tokenIdB = await mintNFTWithRetry(privateKeyB); - if (tokenIdB === "") { - throw new Error("Unable to mint NFT"); - } - expect(tokenIdB).not.empty; - }); - - step("Wallet B register an IP Asset with tokenIdB and get an ipId (ipIdB)", async function () { - const response = await expect( - registerIpAsset("B", nftContractAddress, tokenIdB, waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.ipId).to.be.a("string").and.not.empty; - - ipIdB = response.ipId; - }); - - step("Wallet B attach nonComLicenseTermsId(non-commercial social remixing PIL) to ipIdA", async function () { - const response = await expect( - attachLicenseTerms("B", ipIdB, nonComLicenseTermsId, waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - }); - - step("Wallet B mint a license token with ipIdB and get a licenseTokenId (licenseTokenIdB)", async function () { - const response = await expect( - mintLicenseTokens("B", ipIdB, nonComLicenseTermsId, 1, accountA.address, waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.licenseTokenId).to.be.a("bigint").and.to.be.ok; - - licenseTokenIdB = response.licenseTokenId; - }); - - step("Wallet B can NOT register a derivative IP asset with ipIdB, LicenseRegistry__DerivativeIpAlreadyHasLicense(address)", async function () { - const response = await expect( - registerDerivativeWithLicenseTokens("B", ipIdB, [licenseTokenIdA], waitForTransaction) - ).to.be.rejectedWith("Failed to register derivative with license tokens: The contract function \"registerDerivativeWithLicenseTokens\" reverted with the following signature:", "0x650aa4f5"); - }); + step("Wallet B can NOT register a derivative IP asset with ipIdB, LicenseRegistry__DerivativeIpAlreadyHasLicense(address)", async function () { + const response = await expect( + registerDerivativeWithLicenseTokens("B", ipIdB, [licenseTokenIdA], waitForTransaction) + ).to.be.rejectedWith("Failed to register derivative with license tokens: The contract function \"registerDerivativeWithLicenseTokens\" reverted with the following signature:", "0x650aa4f5"); }); }); }); diff --git a/test/e2e/dispute.test.ts b/test/e2e/dispute.test.ts index e04b6f8..89c9978 100644 --- a/test/e2e/dispute.test.ts +++ b/test/e2e/dispute.test.ts @@ -21,7 +21,7 @@ let licenseTokenId1: bigint; let licenseTokenId2: bigint; let licenseTokenId3: bigint; -describe("SDK E2E Test", function () { +describe("SDK E2E Test - Dispute Module", function () { describe("IP Asset is IN_DISPUTE", async function () { before("Register IP assets and raise dispute", async function () { const tokenIdA = await mintNFTWithRetry(privateKeyA); @@ -89,7 +89,7 @@ describe("SDK E2E Test", function () { ).to.not.be.rejected; expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.licenseTokenId).to.be.a("bigint").and.to.be.ok; + expect(response.licenseTokenIds).to.be.a("array").and.to.have.lengthOf(2); }); it("Mint license tokens with commercial use PIL for IN_DISPUTE IP asset", async function () { @@ -98,7 +98,7 @@ describe("SDK E2E Test", function () { ).to.not.be.rejected; expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.licenseTokenId).to.be.a("bigint").and.to.be.ok; + expect(response.licenseTokenIds).to.be.a("array").and.to.have.lengthOf(2); }); it("Mint license tokens with commericial remix PIL for IN_DISPUTE IP asset", async function () { @@ -107,9 +107,9 @@ describe("SDK E2E Test", function () { ).to.not.be.rejected; expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.licenseTokenId).to.be.a("bigint").and.to.be.ok; + expect(response.licenseTokenIds).to.be.a("array").and.to.have.lengthOf(2); - licenseTokenId3 = response.licenseTokenId; + licenseTokenId3 = response.licenseTokenIds[0]; }); }); @@ -163,7 +163,7 @@ describe("SDK E2E Test", function () { step("Claim royalty tokens", async function () { const response = await expect( - royaltyClaimRevenue("A", [snapshotId1], ipIdA, ipIdA, mintingFeeTokenAddress, waitForTransaction) + royaltyClaimRevenue("A", [snapshotId1], ipIdA, mintingFeeTokenAddress, ipIdA, waitForTransaction) ).to.not.be.rejected; expect(response.txHash).to.be.a("string").and.not.empty; @@ -455,27 +455,27 @@ describe("SDK E2E Test", function () { ).to.not.be.rejected; expect(responsemintLicenseTokens1.txHash).to.be.a("string").and.not.empty; - expect(responsemintLicenseTokens1.licenseTokenId).to.be.a("bigint").and.to.be.ok; + expect(responsemintLicenseTokens1.licenseTokenIds).to.be.a("array").and.to.have.lengthOf(2); - licenseTokenId1 = responsemintLicenseTokens1.licenseTokenId; + licenseTokenId1 = responsemintLicenseTokens1.licenseTokenIds[0]; const responsemintLicenseTokens2 = await expect( mintLicenseTokens("B", ipIdB, comUseLicenseTermsId1, 2, accountA.address, true) ).to.not.be.rejected; expect(responsemintLicenseTokens2.txHash).to.be.a("string").and.not.empty; - expect(responsemintLicenseTokens2.licenseTokenId).to.be.a("bigint").and.to.be.ok; + expect(responsemintLicenseTokens2.licenseTokenIds).to.be.a("array").and.to.have.lengthOf(2); - licenseTokenId2 = responsemintLicenseTokens2.licenseTokenId; + licenseTokenId2 = responsemintLicenseTokens2.licenseTokenIds[0]; const responsemintLicenseTokens3 = await expect( mintLicenseTokens("B", ipIdB, comRemixLicenseTermsId2, 2, accountA.address, true) ).to.not.be.rejected; expect(responsemintLicenseTokens3.txHash).to.be.a("string").and.not.empty; - expect(responsemintLicenseTokens3.licenseTokenId).to.be.a("bigint").and.to.be.ok; + expect(responsemintLicenseTokens3.licenseTokenIds).to.be.a("array").and.to.have.lengthOf(2); - licenseTokenId3 = responsemintLicenseTokens3.licenseTokenId; + licenseTokenId3 = responsemintLicenseTokens3.licenseTokenIds[0]; const responseRaiseDispute = await expect( raiseDispute("A", ipIdB, arbitrationPolicyAddress, "test", "PLAGIARISM", waitForTransaction) @@ -686,7 +686,7 @@ describe("SDK E2E Test", function () { // IP asset is disputed, the cliaimable revenue should be 0 step("Claim royalty tokens", async function () { const response = await expect( - royaltyClaimRevenue("B", [snapshotId1], ipIdB, ipIdB, mintingFeeTokenAddress, waitForTransaction) + royaltyClaimRevenue("B", [snapshotId1], ipIdB, mintingFeeTokenAddress, ipIdB, waitForTransaction) ).to.not.be.rejected; expect(response.txHash).to.be.a("string").and.not.empty; @@ -696,3 +696,4 @@ describe("SDK E2E Test", function () { }); }); + diff --git a/test/e2e/licenseTerms.nonComPIL.test.ts b/test/e2e/licenseTerms.nonComPIL.test.ts new file mode 100644 index 0000000..eebdd45 --- /dev/null +++ b/test/e2e/licenseTerms.nonComPIL.test.ts @@ -0,0 +1,199 @@ +import { privateKeyA, nftContractAddress, accountA, accountB, privateKeyB } from '../../config/config'; +import { attachLicenseTerms, mintLicenseTokens, registerDerivativeIp, registerDerivativeWithLicenseTokens, registerIpAndAttachPilTerms, registerIpAsset } from '../../utils/sdkUtils'; +import { getLicenseTokenOwner, mintNFTWithRetry, transferLicenseToken } from '../../utils/utils'; +import { expect } from 'chai' +import chai from 'chai'; +import chaiAsPromised from 'chai-as-promised'; +chai.use(chaiAsPromised); +import '../setup'; +import { Address } from 'viem'; +import { PIL_TYPE } from '@story-protocol/core-sdk'; + +let tokenIdA: string; +let tokenIdB: string; +let ipIdA: Address; +let ipIdB: Address; +let licenseTermsId1: bigint; +let licenseTokenId1: bigint; + +describe('SDK E2E Test', function () { + describe(`Non-Commercial Social Remixing PIL: "transferable":false, "derivativesAllowed":false`, async function () { + licenseTermsId1 = 0n; + + step("Mint a NFT to Wallet A and get a tokenId (tokenIdA)", async function () { + tokenIdA = await mintNFTWithRetry(privateKeyA); + expect(tokenIdA).to.be.a("string").and.not.empty; + }); + + step("Wallet A register an IP Asset with tokenIdA and get an ipId (ipIdA)", async function () { + const response = await expect( + registerIpAsset("A", nftContractAddress, tokenIdA, true) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdA = response.ipId; + }); + + step("Wallet A attach the non-commercial social remixing PIL(licenseTermsId:0 - transferable:false) to ipIdA", async function () { + const response = await expect( + attachLicenseTerms("A", ipIdA, 0n, true) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.success).to.be.a("boolean").and.to.be.true; + }); + + step("Wallet A mint a license token with the receiverAddress set as Wallet B, get a licenseTokenId (licenseTokenId1)", async function () { + const response = await expect( + mintLicenseTokens("A", ipIdA, 0n, 1, accountB.address, true) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.licenseTokenIds).to.be.a("array").and.to.have.lengthOf(1); + + licenseTokenId1 = response.licenseTokenIds[0]; + }); + + step(`"transferable":false, 1 - check the owner of licenseTokenId1`, async function () { + const response = await expect( + getLicenseTokenOwner(Number(licenseTokenId1)) + ).to.not.be.rejected; + + expect(response).to.be.a("string").and.to.be.equal(accountB.address); + }); + + // ipAccountExecute to call licenseToken.transferFrom + // 0xd175f85c - LicenseToken__NotTransferable() + step(`"transferable":false, 2 - WalletB cannot transfer licenseTokenId to WalletA as LicenseToken__NotTransferable()`, async function () { + const errorMessage = `The contract function "transferFrom" reverted with the following signature:`; + const errorCode = `0xd175f85c`; + await expect( + transferLicenseToken(privateKeyB, accountB.address, accountA.address, Number(licenseTokenId1)) + ).to.be.rejectedWith(errorMessage, errorCode); + console.log(`${errorMessage} ${errorCode}`); + }); + + step(`"transferable":false, 3 - check the owner of licenseTokenId1 again`, async function () { + const owner = await expect( + getLicenseTokenOwner(Number(licenseTokenId1)) + ).to.not.be.rejected; + + expect(owner).to.be.a("string").and.to.be.equal(accountB.address); + }); + + step(`"derivativesAllowed":false, cannot register an IP asset as licenseTokenId1's derivative as LicenseTokenNotCompatibleForDerivative`, async function () { + const errorMessage = `Failed to register derivative with license tokens: The contract function "registerDerivativeWithLicenseTokens" reverted.`; + const errorReason = `Error: LicensingModule__LicenseTokenNotCompatibleForDerivative(address childIpId, uint256[] licenseTokenIds)`; + + tokenIdB = await mintNFTWithRetry(privateKeyB); + expect(tokenIdB).to.be.a("string").and.not.empty; + + const responseRegisterIpAsset = await expect( + registerIpAsset("B", nftContractAddress, tokenIdB, true) + ).to.not.be.rejected; + + expect(responseRegisterIpAsset.txHash).to.be.a("string").and.not.empty; + expect(responseRegisterIpAsset.ipId).to.be.a("string").and.not.empty; + + ipIdB = responseRegisterIpAsset.ipId; + + await expect( + registerDerivativeWithLicenseTokens("B", ipIdB, [licenseTokenId1], true) + ).to.be.rejectedWith(errorMessage, errorReason); + console.log(`${errorMessage} ${errorReason}`); + }); + }); + + describe(`Non-Commercial Social Remixing PIL: "transferable":true, "derivativesAllowed":true, "derivativesReciprocal":true`, async function () { + step("Mint a NFT to Wallet A and get a tokenId (tokenIdA)", async function () { + tokenIdA = await mintNFTWithRetry(privateKeyA); + expect(tokenIdA).to.be.a("string").and.not.empty; + }); + + step(`Wallet A register an IP Asset and attach the non-commercial remixing PIL(licenseTermsId:2 - "transferable":true"), get an ipId (ipIdA) and a licenseTermsId (licenseTermsId1)`, async function () { + const responseRegisterIpAndAttachPilTerms = await expect( + registerIpAndAttachPilTerms("A", nftContractAddress, tokenIdA, PIL_TYPE.NON_COMMERCIAL_REMIX, true) + ).to.not.be.rejected; + + expect(responseRegisterIpAndAttachPilTerms.txHash).to.be.a("string").and.not.empty; + expect(responseRegisterIpAndAttachPilTerms.ipId).to.be.a("string").and.not.empty; + expect(responseRegisterIpAndAttachPilTerms.licenseTermsId).to.be.a("bigint").and.to.be.ok; + + ipIdA = responseRegisterIpAndAttachPilTerms.ipId; + licenseTermsId1 = responseRegisterIpAndAttachPilTerms.licenseTermsId; + }); + + step("Wallet A attach another non-commercial social remixing PIL(licenseTermsId:0) to ipIdA", async function () { + const responseAttachLicenseTerms = await expect( + attachLicenseTerms("A", ipIdA, 0n, true) + ).to.not.be.rejected; + + expect(responseAttachLicenseTerms.txHash).to.be.a("string").and.not.empty; + expect(responseAttachLicenseTerms.success).to.be.a("boolean").and.to.be.true; + }); + + step(`Wallet A mint a license token with ipIdA and licenseTermsId1, get a licenseTokenId (licenseTokenId1)`, async function () { + const responseMintLicenseTokens = await expect( + mintLicenseTokens("A", ipIdA, licenseTermsId1, 1, accountA.address, true) + ).to.not.be.rejected; + + expect(responseMintLicenseTokens.txHash).to.be.a("string").and.not.empty; + expect(responseMintLicenseTokens.licenseTokenIds).to.be.a("array").and.to.have.lengthOf(1); + + licenseTokenId1 = responseMintLicenseTokens.licenseTokenIds[0]; + }); + + step(`"derivativesAllowed":true & "derivativesReciprocal":true, only can register a derivative with the same license terms as parent IP`, async function () { + tokenIdB = await mintNFTWithRetry(privateKeyB); + expect(tokenIdB).to.be.a("string").and.not.empty; + + const response = await expect( + registerDerivativeIp("B", nftContractAddress, tokenIdB, [ipIdA], [licenseTermsId1], true) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdB = response.ipId; + }); + + // 0x1ae3058f LicensingModule__DerivativesCannotAddLicenseTerms() + step(`"derivativesReciprocal":true, derivative IP cannot add additional license terms`, async function () { + const errorMessage = `The contract function "attachLicenseTerms" reverted with the following signature:`; + const errorCode = `0x1ae3058f`; + + await expect( + attachLicenseTerms("B", ipIdB, 0n,true) + ).to.be.rejectedWith( + `Failed to attach license terms: The contract function "attachLicenseTerms" reverted with the following signature:`, + `0x1ae3058f` + ); + + console.log(`${errorMessage} ${errorCode}`); + }); + + step(`"transferable":true, 1 - check the owner of licenseTokenId1`, async function () { + const response = await expect(getLicenseTokenOwner(Number(licenseTokenId1)) + ).to.not.be.rejected; + + expect(response).to.be.a("string").and.to.be.equal(accountA.address); + }); + + step(`"transferable":true, 2 - wallet A can transfer the licenseTokenId to Wallet B`, async function () { + const response = await expect( + transferLicenseToken(privateKeyA, accountA.address, accountB.address, Number(licenseTokenId1)) + ).to.not.be.rejected; + + expect(response).to.be.a("string").and.not.empty; + }); + + step(`"transferable":true, 3 - check the owner of licenseTokenId1 again`, async function () { + const response = await expect(getLicenseTokenOwner(Number(licenseTokenId1)) + ).to.not.be.rejected; + + expect(response).to.be.a("string").and.to.be.equal(accountB.address); + }); + }); +}); diff --git a/test/e2e/multiLIcenseTerms.test.ts b/test/e2e/multiLIcenseTerms.test.ts index eecd01f..5dba1cf 100644 --- a/test/e2e/multiLIcenseTerms.test.ts +++ b/test/e2e/multiLIcenseTerms.test.ts @@ -20,268 +20,266 @@ let ipIdC: Hex; const waitForTransaction: boolean = true; -describe('SDK E2E Test', function () { - describe("Register Derivative IP Asset with multiple PILs", function () { - describe("[smoke]Register derivative IP assets, parent IP asset with multiple commercial use PILs", async function () { - step("Mint a NFT to Wallet A and get a tokenId (tokenIdA)", async function () { - tokenIdA = await mintNFTWithRetry(privateKeyA); - expect(tokenIdA).not.empty; - }); - - step("Wallet A register an IP Asset with tokenIdA and get an ipId (ipIdA)", async function () { - const response = await expect( - registerIpAsset("A", nftContractAddress, tokenIdA, waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.ipId).to.be.a("string").and.not.empty; - - ipIdA = response.ipId; - }); - - step("Wallet A attach comUseLicenseTermsId1 (commercial use PIL) to ipIdA", async function () { - const response = await expect( - attachLicenseTerms("A", ipIdA, comUseLicenseTermsId1, waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - }); - - step("Wallet A attach comUseLicenseTermsId2 (commercial use PIL) to ipIdA", async function () { - const response = await expect( - attachLicenseTerms("A", ipIdA, comUseLicenseTermsId2, waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - }); - - step("Mint a NFT to Wallet B and get a tokenId (tokenIdB)", async function () { - tokenIdB = await mintNFTWithRetry(privateKeyB); - expect(tokenIdB).not.empty; - }); - - step("Wallet B register an IP Asset with tokenIdB and get an ipId (ipIdB)", async function () { - const response = await expect( - registerIpAsset("B", nftContractAddress, tokenIdB, waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.ipId).to.be.a("string").and.not.empty; - - ipIdB = response.ipId; - }); - - step("Wallet B can use comUseLicenseTermsId1 to register ipIdB as ipIdA's derivative IP asset", async function () { - const response = await expect( - registerDerivative("B", ipIdB, [ipIdA], [comUseLicenseTermsId1], waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - }); - - step("Mint a NFT to Wallet B and get a tokenId (tokenIdB)", async function () { - tokenIdC = await mintNFTWithRetry(privateKeyB); - expect(tokenIdC).not.empty; - }); - - step("Wallet B register an IP Asset with tokenIdB and get an ipId (ipIdC)", async function () { - const response = await expect( - registerIpAsset("B", nftContractAddress, tokenIdC, waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.ipId).to.be.a("string").and.not.empty; - - ipIdC = response.ipId; - }); - - step("Wallet B can NOT use comRemixLicenseTermsId1 to register ipIdC as ipIdA's derivative IP asset", async function () { - const response = await expect( - registerDerivative("B", ipIdC, [ipIdA], [comRemixLicenseTermsId1], waitForTransaction) - ).to.be.rejectedWith("Failed to register derivative: License terms id " + comRemixLicenseTermsId1 + " must be attached to the parent ipId " + ipIdA + " before registering derivative."); - }); - - step("Wallet B can use comUseLicenseTermsId1 and comUseLicenseTermsId2 to register ipIdC as ipIdA's derivative IP asset", async function () { - const response = await expect( - registerDerivative("B", ipIdC, [ipIdA, ipIdA], [comUseLicenseTermsId1, comUseLicenseTermsId2], waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - }); - }); - - describe("[smoke]Register derivative IP assets, parent IP asset with multiple commercial remix PILs", async function () { - step("Mint a NFT to Wallet A and get a tokenId (tokenIdA)", async function () { - tokenIdA = await mintNFTWithRetry(privateKeyA); - expect(tokenIdA).not.empty; - }); - - step("Wallet A register an IP Asset with tokenIdA and get an ipId (ipIdA)", async function () { - const response = await expect( - registerIpAsset("A", nftContractAddress, tokenIdA, waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.ipId).to.be.a("string").and.not.empty; +describe("SDK E2E Test - Register Derivative IP Asset with multiple PILs", function () { + describe("@smoke Register derivative IP assets, parent IP asset with multiple commercial use PILs", async function () { + step("Mint a NFT to Wallet A and get a tokenId (tokenIdA)", async function () { + tokenIdA = await mintNFTWithRetry(privateKeyA); + expect(tokenIdA).not.empty; + }); + + step("Wallet A register an IP Asset with tokenIdA and get an ipId (ipIdA)", async function () { + const response = await expect( + registerIpAsset("A", nftContractAddress, tokenIdA, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdA = response.ipId; + }); + + step("Wallet A attach comUseLicenseTermsId1 (commercial use PIL) to ipIdA", async function () { + const response = await expect( + attachLicenseTerms("A", ipIdA, comUseLicenseTermsId1, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + + step("Wallet A attach comUseLicenseTermsId2 (commercial use PIL) to ipIdA", async function () { + const response = await expect( + attachLicenseTerms("A", ipIdA, comUseLicenseTermsId2, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + + step("Mint a NFT to Wallet B and get a tokenId (tokenIdB)", async function () { + tokenIdB = await mintNFTWithRetry(privateKeyB); + expect(tokenIdB).not.empty; + }); + + step("Wallet B register an IP Asset with tokenIdB and get an ipId (ipIdB)", async function () { + const response = await expect( + registerIpAsset("B", nftContractAddress, tokenIdB, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdB = response.ipId; + }); + + step("Wallet B can use comUseLicenseTermsId1 to register ipIdB as ipIdA's derivative IP asset", async function () { + const response = await expect( + registerDerivative("B", ipIdB, [ipIdA], [comUseLicenseTermsId1], waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + + step("Mint a NFT to Wallet B and get a tokenId (tokenIdB)", async function () { + tokenIdC = await mintNFTWithRetry(privateKeyB); + expect(tokenIdC).not.empty; + }); + + step("Wallet B register an IP Asset with tokenIdB and get an ipId (ipIdC)", async function () { + const response = await expect( + registerIpAsset("B", nftContractAddress, tokenIdC, waitForTransaction) + ).to.not.be.rejected; - ipIdA = response.ipId; - }); + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; - step("Wallet A attach comRemixLicenseTermsId1(commercial remix PIL) to ipIdA", async function () { - const response = await expect( - attachLicenseTerms("A", ipIdA, comRemixLicenseTermsId1, waitForTransaction) - ).to.not.be.rejected; + ipIdC = response.ipId; + }); - expect(response.txHash).to.be.a("string").and.not.empty; - }); + step("Wallet B can NOT use comRemixLicenseTermsId1 to register ipIdC as ipIdA's derivative IP asset", async function () { + const response = await expect( + registerDerivative("B", ipIdC, [ipIdA], [comRemixLicenseTermsId1], waitForTransaction) + ).to.be.rejectedWith("Failed to register derivative: License terms id " + comRemixLicenseTermsId1 + " must be attached to the parent ipId " + ipIdA + " before registering derivative."); + }); - step("Wallet A attach comRemixLicenseTermsId2(commercial remix PIL) to ipIdA", async function () { - const response = await expect( - attachLicenseTerms("A", ipIdA, comRemixLicenseTermsId2, waitForTransaction) - ).to.not.be.rejected; + step("Wallet B can use comUseLicenseTermsId1 and comUseLicenseTermsId2 to register ipIdC as ipIdA's derivative IP asset", async function () { + const response = await expect( + registerDerivative("B", ipIdC, [ipIdA, ipIdA], [comUseLicenseTermsId1, comUseLicenseTermsId2], waitForTransaction) + ).to.not.be.rejected; - expect(response.txHash).to.be.a("string").and.not.empty; - }); + expect(response.txHash).to.be.a("string").and.not.empty; + }); + }); - step("Mint a NFT to Wallet B and get a tokenId (tokenIdB)", async function () { - tokenIdB = await mintNFTWithRetry(privateKeyB); - expect(tokenIdB).not.empty; - }); - - step("Wallet B register an IP Asset with tokenIdB and get an ipId (ipIdB)", async function () { - const response = await expect( - registerIpAsset("B", nftContractAddress, tokenIdB, waitForTransaction) - ).to.not.be.rejected; + describe("[smoke]Register derivative IP assets, parent IP asset with multiple commercial remix PILs", async function () { + step("Mint a NFT to Wallet A and get a tokenId (tokenIdA)", async function () { + tokenIdA = await mintNFTWithRetry(privateKeyA); + expect(tokenIdA).not.empty; + }); + + step("Wallet A register an IP Asset with tokenIdA and get an ipId (ipIdA)", async function () { + const response = await expect( + registerIpAsset("A", nftContractAddress, tokenIdA, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdA = response.ipId; + }); - expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.ipId).to.be.a("string").and.not.empty; + step("Wallet A attach comRemixLicenseTermsId1(commercial remix PIL) to ipIdA", async function () { + const response = await expect( + attachLicenseTerms("A", ipIdA, comRemixLicenseTermsId1, waitForTransaction) + ).to.not.be.rejected; - ipIdB = response.ipId; - }); + expect(response.txHash).to.be.a("string").and.not.empty; + }); + + step("Wallet A attach comRemixLicenseTermsId2(commercial remix PIL) to ipIdA", async function () { + const response = await expect( + attachLicenseTerms("A", ipIdA, comRemixLicenseTermsId2, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + + step("Mint a NFT to Wallet B and get a tokenId (tokenIdB)", async function () { + tokenIdB = await mintNFTWithRetry(privateKeyB); + expect(tokenIdB).not.empty; + }); + + step("Wallet B register an IP Asset with tokenIdB and get an ipId (ipIdB)", async function () { + const response = await expect( + registerIpAsset("B", nftContractAddress, tokenIdB, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdB = response.ipId; + }); - step("Wallet B can use comRemixLicenseTermsId2 to register ipIdB as ipIdA's derivative IP asset", async function () { - const response = await expect( - registerDerivative("B", ipIdB, [ipIdA], [comRemixLicenseTermsId2], waitForTransaction) - ).to.not.be.rejected; + step("Wallet B can use comRemixLicenseTermsId2 to register ipIdB as ipIdA's derivative IP asset", async function () { + const response = await expect( + registerDerivative("B", ipIdB, [ipIdA], [comRemixLicenseTermsId2], waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + + step("Mint a NFT to Wallet B and get a tokenId (tokenIdB)", async function () { + tokenIdC = await mintNFTWithRetry(privateKeyB); + expect(tokenIdC).not.empty; + }); + + step("Wallet B register an IP Asset with tokenIdB and get an ipId (ipIdC)", async function () { + const response = await expect( + registerIpAsset("B", nftContractAddress, tokenIdC, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdC = response.ipId; + }); + + step("Wallet B can NOT use nonComLicenseTermsId to register ipIdC as ipIdA's derivative IP asset", async function () { + const response = await expect( + registerDerivative("B", ipIdC, [ipIdA], [nonComLicenseTermsId], waitForTransaction) + ).to.be.rejectedWith("Failed to register derivative: License terms id " + nonComLicenseTermsId + " must be attached to the parent ipId " + ipIdA + " before registering derivative."); + }); + + step("Wallet B can use comRemixLicenseTermsId1 and comRemixLicenseTermsId2 to register ipIdC as ipIdA's derivative IP asset", async function () { + const response = await expect( + registerDerivative("B", ipIdC, [ipIdA, ipIdA], [comRemixLicenseTermsId1, comRemixLicenseTermsId2], waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + }); + + describe("Register a derivative IP asset, parent IP asset with multiple non-commericial and commercial PILs", async function () { + step("Mint a NFT to Wallet A and get a tokenId (tokenIdA)", async function () { + tokenIdA = await mintNFTWithRetry(privateKeyA); + expect(tokenIdA).not.empty; + }); + + step("Wallet A register an IP Asset with tokenIdA and get an ipId (ipIdA)", async function () { + const response = await expect( + registerIpAsset("A", nftContractAddress, tokenIdA, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdA = response.ipId; + }); + + step("Wallet A attach comUseLicenseTermsId1(commercial use PIL) to ipIdA", async function () { + const response = await expect( + attachLicenseTerms("A", ipIdA, comUseLicenseTermsId1, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + + step("Wallet A attach comRemixLicenseTermsId1(commercial remix PIL) to ipIdA", async function () { + const response = await expect( + attachLicenseTerms("A", ipIdA, comRemixLicenseTermsId1, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + + step("Wallet A attach nonComLicenseTermsId(non-commercial social remixing PIL) to ipIdA", async function () { + const response = await expect( + attachLicenseTerms("A", ipIdA, nonComLicenseTermsId, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + + step("Mint a NFT to Wallet B and get a tokenId (tokenIdB)", async function () { + tokenIdB = await mintNFTWithRetry(privateKeyB); + expect(tokenIdB).not.empty; + }); + + step("Wallet B register an IP Asset with tokenIdB and get an ipId (ipIdB)", async function () { + const response = await expect( + registerIpAsset("B", nftContractAddress, tokenIdB, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.ipId).to.be.a("string").and.not.empty; + + ipIdB = response.ipId; + }); + + step("Wallet B can NOT use comUseLicenseTermsId1, comRemixLicenseTermsId1 to register ipIdB as ipIdA's derivative IP asset", async function () { + const response = await expect( + registerDerivative("B", ipIdB, [ipIdA, ipIdA], [comUseLicenseTermsId1, comRemixLicenseTermsId1], waitForTransaction) + ).to.be.rejectedWith("Failed to register derivative: The contract function \"registerDerivative\" reverted.", + "Error: LicensingModule__LicenseNotCompatibleForDerivative"); + }); + + step("Wallet B can NOT use comUseLicenseTermsId1, nonComLicenseTermsId to register ipIdB as ipIdA's derivative IP asset", async function () { + const response = await expect( + registerDerivative("B", ipIdB, [ipIdA, ipIdA], [comUseLicenseTermsId1, nonComLicenseTermsId], waitForTransaction) + ).to.be.rejectedWith("Failed to register derivative: The contract function \"registerDerivative\" reverted.", + "Error: LicensingModule__LicenseNotCompatibleForDerivative"); + }); + + step("Wallet B can NOT use comRemixLicenseTermsId1, nonComLicenseTermsId to register ipIdB as ipIdA's derivative IP asset", async function () { + const response = await expect( + registerDerivative("B", ipIdB, [ipIdA, ipIdA], [comRemixLicenseTermsId1, nonComLicenseTermsId], waitForTransaction) + ).to.be.rejectedWith("Failed to register derivative: The contract function \"registerDerivative\" reverted.", + "Error: LicensingModule__LicenseNotCompatibleForDerivative"); + }); - expect(response.txHash).to.be.a("string").and.not.empty; - }); - - step("Mint a NFT to Wallet B and get a tokenId (tokenIdB)", async function () { - tokenIdC = await mintNFTWithRetry(privateKeyB); - expect(tokenIdC).not.empty; - }); - - step("Wallet B register an IP Asset with tokenIdB and get an ipId (ipIdC)", async function () { - const response = await expect( - registerIpAsset("B", nftContractAddress, tokenIdC, waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.ipId).to.be.a("string").and.not.empty; - - ipIdC = response.ipId; - }); - - step("Wallet B can NOT use nonComLicenseTermsId to register ipIdC as ipIdA's derivative IP asset", async function () { - const response = await expect( - registerDerivative("B", ipIdC, [ipIdA], [nonComLicenseTermsId], waitForTransaction) - ).to.be.rejectedWith("Failed to register derivative: License terms id " + nonComLicenseTermsId + " must be attached to the parent ipId " + ipIdA + " before registering derivative."); - }); - - step("Wallet B can use comRemixLicenseTermsId1 and comRemixLicenseTermsId2 to register ipIdC as ipIdA's derivative IP asset", async function () { - const response = await expect( - registerDerivative("B", ipIdC, [ipIdA, ipIdA], [comRemixLicenseTermsId1, comRemixLicenseTermsId2], waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - }); - }); - - describe("Register a derivative IP asset, parent IP asset with multiple non-commericial and commercial PILs", async function () { - step("Mint a NFT to Wallet A and get a tokenId (tokenIdA)", async function () { - tokenIdA = await mintNFTWithRetry(privateKeyA); - expect(tokenIdA).not.empty; - }); - - step("Wallet A register an IP Asset with tokenIdA and get an ipId (ipIdA)", async function () { - const response = await expect( - registerIpAsset("A", nftContractAddress, tokenIdA, waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.ipId).to.be.a("string").and.not.empty; - - ipIdA = response.ipId; - }); - - step("Wallet A attach comUseLicenseTermsId1(commercial use PIL) to ipIdA", async function () { - const response = await expect( - attachLicenseTerms("A", ipIdA, comUseLicenseTermsId1, waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - }); - - step("Wallet A attach comRemixLicenseTermsId1(commercial remix PIL) to ipIdA", async function () { - const response = await expect( - attachLicenseTerms("A", ipIdA, comRemixLicenseTermsId1, waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - }); - - step("Wallet A attach nonComLicenseTermsId(non-commercial social remixing PIL) to ipIdA", async function () { - const response = await expect( - attachLicenseTerms("A", ipIdA, nonComLicenseTermsId, waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - }); - - step("Mint a NFT to Wallet B and get a tokenId (tokenIdB)", async function () { - tokenIdB = await mintNFTWithRetry(privateKeyB); - expect(tokenIdB).not.empty; - }); - - step("Wallet B register an IP Asset with tokenIdB and get an ipId (ipIdB)", async function () { - const response = await expect( - registerIpAsset("B", nftContractAddress, tokenIdB, waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.ipId).to.be.a("string").and.not.empty; - - ipIdB = response.ipId; - }); - - step("Wallet B can NOT use comUseLicenseTermsId1, comRemixLicenseTermsId1 to register ipIdB as ipIdA's derivative IP asset", async function () { - const response = await expect( - registerDerivative("B", ipIdB, [ipIdA, ipIdA], [comUseLicenseTermsId1, comRemixLicenseTermsId1], waitForTransaction) - ).to.be.rejectedWith("Failed to register derivative: The contract function \"registerDerivative\" reverted.", - "Error: LicensingModule__LicenseNotCompatibleForDerivative"); - }); - - step("Wallet B can NOT use comUseLicenseTermsId1, nonComLicenseTermsId to register ipIdB as ipIdA's derivative IP asset", async function () { - const response = await expect( - registerDerivative("B", ipIdB, [ipIdA, ipIdA], [comUseLicenseTermsId1, nonComLicenseTermsId], waitForTransaction) - ).to.be.rejectedWith("Failed to register derivative: The contract function \"registerDerivative\" reverted.", - "Error: LicensingModule__LicenseNotCompatibleForDerivative"); - }); - - step("Wallet B can NOT use comRemixLicenseTermsId1, nonComLicenseTermsId to register ipIdB as ipIdA's derivative IP asset", async function () { - const response = await expect( - registerDerivative("B", ipIdB, [ipIdA, ipIdA], [comRemixLicenseTermsId1, nonComLicenseTermsId], waitForTransaction) - ).to.be.rejectedWith("Failed to register derivative: The contract function \"registerDerivative\" reverted.", - "Error: LicensingModule__LicenseNotCompatibleForDerivative"); - }); - - step("Wallet B can NOT use comUseLicenseTermsId1, comRemixLicenseTermsId1, nonComLicenseTermsId to register ipIdB as ipIdA's derivative IP asset", async function () { - const response = await expect( - registerDerivative("B", ipIdB, [ipIdA, ipIdA, ipIdA], [comUseLicenseTermsId1, comRemixLicenseTermsId1, nonComLicenseTermsId], waitForTransaction) - ).to.be.rejectedWith("Failed to register derivative: The contract function \"registerDerivative\" reverted.", - "Error: LicensingModule__LicenseNotCompatibleForDerivative"); - }); + step("Wallet B can NOT use comUseLicenseTermsId1, comRemixLicenseTermsId1, nonComLicenseTermsId to register ipIdB as ipIdA's derivative IP asset", async function () { + const response = await expect( + registerDerivative("B", ipIdB, [ipIdA, ipIdA, ipIdA], [comUseLicenseTermsId1, comRemixLicenseTermsId1, nonComLicenseTermsId], waitForTransaction) + ).to.be.rejectedWith("Failed to register derivative: The contract function \"registerDerivative\" reverted.", + "Error: LicensingModule__LicenseNotCompatibleForDerivative"); }); }); }); \ No newline at end of file diff --git a/test/e2e/royalty.comRemixPIL.test.ts b/test/e2e/royalty.comRemixPIL.test.ts new file mode 100644 index 0000000..b516020 --- /dev/null +++ b/test/e2e/royalty.comRemixPIL.test.ts @@ -0,0 +1,535 @@ +import { privateKeyA, privateKeyB, privateKeyC, mintingFeeTokenAddress, accountC, clientC, accountB, chainId, clientA, accountA } from '../../config/config' +import { getTotalRTSupply} from '../../utils/utils' +import { getRoyaltyVaultAddress, payRoyaltyOnBehalf, registerCommercialRemixPIL } from '../../utils/sdkUtils' +import { mintNFTCreateRootIPandAttachPIL, mintNFTAndRegisterDerivative, checkRoyaltyTokensCollected, getSnapshotId,checkClaimableRevenue, claimRevenueByIPA, claimRevenueByEOA, transferTokenToEOA, transferTokenToEOAWithSig } from '../testUtils' + +import { expect } from 'chai' +import chai from 'chai'; +import chaiAsPromised from 'chai-as-promised'; +chai.use(chaiAsPromised); +import { Address, Hex } from 'viem'; +import '../setup'; +import { AccessPermission, getPermissionSignature } from '@story-protocol/core-sdk' +import { coreMetadataModuleAbi } from '@story-protocol/core-sdk/dist/declarations/src/abi/generated' + +let ipIdA: Address; +let ipIdB: Address; +let ipIdC: Address; +let ipIdD: Address; +let snapshotId1_ipIdA: bigint; +let snapshotId1_ipIdB: bigint; +let snapshotId1_ipIdC: bigint; +let snapshotId1_ipIdD: bigint; +let TOTAL_RT_SUPPLY: number; + +describe("SDK E2E Test - Royalty", function () { + this.beforeAll("Get total RT supply", async function (){ + TOTAL_RT_SUPPLY = await getTotalRTSupply(); + console.log("TOTAL_RT_SUPPLY: " + TOTAL_RT_SUPPLY); + }); + + describe("Commercial Remix PIL - Claim Minting Fee by IPA account", function () { + const mintingFee: string = "100"; + const commercialRevShare: number = 0.5; + before("Register parent and derivative IP Assets", async function () { + // Register commercial use PIL + const licenseTermsId = Number((await registerCommercialRemixPIL("A", mintingFee, commercialRevShare, mintingFeeTokenAddress, true)).licenseTermsId); + + // root IP: ipIdA + ipIdA = await mintNFTCreateRootIPandAttachPIL("A", privateKeyA, licenseTermsId); + // ipIdB is ipIdA's derivative IP + ipIdB = await mintNFTAndRegisterDerivative("B", privateKeyB, [ipIdA], [licenseTermsId]); + }); + + step("ipIdA collect royalty tokens from ipIdB", async function () { + await checkRoyaltyTokensCollected("A", ipIdA, ipIdB, BigInt(TOTAL_RT_SUPPLY * (commercialRevShare/100))); + }); + + step("Capture snapshotId for ipIdB", async function () { + snapshotId1_ipIdB = await getSnapshotId("B", ipIdB); + }); + + step("ipIdA check claimable revenue from vaultIpIdB", async function () { + await checkClaimableRevenue("A", ipIdB, ipIdA, snapshotId1_ipIdB, 0n); + }); + + step("ipIdA claim revenue from vaultIpIdB", async function () { + await claimRevenueByIPA("A", [snapshotId1_ipIdB], ipIdB, ipIdA, 0n); + }); + + step("ipIdB check claimable revenue from vaultIpIdB", async function () { + await checkClaimableRevenue("B", ipIdB, ipIdB, snapshotId1_ipIdB, 0n); + }); + + step("ipIdB claim revenue from vaultIpIdB", async function () { + await claimRevenueByIPA("B", [snapshotId1_ipIdB], ipIdB, ipIdB, 0n); + }); + + step("Capture snapshotId for ipIdA", async function () { + snapshotId1_ipIdA = await getSnapshotId("A", ipIdA); + }); + + step("ipIdA check claimable revenue from vaultIpIdA", async function () { + await checkClaimableRevenue("A", ipIdA, ipIdA, snapshotId1_ipIdA, BigInt(mintingFee)); + }); + + step("idIdA claim revenue from vaultIpIdA (minting fee)", async function () { + await claimRevenueByIPA("A", [snapshotId1_ipIdA], ipIdA, ipIdA, BigInt(mintingFee)); + }); + + step("Check claimable revenue again", async function () { + await checkClaimableRevenue("A", ipIdA, ipIdA, snapshotId1_ipIdA, 0n); + }); + }); + + describe('Commercial Remix PIL - Claim Minting Fee and Revenue by IPA account', async function () { + const mintingFee = "600"; + const payAmount = 100; + const commercialRevShare = 10; + before("Register parent and derivative IP Assets", async function () { + // create license terms + const licenseTermsId = Number((await registerCommercialRemixPIL("A", mintingFee, commercialRevShare, mintingFeeTokenAddress, true)).licenseTermsId); + + // root IP: ipIdA + ipIdA = await mintNFTCreateRootIPandAttachPIL("A", privateKeyA, licenseTermsId); + // ipIdB is ipIdA's derivative IP + ipIdB = await mintNFTAndRegisterDerivative("B", privateKeyB, [ipIdA], [licenseTermsId]); + // ipIdC is ipIdB's derivative IP + ipIdC = await mintNFTAndRegisterDerivative("C", privateKeyC, [ipIdB], [licenseTermsId]); + // ipIdD is ipIdC's derivative IP + ipIdD = await mintNFTAndRegisterDerivative("C", privateKeyC, [ipIdC], [licenseTermsId]); + }); + + step("ipIdA collect royalty tokens from ipIdB's vault account", async function () { + const expectedRoyaltyTokensCollected = BigInt(commercialRevShare/100 * TOTAL_RT_SUPPLY); + await checkRoyaltyTokensCollected("A", ipIdA, ipIdB, expectedRoyaltyTokensCollected); + }); + + step("ipIdA collect royalty tokens from ipIdC's vault account", async function () { + const expectedRoyaltyTokensCollected = BigInt(commercialRevShare/100 * TOTAL_RT_SUPPLY); + await checkRoyaltyTokensCollected("A", ipIdA, ipIdC, expectedRoyaltyTokensCollected); + }); + + step("ipIdA collect royalty tokens from ipIdD's vault account", async function () { + const expectedRoyaltyTokensCollected = BigInt(commercialRevShare/100 * TOTAL_RT_SUPPLY); + await checkRoyaltyTokensCollected("A", ipIdA, ipIdD, expectedRoyaltyTokensCollected); + }); + + step("ipIdB collect royalty tokens from ipIdC's vault account", async function () { + const expectedRoyaltyTokensCollected = BigInt(commercialRevShare/100 * TOTAL_RT_SUPPLY); + await checkRoyaltyTokensCollected("B", ipIdB, ipIdC, expectedRoyaltyTokensCollected); + }); + + step("ipIdB collect royalty tokens from ipIdD's vault account", async function () { + const expectedRoyaltyTokensCollected = BigInt(commercialRevShare/100 * TOTAL_RT_SUPPLY); + await checkRoyaltyTokensCollected("B", ipIdB, ipIdD, expectedRoyaltyTokensCollected); + }); + + step("ipIdC collect royalty tokens from ipIdD's vault account", async function () { + const expectedRoyaltyTokensCollected = BigInt(commercialRevShare/100 * TOTAL_RT_SUPPLY); + await checkRoyaltyTokensCollected("C", ipIdC, ipIdD, expectedRoyaltyTokensCollected); + }); + + step("ipIdD pay royalty on behalf to ipIdC", async function () { + const response = await expect( + payRoyaltyOnBehalf("C", ipIdC, ipIdD, mintingFeeTokenAddress, payAmount, true) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + + step("Capture snapshotId for ipIdD", async function () { + snapshotId1_ipIdD = await getSnapshotId("C", ipIdD); + }); + + step("Capture snapshotId for ipIdC", async function () { + snapshotId1_ipIdC = await getSnapshotId("C", ipIdC); + }); + + step("Capture snapshotId for ipIdB", async function () { + snapshotId1_ipIdB = await getSnapshotId("B", ipIdB); + }); + + step("Capture snapshotId for ipIdA", async function () { + snapshotId1_ipIdA = await getSnapshotId("A", ipIdA); + }); + + step("Check claimable revenue A from D", async function () { + await checkClaimableRevenue("A", ipIdD, ipIdA, snapshotId1_ipIdD, 0n); + }); + + step("Check claimable revenue B from D", async function () { + await checkClaimableRevenue("B", ipIdD, ipIdB, snapshotId1_ipIdD, 0n); + }); + + step("Check claimable revenue C from D", async function () { + await checkClaimableRevenue("C", ipIdD, ipIdC, snapshotId1_ipIdD, 0n); + }); + + step("Check claimable revenue D from D", async function () { + await checkClaimableRevenue("C", ipIdD, ipIdD, snapshotId1_ipIdD, 0n); + }); + + step("Check claimable revenue A from C", async function () { + const expectedClaimableRevenue = BigInt((Number(mintingFee) + payAmount) * commercialRevShare / 100); + await checkClaimableRevenue("A", ipIdC, ipIdA, snapshotId1_ipIdC, expectedClaimableRevenue); + }); + + step("Check claimable revenue B from C", async function () { + const expectedClaimableRevenue = BigInt((Number(mintingFee) + payAmount) * commercialRevShare / 100); + await checkClaimableRevenue("B", ipIdC, ipIdB, snapshotId1_ipIdC, expectedClaimableRevenue); + }); + + step("Check claimable revenue C from C", async function () { + const expectedClaimableRevenue = BigInt((Number(mintingFee) + payAmount) * ((100 - 2 * commercialRevShare) / 100)); + await checkClaimableRevenue("C", ipIdC, ipIdC, snapshotId1_ipIdC, expectedClaimableRevenue); + }); + + step("Check claimable revenue A from B", async function () { + const expectedClaimableRevenue = BigInt((Number(mintingFee)) * commercialRevShare / 100); + await checkClaimableRevenue("A", ipIdB, ipIdA, snapshotId1_ipIdB, expectedClaimableRevenue); + }); + + step("Check claimable revenue B from B", async function () { + const expectedClaimableRevenue = BigInt((Number(mintingFee)) * ((100 - commercialRevShare) / 100)); + await checkClaimableRevenue("B", ipIdB, ipIdB, snapshotId1_ipIdB, expectedClaimableRevenue); + }); + + step("Check claimable revenue A from A", async function () { + const expectedClaimableRevenue = BigInt(mintingFee); + await checkClaimableRevenue("A", ipIdA, ipIdA, snapshotId1_ipIdA, expectedClaimableRevenue); + }); + + step("Claim revenue A from D", async function () { + await claimRevenueByIPA("A", [snapshotId1_ipIdD], ipIdD, ipIdA, 0n); + }); + + step("Claim revenue B from D", async function () { + await claimRevenueByIPA("B", [snapshotId1_ipIdD], ipIdD, ipIdB, 0n); + }); + + step("Claim revenue C from D", async function () { + await claimRevenueByIPA("C", [snapshotId1_ipIdD], ipIdD, ipIdC, 0n); + }); + + step("Claim revenue D from D", async function () { + await claimRevenueByIPA("C", [snapshotId1_ipIdD], ipIdD, ipIdD, 0n); + }); + + step("Claim revenue A from C", async function () { + const expectedClaimableToken = BigInt((Number(mintingFee) + payAmount) * commercialRevShare / 100); + await claimRevenueByIPA("A", [snapshotId1_ipIdC], ipIdC, ipIdA, expectedClaimableToken); + }); + + step("Claim revenue B from C", async function () { + const expectedClaimableToken = BigInt((Number(mintingFee) + payAmount) * commercialRevShare / 100); + await claimRevenueByIPA("B", [snapshotId1_ipIdC], ipIdC, ipIdB, expectedClaimableToken); + }); + + step("Claim revenue C from C", async function () { + const expectedClaimableToken = BigInt((Number(mintingFee) + payAmount) * ((100 - commercialRevShare - commercialRevShare) / 100)); + await claimRevenueByIPA("C", [snapshotId1_ipIdC], ipIdC, ipIdC, expectedClaimableToken); + }); + + step("Claim revenue A from B", async function () { + const expectedClaimableToken = BigInt((Number(mintingFee)) * commercialRevShare / 100); + await claimRevenueByIPA("A", [snapshotId1_ipIdB], ipIdB, ipIdA, expectedClaimableToken); + }); + + step("Claim revenue B from B", async function () { + const expectedClaimableToken = BigInt((Number(mintingFee)) * ((100 - commercialRevShare) / 100)); + await claimRevenueByIPA("B", [snapshotId1_ipIdB], ipIdB, ipIdB, expectedClaimableToken); + }); + + step("Claim revenue A from A", async function () { + const expectedClaimableToken = BigInt(mintingFee); + await claimRevenueByIPA("A", [snapshotId1_ipIdA], ipIdA, ipIdA, expectedClaimableToken); + }); + }); + + describe("Commercial Remix PIL - Claim Minting Fee and Revenue by EOA", function () { + const mintingFee = "1000"; + const payAmount = 6000; + const commercialRevShare = 20; + before("Register parent and derivative IP Assets", async function () { + // create license terms + const licenseTermsId = Number((await registerCommercialRemixPIL("A", mintingFee, commercialRevShare, mintingFeeTokenAddress, true)).licenseTermsId); + + // root IP: ipIdA + ipIdA = await mintNFTCreateRootIPandAttachPIL("A", privateKeyA, licenseTermsId); + // ipIdB is ipIdA's derivative IP + ipIdB = await mintNFTAndRegisterDerivative("B", privateKeyB, [ipIdA], [licenseTermsId]); + // ipIdC is ipIdB's derivative IP + ipIdC = await mintNFTAndRegisterDerivative("C", privateKeyC, [ipIdB], [licenseTermsId]); + // ipIdD is ipIdC's derivative IP + ipIdD = await mintNFTAndRegisterDerivative("C", privateKeyC, [ipIdC], [licenseTermsId]); + }); + + step("ipIdA collect royalty tokens from ipIdB's vault account", async function () { + await checkRoyaltyTokensCollected("A", ipIdA, ipIdB, BigInt(commercialRevShare/100 * TOTAL_RT_SUPPLY)); + }); + + step("ipIdA collect royalty tokens from ipIdC's vault account", async function () { + await checkRoyaltyTokensCollected("A", ipIdA, ipIdC, BigInt(commercialRevShare/100 * TOTAL_RT_SUPPLY)); + }); + + step("ipIdA collect royalty tokens from ipIdD's vault account", async function () { + await checkRoyaltyTokensCollected("A", ipIdA, ipIdD, BigInt(commercialRevShare/100 * TOTAL_RT_SUPPLY)); + }); + + step("ipIdB collect royalty tokens from ipIdC's vault account", async function () { + await checkRoyaltyTokensCollected("B", ipIdB, ipIdC, BigInt(commercialRevShare/100 * TOTAL_RT_SUPPLY)); + }); + + step("ipIdB collect royalty tokens from ipIdD's vault account", async function () { + await checkRoyaltyTokensCollected("B", ipIdB, ipIdD, BigInt(commercialRevShare/100 * TOTAL_RT_SUPPLY)); + }); + + step("ipIdC collect royalty tokens from ipIdD's vault account", async function () { + await checkRoyaltyTokensCollected("C", ipIdC, ipIdD, BigInt(commercialRevShare/100 * TOTAL_RT_SUPPLY)); + }); + + step("Transfer token to EOA - ipIdC", async function () { + await transferTokenToEOA("C", ipIdC, accountC.address, BigInt(60 * 10 ** 6)); + }); + + step("ipIdD pay royalty on behalf to ipIdC", async function () { + const response = await expect( + payRoyaltyOnBehalf("C", ipIdC, ipIdD, mintingFeeTokenAddress, payAmount, true) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + + step("Capture snapshotId for ipIdC", async function () { + snapshotId1_ipIdC = await getSnapshotId("C", ipIdC); + }); + + step("Check claimable revenue A from C", async function () { + const expectedClaimableRevenue = BigInt((Number(mintingFee) + payAmount) * commercialRevShare / 100); + await checkClaimableRevenue("A", ipIdC, ipIdA, snapshotId1_ipIdC, expectedClaimableRevenue); + }); + + step("Check claimable revenue B from C", async function () { + const expectedClaimableRevenue = BigInt((Number(mintingFee) + payAmount) * commercialRevShare / 100); + await checkClaimableRevenue("B", ipIdC, ipIdB, snapshotId1_ipIdC, expectedClaimableRevenue); + }); + + step("Check claimable revenue C from C", async function () { + await checkClaimableRevenue("C", ipIdC, ipIdC, snapshotId1_ipIdC, 0n); + }); + + step("Claim revenue by EOA A from C", async function () { + await claimRevenueByEOA("A", [snapshotId1_ipIdC], ipIdC, 0n); + }); + + step("Claim revenue by EOA B from C", async function () { + await claimRevenueByEOA("B", [snapshotId1_ipIdC], ipIdC, 0n); + }); + + step("Claim revenue by EOA C from C", async function () { + const expectedClaimableToken = BigInt((Number(mintingFee) + payAmount) * ((100 - 2 * commercialRevShare) / 100)); + await claimRevenueByEOA("C", [snapshotId1_ipIdC], ipIdC, expectedClaimableToken); + }); + }); + + describe("Commercial Remix PIL - Claim Minting Fee and Revenue by EOA1", function () { + const mintingFee = 600; + const payAmount = 2000; + const commercialRevShare = 10; + before("Register parent and derivative IP Assets", async function () { + // create license terms + const licenseTermsId = Number((await registerCommercialRemixPIL("A", mintingFee, commercialRevShare, mintingFeeTokenAddress, true)).licenseTermsId); + + // root IP: ipIdA + ipIdA = await mintNFTCreateRootIPandAttachPIL("A", privateKeyA, licenseTermsId); + // ipIdB is ipIdA's derivative IP + ipIdB = await mintNFTAndRegisterDerivative("B", privateKeyB, [ipIdA], [licenseTermsId]); + // ipIdC is ipIdB's derivative IP + ipIdC = await mintNFTAndRegisterDerivative("C", privateKeyC, [ipIdB], [licenseTermsId]); + // ipIdD is ipIdC's derivative IP + ipIdD = await mintNFTAndRegisterDerivative("C", privateKeyC, [ipIdC], [licenseTermsId]); + }); + + step("ipIdA collect royalty tokens from ipIdB's vault account", async function () { + await checkRoyaltyTokensCollected("A", ipIdA, ipIdB, BigInt(commercialRevShare/100 * TOTAL_RT_SUPPLY)); + }); + + step("ipIdA collect royalty tokens from ipIdC's vault account", async function () { + await checkRoyaltyTokensCollected("A", ipIdA, ipIdC, BigInt(commercialRevShare/100 * TOTAL_RT_SUPPLY)); + }); + + step("ipIdA collect royalty tokens from ipIdD's vault account", async function () { + await checkRoyaltyTokensCollected("A", ipIdA, ipIdD, BigInt(commercialRevShare/100 * TOTAL_RT_SUPPLY)); + }); + + step("ipIdB collect royalty tokens from ipIdC's vault account", async function () { + await checkRoyaltyTokensCollected("B", ipIdB, ipIdC, BigInt(commercialRevShare/100 * TOTAL_RT_SUPPLY)); + }); + + step("ipIdB collect royalty tokens from ipIdD's vault account", async function () { + await checkRoyaltyTokensCollected("B", ipIdB, ipIdD, BigInt(commercialRevShare/100 * TOTAL_RT_SUPPLY)); + }); + + step("ipIdC collect royalty tokens from ipIdD's vault account", async function () { + await checkRoyaltyTokensCollected("C", ipIdC, ipIdD, BigInt(commercialRevShare/100 * TOTAL_RT_SUPPLY)); + }); + + step("Transfer token to EOA - ipIdC to ipIdA", async function () { + console.log((100 - 2 * commercialRevShare)/100 * TOTAL_RT_SUPPLY / 4) + await transferTokenToEOA("C", ipIdC, accountA.address, BigInt((100 - 2 * commercialRevShare)/100 * TOTAL_RT_SUPPLY / 4)); + }); + + step("Transfer token to EOA - ipIdC to ipIdB", async function () { + console.log((100 - 2 * commercialRevShare)/100 * TOTAL_RT_SUPPLY / 4) + await transferTokenToEOA("C", ipIdC, accountB.address, BigInt((100 - 2 * commercialRevShare)/100 * TOTAL_RT_SUPPLY / 4)); + }); + + step("Transfer token to EOA - ipIdC to ipIdC", async function () { + console.log((100 - 2 * commercialRevShare)/100 * TOTAL_RT_SUPPLY / 2) + await transferTokenToEOA("C", ipIdC, accountC.address, BigInt((100 - 2 * commercialRevShare)/100 * TOTAL_RT_SUPPLY / 4)); + }); + + step("ipIdD pay royalty on behalf to ipIdC", async function () { + const response = await expect( + payRoyaltyOnBehalf("C", ipIdC, ipIdD, mintingFeeTokenAddress, payAmount, true) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + + step("Capture snapshotId for ipIdC", async function () { + snapshotId1_ipIdC = await getSnapshotId("C", ipIdC); + }); + + step("Check claimable revenue A from C", async function () { + const expectedClaimableRevenue = BigInt((mintingFee + payAmount) * commercialRevShare / 100); + await checkClaimableRevenue("A", ipIdC, ipIdA, snapshotId1_ipIdC, expectedClaimableRevenue); + }); + + step("Check claimable revenue B from C", async function () { + const expectedClaimableRevenue = BigInt((mintingFee + payAmount) * commercialRevShare / 100); + await checkClaimableRevenue("B", ipIdC, ipIdB, snapshotId1_ipIdC, expectedClaimableRevenue); + }); + + step("Check claimable revenue C from C", async function () { + const expectedClaimableRevenue = BigInt((mintingFee + payAmount) * (100 - 2 * commercialRevShare)/100 /4); + await checkClaimableRevenue("C", ipIdC, ipIdC, snapshotId1_ipIdC, expectedClaimableRevenue); + }); + + step("Claim revenue by EOA A from C", async function () { + const expectedClaimableToken = BigInt((mintingFee + payAmount) * ((100 - 2 * commercialRevShare) / 100) / 4); + await claimRevenueByEOA("A", [snapshotId1_ipIdC], ipIdC, expectedClaimableToken); + }); + + step("Claim revenue by EOA B from C", async function () { + const expectedClaimableToken = BigInt((mintingFee + payAmount) * ((100 - 2 * commercialRevShare) / 100) / 4); + await claimRevenueByEOA("B", [snapshotId1_ipIdC], ipIdC, expectedClaimableToken); + }); + + step("Claim revenue by EOA C from C", async function () { + const expectedClaimableToken = BigInt((mintingFee + payAmount) * ((100 - 2 * commercialRevShare) / 100) / 4); + await claimRevenueByEOA("C", [snapshotId1_ipIdC], ipIdC, expectedClaimableToken); + }); + }); + + describe("Commercial Remix PIL - Claim Minting Fee and Revenue by EOA2", function () { + const mintingFee = 600; + const payAmount = 2000; + const commercialRevShare = 10; + before("Register parent and derivative IP Assets", async function () { + // create license terms + const licenseTermsId = Number((await registerCommercialRemixPIL("A", mintingFee, commercialRevShare, mintingFeeTokenAddress, true)).licenseTermsId); + + // root IP: ipIdA + ipIdA = await mintNFTCreateRootIPandAttachPIL("A", privateKeyA, licenseTermsId); + // ipIdB is ipIdA's derivative IP + ipIdB = await mintNFTAndRegisterDerivative("B", privateKeyB, [ipIdA], [licenseTermsId]); + // ipIdC is ipIdB's derivative IP + ipIdC = await mintNFTAndRegisterDerivative("C", privateKeyC, [ipIdB], [licenseTermsId]); + // ipIdD is ipIdC's derivative IP + ipIdD = await mintNFTAndRegisterDerivative("C", privateKeyC, [ipIdC], [licenseTermsId]); + }); + + step("Transfer token to EOA - ipIdC to ipIdA", async function () { + console.log((100 - 2 * commercialRevShare)/100 * TOTAL_RT_SUPPLY / 4) + await transferTokenToEOA("C", ipIdC, accountA.address, BigInt((100 - 2 * commercialRevShare)/100 * TOTAL_RT_SUPPLY / 4)); + }); + + step("Transfer token to EOA - ipIdC to ipIdB", async function () { + console.log((100 - 2 * commercialRevShare)/100 * TOTAL_RT_SUPPLY / 4) + await transferTokenToEOA("C", ipIdC, accountB.address, BigInt((100 - 2 * commercialRevShare)/100 * TOTAL_RT_SUPPLY / 4)); + }); + + step("Transfer token to EOA - ipIdC to ipIdC", async function () { + console.log((100 - 2 * commercialRevShare)/100 * TOTAL_RT_SUPPLY / 2) + await transferTokenToEOA("C", ipIdC, accountC.address, BigInt((100 - 2 * commercialRevShare)/100 * TOTAL_RT_SUPPLY / 4)); + }); + + step("ipIdD pay royalty on behalf to ipIdC", async function () { + const response = await expect( + payRoyaltyOnBehalf("C", ipIdC, ipIdD, mintingFeeTokenAddress, payAmount, true) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + + step("ipIdA collect royalty tokens from ipIdB's vault account", async function () { + await checkRoyaltyTokensCollected("A", ipIdA, ipIdB, BigInt(commercialRevShare/100 * TOTAL_RT_SUPPLY)); + }); + + step("ipIdA collect royalty tokens from ipIdC's vault account", async function () { + await checkRoyaltyTokensCollected("A", ipIdA, ipIdC, BigInt(commercialRevShare/100 * TOTAL_RT_SUPPLY)); + }); + + step("ipIdA collect royalty tokens from ipIdD's vault account", async function () { + await checkRoyaltyTokensCollected("A", ipIdA, ipIdD, BigInt(commercialRevShare/100 * TOTAL_RT_SUPPLY)); + }); + + step("ipIdB collect royalty tokens from ipIdC's vault account", async function () { + await checkRoyaltyTokensCollected("B", ipIdB, ipIdC, BigInt(commercialRevShare/100 * TOTAL_RT_SUPPLY)); + }); + + step("ipIdB collect royalty tokens from ipIdD's vault account", async function () { + await checkRoyaltyTokensCollected("B", ipIdB, ipIdD, BigInt(commercialRevShare/100 * TOTAL_RT_SUPPLY)); + }); + + step("ipIdC collect royalty tokens from ipIdD's vault account", async function () { + await checkRoyaltyTokensCollected("C", ipIdC, ipIdD, BigInt(commercialRevShare/100 * TOTAL_RT_SUPPLY)); + }); + + step("Capture snapshotId for ipIdC", async function () { + snapshotId1_ipIdC = await getSnapshotId("C", ipIdC); + }); + + step("Check claimable revenue A from C", async function () { + const expectedClaimableRevenue = BigInt((mintingFee + payAmount) * commercialRevShare / 100); + await checkClaimableRevenue("A", ipIdC, ipIdA, snapshotId1_ipIdC, expectedClaimableRevenue); + }); + + step("Check claimable revenue B from C", async function () { + const expectedClaimableRevenue = BigInt((mintingFee + payAmount) * commercialRevShare / 100); + await checkClaimableRevenue("B", ipIdC, ipIdB, snapshotId1_ipIdC, expectedClaimableRevenue); + }); + + step("Check claimable revenue C from C", async function () { + const expectedClaimableRevenue = BigInt((mintingFee + payAmount) * (100 - 2 * commercialRevShare)/100 /4); + await checkClaimableRevenue("C", ipIdC, ipIdC, snapshotId1_ipIdC, expectedClaimableRevenue); + }); + + step("Claim revenue by EOA A from C", async function () { + const expectedClaimableToken = BigInt((mintingFee + payAmount) * ((100 - 2 * commercialRevShare) / 100) / 4); + await claimRevenueByEOA("A", [snapshotId1_ipIdC], ipIdC, expectedClaimableToken); + }); + + step("Claim revenue by EOA B from C", async function () { + const expectedClaimableToken = BigInt((mintingFee + payAmount) * ((100 - 2 * commercialRevShare) / 100) / 4); + await claimRevenueByEOA("B", [snapshotId1_ipIdC], ipIdC, expectedClaimableToken); + }); + + step("Claim revenue by EOA C from C", async function () { + const expectedClaimableToken = BigInt((mintingFee + payAmount) * ((100 - 2 * commercialRevShare) / 100) / 4); + await claimRevenueByEOA("C", [snapshotId1_ipIdC], ipIdC, expectedClaimableToken); + }); + }); +}); diff --git a/test/e2e/royalty.comUsePIL.test.ts b/test/e2e/royalty.comUsePIL.test.ts new file mode 100644 index 0000000..fc132e4 --- /dev/null +++ b/test/e2e/royalty.comUsePIL.test.ts @@ -0,0 +1,206 @@ +import { privateKeyA, privateKeyB, privateKeyC, mintingFeeTokenAddress, accountB, accountA } from '../../config/config' +import { getTotalRTSupply} from '../../utils/utils' +import { payRoyaltyOnBehalf, registerCommercialUsePIL } from '../../utils/sdkUtils' +import { expect } from 'chai' +import { mintNFTCreateRootIPandAttachPIL, mintNFTAndRegisterDerivative, checkRoyaltyTokensCollected, getSnapshotId,checkClaimableRevenue, claimRevenueByIPA, claimRevenueByEOA, transferTokenToEOA } from '../testUtils' + +import chai from 'chai'; +import chaiAsPromised from 'chai-as-promised'; +chai.use(chaiAsPromised); +import '../setup'; +import { Address } from 'viem'; +import { comUseLicenseTermsId1, mintingFee1 } from '../setup' + +let ipIdA: Address; +let ipIdB: Address; +let ipIdC: Address; +let ipIdD: Address; +let snapshotId1_ipIdA: bigint; +let snapshotId1_ipIdB: bigint; +let TOTAL_RT_SUPPLY: number; + +describe("SDK E2E Test - Royalty", function () { + this.beforeAll("Get total RT supply", async function (){ + TOTAL_RT_SUPPLY = await getTotalRTSupply(); + console.log("TOTAL_RT_SUPPLY: " + TOTAL_RT_SUPPLY); + }); + + describe("Commercial Use PIL - Claim Minting Fee by IPA account", function () { + before("Register parent and derivative IP assets", async function () { + // root IP: ipIdA + ipIdA = await mintNFTCreateRootIPandAttachPIL("A", privateKeyA, comUseLicenseTermsId1); + // ipIdB is ipIdA's derivative IP + ipIdB = await mintNFTAndRegisterDerivative("B", privateKeyB, [ipIdA], [comUseLicenseTermsId1]); + }); + + step("ipIdA collect royalty tokens from ipIdB", async function () { + await checkRoyaltyTokensCollected("A", ipIdA, ipIdB, 0n); + }); + + step("Capture snapshotId for ipIdB", async function () { + snapshotId1_ipIdB = await getSnapshotId("B", ipIdB); + }); + + step("ipIdA check claimable revenue from vaultIpIdB", async function () { + await checkClaimableRevenue("A", ipIdB, ipIdA, snapshotId1_ipIdB, 0n); + }); + + step("ipIdA claim revenue from vaultIpIdB", async function () { + await claimRevenueByIPA("A", [snapshotId1_ipIdB], ipIdB, ipIdA, 0n); + }); + + step("ipIdB check claimable revenue from vaultIpIdB", async function () { + await checkClaimableRevenue("B", ipIdB, ipIdB, snapshotId1_ipIdB, 0n); + }); + + step("ipIdB claim revenue from vaultIpIdB", async function () { + await claimRevenueByIPA("B", [snapshotId1_ipIdB], ipIdB, ipIdB, 0n); + }); + + step("Capture snapshotId for ipIdA", async function () { + snapshotId1_ipIdA = await getSnapshotId("A", ipIdA); + }); + + step("ipIdA check claimable revenue from vaultIpIdA", async function () { + await checkClaimableRevenue("A", ipIdA, ipIdA, snapshotId1_ipIdA, BigInt(mintingFee1)); + }); + + step("idIdA claim revenue from vaultIpIdA (minting fee)", async function () { + await claimRevenueByIPA("A", [snapshotId1_ipIdA], ipIdA, ipIdA, BigInt(mintingFee1)); + }); + + step("Check claimable revenue again", async function () { + await checkClaimableRevenue("A", ipIdA, ipIdA, snapshotId1_ipIdA, 0n); + }); + }); + + describe('Commercial Use PIL - Claim Minting Fee and Revenue by IPA account', async function () { + const mintingFee: number = 180; + const payAmount: number = 1000000; + + before("Register parent and derivative IP assets", async function () { + // register commercial use PIL + const licenseTermsId = Number((await registerCommercialUsePIL("A", mintingFee, mintingFeeTokenAddress, true)).licenseTermsId); + + // root IP: ipIdA + ipIdA = await mintNFTCreateRootIPandAttachPIL("A", privateKeyA, licenseTermsId); + // ipIdB is ipIdA's derivative IP + ipIdB = await mintNFTAndRegisterDerivative("B", privateKeyB, [ipIdA], [licenseTermsId]); + // ipIdC is ipIdB's derivative IP + ipIdC = await mintNFTAndRegisterDerivative("C", privateKeyC, [ipIdB], [licenseTermsId]); + }); + + step("ipIdC pay royalty on behalf to ipIdB", async function () { + const response = await expect( + payRoyaltyOnBehalf("C", ipIdB, ipIdC, mintingFeeTokenAddress, payAmount, true) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + + step("Capture snapshotId for ipIdB", async function () { + snapshotId1_ipIdB = await getSnapshotId("B", ipIdB); + }); + + step("ipIdA check claimable revenue from vaultIpIdB", async function () { + await checkClaimableRevenue("A", ipIdB, ipIdA, snapshotId1_ipIdB, 0n); + }); + + step("ipIdA claim revenue from vaultIpIdB", async function () { + await claimRevenueByIPA("A", [snapshotId1_ipIdB], ipIdB, ipIdA, 0n); + }); + + step("ipIdB check claimable revenue from vaultIpIdB", async function () { + await checkClaimableRevenue("B", ipIdB, ipIdB, snapshotId1_ipIdB, BigInt(payAmount + mintingFee)); + }); + + step("ipIdB claim revenue from vaultIpIdB", async function () { + await claimRevenueByIPA("B", [snapshotId1_ipIdB], ipIdB, ipIdB, BigInt(payAmount + mintingFee)); + }); + + step("Capture snapshotId for ipIdA", async function () { + snapshotId1_ipIdA = await getSnapshotId("A", ipIdA); + }); + + step("ipIdA check claimable revenue from vaultIpIdA", async function () { + await checkClaimableRevenue("A", ipIdA, ipIdA, snapshotId1_ipIdA, BigInt(mintingFee)); + }); + + step("ipIdA claim revenue from vaultIpIdA", async function () { + await claimRevenueByIPA("A", [snapshotId1_ipIdA], ipIdA, ipIdA, BigInt(mintingFee)); + }); + }); + + describe('Commercial Use PIL - Claim Minting Fee and Revenue by EOA', async function () { + const mintingFee: number = 200; + const payAmount: number = 1000; + + before("Register parent and derivative IP assets", async function () { + // register commercial use PIL + const licenseTermsId = Number((await registerCommercialUsePIL("A", mintingFee, mintingFeeTokenAddress, true)).licenseTermsId); + + // root IP: ipIdA + ipIdA = await mintNFTCreateRootIPandAttachPIL("A", privateKeyA, licenseTermsId); + // ipIdB is ipIdA's derivative IP + ipIdB = await mintNFTAndRegisterDerivative("B", privateKeyB, [ipIdA], [licenseTermsId]); + // ipIdC is ipIdB's derivative IP + ipIdC = await mintNFTAndRegisterDerivative("C", privateKeyC, [ipIdB], [licenseTermsId]); + }); + + step("Transfer token to EOA - ipIdB", async function () { + await transferTokenToEOA("B", ipIdB, accountB.address, BigInt(100 * 10 ** 6)); + }); + + step("Transfer token to EOA - ipIdA", async function () { + await transferTokenToEOA("A", ipIdA, accountA.address, BigInt(100 * 10 ** 6)); + }); + + step("ipIdC pay royalty on behalf to ipIdB", async function () { + const response = await expect( + payRoyaltyOnBehalf("C", ipIdB, ipIdC, mintingFeeTokenAddress, payAmount, true) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + + step("Capture snapshotId for ipIdB", async function () { + snapshotId1_ipIdB = await getSnapshotId("B", ipIdB); + }); + + step("ipIdA check claimable revenue from vaultIpIdB", async function () { + await checkClaimableRevenue("A", ipIdB, ipIdA, snapshotId1_ipIdB, 0n); + }); + + step("ipIdB check claimable revenue from vaultIpIdB", async function () { + await checkClaimableRevenue("B", ipIdB, ipIdB, snapshotId1_ipIdB, 0n); + }); + + step("ipIdA claim revenue from vaultIpIdB", async function () { + await claimRevenueByEOA("A", [snapshotId1_ipIdB], ipIdB, 0n); + }); + + step("ipIdB claim revenue from vaultIpIdB by IPA", async function () { + await claimRevenueByIPA("B", [snapshotId1_ipIdB], ipIdB, ipIdB, 0n); + }); + + step("ipIdB claim revenue from vaultIpIdB by EOA", async function () { + await claimRevenueByEOA("B", [snapshotId1_ipIdB], ipIdB, BigInt(payAmount + mintingFee)); + }); + + step("Capture snapshotId for ipIdA", async function () { + snapshotId1_ipIdA = await getSnapshotId("A", ipIdA); + }); + + step("ipIdA check claimable revenue from vaultIpIdA", async function () { + await checkClaimableRevenue("A", ipIdA, ipIdA, snapshotId1_ipIdA, 0n); + }); + + step("ipIdA claim revenue from vaultIpIdA by IPA", async function () { + await claimRevenueByIPA("A", [snapshotId1_ipIdA], ipIdA, ipIdA, 0n); + }); + + step("ipIdA claim revenue from vaultIpIdA by EOA", async function () { + await claimRevenueByEOA("A", [snapshotId1_ipIdA], ipIdA, BigInt(mintingFee)); + }); + }); +}); diff --git a/test/e2e/royalty.test.ts b/test/e2e/royalty.test.ts deleted file mode 100644 index ca61025..0000000 --- a/test/e2e/royalty.test.ts +++ /dev/null @@ -1,571 +0,0 @@ -import { privateKeyA, privateKeyB, privateKeyC, nftContractAddress, mintingFeeTokenAddress } from '../../config/config' -import { checkMintResult, mintNFTWithRetry } from '../../utils/utils' -import { registerIpAsset, attachLicenseTerms, registerDerivative, payRoyaltyOnBehalf, royaltySnapshot, collectRoyaltyTokens, royaltyClaimableRevenue, royaltyClaimRevenue } from '../../utils/sdkUtils' -import { expect } from 'chai' - -import chai from 'chai'; -import chaiAsPromised from 'chai-as-promised'; -chai.use(chaiAsPromised); -import '../setup'; -import { comUseLicenseTermsId1, comRemixLicenseTermsId2, mintingFee1, mintingFee2, commercialRevShare2, comUseLicenseTermsId2, comRemixLicenseTermsId1, commercialRevShare1 } from '../setup'; -import { Address } from 'viem'; - -let tokenIdA: string; -let tokenIdB: string; -let tokenIdC: string; -let ipIdA: Address; -let ipIdB: Address; -let ipIdC: Address; -let snapshotId1: bigint; -let snapshotId2: bigint; - -const waitForTransaction: boolean = true; - -describe('SDK E2E Test', function () { - describe("Royalty", function () { - describe("Commercial Use PIL - Claim Minting Fee", function () { - before("Register parent and derivative IP assets", async function () { - tokenIdA = await mintNFTWithRetry(privateKeyA); - checkMintResult(tokenIdA); - - const responseRegisterIpAsset = await expect( - registerIpAsset("A", nftContractAddress, tokenIdA, waitForTransaction) - ).to.not.be.rejected; - - expect(responseRegisterIpAsset.txHash).to.be.a("string").and.not.empty; - expect(responseRegisterIpAsset.ipId).to.be.a("string").and.not.empty; - - ipIdA = responseRegisterIpAsset.ipId; - - const responseAttachLicenseTerms = await expect( - attachLicenseTerms("A", ipIdA, comUseLicenseTermsId1, waitForTransaction) - ).to.not.be.rejected; - - expect(responseAttachLicenseTerms.txHash).to.be.a("string").and.not.empty; - - tokenIdB = await mintNFTWithRetry(privateKeyB); - checkMintResult(tokenIdB); - - const responseregisterIpAssetB = await expect( - registerIpAsset("B", nftContractAddress, tokenIdB, waitForTransaction) - ).to.not.be.rejected; - - expect(responseregisterIpAssetB.txHash).to.be.a("string").and.not.empty; - expect(responseregisterIpAssetB.ipId).to.be.a("string").and.not.empty; - - ipIdB = responseregisterIpAssetB.ipId; - - const response = await expect( - registerDerivative("B", ipIdB, [ipIdA], [comUseLicenseTermsId1], waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - }); - - step("Collect royalty tokens", async function () { - const response = await expect( - collectRoyaltyTokens("B", ipIdA, ipIdB, waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.royaltyTokensCollected).to.be.a('bigint').and.equal(0n); - }); - - step("Capture snapshotId", async function () { - const response = await expect( - royaltySnapshot("A", ipIdA, waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.snapshotId).to.be.a("bigint").and.to.be.ok; - - snapshotId1 = response.snapshotId; - }); - - step("Check claimable revenue", async function () { - const response = await expect( - royaltyClaimableRevenue("A", ipIdA, ipIdA, snapshotId1, mintingFeeTokenAddress, waitForTransaction) - ).to.not.be.rejected; - - expect(response).to.be.a("bigint").and.to.be.ok; - expect(response).to.be.equal(BigInt(mintingFee1)); - }); - - step("Claim minting fee", async function () { - const response = await expect( - royaltyClaimRevenue("A", [snapshotId1], ipIdA, ipIdA, mintingFeeTokenAddress, waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.claimableToken).to.be.equal(BigInt(mintingFee1)); - }); - - step("Check claimable revenue again", async function () { - const response = await expect( - royaltyClaimableRevenue("A", ipIdA, ipIdA, snapshotId1, mintingFeeTokenAddress, waitForTransaction) - ).to.not.be.rejected; - - expect(response).to.be.a("bigint").and.to.be.equal(0n); - }); - }) - - describe('Commercial Use PIL - Claim Minting Fee and Pay on Behalf', async function () { - let payAmount: string = "100"; - - before("Register parent and derivative IP assets", async function () { - tokenIdA = await mintNFTWithRetry(privateKeyA); - checkMintResult(tokenIdA); - - const responseRegisterIpAsset = await expect( - registerIpAsset("A", nftContractAddress, tokenIdA, waitForTransaction) - ).to.not.be.rejected; - - expect(responseRegisterIpAsset.txHash).to.be.a("string").and.not.empty; - expect(responseRegisterIpAsset.ipId).to.be.a("string").and.not.empty; - - ipIdA = responseRegisterIpAsset.ipId; - - const responseAttachLicenseTerms = await expect( - attachLicenseTerms("A", ipIdA, comUseLicenseTermsId2, waitForTransaction) - ).to.not.be.rejected; - - expect(responseAttachLicenseTerms.txHash).to.be.a("string").and.not.empty; - - tokenIdB = await mintNFTWithRetry(privateKeyB); - checkMintResult(tokenIdB); - - const responseregisterIpAssetB = await expect( - registerIpAsset("B", nftContractAddress, tokenIdB, waitForTransaction) - ).to.not.be.rejected; - - expect(responseregisterIpAssetB.txHash).to.be.a("string").and.not.empty; - expect(responseregisterIpAssetB.ipId).to.be.a("string").and.not.empty; - - ipIdB = responseregisterIpAssetB.ipId; - - const response = await expect( - registerDerivative("B", ipIdB, [ipIdA], [comUseLicenseTermsId2], waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - }); - - step("Collect royalty tokens", async function () { - const response = await expect( - collectRoyaltyTokens("B", ipIdA, ipIdB, waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.royaltyTokensCollected).to.be.a('bigint').and.equal(0n); - }); - - step("Capture snapshotId", async function () { - const response = await expect( - royaltySnapshot("A", ipIdA, waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.snapshotId).to.be.a("bigint").and.to.be.ok; - - snapshotId1 = response.snapshotId; - }); - - step("Check claimable revenue", async function () { - const response = await expect( - royaltyClaimableRevenue("A", ipIdA, ipIdA, snapshotId1, mintingFeeTokenAddress, waitForTransaction) - ).to.not.be.rejected; - - expect(response).to.be.a("bigint").and.to.be.ok; - expect(response).to.be.equal(BigInt(mintingFee2)); - }); - - step("Pay royalty on behalf", async function () { - const response = await expect( - payRoyaltyOnBehalf("B", ipIdA, ipIdB, mintingFeeTokenAddress, payAmount, waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - }); - - step("Capture snapshotId", async function () { - const response = await expect( - royaltySnapshot("A",ipIdA, waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.snapshotId).to.be.a("bigint").and.to.be.ok; - - snapshotId2 = response.snapshotId; - }); - - step("Check claimable revenue", async function () { - const response = await expect( - royaltyClaimableRevenue("A", ipIdA, ipIdA, snapshotId2, mintingFeeTokenAddress, waitForTransaction) - ).to.not.be.rejected; - - expect(response).to.be.a("bigint").and.to.be.ok; - expect(response).to.be.equal(BigInt(payAmount)); - }); - - step("Claim revenue", async function () { - const claimableRevenue = String(Number(mintingFee2) + Number(payAmount)); - const response = await expect( - royaltyClaimRevenue("A", [snapshotId1, snapshotId2], ipIdA, ipIdA, mintingFeeTokenAddress, waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.claimableToken).to.be.a("bigint").and.to.be.equal(BigInt(claimableRevenue)); - }); - - step("Check claimable revenue again", async function () { - const responseClaimableRevenue1 = await expect( - royaltyClaimableRevenue("A", ipIdA, ipIdA, snapshotId1, mintingFeeTokenAddress, waitForTransaction) - ).to.not.be.rejected; - - const responseClaimableRevenue2 = await expect( - royaltyClaimableRevenue("A", ipIdA, ipIdA, snapshotId2, mintingFeeTokenAddress, waitForTransaction) - ).to.not.be.rejected; - - expect(responseClaimableRevenue1).to.be.a("bigint").and.to.be.equal(0n); - expect(responseClaimableRevenue2).to.be.a("bigint").and.to.be.equal(0n); - }); - }); - - describe("Commercial Remix PIL - Claim Minting Fee", function () { - before("Register parent and derivative IP Assets", async function () { - tokenIdA = await mintNFTWithRetry(privateKeyA); - checkMintResult(tokenIdA); - - const responseRegisterIpAsset = await expect( - registerIpAsset("A", nftContractAddress, tokenIdA, waitForTransaction) - ).to.not.be.rejected; - - expect(responseRegisterIpAsset.txHash).to.be.a("string").and.not.empty; - expect(responseRegisterIpAsset.ipId).to.be.a("string").and.not.empty; - - ipIdA = responseRegisterIpAsset.ipId; - - const responseAttachLicenseTerms = await expect( - attachLicenseTerms("A", ipIdA, comRemixLicenseTermsId1, waitForTransaction) - ).to.not.be.rejected; - - expect(responseAttachLicenseTerms.txHash).to.be.a("string").and.not.empty; - - tokenIdB = await mintNFTWithRetry(privateKeyB); - checkMintResult(tokenIdB); - - const responseregisterIpAssetB = await expect( - registerIpAsset("B", nftContractAddress, tokenIdB, waitForTransaction) - ).to.not.be.rejected; - - expect(responseregisterIpAssetB.txHash).to.be.a("string").and.not.empty; - expect(responseregisterIpAssetB.ipId).to.be.a("string").and.not.empty; - - ipIdB = responseregisterIpAssetB.ipId; - - const response = await expect( - registerDerivative("B", ipIdB, [ipIdA], [comRemixLicenseTermsId1], waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - }); - - step("Collect royalty tokens", async function () { - const response = await expect( - collectRoyaltyTokens("A", ipIdA, ipIdB, waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.royaltyTokensCollected).to.be.a('bigint').and.to.be.ok; - - expect(Number(response.royaltyTokensCollected)).to.be.equal(commercialRevShare1 * 1000000); - }); - - step("Capture snapshotId", async function () { - const response = await expect( - royaltySnapshot("A", ipIdA, waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.snapshotId).to.be.a("bigint").and.to.be.ok; - - snapshotId1 = response.snapshotId; - }); - - step("Check claimable revenue", async function () { - const response = await expect( - royaltyClaimableRevenue("A", ipIdA, ipIdA, snapshotId1, mintingFeeTokenAddress, waitForTransaction) - ).to.not.be.rejected; - - expect(response).to.be.a("bigint").and.to.be.ok; - expect(response).to.be.equal(BigInt(mintingFee1)); - }); - - step("Claim revenue", async function () { - const response = await expect( - royaltyClaimRevenue("A", [snapshotId1], ipIdA, ipIdA, mintingFeeTokenAddress, waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.claimableToken).to.be.a("bigint").to.be.equal(BigInt(mintingFee1)); - }); - - step("Check claimable revenue again", async function () { - const response = await expect( - royaltyClaimableRevenue("A", ipIdA, ipIdA, snapshotId1, mintingFeeTokenAddress, waitForTransaction) - ).to.not.be.rejected; - - expect(response).to.be.a("bigint").and.to.be.equal(0n); - }); - }) - - describe('Commercial Remix PIL - Claim Minting Fee and Pay on Behalf', async function () { - let payAmount: string = "600"; - const claimableRevenue = String(Number(mintingFee2) + Number(payAmount)); - - before("Register parent and derivative IP assets", async function () { - tokenIdA = await mintNFTWithRetry(privateKeyA); - checkMintResult(tokenIdA); - expect(tokenIdA).not.empty; - - const responseRegisterIpAsset = await expect( - registerIpAsset("A", nftContractAddress, tokenIdA, waitForTransaction) - ).to.not.be.rejected; - - expect(responseRegisterIpAsset.txHash).to.be.a("string").and.not.empty; - expect(responseRegisterIpAsset.ipId).to.be.a("string").and.not.empty; - - ipIdA = responseRegisterIpAsset.ipId; - - const responseAttachLicenseTerms = await expect( - attachLicenseTerms("A", ipIdA, comRemixLicenseTermsId2, waitForTransaction) - ).to.not.be.rejected; - - expect(responseAttachLicenseTerms.txHash).to.be.a("string").and.not.empty; - - tokenIdB = await mintNFTWithRetry(privateKeyB); - checkMintResult(tokenIdB); - expect(tokenIdB).not.empty; - - const responseregisterIpAssetB = await expect( - registerIpAsset("B", nftContractAddress, tokenIdB, waitForTransaction) - ).to.not.be.rejected; - - expect(responseregisterIpAssetB.txHash).to.be.a("string").and.not.empty; - expect(responseregisterIpAssetB.ipId).to.be.a("string").and.not.empty; - - ipIdB = responseregisterIpAssetB.ipId; - - const responseB = await expect( - registerDerivative("B", ipIdB, [ipIdA], [comRemixLicenseTermsId2], waitForTransaction) - ).to.not.be.rejected; - - expect(responseB.txHash).to.be.a("string").and.not.empty; - }); - - step("Collect royalty tokens", async function () { - const response = await expect( - collectRoyaltyTokens("C", ipIdA, ipIdB, waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.royaltyTokensCollected).to.be.a('bigint').and.equal(BigInt(commercialRevShare2 * 1000000)); - }); - - step("Capture snapshot", async function () { - const response = await expect( - royaltySnapshot("A", ipIdA, waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.snapshotId).to.be.a("bigint").and.to.be.ok; - - snapshotId1 = response.snapshotId; - }); - - step("Check claimable revenue", async function () { - const response = await expect( - royaltyClaimableRevenue("A", ipIdA, ipIdA, snapshotId1, mintingFeeTokenAddress, waitForTransaction) - ).to.not.be.rejected; - - expect(response).to.be.a("bigint").and.to.be.ok; - expect(response).to.be.equal(BigInt(mintingFee2)); - }); - - step("Pay royalty on behalf", async function () { - const response = await expect( - payRoyaltyOnBehalf("C", ipIdA, ipIdB, mintingFeeTokenAddress, payAmount, waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - }); - - step("Capture snapshot", async function () { - const response = await expect( - royaltySnapshot("A", ipIdA, waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.snapshotId).to.be.a("bigint").and.to.be.ok; - - snapshotId2 = response.snapshotId; - }); - - step("Check claimable revenue", async function () { - const response = await expect( - royaltyClaimableRevenue("A", ipIdA, ipIdA, snapshotId2, mintingFeeTokenAddress, waitForTransaction) - ).to.not.be.rejected; - - expect(response).to.be.a("bigint").and.to.be.ok; - expect(response).to.be.equal(BigInt(payAmount)); - }); - - step("Claim royalty tokens", async function () { - const response = await expect( - royaltyClaimRevenue("A", [snapshotId1, snapshotId2], ipIdA, ipIdA, mintingFeeTokenAddress, waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.claimableToken).to.be.a("bigint").and.to.be.equal(BigInt(claimableRevenue)); - }) - - step("Check claimable revenue again", async function () { - const responseClaimableRevenue1 = await expect( - royaltyClaimableRevenue("A", ipIdA, ipIdA, snapshotId1, mintingFeeTokenAddress, waitForTransaction) - ).to.not.be.rejected; - - const responseClaimableRevenue2 = await expect( - royaltyClaimableRevenue("A", ipIdA, ipIdA, snapshotId2, mintingFeeTokenAddress, waitForTransaction) - ).to.not.be.rejected; - - expect(responseClaimableRevenue1).to.be.a("bigint").and.to.be.equal(0n); - expect(responseClaimableRevenue2).to.be.a("bigint").and.to.be.equal(0n); - }); - }); - - describe('Royalty - Derivative and Re-inherited IP Assets', async function () { - let payAmount: string = "800"; - - before("Register parent and derivative IP assets", async function () { - tokenIdA = await mintNFTWithRetry(privateKeyA); - checkMintResult(tokenIdA); - expect(tokenIdA).not.empty; - - const responseRegisterIpAsset = await expect( - registerIpAsset("A", nftContractAddress, tokenIdA, waitForTransaction) - ).to.not.be.rejected; - - expect(responseRegisterIpAsset.txHash).to.be.a("string").and.not.empty; - expect(responseRegisterIpAsset.ipId).to.be.a("string").and.not.empty; - - ipIdA = responseRegisterIpAsset.ipId; - - const responseAttachLicenseTerms = await expect( - attachLicenseTerms("A", ipIdA, comRemixLicenseTermsId1, waitForTransaction) - ).to.not.be.rejected; - - expect(responseAttachLicenseTerms.txHash).to.be.a("string").and.not.empty; - - tokenIdB = await mintNFTWithRetry(privateKeyB); - checkMintResult(tokenIdB); - expect(tokenIdB).not.empty; - - const responseregisterIpAssetB = await expect( - registerIpAsset("B", nftContractAddress, tokenIdB, waitForTransaction) - ).to.not.be.rejected; - - expect(responseregisterIpAssetB.txHash).to.be.a("string").and.not.empty; - expect(responseregisterIpAssetB.ipId).to.be.a("string").and.not.empty; - - ipIdB = responseregisterIpAssetB.ipId; - - const responseB = await expect( - registerDerivative("B", ipIdB, [ipIdA], [comRemixLicenseTermsId1], waitForTransaction) - ).to.not.be.rejected; - - expect(responseB.txHash).to.be.a("string").and.not.empty; - - tokenIdC = await mintNFTWithRetry(privateKeyC); - checkMintResult(tokenIdC); - - const responseregisterIpAssetC = await expect( - registerIpAsset("C", nftContractAddress, tokenIdC, waitForTransaction) - ).to.not.be.rejected; - - expect(responseregisterIpAssetC.txHash).to.be.a("string").and.not.empty; - expect(responseregisterIpAssetC.ipId).to.be.a("string").and.not.empty; - - ipIdC = responseregisterIpAssetC.ipId; - - const responseC = await expect( - registerDerivative("C", ipIdC, [ipIdB], [comRemixLicenseTermsId1], waitForTransaction) - ).to.not.be.rejected; - - expect(responseC.txHash).to.be.a("string").and.not.empty; - }); - - step("Pay royalty on behalf", async function () { - const response = await expect( - payRoyaltyOnBehalf("C", ipIdB, ipIdC, mintingFeeTokenAddress, payAmount, waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - }); - - step("Collect royalty tokens", async function () { - const response = await expect( - collectRoyaltyTokens("C", ipIdA, ipIdB, waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.royaltyTokensCollected).to.be.a('bigint').and.equal(BigInt(commercialRevShare1 * 1000000)); - }); - - step("Collect royalty tokens", async function () { - const response = await expect( - collectRoyaltyTokens("C", ipIdB, ipIdC, waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.royaltyTokensCollected).to.be.a('bigint').and.equal(BigInt(commercialRevShare1 * 1000000)); - }); - - step("Capture snapshot", async function () { - const response = await expect( - royaltySnapshot("A", ipIdA, waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.snapshotId).to.be.a("bigint").and.to.be.ok; - - snapshotId1 = response.snapshotId; - }); - - step("Check claimable revenue", async function () { - const response = await expect( - royaltyClaimableRevenue("A", ipIdA, ipIdA, snapshotId1, mintingFeeTokenAddress, waitForTransaction) - ).to.not.be.rejected; - - expect(response).to.be.a("bigint").and.to.be.ok; - expect(response).to.be.equal(BigInt(mintingFee1)); - }); - - step("Claim royalty tokens", async function () { - const response = await expect( - royaltyClaimRevenue("A", [snapshotId1], ipIdA, ipIdA, mintingFeeTokenAddress, waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.claimableToken).to.be.a("bigint").and.to.be.equal(BigInt(mintingFee1)); - }) - - step("Check claimable revenue again", async function () { - const responseClaimableRevenue1 = await expect( - royaltyClaimableRevenue("A", ipIdA, ipIdA, snapshotId1, mintingFeeTokenAddress, waitForTransaction) - ).to.not.be.rejected; - - expect(responseClaimableRevenue1).to.be.a("bigint").and.to.be.equal(0n); - }); - }); - }); -}); diff --git a/test/e2e/setPermissions.test.ts b/test/e2e/setPermissions.test.ts index e9f221a..b72ebce 100644 --- a/test/e2e/setPermissions.test.ts +++ b/test/e2e/setPermissions.test.ts @@ -17,123 +17,121 @@ let ipIdB: Hex; const waitForTransaction: boolean = true; -describe('SDK E2E Test', function () { - describe("[smoke]Set Permissions", async function () { - this.beforeAll("Wallet A register 2 license terms and 2 IP assets", async function () { - tokenIdA = await mintNFTWithRetry(privateKeyA); - checkMintResult(tokenIdA); - - const responseRegisterIpA = await expect( - registerIpAsset("A", nftContractAddress, tokenIdA, waitForTransaction) - ).to.not.be.rejected; +describe('@smoke SDK E2E Test - Permissions', function () { + this.beforeAll("Wallet A register 2 license terms and 2 IP assets", async function () { + tokenIdA = await mintNFTWithRetry(privateKeyA); + checkMintResult(tokenIdA); - expect(responseRegisterIpA.txHash).to.be.a("string").and.not.empty; - expect(responseRegisterIpA.ipId).to.be.a("string").and.not.empty; + const responseRegisterIpA = await expect( + registerIpAsset("A", nftContractAddress, tokenIdA, waitForTransaction) + ).to.not.be.rejected; + + expect(responseRegisterIpA.txHash).to.be.a("string").and.not.empty; + expect(responseRegisterIpA.ipId).to.be.a("string").and.not.empty; + + ipIdA = responseRegisterIpA.ipId; + + tokenIdB = await mintNFTWithRetry(privateKeyA); + checkMintResult(tokenIdB); - ipIdA = responseRegisterIpA.ipId; + const responseRegisterIpB = await expect( + registerIpAsset("A", nftContractAddress, tokenIdB, waitForTransaction) + ).to.not.be.rejected; - tokenIdB = await mintNFTWithRetry(privateKeyA); - checkMintResult(tokenIdB); - - const responseRegisterIpB = await expect( - registerIpAsset("A", nftContractAddress, tokenIdB, waitForTransaction) + expect(responseRegisterIpB.txHash).to.be.a("string").and.not.empty; + expect(responseRegisterIpB.ipId).to.be.a("string").and.not.empty; + + ipIdB = responseRegisterIpB.ipId; + }) + + describe("Set permission - 1 ALLOW", async function (){ + // error 0xb3e96921: AccessController__PermissionDenied(address,address,address,bytes4) + step("Wallet B(non-owner) can NOT attach licenseTermsId1 to ipIdA", async function () { + const response = await expect( + attachLicenseTerms("B", ipIdA, nonComLicenseTermsId, waitForTransaction) + ).to.be.rejectedWith("Failed to attach license terms: The contract function \"attachLicenseTerms\" reverted with the following signature:", "0xb3e96921"); + }); + + // wallet B is granted permission - 1 ALLOW for ipIdA + step("Wallet A set permission (permission id: 1) to allow Wallet B to call license Module for ipIdA", async function () { + const response = await expect( + setPermission("A", ipIdA, accountB.address, licensingModuleAddress, 1, waitForTransaction) ).to.not.be.rejected; - expect(responseRegisterIpB.txHash).to.be.a("string").and.not.empty; - expect(responseRegisterIpB.ipId).to.be.a("string").and.not.empty; + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.success).to.be.true; + }); + + step("Wallet B can attach licenseTermsId1 to ipIdA", async function () { + const response = await expect( + attachLicenseTerms("B", ipIdA, nonComLicenseTermsId, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + + // wallet B is not granted any permission for ipIdB + // error 0xb3e96921: AccessController__PermissionDenied(address,address,address,bytes4) + step("Wallet B can NOT attach licenseTermsId1 to ipIdB", async function () { + const response = await expect( + attachLicenseTerms("B", ipIdB, nonComLicenseTermsId, waitForTransaction) + ).to.be.rejectedWith("Failed to attach license terms: The contract function \"attachLicenseTerms\" reverted with the following signature:", "0xb3e96921"); + }); + }); - ipIdB = responseRegisterIpB.ipId; - }) - - describe("Set permission - 1 ALLOW", async function (){ - // error 0xb3e96921: AccessController__PermissionDenied(address,address,address,bytes4) - step("Wallet B(non-owner) can NOT attach licenseTermsId1 to ipIdA", async function () { - const response = await expect( - attachLicenseTerms("B", ipIdA, nonComLicenseTermsId, waitForTransaction) - ).to.be.rejectedWith("Failed to attach license terms: The contract function \"attachLicenseTerms\" reverted with the following signature:", "0xb3e96921"); - }); - - // wallet B is granted permission - 1 ALLOW for ipIdA - step("Wallet A set permission (permission id: 1) to allow Wallet B to call license Module for ipIdA", async function () { - const response = await expect( - setPermission("A", ipIdA, accountB.address, licensingModuleAddress, 1, waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.success).to.be.true; - }); - - step("Wallet B can attach licenseTermsId1 to ipIdA", async function () { - const response = await expect( - attachLicenseTerms("B", ipIdA, nonComLicenseTermsId, waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - }); - - // wallet B is not granted any permission for ipIdB - // error 0xb3e96921: AccessController__PermissionDenied(address,address,address,bytes4) - step("Wallet B can NOT attach licenseTermsId1 to ipIdB", async function () { - const response = await expect( - attachLicenseTerms("B", ipIdB, nonComLicenseTermsId, waitForTransaction) - ).to.be.rejectedWith("Failed to attach license terms: The contract function \"attachLicenseTerms\" reverted with the following signature:", "0xb3e96921"); - }); + describe("Set permission - 2 DENY", async function (){ + // change wallet B's permission to 2 DENY for ipIdA + step("Wallet A set permission (permission id: 2) to NOT allow Wallet B to call license Module for ipIdA", async function () { + const response = await expect( + setPermission("A", ipIdA, accountB.address, licensingModuleAddress, 2, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.success).to.be.true; }); - describe("Set permission - 2 DENY", async function (){ - // change wallet B's permission to 2 DENY for ipIdA - step("Wallet A set permission (permission id: 2) to NOT allow Wallet B to call license Module for ipIdA", async function () { - const response = await expect( - setPermission("A", ipIdA, accountB.address, licensingModuleAddress, 2, waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.success).to.be.true; - }); - - // error 0xb3e96921: AccessController__PermissionDenied(address,address,address,bytes4) - step("Wallet B can NOT attach licenseTermsId1 to ipIdA", async function () { - const response = await expect( - attachLicenseTerms("B", ipIdA, comUseLicenseTermsId1, waitForTransaction) - ).to.be.rejectedWith("Failed to attach license terms: The contract function \"attachLicenseTerms\" reverted with the following signature:", "0xb3e96921"); - }); + // error 0xb3e96921: AccessController__PermissionDenied(address,address,address,bytes4) + step("Wallet B can NOT attach licenseTermsId1 to ipIdA", async function () { + const response = await expect( + attachLicenseTerms("B", ipIdA, comUseLicenseTermsId1, waitForTransaction) + ).to.be.rejectedWith("Failed to attach license terms: The contract function \"attachLicenseTerms\" reverted with the following signature:", "0xb3e96921"); + }); + }); + + describe("Set permission - 0 ABSTAIN", async function (){ + // wallet B is granted permission - 1 ALLOW for ipIdB + step("Wallet A set permission (permission id: 1) to allow Wallet B to call license Module for ipIdB", async function () { + const response = await expect( + setPermission("A", ipIdB, accountB.address, licensingModuleAddress, 1, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.success).to.be.true; + }); + + step("Wallet B can attach licenseTermsId1 to ipIdB", async function () { + const response = await expect( + attachLicenseTerms("B", ipIdB, nonComLicenseTermsId, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; }); - describe("Set permission - 0 ABSTAIN", async function (){ - // wallet B is granted permission - 1 ALLOW for ipIdB - step("Wallet A set permission (permission id: 1) to allow Wallet B to call license Module for ipIdB", async function () { - const response = await expect( - setPermission("A", ipIdB, accountB.address, licensingModuleAddress, 1, waitForTransaction) - ).to.not.be.rejected; + // change wallet B's permission to 0 ABSTAIN for ipIdB + step("Wallet A set permission (permission id: 0) to NOT allow Wallet B to call license Module for ipIdB", async function () { + const response = await expect( + setPermission("A", ipIdB, accountB.address, licensingModuleAddress, 0, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.success).to.be.true; + }); - expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.success).to.be.true; - }); - - step("Wallet B can attach licenseTermsId1 to ipIdB", async function () { - const response = await expect( - attachLicenseTerms("B", ipIdB, nonComLicenseTermsId, waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - }); - - // change wallet B's permission to 0 ABSTAIN for ipIdB - step("Wallet A set permission (permission id: 0) to NOT allow Wallet B to call license Module for ipIdB", async function () { - const response = await expect( - setPermission("A", ipIdB, accountB.address, licensingModuleAddress, 0, waitForTransaction) - ).to.not.be.rejected; - - expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.success).to.be.true; - }); - - // error 0xb3e96921: AccessController__PermissionDenied(address,address,address,bytes4) - step("Wallet B can NOT attach licenseTermsId2 to ipIdB", async function () { - const response = await expect( - attachLicenseTerms("B", ipIdB, comUseLicenseTermsId1, waitForTransaction) - ).to.be.rejectedWith("Failed to attach license terms: The contract function \"attachLicenseTerms\" reverted with the following signature:", "0xb3e96921"); - }); + // error 0xb3e96921: AccessController__PermissionDenied(address,address,address,bytes4) + step("Wallet B can NOT attach licenseTermsId2 to ipIdB", async function () { + const response = await expect( + attachLicenseTerms("B", ipIdB, comUseLicenseTermsId1, waitForTransaction) + ).to.be.rejectedWith("Failed to attach license terms: The contract function \"attachLicenseTerms\" reverted with the following signature:", "0xb3e96921"); }); }); }); diff --git a/test/ipAccount/executeWithSig.test.ts b/test/ipAccount/executeWithSig.test.ts new file mode 100644 index 0000000..88d4f4d --- /dev/null +++ b/test/ipAccount/executeWithSig.test.ts @@ -0,0 +1,77 @@ +import { privateKeyA, privateKeyB, clientA, accountA, chainId } from '../../config/config'; +import { getDeadline, getWalletClient } from '../../utils/utils'; +import { expect } from 'chai' +import chai from 'chai'; +import chaiAsPromised from 'chai-as-promised'; +chai.use(chaiAsPromised); +import '../setup'; +import { Address, Hex, encodeFunctionData, getAddress, toFunctionSelector } from 'viem'; +import { getPermissionSignature, AccessPermission } from '@story-protocol/core-sdk'; +import { mintNFTAndRegisterDerivative, mintNFTCreateRootIPandAttachPIL } from '../testUtils'; +import { comUseLicenseTermsId1 } from '../setup'; +import { accessControllerAbi } from '../../config/abi'; +import { ipAccountExecuteWithSig } from '../../utils/sdkUtils'; + +let ipIdA: Address; +let ipIdB: Address; +let signature: Hex; + +const coreMetadataModule = "0xDa498A3f7c8a88cb72201138C366bE3778dB9575" as Address; +const accessControllerAddress = "0xF9936a224b3Deb6f9A4645ccAfa66f7ECe83CF0A" as Address; +const deadline = getDeadline(60000n); +const walletClinet = getWalletClient(privateKeyA); + +describe('SDK Test', function () { + describe('Test ipAccount.executeWithSig Function', async function () { + before("Mint 3 NFTs to Wallet A", async function () { + // root IP: ipIdA + ipIdA = await mintNFTCreateRootIPandAttachPIL("A", privateKeyA, comUseLicenseTermsId1); + + // ipIdB is ipIdA's derivative IP + ipIdB = await mintNFTAndRegisterDerivative("B", privateKeyB, [ipIdA], [comUseLicenseTermsId1]); + + const state = await clientA.ipAccount.getIpAccountNonce(ipIdA); + const expectedState = state + 1n; + + signature = await getPermissionSignature({ + ipId: ipIdA, + wallet: walletClinet, + permissions: [ + { + ipId: ipIdA, + signer: accountA.address, + to: coreMetadataModule, + permission: AccessPermission.ALLOW, + func: "function setAll(address,string,bytes32,bytes32)", + }, + ], + nonce: expectedState, + + chainId: BigInt(chainId), + deadline: deadline, + }); + }); + + it("ipAccount execute with siganature", async function () { + console.log("ipIdA: " + ipIdA); + + const data = encodeFunctionData({ + abi: accessControllerAbi, + functionName: "setPermission", + args: [ + getAddress(ipIdA), + getAddress(accountA.address), + getAddress(coreMetadataModule), + toFunctionSelector("function setAll(address,string,bytes32,bytes32)"), + AccessPermission.ALLOW, + ], + }); + + const response = await ipAccountExecuteWithSig("A", ipIdA, accessControllerAddress, 0, data, accountA.address, deadline, signature, true); + + console.log(response); + + expect(response.txHash).to.be.a("string").and.not.empty; + }); + }); +}); diff --git a/test/ipAsset/mintAndRegisterIpAssetWithPilTerms.test.ts b/test/ipAsset/mintAndRegisterIpAssetWithPilTerms.test.ts index 03c91a2..baeaae6 100644 --- a/test/ipAsset/mintAndRegisterIpAssetWithPilTerms.test.ts +++ b/test/ipAsset/mintAndRegisterIpAssetWithPilTerms.test.ts @@ -30,13 +30,13 @@ describe('SDK Test', function () { let nftContractAddress: any; await expect( mintAndRegisterIpAssetWithPilTerms("A", nftContractAddress, PIL_TYPE.NON_COMMERCIAL_REMIX) - ).to.be.rejectedWith(`Failed to mint and register IP and attach PIL terms: Address "undefined" is invalid.`); + ).to.be.rejectedWith(`Failed to mint and register IP and attach PIL terms: request.nftContract address is invalid: undefined, Address must be a hex value of 20 bytes (40 hex characters) and match its checksum counterpart.`); }); it("Register an IP asset fail as invalid NFT contract address", async function () { await expect( mintAndRegisterIpAssetWithPilTerms("A", "0x0000", PIL_TYPE.NON_COMMERCIAL_REMIX) - ).to.be.rejectedWith(`Failed to mint and register IP and attach PIL terms: Address "0x0000" is invalid.`); + ).to.be.rejectedWith(`Failed to mint and register IP and attach PIL terms: request.nftContract address is invalid: 0x0000, Address must be a hex value of 20 bytes (40 hex characters) and match its checksum counterpart.`); }); it("Register an IP asset fail as non-existent NFT contract address", async function () { @@ -67,7 +67,7 @@ describe('SDK Test', function () { it("Register an IP asset fail as invalid recipient", async function () { await expect( mintAndRegisterIpAssetWithPilTerms("A", nftCollectionAddress, PIL_TYPE.NON_COMMERCIAL_REMIX, true, metadataURI, undefined, undefined, "0x000") - ).to.be.rejectedWith(`Failed to mint and register IP and attach PIL terms: Address "0x000" is invalid.`); + ).to.be.rejectedWith(`Failed to mint and register IP and attach PIL terms: request.recipient address is invalid: 0x000, Address must be a hex value of 20 bytes (40 hex characters) and match its checksum counterpart.`); }); it("Register an IP asset fail as missing required parameters for commercial use PIL", async function () { diff --git a/test/ipAsset/register.test.ts b/test/ipAsset/register.test.ts index 15c9856..a05ed85 100644 --- a/test/ipAsset/register.test.ts +++ b/test/ipAsset/register.test.ts @@ -36,7 +36,7 @@ describe('SDK Test', function () { it("Register an IP asset fail as invalid NFT contract address", async function () { await expect( registerIpAsset("A", "0x000000", tokenIdA, true) - ).to.be.rejectedWith("Failed to register IP: Address \"0x000000\" is invalid."); + ).to.be.rejectedWith(`Failed to register IP: nftContract address is invalid: 0x000000, Address must be a hex value of 20 bytes (40 hex characters) and match its checksum counterpart.`); }); it("Register an IP asset fail as invalid tokenId", async function () { diff --git a/test/ipAsset/registerDerivative.test.ts b/test/ipAsset/registerDerivative.test.ts index fea3945..b934fcb 100644 --- a/test/ipAsset/registerDerivative.test.ts +++ b/test/ipAsset/registerDerivative.test.ts @@ -65,13 +65,13 @@ describe('SDK Test', function () { let ipIdB: any; await expect( registerDerivative("B", ipIdB, [ipIdA], [nonComLicenseTermsId], true) - ).to.be.rejectedWith("Failed to register derivative: Address \"undefined\" is invalid."); + ).to.be.rejectedWith(`Failed to register derivative: ipId address is invalid: undefined, Address must be a hex value of 20 bytes (40 hex characters) and match its checksum counterpart.`); }); it("Register a derivative IP asset fail as invalid child ipId", async function () { await expect( registerDerivative("B", "0x0000", [ipIdA], [nonComLicenseTermsId], true) - ).to.be.rejectedWith("Failed to register derivative: Address \"0x0000\" is invalid."); + ).to.be.rejectedWith(`Failed to register derivative: ipId address is invalid: 0x0000, Address must be a hex value of 20 bytes (40 hex characters) and match its checksum counterpart.`); }); it("Register a derivative IP asset fail as non-existent child ipId", async function () { @@ -84,13 +84,13 @@ describe('SDK Test', function () { let ipIdA: any; await expect( registerDerivative("B", ipIdB, [ipIdA], [nonComLicenseTermsId], true) - ).to.be.rejectedWith("Failed to register derivative: Address \"undefined\" is invalid."); + ).to.be.rejectedWith(`Failed to register derivative: request.parentIpIds address is invalid: undefined, Address must be a hex value of 20 bytes (40 hex characters) and match its checksum counterpart.`); }); it("Register a derivative IP asset fail as invalid parent ipId", async function () { await expect( registerDerivative("B", ipIdB, ["0x0000"], [nonComLicenseTermsId], true) - ).to.be.rejectedWith("Failed to register derivative: Address \"0x0000\" is invalid."); + ).to.be.rejectedWith(`Failed to register derivative: request.parentIpIds address is invalid: 0x0000, Address must be a hex value of 20 bytes (40 hex characters) and match its checksum counterpart.`); }); it("Register a derivative IP asset fail as non-existent parent ipId", async function () { diff --git a/test/ipAsset/registerDerivativeIp.test.ts b/test/ipAsset/registerDerivativeIp.test.ts index 521fcef..c318f4a 100644 --- a/test/ipAsset/registerDerivativeIp.test.ts +++ b/test/ipAsset/registerDerivativeIp.test.ts @@ -53,13 +53,13 @@ describe('SDK Test', function () { let nftContractAddress: any; await expect( registerDerivativeIp("A", nftContractAddress, tokenIdB, [ipIdA], [nonComLicenseTermsId], true) - ).to.be.rejectedWith(`Failed to register derivative IP: Address "undefined" is invalid.`); + ).to.be.rejectedWith(`Failed to register derivative IP: nftContract address is invalid: undefined, Address must be a hex value of 20 bytes (40 hex characters) and match its checksum counterpart.`); }); it("Register a derivative IP asset fail as invalid NFT contract address", async function () { await expect( registerDerivativeIp("A", "0x0000", tokenIdB, [ipIdA], [nonComLicenseTermsId], true) - ).to.be.rejectedWith(`Failed to register derivative IP: Address "0x0000" is invalid.`); + ).to.be.rejectedWith(`Failed to register derivative IP: nftContract address is invalid: 0x0000, Address must be a hex value of 20 bytes (40 hex characters) and match its checksum counterpart.`); }); // 0x1033cd88: IPAssetRegistry__UnsupportedIERC721(address) @@ -92,13 +92,13 @@ describe('SDK Test', function () { let ipId: any; await expect( registerDerivativeIp("A", nftContractAddress, tokenIdB, [ipId], [nonComLicenseTermsId], true) - ).to.be.rejectedWith(`Failed to register derivative IP: Address "undefined" is invalid.`); + ).to.be.rejectedWith(`Failed to register derivative IP: request.derivData.parentIpIds address is invalid: undefined, Address must be a hex value of 20 bytes (40 hex characters) and match its checksum counterpart.`); }); it("Register a derivative IP asset fail as invalid ipId", async function () { await expect( registerDerivativeIp("A", nftContractAddress, tokenIdB, ["0x0000"], [nonComLicenseTermsId], true) - ).to.be.rejectedWith(`Failed to register derivative IP: Address "0x0000" is invalid.`); + ).to.be.rejectedWith(`Failed to register derivative IP: request.derivData.parentIpIds address is invalid: 0x0000, Address must be a hex value of 20 bytes (40 hex characters) and match its checksum counterpart.`); }); it("Register a derivative IP asset fail as undefined licenseTermsId", async function () { @@ -129,7 +129,7 @@ describe('SDK Test', function () { it("Register a derivative IP asset fail as invalid licenseTemplate", async function () { await expect( registerDerivativeIp("A", nftContractAddress, tokenIdB, [ipIdA], [nonComLicenseTermsId], true, "0x0000") - ).to.be.rejectedWith(`Failed to register derivative IP: Address "0x0000" is invalid.`); + ).to.be.rejectedWith(`Failed to register derivative IP: request.derivData.licenseTemplate address is invalid: 0x0000, Address must be a hex value of 20 bytes (40 hex characters) and match its checksum counterpart.`); }); it("Register a derivative IP asset fail as invalid metadataHash", async function () { diff --git a/test/ipAsset/registerDerivativeWithLicenseTokens.test.ts b/test/ipAsset/registerDerivativeWithLicenseTokens.test.ts index c8f9955..05400cc 100644 --- a/test/ipAsset/registerDerivativeWithLicenseTokens.test.ts +++ b/test/ipAsset/registerDerivativeWithLicenseTokens.test.ts @@ -70,9 +70,9 @@ describe('SDK Test', function () { ).to.not.be.rejected; expect(responsemintLicenseTokenA.txHash).to.be.a("string").and.not.empty; - expect(responsemintLicenseTokenA.licenseTokenId).to.be.a("bigint").and.to.be.ok; + expect(responsemintLicenseTokenA.licenseTokenIds).to.be.a("array").and.to.have.lengthOf(2); - licenseTokenIdA = responsemintLicenseTokenA.licenseTokenId; + licenseTokenIdA = responsemintLicenseTokenA.licenseTokenIds[0]; const responseAttachLicenseTerms2 = await expect( attachLicenseTerms("A", ipIdA, comUseLicenseTermsId1, true) @@ -85,18 +85,18 @@ describe('SDK Test', function () { ).to.not.be.rejected; expect(responsemintLicenseTokenB.txHash).to.be.a("string").and.not.empty; - expect(responsemintLicenseTokenB.licenseTokenId).to.be.a("bigint").and.to.be.ok; + expect(responsemintLicenseTokenB.licenseTokenIds).to.be.a("array").and.to.have.lengthOf(2); - licenseTokenIdB = responsemintLicenseTokenB.licenseTokenId; + licenseTokenIdB = responsemintLicenseTokenB.licenseTokenIds[0]; const responsemintLicenseTokenC = await expect( mintLicenseTokens("A", ipIdA, comUseLicenseTermsId1, 2, accountC.address, true) ).to.not.be.rejected; expect(responsemintLicenseTokenC.txHash).to.be.a("string").and.not.empty; - expect(responsemintLicenseTokenC.licenseTokenId).to.be.a("bigint").and.to.be.ok; + expect(responsemintLicenseTokenC.licenseTokenIds).to.be.a("array").and.to.have.lengthOf(2); - licenseTokenIdC = responsemintLicenseTokenC.licenseTokenId; + licenseTokenIdC = responsemintLicenseTokenC.licenseTokenIds[0]; const responseAttachLicenseTerms3 = await expect( attachLicenseTerms("A", ipIdA, comUseLicenseTermsId2, true) @@ -109,9 +109,9 @@ describe('SDK Test', function () { ).to.not.be.rejected; expect(responsemintLicenseTokenD.txHash).to.be.a("string").and.not.empty; - expect(responsemintLicenseTokenD.licenseTokenId).to.be.a("bigint").and.to.be.ok; + expect(responsemintLicenseTokenD.licenseTokenIds).to.be.a("array").and.to.have.lengthOf(2); - licenseTokenIdD = responsemintLicenseTokenD.licenseTokenId; + licenseTokenIdD = responsemintLicenseTokenD.licenseTokenIds[0]; }); it("Register a derivative IP asset fail as non-owner", async function () { @@ -124,13 +124,13 @@ describe('SDK Test', function () { let ipIdB: any; await expect( registerDerivativeWithLicenseTokens("B", ipIdB, [licenseTokenIdA], true) - ).to.be.rejectedWith("Failed to register derivative with license tokens: Address \"undefined\" is invalid."); + ).to.be.rejectedWith(`Failed to register derivative with license tokens: ipId address is invalid: undefined, Address must be a hex value of 20 bytes (40 hex characters) and match its checksum counterpart.`); }); it("Register a derivative IP asset fail as invalid child ipId", async function () { await expect( registerDerivativeWithLicenseTokens("B", "0x0000", [licenseTokenIdA], true) - ).to.be.rejectedWith("Failed to register derivative with license tokens: Address \"0x0000\" is invalid."); + ).to.be.rejectedWith(`Failed to register derivative with license tokens: ipId address is invalid: 0x0000, Address must be a hex value of 20 bytes (40 hex characters) and match its checksum counterpart.`); }); it("Register a derivative IP asset fail as non-existent child ipId", async function () { @@ -152,10 +152,11 @@ describe('SDK Test', function () { ).to.be.rejectedWith("Failed to register derivative with license tokens: Cannot convert test to a BigInt"); }); + // 0xd474000f - LicenseToken__NotLicenseTokenOwner(uint256,address,address) it("Register a derivative IP asset fail as non-existent licenseTokenId", async function () { await expect( registerDerivativeWithLicenseTokens("B", ipIdB, ["999"], true) - ).to.be.rejectedWith("Failed to register derivative with license tokens: The contract function \"ownerOf\" reverted."); + ).to.be.rejectedWith(`Failed to register derivative with license tokens: The contract function "registerDerivativeWithLicenseTokens" reverted with the following signature:`, `0xd474000f`); }); it("Register a derivative IP asset fail as LicenseTokenNotCompatibleForDerivative", async function () { diff --git a/test/ipAsset/registerIpAndAttachPilTerms.test.ts b/test/ipAsset/registerIpAndAttachPilTerms.test.ts index c2d75a6..26d04a6 100644 --- a/test/ipAsset/registerIpAndAttachPilTerms.test.ts +++ b/test/ipAsset/registerIpAndAttachPilTerms.test.ts @@ -43,13 +43,13 @@ describe('SDK Test', function () { let nftContractAddress: any; await expect( registerIpAndAttachPilTerms("A", nftContractAddress, tokenIdA, PIL_TYPE.NON_COMMERCIAL_REMIX, true) - ).to.be.rejectedWith(`Failed to register IP and attach PIL terms: Address "undefined" is invalid.`); + ).to.be.rejectedWith(`Failed to register IP and attach PIL terms: nftContract address is invalid: undefined, Address must be a hex value of 20 bytes (40 hex characters) and match its checksum counterpart.`); }); it("Register IP and attach PilTerms fail as invalid NFT contract address", async function () { await expect( registerIpAndAttachPilTerms("A", "0x0000", tokenIdA, PIL_TYPE.NON_COMMERCIAL_REMIX, true) - ).to.be.rejectedWith(`Failed to register IP and attach PIL terms: Address "0x0000" is invalid.`); + ).to.be.rejectedWith(`Failed to register IP and attach PIL terms: nftContract address is invalid: 0x0000, Address must be a hex value of 20 bytes (40 hex characters) and match its checksum counterpart.`); }); // 0x1033cd88: IPAssetRegistry__UnsupportedIERC721(address) diff --git a/test/license/attachLicenseTerms.test.ts b/test/license/attachLicenseTerms.test.ts index b59990d..dc13e02 100644 --- a/test/license/attachLicenseTerms.test.ts +++ b/test/license/attachLicenseTerms.test.ts @@ -57,7 +57,7 @@ describe("SDK Test", function () { let ipId: any; const response = await expect( attachLicenseTerms("A", ipId, comUseLicenseTermsId1, true) - ).to.be.rejectedWith("Address \"undefined\" is invalid."); + ).to.be.rejectedWith(`Failed to attach license terms: request.ipId address is invalid: undefined, Address must be a hex value of 20 bytes (40 hex characters) and match its checksum counterpart.`); }); it("Attach license terms with an invalid ipId", async function () { diff --git a/test/license/getLicenseTerms.test.ts b/test/license/getLicenseTerms.test.ts index b4035fe..6738ec2 100644 --- a/test/license/getLicenseTerms.test.ts +++ b/test/license/getLicenseTerms.test.ts @@ -89,7 +89,7 @@ describe("SDK Test", function () { expect(response.terms.derivativesApproval).to.be.a("boolean").and.to.be.false; expect(response.terms.derivativesReciprocal).to.be.a("boolean").and.to.be.true; expect(response.terms.mintingFee).to.be.a("bigint").and.to.be.equal(BigInt(mintingFee1)); - expect(response.terms.commercialRevShare).to.be.a("number").and.to.be.equal(commercialRevShare1); + expect(response.terms.commercialRevShare).to.be.a("number").and.to.be.equal(commercialRevShare1 * 1000000); expect(response.terms.expiration).to.be.a("bigint").and.to.be.equal(0n); }); }); diff --git a/test/license/mintLicenseTokens.test.ts b/test/license/mintLicenseTokens.test.ts index a580954..1bdb2ff 100644 --- a/test/license/mintLicenseTokens.test.ts +++ b/test/license/mintLicenseTokens.test.ts @@ -55,13 +55,13 @@ describe('SDK Test', function () { let ipIdA: any; const response = await expect( mintLicenseTokens("A", ipIdA, nonComLicenseTermsId, 2, accountB.address, true) - ).to.be.rejectedWith("Failed to mint license tokens: Address \"undefined\" is invalid."); + ).to.be.rejectedWith(`Failed to mint license tokens: request.licensorIpId address is invalid: undefined, Address must be a hex value of 20 bytes (40 hex characters) and match its checksum counterpart.`); }); it("Mint a license token fail as invalid ipId", async function () { const response = await expect( mintLicenseTokens("A", "0x0000", nonComLicenseTermsId, 2, accountB.address, true) - ).to.be.rejectedWith("Failed to mint license tokens: Address \"0x0000\" is invalid."); + ).to.be.rejectedWith(`Failed to mint license tokens: request.licensorIpId address is invalid: 0x0000, Address must be a hex value of 20 bytes (40 hex characters) and match its checksum counterpart.`); }); it("Mint a license token fail as non-existent ipId", async function () { @@ -99,7 +99,7 @@ describe('SDK Test', function () { it("Mint a license token fail as invalid receiver address", async function () { const response = await expect( mintLicenseTokens("A", ipIdA, nonComLicenseTermsId, 2, "0x0000", true) - ).to.be.rejectedWith("Failed to mint license tokens: Address \"0x0000\" is invalid."); + ).to.be.rejectedWith(`Failed to mint license tokens: request.receiver address is invalid: 0x0000, Address must be a hex value of 20 bytes (40 hex characters) and match its checksum counterpart.`); }); it("Mint a license token fail as not attached licenseTermsId", async function () { @@ -117,7 +117,7 @@ describe('SDK Test', function () { ).to.not.be.rejected; expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.licenseTokenId).to.be.a("bigint").and.to.be.ok; + expect(response.licenseTokenIds).to.be.a("array").and.to.have.lengthOf(1); }); it("Mint a license token with amount: 0", async function () { @@ -126,7 +126,7 @@ describe('SDK Test', function () { ).to.not.be.rejected; expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.licenseTokenId).to.be.a("bigint").and.to.be.ok; + expect(response.licenseTokenIds).to.be.a("array").and.to.have.lengthOf(1); }); it("Mint a license token by non-owner", async function () { @@ -135,7 +135,7 @@ describe('SDK Test', function () { ).to.not.be.rejected; expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.licenseTokenId).to.be.a("bigint").and.to.be.ok; + expect(response.licenseTokenIds).to.be.a("array").and.to.have.lengthOf(2); }); it("Mint a license token with undefined receiver address", async function () { @@ -145,7 +145,7 @@ describe('SDK Test', function () { ).to.not.be.rejected; expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.licenseTokenId).to.be.a("bigint").and.to.be.ok; + expect(response.licenseTokenIds).to.be.a("array").and.to.have.lengthOf(2); }); it("Mint a license token with waitForTransaction:true", async function () { @@ -154,7 +154,7 @@ describe('SDK Test', function () { ).to.not.be.rejected; expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.licenseTokenId).to.be.a("bigint").and.to.be.ok; + expect(response.licenseTokenIds).to.be.a("array").and.to.have.lengthOf(2); }); it("Mint a license token with the same parameters before", async function () { @@ -163,7 +163,7 @@ describe('SDK Test', function () { ).to.not.be.rejected; expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.licenseTokenId).to.be.a("bigint").and.to.be.ok; + expect(response.licenseTokenIds).to.be.a("array").and.to.have.lengthOf(2); }); it("Mint a license token with undefined waitForTransaction", async function () { @@ -203,7 +203,7 @@ describe('SDK Test', function () { ).to.not.be.rejected; expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.licenseTokenId).to.be.a("bigint").and.to.be.ok; + expect(response.licenseTokenIds).to.be.a("array").and.to.have.lengthOf(2); }); it("Mint a license token with ipIdB and comUsenonComLicenseTermsId", async function () { @@ -212,7 +212,7 @@ describe('SDK Test', function () { ).to.not.be.rejected; expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.licenseTokenId).to.be.a("bigint").and.to.be.ok; + expect(response.licenseTokenIds).to.be.a("array").and.to.have.lengthOf(2); }); it("Mint a license token with ipIdB and comRemixnonComLicenseTermsId", async function () { @@ -221,7 +221,7 @@ describe('SDK Test', function () { ).to.not.be.rejected; expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.licenseTokenId).to.not.be.exist; + expect(response.licenseTokenIds).to.not.be.exist; }); }); }); diff --git a/test/license/registerPIL.test.ts b/test/license/registerPIL.test.ts index 31230fe..9a36b1a 100644 --- a/test/license/registerPIL.test.ts +++ b/test/license/registerPIL.test.ts @@ -124,7 +124,13 @@ describe("SDK Test", function () { it("Register Commercial Remix PIL with an invalid commercialRevShare value (-1)", async function () { const response = await expect( registerCommercialRemixPIL("A", "0", -1, mintingFeeTokenAddress, true) - ).to.be.rejectedWith("Failed to register commercial remix PIL: Number \"-1\" is not in safe 256-bit unsigned integer range"); + ).to.be.rejectedWith("Failed to register commercial remix PIL: commercialRevShare should be between 0 and 100."); + }); + + it("Register Commercial Remix PIL with an invalid commercialRevShare value (101)", async function () { + const response = await expect( + registerCommercialRemixPIL("A", "0", 101, mintingFeeTokenAddress, true) + ).to.be.rejectedWith("Failed to register commercial remix PIL: commercialRevShare should be between 0 and 100."); }); it("Register Commercial Remix PIL with currency: undefined", async function () { @@ -163,7 +169,7 @@ describe("SDK Test", function () { it("Register Commercial Remix PIL with waitForTransaction: false", async function () { const response = await expect( - registerCommercialRemixPIL("A", "16", 1001, mintingFeeTokenAddress, false) + registerCommercialRemixPIL("A", "16", 100, mintingFeeTokenAddress, false) ).to.not.be.rejected; if (response.licenseTermsId) { diff --git a/test/nftClient/createNFTCollection.test.ts b/test/nftClient/createNFTCollection.test.ts index 19fbd15..e1ea9af 100644 --- a/test/nftClient/createNFTCollection.test.ts +++ b/test/nftClient/createNFTCollection.test.ts @@ -61,7 +61,7 @@ describe("SDK Test", function () { expect(response.nftContract).to.be.a("string").and.not.empty; }); - it("Create NFT collection with mintCost and invalid mintToken", async function () { + it.skip("Create NFT collection with mintCost and invalid mintToken", async function () { let mintToken: any; const options = { maxSupply: 10n, @@ -106,7 +106,7 @@ describe("SDK Test", function () { ).to.be.rejectedWith("Failed to create a SPG NFT collection: Cannot convert test to a BigInt"); }); - it("Create NFT collection with invalid type for mintCost", async function () { + it.skip("Create NFT collection with invalid type for mintCost", async function () { const options = { mintCost: "test" }; @@ -116,7 +116,7 @@ describe("SDK Test", function () { ).to.be.rejectedWith("Failed to create a SPG NFT collection: Cannot convert test to a BigInt"); }); - it("Create NFT collection with invalid type for mintToken", async function () { + it.skip("Create NFT collection with invalid type for mintToken", async function () { const options = { mintToken: "test" }; @@ -126,7 +126,7 @@ describe("SDK Test", function () { ).to.be.rejectedWith("Failed to create a SPG NFT collection: Address \"test\" is invalid."); }); - it("Create NFT collection with mintToken: 0x0000", async function () { + it.skip("Create NFT collection with mintToken: 0x0000", async function () { const options = { mintToken: "0x0000" }; @@ -143,7 +143,7 @@ describe("SDK Test", function () { const response = await expect( createNFTCollection("A", "sdk-e2e-test", "test", true, options) - ).to.be.rejectedWith("Failed to create a SPG NFT collection: Address \"test\" is invalid."); + ).to.be.rejectedWith(`Failed to create a SPG NFT collection: request.owner address is invalid: test, Address must be a hex value of 20 bytes (40 hex characters) and match its checksum counterpart.`); }); it("Create NFT collection with owner: 0x0000", async function () { @@ -153,7 +153,7 @@ describe("SDK Test", function () { const response = await expect( createNFTCollection("A", "sdk-e2e-test", "test", true, options) - ).to.be.rejectedWith("Failed to create a SPG NFT collection: Address \"0x0000\" is invalid."); + ).to.be.rejectedWith(`Failed to create a SPG NFT collection: request.owner address is invalid: 0x0000, Address must be a hex value of 20 bytes (40 hex characters) and match its checksum counterpart.`); }); }); }); diff --git a/test/permission/permission.test.ts b/test/permission/permission.test.ts index b5a0534..4bd5dec 100644 --- a/test/permission/permission.test.ts +++ b/test/permission/permission.test.ts @@ -30,27 +30,27 @@ describe('SDK Test', function () { it("Non-owner set permission", async function () { const response = await expect( setPermission("B", ipIdA, accountB.address, licensingModuleAddress, 1, true) - ).to.be.rejectedWith("Failed to set permissions: The contract function \"execute\" reverted with the following signature:", - "0xb3e96921"); + ).to.be.rejectedWith(`Failed to set permissions: The contract function "setPermission" reverted.`, + `Error: AccessController__CallerIsNotIPAccountOrOwner()`); }); it("Set permission with an empty IP id", async function () { let testIpId:any; const response = await expect( setPermission("A", testIpId, accountB.address, licensingModuleAddress, 1, true) - ).to.be.rejectedWith("Failed to set permissions: Address \"undefined\" is invalid."); + ).to.be.rejectedWith(`Failed to set permissions: ipId address is invalid: undefined, Address must be a hex value of 20 bytes (40 hex characters) and match its checksum counterpart.`); }); it("Set permission with a non-existent IP id", async function () { const response = await expect( setPermission("B", "0x1954631f55AC9a79CC4ec57103D23A9b2e8aDBfa", accountB.address, licensingModuleAddress, 1, true) - ).to.be.rejectedWith("Failed to set permissions: The contract function \"execute\" returned no data (\"0x\")."); + ).to.be.rejectedWith(`Failed to set permissions: IP id with 0x1954631f55AC9a79CC4ec57103D23A9b2e8aDBfa is not registered.`); }); it("Set permission with an invalid IP id", async function () { const response = await expect( setPermission("A", "0x00000", accountB.address, licensingModuleAddress, 1, true) - ).to.be.rejectedWith("Failed to set permissions: Address \"0x00000\" is invalid."); + ).to.be.rejectedWith(`Failed to set permissions: ipId address is invalid: 0x00000, Address must be a hex value of 20 bytes (40 hex characters) and match its checksum counterpart.`); }); it("Set permission with an empty signer address", async function () { @@ -88,8 +88,8 @@ describe('SDK Test', function () { it("Set permission with an invalid permission id (4)", async function () { const response = await expect( setPermission("A", ipIdA, accountB.address, licensingModuleAddress, 4, true) - ).to.be.rejectedWith("Failed to set permissions: The contract function \"execute\" reverted with the following signature:", - "0x07e5a971"); + ).to.be.rejectedWith(`Failed to set permissions: The contract function "setPermission" reverted.`, + `Error: AccessController__PermissionIsNotValid()`); }); it("Set permission (permission id: 1) to wallet B", async function () { diff --git a/test/royalty/claimRevenue.test.ts b/test/royalty/claimRevenue.test.ts index 3b205b5..33652ec 100644 --- a/test/royalty/claimRevenue.test.ts +++ b/test/royalty/claimRevenue.test.ts @@ -71,19 +71,19 @@ describe("SDK Test", function () { it("Claim revenue fail as undefined snapshotId", async function () { let snapshotId: any; const response = await expect( - royaltyClaimRevenue("A", [snapshotId], ipIdA, ipIdA, mintingFeeTokenAddress, waitForTransaction) + royaltyClaimRevenue("A", [snapshotId], ipIdA, mintingFeeTokenAddress, ipIdA, waitForTransaction) ).to.be.rejectedWith("Failed to claim revenue: Cannot convert undefined to a BigInt"); }); it("Claim revenue fail as invalid snapshotId", async function () { const response = await expect( - royaltyClaimRevenue("A", ["test"], ipIdA, ipIdA, mintingFeeTokenAddress, waitForTransaction) + royaltyClaimRevenue("A", ["test"], ipIdA, mintingFeeTokenAddress, ipIdA, waitForTransaction) ).to.be.rejectedWith("Failed to claim revenue: Cannot convert test to a BigInt"); }); it("Claim revenue fail as non-existent snapshotId", async function () { const response = await expect( - royaltyClaimRevenue("A", ["999"], ipIdA, ipIdA, mintingFeeTokenAddress, waitForTransaction) + royaltyClaimRevenue("A", ["999"], ipIdA, mintingFeeTokenAddress, ipIdA, waitForTransaction) ).to.be.rejectedWith("Failed to claim revenue: Failed to execute the IP Account transaction: The contract function \"execute\" reverted with the following reason:", "ERC20Snapshot: nonexistent id"); }); @@ -91,26 +91,26 @@ describe("SDK Test", function () { it("Claim revenue fail as undefined royaltyVaultIpId", async function () { let royaltyVaultIpId: any; const response = await expect( - royaltyClaimRevenue("A", [snapshotId1], royaltyVaultIpId, ipIdA, mintingFeeTokenAddress, waitForTransaction) - ).to.be.rejectedWith("Failed to claim revenue: Address \"undefined\" is invalid."); + royaltyClaimRevenue("A", [snapshotId1], royaltyVaultIpId, mintingFeeTokenAddress, ipIdA, waitForTransaction) + ).to.be.rejectedWith(`Failed to claim revenue: request.royaltyVaultIpId address is invalid: undefined, Address must be a hex value of 20 bytes (40 hex characters) and match its checksum counterpart.`); }); it("Claim revenue fail as invalid royaltyVaultIpId", async function () { const response = await expect( - royaltyClaimRevenue("A", [snapshotId1], "0x0000", ipIdA, mintingFeeTokenAddress, waitForTransaction) - ).to.be.rejectedWith("Failed to claim revenue: Address \"0x0000\" is invalid."); + royaltyClaimRevenue("A", [snapshotId1], "0x0000", mintingFeeTokenAddress, ipIdA, waitForTransaction) + ).to.be.rejectedWith(`Failed to claim revenue: request.royaltyVaultIpId address is invalid: 0x0000, Address must be a hex value of 20 bytes (40 hex characters) and match its checksum counterpart.`); }); it("Claim revenue fail as non-existent royaltyVaultIpId", async function () { const response = await expect( - royaltyClaimRevenue("A", [snapshotId1], "0xe967f54D03acc01CF624b54e0F24794a2f8f229b", ipIdA, mintingFeeTokenAddress, waitForTransaction) + royaltyClaimRevenue("A", [snapshotId1], "0xe967f54D03acc01CF624b54e0F24794a2f8f229b", mintingFeeTokenAddress, ipIdA, waitForTransaction) ).to.be.rejectedWith("Failed to claim revenue: The royalty vault IP with id 0xE967F54d03aCC01Cf624b54E0f24794A2F8F229b is not registered."); }); it("Claim revenue with undefined account address", async function () { let accountAddress: any; const response = await expect( - royaltyClaimRevenue("A", [snapshotId1], ipIdA, accountAddress, mintingFeeTokenAddress, waitForTransaction) + royaltyClaimRevenue("A", [snapshotId1], ipIdA, mintingFeeTokenAddress, accountAddress, waitForTransaction) ).to.not.be.rejected; expect(response.txHash).to.be.a("string").and.not.empty; @@ -119,39 +119,38 @@ describe("SDK Test", function () { it("Claim revenue fail as invalid account address", async function () { const response = await expect( - royaltyClaimRevenue("A", [snapshotId1], ipIdA, "0x00000", mintingFeeTokenAddress, waitForTransaction) - ).to.be.rejectedWith("Failed to claim revenue: Address \"0x00000\" is invalid."); + royaltyClaimRevenue("A", [snapshotId1], ipIdA, mintingFeeTokenAddress, "0x00000", waitForTransaction) + ).to.be.rejectedWith(`ailed to claim revenue: request.account address is invalid: 0x00000, Address must be a hex value of 20 bytes (40 hex characters) and match its checksum counterpart.`); }); it("Claim revenue fail as non-existent account address", async function () { const response = await expect( - royaltyClaimRevenue("A", [snapshotId1], ipIdA, "0xe967f54D03acc01CF624b54e0F24794a2f8f229c", mintingFeeTokenAddress, waitForTransaction) + royaltyClaimRevenue("A", [snapshotId1], ipIdA, mintingFeeTokenAddress, "0xe967f54D03acc01CF624b54e0F24794a2f8f229c", waitForTransaction) ).to.be.rejectedWith("Failed to claim revenue: Failed to execute the IP Account transaction: The contract function \"execute\" returned no data (\"0x\")."); }); it("Claim revenue fail as undefined token address", async function () { let tokenAddress: any; const response = await expect( - royaltyClaimRevenue("A", [snapshotId1], ipIdA, ipIdA, tokenAddress, waitForTransaction) + royaltyClaimRevenue("A", [snapshotId1], ipIdA, tokenAddress, ipIdA, waitForTransaction) ).to.be.rejectedWith("Failed to claim revenue: Address \"undefined\" is invalid."); }); it("Claim revenue fail as invalid token address", async function () { const response = await expect( - royaltyClaimRevenue("A", [snapshotId1], ipIdA, ipIdA, "0x0000", waitForTransaction) + royaltyClaimRevenue("A", [snapshotId1], ipIdA, "0x0000", ipIdA, waitForTransaction) ).to.be.rejectedWith("Failed to claim revenue: Address \"0x0000\" is invalid."); }); it("Claim revenue fail as non-existent token address", async function () { const response = await expect( - royaltyClaimRevenue("A", [snapshotId1], ipIdA, ipIdA, "0xe967f54D03acc01CF624b54e0F24794a2f8f229c", waitForTransaction) - ).to.be.rejectedWith("Failed to claim revenue: Failed to execute the IP Account transaction: The contract function \"execute\" reverted with the following reason:", - "Address: call to non-contract"); + royaltyClaimRevenue("A", [snapshotId1], ipIdA, "0xe967f54D03acc01CF624b54e0F24794a2f8f229c", ipIdA, waitForTransaction) + ).to.be.rejectedWith(`Failed to claim revenue: Address "0xe967f54D03acc01CF624b54e0F24794a2f8f229c" is invalid.`); }); it("Claim revenue with waitForTransaction: true", async function () { const response = await expect( - royaltyClaimRevenue("A", [snapshotId1], ipIdA, ipIdA, mintingFeeTokenAddress, true) + royaltyClaimRevenue("A", [snapshotId1], ipIdA, mintingFeeTokenAddress, ipIdA, true) ).to.not.be.rejected; expect(response.txHash).to.be.a("string").and.not.empty; @@ -160,7 +159,7 @@ describe("SDK Test", function () { it("Claim revenue with waitForTransaction: false", async function () { const response = await expect( - royaltyClaimRevenue("A", [snapshotId1], ipIdA, ipIdA, mintingFeeTokenAddress, false) + royaltyClaimRevenue("A", [snapshotId1], ipIdA, mintingFeeTokenAddress, ipIdA, false) ).to.not.be.rejected; expect(response.txHash).to.be.a("string").and.not.empty; @@ -170,7 +169,7 @@ describe("SDK Test", function () { it("Claim revenue with waitForTransaction: undefined", async function () { let waitForTransaction: any; const response = await expect( - royaltyClaimRevenue("A", [snapshotId1], ipIdA, ipIdA, mintingFeeTokenAddress, waitForTransaction) + royaltyClaimRevenue("A", [snapshotId1], ipIdA, mintingFeeTokenAddress, ipIdA, waitForTransaction) ).to.not.be.rejected; expect(response.txHash).to.be.a("string").and.not.empty; @@ -179,7 +178,7 @@ describe("SDK Test", function () { it("Claim revenue fail by non-owner", async function () { const response = await expect( - royaltyClaimRevenue("B", [snapshotId1], ipIdA, ipIdA, mintingFeeTokenAddress, waitForTransaction) + royaltyClaimRevenue("B", [snapshotId1], ipIdA, mintingFeeTokenAddress, ipIdA, waitForTransaction) ).to.be.rejectedWith("Failed to claim revenue: Failed to execute the IP Account transaction: The contract function \"execute\" reverted with the following signature:", "0x8ea0b111"); }); }); diff --git a/test/royalty/claimableRevenue.test.ts b/test/royalty/claimableRevenue.test.ts index cd6892d..7564351 100644 --- a/test/royalty/claimableRevenue.test.ts +++ b/test/royalty/claimableRevenue.test.ts @@ -72,13 +72,13 @@ describe("SDK Test", function () { let royaltyVaultIpId: any; const response = await expect( royaltyClaimableRevenue("A", royaltyVaultIpId, ipIdA, snapshotId1, mintingFeeTokenAddress, waitForTransaction) - ).to.be.rejectedWith("Failed to calculate claimable revenue: Address \"undefined\" is invalid."); + ).to.be.rejectedWith(`ailed to calculate claimable revenue: request.royaltyVaultIpId address is invalid: undefined, Address must be a hex value of 20 bytes (40 hex characters) and match its checksum counterpart.`); }); it("Check claimable revenue fail as invalid parentIpId", async function () { const response = await expect( royaltyClaimableRevenue("A", "0x0000", ipIdA, "1", mintingFeeTokenAddress, waitForTransaction) - ).to.be.rejectedWith("Failed to calculate claimable revenue: Address \"0x0000\" is invalid."); + ).to.be.rejectedWith(`Failed to calculate claimable revenue: request.royaltyVaultIpId address is invalid: 0x0000, Address must be a hex value of 20 bytes (40 hex characters) and match its checksum counterpart.`); }); it("Check claimable revenue fail as non-existent parentIpId", async function () { @@ -91,13 +91,13 @@ describe("SDK Test", function () { let account: any; const response = await expect( royaltyClaimableRevenue("A", ipIdA, account, "1", mintingFeeTokenAddress, waitForTransaction) - ).to.be.rejectedWith("Failed to calculate claimable revenue: Address \"undefined\" is invalid."); + ).to.be.rejectedWith(`Failed to calculate claimable revenue: request.account address is invalid: undefined, Address must be a hex value of 20 bytes (40 hex characters) and match its checksum counterpart.`); }); it("Check claimable revenue fail as invalid account address", async function () { const response = await expect( royaltyClaimableRevenue("A", ipIdA, "0x0000", "1", mintingFeeTokenAddress, waitForTransaction) - ).to.be.rejectedWith("Failed to calculate claimable revenue: Address \"0x0000\" is invalid."); + ).to.be.rejectedWith(`Failed to calculate claimable revenue: request.account address is invalid: 0x0000, Address must be a hex value of 20 bytes (40 hex characters) and match its checksum counterpart.`); }); it("Check claimable revenue fail as undefined snapshotId", async function () { @@ -137,13 +137,13 @@ describe("SDK Test", function () { let tokenAddress: any; const response = await expect( royaltyClaimableRevenue("A", ipIdA, ipIdA, snapshotId1, tokenAddress, waitForTransaction) - ).to.be.rejectedWith("Failed to calculate claimable revenue: Address \"undefined\" is invalid."); + ).to.be.rejectedWith(`Failed to calculate claimable revenue: request.token address is invalid: undefined, Address must be a hex value of 20 bytes (40 hex characters) and match its checksum counterpart.`); }); it("Check claimable revenue fail as invalid token address", async function () { const response = await expect( royaltyClaimableRevenue("A", ipIdA, ipIdA, snapshotId1, "0x0000", waitForTransaction) - ).to.be.rejectedWith("Failed to calculate claimable revenue: Address \"0x0000\" is invalid."); + ).to.be.rejectedWith(`Failed to calculate claimable revenue: request.token address is invalid: 0x0000, Address must be a hex value of 20 bytes (40 hex characters) and match its checksum counterpart.`); }); it("Check claimable revenue with waitForTransaction: undefined", async function () { diff --git a/test/royalty/collectRoyaltyTokens.test.ts b/test/royalty/collectRoyaltyTokens.test.ts index 7687f0f..f2bc3f0 100644 --- a/test/royalty/collectRoyaltyTokens.test.ts +++ b/test/royalty/collectRoyaltyTokens.test.ts @@ -83,13 +83,13 @@ describe("SDK Test", function () { let parentIpId: any; const response = await expect( collectRoyaltyTokens("B", parentIpId, ipIdB, waitForTransaction) - ).to.be.rejectedWith("Failed to collect royalty tokens: Address \"undefined\" is invalid."); + ).to.be.rejectedWith(`Failed to collect royalty tokens: request.parentIpId address is invalid: undefined, Address must be a hex value of 20 bytes (40 hex characters) and match its checksum counterpart.`); }); it("Collect royalty tokens fail as invalid parentIpId", async function () { const response = await expect( collectRoyaltyTokens("B", "0x0000", ipIdB, waitForTransaction) - ).to.be.rejectedWith("Failed to collect royalty tokens: Address \"0x0000\" is invalid."); + ).to.be.rejectedWith(`Failed to collect royalty tokens: request.parentIpId address is invalid: 0x0000, Address must be a hex value of 20 bytes (40 hex characters) and match its checksum counterpart.`); }); it("Collect royalty tokens fail as non-existent parentIpId", async function () { @@ -102,13 +102,13 @@ describe("SDK Test", function () { let royaltyVaultIpId: any; const response = await expect( collectRoyaltyTokens("B", ipIdA, royaltyVaultIpId, waitForTransaction) - ).to.be.rejectedWith("Failed to collect royalty tokens: Address \"undefined\" is invalid."); + ).to.be.rejectedWith(`Failed to collect royalty tokens: request.royaltyVaultIpId address is invalid: undefined, Address must be a hex value of 20 bytes (40 hex characters) and match its checksum counterpart.`); }); it("Collect royalty tokens fail as invalid royaltyVaultIpId", async function () { const response = await expect( collectRoyaltyTokens("B", ipIdA, "0x0000", waitForTransaction) - ).to.be.rejectedWith("Failed to collect royalty tokens: Address \"0x0000\" is invalid."); + ).to.be.rejectedWith(`Failed to collect royalty tokens: request.royaltyVaultIpId address is invalid: 0x0000, Address must be a hex value of 20 bytes (40 hex characters) and match its checksum counterpart.`); }); it("Collect royalty tokens fail as non-existent royaltyVaultIpId", async function () { @@ -123,7 +123,7 @@ describe("SDK Test", function () { ).to.not.be.rejected; expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.royaltyTokensCollected).to.be.a("bigint").and.equal(BigInt(commercialRevShare1)); + expect(response.royaltyTokensCollected).to.be.a("bigint").and.equal(BigInt(commercialRevShare1 * 1000000)); }); it("Collect royalty tokens fail as already claimed", async function () { @@ -154,7 +154,7 @@ describe("SDK Test", function () { ).to.not.be.rejected; expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.royaltyTokensCollected).to.be.a("bigint").and.equal(BigInt(commercialRevShare2)); + expect(response.royaltyTokensCollected).to.be.a("bigint").and.equal(BigInt(commercialRevShare2 * 1000000)); }); it("Collect royalty tokens for derivative IP attached multiple license terms", async function () { @@ -178,7 +178,7 @@ describe("SDK Test", function () { ).to.not.be.rejected; expect(response.txHash).to.be.a("string").and.not.empty; - expect(response.royaltyTokensCollected).to.be.a("bigint").and.equal(BigInt(commercialRevShare1 + commercialRevShare2)); + expect(response.royaltyTokensCollected).to.be.a("bigint").and.equal(BigInt((commercialRevShare1 + commercialRevShare2) * 1000000)); }); it("Collect royalty tokens fail as royaltyVaultIpId is not derivative IP", async function () { diff --git a/test/royalty/payRoyaltyOnBehalf.test.ts b/test/royalty/payRoyaltyOnBehalf.test.ts index a10b361..66d379a 100644 --- a/test/royalty/payRoyaltyOnBehalf.test.ts +++ b/test/royalty/payRoyaltyOnBehalf.test.ts @@ -71,13 +71,13 @@ describe("SDK Test", function () { let receiverIpId: any; const response = await expect( payRoyaltyOnBehalf("B", receiverIpId, ipIdB, mintingFeeTokenAddress, "100", waitForTransaction) - ).to.be.rejectedWith("Failed to pay royalty on behalf: Address \"undefined\" is invalid."); + ).to.be.rejectedWith(`Failed to pay royalty on behalf: request.receiverIpId address is invalid: undefined, Address must be a hex value of 20 bytes (40 hex characters) and match its checksum counterpart.`); }); it("Pay royalty on behalf fail as invalid receiverIpId", async function () { const response = await expect( payRoyaltyOnBehalf("B", "0x0000", ipIdB, mintingFeeTokenAddress, "100", waitForTransaction) - ).to.be.rejectedWith("Failed to pay royalty on behalf: Address \"0x0000\" is invalid."); + ).to.be.rejectedWith(`Failed to pay royalty on behalf: request.receiverIpId address is invalid: 0x0000, Address must be a hex value of 20 bytes (40 hex characters) and match its checksum counterpart.`); }); it("Pay royalty on behalf fail as non-existent receiverIpId", async function () { @@ -90,13 +90,13 @@ describe("SDK Test", function () { let payerIpId: any; const response = await expect( payRoyaltyOnBehalf("B", ipIdA, payerIpId, mintingFeeTokenAddress, "100", waitForTransaction) - ).to.be.rejectedWith("Failed to pay royalty on behalf: Address \"undefined\" is invalid."); + ).to.be.rejectedWith(`Failed to pay royalty on behalf: request.payerIpId address is invalid: undefined, Address must be a hex value of 20 bytes (40 hex characters) and match its checksum counterpart.`); }); it("Pay royalty on behalf fail as invalid payerIpId", async function () { const response = await expect( payRoyaltyOnBehalf("B", ipIdA, "0x0000", mintingFeeTokenAddress, "100", waitForTransaction) - ).to.be.rejectedWith("Failed to pay royalty on behalf: Address \"0x0000\" is invalid."); + ).to.be.rejectedWith(`Failed to pay royalty on behalf: request.payerIpId address is invalid: 0x0000, Address must be a hex value of 20 bytes (40 hex characters) and match its checksum counterpart.`); }); it("Pay royalty on behalf fail as non-existent payerIpId", async function () { @@ -109,13 +109,13 @@ describe("SDK Test", function () { let mintingFeeTokenAddress: any; const response = await expect( payRoyaltyOnBehalf("B", ipIdA, ipIdB, mintingFeeTokenAddress, "100", waitForTransaction) - ).to.be.rejectedWith("Failed to pay royalty on behalf: Address \"undefined\" is invalid."); + ).to.be.rejectedWith(`Failed to pay royalty on behalf: request.token address is invalid: undefined, Address must be a hex value of 20 bytes (40 hex characters) and match its checksum counterpart.`); }); it("Pay royalty on behalf fail as invalid token address", async function () { const response = await expect( payRoyaltyOnBehalf("B", ipIdA, ipIdB, "0x0000", "100", waitForTransaction) - ).to.be.rejectedWith("Failed to pay royalty on behalf: Address \"0x0000\" is invalid"); + ).to.be.rejectedWith(`Failed to pay royalty on behalf: request.token address is invalid: 0x0000, Address must be a hex value of 20 bytes (40 hex characters) and match its checksum counterpart.`); }); it("Pay royalty on behalf fail as non-existent token address", async function () { diff --git a/test/royalty/snapshot.test.ts b/test/royalty/snapshot.test.ts index 1ddec96..6061c6e 100644 --- a/test/royalty/snapshot.test.ts +++ b/test/royalty/snapshot.test.ts @@ -74,14 +74,14 @@ describe("SDK Test", function () { let ipIdA: any; const response = await expect( royaltySnapshot("A", ipIdA, waitForTransaction) - ).to.be.rejectedWith("Failed to snapshot: Address \"undefined\" is invalid."); + ).to.be.rejectedWith(`Failed to snapshot: request.royaltyVaultIpId address is invalid: undefined, Address must be a hex value of 20 bytes (40 hex characters) and match its checksum counterpart.`); }); it("Captue snapshot fail as invalid ipId", async function () { const response = await expect( royaltySnapshot("A", "0x0000", waitForTransaction) - ).to.be.rejectedWith("Failed to snapshot: Address \"0x0000\" is invalid."); + ).to.be.rejectedWith(`Failed to snapshot: request.royaltyVaultIpId address is invalid: 0x0000, Address must be a hex value of 20 bytes (40 hex characters) and match its checksum counterpart.`); }); diff --git a/test/setup.ts b/test/setup.ts index d8ee5e4..4e33975 100644 --- a/test/setup.ts +++ b/test/setup.ts @@ -24,8 +24,9 @@ afterEach(function () { if (consoleLogs.length > 0) { addContext(this, { title: 'Test Result', - value: consoleLogs[0], + value: consoleLogs.join('\n'), }); + consoleLogs = []; }; }); diff --git a/test/testUtils.ts b/test/testUtils.ts new file mode 100644 index 0000000..c0d3a9c --- /dev/null +++ b/test/testUtils.ts @@ -0,0 +1,213 @@ +import { nftContractAddress, mintingFeeTokenAddress} from '../config/config' +import { checkMintResult, mintNFTWithRetry } from '../utils/utils' +import { registerIpAsset, attachLicenseTerms, registerDerivative, royaltySnapshot, collectRoyaltyTokens, royaltyClaimableRevenue, royaltyClaimRevenue, getRoyaltyVaultAddress, ipAccountExecute, storyClients, ipAccountExecuteWithSig } from '../utils/sdkUtils' +import { expect } from 'chai' + +import chai from 'chai'; +import chaiAsPromised from 'chai-as-promised'; +chai.use(chaiAsPromised); +import { Address, Hex, encodeFunctionData } from 'viem'; + +const waitForTransaction: boolean = true; + +export const mintNFTCreateRootIPandAttachPIL = async function( + wallet: keyof typeof storyClients, + walletPrivateKey: Address, + licenseTermsId: string | number | bigint +): Promise
{ + const tokenId = await mintNFTWithRetry(walletPrivateKey); + checkMintResult(tokenId); + + const responseRegisterIpAsset = await expect( + registerIpAsset(wallet, nftContractAddress, tokenId, waitForTransaction) + ).to.not.be.rejected; + + expect(responseRegisterIpAsset.txHash).to.be.a("string").and.not.empty; + expect(responseRegisterIpAsset.ipId).to.be.a("string").and.not.empty; + + const ipId = responseRegisterIpAsset.ipId; + + const responseAttachLicenseTerms = await expect( + attachLicenseTerms(wallet, ipId, licenseTermsId, waitForTransaction) + ).to.not.be.rejected; + + expect(responseAttachLicenseTerms.txHash).to.be.a("string").and.not.empty; + + return ipId; +}; + +export const mintNFTAndRegisterDerivative = async function( + wallet: keyof typeof storyClients, + walletPrivateKey: Address, + parentIpIds: Address[], + licenseTermsIds: string[] | bigint[] | number[] +): Promise
{ + const tokenId = await mintNFTWithRetry(walletPrivateKey); + checkMintResult(tokenId); + + const responseregisterIpAsset = await expect( + registerIpAsset(wallet, nftContractAddress, tokenId, waitForTransaction) + ).to.not.be.rejected; + + expect(responseregisterIpAsset.txHash).to.be.a("string").and.not.empty; + expect(responseregisterIpAsset.ipId).to.be.a("string").and.not.empty; + + const ipId = responseregisterIpAsset.ipId; + + const response = await expect( + registerDerivative(wallet, ipId, parentIpIds, licenseTermsIds, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + + return ipId; +}; + +export const checkRoyaltyTokensCollected = async function( + caller: keyof typeof storyClients, + parentIpId: Address, + royaltyVaultIpId: Address, + expectedRoyaltyTokensCollected: bigint +){ + const responseAFromB = await expect( + collectRoyaltyTokens(caller, parentIpId, royaltyVaultIpId, waitForTransaction) + ).to.not.be.rejected; + + expect(responseAFromB.txHash).to.be.a("string").and.not.empty; + expect(responseAFromB.royaltyTokensCollected).to.be.a('bigint').and.to.be.equal(expectedRoyaltyTokensCollected); +}; + +export const getSnapshotId = async function( + caller: keyof typeof storyClients, + royaltyVaultIpId: Address +): Promise{ + const response = await expect( + royaltySnapshot(caller, royaltyVaultIpId, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + expect(response.snapshotId).to.be.a("bigint").and.to.be.ok; + + const snapshotId = response.snapshotId; + return snapshotId; +}; + +export const checkClaimableRevenue = async function( + caller: keyof typeof storyClients, + royaltyVaultIpId: Address, + account: Address, + snapshotId: bigint, + expectedClaimableRevenue: bigint +){ + const response = await expect( + royaltyClaimableRevenue(caller, royaltyVaultIpId, account, snapshotId, mintingFeeTokenAddress, waitForTransaction) + ).to.not.be.rejected; + + // expect(response).to.be.a("bigint").and.to.be.equal(expectedClaimableRevenue); +}; + +export const claimRevenueByEOA = async function ( + caller: keyof typeof storyClients, + snapshotIds: bigint[], + royaltyVaultIpId: Address, + expectedClaimableToken: bigint +) { + const response = await expect( + royaltyClaimRevenue(caller, snapshotIds, royaltyVaultIpId, mintingFeeTokenAddress, undefined, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + // expect(response.claimableToken).to.be.a("bigint").to.be.equal(expectedClaimableToken); +}; + +export const claimRevenueByIPA = async function ( + caller: keyof typeof storyClients, + snapshotIds: bigint[], + royaltyVaultIpId: Address, + ipAccount: Address, + expectedClaimableToken: bigint +) { + const response = await expect( + royaltyClaimRevenue(caller, snapshotIds, royaltyVaultIpId, mintingFeeTokenAddress, ipAccount, waitForTransaction) + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; + // expect(response.claimableToken).to.be.a("bigint").to.be.equal(expectedClaimableToken); +}; + +export const transferTokenToEOA = async function( + caller: keyof typeof storyClients, + royaltyVaultIpId: Address, + toAddress: Address, + amount: bigint +){ + const royaltyVaultAddress = await getRoyaltyVaultAddress(caller, royaltyVaultIpId); + console.log(royaltyVaultAddress); + + const data = { + abi: [ + { + inputs: [ + { internalType: "address", name: "to", type: "address" }, + { internalType: "uint256", name: "value", type: "uint256" } + ], + name: "transfer", + outputs: [ + { internalType: "bool", name: "", type: "bool" } + ], + stateMutability: "nonpayable", + type: "function", + }, + ], + functionName: "transfer", + args: [toAddress as Hex, amount] + }; + + // const response = await expect( + const response = await + ipAccountExecute(caller, royaltyVaultAddress, 0, royaltyVaultIpId, encodeFunctionData(data), true) + console.log(response); + // ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; +}; + +export const transferTokenToEOAWithSig = async function( + caller: keyof typeof storyClients, + royaltyVaultIpId: Address, + toAddress: Address, + amount: bigint, + signer: Address, + deadline: number | bigint | string, + signature: Address +){ + const royaltyVaultAddress = await getRoyaltyVaultAddress(caller, royaltyVaultIpId); + console.log(royaltyVaultAddress); + + const data = { + abi: [ + { + inputs: [ + { internalType: "address", name: "to", type: "address" }, + { internalType: "uint256", name: "value", type: "uint256" } + ], + name: "transfer", + outputs: [ + { internalType: "bool", name: "", type: "bool" } + ], + stateMutability: "nonpayable", + type: "function", + }, + ], + functionName: "transfer", + args: [toAddress as Hex, amount] + }; + + // const response = await expect( + const response = await + ipAccountExecuteWithSig(caller, royaltyVaultAddress, toAddress, 0, encodeFunctionData(data), signer, deadline, signature, true) + console.log(response); + // ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string").and.not.empty; +}; diff --git a/utils/sdkUtils.ts b/utils/sdkUtils.ts index de33a10..6389fec 100644 --- a/utils/sdkUtils.ts +++ b/utils/sdkUtils.ts @@ -1,9 +1,9 @@ -import { Hex, Address } from "viem"; +import { Hex, Address, encodeFunctionData } from "viem"; import { clientA, clientB, clientC, } from '../config/config'; import { PIL_TYPE } from "@story-protocol/core-sdk"; import { processResponse } from "./utils"; -const storyClients = { +export const storyClients = { A: clientA, B: clientB, C: clientC, @@ -218,7 +218,7 @@ export const registerNonComSocialRemixingPIL = async function ( export const registerCommercialRemixPIL = async function ( wallet: keyof typeof storyClients, - mintingFee: string, + mintingFee: string | number | bigint, commercialRevShare: number, currency: Hex, waitForTransaction: boolean @@ -283,8 +283,16 @@ export const getLicenseTerms = async function ( const storyClient = getStoryClient(wallet); const response = await storyClient.license.getLicenseTerms(selectedLicenseTermsId); - const responseJson = processResponse(response); + const responseJson: { [key: string]: string | bigint } = {}; + Object.entries(response["terms"]).forEach(([key, value]) => { + if (typeof value === "bigint") { + responseJson[key] = value.toString() + 'n'; + } else { + responseJson[key] = value as string; + } + }); console.log(JSON.stringify(responseJson)); + return response; }; @@ -357,7 +365,7 @@ export const payRoyaltyOnBehalf = async function ( receiverIpId: Hex, payerIpId: Hex, token: Address, - amount: string, + amount: string | number | bigint, waitForTransaction: boolean ) { const storyClient = getStoryClient(wallet); @@ -417,10 +425,10 @@ export const royaltyClaimableRevenue = async function ( export const royaltyClaimRevenue = async function ( wallet: keyof typeof storyClients, snapshotIds:string[] | bigint[] | number[], - royaltyVaultIpId: Hex, - account: Hex, - token: Hex, - waitForTransaction: boolean + royaltyVaultIpId: Address, + token: Address, + account?: Address | undefined, + waitForTransaction?: boolean ) { const storyClient = getStoryClient(wallet); const response = await storyClient.royalty.claimRevenue({ @@ -438,6 +446,17 @@ export const royaltyClaimRevenue = async function ( return response; }; +export const getRoyaltyVaultAddress = async function ( + wallet: keyof typeof storyClients, + royaltyVaultIpId: Hex +) { + const storyClient = getStoryClient(wallet); + const response = await storyClient.royalty.getRoyaltyVaultAddress(royaltyVaultIpId); + + console.log(response); + return response; +}; + export const raiseDispute = async function ( wallet: keyof typeof storyClients, targetIpId: Hex, @@ -517,3 +536,54 @@ export const createNFTCollection = async function ( return response; }; + +export const ipAccountExecute = async function ( + wallet: keyof typeof storyClients, + toAddress: Address, + value: number, + ipId: Address, + data: Address, + waitForTransaction?: boolean +) { + const storyClient = getStoryClient(wallet); + const response = await storyClient.ipAccount.execute({ + to: toAddress, + value: value, + ipId: ipId, + data: data, + txOptions: { + waitForTransaction: waitForTransaction + }, + }); + console.log(JSON.stringify(response)); + return response; +}; + +export const ipAccountExecuteWithSig = async function ( + wallet: keyof typeof storyClients, + ipId: Address, + to: Address, + value: number, + data: Address, + signer: Address, + deadline: number | bigint | string, + signature: Address, + waitForTransaction?: boolean | undefined +) { + const storyClient = getStoryClient(wallet); + const response = await storyClient.ipAccount.executeWithSig({ + ipId: ipId, + to: to, + value: value, + data: data, + deadline: deadline, + signer: signer, + signature: signature, + txOptions: { + waitForTransaction: waitForTransaction, + }, + }); + console.log(JSON.stringify(response)); + return response; +}; + diff --git a/utils/utils.ts b/utils/utils.ts index eb4a3ec..afbfba9 100644 --- a/utils/utils.ts +++ b/utils/utils.ts @@ -2,7 +2,8 @@ import { Hex, http, Address, createWalletClient, createPublicClient, Chain } fro import { privateKeyToAccount } from 'viem/accounts' import { sepolia } from 'viem/chains'; import fs from 'fs'; -import { chainStringToViemChain, nftContractAddress, rpcProviderUrl, royaltyPolicyLAPAddress, royaltyApproveAddress, disputeModuleAddress, ipAssetRegistryAddress } from "../config/config"; +import { chainStringToViemChain, nftContractAddress, rpcProviderUrl, royaltyPolicyLAPAddress, royaltyApproveAddress, disputeModuleAddress, ipAssetRegistryAddress, licenseTokenAddress } from "../config/config"; +import { getLicenseTokenOwnerAbi, transferLicenseTokenAbi } from '../config/abi'; const TEST_ENV = process.env.TEST_ENV as string | undefined; @@ -36,6 +37,17 @@ export function captureConsoleLogs(consoleLogs:string[]){ return consoleLogs; }; +export function getWalletClient(WALLET_PRIVATE_KEY: Hex){ + const account = privateKeyToAccount(WALLET_PRIVATE_KEY as Address); + const walletClient = createWalletClient({ + chain: chainId, + transport: http(rpcProviderUrl), + account + }); + + return walletClient; +}; + export async function mintNFT(WALLET_PRIVATE_KEY: Hex, NFT_COLLECTION_ADDRESS?: Address): Promise { const account = privateKeyToAccount(WALLET_PRIVATE_KEY as Address); const baseConfig = { @@ -319,6 +331,35 @@ export async function mintNFTWithRetry(WALLET_PRIVATE_KEY: Hex, NFT_COLLECTION_A return tokenId; }; +export async function getTotalRTSupply(): Promise { + const baseConfig = { + chain: chainId, + transport: http(rpcProviderUrl) + }; + + const publicClient = createPublicClient(baseConfig); + const contractAbi = { + inputs: [], + name: 'TOTAL_RT_SUPPLY', + outputs: [ + { internalType: 'uint32', name: '', type: 'uint32' } + ], + stateMutability: 'view', + type: 'function' + }; + + const requestArgs = { + address: royaltyPolicyLAPAddress as Address, + functionName: 'TOTAL_RT_SUPPLY', + abi: [contractAbi] + }; + + const result = await publicClient.readContract(requestArgs); + console.log(result); + + return Number(result); +}; + export async function checkMintResult(tokenIdA: string){ if (tokenIdA === '') { throw new Error('Unable to mint NFT'); @@ -335,10 +376,18 @@ export async function getBlockTimestamp(): Promise { return (await publicClient.getBlock()).timestamp; }; -export function processResponse(response: any):{ [key: string]: string | bigint } { - const responseJson: { [key: string]: string | bigint } = {}; +export function processResponse(response: any): { [key: string]: string | string[] } { + const responseJson: { [key: string]: string | string[] } = {}; Object.entries(response).forEach(([key, value]) => { - if (typeof value === "bigint") { + if (Array.isArray(value)) { + responseJson[key] = value.map((item: any) => { + if(typeof item === 'bigint') { + return item.toString() + 'n'; + } else { + return item as string; + } + }); + } else if (typeof value === 'bigint') { responseJson[key] = value.toString() + 'n'; } else { responseJson[key] = value as string; @@ -347,3 +396,66 @@ export function processResponse(response: any):{ [key: string]: string | bigint return responseJson; }; +export const getDeadline = (deadline?: bigint | number | string): bigint => { + if (deadline && (isNaN(Number(deadline)) || BigInt(deadline) < 0n)) { + throw new Error("Invalid deadline value."); + } + const timestamp = BigInt(Date.now()); + return deadline ? timestamp + BigInt(deadline) : timestamp + 1000n; +}; + +export async function transferLicenseToken(WALLET_PRIVATE_KEY: Hex, from: Address, to: Address, licenseTokenId: number){ + const account = privateKeyToAccount(WALLET_PRIVATE_KEY as Address); + const baseConfig = { + chain: chainId, + transport: http(rpcProviderUrl) + }; + const walletClient = createWalletClient({ + ...baseConfig, + account + }); + const publicClient = createPublicClient(baseConfig); + + const requestArgs = { + address: licenseTokenAddress, + functionName: 'transferFrom', + args: [from, to, licenseTokenId], + abi: [transferLicenseTokenAbi], + account: account + }; + + await publicClient.simulateContract(requestArgs); + const hash = await walletClient.writeContract(requestArgs); + await publicClient.waitForTransactionReceipt({ + hash: hash + }); + + console.log(`Transaction hash: ${hash}`); + + return hash; +}; + +export async function getLicenseTokenOwner(tokenId: number): Promise
{ + let result: Address | unknown; + const baseConfig = { + chain: chainId, + transport: http(rpcProviderUrl) + }; + + const publicClient = createPublicClient(baseConfig); + + const requestArgs = { + address: licenseTokenAddress as Address, + args: [tokenId], + functionName: 'ownerOf', + abi: [getLicenseTokenOwnerAbi] + }; + + result = await publicClient.readContract(requestArgs); + console.log(`Owner: ${result}`); + + return result; +}; + + +