From d1e7b1de5db22911f7aeaf461328a2dbe9c5986a Mon Sep 17 00:00:00 2001 From: owl352 Date: Fri, 1 Nov 2024 01:21:50 +0300 Subject: [PATCH 01/35] work work work --- packages/api/.env | 1 + packages/api/src/DAPI.js | 41 +++++++-- packages/api/src/constants.js | 1 + .../src/controllers/IdentitiesController.js | 91 ++++++++++++++----- .../api/src/controllers/MainController.js | 63 +++++++++---- packages/api/src/models/Identity.js | 4 + packages/api/src/utils.js | 62 ++++++++++++- 7 files changed, 212 insertions(+), 51 deletions(-) diff --git a/packages/api/.env b/packages/api/.env index f784f739d..414941241 100644 --- a/packages/api/.env +++ b/packages/api/.env @@ -10,3 +10,4 @@ DASHCORE_PASS=password EPOCH_CHANGE_TIME=3600000 DAPI_URL=127.0.0.1:1443:self-signed TCP_CONNECT_TIMEOUT=400 +DPNS_CONTRACT=5mjGWa9mruHnLBht3ntbfgodcSoJxA1XIfYiv1PFMVU= diff --git a/packages/api/src/DAPI.js b/packages/api/src/DAPI.js index a2fc9ba64..955072d17 100644 --- a/packages/api/src/DAPI.js +++ b/packages/api/src/DAPI.js @@ -1,28 +1,53 @@ -const { Identifier } = require('dash').PlatformProtocol +const {Identifier} = require('dash').PlatformProtocol + +const { + v0: {GetDocumentsRequest}, +} = require('@dashevo/dapi-grpc'); class DAPI { dapi dpp - constructor (dapi, dpp) { + constructor(dapi, dpp) { this.dapi = dapi this.dpp = dpp } - async getIdentityBalance (identifier) { - const { balance } = await this.dapi.platform.getIdentityBalance(Identifier.from(identifier)) + async getIdentityBalance(identifier) { + const {balance} = await this.dapi.platform.getIdentityBalance(Identifier.from(identifier)) return balance } - async getTotalCredits () { - const { totalCreditsInPlatform } = await this.dapi.platform.getTotalCreditsInPlatform() + async getTotalCredits() { + const {totalCreditsInPlatform} = await this.dapi.platform.getTotalCreditsInPlatform() return totalCreditsInPlatform } - async getEpochsInfo (count, start, ascending) { - const { epochsInfo } = await this.dapi.platform.getEpochsInfo(start, count, { ascending }) + async getEpochsInfo(count, start, ascending) { + const {epochsInfo} = await this.dapi.platform.getEpochsInfo(start, count, {ascending}) return epochsInfo } + + async getContestedState(contractId, + documentTypeName, + indexName = 'parentNameAndLabel', + resultType = 2, + indexValuesList, startAtIdentifierInfo, + allowIncludeLockedAndAbstainingVoteTally, + count + ) { + const {contestedResourceContenders} = await this.dapi.platform.getContestedResourceVoteState( + Buffer.from(contractId, 'base64'), + documentTypeName, + indexName, + resultType, + indexValuesList, + startAtIdentifierInfo, + allowIncludeLockedAndAbstainingVoteTally, + count + ) + return contestedResourceContenders + } } module.exports = DAPI diff --git a/packages/api/src/constants.js b/packages/api/src/constants.js index 729ac0a23..72f606188 100644 --- a/packages/api/src/constants.js +++ b/packages/api/src/constants.js @@ -5,6 +5,7 @@ let genesisTime module.exports = { EPOCH_CHANGE_TIME: Number(process.env.EPOCH_CHANGE_TIME), TCP_CONNECT_TIMEOUT: Number(process.env.TCP_CONNECT_TIMEOUT), + DPNS_CONTRACT: process.env.DPNS_CONTRACT ?? '5mjGWa9mruHnLBht3ntbfgodcSoJxA1XIfYiv1PFMVU=', get genesisTime () { if (!genesisTime || isNaN(genesisTime)) { return TenderdashRPC.getBlockByHeight(1).then((blockInfo) => { diff --git a/packages/api/src/controllers/IdentitiesController.js b/packages/api/src/controllers/IdentitiesController.js index 0e6092fe1..8f41cc4f9 100644 --- a/packages/api/src/controllers/IdentitiesController.js +++ b/packages/api/src/controllers/IdentitiesController.js @@ -1,56 +1,99 @@ const IdentitiesDAO = require('../dao/IdentitiesDAO') -const { IDENTITY_CREDIT_WITHDRAWAL } = require('../enums/StateTransitionEnum') +const {IDENTITY_CREDIT_WITHDRAWAL} = require('../enums/StateTransitionEnum') +const {generateNormalizedLabelBuffer, getLabelBuffer, validateAliases} = require("../utils"); +const Identity = require("../models/Identity"); +const {base58} = require("@scure/base"); class IdentitiesController { - constructor (knex, dapi) { + constructor(knex, dapi) { this.identitiesDAO = new IdentitiesDAO(knex) this.dapi = dapi } getIdentityByIdentifier = async (request, response) => { - const { identifier } = request.params - - const identity = await this.identitiesDAO.getIdentityByIdentifier(identifier) + const {identifier} = request.params + let [identity] = await Promise.all([this.identitiesDAO.getIdentityByIdentifier(identifier)]) if (!identity) { - return response.status(404).send({ message: 'not found' }) + return response.status(404).send({message: 'not found'}) } + const validatedAliases = await validateAliases(identity.aliases, identity.identifier, this.dapi) + + identity = Identity.fromObject({...identity, aliases: validatedAliases}) + const balance = await this.dapi.getIdentityBalance(identifier) - response.send({ ...identity, balance }) + response.send({...identity, balance}) } + getIdentityByDPNS = async (request, response) => { - const { dpns } = request.query + const {dpns} = request.query + + let preIdentity + let identity - const identity = await this.identitiesDAO.getIdentityByDPNS(dpns) + let contestedState + + if (!dpns.includes('.')) { + preIdentity = await this.identitiesDAO.getIdentityByDPNS(dpns) + + if (!preIdentity) { + return response.status(404).send({message: 'not found'}) + } + } + + [{contestedState}] = await validateAliases( + [preIdentity ? preIdentity.aliases.find(v => v.includes(dpns)) : dpns], + null, + this.dapi + ) + + if (contestedState) { + if (typeof contestedState.finishedVoteInfo?.wonByIdentityId === 'string') { + const identifier = base58.encode(Buffer.from(contestedState.finishedVoteInfo?.wonByIdentityId, 'base64')) + + identity = await this.identitiesDAO.getIdentityByIdentifier(identifier) + } + } + + if (!contestedState) { + identity = preIdentity + } if (!identity) { - return response.status(404).send({ message: 'not found' }) + return response.status(404).send({message: 'not found'}) } const balance = await this.dapi.getIdentityBalance(identity.identifier) - response.send({ ...identity, balance }) + const validatedAliases = await validateAliases(identity.aliases, identity.identifier, this.dapi) + + identity = Identity.fromObject({...identity, aliases: validatedAliases}) + + response.send({...identity, balance}) } getIdentities = async (request, response) => { - const { page = 1, limit = 10, order = 'asc', order_by: orderBy = 'block_height' } = request.query + const {page = 1, limit = 10, order = 'asc', order_by: orderBy = 'block_height'} = request.query const identities = await this.identitiesDAO.getIdentities(Number(page ?? 1), Number(limit ?? 10), order, orderBy) const identitiesWithBalance = await Promise.all(identities.resultSet.map(async identity => { const balance = await this.dapi.getIdentityBalance(identity.identifier) - return { ...identity, balance } + + const validatedAliases = await validateAliases(identity.aliases, identity.identifier, this.dapi) + + return {...identity, aliases: validatedAliases, balance} })) - response.send({ ...identities, resultSet: identitiesWithBalance }) + response.send({...identities, resultSet: identitiesWithBalance}) } getTransactionsByIdentity = async (request, response) => { - const { identifier } = request.params - const { page = 1, limit = 10, order = 'asc' } = request.query + const {identifier} = request.params + const {page = 1, limit = 10, order = 'asc'} = request.query const transactions = await this.identitiesDAO.getTransactionsByIdentity(identifier, Number(page ?? 1), Number(limit ?? 10), order) @@ -58,8 +101,8 @@ class IdentitiesController { } getDataContractsByIdentity = async (request, response) => { - const { identifier } = request.params - const { page = 1, limit = 10, order = 'asc' } = request.query + const {identifier} = request.params + const {page = 1, limit = 10, order = 'asc'} = request.query const dataContracts = await this.identitiesDAO.getDataContractsByIdentity(identifier, Number(page ?? 1), Number(limit ?? 10), order) @@ -67,8 +110,8 @@ class IdentitiesController { } getDocumentsByIdentity = async (request, response) => { - const { identifier } = request.params - const { page = 1, limit = 10, order = 'asc' } = request.query + const {identifier} = request.params + const {page = 1, limit = 10, order = 'asc'} = request.query const documents = await this.identitiesDAO.getDocumentsByIdentity(identifier, Number(page ?? 1), Number(limit ?? 10), order) @@ -76,8 +119,8 @@ class IdentitiesController { } getTransfersByIdentity = async (request, response) => { - const { identifier } = request.params - const { page = 1, limit = 10, order = 'asc', type = undefined } = request.query + const {identifier} = request.params + const {page = 1, limit = 10, order = 'asc', type = undefined} = request.query const transfers = await this.identitiesDAO.getTransfersByIdentity(identifier, Number(page ?? 1), Number(limit ?? 10), order, type) @@ -85,8 +128,8 @@ class IdentitiesController { } getWithdrawalsByIdentity = async (request, response) => { - const { identifier } = request.params - const { page = 1, limit = 10, order = 'asc' } = request.query + const {identifier} = request.params + const {page = 1, limit = 10, order = 'asc'} = request.query const withdrawals = await this.identitiesDAO.getTransfersByIdentity( identifier, diff --git a/packages/api/src/controllers/MainController.js b/packages/api/src/controllers/MainController.js index bbe3b6590..7a7aa28a6 100644 --- a/packages/api/src/controllers/MainController.js +++ b/packages/api/src/controllers/MainController.js @@ -6,12 +6,14 @@ const IdentitiesDAO = require('../dao/IdentitiesDAO') const ValidatorsDAO = require('../dao/ValidatorsDAO') const TenderdashRPC = require('../tenderdashRpc') const Epoch = require('../models/Epoch') +const {validateAliases} = require("../utils"); +const {base58} = require("@scure/base"); const API_VERSION = require('../../package.json').version const PLATFORM_VERSION = '1' + require('../../package.json').dependencies.dash.substring(1) class MainController { - constructor (knex, dapi) { + constructor(knex, dapi) { this.blocksDAO = new BlocksDAO(knex) this.dataContractsDAO = new DataContractsDAO(knex) this.documentsDAO = new DocumentsDAO(knex) @@ -70,7 +72,7 @@ class MainController { } search = async (request, response) => { - const { query } = request.query + const {query} = request.query const epoch = Epoch.fromObject({ startTime: 0, @@ -82,7 +84,7 @@ class MainController { const block = await this.blocksDAO.getBlockByHeight(query) if (block) { - return response.send({ block }) + return response.send({block}) } } @@ -91,21 +93,21 @@ class MainController { const block = await this.blocksDAO.getBlockByHash(query) if (block) { - return response.send({ block }) + return response.send({block}) } // search transactions const transaction = await this.transactionsDAO.getTransactionByHash(query) if (transaction) { - return response.send({ transaction }) + return response.send({transaction}) } // search validators const validator = await this.validatorsDAO.getValidatorByProTxHash(query, null, epoch) if (validator) { - return response.send({ validator }) + return response.send({validator}) } } @@ -115,37 +117,66 @@ class MainController { const identity = await this.identitiesDAO.getIdentityByIdentifier(query) if (identity) { - const balance = await this.dapi.getIdentityBalance(identity.identifier) - - return response.send({ identity: { ...identity, balance } }) + // Sending without actual balance and aliases, because on frontend we were making + // request /identity/:identifier for actual data + return response.send({identity}) } // search data contracts const dataContract = await this.dataContractsDAO.getDataContractByIdentifier(query) if (dataContract) { - return response.send({ dataContract }) + return response.send({dataContract}) } // search documents const document = await this.documentsDAO.getDocumentByIdentifier(query) if (document) { - return response.send({ document }) + return response.send({document}) } } if (/^[^\s.]+(\.[^\s.]+)*$/.test(query)) { - const identity = await this.identitiesDAO.getIdentityByDPNS(query) + let preIdentity + let identity - if (identity) { - const balance = await this.dapi.getIdentityBalance(identity.identifier) + let contestedState + + if (!query.includes('.')) { + preIdentity = await this.identitiesDAO.getIdentityByDPNS(query) + + if (!preIdentity) { + return response.status(404).send({message: 'not found'}) + } + } + + [{contestedState}] = await validateAliases( + [preIdentity ? preIdentity.aliases.find(v => v.includes(query)) : query], + null, + this.dapi + ) - return response.send({ identity: { ...identity, balance } }) + if (contestedState) { + if (typeof contestedState.finishedVoteInfo?.wonByIdentityId === 'string') { + const identifier = base58.encode(Buffer.from(contestedState.finishedVoteInfo?.wonByIdentityId, 'base64')) + + identity = await this.identitiesDAO.getIdentityByIdentifier(identifier) + } + } + + if (!contestedState) { + identity = preIdentity + } + + if (identity) { + // Sending without actual balance and aliases, because on frontend we were making + // request /identity/:identifier for actual data + return response.send({identity}) } } - response.status(404).send({ message: 'not found' }) + response.status(404).send({message: 'not found'}) } } diff --git a/packages/api/src/models/Identity.js b/packages/api/src/models/Identity.js index ddfd01e6d..1456ca6ee 100644 --- a/packages/api/src/models/Identity.js +++ b/packages/api/src/models/Identity.js @@ -30,4 +30,8 @@ module.exports = class Identity { static fromRow ({ identifier, owner, revision, balance, timestamp, total_txs, total_data_contracts, total_documents, total_transfers, tx_hash, is_system, aliases }) { return new Identity(identifier, owner, revision, Number(balance), timestamp, Number(total_txs), Number(total_data_contracts), Number(total_documents), Number(total_transfers), tx_hash, is_system, aliases) } + + static fromObject({identifier, owner, revision, balance, timestamp, totalTxs, totalDataContracts, totalDocuments, totalTransfers, txHash, isSystem, aliases}){ + return new Identity(identifier, owner, revision, balance, timestamp, totalTxs, totalDataContracts, totalDocuments, totalTransfers, txHash, isSystem, aliases) + } } diff --git a/packages/api/src/utils.js b/packages/api/src/utils.js index f07c5a48c..69a928fc2 100644 --- a/packages/api/src/utils.js +++ b/packages/api/src/utils.js @@ -1,7 +1,8 @@ const crypto = require('crypto') const StateTransitionEnum = require('./enums/StateTransitionEnum') const net = require('net') -const { TCP_CONNECT_TIMEOUT } = require('./constants') +const {TCP_CONNECT_TIMEOUT, DPNS_CONTRACT} = require('./constants') +const {base58} = require("@scure/base"); const getKnex = () => { return require('knex')({ @@ -12,7 +13,7 @@ const getKnex = () => { user: process.env.POSTGRES_USER, database: process.env.POSTGRES_DB, password: process.env.POSTGRES_PASS, - ssl: process.env.POSTGRES_SSL ? { rejectUnauthorized: false } : false + ssl: process.env.POSTGRES_SSL ? {rejectUnauthorized: false} : false } }) } @@ -174,4 +175,59 @@ const calculateInterval = (start, end) => { }, intervalsInRFC[0]) } -module.exports = { hash, decodeStateTransition, getKnex, checkTcpConnect, calculateInterval } +const getLabelBuffer = (text) => + Buffer.from(`${ + Buffer.from(`12${`0${(text.length).toString(16)}`.slice(-2) + }`, 'hex')}${text}` + ) + +const validateAliases = async (aliases, identifier, dapi) => { + const aliasesWithContestedState = await Promise.all(aliases.map(async (alias) => { + const [label, domain] = alias.split('.') + + const normalizedLabel = label.toLowerCase().replace(/[oli]/g, (match) => { + if (match === 'o') { + return '0'; + } + if (match === 'l' || match === 'i') { + return '1'; + } + return match; + }) + + if (/^[a-zA-Z01]{3,19}$/.test(normalizedLabel)) { + + const domainBuffer = getLabelBuffer(domain) + const labelBuffer = getLabelBuffer(normalizedLabel) + + const contestedState = await dapi.getContestedState( + DPNS_CONTRACT, + 'domain', + 'parentNameAndLabel', + 1, + [ + domainBuffer, + labelBuffer + ] + ) + + return {alias, contestedState} + } + + return {alias, contestedState: null} + })) + + return (identifier ? aliasesWithContestedState.filter(alias => ( + typeof alias.contestedState?.finishedVoteInfo?.wonByIdentityId === 'string' + ? base58.encode(Buffer.from(alias.contestedState?.finishedVoteInfo.wonByIdentityId, 'base64')) === identifier + : false + ) || alias.contestedState === null + ).map(v => v.alias) + : aliasesWithContestedState) +} + +module.exports = { + hash, decodeStateTransition, + getKnex, checkTcpConnect, calculateInterval, + validateAliases, getLabelBuffer +} From 8b8009680f3ca45794e053a3950adf65790c43ec Mon Sep 17 00:00:00 2001 From: owl352 Date: Fri, 1 Nov 2024 01:40:27 +0300 Subject: [PATCH 02/35] lint and fixes --- packages/api/src/DAPI.js | 36 +++++------ .../src/controllers/IdentitiesController.js | 63 +++++++++---------- .../api/src/controllers/MainController.js | 36 +++++------ packages/api/src/models/Identity.js | 2 +- packages/api/src/utils.js | 38 ++++++----- 5 files changed, 85 insertions(+), 90 deletions(-) diff --git a/packages/api/src/DAPI.js b/packages/api/src/DAPI.js index 955072d17..9f5d02bd9 100644 --- a/packages/api/src/DAPI.js +++ b/packages/api/src/DAPI.js @@ -1,42 +1,38 @@ -const {Identifier} = require('dash').PlatformProtocol - -const { - v0: {GetDocumentsRequest}, -} = require('@dashevo/dapi-grpc'); +const { Identifier } = require('dash').PlatformProtocol class DAPI { dapi dpp - constructor(dapi, dpp) { + constructor (dapi, dpp) { this.dapi = dapi this.dpp = dpp } - async getIdentityBalance(identifier) { - const {balance} = await this.dapi.platform.getIdentityBalance(Identifier.from(identifier)) + async getIdentityBalance (identifier) { + const { balance } = await this.dapi.platform.getIdentityBalance(Identifier.from(identifier)) return balance } - async getTotalCredits() { - const {totalCreditsInPlatform} = await this.dapi.platform.getTotalCreditsInPlatform() + async getTotalCredits () { + const { totalCreditsInPlatform } = await this.dapi.platform.getTotalCreditsInPlatform() return totalCreditsInPlatform } - async getEpochsInfo(count, start, ascending) { - const {epochsInfo} = await this.dapi.platform.getEpochsInfo(start, count, {ascending}) + async getEpochsInfo (count, start, ascending) { + const { epochsInfo } = await this.dapi.platform.getEpochsInfo(start, count, { ascending }) return epochsInfo } - async getContestedState(contractId, - documentTypeName, - indexName = 'parentNameAndLabel', - resultType = 2, - indexValuesList, startAtIdentifierInfo, - allowIncludeLockedAndAbstainingVoteTally, - count + async getContestedState (contractId, + documentTypeName, + indexName = 'parentNameAndLabel', + resultType = 2, + indexValuesList, startAtIdentifierInfo, + allowIncludeLockedAndAbstainingVoteTally, + count ) { - const {contestedResourceContenders} = await this.dapi.platform.getContestedResourceVoteState( + const { contestedResourceContenders } = await this.dapi.platform.getContestedResourceVoteState( Buffer.from(contractId, 'base64'), documentTypeName, indexName, diff --git a/packages/api/src/controllers/IdentitiesController.js b/packages/api/src/controllers/IdentitiesController.js index 8f41cc4f9..7c1f81e61 100644 --- a/packages/api/src/controllers/IdentitiesController.js +++ b/packages/api/src/controllers/IdentitiesController.js @@ -1,51 +1,48 @@ const IdentitiesDAO = require('../dao/IdentitiesDAO') -const {IDENTITY_CREDIT_WITHDRAWAL} = require('../enums/StateTransitionEnum') -const {generateNormalizedLabelBuffer, getLabelBuffer, validateAliases} = require("../utils"); -const Identity = require("../models/Identity"); -const {base58} = require("@scure/base"); +const { IDENTITY_CREDIT_WITHDRAWAL } = require('../enums/StateTransitionEnum') +const { validateAliases } = require('../utils') +const Identity = require('../models/Identity') +const { base58 } = require('@scure/base') class IdentitiesController { - constructor(knex, dapi) { + constructor (knex, dapi) { this.identitiesDAO = new IdentitiesDAO(knex) this.dapi = dapi } getIdentityByIdentifier = async (request, response) => { - const {identifier} = request.params + const { identifier } = request.params let [identity] = await Promise.all([this.identitiesDAO.getIdentityByIdentifier(identifier)]) if (!identity) { - return response.status(404).send({message: 'not found'}) + return response.status(404).send({ message: 'not found' }) } const validatedAliases = await validateAliases(identity.aliases, identity.identifier, this.dapi) - identity = Identity.fromObject({...identity, aliases: validatedAliases}) + identity = Identity.fromObject({ ...identity, aliases: validatedAliases }) const balance = await this.dapi.getIdentityBalance(identifier) - response.send({...identity, balance}) + response.send({ ...identity, balance }) } - getIdentityByDPNS = async (request, response) => { - const {dpns} = request.query + const { dpns } = request.query let preIdentity let identity - let contestedState - if (!dpns.includes('.')) { preIdentity = await this.identitiesDAO.getIdentityByDPNS(dpns) if (!preIdentity) { - return response.status(404).send({message: 'not found'}) + return response.status(404).send({ message: 'not found' }) } } - [{contestedState}] = await validateAliases( - [preIdentity ? preIdentity.aliases.find(v => v.includes(dpns)) : dpns], + const [{ contestedState }] = await validateAliases( + [preIdentity ? preIdentity.aliases.find(v => v.includes(`${dpns}.`)) : dpns], null, this.dapi ) @@ -59,24 +56,24 @@ class IdentitiesController { } if (!contestedState) { - identity = preIdentity + identity = preIdentity ?? await this.identitiesDAO.getIdentityByDPNS(dpns) } if (!identity) { - return response.status(404).send({message: 'not found'}) + return response.status(404).send({ message: 'not found' }) } const balance = await this.dapi.getIdentityBalance(identity.identifier) const validatedAliases = await validateAliases(identity.aliases, identity.identifier, this.dapi) - identity = Identity.fromObject({...identity, aliases: validatedAliases}) + identity = Identity.fromObject({ ...identity, aliases: validatedAliases }) - response.send({...identity, balance}) + response.send({ ...identity, balance }) } getIdentities = async (request, response) => { - const {page = 1, limit = 10, order = 'asc', order_by: orderBy = 'block_height'} = request.query + const { page = 1, limit = 10, order = 'asc', order_by: orderBy = 'block_height' } = request.query const identities = await this.identitiesDAO.getIdentities(Number(page ?? 1), Number(limit ?? 10), order, orderBy) @@ -85,15 +82,15 @@ class IdentitiesController { const validatedAliases = await validateAliases(identity.aliases, identity.identifier, this.dapi) - return {...identity, aliases: validatedAliases, balance} + return { ...identity, aliases: validatedAliases, balance } })) - response.send({...identities, resultSet: identitiesWithBalance}) + response.send({ ...identities, resultSet: identitiesWithBalance }) } getTransactionsByIdentity = async (request, response) => { - const {identifier} = request.params - const {page = 1, limit = 10, order = 'asc'} = request.query + const { identifier } = request.params + const { page = 1, limit = 10, order = 'asc' } = request.query const transactions = await this.identitiesDAO.getTransactionsByIdentity(identifier, Number(page ?? 1), Number(limit ?? 10), order) @@ -101,8 +98,8 @@ class IdentitiesController { } getDataContractsByIdentity = async (request, response) => { - const {identifier} = request.params - const {page = 1, limit = 10, order = 'asc'} = request.query + const { identifier } = request.params + const { page = 1, limit = 10, order = 'asc' } = request.query const dataContracts = await this.identitiesDAO.getDataContractsByIdentity(identifier, Number(page ?? 1), Number(limit ?? 10), order) @@ -110,8 +107,8 @@ class IdentitiesController { } getDocumentsByIdentity = async (request, response) => { - const {identifier} = request.params - const {page = 1, limit = 10, order = 'asc'} = request.query + const { identifier } = request.params + const { page = 1, limit = 10, order = 'asc' } = request.query const documents = await this.identitiesDAO.getDocumentsByIdentity(identifier, Number(page ?? 1), Number(limit ?? 10), order) @@ -119,8 +116,8 @@ class IdentitiesController { } getTransfersByIdentity = async (request, response) => { - const {identifier} = request.params - const {page = 1, limit = 10, order = 'asc', type = undefined} = request.query + const { identifier } = request.params + const { page = 1, limit = 10, order = 'asc', type = undefined } = request.query const transfers = await this.identitiesDAO.getTransfersByIdentity(identifier, Number(page ?? 1), Number(limit ?? 10), order, type) @@ -128,8 +125,8 @@ class IdentitiesController { } getWithdrawalsByIdentity = async (request, response) => { - const {identifier} = request.params - const {page = 1, limit = 10, order = 'asc'} = request.query + const { identifier } = request.params + const { page = 1, limit = 10, order = 'asc' } = request.query const withdrawals = await this.identitiesDAO.getTransfersByIdentity( identifier, diff --git a/packages/api/src/controllers/MainController.js b/packages/api/src/controllers/MainController.js index 7a7aa28a6..f98d77e59 100644 --- a/packages/api/src/controllers/MainController.js +++ b/packages/api/src/controllers/MainController.js @@ -6,14 +6,14 @@ const IdentitiesDAO = require('../dao/IdentitiesDAO') const ValidatorsDAO = require('../dao/ValidatorsDAO') const TenderdashRPC = require('../tenderdashRpc') const Epoch = require('../models/Epoch') -const {validateAliases} = require("../utils"); -const {base58} = require("@scure/base"); +const { validateAliases } = require('../utils') +const { base58 } = require('@scure/base') const API_VERSION = require('../../package.json').version const PLATFORM_VERSION = '1' + require('../../package.json').dependencies.dash.substring(1) class MainController { - constructor(knex, dapi) { + constructor (knex, dapi) { this.blocksDAO = new BlocksDAO(knex) this.dataContractsDAO = new DataContractsDAO(knex) this.documentsDAO = new DocumentsDAO(knex) @@ -72,7 +72,7 @@ class MainController { } search = async (request, response) => { - const {query} = request.query + const { query } = request.query const epoch = Epoch.fromObject({ startTime: 0, @@ -84,7 +84,7 @@ class MainController { const block = await this.blocksDAO.getBlockByHeight(query) if (block) { - return response.send({block}) + return response.send({ block }) } } @@ -93,21 +93,21 @@ class MainController { const block = await this.blocksDAO.getBlockByHash(query) if (block) { - return response.send({block}) + return response.send({ block }) } // search transactions const transaction = await this.transactionsDAO.getTransactionByHash(query) if (transaction) { - return response.send({transaction}) + return response.send({ transaction }) } // search validators const validator = await this.validatorsDAO.getValidatorByProTxHash(query, null, epoch) if (validator) { - return response.send({validator}) + return response.send({ validator }) } } @@ -119,21 +119,21 @@ class MainController { if (identity) { // Sending without actual balance and aliases, because on frontend we were making // request /identity/:identifier for actual data - return response.send({identity}) + return response.send({ identity }) } // search data contracts const dataContract = await this.dataContractsDAO.getDataContractByIdentifier(query) if (dataContract) { - return response.send({dataContract}) + return response.send({ dataContract }) } // search documents const document = await this.documentsDAO.getDocumentByIdentifier(query) if (document) { - return response.send({document}) + return response.send({ document }) } } @@ -141,18 +141,16 @@ class MainController { let preIdentity let identity - let contestedState - if (!query.includes('.')) { preIdentity = await this.identitiesDAO.getIdentityByDPNS(query) if (!preIdentity) { - return response.status(404).send({message: 'not found'}) + return response.status(404).send({ message: 'not found' }) } } - [{contestedState}] = await validateAliases( - [preIdentity ? preIdentity.aliases.find(v => v.includes(query)) : query], + const [{ contestedState }] = await validateAliases( + [preIdentity ? preIdentity.aliases.find(v => v.includes(`${query}.`)) : query], null, this.dapi ) @@ -166,17 +164,17 @@ class MainController { } if (!contestedState) { - identity = preIdentity + identity = preIdentity ?? await this.identitiesDAO.getIdentityByDPNS(query) } if (identity) { // Sending without actual balance and aliases, because on frontend we were making // request /identity/:identifier for actual data - return response.send({identity}) + return response.send({ identity }) } } - response.status(404).send({message: 'not found'}) + response.status(404).send({ message: 'not found' }) } } diff --git a/packages/api/src/models/Identity.js b/packages/api/src/models/Identity.js index 1456ca6ee..229fc2fb3 100644 --- a/packages/api/src/models/Identity.js +++ b/packages/api/src/models/Identity.js @@ -31,7 +31,7 @@ module.exports = class Identity { return new Identity(identifier, owner, revision, Number(balance), timestamp, Number(total_txs), Number(total_data_contracts), Number(total_documents), Number(total_transfers), tx_hash, is_system, aliases) } - static fromObject({identifier, owner, revision, balance, timestamp, totalTxs, totalDataContracts, totalDocuments, totalTransfers, txHash, isSystem, aliases}){ + static fromObject ({ identifier, owner, revision, balance, timestamp, totalTxs, totalDataContracts, totalDocuments, totalTransfers, txHash, isSystem, aliases }) { return new Identity(identifier, owner, revision, balance, timestamp, totalTxs, totalDataContracts, totalDocuments, totalTransfers, txHash, isSystem, aliases) } } diff --git a/packages/api/src/utils.js b/packages/api/src/utils.js index 69a928fc2..41df8978e 100644 --- a/packages/api/src/utils.js +++ b/packages/api/src/utils.js @@ -1,8 +1,8 @@ const crypto = require('crypto') const StateTransitionEnum = require('./enums/StateTransitionEnum') const net = require('net') -const {TCP_CONNECT_TIMEOUT, DPNS_CONTRACT} = require('./constants') -const {base58} = require("@scure/base"); +const { TCP_CONNECT_TIMEOUT, DPNS_CONTRACT } = require('./constants') +const { base58 } = require('@scure/base') const getKnex = () => { return require('knex')({ @@ -13,7 +13,7 @@ const getKnex = () => { user: process.env.POSTGRES_USER, database: process.env.POSTGRES_DB, password: process.env.POSTGRES_PASS, - ssl: process.env.POSTGRES_SSL ? {rejectUnauthorized: false} : false + ssl: process.env.POSTGRES_SSL ? { rejectUnauthorized: false } : false } }) } @@ -187,16 +187,15 @@ const validateAliases = async (aliases, identifier, dapi) => { const normalizedLabel = label.toLowerCase().replace(/[oli]/g, (match) => { if (match === 'o') { - return '0'; + return '0' } if (match === 'l' || match === 'i') { - return '1'; + return '1' } - return match; + return match }) if (/^[a-zA-Z01]{3,19}$/.test(normalizedLabel)) { - const domainBuffer = getLabelBuffer(domain) const labelBuffer = getLabelBuffer(normalizedLabel) @@ -211,23 +210,28 @@ const validateAliases = async (aliases, identifier, dapi) => { ] ) - return {alias, contestedState} + return { alias, contestedState } } - return {alias, contestedState: null} + return { alias, contestedState: null } })) - return (identifier ? aliasesWithContestedState.filter(alias => ( - typeof alias.contestedState?.finishedVoteInfo?.wonByIdentityId === 'string' - ? base58.encode(Buffer.from(alias.contestedState?.finishedVoteInfo.wonByIdentityId, 'base64')) === identifier - : false - ) || alias.contestedState === null + return (identifier + ? aliasesWithContestedState.filter(alias => ( + typeof alias.contestedState?.finishedVoteInfo?.wonByIdentityId === 'string' + ? base58.encode(Buffer.from(alias.contestedState?.finishedVoteInfo.wonByIdentityId, 'base64')) === identifier + : false + ) || alias.contestedState === null ).map(v => v.alias) : aliasesWithContestedState) } module.exports = { - hash, decodeStateTransition, - getKnex, checkTcpConnect, calculateInterval, - validateAliases, getLabelBuffer + hash, + decodeStateTransition, + getKnex, + checkTcpConnect, + calculateInterval, + validateAliases, + getLabelBuffer } From a2ce9ea98d9e15d5d822fad85da2dc0be9fd8739 Mon Sep 17 00:00:00 2001 From: owl352 Date: Fri, 1 Nov 2024 16:09:44 +0300 Subject: [PATCH 03/35] update package.json --- packages/api/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/api/package.json b/packages/api/package.json index 67832c267..39de5ea35 100644 --- a/packages/api/package.json +++ b/packages/api/package.json @@ -12,7 +12,7 @@ "lint": "standard ." }, "dependencies": { - "@dashevo/dapi-client": "1.4.1", + "@dashevo/dapi-client": "github:owl352/dapi-client", "@dashevo/dashd-rpc": "19.0.0", "@fastify/cors": "^8.3.0", "@scure/base": "^1.1.5", From f00f3b58e5c05becae6335f03572927e02f7a862 Mon Sep 17 00:00:00 2001 From: owl352 Date: Fri, 1 Nov 2024 16:41:34 +0300 Subject: [PATCH 04/35] main controller tests update --- packages/api/test/integration/main.spec.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/api/test/integration/main.spec.js b/packages/api/test/integration/main.spec.js index 6600ffeba..8ea73bcab 100644 --- a/packages/api/test/integration/main.spec.js +++ b/packages/api/test/integration/main.spec.js @@ -39,6 +39,8 @@ describe('Other routes', () => { nextEpoch: 0 }]) + mock.method(DAPI.prototype, 'getContestedState', async () => null) + mock.method(tenderdashRpc, 'getBlockByHeight', async () => ({ block: { header: { @@ -228,7 +230,7 @@ describe('Other routes', () => { const expectedIdentity = { identifier: identity.identifier, revision: 0, - balance: 0, + balance: null, timestamp: block.timestamp.toISOString(), txHash: identityTransaction.hash, totalTxs: 51, @@ -251,7 +253,7 @@ describe('Other routes', () => { const expectedIdentity = { identifier: identity.identifier, revision: 0, - balance: 0, + balance: null, timestamp: block.timestamp.toISOString(), txHash: identityTransaction.hash, totalTxs: 51, From 8c6d0927412921f8e212c21202892cc5387c96c6 Mon Sep 17 00:00:00 2001 From: owl352 Date: Fri, 1 Nov 2024 16:54:06 +0300 Subject: [PATCH 05/35] fix --- packages/api/src/controllers/IdentitiesController.js | 7 +++---- packages/api/test/integration/identities.spec.js | 4 +++- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/packages/api/src/controllers/IdentitiesController.js b/packages/api/src/controllers/IdentitiesController.js index 7c1f81e61..33cc6ae63 100644 --- a/packages/api/src/controllers/IdentitiesController.js +++ b/packages/api/src/controllers/IdentitiesController.js @@ -12,7 +12,8 @@ class IdentitiesController { getIdentityByIdentifier = async (request, response) => { const { identifier } = request.params - let [identity] = await Promise.all([this.identitiesDAO.getIdentityByIdentifier(identifier)]) + + const identity = await this.identitiesDAO.getIdentityByIdentifier(identifier) if (!identity) { return response.status(404).send({ message: 'not found' }) @@ -20,11 +21,9 @@ class IdentitiesController { const validatedAliases = await validateAliases(identity.aliases, identity.identifier, this.dapi) - identity = Identity.fromObject({ ...identity, aliases: validatedAliases }) - const balance = await this.dapi.getIdentityBalance(identifier) - response.send({ ...identity, balance }) + response.send(Identity.fromObject({ ...identity, aliases: validatedAliases, balance })) } getIdentityByDPNS = async (request, response) => { diff --git a/packages/api/test/integration/identities.spec.js b/packages/api/test/integration/identities.spec.js index abbb4c1e1..133080c51 100644 --- a/packages/api/test/integration/identities.spec.js +++ b/packages/api/test/integration/identities.spec.js @@ -30,6 +30,8 @@ describe('Identities routes', () => { before(async () => { mock.method(DAPI.prototype, 'getIdentityBalance', async () => 0) + mock.method(DAPI.prototype, 'getContestedState', async () => null) + mock.method(tenderdashRpc, 'getBlockByHeight', async () => ({ block: { header: { @@ -58,7 +60,7 @@ describe('Identities routes', () => { const identity = await fixtures.identity(knex, { block_hash: block.hash }) const { alias } = await fixtures.identity_alias(knex, { - alias: 'test', + alias: 'test.dash', identity } ) From 4fd87d9efec6b3cf394573f4b0489efbeac151d5 Mon Sep 17 00:00:00 2001 From: owl352 Date: Thu, 7 Nov 2024 20:50:43 +0300 Subject: [PATCH 06/35] initial commit --- packages/api/README.md | 6 +++-- packages/api/src/dao/TransactionsDAO.js | 6 ++--- packages/api/src/models/Transaction.js | 8 +++--- .../api/test/integration/transactions.spec.js | 18 ++++++++----- packages/frontend/src/app/api/content.md | 25 +++++++++++++------ 5 files changed, 42 insertions(+), 21 deletions(-) diff --git a/packages/api/README.md b/packages/api/README.md index f7b839ec2..d0846daa9 100644 --- a/packages/api/README.md +++ b/packages/api/README.md @@ -412,7 +412,8 @@ GET /transaction/DEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEE type: 0, gasUsed: 1337000, status: "SUCCESS", - error: null + error: null, + owner: "6q9RFbeea73tE31LGMBLFZhtBUX3wZL3TcNynqE18Zgs" } ``` @@ -450,7 +451,8 @@ GET /transactions?=1&limit=10&order=asc type: 0, gasUsed: 1337000, status: "SUCCESS", - error: null + error: null, + owner: "6q9RFbeea73tE31LGMBLFZhtBUX3wZL3TcNynqE18Zgs" }, ... ] } diff --git a/packages/api/src/dao/TransactionsDAO.js b/packages/api/src/dao/TransactionsDAO.js index b5d0e87ea..4aac6a5eb 100644 --- a/packages/api/src/dao/TransactionsDAO.js +++ b/packages/api/src/dao/TransactionsDAO.js @@ -12,7 +12,7 @@ module.exports = class TransactionsDAO { .select('state_transitions.hash as tx_hash', 'state_transitions.data as data', 'state_transitions.gas_used as gas_used', 'state_transitions.status as status', 'state_transitions.error as error', 'state_transitions.type as type', 'state_transitions.index as index', 'blocks.height as block_height', - 'blocks.hash as block_hash', 'blocks.timestamp as timestamp') + 'blocks.hash as block_hash', 'blocks.timestamp as timestamp', 'state_transitions.owner as owner') .whereILike('state_transitions.hash', hash) .leftJoin('blocks', 'blocks.hash', 'state_transitions.block_hash') @@ -31,13 +31,13 @@ module.exports = class TransactionsDAO { .select(this.knex('state_transitions').count('hash').as('total_count'), 'state_transitions.hash as tx_hash', 'state_transitions.data as data', 'state_transitions.type as type', 'state_transitions.index as index', 'state_transitions.gas_used as gas_used', 'state_transitions.status as status', 'state_transitions.error as error', - 'state_transitions.block_hash as block_hash', 'state_transitions.id as id') + 'state_transitions.block_hash as block_hash', 'state_transitions.id as id', 'state_transitions.owner as owner') .select(this.knex.raw(`rank() over (order by state_transitions.id ${order}) rank`)) .as('state_transitions') const rows = await this.knex(subquery) .select('total_count', 'data', 'type', 'index', 'rank', 'block_hash', 'state_transitions.tx_hash as tx_hash', - 'gas_used', 'status', 'error', 'blocks.height as block_height', 'blocks.timestamp as timestamp') + 'gas_used', 'status', 'error', 'blocks.height as block_height', 'blocks.timestamp as timestamp', 'owner') .leftJoin('blocks', 'blocks.hash', 'block_hash') .whereBetween('rank', [fromRank, toRank]) .orderBy('state_transitions.id', order) diff --git a/packages/api/src/models/Transaction.js b/packages/api/src/models/Transaction.js index bf062ff2e..b195a28ed 100644 --- a/packages/api/src/models/Transaction.js +++ b/packages/api/src/models/Transaction.js @@ -13,8 +13,9 @@ module.exports = class Transaction { gasUsed status error + owner - constructor (hash, index, blockHash, blockHeight, type, data, timestamp, gasUsed, status, error) { + constructor (hash, index, blockHash, blockHeight, type, data, timestamp, gasUsed, status, error, owner) { this.hash = hash ?? null this.index = index ?? null this.blockHash = blockHash ?? null @@ -25,10 +26,11 @@ module.exports = class Transaction { this.gasUsed = gasUsed ?? null this.status = status ?? null this.error = error ?? null + this.owner = owner ?? null } // eslint-disable-next-line camelcase - static fromRow ({ tx_hash, index, block_hash, block_height, type, data, timestamp, gas_used, status, error }) { + static fromRow ({ tx_hash, index, block_hash, block_height, type, data, timestamp, gas_used, status, error, owner }) { let decodedError = null try { @@ -41,6 +43,6 @@ module.exports = class Transaction { decodedError = 'Cannot deserialize' } - return new Transaction(tx_hash, index, block_hash, block_height, type, data, timestamp, parseInt(gas_used), status, decodedError ?? error) + return new Transaction(tx_hash, index, block_hash, block_height, type, data, timestamp, parseInt(gas_used), status, decodedError ?? error, owner) } } diff --git a/packages/api/test/integration/transactions.spec.js b/packages/api/test/integration/transactions.spec.js index 672d412f5..f1df2708d 100644 --- a/packages/api/test/integration/transactions.spec.js +++ b/packages/api/test/integration/transactions.spec.js @@ -104,7 +104,8 @@ describe('Transaction routes', () => { type: transaction.transaction.type, gasUsed: transaction.transaction.gas_used, status: transaction.transaction.status, - error: transaction.transaction.error + error: transaction.transaction.error, + owner: transaction.transaction.owner } assert.deepEqual(expectedTransaction, body) @@ -126,7 +127,8 @@ describe('Transaction routes', () => { type: transaction.transaction.type, gasUsed: 0, status: 'FAIL', - error: 'Cannot deserialize' + error: 'Cannot deserialize', + owner: transaction.transaction.owner } assert.deepEqual(expectedTransaction, body) @@ -162,7 +164,8 @@ describe('Transaction routes', () => { type: transaction.transaction.type, gasUsed: transaction.transaction.gas_used, status: transaction.transaction.status, - error: transaction.transaction.error + error: transaction.transaction.error, + owner: transaction.transaction.owner })) assert.deepEqual(expectedTransactions, body.resultSet) @@ -191,7 +194,8 @@ describe('Transaction routes', () => { type: transaction.transaction.type, gasUsed: transaction.transaction.gas_used, status: transaction.transaction.status, - error: transaction.transaction.error + error: transaction.transaction.error, + owner: transaction.transaction.owner })) assert.deepEqual(expectedTransactions, body.resultSet) @@ -220,7 +224,8 @@ describe('Transaction routes', () => { type: transaction.transaction.type, gasUsed: transaction.transaction.gas_used, status: transaction.transaction.status, - error: transaction.transaction.error + error: transaction.transaction.error, + owner: transaction.transaction.owner })) assert.deepEqual(expectedTransactions, body.resultSet) @@ -249,7 +254,8 @@ describe('Transaction routes', () => { type: transaction.transaction.type, gasUsed: transaction.transaction.gas_used, status: transaction.transaction.status, - error: transaction.transaction.error + error: transaction.transaction.error, + owner: transaction.transaction.owner })) assert.deepEqual(expectedTransactions, body.resultSet) diff --git a/packages/frontend/src/app/api/content.md b/packages/frontend/src/app/api/content.md index a770c6996..f1297525d 100644 --- a/packages/frontend/src/app/api/content.md +++ b/packages/frontend/src/app/api/content.md @@ -343,9 +343,14 @@ GET /validator/F60A6BF9EC0794BB0CFD1E0F2217933F4B33EDE6FE810692BC275CA18148AEF0 ``` --- ### Validator stats by ProTxHash -Return a series data for the amount of proposed blocks by validator chart with variable timespan (1h, 24h, 3d, 1w) +Return a series data for the amount of proposed blocks by validator chart with + +* `start` lower interval threshold in ISO string ( _optional_ ) +* `end` upper interval threshold in ISO string ( _optional_ ) + + ``` -GET /validator/F60A6BF9EC0794BB0CFD1E0F2217933F4B33EDE6FE810692BC275CA18148AEF0/stats?timespan=24h +GET /validator/F60A6BF9EC0794BB0CFD1E0F2217933F4B33EDE6FE810692BC275CA18148AEF0/stats?start=2024-01-01T00:00:00&end=2025-01-01T00:00:00 [ { timestamp: "2024-06-23T13:51:44.154Z", @@ -374,7 +379,8 @@ GET /transaction/DEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEE type: 0, gasUsed: 1337000, status: "SUCCESS", - error: null + error: null, + owner: "6q9RFbeea73tE31LGMBLFZhtBUX3wZL3TcNynqE18Zgs" } ``` @@ -412,7 +418,8 @@ GET /transactions?=1&limit=10&order=asc type: 0, gasUsed: 1337000, status: "SUCCESS", - error: null + error: null, + owner: "6q9RFbeea73tE31LGMBLFZhtBUX3wZL3TcNynqE18Zgs" }, ... ] } @@ -772,9 +779,13 @@ Response codes: 500: Internal Server Error ``` ### Transactions history -Return a series data for the amount of transactions chart with variable timespan (1h, 24h, 3d, 1w) +Return a series data for the amount of transactions chart + +* `start` lower interval threshold in ISO string ( _optional_ ) +* `end` upper interval threshold in ISO string ( _optional_ ) + ``` -GET /transactions/history?timespan=1h +GET /transactions/history?start=2024-01-01T00:00:00&end=2025-01-01T00:00:00 [ { timestamp: "2024-04-22T08:45:20.911Z", @@ -797,7 +808,7 @@ GET /transactions/history?timespan=1h Response codes: ``` 200: OK -400: Invalid input, check timespan value +400: Invalid input, check start/end values 500: Internal Server Error ``` ### Rate From 31250288f757a7d94c2f35a25b595c8eda68f9e6 Mon Sep 17 00:00:00 2001 From: owl352 Date: Thu, 7 Nov 2024 21:01:14 +0300 Subject: [PATCH 07/35] search and txs by identity fix --- packages/api/README.md | 3 ++- packages/api/src/dao/IdentitiesDAO.js | 5 +++-- packages/api/test/integration/identities.spec.js | 12 ++++++++---- packages/api/test/integration/main.spec.js | 3 ++- packages/frontend/src/app/api/content.md | 3 ++- 5 files changed, 17 insertions(+), 9 deletions(-) diff --git a/packages/api/README.md b/packages/api/README.md index d0846daa9..1b1f7fa66 100644 --- a/packages/api/README.md +++ b/packages/api/README.md @@ -770,7 +770,8 @@ GET /identities/GWRSAVFMjXx8HpQFaNJMqBV7MBgMK4br5UESsB4S31Ec/transactions?page=1 timestamp: "2024-03-18T10:13:54.150Z", gasUsed: 1337000, status: "SUCCESS", - error: null + error: null, + owner: "GWRSAVFMjXx8HpQFaNJMqBV7MBgMK4br5UESsB4S31Ec" }, ... ] } diff --git a/packages/api/src/dao/IdentitiesDAO.js b/packages/api/src/dao/IdentitiesDAO.js index 5ce47094d..020e1a772 100644 --- a/packages/api/src/dao/IdentitiesDAO.js +++ b/packages/api/src/dao/IdentitiesDAO.js @@ -246,14 +246,15 @@ module.exports = class IdentitiesDAO { const subquery = this.knex('state_transitions') .select('state_transitions.id as state_transition_id', 'state_transitions.hash as tx_hash', 'state_transitions.index as index', 'state_transitions.type as type', 'state_transitions.block_hash as block_hash', - 'state_transitions.gas_used as gas_used', 'state_transitions.status as status', 'state_transitions.error as error' + 'state_transitions.gas_used as gas_used', 'state_transitions.status as status', 'state_transitions.error as error', + 'state_transitions.owner as owner' ) .select(this.knex.raw(`rank() over (order by state_transitions.id ${order}) rank`)) .where('state_transitions.owner', '=', identifier) const rows = await this.knex.with('with_alias', subquery) .select('state_transition_id', 'tx_hash', 'index', 'block_hash', 'type', 'rank', - 'gas_used', 'status', 'gas_used', + 'gas_used', 'status', 'gas_used', 'owner', 'blocks.timestamp as timestamp', 'blocks.height as block_height') .select(this.knex('with_alias').count('*').as('total_count')) .leftJoin('blocks', 'blocks.hash', 'block_hash') diff --git a/packages/api/test/integration/identities.spec.js b/packages/api/test/integration/identities.spec.js index abbb4c1e1..5328ff4de 100644 --- a/packages/api/test/integration/identities.spec.js +++ b/packages/api/test/integration/identities.spec.js @@ -886,7 +886,8 @@ describe('Identities routes', () => { timestamp: _transaction.block.timestamp.toISOString(), gasUsed: _transaction.transaction.gas_used, status: _transaction.transaction.status, - error: _transaction.transaction.error + error: _transaction.transaction.error, + owner: _transaction.transaction.owner })) assert.deepEqual(body.resultSet, expectedTransactions) @@ -929,7 +930,8 @@ describe('Identities routes', () => { timestamp: _transaction.block.timestamp.toISOString(), gasUsed: _transaction.transaction.gas_used, status: _transaction.transaction.status, - error: _transaction.transaction.error + error: _transaction.transaction.error, + owner: _transaction.transaction.owner })) assert.deepEqual(body.resultSet, expectedTransactions) @@ -972,7 +974,8 @@ describe('Identities routes', () => { timestamp: _transaction.block.timestamp.toISOString(), gasUsed: _transaction.transaction.gas_used, status: _transaction.transaction.status, - error: _transaction.transaction.error + error: _transaction.transaction.error, + owner: _transaction.transaction.owner })) assert.deepEqual(body.resultSet, expectedTransactions) @@ -1015,7 +1018,8 @@ describe('Identities routes', () => { timestamp: _transaction.block.timestamp.toISOString(), gasUsed: _transaction.transaction.gas_used, status: _transaction.transaction.status, - error: _transaction.transaction.error + error: _transaction.transaction.error, + owner: _transaction.transaction.owner })) assert.deepEqual(body.resultSet, expectedTransactions) diff --git a/packages/api/test/integration/main.spec.js b/packages/api/test/integration/main.spec.js index 6600ffeba..8c0baf079 100644 --- a/packages/api/test/integration/main.spec.js +++ b/packages/api/test/integration/main.spec.js @@ -171,7 +171,8 @@ describe('Other routes', () => { timestamp: block.timestamp.toISOString(), gasUsed: dataContractTransaction.gas_used, status: dataContractTransaction.status, - error: dataContractTransaction.error + error: dataContractTransaction.error, + owner: dataContractTransaction.owner } assert.deepEqual({ transaction: expectedTransaction }, body) diff --git a/packages/frontend/src/app/api/content.md b/packages/frontend/src/app/api/content.md index f1297525d..d3a64c5c9 100644 --- a/packages/frontend/src/app/api/content.md +++ b/packages/frontend/src/app/api/content.md @@ -737,7 +737,8 @@ GET /identities/GWRSAVFMjXx8HpQFaNJMqBV7MBgMK4br5UESsB4S31Ec/transactions?page=1 timestamp: "2024-03-18T10:13:54.150Z", gasUsed: 1337000, status: "SUCCESS", - error: null + error: null, + owner: "GWRSAVFMjXx8HpQFaNJMqBV7MBgMK4br5UESsB4S31Ec" }, ... ] } From 2b5d84e694c04578ad7eaf18f8047958f8de2adb Mon Sep 17 00:00:00 2001 From: owl352 Date: Thu, 7 Nov 2024 21:18:13 +0300 Subject: [PATCH 08/35] trim --- packages/api/src/models/Transaction.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/api/src/models/Transaction.js b/packages/api/src/models/Transaction.js index b195a28ed..50e605631 100644 --- a/packages/api/src/models/Transaction.js +++ b/packages/api/src/models/Transaction.js @@ -43,6 +43,6 @@ module.exports = class Transaction { decodedError = 'Cannot deserialize' } - return new Transaction(tx_hash, index, block_hash, block_height, type, data, timestamp, parseInt(gas_used), status, decodedError ?? error, owner) + return new Transaction(tx_hash, index, block_hash, block_height, type, data, timestamp, parseInt(gas_used), status, decodedError ?? error, owner?.trim()) } } From d366c6d9d35a2f47d1488f15401617fd27be40b7 Mon Sep 17 00:00:00 2001 From: owl352 Date: Thu, 7 Nov 2024 21:19:31 +0300 Subject: [PATCH 09/35] trim --- packages/api/src/models/Transaction.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/api/src/models/Transaction.js b/packages/api/src/models/Transaction.js index 50e605631..2d73cfe62 100644 --- a/packages/api/src/models/Transaction.js +++ b/packages/api/src/models/Transaction.js @@ -1,6 +1,6 @@ const cbor = require('cbor') -const { deserializeConsensusError } = require('dash').PlatformProtocol +const {deserializeConsensusError} = require('dash').PlatformProtocol module.exports = class Transaction { hash @@ -15,7 +15,7 @@ module.exports = class Transaction { error owner - constructor (hash, index, blockHash, blockHeight, type, data, timestamp, gasUsed, status, error, owner) { + constructor(hash, index, blockHash, blockHeight, type, data, timestamp, gasUsed, status, error, owner) { this.hash = hash ?? null this.index = index ?? null this.blockHash = blockHash ?? null @@ -26,16 +26,16 @@ module.exports = class Transaction { this.gasUsed = gasUsed ?? null this.status = status ?? null this.error = error ?? null - this.owner = owner ?? null + this.owner = owner ? owner.trim() : null } // eslint-disable-next-line camelcase - static fromRow ({ tx_hash, index, block_hash, block_height, type, data, timestamp, gas_used, status, error, owner }) { + static fromRow({tx_hash, index, block_hash, block_height, type, data, timestamp, gas_used, status, error, owner}) { let decodedError = null try { if (typeof error === 'string') { - const { serializedError } = cbor.decode(Buffer.from(error, 'base64'))?.data + const {serializedError} = cbor.decode(Buffer.from(error, 'base64'))?.data decodedError = deserializeConsensusError(serializedError).message } } catch (e) { @@ -43,6 +43,6 @@ module.exports = class Transaction { decodedError = 'Cannot deserialize' } - return new Transaction(tx_hash, index, block_hash, block_height, type, data, timestamp, parseInt(gas_used), status, decodedError ?? error, owner?.trim()) + return new Transaction(tx_hash, index, block_hash, block_height, type, data, timestamp, parseInt(gas_used), status, decodedError ?? error, owner) } } From 604523105b4e928ba7fe1e599fc4c96c57676c4a Mon Sep 17 00:00:00 2001 From: owl352 Date: Thu, 7 Nov 2024 21:24:44 +0300 Subject: [PATCH 10/35] lint --- packages/api/src/models/Transaction.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/api/src/models/Transaction.js b/packages/api/src/models/Transaction.js index 2d73cfe62..69e3ec1f6 100644 --- a/packages/api/src/models/Transaction.js +++ b/packages/api/src/models/Transaction.js @@ -1,6 +1,6 @@ const cbor = require('cbor') -const {deserializeConsensusError} = require('dash').PlatformProtocol +const { deserializeConsensusError } = require('dash').PlatformProtocol module.exports = class Transaction { hash @@ -15,7 +15,7 @@ module.exports = class Transaction { error owner - constructor(hash, index, blockHash, blockHeight, type, data, timestamp, gasUsed, status, error, owner) { + constructor (hash, index, blockHash, blockHeight, type, data, timestamp, gasUsed, status, error, owner) { this.hash = hash ?? null this.index = index ?? null this.blockHash = blockHash ?? null @@ -30,12 +30,12 @@ module.exports = class Transaction { } // eslint-disable-next-line camelcase - static fromRow({tx_hash, index, block_hash, block_height, type, data, timestamp, gas_used, status, error, owner}) { + static fromRow ({ tx_hash, index, block_hash, block_height, type, data, timestamp, gas_used, status, error, owner }) { let decodedError = null try { if (typeof error === 'string') { - const {serializedError} = cbor.decode(Buffer.from(error, 'base64'))?.data + const { serializedError } = cbor.decode(Buffer.from(error, 'base64'))?.data decodedError = deserializeConsensusError(serializedError).message } } catch (e) { From afb8a4448349352bfd204ce5d48c37de1f99bf34 Mon Sep 17 00:00:00 2001 From: owl352 Date: Sat, 9 Nov 2024 01:47:16 +0300 Subject: [PATCH 11/35] added aliases --- packages/api/package.json | 4 +-- .../src/controllers/TransactionsController.js | 31 +++++++++++++--- packages/api/src/dao/TransactionsDAO.js | 27 +++++++++++--- packages/api/src/models/Transaction.js | 31 +++++++++++++--- packages/api/src/server.js | 13 ++++--- .../api/test/integration/transactions.spec.js | 36 +++++++++++++++---- 6 files changed, 114 insertions(+), 28 deletions(-) diff --git a/packages/api/package.json b/packages/api/package.json index 39de5ea35..e5c8ecb71 100644 --- a/packages/api/package.json +++ b/packages/api/package.json @@ -12,7 +12,6 @@ "lint": "standard ." }, "dependencies": { - "@dashevo/dapi-client": "github:owl352/dapi-client", "@dashevo/dashd-rpc": "19.0.0", "@fastify/cors": "^8.3.0", "@scure/base": "^1.1.5", @@ -24,7 +23,8 @@ "fastify-metrics": "^11.0.0", "knex": "^2.5.1", "node-fetch": "^2.6.11", - "pg": "^8.11.3" + "pg": "^8.11.3", + "@dashevo/dapi-client": "github:owl352/dapi-client" }, "devDependencies": { "standard": "^17.1.0", diff --git a/packages/api/src/controllers/TransactionsController.js b/packages/api/src/controllers/TransactionsController.js index c792866c6..da88ffa0e 100644 --- a/packages/api/src/controllers/TransactionsController.js +++ b/packages/api/src/controllers/TransactionsController.js @@ -1,11 +1,12 @@ const TransactionsDAO = require('../dao/TransactionsDAO') const utils = require('../utils') -const { calculateInterval } = require('../utils') +const { calculateInterval, validateAliases } = require('../utils') class TransactionsController { - constructor (client, knex) { + constructor (client, knex, dapi) { this.client = client this.transactionsDAO = new TransactionsDAO(knex) + this.dapi = dapi } getTransactionByHash = async (request, reply) => { @@ -17,7 +18,17 @@ class TransactionsController { return reply.status(404).send({ message: 'not found' }) } - reply.send(transaction) + const validatedAliases = transaction.owner.aliases?.length > 0 + ? await validateAliases(transaction.owner.aliases ?? [], transaction.owner?.identifier, this.dapi) + : [] + + reply.send({ + ...transaction, + owner: { + ...transaction.owner, + aliases: validatedAliases + } + }) } getTransactions = async (request, response) => { @@ -29,7 +40,19 @@ class TransactionsController { const transactions = await this.transactionsDAO.getTransactions(Number(page ?? 1), Number(limit ?? 10), order) - response.send(transactions) + const transactionsWithCorrectAliases = await Promise.all(transactions.resultSet.map(async transaction => + ({ + ...transaction, + owner: { + ...transaction.owner, + aliases: transaction.owner.aliases?.length > 0 + ? await validateAliases(transaction.owner.aliases ?? [], transaction.owner?.identifier, this.dapi) + : [] + } + }) + )) + + response.send({ ...transactions, resultSet: transactionsWithCorrectAliases }) } getTransactionHistory = async (request, response) => { diff --git a/packages/api/src/dao/TransactionsDAO.js b/packages/api/src/dao/TransactionsDAO.js index 4aac6a5eb..156d48a66 100644 --- a/packages/api/src/dao/TransactionsDAO.js +++ b/packages/api/src/dao/TransactionsDAO.js @@ -8,13 +8,23 @@ module.exports = class TransactionsDAO { } getTransactionByHash = async (hash) => { + const aliasesSubquery = this.knex('identity_aliases') + .select('identity_identifier', this.knex.raw('array_agg(alias) as aliases')) + .groupBy('identity_identifier') + .as('aliases') + const [row] = await this.knex('state_transitions') - .select('state_transitions.hash as tx_hash', 'state_transitions.data as data', - 'state_transitions.gas_used as gas_used', 'state_transitions.status as status', 'state_transitions.error as error', - 'state_transitions.type as type', 'state_transitions.index as index', 'blocks.height as block_height', - 'blocks.hash as block_hash', 'blocks.timestamp as timestamp', 'state_transitions.owner as owner') + .select( + 'state_transitions.hash as tx_hash', 'state_transitions.data as data', + 'state_transitions.gas_used as gas_used', 'state_transitions.status as status', + 'state_transitions.error as error', 'state_transitions.type as type', + 'state_transitions.index as index', 'blocks.height as block_height', + 'blocks.hash as block_hash', 'blocks.timestamp as timestamp', 'state_transitions.owner as owner', + 'aliases.aliases as aliases' + ) .whereILike('state_transitions.hash', hash) .leftJoin('blocks', 'blocks.hash', 'state_transitions.block_hash') + .leftJoin(aliasesSubquery, 'aliases.identity_identifier', 'owner') if (!row) { return null @@ -27,17 +37,24 @@ module.exports = class TransactionsDAO { const fromRank = ((page - 1) * limit) + 1 const toRank = fromRank + limit - 1 + const aliasesSubquery = this.knex('identity_aliases') + .select('identity_identifier', this.knex.raw('array_agg(alias) as aliases')) + .groupBy('identity_identifier') + .as('aliases') + const subquery = this.knex('state_transitions') .select(this.knex('state_transitions').count('hash').as('total_count'), 'state_transitions.hash as tx_hash', 'state_transitions.data as data', 'state_transitions.type as type', 'state_transitions.index as index', 'state_transitions.gas_used as gas_used', 'state_transitions.status as status', 'state_transitions.error as error', 'state_transitions.block_hash as block_hash', 'state_transitions.id as id', 'state_transitions.owner as owner') .select(this.knex.raw(`rank() over (order by state_transitions.id ${order}) rank`)) + .select('aliases') + .leftJoin(aliasesSubquery, 'aliases.identity_identifier', 'state_transitions.owner') .as('state_transitions') const rows = await this.knex(subquery) .select('total_count', 'data', 'type', 'index', 'rank', 'block_hash', 'state_transitions.tx_hash as tx_hash', - 'gas_used', 'status', 'error', 'blocks.height as block_height', 'blocks.timestamp as timestamp', 'owner') + 'gas_used', 'status', 'error', 'blocks.height as block_height', 'blocks.timestamp as timestamp', 'owner', 'aliases') .leftJoin('blocks', 'blocks.hash', 'block_hash') .whereBetween('rank', [fromRank, toRank]) .orderBy('state_transitions.id', order) diff --git a/packages/api/src/models/Transaction.js b/packages/api/src/models/Transaction.js index 69e3ec1f6..d7b133651 100644 --- a/packages/api/src/models/Transaction.js +++ b/packages/api/src/models/Transaction.js @@ -26,11 +26,24 @@ module.exports = class Transaction { this.gasUsed = gasUsed ?? null this.status = status ?? null this.error = error ?? null - this.owner = owner ? owner.trim() : null + this.owner = owner || null } - // eslint-disable-next-line camelcase - static fromRow ({ tx_hash, index, block_hash, block_height, type, data, timestamp, gas_used, status, error, owner }) { + /* eslint-disable camelcase */ + static fromRow ({ + tx_hash, + index, + block_hash, + block_height, + type, + data, + timestamp, + gas_used, + status, + error, + owner, + aliases + }) { let decodedError = null try { @@ -43,6 +56,16 @@ module.exports = class Transaction { decodedError = 'Cannot deserialize' } - return new Transaction(tx_hash, index, block_hash, block_height, type, data, timestamp, parseInt(gas_used), status, decodedError ?? error, owner) + return new Transaction( + tx_hash, index, block_hash, + block_height, type, data, + timestamp, parseInt(gas_used), + status, decodedError ?? error, + aliases + ? { + identifier: owner, + aliases + } + : owner) } } diff --git a/packages/api/src/server.js b/packages/api/src/server.js index 943318896..25c499f84 100644 --- a/packages/api/src/server.js +++ b/packages/api/src/server.js @@ -16,7 +16,6 @@ const ValidatorsController = require('./controllers/ValidatorsController') const { getKnex } = require('./utils') const BlocksDAO = require('./dao/BlocksDAO') const DAPI = require('./DAPI') -const DAPIClient = require('@dashevo/dapi-client') const RateController = require('./controllers/RateController') const { default: loadWasmDpp } = require('dash').PlatformProtocol @@ -45,16 +44,16 @@ let dapi module.exports = { start: async () => { - client = new Dash.Client() + client = new Dash.Client({ + dapiAddresses: (process.env.DAPI_URL ?? '127.0.0.1:1443:self-signed').split(','), + network: process.env.NETWORK ?? 'testnet' + }) await loadWasmDpp() await client.platform.initialize() - const dapiClient = new DAPIClient({ - dapiAddresses: (process.env.DAPI_URL ?? '127.0.0.1:1443:self-signed').split(','), - network: process.env.NETWORK ?? 'testnet' - }) + const dapiClient = client.getDAPIClient() const { dpp } = client.platform @@ -79,7 +78,7 @@ module.exports = { const mainController = new MainController(knex, dapi) const epochController = new EpochController(knex, dapi) const blocksController = new BlocksController(knex) - const transactionsController = new TransactionsController(client, knex) + const transactionsController = new TransactionsController(client, knex, dapi) const dataContractsController = new DataContractsController(knex) const documentsController = new DocumentsController(knex) const identitiesController = new IdentitiesController(knex, dapi) diff --git a/packages/api/test/integration/transactions.spec.js b/packages/api/test/integration/transactions.spec.js index f1df2708d..4b01ab46c 100644 --- a/packages/api/test/integration/transactions.spec.js +++ b/packages/api/test/integration/transactions.spec.js @@ -6,6 +6,7 @@ const { getKnex } = require('../../src/utils') const fixtures = require('../utils/fixtures') const StateTransitionEnum = require('../../src/enums/StateTransitionEnum') const tenderdashRpc = require('../../src/tenderdashRpc') +const DAPI = require('../../src/DAPI') describe('Transaction routes', () => { let app @@ -13,6 +14,7 @@ describe('Transaction routes', () => { let knex let identity + let identityAlias let block let transactions @@ -25,6 +27,8 @@ describe('Transaction routes', () => { } })) + mock.method(DAPI.prototype, 'getContestedState', async () => null) + const startDate = new Date(new Date() - 1000 * 60 * 60) app = await server.start() @@ -38,6 +42,8 @@ describe('Transaction routes', () => { }) identity = await fixtures.identity(knex, { block_hash: block.hash }) + identityAlias = await fixtures.identity_alias(knex, { alias: 'test.dash', identity }) + transactions = [{ transaction: identity.transaction, block }] // error tx @@ -105,7 +111,10 @@ describe('Transaction routes', () => { gasUsed: transaction.transaction.gas_used, status: transaction.transaction.status, error: transaction.transaction.error, - owner: transaction.transaction.owner + owner: { + identifier: transaction.transaction.owner, + aliases: [identityAlias.alias] + } } assert.deepEqual(expectedTransaction, body) @@ -128,7 +137,10 @@ describe('Transaction routes', () => { gasUsed: 0, status: 'FAIL', error: 'Cannot deserialize', - owner: transaction.transaction.owner + owner: { + identifier: transaction.transaction.owner, + aliases: [identityAlias.alias] + } } assert.deepEqual(expectedTransaction, body) @@ -165,7 +177,10 @@ describe('Transaction routes', () => { gasUsed: transaction.transaction.gas_used, status: transaction.transaction.status, error: transaction.transaction.error, - owner: transaction.transaction.owner + owner: { + identifier: transaction.transaction.owner, + aliases: [identityAlias.alias] + } })) assert.deepEqual(expectedTransactions, body.resultSet) @@ -195,7 +210,10 @@ describe('Transaction routes', () => { gasUsed: transaction.transaction.gas_used, status: transaction.transaction.status, error: transaction.transaction.error, - owner: transaction.transaction.owner + owner: { + identifier: transaction.transaction.owner, + aliases: [identityAlias.alias] + } })) assert.deepEqual(expectedTransactions, body.resultSet) @@ -225,7 +243,10 @@ describe('Transaction routes', () => { gasUsed: transaction.transaction.gas_used, status: transaction.transaction.status, error: transaction.transaction.error, - owner: transaction.transaction.owner + owner: { + identifier: transaction.transaction.owner, + aliases: [identityAlias.alias] + } })) assert.deepEqual(expectedTransactions, body.resultSet) @@ -255,7 +276,10 @@ describe('Transaction routes', () => { gasUsed: transaction.transaction.gas_used, status: transaction.transaction.status, error: transaction.transaction.error, - owner: transaction.transaction.owner + owner: { + identifier: transaction.transaction.owner, + aliases: [identityAlias.alias] + } })) assert.deepEqual(expectedTransactions, body.resultSet) From 42b93aa5b0039369200e9de5f51ba8de841c7e35 Mon Sep 17 00:00:00 2001 From: owl352 Date: Sat, 9 Nov 2024 01:49:27 +0300 Subject: [PATCH 12/35] README.md update --- packages/api/README.md | 10 ++++++++-- packages/frontend/src/app/api/content.md | 10 ++++++++-- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/packages/api/README.md b/packages/api/README.md index 1b1f7fa66..28a0013d4 100644 --- a/packages/api/README.md +++ b/packages/api/README.md @@ -413,7 +413,10 @@ GET /transaction/DEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEE gasUsed: 1337000, status: "SUCCESS", error: null, - owner: "6q9RFbeea73tE31LGMBLFZhtBUX3wZL3TcNynqE18Zgs" + owner: { + identifier: "6q9RFbeea73tE31LGMBLFZhtBUX3wZL3TcNynqE18Zgs", + aliases: [] + } } ``` @@ -452,7 +455,10 @@ GET /transactions?=1&limit=10&order=asc gasUsed: 1337000, status: "SUCCESS", error: null, - owner: "6q9RFbeea73tE31LGMBLFZhtBUX3wZL3TcNynqE18Zgs" + owner: { + identifier: "6q9RFbeea73tE31LGMBLFZhtBUX3wZL3TcNynqE18Zgs", + aliases: [] + } }, ... ] } diff --git a/packages/frontend/src/app/api/content.md b/packages/frontend/src/app/api/content.md index d3a64c5c9..c1bd824a2 100644 --- a/packages/frontend/src/app/api/content.md +++ b/packages/frontend/src/app/api/content.md @@ -380,7 +380,10 @@ GET /transaction/DEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEE gasUsed: 1337000, status: "SUCCESS", error: null, - owner: "6q9RFbeea73tE31LGMBLFZhtBUX3wZL3TcNynqE18Zgs" + owner: { + identifier: "6q9RFbeea73tE31LGMBLFZhtBUX3wZL3TcNynqE18Zgs", + aliases: [] + } } ``` @@ -419,7 +422,10 @@ GET /transactions?=1&limit=10&order=asc gasUsed: 1337000, status: "SUCCESS", error: null, - owner: "6q9RFbeea73tE31LGMBLFZhtBUX3wZL3TcNynqE18Zgs" + owner: { + identifier: "6q9RFbeea73tE31LGMBLFZhtBUX3wZL3TcNynqE18Zgs", + aliases: [] + } }, ... ] } From 10b1d22bb75a22ef3ac8c25b85581332c61ed542 Mon Sep 17 00:00:00 2001 From: owl352 Date: Sat, 9 Nov 2024 02:13:08 +0300 Subject: [PATCH 13/35] tiny fixes --- packages/api/src/models/Transaction.js | 4 ++-- packages/api/test/integration/main.spec.js | 15 +++++++++++---- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/packages/api/src/models/Transaction.js b/packages/api/src/models/Transaction.js index d7b133651..0beba1206 100644 --- a/packages/api/src/models/Transaction.js +++ b/packages/api/src/models/Transaction.js @@ -63,9 +63,9 @@ module.exports = class Transaction { status, decodedError ?? error, aliases ? { - identifier: owner, + identifier: owner?.trim(), aliases } - : owner) + : owner?.trim()) } } diff --git a/packages/api/test/integration/main.spec.js b/packages/api/test/integration/main.spec.js index 3f5f78f8a..cb29c311b 100644 --- a/packages/api/test/integration/main.spec.js +++ b/packages/api/test/integration/main.spec.js @@ -119,15 +119,19 @@ describe('Other routes', () => { for (let i = 0; i < 48; i++) { const tmpBlock = await fixtures.block(knex, { - timestamp: new Date(new Date().getTime() - 3600000 * i) + timestamp: new Date(new Date().getTime() - 3600000 * i), + height: i + 10 }) + const transaction = await fixtures.transaction(knex, { block_hash: tmpBlock.hash, type: 0, owner: identity.identifier, gas_used: 10000 }) + transactions.push(transaction.hash) + blocks.push(tmpBlock) } }) @@ -174,7 +178,10 @@ describe('Other routes', () => { gasUsed: dataContractTransaction.gas_used, status: dataContractTransaction.status, error: dataContractTransaction.error, - owner: dataContractTransaction.owner + owner: { + identifier: dataContractTransaction.owner, + aliases: [identityAlias.alias] + } } assert.deepEqual({ transaction: expectedTransaction }, body) @@ -195,7 +202,7 @@ describe('Other routes', () => { l1LockedHeight: block.l1_locked_height, validator: block.validator }, - txs: transactions + txs: [identityTransaction.hash, dataContractTransaction.hash, documentTransaction.hash] } assert.deepEqual({ block: expectedBlock }, body) @@ -323,7 +330,7 @@ describe('Other routes', () => { api: { version: require('../../package.json').version, block: { - height: 10, + height: blocks.length - 1, hash: blocks[blocks.length - 1].hash, timestamp: blocks[blocks.length - 1].timestamp.toISOString() } From e579d4b9aee5fbcde56df8965c8d5d8f0fd602f0 Mon Sep 17 00:00:00 2001 From: owl352 Date: Sun, 17 Nov 2024 14:08:39 +0300 Subject: [PATCH 14/35] fixes --- packages/api/package.json | 2 +- packages/api/src/DAPI.js | 17 +++++++++++++++-- packages/api/src/constants.js | 2 +- .../api/src/controllers/IdentitiesController.js | 8 +++----- packages/api/src/controllers/MainController.js | 2 +- packages/api/src/dao/IdentitiesDAO.js | 17 ++++++++++------- packages/api/src/routes.js | 2 +- packages/api/src/utils.js | 11 ++--------- 8 files changed, 34 insertions(+), 27 deletions(-) diff --git a/packages/api/package.json b/packages/api/package.json index e5c8ecb71..60766c773 100644 --- a/packages/api/package.json +++ b/packages/api/package.json @@ -17,7 +17,7 @@ "@scure/base": "^1.1.5", "bs58": "^6.0.0", "cbor": "^9.0.2", - "dash": "4.4.1", + "dash": "4.5.1", "dotenv": "^16.3.1", "fastify": "^4.21.0", "fastify-metrics": "^11.0.0", diff --git a/packages/api/src/DAPI.js b/packages/api/src/DAPI.js index 9f5d02bd9..19a2e2c0b 100644 --- a/packages/api/src/DAPI.js +++ b/packages/api/src/DAPI.js @@ -24,10 +24,23 @@ class DAPI { return epochsInfo } + /** + * Fetch the version upgrade votes status + * @typedef {getContestedState} + * @param {string} contractId - base64 contractId + * @param {string} documentTypeName + * @param {string} indexName + * @param {number} resultType + * @param {Array} indexValuesList + * @param {Buffer} [startAtIdentifierInfo] + * @param {bool} [allowIncludeLockedAndAbstainingVoteTally] + * @param {number} [count] + * @returns {Promise} + */ async getContestedState (contractId, documentTypeName, - indexName = 'parentNameAndLabel', - resultType = 2, + indexName, + resultType, indexValuesList, startAtIdentifierInfo, allowIncludeLockedAndAbstainingVoteTally, count diff --git a/packages/api/src/constants.js b/packages/api/src/constants.js index 72f606188..505d0232c 100644 --- a/packages/api/src/constants.js +++ b/packages/api/src/constants.js @@ -5,7 +5,7 @@ let genesisTime module.exports = { EPOCH_CHANGE_TIME: Number(process.env.EPOCH_CHANGE_TIME), TCP_CONNECT_TIMEOUT: Number(process.env.TCP_CONNECT_TIMEOUT), - DPNS_CONTRACT: process.env.DPNS_CONTRACT ?? '5mjGWa9mruHnLBht3ntbfgodcSoJxA1XIfYiv1PFMVU=', + DPNS_CONTRACT: '5mjGWa9mruHnLBht3ntbfgodcSoJxA1XIfYiv1PFMVU=', get genesisTime () { if (!genesisTime || isNaN(genesisTime)) { return TenderdashRPC.getBlockByHeight(1).then((blockInfo) => { diff --git a/packages/api/src/controllers/IdentitiesController.js b/packages/api/src/controllers/IdentitiesController.js index 33cc6ae63..bea7db472 100644 --- a/packages/api/src/controllers/IdentitiesController.js +++ b/packages/api/src/controllers/IdentitiesController.js @@ -6,7 +6,7 @@ const { base58 } = require('@scure/base') class IdentitiesController { constructor (knex, dapi) { - this.identitiesDAO = new IdentitiesDAO(knex) + this.identitiesDAO = new IdentitiesDAO(knex, dapi) this.dapi = dapi } @@ -19,14 +19,12 @@ class IdentitiesController { return response.status(404).send({ message: 'not found' }) } - const validatedAliases = await validateAliases(identity.aliases, identity.identifier, this.dapi) - const balance = await this.dapi.getIdentityBalance(identifier) - response.send(Identity.fromObject({ ...identity, aliases: validatedAliases, balance })) + response.send(Identity.fromObject({ ...identity, balance })) } - getIdentityByDPNS = async (request, response) => { + getIdentityByDPNSName = async (request, response) => { const { dpns } = request.query let preIdentity diff --git a/packages/api/src/controllers/MainController.js b/packages/api/src/controllers/MainController.js index f98d77e59..65ce543c3 100644 --- a/packages/api/src/controllers/MainController.js +++ b/packages/api/src/controllers/MainController.js @@ -18,7 +18,7 @@ class MainController { this.dataContractsDAO = new DataContractsDAO(knex) this.documentsDAO = new DocumentsDAO(knex) this.transactionsDAO = new TransactionsDAO(knex) - this.identitiesDAO = new IdentitiesDAO(knex) + this.identitiesDAO = new IdentitiesDAO(knex, dapi) this.validatorsDAO = new ValidatorsDAO(knex) this.dapi = dapi } diff --git a/packages/api/src/dao/IdentitiesDAO.js b/packages/api/src/dao/IdentitiesDAO.js index 020e1a772..cb1333925 100644 --- a/packages/api/src/dao/IdentitiesDAO.js +++ b/packages/api/src/dao/IdentitiesDAO.js @@ -4,10 +4,12 @@ const Transaction = require('../models/Transaction') const Document = require('../models/Document') const DataContract = require('../models/DataContract') const PaginatedResultSet = require('../models/PaginatedResultSet') +const { validateAliases } = require('../utils') module.exports = class IdentitiesDAO { - constructor (knex) { + constructor (knex, dapi) { this.knex = knex + this.dapi = dapi } getIdentityByIdentifier = async (identifier) => { @@ -68,7 +70,9 @@ module.exports = class IdentitiesDAO { const [row] = rows - return Identity.fromRow({ ...row }) + const identity = Identity.fromRow({ ...row }) + + return { ...identity, aliases: await validateAliases(identity.aliases, identity.identifier, this.dapi) } } getIdentityByDPNS = async (dpns) => { @@ -108,15 +112,16 @@ module.exports = class IdentitiesDAO { const subquery = this.knex('identities') .select('identities.id as identity_id', 'identities.identifier as identifier', 'identities.owner as identity_owner', - 'identities.is_system as is_system', 'identities.state_transition_hash as tx_hash', + 'identities.is_system as is_system', 'identities.state_transition_hash as tx_hash', 'aliases.aliases as aliases', 'identities.revision as revision') .select(this.knex.raw('COALESCE((select sum(amount) from transfers where recipient = identifier), 0) - COALESCE((select sum(amount) from transfers where sender = identifier), 0) as balance')) .select(this.knex('state_transitions').count('*').whereRaw('owner = identifier').as('total_txs')) .select(this.knex.raw('rank() over (partition by identities.identifier order by identities.id desc) rank')) + .leftJoin(aliasesSubquery, 'identity_identifier', 'identifier') .as('identities') const filteredIdentities = this.knex(subquery) - .select('balance', 'total_txs', 'identity_id', 'identifier', 'identity_owner', 'tx_hash', 'revision', 'rank', 'is_system') + .select('balance', 'aliases', 'total_txs', 'identity_id', 'identifier', 'identity_owner', 'tx_hash', 'revision', 'rank', 'is_system') .select(this.knex.raw(`row_number() over (${getRankString()}) row_number`)) .where('rank', 1) @@ -131,7 +136,7 @@ module.exports = class IdentitiesDAO { .as('as_data_contracts') const rows = await this.knex.with('with_alias', filteredIdentities) - .select('total_txs', 'identity_id', 'identifier', 'identity_owner', 'revision', 'tx_hash', 'blocks.timestamp as timestamp', 'row_number', 'is_system', 'aliases.aliases as aliases', 'balance') + .select('total_txs', 'identity_id', 'aliases', 'identifier', 'identity_owner', 'revision', 'tx_hash', 'blocks.timestamp as timestamp', 'row_number', 'aliases', 'is_system', 'balance') .select(this.knex('with_alias').count('*').as('total_count')) .select(this.knex(this.knex(documentsSubQuery) .select('id', this.knex.raw('rank() over (partition by as_documents.identifier order by as_documents.id desc) rank')).as('ranked_documents')) @@ -142,7 +147,6 @@ module.exports = class IdentitiesDAO { .select(this.knex('transfers').count('*').whereRaw('sender = identifier or recipient = identifier').as('total_transfers')) .leftJoin('state_transitions', 'state_transitions.hash', 'tx_hash') .leftJoin('blocks', 'state_transitions.block_hash', 'blocks.hash') - .leftJoin(aliasesSubquery, 'identity_identifier', 'identifier') .whereBetween('row_number', [fromRank, toRank]) .orderBy(orderByOptions) .from('with_alias') @@ -278,7 +282,6 @@ module.exports = class IdentitiesDAO { 'transfers.state_transition_hash as tx_hash', 'state_transitions.block_hash as block_hash', 'state_transitions.type as type' - ) .select(this.knex.raw(`rank() over (order by transfers.id ${order}) rank`)) .whereRaw(`(transfers.sender = '${identifier}' OR transfers.recipient = '${identifier}') ${ diff --git a/packages/api/src/routes.js b/packages/api/src/routes.js index ba1b24b64..0347fe1a4 100644 --- a/packages/api/src/routes.js +++ b/packages/api/src/routes.js @@ -171,7 +171,7 @@ module.exports = ({ { path: '/dpns/identity', method: 'GET', - handler: identitiesController.getIdentityByDPNS, + handler: identitiesController.getIdentityByDPNSName, schema: { querystring: { type: 'object', diff --git a/packages/api/src/utils.js b/packages/api/src/utils.js index 41df8978e..c38f8175b 100644 --- a/packages/api/src/utils.js +++ b/packages/api/src/utils.js @@ -3,6 +3,7 @@ const StateTransitionEnum = require('./enums/StateTransitionEnum') const net = require('net') const { TCP_CONNECT_TIMEOUT, DPNS_CONTRACT } = require('./constants') const { base58 } = require('@scure/base') +const convertToHomographSafeChars = require('dash/build/utils/convertToHomographSafeChars').default const getKnex = () => { return require('knex')({ @@ -185,15 +186,7 @@ const validateAliases = async (aliases, identifier, dapi) => { const aliasesWithContestedState = await Promise.all(aliases.map(async (alias) => { const [label, domain] = alias.split('.') - const normalizedLabel = label.toLowerCase().replace(/[oli]/g, (match) => { - if (match === 'o') { - return '0' - } - if (match === 'l' || match === 'i') { - return '1' - } - return match - }) + const normalizedLabel = convertToHomographSafeChars(label ?? '') if (/^[a-zA-Z01]{3,19}$/.test(normalizedLabel)) { const domainBuffer = getLabelBuffer(domain) From 664ba7ee6410fbc2d0711bae22fa6c211d9428ea Mon Sep 17 00:00:00 2001 From: owl352 <64574305+owl352@users.noreply.github.com> Date: Sun, 17 Nov 2024 16:09:08 +0500 Subject: [PATCH 15/35] Update packages/api/src/controllers/MainController.js Co-authored-by: pshenmic --- packages/api/src/controllers/MainController.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/api/src/controllers/MainController.js b/packages/api/src/controllers/MainController.js index 65ce543c3..d9f91b1a0 100644 --- a/packages/api/src/controllers/MainController.js +++ b/packages/api/src/controllers/MainController.js @@ -117,7 +117,7 @@ class MainController { const identity = await this.identitiesDAO.getIdentityByIdentifier(query) if (identity) { - // Sending without actual balance and aliases, because on frontend we were making + // Sending without balance and aliases, not available on search, use // request /identity/:identifier for actual data return response.send({ identity }) } From bffe9d77c3ebba4bc658c82c99ec570fbcf97b48 Mon Sep 17 00:00:00 2001 From: owl352 Date: Sun, 17 Nov 2024 14:10:13 +0300 Subject: [PATCH 16/35] fix --- packages/api/src/controllers/MainController.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/api/src/controllers/MainController.js b/packages/api/src/controllers/MainController.js index d9f91b1a0..50cc5e497 100644 --- a/packages/api/src/controllers/MainController.js +++ b/packages/api/src/controllers/MainController.js @@ -117,7 +117,7 @@ class MainController { const identity = await this.identitiesDAO.getIdentityByIdentifier(query) if (identity) { - // Sending without balance and aliases, not available on search, use + // Sending without balance and aliases, not available on search, use // request /identity/:identifier for actual data return response.send({ identity }) } @@ -168,7 +168,7 @@ class MainController { } if (identity) { - // Sending without actual balance and aliases, because on frontend we were making + // Sending without balance and aliases, not available on search, use // request /identity/:identifier for actual data return response.send({ identity }) } From 83d0c869d6ed1ca11cacaf0a962e91d05b5a83b1 Mon Sep 17 00:00:00 2001 From: owl352 Date: Sun, 17 Nov 2024 14:13:38 +0300 Subject: [PATCH 17/35] env update --- packages/api/.env | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/api/.env b/packages/api/.env index 414941241..f784f739d 100644 --- a/packages/api/.env +++ b/packages/api/.env @@ -10,4 +10,3 @@ DASHCORE_PASS=password EPOCH_CHANGE_TIME=3600000 DAPI_URL=127.0.0.1:1443:self-signed TCP_CONNECT_TIMEOUT=400 -DPNS_CONTRACT=5mjGWa9mruHnLBht3ntbfgodcSoJxA1XIfYiv1PFMVU= From ada63dfc73a50726eaeb86eb2ffb087d61aae5b3 Mon Sep 17 00:00:00 2001 From: owl352 Date: Sun, 17 Nov 2024 14:14:05 +0300 Subject: [PATCH 18/35] env update --- packages/api/.env | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/api/.env b/packages/api/.env index 414941241..f784f739d 100644 --- a/packages/api/.env +++ b/packages/api/.env @@ -10,4 +10,3 @@ DASHCORE_PASS=password EPOCH_CHANGE_TIME=3600000 DAPI_URL=127.0.0.1:1443:self-signed TCP_CONNECT_TIMEOUT=400 -DPNS_CONTRACT=5mjGWa9mruHnLBht3ntbfgodcSoJxA1XIfYiv1PFMVU= From 3f9830c4fededc141dc6bde4804f144ec8a1d7e2 Mon Sep 17 00:00:00 2001 From: owl352 Date: Sun, 17 Nov 2024 16:13:42 +0300 Subject: [PATCH 19/35] fixes --- .../src/controllers/IdentitiesController.js | 23 ++---------- .../api/src/controllers/MainController.js | 4 --- packages/api/src/dao/IdentitiesDAO.js | 35 ++++++++++++++----- packages/api/src/models/Identity.js | 2 +- 4 files changed, 30 insertions(+), 34 deletions(-) diff --git a/packages/api/src/controllers/IdentitiesController.js b/packages/api/src/controllers/IdentitiesController.js index bea7db472..47cab1cf8 100644 --- a/packages/api/src/controllers/IdentitiesController.js +++ b/packages/api/src/controllers/IdentitiesController.js @@ -1,7 +1,6 @@ const IdentitiesDAO = require('../dao/IdentitiesDAO') const { IDENTITY_CREDIT_WITHDRAWAL } = require('../enums/StateTransitionEnum') const { validateAliases } = require('../utils') -const Identity = require('../models/Identity') const { base58 } = require('@scure/base') class IdentitiesController { @@ -19,9 +18,7 @@ class IdentitiesController { return response.status(404).send({ message: 'not found' }) } - const balance = await this.dapi.getIdentityBalance(identifier) - - response.send(Identity.fromObject({ ...identity, balance })) + response.send(identity) } getIdentityByDPNSName = async (request, response) => { @@ -60,13 +57,7 @@ class IdentitiesController { return response.status(404).send({ message: 'not found' }) } - const balance = await this.dapi.getIdentityBalance(identity.identifier) - - const validatedAliases = await validateAliases(identity.aliases, identity.identifier, this.dapi) - - identity = Identity.fromObject({ ...identity, aliases: validatedAliases }) - - response.send({ ...identity, balance }) + response.send(identity) } getIdentities = async (request, response) => { @@ -74,15 +65,7 @@ class IdentitiesController { const identities = await this.identitiesDAO.getIdentities(Number(page ?? 1), Number(limit ?? 10), order, orderBy) - const identitiesWithBalance = await Promise.all(identities.resultSet.map(async identity => { - const balance = await this.dapi.getIdentityBalance(identity.identifier) - - const validatedAliases = await validateAliases(identity.aliases, identity.identifier, this.dapi) - - return { ...identity, aliases: validatedAliases, balance } - })) - - response.send({ ...identities, resultSet: identitiesWithBalance }) + response.send(identities) } getTransactionsByIdentity = async (request, response) => { diff --git a/packages/api/src/controllers/MainController.js b/packages/api/src/controllers/MainController.js index 50cc5e497..3e5336614 100644 --- a/packages/api/src/controllers/MainController.js +++ b/packages/api/src/controllers/MainController.js @@ -117,8 +117,6 @@ class MainController { const identity = await this.identitiesDAO.getIdentityByIdentifier(query) if (identity) { - // Sending without balance and aliases, not available on search, use - // request /identity/:identifier for actual data return response.send({ identity }) } @@ -168,8 +166,6 @@ class MainController { } if (identity) { - // Sending without balance and aliases, not available on search, use - // request /identity/:identifier for actual data return response.send({ identity }) } } diff --git a/packages/api/src/dao/IdentitiesDAO.js b/packages/api/src/dao/IdentitiesDAO.js index cb1333925..cdbe58e45 100644 --- a/packages/api/src/dao/IdentitiesDAO.js +++ b/packages/api/src/dao/IdentitiesDAO.js @@ -70,9 +70,16 @@ module.exports = class IdentitiesDAO { const [row] = rows - const identity = Identity.fromRow({ ...row }) + if (!row) { + return null + } - return { ...identity, aliases: await validateAliases(identity.aliases, identity.identifier, this.dapi) } + const identity = Identity.fromRow({ ...row }) + return { + ...identity, + aliases: await validateAliases(identity.aliases, identity.identifier, this.dapi), + balance: await this.dapi.getIdentityBalance(identity.identifier.trim()) + } } getIdentityByDPNS = async (dpns) => { @@ -153,13 +160,23 @@ module.exports = class IdentitiesDAO { const totalCount = rows.length > 0 ? Number(rows[0].total_count) : 0 - return new PaginatedResultSet(rows.map(row => Identity.fromRow({ - ...row, - owner: row.identity_owner, - total_data_contracts: parseInt(row.total_data_contracts), - total_documents: parseInt(row.total_documents), - total_txs: parseInt(row.total_txs) - })), page, limit, totalCount) + const resultSet = await Promise.all(rows.map(async row => { + const balance = await this.dapi.getIdentityBalance(row.identifier.trim()) + + const validatedAliases = await validateAliases(row.aliases ?? [], row.identifier.trim(), this.dapi) + + return Identity.fromRow({ + ...row, + owner: row.identity_owner, + total_data_contracts: parseInt(row.total_data_contracts), + total_documents: parseInt(row.total_documents), + total_txs: parseInt(row.total_txs), + balance, + aliases: validatedAliases + }) + })) + + return new PaginatedResultSet(resultSet, page, limit, totalCount) } getDataContractsByIdentity = async (identifier, page, limit, order) => { diff --git a/packages/api/src/models/Identity.js b/packages/api/src/models/Identity.js index 229fc2fb3..dc6363ff2 100644 --- a/packages/api/src/models/Identity.js +++ b/packages/api/src/models/Identity.js @@ -28,7 +28,7 @@ module.exports = class Identity { // eslint-disable-next-line camelcase static fromRow ({ identifier, owner, revision, balance, timestamp, total_txs, total_data_contracts, total_documents, total_transfers, tx_hash, is_system, aliases }) { - return new Identity(identifier, owner, revision, Number(balance), timestamp, Number(total_txs), Number(total_data_contracts), Number(total_documents), Number(total_transfers), tx_hash, is_system, aliases) + return new Identity(identifier?.trim(), owner, revision, Number(balance), timestamp, Number(total_txs), Number(total_data_contracts), Number(total_documents), Number(total_transfers), tx_hash, is_system, aliases) } static fromObject ({ identifier, owner, revision, balance, timestamp, totalTxs, totalDataContracts, totalDocuments, totalTransfers, txHash, isSystem, aliases }) { From 07ac06ffc20770650669d4558bb7f224946888ce Mon Sep 17 00:00:00 2001 From: owl352 Date: Sun, 17 Nov 2024 16:13:42 +0300 Subject: [PATCH 20/35] fixes --- .../src/controllers/IdentitiesController.js | 23 ++---------- .../api/src/controllers/MainController.js | 4 --- packages/api/src/dao/IdentitiesDAO.js | 35 ++++++++++++++----- packages/api/src/models/Identity.js | 2 +- 4 files changed, 30 insertions(+), 34 deletions(-) diff --git a/packages/api/src/controllers/IdentitiesController.js b/packages/api/src/controllers/IdentitiesController.js index bea7db472..47cab1cf8 100644 --- a/packages/api/src/controllers/IdentitiesController.js +++ b/packages/api/src/controllers/IdentitiesController.js @@ -1,7 +1,6 @@ const IdentitiesDAO = require('../dao/IdentitiesDAO') const { IDENTITY_CREDIT_WITHDRAWAL } = require('../enums/StateTransitionEnum') const { validateAliases } = require('../utils') -const Identity = require('../models/Identity') const { base58 } = require('@scure/base') class IdentitiesController { @@ -19,9 +18,7 @@ class IdentitiesController { return response.status(404).send({ message: 'not found' }) } - const balance = await this.dapi.getIdentityBalance(identifier) - - response.send(Identity.fromObject({ ...identity, balance })) + response.send(identity) } getIdentityByDPNSName = async (request, response) => { @@ -60,13 +57,7 @@ class IdentitiesController { return response.status(404).send({ message: 'not found' }) } - const balance = await this.dapi.getIdentityBalance(identity.identifier) - - const validatedAliases = await validateAliases(identity.aliases, identity.identifier, this.dapi) - - identity = Identity.fromObject({ ...identity, aliases: validatedAliases }) - - response.send({ ...identity, balance }) + response.send(identity) } getIdentities = async (request, response) => { @@ -74,15 +65,7 @@ class IdentitiesController { const identities = await this.identitiesDAO.getIdentities(Number(page ?? 1), Number(limit ?? 10), order, orderBy) - const identitiesWithBalance = await Promise.all(identities.resultSet.map(async identity => { - const balance = await this.dapi.getIdentityBalance(identity.identifier) - - const validatedAliases = await validateAliases(identity.aliases, identity.identifier, this.dapi) - - return { ...identity, aliases: validatedAliases, balance } - })) - - response.send({ ...identities, resultSet: identitiesWithBalance }) + response.send(identities) } getTransactionsByIdentity = async (request, response) => { diff --git a/packages/api/src/controllers/MainController.js b/packages/api/src/controllers/MainController.js index 50cc5e497..3e5336614 100644 --- a/packages/api/src/controllers/MainController.js +++ b/packages/api/src/controllers/MainController.js @@ -117,8 +117,6 @@ class MainController { const identity = await this.identitiesDAO.getIdentityByIdentifier(query) if (identity) { - // Sending without balance and aliases, not available on search, use - // request /identity/:identifier for actual data return response.send({ identity }) } @@ -168,8 +166,6 @@ class MainController { } if (identity) { - // Sending without balance and aliases, not available on search, use - // request /identity/:identifier for actual data return response.send({ identity }) } } diff --git a/packages/api/src/dao/IdentitiesDAO.js b/packages/api/src/dao/IdentitiesDAO.js index cb1333925..cdbe58e45 100644 --- a/packages/api/src/dao/IdentitiesDAO.js +++ b/packages/api/src/dao/IdentitiesDAO.js @@ -70,9 +70,16 @@ module.exports = class IdentitiesDAO { const [row] = rows - const identity = Identity.fromRow({ ...row }) + if (!row) { + return null + } - return { ...identity, aliases: await validateAliases(identity.aliases, identity.identifier, this.dapi) } + const identity = Identity.fromRow({ ...row }) + return { + ...identity, + aliases: await validateAliases(identity.aliases, identity.identifier, this.dapi), + balance: await this.dapi.getIdentityBalance(identity.identifier.trim()) + } } getIdentityByDPNS = async (dpns) => { @@ -153,13 +160,23 @@ module.exports = class IdentitiesDAO { const totalCount = rows.length > 0 ? Number(rows[0].total_count) : 0 - return new PaginatedResultSet(rows.map(row => Identity.fromRow({ - ...row, - owner: row.identity_owner, - total_data_contracts: parseInt(row.total_data_contracts), - total_documents: parseInt(row.total_documents), - total_txs: parseInt(row.total_txs) - })), page, limit, totalCount) + const resultSet = await Promise.all(rows.map(async row => { + const balance = await this.dapi.getIdentityBalance(row.identifier.trim()) + + const validatedAliases = await validateAliases(row.aliases ?? [], row.identifier.trim(), this.dapi) + + return Identity.fromRow({ + ...row, + owner: row.identity_owner, + total_data_contracts: parseInt(row.total_data_contracts), + total_documents: parseInt(row.total_documents), + total_txs: parseInt(row.total_txs), + balance, + aliases: validatedAliases + }) + })) + + return new PaginatedResultSet(resultSet, page, limit, totalCount) } getDataContractsByIdentity = async (identifier, page, limit, order) => { diff --git a/packages/api/src/models/Identity.js b/packages/api/src/models/Identity.js index 229fc2fb3..dc6363ff2 100644 --- a/packages/api/src/models/Identity.js +++ b/packages/api/src/models/Identity.js @@ -28,7 +28,7 @@ module.exports = class Identity { // eslint-disable-next-line camelcase static fromRow ({ identifier, owner, revision, balance, timestamp, total_txs, total_data_contracts, total_documents, total_transfers, tx_hash, is_system, aliases }) { - return new Identity(identifier, owner, revision, Number(balance), timestamp, Number(total_txs), Number(total_data_contracts), Number(total_documents), Number(total_transfers), tx_hash, is_system, aliases) + return new Identity(identifier?.trim(), owner, revision, Number(balance), timestamp, Number(total_txs), Number(total_data_contracts), Number(total_documents), Number(total_transfers), tx_hash, is_system, aliases) } static fromObject ({ identifier, owner, revision, balance, timestamp, totalTxs, totalDataContracts, totalDocuments, totalTransfers, txHash, isSystem, aliases }) { From 5cc584206f119b503f916df4a2337b5a69c383a2 Mon Sep 17 00:00:00 2001 From: owl352 Date: Sun, 17 Nov 2024 16:30:44 +0300 Subject: [PATCH 21/35] test fix --- packages/api/test/integration/main.spec.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/api/test/integration/main.spec.js b/packages/api/test/integration/main.spec.js index cb29c311b..a8d62c9ea 100644 --- a/packages/api/test/integration/main.spec.js +++ b/packages/api/test/integration/main.spec.js @@ -238,7 +238,7 @@ describe('Other routes', () => { const expectedIdentity = { identifier: identity.identifier, revision: 0, - balance: null, + balance: 0, timestamp: block.timestamp.toISOString(), txHash: identityTransaction.hash, totalTxs: 51, @@ -261,7 +261,7 @@ describe('Other routes', () => { const expectedIdentity = { identifier: identity.identifier, revision: 0, - balance: null, + balance: 0, timestamp: block.timestamp.toISOString(), txHash: identityTransaction.hash, totalTxs: 51, From 2fee3fe73273ef663b9558ff269ca02fb1728e68 Mon Sep 17 00:00:00 2001 From: owl352 Date: Sun, 17 Nov 2024 22:39:23 +0300 Subject: [PATCH 22/35] fixes --- .../src/controllers/IdentitiesController.js | 31 +-------- .../api/src/controllers/MainController.js | 34 +-------- .../src/controllers/TransactionsController.js | 30 ++------ packages/api/src/dao/IdentitiesDAO.js | 44 +++++++++--- packages/api/src/dao/TransactionsDAO.js | 37 +++++++++- packages/api/src/utils.js | 69 +++++++++---------- 6 files changed, 108 insertions(+), 137 deletions(-) diff --git a/packages/api/src/controllers/IdentitiesController.js b/packages/api/src/controllers/IdentitiesController.js index 47cab1cf8..936a4f682 100644 --- a/packages/api/src/controllers/IdentitiesController.js +++ b/packages/api/src/controllers/IdentitiesController.js @@ -1,7 +1,5 @@ const IdentitiesDAO = require('../dao/IdentitiesDAO') const { IDENTITY_CREDIT_WITHDRAWAL } = require('../enums/StateTransitionEnum') -const { validateAliases } = require('../utils') -const { base58 } = require('@scure/base') class IdentitiesController { constructor (knex, dapi) { @@ -24,34 +22,7 @@ class IdentitiesController { getIdentityByDPNSName = async (request, response) => { const { dpns } = request.query - let preIdentity - let identity - - if (!dpns.includes('.')) { - preIdentity = await this.identitiesDAO.getIdentityByDPNS(dpns) - - if (!preIdentity) { - return response.status(404).send({ message: 'not found' }) - } - } - - const [{ contestedState }] = await validateAliases( - [preIdentity ? preIdentity.aliases.find(v => v.includes(`${dpns}.`)) : dpns], - null, - this.dapi - ) - - if (contestedState) { - if (typeof contestedState.finishedVoteInfo?.wonByIdentityId === 'string') { - const identifier = base58.encode(Buffer.from(contestedState.finishedVoteInfo?.wonByIdentityId, 'base64')) - - identity = await this.identitiesDAO.getIdentityByIdentifier(identifier) - } - } - - if (!contestedState) { - identity = preIdentity ?? await this.identitiesDAO.getIdentityByDPNS(dpns) - } + const identity = await this.identitiesDAO.getIdentityByDPNSName(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 3e5336614..b42535c23 100644 --- a/packages/api/src/controllers/MainController.js +++ b/packages/api/src/controllers/MainController.js @@ -6,8 +6,6 @@ const IdentitiesDAO = require('../dao/IdentitiesDAO') const ValidatorsDAO = require('../dao/ValidatorsDAO') const TenderdashRPC = require('../tenderdashRpc') const Epoch = require('../models/Epoch') -const { validateAliases } = require('../utils') -const { base58 } = require('@scure/base') const API_VERSION = require('../../package.json').version const PLATFORM_VERSION = '1' + require('../../package.json').dependencies.dash.substring(1) @@ -17,7 +15,7 @@ class MainController { this.blocksDAO = new BlocksDAO(knex) this.dataContractsDAO = new DataContractsDAO(knex) this.documentsDAO = new DocumentsDAO(knex) - this.transactionsDAO = new TransactionsDAO(knex) + this.transactionsDAO = new TransactionsDAO(knex, dapi) this.identitiesDAO = new IdentitiesDAO(knex, dapi) this.validatorsDAO = new ValidatorsDAO(knex) this.dapi = dapi @@ -135,35 +133,9 @@ class MainController { } } + // by dpns name if (/^[^\s.]+(\.[^\s.]+)*$/.test(query)) { - let preIdentity - let identity - - if (!query.includes('.')) { - preIdentity = await this.identitiesDAO.getIdentityByDPNS(query) - - if (!preIdentity) { - return response.status(404).send({ message: 'not found' }) - } - } - - const [{ contestedState }] = await validateAliases( - [preIdentity ? preIdentity.aliases.find(v => v.includes(`${query}.`)) : query], - null, - this.dapi - ) - - if (contestedState) { - if (typeof contestedState.finishedVoteInfo?.wonByIdentityId === 'string') { - const identifier = base58.encode(Buffer.from(contestedState.finishedVoteInfo?.wonByIdentityId, 'base64')) - - identity = await this.identitiesDAO.getIdentityByIdentifier(identifier) - } - } - - if (!contestedState) { - identity = preIdentity ?? await this.identitiesDAO.getIdentityByDPNS(query) - } + const identity = await this.identitiesDAO.getIdentityByDPNSName(query) if (identity) { return response.send({ identity }) diff --git a/packages/api/src/controllers/TransactionsController.js b/packages/api/src/controllers/TransactionsController.js index da88ffa0e..09aafbd60 100644 --- a/packages/api/src/controllers/TransactionsController.js +++ b/packages/api/src/controllers/TransactionsController.js @@ -1,11 +1,11 @@ const TransactionsDAO = require('../dao/TransactionsDAO') const utils = require('../utils') -const { calculateInterval, validateAliases } = require('../utils') +const { calculateInterval } = require('../utils') class TransactionsController { constructor (client, knex, dapi) { this.client = client - this.transactionsDAO = new TransactionsDAO(knex) + this.transactionsDAO = new TransactionsDAO(knex, dapi) this.dapi = dapi } @@ -18,17 +18,7 @@ class TransactionsController { return reply.status(404).send({ message: 'not found' }) } - const validatedAliases = transaction.owner.aliases?.length > 0 - ? await validateAliases(transaction.owner.aliases ?? [], transaction.owner?.identifier, this.dapi) - : [] - - reply.send({ - ...transaction, - owner: { - ...transaction.owner, - aliases: validatedAliases - } - }) + reply.send(transaction) } getTransactions = async (request, response) => { @@ -40,19 +30,7 @@ class TransactionsController { const transactions = await this.transactionsDAO.getTransactions(Number(page ?? 1), Number(limit ?? 10), order) - const transactionsWithCorrectAliases = await Promise.all(transactions.resultSet.map(async transaction => - ({ - ...transaction, - owner: { - ...transaction.owner, - aliases: transaction.owner.aliases?.length > 0 - ? await validateAliases(transaction.owner.aliases ?? [], transaction.owner?.identifier, this.dapi) - : [] - } - }) - )) - - response.send({ ...transactions, resultSet: transactionsWithCorrectAliases }) + response.send(transactions) } getTransactionHistory = async (request, response) => { diff --git a/packages/api/src/dao/IdentitiesDAO.js b/packages/api/src/dao/IdentitiesDAO.js index cdbe58e45..8a4b1f411 100644 --- a/packages/api/src/dao/IdentitiesDAO.js +++ b/packages/api/src/dao/IdentitiesDAO.js @@ -4,7 +4,8 @@ const Transaction = require('../models/Transaction') const Document = require('../models/Document') const DataContract = require('../models/DataContract') const PaginatedResultSet = require('../models/PaginatedResultSet') -const { validateAliases } = require('../utils') +const { getAliasInfo } = require('../utils') +const { base58 } = require('@scure/base') module.exports = class IdentitiesDAO { constructor (knex, dapi) { @@ -74,22 +75,34 @@ module.exports = class IdentitiesDAO { return null } - const identity = Identity.fromRow({ ...row }) + const identity = Identity.fromRow(row) + + const aliases = await Promise.all(identity.aliases.map(async alias => { + const contested = await getAliasInfo(alias, this.dapi) + + const isLocked = base58.encode( + Buffer.from(contested.contestedState?.finishedVoteInfo?.wonByIdentityId ?? ''), + 'base64') !== identifier + + return { + alias, + status: (contested.contestedState !== null && isLocked) ? 'locked' : 'ok' + } + })) + return { ...identity, - aliases: await validateAliases(identity.aliases, identity.identifier, this.dapi), + aliases, balance: await this.dapi.getIdentityBalance(identity.identifier.trim()) } } - getIdentityByDPNS = async (dpns) => { - const identifier = this.knex('identity_aliases') - .select('identity_identifier') + getIdentityByDPNSName = async (dpns) => { + const [identity] = await this.knex('identity_aliases') + .select('identity_identifier', 'alias') .whereRaw(`LOWER(alias) LIKE LOWER('${dpns}${dpns.includes('.') ? '' : '.%'}')`) .limit(1) - const identity = await this.getIdentityByIdentifier(identifier) - return identity } @@ -163,7 +176,18 @@ module.exports = class IdentitiesDAO { const resultSet = await Promise.all(rows.map(async row => { const balance = await this.dapi.getIdentityBalance(row.identifier.trim()) - const validatedAliases = await validateAliases(row.aliases ?? [], row.identifier.trim(), this.dapi) + const aliases = await Promise.all((row.aliases ?? []).map(async alias => { + const contested = await getAliasInfo(alias, this.dapi) + + const isLocked = base58.encode( + Buffer.from(contested.contestedState?.finishedVoteInfo?.wonByIdentityId ?? ''), + 'base64') !== row.identifier + + return { + alias, + status: (contested.contestedState !== null && isLocked) ? 'locked' : 'ok' + } + })) return Identity.fromRow({ ...row, @@ -172,7 +196,7 @@ module.exports = class IdentitiesDAO { total_documents: parseInt(row.total_documents), total_txs: parseInt(row.total_txs), balance, - aliases: validatedAliases + aliases }) })) diff --git a/packages/api/src/dao/TransactionsDAO.js b/packages/api/src/dao/TransactionsDAO.js index 156d48a66..3b64e683f 100644 --- a/packages/api/src/dao/TransactionsDAO.js +++ b/packages/api/src/dao/TransactionsDAO.js @@ -1,10 +1,13 @@ const Transaction = require('../models/Transaction') const PaginatedResultSet = require('../models/PaginatedResultSet') const SeriesData = require('../models/SeriesData') +const { getAliasInfo } = require('../utils') +const { base58 } = require('@scure/base') module.exports = class TransactionsDAO { - constructor (knex) { + constructor (knex, dapi) { this.knex = knex + this.dapi = dapi } getTransactionByHash = async (hash) => { @@ -30,7 +33,20 @@ module.exports = class TransactionsDAO { return null } - return Transaction.fromRow(row) + const aliases = await Promise.all(row.aliases.map(async alias => { + const contested = await getAliasInfo(alias, this.dapi) + + const isLocked = base58.encode( + Buffer.from(contested.contestedState?.finishedVoteInfo?.wonByIdentityId ?? ''), + 'base64') !== row.identifier + + return { + alias, + status: (contested.contestedState !== null && isLocked) ? 'locked' : 'ok' + } + })) + + return Transaction.fromRow({ ...row, aliases }) } getTransactions = async (page, limit, order) => { @@ -60,7 +76,22 @@ module.exports = class TransactionsDAO { .orderBy('state_transitions.id', order) const totalCount = rows.length > 0 ? Number(rows[0].total_count) : 0 - const resultSet = rows.map((row) => Transaction.fromRow(row)) + const resultSet = await Promise.all(rows.map(async (row) => { + const aliases = await Promise.all((row.aliases ?? []).map(async alias => { + const contested = await getAliasInfo(alias, this.dapi) + + const isLocked = base58.encode( + Buffer.from(contested.contestedState?.finishedVoteInfo?.wonByIdentityId ?? ''), + 'base64') !== row.identifier + + return { + alias, + status: (contested.contestedState !== null && isLocked) ? 'locked' : 'ok' + } + })) + + return Transaction.fromRow({ ...row, aliases }) + })) return new PaginatedResultSet(resultSet, page, limit, totalCount) } diff --git a/packages/api/src/utils.js b/packages/api/src/utils.js index c38f8175b..7b2f053f1 100644 --- a/packages/api/src/utils.js +++ b/packages/api/src/utils.js @@ -2,7 +2,6 @@ const crypto = require('crypto') const StateTransitionEnum = require('./enums/StateTransitionEnum') const net = require('net') const { TCP_CONNECT_TIMEOUT, DPNS_CONTRACT } = require('./constants') -const { base58 } = require('@scure/base') const convertToHomographSafeChars = require('dash/build/utils/convertToHomographSafeChars').default const getKnex = () => { @@ -176,47 +175,44 @@ const calculateInterval = (start, end) => { }, intervalsInRFC[0]) } -const getLabelBuffer = (text) => - Buffer.from(`${ - Buffer.from(`12${`0${(text.length).toString(16)}`.slice(-2) - }`, 'hex')}${text}` +const generateNameIndexBuffer = (name) => { + const lengthBuffer = Buffer.alloc(1) + lengthBuffer.writeUInt8(name.length.toString(16), 0) + + return Buffer.concat( + [ + Buffer.from('12', 'hex'), + lengthBuffer, + Buffer.from(name, 'ascii') + ] ) +} -const validateAliases = async (aliases, identifier, dapi) => { - const aliasesWithContestedState = await Promise.all(aliases.map(async (alias) => { - const [label, domain] = alias.split('.') +const getAliasInfo = async (alias, dapi) => { + const [label, domain] = alias.split('.') - const normalizedLabel = convertToHomographSafeChars(label ?? '') + const normalizedLabel = convertToHomographSafeChars(label ?? '') - if (/^[a-zA-Z01]{3,19}$/.test(normalizedLabel)) { - const domainBuffer = getLabelBuffer(domain) - const labelBuffer = getLabelBuffer(normalizedLabel) + if (/^[a-zA-Z01]{3,19}$/.test(normalizedLabel)) { + const domainBuffer = generateNameIndexBuffer(domain) - const contestedState = await dapi.getContestedState( - DPNS_CONTRACT, - 'domain', - 'parentNameAndLabel', - 1, - [ - domainBuffer, - labelBuffer - ] - ) + const labelBuffer = generateNameIndexBuffer(normalizedLabel) - return { alias, contestedState } - } + const contestedState = await dapi.getContestedState( + DPNS_CONTRACT, + 'domain', + 'parentNameAndLabel', + 1, + [ + domainBuffer, + labelBuffer + ] + ) + + return { alias, contestedState } + } - return { alias, contestedState: null } - })) - - return (identifier - ? aliasesWithContestedState.filter(alias => ( - typeof alias.contestedState?.finishedVoteInfo?.wonByIdentityId === 'string' - ? base58.encode(Buffer.from(alias.contestedState?.finishedVoteInfo.wonByIdentityId, 'base64')) === identifier - : false - ) || alias.contestedState === null - ).map(v => v.alias) - : aliasesWithContestedState) + return { alias, contestedState: null } } module.exports = { @@ -225,6 +221,5 @@ module.exports = { getKnex, checkTcpConnect, calculateInterval, - validateAliases, - getLabelBuffer + getAliasInfo } From f673d569077f3a8593e39dd1e807566d1a8e31ef Mon Sep 17 00:00:00 2001 From: owl352 Date: Sun, 17 Nov 2024 22:44:16 +0300 Subject: [PATCH 23/35] `README.md` update --- packages/api/README.md | 70 ++++++++++++++---------- packages/frontend/src/app/api/content.md | 70 ++++++++++++++---------- 2 files changed, 80 insertions(+), 60 deletions(-) diff --git a/packages/api/README.md b/packages/api/README.md index 28a0013d4..2718c1908 100644 --- a/packages/api/README.md +++ b/packages/api/README.md @@ -415,7 +415,12 @@ GET /transaction/DEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEE error: null, owner: { identifier: "6q9RFbeea73tE31LGMBLFZhtBUX3wZL3TcNynqE18Zgs", - aliases: [] + aliases: [ + { + alias: "alias.dash", + status: "locked" + } + ] } } ``` @@ -457,7 +462,12 @@ GET /transactions?=1&limit=10&order=asc error: null, owner: { identifier: "6q9RFbeea73tE31LGMBLFZhtBUX3wZL3TcNynqE18Zgs", - aliases: [] + aliases: [ + { + alias: "alias.dash", + status: "locked" + } + ] } }, ... ] @@ -607,7 +617,12 @@ GET /identity/GWRSAVFMjXx8HpQFaNJMqBV7MBgMK4br5UESsB4S31Ec totalDocuments: 0, totalDataContracts: 0, isSystem: false, - aliases: ["test.dash"...] + aliases: [ + { + alias: "alias.dash", + status: "locked" + } + ] } ``` Response codes: @@ -620,21 +635,11 @@ Response codes: ### Identity by DPNS Return identity by given DPNS/alias ``` -GET /dpns/identity?dpns=test-name.1.dash +GET /dpns/identity?dpns=canuseethat2.dash { - identifier: "GWRSAVFMjXx8HpQFaNJMqBV7MBgMK4br5UESsB4S31Ec", - owner: "GWRSAVFMjXx8HpQFaNJMqBV7MBgMK4br5UESsB4S31Ec", - revision: 1, - balance: 1000000, - timestamp: "2024-03-18T10:13:54.150Z", - txHash: "DEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF", - totalTxs: 1, - totalTransfers: 0, - totalDocuments: 0, - totalDataContracts: 0, - isSystem: false, - aliases: [] + "identity_identifier": "8eTDkBhpQjHeqgbVeriwLeZr1tCa6yBGw76SckvD1cwc", + "alias": "canuseethat2.dash" } ``` Response codes: @@ -659,20 +664,25 @@ GET /identities?page=1&limit=10&order=asc&order_by=block_height total: 10 }, resultSet: [ - { - identifier: "GWRSAVFMjXx8HpQFaNJMqBV7MBgMK4br5UESsB4S31Ec", - owner: "GWRSAVFMjXx8HpQFaNJMqBV7MBgMK4br5UESsB4S31Ec", - revision: 1, - balance: 1000000, - timestamp: "2024-03-18T10:13:54.150Z", - txHash: "DEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF", - totalTxs: 1, - totalTransfers: 0, - totalDocuments: 0, - totalDataContracts: 0, - isSystem: false, - aliases: ["test.dash"] - }, ... + { + identifier: "GWRSAVFMjXx8HpQFaNJMqBV7MBgMK4br5UESsB4S31Ec", + owner: "GWRSAVFMjXx8HpQFaNJMqBV7MBgMK4br5UESsB4S31Ec", + revision: 1, + balance: 1000000, + timestamp: "2024-03-18T10:13:54.150Z", + txHash: "DEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF", + totalTxs: 1, + totalTransfers: 0, + totalDocuments: 0, + totalDataContracts: 0, + isSystem: false, + aliases: [ + { + alias: "alias.dash", + status: "locked" + } + ] + }, ... ] } ``` diff --git a/packages/frontend/src/app/api/content.md b/packages/frontend/src/app/api/content.md index c1bd824a2..2b65ce0e1 100644 --- a/packages/frontend/src/app/api/content.md +++ b/packages/frontend/src/app/api/content.md @@ -382,7 +382,12 @@ GET /transaction/DEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEE error: null, owner: { identifier: "6q9RFbeea73tE31LGMBLFZhtBUX3wZL3TcNynqE18Zgs", - aliases: [] + aliases: [ + { + alias: "alias.dash", + status: "locked" + } + ] } } ``` @@ -424,7 +429,12 @@ GET /transactions?=1&limit=10&order=asc error: null, owner: { identifier: "6q9RFbeea73tE31LGMBLFZhtBUX3wZL3TcNynqE18Zgs", - aliases: [] + aliases: [ + { + alias: "alias.dash", + status: "locked" + } + ] } }, ... ] @@ -574,7 +584,12 @@ GET /identity/GWRSAVFMjXx8HpQFaNJMqBV7MBgMK4br5UESsB4S31Ec totalDocuments: 0, totalDataContracts: 0, isSystem: false, - aliases: ["test.dash"...] + aliases: [ + { + alias: "alias.dash", + status: "locked" + } + ] } ``` Response codes: @@ -587,21 +602,11 @@ Response codes: ### Identity by DPNS Return identity by given DPNS/alias ``` -GET /dpns/identity?dpns=test-name.1.dash +GET /dpns/identity?dpns=canuseethat2.dash { - identifier: "GWRSAVFMjXx8HpQFaNJMqBV7MBgMK4br5UESsB4S31Ec", - owner: "GWRSAVFMjXx8HpQFaNJMqBV7MBgMK4br5UESsB4S31Ec", - revision: 1, - balance: 1000000, - timestamp: "2024-03-18T10:13:54.150Z", - txHash: "DEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF", - totalTxs: 1, - totalTransfers: 0, - totalDocuments: 0, - totalDataContracts: 0, - isSystem: false, - aliases: [] + "identity_identifier": "8eTDkBhpQjHeqgbVeriwLeZr1tCa6yBGw76SckvD1cwc", + "alias": "canuseethat2.dash" } ``` Response codes: @@ -626,20 +631,25 @@ GET /identities?page=1&limit=10&order=asc&order_by=block_height total: 10 }, resultSet: [ - { - identifier: "GWRSAVFMjXx8HpQFaNJMqBV7MBgMK4br5UESsB4S31Ec", - owner: "GWRSAVFMjXx8HpQFaNJMqBV7MBgMK4br5UESsB4S31Ec", - revision: 1, - balance: 1000000, - timestamp: "2024-03-18T10:13:54.150Z", - txHash: "DEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF", - totalTxs: 1, - totalTransfers: 0, - totalDocuments: 0, - totalDataContracts: 0, - isSystem: false, - aliases: ["test.dash"] - }, ... + { + identifier: "GWRSAVFMjXx8HpQFaNJMqBV7MBgMK4br5UESsB4S31Ec", + owner: "GWRSAVFMjXx8HpQFaNJMqBV7MBgMK4br5UESsB4S31Ec", + revision: 1, + balance: 1000000, + timestamp: "2024-03-18T10:13:54.150Z", + txHash: "DEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF", + totalTxs: 1, + totalTransfers: 0, + totalDocuments: 0, + totalDataContracts: 0, + isSystem: false, + aliases: [ + { + alias: "alias.dash", + status: "locked" + } + ] + }, ... ] } ``` From 3cf5b5f17d7e45043df0cfc42e7ed20e9d7f876c Mon Sep 17 00:00:00 2001 From: owl352 Date: Sun, 17 Nov 2024 22:47:50 +0300 Subject: [PATCH 24/35] `identities.spec.js` update --- .../api/test/integration/identities.spec.js | 293 ++++++++++-------- 1 file changed, 156 insertions(+), 137 deletions(-) diff --git a/packages/api/test/integration/identities.spec.js b/packages/api/test/integration/identities.spec.js index cb231f377..e5c88248c 100644 --- a/packages/api/test/integration/identities.spec.js +++ b/packages/api/test/integration/identities.spec.js @@ -1,8 +1,8 @@ -const { describe, it, before, after, beforeEach, mock } = require('node:test') +const {describe, it, before, after, beforeEach, mock} = require('node:test') const assert = require('node:assert').strict const supertest = require('supertest') const server = require('../../src/server') -const { getKnex } = require('../../src/utils') +const {getKnex} = require('../../src/utils') const fixtures = require('../utils/fixtures') const StateTransitionEnum = require('../../src/enums/StateTransitionEnum') const tenderdashRpc = require('../../src/tenderdashRpc') @@ -57,15 +57,15 @@ describe('Identities routes', () => { describe('getIdentityByIdentifier()', async () => { it('should return identity by identifier', async () => { const block = await fixtures.block(knex) - const identity = await fixtures.identity(knex, { block_hash: block.hash }) - const { alias } = await fixtures.identity_alias(knex, + const identity = await fixtures.identity(knex, {block_hash: block.hash}) + const {alias} = await fixtures.identity_alias(knex, { alias: 'test.dash', identity } ) - const { body } = await client.get(`/identity/${identity.identifier}`) + const {body} = await client.get(`/identity/${identity.identifier}`) .expect(200) .expect('Content-Type', 'application/json; charset=utf-8') @@ -81,7 +81,10 @@ describe('Identities routes', () => { totalDocuments: 0, totalDataContracts: 0, isSystem: false, - aliases: [alias] + aliases: [{ + alias, + status: 'ok' + }] } assert.deepEqual(body, expectedIdentity) @@ -97,10 +100,10 @@ describe('Identities routes', () => { describe('getIdentityByDPNS()', async () => { it('should return identity by dpns', async () => { const block = await fixtures.block(knex) - const identity = await fixtures.identity(knex, { block_hash: block.hash }) - const { alias } = await fixtures.identity_alias(knex, { alias: 'test-name.1.dash', identity }) + const identity = await fixtures.identity(knex, {block_hash: block.hash}) + const {alias} = await fixtures.identity_alias(knex, {alias: 'test-name.1.dash', identity}) - const { body } = await client.get('/dpns/identity?dpns=test-name.1.dash') + const {body} = await client.get('/dpns/identity?dpns=test-name.1.dash') .expect(200) .expect('Content-Type', 'application/json; charset=utf-8') @@ -116,7 +119,10 @@ describe('Identities routes', () => { totalDocuments: 0, totalDataContracts: 0, isSystem: false, - aliases: [alias] + aliases: [{ + alias, + status: 'ok' + }] } assert.deepEqual(body, expectedIdentity) @@ -124,10 +130,10 @@ describe('Identities routes', () => { it('should return identity by dpns with any case', async () => { const block = await fixtures.block(knex) - const identity = await fixtures.identity(knex, { block_hash: block.hash }) - const { alias } = await fixtures.identity_alias(knex, { alias: 'test-name.2.dash', identity }) + const identity = await fixtures.identity(knex, {block_hash: block.hash}) + const {alias} = await fixtures.identity_alias(knex, {alias: 'test-name.2.dash', identity}) - const { body } = await client.get('/dpns/identity?dpns=TeSt-NaME.2.DAsH') + const {body} = await client.get('/dpns/identity?dpns=TeSt-NaME.2.DAsH') .expect(200) .expect('Content-Type', 'application/json; charset=utf-8') @@ -143,7 +149,10 @@ describe('Identities routes', () => { totalDocuments: 0, totalDataContracts: 0, isSystem: false, - aliases: [alias] + aliases: [{ + alias, + status: 'ok' + }] } assert.deepEqual(body, expectedIdentity) @@ -162,14 +171,14 @@ describe('Identities routes', () => { const aliases = [] for (let i = 0; i < 30; i++) { - block = await fixtures.block(knex, { height: i + 1 }) - identity = await fixtures.identity(knex, { block_hash: block.hash }) - alias = await fixtures.identity_alias(knex, { alias: `#test$${i}`, identity }) - identities.push({ identity, block }) + block = await fixtures.block(knex, {height: i + 1}) + identity = await fixtures.identity(knex, {block_hash: block.hash}) + alias = await fixtures.identity_alias(knex, {alias: `#test$${i}`, identity}) + identities.push({identity, block}) aliases.push(alias) } - const { body } = await client.get('/identities') + const {body} = await client.get('/identities') .expect(200) .expect('Content-Type', 'application/json; charset=utf-8') @@ -190,7 +199,9 @@ describe('Identities routes', () => { totalDocuments: 0, totalDataContracts: 0, isSystem: false, - aliases: [aliases.find((_alias) => _alias.identity_identifier === _identity.identity.identifier).alias] + aliases: [ + aliases.find((_alias) => _alias.identity_identifier === _identity.identity.identifier).alias + ].map(alias => ({alias, status: 'ok'})) })) assert.deepEqual(body.resultSet, expectedIdentities) @@ -200,14 +211,14 @@ describe('Identities routes', () => { const aliases = [] for (let i = 0; i < 30; i++) { - block = await fixtures.block(knex, { height: i + 1 }) - identity = await fixtures.identity(knex, { block_hash: block.hash }) - alias = await fixtures.identity_alias(knex, { alias: `#test1$${i}`, identity }) - identities.push({ identity, block }) + block = await fixtures.block(knex, {height: i + 1}) + identity = await fixtures.identity(knex, {block_hash: block.hash}) + alias = await fixtures.identity_alias(knex, {alias: `#test1$${i}`, identity}) + identities.push({identity, block}) aliases.push(alias) } - const { body } = await client.get('/identities?order=desc') + const {body} = await client.get('/identities?order=desc') .expect(200) .expect('Content-Type', 'application/json; charset=utf-8') @@ -230,7 +241,9 @@ describe('Identities routes', () => { totalDocuments: 0, totalDataContracts: 0, isSystem: false, - aliases: [aliases.find((_alias) => _alias.identity_identifier === _identity.identity.identifier).alias] + aliases: [ + aliases.find((_alias) => _alias.identity_identifier === _identity.identity.identifier).alias + ].map(alias => ({alias, status: 'ok'})) })) assert.deepEqual(body.resultSet, expectedIdentities) @@ -241,14 +254,14 @@ describe('Identities routes', () => { const aliases = [] for (let i = 0; i < 30; i++) { - block = await fixtures.block(knex, { height: i + 1 }) - identity = await fixtures.identity(knex, { block_hash: block.hash }) - alias = await fixtures.identity_alias(knex, { alias: `#test2$${i}`, identity }) - identities.push({ identity, block }) + block = await fixtures.block(knex, {height: i + 1}) + identity = await fixtures.identity(knex, {block_hash: block.hash}) + alias = await fixtures.identity_alias(knex, {alias: `#test2$${i}`, identity}) + identities.push({identity, block}) aliases.push(alias) } - const { body } = await client.get('/identities?page=2') + const {body} = await client.get('/identities?page=2') .expect(200) .expect('Content-Type', 'application/json; charset=utf-8') @@ -271,7 +284,9 @@ describe('Identities routes', () => { totalDocuments: 0, totalDataContracts: 0, isSystem: false, - aliases: [aliases.find((_alias) => _alias.identity_identifier === _identity.identity.identifier).alias] + aliases: [ + aliases.find((_alias) => _alias.identity_identifier === _identity.identity.identifier).alias + ].map(alias => ({alias, status: 'ok'})) })) assert.deepEqual(body.resultSet, expectedIdentities) @@ -282,14 +297,14 @@ describe('Identities routes', () => { const aliases = [] for (let i = 0; i < 30; i++) { - block = await fixtures.block(knex, { height: i + 1 }) - identity = await fixtures.identity(knex, { block_hash: block.hash }) - alias = await fixtures.identity_alias(knex, { alias: `#test3$${i}`, identity }) - identities.push({ identity, block }) + block = await fixtures.block(knex, {height: i + 1}) + identity = await fixtures.identity(knex, {block_hash: block.hash}) + alias = await fixtures.identity_alias(knex, {alias: `#test3$${i}`, identity}) + identities.push({identity, block}) aliases.push(alias) } - const { body } = await client.get('/identities?page=2&limit=5&order=desc') + const {body} = await client.get('/identities?page=2&limit=5&order=desc') .expect(200) .expect('Content-Type', 'application/json; charset=utf-8') @@ -313,8 +328,9 @@ describe('Identities routes', () => { totalDocuments: 0, totalDataContracts: 0, isSystem: false, - aliases: [aliases.find((_alias) => _alias.identity_identifier === _identity.identity.identifier).alias] - + aliases: [ + aliases.find((_alias) => _alias.identity_identifier === _identity.identity.identifier).alias + ].map(alias => ({alias, status: 'ok'})) })) assert.deepEqual(body.resultSet, expectedIdentities) @@ -327,8 +343,8 @@ describe('Identities routes', () => { for (let i = 0; i < 30; i++) { const transactions = [] - block = await fixtures.block(knex, { height: i + 1 }) - identity = await fixtures.identity(knex, { block_hash: block.hash }) + block = await fixtures.block(knex, {height: i + 1}) + identity = await fixtures.identity(knex, {block_hash: block.hash}) for (let j = 0; j < Math.floor(Math.random() * 50); j++) { const tx = await fixtures.transaction(knex, { @@ -342,12 +358,12 @@ describe('Identities routes', () => { identity.transactions = transactions - identities.push({ identity, block }) - alias = await fixtures.identity_alias(knex, { alias: `#test3$${i}`, identity }) + identities.push({identity, block}) + alias = await fixtures.identity_alias(knex, {alias: `#test3$${i}`, identity}) aliases.push(alias) } - const { body } = await client.get('/identities?order_by=tx_count&order=desc') + const {body} = await client.get('/identities?order_by=tx_count&order=desc') .expect(200) .expect('Content-Type', 'application/json; charset=utf-8') @@ -371,7 +387,9 @@ describe('Identities routes', () => { totalDocuments: 0, totalDataContracts: 0, isSystem: false, - aliases: [aliases.find((_alias) => _alias.identity_identifier === _identity.identity.identifier).alias] + aliases: [ + aliases.find((_alias) => _alias.identity_identifier === _identity.identity.identifier).alias + ].map(alias => ({alias, status: 'ok'})) })) assert.deepEqual(body.resultSet, expectedIdentities) @@ -382,8 +400,8 @@ describe('Identities routes', () => { const aliases = [] for (let i = 0; i < 30; i++) { - block = await fixtures.block(knex, { height: i + 1 }) - identity = await fixtures.identity(knex, { block_hash: block.hash }) + block = await fixtures.block(knex, {height: i + 1}) + identity = await fixtures.identity(knex, {block_hash: block.hash}) transferTx = await fixtures.transaction(knex, { block_hash: block.hash, type: StateTransitionEnum.IDENTITY_TOP_UP, @@ -397,15 +415,15 @@ describe('Identities routes', () => { identity.balance = transfer.amount - identities.push({ identity, block, transfer }) - alias = await fixtures.identity_alias(knex, { alias: `#test3$${i}`, identity }) + identities.push({identity, block, transfer}) + alias = await fixtures.identity_alias(knex, {alias: `#test3$${i}`, identity}) aliases.push(alias) } mock.reset() mock.method(DAPI.prototype, 'getIdentityBalance', async (identifier) => { - const { identity } = identities.find(({ identity }) => identity.identifier === identifier) + const {identity} = identities.find(({identity}) => identity.identifier === identifier) return identity.balance }) mock.method(tenderdashRpc, 'getBlockByHeight', async () => ({ @@ -416,7 +434,7 @@ describe('Identities routes', () => { } })) - const { body } = await client.get('/identities?order_by=balance&order=desc') + const {body} = await client.get('/identities?order_by=balance&order=desc') .expect(200) .expect('Content-Type', 'application/json; charset=utf-8') @@ -440,8 +458,9 @@ describe('Identities routes', () => { totalDocuments: 0, totalDataContracts: 0, isSystem: false, - aliases: [aliases.find((_alias) => _alias.identity_identifier === _identity.identity.identifier).alias] - + aliases: [ + aliases.find((_alias) => _alias.identity_identifier === _identity.identity.identifier).alias + ].map(alias => ({alias, status: 'ok'})) })) assert.deepEqual(body.resultSet, expectedIdentities) @@ -451,11 +470,11 @@ describe('Identities routes', () => { describe('getDataContractsByIdentity()', async () => { it('should return default set of data contracts by identity', async () => { dataContracts = [] - block = await fixtures.block(knex, { height: 1 }) - identity = await fixtures.identity(knex, { block_hash: block.hash }) + block = await fixtures.block(knex, {height: 1}) + identity = await fixtures.identity(knex, {block_hash: block.hash}) for (let i = 1; i < 31; i++) { - block = await fixtures.block(knex, { height: i + 1 }) + block = await fixtures.block(knex, {height: i + 1}) transaction = await fixtures.transaction(knex, { block_hash: block.hash, owner: identity.identifier, @@ -465,10 +484,10 @@ describe('Identities routes', () => { state_transition_hash: transaction.hash, owner: identity.identifier }) - dataContracts.push({ dataContract, transaction, identity, block }) + dataContracts.push({dataContract, transaction, identity, block}) } - const { body } = await client.get(`/identity/${identity.identifier}/dataContracts`) + const {body} = await client.get(`/identity/${identity.identifier}/dataContracts`) .expect(200) .expect('Content-Type', 'application/json; charset=utf-8') @@ -493,11 +512,11 @@ describe('Identities routes', () => { it('should return default set of data contracts by identity desc', async () => { dataContracts = [] - block = await fixtures.block(knex, { height: 1 }) - identity = await fixtures.identity(knex, { block_hash: block.hash }) + block = await fixtures.block(knex, {height: 1}) + identity = await fixtures.identity(knex, {block_hash: block.hash}) for (let i = 1; i < 31; i++) { - block = await fixtures.block(knex, { height: i + 1 }) + block = await fixtures.block(knex, {height: i + 1}) transaction = await fixtures.transaction(knex, { block_hash: block.hash, owner: identity.identifier, @@ -507,10 +526,10 @@ describe('Identities routes', () => { state_transition_hash: transaction.hash, owner: identity.identifier }) - dataContracts.push({ dataContract, transaction, identity, block }) + dataContracts.push({dataContract, transaction, identity, block}) } - const { body } = await client.get(`/identity/${identity.identifier}/dataContracts?order=desc`) + const {body} = await client.get(`/identity/${identity.identifier}/dataContracts?order=desc`) .expect(200) .expect('Content-Type', 'application/json; charset=utf-8') @@ -538,11 +557,11 @@ describe('Identities routes', () => { it('should allow walk through pages', async () => { dataContracts = [] - block = await fixtures.block(knex, { height: 1 }) - identity = await fixtures.identity(knex, { block_hash: block.hash }) + block = await fixtures.block(knex, {height: 1}) + identity = await fixtures.identity(knex, {block_hash: block.hash}) for (let i = 1; i < 31; i++) { - block = await fixtures.block(knex, { height: i + 1 }) + block = await fixtures.block(knex, {height: i + 1}) transaction = await fixtures.transaction(knex, { block_hash: block.hash, owner: identity.identifier, @@ -552,10 +571,10 @@ describe('Identities routes', () => { state_transition_hash: transaction.hash, owner: identity.identifier }) - dataContracts.push({ dataContract, transaction, identity, block }) + dataContracts.push({dataContract, transaction, identity, block}) } - const { body } = await client.get(`/identity/${identity.identifier}/dataContracts?page=2&limit=5`) + const {body} = await client.get(`/identity/${identity.identifier}/dataContracts?page=2&limit=5`) .expect(200) .expect('Content-Type', 'application/json; charset=utf-8') @@ -583,11 +602,11 @@ describe('Identities routes', () => { it('should allow walk through pages desc', async () => { dataContracts = [] - block = await fixtures.block(knex, { height: 1 }) - identity = await fixtures.identity(knex, { block_hash: block.hash }) + block = await fixtures.block(knex, {height: 1}) + identity = await fixtures.identity(knex, {block_hash: block.hash}) for (let i = 1; i < 31; i++) { - block = await fixtures.block(knex, { height: i + 1 }) + block = await fixtures.block(knex, {height: i + 1}) transaction = await fixtures.transaction(knex, { block_hash: block.hash, owner: identity.identifier, @@ -597,10 +616,10 @@ describe('Identities routes', () => { state_transition_hash: transaction.hash, owner: identity.identifier }) - dataContracts.push({ dataContract, transaction, identity, block }) + dataContracts.push({dataContract, transaction, identity, block}) } - const { body } = await client.get(`/identity/${identity.identifier}/dataContracts?page=2&limit=5&order=desc`) + const {body} = await client.get(`/identity/${identity.identifier}/dataContracts?page=2&limit=5&order=desc`) .expect(200) .expect('Content-Type', 'application/json; charset=utf-8') @@ -630,11 +649,11 @@ describe('Identities routes', () => { describe('getDocumentsByIdentity()', async () => { it('should return default set of data contracts by identity', async () => { documents = [] - block = await fixtures.block(knex, { height: 1 }) - identity = await fixtures.identity(knex, { block_hash: block.hash }) + block = await fixtures.block(knex, {height: 1}) + identity = await fixtures.identity(knex, {block_hash: block.hash}) for (let i = 1; i < 31; i++) { - block = await fixtures.block(knex, { height: i + 1 }) + block = await fixtures.block(knex, {height: i + 1}) dataContractTransaction = await fixtures.transaction(knex, { block_hash: block.hash, owner: identity.identifier, @@ -654,10 +673,10 @@ describe('Identities routes', () => { owner: identity.identifier, data_contract_id: dataContract.id }) - documents.push({ document, dataContract, transaction, identity, block }) + documents.push({document, dataContract, transaction, identity, block}) } - const { body } = await client.get(`/identity/${identity.identifier}/documents`) + const {body} = await client.get(`/identity/${identity.identifier}/documents`) .expect(200) .expect('Content-Type', 'application/json; charset=utf-8') @@ -683,11 +702,11 @@ describe('Identities routes', () => { it('should return default set of data contracts by identity dsc', async () => { documents = [] - block = await fixtures.block(knex, { height: 1 }) - identity = await fixtures.identity(knex, { block_hash: block.hash }) + block = await fixtures.block(knex, {height: 1}) + identity = await fixtures.identity(knex, {block_hash: block.hash}) for (let i = 1; i < 31; i++) { - block = await fixtures.block(knex, { height: i + 1 }) + block = await fixtures.block(knex, {height: i + 1}) dataContractTransaction = await fixtures.transaction(knex, { block_hash: block.hash, owner: identity.identifier, @@ -707,10 +726,10 @@ describe('Identities routes', () => { owner: identity.identifier, data_contract_id: dataContract.id }) - documents.push({ document, dataContract, transaction, identity, block }) + documents.push({document, dataContract, transaction, identity, block}) } - const { body } = await client.get(`/identity/${identity.identifier}/documents?order=desc`) + const {body} = await client.get(`/identity/${identity.identifier}/documents?order=desc`) .expect(200) .expect('Content-Type', 'application/json; charset=utf-8') @@ -739,11 +758,11 @@ describe('Identities routes', () => { it('should be able to walk through pages', async () => { documents = [] - block = await fixtures.block(knex, { height: 1 }) - identity = await fixtures.identity(knex, { block_hash: block.hash }) + block = await fixtures.block(knex, {height: 1}) + identity = await fixtures.identity(knex, {block_hash: block.hash}) for (let i = 1; i < 31; i++) { - block = await fixtures.block(knex, { height: i + 1 }) + block = await fixtures.block(knex, {height: i + 1}) dataContractTransaction = await fixtures.transaction(knex, { block_hash: block.hash, owner: identity.identifier, @@ -763,10 +782,10 @@ describe('Identities routes', () => { owner: identity.identifier, data_contract_id: dataContract.id }) - documents.push({ document, dataContract, transaction, identity, block }) + documents.push({document, dataContract, transaction, identity, block}) } - const { body } = await client.get(`/identity/${identity.identifier}/documents?page=2&limit=3`) + const {body} = await client.get(`/identity/${identity.identifier}/documents?page=2&limit=3`) .expect(200) .expect('Content-Type', 'application/json; charset=utf-8') @@ -795,11 +814,11 @@ describe('Identities routes', () => { it('should be able to walk through pages desc', async () => { documents = [] - block = await fixtures.block(knex, { height: 1 }) - identity = await fixtures.identity(knex, { block_hash: block.hash }) + block = await fixtures.block(knex, {height: 1}) + identity = await fixtures.identity(knex, {block_hash: block.hash}) for (let i = 1; i < 31; i++) { - block = await fixtures.block(knex, { height: i + 1 }) + block = await fixtures.block(knex, {height: i + 1}) dataContractTransaction = await fixtures.transaction(knex, { block_hash: block.hash, owner: identity.identifier, @@ -819,10 +838,10 @@ describe('Identities routes', () => { owner: identity.identifier, data_contract_id: dataContract.id }) - documents.push({ document, dataContract, transaction, identity, block }) + documents.push({document, dataContract, transaction, identity, block}) } - const { body } = await client.get(`/identity/${identity.identifier}/documents?page=2&limit=3&order=desc`) + const {body} = await client.get(`/identity/${identity.identifier}/documents?page=2&limit=3&order=desc`) .expect(200) .expect('Content-Type', 'application/json; charset=utf-8') @@ -852,21 +871,21 @@ describe('Identities routes', () => { describe('getTransactionsByIdentity()', async () => { it('should return default set of transactions by identity', async () => { - block = await fixtures.block(knex, { height: 1 }) - identity = await fixtures.identity(knex, { block_hash: block.hash }) - transactions = [{ transaction: identity.transaction, block }] + block = await fixtures.block(knex, {height: 1}) + identity = await fixtures.identity(knex, {block_hash: block.hash}) + transactions = [{transaction: identity.transaction, block}] for (let i = 1; i < 30; i++) { - block = await fixtures.block(knex, { height: i + 1 }) + block = await fixtures.block(knex, {height: i + 1}) transaction = await fixtures.transaction(knex, { block_hash: block.hash, owner: identity.identifier, type: StateTransitionEnum.DOCUMENTS_BATCH }) - transactions.push({ transaction, block }) + transactions.push({transaction, block}) } - const { body } = await client.get(`/identity/${identity.identifier}/transactions`) + const {body} = await client.get(`/identity/${identity.identifier}/transactions`) .expect(200) .expect('Content-Type', 'application/json; charset=utf-8') @@ -896,21 +915,21 @@ describe('Identities routes', () => { }) it('should return default set of transactions by identity desc', async () => { - block = await fixtures.block(knex, { height: 1 }) - identity = await fixtures.identity(knex, { block_hash: block.hash }) - transactions = [{ transaction: identity.transaction, block }] + block = await fixtures.block(knex, {height: 1}) + identity = await fixtures.identity(knex, {block_hash: block.hash}) + transactions = [{transaction: identity.transaction, block}] for (let i = 1; i < 30; i++) { - block = await fixtures.block(knex, { height: i + 1 }) + block = await fixtures.block(knex, {height: i + 1}) transaction = await fixtures.transaction(knex, { block_hash: block.hash, owner: identity.identifier, type: StateTransitionEnum.DOCUMENTS_BATCH }) - transactions.push({ transaction, block }) + transactions.push({transaction, block}) } - const { body } = await client.get(`/identity/${identity.identifier}/transactions?order=desc`) + const {body} = await client.get(`/identity/${identity.identifier}/transactions?order=desc`) .expect(200) .expect('Content-Type', 'application/json; charset=utf-8') @@ -940,21 +959,21 @@ describe('Identities routes', () => { }) it('should allow walk through pages', async () => { - block = await fixtures.block(knex, { height: 1 }) - identity = await fixtures.identity(knex, { block_hash: block.hash }) - transactions = [{ transaction: identity.transaction, block }] + block = await fixtures.block(knex, {height: 1}) + identity = await fixtures.identity(knex, {block_hash: block.hash}) + transactions = [{transaction: identity.transaction, block}] for (let i = 1; i < 30; i++) { - block = await fixtures.block(knex, { height: i + 1 }) + block = await fixtures.block(knex, {height: i + 1}) transaction = await fixtures.transaction(knex, { block_hash: block.hash, owner: identity.identifier, type: StateTransitionEnum.DOCUMENTS_BATCH }) - transactions.push({ transaction, block }) + transactions.push({transaction, block}) } - const { body } = await client.get(`/identity/${identity.identifier}/transactions?page=2&limit=4`) + const {body} = await client.get(`/identity/${identity.identifier}/transactions?page=2&limit=4`) .expect(200) .expect('Content-Type', 'application/json; charset=utf-8') @@ -984,21 +1003,21 @@ describe('Identities routes', () => { }) it('should allow walk through pages desc', async () => { - block = await fixtures.block(knex, { height: 1 }) - identity = await fixtures.identity(knex, { block_hash: block.hash }) - transactions = [{ transaction: identity.transaction, block }] + block = await fixtures.block(knex, {height: 1}) + identity = await fixtures.identity(knex, {block_hash: block.hash}) + transactions = [{transaction: identity.transaction, block}] for (let i = 1; i < 30; i++) { - block = await fixtures.block(knex, { height: i + 1 }) + block = await fixtures.block(knex, {height: i + 1}) transaction = await fixtures.transaction(knex, { block_hash: block.hash, owner: identity.identifier, type: StateTransitionEnum.DOCUMENTS_BATCH }) - transactions.push({ transaction, block }) + transactions.push({transaction, block}) } - const { body } = await client.get(`/identity/${identity.identifier}/transactions?page=2&limit=4&order=desc`) + const {body} = await client.get(`/identity/${identity.identifier}/transactions?page=2&limit=4&order=desc`) .expect(200) .expect('Content-Type', 'application/json; charset=utf-8') @@ -1030,12 +1049,12 @@ describe('Identities routes', () => { describe('getTransfersByIdentity()', async () => { it('should return default set of transfers by identity', async () => { - block = await fixtures.block(knex, { height: 1 }) - identity = await fixtures.identity(knex, { block_hash: block.hash }) + block = await fixtures.block(knex, {height: 1}) + identity = await fixtures.identity(knex, {block_hash: block.hash}) transfers = [] for (let i = 1; i < 31; i++) { - block = await fixtures.block(knex, { height: i + 1 }) + block = await fixtures.block(knex, {height: i + 1}) transaction = await fixtures.transaction(knex, { block_hash: block.hash, owner: identity.identifier, @@ -1047,10 +1066,10 @@ describe('Identities routes', () => { sender: null, state_transition_hash: transaction.hash }) - transfers.push({ transfer, transaction, block }) + transfers.push({transfer, transaction, block}) } - const { body } = await client.get(`/identity/${identity.identifier}/transfers`) + const {body} = await client.get(`/identity/${identity.identifier}/transfers`) .expect(200) .expect('Content-Type', 'application/json; charset=utf-8') @@ -1076,12 +1095,12 @@ describe('Identities routes', () => { }) it('should return default set of transfers by identity desc', async () => { - block = await fixtures.block(knex, { height: 1 }) - identity = await fixtures.identity(knex, { block_hash: block.hash }) + block = await fixtures.block(knex, {height: 1}) + identity = await fixtures.identity(knex, {block_hash: block.hash}) transfers = [] for (let i = 1; i < 31; i++) { - block = await fixtures.block(knex, { height: i + 1 }) + block = await fixtures.block(knex, {height: i + 1}) transaction = await fixtures.transaction(knex, { block_hash: block.hash, owner: identity.identifier, @@ -1093,10 +1112,10 @@ describe('Identities routes', () => { sender: null, state_transition_hash: transaction.hash }) - transfers.push({ transfer, transaction, block }) + transfers.push({transfer, transaction, block}) } - const { body } = await client.get(`/identity/${identity.identifier}/transfers?order=desc`) + const {body} = await client.get(`/identity/${identity.identifier}/transfers?order=desc`) .expect(200) .expect('Content-Type', 'application/json; charset=utf-8') @@ -1122,12 +1141,12 @@ describe('Identities routes', () => { }) it('should allow to walk through pages', async () => { - block = await fixtures.block(knex, { height: 1 }) - identity = await fixtures.identity(knex, { block_hash: block.hash }) + block = await fixtures.block(knex, {height: 1}) + identity = await fixtures.identity(knex, {block_hash: block.hash}) transfers = [] for (let i = 1; i < 31; i++) { - block = await fixtures.block(knex, { height: i + 1 }) + block = await fixtures.block(knex, {height: i + 1}) transaction = await fixtures.transaction(knex, { block_hash: block.hash, owner: identity.identifier, @@ -1139,10 +1158,10 @@ describe('Identities routes', () => { sender: null, state_transition_hash: transaction.hash }) - transfers.push({ transfer, transaction, block }) + transfers.push({transfer, transaction, block}) } - const { body } = await client.get(`/identity/${identity.identifier}/transfers?page=2&limit=7`) + const {body} = await client.get(`/identity/${identity.identifier}/transfers?page=2&limit=7`) .expect(200) .expect('Content-Type', 'application/json; charset=utf-8') @@ -1168,12 +1187,12 @@ describe('Identities routes', () => { }) it('should allow to walk through pages desc', async () => { - block = await fixtures.block(knex, { height: 1 }) - identity = await fixtures.identity(knex, { block_hash: block.hash }) + block = await fixtures.block(knex, {height: 1}) + identity = await fixtures.identity(knex, {block_hash: block.hash}) transfers = [] for (let i = 1; i < 31; i++) { - block = await fixtures.block(knex, { height: i + 1 }) + block = await fixtures.block(knex, {height: i + 1}) transaction = await fixtures.transaction(knex, { block_hash: block.hash, owner: identity.identifier, @@ -1185,10 +1204,10 @@ describe('Identities routes', () => { sender: null, state_transition_hash: transaction.hash }) - transfers.push({ transfer, transaction, block }) + transfers.push({transfer, transaction, block}) } - const { body } = await client.get(`/identity/${identity.identifier}/transfers?page=2&limit=7&order=desc`) + const {body} = await client.get(`/identity/${identity.identifier}/transfers?page=2&limit=7&order=desc`) .expect(200) .expect('Content-Type', 'application/json; charset=utf-8') From ed320b990bdf8fe6ad32b76a93495dad23253fae Mon Sep 17 00:00:00 2001 From: owl352 Date: Sun, 17 Nov 2024 22:49:39 +0300 Subject: [PATCH 25/35] `identities.spec.js` and `main.spec.js` updates --- .../api/test/integration/identities.spec.js | 264 +++++++++--------- packages/api/test/integration/main.spec.js | 15 +- 2 files changed, 144 insertions(+), 135 deletions(-) diff --git a/packages/api/test/integration/identities.spec.js b/packages/api/test/integration/identities.spec.js index e5c88248c..afe66bf9f 100644 --- a/packages/api/test/integration/identities.spec.js +++ b/packages/api/test/integration/identities.spec.js @@ -1,8 +1,8 @@ -const {describe, it, before, after, beforeEach, mock} = require('node:test') +const { describe, it, before, after, beforeEach, mock } = require('node:test') const assert = require('node:assert').strict const supertest = require('supertest') const server = require('../../src/server') -const {getKnex} = require('../../src/utils') +const { getKnex } = require('../../src/utils') const fixtures = require('../utils/fixtures') const StateTransitionEnum = require('../../src/enums/StateTransitionEnum') const tenderdashRpc = require('../../src/tenderdashRpc') @@ -57,15 +57,15 @@ describe('Identities routes', () => { describe('getIdentityByIdentifier()', async () => { it('should return identity by identifier', async () => { const block = await fixtures.block(knex) - const identity = await fixtures.identity(knex, {block_hash: block.hash}) - const {alias} = await fixtures.identity_alias(knex, + const identity = await fixtures.identity(knex, { block_hash: block.hash }) + const { alias } = await fixtures.identity_alias(knex, { alias: 'test.dash', identity } ) - const {body} = await client.get(`/identity/${identity.identifier}`) + const { body } = await client.get(`/identity/${identity.identifier}`) .expect(200) .expect('Content-Type', 'application/json; charset=utf-8') @@ -100,10 +100,10 @@ describe('Identities routes', () => { describe('getIdentityByDPNS()', async () => { it('should return identity by dpns', async () => { const block = await fixtures.block(knex) - const identity = await fixtures.identity(knex, {block_hash: block.hash}) - const {alias} = await fixtures.identity_alias(knex, {alias: 'test-name.1.dash', identity}) + const identity = await fixtures.identity(knex, { block_hash: block.hash }) + const { alias } = await fixtures.identity_alias(knex, { alias: 'test-name.1.dash', identity }) - const {body} = await client.get('/dpns/identity?dpns=test-name.1.dash') + const { body } = await client.get('/dpns/identity?dpns=test-name.1.dash') .expect(200) .expect('Content-Type', 'application/json; charset=utf-8') @@ -130,10 +130,10 @@ describe('Identities routes', () => { it('should return identity by dpns with any case', async () => { const block = await fixtures.block(knex) - const identity = await fixtures.identity(knex, {block_hash: block.hash}) - const {alias} = await fixtures.identity_alias(knex, {alias: 'test-name.2.dash', identity}) + const identity = await fixtures.identity(knex, { block_hash: block.hash }) + const { alias } = await fixtures.identity_alias(knex, { alias: 'test-name.2.dash', identity }) - const {body} = await client.get('/dpns/identity?dpns=TeSt-NaME.2.DAsH') + const { body } = await client.get('/dpns/identity?dpns=TeSt-NaME.2.DAsH') .expect(200) .expect('Content-Type', 'application/json; charset=utf-8') @@ -171,14 +171,14 @@ describe('Identities routes', () => { const aliases = [] for (let i = 0; i < 30; i++) { - block = await fixtures.block(knex, {height: i + 1}) - identity = await fixtures.identity(knex, {block_hash: block.hash}) - alias = await fixtures.identity_alias(knex, {alias: `#test$${i}`, identity}) - identities.push({identity, block}) + block = await fixtures.block(knex, { height: i + 1 }) + identity = await fixtures.identity(knex, { block_hash: block.hash }) + alias = await fixtures.identity_alias(knex, { alias: `#test$${i}`, identity }) + identities.push({ identity, block }) aliases.push(alias) } - const {body} = await client.get('/identities') + const { body } = await client.get('/identities') .expect(200) .expect('Content-Type', 'application/json; charset=utf-8') @@ -201,7 +201,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' })) })) assert.deepEqual(body.resultSet, expectedIdentities) @@ -211,14 +211,14 @@ describe('Identities routes', () => { const aliases = [] for (let i = 0; i < 30; i++) { - block = await fixtures.block(knex, {height: i + 1}) - identity = await fixtures.identity(knex, {block_hash: block.hash}) - alias = await fixtures.identity_alias(knex, {alias: `#test1$${i}`, identity}) - identities.push({identity, block}) + block = await fixtures.block(knex, { height: i + 1 }) + identity = await fixtures.identity(knex, { block_hash: block.hash }) + alias = await fixtures.identity_alias(knex, { alias: `#test1$${i}`, identity }) + identities.push({ identity, block }) aliases.push(alias) } - const {body} = await client.get('/identities?order=desc') + const { body } = await client.get('/identities?order=desc') .expect(200) .expect('Content-Type', 'application/json; charset=utf-8') @@ -243,7 +243,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' })) })) assert.deepEqual(body.resultSet, expectedIdentities) @@ -254,14 +254,14 @@ describe('Identities routes', () => { const aliases = [] for (let i = 0; i < 30; i++) { - block = await fixtures.block(knex, {height: i + 1}) - identity = await fixtures.identity(knex, {block_hash: block.hash}) - alias = await fixtures.identity_alias(knex, {alias: `#test2$${i}`, identity}) - identities.push({identity, block}) + block = await fixtures.block(knex, { height: i + 1 }) + identity = await fixtures.identity(knex, { block_hash: block.hash }) + alias = await fixtures.identity_alias(knex, { alias: `#test2$${i}`, identity }) + identities.push({ identity, block }) aliases.push(alias) } - const {body} = await client.get('/identities?page=2') + const { body } = await client.get('/identities?page=2') .expect(200) .expect('Content-Type', 'application/json; charset=utf-8') @@ -286,7 +286,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' })) })) assert.deepEqual(body.resultSet, expectedIdentities) @@ -297,14 +297,14 @@ describe('Identities routes', () => { const aliases = [] for (let i = 0; i < 30; i++) { - block = await fixtures.block(knex, {height: i + 1}) - identity = await fixtures.identity(knex, {block_hash: block.hash}) - alias = await fixtures.identity_alias(knex, {alias: `#test3$${i}`, identity}) - identities.push({identity, block}) + block = await fixtures.block(knex, { height: i + 1 }) + identity = await fixtures.identity(knex, { block_hash: block.hash }) + alias = await fixtures.identity_alias(knex, { alias: `#test3$${i}`, identity }) + identities.push({ identity, block }) aliases.push(alias) } - const {body} = await client.get('/identities?page=2&limit=5&order=desc') + const { body } = await client.get('/identities?page=2&limit=5&order=desc') .expect(200) .expect('Content-Type', 'application/json; charset=utf-8') @@ -330,7 +330,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' })) })) assert.deepEqual(body.resultSet, expectedIdentities) @@ -343,8 +343,8 @@ describe('Identities routes', () => { for (let i = 0; i < 30; i++) { const transactions = [] - block = await fixtures.block(knex, {height: i + 1}) - identity = await fixtures.identity(knex, {block_hash: block.hash}) + block = await fixtures.block(knex, { height: i + 1 }) + identity = await fixtures.identity(knex, { block_hash: block.hash }) for (let j = 0; j < Math.floor(Math.random() * 50); j++) { const tx = await fixtures.transaction(knex, { @@ -358,12 +358,12 @@ describe('Identities routes', () => { identity.transactions = transactions - identities.push({identity, block}) - alias = await fixtures.identity_alias(knex, {alias: `#test3$${i}`, identity}) + identities.push({ identity, block }) + alias = await fixtures.identity_alias(knex, { alias: `#test3$${i}`, identity }) aliases.push(alias) } - const {body} = await client.get('/identities?order_by=tx_count&order=desc') + const { body } = await client.get('/identities?order_by=tx_count&order=desc') .expect(200) .expect('Content-Type', 'application/json; charset=utf-8') @@ -389,7 +389,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' })) })) assert.deepEqual(body.resultSet, expectedIdentities) @@ -400,8 +400,8 @@ describe('Identities routes', () => { const aliases = [] for (let i = 0; i < 30; i++) { - block = await fixtures.block(knex, {height: i + 1}) - identity = await fixtures.identity(knex, {block_hash: block.hash}) + block = await fixtures.block(knex, { height: i + 1 }) + identity = await fixtures.identity(knex, { block_hash: block.hash }) transferTx = await fixtures.transaction(knex, { block_hash: block.hash, type: StateTransitionEnum.IDENTITY_TOP_UP, @@ -415,15 +415,15 @@ describe('Identities routes', () => { identity.balance = transfer.amount - identities.push({identity, block, transfer}) - alias = await fixtures.identity_alias(knex, {alias: `#test3$${i}`, identity}) + identities.push({ identity, block, transfer }) + alias = await fixtures.identity_alias(knex, { alias: `#test3$${i}`, identity }) aliases.push(alias) } mock.reset() mock.method(DAPI.prototype, 'getIdentityBalance', async (identifier) => { - const {identity} = identities.find(({identity}) => identity.identifier === identifier) + const { identity } = identities.find(({ identity }) => identity.identifier === identifier) return identity.balance }) mock.method(tenderdashRpc, 'getBlockByHeight', async () => ({ @@ -434,7 +434,7 @@ describe('Identities routes', () => { } })) - const {body} = await client.get('/identities?order_by=balance&order=desc') + const { body } = await client.get('/identities?order_by=balance&order=desc') .expect(200) .expect('Content-Type', 'application/json; charset=utf-8') @@ -460,7 +460,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' })) })) assert.deepEqual(body.resultSet, expectedIdentities) @@ -470,11 +470,11 @@ describe('Identities routes', () => { describe('getDataContractsByIdentity()', async () => { it('should return default set of data contracts by identity', async () => { dataContracts = [] - block = await fixtures.block(knex, {height: 1}) - identity = await fixtures.identity(knex, {block_hash: block.hash}) + block = await fixtures.block(knex, { height: 1 }) + identity = await fixtures.identity(knex, { block_hash: block.hash }) for (let i = 1; i < 31; i++) { - block = await fixtures.block(knex, {height: i + 1}) + block = await fixtures.block(knex, { height: i + 1 }) transaction = await fixtures.transaction(knex, { block_hash: block.hash, owner: identity.identifier, @@ -484,10 +484,10 @@ describe('Identities routes', () => { state_transition_hash: transaction.hash, owner: identity.identifier }) - dataContracts.push({dataContract, transaction, identity, block}) + dataContracts.push({ dataContract, transaction, identity, block }) } - const {body} = await client.get(`/identity/${identity.identifier}/dataContracts`) + const { body } = await client.get(`/identity/${identity.identifier}/dataContracts`) .expect(200) .expect('Content-Type', 'application/json; charset=utf-8') @@ -512,11 +512,11 @@ describe('Identities routes', () => { it('should return default set of data contracts by identity desc', async () => { dataContracts = [] - block = await fixtures.block(knex, {height: 1}) - identity = await fixtures.identity(knex, {block_hash: block.hash}) + block = await fixtures.block(knex, { height: 1 }) + identity = await fixtures.identity(knex, { block_hash: block.hash }) for (let i = 1; i < 31; i++) { - block = await fixtures.block(knex, {height: i + 1}) + block = await fixtures.block(knex, { height: i + 1 }) transaction = await fixtures.transaction(knex, { block_hash: block.hash, owner: identity.identifier, @@ -526,10 +526,10 @@ describe('Identities routes', () => { state_transition_hash: transaction.hash, owner: identity.identifier }) - dataContracts.push({dataContract, transaction, identity, block}) + dataContracts.push({ dataContract, transaction, identity, block }) } - const {body} = await client.get(`/identity/${identity.identifier}/dataContracts?order=desc`) + const { body } = await client.get(`/identity/${identity.identifier}/dataContracts?order=desc`) .expect(200) .expect('Content-Type', 'application/json; charset=utf-8') @@ -557,11 +557,11 @@ describe('Identities routes', () => { it('should allow walk through pages', async () => { dataContracts = [] - block = await fixtures.block(knex, {height: 1}) - identity = await fixtures.identity(knex, {block_hash: block.hash}) + block = await fixtures.block(knex, { height: 1 }) + identity = await fixtures.identity(knex, { block_hash: block.hash }) for (let i = 1; i < 31; i++) { - block = await fixtures.block(knex, {height: i + 1}) + block = await fixtures.block(knex, { height: i + 1 }) transaction = await fixtures.transaction(knex, { block_hash: block.hash, owner: identity.identifier, @@ -571,10 +571,10 @@ describe('Identities routes', () => { state_transition_hash: transaction.hash, owner: identity.identifier }) - dataContracts.push({dataContract, transaction, identity, block}) + dataContracts.push({ dataContract, transaction, identity, block }) } - const {body} = await client.get(`/identity/${identity.identifier}/dataContracts?page=2&limit=5`) + const { body } = await client.get(`/identity/${identity.identifier}/dataContracts?page=2&limit=5`) .expect(200) .expect('Content-Type', 'application/json; charset=utf-8') @@ -602,11 +602,11 @@ describe('Identities routes', () => { it('should allow walk through pages desc', async () => { dataContracts = [] - block = await fixtures.block(knex, {height: 1}) - identity = await fixtures.identity(knex, {block_hash: block.hash}) + block = await fixtures.block(knex, { height: 1 }) + identity = await fixtures.identity(knex, { block_hash: block.hash }) for (let i = 1; i < 31; i++) { - block = await fixtures.block(knex, {height: i + 1}) + block = await fixtures.block(knex, { height: i + 1 }) transaction = await fixtures.transaction(knex, { block_hash: block.hash, owner: identity.identifier, @@ -616,10 +616,10 @@ describe('Identities routes', () => { state_transition_hash: transaction.hash, owner: identity.identifier }) - dataContracts.push({dataContract, transaction, identity, block}) + dataContracts.push({ dataContract, transaction, identity, block }) } - const {body} = await client.get(`/identity/${identity.identifier}/dataContracts?page=2&limit=5&order=desc`) + const { body } = await client.get(`/identity/${identity.identifier}/dataContracts?page=2&limit=5&order=desc`) .expect(200) .expect('Content-Type', 'application/json; charset=utf-8') @@ -649,11 +649,11 @@ describe('Identities routes', () => { describe('getDocumentsByIdentity()', async () => { it('should return default set of data contracts by identity', async () => { documents = [] - block = await fixtures.block(knex, {height: 1}) - identity = await fixtures.identity(knex, {block_hash: block.hash}) + block = await fixtures.block(knex, { height: 1 }) + identity = await fixtures.identity(knex, { block_hash: block.hash }) for (let i = 1; i < 31; i++) { - block = await fixtures.block(knex, {height: i + 1}) + block = await fixtures.block(knex, { height: i + 1 }) dataContractTransaction = await fixtures.transaction(knex, { block_hash: block.hash, owner: identity.identifier, @@ -673,10 +673,10 @@ describe('Identities routes', () => { owner: identity.identifier, data_contract_id: dataContract.id }) - documents.push({document, dataContract, transaction, identity, block}) + documents.push({ document, dataContract, transaction, identity, block }) } - const {body} = await client.get(`/identity/${identity.identifier}/documents`) + const { body } = await client.get(`/identity/${identity.identifier}/documents`) .expect(200) .expect('Content-Type', 'application/json; charset=utf-8') @@ -702,11 +702,11 @@ describe('Identities routes', () => { it('should return default set of data contracts by identity dsc', async () => { documents = [] - block = await fixtures.block(knex, {height: 1}) - identity = await fixtures.identity(knex, {block_hash: block.hash}) + block = await fixtures.block(knex, { height: 1 }) + identity = await fixtures.identity(knex, { block_hash: block.hash }) for (let i = 1; i < 31; i++) { - block = await fixtures.block(knex, {height: i + 1}) + block = await fixtures.block(knex, { height: i + 1 }) dataContractTransaction = await fixtures.transaction(knex, { block_hash: block.hash, owner: identity.identifier, @@ -726,10 +726,10 @@ describe('Identities routes', () => { owner: identity.identifier, data_contract_id: dataContract.id }) - documents.push({document, dataContract, transaction, identity, block}) + documents.push({ document, dataContract, transaction, identity, block }) } - const {body} = await client.get(`/identity/${identity.identifier}/documents?order=desc`) + const { body } = await client.get(`/identity/${identity.identifier}/documents?order=desc`) .expect(200) .expect('Content-Type', 'application/json; charset=utf-8') @@ -758,11 +758,11 @@ describe('Identities routes', () => { it('should be able to walk through pages', async () => { documents = [] - block = await fixtures.block(knex, {height: 1}) - identity = await fixtures.identity(knex, {block_hash: block.hash}) + block = await fixtures.block(knex, { height: 1 }) + identity = await fixtures.identity(knex, { block_hash: block.hash }) for (let i = 1; i < 31; i++) { - block = await fixtures.block(knex, {height: i + 1}) + block = await fixtures.block(knex, { height: i + 1 }) dataContractTransaction = await fixtures.transaction(knex, { block_hash: block.hash, owner: identity.identifier, @@ -782,10 +782,10 @@ describe('Identities routes', () => { owner: identity.identifier, data_contract_id: dataContract.id }) - documents.push({document, dataContract, transaction, identity, block}) + documents.push({ document, dataContract, transaction, identity, block }) } - const {body} = await client.get(`/identity/${identity.identifier}/documents?page=2&limit=3`) + const { body } = await client.get(`/identity/${identity.identifier}/documents?page=2&limit=3`) .expect(200) .expect('Content-Type', 'application/json; charset=utf-8') @@ -814,11 +814,11 @@ describe('Identities routes', () => { it('should be able to walk through pages desc', async () => { documents = [] - block = await fixtures.block(knex, {height: 1}) - identity = await fixtures.identity(knex, {block_hash: block.hash}) + block = await fixtures.block(knex, { height: 1 }) + identity = await fixtures.identity(knex, { block_hash: block.hash }) for (let i = 1; i < 31; i++) { - block = await fixtures.block(knex, {height: i + 1}) + block = await fixtures.block(knex, { height: i + 1 }) dataContractTransaction = await fixtures.transaction(knex, { block_hash: block.hash, owner: identity.identifier, @@ -838,10 +838,10 @@ describe('Identities routes', () => { owner: identity.identifier, data_contract_id: dataContract.id }) - documents.push({document, dataContract, transaction, identity, block}) + documents.push({ document, dataContract, transaction, identity, block }) } - const {body} = await client.get(`/identity/${identity.identifier}/documents?page=2&limit=3&order=desc`) + const { body } = await client.get(`/identity/${identity.identifier}/documents?page=2&limit=3&order=desc`) .expect(200) .expect('Content-Type', 'application/json; charset=utf-8') @@ -871,21 +871,21 @@ describe('Identities routes', () => { describe('getTransactionsByIdentity()', async () => { it('should return default set of transactions by identity', async () => { - block = await fixtures.block(knex, {height: 1}) - identity = await fixtures.identity(knex, {block_hash: block.hash}) - transactions = [{transaction: identity.transaction, block}] + block = await fixtures.block(knex, { height: 1 }) + identity = await fixtures.identity(knex, { block_hash: block.hash }) + transactions = [{ transaction: identity.transaction, block }] for (let i = 1; i < 30; i++) { - block = await fixtures.block(knex, {height: i + 1}) + block = await fixtures.block(knex, { height: i + 1 }) transaction = await fixtures.transaction(knex, { block_hash: block.hash, owner: identity.identifier, type: StateTransitionEnum.DOCUMENTS_BATCH }) - transactions.push({transaction, block}) + transactions.push({ transaction, block }) } - const {body} = await client.get(`/identity/${identity.identifier}/transactions`) + const { body } = await client.get(`/identity/${identity.identifier}/transactions`) .expect(200) .expect('Content-Type', 'application/json; charset=utf-8') @@ -915,21 +915,21 @@ describe('Identities routes', () => { }) it('should return default set of transactions by identity desc', async () => { - block = await fixtures.block(knex, {height: 1}) - identity = await fixtures.identity(knex, {block_hash: block.hash}) - transactions = [{transaction: identity.transaction, block}] + block = await fixtures.block(knex, { height: 1 }) + identity = await fixtures.identity(knex, { block_hash: block.hash }) + transactions = [{ transaction: identity.transaction, block }] for (let i = 1; i < 30; i++) { - block = await fixtures.block(knex, {height: i + 1}) + block = await fixtures.block(knex, { height: i + 1 }) transaction = await fixtures.transaction(knex, { block_hash: block.hash, owner: identity.identifier, type: StateTransitionEnum.DOCUMENTS_BATCH }) - transactions.push({transaction, block}) + transactions.push({ transaction, block }) } - const {body} = await client.get(`/identity/${identity.identifier}/transactions?order=desc`) + const { body } = await client.get(`/identity/${identity.identifier}/transactions?order=desc`) .expect(200) .expect('Content-Type', 'application/json; charset=utf-8') @@ -959,21 +959,21 @@ describe('Identities routes', () => { }) it('should allow walk through pages', async () => { - block = await fixtures.block(knex, {height: 1}) - identity = await fixtures.identity(knex, {block_hash: block.hash}) - transactions = [{transaction: identity.transaction, block}] + block = await fixtures.block(knex, { height: 1 }) + identity = await fixtures.identity(knex, { block_hash: block.hash }) + transactions = [{ transaction: identity.transaction, block }] for (let i = 1; i < 30; i++) { - block = await fixtures.block(knex, {height: i + 1}) + block = await fixtures.block(knex, { height: i + 1 }) transaction = await fixtures.transaction(knex, { block_hash: block.hash, owner: identity.identifier, type: StateTransitionEnum.DOCUMENTS_BATCH }) - transactions.push({transaction, block}) + transactions.push({ transaction, block }) } - const {body} = await client.get(`/identity/${identity.identifier}/transactions?page=2&limit=4`) + const { body } = await client.get(`/identity/${identity.identifier}/transactions?page=2&limit=4`) .expect(200) .expect('Content-Type', 'application/json; charset=utf-8') @@ -1003,21 +1003,21 @@ describe('Identities routes', () => { }) it('should allow walk through pages desc', async () => { - block = await fixtures.block(knex, {height: 1}) - identity = await fixtures.identity(knex, {block_hash: block.hash}) - transactions = [{transaction: identity.transaction, block}] + block = await fixtures.block(knex, { height: 1 }) + identity = await fixtures.identity(knex, { block_hash: block.hash }) + transactions = [{ transaction: identity.transaction, block }] for (let i = 1; i < 30; i++) { - block = await fixtures.block(knex, {height: i + 1}) + block = await fixtures.block(knex, { height: i + 1 }) transaction = await fixtures.transaction(knex, { block_hash: block.hash, owner: identity.identifier, type: StateTransitionEnum.DOCUMENTS_BATCH }) - transactions.push({transaction, block}) + transactions.push({ transaction, block }) } - const {body} = await client.get(`/identity/${identity.identifier}/transactions?page=2&limit=4&order=desc`) + const { body } = await client.get(`/identity/${identity.identifier}/transactions?page=2&limit=4&order=desc`) .expect(200) .expect('Content-Type', 'application/json; charset=utf-8') @@ -1049,12 +1049,12 @@ describe('Identities routes', () => { describe('getTransfersByIdentity()', async () => { it('should return default set of transfers by identity', async () => { - block = await fixtures.block(knex, {height: 1}) - identity = await fixtures.identity(knex, {block_hash: block.hash}) + block = await fixtures.block(knex, { height: 1 }) + identity = await fixtures.identity(knex, { block_hash: block.hash }) transfers = [] for (let i = 1; i < 31; i++) { - block = await fixtures.block(knex, {height: i + 1}) + block = await fixtures.block(knex, { height: i + 1 }) transaction = await fixtures.transaction(knex, { block_hash: block.hash, owner: identity.identifier, @@ -1066,10 +1066,10 @@ describe('Identities routes', () => { sender: null, state_transition_hash: transaction.hash }) - transfers.push({transfer, transaction, block}) + transfers.push({ transfer, transaction, block }) } - const {body} = await client.get(`/identity/${identity.identifier}/transfers`) + const { body } = await client.get(`/identity/${identity.identifier}/transfers`) .expect(200) .expect('Content-Type', 'application/json; charset=utf-8') @@ -1095,12 +1095,12 @@ describe('Identities routes', () => { }) it('should return default set of transfers by identity desc', async () => { - block = await fixtures.block(knex, {height: 1}) - identity = await fixtures.identity(knex, {block_hash: block.hash}) + block = await fixtures.block(knex, { height: 1 }) + identity = await fixtures.identity(knex, { block_hash: block.hash }) transfers = [] for (let i = 1; i < 31; i++) { - block = await fixtures.block(knex, {height: i + 1}) + block = await fixtures.block(knex, { height: i + 1 }) transaction = await fixtures.transaction(knex, { block_hash: block.hash, owner: identity.identifier, @@ -1112,10 +1112,10 @@ describe('Identities routes', () => { sender: null, state_transition_hash: transaction.hash }) - transfers.push({transfer, transaction, block}) + transfers.push({ transfer, transaction, block }) } - const {body} = await client.get(`/identity/${identity.identifier}/transfers?order=desc`) + const { body } = await client.get(`/identity/${identity.identifier}/transfers?order=desc`) .expect(200) .expect('Content-Type', 'application/json; charset=utf-8') @@ -1141,12 +1141,12 @@ describe('Identities routes', () => { }) it('should allow to walk through pages', async () => { - block = await fixtures.block(knex, {height: 1}) - identity = await fixtures.identity(knex, {block_hash: block.hash}) + block = await fixtures.block(knex, { height: 1 }) + identity = await fixtures.identity(knex, { block_hash: block.hash }) transfers = [] for (let i = 1; i < 31; i++) { - block = await fixtures.block(knex, {height: i + 1}) + block = await fixtures.block(knex, { height: i + 1 }) transaction = await fixtures.transaction(knex, { block_hash: block.hash, owner: identity.identifier, @@ -1158,10 +1158,10 @@ describe('Identities routes', () => { sender: null, state_transition_hash: transaction.hash }) - transfers.push({transfer, transaction, block}) + transfers.push({ transfer, transaction, block }) } - const {body} = await client.get(`/identity/${identity.identifier}/transfers?page=2&limit=7`) + const { body } = await client.get(`/identity/${identity.identifier}/transfers?page=2&limit=7`) .expect(200) .expect('Content-Type', 'application/json; charset=utf-8') @@ -1187,12 +1187,12 @@ describe('Identities routes', () => { }) it('should allow to walk through pages desc', async () => { - block = await fixtures.block(knex, {height: 1}) - identity = await fixtures.identity(knex, {block_hash: block.hash}) + block = await fixtures.block(knex, { height: 1 }) + identity = await fixtures.identity(knex, { block_hash: block.hash }) transfers = [] for (let i = 1; i < 31; i++) { - block = await fixtures.block(knex, {height: i + 1}) + block = await fixtures.block(knex, { height: i + 1 }) transaction = await fixtures.transaction(knex, { block_hash: block.hash, owner: identity.identifier, @@ -1204,10 +1204,10 @@ describe('Identities routes', () => { sender: null, state_transition_hash: transaction.hash }) - transfers.push({transfer, transaction, block}) + transfers.push({ transfer, transaction, block }) } - const {body} = await client.get(`/identity/${identity.identifier}/transfers?page=2&limit=7&order=desc`) + const { body } = await client.get(`/identity/${identity.identifier}/transfers?page=2&limit=7&order=desc`) .expect(200) .expect('Content-Type', 'application/json; charset=utf-8') diff --git a/packages/api/test/integration/main.spec.js b/packages/api/test/integration/main.spec.js index a8d62c9ea..192444059 100644 --- a/packages/api/test/integration/main.spec.js +++ b/packages/api/test/integration/main.spec.js @@ -180,7 +180,10 @@ describe('Other routes', () => { error: dataContractTransaction.error, owner: { identifier: dataContractTransaction.owner, - aliases: [identityAlias.alias] + aliases: [{ + alias: identityAlias.alias, + status: 'ok' + }] } } @@ -247,7 +250,10 @@ describe('Other routes', () => { totalDataContracts: 1, isSystem: false, owner: identity.identifier, - aliases: ['dpns.dash'] + aliases: [{ + alias: 'dpns.dash', + status: 'ok' + }] } assert.deepEqual({ identity: expectedIdentity }, body) @@ -270,7 +276,10 @@ describe('Other routes', () => { totalDataContracts: 1, isSystem: false, owner: identity.identifier, - aliases: ['dpns.dash'] + aliases: [{ + alias: 'dpns.dash', + status: 'ok' + }] } assert.deepEqual({ identity: expectedIdentity }, body) From 90bd4d56700225c66ee3598ac03f2bd9e00f390b Mon Sep 17 00:00:00 2001 From: owl352 Date: Sun, 17 Nov 2024 22:51:36 +0300 Subject: [PATCH 26/35] `main.spec.js` update --- packages/api/test/integration/main.spec.js | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) diff --git a/packages/api/test/integration/main.spec.js b/packages/api/test/integration/main.spec.js index 192444059..2eae56153 100644 --- a/packages/api/test/integration/main.spec.js +++ b/packages/api/test/integration/main.spec.js @@ -239,21 +239,10 @@ describe('Other routes', () => { .expect('Content-Type', 'application/json; charset=utf-8') const expectedIdentity = { - identifier: identity.identifier, - revision: 0, - balance: 0, - timestamp: block.timestamp.toISOString(), - txHash: identityTransaction.hash, - totalTxs: 51, - totalTransfers: 0, - totalDocuments: 1, - totalDataContracts: 1, - isSystem: false, - owner: identity.identifier, - aliases: [{ - alias: 'dpns.dash', - status: 'ok' - }] + identity:{ + identifier: identity.identifier, + alias: identityAlias.alias, + } } assert.deepEqual({ identity: expectedIdentity }, body) From 85f198b6d47c81277e5396d751213349adeeb7e0 Mon Sep 17 00:00:00 2001 From: owl352 Date: Sun, 17 Nov 2024 22:54:32 +0300 Subject: [PATCH 27/35] fixes --- packages/api/src/dao/IdentitiesDAO.js | 2 +- .../api/test/integration/identities.spec.js | 30 ++----------------- packages/api/test/integration/main.spec.js | 4 +-- 3 files changed, 5 insertions(+), 31 deletions(-) diff --git a/packages/api/src/dao/IdentitiesDAO.js b/packages/api/src/dao/IdentitiesDAO.js index 8a4b1f411..f082fd322 100644 --- a/packages/api/src/dao/IdentitiesDAO.js +++ b/packages/api/src/dao/IdentitiesDAO.js @@ -103,7 +103,7 @@ module.exports = class IdentitiesDAO { .whereRaw(`LOWER(alias) LIKE LOWER('${dpns}${dpns.includes('.') ? '' : '.%'}')`) .limit(1) - return identity + return { identifier: identity.identity_identifier, alias: identity.alias } } getIdentities = async (page, limit, order, orderBy) => { diff --git a/packages/api/test/integration/identities.spec.js b/packages/api/test/integration/identities.spec.js index afe66bf9f..f208d3125 100644 --- a/packages/api/test/integration/identities.spec.js +++ b/packages/api/test/integration/identities.spec.js @@ -109,20 +109,7 @@ describe('Identities routes', () => { const expectedIdentity = { identifier: identity.identifier, - owner: identity.identifier, - revision: identity.revision, - balance: 0, - timestamp: block.timestamp.toISOString(), - txHash: identity.txHash, - totalTxs: 1, - totalTransfers: 0, - totalDocuments: 0, - totalDataContracts: 0, - isSystem: false, - aliases: [{ - alias, - status: 'ok' - }] + alias } assert.deepEqual(body, expectedIdentity) @@ -139,20 +126,7 @@ describe('Identities routes', () => { const expectedIdentity = { identifier: identity.identifier, - owner: identity.identifier, - revision: identity.revision, - balance: 0, - timestamp: block.timestamp.toISOString(), - txHash: identity.txHash, - totalTxs: 1, - totalTransfers: 0, - totalDocuments: 0, - totalDataContracts: 0, - isSystem: false, - aliases: [{ - alias, - status: 'ok' - }] + alias } assert.deepEqual(body, expectedIdentity) diff --git a/packages/api/test/integration/main.spec.js b/packages/api/test/integration/main.spec.js index 2eae56153..d305074a2 100644 --- a/packages/api/test/integration/main.spec.js +++ b/packages/api/test/integration/main.spec.js @@ -239,9 +239,9 @@ describe('Other routes', () => { .expect('Content-Type', 'application/json; charset=utf-8') const expectedIdentity = { - identity:{ + identity: { identifier: identity.identifier, - alias: identityAlias.alias, + alias: identityAlias.alias } } From 5d2e9651067e0e7bb4ce20dced3da55c4125b233 Mon Sep 17 00:00:00 2001 From: owl352 Date: Sun, 17 Nov 2024 22:59:26 +0300 Subject: [PATCH 28/35] `IdentitiesDAO.js` fix --- packages/api/src/dao/IdentitiesDAO.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/api/src/dao/IdentitiesDAO.js b/packages/api/src/dao/IdentitiesDAO.js index f082fd322..a0ae39e85 100644 --- a/packages/api/src/dao/IdentitiesDAO.js +++ b/packages/api/src/dao/IdentitiesDAO.js @@ -103,6 +103,10 @@ module.exports = class IdentitiesDAO { .whereRaw(`LOWER(alias) LIKE LOWER('${dpns}${dpns.includes('.') ? '' : '.%'}')`) .limit(1) + if (!identity) { + return null + } + return { identifier: identity.identity_identifier, alias: identity.alias } } From a18d88ac35fe3e2fef1c068ff97f47ad9421a9f1 Mon Sep 17 00:00:00 2001 From: owl352 Date: Sun, 17 Nov 2024 22:59:58 +0300 Subject: [PATCH 29/35] main tests fix --- packages/api/test/integration/main.spec.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/packages/api/test/integration/main.spec.js b/packages/api/test/integration/main.spec.js index d305074a2..e8fdee4fd 100644 --- a/packages/api/test/integration/main.spec.js +++ b/packages/api/test/integration/main.spec.js @@ -239,10 +239,8 @@ describe('Other routes', () => { .expect('Content-Type', 'application/json; charset=utf-8') const expectedIdentity = { - identity: { - identifier: identity.identifier, - alias: identityAlias.alias - } + identifier: identity.identifier, + alias: identityAlias.alias } assert.deepEqual({ identity: expectedIdentity }, body) From 3fe5ae1bf268e727a37739f37a62c61890469f45 Mon Sep 17 00:00:00 2001 From: owl352 Date: Sun, 17 Nov 2024 23:23:31 +0300 Subject: [PATCH 30/35] transactions.spec.js fix --- .../api/test/integration/transactions.spec.js | 40 ++++++++++++++----- 1 file changed, 29 insertions(+), 11 deletions(-) diff --git a/packages/api/test/integration/transactions.spec.js b/packages/api/test/integration/transactions.spec.js index 4b01ab46c..b0c07de9a 100644 --- a/packages/api/test/integration/transactions.spec.js +++ b/packages/api/test/integration/transactions.spec.js @@ -113,7 +113,10 @@ describe('Transaction routes', () => { error: transaction.transaction.error, owner: { identifier: transaction.transaction.owner, - aliases: [identityAlias.alias] + aliases: [{ + alias: identityAlias.alias, + status: 'ok' + }] } } @@ -139,7 +142,10 @@ describe('Transaction routes', () => { error: 'Cannot deserialize', owner: { identifier: transaction.transaction.owner, - aliases: [identityAlias.alias] + aliases: [{ + alias: identityAlias.alias, + status: 'ok' + }] } } @@ -179,7 +185,10 @@ describe('Transaction routes', () => { error: transaction.transaction.error, owner: { identifier: transaction.transaction.owner, - aliases: [identityAlias.alias] + aliases: [{ + alias: identityAlias.alias, + status: 'ok' + }] } })) @@ -212,7 +221,10 @@ describe('Transaction routes', () => { error: transaction.transaction.error, owner: { identifier: transaction.transaction.owner, - aliases: [identityAlias.alias] + aliases: [{ + alias: identityAlias.alias, + status: 'ok' + }] } })) @@ -245,14 +257,17 @@ describe('Transaction routes', () => { error: transaction.transaction.error, owner: { identifier: transaction.transaction.owner, - aliases: [identityAlias.alias] + aliases: [{ + alias: identityAlias.alias, + status: 'ok' + }] } })) assert.deepEqual(expectedTransactions, body.resultSet) }) - it('should return be able to walk through pages desc', async () => { + it('should return be able to walk through pages', async () => { const { body } = await client.get('/transactions?page=3&limit=3') .expect(200) .expect('Content-Type', 'application/json; charset=utf-8') @@ -266,23 +281,26 @@ describe('Transaction routes', () => { .sort((a, b) => a.transaction.id - b.transaction.id) .slice(6, 9) .map(transaction => ({ + hash: transaction.transaction.hash, + index: transaction.transaction.index, blockHash: transaction.block.hash, blockHeight: transaction.block.height, + type: transaction.transaction.type, data: '{}', - hash: transaction.transaction.hash, - index: transaction.transaction.index, timestamp: transaction.block.timestamp.toISOString(), - type: transaction.transaction.type, gasUsed: transaction.transaction.gas_used, status: transaction.transaction.status, error: transaction.transaction.error, owner: { identifier: transaction.transaction.owner, - aliases: [identityAlias.alias] + aliases: [{ + alias: identityAlias.alias, + status: 'ok' + }] } })) - assert.deepEqual(expectedTransactions, body.resultSet) + assert.deepEqual(body.resultSet, expectedTransactions) }) }) From 91b11b2db155acf98ec9b4b7d0d6efce542841d8 Mon Sep 17 00:00:00 2001 From: owl352 Date: Sun, 17 Nov 2024 23:34:20 +0300 Subject: [PATCH 31/35] tiny fixes --- packages/api/src/DAPI.js | 3 ++- packages/api/src/constants.js | 2 +- packages/api/src/models/Transaction.js | 11 +++++------ packages/api/src/utils.js | 3 ++- 4 files changed, 10 insertions(+), 9 deletions(-) diff --git a/packages/api/src/DAPI.js b/packages/api/src/DAPI.js index 19a2e2c0b..aacbdad10 100644 --- a/packages/api/src/DAPI.js +++ b/packages/api/src/DAPI.js @@ -41,7 +41,8 @@ class DAPI { documentTypeName, indexName, resultType, - indexValuesList, startAtIdentifierInfo, + indexValuesList, + startAtIdentifierInfo, allowIncludeLockedAndAbstainingVoteTally, count ) { diff --git a/packages/api/src/constants.js b/packages/api/src/constants.js index 505d0232c..d946603f5 100644 --- a/packages/api/src/constants.js +++ b/packages/api/src/constants.js @@ -5,7 +5,7 @@ let genesisTime module.exports = { EPOCH_CHANGE_TIME: Number(process.env.EPOCH_CHANGE_TIME), TCP_CONNECT_TIMEOUT: Number(process.env.TCP_CONNECT_TIMEOUT), - DPNS_CONTRACT: '5mjGWa9mruHnLBht3ntbfgodcSoJxA1XIfYiv1PFMVU=', + DPNS_CONTRACT: 'GWRSAVFMjXx8HpQFaNJMqBV7MBgMK4br5UESsB4S31Ec', get genesisTime () { if (!genesisTime || isNaN(genesisTime)) { return TenderdashRPC.getBlockByHeight(1).then((blockInfo) => { diff --git a/packages/api/src/models/Transaction.js b/packages/api/src/models/Transaction.js index 0beba1206..9b37c9a26 100644 --- a/packages/api/src/models/Transaction.js +++ b/packages/api/src/models/Transaction.js @@ -61,11 +61,10 @@ module.exports = class Transaction { block_height, type, data, timestamp, parseInt(gas_used), status, decodedError ?? error, - aliases - ? { - identifier: owner?.trim(), - aliases - } - : owner?.trim()) + { + identifier: owner?.trim(), + aliases: aliases ?? null + } + ) } } diff --git a/packages/api/src/utils.js b/packages/api/src/utils.js index 7b2f053f1..a35e34938 100644 --- a/packages/api/src/utils.js +++ b/packages/api/src/utils.js @@ -2,6 +2,7 @@ const crypto = require('crypto') const StateTransitionEnum = require('./enums/StateTransitionEnum') const net = require('net') const { TCP_CONNECT_TIMEOUT, DPNS_CONTRACT } = require('./constants') +const { base58 } = require('@scure/base') const convertToHomographSafeChars = require('dash/build/utils/convertToHomographSafeChars').default const getKnex = () => { @@ -199,7 +200,7 @@ const getAliasInfo = async (alias, dapi) => { const labelBuffer = generateNameIndexBuffer(normalizedLabel) const contestedState = await dapi.getContestedState( - DPNS_CONTRACT, + Buffer.from(base58.decode(DPNS_CONTRACT)).toString('base64'), 'domain', 'parentNameAndLabel', 1, From 0c9d0ba699afebb26755c4ab3ea795aefde58c1f Mon Sep 17 00:00:00 2001 From: owl352 Date: Sun, 17 Nov 2024 23:39:35 +0300 Subject: [PATCH 32/35] tiny fixes --- .../api/test/integration/identities.spec.js | 20 +++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/packages/api/test/integration/identities.spec.js b/packages/api/test/integration/identities.spec.js index f208d3125..c90a30021 100644 --- a/packages/api/test/integration/identities.spec.js +++ b/packages/api/test/integration/identities.spec.js @@ -882,7 +882,10 @@ describe('Identities routes', () => { gasUsed: _transaction.transaction.gas_used, status: _transaction.transaction.status, error: _transaction.transaction.error, - owner: _transaction.transaction.owner + owner: { + identifier: _transaction.transaction.owner, + aliases: null + } })) assert.deepEqual(body.resultSet, expectedTransactions) @@ -926,7 +929,10 @@ describe('Identities routes', () => { gasUsed: _transaction.transaction.gas_used, status: _transaction.transaction.status, error: _transaction.transaction.error, - owner: _transaction.transaction.owner + owner: { + identifier: _transaction.transaction.owner, + aliases: null + } })) assert.deepEqual(body.resultSet, expectedTransactions) @@ -970,7 +976,10 @@ describe('Identities routes', () => { gasUsed: _transaction.transaction.gas_used, status: _transaction.transaction.status, error: _transaction.transaction.error, - owner: _transaction.transaction.owner + owner: { + identifier: _transaction.transaction.owner, + aliases: null + } })) assert.deepEqual(body.resultSet, expectedTransactions) @@ -1014,7 +1023,10 @@ describe('Identities routes', () => { gasUsed: _transaction.transaction.gas_used, status: _transaction.transaction.status, error: _transaction.transaction.error, - owner: _transaction.transaction.owner + owner: { + identifier: _transaction.transaction.owner, + aliases: null + } })) assert.deepEqual(body.resultSet, expectedTransactions) From 9ab1634ffb35f9cf8c1d6d9a8ef89afecb830e50 Mon Sep 17 00:00:00 2001 From: owl352 Date: Sun, 17 Nov 2024 23:47:10 +0300 Subject: [PATCH 33/35] names fix --- packages/api/src/dao/IdentitiesDAO.js | 12 ++++++------ packages/api/src/dao/TransactionsDAO.js | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/packages/api/src/dao/IdentitiesDAO.js b/packages/api/src/dao/IdentitiesDAO.js index a0ae39e85..dc14b40d2 100644 --- a/packages/api/src/dao/IdentitiesDAO.js +++ b/packages/api/src/dao/IdentitiesDAO.js @@ -78,15 +78,15 @@ module.exports = class IdentitiesDAO { const identity = Identity.fromRow(row) const aliases = await Promise.all(identity.aliases.map(async alias => { - const contested = await getAliasInfo(alias, this.dapi) + const aliasInfo = await getAliasInfo(alias, this.dapi) const isLocked = base58.encode( - Buffer.from(contested.contestedState?.finishedVoteInfo?.wonByIdentityId ?? ''), + Buffer.from(aliasInfo.contestedState?.finishedVoteInfo?.wonByIdentityId ?? ''), 'base64') !== identifier return { alias, - status: (contested.contestedState !== null && isLocked) ? 'locked' : 'ok' + status: (aliasInfo.contestedState !== null && isLocked) ? 'locked' : 'ok' } })) @@ -181,15 +181,15 @@ module.exports = class IdentitiesDAO { const balance = await this.dapi.getIdentityBalance(row.identifier.trim()) const aliases = await Promise.all((row.aliases ?? []).map(async alias => { - const contested = await getAliasInfo(alias, this.dapi) + const aliasInfo = await getAliasInfo(alias, this.dapi) const isLocked = base58.encode( - Buffer.from(contested.contestedState?.finishedVoteInfo?.wonByIdentityId ?? ''), + Buffer.from(aliasInfo.contestedState?.finishedVoteInfo?.wonByIdentityId ?? ''), 'base64') !== row.identifier return { alias, - status: (contested.contestedState !== null && isLocked) ? 'locked' : 'ok' + status: (aliasInfo.contestedState !== null && isLocked) ? 'locked' : 'ok' } })) diff --git a/packages/api/src/dao/TransactionsDAO.js b/packages/api/src/dao/TransactionsDAO.js index 3b64e683f..ebba4e79b 100644 --- a/packages/api/src/dao/TransactionsDAO.js +++ b/packages/api/src/dao/TransactionsDAO.js @@ -34,15 +34,15 @@ module.exports = class TransactionsDAO { } const aliases = await Promise.all(row.aliases.map(async alias => { - const contested = await getAliasInfo(alias, this.dapi) + const aliasInfo = await getAliasInfo(alias, this.dapi) const isLocked = base58.encode( - Buffer.from(contested.contestedState?.finishedVoteInfo?.wonByIdentityId ?? ''), + Buffer.from(aliasInfo.contestedState?.finishedVoteInfo?.wonByIdentityId ?? ''), 'base64') !== row.identifier return { alias, - status: (contested.contestedState !== null && isLocked) ? 'locked' : 'ok' + status: (aliasInfo.contestedState !== null && isLocked) ? 'locked' : 'ok' } })) @@ -78,15 +78,15 @@ module.exports = class TransactionsDAO { const resultSet = await Promise.all(rows.map(async (row) => { const aliases = await Promise.all((row.aliases ?? []).map(async alias => { - const contested = await getAliasInfo(alias, this.dapi) + const aliasInfo = await getAliasInfo(alias, this.dapi) const isLocked = base58.encode( - Buffer.from(contested.contestedState?.finishedVoteInfo?.wonByIdentityId ?? ''), + Buffer.from(aliasInfo.contestedState?.finishedVoteInfo?.wonByIdentityId ?? ''), 'base64') !== row.identifier return { alias, - status: (contested.contestedState !== null && isLocked) ? 'locked' : 'ok' + status: (aliasInfo.contestedState !== null && isLocked) ? 'locked' : 'ok' } })) From af1b376d2065254df985da048ca61cbca406877a Mon Sep 17 00:00:00 2001 From: owl352 Date: Sun, 17 Nov 2024 23:55:51 +0300 Subject: [PATCH 34/35] structure fix --- packages/api/src/models/Transaction.js | 2 +- packages/api/test/integration/identities.spec.js | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/api/src/models/Transaction.js b/packages/api/src/models/Transaction.js index 9b37c9a26..9ce7be21e 100644 --- a/packages/api/src/models/Transaction.js +++ b/packages/api/src/models/Transaction.js @@ -63,7 +63,7 @@ module.exports = class Transaction { status, decodedError ?? error, { identifier: owner?.trim(), - aliases: aliases ?? null + aliases: aliases ?? [] } ) } diff --git a/packages/api/test/integration/identities.spec.js b/packages/api/test/integration/identities.spec.js index c90a30021..876d4c587 100644 --- a/packages/api/test/integration/identities.spec.js +++ b/packages/api/test/integration/identities.spec.js @@ -884,7 +884,7 @@ describe('Identities routes', () => { error: _transaction.transaction.error, owner: { identifier: _transaction.transaction.owner, - aliases: null + aliases: [] } })) @@ -931,7 +931,7 @@ describe('Identities routes', () => { error: _transaction.transaction.error, owner: { identifier: _transaction.transaction.owner, - aliases: null + aliases: [] } })) @@ -978,7 +978,7 @@ describe('Identities routes', () => { error: _transaction.transaction.error, owner: { identifier: _transaction.transaction.owner, - aliases: null + aliases: [] } })) @@ -1025,7 +1025,7 @@ describe('Identities routes', () => { error: _transaction.transaction.error, owner: { identifier: _transaction.transaction.owner, - aliases: null + aliases: [] } })) From 9ec6a53f1f13bae670d37ee577c0f3d5fd84a246 Mon Sep 17 00:00:00 2001 From: owl352 Date: Sun, 17 Nov 2024 23:57:24 +0300 Subject: [PATCH 35/35] name fix --- packages/api/src/utils.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/api/src/utils.js b/packages/api/src/utils.js index a35e34938..b1ccec67b 100644 --- a/packages/api/src/utils.js +++ b/packages/api/src/utils.js @@ -176,7 +176,7 @@ const calculateInterval = (start, end) => { }, intervalsInRFC[0]) } -const generateNameIndexBuffer = (name) => { +const buildIndexBuffer = (name) => { const lengthBuffer = Buffer.alloc(1) lengthBuffer.writeUInt8(name.length.toString(16), 0) @@ -195,9 +195,9 @@ const getAliasInfo = async (alias, dapi) => { const normalizedLabel = convertToHomographSafeChars(label ?? '') if (/^[a-zA-Z01]{3,19}$/.test(normalizedLabel)) { - const domainBuffer = generateNameIndexBuffer(domain) + const domainBuffer = buildIndexBuffer(domain) - const labelBuffer = generateNameIndexBuffer(normalizedLabel) + const labelBuffer = buildIndexBuffer(normalizedLabel) const contestedState = await dapi.getContestedState( Buffer.from(base58.decode(DPNS_CONTRACT)).toString('base64'),