@hashgraphonline/standards-sdk 0.1.168 → 0.1.170
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 +1 -0
- package/dist/browser/hcs-11/client.d.ts.map +1 -1
- package/dist/browser/hcs-21/sdk.d.ts.map +1 -1
- package/dist/browser/hcs-27/base-client.d.ts +41 -0
- package/dist/browser/hcs-27/base-client.d.ts.map +1 -0
- package/dist/browser/hcs-27/index.d.ts +6 -0
- package/dist/browser/hcs-27/index.d.ts.map +1 -0
- package/dist/browser/hcs-27/memos.d.ts +5 -0
- package/dist/browser/hcs-27/memos.d.ts.map +1 -0
- package/dist/browser/hcs-27/merkle.d.ts +23 -0
- package/dist/browser/hcs-27/merkle.d.ts.map +1 -0
- package/dist/browser/hcs-27/sdk.d.ts +23 -0
- package/dist/browser/hcs-27/sdk.d.ts.map +1 -0
- package/dist/browser/hcs-27/types.d.ts +1611 -0
- package/dist/browser/hcs-27/types.d.ts.map +1 -0
- package/dist/browser/index.d.ts +1 -0
- package/dist/browser/index.d.ts.map +1 -1
- package/dist/browser/standards-sdk.browser.js +29 -5
- package/dist/browser/standards-sdk.browser.js.map +1 -1
- package/dist/browser/utils/key-type-detector.d.ts.map +1 -1
- package/dist/cjs/hcs-11/client.d.ts.map +1 -1
- package/dist/cjs/hcs-21/sdk.d.ts.map +1 -1
- package/dist/cjs/hcs-27/base-client.d.ts +41 -0
- package/dist/cjs/hcs-27/base-client.d.ts.map +1 -0
- package/dist/cjs/hcs-27/index.d.ts +6 -0
- package/dist/cjs/hcs-27/index.d.ts.map +1 -0
- package/dist/cjs/hcs-27/memos.d.ts +5 -0
- package/dist/cjs/hcs-27/memos.d.ts.map +1 -0
- package/dist/cjs/hcs-27/merkle.d.ts +23 -0
- package/dist/cjs/hcs-27/merkle.d.ts.map +1 -0
- package/dist/cjs/hcs-27/sdk.d.ts +23 -0
- package/dist/cjs/hcs-27/sdk.d.ts.map +1 -0
- package/dist/cjs/hcs-27/types.d.ts +1611 -0
- package/dist/cjs/hcs-27/types.d.ts.map +1 -0
- package/dist/cjs/index.d.ts +1 -0
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/standards-sdk.cjs +2 -2
- package/dist/cjs/standards-sdk.cjs.map +1 -1
- package/dist/cjs/utils/key-type-detector.d.ts.map +1 -1
- package/dist/es/hcs-11/client.d.ts.map +1 -1
- package/dist/es/hcs-21/sdk.d.ts.map +1 -1
- package/dist/es/hcs-27/base-client.d.ts +41 -0
- package/dist/es/hcs-27/base-client.d.ts.map +1 -0
- package/dist/es/hcs-27/index.d.ts +6 -0
- package/dist/es/hcs-27/index.d.ts.map +1 -0
- package/dist/es/hcs-27/memos.d.ts +5 -0
- package/dist/es/hcs-27/memos.d.ts.map +1 -0
- package/dist/es/hcs-27/merkle.d.ts +23 -0
- package/dist/es/hcs-27/merkle.d.ts.map +1 -0
- package/dist/es/hcs-27/sdk.d.ts +23 -0
- package/dist/es/hcs-27/sdk.d.ts.map +1 -0
- package/dist/es/hcs-27/types.d.ts +1611 -0
- package/dist/es/hcs-27/types.d.ts.map +1 -0
- package/dist/es/index.d.ts +1 -0
- package/dist/es/index.d.ts.map +1 -1
- package/dist/es/standards-sdk.es.js +67 -38
- package/dist/es/standards-sdk.es.js.map +1 -1
- package/dist/es/standards-sdk.es101.js +2 -2
- package/dist/es/standards-sdk.es103.js +2 -2
- package/dist/es/standards-sdk.es104.js +1 -1
- package/dist/es/standards-sdk.es106.js +1 -1
- package/dist/es/standards-sdk.es108.js +2 -2
- package/dist/es/standards-sdk.es11.js +1 -1
- package/dist/es/standards-sdk.es110.js +1 -1
- package/dist/es/standards-sdk.es111.js +2 -2
- package/dist/es/standards-sdk.es112.js +151 -234
- package/dist/es/standards-sdk.es112.js.map +1 -1
- package/dist/es/standards-sdk.es113.js +20 -471
- package/dist/es/standards-sdk.es113.js.map +1 -1
- package/dist/es/standards-sdk.es114.js +263 -104
- package/dist/es/standards-sdk.es114.js.map +1 -1
- package/dist/es/standards-sdk.es115.js +167 -138
- package/dist/es/standards-sdk.es115.js.map +1 -1
- package/dist/es/standards-sdk.es116.js +315 -29
- package/dist/es/standards-sdk.es116.js.map +1 -1
- package/dist/es/standards-sdk.es117.js +250 -10
- package/dist/es/standards-sdk.es117.js.map +1 -1
- package/dist/es/standards-sdk.es118.js +448 -152
- package/dist/es/standards-sdk.es118.js.map +1 -1
- package/dist/es/standards-sdk.es119.js +101 -25
- package/dist/es/standards-sdk.es119.js.map +1 -1
- package/dist/es/standards-sdk.es12.js +1 -1
- package/dist/es/standards-sdk.es120.js +155 -17
- package/dist/es/standards-sdk.es120.js.map +1 -1
- package/dist/es/standards-sdk.es121.js +29 -155
- package/dist/es/standards-sdk.es121.js.map +1 -1
- package/dist/es/standards-sdk.es122.js +9 -200
- package/dist/es/standards-sdk.es122.js.map +1 -1
- package/dist/es/standards-sdk.es123.js +146 -754
- package/dist/es/standards-sdk.es123.js.map +1 -1
- package/dist/es/standards-sdk.es124.js +27 -11
- package/dist/es/standards-sdk.es124.js.map +1 -1
- package/dist/es/standards-sdk.es125.js +19 -564
- package/dist/es/standards-sdk.es125.js.map +1 -1
- package/dist/es/standards-sdk.es126.js +140 -582
- package/dist/es/standards-sdk.es126.js.map +1 -1
- package/dist/es/standards-sdk.es127.js +202 -12
- package/dist/es/standards-sdk.es127.js.map +1 -1
- package/dist/es/standards-sdk.es128.js +790 -2
- package/dist/es/standards-sdk.es128.js.map +1 -1
- package/dist/es/standards-sdk.es129.js +10 -84
- package/dist/es/standards-sdk.es129.js.map +1 -1
- package/dist/es/standards-sdk.es13.js +1 -1
- package/dist/es/standards-sdk.es130.js +567 -40
- package/dist/es/standards-sdk.es130.js.map +1 -1
- package/dist/es/standards-sdk.es131.js +626 -2
- package/dist/es/standards-sdk.es131.js.map +1 -1
- package/dist/es/standards-sdk.es132.js +12 -234
- package/dist/es/standards-sdk.es132.js.map +1 -1
- package/dist/es/standards-sdk.es133.js +2 -1140
- package/dist/es/standards-sdk.es133.js.map +1 -1
- package/dist/es/standards-sdk.es134.js +73 -292
- package/dist/es/standards-sdk.es134.js.map +1 -1
- package/dist/es/standards-sdk.es135.js +36 -418
- package/dist/es/standards-sdk.es135.js.map +1 -1
- package/dist/es/standards-sdk.es136.js +2 -355
- package/dist/es/standards-sdk.es136.js.map +1 -1
- package/dist/es/standards-sdk.es137.js +198 -1079
- package/dist/es/standards-sdk.es137.js.map +1 -1
- package/dist/es/standards-sdk.es138.js +1107 -175
- package/dist/es/standards-sdk.es138.js.map +1 -1
- package/dist/es/standards-sdk.es139.js +218 -1479
- package/dist/es/standards-sdk.es139.js.map +1 -1
- package/dist/es/standards-sdk.es14.js +1 -1
- package/dist/es/standards-sdk.es140.js +422 -1500
- package/dist/es/standards-sdk.es140.js.map +1 -1
- package/dist/es/standards-sdk.es141.js +351 -13
- package/dist/es/standards-sdk.es141.js.map +1 -1
- package/dist/es/standards-sdk.es142.js +1102 -73
- package/dist/es/standards-sdk.es142.js.map +1 -1
- package/dist/es/standards-sdk.es143.js +203 -76
- package/dist/es/standards-sdk.es143.js.map +1 -1
- package/dist/es/standards-sdk.es144.js +1459 -830
- package/dist/es/standards-sdk.es144.js.map +1 -1
- package/dist/es/standards-sdk.es145.js +1499 -59
- package/dist/es/standards-sdk.es145.js.map +1 -1
- package/dist/es/standards-sdk.es146.js +14 -156
- package/dist/es/standards-sdk.es146.js.map +1 -1
- package/dist/es/standards-sdk.es147.js +87 -7
- package/dist/es/standards-sdk.es147.js.map +1 -1
- package/dist/es/standards-sdk.es148.js +74 -79
- package/dist/es/standards-sdk.es148.js.map +1 -1
- package/dist/es/standards-sdk.es149.js +934 -61
- package/dist/es/standards-sdk.es149.js.map +1 -1
- package/dist/es/standards-sdk.es15.js +1 -1
- package/dist/es/standards-sdk.es150.js +60 -30
- package/dist/es/standards-sdk.es150.js.map +1 -1
- package/dist/es/standards-sdk.es151.js +159 -34
- package/dist/es/standards-sdk.es151.js.map +1 -1
- package/dist/es/standards-sdk.es152.js +7 -48
- package/dist/es/standards-sdk.es152.js.map +1 -1
- package/dist/es/standards-sdk.es153.js +70 -122
- package/dist/es/standards-sdk.es153.js.map +1 -1
- package/dist/es/standards-sdk.es154.js +58 -35
- package/dist/es/standards-sdk.es154.js.map +1 -1
- package/dist/es/standards-sdk.es155.js +30 -56
- package/dist/es/standards-sdk.es155.js.map +1 -1
- package/dist/es/standards-sdk.es156.js +34 -84
- package/dist/es/standards-sdk.es156.js.map +1 -1
- package/dist/es/standards-sdk.es157.js +48 -81
- package/dist/es/standards-sdk.es157.js.map +1 -1
- package/dist/es/standards-sdk.es158.js +124 -186
- package/dist/es/standards-sdk.es158.js.map +1 -1
- package/dist/es/standards-sdk.es159.js +34 -12474
- package/dist/es/standards-sdk.es159.js.map +1 -1
- package/dist/es/standards-sdk.es16.js +5 -5
- package/dist/es/standards-sdk.es160.js +12477 -12
- package/dist/es/standards-sdk.es160.js.map +1 -1
- package/dist/es/standards-sdk.es161.js +51 -68
- package/dist/es/standards-sdk.es161.js.map +1 -1
- package/dist/es/standards-sdk.es162.js +67 -533
- package/dist/es/standards-sdk.es162.js.map +1 -1
- package/dist/es/standards-sdk.es163.js +70 -161
- package/dist/es/standards-sdk.es163.js.map +1 -1
- package/dist/es/standards-sdk.es164.js +187 -309
- package/dist/es/standards-sdk.es164.js.map +1 -1
- package/dist/es/standards-sdk.es165.js +13 -342
- package/dist/es/standards-sdk.es165.js.map +1 -1
- package/dist/es/standards-sdk.es166.js +538 -441
- package/dist/es/standards-sdk.es166.js.map +1 -1
- package/dist/es/standards-sdk.es167.js +142 -301
- package/dist/es/standards-sdk.es167.js.map +1 -1
- package/dist/es/standards-sdk.es168.js +310 -64
- package/dist/es/standards-sdk.es168.js.map +1 -1
- package/dist/es/standards-sdk.es169.js +332 -158
- package/dist/es/standards-sdk.es169.js.map +1 -1
- package/dist/es/standards-sdk.es170.js +441 -210
- package/dist/es/standards-sdk.es170.js.map +1 -1
- package/dist/es/standards-sdk.es171.js +314 -222
- package/dist/es/standards-sdk.es171.js.map +1 -1
- package/dist/es/standards-sdk.es172.js +65 -108
- package/dist/es/standards-sdk.es172.js.map +1 -1
- package/dist/es/standards-sdk.es173.js +61 -114
- package/dist/es/standards-sdk.es173.js.map +1 -1
- package/dist/es/standards-sdk.es174.js +151 -140
- package/dist/es/standards-sdk.es174.js.map +1 -1
- package/dist/es/standards-sdk.es175.js +193 -156
- package/dist/es/standards-sdk.es175.js.map +1 -1
- package/dist/es/standards-sdk.es176.js +221 -121
- package/dist/es/standards-sdk.es176.js.map +1 -1
- package/dist/es/standards-sdk.es177.js +81 -293
- package/dist/es/standards-sdk.es177.js.map +1 -1
- package/dist/es/standards-sdk.es178.js +114 -247
- package/dist/es/standards-sdk.es178.js.map +1 -1
- package/dist/es/standards-sdk.es179.js +119 -110
- package/dist/es/standards-sdk.es179.js.map +1 -1
- package/dist/es/standards-sdk.es18.js +12 -12
- package/dist/es/standards-sdk.es180.js +188 -0
- package/dist/es/standards-sdk.es180.js.map +1 -0
- package/dist/es/standards-sdk.es181.js +142 -0
- package/dist/es/standards-sdk.es181.js.map +1 -0
- package/dist/es/standards-sdk.es182.js +334 -0
- package/dist/es/standards-sdk.es182.js.map +1 -0
- package/dist/es/standards-sdk.es183.js +262 -0
- package/dist/es/standards-sdk.es183.js.map +1 -0
- package/dist/es/standards-sdk.es184.js +155 -0
- package/dist/es/standards-sdk.es184.js.map +1 -0
- package/dist/es/standards-sdk.es19.js +9 -9
- package/dist/es/standards-sdk.es2.js +2 -2
- package/dist/es/standards-sdk.es20.js +1 -1
- package/dist/es/standards-sdk.es21.js +1 -1
- package/dist/es/standards-sdk.es22.js +1 -1
- package/dist/es/standards-sdk.es23.js +1 -1
- package/dist/es/standards-sdk.es24.js +1 -1
- package/dist/es/standards-sdk.es25.js +1 -1
- package/dist/es/standards-sdk.es26.js +1 -1
- package/dist/es/standards-sdk.es27.js +12 -12
- package/dist/es/standards-sdk.es27.js.map +1 -1
- package/dist/es/standards-sdk.es30.js +2 -2
- package/dist/es/standards-sdk.es31.js +4 -4
- package/dist/es/standards-sdk.es32.js +1 -1
- package/dist/es/standards-sdk.es35.js +6 -6
- package/dist/es/standards-sdk.es36.js +4 -4
- package/dist/es/standards-sdk.es37.js +2 -2
- package/dist/es/standards-sdk.es38.js +2 -2
- package/dist/es/standards-sdk.es39.js +1 -1
- package/dist/es/standards-sdk.es4.js +2 -2
- package/dist/es/standards-sdk.es40.js +1 -1
- package/dist/es/standards-sdk.es41.js +2 -2
- package/dist/es/standards-sdk.es46.js +1 -1
- package/dist/es/standards-sdk.es5.js +2 -2
- package/dist/es/standards-sdk.es51.js +1 -1
- package/dist/es/standards-sdk.es53.js +1 -1
- package/dist/es/standards-sdk.es56.js +2 -2
- package/dist/es/standards-sdk.es59.js +1 -1
- package/dist/es/standards-sdk.es6.js +2 -2
- package/dist/es/standards-sdk.es60.js +1 -1
- package/dist/es/standards-sdk.es62.js +1 -1
- package/dist/es/standards-sdk.es63.js +2 -2
- package/dist/es/standards-sdk.es64.js +1 -1
- package/dist/es/standards-sdk.es65.js +1 -1
- package/dist/es/standards-sdk.es66.js +1 -1
- package/dist/es/standards-sdk.es67.js +7 -7
- package/dist/es/standards-sdk.es69.js +1 -1
- package/dist/es/standards-sdk.es7.js +1 -1
- package/dist/es/standards-sdk.es71.js +2 -2
- package/dist/es/standards-sdk.es72.js +3 -3
- package/dist/es/standards-sdk.es75.js +5 -5
- package/dist/es/standards-sdk.es76.js +3 -3
- package/dist/es/standards-sdk.es77.js +2 -2
- package/dist/es/standards-sdk.es78.js +1 -1
- package/dist/es/standards-sdk.es81.js +2 -2
- package/dist/es/standards-sdk.es83.js +2 -2
- package/dist/es/standards-sdk.es84.js +4 -4
- package/dist/es/standards-sdk.es85.js +1 -1
- package/dist/es/standards-sdk.es88.js +1 -1
- package/dist/es/standards-sdk.es89.js +2 -2
- package/dist/es/standards-sdk.es9.js +2 -2
- package/dist/es/standards-sdk.es90.js +4 -4
- package/dist/es/standards-sdk.es90.js.map +1 -1
- package/dist/es/standards-sdk.es94.js +3 -3
- package/dist/es/standards-sdk.es96.js +2 -2
- package/dist/es/standards-sdk.es98.js +1 -1
- package/dist/es/standards-sdk.es99.js +3 -3
- package/dist/es/utils/key-type-detector.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -1,108 +1,267 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
1
|
+
import { createHash } from "crypto";
|
|
2
|
+
import { hcs27ConsistencyProofSchema, hcs27InclusionProofSchema } from "./standards-sdk.es112.js";
|
|
3
|
+
function normalizeJsonValue(value) {
|
|
4
|
+
if (value === null || typeof value === "boolean" || typeof value === "number" || typeof value === "string") {
|
|
5
|
+
if (typeof value === "number" && !Number.isFinite(value)) {
|
|
6
|
+
throw new Error("JSON numbers must be finite");
|
|
7
|
+
}
|
|
8
|
+
return value;
|
|
9
|
+
}
|
|
10
|
+
if (Array.isArray(value)) {
|
|
11
|
+
return Array.from(
|
|
12
|
+
value,
|
|
13
|
+
(item) => item === void 0 ? null : normalizeJsonValue(item)
|
|
14
|
+
);
|
|
15
|
+
}
|
|
16
|
+
if (typeof value === "object") {
|
|
17
|
+
const toJSON = value.toJSON;
|
|
18
|
+
if (typeof toJSON === "function") {
|
|
19
|
+
return normalizeJsonValue(toJSON.call(value));
|
|
20
|
+
}
|
|
21
|
+
const result = {};
|
|
22
|
+
for (const [key, item] of Object.entries(value)) {
|
|
23
|
+
if (item !== void 0) {
|
|
24
|
+
result[key] = normalizeJsonValue(item);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
return result;
|
|
28
|
+
}
|
|
29
|
+
throw new Error(`Unsupported JSON value type: ${typeof value}`);
|
|
30
|
+
}
|
|
31
|
+
function formatNumber(value) {
|
|
32
|
+
if (Object.is(value, -0)) {
|
|
33
|
+
return "0";
|
|
34
|
+
}
|
|
35
|
+
return value.toString();
|
|
36
|
+
}
|
|
37
|
+
function decodeBase64(value, fieldName) {
|
|
38
|
+
try {
|
|
39
|
+
if (!value) {
|
|
40
|
+
throw new Error("empty base64");
|
|
41
|
+
}
|
|
42
|
+
const decoded = Buffer.from(value, "base64");
|
|
43
|
+
if (decoded.toString("base64") !== value) {
|
|
44
|
+
throw new Error("non-canonical base64");
|
|
45
|
+
}
|
|
46
|
+
return decoded;
|
|
47
|
+
} catch {
|
|
48
|
+
throw new Error(`${fieldName} must be valid base64`);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
function writeCanonicalJson(value) {
|
|
52
|
+
if (value === null) {
|
|
53
|
+
return "null";
|
|
54
|
+
}
|
|
55
|
+
if (typeof value === "boolean") {
|
|
56
|
+
return value ? "true" : "false";
|
|
57
|
+
}
|
|
58
|
+
if (typeof value === "string") {
|
|
59
|
+
return JSON.stringify(value);
|
|
60
|
+
}
|
|
61
|
+
if (typeof value === "number") {
|
|
62
|
+
return formatNumber(value);
|
|
63
|
+
}
|
|
64
|
+
if (Array.isArray(value)) {
|
|
65
|
+
return `[${value.map((item) => writeCanonicalJson(item)).join(",")}]`;
|
|
66
|
+
}
|
|
67
|
+
if (typeof value === "object") {
|
|
68
|
+
const entries = Object.entries(value).sort(
|
|
69
|
+
([left], [right]) => left < right ? -1 : left > right ? 1 : 0
|
|
70
|
+
);
|
|
71
|
+
return `{${entries.map(
|
|
72
|
+
([key, item]) => `${JSON.stringify(key)}:${writeCanonicalJson(item)}`
|
|
73
|
+
).join(",")}}`;
|
|
74
|
+
}
|
|
75
|
+
throw new Error(`Unsupported JSON value type: ${typeof value}`);
|
|
76
|
+
}
|
|
77
|
+
function parseTreeSize(value) {
|
|
78
|
+
return typeof value === "number" ? BigInt(value) : BigInt(value);
|
|
79
|
+
}
|
|
80
|
+
function leastSignificantBit(value) {
|
|
81
|
+
return value & 1n;
|
|
82
|
+
}
|
|
83
|
+
function isExactPowerOfTwo(value) {
|
|
84
|
+
return value !== 0n && (value & value - 1n) === 0n;
|
|
85
|
+
}
|
|
86
|
+
function largestPowerOfTwoLessThan(value) {
|
|
87
|
+
if (value <= 1) {
|
|
88
|
+
return 0;
|
|
89
|
+
}
|
|
90
|
+
let result = 1;
|
|
91
|
+
while (result << 1 < value) {
|
|
92
|
+
result <<= 1;
|
|
93
|
+
}
|
|
94
|
+
return result;
|
|
95
|
+
}
|
|
96
|
+
function canonicalizeHCS27Json(value) {
|
|
97
|
+
const normalized = normalizeJsonValue(value);
|
|
98
|
+
return Buffer.from(writeCanonicalJson(normalized), "utf8");
|
|
99
|
+
}
|
|
100
|
+
function emptyHCS27Root() {
|
|
101
|
+
return createHash("sha256").update(Buffer.alloc(0)).digest();
|
|
102
|
+
}
|
|
103
|
+
function hashHCS27Leaf(canonicalEntry) {
|
|
104
|
+
return createHash("sha256").update(Buffer.from([0])).update(Buffer.from(canonicalEntry)).digest();
|
|
105
|
+
}
|
|
106
|
+
function hashHCS27Node(left, right) {
|
|
107
|
+
return createHash("sha256").update(Buffer.from([1])).update(Buffer.from(left)).update(Buffer.from(right)).digest();
|
|
108
|
+
}
|
|
109
|
+
function merkleRootFromCanonicalEntries(entries) {
|
|
110
|
+
if (entries.length === 0) {
|
|
111
|
+
return emptyHCS27Root();
|
|
112
|
+
}
|
|
113
|
+
if (entries.length === 1) {
|
|
114
|
+
return hashHCS27Leaf(entries[0]);
|
|
115
|
+
}
|
|
116
|
+
const split = largestPowerOfTwoLessThan(entries.length);
|
|
117
|
+
const left = merkleRootFromCanonicalEntries(entries.slice(0, split));
|
|
118
|
+
const right = merkleRootFromCanonicalEntries(entries.slice(split));
|
|
119
|
+
return hashHCS27Node(left, right);
|
|
120
|
+
}
|
|
121
|
+
function merkleRootFromEntries(entries) {
|
|
122
|
+
const canonicalEntries = entries.map((entry) => canonicalizeHCS27Json(entry));
|
|
123
|
+
return merkleRootFromCanonicalEntries(canonicalEntries);
|
|
124
|
+
}
|
|
125
|
+
function leafHashHexFromEntry(entry) {
|
|
126
|
+
return hashHCS27Leaf(canonicalizeHCS27Json(entry)).toString("hex");
|
|
127
|
+
}
|
|
128
|
+
function verifyInclusionProof(params) {
|
|
129
|
+
let leafIndex;
|
|
130
|
+
let treeSize;
|
|
131
|
+
let leafHashHex;
|
|
132
|
+
let path;
|
|
133
|
+
let expectedRootB64;
|
|
134
|
+
if ("leafHash" in params) {
|
|
135
|
+
const proof = hcs27InclusionProofSchema.parse(params);
|
|
136
|
+
leafIndex = BigInt(proof.leafIndex);
|
|
137
|
+
treeSize = BigInt(proof.treeSize);
|
|
138
|
+
leafHashHex = proof.leafHash;
|
|
139
|
+
path = proof.path;
|
|
140
|
+
expectedRootB64 = proof.rootHash;
|
|
141
|
+
} else {
|
|
142
|
+
leafIndex = parseTreeSize(params.leafIndex);
|
|
143
|
+
treeSize = parseTreeSize(params.treeSize);
|
|
144
|
+
leafHashHex = params.leafHashHex;
|
|
145
|
+
path = params.path;
|
|
146
|
+
expectedRootB64 = params.expectedRootB64;
|
|
147
|
+
}
|
|
148
|
+
if (treeSize <= 0n) {
|
|
149
|
+
throw new Error("treeSize must be greater than zero for inclusion proofs");
|
|
150
|
+
}
|
|
151
|
+
if (leafIndex < 0n || leafIndex >= treeSize) {
|
|
152
|
+
throw new Error("leafIndex must be less than treeSize");
|
|
153
|
+
}
|
|
154
|
+
if (!/^(?:[0-9a-f]{2})+$/i.test(leafHashHex.trim())) {
|
|
155
|
+
throw new Error("leafHash must be valid hex");
|
|
156
|
+
}
|
|
157
|
+
let current;
|
|
158
|
+
try {
|
|
159
|
+
current = Buffer.from(leafHashHex.trim(), "hex");
|
|
160
|
+
} catch {
|
|
161
|
+
throw new Error("leafHash must be valid hex");
|
|
162
|
+
}
|
|
163
|
+
let fn = leafIndex;
|
|
164
|
+
let sn = treeSize - 1n;
|
|
165
|
+
for (const [index, node] of path.entries()) {
|
|
166
|
+
if (sn === 0n) {
|
|
167
|
+
return false;
|
|
168
|
+
}
|
|
169
|
+
const sibling = decodeBase64(node, `path[${index}]`);
|
|
170
|
+
if (leastSignificantBit(fn) === 1n || fn === sn) {
|
|
171
|
+
current = hashHCS27Node(sibling, current);
|
|
172
|
+
if (leastSignificantBit(fn) === 0n) {
|
|
173
|
+
while (leastSignificantBit(fn) === 0n && fn !== 0n) {
|
|
174
|
+
fn /= 2n;
|
|
175
|
+
sn /= 2n;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
} else {
|
|
179
|
+
current = hashHCS27Node(current, sibling);
|
|
180
|
+
}
|
|
181
|
+
fn /= 2n;
|
|
182
|
+
sn /= 2n;
|
|
183
|
+
}
|
|
184
|
+
return sn === 0n && current.toString("base64") === expectedRootB64;
|
|
185
|
+
}
|
|
186
|
+
function verifyConsistencyProof(params) {
|
|
187
|
+
let oldTreeSize;
|
|
188
|
+
let newTreeSize;
|
|
189
|
+
let oldRootB64;
|
|
190
|
+
let newRootB64;
|
|
191
|
+
let consistencyPath;
|
|
192
|
+
if ("oldRootHash" in params) {
|
|
193
|
+
const proof = hcs27ConsistencyProofSchema.parse(params);
|
|
194
|
+
oldTreeSize = BigInt(proof.oldTreeSize);
|
|
195
|
+
newTreeSize = BigInt(proof.newTreeSize);
|
|
196
|
+
oldRootB64 = proof.oldRootHash;
|
|
197
|
+
newRootB64 = proof.newRootHash;
|
|
198
|
+
consistencyPath = proof.consistencyPath;
|
|
199
|
+
} else {
|
|
200
|
+
oldTreeSize = parseTreeSize(params.oldTreeSize);
|
|
201
|
+
newTreeSize = parseTreeSize(params.newTreeSize);
|
|
202
|
+
oldRootB64 = params.oldRootB64;
|
|
203
|
+
newRootB64 = params.newRootB64;
|
|
204
|
+
consistencyPath = params.consistencyPath;
|
|
205
|
+
}
|
|
206
|
+
if (oldTreeSize < 0n || newTreeSize < 0n) {
|
|
207
|
+
throw new Error("tree sizes must be non-negative");
|
|
208
|
+
}
|
|
209
|
+
if (oldTreeSize === 0n) {
|
|
210
|
+
return true;
|
|
211
|
+
}
|
|
212
|
+
if (oldTreeSize === newTreeSize) {
|
|
213
|
+
decodeBase64(oldRootB64, "oldRootHash");
|
|
214
|
+
decodeBase64(newRootB64, "newRootHash");
|
|
215
|
+
return oldRootB64 === newRootB64 && consistencyPath.length === 0;
|
|
216
|
+
}
|
|
217
|
+
if (oldTreeSize > newTreeSize || consistencyPath.length === 0) {
|
|
218
|
+
return false;
|
|
219
|
+
}
|
|
220
|
+
const path = consistencyPath.map(
|
|
221
|
+
(node, index) => decodeBase64(node, `consistencyPath[${index}]`)
|
|
18
222
|
);
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
}
|
|
28
|
-
const
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
}
|
|
52
|
-
function buildHcs26TransactionMemo(input) {
|
|
53
|
-
const operation = hcs26OperationEnumSchema.parse(input.operation);
|
|
54
|
-
const topicType = hcs26TopicTypeEnumSchema.parse(input.topicType);
|
|
55
|
-
return `${HCS26_PROTOCOL}:op:${operation}:${topicType}`;
|
|
56
|
-
}
|
|
57
|
-
function parseHcs26TransactionMemo(memoRaw) {
|
|
58
|
-
const memo = memoRaw.trim();
|
|
59
|
-
if (!memo) {
|
|
60
|
-
return null;
|
|
61
|
-
}
|
|
62
|
-
const match = memo.match(/^hcs-26:op:(\d+):(\d+)$/);
|
|
63
|
-
if (!match) {
|
|
64
|
-
return null;
|
|
65
|
-
}
|
|
66
|
-
const operation = Number(match[1]);
|
|
67
|
-
const topicType = Number(match[2]);
|
|
68
|
-
if (![operation, topicType].every(Number.isFinite)) {
|
|
69
|
-
return null;
|
|
70
|
-
}
|
|
71
|
-
const parsedOperation = hcs26OperationEnumSchema.safeParse(operation);
|
|
72
|
-
if (!parsedOperation.success) {
|
|
73
|
-
return null;
|
|
74
|
-
}
|
|
75
|
-
const parsedTopicType = hcs26TopicTypeEnumSchema.safeParse(topicType);
|
|
76
|
-
if (!parsedTopicType.success) {
|
|
77
|
-
return null;
|
|
78
|
-
}
|
|
79
|
-
return {
|
|
80
|
-
protocol: HCS26_PROTOCOL,
|
|
81
|
-
operation: parsedOperation.data,
|
|
82
|
-
topicType: parsedTopicType.data
|
|
83
|
-
};
|
|
84
|
-
}
|
|
85
|
-
const hcs26TopicMemoSchema = z.string().transform((value) => {
|
|
86
|
-
const parsed = parseHcs26TopicMemo(value);
|
|
87
|
-
if (!parsed) {
|
|
88
|
-
throw new Error("Invalid HCS-26 topic memo");
|
|
89
|
-
}
|
|
90
|
-
return parsed;
|
|
91
|
-
});
|
|
92
|
-
const hcs26TransactionMemoSchema = z.string().transform((value) => {
|
|
93
|
-
const parsed = parseHcs26TransactionMemo(value);
|
|
94
|
-
if (!parsed) {
|
|
95
|
-
throw new Error("Invalid HCS-26 transaction memo");
|
|
96
|
-
}
|
|
97
|
-
return parsed;
|
|
98
|
-
});
|
|
223
|
+
if (isExactPowerOfTwo(oldTreeSize)) {
|
|
224
|
+
path.unshift(decodeBase64(oldRootB64, "oldRootHash"));
|
|
225
|
+
}
|
|
226
|
+
let fn = oldTreeSize - 1n;
|
|
227
|
+
let sn = newTreeSize - 1n;
|
|
228
|
+
while (leastSignificantBit(fn) === 1n) {
|
|
229
|
+
fn /= 2n;
|
|
230
|
+
sn /= 2n;
|
|
231
|
+
}
|
|
232
|
+
const firstHash = Buffer.from(path[0]);
|
|
233
|
+
let fr = Buffer.from(firstHash);
|
|
234
|
+
let sr = Buffer.from(firstHash);
|
|
235
|
+
for (const nodeHash of path.slice(1)) {
|
|
236
|
+
if (sn === 0n) {
|
|
237
|
+
return false;
|
|
238
|
+
}
|
|
239
|
+
if (leastSignificantBit(fn) === 1n || fn === sn) {
|
|
240
|
+
fr = hashHCS27Node(nodeHash, fr);
|
|
241
|
+
sr = hashHCS27Node(nodeHash, sr);
|
|
242
|
+
if (leastSignificantBit(fn) === 0n) {
|
|
243
|
+
while (leastSignificantBit(fn) === 0n && fn !== 0n) {
|
|
244
|
+
fn /= 2n;
|
|
245
|
+
sn /= 2n;
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
} else {
|
|
249
|
+
sr = hashHCS27Node(sr, nodeHash);
|
|
250
|
+
}
|
|
251
|
+
fn /= 2n;
|
|
252
|
+
sn /= 2n;
|
|
253
|
+
}
|
|
254
|
+
return sn === 0n && Buffer.from(fr).toString("base64") === oldRootB64 && Buffer.from(sr).toString("base64") === newRootB64;
|
|
255
|
+
}
|
|
99
256
|
export {
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
257
|
+
canonicalizeHCS27Json,
|
|
258
|
+
emptyHCS27Root,
|
|
259
|
+
hashHCS27Leaf,
|
|
260
|
+
hashHCS27Node,
|
|
261
|
+
leafHashHexFromEntry,
|
|
262
|
+
merkleRootFromCanonicalEntries,
|
|
263
|
+
merkleRootFromEntries,
|
|
264
|
+
verifyConsistencyProof,
|
|
265
|
+
verifyInclusionProof
|
|
107
266
|
};
|
|
108
267
|
//# sourceMappingURL=standards-sdk.es114.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"standards-sdk.es114.js","sources":["../../src/hcs-26/memos.ts"],"sourcesContent":["import { z } from 'zod';\nimport {\n HCS26_PROTOCOL,\n hcs26OperationEnumSchema,\n hcs26TopicTypeEnumSchema,\n type Hcs26OperationEnum,\n type Hcs26TopicTypeEnum,\n} from './types';\n\nexport type Hcs26TopicMemo = {\n protocol: typeof HCS26_PROTOCOL;\n indexed: boolean;\n ttlSeconds: number;\n topicType: Hcs26TopicTypeEnum;\n};\n\nexport const HCS26_DEFAULT_TTL_SECONDS = 86400;\n\nfunction toPositiveInt(value: number): number {\n if (!Number.isFinite(value)) {\n throw new Error('Expected a finite number');\n }\n const intValue = Math.floor(value);\n if (intValue <= 0) {\n throw new Error('Expected a positive integer');\n }\n return intValue;\n}\n\nexport function buildHcs26TopicMemo(input: {\n indexed?: boolean;\n ttlSeconds?: number;\n topicType: Hcs26TopicTypeEnum;\n}): string {\n const indexed = input.indexed ?? true;\n const ttlSeconds = toPositiveInt(\n input.ttlSeconds ?? HCS26_DEFAULT_TTL_SECONDS,\n );\n const topicType = hcs26TopicTypeEnumSchema.parse(input.topicType);\n\n // HCS-2 memo convention: indexed topics use \"0\" in the second segment.\n const indexedSegment = indexed ? '0' : '1';\n return `${HCS26_PROTOCOL}:${indexedSegment}:${ttlSeconds}:${topicType}`;\n}\n\nexport function parseHcs26TopicMemo(memoRaw: string): Hcs26TopicMemo | null {\n const memo = memoRaw.trim();\n if (!memo) {\n return null;\n }\n\n const match = memo.match(/^hcs-26:(\\d+):(\\d+):(\\d+)$/);\n if (!match) {\n return null;\n }\n\n const indexedSegment = Number(match[1]);\n const ttlSeconds = Number(match[2]);\n const topicType = Number(match[3]);\n\n if (![indexedSegment, ttlSeconds, topicType].every(Number.isFinite)) {\n return null;\n }\n\n const parsedTopicType = hcs26TopicTypeEnumSchema.safeParse(topicType);\n if (!parsedTopicType.success) {\n return null;\n }\n\n if (indexedSegment !== 0 && indexedSegment !== 1) {\n return null;\n }\n\n return {\n protocol: HCS26_PROTOCOL,\n indexed: indexedSegment === 0,\n ttlSeconds,\n topicType: parsedTopicType.data,\n };\n}\n\nexport function buildHcs26TransactionMemo(input: {\n operation: Hcs26OperationEnum;\n topicType: Hcs26TopicTypeEnum;\n}): string {\n const operation = hcs26OperationEnumSchema.parse(input.operation);\n const topicType = hcs26TopicTypeEnumSchema.parse(input.topicType);\n return `${HCS26_PROTOCOL}:op:${operation}:${topicType}`;\n}\n\nexport type Hcs26TransactionMemo = {\n protocol: typeof HCS26_PROTOCOL;\n operation: Hcs26OperationEnum;\n topicType: Hcs26TopicTypeEnum;\n};\n\nexport function parseHcs26TransactionMemo(\n memoRaw: string,\n): Hcs26TransactionMemo | null {\n const memo = memoRaw.trim();\n if (!memo) {\n return null;\n }\n\n const match = memo.match(/^hcs-26:op:(\\d+):(\\d+)$/);\n if (!match) {\n return null;\n }\n\n const operation = Number(match[1]);\n const topicType = Number(match[2]);\n if (![operation, topicType].every(Number.isFinite)) {\n return null;\n }\n\n const parsedOperation = hcs26OperationEnumSchema.safeParse(operation);\n if (!parsedOperation.success) {\n return null;\n }\n const parsedTopicType = hcs26TopicTypeEnumSchema.safeParse(topicType);\n if (!parsedTopicType.success) {\n return null;\n }\n\n return {\n protocol: HCS26_PROTOCOL,\n operation: parsedOperation.data,\n topicType: parsedTopicType.data,\n };\n}\n\nexport const hcs26TopicMemoSchema = z.string().transform(value => {\n const parsed = parseHcs26TopicMemo(value);\n if (!parsed) {\n throw new Error('Invalid HCS-26 topic memo');\n }\n return parsed;\n});\n\nexport const hcs26TransactionMemoSchema = z.string().transform(value => {\n const parsed = parseHcs26TransactionMemo(value);\n if (!parsed) {\n throw new Error('Invalid HCS-26 transaction memo');\n }\n return parsed;\n});\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"standards-sdk.es114.js","sources":["../../src/hcs-27/merkle.ts"],"sourcesContent":["import { createHash } from 'crypto';\nimport {\n hcs27ConsistencyProofSchema,\n hcs27InclusionProofSchema,\n type HCS27ConsistencyProof,\n type HCS27InclusionProof,\n} from './types';\n\nfunction normalizeJsonValue(value: unknown): unknown {\n if (\n value === null ||\n typeof value === 'boolean' ||\n typeof value === 'number' ||\n typeof value === 'string'\n ) {\n if (typeof value === 'number' && !Number.isFinite(value)) {\n throw new Error('JSON numbers must be finite');\n }\n return value;\n }\n\n if (Array.isArray(value)) {\n return Array.from(value, item =>\n item === undefined ? null : normalizeJsonValue(item),\n );\n }\n\n if (typeof value === 'object') {\n const toJSON = (value as { toJSON?: () => unknown }).toJSON;\n if (typeof toJSON === 'function') {\n return normalizeJsonValue(toJSON.call(value));\n }\n\n const result: Record<string, unknown> = {};\n for (const [key, item] of Object.entries(value)) {\n if (item !== undefined) {\n result[key] = normalizeJsonValue(item);\n }\n }\n return result;\n }\n\n throw new Error(`Unsupported JSON value type: ${typeof value}`);\n}\n\nfunction formatNumber(value: number): string {\n if (Object.is(value, -0)) {\n return '0';\n }\n return value.toString();\n}\n\nfunction decodeBase64(value: string, fieldName: string): Buffer {\n try {\n if (!value) {\n throw new Error('empty base64');\n }\n const decoded = Buffer.from(value, 'base64');\n if (decoded.toString('base64') !== value) {\n throw new Error('non-canonical base64');\n }\n return decoded;\n } catch {\n throw new Error(`${fieldName} must be valid base64`);\n }\n}\n\nfunction writeCanonicalJson(value: unknown): string {\n if (value === null) {\n return 'null';\n }\n if (typeof value === 'boolean') {\n return value ? 'true' : 'false';\n }\n if (typeof value === 'string') {\n return JSON.stringify(value);\n }\n if (typeof value === 'number') {\n return formatNumber(value);\n }\n if (Array.isArray(value)) {\n return `[${value.map(item => writeCanonicalJson(item)).join(',')}]`;\n }\n if (typeof value === 'object') {\n const entries = Object.entries(value).sort(([left], [right]) =>\n left < right ? -1 : left > right ? 1 : 0,\n );\n return `{${entries\n .map(\n ([key, item]) => `${JSON.stringify(key)}:${writeCanonicalJson(item)}`,\n )\n .join(',')}}`;\n }\n throw new Error(`Unsupported JSON value type: ${typeof value}`);\n}\n\nfunction parseTreeSize(value: number | string): bigint {\n return typeof value === 'number' ? BigInt(value) : BigInt(value);\n}\n\nfunction leastSignificantBit(value: bigint): bigint {\n return value & 1n;\n}\n\nfunction isExactPowerOfTwo(value: bigint): boolean {\n return value !== 0n && (value & (value - 1n)) === 0n;\n}\n\nfunction largestPowerOfTwoLessThan(value: number): number {\n if (value <= 1) {\n return 0;\n }\n\n let result = 1;\n while (result << 1 < value) {\n result <<= 1;\n }\n return result;\n}\n\nexport function canonicalizeHCS27Json(value: unknown): Buffer {\n const normalized = normalizeJsonValue(value);\n return Buffer.from(writeCanonicalJson(normalized), 'utf8');\n}\n\nexport function emptyHCS27Root(): Buffer {\n return createHash('sha256').update(Buffer.alloc(0)).digest();\n}\n\nexport function hashHCS27Leaf(canonicalEntry: Buffer | Uint8Array): Buffer {\n return createHash('sha256')\n .update(Buffer.from([0x00]))\n .update(Buffer.from(canonicalEntry))\n .digest();\n}\n\nexport function hashHCS27Node(\n left: Buffer | Uint8Array,\n right: Buffer | Uint8Array,\n): Buffer {\n return createHash('sha256')\n .update(Buffer.from([0x01]))\n .update(Buffer.from(left))\n .update(Buffer.from(right))\n .digest();\n}\n\nexport function merkleRootFromCanonicalEntries(\n entries: ReadonlyArray<Buffer | Uint8Array>,\n): Buffer {\n if (entries.length === 0) {\n return emptyHCS27Root();\n }\n if (entries.length === 1) {\n return hashHCS27Leaf(entries[0]);\n }\n\n const split = largestPowerOfTwoLessThan(entries.length);\n const left = merkleRootFromCanonicalEntries(entries.slice(0, split));\n const right = merkleRootFromCanonicalEntries(entries.slice(split));\n return hashHCS27Node(left, right);\n}\n\nexport function merkleRootFromEntries(entries: ReadonlyArray<unknown>): Buffer {\n const canonicalEntries = entries.map(entry => canonicalizeHCS27Json(entry));\n return merkleRootFromCanonicalEntries(canonicalEntries);\n}\n\nexport function leafHashHexFromEntry(entry: unknown): string {\n return hashHCS27Leaf(canonicalizeHCS27Json(entry)).toString('hex');\n}\n\nexport function verifyInclusionProof(\n params:\n | HCS27InclusionProof\n | {\n leafIndex: number;\n treeSize: number;\n leafHashHex: string;\n path: string[];\n expectedRootB64: string;\n },\n): boolean {\n let leafIndex: bigint;\n let treeSize: bigint;\n let leafHashHex: string;\n let path: string[];\n let expectedRootB64: string;\n\n if ('leafHash' in params) {\n const proof = hcs27InclusionProofSchema.parse(params);\n leafIndex = BigInt(proof.leafIndex);\n treeSize = BigInt(proof.treeSize);\n leafHashHex = proof.leafHash;\n path = proof.path;\n expectedRootB64 = proof.rootHash;\n } else {\n leafIndex = parseTreeSize(params.leafIndex);\n treeSize = parseTreeSize(params.treeSize);\n leafHashHex = params.leafHashHex;\n path = params.path;\n expectedRootB64 = params.expectedRootB64;\n }\n\n if (treeSize <= 0n) {\n throw new Error('treeSize must be greater than zero for inclusion proofs');\n }\n if (leafIndex < 0n || leafIndex >= treeSize) {\n throw new Error('leafIndex must be less than treeSize');\n }\n if (!/^(?:[0-9a-f]{2})+$/i.test(leafHashHex.trim())) {\n throw new Error('leafHash must be valid hex');\n }\n\n let current: Buffer;\n try {\n current = Buffer.from(leafHashHex.trim(), 'hex');\n } catch {\n throw new Error('leafHash must be valid hex');\n }\n\n let fn = leafIndex;\n let sn = treeSize - 1n;\n\n for (const [index, node] of path.entries()) {\n if (sn === 0n) {\n return false;\n }\n\n const sibling = decodeBase64(node, `path[${index}]`);\n\n if (leastSignificantBit(fn) === 1n || fn === sn) {\n current = hashHCS27Node(sibling, current);\n if (leastSignificantBit(fn) === 0n) {\n while (leastSignificantBit(fn) === 0n && fn !== 0n) {\n fn /= 2n;\n sn /= 2n;\n }\n }\n } else {\n current = hashHCS27Node(current, sibling);\n }\n\n fn /= 2n;\n sn /= 2n;\n }\n\n return sn === 0n && current.toString('base64') === expectedRootB64;\n}\n\nexport function verifyConsistencyProof(\n params:\n | HCS27ConsistencyProof\n | {\n oldTreeSize: number;\n newTreeSize: number;\n oldRootB64: string;\n newRootB64: string;\n consistencyPath: string[];\n },\n): boolean {\n let oldTreeSize: bigint;\n let newTreeSize: bigint;\n let oldRootB64: string;\n let newRootB64: string;\n let consistencyPath: string[];\n\n if ('oldRootHash' in params) {\n const proof = hcs27ConsistencyProofSchema.parse(params);\n oldTreeSize = BigInt(proof.oldTreeSize);\n newTreeSize = BigInt(proof.newTreeSize);\n oldRootB64 = proof.oldRootHash;\n newRootB64 = proof.newRootHash;\n consistencyPath = proof.consistencyPath;\n } else {\n oldTreeSize = parseTreeSize(params.oldTreeSize);\n newTreeSize = parseTreeSize(params.newTreeSize);\n oldRootB64 = params.oldRootB64;\n newRootB64 = params.newRootB64;\n consistencyPath = params.consistencyPath;\n }\n\n if (oldTreeSize < 0n || newTreeSize < 0n) {\n throw new Error('tree sizes must be non-negative');\n }\n if (oldTreeSize === 0n) {\n return true;\n }\n if (oldTreeSize === newTreeSize) {\n decodeBase64(oldRootB64, 'oldRootHash');\n decodeBase64(newRootB64, 'newRootHash');\n return oldRootB64 === newRootB64 && consistencyPath.length === 0;\n }\n if (oldTreeSize > newTreeSize || consistencyPath.length === 0) {\n return false;\n }\n\n const path = consistencyPath.map((node, index) =>\n decodeBase64(node, `consistencyPath[${index}]`),\n );\n if (isExactPowerOfTwo(oldTreeSize)) {\n path.unshift(decodeBase64(oldRootB64, 'oldRootHash'));\n }\n\n let fn = oldTreeSize - 1n;\n let sn = newTreeSize - 1n;\n\n while (leastSignificantBit(fn) === 1n) {\n fn /= 2n;\n sn /= 2n;\n }\n\n const firstHash = Buffer.from(path[0]);\n let fr: Uint8Array = Buffer.from(firstHash);\n let sr: Uint8Array = Buffer.from(firstHash);\n\n for (const nodeHash of path.slice(1)) {\n if (sn === 0n) {\n return false;\n }\n\n if (leastSignificantBit(fn) === 1n || fn === sn) {\n fr = hashHCS27Node(nodeHash, fr);\n sr = hashHCS27Node(nodeHash, sr);\n if (leastSignificantBit(fn) === 0n) {\n while (leastSignificantBit(fn) === 0n && fn !== 0n) {\n fn /= 2n;\n sn /= 2n;\n }\n }\n } else {\n sr = hashHCS27Node(sr, nodeHash);\n }\n\n fn /= 2n;\n sn /= 2n;\n }\n\n return (\n sn === 0n &&\n Buffer.from(fr).toString('base64') === oldRootB64 &&\n Buffer.from(sr).toString('base64') === newRootB64\n );\n}\n"],"names":[],"mappings":";;AAQA,SAAS,mBAAmB,OAAyB;AACnD,MACE,UAAU,QACV,OAAO,UAAU,aACjB,OAAO,UAAU,YACjB,OAAO,UAAU,UACjB;AACA,QAAI,OAAO,UAAU,YAAY,CAAC,OAAO,SAAS,KAAK,GAAG;AACxD,YAAM,IAAI,MAAM,6BAA6B;AAAA,IAC/C;AACA,WAAO;AAAA,EACT;AAEA,MAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,WAAO,MAAM;AAAA,MAAK;AAAA,MAAO,CAAA,SACvB,SAAS,SAAY,OAAO,mBAAmB,IAAI;AAAA,IAAA;AAAA,EAEvD;AAEA,MAAI,OAAO,UAAU,UAAU;AAC7B,UAAM,SAAU,MAAqC;AACrD,QAAI,OAAO,WAAW,YAAY;AAChC,aAAO,mBAAmB,OAAO,KAAK,KAAK,CAAC;AAAA,IAC9C;AAEA,UAAM,SAAkC,CAAA;AACxC,eAAW,CAAC,KAAK,IAAI,KAAK,OAAO,QAAQ,KAAK,GAAG;AAC/C,UAAI,SAAS,QAAW;AACtB,eAAO,GAAG,IAAI,mBAAmB,IAAI;AAAA,MACvC;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAEA,QAAM,IAAI,MAAM,gCAAgC,OAAO,KAAK,EAAE;AAChE;AAEA,SAAS,aAAa,OAAuB;AAC3C,MAAI,OAAO,GAAG,OAAO,EAAE,GAAG;AACxB,WAAO;AAAA,EACT;AACA,SAAO,MAAM,SAAA;AACf;AAEA,SAAS,aAAa,OAAe,WAA2B;AAC9D,MAAI;AACF,QAAI,CAAC,OAAO;AACV,YAAM,IAAI,MAAM,cAAc;AAAA,IAChC;AACA,UAAM,UAAU,OAAO,KAAK,OAAO,QAAQ;AAC3C,QAAI,QAAQ,SAAS,QAAQ,MAAM,OAAO;AACxC,YAAM,IAAI,MAAM,sBAAsB;AAAA,IACxC;AACA,WAAO;AAAA,EACT,QAAQ;AACN,UAAM,IAAI,MAAM,GAAG,SAAS,uBAAuB;AAAA,EACrD;AACF;AAEA,SAAS,mBAAmB,OAAwB;AAClD,MAAI,UAAU,MAAM;AAClB,WAAO;AAAA,EACT;AACA,MAAI,OAAO,UAAU,WAAW;AAC9B,WAAO,QAAQ,SAAS;AAAA,EAC1B;AACA,MAAI,OAAO,UAAU,UAAU;AAC7B,WAAO,KAAK,UAAU,KAAK;AAAA,EAC7B;AACA,MAAI,OAAO,UAAU,UAAU;AAC7B,WAAO,aAAa,KAAK;AAAA,EAC3B;AACA,MAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,WAAO,IAAI,MAAM,IAAI,CAAA,SAAQ,mBAAmB,IAAI,CAAC,EAAE,KAAK,GAAG,CAAC;AAAA,EAClE;AACA,MAAI,OAAO,UAAU,UAAU;AAC7B,UAAM,UAAU,OAAO,QAAQ,KAAK,EAAE;AAAA,MAAK,CAAC,CAAC,IAAI,GAAG,CAAC,KAAK,MACxD,OAAO,QAAQ,KAAK,OAAO,QAAQ,IAAI;AAAA,IAAA;AAEzC,WAAO,IAAI,QACR;AAAA,MACC,CAAC,CAAC,KAAK,IAAI,MAAM,GAAG,KAAK,UAAU,GAAG,CAAC,IAAI,mBAAmB,IAAI,CAAC;AAAA,IAAA,EAEpE,KAAK,GAAG,CAAC;AAAA,EACd;AACA,QAAM,IAAI,MAAM,gCAAgC,OAAO,KAAK,EAAE;AAChE;AAEA,SAAS,cAAc,OAAgC;AACrD,SAAO,OAAO,UAAU,WAAW,OAAO,KAAK,IAAI,OAAO,KAAK;AACjE;AAEA,SAAS,oBAAoB,OAAuB;AAClD,SAAO,QAAQ;AACjB;AAEA,SAAS,kBAAkB,OAAwB;AACjD,SAAO,UAAU,OAAO,QAAS,QAAQ,QAAS;AACpD;AAEA,SAAS,0BAA0B,OAAuB;AACxD,MAAI,SAAS,GAAG;AACd,WAAO;AAAA,EACT;AAEA,MAAI,SAAS;AACb,SAAO,UAAU,IAAI,OAAO;AAC1B,eAAW;AAAA,EACb;AACA,SAAO;AACT;AAEO,SAAS,sBAAsB,OAAwB;AAC5D,QAAM,aAAa,mBAAmB,KAAK;AAC3C,SAAO,OAAO,KAAK,mBAAmB,UAAU,GAAG,MAAM;AAC3D;AAEO,SAAS,iBAAyB;AACvC,SAAO,WAAW,QAAQ,EAAE,OAAO,OAAO,MAAM,CAAC,CAAC,EAAE,OAAA;AACtD;AAEO,SAAS,cAAc,gBAA6C;AACzE,SAAO,WAAW,QAAQ,EACvB,OAAO,OAAO,KAAK,CAAC,CAAI,CAAC,CAAC,EAC1B,OAAO,OAAO,KAAK,cAAc,CAAC,EAClC,OAAA;AACL;AAEO,SAAS,cACd,MACA,OACQ;AACR,SAAO,WAAW,QAAQ,EACvB,OAAO,OAAO,KAAK,CAAC,CAAI,CAAC,CAAC,EAC1B,OAAO,OAAO,KAAK,IAAI,CAAC,EACxB,OAAO,OAAO,KAAK,KAAK,CAAC,EACzB,OAAA;AACL;AAEO,SAAS,+BACd,SACQ;AACR,MAAI,QAAQ,WAAW,GAAG;AACxB,WAAO,eAAA;AAAA,EACT;AACA,MAAI,QAAQ,WAAW,GAAG;AACxB,WAAO,cAAc,QAAQ,CAAC,CAAC;AAAA,EACjC;AAEA,QAAM,QAAQ,0BAA0B,QAAQ,MAAM;AACtD,QAAM,OAAO,+BAA+B,QAAQ,MAAM,GAAG,KAAK,CAAC;AACnE,QAAM,QAAQ,+BAA+B,QAAQ,MAAM,KAAK,CAAC;AACjE,SAAO,cAAc,MAAM,KAAK;AAClC;AAEO,SAAS,sBAAsB,SAAyC;AAC7E,QAAM,mBAAmB,QAAQ,IAAI,CAAA,UAAS,sBAAsB,KAAK,CAAC;AAC1E,SAAO,+BAA+B,gBAAgB;AACxD;AAEO,SAAS,qBAAqB,OAAwB;AAC3D,SAAO,cAAc,sBAAsB,KAAK,CAAC,EAAE,SAAS,KAAK;AACnE;AAEO,SAAS,qBACd,QASS;AACT,MAAI;AACJ,MAAI;AACJ,MAAI;AACJ,MAAI;AACJ,MAAI;AAEJ,MAAI,cAAc,QAAQ;AACxB,UAAM,QAAQ,0BAA0B,MAAM,MAAM;AACpD,gBAAY,OAAO,MAAM,SAAS;AAClC,eAAW,OAAO,MAAM,QAAQ;AAChC,kBAAc,MAAM;AACpB,WAAO,MAAM;AACb,sBAAkB,MAAM;AAAA,EAC1B,OAAO;AACL,gBAAY,cAAc,OAAO,SAAS;AAC1C,eAAW,cAAc,OAAO,QAAQ;AACxC,kBAAc,OAAO;AACrB,WAAO,OAAO;AACd,sBAAkB,OAAO;AAAA,EAC3B;AAEA,MAAI,YAAY,IAAI;AAClB,UAAM,IAAI,MAAM,yDAAyD;AAAA,EAC3E;AACA,MAAI,YAAY,MAAM,aAAa,UAAU;AAC3C,UAAM,IAAI,MAAM,sCAAsC;AAAA,EACxD;AACA,MAAI,CAAC,sBAAsB,KAAK,YAAY,KAAA,CAAM,GAAG;AACnD,UAAM,IAAI,MAAM,4BAA4B;AAAA,EAC9C;AAEA,MAAI;AACJ,MAAI;AACF,cAAU,OAAO,KAAK,YAAY,KAAA,GAAQ,KAAK;AAAA,EACjD,QAAQ;AACN,UAAM,IAAI,MAAM,4BAA4B;AAAA,EAC9C;AAEA,MAAI,KAAK;AACT,MAAI,KAAK,WAAW;AAEpB,aAAW,CAAC,OAAO,IAAI,KAAK,KAAK,WAAW;AAC1C,QAAI,OAAO,IAAI;AACb,aAAO;AAAA,IACT;AAEA,UAAM,UAAU,aAAa,MAAM,QAAQ,KAAK,GAAG;AAEnD,QAAI,oBAAoB,EAAE,MAAM,MAAM,OAAO,IAAI;AAC/C,gBAAU,cAAc,SAAS,OAAO;AACxC,UAAI,oBAAoB,EAAE,MAAM,IAAI;AAClC,eAAO,oBAAoB,EAAE,MAAM,MAAM,OAAO,IAAI;AAClD,gBAAM;AACN,gBAAM;AAAA,QACR;AAAA,MACF;AAAA,IACF,OAAO;AACL,gBAAU,cAAc,SAAS,OAAO;AAAA,IAC1C;AAEA,UAAM;AACN,UAAM;AAAA,EACR;AAEA,SAAO,OAAO,MAAM,QAAQ,SAAS,QAAQ,MAAM;AACrD;AAEO,SAAS,uBACd,QASS;AACT,MAAI;AACJ,MAAI;AACJ,MAAI;AACJ,MAAI;AACJ,MAAI;AAEJ,MAAI,iBAAiB,QAAQ;AAC3B,UAAM,QAAQ,4BAA4B,MAAM,MAAM;AACtD,kBAAc,OAAO,MAAM,WAAW;AACtC,kBAAc,OAAO,MAAM,WAAW;AACtC,iBAAa,MAAM;AACnB,iBAAa,MAAM;AACnB,sBAAkB,MAAM;AAAA,EAC1B,OAAO;AACL,kBAAc,cAAc,OAAO,WAAW;AAC9C,kBAAc,cAAc,OAAO,WAAW;AAC9C,iBAAa,OAAO;AACpB,iBAAa,OAAO;AACpB,sBAAkB,OAAO;AAAA,EAC3B;AAEA,MAAI,cAAc,MAAM,cAAc,IAAI;AACxC,UAAM,IAAI,MAAM,iCAAiC;AAAA,EACnD;AACA,MAAI,gBAAgB,IAAI;AACtB,WAAO;AAAA,EACT;AACA,MAAI,gBAAgB,aAAa;AAC/B,iBAAa,YAAY,aAAa;AACtC,iBAAa,YAAY,aAAa;AACtC,WAAO,eAAe,cAAc,gBAAgB,WAAW;AAAA,EACjE;AACA,MAAI,cAAc,eAAe,gBAAgB,WAAW,GAAG;AAC7D,WAAO;AAAA,EACT;AAEA,QAAM,OAAO,gBAAgB;AAAA,IAAI,CAAC,MAAM,UACtC,aAAa,MAAM,mBAAmB,KAAK,GAAG;AAAA,EAAA;AAEhD,MAAI,kBAAkB,WAAW,GAAG;AAClC,SAAK,QAAQ,aAAa,YAAY,aAAa,CAAC;AAAA,EACtD;AAEA,MAAI,KAAK,cAAc;AACvB,MAAI,KAAK,cAAc;AAEvB,SAAO,oBAAoB,EAAE,MAAM,IAAI;AACrC,UAAM;AACN,UAAM;AAAA,EACR;AAEA,QAAM,YAAY,OAAO,KAAK,KAAK,CAAC,CAAC;AACrC,MAAI,KAAiB,OAAO,KAAK,SAAS;AAC1C,MAAI,KAAiB,OAAO,KAAK,SAAS;AAE1C,aAAW,YAAY,KAAK,MAAM,CAAC,GAAG;AACpC,QAAI,OAAO,IAAI;AACb,aAAO;AAAA,IACT;AAEA,QAAI,oBAAoB,EAAE,MAAM,MAAM,OAAO,IAAI;AAC/C,WAAK,cAAc,UAAU,EAAE;AAC/B,WAAK,cAAc,UAAU,EAAE;AAC/B,UAAI,oBAAoB,EAAE,MAAM,IAAI;AAClC,eAAO,oBAAoB,EAAE,MAAM,MAAM,OAAO,IAAI;AAClD,gBAAM;AACN,gBAAM;AAAA,QACR;AAAA,MACF;AAAA,IACF,OAAO;AACL,WAAK,cAAc,IAAI,QAAQ;AAAA,IACjC;AAEA,UAAM;AACN,UAAM;AAAA,EACR;AAEA,SACE,OAAO,MACP,OAAO,KAAK,EAAE,EAAE,SAAS,QAAQ,MAAM,cACvC,OAAO,KAAK,EAAE,EAAE,SAAS,QAAQ,MAAM;AAE3C;"}
|