From 5c7672c7b7cd671c7afbdaeed52819e9a7a3259f Mon Sep 17 00:00:00 2001 From: Tony Boyle <81017245+tonyboylehub@users.noreply.github.com> Date: Thu, 18 Jul 2024 18:49:08 +0100 Subject: [PATCH] fix and test for collectionV2 (#124) * fix and test for collectioV2 * prettier build fix * added extra tests and changed resolver default to V2 * moved collectionPadding helper to _setup file` * lint + prettier pass * Update download-artifact and upload-artifact --------- Co-authored-by: Michael Danenberg <56533526+danenbm@users.noreply.github.com> --- .github/workflows/build-programs.yml | 2 +- .github/workflows/build-rust-client.yml | 2 +- .github/workflows/create-proposal.yml | 2 +- .github/workflows/test-rust-client.yml | 2 +- .github/workflows/version-program.yml | 2 +- clients/js/src/hooked/resolvers.ts | 4 +- clients/js/test/_setup.ts | 2 + clients/js/test/createV1.test.ts | 62 ++++++++++++++++++- .../program/src/utils/metadata.rs | 2 +- 9 files changed, 71 insertions(+), 9 deletions(-) diff --git a/.github/workflows/build-programs.yml b/.github/workflows/build-programs.yml index 2f5adf7d..f84ca8dd 100644 --- a/.github/workflows/build-programs.yml +++ b/.github/workflows/build-programs.yml @@ -59,7 +59,7 @@ jobs: PROGRAMS: ${{ env.PROGRAMS }} - name: Upload program builds - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: program-builds # First wildcard ensures exported paths are consistently under the programs folder. diff --git a/.github/workflows/build-rust-client.yml b/.github/workflows/build-rust-client.yml index 69c505d4..6967213c 100644 --- a/.github/workflows/build-rust-client.yml +++ b/.github/workflows/build-rust-client.yml @@ -63,7 +63,7 @@ jobs: run: cargo build --all-features --release - name: Upload Rust client builds - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: rust-client-builds # First wildcard ensures exported paths are consistently under the clients folder. diff --git a/.github/workflows/create-proposal.yml b/.github/workflows/create-proposal.yml index 6a827420..54391aba 100644 --- a/.github/workflows/create-proposal.yml +++ b/.github/workflows/create-proposal.yml @@ -128,7 +128,7 @@ jobs: echo PROGRAM_NAME="token_metadata" >> $GITHUB_ENV - name: Download program builds - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: program-builds diff --git a/.github/workflows/test-rust-client.yml b/.github/workflows/test-rust-client.yml index 665688e2..aa24c3dd 100644 --- a/.github/workflows/test-rust-client.yml +++ b/.github/workflows/test-rust-client.yml @@ -38,7 +38,7 @@ jobs: key: rust-client-test - name: Download program builds - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: program-builds diff --git a/.github/workflows/version-program.yml b/.github/workflows/version-program.yml index cd95022b..b0ed68bf 100644 --- a/.github/workflows/version-program.yml +++ b/.github/workflows/version-program.yml @@ -103,7 +103,7 @@ jobs: echo PROGRAM_VERSION="${PROGRAM_VERSION}" >> $GITHUB_ENV - name: Download Program Builds - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: program-builds diff --git a/clients/js/src/hooked/resolvers.ts b/clients/js/src/hooked/resolvers.ts index 5e22f87f..20f6dc32 100644 --- a/clients/js/src/hooked/resolvers.ts +++ b/clients/js/src/hooked/resolvers.ts @@ -30,7 +30,9 @@ export const resolveCollectionDetails = ( args: { isCollection?: boolean }, ...rest: any[] ): Option => - args.isCollection ? some(collectionDetails('V1', { size: 0 })) : none(); + args.isCollection + ? some(collectionDetails('V2', { padding: new Array(8).fill(0) })) + : none(); export const resolveIsNonFungible = ( context: any, diff --git a/clients/js/test/_setup.ts b/clients/js/test/_setup.ts index 40a74923..fb8972c7 100644 --- a/clients/js/test/_setup.ts +++ b/clients/js/test/_setup.ts @@ -55,6 +55,8 @@ export const SPL_TOKEN_2022_PROGRAM_ID: PublicKey = publicKey( 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb' ); +export const collectionV2Padding = new Array(8).fill(0); + export const createUmi = async () => (await baseCreateUmi()).use(mplTokenMetadata()); diff --git a/clients/js/test/createV1.test.ts b/clients/js/test/createV1.test.ts index 13c41c67..e6396ea9 100644 --- a/clients/js/test/createV1.test.ts +++ b/clients/js/test/createV1.test.ts @@ -28,7 +28,11 @@ import { programmableConfig, TokenStandard, } from '../src'; -import { createUmi, SPL_TOKEN_2022_PROGRAM_ID } from './_setup'; +import { + collectionV2Padding, + createUmi, + SPL_TOKEN_2022_PROGRAM_ID, +} from './_setup'; test('it can create a new NonFungible', async (t) => { // Given a new mint Signer. @@ -235,7 +239,32 @@ test('it can create a new FungibleAsset', async (t) => { }); }); -test('it can create a collection NonFungible', async (t) => { +test('it can create a collection and defaults to collectionV2', async (t) => { + // Given a new mint Signer. + const umi = await createUmi(); + const mint = generateSigner(umi); + + // When we create a new NonFungible at this address. + await createV1(umi, { + mint, + name: 'My Collection NFT', + uri: 'https://example.com/my-collection-nft.json', + sellerFeeBasisPoints: percentAmount(5.5), + isCollection: true, + }).sendAndConfirm(umi); + + // Then a Metadata account was created with the collection details set. + const metadata = findMetadataPda(umi, { mint: mint.publicKey }); + const metadataAccount = await fetchMetadata(umi, metadata); + t.like(metadataAccount, { + publicKey: publicKey(metadata), + collectionDetails: some( + collectionDetails('V2', { padding: collectionV2Padding }) + ), + }); +}); + +test('it can create a collectionV1 NonFungible', async (t) => { // Given a new mint Signer. const umi = await createUmi(); const mint = generateSigner(umi); @@ -247,6 +276,7 @@ test('it can create a collection NonFungible', async (t) => { uri: 'https://example.com/my-collection-nft.json', sellerFeeBasisPoints: percentAmount(5.5), isCollection: true, + collectionDetails: some(collectionDetails('V1', { size: 0n })), }).sendAndConfirm(umi); // Then a Metadata account was created with the collection details set. @@ -258,6 +288,34 @@ test('it can create a collection NonFungible', async (t) => { }); }); +test('it can create a collectionV2 NonFungible', async (t) => { + // Given a new mint Signer. + const umi = await createUmi(); + const mint = generateSigner(umi); + + // When we create a new NonFungible at this address. + await createV1(umi, { + mint, + name: 'My Collection NFT', + uri: 'https://example.com/my-collection-nft.json', + sellerFeeBasisPoints: percentAmount(5.5), + isCollection: true, + collectionDetails: collectionDetails('V2', { + padding: collectionV2Padding, + }), + }).sendAndConfirm(umi); + + // Then a Metadata account was created with the collection details set. + const metadata = findMetadataPda(umi, { mint: mint.publicKey }); + const metadataAccount = await fetchMetadata(umi, metadata); + t.like(metadataAccount, { + publicKey: publicKey(metadata), + collectionDetails: some( + collectionDetails('V2', { padding: collectionV2Padding }) + ), + }); +}); + test('it can create a NonFungible from an existing mint', async (t) => { // Given an existing mint account. const umi = await createUmi(); diff --git a/programs/token-metadata/program/src/utils/metadata.rs b/programs/token-metadata/program/src/utils/metadata.rs index 7891c22c..15de9f8e 100644 --- a/programs/token-metadata/program/src/utils/metadata.rs +++ b/programs/token-metadata/program/src/utils/metadata.rs @@ -165,7 +165,7 @@ pub fn process_create_metadata_accounts_logic( metadata.collection_details = Some(CollectionDetails::V1 { size: 0 }); } CollectionDetails::V2 { padding: _ } => { - metadata.collection_details = None; + metadata.collection_details = Some(CollectionDetails::V2 { padding: [0; 8] }); } } } else {