UNPKG

@unchainedshop/plugins

Version:

Official plugin collection for the Unchained Engine with payment, delivery, and pricing adapters

120 lines (119 loc) 5.65 kB
import { WarehousingError, WarehousingAdapter, } from '@unchainedshop/core'; import { WarehousingProviderType } from '@unchainedshop/core-warehousing'; import { ProductContractStandard, ProductType } from '@unchainedshop/core-products'; import { systemLocale } from '@unchainedshop/utils'; import { generateDbObjectId } from '@unchainedshop/mongodb'; import { getFileAdapter } from '@unchainedshop/core'; import { createLogger } from '@unchainedshop/logger'; const logger = createLogger('unchained:eth-minter'); export const ETHMinter = { ...WarehousingAdapter, key: 'shop.unchained.warehousing.infinite-minter', version: '1.0', label: 'Infinite Minter', orderIndex: 0, initialConfiguration: [{ key: 'chainId', value: '0' }], typeSupported: (type) => { return type === WarehousingProviderType.VIRTUAL; }, actions: (configuration, context) => { const { MINTER_TOKEN_OFFSET = '0', ROOT_URL = 'http://localhost:4010' } = process.env; const { product, orderPosition, token, modules, locale } = context; const { contractAddress, contractStandard, tokenId, supply, ercMetadataProperties } = product?.tokenization || {}; const getTokensCreated = async () => { const existingTokens = await modules.warehousing.findTokens(contractStandard === ProductContractStandard.ERC721 ? { contractAddress: contractStandard } : { contractAddress: contractStandard, tokenSerialNumber: tokenId, }); const tokensCreated = existingTokens.reduce((acc, curToken) => { return acc + curToken.quantity; }, 0); return tokensCreated; }; return { ...WarehousingAdapter.actions(configuration, context), isActive() { return product?.type === ProductType.TOKENIZED_PRODUCT; }, configurationError() { if (contractStandard === 'ERC1155' && !tokenId) { logger.error(`Token ID is required for ERC1155 contract standard (productId: ${product._id})`); return WarehousingError.INCOMPLETE_CONFIGURATION; } return null; }, stock: async () => { const tokensCreated = await getTokensCreated(); return supply ? supply - tokensCreated : 0; }, tokenize: async () => { const chainId = configuration.find(({ key }) => key === 'chainId')?.value || undefined; const meta = { contractStandard }; const tokensCreated = await getTokensCreated(); if (!orderPosition) { throw new Error('Order position not found in context'); } if (contractStandard === 'ERC721') { const items = new Array(orderPosition.quantity).fill(null).map((_, i) => ({ _id: generateDbObjectId(), tokenSerialNumber: Number(parseInt(MINTER_TOKEN_OFFSET, 10) + tokensCreated + (i + 1)).toString(), contractAddress, quantity: 1, chainId, meta, })); return items; } return [ { _id: generateDbObjectId(), tokenSerialNumber: tokenId, contractAddress, quantity: orderPosition.quantity, chainId, meta, }, ]; }, tokenMetadata: async (tokenSerialNumber) => { if (!product) { throw new Error('Product not found in context'); } const allLanguages = await modules.languages.findLanguages({ includeInactive: false, }); const [firstMedia] = await modules.products.media.findProductMedias({ productId: product._id, limit: 1, }); const file = firstMedia && (await modules.files.findFile({ fileId: firstMedia.mediaId })); const fileAdapter = file && getFileAdapter(); const signedUrl = await fileAdapter?.createDownloadURL(file); const url = signedUrl && (await modules.files.normalizeUrl(signedUrl, {})); const text = await modules.products.texts.findLocalizedText({ productId: product._id, locale: locale || systemLocale, }); const name = `${text.title} #${tokenSerialNumber}`; const isDefaultLanguageActive = locale ? locale.language === systemLocale.language : true; const localization = isDefaultLanguageActive ? { uri: `${ROOT_URL}/erc-metadata/${product._id}/${locale}/${tokenId}.json`, default: systemLocale.language, locales: allLanguages.map((lang) => lang.isoCode), } : undefined; return { name, description: text.description, image: url, properties: ercMetadataProperties, localization, ...(token?.meta || {}), }; }, }; }, };