viz-js-lib 0.11.0 → 0.12.4

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 (60) hide show
  1. package/.qoder/docs/spec/viz-dns-nameserver-spec.md +982 -0
  2. package/.qoder/docs/viz-cpp-node-docs/data-types.md +322 -0
  3. package/.qoder/docs/viz-cpp-node-docs/index.md +160 -0
  4. package/.qoder/docs/viz-cpp-node-docs/op-account-market.md +236 -0
  5. package/.qoder/docs/viz-cpp-node-docs/op-account.md +199 -0
  6. package/.qoder/docs/viz-cpp-node-docs/op-award.md +162 -0
  7. package/.qoder/docs/viz-cpp-node-docs/op-committee.md +193 -0
  8. package/.qoder/docs/viz-cpp-node-docs/op-content.md +157 -0
  9. package/.qoder/docs/viz-cpp-node-docs/op-escrow.md +224 -0
  10. package/.qoder/docs/viz-cpp-node-docs/op-invite.md +219 -0
  11. package/.qoder/docs/viz-cpp-node-docs/op-proposal.md +229 -0
  12. package/.qoder/docs/viz-cpp-node-docs/op-recovery.md +188 -0
  13. package/.qoder/docs/viz-cpp-node-docs/op-subscription.md +146 -0
  14. package/.qoder/docs/viz-cpp-node-docs/op-transfer-vesting.md +224 -0
  15. package/.qoder/docs/viz-cpp-node-docs/op-witness.md +252 -0
  16. package/.qoder/docs/viz-cpp-node-docs/plugins.md +887 -0
  17. package/.qoder/docs/viz-cpp-node-docs/virtual-operations.md +513 -0
  18. package/.qoder/repowiki/en/content/API Reference/API Reference.md +724 -0
  19. package/.qoder/repowiki/en/content/API Reference/Configuration Options.md +410 -0
  20. package/.qoder/repowiki/en/content/API Reference/Core API Methods.md +547 -0
  21. package/.qoder/repowiki/en/content/API Reference/Streaming APIs.md +380 -0
  22. package/.qoder/repowiki/en/content/API Reference/Transport Layer.md +341 -0
  23. package/.qoder/repowiki/en/content/API Reference/VIZ Blockchain Operations Coverage Status.md +427 -0
  24. package/.qoder/repowiki/en/content/Authentication & Cryptography/Authentication & Cryptography.md +430 -0
  25. package/.qoder/repowiki/en/content/Authentication & Cryptography/Digital Signatures.md +462 -0
  26. package/.qoder/repowiki/en/content/Authentication & Cryptography/Key Management.md +456 -0
  27. package/.qoder/repowiki/en/content/Authentication & Cryptography/Memo Encryption.md +331 -0
  28. package/.qoder/repowiki/en/content/Authentication & Cryptography/Security Practices.md +488 -0
  29. package/.qoder/repowiki/en/content/Broadcast Transactions/Broadcast Transactions.md +432 -0
  30. package/.qoder/repowiki/en/content/Broadcast Transactions/Network Broadcasting.md +418 -0
  31. package/.qoder/repowiki/en/content/Broadcast Transactions/Operation Construction.md +352 -0
  32. package/.qoder/repowiki/en/content/Broadcast Transactions/Transaction Preparation.md +353 -0
  33. package/.qoder/repowiki/en/content/Broadcast Transactions/Transaction Signing.md +404 -0
  34. package/.qoder/repowiki/en/content/Data Serialization/Data Serialization.md +540 -0
  35. package/.qoder/repowiki/en/content/Data Serialization/Encoding & Decoding.md +463 -0
  36. package/.qoder/repowiki/en/content/Data Serialization/Object Templates.md +413 -0
  37. package/.qoder/repowiki/en/content/Data Serialization/Type System.md +514 -0
  38. package/.qoder/repowiki/en/content/Data Serialization/Validation Rules.md +439 -0
  39. package/.qoder/repowiki/en/content/Examples & Tutorials.md +485 -0
  40. package/.qoder/repowiki/en/content/Getting Started.md +345 -0
  41. package/.qoder/repowiki/en/content/Testing & Development.md +637 -0
  42. package/.qoder/repowiki/en/content/Utilities & Helpers.md +557 -0
  43. package/.qoder/repowiki/en/meta/repowiki-metadata.json +1 -0
  44. package/VIZ-JS-LIB-COVERAGE-STATUS.md +356 -0
  45. package/config.json +3 -1
  46. package/dist/statistics.html +1 -1
  47. package/dist/viz-tests.min.js +32 -42
  48. package/dist/viz-tests.min.js.gz +0 -0
  49. package/dist/viz.min.js +8 -18
  50. package/dist/viz.min.js.gz +0 -0
  51. package/lib/api/methods.js +24 -0
  52. package/lib/auth/serializer/src/ChainTypes.js +2 -1
  53. package/lib/auth/serializer/src/operations.js +35 -2
  54. package/lib/broadcast/index.js +29 -15
  55. package/lib/broadcast/operations.js +4 -0
  56. package/lib/dns.js +658 -0
  57. package/lib/index.js +3 -1
  58. package/package.json +3 -2
  59. package/test/dns.test.js +395 -0
  60. package/webpack/makeConfig.js +3 -0
package/lib/dns.js ADDED
@@ -0,0 +1,658 @@
1
+ 'use strict';
2
+
3
+ var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
4
+
5
+ var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
6
+
7
+ /**
8
+ * VIZ DNS Nameserver Helpers
9
+ *
10
+ * A module for working with NS records (A and TXT) stored in VIZ blockchain account metadata.
11
+ * Based on viz-dns-nameserver-spec.md
12
+ *
13
+ * @module viz/dns
14
+ */
15
+
16
+ /** Default TTL value in seconds (8 hours) */
17
+ var DEFAULT_TTL = 28800;
18
+
19
+ /** Maximum TXT record length per NS standard */
20
+ var MAX_TXT_LENGTH = 256;
21
+
22
+ /** SHA256 hash length in hex (64 characters) */
23
+ var SHA256_HEX_LENGTH = 64;
24
+
25
+ /** IPv4 address validation regex */
26
+ var IPV4_REGEX = /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/;
27
+
28
+ /** SHA256 hex hash validation regex */
29
+ var SHA256_HEX_REGEX = /^[a-f0-9]{64}$/i;
30
+
31
+ /**
32
+ * Validates an IPv4 address
33
+ * @param {string} ipv4 - IPv4 address to validate
34
+ * @returns {boolean} True if valid IPv4 address
35
+ */
36
+ function isValidIPv4(ipv4) {
37
+ if (typeof ipv4 !== 'string') return false;
38
+ return IPV4_REGEX.test(ipv4);
39
+ }
40
+
41
+ /**
42
+ * Validates a SHA256 hash string (64 hex characters)
43
+ * @param {string} hash - Hash string to validate
44
+ * @returns {boolean} True if valid SHA256 hex hash
45
+ */
46
+ function isValidSHA256Hash(hash) {
47
+ if (typeof hash !== 'string') return false;
48
+ return SHA256_HEX_REGEX.test(hash);
49
+ }
50
+
51
+ /**
52
+ * Validates a TTL value
53
+ * @param {number} ttl - TTL value in seconds
54
+ * @returns {boolean} True if valid TTL (positive integer)
55
+ */
56
+ function isValidTTL(ttl) {
57
+ return Number.isInteger(ttl) && ttl > 0;
58
+ }
59
+
60
+ /**
61
+ * Validates a TXT record value
62
+ * @param {string} txt - TXT record value
63
+ * @returns {boolean} True if valid TXT record (not exceeding max length)
64
+ */
65
+ function isValidTxtRecord(txt) {
66
+ if (typeof txt !== 'string') return false;
67
+ return txt.length > 0 && txt.length <= MAX_TXT_LENGTH;
68
+ }
69
+
70
+ /**
71
+ * Validates an SSL TXT record (ssl=<hash> format)
72
+ * @param {string} txt - TXT record value
73
+ * @returns {boolean} True if valid SSL TXT record
74
+ */
75
+ function isValidSslTxtRecord(txt) {
76
+ if (!isValidTxtRecord(txt)) return false;
77
+ if (!txt.startsWith('ssl=')) return false;
78
+ var hash = txt.substring(4);
79
+ return isValidSHA256Hash(hash);
80
+ }
81
+
82
+ /**
83
+ * Creates an A record tuple
84
+ * @param {string} ipv4 - IPv4 address
85
+ * @returns {Array} A record tuple ["A", ipv4]
86
+ * @throws {Error} If IPv4 address is invalid
87
+ */
88
+ function createARecord(ipv4) {
89
+ if (!isValidIPv4(ipv4)) {
90
+ throw new Error('Invalid IPv4 address: ' + ipv4);
91
+ }
92
+ return ['A', ipv4];
93
+ }
94
+
95
+ /**
96
+ * Creates a TXT record tuple for SSL certificate hash
97
+ * @param {string} hash - SHA256 hash of SSL certificate public key
98
+ * @returns {Array} TXT record tuple ["TXT", "ssl=<hash>"]
99
+ * @throws {Error} If hash is invalid
100
+ */
101
+ function createSslTxtRecord(hash) {
102
+ if (!isValidSHA256Hash(hash)) {
103
+ throw new Error('Invalid SHA256 hash: ' + hash);
104
+ }
105
+ return ['TXT', 'ssl=' + hash.toLowerCase()];
106
+ }
107
+
108
+ /**
109
+ * Creates a generic TXT record tuple
110
+ * @param {string} value - TXT record value
111
+ * @returns {Array} TXT record tuple ["TXT", value]
112
+ * @throws {Error} If TXT value is invalid
113
+ */
114
+ function createTxtRecord(value) {
115
+ if (!isValidTxtRecord(value)) {
116
+ throw new Error('Invalid TXT record value: ' + value);
117
+ }
118
+ return ['TXT', value];
119
+ }
120
+
121
+ /**
122
+ * Creates a new NS metadata object
123
+ * @param {Object} [options] - Options for creating NS metadata
124
+ * @param {Array<string>} [options.aRecords] - Array of IPv4 addresses
125
+ * @param {string} [options.sslHash] - SSL certificate public key hash
126
+ * @param {Array<string>} [options.txtRecords] - Array of custom TXT record values
127
+ * @param {number} [options.ttl] - Time-to-live in seconds (default: 28800)
128
+ * @returns {Object} NS metadata object with ns array and ttl
129
+ * @example
130
+ * createNsMetadata({
131
+ * aRecords: ['188.120.231.153', '192.168.1.100'],
132
+ * sslHash: '4a4613daef37cbc5c4a5156cd7b24ea2e6ee2e5f1e7461262a2df2b63cbf17e2',
133
+ * ttl: 28800
134
+ * })
135
+ */
136
+ function createNsMetadata() {
137
+ var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
138
+ var _options$aRecords = options.aRecords,
139
+ aRecords = _options$aRecords === undefined ? [] : _options$aRecords,
140
+ sslHash = options.sslHash,
141
+ _options$txtRecords = options.txtRecords,
142
+ txtRecords = _options$txtRecords === undefined ? [] : _options$txtRecords,
143
+ _options$ttl = options.ttl,
144
+ ttl = _options$ttl === undefined ? DEFAULT_TTL : _options$ttl;
145
+
146
+
147
+ if (!isValidTTL(ttl)) {
148
+ throw new Error('Invalid TTL value: ' + ttl);
149
+ }
150
+
151
+ var ns = [];
152
+
153
+ // Add A records
154
+ var _iteratorNormalCompletion = true;
155
+ var _didIteratorError = false;
156
+ var _iteratorError = undefined;
157
+
158
+ try {
159
+ for (var _iterator = aRecords[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
160
+ var ip = _step.value;
161
+
162
+ ns.push(createARecord(ip));
163
+ }
164
+
165
+ // Add SSL TXT record if provided
166
+ } catch (err) {
167
+ _didIteratorError = true;
168
+ _iteratorError = err;
169
+ } finally {
170
+ try {
171
+ if (!_iteratorNormalCompletion && _iterator.return) {
172
+ _iterator.return();
173
+ }
174
+ } finally {
175
+ if (_didIteratorError) {
176
+ throw _iteratorError;
177
+ }
178
+ }
179
+ }
180
+
181
+ if (sslHash) {
182
+ ns.push(createSslTxtRecord(sslHash));
183
+ }
184
+
185
+ // Add custom TXT records
186
+ var _iteratorNormalCompletion2 = true;
187
+ var _didIteratorError2 = false;
188
+ var _iteratorError2 = undefined;
189
+
190
+ try {
191
+ for (var _iterator2 = txtRecords[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
192
+ var txt = _step2.value;
193
+
194
+ ns.push(createTxtRecord(txt));
195
+ }
196
+ } catch (err) {
197
+ _didIteratorError2 = true;
198
+ _iteratorError2 = err;
199
+ } finally {
200
+ try {
201
+ if (!_iteratorNormalCompletion2 && _iterator2.return) {
202
+ _iterator2.return();
203
+ }
204
+ } finally {
205
+ if (_didIteratorError2) {
206
+ throw _iteratorError2;
207
+ }
208
+ }
209
+ }
210
+
211
+ return { ns: ns, ttl: ttl };
212
+ }
213
+
214
+ /**
215
+ * Parses NS metadata from account json_metadata
216
+ * @param {string|Object} jsonMetadata - JSON metadata string or parsed object
217
+ * @returns {Object|null} Parsed NS data or null if not found
218
+ * @returns {Array} result.ns - Array of record tuples
219
+ * @returns {number} result.ttl - TTL value
220
+ */
221
+ function parseNsMetadata(jsonMetadata) {
222
+ var metadata = jsonMetadata;
223
+
224
+ // Parse if string
225
+ if (typeof jsonMetadata === 'string') {
226
+ try {
227
+ metadata = JSON.parse(jsonMetadata);
228
+ } catch (e) {
229
+ return null;
230
+ }
231
+ }
232
+
233
+ if (!metadata || (typeof metadata === 'undefined' ? 'undefined' : _typeof(metadata)) !== 'object') {
234
+ return null;
235
+ }
236
+
237
+ if (!metadata.ns || !Array.isArray(metadata.ns)) {
238
+ return null;
239
+ }
240
+
241
+ return {
242
+ ns: metadata.ns,
243
+ ttl: metadata.ttl || DEFAULT_TTL
244
+ };
245
+ }
246
+
247
+ /**
248
+ * Extracts all A records (IPv4 addresses) from NS metadata
249
+ * @param {string|Object} jsonMetadata - JSON metadata string or parsed object
250
+ * @returns {Array<string>} Array of IPv4 addresses
251
+ */
252
+ function extractARecords(jsonMetadata) {
253
+ var nsData = parseNsMetadata(jsonMetadata);
254
+ if (!nsData) return [];
255
+
256
+ return nsData.ns.filter(function (record) {
257
+ return Array.isArray(record) && record[0] === 'A';
258
+ }).map(function (record) {
259
+ return record[1];
260
+ });
261
+ }
262
+
263
+ /**
264
+ * Extracts the SSL hash from TXT records in NS metadata
265
+ * @param {string|Object} jsonMetadata - JSON metadata string or parsed object
266
+ * @returns {string|null} SSL hash or null if not found
267
+ */
268
+ function extractSslHash(jsonMetadata) {
269
+ var nsData = parseNsMetadata(jsonMetadata);
270
+ if (!nsData) return null;
271
+
272
+ var _iteratorNormalCompletion3 = true;
273
+ var _didIteratorError3 = false;
274
+ var _iteratorError3 = undefined;
275
+
276
+ try {
277
+ for (var _iterator3 = nsData.ns[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {
278
+ var record = _step3.value;
279
+
280
+ if (!Array.isArray(record) || record[0] !== 'TXT') continue;
281
+
282
+ var value = record[1];
283
+ if (typeof value === 'string' && value.startsWith('ssl=')) {
284
+ var hash = value.substring(4);
285
+ if (isValidSHA256Hash(hash)) {
286
+ return hash.toLowerCase();
287
+ }
288
+ }
289
+ }
290
+ } catch (err) {
291
+ _didIteratorError3 = true;
292
+ _iteratorError3 = err;
293
+ } finally {
294
+ try {
295
+ if (!_iteratorNormalCompletion3 && _iterator3.return) {
296
+ _iterator3.return();
297
+ }
298
+ } finally {
299
+ if (_didIteratorError3) {
300
+ throw _iteratorError3;
301
+ }
302
+ }
303
+ }
304
+
305
+ return null;
306
+ }
307
+
308
+ /**
309
+ * Extracts all TXT records from NS metadata
310
+ * @param {string|Object} jsonMetadata - JSON metadata string or parsed object
311
+ * @returns {Array<string>} Array of TXT record values
312
+ */
313
+ function extractTxtRecords(jsonMetadata) {
314
+ var nsData = parseNsMetadata(jsonMetadata);
315
+ if (!nsData) return [];
316
+
317
+ return nsData.ns.filter(function (record) {
318
+ return Array.isArray(record) && record[0] === 'TXT';
319
+ }).map(function (record) {
320
+ return record[1];
321
+ });
322
+ }
323
+
324
+ /**
325
+ * Extracts the TTL value from NS metadata
326
+ * @param {string|Object} jsonMetadata - JSON metadata string or parsed object
327
+ * @returns {number} TTL value or default (28800)
328
+ */
329
+ function extractTtl(jsonMetadata) {
330
+ var nsData = parseNsMetadata(jsonMetadata);
331
+ return nsData ? nsData.ttl : DEFAULT_TTL;
332
+ }
333
+
334
+ /**
335
+ * Merges NS data into existing account metadata
336
+ * @param {string|Object} existingMetadata - Existing JSON metadata string or object
337
+ * @param {Object} nsData - NS data to merge (result from createNsMetadata)
338
+ * @returns {Object} Merged metadata object
339
+ */
340
+ function mergeNsMetadata(existingMetadata, nsData) {
341
+ var metadata = {};
342
+
343
+ // Parse existing metadata
344
+ if (typeof existingMetadata === 'string') {
345
+ try {
346
+ metadata = JSON.parse(existingMetadata) || {};
347
+ } catch (e) {
348
+ metadata = {};
349
+ }
350
+ } else if (existingMetadata && (typeof existingMetadata === 'undefined' ? 'undefined' : _typeof(existingMetadata)) === 'object') {
351
+ metadata = Object.assign({}, existingMetadata);
352
+ }
353
+
354
+ // Merge NS data
355
+ if (nsData && nsData.ns) {
356
+ metadata.ns = nsData.ns;
357
+ }
358
+ if (nsData && nsData.ttl) {
359
+ metadata.ttl = nsData.ttl;
360
+ }
361
+
362
+ return metadata;
363
+ }
364
+
365
+ /**
366
+ * Removes NS data from account metadata
367
+ * @param {string|Object} existingMetadata - Existing JSON metadata string or object
368
+ * @returns {Object} Metadata object without NS data
369
+ */
370
+ function removeNsMetadata(existingMetadata) {
371
+ var metadata = {};
372
+
373
+ // Parse existing metadata
374
+ if (typeof existingMetadata === 'string') {
375
+ try {
376
+ metadata = JSON.parse(existingMetadata) || {};
377
+ } catch (e) {
378
+ metadata = {};
379
+ }
380
+ } else if (existingMetadata && (typeof existingMetadata === 'undefined' ? 'undefined' : _typeof(existingMetadata)) === 'object') {
381
+ metadata = Object.assign({}, existingMetadata);
382
+ }
383
+
384
+ // Remove NS fields
385
+ delete metadata.ns;
386
+ delete metadata.ttl;
387
+
388
+ return metadata;
389
+ }
390
+
391
+ /**
392
+ * Adds an A record to existing NS metadata
393
+ * @param {string|Object} jsonMetadata - JSON metadata string or parsed object
394
+ * @param {string} ipv4 - IPv4 address to add
395
+ * @returns {Object} Updated metadata object
396
+ */
397
+ function addARecord(jsonMetadata, ipv4) {
398
+ var metadata = {};
399
+
400
+ if (typeof jsonMetadata === 'string') {
401
+ try {
402
+ metadata = JSON.parse(jsonMetadata) || {};
403
+ } catch (e) {
404
+ metadata = {};
405
+ }
406
+ } else if (jsonMetadata && (typeof jsonMetadata === 'undefined' ? 'undefined' : _typeof(jsonMetadata)) === 'object') {
407
+ metadata = Object.assign({}, jsonMetadata);
408
+ }
409
+
410
+ if (!metadata.ns) {
411
+ metadata.ns = [];
412
+ }
413
+ if (!metadata.ttl) {
414
+ metadata.ttl = DEFAULT_TTL;
415
+ }
416
+
417
+ metadata.ns.push(createARecord(ipv4));
418
+
419
+ return metadata;
420
+ }
421
+
422
+ /**
423
+ * Removes an A record from existing NS metadata
424
+ * @param {string|Object} jsonMetadata - JSON metadata string or parsed object
425
+ * @param {string} ipv4 - IPv4 address to remove
426
+ * @returns {Object} Updated metadata object
427
+ */
428
+ function removeARecord(jsonMetadata, ipv4) {
429
+ var metadata = {};
430
+
431
+ if (typeof jsonMetadata === 'string') {
432
+ try {
433
+ metadata = JSON.parse(jsonMetadata) || {};
434
+ } catch (e) {
435
+ metadata = {};
436
+ }
437
+ } else if (jsonMetadata && (typeof jsonMetadata === 'undefined' ? 'undefined' : _typeof(jsonMetadata)) === 'object') {
438
+ metadata = Object.assign({}, jsonMetadata);
439
+ }
440
+
441
+ if (!metadata.ns || !Array.isArray(metadata.ns)) {
442
+ return metadata;
443
+ }
444
+
445
+ metadata.ns = metadata.ns.filter(function (record) {
446
+ return !(Array.isArray(record) && record[0] === 'A' && record[1] === ipv4);
447
+ });
448
+
449
+ return metadata;
450
+ }
451
+
452
+ /**
453
+ * Sets or updates the SSL hash in NS metadata
454
+ * @param {string|Object} jsonMetadata - JSON metadata string or parsed object
455
+ * @param {string} hash - SHA256 hash of SSL certificate public key
456
+ * @returns {Object} Updated metadata object
457
+ */
458
+ function setSslHash(jsonMetadata, hash) {
459
+ var metadata = {};
460
+
461
+ if (typeof jsonMetadata === 'string') {
462
+ try {
463
+ metadata = JSON.parse(jsonMetadata) || {};
464
+ } catch (e) {
465
+ metadata = {};
466
+ }
467
+ } else if (jsonMetadata && (typeof jsonMetadata === 'undefined' ? 'undefined' : _typeof(jsonMetadata)) === 'object') {
468
+ metadata = Object.assign({}, jsonMetadata);
469
+ }
470
+
471
+ if (!metadata.ns) {
472
+ metadata.ns = [];
473
+ }
474
+ if (!metadata.ttl) {
475
+ metadata.ttl = DEFAULT_TTL;
476
+ }
477
+
478
+ // Remove existing SSL TXT record
479
+ metadata.ns = metadata.ns.filter(function (record) {
480
+ return !(Array.isArray(record) && record[0] === 'TXT' && record[1].startsWith('ssl='));
481
+ });
482
+
483
+ // Add new SSL TXT record
484
+ metadata.ns.push(createSslTxtRecord(hash));
485
+
486
+ return metadata;
487
+ }
488
+
489
+ /**
490
+ * Removes the SSL hash TXT record from NS metadata
491
+ * @param {string|Object} jsonMetadata - JSON metadata string or parsed object
492
+ * @returns {Object} Updated metadata object
493
+ */
494
+ function removeSslHash(jsonMetadata) {
495
+ var metadata = {};
496
+
497
+ if (typeof jsonMetadata === 'string') {
498
+ try {
499
+ metadata = JSON.parse(jsonMetadata) || {};
500
+ } catch (e) {
501
+ metadata = {};
502
+ }
503
+ } else if (jsonMetadata && (typeof jsonMetadata === 'undefined' ? 'undefined' : _typeof(jsonMetadata)) === 'object') {
504
+ metadata = Object.assign({}, jsonMetadata);
505
+ }
506
+
507
+ if (!metadata.ns || !Array.isArray(metadata.ns)) {
508
+ return metadata;
509
+ }
510
+
511
+ metadata.ns = metadata.ns.filter(function (record) {
512
+ return !(Array.isArray(record) && record[0] === 'TXT' && record[1].startsWith('ssl='));
513
+ });
514
+
515
+ return metadata;
516
+ }
517
+
518
+ /**
519
+ * Sets the TTL value in NS metadata
520
+ * @param {string|Object} jsonMetadata - JSON metadata string or parsed object
521
+ * @param {number} ttl - TTL value in seconds
522
+ * @returns {Object} Updated metadata object
523
+ * @throws {Error} If TTL value is invalid
524
+ */
525
+ function setTtl(jsonMetadata, ttl) {
526
+ if (!isValidTTL(ttl)) {
527
+ throw new Error('Invalid TTL value: ' + ttl);
528
+ }
529
+
530
+ var metadata = {};
531
+
532
+ if (typeof jsonMetadata === 'string') {
533
+ try {
534
+ metadata = JSON.parse(jsonMetadata) || {};
535
+ } catch (e) {
536
+ metadata = {};
537
+ }
538
+ } else if (jsonMetadata && (typeof jsonMetadata === 'undefined' ? 'undefined' : _typeof(jsonMetadata)) === 'object') {
539
+ metadata = Object.assign({}, jsonMetadata);
540
+ }
541
+
542
+ metadata.ttl = ttl;
543
+
544
+ return metadata;
545
+ }
546
+
547
+ /**
548
+ * Checks if metadata contains NS records
549
+ * @param {string|Object} jsonMetadata - JSON metadata string or parsed object
550
+ * @returns {boolean} True if NS records exist
551
+ */
552
+ function hasNsRecords(jsonMetadata) {
553
+ var nsData = parseNsMetadata(jsonMetadata);
554
+ return nsData !== null && nsData.ns.length > 0;
555
+ }
556
+
557
+ /**
558
+ * Gets a summary of NS records from metadata
559
+ * @param {string|Object} jsonMetadata - JSON metadata string or parsed object
560
+ * @returns {Object} Summary object with aRecords, sslHash, txtRecords, and ttl
561
+ */
562
+ function getNsSummary(jsonMetadata) {
563
+ return {
564
+ aRecords: extractARecords(jsonMetadata),
565
+ sslHash: extractSslHash(jsonMetadata),
566
+ txtRecords: extractTxtRecords(jsonMetadata),
567
+ ttl: extractTtl(jsonMetadata)
568
+ };
569
+ }
570
+
571
+ /**
572
+ * Validates NS metadata structure
573
+ * @param {Object} nsData - NS data object to validate
574
+ * @returns {Object} Validation result with isValid and errors array
575
+ */
576
+ function validateNsMetadata(nsData) {
577
+ var errors = [];
578
+
579
+ if (!nsData || (typeof nsData === 'undefined' ? 'undefined' : _typeof(nsData)) !== 'object') {
580
+ return { isValid: false, errors: ['NS data must be an object'] };
581
+ }
582
+
583
+ // Validate ns array
584
+ if (!Array.isArray(nsData.ns)) {
585
+ errors.push('ns must be an array');
586
+ } else {
587
+ for (var i = 0; i < nsData.ns.length; i++) {
588
+ var record = nsData.ns[i];
589
+ if (!Array.isArray(record) || record.length !== 2) {
590
+ errors.push('ns[' + i + '] must be a tuple [type, value]');
591
+ continue;
592
+ }
593
+
594
+ var _record = _slicedToArray(record, 2),
595
+ type = _record[0],
596
+ value = _record[1];
597
+
598
+ if (type === 'A') {
599
+ if (!isValidIPv4(value)) {
600
+ errors.push('ns[' + i + '] has invalid IPv4 address: ' + value);
601
+ }
602
+ } else if (type === 'TXT') {
603
+ if (!isValidTxtRecord(value)) {
604
+ errors.push('ns[' + i + '] has invalid TXT record value');
605
+ }
606
+ } else {
607
+ errors.push('ns[' + i + '] has unsupported record type: ' + type);
608
+ }
609
+ }
610
+ }
611
+
612
+ // Validate TTL
613
+ if (nsData.ttl !== undefined && !isValidTTL(nsData.ttl)) {
614
+ errors.push('Invalid TTL value: ' + nsData.ttl);
615
+ }
616
+
617
+ return {
618
+ isValid: errors.length === 0,
619
+ errors: errors
620
+ };
621
+ }
622
+
623
+ // Export constants
624
+ module.exports.DEFAULT_TTL = DEFAULT_TTL;
625
+ module.exports.MAX_TXT_LENGTH = MAX_TXT_LENGTH;
626
+ module.exports.SHA256_HEX_LENGTH = SHA256_HEX_LENGTH;
627
+
628
+ // Export validation functions
629
+ module.exports.isValidIPv4 = isValidIPv4;
630
+ module.exports.isValidSHA256Hash = isValidSHA256Hash;
631
+ module.exports.isValidTTL = isValidTTL;
632
+ module.exports.isValidTxtRecord = isValidTxtRecord;
633
+ module.exports.isValidSslTxtRecord = isValidSslTxtRecord;
634
+ module.exports.validateNsMetadata = validateNsMetadata;
635
+
636
+ // Export record creation functions
637
+ module.exports.createARecord = createARecord;
638
+ module.exports.createSslTxtRecord = createSslTxtRecord;
639
+ module.exports.createTxtRecord = createTxtRecord;
640
+ module.exports.createNsMetadata = createNsMetadata;
641
+
642
+ // Export parsing functions
643
+ module.exports.parseNsMetadata = parseNsMetadata;
644
+ module.exports.extractARecords = extractARecords;
645
+ module.exports.extractSslHash = extractSslHash;
646
+ module.exports.extractTxtRecords = extractTxtRecords;
647
+ module.exports.extractTtl = extractTtl;
648
+ module.exports.getNsSummary = getNsSummary;
649
+ module.exports.hasNsRecords = hasNsRecords;
650
+
651
+ // Export metadata manipulation functions
652
+ module.exports.mergeNsMetadata = mergeNsMetadata;
653
+ module.exports.removeNsMetadata = removeNsMetadata;
654
+ module.exports.addARecord = addARecord;
655
+ module.exports.removeARecord = removeARecord;
656
+ module.exports.setSslHash = setSslHash;
657
+ module.exports.removeSslHash = removeSslHash;
658
+ module.exports.setTtl = setTtl;
package/lib/index.js CHANGED
@@ -8,6 +8,7 @@ var memo = require('./auth/memo');
8
8
  var aes = require('./auth/ecc/src/aes');
9
9
  var config = require('./config');
10
10
  var utils = require('./utils');
11
+ var dns = require('./dns');
11
12
 
12
13
  module.exports = {
13
14
  api: api,
@@ -17,5 +18,6 @@ module.exports = {
17
18
  memo: memo,
18
19
  aes: aes,
19
20
  config: config,
20
- utils: utils
21
+ utils: utils,
22
+ dns: dns
21
23
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "viz-js-lib",
3
- "version": "0.11.0",
3
+ "version": "0.12.4",
4
4
  "description": "viz.js the JavaScript Library with API support for VIZ blockchain",
5
5
  "main": "lib/index.js",
6
6
  "scripts": {
@@ -14,7 +14,8 @@
14
14
  },
15
15
  "browser": {
16
16
  "ws": false,
17
- "crypto": false
17
+ "crypto": false,
18
+ "async_hooks": false
18
19
  },
19
20
  "repository": {
20
21
  "type": "git",