@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,289 @@
1
+ // Copyright (c) 2018-2020, The TurtleCoin Developers
2
+ //
3
+ // Please see the included LICENSE file for more information.
4
+
5
+ import {Block} from './Block';
6
+ import {Transaction} from './Transaction';
7
+ import {Reader} from 'bytestream-helper';
8
+ import {BigInteger, ExtraTag} from './Types';
9
+
10
+ /** @ignore */
11
+ export enum SIZES {
12
+ KEY = 32,
13
+ CHECKSUM = 4,
14
+ }
15
+
16
+ declare namespace Interfaces {
17
+ /**
18
+ * The daemon block template response
19
+ */
20
+ interface DaemonBlockTemplateResponse {
21
+ /**
22
+ * The block template supplied by the daemon
23
+ */
24
+ blocktemplate: string;
25
+ /**
26
+ * The blocktemplate difficulty supplied by the daemon
27
+ */
28
+ difficulty: number;
29
+ /**
30
+ * The blocktemplate height supplied by the daemon
31
+ */
32
+ height: number;
33
+ /**
34
+ * The reserved offset position for the blocktemplate supplied by the daemon
35
+ */
36
+ reservedOffset: number;
37
+ }
38
+ }
39
+
40
+ /**
41
+ * Represents a BlockTemplate received from a Daemon that can be manipulated to perform mining operations
42
+ */
43
+ export class BlockTemplate {
44
+
45
+ /**
46
+ * The major block version for which to activate the use of parent blocks
47
+ */
48
+ public get activateParentBlockVersion(): number {
49
+ return this.m_block.activateParentBlockVersion;
50
+ }
51
+
52
+ public set activateParentBlockVersion(value: number) {
53
+ this.m_block.activateParentBlockVersion = value;
54
+ }
55
+
56
+ /**
57
+ * The original block template as a buffer
58
+ */
59
+ public get blockTemplateBuffer(): Buffer {
60
+ return this.m_blockTemplate;
61
+ }
62
+
63
+ /**
64
+ * The original block template in hexadecimal (blob)
65
+ */
66
+ public get blockTemplate(): string {
67
+ return this.blockTemplateBuffer.toString('hex');
68
+ }
69
+
70
+ /**
71
+ * The block template difficulty
72
+ */
73
+ public get difficulty(): number {
74
+ return this.m_difficulty;
75
+ }
76
+
77
+ /**
78
+ * The block template height
79
+ */
80
+ public get height(): number {
81
+ return this.m_height;
82
+ }
83
+
84
+ /**
85
+ * The block template reserved offset position
86
+ */
87
+ public get reservedOffset(): number {
88
+ return this.m_reservedOffset;
89
+ }
90
+
91
+ /**
92
+ * The block nonce
93
+ */
94
+ public get nonce(): number {
95
+ return this.m_block.nonce;
96
+ }
97
+
98
+ public set nonce(value: number) {
99
+ this.m_block.nonce = value;
100
+ }
101
+
102
+ /**
103
+ * The block defined in the block template
104
+ */
105
+ public get block(): Block {
106
+ return this.m_block;
107
+ }
108
+
109
+ /**
110
+ * The miner transaction defined in the block of the block template
111
+ */
112
+ public get minerTransaction(): Transaction {
113
+ return this.m_block.minerTransaction;
114
+ }
115
+
116
+ /**
117
+ * The extra miner nonce typically used for pool based mining
118
+ */
119
+ public get minerNonce(): number {
120
+ const extra = this.minerTransaction.extra;
121
+
122
+ const reader = new Reader(extra);
123
+
124
+ let offset: number = 0;
125
+
126
+ while (reader.unreadBytes > 0) {
127
+ const tag = reader.varint().toJSNumber();
128
+
129
+ switch (tag) {
130
+ case ExtraTag.ExtraTagType.PADDING:
131
+ break;
132
+ case ExtraTag.ExtraTagType.PUBKEY:
133
+ reader.skip(SIZES.KEY);
134
+ break;
135
+ case ExtraTag.ExtraTagType.MERGED_MINING:
136
+ const length = reader.varint().toJSNumber();
137
+ reader.skip(length);
138
+ break;
139
+ case ExtraTag.ExtraTagType.NONCE:
140
+ offset = reader.currentOffset;
141
+ const nonceLength = reader.varint().toJSNumber();
142
+ this.m_extraNonceOffset = reader.currentOffset;
143
+ this.m_extraNonceSafeLength = (nonceLength >= 4) ? 4 : (nonceLength >= 2) ? 2 : 1;
144
+ return reader.uint_t(this.m_extraNonceSafeLength * 8, true).toJSNumber();
145
+ }
146
+ }
147
+
148
+ return 0;
149
+ }
150
+
151
+ public set minerNonce(nonce: number) {
152
+ if (nonce > 0xFFFFFFFF) {
153
+ throw new RangeError('Cannot store values larger than uint64_t');
154
+ }
155
+
156
+ if (nonce !== this.minerNonce) {
157
+ const extra = this.minerTransaction.extra;
158
+
159
+ const bytesRequired = (nonce > 65535) ? 4 : (nonce > 255) ? 2 : 1;
160
+
161
+ if (bytesRequired > this.m_extraNonceSafeLength) {
162
+ throw new RangeError('Reserved space ');
163
+ }
164
+
165
+ switch (this.m_extraNonceSafeLength) {
166
+ case 4:
167
+ extra.writeUInt32BE(nonce, this.m_extraNonceOffset);
168
+ break;
169
+ case 2:
170
+ extra.writeUInt16BE(nonce, this.m_extraNonceOffset);
171
+ break;
172
+ case 1:
173
+ extra.writeUInt8(nonce, this.m_extraNonceOffset);
174
+ break;
175
+ default:
176
+ throw new Error('Unhandled safe nonce length');
177
+ }
178
+
179
+ this.minerTransaction.parseExtra(extra);
180
+ }
181
+ }
182
+
183
+ /**
184
+ * Whether the given hash meets the difficulty specified
185
+ * @param hash the block POW hash
186
+ * @param difficulty the target difficulty
187
+ */
188
+ public static hashMeetsDifficulty(hash: string, difficulty: number): boolean {
189
+ // @ts-ignore
190
+ const reversedHash = hash.match(/[0-9a-f]{2}/gi).reverse().join('');
191
+
192
+ const hashDiff = BigInteger(reversedHash, 16).multiply(difficulty);
193
+
194
+ const maxValue = BigInteger('ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff', 16);
195
+
196
+ return (hashDiff.compare(maxValue) === -1);
197
+ }
198
+
199
+ /**
200
+ * Creates a new block template instance using the supplied daemon response
201
+ * @param response the daemon response to the get_blocktemplate call
202
+ */
203
+ public static from(response: Interfaces.DaemonBlockTemplateResponse): BlockTemplate {
204
+ const result = new BlockTemplate();
205
+
206
+ result.m_blockTemplate = Buffer.from(response.blocktemplate, 'hex');
207
+ result.m_difficulty = response.difficulty;
208
+ result.m_reservedOffset = response.reservedOffset;
209
+ result.m_height = response.height;
210
+ result.m_block = Block.from(response.blocktemplate);
211
+
212
+ return result;
213
+ }
214
+
215
+ protected m_blockTemplate: Buffer = Buffer.alloc(0);
216
+ protected m_difficulty: number = 1;
217
+ protected m_height: number = 0;
218
+ protected m_reservedOffset: number = 0;
219
+ protected m_block: Block = new Block();
220
+ protected m_extraNonceOffset: number = 0;
221
+ protected m_extraNonceSafeLength: number = 0;
222
+
223
+ /**
224
+ * Converts a block into a v1 hashing block typically used by miners during mining operations
225
+ * this method actually creates a merged mining block that merge mines itself
226
+ * @param block the block to convert for miner hashing
227
+ * @returns the mining block
228
+ */
229
+ public convert(block?: Block): Block {
230
+ const originalBlock = block || this.m_block;
231
+
232
+ if (originalBlock.majorVersion >= this.activateParentBlockVersion) {
233
+ /* If we support merged mining, then we can reduce the size of
234
+ the block blob sent to the miners by crafting a new block
235
+ with the blocktemplate provided by the daemon into a new
236
+ block that contains the original block information as a MM
237
+ tag in the miner transaction */
238
+ const newBlock = new Block();
239
+ newBlock.majorVersion = 1;
240
+ newBlock.minorVersion = 0;
241
+ newBlock.timestamp = originalBlock.timestamp;
242
+ newBlock.previousBlockHash = originalBlock.previousBlockHash;
243
+ newBlock.nonce = originalBlock.nonce;
244
+
245
+ newBlock.minerTransaction.addMergedMining(0, originalBlock.merkleRoot);
246
+
247
+ return newBlock;
248
+ } else {
249
+ return originalBlock;
250
+ }
251
+ }
252
+
253
+ /**
254
+ * Constructs a new "final" block that can be submitted to the network using
255
+ * an original the original block in the block template and the nonce value found
256
+ * @param nonce the nonce value for the block
257
+ * @param [branch] the blockchain branch containing the merged mining information
258
+ * @returns the block that can be submitted to the network
259
+ */
260
+ public construct(nonce: number, branch?: string): Block {
261
+ const block: Block = this.m_block;
262
+
263
+ block.nonce = nonce;
264
+
265
+ if (block.majorVersion >= this.activateParentBlockVersion) {
266
+ /* First we create the new parent block */
267
+ const newBlock = this.convert(block);
268
+
269
+ /* Then assign the nonce to it */
270
+ newBlock.nonce = nonce;
271
+
272
+ /* Then we merge the two blocks together */
273
+ block.timestamp = newBlock.timestamp;
274
+ block.parentBlock.majorVersion = newBlock.majorVersion;
275
+ block.parentBlock.minorVersion = newBlock.minorVersion;
276
+ block.parentBlock.previousBlockHash = newBlock.previousBlockHash;
277
+ block.parentBlock.minerTransaction = newBlock.minerTransaction;
278
+ block.parentBlock.transactionCount = newBlock.transactions.length + 1; // +1 for the miner transaction
279
+ block.parentBlock.baseTransactionBranch = newBlock.baseTransactionBranch;
280
+
281
+ /* We only add this if it actually exists */
282
+ if (branch) {
283
+ block.parentBlock.blockchainBranch = [branch];
284
+ }
285
+ }
286
+
287
+ return block;
288
+ }
289
+ }
package/src/Common.ts ADDED
@@ -0,0 +1,105 @@
1
+ // Copyright (c) 2018-2020, The TurtleCoin Developers
2
+ //
3
+ // Please see the included LICENSE file for more information.
4
+
5
+ import {Writer} from 'bytestream-helper';
6
+ import {BigInteger} from './Types';
7
+
8
+ /** @ignore */
9
+ export class Common {
10
+ public static absoluteToRelativeOffsets(
11
+ offsets: BigInteger.BigInteger[] | number[] | string []): BigInteger.BigInteger[] {
12
+ const offsetsCopy: BigInteger.BigInteger[] = [];
13
+
14
+ for (const offset of offsets) {
15
+ if (typeof offset === 'string') {
16
+ offsetsCopy.push(BigInteger(offset));
17
+ } else if (typeof offset === 'number') {
18
+ offsetsCopy.push(BigInteger(offset));
19
+ } else {
20
+ offsetsCopy.push(offset);
21
+ }
22
+ }
23
+
24
+ if (offsetsCopy.length === 1) {
25
+ return offsetsCopy;
26
+ }
27
+
28
+ for (let i = offsetsCopy.length - 1; i >= 1; --i) {
29
+ offsetsCopy[i] = offsetsCopy[i].subtract(offsetsCopy[i - 1]);
30
+ }
31
+
32
+ return offsetsCopy;
33
+ }
34
+
35
+ public static relativeToAbsoluteOffsets(
36
+ offsets: BigInteger.BigInteger[] | number[] | string[]): BigInteger.BigInteger[] {
37
+ const offsetsCopy: BigInteger.BigInteger[] = [];
38
+
39
+ for (const offset of offsets) {
40
+ if (typeof offset === 'string') {
41
+ offsetsCopy.push(BigInteger(offset));
42
+ } else if (typeof offset === 'number') {
43
+ offsetsCopy.push(BigInteger(offset));
44
+ } else {
45
+ offsetsCopy.push(offset);
46
+ }
47
+ }
48
+
49
+ if (offsetsCopy.length === 1) {
50
+ return offsetsCopy;
51
+ }
52
+
53
+ for (let i = 1; i < offsetsCopy.length; i++) {
54
+ offsetsCopy[i] = offsetsCopy[i - 1].add(offsetsCopy[i]);
55
+ }
56
+
57
+ return offsetsCopy;
58
+ }
59
+
60
+ public static bin2hex(bin: Uint8Array): string {
61
+ const result = [];
62
+
63
+ for (const b of bin) {
64
+ result.push(('0' + b.toString(16)).slice(-2));
65
+ }
66
+
67
+ return result.join('');
68
+ }
69
+
70
+ public static isHex(value: string): boolean {
71
+ if (value.length % 2 !== 0) {
72
+ return false;
73
+ }
74
+
75
+ const regex = new RegExp('^[0-9a-fA-F]{' + value.length + '}$');
76
+
77
+ return regex.test(value);
78
+ }
79
+
80
+ public static isHex64(value: string): boolean {
81
+ return (Common.isHex(value) && value.length === 64);
82
+ }
83
+
84
+ public static isHex128(value: string): boolean {
85
+ return (Common.isHex(value) && value.length === 128);
86
+ }
87
+
88
+ public static str2bin(str: string): Uint8Array {
89
+ const result = new Uint8Array(str.length);
90
+ for (let i = 0; i < str.length; i++) {
91
+ result[i] = str.charCodeAt(i);
92
+ }
93
+
94
+ return result;
95
+ }
96
+
97
+ public static varintLength(value: BigInteger.BigInteger | number): number {
98
+ if (typeof value === 'number') {
99
+ value = BigInteger(value);
100
+ }
101
+ const writer = new Writer();
102
+ writer.varint(value);
103
+ return writer.length;
104
+ }
105
+ }
package/src/Config.ts ADDED
@@ -0,0 +1,66 @@
1
+ // Copyright (c) 2018-2020, The TurtleCoin Developers
2
+ //
3
+ // Please see the included LICENSE file for more information.
4
+
5
+ export namespace Interfaces {
6
+ export interface Config {
7
+ activateParentBlockVersion?: number;
8
+ coinUnitPlaces?: number;
9
+ addressPrefix?: number;
10
+ keccakIterations?: number;
11
+ defaultNetworkFee?: number;
12
+ fusionMinInputCount?: number;
13
+ fusionMinInOutCountRatio?: number;
14
+ mmMiningBlockVersion?: number;
15
+ maximumOutputAmount?: number;
16
+ maximumOutputsPerTransaction?: number;
17
+ maximumExtraSize?: number;
18
+ activateFeePerByteTransactions?: boolean;
19
+ feePerByte?: number;
20
+ feePerByteChunkSize?: number;
21
+
22
+ underivePublicKey?: (derivation: string,
23
+ outputIndex: number,
24
+ outputKey: string) => string;
25
+
26
+ derivePublicKey?: (derivation: string,
27
+ outputIndex: number,
28
+ publicKey: string) => string;
29
+
30
+ deriveSecretKey?: (derivation: string,
31
+ outputIndex: number,
32
+ privateKey: string) => string;
33
+
34
+ generateKeyImage?: (transactionPublicKey: string,
35
+ privateViewKey: string,
36
+ publicSpendKey: string,
37
+ privateSpendKey: string,
38
+ outputIndex: number) => string;
39
+
40
+ secretKeyToPublicKey?: (privateKey: string) => string;
41
+
42
+ cn_fast_hash?: (input: string) => string;
43
+
44
+ generateRingSignatures?: (transactionPrefixHash: string,
45
+ keyImage: string,
46
+ inputKeys: string[],
47
+ privateKey: string,
48
+ realIndex: number) => string[];
49
+
50
+ checkRingSignatures?: (transactionPrefixHash: string,
51
+ keyImage: string,
52
+ publicKeys: string[],
53
+ signatures: string[]) => boolean;
54
+
55
+ generateKeyDerivation?: (transactionPublicKey: string,
56
+ privateViewKey: string) => string;
57
+
58
+ checkSignature?: (digestHash: string,
59
+ publicKey: string,
60
+ signature: string) => boolean;
61
+
62
+ generateSignature?: (digestHash: string,
63
+ publicKey: string,
64
+ privateKey: string) => [boolean, string];
65
+ }
66
+ }