From b8241589dff79198edbf4662c12577df5b16076e Mon Sep 17 00:00:00 2001 From: tim Date: Mon, 19 Jun 2017 13:27:39 +0200 Subject: [PATCH] fulfills.txid => fulfills.transaction_id + tests --- src/transaction/makeCreateTransaction.js | 2 + src/transaction/makeTransferTransaction.js | 49 +++++++++++----- test/transaction/test_transaction.js | 68 +++++++++++++++++++++- 3 files changed, 102 insertions(+), 17 deletions(-) diff --git a/src/transaction/makeCreateTransaction.js b/src/transaction/makeCreateTransaction.js index 8b259de..cc2d6d8 100644 --- a/src/transaction/makeCreateTransaction.js +++ b/src/transaction/makeCreateTransaction.js @@ -21,6 +21,8 @@ import makeTransaction from './makeTransaction' * @returns {object} Unsigned transaction -- make sure to call signTransaction() on it before * sending it off! */ +// TODO: `outputs` should throw or include output in array if no array was +// passed export default function makeCreateTransaction(asset, metadata, outputs, ...issuers) { const assetDefinition = { 'data': asset || null, diff --git a/src/transaction/makeTransferTransaction.js b/src/transaction/makeTransferTransaction.js index 5fbf228..b1a217f 100644 --- a/src/transaction/makeTransferTransaction.js +++ b/src/transaction/makeTransferTransaction.js @@ -2,6 +2,32 @@ import makeInputTemplate from './makeInputTemplate' import makeTransaction from './makeTransaction' +// TODO: Can we remove `export` here somehow, but still be able to import the +// function for tests? +export function _makeTransferTransaction( + unspentTransaction, + metadata, + outputs, + ...fulfilledOutputs + ) { + const inputs = fulfilledOutputs.map((outputIndex) => { + const fulfilledOutput = unspentTransaction.outputs[outputIndex] + const transactionLink = { + 'output': outputIndex, + 'transaction_id': unspentTransaction.id, + } + + return makeInputTemplate(fulfilledOutput.public_keys, transactionLink) + }) + + const assetLink = { + 'id': unspentTransaction.operation === 'CREATE' ? unspentTransaction.id + : unspentTransaction.asset.id + } + + return ['TRANSFER', assetLink, metadata, outputs, inputs] +} + /** * @public * Generate a `TRANSFER` transaction holding the `asset`, `metadata`, and `outputs`, that fulfills @@ -22,26 +48,17 @@ import makeTransaction from './makeTransaction' * @returns {object} Unsigned transaction -- make sure to call signTransaction() on it before * sending it off! */ + +// TODO: +// - Make `metadata` optional argument +// - Rename `fulfilledOutputs`, e.g. inputs +// TODO: `outputs` should throw or include output in array if no array was +// passed export default function makeTransferTransaction( unspentTransaction, metadata, outputs, ...fulfilledOutputs ) { - const inputs = fulfilledOutputs.map((outputIndex) => { - const fulfilledOutput = unspentTransaction.outputs[outputIndex] - const transactionLink = { - 'output': outputIndex, - 'transaction_id': unspentTransaction.id, - } - - return makeInputTemplate(fulfilledOutput.public_keys, transactionLink) - }) - - const assetLink = { - 'id': unspentTransaction.operation === 'CREATE' ? unspentTransaction.id - : unspentTransaction.asset.id - } - - return makeTransaction('TRANSFER', assetLink, metadata, outputs, inputs) + return makeTransaction(..._makeTransferTransaction(...arguments)) } diff --git a/test/transaction/test_transaction.js b/test/transaction/test_transaction.js index f23d110..0999005 100644 --- a/test/transaction/test_transaction.js +++ b/test/transaction/test_transaction.js @@ -1,5 +1,27 @@ import test from 'ava' -import { Transaction } from '../../src' +import { Transaction, Ed25519Keypair } from '../../src' +import { _makeTransferTransaction } from '../../src/transaction/makeTransferTransaction' +import makeInputTemplate from '../../src/transaction/makeInputTemplate' + + +// TODO: Find out if ava has something like conftest, if so put this there. +const alice = new Ed25519Keypair() +const aliceCondition = Transaction.makeEd25519Condition(alice.publicKey) +const aliceOutput = Transaction.makeOutput(aliceCondition) +const assetMessage = { assetMessage: 'assetMessage' } +const metaDataMessage = { metaDataMessage: 'metaDataMessage' } +const createTx = Transaction.makeCreateTransaction( + assetMessage, + metaDataMessage, + [aliceOutput], + alice.publicKey +) +const transferTx = Transaction.makeTransferTransaction( + createTx, + metaDataMessage, + [aliceOutput], + 0 +) test('Create valid output with default amount', t => { @@ -53,3 +75,47 @@ test('Pass condition not based on public_keys to makeOutput', t => { test('makeOutput throws TypeError with incorrect amount type', t => { t.throws(() => Transaction.makeOutput({}, 1337), TypeError) }) + + +test('Create TRANSFER transaction based on CREATE transaction', t => { + const testTx = _makeTransferTransaction( + createTx, + metaDataMessage, + [aliceOutput], + 0 + ) + const expected = [ + 'TRANSFER', + {id: createTx.id }, + metaDataMessage, + [aliceOutput], + [makeInputTemplate( + [alice.publicKey], + { output: 0, transaction_id: createTx.id } + )] + ] + + t.deepEqual(testTx, expected) +}) + + +test('Create TRANSFER transaction based on TRANSFER transaction', t => { + const testTx = _makeTransferTransaction( + transferTx, + metaDataMessage, + [aliceOutput], + 0 + ) + const expected = [ + 'TRANSFER', + { id: transferTx.asset.id }, + metaDataMessage, + [aliceOutput], + [makeInputTemplate( + [alice.publicKey], + { output: 0, transaction_id: transferTx.id } + )] + ] + + t.deepEqual(testTx, expected) +})