From e4360f1247ae9195e1e369926fe5ae0f740fe99d Mon Sep 17 00:00:00 2001 From: surangap Date: Wed, 23 Jun 2021 23:33:15 +0800 Subject: [PATCH] Refactored code. --- .../icxorderbook/claimDFCHTLC.test.ts | 147 ++++-------------- .../category/icxorderbook/icx_setup.ts | 59 ++++++- .../src/category/icxorderbook.ts | 4 +- website/docs/jellyfish/api/icxorderbook.md | 4 +- 4 files changed, 89 insertions(+), 125 deletions(-) diff --git a/packages/jellyfish-api-core/__tests__/category/icxorderbook/claimDFCHTLC.test.ts b/packages/jellyfish-api-core/__tests__/category/icxorderbook/claimDFCHTLC.test.ts index 9868d920ce..5e333d397a 100644 --- a/packages/jellyfish-api-core/__tests__/category/icxorderbook/claimDFCHTLC.test.ts +++ b/packages/jellyfish-api-core/__tests__/category/icxorderbook/claimDFCHTLC.test.ts @@ -1,22 +1,30 @@ import { ContainerAdapterClient } from '../../container_adapter_client' import { MasterNodeRegTestContainer } from '@defichain/testcontainers' import { - ExtHTLC, HTLC, ICXClaimDFCHTLCInfo, ICXDFCHTLCInfo, ICXEXTHTLCInfo, ICXGenericResult, ICXHTLCStatus, - ICXHTLCType, ICXListHTLCOptions, ICXOfferInfo, ICXOrderInfo, ICXOffer, ICXOrder, InputUTXO + ICXClaimDFCHTLCInfo, ICXDFCHTLCInfo, ICXEXTHTLCInfo, ICXHTLCStatus, + ICXHTLCType, ICXListHTLCOptions, UTXO } from '../../../src/category/icxorderbook' -import BigNumber from 'bignumber.js' -import { setup, accountDFI, idDFI, accountBTC, checkDFIBuyOfferDetails, checkDFISellOrderDetails, checkDFCHTLCDetails, checkEXTHTLCDetails } from './common.test' +import { accountDFI, idDFI, accountBTC, ICXSetup, symbolDFI } from './icx_setup' import { RpcApiError } from '../../../src' -describe('Should test ICXOrderBook.calimDFCHTLC', () => { +describe('ICXOrderBook.calimDFCHTLC', () => { const container = new MasterNodeRegTestContainer() const client = new ContainerAdapterClient(container) + const icxSetup = new ICXSetup(container, client) beforeAll(async () => { await container.start() await container.waitForReady() await container.waitForBlock(1) - await setup(container) + await icxSetup.createAccounts() + await icxSetup.createBTCToken() + await icxSetup.initializeTokensIds() + await icxSetup.mintBTCtoken(100) + await icxSetup.fundAccount(accountDFI, symbolDFI, 500) + await icxSetup.fundAccount(accountBTC, symbolDFI, 10) // for fee + await icxSetup.createBTCDFIPool() + await icxSetup.addLiquidityToBTCDFIPool(1, 100) + await icxSetup.setTakerFee(0.001) }) afterAll(async () => { @@ -27,105 +35,8 @@ describe('Should test ICXOrderBook.calimDFCHTLC', () => { // cleanup code here }) - // setup untill submitting external HTLC for DFC buy offer - // returns the {makeOfferTxId, DFCHTLCTxId, ExtHTLCTxId} - const setupUntilSubmitExtHTLCForDFCBuyOffer = async (): Promise => { - // create order - maker - const order: ICXOrder = { - tokenFrom: idDFI, - chainTo: 'BTC', - ownerAddress: accountDFI, - receivePubkey: '037f9563f30c609b19fd435a19b8bde7d6db703012ba1aba72e9f42a87366d1941', - amountFrom: new BigNumber(15), - orderPrice: new BigNumber(0.01) - } - let result: ICXGenericResult = await client.icxorderbook.createOrder(order, []) - const createOrderTxId = result.txid - await container.generate(1) - - // list ICX orders - let orders: Record = await client.icxorderbook.listOrders() - await checkDFISellOrderDetails(container, order, createOrderTxId, orders as Record) - - // make offer to 15 DFI - taker - const offer: ICXOffer = { - orderTx: createOrderTxId, - amount: new BigNumber(0.15), // 0.15 BTC = 15 DFI - ownerAddress: accountBTC - } - const accountBTCBeforeOffer = await container.call('getaccount', [accountBTC, {}, true]) - result = await client.icxorderbook.makeOffer(offer, []) - const makeOfferTxId = result.txid - await container.generate(1) - - const accountBTCAfterOffer = await container.call('getaccount', [accountBTC, {}, true]) - // check fee of 0.015 DFI has been reduced from the accountBTCBeforeOffer[idDFI] - // Fee = takerFeePerBTC(inBTC) * amount(inBTC) * DEX DFI per BTC rate - expect(Number(accountBTCAfterOffer[idDFI]).toPrecision(8)).toStrictEqual((Number(accountBTCBeforeOffer[idDFI]) - Number(0.015)).toPrecision(8)) - - // List the ICX offers for orderTx = createOrderTxId and check - orders = await client.icxorderbook.listOrders({ orderTx: createOrderTxId }) - expect(Object.keys(orders).length).toBe(2) // extra entry for the warning text returned by the RPC atm. - await checkDFIBuyOfferDetails(container, offer, makeOfferTxId, orders as Record) - - const accountDFIBeforeDFCHTLC = await container.call('getaccount', [accountDFI, {}, true]) - - // create DFCHTLC - maker - const DFCHTLC: HTLC = { - offerTx: makeOfferTxId, - amount: new BigNumber(15), // in DFC - hash: '957fc0fd643f605b2938e0631a61529fd70bd35b2162a21d978c41e5241a5220', - timeout: 500 - } - const DFCHTLCTxId = (await client.icxorderbook.submitDFCHTLC(DFCHTLC)).txid - await container.generate(1) - - const accountDFIAfterDFCHTLC = await container.call('getaccount', [accountDFI, {}, true]) - // should reduce accountDFIBeforeDFCHTLC[idDFI] balance by 0.015 DFI - expect(Number(accountDFIAfterDFCHTLC[idDFI]).toPrecision(8)).toStrictEqual((Number(accountDFIBeforeDFCHTLC[idDFI]) - Number(0.015)).toPrecision(8)) - - // List htlc - let listHTLCOptions: ICXListHTLCOptions = { - offerTx: makeOfferTxId - } - let HTLCs: Record = await container.call('icx_listhtlcs', [listHTLCOptions]) - expect(Object.keys(HTLCs).length).toBe(2) // extra entry for the warning text returned by the RPC atm. - await checkDFCHTLCDetails(DFCHTLC, DFCHTLCTxId, HTLCs) - - const accountBTCBeforeEXTHTLC = await container.call('getaccount', [accountBTC, {}, true]) - // submit EXT HTLC - taker - const ExtHTLC: ExtHTLC = { - offerTx: makeOfferTxId, - amount: new BigNumber(0.15), - hash: '957fc0fd643f605b2938e0631a61529fd70bd35b2162a21d978c41e5241a5220', - htlcScriptAddress: '13sJQ9wBWh8ssihHUgAaCmNWJbBAG5Hr9N', - ownerPubkey: '036494e7c9467c8c7ff3bf29e841907fb0fa24241866569944ea422479ec0e6252', - timeout: 15 - } - const ExtHTLCTxId = (await client.icxorderbook.submitExtHTLC(ExtHTLC)).txid - await container.generate(1) - - // List htlc - listHTLCOptions = { - offerTx: makeOfferTxId - } - HTLCs = await container.call('icx_listhtlcs', [listHTLCOptions]) - expect(Object.keys(HTLCs).length).toBe(3) // extra entry for the warning text returned by the RPC atm. - await checkEXTHTLCDetails(ExtHTLC, ExtHTLCTxId, HTLCs) - - const accountBTCAfterEXTHTLC = await container.call('getaccount', [accountBTC, {}, true]) - // should have the same balance as accountBTCAfterDFCHTLC - expect(accountBTCAfterEXTHTLC).toStrictEqual(accountBTCBeforeEXTHTLC) - - return { - makeOfferTxId: makeOfferTxId, - DFCHTLCTxId: DFCHTLCTxId, - ExtHTLCTxId: ExtHTLCTxId - } - } - - it('Create ICX order to sell DFI, make offer, create HTLCs and claim DFCHTLC, maker and taker balances should be updated as expected', async () => { - const { makeOfferTxId, DFCHTLCTxId } = await setupUntilSubmitExtHTLCForDFCBuyOffer() + it('create icx order to sell dfi, make offer, create htlcs and claim dfc htlc, maker and taker balances should be updated as expected', async () => { + const { makeOfferTxId, DFCHTLCTxId } = await icxSetup.setupUntilSubmitExtHTLCForDFCBuyOffer() const accountDFIBeforeClaim = await container.call('getaccount', [accountDFI, {}, true]) const accountBTCBeforeClaim = await container.call('getaccount', [accountBTC, {}, true]) @@ -138,7 +49,7 @@ describe('Should test ICXOrderBook.calimDFCHTLC', () => { offerTx: makeOfferTxId, closed: true } - const HTLCs: Record = await container.call('icx_listhtlcs', [listHTLCOptions]) + const HTLCs: Record = await client.call('icx_listhtlcs', [listHTLCOptions], 'bignumber') expect(Object.keys(HTLCs).length).toBe(4) // extra entry for the warning text returned by the RPC atm. // we have a common field "type", use that to narrow down the record if (HTLCs[claimTxId].type === ICXHTLCType.CLAIM_DFC) { @@ -160,19 +71,19 @@ describe('Should test ICXOrderBook.calimDFCHTLC', () => { // maker should get incentive + maker deposit and taker should get amount in DFCHTLCTxId HTLC - takerfee // expect(Number(accountDFIAfterClaim[idDFI])).toStrictEqual(Number(accountDFIBeforeClaim[idDFI]) + Number(0.01500000000000) + Number(0.00375000000000)) - expect(Number(accountDFIAfterClaim[idDFI]).toPrecision(8)).toStrictEqual((Number(accountDFIBeforeClaim[idDFI]) + Number(0.01500000000000) + Number(0.00375000000000)).toPrecision(8)) - expect(Number(accountBTCAfterClaim[idDFI])).toStrictEqual(Number(accountBTCBeforeClaim[idDFI]) + Number(15)) + expect(accountDFIAfterClaim[idDFI]).toStrictEqual(Number(accountDFIBeforeClaim[idDFI]) + Number(0.010) + Number(0.00250)) + expect(accountBTCAfterClaim[idDFI]).toStrictEqual(Number(accountBTCBeforeClaim[idDFI]) + Number(10)) }) - it('Should claim DFCHTLC with input UTXOs', async () => { - const { makeOfferTxId, DFCHTLCTxId } = await setupUntilSubmitExtHTLCForDFCBuyOffer() + it('should claim dfc htlc with input utxos', async () => { + const { makeOfferTxId, DFCHTLCTxId } = await icxSetup.setupUntilSubmitExtHTLCForDFCBuyOffer() const accountDFIBeforeClaim = await container.call('getaccount', [accountDFI, {}, true]) const accountBTCBeforeClaim = await container.call('getaccount', [accountBTC, {}, true]) // input utxos const utxos = await container.call('listunspent', [1, 9999999, [accountDFI], true]) - const inputUTXOs: InputUTXO[] = utxos.map((utxo: InputUTXO) => { + const inputUTXOs: UTXO[] = utxos.map((utxo: UTXO) => { return { txid: utxo.txid, vout: utxo.vout @@ -187,7 +98,7 @@ describe('Should test ICXOrderBook.calimDFCHTLC', () => { offerTx: makeOfferTxId, closed: true } - const HTLCs: Record = await container.call('icx_listhtlcs', [listHTLCOptions]) + const HTLCs: Record = await client.call('icx_listhtlcs', [listHTLCOptions], 'bignumber') expect(Object.keys(HTLCs).length).toBe(4) // extra entry for the warning text returned by the RPC atm. // we have a common field "type", use that to narrow down the record if (HTLCs[claimTxId].type === ICXHTLCType.CLAIM_DFC) { @@ -209,12 +120,12 @@ describe('Should test ICXOrderBook.calimDFCHTLC', () => { // maker should get incentive + maker deposit and taker should get amount in DFCHTLCTxId HTLC - takerfee // expect(Number(accountDFIAfterClaim[idDFI])).toStrictEqual(Number(accountDFIBeforeClaim[idDFI]) + Number(0.01500000000000) + Number(0.00375000000000)) - expect(Number(accountDFIAfterClaim[idDFI]).toPrecision(8)).toStrictEqual((Number(accountDFIBeforeClaim[idDFI]) + Number(0.01500000000000) + Number(0.00375000000000)).toPrecision(8)) - expect(Number(accountBTCAfterClaim[idDFI])).toStrictEqual(Number(accountBTCBeforeClaim[idDFI]) + Number(15)) + expect(accountDFIAfterClaim[idDFI]).toStrictEqual(Number(accountDFIBeforeClaim[idDFI]) + Number(0.010) + Number(0.00250)) + expect(accountBTCAfterClaim[idDFI].toPrecision(8)).toStrictEqual((Number(accountBTCBeforeClaim[idDFI]) + Number(10)).toPrecision(8)) }) - it('Should return an error when try to claim with invalid htlc transaction id', async () => { - await setupUntilSubmitExtHTLCForDFCBuyOffer() + it('should return an error when try to claim with invalid htlc transaction id', async () => { + await icxSetup.setupUntilSubmitExtHTLCForDFCBuyOffer() // claim with invalid dfc htlc tx id "123" const promise = client.icxorderbook.claimDFCHTLC('123', 'f75a61ad8f7a6e0ab701d5be1f5d4523a9b534571e4e92e0c4610c6a6784ccef') @@ -222,8 +133,8 @@ describe('Should test ICXOrderBook.calimDFCHTLC', () => { await expect(promise).rejects.toThrow('RpcApiError: \'Test ICXClaimDFCHTLCTx execution failed:\ndfc htlc with creation tx 0000000000000000000000000000000000000000000000000000000000000123 does not exists!\', code: -32600, method: icx_claimdfchtlc') }) - it('Should return an error when try to claim with invalid seed', async () => { - const { DFCHTLCTxId } = await setupUntilSubmitExtHTLCForDFCBuyOffer() + it('should return an error when try to claim with invalid seed', async () => { + const { DFCHTLCTxId } = await icxSetup.setupUntilSubmitExtHTLCForDFCBuyOffer() // claim with invalid seed "123" const promise = client.icxorderbook.claimDFCHTLC(DFCHTLCTxId, '123') diff --git a/packages/jellyfish-api-core/__tests__/category/icxorderbook/icx_setup.ts b/packages/jellyfish-api-core/__tests__/category/icxorderbook/icx_setup.ts index 99281aa0c8..fb39b6e471 100644 --- a/packages/jellyfish-api-core/__tests__/category/icxorderbook/icx_setup.ts +++ b/packages/jellyfish-api-core/__tests__/category/icxorderbook/icx_setup.ts @@ -1,7 +1,7 @@ import { BigNumber } from '@defichain/jellyfish-api-core' import { ICXOrder, ICXGenericResult, ICXOrderInfo, ICXOfferInfo, ICXOffer, - HTLC, ICXClaimDFCHTLCInfo, ICXDFCHTLCInfo, ICXEXTHTLCInfo, ICXListHTLCOptions + HTLC, ICXClaimDFCHTLCInfo, ICXDFCHTLCInfo, ICXEXTHTLCInfo, ICXListHTLCOptions, ExtHTLC } from '@defichain/jellyfish-api-core/category/icxorderbook' import { MasterNodeRegTestContainer } from '@defichain/testcontainers' import { createToken, mintTokens, accountToAccount } from '@defichain/testing' @@ -195,7 +195,7 @@ export class ICXSetup { } // setup the flow until ICX submit DFC HTLC for DFI sell order - async setupUntilSubmitDFCHTLCForDFIBuyOffer (): Promise<{order: ICXOrder, createOrderTxId: string, offer: ICXOffer, makeOfferTxId: string}> { + async setupUntilSubmitDFCHTLCForDFIBuyOffer (): Promise<{order: ICXOrder, createOrderTxId: string, offer: ICXOffer, makeOfferTxId: string, DFCHTLCTxId: string}> { const { order, createOrderTxId, offer, makeOfferTxId } = await this.setupUntilDFIBuyOffer() const accountDFIBeforeDFCHTLC = await this.container.call('getaccount', [accountDFI, {}, true]) @@ -237,7 +237,60 @@ export class ICXSetup { order: order, createOrderTxId: createOrderTxId, offer: offer, - makeOfferTxId: makeOfferTxId + makeOfferTxId: makeOfferTxId, + DFCHTLCTxId: DFCHTLCTxId + } + } + + // setup the flow until ICX submit EXT HTLC for DFI sell order + async setupUntilSubmitExtHTLCForDFCBuyOffer (): Promise<{order: ICXOrder, createOrderTxId: string, offer: ICXOffer, makeOfferTxId: string, DFCHTLCTxId: string, ExtHTLCTxId: string}> { + const { order, createOrderTxId, offer, makeOfferTxId, DFCHTLCTxId } = await this.setupUntilSubmitDFCHTLCForDFIBuyOffer() + + const accountBTCBeforeEXTHTLC = await this.container.call('getaccount', [accountBTC, {}, true]) + // submit EXT HTLC - taker + const ExtHTLC: ExtHTLC = { + offerTx: makeOfferTxId, + amount: new BigNumber(0.10), + hash: '957fc0fd643f605b2938e0631a61529fd70bd35b2162a21d978c41e5241a5220', + htlcScriptAddress: '13sJQ9wBWh8ssihHUgAaCmNWJbBAG5Hr9N', + ownerPubkey: '036494e7c9467c8c7ff3bf29e841907fb0fa24241866569944ea422479ec0e6252', + timeout: 15 + } + const ExtHTLCTxId = (await this.client.icxorderbook.submitExtHTLC(ExtHTLC)).txid + await this.container.generate(1) + + // List htlc + const listHTLCOptions: ICXListHTLCOptions = { + offerTx: makeOfferTxId + } + const HTLCs: Record = await this.client.call('icx_listhtlcs', [listHTLCOptions], 'bignumber') + expect(Object.keys(HTLCs).length).toBe(3) // extra entry for the warning text returned by the RPC atm. + expect(HTLCs[ExtHTLCTxId] as ICXEXTHTLCInfo).toStrictEqual( + { + type: 'EXTERNAL', + status: 'OPEN', + offerTx: makeOfferTxId, + amount: ExtHTLC.amount, + amountInDFCAsset: ExtHTLC.amount.dividedBy(order.orderPrice), + hash: ExtHTLC.hash, + htlcScriptAddress: ExtHTLC.htlcScriptAddress, + ownerPubkey: ExtHTLC.ownerPubkey, + timeout: new BigNumber(ExtHTLC.timeout), + height: expect.any(BigNumber) + } + ) + + const accountBTCAfterEXTHTLC = await this.container.call('getaccount', [accountBTC, {}, true]) + // should have the same balance as accountBTCAfterDFCHTLC + expect(accountBTCAfterEXTHTLC).toStrictEqual(accountBTCBeforeEXTHTLC) + + return { + order: order, + createOrderTxId: createOrderTxId, + offer: offer, + makeOfferTxId: makeOfferTxId, + DFCHTLCTxId: DFCHTLCTxId, + ExtHTLCTxId: ExtHTLCTxId } } } diff --git a/packages/jellyfish-api-core/src/category/icxorderbook.ts b/packages/jellyfish-api-core/src/category/icxorderbook.ts index 6a26c9a169..3ebcb97a42 100644 --- a/packages/jellyfish-api-core/src/category/icxorderbook.ts +++ b/packages/jellyfish-api-core/src/category/icxorderbook.ts @@ -134,12 +134,12 @@ export class ICXOrderBook { * * @param {string} [DFCHTLCTx] Transaction id of DFC HTLC transaction for which the claim is * @param {string} [seed] Secret seed for claiming HTLC - * @param {InputUTXO[]} inputUTXOs Specific utxos to spend + * @param {UTXO[]} inputUTXOs Specific utxos to spend * @param {string} [inputUTXOs.txid] transaction Id * @param {number} [inputUTXOs.vout] The output number * @return {Promise} Object indluding transaction id of the the transaction */ - async claimDFCHTLC (DFCHTLCTx: string, seed: string, inputUTXOs: InputUTXO[] = []): Promise { + async claimDFCHTLC (DFCHTLCTx: string, seed: string, inputUTXOs: UTXO[] = []): Promise { const htlc = { dfchtlcTx: DFCHTLCTx, seed: seed diff --git a/website/docs/jellyfish/api/icxorderbook.md b/website/docs/jellyfish/api/icxorderbook.md index 4d41ee4ce6..0360962776 100644 --- a/website/docs/jellyfish/api/icxorderbook.md +++ b/website/docs/jellyfish/api/icxorderbook.md @@ -155,10 +155,10 @@ Claims a DFC HTLC ```ts title="client.icxorderbook.claimDFCHTLC()" interface icxorderbook { - claimDFCHTLC (DFCHTLCTx: string, seed: string, inputUTXOs: InputUTXO[] = []): Promise + claimDFCHTLC (DFCHTLCTx: string, seed: string, inputUTXOs: UTXO[] = []): Promise } -interface InputUTXO { +interface UTXO { txid: string vout: number }