@freedomofpress/ics23 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/Readme.md +3 -0
  2. package/dist/.gitkeep +0 -0
  3. package/dist/compress.d.ts +3 -0
  4. package/dist/compress.js +96 -0
  5. package/dist/compress.js.map +1 -0
  6. package/dist/ics23.d.ts +18 -0
  7. package/dist/ics23.js +118 -0
  8. package/dist/ics23.js.map +1 -0
  9. package/dist/index.d.ts +3 -0
  10. package/dist/index.js +4 -0
  11. package/dist/index.js.map +1 -0
  12. package/dist/ops.d.ts +4 -0
  13. package/dist/ops.js +111 -0
  14. package/dist/ops.js.map +1 -0
  15. package/dist/proofs.d.ts +11 -0
  16. package/dist/proofs.js +235 -0
  17. package/dist/proofs.js.map +1 -0
  18. package/dist/proto/cosmos/ics23/v1/proofs.d.ts +264 -0
  19. package/dist/proto/cosmos/ics23/v1/proofs.js +1411 -0
  20. package/dist/proto/cosmos/ics23/v1/proofs.js.map +1 -0
  21. package/dist/specs.d.ts +7 -0
  22. package/dist/specs.js +105 -0
  23. package/dist/specs.js.map +1 -0
  24. package/dist/tests/ops.test.d.ts +1 -0
  25. package/dist/tests/ops.test.js +143 -0
  26. package/dist/tests/ops.test.js.map +1 -0
  27. package/dist/tests/proofs.test.d.ts +1 -0
  28. package/dist/tests/proofs.test.js +194 -0
  29. package/dist/tests/proofs.test.js.map +1 -0
  30. package/dist/tests/testhelpers.d.ts +3 -0
  31. package/dist/tests/testhelpers.js +35 -0
  32. package/dist/tests/testhelpers.js.map +1 -0
  33. package/dist/tests/testvectors.test.d.ts +1 -0
  34. package/dist/tests/testvectors.test.js +229 -0
  35. package/dist/tests/testvectors.test.js.map +1 -0
  36. package/dist/tests/webcat.test.d.ts +1 -0
  37. package/dist/tests/webcat.test.js +45 -0
  38. package/dist/tests/webcat.test.js.map +1 -0
  39. package/dist/webcat.d.ts +15 -0
  40. package/dist/webcat.js +77 -0
  41. package/dist/webcat.js.map +1 -0
  42. package/package.json +46 -0
@@ -0,0 +1,35 @@
1
+ export function fromHex(hexstring) {
2
+ if (hexstring.length % 2 !== 0) {
3
+ throw new Error("hex string length must be a multiple of 2");
4
+ }
5
+ const listOfInts = [];
6
+ for (let i = 0; i < hexstring.length; i += 2) {
7
+ const hexByteAsString = hexstring.substr(i, 2);
8
+ if (!hexByteAsString.match(/[0-9a-f]{2}/i)) {
9
+ throw new Error("hex string contains invalid characters");
10
+ }
11
+ listOfInts.push(parseInt(hexByteAsString, 16));
12
+ }
13
+ return new Uint8Array(listOfInts);
14
+ }
15
+ export function toAscii(input) {
16
+ const toNums = (str) => str.split("").map((x) => {
17
+ const charCode = x.charCodeAt(0);
18
+ // 0x00–0x1F control characters
19
+ // 0x20–0x7E printable characters
20
+ // 0x7F delete character
21
+ // 0x80–0xFF out of 7 bit ascii range
22
+ if (charCode < 0x20 || charCode > 0x7e) {
23
+ throw new Error("Cannot encode character that is out of printable ASCII range: " +
24
+ charCode);
25
+ }
26
+ return charCode;
27
+ });
28
+ return Uint8Array.from(toNums(input));
29
+ }
30
+ export function toHex(bytes) {
31
+ return Array.from(bytes)
32
+ .map((byte) => byte.toString(16).padStart(2, "0"))
33
+ .join("");
34
+ }
35
+ //# sourceMappingURL=testhelpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"testhelpers.js","sourceRoot":"","sources":["../../src/tests/testhelpers.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,OAAO,CAAC,SAAiB;IACvC,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;QAC/B,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAC;IAC/D,CAAC;IAED,MAAM,UAAU,GAAa,EAAE,CAAC;IAChC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QAC7C,MAAM,eAAe,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QAC/C,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,cAAc,CAAC,EAAE,CAAC;YAC3C,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAC;QAC5D,CAAC;QACD,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,eAAe,EAAE,EAAE,CAAC,CAAC,CAAC;IACjD,CAAC;IACD,OAAO,IAAI,UAAU,CAAC,UAAU,CAAC,CAAC;AACpC,CAAC;AAED,MAAM,UAAU,OAAO,CAAC,KAAa;IACnC,MAAM,MAAM,GAAG,CAAC,GAAW,EAAY,EAAE,CACvC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAS,EAAE,EAAE;QAC9B,MAAM,QAAQ,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;QACjC,+BAA+B;QAC/B,iCAAiC;QACjC,wBAAwB;QACxB,qCAAqC;QACrC,IAAI,QAAQ,GAAG,IAAI,IAAI,QAAQ,GAAG,IAAI,EAAE,CAAC;YACvC,MAAM,IAAI,KAAK,CACb,gEAAgE;gBAC9D,QAAQ,CACX,CAAC;QACJ,CAAC;QACD,OAAO,QAAQ,CAAC;IAClB,CAAC,CAAC,CAAC;IACL,OAAO,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;AACxC,CAAC;AAED,MAAM,UAAU,KAAK,CAAC,KAAiB;IACrC,OAAO,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC;SACrB,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;SACjD,IAAI,CAAC,EAAE,CAAC,CAAC;AACd,CAAC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,229 @@
1
+ import iavlExistLeft from "../../testdata/iavl/exist_left.json";
2
+ import iavlExistMiddle from "../../testdata/iavl/exist_middle.json";
3
+ import iavlExistRight from "../../testdata/iavl/exist_right.json";
4
+ import iavlNonexistLeft from "../../testdata/iavl/nonexist_left.json";
5
+ import iavlNonexistMiddle from "../../testdata/iavl/nonexist_middle.json";
6
+ import iavlNonexistRight from "../../testdata/iavl/nonexist_right.json";
7
+ import smtExistLeft from "../../testdata/smt/exist_left.json";
8
+ import smtExistMiddle from "../../testdata/smt/exist_middle.json";
9
+ import smtExistRight from "../../testdata/smt/exist_right.json";
10
+ import smtNonexistLeft from "../../testdata/smt/nonexist_left.json";
11
+ import smtNonexistMiddle from "../../testdata/smt/nonexist_middle.json";
12
+ import smtNonexistRight from "../../testdata/smt/nonexist_right.json";
13
+ import tendermintExistLeft from "../../testdata/tendermint/exist_left.json";
14
+ import tendermintExistMiddle from "../../testdata/tendermint/exist_middle.json";
15
+ import tendermintExistRight from "../../testdata/tendermint/exist_right.json";
16
+ import tendermintNonexistLeft from "../../testdata/tendermint/nonexist_left.json";
17
+ import tendermintNonexistMiddle from "../../testdata/tendermint/nonexist_middle.json";
18
+ import tendermintNonexistRight from "../../testdata/tendermint/nonexist_right.json";
19
+ import { compress } from "./../compress";
20
+ import { batchVerifyMembership, batchVerifyNonMembership, verifyMembership, verifyNonMembership, } from "./../ics23";
21
+ import { iavlSpec, smtSpec, tendermintSpec } from "./../proofs";
22
+ import { fromHex } from "./testhelpers";
23
+ import { describe, it, expect } from "vitest";
24
+ import { CommitmentProof, } from "./../proto/cosmos/ics23/v1/proofs";
25
+ describe("calculateExistenceRoot", () => {
26
+ function loadVector(vector) {
27
+ const { root, proof, key, value } = vector;
28
+ expect(proof).toBeDefined();
29
+ expect(root).toBeDefined();
30
+ expect(key).toBeDefined();
31
+ const commit = CommitmentProof.decode(fromHex(proof));
32
+ const data = {
33
+ root: fromHex(root),
34
+ key: fromHex(key),
35
+ value: value ? fromHex(value) : undefined,
36
+ };
37
+ return { proof: commit, data };
38
+ }
39
+ async function validateTestVector(vector, spec) {
40
+ const { proof, data: { root, key, value }, } = loadVector(vector);
41
+ if (value) {
42
+ const valid = await verifyMembership(proof, spec, root, key, value);
43
+ expect(valid).toBe(true);
44
+ }
45
+ else {
46
+ const valid = await verifyNonMembership(proof, spec, root, key);
47
+ expect(valid).toBe(true);
48
+ }
49
+ }
50
+ it("should parse iavl left", async () => {
51
+ await validateTestVector(iavlExistLeft, iavlSpec);
52
+ });
53
+ it("should parse iavl right", async () => {
54
+ await validateTestVector(iavlExistRight, iavlSpec);
55
+ });
56
+ it("should parse iavl middle", async () => {
57
+ await validateTestVector(iavlExistMiddle, iavlSpec);
58
+ });
59
+ it("should parse iavl left - nonexist", async () => {
60
+ await validateTestVector(iavlNonexistLeft, iavlSpec);
61
+ });
62
+ it("should parse iavl right - nonexist", async () => {
63
+ await validateTestVector(iavlNonexistRight, iavlSpec);
64
+ });
65
+ it("should parse iavl middle - nonexist", async () => {
66
+ await validateTestVector(iavlNonexistMiddle, iavlSpec);
67
+ });
68
+ it("should parse tendermint left", async () => {
69
+ await validateTestVector(tendermintExistLeft, tendermintSpec);
70
+ });
71
+ it("should parse tendermint right", async () => {
72
+ await validateTestVector(tendermintExistRight, tendermintSpec);
73
+ });
74
+ it("should parse tendermint middle", async () => {
75
+ await validateTestVector(tendermintExistMiddle, tendermintSpec);
76
+ });
77
+ it("should parse tendermint left - nonexist", async () => {
78
+ await validateTestVector(tendermintNonexistLeft, tendermintSpec);
79
+ });
80
+ it("should parse tendermint right - nonexist", async () => {
81
+ await validateTestVector(tendermintNonexistRight, tendermintSpec);
82
+ });
83
+ it("should parse tendermint middle - nonexist", async () => {
84
+ await validateTestVector(tendermintNonexistMiddle, tendermintSpec);
85
+ });
86
+ function loadBatch(vectors) {
87
+ let refs = [];
88
+ let entries = [];
89
+ for (const vector of vectors) {
90
+ const { proof, data } = loadVector(vector);
91
+ refs = [...refs, data];
92
+ if (proof.exist) {
93
+ entries = [...entries, { exist: proof.exist }];
94
+ }
95
+ else if (proof.nonexist) {
96
+ entries = [...entries, { nonexist: proof.nonexist }];
97
+ }
98
+ }
99
+ const commit = {
100
+ batch: {
101
+ entries: entries,
102
+ },
103
+ };
104
+ return {
105
+ proof: commit,
106
+ data: refs,
107
+ };
108
+ }
109
+ async function validateBatch(proof, spec, data) {
110
+ const { root, key, value } = data;
111
+ if (value) {
112
+ let valid = await verifyMembership(proof, spec, root, key, value);
113
+ expect(valid).toBe(true);
114
+ const items = new Map([[key, value]]);
115
+ valid = await batchVerifyMembership(proof, spec, root, items);
116
+ expect(valid).toBe(true);
117
+ }
118
+ else {
119
+ let valid = await verifyNonMembership(proof, spec, root, key);
120
+ expect(valid).toBe(true);
121
+ const keys = [key];
122
+ valid = await batchVerifyNonMembership(proof, spec, root, keys);
123
+ expect(valid).toBe(true);
124
+ }
125
+ }
126
+ it("should validate iavl batch exist", async () => {
127
+ const { proof, data } = loadBatch([
128
+ iavlExistLeft,
129
+ iavlExistRight,
130
+ iavlExistMiddle,
131
+ iavlNonexistLeft,
132
+ iavlNonexistRight,
133
+ iavlNonexistMiddle,
134
+ ]);
135
+ await validateBatch(proof, iavlSpec, data[0]);
136
+ });
137
+ it("should validate iavl batch nonexist", async () => {
138
+ const { proof, data } = loadBatch([
139
+ iavlExistLeft,
140
+ iavlExistRight,
141
+ iavlExistMiddle,
142
+ iavlNonexistLeft,
143
+ iavlNonexistRight,
144
+ iavlNonexistMiddle,
145
+ ]);
146
+ await validateBatch(proof, iavlSpec, data[5]);
147
+ });
148
+ it("should validate compressed iavl batch exist", async () => {
149
+ const { proof, data } = loadBatch([
150
+ iavlExistLeft,
151
+ iavlExistRight,
152
+ iavlExistMiddle,
153
+ iavlNonexistLeft,
154
+ iavlNonexistRight,
155
+ iavlNonexistMiddle,
156
+ ]);
157
+ const small = compress(proof);
158
+ // ensure this is actually a different format
159
+ const origBin = CommitmentProof.encode(proof).finish();
160
+ const origBin2 = CommitmentProof.encode(proof).finish();
161
+ const smallBin = CommitmentProof.encode(small).finish();
162
+ expect(origBin).toEqual(origBin2);
163
+ expect(origBin).not.toEqual(smallBin);
164
+ await validateBatch(small, iavlSpec, data[0]);
165
+ });
166
+ it("should validate compressed iavl batch nonexist", async () => {
167
+ const { proof, data } = loadBatch([
168
+ iavlExistLeft,
169
+ iavlExistRight,
170
+ iavlExistMiddle,
171
+ iavlNonexistLeft,
172
+ iavlNonexistRight,
173
+ iavlNonexistMiddle,
174
+ ]);
175
+ const small = compress(proof);
176
+ // ensure this is actually a different format
177
+ const origBin = CommitmentProof.encode(proof).finish();
178
+ const origBin2 = CommitmentProof.encode(proof).finish();
179
+ const smallBin = CommitmentProof.encode(small).finish();
180
+ expect(origBin).toEqual(origBin2);
181
+ expect(origBin).not.toEqual(smallBin);
182
+ await validateBatch(small, iavlSpec, data[5]);
183
+ });
184
+ it("should validate tendermint batch exist", async () => {
185
+ const { proof, data } = loadBatch([
186
+ tendermintExistLeft,
187
+ tendermintExistRight,
188
+ tendermintExistMiddle,
189
+ tendermintNonexistLeft,
190
+ tendermintNonexistRight,
191
+ tendermintNonexistMiddle,
192
+ ]);
193
+ await validateBatch(proof, tendermintSpec, data[2]);
194
+ });
195
+ it("should validate tendermint batch nonexist", async () => {
196
+ const { proof, data } = loadBatch([
197
+ tendermintExistLeft,
198
+ tendermintExistRight,
199
+ tendermintExistMiddle,
200
+ tendermintNonexistLeft,
201
+ tendermintNonexistRight,
202
+ tendermintNonexistMiddle,
203
+ ]);
204
+ await validateBatch(proof, tendermintSpec, data[3]);
205
+ });
206
+ it("should validate smt batch exist", async () => {
207
+ const { proof, data } = loadBatch([
208
+ smtExistLeft,
209
+ smtExistRight,
210
+ smtExistMiddle,
211
+ smtNonexistLeft,
212
+ smtNonexistRight,
213
+ smtNonexistMiddle,
214
+ ]);
215
+ await validateBatch(proof, smtSpec, data[2]);
216
+ });
217
+ it("should validate smt batch nonexist", async () => {
218
+ const { proof, data } = loadBatch([
219
+ smtExistLeft,
220
+ smtExistRight,
221
+ smtExistMiddle,
222
+ smtNonexistLeft,
223
+ smtNonexistRight,
224
+ smtNonexistMiddle,
225
+ ]);
226
+ await validateBatch(proof, smtSpec, data[3]);
227
+ });
228
+ });
229
+ //# sourceMappingURL=testvectors.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"testvectors.test.js","sourceRoot":"","sources":["../../src/tests/testvectors.test.ts"],"names":[],"mappings":"AAAA,OAAO,aAAa,MAAM,qCAAqC,CAAC;AAChE,OAAO,eAAe,MAAM,uCAAuC,CAAC;AACpE,OAAO,cAAc,MAAM,sCAAsC,CAAC;AAClE,OAAO,gBAAgB,MAAM,wCAAwC,CAAC;AACtE,OAAO,kBAAkB,MAAM,0CAA0C,CAAC;AAC1E,OAAO,iBAAiB,MAAM,yCAAyC,CAAC;AACxE,OAAO,YAAY,MAAM,oCAAoC,CAAC;AAC9D,OAAO,cAAc,MAAM,sCAAsC,CAAC;AAClE,OAAO,aAAa,MAAM,qCAAqC,CAAC;AAChE,OAAO,eAAe,MAAM,uCAAuC,CAAC;AACpE,OAAO,iBAAiB,MAAM,yCAAyC,CAAC;AACxE,OAAO,gBAAgB,MAAM,wCAAwC,CAAC;AACtE,OAAO,mBAAmB,MAAM,2CAA2C,CAAC;AAC5E,OAAO,qBAAqB,MAAM,6CAA6C,CAAC;AAChF,OAAO,oBAAoB,MAAM,4CAA4C,CAAC;AAC9E,OAAO,sBAAsB,MAAM,8CAA8C,CAAC;AAClF,OAAO,wBAAwB,MAAM,gDAAgD,CAAC;AACtF,OAAO,uBAAuB,MAAM,+CAA+C,CAAC;AAEpF,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EACL,qBAAqB,EACrB,wBAAwB,EACxB,gBAAgB,EAChB,mBAAmB,GACpB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAChE,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAExC,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAEL,eAAe,GAEhB,MAAM,mCAAmC,CAAC;AAE3C,QAAQ,CAAC,wBAAwB,EAAE,GAAG,EAAE;IAmBtC,SAAS,UAAU,CAAC,MAAsB;QACxC,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,MAAM,CAAC;QAC3C,MAAM,CAAC,KAAK,CAAC,CAAC,WAAW,EAAE,CAAC;QAC5B,MAAM,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC;QAC3B,MAAM,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC;QAE1B,MAAM,MAAM,GAAG,eAAe,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;QAEtD,MAAM,IAAI,GAAG;YACX,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC;YACnB,GAAG,EAAE,OAAO,CAAC,GAAG,CAAC;YACjB,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS;SAC1C,CAAC;QAEF,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;IACjC,CAAC;IAOD,KAAK,UAAU,kBAAkB,CAC/B,MAAsB,EACtB,IAAe;QAEf,MAAM,EACJ,KAAK,EACL,IAAI,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,GAC3B,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC;QACvB,IAAI,KAAK,EAAE,CAAC;YACV,MAAM,KAAK,GAAG,MAAM,gBAAgB,CAAC,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC;YACpE,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC3B,CAAC;aAAM,CAAC;YACN,MAAM,KAAK,GAAG,MAAM,mBAAmB,CAAC,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC;YAChE,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC3B,CAAC;IACH,CAAC;IAED,EAAE,CAAC,wBAAwB,EAAE,KAAK,IAAI,EAAE;QACtC,MAAM,kBAAkB,CAAC,aAAa,EAAE,QAAQ,CAAC,CAAC;IACpD,CAAC,CAAC,CAAC;IACH,EAAE,CAAC,yBAAyB,EAAE,KAAK,IAAI,EAAE;QACvC,MAAM,kBAAkB,CAAC,cAAc,EAAE,QAAQ,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;IACH,EAAE,CAAC,0BAA0B,EAAE,KAAK,IAAI,EAAE;QACxC,MAAM,kBAAkB,CAAC,eAAe,EAAE,QAAQ,CAAC,CAAC;IACtD,CAAC,CAAC,CAAC;IACH,EAAE,CAAC,mCAAmC,EAAE,KAAK,IAAI,EAAE;QACjD,MAAM,kBAAkB,CAAC,gBAAgB,EAAE,QAAQ,CAAC,CAAC;IACvD,CAAC,CAAC,CAAC;IACH,EAAE,CAAC,oCAAoC,EAAE,KAAK,IAAI,EAAE;QAClD,MAAM,kBAAkB,CAAC,iBAAiB,EAAE,QAAQ,CAAC,CAAC;IACxD,CAAC,CAAC,CAAC;IACH,EAAE,CAAC,qCAAqC,EAAE,KAAK,IAAI,EAAE;QACnD,MAAM,kBAAkB,CAAC,kBAAkB,EAAE,QAAQ,CAAC,CAAC;IACzD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8BAA8B,EAAE,KAAK,IAAI,EAAE;QAC5C,MAAM,kBAAkB,CAAC,mBAAmB,EAAE,cAAc,CAAC,CAAC;IAChE,CAAC,CAAC,CAAC;IACH,EAAE,CAAC,+BAA+B,EAAE,KAAK,IAAI,EAAE;QAC7C,MAAM,kBAAkB,CAAC,oBAAoB,EAAE,cAAc,CAAC,CAAC;IACjE,CAAC,CAAC,CAAC;IACH,EAAE,CAAC,gCAAgC,EAAE,KAAK,IAAI,EAAE;QAC9C,MAAM,kBAAkB,CAAC,qBAAqB,EAAE,cAAc,CAAC,CAAC;IAClE,CAAC,CAAC,CAAC;IACH,EAAE,CAAC,yCAAyC,EAAE,KAAK,IAAI,EAAE;QACvD,MAAM,kBAAkB,CAAC,sBAAsB,EAAE,cAAc,CAAC,CAAC;IACnE,CAAC,CAAC,CAAC;IACH,EAAE,CAAC,0CAA0C,EAAE,KAAK,IAAI,EAAE;QACxD,MAAM,kBAAkB,CAAC,uBAAuB,EAAE,cAAc,CAAC,CAAC;IACpE,CAAC,CAAC,CAAC;IACH,EAAE,CAAC,2CAA2C,EAAE,KAAK,IAAI,EAAE;QACzD,MAAM,kBAAkB,CAAC,wBAAwB,EAAE,cAAc,CAAC,CAAC;IACrE,CAAC,CAAC,CAAC;IAEH,SAAS,SAAS,CAAC,OAAkC;QACnD,IAAI,IAAI,GAAuB,EAAE,CAAC;QAClC,IAAI,OAAO,GAA0B,EAAE,CAAC;QAExC,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;YAC7B,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC;YAC3C,IAAI,GAAG,CAAC,GAAG,IAAI,EAAE,IAAI,CAAC,CAAC;YACvB,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;gBAChB,OAAO,GAAG,CAAC,GAAG,OAAO,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC;YACjD,CAAC;iBAAM,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;gBAC1B,OAAO,GAAG,CAAC,GAAG,OAAO,EAAE,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;YACvD,CAAC;QACH,CAAC;QACD,MAAM,MAAM,GAAoB;YAC9B,KAAK,EAAE;gBACL,OAAO,EAAE,OAAuB;aACjC;SACF,CAAC;QAEF,OAAO;YACL,KAAK,EAAE,MAAM;YACb,IAAI,EAAE,IAAI;SACX,CAAC;IACJ,CAAC;IAED,KAAK,UAAU,aAAa,CAC1B,KAAsB,EACtB,IAAe,EACf,IAAa;QAEb,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC;QAClC,IAAI,KAAK,EAAE,CAAC;YACV,IAAI,KAAK,GAAG,MAAM,gBAAgB,CAAC,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC;YAClE,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACzB,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;YACtC,KAAK,GAAG,MAAM,qBAAqB,CAAC,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;YAC9D,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC3B,CAAC;aAAM,CAAC;YACN,IAAI,KAAK,GAAG,MAAM,mBAAmB,CAAC,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC;YAC9D,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACzB,MAAM,IAAI,GAA0B,CAAC,GAAG,CAAC,CAAC;YAC1C,KAAK,GAAG,MAAM,wBAAwB,CAAC,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;YAChE,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC3B,CAAC;IACH,CAAC;IAED,EAAE,CAAC,kCAAkC,EAAE,KAAK,IAAI,EAAE;QAChD,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,SAAS,CAAC;YAChC,aAAa;YACb,cAAc;YACd,eAAe;YACf,gBAAgB;YAChB,iBAAiB;YACjB,kBAAkB;SACnB,CAAC,CAAC;QACH,MAAM,aAAa,CAAC,KAAK,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IAChD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qCAAqC,EAAE,KAAK,IAAI,EAAE;QACnD,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,SAAS,CAAC;YAChC,aAAa;YACb,cAAc;YACd,eAAe;YACf,gBAAgB;YAChB,iBAAiB;YACjB,kBAAkB;SACnB,CAAC,CAAC;QACH,MAAM,aAAa,CAAC,KAAK,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IAChD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6CAA6C,EAAE,KAAK,IAAI,EAAE;QAC3D,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,SAAS,CAAC;YAChC,aAAa;YACb,cAAc;YACd,eAAe;YACf,gBAAgB;YAChB,iBAAiB;YACjB,kBAAkB;SACnB,CAAC,CAAC;QACH,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;QAE9B,6CAA6C;QAC7C,MAAM,OAAO,GAAG,eAAe,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,EAAE,CAAC;QACvD,MAAM,QAAQ,GAAG,eAAe,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,EAAE,CAAC;QACxD,MAAM,QAAQ,GAAG,eAAe,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,EAAE,CAAC;QACxD,MAAM,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QAClC,MAAM,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QAEtC,MAAM,aAAa,CAAC,KAAK,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IAChD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gDAAgD,EAAE,KAAK,IAAI,EAAE;QAC9D,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,SAAS,CAAC;YAChC,aAAa;YACb,cAAc;YACd,eAAe;YACf,gBAAgB;YAChB,iBAAiB;YACjB,kBAAkB;SACnB,CAAC,CAAC;QACH,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;QAE9B,6CAA6C;QAC7C,MAAM,OAAO,GAAG,eAAe,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,EAAE,CAAC;QACvD,MAAM,QAAQ,GAAG,eAAe,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,EAAE,CAAC;QACxD,MAAM,QAAQ,GAAG,eAAe,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,EAAE,CAAC;QACxD,MAAM,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QAClC,MAAM,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QAEtC,MAAM,aAAa,CAAC,KAAK,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IAChD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wCAAwC,EAAE,KAAK,IAAI,EAAE;QACtD,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,SAAS,CAAC;YAChC,mBAAmB;YACnB,oBAAoB;YACpB,qBAAqB;YACrB,sBAAsB;YACtB,uBAAuB;YACvB,wBAAwB;SACzB,CAAC,CAAC;QACH,MAAM,aAAa,CAAC,KAAK,EAAE,cAAc,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IACtD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2CAA2C,EAAE,KAAK,IAAI,EAAE;QACzD,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,SAAS,CAAC;YAChC,mBAAmB;YACnB,oBAAoB;YACpB,qBAAqB;YACrB,sBAAsB;YACtB,uBAAuB;YACvB,wBAAwB;SACzB,CAAC,CAAC;QACH,MAAM,aAAa,CAAC,KAAK,EAAE,cAAc,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IACtD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iCAAiC,EAAE,KAAK,IAAI,EAAE;QAC/C,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,SAAS,CAAC;YAChC,YAAY;YACZ,aAAa;YACb,cAAc;YACd,eAAe;YACf,gBAAgB;YAChB,iBAAiB;SAClB,CAAC,CAAC;QACH,MAAM,aAAa,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oCAAoC,EAAE,KAAK,IAAI,EAAE;QAClD,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,SAAS,CAAC;YAChC,YAAY;YACZ,aAAa;YACb,cAAc;YACd,eAAe;YACf,gBAAgB;YAChB,iBAAiB;SAClB,CAAC,CAAC;QACH,MAAM,aAAa,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,45 @@
1
+ import leavesData from "../../testdata/webcat/leaves.json";
2
+ import { describe, expect, it } from "vitest";
3
+ import { calculateExistenceRoot, verifyExistence } from "../proofs";
4
+ import { verifyWebcatProof, webcatSpec } from "../webcat";
5
+ import { CommitmentProof } from "../proto/cosmos/ics23/v1/proofs";
6
+ import { fromHex, toHex } from "./testhelpers";
7
+ describe("verifyWebcatProof", () => {
8
+ it("verifies the provided leaf and canonical linkage", async () => {
9
+ const [elementBytes, canonicalBytes] = leavesData.proof.merkle_proof.proof_bytes;
10
+ const elementProof = CommitmentProof.decode(fromHex(elementBytes));
11
+ const canonicalProof = CommitmentProof.decode(fromHex(canonicalBytes));
12
+ const elementRoot = await calculateExistenceRoot(elementProof.exist);
13
+ const canonicalRoot = await calculateExistenceRoot(canonicalProof.exist);
14
+ const elementKey = new TextEncoder().encode(leavesData.proof.merkle_proof.representative_key.replace(/^canonical\//, ""));
15
+ const elementValue = fromHex(leavesData.leaves[1][1]);
16
+ expect(elementProof.exist?.key).toEqual(elementKey);
17
+ await expect(verifyExistence(elementProof.exist, webcatSpec, fromHex(leavesData.proof.canonical_root_hash), elementKey, elementValue)).resolves.not.toThrow();
18
+ await expect(verifyExistence(canonicalProof.exist, webcatSpec, fromHex(leavesData.proof.app_hash), new TextEncoder().encode("canonical"), fromHex(leavesData.proof.canonical_root_hash))).resolves.not.toThrow();
19
+ expect(toHex(elementRoot)).toBe(leavesData.proof.canonical_root_hash);
20
+ expect(toHex(canonicalRoot)).toBe(leavesData.proof.app_hash);
21
+ await expect(verifyWebcatProof(leavesData)).resolves.toBe(true);
22
+ });
23
+ it("fails when app hash linkage is modified", async () => {
24
+ const tampered = {
25
+ ...leavesData,
26
+ proof: {
27
+ ...leavesData.proof,
28
+ app_hash: "00" + leavesData.proof.app_hash.slice(2),
29
+ },
30
+ };
31
+ await expect(verifyWebcatProof(tampered)).resolves.toBe(false);
32
+ });
33
+ it("exposes the webcat spec for manual validation", async () => {
34
+ const proofBytes = leavesData.proof.merkle_proof.proof_bytes[0];
35
+ const proof = CommitmentProof.decode(fromHex(proofBytes));
36
+ const validation = await verifyWebcatProof({
37
+ ...leavesData,
38
+ proof: leavesData.proof,
39
+ });
40
+ expect(validation).toBe(true);
41
+ expect(webcatSpec.leafSpec?.prefix?.length).toBe(13);
42
+ expect(proof.exist?.leaf?.prefix).toEqual(webcatSpec.leafSpec?.prefix);
43
+ });
44
+ });
45
+ //# sourceMappingURL=webcat.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webcat.test.js","sourceRoot":"","sources":["../../src/tests/webcat.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import { ProofSpec } from "./proto/cosmos/ics23/v1/proofs";
2
+ export interface WebcatLeavesFile {
3
+ readonly block_height: number;
4
+ readonly leaves: readonly (readonly [string, string] | readonly string[])[];
5
+ readonly proof: {
6
+ readonly app_hash: string;
7
+ readonly canonical_root_hash: string;
8
+ readonly merkle_proof: {
9
+ readonly proof_bytes: readonly string[];
10
+ readonly representative_key: string;
11
+ };
12
+ };
13
+ }
14
+ export declare const webcatSpec: ProofSpec;
15
+ export declare function verifyWebcatProof(data: WebcatLeavesFile): Promise<boolean>;
package/dist/webcat.js ADDED
@@ -0,0 +1,77 @@
1
+ import { verifyExistence } from "./proofs";
2
+ import { CommitmentProof, HashOp, LengthOp, } from "./proto/cosmos/ics23/v1/proofs";
3
+ function fromHex(hexstring) {
4
+ if (hexstring.length % 2 !== 0) {
5
+ throw new Error("hex string length must be a multiple of 2");
6
+ }
7
+ const listOfInts = [];
8
+ for (let i = 0; i < hexstring.length; i += 2) {
9
+ const hexByteAsString = hexstring.substr(i, 2);
10
+ if (!hexByteAsString.match(/[0-9a-f]{2}/i)) {
11
+ throw new Error("hex string contains invalid characters");
12
+ }
13
+ listOfInts.push(parseInt(hexByteAsString, 16));
14
+ }
15
+ return new Uint8Array(listOfInts);
16
+ }
17
+ const utf8Encoder = new TextEncoder();
18
+ const leafPrefix = utf8Encoder.encode("JMT::LeafNode");
19
+ const innerPrefix = utf8Encoder.encode("JMT::InternalNode");
20
+ export const webcatSpec = {
21
+ leafSpec: {
22
+ hash: HashOp.SHA256,
23
+ prehashKey: HashOp.SHA256,
24
+ prehashValue: HashOp.SHA256,
25
+ length: LengthOp.NO_PREFIX,
26
+ prefix: leafPrefix,
27
+ },
28
+ innerSpec: {
29
+ hash: HashOp.SHA256,
30
+ childOrder: [0, 1],
31
+ childSize: 32,
32
+ minPrefixLength: innerPrefix.length - 1,
33
+ maxPrefixLength: innerPrefix.length,
34
+ emptyChild: new Uint8Array(),
35
+ },
36
+ maxDepth: 256,
37
+ minDepth: 0,
38
+ prehashKeyBeforeComparison: true,
39
+ };
40
+ function decodeProof(hex) {
41
+ return CommitmentProof.decode(fromHex(hex));
42
+ }
43
+ function collectLeafValue(data, representativeKey) {
44
+ const match = data.leaves.find(([key]) => key === representativeKey);
45
+ if (!match) {
46
+ throw new Error("Representative key is missing from leaf set");
47
+ }
48
+ return fromHex(match[1]);
49
+ }
50
+ function stripCanonicalPrefix(key) {
51
+ return key.replace(/^canonical\//, "");
52
+ }
53
+ export async function verifyWebcatProof(data) {
54
+ try {
55
+ const { proof_bytes: proofBytes, representative_key } = data.proof.merkle_proof;
56
+ if (proofBytes.length < 2) {
57
+ return false;
58
+ }
59
+ const elementProof = decodeProof(proofBytes[0]);
60
+ const canonicalProof = decodeProof(proofBytes[1]);
61
+ const canonicalRoot = fromHex(data.proof.canonical_root_hash);
62
+ const appHash = fromHex(data.proof.app_hash);
63
+ const elementKey = utf8Encoder.encode(stripCanonicalPrefix(representative_key));
64
+ const elementValue = collectLeafValue(data, representative_key);
65
+ if (!elementProof.exist || !canonicalProof.exist) {
66
+ return false;
67
+ }
68
+ await verifyExistence(elementProof.exist, webcatSpec, canonicalRoot, elementKey, elementValue);
69
+ const canonicalKey = utf8Encoder.encode("canonical");
70
+ await verifyExistence(canonicalProof.exist, webcatSpec, appHash, canonicalKey, canonicalRoot);
71
+ return true;
72
+ }
73
+ catch {
74
+ return false;
75
+ }
76
+ }
77
+ //# sourceMappingURL=webcat.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webcat.js","sourceRoot":"","sources":["../src/webcat.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,46 @@
1
+ {
2
+ "name": "@freedomofpress/ics23",
3
+ "version": "0.1.0",
4
+ "description": "Merkle proof verification library (ICS23)",
5
+ "main": "build/index.js",
6
+ "types": "build/index.d.ts",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "https://github.com/freedomofpress/ics23-ts"
10
+ },
11
+ "publishConfig": {
12
+ "access": "public",
13
+ "registry": "https://registry.npmjs.org/"
14
+ },
15
+ "author": "Giulio B",
16
+ "license": "Apache-2.0",
17
+ "files": [
18
+ "dist/**"
19
+ ],
20
+ "scripts": {
21
+ "proto:gen": "npx buf generate buf.build/cosmos/ics23",
22
+ "lint": "npx eslint --ignore-pattern '**/*.test.ts' . --fix && npx prettier --write .",
23
+ "test": "vitest run",
24
+ "test:playwright": "vitest run --config vite.config.playwright.ts",
25
+ "coverage": "vitest run --coverage",
26
+ "prebuild": "npm run proto:gen",
27
+ "build": "tsc"
28
+ },
29
+ "devDependencies": {
30
+ "@bufbuild/buf": "^1.61.0",
31
+ "@vitest/browser": "^4.0.14",
32
+ "@vitest/browser-playwright": "^4.0.14",
33
+ "@vitest/coverage-v8": "^4.0.14",
34
+ "esbuild": "^0.27.0",
35
+ "eslint-plugin-simple-import-sort": "^12.1.1",
36
+ "playwright": "^1.57.0",
37
+ "typescript": "^5.0",
38
+ "typescript-eslint": "^8.48.0",
39
+ "vite": "^7.2.6",
40
+ "vite-node": "^5.2.0",
41
+ "vitest": "^4.0.14"
42
+ },
43
+ "dependencies": {
44
+ "@bufbuild/protobuf": "^2.0.0"
45
+ }
46
+ }