index.js 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. exports.isValidXAddress = exports.decodeXAddress = exports.xAddressToClassicAddress = exports.encodeXAddress = exports.classicAddressToXAddress = exports.isValidClassicAddress = exports.decodeAccountPublic = exports.encodeAccountPublic = exports.decodeNodePublic = exports.encodeNodePublic = exports.decodeAccountID = exports.encodeAccountID = exports.decodeSeed = exports.encodeSeed = exports.codec = void 0;
  4. const assert = require("assert");
  5. const xrp_codec_1 = require("./xrp-codec");
  6. Object.defineProperty(exports, "codec", { enumerable: true, get: function () { return xrp_codec_1.codec; } });
  7. Object.defineProperty(exports, "encodeSeed", { enumerable: true, get: function () { return xrp_codec_1.encodeSeed; } });
  8. Object.defineProperty(exports, "decodeSeed", { enumerable: true, get: function () { return xrp_codec_1.decodeSeed; } });
  9. Object.defineProperty(exports, "encodeAccountID", { enumerable: true, get: function () { return xrp_codec_1.encodeAccountID; } });
  10. Object.defineProperty(exports, "decodeAccountID", { enumerable: true, get: function () { return xrp_codec_1.decodeAccountID; } });
  11. Object.defineProperty(exports, "encodeNodePublic", { enumerable: true, get: function () { return xrp_codec_1.encodeNodePublic; } });
  12. Object.defineProperty(exports, "decodeNodePublic", { enumerable: true, get: function () { return xrp_codec_1.decodeNodePublic; } });
  13. Object.defineProperty(exports, "encodeAccountPublic", { enumerable: true, get: function () { return xrp_codec_1.encodeAccountPublic; } });
  14. Object.defineProperty(exports, "decodeAccountPublic", { enumerable: true, get: function () { return xrp_codec_1.decodeAccountPublic; } });
  15. Object.defineProperty(exports, "isValidClassicAddress", { enumerable: true, get: function () { return xrp_codec_1.isValidClassicAddress; } });
  16. const PREFIX_BYTES = {
  17. // 5, 68
  18. MAIN: Buffer.from([0x05, 0x44]),
  19. // 4, 147
  20. TEST: Buffer.from([0x04, 0x93]),
  21. };
  22. const MAX_32_BIT_UNSIGNED_INT = 4294967295;
  23. function classicAddressToXAddress(classicAddress, tag, test) {
  24. const accountId = (0, xrp_codec_1.decodeAccountID)(classicAddress);
  25. return encodeXAddress(accountId, tag, test);
  26. }
  27. exports.classicAddressToXAddress = classicAddressToXAddress;
  28. function encodeXAddress(accountId, tag, test) {
  29. if (accountId.length !== 20) {
  30. // RIPEMD160 is 160 bits = 20 bytes
  31. throw new Error('Account ID must be 20 bytes');
  32. }
  33. if (tag > MAX_32_BIT_UNSIGNED_INT) {
  34. throw new Error('Invalid tag');
  35. }
  36. const theTag = tag === false ? 0 : tag;
  37. const flag = tag === false ? 0 : 1;
  38. /* eslint-disable no-bitwise ---
  39. * need to use bitwise operations here */
  40. const bytes = Buffer.concat([
  41. test ? PREFIX_BYTES.TEST : PREFIX_BYTES.MAIN,
  42. accountId,
  43. Buffer.from([
  44. // 0x00 if no tag, 0x01 if 32-bit tag
  45. flag,
  46. // first byte
  47. theTag & 0xff,
  48. // second byte
  49. (theTag >> 8) & 0xff,
  50. // third byte
  51. (theTag >> 16) & 0xff,
  52. // fourth byte
  53. (theTag >> 24) & 0xff,
  54. 0,
  55. 0,
  56. 0,
  57. // four zero bytes (reserved for 64-bit tags)
  58. 0,
  59. ]),
  60. ]);
  61. /* eslint-enable no-bitwise */
  62. return xrp_codec_1.codec.encodeChecked(bytes);
  63. }
  64. exports.encodeXAddress = encodeXAddress;
  65. function xAddressToClassicAddress(xAddress) {
  66. const { accountId, tag, test } = decodeXAddress(xAddress);
  67. const classicAddress = (0, xrp_codec_1.encodeAccountID)(accountId);
  68. return {
  69. classicAddress,
  70. tag,
  71. test,
  72. };
  73. }
  74. exports.xAddressToClassicAddress = xAddressToClassicAddress;
  75. function decodeXAddress(xAddress) {
  76. const decoded = xrp_codec_1.codec.decodeChecked(xAddress);
  77. const test = isBufferForTestAddress(decoded);
  78. const accountId = decoded.slice(2, 22);
  79. const tag = tagFromBuffer(decoded);
  80. return {
  81. accountId,
  82. tag,
  83. test,
  84. };
  85. }
  86. exports.decodeXAddress = decodeXAddress;
  87. function isBufferForTestAddress(buf) {
  88. const decodedPrefix = buf.slice(0, 2);
  89. if (PREFIX_BYTES.MAIN.equals(decodedPrefix)) {
  90. return false;
  91. }
  92. if (PREFIX_BYTES.TEST.equals(decodedPrefix)) {
  93. return true;
  94. }
  95. throw new Error('Invalid X-address: bad prefix');
  96. }
  97. function tagFromBuffer(buf) {
  98. const flag = buf[22];
  99. if (flag >= 2) {
  100. // No support for 64-bit tags at this time
  101. throw new Error('Unsupported X-address');
  102. }
  103. if (flag === 1) {
  104. // Little-endian to big-endian
  105. return buf[23] + buf[24] * 0x100 + buf[25] * 0x10000 + buf[26] * 0x1000000;
  106. }
  107. assert.strictEqual(flag, 0, 'flag must be zero to indicate no tag');
  108. assert.ok(Buffer.from('0000000000000000', 'hex').equals(buf.slice(23, 23 + 8)), 'remaining bytes must be zero');
  109. return false;
  110. }
  111. function isValidXAddress(xAddress) {
  112. try {
  113. decodeXAddress(xAddress);
  114. }
  115. catch (_error) {
  116. return false;
  117. }
  118. return true;
  119. }
  120. exports.isValidXAddress = isValidXAddress;
  121. //# sourceMappingURL=index.js.map