From 025e79fbf34dc1c6cbc869d969bad3dade548cab Mon Sep 17 00:00:00 2001 From: Mark Paul Date: Thu, 12 Sep 2024 20:25:17 +1000 Subject: [PATCH 01/27] feature: Intial test build on Solana cNFT minting option --- package.json | 4 +- src/cnft-sol-minter.ts | 225 +++++++++++++++++++++++++++++++++++++++ src/common/mint-utils.ts | 104 ++++++++++++++++++ src/config.ts | 6 ++ src/contract-sol.ts | 19 ++++ src/index.ts | 3 + src/minter-sol.ts | 14 +++ 7 files changed, 373 insertions(+), 2 deletions(-) create mode 100644 src/cnft-sol-minter.ts create mode 100644 src/contract-sol.ts create mode 100644 src/minter-sol.ts diff --git a/package.json b/package.json index 08466bc..4965b6b 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@itheum/sdk-mx-data-nft", - "version": "3.6.1", - "description": "SDK for Itheum's Data NFT Technology on MultiversX Blockchain", + "version": "3.7.0-alpha.1", + "description": "SDK for Itheum's Data NFT Technology on MultiversX and Solana", "main": "out/index.js", "types": "out/index.d.js", "files": [ diff --git a/src/cnft-sol-minter.ts b/src/cnft-sol-minter.ts new file mode 100644 index 0000000..8adde96 --- /dev/null +++ b/src/cnft-sol-minter.ts @@ -0,0 +1,225 @@ +import { + dataNFTDataStreamAdvertise, + storeToIpfsOnlyImg, + createIpfsMetadataSolCNft, + storeToIpfsFullSolCNftMetadata +} from './common/mint-utils'; +import { checkTraitsUrl, checkUrlIsUp } from './common/utils'; +import { ErrArgumentNotSet } from './errors'; +import { MinterSol } from './minter-sol'; +import { StringValidator, validateResults } from './common/validator'; + +export class CNftSolMinter extends MinterSol { + /** + * Creates a new instance of the `SftMinter` class, which can be used to interact with the Data NFT-FT minter smart contract + * @param env 'devnet' | 'mainnet' | 'testnet' + */ + constructor(env: string) { + super(env); + } + + /** + * Creates a `mint` transaction + * + * NOTE: The `dataStreamUrl` is being encrypted and the `media` and `metadata` urls are build and uploaded to IPFS + * + * NOTE: The `options.nftStorageToken` is required when not using custom image and traits, when using custom image and traits the traits should be compliant with the `traits` structure + * + * For more information, see the [README documentation](https://github.com/Itheum/sdk-mx-data-nft#create-a-mint-transaction). + * + * @param creatorAddress the address of the creator who we mint a CNft for + * @param tokenName the name of the DataNFT-FT. Between 3 and 20 alphanumeric characters, no spaces. + * @param dataMarshalUrl the url of the data marshal. A live HTTPS URL that returns a 200 OK HTTP code. + * @param dataStreamUrl the url of the data stream to be encrypted. A live HTTPS URL that returns a 200 OK HTTP code. + * @param dataPreviewUrl the url of the data preview. A live HTTPS URL that returns a 200 OK HTTP code. + * @param datasetTitle the title of the dataset. Between 10 and 60 alphanumeric characters. + * @param datasetDescription the description of the dataset. Between 10 and 400 alphanumeric characters. + * @param options [optional] below parameters are optional or required based on use case + * - imageUrl: the URL of the image for the Data NFT + * - traitsUrl: the URL of the traits for the Data NFT + * - nftStorageToken: the nft storage token to be used to upload the image and metadata to IPFS + * - extraAssets: [optional] extra URIs to attached to the NFT. Can be media files, documents, etc. These URIs are public + * - imgGenBg: [optional] the custom series bg to influence the image generation service + * - imgGenSet: [optional] the custom series layer set to influence the image generation service + * + */ + async mint( + creatorAddress: string, + tokenName: string, + dataMarshalUrl: string, + dataStreamUrl: string, + dataPreviewUrl: string, + datasetTitle: string, + datasetDescription: string, + options?: { + imageUrl?: string; + traitsUrl?: string; + nftStorageToken?: string; + extraAssets?: string[]; + imgGenBg?: string; + imgGenSet?: string; + } + ): Promise<{ imageUrl: string; metadataUrl: string; mintMeta: object }> { + const { + imageUrl, + traitsUrl, + nftStorageToken, + extraAssets, + imgGenBg, + imgGenSet + } = options ?? {}; + + const tokenNameValidator = new StringValidator() + .notEmpty() + .alphanumeric() + .minLength(3) + .maxLength(20) + .validate(tokenName); + + const datasetTitleValidator = new StringValidator() + .notEmpty() + .minLength(10) + .maxLength(60) + .validate(datasetTitle.trim()); + + const datasetDescriptionValidator = new StringValidator() + .notEmpty() + .minLength(10) + .maxLength(400) + .validate(datasetDescription); + + validateResults([ + tokenNameValidator, + datasetTitleValidator, + datasetDescriptionValidator + ]); + + // deep validate all mandatory URLs + try { + await checkUrlIsUp(dataPreviewUrl, [200]); + await checkUrlIsUp(dataMarshalUrl + '/health-check', [200]); + } catch (error) { + throw error; + } + + let imageOnIpfsUrl: string; + let metadataOnIpfsUrl: string; + + const { dataNftHash, dataNftStreamUrlEncrypted } = + await dataNFTDataStreamAdvertise( + dataStreamUrl, + dataMarshalUrl, + creatorAddress // the caller is the Creator + ); + + if (!imageUrl) { + if (!nftStorageToken) { + throw new ErrArgumentNotSet( + 'nftStorageToken', + 'NFT Storage token is required when not using custom image and traits' + ); + } + + // create the img generative service API based on user options + let imgGenServiceApi = `${this.imageServiceUrl}/v1/generateNFTArt?hash=${dataNftHash}`; + + if (imgGenBg && imgGenBg.trim() !== '') { + imgGenServiceApi += `&bg=${imgGenBg.trim()}`; + } + + if (imgGenSet && imgGenSet.trim() !== '') { + imgGenServiceApi += `&set=${imgGenSet.trim()}`; + } + + let resImgCall: any = ''; + let dataImgCall: any = ''; + let _imageFile: Blob = new Blob(); + + resImgCall = await fetch(imgGenServiceApi); + dataImgCall = await resImgCall.blob(); + _imageFile = dataImgCall; + + const traitsFromImgHeader = resImgCall.headers.get('x-nft-traits') || ''; + + const { imageOnIpfsUrl: imgOnIpfsUrl } = await storeToIpfsOnlyImg( + nftStorageToken, + _imageFile + ); + + const cNftMetadataContent = createIpfsMetadataSolCNft( + tokenName, + datasetTitle, + datasetDescription, + imgOnIpfsUrl, + creatorAddress, + dataNftStreamUrlEncrypted, + dataPreviewUrl, + dataMarshalUrl, + traitsFromImgHeader, + extraAssets ?? [] + ); + + const { metadataIpfsUrl } = await storeToIpfsFullSolCNftMetadata( + nftStorageToken, + cNftMetadataContent + ); + + imageOnIpfsUrl = imgOnIpfsUrl; + metadataOnIpfsUrl = metadataIpfsUrl; + } else { + if (!traitsUrl) { + throw new ErrArgumentNotSet( + 'traitsUrl', + 'Traits URL is required when using custom image' + ); + } + + await checkTraitsUrl(traitsUrl); + + imageOnIpfsUrl = imageUrl; + metadataOnIpfsUrl = traitsUrl; + } + + // we not make a call to our private cNFt minter API + let mintMeta: any = {}; + + try { + const postHeaders = new Headers(); + postHeaders.append('Content-Type', 'application/json'); + + const raw = JSON.stringify({ + metadataOnIpfsUrl, + tokenName, + mintForSolAddr: creatorAddress, + solSignature: 'solSignature', + signatureNonce: 'signatureNonce' + }); + + const requestOptions = { + method: 'POST', + headers: postHeaders, + body: raw + }; + + let resMintCall: any = ''; + let dataMintCall: any = ''; + + resMintCall = await fetch(this.solCNftMinterServiceUrl, requestOptions); + dataMintCall = await resMintCall.text(); + mintMeta = dataMintCall; + + // .then((response) => response.text()) + // .then((result) => console.log(result)) + // .catch((error) => console.error(error)); + } catch (e: any) { + mintMeta = { error: true, errMsg: e.toString() }; + throw e; + } + + return { + imageUrl: imageOnIpfsUrl, + metadataUrl: metadataOnIpfsUrl, + mintMeta + }; + } +} diff --git a/src/common/mint-utils.ts b/src/common/mint-utils.ts index caadeff..709723c 100644 --- a/src/common/mint-utils.ts +++ b/src/common/mint-utils.ts @@ -52,6 +52,37 @@ export async function storeToIpfs( } } +export async function storeToIpfsFullSolCNftMetadata( + storageToken: string, + metadataStructureSolCNft: object +): Promise<{ metadataIpfsUrl: string }> { + try { + const metadataIpfsHash = await storeTraitsToIpfs( + metadataStructureSolCNft, + storageToken + ); + return { + metadataIpfsUrl: `https://ipfs.io/ipfs/${metadataIpfsHash}` + }; + } catch (error) { + throw error; + } +} + +export async function storeToIpfsOnlyImg( + storageToken: string, + image: Blob +): Promise<{ imageOnIpfsUrl: string }> { + try { + const imageHash = await storeImageToIpfs(image, storageToken); + return { + imageOnIpfsUrl: `https://ipfs.io/ipfs/${imageHash}` + }; + } catch (error) { + throw error; + } +} + async function storeImageToIpfs(image: Blob, storageToken: string) { const form = new FormData(); form.append('file', image); @@ -127,6 +158,49 @@ export function createIpfsMetadata( return metadata; } +export function createIpfsMetadataSolCNft( + tokenName: string, + datasetTitle: string, + datasetDescription: string, + imageOnIpfsUrl: string, + creatorAddress: string, + dataNFTStreamUrl: string, + dataNFTStreamPreviewUrl: string, + dataNFTDataMarshalUrl: string, + traits: string, + extraAssets: string[] +) { + const metadata: Record = { + name: tokenName, + description: `${datasetTitle} : ${datasetDescription}`, + image: imageOnIpfsUrl, + itheum_creator: creatorAddress, + itheum_data_stream_url: dataNFTStreamUrl, + itheum_data_preview_url: dataNFTStreamPreviewUrl, + itheum_data_marshal_url: dataNFTDataMarshalUrl, + attributes: [] as object[] + }; + + if (extraAssets && extraAssets.length > 0) { + metadata.extra_assets = extraAssets; + } + + const attributes = traits + .split(',') + .filter((element) => element.trim() !== ''); + + const metadataAttributes = []; + + for (const attribute of attributes) { + const [key, value] = attribute.split(':'); + const trait = { trait_type: key.trim(), value: value.trim() }; + metadataAttributes.push(trait); + } + + metadata.attributes = metadataAttributes; + return metadata; +} + export async function createFileFromUrl( url: string, datasetTitle: string, @@ -154,3 +228,33 @@ export async function createFileFromUrl( const _traitsFile = traits; return { image: _imageFile, traits: _traitsFile }; } + +export async function createFileFromUrlSolCNft( + url: string, + datasetTitle: string, + datasetDescription: string, + dataNFTStreamPreviewUrl: string, + address: string, + extraAssets: string[] +) { + let res: any = ''; + let data: any = ''; + let _imageFile: Blob = new Blob(); + + if (url) { + res = await fetch(url); + data = await res.blob(); + _imageFile = data; + } + + const traits = createIpfsMetadata( + res.headers.get('x-nft-traits') || '', + datasetTitle, + datasetDescription, + dataNFTStreamPreviewUrl, + address, + extraAssets + ); + const _traitsFile = traits; + return { image: _imageFile, traits: _traitsFile }; +} diff --git a/src/config.ts b/src/config.ts index d55a468..91ec1a0 100644 --- a/src/config.ts +++ b/src/config.ts @@ -81,6 +81,12 @@ export const imageService: { [key in EnvironmentsEnum]: string } = { testnet: '' }; +export const solCNftMinterService: { [key in EnvironmentsEnum]: string } = { + devnet: 'https://api.itheumcloud-stg.com/datadexapi/solNftUtils/mintNft', + mainnet: 'https://api.itheumcloud.com/datadexapi/solNftUtils/mintNft', + testnet: '' +}; + export const marshalUrls = { devnet: 'https://api.itheumcloud-stg.com/datamarshalapi/router/v1', mainnet: 'https://api.itheumcloud.com/datamarshalapi/router/v1', diff --git a/src/contract-sol.ts b/src/contract-sol.ts new file mode 100644 index 0000000..9b6aecf --- /dev/null +++ b/src/contract-sol.ts @@ -0,0 +1,19 @@ +import { EnvironmentsEnum, networkConfiguration } from './config'; +import { ErrNetworkConfig } from './errors'; + +export abstract class ContractSol { + readonly chainID: string; + readonly env: string; + + protected constructor(env: string) { + if (!(env in EnvironmentsEnum)) { + throw new ErrNetworkConfig( + `Invalid environment: ${env}, Expected: 'devnet' | 'mainnet' | 'testnet'` + ); + } + + this.env = env; + const networkConfig = networkConfiguration[env as EnvironmentsEnum]; + this.chainID = networkConfig.chainID; + } +} diff --git a/src/index.ts b/src/index.ts index eb81c43..e821819 100644 --- a/src/index.ts +++ b/src/index.ts @@ -3,9 +3,12 @@ export * from './datanft'; export * from './interfaces'; export * from './marketplace'; export * from './minter'; +export * from './minter-sol'; export * from './nft-minter'; export * from './sft-minter'; +export * from './cnft-sol-minter'; export * from './bond'; export * from './contract'; +export * from './contract-sol'; export * from './liveliness-stake'; export { parseTokenIdentifier, createTokenIdentifier } from './common/utils'; diff --git a/src/minter-sol.ts b/src/minter-sol.ts new file mode 100644 index 0000000..cf8cc61 --- /dev/null +++ b/src/minter-sol.ts @@ -0,0 +1,14 @@ +import { EnvironmentsEnum, imageService, solCNftMinterService } from './config'; +import { ContractSol } from './contract-sol'; + +export abstract class MinterSol extends ContractSol { + readonly imageServiceUrl: string; + readonly solCNftMinterServiceUrl: string; + + protected constructor(env: string) { + super(env); + this.imageServiceUrl = imageService[env as EnvironmentsEnum]; + this.solCNftMinterServiceUrl = + solCNftMinterService[env as EnvironmentsEnum]; + } +} From fe60bf3b49eb0f48487503bdab41819cb8ae51d6 Mon Sep 17 00:00:00 2001 From: Mark Paul Date: Fri, 13 Sep 2024 10:29:30 +1000 Subject: [PATCH 02/27] feature: logic and error handling improvements to CNftSolMinter --- package.json | 2 +- src/cnft-sol-minter.ts | 211 ++++++++++++++++++++++------------------- src/errors.ts | 1 + src/interfaces.ts | 10 ++ 4 files changed, 123 insertions(+), 101 deletions(-) diff --git a/package.json b/package.json index 4965b6b..c0def82 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@itheum/sdk-mx-data-nft", - "version": "3.7.0-alpha.1", + "version": "3.7.0-alpha.2", "description": "SDK for Itheum's Data NFT Technology on MultiversX and Solana", "main": "out/index.js", "types": "out/index.d.js", diff --git a/src/cnft-sol-minter.ts b/src/cnft-sol-minter.ts index 8adde96..28b85a1 100644 --- a/src/cnft-sol-minter.ts +++ b/src/cnft-sol-minter.ts @@ -8,6 +8,7 @@ import { checkTraitsUrl, checkUrlIsUp } from './common/utils'; import { ErrArgumentNotSet } from './errors'; import { MinterSol } from './minter-sol'; import { StringValidator, validateResults } from './common/validator'; +import { CNftSolPostMintMetaType } from './interfaces'; export class CNftSolMinter extends MinterSol { /** @@ -25,8 +26,6 @@ export class CNftSolMinter extends MinterSol { * * NOTE: The `options.nftStorageToken` is required when not using custom image and traits, when using custom image and traits the traits should be compliant with the `traits` structure * - * For more information, see the [README documentation](https://github.com/Itheum/sdk-mx-data-nft#create-a-mint-transaction). - * * @param creatorAddress the address of the creator who we mint a CNft for * @param tokenName the name of the DataNFT-FT. Between 3 and 20 alphanumeric characters, no spaces. * @param dataMarshalUrl the url of the data marshal. A live HTTPS URL that returns a 200 OK HTTP code. @@ -59,7 +58,11 @@ export class CNftSolMinter extends MinterSol { imgGenBg?: string; imgGenSet?: string; } - ): Promise<{ imageUrl: string; metadataUrl: string; mintMeta: object }> { + ): Promise<{ + imageUrl: string; + metadataUrl: string; + mintMeta: CNftSolPostMintMetaType; + }> { const { imageUrl, traitsUrl, @@ -105,117 +108,125 @@ export class CNftSolMinter extends MinterSol { let imageOnIpfsUrl: string; let metadataOnIpfsUrl: string; - const { dataNftHash, dataNftStreamUrlEncrypted } = - await dataNFTDataStreamAdvertise( - dataStreamUrl, - dataMarshalUrl, - creatorAddress // the caller is the Creator - ); - - if (!imageUrl) { - if (!nftStorageToken) { - throw new ErrArgumentNotSet( - 'nftStorageToken', - 'NFT Storage token is required when not using custom image and traits' + // handle all logic related to data stream and ipfs gen of img,traits etc + let allDataStreamAndIPFSLogicDone = false; + + try { + const { dataNftHash, dataNftStreamUrlEncrypted } = + await dataNFTDataStreamAdvertise( + dataStreamUrl, + dataMarshalUrl, + creatorAddress // the caller is the Creator ); - } - // create the img generative service API based on user options - let imgGenServiceApi = `${this.imageServiceUrl}/v1/generateNFTArt?hash=${dataNftHash}`; + if (!imageUrl) { + if (!nftStorageToken) { + throw new ErrArgumentNotSet( + 'nftStorageToken', + 'NFT Storage token is required when not using custom image and traits' + ); + } - if (imgGenBg && imgGenBg.trim() !== '') { - imgGenServiceApi += `&bg=${imgGenBg.trim()}`; - } + // create the img generative service API based on user options + let imgGenServiceApi = `${this.imageServiceUrl}/v1/generateNFTArt?hash=${dataNftHash}`; - if (imgGenSet && imgGenSet.trim() !== '') { - imgGenServiceApi += `&set=${imgGenSet.trim()}`; - } + if (imgGenBg && imgGenBg.trim() !== '') { + imgGenServiceApi += `&bg=${imgGenBg.trim()}`; + } - let resImgCall: any = ''; - let dataImgCall: any = ''; - let _imageFile: Blob = new Blob(); - - resImgCall = await fetch(imgGenServiceApi); - dataImgCall = await resImgCall.blob(); - _imageFile = dataImgCall; - - const traitsFromImgHeader = resImgCall.headers.get('x-nft-traits') || ''; - - const { imageOnIpfsUrl: imgOnIpfsUrl } = await storeToIpfsOnlyImg( - nftStorageToken, - _imageFile - ); - - const cNftMetadataContent = createIpfsMetadataSolCNft( - tokenName, - datasetTitle, - datasetDescription, - imgOnIpfsUrl, - creatorAddress, - dataNftStreamUrlEncrypted, - dataPreviewUrl, - dataMarshalUrl, - traitsFromImgHeader, - extraAssets ?? [] - ); - - const { metadataIpfsUrl } = await storeToIpfsFullSolCNftMetadata( - nftStorageToken, - cNftMetadataContent - ); - - imageOnIpfsUrl = imgOnIpfsUrl; - metadataOnIpfsUrl = metadataIpfsUrl; - } else { - if (!traitsUrl) { - throw new ErrArgumentNotSet( - 'traitsUrl', - 'Traits URL is required when using custom image' + if (imgGenSet && imgGenSet.trim() !== '') { + imgGenServiceApi += `&set=${imgGenSet.trim()}`; + } + + let resImgCall: any = ''; + let dataImgCall: any = ''; + let _imageFile: Blob = new Blob(); + + resImgCall = await fetch(imgGenServiceApi); + dataImgCall = await resImgCall.blob(); + _imageFile = dataImgCall; + + const traitsFromImgHeader = + resImgCall.headers.get('x-nft-traits') || ''; + + const { imageOnIpfsUrl: imgOnIpfsUrl } = await storeToIpfsOnlyImg( + nftStorageToken, + _imageFile ); - } - await checkTraitsUrl(traitsUrl); + const cNftMetadataContent = createIpfsMetadataSolCNft( + tokenName, + datasetTitle, + datasetDescription, + imgOnIpfsUrl, + creatorAddress, + dataNftStreamUrlEncrypted, + dataPreviewUrl, + dataMarshalUrl, + traitsFromImgHeader, + extraAssets ?? [] + ); - imageOnIpfsUrl = imageUrl; - metadataOnIpfsUrl = traitsUrl; - } + const { metadataIpfsUrl } = await storeToIpfsFullSolCNftMetadata( + nftStorageToken, + cNftMetadataContent + ); - // we not make a call to our private cNFt minter API - let mintMeta: any = {}; + imageOnIpfsUrl = imgOnIpfsUrl; + metadataOnIpfsUrl = metadataIpfsUrl; + } else { + if (!traitsUrl) { + throw new ErrArgumentNotSet( + 'traitsUrl', + 'Traits URL is required when using custom image' + ); + } - try { - const postHeaders = new Headers(); - postHeaders.append('Content-Type', 'application/json'); - - const raw = JSON.stringify({ - metadataOnIpfsUrl, - tokenName, - mintForSolAddr: creatorAddress, - solSignature: 'solSignature', - signatureNonce: 'signatureNonce' - }); - - const requestOptions = { - method: 'POST', - headers: postHeaders, - body: raw - }; - - let resMintCall: any = ''; - let dataMintCall: any = ''; - - resMintCall = await fetch(this.solCNftMinterServiceUrl, requestOptions); - dataMintCall = await resMintCall.text(); - mintMeta = dataMintCall; - - // .then((response) => response.text()) - // .then((result) => console.log(result)) - // .catch((error) => console.error(error)); + await checkTraitsUrl(traitsUrl); + + imageOnIpfsUrl = imageUrl; + metadataOnIpfsUrl = traitsUrl; + } + + allDataStreamAndIPFSLogicDone = true; } catch (e: any) { - mintMeta = { error: true, errMsg: e.toString() }; throw e; } + // we not make a call to our private cNFt minter API + let mintMeta: CNftSolPostMintMetaType = {}; + + if (allDataStreamAndIPFSLogicDone) { + try { + const postHeaders = new Headers(); + postHeaders.append('Content-Type', 'application/json'); + + const raw = JSON.stringify({ + metadataOnIpfsUrl, + tokenName, + mintForSolAddr: creatorAddress, + solSignature: 'solSignature', + signatureNonce: 'signatureNonce' + }); + + const requestOptions = { + method: 'POST', + headers: postHeaders, + body: raw + }; + + let resMintCall: any = ''; + let dataMintCall: any = ''; + + resMintCall = await fetch(this.solCNftMinterServiceUrl, requestOptions); + dataMintCall = await resMintCall.text(); + mintMeta = dataMintCall; + } catch (e: any) { + mintMeta = { error: true, errMsg: e.toString() }; + throw e; + } + } + return { imageUrl: imageOnIpfsUrl, metadataUrl: metadataOnIpfsUrl, diff --git a/src/errors.ts b/src/errors.ts index 9e3642b..a6a63c5 100644 --- a/src/errors.ts +++ b/src/errors.ts @@ -20,6 +20,7 @@ export class ErrArgumentNotSet extends Error { super(`Argument "${argument}" is not set. ${message}`); } } + export class ErrInvalidArgument extends Error { public constructor(message: string) { super(`Invalid argument: ${message}`); diff --git a/src/interfaces.ts b/src/interfaces.ts index 7d41348..4a370ee 100644 --- a/src/interfaces.ts +++ b/src/interfaces.ts @@ -86,6 +86,7 @@ export enum NftEnumType { SemiFungibleESDT = 'SemiFungibleESDT', MetaESDT = 'MetaESDT' } + export interface MarketplaceRequirements { acceptedTokens: string[]; acceptedPayments: string[]; @@ -234,3 +235,12 @@ export interface UserData { accumulatedRewardsBypass: BigNumber.Value; vaultNonce: number; } + +export type CNftSolPostMintMetaType = { + error?: boolean; + errMsg?: string; + assetId?: string; + leafSchema?: any; + index?: number; + root?: any; +}; From 507e028d0ca63713970eb8c1bc10fd224eb8f0e0 Mon Sep 17 00:00:00 2001 From: Mark Paul Date: Fri, 13 Sep 2024 11:04:25 +1000 Subject: [PATCH 03/27] feature: logic and error handling improvements to CNftSolMinter --- package.json | 2 +- src/cnft-sol-minter.ts | 304 ++++++++++++++++++++------------------- src/common/mint-utils.ts | 42 ++++-- 3 files changed, 192 insertions(+), 156 deletions(-) diff --git a/package.json b/package.json index c0def82..9aad241 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@itheum/sdk-mx-data-nft", - "version": "3.7.0-alpha.2", + "version": "3.7.0-alpha.3", "description": "SDK for Itheum's Data NFT Technology on MultiversX and Solana", "main": "out/index.js", "types": "out/index.d.js", diff --git a/src/cnft-sol-minter.ts b/src/cnft-sol-minter.ts index 28b85a1..cbf2e3d 100644 --- a/src/cnft-sol-minter.ts +++ b/src/cnft-sol-minter.ts @@ -63,168 +63,182 @@ export class CNftSolMinter extends MinterSol { metadataUrl: string; mintMeta: CNftSolPostMintMetaType; }> { - const { - imageUrl, - traitsUrl, - nftStorageToken, - extraAssets, - imgGenBg, - imgGenSet - } = options ?? {}; - - const tokenNameValidator = new StringValidator() - .notEmpty() - .alphanumeric() - .minLength(3) - .maxLength(20) - .validate(tokenName); - - const datasetTitleValidator = new StringValidator() - .notEmpty() - .minLength(10) - .maxLength(60) - .validate(datasetTitle.trim()); - - const datasetDescriptionValidator = new StringValidator() - .notEmpty() - .minLength(10) - .maxLength(400) - .validate(datasetDescription); - - validateResults([ - tokenNameValidator, - datasetTitleValidator, - datasetDescriptionValidator - ]); - - // deep validate all mandatory URLs - try { - await checkUrlIsUp(dataPreviewUrl, [200]); - await checkUrlIsUp(dataMarshalUrl + '/health-check', [200]); - } catch (error) { - throw error; - } + let imageOnIpfsUrl: string = ''; + let metadataOnIpfsUrl: string = ''; + let mintMeta: CNftSolPostMintMetaType = {}; - let imageOnIpfsUrl: string; - let metadataOnIpfsUrl: string; + try { + const { + imageUrl, + traitsUrl, + nftStorageToken, + extraAssets, + imgGenBg, + imgGenSet + } = options ?? {}; + + const tokenNameValidator = new StringValidator() + .notEmpty() + .alphanumeric() + .minLength(3) + .maxLength(20) + .validate(tokenName); + + const datasetTitleValidator = new StringValidator() + .notEmpty() + .minLength(10) + .maxLength(60) + .validate(datasetTitle.trim()); + + const datasetDescriptionValidator = new StringValidator() + .notEmpty() + .minLength(10) + .maxLength(400) + .validate(datasetDescription); + + validateResults([ + tokenNameValidator, + datasetTitleValidator, + datasetDescriptionValidator + ]); + + // deep validate all mandatory URLs + try { + await checkUrlIsUp(dataPreviewUrl, [200]); + await checkUrlIsUp(dataMarshalUrl + '/health-check', [200]); + } catch (error) { + throw error; + } - // handle all logic related to data stream and ipfs gen of img,traits etc - let allDataStreamAndIPFSLogicDone = false; + // handle all logic related to data stream and ipfs gen of img,traits etc + let allDataStreamAndIPFSLogicDone = false; - try { - const { dataNftHash, dataNftStreamUrlEncrypted } = - await dataNFTDataStreamAdvertise( - dataStreamUrl, - dataMarshalUrl, - creatorAddress // the caller is the Creator - ); - - if (!imageUrl) { - if (!nftStorageToken) { - throw new ErrArgumentNotSet( - 'nftStorageToken', - 'NFT Storage token is required when not using custom image and traits' + try { + const { dataNftHash, dataNftStreamUrlEncrypted } = + await dataNFTDataStreamAdvertise( + dataStreamUrl, + dataMarshalUrl, + creatorAddress // the caller is the Creator ); - } - // create the img generative service API based on user options - let imgGenServiceApi = `${this.imageServiceUrl}/v1/generateNFTArt?hash=${dataNftHash}`; + if (!imageUrl) { + if (!nftStorageToken) { + throw new ErrArgumentNotSet( + 'nftStorageToken', + 'NFT Storage token is required when not using custom image and traits' + ); + } - if (imgGenBg && imgGenBg.trim() !== '') { - imgGenServiceApi += `&bg=${imgGenBg.trim()}`; - } + // create the img generative service API based on user options + let imgGenServiceApi = `${this.imageServiceUrl}/v1/generateNFTArt?hash=${dataNftHash}`; - if (imgGenSet && imgGenSet.trim() !== '') { - imgGenServiceApi += `&set=${imgGenSet.trim()}`; - } + if (imgGenBg && imgGenBg.trim() !== '') { + imgGenServiceApi += `&bg=${imgGenBg.trim()}`; + } + + if (imgGenSet && imgGenSet.trim() !== '') { + imgGenServiceApi += `&set=${imgGenSet.trim()}`; + } + + let resImgCall: any = ''; + let dataImgCall: any = ''; + let _imageFile: Blob = new Blob(); + + resImgCall = await fetch(imgGenServiceApi); + dataImgCall = await resImgCall.blob(); + _imageFile = dataImgCall; + + const traitsFromImgHeader = + resImgCall.headers.get('x-nft-traits') || ''; - let resImgCall: any = ''; - let dataImgCall: any = ''; - let _imageFile: Blob = new Blob(); - - resImgCall = await fetch(imgGenServiceApi); - dataImgCall = await resImgCall.blob(); - _imageFile = dataImgCall; - - const traitsFromImgHeader = - resImgCall.headers.get('x-nft-traits') || ''; - - const { imageOnIpfsUrl: imgOnIpfsUrl } = await storeToIpfsOnlyImg( - nftStorageToken, - _imageFile - ); - - const cNftMetadataContent = createIpfsMetadataSolCNft( - tokenName, - datasetTitle, - datasetDescription, - imgOnIpfsUrl, - creatorAddress, - dataNftStreamUrlEncrypted, - dataPreviewUrl, - dataMarshalUrl, - traitsFromImgHeader, - extraAssets ?? [] - ); - - const { metadataIpfsUrl } = await storeToIpfsFullSolCNftMetadata( - nftStorageToken, - cNftMetadataContent - ); - - imageOnIpfsUrl = imgOnIpfsUrl; - metadataOnIpfsUrl = metadataIpfsUrl; - } else { - if (!traitsUrl) { - throw new ErrArgumentNotSet( - 'traitsUrl', - 'Traits URL is required when using custom image' + const { imageOnIpfsUrl: imgOnIpfsUrl } = await storeToIpfsOnlyImg( + nftStorageToken, + _imageFile ); - } - await checkTraitsUrl(traitsUrl); + if (!imgOnIpfsUrl || imgOnIpfsUrl === '') { + throw new Error('Saving Image to IPFS failed'); + } + + const cNftMetadataContent = createIpfsMetadataSolCNft( + tokenName, + datasetTitle, + datasetDescription, + imgOnIpfsUrl, + creatorAddress, + dataNftStreamUrlEncrypted, + dataPreviewUrl, + dataMarshalUrl, + traitsFromImgHeader, + extraAssets ?? [] + ); - imageOnIpfsUrl = imageUrl; - metadataOnIpfsUrl = traitsUrl; - } + const { metadataIpfsUrl } = await storeToIpfsFullSolCNftMetadata( + nftStorageToken, + cNftMetadataContent + ); - allDataStreamAndIPFSLogicDone = true; - } catch (e: any) { - throw e; - } + if (!metadataIpfsUrl || metadataIpfsUrl === '') { + throw new Error('Saving cNFT Metadata to IPFS failed'); + } - // we not make a call to our private cNFt minter API - let mintMeta: CNftSolPostMintMetaType = {}; + imageOnIpfsUrl = imgOnIpfsUrl; + metadataOnIpfsUrl = metadataIpfsUrl; + } else { + if (!traitsUrl) { + throw new ErrArgumentNotSet( + 'traitsUrl', + 'Traits URL is required when using custom image' + ); + } - if (allDataStreamAndIPFSLogicDone) { - try { - const postHeaders = new Headers(); - postHeaders.append('Content-Type', 'application/json'); - - const raw = JSON.stringify({ - metadataOnIpfsUrl, - tokenName, - mintForSolAddr: creatorAddress, - solSignature: 'solSignature', - signatureNonce: 'signatureNonce' - }); - - const requestOptions = { - method: 'POST', - headers: postHeaders, - body: raw - }; - - let resMintCall: any = ''; - let dataMintCall: any = ''; - - resMintCall = await fetch(this.solCNftMinterServiceUrl, requestOptions); - dataMintCall = await resMintCall.text(); - mintMeta = dataMintCall; + await checkTraitsUrl(traitsUrl); + + imageOnIpfsUrl = imageUrl; + metadataOnIpfsUrl = traitsUrl; + } + + allDataStreamAndIPFSLogicDone = true; } catch (e: any) { - mintMeta = { error: true, errMsg: e.toString() }; throw e; } + + // we not make a call to our private cNFt minter API + if (allDataStreamAndIPFSLogicDone) { + try { + const postHeaders = new Headers(); + postHeaders.append('Content-Type', 'application/json'); + + const raw = JSON.stringify({ + metadataOnIpfsUrl, + tokenName, + mintForSolAddr: creatorAddress, + solSignature: 'solSignature', + signatureNonce: 'signatureNonce' + }); + + const requestOptions = { + method: 'POST', + headers: postHeaders, + body: raw + }; + + let resMintCall: any = ''; + let dataMintCall: any = ''; + + resMintCall = await fetch( + this.solCNftMinterServiceUrl, + requestOptions + ); + dataMintCall = await resMintCall.text(); + mintMeta = dataMintCall; + } catch (e: any) { + mintMeta = { error: true, errMsg: e.toString() }; + throw e; + } + } + } catch (e) { + console.error(e); } return { diff --git a/src/common/mint-utils.ts b/src/common/mint-utils.ts index 709723c..5310f7c 100644 --- a/src/common/mint-utils.ts +++ b/src/common/mint-utils.ts @@ -43,10 +43,18 @@ export async function storeToIpfs( try { const imageHash = await storeImageToIpfs(image, storageToken); const traitsHash = await storeTraitsToIpfs(traits, storageToken); - return { - imageOnIpfsUrl: `https://ipfs.io/ipfs/${imageHash}`, - metadataOnIpfsUrl: `https://ipfs.io/ipfs/${traitsHash}` - }; + + if (imageHash && traitsHash) { + return { + imageOnIpfsUrl: `https://ipfs.io/ipfs/${imageHash}`, + metadataOnIpfsUrl: `https://ipfs.io/ipfs/${traitsHash}` + }; + } else { + return { + imageOnIpfsUrl: '', + metadataOnIpfsUrl: '' + }; + } } catch (error) { throw error; } @@ -61,9 +69,16 @@ export async function storeToIpfsFullSolCNftMetadata( metadataStructureSolCNft, storageToken ); - return { - metadataIpfsUrl: `https://ipfs.io/ipfs/${metadataIpfsHash}` - }; + + if (metadataIpfsHash) { + return { + metadataIpfsUrl: `https://ipfs.io/ipfs/${metadataIpfsHash}` + }; + } else { + return { + metadataIpfsUrl: '' + }; + } } catch (error) { throw error; } @@ -75,9 +90,16 @@ export async function storeToIpfsOnlyImg( ): Promise<{ imageOnIpfsUrl: string }> { try { const imageHash = await storeImageToIpfs(image, storageToken); - return { - imageOnIpfsUrl: `https://ipfs.io/ipfs/${imageHash}` - }; + + if (imageHash) { + return { + imageOnIpfsUrl: `https://ipfs.io/ipfs/${imageHash}` + }; + } else { + return { + imageOnIpfsUrl: '' + }; + } } catch (error) { throw error; } From c506deb30089b626cb1cf0c2a2f924df958e5ce1 Mon Sep 17 00:00:00 2001 From: Mark Paul Date: Fri, 13 Sep 2024 11:06:54 +1000 Subject: [PATCH 04/27] feature: logic and error handling improvements to CNftSolMinter --- package.json | 2 +- src/cnft-sol-minter.ts | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 9aad241..7d88792 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@itheum/sdk-mx-data-nft", - "version": "3.7.0-alpha.3", + "version": "3.7.0-alpha.4", "description": "SDK for Itheum's Data NFT Technology on MultiversX and Solana", "main": "out/index.js", "types": "out/index.d.js", diff --git a/src/cnft-sol-minter.ts b/src/cnft-sol-minter.ts index cbf2e3d..0a90a44 100644 --- a/src/cnft-sol-minter.ts +++ b/src/cnft-sol-minter.ts @@ -237,8 +237,9 @@ export class CNftSolMinter extends MinterSol { throw e; } } - } catch (e) { - console.error(e); + } catch (error) { + console.error(error); + throw error; } return { From 27866019eaa8076402d1af015b085ad57e5d6447 Mon Sep 17 00:00:00 2001 From: Mark Paul Date: Fri, 13 Sep 2024 20:49:42 +1000 Subject: [PATCH 05/27] feature: add proof as well to CNftSolPostMintMetaType --- package.json | 2 +- src/interfaces.ts | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 7d88792..e4e2414 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@itheum/sdk-mx-data-nft", - "version": "3.7.0-alpha.4", + "version": "3.7.0-alpha.5", "description": "SDK for Itheum's Data NFT Technology on MultiversX and Solana", "main": "out/index.js", "types": "out/index.d.js", diff --git a/src/interfaces.ts b/src/interfaces.ts index 4a370ee..c4e75b4 100644 --- a/src/interfaces.ts +++ b/src/interfaces.ts @@ -243,4 +243,5 @@ export type CNftSolPostMintMetaType = { leafSchema?: any; index?: number; root?: any; + proof?: any; }; From cc08a3ad4d6696116aee73759ff27d080caf83d2 Mon Sep 17 00:00:00 2001 From: bucurdavid Date: Thu, 26 Sep 2024 21:46:23 +0300 Subject: [PATCH 06/27] feat: cache duration on access request --- package-lock.json | 4 ++-- src/datanft.ts | 5 ++++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 39d350b..9c1bdc3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@itheum/sdk-mx-data-nft", - "version": "3.6.0-alpha.3", + "version": "3.6.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@itheum/sdk-mx-data-nft", - "version": "3.6.0-alpha.3", + "version": "3.6.1", "license": "GPL-3.0-only", "dependencies": { "@multiversx/sdk-core": "13.2.2", diff --git a/src/datanft.ts b/src/datanft.ts index 49696c0..e9d76f3 100644 --- a/src/datanft.ts +++ b/src/datanft.ts @@ -508,6 +508,7 @@ export class DataNft implements DataNftType { stream?: boolean; nestedIdxToStream?: number; asDeputyOnAppointerAddr?: string; + cacheDurationSeconds?: number; }): Promise { try { // S: run any format specific validation @@ -575,7 +576,9 @@ export class DataNft implements DataNftType { this.nonce )}&chainId=${chainId}&mvxNativeAuthEnable=1&mvxNativeAuthMaxExpirySeconds=${ p.mvxNativeAuthMaxExpirySeconds - }&mvxNativeAuthOrigins=${mvxNativeAuthOriginsToBase64}`; + }&mvxNativeAuthOrigins=${mvxNativeAuthOriginsToBase64}&cacheDurationSeconds=${ + p.cacheDurationSeconds || 0 + }`; type FetchConfig = { [key: string]: any; From 4612ff9a1fad17229a426f1974a7dc8abcd83569 Mon Sep 17 00:00:00 2001 From: bucurdavid Date: Thu, 26 Sep 2024 21:48:01 +0300 Subject: [PATCH 07/27] chore: alpha version bump --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 08466bc..b76b11d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@itheum/sdk-mx-data-nft", - "version": "3.6.1", + "version": "3.7.0-alpha.6", "description": "SDK for Itheum's Data NFT Technology on MultiversX Blockchain", "main": "out/index.js", "types": "out/index.d.js", From 066e848059ea65be2cb977b32df9af8e23d87a61 Mon Sep 17 00:00:00 2001 From: Mark Paul Date: Thu, 10 Oct 2024 20:56:47 +0100 Subject: [PATCH 08/27] feature: signatureNonce and solSignature added for CNftSolMinter --- package.json | 3 +-- src/cnft-sol-minter.ts | 13 ++++++++++--- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 8d0cbbc..522de3d 100644 --- a/package.json +++ b/package.json @@ -1,8 +1,7 @@ { "name": "@itheum/sdk-mx-data-nft", - "version": "3.7.0-alpha.6", + "version": "3.7.0-alpha.7", "description": "SDK for Itheum's Data NFT Technology on MultiversX Blockchain", - "main": "out/index.js", "types": "out/index.d.js", "files": [ diff --git a/src/cnft-sol-minter.ts b/src/cnft-sol-minter.ts index 0a90a44..fd71e5c 100644 --- a/src/cnft-sol-minter.ts +++ b/src/cnft-sol-minter.ts @@ -40,6 +40,8 @@ export class CNftSolMinter extends MinterSol { * - extraAssets: [optional] extra URIs to attached to the NFT. Can be media files, documents, etc. These URIs are public * - imgGenBg: [optional] the custom series bg to influence the image generation service * - imgGenSet: [optional] the custom series layer set to influence the image generation service + * - signatureNonce: [optional] a recent nonce from the marshal network that will be signed to produce solSignature + * - solSignature: [optional] a solana signature of signatureNonce to prove creatorAddress ownership * */ async mint( @@ -57,6 +59,8 @@ export class CNftSolMinter extends MinterSol { extraAssets?: string[]; imgGenBg?: string; imgGenSet?: string; + signatureNonce?: string; + solSignature?: string; } ): Promise<{ imageUrl: string; @@ -74,7 +78,9 @@ export class CNftSolMinter extends MinterSol { nftStorageToken, extraAssets, imgGenBg, - imgGenSet + imgGenSet, + signatureNonce, + solSignature } = options ?? {}; const tokenNameValidator = new StringValidator() @@ -213,8 +219,8 @@ export class CNftSolMinter extends MinterSol { metadataOnIpfsUrl, tokenName, mintForSolAddr: creatorAddress, - solSignature: 'solSignature', - signatureNonce: 'signatureNonce' + solSignature: solSignature || '', + signatureNonce: signatureNonce || '' }); const requestOptions = { @@ -230,6 +236,7 @@ export class CNftSolMinter extends MinterSol { this.solCNftMinterServiceUrl, requestOptions ); + dataMintCall = await resMintCall.text(); mintMeta = dataMintCall; } catch (e: any) { From 8db64c22d8ea89e83b3836c4726833981f62b674 Mon Sep 17 00:00:00 2001 From: Mark Paul Date: Sat, 9 Nov 2024 09:28:23 +1100 Subject: [PATCH 09/27] fix: increase all mvx timeouts to 20s and upgrade mvx network provider to last stable --- package-lock.json | 47 +++++++++++++++++++++++++---------------- package.json | 4 ++-- src/bond.ts | 4 ++-- src/contract.ts | 2 +- src/liveliness-stake.ts | 2 +- src/marketplace.ts | 4 ++-- src/minter.ts | 2 +- src/nft-minter.ts | 4 ++-- src/sft-minter.ts | 4 ++-- 9 files changed, 42 insertions(+), 31 deletions(-) diff --git a/package-lock.json b/package-lock.json index 9c1bdc3..6ff8e94 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,16 +1,16 @@ { "name": "@itheum/sdk-mx-data-nft", - "version": "3.6.1", + "version": "3.7.0-alpha.7", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@itheum/sdk-mx-data-nft", - "version": "3.6.1", + "version": "3.7.0-alpha.7", "license": "GPL-3.0-only", "dependencies": { "@multiversx/sdk-core": "13.2.2", - "@multiversx/sdk-network-providers": "2.4.3", + "@multiversx/sdk-network-providers": "^2.8.0", "bignumber.js": "9.1.2", "nft.storage": "7.2.0" }, @@ -1960,15 +1960,17 @@ } }, "node_modules/@multiversx/sdk-network-providers": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/@multiversx/sdk-network-providers/-/sdk-network-providers-2.4.3.tgz", - "integrity": "sha512-tJmJuxU+BjtC2q29PuzQOM4Qr6aiXujKwQXgIAPHTiuNbMc3Yi6Q4B0DC1PfI3iG+M4DONwfXknvM1uwqnY2zA==", + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/@multiversx/sdk-network-providers/-/sdk-network-providers-2.8.0.tgz", + "integrity": "sha512-p28NVS+uKpfPH4O0yR2LJtCNBHi1o95a3L51pCco1F4UN5seYEXYqOgP0GBxPd0WtajMXR1r5dnCrX9CFHDGcA==", "dependencies": { - "axios": "1.6.8", "bech32": "1.1.4", "bignumber.js": "9.0.1", "buffer": "6.0.3", "json-bigint": "1.0.0" + }, + "peerDependencies": { + "axios": "^1.7.4" } }, "node_modules/@multiversx/sdk-network-providers/node_modules/bignumber.js": { @@ -3275,7 +3277,8 @@ "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "peer": true }, "node_modules/available-typed-arrays": { "version": "1.0.5", @@ -3289,9 +3292,10 @@ } }, "node_modules/axios": { - "version": "1.6.8", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.8.tgz", - "integrity": "sha512-v/ZHtJDU39mDpyBoFVkETcd/uNdxrWRrg3bKpOKzXFA6Bvqopts6ALSMU3y6ijYxbw2B+wPrIv46egTzJXCLGQ==", + "version": "1.7.7", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.7.tgz", + "integrity": "sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==", + "peer": true, "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.0", @@ -3857,6 +3861,7 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "peer": true, "dependencies": { "delayed-stream": "~1.0.0" }, @@ -4264,6 +4269,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "peer": true, "engines": { "node": ">=0.4.0" } @@ -4855,15 +4861,16 @@ } }, "node_modules/follow-redirects": { - "version": "1.15.6", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", - "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", + "version": "1.15.9", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", + "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", "funding": [ { "type": "individual", "url": "https://github.com/sponsors/RubenVerborgh" } ], + "peer": true, "engines": { "node": ">=4.0" }, @@ -4882,9 +4889,10 @@ } }, "node_modules/form-data": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", - "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.1.tgz", + "integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==", + "peer": true, "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", @@ -7452,6 +7460,7 @@ "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "peer": true, "engines": { "node": ">= 0.6" } @@ -7460,6 +7469,7 @@ "version": "2.1.35", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "peer": true, "dependencies": { "mime-db": "1.52.0" }, @@ -10874,7 +10884,8 @@ "node_modules/proxy-from-env": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "peer": true }, "node_modules/punycode.js": { "version": "2.3.1", diff --git a/package.json b/package.json index 522de3d..f2a5737 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@itheum/sdk-mx-data-nft", - "version": "3.7.0-alpha.7", + "version": "3.8.0-alpha.1", "description": "SDK for Itheum's Data NFT Technology on MultiversX Blockchain", "main": "out/index.js", "types": "out/index.d.js", @@ -18,7 +18,7 @@ "license": "GPL-3.0-only", "dependencies": { "@multiversx/sdk-core": "13.2.2", - "@multiversx/sdk-network-providers": "2.4.3", + "@multiversx/sdk-network-providers": "2.8.0", "bignumber.js": "9.1.2", "nft.storage": "7.2.0" }, diff --git a/src/bond.ts b/src/bond.ts index 4ff49ef..f1e65a0 100644 --- a/src/bond.ts +++ b/src/bond.ts @@ -44,9 +44,9 @@ export class BondContract extends Contract { /** * Creates a new instance of the DataNftMarket which can be used to interact with the marketplace smart contract * @param env 'devnet' | 'mainnet' | 'testnet' - * @param timeout Timeout for the network provider (DEFAULT = 10000ms) + * @param timeout Timeout for the network provider (DEFAULT = 20000ms) */ - constructor(env: string, timeout: number = 10000) { + constructor(env: string, timeout: number = 20000) { super( env, new Address(bondContractAddress[env as EnvironmentsEnum]), diff --git a/src/contract.ts b/src/contract.ts index a6c77f4..e7e6702 100644 --- a/src/contract.ts +++ b/src/contract.ts @@ -18,7 +18,7 @@ export abstract class Contract { env: string, contractAddress: IAddress, abiFile: any, - timeout: number = 10000 + timeout: number = 20000 ) { if (!(env in EnvironmentsEnum)) { throw new ErrNetworkConfig( diff --git a/src/liveliness-stake.ts b/src/liveliness-stake.ts index 395c464..56fb9e7 100644 --- a/src/liveliness-stake.ts +++ b/src/liveliness-stake.ts @@ -33,7 +33,7 @@ import BigNumber from 'bignumber.js'; import { Token } from 'nft.storage'; export class LivelinessStake extends Contract { - constructor(env: string, timeout: number = 10000) { + constructor(env: string, timeout: number = 20000) { super( env, new Address(livelinessStakeContractAddress[env as EnvironmentsEnum]), diff --git a/src/marketplace.ts b/src/marketplace.ts index bf6b90e..9b108f3 100644 --- a/src/marketplace.ts +++ b/src/marketplace.ts @@ -39,9 +39,9 @@ export class DataNftMarket { /** * Creates a new instance of the DataNftMarket which can be used to interact with the marketplace smart contract * @param env 'devnet' | 'mainnet' | 'testnet' - * @param timeout Timeout for the network provider (DEFAULT = 10000ms) + * @param timeout Timeout for the network provider (DEFAULT = 20000ms) */ - constructor(env: string, timeout: number = 10000) { + constructor(env: string, timeout: number = 20000) { if (!(env in EnvironmentsEnum)) { throw new ErrNetworkConfig( `Invalid environment: ${env}, Expected: 'devnet' | 'mainnet' | 'testnet'` diff --git a/src/minter.ts b/src/minter.ts index f3757bf..e167d6a 100644 --- a/src/minter.ts +++ b/src/minter.ts @@ -32,7 +32,7 @@ export abstract class Minter extends Contract { env: string, contractAddress: IAddress, abiFile: any, - timeout: number = 10000 + timeout: number = 20000 ) { super(env, contractAddress, abiFile, timeout); this.imageServiceUrl = imageService[env as EnvironmentsEnum]; diff --git a/src/nft-minter.ts b/src/nft-minter.ts index 14f2db8..926c95e 100644 --- a/src/nft-minter.ts +++ b/src/nft-minter.ts @@ -29,9 +29,9 @@ export class NftMinter extends Minter { * Creates a new instance of the `NftMinter` class, which is used to interact with the factory generated smart contract. * @param env 'devnet' | 'mainnet' | 'testnet' * @param contractAddress The address of the factory generated smart contract - * @param timeout Timeout for the network provider (DEFAULT = 10000ms) + * @param timeout Timeout for the network provider (DEFAULT = 20000ms) */ - constructor(env: string, contractAddress: IAddress, timeout: number = 10000) { + constructor(env: string, contractAddress: IAddress, timeout: number = 20000) { super(env, contractAddress, dataNftLeaseAbi, timeout); } diff --git a/src/sft-minter.ts b/src/sft-minter.ts index 3d5d908..1eb2d35 100644 --- a/src/sft-minter.ts +++ b/src/sft-minter.ts @@ -37,9 +37,9 @@ export class SftMinter extends Minter { /** * Creates a new instance of the `SftMinter` class, which can be used to interact with the Data NFT-FT minter smart contract * @param env 'devnet' | 'mainnet' | 'testnet' - * @param timeout Timeout for the network provider (DEFAULT = 10000ms) + * @param timeout Timeout for the network provider (DEFAULT = 20000ms) */ - constructor(env: string, timeout: number = 10000) { + constructor(env: string, timeout: number = 20000) { super( env, new Address(minterContractAddress[env as EnvironmentsEnum]), From aca7fd2bb0af3ef8bf9357c6747ab3f54c8f3fdb Mon Sep 17 00:00:00 2001 From: Mark Paul Date: Sat, 9 Nov 2024 09:33:40 +1100 Subject: [PATCH 10/27] fix: tests that broke based on last update to timeout --- tests/environment.test.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/environment.test.ts b/tests/environment.test.ts index 0b431c0..6d89ac3 100644 --- a/tests/environment.test.ts +++ b/tests/environment.test.ts @@ -8,7 +8,7 @@ describe('testing environment market', () => { expect(datanft.chainID).toStrictEqual('D'); expect(datanft.networkProvider).toStrictEqual( new ApiNetworkProvider('https://devnet-api.multiversx.com', { - timeout: 10000 + timeout: 20000 }) ); }); @@ -19,7 +19,7 @@ describe('testing environment market', () => { expect(datanft.chainID).toStrictEqual('1'); expect(datanft.networkProvider).toStrictEqual( new ApiNetworkProvider('https://api.multiversx.com', { - timeout: 10000 + timeout: 20000 }) ); }); @@ -54,7 +54,7 @@ describe('testing environment minter', () => { expect(datanft.chainID).toStrictEqual('D'); expect(datanft.networkProvider).toStrictEqual( new ApiNetworkProvider('https://devnet-api.multiversx.com', { - timeout: 10000 + timeout: 20000 }) ); }); @@ -65,7 +65,7 @@ describe('testing environment minter', () => { expect(datanft.chainID).toStrictEqual('1'); expect(datanft.networkProvider).toStrictEqual( new ApiNetworkProvider('https://api.multiversx.com', { - timeout: 10000 + timeout: 20000 }) ); }); From f449a5b7ace76acf212a3abaee653e399a0d9e5d Mon Sep 17 00:00:00 2001 From: Mark Paul Date: Sat, 9 Nov 2024 10:47:04 +1100 Subject: [PATCH 11/27] fix: remove sdk-network-providers and use sdk-core for everything, fix tests --- package-lock.json | 48 +++++++++++---------------------------- package.json | 5 ++-- src/contract.ts | 7 +++--- src/marketplace.ts | 7 +++--- src/minter.ts | 4 ++-- tests/environment.test.ts | 34 ++++++++++++++++----------- 6 files changed, 46 insertions(+), 59 deletions(-) diff --git a/package-lock.json b/package-lock.json index 6ff8e94..3da6b31 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,16 +1,15 @@ { "name": "@itheum/sdk-mx-data-nft", - "version": "3.7.0-alpha.7", + "version": "3.8.0-alpha.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@itheum/sdk-mx-data-nft", - "version": "3.7.0-alpha.7", + "version": "3.8.0-alpha.2", "license": "GPL-3.0-only", "dependencies": { - "@multiversx/sdk-core": "13.2.2", - "@multiversx/sdk-network-providers": "^2.8.0", + "@multiversx/sdk-core": "13.9.0", "bignumber.js": "9.1.2", "nft.storage": "7.2.0" }, @@ -1943,9 +1942,9 @@ } }, "node_modules/@multiversx/sdk-core": { - "version": "13.2.2", - "resolved": "https://registry.npmjs.org/@multiversx/sdk-core/-/sdk-core-13.2.2.tgz", - "integrity": "sha512-ABQuy7PcFBnl5f9yFczgaq7tX72X0M836Ky9h4HRCQd5Mao3OJ3TrgHEvxZe9SVYXtwOm337iPsbkZzVslxu9A==", + "version": "13.9.0", + "resolved": "https://registry.npmjs.org/@multiversx/sdk-core/-/sdk-core-13.9.0.tgz", + "integrity": "sha512-WYA5fssMt/jTRTT+dkZW6V0ykCrkczhJ3BbZni6LhHjwFti7lMboVdoUMCIyPbecWZIEdmLq0OTcjOLy9tZX0g==", "dependencies": { "@multiversx/sdk-transaction-decoder": "1.0.2", "bech32": "1.1.4", @@ -1955,32 +1954,11 @@ "keccak": "3.0.2" }, "peerDependencies": { + "axios": "^1.7.4", "bignumber.js": "^9.0.1", "protobufjs": "^7.2.6" } }, - "node_modules/@multiversx/sdk-network-providers": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@multiversx/sdk-network-providers/-/sdk-network-providers-2.8.0.tgz", - "integrity": "sha512-p28NVS+uKpfPH4O0yR2LJtCNBHi1o95a3L51pCco1F4UN5seYEXYqOgP0GBxPd0WtajMXR1r5dnCrX9CFHDGcA==", - "dependencies": { - "bech32": "1.1.4", - "bignumber.js": "9.0.1", - "buffer": "6.0.3", - "json-bigint": "1.0.0" - }, - "peerDependencies": { - "axios": "^1.7.4" - } - }, - "node_modules/@multiversx/sdk-network-providers/node_modules/bignumber.js": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.1.tgz", - "integrity": "sha512-IdZR9mh6ahOBv/hYGiXyVuyCetmGJhtYkqLBpTStdhEGjegpPlUawydyaF3pbIOFynJTpllEs+NP+CS9jKFLjA==", - "engines": { - "node": "*" - } - }, "node_modules/@multiversx/sdk-transaction-decoder": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/@multiversx/sdk-transaction-decoder/-/sdk-transaction-decoder-1.0.2.tgz", @@ -7736,9 +7714,9 @@ } }, "node_modules/node-gyp-build": { - "version": "4.6.1", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.6.1.tgz", - "integrity": "sha512-24vnklJmyRS8ViBNI8KbtK/r/DmXQMRiOMXTNz2nrTnAYUwjmEEbnnpB/+kt+yWRv73bPsSPRFddrcIbAxSiMQ==", + "version": "4.8.2", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.2.tgz", + "integrity": "sha512-IRUxE4BVsHWXkV/SFOut4qTlagw2aM8T5/vnTsmrHJvVoKueJHRc/JaFND7QDDc61kLYUJ6qlZM3sqTSyx2dTw==", "bin": { "node-gyp-build": "bin.js", "node-gyp-build-optional": "optional.js", @@ -10858,9 +10836,9 @@ "dev": true }, "node_modules/protobufjs": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.3.2.tgz", - "integrity": "sha512-RXyHaACeqXeqAKGLDl68rQKbmObRsTIn4TYVUUug1KfS47YWCo5MacGITEryugIgZqORCvJWEk4l449POg5Txg==", + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.4.0.tgz", + "integrity": "sha512-mRUWCc3KUU4w1jU8sGxICXH/gNS94DvI1gxqDvBzhj1JpcsimQkYiOJfwsPUykUI5ZaspFbSgmBLER8IrQ3tqw==", "hasInstallScript": true, "peer": true, "dependencies": { diff --git a/package.json b/package.json index f2a5737..10c064d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@itheum/sdk-mx-data-nft", - "version": "3.8.0-alpha.1", + "version": "3.8.0-alpha.2", "description": "SDK for Itheum's Data NFT Technology on MultiversX Blockchain", "main": "out/index.js", "types": "out/index.d.js", @@ -17,8 +17,7 @@ "author": "Itheum Protocol", "license": "GPL-3.0-only", "dependencies": { - "@multiversx/sdk-core": "13.2.2", - "@multiversx/sdk-network-providers": "2.8.0", + "@multiversx/sdk-core": "13.9.0", "bignumber.js": "9.1.2", "nft.storage": "7.2.0" }, diff --git a/src/contract.ts b/src/contract.ts index e7e6702..2be73f1 100644 --- a/src/contract.ts +++ b/src/contract.ts @@ -2,9 +2,9 @@ import { AbiRegistry, ErrContract, IAddress, - SmartContract + SmartContract, + ApiNetworkProvider } from '@multiversx/sdk-core/out'; -import { ApiNetworkProvider } from '@multiversx/sdk-network-providers/out'; import { EnvironmentsEnum, networkConfiguration } from './config'; import { ErrContractAddressNotSet, ErrNetworkConfig } from './errors'; @@ -35,7 +35,8 @@ export abstract class Contract { this.networkProvider = new ApiNetworkProvider( networkConfig.networkProvider, { - timeout: timeout + timeout: timeout, + clientName: 'ithuemDataNftSDK' } ); this.contract = new SmartContract({ diff --git a/src/marketplace.ts b/src/marketplace.ts index 9b108f3..fb9d627 100644 --- a/src/marketplace.ts +++ b/src/marketplace.ts @@ -14,9 +14,9 @@ import { Transaction, U64Value, U8Value, - VariadicValue + VariadicValue, + ApiNetworkProvider } from '@multiversx/sdk-core/out'; -import { ApiNetworkProvider } from '@multiversx/sdk-network-providers/out'; import dataMarketAbi from './abis/data_market.abi.json'; import { parseOffer } from './common/utils'; import { @@ -53,7 +53,8 @@ export class DataNftMarket { this.networkProvider = new ApiNetworkProvider( networkConfig.networkProvider, { - timeout: timeout + timeout: timeout, + clientName: 'ithuemDataNftSDK' } ); const contractAddress = marketPlaceContractAddress[env as EnvironmentsEnum]; diff --git a/src/minter.ts b/src/minter.ts index e167d6a..e82bb39 100644 --- a/src/minter.ts +++ b/src/minter.ts @@ -12,9 +12,9 @@ import { StringValue, TokenIdentifierValue, Transaction, - U64Value + U64Value, + ApiNetworkProvider } from '@multiversx/sdk-core/out'; -import { ApiNetworkProvider } from '@multiversx/sdk-network-providers/out'; import { EnvironmentsEnum, dataNftTokenIdentifier, diff --git a/tests/environment.test.ts b/tests/environment.test.ts index 6d89ac3..40de54b 100644 --- a/tests/environment.test.ts +++ b/tests/environment.test.ts @@ -1,4 +1,4 @@ -import { ApiNetworkProvider } from '@multiversx/sdk-network-providers/out'; +import { ApiNetworkProvider } from '@multiversx/sdk-core/out'; import { DataNftMarket, SftMinter } from '../src/index'; describe('testing environment market', () => { @@ -8,7 +8,8 @@ describe('testing environment market', () => { expect(datanft.chainID).toStrictEqual('D'); expect(datanft.networkProvider).toStrictEqual( new ApiNetworkProvider('https://devnet-api.multiversx.com', { - timeout: 20000 + timeout: 20000, + clientName: 'ithuemDataNftSDK' }) ); }); @@ -19,29 +20,32 @@ describe('testing environment market', () => { expect(datanft.chainID).toStrictEqual('1'); expect(datanft.networkProvider).toStrictEqual( new ApiNetworkProvider('https://api.multiversx.com', { - timeout: 20000 + timeout: 20000, + clientName: 'ithuemDataNftSDK' }) ); }); test('#devnet-custom-timeout', async () => { - const datanft = new DataNftMarket('devnet', 5000); + const datanft = new DataNftMarket('devnet', 20000); expect(datanft.chainID).toStrictEqual('D'); expect(datanft.networkProvider).toStrictEqual( new ApiNetworkProvider('https://devnet-api.multiversx.com', { - timeout: 5000 + timeout: 20000, + clientName: 'ithuemDataNftSDK' }) ); }); test('#mainnet-custom-timeout', async () => { - const datanft = new DataNftMarket('mainnet', 5000); + const datanft = new DataNftMarket('mainnet', 20000); expect(datanft.chainID).toStrictEqual('1'); expect(datanft.networkProvider).toStrictEqual( new ApiNetworkProvider('https://api.multiversx.com', { - timeout: 5000 + timeout: 20000, + clientName: 'ithuemDataNftSDK' }) ); }); @@ -54,7 +58,8 @@ describe('testing environment minter', () => { expect(datanft.chainID).toStrictEqual('D'); expect(datanft.networkProvider).toStrictEqual( new ApiNetworkProvider('https://devnet-api.multiversx.com', { - timeout: 20000 + timeout: 20000, + clientName: 'ithuemDataNftSDK' }) ); }); @@ -65,29 +70,32 @@ describe('testing environment minter', () => { expect(datanft.chainID).toStrictEqual('1'); expect(datanft.networkProvider).toStrictEqual( new ApiNetworkProvider('https://api.multiversx.com', { - timeout: 20000 + timeout: 20000, + clientName: 'ithuemDataNftSDK' }) ); }); test('#devnet-custom-timeout', async () => { - const datanft = new SftMinter('devnet', 5000); + const datanft = new SftMinter('devnet', 20000); expect(datanft.chainID).toStrictEqual('D'); expect(datanft.networkProvider).toStrictEqual( new ApiNetworkProvider('https://devnet-api.multiversx.com', { - timeout: 5000 + timeout: 20000, + clientName: 'ithuemDataNftSDK' }) ); }); test('#mainnet-custom-timeout', async () => { - const datanft = new SftMinter('mainnet', 5000); + const datanft = new SftMinter('mainnet', 20000); expect(datanft.chainID).toStrictEqual('1'); expect(datanft.networkProvider).toStrictEqual( new ApiNetworkProvider('https://api.multiversx.com', { - timeout: 5000 + timeout: 20000, + clientName: 'ithuemDataNftSDK' }) ); }); From b214ba7c14329767a00700b4f2368ae20d5b01a0 Mon Sep 17 00:00:00 2001 From: Mark Paul Date: Mon, 11 Nov 2024 14:27:38 +1100 Subject: [PATCH 12/27] feature: use ITH_GLOBAL_* if available, introduce poc for Simple Caching Module --- package.json | 2 +- src/common/utils.ts | 47 +++++++++++++++++++++++++++++++++++++++ src/config.ts | 44 +++++++++++++++++++++++++++++++----- src/datanft.ts | 35 ++++++++++++++++++++++------- tests/environment.test.ts | 4 ++++ 5 files changed, 117 insertions(+), 15 deletions(-) diff --git a/package.json b/package.json index 10c064d..4d3c030 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@itheum/sdk-mx-data-nft", - "version": "3.8.0-alpha.2", + "version": "3.8.0-alpha.3", "description": "SDK for Itheum's Data NFT Technology on MultiversX Blockchain", "main": "out/index.js", "types": "out/index.d.js", diff --git a/src/common/utils.ts b/src/common/utils.ts index e82a0b2..e62d1c7 100644 --- a/src/common/utils.ts +++ b/src/common/utils.ts @@ -600,3 +600,50 @@ export function checkStatus(response: Response) { throw new ErrFetch(response.status, response.statusText); } } + +/* +Simple Caching Module helps throttle frequently used calls to RPC that fetch data +this helps speed up the client side app and also reduces calls to the RPC +we allow consumer to set a custom TTL in MS for how long data is stored in cache +*/ +const sessionCache: Record = {}; + +export function getDataFromClientSessionCache(cacheKey: string) { + const cacheObject = sessionCache[cacheKey]; + + if (!cacheObject) { + console.log('getDataFromClientSessionCache: not found'); + return false; + } else { + // did it expire? is so, delete it from the cache + if (cacheObject.addedOn - Date.now() > cacheObject.expireAfter) { + console.log('getDataFromClientSessionCache: expired'); + delete sessionCache[cacheKey]; // remove it from cache as its expired + return false; + } else { + console.log('getDataFromClientSessionCache: available'); + return cacheObject.payload; + } + } +} + +export function setDataToClientSessionCache( + cacheKey: string, + jsonData: any, + ttlInMs?: number +) { + const howManyMsToCacheFor = ttlInMs || 120000; // 120000 is 2 min default TTL + + sessionCache[cacheKey] = { + payload: jsonData, + addedOn: Date.now(), + expireAfter: howManyMsToCacheFor + }; + + console.log( + 'setDataToClientSessionCache: cached for ms ', + howManyMsToCacheFor + ); + + return true; +} diff --git a/src/config.ts b/src/config.ts index 91ec1a0..e732939 100644 --- a/src/config.ts +++ b/src/config.ts @@ -1,3 +1,12 @@ +/* +Host apps like the data dex or explorer, when the MVX dappProvider in initialized (very early in the page) +it calls a utility method that loads the best RPC to use in the ITH_GLOBAL_MVX_RPC_API_SESSION global variable +so we aim to use that if available so this SDK uses the same RPC as the host to talk to the MVX chain +*/ +declare const window: { + ITH_GLOBAL_MVX_RPC_API_SESSION: string; +} & Window; + export enum EnvironmentsEnum { devnet = 'devnet', testnet = 'testnet', @@ -9,19 +18,31 @@ export interface Config { networkProvider: string; } +// note that in all rpc check methods below we check if window === 'undefined' as this is need for tests to pass const devnetNetworkConfig: Config = { chainID: 'D', - networkProvider: 'https://devnet-api.multiversx.com' + networkProvider: + typeof window === 'undefined' + ? 'https://devnet-api.multiversx.com' + : window.ITH_GLOBAL_MVX_RPC_API_SESSION || + 'https://devnet-api.multiversx.com' }; const mainnetNetworkConfig: Config = { chainID: '1', - networkProvider: 'https://api.multiversx.com' + networkProvider: + typeof window === 'undefined' + ? 'https://api.multiversx.com' + : window.ITH_GLOBAL_MVX_RPC_API_SESSION || 'https://api.multiversx.com' }; const testnetNetworkConfig: Config = { chainID: 'T', - networkProvider: 'https://testnet-api.multiversx.com' + networkProvider: + typeof window === 'undefined' + ? 'https://testnet-api.multiversx.com' + : window.ITH_GLOBAL_MVX_RPC_API_SESSION || + 'https://testnet-api.multiversx.com' }; export const itheumTokenIdentifier: { [key in EnvironmentsEnum]: string } = { @@ -64,9 +85,20 @@ export const livelinessStakeContractAddress: { }; export const apiConfiguration: { [key in EnvironmentsEnum]: string } = { - devnet: 'https://devnet-api.multiversx.com', - mainnet: 'https://api.multiversx.com', - testnet: 'https://testnet-api.multiversx.com' + devnet: + typeof window === 'undefined' + ? 'https://devnet-api.multiversx.com' + : window.ITH_GLOBAL_MVX_RPC_API_SESSION || + 'https://devnet-api.multiversx.com', + mainnet: + typeof window === 'undefined' + ? 'https://api.multiversx.com' + : window.ITH_GLOBAL_MVX_RPC_API_SESSION || 'https://api.multiversx.com', + testnet: + typeof window === 'undefined' + ? 'https://testnet-api.multiversx.com' + : window.ITH_GLOBAL_MVX_RPC_API_SESSION || + 'https://testnet-api.multiversx.com' }; export const networkConfiguration: { [key in EnvironmentsEnum]: Config } = { diff --git a/src/datanft.ts b/src/datanft.ts index e9d76f3..37acc54 100644 --- a/src/datanft.ts +++ b/src/datanft.ts @@ -10,7 +10,9 @@ import { numberToPaddedHex, overrideMarshalUrl, parseDataNft, - validateSpecificParamsViewData + validateSpecificParamsViewData, + getDataFromClientSessionCache, + setDataToClientSessionCache } from './common/utils'; import { Config, @@ -163,15 +165,32 @@ export class DataNft implements DataNftType { if (identifiers.length > MAX_ITEMS) { throw new ErrTooManyItems(); } - const response = await fetch( - `${this.apiConfiguration}/nfts?identifiers=${identifiers.join( - ',' - )}&withSupply=true&size=${identifiers.length}` - ); - checkStatus(response); + // lets not make the call if not needed + if (identifiers.length === 0) { + return []; + } + + const fetchUrl = `${ + this.apiConfiguration + }/nfts?identifiers=${identifiers.join(',')}&withSupply=true&size=${ + identifiers.length + }`; + + // check if its in session cache + let jsonDataPayload = null; + const getFromSessionCache = getDataFromClientSessionCache(fetchUrl); + + if (!getFromSessionCache) { + const response = await fetch(fetchUrl); + checkStatus(response); + jsonDataPayload = await response.json(); + setDataToClientSessionCache(fetchUrl, jsonDataPayload, 5 * 60 * 1000); + } else { + jsonDataPayload = getFromSessionCache; + } - const data: NftType[] = await response.json(); + const data: NftType[] = jsonDataPayload; try { const dataNfts = data.map((value) => parseDataNft(value)); diff --git a/tests/environment.test.ts b/tests/environment.test.ts index 40de54b..320bf71 100644 --- a/tests/environment.test.ts +++ b/tests/environment.test.ts @@ -1,3 +1,7 @@ +declare const window: { + ITH_GLOBAL_MVX_RPC_API_SESSION: string; +} & Window; + import { ApiNetworkProvider } from '@multiversx/sdk-core/out'; import { DataNftMarket, SftMinter } from '../src/index'; From 63e731d9ba14a16718461690b3f1d9608334d702 Mon Sep 17 00:00:00 2001 From: Mark Paul Date: Mon, 11 Nov 2024 15:27:21 +1100 Subject: [PATCH 13/27] feature: allow setNetworkConfig to accept useSpecificApiEndpoint so host can change rpc, remove the global variable check for rpc --- package.json | 2 +- src/common/utils.ts | 2 +- src/config.ts | 43 ++++++--------------------------------- src/datanft.ts | 11 +++++++++- tests/environment.test.ts | 4 ---- 5 files changed, 18 insertions(+), 44 deletions(-) diff --git a/package.json b/package.json index 4d3c030..ba203d6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@itheum/sdk-mx-data-nft", - "version": "3.8.0-alpha.3", + "version": "3.8.0-alpha.4", "description": "SDK for Itheum's Data NFT Technology on MultiversX Blockchain", "main": "out/index.js", "types": "out/index.d.js", diff --git a/src/common/utils.ts b/src/common/utils.ts index e62d1c7..c43905e 100644 --- a/src/common/utils.ts +++ b/src/common/utils.ts @@ -616,7 +616,7 @@ export function getDataFromClientSessionCache(cacheKey: string) { return false; } else { // did it expire? is so, delete it from the cache - if (cacheObject.addedOn - Date.now() > cacheObject.expireAfter) { + if (Date.now() - cacheObject.addedOn > cacheObject.expireAfter) { console.log('getDataFromClientSessionCache: expired'); delete sessionCache[cacheKey]; // remove it from cache as its expired return false; diff --git a/src/config.ts b/src/config.ts index e732939..4c4cc61 100644 --- a/src/config.ts +++ b/src/config.ts @@ -1,12 +1,3 @@ -/* -Host apps like the data dex or explorer, when the MVX dappProvider in initialized (very early in the page) -it calls a utility method that loads the best RPC to use in the ITH_GLOBAL_MVX_RPC_API_SESSION global variable -so we aim to use that if available so this SDK uses the same RPC as the host to talk to the MVX chain -*/ -declare const window: { - ITH_GLOBAL_MVX_RPC_API_SESSION: string; -} & Window; - export enum EnvironmentsEnum { devnet = 'devnet', testnet = 'testnet', @@ -21,28 +12,17 @@ export interface Config { // note that in all rpc check methods below we check if window === 'undefined' as this is need for tests to pass const devnetNetworkConfig: Config = { chainID: 'D', - networkProvider: - typeof window === 'undefined' - ? 'https://devnet-api.multiversx.com' - : window.ITH_GLOBAL_MVX_RPC_API_SESSION || - 'https://devnet-api.multiversx.com' + networkProvider: 'https://devnet-api.multiversx.com' }; const mainnetNetworkConfig: Config = { chainID: '1', - networkProvider: - typeof window === 'undefined' - ? 'https://api.multiversx.com' - : window.ITH_GLOBAL_MVX_RPC_API_SESSION || 'https://api.multiversx.com' + networkProvider: 'https://api.multiversx.com' }; const testnetNetworkConfig: Config = { chainID: 'T', - networkProvider: - typeof window === 'undefined' - ? 'https://testnet-api.multiversx.com' - : window.ITH_GLOBAL_MVX_RPC_API_SESSION || - 'https://testnet-api.multiversx.com' + networkProvider: 'https://testnet-api.multiversx.com' }; export const itheumTokenIdentifier: { [key in EnvironmentsEnum]: string } = { @@ -85,20 +65,9 @@ export const livelinessStakeContractAddress: { }; export const apiConfiguration: { [key in EnvironmentsEnum]: string } = { - devnet: - typeof window === 'undefined' - ? 'https://devnet-api.multiversx.com' - : window.ITH_GLOBAL_MVX_RPC_API_SESSION || - 'https://devnet-api.multiversx.com', - mainnet: - typeof window === 'undefined' - ? 'https://api.multiversx.com' - : window.ITH_GLOBAL_MVX_RPC_API_SESSION || 'https://api.multiversx.com', - testnet: - typeof window === 'undefined' - ? 'https://testnet-api.multiversx.com' - : window.ITH_GLOBAL_MVX_RPC_API_SESSION || - 'https://testnet-api.multiversx.com' + devnet: 'https://devnet-api.multiversx.com', + mainnet: 'https://api.multiversx.com', + testnet: 'https://testnet-api.multiversx.com' }; export const networkConfiguration: { [key in EnvironmentsEnum]: Config } = { diff --git a/src/datanft.ts b/src/datanft.ts index 37acc54..6b7ed61 100644 --- a/src/datanft.ts +++ b/src/datanft.ts @@ -98,8 +98,9 @@ export class DataNft implements DataNftType { /** * Sets the network configuration for the DataNft class. * @param env 'devnet' | 'mainnet' | 'testnet' + * @param useSpecificApiEndpoint optional param to use a specific RPC API endpoint for the env, if not given, defaults to config default value. Value need to start with https:// */ - static setNetworkConfig(env: string) { + static setNetworkConfig(env: string, useSpecificApiEndpoint?: string) { if (!(env in EnvironmentsEnum)) { throw new ErrNetworkConfig( `Invalid environment: ${env}, Expected: 'devnet' | 'mainnet' | 'testnet'` @@ -108,6 +109,14 @@ export class DataNft implements DataNftType { this.env = env; this.networkConfiguration = networkConfiguration[env as EnvironmentsEnum]; this.apiConfiguration = apiConfiguration[env as EnvironmentsEnum]; + + if ( + useSpecificApiEndpoint && + useSpecificApiEndpoint.trim().includes('https://') + ) { + this.apiConfiguration = useSpecificApiEndpoint.trim(); + this.networkConfiguration.networkProvider = useSpecificApiEndpoint.trim(); + } } /** diff --git a/tests/environment.test.ts b/tests/environment.test.ts index 320bf71..40de54b 100644 --- a/tests/environment.test.ts +++ b/tests/environment.test.ts @@ -1,7 +1,3 @@ -declare const window: { - ITH_GLOBAL_MVX_RPC_API_SESSION: string; -} & Window; - import { ApiNetworkProvider } from '@multiversx/sdk-core/out'; import { DataNftMarket, SftMinter } from '../src/index'; From 753990eaee21d8d29393e633c77948de77c5525e Mon Sep 17 00:00:00 2001 From: Mark Paul Date: Mon, 11 Nov 2024 15:53:24 +1100 Subject: [PATCH 14/27] chore: add debug --- package.json | 2 +- src/datanft.ts | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index ba203d6..aead7db 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@itheum/sdk-mx-data-nft", - "version": "3.8.0-alpha.4", + "version": "3.8.0-alpha.5", "description": "SDK for Itheum's Data NFT Technology on MultiversX Blockchain", "main": "out/index.js", "types": "out/index.d.js", diff --git a/src/datanft.ts b/src/datanft.ts index 6b7ed61..608751d 100644 --- a/src/datanft.ts +++ b/src/datanft.ts @@ -117,6 +117,19 @@ export class DataNft implements DataNftType { this.apiConfiguration = useSpecificApiEndpoint.trim(); this.networkConfiguration.networkProvider = useSpecificApiEndpoint.trim(); } + + console.log( + 'SDK debug: setNetworkConfig useSpecificApiEndpoint =', + useSpecificApiEndpoint + ); + console.log( + 'SDK debug: setNetworkConfig this.apiConfiguration =', + this.apiConfiguration + ); + console.log( + 'SDK debug: setNetworkConfig this.networkConfiguration =', + this.networkConfiguration + ); } /** @@ -180,6 +193,8 @@ export class DataNft implements DataNftType { return []; } + console.log('SDK debug: createManyFromApi api =', this.apiConfiguration); + const fetchUrl = `${ this.apiConfiguration }/nfts?identifiers=${identifiers.join(',')}&withSupply=true&size=${ From c0ec35c7d3b255f6a629e0d1596746284ed58991 Mon Sep 17 00:00:00 2001 From: Mark Paul Date: Mon, 11 Nov 2024 16:14:57 +1100 Subject: [PATCH 15/27] chore: add debug --- package.json | 2 +- src/datanft.ts | 13 ++++++------- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/package.json b/package.json index aead7db..df82899 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@itheum/sdk-mx-data-nft", - "version": "3.8.0-alpha.5", + "version": "3.8.0-alpha.6", "description": "SDK for Itheum's Data NFT Technology on MultiversX Blockchain", "main": "out/index.js", "types": "out/index.d.js", diff --git a/src/datanft.ts b/src/datanft.ts index 608751d..ce15b9f 100644 --- a/src/datanft.ts +++ b/src/datanft.ts @@ -98,7 +98,7 @@ export class DataNft implements DataNftType { /** * Sets the network configuration for the DataNft class. * @param env 'devnet' | 'mainnet' | 'testnet' - * @param useSpecificApiEndpoint optional param to use a specific RPC API endpoint for the env, if not given, defaults to config default value. Value need to start with https:// + * @param useSpecificApiEndpoint optional param to use a specific RPC API endpoint for the env, if not given, defaults to config default value. */ static setNetworkConfig(env: string, useSpecificApiEndpoint?: string) { if (!(env in EnvironmentsEnum)) { @@ -107,15 +107,14 @@ export class DataNft implements DataNftType { ); } this.env = env; - this.networkConfiguration = networkConfiguration[env as EnvironmentsEnum]; - this.apiConfiguration = apiConfiguration[env as EnvironmentsEnum]; - if ( - useSpecificApiEndpoint && - useSpecificApiEndpoint.trim().includes('https://') - ) { + debugger; + if (useSpecificApiEndpoint && useSpecificApiEndpoint.trim() !== '') { this.apiConfiguration = useSpecificApiEndpoint.trim(); this.networkConfiguration.networkProvider = useSpecificApiEndpoint.trim(); + } else { + this.networkConfiguration = networkConfiguration[env as EnvironmentsEnum]; + this.apiConfiguration = apiConfiguration[env as EnvironmentsEnum]; } console.log( From 614b79a3bb7168232c85e650cbf319a788053555 Mon Sep 17 00:00:00 2001 From: Mark Paul Date: Mon, 11 Nov 2024 16:20:33 +1100 Subject: [PATCH 16/27] chore: add debug --- package.json | 2 +- src/datanft.ts | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index df82899..6e5dda3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@itheum/sdk-mx-data-nft", - "version": "3.8.0-alpha.6", + "version": "3.8.0-alpha.7", "description": "SDK for Itheum's Data NFT Technology on MultiversX Blockchain", "main": "out/index.js", "types": "out/index.d.js", diff --git a/src/datanft.ts b/src/datanft.ts index ce15b9f..30ad1bd 100644 --- a/src/datanft.ts +++ b/src/datanft.ts @@ -107,14 +107,14 @@ export class DataNft implements DataNftType { ); } this.env = env; + this.networkConfiguration = networkConfiguration[env as EnvironmentsEnum]; + this.apiConfiguration = apiConfiguration[env as EnvironmentsEnum]; debugger; + if (useSpecificApiEndpoint && useSpecificApiEndpoint.trim() !== '') { this.apiConfiguration = useSpecificApiEndpoint.trim(); this.networkConfiguration.networkProvider = useSpecificApiEndpoint.trim(); - } else { - this.networkConfiguration = networkConfiguration[env as EnvironmentsEnum]; - this.apiConfiguration = apiConfiguration[env as EnvironmentsEnum]; } console.log( From 5d409d69833bbc894328c1466e3449c08843e74a Mon Sep 17 00:00:00 2001 From: Mark Paul Date: Mon, 11 Nov 2024 16:29:07 +1100 Subject: [PATCH 17/27] chore: add debug --- package.json | 2 +- src/datanft.ts | 15 +++++++++++---- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 6e5dda3..3328027 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@itheum/sdk-mx-data-nft", - "version": "3.8.0-alpha.7", + "version": "3.8.0-alpha.8", "description": "SDK for Itheum's Data NFT Technology on MultiversX Blockchain", "main": "out/index.js", "types": "out/index.d.js", diff --git a/src/datanft.ts b/src/datanft.ts index 30ad1bd..7ecfb08 100644 --- a/src/datanft.ts +++ b/src/datanft.ts @@ -110,7 +110,14 @@ export class DataNft implements DataNftType { this.networkConfiguration = networkConfiguration[env as EnvironmentsEnum]; this.apiConfiguration = apiConfiguration[env as EnvironmentsEnum]; - debugger; + console.log( + 'SDK debug: setNetworkConfig this.apiConfiguration B4 =', + this.apiConfiguration + ); + console.log( + 'SDK debug: setNetworkConfig this.networkConfiguration B4 =', + this.networkConfiguration + ); if (useSpecificApiEndpoint && useSpecificApiEndpoint.trim() !== '') { this.apiConfiguration = useSpecificApiEndpoint.trim(); @@ -118,15 +125,15 @@ export class DataNft implements DataNftType { } console.log( - 'SDK debug: setNetworkConfig useSpecificApiEndpoint =', + 'SDK debug: setNetworkConfig useSpecificApiEndpoint A8 =', useSpecificApiEndpoint ); console.log( - 'SDK debug: setNetworkConfig this.apiConfiguration =', + 'SDK debug: setNetworkConfig this.apiConfiguration A8 =', this.apiConfiguration ); console.log( - 'SDK debug: setNetworkConfig this.networkConfiguration =', + 'SDK debug: setNetworkConfig this.networkConfiguration A8 =', this.networkConfiguration ); } From 9679af27d2dd03b98d566817df0b56ffe2615a41 Mon Sep 17 00:00:00 2001 From: Mark Paul Date: Mon, 11 Nov 2024 16:45:22 +1100 Subject: [PATCH 18/27] feature: upgrade the mvx core sdk --- package-lock.json | 238 ++++++++++++++++++++++++++++++++++++++++---- package.json | 4 +- src/common/utils.ts | 1 - src/contract.ts | 1 - 4 files changed, 223 insertions(+), 21 deletions(-) diff --git a/package-lock.json b/package-lock.json index 3da6b31..1b7ba70 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,15 +1,15 @@ { "name": "@itheum/sdk-mx-data-nft", - "version": "3.8.0-alpha.2", + "version": "3.8.0-alpha.8", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@itheum/sdk-mx-data-nft", - "version": "3.8.0-alpha.2", + "version": "3.8.0-alpha.8", "license": "GPL-3.0-only", "dependencies": { - "@multiversx/sdk-core": "13.9.0", + "@multiversx/sdk-core": "^13.14.1", "bignumber.js": "9.1.2", "nft.storage": "7.2.0" }, @@ -1941,20 +1941,40 @@ "murmurhash3js-revisited": "^3.0.0" } }, + "node_modules/@multiversx/sdk-bls-wasm": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@multiversx/sdk-bls-wasm/-/sdk-bls-wasm-0.3.5.tgz", + "integrity": "sha512-c0tIdQUnbBLSt6NYU+OpeGPYdL0+GV547HeHT8Xc0BKQ7Cj0v82QUoA2QRtWrR1G4MNZmLsIacZSsf6DrIS2Bw==", + "optional": true, + "engines": { + "node": ">=8.9.0" + } + }, "node_modules/@multiversx/sdk-core": { - "version": "13.9.0", - "resolved": "https://registry.npmjs.org/@multiversx/sdk-core/-/sdk-core-13.9.0.tgz", - "integrity": "sha512-WYA5fssMt/jTRTT+dkZW6V0ykCrkczhJ3BbZni6LhHjwFti7lMboVdoUMCIyPbecWZIEdmLq0OTcjOLy9tZX0g==", + "version": "13.14.1", + "resolved": "https://registry.npmjs.org/@multiversx/sdk-core/-/sdk-core-13.14.1.tgz", + "integrity": "sha512-PlUbeAWJVbqwCjF6zhlTPUTTMTatcI3YZtOa5K+YOs4Xk5UEuZcaKacvt1fNGZiSVubBlUlNK0jaxF3Hbi+VwA==", "dependencies": { "@multiversx/sdk-transaction-decoder": "1.0.2", + "@noble/ed25519": "1.7.3", + "@noble/hashes": "1.3.0", "bech32": "1.1.4", "blake2b": "2.1.3", "buffer": "6.0.3", + "ed25519-hd-key": "1.1.2", + "ed2curve": "0.3.0", "json-bigint": "1.0.0", - "keccak": "3.0.2" + "keccak": "3.0.2", + "scryptsy": "2.1.0", + "tweetnacl": "1.0.3", + "uuid": "8.3.2" }, - "peerDependencies": { + "optionalDependencies": { + "@multiversx/sdk-bls-wasm": "0.3.5", "axios": "^1.7.4", + "bip39": "3.1.0" + }, + "peerDependencies": { "bignumber.js": "^9.0.1", "protobufjs": "^7.2.6" } @@ -1972,6 +1992,28 @@ "resolved": "https://registry.npmjs.org/bech32/-/bech32-2.0.0.tgz", "integrity": "sha512-LcknSilhIGatDAsY1ak2I8VtGaHNhgMSYVxFrGLXv+xLHytaKZKcaUJJUE7qmBr7h33o5YQwP55pMI0xmkpJwg==" }, + "node_modules/@noble/ed25519": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/@noble/ed25519/-/ed25519-1.7.3.tgz", + "integrity": "sha512-iR8GBkDt0Q3GyaVcIu7mSsVIqnFbkbRzGLWlvhwunacoLwt4J3swfKhfaM6rN6WY+TBGoYT1GtT1mIh2/jGbRQ==", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ] + }, + "node_modules/@noble/hashes": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.0.tgz", + "integrity": "sha512-ilHEACi9DwqJB0pw7kv+Apvh50jiiSyR/cQ3y4W7lOR5mhvn/50FLUfsnfJz0BDZtl/RR16kXvptiv6q1msYZg==", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ] + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -3256,7 +3298,7 @@ "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "peer": true + "optional": true }, "node_modules/available-typed-arrays": { "version": "1.0.5", @@ -3273,7 +3315,7 @@ "version": "1.7.7", "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.7.tgz", "integrity": "sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==", - "peer": true, + "optional": true, "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.0", @@ -3414,6 +3456,15 @@ "node": "*" } }, + "node_modules/bip39": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/bip39/-/bip39-3.1.0.tgz", + "integrity": "sha512-c9kiwdk45Do5GL0vJMe7tS95VjCii65mYAH7DfWl3uW8AVzXKQVUm64i3hzVybBDMp9r7j9iNxR85+ul8MdN/A==", + "optional": true, + "dependencies": { + "@noble/hashes": "^1.2.0" + } + }, "node_modules/bl": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/bl/-/bl-5.1.0.tgz", @@ -3707,6 +3758,15 @@ "node": ">=8" } }, + "node_modules/cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, "node_modules/cjs-module-lexer": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz", @@ -3839,7 +3899,7 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "peer": true, + "optional": true, "dependencies": { "delayed-stream": "~1.0.0" }, @@ -4082,6 +4142,31 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/create-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "dependencies": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "node_modules/create-hmac": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "dependencies": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, "node_modules/create-jest": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/create-jest/-/create-jest-29.7.0.tgz", @@ -4247,7 +4332,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "peer": true, + "optional": true, "engines": { "node": ">=0.4.0" } @@ -4352,6 +4437,40 @@ "safe-buffer": "~5.1.0" } }, + "node_modules/ed25519-hd-key": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/ed25519-hd-key/-/ed25519-hd-key-1.1.2.tgz", + "integrity": "sha512-/0y9y6N7vM6Kj5ASr9J9wcMVDTtygxSOvYX+PJiMD7VcxCx2G03V5bLRl8Dug9EgkLFsLhGqBtQWQRcElEeWTA==", + "dependencies": { + "bip39": "3.0.2", + "create-hmac": "1.1.7", + "tweetnacl": "1.0.3" + } + }, + "node_modules/ed25519-hd-key/node_modules/@types/node": { + "version": "11.11.6", + "resolved": "https://registry.npmjs.org/@types/node/-/node-11.11.6.tgz", + "integrity": "sha512-Exw4yUWMBXM3X+8oqzJNRqZSwUAaS4+7NdvHqQuFi/d+synz++xmX3QIf+BFqneW8N31R8Ky+sikfZUXq07ggQ==" + }, + "node_modules/ed25519-hd-key/node_modules/bip39": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/bip39/-/bip39-3.0.2.tgz", + "integrity": "sha512-J4E1r2N0tUylTKt07ibXvhpT2c5pyAFgvuA5q1H9uDy6dEGpjV8jmymh3MTYJDLCNbIVClSB9FbND49I6N24MQ==", + "dependencies": { + "@types/node": "11.11.6", + "create-hash": "^1.1.0", + "pbkdf2": "^3.0.9", + "randombytes": "^2.0.1" + } + }, + "node_modules/ed2curve": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/ed2curve/-/ed2curve-0.3.0.tgz", + "integrity": "sha512-8w2fmmq3hv9rCrcI7g9hms2pMunQr1JINfcjwR9tAyZqhtyaMN991lF/ZfHfr5tzZQ8c7y7aBgZbjfbd0fjFwQ==", + "dependencies": { + "tweetnacl": "1.x.x" + } + }, "node_modules/ejs": { "version": "3.1.10", "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz", @@ -4848,7 +4967,7 @@ "url": "https://github.com/sponsors/RubenVerborgh" } ], - "peer": true, + "optional": true, "engines": { "node": ">=4.0" }, @@ -4870,7 +4989,7 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.1.tgz", "integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==", - "peer": true, + "optional": true, "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", @@ -5333,6 +5452,19 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/hash-base": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", + "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", + "dependencies": { + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/highlight.js": { "version": "10.7.3", "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz", @@ -7338,6 +7470,16 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "dependencies": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, "node_modules/mdurl": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz", @@ -7438,7 +7580,7 @@ "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "peer": true, + "optional": true, "engines": { "node": ">= 0.6" } @@ -7447,7 +7589,7 @@ "version": "2.1.35", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "peer": true, + "optional": true, "dependencies": { "mime-db": "1.52.0" }, @@ -10641,6 +10783,21 @@ "node": ">=8" } }, + "node_modules/pbkdf2": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", + "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", + "dependencies": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + }, + "engines": { + "node": ">=0.12" + } + }, "node_modules/picocolors": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", @@ -10863,7 +11020,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", - "peer": true + "optional": true }, "node_modules/punycode.js": { "version": "2.3.1", @@ -10934,6 +11091,14 @@ "rabin-wasm": "cli/bin.js" } }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, "node_modules/rc": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", @@ -11283,6 +11448,15 @@ "node": ">=0.10.0" } }, + "node_modules/ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "dependencies": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -11335,6 +11509,11 @@ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, + "node_modules/scryptsy": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/scryptsy/-/scryptsy-2.1.0.tgz", + "integrity": "sha512-1CdSqHQowJBnMAFyPEBRfqag/YP9OF394FV+4YREIJX4ljD7OxvQRDayyoyyCk+senRjSkP6VnUNQmVQqB6g7w==" + }, "node_modules/semantic-release": { "version": "24.0.0", "resolved": "https://registry.npmjs.org/semantic-release/-/semantic-release-24.0.0.tgz", @@ -11691,6 +11870,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + }, + "bin": { + "sha.js": "bin.js" + } + }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -12537,6 +12728,11 @@ "typescript": ">=2.1.0 || >=2.1.0-dev || >=2.2.0-dev || >=2.3.0-dev || >=2.4.0-dev || >=2.5.0-dev || >=2.6.0-dev || >=2.7.0-dev || >=2.8.0-dev || >=2.9.0-dev || >= 3.0.0-dev || >= 3.1.0-dev" } }, + "node_modules/tweetnacl": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", + "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==" + }, "node_modules/type-detect": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", @@ -12751,6 +12947,14 @@ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" }, + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "bin": { + "uuid": "dist/bin/uuid" + } + }, "node_modules/v8-to-istanbul": { "version": "9.1.0", "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.1.0.tgz", diff --git a/package.json b/package.json index 3328027..9d14bed 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@itheum/sdk-mx-data-nft", - "version": "3.8.0-alpha.8", + "version": "3.8.0-alpha.9", "description": "SDK for Itheum's Data NFT Technology on MultiversX Blockchain", "main": "out/index.js", "types": "out/index.d.js", @@ -17,7 +17,7 @@ "author": "Itheum Protocol", "license": "GPL-3.0-only", "dependencies": { - "@multiversx/sdk-core": "13.9.0", + "@multiversx/sdk-core": "13.14.1", "bignumber.js": "9.1.2", "nft.storage": "7.2.0" }, diff --git a/src/common/utils.ts b/src/common/utils.ts index c43905e..4615108 100644 --- a/src/common/utils.ts +++ b/src/common/utils.ts @@ -11,7 +11,6 @@ import { Bond, BondConfiguration, Compensation, - ContractConfiguration, LivelinessStakeConfiguration, NftEnumType, NftType, diff --git a/src/contract.ts b/src/contract.ts index 2be73f1..4fdad4a 100644 --- a/src/contract.ts +++ b/src/contract.ts @@ -1,6 +1,5 @@ import { AbiRegistry, - ErrContract, IAddress, SmartContract, ApiNetworkProvider From 943fb3d987f6432888ec37e76c49c45352114e65 Mon Sep 17 00:00:00 2001 From: Mark Paul Date: Mon, 11 Nov 2024 17:18:16 +1100 Subject: [PATCH 19/27] fi: downgrade the mvx core sdk --- package-lock.json | 238 ++++------------------------------------------ package.json | 4 +- 2 files changed, 19 insertions(+), 223 deletions(-) diff --git a/package-lock.json b/package-lock.json index 1b7ba70..6191054 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,15 +1,15 @@ { "name": "@itheum/sdk-mx-data-nft", - "version": "3.8.0-alpha.8", + "version": "3.8.0-alpha.9", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@itheum/sdk-mx-data-nft", - "version": "3.8.0-alpha.8", + "version": "3.8.0-alpha.9", "license": "GPL-3.0-only", "dependencies": { - "@multiversx/sdk-core": "^13.14.1", + "@multiversx/sdk-core": "^13.9.0", "bignumber.js": "9.1.2", "nft.storage": "7.2.0" }, @@ -1941,40 +1941,20 @@ "murmurhash3js-revisited": "^3.0.0" } }, - "node_modules/@multiversx/sdk-bls-wasm": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@multiversx/sdk-bls-wasm/-/sdk-bls-wasm-0.3.5.tgz", - "integrity": "sha512-c0tIdQUnbBLSt6NYU+OpeGPYdL0+GV547HeHT8Xc0BKQ7Cj0v82QUoA2QRtWrR1G4MNZmLsIacZSsf6DrIS2Bw==", - "optional": true, - "engines": { - "node": ">=8.9.0" - } - }, "node_modules/@multiversx/sdk-core": { - "version": "13.14.1", - "resolved": "https://registry.npmjs.org/@multiversx/sdk-core/-/sdk-core-13.14.1.tgz", - "integrity": "sha512-PlUbeAWJVbqwCjF6zhlTPUTTMTatcI3YZtOa5K+YOs4Xk5UEuZcaKacvt1fNGZiSVubBlUlNK0jaxF3Hbi+VwA==", + "version": "13.9.0", + "resolved": "https://registry.npmjs.org/@multiversx/sdk-core/-/sdk-core-13.9.0.tgz", + "integrity": "sha512-WYA5fssMt/jTRTT+dkZW6V0ykCrkczhJ3BbZni6LhHjwFti7lMboVdoUMCIyPbecWZIEdmLq0OTcjOLy9tZX0g==", "dependencies": { "@multiversx/sdk-transaction-decoder": "1.0.2", - "@noble/ed25519": "1.7.3", - "@noble/hashes": "1.3.0", "bech32": "1.1.4", "blake2b": "2.1.3", "buffer": "6.0.3", - "ed25519-hd-key": "1.1.2", - "ed2curve": "0.3.0", "json-bigint": "1.0.0", - "keccak": "3.0.2", - "scryptsy": "2.1.0", - "tweetnacl": "1.0.3", - "uuid": "8.3.2" - }, - "optionalDependencies": { - "@multiversx/sdk-bls-wasm": "0.3.5", - "axios": "^1.7.4", - "bip39": "3.1.0" + "keccak": "3.0.2" }, "peerDependencies": { + "axios": "^1.7.4", "bignumber.js": "^9.0.1", "protobufjs": "^7.2.6" } @@ -1992,28 +1972,6 @@ "resolved": "https://registry.npmjs.org/bech32/-/bech32-2.0.0.tgz", "integrity": "sha512-LcknSilhIGatDAsY1ak2I8VtGaHNhgMSYVxFrGLXv+xLHytaKZKcaUJJUE7qmBr7h33o5YQwP55pMI0xmkpJwg==" }, - "node_modules/@noble/ed25519": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/@noble/ed25519/-/ed25519-1.7.3.tgz", - "integrity": "sha512-iR8GBkDt0Q3GyaVcIu7mSsVIqnFbkbRzGLWlvhwunacoLwt4J3swfKhfaM6rN6WY+TBGoYT1GtT1mIh2/jGbRQ==", - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ] - }, - "node_modules/@noble/hashes": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.0.tgz", - "integrity": "sha512-ilHEACi9DwqJB0pw7kv+Apvh50jiiSyR/cQ3y4W7lOR5mhvn/50FLUfsnfJz0BDZtl/RR16kXvptiv6q1msYZg==", - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ] - }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -3298,7 +3256,7 @@ "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "optional": true + "peer": true }, "node_modules/available-typed-arrays": { "version": "1.0.5", @@ -3315,7 +3273,7 @@ "version": "1.7.7", "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.7.tgz", "integrity": "sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==", - "optional": true, + "peer": true, "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.0", @@ -3456,15 +3414,6 @@ "node": "*" } }, - "node_modules/bip39": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/bip39/-/bip39-3.1.0.tgz", - "integrity": "sha512-c9kiwdk45Do5GL0vJMe7tS95VjCii65mYAH7DfWl3uW8AVzXKQVUm64i3hzVybBDMp9r7j9iNxR85+ul8MdN/A==", - "optional": true, - "dependencies": { - "@noble/hashes": "^1.2.0" - } - }, "node_modules/bl": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/bl/-/bl-5.1.0.tgz", @@ -3758,15 +3707,6 @@ "node": ">=8" } }, - "node_modules/cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "dependencies": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, "node_modules/cjs-module-lexer": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz", @@ -3899,7 +3839,7 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "optional": true, + "peer": true, "dependencies": { "delayed-stream": "~1.0.0" }, @@ -4142,31 +4082,6 @@ "js-yaml": "bin/js-yaml.js" } }, - "node_modules/create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "dependencies": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "node_modules/create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "dependencies": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, "node_modules/create-jest": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/create-jest/-/create-jest-29.7.0.tgz", @@ -4332,7 +4247,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "optional": true, + "peer": true, "engines": { "node": ">=0.4.0" } @@ -4437,40 +4352,6 @@ "safe-buffer": "~5.1.0" } }, - "node_modules/ed25519-hd-key": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/ed25519-hd-key/-/ed25519-hd-key-1.1.2.tgz", - "integrity": "sha512-/0y9y6N7vM6Kj5ASr9J9wcMVDTtygxSOvYX+PJiMD7VcxCx2G03V5bLRl8Dug9EgkLFsLhGqBtQWQRcElEeWTA==", - "dependencies": { - "bip39": "3.0.2", - "create-hmac": "1.1.7", - "tweetnacl": "1.0.3" - } - }, - "node_modules/ed25519-hd-key/node_modules/@types/node": { - "version": "11.11.6", - "resolved": "https://registry.npmjs.org/@types/node/-/node-11.11.6.tgz", - "integrity": "sha512-Exw4yUWMBXM3X+8oqzJNRqZSwUAaS4+7NdvHqQuFi/d+synz++xmX3QIf+BFqneW8N31R8Ky+sikfZUXq07ggQ==" - }, - "node_modules/ed25519-hd-key/node_modules/bip39": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/bip39/-/bip39-3.0.2.tgz", - "integrity": "sha512-J4E1r2N0tUylTKt07ibXvhpT2c5pyAFgvuA5q1H9uDy6dEGpjV8jmymh3MTYJDLCNbIVClSB9FbND49I6N24MQ==", - "dependencies": { - "@types/node": "11.11.6", - "create-hash": "^1.1.0", - "pbkdf2": "^3.0.9", - "randombytes": "^2.0.1" - } - }, - "node_modules/ed2curve": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/ed2curve/-/ed2curve-0.3.0.tgz", - "integrity": "sha512-8w2fmmq3hv9rCrcI7g9hms2pMunQr1JINfcjwR9tAyZqhtyaMN991lF/ZfHfr5tzZQ8c7y7aBgZbjfbd0fjFwQ==", - "dependencies": { - "tweetnacl": "1.x.x" - } - }, "node_modules/ejs": { "version": "3.1.10", "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz", @@ -4967,7 +4848,7 @@ "url": "https://github.com/sponsors/RubenVerborgh" } ], - "optional": true, + "peer": true, "engines": { "node": ">=4.0" }, @@ -4989,7 +4870,7 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.1.tgz", "integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==", - "optional": true, + "peer": true, "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", @@ -5452,19 +5333,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/hash-base": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", - "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", - "dependencies": { - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/highlight.js": { "version": "10.7.3", "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz", @@ -7470,16 +7338,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "dependencies": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, "node_modules/mdurl": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz", @@ -7580,7 +7438,7 @@ "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "optional": true, + "peer": true, "engines": { "node": ">= 0.6" } @@ -7589,7 +7447,7 @@ "version": "2.1.35", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "optional": true, + "peer": true, "dependencies": { "mime-db": "1.52.0" }, @@ -10783,21 +10641,6 @@ "node": ">=8" } }, - "node_modules/pbkdf2": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", - "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", - "dependencies": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - }, - "engines": { - "node": ">=0.12" - } - }, "node_modules/picocolors": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", @@ -11020,7 +10863,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", - "optional": true + "peer": true }, "node_modules/punycode.js": { "version": "2.3.1", @@ -11091,14 +10934,6 @@ "rabin-wasm": "cli/bin.js" } }, - "node_modules/randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dependencies": { - "safe-buffer": "^5.1.0" - } - }, "node_modules/rc": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", @@ -11448,15 +11283,6 @@ "node": ">=0.10.0" } }, - "node_modules/ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "dependencies": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -11509,11 +11335,6 @@ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, - "node_modules/scryptsy": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/scryptsy/-/scryptsy-2.1.0.tgz", - "integrity": "sha512-1CdSqHQowJBnMAFyPEBRfqag/YP9OF394FV+4YREIJX4ljD7OxvQRDayyoyyCk+senRjSkP6VnUNQmVQqB6g7w==" - }, "node_modules/semantic-release": { "version": "24.0.0", "resolved": "https://registry.npmjs.org/semantic-release/-/semantic-release-24.0.0.tgz", @@ -11870,18 +11691,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "dependencies": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - }, - "bin": { - "sha.js": "bin.js" - } - }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -12728,11 +12537,6 @@ "typescript": ">=2.1.0 || >=2.1.0-dev || >=2.2.0-dev || >=2.3.0-dev || >=2.4.0-dev || >=2.5.0-dev || >=2.6.0-dev || >=2.7.0-dev || >=2.8.0-dev || >=2.9.0-dev || >= 3.0.0-dev || >= 3.1.0-dev" } }, - "node_modules/tweetnacl": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", - "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==" - }, "node_modules/type-detect": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", @@ -12947,14 +12751,6 @@ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" }, - "node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "bin": { - "uuid": "dist/bin/uuid" - } - }, "node_modules/v8-to-istanbul": { "version": "9.1.0", "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.1.0.tgz", diff --git a/package.json b/package.json index 9d14bed..404ca5a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@itheum/sdk-mx-data-nft", - "version": "3.8.0-alpha.9", + "version": "3.8.0-alpha.10", "description": "SDK for Itheum's Data NFT Technology on MultiversX Blockchain", "main": "out/index.js", "types": "out/index.d.js", @@ -17,7 +17,7 @@ "author": "Itheum Protocol", "license": "GPL-3.0-only", "dependencies": { - "@multiversx/sdk-core": "13.14.1", + "@multiversx/sdk-core": "13.9.0", "bignumber.js": "9.1.2", "nft.storage": "7.2.0" }, From 901eee10e612f0b89a513f13b5e1b8b5dba153de Mon Sep 17 00:00:00 2001 From: Mark Paul Date: Mon, 11 Nov 2024 18:59:31 +1100 Subject: [PATCH 20/27] fix: upgrade the mvx core sdk again --- package-lock.json | 238 ++++++++++++++++++++++++++++++++++++++++++---- package.json | 4 +- 2 files changed, 223 insertions(+), 19 deletions(-) diff --git a/package-lock.json b/package-lock.json index 6191054..59e2d6d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,15 +1,15 @@ { "name": "@itheum/sdk-mx-data-nft", - "version": "3.8.0-alpha.9", + "version": "3.8.0-alpha.10", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@itheum/sdk-mx-data-nft", - "version": "3.8.0-alpha.9", + "version": "3.8.0-alpha.10", "license": "GPL-3.0-only", "dependencies": { - "@multiversx/sdk-core": "^13.9.0", + "@multiversx/sdk-core": "^13.14.1", "bignumber.js": "9.1.2", "nft.storage": "7.2.0" }, @@ -1941,20 +1941,40 @@ "murmurhash3js-revisited": "^3.0.0" } }, + "node_modules/@multiversx/sdk-bls-wasm": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@multiversx/sdk-bls-wasm/-/sdk-bls-wasm-0.3.5.tgz", + "integrity": "sha512-c0tIdQUnbBLSt6NYU+OpeGPYdL0+GV547HeHT8Xc0BKQ7Cj0v82QUoA2QRtWrR1G4MNZmLsIacZSsf6DrIS2Bw==", + "optional": true, + "engines": { + "node": ">=8.9.0" + } + }, "node_modules/@multiversx/sdk-core": { - "version": "13.9.0", - "resolved": "https://registry.npmjs.org/@multiversx/sdk-core/-/sdk-core-13.9.0.tgz", - "integrity": "sha512-WYA5fssMt/jTRTT+dkZW6V0ykCrkczhJ3BbZni6LhHjwFti7lMboVdoUMCIyPbecWZIEdmLq0OTcjOLy9tZX0g==", + "version": "13.14.1", + "resolved": "https://registry.npmjs.org/@multiversx/sdk-core/-/sdk-core-13.14.1.tgz", + "integrity": "sha512-PlUbeAWJVbqwCjF6zhlTPUTTMTatcI3YZtOa5K+YOs4Xk5UEuZcaKacvt1fNGZiSVubBlUlNK0jaxF3Hbi+VwA==", "dependencies": { "@multiversx/sdk-transaction-decoder": "1.0.2", + "@noble/ed25519": "1.7.3", + "@noble/hashes": "1.3.0", "bech32": "1.1.4", "blake2b": "2.1.3", "buffer": "6.0.3", + "ed25519-hd-key": "1.1.2", + "ed2curve": "0.3.0", "json-bigint": "1.0.0", - "keccak": "3.0.2" + "keccak": "3.0.2", + "scryptsy": "2.1.0", + "tweetnacl": "1.0.3", + "uuid": "8.3.2" }, - "peerDependencies": { + "optionalDependencies": { + "@multiversx/sdk-bls-wasm": "0.3.5", "axios": "^1.7.4", + "bip39": "3.1.0" + }, + "peerDependencies": { "bignumber.js": "^9.0.1", "protobufjs": "^7.2.6" } @@ -1972,6 +1992,28 @@ "resolved": "https://registry.npmjs.org/bech32/-/bech32-2.0.0.tgz", "integrity": "sha512-LcknSilhIGatDAsY1ak2I8VtGaHNhgMSYVxFrGLXv+xLHytaKZKcaUJJUE7qmBr7h33o5YQwP55pMI0xmkpJwg==" }, + "node_modules/@noble/ed25519": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/@noble/ed25519/-/ed25519-1.7.3.tgz", + "integrity": "sha512-iR8GBkDt0Q3GyaVcIu7mSsVIqnFbkbRzGLWlvhwunacoLwt4J3swfKhfaM6rN6WY+TBGoYT1GtT1mIh2/jGbRQ==", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ] + }, + "node_modules/@noble/hashes": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.0.tgz", + "integrity": "sha512-ilHEACi9DwqJB0pw7kv+Apvh50jiiSyR/cQ3y4W7lOR5mhvn/50FLUfsnfJz0BDZtl/RR16kXvptiv6q1msYZg==", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ] + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -3256,7 +3298,7 @@ "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "peer": true + "optional": true }, "node_modules/available-typed-arrays": { "version": "1.0.5", @@ -3273,7 +3315,7 @@ "version": "1.7.7", "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.7.tgz", "integrity": "sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==", - "peer": true, + "optional": true, "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.0", @@ -3414,6 +3456,15 @@ "node": "*" } }, + "node_modules/bip39": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/bip39/-/bip39-3.1.0.tgz", + "integrity": "sha512-c9kiwdk45Do5GL0vJMe7tS95VjCii65mYAH7DfWl3uW8AVzXKQVUm64i3hzVybBDMp9r7j9iNxR85+ul8MdN/A==", + "optional": true, + "dependencies": { + "@noble/hashes": "^1.2.0" + } + }, "node_modules/bl": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/bl/-/bl-5.1.0.tgz", @@ -3707,6 +3758,15 @@ "node": ">=8" } }, + "node_modules/cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, "node_modules/cjs-module-lexer": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz", @@ -3839,7 +3899,7 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "peer": true, + "optional": true, "dependencies": { "delayed-stream": "~1.0.0" }, @@ -4082,6 +4142,31 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/create-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "dependencies": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "node_modules/create-hmac": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "dependencies": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, "node_modules/create-jest": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/create-jest/-/create-jest-29.7.0.tgz", @@ -4247,7 +4332,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "peer": true, + "optional": true, "engines": { "node": ">=0.4.0" } @@ -4352,6 +4437,40 @@ "safe-buffer": "~5.1.0" } }, + "node_modules/ed25519-hd-key": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/ed25519-hd-key/-/ed25519-hd-key-1.1.2.tgz", + "integrity": "sha512-/0y9y6N7vM6Kj5ASr9J9wcMVDTtygxSOvYX+PJiMD7VcxCx2G03V5bLRl8Dug9EgkLFsLhGqBtQWQRcElEeWTA==", + "dependencies": { + "bip39": "3.0.2", + "create-hmac": "1.1.7", + "tweetnacl": "1.0.3" + } + }, + "node_modules/ed25519-hd-key/node_modules/@types/node": { + "version": "11.11.6", + "resolved": "https://registry.npmjs.org/@types/node/-/node-11.11.6.tgz", + "integrity": "sha512-Exw4yUWMBXM3X+8oqzJNRqZSwUAaS4+7NdvHqQuFi/d+synz++xmX3QIf+BFqneW8N31R8Ky+sikfZUXq07ggQ==" + }, + "node_modules/ed25519-hd-key/node_modules/bip39": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/bip39/-/bip39-3.0.2.tgz", + "integrity": "sha512-J4E1r2N0tUylTKt07ibXvhpT2c5pyAFgvuA5q1H9uDy6dEGpjV8jmymh3MTYJDLCNbIVClSB9FbND49I6N24MQ==", + "dependencies": { + "@types/node": "11.11.6", + "create-hash": "^1.1.0", + "pbkdf2": "^3.0.9", + "randombytes": "^2.0.1" + } + }, + "node_modules/ed2curve": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/ed2curve/-/ed2curve-0.3.0.tgz", + "integrity": "sha512-8w2fmmq3hv9rCrcI7g9hms2pMunQr1JINfcjwR9tAyZqhtyaMN991lF/ZfHfr5tzZQ8c7y7aBgZbjfbd0fjFwQ==", + "dependencies": { + "tweetnacl": "1.x.x" + } + }, "node_modules/ejs": { "version": "3.1.10", "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz", @@ -4848,7 +4967,7 @@ "url": "https://github.com/sponsors/RubenVerborgh" } ], - "peer": true, + "optional": true, "engines": { "node": ">=4.0" }, @@ -4870,7 +4989,7 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.1.tgz", "integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==", - "peer": true, + "optional": true, "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", @@ -5333,6 +5452,19 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/hash-base": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", + "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", + "dependencies": { + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/highlight.js": { "version": "10.7.3", "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz", @@ -7338,6 +7470,16 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "dependencies": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, "node_modules/mdurl": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz", @@ -7438,7 +7580,7 @@ "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "peer": true, + "optional": true, "engines": { "node": ">= 0.6" } @@ -7447,7 +7589,7 @@ "version": "2.1.35", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "peer": true, + "optional": true, "dependencies": { "mime-db": "1.52.0" }, @@ -10641,6 +10783,21 @@ "node": ">=8" } }, + "node_modules/pbkdf2": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", + "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", + "dependencies": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + }, + "engines": { + "node": ">=0.12" + } + }, "node_modules/picocolors": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", @@ -10863,7 +11020,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", - "peer": true + "optional": true }, "node_modules/punycode.js": { "version": "2.3.1", @@ -10934,6 +11091,14 @@ "rabin-wasm": "cli/bin.js" } }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, "node_modules/rc": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", @@ -11283,6 +11448,15 @@ "node": ">=0.10.0" } }, + "node_modules/ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "dependencies": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -11335,6 +11509,11 @@ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, + "node_modules/scryptsy": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/scryptsy/-/scryptsy-2.1.0.tgz", + "integrity": "sha512-1CdSqHQowJBnMAFyPEBRfqag/YP9OF394FV+4YREIJX4ljD7OxvQRDayyoyyCk+senRjSkP6VnUNQmVQqB6g7w==" + }, "node_modules/semantic-release": { "version": "24.0.0", "resolved": "https://registry.npmjs.org/semantic-release/-/semantic-release-24.0.0.tgz", @@ -11691,6 +11870,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + }, + "bin": { + "sha.js": "bin.js" + } + }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -12537,6 +12728,11 @@ "typescript": ">=2.1.0 || >=2.1.0-dev || >=2.2.0-dev || >=2.3.0-dev || >=2.4.0-dev || >=2.5.0-dev || >=2.6.0-dev || >=2.7.0-dev || >=2.8.0-dev || >=2.9.0-dev || >= 3.0.0-dev || >= 3.1.0-dev" } }, + "node_modules/tweetnacl": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", + "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==" + }, "node_modules/type-detect": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", @@ -12751,6 +12947,14 @@ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" }, + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "bin": { + "uuid": "dist/bin/uuid" + } + }, "node_modules/v8-to-istanbul": { "version": "9.1.0", "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.1.0.tgz", diff --git a/package.json b/package.json index 404ca5a..5f1359b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@itheum/sdk-mx-data-nft", - "version": "3.8.0-alpha.10", + "version": "3.8.0-alpha.11", "description": "SDK for Itheum's Data NFT Technology on MultiversX Blockchain", "main": "out/index.js", "types": "out/index.d.js", @@ -17,7 +17,7 @@ "author": "Itheum Protocol", "license": "GPL-3.0-only", "dependencies": { - "@multiversx/sdk-core": "13.9.0", + "@multiversx/sdk-core": "13.14.1", "bignumber.js": "9.1.2", "nft.storage": "7.2.0" }, From 1f3b02cb159621176985faed8f617906366ea6c7 Mon Sep 17 00:00:00 2001 From: Mark Paul Date: Thu, 14 Nov 2024 11:54:45 +1100 Subject: [PATCH 21/27] feature: make data nft createManyFromApi and ownedByAddress to be opt into cache module --- package.json | 2 +- src/common/utils.ts | 6 ++--- src/datanft.ts | 55 ++++++++++++++++++++++++++++++++++++--------- 3 files changed, 49 insertions(+), 14 deletions(-) diff --git a/package.json b/package.json index 5f1359b..5d647e2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@itheum/sdk-mx-data-nft", - "version": "3.8.0-alpha.11", + "version": "3.8.0-alpha.12", "description": "SDK for Itheum's Data NFT Technology on MultiversX Blockchain", "main": "out/index.js", "types": "out/index.d.js", diff --git a/src/common/utils.ts b/src/common/utils.ts index 4615108..4a52e23 100644 --- a/src/common/utils.ts +++ b/src/common/utils.ts @@ -611,16 +611,16 @@ export function getDataFromClientSessionCache(cacheKey: string) { const cacheObject = sessionCache[cacheKey]; if (!cacheObject) { - console.log('getDataFromClientSessionCache: not found'); + console.log(`getDataFromClientSessionCache: ${cacheKey} not found`); return false; } else { // did it expire? is so, delete it from the cache if (Date.now() - cacheObject.addedOn > cacheObject.expireAfter) { - console.log('getDataFromClientSessionCache: expired'); + console.log(`getDataFromClientSessionCache: ${cacheKey} expired`); delete sessionCache[cacheKey]; // remove it from cache as its expired return false; } else { - console.log('getDataFromClientSessionCache: available'); + console.log(`getDataFromClientSessionCache: ${cacheKey} available`); return cacheObject.payload; } } diff --git a/src/datanft.ts b/src/datanft.ts index 7ecfb08..40bbd04 100644 --- a/src/datanft.ts +++ b/src/datanft.ts @@ -178,10 +178,12 @@ export class DataNft implements DataNftType { * Each object should have a `nonce` property representing the token nonce. * An optional `tokenIdentifier` property can be provided to specify the token identifier. * If not provided, the default token identifier based on the {@link EnvironmentsEnum} + * @param clientCacheForMS optional. You can cache the response for this amount of MS if you want. Don't pass it in if you don't want caching (needs to be "undefined") * @returns An array of {@link DataNft} objects */ static async createManyFromApi( - tokens: { nonce: number; tokenIdentifier?: string }[] + tokens: { nonce: number; tokenIdentifier?: string }[], + clientCacheForMS?: number ): Promise { this.ensureNetworkConfigSet(); const identifiers = tokens.map(({ nonce, tokenIdentifier }) => @@ -190,6 +192,7 @@ export class DataNft implements DataNftType { nonce ) ); + if (identifiers.length > MAX_ITEMS) { throw new ErrTooManyItems(); } @@ -208,14 +211,24 @@ export class DataNft implements DataNftType { }`; // check if its in session cache + let useCache = typeof clientCacheForMS !== 'undefined'; let jsonDataPayload = null; - const getFromSessionCache = getDataFromClientSessionCache(fetchUrl); + const getFromSessionCache = useCache + ? getDataFromClientSessionCache(fetchUrl) + : false; if (!getFromSessionCache) { const response = await fetch(fetchUrl); checkStatus(response); jsonDataPayload = await response.json(); - setDataToClientSessionCache(fetchUrl, jsonDataPayload, 5 * 60 * 1000); + + if (useCache) { + setDataToClientSessionCache( + fetchUrl, + jsonDataPayload, + clientCacheForMS + ); + } } else { jsonDataPayload = getFromSessionCache; } @@ -292,10 +305,12 @@ export class DataNft implements DataNftType { * Returns an array of `DataNft` objects owned by the address * @param address the address to query * @param collections the collection identifiers to query. If not provided, the default collection identifier based on the {@link EnvironmentsEnum} + * @param clientCacheForMS optional. You can cache the response for this amount of MS if you want. Don't pass it in if you don't want caching (needs to be "undefined") */ static async ownedByAddress( address: string, - collections?: string[] + collections?: string[], + clientCacheForMS?: number ): Promise { this.ensureNetworkConfigSet(); @@ -303,15 +318,35 @@ export class DataNft implements DataNftType { collections?.join(',') || dataNftTokenIdentifier[this.env as EnvironmentsEnum]; - const res = await fetch( - `${this.apiConfiguration}/accounts/${address}/nfts?size=10000&collections=${identifiersMap}&withSupply=true` - ); + console.log('SDK debug: ownedByAddress api =', this.apiConfiguration); - checkStatus(res); + const fetchUrl = `${this.apiConfiguration}/accounts/${address}/nfts?size=10000&collections=${identifiersMap}&withSupply=true`; - const data = await res.json(); + // check if its in session cache + let useCache = typeof clientCacheForMS !== 'undefined'; + let jsonDataPayload = null; + const getFromSessionCache = useCache + ? getDataFromClientSessionCache(fetchUrl) + : false; + + if (!getFromSessionCache) { + const response = await fetch(fetchUrl); + checkStatus(response); + jsonDataPayload = await response.json(); + + if (useCache) { + setDataToClientSessionCache( + fetchUrl, + jsonDataPayload, + clientCacheForMS + ); + } + } else { + jsonDataPayload = getFromSessionCache; + } - const dataNfts: DataNft[] = this.createFromApiResponseOrBulk(data); + const dataNfts: DataNft[] = + this.createFromApiResponseOrBulk(jsonDataPayload); return dataNfts; } From 4141cc6a215bb9bd62d092e050ab11e407ef50b4 Mon Sep 17 00:00:00 2001 From: Mark Paul Date: Thu, 14 Nov 2024 12:09:02 +1100 Subject: [PATCH 22/27] version bump --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 5d647e2..f3b64b9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@itheum/sdk-mx-data-nft", - "version": "3.8.0-alpha.12", + "version": "3.8.0-alpha.15", "description": "SDK for Itheum's Data NFT Technology on MultiversX Blockchain", "main": "out/index.js", "types": "out/index.d.js", From 0521f532c7db85455c0ab7e00c04b522a3acdf78 Mon Sep 17 00:00:00 2001 From: Mark Paul Date: Fri, 22 Nov 2024 15:50:58 +1100 Subject: [PATCH 23/27] feature: sol mint aligned to backend service updates --- package.json | 2 +- src/cnft-sol-minter.ts | 9 +++++++-- src/config.ts | 21 ++++++++++++++++++--- src/minter-sol.ts | 16 ++++++++++++---- 4 files changed, 38 insertions(+), 10 deletions(-) diff --git a/package.json b/package.json index f3b64b9..2072dfd 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@itheum/sdk-mx-data-nft", - "version": "3.8.0-alpha.15", + "version": "3.8.0-alpha.16", "description": "SDK for Itheum's Data NFT Technology on MultiversX Blockchain", "main": "out/index.js", "types": "out/index.d.js", diff --git a/src/cnft-sol-minter.ts b/src/cnft-sol-minter.ts index fd71e5c..0c42cf2 100644 --- a/src/cnft-sol-minter.ts +++ b/src/cnft-sol-minter.ts @@ -9,6 +9,7 @@ import { ErrArgumentNotSet } from './errors'; import { MinterSol } from './minter-sol'; import { StringValidator, validateResults } from './common/validator'; import { CNftSolPostMintMetaType } from './interfaces'; +import { SolEnvChainIDEnum } from './config'; export class CNftSolMinter extends MinterSol { /** @@ -220,7 +221,11 @@ export class CNftSolMinter extends MinterSol { tokenName, mintForSolAddr: creatorAddress, solSignature: solSignature || '', - signatureNonce: signatureNonce || '' + signatureNonce: signatureNonce || '', + chainId: + this.env === 'devnet' + ? SolEnvChainIDEnum.devnet + : SolEnvChainIDEnum.mainnet }); const requestOptions = { @@ -233,7 +238,7 @@ export class CNftSolMinter extends MinterSol { let dataMintCall: any = ''; resMintCall = await fetch( - this.solCNftMinterServiceUrl, + this.solCNftNfMeIdMinterServiceUrl, requestOptions ); diff --git a/src/config.ts b/src/config.ts index 4c4cc61..85e8731 100644 --- a/src/config.ts +++ b/src/config.ts @@ -1,3 +1,8 @@ +export enum SolEnvChainIDEnum { + devnet = 'SD', + mainnet = 'S1' +} + export enum EnvironmentsEnum { devnet = 'devnet', testnet = 'testnet', @@ -82,9 +87,19 @@ export const imageService: { [key in EnvironmentsEnum]: string } = { testnet: '' }; -export const solCNftMinterService: { [key in EnvironmentsEnum]: string } = { - devnet: 'https://api.itheumcloud-stg.com/datadexapi/solNftUtils/mintNft', - mainnet: 'https://api.itheumcloud.com/datadexapi/solNftUtils/mintNft', +export const solCNftNfMeIdMinterService: { [key in EnvironmentsEnum]: string } = + { + devnet: + 'https://api.itheumcloud-stg.com/datadexapi/solNftUtils/mintNfMeIdDataNft', + mainnet: + 'https://api.itheumcloud.com/datadexapi/solNftUtils/mintNfMeIdDataNft', + testnet: '' + }; + +export const solCNftMiscMinterService: { [key in EnvironmentsEnum]: string } = { + devnet: + 'https://api.itheumcloud-stg.com/datadexapi/solNftUtils/mintMiscDataNft', + mainnet: 'https://api.itheumcloud.com/datadexapi/solNftUtils/mintMiscDataNft', testnet: '' }; diff --git a/src/minter-sol.ts b/src/minter-sol.ts index cf8cc61..311f513 100644 --- a/src/minter-sol.ts +++ b/src/minter-sol.ts @@ -1,14 +1,22 @@ -import { EnvironmentsEnum, imageService, solCNftMinterService } from './config'; +import { + EnvironmentsEnum, + imageService, + solCNftNfMeIdMinterService, + solCNftMiscMinterService +} from './config'; import { ContractSol } from './contract-sol'; export abstract class MinterSol extends ContractSol { readonly imageServiceUrl: string; - readonly solCNftMinterServiceUrl: string; + readonly solCNftNfMeIdMinterServiceUrl: string; + readonly solCNftMiscMinterServiceUrl: string; protected constructor(env: string) { super(env); this.imageServiceUrl = imageService[env as EnvironmentsEnum]; - this.solCNftMinterServiceUrl = - solCNftMinterService[env as EnvironmentsEnum]; + this.solCNftNfMeIdMinterServiceUrl = + solCNftNfMeIdMinterService[env as EnvironmentsEnum]; + this.solCNftMiscMinterServiceUrl = + solCNftMiscMinterService[env as EnvironmentsEnum]; } } From 8c2d1503d9dedc7fc03a1bbaef4cd890c740260d Mon Sep 17 00:00:00 2001 From: Mark Paul Date: Wed, 27 Nov 2024 11:54:16 +1100 Subject: [PATCH 24/27] feature: on solana mininting, we allow the user to send their own custom ipfs gateway to see if this solves the image not appearing issue --- package.json | 2 +- src/cnft-sol-minter.ts | 11 +++++++--- src/common/mint-utils.ts | 46 +++++++++++++++++++++++++++++++++------- 3 files changed, 47 insertions(+), 12 deletions(-) diff --git a/package.json b/package.json index 2072dfd..c685d10 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@itheum/sdk-mx-data-nft", - "version": "3.8.0-alpha.16", + "version": "3.8.0-alpha.17", "description": "SDK for Itheum's Data NFT Technology on MultiversX Blockchain", "main": "out/index.js", "types": "out/index.d.js", diff --git a/src/cnft-sol-minter.ts b/src/cnft-sol-minter.ts index 0c42cf2..4b75b62 100644 --- a/src/cnft-sol-minter.ts +++ b/src/cnft-sol-minter.ts @@ -43,6 +43,7 @@ export class CNftSolMinter extends MinterSol { * - imgGenSet: [optional] the custom series layer set to influence the image generation service * - signatureNonce: [optional] a recent nonce from the marshal network that will be signed to produce solSignature * - solSignature: [optional] a solana signature of signatureNonce to prove creatorAddress ownership + * - useThisCustomIPFSGateway: [optional] a custom ipfs gateway to use for the img and json. where the CID goes in a {insertCIDHere} placeholder e.g. https://gateway.pinata.cloud/ipfs/{insertCIDHere}. * */ async mint( @@ -62,6 +63,7 @@ export class CNftSolMinter extends MinterSol { imgGenSet?: string; signatureNonce?: string; solSignature?: string; + useThisCustomIPFSGateway?: string; } ): Promise<{ imageUrl: string; @@ -81,7 +83,8 @@ export class CNftSolMinter extends MinterSol { imgGenBg, imgGenSet, signatureNonce, - solSignature + solSignature, + useThisCustomIPFSGateway } = options ?? {}; const tokenNameValidator = new StringValidator() @@ -160,7 +163,8 @@ export class CNftSolMinter extends MinterSol { const { imageOnIpfsUrl: imgOnIpfsUrl } = await storeToIpfsOnlyImg( nftStorageToken, - _imageFile + _imageFile, + useThisCustomIPFSGateway ); if (!imgOnIpfsUrl || imgOnIpfsUrl === '') { @@ -182,7 +186,8 @@ export class CNftSolMinter extends MinterSol { const { metadataIpfsUrl } = await storeToIpfsFullSolCNftMetadata( nftStorageToken, - cNftMetadataContent + cNftMetadataContent, + useThisCustomIPFSGateway ); if (!metadataIpfsUrl || metadataIpfsUrl === '') { diff --git a/src/common/mint-utils.ts b/src/common/mint-utils.ts index 5310f7c..ca7e054 100644 --- a/src/common/mint-utils.ts +++ b/src/common/mint-utils.ts @@ -62,7 +62,8 @@ export async function storeToIpfs( export async function storeToIpfsFullSolCNftMetadata( storageToken: string, - metadataStructureSolCNft: object + metadataStructureSolCNft: object, + useThisCustomIPFSGateway?: string ): Promise<{ metadataIpfsUrl: string }> { try { const metadataIpfsHash = await storeTraitsToIpfs( @@ -71,9 +72,23 @@ export async function storeToIpfsFullSolCNftMetadata( ); if (metadataIpfsHash) { - return { - metadataIpfsUrl: `https://ipfs.io/ipfs/${metadataIpfsHash}` - }; + if ( + useThisCustomIPFSGateway && + useThisCustomIPFSGateway.includes('https://') && + useThisCustomIPFSGateway.includes('{insertCIDHere}') + ) { + // user wanted to use a custom gateway + return { + metadataIpfsUrl: useThisCustomIPFSGateway.replace( + '{insertCIDHere}', + metadataIpfsHash + ) + }; + } else { + return { + metadataIpfsUrl: `https://ipfs.io/ipfs/${metadataIpfsHash}` + }; + } } else { return { metadataIpfsUrl: '' @@ -86,15 +101,30 @@ export async function storeToIpfsFullSolCNftMetadata( export async function storeToIpfsOnlyImg( storageToken: string, - image: Blob + image: Blob, + useThisCustomIPFSGateway?: string ): Promise<{ imageOnIpfsUrl: string }> { try { const imageHash = await storeImageToIpfs(image, storageToken); if (imageHash) { - return { - imageOnIpfsUrl: `https://ipfs.io/ipfs/${imageHash}` - }; + if ( + useThisCustomIPFSGateway && + useThisCustomIPFSGateway.includes('https://') && + useThisCustomIPFSGateway.includes('{insertCIDHere}') + ) { + // user wanted to use a custom gateway + return { + imageOnIpfsUrl: useThisCustomIPFSGateway.replace( + '{insertCIDHere}', + imageHash + ) + }; + } else { + return { + imageOnIpfsUrl: `https://ipfs.io/ipfs/${imageHash}` + }; + } } else { return { imageOnIpfsUrl: '' From 3736df388c4ac7805c775fe3f27e490f6b644031 Mon Sep 17 00:00:00 2001 From: Mark Paul Date: Wed, 11 Dec 2024 23:22:44 +1100 Subject: [PATCH 25/27] feature: allow the solana nft mint to support skipGettingMintMeta flag --- package.json | 2 +- src/cnft-sol-minter.ts | 15 ++++++++++++--- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index c685d10..471d1d0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@itheum/sdk-mx-data-nft", - "version": "3.8.0-alpha.17", + "version": "3.8.0-alpha.18", "description": "SDK for Itheum's Data NFT Technology on MultiversX Blockchain", "main": "out/index.js", "types": "out/index.d.js", diff --git a/src/cnft-sol-minter.ts b/src/cnft-sol-minter.ts index 4b75b62..bba27bf 100644 --- a/src/cnft-sol-minter.ts +++ b/src/cnft-sol-minter.ts @@ -44,6 +44,7 @@ export class CNftSolMinter extends MinterSol { * - signatureNonce: [optional] a recent nonce from the marshal network that will be signed to produce solSignature * - solSignature: [optional] a solana signature of signatureNonce to prove creatorAddress ownership * - useThisCustomIPFSGateway: [optional] a custom ipfs gateway to use for the img and json. where the CID goes in a {insertCIDHere} placeholder e.g. https://gateway.pinata.cloud/ipfs/{insertCIDHere}. + * - skipGettingMintMeta: [optional] if we send "1", then the minting service only mints and does not return any mint meta from the cNFT leaf etc * */ async mint( @@ -64,6 +65,7 @@ export class CNftSolMinter extends MinterSol { signatureNonce?: string; solSignature?: string; useThisCustomIPFSGateway?: string; + skipGettingMintMeta?: string; } ): Promise<{ imageUrl: string; @@ -84,7 +86,8 @@ export class CNftSolMinter extends MinterSol { imgGenSet, signatureNonce, solSignature, - useThisCustomIPFSGateway + useThisCustomIPFSGateway, + skipGettingMintMeta } = options ?? {}; const tokenNameValidator = new StringValidator() @@ -221,7 +224,7 @@ export class CNftSolMinter extends MinterSol { const postHeaders = new Headers(); postHeaders.append('Content-Type', 'application/json'); - const raw = JSON.stringify({ + const payload: Record = { metadataOnIpfsUrl, tokenName, mintForSolAddr: creatorAddress, @@ -231,7 +234,13 @@ export class CNftSolMinter extends MinterSol { this.env === 'devnet' ? SolEnvChainIDEnum.devnet : SolEnvChainIDEnum.mainnet - }); + }; + + if (skipGettingMintMeta && skipGettingMintMeta === '1') { + payload['skipGettingMintMeta'] = '1'; + } + + const raw = JSON.stringify(payload); const requestOptions = { method: 'POST', From ecb98288c0b615ed8acb77a2bf7965feed7dd499 Mon Sep 17 00:00:00 2001 From: Mark Paul Date: Wed, 11 Dec 2024 23:31:05 +1100 Subject: [PATCH 26/27] fix: unit tests --- tests/nftminter.test.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/nftminter.test.ts b/tests/nftminter.test.ts index c4d3463..2a0709b 100644 --- a/tests/nftminter.test.ts +++ b/tests/nftminter.test.ts @@ -49,7 +49,7 @@ describe('Nft minter test', () => { 'TokenName', 'https://d37x5igq4vw5mq.cloudfront.net/datamarshalapi/router/v1', 'https://raw.githubusercontent.com/Itheum/data-assets/main/Health/H1__Signs_of_Anxiety_in_American_Households_due_to_Covid19/dataset.json', - 'https://itheumapi.com/programReadingPreview/70dc6bd0-59b0-11e8-8d54-2d562f6cba54', + 'https://raw.githubusercontent.com/Itheum/data-assets/main/Health/H1__Signs_of_Anxiety_in_American_Households_due_to_Covid19/dataset.json?p=1', 1000, 'Title for token', 'Description for token', @@ -76,7 +76,7 @@ describe('Nft minter test', () => { 'TokenName', 'https://d37x5igq4vw5mq.cloudfront.net/datamarshalapi/router/v1', 'https://raw.githubusercontent.com/Itheum/data-assets/main/Health/H1__Signs_of_Anxiety_in_American_Households_due_to_Covid19/dataset.json', - 'https://itheumapi.com/programReadingPreview/70dc6bd0-59b0-11e8-8d54-2d562f6cba54', + 'https://raw.githubusercontent.com/Itheum/data-assets/main/Health/H1__Signs_of_Anxiety_in_American_Households_due_to_Covid19/dataset.json?p=1', 1000, 'Title for token', 'Description for token', @@ -104,7 +104,7 @@ describe('Nft minter test', () => { 'TokenName', 'https://d37x5igq4vw5mq.cloudfront.net/datamarshalapi/router/v1', 'https://raw.githubusercontent.com/Itheum/data-assets/main/Health/H1__Signs_of_Anxiety_in_American_Households_due_to_Covid19/dataset.json', - 'https://itheumapi.com/programReadingPreview/70dc6bd0-59b0-11e8-8d54-2d562f6cba54', + 'https://raw.githubusercontent.com/Itheum/data-assets/main/Health/H1__Signs_of_Anxiety_in_American_Households_due_to_Covid19/dataset.json?p=1', 1000, 'Title for token', 'Description for token', From d06e316992a96fd03bbe8759816d93a1e70cdfde Mon Sep 17 00:00:00 2001 From: Mark Paul Date: Thu, 12 Dec 2024 21:31:47 +1100 Subject: [PATCH 27/27] feature: for sol mint of cNFT, use the attributes that drip mentioned so the indexers work better --- package.json | 2 +- src/cnft-sol-minter.ts | 2 +- src/common/mint-utils.ts | 14 +++++++++++++- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 471d1d0..5fb40ae 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@itheum/sdk-mx-data-nft", - "version": "3.8.0-alpha.18", + "version": "3.8.0-alpha.19", "description": "SDK for Itheum's Data NFT Technology on MultiversX Blockchain", "main": "out/index.js", "types": "out/index.d.js", diff --git a/src/cnft-sol-minter.ts b/src/cnft-sol-minter.ts index bba27bf..6561ee4 100644 --- a/src/cnft-sol-minter.ts +++ b/src/cnft-sol-minter.ts @@ -35,7 +35,7 @@ export class CNftSolMinter extends MinterSol { * @param datasetTitle the title of the dataset. Between 10 and 60 alphanumeric characters. * @param datasetDescription the description of the dataset. Between 10 and 400 alphanumeric characters. * @param options [optional] below parameters are optional or required based on use case - * - imageUrl: the URL of the image for the Data NFT + * - imageUrl: the URL of the image for the Data NFT (HAS to be PNG as the cNFT metadata hardcodes the filetype property as PNG) * - traitsUrl: the URL of the traits for the Data NFT * - nftStorageToken: the nft storage token to be used to upload the image and metadata to IPFS * - extraAssets: [optional] extra URIs to attached to the NFT. Can be media files, documents, etc. These URIs are public diff --git a/src/common/mint-utils.ts b/src/common/mint-utils.ts index ca7e054..4de0daf 100644 --- a/src/common/mint-utils.ts +++ b/src/common/mint-utils.ts @@ -230,7 +230,19 @@ export function createIpfsMetadataSolCNft( itheum_data_stream_url: dataNFTStreamUrl, itheum_data_preview_url: dataNFTStreamPreviewUrl, itheum_data_marshal_url: dataNFTDataMarshalUrl, - attributes: [] as object[] + attributes: [] as object[], + animation_url: '', + external_url: 'https://itheum.io/datanfts-solana', + properties: { + category: 'image', + files: [ + { + type: 'image/png', + uri: imageOnIpfsUrl + } + ] + }, + symbol: '' }; if (extraAssets && extraAssets.length > 0) {