diff --git a/clients/js/test/printV1.test.ts b/clients/js/test/printV1.test.ts index 4d0c0d92..67268e45 100644 --- a/clients/js/test/printV1.test.ts +++ b/clients/js/test/printV1.test.ts @@ -1,6 +1,5 @@ import { createMintWithAssociatedToken, - fetchToken, setComputeUnitLimit, } from '@metaplex-foundation/mpl-toolbox'; import { @@ -281,9 +280,7 @@ test('it can delegate the authority to print a new edition', async (t) => { }); const digitalAssetWithToken = await fetchDigitalAssetWithAssociatedToken(umi, originalMint.publicKey, originalOwner.publicKey); - console.log(digitalAssetWithToken); - const tokenAccount = await fetchToken(umi, digitalAssetWithToken.token.publicKey); - console.log(tokenAccount); + // const tokenAccount = await fetchToken(umi, digitalAssetWithToken.token.publicKey); await delegatePrintDelegateV1(umi, { delegate: delegate.publicKey, @@ -316,6 +313,228 @@ test('it can delegate the authority to print a new edition', async (t) => { edition: { supply: 1n, maxSupply: some(10n) }, }); + // And the printed NFT was created with the same data. + const editionAsset = await fetchDigitalAssetWithAssociatedToken( + umi, + editionMint.publicKey, + editionOwner.publicKey + ); + t.like(editionAsset, { + publicKey: editionMint.publicKey, + metadata: { + name: 'My NFT', + symbol: 'MNFT', + uri: 'https://example.com/nft.json', + sellerFeeBasisPoints: 542, + }, + token: { + owner: editionOwner.publicKey, + amount: 1n, + }, + edition: { + isOriginal: false, + parent: findMasterEditionPda(umi, { mint: originalMint.publicKey })[0], + edition: 1n, + }, + }); +}); + +test('it can delegate multiple authorities to print new editions', async (t) => { + // Given an existing master edition asset. + const umi = await createUmi(); + const originalOwner = generateSigner(umi); + const delegate0 = generateSigner(umi); + const delegate1 = generateSigner(umi); + umi.rpc.airdrop(delegate0.publicKey, sol(1)); + umi.rpc.airdrop(delegate1.publicKey, sol(1)); + const originalMint = await createDigitalAssetWithToken(umi, { + name: 'My NFT', + symbol: 'MNFT', + uri: 'https://example.com/nft.json', + sellerFeeBasisPoints: percentAmount(5.42), + tokenOwner: originalOwner.publicKey, + printSupply: printSupply('Limited', [10]), + tokenStandard: TokenStandard.NonFungible, + }); + + const holderDelegateRecord0 = findHolderDelegateRecordPda(umi, { + mint: originalMint.publicKey, + delegateRole: 'print_delegate', + owner: originalOwner.publicKey, + delegate: delegate0.publicKey, + }); + + const holderDelegateRecord1 = findHolderDelegateRecordPda(umi, { + mint: originalMint.publicKey, + delegateRole: 'print_delegate', + owner: originalOwner.publicKey, + delegate: delegate1.publicKey, + }); + + const digitalAssetWithToken = await fetchDigitalAssetWithAssociatedToken(umi, originalMint.publicKey, originalOwner.publicKey); + // const tokenAccount = await fetchToken(umi, digitalAssetWithToken.token.publicKey); + + await delegatePrintDelegateV1(umi, { + delegate: delegate0.publicKey, + mint: originalMint.publicKey, + tokenStandard: TokenStandard.NonFungible, + token: digitalAssetWithToken.token.publicKey, + authority: originalOwner, + delegateRecord: holderDelegateRecord0[0], + }).sendAndConfirm(umi); + + await delegatePrintDelegateV1(umi, { + delegate: delegate1.publicKey, + mint: originalMint.publicKey, + tokenStandard: TokenStandard.NonFungible, + token: digitalAssetWithToken.token.publicKey, + authority: originalOwner, + delegateRecord: holderDelegateRecord1[0], + }).sendAndConfirm(umi); + + // When the delegate prints a new edition of the asset. + const editionMint0 = generateSigner(umi); + const editionOwner0 = generateSigner(umi); + await printV1(umi, { + masterTokenAccountOwner: originalOwner, + masterEditionMint: originalMint.publicKey, + editionMint: editionMint0, + editionTokenAccountOwner: editionOwner0.publicKey, + editionNumber: 1, + tokenStandard: TokenStandard.NonFungible, + masterTokenAccount: digitalAssetWithToken.token.publicKey, + payer: delegate0, + }) + .addRemainingAccounts({ pubkey: holderDelegateRecord0[0], isSigner: false, isWritable: true }) + .sendAndConfirm(umi); + + // When the delegate prints a new edition of the asset. + const editionMint1 = generateSigner(umi); + const editionOwner1 = generateSigner(umi); + await printV1(umi, { + masterTokenAccountOwner: originalOwner, + masterEditionMint: originalMint.publicKey, + editionMint: editionMint1, + editionTokenAccountOwner: editionOwner1.publicKey, + editionNumber: 2, + tokenStandard: TokenStandard.NonFungible, + masterTokenAccount: digitalAssetWithToken.token.publicKey, + payer: delegate1, + }) + .addRemainingAccounts({ pubkey: holderDelegateRecord1[0], isSigner: false, isWritable: true }) + .sendAndConfirm(umi); + + // Then the original NFT was updated. + const originalAsset = await fetchDigitalAsset(umi, originalMint.publicKey); + t.like(originalAsset, { + edition: { supply: 2n, maxSupply: some(10n) }, + }); + + // And the printed NFT was created with the same data. + const editionAsset0 = await fetchDigitalAssetWithAssociatedToken( + umi, + editionMint0.publicKey, + editionOwner0.publicKey + ); + t.like(editionAsset0, { + publicKey: editionMint0.publicKey, + metadata: { + name: 'My NFT', + symbol: 'MNFT', + uri: 'https://example.com/nft.json', + sellerFeeBasisPoints: 542, + }, + token: { + owner: editionOwner0.publicKey, + amount: 1n, + }, + edition: { + isOriginal: false, + parent: findMasterEditionPda(umi, { mint: originalMint.publicKey })[0], + edition: 1n, + }, + }); + + // And the printed NFT was created with the same data. + const editionAsset1 = await fetchDigitalAssetWithAssociatedToken( + umi, + editionMint1.publicKey, + editionOwner1.publicKey + ); + t.like(editionAsset1, { + publicKey: editionMint1.publicKey, + metadata: { + name: 'My NFT', + symbol: 'MNFT', + uri: 'https://example.com/nft.json', + sellerFeeBasisPoints: 542, + }, + token: { + owner: editionOwner1.publicKey, + amount: 1n, + }, + edition: { + isOriginal: false, + parent: findMasterEditionPda(umi, { mint: originalMint.publicKey })[0], + edition: 2n, + }, + }); +}); + +test('it can print a new owner as the master holder after delegating the authority', async (t) => { + // Given an existing master edition asset. + const umi = await createUmi(); + const originalOwner = generateSigner(umi); + const delegate = generateSigner(umi); + umi.rpc.airdrop(delegate.publicKey, sol(1)); + const originalMint = await createDigitalAssetWithToken(umi, { + name: 'My NFT', + symbol: 'MNFT', + uri: 'https://example.com/nft.json', + sellerFeeBasisPoints: percentAmount(5.42), + tokenOwner: originalOwner.publicKey, + printSupply: printSupply('Limited', [10]), + tokenStandard: TokenStandard.NonFungible, + }); + + const holderDelegateRecord = findHolderDelegateRecordPda(umi, { + mint: originalMint.publicKey, + delegateRole: 'print_delegate', + owner: originalOwner.publicKey, + delegate: delegate.publicKey, + }); + + const digitalAssetWithToken = await fetchDigitalAssetWithAssociatedToken(umi, originalMint.publicKey, originalOwner.publicKey); + // const tokenAccount = await fetchToken(umi, digitalAssetWithToken.token.publicKey); + + await delegatePrintDelegateV1(umi, { + delegate: delegate.publicKey, + mint: originalMint.publicKey, + tokenStandard: TokenStandard.NonFungible, + token: digitalAssetWithToken.token.publicKey, + authority: originalOwner, + delegateRecord: holderDelegateRecord[0], + }).sendAndConfirm(umi); + + // When the delegate prints a new edition of the asset. + const editionMint = generateSigner(umi); + const editionOwner = generateSigner(umi); + await printV1(umi, { + masterTokenAccountOwner: originalOwner, + masterEditionMint: originalMint.publicKey, + editionMint, + editionTokenAccountOwner: editionOwner.publicKey, + editionNumber: 1, + tokenStandard: TokenStandard.NonFungible, + masterTokenAccount: digitalAssetWithToken.token.publicKey, + }).sendAndConfirm(umi); + + // Then the original NFT was updated. + const originalAsset = await fetchDigitalAsset(umi, originalMint.publicKey); + t.like(originalAsset, { + edition: { supply: 1n, maxSupply: some(10n) }, + }); + // And the printed NFT was created with the same data. const editionAsset = await fetchDigitalAssetWithAssociatedToken( umi,