diff --git a/package-lock.json b/package-lock.json index 016b4605e7..425d7028c3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,6 +12,7 @@ "devDependencies": { "@size-limit/preset-app": "^4.10.1", "@types/jest": "^26.0.22", + "@types/randombytes": "^2.0.0", "husky": "^6.0.0", "jest": "^26.6.3", "lerna": "^4.0.0", @@ -1740,6 +1741,7 @@ "jest-resolve": "^26.6.2", "jest-util": "^26.6.2", "jest-worker": "^26.6.2", + "node-notifier": "^8.0.0", "slash": "^3.0.0", "source-map": "^0.6.0", "string-length": "^4.0.1", @@ -14737,6 +14739,7 @@ "dependencies": { "anymatch": "~3.1.1", "braces": "~3.0.2", + "fsevents": "~2.3.1", "glob-parent": "~5.1.0", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", @@ -16792,7 +16795,8 @@ "esprima": "^4.0.1", "estraverse": "^5.2.0", "esutils": "^2.0.2", - "optionator": "^0.8.1" + "optionator": "^0.8.1", + "source-map": "~0.6.1" }, "bin": { "escodegen": "bin/escodegen.js", @@ -17975,6 +17979,7 @@ "dev": true, "license": "BSD-2-Clause", "dependencies": { + "@types/yauzl": "^2.9.1", "debug": "^4.1.1", "get-stream": "^5.1.0", "yauzl": "^2.10.0" @@ -18925,6 +18930,7 @@ "minimist": "^1.2.5", "neo-async": "^2.6.0", "source-map": "^0.6.1", + "uglify-js": "^3.1.4", "wordwrap": "^1.0.0" }, "bin": { @@ -20567,6 +20573,7 @@ "@types/node": "*", "anymatch": "^3.0.3", "fb-watchman": "^2.0.0", + "fsevents": "^2.1.2", "graceful-fs": "^4.2.4", "jest-regex-util": "^26.0.0", "jest-serializer": "^26.6.2", @@ -21106,6 +21113,7 @@ "dev": true, "license": "MIT", "dependencies": { + "graceful-fs": "^4.1.6", "universalify": "^2.0.0" }, "optionalDependencies": { @@ -21847,6 +21855,7 @@ "dev": true, "license": "MIT", "dependencies": { + "encoding": "^0.1.12", "minipass": "^3.1.0", "minipass-sized": "^1.0.3", "minizlib": "^2.0.0" @@ -28331,7 +28340,8 @@ "esprima": "^4.0.1", "estraverse": "^4.2.0", "esutils": "^2.0.2", - "optionator": "^0.8.1" + "optionator": "^0.8.1", + "source-map": "~0.6.1" }, "bin": { "escodegen": "bin/escodegen.js", diff --git a/package.json b/package.json index d4218aa5af..9d10087854 100644 --- a/package.json +++ b/package.json @@ -36,6 +36,7 @@ "devDependencies": { "@size-limit/preset-app": "^4.10.1", "@types/jest": "^26.0.22", + "@types/randombytes": "^2.0.0", "husky": "^6.0.0", "jest": "^26.6.3", "lerna": "^4.0.0", diff --git a/packages/jellyfish-api-core/__tests__/category/account/removePoolLiquidity.test.ts b/packages/jellyfish-api-core/__tests__/category/account/removePoolLiquidity.test.ts index 9788f68bda..3064315ba7 100644 --- a/packages/jellyfish-api-core/__tests__/category/account/removePoolLiquidity.test.ts +++ b/packages/jellyfish-api-core/__tests__/category/account/removePoolLiquidity.test.ts @@ -1,112 +1,122 @@ import { MasterNodeRegTestContainer } from '@defichain/testcontainers' import { ContainerAdapterClient } from '../../container_adapter_client' +import { addPoolLiquidity, createPoolPair, createToken, getNewAddress, mintTokens } from '@defichain/testing' describe('Poolpair', () => { const container = new MasterNodeRegTestContainer() const client = new ContainerAdapterClient(container) - let poolLiquidityAddress: string beforeAll(async () => { await container.start() await container.waitForReady() await container.waitForWalletCoinbaseMaturity() await container.waitForWalletBalanceGTE(200) - - await createToken('DDAI') - await mintTokens('DDAI') - await createPoolPair('DDAI') - await addPoolLiquidity() }) afterAll(async () => { await container.stop() }) - async function createToken (symbol: string): Promise { - const address = await container.call('getnewaddress') - const metadata = { - symbol, - name: symbol, - isDAT: true, - mintable: true, - tradeable: true, - collateralAddress: address - } - await container.call('createtoken', [metadata]) - await container.generate(1) - } - - async function createPoolPair (tokenB: string, metadata?: any): Promise { - const address = await container.call('getnewaddress') - const defaultMetadata = { - tokenA: 'DFI', - tokenB: 'DDAI', - commission: 0, - status: true, - ownerAddress: address - } - await client.poolpair.createPoolPair({ ...defaultMetadata, ...metadata }) - await container.generate(1) - } - - async function mintTokens (symbol: string): Promise { - const address = await container.call('getnewaddress') - const payload: { [key: string]: string } = {} - payload[address] = '100@0' - await container.call('utxostoaccount', [payload]) - await container.call('minttokens', [`2000@${symbol}`]) - await container.generate(1) - } - - async function addPoolLiquidity (): Promise { - const shareAddress = await container.call('getnewaddress') - const data = await client.poolpair.addPoolLiquidity({ - '*': ['10@DFI', '200@DDAI'] - }, shareAddress) - await container.generate(1) + it.only('should removeLiquidity', async () => { + const dogAddress = await getNewAddress(container) + const foxAddress = await getNewAddress(container) + // const poolPairAddress = await getNewAddress(container) + const poolLiquidityAddress = await getNewAddress(container) + + await createToken(container, 'DOG') + await mintTokens(container, 'DOG', { address: dogAddress }) + + await createToken(container, 'FOX') + await mintTokens(container, 'FOX', { address: foxAddress }) + const dogAccount = await container.call('getaccount', [dogAddress]) + console.log('dogAccount: ', dogAccount) + + await createPoolPair(container, 'DOG', 'FOX') + // const poolpairs = await container.call('listpoolpairs') + // console.log('poolpairs: ', poolpairs) + await addPoolLiquidity(container, { + tokenA: 'DOG', + amountA: 10, + tokenB: 'FOX', + amountB: 200, + shareAddress: poolLiquidityAddress + }) + // totalLiquidity = sqrt(10 * 200) = + // const dogAccountAfter = await container.call('getaccount', [dogAddress]) + // console.log('dogAccountAfter: ', dogAccountAfter) - expect(typeof data).toStrictEqual('string') - } + const poolLiquidityAccount = await container.call('getaccount', [poolLiquidityAddress]) + console.log('poolLiquidityAccountBefore: ', poolLiquidityAccount) - it('should removePoolLiquidity', async () => { const poolPairBefore = await container.call('listpoolpairs') - console.log('poolpairs: ', poolPairBefore) + console.log('poolPairBefore: ', poolPairBefore) + const totalLiquidityBefore = poolPairBefore['3'].totalLiquidity + const hash = await client.poolpair.removePoolLiquidity(poolLiquidityAddress, '13@DOG-FOX') - const totalLiquidityBefore = poolPairBefore['2'].totalLiquidity - - try { - await container.call('removepoolliquidity', [poolLiquidityAddress, '13@DFI-DDAI']) - await container.generate(1) - } catch (err) { - console.log('err: ', err) - } + expect(typeof hash).toStrictEqual('string') + expect(hash.length).toStrictEqual(64) + await container.generate(1) const poolPairAfter = await container.call('listpoolpairs') - console.log('poolpairs: ', poolPairAfter) - const totalLiquidityAfter = poolPairAfter['2'].totalLiquidity + console.log('poolPairAfter: ', poolPairAfter) + console.log('poolLiquidityAddress: ', poolLiquidityAddress) - // expect(poolPairAfter['2'].totalLiquidity - poolPairBefore['2'].totalLiquidity.toStrictEqual(13)) - expect(totalLiquidityBefore - totalLiquidityAfter).toStrictEqual(0) // 13 - }) + const poolLiquidityAccountAfter = await container.call('getaccount', [poolLiquidityAddress]) + console.log('poolLiquidityAccountAfter: ', poolLiquidityAccountAfter) - it('should fail while removePoolLiquidity with utxos which does not include account owner', async () => { - const shareAddress = await container.call('getnewaddress') - const tokenAAddress = await container.call('getnewaddress') - const tokenBAddress = await container.call('getnewaddress') - - const utxos = await container.call('listunspent') - const inputs = utxos.map((utxo: any) => { - return { - txid: utxo.txid, - vout: utxo.vout - } - }) + const dogAccountAfter = await container.call('getaccount', [dogAddress]) + const foxAccountAfter = await container.call('getaccount', [foxAddress]) + + console.log('dogAccountAfter: ', dogAccountAfter, foxAccountAfter) - const promise = client.poolpair.removePoolLiquidity({ - [tokenAAddress]: '10@DFI', - [tokenBAddress]: '200@DDAI' - }, shareAddress, { utxos: inputs }) + const totalLiquidityAfter = poolPairAfter['3'].totalLiquidity + console.log('totalLiquidityAfter: ', totalLiquidityAfter) + console.log('totalLiquidityDiff: ', totalLiquidityBefore - totalLiquidityAfter) - expect(typeof promise).toStrictEqual('object') + expect(totalLiquidityBefore - totalLiquidityAfter).toStrictEqual(13) }) + + // it('should removeLiquidity with utxos', async () => { + // const shareAddress = await container.call('getnewaddress') + // const tokenAAddress = await container.call('getnewaddress', '10@DDFI') + // const tokenBAddress = await container.call('getnewaddress', '200@DBTC') + // const utxos = await container.call('listunspent') + // await container.generate(1) + // + // const inputs = utxos.map((utxo: any) => { + // return { + // txid: utxo.txid, + // vout: utxo.vout + // } + // }) + // + // const hash = await client.poolpair.removePoolLiquidity({ + // [tokenAAddress]: '10@DOG', + // [tokenBAddress]: '200@FOX' + // }, shareAddress, { utxos: inputs }) + // + // expect(typeof hash).toStrictEqual('string') + // expect(hash.length).toStrictEqual(64) + // }) + + // it('fail as utxos does not include an account owner', async () => { + // const shareAddress = await container.call('getnewaddress') + // const tokenAAddress = await container.call('getnewaddress') + // const tokenBAddress = await container.call('getnewaddress') + // const utxos = await container.call('listunspent') + // + // const inputs = utxos.map((utxo: any) => { + // return { + // txid: utxo.txid, + // vout: utxo.vout + // } + // }) + // + // const hash = await client.poolpair.removePoolLiquidity({ + // [tokenAAddress]: '10@DOG', + // [tokenBAddress]: '200@FOX' + // }, shareAddress, { utxos: inputs }) + // + // expect(typeof hash).rejects.toThrow('tx must have at least one input from account owner') + // }) }) diff --git a/packages/jellyfish-api-core/src/category/poolpair.ts b/packages/jellyfish-api-core/src/category/poolpair.ts index d3f0b6b4d9..bfa7a4be6c 100644 --- a/packages/jellyfish-api-core/src/category/poolpair.ts +++ b/packages/jellyfish-api-core/src/category/poolpair.ts @@ -124,9 +124,8 @@ export class PoolPair { /** * Remove pool liquidity transaction * - * @param {RemovePoolLiquiditySource} from pool liquidity sources - * @param {string | string[]} from[address] provides at least two types of token with format 'amoun@token' - * @param {string} shareAddress defi address for crediting tokens + * @param {string} address defi address for crediting tokens + * @param {string} poolAccount pool liquidity account of owner * @param {RemovePoolLiquidityOptions} [options] * @param {RemovePoolLiquidityUTXO[]} [options.utxos] utxos array of specific UTXOs to spend * @param {string} [options.utxos.txid] diff --git a/website/docs/jellyfish/api/poolpair.md b/website/docs/jellyfish/api/poolpair.md index d61980758a..1c89b31a03 100644 --- a/website/docs/jellyfish/api/poolpair.md +++ b/website/docs/jellyfish/api/poolpair.md @@ -161,25 +161,6 @@ interface PoolShareOptions { } ``` -## removePoolLiquidity - -Remove pool liquidity transaction - -```ts title="client.poolpair.addPoolLiquidity()" -interface poolpair { - removePoolLiquidity (from: removePoolLiquiditySource, shareAddress: string, options: removePoolLiquidityOptions = {}): Promise -} - -interface RemovePoolLiquidityOptions { - utxos?: RemovePoolLiquidityUTXO[] -} - -interface RemovePoolLiquidityUTXO { - txid: string - vout: number -} -``` - ## testPoolSwap Create a test pool swap transaction to check pool swap's return result