diff --git a/components/collection/EditModal.vue b/components/collection/EditModal.vue index da1591778b..80ffb518f4 100644 --- a/components/collection/EditModal.vue +++ b/components/collection/EditModal.vue @@ -125,6 +125,87 @@ + + +
+
+

+ {{ $t('mint.mintType') }} +

+ + + +
+ +
+
+

{{ $t(hasMintingPrice ? 'mint.collection.permission.pricePlaceholder' : 'mint.collection.permission.noPriceSet') }}

+ +
+
+ +
+ {{ chainSymbol }} +
+
+
+

+ {{ $t('mint.collection.permission.holderOfCollection') }} +

+ +
+
+ +
+
+ + +

+ {{ permissionSettingWarningMessage }} +

+
+
+
+
@@ -142,9 +223,9 @@ diff --git a/components/collection/SearchInput.vue b/components/collection/SearchInput.vue new file mode 100644 index 0000000000..5eca490f92 --- /dev/null +++ b/components/collection/SearchInput.vue @@ -0,0 +1,130 @@ + + + diff --git a/components/collection/utils/useCollectionDetails.ts b/components/collection/utils/useCollectionDetails.ts index 0beefe32cf..40a64f5963 100644 --- a/components/collection/utils/useCollectionDetails.ts +++ b/components/collection/utils/useCollectionDetails.ts @@ -104,7 +104,7 @@ export function useCollectionSoldData({ address, collectionId }) { export const useCollectionMinimal = ({ collectionId, }: { - collectionId: Ref + collectionId: Ref }) => { const { urlPrefix, client } = usePrefix() const { isAssetHub } = useIsChain(urlPrefix) diff --git a/components/search/utils/collectionSearch.ts b/components/search/utils/collectionSearch.ts index 9876a5215e..0fcf808e52 100644 --- a/components/search/utils/collectionSearch.ts +++ b/components/search/utils/collectionSearch.ts @@ -1,5 +1,6 @@ import { $fetch } from 'ofetch' import consola from 'consola' +import type { Prefix } from '@kodadot1/static' import { URLS } from '~/utils/constants' const SEARCH_BASE_URL = URLS.koda.search @@ -11,11 +12,12 @@ const api = $fetch.create({ }, credentials: 'omit', }) -export async function fetchCollectionSuggestion(key: string, limit?: number) { +export async function fetchCollectionSuggestion(key: string, limit?: number, chain?: Prefix) { const object = { search: key, table: 'collections', limit, + chain, } try { diff --git a/composables/transaction/mintCollection/utils.ts b/composables/transaction/mintCollection/utils.ts index da6a346cfb..d53d7ffe8b 100644 --- a/composables/transaction/mintCollection/utils.ts +++ b/composables/transaction/mintCollection/utils.ts @@ -1,4 +1,5 @@ import { chainAssetOf } from '@/utils/config/chain.config' +import type { CollectionMintSettingType } from '@/composables/transaction/types' export function createArgs( randomId: number, @@ -33,3 +34,14 @@ export const calculateFees = () => { token: symbol, } } + +export const getCollectionMintSettings = async (collectionId: string) => { + const { apiInstance } = useApi() + const api = await apiInstance.value + const config = await api.query.nfts.collectionConfigOf(collectionId) + return (config.toHuman() as { mintSettings: { + price: string + mintType: CollectionMintSettingType + holderOf: string + } }).mintSettings +} diff --git a/composables/transaction/transactionUpdateCollection.ts b/composables/transaction/transactionUpdateCollection.ts index e93bfca69a..77c43a2db9 100644 --- a/composables/transaction/transactionUpdateCollection.ts +++ b/composables/transaction/transactionUpdateCollection.ts @@ -1,7 +1,7 @@ import { createOpenSeaMetadata as createMetadata, protocolize } from '@kodadot1/hyperdata' import type { SubmittableExtrinsic } from '@polkadot/api-base/types' import { uploadMediaFiles } from './mintToken/constructDirectoryMeta' -import type { ActionUpdateCollection, UpdateCollectionParams } from './types' +import { CollectionMintSettingType, type ActionUpdateCollection, type UpdateCollectionParams } from './types' import { pinFileToIPFS, pinJson } from '@/services/nftStorage' const getIpfsMedia = async ({ collection: { image, banner, imageType } }: ActionUpdateCollection) => { @@ -75,6 +75,21 @@ async function execUpdateCollectionStatmine({ item, api, executeTransaction, isL args.push(api.tx.nfts.setCollectionMaxSupply(item.collectionId, item.collection.max ? item.collection.max : undefined)) } + if (item.update.permission) { + if (item.collection.mintingSettings.mintType === CollectionMintSettingType.HolderOf) { + args.push(api.tx.nfts.updateMintSettings(item.collectionId, { + price: item.collection.mintingSettings.price, + mintType: { + HolderOf: item.collection.mintingSettings.holderOf, + }, + })) + } + else { + const { holderOf: _, ...restSettings } = item.collection.mintingSettings + args.push(api.tx.nfts.updateMintSettings(item.collectionId, restSettings)) + } + } + executeTransaction({ cb: api.tx.utility.batchAll, arg: [args], diff --git a/composables/transaction/types.ts b/composables/transaction/types.ts index 9ad960867b..5e81c1f530 100644 --- a/composables/transaction/types.ts +++ b/composables/transaction/types.ts @@ -311,6 +311,18 @@ export interface ActionSetNftMetadata { errorMessage?: string } +export enum CollectionMintSettingType { + Issuer = 'Issuer', + Public = 'Public', + HolderOf = 'HolderOf', +} + +export type CollectionMintSetting = { + price: string + mintType: CollectionMintSettingType + holderOf?: string +} + export type SetNftMetadataParams = BaseUnionMintParams & { api: ApiPromise } export type UpdateCollection = { @@ -320,6 +332,7 @@ export type UpdateCollection = { imageType?: string banner?: File | string | null max: number | null + mintingSettings: CollectionMintSetting } export type UpdateCollectionParams = BaseUnionMintParams & { api: ApiPromise } @@ -328,7 +341,7 @@ export interface ActionUpdateCollection { interaction: Collections.UPDATE_COLLECTION collectionId: string collection: UpdateCollection - update: { max: boolean, metadata: boolean } + update: { max: boolean, metadata: boolean, permission: boolean } urlPrefix: string successMessage?: string | ((blockNumber: string) => string) errorMessage?: string diff --git a/composables/transaction/utils.ts b/composables/transaction/utils.ts index 096858119f..deee6ad00b 100644 --- a/composables/transaction/utils.ts +++ b/composables/transaction/utils.ts @@ -66,7 +66,7 @@ export function isActionValid(action: Actions): boolean { [Collections.DELETE]: (action: ActionDeleteCollection) => Boolean(action.collectionId), [Collections.UPDATE_COLLECTION]: (action: ActionUpdateCollection) => - Boolean(action.collectionId) && (action.update.metadata || action.update.max), + Boolean(action.collectionId) && (action.update.metadata || action.update.max || action.update.permission), [NFTs.SET_METADATA]: (action: ActionSetNftMetadata) => hasContent(action.nftSn), [NFTs.MINT_DROP]: (action: ActionMintDrop) => diff --git a/locales/en.json b/locales/en.json index 9400b45748..be085254c7 100644 --- a/locales/en.json +++ b/locales/en.json @@ -1253,6 +1253,18 @@ "message": "Name of your collection. It will be visible in the gallery", "placeholder": "Enter collection name" }, + "permission": { + "holderOfCollection": "Holder of Collection", + "holderOfIdWarning": "You need to set a HolderOf collection", + "holderOfWarning": "Currently HolderOf collection is not supported to mint on Koda", + "issuerWarning": "You should not set a price for Issuer type", + "label": "Collection Permission", + "noPriceSet": "No specific price set", + "pricePlaceholder": "Set specific price", + "publicWarning": "You need to set a price so that users can mint on Koda", + "publicWithPriceWarning": "You will not be able to mint in Koda. Moreover anyone can mint into your collection" + }, + "search": "Search Collection Name...", "submit": "Create Collection", "symbol": { "label": "Symbol (short name)", @@ -1289,6 +1301,7 @@ "mass": "NFT mass minter", "mintCollectionSuccess": "Collection {name} Saved in block {block}", "mintNFTSuccess": "NFT {name} Saved in block {block}", + "mintType": "Mint Type", "nfsw": "Explicit content (NSFW)", "nfswMessage": "Set your collection as explicit and sensitive content.", "nft": {