1 | "use strict";
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 | const xrp_codec_1 = require("./xrp-codec");
|
4 | exports.codec = xrp_codec_1.codec;
|
5 | exports.encodeSeed = xrp_codec_1.encodeSeed;
|
6 | exports.decodeSeed = xrp_codec_1.decodeSeed;
|
7 | exports.encodeAccountID = xrp_codec_1.encodeAccountID;
|
8 | exports.decodeAccountID = xrp_codec_1.decodeAccountID;
|
9 | exports.encodeNodePublic = xrp_codec_1.encodeNodePublic;
|
10 | exports.decodeNodePublic = xrp_codec_1.decodeNodePublic;
|
11 | exports.encodeAccountPublic = xrp_codec_1.encodeAccountPublic;
|
12 | exports.decodeAccountPublic = xrp_codec_1.decodeAccountPublic;
|
13 | exports.isValidClassicAddress = xrp_codec_1.isValidClassicAddress;
|
14 | const assert = require("assert");
|
15 | const PREFIX_BYTES = {
|
16 | MAIN: Buffer.from([0x05, 0x44]),
|
17 | TEST: Buffer.from([0x04, 0x93])
|
18 | };
|
19 | function classicAddressToXAddress(classicAddress, tag, test) {
|
20 | const accountId = xrp_codec_1.decodeAccountID(classicAddress);
|
21 | return encodeXAddress(accountId, tag, test);
|
22 | }
|
23 | exports.classicAddressToXAddress = classicAddressToXAddress;
|
24 | function encodeXAddress(accountId, tag, test) {
|
25 | if (accountId.length !== 20) {
|
26 |
|
27 | throw new Error('Account ID must be 20 bytes');
|
28 | }
|
29 | const MAX_32_BIT_UNSIGNED_INT = 4294967295;
|
30 | const flag = tag === false ? 0 : tag <= MAX_32_BIT_UNSIGNED_INT ? 1 : 2;
|
31 | if (flag === 2) {
|
32 | throw new Error('Invalid tag');
|
33 | }
|
34 | if (tag === false) {
|
35 | tag = 0;
|
36 | }
|
37 | const bytes = Buffer.concat([
|
38 | test ? PREFIX_BYTES.TEST : PREFIX_BYTES.MAIN,
|
39 | accountId,
|
40 | Buffer.from([
|
41 | flag,
|
42 | tag & 0xff,
|
43 | (tag >> 8) & 0xff,
|
44 | (tag >> 16) & 0xff,
|
45 | (tag >> 24) & 0xff,
|
46 | 0, 0, 0, 0
|
47 | ])
|
48 | ]);
|
49 | const xAddress = xrp_codec_1.codec.encodeChecked(bytes);
|
50 | return xAddress;
|
51 | }
|
52 | exports.encodeXAddress = encodeXAddress;
|
53 | function xAddressToClassicAddress(xAddress) {
|
54 | const { accountId, tag, test } = decodeXAddress(xAddress);
|
55 | const classicAddress = xrp_codec_1.encodeAccountID(accountId);
|
56 | return {
|
57 | classicAddress,
|
58 | tag,
|
59 | test
|
60 | };
|
61 | }
|
62 | exports.xAddressToClassicAddress = xAddressToClassicAddress;
|
63 | function decodeXAddress(xAddress) {
|
64 | const decoded = xrp_codec_1.codec.decodeChecked(xAddress);
|
65 | const test = isBufferForTestAddress(decoded);
|
66 | const accountId = decoded.slice(2, 22);
|
67 | const tag = tagFromBuffer(decoded);
|
68 | return {
|
69 | accountId,
|
70 | tag,
|
71 | test
|
72 | };
|
73 | }
|
74 | exports.decodeXAddress = decodeXAddress;
|
75 | function isBufferForTestAddress(buf) {
|
76 | const decodedPrefix = buf.slice(0, 2);
|
77 | if (PREFIX_BYTES.MAIN.equals(decodedPrefix)) {
|
78 | return false;
|
79 | }
|
80 | else if (PREFIX_BYTES.TEST.equals(decodedPrefix)) {
|
81 | return true;
|
82 | }
|
83 | else {
|
84 | throw new Error('Invalid X-address: bad prefix');
|
85 | }
|
86 | }
|
87 | function tagFromBuffer(buf) {
|
88 | const flag = buf[22];
|
89 | if (flag >= 2) {
|
90 |
|
91 | throw new Error('Unsupported X-address');
|
92 | }
|
93 | if (flag === 1) {
|
94 |
|
95 | return buf[23] + buf[24] * 0x100 + buf[25] * 0x10000 + buf[26] * 0x1000000;
|
96 | }
|
97 | assert.strictEqual(flag, 0, 'flag must be zero to indicate no tag');
|
98 | assert.ok(Buffer.from('0000000000000000', 'hex').equals(buf.slice(23, 23 + 8)), 'remaining bytes must be zero');
|
99 | return false;
|
100 | }
|
101 | function isValidXAddress(xAddress) {
|
102 | try {
|
103 | decodeXAddress(xAddress);
|
104 | }
|
105 | catch (e) {
|
106 | return false;
|
107 | }
|
108 | return true;
|
109 | }
|
110 | exports.isValidXAddress = isValidXAddress;
|
111 |
|
\ | No newline at end of file |