Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BREAKING] Use destination routing #65

Merged
merged 1 commit into from
May 11, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 25 additions & 23 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,10 @@

const co = require('co')
const request = require('superagent')
const Payments = require('./payments')
const transferUtils = require('./transferUtils')
const notaryUtils = require('./notaryUtils')
const conditionUtils = require('./conditionUtils')
const pathUtils = require('./pathUtils')
const quoteUtils = require('./quoteUtils')
const validator = require('./validator')

/**
Expand Down Expand Up @@ -46,8 +45,7 @@ function sendPayment (params) {
destinationAccount: params.destinationAccount,
sourceAmount: params.sourceAmount,
destinationAmount: params.destinationAmount
})
.then((subpayments) => executePayment(subpayments, {
}).then((quote) => executePayment(quote, {
sourceAccount: params.sourceAccount,
sourcePassword: params.sourcePassword,
sourceKey: params.sourceKey,
Expand All @@ -67,7 +65,7 @@ function sendPayment (params) {
/**
* Execute a transaction.
*
* @param {Object[]} _subpayments - The quoted payment path.
* @param {Object[]} quote - The quoted payment path.
* @param {Object} params
*
* Required for both modes:
Expand Down Expand Up @@ -95,24 +93,20 @@ function sendPayment (params) {
* @param {String} [params.caseId] = A notary case ID - if not provided, one will be generated
* @param {String|Buffer} [params.ca] - Optional TLS CA if not using default CA (optional for https requests)
*/
function executePayment (_subpayments, params) {
function executePayment (quote, params) {
return co(function * () {
const isAtomic = !!params.notary
if (isAtomic && !params.notaryPublicKey) {
throw new Error('Missing required parameter: notaryPublicKey')
}

const subpayments = Payments.setupTransfers(_subpayments,
params.sourceAccount,
params.destinationAccount,
params.additionalInfo)
let transfers = Payments.toTransfers(subpayments)
let sourceTransfer = transferUtils.setupTransfers(quote, params.additionalInfo)

if (params.destinationMemo) {
transfers[transfers.length - 1].credits[0].memo = params.destinationMemo
getDestinationTransfer(sourceTransfer).credits[0].memo = params.destinationMemo
}
if (params.sourceMemo) {
transfers[0].debits[0].memo = params.sourceMemo
sourceTransfer.debits[0].memo = params.sourceMemo
}

// In universal mode, all transfers are prepared. Then the recipient
Expand All @@ -132,8 +126,8 @@ function executePayment (_subpayments, params) {
notary: params.notary,
caseId: params.caseID || params.caseId,
receiptCondition: receiptCondition,
transfers: transfers,
expiresAt: transferUtils.transferExpiresAt(Date.now(), transfers[0])
transfers: [sourceTransfer, getDestinationTransfer(sourceTransfer)],
expiresAt: transferUtils.transferExpiresAt(Date.now(), sourceTransfer)
}))

const conditionParams = {
Expand All @@ -146,26 +140,25 @@ function executePayment (_subpayments, params) {
const executionCondition = params.executionCondition || conditionUtils.getExecutionCondition(conditionParams)
const cancellationCondition = isAtomic && (params.cancellationCondition || conditionUtils.getCancellationCondition(conditionParams))

transfers = transferUtils.setupConditions(transfers, {
sourceTransfer = transferUtils.setupConditions(sourceTransfer, {
isAtomic,
executionCondition,
cancellationCondition,
caseId
})

// Prepare the first transfer.
validator.validateTransfer(sourceTransfer)
const sourceUsername = (yield getAccount(params.sourceAccount)).name
const firstTransfer = transferUtils.setupTransferChain(transfers)
validator.validateTransfer(firstTransfer)
firstTransfer.state = yield transferUtils.postTransfer(firstTransfer, {
sourceTransfer.state = yield transferUtils.postTransfer(sourceTransfer, {
username: sourceUsername,
password: params.sourcePassword,
key: params.sourceKey,
cert: params.sourceCert,
ca: params.ca
})

return transfers
return sourceTransfer
})
}

Expand All @@ -180,16 +173,17 @@ function executePayment (_subpayments, params) {
* Exactly one of the following:
* @param {String} params.sourceAmount
* @param {String} params.destinationAmount
* @returns {Promise} an Array of subpayments
* @returns {Promise<Transfer>}
*/
function findPath (params) {
return co(function * () {
const sourceLedger = yield getAccountLedger(params.sourceAccount)
const connectorAccounts = yield getLedgerConnectors(sourceLedger)
const paths = yield connectorAccounts.map(function (connectorAccount) {
return pathUtils.getPathFromConnector(connectorAccount.connector, params)
return quoteUtils.getQuoteFromConnector(connectorAccount.connector, params)
})
return paths.reduce(pathUtils.getCheaperPath)
if (!paths.length) return
return paths.reduce(quoteUtils.getCheaperQuote)
})
}

Expand Down Expand Up @@ -226,6 +220,14 @@ function getLedgerConnectors (ledger) {
})
}

/**
* @param {Transfer} transfer
* @returns {Transfer}
*/
function getDestinationTransfer (transfer) {
return transfer.credits[0].memo.destination_transfer
}

module.exports = sendPayment
module.exports.default = sendPayment
module.exports.executePayment = executePayment
Expand Down
55 changes: 0 additions & 55 deletions src/pathUtils.js

This file was deleted.

67 changes: 0 additions & 67 deletions src/payments.js

This file was deleted.

56 changes: 56 additions & 0 deletions src/quoteUtils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
'use strict'

const co = require('co')
const request = require('superagent')
const BigNumber = require('bignumber.js')

/**
* @param {URI} connector
* @param {Object} params
* @param {String} params.sourceAccount
* @param {String} params.destinationAccount
* Exactly one of the following:
* @param {String} params.sourceAmount
* @param {String} params.destinationAmount
* @returns {Promise<Transfer>}
*/
function getQuoteFromConnector (connector, params) {
return co(function * () {
const res = yield request.get(connector + '/quote')
.query({
source_account: params.sourceAccount,
destination_account: params.destinationAccount,
destination_expiry_duration: 2
})
.query(params.sourceAmount
? {source_amount: params.sourceAmount}
: {destination_amount: params.destinationAmount})
return res.body
})
}

function getAmount (transfer) {
return new BigNumber(transfer.credits[0].amount)
}

/**
* @param {Transfer} quote1
* @param {Transfer} quote2
* @returns {Transfer}
*/
function getCheaperQuote (quote1, quote2) {
if ((getAmount(quote1))
.lessThan(getAmount(quote2))) {
return quote1
}

if ((getAmount(quote1.credits[0].memo.destination_transfer))
.lessThan(getAmount(quote2.credits[0].memo.destination_transfer))) {
return quote1
}

return quote2
}

exports.getQuoteFromConnector = getQuoteFromConnector
exports.getCheaperQuote = getCheaperQuote
Loading