@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,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/3-protocol/3-object-encoding.ts"],
4
+ "sourcesContent": ["import type { JSONSchema } from \"json-schema-to-ts\";\nimport type {\n GraffitiObject,\n GraffitiObjectBase,\n GraffitiPostObject,\n} from \"@graffiti-garden/api\";\nimport type { ChannelAttestations } from \"../2-primitives/3-channel-attestations\";\nimport type { AllowedAttestations } from \"../2-primitives/4-allowed-attestations\";\nimport {\n CONTENT_ADDRESS_METHOD_SHA256,\n type ContentAddresses,\n} from \"../2-primitives/2-content-addresses\";\nimport { randomBytes } from \"@noble/hashes/utils.js\";\nimport {\n encode as dagCborEncode,\n decode as dagCborDecode,\n} from \"@ipld/dag-cbor\";\nimport {\n type infer as infer_,\n array,\n custom,\n looseObject,\n optional,\n strictObject,\n} from \"zod/mini\";\nimport { CHANNEL_ATTESTATION_METHOD_SHA256_ED25519 } from \"../2-primitives/3-channel-attestations\";\nimport { ALLOWED_ATTESTATION_METHOD_HMAC_SHA256 } from \"../2-primitives/4-allowed-attestations\";\nimport {\n STRING_ENCODER_METHOD_BASE64URL,\n type StringEncoder,\n} from \"../2-primitives/1-string-encoding\";\n\n// Objects have a max size of 32kb\n// If each channel and allowed actor takes 32 bytes\n// of space (i.e. they are hashed with 256 bit security)\n// then this means that the combined number of channels\n// and recipients of object has cannot exceed one thousand.\n// This seems like a reasonable limit and on par with\n// signal's group chat limit of 1000\nexport const MAX_OBJECT_SIZE_BYTES = 32 * 1024;\n\nexport class ObjectEncoding {\n constructor(\n protected readonly primitives: {\n readonly stringEncoder: StringEncoder;\n readonly channelAttestations: ChannelAttestations;\n readonly allowedAttestations: AllowedAttestations;\n readonly contentAddresses: ContentAddresses;\n },\n ) {}\n\n async encode<Schema extends JSONSchema>(\n partialObject: GraffitiPostObject<Schema>,\n actor: string,\n ): Promise<{\n object: GraffitiObject<Schema>;\n tags: Uint8Array[];\n objectBytes: Uint8Array;\n allowedTickets: Uint8Array[] | undefined;\n }> {\n // Clean out any undefineds\n partialObject = cleanUndefined(partialObject);\n\n // Create a verifiable attestation that the actor\n // knows the included channels without\n // directly revealing any channel to anyone who doesn't\n // know the channel already\n const channelAttestationAndPublicIds = await Promise.all(\n partialObject.channels.map((channel) =>\n this.primitives.channelAttestations.attest(\n // TODO: get this from the DID document of the actor\n CHANNEL_ATTESTATION_METHOD_SHA256_ED25519,\n actor,\n channel,\n ),\n ),\n );\n const channelAttestations = channelAttestationAndPublicIds.map(\n (c) => c.attestation,\n );\n const channelPublicIds = channelAttestationAndPublicIds.map(\n (c) => c.channelPublicId,\n );\n\n const objectData: infer_<typeof ObjectDataSchema> = {\n [VALUE_PROPERTY]: partialObject.value,\n [CHANNEL_ATTESTATIONS_PROPERTY]: channelAttestations,\n [NONCE_PROPERTY]: randomBytes(32),\n };\n\n let allowedTickets: Uint8Array[] | undefined = undefined;\n\n // If the object is private...\n if (Array.isArray(partialObject.allowed)) {\n // Create an attestation that the object's allowed list\n // includes the given actors, without revealing the\n // presence of an actor on the list to anyone except\n // that actor themselves. Each actor will receive a\n // \"ticket\" that they can use to verify their own membership\n // on the allowed list.\n const allowedAttestations = await Promise.all(\n partialObject.allowed.map(async (allowedActor) =>\n this.primitives.allowedAttestations.attest(\n // TODO: get this from the DID document of the actor\n ALLOWED_ATTESTATION_METHOD_HMAC_SHA256,\n allowedActor,\n ),\n ),\n );\n objectData[ALLOWED_ATTESTATIONS_PROPERTY] = allowedAttestations.map(\n (a) => a.attestation,\n );\n allowedTickets = allowedAttestations.map((a) => a.ticket);\n }\n\n // Encode the mixed JSON/binary data using CBOR\n const objectBytes = dagCborEncode(objectData);\n if (objectBytes.byteLength > MAX_OBJECT_SIZE_BYTES) {\n throw new Error(\"The object is too large\");\n }\n\n // Compute a public identifier (hash) of the object data\n const objectContentAddressBytes =\n await this.primitives.contentAddresses.register(\n // TODO: get this from the DID document of the actor\n CONTENT_ADDRESS_METHOD_SHA256,\n objectBytes,\n );\n const objectContentAddress = await this.primitives.stringEncoder.encode(\n STRING_ENCODER_METHOD_BASE64URL,\n objectContentAddressBytes,\n );\n // Use it to compute the object's URL\n const objectUrl = encodeObjectUrl(actor, objectContentAddress);\n\n const tags = [new TextEncoder().encode(objectUrl), ...channelPublicIds];\n\n const object: GraffitiObject<Schema> = {\n value: partialObject.value,\n channels: partialObject.channels,\n url: objectUrl,\n actor,\n ...(partialObject.allowed\n ? {\n allowed: partialObject.allowed,\n }\n : {}),\n } as GraffitiObject<Schema>;\n\n // Return object URL and allowed secrets\n return {\n object,\n tags,\n objectBytes,\n allowedTickets,\n };\n }\n\n async validate(\n object: GraffitiObjectBase,\n tags: Uint8Array[],\n objectBytes: Uint8Array,\n privateObjectInfo?:\n | {\n recipient: string;\n allowedTicket: Uint8Array;\n allowedIndex: number;\n }\n | {\n allowedTickets: Uint8Array[];\n },\n ): Promise<void> {\n if (objectBytes.byteLength > MAX_OBJECT_SIZE_BYTES) {\n throw new Error(\"Object is too big\");\n }\n const { actor, contentAddress } = decodeObjectUrl(object.url);\n if (actor !== object.actor) {\n throw new Error(\"Object actor does not match URL actor\");\n }\n\n const objectUrlTag = tags.at(0);\n if (!objectUrlTag) {\n throw new Error(\"No object URL tag\");\n }\n if (new TextDecoder().decode(objectUrlTag) !== object.url) {\n throw new Error(\"Object URL tag does not match object URL\");\n }\n const channelPublicIds = tags.slice(1);\n\n // Make sure the object content address matches the object content\n const contentAddressBytes =\n await this.primitives.stringEncoder.decode(contentAddress);\n const contentAddressMethod =\n await this.primitives.contentAddresses.getMethod(contentAddressBytes);\n const expectedContentAddress =\n await this.primitives.contentAddresses.register(\n contentAddressMethod,\n objectBytes,\n );\n if (\n expectedContentAddress.length !== contentAddressBytes.length ||\n !expectedContentAddress.every((b, i) => b === contentAddressBytes[i])\n ) {\n throw new Error(\"Content address is invalid\");\n }\n\n // Convert the raw object data from CBOR\n // back to a javascript object\n const objectDataUnknown = dagCborDecode(objectBytes);\n const objectData = ObjectDataSchema.parse(objectDataUnknown);\n\n // And extract the values\n const value = objectData[VALUE_PROPERTY];\n const channelAttestations = objectData[CHANNEL_ATTESTATIONS_PROPERTY];\n const allowedAttestations = objectData[ALLOWED_ATTESTATIONS_PROPERTY];\n\n // Validate that the object's value matches\n const valueBytes = dagCborEncode(value);\n const expectedValueBytes = dagCborEncode(object.value);\n if (\n valueBytes.length !== expectedValueBytes.length ||\n !valueBytes.every((b, i) => b === expectedValueBytes[i])\n ) {\n throw new Error(\"Object value does not match storage value\");\n }\n\n // Validate the object's channels\n if (channelAttestations.length !== channelPublicIds.length) {\n throw new Error(\"Not as many channel attestations and public ids\");\n }\n for (const [index, attestation] of channelAttestations.entries()) {\n const channelPublicId = channelPublicIds[index];\n const isValid = await this.primitives.channelAttestations.validate(\n attestation,\n actor,\n channelPublicId,\n );\n if (!isValid) {\n throw new Error(\"Invalid channel attestation\");\n }\n }\n if (object.channels.length) {\n // If any channels are included, they all must be included\n if (object.channels.length !== channelPublicIds.length) {\n throw new Error(\n \"Number of claimed channels does not match attestations/public IDs\",\n );\n }\n const channelAttestationMethod =\n await this.primitives.channelAttestations.getMethod(\n channelPublicIds[0],\n );\n const expectedChannelPublicIds = await Promise.all(\n object.channels.map((channel) =>\n this.primitives.channelAttestations.register(\n channelAttestationMethod,\n channel,\n ),\n ),\n );\n for (const [\n index,\n expectedPublicId,\n ] of expectedChannelPublicIds.entries()) {\n const actualPublicId = channelPublicIds[index];\n if (\n expectedPublicId.length !== actualPublicId.length ||\n !expectedPublicId.every((b, i) => b === actualPublicId[i])\n ) {\n throw new Error(\"Channel public id does not match expected\");\n }\n }\n }\n\n // Validate the recipient\n if (privateObjectInfo) {\n if (!allowedAttestations) {\n throw new Error(\"Object is public but thought to be private\");\n }\n\n let recipients: string[];\n let allowedTickets: Uint8Array[];\n let attestations: Uint8Array[];\n if (\"recipient\" in privateObjectInfo) {\n recipients = [privateObjectInfo.recipient];\n allowedTickets = [privateObjectInfo.allowedTicket];\n attestations = allowedAttestations.filter(\n (_, i) => i === privateObjectInfo.allowedIndex,\n );\n } else {\n recipients = [...(object.allowed ?? [])];\n allowedTickets = privateObjectInfo.allowedTickets;\n attestations = allowedAttestations;\n }\n\n // All recipients must be in the allowed list\n if (recipients.length !== object.allowed?.length) {\n throw new Error(\"Recipient count does not match object allowed list\");\n }\n if (!recipients.every((r) => object.allowed?.includes(r))) {\n throw new Error(\"Recipient not in object allowed list\");\n }\n\n for (const [index, recipient] of recipients.entries()) {\n const allowedTicket = allowedTickets.at(index);\n const allowedAttestation = attestations.at(index);\n if (!allowedTicket) {\n throw new Error(\"Missing allowed ticket for recipient\");\n }\n if (!allowedAttestation) {\n throw new Error(\"Missing allowed attestation for recipient\");\n }\n const isValid = await this.primitives.allowedAttestations.validate(\n allowedAttestation,\n recipient,\n allowedTicket,\n );\n\n if (!isValid) {\n throw new Error(\"Invalid allowed attestation for recipient\");\n }\n }\n } else if (allowedAttestations) {\n throw new Error(\"Object is private but no recipient info provided\");\n }\n }\n}\n\n// A compact data representation of the object data\nconst VALUE_PROPERTY = \"v\";\nconst CHANNEL_ATTESTATIONS_PROPERTY = \"c\";\nconst ALLOWED_ATTESTATIONS_PROPERTY = \"a\";\nconst NONCE_PROPERTY = \"n\";\n\nconst Uint8ArraySchema = custom<Uint8Array>(\n (v): v is Uint8Array => v instanceof Uint8Array,\n);\n\nconst ObjectDataSchema = strictObject({\n [VALUE_PROPERTY]: looseObject({}),\n [CHANNEL_ATTESTATIONS_PROPERTY]: array(Uint8ArraySchema),\n [ALLOWED_ATTESTATIONS_PROPERTY]: optional(array(Uint8ArraySchema)),\n [NONCE_PROPERTY]: Uint8ArraySchema,\n});\n\nexport const GRAFFITI_OBJECT_URL_PREFIX = \"graffiti:\";\n\n// Methods to encode and decode object URLs\nexport function encodeObjectUrlComponent(value: string) {\n const replaced = value.replace(/:/g, \"!\").replace(/\\//g, \"~\");\n return encodeURIComponent(replaced);\n}\nexport function decodeObjectUrlComponent(value: string) {\n const decoded = decodeURIComponent(value);\n return decoded.replace(/!/g, \":\").replace(/~/g, \"/\");\n}\nexport function encodeObjectUrl(actor: string, contentAddress: string) {\n return `${GRAFFITI_OBJECT_URL_PREFIX}${encodeObjectUrlComponent(actor)}:${encodeObjectUrlComponent(contentAddress)}`;\n}\nexport function decodeObjectUrl(objectUrl: string) {\n if (!objectUrl.startsWith(GRAFFITI_OBJECT_URL_PREFIX)) {\n throw new Error(\"Invalid object URL\");\n }\n\n const rest = objectUrl.slice(GRAFFITI_OBJECT_URL_PREFIX.length);\n const parts = rest.split(\":\");\n\n if (parts.length !== 2) {\n throw new Error(\"Invalid object URL format\");\n }\n\n const [actor, contentAddress] = parts;\n\n return {\n actor: decodeObjectUrlComponent(actor),\n contentAddress: decodeObjectUrlComponent(contentAddress),\n };\n}\n\nfunction cleanUndefined(value: any): any {\n if (value === undefined) return null;\n\n if (Array.isArray(value)) {\n return value.map(cleanUndefined);\n }\n\n if (typeof value === \"object\") {\n return Object.fromEntries(\n Object.entries(value)\n .filter(([, v]) => v !== undefined)\n .map(([k, v]) => [k, cleanUndefined(v)]),\n );\n }\n\n return value;\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["dagCborEncode", "dagCborDecode"]
7
+ }