@dashevo/dapi-client 1.0.0-pr.1825.9 → 1.0.0-pr.1883.1
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.
- package/docs/_sidebar.md +3 -1
- package/docs/usage/application/core/getBestBlockHeight.md +10 -0
- package/docs/usage/application/core/subscribeToBlockHeadersWithChainLocks.md +39 -0
- package/docs/usage/application/core/subscribeToMasternodeList.md +24 -0
- package/docs/usage/{utils → application/core}/subscribeToTransactionsWithProofs.md +13 -10
- package/lib/BlockHeadersProvider/createBlockHeadersProviderFromOptions.js +4 -2
- package/lib/DAPIClient.js +19 -1
- package/lib/SimplifiedMasternodeListProvider/SimplifiedMasternodeListProvider.js +174 -65
- package/lib/SimplifiedMasternodeListProvider/createMasternodeListStreamFactory.js +49 -0
- package/lib/dapiAddressProvider/createDAPIAddressProviderFromOptions.js +4 -9
- package/lib/methods/core/CoreMethodsFacade.js +6 -4
- package/lib/methods/core/getBestBlockHeightFactory.js +34 -0
- package/lib/methods/core/subscribeToMasternodeListFactory.js +46 -0
- package/lib/methods/core/subscribeToTransactionsWithProofsFactory.js +1 -1
- package/lib/methods/platform/PlatformMethodsFacade.js +4 -2
- package/lib/methods/platform/getIdentitiesContractKeys/GetIdentitiesContractKeysResponse.js +65 -0
- package/lib/methods/platform/getIdentitiesContractKeys/getIdentitiesContractKeysFactory.js +93 -0
- package/lib/methods/platform/getIdentityByPublicKeyHash/GetIdentityByPublicKeyHashResponse.js +40 -0
- package/lib/methods/platform/getIdentityByPublicKeyHash/getIdentityByPublicKeyHashFactory.js +64 -0
- package/lib/transport/GrpcTransport/GrpcTransport.js +7 -1
- package/lib/transport/ReconnectableStream.js +48 -6
- package/package.json +7 -7
- package/docs/usage/application/core/generateToAddress.md +0 -13
- package/docs/usage/application/core/getMnListDiff.md +0 -12
- package/lib/methods/core/generateToAddressFactory.js +0 -25
- package/lib/methods/core/getMnListDiffFactory.js +0 -21
- package/lib/methods/platform/getIdentitiesByPublicKeyHashes/GetIdentitiesByPublicKeyHashesResponse.js +0 -46
- package/lib/methods/platform/getIdentitiesByPublicKeyHashes/getIdentitiesByPublicKeyHashesFactory.js +0 -65
package/docs/_sidebar.md
CHANGED
|
@@ -7,13 +7,15 @@
|
|
|
7
7
|
- [.broadcastTransaction()](usage/application/core/broadcastTransaction.md)
|
|
8
8
|
- [.generateToAddress()](usage/application/core/generateToAddress.md)
|
|
9
9
|
- [.getBestBlockHash()](usage/application/core/getBestBlockHash.md)
|
|
10
|
+
- [.getBestBlockHeight()](usage/application/core/getBestBlockHeight.md)
|
|
10
11
|
- [.getBlockByHash()](usage/application/core/getBlockByHash.md)
|
|
11
12
|
- [.getBlockByHeight()](usage/application/core/getBlockByHeight.md)
|
|
12
13
|
- [.getBlockHash()](usage/application/core/getBlockHash.md)
|
|
13
|
-
- [.getMnListDiff()](usage/application/core/getMnListDiff.md)
|
|
14
14
|
- [.getStatus()](usage/application/core/getStatus.md)
|
|
15
15
|
- [.getTransaction()](usage/application/core/getTransaction.md)
|
|
16
16
|
- [.subscribeToTransactionsWithProofs()](usage/application/core/subscribeToTransactionsWithProofs.md)
|
|
17
|
+
- [.subscribeToBlockHeadersWithChainLocks()](usage/application/core/subscribeToBlockHeadersWithChainLocks.md)
|
|
18
|
+
- [.subscribeToMasternodeList()](usage/application/core/subscribeToMasternodeList.md)
|
|
17
19
|
- Platform
|
|
18
20
|
- [.broadcastStateTransition()](usage/application/platform/broadcastStateTransition.md)
|
|
19
21
|
- [.getDataContract()](usage/application/platform/getDataContract.md)
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
**Usage**: `await client.core.getBestBlockHeight(options)`
|
|
2
|
+
**Description**: Allow to fetch the best (highest/latest block height) from the network
|
|
3
|
+
|
|
4
|
+
Parameters:
|
|
5
|
+
|
|
6
|
+
| parameters | type | required | Description |
|
|
7
|
+
|---------------------------|---------------------|----------------| ------------------------------------------------------------------------------------------------ |
|
|
8
|
+
| **options** | DAPIClientOptions | no | |
|
|
9
|
+
|
|
10
|
+
Returns : {Promise<string>} - The best block height
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
**Usage**: `await client.core.subscribeToBlockHeadersWithChainLocks(options = { count: 0 })`\
|
|
2
|
+
**Description**: Returns a ClientReadableStream streaming of block headers and chainlocks.
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
Parameters:
|
|
6
|
+
|
|
7
|
+
| parameters | type | required | Description |
|
|
8
|
+
|----------------------------|------------------|----------------| ------------------------------------------------------------------------------------------------ |
|
|
9
|
+
| **options.fromBlockHash** | String | yes | Specifies block hash to start syncing from |
|
|
10
|
+
| **options.fromBlockHeight**| Number | yes | Specifies block height to start syncing from |
|
|
11
|
+
| **options.count** | Number | no (default: 0)| Number of blocks to sync, if set to 0 syncing is continuously sends new data as well |
|
|
12
|
+
|
|
13
|
+
Returns : Promise<EventEmitter>|!grpc.web.ClientReadableStream<!BlockHeadersWithChainLocksResponse>
|
|
14
|
+
|
|
15
|
+
Example :
|
|
16
|
+
|
|
17
|
+
```js
|
|
18
|
+
const { BlockHeader, ChainLock } = require('@dashevo/dashcore-lib');
|
|
19
|
+
|
|
20
|
+
const stream = await client.subscribeToBlockHeadersWithChainLocks({ fromBlockHeight: 0 });
|
|
21
|
+
|
|
22
|
+
stream
|
|
23
|
+
.on('data', (response) => {
|
|
24
|
+
const rawHeaders = response.getBlockHeaders();
|
|
25
|
+
const rawChainLock = response.getChainLock();
|
|
26
|
+
|
|
27
|
+
if (headers.length > 0) {
|
|
28
|
+
const headers = rawHeaders.map((rawHeader) => new BlockHeader(rawHeader));
|
|
29
|
+
console.dir(headers);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
if (rawChainLock) {
|
|
33
|
+
const chainLock = new ChainLock(rawChainLock);
|
|
34
|
+
}
|
|
35
|
+
})
|
|
36
|
+
.on('error', (err) => {
|
|
37
|
+
// do something with err
|
|
38
|
+
});
|
|
39
|
+
```
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
**Usage**: `await client.core.subscribeToMasternodeList(options = {})`\
|
|
2
|
+
**Description**: Returns a ClientReadableStream streaming of masternode list diffs ([DIP-4](https://github.com/dashpay/dips/blob/master/dip-0004.md)). As a first message it returns a diff from the first block to the current tip and a diff for each new chainlocked block.
|
|
3
|
+
|
|
4
|
+
Returns : Promise<EventEmitter>|!grpc.web.ClientReadableStream<!MasternodeListResponse>
|
|
5
|
+
|
|
6
|
+
Example :
|
|
7
|
+
|
|
8
|
+
```js
|
|
9
|
+
const { SimplifiedMNList, SimplifiedMNListDiff } = require('@dashevo/dashcore-lib');
|
|
10
|
+
|
|
11
|
+
const stream = await client.subscribeToMasternodeList();
|
|
12
|
+
|
|
13
|
+
const list = new SimplifiedMNList();
|
|
14
|
+
|
|
15
|
+
stream
|
|
16
|
+
.on('data', (response) => {
|
|
17
|
+
const diffBuffer = Buffer.from(response.getMasternodeListDiff_asU8());
|
|
18
|
+
const diff = new SimplifiedMNListDiff(diffBuffer);
|
|
19
|
+
list.applyDiff(diff);
|
|
20
|
+
})
|
|
21
|
+
.on('error', (err) => {
|
|
22
|
+
// do something with err
|
|
23
|
+
});
|
|
24
|
+
```
|
|
@@ -19,24 +19,27 @@ Returns : Promise<EventEmitter>|!grpc.web.ClientReadableStream<!TransactionsWith
|
|
|
19
19
|
Example :
|
|
20
20
|
|
|
21
21
|
```js
|
|
22
|
-
const
|
|
22
|
+
const { BloomFilter, Transaction, MerkleBlock } = require('@dashevo/dashcore-lib');
|
|
23
|
+
|
|
24
|
+
const filter = BloomFilter.create(1, 0.001); // A BloomFilter object
|
|
23
25
|
const stream = await client.subscribeToTransactionsWithProofs(filter, { fromBlockHeight: 0 });
|
|
24
26
|
|
|
25
27
|
stream
|
|
26
28
|
.on('data', (response) => {
|
|
27
|
-
const
|
|
28
|
-
const
|
|
29
|
+
const rawMerkleBlock = response.getRawMerkleBlock();
|
|
30
|
+
const rawTransactions = response.getRawTransactions();
|
|
29
31
|
|
|
30
32
|
if (merkleBlock) {
|
|
31
|
-
const
|
|
33
|
+
const merkleBlock = new MerkleBlock(rawMerkleBlock);
|
|
34
|
+
console.dir(merkleBlock);
|
|
32
35
|
}
|
|
33
36
|
|
|
34
|
-
if (transactions) {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
37
|
+
if (transactions.length > 0) {
|
|
38
|
+
// tx are probabilistic, so you will have to verify it's yours
|
|
39
|
+
const transactions = transactions.getTransactionsList()
|
|
40
|
+
.map((tx) => new Transaction(Buffer.from(tx)));
|
|
41
|
+
|
|
42
|
+
console.dir(transactions);
|
|
40
43
|
}
|
|
41
44
|
})
|
|
42
45
|
.on('error', (err) => {
|
|
@@ -19,14 +19,15 @@ const validateNumber = (value, name, min = NaN, max = NaN) => {
|
|
|
19
19
|
/**
|
|
20
20
|
* @typedef {createBlockHeadersProviderFromOptions}
|
|
21
21
|
* @param {DAPIClientOptions} options
|
|
22
|
+
* @param logger
|
|
22
23
|
* @param {CoreMethodsFacade} coreMethods
|
|
23
24
|
* @returns {BlockHeadersProvider}
|
|
24
25
|
*/
|
|
25
|
-
function createBlockHeadersProviderFromOptions(options, coreMethods) {
|
|
26
|
+
function createBlockHeadersProviderFromOptions(options, coreMethods, logger) {
|
|
26
27
|
let blockHeadersProvider;
|
|
27
28
|
if (options.blockHeadersProvider) {
|
|
28
29
|
if (options.blockHeadersProviderOptions) {
|
|
29
|
-
throw new DAPIClientError(
|
|
30
|
+
throw new DAPIClientError('Can\'t use \'blockHeadersProviderOptions\' with \'blockHeadersProvider\' option');
|
|
30
31
|
}
|
|
31
32
|
|
|
32
33
|
blockHeadersProvider = options.blockHeadersProvider;
|
|
@@ -37,6 +38,7 @@ function createBlockHeadersProviderFromOptions(options, coreMethods) {
|
|
|
37
38
|
coreMethods.subscribeToBlockHeadersWithChainLocks,
|
|
38
39
|
{
|
|
39
40
|
maxRetriesOnError: -1,
|
|
41
|
+
logger,
|
|
40
42
|
},
|
|
41
43
|
)({
|
|
42
44
|
fromBlockHeight,
|
package/lib/DAPIClient.js
CHANGED
|
@@ -70,12 +70,30 @@ class DAPIClient extends EventEmitter {
|
|
|
70
70
|
* @private
|
|
71
71
|
*/
|
|
72
72
|
initBlockHeadersProvider() {
|
|
73
|
-
this.blockHeadersProvider = createBlockHeadersProviderFromOptions(
|
|
73
|
+
this.blockHeadersProvider = createBlockHeadersProviderFromOptions(
|
|
74
|
+
this.options,
|
|
75
|
+
this.core,
|
|
76
|
+
this.logger,
|
|
77
|
+
);
|
|
74
78
|
|
|
75
79
|
this.blockHeadersProvider.on(BlockHeadersProvider.EVENTS.ERROR, (e) => {
|
|
76
80
|
this.emit(EVENTS.ERROR, e);
|
|
77
81
|
});
|
|
78
82
|
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Close all open connections
|
|
86
|
+
* @returns {Promise<void>}
|
|
87
|
+
*/
|
|
88
|
+
async disconnect() {
|
|
89
|
+
// Stop block headers provider
|
|
90
|
+
await this.blockHeadersProvider.stop();
|
|
91
|
+
|
|
92
|
+
// Stop masternode list provider
|
|
93
|
+
if (this.dapiAddressProvider.smlProvider) {
|
|
94
|
+
await this.dapiAddressProvider.smlProvider.unsubscribe();
|
|
95
|
+
}
|
|
96
|
+
}
|
|
79
97
|
}
|
|
80
98
|
|
|
81
99
|
DAPIClient.EVENTS = EVENTS;
|
|
@@ -1,27 +1,33 @@
|
|
|
1
1
|
const SimplifiedMNList = require('@dashevo/dashcore-lib/lib/deterministicmnlist/SimplifiedMNList');
|
|
2
2
|
const SimplifiedMNListDiff = require('@dashevo/dashcore-lib/lib/deterministicmnlist/SimplifiedMNListDiff');
|
|
3
3
|
|
|
4
|
+
const logger = require('../logger');
|
|
5
|
+
|
|
4
6
|
class SimplifiedMasternodeListProvider {
|
|
5
7
|
/**
|
|
6
|
-
*
|
|
7
|
-
* @param {JsonRpcTransport} jsonRpcTransport - JsonRpcTransport instance
|
|
8
|
+
* @param {Function} createStream - JsonRpcTransport instance
|
|
8
9
|
* @param {object} [options] - Options
|
|
9
|
-
* @param {number} [options.updateInterval]
|
|
10
10
|
* @param {string} [options.network]
|
|
11
|
+
* @param {string} [options.loggerOptions]
|
|
11
12
|
*/
|
|
12
|
-
constructor(
|
|
13
|
-
this.
|
|
14
|
-
|
|
15
|
-
this.
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
this.simplifiedMNList = new SimplifiedMNList(undefined, this.options.network);
|
|
13
|
+
constructor(createStream, options = {}) {
|
|
14
|
+
this.createStream = createStream;
|
|
15
|
+
this.options = options;
|
|
16
|
+
this.logger = logger.getForId(
|
|
17
|
+
this.options.loggerOptions.identifier,
|
|
18
|
+
this.options.loggerOptions.level,
|
|
19
|
+
);
|
|
21
20
|
|
|
22
|
-
|
|
21
|
+
/**
|
|
22
|
+
* @type {ReconnectableStream}
|
|
23
|
+
*/
|
|
24
|
+
this.stream = undefined;
|
|
25
|
+
this.removeStreamListeners = () => {};
|
|
23
26
|
|
|
24
|
-
|
|
27
|
+
/**
|
|
28
|
+
* @type {SimplifiedMNList}
|
|
29
|
+
*/
|
|
30
|
+
this.simplifiedMNList = new SimplifiedMNList(undefined);
|
|
25
31
|
}
|
|
26
32
|
|
|
27
33
|
/**
|
|
@@ -29,75 +35,178 @@ class SimplifiedMasternodeListProvider {
|
|
|
29
35
|
* @returns {Promise<SimplifiedMNList>}
|
|
30
36
|
*/
|
|
31
37
|
async getSimplifiedMNList() {
|
|
32
|
-
if (this.
|
|
33
|
-
await this.
|
|
38
|
+
if (this.stream === undefined) {
|
|
39
|
+
await this.subscribeToMasternodeList();
|
|
34
40
|
}
|
|
35
41
|
|
|
36
42
|
return this.simplifiedMNList;
|
|
37
43
|
}
|
|
38
44
|
|
|
39
45
|
/**
|
|
40
|
-
*
|
|
46
|
+
* Subscribe to simplified masternodes list updates. No need to call it manually
|
|
41
47
|
* @private
|
|
42
|
-
* @returns {
|
|
48
|
+
* @returns {Promise<void>}
|
|
43
49
|
*/
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* Updates simplified masternodes list. No need to call it manually
|
|
50
|
-
* @private
|
|
51
|
-
*/
|
|
52
|
-
async updateMasternodeList() {
|
|
53
|
-
const diff = await this.getSimplifiedMNListDiff();
|
|
54
|
-
|
|
55
|
-
try {
|
|
56
|
-
this.simplifiedMNList.applyDiff(diff);
|
|
57
|
-
} catch (e) {
|
|
58
|
-
if (e.message === 'Cannot apply diff: previous blockHash needs to equal the new diff\'s baseBlockHash') {
|
|
59
|
-
this.reset();
|
|
60
|
-
|
|
61
|
-
await this.updateMasternodeList();
|
|
62
|
-
|
|
63
|
-
return;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
throw e;
|
|
50
|
+
async subscribeToMasternodeList() {
|
|
51
|
+
if (this.stream) {
|
|
52
|
+
this.logger.debug('Masternode list stream already started');
|
|
53
|
+
return Promise.resolve();
|
|
67
54
|
}
|
|
68
55
|
|
|
69
|
-
this.
|
|
56
|
+
this.logger.debug('Starting masternode list stream');
|
|
70
57
|
|
|
71
|
-
this.
|
|
72
|
-
}
|
|
58
|
+
this.stream = await this.createStream();
|
|
73
59
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
* @private
|
|
77
|
-
* @returns {Promise<SimplifiedMNListDiff>}
|
|
78
|
-
*/
|
|
79
|
-
async getSimplifiedMNListDiff() {
|
|
80
|
-
const blockHash = await this.jsonRpcTransport.request('getBestBlockHash');
|
|
60
|
+
let diffCount = 0;
|
|
61
|
+
let resolved = false;
|
|
81
62
|
|
|
82
|
-
const
|
|
83
|
-
'
|
|
84
|
-
{ baseBlockHash: this.baseBlockHash, blockHash },
|
|
85
|
-
{ addresses: [this.jsonRpcTransport.getLastUsedAddress()] },
|
|
86
|
-
);
|
|
63
|
+
const rejectDiff = (error) => {
|
|
64
|
+
this.logger.silly('Stream is cancelled due to error. Retrying...', { error });
|
|
87
65
|
|
|
88
|
-
|
|
66
|
+
this.stream.cancel();
|
|
67
|
+
this.stream.retryOnError(error);
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
return new Promise((resolve, reject) => {
|
|
71
|
+
const errorHandler = (error) => {
|
|
72
|
+
this.stream = null;
|
|
73
|
+
|
|
74
|
+
this.logger.error(
|
|
75
|
+
`Masternode list sync failed: ${error.message}`,
|
|
76
|
+
{ error, diffCount },
|
|
77
|
+
);
|
|
78
|
+
|
|
79
|
+
if (!resolved) {
|
|
80
|
+
reject(error);
|
|
81
|
+
resolved = true;
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
const dataHandler = (response) => {
|
|
86
|
+
diffCount += 1;
|
|
87
|
+
|
|
88
|
+
if (diffCount === 1) {
|
|
89
|
+
this.logger.silly(
|
|
90
|
+
'Full masternode list diff received',
|
|
91
|
+
{ diffCount },
|
|
92
|
+
);
|
|
93
|
+
} else {
|
|
94
|
+
this.logger.silly(
|
|
95
|
+
'Received masternode list diff',
|
|
96
|
+
{ diffCount },
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
let simplifiedMNListDiff;
|
|
101
|
+
let simplifiedMNListDiffBuffer;
|
|
102
|
+
try {
|
|
103
|
+
simplifiedMNListDiffBuffer = Buffer.from(response.getMasternodeListDiff_asU8());
|
|
104
|
+
simplifiedMNListDiff = new SimplifiedMNListDiff(
|
|
105
|
+
simplifiedMNListDiffBuffer,
|
|
106
|
+
this.options.network,
|
|
107
|
+
);
|
|
108
|
+
} catch (e) {
|
|
109
|
+
this.logger.warn(
|
|
110
|
+
`Can't parse masternode list diff: ${e.message}`,
|
|
111
|
+
{
|
|
112
|
+
diffCount,
|
|
113
|
+
network: this.options.network,
|
|
114
|
+
error: e,
|
|
115
|
+
simplifiedMNListDiff: simplifiedMNListDiffBuffer.toString('hex'),
|
|
116
|
+
},
|
|
117
|
+
);
|
|
118
|
+
|
|
119
|
+
rejectDiff(e);
|
|
120
|
+
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
this.logger.silly(
|
|
125
|
+
'Parsed masternode list diff successfully',
|
|
126
|
+
{
|
|
127
|
+
diffCount,
|
|
128
|
+
blockHash: simplifiedMNListDiff.blockHash,
|
|
129
|
+
},
|
|
130
|
+
);
|
|
131
|
+
|
|
132
|
+
try {
|
|
133
|
+
// Restart list when we receive a full diff
|
|
134
|
+
if (diffCount === 1) {
|
|
135
|
+
this.simplifiedMNList = new SimplifiedMNList(simplifiedMNListDiff);
|
|
136
|
+
} else {
|
|
137
|
+
this.simplifiedMNList.applyDiff(simplifiedMNListDiff);
|
|
138
|
+
}
|
|
139
|
+
} catch (e) {
|
|
140
|
+
this.logger.warn(
|
|
141
|
+
`Can't apply masternode list diff: ${e.message}`,
|
|
142
|
+
{
|
|
143
|
+
diffCount,
|
|
144
|
+
network: this.options.network,
|
|
145
|
+
blockHash: simplifiedMNListDiff.blockHash,
|
|
146
|
+
error: e,
|
|
147
|
+
simplifiedMNListDiff,
|
|
148
|
+
},
|
|
149
|
+
);
|
|
150
|
+
|
|
151
|
+
rejectDiff(e);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
this.logger.silly(
|
|
155
|
+
'Masternode list diff applied successfully',
|
|
156
|
+
{
|
|
157
|
+
diffCount,
|
|
158
|
+
blockHash: simplifiedMNListDiff.blockHash,
|
|
159
|
+
},
|
|
160
|
+
);
|
|
161
|
+
|
|
162
|
+
if (!resolved) {
|
|
163
|
+
resolve();
|
|
164
|
+
resolved = true;
|
|
165
|
+
}
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
const beforeReconnectHandler = () => {
|
|
169
|
+
diffCount = 0;
|
|
170
|
+
|
|
171
|
+
this.logger.debug(
|
|
172
|
+
'Restarting masternode list stream',
|
|
173
|
+
{ diffCount },
|
|
174
|
+
);
|
|
175
|
+
};
|
|
176
|
+
|
|
177
|
+
const endHandler = () => {
|
|
178
|
+
this.logger.warn(
|
|
179
|
+
'Masternode list sync stopped',
|
|
180
|
+
{ diffCount },
|
|
181
|
+
);
|
|
182
|
+
|
|
183
|
+
this.removeStreamListeners();
|
|
184
|
+
this.stream = null;
|
|
185
|
+
};
|
|
186
|
+
|
|
187
|
+
this.stream.on('data', dataHandler);
|
|
188
|
+
this.stream.on('beforeReconnect', beforeReconnectHandler);
|
|
189
|
+
this.stream.on('error', errorHandler);
|
|
190
|
+
this.stream.on('end', endHandler);
|
|
191
|
+
|
|
192
|
+
this.removeStreamListeners = () => {
|
|
193
|
+
this.stream.removeListener('data', dataHandler);
|
|
194
|
+
this.stream.removeListener('beforeReconnect', beforeReconnectHandler);
|
|
195
|
+
this.stream.removeListener('error', errorHandler);
|
|
196
|
+
this.stream.removeListener('end', endHandler);
|
|
197
|
+
};
|
|
198
|
+
});
|
|
89
199
|
}
|
|
90
200
|
|
|
91
201
|
/**
|
|
92
|
-
*
|
|
93
|
-
* @private
|
|
202
|
+
* Unsubscribe from masternode list updates
|
|
94
203
|
*/
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
204
|
+
unsubscribe() {
|
|
205
|
+
if (this.stream) {
|
|
206
|
+
this.removeStreamListeners();
|
|
207
|
+
this.stream.cancel();
|
|
208
|
+
this.stream = null;
|
|
209
|
+
}
|
|
101
210
|
}
|
|
102
211
|
}
|
|
103
212
|
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
const {
|
|
2
|
+
v0: {
|
|
3
|
+
MasternodeListRequest,
|
|
4
|
+
CorePromiseClient,
|
|
5
|
+
},
|
|
6
|
+
} = require('@dashevo/dapi-grpc');
|
|
7
|
+
|
|
8
|
+
const GrpcTransport = require('../transport/GrpcTransport/GrpcTransport');
|
|
9
|
+
const createGrpcTransportError = require('../transport/GrpcTransport/createGrpcTransportError');
|
|
10
|
+
const ReconnectableStream = require('../transport/ReconnectableStream');
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Creates continues masternode list stream
|
|
14
|
+
*
|
|
15
|
+
* @param {createDAPIAddressProviderFromOptions} createDAPIAddressProviderFromOptions
|
|
16
|
+
* @param {ListDAPIAddressProvider} listDAPIAddressProvider
|
|
17
|
+
* @param {Object} options
|
|
18
|
+
* @return {function(...[*]): Promise<ReconnectableStream>}
|
|
19
|
+
*/
|
|
20
|
+
function createMasternodeListStreamFactory(
|
|
21
|
+
createDAPIAddressProviderFromOptions,
|
|
22
|
+
listDAPIAddressProvider,
|
|
23
|
+
options,
|
|
24
|
+
) {
|
|
25
|
+
const grpcTransport = new GrpcTransport(
|
|
26
|
+
createDAPIAddressProviderFromOptions,
|
|
27
|
+
listDAPIAddressProvider,
|
|
28
|
+
createGrpcTransportError,
|
|
29
|
+
options,
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
return ReconnectableStream
|
|
33
|
+
.create(
|
|
34
|
+
() => grpcTransport.request(
|
|
35
|
+
CorePromiseClient,
|
|
36
|
+
'subscribeToMasternodeList',
|
|
37
|
+
new MasternodeListRequest(),
|
|
38
|
+
{
|
|
39
|
+
timeout: undefined,
|
|
40
|
+
autoReconnectInterval: 0,
|
|
41
|
+
},
|
|
42
|
+
),
|
|
43
|
+
{
|
|
44
|
+
maxRetriesOnError: -1,
|
|
45
|
+
},
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
module.exports = createMasternodeListStreamFactory;
|
|
@@ -6,10 +6,7 @@ const ListDAPIAddressProvider = require('./ListDAPIAddressProvider');
|
|
|
6
6
|
|
|
7
7
|
const SimplifiedMasternodeListProvider = require('../SimplifiedMasternodeListProvider/SimplifiedMasternodeListProvider');
|
|
8
8
|
const SimplifiedMasternodeListDAPIAddressProvider = require('./SimplifiedMasternodeListDAPIAddressProvider');
|
|
9
|
-
|
|
10
|
-
const JsonRpcTransport = require('../transport/JsonRpcTransport/JsonRpcTransport');
|
|
11
|
-
const requestJsonRpc = require('../transport/JsonRpcTransport/requestJsonRpc');
|
|
12
|
-
const createJsonTransportError = require('../transport/JsonRpcTransport/createJsonTransportError');
|
|
9
|
+
const createMasternodeListStreamFactory = require('../SimplifiedMasternodeListProvider/createMasternodeListStreamFactory');
|
|
13
10
|
|
|
14
11
|
const DAPIClientError = require('../errors/DAPIClientError');
|
|
15
12
|
|
|
@@ -82,17 +79,15 @@ function createDAPIAddressProviderFromOptions(options) {
|
|
|
82
79
|
options,
|
|
83
80
|
);
|
|
84
81
|
|
|
85
|
-
const
|
|
82
|
+
const createStream = createMasternodeListStreamFactory(
|
|
86
83
|
createDAPIAddressProviderFromOptions,
|
|
87
|
-
requestJsonRpc,
|
|
88
84
|
listDAPIAddressProvider,
|
|
89
|
-
createJsonTransportError,
|
|
90
85
|
options,
|
|
91
86
|
);
|
|
92
87
|
|
|
93
88
|
const smlProvider = new SimplifiedMasternodeListProvider(
|
|
94
|
-
|
|
95
|
-
|
|
89
|
+
createStream,
|
|
90
|
+
options,
|
|
96
91
|
);
|
|
97
92
|
|
|
98
93
|
return new SimplifiedMasternodeListDAPIAddressProvider(
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
const broadcastTransactionFactory = require('./broadcastTransactionFactory');
|
|
2
|
-
const generateToAddressFactory = require('./generateToAddressFactory');
|
|
3
2
|
const getBestBlockHashFactory = require('./getBestBlockHashFactory');
|
|
3
|
+
const getBestBlockHeightFactory = require('./getBestBlockHeightFactory');
|
|
4
4
|
const getBlockByHashFactory = require('./getBlockByHashFactory');
|
|
5
5
|
const getBlockByHeightFactory = require('./getBlockByHeightFactory');
|
|
6
6
|
const getBlockHashFactory = require('./getBlockHashFactory');
|
|
7
|
-
const getMnListDiffFactory = require('./getMnListDiffFactory');
|
|
8
7
|
const getBlockchainStatusFactory = require('./getBlockchainStatusFactory');
|
|
9
8
|
const getMasternodeStatusFactory = require('./getMasternodeStatusFactory');
|
|
10
9
|
const getTransactionFactory = require('./getTransaction/getTransactionFactory');
|
|
11
10
|
const subscribeToTransactionsWithProofsFactory = require('./subscribeToTransactionsWithProofsFactory');
|
|
12
11
|
const subscribeToBlockHeadersWithChainLocksFactory = require('./subscribeToBlockHeadersWithChainLocksFactory');
|
|
12
|
+
const subscribeToToMasternodeListFactory = require('./subscribeToMasternodeListFactory');
|
|
13
13
|
|
|
14
14
|
class CoreMethodsFacade {
|
|
15
15
|
/**
|
|
@@ -18,12 +18,11 @@ class CoreMethodsFacade {
|
|
|
18
18
|
*/
|
|
19
19
|
constructor(jsonRpcTransport, grpcTransport) {
|
|
20
20
|
this.broadcastTransaction = broadcastTransactionFactory(grpcTransport);
|
|
21
|
-
this.generateToAddress = generateToAddressFactory(jsonRpcTransport);
|
|
22
21
|
this.getBestBlockHash = getBestBlockHashFactory(jsonRpcTransport);
|
|
22
|
+
this.getBestBlockHeight = getBestBlockHeightFactory(grpcTransport);
|
|
23
23
|
this.getBlockByHash = getBlockByHashFactory(grpcTransport);
|
|
24
24
|
this.getBlockByHeight = getBlockByHeightFactory(grpcTransport);
|
|
25
25
|
this.getBlockHash = getBlockHashFactory(jsonRpcTransport);
|
|
26
|
-
this.getMnListDiff = getMnListDiffFactory(jsonRpcTransport);
|
|
27
26
|
this.getBlockchainStatus = getBlockchainStatusFactory(grpcTransport);
|
|
28
27
|
this.getMasternodeStatus = getMasternodeStatusFactory(grpcTransport);
|
|
29
28
|
this.getTransaction = getTransactionFactory(grpcTransport);
|
|
@@ -33,6 +32,9 @@ class CoreMethodsFacade {
|
|
|
33
32
|
this.subscribeToBlockHeadersWithChainLocks = subscribeToBlockHeadersWithChainLocksFactory(
|
|
34
33
|
grpcTransport,
|
|
35
34
|
);
|
|
35
|
+
this.subscribeToMasternodeList = subscribeToToMasternodeListFactory(
|
|
36
|
+
grpcTransport,
|
|
37
|
+
);
|
|
36
38
|
}
|
|
37
39
|
}
|
|
38
40
|
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
const {
|
|
2
|
+
v0: {
|
|
3
|
+
GetBestBlockHeightRequest,
|
|
4
|
+
CorePromiseClient,
|
|
5
|
+
},
|
|
6
|
+
} = require('@dashevo/dapi-grpc');
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
*
|
|
10
|
+
* @param {GrpcTransport} grpcTransport
|
|
11
|
+
* @returns {getBestBlockHeight}
|
|
12
|
+
*/
|
|
13
|
+
function getBestBlockHeightFactory(grpcTransport) {
|
|
14
|
+
/**
|
|
15
|
+
* Returns block height of chain tip
|
|
16
|
+
* @typedef {getBestBlockHeight}
|
|
17
|
+
* @param {DAPIClientOptions} [options]
|
|
18
|
+
* @returns {Promise<string>}
|
|
19
|
+
*/
|
|
20
|
+
async function getBestBlockHeight(options = {}) {
|
|
21
|
+
const response = await grpcTransport.request(
|
|
22
|
+
CorePromiseClient,
|
|
23
|
+
'getBestBlockHeight',
|
|
24
|
+
new GetBestBlockHeightRequest(),
|
|
25
|
+
options,
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
return response.getHeight();
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
return getBestBlockHeight;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
module.exports = getBestBlockHeightFactory;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
const {
|
|
2
|
+
v0: {
|
|
3
|
+
MasternodeListRequest,
|
|
4
|
+
CorePromiseClient,
|
|
5
|
+
},
|
|
6
|
+
} = require('@dashevo/dapi-grpc');
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @param {GrpcTransport} grpcTransport
|
|
10
|
+
* @returns {subscribeToMasternodeList}
|
|
11
|
+
*/
|
|
12
|
+
function subscribeToMasternodeListFactory(grpcTransport) {
|
|
13
|
+
/**
|
|
14
|
+
* @typedef {subscribeToMasternodeList}
|
|
15
|
+
* @param {DAPIClientOptions & subscribeToMasternodeListOptions} [options]
|
|
16
|
+
* @returns {
|
|
17
|
+
* EventEmitter|!grpc.web.ClientReadableStream<!MasternodeListResponse>
|
|
18
|
+
* }
|
|
19
|
+
*/
|
|
20
|
+
async function subscribeToMasternodeList(options = { }) {
|
|
21
|
+
// eslint-disable-next-line no-param-reassign
|
|
22
|
+
options = {
|
|
23
|
+
// Override global timeout option
|
|
24
|
+
// and timeout for this method by default
|
|
25
|
+
timeout: undefined,
|
|
26
|
+
...options,
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const request = new MasternodeListRequest();
|
|
30
|
+
|
|
31
|
+
return grpcTransport.request(
|
|
32
|
+
CorePromiseClient,
|
|
33
|
+
'subscribeToMasternodeList',
|
|
34
|
+
request,
|
|
35
|
+
options,
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return subscribeToMasternodeList;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* @typedef {object} subscribeToMasternodeListOptions
|
|
44
|
+
*/
|
|
45
|
+
|
|
46
|
+
module.exports = subscribeToMasternodeListFactory;
|