@xmtp/browser-sdk 0.0.21 → 0.0.22

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.
@@ -1,10 +1,16 @@
1
- import { ConversationType, type ConsentState } from "@xmtp/wasm-bindings";
1
+ import {
2
+ ConversationType,
3
+ type ConsentState,
4
+ type UserPreference,
5
+ } from "@xmtp/wasm-bindings";
2
6
  import { v4 } from "uuid";
3
7
  import { AsyncStream, type StreamCallback } from "@/AsyncStream";
4
8
  import type { Client } from "@/Client";
5
- import { Conversation } from "@/Conversation";
6
9
  import { DecodedMessage } from "@/DecodedMessage";
10
+ import { Dm } from "@/Dm";
11
+ import { Group } from "@/Group";
7
12
  import type {
13
+ SafeConsent,
8
14
  SafeConversation,
9
15
  SafeCreateDmOptions,
10
16
  SafeCreateGroupOptions,
@@ -33,7 +39,12 @@ export class Conversations {
33
39
  const data = await this.#client.sendMessage("getConversationById", {
34
40
  id,
35
41
  });
36
- return data ? new Conversation(this.#client, id, data) : undefined;
42
+ if (data) {
43
+ return data.metadata.conversationType === "group"
44
+ ? new Group(this.#client, data.id, data)
45
+ : new Dm(this.#client, data.id, data);
46
+ }
47
+ return undefined;
37
48
  }
38
49
 
39
50
  async getMessageById(id: string) {
@@ -47,7 +58,7 @@ export class Conversations {
47
58
  const data = await this.#client.sendMessage("getDmByInboxId", {
48
59
  inboxId,
49
60
  });
50
- return data ? new Conversation(this.#client, data.id, data) : undefined;
61
+ return data ? new Dm(this.#client, data.id, data) : undefined;
51
62
  }
52
63
 
53
64
  async list(options?: SafeListConversationsOptions) {
@@ -55,9 +66,10 @@ export class Conversations {
55
66
  options,
56
67
  });
57
68
 
58
- return conversations.map(
59
- (conversation) =>
60
- new Conversation(this.#client, conversation.id, conversation),
69
+ return conversations.map((conversation) =>
70
+ conversation.metadata.conversationType === "group"
71
+ ? new Group(this.#client, conversation.id, conversation)
72
+ : new Dm(this.#client, conversation.id, conversation),
61
73
  );
62
74
  }
63
75
 
@@ -69,8 +81,7 @@ export class Conversations {
69
81
  });
70
82
 
71
83
  return conversations.map(
72
- (conversation) =>
73
- new Conversation(this.#client, conversation.id, conversation),
84
+ (conversation) => new Group(this.#client, conversation.id, conversation),
74
85
  );
75
86
  }
76
87
 
@@ -82,8 +93,7 @@ export class Conversations {
82
93
  });
83
94
 
84
95
  return conversations.map(
85
- (conversation) =>
86
- new Conversation(this.#client, conversation.id, conversation),
96
+ (conversation) => new Dm(this.#client, conversation.id, conversation),
87
97
  );
88
98
  }
89
99
 
@@ -93,7 +103,7 @@ export class Conversations {
93
103
  options,
94
104
  });
95
105
 
96
- return new Conversation(this.#client, conversation.id, conversation);
106
+ return new Group(this.#client, conversation.id, conversation);
97
107
  }
98
108
 
99
109
  async newGroupByInboxIds(
@@ -105,7 +115,7 @@ export class Conversations {
105
115
  options,
106
116
  });
107
117
 
108
- return new Conversation(this.#client, conversation.id, conversation);
118
+ return new Group(this.#client, conversation.id, conversation);
109
119
  }
110
120
 
111
121
  async newDm(accountAddress: string, options?: SafeCreateDmOptions) {
@@ -114,7 +124,7 @@ export class Conversations {
114
124
  options,
115
125
  });
116
126
 
117
- return new Conversation(this.#client, conversation.id, conversation);
127
+ return new Dm(this.#client, conversation.id, conversation);
118
128
  }
119
129
 
120
130
  async newDmByInboxId(inboxId: string, options?: SafeCreateDmOptions) {
@@ -123,27 +133,39 @@ export class Conversations {
123
133
  options,
124
134
  });
125
135
 
126
- return new Conversation(this.#client, conversation.id, conversation);
136
+ return new Dm(this.#client, conversation.id, conversation);
127
137
  }
128
138
 
129
139
  async getHmacKeys() {
130
140
  return this.#client.sendMessage("getHmacKeys", undefined);
131
141
  }
132
142
 
133
- async stream(
134
- callback?: StreamCallback<Conversation>,
143
+ async stream<T extends Group | Dm = Group | Dm>(
144
+ callback?: StreamCallback<T>,
135
145
  conversationType?: ConversationType,
136
146
  ) {
137
147
  const streamId = v4();
138
- const asyncStream = new AsyncStream<Conversation>();
148
+ const asyncStream = new AsyncStream<T>();
139
149
  const endStream = this.#client.handleStreamMessage<SafeConversation>(
140
150
  streamId,
141
151
  (error, value) => {
142
- const conversation = value
143
- ? new Conversation(this.#client, value.id, value)
144
- : undefined;
145
- void asyncStream.callback(error, conversation);
146
- void callback?.(error, conversation);
152
+ if (error) {
153
+ void asyncStream.callback(error, undefined);
154
+ void callback?.(error, undefined);
155
+ return;
156
+ }
157
+
158
+ let streamValue: T | undefined = undefined;
159
+
160
+ if (value) {
161
+ streamValue =
162
+ value.metadata.conversationType === "group"
163
+ ? (new Group(this.#client, value.id, value) as T)
164
+ : (new Dm(this.#client, value.id, value) as T);
165
+ }
166
+
167
+ void asyncStream.callback(null, streamValue);
168
+ void callback?.(null, streamValue);
147
169
  },
148
170
  );
149
171
  await this.#client.sendMessage("streamAllGroups", {
@@ -159,12 +181,12 @@ export class Conversations {
159
181
  return asyncStream;
160
182
  }
161
183
 
162
- async streamGroups(callback?: StreamCallback<Conversation>) {
163
- return this.stream(callback, ConversationType.Group);
184
+ async streamGroups(callback?: StreamCallback<Group>) {
185
+ return this.stream<Group>(callback, ConversationType.Group);
164
186
  }
165
187
 
166
- async streamDms(callback?: StreamCallback<Conversation>) {
167
- return this.stream(callback, ConversationType.Dm);
188
+ async streamDms(callback?: StreamCallback<Dm>) {
189
+ return this.stream<Dm>(callback, ConversationType.Dm);
168
190
  }
169
191
 
170
192
  async streamAllMessages(
@@ -176,11 +198,17 @@ export class Conversations {
176
198
  const endStream = this.#client.handleStreamMessage<SafeMessage>(
177
199
  streamId,
178
200
  (error, value) => {
201
+ if (error) {
202
+ void asyncStream.callback(error, undefined);
203
+ void callback?.(error, undefined);
204
+ return;
205
+ }
206
+
179
207
  const decodedMessage = value
180
208
  ? new DecodedMessage(this.#client, value)
181
209
  : undefined;
182
- void asyncStream.callback(error, decodedMessage);
183
- void callback?.(error, decodedMessage);
210
+ void asyncStream.callback(null, decodedMessage);
211
+ void callback?.(null, decodedMessage);
184
212
  },
185
213
  );
186
214
  await this.#client.sendMessage("streamAllMessages", {
@@ -203,4 +231,48 @@ export class Conversations {
203
231
  async streamAllDmMessages(callback?: StreamCallback<DecodedMessage>) {
204
232
  return this.streamAllMessages(callback, ConversationType.Dm);
205
233
  }
234
+
235
+ async streamConsent(callback?: StreamCallback<SafeConsent[]>) {
236
+ const streamId = v4();
237
+ const asyncStream = new AsyncStream<SafeConsent[]>();
238
+ const endStream = this.#client.handleStreamMessage<SafeConsent[]>(
239
+ streamId,
240
+ (error, value) => {
241
+ void asyncStream.callback(error, value ?? undefined);
242
+ void callback?.(error, value ?? undefined);
243
+ },
244
+ );
245
+ await this.#client.sendMessage("streamConsent", {
246
+ streamId,
247
+ });
248
+ asyncStream.onReturn = () => {
249
+ void this.#client.sendMessage("endStream", {
250
+ streamId,
251
+ });
252
+ endStream();
253
+ };
254
+ return asyncStream;
255
+ }
256
+
257
+ async streamPreferences(callback?: StreamCallback<UserPreference[]>) {
258
+ const streamId = v4();
259
+ const asyncStream = new AsyncStream<UserPreference[]>();
260
+ const endStream = this.#client.handleStreamMessage<UserPreference[]>(
261
+ streamId,
262
+ (error, value) => {
263
+ void asyncStream.callback(error, value ?? undefined);
264
+ void callback?.(error, value ?? undefined);
265
+ },
266
+ );
267
+ await this.#client.sendMessage("streamPreferences", {
268
+ streamId,
269
+ });
270
+ asyncStream.onReturn = () => {
271
+ void this.#client.sendMessage("endStream", {
272
+ streamId,
273
+ });
274
+ endStream();
275
+ };
276
+ return asyncStream;
277
+ }
206
278
  }
package/src/Dm.ts ADDED
@@ -0,0 +1,21 @@
1
+ import type { Client } from "@/Client";
2
+ import { Conversation } from "@/Conversation";
3
+ import type { SafeConversation } from "@/utils/conversions";
4
+
5
+ export class Dm extends Conversation {
6
+ #client: Client;
7
+
8
+ #id: string;
9
+
10
+ constructor(client: Client, id: string, data?: SafeConversation) {
11
+ super(client, id, data);
12
+ this.#client = client;
13
+ this.#id = id;
14
+ }
15
+
16
+ async peerInboxId() {
17
+ return this.#client.sendMessage("getDmPeerInboxId", {
18
+ id: this.#id,
19
+ });
20
+ }
21
+ }
package/src/Group.ts ADDED
@@ -0,0 +1,190 @@
1
+ import type {
2
+ MetadataField,
3
+ PermissionPolicy,
4
+ PermissionUpdateType,
5
+ } from "@xmtp/wasm-bindings";
6
+ import type { Client } from "@/Client";
7
+ import { Conversation } from "@/Conversation";
8
+ import type { SafeConversation } from "@/utils/conversions";
9
+
10
+ export class Group extends Conversation {
11
+ #client: Client;
12
+
13
+ #id: string;
14
+
15
+ #name?: SafeConversation["name"];
16
+
17
+ #imageUrl?: SafeConversation["imageUrl"];
18
+
19
+ #description?: SafeConversation["description"];
20
+
21
+ #admins: SafeConversation["admins"] = [];
22
+
23
+ #superAdmins: SafeConversation["superAdmins"] = [];
24
+
25
+ #syncData(data?: SafeConversation) {
26
+ this.#name = data?.name ?? "";
27
+ this.#imageUrl = data?.imageUrl ?? "";
28
+ this.#description = data?.description ?? "";
29
+ this.#admins = data?.admins ?? [];
30
+ this.#superAdmins = data?.superAdmins ?? [];
31
+ }
32
+
33
+ constructor(client: Client, id: string, data?: SafeConversation) {
34
+ super(client, id, data);
35
+ this.#client = client;
36
+ this.#id = id;
37
+ this.#syncData(data);
38
+ }
39
+
40
+ async sync() {
41
+ const data = await super.sync();
42
+ this.#syncData(data);
43
+ return data;
44
+ }
45
+
46
+ get name() {
47
+ return this.#name;
48
+ }
49
+
50
+ async updateName(name: string) {
51
+ await this.#client.sendMessage("updateGroupName", {
52
+ id: this.#id,
53
+ name,
54
+ });
55
+ this.#name = name;
56
+ }
57
+
58
+ get imageUrl() {
59
+ return this.#imageUrl;
60
+ }
61
+
62
+ async updateImageUrl(imageUrl: string) {
63
+ await this.#client.sendMessage("updateGroupImageUrlSquare", {
64
+ id: this.#id,
65
+ imageUrl,
66
+ });
67
+ this.#imageUrl = imageUrl;
68
+ }
69
+
70
+ get description() {
71
+ return this.#description;
72
+ }
73
+
74
+ async updateDescription(description: string) {
75
+ await this.#client.sendMessage("updateGroupDescription", {
76
+ id: this.#id,
77
+ description,
78
+ });
79
+ this.#description = description;
80
+ }
81
+
82
+ get admins() {
83
+ return this.#admins;
84
+ }
85
+
86
+ get superAdmins() {
87
+ return this.#superAdmins;
88
+ }
89
+
90
+ async listAdmins() {
91
+ const admins = await this.#client.sendMessage("getGroupAdmins", {
92
+ id: this.#id,
93
+ });
94
+ this.#admins = admins;
95
+ return admins;
96
+ }
97
+
98
+ async listSuperAdmins() {
99
+ const superAdmins = await this.#client.sendMessage("getGroupSuperAdmins", {
100
+ id: this.#id,
101
+ });
102
+ this.#superAdmins = superAdmins;
103
+ return superAdmins;
104
+ }
105
+
106
+ async permissions() {
107
+ return this.#client.sendMessage("getGroupPermissions", {
108
+ id: this.#id,
109
+ });
110
+ }
111
+
112
+ async updatePermission(
113
+ permissionType: PermissionUpdateType,
114
+ policy: PermissionPolicy,
115
+ metadataField?: MetadataField,
116
+ ) {
117
+ return this.#client.sendMessage("updateGroupPermissionPolicy", {
118
+ id: this.#id,
119
+ permissionType,
120
+ policy,
121
+ metadataField,
122
+ });
123
+ }
124
+
125
+ async isAdmin(inboxId: string) {
126
+ const admins = await this.listAdmins();
127
+ return admins.includes(inboxId);
128
+ }
129
+
130
+ async isSuperAdmin(inboxId: string) {
131
+ const superAdmins = await this.listSuperAdmins();
132
+ return superAdmins.includes(inboxId);
133
+ }
134
+
135
+ async addMembers(accountAddresses: string[]) {
136
+ return this.#client.sendMessage("addGroupMembers", {
137
+ id: this.#id,
138
+ accountAddresses,
139
+ });
140
+ }
141
+
142
+ async addMembersByInboxId(inboxIds: string[]) {
143
+ return this.#client.sendMessage("addGroupMembersByInboxId", {
144
+ id: this.#id,
145
+ inboxIds,
146
+ });
147
+ }
148
+
149
+ async removeMembers(accountAddresses: string[]) {
150
+ return this.#client.sendMessage("removeGroupMembers", {
151
+ id: this.#id,
152
+ accountAddresses,
153
+ });
154
+ }
155
+
156
+ async removeMembersByInboxId(inboxIds: string[]) {
157
+ return this.#client.sendMessage("removeGroupMembersByInboxId", {
158
+ id: this.#id,
159
+ inboxIds,
160
+ });
161
+ }
162
+
163
+ async addAdmin(inboxId: string) {
164
+ return this.#client.sendMessage("addGroupAdmin", {
165
+ id: this.#id,
166
+ inboxId,
167
+ });
168
+ }
169
+
170
+ async removeAdmin(inboxId: string) {
171
+ return this.#client.sendMessage("removeGroupAdmin", {
172
+ id: this.#id,
173
+ inboxId,
174
+ });
175
+ }
176
+
177
+ async addSuperAdmin(inboxId: string) {
178
+ return this.#client.sendMessage("addGroupSuperAdmin", {
179
+ id: this.#id,
180
+ inboxId,
181
+ });
182
+ }
183
+
184
+ async removeSuperAdmin(inboxId: string) {
185
+ return this.#client.sendMessage("removeGroupSuperAdmin", {
186
+ id: this.#id,
187
+ inboxId,
188
+ });
189
+ }
190
+ }
@@ -1,10 +1,12 @@
1
1
  import {
2
2
  ConversationType,
3
+ type Consent,
3
4
  type ConsentState,
4
5
  type Conversation,
5
6
  type ConversationListItem,
6
7
  type Conversations,
7
8
  type Message,
9
+ type UserPreference,
8
10
  } from "@xmtp/wasm-bindings";
9
11
  import type { StreamCallback } from "@/AsyncStream";
10
12
  import {
@@ -172,4 +174,27 @@ export class WorkerConversations {
172
174
  conversationType,
173
175
  );
174
176
  }
177
+
178
+ streamConsent(callback?: StreamCallback<Consent[]>) {
179
+ const on_consent_update = (consent: Consent[]) => {
180
+ void callback?.(null, consent);
181
+ };
182
+ const on_error = (error: Error | null) => {
183
+ void callback?.(error, undefined);
184
+ };
185
+ return this.#conversations.streamConsent({ on_consent_update, on_error });
186
+ }
187
+
188
+ streamPreferences(callback?: StreamCallback<UserPreference[]>) {
189
+ const on_user_preference_update = (preferences: UserPreference[]) => {
190
+ void callback?.(null, preferences);
191
+ };
192
+ const on_error = (error: Error | null) => {
193
+ void callback?.(error, undefined);
194
+ };
195
+ return this.#conversations.streamPreferences({
196
+ on_user_preference_update,
197
+ on_error,
198
+ });
199
+ }
175
200
  }
package/src/index.ts CHANGED
@@ -1,30 +1,41 @@
1
1
  export { Client } from "./Client";
2
2
  export { Conversations } from "./Conversations";
3
3
  export { Conversation } from "./Conversation";
4
+ export { Dm } from "./Dm";
5
+ export { Group } from "./Group";
4
6
  export type { MessageDeliveryStatus, MessageKind } from "./DecodedMessage";
5
7
  export { DecodedMessage } from "./DecodedMessage";
6
8
  export { Utils } from "./Utils";
7
9
  export { ApiUrls, HistorySyncUrls } from "./constants";
8
10
  export type * from "./types";
9
11
  export * from "./utils/conversions";
12
+ export type { UserPreference } from "@xmtp/wasm-bindings";
10
13
  export {
14
+ Consent,
11
15
  ConsentEntityType,
12
16
  ConsentState,
17
+ ContentType,
18
+ ContentTypeId,
19
+ ConversationListItem,
13
20
  ConversationType,
21
+ CreateDMOptions,
14
22
  CreateGroupOptions,
15
23
  DeliveryStatus,
16
- GroupMembershipState,
17
24
  EncodedContent,
18
25
  GroupMember,
26
+ GroupMembershipState,
27
+ GroupMessageKind,
19
28
  GroupMetadata,
20
29
  GroupPermissions,
21
- GroupMessageKind,
22
30
  GroupPermissionsOptions,
31
+ HmacKey,
23
32
  InboxState,
24
33
  Installation,
25
34
  ListConversationsOptions,
26
35
  ListMessagesOptions,
36
+ LogOptions,
27
37
  Message,
38
+ MessageDisappearingSettings,
28
39
  MetadataField,
29
40
  PermissionLevel,
30
41
  PermissionPolicy,
@@ -32,8 +43,5 @@ export {
32
43
  PermissionUpdateType,
33
44
  SignatureRequestType,
34
45
  SortDirection,
35
- Consent,
36
- ContentTypeId,
37
- HmacKey,
38
46
  } from "@xmtp/wasm-bindings";
39
47
  export type { Signer } from "./utils/signer";
@@ -336,6 +336,22 @@ export type ClientEvents =
336
336
  conversationType?: ConversationType;
337
337
  };
338
338
  }
339
+ | {
340
+ action: "streamConsent";
341
+ id: string;
342
+ result: undefined;
343
+ data: {
344
+ streamId: string;
345
+ };
346
+ }
347
+ | {
348
+ action: "streamPreferences";
349
+ id: string;
350
+ result: undefined;
351
+ data: {
352
+ streamId: string;
353
+ };
354
+ }
339
355
  /**
340
356
  * Group actions
341
357
  */
@@ -1,9 +1,14 @@
1
+ import type { UserPreference } from "@xmtp/wasm-bindings";
1
2
  import type {
2
3
  StreamEventsClientPostMessageData,
3
4
  StreamEventsErrorData,
4
5
  StreamEventsResult,
5
6
  } from "@/types";
6
- import type { SafeConversation, SafeMessage } from "@/utils/conversions";
7
+ import type {
8
+ SafeConsent,
9
+ SafeConversation,
10
+ SafeMessage,
11
+ } from "@/utils/conversions";
7
12
 
8
13
  export type ClientStreamEvents =
9
14
  | {
@@ -15,6 +20,16 @@ export type ClientStreamEvents =
15
20
  type: "group";
16
21
  streamId: string;
17
22
  result: SafeConversation | undefined;
23
+ }
24
+ | {
25
+ type: "consent";
26
+ streamId: string;
27
+ result: SafeConsent[] | undefined;
28
+ }
29
+ | {
30
+ type: "preferences";
31
+ streamId: string;
32
+ result: UserPreference[] | undefined;
18
33
  };
19
34
 
20
35
  export type ClientStreamEventsTypes = ClientStreamEvents["type"];
@@ -16,9 +16,8 @@ import {
16
16
  EncodedContent as WasmEncodedContent,
17
17
  type ConsentEntityType,
18
18
  type ConsentState,
19
- type ConversationType,
19
+ type ContentType,
20
20
  type DeliveryStatus,
21
- type GroupMembershipState,
22
21
  type GroupMessageKind,
23
22
  type HmacKey,
24
23
  type InboxState,
@@ -147,6 +146,7 @@ export const toSafeMessage = (message: Message): SafeMessage => ({
147
146
  });
148
147
 
149
148
  export type SafeListMessagesOptions = {
149
+ contentTypes?: ContentType[];
150
150
  deliveryStatus?: DeliveryStatus;
151
151
  direction?: SortDirection;
152
152
  limit?: bigint;
@@ -157,6 +157,7 @@ export type SafeListMessagesOptions = {
157
157
  export const toSafeListMessagesOptions = (
158
158
  options: ListMessagesOptions,
159
159
  ): SafeListMessagesOptions => ({
160
+ contentTypes: options.contentTypes,
160
161
  deliveryStatus: options.deliveryStatus,
161
162
  direction: options.direction,
162
163
  limit: options.limit,
@@ -173,29 +174,24 @@ export const fromSafeListMessagesOptions = (
173
174
  options.limit,
174
175
  options.deliveryStatus,
175
176
  options.direction,
177
+ options.contentTypes,
176
178
  );
177
179
 
178
180
  export type SafeListConversationsOptions = {
179
- allowedStates?: GroupMembershipState[];
180
181
  consentStates?: ConsentState[];
181
- conversationType?: ConversationType;
182
182
  createdAfterNs?: bigint;
183
183
  createdBeforeNs?: bigint;
184
184
  includeDuplicateDms?: boolean;
185
- includeSyncGroups?: boolean;
186
185
  limit?: bigint;
187
186
  };
188
187
 
189
188
  export const toSafeListConversationsOptions = (
190
189
  options: ListConversationsOptions,
191
190
  ): SafeListConversationsOptions => ({
192
- allowedStates: options.allowedStates,
193
191
  consentStates: options.consentStates,
194
- conversationType: options.conversationType,
195
192
  createdAfterNs: options.createdAfterNs,
196
193
  createdBeforeNs: options.createdBeforeNs,
197
194
  includeDuplicateDms: options.includeDuplicateDms,
198
- includeSyncGroups: options.includeSyncGroups,
199
195
  limit: options.limit,
200
196
  });
201
197
 
@@ -203,13 +199,10 @@ export const fromSafeListConversationsOptions = (
203
199
  options: SafeListConversationsOptions,
204
200
  ): ListConversationsOptions =>
205
201
  new ListConversationsOptions(
206
- options.allowedStates,
207
202
  options.consentStates,
208
- options.conversationType,
209
203
  options.createdAfterNs,
210
204
  options.createdBeforeNs,
211
205
  options.includeDuplicateDms ?? false,
212
- options.includeSyncGroups ?? false,
213
206
  options.limit,
214
207
  );
215
208