Skip to content

Commit

Permalink
Add support for order expiration
Browse files Browse the repository at this point in the history
  • Loading branch information
Chris Clark committed Oct 30, 2015
1 parent 36806e4 commit 665f5f9
Show file tree
Hide file tree
Showing 22 changed files with 253 additions and 42 deletions.
4 changes: 2 additions & 2 deletions npm-shrinkwrap.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Expand Up @@ -24,7 +24,7 @@
"ripple-binary-codec": "^0.0.6",
"ripple-hashes": "^0.0.1",
"ripple-keypairs": "^0.10.0",
"ripple-lib-transactionparser": "^0.5.1",
"ripple-lib-transactionparser": "^0.6.0",
"ws": "~0.7.1"
},
"devDependencies": {
Expand Down
7 changes: 4 additions & 3 deletions src/common/schemas/order-change.json
Expand Up @@ -7,11 +7,12 @@
"type": "string",
"enum": ["buy", "sell"]
},
"quantity": {"$ref": "balance"},
"totalPrice": {"$ref": "balance"},
"quantity": {"$ref": "amount"},
"totalPrice": {"$ref": "amount"},
"makerExchangeRate": {"$ref": "value"},
"sequence": {"$ref": "sequence"},
"status": {"enum": ["created", "open", "closed", "canceled"]}
"status": {"enum": ["created", "filled", "partially-filled", "cancelled"]},
"expirationTime": {"type": "string", "format": "date-time"}
},
"required": ["direction", "quantity", "totalPrice", "sequence", "status"],
"additionalProperties": false
Expand Down
3 changes: 2 additions & 1 deletion src/common/schemas/order.json
Expand Up @@ -14,7 +14,8 @@
"passive": {
"description": "If enabled, the offer will not consume offers that exactly match it, and instead becomes an Offer node in the ledger. It will still consume offers that cross it.",
"type": "boolean"
}
},
"expirationTime": {"type": "string", "format": "date-time"}
},
"required": ["direction", "quantity", "totalPrice"],
"additionalProperties": false,
Expand Down
4 changes: 3 additions & 1 deletion src/ledger/parse/account-order.js
Expand Up @@ -26,7 +26,9 @@ function parseAccountOrder(address: string, order: Object): Object {
direction: direction,
quantity: quantity,
totalPrice: totalPrice,
passive: ((order.flags & flags.Passive) !== 0) || undefined
passive: ((order.flags & flags.Passive) !== 0) || undefined,
// rippled currently does not provide "expiration" in account_offers
expirationTime: utils.parseTimestamp(order.expiration)
});

const properties = {
Expand Down
3 changes: 2 additions & 1 deletion src/ledger/parse/order.js
Expand Up @@ -21,7 +21,8 @@ function parseOrder(tx: Object): Object {
passive: ((tx.Flags & flags.Passive) !== 0) || undefined,
immediateOrCancel: ((tx.Flags & flags.ImmediateOrCancel) !== 0)
|| undefined,
fillOrKill: ((tx.Flags & flags.FillOrKill) !== 0) || undefined
fillOrKill: ((tx.Flags & flags.FillOrKill) !== 0) || undefined,
expirationTime: utils.parseTimestamp(tx.Expiration)
});
}

Expand Down
3 changes: 2 additions & 1 deletion src/ledger/parse/orderbook-order.js
Expand Up @@ -18,7 +18,8 @@ function parseOrderbookOrder(order: Object): Object {
direction: direction,
quantity: quantity,
totalPrice: totalPrice,
passive: ((order.Flags & flags.Passive) !== 0) || undefined
passive: ((order.Flags & flags.Passive) !== 0) || undefined,
expirationTime: utils.parseTimestamp(order.Expiration)
});

const properties = {
Expand Down
7 changes: 4 additions & 3 deletions src/ledger/parse/utils.js
Expand Up @@ -18,8 +18,8 @@ function adjustQualityForXRP(
(new BigNumber(quality)).shift(shift).toString();
}

function parseTimestamp(tx: {date: string}): string | void {
return tx.date ? (new Date(rippleToUnixTimestamp(tx.date))).toISOString()
function parseTimestamp(date: number): string | void {
return date ? (new Date(rippleToUnixTimestamp(date))).toISOString()
: undefined;
}

Expand Down Expand Up @@ -55,7 +55,7 @@ function parseOutcome(tx: Object): ?Object {

return {
result: tx.meta.TransactionResult,
timestamp: parseTimestamp(tx),
timestamp: parseTimestamp(tx.date),
fee: utils.common.dropsToXrp(tx.Fee),
balanceChanges: balanceChanges,
orderbookChanges: orderbookChanges,
Expand Down Expand Up @@ -85,6 +85,7 @@ module.exports = {
parseOutcome,
parseMemos,
hexToString,
parseTimestamp,
adjustQualityForXRP,
dropsToXrp: utils.common.dropsToXrp,
constants: utils.common.constants,
Expand Down
4 changes: 4 additions & 0 deletions src/transaction/order.js
Expand Up @@ -3,6 +3,7 @@
const utils = require('./utils');
const validate = utils.common.validate;
const offerFlags = utils.common.txFlags.OfferCreate;
const unixToRippleTimestamp = utils.common.unixToRippleTimestamp;
import type {Instructions, Prepare} from './types.js';
import type {Order} from '../ledger/transaction-types.js';

Expand Down Expand Up @@ -34,6 +35,9 @@ function createOrderTransaction(account: string, order: Order): Object {
if (order.fillOrKill === true) {
txJSON.Flags |= offerFlags.FillOrKill;
}
if (order.expirationTime !== undefined) {
txJSON.Expiration = unixToRippleTimestamp(Date.parse(order.expirationTime));
}
return txJSON;
}

Expand Down
27 changes: 22 additions & 5 deletions test/api-test.js
Expand Up @@ -83,14 +83,22 @@ describe('RippleAPI', function() {
});

it('prepareOrder - buy order', function() {
return this.api.prepareOrder(address, requests.prepareOrder, instructions)
.then(_.partial(checkResult, responses.prepareOrder, 'prepare'));
const request = requests.prepareOrder.buy;
return this.api.prepareOrder(address, request, instructions)
.then(_.partial(checkResult, responses.prepareOrder.buy, 'prepare'));
});

it('prepareOrder - buy order with expiration', function() {
const request = requests.prepareOrder.expiration;
const response = responses.prepareOrder.expiration;
return this.api.prepareOrder(address, request, instructions)
.then(_.partial(checkResult, response, 'prepare'));
});

it('prepareOrder - sell order', function() {
return this.api.prepareOrder(
address, requests.prepareOrderSell, instructions).then(
_.partial(checkResult, responses.prepareOrderSell, 'prepare'));
const request = requests.prepareOrder.sell;
return this.api.prepareOrder(address, request, instructions).then(
_.partial(checkResult, responses.prepareOrder.sell, 'prepare'));
});

it('prepareOrderCancellation', function() {
Expand Down Expand Up @@ -280,6 +288,15 @@ describe('RippleAPI', function() {
'getTransaction'));
});

it('getTransaction - order with expiration cancellation', function() {
const hash =
'097B9491CC76B64831F1FEA82EAA93BCD728106D90B65A072C933888E946C40B';
return this.api.getTransaction(hash).then(
_.partial(checkResult,
responses.getTransaction.orderWithExpirationCancellation,
'getTransaction'));
});

it('getTransaction - trustline set', function() {
const hash =
'635A0769BD94710A1F6A76CDE65A3BC661B20B798807D1BBBDADCEA26420538D';
Expand Down
7 changes: 5 additions & 2 deletions test/fixtures/api/requests/index.js
@@ -1,8 +1,11 @@
'use strict';

module.exports = {
prepareOrder: require('./prepare-order'),
prepareOrderSell: require('./prepare-order-sell'),
prepareOrder: {
buy: require('./prepare-order'),
sell: require('./prepare-order-sell'),
expiration: require('./prepare-order-expiration')
},
preparePayment: require('./prepare-payment'),
preparePaymentAllOptions: require('./prepare-payment-all-options'),
preparePaymentNoCounterparty: require('./prepare-payment-no-counterparty'),
Expand Down
14 changes: 14 additions & 0 deletions test/fixtures/api/requests/prepare-order-expiration.json
@@ -0,0 +1,14 @@
{
"direction": "buy",
"quantity": {
"currency": "USD",
"counterparty": "rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM",
"value": "10.1"
},
"totalPrice": {
"currency": "XRP",
"value": "2"
},
"immediateOrCancel": true,
"expirationTime": "2015-01-14T18:36:52.000Z"
}
21 changes: 14 additions & 7 deletions test/fixtures/api/responses/get-orderbook.json
Expand Up @@ -52,7 +52,8 @@
"currency": "BTC",
"value": "0.3",
"counterparty": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B"
}
},
"expirationTime": "2014-12-25T01:14:43.000Z"
},
"properties": {
"maker": "raudnGKfTK23YKfnS7ixejHrqGERTYNFXk",
Expand Down Expand Up @@ -104,7 +105,8 @@
"currency": "BTC",
"value": "0.4499999999999999",
"counterparty": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B"
}
},
"expirationTime": "2014-12-25T01:14:44.000Z"
},
"properties": {
"maker": "raudnGKfTK23YKfnS7ixejHrqGERTYNFXk",
Expand Down Expand Up @@ -144,7 +146,8 @@
"currency": "BTC",
"value": "0.5",
"counterparty": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B"
}
},
"expirationTime": "2014-12-25T00:41:38.000Z"
},
"properties": {
"maker": "rDVBvAQScXrGRGnzrxRrcJPeNLeLeUTAqE",
Expand Down Expand Up @@ -196,7 +199,8 @@
"currency": "BTC",
"value": "0.8",
"counterparty": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B"
}
},
"expirationTime": "2014-12-25T00:41:39.000Z"
},
"properties": {
"maker": "rDVBvAQScXrGRGnzrxRrcJPeNLeLeUTAqE",
Expand Down Expand Up @@ -290,7 +294,8 @@
"currency": "BTC",
"value": "0.4499999999999999",
"counterparty": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B"
}
},
"expirationTime": "2014-12-25T01:14:44.000Z"
},
"properties": {
"maker": "raudnGKfTK23YKfnS7ixejHrqGERTYNFXk",
Expand Down Expand Up @@ -322,7 +327,8 @@
"currency": "BTC",
"value": "0.8",
"counterparty": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B"
}
},
"expirationTime": "2014-12-24T21:44:11.000Z"
},
"properties": {
"maker": "rDVBvAQScXrGRGnzrxRrcJPeNLeLeUTAqE",
Expand Down Expand Up @@ -434,7 +440,8 @@
"currency": "BTC",
"value": "1.6",
"counterparty": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B"
}
},
"expirationTime": "2014-12-24T21:44:12.000Z"
},
"properties": {
"maker": "rDVBvAQScXrGRGnzrxRrcJPeNLeLeUTAqE",
Expand Down
Expand Up @@ -25,15 +25,15 @@
"quantity": {
"currency": "USD",
"counterparty": "rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q",
"value": "0"
"value": "237"
},
"totalPrice": {
"currency": "XRP",
"value": "0"
"value": "0.0002"
},
"makerExchangeRate": "1185000",
"sequence": 465,
"status": "canceled"
"status": "cancelled"
}
]
},
Expand Down
@@ -0,0 +1,44 @@
{
"type": "orderCancellation",
"address": "rBSZe33F5oxHTbxSF1nZJooVDpcrrqNFp3",
"sequence": 1122979,
"id": "097B9491CC76B64831F1FEA82EAA93BCD728106D90B65A072C933888E946C40B",
"specification": {
"orderSequence": 1122978
},
"outcome": {
"result": "tesSUCCESS",
"timestamp": "2015-01-14T18:27:00.000Z",
"fee": "0.011",
"balanceChanges": {
"rBSZe33F5oxHTbxSF1nZJooVDpcrrqNFp3": [
{
"currency": "XRP",
"value": "-0.011"
}
]
},
"orderbookChanges": {
"rBSZe33F5oxHTbxSF1nZJooVDpcrrqNFp3": [
{
"direction": "buy",
"quantity": {
"currency": "CNY",
"counterparty": "rnuF96W4SZoCJmbHYBFoJZpR8eCaxNvekK",
"value": "3200"
},
"totalPrice": {
"currency": "XRP",
"value": "34700.537395"
},
"sequence": 1122978,
"status": "cancelled",
"makerExchangeRate": "0.09221759200942773",
"expirationTime": "2015-01-14T18:36:52.000Z"
}
]
},
"ledgerVersion": 11119599,
"indexInLedger": 15
}
}
6 changes: 3 additions & 3 deletions test/fixtures/api/responses/get-transaction-payment.json
Expand Up @@ -68,16 +68,16 @@
"direction": "buy",
"quantity": {
"currency": "XRP",
"value": "-1.101198"
"value": "1.101198"
},
"totalPrice": {
"currency": "USD",
"counterparty": "rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo",
"value": "-0.001002"
"value": "0.001002"
},
"makerExchangeRate": "1099",
"sequence": 58,
"status": "open"
"status": "partially-filled"
}
]
},
Expand Down
12 changes: 6 additions & 6 deletions test/fixtures/api/responses/get-transactions.json
Expand Up @@ -74,16 +74,16 @@
"direction": "buy",
"quantity": {
"currency": "XRP",
"value": "-1.101198"
"value": "1.101198"
},
"totalPrice": {
"currency": "USD",
"counterparty": "rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo",
"value": "-0.001002"
"value": "0.001002"
},
"makerExchangeRate": "1099",
"sequence": 58,
"status": "open"
"status": "partially-filled"
}
]
},
Expand Down Expand Up @@ -166,16 +166,16 @@
"direction": "buy",
"quantity": {
"currency": "XRP",
"value": "-1.101198"
"value": "1.101198"
},
"totalPrice": {
"currency": "USD",
"counterparty": "rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo",
"value": "-0.001002"
"value": "0.001002"
},
"makerExchangeRate": "1099",
"sequence": 58,
"status": "open"
"status": "partially-filled"
}
]
},
Expand Down

0 comments on commit 665f5f9

Please sign in to comment.