@xmtp/browser-sdk 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.
- package/LICENSE +21 -0
- package/README.md +118 -0
- package/dist/index.d.ts +791 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/dist/workers/client.js +2 -0
- package/dist/workers/client.js.map +1 -0
- package/dist/workers/utils.js +2 -0
- package/dist/workers/utils.js.map +1 -0
- package/package.json +101 -0
- package/src/Client.ts +181 -0
- package/src/ClientWorkerClass.ts +71 -0
- package/src/Conversation.ts +285 -0
- package/src/Conversations.ts +50 -0
- package/src/DecodedMessage.ts +71 -0
- package/src/Utils.ts +28 -0
- package/src/UtilsWorkerClass.ts +71 -0
- package/src/WorkerClient.ts +124 -0
- package/src/WorkerConversation.ts +169 -0
- package/src/WorkerConversations.ts +60 -0
- package/src/constants.ts +5 -0
- package/src/index.ts +9 -0
- package/src/types/clientEvents.ts +426 -0
- package/src/types/index.ts +4 -0
- package/src/types/options.ts +59 -0
- package/src/types/utils.ts +46 -0
- package/src/types/utilsEvents.ts +53 -0
- package/src/utils/conversions.ts +352 -0
- package/src/utils/createClient.ts +30 -0
- package/src/utils/date.ts +3 -0
- package/src/workers/client.ts +689 -0
- package/src/workers/utils.ts +72 -0
- package/tsconfig.json +11 -0
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { v4 } from "uuid";
|
|
2
|
+
import type {
|
|
3
|
+
ClientEventsActions,
|
|
4
|
+
ClientEventsErrorData,
|
|
5
|
+
ClientEventsResult,
|
|
6
|
+
ClientEventsWorkerMessageData,
|
|
7
|
+
ClientSendMessageData,
|
|
8
|
+
} from "@/types";
|
|
9
|
+
|
|
10
|
+
const handleError = (event: ErrorEvent) => {
|
|
11
|
+
console.error(`Worker error on line ${event.lineno} in "${event.filename}"`);
|
|
12
|
+
console.error(event.message);
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export class ClientWorkerClass {
|
|
16
|
+
#worker: Worker;
|
|
17
|
+
|
|
18
|
+
#enableLogging: boolean;
|
|
19
|
+
|
|
20
|
+
#promises = new Map<
|
|
21
|
+
string,
|
|
22
|
+
{ resolve: (value: any) => void; reject: (reason?: any) => void }
|
|
23
|
+
>();
|
|
24
|
+
|
|
25
|
+
constructor(worker: Worker, enableLogging: boolean) {
|
|
26
|
+
this.#worker = worker;
|
|
27
|
+
this.#worker.addEventListener("message", this.handleMessage);
|
|
28
|
+
this.#worker.addEventListener("error", handleError);
|
|
29
|
+
this.#enableLogging = enableLogging;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
sendMessage<A extends ClientEventsActions>(
|
|
33
|
+
action: A,
|
|
34
|
+
data: ClientSendMessageData<A>,
|
|
35
|
+
) {
|
|
36
|
+
const promiseId = v4();
|
|
37
|
+
this.#worker.postMessage({
|
|
38
|
+
action,
|
|
39
|
+
id: promiseId,
|
|
40
|
+
data,
|
|
41
|
+
});
|
|
42
|
+
const promise = new Promise<ClientEventsResult<A>>((resolve, reject) => {
|
|
43
|
+
this.#promises.set(promiseId, { resolve, reject });
|
|
44
|
+
});
|
|
45
|
+
return promise;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
handleMessage = (
|
|
49
|
+
event: MessageEvent<ClientEventsWorkerMessageData | ClientEventsErrorData>,
|
|
50
|
+
) => {
|
|
51
|
+
const eventData = event.data;
|
|
52
|
+
if (this.#enableLogging) {
|
|
53
|
+
console.log("client received event data", eventData);
|
|
54
|
+
}
|
|
55
|
+
const promise = this.#promises.get(eventData.id);
|
|
56
|
+
if (promise) {
|
|
57
|
+
this.#promises.delete(eventData.id);
|
|
58
|
+
if ("error" in eventData) {
|
|
59
|
+
promise.reject(new Error(eventData.error));
|
|
60
|
+
} else {
|
|
61
|
+
promise.resolve(eventData.result);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
close() {
|
|
67
|
+
this.#worker.removeEventListener("message", this.handleMessage);
|
|
68
|
+
this.#worker.removeEventListener("error", handleError);
|
|
69
|
+
this.#worker.terminate();
|
|
70
|
+
}
|
|
71
|
+
}
|
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
import type { ContentTypeId } from "@xmtp/content-type-primitives";
|
|
2
|
+
import { ContentTypeText } from "@xmtp/content-type-text";
|
|
3
|
+
import type { WasmConsentState } from "@xmtp/wasm-bindings";
|
|
4
|
+
import type { Client } from "@/Client";
|
|
5
|
+
import { DecodedMessage } from "@/DecodedMessage";
|
|
6
|
+
import type {
|
|
7
|
+
SafeConversation,
|
|
8
|
+
SafeListMessagesOptions,
|
|
9
|
+
} from "@/utils/conversions";
|
|
10
|
+
import { nsToDate } from "@/utils/date";
|
|
11
|
+
|
|
12
|
+
export class Conversation {
|
|
13
|
+
#client: Client;
|
|
14
|
+
|
|
15
|
+
#id: string;
|
|
16
|
+
|
|
17
|
+
#name?: SafeConversation["name"];
|
|
18
|
+
|
|
19
|
+
#imageUrl?: SafeConversation["imageUrl"];
|
|
20
|
+
|
|
21
|
+
#description?: SafeConversation["description"];
|
|
22
|
+
|
|
23
|
+
#pinnedFrameUrl?: SafeConversation["pinnedFrameUrl"];
|
|
24
|
+
|
|
25
|
+
#isActive?: SafeConversation["isActive"];
|
|
26
|
+
|
|
27
|
+
#addedByInboxId?: SafeConversation["addedByInboxId"];
|
|
28
|
+
|
|
29
|
+
#metadata?: SafeConversation["metadata"];
|
|
30
|
+
|
|
31
|
+
#permissions?: SafeConversation["permissions"];
|
|
32
|
+
|
|
33
|
+
#createdAtNs?: SafeConversation["createdAtNs"];
|
|
34
|
+
|
|
35
|
+
constructor(client: Client, id: string, data?: SafeConversation) {
|
|
36
|
+
this.#client = client;
|
|
37
|
+
this.#id = id;
|
|
38
|
+
this.#syncData(data);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
#syncData(data?: SafeConversation) {
|
|
42
|
+
this.#name = data?.name ?? "";
|
|
43
|
+
this.#imageUrl = data?.imageUrl ?? "";
|
|
44
|
+
this.#description = data?.description ?? "";
|
|
45
|
+
this.#pinnedFrameUrl = data?.pinnedFrameUrl ?? "";
|
|
46
|
+
this.#isActive = data?.isActive ?? undefined;
|
|
47
|
+
this.#addedByInboxId = data?.addedByInboxId ?? "";
|
|
48
|
+
this.#metadata = data?.metadata ?? undefined;
|
|
49
|
+
this.#permissions = data?.permissions ?? undefined;
|
|
50
|
+
this.#createdAtNs = data?.createdAtNs ?? undefined;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
get id() {
|
|
54
|
+
return this.#id;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
get name() {
|
|
58
|
+
return this.#name;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
async updateName(name: string) {
|
|
62
|
+
await this.#client.sendMessage("updateGroupName", {
|
|
63
|
+
id: this.#id,
|
|
64
|
+
name,
|
|
65
|
+
});
|
|
66
|
+
this.#name = name;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
get imageUrl() {
|
|
70
|
+
return this.#imageUrl;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
async updateImageUrl(imageUrl: string) {
|
|
74
|
+
await this.#client.sendMessage("updateGroupImageUrlSquare", {
|
|
75
|
+
id: this.#id,
|
|
76
|
+
imageUrl,
|
|
77
|
+
});
|
|
78
|
+
this.#imageUrl = imageUrl;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
get description() {
|
|
82
|
+
return this.#description;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
async updateDescription(description: string) {
|
|
86
|
+
await this.#client.sendMessage("updateGroupDescription", {
|
|
87
|
+
id: this.#id,
|
|
88
|
+
description,
|
|
89
|
+
});
|
|
90
|
+
this.#description = description;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
get pinnedFrameUrl() {
|
|
94
|
+
return this.#pinnedFrameUrl;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
async updatePinnedFrameUrl(pinnedFrameUrl: string) {
|
|
98
|
+
await this.#client.sendMessage("updateGroupPinnedFrameUrl", {
|
|
99
|
+
id: this.#id,
|
|
100
|
+
pinnedFrameUrl,
|
|
101
|
+
});
|
|
102
|
+
this.#pinnedFrameUrl = pinnedFrameUrl;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
get isActive() {
|
|
106
|
+
return this.#isActive;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
get addedByInboxId() {
|
|
110
|
+
return this.#addedByInboxId;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
get createdAtNs() {
|
|
114
|
+
return this.#createdAtNs;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
get createdAt() {
|
|
118
|
+
return this.#createdAtNs ? nsToDate(this.#createdAtNs) : undefined;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
get metadata() {
|
|
122
|
+
return this.#metadata;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
async members() {
|
|
126
|
+
return this.#client.sendMessage("getGroupMembers", {
|
|
127
|
+
id: this.#id,
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
async admins() {
|
|
132
|
+
return this.#client.sendMessage("getGroupAdmins", {
|
|
133
|
+
id: this.#id,
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
async superAdmins() {
|
|
138
|
+
return this.#client.sendMessage("getGroupSuperAdmins", {
|
|
139
|
+
id: this.#id,
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
get permissions() {
|
|
144
|
+
return this.#permissions;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
async isAdmin(inboxId: string) {
|
|
148
|
+
const admins = await this.admins();
|
|
149
|
+
return admins.includes(inboxId);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
async isSuperAdmin(inboxId: string) {
|
|
153
|
+
const superAdmins = await this.superAdmins();
|
|
154
|
+
return superAdmins.includes(inboxId);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
async sync() {
|
|
158
|
+
const data = await this.#client.sendMessage("syncGroup", {
|
|
159
|
+
id: this.#id,
|
|
160
|
+
});
|
|
161
|
+
this.#syncData(data);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
async addMembers(accountAddresses: string[]) {
|
|
165
|
+
return this.#client.sendMessage("addGroupMembers", {
|
|
166
|
+
id: this.#id,
|
|
167
|
+
accountAddresses,
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
async addMembersByInboxId(inboxIds: string[]) {
|
|
172
|
+
return this.#client.sendMessage("addGroupMembersByInboxId", {
|
|
173
|
+
id: this.#id,
|
|
174
|
+
inboxIds,
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
async removeMembers(accountAddresses: string[]) {
|
|
179
|
+
return this.#client.sendMessage("removeGroupMembers", {
|
|
180
|
+
id: this.#id,
|
|
181
|
+
accountAddresses,
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
async removeMembersByInboxId(inboxIds: string[]) {
|
|
186
|
+
return this.#client.sendMessage("removeGroupMembersByInboxId", {
|
|
187
|
+
id: this.#id,
|
|
188
|
+
inboxIds,
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
async addAdmin(inboxId: string) {
|
|
193
|
+
return this.#client.sendMessage("addGroupAdmin", {
|
|
194
|
+
id: this.#id,
|
|
195
|
+
inboxId,
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
async removeAdmin(inboxId: string) {
|
|
200
|
+
return this.#client.sendMessage("removeGroupAdmin", {
|
|
201
|
+
id: this.#id,
|
|
202
|
+
inboxId,
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
async addSuperAdmin(inboxId: string) {
|
|
207
|
+
return this.#client.sendMessage("addGroupSuperAdmin", {
|
|
208
|
+
id: this.#id,
|
|
209
|
+
inboxId,
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
async removeSuperAdmin(inboxId: string) {
|
|
214
|
+
return this.#client.sendMessage("removeGroupSuperAdmin", {
|
|
215
|
+
id: this.#id,
|
|
216
|
+
inboxId,
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
async publishMessages() {
|
|
221
|
+
return this.#client.sendMessage("publishGroupMessages", {
|
|
222
|
+
id: this.#id,
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
async sendOptimistic(content: any, contentType?: ContentTypeId) {
|
|
227
|
+
if (typeof content !== "string" && !contentType) {
|
|
228
|
+
throw new Error(
|
|
229
|
+
"Content type is required when sending content other than text",
|
|
230
|
+
);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
const safeEncodedContent =
|
|
234
|
+
typeof content === "string"
|
|
235
|
+
? this.#client.encodeContent(content, contentType ?? ContentTypeText)
|
|
236
|
+
: // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
237
|
+
this.#client.encodeContent(content, contentType!);
|
|
238
|
+
|
|
239
|
+
return this.#client.sendMessage("sendOptimisticGroupMessage", {
|
|
240
|
+
id: this.#id,
|
|
241
|
+
content: safeEncodedContent,
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
async send(content: any, contentType?: ContentTypeId) {
|
|
246
|
+
if (typeof content !== "string" && !contentType) {
|
|
247
|
+
throw new Error(
|
|
248
|
+
"Content type is required when sending content other than text",
|
|
249
|
+
);
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
const safeEncodedContent =
|
|
253
|
+
typeof content === "string"
|
|
254
|
+
? this.#client.encodeContent(content, contentType ?? ContentTypeText)
|
|
255
|
+
: // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
256
|
+
this.#client.encodeContent(content, contentType!);
|
|
257
|
+
|
|
258
|
+
return this.#client.sendMessage("sendGroupMessage", {
|
|
259
|
+
id: this.#id,
|
|
260
|
+
content: safeEncodedContent,
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
async messages(options?: SafeListMessagesOptions) {
|
|
265
|
+
const messages = await this.#client.sendMessage("getGroupMessages", {
|
|
266
|
+
id: this.#id,
|
|
267
|
+
options,
|
|
268
|
+
});
|
|
269
|
+
|
|
270
|
+
return messages.map((message) => new DecodedMessage(this.#client, message));
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
async consentState() {
|
|
274
|
+
return this.#client.sendMessage("getGroupConsentState", {
|
|
275
|
+
id: this.#id,
|
|
276
|
+
});
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
async updateConsentState(state: WasmConsentState) {
|
|
280
|
+
return this.#client.sendMessage("updateGroupConsentState", {
|
|
281
|
+
id: this.#id,
|
|
282
|
+
state,
|
|
283
|
+
});
|
|
284
|
+
}
|
|
285
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import type { Client } from "@/Client";
|
|
2
|
+
import { Conversation } from "@/Conversation";
|
|
3
|
+
import type {
|
|
4
|
+
SafeCreateGroupOptions,
|
|
5
|
+
SafeListConversationsOptions,
|
|
6
|
+
} from "@/utils/conversions";
|
|
7
|
+
|
|
8
|
+
export class Conversations {
|
|
9
|
+
#client: Client;
|
|
10
|
+
|
|
11
|
+
constructor(client: Client) {
|
|
12
|
+
this.#client = client;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
async sync() {
|
|
16
|
+
return this.#client.sendMessage("syncConversations", undefined);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
async getConversationById(id: string) {
|
|
20
|
+
return this.#client.sendMessage("getConversationById", {
|
|
21
|
+
id,
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
async getMessageById(id: string) {
|
|
26
|
+
return this.#client.sendMessage("getMessageById", {
|
|
27
|
+
id,
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
async list(options?: SafeListConversationsOptions) {
|
|
32
|
+
const conversations = await this.#client.sendMessage("getConversations", {
|
|
33
|
+
options,
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
return conversations.map(
|
|
37
|
+
(conversation) =>
|
|
38
|
+
new Conversation(this.#client, conversation.id, conversation),
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
async newGroup(accountAddresses: string[], options?: SafeCreateGroupOptions) {
|
|
43
|
+
const conversation = await this.#client.sendMessage("newGroup", {
|
|
44
|
+
accountAddresses,
|
|
45
|
+
options,
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
return new Conversation(this.#client, conversation.id, conversation);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import type { ContentTypeId } from "@xmtp/content-type-primitives";
|
|
2
|
+
import { WasmDeliveryStatus, WasmGroupMessageKind } from "@xmtp/wasm-bindings";
|
|
3
|
+
import type { Client } from "@/Client";
|
|
4
|
+
import { fromSafeContentTypeId, type SafeMessage } from "@/utils/conversions";
|
|
5
|
+
|
|
6
|
+
export type MessageKind = "application" | "membership_change";
|
|
7
|
+
export type MessageDeliveryStatus = "unpublished" | "published" | "failed";
|
|
8
|
+
|
|
9
|
+
export class DecodedMessage {
|
|
10
|
+
#client: Client;
|
|
11
|
+
|
|
12
|
+
content: any;
|
|
13
|
+
|
|
14
|
+
contentType: ContentTypeId;
|
|
15
|
+
|
|
16
|
+
conversationId: string;
|
|
17
|
+
|
|
18
|
+
deliveryStatus: MessageDeliveryStatus;
|
|
19
|
+
|
|
20
|
+
fallback?: string;
|
|
21
|
+
|
|
22
|
+
compression?: number;
|
|
23
|
+
|
|
24
|
+
id: string;
|
|
25
|
+
|
|
26
|
+
kind: MessageKind;
|
|
27
|
+
|
|
28
|
+
parameters: Map<string, string>;
|
|
29
|
+
|
|
30
|
+
senderInboxId: string;
|
|
31
|
+
|
|
32
|
+
sentAtNs: bigint;
|
|
33
|
+
|
|
34
|
+
constructor(client: Client, message: SafeMessage) {
|
|
35
|
+
this.#client = client;
|
|
36
|
+
this.id = message.id;
|
|
37
|
+
this.sentAtNs = message.sentAtNs;
|
|
38
|
+
this.conversationId = message.convoId;
|
|
39
|
+
this.senderInboxId = message.senderInboxId;
|
|
40
|
+
|
|
41
|
+
switch (message.kind) {
|
|
42
|
+
case WasmGroupMessageKind.Application:
|
|
43
|
+
this.kind = "application";
|
|
44
|
+
break;
|
|
45
|
+
case WasmGroupMessageKind.MembershipChange:
|
|
46
|
+
this.kind = "membership_change";
|
|
47
|
+
break;
|
|
48
|
+
// no default
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
switch (message.deliveryStatus) {
|
|
52
|
+
case WasmDeliveryStatus.Unpublished:
|
|
53
|
+
this.deliveryStatus = "unpublished";
|
|
54
|
+
break;
|
|
55
|
+
case WasmDeliveryStatus.Published:
|
|
56
|
+
this.deliveryStatus = "published";
|
|
57
|
+
break;
|
|
58
|
+
case WasmDeliveryStatus.Failed:
|
|
59
|
+
this.deliveryStatus = "failed";
|
|
60
|
+
break;
|
|
61
|
+
// no default
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
this.contentType = fromSafeContentTypeId(message.content.type);
|
|
65
|
+
this.parameters = new Map(Object.entries(message.content.parameters));
|
|
66
|
+
this.fallback = message.content.fallback;
|
|
67
|
+
this.compression = message.content.compression;
|
|
68
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
69
|
+
this.content = this.#client.decodeContent(message, this.contentType);
|
|
70
|
+
}
|
|
71
|
+
}
|
package/src/Utils.ts
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { XmtpEnv } from "@/types/options";
|
|
2
|
+
import { UtilsWorkerClass } from "@/UtilsWorkerClass";
|
|
3
|
+
|
|
4
|
+
export class Utils extends UtilsWorkerClass {
|
|
5
|
+
#enableLogging: boolean;
|
|
6
|
+
constructor(enableLogging?: boolean) {
|
|
7
|
+
const worker = new Worker(new URL("./workers/utils", import.meta.url), {
|
|
8
|
+
type: "module",
|
|
9
|
+
});
|
|
10
|
+
super(worker, enableLogging ?? false);
|
|
11
|
+
this.#enableLogging = enableLogging ?? false;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
async generateInboxId(address: string) {
|
|
15
|
+
return this.sendMessage("generateInboxId", {
|
|
16
|
+
address,
|
|
17
|
+
enableLogging: this.#enableLogging,
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
async getInboxIdForAddress(address: string, env?: XmtpEnv) {
|
|
22
|
+
return this.sendMessage("getInboxIdForAddress", {
|
|
23
|
+
address,
|
|
24
|
+
env,
|
|
25
|
+
enableLogging: this.#enableLogging,
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { v4 } from "uuid";
|
|
2
|
+
import type {
|
|
3
|
+
UtilsEventsActions,
|
|
4
|
+
UtilsEventsErrorData,
|
|
5
|
+
UtilsEventsResult,
|
|
6
|
+
UtilsEventsWorkerMessageData,
|
|
7
|
+
UtilsSendMessageData,
|
|
8
|
+
} from "@/types";
|
|
9
|
+
|
|
10
|
+
const handleError = (event: ErrorEvent) => {
|
|
11
|
+
console.error(`Worker error on line ${event.lineno} in "${event.filename}"`);
|
|
12
|
+
console.error(event.message);
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export class UtilsWorkerClass {
|
|
16
|
+
#worker: Worker;
|
|
17
|
+
|
|
18
|
+
#enableLogging: boolean;
|
|
19
|
+
|
|
20
|
+
#promises = new Map<
|
|
21
|
+
string,
|
|
22
|
+
{ resolve: (value: any) => void; reject: (reason?: any) => void }
|
|
23
|
+
>();
|
|
24
|
+
|
|
25
|
+
constructor(worker: Worker, enableLogging: boolean) {
|
|
26
|
+
this.#worker = worker;
|
|
27
|
+
this.#worker.addEventListener("message", this.handleMessage);
|
|
28
|
+
this.#worker.addEventListener("error", handleError);
|
|
29
|
+
this.#enableLogging = enableLogging;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
sendMessage<A extends UtilsEventsActions>(
|
|
33
|
+
action: A,
|
|
34
|
+
data: UtilsSendMessageData<A>,
|
|
35
|
+
) {
|
|
36
|
+
const promiseId = v4();
|
|
37
|
+
this.#worker.postMessage({
|
|
38
|
+
action,
|
|
39
|
+
id: promiseId,
|
|
40
|
+
data,
|
|
41
|
+
});
|
|
42
|
+
const promise = new Promise<UtilsEventsResult<A>>((resolve, reject) => {
|
|
43
|
+
this.#promises.set(promiseId, { resolve, reject });
|
|
44
|
+
});
|
|
45
|
+
return promise;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
handleMessage = (
|
|
49
|
+
event: MessageEvent<UtilsEventsWorkerMessageData | UtilsEventsErrorData>,
|
|
50
|
+
) => {
|
|
51
|
+
const eventData = event.data;
|
|
52
|
+
if (this.#enableLogging) {
|
|
53
|
+
console.log("utils received event data", eventData);
|
|
54
|
+
}
|
|
55
|
+
const promise = this.#promises.get(eventData.id);
|
|
56
|
+
if (promise) {
|
|
57
|
+
this.#promises.delete(eventData.id);
|
|
58
|
+
if ("error" in eventData) {
|
|
59
|
+
promise.reject(new Error(eventData.error));
|
|
60
|
+
} else {
|
|
61
|
+
promise.resolve(eventData.result);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
close() {
|
|
67
|
+
this.#worker.removeEventListener("message", this.handleMessage);
|
|
68
|
+
this.#worker.removeEventListener("error", handleError);
|
|
69
|
+
this.#worker.terminate();
|
|
70
|
+
}
|
|
71
|
+
}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import {
|
|
2
|
+
type WasmClient,
|
|
3
|
+
type WasmConsentEntityType,
|
|
4
|
+
type WasmSignatureRequestType,
|
|
5
|
+
} from "@xmtp/wasm-bindings";
|
|
6
|
+
import type { ClientOptions } from "@/types";
|
|
7
|
+
import { fromSafeConsent, type SafeConsent } from "@/utils/conversions";
|
|
8
|
+
import { createClient } from "@/utils/createClient";
|
|
9
|
+
import { WorkerConversations } from "@/WorkerConversations";
|
|
10
|
+
|
|
11
|
+
export class WorkerClient {
|
|
12
|
+
#client: WasmClient;
|
|
13
|
+
|
|
14
|
+
#conversations: WorkerConversations;
|
|
15
|
+
|
|
16
|
+
#accountAddress: string;
|
|
17
|
+
|
|
18
|
+
constructor(client: WasmClient) {
|
|
19
|
+
this.#client = client;
|
|
20
|
+
this.#accountAddress = client.accountAddress;
|
|
21
|
+
this.#conversations = new WorkerConversations(this, client.conversations());
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
static async create(
|
|
25
|
+
accountAddress: string,
|
|
26
|
+
options?: Omit<ClientOptions, "codecs">,
|
|
27
|
+
) {
|
|
28
|
+
const client = await createClient(accountAddress, options);
|
|
29
|
+
return new WorkerClient(client);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
get accountAddress() {
|
|
33
|
+
return this.#accountAddress;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
get inboxId() {
|
|
37
|
+
return this.#client.inboxId;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
get installationId() {
|
|
41
|
+
return this.#client.installationId;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
get isRegistered() {
|
|
45
|
+
return this.#client.isRegistered;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
async getCreateInboxSignatureText() {
|
|
49
|
+
try {
|
|
50
|
+
return await this.#client.createInboxSignatureText();
|
|
51
|
+
} catch {
|
|
52
|
+
return undefined;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
async getAddWalletSignatureText(accountAddress: string) {
|
|
57
|
+
try {
|
|
58
|
+
return await this.#client.addWalletSignatureText(
|
|
59
|
+
this.#accountAddress,
|
|
60
|
+
accountAddress,
|
|
61
|
+
);
|
|
62
|
+
} catch {
|
|
63
|
+
return undefined;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
async getRevokeWalletSignatureText(accountAddress: string) {
|
|
68
|
+
try {
|
|
69
|
+
return await this.#client.revokeWalletSignatureText(accountAddress);
|
|
70
|
+
} catch {
|
|
71
|
+
return undefined;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
async getRevokeInstallationsSignatureText() {
|
|
76
|
+
try {
|
|
77
|
+
return await this.#client.revokeInstallationsSignatureText();
|
|
78
|
+
} catch {
|
|
79
|
+
return undefined;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
async addSignature(type: WasmSignatureRequestType, bytes: Uint8Array) {
|
|
84
|
+
return this.#client.addSignature(type, bytes);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
async applySignaturesRequests() {
|
|
88
|
+
return this.#client.applySignatureRequests();
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
async canMessage(accountAddresses: string[]) {
|
|
92
|
+
return this.#client.canMessage(accountAddresses) as Promise<
|
|
93
|
+
Map<string, boolean>
|
|
94
|
+
>;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
async registerIdentity() {
|
|
98
|
+
return this.#client.registerIdentity();
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
async findInboxIdByAddress(address: string) {
|
|
102
|
+
return this.#client.findInboxIdByAddress(address);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
async inboxState(refreshFromNetwork: boolean) {
|
|
106
|
+
return this.#client.inboxState(refreshFromNetwork);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
async getLatestInboxState(inboxId: string) {
|
|
110
|
+
return this.#client.getLatestInboxState(inboxId);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
async setConsentStates(records: SafeConsent[]) {
|
|
114
|
+
return this.#client.setConsentStates(records.map(fromSafeConsent));
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
async getConsentState(entityType: WasmConsentEntityType, entity: string) {
|
|
118
|
+
return this.#client.getConsentState(entityType, entity);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
get conversations() {
|
|
122
|
+
return this.#conversations;
|
|
123
|
+
}
|
|
124
|
+
}
|