diff --git a/lib/chain/ElementsWrapper.ts b/lib/chain/ElementsWrapper.ts index 8291ba5f..5c3d9b58 100644 --- a/lib/chain/ElementsWrapper.ts +++ b/lib/chain/ElementsWrapper.ts @@ -65,13 +65,29 @@ class ElementsWrapper // of the public client const hasLowball = this.lowballClient() !== undefined; - this.publicClient().on('transaction', ({ transaction, confirmed }) => { - if (hasLowball && !confirmed) { - return; - } + this.publicClient().on( + 'transaction', + async ({ transaction, confirmed }) => { + if (hasLowball && !confirmed) { + return; + } + + if (confirmed) { + this.emit('transaction', { transaction, confirmed }); + return; + } - this.emit('transaction', { transaction, confirmed }); - }); + try { + if (await this.zeroConfCheck.checkTransaction(transaction)) { + this.emit('transaction', { transaction, confirmed }); + } + } catch (e) { + this.logger.error( + `${this.symbol} 0-conf transaction check failed: ${formatError(e)}`, + ); + } + }, + ); this.lowballClient()?.on( 'transaction', diff --git a/lib/chain/elements/ZeroConfTool.ts b/lib/chain/elements/ZeroConfTool.ts index e14600d3..20ba6949 100644 --- a/lib/chain/elements/ZeroConfTool.ts +++ b/lib/chain/elements/ZeroConfTool.ts @@ -15,8 +15,8 @@ export type ZeroConfToolConfig = { }; type ZeroConfResponse = { - node_types: { - bridge: { + observations?: { + bridge?: { seen: number; total: number; }; @@ -50,7 +50,7 @@ class ZeroConfTool this.maxRetries = config.maxRetries || 60; this.logger.info( - `Checking every ${this.retryDelay}ms with ${this.maxRetries} retries with 0-conf tool at ${this.endpoint}`, + `Checking every ${this.retryDelay}ms with ${this.maxRetries} retries with 0-conf tool at: ${this.endpoint}`, ); this.start().then(); @@ -125,13 +125,18 @@ class ZeroConfTool private check = async () => { for (const [txId, { retries }] of this.toCheck) { - const res = await axios.get>( - `${this.endpoint}/${txId}`, - ); + const res = ( + await axios.get>( + `${this.endpoint}/${txId}`, + ) + ).data; + + const bridgeData = res.observations?.bridge; + if (bridgeData === undefined) { + continue; + } - if ( - res.data.node_types.bridge.seen === res.data.node_types.bridge.total - ) { + if (bridgeData.seen > 0 && bridgeData.seen === bridgeData.total) { this.toCheck.delete(txId); this.emit('accepted', txId); diff --git a/test/integration/chain/ElementsWrapper.spec.ts b/test/integration/chain/ElementsWrapper.spec.ts index 580c2492..0f0de54b 100644 --- a/test/integration/chain/ElementsWrapper.spec.ts +++ b/test/integration/chain/ElementsWrapper.spec.ts @@ -147,6 +147,13 @@ describe('ElementsWrapper', () => { Logger.disabledLogger, elementsConfig, ); + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-expect-error + oneWrapper['zeroConfCheck'] = { + name: 'stub', + checkTransaction: jest.fn().mockResolvedValue(true), + }; + await oneWrapper.connect(); expect.assertions(2); diff --git a/test/integration/chain/elements/ZeroConfTool.spec.ts b/test/integration/chain/elements/ZeroConfTool.spec.ts index 98767461..f8a91766 100644 --- a/test/integration/chain/elements/ZeroConfTool.spec.ts +++ b/test/integration/chain/elements/ZeroConfTool.spec.ts @@ -26,7 +26,7 @@ describe('ZeroConfTool', () => { app.get('/accept', (_, res) => { res.json({ - node_types: { + observations: { bridge: { seen: 21, total: 21, @@ -37,7 +37,7 @@ describe('ZeroConfTool', () => { app.get('/timeout', (_, res) => { res.json({ - node_types: { + observations: { bridge: { seen: 20, total: 21,