@dashevo/dapi-client 0.25.0-dev.9 → 0.25.0-pr.1545.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/lib/BlockHeadersProvider/BlockHeadersProvider.js +14 -16
  2. package/lib/DAPIClient.js +8 -0
  3. package/lib/logger/index.js +76 -0
  4. package/lib/methods/platform/PlatformMethodsFacade.js +10 -0
  5. package/lib/methods/platform/getConsensusParams/getConsensusParamsFactory.js +10 -2
  6. package/lib/methods/platform/getConsensusParams/getConsensusParamsResponse.js +2 -2
  7. package/lib/methods/platform/getDataContract/GetDataContractResponse.js +1 -1
  8. package/lib/methods/platform/getDataContract/getDataContractFactory.js +6 -2
  9. package/lib/methods/platform/getDataContractHistory/GetDataContractHistoryResponse.js +55 -0
  10. package/lib/methods/platform/getDataContractHistory/getDataContractHistoryFactory.js +86 -0
  11. package/lib/methods/platform/getDocuments/GetDocumentsResponse.js +4 -1
  12. package/lib/methods/platform/getDocuments/getDocumentsFactory.js +12 -8
  13. package/lib/methods/platform/getEpochsInfo/EpochInfo.js +54 -0
  14. package/lib/methods/platform/getEpochsInfo/GetEpochsInfoResponse.js +59 -0
  15. package/lib/methods/platform/getEpochsInfo/getEpochsInfoFactory.js +69 -0
  16. package/lib/methods/platform/getIdentitiesByPublicKeyHashes/GetIdentitiesByPublicKeyHashesResponse.js +10 -1
  17. package/lib/methods/platform/getIdentitiesByPublicKeyHashes/getIdentitiesByPublicKeyHashesFactory.js +6 -3
  18. package/lib/methods/platform/getIdentity/GetIdentityResponse.js +2 -2
  19. package/lib/methods/platform/getIdentity/getIdentityFactory.js +6 -2
  20. package/lib/methods/platform/getProtocolVersionUpgradeState/GetProtocolVersionUpgradeStateResponse.js +56 -0
  21. package/lib/methods/platform/getProtocolVersionUpgradeState/VersionEntry.js +26 -0
  22. package/lib/methods/platform/getProtocolVersionUpgradeState/getProtocolVersionUpgradeStateFactory.js +63 -0
  23. package/lib/methods/platform/getProtocolVersionUpgradeVoteStatus/GetProtocolVersionUpgradeVoteStatusResponse.js +56 -0
  24. package/lib/methods/platform/getProtocolVersionUpgradeVoteStatus/VersionSignal.js +26 -0
  25. package/lib/methods/platform/getProtocolVersionUpgradeVoteStatus/getProtocolVersionUpgradeVoteStatusFactory.js +72 -0
  26. package/lib/methods/platform/response/AbstractResponse.js +2 -2
  27. package/lib/methods/platform/response/Proof.js +3 -3
  28. package/lib/methods/platform/waitForStateTransitionResult/WaitForStateTransitionResultResponse.js +8 -7
  29. package/lib/methods/platform/waitForStateTransitionResult/waitForStateTransitionResultFactory.js +7 -4
  30. package/lib/networkConfigs.js +38 -129
  31. package/lib/test/bootstrap.js +6 -0
  32. package/lib/transport/GrpcTransport/GrpcTransport.js +7 -0
  33. package/lib/transport/GrpcTransport/errors/InternalServerError.js +2 -2
  34. package/lib/transport/JsonRpcTransport/JsonRpcTransport.js +6 -0
  35. package/lib/transport/JsonRpcTransport/requestJsonRpc.js +2 -3
  36. package/package.json +13 -10
  37. package/polyfills/fetch-polyfill.js +1 -1
@@ -1,6 +1,4 @@
1
1
  const EventEmitter = require('events');
2
- const { configure: configureDashcore } = require('@dashevo/dashcore-lib');
3
- const X11 = require('wasm-x11-hash');
4
2
  const { SpvChain, SPVError } = require('@dashevo/dash-spv');
5
3
 
6
4
  const BlockHeadersReader = require('./BlockHeadersReader');
@@ -51,7 +49,6 @@ class BlockHeadersProvider extends EventEmitter {
51
49
  this.spvChain = new SpvChain(this.options.network, 100);
52
50
 
53
51
  this.state = STATES.IDLE;
54
- this.wasmX11Ready = false;
55
52
 
56
53
  this.errorHandler = this.errorHandler.bind(this);
57
54
  this.headersHandler = this.headersHandler.bind(this);
@@ -79,13 +76,7 @@ class BlockHeadersProvider extends EventEmitter {
79
76
  * @private
80
77
  */
81
78
  async init() {
82
- if (!this.wasmX11Ready) {
83
- const x11Hash = await X11();
84
- configureDashcore({
85
- x11hash: x11Hash,
86
- });
87
- this.wasmX11Ready = true;
88
- }
79
+ await SpvChain.wasmX11Ready();
89
80
 
90
81
  if (!this.blockHeadersReader) {
91
82
  this.blockHeadersReader = new BlockHeadersReader(
@@ -113,12 +104,18 @@ class BlockHeadersProvider extends EventEmitter {
113
104
  * Initializes SPV chain with a list of headers and a known lastSyncedHeaderHeight
114
105
  *
115
106
  * @param headers
116
- * @param lastSyncedHeaderHeight
107
+ * @param firstHeaderHeight
117
108
  */
118
- initializeWith(headers, lastSyncedHeaderHeight) {
119
- const firstHeaderHeight = lastSyncedHeaderHeight - headers.length + 1;
120
- this.spvChain.reset(firstHeaderHeight);
121
- this.spvChain.addHeaders(headers, firstHeaderHeight);
109
+ async initializeChainWith(headers, firstHeaderHeight) {
110
+ await SpvChain.wasmX11Ready();
111
+
112
+ if (headers.length === 0) {
113
+ // If there are no headers, initialize chain from genesis
114
+ this.spvChain.initialize();
115
+ } else {
116
+ this.spvChain.initialize(headers[0], firstHeaderHeight);
117
+ this.spvChain.addHeaders(headers);
118
+ }
122
119
  }
123
120
 
124
121
  /**
@@ -130,7 +127,8 @@ class BlockHeadersProvider extends EventEmitter {
130
127
  ensureChainRoot(height) {
131
128
  // Flush spv chain in case header at specified height was not found
132
129
  if (!this.spvChain.hashesByHeight.has(height - 1)) {
133
- this.spvChain.reset(height);
130
+ this.spvChain.reset();
131
+ this.spvChain.pendingStartBlockHeight = height;
134
132
  }
135
133
  }
136
134
 
package/lib/DAPIClient.js CHANGED
@@ -14,6 +14,8 @@ const createJsonTransportError = require('./transport/JsonRpcTransport/createJso
14
14
  const BlockHeadersProvider = require('./BlockHeadersProvider/BlockHeadersProvider');
15
15
  const createBlockHeadersProviderFromOptions = require('./BlockHeadersProvider/createBlockHeadersProviderFromOptions');
16
16
 
17
+ const logger = require('./logger');
18
+
17
19
  const EVENTS = {
18
20
  ERROR: 'error',
19
21
  };
@@ -30,6 +32,9 @@ class DAPIClient extends EventEmitter {
30
32
  timeout: 10000,
31
33
  retries: 5,
32
34
  blockHeadersProviderOptions: BlockHeadersProvider.defaultOptions,
35
+ loggerOptions: {
36
+ identifier: '',
37
+ },
33
38
  ...options,
34
39
  };
35
40
 
@@ -52,6 +57,7 @@ class DAPIClient extends EventEmitter {
52
57
 
53
58
  this.core = new CoreMethodsFacade(jsonRpcTransport, grpcTransport);
54
59
  this.platform = new PlatformMethodsFacade(grpcTransport);
60
+ this.logger = logger.getForId(this.options.loggerOptions.identifier);
55
61
 
56
62
  this.initBlockHeadersProvider();
57
63
  }
@@ -81,6 +87,8 @@ DAPIClient.EVENTS = EVENTS;
81
87
  * @property {number} [retries=3]
82
88
  * @property {number} [baseBanTime=60000]
83
89
  * @property {boolean} [throwDeadlineExceeded]
90
+ * @property {object} [loggerOptions]
91
+ * @property {string} [loggerOptions.identifier]
84
92
  * @property {BlockHeadersProvider} [blockHeadersProvider]
85
93
  * @property {BlockHeadersProviderOptions} [blockHeadersProviderOptions]
86
94
  */
@@ -0,0 +1,76 @@
1
+ const util = require('util');
2
+ const winston = require('winston');
3
+
4
+ const LOG_LEVEL = process.env.LOG_LEVEL || 'info';
5
+ const LOG_TO_FILE = process.env.LOG_WALLET_TO_FILE || 'false';
6
+
7
+ // Log levels:
8
+ // error 0
9
+ // warn 1
10
+ // info 2 (default)
11
+ // verbose 3
12
+ // debug 4
13
+ // silly 5
14
+
15
+ const loggers = {};
16
+
17
+ const createLogger = (formats = [], id = '') => {
18
+ const format = winston.format.combine(
19
+ {
20
+ transform: (info) => {
21
+ const args = info[Symbol.for('splat')];
22
+ const result = { ...info };
23
+ if (args) {
24
+ result.message = util.format(info.message, ...args);
25
+ }
26
+ return result;
27
+ },
28
+ },
29
+ ...formats,
30
+ winston.format.colorize(),
31
+ winston.format.printf(({
32
+ level, message,
33
+ }) => `${level}: ${message}`),
34
+ );
35
+
36
+ const transports = [
37
+ new winston.transports.Console({
38
+ format,
39
+ }),
40
+ ];
41
+
42
+ if (LOG_TO_FILE === 'true' && typeof window === 'undefined') {
43
+ transports.push(
44
+ new winston.transports.File({
45
+ filename: `wallet${id !== '' ? `_${id}` : ''}`,
46
+ format,
47
+ }),
48
+ );
49
+ }
50
+
51
+ return winston.createLogger({
52
+ level: LOG_LEVEL,
53
+ transports,
54
+ });
55
+ };
56
+
57
+ const logger = createLogger();
58
+
59
+ logger.getForId = (id) => {
60
+ if (!loggers[id]) {
61
+ const format = {
62
+ transform: (info) => {
63
+ const message = `[DAPIClient: ${id}] ${info.message}`;
64
+ return { ...info, message };
65
+ },
66
+ };
67
+
68
+ loggers[id] = createLogger([format], id);
69
+ }
70
+
71
+ return loggers[id];
72
+ };
73
+
74
+ logger.verbose(`Logger uses "${LOG_LEVEL}" level`, { level: LOG_LEVEL });
75
+
76
+ module.exports = logger;
@@ -1,10 +1,14 @@
1
1
  const broadcastStateTransitionFactory = require('./broadcastStateTransition/broadcastStateTransitionFactory');
2
2
  const getDataContractFactory = require('./getDataContract/getDataContractFactory');
3
+ const getDataContractHistoryFactory = require('./getDataContractHistory/getDataContractHistoryFactory');
3
4
  const getDocumentsFactory = require('./getDocuments/getDocumentsFactory');
4
5
  const getIdentityFactory = require('./getIdentity/getIdentityFactory');
5
6
  const getIdentitiesByPublicKeyHashesFactory = require('./getIdentitiesByPublicKeyHashes/getIdentitiesByPublicKeyHashesFactory');
6
7
  const waitForStateTransitionResultFactory = require('./waitForStateTransitionResult/waitForStateTransitionResultFactory');
7
8
  const getConsensusParamsFactory = require('./getConsensusParams/getConsensusParamsFactory');
9
+ const getEpochsInfoFactory = require('./getEpochsInfo/getEpochsInfoFactory');
10
+ const getProtocolVersionUpgradeVoteStatusFactory = require('./getProtocolVersionUpgradeVoteStatus/getProtocolVersionUpgradeVoteStatusFactory');
11
+ const getProtocolVersionUpgradeStateFactory = require('./getProtocolVersionUpgradeState/getProtocolVersionUpgradeStateFactory');
8
12
 
9
13
  class PlatformMethodsFacade {
10
14
  /**
@@ -13,11 +17,17 @@ class PlatformMethodsFacade {
13
17
  constructor(grpcTransport) {
14
18
  this.broadcastStateTransition = broadcastStateTransitionFactory(grpcTransport);
15
19
  this.getDataContract = getDataContractFactory(grpcTransport);
20
+ this.getDataContractHistory = getDataContractHistoryFactory(grpcTransport);
16
21
  this.getDocuments = getDocumentsFactory(grpcTransport);
17
22
  this.getIdentity = getIdentityFactory(grpcTransport);
18
23
  this.getIdentitiesByPublicKeyHashes = getIdentitiesByPublicKeyHashesFactory(grpcTransport);
19
24
  this.waitForStateTransitionResult = waitForStateTransitionResultFactory(grpcTransport);
20
25
  this.getConsensusParams = getConsensusParamsFactory(grpcTransport);
26
+ this.getEpochsInfo = getEpochsInfoFactory(grpcTransport);
27
+ this.getProtocolVersionUpgradeVoteStatus = getProtocolVersionUpgradeVoteStatusFactory(
28
+ grpcTransport,
29
+ );
30
+ this.getProtocolVersionUpgradeState = getProtocolVersionUpgradeStateFactory(grpcTransport);
21
31
  }
22
32
  }
23
33
 
@@ -7,6 +7,10 @@ const {
7
7
  const InvalidResponseError = require('../response/errors/InvalidResponseError');
8
8
  const GetConsensusParamsResponse = require('./getConsensusParamsResponse');
9
9
 
10
+ const {
11
+ GetConsensusParamsRequestV0,
12
+ } = GetConsensusParamsRequest;
13
+
10
14
  /**
11
15
  * @param {GrpcTransport} grpcTransport
12
16
  * @returns {getConsensusParams}
@@ -22,11 +26,15 @@ function getConsensusParamsFactory(grpcTransport) {
22
26
  */
23
27
  async function getConsensusParams(height = undefined, options = {}) {
24
28
  const getConsensusParamsRequest = new GetConsensusParamsRequest();
29
+ getConsensusParamsRequest.setV0(
30
+ new GetConsensusParamsRequestV0(),
31
+ );
32
+
25
33
  if (height !== undefined) {
26
- getConsensusParamsRequest.setHeight(height);
34
+ getConsensusParamsRequest.getV0().setHeight(height);
27
35
  }
28
36
 
29
- getConsensusParamsRequest.setProve(!!options.prove);
37
+ getConsensusParamsRequest.getV0().setProve(!!options.prove);
30
38
 
31
39
  let lastError;
32
40
 
@@ -32,8 +32,8 @@ class GetConsensusParamsResponse {
32
32
  * @returns {GetConsensusParamsResponse}
33
33
  */
34
34
  static createFromProto(proto) {
35
- const protoBlock = proto.getBlock();
36
- const protoEvidence = proto.getEvidence();
35
+ const protoBlock = proto.getV0().getBlock();
36
+ const protoEvidence = proto.getV0().getEvidence();
37
37
 
38
38
  if (!protoBlock && !protoEvidence) {
39
39
  throw new InvalidResponseError('Consensus params are not defined');
@@ -25,7 +25,7 @@ class GetDataContractResponse extends AbstractResponse {
25
25
  * @returns {GetDataContractResponse}
26
26
  */
27
27
  static createFromProto(proto) {
28
- const dataContract = proto.getDataContract();
28
+ const dataContract = proto.getV0().getDataContract();
29
29
  const { metadata, proof } = AbstractResponse.createMetadataAndProofFromProto(proto);
30
30
 
31
31
  if (!dataContract && !proof) {
@@ -22,6 +22,7 @@ function getDataContractFactory(grpcTransport) {
22
22
  * @returns {Promise<GetDataContractResponse>}
23
23
  */
24
24
  async function getDataContract(contractId, options = {}) {
25
+ const { GetDataContractRequestV0 } = GetDataContractRequest;
25
26
  const getDataContractRequest = new GetDataContractRequest();
26
27
 
27
28
  // need to convert objects inherited from Buffer to pure buffer as google protobuf
@@ -32,8 +33,11 @@ function getDataContractFactory(grpcTransport) {
32
33
  contractId = Buffer.from(contractId);
33
34
  }
34
35
 
35
- getDataContractRequest.setId(contractId);
36
- getDataContractRequest.setProve(!!options.prove);
36
+ getDataContractRequest.setV0(
37
+ new GetDataContractRequestV0()
38
+ .setId(contractId)
39
+ .setProve(!!options.prove),
40
+ );
37
41
 
38
42
  let lastError;
39
43
 
@@ -0,0 +1,55 @@
1
+ const AbstractResponse = require('../response/AbstractResponse');
2
+ const InvalidResponseError = require('../response/errors/InvalidResponseError');
3
+
4
+ class GetDataContractHistoryResponse extends AbstractResponse {
5
+ /**
6
+ * @param {object.<number, Buffer>} dataContractHistory
7
+ * @param {Metadata} metadata
8
+ * @param {Proof} [proof]
9
+ */
10
+ constructor(dataContractHistory, metadata, proof = undefined) {
11
+ super(metadata, proof);
12
+
13
+ this.dataContractHistory = dataContractHistory;
14
+ }
15
+
16
+ /**
17
+ * @returns {object.<number, Buffer>}
18
+ */
19
+ getDataContractHistory() {
20
+ return this.dataContractHistory;
21
+ }
22
+
23
+ /**
24
+ * @param proto
25
+ * @returns {GetDataContractHistoryResponse}
26
+ */
27
+ static createFromProto(proto) {
28
+ // History is something that we need to call a method to get a list of entries on
29
+ const dataContractHistory = proto.getV0().getDataContractHistory();
30
+ const { metadata, proof } = AbstractResponse.createMetadataAndProofFromProto(proto);
31
+
32
+ if (!dataContractHistory && !proof) {
33
+ throw new InvalidResponseError('DataContract is not defined');
34
+ }
35
+
36
+ const history = {};
37
+
38
+ if (dataContractHistory) {
39
+ const dataContractHistoryEntries = dataContractHistory.getDataContractEntriesList();
40
+
41
+ // eslint-disable-next-line no-restricted-syntax
42
+ for (const historyEntry of dataContractHistoryEntries) {
43
+ history[historyEntry.getDate()] = historyEntry.getValue();
44
+ }
45
+ }
46
+
47
+ return new GetDataContractHistoryResponse(
48
+ history,
49
+ metadata,
50
+ proof,
51
+ );
52
+ }
53
+ }
54
+
55
+ module.exports = GetDataContractHistoryResponse;
@@ -0,0 +1,86 @@
1
+ const {
2
+ v0: {
3
+ PlatformPromiseClient,
4
+ GetDataContractHistoryRequest,
5
+ },
6
+ } = require('@dashevo/dapi-grpc');
7
+
8
+ const { UInt32Value } = require('google-protobuf/google/protobuf/wrappers_pb');
9
+
10
+ const GetDataContractHistoryResponse = require('./GetDataContractHistoryResponse');
11
+ const InvalidResponseError = require('../response/errors/InvalidResponseError');
12
+ /**
13
+ * @param {GrpcTransport} grpcTransport
14
+ * @returns {getDataContractHistory}
15
+ */
16
+ function getDataContractHistoryFactory(grpcTransport) {
17
+ /**
18
+ * Fetch Data Contract by id
19
+ *
20
+ * @typedef {getDataContractHistory}
21
+ * @param {Buffer} contractId
22
+ * @param {number} [startAtMs]
23
+ * @param {number} [limit]
24
+ * @param {number} [offset]
25
+ * @param {DAPIClientOptions & {prove: boolean}} [options]
26
+ * @returns {Promise<GetDataContractHistoryResponse>}
27
+ */
28
+ async function getDataContractHistory(
29
+ contractId,
30
+ startAtMs = 0,
31
+ limit = 10,
32
+ offset = 0,
33
+ options = {},
34
+ ) {
35
+ const { GetDataContractHistoryRequestV0 } = GetDataContractHistoryRequest;
36
+ const getDataContractHistoryRequest = new GetDataContractHistoryRequest();
37
+
38
+ // need to convert objects inherited from Buffer to pure buffer as google protobuf
39
+ // doesn't support extended buffers
40
+ // https://github.com/protocolbuffers/protobuf/blob/master/js/binary/utils.js#L1049
41
+ if (Buffer.isBuffer(contractId)) {
42
+ // eslint-disable-next-line no-param-reassign
43
+ contractId = Buffer.from(contractId);
44
+ }
45
+
46
+ getDataContractHistoryRequest.setV0(
47
+ new GetDataContractHistoryRequestV0()
48
+ .setId(contractId)
49
+ .setStartAtMs(startAtMs)
50
+ .setLimit(new UInt32Value([limit]))
51
+ .setOffset(new UInt32Value([offset]))
52
+ .setProve(!!options.prove),
53
+ );
54
+
55
+ let lastError;
56
+
57
+ // TODO: simple retry before the dapi versioning is properly implemented
58
+ for (let i = 0; i < 3; i += 1) {
59
+ try {
60
+ // eslint-disable-next-line no-await-in-loop
61
+ const getDataContractHistoryResponse = await grpcTransport.request(
62
+ PlatformPromiseClient,
63
+ 'getDataContractHistory',
64
+ getDataContractHistoryRequest,
65
+ options,
66
+ );
67
+
68
+ return GetDataContractHistoryResponse.createFromProto(getDataContractHistoryResponse);
69
+ } catch (e) {
70
+ if (e instanceof InvalidResponseError) {
71
+ lastError = e;
72
+ } else {
73
+ throw e;
74
+ }
75
+ }
76
+ }
77
+
78
+ // If we made it past the cycle it means that the retry didn't work,
79
+ // and we're throwing the last error encountered
80
+ throw lastError;
81
+ }
82
+
83
+ return getDataContractHistory;
84
+ }
85
+
86
+ module.exports = getDataContractHistoryFactory;
@@ -26,8 +26,11 @@ class GetDocumentsResponse extends AbstractResponse {
26
26
  static createFromProto(proto) {
27
27
  const { metadata, proof } = AbstractResponse.createMetadataAndProofFromProto(proto);
28
28
 
29
+ const documents = proto.getV0().getDocuments();
30
+
29
31
  return new GetDocumentsResponse(
30
- proto.getDocumentsList().map((document) => Buffer.from(document)),
32
+ documents !== undefined
33
+ ? documents.getDocumentsList().map((document) => Buffer.from(document)) : [],
31
34
  metadata,
32
35
  proof,
33
36
  );
@@ -43,6 +43,7 @@ function getDocumentsFactory(grpcTransport) {
43
43
  orderBySerialized = cbor.encode(orderBy);
44
44
  }
45
45
 
46
+ const { GetDocumentsRequestV0 } = GetDocumentsRequest;
46
47
  const getDocumentsRequest = new GetDocumentsRequest();
47
48
  // need to convert Identifier to pure buffer as google protobuf doesn't support extended buffers
48
49
  // https://github.com/protocolbuffers/protobuf/blob/master/js/binary/utils.js#L1049
@@ -55,14 +56,17 @@ function getDocumentsFactory(grpcTransport) {
55
56
  contractId = Buffer.from(contractId);
56
57
  }
57
58
 
58
- getDocumentsRequest.setDataContractId(contractId);
59
- getDocumentsRequest.setDocumentType(type);
60
- getDocumentsRequest.setWhere(whereSerialized);
61
- getDocumentsRequest.setOrderBy(orderBySerialized);
62
- getDocumentsRequest.setLimit(limit);
63
- getDocumentsRequest.setStartAfter(startAfter);
64
- getDocumentsRequest.setStartAt(startAt);
65
- getDocumentsRequest.setProve(!!options.prove);
59
+ getDocumentsRequest.setV0(
60
+ new GetDocumentsRequestV0()
61
+ .setDataContractId(contractId)
62
+ .setDocumentType(type)
63
+ .setWhere(whereSerialized)
64
+ .setOrderBy(orderBySerialized)
65
+ .setLimit(limit)
66
+ .setStartAfter(startAfter)
67
+ .setStartAt(startAt)
68
+ .setProve(!!options.prove),
69
+ );
66
70
 
67
71
  let lastError;
68
72
 
@@ -0,0 +1,54 @@
1
+ class EpochInfo {
2
+ /**
3
+ *
4
+ * @param {number} number
5
+ * @param {number} firstBlockHeight
6
+ * @param {number} firstCoreBlockHeight
7
+ * @param {number} startTime
8
+ * @param {number} feeMultiplier
9
+ */
10
+ constructor(number, firstBlockHeight, firstCoreBlockHeight, startTime, feeMultiplier) {
11
+ this.number = number;
12
+ this.firstBlockHeight = firstBlockHeight;
13
+ this.firstCoreBlockHeight = firstCoreBlockHeight;
14
+ this.startTime = startTime;
15
+ this.feeMultiplier = feeMultiplier;
16
+ }
17
+
18
+ /**
19
+ * @returns {number}
20
+ */
21
+ getNumber() {
22
+ return this.number;
23
+ }
24
+
25
+ /**
26
+ * @returns {number}
27
+ */
28
+ getFirstBlockHeight() {
29
+ return this.firstBlockHeight;
30
+ }
31
+
32
+ /**
33
+ * @returns {number}
34
+ */
35
+ getFirstCoreBlockHeight() {
36
+ return this.firstCoreBlockHeight;
37
+ }
38
+
39
+ /**
40
+ * @returns {number}
41
+ */
42
+ getStartTime() {
43
+ return this.startTime;
44
+ }
45
+
46
+ /**
47
+ * @returns {number}
48
+ */
49
+ getFeeMultiplier() {
50
+ return this.feeMultiplier;
51
+ }
52
+ }
53
+
54
+ module.exports = EpochInfo;
@@ -0,0 +1,59 @@
1
+ const AbstractResponse = require('../response/AbstractResponse');
2
+ const EpochInfo = require('./EpochInfo');
3
+ const InvalidResponseError = require('../response/errors/InvalidResponseError');
4
+
5
+ class GetEpochsInfoResponse extends AbstractResponse {
6
+ /**
7
+ * @param {EpochInfo[]} epochsInfo
8
+ * @param {Metadata} metadata
9
+ * @param {Proof} [proof]
10
+ */
11
+ constructor(epochsInfo, metadata, proof = undefined) {
12
+ super(metadata, proof);
13
+
14
+ this.epochsInfo = epochsInfo;
15
+ }
16
+
17
+ /**
18
+ * @returns {EpochInfo[]}
19
+ */
20
+ getEpochsInfo() {
21
+ return this.epochsInfo;
22
+ }
23
+
24
+ /**
25
+ * @param proto
26
+ * @returns {GetEpochsInfoResponse}
27
+ */
28
+ static createFromProto(proto) {
29
+ const epochs = proto.getV0().getEpochs();
30
+ const { metadata, proof } = AbstractResponse.createMetadataAndProofFromProto(
31
+ proto,
32
+ );
33
+
34
+ if (!epochs && !proof) {
35
+ throw new InvalidResponseError('Epochs are not defined');
36
+ }
37
+
38
+ let epochsInfo = [];
39
+
40
+ const epochsInfoList = epochs && epochs.getEpochInfosList();
41
+ if (epochsInfoList) {
42
+ epochsInfo = epochsInfoList.map((epoch) => new EpochInfo(
43
+ epoch.getNumber(),
44
+ epoch.getFirstBlockHeight(),
45
+ epoch.getFirstCoreBlockHeight(),
46
+ epoch.getStartTime(),
47
+ epoch.getFeeMultiplier(),
48
+ ));
49
+ }
50
+
51
+ return new GetEpochsInfoResponse(
52
+ epochsInfo,
53
+ metadata,
54
+ proof,
55
+ );
56
+ }
57
+ }
58
+
59
+ module.exports = GetEpochsInfoResponse;
@@ -0,0 +1,69 @@
1
+ const {
2
+ v0: {
3
+ PlatformPromiseClient,
4
+ GetEpochsInfoRequest,
5
+ },
6
+ } = require('@dashevo/dapi-grpc');
7
+
8
+ const { UInt32Value } = require('google-protobuf/google/protobuf/wrappers_pb');
9
+
10
+ const GetEpochsInfoResponse = require('./GetEpochsInfoResponse');
11
+ const InvalidResponseError = require('../response/errors/InvalidResponseError');
12
+
13
+ /**
14
+ * @param {GrpcTransport} grpcTransport
15
+ * @returns {getEpochsInfo}
16
+ */
17
+ function getEpochsInfoFactory(grpcTransport) {
18
+ /**
19
+ * Fetch the epoch info
20
+ *
21
+ * @typedef {getEpochsInfo}
22
+ * @param {number} startEpoch
23
+ * @param {number} count
24
+ * @param {DAPIClientOptions & {prove: boolean, ascending: boolean}} [options]
25
+ * @returns {Promise<GetEpochsInfoResponse>}
26
+ */
27
+ async function getEpochsInfo(startEpoch, count, options = {}) {
28
+ const { GetEpochsInfoRequestV0 } = GetEpochsInfoRequest;
29
+ const getEpochInfosRequest = new GetEpochsInfoRequest();
30
+ getEpochInfosRequest.setV0(
31
+ new GetEpochsInfoRequestV0()
32
+ .setStartEpoch(new UInt32Value([startEpoch]))
33
+ .setCount(count)
34
+ .setAscending(!!options.ascending)
35
+ .setProve(!!options.prove),
36
+ );
37
+
38
+ let lastError;
39
+
40
+ // TODO: simple retry before the dapi versioning is properly implemented
41
+ for (let i = 0; i < 3; i += 1) {
42
+ try {
43
+ // eslint-disable-next-line no-await-in-loop
44
+ const getEpochsInfoResponse = await grpcTransport.request(
45
+ PlatformPromiseClient,
46
+ 'getEpochsInfo',
47
+ getEpochInfosRequest,
48
+ options,
49
+ );
50
+
51
+ return GetEpochsInfoResponse.createFromProto(getEpochsInfoResponse);
52
+ } catch (e) {
53
+ if (e instanceof InvalidResponseError) {
54
+ lastError = e;
55
+ } else {
56
+ throw e;
57
+ }
58
+ }
59
+ }
60
+
61
+ // If we made it past the cycle it means that the retry didn't work,
62
+ // and we're throwing the last error encountered
63
+ throw lastError;
64
+ }
65
+
66
+ return getEpochsInfo;
67
+ }
68
+
69
+ module.exports = getEpochsInfoFactory;
@@ -26,8 +26,17 @@ class GetIdentitiesByPublicKeyHashesResponse extends AbstractResponse {
26
26
  static createFromProto(proto) {
27
27
  const { metadata, proof } = AbstractResponse.createMetadataAndProofFromProto(proto);
28
28
 
29
+ const identitiesList = proto.getV0().getIdentities();
30
+
29
31
  return new GetIdentitiesByPublicKeyHashesResponse(
30
- proto.getIdentitiesList_asU8().map((identity) => Buffer.from(identity)),
32
+ identitiesList !== undefined
33
+ ? identitiesList.getIdentityEntriesList()
34
+ .map((identity) => {
35
+ const value = identity.getValue();
36
+ // TODO: rework to return whole `identity.getValue()` instead of inner getValue()
37
+ return value && Buffer.from(value.getValue());
38
+ })
39
+ : [],
31
40
  metadata,
32
41
  proof,
33
42
  );