diff --git a/README.md b/README.md
index 5c9961b..4ae1957 100644
--- a/README.md
+++ b/README.md
@@ -43,7 +43,7 @@ const dataNft = new DataNft({
// Create a new DataNft object from API
const nonce = 1;
-const nft = await DataNft.createFromApi(nonce);
+const nft = await DataNft.createFromApi({ nonce });
// Create a new DataNft object from API Response
const response = await fetch('https://devnet-api.multiversx.com/address/nfts');
@@ -60,7 +60,7 @@ const dataNfts = [];
dataNfts = await DataNft.ownedByAddress(address);
// Retrieves the specific DataNft
-const dataNft = DataNft.createFromApi(nonce);
+const dataNft = DataNft.createFromApi({ nonce });
// (A) Get a message from the Data Marshal node for your to sign to prove ownership
const message = await dataNft.messageToSign();
diff --git a/package-lock.json b/package-lock.json
index f6c1422..47f9f4b 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "@itheum/sdk-mx-data-nft",
- "version": "1.0.0",
+ "version": "1.1.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@itheum/sdk-mx-data-nft",
- "version": "1.0.0",
+ "version": "1.1.0",
"license": "GPL-3.0-only",
"dependencies": {
"@multiversx/sdk-core": "12.6.0",
diff --git a/package.json b/package.json
index 78df9ff..7889621 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@itheum/sdk-mx-data-nft",
- "version": "1.0.0",
+ "version": "1.2.0",
"description": "SDK for Itheum's Data NFT Technology on MultiversX Blockchain",
"main": "out/index.js",
"types": "out/index.d.js",
@@ -16,17 +16,17 @@
"author": "Itheum Protocol",
"license": "GPL-3.0-only",
"dependencies": {
- "@multiversx/sdk-core": "12.6.0",
- "@multiversx/sdk-network-providers": "1.5.0",
- "bignumber.js": "^9.1.1",
- "nft.storage": "^7.1.1"
+ "@multiversx/sdk-core": "12.8.0",
+ "@multiversx/sdk-network-providers": "2.0.0",
+ "bignumber.js": "9.1.2",
+ "nft.storage": "7.1.1"
},
"devDependencies": {
- "@types/jest": "^29.5.1",
- "jest": "^29.5.0",
- "ts-jest": "^29.1.0",
- "tslint": "^6.1.3",
- "typescript": "^5.0.4"
+ "@types/jest": "29.5.4",
+ "jest": "29.7.0",
+ "ts-jest": "29.1.1",
+ "tslint": "6.1.3",
+ "typescript": "5.2.2"
},
"repository": {
"type": "git",
diff --git a/src/abis/data-nft-lease.abi.json b/src/abis/data-nft-lease.abi.json
new file mode 100644
index 0000000..05adf82
--- /dev/null
+++ b/src/abis/data-nft-lease.abi.json
@@ -0,0 +1,1069 @@
+{
+ "buildInfo": {
+ "rustc": {
+ "version": "1.71.0-nightly",
+ "commitHash": "7f94b314cead7059a71a265a8b64905ef2511796",
+ "commitDate": "2023-04-23",
+ "channel": "Nightly",
+ "short": "rustc 1.71.0-nightly (7f94b314c 2023-04-23)"
+ },
+ "contractCrate": {
+ "name": "data-nft-lease",
+ "version": "1.0.0"
+ },
+ "framework": {
+ "name": "multiversx-sc",
+ "version": "0.43.2"
+ }
+ },
+ "name": "DataNftMint",
+ "constructor": {
+ "inputs": [
+ {
+ "name": "administrator",
+ "type": "optional
",
+ "multi_arg": true
+ }
+ ],
+ "outputs": []
+ },
+ "endpoints": [
+ {
+ "name": "initializeContract",
+ "mutability": "mutable",
+ "payableInTokens": [
+ "EGLD"
+ ],
+ "inputs": [
+ {
+ "name": "collection_name",
+ "type": "bytes"
+ },
+ {
+ "name": "token_ticker",
+ "type": "bytes"
+ },
+ {
+ "name": "mint_time_limit",
+ "type": "u64"
+ },
+ {
+ "name": "require_mint_tax",
+ "type": "bool"
+ },
+ {
+ "name": "payment",
+ "type": "optional>",
+ "multi_arg": true
+ }
+ ],
+ "outputs": []
+ },
+ {
+ "name": "setLocalRoles",
+ "mutability": "mutable",
+ "inputs": [],
+ "outputs": []
+ },
+ {
+ "name": "updateAttributes",
+ "mutability": "mutable",
+ "payableInTokens": [
+ "*"
+ ],
+ "inputs": [
+ {
+ "name": "data_marshal",
+ "type": "bytes"
+ },
+ {
+ "name": "data_stream",
+ "type": "bytes"
+ },
+ {
+ "name": "data_preview",
+ "type": "bytes"
+ },
+ {
+ "name": "creator",
+ "type": "Address"
+ },
+ {
+ "name": "title",
+ "type": "bytes"
+ },
+ {
+ "name": "description",
+ "type": "bytes"
+ }
+ ],
+ "outputs": []
+ },
+ {
+ "name": "setTransferRole",
+ "mutability": "mutable",
+ "inputs": [
+ {
+ "name": "address",
+ "type": "Address"
+ }
+ ],
+ "outputs": []
+ },
+ {
+ "name": "unsetTransferRole",
+ "mutability": "mutable",
+ "inputs": [
+ {
+ "name": "address",
+ "type": "Address"
+ }
+ ],
+ "outputs": []
+ },
+ {
+ "name": "mint",
+ "mutability": "mutable",
+ "payableInTokens": [
+ "*"
+ ],
+ "inputs": [
+ {
+ "name": "name",
+ "type": "bytes"
+ },
+ {
+ "name": "media",
+ "type": "bytes"
+ },
+ {
+ "name": "metadata",
+ "type": "bytes"
+ },
+ {
+ "name": "data_marshal",
+ "type": "bytes"
+ },
+ {
+ "name": "data_stream",
+ "type": "bytes"
+ },
+ {
+ "name": "data_preview",
+ "type": "bytes"
+ },
+ {
+ "name": "royalties",
+ "type": "BigUint"
+ },
+ {
+ "name": "title",
+ "type": "bytes"
+ },
+ {
+ "name": "description",
+ "type": "bytes"
+ }
+ ],
+ "outputs": [
+ {
+ "type": "DataNftAttributes"
+ }
+ ]
+ },
+ {
+ "name": "burn",
+ "mutability": "mutable",
+ "payableInTokens": [
+ "*"
+ ],
+ "inputs": [],
+ "outputs": []
+ },
+ {
+ "name": "setIsPaused",
+ "mutability": "mutable",
+ "inputs": [
+ {
+ "name": "is_paused",
+ "type": "bool"
+ }
+ ],
+ "outputs": []
+ },
+ {
+ "name": "setAntiSpamTax",
+ "mutability": "mutable",
+ "inputs": [
+ {
+ "name": "token_id",
+ "type": "EgldOrEsdtTokenIdentifier"
+ },
+ {
+ "name": "tax",
+ "type": "BigUint"
+ }
+ ],
+ "outputs": []
+ },
+ {
+ "name": "setTaxIsRequired",
+ "mutability": "mutable",
+ "inputs": [
+ {
+ "name": "is_required",
+ "type": "bool"
+ }
+ ],
+ "outputs": []
+ },
+ {
+ "name": "setWhiteListEnabled",
+ "mutability": "mutable",
+ "inputs": [
+ {
+ "name": "is_enabled",
+ "type": "bool"
+ }
+ ],
+ "outputs": []
+ },
+ {
+ "name": "setWhiteListSpots",
+ "mutability": "mutable",
+ "inputs": [
+ {
+ "name": "whitelist",
+ "type": "variadic",
+ "multi_arg": true
+ }
+ ],
+ "outputs": []
+ },
+ {
+ "name": "removeWhiteListSpots",
+ "mutability": "mutable",
+ "inputs": [
+ {
+ "name": "whitelist",
+ "type": "variadic",
+ "multi_arg": true
+ }
+ ],
+ "outputs": []
+ },
+ {
+ "name": "setMintTimeLimit",
+ "mutability": "mutable",
+ "inputs": [
+ {
+ "name": "mint_time_limit",
+ "type": "u64"
+ }
+ ],
+ "outputs": []
+ },
+ {
+ "name": "setRoyaltiesLimits",
+ "mutability": "mutable",
+ "inputs": [
+ {
+ "name": "min_royalties",
+ "type": "BigUint"
+ },
+ {
+ "name": "max_royalties",
+ "type": "BigUint"
+ }
+ ],
+ "outputs": []
+ },
+ {
+ "name": "setAdministrator",
+ "onlyOwner": true,
+ "mutability": "mutable",
+ "inputs": [
+ {
+ "name": "administrator",
+ "type": "Address"
+ }
+ ],
+ "outputs": []
+ },
+ {
+ "name": "setTax",
+ "onlyOwner": true,
+ "mutability": "mutable",
+ "inputs": [
+ {
+ "name": "itheum_address",
+ "type": "Address"
+ },
+ {
+ "name": "tax",
+ "type": "BigUint"
+ }
+ ],
+ "outputs": [
+ {
+ "type": "BigUint"
+ }
+ ]
+ },
+ {
+ "name": "setClaimsAddress",
+ "mutability": "mutable",
+ "inputs": [
+ {
+ "name": "address",
+ "type": "Address"
+ }
+ ],
+ "outputs": []
+ },
+ {
+ "name": "claimRoyalties",
+ "mutability": "mutable",
+ "inputs": [
+ {
+ "name": "token_identifier",
+ "type": "EgldOrEsdtTokenIdentifier"
+ },
+ {
+ "name": "nonce",
+ "type": "u64"
+ }
+ ],
+ "outputs": []
+ },
+ {
+ "name": "getTokenId",
+ "mutability": "readonly",
+ "inputs": [],
+ "outputs": [
+ {
+ "type": "TokenIdentifier"
+ }
+ ]
+ },
+ {
+ "name": "getMintedTokens",
+ "mutability": "readonly",
+ "inputs": [],
+ "outputs": [
+ {
+ "type": "BigUint"
+ }
+ ]
+ },
+ {
+ "name": "getMintTax",
+ "mutability": "readonly",
+ "inputs": [
+ {
+ "name": "token",
+ "type": "EgldOrEsdtTokenIdentifier"
+ }
+ ],
+ "outputs": [
+ {
+ "type": "BigUint"
+ }
+ ]
+ },
+ {
+ "name": "getTaxIsRequired",
+ "mutability": "readonly",
+ "inputs": [],
+ "outputs": [
+ {
+ "type": "bool"
+ }
+ ]
+ },
+ {
+ "name": "getIsPaused",
+ "mutability": "readonly",
+ "inputs": [],
+ "outputs": [
+ {
+ "type": "bool"
+ }
+ ]
+ },
+ {
+ "name": "getMaxRoyalties",
+ "mutability": "readonly",
+ "inputs": [],
+ "outputs": [
+ {
+ "type": "BigUint"
+ }
+ ]
+ },
+ {
+ "name": "getMinRoyalties",
+ "mutability": "readonly",
+ "inputs": [],
+ "outputs": [
+ {
+ "type": "BigUint"
+ }
+ ]
+ },
+ {
+ "name": "getMintedPerAddress",
+ "mutability": "readonly",
+ "inputs": [
+ {
+ "name": "address",
+ "type": "Address"
+ }
+ ],
+ "outputs": [
+ {
+ "type": "BigUint"
+ }
+ ]
+ },
+ {
+ "name": "mintTimeLimit",
+ "mutability": "readonly",
+ "inputs": [],
+ "outputs": [
+ {
+ "type": "u64"
+ }
+ ]
+ },
+ {
+ "name": "lastMintTime",
+ "mutability": "readonly",
+ "inputs": [
+ {
+ "name": "address",
+ "type": "Address"
+ }
+ ],
+ "outputs": [
+ {
+ "type": "u64"
+ }
+ ]
+ },
+ {
+ "name": "getWhiteList",
+ "mutability": "readonly",
+ "inputs": [],
+ "outputs": [
+ {
+ "type": "variadic",
+ "multi_result": true
+ }
+ ]
+ },
+ {
+ "name": "getCollectionFrozenList",
+ "mutability": "readonly",
+ "inputs": [],
+ "outputs": [
+ {
+ "type": "variadic",
+ "multi_result": true
+ }
+ ]
+ },
+ {
+ "name": "getSftsFrozenForAddress",
+ "mutability": "readonly",
+ "inputs": [
+ {
+ "name": "address",
+ "type": "Address"
+ }
+ ],
+ "outputs": [
+ {
+ "type": "variadic",
+ "multi_result": true
+ }
+ ]
+ },
+ {
+ "name": "getFrozenCount",
+ "mutability": "readonly",
+ "inputs": [
+ {
+ "name": "address",
+ "type": "Address"
+ }
+ ],
+ "outputs": [
+ {
+ "type": "u32"
+ }
+ ]
+ },
+ {
+ "name": "isWhiteListEnabled",
+ "mutability": "readonly",
+ "inputs": [],
+ "outputs": [
+ {
+ "type": "bool"
+ }
+ ]
+ },
+ {
+ "name": "rolesAreSet",
+ "mutability": "readonly",
+ "inputs": [],
+ "outputs": [
+ {
+ "type": "bool"
+ }
+ ]
+ },
+ {
+ "name": "getAddressesWithTransferRole",
+ "mutability": "readonly",
+ "inputs": [],
+ "outputs": [
+ {
+ "type": "variadic",
+ "multi_result": true
+ }
+ ]
+ },
+ {
+ "name": "getAddressesWithUpdateAttributesRole",
+ "mutability": "readonly",
+ "inputs": [],
+ "outputs": [
+ {
+ "type": "variadic",
+ "multi_result": true
+ }
+ ]
+ },
+ {
+ "name": "getAdministrator",
+ "mutability": "readonly",
+ "inputs": [],
+ "outputs": [
+ {
+ "type": "Address"
+ }
+ ]
+ },
+ {
+ "name": "getItheumTax",
+ "mutability": "readonly",
+ "inputs": [],
+ "outputs": [
+ {
+ "type": "BigUint"
+ }
+ ]
+ },
+ {
+ "name": "getItheumTaxAddress",
+ "mutability": "readonly",
+ "inputs": [],
+ "outputs": [
+ {
+ "type": "Address"
+ }
+ ]
+ },
+ {
+ "name": "getClaimsAddress",
+ "mutability": "readonly",
+ "inputs": [],
+ "outputs": [
+ {
+ "type": "Address"
+ }
+ ]
+ },
+ {
+ "name": "getUserDataOut",
+ "mutability": "readonly",
+ "inputs": [
+ {
+ "name": "address",
+ "type": "Address"
+ },
+ {
+ "name": "tax_token",
+ "type": "EgldOrEsdtTokenIdentifier"
+ }
+ ],
+ "outputs": [
+ {
+ "type": "UserDataOut"
+ }
+ ]
+ },
+ {
+ "name": "pause",
+ "mutability": "mutable",
+ "inputs": [],
+ "outputs": []
+ },
+ {
+ "name": "unpause",
+ "mutability": "mutable",
+ "inputs": [],
+ "outputs": []
+ },
+ {
+ "name": "freeze",
+ "mutability": "mutable",
+ "inputs": [
+ {
+ "name": "address",
+ "type": "Address"
+ }
+ ],
+ "outputs": []
+ },
+ {
+ "name": "unfreeze",
+ "mutability": "mutable",
+ "inputs": [
+ {
+ "name": "address",
+ "type": "Address"
+ }
+ ],
+ "outputs": []
+ },
+ {
+ "name": "freezeSingleNFT",
+ "mutability": "mutable",
+ "inputs": [
+ {
+ "name": "nonce",
+ "type": "u64"
+ },
+ {
+ "name": "address",
+ "type": "Address"
+ }
+ ],
+ "outputs": []
+ },
+ {
+ "name": "unFreezeSingleNFT",
+ "mutability": "mutable",
+ "inputs": [
+ {
+ "name": "nonce",
+ "type": "u64"
+ },
+ {
+ "name": "address",
+ "type": "Address"
+ }
+ ],
+ "outputs": []
+ },
+ {
+ "name": "wipeSingleNFT",
+ "mutability": "mutable",
+ "inputs": [
+ {
+ "name": "nonce",
+ "type": "u64"
+ },
+ {
+ "name": "address",
+ "type": "Address"
+ }
+ ],
+ "outputs": []
+ }
+ ],
+ "events": [
+ {
+ "identifier": "mintPauseToggle",
+ "inputs": [
+ {
+ "name": "pause_value",
+ "type": "bool",
+ "indexed": true
+ }
+ ]
+ },
+ {
+ "identifier": "setTreasuryAddress",
+ "inputs": [
+ {
+ "name": "treasury_address",
+ "type": "Address",
+ "indexed": true
+ }
+ ]
+ },
+ {
+ "identifier": "whitelistEnableToggle",
+ "inputs": [
+ {
+ "name": "enable_value",
+ "type": "bool",
+ "indexed": true
+ }
+ ]
+ },
+ {
+ "identifier": "whitelistSpotSet",
+ "inputs": [
+ {
+ "name": "address",
+ "type": "Address",
+ "indexed": true
+ }
+ ]
+ },
+ {
+ "identifier": "collectionFreezeListSpotSet",
+ "inputs": [
+ {
+ "name": "address",
+ "type": "Address",
+ "indexed": true
+ }
+ ]
+ },
+ {
+ "identifier": "frozenSftsPerAddress",
+ "inputs": [
+ {
+ "name": "address",
+ "type": "Address",
+ "indexed": true
+ },
+ {
+ "name": "nonce",
+ "type": "u64",
+ "indexed": true
+ }
+ ]
+ },
+ {
+ "identifier": "unfrozenSftsPerAddress",
+ "inputs": [
+ {
+ "name": "address",
+ "type": "Address",
+ "indexed": true
+ },
+ {
+ "name": "nonce",
+ "type": "u64",
+ "indexed": true
+ }
+ ]
+ },
+ {
+ "identifier": "collectionFreezeListRemoved",
+ "inputs": [
+ {
+ "name": "address",
+ "type": "Address",
+ "indexed": true
+ }
+ ]
+ },
+ {
+ "identifier": "whitelistSpotRemoved",
+ "inputs": [
+ {
+ "name": "address",
+ "type": "Address",
+ "indexed": true
+ }
+ ]
+ },
+ {
+ "identifier": "setRoyaltiesLimits",
+ "inputs": [
+ {
+ "name": "min_royalties",
+ "type": "BigUint",
+ "indexed": true
+ },
+ {
+ "name": "max_royalties",
+ "type": "BigUint",
+ "indexed": true
+ }
+ ]
+ },
+ {
+ "identifier": "antiSpamTaxSet",
+ "inputs": [
+ {
+ "name": "token",
+ "type": "EgldOrEsdtTokenIdentifier",
+ "indexed": true
+ },
+ {
+ "name": "amount",
+ "type": "BigUint",
+ "indexed": true
+ }
+ ]
+ },
+ {
+ "identifier": "taxIsRequired",
+ "inputs": [
+ {
+ "name": "tax_is_required",
+ "type": "bool",
+ "indexed": true
+ }
+ ]
+ },
+ {
+ "identifier": "mintTimeLimitSet",
+ "inputs": [
+ {
+ "name": "mint_time_limit",
+ "type": "u64",
+ "indexed": true
+ }
+ ]
+ },
+ {
+ "identifier": "setAdministrator",
+ "inputs": [
+ {
+ "name": "administrator",
+ "type": "Address",
+ "indexed": true
+ }
+ ]
+ },
+ {
+ "identifier": "pauseCollection",
+ "inputs": [
+ {
+ "name": "token_identifier",
+ "type": "TokenIdentifier",
+ "indexed": true
+ }
+ ]
+ },
+ {
+ "identifier": "unpauseCollection",
+ "inputs": [
+ {
+ "name": "token_identifier",
+ "type": "TokenIdentifier",
+ "indexed": true
+ }
+ ]
+ },
+ {
+ "identifier": "freeze",
+ "inputs": [
+ {
+ "name": "address",
+ "type": "Address",
+ "indexed": true
+ },
+ {
+ "name": "token_identifier",
+ "type": "TokenIdentifier",
+ "indexed": true
+ },
+ {
+ "name": "nonce",
+ "type": "u64",
+ "indexed": true
+ }
+ ]
+ },
+ {
+ "identifier": "unfreeze",
+ "inputs": [
+ {
+ "name": "address",
+ "type": "Address",
+ "indexed": true
+ },
+ {
+ "name": "token_identifier",
+ "type": "TokenIdentifier",
+ "indexed": true
+ },
+ {
+ "name": "nonce",
+ "type": "u64",
+ "indexed": true
+ }
+ ]
+ },
+ {
+ "identifier": "wipe",
+ "inputs": [
+ {
+ "name": "address",
+ "type": "Address",
+ "indexed": true
+ },
+ {
+ "name": "token_identifier",
+ "type": "TokenIdentifier",
+ "indexed": true
+ },
+ {
+ "name": "nonce",
+ "type": "u64",
+ "indexed": true
+ }
+ ]
+ },
+ {
+ "identifier": "burn",
+ "inputs": [
+ {
+ "name": "address",
+ "type": "Address",
+ "indexed": true
+ },
+ {
+ "name": "token_identifier",
+ "type": "TokenIdentifier",
+ "indexed": true
+ },
+ {
+ "name": "nonce",
+ "type": "u64",
+ "indexed": true
+ },
+ {
+ "name": "amount",
+ "type": "BigUint",
+ "indexed": true
+ }
+ ]
+ },
+ {
+ "identifier": "mint",
+ "inputs": [
+ {
+ "name": "address",
+ "type": "Address",
+ "indexed": true
+ },
+ {
+ "name": "amount",
+ "type": "BigUint",
+ "indexed": true
+ },
+ {
+ "name": "token",
+ "type": "EgldOrEsdtTokenIdentifier",
+ "indexed": true
+ },
+ {
+ "name": "price",
+ "type": "BigUint",
+ "indexed": true
+ }
+ ]
+ }
+ ],
+ "hasCallback": true,
+ "types": {
+ "DataNftAttributes": {
+ "type": "struct",
+ "fields": [
+ {
+ "name": "data_stream_url",
+ "type": "bytes"
+ },
+ {
+ "name": "data_preview_url",
+ "type": "bytes"
+ },
+ {
+ "name": "data_marshal_url",
+ "type": "bytes"
+ },
+ {
+ "name": "creator",
+ "type": "Address"
+ },
+ {
+ "name": "creation_time",
+ "type": "u64"
+ },
+ {
+ "name": "title",
+ "type": "bytes"
+ },
+ {
+ "name": "description",
+ "type": "bytes"
+ }
+ ]
+ },
+ "UserDataOut": {
+ "type": "struct",
+ "fields": [
+ {
+ "name": "anti_spam_tax_value",
+ "type": "BigUint"
+ },
+ {
+ "name": "is_paused",
+ "type": "bool"
+ },
+ {
+ "name": "max_royalties",
+ "type": "BigUint"
+ },
+ {
+ "name": "min_royalties",
+ "type": "BigUint"
+ },
+ {
+ "name": "mint_time_limit",
+ "type": "u64"
+ },
+ {
+ "name": "last_mint_time",
+ "type": "u64"
+ },
+ {
+ "name": "whitelist_enabled",
+ "type": "bool"
+ },
+ {
+ "name": "is_whitelisted",
+ "type": "bool"
+ },
+ {
+ "name": "minted_per_user",
+ "type": "BigUint"
+ },
+ {
+ "name": "total_minted",
+ "type": "BigUint"
+ },
+ {
+ "name": "frozen",
+ "type": "bool"
+ },
+ {
+ "name": "frozen_nonces",
+ "type": "List"
+ }
+ ]
+ }
+ }
+}
diff --git a/src/datanft.ts b/src/datanft.ts
index 7df3728..f2dac8a 100644
--- a/src/datanft.ts
+++ b/src/datanft.ts
@@ -15,7 +15,8 @@ import {
createNftIdentifier,
numberToPaddedHex,
parseDataNft,
- validateSpecificParamsViewData
+ validateSpecificParamsViewData,
+ checkStatus
} from './utils';
import minterAbi from './abis/datanftmint.abi.json';
import { NftType, ViewDataReturnType } from './interfaces';
@@ -253,6 +254,7 @@ export class DataNft {
* @param fwdAllHeaders [optional] Forward all request headers to the Origin Data Stream server.
* @param fwdHeaderKeys [optional] Forward only selected headers to the Origin Data Stream server. Has priority over fwdAllHeaders param. A comma separated lowercase string with less than 5 items. e.g. cookie,authorization
* @param fwdHeaderMapLookup [optional] Used with fwdHeaderKeys to set a front-end client side lookup map of headers the SDK uses to setup the forward. e.g. { cookie : "xyz", authorization : "Bearer zxy" }. Note that these are case-sensitive and need to match fwdHeaderKeys exactly.
+ * @param nestedIdxToStream [optional] If you are accessing a "nested stream", this is the index of the nested item you want drill into and fetch
*/
async viewData(p: {
signedMessage: string;
@@ -263,6 +265,7 @@ export class DataNft {
fwdHeaderMapLookup?: {
[key: string]: any;
};
+ nestedIdxToStream?: number;
}): Promise {
DataNft.ensureNetworkConfigSet();
if (!this.dataMarshal) {
@@ -283,6 +286,7 @@ export class DataNft {
fwdAllHeaders: p.fwdAllHeaders,
fwdHeaderKeys: p.fwdHeaderKeys,
fwdHeaderMapLookup: p.fwdHeaderMapLookup,
+ nestedIdxToStream: p.nestedIdxToStream,
_mandatoryParamsList: ['signedMessage', 'signableMessage']
});
@@ -339,6 +343,10 @@ export class DataNft {
url += p.fwdAllHeaders ? '&fwdAllHeaders=1' : '';
}
+ if (typeof p.nestedIdxToStream !== 'undefined') {
+ url += `&nestedIdxToStream=${p.nestedIdxToStream}`;
+ }
+
if (typeof p.fwdHeaderKeys !== 'undefined') {
url += `&fwdHeaderKeys=${p.fwdHeaderKeys}`;
@@ -360,6 +368,20 @@ export class DataNft {
const contentType = response.headers.get('content-type');
const data = await response.blob();
+ // if the marshal returned a error, we should throw it here so that the SDK integrator can handle it
+ // ... if we don't, the marshal error response is just passed through as a normal data stream response
+ // ... and the user won't know what went wrong
+ try {
+ checkStatus(response);
+ } catch (e: any) {
+ // as it's a data marshal error, we get it's payload which is in JSON and send that thrown as text
+ const errorPayload = await (data as Blob).text();
+
+ throw new Error(
+ `${e.toString()}. Detailed error trace follows : ${errorPayload}`
+ );
+ }
+
return {
data: data,
contentType: contentType || ''
@@ -381,6 +403,7 @@ export class DataNft {
* @param fwdHeaderKeys [optional] Forward only selected headers to the Origin Data Stream server. Has priority over fwdAllHeaders param. A comma separated lowercase string with less than 5 items. e.g. cookie,authorization
* @param fwdAllHeaders [optional] Forward all request headers to the Origin Data Stream server.
* @param stream [optional] Instead of auto-downloading if possible, request if data should always be streamed or not.i.e true=stream, false/undefined=default behavior
+ * @param nestedIdxToStream [optional] If you are accessing a "nested stream", this is the index of the nested item you want drill into and fetch
*/
async viewDataViaMVXNativeAuth(p: {
mvxNativeAuthOrigins: string[];
@@ -391,6 +414,7 @@ export class DataNft {
fwdHeaderKeys?: string;
fwdAllHeaders?: boolean;
stream?: boolean;
+ nestedIdxToStream?: number;
}): Promise {
try {
// S: run any format specific validation
@@ -401,6 +425,7 @@ export class DataNft {
fwdHeaderMapLookup: p.fwdHeaderMapLookup,
fwdAllHeaders: p.fwdAllHeaders,
stream: p.stream,
+ nestedIdxToStream: p.nestedIdxToStream,
_fwdHeaderMapLookupMustContainBearerAuthHeader: true,
_mandatoryParamsList: [
'mvxNativeAuthOrigins',
@@ -451,6 +476,10 @@ export class DataNft {
url += p.fwdAllHeaders ? '&fwdAllHeaders=1' : '';
}
+ if (typeof p.nestedIdxToStream !== 'undefined') {
+ url += `&nestedIdxToStream=${p.nestedIdxToStream}`;
+ }
+
// if fwdHeaderMapLookup exists, send these headers and values to the data marshal for forwarding
if (
typeof p.fwdHeaderMapLookup !== 'undefined' &&
@@ -480,6 +509,20 @@ export class DataNft {
const contentType = response.headers.get('content-type');
const data = await response.blob();
+ // if the marshal returned a error, we should throw it here so that the SDK integrator can handle it
+ // ... if we don't, the marshal error response is just passed through as a normal data stream response
+ // ... and the user won't know what went wrong
+ try {
+ checkStatus(response);
+ } catch (e: any) {
+ // as it's a data marshal error, we get it's payload which is in JSON and send that thrown as text
+ const errorPayload = await (data as Blob).text();
+
+ throw new Error(
+ `${e.toString()}. Detailed error trace follows : ${errorPayload}`
+ );
+ }
+
return {
data: data,
contentType: contentType || ''
diff --git a/src/index.ts b/src/index.ts
index 875bff2..82ea680 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -5,3 +5,5 @@ export * from './datanft';
export * from './utils';
export * from './utils';
export * from './minter';
+export * from './nft-minter';
+export * from './sft-minter';
diff --git a/src/minter.ts b/src/minter.ts
index 4f979ce..68f2ff3 100644
--- a/src/minter.ts
+++ b/src/minter.ts
@@ -20,13 +20,9 @@ import {
dataNftTokenIdentifier,
imageService,
itheumTokenIdentifier,
- minterContractAddress,
networkConfiguration
} from './config';
-import dataNftMintAbi from './abis/datanftmint.abi.json';
-import { MinterRequirements } from './interfaces';
-import { NFTStorage } from 'nft.storage';
-import { File } from '@web-std/file';
+import { NFTStorage, File } from 'nft.storage';
import {
checkStatus,
checkTraitsUrl,
@@ -41,7 +37,7 @@ import {
ErrParamValidation
} from './errors';
-export class DataNftMinter {
+export class Minter {
readonly contract: SmartContract;
readonly chainID: string;
readonly networkProvider: ApiNetworkProvider;
@@ -53,12 +49,12 @@ export class DataNftMinter {
* @param env 'devnet' | 'mainnet' | 'testnet'
* @param timeout Timeout for the network provider (DEFAULT = 10000ms)
*/
- constructor(env: string, timeout: number = 10000) {
- if (!(env in EnvironmentsEnum)) {
- throw new ErrNetworkConfig(
- `Invalid environment: ${env}, Expected: 'devnet' | 'mainnet' | 'testnet'`
- );
- }
+ protected constructor(
+ env: string,
+ contractAddress: string,
+ abiFile: any,
+ timeout: number = 10000
+ ) {
this.env = env;
const networkConfig = networkConfiguration[env as EnvironmentsEnum];
this.imageServiceUrl = imageService[env as EnvironmentsEnum];
@@ -69,10 +65,9 @@ export class DataNftMinter {
timeout: timeout
}
);
- const contractAddress = minterContractAddress[env as EnvironmentsEnum];
this.contract = new SmartContract({
address: new Address(contractAddress),
- abi: AbiRegistry.create(dataNftMintAbi)
+ abi: AbiRegistry.create(abiFile)
});
}
@@ -83,52 +78,6 @@ export class DataNftMinter {
return this.contract.getAddress();
}
- /**
- * Retrieves the minter smart contract requirements for the given user
- * @param address the address of the user
- * @param taxToken the tax token to be used for the minting (default = `ITHEUM` token identifier based on the {@link EnvironmentsEnum})
- */
- async viewMinterRequirements(
- address: IAddress,
- taxToken = itheumTokenIdentifier[this.env as EnvironmentsEnum]
- ): Promise {
- const interaction = this.contract.methodsExplicit.getUserDataOut([
- new AddressValue(address),
- new TokenIdentifierValue(taxToken)
- ]);
- const query = interaction.buildQuery();
- const queryResponse = await this.networkProvider.queryContract(query);
- const endpointDefinition = interaction.getEndpoint();
- const { firstValue, returnCode } = new ResultsParser().parseQueryResponse(
- queryResponse,
- endpointDefinition
- );
- if (returnCode.isSuccess()) {
- const returnValue = firstValue?.valueOf();
- const requirements: MinterRequirements = {
- antiSpamTaxValue: returnValue.anti_spam_tax_value.toNumber(),
- contractPaused: returnValue.is_paused,
- maxRoyalties: returnValue.max_royalties.toNumber(),
- minRoyalties: returnValue.min_royalties.toNumber(),
- maxSupply: returnValue.max_supply.toNumber(),
- mintTimeLimit: returnValue.mint_time_limit.toNumber(),
- lastUserMintTime: returnValue.last_mint_time,
- userWhitelistedForMint: returnValue.is_whitelisted,
- contractWhitelistEnabled: returnValue.whitelist_enabled,
- numberOfMintsForUser: returnValue.minted_per_user.toNumber(),
- totalNumberOfMints: returnValue.total_minted.toNumber(),
- addressFrozen: returnValue.frozen,
- frozenNonces: returnValue.frozen_nonces.map((v: any) => v.toNumber())
- };
- return requirements;
- } else {
- throw new ErrContractQuery(
- 'viewMinterRequirements',
- returnCode.toString()
- );
- }
- }
-
/**
* Retrieves the smart contract pause state
*/
diff --git a/src/nft-minter.ts b/src/nft-minter.ts
new file mode 100644
index 0000000..8ab6cec
--- /dev/null
+++ b/src/nft-minter.ts
@@ -0,0 +1,424 @@
+import {
+ Address,
+ AddressValue,
+ BigUIntValue,
+ BooleanValue,
+ ContractCallPayloadBuilder,
+ ContractFunction,
+ IAddress,
+ StringValue,
+ TokenIdentifierValue,
+ Transaction,
+ U64Value
+} from '@multiversx/sdk-core/out';
+import { Minter } from './minter';
+import dataNftLeaseAbi from './abis/data-nft-lease.abi.json';
+
+export class NftMinter extends Minter {
+ constructor(env: string, contractAddress: string, timeout: number = 10000) {
+ super(env, contractAddress, dataNftLeaseAbi, timeout);
+ }
+
+ /**
+ * Creates an initialize contract transaction for the contract
+ * @param senderAddress The address of the sender, must be the admin of the contract
+ * @param collectionName The name of the NFT collection
+ * @param tokenTicker The ticker of the NFT collection
+ * @param mintLimit(seconds)- The mint limit between mints
+ * @param requireMintTax - A boolean value to set if the mint tax is required or not
+ * @param options - If `requireMintTax` is true, the `options` object must contain the `taxTokenIdentifier` and `taxTokenAmount`
+ */
+ initializeContract(
+ senderAddress: IAddress,
+ collectionName: string,
+ tokenTicker: string,
+ mintLimit: number,
+ requireMintTax: boolean,
+ options: {
+ taxTokenIdentifier: string;
+ taxTokenAmount: number;
+ }
+ ): Transaction {
+ let data;
+ if (requireMintTax && options) {
+ data = new ContractCallPayloadBuilder()
+ .setFunction(new ContractFunction('initializeContract'))
+ .addArg(new StringValue(collectionName))
+ .addArg(new StringValue(tokenTicker))
+ .addArg(new BigUIntValue(mintLimit))
+ .addArg(new BooleanValue(requireMintTax))
+ .addArg(new TokenIdentifierValue(options.taxTokenIdentifier))
+ .addArg(new BigUIntValue(options.taxTokenAmount))
+ .build();
+ } else {
+ data = new ContractCallPayloadBuilder()
+ .setFunction(new ContractFunction('initializeContract'))
+ .addArg(new StringValue(collectionName))
+ .addArg(new StringValue(tokenTicker))
+ .addArg(new BigUIntValue(mintLimit))
+ .addArg(new BooleanValue(requireMintTax))
+ .build();
+ }
+
+ const initializeContractTx = new Transaction({
+ value: 50000000000000000,
+ data: data,
+ receiver: this.contract.getAddress(),
+ gasLimit: 10000000,
+ sender: senderAddress,
+ chainID: this.chainID
+ });
+ return initializeContractTx;
+ }
+
+ /**
+ * Creates a updateAttributes transaction for the contract
+ * @param senderAddress The address of the sender, must be the admin of the contract
+ * @param tokenIdentiifer The token identifier of the data nft to update attributes
+ * @param nonce The nonce of the token to update attributes
+ * @param attributes The new attributes to update
+ * @param quantity The quantity of the token to update attributes (default: 1)
+ */
+ updateAttributes(
+ senderAddress: IAddress,
+ tokenIdentiifer: string,
+ nonce: number,
+ attributes: {
+ dataMarshalUrl: string;
+ dataStreamUrl: string;
+ dataPreviewUrl: string;
+ creator: IAddress;
+ title: string;
+ description: string;
+ },
+ quantity = 1
+ ): Transaction {
+ const updateAttributesTx = new Transaction({
+ value: 0,
+ data: new ContractCallPayloadBuilder()
+ .setFunction(new ContractFunction('ESDTNFTTransfer'))
+ .addArg(new TokenIdentifierValue(tokenIdentiifer))
+ .addArg(new U64Value(nonce))
+ .addArg(new U64Value(quantity))
+ .addArg(new AddressValue(this.contract.getAddress()))
+ .addArg(new StringValue('updateAttributes'))
+ .addArg(new StringValue(attributes.dataMarshalUrl))
+ .addArg(new StringValue(attributes.dataStreamUrl))
+ .addArg(new StringValue(attributes.dataPreviewUrl))
+ .addArg(new AddressValue(attributes.creator))
+ .addArg(new StringValue(attributes.title))
+ .addArg(new StringValue(attributes.description))
+ .build(),
+ receiver: senderAddress,
+ gasLimit: 12000000,
+ sender: senderAddress,
+ chainID: this.chainID
+ });
+ return updateAttributesTx;
+ }
+
+ /**
+ * Creates a setLocalRoles transaction for the contract
+ * @param senderAddress The address of the sender, must be the admin of the contract
+ */
+ setLocalRoles(senderAddress: IAddress): Transaction {
+ const setLocalRolesTx = new Transaction({
+ value: 0,
+ data: new ContractCallPayloadBuilder()
+ .setFunction(new ContractFunction('setLocalRoles'))
+ .build(),
+ receiver: this.contract.getAddress(),
+ gasLimit: 10000000,
+ sender: senderAddress,
+ chainID: this.chainID
+ });
+ return setLocalRolesTx;
+ }
+
+ /**
+ * Creates a setTransferRoles transaction for the contract
+ * @param senderAddress The address of the sender, must be the admin of the contract
+ * @param address The address to set the transfer roles
+ */
+ setTransferRole(senderAddress: IAddress, address: IAddress): Transaction {
+ const setTransferRolesTx = new Transaction({
+ value: 0,
+ data: new ContractCallPayloadBuilder()
+ .setFunction(new ContractFunction('setTransferRole'))
+ .addArg(new AddressValue(address))
+ .build(),
+ receiver: this.contract.getAddress(),
+ gasLimit: 10000000,
+ sender: senderAddress,
+ chainID: this.chainID
+ });
+ return setTransferRolesTx;
+ }
+
+ /**
+ * Creates an unsetTransferRoles transaction for the contract
+ * @param senderAddress The address of the sender, must be the admin of the contract
+ * @param address The address to unset the transfer roles
+ */
+ unsetTransferRole(senderAddress: IAddress, address: IAddress): Transaction {
+ const unsetTransferRolesTx = new Transaction({
+ value: 0,
+ data: new ContractCallPayloadBuilder()
+ .setFunction(new ContractFunction('unsetTransferRole'))
+ .addArg(new AddressValue(address))
+ .build(),
+ receiver: this.contract.getAddress(),
+ gasLimit: 10000000,
+ sender: senderAddress,
+ chainID: this.chainID
+ });
+ return unsetTransferRolesTx;
+ }
+
+ /** Creates a pause transaction for the contract
+ * @param senderAddress The address of the sender, must be the admin of the contract
+ */
+ pauseContract(senderAddress: IAddress): Transaction {
+ const pauseContractTx = new Transaction({
+ value: 0,
+ data: new ContractCallPayloadBuilder()
+ .setFunction(new ContractFunction('setIsPaused'))
+ .addArg(new BooleanValue(true))
+ .build(),
+ receiver: this.contract.getAddress(),
+ gasLimit: 10000000,
+ sender: senderAddress,
+ chainID: this.chainID
+ });
+
+ return pauseContractTx;
+ }
+
+ /** Creates a unpause transaction for the contract
+ * @param senderAddress The address of the sender, must be the admin of the contract
+ */
+ unpauseContract(senderAddress: IAddress): Transaction {
+ const unpauseContractTx = new Transaction({
+ value: 0,
+ data: new ContractCallPayloadBuilder()
+ .setFunction(new ContractFunction('setIsPaused'))
+ .addArg(new BooleanValue(false))
+ .build(),
+ receiver: this.contract.getAddress(),
+ gasLimit: 10000000,
+ sender: senderAddress,
+ chainID: this.chainID
+ });
+
+ return unpauseContractTx;
+ }
+
+ /** Creates a set mint tax transaction for the contract
+ * @param senderAddress The address of the sender, must be the admin of the contract
+ * @param is_required A boolean value to set if the mint tax is required or not
+ */
+ setMintTaxIsRequired(
+ senderAddress: IAddress,
+ is_required: boolean
+ ): Transaction {
+ const setMintTaxIsRequiredTx = new Transaction({
+ value: 0,
+ data: new ContractCallPayloadBuilder()
+ .setFunction(new ContractFunction('setTaxIsRequired'))
+ .addArg(new BooleanValue(is_required))
+ .build(),
+ receiver: this.contract.getAddress(),
+ gasLimit: 10000000,
+ sender: senderAddress,
+ chainID: this.chainID
+ });
+
+ return setMintTaxIsRequiredTx;
+ }
+
+ /** Creates a set mint tax transaction for the contract
+ * @param senderAddress The address of the sender, must be the admin of the contract
+ * @param tokenIdentifier The token identifier of the token to set the mint tax
+ * @param tax The tax to set for the token
+ */
+ setMintTax(
+ senderAddress: IAddress,
+ tokenIdentifier: string,
+ tax: number
+ ): Transaction {
+ const setMintTaxTx = new Transaction({
+ value: 0,
+ data: new ContractCallPayloadBuilder()
+ .setFunction(new ContractFunction('setAntiSpamTax'))
+ .addArg(new TokenIdentifierValue(tokenIdentifier))
+ .addArg(new BigUIntValue(tax))
+ .build(),
+ receiver: this.contract.getAddress(),
+ gasLimit: 10000000,
+ sender: senderAddress,
+ chainID: this.chainID
+ });
+ return setMintTaxTx;
+ }
+
+ /** Creates a set mint tax transaction for the contract
+ * @param senderAddress The address of the sender, must be the admin of the contract
+ * @param is_enabled A boolean value to set if whitelist is enabled or not
+ */
+ setWhitelistIsEnabled(
+ senderAddress: IAddress,
+ is_enabled: boolean
+ ): Transaction {
+ const setWhitelistIsEnabledTx = new Transaction({
+ value: 0,
+ data: new ContractCallPayloadBuilder()
+ .setFunction(new ContractFunction('setWhiteListEnabled'))
+ .addArg(new BooleanValue(is_enabled))
+ .build(),
+ receiver: this.contract.getAddress(),
+ gasLimit: 10000000,
+ sender: senderAddress,
+ chainID: this.chainID
+ });
+ return setWhitelistIsEnabledTx;
+ }
+
+ /** Creates a whitelist transaction for the contract
+ * @param senderAddress The address of the sender, must be the admin of the contract
+ * @param addresses The addresses to whitelist
+ */
+
+ whitelist(
+ senderAddress: IAddress,
+ addresses: string[],
+ gasLimit = 0
+ ): Transaction {
+ const whitelistTx = new Transaction({
+ value: 0,
+ data: new ContractCallPayloadBuilder()
+ .setFunction(new ContractFunction('setWhiteListSpots'))
+ .setArgs(
+ addresses.map((address) => new AddressValue(new Address(address)))
+ )
+ .build(),
+ receiver: this.contract.getAddress(),
+ gasLimit: 10000000 + gasLimit,
+ sender: senderAddress,
+ chainID: this.chainID
+ });
+ return whitelistTx;
+ }
+
+ /** Creates a delist transaction for the contract
+ * @param senderAddress The address of the sender, must be the admin of the contract
+ * @param addresses The addresses to delist
+ */
+ delist(
+ senderAddress: IAddress,
+ addresses: string[],
+ gasLimit: 0
+ ): Transaction {
+ const delistTx = new Transaction({
+ value: 0,
+ data: new ContractCallPayloadBuilder()
+ .setFunction(new ContractFunction('delist'))
+ .setArgs(
+ addresses.map((address) => new AddressValue(new Address(address)))
+ )
+ .build(),
+ receiver: this.contract.getAddress(),
+ gasLimit: 10000000 + gasLimit,
+ sender: senderAddress,
+ chainID: this.chainID
+ });
+ return delistTx;
+ }
+
+ /** Creates a set mint time limit transaction for the contract
+ * @param senderAddress The address of the sender, must be the admin of the contract
+ * @param timeLimit(seconds) The time limit to set between mints
+ */
+ setMintTimeLimit(senderAddress: IAddress, timeLimit: number): Transaction {
+ const setMintTimeLimitTx = new Transaction({
+ value: 0,
+ data: new ContractCallPayloadBuilder()
+ .setFunction(new ContractFunction('setMintTimeLimit'))
+ .addArg(new BigUIntValue(timeLimit))
+ .build(),
+ receiver: this.contract.getAddress(),
+ gasLimit: 10000000,
+ sender: senderAddress,
+ chainID: this.chainID
+ });
+ return setMintTimeLimitTx;
+ }
+
+ /** Sets a new administrator for the contract
+ * @param senderAddress The address of the sender, must be the admin of the contract
+ * @param newAdministrator The address of the new administrator
+ */
+ setAdministrator(
+ senderAddress: IAddress,
+ newAdministrator: IAddress
+ ): Transaction {
+ const setAdministratorTx = new Transaction({
+ value: 0,
+ data: new ContractCallPayloadBuilder()
+ .setFunction(new ContractFunction('setAdministrator'))
+ .addArg(new AddressValue(newAdministrator))
+ .build(),
+ receiver: this.contract.getAddress(),
+ gasLimit: 10000000,
+ sender: senderAddress,
+ chainID: this.chainID
+ });
+ return setAdministratorTx;
+ }
+
+ /** Sets the claim address for the contract
+ * @param senderAddress The address of the sender, must be the admin of the contract
+ * @param claimsAddress The claims address
+ */
+ setClaimsAddress(
+ senderAddress: IAddress,
+ claimsAddress: IAddress
+ ): Transaction {
+ const setClaimsAddressTx = new Transaction({
+ value: 0,
+ data: new ContractCallPayloadBuilder()
+ .setFunction(new ContractFunction('setClaimsAddress'))
+ .addArg(new AddressValue(claimsAddress))
+ .build(),
+ receiver: this.contract.getAddress(),
+ gasLimit: 10000000,
+ sender: senderAddress,
+ chainID: this.chainID
+ });
+ return setClaimsAddressTx;
+ }
+
+ /** Creates a claim royalties transaction for the contract
+ * @param senderAddress The address of the sender, must be the admin of the contract
+ * @param tokenIdentifier The token identifier of the token to claim royalties
+ * @param nonce The nonce of the token to claim royalties (default: 0 for ESDT)
+ */
+ claimRoyalties(
+ senderAddress: IAddress,
+ tokenIdentifier: string,
+ nonce = 0
+ ): Transaction {
+ const claimRoyaltiesTx = new Transaction({
+ value: 0,
+ data: new ContractCallPayloadBuilder()
+ .setFunction(new ContractFunction('claimRoyalties'))
+ .addArg(new TokenIdentifierValue(tokenIdentifier))
+ .addArg(new BigUIntValue(nonce))
+ .build(),
+ receiver: this.contract.getAddress(),
+ gasLimit: 10000000,
+ sender: senderAddress,
+ chainID: this.chainID
+ });
+ return claimRoyaltiesTx;
+ }
+}
diff --git a/src/sft-minter.ts b/src/sft-minter.ts
new file mode 100644
index 0000000..28a049b
--- /dev/null
+++ b/src/sft-minter.ts
@@ -0,0 +1,69 @@
+import {
+ AddressValue,
+ IAddress,
+ ResultsParser,
+ TokenIdentifierValue
+} from '@multiversx/sdk-core/out';
+import { Minter } from './minter';
+import {
+ EnvironmentsEnum,
+ itheumTokenIdentifier,
+ minterContractAddress
+} from './config';
+import { MinterRequirements } from './interfaces';
+import dataNftMinterAbi from './abis/datanftmint.abi.json';
+
+export class SftMinter extends Minter {
+ constructor(env: string, timeout: number = 10000) {
+ super(
+ env,
+ minterContractAddress[env as EnvironmentsEnum],
+ dataNftMinterAbi,
+ timeout
+ );
+ }
+
+ /**
+ * Retrieves the minter smart contract requirements for the given user
+ * @param address the address of the user
+ * @param taxToken the tax token to be used for the minting (default = `ITHEUM` token identifier based on the {@link EnvironmentsEnum})
+ */
+ async viewMinterRequirements(
+ address: IAddress,
+ taxToken = itheumTokenIdentifier[this.env as EnvironmentsEnum]
+ ): Promise {
+ const interaction = this.contract.methodsExplicit.getUserDataOut([
+ new AddressValue(address),
+ new TokenIdentifierValue(taxToken)
+ ]);
+ const query = interaction.buildQuery();
+ const queryResponse = await this.networkProvider.queryContract(query);
+ const endpointDefinition = interaction.getEndpoint();
+ const { firstValue, returnCode } = new ResultsParser().parseQueryResponse(
+ queryResponse,
+ endpointDefinition
+ );
+ if (returnCode.isSuccess()) {
+ const returnValue = firstValue?.valueOf();
+ const requirements: MinterRequirements = {
+ antiSpamTaxValue: returnValue.anti_spam_tax_value.toNumber(),
+ contractPaused: returnValue.is_paused,
+ maxRoyalties: returnValue.max_royalties.toNumber(),
+ minRoyalties: returnValue.min_royalties.toNumber(),
+ maxSupply: returnValue.max_supply.toNumber(),
+ mintTimeLimit: returnValue.mint_time_limit.toNumber(),
+ lastUserMintTime: returnValue.last_mint_time,
+ userWhitelistedForMint: returnValue.is_whitelisted,
+ contractWhitelistEnabled: returnValue.whitelist_enabled,
+ numberOfMintsForUser: returnValue.minted_per_user.toNumber(),
+ totalNumberOfMints: returnValue.total_minted.toNumber(),
+ addressFrozen: returnValue.frozen,
+ frozenNonces: returnValue.frozen_nonces.map((v: any) => v.toNumber())
+ };
+ return requirements;
+ } else {
+ throw new Error('Could not retrieve minter contract requirements');
+ // throw new ErrContractQuery('Could not retrieve requirements');
+ }
+ }
+}
diff --git a/src/utils.ts b/src/utils.ts
index 959034a..b85938d 100644
--- a/src/utils.ts
+++ b/src/utils.ts
@@ -111,6 +111,7 @@ export function validateSpecificParamsViewData(params: {
mvxNativeAuthMaxExpirySeconds?: number | undefined;
mvxNativeAuthOrigins?: string[] | undefined;
fwdHeaderMapLookup?: any;
+ nestedIdxToStream?: number | undefined;
_fwdHeaderMapLookupMustContainBearerAuthHeader?: boolean | undefined;
_mandatoryParamsList: string[]; // a pure JS fallback way to validate mandatory params, as typescript rules for mandatory can be bypassed by client app
}): {
@@ -310,6 +311,32 @@ export function validateSpecificParamsViewData(params: {
}
}
+ // nestedIdxToStream test
+ let nestedIdxToStreamValid = true;
+
+ if (
+ params.nestedIdxToStream !== undefined ||
+ params._mandatoryParamsList.includes('nestedIdxToStream')
+ ) {
+ nestedIdxToStreamValid = false;
+
+ const nestedIdxToStreamToInt =
+ params.nestedIdxToStream !== undefined
+ ? parseInt(params.nestedIdxToStream.toString(), 10)
+ : null;
+
+ if (
+ nestedIdxToStreamToInt !== null &&
+ !isNaN(nestedIdxToStreamToInt) &&
+ nestedIdxToStreamToInt >= 0
+ ) {
+ nestedIdxToStreamValid = true;
+ } else {
+ validationMessages +=
+ '[nestedIdxToStream needs to be a number more than 0]';
+ }
+ }
+
if (
!signedMessageValid ||
!signableMessageValid ||
@@ -318,7 +345,8 @@ export function validateSpecificParamsViewData(params: {
!fwdHeaderKeysIsValid ||
!fwdHeaderMapLookupIsValid ||
!mvxNativeAuthMaxExpirySecondsValid ||
- !mvxNativeAuthOriginsIsValid
+ !mvxNativeAuthOriginsIsValid ||
+ !nestedIdxToStreamValid
) {
allPassed = false;
}
@@ -452,7 +480,7 @@ export function validateSpecificParamsMint(params: {
typeof params.royalties === 'number' &&
!(params.royalties % 1 != 0) && // modulus checking. (10 % 1 != 0) EQ false, (10.5 % 1 != 0) EQ true,
params.royalties >= 0 &&
- params.royalties <= 50
+ params.royalties <= 5000
) {
royaltiesValid = true;
} else {
@@ -545,3 +573,11 @@ export function checkStatus(response: Response) {
throw new ErrFetch(response.status, response.statusText);
}
}
+
+export function checkStatus(response: Response) {
+ if (!(response.status >= 200 && response.status <= 299)) {
+ throw new Error(
+ `Response returned non-success HTTP code. status = ${response?.status} statusText = ${response?.statusText}`
+ );
+ }
+}