@xmtp/browser-sdk 2.2.1 → 3.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.
@@ -1,5 +1,4 @@
1
1
  import type { ContentTypeId } from "@xmtp/content-type-primitives";
2
- import { SignatureRequestType } from "@xmtp/wasm-bindings";
3
2
 
4
3
  export class ClientNotInitializedError extends Error {
5
4
  constructor() {
@@ -37,32 +36,6 @@ export class AccountAlreadyAssociatedError extends Error {
37
36
  }
38
37
  }
39
38
 
40
- export class GenerateSignatureError extends Error {
41
- constructor(signatureType: SignatureRequestType) {
42
- let type = "";
43
-
44
- switch (signatureType) {
45
- case SignatureRequestType.AddWallet:
46
- type = "add account";
47
- break;
48
- case SignatureRequestType.CreateInbox:
49
- type = "create inbox";
50
- break;
51
- case SignatureRequestType.RevokeWallet:
52
- type = "remove account";
53
- break;
54
- case SignatureRequestType.RevokeInstallations:
55
- type = "revoke installations";
56
- break;
57
- case SignatureRequestType.ChangeRecoveryIdentifier:
58
- type = "change recovery identifier";
59
- break;
60
- }
61
-
62
- super(`Failed to generate ${type} signature text`);
63
- }
64
- }
65
-
66
39
  export class GroupNotFoundError extends Error {
67
40
  constructor(groupId: string) {
68
41
  super(`Group "${groupId}" not found`);
@@ -21,3 +21,39 @@ export type Signer =
21
21
 
22
22
  export type EOASigner = Extract<Signer, { type: "EOA" }>;
23
23
  export type SCWSigner = Extract<Signer, { type: "SCW" }>;
24
+
25
+ export type SafeSigner =
26
+ | {
27
+ type: "EOA";
28
+ identifier: Identifier;
29
+ signature: Uint8Array;
30
+ }
31
+ | {
32
+ type: "SCW";
33
+ identifier: Identifier;
34
+ signature: Uint8Array;
35
+ chainId: bigint;
36
+ blockNumber?: bigint;
37
+ };
38
+
39
+ export const toSafeSigner = async (
40
+ signer: Signer,
41
+ signature: Uint8Array,
42
+ ): Promise<SafeSigner> => {
43
+ switch (signer.type) {
44
+ case "EOA":
45
+ return {
46
+ type: "EOA",
47
+ identifier: await signer.getIdentifier(),
48
+ signature,
49
+ };
50
+ case "SCW":
51
+ return {
52
+ type: "SCW",
53
+ identifier: await signer.getIdentifier(),
54
+ signature,
55
+ chainId: signer.getChainId(),
56
+ blockNumber: signer.getBlockNumber?.(),
57
+ };
58
+ }
59
+ };
@@ -2,6 +2,7 @@ import init, {
2
2
  type Consent,
3
3
  type Conversation,
4
4
  type Message,
5
+ type SignatureRequestHandle,
5
6
  type StreamCloser,
6
7
  type UserPreference,
7
8
  } from "@xmtp/wasm-bindings";
@@ -43,6 +44,12 @@ let maybeClient: WorkerClient | undefined;
43
44
  let enableLogging = false;
44
45
 
45
46
  const streamClosers = new Map<string, StreamCloser>();
47
+ const signatureRequests = new Map<string, SignatureRequestHandle>();
48
+
49
+ type SignatureRequestResult = {
50
+ signatureText: string;
51
+ signatureRequestId: string;
52
+ };
46
53
 
47
54
  /**
48
55
  * Type-safe postMessage
@@ -143,61 +150,154 @@ self.onmessage = async (
143
150
  /**
144
151
  * Client actions
145
152
  */
153
+ case "client.applySignatureRequest": {
154
+ const signatureRequest = signatureRequests.get(data.signatureRequestId);
155
+ if (!signatureRequest) {
156
+ throw new Error("Signature request not found");
157
+ }
158
+ await client.processSignatureRequest(data.signer, signatureRequest);
159
+ signatureRequests.delete(data.signatureRequestId);
160
+ postMessage({ id, action, result: undefined });
161
+ break;
162
+ }
146
163
  case "client.createInboxSignatureText": {
147
- const result = client.createInboxSignatureText();
148
- postMessage({ id, action, result });
164
+ const result: Partial<SignatureRequestResult> = {
165
+ signatureText: undefined,
166
+ signatureRequestId: undefined,
167
+ };
168
+ try {
169
+ const signatureRequest = client.createInboxSignatureRequest();
170
+ if (signatureRequest) {
171
+ result.signatureText = await signatureRequest.signatureText();
172
+ result.signatureRequestId = data.signatureRequestId;
173
+ signatureRequests.set(data.signatureRequestId, signatureRequest);
174
+ }
175
+ } finally {
176
+ postMessage({ id, action, result });
177
+ }
149
178
  break;
150
179
  }
151
180
  case "client.addAccountSignatureText": {
152
- const result = await client.addAccountSignatureText(data.newIdentifier);
181
+ const signatureRequest = await client.addAccountSignatureRequest(
182
+ data.newIdentifier,
183
+ );
184
+ const result: SignatureRequestResult = {
185
+ signatureText: await signatureRequest.signatureText(),
186
+ signatureRequestId: data.signatureRequestId,
187
+ };
188
+ signatureRequests.set(data.signatureRequestId, signatureRequest);
153
189
  postMessage({ id, action, result });
154
190
  break;
155
191
  }
156
192
  case "client.removeAccountSignatureText": {
157
- const result = await client.removeAccountSignatureText(data.identifier);
193
+ const signatureRequest = await client.removeAccountSignatureRequest(
194
+ data.identifier,
195
+ );
196
+ const result: SignatureRequestResult = {
197
+ signatureText: await signatureRequest.signatureText(),
198
+ signatureRequestId: data.signatureRequestId,
199
+ };
200
+ signatureRequests.set(data.signatureRequestId, signatureRequest);
158
201
  postMessage({ id, action, result });
159
202
  break;
160
203
  }
161
204
  case "client.revokeAllOtherInstallationsSignatureText": {
162
- const result = await client.revokeAllAOtherInstallationsSignatureText();
205
+ const signatureRequest =
206
+ await client.revokeAllOtherInstallationsSignatureRequest();
207
+ const result: SignatureRequestResult = {
208
+ signatureText: await signatureRequest.signatureText(),
209
+ signatureRequestId: data.signatureRequestId,
210
+ };
211
+ signatureRequests.set(data.signatureRequestId, signatureRequest);
163
212
  postMessage({ id, action, result });
164
213
  break;
165
214
  }
166
215
  case "client.revokeInstallationsSignatureText": {
167
- const result = await client.revokeInstallationsSignatureText(
168
- data.installationIds,
169
- );
216
+ const signatureRequest =
217
+ await client.revokeInstallationsSignatureRequest(
218
+ data.installationIds,
219
+ );
220
+ const result: SignatureRequestResult = {
221
+ signatureText: await signatureRequest.signatureText(),
222
+ signatureRequestId: data.signatureRequestId,
223
+ };
224
+ signatureRequests.set(data.signatureRequestId, signatureRequest);
170
225
  postMessage({ id, action, result });
171
226
  break;
172
227
  }
173
228
  case "client.changeRecoveryIdentifierSignatureText": {
174
- const result = await client.changeRecoveryIdentifierSignatureText(
175
- data.identifier,
176
- );
229
+ const signatureRequest =
230
+ await client.changeRecoveryIdentifierSignatureRequest(
231
+ data.identifier,
232
+ );
233
+ const result: SignatureRequestResult = {
234
+ signatureText: await signatureRequest.signatureText(),
235
+ signatureRequestId: data.signatureRequestId,
236
+ };
237
+ signatureRequests.set(data.signatureRequestId, signatureRequest);
177
238
  postMessage({ id, action, result });
178
239
  break;
179
240
  }
180
- case "client.addEcdsaSignature":
181
- await client.addEcdsaSignature(data.type, data.bytes);
241
+ case "client.registerIdentity": {
242
+ const signatureRequest = signatureRequests.get(data.signatureRequestId);
243
+ if (!signatureRequest) {
244
+ throw new Error("Signature request not found");
245
+ }
246
+ await client.registerIdentity(data.signer, signatureRequest);
247
+ signatureRequests.delete(data.signatureRequestId);
182
248
  postMessage({ id, action, result: undefined });
183
249
  break;
184
- case "client.addScwSignature":
185
- await client.addScwSignature(
186
- data.type,
187
- data.bytes,
188
- data.chainId,
189
- data.blockNumber,
190
- );
250
+ }
251
+ case "client.addAccount": {
252
+ const signatureRequest = signatureRequests.get(data.signatureRequestId);
253
+ if (!signatureRequest) {
254
+ throw new Error("Signature request not found");
255
+ }
256
+ await client.processSignatureRequest(data.signer, signatureRequest);
257
+ signatureRequests.delete(data.signatureRequestId);
191
258
  postMessage({ id, action, result: undefined });
192
259
  break;
193
- case "client.applySignatures":
194
- await client.applySignatures();
260
+ }
261
+ case "client.removeAccount": {
262
+ const signatureRequest = signatureRequests.get(data.signatureRequestId);
263
+ if (!signatureRequest) {
264
+ throw new Error("Signature request not found");
265
+ }
266
+ await client.processSignatureRequest(data.signer, signatureRequest);
267
+ signatureRequests.delete(data.signatureRequestId);
195
268
  postMessage({ id, action, result: undefined });
196
269
  break;
197
- case "client.registerIdentity":
198
- await client.registerIdentity();
270
+ }
271
+ case "client.revokeAllOtherInstallations": {
272
+ const signatureRequest = signatureRequests.get(data.signatureRequestId);
273
+ if (!signatureRequest) {
274
+ throw new Error("Signature request not found");
275
+ }
276
+ await client.processSignatureRequest(data.signer, signatureRequest);
277
+ signatureRequests.delete(data.signatureRequestId);
199
278
  postMessage({ id, action, result: undefined });
200
279
  break;
280
+ }
281
+ case "client.revokeInstallations": {
282
+ const signatureRequest = signatureRequests.get(data.signatureRequestId);
283
+ if (!signatureRequest) {
284
+ throw new Error("Signature request not found");
285
+ }
286
+ await client.processSignatureRequest(data.signer, signatureRequest);
287
+ signatureRequests.delete(data.signatureRequestId);
288
+ postMessage({ id, action, result: undefined });
289
+ break;
290
+ }
291
+ case "client.changeRecoveryIdentifier": {
292
+ const signatureRequest = signatureRequests.get(data.signatureRequestId);
293
+ if (!signatureRequest) {
294
+ throw new Error("Signature request not found");
295
+ }
296
+ await client.processSignatureRequest(data.signer, signatureRequest);
297
+ signatureRequests.delete(data.signatureRequestId);
298
+ postMessage({ id, action, result: undefined });
299
+ break;
300
+ }
201
301
  case "client.isRegistered": {
202
302
  const result = client.isRegistered;
203
303
  postMessage({ id, action, result });
@@ -252,30 +352,36 @@ self.onmessage = async (
252
352
  });
253
353
  break;
254
354
  }
255
- case "client.apiStatistics": {
256
- const apiStats = client.apiStatistics();
355
+ /**
356
+ * Debug information actions
357
+ */
358
+ case "debugInformation.apiStatistics": {
359
+ const apiStats = client.debugInformation.apiStatistics();
257
360
  const result = toSafeApiStats(apiStats);
258
361
  postMessage({ id, action, result });
259
362
  break;
260
363
  }
261
- case "client.apiIdentityStatistics": {
262
- const apiIdentityStats = client.apiIdentityStatistics();
364
+ case "debugInformation.apiIdentityStatistics": {
365
+ const apiIdentityStats =
366
+ client.debugInformation.apiIdentityStatistics();
263
367
  const result = toSafeIdentityStats(apiIdentityStats);
264
368
  postMessage({ id, action, result });
265
369
  break;
266
370
  }
267
- case "client.apiAggregateStatistics": {
268
- const result = client.apiAggregateStatistics();
371
+ case "debugInformation.apiAggregateStatistics": {
372
+ const result = client.debugInformation.apiAggregateStatistics();
269
373
  postMessage({ id, action, result });
270
374
  break;
271
375
  }
272
- case "client.clearAllStatistics": {
273
- client.clearAllStatistics();
376
+ case "debugInformation.clearAllStatistics": {
377
+ client.debugInformation.clearAllStatistics();
274
378
  postMessage({ id, action, result: undefined });
275
379
  break;
276
380
  }
277
- case "client.uploadDebugArchive": {
278
- const result = await client.uploadDebugArchive(data.serverUrl);
381
+ case "debugInformation.uploadDebugArchive": {
382
+ const result = await client.debugInformation.uploadDebugArchive(
383
+ data.serverUrl,
384
+ );
279
385
  postMessage({ id, action, result });
280
386
  break;
281
387
  }
@@ -1,6 +1,9 @@
1
1
  import init, {
2
+ applySignatureRequest,
2
3
  generateInboxId,
3
4
  getInboxIdForIdentifier as get_inbox_id_for_identifier,
5
+ inboxStateFromInboxIds,
6
+ revokeInstallationsSignatureRequest,
4
7
  type Identifier,
5
8
  } from "@xmtp/wasm-bindings";
6
9
  import { ApiUrls } from "@/constants";
@@ -12,6 +15,7 @@ import type {
12
15
  } from "@/types/actions";
13
16
  import type { UtilsWorkerAction } from "@/types/actions/utils";
14
17
  import type { XmtpEnv } from "@/types/options";
18
+ import { toSafeInboxState } from "@/utils/conversions";
15
19
 
16
20
  /**
17
21
  * Type-safe postMessage
@@ -72,6 +76,52 @@ self.onmessage = async (
72
76
  postMessage({ id, action, result });
73
77
  break;
74
78
  }
79
+ case "utils.revokeInstallationsSignatureText": {
80
+ const host = ApiUrls[data.env ?? "dev"];
81
+ const signatureRequest = await revokeInstallationsSignatureRequest(
82
+ host,
83
+ data.identifier,
84
+ data.inboxId,
85
+ data.installationIds,
86
+ );
87
+ const signatureText = await signatureRequest.signatureText();
88
+ postMessage({ id, action, result: signatureText });
89
+ break;
90
+ }
91
+ case "utils.revokeInstallations": {
92
+ const host = ApiUrls[data.env ?? "dev"];
93
+ const signatureRequest = await revokeInstallationsSignatureRequest(
94
+ host,
95
+ data.signer.identifier,
96
+ data.inboxId,
97
+ data.installationIds,
98
+ );
99
+ switch (data.signer.type) {
100
+ case "EOA":
101
+ await signatureRequest.addEcdsaSignature(data.signer.signature);
102
+ break;
103
+ case "SCW":
104
+ await signatureRequest.addScwSignature(
105
+ data.signer.identifier,
106
+ data.signer.signature,
107
+ data.signer.chainId,
108
+ data.signer.blockNumber,
109
+ );
110
+ break;
111
+ }
112
+ await applySignatureRequest(host, signatureRequest);
113
+ postMessage({ id, action, result: undefined });
114
+ break;
115
+ }
116
+ case "utils.inboxStateFromInboxIds": {
117
+ const host = ApiUrls[data.env ?? "dev"];
118
+ const inboxStates = await inboxStateFromInboxIds(host, data.inboxIds);
119
+ const result = inboxStates.map((inboxState) =>
120
+ toSafeInboxState(inboxState),
121
+ );
122
+ postMessage({ id, action, result });
123
+ break;
124
+ }
75
125
  }
76
126
  } catch (e) {
77
127
  postMessageError({ id, action, error: e as Error });