From e5cd1b997f597696b1724ed20ec7d8fc7d2faa32 Mon Sep 17 00:00:00 2001 From: reyraa Date: Wed, 18 Oct 2023 12:02:23 +0200 Subject: [PATCH 01/10] Change Audio into Anchor --- .../shared/sdk/constants/eventTopics.js | 16 +-- .../shared/sdk/constants/names.js | 16 +-- .../controllers/{audios.js => anchors.js} | 14 +- .../methods/dataService/modules/anchor.js | 16 +++ .../methods/dataService/modules/audio.js | 16 --- .../shared/dataService/anchors.js | 22 +++ .../shared/dataService/audios.js | 22 --- .../shared/dataService/business/anchors.js | 99 ++++++++++++++ .../shared/dataService/business/audios.js | 127 ------------------ .../shared/dataService/business/index.js | 6 +- .../shared/dataService/index.js | 6 +- .../shared/database/schema/anchors.js | 16 +++ .../shared/database/schema/audios.js | 20 --- .../shared/database/schema/feats.js | 13 -- .../shared/database/schema/images.js | 14 ++ .../shared/database/schema/owners.js | 14 -- .../transactionProcessor/audio/create.js | 120 +++++++---------- .../transactionProcessor/audio/destroy.js | 50 +++---- .../transactionProcessor/audio/index.js | 2 +- .../transactionProcessor/audio/reclaim.js | 76 ----------- .../audio/setAttributes.js | 119 ---------------- .../transactionProcessor/audio/transfer.js | 84 ------------ .../audio/{stream.js => vote.js} | 44 +++--- .../apis/http-version3/methods/anchors.js | 41 ++++++ .../apis/http-version3/methods/audios.js | 43 ------ .../apis/http-version3/swagger/apiJson.json | 4 +- .../definitions/{audios.json => anchors.json} | 20 +-- .../parameters/{audios.json => anchors.json} | 10 +- services/gateway/sources/version3/anchors.js | 31 +++++ services/gateway/sources/version3/audios.js | 42 ------ .../gateway/sources/version3/collections.js | 4 +- .../sources/version3/mappings/anchor.js | 12 ++ .../sources/version3/mappings/audio.js | 21 --- .../gateway/tests/constants/generateDocs.js | 22 ++- .../gateway/tests/constants/registerApi.js | 8 +- 35 files changed, 397 insertions(+), 793 deletions(-) rename services/blockchain-indexer/methods/dataService/controllers/{audios.js => anchors.js} (67%) create mode 100644 services/blockchain-indexer/methods/dataService/modules/anchor.js delete mode 100644 services/blockchain-indexer/methods/dataService/modules/audio.js create mode 100644 services/blockchain-indexer/shared/dataService/anchors.js delete mode 100644 services/blockchain-indexer/shared/dataService/audios.js create mode 100644 services/blockchain-indexer/shared/dataService/business/anchors.js delete mode 100644 services/blockchain-indexer/shared/dataService/business/audios.js create mode 100644 services/blockchain-indexer/shared/database/schema/anchors.js delete mode 100644 services/blockchain-indexer/shared/database/schema/audios.js delete mode 100644 services/blockchain-indexer/shared/database/schema/feats.js create mode 100644 services/blockchain-indexer/shared/database/schema/images.js delete mode 100644 services/blockchain-indexer/shared/database/schema/owners.js delete mode 100644 services/blockchain-indexer/shared/indexer/transactionProcessor/audio/reclaim.js delete mode 100644 services/blockchain-indexer/shared/indexer/transactionProcessor/audio/setAttributes.js delete mode 100644 services/blockchain-indexer/shared/indexer/transactionProcessor/audio/transfer.js rename services/blockchain-indexer/shared/indexer/transactionProcessor/audio/{stream.js => vote.js} (52%) create mode 100644 services/gateway/apis/http-version3/methods/anchors.js delete mode 100644 services/gateway/apis/http-version3/methods/audios.js rename services/gateway/apis/http-version3/swagger/definitions/{audios.json => anchors.json} (87%) rename services/gateway/apis/http-version3/swagger/parameters/{audios.json => anchors.json} (64%) create mode 100644 services/gateway/sources/version3/anchors.js delete mode 100644 services/gateway/sources/version3/audios.js create mode 100644 services/gateway/sources/version3/mappings/anchor.js delete mode 100644 services/gateway/sources/version3/mappings/audio.js diff --git a/services/blockchain-connector/shared/sdk/constants/eventTopics.js b/services/blockchain-connector/shared/sdk/constants/eventTopics.js index 77281c9cf..b919c7ed1 100644 --- a/services/blockchain-connector/shared/sdk/constants/eventTopics.js +++ b/services/blockchain-connector/shared/sdk/constants/eventTopics.js @@ -84,10 +84,10 @@ const { EVENT_NAME_COLLECTION_CREATED, EVENT_NAME_COLLECTION_TRANSFERED, - MODULE_NAME_AUDIO, - EVENT_NAME_AUDIO_CREATED, - EVENT_NAME_AUDIO_STREAMED, - EVENT_NAME_AUDIO_INCOME_RECLAIMED, + MODULE_NAME_ANCHOR, + EVENT_NAME_ANCHOR_CREATED, + EVENT_NAME_ANCHOR_STREAMED, + EVENT_NAME_ANCHOR_INCOME_RECLAIMED, MODULE_NAME_PROFILE, EVENT_NAME_PROFILE_CREATED, @@ -170,10 +170,10 @@ const EVENT_TOPIC_MAPPINGS_BY_MODULE = { [EVENT_NAME_COLLECTION_CREATED]: ['transactionID', 'senderAddress'], [EVENT_NAME_COLLECTION_TRANSFERED]: ['transactionID', 'senderAddress'], }, - [MODULE_NAME_AUDIO]: { - [EVENT_NAME_AUDIO_CREATED]: ['transactionID', 'senderAddress'], - [EVENT_NAME_AUDIO_STREAMED]: ['transactionID', 'senderAddress'], - [EVENT_NAME_AUDIO_INCOME_RECLAIMED]: ['transactionID', 'senderAddress'], + [MODULE_NAME_ANCHOR]: { + [EVENT_NAME_ANCHOR_CREATED]: ['transactionID', 'senderAddress'], + [EVENT_NAME_ANCHOR_STREAMED]: ['transactionID', 'senderAddress'], + [EVENT_NAME_ANCHOR_INCOME_RECLAIMED]: ['transactionID', 'senderAddress'], }, [MODULE_NAME_PROFILE]: { [EVENT_NAME_PROFILE_CREATED]: ['transactionID', 'senderAddress'], diff --git a/services/blockchain-connector/shared/sdk/constants/names.js b/services/blockchain-connector/shared/sdk/constants/names.js index 7c6da5e05..00014971f 100644 --- a/services/blockchain-connector/shared/sdk/constants/names.js +++ b/services/blockchain-connector/shared/sdk/constants/names.js @@ -97,11 +97,10 @@ const MODULE_NAME_COLLECTION = 'collection'; const EVENT_NAME_COLLECTION_CREATED = 'collectionCreated'; const EVENT_NAME_COLLECTION_TRANSFERED = 'collectionTransfered'; -// Audios -const MODULE_NAME_AUDIO = 'audio'; -const EVENT_NAME_AUDIO_CREATED = 'audioCreated'; -const EVENT_NAME_AUDIO_STREAMED = 'audioStreamed'; -const EVENT_NAME_AUDIO_INCOME_RECLAIMED = 'audioIncomeReclaimed'; +// Anchors +const MODULE_NAME_ANCHOR = 'anchor'; +const EVENT_NAME_ANCHOR_CREATED = 'anchorCreated'; +const EVENT_NAME_ANCHOR_VOTED = 'anchorVoted'; // Profiles const MODULE_NAME_PROFILE = 'profile'; @@ -179,10 +178,9 @@ module.exports = { EVENT_NAME_COLLECTION_CREATED, EVENT_NAME_COLLECTION_TRANSFERED, - MODULE_NAME_AUDIO, - EVENT_NAME_AUDIO_CREATED, - EVENT_NAME_AUDIO_STREAMED, - EVENT_NAME_AUDIO_INCOME_RECLAIMED, + MODULE_NAME_ANCHOR, + EVENT_NAME_ANCHOR_CREATED, + EVENT_NAME_ANCHOR_VOTED, MODULE_NAME_PROFILE, EVENT_NAME_PROFILE_CREATED, diff --git a/services/blockchain-indexer/methods/dataService/controllers/audios.js b/services/blockchain-indexer/methods/dataService/controllers/anchors.js similarity index 67% rename from services/blockchain-indexer/methods/dataService/controllers/audios.js rename to services/blockchain-indexer/methods/dataService/controllers/anchors.js index fa9ce364b..3aa077053 100644 --- a/services/blockchain-indexer/methods/dataService/controllers/audios.js +++ b/services/blockchain-indexer/methods/dataService/controllers/anchors.js @@ -5,18 +5,18 @@ const { const dataService = require('../../../shared/dataService'); -const getAudios = async params => { - const audios = { +const getAnchors = async params => { + const anchors = { data: [], meta: {}, }; try { - const response = await dataService.getAudios(params); - if (response.data) audios.data = response.data; - if (response.meta) audios.meta = response.meta; + const response = await dataService.getAnchors(params); + if (response.data) anchors.data = response.data; + if (response.meta) anchors.meta = response.meta; - return audios; + return anchors; } catch (err) { let status; if (err instanceof InvalidParamsException) status = 'INVALID_PARAMS'; @@ -27,5 +27,5 @@ const getAudios = async params => { }; module.exports = { - getAudios, + getAnchors, }; diff --git a/services/blockchain-indexer/methods/dataService/modules/anchor.js b/services/blockchain-indexer/methods/dataService/modules/anchor.js new file mode 100644 index 000000000..b2cafccf3 --- /dev/null +++ b/services/blockchain-indexer/methods/dataService/modules/anchor.js @@ -0,0 +1,16 @@ +const { + getAnchors, +} = require('../controllers/anchors'); + +module.exports = [ + { + name: 'anchors', + controller: getAnchors, + params: { + submitter: { optional: true, type: 'string' }, + anchorID: { optional: true, type: 'string' }, + limit: { optional: true, type: 'number' }, + offset: { optional: true, type: 'number' }, + }, + }, +]; diff --git a/services/blockchain-indexer/methods/dataService/modules/audio.js b/services/blockchain-indexer/methods/dataService/modules/audio.js deleted file mode 100644 index e95dfb599..000000000 --- a/services/blockchain-indexer/methods/dataService/modules/audio.js +++ /dev/null @@ -1,16 +0,0 @@ -const { - getAudios, -} = require('../controllers/audios'); - -module.exports = [ - { - name: 'audios', - controller: getAudios, - params: { - creatorAddress: { optional: true, type: 'string' }, - audioID: { optional: true, type: 'string' }, - limit: { optional: true, type: 'number' }, - offset: { optional: true, type: 'number' }, - }, - }, -]; diff --git a/services/blockchain-indexer/shared/dataService/anchors.js b/services/blockchain-indexer/shared/dataService/anchors.js new file mode 100644 index 000000000..1ef401153 --- /dev/null +++ b/services/blockchain-indexer/shared/dataService/anchors.js @@ -0,0 +1,22 @@ +const { Logger } = require('lisk-service-framework'); +const util = require('util'); + +const logger = Logger(); + +const business = require('./business'); + +const getAnchors = async params => { + // Store logs + if (params.anchorID) logger.debug(`Retrieved anchor with ID ${params.anchorID} from Lisk Core`); + else if (params.submitter) logger.debug(`Retrieved anchor with submitter: ${params.submitter} from Lisk Core`); + else logger.debug(`Retrieved anchors with custom search: ${util.inspect(params)} from Lisk Core`); + + // Get data from server + const response = await business.getAnchors(params); + + return response; +}; + +module.exports = { + getAnchors, +}; diff --git a/services/blockchain-indexer/shared/dataService/audios.js b/services/blockchain-indexer/shared/dataService/audios.js deleted file mode 100644 index 22b4bb6d8..000000000 --- a/services/blockchain-indexer/shared/dataService/audios.js +++ /dev/null @@ -1,22 +0,0 @@ -const { Logger } = require('lisk-service-framework'); -const util = require('util'); - -const logger = Logger(); - -const business = require('./business'); - -const getAudios = async params => { - // Store logs - if (params.audioID) logger.debug(`Retrieved audio with ID ${params.audioID} from Lisk Core`); - else if (params.creatorAddress) logger.debug(`Retrieved audio with creatorAddress: ${params.creatorAddress} from Lisk Core`); - else logger.debug(`Retrieved audios with custom search: ${util.inspect(params)} from Lisk Core`); - - // Get data from server - const response = await business.getAudios(params); - - return response; -}; - -module.exports = { - getAudios, -}; diff --git a/services/blockchain-indexer/shared/dataService/business/anchors.js b/services/blockchain-indexer/shared/dataService/business/anchors.js new file mode 100644 index 000000000..579f66f2c --- /dev/null +++ b/services/blockchain-indexer/shared/dataService/business/anchors.js @@ -0,0 +1,99 @@ +const { + MySQL: { getTableInstance }, +} = require('lisk-service-framework'); +const BluebirdPromise = require('bluebird'); + +const transactionsIndexSchema = require('../../database/schema/anchors'); +const imagesIndexSchema = require('../../database/schema/images'); +const config = require('../../../config'); + +const MYSQL_ENDPOINT = config.endpoints.mysql; + +const getAnchorsIndex = () => getTableInstance( + transactionsIndexSchema.tableName, + transactionsIndexSchema, + MYSQL_ENDPOINT, +); + +const getImagesIndex = () => getTableInstance( + imagesIndexSchema.tableName, + imagesIndexSchema, + MYSQL_ENDPOINT, +); + +const getAnchors = async (params = {}) => { + const anchorsTable = await getAnchorsIndex(); + const imagesTable = await getImagesIndex(); + + if (params.search) { + const { search, ...remParams } = params; + params = remParams; + + params.search = { + property: 'name', + pattern: search, + }; + } + + let anchorData = []; + + if (params.submitter) { + // anchorsID + const anchorIDs = await imagesTable.find( + { address: params.submitter, limit: params.limit }, + ['anchorID', 'shares'], + ); + + const filteredAnchorIDs = anchorIDs.filter(anchor => anchor.shares > 0); + + anchorData = await BluebirdPromise.map( + filteredAnchorIDs, + async (anchorID) => { + const anchor = await anchorsTable.find( + { anchorID: anchorID.anchorID }, + ['anchorID', 'submitter', 'name', 'album', 'artists', 'spotifyId', 'appleMusicId'], + ); + + return anchor[0]; + }, + { concurrency: filteredAnchorIDs.length }, + ); + } else { + anchorData = await anchorsTable.find( + { ...params, limit: params.limit }, + ['anchorID', 'submitter', 'name', 'album', 'artists', 'spotifyId', 'appleMusicId'], + ); + } + + const total = anchorData.length; + + const data = await BluebirdPromise.map( + anchorData, + async (anchor) => { + const imagesData = await imagesTable.find( + { anchorID: anchor.anchorID }, + ['address', 'shares', 'income'], + ); + + return { + ...anchor, + images: imagesData, + }; + }, + { concurrency: anchorData.length }, + ); + + const result = { + data, + meta: { + count: data.length, + offset: parseInt(params.offset, 10) || 0, + total, + }, + }; + return result; +}; + +module.exports = { + getAnchors, +}; diff --git a/services/blockchain-indexer/shared/dataService/business/audios.js b/services/blockchain-indexer/shared/dataService/business/audios.js deleted file mode 100644 index 5af7d3244..000000000 --- a/services/blockchain-indexer/shared/dataService/business/audios.js +++ /dev/null @@ -1,127 +0,0 @@ -const { - MySQL: { getTableInstance }, -} = require('lisk-service-framework'); -const BluebirdPromise = require('bluebird'); - -const transactionsIndexSchema = require('../../database/schema/audios'); -const collectionsIndexSchema = require('../../database/schema/collections'); -const ownersIndexSchema = require('../../database/schema/owners'); -const featsIndexSchema = require('../../database/schema/feats'); -const config = require('../../../config'); - -const MYSQL_ENDPOINT = config.endpoints.mysql; - -const getAudiosIndex = () => getTableInstance( - transactionsIndexSchema.tableName, - transactionsIndexSchema, - MYSQL_ENDPOINT, -); - -const getCollectionsIndex = () => getTableInstance( - collectionsIndexSchema.tableName, - collectionsIndexSchema, - MYSQL_ENDPOINT, -); - -const getOwnersIndex = () => getTableInstance( - ownersIndexSchema.tableName, - ownersIndexSchema, - MYSQL_ENDPOINT, -); - -const getFeatsIndex = () => getTableInstance( - featsIndexSchema.tableName, - featsIndexSchema, - MYSQL_ENDPOINT, -); - -const getAudios = async (params = {}) => { - const audiosTable = await getAudiosIndex(); - const collectionsTable = await getCollectionsIndex(); - const ownersTable = await getOwnersIndex(); - const featsTable = await getFeatsIndex(); - - if (params.search) { - const { search, ...remParams } = params; - params = remParams; - - params.search = { - property: 'name', - pattern: search, - }; - } - - let audioData = []; - - if (params.ownerAddress) { - // audiosID - const audioIDs = await ownersTable.find( - { address: params.ownerAddress, limit: params.limit }, - ['audioID', 'shares'], - ); - - const filteredAudioIDs = audioIDs.filter(audio => audio.shares > 0); - - audioData = await BluebirdPromise.map( - filteredAudioIDs, - async (audioID) => { - const audio = await audiosTable.find( - { audioID: audioID.audioID }, - ['audioID', 'creatorAddress', 'name', 'releaseYear', 'collectionID'], - ); - - return audio[0]; - }, - { concurrency: filteredAudioIDs.length }, - ); - } else { - audioData = await audiosTable.find( - { ...params, limit: params.limit }, - ['audioID', 'creatorAddress', 'name', 'releaseYear', 'collectionID'], - ); - } - - const total = audioData.length; - - const data = await BluebirdPromise.map( - audioData, - async (audio) => { - const collectionData = await collectionsTable.find( - { collectionID: audio.collectionID }, - ['name', 'collectionType', 'releaseYear'], - ); - - const ownersData = await ownersTable.find( - { audioID: audio.audioID }, - ['address', 'shares', 'income'], - ); - - const featData = await featsTable.find( - { audioID: audio.audioID }, - ['address', 'role'], - ); - - return { - ...audio, - collection: collectionData.length ? collectionData[0] : {}, - owners: ownersData, - feat: featData, - }; - }, - { concurrency: audioData.length }, - ); - - const result = { - data, - meta: { - count: data.length, - offset: parseInt(params.offset, 10) || 0, - total, - }, - }; - return result; -}; - -module.exports = { - getAudios, -}; diff --git a/services/blockchain-indexer/shared/dataService/business/index.js b/services/blockchain-indexer/shared/dataService/business/index.js index 58e67ed46..7a0ed7361 100644 --- a/services/blockchain-indexer/shared/dataService/business/index.js +++ b/services/blockchain-indexer/shared/dataService/business/index.js @@ -110,7 +110,7 @@ const { setFeeEstimates, getFeeEstimates, initFeeEstimates } = require('./feeEst // Muzikie Dedicated Modules const { getSubscriptions } = require('./subscriptions'); const { getCollections } = require('./collections'); -const { getAudios } = require('./audios'); +const { getAnchors } = require('./anchors'); const { getProfiles } = require('./profiles'); module.exports = { @@ -214,8 +214,8 @@ module.exports = { // collections getCollections, - // audios - getAudios, + // anchors + getAnchors, // profiles getProfiles, diff --git a/services/blockchain-indexer/shared/dataService/index.js b/services/blockchain-indexer/shared/dataService/index.js index 3e92f8bc4..2ee8d7aaa 100644 --- a/services/blockchain-indexer/shared/dataService/index.js +++ b/services/blockchain-indexer/shared/dataService/index.js @@ -106,7 +106,7 @@ const { getValidator, validateBLSKey } = require('./validator'); const { getGenerators } = require('./generators'); const { getSubscriptions } = require('./subscriptions'); const { getCollections } = require('./collections'); -const { getAudios } = require('./audios'); +const { getAnchors } = require('./anchors'); const { getProfiles } = require('./profiles'); const { invokeEndpoint } = require('./invoke'); @@ -215,8 +215,8 @@ module.exports = { // Collections getCollections, - // Audios - getAudios, + // Anchors + getAnchors, // Profiles getProfiles, diff --git a/services/blockchain-indexer/shared/database/schema/anchors.js b/services/blockchain-indexer/shared/database/schema/anchors.js new file mode 100644 index 000000000..364b9628e --- /dev/null +++ b/services/blockchain-indexer/shared/database/schema/anchors.js @@ -0,0 +1,16 @@ +module.exports = { + tableName: 'anchors', + primaryKey: 'anchorID', + schema: { + anchorID: { type: 'string' }, + name: { type: 'string' }, + album: { type: 'string' }, + artists: { type: 'string' }, + spotifyId: { type: 'string' }, + appleMusicId: { type: 'string' }, + }, + indexes: { + creatorAddress: { type: 'string' }, + }, + purge: {}, +}; diff --git a/services/blockchain-indexer/shared/database/schema/audios.js b/services/blockchain-indexer/shared/database/schema/audios.js deleted file mode 100644 index 0010a770a..000000000 --- a/services/blockchain-indexer/shared/database/schema/audios.js +++ /dev/null @@ -1,20 +0,0 @@ -module.exports = { - tableName: 'audios', - primaryKey: 'audioID', - schema: { - audioID: { type: 'string' }, - name: { type: 'string' }, - releaseYear: { type: 'string' }, - collectionID: { type: 'string' }, - audioSignature: { type: 'string' }, - audioHash: { type: 'string' }, - creatorAddress: { type: 'string' }, - }, - indexes: { - creatorAddress: { type: 'string' }, - }, - purge: {}, -}; - -// genre: number[]; -// fit: Buffer[]; diff --git a/services/blockchain-indexer/shared/database/schema/feats.js b/services/blockchain-indexer/shared/database/schema/feats.js deleted file mode 100644 index aabaff8d9..000000000 --- a/services/blockchain-indexer/shared/database/schema/feats.js +++ /dev/null @@ -1,13 +0,0 @@ -module.exports = { - tableName: 'feats', - primaryKey: ['address', 'audioID'], - schema: { - address: { type: 'string', null: true, defaultValue: null }, - audioID: { type: 'string' }, - role: { type: 'string', null: true, defaultValue: null }, - }, - indexes: { - creatorAddress: { type: 'string' }, - }, - purge: {}, -}; diff --git a/services/blockchain-indexer/shared/database/schema/images.js b/services/blockchain-indexer/shared/database/schema/images.js new file mode 100644 index 000000000..a74013e07 --- /dev/null +++ b/services/blockchain-indexer/shared/database/schema/images.js @@ -0,0 +1,14 @@ +module.exports = { + tableName: 'images', + primaryKey: ['url', 'anchorID'], + schema: { + url: { type: 'string' }, + anchorID: { type: 'string' }, + width: { type: 'integer' }, + height: { type: 'integer' }, + }, + indexes: { + anchorID: { type: 'string' }, + }, + purge: {}, +}; diff --git a/services/blockchain-indexer/shared/database/schema/owners.js b/services/blockchain-indexer/shared/database/schema/owners.js deleted file mode 100644 index 304748ba3..000000000 --- a/services/blockchain-indexer/shared/database/schema/owners.js +++ /dev/null @@ -1,14 +0,0 @@ -module.exports = { - tableName: 'owners', - primaryKey: ['address', 'audioID'], - schema: { - address: { type: 'string' }, - audioID: { type: 'string' }, - shares: { type: 'integer' }, - income: { type: 'bigInteger', defaultValue: 0 }, - }, - indexes: { - creatorAddress: { type: 'string' }, - }, - purge: {}, -}; diff --git a/services/blockchain-indexer/shared/indexer/transactionProcessor/audio/create.js b/services/blockchain-indexer/shared/indexer/transactionProcessor/audio/create.js index 686b273b1..846bab76f 100644 --- a/services/blockchain-indexer/shared/indexer/transactionProcessor/audio/create.js +++ b/services/blockchain-indexer/shared/indexer/transactionProcessor/audio/create.js @@ -12,12 +12,11 @@ const logger = Logger(); const MYSQL_ENDPOINT = config.endpoints.mysql; const accountsTableSchema = require('../../../database/schema/accounts'); -const audiosTableSchema = require('../../../database/schema/audios'); -const ownersTableSchema = require('../../../database/schema/owners'); -const featsTableSchema = require('../../../database/schema/feats'); +const anchorsTableSchema = require('../../../database/schema/anchors'); +const imagesTableSchema = require('../../../database/schema/images'); const { - MODULE_NAME_AUDIO, - EVENT_NAME_AUDIO_CREATED, + MODULE_NAME_ANCHOR, + EVENT_NAME_ANCHOR_CREATED, EVENT_NAME_COMMAND_EXECUTION_RESULT, } = require('../../../../../blockchain-connector/shared/sdk/constants/names'); @@ -27,21 +26,15 @@ const getAccountsTable = () => getTableInstance( MYSQL_ENDPOINT, ); -const getAudiosTable = () => getTableInstance( - audiosTableSchema.tableName, - audiosTableSchema, +const getAnchorsTable = () => getTableInstance( + anchorsTableSchema.tableName, + anchorsTableSchema, MYSQL_ENDPOINT, ); -const getOwnersTable = () => getTableInstance( - ownersTableSchema.tableName, - ownersTableSchema, - MYSQL_ENDPOINT, -); - -const getFeatsTable = () => getTableInstance( - featsTableSchema.tableName, - featsTableSchema, +const getImagesTable = () => getTableInstance( + imagesTableSchema.tableName, + imagesTableSchema, MYSQL_ENDPOINT, ); @@ -52,7 +45,7 @@ const COMMAND_NAME = 'create'; const applyTransaction = async (blockHeader, tx, events, dbTrx) => { // Do not process failed transactions const { data: commandExecutedData = {} } = events.find( - ({ module, name }) => module === MODULE_NAME_AUDIO + ({ module, name }) => module === MODULE_NAME_ANCHOR && name === EVENT_NAME_COMMAND_EXECUTION_RESULT, ); if (!commandExecutedData.success) { @@ -60,16 +53,15 @@ const applyTransaction = async (blockHeader, tx, events, dbTrx) => { } const accountsTable = await getAccountsTable(); - const audiosTable = await getAudiosTable(); - const ownersTable = await getOwnersTable(); - const featsTable = await getFeatsTable(); + const anchorsTable = await getAnchorsTable(); + const imagesTable = await getImagesTable(); - // Use event data to get audioID + // Use event data to get anchorID const eventData = events.find( - ({ module, name }) => module === MODULE_NAME_AUDIO - && name === EVENT_NAME_AUDIO_CREATED, + ({ module, name }) => module === MODULE_NAME_ANCHOR + && name === EVENT_NAME_ANCHOR_CREATED, ); - const { data: audioCreatedData } = eventData || { data: {} }; + const { data: anchorCreatedData } = eventData || { data: {} }; const senderAddress = getLisk32AddressFromPublicKey(tx.senderPublicKey); @@ -82,78 +74,56 @@ const applyTransaction = async (blockHeader, tx, events, dbTrx) => { await accountsTable.upsert(account, dbTrx); logger.debug(`Updated account index for the account with address ${account.address}.`); - // Store owners - await BluebirdPromise.map( - tx.params.owners, - async owner => { - const ownerInfo = { - ...owner, - audioID: audioCreatedData.audioID, - }; - logger.trace(`Updating owner index for the account with address ${owner.address}.`); - await ownersTable.upsert(ownerInfo, dbTrx); - logger.debug(`Updated owner index for the account with address ${owner.address}.`); - return true; - }, - { concurrency: tx.params.owners.length }, - ); - - // Store feats + // Store images await BluebirdPromise.map( - tx.params.feat, - async feat => { - const featInfo = { - address: feat, - role: 'co-artist', - audioID: audioCreatedData.audioID, + tx.params.images, + async image => { + const imageInfo = { + ...image, + anchorID: anchorCreatedData.anchorID, }; - logger.trace(`Updating feats index for the account with address ${feat}.`); - await featsTable.upsert(featInfo, dbTrx); - logger.debug(`Updated feats index for the account with address ${feat}.`); + logger.trace(`Updating image index for the account with address ${image.address}.`); + await imagesTable.upsert(imageInfo, dbTrx); + logger.debug(`Updated image index for the account with address ${image.address}.`); return true; }, - { concurrency: tx.params.feat.length }, + { concurrency: tx.params.images.length }, ); - logger.trace(`Updating owners index for the audio with audioID ${account.address}.`); + logger.trace(`Updating images index for the anchor with anchorID ${account.address}.`); await accountsTable.upsert(account, dbTrx); logger.debug(`Updated account index for the account with address ${account.address}.`); - logger.trace(`Indexing audios with address ${account.address}.`); + logger.trace(`Indexing anchors with address ${account.address}.`); - // And finally, store the audio - const audiosNFT = { - ...audioCreatedData, + // And finally, store the anchor + const anchorsNFT = { + ...anchorCreatedData, ...tx.params, }; - await audiosTable.upsert(audiosNFT, dbTrx); - logger.debug(`Indexed audio with ID ${audioCreatedData.audioID}.`); + await anchorsTable.upsert(anchorsNFT, dbTrx); + logger.debug(`Indexed anchor with ID ${anchorCreatedData.anchorID}.`); return true; }; // eslint-disable-next-line no-unused-vars const revertTransaction = async (blockHeader, tx, events, dbTrx) => { - const audiosTable = await getAudiosTable(); - const ownersTable = await getOwnersTable(); - const featsTable = await getFeatsTable(); + const anchorsTable = await getAnchorsTable(); + const imagesTable = await getImagesTable(); - const { data: audioCreatedData = {} } = events.find( - ({ module, name }) => module === MODULE_NAME_AUDIO - && name === EVENT_NAME_AUDIO_CREATED, + const { data: anchorCreatedData = {} } = events.find( + ({ module, name }) => module === MODULE_NAME_ANCHOR + && name === EVENT_NAME_ANCHOR_CREATED, ); - logger.trace(`Deleting owners corresponding the audio ID ${audioCreatedData.audioID}.`); - await ownersTable.delete({ audioID: audioCreatedData.audioID }, dbTrx); - logger.trace(`Deleted owners corresponding the audio ID ${audioCreatedData.audioID}.`); - - logger.trace(`Deleting feats corresponding the audio ID ${audioCreatedData.audioID}.`); - await featsTable.delete({ audioID: audioCreatedData.audioID }, dbTrx); - logger.trace(`Deleted feats corresponding the audio ID ${audioCreatedData.audioID}.`); + logger.trace(`Deleting images corresponding the anchor ID ${anchorCreatedData.anchorID}.`); + await imagesTable.delete({ anchorID: anchorCreatedData.anchorID }, dbTrx); + logger.trace(`Deleted images corresponding the anchor ID ${anchorCreatedData.anchorID}.`); - logger.trace(`Removing audio entry for ID ${audioCreatedData.audioID}.`); - await audiosTable.deleteByPrimaryKey(audioCreatedData.audioID, dbTrx); - logger.debug(`Removed audio entry for ID ${audioCreatedData.audioID}.`); + logger.trace(`Removing anchor entry for ID ${anchorCreatedData.anchorID}.`); + await anchorsTable.deleteByPrimaryKey(anchorCreatedData.anchorID, dbTrx); + logger.debug(`Removed anchor entry for ID ${anchorCreatedData.anchorID}.`); }; module.exports = { diff --git a/services/blockchain-indexer/shared/indexer/transactionProcessor/audio/destroy.js b/services/blockchain-indexer/shared/indexer/transactionProcessor/audio/destroy.js index 824c1a9fc..b56ab9c40 100644 --- a/services/blockchain-indexer/shared/indexer/transactionProcessor/audio/destroy.js +++ b/services/blockchain-indexer/shared/indexer/transactionProcessor/audio/destroy.js @@ -8,30 +8,23 @@ const config = require('../../../../config'); const logger = Logger(); const MYSQL_ENDPOINT = config.endpoints.mysql; -const audiosTableSchema = require('../../../database/schema/audios'); -const ownersTableSchema = require('../../../database/schema/owners'); -const featsTableSchema = require('../../../database/schema/feats'); +const anchorsTableSchema = require('../../../database/schema/anchors'); +const imagesTableSchema = require('../../../database/schema/images'); const { - MODULE_NAME_AUDIO, + MODULE_NAME_ANCHOR, EVENT_NAME_COMMAND_EXECUTION_RESULT, } = require('../../../../../blockchain-connector/shared/sdk/constants/names'); -const getAudiosTable = () => getTableInstance( - audiosTableSchema.tableName, - audiosTableSchema, +const getAnchorsTable = () => getTableInstance( + anchorsTableSchema.tableName, + anchorsTableSchema, MYSQL_ENDPOINT, ); -const getOwnersTable = () => getTableInstance( - ownersTableSchema.tableName, - ownersTableSchema, - MYSQL_ENDPOINT, -); - -const getFeatsTable = () => getTableInstance( - featsTableSchema.tableName, - featsTableSchema, +const getImagesTable = () => getTableInstance( + imagesTableSchema.tableName, + imagesTableSchema, MYSQL_ENDPOINT, ); @@ -41,30 +34,25 @@ const COMMAND_NAME = 'destroy'; // eslint-disable-next-line no-unused-vars const applyTransaction = async (blockHeader, tx, events, dbTrx) => { const { data: commandExecutedData = {} } = events.find( - ({ module, name }) => module === MODULE_NAME_AUDIO + ({ module, name }) => module === MODULE_NAME_ANCHOR && name === EVENT_NAME_COMMAND_EXECUTION_RESULT, ); if (!commandExecutedData.success) { return false; } - const { audioID } = tx.params; - - const audiosTable = await getAudiosTable(); - const ownersTable = await getOwnersTable(); - const featsTable = await getFeatsTable(); + const { anchorID } = tx.params; - logger.trace(`Removing audio index for the audio with ID ${audioID}.`); - await audiosTable.delete({ audioID }, dbTrx); - logger.trace(`Removed audio index for the audio with ID ${audioID}.`); + const anchorsTable = await getAnchorsTable(); + const imagesTable = await getImagesTable(); - logger.trace(`Removing owners index for the audio with ID ${audioID}.`); - await ownersTable.delete({ audioID }, dbTrx); - logger.trace(`Removed owners index for the audio with ID ${audioID}.`); + logger.trace(`Removing anchor index for the anchor with ID ${anchorID}.`); + await anchorsTable.delete({ anchorID }, dbTrx); + logger.trace(`Removed anchor index for the anchor with ID ${anchorID}.`); - logger.trace(`Removing feats index for the audio with ID ${audioID}.`); - await featsTable.delete({ audioID }, dbTrx); - logger.trace(`Removed feats index for the audio with ID ${audioID}.`); + logger.trace(`Removing images index for the anchor with ID ${anchorID}.`); + await imagesTable.delete({ anchorID }, dbTrx); + logger.trace(`Removed images index for the anchor with ID ${anchorID}.`); return true; }; diff --git a/services/blockchain-indexer/shared/indexer/transactionProcessor/audio/index.js b/services/blockchain-indexer/shared/indexer/transactionProcessor/audio/index.js index d316851af..2e5b448b0 100644 --- a/services/blockchain-indexer/shared/indexer/transactionProcessor/audio/index.js +++ b/services/blockchain-indexer/shared/indexer/transactionProcessor/audio/index.js @@ -1,5 +1,5 @@ // Module specific constants -const MODULE_NAME = 'audio'; +const MODULE_NAME = 'anchor'; module.exports = { MODULE_NAME, diff --git a/services/blockchain-indexer/shared/indexer/transactionProcessor/audio/reclaim.js b/services/blockchain-indexer/shared/indexer/transactionProcessor/audio/reclaim.js deleted file mode 100644 index 9e377b4eb..000000000 --- a/services/blockchain-indexer/shared/indexer/transactionProcessor/audio/reclaim.js +++ /dev/null @@ -1,76 +0,0 @@ -const { - Logger, - MySQL: { getTableInstance }, -} = require('lisk-service-framework'); -const BluebirdPromise = require('bluebird'); - -const config = require('../../../../config'); - -const logger = Logger(); - -const MYSQL_ENDPOINT = config.endpoints.mysql; -const ownersTableSchema = require('../../../database/schema/owners'); - -const { - MODULE_NAME_AUDIO, - EVENT_NAME_COMMAND_EXECUTION_RESULT, - EVENT_NAME_AUDIO_INCOME_RECLAIMED, -} = require('../../../../../blockchain-connector/shared/sdk/constants/names'); - -const getOwnersTable = () => getTableInstance( - ownersTableSchema.tableName, - ownersTableSchema, - MYSQL_ENDPOINT, -); - -// Command specific constants -const COMMAND_NAME = 'reclaim'; - -// eslint-disable-next-line no-unused-vars -const applyTransaction = async (blockHeader, tx, events, dbTrx) => { - const { data: commandExecutedData = {} } = events.find( - ({ module, name }) => module === MODULE_NAME_AUDIO - && name === EVENT_NAME_COMMAND_EXECUTION_RESULT, - ); - if (!commandExecutedData.success) { - return false; - } - - const ownersTable = await getOwnersTable(); - - // Use event data to get audioID - const eventData = events.find( - ({ module, name }) => module === MODULE_NAME_AUDIO - && name === EVENT_NAME_AUDIO_INCOME_RECLAIMED, - ); - const { data: audioIncomeReclaimedData } = eventData || { data: { claimData: { audioIDs: [] } } }; - - await BluebirdPromise.map( - audioIncomeReclaimedData.claimData.audioIDs, - async audioID => { - const owners = await ownersTable.find({ audioID }, ['address', 'shares', 'income'], dbTrx); - const sender = owners.find(owner => owner.address === tx.senderAddress); - const info = { - ...sender, - audioID, - income: 0, - }; - logger.trace(`Updating owner index for the account with address ${sender.address} and audioID: ${audioID}.`); - await ownersTable.upsert(info, dbTrx); - logger.debug(`Updated owner index for the account with address ${sender.address} and audioID: ${audioID}.`); - return true; - }, - { concurrency: audioIncomeReclaimedData.claimData.audioIDs.length }, - ); - - return true; -}; - -// eslint-disable-next-line no-unused-vars -const revertTransaction = async (blockHeader, tx, events, dbTrx) => {}; - -module.exports = { - COMMAND_NAME, - applyTransaction, - revertTransaction, -}; diff --git a/services/blockchain-indexer/shared/indexer/transactionProcessor/audio/setAttributes.js b/services/blockchain-indexer/shared/indexer/transactionProcessor/audio/setAttributes.js deleted file mode 100644 index 3c97464e7..000000000 --- a/services/blockchain-indexer/shared/indexer/transactionProcessor/audio/setAttributes.js +++ /dev/null @@ -1,119 +0,0 @@ -const { - Logger, - MySQL: { getTableInstance }, -} = require('lisk-service-framework'); -const BluebirdPromise = require('bluebird'); - -const config = require('../../../../config'); - -const logger = Logger(); - -const MYSQL_ENDPOINT = config.endpoints.mysql; -const audiosTableSchema = require('../../../database/schema/audios'); -const featsTableSchema = require('../../../database/schema/feats'); - -const { - MODULE_NAME_AUDIO, - EVENT_NAME_COMMAND_EXECUTION_RESULT, -} = require('../../../../../blockchain-connector/shared/sdk/constants/names'); - -const getAudiosTable = () => getTableInstance( - audiosTableSchema.tableName, - audiosTableSchema, - MYSQL_ENDPOINT, -); - -const getFitsTable = () => getTableInstance( - featsTableSchema.tableName, - featsTableSchema, - MYSQL_ENDPOINT, -); - -// Command specific constants -const COMMAND_NAME = 'setAttributes'; - -// eslint-disable-next-line no-unused-vars -const applyTransaction = async (blockHeader, tx, events, dbTrx) => { - // Do not process failed transactions - const { data: commandExecutedData = {} } = events.find( - ({ module, name }) => module === MODULE_NAME_AUDIO - && name === EVENT_NAME_COMMAND_EXECUTION_RESULT, - ); - if (!commandExecutedData.success) { - return false; - } - - const audiosTable = await getAudiosTable(); - const featsTable = await getFitsTable(); - - const { audioID } = tx.params; - - // Find the audio to process - const [audio] = await audiosTable.find( - { audioID }, - ['name', 'releaseYear', 'collectionID', 'creatorAddress'], - dbTrx, - ); - const oldFeats = await featsTable.find( - { audioID }, - ['address'], - dbTrx, - ); - const oldFeatsAddresses = oldFeats.map(({ address }) => address); - - // Define removed and added feats - const removedFeats = oldFeatsAddresses.filter( - address => !tx.params.feat.includes(address), - ); - const addedFeats = tx.params.feat.filter( - address => !oldFeatsAddresses.includes(address), - ); - - // Store new feats - await BluebirdPromise.map( - addedFeats, - async address => { - const featInfo = { - address, - role: 'co-artist', // TODO: get role from tx.params.feat - audioID, - }; - logger.trace(`Updating feats index for the account with address ${address}.`); - await featsTable.upsert(featInfo, dbTrx); - logger.debug(`Updated feats index for the account with address ${address}.`); - return true; - }, - { concurrency: tx.params.feat.length }, - ); - - // Remove old feats - await BluebirdPromise.map( - removedFeats, - async address => { - logger.trace(`Updating feats index for the account with address ${address}.`); - await featsTable.delete({ address, audioID }, dbTrx); - logger.debug(`Updated feats index for the account with address ${address}.`); - return true; - }, - { concurrency: tx.params.feat.length }, - ); - - logger.trace(`Updating audio with ID ${audioID}.`); - const audiosNFT = { - ...audio, - ...tx.params, - }; - - await audiosTable.upsert(audiosNFT, dbTrx); - logger.debug(`Updated audio with ID ${audioID}.`); - return true; -}; - -// eslint-disable-next-line no-unused-vars -const revertTransaction = async (blockHeader, tx, events, dbTrx) => {}; - -module.exports = { - COMMAND_NAME, - applyTransaction, - revertTransaction, -}; diff --git a/services/blockchain-indexer/shared/indexer/transactionProcessor/audio/transfer.js b/services/blockchain-indexer/shared/indexer/transactionProcessor/audio/transfer.js deleted file mode 100644 index 53104eb2c..000000000 --- a/services/blockchain-indexer/shared/indexer/transactionProcessor/audio/transfer.js +++ /dev/null @@ -1,84 +0,0 @@ -const { - Logger, - MySQL: { getTableInstance }, -} = require('lisk-service-framework'); - -const { getLisk32AddressFromPublicKey } = require('../../../utils/account'); - -const config = require('../../../../config'); - -const logger = Logger(); - -const MYSQL_ENDPOINT = config.endpoints.mysql; -const ownersTableSchema = require('../../../database/schema/owners'); - -const { - MODULE_NAME_AUDIO, - EVENT_NAME_COMMAND_EXECUTION_RESULT, -} = require('../../../../../blockchain-connector/shared/sdk/constants/names'); - -const getOwnersTable = () => getTableInstance( - ownersTableSchema.tableName, - ownersTableSchema, - MYSQL_ENDPOINT, -); - -// Command specific constants -const COMMAND_NAME = 'transfer'; - -// eslint-disable-next-line no-unused-vars -const applyTransaction = async (blockHeader, tx, events, dbTrx) => { - const { data: commandExecutedData = {} } = events.find( - ({ module, name }) => module === MODULE_NAME_AUDIO - && name === EVENT_NAME_COMMAND_EXECUTION_RESULT, - ); - if (!commandExecutedData.success) { - return false; - } - - const ownersTable = await getOwnersTable(); - - const senderAddress = getLisk32AddressFromPublicKey(tx.senderPublicKey); - const { - audioID, - address: recipientAddress, - shares: transferredShares, - } = tx.params; - - const [sender] = await ownersTable.find({ audioID, address: senderAddress }, ['address', 'audioID', 'shares', 'income'], dbTrx); - let [recipient] = await ownersTable.find({ audioID, address: recipientAddress }, ['address', 'audioID', 'shares', 'income'], dbTrx); - - // Transfer the shares - logger.trace(`Updating owner index for the account with address ${senderAddress}.`); - sender.shares -= transferredShares; - if (sender.shares === 0) { - await ownersTable.delete({ audioID: tx.params.audioID, address: senderAddress }, dbTrx); - } else { - await ownersTable.upsert(sender, dbTrx); - } - - logger.debug(`Updated owner index for the account with address ${senderAddress}.`); - - logger.trace(`Updating owner index for the account with address ${recipientAddress}.`); - if (recipient) { - recipient.shares += transferredShares; - } else { - recipient = { - audioID, - address: recipientAddress, - shares: transferredShares, - }; - } - await ownersTable.upsert(recipient, dbTrx); - logger.debug(`Updated owner index for the account with address ${recipientAddress}.`); - return true; -}; - -// eslint-disable-next-line no-unused-vars -const revertTransaction = async (blockHeader, tx, events, dbTrx) => {}; - -module.exports = { - COMMAND_NAME, - applyTransaction, - revertTransaction, -}; diff --git a/services/blockchain-indexer/shared/indexer/transactionProcessor/audio/stream.js b/services/blockchain-indexer/shared/indexer/transactionProcessor/audio/vote.js similarity index 52% rename from services/blockchain-indexer/shared/indexer/transactionProcessor/audio/stream.js rename to services/blockchain-indexer/shared/indexer/transactionProcessor/audio/vote.js index 415a9a77e..44a232bcf 100644 --- a/services/blockchain-indexer/shared/indexer/transactionProcessor/audio/stream.js +++ b/services/blockchain-indexer/shared/indexer/transactionProcessor/audio/vote.js @@ -9,56 +9,56 @@ const config = require('../../../../config'); const logger = Logger(); const MYSQL_ENDPOINT = config.endpoints.mysql; -const ownersTableSchema = require('../../../database/schema/owners'); +const imagesTableSchema = require('../../../database/schema/images'); const { - MODULE_NAME_AUDIO, - EVENT_NAME_AUDIO_STREAMED, + MODULE_NAME_ANCHOR, + EVENT_NAME_ANCHOR_VOTED, EVENT_NAME_COMMAND_EXECUTION_RESULT, } = require('../../../../../blockchain-connector/shared/sdk/constants/names'); -const getOwnersTable = () => getTableInstance( - ownersTableSchema.tableName, - ownersTableSchema, +const getImagesTable = () => getTableInstance( + imagesTableSchema.tableName, + imagesTableSchema, MYSQL_ENDPOINT, ); // Command specific constants -const COMMAND_NAME = 'stream'; +const COMMAND_NAME = 'vote'; // eslint-disable-next-line no-unused-vars const applyTransaction = async (blockHeader, tx, events, dbTrx) => { const { data: commandExecutedData = {} } = events.find( - ({ module, name }) => module === MODULE_NAME_AUDIO + ({ module, name }) => module === MODULE_NAME_ANCHOR && name === EVENT_NAME_COMMAND_EXECUTION_RESULT, ); if (!commandExecutedData.success) { return false; } - const ownersTable = await getOwnersTable(); + const imagesTable = await getImagesTable(); - const { audioID } = tx.params; + const { anchorID } = tx.params; - // Use event data to get audioID - const { data: audioStreamedData = {} } = events.find( - ({ module, name }) => module === MODULE_NAME_AUDIO - && name === EVENT_NAME_AUDIO_STREAMED, + // Use event data to get anchorID + const { data: anchorVotedData = {} } = events.find( + ({ module, name }) => module === MODULE_NAME_ANCHOR + && name === EVENT_NAME_ANCHOR_VOTED, ); await BluebirdPromise.map( - audioStreamedData.owners, - async owner => { + anchorVotedData.images, + async image => { const info = { - ...owner, - audioID, + ...image, + anchorID, }; - logger.trace(`Updating owner index for the account with address ${owner.address}.`); - await ownersTable.upsert(info, dbTrx); - logger.debug(`Updated owner index for the account with address ${owner.address}.`); + logger.trace(`Updating image index for the account with address ${image.address}.`); + await imagesTable.upsert(info, dbTrx); + logger.debug(`Updated image index for the account with address ${image.address}.`); return true; }, - { concurrency: audioStreamedData.owners.length }, + { concurrency: anchorVotedData.images.length }, ); return true; diff --git a/services/gateway/apis/http-version3/methods/anchors.js b/services/gateway/apis/http-version3/methods/anchors.js new file mode 100644 index 000000000..45b2f2d91 --- /dev/null +++ b/services/gateway/apis/http-version3/methods/anchors.js @@ -0,0 +1,41 @@ +const anchorsSource = require('../../../sources/version3/anchors'); +const envelope = require('../../../sources/version3/mappings/stdEnvelope'); +const regex = require('../../../shared/regex'); +const { transformParams, response, getSwaggerDescription } = require('../../../shared/utils'); + +module.exports = { + version: '2.0', + swaggerApiPath: '/anchors', + rpcMethod: 'get.anchors', + tags: ['Anchors'], + params: { + submitter: { optional: true, type: 'string', min: 3, max: 41, pattern: regex.ADDRESS_LISK32 }, + anchorID: { optional: true, type: 'string', min: 1, max: 64, pattern: regex.HASH_SHA256 }, + search: { optional: true, type: 'string' }, + limit: { optional: true, type: 'number', min: 1, max: 100, default: 10 }, + offset: { optional: true, type: 'number', min: 0, default: 0 }, + }, + get schema() { + const anchorSchema = {}; + anchorSchema[this.swaggerApiPath] = { get: {} }; + anchorSchema[this.swaggerApiPath].get.tags = this.tags; + anchorSchema[this.swaggerApiPath].get.summary = 'Requests anchors data'; + anchorSchema[this.swaggerApiPath].get.description = getSwaggerDescription({ + rpcMethod: this.rpcMethod, + description: 'Returns anchors data', + }); + anchorSchema[this.swaggerApiPath].get.parameters = transformParams('anchors', this.params); + anchorSchema[this.swaggerApiPath].get.responses = { + 200: { + description: 'Returns a list of anchors', + schema: { + $ref: '#/definitions/anchorsWithEnvelope', + }, + }, + }; + Object.assign(anchorSchema[this.swaggerApiPath].get.responses, response); + return anchorSchema; + }, + source: anchorsSource, + envelope, +}; diff --git a/services/gateway/apis/http-version3/methods/audios.js b/services/gateway/apis/http-version3/methods/audios.js deleted file mode 100644 index f81b74e5c..000000000 --- a/services/gateway/apis/http-version3/methods/audios.js +++ /dev/null @@ -1,43 +0,0 @@ -const audiosSource = require('../../../sources/version3/audios'); -const envelope = require('../../../sources/version3/mappings/stdEnvelope'); -const regex = require('../../../shared/regex'); -const { transformParams, response, getSwaggerDescription } = require('../../../shared/utils'); - -module.exports = { - version: '2.0', - swaggerApiPath: '/audios', - rpcMethod: 'get.audios', - tags: ['Audios'], - params: { - creatorAddress: { optional: true, type: 'string', min: 3, max: 41, pattern: regex.ADDRESS_LISK32 }, - audioID: { optional: true, type: 'string', min: 1, max: 64, pattern: regex.HASH_SHA256 }, - collectionID: { optional: true, type: 'string', min: 1, max: 64, pattern: regex.HASH_SHA256 }, - ownerAddress: { optional: true, type: 'string', min: 3, max: 41, pattern: regex.ADDRESS_LISK32 }, - search: { optional: true, type: 'string' }, - limit: { optional: true, type: 'number', min: 1, max: 100, default: 10 }, - offset: { optional: true, type: 'number', min: 0, default: 0 }, - }, - get schema() { - const audioSchema = {}; - audioSchema[this.swaggerApiPath] = { get: {} }; - audioSchema[this.swaggerApiPath].get.tags = this.tags; - audioSchema[this.swaggerApiPath].get.summary = 'Requests audios data'; - audioSchema[this.swaggerApiPath].get.description = getSwaggerDescription({ - rpcMethod: this.rpcMethod, - description: 'Returns audios data', - }); - audioSchema[this.swaggerApiPath].get.parameters = transformParams('audios', this.params); - audioSchema[this.swaggerApiPath].get.responses = { - 200: { - description: 'Returns a list of audios', - schema: { - $ref: '#/definitions/audiosWithEnvelope', - }, - }, - }; - Object.assign(audioSchema[this.swaggerApiPath].get.responses, response); - return audioSchema; - }, - source: audiosSource, - envelope, -}; diff --git a/services/gateway/apis/http-version3/swagger/apiJson.json b/services/gateway/apis/http-version3/swagger/apiJson.json index 09807a697..b7e505b4d 100644 --- a/services/gateway/apis/http-version3/swagger/apiJson.json +++ b/services/gateway/apis/http-version3/swagger/apiJson.json @@ -96,8 +96,8 @@ "description": "Collection module related API calls." }, { - "name": "Audio", - "description": "Audio module related API calls." + "name": "Anchor", + "description": "Anchor module related API calls." }, { "name": "Profile", diff --git a/services/gateway/apis/http-version3/swagger/definitions/audios.json b/services/gateway/apis/http-version3/swagger/definitions/anchors.json similarity index 87% rename from services/gateway/apis/http-version3/swagger/definitions/audios.json rename to services/gateway/apis/http-version3/swagger/definitions/anchors.json index 5b5e94998..94af8b581 100644 --- a/services/gateway/apis/http-version3/swagger/definitions/audios.json +++ b/services/gateway/apis/http-version3/swagger/definitions/anchors.json @@ -1,8 +1,8 @@ { - "audio": { + "anchor": { "type": "object", "required": [ - "audioID", + "anchorID", "name", "releaseYear", "collectionID", @@ -10,17 +10,17 @@ "feat" ], "properties": { - "audioID": { + "anchorID": { "type": "string", "format": "id", "example": "f9593f101c4acafc3ede650ab4c10fa2ecb59b225813eddbbb17b47e96932e9b", "minLength": 1, "maxLength": 64, - "description": "Unique identifier of the audio.\nDerived from the audio hash." + "description": "Unique identifier of the anchor.\nDerived from the anchor hash." }, "name": { "type": "string", - "description": "name of the audio" + "description": "name of the anchor" }, "releaseYear": { "type": "string", @@ -32,7 +32,7 @@ "example": "f9593f101c4acafc3ede650ab4c10fa2ecb59b225813eddbbb17b47e96932e9b", "minLength": 1, "maxLength": 64, - "description": "Unique identifier of the collection to which the current audio belongs." + "description": "Unique identifier of the collection to which the current anchor belongs." }, "creatorAddress": { "type": "object", @@ -77,13 +77,13 @@ "role": { "type": "string", "example": "guitarist", - "description": "Role of the artist in creation of the audio." + "description": "Role of the artist in creation of the anchor." } } } } }, - "AudiosWithEnvelope": { + "AnchorsWithEnvelope": { "type": "object", "required": [ "data", @@ -91,10 +91,10 @@ ], "properties": { "data": { - "description": "List of audios", + "description": "List of anchors", "type": "array", "items": { - "$ref": "#/definitions/Audios" + "$ref": "#/definitions/Anchors" } }, "meta": { diff --git a/services/gateway/apis/http-version3/swagger/parameters/audios.json b/services/gateway/apis/http-version3/swagger/parameters/anchors.json similarity index 64% rename from services/gateway/apis/http-version3/swagger/parameters/audios.json rename to services/gateway/apis/http-version3/swagger/parameters/anchors.json index 3fe410c6f..071f347a0 100644 --- a/services/gateway/apis/http-version3/swagger/parameters/audios.json +++ b/services/gateway/apis/http-version3/swagger/parameters/anchors.json @@ -1,16 +1,16 @@ { - "creatorAddress": { - "name": "creatorAddress", + "submitter": { + "name": "submitter", "in": "query", "description": "Lisk account address", "type": "string", "minLength": 3, "maxLength": 41 }, - "audioID": { - "name": "audioID", + "anchorID": { + "name": "anchorID", "in": "query", - "description": "audio ID to query", + "description": "anchor ID to query", "type": "string", "format": "id", "minLength": 1, diff --git a/services/gateway/sources/version3/anchors.js b/services/gateway/sources/version3/anchors.js new file mode 100644 index 000000000..8ec387010 --- /dev/null +++ b/services/gateway/sources/version3/anchors.js @@ -0,0 +1,31 @@ +const anchor = require('./mappings/anchor'); + +module.exports = { + type: 'moleculer', + method: 'indexer.anchors', + params: { + anchorID: '=,string', + name: '=,string', + album: '=,string', + artists: '=,string', + images: ['images', { + url: '=,string', + width: '=,number', + height: '=,number', + }], + search: '=,string', + limit: '=,number', + offset: '=,number', + sort: '=,string', + order: '=,string', + }, + definition: { + data: ['data', anchor], + meta: { + count: '=,number', + offset: '=,number', + total: '=,number', + }, + links: {}, + }, +}; diff --git a/services/gateway/sources/version3/audios.js b/services/gateway/sources/version3/audios.js deleted file mode 100644 index 51f89b7f0..000000000 --- a/services/gateway/sources/version3/audios.js +++ /dev/null @@ -1,42 +0,0 @@ -const audio = require('./mappings/audio'); - -module.exports = { - type: 'moleculer', - method: 'indexer.audios', - params: { - name: '=,string', - audioID: '=,string', - creatorAddress: '=,string', - releaseYear: '=,string', - collectionID: '=,string', - collection: { - collectionType: '=,string', - releaseYear: '=,number', - name: '=,number', - }, - owners: ['owners', { - address: '=,string', - shares: '=,number', - income: '=,number', - }], - feat: ['feat', { - address: '=,string', - name: '=,string', - role: '=,string', - }], - search: '=,string', - limit: '=,number', - offset: '=,number', - sort: '=,string', - order: '=,string', - }, - definition: { - data: ['data', audio], - meta: { - count: '=,number', - offset: '=,number', - total: '=,number', - }, - links: {}, - }, -}; diff --git a/services/gateway/sources/version3/collections.js b/services/gateway/sources/version3/collections.js index 1e6cbca35..fdedfc839 100644 --- a/services/gateway/sources/version3/collections.js +++ b/services/gateway/sources/version3/collections.js @@ -9,8 +9,8 @@ module.exports = { creatorAddress: '=,string', releaseYear: '=,string', collectionType: '=,number', - // audios: ['audios', { - // audioID: '=,string', + // anchors: ['anchors', { + // anchorID: '=,string', // name: '=,number', // }], search: '=,string', diff --git a/services/gateway/sources/version3/mappings/anchor.js b/services/gateway/sources/version3/mappings/anchor.js new file mode 100644 index 000000000..f816004c8 --- /dev/null +++ b/services/gateway/sources/version3/mappings/anchor.js @@ -0,0 +1,12 @@ +module.exports = { + name: '=,string', + album: '=,string', + anchorID: '=,string', + artists: '=,string', + submitter: '=,string', + images: ['images', { + url: '=,string', + width: '=,number', + height: '=,number', + }], +}; diff --git a/services/gateway/sources/version3/mappings/audio.js b/services/gateway/sources/version3/mappings/audio.js deleted file mode 100644 index a70f0c474..000000000 --- a/services/gateway/sources/version3/mappings/audio.js +++ /dev/null @@ -1,21 +0,0 @@ -module.exports = { - name: '=,string', - releaseYear: '=,string', - audioID: '=,string', - collectionID: '=,string', - creatorAddress: '=,string', - collection: { - collectionType: '=,string', - releaseYear: '=,number', - name: '=,string', - }, - owners: ['owners', { - address: '=,string', - shares: '=,number', - income: '=,number', - }], - feat: ['feat', { - address: '=,string', - role: '=,string', - }], -}; diff --git a/services/gateway/tests/constants/generateDocs.js b/services/gateway/tests/constants/generateDocs.js index 5c323052a..6e791bfa5 100644 --- a/services/gateway/tests/constants/generateDocs.js +++ b/services/gateway/tests/constants/generateDocs.js @@ -14,21 +14,15 @@ * */ const createApiDocsExpectedResponse = { - '/audios': { + '/anchors': { get: { - description: 'Returns audios data\n RPC => get.audios', + description: 'Returns anchors data\n RPC => get.anchors', parameters: [ { - $ref: '#/parameters/creatorAddress', - }, - { - $ref: '#/parameters/audioID', - }, - { - $ref: '#/parameters/collectionID', + $ref: '#/parameters/submitter', }, { - $ref: '#/parameters/ownerAddress', + $ref: '#/parameters/anchorID', }, { $ref: '#/parameters/search', @@ -42,9 +36,9 @@ const createApiDocsExpectedResponse = { ], responses: { 200: { - description: 'Returns a list of audios', + description: 'Returns a list of anchors', schema: { - $ref: '#/definitions/audiosWithEnvelope', + $ref: '#/definitions/anchorsWithEnvelope', }, }, 400: { @@ -54,9 +48,9 @@ const createApiDocsExpectedResponse = { }, }, }, - summary: 'Requests audios data', + summary: 'Requests anchors data', tags: [ - 'Audios', + 'Anchors', ], }, }, diff --git a/services/gateway/tests/constants/registerApi.js b/services/gateway/tests/constants/registerApi.js index eb340fb90..22825ff88 100644 --- a/services/gateway/tests/constants/registerApi.js +++ b/services/gateway/tests/constants/registerApi.js @@ -17,7 +17,7 @@ const expectedResponseForRegisterHttpApi = [ { whitelist: [ - 'indexer.audios', + 'indexer.anchors', 'indexer.blocks.assets', 'indexer.blockchain.apps', 'app-registry.blockchain.apps.meta.list', @@ -67,7 +67,7 @@ const expectedResponseForRegisterHttpApi = [ 'GET blocks/assets': 'indexer.blocks.assets', 'GET collections': 'indexer.collections', 'GET profiles': 'indexer.profiles', - 'GET audios': 'indexer.audios', + 'GET anchors': 'indexer.anchors', 'GET blockchain/apps': 'indexer.blockchain.apps', 'GET blockchain/apps/meta/list': 'app-registry.blockchain.apps.meta.list', 'GET blockchain/apps/meta': 'app-registry.blockchain.apps.meta', @@ -130,7 +130,7 @@ const expectedResponseForRegisterRpcApi = { events: { request: { whitelist: [ - 'indexer.audios', + 'indexer.anchors', 'indexer.blocks.assets', 'indexer.blockchain.apps', 'app-registry.blockchain.apps.meta.list', @@ -178,7 +178,7 @@ const expectedResponseForRegisterRpcApi = { aliases: { 'get.blocks.assets': 'indexer.blocks.assets', 'get.collections': 'indexer.collections', - 'get.audios': 'indexer.audios', + 'get.anchors': 'indexer.anchors', 'get.blockchain.apps': 'indexer.blockchain.apps', 'get.blockchain.apps.meta.list': 'app-registry.blockchain.apps.meta.list', 'get.blockchain.apps.meta': 'app-registry.blockchain.apps.meta', From 69fa49d74e39334f3ae9a3a9ca0c160b94d1a99a Mon Sep 17 00:00:00 2001 From: reyraa Date: Wed, 18 Oct 2023 23:26:41 +0200 Subject: [PATCH 02/10] Add support for anchors --- .../shared/sdk/constants/eventTopics.js | 20 +--- .../shared/sdk/constants/names.js | 18 +-- .../dataService/controllers/collections.js | 31 ----- .../dataService/controllers/profiles.js | 31 ----- .../methods/dataService/modules/collection.js | 16 --- .../methods/dataService/modules/profile.js | 16 --- .../shared/dataService/business/anchors.js | 50 ++++---- .../dataService/business/collections.js | 47 -------- .../shared/dataService/business/index.js | 7 -- .../shared/dataService/business/profiles.js | 72 ------------ .../shared/dataService/collections.js | 22 ---- .../shared/dataService/index.js | 8 -- .../shared/dataService/profiles.js | 22 ---- .../shared/database/schema/anchors.js | 5 +- .../shared/database/schema/collections.js | 17 --- .../shared/database/schema/profiles.js | 20 ---- .../shared/database/schema/socialAccounts.js | 13 --- .../shared/database/schema/votes.js | 13 +++ .../{audio => anchor}/create.js | 1 + .../{audio => anchor}/destroy.js | 0 .../{audio => anchor}/index.js | 0 .../{audio => anchor}/vote.js | 40 +++---- .../transactionProcessor/collection/create.js | 100 ---------------- .../collection/destroy.js | 39 ------- .../transactionProcessor/collection/index.js | 6 - .../collection/setAttributes.js | 46 -------- .../collection/transfer.js | 45 -------- .../transactionProcessor/profile/create.js | 97 ---------------- .../transactionProcessor/profile/index.js | 6 - .../profile/setAttribute.js | 86 -------------- .../apis/http-version3/methods/collections.js | 39 ------- .../apis/http-version3/methods/profiles.js | 39 ------- .../apis/http-version3/swagger/apiJson.json | 8 -- .../swagger/definitions/anchors.json | 99 ++++++++++------ .../swagger/definitions/collections.json | 88 -------------- .../swagger/definitions/profiles.json | 107 ------------------ .../swagger/parameters/collections.json | 19 ---- .../swagger/parameters/profiles.json | 19 ---- services/gateway/sources/version3/anchors.js | 3 + .../gateway/sources/version3/collections.js | 31 ----- .../sources/version3/mappings/anchor.js | 6 +- .../sources/version3/mappings/collection.js | 22 ---- .../sources/version3/mappings/profile.js | 16 --- services/gateway/sources/version3/profiles.js | 31 ----- .../gateway/tests/constants/generateDocs.js | 68 ----------- .../gateway/tests/constants/registerApi.js | 8 -- 46 files changed, 128 insertions(+), 1369 deletions(-) delete mode 100644 services/blockchain-indexer/methods/dataService/controllers/collections.js delete mode 100644 services/blockchain-indexer/methods/dataService/controllers/profiles.js delete mode 100644 services/blockchain-indexer/methods/dataService/modules/collection.js delete mode 100644 services/blockchain-indexer/methods/dataService/modules/profile.js delete mode 100644 services/blockchain-indexer/shared/dataService/business/collections.js delete mode 100644 services/blockchain-indexer/shared/dataService/business/profiles.js delete mode 100644 services/blockchain-indexer/shared/dataService/collections.js delete mode 100644 services/blockchain-indexer/shared/dataService/profiles.js delete mode 100644 services/blockchain-indexer/shared/database/schema/collections.js delete mode 100644 services/blockchain-indexer/shared/database/schema/profiles.js delete mode 100644 services/blockchain-indexer/shared/database/schema/socialAccounts.js create mode 100644 services/blockchain-indexer/shared/database/schema/votes.js rename services/blockchain-indexer/shared/indexer/transactionProcessor/{audio => anchor}/create.js (99%) rename services/blockchain-indexer/shared/indexer/transactionProcessor/{audio => anchor}/destroy.js (100%) rename services/blockchain-indexer/shared/indexer/transactionProcessor/{audio => anchor}/index.js (100%) rename services/blockchain-indexer/shared/indexer/transactionProcessor/{audio => anchor}/vote.js (53%) delete mode 100644 services/blockchain-indexer/shared/indexer/transactionProcessor/collection/create.js delete mode 100644 services/blockchain-indexer/shared/indexer/transactionProcessor/collection/destroy.js delete mode 100644 services/blockchain-indexer/shared/indexer/transactionProcessor/collection/index.js delete mode 100644 services/blockchain-indexer/shared/indexer/transactionProcessor/collection/setAttributes.js delete mode 100644 services/blockchain-indexer/shared/indexer/transactionProcessor/collection/transfer.js delete mode 100644 services/blockchain-indexer/shared/indexer/transactionProcessor/profile/create.js delete mode 100644 services/blockchain-indexer/shared/indexer/transactionProcessor/profile/index.js delete mode 100644 services/blockchain-indexer/shared/indexer/transactionProcessor/profile/setAttribute.js delete mode 100644 services/gateway/apis/http-version3/methods/collections.js delete mode 100644 services/gateway/apis/http-version3/methods/profiles.js delete mode 100644 services/gateway/apis/http-version3/swagger/definitions/collections.json delete mode 100644 services/gateway/apis/http-version3/swagger/definitions/profiles.json delete mode 100644 services/gateway/apis/http-version3/swagger/parameters/collections.json delete mode 100644 services/gateway/apis/http-version3/swagger/parameters/profiles.json delete mode 100644 services/gateway/sources/version3/collections.js delete mode 100644 services/gateway/sources/version3/mappings/collection.js delete mode 100644 services/gateway/sources/version3/mappings/profile.js delete mode 100644 services/gateway/sources/version3/profiles.js diff --git a/services/blockchain-connector/shared/sdk/constants/eventTopics.js b/services/blockchain-connector/shared/sdk/constants/eventTopics.js index b919c7ed1..39b3871a0 100644 --- a/services/blockchain-connector/shared/sdk/constants/eventTopics.js +++ b/services/blockchain-connector/shared/sdk/constants/eventTopics.js @@ -80,17 +80,9 @@ const { EVENT_NAME_SUBSCRIPTION_CREATED, EVENT_NAME_SUBSCRIPTION_PURCHASED, - MODULE_NAME_COLLECTION, - EVENT_NAME_COLLECTION_CREATED, - EVENT_NAME_COLLECTION_TRANSFERED, - MODULE_NAME_ANCHOR, EVENT_NAME_ANCHOR_CREATED, - EVENT_NAME_ANCHOR_STREAMED, - EVENT_NAME_ANCHOR_INCOME_RECLAIMED, - - MODULE_NAME_PROFILE, - EVENT_NAME_PROFILE_CREATED, + EVENT_NAME_ANCHOR_VOTED, } = require('./names'); const COMMAND_EXECUTION_RESULT_TOPICS = ['transactionID']; @@ -166,17 +158,9 @@ const EVENT_TOPIC_MAPPINGS_BY_MODULE = { [EVENT_NAME_SUBSCRIPTION_CREATED]: ['transactionID', 'senderAddress'], [EVENT_NAME_SUBSCRIPTION_PURCHASED]: ['transactionID', 'senderAddress'], }, - [MODULE_NAME_COLLECTION]: { - [EVENT_NAME_COLLECTION_CREATED]: ['transactionID', 'senderAddress'], - [EVENT_NAME_COLLECTION_TRANSFERED]: ['transactionID', 'senderAddress'], - }, [MODULE_NAME_ANCHOR]: { [EVENT_NAME_ANCHOR_CREATED]: ['transactionID', 'senderAddress'], - [EVENT_NAME_ANCHOR_STREAMED]: ['transactionID', 'senderAddress'], - [EVENT_NAME_ANCHOR_INCOME_RECLAIMED]: ['transactionID', 'senderAddress'], - }, - [MODULE_NAME_PROFILE]: { - [EVENT_NAME_PROFILE_CREATED]: ['transactionID', 'senderAddress'], + [EVENT_NAME_ANCHOR_VOTED]: ['transactionID', 'senderAddress'], }, }; diff --git a/services/blockchain-connector/shared/sdk/constants/names.js b/services/blockchain-connector/shared/sdk/constants/names.js index 00014971f..80faa715d 100644 --- a/services/blockchain-connector/shared/sdk/constants/names.js +++ b/services/blockchain-connector/shared/sdk/constants/names.js @@ -92,19 +92,11 @@ const MODULE_NAME_SUBSCRIPTION = 'subscription'; const EVENT_NAME_SUBSCRIPTION_CREATED = 'subscriptionCreated'; const EVENT_NAME_SUBSCRIPTION_PURCHASED = 'subscriptionPurchased'; -// Collection -const MODULE_NAME_COLLECTION = 'collection'; -const EVENT_NAME_COLLECTION_CREATED = 'collectionCreated'; -const EVENT_NAME_COLLECTION_TRANSFERED = 'collectionTransfered'; - // Anchors const MODULE_NAME_ANCHOR = 'anchor'; const EVENT_NAME_ANCHOR_CREATED = 'anchorCreated'; const EVENT_NAME_ANCHOR_VOTED = 'anchorVoted'; - -// Profiles -const MODULE_NAME_PROFILE = 'profile'; -const EVENT_NAME_PROFILE_CREATED = 'profileCreated'; +const EVENT_NAME_ANCHOR_DESTROYED = 'anchorDestroyed'; module.exports = { MODULE_NAME_AUTH, @@ -174,14 +166,8 @@ module.exports = { EVENT_NAME_SUBSCRIPTION_CREATED, EVENT_NAME_SUBSCRIPTION_PURCHASED, - MODULE_NAME_COLLECTION, - EVENT_NAME_COLLECTION_CREATED, - EVENT_NAME_COLLECTION_TRANSFERED, - MODULE_NAME_ANCHOR, EVENT_NAME_ANCHOR_CREATED, + EVENT_NAME_ANCHOR_DESTROYED, EVENT_NAME_ANCHOR_VOTED, - - MODULE_NAME_PROFILE, - EVENT_NAME_PROFILE_CREATED, }; diff --git a/services/blockchain-indexer/methods/dataService/controllers/collections.js b/services/blockchain-indexer/methods/dataService/controllers/collections.js deleted file mode 100644 index e34ddefa8..000000000 --- a/services/blockchain-indexer/methods/dataService/controllers/collections.js +++ /dev/null @@ -1,31 +0,0 @@ -const { - HTTP: { StatusCodes: { BAD_REQUEST } }, - Exceptions: { ValidationException, InvalidParamsException }, -} = require('lisk-service-framework'); - -const dataService = require('../../../shared/dataService'); - -const getCollections = async params => { - const collections = { - data: [], - meta: {}, - }; - - try { - const response = await dataService.getCollections(params); - if (response.data) collections.data = response.data; - if (response.meta) collections.meta = response.meta; - - return collections; - } catch (err) { - let status; - if (err instanceof InvalidParamsException) status = 'INVALID_PARAMS'; - if (err instanceof ValidationException) status = BAD_REQUEST; - if (status) return { status, data: { error: err.message } }; - throw err; - } -}; - -module.exports = { - getCollections, -}; diff --git a/services/blockchain-indexer/methods/dataService/controllers/profiles.js b/services/blockchain-indexer/methods/dataService/controllers/profiles.js deleted file mode 100644 index 512ea767a..000000000 --- a/services/blockchain-indexer/methods/dataService/controllers/profiles.js +++ /dev/null @@ -1,31 +0,0 @@ -const { - HTTP: { StatusCodes: { BAD_REQUEST } }, - Exceptions: { ValidationException, InvalidParamsException }, -} = require('lisk-service-framework'); - -const dataService = require('../../../shared/dataService'); - -const getProfiles = async params => { - const profiles = { - data: [], - meta: {}, - }; - - try { - const response = await dataService.getProfiles(params); - if (response.data) profiles.data = response.data; - if (response.meta) profiles.meta = response.meta; - - return profiles; - } catch (err) { - let status; - if (err instanceof InvalidParamsException) status = 'INVALID_PARAMS'; - if (err instanceof ValidationException) status = BAD_REQUEST; - if (status) return { status, data: { error: err.message } }; - throw err; - } -}; - -module.exports = { - getProfiles, -}; diff --git a/services/blockchain-indexer/methods/dataService/modules/collection.js b/services/blockchain-indexer/methods/dataService/modules/collection.js deleted file mode 100644 index 76fb7fa94..000000000 --- a/services/blockchain-indexer/methods/dataService/modules/collection.js +++ /dev/null @@ -1,16 +0,0 @@ -const { - getCollections, -} = require('../controllers/collections'); - -module.exports = [ - { - name: 'collections', - controller: getCollections, - params: { - creatorAddress: { optional: true, type: 'string' }, - collectionID: { optional: true, type: 'string' }, - limit: { optional: true, type: 'number' }, - offset: { optional: true, type: 'number' }, - }, - }, -]; diff --git a/services/blockchain-indexer/methods/dataService/modules/profile.js b/services/blockchain-indexer/methods/dataService/modules/profile.js deleted file mode 100644 index b09cf5875..000000000 --- a/services/blockchain-indexer/methods/dataService/modules/profile.js +++ /dev/null @@ -1,16 +0,0 @@ -const { - getProfiles, -} = require('../controllers/profiles'); - -module.exports = [ - { - name: 'profiles', - controller: getProfiles, - params: { - creatorAddress: { optional: true, type: 'string' }, - profileID: { optional: true, type: 'string' }, - limit: { optional: true, type: 'number' }, - offset: { optional: true, type: 'number' }, - }, - }, -]; diff --git a/services/blockchain-indexer/shared/dataService/business/anchors.js b/services/blockchain-indexer/shared/dataService/business/anchors.js index 579f66f2c..cf97a38b5 100644 --- a/services/blockchain-indexer/shared/dataService/business/anchors.js +++ b/services/blockchain-indexer/shared/dataService/business/anchors.js @@ -5,6 +5,7 @@ const BluebirdPromise = require('bluebird'); const transactionsIndexSchema = require('../../database/schema/anchors'); const imagesIndexSchema = require('../../database/schema/images'); +const votesIndexSchema = require('../../database/schema/votes'); const config = require('../../../config'); const MYSQL_ENDPOINT = config.endpoints.mysql; @@ -21,9 +22,16 @@ const getImagesIndex = () => getTableInstance( MYSQL_ENDPOINT, ); +const getVotesIndex = () => getTableInstance( + votesIndexSchema.tableName, + votesIndexSchema, + MYSQL_ENDPOINT, +); + const getAnchors = async (params = {}) => { const anchorsTable = await getAnchorsIndex(); const imagesTable = await getImagesIndex(); + const votesTable = await getVotesIndex(); if (params.search) { const { search, ...remParams } = params; @@ -35,36 +43,10 @@ const getAnchors = async (params = {}) => { }; } - let anchorData = []; - - if (params.submitter) { - // anchorsID - const anchorIDs = await imagesTable.find( - { address: params.submitter, limit: params.limit }, - ['anchorID', 'shares'], - ); - - const filteredAnchorIDs = anchorIDs.filter(anchor => anchor.shares > 0); - - anchorData = await BluebirdPromise.map( - filteredAnchorIDs, - async (anchorID) => { - const anchor = await anchorsTable.find( - { anchorID: anchorID.anchorID }, - ['anchorID', 'submitter', 'name', 'album', 'artists', 'spotifyId', 'appleMusicId'], - ); - - return anchor[0]; - }, - { concurrency: filteredAnchorIDs.length }, - ); - } else { - anchorData = await anchorsTable.find( - { ...params, limit: params.limit }, - ['anchorID', 'submitter', 'name', 'album', 'artists', 'spotifyId', 'appleMusicId'], - ); - } - + const anchorData = await anchorsTable.find( + { ...params, limit: params.limit }, + ['anchorID', 'name', 'album', 'artists', 'spotifyId', 'appleMusicId', 'createdAt', 'submitter'], + ); const total = anchorData.length; const data = await BluebirdPromise.map( @@ -72,12 +54,18 @@ const getAnchors = async (params = {}) => { async (anchor) => { const imagesData = await imagesTable.find( { anchorID: anchor.anchorID }, - ['address', 'shares', 'income'], + ['url', 'width', 'height'], + ); + + const votesData = await votesTable.find( + { anchorID: anchor.anchorID }, + ['senderAddress'], ); return { ...anchor, images: imagesData, + votes: votesData, }; }, { concurrency: anchorData.length }, diff --git a/services/blockchain-indexer/shared/dataService/business/collections.js b/services/blockchain-indexer/shared/dataService/business/collections.js deleted file mode 100644 index b6c2b4cc4..000000000 --- a/services/blockchain-indexer/shared/dataService/business/collections.js +++ /dev/null @@ -1,47 +0,0 @@ -const { - MySQL: { getTableInstance }, -} = require('lisk-service-framework'); -const transactionsIndexSchema = require('../../database/schema/collections'); -const config = require('../../../config'); - -const MYSQL_ENDPOINT = config.endpoints.mysql; - -const getCollectionsIndex = () => getTableInstance( - transactionsIndexSchema.tableName, - transactionsIndexSchema, - MYSQL_ENDPOINT, -); - -const getCollections = async (params = {}) => { - const collectionsTable = await getCollectionsIndex(); - - if (params.search) { - const { search, ...remParams } = params; - params = remParams; - - params.search = { - property: 'name', - pattern: search, - }; - } - - const total = await collectionsTable.count(params); - const resultSet = await collectionsTable.find( - { ...params, limit: params.limit || 10 }, - ['collectionID', 'creatorAddress', 'name', 'releaseYear', 'collectionType'], - ); - - const result = { - data: resultSet, - meta: { - count: resultSet.length, - offset: parseInt(params.offset, 10) || 0, - total, - }, - }; - return result; -}; - -module.exports = { - getCollections, -}; diff --git a/services/blockchain-indexer/shared/dataService/business/index.js b/services/blockchain-indexer/shared/dataService/business/index.js index 7a0ed7361..f58870681 100644 --- a/services/blockchain-indexer/shared/dataService/business/index.js +++ b/services/blockchain-indexer/shared/dataService/business/index.js @@ -109,9 +109,7 @@ const { setFeeEstimates, getFeeEstimates, initFeeEstimates } = require('./feeEst // Muzikie Dedicated Modules const { getSubscriptions } = require('./subscriptions'); -const { getCollections } = require('./collections'); const { getAnchors } = require('./anchors'); -const { getProfiles } = require('./profiles'); module.exports = { // Generators @@ -211,13 +209,8 @@ module.exports = { // subscriptions getSubscriptions, - // collections - getCollections, - // anchors getAnchors, - // profiles - getProfiles, invokeEndpoint, }; diff --git a/services/blockchain-indexer/shared/dataService/business/profiles.js b/services/blockchain-indexer/shared/dataService/business/profiles.js deleted file mode 100644 index 5305fa04c..000000000 --- a/services/blockchain-indexer/shared/dataService/business/profiles.js +++ /dev/null @@ -1,72 +0,0 @@ -const { - MySQL: { getTableInstance }, -} = require('lisk-service-framework'); -const BluebirdPromise = require('bluebird'); -const transactionsIndexSchema = require('../../database/schema/profiles'); -const socialAccountsIndexSchema = require('../../database/schema/socialAccounts'); -const config = require('../../../config'); - -const MYSQL_ENDPOINT = config.endpoints.mysql; - -const getProfilesIndex = () => getTableInstance( - transactionsIndexSchema.tableName, - transactionsIndexSchema, - MYSQL_ENDPOINT, -); - -const getSocialAccountsIndex = () => getTableInstance( - socialAccountsIndexSchema.tableName, - socialAccountsIndexSchema, - MYSQL_ENDPOINT, -); - -const getProfiles = async (params = {}) => { - const profilesTable = await getProfilesIndex(); - - if (params.search) { - const { search, ...remParams } = params; - params = remParams; - - params.search = { - property: 'name', - pattern: search, - }; - } - - const total = await profilesTable.count(params); - const profilesData = await profilesTable.find( - { ...params, limit: params.limit || 10 }, - ['profileID', 'name', 'nickName', 'description', 'creatorAddress', 'avatarHash', 'avatarSignature', 'bannerHash', 'bannerSignature'], - ); - const socialAccountsTable = await getSocialAccountsIndex(); - - const data = await BluebirdPromise.map( - profilesData, - async (profile) => { - const socialData = await socialAccountsTable.find( - { profileID: profile.profileID }, - ['profileID', 'username', 'platform'], - ); - - return { - ...profile, - socialAccounts: socialData, - }; - }, - { concurrency: profilesData.length }, - ); - - const result = { - data, - meta: { - count: data.length, - offset: parseInt(params.offset, 10) || 0, - total, - }, - }; - return result; -}; - -module.exports = { - getProfiles, -}; diff --git a/services/blockchain-indexer/shared/dataService/collections.js b/services/blockchain-indexer/shared/dataService/collections.js deleted file mode 100644 index 06c0380ca..000000000 --- a/services/blockchain-indexer/shared/dataService/collections.js +++ /dev/null @@ -1,22 +0,0 @@ -const { Logger } = require('lisk-service-framework'); -const util = require('util'); - -const logger = Logger(); - -const business = require('./business'); - -const getCollections = async params => { - // Store logs - if (params.collectionID) logger.debug(`Retrieved collection with ID ${params.collectionID} from Lisk Core`); - else if (params.creatorAddress) logger.debug(`Retrieved collection with creatorAddress: ${params.creatorAddress} from Lisk Core`); - else logger.debug(`Retrieved collections with custom search: ${util.inspect(params)} from Lisk Core`); - - // Get data from server - const response = await business.getCollections(params); - - return response; -}; - -module.exports = { - getCollections, -}; diff --git a/services/blockchain-indexer/shared/dataService/index.js b/services/blockchain-indexer/shared/dataService/index.js index 2ee8d7aaa..a4b3a8296 100644 --- a/services/blockchain-indexer/shared/dataService/index.js +++ b/services/blockchain-indexer/shared/dataService/index.js @@ -105,9 +105,7 @@ const { getLegacyAccountInfo } = require('./legacy'); const { getValidator, validateBLSKey } = require('./validator'); const { getGenerators } = require('./generators'); const { getSubscriptions } = require('./subscriptions'); -const { getCollections } = require('./collections'); const { getAnchors } = require('./anchors'); -const { getProfiles } = require('./profiles'); const { invokeEndpoint } = require('./invoke'); module.exports = { @@ -212,15 +210,9 @@ module.exports = { // Subscriptions getSubscriptions, - // Collections - getCollections, - // Anchors getAnchors, - // Profiles - getProfiles, - isMainchain, resolveMainchainServiceURL, diff --git a/services/blockchain-indexer/shared/dataService/profiles.js b/services/blockchain-indexer/shared/dataService/profiles.js deleted file mode 100644 index a6741da7a..000000000 --- a/services/blockchain-indexer/shared/dataService/profiles.js +++ /dev/null @@ -1,22 +0,0 @@ -const { Logger } = require('lisk-service-framework'); -const util = require('util'); - -const logger = Logger(); - -const business = require('./business'); - -const getProfiles = async params => { - // Store logs - if (params.profileID) logger.debug(`Retrieved profile with ID ${params.profileID} from Lisk Core`); - else if (params.creatorAddress) logger.debug(`Retrieved profile with creatorAddress: ${params.creatorAddress} from Lisk Core`); - else logger.debug(`Retrieved profile with custom search: ${util.inspect(params)} from Lisk Core`); - - // Get data from server - const response = await business.getProfiles(params); - - return response; -}; - -module.exports = { - getProfiles, -}; diff --git a/services/blockchain-indexer/shared/database/schema/anchors.js b/services/blockchain-indexer/shared/database/schema/anchors.js index 364b9628e..3abbc09c9 100644 --- a/services/blockchain-indexer/shared/database/schema/anchors.js +++ b/services/blockchain-indexer/shared/database/schema/anchors.js @@ -8,9 +8,12 @@ module.exports = { artists: { type: 'string' }, spotifyId: { type: 'string' }, appleMusicId: { type: 'string' }, + submitter: { type: 'string' }, + createdAt: { type: 'string' }, }, indexes: { - creatorAddress: { type: 'string' }, + submitter: { type: 'string' }, + anchorID: { type: 'string' }, }, purge: {}, }; diff --git a/services/blockchain-indexer/shared/database/schema/collections.js b/services/blockchain-indexer/shared/database/schema/collections.js deleted file mode 100644 index a4dfbd621..000000000 --- a/services/blockchain-indexer/shared/database/schema/collections.js +++ /dev/null @@ -1,17 +0,0 @@ -module.exports = { - tableName: 'collections', - primaryKey: 'collectionID', - schema: { - collectionID: { type: 'string', null: true, defaultValue: null }, - name: { type: 'string', null: true, defaultValue: null }, - releaseYear: { type: 'string', null: true, defaultValue: null }, - collectionType: { type: 'integer', null: true, defaultValue: null }, - coverSignature: { type: 'string', null: true, defaultValue: null }, - coverHash: { type: 'string', null: true, defaultValue: null }, - creatorAddress: { type: 'string', null: true, defaultValue: null }, - }, - indexes: { - creatorAddress: { type: 'string' }, - }, - purge: {}, -}; diff --git a/services/blockchain-indexer/shared/database/schema/profiles.js b/services/blockchain-indexer/shared/database/schema/profiles.js deleted file mode 100644 index 54acb4120..000000000 --- a/services/blockchain-indexer/shared/database/schema/profiles.js +++ /dev/null @@ -1,20 +0,0 @@ -module.exports = { - tableName: 'profiles', - primaryKey: 'profileID', - schema: { - profileID: { type: 'string' }, - name: { type: 'string', null: true, defaultValue: null }, - nickName: { type: 'string', null: true, defaultValue: null }, - description: { type: 'string', null: true, defaultValue: null }, - avatarHash: { type: 'string', null: true, defaultValue: null }, - avatarSignature: { type: 'string', null: true, defaultValue: null }, - bannerHash: { type: 'string', null: true, defaultValue: null }, - bannerSignature: { type: 'string', null: true, defaultValue: null }, - // @TODO: creationDate: { type: 'string', null: true, defaultValue: null }, - creatorAddress: { type: 'string', null: true, defaultValue: null }, - }, - indexes: { - creatorAddress: { type: 'string' }, - }, - purge: {}, -}; diff --git a/services/blockchain-indexer/shared/database/schema/socialAccounts.js b/services/blockchain-indexer/shared/database/schema/socialAccounts.js deleted file mode 100644 index c6d884724..000000000 --- a/services/blockchain-indexer/shared/database/schema/socialAccounts.js +++ /dev/null @@ -1,13 +0,0 @@ -module.exports = { - tableName: 'socialAccounts', - primaryKey: ['profileID', 'platform'], - schema: { - profileID: { type: 'string' }, - username: { type: 'string', null: true, defaultValue: null }, - platform: { type: 'string' }, - }, - indexes: { - profileID: { type: 'string' }, - }, - purge: {}, -}; diff --git a/services/blockchain-indexer/shared/database/schema/votes.js b/services/blockchain-indexer/shared/database/schema/votes.js new file mode 100644 index 000000000..e625678ce --- /dev/null +++ b/services/blockchain-indexer/shared/database/schema/votes.js @@ -0,0 +1,13 @@ +module.exports = { + tableName: 'votes', + primaryKey: ['anchorID', 'senderAddress'], + schema: { + anchorID: { type: 'string' }, + senderAddress: { type: 'string' }, + }, + indexes: { + anchorID: { type: 'string' }, + senderAddress: { type: 'string' }, + }, + purge: {}, +}; diff --git a/services/blockchain-indexer/shared/indexer/transactionProcessor/audio/create.js b/services/blockchain-indexer/shared/indexer/transactionProcessor/anchor/create.js similarity index 99% rename from services/blockchain-indexer/shared/indexer/transactionProcessor/audio/create.js rename to services/blockchain-indexer/shared/indexer/transactionProcessor/anchor/create.js index 846bab76f..7ed6c2d3b 100644 --- a/services/blockchain-indexer/shared/indexer/transactionProcessor/audio/create.js +++ b/services/blockchain-indexer/shared/indexer/transactionProcessor/anchor/create.js @@ -100,6 +100,7 @@ const applyTransaction = async (blockHeader, tx, events, dbTrx) => { const anchorsNFT = { ...anchorCreatedData, ...tx.params, + votes: [], }; await anchorsTable.upsert(anchorsNFT, dbTrx); diff --git a/services/blockchain-indexer/shared/indexer/transactionProcessor/audio/destroy.js b/services/blockchain-indexer/shared/indexer/transactionProcessor/anchor/destroy.js similarity index 100% rename from services/blockchain-indexer/shared/indexer/transactionProcessor/audio/destroy.js rename to services/blockchain-indexer/shared/indexer/transactionProcessor/anchor/destroy.js diff --git a/services/blockchain-indexer/shared/indexer/transactionProcessor/audio/index.js b/services/blockchain-indexer/shared/indexer/transactionProcessor/anchor/index.js similarity index 100% rename from services/blockchain-indexer/shared/indexer/transactionProcessor/audio/index.js rename to services/blockchain-indexer/shared/indexer/transactionProcessor/anchor/index.js diff --git a/services/blockchain-indexer/shared/indexer/transactionProcessor/audio/vote.js b/services/blockchain-indexer/shared/indexer/transactionProcessor/anchor/vote.js similarity index 53% rename from services/blockchain-indexer/shared/indexer/transactionProcessor/audio/vote.js rename to services/blockchain-indexer/shared/indexer/transactionProcessor/anchor/vote.js index 44a232bcf..d1c11bac2 100644 --- a/services/blockchain-indexer/shared/indexer/transactionProcessor/audio/vote.js +++ b/services/blockchain-indexer/shared/indexer/transactionProcessor/anchor/vote.js @@ -2,24 +2,23 @@ const { Logger, MySQL: { getTableInstance }, } = require('lisk-service-framework'); -const BluebirdPromise = require('bluebird'); const config = require('../../../../config'); +const { getLisk32AddressFromPublicKey } = require('../../../utils/account'); const logger = Logger(); const MYSQL_ENDPOINT = config.endpoints.mysql; -const imagesTableSchema = require('../../../database/schema/images'); +const votesTableSchema = require('../../../database/schema/votes'); const { MODULE_NAME_ANCHOR, - EVENT_NAME_ANCHOR_VOTED, EVENT_NAME_COMMAND_EXECUTION_RESULT, } = require('../../../../../blockchain-connector/shared/sdk/constants/names'); -const getImagesTable = () => getTableInstance( - imagesTableSchema.tableName, - imagesTableSchema, +const getVotesTable = () => getTableInstance( + votesTableSchema.tableName, + votesTableSchema, MYSQL_ENDPOINT, ); @@ -36,30 +35,19 @@ const applyTransaction = async (blockHeader, tx, events, dbTrx) => { return false; } - const imagesTable = await getImagesTable(); + const votesTable = await getVotesTable(); const { anchorID } = tx.params; - // Use event data to get anchorID - const { data: anchorVotedData = {} } = events.find( - ({ module, name }) => module === MODULE_NAME_ANCHOR - && name === EVENT_NAME_ANCHOR_VOTED, - ); + const senderAddress = getLisk32AddressFromPublicKey(tx.senderPublicKey); + const vote = { + senderAddress, + anchorID, + }; - await BluebirdPromise.map( - anchorVotedData.images, - async image => { - const info = { - ...image, - anchorID, - }; - logger.trace(`Updating image index for the account with address ${image.address}.`); - await imagesTable.upsert(info, dbTrx); - logger.debug(`Updated image index for the account with address ${image.address}.`); - return true; - }, - { concurrency: anchorVotedData.images.length }, - ); + logger.trace(`Indexing vote with anchor ID ${anchorID} and sender address ${senderAddress}.`); + await votesTable.upsert(vote, dbTrx); + logger.debug(`Indexed vote with transaction ID ${dbTrx.id}.`); return true; }; diff --git a/services/blockchain-indexer/shared/indexer/transactionProcessor/collection/create.js b/services/blockchain-indexer/shared/indexer/transactionProcessor/collection/create.js deleted file mode 100644 index 5f3accb95..000000000 --- a/services/blockchain-indexer/shared/indexer/transactionProcessor/collection/create.js +++ /dev/null @@ -1,100 +0,0 @@ -const { - Logger, - MySQL: { getTableInstance }, -} = require('lisk-service-framework'); - -const { getLisk32AddressFromPublicKey } = require('../../../utils/account'); - -const config = require('../../../../config'); - -const logger = Logger(); - -const MYSQL_ENDPOINT = config.endpoints.mysql; -const accountsTableSchema = require('../../../database/schema/accounts'); -const collectionsTableSchema = require('../../../database/schema/collections'); -const { - MODULE_NAME_COLLECTION, - EVENT_NAME_COLLECTION_CREATED, -} = require('../../../../../blockchain-connector/shared/sdk/constants/names'); - -const getAccountsTable = () => getTableInstance( - accountsTableSchema.tableName, - accountsTableSchema, - MYSQL_ENDPOINT, -); - -const getCollectionsTable = () => getTableInstance( - collectionsTableSchema.tableName, - collectionsTableSchema, - MYSQL_ENDPOINT, -); - -// Command specific constants -const COMMAND_NAME = 'create'; - -// eslint-disable-next-line no-unused-vars -const applyTransaction = async (blockHeader, tx, events, dbTrx) => { - const accountsTable = await getAccountsTable(); - const collectionsTable = await getCollectionsTable(); - - const senderAddress = getLisk32AddressFromPublicKey(tx.senderPublicKey); - - const account = { - address: senderAddress, - }; - - logger.trace(`Updating account index for the account with address ${account.address}.`); - await accountsTable.upsert(account, dbTrx); - logger.debug(`Updated account index for the account with address ${account.address}.`); - - logger.trace(`Indexing collections with address ${account.address}.`); - - const { data: eventData = {} } = events.find( - ({ module, name }) => module === MODULE_NAME_COLLECTION - && name === EVENT_NAME_COLLECTION_CREATED, - ); - - const collectionsNFT = { - ...eventData, - ...tx.params, - }; - - await collectionsTable.upsert(collectionsNFT, dbTrx); - logger.debug(`Indexed collection with ID ${eventData.collectionsID}.`); -}; - -// eslint-disable-next-line no-unused-vars -const revertTransaction = async (blockHeader, tx, events, dbTrx) => { - const accountsTable = await getAccountsTable(); - const collectionsTable = await getCollectionsTable(); - - const oldAccount = accountsTable.find( - { address: getLisk32AddressFromPublicKey(tx.senderPublicKey) }, - dbTrx, - ); - - // Remove the validator details from the table on transaction reversal - const account = { - address: getLisk32AddressFromPublicKey(tx.senderPublicKey), - publicKey: tx.senderPublicKey, - collections: { - owned: oldAccount.collections.owned.filter(id => id !== dbTrx.id), - shared: null, - }, - }; - - logger.trace(`Updating account index for the account with address ${account.address}.`); - await accountsTable.upsert(account, dbTrx); - logger.debug(`Updated account index for the account with address ${account.address}.`); - - logger.trace(`Remove collection entry for address ${account.address}.`); - const collectionPK = account[collectionsTableSchema.primaryKey]; - await collectionsTable.deleteByPrimaryKey(collectionPK, dbTrx); - logger.debug(`Removed collection entry for ID ${collectionPK}.`); -}; - -module.exports = { - COMMAND_NAME, - applyTransaction, - revertTransaction, -}; diff --git a/services/blockchain-indexer/shared/indexer/transactionProcessor/collection/destroy.js b/services/blockchain-indexer/shared/indexer/transactionProcessor/collection/destroy.js deleted file mode 100644 index e398fb407..000000000 --- a/services/blockchain-indexer/shared/indexer/transactionProcessor/collection/destroy.js +++ /dev/null @@ -1,39 +0,0 @@ -const { - Logger, - MySQL: { getTableInstance }, -} = require('lisk-service-framework'); - -const config = require('../../../../config'); - -const logger = Logger(); - -const MYSQL_ENDPOINT = config.endpoints.mysql; -const collectionsTableSchema = require('../../../database/schema/collections'); - -const getCollectionsTable = () => getTableInstance( - collectionsTableSchema.tableName, - collectionsTableSchema, - MYSQL_ENDPOINT, -); - -// Command specific constants -const COMMAND_NAME = 'destroy'; - -// eslint-disable-next-line no-unused-vars -const applyTransaction = async (blockHeader, tx, events, dbTrx) => { - const collectionsTable = await getCollectionsTable(); - const { collectionID } = tx.params; - - logger.trace(`Deleting collection with ID ${collectionID}.`); - await collectionsTable.delete({ collectionID }, dbTrx); - logger.debug(`Deleted collection with ID ${collectionID}.`); -}; - -// eslint-disable-next-line no-unused-vars -const revertTransaction = async (blockHeader, tx, events, dbTrx) => {}; - -module.exports = { - COMMAND_NAME, - applyTransaction, - revertTransaction, -}; diff --git a/services/blockchain-indexer/shared/indexer/transactionProcessor/collection/index.js b/services/blockchain-indexer/shared/indexer/transactionProcessor/collection/index.js deleted file mode 100644 index 0862e2581..000000000 --- a/services/blockchain-indexer/shared/indexer/transactionProcessor/collection/index.js +++ /dev/null @@ -1,6 +0,0 @@ -// Module specific constants -const MODULE_NAME = 'collection'; - -module.exports = { - MODULE_NAME, -}; diff --git a/services/blockchain-indexer/shared/indexer/transactionProcessor/collection/setAttributes.js b/services/blockchain-indexer/shared/indexer/transactionProcessor/collection/setAttributes.js deleted file mode 100644 index c55c74e71..000000000 --- a/services/blockchain-indexer/shared/indexer/transactionProcessor/collection/setAttributes.js +++ /dev/null @@ -1,46 +0,0 @@ -const { - Logger, - MySQL: { getTableInstance }, -} = require('lisk-service-framework'); - -const config = require('../../../../config'); - -const logger = Logger(); - -const MYSQL_ENDPOINT = config.endpoints.mysql; -const collectionsTableSchema = require('../../../database/schema/collections'); - -const getCollectionsTable = () => getTableInstance( - collectionsTableSchema.tableName, - collectionsTableSchema, - MYSQL_ENDPOINT, -); - -// Command specific constants -const COMMAND_NAME = 'setAttributes'; - -// eslint-disable-next-line no-unused-vars -const applyTransaction = async (blockHeader, tx, events, dbTrx) => { - const collectionsTable = await getCollectionsTable(); - const [collection] = await collectionsTable.find( - { collectionID: tx.params.collectionID }, - ['collectionID'], - ); - - if (typeof collection !== 'undefined') { - logger.trace(`Update collection with ID ${tx.params.collectionID}.`); - await collectionsTable.upsert(tx.params, dbTrx); - logger.debug(`Updated collection with ID ${tx.params.collectionID}.`); - } -}; - -// eslint-disable-next-line no-unused-vars -const revertTransaction = async (blockHeader, tx, events, dbTrx) => { - -}; - -module.exports = { - COMMAND_NAME, - applyTransaction, - revertTransaction, -}; diff --git a/services/blockchain-indexer/shared/indexer/transactionProcessor/collection/transfer.js b/services/blockchain-indexer/shared/indexer/transactionProcessor/collection/transfer.js deleted file mode 100644 index 70e5b533c..000000000 --- a/services/blockchain-indexer/shared/indexer/transactionProcessor/collection/transfer.js +++ /dev/null @@ -1,45 +0,0 @@ -const { - Logger, - MySQL: { getTableInstance }, -} = require('lisk-service-framework'); - -const config = require('../../../../config'); - -const logger = Logger(); - -const MYSQL_ENDPOINT = config.endpoints.mysql; -const collectionsTableSchema = require('../../../database/schema/collections'); - -const getCollectionsTable = () => getTableInstance( - collectionsTableSchema.tableName, - collectionsTableSchema, - MYSQL_ENDPOINT, -); - -// Command specific constants -const COMMAND_NAME = 'transfer'; - -// eslint-disable-next-line no-unused-vars -const applyTransaction = async (blockHeader, tx, events, dbTrx) => { - const collectionsTable = await getCollectionsTable(); - const [collectionNFT] = await collectionsTable.find( - { collectionID: tx.params.collectionID }, - ['collectionID', 'name', 'collectionType', 'releaseYear'], - dbTrx, - ); - - collectionNFT.creatorAddress = tx.params.address; - logger.trace(`Indexing collections with new address ${collectionNFT.creatorAddress}.`); - - await collectionsTable.upsert(collectionNFT, dbTrx); - logger.debug(`Indexed collection with ID ${collectionNFT.collectionsID}.`); -}; - -// eslint-disable-next-line no-unused-vars -const revertTransaction = async (blockHeader, tx, events, dbTrx) => {}; - -module.exports = { - COMMAND_NAME, - applyTransaction, - revertTransaction, -}; diff --git a/services/blockchain-indexer/shared/indexer/transactionProcessor/profile/create.js b/services/blockchain-indexer/shared/indexer/transactionProcessor/profile/create.js deleted file mode 100644 index cb4c3cb0c..000000000 --- a/services/blockchain-indexer/shared/indexer/transactionProcessor/profile/create.js +++ /dev/null @@ -1,97 +0,0 @@ -const { - Logger, - MySQL: { getTableInstance }, -} = require('lisk-service-framework'); -const BluebirdPromise = require('bluebird'); - -const { getLisk32AddressFromPublicKey } = require('../../../utils/account'); - -const config = require('../../../../config'); - -const logger = Logger(); - -const MYSQL_ENDPOINT = config.endpoints.mysql; -const accountsTableSchema = require('../../../database/schema/accounts'); -const profilesTableSchema = require('../../../database/schema/profiles'); -const socialAccountsTableSchema = require('../../../database/schema/socialAccounts'); - -const { - MODULE_NAME_PROFILE, - EVENT_NAME_PROFILE_CREATED, -} = require('../../../../../blockchain-connector/shared/sdk/constants/names'); - -const getAccountsTable = () => getTableInstance( - accountsTableSchema.tableName, - accountsTableSchema, - MYSQL_ENDPOINT, -); - -const getProfilesTable = () => getTableInstance( - profilesTableSchema.tableName, - profilesTableSchema, - MYSQL_ENDPOINT, -); - -const getSocialAccountsTable = () => getTableInstance( - socialAccountsTableSchema.tableName, - socialAccountsTableSchema, - MYSQL_ENDPOINT, -); - -// Command specific constants -const COMMAND_NAME = 'create'; - -// eslint-disable-next-line no-unused-vars -const applyTransaction = async (blockHeader, tx, events, dbTrx) => { - const accountsTable = await getAccountsTable(); - const profilesTable = await getProfilesTable(); - const socialAccountsTable = await getSocialAccountsTable(); - const senderAddress = getLisk32AddressFromPublicKey(tx.senderPublicKey); - - const account = { - address: senderAddress, - }; - - logger.trace(`Updating account index for the account with address ${account.address}.`); - await accountsTable.upsert(account, dbTrx); - logger.debug(`Updated account index for the account with address ${account.address}.`); - - logger.trace(`Indexing profiles with address ${account.address}.`); - - const { data: eventData = {} } = events.find( - ({ module, name }) => module === MODULE_NAME_PROFILE - && name === EVENT_NAME_PROFILE_CREATED, - ); - - const profile = { - ...eventData, - ...tx.params, - }; - - await BluebirdPromise.map( - tx.params.socialAccounts, - async socialAccount => { - const socialInfo = { - profileID: eventData.profileID, - ...socialAccount, - }; - logger.trace(`Inserting social accounts for the profile with ID ${eventData.profileID}.`); - await socialAccountsTable.upsert(socialInfo, dbTrx); - logger.debug(`Inserted social accounts for the profile with ID ${eventData.profileID}.`); - return true; - }, - { concurrency: tx.params.socialAccounts.length }, - ); - - await profilesTable.upsert(profile, dbTrx); - logger.debug(`Indexed profile with ID ${eventData.profileID}.`); -}; - -// eslint-disable-next-line no-unused-vars -const revertTransaction = async (blockHeader, tx, events, dbTrx) => {}; - -module.exports = { - COMMAND_NAME, - applyTransaction, - revertTransaction, -}; diff --git a/services/blockchain-indexer/shared/indexer/transactionProcessor/profile/index.js b/services/blockchain-indexer/shared/indexer/transactionProcessor/profile/index.js deleted file mode 100644 index 290c852a1..000000000 --- a/services/blockchain-indexer/shared/indexer/transactionProcessor/profile/index.js +++ /dev/null @@ -1,6 +0,0 @@ -// Module specific constants -const MODULE_NAME = 'profile'; - -module.exports = { - MODULE_NAME, -}; diff --git a/services/blockchain-indexer/shared/indexer/transactionProcessor/profile/setAttribute.js b/services/blockchain-indexer/shared/indexer/transactionProcessor/profile/setAttribute.js deleted file mode 100644 index dcfb8b44c..000000000 --- a/services/blockchain-indexer/shared/indexer/transactionProcessor/profile/setAttribute.js +++ /dev/null @@ -1,86 +0,0 @@ -const { - Logger, - MySQL: { getTableInstance }, -} = require('lisk-service-framework'); -const BluebirdPromise = require('bluebird'); -const config = require('../../../../config'); -const { getLisk32AddressFromPublicKey } = require('../../../utils/account'); - -const logger = Logger(); - -const MYSQL_ENDPOINT = config.endpoints.mysql; -const profilesTableSchema = require('../../../database/schema/profiles'); -const socialAccountsTableSchema = require('../../../database/schema/socialAccounts'); - -const getProfilesTable = () => getTableInstance( - profilesTableSchema.tableName, - profilesTableSchema, - MYSQL_ENDPOINT, -); -const getSocialAccountsTable = () => getTableInstance( - socialAccountsTableSchema.tableName, - socialAccountsTableSchema, - MYSQL_ENDPOINT, -); - -// Command specific constants -const COMMAND_NAME = 'setAttributes'; - -// eslint-disable-next-line no-unused-vars -const applyTransaction = async (blockHeader, tx, events, dbTrx) => { - const profilesTable = await getProfilesTable(); - const socialAccountsTable = await getSocialAccountsTable(); - const senderAddress = getLisk32AddressFromPublicKey(tx.senderPublicKey); - - const account = { - address: senderAddress, - }; - - logger.trace(`Indexing profiles with address ${account.address}.`); - const [existingProfile] = await profilesTable.find( - { profileID: tx.params.profileID }, - ['profileID', 'name', 'nickName', 'description', 'avatarHash', 'avatarSignature', 'bannerHash', 'bannerSignature', 'creatorAddress'], - dbTrx, - ); - if (!existingProfile) { - throw new Error(`Profile with ID ${tx.params.profileID} does not exist.`); - } - - const newProfile = { - ...tx.params, - profileID: existingProfile.profileID, - creatorAddress: existingProfile.creatorAddress, - }; - - // Delete existing social account records - await socialAccountsTable.delete({ profileID: existingProfile.profileID }, dbTrx); - - // Insert new social account records - await BluebirdPromise.map( - tx.params.socialAccounts, - async (socialAccount) => { - const socialInfo = { - profileID: existingProfile.profileID, - ...socialAccount, - }; - logger.trace(`Updating social accounts for the profile with ID ${existingProfile.profileID}.`); - await socialAccountsTable.upsert(socialInfo, dbTrx); - logger.debug(`Updating social accounts for the profile with ID ${existingProfile.profileID}.`); - return true; - }, - { concurrency: tx.params.socialAccounts.length }, - ); - - // Update the profile record - await profilesTable.upsert(newProfile, dbTrx); - logger.debug(`Updated profile with ID ${existingProfile.profileID}.`); -}; - -// eslint-disable-next-line no-unused-vars -const revertTransaction = async (blockHeader, tx, events, dbTrx) => {}; - -module.exports = { - COMMAND_NAME, - applyTransaction, - revertTransaction, -}; diff --git a/services/gateway/apis/http-version3/methods/collections.js b/services/gateway/apis/http-version3/methods/collections.js deleted file mode 100644 index 0d891e8a8..000000000 --- a/services/gateway/apis/http-version3/methods/collections.js +++ /dev/null @@ -1,39 +0,0 @@ -const collectionsSource = require('../../../sources/version3/collections'); -const envelope = require('../../../sources/version3/mappings/stdEnvelope'); -const regex = require('../../../shared/regex'); -const { transformParams, response, getSwaggerDescription } = require('../../../shared/utils'); - -module.exports = { - version: '2.0', - swaggerApiPath: '/collections', - rpcMethod: 'get.collections', - tags: ['Collections'], - params: { - creatorAddress: { optional: true, type: 'string', min: 3, max: 41, pattern: regex.ADDRESS_LISK32 }, - collectionID: { optional: true, type: 'string', min: 1, max: 64, pattern: regex.HASH_SHA256 }, - search: { optional: true, type: 'string' }, - }, - get schema() { - const collectionSchema = {}; - collectionSchema[this.swaggerApiPath] = { get: {} }; - collectionSchema[this.swaggerApiPath].get.tags = this.tags; - collectionSchema[this.swaggerApiPath].get.summary = 'Requests collections data'; - collectionSchema[this.swaggerApiPath].get.description = getSwaggerDescription({ - rpcMethod: this.rpcMethod, - description: 'Returns collections data', - }); - collectionSchema[this.swaggerApiPath].get.parameters = transformParams('collections', this.params); - collectionSchema[this.swaggerApiPath].get.responses = { - 200: { - description: 'Returns a list of collections', - schema: { - $ref: '#/definitions/collectionsWithEnvelope', - }, - }, - }; - Object.assign(collectionSchema[this.swaggerApiPath].get.responses, response); - return collectionSchema; - }, - source: collectionsSource, - envelope, -}; diff --git a/services/gateway/apis/http-version3/methods/profiles.js b/services/gateway/apis/http-version3/methods/profiles.js deleted file mode 100644 index c9662c236..000000000 --- a/services/gateway/apis/http-version3/methods/profiles.js +++ /dev/null @@ -1,39 +0,0 @@ -const profilesSource = require('../../../sources/version3/profiles'); -const envelope = require('../../../sources/version3/mappings/stdEnvelope'); -const regex = require('../../../shared/regex'); -const { transformParams, response, getSwaggerDescription } = require('../../../shared/utils'); - -module.exports = { - version: '2.0', - swaggerApiPath: '/profiles', - rpcMethod: 'get.profiles', - tags: ['Profiles'], - params: { - creatorAddress: { optional: true, type: 'string', min: 3, max: 41, pattern: regex.ADDRESS_LISK32 }, - profileID: { optional: true, type: 'string', min: 1, max: 64, pattern: regex.HASH_SHA256 }, - search: { optional: true, type: 'string' }, - }, - get schema() { - const profileSchema = {}; - profileSchema[this.swaggerApiPath] = { get: {} }; - profileSchema[this.swaggerApiPath].get.tags = this.tags; - profileSchema[this.swaggerApiPath].get.summary = 'Requests profiles data'; - profileSchema[this.swaggerApiPath].get.description = getSwaggerDescription({ - rpcMethod: this.rpcMethod, - description: 'Returns profiles data', - }); - profileSchema[this.swaggerApiPath].get.parameters = transformParams('profiles', this.params); - profileSchema[this.swaggerApiPath].get.responses = { - 200: { - description: 'Returns a list of profiles', - schema: { - $ref: '#/definitions/profilesWithEnvelope', - }, - }, - }; - Object.assign(profileSchema[this.swaggerApiPath].get.responses, response); - return profileSchema; - }, - source: profilesSource, - envelope, -}; diff --git a/services/gateway/apis/http-version3/swagger/apiJson.json b/services/gateway/apis/http-version3/swagger/apiJson.json index b7e505b4d..7a5980a31 100644 --- a/services/gateway/apis/http-version3/swagger/apiJson.json +++ b/services/gateway/apis/http-version3/swagger/apiJson.json @@ -91,17 +91,9 @@ "name": "Subscription", "description": "Subscription module related API calls." }, - { - "name": "Collection", - "description": "Collection module related API calls." - }, { "name": "Anchor", "description": "Anchor module related API calls." - }, - { - "name": "Profile", - "description": "Profile module related API calls." } ], "schemes": [ diff --git a/services/gateway/apis/http-version3/swagger/definitions/anchors.json b/services/gateway/apis/http-version3/swagger/definitions/anchors.json index 94af8b581..725f32133 100644 --- a/services/gateway/apis/http-version3/swagger/definitions/anchors.json +++ b/services/gateway/apis/http-version3/swagger/definitions/anchors.json @@ -4,10 +4,13 @@ "required": [ "anchorID", "name", - "releaseYear", - "collectionID", - "creatorAddress", - "feat" + "album", + "artists", + "submitter", + "images", + "createdAt", + "spotifyId", + "appleMusicId" ], "properties": { "anchorID": { @@ -22,19 +25,27 @@ "type": "string", "description": "name of the anchor" }, - "releaseYear": { + "album": { "type": "string", - "example": "2023" + "description": "name of the album" }, - "collectionID": { + "artists": { "type": "string", - "format": "id", - "example": "f9593f101c4acafc3ede650ab4c10fa2ecb59b225813eddbbb17b47e96932e9b", - "minLength": 1, - "maxLength": 64, - "description": "Unique identifier of the collection to which the current anchor belongs." + "description": "The artists of the song" + }, + "spotifyId": { + "type": "string", + "description": "The id of the anchor on spotify" }, - "creatorAddress": { + "appleMusicId": { + "type": "string", + "description": "The id of the anchor on Apple Music" + }, + "createdAt": { + "type": "string", + "description": "Creation date in YYYY-MM-DD format" + }, + "submitter": { "type": "object", "properties": { "address": { @@ -56,29 +67,49 @@ } } }, - "feat": { - "type": "object", - "required": [ - "address", - "name", - "role" - ], - "properties": { - "address": { + "images": { + "type": "array", + "items": { + "type": "object", + "required": [ + "url", + "width", + "height" + ], + "properties": { + "url": { + "type": "string", + "example": "http://image.url.com", + "description": "URL of the image asset." + }, + "width": { + "type": "number", + "example": "64", + "description": "Width of the image in pixels." + }, + "height": { + "type": "number", + "example": "64", + "description": "Height of the image in pixels." + } + } + } + }, + "votes": { + "type": "array", + "items": { + "type": "object", + "required": [ + "senderAddress" + ], + "properties": { + "senderAddress": { "type": "string", + "format": "address", "example": "lskdwsyfmcko6mcd357446yatromr9vzgu7eb8y99", - "description": "Address of the block generator." - }, - "name": { - "type": "string", - "example": "genesis_3", - "description": "Name of the block generator." - }, - "role": { - "type": "string", - "example": "guitarist", - "description": "Role of the artist in creation of the anchor." - } + "description": "The Lisk Address is the human-readable representation of a blockchain account.\nIt is 41 character long identifier that begins with `lsk`." + } + } } } } diff --git a/services/gateway/apis/http-version3/swagger/definitions/collections.json b/services/gateway/apis/http-version3/swagger/definitions/collections.json deleted file mode 100644 index b0cf3e85d..000000000 --- a/services/gateway/apis/http-version3/swagger/definitions/collections.json +++ /dev/null @@ -1,88 +0,0 @@ -{ - "collection": { - "type": "object", - "required": [ - "collectionID", - "releaseYear", - "name", - "collectionType", - "creatorAddress" - ], - "properties": { - "collectionID": { - "type": "string", - "format": "id", - "example": "f9593f101c4acafc3ede650ab4c10fa2ecb59b225813eddbbb17b47e96932e9b", - "minLength": 1, - "maxLength": 64, - "description": "Unique identifier of the collection.\nDerived from the collection hash." - }, - "releaseYear": { - "type": "string", - "example": "2023" - }, - "name": { - "type": "string", - "description": "name of the collection" - }, - "collectionType": { - "type": "integer", - "example": "1" - }, - "creatorAddress": { - "type": "object", - "properties": { - "address": { - "type": "string", - "format": "address", - "example": "lskdwsyfmcko6mcd357446yatromr9vzgu7eb8y99", - "description": "The Lisk Address is the human-readable representation of a blockchain account.\nIt is 41 character long identifier that begins with `lsk`." - }, - "publicKey": { - "type": "string", - "format": "publicKey", - "example": "b1d6bc6c7edd0673f5fed0681b73de6eb70539c21278b300f07ade277e1962cd", - "description": "The public key is derived from the private key of the owner of the account.\nIt can be used to validate that the private key belongs to the owner, but not provide access to the owner's private key." - }, - "name": { - "type": "string", - "example": "genesis_84", - "description": "Delegate name" - } - } - } - } - }, - "CollectionsWithEnvelope": { - "type": "object", - "required": [ - "data", - "meta" - ], - "properties": { - "data": { - "description": "List of collections", - "type": "array", - "items": { - "$ref": "#/definitions/Collections" - } - }, - "meta": { - "$ref": "#/definitions/pagination" - } - } - }, - "serverErrorEnvelope": { - "type": "object", - "properties": { - "error": { - "type": "boolean", - "example": true - }, - "message": { - "type": "string", - "example": "Unable to reach a network node" - } - } - } -} diff --git a/services/gateway/apis/http-version3/swagger/definitions/profiles.json b/services/gateway/apis/http-version3/swagger/definitions/profiles.json deleted file mode 100644 index 3bba369c2..000000000 --- a/services/gateway/apis/http-version3/swagger/definitions/profiles.json +++ /dev/null @@ -1,107 +0,0 @@ -{ - "profile": { - "type": "object", - "required": [ - "profileID", - "name", - "nickName", - "description", - "socialAccounts", - "avatarHash", - "avatarSignature", - "bannerHash", - "bannerSignature", - "creatorAddress" - ], - "properties": { - "profileID": { - "type": "string", - "format": "id", - "example": "f9593f101c4acafc3ede650ab4c10fa2ecb59b225813eddbbb17b47e96932e9b", - "minLength": 1, - "maxLength": 64, - "description": "Unique identifier of the profile.\nDerived from the profile hash." - }, - "name": { - "type": "string", - "description": "name of the profile" - }, - "nickName": { - "type": "string", - "description": "nickName of the profile" - }, - "description": { - "type": "string", - "description": "description of the profile" - }, - "socialAccounts": { - "type": "array", - "items": { - "type": "object", - "properties": { - "username": { - "type": "string", - "description": "username of the social media platform" - }, - "platform": { - "type": "string", - "description": "name of the social media platform" - } - } - } - }, - "avatarHash": { - "type": "string", - "example": "hash of the profile avatar" - }, - "avatarSignature": { - "type": "string", - "example": "signature of the profile avatar" - }, - "bannerHash": { - "type": "string", - "example": "hash of the profile banner" - }, - "bannerSignature": { - "type": "string", - "example": "signature of the profile banner" - }, - "creatorAddress": { - "type": "string", - "example": "creator address of the profile" - } - } - }, - "ProfilesWithEnvelope": { - "type": "object", - "required": [ - "data", - "meta" - ], - "properties": { - "data": { - "description": "List of profiles", - "type": "array", - "items": { - "$ref": "#/definitions/Profiles" - } - }, - "meta": { - "$ref": "#/definitions/pagination" - } - } - }, - "serverErrorEnvelope": { - "type": "object", - "properties": { - "error": { - "type": "boolean", - "example": true - }, - "message": { - "type": "string", - "example": "Unable to reach a network node" - } - } - } -} diff --git a/services/gateway/apis/http-version3/swagger/parameters/collections.json b/services/gateway/apis/http-version3/swagger/parameters/collections.json deleted file mode 100644 index 3c80f4c56..000000000 --- a/services/gateway/apis/http-version3/swagger/parameters/collections.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "creatorAddress": { - "name": "creatorAddress", - "in": "query", - "description": "Lisk account address", - "type": "string", - "minLength": 3, - "maxLength": 41 - }, - "collectionID": { - "name": "collectionID", - "in": "query", - "description": "collection ID to query", - "type": "string", - "format": "id", - "minLength": 1, - "maxLength": 64 - } -} diff --git a/services/gateway/apis/http-version3/swagger/parameters/profiles.json b/services/gateway/apis/http-version3/swagger/parameters/profiles.json deleted file mode 100644 index 488a2795c..000000000 --- a/services/gateway/apis/http-version3/swagger/parameters/profiles.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "creatorAddress": { - "name": "creatorAddress", - "in": "query", - "description": "Lisk account address", - "type": "string", - "minLength": 3, - "maxLength": 41 - }, - "profileID": { - "name": "profileID", - "in": "query", - "description": "profile ID to query", - "type": "string", - "format": "id", - "minLength": 1, - "maxLength": 64 - } -} diff --git a/services/gateway/sources/version3/anchors.js b/services/gateway/sources/version3/anchors.js index 8ec387010..c142f735c 100644 --- a/services/gateway/sources/version3/anchors.js +++ b/services/gateway/sources/version3/anchors.js @@ -13,6 +13,9 @@ module.exports = { width: '=,number', height: '=,number', }], + votes: ['votes', { + senderAddress: '=,string', + }], search: '=,string', limit: '=,number', offset: '=,number', diff --git a/services/gateway/sources/version3/collections.js b/services/gateway/sources/version3/collections.js deleted file mode 100644 index fdedfc839..000000000 --- a/services/gateway/sources/version3/collections.js +++ /dev/null @@ -1,31 +0,0 @@ -const collection = require('./mappings/collection'); - -module.exports = { - type: 'moleculer', - method: 'indexer.collections', - params: { - name: '=,string', - collectionID: '=,string', - creatorAddress: '=,string', - releaseYear: '=,string', - collectionType: '=,number', - // anchors: ['anchors', { - // anchorID: '=,string', - // name: '=,number', - // }], - search: '=,string', - limit: '=,number', - offset: '=,number', - sort: '=,string', - order: '=,string', - }, - definition: { - data: ['data', collection], - meta: { - count: '=,number', - offset: '=,number', - total: '=,number', - }, - links: {}, - }, -}; diff --git a/services/gateway/sources/version3/mappings/anchor.js b/services/gateway/sources/version3/mappings/anchor.js index f816004c8..e67b77c14 100644 --- a/services/gateway/sources/version3/mappings/anchor.js +++ b/services/gateway/sources/version3/mappings/anchor.js @@ -1,12 +1,16 @@ module.exports = { + anchorID: '=,string', name: '=,string', album: '=,string', - anchorID: '=,string', artists: '=,string', submitter: '=,string', + createdAt: '=,string', images: ['images', { url: '=,string', width: '=,number', height: '=,number', }], + votes: ['votes', { + senderAddress: '=,string', + }], }; diff --git a/services/gateway/sources/version3/mappings/collection.js b/services/gateway/sources/version3/mappings/collection.js deleted file mode 100644 index f444757b8..000000000 --- a/services/gateway/sources/version3/mappings/collection.js +++ /dev/null @@ -1,22 +0,0 @@ -/* - * LiskHQ/lisk-service - * Copyright © 2022 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 = { - name: '=,string', - collectionID: '=,string', - creatorAddress: '=,string', - collectionType: '=,number', - releaseYear: '=,string', -}; diff --git a/services/gateway/sources/version3/mappings/profile.js b/services/gateway/sources/version3/mappings/profile.js deleted file mode 100644 index f17e9927a..000000000 --- a/services/gateway/sources/version3/mappings/profile.js +++ /dev/null @@ -1,16 +0,0 @@ -module.exports = { - name: '=,string', - nickName: '=,string', - profileID: '=,string', - description: '=,string', - socialAccounts: ['socialAccounts', { - username: '=,string', - platform: '=,number', - }], - avatarHash: '=,string', - avatarSignature: '=,string', - bannerHash: '=,string', - bannerSignature: '=,string', - creatorAddress: '=,string', -}; - diff --git a/services/gateway/sources/version3/profiles.js b/services/gateway/sources/version3/profiles.js deleted file mode 100644 index a2ea5e556..000000000 --- a/services/gateway/sources/version3/profiles.js +++ /dev/null @@ -1,31 +0,0 @@ -const profile = require('./mappings/profile'); - -module.exports = { - type: 'moleculer', - method: 'indexer.profiles', - params: { - profileID: '=,string', - name: '=,string', - nickName: '=,string', - description: '=,string', - socialAccounts: ['socialAccounts', { - username: '=,string', - platform: '=,number', - }], - avatarHash: '=,string', - avatarSignature: '=,string', - bannerHash: '=,string', - bannerSignature: '=,string', - creatorAddress: '=,string', - search: '=,string', - }, - definition: { - data: ['data', profile], - meta: { - count: '=,number', - offset: '=,number', - total: '=,number', - }, - links: {}, - }, -}; diff --git a/services/gateway/tests/constants/generateDocs.js b/services/gateway/tests/constants/generateDocs.js index 6e791bfa5..c7dcd7c65 100644 --- a/services/gateway/tests/constants/generateDocs.js +++ b/services/gateway/tests/constants/generateDocs.js @@ -450,40 +450,6 @@ const createApiDocsExpectedResponse = { }, }, }, - '/collections': { - get: { - description: 'Returns collections data\n RPC => get.collections', - parameters: [ - { - $ref: '#/parameters/creatorAddress', - }, - { - $ref: '#/parameters/collectionID', - }, - { - $ref: '#/parameters/search', - }, - ], - responses: { - 200: { - description: 'Returns a list of collections', - schema: { - $ref: '#/definitions/collectionsWithEnvelope', - }, - }, - 400: { - description: 'Bad request', - schema: { - $ref: '#/definitions/badRequest', - }, - }, - }, - summary: 'Requests collections data', - tags: [ - 'Collections', - ], - }, - }, '/events': { get: { tags: [ @@ -995,40 +961,6 @@ const createApiDocsExpectedResponse = { }, }, }, - '/profiles': { - get: { - description: 'Returns profiles data\n RPC => get.profiles', - parameters: [ - { - $ref: '#/parameters/creatorAddress', - }, - { - $ref: '#/parameters/profileID', - }, - { - $ref: '#/parameters/search', - }, - ], - responses: { - 200: { - description: 'Returns a list of profiles', - schema: { - $ref: '#/definitions/profilesWithEnvelope', - }, - }, - 400: { - description: 'Bad request', - schema: { - $ref: '#/definitions/badRequest', - }, - }, - }, - summary: 'Requests profiles data', - tags: [ - 'Profiles', - ], - }, - }, '/transactions/estimate-fees': { post: { description: 'Returns estimated fees for the transaction.\n RPC => post.transactions.estimate-fees', diff --git a/services/gateway/tests/constants/registerApi.js b/services/gateway/tests/constants/registerApi.js index 22825ff88..3d395eb34 100644 --- a/services/gateway/tests/constants/registerApi.js +++ b/services/gateway/tests/constants/registerApi.js @@ -26,7 +26,6 @@ const expectedResponseForRegisterHttpApi = [ 'app-registry.blockchain.apps.meta.tokens', 'app-registry.blockchain.apps.meta.tokens.supported', 'indexer.blocks', - 'indexer.collections', 'indexer.events', 'fees.estimates', 'indexer.generators', @@ -37,7 +36,6 @@ const expectedResponseForRegisterHttpApi = [ 'indexer.network.statistics', 'indexer.network.status', 'indexer.transactions.post', - 'indexer.profiles', 'indexer.schemas', 'gateway.spec', 'indexer.subscriptions', @@ -65,8 +63,6 @@ const expectedResponseForRegisterHttpApi = [ ], aliases: { 'GET blocks/assets': 'indexer.blocks.assets', - 'GET collections': 'indexer.collections', - 'GET profiles': 'indexer.profiles', 'GET anchors': 'indexer.anchors', 'GET blockchain/apps': 'indexer.blockchain.apps', 'GET blockchain/apps/meta/list': 'app-registry.blockchain.apps.meta.list', @@ -139,7 +135,6 @@ const expectedResponseForRegisterRpcApi = { 'app-registry.blockchain.apps.meta.tokens', 'app-registry.blockchain.apps.meta.tokens.supported', 'indexer.blocks', - 'indexer.collections', 'indexer.events', 'fees.estimates', 'indexer.generators', @@ -150,7 +145,6 @@ const expectedResponseForRegisterRpcApi = { 'indexer.network.statistics', 'indexer.network.status', 'indexer.transactions.post', - 'indexer.profiles', 'indexer.schemas', 'indexer.subscriptions', 'indexer.transactions', @@ -177,7 +171,6 @@ const expectedResponseForRegisterRpcApi = { ], aliases: { 'get.blocks.assets': 'indexer.blocks.assets', - 'get.collections': 'indexer.collections', 'get.anchors': 'indexer.anchors', 'get.blockchain.apps': 'indexer.blockchain.apps', 'get.blockchain.apps.meta.list': 'app-registry.blockchain.apps.meta.list', @@ -195,7 +188,6 @@ const expectedResponseForRegisterRpcApi = { 'get.network.peers': 'indexer.network.peers', 'get.network.statistics': 'indexer.network.statistics', 'get.network.status': 'indexer.network.status', - 'get.profiles': 'indexer.profiles', 'post.transactions': 'indexer.transactions.post', 'get.schemas': 'indexer.schemas', 'get.subscriptions': 'indexer.subscriptions', From 1261446222d90597d594da35f77c95bb7c678986 Mon Sep 17 00:00:00 2001 From: reyraa Date: Thu, 19 Oct 2023 16:55:56 +0200 Subject: [PATCH 03/10] Add support for the badge module --- .../shared/sdk/constants/eventTopics.js | 12 +- .../shared/sdk/constants/names.js | 14 +-- .../tests/functional/formatter.test.js | 2 +- .../{subscriptions.js => badges.js} | 14 +-- .../methods/dataService/modules/badge.js | 19 +++ .../dataService/modules/subscription.js | 17 --- .../shared/dataService/badges.js | 23 ++++ .../shared/dataService/business/anchors.js | 2 +- .../shared/dataService/business/badges.js | 38 ++++++ .../shared/dataService/business/index.js | 6 +- .../dataService/business/subscriptions.js | 111 ------------------ .../shared/dataService/index.js | 6 +- .../shared/dataService/subscriptions.js | 23 ---- .../shared/database/schema/badges.js | 18 +++ .../shared/database/schema/members.js | 15 --- .../shared/database/schema/subscriptions.js | 16 --- .../transactionProcessor/badge/claim.js | 74 ++++++++++++ .../transactionProcessor/badge/create.js | 64 ++++++++++ .../{subscription => badge}/index.js | 2 +- .../subscription/create.js | 72 ------------ .../subscription/purchase.js | 111 ------------------ .../subscription/updateMembers.js | 105 ----------------- .../apis/http-version3/methods/badges.js | 56 +++++++++ .../http-version3/methods/subscriptions.js | 55 --------- .../apis/http-version3/swagger/apiJson.json | 4 +- .../{subscriptions.json => badges.json} | 72 +++++++----- .../swagger/parameters/badges.json | 28 +++++ .../swagger/parameters/subscriptions.json | 19 --- .../version3/{subscriptions.js => badges.js} | 25 ++-- .../mappings/{subscription.js => badge.js} | 19 ++- .../gateway/tests/constants/generateDocs.js | 21 ++-- .../gateway/tests/constants/registerApi.js | 8 +- 32 files changed, 426 insertions(+), 645 deletions(-) rename services/blockchain-indexer/methods/dataService/controllers/{subscriptions.js => badges.js} (64%) create mode 100644 services/blockchain-indexer/methods/dataService/modules/badge.js delete mode 100644 services/blockchain-indexer/methods/dataService/modules/subscription.js create mode 100644 services/blockchain-indexer/shared/dataService/badges.js create mode 100644 services/blockchain-indexer/shared/dataService/business/badges.js delete mode 100644 services/blockchain-indexer/shared/dataService/business/subscriptions.js delete mode 100644 services/blockchain-indexer/shared/dataService/subscriptions.js create mode 100644 services/blockchain-indexer/shared/database/schema/badges.js delete mode 100644 services/blockchain-indexer/shared/database/schema/members.js delete mode 100644 services/blockchain-indexer/shared/database/schema/subscriptions.js create mode 100644 services/blockchain-indexer/shared/indexer/transactionProcessor/badge/claim.js create mode 100644 services/blockchain-indexer/shared/indexer/transactionProcessor/badge/create.js rename services/blockchain-indexer/shared/indexer/transactionProcessor/{subscription => badge}/index.js (64%) delete mode 100644 services/blockchain-indexer/shared/indexer/transactionProcessor/subscription/create.js delete mode 100644 services/blockchain-indexer/shared/indexer/transactionProcessor/subscription/purchase.js delete mode 100644 services/blockchain-indexer/shared/indexer/transactionProcessor/subscription/updateMembers.js create mode 100644 services/gateway/apis/http-version3/methods/badges.js delete mode 100644 services/gateway/apis/http-version3/methods/subscriptions.js rename services/gateway/apis/http-version3/swagger/definitions/{subscriptions.json => badges.json} (68%) create mode 100644 services/gateway/apis/http-version3/swagger/parameters/badges.json delete mode 100644 services/gateway/apis/http-version3/swagger/parameters/subscriptions.json rename services/gateway/sources/version3/{subscriptions.js => badges.js} (66%) rename services/gateway/sources/version3/mappings/{subscription.js => badge.js} (67%) diff --git a/services/blockchain-connector/shared/sdk/constants/eventTopics.js b/services/blockchain-connector/shared/sdk/constants/eventTopics.js index 39b3871a0..116101ca7 100644 --- a/services/blockchain-connector/shared/sdk/constants/eventTopics.js +++ b/services/blockchain-connector/shared/sdk/constants/eventTopics.js @@ -76,9 +76,9 @@ const { EVENT_NAME_ACCOUNT_RECLAIMED, EVENT_NAME_KEYS_REGISTERED, - MODULE_NAME_SUBSCRIPTION, - EVENT_NAME_SUBSCRIPTION_CREATED, - EVENT_NAME_SUBSCRIPTION_PURCHASED, + MODULE_NAME_BADGE, + EVENT_NAME_BADGE_CREATED, + EVENT_NAME_BADGE_CLAIMED, MODULE_NAME_ANCHOR, EVENT_NAME_ANCHOR_CREATED, @@ -154,9 +154,9 @@ const EVENT_TOPIC_MAPPINGS_BY_MODULE = { [EVENT_NAME_ACCOUNT_RECLAIMED]: ['transactionID', 'legacyAddress', 'newAddress'], [EVENT_NAME_KEYS_REGISTERED]: ['transactionID', 'validatorAddress', 'generatorKey', 'blsKey'], }, - [MODULE_NAME_SUBSCRIPTION]: { - [EVENT_NAME_SUBSCRIPTION_CREATED]: ['transactionID', 'senderAddress'], - [EVENT_NAME_SUBSCRIPTION_PURCHASED]: ['transactionID', 'senderAddress'], + [MODULE_NAME_BADGE]: { + [EVENT_NAME_BADGE_CREATED]: ['transactionID', 'senderAddress'], + [EVENT_NAME_BADGE_CLAIMED]: ['transactionID', 'senderAddress'], }, [MODULE_NAME_ANCHOR]: { [EVENT_NAME_ANCHOR_CREATED]: ['transactionID', 'senderAddress'], diff --git a/services/blockchain-connector/shared/sdk/constants/names.js b/services/blockchain-connector/shared/sdk/constants/names.js index 80faa715d..c0b515be4 100644 --- a/services/blockchain-connector/shared/sdk/constants/names.js +++ b/services/blockchain-connector/shared/sdk/constants/names.js @@ -87,10 +87,10 @@ const MODULE_NAME_LEGACY = 'legacy'; const EVENT_NAME_ACCOUNT_RECLAIMED = 'accountReclaimed'; const EVENT_NAME_KEYS_REGISTERED = 'keysRegistered'; -// Subscription -const MODULE_NAME_SUBSCRIPTION = 'subscription'; -const EVENT_NAME_SUBSCRIPTION_CREATED = 'subscriptionCreated'; -const EVENT_NAME_SUBSCRIPTION_PURCHASED = 'subscriptionPurchased'; +// Badges +const MODULE_NAME_BADGE = 'badge'; +const EVENT_NAME_BADGE_CREATED = 'badgeCreated'; +const EVENT_NAME_BADGE_CLAIMED = 'badgeClaimed'; // Anchors const MODULE_NAME_ANCHOR = 'anchor'; @@ -162,9 +162,9 @@ module.exports = { EVENT_NAME_ACCOUNT_RECLAIMED, EVENT_NAME_KEYS_REGISTERED, - MODULE_NAME_SUBSCRIPTION, - EVENT_NAME_SUBSCRIPTION_CREATED, - EVENT_NAME_SUBSCRIPTION_PURCHASED, + MODULE_NAME_BADGE, + EVENT_NAME_BADGE_CREATED, + EVENT_NAME_BADGE_CLAIMED, MODULE_NAME_ANCHOR, EVENT_NAME_ANCHOR_CREATED, diff --git a/services/blockchain-connector/tests/functional/formatter.test.js b/services/blockchain-connector/tests/functional/formatter.test.js index ec5135dac..8b758c823 100644 --- a/services/blockchain-connector/tests/functional/formatter.test.js +++ b/services/blockchain-connector/tests/functional/formatter.test.js @@ -84,7 +84,7 @@ xdescribe('Functional tests for formatter', () => { expect(result).toMatchObject(decodedBlockWithoutTransaction); }); - it('format subscription event payload', async () => { + it('format badge event payload', async () => { const result = await broker.call('connector.formatAPIClientEventPayload', { eventName: 'app_newBlock', payload: { block: blockWithTransaction }, diff --git a/services/blockchain-indexer/methods/dataService/controllers/subscriptions.js b/services/blockchain-indexer/methods/dataService/controllers/badges.js similarity index 64% rename from services/blockchain-indexer/methods/dataService/controllers/subscriptions.js rename to services/blockchain-indexer/methods/dataService/controllers/badges.js index 8c33085b5..60b090714 100644 --- a/services/blockchain-indexer/methods/dataService/controllers/subscriptions.js +++ b/services/blockchain-indexer/methods/dataService/controllers/badges.js @@ -5,18 +5,18 @@ const { const dataService = require('../../../shared/dataService'); -const getSubscriptions = async params => { - const subscriptions = { +const getBadges = async params => { + const badges = { data: [], meta: {}, }; try { - const response = await dataService.getSubscriptions(params); - if (response.data) subscriptions.data = response.data; - if (response.meta) subscriptions.meta = response.meta; + const response = await dataService.getBadges(params); + if (response.data) badges.data = response.data; + if (response.meta) badges.meta = response.meta; - return subscriptions; + return badges; } catch (err) { let status; if (err instanceof InvalidParamsException) status = 'INVALID_PARAMS'; @@ -27,5 +27,5 @@ const getSubscriptions = async params => { }; module.exports = { - getSubscriptions, + getBadges, }; diff --git a/services/blockchain-indexer/methods/dataService/modules/badge.js b/services/blockchain-indexer/methods/dataService/modules/badge.js new file mode 100644 index 000000000..a41b306bb --- /dev/null +++ b/services/blockchain-indexer/methods/dataService/modules/badge.js @@ -0,0 +1,19 @@ +const { + getBadges, +} = require('../controllers/badges'); + +module.exports = [ + { + name: 'badges', + controller: getBadges, + params: { + awardedTo: { optional: true, type: 'string' }, + badgeID: { optional: true, type: 'string' }, + anchorID: { optional: true, type: 'string' }, + type: { optional: true, type: 'string' }, + limit: { optional: true, type: 'number' }, + offset: { optional: true, type: 'number' }, + memberAddress: { optional: true, type: 'string' }, + }, + }, +]; diff --git a/services/blockchain-indexer/methods/dataService/modules/subscription.js b/services/blockchain-indexer/methods/dataService/modules/subscription.js deleted file mode 100644 index f13ba86ed..000000000 --- a/services/blockchain-indexer/methods/dataService/modules/subscription.js +++ /dev/null @@ -1,17 +0,0 @@ -const { - getSubscriptions, -} = require('../controllers/subscriptions'); - -module.exports = [ - { - name: 'subscriptions', - controller: getSubscriptions, - params: { - creatorAddress: { optional: true, type: 'string' }, - subscriptionID: { optional: true, type: 'string' }, - limit: { optional: true, type: 'number' }, - offset: { optional: true, type: 'number' }, - memberAddress: { optional: true, type: 'string' }, - }, - }, -]; diff --git a/services/blockchain-indexer/shared/dataService/badges.js b/services/blockchain-indexer/shared/dataService/badges.js new file mode 100644 index 000000000..c10c72f75 --- /dev/null +++ b/services/blockchain-indexer/shared/dataService/badges.js @@ -0,0 +1,23 @@ +const { Logger } = require('lisk-service-framework'); +const util = require('util'); + +const logger = Logger(); + +const business = require('./business'); + +const getBadges = async params => { + // Store logs + if (params.awardedTo) logger.debug(`Retrieved active badge for member ${params.awardedTo} from Lisk Core`); + if (params.badgeID) logger.debug(`Retrieved badge with ID ${params.badgeID} from Lisk Core`); + else if (params.type) logger.debug(`Retrieved badge with creatorAddress: ${params.type} from Lisk Core`); + else logger.debug(`Retrieved badge with custom search: ${util.inspect(params)} from Lisk Core`); + + // Get data from server + const response = await business.getBadges(params); + + return response; +}; + +module.exports = { + getBadges, +}; diff --git a/services/blockchain-indexer/shared/dataService/business/anchors.js b/services/blockchain-indexer/shared/dataService/business/anchors.js index cf97a38b5..fdcfb0a90 100644 --- a/services/blockchain-indexer/shared/dataService/business/anchors.js +++ b/services/blockchain-indexer/shared/dataService/business/anchors.js @@ -44,7 +44,7 @@ const getAnchors = async (params = {}) => { } const anchorData = await anchorsTable.find( - { ...params, limit: params.limit }, + { ...params, limit: params.limit || 10 }, ['anchorID', 'name', 'album', 'artists', 'spotifyId', 'appleMusicId', 'createdAt', 'submitter'], ); const total = anchorData.length; diff --git a/services/blockchain-indexer/shared/dataService/business/badges.js b/services/blockchain-indexer/shared/dataService/business/badges.js new file mode 100644 index 000000000..c70d2d7b7 --- /dev/null +++ b/services/blockchain-indexer/shared/dataService/business/badges.js @@ -0,0 +1,38 @@ +const { + MySQL: { getTableInstance }, +} = require('lisk-service-framework'); + +const badgesIndexSchema = require('../../database/schema/badges'); +const config = require('../../../config'); + +const MYSQL_ENDPOINT = config.endpoints.mysql; + +const getBadgesIndex = () => getTableInstance( + badgesIndexSchema.tableName, + badgesIndexSchema, + MYSQL_ENDPOINT, +); + +const getBadges = async (params = {}) => { + const badgesTable = await getBadgesIndex(); + + const total = await badgesTable.count(params); + const data = await badgesTable.find( + { ...params, limit: params.limit || 10 }, + ['badgeID', 'anchorID', 'awardedTo', 'awardDate', 'type', 'prize', 'rank', 'claimed'], + ); + + const result = { + data, + meta: { + count: data.length, + offset: parseInt(params.offset, 10) || 0, + total, + }, + }; + return result; +}; + +module.exports = { + getBadges, +}; diff --git a/services/blockchain-indexer/shared/dataService/business/index.js b/services/blockchain-indexer/shared/dataService/business/index.js index f58870681..f3d160da5 100644 --- a/services/blockchain-indexer/shared/dataService/business/index.js +++ b/services/blockchain-indexer/shared/dataService/business/index.js @@ -108,7 +108,7 @@ const { invokeEndpoint } = require('./invoke'); const { setFeeEstimates, getFeeEstimates, initFeeEstimates } = require('./feeEstimates'); // Muzikie Dedicated Modules -const { getSubscriptions } = require('./subscriptions'); +const { getBadges } = require('./badges'); const { getAnchors } = require('./anchors'); module.exports = { @@ -206,8 +206,8 @@ module.exports = { getNetworkDisconnectedPeers, getNetworkPeersStatistics, - // subscriptions - getSubscriptions, + // badges + getBadges, // anchors getAnchors, diff --git a/services/blockchain-indexer/shared/dataService/business/subscriptions.js b/services/blockchain-indexer/shared/dataService/business/subscriptions.js deleted file mode 100644 index 6aa6fb0bf..000000000 --- a/services/blockchain-indexer/shared/dataService/business/subscriptions.js +++ /dev/null @@ -1,111 +0,0 @@ -const { - MySQL: { getTableInstance }, -} = require('lisk-service-framework'); -const BluebirdPromise = require('bluebird'); - -const transactionsIndexSchema = require('../../database/schema/subscriptions'); -const membersIndexSchema = require('../../database/schema/members'); -const config = require('../../../config'); - -const MYSQL_ENDPOINT = config.endpoints.mysql; - -const getSubscriptionsIndex = () => getTableInstance( - transactionsIndexSchema.tableName, - transactionsIndexSchema, - MYSQL_ENDPOINT, -); - -const getMembersIndex = () => getTableInstance( - membersIndexSchema.tableName, - membersIndexSchema, - MYSQL_ENDPOINT, -); -const getActiveSubscriptionsByMemberAddress = async (params = {}) => { - const membersTable = await getMembersIndex(); - const subscriptionsTable = await getSubscriptionsIndex(); - const result = { - data: {}, - meta: { - count: 0, - offset: parseInt(params.offset, 10) || 0, - total: 0, - }, - }; - try { - const member = await membersTable.find( - { address: params.memberAddress }, - ['id', 'address', 'shared', 'addedBy', 'removedBy'], - ); - if (member) { - const data = await subscriptionsTable.find( - { subscriptionID: member[0].shared }, - ['subscriptionID', 'creatorAddress', 'price', 'consumable', 'maxMembers', 'streams'], - ); - if (data) { - return { - data, - meta: { - count: 1, - offset: parseInt(params.offset, 10) || 0, - total: 1, - }, - }; - } - } - return result; - } catch (error) { - return { - data: {}, - meta: { - count: 0, - offset: parseInt(params.offset, 10) || 0, - total: 0, - }, - }; - } -}; - -const getSubscriptionsBySubscriptionIdOrCreatorAddress = async (params = {}) => { - const subscriptionsTable = await getSubscriptionsIndex(); - const membersTable = await getMembersIndex(); - - const total = await subscriptionsTable.count(params); - const subscriptionSet = await subscriptionsTable.find( - { ...params, limit: params.limit || total }, - ['subscriptionID', 'creatorAddress', 'price', 'consumable', 'maxMembers', 'streams'], - ); - - const data = await BluebirdPromise.map( - subscriptionSet, - async subscription => { - const membersSet = await membersTable.find( - { shared: subscription.subscriptionID, removedBy: null }, - ['address'], - ); - subscription.members = membersSet.map(member => ({ address: member.address })); - return subscription; - }, - { concurrency: subscriptionSet.length }, - ); - - const result = { - data, - meta: { - count: data.length, - offset: parseInt(params.offset, 10) || 0, - total, - }, - }; - return result; -}; - -const getSubscriptions = async (params = {}) => { - if (params.memberAddress) { - return getActiveSubscriptionsByMemberAddress(params); - } - return getSubscriptionsBySubscriptionIdOrCreatorAddress(params); -}; - -module.exports = { - getSubscriptions, -}; diff --git a/services/blockchain-indexer/shared/dataService/index.js b/services/blockchain-indexer/shared/dataService/index.js index a4b3a8296..f15cbd444 100644 --- a/services/blockchain-indexer/shared/dataService/index.js +++ b/services/blockchain-indexer/shared/dataService/index.js @@ -104,7 +104,7 @@ const { getIndexStatus, isBlockchainFullyIndexed } = require('./indexStatus'); const { getLegacyAccountInfo } = require('./legacy'); const { getValidator, validateBLSKey } = require('./validator'); const { getGenerators } = require('./generators'); -const { getSubscriptions } = require('./subscriptions'); +const { getBadges } = require('./badges'); const { getAnchors } = require('./anchors'); const { invokeEndpoint } = require('./invoke'); @@ -207,8 +207,8 @@ module.exports = { getDefaultRewardAtHeight, getRewardConstants, - // Subscriptions - getSubscriptions, + // Badges + getBadges, // Anchors getAnchors, diff --git a/services/blockchain-indexer/shared/dataService/subscriptions.js b/services/blockchain-indexer/shared/dataService/subscriptions.js deleted file mode 100644 index 8f647cc2e..000000000 --- a/services/blockchain-indexer/shared/dataService/subscriptions.js +++ /dev/null @@ -1,23 +0,0 @@ -const { Logger } = require('lisk-service-framework'); -const util = require('util'); - -const logger = Logger(); - -const business = require('./business'); - -const getSubscriptions = async params => { - // Store logs - if (params.memberAddress) logger.debug(`Retrieved active subscription for member ${params.memberAddress} from Lisk Core`); - if (params.subscriptionID) logger.debug(`Retrieved subscription with ID ${params.subscriptionID} from Lisk Core`); - else if (params.creatorAddress) logger.debug(`Retrieved subscription with creatorAddress: ${params.creatorAddress} from Lisk Core`); - else logger.debug(`Retrieved subscription with custom search: ${util.inspect(params)} from Lisk Core`); - - // Get data from server - const response = await business.getSubscriptions(params); - - return response; -}; - -module.exports = { - getSubscriptions, -}; diff --git a/services/blockchain-indexer/shared/database/schema/badges.js b/services/blockchain-indexer/shared/database/schema/badges.js new file mode 100644 index 000000000..e1d800414 --- /dev/null +++ b/services/blockchain-indexer/shared/database/schema/badges.js @@ -0,0 +1,18 @@ +module.exports = { + tableName: 'badges', + primaryKey: 'badgeID', + schema: { + badgeID: { type: 'string', null: true, defaultValue: null }, + anchorID: { type: 'string', null: true, defaultValue: null }, + awardedTo: { type: 'string', null: true, defaultValue: null }, + awardDate: { type: 'string', null: true, defaultValue: null }, + type: { type: 'string', null: true, defaultValue: null }, + rank: { type: 'bigInteger', null: true, defaultValue: null }, + prize: { type: 'bigInteger', null: true, defaultValue: null }, + claimed: { type: 'boolean', null: true, defaultValue: null }, + }, + indexes: { + creatorAddress: { type: 'string' }, + }, + purge: {}, +}; diff --git a/services/blockchain-indexer/shared/database/schema/members.js b/services/blockchain-indexer/shared/database/schema/members.js deleted file mode 100644 index 3f1aacd2a..000000000 --- a/services/blockchain-indexer/shared/database/schema/members.js +++ /dev/null @@ -1,15 +0,0 @@ -module.exports = { - tableName: 'members', - primaryKey: 'id', - schema: { - id: { type: 'string' }, // memberAddress-nonce - address: { type: 'string' }, // memberAddress - shared: { type: 'string', null: true }, // subscriptionID - addedBy: { type: 'string', null: true }, // transactionID - removedBy: { type: 'string', null: true }, // transactionID - }, - indexes: { - shared: { type: 'key' }, - }, - purge: {}, -}; diff --git a/services/blockchain-indexer/shared/database/schema/subscriptions.js b/services/blockchain-indexer/shared/database/schema/subscriptions.js deleted file mode 100644 index 9246dbf16..000000000 --- a/services/blockchain-indexer/shared/database/schema/subscriptions.js +++ /dev/null @@ -1,16 +0,0 @@ -module.exports = { - tableName: 'subscriptions', - primaryKey: 'subscriptionID', - schema: { - subscriptionID: { type: 'string', null: true, defaultValue: null }, - creatorAddress: { type: 'string', null: true, defaultValue: null }, // at first->DEV but then->user - price: { type: 'bigInteger', null: true, defaultValue: null }, - consumable: { type: 'bigInteger', null: true, defaultValue: null }, - streams: { type: 'bigInteger', null: true, defaultValue: null }, - maxMembers: { type: 'integer', null: true, defaultValue: null }, - }, - indexes: { - creatorAddress: { type: 'string' }, - }, - purge: {}, -}; diff --git a/services/blockchain-indexer/shared/indexer/transactionProcessor/badge/claim.js b/services/blockchain-indexer/shared/indexer/transactionProcessor/badge/claim.js new file mode 100644 index 000000000..70cef292f --- /dev/null +++ b/services/blockchain-indexer/shared/indexer/transactionProcessor/badge/claim.js @@ -0,0 +1,74 @@ +const { + Logger, + MySQL: { getTableInstance }, +} = require('lisk-service-framework'); + +const { getLisk32AddressFromPublicKey } = require('../../../utils/account'); + +const config = require('../../../../config'); + +const logger = Logger(); + +const MYSQL_ENDPOINT = config.endpoints.mysql; +const accountsTableSchema = require('../../../database/schema/accounts'); +const badgesTableSchema = require('../../../database/schema/badges'); + +const getAccountsTable = () => getTableInstance( + accountsTableSchema.tableName, + accountsTableSchema, + MYSQL_ENDPOINT, +); + +const getBadgesTable = () => getTableInstance( + badgesTableSchema.tableName, + badgesTableSchema, + MYSQL_ENDPOINT, +); + +// Command specific constants +const COMMAND_NAME = 'claim'; + +// eslint-disable-next-line no-unused-vars +const applyTransaction = async (blockHeader, tx, events, dbTrx) => { + const accountsTable = await getAccountsTable(); + const badgesTable = await getBadgesTable(); + + const senderAddress = getLisk32AddressFromPublicKey(tx.senderPublicKey); + const { badgeID } = tx.params; + + logger.trace(`Indexing badge with address ${badgeID} updated by transaction with ID ${dbTrx.id}.`); + const badgeNFT = await badgesTable.find( + { badgeID }, + ['badgeID', 'anchorID', 'awardedTo', 'type', 'awardDate', 'rank', 'prize', 'claimed'], + dbTrx, + ); + badgeNFT.claimed = true; + await badgesTable.upsert(badgeNFT, dbTrx); + logger.debug(`Indexed transaction with ID ${dbTrx.id}.`); + + // Update sender in accounts table + const senderAccount = { address: senderAddress }; + await accountsTable.upsert(senderAccount, dbTrx); + logger.trace(`Indexed badge purchase with account address ${senderAddress}.`); +}; + +// eslint-disable-next-line no-unused-vars +const revertTransaction = async (blockHeader, tx, events, dbTrx) => { + const badgesTable = await getBadgesTable(); + + const { badgeID } = tx.params; + + const badgeNFT = await badgesTable.find( + { badgeID }, + ['badgeID', 'anchorID', 'awardedTo', 'type', 'awardDate', 'rank', 'prize', 'claimed'], + dbTrx, + ); + badgeNFT.claimed = false; + await badgesTable.upsert(badgeNFT, dbTrx); +}; + +module.exports = { + COMMAND_NAME, + applyTransaction, + revertTransaction, +}; diff --git a/services/blockchain-indexer/shared/indexer/transactionProcessor/badge/create.js b/services/blockchain-indexer/shared/indexer/transactionProcessor/badge/create.js new file mode 100644 index 000000000..70cead085 --- /dev/null +++ b/services/blockchain-indexer/shared/indexer/transactionProcessor/badge/create.js @@ -0,0 +1,64 @@ +const { + Logger, + MySQL: { getTableInstance }, +} = require('lisk-service-framework'); + +const config = require('../../../../config'); + +const logger = Logger(); + +const MYSQL_ENDPOINT = config.endpoints.mysql; +const badgesTableSchema = require('../../../database/schema/badges'); + +const { + MODULE_NAME_BADGE, + EVENT_NAME_BADGE_CREATED, +} = require('../../../../../blockchain-connector/shared/sdk/constants/names'); + +const getBadgesTable = () => getTableInstance( + badgesTableSchema.tableName, + badgesTableSchema, + MYSQL_ENDPOINT, +); + +// Command specific constants +const COMMAND_NAME = 'create'; + +// eslint-disable-next-line no-unused-vars +const applyTransaction = async (blockHeader, tx, events, dbTrx) => { + const badgesTable = await getBadgesTable(); + + // @todo make sure the process won't break if the event doesn't exist. e.g. do not index. + const { data: eventData = {} } = events.find( + (e) => e.module === MODULE_NAME_BADGE && e.name === EVENT_NAME_BADGE_CREATED, + ); + + const badgesNFT = { + ...eventData, + ...tx.params, + claimed: false, + }; + + logger.debug(`Indexing badge with ID ${eventData.badgeID}.`); + await badgesTable.upsert(badgesNFT, dbTrx); + logger.debug(`Indexed badge with ID ${eventData.badgeID}.`); +}; + +// eslint-disable-next-line no-unused-vars +const revertTransaction = async (blockHeader, tx, events, dbTrx) => { + const badgesTable = await getBadgesTable(); + + const { data: eventData } = events.find( + (e) => e.module === MODULE_NAME_BADGE && e.name === EVENT_NAME_BADGE_CREATED, + ); + + logger.trace(`Remove badge entry for ID ${eventData.badgeID}.`); + await badgesTable.delete({ badgeID: eventData.badgeID }, dbTrx); + logger.debug(`Removed badge entry for ID ${eventData.badgeID}.`); +}; + +module.exports = { + COMMAND_NAME, + applyTransaction, + revertTransaction, +}; diff --git a/services/blockchain-indexer/shared/indexer/transactionProcessor/subscription/index.js b/services/blockchain-indexer/shared/indexer/transactionProcessor/badge/index.js similarity index 64% rename from services/blockchain-indexer/shared/indexer/transactionProcessor/subscription/index.js rename to services/blockchain-indexer/shared/indexer/transactionProcessor/badge/index.js index 7adb3a6ab..140108613 100644 --- a/services/blockchain-indexer/shared/indexer/transactionProcessor/subscription/index.js +++ b/services/blockchain-indexer/shared/indexer/transactionProcessor/badge/index.js @@ -1,5 +1,5 @@ // Module specific constants -const MODULE_NAME = 'subscription'; +const MODULE_NAME = 'badge'; module.exports = { MODULE_NAME, diff --git a/services/blockchain-indexer/shared/indexer/transactionProcessor/subscription/create.js b/services/blockchain-indexer/shared/indexer/transactionProcessor/subscription/create.js deleted file mode 100644 index c3deecc64..000000000 --- a/services/blockchain-indexer/shared/indexer/transactionProcessor/subscription/create.js +++ /dev/null @@ -1,72 +0,0 @@ -const { - Logger, - MySQL: { getTableInstance }, -} = require('lisk-service-framework'); - -const { getLisk32AddressFromPublicKey } = require('../../../utils/account'); - -const config = require('../../../../config'); - -const logger = Logger(); - -const MYSQL_ENDPOINT = config.endpoints.mysql; -const accountsTableSchema = require('../../../database/schema/accounts'); -const subscriptionsTableSchema = require('../../../database/schema/subscriptions'); - -const getAccountsTable = () => getTableInstance( - accountsTableSchema.tableName, - accountsTableSchema, - MYSQL_ENDPOINT, -); - -const getSubscriptionsTable = () => getTableInstance( - subscriptionsTableSchema.tableName, - subscriptionsTableSchema, - MYSQL_ENDPOINT, -); - -// Command specific constants -const COMMAND_NAME = 'create'; - -// eslint-disable-next-line no-unused-vars -const applyTransaction = async (blockHeader, tx, events, dbTrx) => { - const accountsTable = await getAccountsTable(); - const subscriptionsTable = await getSubscriptionsTable(); - - const senderAddress = getLisk32AddressFromPublicKey(tx.senderPublicKey); - const devAccount = { address: senderAddress }; - - logger.trace(`Updating account index for the account with address ${senderAddress}.`); - await accountsTable.upsert(devAccount, dbTrx); - logger.debug(`Updated account index for the account with address ${senderAddress}.`); - - logger.trace(`Indexing subscription with address ${senderAddress}.`); - - // @todo make sure the process won't break if the event doesn't exist. e.g. do not index. - const { data: eventData = {} } = events.find(e => e.module === 'subscription' && e.name === 'subscriptionCreated'); - - const subscriptionsNFT = { - ...eventData, - ...tx.params, - }; - - await subscriptionsTable.upsert(subscriptionsNFT, dbTrx); - logger.debug(`Indexed subscription with ID ${eventData.subscriptionID}.`); -}; - -// eslint-disable-next-line no-unused-vars -const revertTransaction = async (blockHeader, tx, events, dbTrx) => { - const subscriptionsTable = await getSubscriptionsTable(); - - const { data: eventData } = events.find(e => e.module === 'subscription' && e.name === 'subscriptionCreated'); - - logger.trace(`Remove subscription entry for ID ${eventData.subscriptionID}.`); - await subscriptionsTable.delete({ subscriptionID: eventData.subscriptionID }, dbTrx); - logger.debug(`Removed subscription entry for ID ${eventData.subscriptionID}.`); -}; - -module.exports = { - COMMAND_NAME, - applyTransaction, - revertTransaction, -}; diff --git a/services/blockchain-indexer/shared/indexer/transactionProcessor/subscription/purchase.js b/services/blockchain-indexer/shared/indexer/transactionProcessor/subscription/purchase.js deleted file mode 100644 index 9a2c16f0a..000000000 --- a/services/blockchain-indexer/shared/indexer/transactionProcessor/subscription/purchase.js +++ /dev/null @@ -1,111 +0,0 @@ -const { - Logger, - MySQL: { getTableInstance }, -} = require('lisk-service-framework'); -const BluebirdPromise = require('bluebird'); - -const { getLisk32AddressFromPublicKey } = require('../../../utils/account'); -const { DEV_ADDRESS } = require('../../../constants'); - -const config = require('../../../../config'); - -const logger = Logger(); - -const MYSQL_ENDPOINT = config.endpoints.mysql; -const accountsTableSchema = require('../../../database/schema/accounts'); -const subscriptionsTableSchema = require('../../../database/schema/subscriptions'); -const membersTableSchema = require('../../../database/schema/members'); - -const getAccountsTable = () => getTableInstance( - accountsTableSchema.tableName, - accountsTableSchema, - MYSQL_ENDPOINT, -); - -const getSubscriptionsTable = () => getTableInstance( - subscriptionsTableSchema.tableName, - subscriptionsTableSchema, - MYSQL_ENDPOINT, -); - -const getMembersTable = () => getTableInstance( - membersTableSchema.tableName, - membersTableSchema, - MYSQL_ENDPOINT, -); - -// Command specific constants -const COMMAND_NAME = 'purchase'; - -// eslint-disable-next-line no-unused-vars -const applyTransaction = async (blockHeader, tx, events, dbTrx) => { - const accountsTable = await getAccountsTable(); - const subscriptionsTable = await getSubscriptionsTable(); - const membersTable = await getMembersTable(); - - const senderAddress = getLisk32AddressFromPublicKey(tx.senderPublicKey); - const { subscriptionID } = tx.params; - - logger.trace(`Indexing subscription with address ${subscriptionID}.`); - const subscriptionNFT = await subscriptionsTable.find( - { subscriptionID }, - ['subscriptionID', 'creatorAddress', 'price', 'consumable', 'streams', 'maxMembers'], - dbTrx, - ); - subscriptionNFT.creatorAddress = senderAddress; - await subscriptionsTable.upsert(subscriptionNFT, dbTrx); - logger.debug(`Indexed subscription with ID ${dbTrx.id}.`); - - // Update members in accounts and members table - await BluebirdPromise.map( - tx.params.members, - async member => { - const oldAccount = { address: member }; - logger.trace(`Updating account index for the account with address ${member}.`); - await accountsTable.upsert(oldAccount, dbTrx);// Create account for that member if not exists - logger.debug(`Updated account index for the account with address ${member}.`); - - const memberData = { - id: member.concat(`-${tx.nonce.toString()}`), - address: member, - addedBy: tx.id, - shared: subscriptionID, - }; - // subscription members - logger.trace(`Updating member index for the member with address ${member}.`); - await membersTable.upsert(memberData, dbTrx); - logger.debug(`Updated member index for the member with address ${member}.`); - return true; - }, - { concurrency: tx.params.members.length }, - ); - - // Update sender in accounts table - const senderAccount = { address: senderAddress }; - await accountsTable.upsert(senderAccount, dbTrx); - logger.trace(`Indexed subscription purchase with account address ${senderAddress}.`); -}; - -// eslint-disable-next-line no-unused-vars -const revertTransaction = async (blockHeader, tx, events, dbTrx) => { - const subscriptionsTable = await getSubscriptionsTable(); - const membersTable = await getMembersTable(); - - const { subscriptionID } = tx.params; - - const subscriptionNFT = await subscriptionsTable.find( - { subscriptionID }, - ['subscriptionID', 'creatorAddress', 'price', 'consumable', 'streams', 'maxMembers'], - dbTrx, - ); - subscriptionNFT.creatorAddress = DEV_ADDRESS; - await subscriptionsTable.upsert(subscriptionNFT, dbTrx); - - await membersTable.delete({ shared: subscriptionID }, dbTrx); -}; - -module.exports = { - COMMAND_NAME, - applyTransaction, - revertTransaction, -}; diff --git a/services/blockchain-indexer/shared/indexer/transactionProcessor/subscription/updateMembers.js b/services/blockchain-indexer/shared/indexer/transactionProcessor/subscription/updateMembers.js deleted file mode 100644 index e2c035c2d..000000000 --- a/services/blockchain-indexer/shared/indexer/transactionProcessor/subscription/updateMembers.js +++ /dev/null @@ -1,105 +0,0 @@ -const { - Logger, - MySQL: { getTableInstance }, -} = require('lisk-service-framework'); -const BluebirdPromise = require('bluebird'); - -const config = require('../../../../config'); - -const logger = Logger(); - -const MYSQL_ENDPOINT = config.endpoints.mysql; -const membersTableSchema = require('../../../database/schema/members'); - -const getMembersTable = () => getTableInstance( - membersTableSchema.tableName, - membersTableSchema, - MYSQL_ENDPOINT, -); - -// Command specific constants -const COMMAND_NAME = 'updateMembers'; - -// eslint-disable-next-line no-unused-vars -const applyTransaction = async (blockHeader, tx, events, dbTrx) => { - const membersTable = await getMembersTable(); - - const { subscriptionID } = tx.params; - - logger.trace(`Removing existing members with subscription ID ${subscriptionID}.`); - const currentMembers = await membersTable.find( - { shared: subscriptionID, removedBy: null }, - ['id', 'address', 'shared'], - dbTrx, - ); - - const currentAddresses = currentMembers.map(({ address }) => address); - const removed = currentMembers.filter(({ address }) => !tx.params.members.includes(address)); - const added = tx.params.members.filter(member => !currentAddresses.includes(member)); - - await BluebirdPromise.map( - removed, - async member => { - const memberData = { - ...member, - removedBy: tx.id, - }; - logger.trace(`Updating account index for the account with address ${member}.`); - await membersTable.upsert(memberData, dbTrx); - logger.debug(`Updated account index for the account with address ${member}.`); - }, - { concurrency: removed.length }, - ); - logger.trace(`Removed existing members with subscription ID ${subscriptionID}.`); - - logger.trace(`Adding new members with subscription ID ${subscriptionID}.`); - await BluebirdPromise.map( - added, - async member => { - const memberData = { - id: member.concat(`-${tx.nonce.toString()}`), - address: member, - addedBy: tx.id, - shared: subscriptionID, - }; - logger.trace(`Updating account index for the account with address ${member}.`); - await membersTable.upsert(memberData, dbTrx); - logger.debug(`Updated account index for the account with address ${member}.`); - }, - { concurrency: added.length }, - ); - logger.trace(`Added new members with subscription ID ${subscriptionID}.`); -}; - -// eslint-disable-next-line no-unused-vars -const revertTransaction = async (blockHeader, tx, events, dbTrx) => { - const membersTable = await getMembersTable(); - - const removed = await membersTable.find( - { removedBy: tx.id }, - ['id', 'address', 'shared'], - dbTrx, - ); - - await membersTable.delete({ addedBy: tx.id }, dbTrx); - - await BluebirdPromise.map( - removed, - async member => { - const memberData = { - ...member, - removedBy: null, - }; - logger.trace(`Updating account index for the account with address ${member}.`); - await membersTable.upsert(memberData, dbTrx); - logger.debug(`Updated account index for the account with address ${member}.`); - }, - { concurrency: removed.length }, - ); -}; - -module.exports = { - COMMAND_NAME, - applyTransaction, - revertTransaction, -}; diff --git a/services/gateway/apis/http-version3/methods/badges.js b/services/gateway/apis/http-version3/methods/badges.js new file mode 100644 index 000000000..ca384ce3f --- /dev/null +++ b/services/gateway/apis/http-version3/methods/badges.js @@ -0,0 +1,56 @@ +/* + * LiskHQ/lisk-service + * Copyright © 2022 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 badgesSource = require('../../../sources/version3/badges'); +const envelope = require('../../../sources/version3/mappings/stdEnvelope'); +const regex = require('../../../shared/regex'); +const { transformParams, response, getSwaggerDescription } = require('../../../shared/utils'); + +module.exports = { + version: '2.0', + swaggerApiPath: '/badges', + rpcMethod: 'get.badges', + tags: ['Badges'], + params: { + awardedTo: { optional: true, type: 'string', min: 3, max: 41, pattern: regex.ADDRESS_LISK32 }, + badgeID: { optional: true, type: 'string', min: 1, max: 64, pattern: regex.HASH_SHA256 }, + anchorID: { optional: true, type: 'string', min: 1, max: 64, pattern: regex.HASH_SHA256 }, + type: { optional: true, type: 'string' }, + }, + get schema() { + const badgeSchema = {}; + badgeSchema[this.swaggerApiPath] = { get: {} }; + badgeSchema[this.swaggerApiPath].get.tags = this.tags; + badgeSchema[this.swaggerApiPath].get.summary = 'Requests badges data'; + badgeSchema[this.swaggerApiPath].get.description = getSwaggerDescription({ + rpcMethod: this.rpcMethod, + description: 'Returns badges data', + }); + badgeSchema[this.swaggerApiPath].get.parameters = transformParams('badges', this.params); + badgeSchema[this.swaggerApiPath].get.responses = { + 200: { + description: 'Returns a list of badges', + schema: { + $ref: '#/definitions/badgesWithEnvelope', + }, + }, + }; + Object.assign(badgeSchema[this.swaggerApiPath].get.responses, response); + return badgeSchema; + }, + source: badgesSource, + envelope, +}; diff --git a/services/gateway/apis/http-version3/methods/subscriptions.js b/services/gateway/apis/http-version3/methods/subscriptions.js deleted file mode 100644 index e8e2ae19f..000000000 --- a/services/gateway/apis/http-version3/methods/subscriptions.js +++ /dev/null @@ -1,55 +0,0 @@ -/* - * LiskHQ/lisk-service - * Copyright © 2022 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 subscriptionsSource = require('../../../sources/version3/subscriptions'); -const envelope = require('../../../sources/version3/mappings/stdEnvelope'); -const regex = require('../../../shared/regex'); -const { transformParams, response, getSwaggerDescription } = require('../../../shared/utils'); - -module.exports = { - version: '2.0', - swaggerApiPath: '/subscriptions', - rpcMethod: 'get.subscriptions', - tags: ['Subscriptions'], - params: { - creatorAddress: { optional: true, type: 'string', min: 3, max: 41, pattern: regex.ADDRESS_LISK32 }, - subscriptionID: { optional: true, type: 'string', min: 1, max: 64, pattern: regex.HASH_SHA256 }, - memberAddress: { optional: true, type: 'string' }, - }, - get schema() { - const subscriptionSchema = {}; - subscriptionSchema[this.swaggerApiPath] = { get: {} }; - subscriptionSchema[this.swaggerApiPath].get.tags = this.tags; - subscriptionSchema[this.swaggerApiPath].get.summary = 'Requests subscriptions data'; - subscriptionSchema[this.swaggerApiPath].get.description = getSwaggerDescription({ - rpcMethod: this.rpcMethod, - description: 'Returns subscriptions data', - }); - subscriptionSchema[this.swaggerApiPath].get.parameters = transformParams('subscriptions', this.params); - subscriptionSchema[this.swaggerApiPath].get.responses = { - 200: { - description: 'Returns a list of subscriptions', - schema: { - $ref: '#/definitions/subscriptionsWithEnvelope', - }, - }, - }; - Object.assign(subscriptionSchema[this.swaggerApiPath].get.responses, response); - return subscriptionSchema; - }, - source: subscriptionsSource, - envelope, -}; diff --git a/services/gateway/apis/http-version3/swagger/apiJson.json b/services/gateway/apis/http-version3/swagger/apiJson.json index 7a5980a31..b8ddc4210 100644 --- a/services/gateway/apis/http-version3/swagger/apiJson.json +++ b/services/gateway/apis/http-version3/swagger/apiJson.json @@ -88,8 +88,8 @@ "description": "Market prices related API calls." }, { - "name": "Subscription", - "description": "Subscription module related API calls." + "name": "Badge", + "description": "Badge module related API calls." }, { "name": "Anchor", diff --git a/services/gateway/apis/http-version3/swagger/definitions/subscriptions.json b/services/gateway/apis/http-version3/swagger/definitions/badges.json similarity index 68% rename from services/gateway/apis/http-version3/swagger/definitions/subscriptions.json rename to services/gateway/apis/http-version3/swagger/definitions/badges.json index abc2410ec..2c8ee819b 100644 --- a/services/gateway/apis/http-version3/swagger/definitions/subscriptions.json +++ b/services/gateway/apis/http-version3/swagger/definitions/badges.json @@ -1,37 +1,34 @@ { - "Subscription": { + "Badge": { "type": "object", "required": [ - "creatorAddress", - "subscriptionID", - "members", - "price", - "consumable", - "maxMembers", - "streams" + "badgeID", + "anchorID", + "awardedTo", + "type", + "awardDate", + "rank", + "prize", + "claimed" ], "properties": { - "subscriptionID": { + "badgeID": { "type": "string", "format": "id", "example": "f9593f101c4acafc3ede650ab4c10fa2ecb59b225813eddbbb17b47e96932e9b", "minLength": 1, "maxLength": 64, - "description": "Unique identifier of the subscription.\nDerived from the subscription hash." + "description": "Unique identifier of the badge.\nDerived from the badge hash." }, - "price": { + "anchorID": { "type": "string", - "example": "0" - }, - "consumable": { - "type": "string", - "description": "Consumable value." - }, - "MaxMembers": { - "type": "integer", - "example": "1" + "format": "id", + "example": "f9593f101c4acafc3ede650ab4c10fa2ecb59b225813eddbbb17b47e96932e9b", + "minLength": 1, + "maxLength": 64, + "description": "Unique identifier of the anchor.\nDerived from the badge hash." }, - "creatorAddress": { + "awardedTo": { "type": "object", "properties": { "address": { @@ -53,18 +50,29 @@ } } }, - "members": { - "type": "array", - "items": { - "address": { - "type": "string", - "description": "Member address." - } - } + "type": { + "type": "string", + "example": "0" + }, + "awardDate": { + "type": "string", + "description": "Consumable value." + }, + "rank": { + "type": "integer", + "example": "1" + }, + "prize": { + "type": "string", + "example": "10000000000" + }, + "claimed": { + "type": "boolean", + "example": "true" } } }, - "SubscriptionsWithEnvelope": { + "BadgesWithEnvelope": { "type": "object", "required": [ "data", @@ -72,10 +80,10 @@ ], "properties": { "data": { - "description": "List of subscriptions", + "description": "List of badges", "type": "array", "items": { - "$ref": "#/definitions/Subscriptions" + "$ref": "#/definitions/Badges" } }, "meta": { diff --git a/services/gateway/apis/http-version3/swagger/parameters/badges.json b/services/gateway/apis/http-version3/swagger/parameters/badges.json new file mode 100644 index 000000000..954349f93 --- /dev/null +++ b/services/gateway/apis/http-version3/swagger/parameters/badges.json @@ -0,0 +1,28 @@ +{ + "awardedTo": { + "name": "awardedTo", + "in": "query", + "description": "Lisk account address", + "type": "string", + "minLength": 3, + "maxLength": 41 + }, + "badgeID": { + "name": "badgeID", + "in": "query", + "description": "badge ID to query", + "type": "string", + "format": "id", + "minLength": 1, + "maxLength": 64 + }, + "anchorID": { + "name": "anchorID", + "in": "query", + "description": "anchor ID to query", + "type": "string", + "format": "id", + "minLength": 1, + "maxLength": 64 + } +} diff --git a/services/gateway/apis/http-version3/swagger/parameters/subscriptions.json b/services/gateway/apis/http-version3/swagger/parameters/subscriptions.json deleted file mode 100644 index 90b8a19f1..000000000 --- a/services/gateway/apis/http-version3/swagger/parameters/subscriptions.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "creatorAddress": { - "name": "creatorAddress", - "in": "query", - "description": "Lisk account address", - "type": "string", - "minLength": 3, - "maxLength": 41 - }, - "subscriptionID": { - "name": "subscriptionID", - "in": "query", - "description": "subscription ID to query", - "type": "string", - "format": "id", - "minLength": 1, - "maxLength": 64 - } -} diff --git a/services/gateway/sources/version3/subscriptions.js b/services/gateway/sources/version3/badges.js similarity index 66% rename from services/gateway/sources/version3/subscriptions.js rename to services/gateway/sources/version3/badges.js index 45277ffaf..080a2d604 100644 --- a/services/gateway/sources/version3/subscriptions.js +++ b/services/gateway/sources/version3/badges.js @@ -13,30 +13,27 @@ * Removal or modification of this copyright notice is prohibited. * */ -const subscription = require('./mappings/subscription'); +const badge = require('./mappings/badge'); module.exports = { type: 'moleculer', - method: 'indexer.subscriptions', + method: 'indexer.badges', params: { - subscriptionID: '=,string', - creatorAddress: '=,string', - price: '=,string', - consumed: '=,string', - members: ['members', { - address: '=,string', - name: '=,string', - publicKey: '=,string', - }], - streams: '=,string', - maxMembers: '=,number', + badgeID: '=,string', + anchorID: '=,string', + awardedTo: '=,string', + type: '=,string', + awardDate: '=,string', + rank: '=,number', + prize: '=,string', + claimed: '=,boolean', limit: '=,number', offset: '=,number', sort: '=,string', order: '=,string', }, definition: { - data: ['data', subscription], + data: ['data', badge], meta: { count: '=,number', offset: '=,number', diff --git a/services/gateway/sources/version3/mappings/subscription.js b/services/gateway/sources/version3/mappings/badge.js similarity index 67% rename from services/gateway/sources/version3/mappings/subscription.js rename to services/gateway/sources/version3/mappings/badge.js index bf82ee71b..f09349c7a 100644 --- a/services/gateway/sources/version3/mappings/subscription.js +++ b/services/gateway/sources/version3/mappings/badge.js @@ -14,15 +14,12 @@ * */ module.exports = { - subscriptionID: '=,string', - creatorAddress: '=,string', - maxMembers: '=,number', - streams: '=,string', - price: '=,string', - consumable: '=,string', - members: ['members', { - address: '=,string', - name: '=,string', - publicKey: '=,string', - }], + badgeID: '=,string', + anchorID: '=,string', + awardedTo: '=,string', + type: '=,string', + awardDate: '=,string', + rank: '=,number', + prize: '=,string', + claimed: '=,boolean', }; diff --git a/services/gateway/tests/constants/generateDocs.js b/services/gateway/tests/constants/generateDocs.js index c7dcd7c65..409d6986c 100644 --- a/services/gateway/tests/constants/generateDocs.js +++ b/services/gateway/tests/constants/generateDocs.js @@ -768,25 +768,28 @@ const createApiDocsExpectedResponse = { }, }, }, - '/subscriptions': { + '/badges': { get: { - description: 'Returns subscriptions data\n RPC => get.subscriptions', + description: 'Returns badges data\n RPC => get.badges', parameters: [ { - $ref: '#/parameters/creatorAddress', + $ref: '#/parameters/awardedTo', }, { - $ref: '#/parameters/subscriptionID', + $ref: '#/parameters/badgeID', }, { - $ref: '#/parameters/memberAddress', + $ref: '#/parameters/badgeID', + }, + { + $ref: '#/parameters/type', }, ], responses: { 200: { - description: 'Returns a list of subscriptions', + description: 'Returns a list of badges', schema: { - $ref: '#/definitions/subscriptionsWithEnvelope', + $ref: '#/definitions/badgesWithEnvelope', }, }, 400: { @@ -796,9 +799,9 @@ const createApiDocsExpectedResponse = { }, }, }, - summary: 'Requests subscriptions data', + summary: 'Requests badges data', tags: [ - 'Subscriptions', + 'Badges', ], }, }, diff --git a/services/gateway/tests/constants/registerApi.js b/services/gateway/tests/constants/registerApi.js index 3d395eb34..95347d938 100644 --- a/services/gateway/tests/constants/registerApi.js +++ b/services/gateway/tests/constants/registerApi.js @@ -38,7 +38,7 @@ const expectedResponseForRegisterHttpApi = [ 'indexer.transactions.post', 'indexer.schemas', 'gateway.spec', - 'indexer.subscriptions', + 'indexer.badges', 'indexer.transactions', 'indexer.transactions.dryrun', 'indexer.transactions.estimate-fees', @@ -82,7 +82,7 @@ const expectedResponseForRegisterHttpApi = [ 'GET network/status': 'indexer.network.status', 'POST transactions': 'indexer.transactions.post', 'GET schemas': 'indexer.schemas', - 'GET subscriptions': 'indexer.subscriptions', + 'GET badges': 'indexer.badges', 'GET spec': 'gateway.spec', 'GET transactions': 'indexer.transactions', 'POST transactions/dryrun': 'indexer.transactions.dryrun', @@ -146,7 +146,7 @@ const expectedResponseForRegisterRpcApi = { 'indexer.network.status', 'indexer.transactions.post', 'indexer.schemas', - 'indexer.subscriptions', + 'indexer.badges', 'indexer.transactions', 'indexer.transactions.dryrun', 'indexer.transactions.estimate-fees', @@ -190,7 +190,7 @@ const expectedResponseForRegisterRpcApi = { 'get.network.status': 'indexer.network.status', 'post.transactions': 'indexer.transactions.post', 'get.schemas': 'indexer.schemas', - 'get.subscriptions': 'indexer.subscriptions', + 'get.badges': 'indexer.badges', 'get.transactions': 'indexer.transactions', 'post.transactions.estimate-fees': 'indexer.transactions.estimate-fees', 'post.transactions.dryrun': 'indexer.transactions.dryrun', From c10b8444df9ee52f845973b7874dbe6d6b5ddf81 Mon Sep 17 00:00:00 2001 From: reyraa Date: Fri, 20 Oct 2023 11:59:02 +0200 Subject: [PATCH 04/10] Fix badge table indexer --- .../blockchain-indexer/methods/dataService/modules/badge.js | 1 - .../blockchain-indexer/shared/database/schema/badges.js | 2 +- .../shared/indexer/transactionProcessor/badge/claim.js | 6 +++--- .../shared/indexer/transactionProcessor/badge/create.js | 4 ++-- 4 files changed, 6 insertions(+), 7 deletions(-) diff --git a/services/blockchain-indexer/methods/dataService/modules/badge.js b/services/blockchain-indexer/methods/dataService/modules/badge.js index a41b306bb..e08c374b1 100644 --- a/services/blockchain-indexer/methods/dataService/modules/badge.js +++ b/services/blockchain-indexer/methods/dataService/modules/badge.js @@ -13,7 +13,6 @@ module.exports = [ type: { optional: true, type: 'string' }, limit: { optional: true, type: 'number' }, offset: { optional: true, type: 'number' }, - memberAddress: { optional: true, type: 'string' }, }, }, ]; diff --git a/services/blockchain-indexer/shared/database/schema/badges.js b/services/blockchain-indexer/shared/database/schema/badges.js index e1d800414..e33d46965 100644 --- a/services/blockchain-indexer/shared/database/schema/badges.js +++ b/services/blockchain-indexer/shared/database/schema/badges.js @@ -12,7 +12,7 @@ module.exports = { claimed: { type: 'boolean', null: true, defaultValue: null }, }, indexes: { - creatorAddress: { type: 'string' }, + badgeID: { type: 'string' }, }, purge: {}, }; diff --git a/services/blockchain-indexer/shared/indexer/transactionProcessor/badge/claim.js b/services/blockchain-indexer/shared/indexer/transactionProcessor/badge/claim.js index 70cef292f..e1d858a5d 100644 --- a/services/blockchain-indexer/shared/indexer/transactionProcessor/badge/claim.js +++ b/services/blockchain-indexer/shared/indexer/transactionProcessor/badge/claim.js @@ -29,7 +29,7 @@ const getBadgesTable = () => getTableInstance( const COMMAND_NAME = 'claim'; // eslint-disable-next-line no-unused-vars -const applyTransaction = async (blockHeader, tx, events, dbTrx) => { +const applyTransaction = async (_blockHeader, tx, _events, dbTrx) => { const accountsTable = await getAccountsTable(); const badgesTable = await getBadgesTable(); @@ -37,7 +37,7 @@ const applyTransaction = async (blockHeader, tx, events, dbTrx) => { const { badgeID } = tx.params; logger.trace(`Indexing badge with address ${badgeID} updated by transaction with ID ${dbTrx.id}.`); - const badgeNFT = await badgesTable.find( + const [badgeNFT] = await badgesTable.find( { badgeID }, ['badgeID', 'anchorID', 'awardedTo', 'type', 'awardDate', 'rank', 'prize', 'claimed'], dbTrx, @@ -53,7 +53,7 @@ const applyTransaction = async (blockHeader, tx, events, dbTrx) => { }; // eslint-disable-next-line no-unused-vars -const revertTransaction = async (blockHeader, tx, events, dbTrx) => { +const revertTransaction = async (_blockHeader, tx, _events, dbTrx) => { const badgesTable = await getBadgesTable(); const { badgeID } = tx.params; diff --git a/services/blockchain-indexer/shared/indexer/transactionProcessor/badge/create.js b/services/blockchain-indexer/shared/indexer/transactionProcessor/badge/create.js index 70cead085..a7ae54ff0 100644 --- a/services/blockchain-indexer/shared/indexer/transactionProcessor/badge/create.js +++ b/services/blockchain-indexer/shared/indexer/transactionProcessor/badge/create.js @@ -25,7 +25,7 @@ const getBadgesTable = () => getTableInstance( const COMMAND_NAME = 'create'; // eslint-disable-next-line no-unused-vars -const applyTransaction = async (blockHeader, tx, events, dbTrx) => { +const applyTransaction = async (_blockHeader, tx, events, dbTrx) => { const badgesTable = await getBadgesTable(); // @todo make sure the process won't break if the event doesn't exist. e.g. do not index. @@ -45,7 +45,7 @@ const applyTransaction = async (blockHeader, tx, events, dbTrx) => { }; // eslint-disable-next-line no-unused-vars -const revertTransaction = async (blockHeader, tx, events, dbTrx) => { +const revertTransaction = async (_blockHeader, _tx, events, dbTrx) => { const badgesTable = await getBadgesTable(); const { data: eventData } = events.find( From 8122120f3254bab0008c6f49a0573f35a1a700b0 Mon Sep 17 00:00:00 2001 From: reyraa Date: Sat, 28 Oct 2023 13:41:48 +0200 Subject: [PATCH 05/10] Update badges on vote --- .../transactionProcessor/anchor/create.js | 32 +++++++++++++ .../transactionProcessor/anchor/vote.js | 45 +++++++++++++++++++ 2 files changed, 77 insertions(+) diff --git a/services/blockchain-indexer/shared/indexer/transactionProcessor/anchor/create.js b/services/blockchain-indexer/shared/indexer/transactionProcessor/anchor/create.js index 7ed6c2d3b..ebfdec2e7 100644 --- a/services/blockchain-indexer/shared/indexer/transactionProcessor/anchor/create.js +++ b/services/blockchain-indexer/shared/indexer/transactionProcessor/anchor/create.js @@ -14,6 +14,7 @@ const MYSQL_ENDPOINT = config.endpoints.mysql; const accountsTableSchema = require('../../../database/schema/accounts'); const anchorsTableSchema = require('../../../database/schema/anchors'); const imagesTableSchema = require('../../../database/schema/images'); +const badgesTableSchema = require('../../../database/schema/badges'); const { MODULE_NAME_ANCHOR, EVENT_NAME_ANCHOR_CREATED, @@ -38,6 +39,12 @@ const getImagesTable = () => getTableInstance( MYSQL_ENDPOINT, ); +const getBadgesTable = () => getTableInstance( + badgesTableSchema.tableName, + badgesTableSchema, + MYSQL_ENDPOINT, +); + // Command specific constants const COMMAND_NAME = 'create'; @@ -55,6 +62,7 @@ const applyTransaction = async (blockHeader, tx, events, dbTrx) => { const accountsTable = await getAccountsTable(); const anchorsTable = await getAnchorsTable(); const imagesTable = await getImagesTable(); + const badgesTable = await getBadgesTable(); // Use event data to get anchorID const eventData = events.find( @@ -105,6 +113,30 @@ const applyTransaction = async (blockHeader, tx, events, dbTrx) => { await anchorsTable.upsert(anchorsNFT, dbTrx); logger.debug(`Indexed anchor with ID ${anchorCreatedData.anchorID}.`); + + const badge = await badgesTable.find({ badgeID: anchorCreatedData.badgeIDs[0] }); + if (!badge.length) { + await BluebirdPromise.map( + anchorCreatedData.badgeIDs, + async (badgeID, index) => { + const badgeInfo = { + badgeID, + anchorID: '', + awardedTo: '', + type: 'anchor_of_the_day', + awardDate: anchorCreatedData.createdAt, + rank: BigInt(index + 1), + prize: BigInt(0), + claimed: false, + }; + logger.trace(`Updating badge index for the badgeID ${badgeID}.`); + await badgesTable.upsert(badgeInfo, dbTrx); + logger.debug(`Updated badge index for the badgeID ${badgeID}.`); + return true; + }, + { concurrency: anchorCreatedData.badgeIDs.length }, + ); + } return true; }; diff --git a/services/blockchain-indexer/shared/indexer/transactionProcessor/anchor/vote.js b/services/blockchain-indexer/shared/indexer/transactionProcessor/anchor/vote.js index d1c11bac2..94fbbf5c7 100644 --- a/services/blockchain-indexer/shared/indexer/transactionProcessor/anchor/vote.js +++ b/services/blockchain-indexer/shared/indexer/transactionProcessor/anchor/vote.js @@ -2,6 +2,7 @@ const { Logger, MySQL: { getTableInstance }, } = require('lisk-service-framework'); +const BluebirdPromise = require('bluebird'); const config = require('../../../../config'); const { getLisk32AddressFromPublicKey } = require('../../../utils/account'); @@ -10,9 +11,12 @@ const logger = Logger(); const MYSQL_ENDPOINT = config.endpoints.mysql; const votesTableSchema = require('../../../database/schema/votes'); +const anchorsTableSchema = require('../../../database/schema/anchors'); +const badgesTableSchema = require('../../../database/schema/badges'); const { MODULE_NAME_ANCHOR, + EVENT_NAME_ANCHOR_VOTED, EVENT_NAME_COMMAND_EXECUTION_RESULT, } = require('../../../../../blockchain-connector/shared/sdk/constants/names'); @@ -22,11 +26,24 @@ const getVotesTable = () => getTableInstance( MYSQL_ENDPOINT, ); +const getAnchorsTable = () => getTableInstance( + anchorsTableSchema.tableName, + anchorsTableSchema, + MYSQL_ENDPOINT, +); + +const getBadgesTable = () => getTableInstance( + badgesTableSchema.tableName, + badgesTableSchema, + MYSQL_ENDPOINT, +); + // Command specific constants const COMMAND_NAME = 'vote'; // eslint-disable-next-line no-unused-vars const applyTransaction = async (blockHeader, tx, events, dbTrx) => { + // Do not process failed transactions const { data: commandExecutedData = {} } = events.find( ({ module, name }) => module === MODULE_NAME_ANCHOR && name === EVENT_NAME_COMMAND_EXECUTION_RESULT, @@ -35,7 +52,15 @@ const applyTransaction = async (blockHeader, tx, events, dbTrx) => { return false; } + const eventData = events.find( + ({ module, name }) => module === MODULE_NAME_ANCHOR + && name === EVENT_NAME_ANCHOR_VOTED, + ); + const { data: anchorVotedData } = eventData || { data: {} }; + const votesTable = await getVotesTable(); + const anchorsTable = await getAnchorsTable(); + const badgesTable = await getBadgesTable(); const { anchorID } = tx.params; @@ -49,6 +74,26 @@ const applyTransaction = async (blockHeader, tx, events, dbTrx) => { await votesTable.upsert(vote, dbTrx); logger.debug(`Indexed vote with transaction ID ${dbTrx.id}.`); + const [anchor] = await anchorsTable.find( + { anchorID }, + ['createdAt'], + dbTrx); + await BluebirdPromise.map( + anchorVotedData.updatedWinners, + async (winner, index) => { + const { anchorID: winningAnchorID, awardedTo } = winner; + const [badge] = await badgesTable.find( + { awardDate: anchor.createdAt, rank: index + 1 }, + ['badgeID', 'anchorID', 'awardedTo', 'type', 'awardDate', 'rank', 'prize', 'claimed'], + dbTrx, + ); + + badge.anchorID = winningAnchorID; + badge.awardedTo = awardedTo; + + await badgesTable.upsert(badge, dbTrx); + }, + { concurrency: anchorVotedData.updatedWinners.length }); return true; }; From 1a4cf836b416f4e4c03c6aaf73ec2d060aa72494 Mon Sep 17 00:00:00 2001 From: curvesy Date: Thu, 2 Nov 2023 20:25:54 +0330 Subject: [PATCH 06/10] Add limit and ofset to the gateway version3 api params --- services/gateway/apis/http-version3/methods/anchors.js | 2 +- services/gateway/apis/http-version3/methods/badges.js | 6 ++++-- services/gateway/shared/regex.js | 2 ++ 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/services/gateway/apis/http-version3/methods/anchors.js b/services/gateway/apis/http-version3/methods/anchors.js index 45b2f2d91..aa9555cfb 100644 --- a/services/gateway/apis/http-version3/methods/anchors.js +++ b/services/gateway/apis/http-version3/methods/anchors.js @@ -10,7 +10,7 @@ module.exports = { tags: ['Anchors'], params: { submitter: { optional: true, type: 'string', min: 3, max: 41, pattern: regex.ADDRESS_LISK32 }, - anchorID: { optional: true, type: 'string', min: 1, max: 64, pattern: regex.HASH_SHA256 }, + anchorID: { optional: true, type: 'string', min: 1, max: 64, pattern: regex.MD5 }, search: { optional: true, type: 'string' }, limit: { optional: true, type: 'number', min: 1, max: 100, default: 10 }, offset: { optional: true, type: 'number', min: 0, default: 0 }, diff --git a/services/gateway/apis/http-version3/methods/badges.js b/services/gateway/apis/http-version3/methods/badges.js index ca384ce3f..ca9064ad6 100644 --- a/services/gateway/apis/http-version3/methods/badges.js +++ b/services/gateway/apis/http-version3/methods/badges.js @@ -26,9 +26,11 @@ module.exports = { tags: ['Badges'], params: { awardedTo: { optional: true, type: 'string', min: 3, max: 41, pattern: regex.ADDRESS_LISK32 }, - badgeID: { optional: true, type: 'string', min: 1, max: 64, pattern: regex.HASH_SHA256 }, - anchorID: { optional: true, type: 'string', min: 1, max: 64, pattern: regex.HASH_SHA256 }, + badgeID: { optional: true, type: 'string', min: 1, max: 64, pattern: regex.MD5 }, + anchorID: { optional: true, type: 'string', min: 1, max: 64, pattern: regex.MD5 }, type: { optional: true, type: 'string' }, + limit: { optional: true, type: 'number', min: 1, max: 100, default: 10 }, + offset: { optional: true, type: 'number', min: 0, default: 0 }, }, get schema() { const badgeSchema = {}; diff --git a/services/gateway/shared/regex.js b/services/gateway/shared/regex.js index 3249368d7..822c793a0 100644 --- a/services/gateway/shared/regex.js +++ b/services/gateway/shared/regex.js @@ -53,6 +53,7 @@ const TOPIC_CSV = /^\b(?:[0-9a-fA-F]{2,64}|lsk[a-hjkm-z2-9]{38})(?:,(?:[0-9a-fA- const HEX_STRING = /^\b[a-fA-F0-9]+\b$/; const EXCEL_EXPORT_FILENAME = /^\btransactions_([a-fA-F0-9]{8})_(lsk[a-hjkm-z2-9]{38})_((\d{4})-((1[012])|(0?[1-9]))-(([012][1-9])|([123]0)|31))_((\d{4})-((1[012])|(0?[1-9]))-(([012][1-9])|([123]0)|31))\.xlsx\b$/; const EVENT_NAME = /^[\w!@$&. ]{1,32}$/; +const MD5 = /^\b[a-fA-F0-9]{32}\b$/; // MD5 pattern module.exports = { PUBLIC_KEY, @@ -95,4 +96,5 @@ module.exports = { FEE, EXCEL_EXPORT_FILENAME, EVENT_NAME, + MD5, }; From 0be71acd9c6446d208ee5fb9ac17d0b902a7ea26 Mon Sep 17 00:00:00 2001 From: reyraa Date: Sun, 12 Nov 2023 16:18:36 +0100 Subject: [PATCH 07/10] Add support for the winner parameter --- .../methods/dataService/modules/anchor.js | 1 + .../shared/dataService/anchors.js | 1 + .../shared/dataService/business/anchors.js | 57 +++++++++++++++---- .../apis/http-version3/methods/anchors.js | 1 + .../swagger/parameters/anchors.json | 10 ++++ 5 files changed, 59 insertions(+), 11 deletions(-) diff --git a/services/blockchain-indexer/methods/dataService/modules/anchor.js b/services/blockchain-indexer/methods/dataService/modules/anchor.js index b2cafccf3..16f2dc472 100644 --- a/services/blockchain-indexer/methods/dataService/modules/anchor.js +++ b/services/blockchain-indexer/methods/dataService/modules/anchor.js @@ -11,6 +11,7 @@ module.exports = [ anchorID: { optional: true, type: 'string' }, limit: { optional: true, type: 'number' }, offset: { optional: true, type: 'number' }, + winner: { optional: true, type: 'number' }, }, }, ]; diff --git a/services/blockchain-indexer/shared/dataService/anchors.js b/services/blockchain-indexer/shared/dataService/anchors.js index 1ef401153..eeeed3435 100644 --- a/services/blockchain-indexer/shared/dataService/anchors.js +++ b/services/blockchain-indexer/shared/dataService/anchors.js @@ -9,6 +9,7 @@ const getAnchors = async params => { // Store logs if (params.anchorID) logger.debug(`Retrieved anchor with ID ${params.anchorID} from Lisk Core`); else if (params.submitter) logger.debug(`Retrieved anchor with submitter: ${params.submitter} from Lisk Core`); + else if (params.winner) logger.debug('Retrieved winner anchors from Lisk Core'); else logger.debug(`Retrieved anchors with custom search: ${util.inspect(params)} from Lisk Core`); // Get data from server diff --git a/services/blockchain-indexer/shared/dataService/business/anchors.js b/services/blockchain-indexer/shared/dataService/business/anchors.js index fdcfb0a90..f238609a5 100644 --- a/services/blockchain-indexer/shared/dataService/business/anchors.js +++ b/services/blockchain-indexer/shared/dataService/business/anchors.js @@ -6,6 +6,7 @@ const BluebirdPromise = require('bluebird'); const transactionsIndexSchema = require('../../database/schema/anchors'); const imagesIndexSchema = require('../../database/schema/images'); const votesIndexSchema = require('../../database/schema/votes'); +const badgesIndexSchema = require('../../database/schema/badges'); const config = require('../../../config'); const MYSQL_ENDPOINT = config.endpoints.mysql; @@ -28,25 +29,59 @@ const getVotesIndex = () => getTableInstance( MYSQL_ENDPOINT, ); +const getBadgesIndex = () => getTableInstance( + badgesIndexSchema.tableName, + badgesIndexSchema, + MYSQL_ENDPOINT, +); + const getAnchors = async (params = {}) => { const anchorsTable = await getAnchorsIndex(); const imagesTable = await getImagesIndex(); const votesTable = await getVotesIndex(); + const badgesTable = await getBadgesIndex(); + + let anchorData = []; + + const { winner, ...restParams } = params; - if (params.search) { - const { search, ...remParams } = params; - params = remParams; + if (winner !== undefined) { + const response = await badgesTable.find( + { ...restParams, limit: restParams.limit || 10 }, + ['anchorID'], + ); - params.search = { - property: 'name', - pattern: search, - }; + const anchorIDs = response.map((badge) => badge.anchorID).filter(badgeID => badgeID); + + const res = await BluebirdPromise.map( + anchorIDs, + async (anchorID) => { + const anchorsData = await anchorsTable.find( + { anchorID }, + ['anchorID', 'name', 'album', 'artists', 'spotifyId', 'appleMusicId', 'createdAt', 'submitter'], + ); + return anchorsData.length ? anchorsData[0] : null; + }, + { concurrency: anchorIDs.length }, + ); + anchorData = res.filter(anchor => anchor); + } else { + if (restParams.search) { + const { search, ...remParams } = restParams; + params = remParams; + + params.search = { + property: 'name', + pattern: search, + }; + } + + anchorData = await anchorsTable.find( + { ...params, limit: params.limit || 10 }, + ['anchorID', 'name', 'album', 'artists', 'spotifyId', 'appleMusicId', 'createdAt', 'submitter'], + ); } - const anchorData = await anchorsTable.find( - { ...params, limit: params.limit || 10 }, - ['anchorID', 'name', 'album', 'artists', 'spotifyId', 'appleMusicId', 'createdAt', 'submitter'], - ); const total = anchorData.length; const data = await BluebirdPromise.map( diff --git a/services/gateway/apis/http-version3/methods/anchors.js b/services/gateway/apis/http-version3/methods/anchors.js index aa9555cfb..dbb832d4c 100644 --- a/services/gateway/apis/http-version3/methods/anchors.js +++ b/services/gateway/apis/http-version3/methods/anchors.js @@ -14,6 +14,7 @@ module.exports = { search: { optional: true, type: 'string' }, limit: { optional: true, type: 'number', min: 1, max: 100, default: 10 }, offset: { optional: true, type: 'number', min: 0, default: 0 }, + winner: { optional: true, type: 'number', min: 0, max: 1, default: 0 }, }, get schema() { const anchorSchema = {}; diff --git a/services/gateway/apis/http-version3/swagger/parameters/anchors.json b/services/gateway/apis/http-version3/swagger/parameters/anchors.json index 071f347a0..ade4878f3 100644 --- a/services/gateway/apis/http-version3/swagger/parameters/anchors.json +++ b/services/gateway/apis/http-version3/swagger/parameters/anchors.json @@ -15,5 +15,15 @@ "format": "id", "minLength": 1, "maxLength": 64 + }, + "winner": { + "name": "winner", + "in": "query", + "description": "Filter anchors by winning status.", + "type": "integer", + "format": "int32", + "minimum": 0, + "maximum": 1, + "default": 0 } } From e74460af4f5b6e560d76beec734adc3435fb8390 Mon Sep 17 00:00:00 2001 From: curvesy Date: Sun, 12 Nov 2023 21:30:33 +0330 Subject: [PATCH 08/10] update prize in vote command --- .../shared/indexer/transactionProcessor/anchor/vote.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/services/blockchain-indexer/shared/indexer/transactionProcessor/anchor/vote.js b/services/blockchain-indexer/shared/indexer/transactionProcessor/anchor/vote.js index 94fbbf5c7..fa925e1bf 100644 --- a/services/blockchain-indexer/shared/indexer/transactionProcessor/anchor/vote.js +++ b/services/blockchain-indexer/shared/indexer/transactionProcessor/anchor/vote.js @@ -81,7 +81,7 @@ const applyTransaction = async (blockHeader, tx, events, dbTrx) => { await BluebirdPromise.map( anchorVotedData.updatedWinners, async (winner, index) => { - const { anchorID: winningAnchorID, awardedTo } = winner; + const { anchorID: winningAnchorID, awardedTo, prize } = winner; const [badge] = await badgesTable.find( { awardDate: anchor.createdAt, rank: index + 1 }, ['badgeID', 'anchorID', 'awardedTo', 'type', 'awardDate', 'rank', 'prize', 'claimed'], @@ -90,6 +90,7 @@ const applyTransaction = async (blockHeader, tx, events, dbTrx) => { badge.anchorID = winningAnchorID; badge.awardedTo = awardedTo; + badge.prize = prize; await badgesTable.upsert(badge, dbTrx); }, From 1ac62e4bb562ec9569d51532ba8d69f7437a9db0 Mon Sep 17 00:00:00 2001 From: reyraa Date: Wed, 15 Nov 2023 11:22:06 +0100 Subject: [PATCH 09/10] Fix winner parameter --- .../shared/dataService/business/anchors.js | 15 ++++++--------- services/gateway/sources/version3/anchors.js | 1 + 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/services/blockchain-indexer/shared/dataService/business/anchors.js b/services/blockchain-indexer/shared/dataService/business/anchors.js index f238609a5..eb525b55e 100644 --- a/services/blockchain-indexer/shared/dataService/business/anchors.js +++ b/services/blockchain-indexer/shared/dataService/business/anchors.js @@ -43,9 +43,9 @@ const getAnchors = async (params = {}) => { let anchorData = []; - const { winner, ...restParams } = params; + const { winner, search, ...restParams } = params; - if (winner !== undefined) { + if (winner === 1) { const response = await badgesTable.find( { ...restParams, limit: restParams.limit || 10 }, ['anchorID'], @@ -66,18 +66,15 @@ const getAnchors = async (params = {}) => { ); anchorData = res.filter(anchor => anchor); } else { - if (restParams.search) { - const { search, ...remParams } = restParams; - params = remParams; - - params.search = { + if (search) { + restParams.search = { property: 'name', pattern: search, }; } anchorData = await anchorsTable.find( - { ...params, limit: params.limit || 10 }, + { ...restParams, limit: restParams.limit || 10 }, ['anchorID', 'name', 'album', 'artists', 'spotifyId', 'appleMusicId', 'createdAt', 'submitter'], ); } @@ -110,7 +107,7 @@ const getAnchors = async (params = {}) => { data, meta: { count: data.length, - offset: parseInt(params.offset, 10) || 0, + offset: parseInt(restParams.offset, 10) || 0, total, }, }; diff --git a/services/gateway/sources/version3/anchors.js b/services/gateway/sources/version3/anchors.js index c142f735c..93ac5b602 100644 --- a/services/gateway/sources/version3/anchors.js +++ b/services/gateway/sources/version3/anchors.js @@ -17,6 +17,7 @@ module.exports = { senderAddress: '=,string', }], search: '=,string', + winner: '=,number', limit: '=,number', offset: '=,number', sort: '=,string', From f7873d971c1c9dbdb146b39e184068de42fd995a Mon Sep 17 00:00:00 2001 From: reyraa Date: Wed, 15 Nov 2023 20:34:16 +0100 Subject: [PATCH 10/10] Add apple music and spotify IDs to the anchors reponse --- services/gateway/sources/version3/anchors.js | 2 ++ services/gateway/sources/version3/mappings/anchor.js | 2 ++ 2 files changed, 4 insertions(+) diff --git a/services/gateway/sources/version3/anchors.js b/services/gateway/sources/version3/anchors.js index 93ac5b602..2d2104c62 100644 --- a/services/gateway/sources/version3/anchors.js +++ b/services/gateway/sources/version3/anchors.js @@ -8,6 +8,8 @@ module.exports = { name: '=,string', album: '=,string', artists: '=,string', + spotifyId: '=,string', + appleMusicId: '=,string', images: ['images', { url: '=,string', width: '=,number', diff --git a/services/gateway/sources/version3/mappings/anchor.js b/services/gateway/sources/version3/mappings/anchor.js index e67b77c14..3a97f9a09 100644 --- a/services/gateway/sources/version3/mappings/anchor.js +++ b/services/gateway/sources/version3/mappings/anchor.js @@ -2,6 +2,8 @@ module.exports = { anchorID: '=,string', name: '=,string', album: '=,string', + spotifyId: '=,string', + appleMusicId: '=,string', artists: '=,string', submitter: '=,string', createdAt: '=,string',