Skip to content

Commit

Permalink
Merge pull request #357 from pshenmic/feat/identities-fields
Browse files Browse the repository at this point in the history
New fields for identities
owl352 authored Dec 9, 2024
2 parents 8f46959 + bb87cc5 commit e737427
Showing 11 changed files with 478 additions and 111 deletions.
88 changes: 70 additions & 18 deletions packages/api/README.md
Original file line number Diff line number Diff line change
@@ -743,24 +743,76 @@ Return identity by given identifier
GET /identity/GWRSAVFMjXx8HpQFaNJMqBV7MBgMK4br5UESsB4S31Ec
{
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",
contested: true
}
]
"identifier": "3igSMtXaaS9iRQHbWU1w4hHveKdxixwMpgmhLzjVhFZJ",
"revision": 0,
"balance": 49989647300,
"timestamp": "2024-10-12T18:51:44.592Z",
"txHash": "32FB988D87E4122A2FE030B5014A59A05786C1501FD97D765E2329F89A8AD01D",
"totalTxs": 13,
"totalTransfers": 7,
"totalDocuments": 5,
"totalDataContracts": 0,
"isSystem": false,
"aliases": [
{
"alias": "owl352.dash",
"status": "ok",
"contested": false
}
],
"totalGasSpent": 310352700,
"averageGasSpent": 23873285,
"topUpsGasSpent": 46350660,
"withdrawalsGasSpent": 0,
"lastWithdrawalHash": null,
"publicKeys": [
{
"keyId": 0,
"type": 0,
"data": "0386067dea94b1cfb23bf252084a2020a4a6712df7e4ac16c211558a1dbb66904a",
"purpose": 0,
"securityLevel": 0,
"isReadOnly": false,
"isMaster": true,
"hash": "5501114f5842004d1ff6c7d04512c438afe0cb11",
"contractBounds": null
},
{
"keyId": 1,
"type": 0,
"data": "038a09509830d2d04685294e920aa29c96d51f9bd81044e2f934a4c198b934b102",
"purpose": 0,
"securityLevel": 2,
"isReadOnly": false,
"isMaster": false,
"hash": "c563c11128b9e457ad3b7220315b4bf53c8af443",
"contractBounds": null
},
{
"keyId": 2,
"type": 0,
"data": "027734bd9b8864964eb7504a77a986782e9d620e4c6d23e2bd80359e1e81790a1c",
"purpose": 0,
"securityLevel": 1,
"isReadOnly": false,
"isMaster": false,
"hash": "4bd1a43ea0cf7c18c1f90d1d9c0f08c63743ff1d",
"contractBounds": null
},
{
"keyId": 3,
"type": 0,
"data": "03083620dea1216b47568aead0c7cb6302ae3ca8beaa40c51e25b20f1f02ae06d4",
"purpose": 3,
"securityLevel": 1,
"isReadOnly": false,
"isMaster": false,
"hash": "f6d941f2d7aa4bc9d90b90bc103bd583c5943af9",
"contractBounds": null
}
],
"fundingCoreTx": "68d77e0d2da31e9cf2758d8f97547c1bc98b75c4e2cebe64dbcaae3bb5cb8a9c",
"owner": "3igSMtXaaS9iRQHbWU1w4hHveKdxixwMpgmhLzjVhFZJ"
}
```
Response codes:
30 changes: 30 additions & 0 deletions packages/api/src/DAPI.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
const Withdrawal = require('./models/Withdrawal')
const { Identifier } = require('dash').PlatformProtocol

const { IdentityPublicKey } = require('@dashevo/wasm-dpp/dist/wasm/wasm_dpp')

class DAPI {
dapi
dpp
@@ -76,6 +78,34 @@ class DAPI {
)
return contestedResourceContenders
}

async getIdentityKeys (identifier, keysIds, limit) {
const { identityKeys } = await this.dapi.platform.getIdentityKeys(Identifier.from(identifier), keysIds, limit)

return identityKeys.map(key => {
const serialized = IdentityPublicKey.fromBuffer(Buffer.from(key))

const { contractBounds } = IdentityPublicKey.fromBuffer(Buffer.from(key)).toObject()

return {
keyId: serialized.getId(),
type: serialized.getType(),
data: Buffer.from(serialized.getData()).toString('hex'),
purpose: serialized.getPurpose(),
securityLevel: serialized.getSecurityLevel(),
isReadOnly: serialized.isReadOnly(),
isMaster: serialized.isMaster(),
hash: Buffer.from(serialized.hash()).toString('hex'),
contractBounds: contractBounds
? {
type: contractBounds.type,
id: Identifier.from(Buffer.from(contractBounds.id)),
typeName: contractBounds.document_type_name
}
: null
}
})
}
}

module.exports = DAPI
2 changes: 1 addition & 1 deletion packages/api/src/controllers/IdentitiesController.js
Original file line number Diff line number Diff line change
@@ -6,7 +6,7 @@ const { decodeStateTransition } = require('../utils')

class IdentitiesController {
constructor (client, knex, dapi) {
this.identitiesDAO = new IdentitiesDAO(knex, dapi)
this.identitiesDAO = new IdentitiesDAO(knex, dapi, client)
this.dapi = dapi
this.client = client
}
69 changes: 58 additions & 11 deletions packages/api/src/dao/IdentitiesDAO.js
Original file line number Diff line number Diff line change
@@ -4,13 +4,14 @@ const Transaction = require('../models/Transaction')
const Document = require('../models/Document')
const DataContract = require('../models/DataContract')
const PaginatedResultSet = require('../models/PaginatedResultSet')
const { IDENTITY_CREDIT_WITHDRAWAL } = require('../enums/StateTransitionEnum')
const { getAliasInfo, getAliasStateByVote } = require('../utils')
const { IDENTITY_CREDIT_WITHDRAWAL, IDENTITY_TOP_UP } = require('../enums/StateTransitionEnum')
const { getAliasInfo, decodeStateTransition, getAliasStateByVote } = require('../utils')

module.exports = class IdentitiesDAO {
constructor (knex, dapi) {
constructor (knex, dapi, client) {
this.knex = knex
this.dapi = dapi
this.client = client
}

getIdentityByIdentifier = async (identifier) => {
@@ -52,19 +53,53 @@ module.exports = class IdentitiesDAO {
.orWhere('recipient', identifier)
.as('transfer_alias')

const rows = await this.knex.with('with_alias', lastRevisionIdentities)
.select('identifier', 'with_alias.owner as owner', 'revision', 'transfer_id', 'sender',
'tx_hash', 'is_system', 'blocks.timestamp as timestamp', 'recipient', 'amount')
.leftJoin('state_transitions', 'state_transitions.hash', 'tx_hash')
.leftJoin('blocks', 'state_transitions.block_hash', 'blocks.hash')
const mainQuery = this.knex.with('with_alias', lastRevisionIdentities)
.select(
'identifier', 'with_alias.owner as owner', 'revision',
'transfer_id', 'sender', 'tx_hash', 'is_system',
'blocks.timestamp as timestamp', 'recipient', 'amount',
'state_transitions.data as tx_data'
)
.select(this.knex('state_transitions').count('*').where('owner', identifier).as('total_txs'))
.select(this.knex('state_transitions').sum('gas_used').where('owner', identifier).as('total_gas_spent'))
.select(this.knex(documentsSubQuery).count('*').where('rank', 1).as('total_documents'))
.select(this.knex(dataContractsSubQuery).count('*').where('rank', 1).as('total_data_contracts'))
.select(this.knex(transfersSubquery).count('*').as('total_transfers'))
.select(this.knex(aliasSubquery).select('aliases').limit(1).as('aliases'))
.leftJoin('state_transitions', 'state_transitions.hash', 'tx_hash')
.leftJoin('blocks', 'state_transitions.block_hash', 'blocks.hash')
.from('with_alias')
.limit(1)

const rows = await this.knex.with('with_alias', mainQuery)
.select(
'identifier', 'owner', 'revision',
'transfer_id', 'sender', 'tx_hash',
'is_system', 'timestamp', 'recipient',
'amount', 'total_txs', 'total_gas_spent',
'total_documents', 'total_data_contracts',
'total_transfers', 'aliases', 'tx_data',
this.knex.raw('ROUND(total_gas_spent/total_txs) as average_gas_spent')
)
.select(this.knex('state_transitions')
.sum('gas_used')
.where('owner', identifier)
.andWhere('type', IDENTITY_TOP_UP)
.as('top_ups_gas_spent'))
.select(this.knex('state_transitions')
.sum('gas_used')
.where('owner', identifier)
.andWhere('type', IDENTITY_CREDIT_WITHDRAWAL)
.as('withdrawals_gas_spent'))
.select(this.knex('state_transitions')
.select('hash')
.where('owner', identifier)
.andWhere('type', IDENTITY_CREDIT_WITHDRAWAL)
.orderBy('id', 'desc')
.limit(1)
.as('last_withdrawal_hash'))
.from('with_alias')

if (!rows.length) {
return null
}
@@ -83,11 +118,23 @@ module.exports = class IdentitiesDAO {
return getAliasStateByVote(aliasInfo, alias, identifier)
}))

return {
const publicKeys = await this.dapi.getIdentityKeys(identity.identifier)

let fundingCoreTx = null

if (row.tx_data) {
const { assetLockProof } = await decodeStateTransition(this.client, row.tx_data)

fundingCoreTx = assetLockProof?.txid
}

return Identity.fromObject({
...identity,
aliases,
balance: await this.dapi.getIdentityBalance(identity.identifier.trim())
}
balance: await this.dapi.getIdentityBalance(identity.identifier),
publicKeys,
fundingCoreTx
})
}

getIdentitiesByDPNSName = async (dpns) => {
88 changes: 82 additions & 6 deletions packages/api/src/models/Identity.js
Original file line number Diff line number Diff line change
@@ -10,8 +10,23 @@ module.exports = class Identity {
totalDataContracts
isSystem
aliases
totalGasSpent
averageGasSpent
topUpsGasSpent
withdrawalsGasSpent
lastWithdrawalHash
publicKeys
fundingCoreTx

constructor (identifier, owner, revision, balance, timestamp, totalTxs, totalDataContracts, totalDocuments, totalTransfers, txHash, isSystem, aliases) {
constructor (
identifier, owner, revision,
balance, timestamp, totalTxs,
totalDataContracts, totalDocuments,
totalTransfers, txHash, isSystem,
aliases, totalGasSpent, averageGasSpent,
topUpsGasSpent, withdrawalsGasSpent,
lastWithdrawalHash, publicKeys, fundingCoreTx
) {
this.identifier = identifier ? identifier.trim() : null
this.owner = owner ? owner.trim() : null
this.revision = revision ?? null
@@ -24,14 +39,75 @@ module.exports = class Identity {
this.txHash = txHash ?? null
this.isSystem = isSystem ?? null
this.aliases = aliases ?? []
this.totalGasSpent = totalGasSpent ?? null
this.averageGasSpent = averageGasSpent ?? null
this.topUpsGasSpent = topUpsGasSpent ?? null
this.withdrawalsGasSpent = withdrawalsGasSpent ?? null
this.lastWithdrawalHash = lastWithdrawalHash ?? null
this.publicKeys = publicKeys ?? []
this.fundingCoreTx = fundingCoreTx ?? null
}

// 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?.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, totalGasSpent, averageGasSpent,
topUpsGasSpent, withdrawalsGasSpent,
lastWithdrawalHash, publicKeys, fundingCoreTx
}) {
return new Identity(
identifier,
owner,
revision,
balance,
timestamp,
totalTxs,
totalDataContracts,
totalDocuments,
totalTransfers,
txHash,
isSystem,
aliases,
totalGasSpent,
averageGasSpent,
topUpsGasSpent,
withdrawalsGasSpent,
lastWithdrawalHash,
publicKeys,
fundingCoreTx
)
}

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)
/* eslint-disable camelcase */
static fromRow ({
identifier, owner, revision,
balance, timestamp, total_txs,
total_data_contracts, total_documents,
total_transfers, tx_hash, is_system,
aliases, total_gas_spent, average_gas_spent,
top_ups_gas_spent, withdrawals_gas_spent,
last_withdrawal_hash
}) {
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,
Number(total_gas_spent),
Number(average_gas_spent),
Number(top_ups_gas_spent),
Number(withdrawals_gas_spent),
last_withdrawal_hash
)
}
}
Loading

0 comments on commit e737427

Please sign in to comment.