diff --git a/src/api/common/schema-validator.js b/src/api/common/schema-validator.js index eaf74e0f1e..427dfebf89 100644 --- a/src/api/common/schema-validator.js +++ b/src/api/common/schema-validator.js @@ -83,8 +83,12 @@ function loadSchemas() { } function formatSchemaError(error) { - return error.field + ' ' + error.message - + (error.value ? ' (' + JSON.stringify(error.value) + ')' : ''); + try { + return error.field + ' ' + error.message + + (error.value ? ' (' + JSON.stringify(error.value) + ')' : ''); + } catch (err) { + return error.field + ' ' + error.message; + } } function formatSchemaErrors(errors) { diff --git a/src/api/server/server.js b/src/api/server/server.js index 55b182b526..7b92aae302 100644 --- a/src/api/server/server.js +++ b/src/api/server/server.js @@ -4,10 +4,6 @@ const _ = require('lodash'); const common = require('../common'); -import type {Remote} from '../../core/remote'; - -// If a ledger is not received in this time, consider the connection offline -const CONNECTION_TIMEOUT = 1000 * 30; type GetServerInfoResponse = { buildVersion: string, @@ -38,14 +34,9 @@ type GetServerInfoResponse = { validationQuorum: number } -function isUpToDate(remote: Remote): boolean { - const server = remote.getServer(); - return Boolean(server) && (remote._stand_alone - || (Date.now() - server._lastLedgerClose) <= CONNECTION_TIMEOUT); -} - function isConnected(): boolean { - return Boolean(this.remote._ledger_current_index) && isUpToDate(this.remote); + const server = this.remote.getServer(); + return Boolean(server && server.isConnected()); } function getServerInfoAsync( @@ -78,7 +69,7 @@ function connect(): Promise { return common.promisify(callback => { try { this.remote.connect(() => callback(null)); - } catch(error) { + } catch (error) { callback(new common.errors.RippledNetworkError(error.message)); } })(); @@ -88,7 +79,7 @@ function disconnect(): Promise { return common.promisify(callback => { try { this.remote.disconnect(() => callback(null)); - } catch(error) { + } catch (error) { callback(new common.errors.RippledNetworkError(error.message)); } })(); diff --git a/src/api/transaction/order.js b/src/api/transaction/order.js index ebf65abbd6..21f0e446c8 100644 --- a/src/api/transaction/order.js +++ b/src/api/transaction/order.js @@ -35,8 +35,8 @@ function createOrderTransaction(account: string, order: Order): Transaction { function prepareOrderAsync(account: string, order: Order, instructions: Instructions, callback ) { - const transaction = createOrderTransaction(account, order); - utils.prepareTransaction(transaction, this.remote, instructions, callback); + const txJSON = createOrderTransaction(account, order).tx_json; + utils.prepareTransaction(txJSON, this.remote, instructions, callback); } function prepareOrder(account: string, order: Order, diff --git a/src/api/transaction/ordercancellation.js b/src/api/transaction/ordercancellation.js index debd8f86fe..0f80a5ad00 100644 --- a/src/api/transaction/ordercancellation.js +++ b/src/api/transaction/ordercancellation.js @@ -19,8 +19,8 @@ function createOrderCancellationTransaction(account: string, function prepareOrderCancellationAsync(account: string, sequence: number, instructions: Instructions, callback ) { - const transaction = createOrderCancellationTransaction(account, sequence); - utils.prepareTransaction(transaction, this.remote, instructions, callback); + const txJSON = createOrderCancellationTransaction(account, sequence).tx_json; + utils.prepareTransaction(txJSON, this.remote, instructions, callback); } function prepareOrderCancellation(account: string, sequence: number, diff --git a/src/api/transaction/payment.js b/src/api/transaction/payment.js index cf61496edb..4ed74c8569 100644 --- a/src/api/transaction/payment.js +++ b/src/api/transaction/payment.js @@ -144,8 +144,8 @@ function createPaymentTransaction(account: string, paymentArgument: Payment function preparePaymentAsync(account: string, payment: Payment, instructions: Instructions, callback ) { - const transaction = createPaymentTransaction(account, payment); - utils.prepareTransaction(transaction, this.remote, instructions, callback); + const txJSON = createPaymentTransaction(account, payment).tx_json; + utils.prepareTransaction(txJSON, this.remote, instructions, callback); } function preparePayment(account: string, payment: Payment, diff --git a/src/api/transaction/settings.js b/src/api/transaction/settings.js index 372f1f09a3..b194c9a18e 100644 --- a/src/api/transaction/settings.js +++ b/src/api/transaction/settings.js @@ -97,8 +97,8 @@ function createSettingsTransaction(account: string, settings: Settings function prepareSettingsAsync(account: string, settings: Settings, instructions: Instructions, callback ) { - const transaction = createSettingsTransaction(account, settings); - utils.prepareTransaction(transaction, this.remote, instructions, callback); + const txJSON = createSettingsTransaction(account, settings).tx_json; + utils.prepareTransaction(txJSON, this.remote, instructions, callback); } function prepareSettings(account: string, settings: Object, diff --git a/src/api/transaction/suspended-payment-cancellation.js b/src/api/transaction/suspended-payment-cancellation.js index ef339ff1f9..d088dcb8a0 100644 --- a/src/api/transaction/suspended-payment-cancellation.js +++ b/src/api/transaction/suspended-payment-cancellation.js @@ -37,9 +37,9 @@ function createSuspendedPaymentCancellationTransaction(account: string, function prepareSuspendedPaymentCancellationAsync(account: string, payment: SuspendedPaymentCancellation, instructions: Instructions, callback ) { - const transaction = - createSuspendedPaymentCancellationTransaction(account, payment); - utils.prepareTransaction(transaction, this.remote, instructions, callback); + const txJSON = + createSuspendedPaymentCancellationTransaction(account, payment).tx_json; + utils.prepareTransaction(txJSON, this.remote, instructions, callback); } function prepareSuspendedPaymentCancellation(account: string, diff --git a/src/api/transaction/suspended-payment-creation.js b/src/api/transaction/suspended-payment-creation.js index f6705e8360..0bcedf6b62 100644 --- a/src/api/transaction/suspended-payment-creation.js +++ b/src/api/transaction/suspended-payment-creation.js @@ -57,9 +57,9 @@ function createSuspendedPaymentCreationTransaction(account: string, function prepareSuspendedPaymentCreationAsync(account: string, payment: SuspendedPaymentCreation, instructions: Instructions, callback ) { - const transaction = - createSuspendedPaymentCreationTransaction(account, payment); - utils.prepareTransaction(transaction, this.remote, instructions, callback); + const txJSON = + createSuspendedPaymentCreationTransaction(account, payment).tx_json; + utils.prepareTransaction(txJSON, this.remote, instructions, callback); } function prepareSuspendedPaymentCreation(account: string, diff --git a/src/api/transaction/suspended-payment-execution.js b/src/api/transaction/suspended-payment-execution.js index 2ed306357e..3fb95f6928 100644 --- a/src/api/transaction/suspended-payment-execution.js +++ b/src/api/transaction/suspended-payment-execution.js @@ -50,9 +50,9 @@ function createSuspendedPaymentExecutionTransaction(account: string, function prepareSuspendedPaymentExecutionAsync(account: string, payment: SuspendedPaymentExecution, instructions: Instructions, callback ) { - const transaction = - createSuspendedPaymentExecutionTransaction(account, payment); - utils.prepareTransaction(transaction, this.remote, instructions, callback); + const txJSON = + createSuspendedPaymentExecutionTransaction(account, payment).tx_json; + utils.prepareTransaction(txJSON, this.remote, instructions, callback); } function prepareSuspendedPaymentExecution(account: string, diff --git a/src/api/transaction/trustline.js b/src/api/transaction/trustline.js index ee08633bc6..ad96273311 100644 --- a/src/api/transaction/trustline.js +++ b/src/api/transaction/trustline.js @@ -40,8 +40,8 @@ function createTrustlineTransaction(account: string, function prepareTrustlineAsync(account: string, trustline: TrustLineSpecification, instructions: Instructions, callback ) { - const transaction = createTrustlineTransaction(account, trustline); - utils.prepareTransaction(transaction, this.remote, instructions, callback); + const txJSON = createTrustlineTransaction(account, trustline).tx_json; + utils.prepareTransaction(txJSON, this.remote, instructions, callback); } function prepareTrustline(account: string, diff --git a/src/api/transaction/txflags.js b/src/api/transaction/txflags.js new file mode 100644 index 0000000000..d07d5151a5 --- /dev/null +++ b/src/api/transaction/txflags.js @@ -0,0 +1,60 @@ +'use strict'; + +const transactionFlags = { + // Universal flags can apply to any transaction type + Universal: { + FullyCanonicalSig: 0x80000000 + }, + + AccountSet: { + RequireDestTag: 0x00010000, + OptionalDestTag: 0x00020000, + RequireAuth: 0x00040000, + OptionalAuth: 0x00080000, + DisallowXRP: 0x00100000, + AllowXRP: 0x00200000 + }, + + TrustSet: { + SetAuth: 0x00010000, + NoRipple: 0x00020000, + SetNoRipple: 0x00020000, + ClearNoRipple: 0x00040000, + SetFreeze: 0x00100000, + ClearFreeze: 0x00200000 + }, + + OfferCreate: { + Passive: 0x00010000, + ImmediateOrCancel: 0x00020000, + FillOrKill: 0x00040000, + Sell: 0x00080000 + }, + + Payment: { + NoRippleDirect: 0x00010000, + PartialPayment: 0x00020000, + LimitQuality: 0x00040000 + } +}; + +// The following are integer (as opposed to bit) flags +// that can be set for particular transactions in the +// SetFlag or ClearFlag field +const transactionFlagIndices = { + AccountSet: { + asfRequireDest: 1, + asfRequireAuth: 2, + asfDisallowXRP: 3, + asfDisableMaster: 4, + asfAccountTxnID: 5, + asfNoFreeze: 6, + asfGlobalFreeze: 7, + asfDefaultRipple: 8 + } +}; + +module.exports = { + transactionFlags, + transactionFlagIndices +}; diff --git a/src/api/transaction/utils.js b/src/api/transaction/utils.js index 8cc829689a..934273c5ba 100644 --- a/src/api/transaction/utils.js +++ b/src/api/transaction/utils.js @@ -5,6 +5,7 @@ const async = require('async'); const BigNumber = require('bignumber.js'); const common = require('../common'); const composeAsync = common.composeAsync; +const txFlags = require('./txflags'); import type {Remote} from '../../core/remote'; import type {Transaction} from '../../core/transaction'; import type {Instructions} from './types.js'; @@ -44,17 +45,23 @@ function formatPrepareResponse(txJSON: Object): Object { }; } +function setCanonicalFlag(txJSON) { + txJSON.Flags |= txFlags.transactionFlags.Universal.FullyCanonicalSig; + + // JavaScript converts operands to 32-bit signed ints before doing bitwise + // operations. We need to convert it back to an unsigned int. + txJSON.Flags = txJSON.Flags >>> 0; +} + type Callback = (err: ?(typeof Error), data: {txJSON: string, instructions: Instructions}) => void; -function prepareTransaction(transaction: Transaction, remote: Remote, +function prepareTransaction(txJSON: Object, remote: Remote, instructions: Instructions, callback: Callback ): void { common.validate.instructions(instructions); - transaction.complete(); - const account = transaction.getAccount(); - const txJSON = transaction.tx_json; - + const account = txJSON.Account; + setCanonicalFlag(txJSON); function prepareMaxLedgerVersion(callback_) { if (instructions.maxLedgerVersion !== undefined) { diff --git a/test/fixtures/api/requests/sign.json b/test/fixtures/api/requests/sign.json index f2d27b6de9..a0a599c117 100644 --- a/test/fixtures/api/requests/sign.json +++ b/test/fixtures/api/requests/sign.json @@ -1,5 +1,5 @@ { - "txJSON": "{\"Flags\":0,\"TransactionType\":\"AccountSet\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"Domain\":\"726970706C652E636F6D\",\"LastLedgerSequence\":8820051,\"Fee\":\"12\",\"Sequence\":23}", + "txJSON": "{\"Flags\":2147483648,\"TransactionType\":\"AccountSet\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"Domain\":\"726970706C652E636F6D\",\"LastLedgerSequence\":8820051,\"Fee\":\"12\",\"Sequence\":23}", "instructions": { "fee": "12", "sequence": 23, diff --git a/test/fixtures/api/responses/prepare-order-cancellation.json b/test/fixtures/api/responses/prepare-order-cancellation.json index 6b0d6fbe0e..d08fb0f36e 100644 --- a/test/fixtures/api/responses/prepare-order-cancellation.json +++ b/test/fixtures/api/responses/prepare-order-cancellation.json @@ -1,5 +1,5 @@ { - "txJSON": "{\"Flags\":0,\"TransactionType\":\"OfferCancel\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"OfferSequence\":23,\"LastLedgerSequence\":8820051,\"Fee\":\"12\",\"Sequence\":23}", + "txJSON": "{\"Flags\":2147483648,\"TransactionType\":\"OfferCancel\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"OfferSequence\":23,\"LastLedgerSequence\":8820051,\"Fee\":\"12\",\"Sequence\":23}", "instructions": { "fee": "12", "sequence": 23, diff --git a/test/fixtures/api/responses/prepare-order-sell.json b/test/fixtures/api/responses/prepare-order-sell.json index f1ce1da01b..40d5b6cd65 100644 --- a/test/fixtures/api/responses/prepare-order-sell.json +++ b/test/fixtures/api/responses/prepare-order-sell.json @@ -1,5 +1,5 @@ { - "txJSON": "{\"Flags\":655360,\"TransactionType\":\"OfferCreate\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"TakerGets\":{\"value\":\"10.1\",\"currency\":\"USD\",\"issuer\":\"rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM\"},\"TakerPays\":\"2000000\",\"LastLedgerSequence\":8820051,\"Fee\":\"12\",\"Sequence\":23}", + "txJSON": "{\"Flags\":2148139008,\"TransactionType\":\"OfferCreate\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"TakerGets\":{\"value\":\"10.1\",\"currency\":\"USD\",\"issuer\":\"rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM\"},\"TakerPays\":\"2000000\",\"LastLedgerSequence\":8820051,\"Fee\":\"12\",\"Sequence\":23}", "instructions": { "fee": "12", "sequence": 23, diff --git a/test/fixtures/api/responses/prepare-order.json b/test/fixtures/api/responses/prepare-order.json index 862ca51e76..b6c102a8c3 100644 --- a/test/fixtures/api/responses/prepare-order.json +++ b/test/fixtures/api/responses/prepare-order.json @@ -1,5 +1,5 @@ { - "txJSON": "{\"Flags\":131072,\"TransactionType\":\"OfferCreate\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"TakerGets\":\"2000000\",\"TakerPays\":{\"value\":\"10.1\",\"currency\":\"USD\",\"issuer\":\"rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM\"},\"LastLedgerSequence\":8820051,\"Fee\":\"12\",\"Sequence\":23}", + "txJSON": "{\"Flags\":2147614720,\"TransactionType\":\"OfferCreate\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"TakerGets\":\"2000000\",\"TakerPays\":{\"value\":\"10.1\",\"currency\":\"USD\",\"issuer\":\"rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM\"},\"LastLedgerSequence\":8820051,\"Fee\":\"12\",\"Sequence\":23}", "instructions": { "fee": "12", "sequence": 23, diff --git a/test/fixtures/api/responses/prepare-payment-all-options.json b/test/fixtures/api/responses/prepare-payment-all-options.json index abd6f768a6..b8b5bd2a32 100644 --- a/test/fixtures/api/responses/prepare-payment-all-options.json +++ b/test/fixtures/api/responses/prepare-payment-all-options.json @@ -1,5 +1,5 @@ { - "txJSON": "{\"Flags\":327680,\"TransactionType\":\"Payment\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"Destination\":\"rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo\",\"Amount\":\"10000\",\"InvoiceID\":\"A98FD36C17BE2B8511AD36DC335478E7E89F06262949F36EB88E2D683BBCC50A\",\"SourceTag\":14,\"DestinationTag\":58,\"Memos\":[{\"Memo\":{\"MemoType\":\"74657374\",\"MemoFormat\":\"706C61696E2F74657874\",\"MemoData\":\"7465787465642064617461\"}}],\"LastLedgerSequence\":8820051,\"Fee\":\"12\",\"Sequence\":23}", + "txJSON": "{\"Flags\":2147811328,\"TransactionType\":\"Payment\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"Destination\":\"rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo\",\"Amount\":\"10000\",\"InvoiceID\":\"A98FD36C17BE2B8511AD36DC335478E7E89F06262949F36EB88E2D683BBCC50A\",\"SourceTag\":14,\"DestinationTag\":58,\"Memos\":[{\"Memo\":{\"MemoType\":\"74657374\",\"MemoFormat\":\"706C61696E2F74657874\",\"MemoData\":\"7465787465642064617461\"}}],\"LastLedgerSequence\":8820051,\"Fee\":\"12\",\"Sequence\":23}", "instructions": { "fee": "12", "sequence": 23, diff --git a/test/fixtures/api/responses/prepare-payment-min-amount.json b/test/fixtures/api/responses/prepare-payment-min-amount.json index e0fc200059..df3edb1330 100644 --- a/test/fixtures/api/responses/prepare-payment-min-amount.json +++ b/test/fixtures/api/responses/prepare-payment-min-amount.json @@ -1,5 +1,5 @@ { - "txJSON": "{\"Flags\":131072,\"TransactionType\":\"Payment\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"Destination\":\"ra5nK24KXen9AHvsdFTKHSANinZseWnPcX\",\"Amount\":{\"value\":\"9999999999999999e80\",\"currency\":\"USD\",\"issuer\":\"ra5nK24KXen9AHvsdFTKHSANinZseWnPcX\"},\"SendMax\":{\"value\":\"5\",\"currency\":\"USD\",\"issuer\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\"},\"DeliverMin\":{\"value\":\"9999999999999999e80\",\"currency\":\"USD\",\"issuer\":\"ra5nK24KXen9AHvsdFTKHSANinZseWnPcX\"},\"Paths\":[[{\"account\":\"rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B\"},{\"currency\":\"XRP\"},{\"issuer\":\"rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q\",\"currency\":\"USD\"},{\"account\":\"rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q\"},{\"account\":\"rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn\"}],[{\"account\":\"rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B\"},{\"currency\":\"XRP\"},{\"issuer\":\"rfsEoNBUBbvkf4jPcFe2u9CyaQagLVHGfP\",\"currency\":\"USD\"},{\"account\":\"rfsEoNBUBbvkf4jPcFe2u9CyaQagLVHGfP\"},{\"account\":\"rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q\"}]],\"LastLedgerSequence\":8820051,\"Fee\":\"12\",\"Sequence\":23}", + "txJSON": "{\"Flags\":2147614720,\"TransactionType\":\"Payment\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"Destination\":\"ra5nK24KXen9AHvsdFTKHSANinZseWnPcX\",\"Amount\":{\"value\":\"9999999999999999e80\",\"currency\":\"USD\",\"issuer\":\"ra5nK24KXen9AHvsdFTKHSANinZseWnPcX\"},\"SendMax\":{\"value\":\"5\",\"currency\":\"USD\",\"issuer\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\"},\"DeliverMin\":{\"value\":\"9999999999999999e80\",\"currency\":\"USD\",\"issuer\":\"ra5nK24KXen9AHvsdFTKHSANinZseWnPcX\"},\"Paths\":[[{\"account\":\"rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B\"},{\"currency\":\"XRP\"},{\"issuer\":\"rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q\",\"currency\":\"USD\"},{\"account\":\"rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q\"},{\"account\":\"rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn\"}],[{\"account\":\"rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B\"},{\"currency\":\"XRP\"},{\"issuer\":\"rfsEoNBUBbvkf4jPcFe2u9CyaQagLVHGfP\",\"currency\":\"USD\"},{\"account\":\"rfsEoNBUBbvkf4jPcFe2u9CyaQagLVHGfP\"},{\"account\":\"rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q\"}]],\"LastLedgerSequence\":8820051,\"Fee\":\"12\",\"Sequence\":23}", "instructions": { "fee": "12", "sequence": 23, diff --git a/test/fixtures/api/responses/prepare-payment-no-counterparty.json b/test/fixtures/api/responses/prepare-payment-no-counterparty.json index 67f893d025..3ffa57c815 100644 --- a/test/fixtures/api/responses/prepare-payment-no-counterparty.json +++ b/test/fixtures/api/responses/prepare-payment-no-counterparty.json @@ -1,5 +1,5 @@ { - "txJSON": "{\"Flags\":458752,\"TransactionType\":\"Payment\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"Destination\":\"rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo\",\"Amount\":{\"value\":\"0.01\",\"currency\":\"LTC\",\"issuer\":\"rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo\"},\"InvoiceID\":\"A98FD36C17BE2B8511AD36DC335478E7E89F06262949F36EB88E2D683BBCC50A\",\"SourceTag\":14,\"DestinationTag\":58,\"Memos\":[{\"Memo\":{\"MemoType\":\"74657374\",\"MemoFormat\":\"706C61696E2F74657874\",\"MemoData\":\"7465787465642064617461\"}}],\"SendMax\":{\"value\":\"0.01\",\"currency\":\"USD\",\"issuer\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\"},\"Paths\":[[{\"account\":\"rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q\",\"issuer\":\"rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q\",\"currency\":\"USD\",\"type_hex\":\"0000000000000031\"},{\"issuer\":\"rfYv1TXnwgDDK4WQNbFALykYuEBnrR4pDX\",\"currency\":\"LTC\",\"type_hex\":\"0000000000000030\"},{\"account\":\"rfYv1TXnwgDDK4WQNbFALykYuEBnrR4pDX\",\"issuer\":\"rfYv1TXnwgDDK4WQNbFALykYuEBnrR4pDX\",\"currency\":\"LTC\",\"type_hex\":\"0000000000000031\"}]],\"LastLedgerSequence\":8820051,\"Fee\":\"12\",\"Sequence\":23}", + "txJSON": "{\"Flags\":2147942400,\"TransactionType\":\"Payment\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"Destination\":\"rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo\",\"Amount\":{\"value\":\"0.01\",\"currency\":\"LTC\",\"issuer\":\"rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo\"},\"InvoiceID\":\"A98FD36C17BE2B8511AD36DC335478E7E89F06262949F36EB88E2D683BBCC50A\",\"SourceTag\":14,\"DestinationTag\":58,\"Memos\":[{\"Memo\":{\"MemoType\":\"74657374\",\"MemoFormat\":\"706C61696E2F74657874\",\"MemoData\":\"7465787465642064617461\"}}],\"SendMax\":{\"value\":\"0.01\",\"currency\":\"USD\",\"issuer\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\"},\"Paths\":[[{\"account\":\"rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q\",\"issuer\":\"rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q\",\"currency\":\"USD\",\"type_hex\":\"0000000000000031\"},{\"issuer\":\"rfYv1TXnwgDDK4WQNbFALykYuEBnrR4pDX\",\"currency\":\"LTC\",\"type_hex\":\"0000000000000030\"},{\"account\":\"rfYv1TXnwgDDK4WQNbFALykYuEBnrR4pDX\",\"issuer\":\"rfYv1TXnwgDDK4WQNbFALykYuEBnrR4pDX\",\"currency\":\"LTC\",\"type_hex\":\"0000000000000031\"}]],\"LastLedgerSequence\":8820051,\"Fee\":\"12\",\"Sequence\":23}", "instructions": { "fee": "12", "sequence": 23, diff --git a/test/fixtures/api/responses/prepare-payment.json b/test/fixtures/api/responses/prepare-payment.json index 59eeb2ac60..08b044b58a 100644 --- a/test/fixtures/api/responses/prepare-payment.json +++ b/test/fixtures/api/responses/prepare-payment.json @@ -1,5 +1,5 @@ { - "txJSON": "{\"Flags\":0,\"TransactionType\":\"Payment\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"Destination\":\"rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo\",\"Amount\":{\"value\":\"0.01\",\"currency\":\"USD\",\"issuer\":\"rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM\"},\"SendMax\":{\"value\":\"0.01\",\"currency\":\"USD\",\"issuer\":\"rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM\"},\"LastLedgerSequence\":8820051,\"Fee\":\"12\",\"Sequence\":23}", + "txJSON": "{\"Flags\":2147483648,\"TransactionType\":\"Payment\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"Destination\":\"rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo\",\"Amount\":{\"value\":\"0.01\",\"currency\":\"USD\",\"issuer\":\"rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM\"},\"SendMax\":{\"value\":\"0.01\",\"currency\":\"USD\",\"issuer\":\"rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM\"},\"LastLedgerSequence\":8820051,\"Fee\":\"12\",\"Sequence\":23}", "instructions": { "fee": "12", "sequence": 23, diff --git a/test/fixtures/api/responses/prepare-settings-field-clear.json b/test/fixtures/api/responses/prepare-settings-field-clear.json index 11f3a54575..299329f077 100644 --- a/test/fixtures/api/responses/prepare-settings-field-clear.json +++ b/test/fixtures/api/responses/prepare-settings-field-clear.json @@ -1,5 +1,5 @@ { - "txJSON": "{\"Flags\":0,\"TransactionType\":\"AccountSet\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"WalletLocator\":\"0\",\"LastLedgerSequence\":8820051,\"Fee\":\"12\",\"Sequence\":23}", + "txJSON": "{\"Flags\":2147483648,\"TransactionType\":\"AccountSet\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"WalletLocator\":\"0\",\"LastLedgerSequence\":8820051,\"Fee\":\"12\",\"Sequence\":23}", "instructions": { "fee": "12", "sequence": 23, diff --git a/test/fixtures/api/responses/prepare-settings-flag-clear.json b/test/fixtures/api/responses/prepare-settings-flag-clear.json index 617b5f42ad..78c4b12c97 100644 --- a/test/fixtures/api/responses/prepare-settings-flag-clear.json +++ b/test/fixtures/api/responses/prepare-settings-flag-clear.json @@ -1,5 +1,5 @@ { - "txJSON": "{\"Flags\":0,\"TransactionType\":\"AccountSet\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"ClearFlag\":1,\"LastLedgerSequence\":8820051,\"Fee\":\"12\",\"Sequence\":23}", + "txJSON": "{\"Flags\":2147483648,\"TransactionType\":\"AccountSet\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"ClearFlag\":1,\"LastLedgerSequence\":8820051,\"Fee\":\"12\",\"Sequence\":23}", "instructions": { "fee": "12", "sequence": 23, diff --git a/test/fixtures/api/responses/prepare-settings-flag-set.json b/test/fixtures/api/responses/prepare-settings-flag-set.json index 61f2451ac9..fe103d5e2a 100644 --- a/test/fixtures/api/responses/prepare-settings-flag-set.json +++ b/test/fixtures/api/responses/prepare-settings-flag-set.json @@ -1,5 +1,5 @@ { - "txJSON": "{\"Flags\":0,\"TransactionType\":\"AccountSet\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"SetFlag\":1,\"LastLedgerSequence\":8820051,\"Fee\":\"12\",\"Sequence\":23}", + "txJSON": "{\"Flags\":2147483648,\"TransactionType\":\"AccountSet\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"SetFlag\":1,\"LastLedgerSequence\":8820051,\"Fee\":\"12\",\"Sequence\":23}", "instructions": { "fee": "12", "sequence": 23, diff --git a/test/fixtures/api/responses/prepare-settings-regular-key.json b/test/fixtures/api/responses/prepare-settings-regular-key.json index c83c92f111..306be09de1 100644 --- a/test/fixtures/api/responses/prepare-settings-regular-key.json +++ b/test/fixtures/api/responses/prepare-settings-regular-key.json @@ -1,5 +1,5 @@ { - "txJSON": "{\"Flags\":0,\"TransactionType\":\"SetRegularKey\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"RegularKey\":\"rAR8rR8sUkBoCZFawhkWzY4Y5YoyuznwD\",\"LastLedgerSequence\":8820051,\"Fee\":\"12\",\"Sequence\":23}", + "txJSON": "{\"Flags\":2147483648,\"TransactionType\":\"SetRegularKey\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"RegularKey\":\"rAR8rR8sUkBoCZFawhkWzY4Y5YoyuznwD\",\"LastLedgerSequence\":8820051,\"Fee\":\"12\",\"Sequence\":23}", "instructions": { "fee": "12", "sequence": 23, diff --git a/test/fixtures/api/responses/prepare-settings-set-transfer-rate.json b/test/fixtures/api/responses/prepare-settings-set-transfer-rate.json index d9d6393fa4..adc6d83931 100644 --- a/test/fixtures/api/responses/prepare-settings-set-transfer-rate.json +++ b/test/fixtures/api/responses/prepare-settings-set-transfer-rate.json @@ -1,5 +1,5 @@ { - "txJSON": "{\"Flags\":0,\"TransactionType\":\"AccountSet\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"TransferRate\":1000000000,\"LastLedgerSequence\":8820051,\"Fee\":\"12\",\"Sequence\":23}", + "txJSON": "{\"Flags\":2147483648,\"TransactionType\":\"AccountSet\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"TransferRate\":1000000000,\"LastLedgerSequence\":8820051,\"Fee\":\"12\",\"Sequence\":23}", "instructions": { "fee": "12", "sequence": 23, diff --git a/test/fixtures/api/responses/prepare-settings.json b/test/fixtures/api/responses/prepare-settings.json index f2d27b6de9..a0a599c117 100644 --- a/test/fixtures/api/responses/prepare-settings.json +++ b/test/fixtures/api/responses/prepare-settings.json @@ -1,5 +1,5 @@ { - "txJSON": "{\"Flags\":0,\"TransactionType\":\"AccountSet\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"Domain\":\"726970706C652E636F6D\",\"LastLedgerSequence\":8820051,\"Fee\":\"12\",\"Sequence\":23}", + "txJSON": "{\"Flags\":2147483648,\"TransactionType\":\"AccountSet\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"Domain\":\"726970706C652E636F6D\",\"LastLedgerSequence\":8820051,\"Fee\":\"12\",\"Sequence\":23}", "instructions": { "fee": "12", "sequence": 23, diff --git a/test/fixtures/api/responses/prepare-suspended-payment-cancellation.json b/test/fixtures/api/responses/prepare-suspended-payment-cancellation.json index e20055af71..069b801f36 100644 --- a/test/fixtures/api/responses/prepare-suspended-payment-cancellation.json +++ b/test/fixtures/api/responses/prepare-suspended-payment-cancellation.json @@ -1,5 +1,5 @@ { - "txJSON": "{\"Flags\":0,\"TransactionType\":\"SuspendedPaymentCancel\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"Owner\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"OfferSequence\":1234,\"LastLedgerSequence\":8820051,\"Fee\":\"12\",\"Sequence\":23}", + "txJSON": "{\"Flags\":2147483648,\"TransactionType\":\"SuspendedPaymentCancel\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"Owner\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"OfferSequence\":1234,\"LastLedgerSequence\":8820051,\"Fee\":\"12\",\"Sequence\":23}", "instructions": { "fee": "12", "sequence": 23, diff --git a/test/fixtures/api/responses/prepare-suspended-payment-creation.json b/test/fixtures/api/responses/prepare-suspended-payment-creation.json index 9b1ae3ff55..76cd7c30b3 100644 --- a/test/fixtures/api/responses/prepare-suspended-payment-creation.json +++ b/test/fixtures/api/responses/prepare-suspended-payment-creation.json @@ -1,5 +1,5 @@ { - "txJSON": "{\"Flags\":0,\"TransactionType\":\"SuspendedPaymentCreate\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"Destination\":\"rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo\",\"Amount\":{\"value\":\"0.01\",\"currency\":\"USD\",\"issuer\":\"rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM\"},\"CancelAfter\":494009529,\"LastLedgerSequence\":8820051,\"Fee\":\"12\",\"Sequence\":23}", + "txJSON": "{\"Flags\":2147483648,\"TransactionType\":\"SuspendedPaymentCreate\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"Destination\":\"rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo\",\"Amount\":{\"value\":\"0.01\",\"currency\":\"USD\",\"issuer\":\"rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM\"},\"CancelAfter\":494009529,\"LastLedgerSequence\":8820051,\"Fee\":\"12\",\"Sequence\":23}", "instructions": { "fee": "12", "sequence": 23, diff --git a/test/fixtures/api/responses/prepare-suspended-payment-execution.json b/test/fixtures/api/responses/prepare-suspended-payment-execution.json index 5437dd6634..61eb7302ac 100644 --- a/test/fixtures/api/responses/prepare-suspended-payment-execution.json +++ b/test/fixtures/api/responses/prepare-suspended-payment-execution.json @@ -1,5 +1,5 @@ { - "txJSON": "{\"Flags\":0,\"TransactionType\":\"SuspendedPaymentFinish\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"Owner\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"OfferSequence\":1234,\"Method\":1,\"Digest\":\"8F434346648F6B96DF89DDA901C5176B10A6D83961DD3C1AC88B59B2DC327AA4\",\"Proof\":\"7768617465766572\",\"LastLedgerSequence\":8820051,\"Fee\":\"12\",\"Sequence\":23}", + "txJSON": "{\"Flags\":2147483648,\"TransactionType\":\"SuspendedPaymentFinish\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"Owner\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"OfferSequence\":1234,\"Method\":1,\"Digest\":\"8F434346648F6B96DF89DDA901C5176B10A6D83961DD3C1AC88B59B2DC327AA4\",\"Proof\":\"7768617465766572\",\"LastLedgerSequence\":8820051,\"Fee\":\"12\",\"Sequence\":23}", "instructions": { "fee": "12", "sequence": 23, diff --git a/test/fixtures/api/responses/prepare-trustline-simple.json b/test/fixtures/api/responses/prepare-trustline-simple.json index c3f52eda1c..db64cca7d3 100644 --- a/test/fixtures/api/responses/prepare-trustline-simple.json +++ b/test/fixtures/api/responses/prepare-trustline-simple.json @@ -1,5 +1,5 @@ { - "txJSON": "{\"Flags\":0,\"TransactionType\":\"TrustSet\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"LimitAmount\":{\"value\":\"0.1\",\"currency\":\"BTC\",\"issuer\":\"rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM\"},\"LastLedgerSequence\":8820051,\"Fee\":\"12\",\"Sequence\":23}", + "txJSON": "{\"Flags\":2147483648,\"TransactionType\":\"TrustSet\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"LimitAmount\":{\"value\":\"0.1\",\"currency\":\"BTC\",\"issuer\":\"rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM\"},\"LastLedgerSequence\":8820051,\"Fee\":\"12\",\"Sequence\":23}", "instructions": { "fee": "12", "sequence": 23, diff --git a/test/fixtures/api/responses/prepare-trustline.json b/test/fixtures/api/responses/prepare-trustline.json index 82de14a6ce..c32ae27969 100644 --- a/test/fixtures/api/responses/prepare-trustline.json +++ b/test/fixtures/api/responses/prepare-trustline.json @@ -1,5 +1,5 @@ { - "txJSON": "{\"Flags\":2228224,\"TransactionType\":\"TrustSet\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"LimitAmount\":{\"value\":\"10000\",\"currency\":\"USD\",\"issuer\":\"rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM\"},\"QualityIn\":910000000,\"QualityOut\":870000000,\"LastLedgerSequence\":8820051,\"Fee\":\"12\",\"Sequence\":23}", + "txJSON": "{\"Flags\":2149711872,\"TransactionType\":\"TrustSet\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"LimitAmount\":{\"value\":\"10000\",\"currency\":\"USD\",\"issuer\":\"rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM\"},\"QualityIn\":910000000,\"QualityOut\":870000000,\"LastLedgerSequence\":8820051,\"Fee\":\"12\",\"Sequence\":23}", "instructions": { "fee": "12", "sequence": 23, diff --git a/test/fixtures/api/responses/sign.json b/test/fixtures/api/responses/sign.json index 8161e776c7..18f19d49f5 100644 --- a/test/fixtures/api/responses/sign.json +++ b/test/fixtures/api/responses/sign.json @@ -1,4 +1,4 @@ { - "signedTransaction": "12000322000000002400000017201B0086955368400000000000000C732102F89EAEC7667B30F33D0687BBA86C3FE2A08CCA40A9186C5BDE2DAA6FA97A37D874473045022100E3C85A98C3D48E2D746B3993D36C38A8922D9499E7D20B54883511C9CFF7F70A02201790168F671AC558E1B62B911CA7AC5B1D8E454898BE6F6E9D87758076683459770A726970706C652E636F6D81145E7B112523F68D2F5E879DB4EAC51C6698A69304", - "id": "7AFE2F2FBE72467C47CCDD6DBA890AB3C97A708C335983F77AF32C4308C73633" + "signedTransaction": "12000322800000002400000017201B0086955368400000000000000C732102F89EAEC7667B30F33D0687BBA86C3FE2A08CCA40A9186C5BDE2DAA6FA97A37D874473045022100BDE09A1F6670403F341C21A77CF35BA47E45CDE974096E1AA5FC39811D8269E702203D60291B9A27F1DCABA9CF5DED307B4F23223E0B6F156991DB601DFB9C41CE1C770A726970706C652E636F6D81145E7B112523F68D2F5E879DB4EAC51C6698A69304", + "id": "02ACE87F1996E3A23690A5BB7F1774BF71CCBA68F79805831B42ABAD5913D6F4" } diff --git a/test/integration/integration-test.js b/test/integration/integration-test.js index 3593823214..3af7f764cc 100644 --- a/test/integration/integration-test.js +++ b/test/integration/integration-test.js @@ -3,143 +3,129 @@ 'use strict'; const _ = require('lodash'); const assert = require('assert'); -const async = require('async'); - const errors = require('../../src/api/common/errors'); -const composeAsync = require('../../src/api/common/utils').composeAsync; -const common = require('../../src/api/common'); -const validate = common.validate; - +const validate = require('../../src/api/common').validate; const wallet = require('./wallet'); - -const settingsSpecification = require('../fixtures/settings-specification'); -const trustlineSpecification = require('../fixtures/trustline-specification'); -const payments = require('../fixtures/payments'); - +const requests = require('../fixtures/api/requests'); const RippleAPI = require('../../src').RippleAPI; -const TIMEOUT = 20000; // how long before each test case times out -const INTERVAL = 2000; // how long to wait between checks for validated ledger +const TIMEOUT = 30000; // how long before each test case times out +const INTERVAL = 1000; // how long to wait between checks for validated ledger -function verifyTransaction(testcase, hash, type, options, txData, done) { - testcase.api.getTransaction(hash, options, (err, data) => { - if (err instanceof errors.NotFoundError - && testcase.api.getLedgerVersion() <= options.maxLedgerVersion) { - console.log('NOT VALIDATED YET...'); - setTimeout(_.partial(verifyTransaction, testcase, hash, type, - options, txData, done), INTERVAL); - return; - } else if (err) { - done(err); - return; - } +function verifyTransaction(testcase, hash, type, options, txData) { + console.log('VERIFY...'); + return testcase.api.getTransaction(hash, options).then(data => { assert(data && data.outcome); assert.strictEqual(data.type, type); assert.strictEqual(data.address, wallet.getAddress()); assert.strictEqual(data.outcome.result, 'tesSUCCESS'); testcase.transactions.push(hash); - done(null, txData); + return {txJSON: JSON.stringify(txData), id: hash, tx: data}; + }).catch(error => { + if (error instanceof errors.PendingLedgerVersionError) { + console.log('NOT VALIDATED YET...'); + return new Promise((resolve, reject) => { + setTimeout(() => verifyTransaction(testcase, hash, type, + options, txData).then(resolve, reject), INTERVAL); + }); + } + assert(false, 'Transaction not successful: ' + error.message); }); } -function testTransaction(testcase, type, lastClosedLedgerVersion, - txData, done) { - - const signedData = testcase.api.sign(txData, wallet.getSecret()); +function testTransaction(testcase, type, lastClosedLedgerVersion, prepared) { + const txJSON = prepared.txJSON; + assert(txJSON, 'missing txJSON'); + const txData = JSON.parse(txJSON); + assert.strictEqual(txData.Account, wallet.getAddress()); + const signedData = testcase.api.sign(txJSON, wallet.getSecret()); console.log('PREPARED...'); - testcase.api.submit(signedData.signedTransaction, (error, data) => { + return testcase.api.submit(signedData.signedTransaction).then(data => { console.log('SUBMITTED...'); - if (error) { - done(error); - return; - } - assert.strictEqual(data.engine_result, 'tesSUCCESS'); + assert.strictEqual(data.engineResult, 'tesSUCCESS'); const options = { minLedgerVersion: lastClosedLedgerVersion, maxLedgerVersion: txData.LastLedgerSequence }; - setTimeout(_.partial(verifyTransaction, testcase, signedData.id, type, - options, txData, done), INTERVAL); + return new Promise((resolve, reject) => { + setTimeout(() => verifyTransaction(testcase, signedData.id, type, + options, txData).then(resolve, reject), INTERVAL); + }); }); } -function verifyResult(transactionType, transaction, done) { - assert(transaction); - assert.strictEqual(transaction.Account, wallet.getAddress()); - assert.strictEqual(transaction.TransactionType, transactionType); - done(null, transaction); +function setup() { + this.api = new RippleAPI({servers: ['wss://s1.ripple.com']}); + console.log('CONNECTING...'); + return this.api.connect().then(() => { + console.log('CONNECTED...'); + }); } - -function setup(done) { - this.api = new RippleAPI({servers: ['wss://s1.ripple.com:443']}); - this.api.connect(() => { - this.api.remote.getServer().once('ledger_closed', () => { - // this will initialiaze startLedgerVersion with - // on first run and will not overwrite on next invocations - if (!this.startLedgerVersion) { - this.startLedgerVersion = this.api.getLedgerVersion(); - } - done(); - }); - }); +function teardown() { + return this.api.disconnect(); } -function teardown(done) { - this.api.remote.disconnect(done); +function suiteSetup() { + this.transactions = []; + return setup.bind(this)().then(() => { + return this.api.getLedgerVersion().then(ledgerVersion => { + this.startLedgerVersion = ledgerVersion; + }); + }).then(teardown.bind(this)); } -describe.skip('integration tests', function() { - const instructions = {maxLedgerVersionOffset: 100}; +describe('integration tests', function() { + const address = wallet.getAddress(); + const instructions = {maxLedgerVersionOffset: 10}; this.timeout(TIMEOUT); - before(function() { - this.transactions = []; - }); + before(suiteSetup); beforeEach(setup); afterEach(teardown); - it('settings', function(done) { - const lastClosedLedgerVersion = this.api.getLedgerVersion(); - async.waterfall([ - this.api.prepareSettings.bind(this.api, wallet.getAddress(), - settingsSpecification, instructions), - _.partial(verifyResult, 'AccountSet'), - _.partial(testTransaction, this, 'settings', lastClosedLedgerVersion) - ], () => done()); + + it('settings', function() { + return this.api.getLedgerVersion().then(ledgerVersion => { + return this.api.prepareSettings(address, + requests.prepareSettings, instructions).then(prepared => + testTransaction(this, 'settings', ledgerVersion, prepared)); + }); }); - it('trustline', function(done) { - const lastClosedLedgerVersion = this.api.getLedgerVersion(); - async.waterfall([ - this.api.prepareTrustline.bind(this.api, wallet.getAddress(), - trustlineSpecification, instructions), - _.partial(verifyResult, 'TrustSet'), - _.partial(testTransaction, this, 'trustline', lastClosedLedgerVersion) - ], () => done()); + it('trustline', function() { + return this.api.getLedgerVersion().then(ledgerVersion => { + return this.api.prepareTrustline(address, + requests.prepareTrustline.simple, instructions).then(prepared => + testTransaction(this, 'trustline', ledgerVersion, prepared)); + }); }); - it('payment', function(done) { - const paymentSpecification = payments.payment({ - value: '0.000001', - sourceAccount: wallet.getAddress(), - destinationAccount: 'rKmBGxocj9Abgy25J51Mk1iqFzW9aVF9Tc' + it('payment', function() { + const amount = {currency: 'XRP', value: '0.000001'}; + const paymentSpecification = { + source: { + address: address, + maxAmount: amount + }, + destination: { + address: 'rKmBGxocj9Abgy25J51Mk1iqFzW9aVF9Tc', + amount: amount + } + }; + return this.api.getLedgerVersion().then(ledgerVersion => { + return this.api.preparePayment(address, + paymentSpecification, instructions).then(prepared => + testTransaction(this, 'payment', ledgerVersion, prepared)); }); - const lastClosedLedgerVersion = this.api.getLedgerVersion(); - async.waterfall([ - this.api.preparePayment.bind(this.api, wallet.getAddress(), - paymentSpecification, instructions), - _.partial(verifyResult, 'Payment'), - _.partial(testTransaction, this, 'payment', lastClosedLedgerVersion) - ], () => done()); }); - it('order', function(done) { + it('order', function() { const orderSpecification = { direction: 'buy', quantity: { @@ -152,34 +138,28 @@ describe.skip('integration tests', function() { value: '0.0002' } }; - const self = this; - const lastClosedLedgerVersion = this.api.getLedgerVersion(); - async.waterfall([ - this.api.prepareOrder.bind(this.api, wallet.getAddress(), - orderSpecification, instructions), - _.partial(verifyResult, 'OfferCreate'), - _.partial(testTransaction, this, 'order', lastClosedLedgerVersion), - (txData, callback) => { - this.api.getOrders(wallet.getAddress(), {}, composeAsync(orders => { - assert(orders && orders.length > 0); - const createdOrder = _.first(_.filter(orders, (order) => { - return order.properties.sequence === txData.Sequence; - })); - assert(createdOrder); - assert.strictEqual(createdOrder.properties.maker, - wallet.getAddress()); - assert.deepEqual(createdOrder.specification, orderSpecification); - return txData; - }, callback)); - }, - (txData, callback) => { - self.api.prepareOrderCancellation(wallet.getAddress(), txData.Sequence, - instructions, callback); - }, - _.partial(verifyResult, 'OfferCancel'), - _.partial(testTransaction, this, 'orderCancellation', - lastClosedLedgerVersion) - ], () => done()); + return this.api.getLedgerVersion().then(ledgerVersion => { + return this.api.prepareOrder(address, + orderSpecification, instructions).then(prepared => + testTransaction(this, 'order', ledgerVersion, prepared) + ).then(result => { + const txData = JSON.parse(result.txJSON); + return this.api.getOrders(address).then(orders => { + assert(orders && orders.length > 0); + const createdOrder = _.first(_.filter(orders, order => { + return order.properties.sequence === txData.Sequence; + })); + assert(createdOrder); + assert.strictEqual(createdOrder.properties.maker, address); + assert.deepEqual(createdOrder.specification, orderSpecification); + return txData; + }); + }).then(txData => this.api.prepareOrderCancellation( + address, txData.Sequence, instructions).then(prepared => + testTransaction(this, 'orderCancellation', ledgerVersion, + prepared)) + ); + }); }); @@ -188,81 +168,73 @@ describe.skip('integration tests', function() { }); - it('getServerInfo', function(done) { - this.api.getServerInfo(composeAsync(data => { - assert(data && data.info && data.info.pubkey_node); - }, done)); + it('getServerInfo', function() { + return this.api.getServerInfo().then(data => { + assert(data && data.pubkeyNode); + }); }); it('getFee', function() { const fee = this.api.getFee(); assert.strictEqual(typeof fee, 'string'); - assert(!isNaN(+fee)); + assert(!isNaN(Number(fee))); }); it('getLedgerVersion', function() { - const ledgerVersion = this.api.getLedgerVersion(); - assert.strictEqual(typeof ledgerVersion, 'number'); - assert(ledgerVersion >= this.startLedgerVersion); + return this.api.getLedgerVersion().then(ledgerVersion => { + assert.strictEqual(typeof ledgerVersion, 'number'); + assert(ledgerVersion >= this.startLedgerVersion); + }); }); - it('getTransactions', function(done) { + it('getTransactions', function() { const options = { - outgoing: true, + initiated: true, minLedgerVersion: this.startLedgerVersion }; - this.api.getTransactions(wallet.getAddress(), options, - composeAsync(transactionsData => { - assert(transactionsData); - assert.strictEqual(transactionsData.length, this.transactions.length); - }, done)); + return this.api.getTransactions(address, options).then(transactionsData => { + assert(transactionsData); + assert.strictEqual(transactionsData.length, this.transactions.length); + }); }); - it('getTrustlines', function(done) { - const options = { - currency: trustlineSpecification.currency, - counterparty: trustlineSpecification.counterparty - }; - this.api.getTrustlines(wallet.getAddress(), options, composeAsync(data => { + it('getTrustlines', function() { + const fixture = requests.prepareTrustline.simple; + const options = _.pick(fixture, ['currency', 'counterparty']); + return this.api.getTrustlines(address, options).then(data => { assert(data && data.length > 0 && data[0] && data[0].specification); const specification = data[0].specification; - assert.strictEqual(specification.limit, trustlineSpecification.limit); - assert.strictEqual(specification.currency, - trustlineSpecification.currency); - assert.strictEqual(specification.counterparty, - trustlineSpecification.counterparty); - }, done)); + assert.strictEqual(Number(specification.limit), Number(fixture.limit)); + assert.strictEqual(specification.currency, fixture.currency); + assert.strictEqual(specification.counterparty, fixture.counterparty); + }); }); - it('getBalances', function(done) { - const options = { - currency: trustlineSpecification.currency, - counterparty: trustlineSpecification.counterparty - }; - this.api.getBalances(wallet.getAddress(), options, composeAsync(data => { - assert(data && data.length > 1 && data[0] && data[1]); - assert.strictEqual(data[0].currency, 'XRP'); - assert.strictEqual(data[1].currency, trustlineSpecification.currency); - assert.strictEqual(data[1].counterparty, - trustlineSpecification.counterparty); - }, done)); + it('getBalances', function() { + const fixture = requests.prepareTrustline.simple; + const options = _.pick(fixture, ['currency', 'counterparty']); + return this.api.getBalances(address, options).then(data => { + assert(data && data.length > 0 && data[0]); + assert.strictEqual(data[0].currency, fixture.currency); + assert.strictEqual(data[0].counterparty, fixture.counterparty); + }); }); - it('getSettings', function(done) { - this.api.getSettings(wallet.getAddress(), {}, composeAsync(data => { - assert(data && data.sequence); - assert.strictEqual(data.domain, settingsSpecification.domain); - }, done)); + it('getSettings', function() { + return this.api.getSettings(address).then(data => { + assert(data); + assert.strictEqual(data.domain, requests.prepareSettings.domain); + }); }); - it('getOrderbook', function(done) { + it('getOrderbook', function() { const orderbook = { base: { currency: 'XRP' @@ -272,73 +244,53 @@ describe.skip('integration tests', function() { counterparty: 'rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q' } }; - this.api.getOrderbook(wallet.getAddress(), orderbook, {}, - composeAsync(book => { - assert(book && book.bids && book.bids.length > 0); - assert(book.asks && book.asks.length > 0); - const bid = book.bids[0]; - assert(bid && bid.specification && bid.specification.quantity); - assert(bid.specification.totalPrice); - assert.strictEqual(bid.specification.direction, 'buy'); - assert.strictEqual(bid.specification.quantity.currency, 'XRP'); - assert.strictEqual(bid.specification.totalPrice.currency, 'USD'); - const ask = book.asks[0]; - assert(ask && ask.specification && ask.specification.quantity); - assert(ask.specification.totalPrice); - assert.strictEqual(ask.specification.direction, 'sell'); - assert.strictEqual(ask.specification.quantity.currency, 'XRP'); - assert.strictEqual(ask.specification.totalPrice.currency, 'USD'); - }, done)); + return this.api.getOrderbook(address, orderbook).then(book => { + assert(book && book.bids && book.bids.length > 0); + assert(book.asks && book.asks.length > 0); + const bid = book.bids[0]; + assert(bid && bid.specification && bid.specification.quantity); + assert(bid.specification.totalPrice); + assert.strictEqual(bid.specification.direction, 'buy'); + assert.strictEqual(bid.specification.quantity.currency, 'XRP'); + assert.strictEqual(bid.specification.totalPrice.currency, 'USD'); + const ask = book.asks[0]; + assert(ask && ask.specification && ask.specification.quantity); + assert(ask.specification.totalPrice); + assert.strictEqual(ask.specification.direction, 'sell'); + assert.strictEqual(ask.specification.quantity.currency, 'XRP'); + assert.strictEqual(ask.specification.totalPrice.currency, 'USD'); + }); }); - it('getPaths', function(done) { + it('getPaths', function() { const pathfind = { source: { - address: wallet.getAddress() + address: address }, destination: { - address: wallet.getAddress(), + address: 'rKmBGxocj9Abgy25J51Mk1iqFzW9aVF9Tc', amount: { value: '0.000001', - currency: trustlineSpecification.currency, - counterparty: trustlineSpecification.counterparty + currency: 'USD', + counterparty: 'rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q' } } }; - this.api.getPaths(pathfind, composeAsync(data => { + return this.api.getPaths(pathfind).then(data => { assert(data && data.length > 0); const path = data[0]; assert(path && path.source); - assert.strictEqual(path.source.address, wallet.getAddress()); + assert.strictEqual(path.source.address, address); assert(path.paths && path.paths.length > 0); - }, done)); + }); }); it('generateWallet', function() { - const newWallet = this.api.generateWallet(); + const newWallet = this.api.generateAddress(); assert(newWallet && newWallet.address && newWallet.secret); validate.addressAndSecret(newWallet); }); - /* - // the 'order' test case already tests order cancellation - // this is just for cancelling orders if something goes wrong during testing - it('cancel order', function(done) { - const sequence = 280; - const lastClosedLedgerVersion = this.api.getLedgerVersion(); - this.api.prepareOrderCancellation(wallet.getAddress(), sequence, - instructions, (cerr, cancellationTxData) => { - if (cerr) { - done(cerr); - return; - } - verifyResult('OfferCancel', cancellationTxData); - testTransaction(this, cancellationTxData, 'orderCancellation', - lastClosedLedgerVersion, done); - }); - }); - */ - });