Skip to content

Commit

Permalink
Extend createDeFiTx
Browse files Browse the repository at this point in the history
  • Loading branch information
marktanrj committed Dec 1, 2022
1 parent 256e3ef commit ae7b3e5
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 6 deletions.
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import BigNumber from 'bignumber.js'
import { MasterNodeRegTestContainer } from '@defichain/testcontainers'
import { getProviders, MockProviders } from '../provider.mock'
import { P2WPKHTxnBuilder } from '../../src'
import { P2WPKHTxnBuilder, Prevout } from '../../src'
import { fundEllipticPair } from '../test.utils'
import { CDfTx, DeFiOpUnmapped, OP_CODES, OP_DEFI_TX } from '@defichain/jellyfish-transaction'
import { CDfTx, DeFiOpUnmapped, OP_CODES, OP_DEFI_TX, Vin, Vout } from '@defichain/jellyfish-transaction'
import { RegTest } from '@defichain/jellyfish-network'

// P2WPKHTxnBuilder is abstract and not instantiable
Expand Down Expand Up @@ -92,4 +92,46 @@ describe('createDeFiTx()', () => {
expect(result.vout[1].value.gt(new BigNumber(99.999).minus(spendAmount))).toBeTruthy()
expect(result.vout[1].value.lt(new BigNumber(100).minus(spendAmount))).toBeTruthy()
})

it('should create DfTx stack correctly with custom vin and vout', async () => {
const script = await providers.elliptic.script()

const collateralPrevout: Prevout = {
txid: '1111111122222222333333334444444455555555666666667777777788888888',
vout: 0,
script: script,
value: new BigNumber(15),
tokenId: 0
}
const collateralVout: Vout = {
script: script,
value: new BigNumber(15),
tokenId: 0
}
const collateralVin: Vin = {
txid: '1111111122222222333333334444444455555555666666667777777788888888',
index: 1,
script: { stack: [] },
sequence: 0xffffffff
}
const customVinVout = {
prevout: collateralPrevout,
vin: collateralVin,
vout: collateralVout
}

const result = await builder.createDeFiTx(dummyDfTx, script, undefined, [customVinVout])

expect(result.vin.length).toStrictEqual(8)
expect(result.vout.length).toStrictEqual(3)

expect(result.vout[0].value).toStrictEqual(new BigNumber(0))
expect(result.vout[1]).toStrictEqual(expect.objectContaining({
value: new BigNumber(15),
script: script
}))
expect(result.vout[2].value.gt(99.999)).toBeTruthy()
expect(result.vout[2].value.lt(100)).toBeTruthy()
expect(result.vout[2].script).toStrictEqual(script)
})
})
16 changes: 12 additions & 4 deletions packages/jellyfish-transaction-builder/src/txn/txn_builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,8 @@ export abstract class P2WPKHTxnBuilder {
* Craft a transaction with OP_DEFI_TX from the output of OP_CODES.OP_DEFI_TX_.
* This is a helper method for creating custom defi transactions.
*
* Optionally, allow for custom inputs with vin and vout.
*
* As DeFi custom transaction will always require small amount of DFI,
* collectPrevouts() is set to search for at least 0.001 DFI amount of prevout.
* This will also evidently merge small prevout during the operation.
Expand All @@ -98,15 +100,21 @@ export abstract class P2WPKHTxnBuilder {
* @param {OP_DEFI_TX} opDeFiTx to create
* @param {Script} changeScript to send unspent to after deducting the fees
* @param {BigNumber} [outValue=0] for the opDeFiTx, usually always be 0.
* @param {Array<{ vin: Vin, vout: Vout, prevout: Prevout }>} [customVinVout = []] for custom vin and vout
*/
async createDeFiTx (
opDeFiTx: OP_DEFI_TX,
changeScript: Script,
outValue: BigNumber = new BigNumber('0')
outValue: BigNumber = new BigNumber('0'),
customVinVout: Array<{ vin: Vin, vout: Vout, prevout: Prevout }> = []
): Promise<TransactionSegWit> {
const minFee = outValue.plus(0.001) // see JSDoc above
const { prevouts, vin, total } = await this.collectPrevouts(minFee)

const customVins = customVinVout.map(({ vin }) => vin)
const customPrevouts = customVinVout.map(({ prevout }) => prevout)
const customVouts = customVinVout.map(({ vout }) => vout)

const deFiOut: Vout = {
value: outValue,
script: {
Expand All @@ -123,15 +131,15 @@ export abstract class P2WPKHTxnBuilder {

const txn: Transaction = {
version: DeFiTransactionConstants.Version,
vin: vin,
vout: [deFiOut, change],
vin: [...vin, ...customVins],
vout: [deFiOut, ...customVouts, change],
lockTime: 0x00000000
}

const fee = await this.calculateFee(txn)
change.value = total.minus(outValue).minus(fee)

return await this.sign(txn, prevouts)
return await this.sign(txn, [...prevouts, ...customPrevouts])
}

/**
Expand Down

0 comments on commit ae7b3e5

Please sign in to comment.