@leocuvee/turtlecoin-utils 0.0.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (132) hide show
  1. package/.github/workflows/ci.yml +27 -0
  2. package/.idea/codeStyles/codeStyleConfig.xml +5 -0
  3. package/.idea/inspectionProfiles/Project_Default.xml +7 -0
  4. package/.idea/misc.xml +6 -0
  5. package/.idea/modules.xml +8 -0
  6. package/.idea/turtlecoin-utils.iml +12 -0
  7. package/.idea/vcs.xml +6 -0
  8. package/.travis.yml +11 -0
  9. package/CONTRIBUTING.md +3 -0
  10. package/LICENSE +674 -0
  11. package/README.md +203 -0
  12. package/config.json +7 -0
  13. package/docs/.nojekyll +0 -0
  14. package/docs/CNAME +1 -0
  15. package/docs/assets/css/main.css +2321 -0
  16. package/docs/assets/images/icons.png +0 -0
  17. package/docs/assets/images/icons@2x.png +0 -0
  18. package/docs/assets/images/widgets.png +0 -0
  19. package/docs/assets/images/widgets@2x.png +0 -0
  20. package/docs/assets/js/main.js +1 -0
  21. package/docs/assets/js/search.js +3 -0
  22. package/docs/classes/address.html +964 -0
  23. package/docs/classes/addressprefix.html +431 -0
  24. package/docs/classes/block.html +965 -0
  25. package/docs/classes/blocktemplate.html +695 -0
  26. package/docs/classes/cryptonote.html +1137 -0
  27. package/docs/classes/ed25519.keypair.html +400 -0
  28. package/docs/classes/ed25519.keys.html +373 -0
  29. package/docs/classes/extranoncetag.extranoncedata.html +454 -0
  30. package/docs/classes/extranoncetag.extranoncepaymentid.html +453 -0
  31. package/docs/classes/extranoncetag.iextranonce.html +347 -0
  32. package/docs/classes/extratag.extramergedmining.html +494 -0
  33. package/docs/classes/extratag.extranonce.html +530 -0
  34. package/docs/classes/extratag.extrapadding.html +456 -0
  35. package/docs/classes/extratag.extrapublickey.html +460 -0
  36. package/docs/classes/extratag.iextratag.html +355 -0
  37. package/docs/classes/levinpacket.html +674 -0
  38. package/docs/classes/levinpayloads.handshake.html +731 -0
  39. package/docs/classes/levinpayloads.ilevinpayload.html +318 -0
  40. package/docs/classes/levinpayloads.liteblock.html +494 -0
  41. package/docs/classes/levinpayloads.missingtransactions.html +494 -0
  42. package/docs/classes/levinpayloads.newblock.html +540 -0
  43. package/docs/classes/levinpayloads.newtransactions.html +402 -0
  44. package/docs/classes/levinpayloads.peerentry.html +610 -0
  45. package/docs/classes/levinpayloads.ping.html +450 -0
  46. package/docs/classes/levinpayloads.rawblock.html +344 -0
  47. package/docs/classes/levinpayloads.requestchain.html +402 -0
  48. package/docs/classes/levinpayloads.requestgetobjects.html +448 -0
  49. package/docs/classes/levinpayloads.requesttxpool.html +402 -0
  50. package/docs/classes/levinpayloads.responsechain.html +494 -0
  51. package/docs/classes/levinpayloads.responsegetobjects.html +540 -0
  52. package/docs/classes/levinpayloads.timedsync.html +540 -0
  53. package/docs/classes/multisig.html +930 -0
  54. package/docs/classes/multisigmessage.html +694 -0
  55. package/docs/classes/parentblock.html +347 -0
  56. package/docs/classes/transaction.html +925 -0
  57. package/docs/classes/transactioninputs.coinbaseinput.html +390 -0
  58. package/docs/classes/transactioninputs.itransactioninput.html +321 -0
  59. package/docs/classes/transactioninputs.keyinput.html +459 -0
  60. package/docs/classes/transactionoutputs.itransactionoutput.html +317 -0
  61. package/docs/classes/transactionoutputs.keyoutput.html +422 -0
  62. package/docs/enums/extranoncetag.noncetagtype.html +246 -0
  63. package/docs/enums/extratag.extratagtype.html +280 -0
  64. package/docs/enums/levinprotocol.commandtype.html +391 -0
  65. package/docs/enums/transactioninputs.inputtype.html +246 -0
  66. package/docs/enums/transactionoutputs.outputtype.html +229 -0
  67. package/docs/globals.html +238 -0
  68. package/docs/index.html +271 -0
  69. package/docs/interfaces/interfaces.config.html +590 -0
  70. package/docs/interfaces/interfaces.daemonblocktemplateresponse.html +323 -0
  71. package/docs/interfaces/interfaces.generatedinput.html +304 -0
  72. package/docs/interfaces/interfaces.generatedoutput.html +285 -0
  73. package/docs/interfaces/interfaces.inputkeys.html +304 -0
  74. package/docs/interfaces/interfaces.ipreparedtransaction.html +268 -0
  75. package/docs/interfaces/interfaces.output.html +399 -0
  76. package/docs/interfaces/interfaces.preparedringsignature.html +377 -0
  77. package/docs/interfaces/interfaces.preparedtransaction.html +329 -0
  78. package/docs/interfaces/interfaces.randomoutput.html +285 -0
  79. package/docs/interfaces/interfaces.transactionrecipient.html +285 -0
  80. package/docs/interfaces/multisiginterfaces.partialkeyimage.html +277 -0
  81. package/docs/interfaces/multisiginterfaces.partialsigningkey.html +277 -0
  82. package/docs/modules/ed25519.html +195 -0
  83. package/docs/modules/extranoncetag.html +208 -0
  84. package/docs/modules/extratag.html +216 -0
  85. package/docs/modules/interfaces.html +231 -0
  86. package/docs/modules/levinpayloads.html +247 -0
  87. package/docs/modules/levinprotocol.html +191 -0
  88. package/docs/modules/multisiginterfaces.html +195 -0
  89. package/docs/modules/transactioninputs.html +208 -0
  90. package/docs/modules/transactionoutputs.html +204 -0
  91. package/index.d.ts +417 -0
  92. package/index.js +1508 -0
  93. package/lib/base58.js +220 -0
  94. package/lib/biginteger.js +1591 -0
  95. package/lib/blocktemplate.js +408 -0
  96. package/lib/crypto.js +19698 -0
  97. package/lib/mnemonic.js +1204 -0
  98. package/lib/nacl-fast-cn.js +608 -0
  99. package/lib/ringsigs.js +24262 -0
  100. package/lib/sha3.js +477 -0
  101. package/package.json +58 -0
  102. package/src/Address.ts +433 -0
  103. package/src/AddressPrefix.ts +117 -0
  104. package/src/Block.ts +556 -0
  105. package/src/BlockTemplate.ts +289 -0
  106. package/src/Common.ts +105 -0
  107. package/src/Config.ts +66 -0
  108. package/src/CryptoNote.ts +1072 -0
  109. package/src/LevinPacket.ts +366 -0
  110. package/src/Multisig.ts +600 -0
  111. package/src/MultisigMessage.ts +374 -0
  112. package/src/ParentBlock.ts +39 -0
  113. package/src/Transaction.ts +628 -0
  114. package/src/Types/ED25519.ts +187 -0
  115. package/src/Types/IExtraNonce.ts +225 -0
  116. package/src/Types/IExtraTag.ts +507 -0
  117. package/src/Types/ITransaction.ts +230 -0
  118. package/src/Types/ITransactionInput.ts +190 -0
  119. package/src/Types/ITransactionOutput.ts +108 -0
  120. package/src/Types/LevinPayloads.ts +1576 -0
  121. package/src/Types/MultisigInterfaces.ts +65 -0
  122. package/src/Types/PortableStorage.ts +289 -0
  123. package/src/Types.ts +36 -0
  124. package/src/index.ts +36 -0
  125. package/test/template.json +6 -0
  126. package/test/test.js +1457 -0
  127. package/tests/blocktemplate.json +6 -0
  128. package/tests/tests.js +215 -0
  129. package/tsconfig.json +15 -0
  130. package/tslint.json +36 -0
  131. package/typedoc.json +10 -0
  132. package/webpack.config.js +15 -0
@@ -0,0 +1,507 @@
1
+ // Copyright (c) 2018-2020, The TurtleCoin Developers
2
+ //
3
+ // Please see the included LICENSE file for more information.
4
+
5
+ import {Reader, Writer} from 'bytestream-helper';
6
+ import {ExtraNonceTag, TurtleCoinCrypto} from '../Types';
7
+ import {Common} from '../Common';
8
+
9
+ /** @ignore */
10
+ enum SIZES {
11
+ KEY = 32,
12
+ }
13
+
14
+ export namespace ExtraTag {
15
+ /** @ignore */
16
+ import IExtraNonce = ExtraNonceTag.IExtraNonce;
17
+
18
+ /**
19
+ * Extra tag types
20
+ */
21
+ export enum ExtraTagType {
22
+ PADDING = 0,
23
+ PUBKEY,
24
+ NONCE,
25
+ MERGED_MINING,
26
+ }
27
+
28
+ /**
29
+ * Abstract interface for structured data in the transaction extra field
30
+ */
31
+ export abstract class IExtraTag {
32
+ /**
33
+ * Returns the size of the nonce field in bytes including it's tag
34
+ */
35
+ abstract get size(): number;
36
+
37
+ /**
38
+ * Returns the Extra Nonce Field tag
39
+ */
40
+ abstract get tag(): ExtraTagType;
41
+
42
+ /**
43
+ * Returns the Extra Nonce as a Buffer
44
+ * @returns the Buffer representation of the object
45
+ */
46
+ public abstract toBuffer(): Buffer;
47
+
48
+ /**
49
+ * Returns the Extra Nonce as a hexadecimal string (blob)
50
+ * @returns the hexadecimal (blob) representation of the object
51
+ */
52
+ public abstract toString(): string;
53
+ }
54
+
55
+ /**
56
+ * Represents a structured padding field used in the transaction extra field
57
+ */
58
+ export class ExtraPadding implements IExtraTag {
59
+
60
+ /**
61
+ * The tag type of the field
62
+ */
63
+ public get tag(): ExtraTagType {
64
+ return this.m_tag;
65
+ }
66
+
67
+ /**
68
+ * The size of the field in bytes including the tag
69
+ */
70
+ public get size(): number {
71
+ return this.toBuffer().length;
72
+ }
73
+
74
+ /**
75
+ * Creates a new instance of the field using a Buffer or Blob copy of
76
+ * field created through other means
77
+ * @param data the data that makes up the nonce field
78
+ * @returns the new object
79
+ */
80
+ public static from(data: Buffer | string): ExtraPadding {
81
+ const reader = new Reader(data);
82
+
83
+ if (reader.varint().toJSNumber() !== ExtraTagType.PADDING) {
84
+ throw new Error('Not a padding field');
85
+ }
86
+
87
+ return new ExtraPadding(0);
88
+ }
89
+
90
+ public m_size: number = 0;
91
+ private readonly m_tag: ExtraTagType = ExtraTagType.PADDING;
92
+
93
+ /**
94
+ * Constructs a new field of the specified size
95
+ * @param size the size of the padding field
96
+ */
97
+ constructor(size: number) {
98
+ this.m_size = size;
99
+ }
100
+
101
+ /**
102
+ * Represents the field as a Buffer
103
+ * @returns the Buffer representation of the object
104
+ */
105
+ public toBuffer(): Buffer {
106
+ const writer = new Writer();
107
+
108
+ writer.varint(this.tag);
109
+
110
+ for (let i = 0; i < this.size; i++) {
111
+ writer.varint(this.tag);
112
+ }
113
+
114
+ return writer.buffer;
115
+ }
116
+
117
+ /**
118
+ * Represents the field as a hexadecimal string (blob)
119
+ * @returns the hexadecimal (blob) representation of the object
120
+ */
121
+ public toString(): string {
122
+ return this.toBuffer().toString('hex');
123
+ }
124
+ }
125
+
126
+ /**
127
+ * Represents the transaction public key contained in the transaction extra field
128
+ */
129
+ export class ExtraPublicKey implements IExtraTag {
130
+
131
+ /**
132
+ * The tag type of the field
133
+ */
134
+ public get tag(): ExtraTagType {
135
+ return this.m_tag;
136
+ }
137
+
138
+ /**
139
+ * The public key contained in the field
140
+ */
141
+ public get publicKey(): string {
142
+ return this.m_publicKey;
143
+ }
144
+
145
+ /**
146
+ * The size of the field in bytes including the tag
147
+ */
148
+ public get size(): number {
149
+ return this.toBuffer().length;
150
+ }
151
+
152
+ /**
153
+ * Creates a new instance of the field using a Buffer or Blob copy of
154
+ * field created through other means
155
+ * @param data the data that makes up the nonce field
156
+ * @returns the new object
157
+ */
158
+ public static from(data: Buffer | string): ExtraPublicKey {
159
+ const reader = new Reader(data);
160
+
161
+ if (reader.varint().toJSNumber() !== ExtraTagType.PUBKEY) {
162
+ throw new Error('Not a public key field');
163
+ }
164
+
165
+ if (reader.unreadBytes !== SIZES.KEY) {
166
+ throw new RangeError('Not enough data available for reading');
167
+ }
168
+
169
+ const publicKey = reader.hash();
170
+
171
+ return new ExtraPublicKey(publicKey);
172
+ }
173
+
174
+ private readonly m_tag: ExtraTagType = ExtraTagType.PUBKEY;
175
+ private readonly m_publicKey: string = '';
176
+
177
+ /**
178
+ * Creates a new instance of the field using the supplied public key
179
+ * @param publicKey the public key to be stored in the field
180
+ */
181
+ constructor(publicKey: string) {
182
+ if (TurtleCoinCrypto.checkKey(publicKey)) {
183
+ this.m_publicKey = publicKey;
184
+ } else {
185
+ throw new Error('invalid publicKey supplied');
186
+ }
187
+ }
188
+
189
+ /**
190
+ * Represents the field as a Buffer
191
+ * @returns the Buffer representation of the object
192
+ */
193
+ public toBuffer(): Buffer {
194
+ const writer = new Writer();
195
+
196
+ writer.varint(this.tag);
197
+
198
+ writer.hash(this.publicKey);
199
+
200
+ return writer.buffer;
201
+ }
202
+
203
+ /**
204
+ * Represents the field as a hexadecimal string (blob)
205
+ * @returns the hexadecimal (blob) representation of the object
206
+ */
207
+ public toString(): string {
208
+ return this.toBuffer().toString('hex');
209
+ }
210
+ }
211
+
212
+ /**
213
+ * Represents merged mining information contained in the transaction extra field
214
+ */
215
+ export class ExtraMergedMining implements IExtraTag {
216
+
217
+ /**
218
+ * The tag type of the field
219
+ */
220
+ public get tag(): ExtraTagType {
221
+ return this.m_tag;
222
+ }
223
+
224
+ /**
225
+ * The size of the field in bytes including the tag
226
+ */
227
+ public get size(): number {
228
+ return this.toBuffer().length;
229
+ }
230
+
231
+ /**
232
+ * The depth of the block in the merkle root
233
+ */
234
+ public get depth(): number {
235
+ return this.m_depth;
236
+ }
237
+
238
+ /**
239
+ * The merkle root of the block merge mined
240
+ */
241
+ public get merkleRoot(): string {
242
+ return this.m_merkleRoot;
243
+ }
244
+
245
+ /**
246
+ * Creates a new instance of the field using a Buffer or Blob copy of
247
+ * field created through other means
248
+ * @param data the data that makes up the nonce field
249
+ * @returns the new object
250
+ */
251
+ public static from(data: Buffer | string): ExtraMergedMining {
252
+ const reader = new Reader(data);
253
+
254
+ if (reader.varint().toJSNumber() !== ExtraTagType.MERGED_MINING) {
255
+ throw new Error('Not a merged mining field');
256
+ }
257
+
258
+ try {
259
+ reader.varint(true);
260
+ } catch {
261
+ throw new Error('Cannot read required tag data');
262
+ }
263
+
264
+ const length = reader.varint().toJSNumber();
265
+
266
+ if (reader.unreadBytes !== length) {
267
+ throw new RangeError('Not enough data available for reading');
268
+ }
269
+
270
+ try {
271
+ reader.varint(true);
272
+ } catch {
273
+ throw new Error('Cannot read required tag data');
274
+ }
275
+
276
+ const depth = reader.varint().toJSNumber();
277
+
278
+ if (reader.unreadBytes < SIZES.KEY) {
279
+ throw new RangeError('Cannot read required tag data');
280
+ }
281
+
282
+ const merkleRoot = reader.hash();
283
+
284
+ return new ExtraMergedMining(depth, merkleRoot);
285
+ }
286
+
287
+ private readonly m_tag: ExtraTagType = ExtraTagType.MERGED_MINING;
288
+ private readonly m_depth: number = 0;
289
+ private readonly m_merkleRoot: string = '';
290
+
291
+ /**
292
+ * Creates a new instance of the field using the supplied values
293
+ * @param depth The depth of the block in the merkle root
294
+ * @param merkleRoot The merkle root of the block merge mined
295
+ */
296
+ constructor(depth: number, merkleRoot: string) {
297
+ this.m_depth = depth;
298
+
299
+ if (!Common.isHex64(merkleRoot)) {
300
+ throw new Error('merkleRoot must be 64 hexadecimal characters');
301
+ }
302
+
303
+ this.m_merkleRoot = merkleRoot;
304
+ }
305
+
306
+ /**
307
+ * Represents the field as a Buffer
308
+ * @returns the Buffer representation of the object
309
+ */
310
+ public toBuffer(): Buffer {
311
+ const writer = new Writer();
312
+
313
+ writer.varint(this.tag);
314
+
315
+ const subWriter = new Writer();
316
+
317
+ subWriter.varint(this.depth);
318
+
319
+ subWriter.hash(this.merkleRoot);
320
+
321
+ writer.varint(subWriter.length);
322
+
323
+ writer.write(subWriter.buffer);
324
+
325
+ return writer.buffer;
326
+ }
327
+
328
+ /**
329
+ * Represents the field as a hexadecimal string (blob)
330
+ * @returns the hexadecimal (blob) representation of the object
331
+ */
332
+ public toString(): string {
333
+ return this.toBuffer().toString('hex');
334
+ }
335
+ }
336
+
337
+ /**
338
+ * Represents nonce information contained in the transaction extra field
339
+ */
340
+ export class ExtraNonce implements IExtraTag {
341
+
342
+ /**
343
+ * The tag type of the field
344
+ */
345
+ public get tag(): ExtraTagType {
346
+ return this.m_tag;
347
+ }
348
+
349
+ /**
350
+ * The size of the field in bytes including the tag
351
+ */
352
+ public get size(): number {
353
+ return this.toBuffer().length;
354
+ }
355
+
356
+ /**
357
+ * The Extra Nonce fields contained in the field
358
+ */
359
+ public get tags(): IExtraNonce[] {
360
+ return this.m_tags;
361
+ }
362
+
363
+ /**
364
+ * Creates a new instance of the field using a Buffer or Blob copy of
365
+ * field created through other means
366
+ * @param data the data that makes up the nonce field
367
+ * @returns the new object
368
+ */
369
+ public static from(data: Buffer | string): ExtraNonce {
370
+ const reader = new Reader(data);
371
+ const seen = {
372
+ paymentId: false,
373
+ data: false,
374
+ };
375
+
376
+ if (reader.varint().toJSNumber() !== ExtraTagType.NONCE) {
377
+ throw new Error('Not a nonce field');
378
+ }
379
+
380
+ try {
381
+ reader.varint(true);
382
+ } catch {
383
+ throw new Error('Cannot read required field data');
384
+ }
385
+
386
+ const length = reader.varint().toJSNumber();
387
+
388
+ if (reader.unreadBytes !== length) {
389
+ throw new RangeError('Not enough data available for reading');
390
+ }
391
+
392
+ const tags: ExtraNonceTag.IExtraNonce[] = [];
393
+
394
+ while (reader.unreadBytes > 0) {
395
+ let tag: number = 0;
396
+
397
+ try {
398
+ tag = reader.varint(true).toJSNumber();
399
+ } catch {
400
+ reader.skip();
401
+ continue;
402
+ }
403
+
404
+ let totalLength = Common.varintLength(tag);
405
+
406
+ switch (tag) {
407
+ case ExtraNonceTag.NonceTagType.PAYMENT_ID:
408
+ totalLength += SIZES.KEY;
409
+ if (!seen.paymentId && reader.unreadBytes >= totalLength) {
410
+ tags.push(ExtraNonceTag.ExtraNoncePaymentId.from(reader.bytes(33)));
411
+ seen.paymentId = true;
412
+ } else {
413
+ reader.skip();
414
+ }
415
+ break;
416
+ case ExtraNonceTag.NonceTagType.EXTRA_DATA:
417
+ if (!seen.data && reader.unreadBytes >= 1) {
418
+ let dataLength = 0;
419
+
420
+ try {
421
+ dataLength = reader.varint(true).toJSNumber();
422
+ } catch {
423
+ reader.skip();
424
+ continue;
425
+ }
426
+
427
+ totalLength += Common.varintLength(dataLength) + dataLength;
428
+
429
+ if (reader.unreadBytes >= totalLength) {
430
+ tags.push(ExtraNonceTag.ExtraNonceData.from(reader.bytes(totalLength)));
431
+ seen.data = true;
432
+ }
433
+ } else {
434
+ reader.skip();
435
+ }
436
+ break;
437
+ default:
438
+ reader.skip();
439
+ break;
440
+ }
441
+ }
442
+
443
+ return new ExtraNonce(tags);
444
+ }
445
+
446
+ protected m_tags: ExtraNonceTag.IExtraNonce[] = [];
447
+ private readonly m_tag: ExtraTagType = ExtraTagType.NONCE;
448
+
449
+ /**
450
+ * Creates a new instance of the field using the supplied Extra Nonce fields
451
+ * @param tags The Extra Nonce fields to place into the field
452
+ */
453
+ constructor(tags: ExtraNonceTag.IExtraNonce[]) {
454
+ this.m_tags = tags;
455
+ }
456
+
457
+ /**
458
+ * Remove a specific Extra Nonce field from the field
459
+ * @param removeTag the Extra Nonce tag type to remove
460
+ */
461
+ public removeTag(removeTag: ExtraNonceTag.NonceTagType) {
462
+ const result: ExtraNonceTag.IExtraNonce[] = [];
463
+
464
+ for (const tag of this.m_tags) {
465
+ if (tag.tag !== removeTag) {
466
+ result.push(tag);
467
+ }
468
+ }
469
+
470
+ result.sort((a, b) => (a.tag > b.tag) ? 1 : -1);
471
+
472
+ this.m_tags = result;
473
+ }
474
+
475
+ /**
476
+ * Add/Update a specific Extra Nonce field to the field
477
+ * @param tag the Extra Nonce tag to add/update
478
+ */
479
+ public addTag(tag: ExtraNonceTag.IExtraNonce) {
480
+ this.removeTag(tag.tag);
481
+
482
+ this.tags.push(tag);
483
+
484
+ this.m_tags.sort((a, b) => (a.tag > b.tag) ? 1 : -1);
485
+ }
486
+
487
+ /**
488
+ * Represents the field as a Buffer
489
+ * @returns the Buffer representation of the object
490
+ */
491
+ public toBuffer(): Buffer {
492
+ const writer = new Writer();
493
+
494
+ writer.varint(this.tag);
495
+
496
+ return writer.buffer;
497
+ }
498
+
499
+ /**
500
+ * Represents the field as a hexadecimal string (blob)
501
+ * @returns the hexadecimal (blob) representation of the object
502
+ */
503
+ public toString(): string {
504
+ return this.toBuffer().toString('hex');
505
+ }
506
+ }
507
+ }