You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

transactions.js 6.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. "use strict";
  2. var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
  3. if (k2 === undefined) k2 = k;
  4. Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
  5. }) : (function(o, m, k, k2) {
  6. if (k2 === undefined) k2 = k;
  7. o[k2] = m[k];
  8. }));
  9. var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
  10. Object.defineProperty(o, "default", { enumerable: true, value: v });
  11. }) : function(o, v) {
  12. o["default"] = v;
  13. });
  14. var __importStar = (this && this.__importStar) || function (mod) {
  15. if (mod && mod.__esModule) return mod;
  16. var result = {};
  17. if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
  18. __setModuleDefault(result, mod);
  19. return result;
  20. };
  21. var __importDefault = (this && this.__importDefault) || function (mod) {
  22. return (mod && mod.__esModule) ? mod : { "default": mod };
  23. };
  24. Object.defineProperty(exports, "__esModule", { value: true });
  25. const _ = __importStar(require("lodash"));
  26. const ripple_binary_codec_1 = __importDefault(require("ripple-binary-codec"));
  27. const hashes_1 = require("../common/hashes");
  28. const utils = __importStar(require("./utils"));
  29. const transaction_1 = __importDefault(require("./parse/transaction"));
  30. const transaction_2 = __importDefault(require("./transaction"));
  31. const common_1 = require("../common");
  32. function parseBinaryTransaction(transaction) {
  33. const tx = ripple_binary_codec_1.default.decode(transaction.tx_blob);
  34. tx.hash = hashes_1.computeTransactionHash(tx);
  35. tx.ledger_index = transaction.ledger_index;
  36. return {
  37. tx: tx,
  38. meta: ripple_binary_codec_1.default.decode(transaction.meta),
  39. validated: transaction.validated
  40. };
  41. }
  42. function parseAccountTxTransaction(tx, includeRawTransaction) {
  43. const _tx = tx.tx_blob ? parseBinaryTransaction(tx) : tx;
  44. return transaction_1.default(Object.assign({}, _tx.tx, { meta: _tx.meta, validated: _tx.validated }), includeRawTransaction);
  45. }
  46. function counterpartyFilter(filters, tx) {
  47. if (tx.address === filters.counterparty) {
  48. return true;
  49. }
  50. const specification = tx.specification;
  51. if (specification &&
  52. ((specification.destination &&
  53. specification.destination.address === filters.counterparty) ||
  54. specification.counterparty === filters.counterparty)) {
  55. return true;
  56. }
  57. return false;
  58. }
  59. function transactionFilter(address, filters, tx) {
  60. if (filters.excludeFailures && tx.outcome.result !== 'tesSUCCESS') {
  61. return false;
  62. }
  63. if (filters.types && !filters.types.includes(tx.type)) {
  64. return false;
  65. }
  66. if (filters.initiated === true && tx.address !== address) {
  67. return false;
  68. }
  69. if (filters.initiated === false && tx.address === address) {
  70. return false;
  71. }
  72. if (filters.counterparty && !counterpartyFilter(filters, tx)) {
  73. return false;
  74. }
  75. return true;
  76. }
  77. function orderFilter(options, tx) {
  78. return (!options.startTx ||
  79. (options.earliestFirst
  80. ? utils.compareTransactions(tx, options.startTx) > 0
  81. : utils.compareTransactions(tx, options.startTx) < 0));
  82. }
  83. function formatPartialResponse(address, options, data) {
  84. const parse = (tx) => parseAccountTxTransaction(tx, options.includeRawTransactions);
  85. return {
  86. marker: data.marker,
  87. results: data.transactions
  88. .filter((tx) => tx.validated)
  89. .map(parse)
  90. .filter(_.partial(transactionFilter, address, options))
  91. .filter(_.partial(orderFilter, options))
  92. };
  93. }
  94. function getAccountTx(connection, address, options, marker, limit) {
  95. const request = {
  96. command: 'account_tx',
  97. account: address,
  98. ledger_index_min: options.minLedgerVersion || -1,
  99. ledger_index_max: options.maxLedgerVersion || -1,
  100. forward: options.earliestFirst,
  101. binary: options.binary,
  102. limit: utils.clamp(limit, 10, 400),
  103. marker: marker
  104. };
  105. return connection
  106. .request(request)
  107. .then((response) => formatPartialResponse(address, options, response));
  108. }
  109. function checkForLedgerGaps(connection, options, transactions) {
  110. let { minLedgerVersion, maxLedgerVersion } = options;
  111. if (options.limit && transactions.length === options.limit) {
  112. if (options.earliestFirst) {
  113. maxLedgerVersion = transactions[transactions.length - 1].outcome.ledgerVersion;
  114. }
  115. else {
  116. minLedgerVersion = transactions[transactions.length - 1].outcome.ledgerVersion;
  117. }
  118. }
  119. return utils
  120. .hasCompleteLedgerRange(connection, minLedgerVersion, maxLedgerVersion)
  121. .then((hasCompleteLedgerRange) => {
  122. if (!hasCompleteLedgerRange) {
  123. throw new common_1.errors.MissingLedgerHistoryError();
  124. }
  125. });
  126. }
  127. function formatResponse(connection, options, transactions) {
  128. const sortedTransactions = options.earliestFirst
  129. ? transactions.sort(utils.compareTransactions)
  130. : transactions.sort(utils.compareTransactions).reverse();
  131. return checkForLedgerGaps(connection, options, sortedTransactions).then(() => sortedTransactions);
  132. }
  133. function getTransactionsInternal(connection, address, options) {
  134. const getter = _.partial(getAccountTx, connection, address, options);
  135. const format = _.partial(formatResponse, connection, options);
  136. return utils.getRecursive(getter, options.limit).then(format);
  137. }
  138. function getTransactions(address, options = {}) {
  139. common_1.validate.getTransactions({ address, options });
  140. address = common_1.ensureClassicAddress(address);
  141. const defaults = { maxLedgerVersion: -1 };
  142. if (options.start) {
  143. return transaction_2.default.call(this, options.start).then((tx) => {
  144. const ledgerVersion = tx.outcome.ledgerVersion;
  145. const bound = options.earliestFirst
  146. ? { minLedgerVersion: ledgerVersion }
  147. : { maxLedgerVersion: ledgerVersion };
  148. const startOptions = Object.assign({}, defaults, options, { startTx: tx }, bound);
  149. return getTransactionsInternal(this.connection, address, startOptions);
  150. });
  151. }
  152. const newOptions = Object.assign({}, defaults, options);
  153. return getTransactionsInternal(this.connection, address, newOptions);
  154. }
  155. exports.default = getTransactions;
  156. //# sourceMappingURL=transactions.js.map