From 995606b1e6f3643af34d9fd442ccd31f320b03eb Mon Sep 17 00:00:00 2001 From: Ivan Tivonenko Date: Mon, 23 Nov 2015 19:18:03 +0200 Subject: [PATCH] boost coverage to almost 100% --- docs/index.md | 13 +- src/common/connection.js | 6 +- src/common/schemas/input/api-options.json | 5 + src/common/schemas/output/get-trustlines.json | 2 +- src/index.js | 3 +- src/ledger/transactions.js | 3 - src/transaction/payment.js | 6 +- src/transaction/trustline.js | 3 +- test/api-test.js | 550 +++++++++++++++++- .../requests/get-orderbook-with-xrp.json | 9 + test/fixtures/requests/getpaths/invalid.json | 16 + test/fixtures/requests/getpaths/issuer.json | 16 + test/fixtures/requests/index.js | 19 +- test/fixtures/requests/prepare-order.json | 3 +- .../requests/prepare-payment-min-xrp.json | 17 + .../requests/prepare-payment-min.json | 17 + .../prepare-payment-wrong-address.json | 17 + .../prepare-payment-wrong-amount.json | 17 + .../prepare-payment-wrong-partial.json | 17 + ...-suspended-payment-cancellation-memos.json | 11 + ...epare-suspended-payment-creation-full.json | 28 + ...re-suspended-payment-execution-simple.json | 11 + .../requests/prepare-trustline-frozen.json | 8 + test/fixtures/requests/sign.json | 2 +- .../get-ledger-with-settings-tx.json | 2 +- .../get-ledger-with-state-as-hashes.json | 20 + .../responses/get-orderbook-with-xrp.json | 44 ++ .../responses/get-transaction-no-meta.json | 23 + .../responses/get-transaction-order-sell.json | 34 ++ ...nsaction-suspended-payment-create-iou.json | 51 ++ ...on-suspended-payment-execution-simple.json | 34 ++ .../responses/get-transactions-one.json | 27 + .../responses/get-trustlines-all.json | 333 +++++++++++ test/fixtures/responses/index.js | 32 +- ...re-order-cancellation-no-instructions.json | 8 + test/fixtures/responses/prepare-order.json | 4 +- .../prepare-payment-min-amont-xrp-xrp.json | 8 + .../prepare-payment-min-amont-xrp.json | 8 + .../prepare-settings-no-instructions.json | 1 + ...-suspended-payment-cancellation-memos.json | 8 + ...epare-suspended-payment-creation-full.json | 8 + ...re-suspended-payment-execution-simple.json | 8 + .../responses/prepare-trustline-frozen.json | 8 + test/fixtures/rippled/account-offers.js | 1 + test/fixtures/rippled/book-offers-1.json | 31 + test/fixtures/rippled/book-offers-2.json | 32 + .../rippled/get-transactions-one.json | 58 ++ test/fixtures/rippled/index.js | 14 +- .../rippled/ledger-with-settings-tx.json | 1 + .../rippled/ledger-with-state-as-hashes.json | 33 ++ test/fixtures/rippled/tx/ledger-zero.json | 46 ++ test/fixtures/rippled/tx/no-meta.json | 44 ++ .../rippled/tx/offer-create-sell.json | 51 ++ .../tx/suspended-payment-creation-iou.json | 97 +++ .../suspended-payment-execution-simple.json | 99 ++++ test/fixtures/rippled/tx/unrecognized.json | 46 ++ test/mock-rippled.js | 39 +- 57 files changed, 2014 insertions(+), 38 deletions(-) create mode 100644 test/fixtures/requests/get-orderbook-with-xrp.json create mode 100644 test/fixtures/requests/getpaths/invalid.json create mode 100644 test/fixtures/requests/getpaths/issuer.json create mode 100644 test/fixtures/requests/prepare-payment-min-xrp.json create mode 100644 test/fixtures/requests/prepare-payment-min.json create mode 100644 test/fixtures/requests/prepare-payment-wrong-address.json create mode 100644 test/fixtures/requests/prepare-payment-wrong-amount.json create mode 100644 test/fixtures/requests/prepare-payment-wrong-partial.json create mode 100644 test/fixtures/requests/prepare-suspended-payment-cancellation-memos.json create mode 100644 test/fixtures/requests/prepare-suspended-payment-creation-full.json create mode 100644 test/fixtures/requests/prepare-suspended-payment-execution-simple.json create mode 100644 test/fixtures/requests/prepare-trustline-frozen.json create mode 100644 test/fixtures/responses/get-ledger-with-state-as-hashes.json create mode 100644 test/fixtures/responses/get-orderbook-with-xrp.json create mode 100644 test/fixtures/responses/get-transaction-no-meta.json create mode 100644 test/fixtures/responses/get-transaction-order-sell.json create mode 100644 test/fixtures/responses/get-transaction-suspended-payment-create-iou.json create mode 100644 test/fixtures/responses/get-transaction-suspended-payment-execution-simple.json create mode 100644 test/fixtures/responses/get-transactions-one.json create mode 100644 test/fixtures/responses/get-trustlines-all.json create mode 100644 test/fixtures/responses/prepare-order-cancellation-no-instructions.json create mode 100644 test/fixtures/responses/prepare-payment-min-amont-xrp-xrp.json create mode 100644 test/fixtures/responses/prepare-payment-min-amont-xrp.json create mode 100644 test/fixtures/responses/prepare-settings-no-instructions.json create mode 100644 test/fixtures/responses/prepare-suspended-payment-cancellation-memos.json create mode 100644 test/fixtures/responses/prepare-suspended-payment-creation-full.json create mode 100644 test/fixtures/responses/prepare-suspended-payment-execution-simple.json create mode 100644 test/fixtures/responses/prepare-trustline-frozen.json create mode 100644 test/fixtures/rippled/book-offers-1.json create mode 100644 test/fixtures/rippled/book-offers-2.json create mode 100644 test/fixtures/rippled/get-transactions-one.json create mode 100644 test/fixtures/rippled/ledger-with-state-as-hashes.json create mode 100644 test/fixtures/rippled/tx/ledger-zero.json create mode 100644 test/fixtures/rippled/tx/no-meta.json create mode 100644 test/fixtures/rippled/tx/offer-create-sell.json create mode 100644 test/fixtures/rippled/tx/suspended-payment-creation-iou.json create mode 100644 test/fixtures/rippled/tx/suspended-payment-execution-simple.json create mode 100644 test/fixtures/rippled/tx/unrecognized.json diff --git a/docs/index.md b/docs/index.md index 714b8f42..c14f12ed 100644 --- a/docs/index.md +++ b/docs/index.md @@ -112,6 +112,7 @@ feeCushion | number | *Optional* Factor to multiply estimated fee by to provide proxy | uri string | *Optional* URI for HTTP/HTTPS proxy to use to connect to the rippled server. proxyAuthorization | string | *Optional* Username and password for HTTP basic authentication to the proxy in the format **username:password**. servers | array\ | *Optional* Array of rippled servers to connect to. Currently only one server is supported. +timeout | integer | *Optional* Timeout in milliseconds before considering a request to have failed. trace | boolean | *Optional* If true, log rippled requests and responses to stdout. trustedCertificates | array\ | *Optional* Array of PEM-formatted SSL certificates to trust when connecting to a proxy. This is useful if you want to use a self-signed certificate on the proxy server. Note: Each element must contain a single certificate; concatenated certificates are not valid. @@ -373,7 +374,8 @@ passive | boolean | *Optional* If enabled, the offer will not consume offers tha "currency": "XRP", "value": "2" }, - "immediateOrCancel": true + "passive": true, + "fillOrKill": true } ``` @@ -1120,7 +1122,7 @@ counterparty | object | Properties of the trustline from the perspective of the *counterparty.* frozen | boolean | *Optional* If true, the trustline is frozen, which means that funds can only be sent to the counterparty. *counterparty.* ripplingDisabled | boolean | *Optional* If true, payments cannot ripple through this trustline. state | object | Properties of the trustline regarding it's current state that are not part of the specification. -*state.* balance | [value](#value) | The balance on the trustline, representing which party owes the other and by how much. +*state.* balance | [signedValue](#value) | The balance on the trustline, representing which party owes the other and by how much. ### Example @@ -2888,7 +2890,8 @@ const order = { "currency": "XRP", "value": "2" }, - "immediateOrCancel": true + "passive": true, + "fillOrKill": true }; return api.prepareOrder(address, order) .then(prepared => {/* ... */}); @@ -2897,11 +2900,11 @@ return api.prepareOrder(address, order) ```json { - "txJSON": "{\"Flags\":2147614720,\"TransactionType\":\"OfferCreate\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"TakerGets\":\"2000000\",\"TakerPays\":{\"value\":\"10.1\",\"currency\":\"USD\",\"issuer\":\"rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM\"},\"LastLedgerSequence\":8820051,\"Fee\":\"12\",\"Sequence\":23}", + "txJSON": "{\"Flags\":2147811328,\"TransactionType\":\"OfferCreate\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"TakerGets\":\"2000000\",\"TakerPays\":{\"value\":\"10.1\",\"currency\":\"USD\",\"issuer\":\"rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM\"},\"LastLedgerSequence\":8819954,\"Fee\":\"12\",\"Sequence\":23}", "instructions": { "fee": "0.000012", "sequence": 23, - "maxLedgerVersion": 8820051 + "maxLedgerVersion": 8819954 } } ``` diff --git a/src/common/connection.js b/src/common/connection.js index cf11b9bd..bfec45aa 100644 --- a/src/common/connection.js +++ b/src/common/connection.js @@ -80,6 +80,7 @@ class Connection extends EventEmitter { } _onUnexpectedClose() { + this._ws = null; this._isReady = false; this.connect().then(); } @@ -140,7 +141,8 @@ class Connection extends EventEmitter { this._proxyAuthorization, this._authorization, this._trustedCertificates); this._ws.on('message', this._onMessage.bind(this)); - this._ws.once('close', () => this._onUnexpectedClose); + this._onUnexpectedCloseBound = this._onUnexpectedClose.bind(this); + this._ws.once('close', this._onUnexpectedCloseBound); this._ws.once('open', () => this._onOpen().then(resolve, reject)); } }); @@ -153,7 +155,7 @@ class Connection extends EventEmitter { } else if (this._state === WebSocket.CLOSING) { this._ws.once('close', resolve); } else { - this._ws.removeListener('close', this._onUnexpectedClose); + this._ws.removeListener('close', this._onUnexpectedCloseBound); this._ws.once('close', () => { this._ws = null; this._isReady = false; diff --git a/src/common/schemas/input/api-options.json b/src/common/schemas/input/api-options.json index 8d9054f2..8c4bb8ff 100644 --- a/src/common/schemas/input/api-options.json +++ b/src/common/schemas/input/api-options.json @@ -26,6 +26,11 @@ "format": "uri", "description": "URI for HTTP/HTTPS proxy to use to connect to the rippled server." }, + "timeout": { + "type": "integer", + "description": "Timeout in milliseconds before considering a request to have failed.", + "minimum": 1 + }, "proxyAuthorization": { "type": "string", "description": "Username and password for HTTP basic authentication to the proxy in the format **username:password**." diff --git a/src/common/schemas/output/get-trustlines.json b/src/common/schemas/output/get-trustlines.json index 5fdced13..49a5a32d 100644 --- a/src/common/schemas/output/get-trustlines.json +++ b/src/common/schemas/output/get-trustlines.json @@ -34,7 +34,7 @@ "state": { "properties": { "balance": { - "$ref": "value", + "$ref": "signedValue", "description": "The balance on the trustline, representing which party owes the other and by how much." } }, diff --git a/src/index.js b/src/index.js index 4ae30557..098296e5 100644 --- a/src/index.js +++ b/src/index.js @@ -54,7 +54,8 @@ type APIOptions = { servers?: Array, feeCushion?: number, trace?: boolean, - proxy?: string + proxy?: string, + timeout?: number } // prevent access to non-validated ledger versions diff --git a/src/ledger/transactions.js b/src/ledger/transactions.js index fe805b08..5ddc43a6 100644 --- a/src/ledger/transactions.js +++ b/src/ledger/transactions.js @@ -47,9 +47,6 @@ function parseAccountTxTransaction(tx) { } function counterpartyFilter(filters, tx: TransactionType) { - if (!filters.counterparty) { - return true; - } if (tx.address === filters.counterparty || ( tx.specification && ( (tx.specification.destination && diff --git a/src/transaction/payment.js b/src/transaction/payment.js index e9ff4336..8b04b05c 100644 --- a/src/transaction/payment.js +++ b/src/transaction/payment.js @@ -33,8 +33,10 @@ type Payment = { } function isXRPToXRPPayment(payment: Payment): boolean { - const sourceCurrency = _.get(payment, 'source.maxAmount.currency'); - const destinationCurrency = _.get(payment, 'destination.amount.currency'); + const sourceCurrency = _.get(payment, 'source.maxAmount.currency', + _.get(payment, 'source.amount.currency')); + const destinationCurrency = _.get(payment, 'destination.amount.currency', + _.get(payment, 'destination.minAmount.currency')); return sourceCurrency === 'XRP' && destinationCurrency === 'XRP'; } diff --git a/src/transaction/trustline.js b/src/transaction/trustline.js index b9ba7ad0..7725a00f 100644 --- a/src/transaction/trustline.js +++ b/src/transaction/trustline.js @@ -8,8 +8,7 @@ import type {Instructions, Prepare} from './types.js'; import type {TrustLineSpecification} from '../ledger/trustlines-types.js'; function convertQuality(quality) { - return quality === undefined ? undefined : - (new BigNumber(quality)).shift(9).truncated().toNumber(); + return (new BigNumber(quality)).shift(9).truncated().toNumber(); } function createTrustlineTransaction(account: string, diff --git a/test/api-test.js b/test/api-test.js index 34dcaf28..58fffdf6 100644 --- a/test/api-test.js +++ b/test/api-test.js @@ -1,6 +1,7 @@ /* eslint-disable max-nested-callbacks */ 'use strict'; const _ = require('lodash'); +const net = require('net'); const assert = require('assert-diff'); const setupAPI = require('./setup-api'); const RippleAPI = require('ripple-api').RippleAPI; @@ -15,6 +16,9 @@ const utils = RippleAPI._PRIVATE.ledgerUtils; const ledgerClosed = require('./fixtures/rippled/ledger-close-newer'); const schemaValidator = RippleAPI._PRIVATE.schemaValidator; +function unused() { +} + function closeLedger(connection) { connection._ws.emit('message', JSON.stringify(ledgerClosed)); } @@ -31,11 +35,247 @@ function checkResult(expected, schemaName, response) { return response; } +function createServer() { + return new Promise((resolve, reject) => { + const server = net.createServer(); + server.on('listening', function() { + resolve(server); + }); + server.on('error', function(error) { + reject(error); + }); + server.listen(0, '0.0.0.0'); + }); +} + + describe('RippleAPI', function() { const instructions = {maxLedgerVersionOffset: 100}; beforeEach(setupAPI.setup); afterEach(setupAPI.teardown); + describe('Connection', function() { + + it('connection default options', function() { + const connection = new utils.common.Connection('url'); + assert.strictEqual(connection._url, 'url'); + assert(_.isUndefined(connection._proxyURL)); + assert(_.isUndefined(connection._authorization)); + }); + + it('with proxy', function(done) { + createServer().then((server) => { + const port = server.address().port; + const expect = 'CONNECT localhost'; + server.on('connection', (socket) => { + socket.on('data', (data) => { + const got = data.toString('ascii', 0, expect.length); + assert.strictEqual(got, expect); + server.close(); + done(); + }); + }); + + const options = { + proxy: 'ws://localhost:' + port, + authorization: 'authorization', + trustedCertificates: 'something' + }; + const connection = + new utils.common.Connection(this.api.connection._url, options); + connection.connect().catch(done); + connection.connect().catch(done); + }, done); + }); + + it('Multiply disconnect calls', function() { + this.api.disconnect(); + return this.api.disconnect(); + }); + + it('reconnect', function() { + return this.api.connection.reconnect(); + }); + + it('NotConnectedError', function() { + const connection = new utils.common.Connection('url'); + return connection.getLedgerVersion().then(() => { + assert(false, 'Should throw NotConnectedError'); + }).catch(error => { + assert(error instanceof this.api.errors.NotConnectedError); + }); + }); + + it('DisconnectedError', function() { + this.api.connection._send = function() { + this._ws.close(); + }; + return this.api.getServerInfo().then(() => { + assert(false, 'Should throw DisconnectedError'); + }).catch(error => { + assert(error instanceof this.api.errors.DisconnectedError); + }); + }); + + it('TimeoutError', function() { + this.api.connection._send = function() { + return Promise.resolve({}); + }; + const request = {command: 'server_info'}; + return this.api.connection.request(request, 1).then(() => { + assert(false, 'Should throw TimeoutError'); + }).catch(error => { + assert(error instanceof this.api.errors.TimeoutError); + }); + }); + + it('DisconnectedError on send', function() { + this.api.connection._ws.send = function(message, options, callback) { + unused(message, options); + callback({message: 'not connected'}); + }; + return this.api.getServerInfo().then(() => { + assert(false, 'Should throw DisconnectedError'); + }).catch(error => { + assert(error instanceof this.api.errors.DisconnectedError); + assert.strictEqual(error.message, 'not connected'); + }); + }); + + it('ResponseFormatError', function() { + this.api.connection._send = function(message) { + const parsed = JSON.parse(message); + setTimeout(() => { + this._ws.emit('message', JSON.stringify({ + id: parsed.id, + type: 'response', + status: 'unrecognized' + })); + }, 2); + return new Promise(() => {}); + }; + return this.api.getServerInfo().then(() => { + assert(false, 'Should throw ResponseFormatError'); + }).catch(error => { + assert(error instanceof this.api.errors.ResponseFormatError); + }); + }); + + it('reconnect on unexpected close ', function(done) { + this.api.connection.on('connected', () => { + done(); + }); + + setTimeout(() => { + this.api.connection._ws.close(); + }, 1); + }); + + it('Multiply connect calls', function() { + return this.api.connect().then(() => { + return this.api.connect(); + }); + }); + + it('hasLedgerVersion', function() { + return this.api.connection.hasLedgerVersion(8819951).then((result) => { + assert(result); + }); + }); + + it('Cannot connect because no server', function() { + const connection = new utils.common.Connection(); + return connection.connect().then(() => { + assert(false, 'Should throw ConnectionError'); + }).catch(error => { + assert(error instanceof this.api.errors.ConnectionError); + }); + }); + + it('connect multiserver error', function() { + const options = { + servers: ['wss://server1.com', 'wss://server2.com'] + }; + assert.throws(function() { + const api = new RippleAPI(options); + unused(api); + }, this.api.errors.RippleError); + }); + + it('connect throws error', function(done) { + this.api.once('error', (type, info) => { + assert.strictEqual(type, 'type'); + assert.strictEqual(info, 'info'); + done(); + }); + this.api.connection.emit('error', 'type', 'info'); + }); + + it('connection emit stream messages', function(done) { + let transactionCount = 0; + let pathFindCount = 0; + this.api.connection.on('transaction', () => { + transactionCount++; + }); + this.api.connection.on('path_find', () => { + pathFindCount++; + }); + this.api.connection.on('1', () => { + assert.strictEqual(transactionCount, 1); + assert.strictEqual(pathFindCount, 1); + done(); + }); + + this.api.connection._onMessage(JSON.stringify({ + type: 'transaction' + })); + this.api.connection._onMessage(JSON.stringify({ + type: 'path_find' + })); + this.api.connection._onMessage(JSON.stringify({ + type: 'response', id: 1 + })); + }); + + it('connection - invalid message id', function(done) { + this.api.on('error', (type, message) => { + assert.strictEqual(type, 'badMessage'); + assert.strictEqual(message, + '{"type":"response","id":"must be integer"}'); + done(); + }); + this.api.connection._onMessage(JSON.stringify({ + type: 'response', id: 'must be integer' + })); + }); + + it('connection - error message', function(done) { + this.api.on('error', (type, message) => { + assert.strictEqual(type, 'slowDown'); + assert.strictEqual(message, 'slow down'); + done(); + }); + this.api.connection._onMessage(JSON.stringify({ + error: 'slowDown', error_message: 'slow down' + })); + }); + + it('connection - unrecognized message type', function(done) { + this.api.on('error', (type, message) => { + assert.strictEqual(type, 'badMessage'); + assert.strictEqual(message, '{"type":"unknown"}'); + done(); + }); + + this.api.connection._onMessage(JSON.stringify({type: 'unknown'})); + }); + }); + + it('error inspect', function() { + const error = new this.api.errors.RippleError('mess', {data: 1}); + assert.strictEqual(error.inspect(), '[RippleError(mess, { data: 1 })]'); + }); + it('preparePayment', function() { const localInstructions = _.defaults({ maxFee: '0.000012' @@ -45,6 +285,40 @@ describe('RippleAPI', function() { _.partial(checkResult, responses.preparePayment.normal, 'prepare')); }); + it('preparePayment - min amount xrp', function() { + const localInstructions = _.defaults({ + maxFee: '0.000012' + }, instructions); + return this.api.preparePayment( + address, requests.preparePaymentMinAmountXRP, localInstructions).then( + _.partial(checkResult, responses.preparePayment.minAmountXRP, 'prepare')); + }); + + it('preparePayment - min amount xrp2xrp', function() { + return this.api.preparePayment( + address, requests.preparePaymentMinAmount, instructions).then( + _.partial(checkResult, + responses.preparePayment.minAmountXRPXRP, 'prepare')); + }); + + it('preparePayment - XRP to XRP no partial', function() { + assert.throws(() => { + this.api.preparePayment(address, requests.preparePaymentWrongPartial); + }, /XRP to XRP payments cannot be partial payments/); + }); + + it('preparePayment - address must match payment.source.address', function() { + assert.throws(() => { + this.api.preparePayment(address, requests.preparePaymentWrongAddress); + }, /address must match payment.source.address/); + }); + + it('preparePayment - wrong amount', function() { + assert.throws(() => { + this.api.preparePayment(address, requests.preparePaymentWrongAmount); + }, this.api.errors.ValidationError); + }); + it('preparePayment with all options specified', function() { return this.api.getLedgerVersion().then((ver) => { const localInstructions = { @@ -73,7 +347,7 @@ describe('RippleAPI', function() { it('prepareOrder - buy order', function() { const request = requests.prepareOrder.buy; - return this.api.prepareOrder(address, request, instructions) + return this.api.prepareOrder(address, request) .then(_.partial(checkResult, responses.prepareOrder.buy, 'prepare')); }); @@ -93,7 +367,15 @@ describe('RippleAPI', function() { it('prepareOrderCancellation', function() { const request = requests.prepareOrderCancellation; return this.api.prepareOrderCancellation(address, request, instructions) - .then(_.partial(checkResult, responses.prepareOrderCancellation, + .then(_.partial(checkResult, responses.prepareOrder.cancellation, + 'prepare')); + }); + + it('prepareOrderCancellation - no instructions', function() { + const request = requests.prepareOrderCancellation; + return this.api.prepareOrderCancellation(address, request) + .then(_.partial(checkResult, + responses.prepareOrder.cancellationNoInstructions, 'prepare')); }); @@ -103,6 +385,12 @@ describe('RippleAPI', function() { _.partial(checkResult, responses.prepareTrustline.simple, 'prepare')); }); + it('prepareTrustline - frozen', function() { + return this.api.prepareTrustline( + address, requests.prepareTrustline.frozen).then( + _.partial(checkResult, responses.prepareTrustline.frozen, 'prepare')); + }); + it('prepareTrustline - complex', function() { return this.api.prepareTrustline( address, requests.prepareTrustline.complex, instructions).then( @@ -115,6 +403,15 @@ describe('RippleAPI', function() { _.partial(checkResult, responses.prepareSettings.flags, 'prepare')); }); + it('prepareSettings - no instructions', function() { + return this.api.prepareSettings( + address, requests.prepareSettings).then( + _.partial( + checkResult, + responses.prepareSettings.noInstructions, + 'prepare')); + }); + it('prepareSettings - regularKey', function() { const regularKey = {regularKey: 'rAR8rR8sUkBoCZFawhkWzY4Y5YoyuznwD'}; return this.api.prepareSettings(address, regularKey, instructions).then( @@ -167,6 +464,13 @@ describe('RippleAPI', function() { 'prepare')); }); + it('prepareSuspendedPaymentCreation full', function() { + return this.api.prepareSuspendedPaymentCreation( + address, requests.prepareSuspendedPaymentCreationFull).then( + _.partial(checkResult, responses.prepareSuspendedPaymentCreationFull, + 'prepare')); + }); + it('prepareSuspendedPaymentExecution', function() { return this.api.prepareSuspendedPaymentExecution( address, requests.prepareSuspendedPaymentExecution, instructions).then( @@ -174,6 +478,13 @@ describe('RippleAPI', function() { 'prepare')); }); + it('prepareSuspendedPaymentExecution - simple', function() { + return this.api.prepareSuspendedPaymentExecution( + address, requests.prepareSuspendedPaymentExecutionSimple).then( + _.partial(checkResult, responses.prepareSuspendedPaymentExecutionSimple, + 'prepare')); + }); + it('prepareSuspendedPaymentCancellation', function() { return this.api.prepareSuspendedPaymentCancellation( address, requests.prepareSuspendedPaymentCancellation, instructions).then( @@ -181,6 +492,13 @@ describe('RippleAPI', function() { 'prepare')); }); + it('prepareSuspendedPaymentCancellation with memos', function() { + return this.api.prepareSuspendedPaymentCancellation( + address, requests.prepareSuspendedPaymentCancellationMemos).then( + _.partial(checkResult, responses.prepareSuspendedPaymentCancellationMemos, + 'prepare')); + }); + it('sign', function() { const secret = 'shsWGZcmZz6YsWWmcnpfr6fLTdtFV'; const result = this.api.sign(requests.sign.txJSON, secret); @@ -218,7 +536,8 @@ describe('RippleAPI', function() { it('getBalances - limit', function() { const options = { - limit: 3 + limit: 3, + ledgerVersion: 123456 }; const expectedResponse = responses.getBalances.slice(0, 3); return this.api.getBalances(address, options).then( @@ -255,6 +574,18 @@ describe('RippleAPI', function() { _.partial(checkResult, responses.getBalanceSheet, 'getBalanceSheet')); }); + it('getBalanceSheet - invalid options', function() { + assert.throws(() => { + this.api.getBalanceSheet(address, {invalid: 'options'}); + }, this.api.errors.ValidationError); + }); + + it('getBalanceSheet - empty', function() { + const options = {ledgerVersion: 123456}; + return this.api.getBalanceSheet(address, options).then( + _.partial(checkResult, {}, 'getBalanceSheet')); + }); + describe('getTransaction', () => { it('getTransaction - payment', function() { return this.api.getTransaction(hashes.VALID_TRANSACTION_HASH).then( @@ -279,6 +610,15 @@ describe('RippleAPI', function() { 'getTransaction')); }); + it('getTransaction - sell order', function() { + const hash = + '458101D51051230B1D56E9ACAFAA34451BF65FA000F95DF6F0FF5B3A62D83FC2'; + closeLedger(this.api.connection); + return this.api.getTransaction(hash).then( + _.partial(checkResult, responses.getTransaction.orderSell, + 'getTransaction')); + }); + it('getTransaction - order cancellation', function() { const hash = '809335DD3B0B333865096217AA2F55A4DF168E0198080B3A090D12D88880FF0E'; @@ -456,6 +796,15 @@ describe('RippleAPI', function() { 'getTransaction')); }); + it('getTransaction - SuspendedPaymentCreation iou', function() { + const hash = + '144F272380BDB4F1BD92329A2178BABB70C20F59042C495E10BF72EBFB408EE2'; + return this.api.getTransaction(hash).then( + _.partial(checkResult, + responses.getTransaction.SuspendedPaymentCreationIOU, + 'getTransaction')); + }); + it('getTransaction - SuspendedPaymentCancellation', function() { const hash = 'F346E542FFB7A8398C30A87B952668DAB48B7D421094F8B71776DA19775A3B22'; @@ -466,14 +815,46 @@ describe('RippleAPI', function() { }); it('getTransaction - SuspendedPaymentExecution', function() { + const options = { + minLedgerVersion: 10, + maxLedgerVersion: 15 + }; const hash = 'CC5277137B3F25EE8B86259C83CB0EAADE818505E4E9BCBF19B1AC6FD136993B'; - return this.api.getTransaction(hash).then( + return this.api.getTransaction(hash, options).then( _.partial(checkResult, responses.getTransaction.suspendedPaymentExecution, 'getTransaction')); }); + it('getTransaction - SuspendedPaymentExecution simple', function() { + const hash = + 'CC5277137B3F25EE8B86259C83CB0EAADE818505E4E9BCBF19B1AC6FD1369931'; + return this.api.getTransaction(hash).then( + _.partial(checkResult, + responses.getTransaction.suspendedPaymentExecutionSimple, + 'getTransaction')); + }); + + it('getTransaction - no Meta', function() { + const hash = + 'AFB3ADF22F3C605E23FAEFAA185F3BD763C4692CAC490D9819D117CD33BFAA1B'; + return this.api.getTransaction(hash).then(result => { + assert.deepEqual(result, responses.getTransaction.noMeta); + }); + }); + + it('getTransaction - Unrecognized transaction type', function() { + const hash = + 'AFB3ADF22F3C605E23FAEFAA185F3BD763C4692CAC490D9819D117CD33BFAA11'; + closeLedger(this.api.connection); + return this.api.getTransaction(hash).then(() => { + assert(false, 'Unrecognized transaction type'); + }).catch(error => { + assert.strictEqual(error.message, 'Unrecognized transaction type'); + }); + }); + }); it('getTransactions', function() { @@ -493,6 +874,7 @@ describe('RippleAPI', function() { _.partial(checkResult, expected, 'getTransactions')); }); + it('getTransactions - earliest first with start option', function() { const options = {types: ['payment', 'order'], initiated: true, limit: 2, start: hashes.VALID_TRANSACTION_HASH, @@ -572,12 +954,32 @@ describe('RippleAPI', function() { _.partial(checkResult, responses.getTransactions, 'getTransactions')); }); + it('getTransactions - start transaction with zero ledger version', function( + ) { + const options = { + start: '4FB3ADF22F3C605E23FAEFAA185F3BD763C4692CAC490D9819D117CD33BFAA13', + limit: 1 + }; + return this.api.getTransactions(address, options).then( + _.partial(checkResult, [], 'getTransactions')); + }); + + it('getTransactions - no options', function() { + return this.api.getTransactions(addresses.OTHER_ACCOUNT).then( + _.partial(checkResult, responses.getTransactionsOne, 'getTransactions')); + }); + it('getTrustlines', function() { const options = {currency: 'USD'}; return this.api.getTrustlines(address, options).then( _.partial(checkResult, responses.getTrustlines, 'getTrustlines')); }); + it('getTrustlines - ono options', function() { + return this.api.getTrustlines(address).then( + _.partial(checkResult, responses.getTrustlinesAll, 'getTrustlines')); + }); + it('generateAddress', function() { function random() { return _.fill(Array(16), 0); @@ -586,24 +988,79 @@ describe('RippleAPI', function() { responses.generateAddress); }); + it('generateAddress invalid', function() { + assert.throws(() => { + function random() { + return _.fill(Array(1), 0); + } + this.api.generateAddress({entropy: random()}); + }, this.api.errors.UnexpectedError); + }); + it('getSettings', function() { return this.api.getSettings(address).then( _.partial(checkResult, responses.getSettings, 'getSettings')); }); + it('getSettings - options undefined', function() { + return this.api.getSettings(address, undefined).then( + _.partial(checkResult, responses.getSettings, 'getSettings')); + }); + + it('getSettings - invalid options', function() { + assert.throws(() => { + this.api.getSettings(address, {invalid: 'options'}); + }, this.api.errors.ValidationError); + }); + it('getAccountInfo', function() { return this.api.getAccountInfo(address).then( _.partial(checkResult, responses.getAccountInfo, 'getAccountInfo')); }); + it('getAccountInfo - options undefined', function() { + return this.api.getAccountInfo(address, undefined).then( + _.partial(checkResult, responses.getAccountInfo, 'getAccountInfo')); + }); + + it('getAccountInfo - invalid options', function() { + assert.throws(() => { + this.api.getAccountInfo(address, {invalid: 'options'}); + }, this.api.errors.ValidationError); + }); + it('getOrders', function() { return this.api.getOrders(address).then( _.partial(checkResult, responses.getOrders, 'getOrders')); }); + it('getOrders', function() { + return this.api.getOrders(address, undefined).then( + _.partial(checkResult, responses.getOrders, 'getOrders')); + }); + + it('getOrders - invalid options', function() { + assert.throws(() => { + this.api.getOrders(address, {invalid: 'options'}); + }, this.api.errors.ValidationError); + }); + it('getOrderbook', function() { - return this.api.getOrderbook(address, requests.getOrderbook).then( - _.partial(checkResult, responses.getOrderbook, 'getOrderbook')); + return this.api.getOrderbook(address, requests.getOrderbook, undefined) + .then( + _.partial(checkResult, responses.getOrderbook, 'getOrderbook')); + }); + + it('getOrderbook - invalid options', function() { + assert.throws(() => { + this.api.getOrderbook(address, requests.getOrderbook, + {invalid: 'options'}); + }, this.api.errors.ValidationError); + }); + + it('getOrderbook with XRP', function() { + return this.api.getOrderbook(address, requests.getOrderbookWithXRP).then( + _.partial(checkResult, responses.getOrderbookWithXRP, 'getOrderbook')); }); it('getOrderbook - sorted so that best deals come first', function() { @@ -664,6 +1121,13 @@ describe('RippleAPI', function() { }); }); + it('getFee default', function() { + this.api._feeCushion = undefined; + return this.api.getFee().then(fee => { + assert.strictEqual(fee, '0.000012'); + }); + }); + it('disconnect & isConnected', function() { assert.strictEqual(this.api.isConnected(), true); return this.api.disconnect().then(() => { @@ -702,6 +1166,14 @@ describe('RippleAPI', function() { _.partial(checkResult, responses.getPaths.XrpToXrp, 'getPaths')); }); + it('getPaths - source with issuer', function() { + return this.api.getPaths(requests.getPaths.issuer).then(() => { + assert(false, 'Should throw NotFoundError'); + }).catch(error => { + assert(error instanceof this.api.errors.NotFoundError); + }); + }); + it('getPaths - XRP 2 XRP - not enough', function() { return this.api.getPaths(requests.getPaths.XrpToXrpNotEnough).then(() => { assert(false, 'Should throw NotFoundError'); @@ -710,6 +1182,12 @@ describe('RippleAPI', function() { }); }); + it('getPaths - invalid PathFind', function() { + assert.throws(() => { + this.api.getPaths(requests.getPaths.invalid); + }, /Cannot specify both source.amount/); + }); + it('getPaths - does not accept currency', function() { return this.api.getPaths(requests.getPaths.NotAcceptCurrency).then(() => { assert(false, 'Should throw NotFoundError'); @@ -768,6 +1246,18 @@ describe('RippleAPI', function() { }); }); + it('getLedger - with state as hashes', function() { + const request = { + includeTransactions: true, + includeAllData: false, + includeState: true, + ledgerVersion: 6 + }; + return this.api.getLedger(request).then( + _.partial(checkResult, responses.getLedger.withStateAsHashes, + 'getLedger')); + }); + it('getLedger - with settings transaction', function() { const request = { includeTransactions: true, @@ -796,7 +1286,55 @@ describe('RippleAPI', function() { }); }); + it('computeLedgerHash - wrong hash', function() { + const request = { + includeTransactions: true, + includeState: true, + includeAllData: true, + ledgerVersion: 38129 + }; + return this.api.getLedger(request).then( + _.partial(checkResult, responses.getLedger.full, 'getLedger')) + .then(response => { + const ledger = _.assign({}, response, { + parentCloseTime: response.closeTime, stateHash: + 'D9ABF622DA26EEEE48203085D4BC23B0F77DC6F8724AC33D975DA3CA492D2E44'}); + assert.throws(() => { + const hash = this.api.computeLedgerHash(ledger); + unused(hash); + }, /does not match computed hash of state/); + }); + }); + + it('RippleError with data', function() { + const error = new this.api.errors.RippleError('_message_', '_data_'); + assert.strictEqual(error.toString(), + '[RippleError(_message_, \'_data_\')]'); + }); + + it('NotFoundError default message', function() { + const error = new this.api.errors.NotFoundError(); + assert.strictEqual(error.toString(), + '[NotFoundError(Not found)]'); + }); + + it('common utils - toRippledAmount', function() { + const amount = {issuer: 'is', currency: 'c', value: 'v'}; + + assert.deepEqual(utils.common.toRippledAmount(amount), { + issuer: 'is', currency: 'c', value: 'v' + }); + }); + + it('ledger utils - renameCounterpartyToIssuerInOrder', function() { + const order = {taker_gets: {issuer: '1'}}; + const expected = {taker_gets: {issuer: '1'}}; + + assert.deepEqual(utils.renameCounterpartyToIssuerInOrder(order), expected); + }); + it('ledger utils - compareTransactions', function() { + assert.strictEqual(utils.compareTransactions({}, {}), 0); let first = {outcome: {ledgerVersion: 1, indexInLedger: 100}}; let second = {outcome: {ledgerVersion: 1, indexInLedger: 200}}; diff --git a/test/fixtures/requests/get-orderbook-with-xrp.json b/test/fixtures/requests/get-orderbook-with-xrp.json new file mode 100644 index 00000000..d8016465 --- /dev/null +++ b/test/fixtures/requests/get-orderbook-with-xrp.json @@ -0,0 +1,9 @@ +{ + "base": { + "currency": "USD", + "counterparty": "rp8rJYTpodf8qbSCHVTNacf8nSW8mRakFw" + }, + "counter": { + "currency": "XRP" + } +} \ No newline at end of file diff --git a/test/fixtures/requests/getpaths/invalid.json b/test/fixtures/requests/getpaths/invalid.json new file mode 100644 index 00000000..f3f944b3 --- /dev/null +++ b/test/fixtures/requests/getpaths/invalid.json @@ -0,0 +1,16 @@ +{ + "source": { + "address": "rwBYyfufTzk77zUSKEu4MvixfarC35av1J", + "amount": { + "value": "1000002", + "currency": "USD" + } + }, + "destination": { + "address": "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59", + "amount": { + "value": "1000002", + "currency": "USD" + } + } +} diff --git a/test/fixtures/requests/getpaths/issuer.json b/test/fixtures/requests/getpaths/issuer.json new file mode 100644 index 00000000..e2776ea8 --- /dev/null +++ b/test/fixtures/requests/getpaths/issuer.json @@ -0,0 +1,16 @@ +{ + "source": { + "address": "rwBYyfufTzk77zUSKEu4MvixfarC35av1J", + "amount": { + "value": "1000002", + "currency": "USD", + "counterparty": "rwBYyfufTzk77zUSKEu4MvixfarC35av1J" + } + }, + "destination": { + "address": "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59", + "amount": { + "currency": "USD" + } + } +} diff --git a/test/fixtures/requests/index.js b/test/fixtures/requests/index.js index 93bc222f..aaddbf9e 100644 --- a/test/fixtures/requests/index.js +++ b/test/fixtures/requests/index.js @@ -8,18 +8,30 @@ module.exports = { }, prepareOrderCancellation: require('./prepare-order-cancellation'), preparePayment: require('./prepare-payment'), + preparePaymentMinAmountXRP: require('./prepare-payment-min-xrp'), + preparePaymentMinAmount: require('./prepare-payment-min'), + preparePaymentWrongAddress: require('./prepare-payment-wrong-address'), + preparePaymentWrongAmount: require('./prepare-payment-wrong-amount'), + preparePaymentWrongPartial: require('./prepare-payment-wrong-partial'), preparePaymentAllOptions: require('./prepare-payment-all-options'), preparePaymentNoCounterparty: require('./prepare-payment-no-counterparty'), prepareSettings: require('./prepare-settings'), prepareSuspendedPaymentCreation: require('./prepare-suspended-payment-creation'), + prepareSuspendedPaymentCreationFull: + require('./prepare-suspended-payment-creation-full'), prepareSuspendedPaymentExecution: require('./prepare-suspended-payment-execution'), + prepareSuspendedPaymentExecutionSimple: + require('./prepare-suspended-payment-execution-simple'), prepareSuspendedPaymentCancellation: require('./prepare-suspended-payment-cancellation'), + prepareSuspendedPaymentCancellationMemos: + require('./prepare-suspended-payment-cancellation-memos'), prepareTrustline: { simple: require('./prepare-trustline-simple'), - complex: require('./prepare-trustline') + complex: require('./prepare-trustline'), + frozen: require('./prepare-trustline-frozen.json') }, sign: require('./sign'), signSuspended: require('./sign-suspended.json'), @@ -31,9 +43,12 @@ module.exports = { NotAcceptCurrency: require('./getpaths/not-accept-currency'), NoPaths: require('./getpaths/no-paths'), NoPathsWithCurrencies: require('./getpaths/no-paths-with-currencies'), - sendAll: require('./getpaths/send-all') + sendAll: require('./getpaths/send-all'), + invalid: require('./getpaths/invalid'), + issuer: require('./getpaths/issuer') }, getOrderbook: require('./get-orderbook'), + getOrderbookWithXRP: require('./get-orderbook-with-xrp'), computeLedgerHash: { header: require('./compute-ledger-hash'), transactions: require('./compute-ledger-hash-transactions') diff --git a/test/fixtures/requests/prepare-order.json b/test/fixtures/requests/prepare-order.json index 40f49eb2..510f68a6 100644 --- a/test/fixtures/requests/prepare-order.json +++ b/test/fixtures/requests/prepare-order.json @@ -9,5 +9,6 @@ "currency": "XRP", "value": "2" }, - "immediateOrCancel": true + "passive": true, + "fillOrKill": true } diff --git a/test/fixtures/requests/prepare-payment-min-xrp.json b/test/fixtures/requests/prepare-payment-min-xrp.json new file mode 100644 index 00000000..944da581 --- /dev/null +++ b/test/fixtures/requests/prepare-payment-min-xrp.json @@ -0,0 +1,17 @@ +{ + "source": { + "address": "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59", + "amount": { + "value": "0.01", + "currency": "USD", + "counterparty": "rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM" + } + }, + "destination": { + "address": "rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo", + "minAmount": { + "value": "0.01", + "currency": "XRP" + } + } +} diff --git a/test/fixtures/requests/prepare-payment-min.json b/test/fixtures/requests/prepare-payment-min.json new file mode 100644 index 00000000..b2cf735e --- /dev/null +++ b/test/fixtures/requests/prepare-payment-min.json @@ -0,0 +1,17 @@ +{ + "source": { + "address": "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59", + "amount": { + "value": "0.01", + "currency": "XRP", + "counterparty": "rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM" + } + }, + "destination": { + "address": "rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo", + "minAmount": { + "value": "0.01", + "currency": "XRP" + } + } +} diff --git a/test/fixtures/requests/prepare-payment-wrong-address.json b/test/fixtures/requests/prepare-payment-wrong-address.json new file mode 100644 index 00000000..0533a0b9 --- /dev/null +++ b/test/fixtures/requests/prepare-payment-wrong-address.json @@ -0,0 +1,17 @@ +{ + "source": { + "address": "rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM", + "amount": { + "value": "0.01", + "currency": "USD", + "counterparty": "rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM" + } + }, + "destination": { + "address": "rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo", + "minAmount": { + "value": "0.01", + "currency": "XRP" + } + } +} diff --git a/test/fixtures/requests/prepare-payment-wrong-amount.json b/test/fixtures/requests/prepare-payment-wrong-amount.json new file mode 100644 index 00000000..eda7eb8a --- /dev/null +++ b/test/fixtures/requests/prepare-payment-wrong-amount.json @@ -0,0 +1,17 @@ +{ + "source": { + "address": "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59", + "maxAmount": { + "value": "0.01", + "currency": "USD", + "counterparty": "rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM" + } + }, + "destination": { + "address": "rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo", + "minAmount": { + "value": "0.01", + "currency": "XRP" + } + } +} diff --git a/test/fixtures/requests/prepare-payment-wrong-partial.json b/test/fixtures/requests/prepare-payment-wrong-partial.json new file mode 100644 index 00000000..d94e7b62 --- /dev/null +++ b/test/fixtures/requests/prepare-payment-wrong-partial.json @@ -0,0 +1,17 @@ +{ + "source": { + "address": "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59", + "amount": { + "value": "0.01", + "currency": "XRP" + } + }, + "destination": { + "address": "rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo", + "minAmount": { + "value": "0.01", + "currency": "XRP" + } + }, + "allowPartialPayment": true +} diff --git a/test/fixtures/requests/prepare-suspended-payment-cancellation-memos.json b/test/fixtures/requests/prepare-suspended-payment-cancellation-memos.json new file mode 100644 index 00000000..15b3e9fa --- /dev/null +++ b/test/fixtures/requests/prepare-suspended-payment-cancellation-memos.json @@ -0,0 +1,11 @@ +{ + "owner": "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59", + "suspensionSequence": 1234, + "memos": [ + { + "type": "test", + "format": "plain/text", + "data": "texted data" + } + ] +} diff --git a/test/fixtures/requests/prepare-suspended-payment-creation-full.json b/test/fixtures/requests/prepare-suspended-payment-creation-full.json new file mode 100644 index 00000000..bfaa71e2 --- /dev/null +++ b/test/fixtures/requests/prepare-suspended-payment-creation-full.json @@ -0,0 +1,28 @@ +{ + "source": { + "address": "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59", + "maxAmount": { + "value": "0.01", + "currency": "USD", + "counterparty": "rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM" + }, + "tag": 1 + }, + "destination": { + "address": "rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo", + "amount": { + "value": "0.01", + "currency": "USD", + "counterparty": "rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM" + }, + "tag": 2 + }, + "digest": "8F434346648F6B96DF89DDA901C5176B10A6D83961DD3C1AC88B59B2DC327AA4", + "allowExecuteAfter": "2014-09-24T21:21:50.000Z", + "memos": [ + { + "type": "test", + "data": "texted data" + } + ] +} diff --git a/test/fixtures/requests/prepare-suspended-payment-execution-simple.json b/test/fixtures/requests/prepare-suspended-payment-execution-simple.json new file mode 100644 index 00000000..15b3e9fa --- /dev/null +++ b/test/fixtures/requests/prepare-suspended-payment-execution-simple.json @@ -0,0 +1,11 @@ +{ + "owner": "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59", + "suspensionSequence": 1234, + "memos": [ + { + "type": "test", + "format": "plain/text", + "data": "texted data" + } + ] +} diff --git a/test/fixtures/requests/prepare-trustline-frozen.json b/test/fixtures/requests/prepare-trustline-frozen.json new file mode 100644 index 00000000..d4138f4d --- /dev/null +++ b/test/fixtures/requests/prepare-trustline-frozen.json @@ -0,0 +1,8 @@ +{ + "currency": "BTC", + "counterparty": "rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM", + "limit": "0.1", + "authorized": true, + "ripplingDisabled": false, + "frozen": true +} diff --git a/test/fixtures/requests/sign.json b/test/fixtures/requests/sign.json index df9ea7c0..664f31c5 100644 --- a/test/fixtures/requests/sign.json +++ b/test/fixtures/requests/sign.json @@ -1,5 +1,5 @@ { - "txJSON": "{\"Flags\":2147483648,\"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,\"SigningPubKey\":\"02F89EAEC7667B30F33D0687BBA86C3FE2A08CCA40A9186C5BDE2DAA6FA97A37D8\"}", "instructions": { "fee": "0.000012", "sequence": 23, diff --git a/test/fixtures/responses/get-ledger-with-settings-tx.json b/test/fixtures/responses/get-ledger-with-settings-tx.json index 5a6137ed..b8a84371 100644 --- a/test/fixtures/responses/get-ledger-with-settings-tx.json +++ b/test/fixtures/responses/get-ledger-with-settings-tx.json @@ -33,5 +33,5 @@ } } ], - "rawTransactions": "[{\"Account\":\"rEGy9CxMTFGXFgUHUMreTy2FbqArabGy38\",\"Fee\":\"10\",\"Flags\":0,\"Sequence\":6478,\"SigningPubKey\":\"02CAB6F3A798712136DB5F105A98B0DE27C99AEDB68500181706B087CF1B6D0F2D\",\"TransactionType\":\"AccountSet\",\"TxnSignature\":\"304402202144BD33CC30793455B0F90954576EEE80F13C4C73538D2AEE012564C48E522E02207A8A4AD2CF2B4DB549FB2F05D38E065B5DD1EAA386310698E5247F1BB515E99F\",\"hash\":\"FEEFC959B0351156F58A2275F5A6B37B07AA85CCCE2C4AF8A1342A0196A3CD4D\",\"metaData\":{\"AffectedNodes\":[{\"ModifiedNode\":{\"FinalFields\":{\"Account\":\"rEGy9CxMTFGXFgUHUMreTy2FbqArabGy38\",\"Balance\":\"403657865\",\"Flags\":0,\"OwnerCount\":2,\"Sequence\":6479},\"LedgerEntryType\":\"AccountRoot\",\"LedgerIndex\":\"F64FAA4CAFDB9931DC06890FE30B4E29C32F7AD574FC7C3362B81265682BFAEA\",\"PreviousFields\":{\"Balance\":\"403657875\",\"Sequence\":6478},\"PreviousTxnID\":\"B257B95A637C6C396507AD0AE122161A849C701F065B67009BB939690DB74BC9\",\"PreviousTxnLgrSeq\":4181972}}],\"TransactionIndex\":0,\"TransactionResult\":\"tesSUCCESS\"}}]" + "rawTransactions": "[{\"Account\":\"rEGy9CxMTFGXFgUHUMreTy2FbqArabGy38\",\"Fee\":\"10\",\"ledger_index\":4181996,\"Flags\":0,\"Sequence\":6478,\"SigningPubKey\":\"02CAB6F3A798712136DB5F105A98B0DE27C99AEDB68500181706B087CF1B6D0F2D\",\"TransactionType\":\"AccountSet\",\"TxnSignature\":\"304402202144BD33CC30793455B0F90954576EEE80F13C4C73538D2AEE012564C48E522E02207A8A4AD2CF2B4DB549FB2F05D38E065B5DD1EAA386310698E5247F1BB515E99F\",\"hash\":\"FEEFC959B0351156F58A2275F5A6B37B07AA85CCCE2C4AF8A1342A0196A3CD4D\",\"metaData\":{\"AffectedNodes\":[{\"ModifiedNode\":{\"FinalFields\":{\"Account\":\"rEGy9CxMTFGXFgUHUMreTy2FbqArabGy38\",\"Balance\":\"403657865\",\"Flags\":0,\"OwnerCount\":2,\"Sequence\":6479},\"LedgerEntryType\":\"AccountRoot\",\"LedgerIndex\":\"F64FAA4CAFDB9931DC06890FE30B4E29C32F7AD574FC7C3362B81265682BFAEA\",\"PreviousFields\":{\"Balance\":\"403657875\",\"Sequence\":6478},\"PreviousTxnID\":\"B257B95A637C6C396507AD0AE122161A849C701F065B67009BB939690DB74BC9\",\"PreviousTxnLgrSeq\":4181972}}],\"TransactionIndex\":0,\"TransactionResult\":\"tesSUCCESS\"}}]" } diff --git a/test/fixtures/responses/get-ledger-with-state-as-hashes.json b/test/fixtures/responses/get-ledger-with-state-as-hashes.json new file mode 100644 index 00000000..a9f7fd58 --- /dev/null +++ b/test/fixtures/responses/get-ledger-with-state-as-hashes.json @@ -0,0 +1,20 @@ +{ + "stateHash": "8DBB7FA4036704D96AD32A4573BEE461FDDBDCB1B6F62CB17EDB5182F52AE9F1", + "closeTime": "2015-11-18T11:00:30.000Z", + "closeTimeResolution": 30, + "closeFlags": 0, + "ledgerHash": "3D7115EDB5EC72FEF4ADDF46CA5B7770CBDECEAB3A97EA210BCC04E8C54A7CEE", + "ledgerVersion": 6, + "parentLedgerHash": "6D36AEFD3639EE22A27DDE0FA6C57525D103941F11D7FD6D91AC8D439DE2B3EE", + "parentCloseTime": "2015-11-18T07:53:01.000Z", + "totalDrops": "99999999999999964", + "transactionHash": "B8D716B82BFFF4186BBBE7B7341AE0E1CBD2558952408B96E925EC0A51A6AEC2", + "transactionHashes": [ + "B22E27F35F3F7679F76A474E4FF8E71EFA21B313DF2FC6678037A053A00FD084" + ], + "stateHashes": [ + "2B6AC232AA4C4BE41BF49D2459FA4A0347E1B543A4C92FCEE0821C0201E2E9A8", + "8B24E55376A65D68542C17F3BF446231AC7062CB43BED28817570128A1849819", + "B4979A36CDC7F3D3D5C31A4EAE2AC7D7209DDA877588B9AFC66799692AB0D66B" + ] +} diff --git a/test/fixtures/responses/get-orderbook-with-xrp.json b/test/fixtures/responses/get-orderbook-with-xrp.json new file mode 100644 index 00000000..49799d17 --- /dev/null +++ b/test/fixtures/responses/get-orderbook-with-xrp.json @@ -0,0 +1,44 @@ +{ + "bids": [ + { + "specification": { + "direction": "buy", + "quantity": { + "currency": "USD", + "value": "10.1", + "counterparty": "rp8rJYTpodf8qbSCHVTNacf8nSW8mRakFw" + }, + "totalPrice": { + "currency": "XRP", + "value": "254391353" + } + }, + "properties": { + "maker": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + "sequence": 5, + "makerExchangeRate": "3.970260734451929e-8" + } + } + ], + "asks": [ + { + "specification": { + "direction": "sell", + "quantity": { + "currency": "USD", + "value": "10453252347.1", + "counterparty": "rp8rJYTpodf8qbSCHVTNacf8nSW8mRakFw" + }, + "totalPrice": { + "currency": "XRP", + "value": "134" + } + }, + "properties": { + "maker": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + "sequence": 6, + "makerExchangeRate": "0.0000780093458738806" + } + } + ] +} diff --git a/test/fixtures/responses/get-transaction-no-meta.json b/test/fixtures/responses/get-transaction-no-meta.json new file mode 100644 index 00000000..5be1a066 --- /dev/null +++ b/test/fixtures/responses/get-transaction-no-meta.json @@ -0,0 +1,23 @@ +{ + "type": "payment", + "address": "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59", + "sequence": 4, + "id": "AFB3ADF22F3C605E23FAEFAA185F3BD763C4692CAC490D9819D117CD33BFAA1B", + "specification": { + "source": { + "address": "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59", + "maxAmount": { + "currency": "XRP", + "value": "1.112209" + } + }, + "destination": { + "address": "rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM", + "amount": { + "currency": "USD", + "value": "0.001" + } + }, + "paths": "[[{\"currency\":\"USD\",\"issuer\":\"rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo\",\"type\":48,\"type_hex\":\"0000000000000030\"},{\"account\":\"rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo\",\"currency\":\"USD\",\"issuer\":\"rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo\",\"type\":49,\"type_hex\":\"0000000000000031\"}]]" + } +} diff --git a/test/fixtures/responses/get-transaction-order-sell.json b/test/fixtures/responses/get-transaction-order-sell.json new file mode 100644 index 00000000..d3bf0f53 --- /dev/null +++ b/test/fixtures/responses/get-transaction-order-sell.json @@ -0,0 +1,34 @@ +{ + "type": "order", + "address": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + "sequence": 2, + "id": "458101D51051230B1D56E9ACAFAA34451BF65FA000F95DF6F0FF5B3A62D83FC2", + "specification": { + "direction": "sell", + "quantity": { + "currency": "USD", + "value": "10.1", + "counterparty": "rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM" + }, + "totalPrice": { + "currency": "XRP", + "value": "254391353" + } + }, + "outcome": { + "result": "tecUNFUNDED_OFFER", + "timestamp": "2015-11-18T20:56:30.000Z", + "fee": "0.000012", + "balanceChanges": { + "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh": [ + { + "currency": "XRP", + "value": "-0.000012" + } + ] + }, + "orderbookChanges": {}, + "ledgerVersion": 6, + "indexInLedger": 0 + } +} diff --git a/test/fixtures/responses/get-transaction-suspended-payment-create-iou.json b/test/fixtures/responses/get-transaction-suspended-payment-create-iou.json new file mode 100644 index 00000000..3d4cb913 --- /dev/null +++ b/test/fixtures/responses/get-transaction-suspended-payment-create-iou.json @@ -0,0 +1,51 @@ +{ + "type": "suspendedPaymentCreation", + "address": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + "sequence": 10, + "id": "144F272380BDB4F1BD92329A2178BABB70C20F59042C495E10BF72EBFB408EE2", + "specification": { + "source": { + "address": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + "maxAmount": { + "currency": "USD", + "value": "2" + }, + "tag": 1 + }, + "destination": { + "address": "rp8rJYTpodf8qbSCHVTNacf8nSW8mRakFw", + "amount": { + "currency": "USD", + "value": "2", + "counterparty": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" + }, + "tag": 2 + }, + "memos": [ + { + "type": "x2", + "format": "text/plain", + "data": "mema data" + } + ], + "digest": "8F434346648F6B96DF89DDA901C5176B10A6D83961DD3C1AC88B59B2DC327AA4", + "allowCancelAfter": "2015-11-16T06:53:42.000Z", + "allowExecuteAfter": "2015-11-16T06:47:42.000Z" + }, + "outcome": { + "result": "tesSUCCESS", + "timestamp": "2015-11-16T06:43:00.000Z", + "fee": "0.000012", + "balanceChanges": { + "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh": [ + { + "currency": "XRP", + "value": "-0.000014" + } + ] + }, + "orderbookChanges": {}, + "ledgerVersion": 15, + "indexInLedger": 0 + } +} diff --git a/test/fixtures/responses/get-transaction-suspended-payment-execution-simple.json b/test/fixtures/responses/get-transaction-suspended-payment-execution-simple.json new file mode 100644 index 00000000..437499cd --- /dev/null +++ b/test/fixtures/responses/get-transaction-suspended-payment-execution-simple.json @@ -0,0 +1,34 @@ +{ + "type": "suspendedPaymentExecution", + "address": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + "sequence": 6, + "id": "CC5277137B3F25EE8B86259C83CB0EAADE818505E4E9BCBF19B1AC6FD1369931", + "specification": { + "owner": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + "suspensionSequence": 5, + "method": 1, + "digest": "632F2F3E437AE720C397994A985B5D21FE186DE61523A9CA3E8709CC581671A1" + }, + "outcome": { + "result": "tesSUCCESS", + "timestamp": "2015-11-17T01:47:40.000Z", + "fee": "0.000012", + "balanceChanges": { + "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh": [ + { + "currency": "XRP", + "value": "-0.000012" + } + ], + "rp8rJYTpodf8qbSCHVTNacf8nSW8mRakFw": [ + { + "currency": "XRP", + "value": "10.000043" + } + ] + }, + "orderbookChanges": {}, + "ledgerVersion": 14, + "indexInLedger": 0 + } +} diff --git a/test/fixtures/responses/get-transactions-one.json b/test/fixtures/responses/get-transactions-one.json new file mode 100644 index 00000000..72b5dcd1 --- /dev/null +++ b/test/fixtures/responses/get-transactions-one.json @@ -0,0 +1,27 @@ +[ + { + "type": "settings", + "address": "r9UHu5CWni1qRY7Q4CfFZLGvXo2pGQy96b", + "sequence": 491, + "id": "D868CFF0DF8C8AAF205404460EA764ACB3B8862527FA414BC8C1CA9A45B1F276", + "specification": { + "domain": "ripple.com" + }, + "outcome": { + "result": "tesSUCCESS", + "timestamp": "2015-10-23T02:07:00.000Z", + "fee": "0.012", + "balanceChanges": { + "r9UHu5CWni1qRY7Q4CfFZLGvXo2pGQy96b": [ + { + "currency": "XRP", + "value": "-0.012" + } + ] + }, + "orderbookChanges": {}, + "ledgerVersion": 16635149, + "indexInLedger": 4 + } + } +] diff --git a/test/fixtures/responses/get-trustlines-all.json b/test/fixtures/responses/get-trustlines-all.json new file mode 100644 index 00000000..407898e5 --- /dev/null +++ b/test/fixtures/responses/get-trustlines-all.json @@ -0,0 +1,333 @@ +[ + { + "specification": { + "limit": "0", + "currency": "ASP", + "counterparty": "r3vi7mWxru9rJCxETCyA1CHvzL96eZWx5z" + }, + "counterparty": { + "limit": "10" + }, + "state": { + "balance": "0" + } + }, + { + "specification": { + "limit": "0", + "currency": "XAU", + "counterparty": "r3vi7mWxru9rJCxETCyA1CHvzL96eZWx5z", + "ripplingDisabled": true, + "frozen": true + }, + "counterparty": { + "limit": "0", + "ripplingDisabled": true + }, + "state": { + "balance": "0" + } + }, + { + "specification": { + "limit": "5", + "currency": "USD", + "counterparty": "rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q", + "ripplingDisabled": true, + "frozen": true + }, + "counterparty": { + "limit": "0" + }, + "state": { + "balance": "2.497605752725159" + } + }, + { + "specification": { + "limit": "1000", + "currency": "MXN", + "counterparty": "rHpXfibHgSb64n8kK9QWDpdbfqSpYbM9a4" + }, + "counterparty": { + "limit": "0" + }, + "state": { + "balance": "481.992867407479" + } + }, + { + "specification": { + "limit": "1", + "currency": "EUR", + "counterparty": "rLEsXccBGNR3UPuPu2hUXPjziKC3qKSBun", + "ripplingDisabled": true + }, + "counterparty": { + "limit": "0" + }, + "state": { + "balance": "0.793598266778297" + } + }, + { + "specification": { + "limit": "3", + "currency": "CNY", + "counterparty": "rnuF96W4SZoCJmbHYBFoJZpR8eCaxNvekK", + "ripplingDisabled": true + }, + "counterparty": { + "limit": "0" + }, + "state": { + "balance": "0" + } + }, + { + "specification": { + "limit": "3", + "currency": "DYM", + "counterparty": "rGwUWgN5BEg3QGNY3RX2HfYowjUTZdid3E" + }, + "counterparty": { + "limit": "0" + }, + "state": { + "balance": "1.294889190631542" + } + }, + { + "specification": { + "limit": "0", + "currency": "CHF", + "counterparty": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B" + }, + "counterparty": { + "limit": "0" + }, + "state": { + "balance": "0.3488146605801446" + } + }, + { + "specification": { + "limit": "3", + "currency": "BTC", + "counterparty": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B" + }, + "counterparty": { + "limit": "0" + }, + "state": { + "balance": "2.114103174931847" + } + }, + { + "specification": { + "limit": "5000", + "currency": "USD", + "counterparty": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B" + }, + "counterparty": { + "limit": "0" + }, + "state": { + "balance": "0" + } + }, + { + "specification": { + "limit": "0", + "currency": "BTC", + "counterparty": "rpgKWEmNqSDAGFhy5WDnsyPqfQxbWxKeVd" + }, + "counterparty": { + "limit": "10" + }, + "state": { + "balance": "-0.00111" + } + }, + { + "specification": { + "limit": "0", + "currency": "BTC", + "counterparty": "rBJ3YjwXi2MGbg7GVLuTXUWQ8DjL7tDXh4" + }, + "counterparty": { + "limit": "10" + }, + "state": { + "balance": "-0.1010780000080207" + } + }, + { + "specification": { + "limit": "1", + "currency": "USD", + "counterparty": "rLEsXccBGNR3UPuPu2hUXPjziKC3qKSBun" + }, + "counterparty": { + "limit": "0" + }, + "state": { + "balance": "1" + } + }, + { + "specification": { + "limit": "100", + "currency": "CNY", + "counterparty": "razqQKzJRdB4UxFPWf5NEpEG3WMkmwgcXA", + "ripplingDisabled": true + }, + "counterparty": { + "limit": "0" + }, + "state": { + "balance": "8.07619790068559" + } + }, + { + "specification": { + "limit": "0", + "currency": "JPY", + "counterparty": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B", + "ripplingDisabled": true + }, + "counterparty": { + "limit": "0" + }, + "state": { + "balance": "7.292695098901099" + } + }, + { + "specification": { + "limit": "0", + "currency": "AUX", + "counterparty": "r3vi7mWxru9rJCxETCyA1CHvzL96eZWx5z", + "ripplingDisabled": true + }, + "counterparty": { + "limit": "0", + "ripplingDisabled": true + }, + "state": { + "balance": "0" + } + }, + { + "specification": { + "limit": "1", + "currency": "USD", + "counterparty": "r9vbV3EHvXWjSkeQ6CAcYVPGeq7TuiXY2X", + "ripplingDisabled": true + }, + "counterparty": { + "limit": "0" + }, + "state": { + "balance": "0" + } + }, + { + "specification": { + "limit": "100", + "currency": "EUR", + "counterparty": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B", + "ripplingDisabled": true + }, + "counterparty": { + "limit": "0" + }, + "state": { + "balance": "12.41688780720394" + } + }, + { + "specification": { + "limit": "500", + "currency": "USD", + "counterparty": "rfF3PNkwkq1DygW2wum2HK3RGfgkJjdPVD", + "ripplingDisabled": true + }, + "counterparty": { + "limit": "0" + }, + "state": { + "balance": "35" + } + }, + { + "specification": { + "limit": "0", + "currency": "JOE", + "counterparty": "rwUVoVMSURqNyvocPCcvLu3ygJzZyw8qwp" + }, + "counterparty": { + "limit": "50", + "ripplingDisabled": true + }, + "state": { + "balance": "-5" + } + }, + { + "specification": { + "limit": "0", + "currency": "USD", + "counterparty": "rE6R3DWF9fBD7CyiQciePF9SqK58Ubp8o2" + }, + "counterparty": { + "limit": "100", + "ripplingDisabled": true + }, + "state": { + "balance": "0" + } + }, + { + "specification": { + "limit": "0", + "currency": "JOE", + "counterparty": "rE6R3DWF9fBD7CyiQciePF9SqK58Ubp8o2" + }, + "counterparty": { + "limit": "100", + "ripplingDisabled": true + }, + "state": { + "balance": "0" + } + }, + { + "specification": { + "limit": "10.01037626125837", + "currency": "015841551A748AD2C1F76FF6ECB0CCCD00000000", + "counterparty": "rs9M85karFkCRjvc6KMWn8Coigm9cbcgcx", + "ripplingDisabled": true + }, + "counterparty": { + "limit": "0" + }, + "state": { + "balance": "0" + } + }, + { + "specification": { + "limit": "0", + "currency": "USD", + "counterparty": "rEhDDUUNxpXgEHVJtC2cjXAgyx5VCFxdMF", + "frozen": true + }, + "counterparty": { + "limit": "1" + }, + "state": { + "balance": "0" + } + } +] diff --git a/test/fixtures/responses/index.js b/test/fixtures/responses/index.js index 334536df..cdf16d53 100644 --- a/test/fixtures/responses/index.js +++ b/test/fixtures/responses/index.js @@ -6,6 +6,7 @@ module.exports = { getBalances: require('./get-balances.json'), getBalanceSheet: require('./get-balance-sheet.json'), getOrderbook: require('./get-orderbook.json'), + getOrderbookWithXRP: require('./get-orderbook-with-xrp.json'), getOrders: require('./get-orders.json'), getPaths: { XrpToUsd: require('./get-paths.json'), @@ -20,6 +21,8 @@ module.exports = { orderWithExpirationCancellation: require('./get-transaction-order-with-expiration-cancellation.json'), order: require('./get-transaction-order.json'), + orderSell: require('./get-transaction-order-sell.json'), + noMeta: require('./get-transaction-no-meta.json'), payment: require('./get-transaction-payment.json'), settings: require('./get-transaction-settings.json'), trustline: require('./get-transaction-trustline-set.json'), @@ -31,26 +34,37 @@ module.exports = { notValidated: require('./get-transaction-not-validated.json'), suspendedPaymentCreation: require('./get-transaction-suspended-payment-create.json'), + SuspendedPaymentCreationIOU: + require('./get-transaction-suspended-payment-create-iou.json'), suspendedPaymentCancellation: require('./get-transaction-suspended-payment-cancellation.json'), suspendedPaymentExecution: - require('./get-transaction-suspended-payment-execution.json') + require('./get-transaction-suspended-payment-execution.json'), + suspendedPaymentExecutionSimple: + require('./get-transaction-suspended-payment-execution-simple.json') }, getTransactions: require('./get-transactions.json'), + getTransactionsOne: require('./get-transactions-one.json'), getTrustlines: require('./get-trustlines.json'), + getTrustlinesAll: require('./get-trustlines-all.json'), getLedger: { header: require('./get-ledger'), full: require('./get-ledger-full'), - withSettingsTx: require('./get-ledger-with-settings-tx') + withSettingsTx: require('./get-ledger-with-settings-tx'), + withStateAsHashes: require('./get-ledger-with-state-as-hashes') }, - prepareOrderCancellation: require('./prepare-order-cancellation.json'), prepareOrder: { buy: require('./prepare-order.json'), sell: require('./prepare-order-sell.json'), - expiration: require('./prepare-order-expiration') + expiration: require('./prepare-order-expiration'), + cancellation: require('./prepare-order-cancellation.json'), + cancellationNoInstructions: + require('./prepare-order-cancellation-no-instructions.json') }, preparePayment: { normal: require('./prepare-payment.json'), + minAmountXRP: require('./prepare-payment-min-amont-xrp.json'), + minAmountXRPXRP: require('./prepare-payment-min-amont-xrp-xrp.json'), allOptions: require('./prepare-payment-all-options.json'), noCounterparty: require('./prepare-payment-no-counterparty.json'), minAmount: require('./prepare-payment-min-amount.json') @@ -62,16 +76,24 @@ module.exports = { flagSet: require('./prepare-settings-flag-set.json'), flagClear: require('./prepare-settings-flag-clear.json'), setTransferRate: require('./prepare-settings-set-transfer-rate.json'), - fieldClear: require('./prepare-settings-field-clear.json') + fieldClear: require('./prepare-settings-field-clear.json'), + noInstructions: require('./prepare-settings-no-instructions.json') }, prepareSuspendedPaymentCreation: require('./prepare-suspended-payment-creation'), + prepareSuspendedPaymentCreationFull: + require('./prepare-suspended-payment-creation-full'), prepareSuspendedPaymentExecution: require('./prepare-suspended-payment-execution'), + prepareSuspendedPaymentExecutionSimple: + require('./prepare-suspended-payment-execution-simple'), prepareSuspendedPaymentCancellation: require('./prepare-suspended-payment-cancellation'), + prepareSuspendedPaymentCancellationMemos: + require('./prepare-suspended-payment-cancellation-memos'), prepareTrustline: { simple: require('./prepare-trustline-simple.json'), + frozen: require('./prepare-trustline-frozen.json'), complex: require('./prepare-trustline.json') }, sign: require('./sign.json'), diff --git a/test/fixtures/responses/prepare-order-cancellation-no-instructions.json b/test/fixtures/responses/prepare-order-cancellation-no-instructions.json new file mode 100644 index 00000000..d729b220 --- /dev/null +++ b/test/fixtures/responses/prepare-order-cancellation-no-instructions.json @@ -0,0 +1,8 @@ +{ + "txJSON": "{\"Flags\":2147483648,\"TransactionType\":\"OfferCancel\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"OfferSequence\":23,\"LastLedgerSequence\":8819954,\"Fee\":\"12\",\"Sequence\":23}", + "instructions": { + "fee": "0.000012", + "sequence": 23, + "maxLedgerVersion": 8819954 + } +} diff --git a/test/fixtures/responses/prepare-order.json b/test/fixtures/responses/prepare-order.json index 72fa4b25..5bd790c1 100644 --- a/test/fixtures/responses/prepare-order.json +++ b/test/fixtures/responses/prepare-order.json @@ -1,8 +1,8 @@ { - "txJSON": "{\"Flags\":2147614720,\"TransactionType\":\"OfferCreate\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"TakerGets\":\"2000000\",\"TakerPays\":{\"value\":\"10.1\",\"currency\":\"USD\",\"issuer\":\"rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM\"},\"LastLedgerSequence\":8820051,\"Fee\":\"12\",\"Sequence\":23}", + "txJSON": "{\"Flags\":2147811328,\"TransactionType\":\"OfferCreate\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"TakerGets\":\"2000000\",\"TakerPays\":{\"value\":\"10.1\",\"currency\":\"USD\",\"issuer\":\"rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM\"},\"LastLedgerSequence\":8819954,\"Fee\":\"12\",\"Sequence\":23}", "instructions": { "fee": "0.000012", "sequence": 23, - "maxLedgerVersion": 8820051 + "maxLedgerVersion": 8819954 } } diff --git a/test/fixtures/responses/prepare-payment-min-amont-xrp-xrp.json b/test/fixtures/responses/prepare-payment-min-amont-xrp-xrp.json new file mode 100644 index 00000000..b2db5d6e --- /dev/null +++ b/test/fixtures/responses/prepare-payment-min-amont-xrp-xrp.json @@ -0,0 +1,8 @@ +{ + "txJSON": "{\"TransactionType\":\"Payment\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"Destination\":\"rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo\",\"Amount\":\"10000\",\"Flags\":2147483648,\"LastLedgerSequence\":8820051,\"Fee\":\"12\",\"Sequence\":23}", + "instructions": { + "fee": "0.000012", + "sequence": 23, + "maxLedgerVersion": 8820051 + } +} diff --git a/test/fixtures/responses/prepare-payment-min-amont-xrp.json b/test/fixtures/responses/prepare-payment-min-amont-xrp.json new file mode 100644 index 00000000..84a0b068 --- /dev/null +++ b/test/fixtures/responses/prepare-payment-min-amont-xrp.json @@ -0,0 +1,8 @@ +{ + "txJSON": "{\"TransactionType\":\"Payment\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"Destination\":\"rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo\",\"Amount\":\"100000000000000000\",\"Flags\":2147614720,\"SendMax\":{\"currency\":\"USD\",\"issuer\":\"rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM\",\"value\":\"0.01\"},\"DeliverMin\":\"100000000000000000\",\"LastLedgerSequence\":8820051,\"Fee\":\"12\",\"Sequence\":23}", + "instructions": { + "fee": "0.000012", + "sequence": 23, + "maxLedgerVersion": 8820051 + } +} diff --git a/test/fixtures/responses/prepare-settings-no-instructions.json b/test/fixtures/responses/prepare-settings-no-instructions.json new file mode 100644 index 00000000..aad61b7e --- /dev/null +++ b/test/fixtures/responses/prepare-settings-no-instructions.json @@ -0,0 +1 @@ +{"txJSON":"{\"TransactionType\":\"AccountSet\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"Domain\":\"726970706C652E636F6D\",\"Flags\":2147483648,\"LastLedgerSequence\":8819954,\"Fee\":\"12\",\"Sequence\":23}","instructions":{"fee":"0.000012","sequence":23,"maxLedgerVersion":8819954}} \ No newline at end of file diff --git a/test/fixtures/responses/prepare-suspended-payment-cancellation-memos.json b/test/fixtures/responses/prepare-suspended-payment-cancellation-memos.json new file mode 100644 index 00000000..ab501488 --- /dev/null +++ b/test/fixtures/responses/prepare-suspended-payment-cancellation-memos.json @@ -0,0 +1,8 @@ +{ + "txJSON": "{\"TransactionType\":\"SuspendedPaymentCancel\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"Owner\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"OfferSequence\":1234,\"Memos\":[{\"Memo\":{\"MemoData\":\"7465787465642064617461\",\"MemoType\":\"74657374\",\"MemoFormat\":\"706C61696E2F74657874\"}}],\"Flags\":2147483648,\"LastLedgerSequence\":8819954,\"Fee\":\"12\",\"Sequence\":23}", + "instructions": { + "fee": "0.000012", + "sequence": 23, + "maxLedgerVersion": 8819954 + } +} diff --git a/test/fixtures/responses/prepare-suspended-payment-creation-full.json b/test/fixtures/responses/prepare-suspended-payment-creation-full.json new file mode 100644 index 00000000..fcd62d21 --- /dev/null +++ b/test/fixtures/responses/prepare-suspended-payment-creation-full.json @@ -0,0 +1,8 @@ +{ + "txJSON": "{\"TransactionType\":\"SuspendedPaymentCreate\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"Destination\":\"rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo\",\"Amount\":{\"currency\":\"USD\",\"issuer\":\"rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM\",\"value\":\"0.01\"},\"Digest\":\"8F434346648F6B96DF89DDA901C5176B10A6D83961DD3C1AC88B59B2DC327AA4\",\"FinishAfter\":464908910,\"SourceTag\":1,\"DestinationTag\":2,\"Memos\":[{\"Memo\":{\"MemoData\":\"7465787465642064617461\",\"MemoType\":\"74657374\"}}],\"Flags\":2147483648,\"LastLedgerSequence\":8819954,\"Fee\":\"12\",\"Sequence\":23}", + "instructions": { + "fee": "0.000012", + "sequence": 23, + "maxLedgerVersion": 8819954 + } +} diff --git a/test/fixtures/responses/prepare-suspended-payment-execution-simple.json b/test/fixtures/responses/prepare-suspended-payment-execution-simple.json new file mode 100644 index 00000000..36851336 --- /dev/null +++ b/test/fixtures/responses/prepare-suspended-payment-execution-simple.json @@ -0,0 +1,8 @@ +{ + "txJSON": "{\"TransactionType\":\"SuspendedPaymentFinish\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"Owner\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"OfferSequence\":1234,\"Memos\":[{\"Memo\":{\"MemoData\":\"7465787465642064617461\",\"MemoType\":\"74657374\",\"MemoFormat\":\"706C61696E2F74657874\"}}],\"Flags\":2147483648,\"LastLedgerSequence\":8819954,\"Fee\":\"12\",\"Sequence\":23}", + "instructions": { + "fee": "0.000012", + "sequence": 23, + "maxLedgerVersion": 8819954 + } +} diff --git a/test/fixtures/responses/prepare-trustline-frozen.json b/test/fixtures/responses/prepare-trustline-frozen.json new file mode 100644 index 00000000..9dbbe4b2 --- /dev/null +++ b/test/fixtures/responses/prepare-trustline-frozen.json @@ -0,0 +1,8 @@ +{ + "txJSON": "{\"TransactionType\":\"TrustSet\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"LimitAmount\":{\"currency\":\"BTC\",\"issuer\":\"rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM\",\"value\":\"0.1\"},\"Flags\":2148859904,\"LastLedgerSequence\":8819954,\"Fee\":\"12\",\"Sequence\":23}", + "instructions": { + "fee": "0.000012", + "sequence": 23, + "maxLedgerVersion": 8819954 + } +} diff --git a/test/fixtures/rippled/account-offers.js b/test/fixtures/rippled/account-offers.js index 4b3b773d..551e12d1 100644 --- a/test/fixtures/rippled/account-offers.js +++ b/test/fixtures/rippled/account-offers.js @@ -24,6 +24,7 @@ module.exports = function(request, options = {}) { 'issuer': 'rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q', 'value': '17.70155237781915' }, + 'quality': '63.44025128030504', 'taker_pays': { 'currency': 'USD', 'issuer': 'rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q', diff --git a/test/fixtures/rippled/book-offers-1.json b/test/fixtures/rippled/book-offers-1.json new file mode 100644 index 00000000..6f774ea3 --- /dev/null +++ b/test/fixtures/rippled/book-offers-1.json @@ -0,0 +1,31 @@ +{ + "id": 0, + "result": { + "ledger_hash": "36783BEDBDEFC0402EB5347B8D9545AC69E70B0F14A95E0879CE2D3C2B4CE748", + "ledger_index": 13, + "offers": [ + { + "Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + "BookDirectory": "A118405CF7C2C89AB0CC084417187B86870DC14325C861A0561BB6E89EFF509C", + "BookNode": "0000000000000000", + "Flags": 131072, + "LedgerEntryType": "Offer", + "OwnerNode": "0000000000000000", + "PreviousTxnID": "CFB5786459E568DFC504E7319C515658DED657A7F4EFB5957B33E5E3BD9A1353", + "PreviousTxnLgrSeq": 13, + "Sequence": 6, + "TakerPays": "134000000", + "TakerGets": { + "currency": "USD", + "issuer": "rp8rJYTpodf8qbSCHVTNacf8nSW8mRakFw", + "value": "10453252347.1" + }, + "index": "C72CDC1BA4DA529B062871F22C6D175A4D97D4F1160D0D7E646E60699278B5B5", + "quality": "78.0093458738806" + } + ], + "validated": true + }, + "status": "success", + "type": "response" +} diff --git a/test/fixtures/rippled/book-offers-2.json b/test/fixtures/rippled/book-offers-2.json new file mode 100644 index 00000000..cb75a9f8 --- /dev/null +++ b/test/fixtures/rippled/book-offers-2.json @@ -0,0 +1,32 @@ +{ + "id": 3, + "result": { + "ledger_hash": "36783BEDBDEFC0402EB5347B8D9545AC69E70B0F14A95E0879CE2D3C2B4CE748", + "ledger_index": 13, + "offers": [ + { + "Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + "BookDirectory": "A118405CF7C2C89AB0CC084417187B86870DC14325C861A0470E1AEE5CBE20D9", + "BookNode": "0000000000000000", + "Flags": 0, + "LedgerEntryType": "Offer", + "OwnerNode": "0000000000000000", + "PreviousTxnID": "9DD36CC7338FEB9E501A33EAAA4C00DBE4ED3A692704C62DDBD1848EE1F6E762", + "PreviousTxnLgrSeq": 11, + "Sequence": 5, + "TakerGets": "254391353000000", + "TakerPays": { + "currency": "USD", + "issuer": "rp8rJYTpodf8qbSCHVTNacf8nSW8mRakFw", + "value": "10.1" + }, + "index": "BF656DABDD84E6128A45039F8D557C9477D4DA31F5B00868F2191F0A11FE3798", + "owner_funds": "99999998959999928", + "quality": "3970260734451929e-29" + } + ], + "validated": true + }, + "status": "success", + "type": "response" +} diff --git a/test/fixtures/rippled/get-transactions-one.json b/test/fixtures/rippled/get-transactions-one.json new file mode 100644 index 00000000..0533ef1e --- /dev/null +++ b/test/fixtures/rippled/get-transactions-one.json @@ -0,0 +1,58 @@ +{ + "id": 0, + "status": "success", + "type": "response", + "result": { + "account": "rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo", + "ledger_index_max": 17207682, + "ledger_index_min": 16462279, + "limit": 400, + "transactions": [ + { + "meta": { + "AffectedNodes": [ + { + "ModifiedNode": { + "FinalFields": { + "Account": "r9UHu5CWni1qRY7Q4CfFZLGvXo2pGQy96b", + "Balance": "71515076", + "Domain": "726970706C652E636F6D", + "Flags": 65536, + "OwnerCount": 3, + "RegularKey": "rsvEdWvfwzqkgvmaSEh9kgbcWiUc6s69ZC", + "Sequence": 492 + }, + "LedgerEntryType": "AccountRoot", + "LedgerIndex": "4AD70690C6FF8A069F8AE00B09F70E9B732360026E8085050D314432091A59C9", + "PreviousFields": { + "Balance": "71527076", + "Sequence": 491 + }, + "PreviousTxnID": "9B093C92C94EC9E492631B21E2DF45A9142C1BC39B60F3E5C4018DBAA164A423", + "PreviousTxnLgrSeq": 16318991 + } + } + ], + "TransactionIndex": 4, + "TransactionResult": "tesSUCCESS" + }, + "tx": { + "Account": "r9UHu5CWni1qRY7Q4CfFZLGvXo2pGQy96b", + "Domain": "726970706C652E636F6D", + "Fee": "12000", + "Flags": 2147483648, + "LastLedgerSequence": 16635157, + "Sequence": 491, + "SigningPubKey": "036A749E3B7187E43E8936E3D83A7030989325249E03803F12B7F64BAACABA6025", + "TransactionType": "AccountSet", + "TxnSignature": "3044022060C8F4CDD6092B539612790705B967E68111BC270B6B80AF23DF7B33E4C77137022059D9A8AA81052B7348F2728B263E2CCBEBE32880C54936D335F8125C6ED2F90E", + "date": 498881220, + "hash": "D868CFF0DF8C8AAF205404460EA764ACB3B8862527FA414BC8C1CA9A45B1F276", + "inLedger": 16635149, + "ledger_index": 16635149 + }, + "validated": true + } + ] + } +} diff --git a/test/fixtures/rippled/index.js b/test/fixtures/rippled/index.js index 5786f1ce..1abebc73 100644 --- a/test/fixtures/rippled/index.js +++ b/test/fixtures/rippled/index.js @@ -9,6 +9,7 @@ module.exports = { ledgerNotFound: require('./ledger-not-found'), ledgerWithoutCloseTime: require('./ledger-without-close-time'), ledgerWithSettingsTx: require('./ledger-with-settings-tx'), + ledgerWithStateAsHashes: require('./ledger-with-state-as-hashes'), subscribe: require('./subscribe'), unsubscribe: require('./unsubscribe'), account_info: { @@ -17,8 +18,11 @@ module.exports = { }, account_offers: require('./account-offers'), account_tx: require('./account-tx'), + account_tx_one: require('./get-transactions-one'), gateway_balances: require('./gateway-balances'), book_offers: require('./book-offers'), + book_offers_1: require('./book-offers-1'), + book_offers_2: require('./book-offers-2'), server_info: require('./server-info'), server_info_error: require('./server-info-error'), path_find: { @@ -35,6 +39,7 @@ module.exports = { AccountSetTrackingOff: require('./tx/account-set-tracking-off.json'), RegularKey: require('./tx/set-regular-key.json'), OfferCreate: require('./tx/offer-create.json'), + OfferCreateSell: require('./tx/offer-create-sell.json'), OfferCancel: require('./tx/offer-cancel.json'), TrustSet: require('./tx/trust-set.json'), TrustSetFrozenOff: require('./tx/trust-set-frozen-off.json'), @@ -46,8 +51,15 @@ module.exports = { NotValidated: require('./tx/not-validated.json'), OfferWithExpiration: require('./tx/order-with-expiration.json'), SuspendedPaymentCreation: require('./tx/suspended-payment-creation.json'), + SuspendedPaymentCreationIOU: + require('./tx/suspended-payment-creation-iou.json'), SuspendedPaymentCancellation: require('./tx/suspended-payment-cancellation.json'), - SuspendedPaymentExecution: require('./tx/suspended-payment-execution.json') + SuspendedPaymentExecution: require('./tx/suspended-payment-execution.json'), + SuspendedPaymentExecutionSimple: + require('./tx/suspended-payment-execution-simple.json'), + Unrecognized: require('./tx/unrecognized.json'), + NoMeta: require('./tx/no-meta.json'), + LedgerZero: require('./tx/ledger-zero.json') } }; diff --git a/test/fixtures/rippled/ledger-with-settings-tx.json b/test/fixtures/rippled/ledger-with-settings-tx.json index 4b630282..787b89e6 100644 --- a/test/fixtures/rippled/ledger-with-settings-tx.json +++ b/test/fixtures/rippled/ledger-with-settings-tx.json @@ -23,6 +23,7 @@ { "Account": "rEGy9CxMTFGXFgUHUMreTy2FbqArabGy38", "Fee": "10", + "ledger_index": 4181996, "Flags": 0, "Sequence": 6478, "SigningPubKey": "02CAB6F3A798712136DB5F105A98B0DE27C99AEDB68500181706B087CF1B6D0F2D", diff --git a/test/fixtures/rippled/ledger-with-state-as-hashes.json b/test/fixtures/rippled/ledger-with-state-as-hashes.json new file mode 100644 index 00000000..4ffbcc1e --- /dev/null +++ b/test/fixtures/rippled/ledger-with-state-as-hashes.json @@ -0,0 +1,33 @@ +{ + "id": 2, + "result": { + "ledger": { + "accepted": true, + "accountState": [ + "2B6AC232AA4C4BE41BF49D2459FA4A0347E1B543A4C92FCEE0821C0201E2E9A8", + "8B24E55376A65D68542C17F3BF446231AC7062CB43BED28817570128A1849819", + "B4979A36CDC7F3D3D5C31A4EAE2AC7D7209DDA877588B9AFC66799692AB0D66B" + ], + "account_hash": "8DBB7FA4036704D96AD32A4573BEE461FDDBDCB1B6F62CB17EDB5182F52AE9F1", + "close_flags": 0, + "close_time": 501159630, + "close_time_human": "2015-Nov-18 11:00:30", + "close_time_resolution": 30, + "closed": true, + "ledger_hash": "3D7115EDB5EC72FEF4ADDF46CA5B7770CBDECEAB3A97EA210BCC04E8C54A7CEE", + "parent_close_time": 501148381, + "parent_hash": "6D36AEFD3639EE22A27DDE0FA6C57525D103941F11D7FD6D91AC8D439DE2B3EE", + "seqNum": "6", + "totalCoins": "99999999999999964", + "transaction_hash": "B8D716B82BFFF4186BBBE7B7341AE0E1CBD2558952408B96E925EC0A51A6AEC2", + "transactions": [ + "B22E27F35F3F7679F76A474E4FF8E71EFA21B313DF2FC6678037A053A00FD084" + ] + }, + "ledger_hash": "3D7115EDB5EC72FEF4ADDF46CA5B7770CBDECEAB3A97EA210BCC04E8C54A7CEE", + "ledger_index": 6, + "validated": true + }, + "status": "success", + "type": "response" +} diff --git a/test/fixtures/rippled/tx/ledger-zero.json b/test/fixtures/rippled/tx/ledger-zero.json new file mode 100644 index 00000000..0835e7f6 --- /dev/null +++ b/test/fixtures/rippled/tx/ledger-zero.json @@ -0,0 +1,46 @@ +{ + "id": 0, + "status": "success", + "type": "response", + "result": { + "Account": "rLVKsA4F9iJBbA6rX2x4wCmkj6drgtqpQe", + "Fee": "10", + "Flags": 2147483648, + "Sequence": 1, + "SetFlag": 2, + "SigningPubKey": "03EA3ADCA632F125EC2CC4F7F6A82DE0DCE2B65290CAC1F22242C5163F0DA9652D", + "TransactionType": "AccountSet", + "TxnSignature": "3045022100DE8B666B1A31EA65011B0F32130AB91A5747E32FA49B3054CEE8E8362DBAB98A022040CF0CF254677A8E5CD04C59CA2ED7F6F15F7E184641BAE169C561650967B226", + "date": 460832270, + "hash": "4FB3ADF22F3C605E23FAEFAA185F3BD763C4692CAC490D9819D117CD33BFAA13", + "inLedger": 0, + "ledger_index": 0, + "meta": { + "AffectedNodes": [ + { + "ModifiedNode": { + "FinalFields": { + "Account": "rLVKsA4F9iJBbA6rX2x4wCmkj6drgtqpQe", + "Balance": "29999990", + "Flags": 786432, + "OwnerCount": 0, + "Sequence": 2 + }, + "LedgerEntryType": "AccountRoot", + "LedgerIndex": "3F5072C4875F32ED770DAF3610A716600ED7C7BB0348FADC7A98E011BB2CD36F", + "PreviousFields": { + "Balance": "30000000", + "Flags": 4194304, + "Sequence": 1 + }, + "PreviousTxnID": "3FB0350A3742BBCC0D8AA3C5247D1AEC01177D0A24D9C34762BAA2FEA8AD88B3", + "PreviousTxnLgrSeq": 8206397 + } + } + ], + "TransactionIndex": 5, + "TransactionResult": "tesSUCCESS" + }, + "validated": true + } +} diff --git a/test/fixtures/rippled/tx/no-meta.json b/test/fixtures/rippled/tx/no-meta.json new file mode 100644 index 00000000..28101a7c --- /dev/null +++ b/test/fixtures/rippled/tx/no-meta.json @@ -0,0 +1,44 @@ +{ + "id": 0, + "status": "success", + "type": "response", + "result": { + "Account": "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59", + "Amount": { + "currency": "USD", + "issuer": "rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM", + "value": "0.001" + }, + "Destination": "rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM", + "Fee": "10", + "Flags": 0, + "Paths": [ + [ + { + "currency": "USD", + "issuer": "rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo", + "type": 48, + "type_hex": "0000000000000030" + }, + { + "account": "rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo", + "currency": "USD", + "issuer": "rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo", + "type": 49, + "type_hex": "0000000000000031" + } + ] + ], + "SendMax": "1112209", + "Sequence": 4, + "SigningPubKey": "02BC8C02199949B15C005B997E7C8594574E9B02BA2D0628902E0532989976CF9D", + "TransactionType": "Payment", + "TxnSignature": "304502204EE3E9D1B01D8959B08450FCA9E22025AF503DEF310E34A93863A85CAB3C0BC5022100B61F5B567F77026E8DEED89EED0B7CAF0E6C96C228A2A65216F0DC2D04D52083", + "date": 416447810, + "hash": "AFB3ADF22F3C605E23FAEFAA185F3BD763C4692CAC490D9819D117CD33BFAA1B", + "inLedger": 348860, + "ledger_index": 348860, + "validated": true, + "validated": true + } +} diff --git a/test/fixtures/rippled/tx/offer-create-sell.json b/test/fixtures/rippled/tx/offer-create-sell.json new file mode 100644 index 00000000..a3e2c483 --- /dev/null +++ b/test/fixtures/rippled/tx/offer-create-sell.json @@ -0,0 +1,51 @@ +{ + "id": 0, + "result": { + "Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + "Fee": "12", + "Flags": 2148007936, + "LastLedgerSequence": 105, + "Sequence": 2, + "SigningPubKey": "0330E7FC9D56BB25D6893BA3F317AE5BCF33B3291BD63DB32654A313222F7FD020", + "TakerGets": { + "currency": "USD", + "issuer": "rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM", + "value": "10.1" + }, + "TakerPays": "254391353000000", + "TransactionType": "OfferCreate", + "TxnSignature": "30440221008C13CA1BD56431B643FD145CDE7BE1805424B48FDF40E0D1A8C2FD53FAACA974021F6393721438C01B9E3138D55469049C8B72B4F6A4508ACA3C0036788C300459", + "date": 501195390, + "hash": "458101D51051230B1D56E9ACAFAA34451BF65FA000F95DF6F0FF5B3A62D83FC2", + "inLedger": 6, + "ledger_index": 6, + "meta": { + "AffectedNodes": [ + { + "ModifiedNode": { + "FinalFields": { + "Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + "Balance": "99999999259999976", + "Flags": 0, + "OwnerCount": 0, + "Sequence": 3 + }, + "LedgerEntryType": "AccountRoot", + "LedgerIndex": "2B6AC232AA4C4BE41BF49D2459FA4A0347E1B543A4C92FCEE0821C0201E2E9A8", + "PreviousFields": { + "Balance": "99999999259999988", + "Sequence": 2 + }, + "PreviousTxnID": "4BF785A253AB67875973EE79B3ED939DF371B435696D09F8BE2FB2DADA1BFAB7", + "PreviousTxnLgrSeq": 4 + } + } + ], + "TransactionIndex": 0, + "TransactionResult": "tecUNFUNDED_OFFER" + }, + "validated": true + }, + "status": "success", + "type": "response" +} diff --git a/test/fixtures/rippled/tx/suspended-payment-creation-iou.json b/test/fixtures/rippled/tx/suspended-payment-creation-iou.json new file mode 100644 index 00000000..e05a1145 --- /dev/null +++ b/test/fixtures/rippled/tx/suspended-payment-creation-iou.json @@ -0,0 +1,97 @@ +{ + "id": 0, + "result": { + "Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + "Amount": {"value": "2", "issuer": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", "currency": "USD"}, + "CancelAfter": 500972022, + "Destination": "rp8rJYTpodf8qbSCHVTNacf8nSW8mRakFw", + "DestinationTag": 2, + "Digest": "8F434346648F6B96DF89DDA901C5176B10A6D83961DD3C1AC88B59B2DC327AA4", + "Fee": "12", + "FinishAfter": 500971662, + "Flags": 2147483648, + "LastLedgerSequence": 114, + "Memos": [ + { + "Memo": { + "MemoData": "6D656D612064617461", + "MemoFormat": "746578742F706C61696E", + "MemoType": "7832" + } + } + ], + "Sequence": 10, + "SigningPubKey": "0330E7FC9D56BB25D6893BA3F317AE5BCF33B3291BD63DB32654A313222F7FD020", + "SourceTag": 1, + "TransactionType": "SuspendedPaymentCreate", + "TxnSignature": "3045022100EA1C5433AFA3F0BAAAF7C4146B032B86A0212EB4E2A3551DE9717651A538AE260220228C9E9FC857EC8143F01C2F959A8F134B285B67D8261B49E57BFF8DF76D2255", + "date": 500971380, + "hash": "144F272380BDB4F1BD92329A2178BABB70C20F59042C495E10BF72EBFB408EE2", + "inLedger": 15, + "ledger_index": 15, + "meta": { + "AffectedNodes": [ + { + "CreatedNode": { + "LedgerEntryType": "SuspendedPayment", + "LedgerIndex": "0D7629A23BC20F25C48D9423E2485582255A74B76A25F26EDB46766982E4C2C4", + "NewFields": { + "Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + "Amount": "2", + "CancelAfter": 500972022, + "Destination": "rp8rJYTpodf8qbSCHVTNacf8nSW8mRakFw", + "DestinationTag": 2, + "Digest": "8F434346648F6B96DF89DDA901C5176B10A6D83961DD3C1AC88B59B2DC327AA4", + "FinishAfter": 500971662, + "SourceTag": 1 + } + } + }, + { + "ModifiedNode": { + "FinalFields": { + "Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + "Balance": "99999997964999876", + "Flags": 0, + "OwnerCount": 3, + "Sequence": 11 + }, + "LedgerEntryType": "AccountRoot", + "LedgerIndex": "2B6AC232AA4C4BE41BF49D2459FA4A0347E1B543A4C92FCEE0821C0201E2E9A8", + "PreviousFields": { + "Balance": "99999997964999890", + "OwnerCount": 2, + "Sequence": 10 + }, + "PreviousTxnID": "F346E542FFB7A8398C30A87B952668DAB48B7D421094F8B71776DA19775A3B22", + "PreviousTxnLgrSeq": 14 + } + }, + { + "ModifiedNode": { + "LedgerEntryType": "AccountRoot", + "LedgerIndex": "8B24E55376A65D68542C17F3BF446231AC7062CB43BED28817570128A1849819", + "PreviousTxnID": "F346E542FFB7A8398C30A87B952668DAB48B7D421094F8B71776DA19775A3B22", + "PreviousTxnLgrSeq": 14 + } + }, + { + "ModifiedNode": { + "FinalFields": { + "Flags": 0, + "Owner": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + "RootIndex": "D8120FC732737A2CF2E9968FDF3797A43B457F2A81AA06D2653171A1EA635204" + }, + "LedgerEntryType": "DirectoryNode", + "LedgerIndex": "D8120FC732737A2CF2E9968FDF3797A43B457F2A81AA06D2653171A1EA635204" + } + } + ], + "TransactionIndex": 0, + "TransactionResult": "tesSUCCESS" + }, + "validated": true + }, + "status": "success", + "type": "response" +} \ No newline at end of file diff --git a/test/fixtures/rippled/tx/suspended-payment-execution-simple.json b/test/fixtures/rippled/tx/suspended-payment-execution-simple.json new file mode 100644 index 00000000..3d76a2e9 --- /dev/null +++ b/test/fixtures/rippled/tx/suspended-payment-execution-simple.json @@ -0,0 +1,99 @@ +{ + "id": 0, + "result": { + "Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + "Digest": "632F2F3E437AE720C397994A985B5D21FE186DE61523A9CA3E8709CC581671A1", + "Fee": "12", + "Flags": 2147483648, + "LastLedgerSequence": 113, + "Method": 1, + "OfferSequence": 5, + "Owner": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + "Sequence": 6, + "SigningPubKey": "0330E7FC9D56BB25D6893BA3F317AE5BCF33B3291BD63DB32654A313222F7FD020", + "TransactionType": "SuspendedPaymentFinish", + "TxnSignature": "304402204E981802BA2F4C3677E69B26387CC157284D31886CF95B73A8AB3E717FE6A6490220519CD84CA01BA5D7A49809B041929F12D56F32E76FAE73F0FAFF7B5E7B8B110B", + "date": 501040060, + "hash": "CC5277137B3F25EE8B86259C83CB0EAADE818505E4E9BCBF19B1AC6FD1369931", + "inLedger": 14, + "ledger_index": 14, + "meta": { + "AffectedNodes": [ + { + "ModifiedNode": { + "FinalFields": { + "Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + "Balance": "99999999239999842", + "Flags": 0, + "OwnerCount": 0, + "Sequence": 7 + }, + "LedgerEntryType": "AccountRoot", + "LedgerIndex": "2B6AC232AA4C4BE41BF49D2459FA4A0347E1B543A4C92FCEE0821C0201E2E9A8", + "PreviousFields": { + "Balance": "99999999239999854", + "OwnerCount": 1, + "Sequence": 6 + }, + "PreviousTxnID": "22E0E87BAD4832CFD2B49409D488E5F92DD38424FD1781602277585914120C1E", + "PreviousTxnLgrSeq": 12 + } + }, + { + "ModifiedNode": { + "FinalFields": { + "Account": "rp8rJYTpodf8qbSCHVTNacf8nSW8mRakFw", + "Balance": "760000086", + "Flags": 0, + "OwnerCount": 0, + "Sequence": 1 + }, + "LedgerEntryType": "AccountRoot", + "LedgerIndex": "8B24E55376A65D68542C17F3BF446231AC7062CB43BED28817570128A1849819", + "PreviousFields": { + "Balance": "750000043" + }, + "PreviousTxnID": "22E0E87BAD4832CFD2B49409D488E5F92DD38424FD1781602277585914120C1E", + "PreviousTxnLgrSeq": 12 + } + }, + { + "DeletedNode": { + "FinalFields": { + "Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + "Amount": "10000043", + "CancelAfter": 501079458, + "Destination": "rp8rJYTpodf8qbSCHVTNacf8nSW8mRakFw", + "DestinationTag": 2, + "Digest": "632F2F3E437AE720C397994A985B5D21FE186DE61523A9CA3E8709CC581671A1", + "FinishAfter": 501039918, + "Flags": 0, + "OwnerNode": "0000000000000000", + "PreviousTxnID": "22E0E87BAD4832CFD2B49409D488E5F92DD38424FD1781602277585914120C1E", + "PreviousTxnLgrSeq": 12, + "SourceTag": 1 + }, + "LedgerEntryType": "SuspendedPayment", + "LedgerIndex": "AA7D93BDB975252718205C98792BF8940E3FC6E6972213F451AB5D602E8AD971" + } + }, + { + "DeletedNode": { + "FinalFields": { + "Flags": 0, + "Owner": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + "RootIndex": "D8120FC732737A2CF2E9968FDF3797A43B457F2A81AA06D2653171A1EA635204" + }, + "LedgerEntryType": "DirectoryNode", + "LedgerIndex": "D8120FC732737A2CF2E9968FDF3797A43B457F2A81AA06D2653171A1EA635204" + } + } + ], + "TransactionIndex": 0, + "TransactionResult": "tesSUCCESS" + }, + "validated": true + }, + "status": "success", + "type": "response" +} diff --git a/test/fixtures/rippled/tx/unrecognized.json b/test/fixtures/rippled/tx/unrecognized.json new file mode 100644 index 00000000..f55222e0 --- /dev/null +++ b/test/fixtures/rippled/tx/unrecognized.json @@ -0,0 +1,46 @@ +{ + "id": 0, + "status": "success", + "type": "response", + "result": { + "Account": "rLVKsA4F9iJBbA6rX2x4wCmkj6drgtqpQe", + "Fee": "10", + "Flags": 2147483648, + "Sequence": 1, + "SetFlag": 2, + "SigningPubKey": "03EA3ADCA632F125EC2CC4F7F6A82DE0DCE2B65290CAC1F22242C5163F0DA9652D", + "TransactionType": "Unrecognized", + "TxnSignature": "3045022100DE8B666B1A31EA65011B0F32130AB91A5747E32FA49B3054CEE8E8362DBAB98A022040CF0CF254677A8E5CD04C59CA2ED7F6F15F7E184641BAE169C561650967B226", + "date": 460832270, + "hash": "AFB3ADF22F3C605E23FAEFAA185F3BD763C4692CAC490D9819D117CD33BFAA11", + "inLedger": 8206418, + "ledger_index": 8206418, + "meta": { + "AffectedNodes": [ + { + "ModifiedNode": { + "FinalFields": { + "Account": "rLVKsA4F9iJBbA6rX2x4wCmkj6drgtqpQe", + "Balance": "29999990", + "Flags": 786432, + "OwnerCount": 0, + "Sequence": 2 + }, + "LedgerEntryType": "AccountRoot", + "LedgerIndex": "3F5072C4875F32ED770DAF3610A716600ED7C7BB0348FADC7A98E011BB2CD36F", + "PreviousFields": { + "Balance": "30000000", + "Flags": 4194304, + "Sequence": 1 + }, + "PreviousTxnID": "3FB0350A3742BBCC0D8AA3C5247D1AEC01177D0A24D9C34762BAA2FEA8AD88B3", + "PreviousTxnLgrSeq": 8206397 + } + } + ], + "TransactionIndex": 5, + "TransactionResult": "tesSUCCESS" + }, + "validated": true + } +} diff --git a/test/mock-rippled.js b/test/mock-rippled.js index beabbd64..03d849b5 100644 --- a/test/mock-rippled.js +++ b/test/mock-rippled.js @@ -70,7 +70,7 @@ module.exports = function(port) { mock.expectedRequests = expectedRequests; }; - mock.once('connection', function(conn) { + mock.on('connection', function(conn) { conn.on('message', function(requestJSON) { const request = JSON.parse(requestJSON); mock.emit('request_' + request.command, request, conn); @@ -140,6 +140,8 @@ module.exports = function(port) { assert.strictEqual(request.command, 'ledger'); if (request.ledger_index === 34) { conn.send(createLedgerResponse(request, fixtures.ledgerNotFound)); + } else if (request.ledger_index === 6) { + conn.send(createResponse(request, fixtures.ledgerWithStateAsHashes)); } else if (request.ledger_index === 9038215) { conn.send(createLedgerResponse(request, fixtures.ledgerWithoutCloseTime)); } else if (request.ledger_index === 4181996) { @@ -172,6 +174,9 @@ module.exports = function(port) { } else if (request.transaction === '10A6FB4A66EE80BED46AAE4815D7DC43B97E944984CCD5B93BCF3F8538CABC51') { conn.send(createResponse(request, fixtures.tx.OfferCreate)); + } else if (request.transaction === + '458101D51051230B1D56E9ACAFAA34451BF65FA000F95DF6F0FF5B3A62D83FC2') { + conn.send(createResponse(request, fixtures.tx.OfferCreateSell)); } else if (request.transaction === '809335DD3B0B333865096217AA2F55A4DF168E0198080B3A090D12D88880FF0E') { conn.send(createResponse(request, fixtures.tx.OfferCancel)); @@ -204,6 +209,10 @@ module.exports = function(port) { } else if (request.transaction === '144F272380BDB4F1BD92329A2178BABB70C20F59042C495E10BF72EBFB408EE1') { conn.send(createResponse(request, fixtures.tx.SuspendedPaymentCreation)); + } else if (request.transaction === + '144F272380BDB4F1BD92329A2178BABB70C20F59042C495E10BF72EBFB408EE2') { + conn.send(createResponse(request, + fixtures.tx.SuspendedPaymentCreationIOU)); } else if (request.transaction === 'F346E542FFB7A8398C30A87B952668DAB48B7D421094F8B71776DA19775A3B22') { conn.send(createResponse(request, @@ -211,6 +220,19 @@ module.exports = function(port) { } else if (request.transaction === 'CC5277137B3F25EE8B86259C83CB0EAADE818505E4E9BCBF19B1AC6FD136993B') { conn.send(createResponse(request, fixtures.tx.SuspendedPaymentExecution)); + } else if (request.transaction === + 'CC5277137B3F25EE8B86259C83CB0EAADE818505E4E9BCBF19B1AC6FD1369931') { + conn.send(createResponse(request, + fixtures.tx.SuspendedPaymentExecutionSimple)); + } else if (request.transaction === + 'AFB3ADF22F3C605E23FAEFAA185F3BD763C4692CAC490D9819D117CD33BFAA11') { + conn.send(createResponse(request, fixtures.tx.Unrecognized)); + } else if (request.transaction === + 'AFB3ADF22F3C605E23FAEFAA185F3BD763C4692CAC490D9819D117CD33BFAA1B') { + conn.send(createResponse(request, fixtures.tx.NoMeta)); + } else if (request.transaction === + '4FB3ADF22F3C605E23FAEFAA185F3BD763C4692CAC490D9819D117CD33BFAA13') { + conn.send(createResponse(request, fixtures.tx.LedgerZero)); } else { assert(false, 'Unrecognized transaction hash: ' + request.transaction); } @@ -240,6 +262,8 @@ module.exports = function(port) { mock.on('request_account_tx', function(request, conn) { if (request.account === addresses.ACCOUNT) { conn.send(transactionsResponse(request)); + } else if (request.account === addresses.OTHER_ACCOUNT) { + conn.send(createResponse(request, fixtures.account_tx_one)); } else { assert(false, 'Unrecognized account address: ' + request.account); } @@ -254,7 +278,12 @@ module.exports = function(port) { }); mock.on('request_book_offers', function(request, conn) { - if (isBTC(request.taker_gets.currency) + if (request.taker_pays.issuer === 'rp8rJYTpodf8qbSCHVTNacf8nSW8mRakFw') { + conn.send(createResponse(request, fixtures.book_offers_2)); + } else if (request.taker_gets.issuer + === 'rp8rJYTpodf8qbSCHVTNacf8nSW8mRakFw') { + conn.send(createResponse(request, fixtures.book_offers_1)); + } else if (isBTC(request.taker_gets.currency) && isUSD(request.taker_pays.currency)) { conn.send(fixtures.book_offers.requestBookOffersBidsResponse(request)); } else if (isUSD(request.taker_gets.currency) @@ -296,7 +325,11 @@ module.exports = function(port) { }); mock.on('request_gateway_balances', function(request, conn) { - conn.send(createResponse(request, fixtures.gateway_balances)); + if (request.ledger_index === 123456) { + conn.send(createResponse(request, fixtures.unsubscribe)); + } else { + conn.send(createResponse(request, fixtures.gateway_balances)); + } }); return mock;