Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

update useCreateNFT to use new APIs #102

Merged
merged 5 commits into from
Dec 23, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 8 additions & 5 deletions docs/pages/hooks/useCreateNFT.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,15 @@ export default function Component() {

const handleClick = async () => {
await createNFT({
NicolasMahe marked this conversation as resolved.
Show resolved Hide resolved
standard: 'ERC721', // can be Standard.ERC721 or Standard.ERC1155
chainId: 1, // chainId of the network to mint on
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
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: [
Expand Down Expand Up @@ -78,7 +79,8 @@ useCreateNFT(
```tsx
[
({
standard: Standard
chainId: number
collectionAddress: string
name: string
description: string
content: File
Expand All @@ -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.
antho1404 marked this conversation as resolved.
Show resolved Hide resolved
amount?: number, // number of NFT to create. Require Standard.ERC1155
amount?: number, // number of NFT to create. Require ERC1155
antho1404 marked this conversation as resolved.
Show resolved Hide resolved
royalties?: number, // royalty amount in percentage
traits?: { type: string, value: string }[] // Array of traits associated to the NFT
}
Expand Down
16 changes: 8 additions & 8 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions packages/hooks/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +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. [#102](https://github.com/liteflow-labs/liteflow-js/pull/102)
- Removed parsePrice from package. [#106](https://github.com/liteflow-labs/liteflow-js/pull/106)

#### Added
Expand All @@ -13,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

Expand Down
2 changes: 1 addition & 1 deletion packages/hooks/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,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"
},
Expand Down
4 changes: 1 addition & 3 deletions packages/hooks/src/errorMessages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down
135 changes: 73 additions & 62 deletions packages/hooks/src/useCreateNFT.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,60 +4,70 @@ 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 } 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
}
}
}
`

gql`
mutation CreateLazyMintedAssetSignature(
$chainId: Int!
$collectionAddress: Address!
$asset: LazyMintedAssetSignatureInput!
) {
createLazyMintedAssetSignature(input: { asset: $asset }) {
createLazyMintedAssetSignature(
input: {
chainId: $chainId
collectionAddress: $collectionAddress
asset: $asset
}
) {
eip712Data
}
}
`

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
}
Expand All @@ -76,7 +86,8 @@ export enum CreateNftStep {
}

type createNftFn = (data: {
standard: Standard
chainId: number
collectionAddress: string
name: string
description: string
content: File
Expand Down Expand Up @@ -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,
Expand All @@ -184,23 +196,30 @@ export default function useCreateNFT(
isAnimation,
isPrivate,
})
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 = {
standard,
creatorAddress: account.toLowerCase(),
description,
name,
traits: traits || null,
...media,
supply: amount ? amount.toString() : '1',
royalties: royalties ? Math.round(royalties * 100) : null,
}

const { createLazyMintedAssetSignature } =
await sdk.CreateLazyMintedAssetSignature({
asset: assetToCreate,
chainId: chainId,
collectionAddress: collectionAddress,
asset: assetToCreate as LazyMintedAssetSignatureInput, // TODO: remove this cast when attributes from the API are removed
})

invariant(
Expand All @@ -218,10 +237,12 @@ 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,
...assetToCreate,
...(assetToCreate as LazyMintedAssetSignatureInput), // TODO: remove this cast when attributes from the API are removed
},
})
invariant(
Expand All @@ -231,30 +252,20 @@ export default function useCreateNFT(
return createLazyMintedAsset.asset.id
}

const { createAsset } = await sdk.CreateAsset({
input: {
standard,
creatorAddress: account.toLowerCase(),
description,
name,
traits: traits || null,
...media,
},
creatorAddress: account.toLowerCase(),
amount: amount ? amount.toString() : '1',
royalties: royalties ? Math.round(royalties * 100) : 0,
const { createAssetTransaction } = await sdk.CreateAssetTransaction({
chainId: chainId,
collectionAddress: collectionAddress,
...assetToCreate,
})
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,
antho1404 marked this conversation as resolved.
Show resolved Hide resolved
)
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
Expand All @@ -266,13 +277,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)
Expand Down