@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.
- package/.github/workflows/ci.yml +27 -0
- package/.idea/codeStyles/codeStyleConfig.xml +5 -0
- package/.idea/inspectionProfiles/Project_Default.xml +7 -0
- package/.idea/misc.xml +6 -0
- package/.idea/modules.xml +8 -0
- package/.idea/turtlecoin-utils.iml +12 -0
- package/.idea/vcs.xml +6 -0
- package/.travis.yml +11 -0
- package/CONTRIBUTING.md +3 -0
- package/LICENSE +674 -0
- package/README.md +203 -0
- package/config.json +7 -0
- package/docs/.nojekyll +0 -0
- package/docs/CNAME +1 -0
- package/docs/assets/css/main.css +2321 -0
- package/docs/assets/images/icons.png +0 -0
- package/docs/assets/images/icons@2x.png +0 -0
- package/docs/assets/images/widgets.png +0 -0
- package/docs/assets/images/widgets@2x.png +0 -0
- package/docs/assets/js/main.js +1 -0
- package/docs/assets/js/search.js +3 -0
- package/docs/classes/address.html +964 -0
- package/docs/classes/addressprefix.html +431 -0
- package/docs/classes/block.html +965 -0
- package/docs/classes/blocktemplate.html +695 -0
- package/docs/classes/cryptonote.html +1137 -0
- package/docs/classes/ed25519.keypair.html +400 -0
- package/docs/classes/ed25519.keys.html +373 -0
- package/docs/classes/extranoncetag.extranoncedata.html +454 -0
- package/docs/classes/extranoncetag.extranoncepaymentid.html +453 -0
- package/docs/classes/extranoncetag.iextranonce.html +347 -0
- package/docs/classes/extratag.extramergedmining.html +494 -0
- package/docs/classes/extratag.extranonce.html +530 -0
- package/docs/classes/extratag.extrapadding.html +456 -0
- package/docs/classes/extratag.extrapublickey.html +460 -0
- package/docs/classes/extratag.iextratag.html +355 -0
- package/docs/classes/levinpacket.html +674 -0
- package/docs/classes/levinpayloads.handshake.html +731 -0
- package/docs/classes/levinpayloads.ilevinpayload.html +318 -0
- package/docs/classes/levinpayloads.liteblock.html +494 -0
- package/docs/classes/levinpayloads.missingtransactions.html +494 -0
- package/docs/classes/levinpayloads.newblock.html +540 -0
- package/docs/classes/levinpayloads.newtransactions.html +402 -0
- package/docs/classes/levinpayloads.peerentry.html +610 -0
- package/docs/classes/levinpayloads.ping.html +450 -0
- package/docs/classes/levinpayloads.rawblock.html +344 -0
- package/docs/classes/levinpayloads.requestchain.html +402 -0
- package/docs/classes/levinpayloads.requestgetobjects.html +448 -0
- package/docs/classes/levinpayloads.requesttxpool.html +402 -0
- package/docs/classes/levinpayloads.responsechain.html +494 -0
- package/docs/classes/levinpayloads.responsegetobjects.html +540 -0
- package/docs/classes/levinpayloads.timedsync.html +540 -0
- package/docs/classes/multisig.html +930 -0
- package/docs/classes/multisigmessage.html +694 -0
- package/docs/classes/parentblock.html +347 -0
- package/docs/classes/transaction.html +925 -0
- package/docs/classes/transactioninputs.coinbaseinput.html +390 -0
- package/docs/classes/transactioninputs.itransactioninput.html +321 -0
- package/docs/classes/transactioninputs.keyinput.html +459 -0
- package/docs/classes/transactionoutputs.itransactionoutput.html +317 -0
- package/docs/classes/transactionoutputs.keyoutput.html +422 -0
- package/docs/enums/extranoncetag.noncetagtype.html +246 -0
- package/docs/enums/extratag.extratagtype.html +280 -0
- package/docs/enums/levinprotocol.commandtype.html +391 -0
- package/docs/enums/transactioninputs.inputtype.html +246 -0
- package/docs/enums/transactionoutputs.outputtype.html +229 -0
- package/docs/globals.html +238 -0
- package/docs/index.html +271 -0
- package/docs/interfaces/interfaces.config.html +590 -0
- package/docs/interfaces/interfaces.daemonblocktemplateresponse.html +323 -0
- package/docs/interfaces/interfaces.generatedinput.html +304 -0
- package/docs/interfaces/interfaces.generatedoutput.html +285 -0
- package/docs/interfaces/interfaces.inputkeys.html +304 -0
- package/docs/interfaces/interfaces.ipreparedtransaction.html +268 -0
- package/docs/interfaces/interfaces.output.html +399 -0
- package/docs/interfaces/interfaces.preparedringsignature.html +377 -0
- package/docs/interfaces/interfaces.preparedtransaction.html +329 -0
- package/docs/interfaces/interfaces.randomoutput.html +285 -0
- package/docs/interfaces/interfaces.transactionrecipient.html +285 -0
- package/docs/interfaces/multisiginterfaces.partialkeyimage.html +277 -0
- package/docs/interfaces/multisiginterfaces.partialsigningkey.html +277 -0
- package/docs/modules/ed25519.html +195 -0
- package/docs/modules/extranoncetag.html +208 -0
- package/docs/modules/extratag.html +216 -0
- package/docs/modules/interfaces.html +231 -0
- package/docs/modules/levinpayloads.html +247 -0
- package/docs/modules/levinprotocol.html +191 -0
- package/docs/modules/multisiginterfaces.html +195 -0
- package/docs/modules/transactioninputs.html +208 -0
- package/docs/modules/transactionoutputs.html +204 -0
- package/index.d.ts +417 -0
- package/index.js +1508 -0
- package/lib/base58.js +220 -0
- package/lib/biginteger.js +1591 -0
- package/lib/blocktemplate.js +408 -0
- package/lib/crypto.js +19698 -0
- package/lib/mnemonic.js +1204 -0
- package/lib/nacl-fast-cn.js +608 -0
- package/lib/ringsigs.js +24262 -0
- package/lib/sha3.js +477 -0
- package/package.json +58 -0
- package/src/Address.ts +433 -0
- package/src/AddressPrefix.ts +117 -0
- package/src/Block.ts +556 -0
- package/src/BlockTemplate.ts +289 -0
- package/src/Common.ts +105 -0
- package/src/Config.ts +66 -0
- package/src/CryptoNote.ts +1072 -0
- package/src/LevinPacket.ts +366 -0
- package/src/Multisig.ts +600 -0
- package/src/MultisigMessage.ts +374 -0
- package/src/ParentBlock.ts +39 -0
- package/src/Transaction.ts +628 -0
- package/src/Types/ED25519.ts +187 -0
- package/src/Types/IExtraNonce.ts +225 -0
- package/src/Types/IExtraTag.ts +507 -0
- package/src/Types/ITransaction.ts +230 -0
- package/src/Types/ITransactionInput.ts +190 -0
- package/src/Types/ITransactionOutput.ts +108 -0
- package/src/Types/LevinPayloads.ts +1576 -0
- package/src/Types/MultisigInterfaces.ts +65 -0
- package/src/Types/PortableStorage.ts +289 -0
- package/src/Types.ts +36 -0
- package/src/index.ts +36 -0
- package/test/template.json +6 -0
- package/test/test.js +1457 -0
- package/tests/blocktemplate.json +6 -0
- package/tests/tests.js +215 -0
- package/tsconfig.json +15 -0
- package/tslint.json +36 -0
- package/typedoc.json +10 -0
- 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
|
+
}
|