diff --git a/docs/api/version3.md b/docs/api/version3.md index 5613f48df6..708ccd11f7 100644 --- a/docs/api/version3.md +++ b/docs/api/version3.md @@ -59,6 +59,8 @@ The Lisk Service API is compatible with RESTful guidelines. The specification be - [Annual Inflation](#annual-inflation) - [Legacy](#legacy) - [Legacy Account Details](#legacy-account-details) + - [Non-fungible Token](#non-fungible-token) + - [Module Constants](#module-constants-3) - [Network](#network) - [Network peers](#network-peers) - [Network status](#network-status) @@ -2049,6 +2051,48 @@ Get legacy account details by publicKey https://service.lisk.com/api/v3/legacy?publicKey=b1d6bc6c7edd0673f5fed0681b73de6eb70539c21278b300f07ade277e1962cd ``` +## Non-fungible Token + +### Module Constants + +Retrieves module constants from the NFT module. + +#### Endpoints + +- HTTP GET `/api/v3/nft/constants` +- RPC `get.nft.constants` + +#### Request parameters + +No parameters are required. + +#### Response example + +200 OK + +```jsonc +{ + "data": { + "feeCreateNFT": "5000000", + }, + "meta": {} +} +``` + +400 Bad Request +```jsonc +{ + "error": true, + "message": "Unknown input parameter(s): " +} +``` + +#### Examples + +Get module constants from the NFT module +``` +https://service.lisk.com/api/v3/nft/constants +``` ## Network ### Network peers diff --git a/services/blockchain-connector/methods/nft.js b/services/blockchain-connector/methods/nft.js new file mode 100644 index 0000000000..23910359ad --- /dev/null +++ b/services/blockchain-connector/methods/nft.js @@ -0,0 +1,24 @@ +/* + * LiskHQ/lisk-service + * Copyright © 2023 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +const { getNFTConstants } = require('../shared/sdk'); + +module.exports = [ + { + name: 'getNFTConstants', + controller: async () => getNFTConstants(), + params: {}, + }, +]; diff --git a/services/blockchain-connector/shared/sdk/index.js b/services/blockchain-connector/shared/sdk/index.js index 824c472194..a187b1bfaa 100644 --- a/services/blockchain-connector/shared/sdk/index.js +++ b/services/blockchain-connector/shared/sdk/index.js @@ -117,6 +117,7 @@ const { const { cacheCleanup } = require('./cache'); const { formatTransaction } = require('./formatter'); const { encodeCCM } = require('./encoder'); +const { getNFTConstants } = require('./nft'); const init = async () => { // Initialize the local cache @@ -242,4 +243,7 @@ module.exports = { // Cache cacheCleanup, + + // NFT + getNFTConstants, }; diff --git a/services/blockchain-connector/shared/sdk/nft.js b/services/blockchain-connector/shared/sdk/nft.js new file mode 100644 index 0000000000..784ad57ce9 --- /dev/null +++ b/services/blockchain-connector/shared/sdk/nft.js @@ -0,0 +1,42 @@ +/* +* LiskHQ/lisk-service +* Copyright © 2023 Lisk Foundation +* +* See the LICENSE file at the top-level directory of this distribution +* for licensing information. +* +* Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, +* no part of this software, including this file, may be copied, modified, +* propagated, or distributed except according to the terms contained in the +* LICENSE file. +* +* Removal or modification of this copyright notice is prohibited. +* +*/ +const { Exceptions: { TimeoutException }, Logger } = require('lisk-service-framework'); +const { timeoutMessage } = require('./client'); + +const logger = Logger(); + +let moduleConstants; + +const getNFTConstants = async () => { + try { + if (!moduleConstants) { + // TODO: Fetch feeCreateNFT directly from node when implemented + // moduleConstants = await invokeEndpoint('nft_getConstants'); + moduleConstants = { feeCreateNFT: 5000000 }; + } + return moduleConstants; + } catch (err) { + if (err.message.includes(timeoutMessage)) { + throw new TimeoutException('Request timed out when calling \'getConstants\'.'); + } + logger.warn(`Error returned when invoking 'nft_getConstants'.\n${err.stack}`); + throw err; + } +}; + +module.exports = { + getNFTConstants, +}; diff --git a/services/blockchain-indexer/methods/dataService/controllers/nft.js b/services/blockchain-indexer/methods/dataService/controllers/nft.js new file mode 100644 index 0000000000..9ffa39080f --- /dev/null +++ b/services/blockchain-indexer/methods/dataService/controllers/nft.js @@ -0,0 +1,33 @@ +/* + * LiskHQ/lisk-service + * Copyright © 2023 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +const dataService = require('../../../shared/dataService'); + +const getNFTConstants = async () => { + const constants = { + data: {}, + meta: {}, + }; + + const response = await dataService.getNFTConstants(); + if (response.data) constants.data = response.data; + if (response.meta) constants.meta = response.meta; + + return constants; +}; + +module.exports = { + getNFTConstants, +}; diff --git a/services/blockchain-indexer/methods/dataService/modules/nft.js b/services/blockchain-indexer/methods/dataService/modules/nft.js new file mode 100644 index 0000000000..c1aa6f38a6 --- /dev/null +++ b/services/blockchain-indexer/methods/dataService/modules/nft.js @@ -0,0 +1,24 @@ +/* + * LiskHQ/lisk-service + * Copyright © 2023 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +const { getNFTConstants } = require('../controllers/nft'); + +module.exports = [ + { + name: 'nft.constants', + controller: getNFTConstants, + params: {}, + }, +]; diff --git a/services/blockchain-indexer/shared/dataService/business/nft/constants.js b/services/blockchain-indexer/shared/dataService/business/nft/constants.js new file mode 100644 index 0000000000..d2a71d2178 --- /dev/null +++ b/services/blockchain-indexer/shared/dataService/business/nft/constants.js @@ -0,0 +1,41 @@ +/* + * LiskHQ/lisk-service + * Copyright © 2023 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +const { Logger } = require('lisk-service-framework'); +const { requestConnector } = require('../../../utils/request'); + +const logger = Logger(); + +let moduleConstants; + +const getNFTConstants = async () => { + try { + if (typeof moduleConstants === 'undefined') moduleConstants = await requestConnector('getNFTConstants'); + + return { + data: moduleConstants, + meta: {}, + }; + } catch (err) { + const errMessage = `Unable to fetch the NFT constants from connector due to: ${err.message}.`; + logger.warn(errMessage); + logger.trace(err.stack); + throw new Error(errMessage); + } +}; + +module.exports = { + getNFTConstants, +}; diff --git a/services/blockchain-indexer/shared/dataService/business/nft/index.js b/services/blockchain-indexer/shared/dataService/business/nft/index.js new file mode 100644 index 0000000000..b474dd8e77 --- /dev/null +++ b/services/blockchain-indexer/shared/dataService/business/nft/index.js @@ -0,0 +1,20 @@ +/* + * LiskHQ/lisk-service + * Copyright © 2023 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +const { getNFTConstants } = require('./constants'); + +module.exports = { + getNFTConstants, +}; diff --git a/services/blockchain-indexer/shared/dataService/index.js b/services/blockchain-indexer/shared/dataService/index.js index 7764693ecd..41d098d135 100644 --- a/services/blockchain-indexer/shared/dataService/index.js +++ b/services/blockchain-indexer/shared/dataService/index.js @@ -103,6 +103,10 @@ const { getValidator, validateBLSKey } = require('./validator'); const { getGenerators } = require('./generators'); const { invokeEndpoint } = require('./invoke'); +const { + getNFTConstants, +} = require('./nft'); + module.exports = { // Blocks getBlocks, @@ -201,4 +205,7 @@ module.exports = { resolveMainchainServiceURL, invokeEndpoint, + + // NFT + getNFTConstants, }; diff --git a/services/blockchain-indexer/shared/dataService/nft/constants.js b/services/blockchain-indexer/shared/dataService/nft/constants.js new file mode 100644 index 0000000000..77719f891c --- /dev/null +++ b/services/blockchain-indexer/shared/dataService/nft/constants.js @@ -0,0 +1,22 @@ +/* + * LiskHQ/lisk-service + * Copyright © 2023 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +const business = require('../business'); + +const getNFTConstants = async () => business.getNFTConstants(); + +module.exports = { + getNFTConstants, +}; diff --git a/services/blockchain-indexer/shared/dataService/nft/index.js b/services/blockchain-indexer/shared/dataService/nft/index.js new file mode 100644 index 0000000000..b474dd8e77 --- /dev/null +++ b/services/blockchain-indexer/shared/dataService/nft/index.js @@ -0,0 +1,20 @@ +/* + * LiskHQ/lisk-service + * Copyright © 2023 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +const { getNFTConstants } = require('./constants'); + +module.exports = { + getNFTConstants, +}; diff --git a/services/gateway/apis/http-version3/methods/modules/nft/constants.js b/services/gateway/apis/http-version3/methods/modules/nft/constants.js new file mode 100644 index 0000000000..b999a6a9dd --- /dev/null +++ b/services/gateway/apis/http-version3/methods/modules/nft/constants.js @@ -0,0 +1,48 @@ +/* + * LiskHQ/lisk-service + * Copyright © 2023 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ + +const nftConstantsSource = require('../../../../../sources/version3/nftConstants'); +const envelope = require('../../../../../sources/version3/mappings/stdEnvelope'); +const { response, getSwaggerDescription } = require('../../../../../shared/utils'); + +module.exports = { + version: '2.0', + swaggerApiPath: '/nft/constants', + rpcMethod: 'get.nft.constants', + tags: ['NFT'], + get schema() { + const constantsSchema = {}; + constantsSchema[this.swaggerApiPath] = { get: {} }; + constantsSchema[this.swaggerApiPath].get.tags = this.tags; + constantsSchema[this.swaggerApiPath].get.summary = 'Requests NFT module constants.'; + constantsSchema[this.swaggerApiPath].get.description = getSwaggerDescription({ + rpcMethod: this.rpcMethod, + description: 'Requests all the configured constants for the NFT module.', + }); + constantsSchema[this.swaggerApiPath].get.responses = { + 200: { + description: 'Returns all the configured constants for the NFT module.', + schema: { + $ref: '#/definitions/nftConstantsWithEnvelope', + }, + }, + }; + Object.assign(constantsSchema[this.swaggerApiPath].get.responses, response); + return constantsSchema; + }, + source: nftConstantsSource, + envelope, +}; diff --git a/services/gateway/apis/http-version3/swagger/definitions/nft.json b/services/gateway/apis/http-version3/swagger/definitions/nft.json new file mode 100644 index 0000000000..b25b58e343 --- /dev/null +++ b/services/gateway/apis/http-version3/swagger/definitions/nft.json @@ -0,0 +1,28 @@ +{ + "nftConstantsWithEnvelope": { + "type": "object", + "required": [ + "data", + "meta" + ], + "properties": { + "data": { + "description": "NFT module constants.", + "type": "object", + "required": [ + "feeCreateNFT" + ], + "properties": { + "feeCreateNFT": { + "type": "string", + "example": "5000000", + "description": "The extra fee to be supplied for creating NFT." + } + } + }, + "meta": { + "type": "object" + } + } + } +} diff --git a/services/gateway/sources/version3/nftConstants.js b/services/gateway/sources/version3/nftConstants.js new file mode 100644 index 0000000000..ede02f71af --- /dev/null +++ b/services/gateway/sources/version3/nftConstants.js @@ -0,0 +1,26 @@ +/* + * LiskHQ/lisk-service + * Copyright © 2023 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +module.exports = { + type: 'moleculer', + method: 'indexer.nft.constants', + params: {}, + definition: { + data: { + feeCreateNFT: '=,string', + }, + meta: {}, + }, +}; diff --git a/tests/integration/api_v3/http/nftConstants.test.js b/tests/integration/api_v3/http/nftConstants.test.js new file mode 100644 index 0000000000..c8470b6308 --- /dev/null +++ b/tests/integration/api_v3/http/nftConstants.test.js @@ -0,0 +1,39 @@ +/* + * LiskHQ/lisk-service + * Copyright © 2023 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +const config = require('../../../config'); +const { api } = require('../../../helpers/api'); + +const { + badRequestSchema, +} = require('../../../schemas/httpGenerics.schema'); + +const { nftConstantsSchema } = require('../../../schemas/api_v3/nftConstants.schema'); + +const baseUrl = config.SERVICE_ENDPOINT; +const baseUrlV3 = `${baseUrl}/api/v3`; +const endpoint = `${baseUrlV3}/nft/constants`; + +describe('NFT Constants API', () => { + it('returns NFT module constants', async () => { + const response = await api.get(endpoint); + expect(response).toMap(nftConstantsSchema); + }); + + it('params not supported -> 400 BAD_REQUEST', async () => { + const response = await api.get(`${endpoint}?someparam='not_supported'`, 400); + expect(response).toMap(badRequestSchema); + }); +}); diff --git a/tests/integration/api_v3/rpc/nftConstants.test.js b/tests/integration/api_v3/rpc/nftConstants.test.js new file mode 100644 index 0000000000..f649d82144 --- /dev/null +++ b/tests/integration/api_v3/rpc/nftConstants.test.js @@ -0,0 +1,47 @@ +/* + * LiskHQ/lisk-service + * Copyright © 2023 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +const config = require('../../../config'); +const { request } = require('../../../helpers/socketIoRpcRequest'); + +const { + jsonRpcEnvelopeSchema, + invalidParamsSchema, +} = require('../../../schemas/rpcGenerics.schema'); + +const { nftConstantsSchema } = require('../../../schemas/api_v3/nftConstants.schema'); + +const wsRpcUrl = `${config.SERVICE_ENDPOINT}/rpc-v3`; + +const getNFTConstants = async (params) => request(wsRpcUrl, 'get.nft.constants', params); + +describe('get.nft.constants', () => { + it('returns NFT module constants', async () => { + const response = await getNFTConstants(); + expect(response).toMap(jsonRpcEnvelopeSchema); + + const { result } = response; + expect(result).toMap(nftConstantsSchema); + }); + + it('params not supported -> INVALID_PARAMS (-32602)', async () => { + const response = await request( + wsRpcUrl, + 'get.nft.constants', + { someparam: 'not_supported' }, + ).catch(e => e); + expect(response).toMap(invalidParamsSchema); + }); +}); diff --git a/tests/schemas/api_v3/nftConstants.schema.js b/tests/schemas/api_v3/nftConstants.schema.js new file mode 100644 index 0000000000..17877ac03a --- /dev/null +++ b/tests/schemas/api_v3/nftConstants.schema.js @@ -0,0 +1,33 @@ +/* + * LiskHQ/lisk-service + * Copyright © 2023 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import Joi from 'joi'; + +const regex = require('./regex'); + +const nftConstantsDataSchema = { + feeCreateNFT: Joi.string().pattern(regex.DIGITS).required(), +}; + +const nftConstantsMetaSchema = {}; + +const nftConstantsSchema = { + data: Joi.object(nftConstantsDataSchema).required(), + meta: Joi.object(nftConstantsMetaSchema).required(), +}; + +module.exports = { + nftConstantsSchema: Joi.object(nftConstantsSchema).required(), +};