Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Withdrawals data from dapi #313

Merged
merged 20 commits into from
Nov 18, 2024
Merged
53 changes: 53 additions & 0 deletions packages/api/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -712,7 +712,60 @@ Response codes:
200: OK
500: Internal Server Error
```
---
### Identity Withdrawals
Return all withdrawals for identity

_Note: this request does not contain any pagination data in the response_

* `limit` cannot be more then 100
```
GET /identity/A1rgGVjRGuznRThdAA316VEEpKuVQ7mV8mBK1BFJvXnb/withdrawals?limit=5

[
{
"timestamp": 1729096625509,
"sender": "A1rgGVjRGuznRThdAA316VEEpKuVQ7mV8mBK1BFJvXnb",
"id": "95eiiqMotMvH23f6cv3BPC4ykcHFWTy2g3baCTWZANAs",
"amount": 200000,
"status": 3
},
{
"timestamp": 1729096140465,
"sender": "A1rgGVjRGuznRThdAA316VEEpKuVQ7mV8mBK1BFJvXnb",
"id": "DJzb8nj7JTHwnvAGEGhyFc5hHLFa5Es9WFAyS4HhhNeF",
"amount": 200000,
"status": 3
},
{
"timestamp": 1729096636318,
"sender": "A1rgGVjRGuznRThdAA316VEEpKuVQ7mV8mBK1BFJvXnb",
"id": "E4gbWCQgqrz9DVrzCeDKhr4PVsfp6CeL5DUAYndRVWdk",
"amount": 200000,
"status": 3
},
{
"timestamp": 1729096795042,
"sender": "A1rgGVjRGuznRThdAA316VEEpKuVQ7mV8mBK1BFJvXnb",
"id": "FouX2qY8Eaxj5rSBrH9uxbhAM16ozrUP4sJwdo9pL7Cr",
"amount": 200000,
"status": 3
},
{
"timestamp": 1729097247874,
"sender": "A1rgGVjRGuznRThdAA316VEEpKuVQ7mV8mBK1BFJvXnb",
"id": "9VEpb2aJRnCxfi3LjFXWa1zshkBPfzzHHh5yqEkgqw1t",
"amount": 200000,
"status": 3
}
]
```
Response codes:
```
200: OK
500: Internal Server Error
```
---
### Data contracts by Identity
Return all data contracts by the given identity

Expand Down
141 changes: 141 additions & 0 deletions packages/api/data_contracts/withdrawals.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
{
"version": 0,
"ownerId": "11111111111111111111111111111111",
"id": "4fJLR2GYTPFdomuTVvNy3VRrvWgvkKPzqehEBpNf2nk6",
"$format_version": "0",
"documentSchemas": {
"withdrawal": {
"type": "object",
"indices": [
{
"name": "identityStatus",
"unique": false,
"properties": [
{
"$ownerId": "asc"
},
{
"status": "asc"
},
{
"$createdAt": "asc"
}
]
},
{
"name": "identityRecent",
"unique": false,
"properties": [
{
"$ownerId": "asc"
},
{
"$updatedAt": "asc"
},
{
"status": "asc"
}
]
},
{
"name": "pooling",
"unique": false,
"properties": [
{
"status": "asc"
},
{
"pooling": "asc"
},
{
"coreFeePerByte": "asc"
},
{
"$updatedAt": "asc"
}
]
},
{
"name": "transaction",
"unique": false,
"properties": [
{
"status": "asc"
},
{
"transactionIndex": "asc"
}
]
}
],
"required": [
"$createdAt",
"$updatedAt",
"amount",
"coreFeePerByte",
"pooling",
"outputScript",
"status"
],
"properties": {
"amount": {
"type": "integer",
"minimum": 1000,
"position": 2,
"description": "The amount to be withdrawn"
},
"status": {
"enum": [
0,
1,
2,
3,
4
],
"type": "integer",
"position": 6,
"description": "0 - Pending, 1 - Signed, 2 - Broadcasted, 3 - Complete, 4 - Expired"
},
"pooling": {
"enum": [
0,
1,
2
],
"type": "integer",
"position": 4,
"description": "This indicated the level at which Platform should try to pool this transaction"
},
"outputScript": {
"type": "array",
"maxItems": 25,
"minItems": 23,
"position": 5,
"byteArray": true
},
"coreFeePerByte": {
"type": "integer",
"maximum": 4294967295,
"minimum": 1,
"position": 3,
"description": "This is the fee that you are willing to spend for this transaction in Duffs/Byte"
},
"transactionIndex": {
"type": "integer",
"minimum": 1,
"position": 0,
"description": "Sequential index of asset unlock (withdrawal) transaction. Populated when a withdrawal pooled into withdrawal transaction"
},
"transactionSignHeight": {
"type": "integer",
"minimum": 1,
"position": 1,
"description": "The Core height on which transaction was signed"
}
},
"description": "Withdrawal document to track underlying withdrawal transactions. Withdrawals should be created with IdentityWithdrawalTransition",
"additionalProperties": false,
"creationRestrictionMode": 2
}
}
}
19 changes: 19 additions & 0 deletions packages/api/src/DAPI.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
const Withdrawal = require('./models/Withdrawal')
const { Identifier } = require('dash').PlatformProtocol

class DAPI {
Expand All @@ -24,6 +25,24 @@ class DAPI {
return epochsInfo
}

async getDocuments (type, dataContractObject, identifier, limit) {
const dataContract = await this.dpp.dataContract.createFromObject(dataContractObject)

const { documents } = await this.dapi.platform.getDocuments(Identifier.from(dataContractObject.id), type, {
limit,
where: [
['$ownerId', '=', Identifier.from(identifier)]
]
})

return documents.map(
pshenmic marked this conversation as resolved.
Show resolved Hide resolved
(document) =>
Withdrawal.fromRaw(
this.dpp.document.createExtendedDocumentFromDocumentBuffer(document, type, dataContract).toJSON()
)
)
}

/**
* Fetch the version upgrade votes status
* @typedef {getContestedState}
Expand Down
1 change: 1 addition & 0 deletions packages/api/src/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ const TenderdashRPC = require('./tenderdashRpc')
let genesisTime

module.exports = {
WITHDRAWAL_CONTRACT_TYPE: 'withdrawal',
EPOCH_CHANGE_TIME: Number(process.env.EPOCH_CHANGE_TIME),
TCP_CONNECT_TIMEOUT: Number(process.env.TCP_CONNECT_TIMEOUT),
DPNS_CONTRACT: 'GWRSAVFMjXx8HpQFaNJMqBV7MBgMK4br5UESsB4S31Ec',
Expand Down
28 changes: 18 additions & 10 deletions packages/api/src/controllers/IdentitiesController.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
const IdentitiesDAO = require('../dao/IdentitiesDAO')
const { IDENTITY_CREDIT_WITHDRAWAL } = require('../enums/StateTransitionEnum')
const { WITHDRAWAL_CONTRACT_TYPE } = require('../constants')
const WithdrawalsContract = require('../../data_contracts/withdrawals.json')

class IdentitiesController {
constructor (knex, dapi) {
Expand Down Expand Up @@ -77,17 +78,24 @@ class IdentitiesController {

getWithdrawalsByIdentity = async (request, response) => {
const { identifier } = request.params
const { page = 1, limit = 10, order = 'asc' } = request.query
const { limit = 100 } = request.query

const documents = await this.dapi.getDocuments(WITHDRAWAL_CONTRACT_TYPE, WithdrawalsContract, identifier, limit)

const timestamps = documents.map(document => new Date(document.timestamp).toISOString())

const withdrawals = await this.identitiesDAO.getTransfersByIdentity(
identifier,
Number(page ?? 1),
Number(limit ?? 10),
order ?? 'asc',
IDENTITY_CREDIT_WITHDRAWAL
)
const txHashes = await this.identitiesDAO.getIdentityWithdrawalsByTimestamps(identifier, timestamps)

if (documents.length === 0) {
return response.status(404).send({ message: 'not found' })
}

response.send(withdrawals)
response.send(documents.map(document => ({
...document,
hash: txHashes.find(
hash =>
new Date(hash.timestamp).toISOString() === new Date(document.timestamp).toISOString())?.hash ?? null
})))
}
}

Expand Down
13 changes: 13 additions & 0 deletions packages/api/src/dao/IdentitiesDAO.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ 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 } = require('../utils')
const { base58 } = require('@scure/base')

Expand Down Expand Up @@ -353,4 +354,16 @@ module.exports = class IdentitiesDAO {

return new PaginatedResultSet(rows.map(row => Transfer.fromRow(row)), page, limit, totalCount)
}

getIdentityWithdrawalsByTimestamps = async (identifier, timestamps = []) => {
return this.knex('state_transitions')
.select('state_transitions.hash', 'blocks.timestamp as timestamp')
.whereIn(
'blocks.timestamp',
timestamps
)
.andWhere('owner', identifier)
.andWhere('type', IDENTITY_CREDIT_WITHDRAWAL)
.leftJoin('blocks', 'block_hash', 'blocks.hash')
}
}
21 changes: 21 additions & 0 deletions packages/api/src/models/Withdrawal.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
module.exports = class Withdrawal {
timestamp
hash
sender
id
amount
status

constructor (timestamp, hash, sender, id, amount, status) {
this.timestamp = timestamp ?? null
this.hash = hash ?? null
this.sender = sender ?? null
this.id = id ?? null
this.amount = amount ?? null
this.status = status ?? null
}

static fromRaw (data = {}) {
return new Withdrawal(data.$createdAt, null, data.$ownerId, data.$id, data.amount, data.status)
}
}
1 change: 0 additions & 1 deletion packages/api/src/routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,6 @@ module.exports = ({
method: 'GET',
handler: identitiesController.getWithdrawalsByIdentity,
schema: {
querystring: { $ref: 'paginationOptions#' },
params: {
type: 'object',
properties: {
Expand Down
Loading
Loading