1 | "use strict";
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 | const api = require("./xrp-codec");
|
4 | function toHex(bytes) {
|
5 | return Buffer.from(bytes).toString('hex').toUpperCase();
|
6 | }
|
7 | function toBytes(hex) {
|
8 | return Buffer.from(hex, 'hex');
|
9 | }
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
18 | function makeEncodeDecodeTest(encoder, decoder, base58, hex) {
|
19 | test(`can translate between ${hex} and ${base58}`, function () {
|
20 | const actual = encoder(toBytes(hex));
|
21 | expect(actual).toBe(base58);
|
22 | });
|
23 | test(`can translate between ${base58} and ${hex})`, function () {
|
24 | const buf = decoder(base58);
|
25 | expect(toHex(buf)).toBe(hex);
|
26 | });
|
27 | }
|
28 | makeEncodeDecodeTest(api.encodeAccountID, api.decodeAccountID, 'rJrRMgiRgrU6hDF4pgu5DXQdWyPbY35ErN', 'BA8E78626EE42C41B46D46C3048DF3A1C3C87072');
|
29 | makeEncodeDecodeTest(api.encodeNodePublic, api.decodeNodePublic, 'n9MXXueo837zYH36DvMc13BwHcqtfAWNJY5czWVbp7uYTj7x17TH', '0388E5BA87A000CB807240DF8C848EB0B5FFA5C8E5A521BC8E105C0F0A44217828');
|
30 | makeEncodeDecodeTest(api.encodeAccountPublic, api.decodeAccountPublic, 'aB44YfzW24VDEJQ2UuLPV2PvqcPCSoLnL7y5M1EzhdW4LnK5xMS3', '023693F15967AE357D0327974AD46FE3C127113B1110D6044FD41E723689F81CC6');
|
31 | test('can decode arbitrary seeds', function () {
|
32 | const decoded = api.decodeSeed('sEdTM1uX8pu2do5XvTnutH6HsouMaM2');
|
33 | expect(toHex(decoded.bytes)).toBe('4C3A1D213FBDFB14C7C28D609469B341');
|
34 | expect(decoded.type).toBe('ed25519');
|
35 | const decoded2 = api.decodeSeed('sn259rEFXrQrWyx3Q7XneWcwV6dfL');
|
36 | expect(toHex(decoded2.bytes)).toBe('CF2DE378FBDD7E2EE87D486DFB5A7BFF');
|
37 | expect(decoded2.type).toBe('secp256k1');
|
38 | });
|
39 | test('can pass a type as second arg to encodeSeed', function () {
|
40 | const edSeed = 'sEdTM1uX8pu2do5XvTnutH6HsouMaM2';
|
41 | const decoded = api.decodeSeed(edSeed);
|
42 | const type = 'ed25519';
|
43 | expect(toHex(decoded.bytes)).toBe('4C3A1D213FBDFB14C7C28D609469B341');
|
44 | expect(decoded.type).toBe(type);
|
45 | expect(api.encodeSeed(decoded.bytes, type)).toBe(edSeed);
|
46 | });
|
47 | test('isValidClassicAddress - secp256k1 address valid', function () {
|
48 | expect(api.isValidClassicAddress('rU6K7V3Po4snVhBBaU29sesqs2qTQJWDw1')).toBe(true);
|
49 | });
|
50 | test('isValidClassicAddress - ed25519 address valid', function () {
|
51 | expect(api.isValidClassicAddress('rLUEXYuLiQptky37CqLcm9USQpPiz5rkpD')).toBe(true);
|
52 | });
|
53 | test('isValidClassicAddress - invalid', function () {
|
54 | expect(api.isValidClassicAddress('rU6K7V3Po4snVhBBaU29sesqs2qTQJWDw2')).toBe(false);
|
55 | });
|
56 | test('isValidClassicAddress - empty', function () {
|
57 | expect(api.isValidClassicAddress('')).toBe(false);
|
58 | });
|
59 | describe('encodeSeed', function () {
|
60 | it('encodes a secp256k1 seed', function () {
|
61 | const result = api.encodeSeed(Buffer.from('CF2DE378FBDD7E2EE87D486DFB5A7BFF', 'hex'), 'secp256k1');
|
62 | expect(result).toBe('sn259rEFXrQrWyx3Q7XneWcwV6dfL');
|
63 | });
|
64 | it('encodes low secp256k1 seed', function () {
|
65 | const result = api.encodeSeed(Buffer.from('00000000000000000000000000000000', 'hex'), 'secp256k1');
|
66 | expect(result).toBe('sp6JS7f14BuwFY8Mw6bTtLKWauoUs');
|
67 | });
|
68 | it('encodes high secp256k1 seed', function () {
|
69 | const result = api.encodeSeed(Buffer.from('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF', 'hex'), 'secp256k1');
|
70 | expect(result).toBe('saGwBRReqUNKuWNLpUAq8i8NkXEPN');
|
71 | });
|
72 | it('encodes an ed25519 seed', function () {
|
73 | const result = api.encodeSeed(Buffer.from('4C3A1D213FBDFB14C7C28D609469B341', 'hex'), 'ed25519');
|
74 | expect(result).toBe('sEdTM1uX8pu2do5XvTnutH6HsouMaM2');
|
75 | });
|
76 | it('encodes low ed25519 seed', function () {
|
77 | const result = api.encodeSeed(Buffer.from('00000000000000000000000000000000', 'hex'), 'ed25519');
|
78 | expect(result).toBe('sEdSJHS4oiAdz7w2X2ni1gFiqtbJHqE');
|
79 | });
|
80 | it('encodes high ed25519 seed', function () {
|
81 | const result = api.encodeSeed(Buffer.from('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF', 'hex'), 'ed25519');
|
82 | expect(result).toBe('sEdV19BLfeQeKdEXyYA4NhjPJe6XBfG');
|
83 | });
|
84 | test('attempting to encode a seed with less than 16 bytes of entropy throws', function () {
|
85 | expect(() => {
|
86 | api.encodeSeed(Buffer.from('CF2DE378FBDD7E2EE87D486DFB5A7B', 'hex'), 'secp256k1');
|
87 | }).toThrow('entropy must have length 16');
|
88 | });
|
89 | test('attempting to encode a seed with more than 16 bytes of entropy throws', function () {
|
90 | expect(() => {
|
91 | api.encodeSeed(Buffer.from('CF2DE378FBDD7E2EE87D486DFB5A7BFFFF', 'hex'), 'secp256k1');
|
92 | }).toThrow('entropy must have length 16');
|
93 | });
|
94 | });
|
95 | describe('decodeSeed', function () {
|
96 | it('can decode an Ed25519 seed', function () {
|
97 | const decoded = api.decodeSeed('sEdTM1uX8pu2do5XvTnutH6HsouMaM2');
|
98 | expect(toHex(decoded.bytes)).toBe('4C3A1D213FBDFB14C7C28D609469B341');
|
99 | expect(decoded.type).toBe('ed25519');
|
100 | });
|
101 | it('can decode a secp256k1 seed', function () {
|
102 | const decoded = api.decodeSeed('sn259rEFXrQrWyx3Q7XneWcwV6dfL');
|
103 | expect(toHex(decoded.bytes)).toBe('CF2DE378FBDD7E2EE87D486DFB5A7BFF');
|
104 | expect(decoded.type).toBe('secp256k1');
|
105 | });
|
106 | });
|
107 | describe('encodeAccountID', function () {
|
108 | it('can encode an AccountID', function () {
|
109 | const encoded = api.encodeAccountID(Buffer.from('BA8E78626EE42C41B46D46C3048DF3A1C3C87072', 'hex'));
|
110 | expect(encoded).toBe('rJrRMgiRgrU6hDF4pgu5DXQdWyPbY35ErN');
|
111 | });
|
112 | test('unexpected length should throw', function () {
|
113 | expect(() => {
|
114 | api.encodeAccountID(Buffer.from('ABCDEF', 'hex'));
|
115 | }).toThrow('unexpected_payload_length: bytes.length does not match expectedLength');
|
116 | });
|
117 | });
|
118 | describe('decodeNodePublic', function () {
|
119 | it('can decode a NodePublic', function () {
|
120 | const decoded = api.decodeNodePublic('n9MXXueo837zYH36DvMc13BwHcqtfAWNJY5czWVbp7uYTj7x17TH');
|
121 | expect(toHex(decoded)).toBe('0388E5BA87A000CB807240DF8C848EB0B5FFA5C8E5A521BC8E105C0F0A44217828');
|
122 | });
|
123 | });
|
124 | test('encodes 123456789 with version byte of 0', () => {
|
125 | expect(api.codec.encode(Buffer.from('123456789'), {
|
126 | versions: [0],
|
127 | expectedLength: 9
|
128 | })).toBe('rnaC7gW34M77Kneb78s');
|
129 | });
|
130 | test('multiple versions with no expected length should throw', () => {
|
131 | expect(() => {
|
132 | api.codec.decode('rnaC7gW34M77Kneb78s', {
|
133 | versions: [0, 1]
|
134 | });
|
135 | }).toThrow('expectedLength is required because there are >= 2 possible versions');
|
136 | });
|
137 | test('attempting to decode data with length < 5 should throw', () => {
|
138 | expect(() => {
|
139 | api.codec.decode('1234', {
|
140 | versions: [0]
|
141 | });
|
142 | }).toThrow('invalid_input_size: decoded data must have length >= 5');
|
143 | });
|
144 | test('attempting to decode data with unexpected version should throw', () => {
|
145 | expect(() => {
|
146 | api.codec.decode('rnaC7gW34M77Kneb78s', {
|
147 | versions: [2]
|
148 | });
|
149 | }).toThrow('version_invalid: version bytes do not match any of the provided version(s)');
|
150 | });
|
151 | test('invalid checksum should throw', () => {
|
152 | expect(() => {
|
153 | api.codec.decode('123456789', {
|
154 | versions: [0, 1]
|
155 | });
|
156 | }).toThrow('checksum_invalid');
|
157 | });
|
158 | test('empty payload should throw', () => {
|
159 | expect(() => {
|
160 | api.codec.decode('', {
|
161 | versions: [0, 1]
|
162 | });
|
163 | }).toThrow('invalid_input_size: decoded data must have length >= 5');
|
164 | });
|
165 | test('decode data', () => {
|
166 | expect(api.codec.decode('rnaC7gW34M77Kneb78s', {
|
167 | versions: [0]
|
168 | })).toStrictEqual({
|
169 | version: [0],
|
170 | bytes: Buffer.from('123456789'),
|
171 | type: null
|
172 | });
|
173 | });
|
174 | test('decode data with expected length', function () {
|
175 | expect(api.codec.decode('rnaC7gW34M77Kneb78s', {
|
176 | versions: [0],
|
177 | expectedLength: 9
|
178 | })).toStrictEqual({
|
179 | version: [0],
|
180 | bytes: Buffer.from('123456789'),
|
181 | type: null
|
182 | });
|
183 | });
|
184 | test('decode data with wrong expected length should throw', function () {
|
185 | expect(() => {
|
186 | api.codec.decode('rnaC7gW34M77Kneb78s', {
|
187 | versions: [0],
|
188 | expectedLength: 8
|
189 | });
|
190 | }).toThrow('version_invalid: version bytes do not match any of the provided version(s)');
|
191 | expect(() => {
|
192 | api.codec.decode('rnaC7gW34M77Kneb78s', {
|
193 | versions: [0],
|
194 | expectedLength: 10
|
195 | });
|
196 | }).toThrow('version_invalid: version bytes do not match any of the provided version(s)');
|
197 | });
|
198 |
|
\ | No newline at end of file |