diff --git a/packages/api/README.md b/packages/api/README.md index 0ef824912..372205a2e 100644 --- a/packages/api/README.md +++ b/packages/api/README.md @@ -67,6 +67,7 @@ Reference: * [Transfers by Identity](#transfers-by-identity) * [Transactions history](#transactions-history) * [Rate](#rate) +* [Search](#search) * [Decode Raw Transaction](#decode-raw-transaction) ### Status @@ -546,7 +547,8 @@ GET /transaction/DEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEE aliases: [ { alias: "alias.dash", - status: "locked" + status: "locked", + contested: true } ] } @@ -598,7 +600,8 @@ GET /transactions?=1&limit=10&order=asc&owner=6q9RFbeea73tE31LGMBLFZhtBUX3wZL3Tc aliases: [ { alias: "alias.dash", - status: "locked" + status: "locked", + contested: true } ] } @@ -753,7 +756,8 @@ GET /identity/GWRSAVFMjXx8HpQFaNJMqBV7MBgMK4br5UESsB4S31Ec aliases: [ { alias: "alias.dash", - status: "locked" + status: "locked", + contested: true } ] } @@ -770,10 +774,17 @@ Return identity by given DPNS/alias ``` GET /dpns/identity?dpns=canuseethat2.dash -{ - "identity_identifier": "8eTDkBhpQjHeqgbVeriwLeZr1tCa6yBGw76SckvD1cwc", - "alias": "canuseethat2.dash" -} +[ + { + "identity_identifier": "8eTDkBhpQjHeqgbVeriwLeZr1tCa6yBGw76SckvD1cwc", + "alias": "canuseethat2.dash", + "status": { + "alias": "canuseethat2.dash", + "contested": false, + "status": "ok" + } + } +] ``` Response codes: ``` @@ -812,7 +823,8 @@ GET /identities?page=1&limit=10&order=asc&order_by=block_height aliases: [ { alias: "alias.dash", - status: "locked" + status: "locked", + contested: true } ] }, ... @@ -999,6 +1011,78 @@ Response codes: 200: OK 500: Internal Server Error ``` +--- +### Search +This endpoint allows search any types of data + +* `query` required and must contains data for search +* Response may contain array for Identity and Data Contract when searching by part of field + +#### Can be found: +* Block + * Full `height` + * Full `hash` +* Transaction + * Full `hash` +* Validator + * Full `proTxHash` + * Full `Identifier` of Masternode Identity +* Identity + * Full `Identifier` + * Part `alias` +* Data Contract + * Full `Identifier` + * Part `name` +* Document + * Full `Identifier` + +``` +GET /search?query=xyz + +{ + "identities": [ + { + "identifier": "36LGwPSXef8q8wpdnx4EdDeVNuqCYNAE9boDu5bxytsm", + "alias": "xyz.dash", + "status": { + "alias": "xyz.dash", + "status": "ok", + "contested": true + } + }, + { + "identifier": "5bUPV8KGgL42ZBS9fsmmKU3wweQbVeHHsiVrG3YMHyG5", + "alias": "xyz.dash", + "status": { + "alias": "xyz.dash", + "status": "locked", + "contested": true + } + } + ] +} +``` + +``` +GET /search?query=36LGwPSXef8q8wpdnx4EdDeVNuqCYNAE9boDu5bxytsm + +{ + "identity": { + "identifier": "36LGwPSXef8q8wpdnx4EdDeVNuqCYNAE9boDu5bxytsm", + "alias": "xyz.dash", + "status": { + "alias": "xyz.dash", + "status": "ok", + "contested": true + } + } +} +``` +Response codes: +``` +200: OK +500: Internal Server Error +``` ### Transactions history Return a series data for the amount of transactions chart diff --git a/packages/api/src/controllers/IdentitiesController.js b/packages/api/src/controllers/IdentitiesController.js index e9529c847..c5c872772 100644 --- a/packages/api/src/controllers/IdentitiesController.js +++ b/packages/api/src/controllers/IdentitiesController.js @@ -26,7 +26,7 @@ class IdentitiesController { getIdentityByDPNSName = async (request, response) => { const { dpns } = request.query - const identity = await this.identitiesDAO.getIdentityByDPNSName(dpns) + const identity = await this.identitiesDAO.getIdentitiesByDPNSName(dpns) if (!identity) { return response.status(404).send({ message: 'not found' }) diff --git a/packages/api/src/controllers/MainController.js b/packages/api/src/controllers/MainController.js index 61ce772a6..c580fb3b9 100644 --- a/packages/api/src/controllers/MainController.js +++ b/packages/api/src/controllers/MainController.js @@ -6,6 +6,7 @@ const IdentitiesDAO = require('../dao/IdentitiesDAO') const ValidatorsDAO = require('../dao/ValidatorsDAO') const TenderdashRPC = require('../tenderdashRpc') const Epoch = require('../models/Epoch') +const { base58 } = require('@scure/base') const API_VERSION = require('../../package.json').version const PLATFORM_VERSION = '1' + require('../../package.json').dependencies.dash.substring(1) @@ -72,6 +73,8 @@ class MainController { search = async (request, response) => { const { query } = request.query + let result = {} + const epoch = Epoch.fromObject({ startTime: 0, endTime: 0 @@ -82,7 +85,7 @@ class MainController { const block = await this.blocksDAO.getBlockByHeight(query) if (block) { - return response.send({ block }) + result = { ...result, block } } } @@ -91,21 +94,21 @@ class MainController { const block = await this.blocksDAO.getBlockByHash(query) if (block) { - return response.send({ block }) + result = { ...result, block } } // search transactions const transaction = await this.transactionsDAO.getTransactionByHash(query) if (transaction) { - return response.send({ transaction }) + result = { ...result, transaction } } - // search validators + // search validators by hash const validator = await this.validatorsDAO.getValidatorByProTxHash(query, null, epoch) if (validator) { - return response.send({ validator }) + result = { ...result, validator } } } @@ -115,34 +118,52 @@ class MainController { const identity = await this.identitiesDAO.getIdentityByIdentifier(query) if (identity) { - return response.send({ identity }) + result = { ...result, identity } } - // search data contracts + // search validator by MasterNode identity + const proTxHash = Buffer.from(base58.decode(query)).toString('hex') + + const validator = await this.validatorsDAO.getValidatorByProTxHash(proTxHash, null, epoch) + + if (validator) { + result = { ...result, validator } + } + + // search data contract by id const dataContract = await this.dataContractsDAO.getDataContractByIdentifier(query) if (dataContract) { - return response.send({ dataContract }) + result = { ...result, dataContract } } // search documents const document = await this.documentsDAO.getDocumentByIdentifier(query) if (document) { - return response.send({ document }) + result = { ...result, document } } } // by dpns name - if (/^[^\s.]+(\.[^\s.]+)*$/.test(query)) { - const identity = await this.identitiesDAO.getIdentityByDPNSName(query) + const identities = await this.identitiesDAO.getIdentitiesByDPNSName(query) - if (identity) { - return response.send({ identity }) - } + if (identities) { + result = { ...result, identities } + } + + // by data-contract name + const dataContracts = await this.dataContractsDAO.getDataContractByName(query) + + if (dataContracts) { + result = { ...result, dataContracts } + } + + if (Object.keys(result).length === 0) { + response.status(404).send({ message: 'not found' }) } - response.status(404).send({ message: 'not found' }) + response.send(result) } } diff --git a/packages/api/src/dao/BlocksDAO.js b/packages/api/src/dao/BlocksDAO.js index 94d56c912..b329c6dee 100644 --- a/packages/api/src/dao/BlocksDAO.js +++ b/packages/api/src/dao/BlocksDAO.js @@ -1,7 +1,6 @@ const Block = require('../models/Block') const PaginatedResultSet = require('../models/PaginatedResultSet') -const { getAliasInfo } = require('../utils') -const { base58 } = require('@scure/base') +const { getAliasInfo, getAliasStateByVote } = require('../utils') const Transaction = require('../models/Transaction') module.exports = class BlockDAO { @@ -70,14 +69,7 @@ module.exports = class BlockDAO { const aliases = await Promise.all((row.aliases ?? []).map(async alias => { const aliasInfo = await getAliasInfo(alias, this.dapi) - const isLocked = base58.encode( - Buffer.from(aliasInfo.contestedState?.finishedVoteInfo?.wonByIdentityId ?? ''), - 'base64') !== row.identifier - - return { - alias, - status: (aliasInfo.contestedState !== null && isLocked) ? 'locked' : 'ok' - } + return getAliasStateByVote(aliasInfo, alias, row.owner) })) return Transaction.fromRow({ ...row, aliases }) diff --git a/packages/api/src/dao/DataContractsDAO.js b/packages/api/src/dao/DataContractsDAO.js index d66e46b80..17aeb5f5e 100644 --- a/packages/api/src/dao/DataContractsDAO.js +++ b/packages/api/src/dao/DataContractsDAO.js @@ -84,4 +84,30 @@ module.exports = class DataContractsDAO { return DataContract.fromRow(row) } + + getDataContractByName = async (name) => { + const rows = await this.knex('data_contracts') + .select( + 'data_contracts.identifier as identifier', 'data_contracts.name as name', + 'data_contracts.owner as owner', 'data_contracts.is_system as is_system', + 'data_contracts.version as version', 'data_contracts.schema as schema', + 'data_contracts.state_transition_hash as tx_hash', 'blocks.timestamp as timestamp' + ) + .select( + this.knex('documents') + .count('*') + .leftJoin('data_contracts', 'data_contracts.id', 'documents.data_contract_id') + .whereILike('data_contracts.name', `${name}%`) + .as('documents_count') + ) + .whereILike('data_contracts.name', `${name}%`) + .leftJoin('state_transitions', 'state_transitions.hash', 'data_contracts.state_transition_hash') + .leftJoin('blocks', 'state_transitions.block_hash', 'blocks.hash') + + if (rows.length === 0) { + return null + } + + return rows.map(row => DataContract.fromRow(row)) + } } diff --git a/packages/api/src/dao/IdentitiesDAO.js b/packages/api/src/dao/IdentitiesDAO.js index 0d01f3feb..c3064f4f3 100644 --- a/packages/api/src/dao/IdentitiesDAO.js +++ b/packages/api/src/dao/IdentitiesDAO.js @@ -5,8 +5,7 @@ const Document = require('../models/Document') const DataContract = require('../models/DataContract') const PaginatedResultSet = require('../models/PaginatedResultSet') const { IDENTITY_CREDIT_WITHDRAWAL } = require('../enums/StateTransitionEnum') -const { getAliasInfo } = require('../utils') -const { base58 } = require('@scure/base') +const { getAliasInfo, getAliasStateByVote } = require('../utils') module.exports = class IdentitiesDAO { constructor (knex, dapi) { @@ -81,14 +80,7 @@ module.exports = class IdentitiesDAO { const aliases = await Promise.all(identity.aliases.map(async alias => { const aliasInfo = await getAliasInfo(alias, this.dapi) - const isLocked = base58.encode( - Buffer.from(aliasInfo.contestedState?.finishedVoteInfo?.wonByIdentityId ?? '', 'base64') - ) !== identifier - - return { - alias, - status: (aliasInfo.contestedState !== null && isLocked) ? 'locked' : 'ok' - } + return getAliasStateByVote(aliasInfo, alias, identifier) })) return { @@ -98,17 +90,24 @@ module.exports = class IdentitiesDAO { } } - getIdentityByDPNSName = async (dpns) => { - const [identity] = await this.knex('identity_aliases') + getIdentitiesByDPNSName = async (dpns) => { + const rows = await this.knex('identity_aliases') .select('identity_identifier', 'alias') - .whereRaw(`LOWER(alias) LIKE LOWER('${dpns}${dpns.includes('.') ? '' : '.%'}')`) - .limit(1) + .whereILike('alias', `${dpns}%`) - if (!identity) { + if (rows.length === 0) { return null } - return { identifier: identity.identity_identifier, alias: identity.alias } + return Promise.all(rows.map(async row => { + const aliasInfo = await getAliasInfo(row.alias, this.dapi) + + return { + identifier: row.identity_identifier, + alias: row.alias, + status: getAliasStateByVote(aliasInfo, row.alias, row.identity_identifier) + } + })) } getIdentities = async (page, limit, order, orderBy) => { @@ -184,14 +183,7 @@ module.exports = class IdentitiesDAO { const aliases = await Promise.all((row.aliases ?? []).map(async alias => { const aliasInfo = await getAliasInfo(alias, this.dapi) - const isLocked = base58.encode( - Buffer.from(aliasInfo.contestedState?.finishedVoteInfo?.wonByIdentityId ?? ''), - 'base64') !== row.identifier - - return { - alias, - status: (aliasInfo.contestedState !== null && isLocked) ? 'locked' : 'ok' - } + return getAliasStateByVote(aliasInfo, alias, row.identifier.trim()) })) return Identity.fromRow({ diff --git a/packages/api/src/dao/TransactionsDAO.js b/packages/api/src/dao/TransactionsDAO.js index ec7cbd93d..3ce1c9d11 100644 --- a/packages/api/src/dao/TransactionsDAO.js +++ b/packages/api/src/dao/TransactionsDAO.js @@ -1,8 +1,7 @@ const Transaction = require('../models/Transaction') const PaginatedResultSet = require('../models/PaginatedResultSet') const SeriesData = require('../models/SeriesData') -const { getAliasInfo } = require('../utils') -const { base58 } = require('@scure/base') +const { getAliasInfo, getAliasStateByVote } = require('../utils') module.exports = class TransactionsDAO { constructor (knex, dapi) { @@ -36,14 +35,7 @@ module.exports = class TransactionsDAO { const aliases = await Promise.all((row.aliases ?? []).map(async alias => { const aliasInfo = await getAliasInfo(alias, this.dapi) - const isLocked = base58.encode( - Buffer.from(aliasInfo.contestedState?.finishedVoteInfo?.wonByIdentityId ?? ''), - 'base64') !== row.identifier - - return { - alias, - status: (aliasInfo.contestedState !== null && isLocked) ? 'locked' : 'ok' - } + return getAliasStateByVote(aliasInfo, alias, row.owner) })) return Transaction.fromRow({ ...row, aliases }) @@ -119,14 +111,7 @@ module.exports = class TransactionsDAO { const aliases = await Promise.all((row.aliases ?? []).map(async alias => { const aliasInfo = await getAliasInfo(alias, this.dapi) - const isLocked = base58.encode( - Buffer.from(aliasInfo.contestedState?.finishedVoteInfo?.wonByIdentityId ?? ''), - 'base64') !== row.identifier - - return { - alias, - status: (aliasInfo.contestedState !== null && isLocked) ? 'locked' : 'ok' - } + return getAliasStateByVote(aliasInfo, alias, row.owner) })) return Transaction.fromRow({ ...row, aliases }) diff --git a/packages/api/src/utils.js b/packages/api/src/utils.js index 1deb264f8..3b5ff70c4 100644 --- a/packages/api/src/utils.js +++ b/packages/api/src/utils.js @@ -417,6 +417,36 @@ const buildIndexBuffer = (name) => { ) } +const getAliasStateByVote = (aliasInfo, alias, identifier) => { + let status = null + + if (aliasInfo.contestedState === null) { + return { + alias, + status: 'ok', + contested: false + } + } + + const isLocked = base58.encode( + Buffer.from(aliasInfo.contestedState?.finishedVoteInfo?.wonByIdentityId ?? '', 'base64') + ) !== identifier + + if (isLocked) { + status = 'locked' + } else if (aliasInfo.contestedState?.finishedVoteInfo?.wonByIdentityId === undefined) { + status = 'pending' + } else { + status = 'ok' + } + + return { + alias, + status, + contested: true + } +} + const getAliasInfo = async (alias, dapi) => { const [label, domain] = alias.split('.') @@ -451,5 +481,6 @@ module.exports = { checkTcpConnect, calculateInterval, iso8601duration, - getAliasInfo + getAliasInfo, + getAliasStateByVote } diff --git a/packages/api/test/integration/identities.spec.js b/packages/api/test/integration/identities.spec.js index a452b86b9..65e0d702a 100644 --- a/packages/api/test/integration/identities.spec.js +++ b/packages/api/test/integration/identities.spec.js @@ -221,6 +221,7 @@ describe('Identities routes', () => { isSystem: false, aliases: [{ alias, + contested: false, status: 'ok' }] } @@ -307,10 +308,15 @@ describe('Identities routes', () => { const expectedIdentity = { identifier: identity.identifier, - alias + alias, + status: { + alias, + contested: false, + status: 'ok' + } } - assert.deepEqual(body, expectedIdentity) + assert.deepEqual(body, [expectedIdentity]) }) it('should return identity by dpns with any case', async () => { @@ -324,10 +330,15 @@ describe('Identities routes', () => { const expectedIdentity = { identifier: identity.identifier, - alias + alias, + status: { + alias, + contested: false, + status: 'ok' + } } - assert.deepEqual(body, expectedIdentity) + assert.deepEqual(body, [expectedIdentity]) }) it('should return 404 when identity not found', async () => { @@ -373,7 +384,7 @@ describe('Identities routes', () => { isSystem: false, aliases: [ aliases.find((_alias) => _alias.identity_identifier === _identity.identity.identifier).alias - ].map(alias => ({ alias, status: 'ok' })) + ].map(alias => ({ alias, status: 'ok', contested: false })) })) assert.deepEqual(body.resultSet, expectedIdentities) @@ -415,7 +426,7 @@ describe('Identities routes', () => { isSystem: false, aliases: [ aliases.find((_alias) => _alias.identity_identifier === _identity.identity.identifier).alias - ].map(alias => ({ alias, status: 'ok' })) + ].map(alias => ({ alias, status: 'ok', contested: false })) })) assert.deepEqual(body.resultSet, expectedIdentities) @@ -458,7 +469,7 @@ describe('Identities routes', () => { isSystem: false, aliases: [ aliases.find((_alias) => _alias.identity_identifier === _identity.identity.identifier).alias - ].map(alias => ({ alias, status: 'ok' })) + ].map(alias => ({ alias, status: 'ok', contested: false })) })) assert.deepEqual(body.resultSet, expectedIdentities) @@ -502,7 +513,7 @@ describe('Identities routes', () => { isSystem: false, aliases: [ aliases.find((_alias) => _alias.identity_identifier === _identity.identity.identifier).alias - ].map(alias => ({ alias, status: 'ok' })) + ].map(alias => ({ alias, status: 'ok', contested: false })) })) assert.deepEqual(body.resultSet, expectedIdentities) @@ -561,7 +572,7 @@ describe('Identities routes', () => { isSystem: false, aliases: [ aliases.find((_alias) => _alias.identity_identifier === _identity.identity.identifier).alias - ].map(alias => ({ alias, status: 'ok' })) + ].map(alias => ({ alias, status: 'ok', contested: false })) })) assert.deepEqual(body.resultSet, expectedIdentities) @@ -632,7 +643,7 @@ describe('Identities routes', () => { isSystem: false, aliases: [ aliases.find((_alias) => _alias.identity_identifier === _identity.identity.identifier).alias - ].map(alias => ({ alias, status: 'ok' })) + ].map(alias => ({ alias, status: 'ok', contested: false })) })) assert.deepEqual(body.resultSet, expectedIdentities) diff --git a/packages/api/test/integration/main.spec.js b/packages/api/test/integration/main.spec.js index 209805df2..feea231d3 100644 --- a/packages/api/test/integration/main.spec.js +++ b/packages/api/test/integration/main.spec.js @@ -90,7 +90,8 @@ describe('Other routes', () => { }) dataContract = await fixtures.dataContract(knex, { state_transition_hash: dataContractTransaction.hash, - owner: identity.identifier + owner: identity.identifier, + name: 'test' }) documentTransaction = await fixtures.transaction(knex, { @@ -174,6 +175,7 @@ describe('Other routes', () => { identifier: identityTransaction.owner, aliases: [{ alias: 'dpns.dash', + contested: false, status: 'ok' }] } @@ -193,7 +195,8 @@ describe('Other routes', () => { identifier: dataContractTransaction.owner, aliases: [{ alias: 'dpns.dash', - status: 'ok' + status: 'ok', + contested: false }] } }, @@ -212,7 +215,8 @@ describe('Other routes', () => { identifier: documentTransaction.owner, aliases: [{ alias: 'dpns.dash', - status: 'ok' + status: 'ok', + contested: false }] } } @@ -242,6 +246,7 @@ describe('Other routes', () => { identifier: dataContractTransaction.owner, aliases: [{ alias: identityAlias.alias, + contested: false, status: 'ok' }] } @@ -291,6 +296,26 @@ describe('Other routes', () => { assert.deepEqual({ dataContract: expectedDataContract }, body) }) + it('should search by data contract name', async () => { + const { body } = await client.get('/search?query=test') + .expect(200) + .expect('Content-Type', 'application/json; charset=utf-8') + + const expectedDataContract = { + identifier: dataContract.identifier, + name: dataContract.name, + owner: identity.identifier.trim(), + schema: JSON.stringify(dataContract.schema), + version: 0, + txHash: dataContractTransaction.hash, + timestamp: block.timestamp.toISOString(), + isSystem: false, + documentsCount: 1 + } + + assert.deepEqual({ dataContracts: [expectedDataContract] }, body) + }) + it('should search by identity DPNS', async () => { mock.method(DAPI.prototype, 'getIdentityBalance', async () => 0) @@ -298,12 +323,17 @@ describe('Other routes', () => { .expect(200) .expect('Content-Type', 'application/json; charset=utf-8') - const expectedIdentity = { + const expectedIdentity = [{ identifier: identity.identifier, - alias: identityAlias.alias - } + alias: identityAlias.alias, + status: { + alias: identityAlias.alias, + contested: false, + status: 'ok' + } + }] - assert.deepEqual({ identity: expectedIdentity }, body) + assert.deepEqual({ identities: expectedIdentity }, body) }) it('should search identity', async () => { @@ -325,6 +355,7 @@ describe('Other routes', () => { owner: identity.identifier, aliases: [{ alias: 'dpns.dash', + contested: false, status: 'ok' }] } diff --git a/packages/api/test/integration/transactions.spec.js b/packages/api/test/integration/transactions.spec.js index 552a58485..3dcc2639a 100644 --- a/packages/api/test/integration/transactions.spec.js +++ b/packages/api/test/integration/transactions.spec.js @@ -119,6 +119,7 @@ describe('Transaction routes', () => { identifier: transaction.transaction.owner, aliases: [{ alias: identityAlias.alias, + contested: false, status: 'ok' }] } @@ -127,7 +128,7 @@ describe('Transaction routes', () => { assert.deepEqual(expectedTransaction, body) }) - it('should error transaction', async () => { + it('should return error transaction', async () => { const [, transaction] = transactions const { body } = await client.get(`/transaction/${transaction.transaction.hash}`) .expect(200) @@ -148,6 +149,7 @@ describe('Transaction routes', () => { identifier: transaction.transaction.owner, aliases: [{ alias: identityAlias.alias, + contested: false, status: 'ok' }] } @@ -191,6 +193,7 @@ describe('Transaction routes', () => { identifier: transaction.transaction.owner, aliases: [{ alias: identityAlias.alias, + contested: false, status: 'ok' }] } @@ -227,6 +230,7 @@ describe('Transaction routes', () => { identifier: transaction.transaction.owner, aliases: [{ alias: identityAlias.alias, + contested: false, status: 'ok' }] } @@ -266,6 +270,7 @@ describe('Transaction routes', () => { identifier: transaction.transaction.owner, aliases: [{ alias: identityAlias.alias, + contested: false, status: 'ok' }] } @@ -305,6 +310,7 @@ describe('Transaction routes', () => { identifier: transaction.transaction.owner, aliases: [{ alias: identityAlias.alias, + contested: false, status: 'ok' }] } @@ -342,6 +348,7 @@ describe('Transaction routes', () => { identifier: transaction.transaction.owner, aliases: [{ alias: identityAlias.alias, + contested: false, status: 'ok' }] } @@ -379,6 +386,7 @@ describe('Transaction routes', () => { identifier: transaction.transaction.owner, aliases: [{ alias: identityAlias.alias, + contested: false, status: 'ok' }] } @@ -425,6 +433,7 @@ describe('Transaction routes', () => { identifier: transaction.transaction.owner, aliases: [{ alias: identityAlias.alias, + contested: false, status: 'ok' }] } @@ -461,6 +470,7 @@ describe('Transaction routes', () => { identifier: transaction.transaction.owner, aliases: [{ alias: identityAlias.alias, + contested: false, status: 'ok' }] } diff --git a/packages/frontend/src/app/api/content.md b/packages/frontend/src/app/api/content.md index d4bbdeb2a..2880c4357 100644 --- a/packages/frontend/src/app/api/content.md +++ b/packages/frontend/src/app/api/content.md @@ -34,6 +34,7 @@ Reference: * [Transfers by Identity](#transfers-by-identity) * [Transactions history](#transactions-history) * [Rate](#rate) +* [Search](#search) * [Decode Raw Transaction](#decode-raw-transaction) ### Status @@ -513,7 +514,8 @@ GET /transaction/DEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEE aliases: [ { alias: "alias.dash", - status: "locked" + status: "locked", + contested: true } ] } @@ -565,7 +567,8 @@ GET /transactions?=1&limit=10&order=asc&owner=6q9RFbeea73tE31LGMBLFZhtBUX3wZL3Tc aliases: [ { alias: "alias.dash", - status: "locked" + status: "locked", + contested: true } ] } @@ -720,7 +723,8 @@ GET /identity/GWRSAVFMjXx8HpQFaNJMqBV7MBgMK4br5UESsB4S31Ec aliases: [ { alias: "alias.dash", - status: "locked" + status: "locked", + contested: true } ] } @@ -737,10 +741,17 @@ Return identity by given DPNS/alias ``` GET /dpns/identity?dpns=canuseethat2.dash -{ - "identity_identifier": "8eTDkBhpQjHeqgbVeriwLeZr1tCa6yBGw76SckvD1cwc", - "alias": "canuseethat2.dash" -} +[ + { + "identity_identifier": "8eTDkBhpQjHeqgbVeriwLeZr1tCa6yBGw76SckvD1cwc", + "alias": "canuseethat2.dash", + "status": { + "alias": "canuseethat2.dash", + "contested": false, + "status": "ok" + } + } +] ``` Response codes: ``` @@ -779,7 +790,8 @@ GET /identities?page=1&limit=10&order=asc&order_by=block_height aliases: [ { alias: "alias.dash", - status: "locked" + status: "locked", + contested: true } ] }, ... @@ -966,6 +978,78 @@ Response codes: 200: OK 500: Internal Server Error ``` +--- +### Search +This endpoint allows search any types of data + +* `query` required and must contains data for search +* Response may contain array for Identity and Data Contract when searching by part of field + +#### Can be found: +* Block + * Full `height` + * Full `hash` +* Transaction + * Full `hash` +* Validator + * Full `proTxHash` + * Full `Identifier` of Masternode Identity +* Identity + * Full `Identifier` + * Part `alias` +* Data Contract + * Full `Identifier` + * Part `name` +* Document + * Full `Identifier` + +``` +GET /search?query=xyz + +{ + "identities": [ + { + "identifier": "36LGwPSXef8q8wpdnx4EdDeVNuqCYNAE9boDu5bxytsm", + "alias": "xyz.dash", + "status": { + "alias": "xyz.dash", + "status": "ok", + "contested": true + } + }, + { + "identifier": "5bUPV8KGgL42ZBS9fsmmKU3wweQbVeHHsiVrG3YMHyG5", + "alias": "xyz.dash", + "status": { + "alias": "xyz.dash", + "status": "locked", + "contested": true + } + } + ] +} +``` + +``` +GET /search?query=36LGwPSXef8q8wpdnx4EdDeVNuqCYNAE9boDu5bxytsm + +{ + "identity": { + "identifier": "36LGwPSXef8q8wpdnx4EdDeVNuqCYNAE9boDu5bxytsm", + "alias": "xyz.dash", + "status": { + "alias": "xyz.dash", + "status": "ok", + "contested": true + } + } +} +``` +Response codes: +``` +200: OK +500: Internal Server Error +``` ### Transactions history Return a series data for the amount of transactions chart