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.

fundWallet.js 7.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. "use strict";
  2. var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
  3. function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
  4. return new (P || (P = Promise))(function (resolve, reject) {
  5. function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
  6. function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
  7. function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
  8. step((generator = generator.apply(thisArg, _arguments || [])).next());
  9. });
  10. };
  11. var __importDefault = (this && this.__importDefault) || function (mod) {
  12. return (mod && mod.__esModule) ? mod : { "default": mod };
  13. };
  14. Object.defineProperty(exports, "__esModule", { value: true });
  15. const https_1 = require("https");
  16. const ripple_address_codec_1 = require("ripple-address-codec");
  17. const errors_1 = require("../errors");
  18. const defaultFaucets_1 = require("./defaultFaucets");
  19. const _1 = __importDefault(require("."));
  20. const INTERVAL_SECONDS = 1;
  21. const MAX_ATTEMPTS = 20;
  22. function fundWallet(wallet, options) {
  23. return __awaiter(this, void 0, void 0, function* () {
  24. if (!this.isConnected()) {
  25. throw new errors_1.RippledError('Client not connected, cannot call faucet');
  26. }
  27. const walletToFund = wallet && (0, ripple_address_codec_1.isValidClassicAddress)(wallet.classicAddress)
  28. ? wallet
  29. : _1.default.generate();
  30. const postBody = Buffer.from(new TextEncoder().encode(JSON.stringify({
  31. destination: walletToFund.classicAddress,
  32. xrpAmount: options === null || options === void 0 ? void 0 : options.amount,
  33. })));
  34. let startingBalance = 0;
  35. try {
  36. startingBalance = Number(yield this.getXrpBalance(walletToFund.classicAddress));
  37. }
  38. catch (_a) {
  39. }
  40. const httpOptions = getHTTPOptions(this, postBody, {
  41. hostname: options === null || options === void 0 ? void 0 : options.faucetHost,
  42. pathname: options === null || options === void 0 ? void 0 : options.faucetPath,
  43. });
  44. return returnPromise(httpOptions, this, startingBalance, walletToFund, postBody);
  45. });
  46. }
  47. function returnPromise(options, client, startingBalance, walletToFund, postBody) {
  48. return __awaiter(this, void 0, void 0, function* () {
  49. return new Promise((resolve, reject) => {
  50. const request = (0, https_1.request)(options, (response) => {
  51. const chunks = [];
  52. response.on('data', (data) => chunks.push(data));
  53. response.on('end', () => __awaiter(this, void 0, void 0, function* () {
  54. return onEnd(response, chunks, client, startingBalance, walletToFund, resolve, reject);
  55. }));
  56. });
  57. request.write(postBody);
  58. request.on('error', (error) => {
  59. reject(error);
  60. });
  61. request.end();
  62. });
  63. });
  64. }
  65. function getHTTPOptions(client, postBody, options) {
  66. var _a, _b;
  67. const finalHostname = (_a = options === null || options === void 0 ? void 0 : options.hostname) !== null && _a !== void 0 ? _a : (0, defaultFaucets_1.getFaucetHost)(client);
  68. const finalPathname = (_b = options === null || options === void 0 ? void 0 : options.pathname) !== null && _b !== void 0 ? _b : (0, defaultFaucets_1.getDefaultFaucetPath)(finalHostname);
  69. return {
  70. hostname: finalHostname,
  71. port: 443,
  72. path: finalPathname,
  73. method: 'POST',
  74. headers: {
  75. 'Content-Type': 'application/json',
  76. 'Content-Length': postBody.length,
  77. },
  78. };
  79. }
  80. function onEnd(response, chunks, client, startingBalance, walletToFund, resolve, reject) {
  81. var _a;
  82. return __awaiter(this, void 0, void 0, function* () {
  83. const body = Buffer.concat(chunks).toString();
  84. if ((_a = response.headers['content-type']) === null || _a === void 0 ? void 0 : _a.startsWith('application/json')) {
  85. const faucetWallet = JSON.parse(body);
  86. const classicAddress = faucetWallet.account.classicAddress;
  87. yield processSuccessfulResponse(client, classicAddress, walletToFund, startingBalance, resolve, reject);
  88. }
  89. else {
  90. reject(new errors_1.XRPLFaucetError(`Content type is not \`application/json\`: ${JSON.stringify({
  91. statusCode: response.statusCode,
  92. contentType: response.headers['content-type'],
  93. body,
  94. })}`));
  95. }
  96. });
  97. }
  98. function processSuccessfulResponse(client, classicAddress, walletToFund, startingBalance, resolve, reject) {
  99. return __awaiter(this, void 0, void 0, function* () {
  100. if (!classicAddress) {
  101. reject(new errors_1.XRPLFaucetError(`The faucet account is undefined`));
  102. return;
  103. }
  104. try {
  105. const updatedBalance = yield getUpdatedBalance(client, classicAddress, startingBalance);
  106. if (updatedBalance > startingBalance) {
  107. resolve({
  108. wallet: walletToFund,
  109. balance: yield getUpdatedBalance(client, walletToFund.classicAddress, startingBalance),
  110. });
  111. }
  112. else {
  113. reject(new errors_1.XRPLFaucetError(`Unable to fund address with faucet after waiting ${INTERVAL_SECONDS * MAX_ATTEMPTS} seconds`));
  114. }
  115. }
  116. catch (err) {
  117. if (err instanceof Error) {
  118. reject(new errors_1.XRPLFaucetError(err.message));
  119. }
  120. reject(err);
  121. }
  122. });
  123. }
  124. function getUpdatedBalance(client, address, originalBalance) {
  125. return __awaiter(this, void 0, void 0, function* () {
  126. return new Promise((resolve, reject) => {
  127. let attempts = MAX_ATTEMPTS;
  128. const interval = setInterval(() => __awaiter(this, void 0, void 0, function* () {
  129. if (attempts < 0) {
  130. clearInterval(interval);
  131. resolve(originalBalance);
  132. }
  133. else {
  134. attempts -= 1;
  135. }
  136. try {
  137. let newBalance;
  138. try {
  139. newBalance = Number(yield client.getXrpBalance(address));
  140. }
  141. catch (_a) {
  142. }
  143. if (newBalance > originalBalance) {
  144. clearInterval(interval);
  145. resolve(newBalance);
  146. }
  147. }
  148. catch (err) {
  149. clearInterval(interval);
  150. if (err instanceof Error) {
  151. reject(new errors_1.XRPLFaucetError(`Unable to check if the address ${address} balance has increased. Error: ${err.message}`));
  152. }
  153. reject(err);
  154. }
  155. }), INTERVAL_SECONDS * 1000);
  156. });
  157. });
  158. }
  159. exports.default = fundWallet;
  160. //# sourceMappingURL=fundWallet.js.map