From 3feb01fa8653890ae77820b883af7171b695c075 Mon Sep 17 00:00:00 2001 From: Fuxing Loh Date: Tue, 20 Apr 2021 13:16:23 +0800 Subject: [PATCH 1/4] refactor dftx_pool.test.ts to PoolSwap.test.ts --- .../__tests__/script/defi/dftx_pool.test.ts | 75 ------------------- .../script/defi/dftx_pool/PoolSwap.test.ts | 73 ++++++++++++++++++ 2 files changed, 73 insertions(+), 75 deletions(-) delete mode 100644 packages/jellyfish-transaction/__tests__/script/defi/dftx_pool.test.ts create mode 100644 packages/jellyfish-transaction/__tests__/script/defi/dftx_pool/PoolSwap.test.ts diff --git a/packages/jellyfish-transaction/__tests__/script/defi/dftx_pool.test.ts b/packages/jellyfish-transaction/__tests__/script/defi/dftx_pool.test.ts deleted file mode 100644 index 821d0df9d7..0000000000 --- a/packages/jellyfish-transaction/__tests__/script/defi/dftx_pool.test.ts +++ /dev/null @@ -1,75 +0,0 @@ -import { SmartBuffer } from 'smart-buffer' -import { CPoolSwap, PoolSwap } from '../../../src/script/defi/dftx_pool' -import { OP_CODES, toBuffer, toOPCodes } from '../../../src/script' -import BigNumber from 'bignumber.js' - -it('should bi-directional buffer-object-buffer', () => { - const fixtures = [ - '6a4c4f446654787317a914c34ca9c54dc87e7e875b212ec6ba0704be3de587870000d6117e0300000017a914c34ca9c54dc87e7e875b212ec6ba0704be3de5878702ffffffffffffff7fffffffffffffff7f', - '6a4c4f446654787317a914635794bb3db157b6dac4dcb7467710a10f03c6ac8700809698000000000017a914582328ee9beebc3fb5844964302cc0fdbb27e04c8702ffffffffffffff7fffffffffffffff7f', - '6a4c4f446654787317a9148646fc3d44c92e190c18db1cf08f430e421dba9887005671518a0000000017a9148646fc3d44c92e190c18db1cf08f430e421dba988707a0860100000000000000000000000000' - ] - - fixtures.forEach(hex => { - const stack = toOPCodes( - SmartBuffer.fromBuffer(Buffer.from(hex, 'hex')) - ) - const buffer = toBuffer(stack) - expect(buffer.toString('hex')).toBe(hex) - }) -}) - -describe('PoolSwap', () => { - const header = '6a4c4f4466547873' // OP_RETURN, PUSH_DATA(44665478, 73) - const data = '17a914c34ca9c54dc87e7e875b212ec6ba0704be3de587870000d6117e0300000017a914c34ca9c54dc87e7e875b212ec6ba0704be3de5878702ffffffffffffff7fffffffffffffff7f' - const poolSwap: PoolSwap = { - fromAmount: new BigNumber(150), - fromScript: { - stack: [ - OP_CODES.OP_HASH160, - OP_CODES.OP_PUSHDATA_HEX_LE('c34ca9c54dc87e7e875b212ec6ba0704be3de587'), - OP_CODES.OP_EQUAL - ] - }, - fromTokenId: 0, - toTokenId: 2, - toScript: { - stack: [ - OP_CODES.OP_HASH160, - OP_CODES.OP_PUSHDATA_HEX_LE('c34ca9c54dc87e7e875b212ec6ba0704be3de587'), - OP_CODES.OP_EQUAL - ] - }, - maxPrice: { - integer: new BigNumber('9223372036854775807'), - fraction: new BigNumber('9223372036854775807') - } - } - - it('should craft dftx with OP_CODES.OP_DEFI_TX_POOL_SWAP', () => { - const stack = [ - OP_CODES.OP_RETURN, - OP_CODES.OP_DEFI_TX_POOL_SWAP(poolSwap) - ] - - const buffer = toBuffer(stack) - expect(buffer.toString('hex')).toBe(header + data) - }) - - describe('CPoolSwap', () => { - it('should compose from buffer to poolswap', () => { - const buffer = SmartBuffer.fromBuffer(Buffer.from(data, 'hex')) - const cPoolSwap = new CPoolSwap(buffer) - - expect(cPoolSwap.toObject()).toEqual(poolSwap) - }) - - it('should compose from poolswap to buffer', () => { - const cPoolSwap = new CPoolSwap(poolSwap) - const buffer = new SmartBuffer() - cPoolSwap.toBuffer(buffer) - - expect(buffer.toBuffer().toString('hex')).toEqual(data) - }) - }) -}) diff --git a/packages/jellyfish-transaction/__tests__/script/defi/dftx_pool/PoolSwap.test.ts b/packages/jellyfish-transaction/__tests__/script/defi/dftx_pool/PoolSwap.test.ts new file mode 100644 index 0000000000..a7f76bb613 --- /dev/null +++ b/packages/jellyfish-transaction/__tests__/script/defi/dftx_pool/PoolSwap.test.ts @@ -0,0 +1,73 @@ +import { SmartBuffer } from 'smart-buffer' +import { CPoolSwap, PoolSwap } from '../../../../src/script/defi/dftx_pool' +import { OP_CODES, toBuffer, toOPCodes } from '../../../../src/script' +import BigNumber from 'bignumber.js' + +it('should bi-directional buffer-object-buffer', () => { + const fixtures = [ + '6a4c4f446654787317a914c34ca9c54dc87e7e875b212ec6ba0704be3de587870000d6117e0300000017a914c34ca9c54dc87e7e875b212ec6ba0704be3de5878702ffffffffffffff7fffffffffffffff7f', + '6a4c4f446654787317a914635794bb3db157b6dac4dcb7467710a10f03c6ac8700809698000000000017a914582328ee9beebc3fb5844964302cc0fdbb27e04c8702ffffffffffffff7fffffffffffffff7f', + '6a4c4f446654787317a9148646fc3d44c92e190c18db1cf08f430e421dba9887005671518a0000000017a9148646fc3d44c92e190c18db1cf08f430e421dba988707a0860100000000000000000000000000' + ] + + fixtures.forEach(hex => { + const stack = toOPCodes( + SmartBuffer.fromBuffer(Buffer.from(hex, 'hex')) + ) + const buffer = toBuffer(stack) + expect(buffer.toString('hex')).toBe(hex) + }) +}) + +const header = '6a4c4f4466547873' // OP_RETURN, PUSH_DATA(44665478, 73) +const data = '17a914c34ca9c54dc87e7e875b212ec6ba0704be3de587870000d6117e0300000017a914c34ca9c54dc87e7e875b212ec6ba0704be3de5878702ffffffffffffff7fffffffffffffff7f' +const poolSwap: PoolSwap = { + fromAmount: new BigNumber(150), + fromScript: { + stack: [ + OP_CODES.OP_HASH160, + OP_CODES.OP_PUSHDATA_HEX_LE('c34ca9c54dc87e7e875b212ec6ba0704be3de587'), + OP_CODES.OP_EQUAL + ] + }, + fromTokenId: 0, + toTokenId: 2, + toScript: { + stack: [ + OP_CODES.OP_HASH160, + OP_CODES.OP_PUSHDATA_HEX_LE('c34ca9c54dc87e7e875b212ec6ba0704be3de587'), + OP_CODES.OP_EQUAL + ] + }, + maxPrice: { + integer: new BigNumber('9223372036854775807'), + fraction: new BigNumber('9223372036854775807') + } +} + +it('should craft dftx with OP_CODES.OP_DEFI_TX_POOL_SWAP', () => { + const stack = [ + OP_CODES.OP_RETURN, + OP_CODES.OP_DEFI_TX_POOL_SWAP(poolSwap) + ] + + const buffer = toBuffer(stack) + expect(buffer.toString('hex')).toBe(header + data) +}) + +describe('Composable', () => { + it('should compose from buffer to poolswap', () => { + const buffer = SmartBuffer.fromBuffer(Buffer.from(data, 'hex')) + const composable = new CPoolSwap(buffer) + + expect(composable.toObject()).toEqual(poolSwap) + }) + + it('should compose from poolswap to buffer', () => { + const composable = new CPoolSwap(poolSwap) + const buffer = new SmartBuffer() + composable.toBuffer(buffer) + + expect(buffer.toBuffer().toString('hex')).toEqual(data) + }) +}) From 1bf705273a16d16ed817446a5c99bd1642a8a6da Mon Sep 17 00:00:00 2001 From: Fuxing Loh Date: Tue, 20 Apr 2021 13:43:58 +0800 Subject: [PATCH 2/4] added PoolAddLiquidity dftx --- .../defi/dftx_pool/PoolAddLiquidity.test.ts | 76 +++++++++++++++++++ .../script/defi/dftx_pool/PoolSwap.test.ts | 10 ++- .../src/script/defi/dftx.ts | 4 +- .../src/script/defi/dftx_pool.ts | 62 ++++++++++++++- .../src/script/mapping.ts | 15 +++- 5 files changed, 162 insertions(+), 5 deletions(-) create mode 100644 packages/jellyfish-transaction/__tests__/script/defi/dftx_pool/PoolAddLiquidity.test.ts diff --git a/packages/jellyfish-transaction/__tests__/script/defi/dftx_pool/PoolAddLiquidity.test.ts b/packages/jellyfish-transaction/__tests__/script/defi/dftx_pool/PoolAddLiquidity.test.ts new file mode 100644 index 0000000000..30d986a54c --- /dev/null +++ b/packages/jellyfish-transaction/__tests__/script/defi/dftx_pool/PoolAddLiquidity.test.ts @@ -0,0 +1,76 @@ +import { SmartBuffer } from 'smart-buffer' +import { CPoolAddLiquidity, PoolAddLiquidity } from '../../../../src/script/defi/dftx_pool' +import { OP_CODES, toBuffer, toOPCodes } from '../../../../src/script' +import BigNumber from 'bignumber.js' + +it('should bi-directional buffer-object-buffer', () => { + const fixtures = [ + '6a4c4f446654786c0117a914055f1a204428e2a826f7555bb1194cb5ea44ce74870200000000d2956e220000000002000000c68900000000000017a914055f1a204428e2a826f7555bb1194cb5ea44ce7487', + '6a4c53446654786c011976a9147742abf9be1e2a9e42d665faf9c982c65f41315988ac0200000000fb3f0000000000000200000001000000000000001976a9147742abf9be1e2a9e42d665faf9c982c65f41315988ac', + '6a4c53446654786c011976a9147742abf9be1e2a9e42d665faf9c982c65f41315988ac0200000000d6ff0100000000000200000008000000000000001976a9147742abf9be1e2a9e42d665faf9c982c65f41315988ac' + ] + + fixtures.forEach(hex => { + const stack = toOPCodes( + SmartBuffer.fromBuffer(Buffer.from(hex, 'hex')) + ) + const buffer = toBuffer(stack) + expect(buffer.toString('hex')).toBe(hex) + }) +}) + +const header = '6a4c4f446654786c' // OP_RETURN, PUSH_DATA(44665478, 6c) +const data = '0117a914055f1a204428e2a826f7555bb1194cb5ea44ce74870200000000d2956e220000000002000000c68900000000000017a914055f1a204428e2a826f7555bb1194cb5ea44ce7487' +const poolAddLiquidity: PoolAddLiquidity = { + from: [{ + balances: [ + { + amount: new BigNumber('5.77672658'), token: 0 + }, + { + amount: new BigNumber('0.0003527'), token: 2 + } + ], + script: { + stack: [ + OP_CODES.OP_HASH160, + OP_CODES.OP_PUSHDATA_HEX_LE('055f1a204428e2a826f7555bb1194cb5ea44ce74'), + OP_CODES.OP_EQUAL + ] + } + }], + shareAddress: { + stack: [ + OP_CODES.OP_HASH160, + OP_CODES.OP_PUSHDATA_HEX_LE('055f1a204428e2a826f7555bb1194cb5ea44ce74'), + OP_CODES.OP_EQUAL + ] + } +} + +it('should craft dftx with OP_CODES.OP_DEFI_TX_POOL_SWAP', () => { + const stack = [ + OP_CODES.OP_RETURN, + OP_CODES.OP_DEFI_TX_POOL_ADD_LIQUIDITY(poolAddLiquidity) + ] + + const buffer = toBuffer(stack) + expect(buffer.toString('hex')).toBe(header + data) +}) + +describe('Composable', () => { + it('should compose from buffer to poolswap', () => { + const buffer = SmartBuffer.fromBuffer(Buffer.from(data, 'hex')) + const composable = new CPoolAddLiquidity(buffer) + + expect(composable.toObject()).toEqual(poolAddLiquidity) + }) + + it('should compose from poolswap to buffer', () => { + const composable = new CPoolAddLiquidity(poolAddLiquidity) + const buffer = new SmartBuffer() + composable.toBuffer(buffer) + + expect(buffer.toBuffer().toString('hex')).toEqual(data) + }) +}) diff --git a/packages/jellyfish-transaction/__tests__/script/defi/dftx_pool/PoolSwap.test.ts b/packages/jellyfish-transaction/__tests__/script/defi/dftx_pool/PoolSwap.test.ts index a7f76bb613..64cf5c4f20 100644 --- a/packages/jellyfish-transaction/__tests__/script/defi/dftx_pool/PoolSwap.test.ts +++ b/packages/jellyfish-transaction/__tests__/script/defi/dftx_pool/PoolSwap.test.ts @@ -2,12 +2,19 @@ import { SmartBuffer } from 'smart-buffer' import { CPoolSwap, PoolSwap } from '../../../../src/script/defi/dftx_pool' import { OP_CODES, toBuffer, toOPCodes } from '../../../../src/script' import BigNumber from 'bignumber.js' +import { OP_DEFI_TX } from '../../../../src/script/defi' it('should bi-directional buffer-object-buffer', () => { const fixtures = [ '6a4c4f446654787317a914c34ca9c54dc87e7e875b212ec6ba0704be3de587870000d6117e0300000017a914c34ca9c54dc87e7e875b212ec6ba0704be3de5878702ffffffffffffff7fffffffffffffff7f', '6a4c4f446654787317a914635794bb3db157b6dac4dcb7467710a10f03c6ac8700809698000000000017a914582328ee9beebc3fb5844964302cc0fdbb27e04c8702ffffffffffffff7fffffffffffffff7f', - '6a4c4f446654787317a9148646fc3d44c92e190c18db1cf08f430e421dba9887005671518a0000000017a9148646fc3d44c92e190c18db1cf08f430e421dba988707a0860100000000000000000000000000' + '6a4c4f446654787317a9148646fc3d44c92e190c18db1cf08f430e421dba9887005671518a0000000017a9148646fc3d44c92e190c18db1cf08f430e421dba988707a0860100000000000000000000000000', + '6a4c4f446654787317a9140c1ff6de17f73dad607a2b03b5bd77b4e57327e58707d3e2a0470000000017a9140c1ff6de17f73dad607a2b03b5bd77b4e57327e58700ffffffffffffff7fffffffffffffff7f', + '6a4c4f446654787317a914094b5e971325dee0161beccc7a78592f95c27100870080397a120000000017a914094b5e971325dee0161beccc7a78592f95c271008702ffffffffffffff7fffffffffffffff7f', + '6a4c4f446654787317a914f64714403dd1b872494851ca4ed8d5071af79ea6870087b4104d0200000017a914f64714403dd1b872494851ca4ed8d5071af79ea68707a0860100000000000000000000000000', + '6a4c5144665478731976a9140b7127e943eaa3f28536c3f046ddbdeb790f691e88ac0080889e2a0100000017a914b3a65aa3fd9c60860bebd231d71b5bc5749ff5be8702ffffffffffffff7fffffffffffffff7f', + '6a4c4f446654787317a9140164e31629342622b35bc134c8e4fe7c45c42e43870205fd0b030000000017a9140164e31629342622b35bc134c8e4fe7c45c42e438700ffffffffffffff7fffffffffffffff7f', + '6a4c4f446654787317a914963a12667d64728009567ad5eb26777e1673c479870000db7d2e0000000017a914963a12667d64728009567ad5eb26777e1673c4798702ffffffffffffff7fffffffffffffff7f' ] fixtures.forEach(hex => { @@ -16,6 +23,7 @@ it('should bi-directional buffer-object-buffer', () => { ) const buffer = toBuffer(stack) expect(buffer.toString('hex')).toBe(hex) + expect((stack[1] as OP_DEFI_TX).tx.type).toBe(0x73) }) }) diff --git a/packages/jellyfish-transaction/src/script/defi/dftx.ts b/packages/jellyfish-transaction/src/script/defi/dftx.ts index 3f9c687fc6..65927b86f9 100644 --- a/packages/jellyfish-transaction/src/script/defi/dftx.ts +++ b/packages/jellyfish-transaction/src/script/defi/dftx.ts @@ -1,7 +1,7 @@ import { SmartBuffer } from 'smart-buffer' import { BufferComposer, ComposableBuffer } from '../../buffer/buffer_composer' import { - CPoolSwap, + CPoolAddLiquidity, CPoolSwap, PoolAddLiquidity, PoolSwap } from './dftx_pool' import { CDeFiOpUnmapped, DeFiOpUnmapped } from './dftx_unmapped' @@ -83,6 +83,8 @@ export class CDfTx extends ComposableBuffer> { switch (dftx.type) { case CPoolSwap.OP_CODE: return compose(CPoolSwap.OP_NAME, d => new CPoolSwap(d)) + case CPoolAddLiquidity.OP_CODE: + return compose(CPoolAddLiquidity.OP_NAME, d => new CPoolAddLiquidity(d)) default: return compose(CDeFiOpUnmapped.OP_NAME, d => new CDeFiOpUnmapped(d)) } diff --git a/packages/jellyfish-transaction/src/script/defi/dftx_pool.ts b/packages/jellyfish-transaction/src/script/defi/dftx_pool.ts index f9ba7053da..16326b4bf9 100644 --- a/packages/jellyfish-transaction/src/script/defi/dftx_pool.ts +++ b/packages/jellyfish-transaction/src/script/defi/dftx_pool.ts @@ -8,7 +8,7 @@ import { SmartBuffer } from 'smart-buffer' /* eslint-disable no-return-assign */ /** - * A poolswap transaction. + * PoolSwap DeFi Transaction */ export interface PoolSwap { fromScript: Script // ----------------| n = VarUInt{1-9 bytes}, + n bytes @@ -52,3 +52,63 @@ export class CPoolSwap extends ComposableBuffer { ] } } + +/** + * PoolAddLiquidity DeFi Transaction + */ +export interface PoolAddLiquidity { + from: ScriptBalances[] // ------------| c = VarUInt{1-9 bytes}, + c x ScriptBalances + shareAddress: Script // --------------| n = VarUInt{1-9 bytes}, + n bytes +} + +export interface ScriptBalances { + script: Script // --------------------| n = VarUInt{1-9 bytes}, + n bytes + balances: TokenBalance[] // ----------| c = VarUInt{1-9 bytes}, + c x TokenBalance +} + +export interface TokenBalance { + token: number // ---------------------| 4 bytes unsigned + amount: BigNumber // -----------------| 8 bytes unsigned +} + +/** + * Composable PoolAddLiquidity, C stands for Composable. + * Immutable by design, bi-directional fromBuffer, toBuffer deep composer. + */ +export class CPoolAddLiquidity extends ComposableBuffer { + static OP_CODE = 0x6c + static OP_NAME = 'DEFI_OP_POOL_ADD_LIQUIDITY' + + composers (p: PoolAddLiquidity): BufferComposer[] { + return [ + ComposableBuffer.varUIntArray(() => p.from, v => p.from = v, v => new CScriptBalances(v)), + ComposableBuffer.single