From 9fd8fa050019f827d2fcc912d74f80c415f3145c Mon Sep 17 00:00:00 2001 From: Nodari Chkuaselidze Date: Mon, 18 Dec 2023 18:30:34 +0400 Subject: [PATCH 1/3] node-client: Add methods for the HTTP endpoints. Add getMempoolRejectionFilter and checkMempoolRejectionFilter methods to client. Add getFee, alternative to websocket estimateFee call. --- CHANGELOG.md | 3 +++ lib/client/node.js | 31 +++++++++++++++++++++++++++++++ test/node-http-test.js | 18 ++++++++++-------- 3 files changed, 44 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3aca6676d..ea54c913c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -38,6 +38,9 @@ process and allows parallel rescans. - expects ws hook for `block rescan interactive` params `rawEntry, rawTXs` that returns scanAction object. - expects ws hook for `block rescan interactive abort` param `message`. + - Add `getMempoolRejectionFilter` and `checkMempoolRejectionFilter` NodeClient + aliases. + - Add `getFee`, an HTTP alternative to estimateFee socket call. ### Wallet Changes #### Configuration diff --git a/lib/client/node.js b/lib/client/node.js index 4bf1ae02d..631eb3d02 100644 --- a/lib/client/node.js +++ b/lib/client/node.js @@ -57,6 +57,26 @@ class NodeClient extends Client { return this.get('/mempool'); } + /** + * Get a mempool rejection filter. + * @param {Object} options + * @returns {Promise} + */ + + getMempoolRejectionFilter(options) { + return this.get('/mempool/invalid', options); + } + + /** + * Check against mempool rejection filter. + * @param {Hash} hash - transaction hash + * @returns {Promise} + */ + + checkMempoolRejectionFilter(hash) { + return this.get(`/mempool/invalid/${hash}`); + } + /** * Get some info about the server (network and version). * @returns {Promise} @@ -183,6 +203,17 @@ class NodeClient extends Client { return this.post('/claim', { claim }); } + /** + * Estimate smart fee. Same as estimateFee, but + * an HTTP call instead of websocket call. + * @param {Number} blocks + * @returns {Promise} + */ + + getSmartFee(blocks) { + return this.get('/fee', { blocks }); + } + /** * Reset the chain. * @param {Number} height diff --git a/test/node-http-test.js b/test/node-http-test.js index a27679186..0bf8c16b5 100644 --- a/test/node-http-test.js +++ b/test/node-http-test.js @@ -39,7 +39,9 @@ describe('Node HTTP', function() { }); it('should get mempool rejection filter', async () => { - const filterInfo = await nclient.get('/mempool/invalid', { verbose: true }); + const filterInfo = await nclient.getMempoolRejectionFilter({ + verbose: true + }); assert.ok('items' in filterInfo); assert.ok('filter' in filterInfo); @@ -59,10 +61,10 @@ describe('Node HTTP', function() { const raw = mtx.toHex(); const txid = await nclient.execute('sendrawtransaction', [raw]); - const json = await nclient.get(`/mempool/invalid/${txid}`); + const json = await nclient.checkMempoolRejectionFilter(txid); assert.equal(json.invalid, true); - const filterInfo = await nclient.get('/mempool/invalid'); + const filterInfo = await nclient.getMempoolRejectionFilter(); assert.equal(filterInfo.entries, 1); }); }); @@ -90,7 +92,7 @@ describe('Node HTTP', function() { // fetch corresponding header and block const height = 7; - const header = await nclient.get(`/header/${height}`); + const header = await nclient.getBlockHeader(height); assert.equal(header.height, height); const properties = [ @@ -116,7 +118,7 @@ describe('Node HTTP', function() { it('should fetch null for block header that does not exist', async () => { // many blocks in the future - const header = await nclient.get(`/header/${40000}`); + const header = await nclient.getBlockHeader(40000); assert.equal(header, null); }); @@ -130,7 +132,7 @@ describe('Node HTTP', function() { let prevBlock = '0000000000000000000000000000000000000000000000000000000000000000'; for (let i = 0; i < 10; i++) { - const header = await nclient.get(`/header/${i}`); + const header = await nclient.getBlockHeader(i); assert.equal(prevBlock, header.prevBlock); prevBlock = header.hash; @@ -140,8 +142,8 @@ describe('Node HTTP', function() { it('should fetch block header by hash', async () => { const info = await nclient.getInfo(); - const headerByHash = await nclient.get(`/header/${info.chain.tip}`); - const headerByHeight = await nclient.get(`/header/${info.chain.height}`); + const headerByHash = await nclient.getBlockHeader(info.chain.tip); + const headerByHeight = await nclient.getBlockHeader(info.chain.height); assert.deepEqual(headerByHash, headerByHeight); }); From a3602b0572ecc0b64e5bef8195f75cfe9a1093d4 Mon Sep 17 00:00:00 2001 From: Nodari Chkuaselidze Date: Mon, 18 Dec 2023 21:06:24 +0400 Subject: [PATCH 2/3] pkg: update lint rules to the latest. --- .eslintrc.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.eslintrc.json b/.eslintrc.json index 45ef023b9..d5d0f1ef7 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,6 +1,6 @@ { "env": { - "es2022": true, + "es2024": true, "node": true }, "extends": "eslint:recommended", @@ -35,7 +35,7 @@ } ], "parserOptions": { - "ecmaVersion": 13, + "ecmaVersion": "latest", "ecmaFeatures": { "globalReturn": true }, From 501f529504c79f240be7fe96acf87bb0ccc56d52 Mon Sep 17 00:00:00 2001 From: Nodari Chkuaselidze Date: Mon, 18 Dec 2023 21:25:49 +0400 Subject: [PATCH 3/3] wallet-client: add options to the getNames. --- CHANGELOG.md | 4 +++- lib/client/wallet.js | 27 +++++++++++++++++++++++---- test/util/node-context.js | 9 +++++++++ test/wallet-http-test.js | 4 +--- 4 files changed, 36 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ea54c913c..96a52e3b1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -61,11 +61,13 @@ process and allows parallel rescans. - `open()` no longer calls scan, instead only rollbacks and waits for sync to do the rescan. - emits events for: `open`, `close`, `connect`, `disconnect`, `sync done`. -- HTTP Changes: + +### Wallet HTTP Client - All transaction creating endpoints now accept `hardFee` for specifying the exact fee. - All transaction sending endpoints now fundlock/queue tx creation. (no more conflicting transactions) + - Add options to `getNames` for passing `own`. ## v6.0.0 diff --git a/lib/client/wallet.js b/lib/client/wallet.js index 3ae11d8e4..1a027ce45 100644 --- a/lib/client/wallet.js +++ b/lib/client/wallet.js @@ -118,6 +118,9 @@ class WalletClient extends Client { /** * Create a wallet object. + * @param {String} id + * @param {String} [token] + * @returns {Wallet} */ wallet(id, token) { @@ -339,11 +342,13 @@ class WalletClient extends Client { * that the wallet is managing. * {@see hsd.NameState} * @param {String} id + * @param {Object} options + * @param {Boolean} [optoins.own=false] * @returns {Promise} */ - getNames(id) { - return this.get(`/wallet/${id}/name`); + getNames(id, options) { + return this.get(`/wallet/${id}/name`, options); } /** @@ -893,6 +898,18 @@ class WalletClient extends Client { */ class Wallet extends EventEmitter { + /** @type {WalletClient} */ + client; + + /** @type {WalletClient} */ + parent; + + /** @type {String} */ + id; + + /** @type {String} */ + token; + /** * Create a wallet client. * @param {Object?} options @@ -1051,11 +1068,13 @@ class Wallet extends EventEmitter { * Get name state for all names * that the wallet is managing. * {@see hsd.NameState} + * @param {Object} options + * @param {Boolean} [optoins.own=false] * @returns {Promise} */ - getNames() { - return this.client.getNames(this.id); + getNames(options) { + return this.client.getNames(this.id, options); } /** diff --git a/test/util/node-context.js b/test/util/node-context.js index fce35076c..c0a49db1c 100644 --- a/test/util/node-context.js +++ b/test/util/node-context.js @@ -11,6 +11,15 @@ const {NodeClient, WalletClient} = require('../../lib/client'); const Logger = require('blgr'); class NodeContext { + /** @type {FullNode|SPVNode} */ + node; + + /** @type {WalletClient} */ + wclient; + + /** @type {NodeClient} */ + nclient; + constructor(options = {}) { this.name = 'node-test'; this.options = {}; diff --git a/test/wallet-http-test.js b/test/wallet-http-test.js index 6f1dd4d92..ea0a3d266 100644 --- a/test/wallet-http-test.js +++ b/test/wallet-http-test.js @@ -1787,9 +1787,7 @@ describe('Wallet HTTP', function() { }); it('should only get wallet-owned names', async () => { - // TODO: convert to using hs-client method - // when wallet.getNames() allows `options` - const names = await wallet.client.get(`/wallet/${wallet.id}/name`, {own: true}); + const names = await wallet.getNames({ own: true }); assert.equal(names.length, ownedNames.length);