@graffiti-garden/implementation-decentralized 0.0.1

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 (193) hide show
  1. package/LICENSE +674 -0
  2. package/dist/1-services/1-authorization.d.ts +37 -0
  3. package/dist/1-services/1-authorization.d.ts.map +1 -0
  4. package/dist/1-services/2-dids-tests.d.ts +2 -0
  5. package/dist/1-services/2-dids-tests.d.ts.map +1 -0
  6. package/dist/1-services/2-dids.d.ts +9 -0
  7. package/dist/1-services/2-dids.d.ts.map +1 -0
  8. package/dist/1-services/3-storage-buckets-tests.d.ts +2 -0
  9. package/dist/1-services/3-storage-buckets-tests.d.ts.map +1 -0
  10. package/dist/1-services/3-storage-buckets.d.ts +11 -0
  11. package/dist/1-services/3-storage-buckets.d.ts.map +1 -0
  12. package/dist/1-services/4-inboxes-tests.d.ts +2 -0
  13. package/dist/1-services/4-inboxes-tests.d.ts.map +1 -0
  14. package/dist/1-services/4-inboxes.d.ts +87 -0
  15. package/dist/1-services/4-inboxes.d.ts.map +1 -0
  16. package/dist/1-services/utilities.d.ts +7 -0
  17. package/dist/1-services/utilities.d.ts.map +1 -0
  18. package/dist/2-primitives/1-string-encoding-tests.d.ts +2 -0
  19. package/dist/2-primitives/1-string-encoding-tests.d.ts.map +1 -0
  20. package/dist/2-primitives/1-string-encoding.d.ts +6 -0
  21. package/dist/2-primitives/1-string-encoding.d.ts.map +1 -0
  22. package/dist/2-primitives/2-content-addresses-tests.d.ts +2 -0
  23. package/dist/2-primitives/2-content-addresses-tests.d.ts.map +1 -0
  24. package/dist/2-primitives/2-content-addresses.d.ts +8 -0
  25. package/dist/2-primitives/2-content-addresses.d.ts.map +1 -0
  26. package/dist/2-primitives/3-channel-attestations-tests.d.ts +2 -0
  27. package/dist/2-primitives/3-channel-attestations-tests.d.ts.map +1 -0
  28. package/dist/2-primitives/3-channel-attestations.d.ts +13 -0
  29. package/dist/2-primitives/3-channel-attestations.d.ts.map +1 -0
  30. package/dist/2-primitives/4-allowed-attestations-tests.d.ts +2 -0
  31. package/dist/2-primitives/4-allowed-attestations-tests.d.ts.map +1 -0
  32. package/dist/2-primitives/4-allowed-attestations.d.ts +9 -0
  33. package/dist/2-primitives/4-allowed-attestations.d.ts.map +1 -0
  34. package/dist/3-protocol/1-sessions.d.ts +81 -0
  35. package/dist/3-protocol/1-sessions.d.ts.map +1 -0
  36. package/dist/3-protocol/2-handles-tests.d.ts +2 -0
  37. package/dist/3-protocol/2-handles-tests.d.ts.map +1 -0
  38. package/dist/3-protocol/2-handles.d.ts +13 -0
  39. package/dist/3-protocol/2-handles.d.ts.map +1 -0
  40. package/dist/3-protocol/3-object-encoding-tests.d.ts +2 -0
  41. package/dist/3-protocol/3-object-encoding-tests.d.ts.map +1 -0
  42. package/dist/3-protocol/3-object-encoding.d.ts +43 -0
  43. package/dist/3-protocol/3-object-encoding.d.ts.map +1 -0
  44. package/dist/3-protocol/4-graffiti.d.ts +79 -0
  45. package/dist/3-protocol/4-graffiti.d.ts.map +1 -0
  46. package/dist/3-protocol/login-dialog.html.d.ts +2 -0
  47. package/dist/3-protocol/login-dialog.html.d.ts.map +1 -0
  48. package/dist/browser/ajv-QBSREQSI.js +9 -0
  49. package/dist/browser/ajv-QBSREQSI.js.map +7 -0
  50. package/dist/browser/build-BXWPS7VK.js +2 -0
  51. package/dist/browser/build-BXWPS7VK.js.map +7 -0
  52. package/dist/browser/chunk-RFBBAUMM.js +2 -0
  53. package/dist/browser/chunk-RFBBAUMM.js.map +7 -0
  54. package/dist/browser/graffiti-KV3G3O72-URO7SJIJ.js +2 -0
  55. package/dist/browser/graffiti-KV3G3O72-URO7SJIJ.js.map +7 -0
  56. package/dist/browser/index.js +16 -0
  57. package/dist/browser/index.js.map +7 -0
  58. package/dist/browser/login-dialog.html-XUWYDNNI.js +44 -0
  59. package/dist/browser/login-dialog.html-XUWYDNNI.js.map +7 -0
  60. package/dist/browser/rock-salt-LI7DAH66-KPFEBIBO.js +2 -0
  61. package/dist/browser/rock-salt-LI7DAH66-KPFEBIBO.js.map +7 -0
  62. package/dist/browser/style-YUTCEBZV-RWYJV575.js +287 -0
  63. package/dist/browser/style-YUTCEBZV-RWYJV575.js.map +7 -0
  64. package/dist/cjs/1-services/1-authorization.js +317 -0
  65. package/dist/cjs/1-services/1-authorization.js.map +7 -0
  66. package/dist/cjs/1-services/2-dids-tests.js +44 -0
  67. package/dist/cjs/1-services/2-dids-tests.js.map +7 -0
  68. package/dist/cjs/1-services/2-dids.js +47 -0
  69. package/dist/cjs/1-services/2-dids.js.map +7 -0
  70. package/dist/cjs/1-services/3-storage-buckets-tests.js +123 -0
  71. package/dist/cjs/1-services/3-storage-buckets-tests.js.map +7 -0
  72. package/dist/cjs/1-services/3-storage-buckets.js +148 -0
  73. package/dist/cjs/1-services/3-storage-buckets.js.map +7 -0
  74. package/dist/cjs/1-services/4-inboxes-tests.js +145 -0
  75. package/dist/cjs/1-services/4-inboxes-tests.js.map +7 -0
  76. package/dist/cjs/1-services/4-inboxes.js +539 -0
  77. package/dist/cjs/1-services/4-inboxes.js.map +7 -0
  78. package/dist/cjs/1-services/utilities.js +75 -0
  79. package/dist/cjs/1-services/utilities.js.map +7 -0
  80. package/dist/cjs/2-primitives/1-string-encoding-tests.js +50 -0
  81. package/dist/cjs/2-primitives/1-string-encoding-tests.js.map +7 -0
  82. package/dist/cjs/2-primitives/1-string-encoding.js +46 -0
  83. package/dist/cjs/2-primitives/1-string-encoding.js.map +7 -0
  84. package/dist/cjs/2-primitives/2-content-addresses-tests.js +62 -0
  85. package/dist/cjs/2-primitives/2-content-addresses-tests.js.map +7 -0
  86. package/dist/cjs/2-primitives/2-content-addresses.js +53 -0
  87. package/dist/cjs/2-primitives/2-content-addresses.js.map +7 -0
  88. package/dist/cjs/2-primitives/3-channel-attestations-tests.js +130 -0
  89. package/dist/cjs/2-primitives/3-channel-attestations-tests.js.map +7 -0
  90. package/dist/cjs/2-primitives/3-channel-attestations.js +84 -0
  91. package/dist/cjs/2-primitives/3-channel-attestations.js.map +7 -0
  92. package/dist/cjs/2-primitives/4-allowed-attestations-tests.js +96 -0
  93. package/dist/cjs/2-primitives/4-allowed-attestations-tests.js.map +7 -0
  94. package/dist/cjs/2-primitives/4-allowed-attestations.js +68 -0
  95. package/dist/cjs/2-primitives/4-allowed-attestations.js.map +7 -0
  96. package/dist/cjs/3-protocol/1-sessions.js +473 -0
  97. package/dist/cjs/3-protocol/1-sessions.js.map +7 -0
  98. package/dist/cjs/3-protocol/2-handles-tests.js +39 -0
  99. package/dist/cjs/3-protocol/2-handles-tests.js.map +7 -0
  100. package/dist/cjs/3-protocol/2-handles.js +65 -0
  101. package/dist/cjs/3-protocol/2-handles.js.map +7 -0
  102. package/dist/cjs/3-protocol/3-object-encoding-tests.js +253 -0
  103. package/dist/cjs/3-protocol/3-object-encoding-tests.js.map +7 -0
  104. package/dist/cjs/3-protocol/3-object-encoding.js +287 -0
  105. package/dist/cjs/3-protocol/3-object-encoding.js.map +7 -0
  106. package/dist/cjs/3-protocol/4-graffiti.js +937 -0
  107. package/dist/cjs/3-protocol/4-graffiti.js.map +7 -0
  108. package/dist/cjs/3-protocol/login-dialog.html.js +67 -0
  109. package/dist/cjs/3-protocol/login-dialog.html.js.map +7 -0
  110. package/dist/cjs/index.js +32 -0
  111. package/dist/cjs/index.js.map +7 -0
  112. package/dist/cjs/index.spec.js +130 -0
  113. package/dist/cjs/index.spec.js.map +7 -0
  114. package/dist/esm/1-services/1-authorization.js +304 -0
  115. package/dist/esm/1-services/1-authorization.js.map +7 -0
  116. package/dist/esm/1-services/2-dids-tests.js +24 -0
  117. package/dist/esm/1-services/2-dids-tests.js.map +7 -0
  118. package/dist/esm/1-services/2-dids.js +27 -0
  119. package/dist/esm/1-services/2-dids.js.map +7 -0
  120. package/dist/esm/1-services/3-storage-buckets-tests.js +103 -0
  121. package/dist/esm/1-services/3-storage-buckets-tests.js.map +7 -0
  122. package/dist/esm/1-services/3-storage-buckets.js +132 -0
  123. package/dist/esm/1-services/3-storage-buckets.js.map +7 -0
  124. package/dist/esm/1-services/4-inboxes-tests.js +125 -0
  125. package/dist/esm/1-services/4-inboxes-tests.js.map +7 -0
  126. package/dist/esm/1-services/4-inboxes.js +533 -0
  127. package/dist/esm/1-services/4-inboxes.js.map +7 -0
  128. package/dist/esm/1-services/utilities.js +60 -0
  129. package/dist/esm/1-services/utilities.js.map +7 -0
  130. package/dist/esm/2-primitives/1-string-encoding-tests.js +33 -0
  131. package/dist/esm/2-primitives/1-string-encoding-tests.js.map +7 -0
  132. package/dist/esm/2-primitives/1-string-encoding.js +26 -0
  133. package/dist/esm/2-primitives/1-string-encoding.js.map +7 -0
  134. package/dist/esm/2-primitives/2-content-addresses-tests.js +45 -0
  135. package/dist/esm/2-primitives/2-content-addresses-tests.js.map +7 -0
  136. package/dist/esm/2-primitives/2-content-addresses.js +33 -0
  137. package/dist/esm/2-primitives/2-content-addresses.js.map +7 -0
  138. package/dist/esm/2-primitives/3-channel-attestations-tests.js +116 -0
  139. package/dist/esm/2-primitives/3-channel-attestations-tests.js.map +7 -0
  140. package/dist/esm/2-primitives/3-channel-attestations.js +69 -0
  141. package/dist/esm/2-primitives/3-channel-attestations.js.map +7 -0
  142. package/dist/esm/2-primitives/4-allowed-attestations-tests.js +82 -0
  143. package/dist/esm/2-primitives/4-allowed-attestations-tests.js.map +7 -0
  144. package/dist/esm/2-primitives/4-allowed-attestations.js +51 -0
  145. package/dist/esm/2-primitives/4-allowed-attestations.js.map +7 -0
  146. package/dist/esm/3-protocol/1-sessions.js +465 -0
  147. package/dist/esm/3-protocol/1-sessions.js.map +7 -0
  148. package/dist/esm/3-protocol/2-handles-tests.js +19 -0
  149. package/dist/esm/3-protocol/2-handles-tests.js.map +7 -0
  150. package/dist/esm/3-protocol/2-handles.js +45 -0
  151. package/dist/esm/3-protocol/2-handles.js.map +7 -0
  152. package/dist/esm/3-protocol/3-object-encoding-tests.js +248 -0
  153. package/dist/esm/3-protocol/3-object-encoding-tests.js.map +7 -0
  154. package/dist/esm/3-protocol/3-object-encoding.js +280 -0
  155. package/dist/esm/3-protocol/3-object-encoding.js.map +7 -0
  156. package/dist/esm/3-protocol/4-graffiti.js +957 -0
  157. package/dist/esm/3-protocol/4-graffiti.js.map +7 -0
  158. package/dist/esm/3-protocol/login-dialog.html.js +47 -0
  159. package/dist/esm/3-protocol/login-dialog.html.js.map +7 -0
  160. package/dist/esm/index.js +14 -0
  161. package/dist/esm/index.js.map +7 -0
  162. package/dist/esm/index.spec.js +133 -0
  163. package/dist/esm/index.spec.js.map +7 -0
  164. package/dist/index.d.ts +10 -0
  165. package/dist/index.d.ts.map +1 -0
  166. package/dist/index.spec.d.ts +2 -0
  167. package/dist/index.spec.d.ts.map +1 -0
  168. package/package.json +62 -0
  169. package/src/1-services/1-authorization.ts +399 -0
  170. package/src/1-services/2-dids-tests.ts +24 -0
  171. package/src/1-services/2-dids.ts +30 -0
  172. package/src/1-services/3-storage-buckets-tests.ts +121 -0
  173. package/src/1-services/3-storage-buckets.ts +183 -0
  174. package/src/1-services/4-inboxes-tests.ts +154 -0
  175. package/src/1-services/4-inboxes.ts +722 -0
  176. package/src/1-services/utilities.ts +65 -0
  177. package/src/2-primitives/1-string-encoding-tests.ts +33 -0
  178. package/src/2-primitives/1-string-encoding.ts +33 -0
  179. package/src/2-primitives/2-content-addresses-tests.ts +46 -0
  180. package/src/2-primitives/2-content-addresses.ts +42 -0
  181. package/src/2-primitives/3-channel-attestations-tests.ts +125 -0
  182. package/src/2-primitives/3-channel-attestations.ts +95 -0
  183. package/src/2-primitives/4-allowed-attestations-tests.ts +86 -0
  184. package/src/2-primitives/4-allowed-attestations.ts +69 -0
  185. package/src/3-protocol/1-sessions.ts +601 -0
  186. package/src/3-protocol/2-handles-tests.ts +17 -0
  187. package/src/3-protocol/2-handles.ts +60 -0
  188. package/src/3-protocol/3-object-encoding-tests.ts +269 -0
  189. package/src/3-protocol/3-object-encoding.ts +396 -0
  190. package/src/3-protocol/4-graffiti.ts +1265 -0
  191. package/src/3-protocol/login-dialog.html.ts +43 -0
  192. package/src/index.spec.ts +158 -0
  193. package/src/index.ts +16 -0
@@ -0,0 +1,65 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var handles_exports = {};
20
+ __export(handles_exports, {
21
+ Handles: () => Handles
22
+ });
23
+ module.exports = __toCommonJS(handles_exports);
24
+ var import_api = require("@graffiti-garden/api");
25
+ var import_dids = require("../1-services/2-dids");
26
+ const HANDLE_DID_PREFIX = "did:web:";
27
+ class Handles {
28
+ constructor(services) {
29
+ this.services = services;
30
+ }
31
+ actorToHandle = async (actor) => {
32
+ const actorDocument = await this.services.dids.resolve(actor);
33
+ const handleDid = actorDocument.alsoKnownAs?.at(0);
34
+ if (!handleDid) {
35
+ throw new import_api.GraffitiErrorNotFound(
36
+ `Handle for actor DID ${actor} not found`
37
+ );
38
+ }
39
+ if (!handleDid.startsWith(HANDLE_DID_PREFIX)) {
40
+ throw new Error(`Handle DID ${handleDid} is not a valid handle`);
41
+ }
42
+ const handle = handleDid.slice(HANDLE_DID_PREFIX.length);
43
+ const handleDocument = await this.services.dids.resolve(handleDid);
44
+ if (!handleDocument.alsoKnownAs || !handleDocument.alsoKnownAs.includes(actor)) {
45
+ throw new Error(`Handle ${handle} does not match actor ${actor}`);
46
+ }
47
+ return handle;
48
+ };
49
+ handleToActor = async (handle) => {
50
+ const handleDid = `${HANDLE_DID_PREFIX}${handle}`;
51
+ const handleDocument = await this.services.dids.resolve(handleDid);
52
+ const actor = handleDocument.alsoKnownAs?.at(0);
53
+ if (!actor) {
54
+ throw new import_api.GraffitiErrorNotFound(
55
+ `Actor for handle DID ${handleDid} not found`
56
+ );
57
+ }
58
+ const actorDocument = await this.services.dids.resolve(actor);
59
+ if (!actorDocument.alsoKnownAs || !actorDocument.alsoKnownAs.includes(handleDid)) {
60
+ throw new Error(`Actor ${actor} does not match handle ${handle}`);
61
+ }
62
+ return actor;
63
+ };
64
+ }
65
+ //# sourceMappingURL=2-handles.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/3-protocol/2-handles.ts"],
4
+ "sourcesContent": ["import type { Graffiti } from \"@graffiti-garden/api\";\nimport { GraffitiErrorNotFound } from \"@graffiti-garden/api\";\nimport { DecentralizedIdentifiers } from \"../1-services/2-dids\";\n\n// Handles used a fixed method\nconst HANDLE_DID_PREFIX = \"did:web:\";\n\nexport class Handles {\n constructor(\n protected readonly services: { dids: DecentralizedIdentifiers },\n ) {}\n\n actorToHandle: Graffiti[\"actorToHandle\"] = async (actor) => {\n const actorDocument = await this.services.dids.resolve(actor);\n\n const handleDid = actorDocument.alsoKnownAs?.at(0);\n if (!handleDid) {\n throw new GraffitiErrorNotFound(\n `Handle for actor DID ${actor} not found`,\n );\n }\n if (!handleDid.startsWith(HANDLE_DID_PREFIX)) {\n throw new Error(`Handle DID ${handleDid} is not a valid handle`);\n }\n\n const handle = handleDid.slice(HANDLE_DID_PREFIX.length);\n\n const handleDocument = await this.services.dids.resolve(handleDid);\n if (\n !handleDocument.alsoKnownAs ||\n !handleDocument.alsoKnownAs.includes(actor)\n ) {\n throw new Error(`Handle ${handle} does not match actor ${actor}`);\n }\n\n return handle;\n };\n\n handleToActor: Graffiti[\"handleToActor\"] = async (handle) => {\n const handleDid = `${HANDLE_DID_PREFIX}${handle}`;\n const handleDocument = await this.services.dids.resolve(handleDid);\n\n const actor = handleDocument.alsoKnownAs?.at(0);\n if (!actor) {\n throw new GraffitiErrorNotFound(\n `Actor for handle DID ${handleDid} not found`,\n );\n }\n\n const actorDocument = await this.services.dids.resolve(actor);\n if (\n !actorDocument.alsoKnownAs ||\n !actorDocument.alsoKnownAs.includes(handleDid)\n ) {\n throw new Error(`Actor ${actor} does not match handle ${handle}`);\n }\n\n return actor;\n };\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,iBAAsC;AACtC,kBAAyC;AAGzC,MAAM,oBAAoB;AAEnB,MAAM,QAAQ;AAAA,EACnB,YACqB,UACnB;AADmB;AAAA,EAClB;AAAA,EAEH,gBAA2C,OAAO,UAAU;AAC1D,UAAM,gBAAgB,MAAM,KAAK,SAAS,KAAK,QAAQ,KAAK;AAE5D,UAAM,YAAY,cAAc,aAAa,GAAG,CAAC;AACjD,QAAI,CAAC,WAAW;AACd,YAAM,IAAI;AAAA,QACR,wBAAwB,KAAK;AAAA,MAC/B;AAAA,IACF;AACA,QAAI,CAAC,UAAU,WAAW,iBAAiB,GAAG;AAC5C,YAAM,IAAI,MAAM,cAAc,SAAS,wBAAwB;AAAA,IACjE;AAEA,UAAM,SAAS,UAAU,MAAM,kBAAkB,MAAM;AAEvD,UAAM,iBAAiB,MAAM,KAAK,SAAS,KAAK,QAAQ,SAAS;AACjE,QACE,CAAC,eAAe,eAChB,CAAC,eAAe,YAAY,SAAS,KAAK,GAC1C;AACA,YAAM,IAAI,MAAM,UAAU,MAAM,yBAAyB,KAAK,EAAE;AAAA,IAClE;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,gBAA2C,OAAO,WAAW;AAC3D,UAAM,YAAY,GAAG,iBAAiB,GAAG,MAAM;AAC/C,UAAM,iBAAiB,MAAM,KAAK,SAAS,KAAK,QAAQ,SAAS;AAEjE,UAAM,QAAQ,eAAe,aAAa,GAAG,CAAC;AAC9C,QAAI,CAAC,OAAO;AACV,YAAM,IAAI;AAAA,QACR,wBAAwB,SAAS;AAAA,MACnC;AAAA,IACF;AAEA,UAAM,gBAAgB,MAAM,KAAK,SAAS,KAAK,QAAQ,KAAK;AAC5D,QACE,CAAC,cAAc,eACf,CAAC,cAAc,YAAY,SAAS,SAAS,GAC7C;AACA,YAAM,IAAI,MAAM,SAAS,KAAK,0BAA0B,MAAM,EAAE;AAAA,IAClE;AAEA,WAAO;AAAA,EACT;AACF;",
6
+ "names": []
7
+ }
@@ -0,0 +1,253 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var object_encoding_tests_exports = {};
20
+ __export(object_encoding_tests_exports, {
21
+ objectEncodingTests: () => objectEncodingTests
22
+ });
23
+ module.exports = __toCommonJS(object_encoding_tests_exports);
24
+ var import_vitest = require("vitest");
25
+ var import_object_encoding = require("./3-object-encoding.js");
26
+ var import_utils = require("@noble/hashes/utils.js");
27
+ var import_string_encoding = require("../2-primitives/1-string-encoding.js");
28
+ var import_content_addresses = require("../2-primitives/2-content-addresses.js");
29
+ var import_channel_attestations = require("../2-primitives/3-channel-attestations.js");
30
+ var import_allowed_attestations = require("../2-primitives/4-allowed-attestations.js");
31
+ var import_dag_cbor = require("@ipld/dag-cbor");
32
+ var import_api = require("@graffiti-garden/api");
33
+ function objectEncodingTests() {
34
+ (0, import_vitest.describe)("object Urls", () => {
35
+ for (const actor of [
36
+ "did:plc:alsdkjfkdjf",
37
+ "did:web:example.com/someone",
38
+ "did:example:123456789abcdefghi\u{1F47B}"
39
+ ]) {
40
+ (0, import_vitest.test)(`encodeObjectUrl encodes and decodes correctly with actor: ${actor}`, async () => {
41
+ const contentAddressBytes = (0, import_utils.randomBytes)();
42
+ const contentAddress = await new import_string_encoding.StringEncoder().encode(
43
+ import_string_encoding.STRING_ENCODER_METHOD_BASE64URL,
44
+ contentAddressBytes
45
+ );
46
+ const url = (0, import_object_encoding.encodeObjectUrl)(actor, contentAddress);
47
+ const decoded = (0, import_object_encoding.decodeObjectUrl)(url);
48
+ (0, import_vitest.expect)(decoded.actor).toBe(actor);
49
+ (0, import_vitest.expect)(decoded.contentAddress).toBe(contentAddress);
50
+ });
51
+ }
52
+ for (const invalidUrl of [
53
+ "http://example.com/not-an-object-url",
54
+ "graffiti:",
55
+ "graffiti:",
56
+ "graffiti:no-content-address",
57
+ "graffiti:too:many:parts"
58
+ ]) {
59
+ (0, import_vitest.test)(`Invalid Graffiti URL: ${invalidUrl}`, () => {
60
+ (0, import_vitest.expect)(() => (0, import_object_encoding.decodeObjectUrl)(invalidUrl)).toThrow();
61
+ });
62
+ }
63
+ });
64
+ (0, import_vitest.describe)("object encoding and validation", async () => {
65
+ const objectEncoding = new import_object_encoding.ObjectEncoding({
66
+ stringEncoder: new import_string_encoding.StringEncoder(),
67
+ allowedAttestations: new import_allowed_attestations.AllowedAttestations(),
68
+ channelAttestations: new import_channel_attestations.ChannelAttestations(),
69
+ contentAddresses: new import_content_addresses.ContentAddresses()
70
+ });
71
+ const value = {
72
+ message: "Hello world!",
73
+ nested: {
74
+ foo: {
75
+ bar: 42
76
+ }
77
+ },
78
+ array: [1, "something \u{1F47B}", { key: "value" }]
79
+ };
80
+ const channels = ["channel1\u{1F47B}", "channel2"];
81
+ const allowed = ["did:web:noone.example.com", "did:web:someone.else.com"];
82
+ const actor = "did:web:someone.example.com";
83
+ const { allowedTickets, tags, objectBytes, object } = await objectEncoding.encode(
84
+ {
85
+ value,
86
+ channels,
87
+ allowed
88
+ },
89
+ actor
90
+ );
91
+ (0, import_vitest.assert)(Array.isArray(allowedTickets));
92
+ (0, import_vitest.test)("validate private", async () => {
93
+ await objectEncoding.validate(object, tags, objectBytes, {
94
+ allowedTickets
95
+ });
96
+ for (const [index, recipient] of allowed.entries()) {
97
+ const copy = JSON.parse(JSON.stringify(object));
98
+ const masked = (0, import_api.maskGraffitiObject)(copy, [], recipient);
99
+ await objectEncoding.validate(masked, tags, objectBytes, {
100
+ recipient,
101
+ allowedTicket: allowedTickets[index],
102
+ allowedIndex: index
103
+ });
104
+ }
105
+ });
106
+ (0, import_vitest.test)("incorrect value", async () => {
107
+ await (0, import_vitest.expect)(
108
+ objectEncoding.validate(
109
+ {
110
+ ...object,
111
+ value: {
112
+ ...object.value,
113
+ extra: "field"
114
+ }
115
+ },
116
+ tags,
117
+ objectBytes,
118
+ {
119
+ allowedTickets
120
+ }
121
+ )
122
+ ).rejects.toThrow();
123
+ });
124
+ (0, import_vitest.test)("incorrect content address", async () => {
125
+ const url = (0, import_object_encoding.encodeObjectUrl)(
126
+ actor,
127
+ await new import_string_encoding.StringEncoder().encode(
128
+ import_string_encoding.STRING_ENCODER_METHOD_BASE64URL,
129
+ (0, import_utils.randomBytes)()
130
+ )
131
+ );
132
+ await (0, import_vitest.expect)(
133
+ objectEncoding.validate(
134
+ {
135
+ ...object,
136
+ url
137
+ },
138
+ [new TextEncoder().encode(url), ...tags.slice(1)],
139
+ objectBytes,
140
+ {
141
+ allowedTickets
142
+ }
143
+ )
144
+ ).rejects.toThrow();
145
+ });
146
+ (0, import_vitest.test)("incorrect bytes", async () => {
147
+ const wrongObjectBytes = (0, import_utils.randomBytes)();
148
+ const correctContentAddress = (0, import_object_encoding.decodeObjectUrl)(object.url).contentAddress;
149
+ const correctContentAddressBytes = await new import_string_encoding.StringEncoder().decode(
150
+ correctContentAddress
151
+ );
152
+ const contentAddresses = new import_content_addresses.ContentAddresses();
153
+ const contentAddressMethod = await contentAddresses.getMethod(
154
+ correctContentAddressBytes
155
+ );
156
+ const wrongContentAddressBytes = await contentAddresses.register(
157
+ contentAddressMethod,
158
+ wrongObjectBytes
159
+ );
160
+ const wrongContentAddress = await new import_string_encoding.StringEncoder().encode(
161
+ import_string_encoding.STRING_ENCODER_METHOD_BASE64URL,
162
+ wrongContentAddressBytes
163
+ );
164
+ const wrongObjectUrl = (0, import_object_encoding.encodeObjectUrl)(actor, wrongContentAddress);
165
+ await (0, import_vitest.expect)(
166
+ objectEncoding.validate(
167
+ {
168
+ ...object,
169
+ url: wrongObjectUrl
170
+ },
171
+ [new TextEncoder().encode(wrongObjectUrl), ...tags.slice(1)],
172
+ wrongObjectBytes,
173
+ {
174
+ allowedTickets
175
+ }
176
+ )
177
+ ).rejects.toThrow();
178
+ });
179
+ (0, import_vitest.test)("incorrect format", async () => {
180
+ const wrongData = {
181
+ not: "the expected format"
182
+ };
183
+ const wrongObjectBytes = (0, import_dag_cbor.encode)(wrongData);
184
+ const correctContentAddress = (0, import_object_encoding.decodeObjectUrl)(object.url).contentAddress;
185
+ const correctContentAddressBytes = await new import_string_encoding.StringEncoder().decode(
186
+ correctContentAddress
187
+ );
188
+ const contentAddresses = new import_content_addresses.ContentAddresses();
189
+ const contentAddressMethod = await contentAddresses.getMethod(
190
+ correctContentAddressBytes
191
+ );
192
+ const wrongContentAddressBytes = await contentAddresses.register(
193
+ contentAddressMethod,
194
+ wrongObjectBytes
195
+ );
196
+ const wrongContentAddress = await new import_string_encoding.StringEncoder().encode(
197
+ import_string_encoding.STRING_ENCODER_METHOD_BASE64URL,
198
+ wrongContentAddressBytes
199
+ );
200
+ const wrongObjectUrl = (0, import_object_encoding.encodeObjectUrl)(actor, wrongContentAddress);
201
+ await (0, import_vitest.expect)(
202
+ objectEncoding.validate(
203
+ {
204
+ ...object,
205
+ url: wrongObjectUrl
206
+ },
207
+ [new TextEncoder().encode(wrongObjectUrl), ...tags.slice(1)],
208
+ wrongObjectBytes,
209
+ {
210
+ allowedTickets
211
+ }
212
+ )
213
+ ).rejects.toThrow();
214
+ });
215
+ (0, import_vitest.test)("missing allowed tickets", async () => {
216
+ await (0, import_vitest.expect)(
217
+ objectEncoding.validate(object, tags, objectBytes)
218
+ ).rejects.toThrow();
219
+ });
220
+ (0, import_vitest.test)("wrong allowed tickets", async () => {
221
+ const wrongAllowedTickets = await Promise.all(
222
+ allowedTickets.map(
223
+ async (ticket) => (await new import_allowed_attestations.AllowedAttestations().attest(
224
+ import_allowed_attestations.ALLOWED_ATTESTATION_METHOD_HMAC_SHA256,
225
+ "did:web:not-the-right.actor"
226
+ )).ticket
227
+ )
228
+ );
229
+ await (0, import_vitest.expect)(
230
+ objectEncoding.validate(object, tags, objectBytes, {
231
+ allowedTickets: wrongAllowedTickets
232
+ })
233
+ ).rejects.toThrow();
234
+ });
235
+ (0, import_vitest.test)("wrong recipients", async () => {
236
+ const wrongRecipients = allowed.map((recipient) => recipient + "-wrong");
237
+ await (0, import_vitest.expect)(
238
+ objectEncoding.validate(
239
+ {
240
+ ...object,
241
+ allowed: wrongRecipients
242
+ },
243
+ tags,
244
+ objectBytes,
245
+ {
246
+ allowedTickets
247
+ }
248
+ )
249
+ ).rejects.toThrow();
250
+ });
251
+ });
252
+ }
253
+ //# sourceMappingURL=3-object-encoding-tests.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/3-protocol/3-object-encoding-tests.ts"],
4
+ "sourcesContent": ["import { assert, describe, expect, test } from \"vitest\";\n\nimport {\n encodeObjectUrl,\n decodeObjectUrl,\n ObjectEncoding,\n} from \"./3-object-encoding.js\";\nimport { randomBytes } from \"@noble/hashes/utils.js\";\nimport {\n STRING_ENCODER_METHOD_BASE64URL,\n StringEncoder,\n} from \"../2-primitives/1-string-encoding.js\";\nimport { ContentAddresses } from \"../2-primitives/2-content-addresses.js\";\nimport { ChannelAttestations } from \"../2-primitives/3-channel-attestations.js\";\nimport {\n ALLOWED_ATTESTATION_METHOD_HMAC_SHA256,\n AllowedAttestations,\n} from \"../2-primitives/4-allowed-attestations.js\";\nimport {\n encode as dagCborEncode,\n decode as dagCborDecode,\n} from \"@ipld/dag-cbor\";\nimport {\n maskGraffitiObject,\n type GraffitiObjectBase,\n} from \"@graffiti-garden/api\";\n\nexport function objectEncodingTests() {\n describe(\"object Urls\", () => {\n for (const actor of [\n \"did:plc:alsdkjfkdjf\",\n \"did:web:example.com/someone\",\n \"did:example:123456789abcdefghi\uD83D\uDC7B\",\n ]) {\n test(`encodeObjectUrl encodes and decodes correctly with actor: ${actor}`, async () => {\n const contentAddressBytes = randomBytes();\n const contentAddress = await new StringEncoder().encode(\n STRING_ENCODER_METHOD_BASE64URL,\n contentAddressBytes,\n );\n\n const url = encodeObjectUrl(actor, contentAddress);\n const decoded = decodeObjectUrl(url);\n expect(decoded.actor).toBe(actor);\n expect(decoded.contentAddress).toBe(contentAddress);\n });\n }\n\n for (const invalidUrl of [\n \"http://example.com/not-an-object-url\",\n \"graffiti:\",\n \"graffiti:\",\n \"graffiti:no-content-address\",\n \"graffiti:too:many:parts\",\n ]) {\n test(`Invalid Graffiti URL: ${invalidUrl}`, () => {\n expect(() => decodeObjectUrl(invalidUrl)).toThrow();\n });\n }\n });\n\n describe(\"object encoding and validation\", async () => {\n const objectEncoding = new ObjectEncoding({\n stringEncoder: new StringEncoder(),\n allowedAttestations: new AllowedAttestations(),\n channelAttestations: new ChannelAttestations(),\n contentAddresses: new ContentAddresses(),\n });\n\n const value = {\n message: \"Hello world!\",\n nested: {\n foo: {\n bar: 42,\n },\n },\n array: [1, \"something \uD83D\uDC7B\", { key: \"value\" }],\n };\n const channels = [\"channel1\uD83D\uDC7B\", \"channel2\"];\n const allowed = [\"did:web:noone.example.com\", \"did:web:someone.else.com\"];\n const actor = \"did:web:someone.example.com\";\n\n const { allowedTickets, tags, objectBytes, object } =\n await objectEncoding.encode<{}>(\n {\n value,\n channels,\n allowed,\n },\n actor,\n );\n assert(Array.isArray(allowedTickets));\n\n test(\"validate private\", async () => {\n await objectEncoding.validate(object, tags, objectBytes, {\n allowedTickets,\n });\n\n for (const [index, recipient] of allowed.entries()) {\n const copy = JSON.parse(JSON.stringify(object)) as GraffitiObjectBase;\n const masked = maskGraffitiObject(copy, [], recipient);\n await objectEncoding.validate(masked, tags, objectBytes, {\n recipient: recipient,\n allowedTicket: allowedTickets[index],\n allowedIndex: index,\n });\n }\n });\n\n test(\"incorrect value\", async () => {\n await expect(\n objectEncoding.validate(\n {\n ...object,\n value: {\n ...object.value,\n extra: \"field\",\n },\n },\n tags,\n objectBytes,\n {\n allowedTickets,\n },\n ),\n ).rejects.toThrow();\n });\n\n test(\"incorrect content address\", async () => {\n const url = encodeObjectUrl(\n actor,\n await new StringEncoder().encode(\n STRING_ENCODER_METHOD_BASE64URL,\n randomBytes(),\n ),\n );\n\n await expect(\n objectEncoding.validate(\n {\n ...object,\n url,\n },\n [new TextEncoder().encode(url), ...tags.slice(1)],\n objectBytes,\n {\n allowedTickets,\n },\n ),\n ).rejects.toThrow();\n });\n\n test(\"incorrect bytes\", async () => {\n const wrongObjectBytes = randomBytes();\n const correctContentAddress = decodeObjectUrl(object.url).contentAddress;\n const correctContentAddressBytes = await new StringEncoder().decode(\n correctContentAddress,\n );\n const contentAddresses = new ContentAddresses();\n const contentAddressMethod = await contentAddresses.getMethod(\n correctContentAddressBytes,\n );\n const wrongContentAddressBytes = await contentAddresses.register(\n contentAddressMethod,\n wrongObjectBytes,\n );\n const wrongContentAddress = await new StringEncoder().encode(\n STRING_ENCODER_METHOD_BASE64URL,\n wrongContentAddressBytes,\n );\n const wrongObjectUrl = encodeObjectUrl(actor, wrongContentAddress);\n\n await expect(\n objectEncoding.validate(\n {\n ...object,\n url: wrongObjectUrl,\n },\n [new TextEncoder().encode(wrongObjectUrl), ...tags.slice(1)],\n wrongObjectBytes,\n {\n allowedTickets,\n },\n ),\n ).rejects.toThrow();\n });\n\n test(\"incorrect format\", async () => {\n const wrongData = {\n not: \"the expected format\",\n };\n const wrongObjectBytes = dagCborEncode(wrongData);\n const correctContentAddress = decodeObjectUrl(object.url).contentAddress;\n const correctContentAddressBytes = await new StringEncoder().decode(\n correctContentAddress,\n );\n const contentAddresses = new ContentAddresses();\n const contentAddressMethod = await contentAddresses.getMethod(\n correctContentAddressBytes,\n );\n const wrongContentAddressBytes = await contentAddresses.register(\n contentAddressMethod,\n wrongObjectBytes,\n );\n const wrongContentAddress = await new StringEncoder().encode(\n STRING_ENCODER_METHOD_BASE64URL,\n wrongContentAddressBytes,\n );\n const wrongObjectUrl = encodeObjectUrl(actor, wrongContentAddress);\n await expect(\n objectEncoding.validate(\n {\n ...object,\n url: wrongObjectUrl,\n },\n [new TextEncoder().encode(wrongObjectUrl), ...tags.slice(1)],\n wrongObjectBytes,\n {\n allowedTickets,\n },\n ),\n ).rejects.toThrow();\n });\n\n test(\"missing allowed tickets\", async () => {\n await expect(\n objectEncoding.validate(object, tags, objectBytes),\n ).rejects.toThrow();\n });\n\n test(\"wrong allowed tickets\", async () => {\n const wrongAllowedTickets = await Promise.all(\n allowedTickets.map(\n async (ticket) =>\n (\n await new AllowedAttestations().attest(\n ALLOWED_ATTESTATION_METHOD_HMAC_SHA256,\n \"did:web:not-the-right.actor\",\n )\n ).ticket,\n ),\n );\n\n await expect(\n objectEncoding.validate(object, tags, objectBytes, {\n allowedTickets: wrongAllowedTickets,\n }),\n ).rejects.toThrow();\n });\n\n test(\"wrong recipients\", async () => {\n const wrongRecipients = allowed.map((recipient) => recipient + \"-wrong\");\n\n await expect(\n objectEncoding.validate(\n {\n ...object,\n allowed: wrongRecipients,\n },\n tags,\n objectBytes,\n {\n allowedTickets,\n },\n ),\n ).rejects.toThrow();\n });\n });\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["dagCborEncode"]
7
+ }
@@ -0,0 +1,287 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var object_encoding_exports = {};
20
+ __export(object_encoding_exports, {
21
+ GRAFFITI_OBJECT_URL_PREFIX: () => GRAFFITI_OBJECT_URL_PREFIX,
22
+ MAX_OBJECT_SIZE_BYTES: () => MAX_OBJECT_SIZE_BYTES,
23
+ ObjectEncoding: () => ObjectEncoding,
24
+ decodeObjectUrl: () => decodeObjectUrl,
25
+ decodeObjectUrlComponent: () => decodeObjectUrlComponent,
26
+ encodeObjectUrl: () => encodeObjectUrl,
27
+ encodeObjectUrlComponent: () => encodeObjectUrlComponent
28
+ });
29
+ module.exports = __toCommonJS(object_encoding_exports);
30
+ var import_content_addresses = require("../2-primitives/2-content-addresses");
31
+ var import_utils = require("@noble/hashes/utils.js");
32
+ var import_dag_cbor = require("@ipld/dag-cbor");
33
+ var import_mini = require("zod/mini");
34
+ var import_channel_attestations = require("../2-primitives/3-channel-attestations");
35
+ var import_allowed_attestations = require("../2-primitives/4-allowed-attestations");
36
+ var import_string_encoding = require("../2-primitives/1-string-encoding");
37
+ const MAX_OBJECT_SIZE_BYTES = 32 * 1024;
38
+ class ObjectEncoding {
39
+ constructor(primitives) {
40
+ this.primitives = primitives;
41
+ }
42
+ async encode(partialObject, actor) {
43
+ partialObject = cleanUndefined(partialObject);
44
+ const channelAttestationAndPublicIds = await Promise.all(
45
+ partialObject.channels.map(
46
+ (channel) => this.primitives.channelAttestations.attest(
47
+ // TODO: get this from the DID document of the actor
48
+ import_channel_attestations.CHANNEL_ATTESTATION_METHOD_SHA256_ED25519,
49
+ actor,
50
+ channel
51
+ )
52
+ )
53
+ );
54
+ const channelAttestations = channelAttestationAndPublicIds.map(
55
+ (c) => c.attestation
56
+ );
57
+ const channelPublicIds = channelAttestationAndPublicIds.map(
58
+ (c) => c.channelPublicId
59
+ );
60
+ const objectData = {
61
+ [VALUE_PROPERTY]: partialObject.value,
62
+ [CHANNEL_ATTESTATIONS_PROPERTY]: channelAttestations,
63
+ [NONCE_PROPERTY]: (0, import_utils.randomBytes)(32)
64
+ };
65
+ let allowedTickets = void 0;
66
+ if (Array.isArray(partialObject.allowed)) {
67
+ const allowedAttestations = await Promise.all(
68
+ partialObject.allowed.map(
69
+ async (allowedActor) => this.primitives.allowedAttestations.attest(
70
+ // TODO: get this from the DID document of the actor
71
+ import_allowed_attestations.ALLOWED_ATTESTATION_METHOD_HMAC_SHA256,
72
+ allowedActor
73
+ )
74
+ )
75
+ );
76
+ objectData[ALLOWED_ATTESTATIONS_PROPERTY] = allowedAttestations.map(
77
+ (a) => a.attestation
78
+ );
79
+ allowedTickets = allowedAttestations.map((a) => a.ticket);
80
+ }
81
+ const objectBytes = (0, import_dag_cbor.encode)(objectData);
82
+ if (objectBytes.byteLength > MAX_OBJECT_SIZE_BYTES) {
83
+ throw new Error("The object is too large");
84
+ }
85
+ const objectContentAddressBytes = await this.primitives.contentAddresses.register(
86
+ // TODO: get this from the DID document of the actor
87
+ import_content_addresses.CONTENT_ADDRESS_METHOD_SHA256,
88
+ objectBytes
89
+ );
90
+ const objectContentAddress = await this.primitives.stringEncoder.encode(
91
+ import_string_encoding.STRING_ENCODER_METHOD_BASE64URL,
92
+ objectContentAddressBytes
93
+ );
94
+ const objectUrl = encodeObjectUrl(actor, objectContentAddress);
95
+ const tags = [new TextEncoder().encode(objectUrl), ...channelPublicIds];
96
+ const object = {
97
+ value: partialObject.value,
98
+ channels: partialObject.channels,
99
+ url: objectUrl,
100
+ actor,
101
+ ...partialObject.allowed ? {
102
+ allowed: partialObject.allowed
103
+ } : {}
104
+ };
105
+ return {
106
+ object,
107
+ tags,
108
+ objectBytes,
109
+ allowedTickets
110
+ };
111
+ }
112
+ async validate(object, tags, objectBytes, privateObjectInfo) {
113
+ if (objectBytes.byteLength > MAX_OBJECT_SIZE_BYTES) {
114
+ throw new Error("Object is too big");
115
+ }
116
+ const { actor, contentAddress } = decodeObjectUrl(object.url);
117
+ if (actor !== object.actor) {
118
+ throw new Error("Object actor does not match URL actor");
119
+ }
120
+ const objectUrlTag = tags.at(0);
121
+ if (!objectUrlTag) {
122
+ throw new Error("No object URL tag");
123
+ }
124
+ if (new TextDecoder().decode(objectUrlTag) !== object.url) {
125
+ throw new Error("Object URL tag does not match object URL");
126
+ }
127
+ const channelPublicIds = tags.slice(1);
128
+ const contentAddressBytes = await this.primitives.stringEncoder.decode(contentAddress);
129
+ const contentAddressMethod = await this.primitives.contentAddresses.getMethod(contentAddressBytes);
130
+ const expectedContentAddress = await this.primitives.contentAddresses.register(
131
+ contentAddressMethod,
132
+ objectBytes
133
+ );
134
+ if (expectedContentAddress.length !== contentAddressBytes.length || !expectedContentAddress.every((b, i) => b === contentAddressBytes[i])) {
135
+ throw new Error("Content address is invalid");
136
+ }
137
+ const objectDataUnknown = (0, import_dag_cbor.decode)(objectBytes);
138
+ const objectData = ObjectDataSchema.parse(objectDataUnknown);
139
+ const value = objectData[VALUE_PROPERTY];
140
+ const channelAttestations = objectData[CHANNEL_ATTESTATIONS_PROPERTY];
141
+ const allowedAttestations = objectData[ALLOWED_ATTESTATIONS_PROPERTY];
142
+ const valueBytes = (0, import_dag_cbor.encode)(value);
143
+ const expectedValueBytes = (0, import_dag_cbor.encode)(object.value);
144
+ if (valueBytes.length !== expectedValueBytes.length || !valueBytes.every((b, i) => b === expectedValueBytes[i])) {
145
+ throw new Error("Object value does not match storage value");
146
+ }
147
+ if (channelAttestations.length !== channelPublicIds.length) {
148
+ throw new Error("Not as many channel attestations and public ids");
149
+ }
150
+ for (const [index, attestation] of channelAttestations.entries()) {
151
+ const channelPublicId = channelPublicIds[index];
152
+ const isValid = await this.primitives.channelAttestations.validate(
153
+ attestation,
154
+ actor,
155
+ channelPublicId
156
+ );
157
+ if (!isValid) {
158
+ throw new Error("Invalid channel attestation");
159
+ }
160
+ }
161
+ if (object.channels.length) {
162
+ if (object.channels.length !== channelPublicIds.length) {
163
+ throw new Error(
164
+ "Number of claimed channels does not match attestations/public IDs"
165
+ );
166
+ }
167
+ const channelAttestationMethod = await this.primitives.channelAttestations.getMethod(
168
+ channelPublicIds[0]
169
+ );
170
+ const expectedChannelPublicIds = await Promise.all(
171
+ object.channels.map(
172
+ (channel) => this.primitives.channelAttestations.register(
173
+ channelAttestationMethod,
174
+ channel
175
+ )
176
+ )
177
+ );
178
+ for (const [
179
+ index,
180
+ expectedPublicId
181
+ ] of expectedChannelPublicIds.entries()) {
182
+ const actualPublicId = channelPublicIds[index];
183
+ if (expectedPublicId.length !== actualPublicId.length || !expectedPublicId.every((b, i) => b === actualPublicId[i])) {
184
+ throw new Error("Channel public id does not match expected");
185
+ }
186
+ }
187
+ }
188
+ if (privateObjectInfo) {
189
+ if (!allowedAttestations) {
190
+ throw new Error("Object is public but thought to be private");
191
+ }
192
+ let recipients;
193
+ let allowedTickets;
194
+ let attestations;
195
+ if ("recipient" in privateObjectInfo) {
196
+ recipients = [privateObjectInfo.recipient];
197
+ allowedTickets = [privateObjectInfo.allowedTicket];
198
+ attestations = allowedAttestations.filter(
199
+ (_, i) => i === privateObjectInfo.allowedIndex
200
+ );
201
+ } else {
202
+ recipients = [...object.allowed ?? []];
203
+ allowedTickets = privateObjectInfo.allowedTickets;
204
+ attestations = allowedAttestations;
205
+ }
206
+ if (recipients.length !== object.allowed?.length) {
207
+ throw new Error("Recipient count does not match object allowed list");
208
+ }
209
+ if (!recipients.every((r) => object.allowed?.includes(r))) {
210
+ throw new Error("Recipient not in object allowed list");
211
+ }
212
+ for (const [index, recipient] of recipients.entries()) {
213
+ const allowedTicket = allowedTickets.at(index);
214
+ const allowedAttestation = attestations.at(index);
215
+ if (!allowedTicket) {
216
+ throw new Error("Missing allowed ticket for recipient");
217
+ }
218
+ if (!allowedAttestation) {
219
+ throw new Error("Missing allowed attestation for recipient");
220
+ }
221
+ const isValid = await this.primitives.allowedAttestations.validate(
222
+ allowedAttestation,
223
+ recipient,
224
+ allowedTicket
225
+ );
226
+ if (!isValid) {
227
+ throw new Error("Invalid allowed attestation for recipient");
228
+ }
229
+ }
230
+ } else if (allowedAttestations) {
231
+ throw new Error("Object is private but no recipient info provided");
232
+ }
233
+ }
234
+ }
235
+ const VALUE_PROPERTY = "v";
236
+ const CHANNEL_ATTESTATIONS_PROPERTY = "c";
237
+ const ALLOWED_ATTESTATIONS_PROPERTY = "a";
238
+ const NONCE_PROPERTY = "n";
239
+ const Uint8ArraySchema = (0, import_mini.custom)(
240
+ (v) => v instanceof Uint8Array
241
+ );
242
+ const ObjectDataSchema = (0, import_mini.strictObject)({
243
+ [VALUE_PROPERTY]: (0, import_mini.looseObject)({}),
244
+ [CHANNEL_ATTESTATIONS_PROPERTY]: (0, import_mini.array)(Uint8ArraySchema),
245
+ [ALLOWED_ATTESTATIONS_PROPERTY]: (0, import_mini.optional)((0, import_mini.array)(Uint8ArraySchema)),
246
+ [NONCE_PROPERTY]: Uint8ArraySchema
247
+ });
248
+ const GRAFFITI_OBJECT_URL_PREFIX = "graffiti:";
249
+ function encodeObjectUrlComponent(value) {
250
+ const replaced = value.replace(/:/g, "!").replace(/\//g, "~");
251
+ return encodeURIComponent(replaced);
252
+ }
253
+ function decodeObjectUrlComponent(value) {
254
+ const decoded = decodeURIComponent(value);
255
+ return decoded.replace(/!/g, ":").replace(/~/g, "/");
256
+ }
257
+ function encodeObjectUrl(actor, contentAddress) {
258
+ return `${GRAFFITI_OBJECT_URL_PREFIX}${encodeObjectUrlComponent(actor)}:${encodeObjectUrlComponent(contentAddress)}`;
259
+ }
260
+ function decodeObjectUrl(objectUrl) {
261
+ if (!objectUrl.startsWith(GRAFFITI_OBJECT_URL_PREFIX)) {
262
+ throw new Error("Invalid object URL");
263
+ }
264
+ const rest = objectUrl.slice(GRAFFITI_OBJECT_URL_PREFIX.length);
265
+ const parts = rest.split(":");
266
+ if (parts.length !== 2) {
267
+ throw new Error("Invalid object URL format");
268
+ }
269
+ const [actor, contentAddress] = parts;
270
+ return {
271
+ actor: decodeObjectUrlComponent(actor),
272
+ contentAddress: decodeObjectUrlComponent(contentAddress)
273
+ };
274
+ }
275
+ function cleanUndefined(value) {
276
+ if (value === void 0) return null;
277
+ if (Array.isArray(value)) {
278
+ return value.map(cleanUndefined);
279
+ }
280
+ if (typeof value === "object") {
281
+ return Object.fromEntries(
282
+ Object.entries(value).filter(([, v]) => v !== void 0).map(([k, v]) => [k, cleanUndefined(v)])
283
+ );
284
+ }
285
+ return value;
286
+ }
287
+ //# sourceMappingURL=3-object-encoding.js.map