diff --git a/clients/tests/web/test/tb03-simple-atomic-transfer.test.js b/clients/tests/web/test/tb03-simple-atomic-transfer.test.js index 0760a55d..e0d3906c 100644 --- a/clients/tests/web/test/tb03-simple-atomic-transfer.test.js +++ b/clients/tests/web/test/tb03-simple-atomic-transfer.test.js @@ -473,7 +473,7 @@ describe('TB03 - Atomic swap with first party steal', () => { await mercuryweblib.transferSend(clientConfig, wallet1.name, statechainId1, toAddress3_for_steal.transfer_receive, false, toAddress3.batch_id); } catch (error) { // Assert the captured error message - const expectedMessage = 'expected a string argument, found undefined'; + const expectedMessage = 'Request failed'; expect(error.message).contains(expectedMessage); } @@ -582,7 +582,7 @@ describe('TB03 - Atomic swap with second party steal', () => { await mercuryweblib.transferSend(clientConfig, wallet2.name, statechainId1, toAddress4_for_steal.transfer_receive, false, toAddress4.batch_id); } catch (error) { // Assert the captured error message - const expectedMessage = 'expected a string argument, found undefined'; + const expectedMessage = 'Request failed'; expect(error.message).contains(expectedMessage); } diff --git a/clients/tests/web/test/tb04-simple-lightning-latch.test.js b/clients/tests/web/test/tb04-simple-lightning-latch.test.js index ef9e030b..5322fac3 100644 --- a/clients/tests/web/test/tb04-simple-lightning-latch.test.js +++ b/clients/tests/web/test/tb04-simple-lightning-latch.test.js @@ -105,4 +105,220 @@ describe('TB04 - Simple Lightning Latch', () => { expect(hashPreImage).toEqual(paymentHash.hash); }); -}, 50000); \ No newline at end of file +}, 50000); + +describe('TB04 - The sender tries to get the pre-image before the batch is unlocked should fail', () => { + test("expected flow", async () => { + + localStorage.removeItem("mercury-layer:wallet1_tb04"); + localStorage.removeItem("mercury-layer:wallet2_tb04"); + + let wallet1 = await mercuryweblib.createWallet(clientConfig, "wallet1_tb04"); + let wallet2 = await mercuryweblib.createWallet(clientConfig, "wallet2_tb04"); + + await mercuryweblib.newToken(clientConfig, wallet1.name); + await mercuryweblib.newToken(clientConfig, wallet2.name); + + const amount = 1000; + + let result1 = await mercuryweblib.getDepositBitcoinAddress(clientConfig, wallet1.name, amount); + let result2 = await mercuryweblib.getDepositBitcoinAddress(clientConfig, wallet2.name, amount); + + const statechainId1 = result1.statechain_id; + const statechainId2 = result2.statechain_id; + + let isDepositInMempool1 = false; + let isDepositConfirmed1 = false; + + let isDepositInMempool2 = false; + let isDepositConfirmed2 = false; + + let areBlocksGenerated = false; + + await depositCoin(result1.deposit_address, amount); + await depositCoin(result2.deposit_address, amount); + + while (!isDepositConfirmed2 || !isDepositConfirmed1) { + + let coins = await mercuryweblib.listStatecoins(clientConfig, wallet1.name); + + for (let coin of coins) { + if (coin.statechain_id === statechainId1 && coin.status === CoinStatus.IN_MEMPOOL && !isDepositInMempool1) { + isDepositInMempool1 = true; + } else if (coin.statechain_id === statechainId1 && coin.status === CoinStatus.CONFIRMED) { + isDepositConfirmed1 = true; + } + } + + coins = await mercuryweblib.listStatecoins(clientConfig, wallet2.name); + + for (let coin of coins) { + if (coin.statechain_id === statechainId2 && coin.status === CoinStatus.IN_MEMPOOL && !isDepositInMempool2) { + isDepositInMempool2 = true; + } else if (coin.statechain_id === statechainId2 && coin.status === CoinStatus.CONFIRMED) { + isDepositConfirmed2 = true; + } + } + + if (isDepositInMempool1 && isDepositInMempool2 && !areBlocksGenerated) { + areBlocksGenerated = true; + await generateBlocks(clientConfig.confirmationTarget); + } + + await new Promise(r => setTimeout(r, 1000)); + } + + const paymentHash1 = await mercuryweblib.paymentHash(clientConfig, wallet1.name, statechainId1); + const paymentHash2 = await mercuryweblib.paymentHash(clientConfig, wallet2.name, statechainId2); + + let transferAddress1 = await mercuryweblib.newTransferAddress(wallet2.name); + let transferAddress2 = await mercuryweblib.newTransferAddress(wallet1.name); + + await mercuryweblib.transferSend(clientConfig, wallet1.name, statechainId1, transferAddress1.transfer_receive, false, paymentHash1.batchId ); + await mercuryweblib.transferSend(clientConfig, wallet2.name, statechainId2, transferAddress2.transfer_receive, false, paymentHash2.batchId); + + let transferReceive = await mercuryweblib.transferReceive(clientConfig, wallet2.name); + + expect(transferReceive.isThereBatchLocked).toBe(true); + + try { + const { preimage } = await mercuryweblib.retrievePreImage(clientConfig, wallet1.name, statechainId1, paymentHash1.batchId); + } catch (error) { + // Assert the captured error message + const expectedMessage = 'Request failed with status code 404'; + expect(error.message).to.equal(expectedMessage); + } + + await mercuryweblib.confirmPendingInvoice(clientConfig, wallet1.name, statechainId1); + await mercuryweblib.confirmPendingInvoice(clientConfig, wallet2.name, statechainId2); + + transferReceive = await mercuryweblib.transferReceive(clientConfig, wallet2.name); + + expect(transferReceive.isThereBatchLocked).toBe(false); + + let toAddress = "bcrt1q805t9k884s5qckkxv7l698hqlz7t6alsfjsqym"; + + await mercuryweblib.withdrawCoin(clientConfig, wallet2.name, statechainId, toAddress, null, null); + + const { preimage } = await mercuryweblib.retrievePreImage(clientConfig, wallet1.name, statechainId1, paymentHash1.batchId); + + let hashPreImage = await sha256(preimage); + + expect(hashPreImage).toEqual(paymentHash1.hash); + }); +}, 50000); + +describe('TB04 - Statecoin sender can recover (resend their coin) after batch timeout without completion', () => { + test("expected flow", async () => { + + localStorage.removeItem("mercury-layer:wallet1_tb04"); + localStorage.removeItem("mercury-layer:wallet2_tb04"); + + let wallet1 = await mercuryweblib.createWallet(clientConfig, "wallet1_tb04"); + let wallet2 = await mercuryweblib.createWallet(clientConfig, "wallet2_tb04"); + + await mercuryweblib.newToken(clientConfig, wallet1.name); + await mercuryweblib.newToken(clientConfig, wallet2.name); + + const amount = 1000; + + let result1 = await mercuryweblib.getDepositBitcoinAddress(clientConfig, wallet1.name, amount); + let result2 = await mercuryweblib.getDepositBitcoinAddress(clientConfig, wallet2.name, amount); + + const statechainId1 = result1.statechain_id; + const statechainId2 = result2.statechain_id; + + let isDepositInMempool1 = false; + let isDepositConfirmed1 = false; + + let isDepositInMempool2 = false; + let isDepositConfirmed2 = false; + + let areBlocksGenerated = false; + + await depositCoin(result1.deposit_address, amount); + await depositCoin(result2.deposit_address, amount); + + while (!isDepositConfirmed2 || !isDepositConfirmed1) { + + let coins = await mercuryweblib.listStatecoins(clientConfig, wallet1.name); + + for (let coin of coins) { + if (coin.statechain_id === statechainId1 && coin.status === CoinStatus.IN_MEMPOOL && !isDepositInMempool1) { + isDepositInMempool1 = true; + } else if (coin.statechain_id === statechainId1 && coin.status === CoinStatus.CONFIRMED) { + isDepositConfirmed1 = true; + } + } + + coins = await mercuryweblib.listStatecoins(clientConfig, wallet2.name); + + for (let coin of coins) { + if (coin.statechain_id === statechainId2 && coin.status === CoinStatus.IN_MEMPOOL && !isDepositInMempool2) { + isDepositInMempool2 = true; + } else if (coin.statechain_id === statechainId2 && coin.status === CoinStatus.CONFIRMED) { + isDepositConfirmed2 = true; + } + } + + if (isDepositInMempool1 && isDepositInMempool2 && !areBlocksGenerated) { + areBlocksGenerated = true; + await generateBlocks(clientConfig.confirmationTarget); + } + + await new Promise(r => setTimeout(r, 1000)); + } + + const paymentHash1 = await mercuryweblib.paymentHash(clientConfig, wallet1.name, statechainId1); + const paymentHash2 = await mercuryweblib.paymentHash(clientConfig, wallet2.name, statechainId2); + + let transferAddress1 = await mercuryweblib.newTransferAddress(wallet2.name); + let transferAddress2 = await mercuryweblib.newTransferAddress(wallet1.name); + + await mercuryweblib.transferSend(clientConfig, wallet1.name, statechainId1, transferAddress1.transfer_receive, false, paymentHash1.batchId ); + await mercuryweblib.transferSend(clientConfig, wallet2.name, statechainId2, transferAddress2.transfer_receive, false, paymentHash2.batchId); + + let transferReceive = await mercuryweblib.transferReceive(clientConfig, wallet2.name); + + expect(transferReceive.isThereBatchLocked).toBe(true); + + await mercuryweblib.confirmPendingInvoice(clientConfig, wallet1.name, statechainId1); + await mercuryweblib.confirmPendingInvoice(clientConfig, wallet2.name, statechainId2); + + await sleep(20000); + + let errorMessage; + console.error = (msg) => { + errorMessage = msg; + }; + + transferReceive = await mercuryweblib.transferReceive(clientConfig, wallet2.name); + + // Assert the captured error message + const expectedMessage = 'Failed to update transfer message'; + expect(errorMessage).contains(expectedMessage); + + let transferAddress3 = await mercuryweblib.newTransferAddress(wallet2.name); + let transferAddress4 = await mercuryweblib.newTransferAddress(wallet1.name); + + await mercuryweblib.transferSend(clientConfig, wallet1.name, statechainId1, transferAddress3.transfer_receive, false, paymentHash2.batchId ); + await mercuryweblib.transferSend(clientConfig, wallet2.name, statechainId2, transferAddress4.transfer_receive, false, paymentHash2.batchId); + + transferReceive = await mercuryweblib.transferReceive(clientConfig, wallet1.name); + + await mercuryweblib.confirmPendingInvoice(clientConfig, wallet1.name, statechainId1); + await mercuryweblib.confirmPendingInvoice(clientConfig, wallet2.name, statechainId2); + + expect(transferReceive.isThereBatchLocked).toBe(false); + + let toAddress = "bcrt1q805t9k884s5qckkxv7l698hqlz7t6alsfjsqym"; + + await mercuryweblib.withdrawCoin(clientConfig, wallet2.name, statechainId, toAddress, null, null); + + const { preimage } = await mercuryweblib.retrievePreImage(clientConfig, wallet1.name, statechainId1, paymentHash1.batchId); + + let hashPreImage = await sha256(preimage); + + expect(hashPreImage).toEqual(paymentHash1.hash); + }); +}, 50000);