@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,937 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+ var graffiti_exports = {};
30
+ __export(graffiti_exports, {
31
+ GraffitiDecentralized: () => GraffitiDecentralized
32
+ });
33
+ module.exports = __toCommonJS(graffiti_exports);
34
+ var import_api = require("@graffiti-garden/api");
35
+ var import_utils = require("@noble/hashes/utils.js");
36
+ var import_dag_cbor = require("@ipld/dag-cbor");
37
+ var import_dids = require("../1-services/2-dids");
38
+ var import_authorization = require("../1-services/1-authorization");
39
+ var import_storage_buckets = require("../1-services/3-storage-buckets");
40
+ var import_inboxes = require("../1-services/4-inboxes");
41
+ var import_string_encoding = require("../2-primitives/1-string-encoding");
42
+ var import_content_addresses = require("../2-primitives/2-content-addresses");
43
+ var import_channel_attestations = require("../2-primitives/3-channel-attestations");
44
+ var import_allowed_attestations = require("../2-primitives/4-allowed-attestations");
45
+ var import_handles = require("./2-handles");
46
+ var import_sessions = require("./1-sessions");
47
+ var import_object_encoding = require("./3-object-encoding");
48
+ var import_modal = require("@graffiti-garden/modal");
49
+ var import_mini = require("zod/mini");
50
+ const Uint8ArraySchema = (0, import_mini.custom)(
51
+ (v) => v instanceof Uint8Array
52
+ );
53
+ const MESSAGE_DATA_STORAGE_BUCKET_KEY = "k";
54
+ const MESSAGE_DATA_TOMBSTONED_MESSAGE_ID_KEY = "t";
55
+ const MessageMetadataBaseSchema = (0, import_mini.strictObject)({
56
+ [MESSAGE_DATA_STORAGE_BUCKET_KEY]: (0, import_mini.string)(),
57
+ [MESSAGE_DATA_TOMBSTONED_MESSAGE_ID_KEY]: (0, import_mini.optional)((0, import_mini.string)())
58
+ });
59
+ const MESSAGE_DATA_ANNOUNCEMENT_MESSAGE_ID_KEY = "id";
60
+ const MESSAGE_DATA_ANNOUNCEMENT_ENDPOINT_KEY = "e";
61
+ const MESSAGE_DATA_ANNOUNCEMENT_ACTOR_KEY = "a";
62
+ const MessageMetadataAnnouncementsSchema = (0, import_mini.array)(
63
+ (0, import_mini.strictObject)({
64
+ [MESSAGE_DATA_ANNOUNCEMENT_MESSAGE_ID_KEY]: (0, import_mini.string)(),
65
+ [MESSAGE_DATA_ANNOUNCEMENT_ENDPOINT_KEY]: (0, import_mini.optional)((0, import_mini.url)()),
66
+ [MESSAGE_DATA_ANNOUNCEMENT_ACTOR_KEY]: (0, import_mini.optional)((0, import_mini.url)())
67
+ })
68
+ );
69
+ const MESSAGE_DATA_ALLOWED_TICKETS_KEY = "s";
70
+ const MESSAGE_DATA_ANNOUNCEMENTS_KEY = "n";
71
+ const MessageMetaDataSelfSchema = (0, import_mini.extend)(MessageMetadataBaseSchema, {
72
+ [MESSAGE_DATA_ALLOWED_TICKETS_KEY]: (0, import_mini.optional)((0, import_mini.array)(Uint8ArraySchema)),
73
+ [MESSAGE_DATA_ANNOUNCEMENTS_KEY]: MessageMetadataAnnouncementsSchema
74
+ });
75
+ const MESSAGE_DATA_ALLOWED_TICKET_KEY = "a";
76
+ const MESSAGE_DATA_ALLOWED_TICKET_INDEX_KEY = "i";
77
+ const MessageMetadataPrivateSchema = (0, import_mini.extend)(MessageMetadataBaseSchema, {
78
+ [MESSAGE_DATA_ALLOWED_TICKET_KEY]: Uint8ArraySchema,
79
+ [MESSAGE_DATA_ALLOWED_TICKET_INDEX_KEY]: (0, import_mini.int)().check((0, import_mini.nonnegative)())
80
+ });
81
+ const MessageMetadataSchema = (0, import_mini.union)([
82
+ MessageMetadataBaseSchema,
83
+ MessageMetaDataSelfSchema,
84
+ MessageMetadataPrivateSchema
85
+ ]);
86
+ const MESSAGE_LABEL_UNLABELED = 0;
87
+ const MESSAGE_LABEL_VALID = 1;
88
+ const MESSAGE_LABEL_TRASH = 2;
89
+ const MESSAGE_LABEL_INVALID = 3;
90
+ class GraffitiDecentralized {
91
+ dids = new import_dids.DecentralizedIdentifiers();
92
+ authorization = new import_authorization.Authorization();
93
+ storageBuckets = new import_storage_buckets.StorageBuckets();
94
+ inboxes = new import_inboxes.Inboxes();
95
+ stringEncoder = new import_string_encoding.StringEncoder();
96
+ contentAddresses = new import_content_addresses.ContentAddresses();
97
+ channelAttestations = new import_channel_attestations.ChannelAttestations();
98
+ allowedAttestations = new import_allowed_attestations.AllowedAttestations();
99
+ sessions = new import_sessions.Sessions({
100
+ dids: this.dids,
101
+ authorization: this.authorization,
102
+ storageBuckets: this.storageBuckets,
103
+ inboxes: this.inboxes
104
+ });
105
+ handles = new import_handles.Handles({ dids: this.dids });
106
+ objectEncoding = new import_object_encoding.ObjectEncoding({
107
+ stringEncoder: this.stringEncoder,
108
+ contentAddresses: this.contentAddresses,
109
+ channelAttestations: this.channelAttestations,
110
+ allowedAttestations: this.allowedAttestations
111
+ });
112
+ modal = typeof window === "undefined" ? void 0 : new import_modal.GraffitiModal({
113
+ useTemplateHTML: () => import("./login-dialog.html").then(({ template }) => template),
114
+ onManualClose: () => {
115
+ const event = new CustomEvent("login", {
116
+ detail: {
117
+ error: new Error("User cancelled login"),
118
+ manual: true
119
+ }
120
+ });
121
+ this.sessionEvents.dispatchEvent(event);
122
+ }
123
+ });
124
+ defaultInboxEndpoints;
125
+ identityCreatorEndpoint;
126
+ constructor(options) {
127
+ this.defaultInboxEndpoints = options?.defaultInboxEndpoints ?? [
128
+ "https://graffiti.actor/i/shared"
129
+ ];
130
+ this.identityCreatorEndpoint = options?.identityCreatorEndpoint ?? "https://graffiti.actor/create";
131
+ this.sessionEvents.addEventListener("login", async (event) => {
132
+ if (!(event instanceof CustomEvent)) return;
133
+ const detail = event.detail;
134
+ if (detail.error !== void 0 && !("manual" in detail && detail.manual)) {
135
+ alert("Login failed: " + detail.error.message);
136
+ const actor = detail.session?.actor;
137
+ let handle;
138
+ if (actor) {
139
+ try {
140
+ handle = await this.actorToHandle(actor);
141
+ } catch (error) {
142
+ console.error("Failed to handle actor:", error);
143
+ }
144
+ }
145
+ this.login_(handle);
146
+ }
147
+ });
148
+ }
149
+ actorToHandle = this.handles.actorToHandle.bind(this.handles);
150
+ handleToActor = this.handles.handleToActor.bind(this.handles);
151
+ sessionEvents = this.sessions.sessionEvents;
152
+ login = async (actor) => {
153
+ try {
154
+ let proposedHandle;
155
+ try {
156
+ proposedHandle = actor ? await this.actorToHandle(actor) : void 0;
157
+ } catch (error) {
158
+ console.error("Error fetching handle for actor:", error);
159
+ }
160
+ await this.login_(proposedHandle);
161
+ } catch (e) {
162
+ const loginError = new CustomEvent("login", {
163
+ detail: {
164
+ error: e instanceof Error ? e : new Error(String(e))
165
+ }
166
+ });
167
+ this.sessionEvents.dispatchEvent(loginError);
168
+ }
169
+ };
170
+ async login_(proposedHandle) {
171
+ if (typeof window !== "undefined") {
172
+ let template;
173
+ if (proposedHandle !== void 0) {
174
+ template = await this.modal?.displayTemplate("graffiti-login-handle");
175
+ const input = template?.querySelector(
176
+ "#username"
177
+ );
178
+ input?.setAttribute("value", proposedHandle);
179
+ input?.addEventListener("focus", () => input?.select());
180
+ new Promise((r) => {
181
+ setTimeout(() => r(), 0);
182
+ }).then(() => {
183
+ input?.focus();
184
+ });
185
+ template?.querySelector("#graffiti-login-handle-form")?.addEventListener("submit", async (e) => {
186
+ e.preventDefault();
187
+ input?.setAttribute("disabled", "true");
188
+ const submitButton = template?.querySelector(
189
+ "#graffiti-login-handle-submit"
190
+ );
191
+ submitButton?.setAttribute("disabled", "true");
192
+ submitButton && (submitButton.innerHTML = "Logging in...");
193
+ if (!input?.value) {
194
+ alert("No handle provided");
195
+ this.login_("");
196
+ return;
197
+ }
198
+ let handle = input.value;
199
+ if (!handle.includes(".") && !handle.startsWith("localhost")) {
200
+ const defaultHost = new URL(this.identityCreatorEndpoint).host;
201
+ handle = `${handle}.${defaultHost}`;
202
+ }
203
+ let actor;
204
+ try {
205
+ actor = await this.handleToActor(handle);
206
+ } catch (e2) {
207
+ alert("Could not find an identity associated with that handle.");
208
+ this.login_(handle);
209
+ return;
210
+ }
211
+ try {
212
+ await this.sessions.login(actor);
213
+ } catch (e2) {
214
+ alert("Error logging in.");
215
+ console.error(e2);
216
+ this.login_(handle);
217
+ }
218
+ });
219
+ } else {
220
+ template = await this.modal?.displayTemplate("graffiti-login-welcome");
221
+ template?.querySelector("#graffiti-login-existing")?.addEventListener("click", (e) => {
222
+ e.preventDefault();
223
+ this.login_("");
224
+ });
225
+ new Promise((r) => {
226
+ setTimeout(() => r(), 0);
227
+ }).then(() => {
228
+ template?.querySelector("#graffiti-login-new")?.focus();
229
+ });
230
+ }
231
+ const createUrl = new URL(this.identityCreatorEndpoint);
232
+ createUrl.searchParams.set(
233
+ "redirect_uri",
234
+ encodeURIComponent(window.location.toString())
235
+ );
236
+ template?.querySelector("#graffiti-login-new")?.setAttribute("href", createUrl.toString());
237
+ await this.modal?.open();
238
+ } else {
239
+ const readline = await import("readline").catch((e) => {
240
+ throw new Error(
241
+ "Unrecognized environment: neither window nor readline"
242
+ );
243
+ });
244
+ console.log(
245
+ "If you do not already have a Graffiti handle, you can create one here:"
246
+ );
247
+ console.log(this.identityCreatorEndpoint);
248
+ const rl = readline.createInterface({
249
+ input: process.stdin,
250
+ output: process.stdout
251
+ });
252
+ const handle = await new Promise((resolve) => {
253
+ rl.question(
254
+ `Please enter your handle${proposedHandle ? ` (default: ${proposedHandle})` : ""}: `,
255
+ (input) => {
256
+ rl.close();
257
+ resolve(input || proposedHandle);
258
+ }
259
+ );
260
+ });
261
+ if (!handle) {
262
+ throw new Error("No handle provided");
263
+ }
264
+ const actor = await this.handleToActor(handle);
265
+ await this.sessions.login(actor);
266
+ }
267
+ }
268
+ logout = async (session) => {
269
+ await this.sessions.logout(session.actor);
270
+ };
271
+ // @ts-ignore
272
+ post = async (...args) => {
273
+ const [partialObject, session] = args;
274
+ const resolvedSession = this.sessions.resolveSession(session);
275
+ const { object, tags, objectBytes, allowedTickets } = await this.objectEncoding.encode(partialObject, session.actor);
276
+ const storageBucketKeyBytes = (0, import_utils.randomBytes)();
277
+ const storageBucketKey = await this.stringEncoder.encode(
278
+ import_string_encoding.STRING_ENCODER_METHOD_BASE64URL,
279
+ storageBucketKeyBytes
280
+ );
281
+ await this.storageBuckets.put(
282
+ resolvedSession.storageBucket.serviceEndpoint,
283
+ storageBucketKey,
284
+ objectBytes,
285
+ resolvedSession.storageBucket.token
286
+ );
287
+ await this.announceObject(
288
+ object,
289
+ tags,
290
+ allowedTickets,
291
+ storageBucketKey,
292
+ session
293
+ );
294
+ return object;
295
+ };
296
+ get = async (...args) => {
297
+ const [url2, schema, session] = args;
298
+ let services;
299
+ const validator = await (0, import_api.compileGraffitiObjectSchema)(schema);
300
+ if (session) {
301
+ const resolvedSession = this.sessions.resolveSession(session);
302
+ services = [
303
+ resolvedSession.personalInbox,
304
+ ...resolvedSession.sharedInboxes
305
+ ];
306
+ } else {
307
+ services = this.defaultInboxEndpoints.map((s) => ({
308
+ serviceEndpoint: s
309
+ }));
310
+ }
311
+ const objectUrl = (0, import_api.unpackObjectUrl)(url2);
312
+ const tags = [new TextEncoder().encode(objectUrl)];
313
+ for (const service of services) {
314
+ let object = void 0;
315
+ const iterator = this.querySingleEndpoint(
316
+ service.serviceEndpoint,
317
+ {
318
+ tags,
319
+ objectSchema: {}
320
+ },
321
+ service.token,
322
+ session?.actor
323
+ );
324
+ for await (const result of iterator) {
325
+ if (result.object.url !== objectUrl) continue;
326
+ if (result.tombstone) {
327
+ object = void 0;
328
+ } else {
329
+ object = result.object;
330
+ }
331
+ }
332
+ if (object) {
333
+ if (!validator(object)) {
334
+ throw new import_api.GraffitiErrorSchemaMismatch(
335
+ "Object exists but does not match the supplied schema"
336
+ );
337
+ }
338
+ return object;
339
+ }
340
+ }
341
+ throw new import_api.GraffitiErrorNotFound("Object not found");
342
+ };
343
+ delete = async (url2, session) => {
344
+ const resolvedSession = this.sessions.resolveSession(session);
345
+ const objectUrl = (0, import_api.unpackObjectUrl)(url2);
346
+ const { actor } = (0, import_object_encoding.decodeObjectUrl)(objectUrl);
347
+ if (actor !== session.actor) {
348
+ throw new import_api.GraffitiErrorForbidden("Cannot delete someone else's actor");
349
+ }
350
+ const iterator = this.querySingleEndpoint(
351
+ resolvedSession.personalInbox.serviceEndpoint,
352
+ {
353
+ tags: [new TextEncoder().encode(objectUrl)],
354
+ objectSchema: {}
355
+ },
356
+ resolvedSession.personalInbox.token
357
+ );
358
+ let existing;
359
+ for await (const result of iterator) {
360
+ if (result.object.url !== objectUrl) continue;
361
+ if (result.tombstone) {
362
+ existing = void 0;
363
+ } else {
364
+ existing = result;
365
+ }
366
+ }
367
+ if (!existing) {
368
+ throw new import_api.GraffitiErrorNotFound(`Object ${objectUrl} not found`);
369
+ }
370
+ const {
371
+ object,
372
+ storageBucketKey,
373
+ tags,
374
+ allowedTickets,
375
+ announcements,
376
+ messageId
377
+ } = existing;
378
+ await this.storageBuckets.delete(
379
+ resolvedSession.storageBucket.serviceEndpoint,
380
+ storageBucketKey,
381
+ resolvedSession.storageBucket.token
382
+ );
383
+ await this.announceObject(
384
+ object,
385
+ tags,
386
+ allowedTickets,
387
+ storageBucketKey,
388
+ session,
389
+ [
390
+ ...announcements ?? [],
391
+ // Make sure we delete from our own inbox too
392
+ {
393
+ [MESSAGE_DATA_ANNOUNCEMENT_ACTOR_KEY]: session.actor,
394
+ [MESSAGE_DATA_ANNOUNCEMENT_MESSAGE_ID_KEY]: messageId
395
+ }
396
+ ]
397
+ );
398
+ return object;
399
+ };
400
+ postMedia = async (...args) => {
401
+ const [media, session] = args;
402
+ const type = media.data.type;
403
+ const resolvedSession = this.sessions.resolveSession(session);
404
+ const keyBytes = (0, import_utils.randomBytes)();
405
+ const key = await this.stringEncoder.encode(
406
+ import_string_encoding.STRING_ENCODER_METHOD_BASE64URL,
407
+ keyBytes
408
+ );
409
+ await this.storageBuckets.put(
410
+ resolvedSession.storageBucket.serviceEndpoint,
411
+ key,
412
+ new Uint8Array(await media.data.arrayBuffer()),
413
+ resolvedSession.storageBucket.token
414
+ );
415
+ const { url: url2 } = await this.post(
416
+ {
417
+ value: {
418
+ key,
419
+ type,
420
+ size: media.data.size
421
+ },
422
+ channels: [],
423
+ allowed: media.allowed
424
+ },
425
+ session
426
+ );
427
+ return url2;
428
+ };
429
+ getMedia = async (...args) => {
430
+ const [mediaUrl, accept, session] = args;
431
+ const object = await this.get(
432
+ mediaUrl,
433
+ MEDIA_OBJECT_SCHEMA,
434
+ session
435
+ );
436
+ const { key, type, size } = object.value;
437
+ if (accept?.maxBytes && size > accept.maxBytes) {
438
+ throw new import_api.GraffitiErrorTooLarge("File size exceeds limit");
439
+ }
440
+ if (accept?.types) {
441
+ if (!(0, import_api.isMediaAcceptable)(type, accept.types)) {
442
+ throw new import_api.GraffitiErrorNotAcceptable(
443
+ `Unacceptable media type, ${type}`
444
+ );
445
+ }
446
+ }
447
+ const actorDocument = await this.dids.resolve(object.actor);
448
+ const storageBucketService = actorDocument?.service?.find(
449
+ (service) => service.id === import_sessions.DID_SERVICE_ID_GRAFFITI_STORAGE_BUCKET && service.type === import_sessions.DID_SERVICE_TYPE_GRAFFITI_STORAGE_BUCKET
450
+ );
451
+ if (!storageBucketService) {
452
+ throw new import_api.GraffitiErrorNotFound(
453
+ `Actor ${object.actor} has no storage bucket service`
454
+ );
455
+ }
456
+ if (typeof storageBucketService.serviceEndpoint !== "string") {
457
+ throw new import_api.GraffitiErrorNotFound(
458
+ `Actor ${object.actor} does not have a valid storage bucket endpoint`
459
+ );
460
+ }
461
+ const storageBucketEndpoint = storageBucketService.serviceEndpoint;
462
+ const data = await this.storageBuckets.get(
463
+ storageBucketEndpoint,
464
+ key,
465
+ size
466
+ );
467
+ const blob = new Blob([data.slice()], { type });
468
+ return {
469
+ data: blob,
470
+ actor: object.actor,
471
+ allowed: object.allowed
472
+ };
473
+ };
474
+ deleteMedia = async (...args) => {
475
+ const [mediaUrl, session] = args;
476
+ const resolvedSession = this.sessions.resolveSession(session);
477
+ const result = await this.delete(mediaUrl, session);
478
+ if (!("key" in result.value && typeof result.value.key === "string"))
479
+ throw new Error(
480
+ "Deleted object was not media: " + JSON.stringify(result, null, 2)
481
+ );
482
+ await this.storageBuckets.delete(
483
+ resolvedSession.storageBucket.serviceEndpoint,
484
+ result.value.key,
485
+ resolvedSession.storageBucket.token
486
+ );
487
+ };
488
+ async *discoverMeta(channels, schema, cursors, session) {
489
+ const tombstones = /* @__PURE__ */ new Map();
490
+ let allInboxes;
491
+ if (session) {
492
+ const resolvedSession = this.sessions.resolveSession(session);
493
+ allInboxes = [
494
+ resolvedSession.personalInbox,
495
+ ...resolvedSession.sharedInboxes
496
+ ];
497
+ } else {
498
+ allInboxes = this.defaultInboxEndpoints.map((e) => ({
499
+ serviceEndpoint: e
500
+ }));
501
+ }
502
+ for (const endpoint in cursors) {
503
+ if (!allInboxes.some((i) => i.serviceEndpoint === endpoint)) {
504
+ throw new import_api.GraffitiErrorForbidden(
505
+ "Cursor does not match actor's inboxes"
506
+ );
507
+ }
508
+ }
509
+ const tags = await Promise.all(
510
+ channels.map(
511
+ (c) => this.channelAttestations.register(
512
+ import_channel_attestations.CHANNEL_ATTESTATION_METHOD_SHA256_ED25519,
513
+ c
514
+ )
515
+ )
516
+ );
517
+ const iterators = allInboxes.map(
518
+ (i) => {
519
+ const cursor = cursors[i.serviceEndpoint];
520
+ return this.querySingleEndpoint(
521
+ i.serviceEndpoint,
522
+ cursor ? {
523
+ cursor
524
+ } : {
525
+ tags,
526
+ objectSchema: schema
527
+ },
528
+ i.token,
529
+ session?.actor
530
+ );
531
+ }
532
+ );
533
+ let indexedIteratorNexts = iterators.map(async (it, index) => indexedSingleEndpointQueryNext(it, index));
534
+ let active = indexedIteratorNexts.length;
535
+ while (active > 0) {
536
+ const next = await Promise.race(indexedIteratorNexts);
537
+ if (next.error !== void 0) {
538
+ indexedIteratorNexts[next.index] = new Promise(() => {
539
+ });
540
+ active--;
541
+ yield {
542
+ error: next.error,
543
+ origin: allInboxes[next.index].serviceEndpoint
544
+ };
545
+ } else if (next.result.done) {
546
+ const inbox = allInboxes[next.index];
547
+ cursors[inbox.serviceEndpoint] = next.result.value;
548
+ indexedIteratorNexts[next.index] = new Promise(() => {
549
+ });
550
+ active--;
551
+ } else {
552
+ indexedIteratorNexts[next.index] = indexedSingleEndpointQueryNext(
553
+ iterators[next.index],
554
+ next.index
555
+ );
556
+ const { object, tombstone, tags: receivedTags } = next.result.value;
557
+ if (tombstone) {
558
+ if (tombstones.get(object.url) === true) continue;
559
+ tombstones.set(object.url, true);
560
+ yield {
561
+ tombstone,
562
+ object: { url: object.url }
563
+ };
564
+ } else {
565
+ if (tombstones.get(object.url) === false) continue;
566
+ const matchedTagIndices = tags.reduce(
567
+ (acc, tag, tagIndex) => {
568
+ for (const receivedTag of receivedTags) {
569
+ if (tag.length === receivedTag.length && tag.every((b, i) => receivedTag[i] === b)) {
570
+ acc.push(tagIndex);
571
+ break;
572
+ }
573
+ }
574
+ return acc;
575
+ },
576
+ []
577
+ );
578
+ const matchedChannels = matchedTagIndices.map(
579
+ (index) => channels[index]
580
+ );
581
+ if (matchedChannels.length === 0) {
582
+ yield {
583
+ error: new Error(
584
+ "Inbox returned object without matching channels"
585
+ ),
586
+ origin: allInboxes[next.index].serviceEndpoint
587
+ };
588
+ }
589
+ tombstones.set(object.url, false);
590
+ yield {
591
+ object: {
592
+ ...object,
593
+ channels: matchedChannels
594
+ }
595
+ };
596
+ }
597
+ }
598
+ }
599
+ return {
600
+ cursor: JSON.stringify({
601
+ channels,
602
+ cursors
603
+ }),
604
+ continue: (session2) => this.discoverMeta(channels, schema, cursors, session2)
605
+ };
606
+ }
607
+ discover = (...args) => {
608
+ const [channels, schema, session] = args;
609
+ return this.discoverMeta(channels, schema, {}, session);
610
+ };
611
+ continueDiscover = (...args) => {
612
+ const [cursor, session] = args;
613
+ let channels;
614
+ let cursors;
615
+ try {
616
+ const json = JSON.parse(cursor);
617
+ const parsed = CursorSchema.parse(json);
618
+ channels = parsed.channels;
619
+ cursors = parsed.cursors;
620
+ } catch (error) {
621
+ return (async function* () {
622
+ throw new import_api.GraffitiErrorCursorExpired("Invalid cursor");
623
+ })();
624
+ }
625
+ return this.discoverMeta(channels, {}, cursors, session);
626
+ };
627
+ async announceObject(object, tags, allowedTickets, storageBucketKey, session, priorAnnouncements) {
628
+ const resolvedSession = this.sessions.resolveSession(session);
629
+ const metadataBase = {
630
+ [MESSAGE_DATA_STORAGE_BUCKET_KEY]: storageBucketKey
631
+ };
632
+ const announcements = [];
633
+ const allowed = object.allowed;
634
+ if (Array.isArray(allowed)) {
635
+ if (!allowedTickets || allowedTickets.length !== allowed.length) {
636
+ throw new Error(
637
+ "If allowed actors are specified, there must be a corresponding ticket for each allowed actor"
638
+ );
639
+ }
640
+ const results = await Promise.allSettled(
641
+ allowed.map(async (recipient, recipientIndex) => {
642
+ const copy = JSON.parse(JSON.stringify(object));
643
+ const masked = (0, import_api.maskGraffitiObject)(copy, [], recipient);
644
+ const actorDocument = await this.dids.resolve(recipient);
645
+ const personalInbox = actorDocument.service?.find(
646
+ (service) => service.type === import_sessions.DID_SERVICE_TYPE_GRAFFITI_INBOX && service.id === import_sessions.DID_SERVICE_ID_GRAFFITI_PERSONAL_INBOX
647
+ );
648
+ if (!personalInbox) {
649
+ throw new Error(
650
+ `Recipient ${recipient} does not have a personal inbox`
651
+ );
652
+ }
653
+ if (typeof personalInbox.serviceEndpoint !== "string") {
654
+ throw new Error(
655
+ `Recipient ${recipient} does not have a valid personal inbox endpoint`
656
+ );
657
+ }
658
+ const tombstonedMessageId2 = priorAnnouncements ? priorAnnouncements.find(
659
+ (a) => a[MESSAGE_DATA_ANNOUNCEMENT_ACTOR_KEY] === recipient
660
+ )?.[MESSAGE_DATA_ANNOUNCEMENT_MESSAGE_ID_KEY] : void 0;
661
+ const privateMetadata = {
662
+ ...metadataBase,
663
+ ...tombstonedMessageId2 ? {
664
+ [MESSAGE_DATA_TOMBSTONED_MESSAGE_ID_KEY]: tombstonedMessageId2
665
+ } : {},
666
+ [MESSAGE_DATA_ALLOWED_TICKET_KEY]: allowedTickets[recipientIndex],
667
+ [MESSAGE_DATA_ALLOWED_TICKET_INDEX_KEY]: recipientIndex
668
+ };
669
+ const messageId = await this.inboxes.send(
670
+ personalInbox.serviceEndpoint,
671
+ {
672
+ [import_inboxes.MESSAGE_TAGS_KEY]: tags,
673
+ [import_inboxes.MESSAGE_OBJECT_KEY]: masked,
674
+ [import_inboxes.MESSAGE_METADATA_KEY]: (0, import_dag_cbor.encode)(privateMetadata)
675
+ }
676
+ );
677
+ announcements.push({
678
+ [MESSAGE_DATA_ANNOUNCEMENT_MESSAGE_ID_KEY]: messageId,
679
+ [MESSAGE_DATA_ANNOUNCEMENT_ACTOR_KEY]: recipient
680
+ });
681
+ })
682
+ );
683
+ for (const [index, result] of results.entries()) {
684
+ if (result.status === "rejected") {
685
+ const recipient = allowed[index];
686
+ console.error("Error sending to recipient:", recipient);
687
+ console.error(result.reason);
688
+ }
689
+ }
690
+ } else {
691
+ const copy = JSON.parse(JSON.stringify(object));
692
+ const masked = (0, import_api.maskGraffitiObject)(copy, []);
693
+ const sharedInboxes = resolvedSession.sharedInboxes;
694
+ const results = await Promise.allSettled(
695
+ sharedInboxes.map(async (inbox) => {
696
+ const tombstonedMessageId2 = priorAnnouncements ? priorAnnouncements.find(
697
+ (a) => a[MESSAGE_DATA_ANNOUNCEMENT_ENDPOINT_KEY] === inbox.serviceEndpoint
698
+ )?.[MESSAGE_DATA_ANNOUNCEMENT_MESSAGE_ID_KEY] : void 0;
699
+ const metadata = {
700
+ ...metadataBase,
701
+ ...tombstonedMessageId2 ? {
702
+ [MESSAGE_DATA_TOMBSTONED_MESSAGE_ID_KEY]: tombstonedMessageId2
703
+ } : {}
704
+ };
705
+ const messageId = await this.inboxes.send(inbox.serviceEndpoint, {
706
+ ...tombstonedMessageId2 ? {
707
+ [MESSAGE_DATA_TOMBSTONED_MESSAGE_ID_KEY]: tombstonedMessageId2
708
+ } : {},
709
+ [import_inboxes.MESSAGE_TAGS_KEY]: tags,
710
+ [import_inboxes.MESSAGE_OBJECT_KEY]: masked,
711
+ [import_inboxes.MESSAGE_METADATA_KEY]: (0, import_dag_cbor.encode)(metadata)
712
+ });
713
+ announcements.push({
714
+ [MESSAGE_DATA_ANNOUNCEMENT_MESSAGE_ID_KEY]: messageId,
715
+ [MESSAGE_DATA_ANNOUNCEMENT_ENDPOINT_KEY]: inbox.serviceEndpoint
716
+ });
717
+ })
718
+ );
719
+ for (const [index, result] of results.entries()) {
720
+ if (result.status === "rejected") {
721
+ const inbox = sharedInboxes[index];
722
+ console.error("Error sending to inbox:", inbox);
723
+ console.error(result.reason);
724
+ }
725
+ }
726
+ }
727
+ const tombstonedMessageId = priorAnnouncements ? priorAnnouncements.find(
728
+ (a) => a[MESSAGE_DATA_ANNOUNCEMENT_ACTOR_KEY] === session.actor
729
+ )?.[MESSAGE_DATA_ANNOUNCEMENT_MESSAGE_ID_KEY] : void 0;
730
+ const selfMetadata = {
731
+ ...metadataBase,
732
+ ...allowedTickets ? {
733
+ [MESSAGE_DATA_ALLOWED_TICKETS_KEY]: allowedTickets
734
+ } : {},
735
+ ...tombstonedMessageId ? {
736
+ [MESSAGE_DATA_TOMBSTONED_MESSAGE_ID_KEY]: tombstonedMessageId
737
+ } : {},
738
+ [MESSAGE_DATA_ANNOUNCEMENTS_KEY]: announcements
739
+ };
740
+ await this.inboxes.send(resolvedSession.personalInbox.serviceEndpoint, {
741
+ [import_inboxes.MESSAGE_TAGS_KEY]: tags,
742
+ [import_inboxes.MESSAGE_OBJECT_KEY]: object,
743
+ [import_inboxes.MESSAGE_METADATA_KEY]: (0, import_dag_cbor.encode)(selfMetadata)
744
+ });
745
+ }
746
+ async *querySingleEndpoint(inboxEndpoint, queryArguments, inboxToken, recipient) {
747
+ const iterator = "tags" in queryArguments ? this.inboxes.query(
748
+ inboxEndpoint,
749
+ queryArguments.tags,
750
+ queryArguments.objectSchema,
751
+ inboxToken
752
+ ) : this.inboxes.continueQuery(
753
+ inboxEndpoint,
754
+ queryArguments.cursor,
755
+ inboxToken
756
+ );
757
+ while (true) {
758
+ const itResult = await iterator.next();
759
+ if (itResult.done) return itResult.value;
760
+ const result = itResult.value;
761
+ const label = result.l;
762
+ if (label !== MESSAGE_LABEL_VALID && label !== MESSAGE_LABEL_UNLABELED)
763
+ continue;
764
+ const messageId = result.id;
765
+ const { o: object, m: metadataBytes, t: receivedTags } = result.m;
766
+ let metadata;
767
+ try {
768
+ const metadataRaw = (0, import_dag_cbor.decode)(metadataBytes);
769
+ metadata = MessageMetadataSchema.parse(metadataRaw);
770
+ } catch (e) {
771
+ this.inboxes.label(
772
+ inboxEndpoint,
773
+ messageId,
774
+ MESSAGE_LABEL_INVALID,
775
+ inboxToken
776
+ );
777
+ continue;
778
+ }
779
+ const {
780
+ [MESSAGE_DATA_STORAGE_BUCKET_KEY]: storageBucketKey,
781
+ [MESSAGE_DATA_TOMBSTONED_MESSAGE_ID_KEY]: tombstonedMessageId
782
+ } = metadata;
783
+ const allowedTickets = MESSAGE_DATA_ALLOWED_TICKETS_KEY in metadata ? metadata[MESSAGE_DATA_ALLOWED_TICKETS_KEY] : void 0;
784
+ const announcements = MESSAGE_DATA_ANNOUNCEMENTS_KEY in metadata ? metadata[MESSAGE_DATA_ANNOUNCEMENTS_KEY] : void 0;
785
+ if (label === MESSAGE_LABEL_VALID) {
786
+ yield {
787
+ messageId,
788
+ object,
789
+ storageBucketKey,
790
+ allowedTickets,
791
+ tags: receivedTags,
792
+ announcements
793
+ };
794
+ continue;
795
+ }
796
+ let validationError = void 0;
797
+ try {
798
+ const actor = object.actor;
799
+ const actorDocument = await this.dids.resolve(actor);
800
+ const storageBucketService = actorDocument?.service?.find(
801
+ (service) => service.id === import_sessions.DID_SERVICE_ID_GRAFFITI_STORAGE_BUCKET && service.type === import_sessions.DID_SERVICE_TYPE_GRAFFITI_STORAGE_BUCKET
802
+ );
803
+ if (!storageBucketService) {
804
+ throw new import_api.GraffitiErrorNotFound(
805
+ `Actor ${actor} has no storage bucket service`
806
+ );
807
+ }
808
+ if (typeof storageBucketService.serviceEndpoint !== "string") {
809
+ throw new import_api.GraffitiErrorNotFound(
810
+ `Actor ${actor} does not have a valid storage bucket endpoint`
811
+ );
812
+ }
813
+ const storageBucketEndpoint = storageBucketService.serviceEndpoint;
814
+ const objectBytes = await this.storageBuckets.get(
815
+ storageBucketEndpoint,
816
+ storageBucketKey,
817
+ import_object_encoding.MAX_OBJECT_SIZE_BYTES
818
+ );
819
+ if (MESSAGE_DATA_ALLOWED_TICKET_KEY in metadata && !recipient) {
820
+ throw new import_api.GraffitiErrorForbidden(
821
+ `Recipient is required when allowed ticket is present`
822
+ );
823
+ }
824
+ const privateObjectInfo = allowedTickets ? { allowedTickets } : MESSAGE_DATA_ALLOWED_TICKET_KEY in metadata ? {
825
+ recipient: recipient ?? "null",
826
+ allowedTicket: metadata[MESSAGE_DATA_ALLOWED_TICKET_KEY],
827
+ allowedIndex: metadata[MESSAGE_DATA_ALLOWED_TICKET_INDEX_KEY]
828
+ } : void 0;
829
+ await this.objectEncoding.validate(
830
+ object,
831
+ receivedTags,
832
+ objectBytes,
833
+ privateObjectInfo
834
+ );
835
+ } catch (e) {
836
+ validationError = e;
837
+ }
838
+ if (tombstonedMessageId) {
839
+ if (validationError instanceof import_api.GraffitiErrorNotFound) {
840
+ this.inboxes.get(inboxEndpoint, tombstonedMessageId, inboxToken).then((result2) => {
841
+ if (result2 && result2[import_inboxes.LABELED_MESSAGE_MESSAGE_KEY][import_inboxes.MESSAGE_OBJECT_KEY].url === object.url) {
842
+ this.inboxes.label(
843
+ inboxEndpoint,
844
+ tombstonedMessageId,
845
+ MESSAGE_LABEL_TRASH,
846
+ inboxToken
847
+ );
848
+ }
849
+ this.inboxes.label(
850
+ inboxEndpoint,
851
+ messageId,
852
+ MESSAGE_LABEL_TRASH,
853
+ inboxToken
854
+ );
855
+ });
856
+ yield {
857
+ messageId,
858
+ tombstone: true,
859
+ object,
860
+ storageBucketKey,
861
+ allowedTickets,
862
+ tags: receivedTags,
863
+ announcements
864
+ };
865
+ } else {
866
+ console.error("Recieved an incorrect object");
867
+ console.error(validationError);
868
+ this.inboxes.label(
869
+ inboxEndpoint,
870
+ messageId,
871
+ MESSAGE_LABEL_INVALID,
872
+ inboxToken
873
+ );
874
+ }
875
+ } else {
876
+ if (validationError === void 0) {
877
+ this.inboxes.label(
878
+ inboxEndpoint,
879
+ messageId,
880
+ MESSAGE_LABEL_VALID,
881
+ inboxToken
882
+ );
883
+ yield {
884
+ messageId,
885
+ object,
886
+ storageBucketKey,
887
+ tags: receivedTags,
888
+ allowedTickets,
889
+ announcements
890
+ };
891
+ } else {
892
+ console.error("Recieved an incorrect object");
893
+ console.error(validationError);
894
+ this.inboxes.label(
895
+ inboxEndpoint,
896
+ messageId,
897
+ MESSAGE_LABEL_INVALID,
898
+ inboxToken
899
+ );
900
+ }
901
+ }
902
+ }
903
+ }
904
+ }
905
+ const MEDIA_OBJECT_SCHEMA = {
906
+ properties: {
907
+ value: {
908
+ properties: {
909
+ type: { type: "string" },
910
+ size: { type: "number" },
911
+ key: { type: "string" }
912
+ },
913
+ required: ["type", "size", "key"]
914
+ }
915
+ }
916
+ };
917
+ const CursorSchema = (0, import_mini.strictObject)({
918
+ cursors: (0, import_mini.record)((0, import_mini.url)(), (0, import_mini.string)()),
919
+ channels: (0, import_mini.array)((0, import_mini.string)())
920
+ });
921
+ async function indexedSingleEndpointQueryNext(it, index) {
922
+ try {
923
+ return {
924
+ index,
925
+ result: await it.next()
926
+ };
927
+ } catch (e) {
928
+ if (e instanceof import_api.GraffitiErrorCursorExpired || e instanceof import_api.GraffitiErrorInvalidSchema) {
929
+ throw e;
930
+ }
931
+ return {
932
+ index,
933
+ error: e instanceof Error ? e : new Error(String(e))
934
+ };
935
+ }
936
+ }
937
+ //# sourceMappingURL=4-graffiti.js.map