@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,408 @@
1
+ // Copyright (c) 2018-2019, The TurtleCoin Developers
2
+ //
3
+ // Please see the included LICENSE file for more information.
4
+
5
+ 'use strict'
6
+
7
+ const varint = require('varint')
8
+ const assert = require('assert')
9
+
10
+ const Self = function (daemonResponse, mergedMiningBlockVersion) {
11
+ if (!(this instanceof Self)) return new Self(daemonResponse, mergedMiningBlockVersion)
12
+ this.mmBlockVersion = mergedMiningBlockVersion || 2
13
+ this.difficulty = daemonResponse.difficulty
14
+ this.height = daemonResponse.height
15
+ this.reservedOffset = daemonResponse.reservedOffset || daemonResponse.reserved_offset
16
+ this.blockTemplate = daemonResponse.blocktemplate || daemonResponse.blocktemplate_blob
17
+ this.block = blockFromBlob(Buffer.from(this.blockTemplate, 'hex'), this.mmBlockVersion)
18
+
19
+ Object.defineProperty(this, 'blob', {
20
+ get: function (blob) {
21
+ return blockToBlob(this.block, this.mmBlockVersion)
22
+ }
23
+ })
24
+ }
25
+
26
+ /* This interface allows for easier building of a Buffer (blob)
27
+ without manually doing repetitive code entry */
28
+ const Writer = function () {
29
+ if (!(this instanceof Writer)) return new Writer()
30
+ this.blobs = []
31
+ Object.defineProperty(this, 'blob', {
32
+ get: function blob () {
33
+ return Buffer.concat(this.blobs).toString('hex')
34
+ }
35
+ })
36
+ Object.defineProperty(this, 'buffer', {
37
+ get: function buffer () {
38
+ return Buffer.concat(this.blobs)
39
+ }
40
+ })
41
+ Object.defineProperty(this, 'length', {
42
+ get: function length () {
43
+ return Buffer.concat(this.blobs).length
44
+ }
45
+ })
46
+ }
47
+
48
+ Writer.prototype.writeVarint = function (value) {
49
+ this.blobs.push(Buffer.from(varint.encode(value)))
50
+ }
51
+
52
+ Writer.prototype.writeBytes = function (bytes) {
53
+ this.blobs.push(bytes)
54
+ }
55
+
56
+ Writer.prototype.writeHex = function (hex) {
57
+ this.blobs.push(Buffer.from(hex, 'hex'))
58
+ }
59
+
60
+ Writer.prototype.writeHash = function (hash) {
61
+ this.writeHex(hash)
62
+ }
63
+
64
+ Writer.prototype.writeUInt32 = function (value) {
65
+ const buf = Buffer.alloc(4)
66
+ buf.writeUInt32BE(value)
67
+ this.blobs.push(buf)
68
+ }
69
+
70
+ /* This interface allows for easier reading of a Buffer (blob)
71
+ without manually keeping track of where we are at in the Buffer */
72
+ const Reader = function (blob) {
73
+ if (!(this instanceof Reader)) return new Reader(blob)
74
+ this.blob = blob
75
+ this.currentOffset = 0
76
+ }
77
+
78
+ /* Reads the next varint encoded value from the Buffer */
79
+ Reader.prototype.nextVarint = function () {
80
+ const start = this.currentOffset
81
+ do {
82
+ /* Check to see if the MSB not set and if it's not
83
+ then we have reached the end of our varint */
84
+ if (this.blob.readUInt8(this.currentOffset) < 128) {
85
+ this.currentOffset++
86
+ return varint.decode(this.blob.slice(start, this.currentOffset))
87
+ }
88
+ this.currentOffset++
89
+ } while (true)
90
+ }
91
+
92
+ /* Reads the next hash value from the buffer */
93
+ Reader.prototype.nextHash = function () {
94
+ const start = this.currentOffset
95
+ this.currentOffset += 32
96
+ return this.blob.slice(start, this.currentOffset).toString('hex')
97
+ }
98
+
99
+ /* Reads the next uint32 from the buffer */
100
+ Reader.prototype.nextUInt32 = function () {
101
+ const start = this.currentOffset
102
+ this.currentOffset += 4
103
+ return this.blob.readUInt32BE(start)
104
+ }
105
+
106
+ /* Reads the next byte(s) from the Buffer and returns a Buffer */
107
+ Reader.prototype.nextBytes = function (count) {
108
+ count = count || 1
109
+ const start = this.currentOffset
110
+ this.currentOffset += count
111
+ return this.blob.slice(start, this.currentOffset)
112
+ }
113
+
114
+ /* Skips the specified number of bytes in the Buffer */
115
+ Reader.prototype.skip = function (count) {
116
+ count = count || 1
117
+ this.currentOffset += count
118
+ }
119
+
120
+ /* Helper function that parses a Buffer into a CryptoNote BlockTemplate */
121
+ function blockFromBlob (blob, mmBlockVersion) {
122
+ /* Initiate a new Reader */
123
+ const reader = new Reader(blob)
124
+
125
+ /* Set up our base object for return */
126
+ const BlockTemplate = {}
127
+
128
+ /* Get the major & minor block versions */
129
+ BlockTemplate.majorVersion = reader.nextVarint()
130
+ BlockTemplate.minorVersion = reader.nextVarint()
131
+
132
+ /* If we activated Merged Mining, the next few values in the
133
+ blob are related to the Parent Block */
134
+ if (BlockTemplate.majorVersion >= mmBlockVersion) {
135
+ BlockTemplate.previousBlockHash = reader.nextHash()
136
+ BlockTemplate.parentBlock = {
137
+ majorVersion: reader.nextVarint(),
138
+ minorVersion: reader.nextVarint()
139
+ }
140
+ }
141
+
142
+ /* Get the block timestamp */
143
+ BlockTemplate.timestamp = reader.nextVarint()
144
+
145
+ /* If we activated Merged Mining, the next hash in the blob
146
+ is that of the parentBlock previous hash; otherwise, its
147
+ the previous block hash for the block */
148
+ if (BlockTemplate.majorVersion >= mmBlockVersion) {
149
+ BlockTemplate.parentBlock.previousBlockHash = reader.nextHash()
150
+ } else {
151
+ BlockTemplate.previousBlockHash = reader.nextHash()
152
+ }
153
+
154
+ /* Get the block nonce */
155
+ BlockTemplate.nonce = reader.nextUInt32()
156
+
157
+ /* If we activated Merged Mining, the next few values in the
158
+ blob are the rest of the parentBlock */
159
+ if (BlockTemplate.majorVersion >= mmBlockVersion) {
160
+ BlockTemplate.parentBlock.transactionCount = reader.nextVarint()
161
+ BlockTemplate.parentBlock.version = reader.nextVarint()
162
+ BlockTemplate.parentBlock.unlockTime = reader.nextVarint()
163
+
164
+ /* The daemon doesn't usually return any data here other
165
+ than to say that these arrays are empty with 0 lengths
166
+ so we'll skip the next two bytes in the Buffer and
167
+ initialize the arrays */
168
+ reader.skip(2)
169
+ BlockTemplate.parentBlock.inputs = []
170
+ BlockTemplate.parentBlock.outputs = []
171
+
172
+ /* Get the parent block base transaction extra field size */
173
+ const extraSize = reader.nextVarint()
174
+
175
+ /* Read the extra blob out so we can handle it on its own */
176
+ const extraBlob = reader.nextBytes(extraSize)
177
+
178
+ /* Parse the extra blob and stuff it in the parent block */
179
+ BlockTemplate.parentBlock.extra = extraFromBlob(extraBlob)
180
+ }
181
+
182
+ /* Set up the base transaction for the block including
183
+ grabbing the transaction version and unlockTime */
184
+ BlockTemplate.baseTransaction = {
185
+ version: reader.nextVarint(),
186
+ unlockTime: reader.nextVarint(),
187
+ inputs: [],
188
+ outputs: []
189
+ }
190
+
191
+ /* Get how many inputs there are in the base transaction */
192
+ const inputCount = reader.nextVarint()
193
+
194
+ /* There should only ever be a single input for a base transaction */
195
+ assert(inputCount === 1)
196
+
197
+ /* Even though we only have one input, we'll build out the base
198
+ transaction inputs array */
199
+ for (var i = 0; i < inputCount; i++) {
200
+ BlockTemplate.baseTransaction.inputs.push({
201
+ type: reader.nextBytes().toString('hex'),
202
+ blockIndex: reader.nextVarint()
203
+ })
204
+ }
205
+
206
+ /* Get how many outputs there are in the base transaction */
207
+ const outputCount = reader.nextVarint()
208
+
209
+ /* Loop through the outputs and build those out into the
210
+ base transaction outputs array */
211
+ for (var j = 0; j < outputCount; j++) {
212
+ BlockTemplate.baseTransaction.outputs.push({
213
+ amount: reader.nextVarint(),
214
+ type: reader.nextBytes().toString('hex'),
215
+ key: reader.nextHash()
216
+ })
217
+ }
218
+
219
+ /* Get the base transaction extra length */
220
+ const extraLength = reader.nextVarint()
221
+
222
+ /* Read the extra blob out so we can handle it on its own */
223
+ const extra = reader.nextBytes(extraLength)
224
+
225
+ /* Parse the extra blob and stuff it in the parent block */
226
+ BlockTemplate.baseTransaction.extra = extraFromBlob(extra)
227
+
228
+ /* Get the number of transactions included in the block */
229
+ const transactionCount = reader.nextVarint()
230
+
231
+ /* Set up our transactions array */
232
+ BlockTemplate.transactions = []
233
+
234
+ /* Loop through the Buffer and read in the transaction hashes */
235
+ for (var k = 0; k < transactionCount; k++) {
236
+ BlockTemplate.transactions.push(reader.nextHash())
237
+ }
238
+
239
+ /* That's it, return the resulting object */
240
+ return BlockTemplate
241
+ }
242
+
243
+ function blockToBlob (block, mmBlockVersion) {
244
+ /* Set up a new writer */
245
+ const writer = new Writer()
246
+
247
+ /* Write out the major & minor block versions */
248
+ writer.writeVarint(block.majorVersion)
249
+ writer.writeVarint(block.minorVersion)
250
+
251
+ /* If the block version supports MM, write out a few values */
252
+ if (block.majorVersion >= mmBlockVersion) {
253
+ writer.writeHash(block.previousBlockHash)
254
+ writer.writeVarint(block.parentBlock.majorVersion)
255
+ writer.writeVarint(block.parentBlock.minorVersion)
256
+ }
257
+
258
+ /* Write out the block timestamp */
259
+ writer.writeVarint(block.timestamp)
260
+
261
+ /* If the block version supports MM, write out the parent block
262
+ previous hash otherwise print the block hash */
263
+ if (block.majorVersion >= mmBlockVersion) {
264
+ writer.writeHash(block.parentBlock.previousBlockHash)
265
+ } else {
266
+ writer.writeHash(block.previousBlockHash)
267
+ }
268
+
269
+ /* Write out the block nonce */
270
+ writer.writeUInt32(block.nonce)
271
+
272
+ /* If the block version supports MM, write out the rest
273
+ of the parent block values */
274
+ if (block.majorVersion >= mmBlockVersion) {
275
+ writer.writeVarint(block.parentBlock.transactionCount)
276
+ writer.writeVarint(block.parentBlock.versions)
277
+ writer.writeVarint(block.parentBlock.unlockTime)
278
+
279
+ writer.writeVarint(block.parentBlock.inputs.length)
280
+ writer.writeVarint(block.parentBlock.outputs.length)
281
+ writer.writeHex(extraToBlob(block.parentBlock.extra))
282
+ }
283
+
284
+ /* Write out the information for the base transaction */
285
+ writer.writeVarint(block.baseTransaction.version)
286
+ writer.writeVarint(block.baseTransaction.unlockTime)
287
+
288
+ /* Loop through the base transaction inputs */
289
+ writer.writeVarint(block.baseTransaction.inputs.length)
290
+ block.baseTransaction.inputs.forEach((input) => {
291
+ writer.writeHex(input.type)
292
+ writer.writeVarint(input.blockIndex)
293
+ })
294
+
295
+ /* Loop through the base transaction outputs */
296
+ writer.writeVarint(block.baseTransaction.outputs.length)
297
+ block.baseTransaction.outputs.forEach((output) => {
298
+ writer.writeVarint(output.amount)
299
+ writer.writeHex(output.type)
300
+ writer.writeHash(output.key)
301
+ })
302
+
303
+ /* Write out the base transaction extra information */
304
+ writer.writeHex(extraToBlob(block.baseTransaction.extra))
305
+
306
+ /* Write out the transaction hashes that are included in
307
+ this block template */
308
+ writer.writeVarint(block.transactions.length)
309
+ block.transactions.forEach((txn) => {
310
+ writer.writeHash(txn)
311
+ })
312
+
313
+ return writer.blob
314
+ }
315
+
316
+ function extraFromBlob (blob) {
317
+ /* We were passed a Buffer and we're going to set up
318
+ a new reader for it to make life easier */
319
+ const reader = new Reader(blob)
320
+
321
+ /* Set up our result for returning what we find */
322
+ const result = []
323
+
324
+ /* We're going to shadow this later */
325
+ var length
326
+
327
+ /* While there's still data to read, we need to loop
328
+ through it until we're done */
329
+ while (reader.currentOffset < blob.length) {
330
+ /* Get the TX extra tag */
331
+ const tag = reader.nextVarint()
332
+
333
+ switch (tag) {
334
+ case 1: // Transaction Public Key
335
+ result.push({
336
+ tag: tag,
337
+ publicKey: reader.nextHash()
338
+ })
339
+ break
340
+ case 2: // Extra Nonce
341
+ length = reader.nextVarint()
342
+ result.push({
343
+ tag: tag,
344
+ nonce: reader.nextBytes(length).toString('hex')
345
+ })
346
+ break
347
+ case 3: // Merged Mining Tag
348
+ length = reader.nextVarint()
349
+ result.push({
350
+ tag: tag,
351
+ depth: reader.nextVarint(),
352
+ merkleRoot: reader.nextHash()
353
+ })
354
+ break
355
+ }
356
+ }
357
+
358
+ /* We have what we need so we'll kick it back */
359
+ return result
360
+ }
361
+
362
+ function extraToBlob (extras) {
363
+ /* Define our writer helper */
364
+ const writer = new Writer()
365
+
366
+ /* Loop through the extra fields */
367
+ extras.forEach((extra) => {
368
+ /* Write out the tag */
369
+ writer.writeVarint(extra.tag)
370
+ var data
371
+
372
+ /* Figure out which tag we're working with */
373
+ switch (extra.tag) {
374
+ case 1:
375
+ /* Write the transaction public key to the buffer */
376
+ writer.writeHash(extra.publicKey)
377
+ break
378
+ case 2:
379
+ /* Set up a new writer to write our nonce to */
380
+ data = new Writer()
381
+ data.writeHex(extra.nonce)
382
+ /* Write out the length of our nonce and finally the nonce */
383
+ writer.writeVarint(data.length)
384
+ writer.writeHex(data.blob)
385
+ break
386
+ case 3:
387
+ /* Set up a new writer to write the MM tag info */
388
+ data = new Writer()
389
+ data.writeVarint(extra.depth)
390
+ data.writeHash(extra.merkleRoot)
391
+ /* Write out the length of the information and finally the data */
392
+ writer.writeVarint(data.length)
393
+ writer.writeHex(data.blob)
394
+ break
395
+ }
396
+ })
397
+
398
+ /* Set up a new writer to write the total Buffer including
399
+ the length of the extra information as a prefix */
400
+ const resultWriter = new Writer()
401
+ resultWriter.writeVarint(writer.length)
402
+ resultWriter.writeHex(writer.blob)
403
+
404
+ /* Spit back the raw Buffer */
405
+ return resultWriter.buffer
406
+ }
407
+
408
+ module.exports = Self