From 646c4b12489490b7c152fd964989716cdb1b34cf Mon Sep 17 00:00:00 2001 From: antho1404 Date: Wed, 21 Dec 2022 22:47:33 +0700 Subject: [PATCH 1/4] update useCreateNFT to use new APIs --- docs/pages/hooks/useCreateNFT.mdx | 13 +-- package-lock.json | 16 ++-- packages/hooks/CHANGELOG.md | 2 + packages/hooks/package.json | 2 +- packages/hooks/src/errorMessages.ts | 4 +- packages/hooks/src/useCreateNFT.ts | 132 ++++++++++++++++------------ 6 files changed, 98 insertions(+), 71 deletions(-) diff --git a/docs/pages/hooks/useCreateNFT.mdx b/docs/pages/hooks/useCreateNFT.mdx index 35698c7a..6c6aa5e2 100644 --- a/docs/pages/hooks/useCreateNFT.mdx +++ b/docs/pages/hooks/useCreateNFT.mdx @@ -20,14 +20,15 @@ export default function Component() { const handleClick = async () => { await createNFT({ - standard: 'ERC721', // can be Standard.ERC721 or Standard.ERC1155 + chainId: 1, // chainId of the network to mint on + collection: '0x0000', // address of the collection to use name: 'Azuki #1', // name of the NFT description: 'Take the red bean to join the garden.', // description of the NFT content: azukiImage, // content file uploaded by the user isAnimation: false, // set to true if content file is a video. Require to set preview isPrivate: false, // set to true if content is private. Require to set preview. // optional - amount: 1, // number of NFT to create. Require Standard.ERC1155 + amount: 1, // number of NFT to create. Require ERC1155 royalties: 10, // royalty amount in percentage preview: azukiImagePreview, // preview in the case of private or animation content uploaded by user traits: [ @@ -78,7 +79,8 @@ useCreateNFT( ```tsx [ ({ - standard: Standard + chainId: number + collectionAddress: string name: string description: string content: File @@ -104,14 +106,15 @@ Arguments: ```tsx { - standard: Standard, // can be Standard.ERC721 or Standard.ERC1155 + chainId: Number, // id of the chain to mint on + collectionAddress: string, // address of the collection to mint on name: string, // name of the NFT description: string, // description of the NFT content: File, // content file uploaded by the user preview?: File, // preview in the case of private or animation content uploaded by user isAnimation: boolean, // set to true if content file is a video. Require to set preview isPrivate: boolean, // set to true if content is private. Require to set preview. - amount?: number, // number of NFT to create. Require Standard.ERC1155 + amount?: number, // number of NFT to create. Require ERC1155 royalties?: number, // royalty amount in percentage traits?: { type: string, value: string }[] // Array of traits associated to the NFT } diff --git a/package-lock.json b/package-lock.json index 3797397d..1be307a7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3348,9 +3348,9 @@ "integrity": "sha512-eMk0b9ReBbV23xXU693TAIrLyeO5iTgBZGSJfpqriG8UkYvr/hC9u9pyMlAakDNHWmbhMZCDs6KQO0jzKD8OTw==" }, "node_modules/@nft/api-graphql": { - "version": "1.0.0-beta.7", - "resolved": "https://registry.npmjs.org/@nft/api-graphql/-/api-graphql-1.0.0-beta.7.tgz", - "integrity": "sha512-CboV4ZSRGNrjJV5hcwNaaErci33ilzzt9qa4ROW42DIaHp4Tku19ed7PGySZb4gqiAfbjqSohaGtwBXFCEfIqQ==", + "version": "1.0.0-beta.9", + "resolved": "https://registry.npmjs.org/@nft/api-graphql/-/api-graphql-1.0.0-beta.9.tgz", + "integrity": "sha512-+FGMUFLkHP7z/SjuPyV9ZyxnnKkEu56mkq3ZkYnhzPaVKwpxf1LKjnlf/qdZwvLlhVhsjc7fFWGV1lBo7/zQ6Q==", "dev": true }, "node_modules/@nft/email-connector": { @@ -14735,7 +14735,7 @@ "@graphql-codegen/typescript": "^1.23.0", "@graphql-codegen/typescript-graphql-request": "^4.5.5", "@graphql-codegen/typescript-operations": "^1.18.4", - "@nft/api-graphql": "^1.0.0-beta.7", + "@nft/api-graphql": "^1.0.0-beta.9", "@types/react": "^17.0.51", "eslint-plugin-react-hooks": "^4.2.0" }, @@ -17338,9 +17338,9 @@ "integrity": "sha512-eMk0b9ReBbV23xXU693TAIrLyeO5iTgBZGSJfpqriG8UkYvr/hC9u9pyMlAakDNHWmbhMZCDs6KQO0jzKD8OTw==" }, "@nft/api-graphql": { - "version": "1.0.0-beta.7", - "resolved": "https://registry.npmjs.org/@nft/api-graphql/-/api-graphql-1.0.0-beta.7.tgz", - "integrity": "sha512-CboV4ZSRGNrjJV5hcwNaaErci33ilzzt9qa4ROW42DIaHp4Tku19ed7PGySZb4gqiAfbjqSohaGtwBXFCEfIqQ==", + "version": "1.0.0-beta.9", + "resolved": "https://registry.npmjs.org/@nft/api-graphql/-/api-graphql-1.0.0-beta.9.tgz", + "integrity": "sha512-+FGMUFLkHP7z/SjuPyV9ZyxnnKkEu56mkq3ZkYnhzPaVKwpxf1LKjnlf/qdZwvLlhVhsjc7fFWGV1lBo7/zQ6Q==", "dev": true }, "@nft/email-connector": { @@ -17365,7 +17365,7 @@ "@graphql-codegen/typescript": "^1.23.0", "@graphql-codegen/typescript-graphql-request": "^4.5.5", "@graphql-codegen/typescript-operations": "^1.18.4", - "@nft/api-graphql": "^1.0.0-beta.7", + "@nft/api-graphql": "1.0.0-beta.9", "@pinata/ipfs-gateway-tools": "1.1.6", "@types/react": "^17.0.51", "bignumber.js": "^9.0.2", diff --git a/packages/hooks/CHANGELOG.md b/packages/hooks/CHANGELOG.md index 23c4e70a..77b2a66e 100644 --- a/packages/hooks/CHANGELOG.md +++ b/packages/hooks/CHANGELOG.md @@ -4,6 +4,8 @@ #### Breaking Changes +- The `useCreateNFT` function has been updated to accept `chainId` and `collectionAddress` as arguments, rather than the previous `standard` attribute. To migrate your application to this new version, you will need to pass the desired collection to `useCreateNFT` by either fetching it dynamically or hardcoding it in your code. + #### Added #### Changed diff --git a/packages/hooks/package.json b/packages/hooks/package.json index a20a7692..b84206d6 100644 --- a/packages/hooks/package.json +++ b/packages/hooks/package.json @@ -29,7 +29,7 @@ "@graphql-codegen/typescript": "^1.23.0", "@graphql-codegen/typescript-graphql-request": "^4.5.5", "@graphql-codegen/typescript-operations": "^1.18.4", - "@nft/api-graphql": "^1.0.0-beta.7", + "@nft/api-graphql": "^1.0.0-beta.9", "@types/react": "^17.0.51", "eslint-plugin-react-hooks": "^4.2.0" }, diff --git a/packages/hooks/src/errorMessages.ts b/packages/hooks/src/errorMessages.ts index c0c2d00d..bb979ecc 100644 --- a/packages/hooks/src/errorMessages.ts +++ b/packages/hooks/src/errorMessages.ts @@ -19,9 +19,7 @@ export enum ErrorMessages { MINT_SIGNATURE_GENERATION = 'Error while creating the lazy minted asset signature', ASSET_LAZY_MINT_CREATION_FAILED = 'Error while creating the lazy minted asset', - ASSET_CREATION_FAILED = 'Error while creating this asset', - ASSET_INVALID_STANDARD = 'Invalid token', - ASSET_NO_MINT = 'No transaction to mint', + ASSET_TRANSACTION_CREATION_FAILED = 'Error while creating the transaction for the asset', INVITATION_NOT_FOUND = 'Invitation not found', INVITATION_CREATION_FAILED = 'Invitation creation failed', diff --git a/packages/hooks/src/useCreateNFT.ts b/packages/hooks/src/useCreateNFT.ts index 041e5c78..b6d5cc24 100644 --- a/packages/hooks/src/useCreateNFT.ts +++ b/packages/hooks/src/useCreateNFT.ts @@ -4,39 +4,32 @@ import { useCallback, useContext, useState } from 'react' import invariant from 'ts-invariant' import { LiteflowContext } from './context' import { ErrorMessages } from './errorMessages' -import { Standard } from './graphql' +import { LazyMintedAssetSignatureInput, MetadataInput } from './graphql' import useCheckOwnership from './useCheckOwnership' import useConfig from './useConfig' import useIPFSUploader from './useIPFSUploader' import { convertTx } from './utils/transaction' gql` - mutation CreateAsset( - $input: AssetInputBis! + mutation CreateAssetTransaction( + $chainId: Int! + $collectionAddress: Address! + $metadata: MetadataInput! $creatorAddress: Address! - $amount: Uint256! $royalties: Int + $supply: Uint256! ) { - createAsset(input: { asset: $input }) { - asset { - id - token { - __typename - ... on ERC721 { - mint(owner: $creatorAddress, royalties: $royalties) { - ...Transaction - } - } - ... on ERC1155 { - mint( - owner: $creatorAddress - amount: $amount - royalties: $royalties - ) { - ...Transaction - } - } - } + createAssetTransaction( + chainId: $chainId + collectionAddress: $collectionAddress + creatorAddress: $creatorAddress + metadata: $metadata + royalties: $royalties + supply: $supply + ) { + assetId + transaction { + ...Transaction } } } @@ -44,9 +37,17 @@ gql` gql` mutation CreateLazyMintedAssetSignature( + $chainId: Int! + $collectionAddress: Address! $asset: LazyMintedAssetSignatureInput! ) { - createLazyMintedAssetSignature(input: { asset: $asset }) { + createLazyMintedAssetSignature( + input: { + chainId: $chainId + collectionAddress: $collectionAddress + asset: $asset + } + ) { eip712Data } } @@ -54,10 +55,19 @@ gql` gql` mutation CreateLazyMintedAsset( + $chainId: Int! + $collectionAddress: Address! $asset: LazyMintedAssetInput! $signature: String! ) { - createLazyMintedAsset(input: { asset: $asset, signature: $signature }) { + createLazyMintedAsset( + input: { + chainId: $chainId + collectionAddress: $collectionAddress + asset: $asset + signature: $signature + } + ) { asset { id } @@ -76,7 +86,8 @@ export enum CreateNftStep { } type createNftFn = (data: { - standard: Standard + chainId: number + collectionAddress: string name: string description: string content: File @@ -158,13 +169,14 @@ export default function useCreateNFT( const createNft: createNftFn = useCallback( async ({ + chainId, + collectionAddress, name, description, content, preview, isAnimation, isPrivate, - standard, amount, royalties, traits, @@ -184,22 +196,39 @@ export default function useCreateNFT( isAnimation, isPrivate, }) + const metadata: MetadataInput = { + name, + image: media.image, + description, + animationUrl: media.animationUrl, + unlockableContent: media.unlockableContent, + attributes: (traits || []).map((x) => ({ + traitType: x.type, + value: x.value, + })), + } // lazy minting if ((await config).hasLazyMint) { - const assetToCreate = { - standard, + const assetToCreate: LazyMintedAssetSignatureInput = { creatorAddress: account.toLowerCase(), - description, - name, - traits: traits || null, - ...media, - supply: amount ? amount.toString() : '1', royalties: royalties ? Math.round(royalties * 100) : null, + supply: amount ? amount.toString() : '1', + metadata: metadata, + // deprecated fields that are meant to be removed + standard: null, + animationUrl: null, + description: null, + image: null, + name: null, + traits: null, + unlockableContent: null, } const { createLazyMintedAssetSignature } = await sdk.CreateLazyMintedAssetSignature({ + chainId: chainId, + collectionAddress: collectionAddress, asset: assetToCreate, }) @@ -218,6 +247,8 @@ export default function useCreateNFT( // send signature to api setActiveProcess(CreateNftStep.LAZYMINT_PENDING) const { createLazyMintedAsset } = await sdk.CreateLazyMintedAsset({ + chainId: chainId, + collectionAddress: collectionAddress, signature, asset: { tokenId: message.tokenId, @@ -231,30 +262,23 @@ export default function useCreateNFT( return createLazyMintedAsset.asset.id } - const { createAsset } = await sdk.CreateAsset({ - input: { - standard, - creatorAddress: account.toLowerCase(), - description, - name, - traits: traits || null, - ...media, - }, + const { createAssetTransaction } = await sdk.CreateAssetTransaction({ + chainId: chainId, + collectionAddress: collectionAddress, creatorAddress: account.toLowerCase(), - amount: amount ? amount.toString() : '1', + metadata: metadata, + supply: amount ? amount.toString() : '1', royalties: royalties ? Math.round(royalties * 100) : 0, }) - const asset = createAsset?.asset - invariant(asset, ErrorMessages.ASSET_CREATION_FAILED) invariant( - asset.token.__typename === 'ERC721' || - asset.token.__typename === 'ERC1155', - ErrorMessages.ASSET_INVALID_STANDARD, + createAssetTransaction, + ErrorMessages.ASSET_TRANSACTION_CREATION_FAILED, ) - invariant(asset.token.mint, ErrorMessages.ASSET_NO_MINT) setActiveProcess(CreateNftStep.TRANSACTION_SIGNATURE) - const tx = await signer.sendTransaction(convertTx(asset.token.mint)) + const tx = await signer.sendTransaction( + convertTx(createAssetTransaction.transaction), + ) setTransactionHash(tx.hash) setActiveProcess(CreateNftStep.TRANSACTION_PENDING) // waiting for transaction to be mined @@ -266,13 +290,13 @@ export default function useCreateNFT( // poll the api until the ownership is updated console.info('polling api to check ownership...') await pollOwnership({ - assetId: asset.id, + assetId: createAssetTransaction.assetId, ownerAddress: account.toLowerCase(), initialQuantity: '0', }) console.info('polling done') - return asset.id + return createAssetTransaction.assetId } finally { setActiveProcess(CreateNftStep.INITIAL) setTransactionHash(undefined) From 7cb283024d9aa947a5b5aed44f54c879cb0a6c21 Mon Sep 17 00:00:00 2001 From: antho1404 Date: Thu, 22 Dec 2022 11:11:21 +0700 Subject: [PATCH 2/4] fix doc, type and changelog --- docs/pages/hooks/useCreateNFT.mdx | 2 +- packages/hooks/CHANGELOG.md | 2 +- packages/hooks/src/useCreateNFT.ts | 12 ++---------- 3 files changed, 4 insertions(+), 12 deletions(-) diff --git a/docs/pages/hooks/useCreateNFT.mdx b/docs/pages/hooks/useCreateNFT.mdx index 6c6aa5e2..f64ea05a 100644 --- a/docs/pages/hooks/useCreateNFT.mdx +++ b/docs/pages/hooks/useCreateNFT.mdx @@ -21,7 +21,7 @@ export default function Component() { const handleClick = async () => { await createNFT({ chainId: 1, // chainId of the network to mint on - collection: '0x0000', // address of the collection to use + collectionAddress: '0x0000', // address of the collection to use name: 'Azuki #1', // name of the NFT description: 'Take the red bean to join the garden.', // description of the NFT content: azukiImage, // content file uploaded by the user diff --git a/packages/hooks/CHANGELOG.md b/packages/hooks/CHANGELOG.md index 77b2a66e..9e77e500 100644 --- a/packages/hooks/CHANGELOG.md +++ b/packages/hooks/CHANGELOG.md @@ -4,7 +4,7 @@ #### Breaking Changes -- The `useCreateNFT` function has been updated to accept `chainId` and `collectionAddress` as arguments, rather than the previous `standard` attribute. To migrate your application to this new version, you will need to pass the desired collection to `useCreateNFT` by either fetching it dynamically or hardcoding it in your code. +- The `useCreateNFT` function has been updated to accept `chainId` and `collectionAddress` as arguments, rather than the previous `standard` attribute. To migrate your application to this new version, you will need to pass the desired collection to `useCreateNFT` by either fetching it dynamically or hardcoding it in your code. [#102](https://github.com/liteflow-labs/liteflow-js/pull/102) #### Added diff --git a/packages/hooks/src/useCreateNFT.ts b/packages/hooks/src/useCreateNFT.ts index b6d5cc24..4158a0bb 100644 --- a/packages/hooks/src/useCreateNFT.ts +++ b/packages/hooks/src/useCreateNFT.ts @@ -210,20 +210,12 @@ export default function useCreateNFT( // lazy minting if ((await config).hasLazyMint) { - const assetToCreate: LazyMintedAssetSignatureInput = { + const assetToCreate = { creatorAddress: account.toLowerCase(), royalties: royalties ? Math.round(royalties * 100) : null, supply: amount ? amount.toString() : '1', metadata: metadata, - // deprecated fields that are meant to be removed - standard: null, - animationUrl: null, - description: null, - image: null, - name: null, - traits: null, - unlockableContent: null, - } + } as LazyMintedAssetSignatureInput const { createLazyMintedAssetSignature } = await sdk.CreateLazyMintedAssetSignature({ From 91042690a1173778247c248a3300220bc5085fa9 Mon Sep 17 00:00:00 2001 From: antho1404 Date: Fri, 23 Dec 2022 14:40:03 +0700 Subject: [PATCH 3/4] update changelog --- packages/hooks/CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/hooks/CHANGELOG.md b/packages/hooks/CHANGELOG.md index 15979080..10ea1e6d 100644 --- a/packages/hooks/CHANGELOG.md +++ b/packages/hooks/CHANGELOG.md @@ -14,6 +14,7 @@ #### Changed - Change react library from dependency to peerDependencies and accept react 18 [#97](https://github.com/liteflow-labs/liteflow-js/pull/97) +- Updated `@nft/api-graphql` lib to `1.0.0-beta.9` (https://github.com/liteflow-labs/liteflow-js/pull/102) #### Deprecated From b97d3bfa6aedc4bd6e3e39190710d4dc6dac5aca Mon Sep 17 00:00:00 2001 From: antho1404 Date: Fri, 23 Dec 2022 14:53:37 +0700 Subject: [PATCH 4/4] generalize asset to create --- packages/hooks/src/useCreateNFT.ts | 43 +++++++++++++----------------- 1 file changed, 19 insertions(+), 24 deletions(-) diff --git a/packages/hooks/src/useCreateNFT.ts b/packages/hooks/src/useCreateNFT.ts index 4158a0bb..23dbe0fb 100644 --- a/packages/hooks/src/useCreateNFT.ts +++ b/packages/hooks/src/useCreateNFT.ts @@ -4,7 +4,7 @@ import { useCallback, useContext, useState } from 'react' import invariant from 'ts-invariant' import { LiteflowContext } from './context' import { ErrorMessages } from './errorMessages' -import { LazyMintedAssetSignatureInput, MetadataInput } from './graphql' +import { LazyMintedAssetSignatureInput } from './graphql' import useCheckOwnership from './useCheckOwnership' import useConfig from './useConfig' import useIPFSUploader from './useIPFSUploader' @@ -196,32 +196,30 @@ export default function useCreateNFT( isAnimation, isPrivate, }) - const metadata: MetadataInput = { - name, - image: media.image, - description, - animationUrl: media.animationUrl, - unlockableContent: media.unlockableContent, - attributes: (traits || []).map((x) => ({ - traitType: x.type, - value: x.value, - })), + const assetToCreate = { + creatorAddress: account.toLowerCase(), + royalties: royalties ? Math.round(royalties * 100) : null, + supply: amount ? amount.toString() : '1', + metadata: { + name, + image: media.image, + description, + animationUrl: media.animationUrl, + unlockableContent: media.unlockableContent, + attributes: (traits || []).map((x) => ({ + traitType: x.type, + value: x.value, + })), + }, } // lazy minting if ((await config).hasLazyMint) { - const assetToCreate = { - creatorAddress: account.toLowerCase(), - royalties: royalties ? Math.round(royalties * 100) : null, - supply: amount ? amount.toString() : '1', - metadata: metadata, - } as LazyMintedAssetSignatureInput - const { createLazyMintedAssetSignature } = await sdk.CreateLazyMintedAssetSignature({ chainId: chainId, collectionAddress: collectionAddress, - asset: assetToCreate, + asset: assetToCreate as LazyMintedAssetSignatureInput, // TODO: remove this cast when attributes from the API are removed }) invariant( @@ -244,7 +242,7 @@ export default function useCreateNFT( signature, asset: { tokenId: message.tokenId, - ...assetToCreate, + ...(assetToCreate as LazyMintedAssetSignatureInput), // TODO: remove this cast when attributes from the API are removed }, }) invariant( @@ -257,10 +255,7 @@ export default function useCreateNFT( const { createAssetTransaction } = await sdk.CreateAssetTransaction({ chainId: chainId, collectionAddress: collectionAddress, - creatorAddress: account.toLowerCase(), - metadata: metadata, - supply: amount ? amount.toString() : '1', - royalties: royalties ? Math.round(royalties * 100) : 0, + ...assetToCreate, }) invariant( createAssetTransaction,