postchain-client 1.0.2 → 1.0.3
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/README.md +0 -27
- package/built/cjs/index.js +2571 -0
- package/built/cjs/index.js.map +1 -0
- package/built/esm/index.js +29927 -0
- package/built/esm/index.js.map +1 -0
- package/built/index.js +21 -3
- package/built/index.js.map +1 -0
- package/built/src/chromia/chromiaClientProvider.js +35 -0
- package/built/src/chromia/chromiaClientProvider.js.map +1 -0
- package/built/src/chromia/errors.js +6 -0
- package/built/src/chromia/errors.js.map +1 -0
- package/built/src/chromia/interfaces.js +2 -0
- package/built/src/chromia/interfaces.js.map +1 -0
- package/built/src/encryption/encryption.js +105 -0
- package/built/src/encryption/encryption.js.map +1 -0
- package/built/src/encryption/errors.js +11 -0
- package/built/src/encryption/errors.js.map +1 -0
- package/built/src/encryption/types.js +2 -0
- package/built/src/encryption/types.js.map +1 -0
- package/built/src/formatter.d.ts +2 -0
- package/built/src/formatter.js +119 -0
- package/built/src/formatter.js.map +1 -0
- package/built/src/gtv/definition.js +20 -0
- package/built/src/gtv/definition.js.map +1 -0
- package/built/src/gtv/index.d.ts +1 -0
- package/built/src/gtv/index.js +11 -0
- package/built/src/gtv/index.js.map +1 -0
- package/built/src/gtv/types.d.ts +2 -3
- package/built/src/gtv/types.js +2 -0
- package/built/src/gtv/types.js.map +1 -0
- package/built/src/gtx/errors.js +26 -0
- package/built/src/gtx/errors.js.map +1 -0
- package/built/src/gtx/gtx.d.ts +1 -1
- package/built/src/gtx/gtx.js +115 -0
- package/built/src/gtx/gtx.js.map +1 -0
- package/built/src/gtx/gtxclient.js +77 -0
- package/built/src/gtx/gtxclient.js.map +1 -0
- package/built/src/gtx/index.js +5 -0
- package/built/src/gtx/index.js.map +1 -0
- package/built/src/gtx/interfaces.js +2 -0
- package/built/src/gtx/interfaces.js.map +1 -0
- package/built/src/gtx/serialization.d.ts +3 -2
- package/built/src/gtx/serialization.js +95 -0
- package/built/src/gtx/serialization.js.map +1 -0
- package/built/src/gtx/types.d.ts +10 -1
- package/built/src/gtx/types.js +2 -0
- package/built/src/gtx/types.js.map +1 -0
- package/built/src/logger.d.ts +2 -1
- package/built/src/logger.js +53 -0
- package/built/src/logger.js.map +1 -0
- package/built/src/merkle/binarytree.d.ts +137 -0
- package/built/src/merkle/binarytree.js +146 -0
- package/built/src/merkle/binarytree.js.map +1 -0
- package/built/src/merkle/binarytreefactory.d.ts +86 -0
- package/built/src/merkle/binarytreefactory.js +235 -0
- package/built/src/merkle/binarytreefactory.js.map +1 -0
- package/built/src/merkle/merkleHelper.js +109 -0
- package/built/src/merkle/merkleHelper.js.map +1 -0
- package/built/src/merkle/merklehashcalculator.d.ts +35 -0
- package/built/src/merkle/merklehashcalculator.js +71 -0
- package/built/src/merkle/merklehashcalculator.js.map +1 -0
- package/built/src/merkle/path.d.ts +155 -0
- package/built/src/merkle/path.js +306 -0
- package/built/src/merkle/path.js.map +1 -0
- package/built/src/merkle/proof/merklehashcarrier.d.ts +17 -0
- package/built/src/merkle/proof/merklehashcarrier.js +23 -0
- package/built/src/merkle/proof/merklehashcarrier.js.map +1 -0
- package/built/src/merkle/proof/merklehashsummaryfactory.d.ts +53 -0
- package/built/src/merkle/proof/merklehashsummaryfactory.js +81 -0
- package/built/src/merkle/proof/merklehashsummaryfactory.js.map +1 -0
- package/built/src/merkle/proof/merkleproof.d.ts +35 -0
- package/built/src/merkle/proof/merkleproof.js +59 -0
- package/built/src/merkle/proof/merkleproof.js.map +1 -0
- package/built/src/merkle/proof/merkleprooftree.d.ts +130 -0
- package/built/src/merkle/proof/merkleprooftree.js +116 -0
- package/built/src/merkle/proof/merkleprooftree.js.map +1 -0
- package/built/src/merkle/proof/merkleprooftreefactory.d.ts +47 -0
- package/built/src/merkle/proof/merkleprooftreefactory.js +121 -0
- package/built/src/merkle/proof/merkleprooftreefactory.js.map +1 -0
- package/built/src/merkle/types.js +2 -0
- package/built/src/merkle/types.js.map +1 -0
- package/built/src/restclient/errors.js +54 -0
- package/built/src/restclient/errors.js.map +1 -0
- package/built/src/restclient/interfaces.d.ts +2 -1
- package/built/src/restclient/interfaces.js +2 -0
- package/built/src/restclient/interfaces.js.map +1 -0
- package/built/src/restclient/restclient.js +309 -0
- package/built/src/restclient/restclient.js.map +1 -0
- package/built/src/restclient/restclientutil.d.ts +4 -0
- package/built/src/restclient/restclientutil.js +137 -0
- package/built/src/restclient/restclientutil.js.map +1 -0
- package/built/src/restclient/types.d.ts +4 -0
- package/built/src/restclient/types.js +13 -0
- package/built/src/restclient/types.js.map +1 -0
- package/built/umd/index.js +29931 -0
- package/built/umd/index.js.map +1 -0
- package/package.json +26 -16
- package/built/index.js.LICENSE.txt +0 -657
|
@@ -0,0 +1,2571 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var bn_js = require('bn.js');
|
|
4
|
+
var crypto = require('crypto');
|
|
5
|
+
var secp256k1$1 = require('secp256k1');
|
|
6
|
+
|
|
7
|
+
function _interopNamespaceDefault(e) {
|
|
8
|
+
var n = Object.create(null);
|
|
9
|
+
if (e) {
|
|
10
|
+
Object.keys(e).forEach(function (k) {
|
|
11
|
+
if (k !== 'default') {
|
|
12
|
+
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
13
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
14
|
+
enumerable: true,
|
|
15
|
+
get: function () { return e[k]; }
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
n.default = e;
|
|
21
|
+
return Object.freeze(n);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
var crypto__namespace = /*#__PURE__*/_interopNamespaceDefault(crypto);
|
|
25
|
+
var secp256k1__namespace = /*#__PURE__*/_interopNamespaceDefault(secp256k1$1);
|
|
26
|
+
|
|
27
|
+
function getAugmentedNamespace(n) {
|
|
28
|
+
if (n.__esModule) return n;
|
|
29
|
+
var f = n.default;
|
|
30
|
+
if (typeof f == "function") {
|
|
31
|
+
var a = function a () {
|
|
32
|
+
if (this instanceof a) {
|
|
33
|
+
var args = [null];
|
|
34
|
+
args.push.apply(args, arguments);
|
|
35
|
+
var Ctor = Function.bind.apply(f, args);
|
|
36
|
+
return new Ctor();
|
|
37
|
+
}
|
|
38
|
+
return f.apply(this, arguments);
|
|
39
|
+
};
|
|
40
|
+
a.prototype = f.prototype;
|
|
41
|
+
} else a = {};
|
|
42
|
+
Object.defineProperty(a, '__esModule', {value: true});
|
|
43
|
+
Object.keys(n).forEach(function (k) {
|
|
44
|
+
var d = Object.getOwnPropertyDescriptor(n, k);
|
|
45
|
+
Object.defineProperty(a, k, d.get ? d : {
|
|
46
|
+
enumerable: true,
|
|
47
|
+
get: function () {
|
|
48
|
+
return n[k];
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
return a;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
56
|
+
const asn = require("asn1.js/lib/asn1");
|
|
57
|
+
const ASNDictPair = asn.define("DictPair", function () {
|
|
58
|
+
this.seq().obj(this.key("name").utf8str(), this.key("value").use(rawGTV));
|
|
59
|
+
});
|
|
60
|
+
const rawGTV = asn.define("GtvValue", function () {
|
|
61
|
+
this.choice({
|
|
62
|
+
null: this.explicit(0).null_(),
|
|
63
|
+
byteArray: this.explicit(1).octstr(),
|
|
64
|
+
string: this.explicit(2).utf8str(),
|
|
65
|
+
integer: this.explicit(3).int(),
|
|
66
|
+
dict: this.explicit(4).seqof(ASNDictPair),
|
|
67
|
+
array: this.explicit(5).seqof(rawGTV),
|
|
68
|
+
bigInteger: this.explicit(6).int(),
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
asn.define("Buffer", function () {
|
|
72
|
+
this.octstr();
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
class UnexpectedArgumentTypeError extends Error {
|
|
76
|
+
constructor(typedArg) {
|
|
77
|
+
super(`Cannot parse typedArg ${JSON.stringify(typedArg)}. Unknown type ${typedArg.type}`);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
class MissingGtxException extends Error {
|
|
81
|
+
constructor() {
|
|
82
|
+
super(`Missing instance of gtx protocol (used for communicating with postchain) to add operation to`);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
class AlreadySignedTransactionException extends Error {
|
|
86
|
+
constructor(operation) {
|
|
87
|
+
super(`Cannot add ${operation} calls to an already signed gtx`);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
class NumberOfSignersAndSignaturesException extends Error {
|
|
91
|
+
constructor() {
|
|
92
|
+
super(`Not matching number of signers and signatures`);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
class MissingSignerException extends Error {
|
|
96
|
+
constructor() {
|
|
97
|
+
super(`No such signer, remember to call addSignerToGtx() before adding a signature`);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function pgBytes(buffer) {
|
|
102
|
+
if (!Buffer.isBuffer(buffer)) {
|
|
103
|
+
throw new PgBytesInputException(buffer);
|
|
104
|
+
}
|
|
105
|
+
return "\\x" + buffer.toString("hex");
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Converts hex string to Buffer
|
|
109
|
+
* @param key: string
|
|
110
|
+
* @returns {Buffer}
|
|
111
|
+
*/
|
|
112
|
+
function toBuffer(key) {
|
|
113
|
+
return Buffer.from(key, "hex");
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Converts Buffer to hex string
|
|
117
|
+
* @param buffer: Buffer
|
|
118
|
+
* @returns {string}
|
|
119
|
+
*/
|
|
120
|
+
function toString(buffer) {
|
|
121
|
+
return buffer.toString("hex");
|
|
122
|
+
}
|
|
123
|
+
function toQueryObjectGTV(object) {
|
|
124
|
+
const objectCopy = Object.assign({}, object);
|
|
125
|
+
const name = objectCopy.type;
|
|
126
|
+
delete objectCopy.type;
|
|
127
|
+
return [name, objectCopy];
|
|
128
|
+
}
|
|
129
|
+
class PgBytesInputException extends Error {
|
|
130
|
+
constructor(buffer) {
|
|
131
|
+
super(`util.pgBytes expects a buffer, but got ${typeof buffer}`);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
function ensureBuffer(value) {
|
|
135
|
+
if (value instanceof Buffer) {
|
|
136
|
+
return value;
|
|
137
|
+
}
|
|
138
|
+
else {
|
|
139
|
+
return toBuffer(value);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
function checkGtvType(value) {
|
|
143
|
+
try {
|
|
144
|
+
if (value == null) {
|
|
145
|
+
return true;
|
|
146
|
+
}
|
|
147
|
+
if (Buffer.isBuffer(value)) {
|
|
148
|
+
return true;
|
|
149
|
+
}
|
|
150
|
+
if (typeof value === "string") {
|
|
151
|
+
return true;
|
|
152
|
+
}
|
|
153
|
+
if (typeof value === "number") {
|
|
154
|
+
if (!Number.isInteger(value)) {
|
|
155
|
+
throw Error("User error: Only integers are supported");
|
|
156
|
+
}
|
|
157
|
+
return true;
|
|
158
|
+
}
|
|
159
|
+
if (typeof value === "bigint") {
|
|
160
|
+
return true;
|
|
161
|
+
}
|
|
162
|
+
if (value.constructor === Array) {
|
|
163
|
+
value.map((item) => checkGtvType(item));
|
|
164
|
+
return true;
|
|
165
|
+
}
|
|
166
|
+
if (typeof value === "object") {
|
|
167
|
+
Object.keys(value).map(function (key) {
|
|
168
|
+
checkGtvType(value[key]);
|
|
169
|
+
});
|
|
170
|
+
return true;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
catch (error) {
|
|
174
|
+
throw new Error(`Failed to check type: ${error}`);
|
|
175
|
+
}
|
|
176
|
+
return false;
|
|
177
|
+
}
|
|
178
|
+
function rawGtxToGtx(rawGtx) {
|
|
179
|
+
const rawGtxBody = rawGtx[0];
|
|
180
|
+
const signatures = rawGtx[1];
|
|
181
|
+
const gtxBody = {
|
|
182
|
+
blockchainRID: rawGtxBody[0],
|
|
183
|
+
operations: rawGtxBody[1].map((operation) => ({
|
|
184
|
+
opName: operation[0],
|
|
185
|
+
args: operation[1],
|
|
186
|
+
})),
|
|
187
|
+
signers: rawGtxBody[2],
|
|
188
|
+
};
|
|
189
|
+
return {
|
|
190
|
+
blockchainRID: gtxBody.blockchainRID,
|
|
191
|
+
operations: gtxBody.operations,
|
|
192
|
+
signers: gtxBody.signers,
|
|
193
|
+
signatures,
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
function checkGtxType(value) {
|
|
197
|
+
try {
|
|
198
|
+
rawGtxToGtx(value);
|
|
199
|
+
return true;
|
|
200
|
+
}
|
|
201
|
+
catch (error) {
|
|
202
|
+
return false;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
function removeDuplicateSigners(signers) {
|
|
206
|
+
const signersAsString = [];
|
|
207
|
+
signers.forEach((item) => {
|
|
208
|
+
const itemAsString = item.toString("hex");
|
|
209
|
+
if (!signersAsString.includes(itemAsString)) {
|
|
210
|
+
signersAsString.push(itemAsString);
|
|
211
|
+
}
|
|
212
|
+
});
|
|
213
|
+
const result = [];
|
|
214
|
+
signersAsString.forEach((item) => {
|
|
215
|
+
result.push(Buffer.from(item, "hex"));
|
|
216
|
+
});
|
|
217
|
+
return result;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
var formatter = /*#__PURE__*/Object.freeze({
|
|
221
|
+
__proto__: null,
|
|
222
|
+
PgBytesInputException: PgBytesInputException,
|
|
223
|
+
checkGtvType: checkGtvType,
|
|
224
|
+
checkGtxType: checkGtxType,
|
|
225
|
+
ensureBuffer: ensureBuffer,
|
|
226
|
+
pgBytes: pgBytes,
|
|
227
|
+
rawGtxToGtx: rawGtxToGtx,
|
|
228
|
+
removeDuplicateSigners: removeDuplicateSigners,
|
|
229
|
+
toBuffer: toBuffer,
|
|
230
|
+
toQueryObjectGTV: toQueryObjectGTV,
|
|
231
|
+
toString: toString
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
function encodeValue(rawGtv) {
|
|
235
|
+
return rawGTV.encode(createTypedArg(rawGtv));
|
|
236
|
+
}
|
|
237
|
+
function encodeValueGtx(rawGtx) {
|
|
238
|
+
return encodeValue(rawGtx);
|
|
239
|
+
}
|
|
240
|
+
function decodeValue(bytes) {
|
|
241
|
+
const obj = rawGTV.decode(bytes);
|
|
242
|
+
return parseValue(obj);
|
|
243
|
+
}
|
|
244
|
+
function decodeValueGtx(bytes) {
|
|
245
|
+
const decodedValue = decodeValue(bytes);
|
|
246
|
+
if (!checkGtxType(decodedValue)) {
|
|
247
|
+
throw new Error(`Unexpected type of value: ${decodedValue}, expected decoded value to be of type RawGtx`);
|
|
248
|
+
}
|
|
249
|
+
return decodedValue;
|
|
250
|
+
}
|
|
251
|
+
function parseValue(typedArg) {
|
|
252
|
+
if (typedArg.type === "null") {
|
|
253
|
+
return null;
|
|
254
|
+
}
|
|
255
|
+
else if (typedArg.type === "byteArray") {
|
|
256
|
+
return typedArg.value;
|
|
257
|
+
}
|
|
258
|
+
else if (typedArg.type === "string") {
|
|
259
|
+
return typedArg.value;
|
|
260
|
+
}
|
|
261
|
+
else if (typedArg.type === "integer") {
|
|
262
|
+
return Number(typedArg.value);
|
|
263
|
+
}
|
|
264
|
+
else if (typedArg.type === "array") {
|
|
265
|
+
const arrayValue = typedArg.value;
|
|
266
|
+
return arrayValue.map((item) => parseValue(item));
|
|
267
|
+
}
|
|
268
|
+
else if (typedArg.type === "bigInteger") {
|
|
269
|
+
return BigInt(typedArg.value);
|
|
270
|
+
}
|
|
271
|
+
else if (typedArg.type === "dict") {
|
|
272
|
+
const arrayValue = typedArg.value;
|
|
273
|
+
const result = {};
|
|
274
|
+
arrayValue.forEach((pair) => {
|
|
275
|
+
result[pair.name] = parseValue(pair.value);
|
|
276
|
+
});
|
|
277
|
+
return result;
|
|
278
|
+
}
|
|
279
|
+
else {
|
|
280
|
+
throw new UnexpectedArgumentTypeError(typedArg);
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
function createTypedArg(value) {
|
|
284
|
+
try {
|
|
285
|
+
if (value == null) {
|
|
286
|
+
return { type: "null", value: null };
|
|
287
|
+
}
|
|
288
|
+
if (Buffer.isBuffer(value)) {
|
|
289
|
+
return { type: "byteArray", value: value };
|
|
290
|
+
}
|
|
291
|
+
if (typeof value === "boolean") {
|
|
292
|
+
return { type: "integer", value: value ? 1 : 0 };
|
|
293
|
+
}
|
|
294
|
+
if (typeof value === "string") {
|
|
295
|
+
return { type: "string", value: value };
|
|
296
|
+
}
|
|
297
|
+
if (typeof value === "number") {
|
|
298
|
+
if (!Number.isInteger(value)) {
|
|
299
|
+
throw Error("User error: Only integers are supported");
|
|
300
|
+
}
|
|
301
|
+
return { type: "integer", value: new bn_js.BN(value) };
|
|
302
|
+
}
|
|
303
|
+
if (typeof value === "bigint") {
|
|
304
|
+
return { type: "bigInteger", value: new bn_js.BN(Number(value)) };
|
|
305
|
+
}
|
|
306
|
+
if (value.constructor === Array) {
|
|
307
|
+
return {
|
|
308
|
+
type: "array",
|
|
309
|
+
value: value.map((item) => createTypedArg(item)),
|
|
310
|
+
};
|
|
311
|
+
}
|
|
312
|
+
if (typeof value === "object") {
|
|
313
|
+
const valueAsDictPair = value;
|
|
314
|
+
return { type: "dict", value: Object.keys(valueAsDictPair).map(function (key) {
|
|
315
|
+
return { name: key, value: createTypedArg(valueAsDictPair[key]) };
|
|
316
|
+
}) };
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
catch (error) {
|
|
320
|
+
throw new Error(`Failed to encode ${value.toString()}: ${error}`);
|
|
321
|
+
}
|
|
322
|
+
throw new Error(`value ${value} have unsupported type: ${typeof value}`);
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
var serialization$1 = /*#__PURE__*/Object.freeze({
|
|
326
|
+
__proto__: null,
|
|
327
|
+
createTypedArg: createTypedArg,
|
|
328
|
+
decodeValue: decodeValue,
|
|
329
|
+
decodeValueGtx: decodeValueGtx,
|
|
330
|
+
encodeValue: encodeValue,
|
|
331
|
+
encodeValueGtx: encodeValueGtx,
|
|
332
|
+
parseValue: parseValue
|
|
333
|
+
});
|
|
334
|
+
|
|
335
|
+
var require$$0$1 = /*@__PURE__*/getAugmentedNamespace(serialization$1);
|
|
336
|
+
|
|
337
|
+
var require$$0 = /*@__PURE__*/getAugmentedNamespace(formatter);
|
|
338
|
+
|
|
339
|
+
var util$1 = require$$0;
|
|
340
|
+
function PathElement(previous) {
|
|
341
|
+
this.previous = previous;
|
|
342
|
+
}
|
|
343
|
+
PathElement.prototype.getSearchKey = function () { };
|
|
344
|
+
function PathLeafElement$3(previous) {
|
|
345
|
+
PathElement.call(this, previous);
|
|
346
|
+
}
|
|
347
|
+
PathLeafElement$3.prototype = Object.create(PathElement.prototype);
|
|
348
|
+
PathLeafElement$3.prototype.constructor = PathLeafElement$3;
|
|
349
|
+
PathLeafElement$3.prototype.equals = function (other) {
|
|
350
|
+
if (this === other)
|
|
351
|
+
return true;
|
|
352
|
+
if (typeof this !== typeof other)
|
|
353
|
+
return false;
|
|
354
|
+
return true;
|
|
355
|
+
};
|
|
356
|
+
function SearchablePathElement(previous) {
|
|
357
|
+
PathElement.call(this, previous);
|
|
358
|
+
}
|
|
359
|
+
SearchablePathElement.prototype = Object.create(PathElement.prototype);
|
|
360
|
+
SearchablePathElement.prototype.constructor = SearchablePathElement;
|
|
361
|
+
SearchablePathElement.prototype.getSearchKey = function () { };
|
|
362
|
+
/**
|
|
363
|
+
*
|
|
364
|
+
* @param {SearchablePathElement} previous
|
|
365
|
+
* @param {number} index
|
|
366
|
+
*/
|
|
367
|
+
function ArrayPathElement(previous, index) {
|
|
368
|
+
SearchablePathElement.call(this, previous);
|
|
369
|
+
this.index = index;
|
|
370
|
+
}
|
|
371
|
+
ArrayPathElement.prototype = Object.create(SearchablePathElement.prototype);
|
|
372
|
+
ArrayPathElement.prototype.constructor = ArrayPathElement;
|
|
373
|
+
ArrayPathElement.prototype.getSearchKey = function () {
|
|
374
|
+
return this.index;
|
|
375
|
+
};
|
|
376
|
+
/**
|
|
377
|
+
* @param {ArrayPathElement} other
|
|
378
|
+
*/
|
|
379
|
+
ArrayPathElement.prototype.equals = function (other) {
|
|
380
|
+
if (this === other)
|
|
381
|
+
return true;
|
|
382
|
+
if (typeof this !== typeof other)
|
|
383
|
+
return false;
|
|
384
|
+
if (this.index != other.index)
|
|
385
|
+
return false;
|
|
386
|
+
return true;
|
|
387
|
+
};
|
|
388
|
+
/**
|
|
389
|
+
*
|
|
390
|
+
* @param {SearchablePathElement} previous
|
|
391
|
+
* @param {string} key
|
|
392
|
+
*/
|
|
393
|
+
function DictPathElement(previous, key) {
|
|
394
|
+
SearchablePathElement.call(this, previous);
|
|
395
|
+
this.key = key;
|
|
396
|
+
}
|
|
397
|
+
DictPathElement.prototype = Object.create(SearchablePathElement.prototype);
|
|
398
|
+
DictPathElement.prototype.constructor = DictPathElement;
|
|
399
|
+
DictPathElement.prototype.getSearchKey = function () {
|
|
400
|
+
return this.key;
|
|
401
|
+
};
|
|
402
|
+
/**
|
|
403
|
+
* @param {DictPathElement} other
|
|
404
|
+
*/
|
|
405
|
+
DictPathElement.prototype.equals = function (other) {
|
|
406
|
+
if (this === other)
|
|
407
|
+
return true;
|
|
408
|
+
if (typeof this !== typeof other)
|
|
409
|
+
return false;
|
|
410
|
+
if (this.key != other.key)
|
|
411
|
+
return false;
|
|
412
|
+
return true;
|
|
413
|
+
};
|
|
414
|
+
/**
|
|
415
|
+
*
|
|
416
|
+
* @param {Array} pathElements
|
|
417
|
+
*/
|
|
418
|
+
function Path(pathElements) {
|
|
419
|
+
this.pathElements = pathElements;
|
|
420
|
+
}
|
|
421
|
+
/**
|
|
422
|
+
*
|
|
423
|
+
*/
|
|
424
|
+
Path.prototype.getCurrentPathElement = function () {
|
|
425
|
+
return this.pathElements[0];
|
|
426
|
+
};
|
|
427
|
+
/**
|
|
428
|
+
*
|
|
429
|
+
*/
|
|
430
|
+
Path.prototype.size = function () {
|
|
431
|
+
return this.pathElements.length;
|
|
432
|
+
};
|
|
433
|
+
/**
|
|
434
|
+
*
|
|
435
|
+
*/
|
|
436
|
+
Path.prototype.tail = function () {
|
|
437
|
+
if (this.pathElements.length == 0) {
|
|
438
|
+
throw new Error("Impossible to tail this array");
|
|
439
|
+
}
|
|
440
|
+
else {
|
|
441
|
+
var tail = this.pathElements.slice(1);
|
|
442
|
+
return new Path(tail);
|
|
443
|
+
}
|
|
444
|
+
};
|
|
445
|
+
Path.prototype.debugString = function () {
|
|
446
|
+
var sb = "";
|
|
447
|
+
this.pathElements.forEach(elem => {
|
|
448
|
+
if (elem instanceof SearchablePathElement) {
|
|
449
|
+
sb = sb + "-> " + elem.getSearchKey();
|
|
450
|
+
}
|
|
451
|
+
else if (elem instanceof PathLeafElement$3) {
|
|
452
|
+
sb = sb + "-> Leaf";
|
|
453
|
+
}
|
|
454
|
+
});
|
|
455
|
+
return sb;
|
|
456
|
+
};
|
|
457
|
+
/**
|
|
458
|
+
* @param {Path} other
|
|
459
|
+
*/
|
|
460
|
+
Path.prototype.equals = function (other) {
|
|
461
|
+
if (this === other)
|
|
462
|
+
return true;
|
|
463
|
+
if (typeof this != typeof other)
|
|
464
|
+
return false;
|
|
465
|
+
return this.pathElements == other.pathElements;
|
|
466
|
+
};
|
|
467
|
+
/**
|
|
468
|
+
* @param {number} index
|
|
469
|
+
* @param {Path} path
|
|
470
|
+
*/
|
|
471
|
+
var getTailIfFirstElementIsArrayOfThisIndex = function (index, path) {
|
|
472
|
+
return getTail(index, path);
|
|
473
|
+
};
|
|
474
|
+
/**
|
|
475
|
+
*
|
|
476
|
+
* @param {string} key
|
|
477
|
+
* @param {Path} path
|
|
478
|
+
*/
|
|
479
|
+
var getTailIfFirstElementIsDictOfThisKey = function (key, path) {
|
|
480
|
+
return getTail(key, path);
|
|
481
|
+
};
|
|
482
|
+
/**
|
|
483
|
+
*
|
|
484
|
+
* @param {string|number} searchKey
|
|
485
|
+
* @param {Path} path
|
|
486
|
+
*/
|
|
487
|
+
var getTail = function (searchKey, path) {
|
|
488
|
+
if (searchKey === null) {
|
|
489
|
+
throw new Error("Have to provide a search key");
|
|
490
|
+
}
|
|
491
|
+
try {
|
|
492
|
+
var firstElement = path.pathElements[0];
|
|
493
|
+
if (firstElement instanceof SearchablePathElement) {
|
|
494
|
+
if (firstElement.getSearchKey() == searchKey) {
|
|
495
|
+
return path.tail();
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
catch (err) {
|
|
500
|
+
util$1.logError("Why are we dropping first element of an empty path? " + err);
|
|
501
|
+
return null;
|
|
502
|
+
}
|
|
503
|
+
return null;
|
|
504
|
+
};
|
|
505
|
+
/**
|
|
506
|
+
*
|
|
507
|
+
* @param {Array} paths
|
|
508
|
+
*/
|
|
509
|
+
function PathSet$1(paths) {
|
|
510
|
+
this.paths = paths;
|
|
511
|
+
}
|
|
512
|
+
/**
|
|
513
|
+
*
|
|
514
|
+
*/
|
|
515
|
+
PathSet$1.prototype.isEmpty = function () {
|
|
516
|
+
return this.paths.length == 0;
|
|
517
|
+
};
|
|
518
|
+
/**
|
|
519
|
+
*
|
|
520
|
+
*/
|
|
521
|
+
PathSet$1.prototype.getPathLeafOrElseAnyCurrentPathElement = function () {
|
|
522
|
+
var leafElem = null;
|
|
523
|
+
var currElem = null;
|
|
524
|
+
var prev = {
|
|
525
|
+
"path": null,
|
|
526
|
+
"elem": null,
|
|
527
|
+
};
|
|
528
|
+
this.paths.forEach(path => {
|
|
529
|
+
currElem = path.getCurrentPathElement();
|
|
530
|
+
if (currElem instanceof PathLeafElement$3) {
|
|
531
|
+
leafElem = currElem;
|
|
532
|
+
}
|
|
533
|
+
prev = this.errorCheckUnequalParent(path, currElem, prev.path, prev.elem);
|
|
534
|
+
});
|
|
535
|
+
if (leafElem != null) {
|
|
536
|
+
return leafElem;
|
|
537
|
+
}
|
|
538
|
+
else {
|
|
539
|
+
return currElem; // It doesn't matter which one we return (Next step we will get the "previous" from this one)
|
|
540
|
+
}
|
|
541
|
+
};
|
|
542
|
+
/**
|
|
543
|
+
* Yeah, this might be a completely un-needed check (but it MIGHT save us later on if we forget this rule).
|
|
544
|
+
* What we are looking for here is an impossible state where two paths in the same set don't have the same parent.
|
|
545
|
+
* (Since we usually only have one path in a path set, this check should be cheap)
|
|
546
|
+
*
|
|
547
|
+
* @param {Path} currPath
|
|
548
|
+
* @param {PathElement} currElem
|
|
549
|
+
* @param {Path} prevPath
|
|
550
|
+
* @param {PathElement} prevElem
|
|
551
|
+
*/
|
|
552
|
+
PathSet$1.prototype.errorCheckUnequalParent = function (currPath, currElem, prevPath, prevElem) {
|
|
553
|
+
if (prevElem != null) {
|
|
554
|
+
// weird: javascript cannot compare null == null then we have to compare each with null separately :(
|
|
555
|
+
if (currElem.previous == null && prevElem.previous == null) {
|
|
556
|
+
return {
|
|
557
|
+
"path": currPath,
|
|
558
|
+
"elem": currElem
|
|
559
|
+
};
|
|
560
|
+
}
|
|
561
|
+
else if ((currElem.previous == null && prevElem.previous != null) || (currElem.previous != null && prevElem.previous == null)) {
|
|
562
|
+
throw new Error("Something is wrong, these paths do not have the same parent. (" + currPath + ") (" + prevPath + ")");
|
|
563
|
+
}
|
|
564
|
+
else if (!currElem.previous.equals(prevElem.previous)) {
|
|
565
|
+
throw new Error("Something is wrong, these paths do not have the same parent. (" + currPath + ") (" + prevPath + ")");
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
return {
|
|
569
|
+
"path": currPath,
|
|
570
|
+
"elem": currElem
|
|
571
|
+
};
|
|
572
|
+
};
|
|
573
|
+
/**
|
|
574
|
+
*
|
|
575
|
+
*/
|
|
576
|
+
PathSet$1.prototype.keepOnlyArrayPaths = function () {
|
|
577
|
+
var filteredPaths = this.paths.filter(path => {
|
|
578
|
+
return path.pathElements[0] instanceof ArrayPathElement;
|
|
579
|
+
});
|
|
580
|
+
return new PathSet$1(filteredPaths);
|
|
581
|
+
};
|
|
582
|
+
/**
|
|
583
|
+
*
|
|
584
|
+
*/
|
|
585
|
+
PathSet$1.prototype.keepOnlyDictPaths = function () {
|
|
586
|
+
var filteredPaths = this.paths.filter(path => {
|
|
587
|
+
return path.pathElements[0] instanceof DictPathElement;
|
|
588
|
+
});
|
|
589
|
+
return new PathSet$1(filteredPaths);
|
|
590
|
+
};
|
|
591
|
+
/**
|
|
592
|
+
*
|
|
593
|
+
*/
|
|
594
|
+
PathSet$1.prototype.getTailIfFirstElementIsArrayOfThisIndexFromList = function (index) {
|
|
595
|
+
return this.getTailFromList(index, getTailIfFirstElementIsArrayOfThisIndex);
|
|
596
|
+
};
|
|
597
|
+
/**
|
|
598
|
+
*
|
|
599
|
+
*/
|
|
600
|
+
PathSet$1.prototype.getTailIfFirstElementIsDictOfThisKeyFromList = function (key) {
|
|
601
|
+
return this.getTailFromList(key, getTailIfFirstElementIsDictOfThisKey);
|
|
602
|
+
};
|
|
603
|
+
/**
|
|
604
|
+
*
|
|
605
|
+
*/
|
|
606
|
+
PathSet$1.prototype.getTailFromList = function (searchKey, filterFunc) {
|
|
607
|
+
var retPaths = new Array();
|
|
608
|
+
this.paths.forEach(path => {
|
|
609
|
+
var newPath = filterFunc(searchKey, path);
|
|
610
|
+
if (newPath != null) {
|
|
611
|
+
retPaths.push(newPath);
|
|
612
|
+
}
|
|
613
|
+
});
|
|
614
|
+
return new PathSet$1(retPaths);
|
|
615
|
+
};
|
|
616
|
+
/**
|
|
617
|
+
*
|
|
618
|
+
* @param {Array} arr
|
|
619
|
+
*/
|
|
620
|
+
var buildPathFromArray = function (arr) {
|
|
621
|
+
var pathElements = new Array();
|
|
622
|
+
var lastPathElem = null;
|
|
623
|
+
arr.forEach(item => {
|
|
624
|
+
var newElem = null;
|
|
625
|
+
if (typeof item === 'number') {
|
|
626
|
+
newElem = new ArrayPathElement(lastPathElem, item);
|
|
627
|
+
}
|
|
628
|
+
else if (typeof item === 'string') {
|
|
629
|
+
newElem = new DictPathElement(lastPathElem, item);
|
|
630
|
+
}
|
|
631
|
+
else {
|
|
632
|
+
throw new Error("A path structure must only consist of Ints and Strings, not " + item);
|
|
633
|
+
}
|
|
634
|
+
pathElements.push(newElem);
|
|
635
|
+
lastPathElem = newElem;
|
|
636
|
+
});
|
|
637
|
+
var lastOne = lastPathElem;
|
|
638
|
+
pathElements.push(new PathLeafElement$3(lastOne));
|
|
639
|
+
return new Path(pathElements);
|
|
640
|
+
};
|
|
641
|
+
var path = { Path, PathElement, PathLeafElement: PathLeafElement$3, ArrayPathElement, SearchablePathElement, DictPathElement, PathSet: PathSet$1,
|
|
642
|
+
getTailIfFirstElementIsArrayOfThisIndex, buildPathFromArray };
|
|
643
|
+
|
|
644
|
+
var PathLeafElement$2 = path.PathLeafElement;
|
|
645
|
+
const HASH_PREFIX_NODE$1 = 0;
|
|
646
|
+
const HASH_PREFIX_LEAF$1 = 1;
|
|
647
|
+
const HASH_PREFIX_NODE_ARRAY$1 = 7;
|
|
648
|
+
const HASH_PREFIX_NODE_DICT$1 = 8;
|
|
649
|
+
/**
|
|
650
|
+
*
|
|
651
|
+
*/
|
|
652
|
+
function BinaryTreeElement() {
|
|
653
|
+
this.pathElem = null;
|
|
654
|
+
}
|
|
655
|
+
BinaryTreeElement.prototype.isPath = function () {
|
|
656
|
+
return this.pathElem != null;
|
|
657
|
+
};
|
|
658
|
+
BinaryTreeElement.prototype.isPathLeaf = function () {
|
|
659
|
+
if (this.pathElem == null) {
|
|
660
|
+
return false;
|
|
661
|
+
}
|
|
662
|
+
if (this.pathElem instanceof PathLeafElement$2) {
|
|
663
|
+
return true;
|
|
664
|
+
}
|
|
665
|
+
else {
|
|
666
|
+
return false;
|
|
667
|
+
}
|
|
668
|
+
};
|
|
669
|
+
BinaryTreeElement.prototype.setPathElement = function (pathElem) {
|
|
670
|
+
this.pathElem = pathElem;
|
|
671
|
+
};
|
|
672
|
+
BinaryTreeElement.prototype.getPrefixByte = function () {
|
|
673
|
+
return HASH_PREFIX_NODE$1;
|
|
674
|
+
};
|
|
675
|
+
/**
|
|
676
|
+
*
|
|
677
|
+
* @param {BinaryTreeElement} left
|
|
678
|
+
* @param {BinaryTreeElement} right
|
|
679
|
+
*/
|
|
680
|
+
function Node$2(left, right) {
|
|
681
|
+
this.left = left;
|
|
682
|
+
this.right = right;
|
|
683
|
+
}
|
|
684
|
+
Node$2.prototype = Object.create(BinaryTreeElement.prototype);
|
|
685
|
+
Node$2.prototype.constructor = Node$2;
|
|
686
|
+
Node$2.prototype.getPrefixByte = function () {
|
|
687
|
+
return HASH_PREFIX_NODE$1;
|
|
688
|
+
};
|
|
689
|
+
/**
|
|
690
|
+
*
|
|
691
|
+
* @param {BinaryTreeElement} left
|
|
692
|
+
* @param {BinaryTreeElement} right
|
|
693
|
+
* @param {*} content
|
|
694
|
+
* @param {PathSet} pathElem
|
|
695
|
+
*/
|
|
696
|
+
function SubTreeRootNode$1(left, right, content, pathElem) {
|
|
697
|
+
Node$2.call(this, left, right);
|
|
698
|
+
this.content = content;
|
|
699
|
+
BinaryTreeElement.prototype.setPathElement.call(this, pathElem);
|
|
700
|
+
}
|
|
701
|
+
SubTreeRootNode$1.prototype = Object.create(Node$2.prototype);
|
|
702
|
+
SubTreeRootNode$1.prototype.constructor = SubTreeRootNode$1;
|
|
703
|
+
/**
|
|
704
|
+
*
|
|
705
|
+
* @param {*} content
|
|
706
|
+
* @param {PathElement} pathElem
|
|
707
|
+
*/
|
|
708
|
+
function Leaf$2(content, pathElem = null) {
|
|
709
|
+
this.content = content;
|
|
710
|
+
if (pathElem != null) {
|
|
711
|
+
if (pathElem instanceof PathLeafElement$2) {
|
|
712
|
+
BinaryTreeElement.prototype.setPathElement.call(this, pathElem);
|
|
713
|
+
}
|
|
714
|
+
else {
|
|
715
|
+
throw new Error("The path and object structure does not match! We are at a leaf, but the path expects a sub structure.");
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
}
|
|
719
|
+
Leaf$2.prototype = Object.create(BinaryTreeElement.prototype);
|
|
720
|
+
Leaf$2.prototype.constructor = Leaf$2;
|
|
721
|
+
Leaf$2.prototype.getPrefixByte = function () {
|
|
722
|
+
return HASH_PREFIX_LEAF$1;
|
|
723
|
+
};
|
|
724
|
+
function EmptyLeaf$2() { }
|
|
725
|
+
EmptyLeaf$2.prototype = Object.create(BinaryTreeElement.prototype);
|
|
726
|
+
EmptyLeaf$2.prototype.constructor = EmptyLeaf$2;
|
|
727
|
+
/**
|
|
728
|
+
* Wrapper class for the root object.
|
|
729
|
+
* @param {BinaryTreeElement} root
|
|
730
|
+
*/
|
|
731
|
+
function BinaryTree$1(root) {
|
|
732
|
+
this.root = root;
|
|
733
|
+
}
|
|
734
|
+
BinaryTree$1.prototype.maxLevel = function () {
|
|
735
|
+
return this.maxLevelInternal(this.root);
|
|
736
|
+
};
|
|
737
|
+
BinaryTree$1.prototype.maxLevelInternal = function (node) {
|
|
738
|
+
if (node instanceof EmptyLeaf$2) {
|
|
739
|
+
return 0;
|
|
740
|
+
}
|
|
741
|
+
else if (node instanceof Leaf$2) {
|
|
742
|
+
return 1;
|
|
743
|
+
}
|
|
744
|
+
else if (node instanceof Node$2) {
|
|
745
|
+
return Math.max(this.maxLevelInternal(node.left), this.maxLevelInternal(node.right)) + 1;
|
|
746
|
+
}
|
|
747
|
+
else {
|
|
748
|
+
throw new Error("What is this type? " + typeof node);
|
|
749
|
+
}
|
|
750
|
+
};
|
|
751
|
+
/**
|
|
752
|
+
* Represents the top of a sub tree generated by a [Array]
|
|
753
|
+
*
|
|
754
|
+
* @param {*} left
|
|
755
|
+
* @param {*} right
|
|
756
|
+
* @param {*} content
|
|
757
|
+
* @param {*} size
|
|
758
|
+
* @param {PathElement} pathElem
|
|
759
|
+
*/
|
|
760
|
+
function ArrayHeadNode$2(left, right, content, size, pathElem = null) {
|
|
761
|
+
SubTreeRootNode$1.call(this, left, right, content, pathElem);
|
|
762
|
+
this.size = size;
|
|
763
|
+
}
|
|
764
|
+
ArrayHeadNode$2.prototype = Object.create(SubTreeRootNode$1.prototype);
|
|
765
|
+
ArrayHeadNode$2.prototype.constructor = ArrayHeadNode$2;
|
|
766
|
+
ArrayHeadNode$2.prototype.getPrefixByte = function () {
|
|
767
|
+
return HASH_PREFIX_NODE_ARRAY$1;
|
|
768
|
+
};
|
|
769
|
+
/**
|
|
770
|
+
* Represents the top a sub tree generated by a [Dictionary]
|
|
771
|
+
* @param {*} left
|
|
772
|
+
* @param {*} right
|
|
773
|
+
* @param {*} content
|
|
774
|
+
* @param {*} size
|
|
775
|
+
* @param {PathElement} pathElem
|
|
776
|
+
*/
|
|
777
|
+
function DictHeadNode$2(left, right, content, size, pathElem = null) {
|
|
778
|
+
SubTreeRootNode$1.call(this, left, right, content, pathElem);
|
|
779
|
+
this.size = size;
|
|
780
|
+
}
|
|
781
|
+
DictHeadNode$2.prototype = Object.create(SubTreeRootNode$1.prototype);
|
|
782
|
+
DictHeadNode$2.prototype.constructor = DictHeadNode$2;
|
|
783
|
+
DictHeadNode$2.prototype.getPrefixByte = function () {
|
|
784
|
+
return HASH_PREFIX_NODE_DICT$1;
|
|
785
|
+
};
|
|
786
|
+
var binarytree = { HASH_PREFIX_NODE: HASH_PREFIX_NODE$1, HASH_PREFIX_LEAF: HASH_PREFIX_LEAF$1, HASH_PREFIX_NODE_ARRAY: HASH_PREFIX_NODE_ARRAY$1, HASH_PREFIX_NODE_DICT: HASH_PREFIX_NODE_DICT$1,
|
|
787
|
+
Node: Node$2, Leaf: Leaf$2, EmptyLeaf: EmptyLeaf$2, SubTreeRootNode: SubTreeRootNode$1, BinaryTreeElement, BinaryTree: BinaryTree$1, ArrayHeadNode: ArrayHeadNode$2, DictHeadNode: DictHeadNode$2 };
|
|
788
|
+
|
|
789
|
+
class PrivKeyFormatException extends Error {
|
|
790
|
+
constructor(privKey) {
|
|
791
|
+
super(`Invalid key length. Expected 32, but got ${privKey.length}`);
|
|
792
|
+
}
|
|
793
|
+
}
|
|
794
|
+
class MissingPrivKeyArgumentException extends Error {
|
|
795
|
+
constructor() {
|
|
796
|
+
super(`Missing argument privKey`);
|
|
797
|
+
}
|
|
798
|
+
}
|
|
799
|
+
|
|
800
|
+
function createPublicKey(privKey) {
|
|
801
|
+
validatePrivKeyFormat(privKey);
|
|
802
|
+
return Buffer.from(secp256k1__namespace.publicKeyCreate(privKey, true).buffer);
|
|
803
|
+
}
|
|
804
|
+
function randomBytes(size) {
|
|
805
|
+
return crypto__namespace.randomBytes(size);
|
|
806
|
+
}
|
|
807
|
+
function sha256(buffer) {
|
|
808
|
+
return crypto__namespace.createHash("sha256").update(buffer).digest();
|
|
809
|
+
}
|
|
810
|
+
const hash256 = sha256;
|
|
811
|
+
function hashConcat(items) {
|
|
812
|
+
return hash256(Buffer.concat(items));
|
|
813
|
+
}
|
|
814
|
+
/**
|
|
815
|
+
* @param content the content that the signature signs. It will be digested before validating.
|
|
816
|
+
* @param pubKey The pubKey to validate the signature with
|
|
817
|
+
* @param signature the signature to validate
|
|
818
|
+
*
|
|
819
|
+
* @return true if signature ok, false otherwise
|
|
820
|
+
*/
|
|
821
|
+
function checkSignature(content, pubKey, signature) {
|
|
822
|
+
const digest = hash256(content);
|
|
823
|
+
return checkDigestSignature(digest, pubKey, signature);
|
|
824
|
+
}
|
|
825
|
+
/**
|
|
826
|
+
* @param digest the signed digest. It will not be digested before validating.
|
|
827
|
+
* @param pubKey The pubKey to validate the signature with
|
|
828
|
+
* @param signature the signature to validate
|
|
829
|
+
*
|
|
830
|
+
* @return true if signature ok, false otherwise
|
|
831
|
+
*/
|
|
832
|
+
function checkDigestSignature(digest, pubKey, signature) {
|
|
833
|
+
return secp256k1__namespace.ecdsaVerify(signature, digest, pubKey);
|
|
834
|
+
}
|
|
835
|
+
/**
|
|
836
|
+
* @param content to sign. It will be digested before signing.
|
|
837
|
+
* @param privKey The private key to sign the content with
|
|
838
|
+
*
|
|
839
|
+
* @return the signature
|
|
840
|
+
*/
|
|
841
|
+
function sign$1(content, privKey) {
|
|
842
|
+
validatePrivKeyFormat(privKey);
|
|
843
|
+
const digestBuffer = sha256(content);
|
|
844
|
+
return signDigest(digestBuffer, privKey);
|
|
845
|
+
}
|
|
846
|
+
/**
|
|
847
|
+
* @param digestBuffer to sign. It will not be digested before signing.
|
|
848
|
+
* @param privKey The private key to sign the digest with
|
|
849
|
+
*
|
|
850
|
+
* @return the signature
|
|
851
|
+
*/
|
|
852
|
+
function signDigest(digestBuffer, privKey) {
|
|
853
|
+
return Buffer.from(secp256k1__namespace.ecdsaSign(digestBuffer, privKey).signature);
|
|
854
|
+
}
|
|
855
|
+
/**
|
|
856
|
+
* Creates a key pair (which usually represents one user)
|
|
857
|
+
* @param privKey to create key pair based on
|
|
858
|
+
* @returns {{pubKey: Buffer, privKey: Buffer}}
|
|
859
|
+
*/
|
|
860
|
+
function makeKeyPair(privKey) {
|
|
861
|
+
let pubKey;
|
|
862
|
+
if (privKey) {
|
|
863
|
+
privKey = ensureBuffer(privKey);
|
|
864
|
+
pubKey = createPublicKey(privKey);
|
|
865
|
+
}
|
|
866
|
+
else {
|
|
867
|
+
do {
|
|
868
|
+
privKey = randomBytes(32);
|
|
869
|
+
} while (!secp256k1__namespace.privateKeyVerify(privKey));
|
|
870
|
+
pubKey = Buffer.from(secp256k1__namespace.publicKeyCreate(privKey).buffer);
|
|
871
|
+
}
|
|
872
|
+
return { pubKey, privKey };
|
|
873
|
+
}
|
|
874
|
+
/**
|
|
875
|
+
* Generates a 16bytes TUID (Text unique ID) (a 32characters long string)
|
|
876
|
+
* @returns string
|
|
877
|
+
*/
|
|
878
|
+
function makeTuid() {
|
|
879
|
+
return randomBytes(16).toString("hex");
|
|
880
|
+
}
|
|
881
|
+
/**
|
|
882
|
+
* Verify that keypair is correct. Providing the private key, this function returns its associated public key
|
|
883
|
+
* @param privKey: Buffer
|
|
884
|
+
* @returns {{pubKey: Buffer, privKey: Buffer}}
|
|
885
|
+
*/
|
|
886
|
+
function verifyKeyPair(privKey) {
|
|
887
|
+
validatePrivKeyFormat(privKey);
|
|
888
|
+
const pubKey = Buffer.from(secp256k1__namespace.publicKeyCreate(privKey).buffer);
|
|
889
|
+
return { pubKey, privKey };
|
|
890
|
+
}
|
|
891
|
+
function validatePrivKeyFormat(privKey) {
|
|
892
|
+
if (!privKey) {
|
|
893
|
+
throw new MissingPrivKeyArgumentException();
|
|
894
|
+
}
|
|
895
|
+
if (!Buffer.isBuffer(privKey) || privKey.length !== 32) {
|
|
896
|
+
throw new PrivKeyFormatException(privKey);
|
|
897
|
+
}
|
|
898
|
+
}
|
|
899
|
+
|
|
900
|
+
var encryption$1 = /*#__PURE__*/Object.freeze({
|
|
901
|
+
__proto__: null,
|
|
902
|
+
checkDigestSignature: checkDigestSignature,
|
|
903
|
+
checkSignature: checkSignature,
|
|
904
|
+
createPublicKey: createPublicKey,
|
|
905
|
+
hash256: hash256,
|
|
906
|
+
hashConcat: hashConcat,
|
|
907
|
+
makeKeyPair: makeKeyPair,
|
|
908
|
+
makeTuid: makeTuid,
|
|
909
|
+
randomBytes: randomBytes,
|
|
910
|
+
sha256: sha256,
|
|
911
|
+
sign: sign$1,
|
|
912
|
+
signDigest: signDigest,
|
|
913
|
+
verifyKeyPair: verifyKeyPair
|
|
914
|
+
});
|
|
915
|
+
|
|
916
|
+
var require$$2 = /*@__PURE__*/getAugmentedNamespace(encryption$1);
|
|
917
|
+
|
|
918
|
+
var serialization = require$$0$1;
|
|
919
|
+
var HASH_PREFIX_LEAF = binarytree.HASH_PREFIX_LEAF;
|
|
920
|
+
var encryption = require$$2;
|
|
921
|
+
function CryptoSystem() { }
|
|
922
|
+
CryptoSystem.prototype.digest = function (buffer) {
|
|
923
|
+
return encryption.hash256(buffer);
|
|
924
|
+
};
|
|
925
|
+
/**
|
|
926
|
+
*
|
|
927
|
+
* @param {Buffer} buffer
|
|
928
|
+
* @param {CryptoSystem} cryptoSystem
|
|
929
|
+
*/
|
|
930
|
+
function hashingFun(buffer, cryptoSystem) {
|
|
931
|
+
if (cryptoSystem === null) {
|
|
932
|
+
throw new Error("In this case we need the CryptoSystem to calculate the hash");
|
|
933
|
+
}
|
|
934
|
+
else {
|
|
935
|
+
return cryptoSystem.digest(buffer);
|
|
936
|
+
}
|
|
937
|
+
}
|
|
938
|
+
/**
|
|
939
|
+
*
|
|
940
|
+
* @param {CryptoSystem} cryptoSystem
|
|
941
|
+
*/
|
|
942
|
+
function MerkleHashCalculator(cryptoSystem) {
|
|
943
|
+
this.cryptoSystem = cryptoSystem;
|
|
944
|
+
}
|
|
945
|
+
/**
|
|
946
|
+
* @param {number} prefix
|
|
947
|
+
* @param {Buffer} hashLeft
|
|
948
|
+
* @param {Buffer} hashRight
|
|
949
|
+
*/
|
|
950
|
+
MerkleHashCalculator.prototype.calculateNodeHash = function (prefix, hashLeft, hashRight) {
|
|
951
|
+
return this.calculateNodeHashInternal(prefix, hashLeft, hashRight, hashingFun);
|
|
952
|
+
};
|
|
953
|
+
/**
|
|
954
|
+
* @param {*} value
|
|
955
|
+
*/
|
|
956
|
+
MerkleHashCalculator.prototype.calculateLeafHash = function (value) {
|
|
957
|
+
return this.calculateHashOfValueInternal(value, serialization.encodeValue, hashingFun);
|
|
958
|
+
};
|
|
959
|
+
/**
|
|
960
|
+
* @param {number} prefix
|
|
961
|
+
* @param {Buffer} hashLeft
|
|
962
|
+
* @param {Buffer} hashRight
|
|
963
|
+
*/
|
|
964
|
+
MerkleHashCalculator.prototype.calculateNodeHashInternal = function (prefix, hashLeft, hashRight, hashFunc) {
|
|
965
|
+
var buf = Buffer.alloc(1);
|
|
966
|
+
buf.writeInt8(prefix);
|
|
967
|
+
var bufferSum = Buffer.concat([buf, hashLeft, hashRight]);
|
|
968
|
+
return hashFunc(bufferSum, this.cryptoSystem);
|
|
969
|
+
};
|
|
970
|
+
MerkleHashCalculator.prototype.calculateHashOfValueInternal = function (valuetoHash, serializeFun, hashFunc) {
|
|
971
|
+
var buf = Buffer.alloc(1);
|
|
972
|
+
buf.writeInt8(HASH_PREFIX_LEAF);
|
|
973
|
+
var bufferSum = Buffer.concat([buf, serializeFun(valuetoHash)]);
|
|
974
|
+
return hashFunc(bufferSum, this.cryptoSystem);
|
|
975
|
+
};
|
|
976
|
+
MerkleHashCalculator.prototype.isContainerProofValueLeaf = function (value) {
|
|
977
|
+
if (value == null) {
|
|
978
|
+
return false;
|
|
979
|
+
}
|
|
980
|
+
if (value.constructor === Array || typeof value === 'object') {
|
|
981
|
+
return true;
|
|
982
|
+
}
|
|
983
|
+
else {
|
|
984
|
+
return false;
|
|
985
|
+
}
|
|
986
|
+
};
|
|
987
|
+
var merklehashcalculator = { MerkleHashCalculator, CryptoSystem };
|
|
988
|
+
|
|
989
|
+
var util = require$$0;
|
|
990
|
+
var PathSet = path.PathSet;
|
|
991
|
+
var PathLeafElement$1 = path.PathLeafElement;
|
|
992
|
+
var EmptyLeaf$1 = binarytree.EmptyLeaf;
|
|
993
|
+
var Leaf$1 = binarytree.Leaf;
|
|
994
|
+
var Node$1 = binarytree.Node;
|
|
995
|
+
var BinaryTree = binarytree.BinaryTree;
|
|
996
|
+
var ArrayHeadNode$1 = binarytree.ArrayHeadNode;
|
|
997
|
+
var DictHeadNode$1 = binarytree.DictHeadNode;
|
|
998
|
+
const NO_PATHS = new PathSet([]);
|
|
999
|
+
/**
|
|
1000
|
+
* The factory does the conversion between list of elements and tree of elements.
|
|
1001
|
+
*
|
|
1002
|
+
* Note: The idea is that you should sub class for each type of element you want to build.
|
|
1003
|
+
*/
|
|
1004
|
+
function BinaryTreeFactory$1() { }
|
|
1005
|
+
/**
|
|
1006
|
+
* Transforms the incoming leaf into an [BinaryTreeElement]
|
|
1007
|
+
* The idea with this function is that it can be recursive (if the leaf in turn is complex object with sub objects).
|
|
1008
|
+
*
|
|
1009
|
+
* Note: If we don't have a path here we can try to find the leaf in the cache.
|
|
1010
|
+
*
|
|
1011
|
+
* @param leaf the raw data we should wrap in a leaf
|
|
1012
|
+
* @param paths a collection of proof paths that might point to this leaf
|
|
1013
|
+
* @return the resulting [BinaryTreeElement] the leaf got converted to
|
|
1014
|
+
*/
|
|
1015
|
+
BinaryTreeFactory$1.prototype.handleLeaf = function (leaf, paths, isRoot = false) {
|
|
1016
|
+
if (paths.length == 0 && !isRoot) {
|
|
1017
|
+
return this.innerHandleLeaf(leaf, this.getEmptyPathSet());
|
|
1018
|
+
}
|
|
1019
|
+
else {
|
|
1020
|
+
return this.innerHandleLeaf(leaf, paths);
|
|
1021
|
+
}
|
|
1022
|
+
};
|
|
1023
|
+
/**
|
|
1024
|
+
*
|
|
1025
|
+
*/
|
|
1026
|
+
BinaryTreeFactory$1.prototype.getEmptyPathSet = function () {
|
|
1027
|
+
return NO_PATHS;
|
|
1028
|
+
};
|
|
1029
|
+
/**
|
|
1030
|
+
* At this point we should have looked in cache.
|
|
1031
|
+
*
|
|
1032
|
+
* @param leaf we should turn into a tree element
|
|
1033
|
+
* @param {PathSet} paths
|
|
1034
|
+
* @return the tree element we created.
|
|
1035
|
+
*/
|
|
1036
|
+
BinaryTreeFactory$1.prototype.innerHandleLeaf = function (leaf, paths) {
|
|
1037
|
+
if (leaf == null) {
|
|
1038
|
+
return this.handlePrimitiveLeaf(leaf, paths);
|
|
1039
|
+
}
|
|
1040
|
+
if (Buffer.isBuffer(leaf)) {
|
|
1041
|
+
return this.handlePrimitiveLeaf(leaf, paths);
|
|
1042
|
+
}
|
|
1043
|
+
if (typeof leaf === 'string') {
|
|
1044
|
+
return this.handlePrimitiveLeaf(leaf, paths);
|
|
1045
|
+
}
|
|
1046
|
+
if (typeof leaf === 'number') {
|
|
1047
|
+
return this.handlePrimitiveLeaf(leaf, paths);
|
|
1048
|
+
}
|
|
1049
|
+
if (typeof leaf === 'boolean') {
|
|
1050
|
+
return this.handlePrimitiveLeaf(leaf ? 1 : 0, paths);
|
|
1051
|
+
}
|
|
1052
|
+
if (leaf.constructor === Array) {
|
|
1053
|
+
return this.buildFromArray(leaf, paths);
|
|
1054
|
+
}
|
|
1055
|
+
if (typeof leaf === 'object') {
|
|
1056
|
+
return this.buildFromDictionary(leaf, paths);
|
|
1057
|
+
}
|
|
1058
|
+
else {
|
|
1059
|
+
throw new Error("Unsupporting data type");
|
|
1060
|
+
}
|
|
1061
|
+
};
|
|
1062
|
+
/**
|
|
1063
|
+
* Just like [handleLeaf] but we know that this leaf should not be a complex type, but something we can
|
|
1064
|
+
* immediately wrap
|
|
1065
|
+
*
|
|
1066
|
+
* @param leaf
|
|
1067
|
+
* @param {PathSet} paths
|
|
1068
|
+
*/
|
|
1069
|
+
BinaryTreeFactory$1.prototype.handlePrimitiveLeaf = function (leaf, paths) {
|
|
1070
|
+
var pathElem = paths.getPathLeafOrElseAnyCurrentPathElement();
|
|
1071
|
+
if (pathElem != null && !(pathElem instanceof PathLeafElement$1)) {
|
|
1072
|
+
throw new Error("Path does not match the tree structure. We are at a leaf " + leaf + " but found path element " + pathElem);
|
|
1073
|
+
}
|
|
1074
|
+
return new Leaf$1(leaf, pathElem);
|
|
1075
|
+
};
|
|
1076
|
+
/**
|
|
1077
|
+
* Calls itself until the return value only holds 1 element
|
|
1078
|
+
*
|
|
1079
|
+
* Note: This method can only create standard [Node] that fills up the area between the "top" and the leaves.
|
|
1080
|
+
* These "in-between" nodes cannot be "path leaf" or have any interesting properties.
|
|
1081
|
+
*
|
|
1082
|
+
* @param layer What layer we aim calculate
|
|
1083
|
+
* @param inList The args of nodes we should build from
|
|
1084
|
+
* @return All [BinaryTreeElement] nodes of the next layer
|
|
1085
|
+
*/
|
|
1086
|
+
BinaryTreeFactory$1.prototype.buildHigherLayer = function (layer, inList) {
|
|
1087
|
+
if (inList.length === 0) {
|
|
1088
|
+
throw new Error("Cannot work on empty arrays. Layer: " + layer);
|
|
1089
|
+
}
|
|
1090
|
+
else if (inList.length === 1) {
|
|
1091
|
+
return inList;
|
|
1092
|
+
}
|
|
1093
|
+
var returnArray = new Array();
|
|
1094
|
+
var nrOfNodesToCreate = Math.floor(inList.length / 2);
|
|
1095
|
+
var leftValue = null;
|
|
1096
|
+
var isLeft = true;
|
|
1097
|
+
for (var i = 0; i < inList.length; i++) {
|
|
1098
|
+
if (isLeft) {
|
|
1099
|
+
leftValue = inList[i];
|
|
1100
|
+
isLeft = false;
|
|
1101
|
+
}
|
|
1102
|
+
else {
|
|
1103
|
+
var tempNode = new Node$1(leftValue, inList[i]);
|
|
1104
|
+
returnArray.push(tempNode);
|
|
1105
|
+
nrOfNodesToCreate--;
|
|
1106
|
+
isLeft = true;
|
|
1107
|
+
leftValue = null;
|
|
1108
|
+
}
|
|
1109
|
+
}
|
|
1110
|
+
if (!isLeft) {
|
|
1111
|
+
// If there is odd number of nodes, then move the last node up one level
|
|
1112
|
+
returnArray.push(leftValue);
|
|
1113
|
+
}
|
|
1114
|
+
// Extra check
|
|
1115
|
+
if (nrOfNodesToCreate != 0) {
|
|
1116
|
+
util.logDebug("Why didn't we build exactly the correct amount? Layer: " + layer + " , residue: " + nrOfNodesToCreate + " , input args size: " + inList.length + ".");
|
|
1117
|
+
}
|
|
1118
|
+
return this.buildHigherLayer((layer + 1), returnArray);
|
|
1119
|
+
};
|
|
1120
|
+
BinaryTreeFactory$1.prototype.build = function (data) {
|
|
1121
|
+
return this.buildWithPath(data, NO_PATHS);
|
|
1122
|
+
};
|
|
1123
|
+
/**
|
|
1124
|
+
* @param {PathSet} paths
|
|
1125
|
+
*/
|
|
1126
|
+
BinaryTreeFactory$1.prototype.buildWithPath = function (data, paths) {
|
|
1127
|
+
var result = this.handleLeaf(data, paths, true);
|
|
1128
|
+
return new BinaryTree(result);
|
|
1129
|
+
};
|
|
1130
|
+
/**
|
|
1131
|
+
* @param {Array} array
|
|
1132
|
+
* @param {PathSet} paths
|
|
1133
|
+
*/
|
|
1134
|
+
BinaryTreeFactory$1.prototype.buildFromArray = function (array, paths) {
|
|
1135
|
+
var pathElem = paths.getPathLeafOrElseAnyCurrentPathElement();
|
|
1136
|
+
// 1. Build leaf layer
|
|
1137
|
+
if (array.length == 0) {
|
|
1138
|
+
return new ArrayHeadNode$1(new EmptyLeaf$1(), new EmptyLeaf$1(), array, 0, 0, pathElem);
|
|
1139
|
+
}
|
|
1140
|
+
var leafArray = this.buildLeafElements(array, paths);
|
|
1141
|
+
// 2. Build all higher layers
|
|
1142
|
+
var result = this.buildHigherLayer(1, leafArray);
|
|
1143
|
+
// 3. Fix and return the root node
|
|
1144
|
+
var orgRoot = result[0];
|
|
1145
|
+
if (orgRoot instanceof Node$1) {
|
|
1146
|
+
return new ArrayHeadNode$1(orgRoot.left, orgRoot.right, array, array.length, pathElem);
|
|
1147
|
+
}
|
|
1148
|
+
if (orgRoot instanceof Leaf$1) {
|
|
1149
|
+
return this.buildFromOneLeaf(array, orgRoot, pathElem);
|
|
1150
|
+
}
|
|
1151
|
+
else {
|
|
1152
|
+
throw new Error("Should not find element of this type here");
|
|
1153
|
+
}
|
|
1154
|
+
};
|
|
1155
|
+
/**
|
|
1156
|
+
*
|
|
1157
|
+
*/
|
|
1158
|
+
BinaryTreeFactory$1.prototype.buildFromOneLeaf = function (array, orgRoot, pathElem) {
|
|
1159
|
+
if (array.length > 1) {
|
|
1160
|
+
throw new Error("How come we got a leaf returned when we had " + array.length + " elements is the args?");
|
|
1161
|
+
}
|
|
1162
|
+
else {
|
|
1163
|
+
return new ArrayHeadNode$1(orgRoot, new EmptyLeaf$1(), array, array.length, pathElem);
|
|
1164
|
+
}
|
|
1165
|
+
};
|
|
1166
|
+
/**
|
|
1167
|
+
* @param {PathSet} paths
|
|
1168
|
+
*/
|
|
1169
|
+
BinaryTreeFactory$1.prototype.buildLeafElements = function (leafList, paths) {
|
|
1170
|
+
var leafArray = new Array();
|
|
1171
|
+
var onlyArrayPaths = paths.keepOnlyArrayPaths(); // For performance, since we will loop soon
|
|
1172
|
+
for (var i = 0; i < leafList.length; i++) {
|
|
1173
|
+
var pathsRelevantForThisLeaf = onlyArrayPaths.getTailIfFirstElementIsArrayOfThisIndexFromList(i);
|
|
1174
|
+
var leaf = leafList[i];
|
|
1175
|
+
var binaryTreeElement = this.handleLeaf(leaf, pathsRelevantForThisLeaf);
|
|
1176
|
+
leafArray.push(binaryTreeElement);
|
|
1177
|
+
}
|
|
1178
|
+
return leafArray;
|
|
1179
|
+
};
|
|
1180
|
+
/**
|
|
1181
|
+
* @param {PathSet} paths
|
|
1182
|
+
*/
|
|
1183
|
+
BinaryTreeFactory$1.prototype.buildFromDictionary = function (dict, paths) {
|
|
1184
|
+
var pathElem = paths.getPathLeafOrElseAnyCurrentPathElement();
|
|
1185
|
+
// Needs to be sorted, or else the order is undefined
|
|
1186
|
+
var keys = Object.keys(dict).sort();
|
|
1187
|
+
if (keys.length == 0) {
|
|
1188
|
+
return new DictHeadNode$1(new EmptyLeaf$1(), new EmptyLeaf$1(), dict, keys.length, 0, pathElem);
|
|
1189
|
+
}
|
|
1190
|
+
// 1. Build first (leaf) layer
|
|
1191
|
+
var leafArray = this.buildLeafElementFromDict(keys, dict, paths);
|
|
1192
|
+
// 2. Build all higher layers
|
|
1193
|
+
var result = this.buildHigherLayer(1, leafArray);
|
|
1194
|
+
// 3. Fix and return the root node
|
|
1195
|
+
var orgRoot = result[0];
|
|
1196
|
+
if (orgRoot instanceof Node$1) {
|
|
1197
|
+
return new DictHeadNode$1(orgRoot.left, orgRoot.right, dict, keys.length, pathElem);
|
|
1198
|
+
}
|
|
1199
|
+
else {
|
|
1200
|
+
throw new Error("Should not find element of this type here: " + typeof orgRoot);
|
|
1201
|
+
}
|
|
1202
|
+
};
|
|
1203
|
+
/**
|
|
1204
|
+
* @param {PathSet} paths
|
|
1205
|
+
*/
|
|
1206
|
+
BinaryTreeFactory$1.prototype.buildLeafElementFromDict = function (keys, dict, paths) {
|
|
1207
|
+
var leafArray = new Array();
|
|
1208
|
+
var onlyDictPaths = paths.keepOnlyDictPaths(); // For performance, since we will loop soon
|
|
1209
|
+
for (var i = 0; i < keys.length; i++) {
|
|
1210
|
+
// The key cannot not be proved, so NO_PATHS
|
|
1211
|
+
var key = keys[i];
|
|
1212
|
+
var keyElement = this.handleLeaf(key, NO_PATHS);
|
|
1213
|
+
leafArray.push(keyElement);
|
|
1214
|
+
var content = dict[key];
|
|
1215
|
+
var pathsRelevantForThisLeaf = onlyDictPaths.getTailIfFirstElementIsDictOfThisKeyFromList(key);
|
|
1216
|
+
var contentElement = this.handleLeaf(content, pathsRelevantForThisLeaf);
|
|
1217
|
+
leafArray.push(contentElement);
|
|
1218
|
+
}
|
|
1219
|
+
return leafArray;
|
|
1220
|
+
};
|
|
1221
|
+
var binarytreefactory = { BinaryTreeFactory: BinaryTreeFactory$1 };
|
|
1222
|
+
|
|
1223
|
+
var HASH_PREFIX_NODE = binarytree.HASH_PREFIX_NODE;
|
|
1224
|
+
var HASH_PREFIX_NODE_ARRAY = binarytree.HASH_PREFIX_NODE_ARRAY;
|
|
1225
|
+
var HASH_PREFIX_NODE_DICT = binarytree.HASH_PREFIX_NODE_DICT;
|
|
1226
|
+
/**
|
|
1227
|
+
*
|
|
1228
|
+
*/
|
|
1229
|
+
function MerkleProofElement() { }
|
|
1230
|
+
/**
|
|
1231
|
+
*
|
|
1232
|
+
* @param {Buffer} prefix
|
|
1233
|
+
* @param {MerkleProofElement} left
|
|
1234
|
+
* @param {MerkleProofElement} right
|
|
1235
|
+
*/
|
|
1236
|
+
function ProofNode$1(prefix, left, right) {
|
|
1237
|
+
this.prefix = prefix;
|
|
1238
|
+
this.left = left;
|
|
1239
|
+
this.right = right;
|
|
1240
|
+
}
|
|
1241
|
+
ProofNode$1.prototype = Object.create(MerkleProofElement.prototype);
|
|
1242
|
+
ProofNode$1.prototype.constructor = ProofNode$1;
|
|
1243
|
+
/**
|
|
1244
|
+
*
|
|
1245
|
+
* @param {MerkleProofElement} left
|
|
1246
|
+
* @param {MerkleProofElement} right
|
|
1247
|
+
*/
|
|
1248
|
+
function ProofNodeSimple$1(left, right) {
|
|
1249
|
+
ProofNode$1.call(this, HASH_PREFIX_NODE, left, right);
|
|
1250
|
+
}
|
|
1251
|
+
ProofNodeSimple$1.prototype = Object.create(ProofNode$1.prototype);
|
|
1252
|
+
ProofNodeSimple$1.prototype.constructor = ProofNodeSimple$1;
|
|
1253
|
+
/**
|
|
1254
|
+
*
|
|
1255
|
+
* @param {*} content
|
|
1256
|
+
* @param {SearchablePathElement} pathElem
|
|
1257
|
+
*/
|
|
1258
|
+
function ProofValueLeaf$2(content, pathElem) {
|
|
1259
|
+
this.content = content;
|
|
1260
|
+
this.pathElem = pathElem;
|
|
1261
|
+
}
|
|
1262
|
+
ProofValueLeaf$2.prototype = Object.create(MerkleProofElement.prototype);
|
|
1263
|
+
ProofValueLeaf$2.prototype.constructor = ProofValueLeaf$2;
|
|
1264
|
+
/**
|
|
1265
|
+
*
|
|
1266
|
+
* @param {Buffer} merkleHash
|
|
1267
|
+
*/
|
|
1268
|
+
function ProofHashedLeaf$2(merkleHash) {
|
|
1269
|
+
this.merkleHash = merkleHash;
|
|
1270
|
+
}
|
|
1271
|
+
ProofHashedLeaf$2.prototype = Object.create(MerkleProofElement.prototype);
|
|
1272
|
+
ProofHashedLeaf$2.prototype.constructor = ProofHashedLeaf$2;
|
|
1273
|
+
/**
|
|
1274
|
+
* @param {ProofHashedLeaf} other
|
|
1275
|
+
*/
|
|
1276
|
+
ProofHashedLeaf$2.prototype.equals = function (other) {
|
|
1277
|
+
if (other instanceof ProofHashedLeaf$2) {
|
|
1278
|
+
return this.merkleHash.equals(other.merkleHash);
|
|
1279
|
+
}
|
|
1280
|
+
else {
|
|
1281
|
+
return false;
|
|
1282
|
+
}
|
|
1283
|
+
};
|
|
1284
|
+
/**
|
|
1285
|
+
*
|
|
1286
|
+
* @param {MerkleProofElement} left
|
|
1287
|
+
* @param {MerkleProofElement} right
|
|
1288
|
+
* @param {SearchablePathElement} pathElem
|
|
1289
|
+
*/
|
|
1290
|
+
function ProofNodeArrayHead$1(left, right, pathElem = null) {
|
|
1291
|
+
ProofNode$1.call(this, HASH_PREFIX_NODE_ARRAY, left, right);
|
|
1292
|
+
this.pathElem = pathElem;
|
|
1293
|
+
}
|
|
1294
|
+
ProofNodeArrayHead$1.prototype = Object.create(ProofNode$1.prototype);
|
|
1295
|
+
ProofNodeArrayHead$1.prototype.constructor = ProofNodeArrayHead$1;
|
|
1296
|
+
/**
|
|
1297
|
+
*
|
|
1298
|
+
* @param {MerkleProofElement} left
|
|
1299
|
+
* @param {MerkleProofElement} right
|
|
1300
|
+
* @param {SearchablePathElement} pathElem
|
|
1301
|
+
*/
|
|
1302
|
+
function ProofNodeDictHead$1(left, right, pathElem = null) {
|
|
1303
|
+
ProofNode$1.call(this, HASH_PREFIX_NODE_DICT, left, right);
|
|
1304
|
+
this.pathElem = pathElem;
|
|
1305
|
+
}
|
|
1306
|
+
ProofNodeDictHead$1.prototype = Object.create(ProofNode$1.prototype);
|
|
1307
|
+
ProofNodeDictHead$1.prototype.constructor = ProofNodeDictHead$1;
|
|
1308
|
+
/**
|
|
1309
|
+
*
|
|
1310
|
+
* @param {MerkleProofElement} root
|
|
1311
|
+
*/
|
|
1312
|
+
function MerkleProofTree$1(root) {
|
|
1313
|
+
this.root = root;
|
|
1314
|
+
}
|
|
1315
|
+
MerkleProofTree$1.prototype.maxLevel = function () {
|
|
1316
|
+
return this.maxLevelInternal(this.root);
|
|
1317
|
+
};
|
|
1318
|
+
/**
|
|
1319
|
+
* @param {MerkleProofElement} node
|
|
1320
|
+
*/
|
|
1321
|
+
MerkleProofTree$1.prototype.maxLevelInternal = function (node) {
|
|
1322
|
+
if (node instanceof ProofValueLeaf$2) {
|
|
1323
|
+
return 1;
|
|
1324
|
+
}
|
|
1325
|
+
else if (node instanceof ProofHashedLeaf$2) {
|
|
1326
|
+
return 1;
|
|
1327
|
+
}
|
|
1328
|
+
else if (node instanceof ProofNode$1) {
|
|
1329
|
+
return Math.max(this.maxLevelInternal(node.left), this.maxLevelInternal(node.right)) + 1;
|
|
1330
|
+
}
|
|
1331
|
+
else {
|
|
1332
|
+
throw new Error("Should be able to handle node type: " + typeof node);
|
|
1333
|
+
}
|
|
1334
|
+
};
|
|
1335
|
+
var merkleprooftree = { ProofNode: ProofNode$1, ProofNodeSimple: ProofNodeSimple$1, ProofHashedLeaf: ProofHashedLeaf$2, ProofValueLeaf: ProofValueLeaf$2,
|
|
1336
|
+
ProofNodeArrayHead: ProofNodeArrayHead$1, ProofNodeDictHead: ProofNodeDictHead$1, MerkleProofElement, MerkleProofTree: MerkleProofTree$1 };
|
|
1337
|
+
|
|
1338
|
+
var Node = binarytree.Node;
|
|
1339
|
+
var Leaf = binarytree.Leaf;
|
|
1340
|
+
var EmptyLeaf = binarytree.EmptyLeaf;
|
|
1341
|
+
var ProofHashedLeaf$1 = merkleprooftree.ProofHashedLeaf;
|
|
1342
|
+
var ProofValueLeaf$1 = merkleprooftree.ProofValueLeaf;
|
|
1343
|
+
var MerkleProofTree = merkleprooftree.MerkleProofTree;
|
|
1344
|
+
var ProofNodeArrayHead = merkleprooftree.ProofNodeArrayHead;
|
|
1345
|
+
var ProofNodeDictHead = merkleprooftree.ProofNodeDictHead;
|
|
1346
|
+
var PathLeafElement = path.PathLeafElement;
|
|
1347
|
+
var SubTreeRootNode = binarytree.SubTreeRootNode;
|
|
1348
|
+
var ArrayHeadNode = binarytree.ArrayHeadNode;
|
|
1349
|
+
var DictHeadNode = binarytree.DictHeadNode;
|
|
1350
|
+
var ProofNodeSimple = merkleprooftree.ProofNodeSimple;
|
|
1351
|
+
const EMPTY_HASH = new Buffer.alloc(32);
|
|
1352
|
+
/**
|
|
1353
|
+
*
|
|
1354
|
+
*/
|
|
1355
|
+
function MerkleProofTreeFactory$1() { }
|
|
1356
|
+
/**
|
|
1357
|
+
* @param {BinaryTree} orginalTree
|
|
1358
|
+
*/
|
|
1359
|
+
MerkleProofTreeFactory$1.prototype.buildFromBinaryTree = function (orginalTree, calculator) {
|
|
1360
|
+
var rootElem = this.buildFromBinaryTreeInternal(orginalTree.root, calculator);
|
|
1361
|
+
return new MerkleProofTree(rootElem);
|
|
1362
|
+
};
|
|
1363
|
+
/**
|
|
1364
|
+
* @param {BinaryTreeElement} elem
|
|
1365
|
+
* @param {*} calculator
|
|
1366
|
+
*/
|
|
1367
|
+
MerkleProofTreeFactory$1.prototype.buildFromBinaryTreeInternal = function (elem, calculator) {
|
|
1368
|
+
if (elem instanceof EmptyLeaf) {
|
|
1369
|
+
return new ProofHashedLeaf$1(EMPTY_HASH);
|
|
1370
|
+
}
|
|
1371
|
+
else if (elem instanceof Leaf) {
|
|
1372
|
+
var pathElem = elem.pathElem;
|
|
1373
|
+
if (pathElem != null) {
|
|
1374
|
+
if (pathElem instanceof PathLeafElement) {
|
|
1375
|
+
return new ProofValueLeaf$1(elem.content, pathElem.previous);
|
|
1376
|
+
}
|
|
1377
|
+
else {
|
|
1378
|
+
throw new Error("The path and structure don't match. We are at a leaf, but path elem is not a leaf: " + pathElem);
|
|
1379
|
+
}
|
|
1380
|
+
}
|
|
1381
|
+
else {
|
|
1382
|
+
// make a hash
|
|
1383
|
+
var hash = calculator.calculateLeafHash(elem.content);
|
|
1384
|
+
return new ProofHashedLeaf$1(hash);
|
|
1385
|
+
}
|
|
1386
|
+
}
|
|
1387
|
+
else if (elem instanceof SubTreeRootNode) {
|
|
1388
|
+
var pathElem = elem.pathElem;
|
|
1389
|
+
if (pathElem != null) {
|
|
1390
|
+
if (pathElem instanceof PathLeafElement) {
|
|
1391
|
+
// Don't convert it
|
|
1392
|
+
return new ProofValueLeaf$1(elem.content, pathElem.previous);
|
|
1393
|
+
}
|
|
1394
|
+
else {
|
|
1395
|
+
return this.convertNode(elem, calculator);
|
|
1396
|
+
}
|
|
1397
|
+
}
|
|
1398
|
+
else {
|
|
1399
|
+
return this.convertNode(elem, calculator);
|
|
1400
|
+
}
|
|
1401
|
+
}
|
|
1402
|
+
else if (elem instanceof Node) {
|
|
1403
|
+
return this.convertNode(elem, calculator);
|
|
1404
|
+
}
|
|
1405
|
+
else {
|
|
1406
|
+
throw new Error("Cannot handle " + elem);
|
|
1407
|
+
}
|
|
1408
|
+
};
|
|
1409
|
+
/**
|
|
1410
|
+
* @param {Node} node
|
|
1411
|
+
*/
|
|
1412
|
+
MerkleProofTreeFactory$1.prototype.convertNode = function (node, calculator) {
|
|
1413
|
+
var left = this.buildFromBinaryTreeInternal(node.left, calculator);
|
|
1414
|
+
var right = this.buildFromBinaryTreeInternal(node.right, calculator);
|
|
1415
|
+
if (left instanceof ProofHashedLeaf$1 && right instanceof ProofHashedLeaf$1) {
|
|
1416
|
+
var addedHash = calculator.calculateNodeHash(node.getPrefixByte(), left.merkleHash, right.merkleHash);
|
|
1417
|
+
return new ProofHashedLeaf$1(addedHash);
|
|
1418
|
+
}
|
|
1419
|
+
else {
|
|
1420
|
+
return this.buildNodeOfCorrectType(node, left, right);
|
|
1421
|
+
}
|
|
1422
|
+
};
|
|
1423
|
+
/**
|
|
1424
|
+
* @param {ArrayHeadNode} node
|
|
1425
|
+
*/
|
|
1426
|
+
MerkleProofTreeFactory$1.prototype.extractSearchablePathElement = function (node) {
|
|
1427
|
+
var pathElem = node.pathElem;
|
|
1428
|
+
if (pathElem != null) {
|
|
1429
|
+
return pathElem.previous;
|
|
1430
|
+
}
|
|
1431
|
+
else {
|
|
1432
|
+
return null;
|
|
1433
|
+
}
|
|
1434
|
+
};
|
|
1435
|
+
/**
|
|
1436
|
+
* @param {Node} node
|
|
1437
|
+
* @param {MerkleProofElement} left
|
|
1438
|
+
* @param {MerkleProofElement} right
|
|
1439
|
+
*/
|
|
1440
|
+
MerkleProofTreeFactory$1.prototype.buildNodeOfCorrectType = function (node, left, right) {
|
|
1441
|
+
if (node instanceof ArrayHeadNode) {
|
|
1442
|
+
return new ProofNodeArrayHead(left, right, this.extractSearchablePathElement(node));
|
|
1443
|
+
}
|
|
1444
|
+
else if (node instanceof DictHeadNode) {
|
|
1445
|
+
return new ProofNodeDictHead(left, right, this.extractSearchablePathElement(node));
|
|
1446
|
+
}
|
|
1447
|
+
else if (node instanceof Node) {
|
|
1448
|
+
return new ProofNodeSimple(left, right);
|
|
1449
|
+
}
|
|
1450
|
+
else {
|
|
1451
|
+
throw new Error("Should have taken care of this node type: " + node);
|
|
1452
|
+
}
|
|
1453
|
+
};
|
|
1454
|
+
var merkleprooftreefactory = { MerkleProofTreeFactory: MerkleProofTreeFactory$1 };
|
|
1455
|
+
|
|
1456
|
+
/**
|
|
1457
|
+
*
|
|
1458
|
+
* @param {Buffer} merkleHash
|
|
1459
|
+
*/
|
|
1460
|
+
function MerkleHashSummary$1(merkleHash) {
|
|
1461
|
+
this.merkleHash = merkleHash;
|
|
1462
|
+
}
|
|
1463
|
+
/**
|
|
1464
|
+
* @param {MerkleHashSummary} other
|
|
1465
|
+
*/
|
|
1466
|
+
MerkleHashSummary$1.prototype.equals = function (other) {
|
|
1467
|
+
if (this === other)
|
|
1468
|
+
return true;
|
|
1469
|
+
if (typeof this != typeof other)
|
|
1470
|
+
return false;
|
|
1471
|
+
if (this.merkleHash.compare(other.merkleHash) === 0) {
|
|
1472
|
+
return true;
|
|
1473
|
+
}
|
|
1474
|
+
return false;
|
|
1475
|
+
};
|
|
1476
|
+
var merklehashcarrier = { MerkleHashSummary: MerkleHashSummary$1 };
|
|
1477
|
+
|
|
1478
|
+
var ProofHashedLeaf = merkleprooftree.ProofHashedLeaf;
|
|
1479
|
+
var ProofValueLeaf = merkleprooftree.ProofValueLeaf;
|
|
1480
|
+
var ProofNode = merkleprooftree.ProofNode;
|
|
1481
|
+
var MerkleHashSummary = merklehashcarrier.MerkleHashSummary;
|
|
1482
|
+
/**
|
|
1483
|
+
*
|
|
1484
|
+
* @param {BinaryTreeFactory} treeFactory
|
|
1485
|
+
* @param {MerkleProofTreeFactory} proofFactory
|
|
1486
|
+
*/
|
|
1487
|
+
function MerkleHashSummaryFactory$1(treeFactory, proofFactory) {
|
|
1488
|
+
this.treeFactory = treeFactory;
|
|
1489
|
+
this.proofFactory = proofFactory;
|
|
1490
|
+
}
|
|
1491
|
+
/**
|
|
1492
|
+
* @param {any} value
|
|
1493
|
+
* @param {MerkleHashCalculator} calculator
|
|
1494
|
+
*/
|
|
1495
|
+
MerkleHashSummaryFactory$1.prototype.calculateMerkleRoot = function (value, calculator) {
|
|
1496
|
+
var binaryTree = this.treeFactory.build(value);
|
|
1497
|
+
var proofTree = this.proofFactory.buildFromBinaryTree(binaryTree, calculator);
|
|
1498
|
+
return this.calculateMerkleRootOfTree(proofTree, calculator);
|
|
1499
|
+
};
|
|
1500
|
+
/**
|
|
1501
|
+
* @param {MerkleProofTree} value
|
|
1502
|
+
* @param {MerkleHashCalculator} calculator
|
|
1503
|
+
*/
|
|
1504
|
+
MerkleHashSummaryFactory$1.prototype.calculateMerkleTreeRoot = function (tree, calculator) {
|
|
1505
|
+
return this.calculateMerkleRootOfTree(tree, calculator);
|
|
1506
|
+
};
|
|
1507
|
+
/**
|
|
1508
|
+
* @param {MerkleProofTree} proofTree
|
|
1509
|
+
* @param {MerkleHashCalculator} calculator
|
|
1510
|
+
*/
|
|
1511
|
+
MerkleHashSummaryFactory$1.prototype.calculateMerkleRootOfTree = function (proofTree, calculator) {
|
|
1512
|
+
var calculatedSummary = this.calculateMerkleRootInternal(proofTree.root, calculator);
|
|
1513
|
+
return new MerkleHashSummary(calculatedSummary);
|
|
1514
|
+
};
|
|
1515
|
+
/**
|
|
1516
|
+
* @param {MerkleProofElement} currentElement
|
|
1517
|
+
* @param {MerkleHashCalculator} calculator
|
|
1518
|
+
*/
|
|
1519
|
+
MerkleHashSummaryFactory$1.prototype.calculateMerkleRootInternal = function (currentElement, calculator) {
|
|
1520
|
+
if (currentElement instanceof ProofHashedLeaf) {
|
|
1521
|
+
return currentElement.merkleHash;
|
|
1522
|
+
}
|
|
1523
|
+
else if (currentElement instanceof ProofValueLeaf) {
|
|
1524
|
+
var value = currentElement.content;
|
|
1525
|
+
if (calculator.isContainerProofValueLeaf(value)) {
|
|
1526
|
+
// We have a container value to prove, so need to convert the value to a binary tree, and THEN hash it
|
|
1527
|
+
var merkleProofTree = this.buildProofTree(value, calculator);
|
|
1528
|
+
return this.calculateMerkleRootInternal(merkleProofTree.root, calculator);
|
|
1529
|
+
}
|
|
1530
|
+
else {
|
|
1531
|
+
// This is a primitive value, just hash it
|
|
1532
|
+
return calculator.calculateLeafHash(value);
|
|
1533
|
+
}
|
|
1534
|
+
}
|
|
1535
|
+
else if (currentElement instanceof ProofNode) {
|
|
1536
|
+
var left = this.calculateMerkleRootInternal(currentElement.left, calculator);
|
|
1537
|
+
var right = this.calculateMerkleRootInternal(currentElement.right, calculator);
|
|
1538
|
+
return calculator.calculateNodeHash(currentElement.prefix, left, right);
|
|
1539
|
+
}
|
|
1540
|
+
else {
|
|
1541
|
+
throw new Error("Should have handled this type? " + typeof currentElement);
|
|
1542
|
+
}
|
|
1543
|
+
};
|
|
1544
|
+
/**
|
|
1545
|
+
* @param {any} value
|
|
1546
|
+
* @param {MerkleHashCalculator} calculator
|
|
1547
|
+
*/
|
|
1548
|
+
MerkleHashSummaryFactory$1.prototype.buildProofTree = function (value, calculator) {
|
|
1549
|
+
var root = this.treeFactory.build(value);
|
|
1550
|
+
return this.proofFactory.buildFromBinaryTree(root, calculator);
|
|
1551
|
+
};
|
|
1552
|
+
var merklehashsummaryfactory = { MerkleHashSummaryFactory: MerkleHashSummaryFactory$1 };
|
|
1553
|
+
|
|
1554
|
+
var MerkleHashSummaryFactory = merklehashsummaryfactory.MerkleHashSummaryFactory;
|
|
1555
|
+
var BinaryTreeFactory = binarytreefactory.BinaryTreeFactory;
|
|
1556
|
+
var MerkleProofTreeFactory = merkleprooftreefactory.MerkleProofTreeFactory;
|
|
1557
|
+
var treeFactory = new BinaryTreeFactory();
|
|
1558
|
+
var proofFactory = new MerkleProofTreeFactory();
|
|
1559
|
+
/**
|
|
1560
|
+
* Calculates the merkle root hash of the structure.
|
|
1561
|
+
*
|
|
1562
|
+
* @param {any} value
|
|
1563
|
+
* @param {MerkleHashCalculator} calculator describes the method we use for hashing and serialization
|
|
1564
|
+
* @return the merkle root hash (32 bytes) of the data structure.
|
|
1565
|
+
*/
|
|
1566
|
+
function merkleHash(value, calculator) {
|
|
1567
|
+
return merkleHashSummary(value, calculator).merkleHash;
|
|
1568
|
+
}
|
|
1569
|
+
/**
|
|
1570
|
+
*
|
|
1571
|
+
* @param {MerkleProofTree} tree
|
|
1572
|
+
* @param {MerkleHashCalculator} calculator
|
|
1573
|
+
*/
|
|
1574
|
+
function merkleTreeHash(tree, calculator) {
|
|
1575
|
+
return merkleProofHashSummary(tree, calculator).merkleHash;
|
|
1576
|
+
}
|
|
1577
|
+
/**
|
|
1578
|
+
* Calculates the merkle root hash of the structure
|
|
1579
|
+
*
|
|
1580
|
+
* @param {any} value
|
|
1581
|
+
* @param {MerkleHashCalculator} calculator describes the method we use for hashing and serialization
|
|
1582
|
+
* @return the merkle root hash summary
|
|
1583
|
+
*/
|
|
1584
|
+
function merkleHashSummary(value, calculator) {
|
|
1585
|
+
var summaryFactory = new MerkleHashSummaryFactory(treeFactory, proofFactory);
|
|
1586
|
+
return summaryFactory.calculateMerkleRoot(value, calculator);
|
|
1587
|
+
}
|
|
1588
|
+
/**
|
|
1589
|
+
*
|
|
1590
|
+
* @param {MerkleProofTree} tree
|
|
1591
|
+
* @param {MerkleHashCalculator} calculator
|
|
1592
|
+
*/
|
|
1593
|
+
function merkleProofHashSummary(tree, calculator) {
|
|
1594
|
+
var summaryFactory = new MerkleHashSummaryFactory(treeFactory, proofFactory);
|
|
1595
|
+
return summaryFactory.calculateMerkleTreeRoot(tree, calculator);
|
|
1596
|
+
}
|
|
1597
|
+
/**
|
|
1598
|
+
*
|
|
1599
|
+
* @param {any} value
|
|
1600
|
+
* @param {PathSet} pathSet
|
|
1601
|
+
* @param {MerkleHashCalculator} calculator
|
|
1602
|
+
*/
|
|
1603
|
+
function generateProof(value, pathSet, calculator) {
|
|
1604
|
+
var binaryTree = treeFactory.buildWithPath(value, pathSet);
|
|
1605
|
+
return proofFactory.buildFromBinaryTree(binaryTree, calculator);
|
|
1606
|
+
}
|
|
1607
|
+
var merkleproof = { merkleHash, merkleTreeHash, merkleHashSummary, generateProof };
|
|
1608
|
+
|
|
1609
|
+
const theMerkleHashCalculator = new merklehashcalculator.MerkleHashCalculator(new merklehashcalculator.CryptoSystem());
|
|
1610
|
+
const gtvHash = (obj) => {
|
|
1611
|
+
return merkleproof.merkleHashSummary(obj, theMerkleHashCalculator).merkleHash;
|
|
1612
|
+
};
|
|
1613
|
+
const encode$1 = encodeValue;
|
|
1614
|
+
const decode$1 = decodeValue;
|
|
1615
|
+
|
|
1616
|
+
var index = /*#__PURE__*/Object.freeze({
|
|
1617
|
+
__proto__: null,
|
|
1618
|
+
decode: decode$1,
|
|
1619
|
+
encode: encode$1,
|
|
1620
|
+
gtvHash: gtvHash
|
|
1621
|
+
});
|
|
1622
|
+
|
|
1623
|
+
const encode = encodeValueGtx;
|
|
1624
|
+
const decode = decodeValueGtx;
|
|
1625
|
+
|
|
1626
|
+
function emptyGtx(blockchainRID) {
|
|
1627
|
+
return { blockchainRID: blockchainRID, operations: [], signers: [] };
|
|
1628
|
+
}
|
|
1629
|
+
/**
|
|
1630
|
+
* Adds a function call to a GTX. Creates a new GTX if none specified.
|
|
1631
|
+
* This function will throw Error if gtx is already signed
|
|
1632
|
+
* @param opName the name of the function to call
|
|
1633
|
+
* @param args the array of arguments of the function call. If no args, this must be an empty array
|
|
1634
|
+
* @param gtx the function call will be added to this gtx
|
|
1635
|
+
* @returns the gtx
|
|
1636
|
+
* @throws if gtx is null or if gtx is already signed
|
|
1637
|
+
*/
|
|
1638
|
+
function addTransactionToGtx(opName, args, gtx) {
|
|
1639
|
+
if (gtx == null) {
|
|
1640
|
+
throw new MissingGtxException();
|
|
1641
|
+
}
|
|
1642
|
+
if (gtx.signatures) {
|
|
1643
|
+
throw new AlreadySignedTransactionException("function");
|
|
1644
|
+
}
|
|
1645
|
+
gtx.operations.push({ opName: opName, args: args });
|
|
1646
|
+
return gtx;
|
|
1647
|
+
}
|
|
1648
|
+
function addSignerToGtx(signer, gtx) {
|
|
1649
|
+
if (gtx.signatures) {
|
|
1650
|
+
throw new AlreadySignedTransactionException("signer");
|
|
1651
|
+
}
|
|
1652
|
+
gtx.signers.push(signer);
|
|
1653
|
+
}
|
|
1654
|
+
/**
|
|
1655
|
+
* Serializes the gtx for signing
|
|
1656
|
+
* @param gtx the gtx to serialize
|
|
1657
|
+
*/
|
|
1658
|
+
function getDigestToSign(gtx) {
|
|
1659
|
+
return gtvHash(gtvTxBody(gtx));
|
|
1660
|
+
}
|
|
1661
|
+
function gtvTxBody(gtx) {
|
|
1662
|
+
return [
|
|
1663
|
+
gtx.blockchainRID,
|
|
1664
|
+
gtx.operations.map((op) => [op.opName, op.args]),
|
|
1665
|
+
gtx.signers,
|
|
1666
|
+
];
|
|
1667
|
+
}
|
|
1668
|
+
/**
|
|
1669
|
+
* Signs the gtx with the provided privKey. This is a convenience function
|
|
1670
|
+
* for situations where you don't have to ask someone else to sign.
|
|
1671
|
+
*/
|
|
1672
|
+
function sign(privKey, pubKey, gtx) {
|
|
1673
|
+
const digestToSign = getDigestToSign(gtx);
|
|
1674
|
+
const signature = signDigest(digestToSign, privKey);
|
|
1675
|
+
addSignature(pubKey, signature, gtx);
|
|
1676
|
+
}
|
|
1677
|
+
function signRawTransaction(_keyPair, _rawTransaction) {
|
|
1678
|
+
throw Error("TODO");
|
|
1679
|
+
//TODO
|
|
1680
|
+
//const gtx = module.exports.deserialize(rawTransaction);
|
|
1681
|
+
//module.exports.sign(keyPair.privKey, keyPair.pubKey, gtx);
|
|
1682
|
+
// return module.exports.serialize(gtx)
|
|
1683
|
+
}
|
|
1684
|
+
/**
|
|
1685
|
+
* Adds a signature to the gtx
|
|
1686
|
+
*/
|
|
1687
|
+
function addSignature(pubKeyBuffer, signatureBuffer, gtx) {
|
|
1688
|
+
if (!gtx.signatures) {
|
|
1689
|
+
gtx.signatures = Array(gtx.signers.length).fill(Buffer.alloc(64));
|
|
1690
|
+
}
|
|
1691
|
+
if (gtx.signers.length !== gtx.signatures.length) {
|
|
1692
|
+
throw new NumberOfSignersAndSignaturesException();
|
|
1693
|
+
}
|
|
1694
|
+
const signerIndex = gtx.signers.findIndex((signer) => pubKeyBuffer.equals(signer));
|
|
1695
|
+
if (signerIndex === -1) {
|
|
1696
|
+
throw new MissingSignerException();
|
|
1697
|
+
}
|
|
1698
|
+
gtx.signatures[signerIndex] = signatureBuffer;
|
|
1699
|
+
}
|
|
1700
|
+
function serialize(gtx) {
|
|
1701
|
+
if (!gtx.signatures) {
|
|
1702
|
+
// TODO
|
|
1703
|
+
// The gtx is not signed, but we must include
|
|
1704
|
+
// the signatures attribute, so let's add that.
|
|
1705
|
+
gtx.signatures = [];
|
|
1706
|
+
}
|
|
1707
|
+
return encode([gtvTxBody(gtx), gtx.signatures]);
|
|
1708
|
+
}
|
|
1709
|
+
function deserialize(gtxBytes) {
|
|
1710
|
+
const deserializedTx = decode(gtxBytes);
|
|
1711
|
+
const body = deserializedTx[0];
|
|
1712
|
+
const gtvTxBody = {
|
|
1713
|
+
blockchainRID: body[0],
|
|
1714
|
+
operations: body[1].map((operation) => ({
|
|
1715
|
+
opName: operation[0],
|
|
1716
|
+
args: operation[1],
|
|
1717
|
+
})),
|
|
1718
|
+
signers: body[2],
|
|
1719
|
+
};
|
|
1720
|
+
const signatures = deserializedTx[1];
|
|
1721
|
+
return {
|
|
1722
|
+
blockchainRID: gtvTxBody.blockchainRID,
|
|
1723
|
+
operations: gtvTxBody.operations,
|
|
1724
|
+
signers: gtvTxBody.signers,
|
|
1725
|
+
signatures,
|
|
1726
|
+
};
|
|
1727
|
+
}
|
|
1728
|
+
function checkGTXSignatures(txHash, gtx) {
|
|
1729
|
+
for (const i in gtx.signers) {
|
|
1730
|
+
const signValid = checkDigestSignature(txHash, gtx.signers[i], gtx.signatures[i]);
|
|
1731
|
+
if (!signValid)
|
|
1732
|
+
return signValid;
|
|
1733
|
+
}
|
|
1734
|
+
return true;
|
|
1735
|
+
}
|
|
1736
|
+
|
|
1737
|
+
var gtx = /*#__PURE__*/Object.freeze({
|
|
1738
|
+
__proto__: null,
|
|
1739
|
+
addSignature: addSignature,
|
|
1740
|
+
addSignerToGtx: addSignerToGtx,
|
|
1741
|
+
addTransactionToGtx: addTransactionToGtx,
|
|
1742
|
+
checkGTXSignatures: checkGTXSignatures,
|
|
1743
|
+
deserialize: deserialize,
|
|
1744
|
+
emptyGtx: emptyGtx,
|
|
1745
|
+
getDigestToSign: getDigestToSign,
|
|
1746
|
+
gtvTxBody: gtvTxBody,
|
|
1747
|
+
serialize: serialize,
|
|
1748
|
+
sign: sign,
|
|
1749
|
+
signRawTransaction: signRawTransaction
|
|
1750
|
+
});
|
|
1751
|
+
|
|
1752
|
+
var MsgType;
|
|
1753
|
+
(function (MsgType) {
|
|
1754
|
+
MsgType["debug"] = "DEBUG";
|
|
1755
|
+
MsgType["info"] = "INFO";
|
|
1756
|
+
MsgType["error"] = "ERROR";
|
|
1757
|
+
MsgType["warning"] = "WARNING";
|
|
1758
|
+
})(MsgType || (MsgType = {}));
|
|
1759
|
+
var LogColor;
|
|
1760
|
+
(function (LogColor) {
|
|
1761
|
+
LogColor["red"] = "\u001B[91m";
|
|
1762
|
+
LogColor["green"] = "\u001B[92m";
|
|
1763
|
+
LogColor["blue"] = "\u001B[36m";
|
|
1764
|
+
LogColor["yellow"] = "\u001B[93m";
|
|
1765
|
+
LogColor["stopColor"] = "\u001B[0m";
|
|
1766
|
+
})(LogColor || (LogColor = {}));
|
|
1767
|
+
let logLevel = 1;
|
|
1768
|
+
function setLogLevel(level) {
|
|
1769
|
+
logLevel = level;
|
|
1770
|
+
}
|
|
1771
|
+
function getLogLevel() {
|
|
1772
|
+
return logLevel;
|
|
1773
|
+
}
|
|
1774
|
+
function debug(message) {
|
|
1775
|
+
if (logLevel >= 3) {
|
|
1776
|
+
emitLogMessage(MsgType.debug, message, LogColor.blue);
|
|
1777
|
+
}
|
|
1778
|
+
}
|
|
1779
|
+
function info(message) {
|
|
1780
|
+
if (logLevel >= 2) {
|
|
1781
|
+
emitLogMessage(MsgType.info, message, LogColor.green);
|
|
1782
|
+
}
|
|
1783
|
+
}
|
|
1784
|
+
function error(message) {
|
|
1785
|
+
if (logLevel != -1) {
|
|
1786
|
+
emitLogMessage(MsgType.error, message, LogColor.red);
|
|
1787
|
+
}
|
|
1788
|
+
}
|
|
1789
|
+
function warning(message) {
|
|
1790
|
+
if (logLevel >= 1) {
|
|
1791
|
+
emitLogMessage(MsgType.warning, message, LogColor.yellow);
|
|
1792
|
+
}
|
|
1793
|
+
}
|
|
1794
|
+
function emitLogMessage(msgType, message, color) {
|
|
1795
|
+
const time = getTimestamp();
|
|
1796
|
+
console.log(`[${time}] ${color}${msgType}:${LogColor.stopColor} ${message}`);
|
|
1797
|
+
}
|
|
1798
|
+
function getTimestamp() {
|
|
1799
|
+
const pad = (n, s = 2) => `${new Array(s).fill(0)}${n}`.slice(-s);
|
|
1800
|
+
const date = new Date();
|
|
1801
|
+
return `${pad(date.getHours())}:${pad(date.getMinutes())}:${pad(date.getSeconds())}:${pad(date.getMilliseconds(), 3)}`;
|
|
1802
|
+
}
|
|
1803
|
+
|
|
1804
|
+
var logger = /*#__PURE__*/Object.freeze({
|
|
1805
|
+
__proto__: null,
|
|
1806
|
+
debug: debug,
|
|
1807
|
+
error: error,
|
|
1808
|
+
getLogLevel: getLogLevel,
|
|
1809
|
+
info: info,
|
|
1810
|
+
setLogLevel: setLogLevel,
|
|
1811
|
+
warning: warning
|
|
1812
|
+
});
|
|
1813
|
+
|
|
1814
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
1815
|
+
const secp256k1 = require("secp256k1");
|
|
1816
|
+
function createClient(restApiClient, blockchainRID, functionNames) {
|
|
1817
|
+
functionNames.push("message");
|
|
1818
|
+
function transaction(gtx$1) {
|
|
1819
|
+
return {
|
|
1820
|
+
gtx: gtx$1,
|
|
1821
|
+
sign: function (privKey, pubKey) {
|
|
1822
|
+
let pub = pubKey;
|
|
1823
|
+
if (!pub) {
|
|
1824
|
+
debug(`pubKey not provided, will instead be generated using secp256k1`);
|
|
1825
|
+
pub = Buffer.from(secp256k1.publicKeyCreate(privKey));
|
|
1826
|
+
}
|
|
1827
|
+
debug(`signing transaction with privKey: ${privKey}, pubKey: ${pub}`);
|
|
1828
|
+
sign(privKey, pub, this.gtx);
|
|
1829
|
+
},
|
|
1830
|
+
getTxRID: function () {
|
|
1831
|
+
return this.getDigestToSign();
|
|
1832
|
+
},
|
|
1833
|
+
getDigestToSign: function () {
|
|
1834
|
+
return getDigestToSign(this.gtx);
|
|
1835
|
+
},
|
|
1836
|
+
addSignature: function (pubKey, signature) {
|
|
1837
|
+
addSignature(pubKey, signature, this.gtx);
|
|
1838
|
+
},
|
|
1839
|
+
// raw call
|
|
1840
|
+
addOperation: function (name, ...args) {
|
|
1841
|
+
addTransactionToGtx(name, args, this.gtx);
|
|
1842
|
+
},
|
|
1843
|
+
postAndWaitConfirmation() {
|
|
1844
|
+
return restApiClient.postAndWaitConfirmation(serialize(this.gtx), this.getTxRID());
|
|
1845
|
+
},
|
|
1846
|
+
send: function (callback) {
|
|
1847
|
+
const gtxBytes = serialize(this.gtx);
|
|
1848
|
+
restApiClient.postTransaction(gtxBytes, callback);
|
|
1849
|
+
this.gtx = null;
|
|
1850
|
+
this.gtxBytes = gtxBytes;
|
|
1851
|
+
},
|
|
1852
|
+
encode: function () {
|
|
1853
|
+
return serialize(this.gtx);
|
|
1854
|
+
},
|
|
1855
|
+
};
|
|
1856
|
+
}
|
|
1857
|
+
function addFunctions(req) {
|
|
1858
|
+
functionNames.forEach((functionName) => {
|
|
1859
|
+
req[functionName] = function (...args) {
|
|
1860
|
+
addTransactionToGtx(functionName, args, this.gtx);
|
|
1861
|
+
};
|
|
1862
|
+
});
|
|
1863
|
+
}
|
|
1864
|
+
const client = {
|
|
1865
|
+
newTransaction: function (signers) {
|
|
1866
|
+
signers = removeDuplicateSigners(signers);
|
|
1867
|
+
const newGtx = emptyGtx(Buffer.from(blockchainRID, "hex"));
|
|
1868
|
+
signers.forEach((signer) => addSignerToGtx(signer, newGtx));
|
|
1869
|
+
const req = transaction(newGtx);
|
|
1870
|
+
addFunctions(req);
|
|
1871
|
+
return req;
|
|
1872
|
+
},
|
|
1873
|
+
transactionFromRawTransaction: function (rawTransaction) {
|
|
1874
|
+
const gtx$1 = deserialize(rawTransaction);
|
|
1875
|
+
debug(`Output from deserializing a raw transaction: ${JSON.stringify(gtx$1)}`);
|
|
1876
|
+
const req = transaction(gtx$1);
|
|
1877
|
+
addFunctions(req);
|
|
1878
|
+
return req;
|
|
1879
|
+
},
|
|
1880
|
+
query: function (queryObject, callback) {
|
|
1881
|
+
return restApiClient.query(queryObject, callback);
|
|
1882
|
+
},
|
|
1883
|
+
};
|
|
1884
|
+
return client;
|
|
1885
|
+
}
|
|
1886
|
+
|
|
1887
|
+
var gtxclient = /*#__PURE__*/Object.freeze({
|
|
1888
|
+
__proto__: null,
|
|
1889
|
+
createClient: createClient
|
|
1890
|
+
});
|
|
1891
|
+
|
|
1892
|
+
var ResponseStatus;
|
|
1893
|
+
(function (ResponseStatus) {
|
|
1894
|
+
ResponseStatus["Confirmed"] = "confirmed";
|
|
1895
|
+
ResponseStatus["Rejected"] = "rejected";
|
|
1896
|
+
ResponseStatus["Unknown"] = "unknown";
|
|
1897
|
+
ResponseStatus["Waiting"] = "waiting";
|
|
1898
|
+
})(ResponseStatus || (ResponseStatus = {}));
|
|
1899
|
+
var Method;
|
|
1900
|
+
(function (Method) {
|
|
1901
|
+
Method["GET"] = "get";
|
|
1902
|
+
Method["POST"] = "post";
|
|
1903
|
+
})(Method || (Method = {}));
|
|
1904
|
+
|
|
1905
|
+
class TxRejectedError extends Error {
|
|
1906
|
+
constructor(rejectReason) {
|
|
1907
|
+
super("Transaction was rejected");
|
|
1908
|
+
this.name = "TxRejectedError";
|
|
1909
|
+
this.fullReason = rejectReason;
|
|
1910
|
+
const parsed = rejectReason.match(/^\[(.+)\] Operation '(.+)' failed: (.+)$/);
|
|
1911
|
+
if (parsed) {
|
|
1912
|
+
this.shortReason = parsed[3];
|
|
1913
|
+
this.rellLine = parsed[1];
|
|
1914
|
+
this.operation = parsed[2];
|
|
1915
|
+
}
|
|
1916
|
+
}
|
|
1917
|
+
}
|
|
1918
|
+
class UnexpectedStatusError extends Error {
|
|
1919
|
+
constructor(status) {
|
|
1920
|
+
super(`Unexpected status code from server: ${status}`);
|
|
1921
|
+
}
|
|
1922
|
+
}
|
|
1923
|
+
class LostMessageError extends Error {
|
|
1924
|
+
constructor() {
|
|
1925
|
+
super(`Server lost our message`);
|
|
1926
|
+
}
|
|
1927
|
+
}
|
|
1928
|
+
class UnexpectedResponseError extends Error {
|
|
1929
|
+
constructor() {
|
|
1930
|
+
super(`got unexpected response from server`);
|
|
1931
|
+
}
|
|
1932
|
+
}
|
|
1933
|
+
class UnvalidTxRidException extends Error {
|
|
1934
|
+
constructor(txRID) {
|
|
1935
|
+
super(`expected length 32 of txRID, but got ${txRID.length}`);
|
|
1936
|
+
}
|
|
1937
|
+
}
|
|
1938
|
+
class SerializedTransactionFormatException extends Error {
|
|
1939
|
+
constructor() {
|
|
1940
|
+
super(`messageHash is not a Buffer`);
|
|
1941
|
+
}
|
|
1942
|
+
}
|
|
1943
|
+
class GetBridFromChainException extends Error {
|
|
1944
|
+
constructor(chainId, reason) {
|
|
1945
|
+
super(`Error resolving BRID for chainId ${chainId}, reason: ${reason}`);
|
|
1946
|
+
}
|
|
1947
|
+
}
|
|
1948
|
+
class EmptyListOfUrlsException extends Error {
|
|
1949
|
+
constructor() {
|
|
1950
|
+
super(`Failed to initialize rest client with empty list of urls`);
|
|
1951
|
+
}
|
|
1952
|
+
}
|
|
1953
|
+
|
|
1954
|
+
var __awaiter$2 = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
1955
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
1956
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
1957
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
1958
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
1959
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
1960
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
1961
|
+
});
|
|
1962
|
+
};
|
|
1963
|
+
function getBrid(urlBase, chainId) {
|
|
1964
|
+
if (chainId >= 0) {
|
|
1965
|
+
const url = `${urlBase}/brid/iid_${chainId}`;
|
|
1966
|
+
return fetch(url).then((response) => {
|
|
1967
|
+
if (response.ok)
|
|
1968
|
+
return response.text();
|
|
1969
|
+
throw new GetBridFromChainException(chainId, response.statusText);
|
|
1970
|
+
});
|
|
1971
|
+
}
|
|
1972
|
+
else {
|
|
1973
|
+
const url = `${urlBase}/_debug`;
|
|
1974
|
+
return fetch(url).then((response) => {
|
|
1975
|
+
if (response.ok)
|
|
1976
|
+
return response
|
|
1977
|
+
.json()
|
|
1978
|
+
.then((json) => json.blockchain[json.blockchain.length - 1].brid);
|
|
1979
|
+
throw new GetBridFromChainException(chainId, response.statusText);
|
|
1980
|
+
});
|
|
1981
|
+
}
|
|
1982
|
+
}
|
|
1983
|
+
function requestWithRetry(method, path, config, postObject) {
|
|
1984
|
+
return __awaiter$2(this, void 0, void 0, function* () {
|
|
1985
|
+
let statusCode, rspBody, error;
|
|
1986
|
+
const noRetryStatusCodes = [200, 400, 409, 500];
|
|
1987
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
1988
|
+
for (const _endpoint of config.endpointPool) {
|
|
1989
|
+
const endpoint = nextEndpoint(config.endpointPool);
|
|
1990
|
+
for (let attempt = 0; attempt < config.attemptsPerEndpoint; attempt++) {
|
|
1991
|
+
({ error, statusCode, rspBody } = yield handleRequest(method, path, endpoint, postObject));
|
|
1992
|
+
if (noRetryStatusCodes.includes(statusCode)) {
|
|
1993
|
+
return { error, statusCode, rspBody };
|
|
1994
|
+
}
|
|
1995
|
+
if (statusCode == 503) {
|
|
1996
|
+
break;
|
|
1997
|
+
}
|
|
1998
|
+
info(`${method} request failed on ${endpoint}. Attempt: ${attempt + 1} / ${config.attemptsPerEndpoint}`);
|
|
1999
|
+
yield sleep(config.attemptInterval);
|
|
2000
|
+
}
|
|
2001
|
+
}
|
|
2002
|
+
return { error, statusCode, rspBody };
|
|
2003
|
+
});
|
|
2004
|
+
}
|
|
2005
|
+
function handleRequest(method, path, endpoint, postObject) {
|
|
2006
|
+
return __awaiter$2(this, void 0, void 0, function* () {
|
|
2007
|
+
if (method == Method.GET) {
|
|
2008
|
+
return yield get(path, endpoint);
|
|
2009
|
+
}
|
|
2010
|
+
else {
|
|
2011
|
+
return yield post(path, endpoint, postObject);
|
|
2012
|
+
}
|
|
2013
|
+
});
|
|
2014
|
+
}
|
|
2015
|
+
/**
|
|
2016
|
+
* Sends request to get data from a given API endpoint.
|
|
2017
|
+
* @param path API endpoint of Rell backend
|
|
2018
|
+
* @param endpoint
|
|
2019
|
+
*/
|
|
2020
|
+
function get(path, endpoint) {
|
|
2021
|
+
return __awaiter$2(this, void 0, void 0, function* () {
|
|
2022
|
+
debug("GET URL " + new URL(path, endpoint).href);
|
|
2023
|
+
try {
|
|
2024
|
+
const response = yield fetch(new URL(path, endpoint).href);
|
|
2025
|
+
if (response.status == 404) {
|
|
2026
|
+
return { error: null, statusCode: response.status, rspBody: null };
|
|
2027
|
+
}
|
|
2028
|
+
const rspBody = yield response.json();
|
|
2029
|
+
return { error: null, statusCode: response.status, rspBody };
|
|
2030
|
+
}
|
|
2031
|
+
catch (error$1) {
|
|
2032
|
+
error(error$1.message);
|
|
2033
|
+
return { error: error$1, statusCode: null, rspBody: null };
|
|
2034
|
+
}
|
|
2035
|
+
});
|
|
2036
|
+
}
|
|
2037
|
+
/**
|
|
2038
|
+
* Sends request to post data to a given API endpoint.
|
|
2039
|
+
* @param path API endpoint of Rell backend
|
|
2040
|
+
* @param endpoint
|
|
2041
|
+
* @param requestBody request body
|
|
2042
|
+
*/
|
|
2043
|
+
function post(path, endpoint, requestBody) {
|
|
2044
|
+
return __awaiter$2(this, void 0, void 0, function* () {
|
|
2045
|
+
debug("POST URL " + new URL(path, endpoint).href);
|
|
2046
|
+
debug("POST body " + JSON.stringify(requestBody));
|
|
2047
|
+
if (Buffer.isBuffer(requestBody)) {
|
|
2048
|
+
try {
|
|
2049
|
+
const requestOptions = {
|
|
2050
|
+
method: "post",
|
|
2051
|
+
body: requestBody,
|
|
2052
|
+
};
|
|
2053
|
+
const response = yield fetch(new URL(path, endpoint).href, requestOptions);
|
|
2054
|
+
return {
|
|
2055
|
+
error: null,
|
|
2056
|
+
statusCode: response.status,
|
|
2057
|
+
rspBody: decodeValue(Buffer.from(yield response.arrayBuffer())),
|
|
2058
|
+
};
|
|
2059
|
+
}
|
|
2060
|
+
catch (error) {
|
|
2061
|
+
return { error, statusCode: null, rspBody: null };
|
|
2062
|
+
}
|
|
2063
|
+
}
|
|
2064
|
+
else {
|
|
2065
|
+
try {
|
|
2066
|
+
const response = yield fetch(new URL(path, endpoint).href, {
|
|
2067
|
+
method: "post",
|
|
2068
|
+
body: JSON.stringify(requestBody),
|
|
2069
|
+
});
|
|
2070
|
+
return {
|
|
2071
|
+
error: null,
|
|
2072
|
+
statusCode: response.status,
|
|
2073
|
+
rspBody: yield response.json(),
|
|
2074
|
+
};
|
|
2075
|
+
}
|
|
2076
|
+
catch (error) {
|
|
2077
|
+
return { error, statusCode: null, rspBody: null };
|
|
2078
|
+
}
|
|
2079
|
+
}
|
|
2080
|
+
});
|
|
2081
|
+
}
|
|
2082
|
+
function nextEndpoint(endpointPool) {
|
|
2083
|
+
return endpointPool[Math.floor(Math.random() * endpointPool.length)];
|
|
2084
|
+
}
|
|
2085
|
+
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
2086
|
+
|
|
2087
|
+
var restclientutil = /*#__PURE__*/Object.freeze({
|
|
2088
|
+
__proto__: null,
|
|
2089
|
+
getBrid: getBrid,
|
|
2090
|
+
handleRequest: handleRequest,
|
|
2091
|
+
nextEndpoint: nextEndpoint,
|
|
2092
|
+
requestWithRetry: requestWithRetry,
|
|
2093
|
+
sleep: sleep
|
|
2094
|
+
});
|
|
2095
|
+
|
|
2096
|
+
var __awaiter$1 = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2097
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
2098
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
2099
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
2100
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
2101
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
2102
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
2103
|
+
});
|
|
2104
|
+
};
|
|
2105
|
+
function createRestClient(endpointPool, blockchainRID, maxSockets = 10, pollingInterval = 500, failOverConfig) {
|
|
2106
|
+
validateInput(endpointPool, failOverConfig);
|
|
2107
|
+
return {
|
|
2108
|
+
config: {
|
|
2109
|
+
endpointPool: endpointPool,
|
|
2110
|
+
pool: { maxSockets },
|
|
2111
|
+
pollingInterval,
|
|
2112
|
+
attemptsPerEndpoint: (failOverConfig === null || failOverConfig === void 0 ? void 0 : failOverConfig.attemptsPerEndpoint) || 3,
|
|
2113
|
+
attemptInterval: (failOverConfig === null || failOverConfig === void 0 ? void 0 : failOverConfig.attemptInterval) || 500,
|
|
2114
|
+
},
|
|
2115
|
+
/**
|
|
2116
|
+
* Retrieves the client message with the specified double-sha256 hash
|
|
2117
|
+
* @param txRID the id of the transaction
|
|
2118
|
+
* @param callback parameters (error, serializedMessage) if first
|
|
2119
|
+
* parameter is not null, an error occurred.
|
|
2120
|
+
* If first parameter is null, then the second parameter is a buffer
|
|
2121
|
+
* with the serialized client message. If no such client message exists,
|
|
2122
|
+
* the callback will be called with (null, null).
|
|
2123
|
+
*/
|
|
2124
|
+
getTransaction: function (txRID, callback) {
|
|
2125
|
+
return __awaiter$1(this, void 0, void 0, function* () {
|
|
2126
|
+
if (!validTxRID(txRID)) {
|
|
2127
|
+
callback(new UnvalidTxRidException(txRID), null);
|
|
2128
|
+
}
|
|
2129
|
+
else {
|
|
2130
|
+
const { error, statusCode, rspBody } = yield requestWithRetry(Method.GET, "tx/" + blockchainRID + "/" + txRID.toString("hex"), this.config);
|
|
2131
|
+
handleGetResponse(error, statusCode, statusCode === 200 ? toBuffer(rspBody.tx) : rspBody, callback);
|
|
2132
|
+
}
|
|
2133
|
+
});
|
|
2134
|
+
},
|
|
2135
|
+
/**
|
|
2136
|
+
* Sends a transaction to postchain for inclusion in a block.
|
|
2137
|
+
* Use status() to monitor progress once this transaction is
|
|
2138
|
+
* posted.
|
|
2139
|
+
*
|
|
2140
|
+
* @param serializedTransaction The transaction (a buffer) to send
|
|
2141
|
+
* @param callback taking parameter (error, responseObject) if error is null
|
|
2142
|
+
* then resonseObject is also null. If error is not null, then responseObject
|
|
2143
|
+
* is an object with the string property 'error'
|
|
2144
|
+
*/
|
|
2145
|
+
postTransaction: function (serializedTransaction, callback) {
|
|
2146
|
+
return __awaiter$1(this, void 0, void 0, function* () {
|
|
2147
|
+
if (!Buffer.isBuffer(serializedTransaction)) {
|
|
2148
|
+
throw new SerializedTransactionFormatException();
|
|
2149
|
+
}
|
|
2150
|
+
const transactionObject = {
|
|
2151
|
+
tx: serializedTransaction.toString("hex"),
|
|
2152
|
+
};
|
|
2153
|
+
const { error, statusCode, rspBody } = yield requestWithRetry(Method.POST, "tx/" + blockchainRID, this.config, transactionObject);
|
|
2154
|
+
handlePostResponse(error, statusCode, rspBody, callback);
|
|
2155
|
+
});
|
|
2156
|
+
},
|
|
2157
|
+
/**
|
|
2158
|
+
* Retrieves a confirmation proof for a client message with the specified double-sha256
|
|
2159
|
+
* hash.
|
|
2160
|
+
* @param txRID the id of the transaction
|
|
2161
|
+
* @param callback parameters (error, responseObjectProof) if first
|
|
2162
|
+
* parameter is not null, an error occurred.
|
|
2163
|
+
* If first parameter is null, then the second parameter is an object
|
|
2164
|
+
* like the following:
|
|
2165
|
+
*
|
|
2166
|
+
* {hash: messageHashBuffer,
|
|
2167
|
+
* blockHeader: blockHeaderBuffer,
|
|
2168
|
+
* signatures: [{pubKey: pubKeyBuffer, signature: sigBuffer}, ...],
|
|
2169
|
+
* merklePath: [{side: <0|1>, hash: <hash buffer level n-1>},
|
|
2170
|
+
* ...
|
|
2171
|
+
* {side: <0|1>, hash: <hash buffer level 1>}]}
|
|
2172
|
+
*
|
|
2173
|
+
* If no such client message exists, the callback will be called with (null, null).
|
|
2174
|
+
*
|
|
2175
|
+
* The proof object can be validated using
|
|
2176
|
+
* postchain-common.util.validateMerklePath(proof.merklePath, proof.hash,
|
|
2177
|
+
* proof.blockHeader.slice(32, 64))
|
|
2178
|
+
*
|
|
2179
|
+
* The signatures must be validated agains some know trusted source for valid signers
|
|
2180
|
+
* at this specific block height.
|
|
2181
|
+
*/
|
|
2182
|
+
getConfirmationProof: function (txRID, callback) {
|
|
2183
|
+
return __awaiter$1(this, void 0, void 0, function* () {
|
|
2184
|
+
if (!validTxRID(txRID)) {
|
|
2185
|
+
callback(new UnvalidTxRidException(txRID), null);
|
|
2186
|
+
}
|
|
2187
|
+
else {
|
|
2188
|
+
const { error, statusCode, rspBody } = yield requestWithRetry(Method.GET, "tx/" +
|
|
2189
|
+
blockchainRID +
|
|
2190
|
+
"/" +
|
|
2191
|
+
txRID.toString("hex") +
|
|
2192
|
+
"/confirmationProof", this.config);
|
|
2193
|
+
const confirmationProof = {
|
|
2194
|
+
hash: undefined,
|
|
2195
|
+
blockHeader: undefined,
|
|
2196
|
+
signatures: [],
|
|
2197
|
+
merklePath: [],
|
|
2198
|
+
};
|
|
2199
|
+
if (statusCode === 200 || statusCode === 503) {
|
|
2200
|
+
confirmationProof.hash = toBuffer(rspBody.hash);
|
|
2201
|
+
confirmationProof.blockHeader = toBuffer(rspBody.blockHeader);
|
|
2202
|
+
if (rspBody.signatures) {
|
|
2203
|
+
confirmationProof.signatures = rspBody.signatures.map((item) => ({
|
|
2204
|
+
pubKey: toBuffer(item.pubKey),
|
|
2205
|
+
signature: toBuffer(item.signature),
|
|
2206
|
+
}));
|
|
2207
|
+
}
|
|
2208
|
+
if (rspBody.merklePath) {
|
|
2209
|
+
confirmationProof.merklePath = rspBody.merklePath.map((item) => {
|
|
2210
|
+
return { side: item.side, hash: toBuffer(item.hash) };
|
|
2211
|
+
});
|
|
2212
|
+
}
|
|
2213
|
+
}
|
|
2214
|
+
handleGetResponse(error, statusCode, confirmationProof, callback);
|
|
2215
|
+
}
|
|
2216
|
+
});
|
|
2217
|
+
},
|
|
2218
|
+
/**
|
|
2219
|
+
* Queries the status of a certain transaction.
|
|
2220
|
+
* @param txRID the id of the transaction
|
|
2221
|
+
* @param callback taking parameters (error, responseBody). If error is null
|
|
2222
|
+
* then responseBody is an object on the form
|
|
2223
|
+
* { status: '<confirmed|waiting|rejected|unknown>' }
|
|
2224
|
+
* If error is not null, then responseBody
|
|
2225
|
+
* is an object with the string property 'error'
|
|
2226
|
+
*/
|
|
2227
|
+
status: function (txRID, callback) {
|
|
2228
|
+
return __awaiter$1(this, void 0, void 0, function* () {
|
|
2229
|
+
if (!validTxRID(txRID)) {
|
|
2230
|
+
callback(new UnvalidTxRidException(txRID), null);
|
|
2231
|
+
}
|
|
2232
|
+
else {
|
|
2233
|
+
const { error, statusCode, rspBody } = yield requestWithRetry(Method.GET, "tx/" + blockchainRID + "/" + txRID.toString("hex") + "/status", this.config);
|
|
2234
|
+
handleGetResponse(error, statusCode, rspBody, callback);
|
|
2235
|
+
}
|
|
2236
|
+
});
|
|
2237
|
+
},
|
|
2238
|
+
/**
|
|
2239
|
+
* Interfaces the query enpoint of the Rell backend. Returns either a resolved or rejected promise.
|
|
2240
|
+
* @param queryObject an object that must contain a "type" and follows this pattern: { type: "nameOfQuery", arg1: argValue1, arg2: argvalue2 }
|
|
2241
|
+
*/
|
|
2242
|
+
query: function (queryObject) {
|
|
2243
|
+
return __awaiter$1(this, void 0, void 0, function* () {
|
|
2244
|
+
// eslint-disable-next-line no-async-promise-executor
|
|
2245
|
+
return new Promise((resolve, reject) => __awaiter$1(this, void 0, void 0, function* () {
|
|
2246
|
+
const callback = (error, result) => {
|
|
2247
|
+
if (error) {
|
|
2248
|
+
reject(error);
|
|
2249
|
+
}
|
|
2250
|
+
else {
|
|
2251
|
+
resolve(result);
|
|
2252
|
+
}
|
|
2253
|
+
};
|
|
2254
|
+
const { error, statusCode, rspBody } = yield requestWithRetry(Method.POST, `query_gtv/${blockchainRID}`, this.config, encodeValue(toQueryObjectGTV(queryObject)));
|
|
2255
|
+
handlePostResponse(error, statusCode, rspBody, callback);
|
|
2256
|
+
}));
|
|
2257
|
+
});
|
|
2258
|
+
},
|
|
2259
|
+
/**
|
|
2260
|
+
* Polls for status while waiting for response; confirmed, rejected or unknown. Returns either a resolved or rejected promise.
|
|
2261
|
+
* @param txRID the id of the transaction
|
|
2262
|
+
*/
|
|
2263
|
+
waitConfirmation(txRID) {
|
|
2264
|
+
return new Promise((resolve, reject) => {
|
|
2265
|
+
this.status(txRID, (error$1, result) => {
|
|
2266
|
+
if (error$1) {
|
|
2267
|
+
reject(error$1);
|
|
2268
|
+
}
|
|
2269
|
+
else {
|
|
2270
|
+
const status = result.status;
|
|
2271
|
+
switch (status) {
|
|
2272
|
+
case ResponseStatus.Confirmed:
|
|
2273
|
+
resolve(null);
|
|
2274
|
+
break;
|
|
2275
|
+
case ResponseStatus.Rejected:
|
|
2276
|
+
reject(new TxRejectedError(result.rejectReason));
|
|
2277
|
+
break;
|
|
2278
|
+
case ResponseStatus.Unknown:
|
|
2279
|
+
reject(new LostMessageError());
|
|
2280
|
+
break;
|
|
2281
|
+
case ResponseStatus.Waiting:
|
|
2282
|
+
setTimeout(() => this.waitConfirmation(txRID).then(resolve, reject), this.config.pollingInterval);
|
|
2283
|
+
break;
|
|
2284
|
+
default:
|
|
2285
|
+
error(status);
|
|
2286
|
+
reject(new UnexpectedResponseError());
|
|
2287
|
+
}
|
|
2288
|
+
}
|
|
2289
|
+
});
|
|
2290
|
+
});
|
|
2291
|
+
},
|
|
2292
|
+
/**
|
|
2293
|
+
* Posts a transaction and polls for status while waiting for status response; confirmed, rejected or unknown. Returns either a resolved or rejected promise.
|
|
2294
|
+
* @param serializedTransaction The transaction (a buffer) to send
|
|
2295
|
+
* @param txRID the id of the transaction
|
|
2296
|
+
* @param validate true if the transaction needs to be validated
|
|
2297
|
+
*/
|
|
2298
|
+
postAndWaitConfirmation(serializedTransaction, txRID, validate) {
|
|
2299
|
+
if (validate === true) {
|
|
2300
|
+
return Promise.reject("Automatic validation is not yet implemented");
|
|
2301
|
+
}
|
|
2302
|
+
return new Promise((resolve, reject) => {
|
|
2303
|
+
this.postTransaction(serializedTransaction, (error) => {
|
|
2304
|
+
if (error)
|
|
2305
|
+
reject(error);
|
|
2306
|
+
else {
|
|
2307
|
+
setTimeout(() => this.waitConfirmation(txRID).then(resolve, reject), 1011);
|
|
2308
|
+
}
|
|
2309
|
+
});
|
|
2310
|
+
});
|
|
2311
|
+
},
|
|
2312
|
+
/**
|
|
2313
|
+
* Returns a string array with the endpoints hosting the dApp the client
|
|
2314
|
+
* is connected to
|
|
2315
|
+
*/
|
|
2316
|
+
getEndpointPool() {
|
|
2317
|
+
return this.config.endpointPool;
|
|
2318
|
+
},
|
|
2319
|
+
};
|
|
2320
|
+
}
|
|
2321
|
+
/**
|
|
2322
|
+
* Validates that txRID is a Buffer of 32 bytes.
|
|
2323
|
+
* @param txRID A buffer of 32 bytes
|
|
2324
|
+
*/
|
|
2325
|
+
function validTxRID(txRID) {
|
|
2326
|
+
if (txRID.length != 32) {
|
|
2327
|
+
const error$1 = new UnvalidTxRidException(txRID);
|
|
2328
|
+
error(error$1.toString());
|
|
2329
|
+
return false;
|
|
2330
|
+
}
|
|
2331
|
+
return true;
|
|
2332
|
+
}
|
|
2333
|
+
function validateInput(endpointPool, failOverConfig) {
|
|
2334
|
+
if (!endpointPool.length) {
|
|
2335
|
+
throw new EmptyListOfUrlsException();
|
|
2336
|
+
}
|
|
2337
|
+
if ((failOverConfig === null || failOverConfig === void 0 ? void 0 : failOverConfig.attemptsPerEndpoint) < 1) {
|
|
2338
|
+
debug("Attempts can not be 0 or below, setting it to 1");
|
|
2339
|
+
failOverConfig.attemptsPerEndpoint = 1;
|
|
2340
|
+
}
|
|
2341
|
+
}
|
|
2342
|
+
/**
|
|
2343
|
+
* @param error response error
|
|
2344
|
+
* @param statusCode response status code
|
|
2345
|
+
* @param responseObject the responsebody from the server
|
|
2346
|
+
* @param callback the callback function to propagate the error and response back to the caller
|
|
2347
|
+
*/
|
|
2348
|
+
function handleGetResponse(error$1, statusCode, responseObject, callback) {
|
|
2349
|
+
try {
|
|
2350
|
+
debug(`error: ${error$1}, status code: ${statusCode}, response body: ${JSON.stringify(responseObject)}`);
|
|
2351
|
+
if (error$1) {
|
|
2352
|
+
callback(error$1, null);
|
|
2353
|
+
}
|
|
2354
|
+
else if (statusCode === 404) {
|
|
2355
|
+
error("404 received");
|
|
2356
|
+
callback(null, null);
|
|
2357
|
+
}
|
|
2358
|
+
else if (statusCode != 200) {
|
|
2359
|
+
callback(new UnexpectedStatusError(statusCode), responseObject);
|
|
2360
|
+
}
|
|
2361
|
+
else {
|
|
2362
|
+
callback(null, responseObject);
|
|
2363
|
+
}
|
|
2364
|
+
}
|
|
2365
|
+
catch (error$1) {
|
|
2366
|
+
error("restclient.handleGetResponse(): Failed to call callback function " +
|
|
2367
|
+
error$1);
|
|
2368
|
+
}
|
|
2369
|
+
}
|
|
2370
|
+
/**
|
|
2371
|
+
* @param error response error
|
|
2372
|
+
* @param statusCode response status code
|
|
2373
|
+
* @param responseObject the responsebody from the server
|
|
2374
|
+
* @param callback the callback function to propagate the error and response back to the caller
|
|
2375
|
+
*/
|
|
2376
|
+
function handlePostResponse(error$1, statusCode, responseObject, callback) {
|
|
2377
|
+
debug(`error: ${error$1}, status code: ${statusCode}, response body: ${JSON.stringify(responseObject)}`);
|
|
2378
|
+
try {
|
|
2379
|
+
if (error$1) {
|
|
2380
|
+
error(`In restclient post(). ${error$1}`);
|
|
2381
|
+
callback(error$1);
|
|
2382
|
+
}
|
|
2383
|
+
else if (statusCode != 200) {
|
|
2384
|
+
error(`Unexpected status code from server: ${statusCode}`);
|
|
2385
|
+
callback(new UnexpectedStatusError(statusCode), responseObject);
|
|
2386
|
+
}
|
|
2387
|
+
else {
|
|
2388
|
+
info(`Calling responseCallback with responseObject: ${JSON.stringify(responseObject)}`);
|
|
2389
|
+
callback(null, responseObject);
|
|
2390
|
+
}
|
|
2391
|
+
}
|
|
2392
|
+
catch (error$1) {
|
|
2393
|
+
error("restclient.handlePostResponse(): Failed to call callback function " +
|
|
2394
|
+
error$1);
|
|
2395
|
+
}
|
|
2396
|
+
}
|
|
2397
|
+
|
|
2398
|
+
var restclient = /*#__PURE__*/Object.freeze({
|
|
2399
|
+
__proto__: null,
|
|
2400
|
+
createRestClient: createRestClient
|
|
2401
|
+
});
|
|
2402
|
+
|
|
2403
|
+
var internalNodePrefix = Buffer.alloc(1, 0);
|
|
2404
|
+
var leafPrefix = Buffer.alloc(1, 1);
|
|
2405
|
+
var nonExistingNodeHash = Buffer.alloc(32);
|
|
2406
|
+
function calculateRoot(hashes, depth, leafDepth) {
|
|
2407
|
+
var numTransactions = hashes.length;
|
|
2408
|
+
if (numTransactions === 0) {
|
|
2409
|
+
return Buffer.alloc(32);
|
|
2410
|
+
}
|
|
2411
|
+
if (depth === undefined) {
|
|
2412
|
+
depth = 0;
|
|
2413
|
+
}
|
|
2414
|
+
if (!leafDepth) {
|
|
2415
|
+
leafDepth = Math.ceil(Math.log2(numTransactions));
|
|
2416
|
+
}
|
|
2417
|
+
if (depth === leafDepth) {
|
|
2418
|
+
return hashes[0];
|
|
2419
|
+
}
|
|
2420
|
+
var maxLeavesPerChild = Math.pow(2, leafDepth - depth - 1);
|
|
2421
|
+
var prefix = depth === leafDepth - 1 ? leafPrefix : internalNodePrefix;
|
|
2422
|
+
if (numTransactions <= maxLeavesPerChild) {
|
|
2423
|
+
var left = calculateRoot(hashes, depth + 1, leafDepth);
|
|
2424
|
+
return hashConcat([prefix, left, nonExistingNodeHash]);
|
|
2425
|
+
}
|
|
2426
|
+
var left = calculateRoot(hashes.slice(0, maxLeavesPerChild), depth + 1, leafDepth);
|
|
2427
|
+
var right = calculateRoot(hashes.slice(maxLeavesPerChild), depth + 1, leafDepth);
|
|
2428
|
+
return hashConcat([prefix, left, prefix, right]);
|
|
2429
|
+
}
|
|
2430
|
+
function internalMerklePath(hashes, targetIndex, depth, leafDepth) {
|
|
2431
|
+
var numTransactions = hashes.length;
|
|
2432
|
+
if (depth === leafDepth) {
|
|
2433
|
+
return [];
|
|
2434
|
+
}
|
|
2435
|
+
var maxLeavesPerChild = Math.pow(2, leafDepth - depth - 1);
|
|
2436
|
+
if (numTransactions <= maxLeavesPerChild) {
|
|
2437
|
+
var path = internalMerklePath(hashes, targetIndex, depth + 1, leafDepth);
|
|
2438
|
+
path.push({ side: 1, hash: nonExistingNodeHash });
|
|
2439
|
+
return path;
|
|
2440
|
+
}
|
|
2441
|
+
if (targetIndex < maxLeavesPerChild) {
|
|
2442
|
+
var path = internalMerklePath(hashes.slice(0, maxLeavesPerChild), targetIndex, depth + 1, leafDepth);
|
|
2443
|
+
var right = calculateRoot(hashes.slice(maxLeavesPerChild), depth + 1, leafDepth);
|
|
2444
|
+
path.push({ side: 1, hash: right });
|
|
2445
|
+
}
|
|
2446
|
+
else {
|
|
2447
|
+
var left = calculateRoot(hashes.slice(0, maxLeavesPerChild), depth + 1, leafDepth);
|
|
2448
|
+
var path = internalMerklePath(hashes.slice(maxLeavesPerChild), targetIndex - maxLeavesPerChild, depth + 1, leafDepth);
|
|
2449
|
+
path.push({ side: 0, hash: left });
|
|
2450
|
+
}
|
|
2451
|
+
return path;
|
|
2452
|
+
}
|
|
2453
|
+
/*
|
|
2454
|
+
* a path looks like this:
|
|
2455
|
+
* {merklePath: [{side: <0|1>, hash: <hash buffer depth n-1>},
|
|
2456
|
+
* {side: <0|1>, hash: <hash buffer depth n-2>},
|
|
2457
|
+
* ...
|
|
2458
|
+
* {side: <0|1>, hash: <hash buffer depth 1>}]}
|
|
2459
|
+
*/
|
|
2460
|
+
function merklePath(hashes, target) {
|
|
2461
|
+
if (!hashes || hashes.length == 0) {
|
|
2462
|
+
throw new Error("Cannot make merkle path from empty transaction set");
|
|
2463
|
+
}
|
|
2464
|
+
var index = -1;
|
|
2465
|
+
for (var i = 0; i < hashes.length; i++) {
|
|
2466
|
+
if (hashes[i].equals(target)) {
|
|
2467
|
+
index = i;
|
|
2468
|
+
break;
|
|
2469
|
+
}
|
|
2470
|
+
}
|
|
2471
|
+
if (index === -1) {
|
|
2472
|
+
throw new Error("Target is not in list of hashes");
|
|
2473
|
+
}
|
|
2474
|
+
var leafDepth = Math.ceil(Math.log2(hashes.length));
|
|
2475
|
+
var path = internalMerklePath(hashes, index, 0, leafDepth);
|
|
2476
|
+
return path;
|
|
2477
|
+
}
|
|
2478
|
+
/**
|
|
2479
|
+
*
|
|
2480
|
+
* @param path The merkle path to validate.
|
|
2481
|
+
* Format [{side: <0|1>, hash: <hash buffer depth n-1>},
|
|
2482
|
+
* {side: <0|1>, hash: <hash buffer depth n-2>},
|
|
2483
|
+
* ...,
|
|
2484
|
+
* {side: <0|1>, hash: <hash buffer depth 1>}]
|
|
2485
|
+
|
|
2486
|
+
* @param target the leaf hash that the path proves belongs in the merkleRoot
|
|
2487
|
+
* @param merkleRoot The merkle root that supposedly contains the target via the supplied path.
|
|
2488
|
+
* The merkle root is typically taken from a block header.
|
|
2489
|
+
*/
|
|
2490
|
+
function validateMerklePath(path, target, merkleRoot) {
|
|
2491
|
+
let currentHash = target;
|
|
2492
|
+
for (let i = 0; i < path.length; i++) {
|
|
2493
|
+
const item = path[i];
|
|
2494
|
+
const prefix = (i === 0) ? Buffer.from([1]) : Buffer.from([0]);
|
|
2495
|
+
if (item.side === 0) {
|
|
2496
|
+
currentHash = hashConcat([prefix, item.hash, prefix, currentHash]);
|
|
2497
|
+
}
|
|
2498
|
+
else {
|
|
2499
|
+
if (item.hash.equals(nonExistingNodeHash)) {
|
|
2500
|
+
currentHash = hashConcat([prefix, currentHash, nonExistingNodeHash]);
|
|
2501
|
+
}
|
|
2502
|
+
else {
|
|
2503
|
+
currentHash = hashConcat([prefix, currentHash, prefix, item.hash]);
|
|
2504
|
+
}
|
|
2505
|
+
}
|
|
2506
|
+
}
|
|
2507
|
+
return merkleRoot.equals(currentHash);
|
|
2508
|
+
}
|
|
2509
|
+
|
|
2510
|
+
var merkleHelper = /*#__PURE__*/Object.freeze({
|
|
2511
|
+
__proto__: null,
|
|
2512
|
+
calculateRoot: calculateRoot,
|
|
2513
|
+
merklePath: merklePath,
|
|
2514
|
+
validateMerklePath: validateMerklePath
|
|
2515
|
+
});
|
|
2516
|
+
|
|
2517
|
+
class BlockchainUrlUndefinedException extends Error {
|
|
2518
|
+
constructor(brid) {
|
|
2519
|
+
super(`Cannot find nodes hosting the blockchain with RID ${brid}`);
|
|
2520
|
+
}
|
|
2521
|
+
}
|
|
2522
|
+
|
|
2523
|
+
var __awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2524
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
2525
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
2526
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
2527
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
2528
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
2529
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
2530
|
+
});
|
|
2531
|
+
};
|
|
2532
|
+
/**
|
|
2533
|
+
* Provides postchain clients that can be used to communicate with dapps within the chromia network
|
|
2534
|
+
* @param chain0BRID brid of chain0
|
|
2535
|
+
* @param rest rest client configured to node running chain0
|
|
2536
|
+
*/
|
|
2537
|
+
function chromiaClientProvider(chain0BRID, rest) {
|
|
2538
|
+
const chain0Client = createClient(rest, chain0BRID, []);
|
|
2539
|
+
return {
|
|
2540
|
+
blockchainConnection: function (dappBRID) {
|
|
2541
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
2542
|
+
const queryObject = {
|
|
2543
|
+
type: "cm_get_blockchain_api_urls",
|
|
2544
|
+
blockchain_rid: dappBRID,
|
|
2545
|
+
};
|
|
2546
|
+
const baseUrls = yield chain0Client.query(queryObject);
|
|
2547
|
+
if (!baseUrls.length) {
|
|
2548
|
+
throw new BlockchainUrlUndefinedException(dappBRID);
|
|
2549
|
+
}
|
|
2550
|
+
return createRestClient(baseUrls, dappBRID);
|
|
2551
|
+
});
|
|
2552
|
+
},
|
|
2553
|
+
};
|
|
2554
|
+
}
|
|
2555
|
+
|
|
2556
|
+
var chromiaClientProvider$1 = /*#__PURE__*/Object.freeze({
|
|
2557
|
+
__proto__: null,
|
|
2558
|
+
chromiaClientProvider: chromiaClientProvider
|
|
2559
|
+
});
|
|
2560
|
+
|
|
2561
|
+
exports.chromiaClient = chromiaClientProvider$1;
|
|
2562
|
+
exports.encryption = encryption$1;
|
|
2563
|
+
exports.formatter = formatter;
|
|
2564
|
+
exports.gtv = index;
|
|
2565
|
+
exports.gtx = gtx;
|
|
2566
|
+
exports.gtxClient = gtxclient;
|
|
2567
|
+
exports.logger = logger;
|
|
2568
|
+
exports.merkle = merkleHelper;
|
|
2569
|
+
exports.restClient = restclient;
|
|
2570
|
+
exports.restClientutil = restclientutil;
|
|
2571
|
+
//# sourceMappingURL=index.js.map
|