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.

pathfind.js 6.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  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 bignumber_js_1 = __importDefault(require("bignumber.js"));
  27. const utils_1 = require("./utils");
  28. const common_1 = require("../common");
  29. const pathfind_1 = __importDefault(require("./parse/pathfind"));
  30. const NotFoundError = common_1.errors.NotFoundError;
  31. const ValidationError = common_1.errors.ValidationError;
  32. function addParams(request, result) {
  33. return _.defaults(Object.assign({}, result, {
  34. source_account: request.source_account,
  35. source_currencies: request.source_currencies
  36. }), { destination_amount: request.destination_amount });
  37. }
  38. function requestPathFind(connection, pathfind) {
  39. const destinationAmount = Object.assign({
  40. value: pathfind.destination.amount.currency === 'XRP' ? common_1.dropsToXrp('-1') : '-1'
  41. }, pathfind.destination.amount);
  42. const request = {
  43. command: 'ripple_path_find',
  44. source_account: pathfind.source.address,
  45. destination_account: pathfind.destination.address,
  46. destination_amount: common_1.toRippledAmount(destinationAmount)
  47. };
  48. if (typeof request.destination_amount === 'object' &&
  49. !request.destination_amount.issuer) {
  50. request.destination_amount.issuer = request.destination_account;
  51. }
  52. if (pathfind.source.currencies && pathfind.source.currencies.length > 0) {
  53. request.source_currencies = pathfind.source.currencies.map((amount) => utils_1.renameCounterpartyToIssuer(amount));
  54. }
  55. if (pathfind.source.amount) {
  56. if (pathfind.destination.amount.value != null) {
  57. throw new ValidationError('Cannot specify both source.amount' +
  58. ' and destination.amount.value in getPaths');
  59. }
  60. request.send_max = common_1.toRippledAmount(pathfind.source.amount);
  61. if (typeof request.send_max !== 'string' && !request.send_max.issuer) {
  62. request.send_max.issuer = pathfind.source.address;
  63. }
  64. }
  65. return connection.request(request).then((paths) => addParams(request, paths));
  66. }
  67. function addDirectXrpPath(paths, xrpBalance) {
  68. const destinationAmount = paths.destination_amount;
  69. if (new bignumber_js_1.default(xrpBalance).isGreaterThanOrEqualTo(destinationAmount)) {
  70. paths.alternatives.unshift({
  71. paths_computed: [],
  72. source_amount: paths.destination_amount
  73. });
  74. }
  75. return paths;
  76. }
  77. function isRippledIOUAmount(amount) {
  78. return (typeof amount === 'object' && amount.currency && amount.currency !== 'XRP');
  79. }
  80. function conditionallyAddDirectXRPPath(connection, address, paths) {
  81. if (isRippledIOUAmount(paths.destination_amount) ||
  82. !paths.destination_currencies.includes('XRP')) {
  83. return Promise.resolve(paths);
  84. }
  85. return utils_1.getXRPBalance(connection, address, undefined).then((xrpBalance) => addDirectXrpPath(paths, xrpBalance));
  86. }
  87. function filterSourceFundsLowPaths(pathfind, paths) {
  88. if (pathfind.source.amount &&
  89. pathfind.destination.amount.value == null &&
  90. paths.alternatives) {
  91. paths.alternatives = paths.alternatives.filter((alt) => {
  92. if (!alt.source_amount) {
  93. return false;
  94. }
  95. const pathfindSourceAmountValue = new bignumber_js_1.default(pathfind.source.amount.currency === 'XRP'
  96. ? common_1.xrpToDrops(pathfind.source.amount.value)
  97. : pathfind.source.amount.value);
  98. const altSourceAmountValue = new bignumber_js_1.default(typeof alt.source_amount === 'string'
  99. ? alt.source_amount
  100. : alt.source_amount.value);
  101. return altSourceAmountValue.eq(pathfindSourceAmountValue);
  102. });
  103. }
  104. return paths;
  105. }
  106. function formatResponse(pathfind, paths) {
  107. if (paths.alternatives && paths.alternatives.length > 0) {
  108. return pathfind_1.default(paths);
  109. }
  110. if (paths.destination_currencies != null &&
  111. !paths.destination_currencies.includes(pathfind.destination.amount.currency)) {
  112. throw new NotFoundError('No paths found. ' +
  113. 'The destination_account does not accept ' +
  114. pathfind.destination.amount.currency +
  115. ', they only accept: ' +
  116. paths.destination_currencies.join(', '));
  117. }
  118. else if (paths.source_currencies && paths.source_currencies.length > 0) {
  119. throw new NotFoundError('No paths found. Please ensure' +
  120. ' that the source_account has sufficient funds to execute' +
  121. ' the payment in one of the specified source_currencies. If it does' +
  122. ' there may be insufficient liquidity in the network to execute' +
  123. ' this payment right now');
  124. }
  125. else {
  126. throw new NotFoundError('No paths found.' +
  127. ' Please ensure that the source_account has sufficient funds to' +
  128. ' execute the payment. If it does there may be insufficient liquidity' +
  129. ' in the network to execute this payment right now');
  130. }
  131. }
  132. function getPaths(pathfind) {
  133. common_1.validate.getPaths({ pathfind });
  134. const address = pathfind.source.address;
  135. return requestPathFind(this.connection, pathfind)
  136. .then((paths) => conditionallyAddDirectXRPPath(this.connection, address, paths))
  137. .then((paths) => filterSourceFundsLowPaths(pathfind, paths))
  138. .then((paths) => formatResponse(pathfind, paths));
  139. }
  140. exports.default = getPaths;
  141. //# sourceMappingURL=pathfind.js.map