diff --git a/apps/mock-chronik-client/README.md b/apps/mock-chronik-client/README.md --- a/apps/mock-chronik-client/README.md +++ b/apps/mock-chronik-client/README.md @@ -103,3 +103,7 @@ 1.2.0 - Add support to calls by `address(address)` returning same as `script(type, hash)` + +1.3.0 + +- Add support for `subscribeToAddress` and `unsubscribeFromAddress` websocket methods diff --git a/apps/mock-chronik-client/index.js b/apps/mock-chronik-client/index.js --- a/apps/mock-chronik-client/index.js +++ b/apps/mock-chronik-client/index.js @@ -2,6 +2,7 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. 'use strict'; +const cashaddr = require('ecashaddrjs'); module.exports = { MockChronikClient: class { @@ -90,6 +91,38 @@ }); self.wsSubscribeCalled = true; }, + subscribeToAddress: function (address) { + const { type, hash } = cashaddr.decode( + address, + true, + ); + this.subs.push({ + scriptType: type, + scriptPayload: hash, + }); + }, + unsubscribeFromAddress: function (address) { + const { type, hash } = cashaddr.decode( + address, + true, + ); + // Find the requested unsub script and remove it + const unsubIndex = this.subs.findIndex( + sub => + sub.scriptType === type && + sub.scriptPayload === hash, + ); + if (unsubIndex === -1) { + // If we cannot find this subscription in this.subs, throw an error + // We do not want an app developer thinking they have unsubscribed from something + throw new Error( + `No existing sub at ${type}, ${hash}`, + ); + } + + // Remove the requested subscription from this.subs + this.subs.splice(unsubIndex, 1); + }, subscribeToBlocks: function () { this.isSubscribedBlocks = true; }, diff --git a/apps/mock-chronik-client/package-lock.json b/apps/mock-chronik-client/package-lock.json --- a/apps/mock-chronik-client/package-lock.json +++ b/apps/mock-chronik-client/package-lock.json @@ -1,12 +1,12 @@ { "name": "mock-chronik-client", - "version": "1.2.0", + "version": "1.3.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "mock-chronik-client", - "version": "1.2.0", + "version": "1.3.0", "license": "MIT", "dependencies": { "ecashaddrjs": "^1.5.2" diff --git a/apps/mock-chronik-client/package.json b/apps/mock-chronik-client/package.json --- a/apps/mock-chronik-client/package.json +++ b/apps/mock-chronik-client/package.json @@ -4,7 +4,7 @@ }, "name": "mock-chronik-client", "description": "Testing utility to mock the Chronik indexer client and support unit tests that need to mock chronik related API calls.", - "version": "1.2.0", + "version": "1.3.0", "main": "index.js", "devDependencies": { "mocha": "^10.2.0", diff --git a/apps/mock-chronik-client/test/index.test.js b/apps/mock-chronik-client/test/index.test.js --- a/apps/mock-chronik-client/test/index.test.js +++ b/apps/mock-chronik-client/test/index.test.js @@ -181,6 +181,34 @@ assert.strictEqual(mockedChronik.mockedResponses.ws.txid, txid); }); +it('We can subscribe to and unsubscribe from addresses with the ws object', async function () { + // Initialize chronik mock with script info + const mockedChronik = new MockChronikClient(); + const { type, hash } = ecashaddr.decode(P2PKH_ADDRESS, true); + + // Create websocket subscription to listen to confirmations on txid + const ws = mockedChronik.ws({ + onMessage: msg => { + console.log(msg); + }, + }); + + // Wait for WS to be connected: + await ws.waitForOpen(); + + // Subscribe to address + ws.subscribeToAddress(P2PKH_ADDRESS); + + // Verify websocket subscription is as expected + assert.deepEqual(ws.subs, [{ scriptType: type, scriptPayload: hash }]); + + // Unsubscribe from address + ws.unsubscribeFromAddress(P2PKH_ADDRESS); + + // Verify websocket subscription is as expected + assert.deepEqual(ws.subs, []); +}); + it('Mock an error returned from the block() API', async function () { const mockedChronik = new MockChronikClient(); const blockHash = 'some block hash';