@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,163 +1,192 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
if (typeof hrlCandidate !== "string" || !hrlCandidate.trim()) {
|
|
10
|
-
throw new Error("Missing manifest reference in version register entry");
|
|
11
|
-
}
|
|
12
|
-
const hrl = hrlCandidate.trim();
|
|
13
|
-
const prefix = "hcs://1/";
|
|
14
|
-
if (!hrl.startsWith(prefix)) {
|
|
15
|
-
throw new Error(`Invalid manifest HRL: ${hrl}`);
|
|
16
|
-
}
|
|
17
|
-
return hrl.slice(prefix.length);
|
|
18
|
-
}
|
|
19
|
-
class HCS26BaseClient {
|
|
1
|
+
import { createHash } from "crypto";
|
|
2
|
+
import { HederaMirrorNode } from "./standards-sdk.es144.js";
|
|
3
|
+
import { HRLResolver } from "./standards-sdk.es127.js";
|
|
4
|
+
import { Logger } from "./standards-sdk.es123.js";
|
|
5
|
+
import { buildHCS27TopicMemo, parseHCS27TopicMemo, buildHCS27TransactionMemo } from "./standards-sdk.es113.js";
|
|
6
|
+
import { emptyHCS27Root, hashHCS27Leaf, hashHCS27Node, merkleRootFromCanonicalEntries, merkleRootFromEntries, leafHashHexFromEntry, verifyInclusionProof, verifyConsistencyProof } from "./standards-sdk.es114.js";
|
|
7
|
+
import { hcs27CheckpointMessageSchema, toHCS27CheckpointMetadata, hcs27CheckpointMetadataSchema, toHCS27CheckpointMessage } from "./standards-sdk.es112.js";
|
|
8
|
+
class HCS27BaseClient {
|
|
20
9
|
constructor(config) {
|
|
21
10
|
this.network = config.network;
|
|
22
11
|
this.logger = config.logger ?? Logger.getInstance({
|
|
23
|
-
module: "
|
|
12
|
+
module: "HCS27Client",
|
|
24
13
|
level: "info"
|
|
25
14
|
});
|
|
26
|
-
this.
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
15
|
+
this.mirrorNode = new HederaMirrorNode(
|
|
16
|
+
this.network,
|
|
17
|
+
this.logger,
|
|
18
|
+
config.mirrorNode
|
|
19
|
+
);
|
|
20
|
+
this.cdnEndpoint = config.cdnEndpoint?.trim() || void 0;
|
|
21
|
+
this.hrlResolver = new HRLResolver();
|
|
32
22
|
}
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
23
|
+
buildTopicMemo(ttlSeconds) {
|
|
24
|
+
return buildHCS27TopicMemo(ttlSeconds);
|
|
25
|
+
}
|
|
26
|
+
parseTopicMemo(memo) {
|
|
27
|
+
return parseHCS27TopicMemo(memo);
|
|
28
|
+
}
|
|
29
|
+
buildTransactionMemo() {
|
|
30
|
+
return buildHCS27TransactionMemo();
|
|
31
|
+
}
|
|
32
|
+
emptyRoot() {
|
|
33
|
+
return emptyHCS27Root();
|
|
34
|
+
}
|
|
35
|
+
/** Strings are treated as UTF-8 canonical entry bytes. */
|
|
36
|
+
hashLeaf(canonicalEntry) {
|
|
37
|
+
const entry = typeof canonicalEntry === "string" ? Buffer.from(canonicalEntry, "utf8") : Buffer.from(canonicalEntry);
|
|
38
|
+
return hashHCS27Leaf(entry);
|
|
39
|
+
}
|
|
40
|
+
/** Strings are treated as hex-encoded hash bytes. */
|
|
41
|
+
hashNode(left, right) {
|
|
42
|
+
const leftBytes = typeof left === "string" ? Buffer.from(left, "hex") : Buffer.from(left);
|
|
43
|
+
const rightBytes = typeof right === "string" ? Buffer.from(right, "hex") : Buffer.from(right);
|
|
44
|
+
return hashHCS27Node(leftBytes, rightBytes);
|
|
45
|
+
}
|
|
46
|
+
merkleRootFromCanonicalEntries(entries) {
|
|
47
|
+
const canonicalEntries = entries.map(
|
|
48
|
+
(entry) => typeof entry === "string" ? Buffer.from(entry, "utf8") : Buffer.from(entry)
|
|
49
|
+
);
|
|
50
|
+
return merkleRootFromCanonicalEntries(canonicalEntries);
|
|
51
|
+
}
|
|
52
|
+
merkleRootFromEntries(entries) {
|
|
53
|
+
return merkleRootFromEntries(entries);
|
|
54
|
+
}
|
|
55
|
+
leafHashHexFromEntry(entry) {
|
|
56
|
+
return leafHashHexFromEntry(entry);
|
|
57
|
+
}
|
|
58
|
+
verifyInclusionProof(proof) {
|
|
59
|
+
return verifyInclusionProof(proof);
|
|
60
|
+
}
|
|
61
|
+
verifyConsistencyProof(proof) {
|
|
62
|
+
return verifyConsistencyProof(proof);
|
|
63
|
+
}
|
|
64
|
+
async validateCheckpointMessage(message, resolver, inlineMetadataDigestSource) {
|
|
65
|
+
const originalInlineMetadataBytes = inlineMetadataDigestSource ?? (typeof message.metadata === "string" ? void 0 : Buffer.from(JSON.stringify(message.metadata), "utf8"));
|
|
66
|
+
const parsedMessage = hcs27CheckpointMessageSchema.parse(message);
|
|
67
|
+
const effectiveResolver = resolver ?? ((reference) => this.resolveHCS1Reference(reference));
|
|
68
|
+
let metadataBytes;
|
|
69
|
+
let metadata;
|
|
70
|
+
if (typeof parsedMessage.metadata === "string") {
|
|
71
|
+
metadataBytes = await effectiveResolver(parsedMessage.metadata);
|
|
72
|
+
metadata = toHCS27CheckpointMetadata(
|
|
73
|
+
hcs27CheckpointMetadataSchema.parse(
|
|
74
|
+
JSON.parse(metadataBytes.toString("utf8"))
|
|
75
|
+
)
|
|
76
|
+
);
|
|
77
|
+
} else {
|
|
78
|
+
metadata = toHCS27CheckpointMetadata(
|
|
79
|
+
hcs27CheckpointMetadataSchema.parse(parsedMessage.metadata)
|
|
50
80
|
);
|
|
51
81
|
}
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
versionRegister: latestVersion,
|
|
58
|
-
manifestSha256Hex: sha256Hex
|
|
59
|
-
});
|
|
60
|
-
let verification;
|
|
61
|
-
const provider = this.verificationProvider;
|
|
62
|
-
const includeVerification = params.includeVerification === true;
|
|
63
|
-
const name = typeof discovery.metadata?.name === "string" ? discovery.metadata.name.trim() : "";
|
|
64
|
-
if (includeVerification && provider && name) {
|
|
65
|
-
try {
|
|
66
|
-
verification = await provider.getSkillVerificationStatus({ name });
|
|
67
|
-
} catch (error) {
|
|
68
|
-
const detail = error instanceof Error ? error.message : String(error);
|
|
69
|
-
this.logger.warn(
|
|
70
|
-
`Failed to resolve verification status for skill "${name}": ${detail}`
|
|
71
|
-
);
|
|
72
|
-
verification = null;
|
|
82
|
+
if (parsedMessage.metadata_digest) {
|
|
83
|
+
const digestBytes = metadataBytes ?? originalInlineMetadataBytes ?? Buffer.from(JSON.stringify(parsedMessage.metadata), "utf8");
|
|
84
|
+
const digest = createHash("sha256").update(digestBytes).digest("base64url");
|
|
85
|
+
if (digest !== parsedMessage.metadata_digest.b64u) {
|
|
86
|
+
throw new Error("metadata digest does not match resolved payload");
|
|
73
87
|
}
|
|
74
88
|
}
|
|
75
|
-
return
|
|
76
|
-
directoryTopicId: params.directoryTopicId,
|
|
77
|
-
skillUid: params.skillUid,
|
|
78
|
-
discovery,
|
|
79
|
-
versionRegistryTopicId,
|
|
80
|
-
latestVersion,
|
|
81
|
-
manifest,
|
|
82
|
-
manifestSha256Hex: sha256Hex,
|
|
83
|
-
...includeVerification ? { verification } : {}
|
|
84
|
-
};
|
|
85
|
-
}
|
|
86
|
-
async listSkillVersions(params) {
|
|
87
|
-
const discovery = await this.resolver.resolveDiscoveryRecord({
|
|
88
|
-
directoryTopicId: params.directoryTopicId,
|
|
89
|
-
skillUid: params.skillUid,
|
|
90
|
-
scanLimit: params.discoveryScanLimit
|
|
91
|
-
});
|
|
92
|
-
if (!discovery) {
|
|
93
|
-
return [];
|
|
94
|
-
}
|
|
95
|
-
const versionRegistryTopicId = discovery.t_id;
|
|
96
|
-
return this.resolver.listVersionRegisters({
|
|
97
|
-
versionRegistryTopicId,
|
|
98
|
-
skillUid: params.skillUid,
|
|
99
|
-
limit: params.limit
|
|
100
|
-
});
|
|
89
|
+
return metadata;
|
|
101
90
|
}
|
|
102
|
-
|
|
103
|
-
const
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
91
|
+
validateCheckpointChain(records) {
|
|
92
|
+
const streams = /* @__PURE__ */ new Map();
|
|
93
|
+
for (const record of records) {
|
|
94
|
+
const streamRegistry = record.effectiveMetadata.stream.registry;
|
|
95
|
+
const streamLogId = record.effectiveMetadata.stream.log_id;
|
|
96
|
+
let registryStreams = streams.get(streamRegistry);
|
|
97
|
+
if (!registryStreams) {
|
|
98
|
+
registryStreams = /* @__PURE__ */ new Map();
|
|
99
|
+
streams.set(streamRegistry, registryStreams);
|
|
100
|
+
}
|
|
101
|
+
const streamLabel = JSON.stringify({
|
|
102
|
+
registry: streamRegistry,
|
|
103
|
+
log_id: streamLogId
|
|
104
|
+
});
|
|
105
|
+
const currentTreeSize = BigInt(record.effectiveMetadata.root.treeSize);
|
|
106
|
+
const previous = registryStreams.get(streamLogId);
|
|
107
|
+
if (previous) {
|
|
108
|
+
if (currentTreeSize < previous.treeSize) {
|
|
109
|
+
throw new Error(`tree size decreased for stream ${streamLabel}`);
|
|
110
|
+
}
|
|
111
|
+
if (currentTreeSize === previous.treeSize && record.effectiveMetadata.root.rootHashB64u !== previous.rootHashB64u) {
|
|
112
|
+
throw new Error(
|
|
113
|
+
`root changed without growing tree size for stream ${streamLabel}`
|
|
114
|
+
);
|
|
115
|
+
}
|
|
116
|
+
if (!record.effectiveMetadata.prev) {
|
|
117
|
+
throw new Error(`missing prev linkage for stream ${streamLabel}`);
|
|
118
|
+
}
|
|
119
|
+
const previousTreeSize = BigInt(record.effectiveMetadata.prev.treeSize);
|
|
120
|
+
if (previousTreeSize !== previous.treeSize) {
|
|
121
|
+
throw new Error(`prev.treeSize mismatch for stream ${streamLabel}`);
|
|
122
|
+
}
|
|
123
|
+
if (record.effectiveMetadata.prev.rootHashB64u !== previous.rootHashB64u) {
|
|
124
|
+
throw new Error(
|
|
125
|
+
`prev.rootHashB64u mismatch for stream ${streamLabel}`
|
|
126
|
+
);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
registryStreams.set(streamLogId, {
|
|
130
|
+
treeSize: currentTreeSize,
|
|
131
|
+
rootHashB64u: record.effectiveMetadata.root.rootHashB64u
|
|
132
|
+
});
|
|
124
133
|
}
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
await this.resolver.verifyVersionRegisterMatchesManifest({
|
|
130
|
-
versionRegister: target,
|
|
131
|
-
manifestSha256Hex: sha256Hex
|
|
134
|
+
}
|
|
135
|
+
async getCheckpoints(topicId) {
|
|
136
|
+
const messages = await this.mirrorNode.getTopicMessages(topicId, {
|
|
137
|
+
order: "asc"
|
|
132
138
|
});
|
|
133
|
-
|
|
134
|
-
const
|
|
135
|
-
const includeVerification = params.includeVerification === true;
|
|
136
|
-
const name = typeof discovery.metadata?.name === "string" ? discovery.metadata.name.trim() : "";
|
|
137
|
-
if (includeVerification && provider && name) {
|
|
139
|
+
const records = [];
|
|
140
|
+
for (const item of messages) {
|
|
138
141
|
try {
|
|
139
|
-
|
|
142
|
+
const parsedMessage = hcs27CheckpointMessageSchema.parse({
|
|
143
|
+
p: item.p,
|
|
144
|
+
op: item.op,
|
|
145
|
+
metadata: item.metadata,
|
|
146
|
+
metadata_digest: item.metadata_digest,
|
|
147
|
+
m: item.m
|
|
148
|
+
});
|
|
149
|
+
const rawInlineMetadataDigestSource = typeof item.metadata === "string" ? void 0 : Buffer.from(JSON.stringify(item.metadata), "utf8");
|
|
150
|
+
const effectiveMetadata = await this.validateCheckpointMessage(
|
|
151
|
+
parsedMessage,
|
|
152
|
+
void 0,
|
|
153
|
+
rawInlineMetadataDigestSource
|
|
154
|
+
);
|
|
155
|
+
const message = toHCS27CheckpointMessage(parsedMessage);
|
|
156
|
+
records.push({
|
|
157
|
+
topicId,
|
|
158
|
+
sequence: item.sequence_number,
|
|
159
|
+
consensusTimestamp: item.consensus_timestamp ?? "",
|
|
160
|
+
payer: typeof item.payer_account_id === "string" ? item.payer_account_id : item.payer,
|
|
161
|
+
message,
|
|
162
|
+
effectiveMetadata
|
|
163
|
+
});
|
|
140
164
|
} catch (error) {
|
|
141
165
|
const detail = error instanceof Error ? error.message : String(error);
|
|
142
166
|
this.logger.warn(
|
|
143
|
-
`
|
|
167
|
+
`Skipping invalid HCS-27 checkpoint message: ${detail}`
|
|
144
168
|
);
|
|
145
|
-
verification = null;
|
|
146
169
|
}
|
|
147
170
|
}
|
|
148
|
-
return
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
171
|
+
return records;
|
|
172
|
+
}
|
|
173
|
+
async resolveHCS1Reference(reference) {
|
|
174
|
+
const trimmed = reference.trim();
|
|
175
|
+
if (!/^hcs:\/\/1\/\d+\.\d+\.\d+$/.test(trimmed)) {
|
|
176
|
+
throw new Error(`Invalid HCS-1 reference: ${reference}`);
|
|
177
|
+
}
|
|
178
|
+
const resolved = await this.hrlResolver.resolveHRL(trimmed, {
|
|
179
|
+
network: this.network,
|
|
180
|
+
cdnEndpoint: this.cdnEndpoint,
|
|
181
|
+
returnRaw: true
|
|
182
|
+
});
|
|
183
|
+
if (typeof resolved.content === "string") {
|
|
184
|
+
return Buffer.from(resolved.content, "utf8");
|
|
185
|
+
}
|
|
186
|
+
return Buffer.from(resolved.content);
|
|
158
187
|
}
|
|
159
188
|
}
|
|
160
189
|
export {
|
|
161
|
-
|
|
190
|
+
HCS27BaseClient
|
|
162
191
|
};
|
|
163
192
|
//# sourceMappingURL=standards-sdk.es115.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"standards-sdk.es115.js","sources":["../../src/hcs-26/base-client.ts"],"sourcesContent":["import type { ILogger } from '../utils/logger';\nimport { Logger } from '../utils/logger';\nimport type { NetworkType } from '../utils/types';\nimport type { MirrorNodeConfig } from '../services/mirror-node';\nimport { Hcs26SkillRegistryResolver } from './resolver';\nimport type {\n Hcs26SkillManifest,\n Hcs26VersionRegister,\n Hcs26VersionRegisterLegacy,\n} from './types';\n\nexport type HCS26SkillVerificationStatus = {\n name: string;\n verified: boolean;\n previouslyVerified: boolean;\n pendingRequest?: unknown;\n};\n\nexport interface HCS26SkillVerificationProvider {\n getSkillVerificationStatus(params: {\n name: string;\n }): Promise<HCS26SkillVerificationStatus | null>;\n}\n\nexport interface HCS26ClientConfig {\n network: NetworkType;\n logger?: ILogger;\n mirrorNode?: MirrorNodeConfig;\n verificationProvider?: HCS26SkillVerificationProvider;\n}\n\nexport type HCS26DiscoveryRecord = {\n p: 'hcs-26';\n op: 'register';\n t_id: string;\n account_id: string;\n metadata: Record<string, unknown>;\n m?: string;\n sequence_number?: number;\n};\n\nexport type HCS26ResolvedSkill = {\n directoryTopicId: string;\n skillUid: number;\n discovery: HCS26DiscoveryRecord;\n versionRegistryTopicId: string;\n latestVersion:\n | (Hcs26VersionRegister & { sequence_number?: number })\n | (Hcs26VersionRegisterLegacy & { sequence_number?: number });\n manifest: Hcs26SkillManifest;\n manifestSha256Hex: string;\n verification?: HCS26SkillVerificationStatus | null;\n};\n\nexport type HCS26ResolvedSkillVersion = Omit<\n HCS26ResolvedSkill,\n 'latestVersion'\n> & {\n versionEntry:\n | (Hcs26VersionRegister & { sequence_number?: number })\n | (Hcs26VersionRegisterLegacy & { sequence_number?: number });\n};\n\nfunction getManifestTopicId(\n entry: Hcs26VersionRegister | Hcs26VersionRegisterLegacy,\n): string {\n const topicIdCandidate = (entry as { t_id?: unknown }).t_id;\n if (typeof topicIdCandidate === 'string' && topicIdCandidate.trim()) {\n return topicIdCandidate.trim();\n }\n\n const hrlCandidate = (entry as { manifest_hcs1?: unknown }).manifest_hcs1;\n if (typeof hrlCandidate !== 'string' || !hrlCandidate.trim()) {\n throw new Error('Missing manifest reference in version register entry');\n }\n\n const hrl = hrlCandidate.trim();\n const prefix = 'hcs://1/';\n if (!hrl.startsWith(prefix)) {\n throw new Error(`Invalid manifest HRL: ${hrl}`);\n }\n return hrl.slice(prefix.length);\n}\n\nexport class HCS26BaseClient {\n protected readonly network: NetworkType;\n protected readonly logger: ILogger;\n protected readonly resolver: Hcs26SkillRegistryResolver;\n protected readonly verificationProvider?: HCS26SkillVerificationProvider;\n\n constructor(config: HCS26ClientConfig) {\n this.network = config.network;\n this.logger =\n config.logger ??\n Logger.getInstance({\n module: 'HCS26Client',\n level: 'info',\n });\n this.verificationProvider = config.verificationProvider;\n\n this.resolver = new Hcs26SkillRegistryResolver({\n network: this.network,\n logger: this.logger,\n mirrorNode: config.mirrorNode,\n });\n }\n\n async resolveSkill(params: {\n directoryTopicId: string;\n skillUid: number;\n discoveryScanLimit?: number;\n includeVerification?: boolean;\n }): Promise<HCS26ResolvedSkill | null> {\n const discovery = (await this.resolver.resolveDiscoveryRecord({\n directoryTopicId: params.directoryTopicId,\n skillUid: params.skillUid,\n scanLimit: params.discoveryScanLimit,\n })) as HCS26DiscoveryRecord | null;\n\n if (!discovery) {\n return null;\n }\n\n const versionRegistryTopicId = discovery.t_id;\n const latestVersion = await this.resolver.getLatestVersionRegister({\n versionRegistryTopicId,\n skillUid: params.skillUid,\n });\n\n if (!latestVersion) {\n throw new Error(\n `No active version entries found for skill ${params.skillUid} in version registry ${versionRegistryTopicId}`,\n );\n }\n\n const manifestTopicId = getManifestTopicId(latestVersion);\n const { manifest, sha256Hex } = await this.resolver.resolveManifest({\n manifestTopicId,\n });\n\n await this.resolver.verifyVersionRegisterMatchesManifest({\n versionRegister: latestVersion,\n manifestSha256Hex: sha256Hex,\n });\n\n let verification: HCS26SkillVerificationStatus | null | undefined;\n const provider = this.verificationProvider;\n const includeVerification = params.includeVerification === true;\n const name =\n typeof discovery.metadata?.name === 'string'\n ? discovery.metadata.name.trim()\n : '';\n\n if (includeVerification && provider && name) {\n try {\n verification = await provider.getSkillVerificationStatus({ name });\n } catch (error) {\n const detail = error instanceof Error ? error.message : String(error);\n this.logger.warn(\n `Failed to resolve verification status for skill \"${name}\": ${detail}`,\n );\n verification = null;\n }\n }\n\n return {\n directoryTopicId: params.directoryTopicId,\n skillUid: params.skillUid,\n discovery,\n versionRegistryTopicId,\n latestVersion,\n manifest,\n manifestSha256Hex: sha256Hex,\n ...(includeVerification ? { verification } : {}),\n };\n }\n\n async listSkillVersions(params: {\n directoryTopicId: string;\n skillUid: number;\n discoveryScanLimit?: number;\n limit?: number;\n }): Promise<\n Array<\n | (Hcs26VersionRegister & { sequence_number?: number })\n | (Hcs26VersionRegisterLegacy & { sequence_number?: number })\n >\n > {\n const discovery = (await this.resolver.resolveDiscoveryRecord({\n directoryTopicId: params.directoryTopicId,\n skillUid: params.skillUid,\n scanLimit: params.discoveryScanLimit,\n })) as HCS26DiscoveryRecord | null;\n\n if (!discovery) {\n return [];\n }\n\n const versionRegistryTopicId = discovery.t_id;\n return this.resolver.listVersionRegisters({\n versionRegistryTopicId,\n skillUid: params.skillUid,\n limit: params.limit,\n });\n }\n\n async resolveSkillVersion(params: {\n directoryTopicId: string;\n skillUid: number;\n version: string;\n discoveryScanLimit?: number;\n includeVerification?: boolean;\n }): Promise<HCS26ResolvedSkillVersion | null> {\n const versionRaw = params.version.trim();\n if (!versionRaw) {\n throw new Error('version is required');\n }\n\n const discovery = (await this.resolver.resolveDiscoveryRecord({\n directoryTopicId: params.directoryTopicId,\n skillUid: params.skillUid,\n scanLimit: params.discoveryScanLimit,\n })) as HCS26DiscoveryRecord | null;\n\n if (!discovery) {\n return null;\n }\n\n const versionRegistryTopicId = discovery.t_id;\n const entries = await this.resolver.listVersionRegisters({\n versionRegistryTopicId,\n skillUid: params.skillUid,\n limit: 250,\n });\n\n const target = entries.find(entry => entry.version.trim() === versionRaw);\n if (!target) {\n return null;\n }\n\n const manifestTopicId = getManifestTopicId(target);\n const { manifest, sha256Hex } = await this.resolver.resolveManifest({\n manifestTopicId,\n });\n\n await this.resolver.verifyVersionRegisterMatchesManifest({\n versionRegister: target,\n manifestSha256Hex: sha256Hex,\n });\n\n let verification: HCS26SkillVerificationStatus | null | undefined;\n const provider = this.verificationProvider;\n const includeVerification = params.includeVerification === true;\n const name =\n typeof discovery.metadata?.name === 'string'\n ? discovery.metadata.name.trim()\n : '';\n\n if (includeVerification && provider && name) {\n try {\n verification = await provider.getSkillVerificationStatus({ name });\n } catch (error) {\n const detail = error instanceof Error ? error.message : String(error);\n this.logger.warn(\n `Failed to resolve verification status for skill \"${name}\": ${detail}`,\n );\n verification = null;\n }\n }\n\n return {\n directoryTopicId: params.directoryTopicId,\n skillUid: params.skillUid,\n discovery,\n versionRegistryTopicId,\n versionEntry: target,\n manifest,\n manifestSha256Hex: sha256Hex,\n ...(includeVerification ? { verification } : {}),\n };\n }\n}\n"],"names":[],"mappings":";;AA+DA,SAAS,mBACP,OACQ;AACR,QAAM,mBAAoB,MAA6B;AACvD,MAAI,OAAO,qBAAqB,YAAY,iBAAiB,QAAQ;AACnE,WAAO,iBAAiB,KAAA;AAAA,EAC1B;AAEA,QAAM,eAAgB,MAAsC;AAC5D,MAAI,OAAO,iBAAiB,YAAY,CAAC,aAAa,QAAQ;AAC5D,UAAM,IAAI,MAAM,sDAAsD;AAAA,EACxE;AAEA,QAAM,MAAM,aAAa,KAAA;AACzB,QAAM,SAAS;AACf,MAAI,CAAC,IAAI,WAAW,MAAM,GAAG;AAC3B,UAAM,IAAI,MAAM,yBAAyB,GAAG,EAAE;AAAA,EAChD;AACA,SAAO,IAAI,MAAM,OAAO,MAAM;AAChC;AAEO,MAAM,gBAAgB;AAAA,EAM3B,YAAY,QAA2B;AACrC,SAAK,UAAU,OAAO;AACtB,SAAK,SACH,OAAO,UACP,OAAO,YAAY;AAAA,MACjB,QAAQ;AAAA,MACR,OAAO;AAAA,IAAA,CACR;AACH,SAAK,uBAAuB,OAAO;AAEnC,SAAK,WAAW,IAAI,2BAA2B;AAAA,MAC7C,SAAS,KAAK;AAAA,MACd,QAAQ,KAAK;AAAA,MACb,YAAY,OAAO;AAAA,IAAA,CACpB;AAAA,EACH;AAAA,EAEA,MAAM,aAAa,QAKoB;AACrC,UAAM,YAAa,MAAM,KAAK,SAAS,uBAAuB;AAAA,MAC5D,kBAAkB,OAAO;AAAA,MACzB,UAAU,OAAO;AAAA,MACjB,WAAW,OAAO;AAAA,IAAA,CACnB;AAED,QAAI,CAAC,WAAW;AACd,aAAO;AAAA,IACT;AAEA,UAAM,yBAAyB,UAAU;AACzC,UAAM,gBAAgB,MAAM,KAAK,SAAS,yBAAyB;AAAA,MACjE;AAAA,MACA,UAAU,OAAO;AAAA,IAAA,CAClB;AAED,QAAI,CAAC,eAAe;AAClB,YAAM,IAAI;AAAA,QACR,6CAA6C,OAAO,QAAQ,wBAAwB,sBAAsB;AAAA,MAAA;AAAA,IAE9G;AAEA,UAAM,kBAAkB,mBAAmB,aAAa;AACxD,UAAM,EAAE,UAAU,UAAA,IAAc,MAAM,KAAK,SAAS,gBAAgB;AAAA,MAClE;AAAA,IAAA,CACD;AAED,UAAM,KAAK,SAAS,qCAAqC;AAAA,MACvD,iBAAiB;AAAA,MACjB,mBAAmB;AAAA,IAAA,CACpB;AAED,QAAI;AACJ,UAAM,WAAW,KAAK;AACtB,UAAM,sBAAsB,OAAO,wBAAwB;AAC3D,UAAM,OACJ,OAAO,UAAU,UAAU,SAAS,WAChC,UAAU,SAAS,KAAK,KAAA,IACxB;AAEN,QAAI,uBAAuB,YAAY,MAAM;AAC3C,UAAI;AACF,uBAAe,MAAM,SAAS,2BAA2B,EAAE,MAAM;AAAA,MACnE,SAAS,OAAO;AACd,cAAM,SAAS,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACpE,aAAK,OAAO;AAAA,UACV,oDAAoD,IAAI,MAAM,MAAM;AAAA,QAAA;AAEtE,uBAAe;AAAA,MACjB;AAAA,IACF;AAEA,WAAO;AAAA,MACL,kBAAkB,OAAO;AAAA,MACzB,UAAU,OAAO;AAAA,MACjB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,mBAAmB;AAAA,MACnB,GAAI,sBAAsB,EAAE,iBAAiB,CAAA;AAAA,IAAC;AAAA,EAElD;AAAA,EAEA,MAAM,kBAAkB,QAUtB;AACA,UAAM,YAAa,MAAM,KAAK,SAAS,uBAAuB;AAAA,MAC5D,kBAAkB,OAAO;AAAA,MACzB,UAAU,OAAO;AAAA,MACjB,WAAW,OAAO;AAAA,IAAA,CACnB;AAED,QAAI,CAAC,WAAW;AACd,aAAO,CAAA;AAAA,IACT;AAEA,UAAM,yBAAyB,UAAU;AACzC,WAAO,KAAK,SAAS,qBAAqB;AAAA,MACxC;AAAA,MACA,UAAU,OAAO;AAAA,MACjB,OAAO,OAAO;AAAA,IAAA,CACf;AAAA,EACH;AAAA,EAEA,MAAM,oBAAoB,QAMoB;AAC5C,UAAM,aAAa,OAAO,QAAQ,KAAA;AAClC,QAAI,CAAC,YAAY;AACf,YAAM,IAAI,MAAM,qBAAqB;AAAA,IACvC;AAEA,UAAM,YAAa,MAAM,KAAK,SAAS,uBAAuB;AAAA,MAC5D,kBAAkB,OAAO;AAAA,MACzB,UAAU,OAAO;AAAA,MACjB,WAAW,OAAO;AAAA,IAAA,CACnB;AAED,QAAI,CAAC,WAAW;AACd,aAAO;AAAA,IACT;AAEA,UAAM,yBAAyB,UAAU;AACzC,UAAM,UAAU,MAAM,KAAK,SAAS,qBAAqB;AAAA,MACvD;AAAA,MACA,UAAU,OAAO;AAAA,MACjB,OAAO;AAAA,IAAA,CACR;AAED,UAAM,SAAS,QAAQ,KAAK,CAAA,UAAS,MAAM,QAAQ,KAAA,MAAW,UAAU;AACxE,QAAI,CAAC,QAAQ;AACX,aAAO;AAAA,IACT;AAEA,UAAM,kBAAkB,mBAAmB,MAAM;AACjD,UAAM,EAAE,UAAU,UAAA,IAAc,MAAM,KAAK,SAAS,gBAAgB;AAAA,MAClE;AAAA,IAAA,CACD;AAED,UAAM,KAAK,SAAS,qCAAqC;AAAA,MACvD,iBAAiB;AAAA,MACjB,mBAAmB;AAAA,IAAA,CACpB;AAED,QAAI;AACJ,UAAM,WAAW,KAAK;AACtB,UAAM,sBAAsB,OAAO,wBAAwB;AAC3D,UAAM,OACJ,OAAO,UAAU,UAAU,SAAS,WAChC,UAAU,SAAS,KAAK,KAAA,IACxB;AAEN,QAAI,uBAAuB,YAAY,MAAM;AAC3C,UAAI;AACF,uBAAe,MAAM,SAAS,2BAA2B,EAAE,MAAM;AAAA,MACnE,SAAS,OAAO;AACd,cAAM,SAAS,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACpE,aAAK,OAAO;AAAA,UACV,oDAAoD,IAAI,MAAM,MAAM;AAAA,QAAA;AAEtE,uBAAe;AAAA,MACjB;AAAA,IACF;AAEA,WAAO;AAAA,MACL,kBAAkB,OAAO;AAAA,MACzB,UAAU,OAAO;AAAA,MACjB;AAAA,MACA;AAAA,MACA,cAAc;AAAA,MACd;AAAA,MACA,mBAAmB;AAAA,MACnB,GAAI,sBAAsB,EAAE,iBAAiB,CAAA;AAAA,IAAC;AAAA,EAElD;AACF;"}
|
|
1
|
+
{"version":3,"file":"standards-sdk.es115.js","sources":["../../src/hcs-27/base-client.ts"],"sourcesContent":["import { createHash } from 'crypto';\nimport { HederaMirrorNode } from '../services/mirror-node';\nimport { HRLResolver } from '../utils/hrl-resolver';\nimport { Logger, type ILogger } from '../utils/logger';\nimport {\n buildHCS27TopicMemo,\n buildHCS27TransactionMemo,\n parseHCS27TopicMemo,\n} from './memos';\nimport {\n emptyHCS27Root,\n hashHCS27Leaf,\n hashHCS27Node,\n leafHashHexFromEntry,\n merkleRootFromCanonicalEntries,\n merkleRootFromEntries,\n verifyConsistencyProof,\n verifyInclusionProof,\n} from './merkle';\nimport {\n hcs27CheckpointMessageSchema,\n hcs27CheckpointMetadataSchema,\n type HCS27CheckpointMessage,\n type HCS27CheckpointMetadata,\n type HCS27CheckpointRecord,\n type HCS27ClientConfig,\n type HCS27ConsistencyProof,\n type HCS27InclusionProof,\n type HCS27TopicMemo,\n type HCS27ValidatedCheckpointMessage,\n toHCS27CheckpointMessage,\n toHCS27CheckpointMetadata,\n} from './types';\n\nexport class HCS27BaseClient {\n protected readonly network: HCS27ClientConfig['network'];\n protected readonly logger: ILogger;\n protected readonly mirrorNode: HederaMirrorNode;\n private readonly hrlResolver: HRLResolver;\n private readonly cdnEndpoint?: string;\n\n constructor(config: HCS27ClientConfig) {\n this.network = config.network;\n this.logger =\n config.logger ??\n Logger.getInstance({\n module: 'HCS27Client',\n level: 'info',\n });\n this.mirrorNode = new HederaMirrorNode(\n this.network,\n this.logger,\n config.mirrorNode,\n );\n this.cdnEndpoint = config.cdnEndpoint?.trim() || undefined;\n this.hrlResolver = new HRLResolver();\n }\n\n buildTopicMemo(ttlSeconds?: number): string {\n return buildHCS27TopicMemo(ttlSeconds);\n }\n\n parseTopicMemo(memo: string): HCS27TopicMemo | undefined {\n return parseHCS27TopicMemo(memo);\n }\n\n buildTransactionMemo(): string {\n return buildHCS27TransactionMemo();\n }\n\n emptyRoot(): Buffer {\n return emptyHCS27Root();\n }\n\n /** Strings are treated as UTF-8 canonical entry bytes. */\n hashLeaf(canonicalEntry: Buffer | Uint8Array | string): Buffer {\n const entry =\n typeof canonicalEntry === 'string'\n ? Buffer.from(canonicalEntry, 'utf8')\n : Buffer.from(canonicalEntry);\n return hashHCS27Leaf(entry);\n }\n\n /** Strings are treated as hex-encoded hash bytes. */\n hashNode(\n left: Buffer | Uint8Array | string,\n right: Buffer | Uint8Array | string,\n ): Buffer {\n const leftBytes =\n typeof left === 'string' ? Buffer.from(left, 'hex') : Buffer.from(left);\n const rightBytes =\n typeof right === 'string'\n ? Buffer.from(right, 'hex')\n : Buffer.from(right);\n return hashHCS27Node(leftBytes, rightBytes);\n }\n\n merkleRootFromCanonicalEntries(\n entries: ReadonlyArray<Buffer | Uint8Array | string>,\n ): Buffer {\n const canonicalEntries = entries.map(entry =>\n typeof entry === 'string'\n ? Buffer.from(entry, 'utf8')\n : Buffer.from(entry),\n );\n return merkleRootFromCanonicalEntries(canonicalEntries);\n }\n\n merkleRootFromEntries(entries: ReadonlyArray<unknown>): Buffer {\n return merkleRootFromEntries(entries);\n }\n\n leafHashHexFromEntry(entry: unknown): string {\n return leafHashHexFromEntry(entry);\n }\n\n verifyInclusionProof(\n proof:\n | HCS27InclusionProof\n | {\n leafIndex: number;\n treeSize: number;\n leafHashHex: string;\n path: string[];\n expectedRootB64: string;\n },\n ): boolean {\n return verifyInclusionProof(proof);\n }\n\n verifyConsistencyProof(\n proof:\n | HCS27ConsistencyProof\n | {\n oldTreeSize: number;\n newTreeSize: number;\n oldRootB64: string;\n newRootB64: string;\n consistencyPath: string[];\n },\n ): boolean {\n return verifyConsistencyProof(proof);\n }\n\n async validateCheckpointMessage(\n message: HCS27CheckpointMessage | HCS27ValidatedCheckpointMessage,\n resolver?: (reference: string) => Promise<Buffer>,\n inlineMetadataDigestSource?: Buffer,\n ): Promise<HCS27CheckpointMetadata> {\n const originalInlineMetadataBytes =\n inlineMetadataDigestSource ??\n (typeof message.metadata === 'string'\n ? undefined\n : Buffer.from(JSON.stringify(message.metadata), 'utf8'));\n const parsedMessage = hcs27CheckpointMessageSchema.parse(message);\n const effectiveResolver =\n resolver ?? (reference => this.resolveHCS1Reference(reference));\n\n let metadataBytes: Buffer | undefined;\n let metadata: HCS27CheckpointMetadata;\n\n if (typeof parsedMessage.metadata === 'string') {\n metadataBytes = await effectiveResolver(parsedMessage.metadata);\n metadata = toHCS27CheckpointMetadata(\n hcs27CheckpointMetadataSchema.parse(\n JSON.parse(metadataBytes.toString('utf8')),\n ),\n );\n } else {\n metadata = toHCS27CheckpointMetadata(\n hcs27CheckpointMetadataSchema.parse(parsedMessage.metadata),\n );\n }\n\n if (parsedMessage.metadata_digest) {\n const digestBytes =\n metadataBytes ??\n originalInlineMetadataBytes ??\n Buffer.from(JSON.stringify(parsedMessage.metadata), 'utf8');\n const digest = createHash('sha256')\n .update(digestBytes)\n .digest('base64url');\n if (digest !== parsedMessage.metadata_digest.b64u) {\n throw new Error('metadata digest does not match resolved payload');\n }\n }\n\n return metadata;\n }\n\n validateCheckpointChain(records: ReadonlyArray<HCS27CheckpointRecord>): void {\n const streams = new Map<\n string,\n Map<string, { treeSize: bigint; rootHashB64u: string }>\n >();\n\n for (const record of records) {\n const streamRegistry = record.effectiveMetadata.stream.registry;\n const streamLogId = record.effectiveMetadata.stream.log_id;\n let registryStreams = streams.get(streamRegistry);\n if (!registryStreams) {\n registryStreams = new Map<\n string,\n { treeSize: bigint; rootHashB64u: string }\n >();\n streams.set(streamRegistry, registryStreams);\n }\n const streamLabel = JSON.stringify({\n registry: streamRegistry,\n log_id: streamLogId,\n });\n const currentTreeSize = BigInt(record.effectiveMetadata.root.treeSize);\n const previous = registryStreams.get(streamLogId);\n\n if (previous) {\n if (currentTreeSize < previous.treeSize) {\n throw new Error(`tree size decreased for stream ${streamLabel}`);\n }\n if (\n currentTreeSize === previous.treeSize &&\n record.effectiveMetadata.root.rootHashB64u !== previous.rootHashB64u\n ) {\n throw new Error(\n `root changed without growing tree size for stream ${streamLabel}`,\n );\n }\n if (!record.effectiveMetadata.prev) {\n throw new Error(`missing prev linkage for stream ${streamLabel}`);\n }\n const previousTreeSize = BigInt(record.effectiveMetadata.prev.treeSize);\n if (previousTreeSize !== previous.treeSize) {\n throw new Error(`prev.treeSize mismatch for stream ${streamLabel}`);\n }\n if (\n record.effectiveMetadata.prev.rootHashB64u !== previous.rootHashB64u\n ) {\n throw new Error(\n `prev.rootHashB64u mismatch for stream ${streamLabel}`,\n );\n }\n }\n\n registryStreams.set(streamLogId, {\n treeSize: currentTreeSize,\n rootHashB64u: record.effectiveMetadata.root.rootHashB64u,\n });\n }\n }\n\n async getCheckpoints(topicId: string): Promise<HCS27CheckpointRecord[]> {\n const messages = await this.mirrorNode.getTopicMessages(topicId, {\n order: 'asc',\n });\n const records: HCS27CheckpointRecord[] = [];\n\n for (const item of messages) {\n try {\n const parsedMessage = hcs27CheckpointMessageSchema.parse({\n p: item.p,\n op: item.op,\n metadata: item.metadata,\n metadata_digest: item.metadata_digest,\n m: item.m,\n });\n const rawInlineMetadataDigestSource =\n typeof item.metadata === 'string'\n ? undefined\n : Buffer.from(JSON.stringify(item.metadata), 'utf8');\n\n const effectiveMetadata = await this.validateCheckpointMessage(\n parsedMessage,\n undefined,\n rawInlineMetadataDigestSource,\n );\n const message = toHCS27CheckpointMessage(parsedMessage);\n records.push({\n topicId,\n sequence: item.sequence_number,\n consensusTimestamp: item.consensus_timestamp ?? '',\n payer:\n typeof item.payer_account_id === 'string'\n ? item.payer_account_id\n : item.payer,\n message,\n effectiveMetadata,\n });\n } catch (error) {\n const detail = error instanceof Error ? error.message : String(error);\n this.logger.warn(\n `Skipping invalid HCS-27 checkpoint message: ${detail}`,\n );\n }\n }\n\n return records;\n }\n\n async resolveHCS1Reference(reference: string): Promise<Buffer> {\n const trimmed = reference.trim();\n if (!/^hcs:\\/\\/1\\/\\d+\\.\\d+\\.\\d+$/.test(trimmed)) {\n throw new Error(`Invalid HCS-1 reference: ${reference}`);\n }\n\n const resolved = await this.hrlResolver.resolveHRL(trimmed, {\n network: this.network,\n cdnEndpoint: this.cdnEndpoint,\n returnRaw: true,\n });\n if (typeof resolved.content === 'string') {\n return Buffer.from(resolved.content, 'utf8');\n }\n return Buffer.from(resolved.content);\n }\n}\n"],"names":[],"mappings":"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"}
|