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.
- package/.qoder/docs/spec/viz-dns-nameserver-spec.md +982 -0
- package/.qoder/docs/viz-cpp-node-docs/data-types.md +322 -0
- package/.qoder/docs/viz-cpp-node-docs/index.md +160 -0
- package/.qoder/docs/viz-cpp-node-docs/op-account-market.md +236 -0
- package/.qoder/docs/viz-cpp-node-docs/op-account.md +199 -0
- package/.qoder/docs/viz-cpp-node-docs/op-award.md +162 -0
- package/.qoder/docs/viz-cpp-node-docs/op-committee.md +193 -0
- package/.qoder/docs/viz-cpp-node-docs/op-content.md +157 -0
- package/.qoder/docs/viz-cpp-node-docs/op-escrow.md +224 -0
- package/.qoder/docs/viz-cpp-node-docs/op-invite.md +219 -0
- package/.qoder/docs/viz-cpp-node-docs/op-proposal.md +229 -0
- package/.qoder/docs/viz-cpp-node-docs/op-recovery.md +188 -0
- package/.qoder/docs/viz-cpp-node-docs/op-subscription.md +146 -0
- package/.qoder/docs/viz-cpp-node-docs/op-transfer-vesting.md +224 -0
- package/.qoder/docs/viz-cpp-node-docs/op-witness.md +252 -0
- package/.qoder/docs/viz-cpp-node-docs/plugins.md +887 -0
- package/.qoder/docs/viz-cpp-node-docs/virtual-operations.md +513 -0
- package/.qoder/repowiki/en/content/API Reference/API Reference.md +724 -0
- package/.qoder/repowiki/en/content/API Reference/Configuration Options.md +410 -0
- package/.qoder/repowiki/en/content/API Reference/Core API Methods.md +547 -0
- package/.qoder/repowiki/en/content/API Reference/Streaming APIs.md +380 -0
- package/.qoder/repowiki/en/content/API Reference/Transport Layer.md +341 -0
- package/.qoder/repowiki/en/content/API Reference/VIZ Blockchain Operations Coverage Status.md +427 -0
- package/.qoder/repowiki/en/content/Authentication & Cryptography/Authentication & Cryptography.md +430 -0
- package/.qoder/repowiki/en/content/Authentication & Cryptography/Digital Signatures.md +462 -0
- package/.qoder/repowiki/en/content/Authentication & Cryptography/Key Management.md +456 -0
- package/.qoder/repowiki/en/content/Authentication & Cryptography/Memo Encryption.md +331 -0
- package/.qoder/repowiki/en/content/Authentication & Cryptography/Security Practices.md +488 -0
- package/.qoder/repowiki/en/content/Broadcast Transactions/Broadcast Transactions.md +432 -0
- package/.qoder/repowiki/en/content/Broadcast Transactions/Network Broadcasting.md +418 -0
- package/.qoder/repowiki/en/content/Broadcast Transactions/Operation Construction.md +352 -0
- package/.qoder/repowiki/en/content/Broadcast Transactions/Transaction Preparation.md +353 -0
- package/.qoder/repowiki/en/content/Broadcast Transactions/Transaction Signing.md +404 -0
- package/.qoder/repowiki/en/content/Data Serialization/Data Serialization.md +540 -0
- package/.qoder/repowiki/en/content/Data Serialization/Encoding & Decoding.md +463 -0
- package/.qoder/repowiki/en/content/Data Serialization/Object Templates.md +413 -0
- package/.qoder/repowiki/en/content/Data Serialization/Type System.md +514 -0
- package/.qoder/repowiki/en/content/Data Serialization/Validation Rules.md +439 -0
- package/.qoder/repowiki/en/content/Examples & Tutorials.md +485 -0
- package/.qoder/repowiki/en/content/Getting Started.md +345 -0
- package/.qoder/repowiki/en/content/Testing & Development.md +637 -0
- package/.qoder/repowiki/en/content/Utilities & Helpers.md +557 -0
- package/.qoder/repowiki/en/meta/repowiki-metadata.json +1 -0
- package/VIZ-JS-LIB-COVERAGE-STATUS.md +356 -0
- package/config.json +3 -1
- package/dist/statistics.html +1 -1
- package/dist/viz-tests.min.js +32 -42
- package/dist/viz-tests.min.js.gz +0 -0
- package/dist/viz.min.js +8 -18
- package/dist/viz.min.js.gz +0 -0
- package/lib/api/methods.js +24 -0
- package/lib/auth/serializer/src/ChainTypes.js +2 -1
- package/lib/auth/serializer/src/operations.js +35 -2
- package/lib/broadcast/index.js +29 -15
- package/lib/broadcast/operations.js +4 -0
- package/lib/dns.js +658 -0
- package/lib/index.js +3 -1
- package/package.json +3 -2
- package/test/dns.test.js +395 -0
- 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.
|
|
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",
|