@xmtp/browser-sdk 0.0.1 → 0.0.3

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.
@@ -3,23 +3,26 @@ import {
3
3
  type EncodedContent,
4
4
  } from "@xmtp/content-type-primitives";
5
5
  import {
6
- WasmConsent,
7
- WasmContentTypeId,
8
- WasmCreateGroupOptions,
9
- WasmEncodedContent,
10
- WasmGroupMember,
11
- WasmListConversationsOptions,
12
- WasmListMessagesOptions,
13
- type WasmConsentEntityType,
14
- type WasmConsentState,
15
- type WasmDeliveryStatus,
16
- type WasmGroupMessageKind,
17
- type WasmGroupPermissionsOptions,
18
- type WasmInboxState,
19
- type WasmInstallation,
20
- type WasmMessage,
21
- type WasmPermissionLevel,
22
- type WasmPermissionPolicy,
6
+ Consent,
7
+ CreateGroupOptions,
8
+ GroupMember,
9
+ ListConversationsOptions,
10
+ ListMessagesOptions,
11
+ ContentTypeId as WasmContentTypeId,
12
+ EncodedContent as WasmEncodedContent,
13
+ type ConsentEntityType,
14
+ type ConsentState,
15
+ type ConversationType,
16
+ type DeliveryStatus,
17
+ type GroupMembershipState,
18
+ type GroupMessageKind,
19
+ type GroupPermissionsOptions,
20
+ type InboxState,
21
+ type Installation,
22
+ type Message,
23
+ type PermissionLevel,
24
+ type PermissionPolicy,
25
+ type SortDirection,
23
26
  } from "@xmtp/wasm-bindings";
24
27
  import type { WorkerConversation } from "@/WorkerConversation";
25
28
 
@@ -27,10 +30,10 @@ export const toContentTypeId = (
27
30
  contentTypeId: WasmContentTypeId,
28
31
  ): ContentTypeId =>
29
32
  new ContentTypeId({
30
- authorityId: contentTypeId.authority_id,
31
- typeId: contentTypeId.type_id,
32
- versionMajor: contentTypeId.version_major,
33
- versionMinor: contentTypeId.version_minor,
33
+ authorityId: contentTypeId.authorityId,
34
+ typeId: contentTypeId.typeId,
35
+ versionMajor: contentTypeId.versionMajor,
36
+ versionMinor: contentTypeId.versionMinor,
34
37
  });
35
38
 
36
39
  export const fromContentTypeId = (
@@ -122,74 +125,83 @@ export const fromSafeEncodedContent = (
122
125
  export type SafeMessage = {
123
126
  content: SafeEncodedContent;
124
127
  convoId: string;
125
- deliveryStatus: WasmDeliveryStatus;
128
+ deliveryStatus: DeliveryStatus;
126
129
  id: string;
127
- kind: WasmGroupMessageKind;
130
+ kind: GroupMessageKind;
128
131
  senderInboxId: string;
129
132
  sentAtNs: bigint;
130
133
  };
131
134
 
132
- export const toSafeMessage = (message: WasmMessage): SafeMessage => ({
135
+ export const toSafeMessage = (message: Message): SafeMessage => ({
133
136
  content: toSafeEncodedContent(toEncodedContent(message.content)),
134
- convoId: message.convo_id,
135
- deliveryStatus: message.delivery_status,
137
+ convoId: message.convoId,
138
+ deliveryStatus: message.deliveryStatus,
136
139
  id: message.id,
137
140
  kind: message.kind,
138
- senderInboxId: message.sender_inbox_id,
139
- sentAtNs: message.sent_at_ns,
141
+ senderInboxId: message.senderInboxId,
142
+ sentAtNs: message.sentAtNs,
140
143
  });
141
144
 
142
145
  export type SafeListMessagesOptions = {
143
- delivery_status?: WasmDeliveryStatus;
146
+ deliveryStatus?: DeliveryStatus;
147
+ direction?: SortDirection;
144
148
  limit?: bigint;
145
- sent_after_ns?: bigint;
146
- sent_before_ns?: bigint;
149
+ sentAfterNs?: bigint;
150
+ sentBeforeNs?: bigint;
147
151
  };
148
152
 
149
153
  export const toSafeListMessagesOptions = (
150
- options: WasmListMessagesOptions,
154
+ options: ListMessagesOptions,
151
155
  ): SafeListMessagesOptions => ({
152
- delivery_status: options.delivery_status,
156
+ deliveryStatus: options.deliveryStatus,
157
+ direction: options.direction,
153
158
  limit: options.limit,
154
- sent_after_ns: options.sent_after_ns,
155
- sent_before_ns: options.sent_before_ns,
159
+ sentAfterNs: options.sentAfterNs,
160
+ sentBeforeNs: options.sentBeforeNs,
156
161
  });
157
162
 
158
163
  export const fromSafeListMessagesOptions = (
159
164
  options: SafeListMessagesOptions,
160
- ): WasmListMessagesOptions =>
161
- new WasmListMessagesOptions(
162
- options.sent_before_ns,
163
- options.sent_after_ns,
165
+ ): ListMessagesOptions =>
166
+ new ListMessagesOptions(
167
+ options.sentBeforeNs,
168
+ options.sentAfterNs,
164
169
  options.limit,
165
- options.delivery_status,
170
+ options.deliveryStatus,
171
+ options.direction,
166
172
  );
167
173
 
168
174
  export type SafeListConversationsOptions = {
169
- created_after_ns?: bigint;
170
- created_before_ns?: bigint;
175
+ allowedStates?: GroupMembershipState[];
176
+ conversationType?: ConversationType;
177
+ createdAfterNs?: bigint;
178
+ createdBeforeNs?: bigint;
171
179
  limit?: bigint;
172
180
  };
173
181
 
174
182
  export const toSafeListConversationsOptions = (
175
- options: WasmListConversationsOptions,
183
+ options: ListConversationsOptions,
176
184
  ): SafeListConversationsOptions => ({
177
- created_after_ns: options.created_after_ns,
178
- created_before_ns: options.created_before_ns,
185
+ allowedStates: options.allowedStates,
186
+ conversationType: options.conversationType,
187
+ createdAfterNs: options.createdAfterNs,
188
+ createdBeforeNs: options.createdBeforeNs,
179
189
  limit: options.limit,
180
190
  });
181
191
 
182
192
  export const fromSafeListConversationsOptions = (
183
193
  options: SafeListConversationsOptions,
184
- ): WasmListConversationsOptions =>
185
- new WasmListConversationsOptions(
186
- options.created_after_ns,
187
- options.created_before_ns,
194
+ ): ListConversationsOptions =>
195
+ new ListConversationsOptions(
196
+ options.allowedStates,
197
+ options.conversationType,
198
+ options.createdAfterNs,
199
+ options.createdBeforeNs,
188
200
  options.limit,
189
201
  );
190
202
 
191
203
  export type SafeCreateGroupOptions = {
192
- permissions?: WasmGroupPermissionsOptions;
204
+ permissions?: GroupPermissionsOptions;
193
205
  name?: string;
194
206
  imageUrlSquare?: string;
195
207
  description?: string;
@@ -197,19 +209,19 @@ export type SafeCreateGroupOptions = {
197
209
  };
198
210
 
199
211
  export const toSafeCreateGroupOptions = (
200
- options: WasmCreateGroupOptions,
212
+ options: CreateGroupOptions,
201
213
  ): SafeCreateGroupOptions => ({
202
214
  permissions: options.permissions,
203
- name: options.group_name,
204
- imageUrlSquare: options.group_image_url_square,
205
- description: options.group_description,
206
- pinnedFrameUrl: options.group_pinned_frame_url,
215
+ name: options.groupName,
216
+ imageUrlSquare: options.groupImageUrlSquare,
217
+ description: options.groupDescription,
218
+ pinnedFrameUrl: options.groupPinnedFrameUrl,
207
219
  });
208
220
 
209
221
  export const fromSafeCreateGroupOptions = (
210
222
  options: SafeCreateGroupOptions,
211
- ): WasmCreateGroupOptions =>
212
- new WasmCreateGroupOptions(
223
+ ): CreateGroupOptions =>
224
+ new CreateGroupOptions(
213
225
  options.permissions,
214
226
  options.name,
215
227
  options.imageUrlSquare,
@@ -224,16 +236,16 @@ export type SafeConversation = {
224
236
  description: string;
225
237
  pinnedFrameUrl: string;
226
238
  permissions: {
227
- policyType: WasmGroupPermissionsOptions;
239
+ policyType: GroupPermissionsOptions;
228
240
  policySet: {
229
- addAdminPolicy: WasmPermissionPolicy;
230
- addMemberPolicy: WasmPermissionPolicy;
231
- removeAdminPolicy: WasmPermissionPolicy;
232
- removeMemberPolicy: WasmPermissionPolicy;
233
- updateGroupDescriptionPolicy: WasmPermissionPolicy;
234
- updateGroupImageUrlSquarePolicy: WasmPermissionPolicy;
235
- updateGroupNamePolicy: WasmPermissionPolicy;
236
- updateGroupPinnedFrameUrlPolicy: WasmPermissionPolicy;
241
+ addAdminPolicy: PermissionPolicy;
242
+ addMemberPolicy: PermissionPolicy;
243
+ removeAdminPolicy: PermissionPolicy;
244
+ removeMemberPolicy: PermissionPolicy;
245
+ updateGroupDescriptionPolicy: PermissionPolicy;
246
+ updateGroupImageUrlSquarePolicy: PermissionPolicy;
247
+ updateGroupNamePolicy: PermissionPolicy;
248
+ updateGroupPinnedFrameUrlPolicy: PermissionPolicy;
237
249
  };
238
250
  };
239
251
  isActive: boolean;
@@ -258,19 +270,18 @@ export const toSafeConversation = (
258
270
  permissions: {
259
271
  policyType: conversation.permissions.policyType,
260
272
  policySet: {
261
- addAdminPolicy: conversation.permissions.policySet.add_admin_policy,
262
- addMemberPolicy: conversation.permissions.policySet.add_member_policy,
263
- removeAdminPolicy: conversation.permissions.policySet.remove_admin_policy,
264
- removeMemberPolicy:
265
- conversation.permissions.policySet.remove_member_policy,
273
+ addAdminPolicy: conversation.permissions.policySet.addAdminPolicy,
274
+ addMemberPolicy: conversation.permissions.policySet.addMemberPolicy,
275
+ removeAdminPolicy: conversation.permissions.policySet.removeAdminPolicy,
276
+ removeMemberPolicy: conversation.permissions.policySet.removeMemberPolicy,
266
277
  updateGroupDescriptionPolicy:
267
- conversation.permissions.policySet.update_group_description_policy,
278
+ conversation.permissions.policySet.updateGroupDescriptionPolicy,
268
279
  updateGroupImageUrlSquarePolicy:
269
- conversation.permissions.policySet.update_group_image_url_square_policy,
280
+ conversation.permissions.policySet.updateGroupImageUrlSquarePolicy,
270
281
  updateGroupNamePolicy:
271
- conversation.permissions.policySet.update_group_name_policy,
282
+ conversation.permissions.policySet.updateGroupNamePolicy,
272
283
  updateGroupPinnedFrameUrlPolicy:
273
- conversation.permissions.policySet.update_group_pinned_frame_url_policy,
284
+ conversation.permissions.policySet.updateGroupPinnedFrameUrlPolicy,
274
285
  },
275
286
  },
276
287
  isActive: conversation.isActive,
@@ -287,10 +298,10 @@ export type SafeInstallation = {
287
298
  };
288
299
 
289
300
  export const toSafeInstallation = (
290
- installation: WasmInstallation,
301
+ installation: Installation,
291
302
  ): SafeInstallation => ({
292
303
  id: installation.id,
293
- clientTimestampNs: installation.client_timestamp_ns,
304
+ clientTimestampNs: installation.clientTimestampNs,
294
305
  });
295
306
 
296
307
  export type SafeInboxState = {
@@ -300,50 +311,46 @@ export type SafeInboxState = {
300
311
  recoveryAddress: string;
301
312
  };
302
313
 
303
- export const toSafeInboxState = (
304
- inboxState: WasmInboxState,
305
- ): SafeInboxState => ({
306
- accountAddresses: inboxState.account_addresses,
307
- inboxId: inboxState.inbox_id,
314
+ export const toSafeInboxState = (inboxState: InboxState): SafeInboxState => ({
315
+ accountAddresses: inboxState.accountAddresses,
316
+ inboxId: inboxState.inboxId,
308
317
  installations: inboxState.installations.map(toSafeInstallation),
309
- recoveryAddress: inboxState.recovery_address,
318
+ recoveryAddress: inboxState.recoveryAddress,
310
319
  });
311
320
 
312
321
  export type SafeConsent = {
313
322
  entity: string;
314
- entityType: WasmConsentEntityType;
315
- state: WasmConsentState;
323
+ entityType: ConsentEntityType;
324
+ state: ConsentState;
316
325
  };
317
326
 
318
- export const toSafeConsent = (consent: WasmConsent): SafeConsent => ({
327
+ export const toSafeConsent = (consent: Consent): SafeConsent => ({
319
328
  entity: consent.entity,
320
- entityType: consent.entity_type,
329
+ entityType: consent.entityType,
321
330
  state: consent.state,
322
331
  });
323
332
 
324
- export const fromSafeConsent = (consent: SafeConsent): WasmConsent =>
325
- new WasmConsent(consent.entityType, consent.state, consent.entity);
333
+ export const fromSafeConsent = (consent: SafeConsent): Consent =>
334
+ new Consent(consent.entityType, consent.state, consent.entity);
326
335
 
327
336
  export type SafeGroupMember = {
328
337
  accountAddresses: string[];
329
- consentState: WasmConsentState;
338
+ consentState: ConsentState;
330
339
  inboxId: string;
331
340
  installationIds: string[];
332
- permissionLevel: WasmPermissionLevel;
341
+ permissionLevel: PermissionLevel;
333
342
  };
334
343
 
335
- export const toSafeGroupMember = (
336
- member: WasmGroupMember,
337
- ): SafeGroupMember => ({
338
- accountAddresses: member.account_addresses,
339
- consentState: member.consent_state,
340
- inboxId: member.inbox_id,
341
- installationIds: member.installation_ids,
342
- permissionLevel: member.permission_level,
344
+ export const toSafeGroupMember = (member: GroupMember): SafeGroupMember => ({
345
+ accountAddresses: member.accountAddresses,
346
+ consentState: member.consentState,
347
+ inboxId: member.inboxId,
348
+ installationIds: member.installationIds,
349
+ permissionLevel: member.permissionLevel,
343
350
  });
344
351
 
345
- export const fromSafeGroupMember = (member: SafeGroupMember): WasmGroupMember =>
346
- new WasmGroupMember(
352
+ export const fromSafeGroupMember = (member: SafeGroupMember): GroupMember =>
353
+ new GroupMember(
347
354
  member.inboxId,
348
355
  member.accountAddresses,
349
356
  member.installationIds,
@@ -2,29 +2,50 @@ import init, {
2
2
  createClient as createWasmClient,
3
3
  generateInboxId,
4
4
  getInboxIdForAddress,
5
+ LogOptions,
5
6
  } from "@xmtp/wasm-bindings";
6
7
  import { ApiUrls } from "@/constants";
7
8
  import type { ClientOptions } from "@/types";
8
9
 
9
10
  export const createClient = async (
10
11
  accountAddress: string,
12
+ encryptionKey: Uint8Array,
11
13
  options?: Omit<ClientOptions, "codecs">,
12
14
  ) => {
13
15
  // initialize WASM module
14
16
  await init();
15
17
 
16
18
  const host = options?.apiUrl ?? ApiUrls[options?.env ?? "dev"];
17
- const dbPath = `xmtp-${options?.env ?? "dev"}-${accountAddress}.db3`;
19
+ // TODO: add db path validation
20
+ // - must end with .db3
21
+ // - must not contain invalid characters
22
+ // - must not start with a dot
23
+ const dbPath =
24
+ options?.dbPath ?? `xmtp-${options?.env ?? "dev"}-${accountAddress}.db3`;
18
25
 
19
26
  const inboxId =
20
27
  (await getInboxIdForAddress(host, accountAddress)) ||
21
28
  generateInboxId(accountAddress);
22
29
 
30
+ const isLogging =
31
+ options &&
32
+ (options.loggingLevel !== undefined ||
33
+ options.structuredLogging ||
34
+ options.performanceLogging);
35
+
23
36
  return createWasmClient(
24
37
  host,
25
38
  inboxId,
26
39
  accountAddress,
27
40
  dbPath,
28
- options?.encryptionKey,
41
+ encryptionKey,
42
+ undefined,
43
+ isLogging
44
+ ? new LogOptions(
45
+ options.structuredLogging ?? false,
46
+ options.performanceLogging ?? false,
47
+ options.loggingLevel,
48
+ )
49
+ : undefined,
29
50
  );
30
51
  };
@@ -8,7 +8,6 @@ import {
8
8
  fromEncodedContent,
9
9
  fromSafeEncodedContent,
10
10
  toSafeConversation,
11
- toSafeGroupMember,
12
11
  toSafeInboxState,
13
12
  toSafeMessage,
14
13
  } from "@/utils/conversions";
@@ -57,8 +56,14 @@ self.onmessage = async (event: MessageEvent<ClientEventsClientMessageData>) => {
57
56
  * Client actions
58
57
  */
59
58
  case "init":
60
- client = await WorkerClient.create(data.address, data.options);
61
- enableLogging = data.options?.enableLogging ?? false;
59
+ client = await WorkerClient.create(
60
+ data.address,
61
+ data.encryptionKey,
62
+ data.options,
63
+ );
64
+ enableLogging =
65
+ data.options?.loggingLevel !== undefined &&
66
+ data.options.loggingLevel !== "off";
62
67
  postMessage({
63
68
  id,
64
69
  action,
@@ -99,6 +104,15 @@ self.onmessage = async (event: MessageEvent<ClientEventsClientMessageData>) => {
99
104
  });
100
105
  break;
101
106
  }
107
+ case "getRevokeInstallationsSignatureText": {
108
+ const result = await client.getRevokeInstallationsSignatureText();
109
+ postMessage({
110
+ id,
111
+ action,
112
+ result,
113
+ });
114
+ break;
115
+ }
102
116
  case "addSignature":
103
117
  await client.addSignature(data.type, data.bytes);
104
118
  postMessage({
@@ -107,8 +121,21 @@ self.onmessage = async (event: MessageEvent<ClientEventsClientMessageData>) => {
107
121
  result: undefined,
108
122
  });
109
123
  break;
110
- case "applySignaturesRequests":
111
- await client.applySignaturesRequests();
124
+ case "addScwSignature":
125
+ await client.addScwSignature(
126
+ data.type,
127
+ data.bytes,
128
+ data.chainId,
129
+ data.blockNumber,
130
+ );
131
+ postMessage({
132
+ id,
133
+ action,
134
+ result: undefined,
135
+ });
136
+ break;
137
+ case "applySignatures":
138
+ await client.applySignatures();
112
139
  postMessage({
113
140
  id,
114
141
  action,
@@ -203,6 +230,30 @@ self.onmessage = async (event: MessageEvent<ClientEventsClientMessageData>) => {
203
230
  });
204
231
  break;
205
232
  }
233
+ case "getGroups": {
234
+ const conversations = await client.conversations.listGroups(
235
+ data.options,
236
+ );
237
+ postMessage({
238
+ id,
239
+ action,
240
+ result: conversations.map((conversation) =>
241
+ toSafeConversation(conversation),
242
+ ),
243
+ });
244
+ break;
245
+ }
246
+ case "getDms": {
247
+ const conversations = await client.conversations.listDms(data.options);
248
+ postMessage({
249
+ id,
250
+ action,
251
+ result: conversations.map((conversation) =>
252
+ toSafeConversation(conversation),
253
+ ),
254
+ });
255
+ break;
256
+ }
206
257
  case "newGroup": {
207
258
  const conversation = await client.conversations.newGroup(
208
259
  data.accountAddresses,
@@ -215,6 +266,17 @@ self.onmessage = async (event: MessageEvent<ClientEventsClientMessageData>) => {
215
266
  });
216
267
  break;
217
268
  }
269
+ case "newDm": {
270
+ const conversation = await client.conversations.newDm(
271
+ data.accountAddress,
272
+ );
273
+ postMessage({
274
+ id,
275
+ action,
276
+ result: toSafeConversation(conversation),
277
+ });
278
+ break;
279
+ }
218
280
  case "syncConversations": {
219
281
  await client.conversations.sync();
220
282
  postMessage({
@@ -242,6 +304,15 @@ self.onmessage = async (event: MessageEvent<ClientEventsClientMessageData>) => {
242
304
  });
243
305
  break;
244
306
  }
307
+ case "getDmByInboxId": {
308
+ const conversation = client.conversations.getDmByInboxId(data.inboxId);
309
+ postMessage({
310
+ id,
311
+ action,
312
+ result: conversation ? toSafeConversation(conversation) : undefined,
313
+ });
314
+ break;
315
+ }
245
316
  /**
246
317
  * Group actions
247
318
  */
@@ -414,11 +485,11 @@ self.onmessage = async (event: MessageEvent<ClientEventsClientMessageData>) => {
414
485
  case "getGroupMembers": {
415
486
  const group = client.conversations.getConversationById(data.id);
416
487
  if (group) {
417
- const members = await group.members();
488
+ const result = await group.members();
418
489
  postMessage({
419
490
  id,
420
491
  action,
421
- result: members.map((member) => toSafeGroupMember(member)),
492
+ result,
422
493
  });
423
494
  } else {
424
495
  postMessageError({
@@ -678,6 +749,24 @@ self.onmessage = async (event: MessageEvent<ClientEventsClientMessageData>) => {
678
749
  }
679
750
  break;
680
751
  }
752
+ case "getDmPeerInboxId": {
753
+ const group = client.conversations.getConversationById(data.id);
754
+ if (group) {
755
+ const result = group.dmPeerInboxId();
756
+ postMessage({
757
+ id,
758
+ action,
759
+ result,
760
+ });
761
+ } else {
762
+ postMessageError({
763
+ id,
764
+ action,
765
+ error: "Group not found",
766
+ });
767
+ }
768
+ break;
769
+ }
681
770
  }
682
771
  } catch (e) {
683
772
  postMessageError({