diff --git a/clients/apps/nodejs/test/tb04-simple-lightning-latch.mjs b/clients/apps/nodejs/test/tb04-simple-lightning-latch.mjs index d94d73ed..774f48b5 100644 --- a/clients/apps/nodejs/test/tb04-simple-lightning-latch.mjs +++ b/clients/apps/nodejs/test/tb04-simple-lightning-latch.mjs @@ -3,7 +3,7 @@ import client_config from '../client_config.js'; import mercurynodejslib from 'mercurynodejslib'; import { CoinStatus } from 'mercurynodejslib/coin_enum.js'; import crypto from 'crypto'; -import { createWallet, depositCoin, generateInvoice, payInvoice } from '../test_utils.js'; +import { sleep, createWallet, depositCoin, generateInvoice, payInvoice, settleInvoice } from '../test_utils.js'; describe('TB04 - Lightning Latch', function() { this.timeout(30000); @@ -279,7 +279,7 @@ describe('TB04 - Lightning Latch', function() { }) }) - context('Receiver tries to transfer invoice amount to another invoice before preimage retrieval should fail', () => { + context('Statecoin trade with invoice creation, payment and settlement', () => { it('should complete successfully', async () => { // await removeDatabase(); @@ -314,7 +314,7 @@ describe('TB04 - Lightning Latch', function() { const invoice = await generateInvoice(paymentHash.hash, amount); - await payInvoice(invoice.payment_request); + payInvoice(invoice.payment_request); const transferAddress = await mercurynodejslib.newTransferAddress(clientConfig, wallet_2_name, null); @@ -339,6 +339,76 @@ describe('TB04 - Lightning Latch', function() { .digest('hex') expect(hash).to.equal(paymentHash.hash); + + await settleInvoice(preimage); + }) + }) + + context('Receiver tries to transfer invoice amount to another invoice before preimage retrieval should fail', () => { + it('should complete successfully', async () => { + + // await removeDatabase(); + const clientConfig = client_config.load(); + let wallet_1_name = "w_ln_7"; + let wallet_2_name = "w_ln_8"; + await createWallet(clientConfig, wallet_1_name); + await createWallet(clientConfig, wallet_2_name); + + const token = await mercurynodejslib.newToken(clientConfig, wallet_1_name); + const tokenId = token.token_id; + + const amount = 60000; + const depositInfo = await mercurynodejslib.getDepositBitcoinAddress(clientConfig, wallet_1_name, amount); + + const tokenList = await mercurynodejslib.getWalletTokens(clientConfig, wallet_1_name); + const usedToken = tokenList.find(token => token.token_id === tokenId); + + expect(usedToken.spent).is.true; + + await depositCoin(clientConfig, wallet_1_name, amount, depositInfo); + + const listCoins = await mercurynodejslib.listStatecoins(clientConfig, wallet_1_name); + + expect(listCoins.length).to.equal(1); + + const coin = listCoins[0]; + + expect(coin.status).to.equal(CoinStatus.CONFIRMED); + + const paymentHash = await mercurynodejslib.paymentHash(clientConfig, wallet_1_name, coin.statechain_id); + + const invoice = await generateInvoice(paymentHash.hash, amount); + + payInvoice(invoice.payment_request); + + const transferAddress = await mercurynodejslib.newTransferAddress(clientConfig, wallet_2_name, null); + + await mercurynodejslib.transferSend(clientConfig, wallet_1_name, coin.statechain_id, transferAddress.transfer_receive, false, paymentHash.batchId); + + let transferReceiveResult = await mercurynodejslib.transferReceive(clientConfig, wallet_2_name); + + expect(transferReceiveResult.isThereBatchLocked).is.true; + expect(transferReceiveResult.receivedStatechainIds).empty; + + await mercurynodejslib.confirmPendingInvoice(clientConfig, wallet_1_name, coin.statechain_id); + + transferReceiveResult = await mercurynodejslib.transferReceive(clientConfig, wallet_2_name); + + expect(transferReceiveResult.isThereBatchLocked).is.false; + expect(transferReceiveResult.receivedStatechainIds).not.empty; + + const { preimage } = await mercurynodejslib.retrievePreImage(clientConfig, wallet_1_name, coin.statechain_id, paymentHash.batchId); + + const hash = crypto.createHash('sha256') + .update(Buffer.from(preimage, 'hex')) + .digest('hex') + + expect(hash).to.equal(paymentHash.hash); + + const paymentHashSecond = await mercurynodejslib.paymentHash(clientConfig, wallet_1_name, coin.statechain_id); + const invoiceSecond = await generateInvoice(paymentHashSecond.hash, amount); + + payInvoice(invoiceSecond.payment_request); }) }) }) diff --git a/clients/apps/nodejs/test_utils.js b/clients/apps/nodejs/test_utils.js index 9c72cc2f..1a22b2b1 100644 --- a/clients/apps/nodejs/test_utils.js +++ b/clients/apps/nodejs/test_utils.js @@ -108,18 +108,26 @@ const generateInvoice = async (paymentHash, amountInSats) => { console.error('Error:', stderr); return null; } - return stdout.trim(); -} - -const payInvoice = async (paymentRequest) => { - const payInvoiceCommand = `docker exec $(docker ps -qf "name=mercurylayer_bob_1") lncli -n regtest payinvoice ${paymentRequest}`; - const { stdout, stderr } = await exec(payInvoiceCommand); - if (stderr) { - console.error('Error:', stderr); + try { + const response = JSON.parse(stdout.trim()); + return response; + } catch (error) { + console.error('Error parsing JSON:', error); return null; } - return stdout.trim(); +} + +const payInvoice = (paymentRequest) => { + + const payInvoiceCommand = `docker exec $(docker ps -qf "name=mercurylayer_bob_1") lncli -n regtest payinvoice --force ${paymentRequest}`; + exec(payInvoiceCommand); +} + +const settleInvoice = async (preimage) => { + + const settleInvoiceCommand = `docker exec $(docker ps -qf "name=mercurylayer_alice_1") lncli -n regtest settleinvoice ${preimage}`; + await exec(settleInvoiceCommand); } module.exports = { @@ -135,5 +143,6 @@ module.exports = { connectMercuryServer, disconnectMercuryServer , generateInvoice, - payInvoice + payInvoice, + settleInvoice };