diff --git a/src/baseRequest.js b/src/baseRequest.js index 90ce3b26..b4b6d388 100644 --- a/src/baseRequest.js +++ b/src/baseRequest.js @@ -37,7 +37,9 @@ const fetch = fetchPonyfill(Promise) * @return {Promise} Promise that will resolve with the response if its status was 2xx; * otherwise rejects with the response */ -export default function baseRequest(url, { jsonBody, query, urlTemplateSpec, ...fetchConfig } = {}) { +export default function baseRequest(url, { + jsonBody, query, urlTemplateSpec, ...fetchConfig +} = {}) { let expandedUrl = url if (urlTemplateSpec != null) { diff --git a/src/format_text.js b/src/format_text.js index 63bb5edc..38f697ae 100644 --- a/src/format_text.js +++ b/src/format_text.js @@ -84,9 +84,7 @@ export default function formatText(s, ...argv) { // If there's anything left to interpolate by the end then we've failed to interpolate // the entire replacement string. if (interpolationLeft.length) { - throw new SyntaxError( - `[formatText] failed to parse named argument key: ${replacement}` - ) + throw new SyntaxError(`[formatText] failed to parse named argument key: ${replacement}`) } return value diff --git a/src/index.js b/src/index.js index 96b539cb..bbc98ee2 100644 --- a/src/index.js +++ b/src/index.js @@ -1,5 +1,6 @@ - export Ed25519Keypair from './Ed25519Keypair' -export * as Transaction from './transaction' export Connection from './connection' +export Transaction from './transaction' +export ccJsonLoad from './utils/ccJsonLoad' +export ccJsonify from './utils/ccJsonify' diff --git a/src/transaction.js b/src/transaction.js new file mode 100644 index 00000000..f84cf4c9 --- /dev/null +++ b/src/transaction.js @@ -0,0 +1,260 @@ +import { Buffer } from 'buffer' +import stableStringify from 'json-stable-stringify' +import clone from 'clone' +import base58 from 'bs58' +import cc from 'crypto-conditions' +import ccJsonify from './utils/ccJsonify' +import sha256Hash from './sha256Hash' + +export default class Transaction { + /** + * @public + * Canonically serializes a transaction into a string by sorting the keys + * @param {object} (transaction) + * @return {string} a canonically serialized Transaction + */ + static serializeTransactionIntoCanonicalString(transaction) { + // BigchainDB signs fulfillments by serializing transactions into a + // "canonical" format where + const tx = clone(transaction) + // TODO: set fulfillments to null + // Sort the keys + return stableStringify(tx, (a, b) => (a.key > b.key ? 1 : -1)) + } + + static makeInputTemplate(publicKeys = [], fulfills = null, fulfillment = null) { + return { + fulfillment, + fulfills, + 'owners_before': publicKeys, + } + } + + static hashTransaction(transaction) { + // Safely remove any tx id from the given transaction for hashing + const tx = { ...transaction } + delete tx.id + + return sha256Hash(Transaction.serializeTransactionIntoCanonicalString(tx)) + } + + static makeTransactionTemplate() { + const txTemplate = { + 'id': null, + 'operation': null, + 'outputs': [], + 'inputs': [], + 'metadata': null, + 'asset': null, + 'version': '1.0', + } + return txTemplate + } + + static makeTransaction(operation, asset, metadata = null, outputs = [], inputs = []) { + const tx = Transaction.makeTransactionTemplate() + tx.operation = operation + tx.asset = asset + tx.metadata = metadata + tx.inputs = inputs + tx.outputs = outputs + + tx.id = Transaction.hashTransaction(tx) + return tx + } + + /** + * @public + * Generate a `CREATE` transaction holding the `asset`, `metadata`, and `outputs`, to be signed by + * the `issuers`. + * @param {object} asset Created asset's data + * @param {object} metadata Metadata for the Transaction + * @param {object[]} outputs Array of Output objects to add to the Transaction. + * Think of these as the recipients of the asset after the transaction. + * For `CREATE` Transactions, this should usually just be a list of + * Outputs wrapping Ed25519 Conditions generated from the issuers' public + * keys (so that the issuers are the recipients of the created asset). + * @param {...string[]} issuers Public key of one or more issuers to the asset being created by this + * Transaction. + * Note: Each of the private keys corresponding to the given public + * keys MUST be used later (and in the same order) when signing the + * Transaction (`signTransaction()`). + * @returns {object} Unsigned transaction -- make sure to call signTransaction() on it before + * sending it off! + */ + static makeCreateTransaction(asset, metadata, outputs, ...issuers) { + const assetDefinition = { + 'data': asset || null, + } + const inputs = issuers.map((issuer) => Transaction.makeInputTemplate([issuer])) + + return Transaction.makeTransaction('CREATE', assetDefinition, metadata, outputs, inputs) + } + + /** + * @public + * Create an Ed25519 Cryptocondition from an Ed25519 public key + * to put into an Output of a Transaction + * @param {string} publicKey base58 encoded Ed25519 public key for the recipient of the Transaction + * @param {boolean} [json=true] If true returns a json object otherwise a crypto-condition type + * @returns {object} Ed25519 Condition (that will need to wrapped in an Output) + */ + static makeEd25519Condition(publicKey, json = true) { + const publicKeyBuffer = Buffer.from(base58.decode(publicKey)) + + const ed25519Fulfillment = new cc.Ed25519Sha256() + ed25519Fulfillment.setPublicKey(publicKeyBuffer) + + if (json) { + return ccJsonify(ed25519Fulfillment) + } + + return ed25519Fulfillment + } + + /** + * @public + * Create an Output from a Condition. + * Note: Assumes the given Condition was generated from a + * single public key (e.g. a Ed25519 Condition) + * @param {object} condition Condition (e.g. a Ed25519 Condition from `makeEd25519Condition()`) + * @param {string} amount Amount of the output + * @returns {object} An Output usable in a Transaction + */ + static makeOutput(condition, amount = '1') { + if (typeof amount !== 'string') { + throw new TypeError('`amount` must be of type string') + } + const publicKeys = [] + const getPublicKeys = details => { + if (details.type === 'ed25519-sha-256') { + if (!publicKeys.includes(details.public_key)) { + publicKeys.push(details.public_key) + } + } else if (details.type === 'threshold-sha-256') { + details.subconditions.map(getPublicKeys) + } + } + getPublicKeys(condition.details) + return { + condition, + 'amount': amount, + 'public_keys': publicKeys, + } + } + + /** + * @public + * Create a Preimage-Sha256 Cryptocondition from a secret to put into an Output of a Transaction + * @param {string} preimage Preimage to be hashed and wrapped in a crypto-condition + * @param {boolean} [json=true] If true returns a json object otherwise a crypto-condition type + * @returns {object} Preimage-Sha256 Condition (that will need to wrapped in an Output) + */ + static makeSha256Condition(preimage, json = true) { + const sha256Fulfillment = new cc.PreimageSha256() + sha256Fulfillment.preimage = Buffer.from(preimage) + + if (json) { + return ccJsonify(sha256Fulfillment) + } + return sha256Fulfillment + } + + /** + * @public + * Create an Sha256 Threshold Cryptocondition from threshold to put into an Output of a Transaction + * @param {number} threshold + * @param {Array} [subconditions=[]] + * @param {boolean} [json=true] If true returns a json object otherwise a crypto-condition type + * @returns {object} Sha256 Threshold Condition (that will need to wrapped in an Output) + */ + static makeThresholdCondition(threshold, subconditions = [], json = true) { + const thresholdCondition = new cc.ThresholdSha256() + thresholdCondition.threshold = threshold + + subconditions.forEach((subcondition) => { + // TODO: add support for Condition and URIs + thresholdCondition.addSubfulfillment(subcondition) + }) + + if (json) { + return ccJsonify(thresholdCondition) + } + + return thresholdCondition + } + + /** + * @public + * Generate a `TRANSFER` transaction holding the `asset`, `metadata`, and `outputs`, that fulfills + * the `fulfilledOutputs` of `unspentTransaction`. + * @param {object} unspentTransaction Previous Transaction you have control over (i.e. can fulfill + * its Output Condition) + * @param {object} metadata Metadata for the Transaction + * @param {object[]} outputs Array of Output objects to add to the Transaction. + * Think of these as the recipients of the asset after the transaction. + * For `TRANSFER` Transactions, this should usually just be a list of + * Outputs wrapping Ed25519 Conditions generated from the public keys of + * the recipients. + * @param {...number} OutputIndices Indices of the Outputs in `unspentTransaction` that this + * Transaction fulfills. + * Note that listed public keys listed must be used (and in + * the same order) to sign the Transaction + * (`signTransaction()`). + * @returns {object} Unsigned transaction -- make sure to call signTransaction() on it before + * sending it off! + */ + // TODO: + // - Make `metadata` optional argument + static makeTransferTransaction( + unspentOutputs, + outputs, + metadata + ) { + const inputs = unspentOutputs.map((unspentOutput) => { + const { tx, outputIndex } = { tx: unspentOutput.tx, outputIndex: unspentOutput.output_index } + const fulfilledOutput = tx.outputs[outputIndex] + const transactionLink = { + 'output_index': outputIndex, + 'transaction_id': tx.id, + } + + return Transaction.makeInputTemplate(fulfilledOutput.public_keys, transactionLink) + }) + + const assetLink = { + 'id': unspentOutputs[0].tx.operation === 'CREATE' ? unspentOutputs[0].tx.id + : unspentOutputs[0].tx.asset.id + } + return Transaction.makeTransaction('TRANSFER', assetLink, metadata, outputs, inputs) + } + + /** + * @public + * Sign the given `transaction` with the given `privateKey`s, returning a new copy of `transaction` + * that's been signed. + * Note: Only generates Ed25519 Fulfillments. Thresholds and other types of Fulfillments are left as + * an exercise for the user. + * @param {object} transaction Transaction to sign. `transaction` is not modified. + * @param {...string} privateKeys Private keys associated with the issuers of the `transaction`. + * Looped through to iteratively sign any Input Fulfillments found in + * the `transaction`. + * @returns {object} The signed version of `transaction`. + */ + static signTransaction(transaction, ...privateKeys) { + const signedTx = clone(transaction) + signedTx.inputs.forEach((input, index) => { + const privateKey = privateKeys[index] + const privateKeyBuffer = Buffer.from(base58.decode(privateKey)) + const serializedTransaction = Transaction + .serializeTransactionIntoCanonicalString(transaction) + const ed25519Fulfillment = new cc.Ed25519Sha256() + ed25519Fulfillment.sign(Buffer.from(serializedTransaction), privateKeyBuffer) + const fulfillmentUri = ed25519Fulfillment.serializeUri() + + input.fulfillment = fulfillmentUri + }) + + return signedTx + } +} diff --git a/src/transaction/hashTransaction.js b/src/transaction/hashTransaction.js deleted file mode 100644 index 13d1c51c..00000000 --- a/src/transaction/hashTransaction.js +++ /dev/null @@ -1,10 +0,0 @@ -import serializeTransactionIntoCanonicalString from './serializeTransactionIntoCanonicalString' -import sha256Hash from '../sha256Hash' - -export default function hashTransaction(transaction) { - // Safely remove any tx id from the given transaction for hashing - const tx = { ...transaction } - delete tx.id - - return sha256Hash(serializeTransactionIntoCanonicalString(tx)) -} diff --git a/src/transaction/index.js b/src/transaction/index.js deleted file mode 100644 index 01d4a1f1..00000000 --- a/src/transaction/index.js +++ /dev/null @@ -1,11 +0,0 @@ -export makeEd25519Condition from './makeEd25519Condition' -export makeSha256Condition from './makeSha256Condition' -export makeThresholdCondition from './makeThresholdCondition' -export makeCreateTransaction from './makeCreateTransaction' -export makeOutput from './makeOutput' -export makeTransaction from './makeTransaction' -export makeTransferTransaction from './makeTransferTransaction' -export serializeTransactionIntoCanonicalString from './serializeTransactionIntoCanonicalString' -export signTransaction from './signTransaction' -export ccJsonLoad from './utils/ccJsonLoad' -export ccJsonify from './utils/ccJsonify' diff --git a/src/transaction/makeCreateTransaction.js b/src/transaction/makeCreateTransaction.js deleted file mode 100644 index 8b259dea..00000000 --- a/src/transaction/makeCreateTransaction.js +++ /dev/null @@ -1,31 +0,0 @@ -import makeInputTemplate from './makeInputTemplate' -import makeTransaction from './makeTransaction' - - -/** - * @public - * Generate a `CREATE` transaction holding the `asset`, `metadata`, and `outputs`, to be signed by - * the `issuers`. - * @param {object} asset Created asset's data - * @param {object} metadata Metadata for the Transaction - * @param {object[]} outputs Array of Output objects to add to the Transaction. - * Think of these as the recipients of the asset after the transaction. - * For `CREATE` Transactions, this should usually just be a list of - * Outputs wrapping Ed25519 Conditions generated from the issuers' public - * keys (so that the issuers are the recipients of the created asset). - * @param {...string[]} issuers Public key of one or more issuers to the asset being created by this - * Transaction. - * Note: Each of the private keys corresponding to the given public - * keys MUST be used later (and in the same order) when signing the - * Transaction (`signTransaction()`). - * @returns {object} Unsigned transaction -- make sure to call signTransaction() on it before - * sending it off! - */ -export default function makeCreateTransaction(asset, metadata, outputs, ...issuers) { - const assetDefinition = { - 'data': asset || null, - } - const inputs = issuers.map((issuer) => makeInputTemplate([issuer])) - - return makeTransaction('CREATE', assetDefinition, metadata, outputs, inputs) -} diff --git a/src/transaction/makeEd25519Condition.js b/src/transaction/makeEd25519Condition.js deleted file mode 100644 index c7988e83..00000000 --- a/src/transaction/makeEd25519Condition.js +++ /dev/null @@ -1,27 +0,0 @@ -import { Buffer } from 'buffer' - -import base58 from 'bs58' -import cc from 'crypto-conditions' - -import ccJsonify from './utils/ccJsonify' - - -/** - * @public - * Create an Ed25519 Cryptocondition from an Ed25519 public key to put into an Output of a Transaction - * @param {string} publicKey base58 encoded Ed25519 public key for the recipient of the Transaction - * @param {boolean} [json=true] If true returns a json object otherwise a crypto-condition type - * @returns {object} Ed25519 Condition (that will need to wrapped in an Output) - */ -export default function makeEd25519Condition(publicKey, json = true) { - const publicKeyBuffer = new Buffer(base58.decode(publicKey)) - - const ed25519Fulfillment = new cc.Ed25519Sha256() - ed25519Fulfillment.setPublicKey(publicKeyBuffer) - - if (json) { - return ccJsonify(ed25519Fulfillment) - } - - return ed25519Fulfillment -} diff --git a/src/transaction/makeInputTemplate.js b/src/transaction/makeInputTemplate.js deleted file mode 100644 index f080b064..00000000 --- a/src/transaction/makeInputTemplate.js +++ /dev/null @@ -1,7 +0,0 @@ -export default function makeInputTemplate(publicKeys = [], fulfills = null, fulfillment = null) { - return { - fulfillment, - fulfills, - 'owners_before': publicKeys, - } -} diff --git a/src/transaction/makeOutput.js b/src/transaction/makeOutput.js deleted file mode 100644 index d9375702..00000000 --- a/src/transaction/makeOutput.js +++ /dev/null @@ -1,29 +0,0 @@ -/** - * @public - * Create an Output from a Condition. - * Note: Assumes the given Condition was generated from a single public key (e.g. a Ed25519 Condition) - * @param {object} condition Condition (e.g. a Ed25519 Condition from `makeEd25519Condition()`) - * @param {string} amount Amount of the output - * @returns {object} An Output usable in a Transaction - */ -export default function makeOutput(condition, amount = '1') { - if (typeof amount !== 'string') { - throw new TypeError('`amount` must be of type string') - } - const publicKeys = [] - const getPublicKeys = details => { - if (details.type === 'ed25519-sha-256') { - if (!publicKeys.includes(details.public_key)) { - publicKeys.push(details.public_key) - } - } else if (details.type === 'threshold-sha-256') { - details.subconditions.map(getPublicKeys) - } - } - getPublicKeys(condition.details) - return { - condition, - 'amount': amount, - 'public_keys': publicKeys, - } -} diff --git a/src/transaction/makeSha256Condition.js b/src/transaction/makeSha256Condition.js deleted file mode 100644 index 27a8adf7..00000000 --- a/src/transaction/makeSha256Condition.js +++ /dev/null @@ -1,23 +0,0 @@ -import { Buffer } from 'buffer' - -import cc from 'crypto-conditions' - -import ccJsonify from './utils/ccJsonify' - - -/** - * @public - * Create a Preimage-Sha256 Cryptocondition from a secret to put into an Output of a Transaction - * @param {string} preimage Preimage to be hashed and wrapped in a crypto-condition - * @param {boolean} [json=true] If true returns a json object otherwise a crypto-condition type - * @returns {object} Preimage-Sha256 Condition (that will need to wrapped in an Output) - */ -export default function makeSha256Condition(preimage, json = true) { - const sha256Fulfillment = new cc.PreimageSha256() - sha256Fulfillment.preimage = new Buffer(preimage) - - if (json) { - return ccJsonify(sha256Fulfillment) - } - return sha256Fulfillment -} diff --git a/src/transaction/makeThresholdCondition.js b/src/transaction/makeThresholdCondition.js deleted file mode 100644 index 34058612..00000000 --- a/src/transaction/makeThresholdCondition.js +++ /dev/null @@ -1,28 +0,0 @@ -import cc from 'crypto-conditions' - -import ccJsonify from './utils/ccJsonify' - - -/** - * @public - * Create an Sha256 Threshold Cryptocondition from threshold to put into an Output of a Transaction - * @param {number} threshold - * @param {Array} [subconditions=[]] - * @param {boolean} [json=true] If true returns a json object otherwise a crypto-condition type - * @returns {object} Sha256 Threshold Condition (that will need to wrapped in an Output) - */ -export default function makeThresholdCondition(threshold, subconditions = [], json = true) { - const thresholdCondition = new cc.ThresholdSha256() - thresholdCondition.threshold = threshold - - subconditions.forEach((subcondition) => { - // TODO: add support for Condition and URIs - thresholdCondition.addSubfulfillment(subcondition) - }) - - if (json) { - return ccJsonify(thresholdCondition) - } - - return thresholdCondition -} diff --git a/src/transaction/makeTransaction.js b/src/transaction/makeTransaction.js deleted file mode 100644 index 00c8ce26..00000000 --- a/src/transaction/makeTransaction.js +++ /dev/null @@ -1,28 +0,0 @@ -import hashTransaction from './hashTransaction' - - -function makeTransactionTemplate() { - return { - 'id': null, - 'operation': null, - 'outputs': [], - 'inputs': [], - 'metadata': null, - 'asset': null, - 'version': '1.0', - } -} - - -export default function makeTransaction(operation, asset, metadata = null, outputs = [], inputs = []) { - const tx = makeTransactionTemplate() - tx.operation = operation - tx.asset = asset - tx.metadata = metadata - tx.inputs = inputs - tx.outputs = outputs - - // Hashing must be done after, as the hash is of the Transaction (up to now) - tx.id = hashTransaction(tx) - return tx -} diff --git a/src/transaction/makeTransferTransaction.js b/src/transaction/makeTransferTransaction.js deleted file mode 100644 index b2a51101..00000000 --- a/src/transaction/makeTransferTransaction.js +++ /dev/null @@ -1,46 +0,0 @@ -import makeInputTemplate from './makeInputTemplate' -import makeTransaction from './makeTransaction' - - -/** - * @public - * Generate a `TRANSFER` transaction holding the `asset`, `metadata`, and `outputs`, that fulfills - * the `fulfilledOutputs` of each `unspentTransaction`. - * @param {object[]} unspentOutputs Array of unspent Transactions' Outputs. - * Each item contains Transaction itself - * and index of unspent Output for that Transaction. - * @param {object[]} outputs Array of Output objects to add to the Transaction. - * Think of these as the recipients of the asset after the transaction. - * For `TRANSFER` Transactions, this should usually just be a list of - * Outputs wrapping Ed25519 Conditions generated from the public keys of - * the recipients. - * @param {object} metadata Metadata for the Transaction - optional - * @returns {object} Unsigned transaction -- make sure to call signTransaction() on it before - * sending it off! - */ -export default function makeTransferTransaction( - unspentOutputs, - outputs, - metadata -) { - const inputs = unspentOutputs.map((unspentOutput) => { - const tx = unspentOutput.tx - const outputIndex = unspentOutput.output_index - const fulfilledOutput = tx.outputs[outputIndex] - const transactionLink = { - 'output_index': outputIndex, - 'transaction_id': tx.id, - } - - return makeInputTemplate(fulfilledOutput.public_keys, transactionLink) - }) - - const assetLink = { - 'id': unspentOutputs[0].tx.operation === 'CREATE' ? unspentOutputs[0].tx.id - : unspentOutputs[0].tx.asset.id - } - - const meta = metadata || null - - return makeTransaction('TRANSFER', assetLink, meta, outputs, inputs) -} diff --git a/src/transaction/serializeTransactionIntoCanonicalString.js b/src/transaction/serializeTransactionIntoCanonicalString.js deleted file mode 100644 index 382ed322..00000000 --- a/src/transaction/serializeTransactionIntoCanonicalString.js +++ /dev/null @@ -1,18 +0,0 @@ -import stableStringify from 'json-stable-stringify' -import clone from 'clone' - - -/** - * @public - * Canonically serializes a transaction into a string by sorting the keys - * @param {object} (transaction) - * @return {string} a canonically serialized Transaction - */ -export default function serializeTransactionIntoCanonicalString(transaction) { - // BigchainDB signs fulfillments by serializing transactions into a - // "canonical" format where - const tx = clone(transaction) - // TODO: set fulfillments to null - // Sort the keys - return stableStringify(tx, (a, b) => (a.key > b.key ? 1 : -1)) -} diff --git a/src/transaction/signTransaction.js b/src/transaction/signTransaction.js deleted file mode 100644 index a92cfdf4..00000000 --- a/src/transaction/signTransaction.js +++ /dev/null @@ -1,35 +0,0 @@ -import { Buffer } from 'buffer' -import base58 from 'bs58' -import cc from 'crypto-conditions' -import clone from 'clone' - -import serializeTransactionIntoCanonicalString from './serializeTransactionIntoCanonicalString' - - -/** - * @public - * Sign the given `transaction` with the given `privateKey`s, returning a new copy of `transaction` - * that's been signed. - * Note: Only generates Ed25519 Fulfillments. Thresholds and other types of Fulfillments are left as - * an exercise for the user. - * @param {object} transaction Transaction to sign. `transaction` is not modified. - * @param {...string} privateKeys Private keys associated with the issuers of the `transaction`. - * Looped through to iteratively sign any Input Fulfillments found in - * the `transaction`. - * @returns {object} The signed version of `transaction`. - */ -export default function signTransaction(transaction, ...privateKeys) { - const signedTx = clone(transaction) - signedTx.inputs.forEach((input, index) => { - const privateKey = privateKeys[index] - const privateKeyBuffer = new Buffer(base58.decode(privateKey)) - const serializedTransaction = serializeTransactionIntoCanonicalString(transaction) - const ed25519Fulfillment = new cc.Ed25519Sha256() - ed25519Fulfillment.sign(new Buffer(serializedTransaction), privateKeyBuffer) - const fulfillmentUri = ed25519Fulfillment.serializeUri() - - input.fulfillment = fulfillmentUri - }) - - return signedTx -} diff --git a/src/transaction/utils/ccJsonLoad.js b/src/utils/ccJsonLoad.js similarity index 90% rename from src/transaction/utils/ccJsonLoad.js rename to src/utils/ccJsonLoad.js index 4122f4b0..e4b5f20e 100644 --- a/src/transaction/utils/ccJsonLoad.js +++ b/src/utils/ccJsonLoad.js @@ -13,7 +13,7 @@ export default function ccJsonLoad(conditionJson) { const condition = new cc.Condition() condition.type = conditionJson.type_id condition.bitmask = conditionJson.bitmask - condition.hash = new Buffer(base58.decode(conditionJson.hash)) + condition.hash = Buffer.from(base58.decode(conditionJson.hash)) condition.maxFulfillmentLength = parseInt(conditionJson.max_fulfillment_length, 10) return condition } else { @@ -34,7 +34,7 @@ export default function ccJsonLoad(conditionJson) { if (conditionJson.type === 'ed25519-sha-256') { fulfillment = new cc.Ed25519Sha256() - fulfillment.publicKey = new Buffer(base58.decode(conditionJson.public_key)) + fulfillment.publicKey = Buffer.from(base58.decode(conditionJson.public_key)) } return fulfillment } diff --git a/src/transaction/utils/ccJsonify.js b/src/utils/ccJsonify.js similarity index 100% rename from src/transaction/utils/ccJsonify.js rename to src/utils/ccJsonify.js diff --git a/test/integration/test_integration.js b/test/integration/test_integration.js index 8f7a53b7..255ab55c 100644 --- a/test/integration/test_integration.js +++ b/test/integration/test_integration.js @@ -367,9 +367,7 @@ test('Search blocks containing a transaction', t => { .then(({ id }) => conn.pollStatusAndFetchTransaction(id)) .then(({ id }) => conn.listBlocks(id, 'VALID')) .then(blocks => conn.getBlock(blocks.pop())) - .then(({ block: { transactions } }) => transactions.filter( - ({ id }) => id === createTxSigned.id - )) + .then(({ block: { transactions } }) => transactions.filter(({ id }) => id === createTxSigned.id)) .then(transactions => t.truthy(transactions.length === 1)) }) diff --git a/test/transaction/test_cryptoconditions.js b/test/transaction/test_cryptoconditions.js index 5af52567..4673e17f 100644 --- a/test/transaction/test_cryptoconditions.js +++ b/test/transaction/test_cryptoconditions.js @@ -1,7 +1,6 @@ import test from 'ava' import cc from 'crypto-conditions' -import { Ed25519Keypair, Transaction } from '../../src' - +import { Ed25519Keypair, Transaction, ccJsonLoad } from '../../src' test('Ed25519 condition encoding', t => { const publicKey = '4zvwRjXUKGfvwnParsHAS3HuSVzV5cA4McphgmoCtajS' @@ -19,8 +18,7 @@ test('Ed25519 condition encoding', t => { test('Threshold condition encoding', t => { const publicKey = '4zvwRjXUKGfvwnParsHAS3HuSVzV5cA4McphgmoCtajS' const ed25519 = Transaction.makeEd25519Condition(publicKey, false) - const condition = Transaction.makeThresholdCondition( - 1, [ed25519, ed25519]) + const condition = Transaction.makeThresholdCondition(1, [ed25519, ed25519]) const output = Transaction.makeOutput(condition) const target = { condition: { @@ -62,14 +60,15 @@ test('Fulfillment correctly formed', t => { ) const msg = Transaction.serializeTransactionIntoCanonicalString(txTransfer) const txSigned = Transaction.signTransaction(txTransfer, alice.privateKey) - t.truthy(cc.validateFulfillment(txSigned.inputs[0].fulfillment, - txCreate.outputs[0].condition.uri, - new Buffer(msg))) + t.truthy(cc.validateFulfillment( + txSigned.inputs[0].fulfillment, txCreate.outputs[0].condition.uri, + Buffer.from(msg) + )) }) test('CryptoConditions JSON load', t => { - const cond = Transaction.ccJsonLoad({ + const cond = ccJsonLoad({ type: 'threshold-sha-256', threshold: 1, subconditions: [{ @@ -85,7 +84,7 @@ test('CryptoConditions JSON load', t => { test('CryptoConditions JSON load', t => { - const cond = Transaction.ccJsonLoad({ + const cond = ccJsonLoad({ type: 'threshold-sha-256', threshold: 1, subconditions: [{ diff --git a/test/transaction/test_transaction.js b/test/transaction/test_transaction.js index 002c82e5..b1dc58b5 100644 --- a/test/transaction/test_transaction.js +++ b/test/transaction/test_transaction.js @@ -2,8 +2,6 @@ import test from 'ava' import sinon from 'sinon' import { Transaction } from '../../src' -import * as makeTransaction from '../../src/transaction/makeTransaction' // eslint-disable-line -import makeInputTemplate from '../../src/transaction/makeInputTemplate' import { alice, @@ -70,8 +68,7 @@ test('makeOutput throws TypeError with incorrect amount type', t => { test('Create TRANSFER transaction based on CREATE transaction', t => { - sinon.spy(makeTransaction, 'default') - + sinon.spy(Transaction, 'makeTransaction') Transaction.makeTransferTransaction( [{ tx: createTx, output_index: 0 }], [aliceOutput], @@ -82,22 +79,21 @@ test('Create TRANSFER transaction based on CREATE transaction', t => { { id: createTx.id }, metaData, [aliceOutput], - [makeInputTemplate( + [Transaction.makeInputTemplate( [alice.publicKey], { output_index: 0, transaction_id: createTx.id } )] ] - // NOTE: `src/transaction/makeTransaction` is `export default`, hence we // can only mock `makeTransaction.default` with a hack: // See: https://stackoverflow.com/a/33676328/1263876 - t.truthy(makeTransaction.default.calledWith(...expected)) - makeTransaction.default.restore() + t.truthy(Transaction.makeTransaction.calledWith(...expected)) + Transaction.makeTransaction.restore() }) test('Create TRANSFER transaction based on TRANSFER transaction', t => { - sinon.spy(makeTransaction, 'default') + sinon.spy(Transaction, 'makeTransaction') Transaction.makeTransferTransaction( [{ tx: transferTx, output_index: 0 }], @@ -109,12 +105,12 @@ test('Create TRANSFER transaction based on TRANSFER transaction', t => { { id: transferTx.asset.id }, metaData, [aliceOutput], - [makeInputTemplate( + [Transaction.makeInputTemplate( [alice.publicKey], { output_index: 0, transaction_id: transferTx.id } )] ] - t.truthy(makeTransaction.default.calledWith(...expected)) - makeTransaction.default.restore() + t.truthy(Transaction.makeTransaction.calledWith(...expected)) + Transaction.makeTransaction.restore() })