Skip to content

Commit

Permalink
manage collection metadata
Browse files Browse the repository at this point in the history
  • Loading branch information
levalleux-ludo committed Dec 14, 2023
1 parent b371abd commit 1408b66
Show file tree
Hide file tree
Showing 8 changed files with 801 additions and 6 deletions.
133 changes: 131 additions & 2 deletions e2e/tests/core-sdk-collections.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
createSeller,
createSellerAndOffer,
initCoreSDKWithFundedWallet,
publishNftContractMetadata,
seedWallet20,
updateSeller,
waitForGraphNodeIndexing
Expand All @@ -18,6 +19,30 @@ describe("Offer collections", () => {
let coreSDK_A: CoreSDK, coreSDK_B: CoreSDK;
let wallet_A: Wallet, wallet_B: Wallet;
const customCollectionId = "summer-2024-collection";
const collectionMetadata1 = {
name: "MyCollection",
description: "This is my collection",
image:
"https://upload.wikimedia.org/wikipedia/en/c/c4/Various_Bored_Ape.jpg",
external_link: "www.mycollection.com",
collaborators: [
"Doc",
"Grumpy",
"Happy",
"Sleepy",
"Bashful",
"Sneezy",
"Dopey"
]
};
const collectionMetadata2 = {
name: "MyCollection2",
description: "This is my 2nd collection",
image:
"https://en.wikipedia.org/wiki/Walt_Disney#/media/File:Steamboat-willie.jpg",
external_link: "www.mycollection2.com",
collaborators: ["Alice", "Bob", "Charlie"]
};
beforeEach(async () => {
// Create seller1 with wallet_A, then update all roles to wallet_B address,
// so that wallet_A can now be reused for another seller account
Expand Down Expand Up @@ -228,7 +253,111 @@ describe("Offer collections", () => {
})
).rejects.toThrow(`collectionId length should not exceed 31 characters`);
});
test("Check collection metadata", async () => {
// TODO:
test("Check collection metadata for initial collection", async () => {
const { coreSDK: coreSDK, fundedWallet } =
await initCoreSDKWithFundedWallet(seedWallet20);
const collectionMetadata1Uri = await publishNftContractMetadata(
coreSDK,
collectionMetadata1
);
const seller = await createSeller(coreSDK, fundedWallet.address, {
sellerParams: { contractUri: collectionMetadata1Uri }
});
expect(seller).toBeTruthy();
expect(seller.collections.length).toEqual(1);
expect(seller.collections[0].metadata).toBeTruthy();
expect(seller.collections[0].metadata.name).toEqual(
collectionMetadata1.name
);
expect(seller.collections[0].metadata.externalLink).toEqual(
collectionMetadata1.external_link
);
expect(seller.collections[0].metadata.collaborators.length).toEqual(
collectionMetadata1.collaborators.length
);
});
test("Check collection metadata for an additional collection", async () => {
const { coreSDK: coreSDK, fundedWallet } =
await initCoreSDKWithFundedWallet(seedWallet20);
const collectionMetadata2Uri = await publishNftContractMetadata(
coreSDK,
collectionMetadata2
);
const seller = await createSeller(coreSDK, fundedWallet.address);
expect(seller).toBeTruthy();
const tx = await coreSDK.createNewCollection({
contractUri: collectionMetadata2Uri,
royaltyPercentage: 0,
collectionId: collectionMetadata2.name
});
await tx.wait();
await waitForGraphNodeIndexing();
const collections = await coreSDK.getOfferCollections({
offerCollectionsFilter: {
sellerId: seller.id
}
});
expect(collections.length).toEqual(2);
expect(collections[1].externalId).toEqual(collectionMetadata2.name);
expect(collections[1].metadata).toBeTruthy();
expect(collections[1].metadata.name).toEqual(collectionMetadata2.name);
expect(collections[1].metadata.externalLink).toEqual(
collectionMetadata2.external_link
);
expect(collections[1].metadata.collaborators.length).toEqual(
collectionMetadata2.collaborators.length
);
});
test("Check incomplete collection metadata", async () => {
const { coreSDK: coreSDK, fundedWallet } =
await initCoreSDKWithFundedWallet(seedWallet20);
const collectionMetadataUri = await publishNftContractMetadata(coreSDK, {
name: collectionMetadata1.name
// no other fields
});
const seller = await createSeller(coreSDK, fundedWallet.address, {
sellerParams: { contractUri: collectionMetadataUri }
});
expect(seller).toBeTruthy();
expect(seller.collections.length).toEqual(1);
expect(seller.collections[0].metadata).toBeTruthy();
expect(seller.collections[0].metadata.name).toEqual(
collectionMetadata1.name
);
expect(seller.collections[0].metadata.externalLink).toEqual(null);
expect(seller.collections[0].metadata.collaborators.length).toEqual(0);
});
test("Check invalid collection metadata", async () => {
const { coreSDK: coreSDK, fundedWallet } =
await initCoreSDKWithFundedWallet(seedWallet20);
const collectionMetadataUri = await publishNftContractMetadata(coreSDK, {
invalidKey: "invalidValue"
// no other fields
});
const seller = await createSeller(coreSDK, fundedWallet.address, {
sellerParams: { contractUri: collectionMetadataUri }
});
expect(seller).toBeTruthy();
expect(seller.collections.length).toEqual(1);
expect(seller.collections[0].metadata).toBeTruthy();
expect(seller.collections[0].metadata.name).toEqual(null);
expect(seller.collections[0].metadata.externalLink).toEqual(null);
expect(seller.collections[0].metadata.collaborators.length).toEqual(0);
});
test("Check non existing collection metadata file", async () => {
const { coreSDK: coreSDK, fundedWallet } =
await initCoreSDKWithFundedWallet(seedWallet20);
const collectionMetadata1Uri = await publishNftContractMetadata(
coreSDK,
collectionMetadata1
);
const seller = await createSeller(coreSDK, fundedWallet.address, {
sellerParams: {
contractUri: collectionMetadata1Uri + "x" // tamper the IPFS link
}
});
expect(seller).toBeTruthy();
expect(seller.collections.length).toEqual(1);
expect(seller.collections[0].metadata).toBeFalsy();
});
});
18 changes: 17 additions & 1 deletion e2e/tests/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@ import {
} from "ethers";
import { CoreSDK, getEnvConfigs, accounts } from "../../packages/core-sdk/src";
import { base, seller } from "../../packages/metadata/src";
import { IpfsMetadataStorage } from "../../packages/ipfs-storage/src";
import {
BaseIpfsStorage,
IpfsMetadataStorage
} from "../../packages/ipfs-storage/src";
import { EthersAdapter } from "../../packages/ethers-sdk/src";
import { CreateOfferArgs } from "./../../packages/common/src/types/offers";
import { mockCreateOfferArgs } from "../../packages/common/tests/mocks";
Expand Down Expand Up @@ -48,6 +51,7 @@ import {
} from "./mockAbis";
import { SellerFieldsFragment } from "../../packages/core-sdk/src/subgraph";
import { ZERO_ADDRESS } from "../../packages/core-sdk/tests/mocks";
import { sortObjKeys } from "../../packages/ipfs-storage/src/utils";

const getFirstEnvConfig = (arg0: Parameters<typeof getEnvConfigs>[0]) =>
getEnvConfigs(arg0)[0];
Expand Down Expand Up @@ -755,3 +759,15 @@ export async function commitToOffer(args: {
const exchange = await args.buyerCoreSDK.getExchangeById(exchangeId);
return exchange;
}

export async function publishNftContractMetadata(
coreSDK: CoreSDK,
metadata: Record<string, unknown>
): Promise<string> {
const ipfsStorage = new BaseIpfsStorage({
url: getFirstEnvConfig("local").ipfsMetadataUrl
});
const metadataWithSortedKeys = sortObjKeys(metadata);
const cid = await ipfsStorage.add(JSON.stringify(metadataWithSortedKeys));
return "ipfs://" + cid;
}
9 changes: 9 additions & 0 deletions packages/core-sdk/src/accounts/queries.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,15 @@ fragment BaseOfferCollectionFields on OfferCollection {
collectionAddress
externalIdHash
externalId
metadata {
id
name
description
image
externalLink
createdAt
collaborators
}
}

fragment SellerFields on Seller {
Expand Down
Loading

0 comments on commit 1408b66

Please sign in to comment.