@xmtp/browser-sdk 5.3.0 → 6.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 (53) hide show
  1. package/dist/index.d.ts +541 -671
  2. package/dist/index.js +1 -1
  3. package/dist/index.js.map +1 -1
  4. package/dist/workers/client.js +1 -1
  5. package/dist/workers/client.js.map +1 -1
  6. package/dist/workers/opfs.js +2 -0
  7. package/dist/workers/opfs.js.map +1 -0
  8. package/package.json +12 -16
  9. package/src/Client.ts +92 -219
  10. package/src/CodecRegistry.ts +27 -0
  11. package/src/Conversation.ts +275 -104
  12. package/src/Conversations.ts +188 -99
  13. package/src/DebugInformation.ts +10 -27
  14. package/src/DecodedMessage.ts +155 -58
  15. package/src/Dm.ts +25 -9
  16. package/src/Group.ts +30 -29
  17. package/src/Opfs.ts +63 -0
  18. package/src/Preferences.ts +68 -52
  19. package/src/WorkerClient.ts +5 -5
  20. package/src/WorkerConversation.ts +98 -45
  21. package/src/WorkerConversations.ts +35 -74
  22. package/src/WorkerDebugInformation.ts +1 -12
  23. package/src/WorkerPreferences.ts +6 -14
  24. package/src/index.ts +54 -24
  25. package/src/types/actions/client.ts +6 -17
  26. package/src/types/actions/conversation.ts +160 -31
  27. package/src/types/actions/conversations.ts +21 -24
  28. package/src/types/actions/debugInformation.ts +3 -11
  29. package/src/types/actions/dm.ts +1 -1
  30. package/src/types/actions/opfs.ts +66 -0
  31. package/src/types/actions/preferences.ts +6 -13
  32. package/src/types/actions/streams.ts +8 -8
  33. package/src/types/actions.ts +11 -9
  34. package/src/types/options.ts +46 -6
  35. package/src/{ClientWorkerClass.ts → utils/WorkerBridge.ts} +35 -45
  36. package/src/utils/contentTypes.ts +77 -0
  37. package/src/utils/conversions.ts +17 -590
  38. package/src/utils/createClient.ts +16 -11
  39. package/src/utils/errors.ts +13 -19
  40. package/src/utils/inboxId.ts +46 -0
  41. package/src/utils/inboxState.ts +23 -0
  42. package/src/utils/installations.ts +95 -0
  43. package/src/utils/metadata.ts +15 -0
  44. package/src/utils/signer.ts +4 -4
  45. package/src/utils/uuid.ts +8 -0
  46. package/src/workers/client.ts +176 -135
  47. package/src/workers/opfs.ts +127 -0
  48. package/dist/workers/utils.js +0 -2
  49. package/dist/workers/utils.js.map +0 -1
  50. package/src/Utils.ts +0 -143
  51. package/src/UtilsWorkerClass.ts +0 -121
  52. package/src/types/actions/utils.ts +0 -69
  53. package/src/workers/utils.ts +0 -155
package/src/Client.ts CHANGED
@@ -1,56 +1,45 @@
1
- import {
2
- ContentTypeGroupUpdated,
3
- GroupUpdatedCodec,
4
- } from "@xmtp/content-type-group-updated";
5
- import type {
6
- ContentCodec,
7
- ContentTypeId,
8
- } from "@xmtp/content-type-primitives";
9
- import { TextCodec } from "@xmtp/content-type-text";
10
- import { GroupMessageKind, type Identifier } from "@xmtp/wasm-bindings";
11
- import { v4 } from "uuid";
12
- import { ClientWorkerClass } from "@/ClientWorkerClass";
1
+ import { type ContentCodec } from "@xmtp/content-type-primitives";
2
+ import { LogLevel, type Identifier } from "@xmtp/wasm-bindings";
3
+ import { CodecRegistry } from "@/CodecRegistry";
13
4
  import { Conversations } from "@/Conversations";
14
5
  import { DebugInformation } from "@/DebugInformation";
15
6
  import { Preferences } from "@/Preferences";
16
- import type { ClientOptions, XmtpEnv } from "@/types/options";
17
- import { Utils } from "@/Utils";
18
- import {
19
- fromSafeEncodedContent,
20
- toSafeEncodedContent,
21
- type SafeMessage,
22
- } from "@/utils/conversions";
7
+ import type { ClientWorkerAction } from "@/types/actions";
8
+ import type {
9
+ ClientOptions,
10
+ ExtractCodecContentTypes,
11
+ XmtpEnv,
12
+ } from "@/types/options";
23
13
  import {
24
14
  AccountAlreadyAssociatedError,
25
- CodecNotFoundError,
26
15
  InboxReassignError,
27
- InvalidGroupMembershipChangeError,
28
16
  SignerUnavailableError,
29
17
  } from "@/utils/errors";
18
+ import { getInboxIdForIdentifier } from "@/utils/inboxId";
19
+ import { inboxStateFromInboxIds as utilsInboxStateFromInboxIds } from "@/utils/inboxState";
20
+ import { revokeInstallations as utilsRevokeInstallations } from "@/utils/installations";
30
21
  import { toSafeSigner, type SafeSigner, type Signer } from "@/utils/signer";
31
-
32
- export type ExtractCodecContentTypes<C extends ContentCodec[] = []> =
33
- [...C, GroupUpdatedCodec, TextCodec][number] extends ContentCodec<infer T>
34
- ? T
35
- : never;
22
+ import { uuid } from "@/utils/uuid";
23
+ import { WorkerBridge } from "@/utils/WorkerBridge";
36
24
 
37
25
  /**
38
26
  * Client for interacting with the XMTP network
39
27
  */
40
- export class Client<
41
- ContentTypes = ExtractCodecContentTypes,
42
- > extends ClientWorkerClass {
43
- #codecs: Map<string, ContentCodec>;
28
+ export class Client<ContentTypes = ExtractCodecContentTypes> {
29
+ #appVersion?: string;
30
+ #codecRegistry: CodecRegistry;
44
31
  #conversations: Conversations<ContentTypes>;
45
- #debugInformation: DebugInformation<ContentTypes>;
32
+ #debugInformation: DebugInformation;
46
33
  #identifier?: Identifier;
47
- #inboxId: string | undefined;
48
- #installationId: string | undefined;
49
- #installationIdBytes: Uint8Array | undefined;
34
+ #inboxId?: string;
35
+ #installationId?: string;
36
+ #installationIdBytes?: Uint8Array;
50
37
  #isReady = false;
51
- #preferences: Preferences<ContentTypes>;
52
- #signer?: Signer;
38
+ #libxmtpVersion?: string;
53
39
  #options?: ClientOptions;
40
+ #preferences: Preferences;
41
+ #signer?: Signer;
42
+ #worker: WorkerBridge<ClientWorkerAction>;
54
43
 
55
44
  /**
56
45
  * Creates a new XMTP client instance
@@ -64,22 +53,15 @@ export class Client<
64
53
  const worker = new Worker(new URL("./workers/client", import.meta.url), {
65
54
  type: "module",
66
55
  });
67
- super(
68
- worker,
69
- options?.loggingLevel !== undefined && options.loggingLevel !== "off",
70
- );
56
+ const enableLogging =
57
+ options?.loggingLevel !== undefined &&
58
+ options.loggingLevel !== LogLevel.Off;
59
+ this.#worker = new WorkerBridge<ClientWorkerAction>(worker, enableLogging);
71
60
  this.#options = options;
72
- this.#conversations = new Conversations(this);
73
- this.#debugInformation = new DebugInformation(this);
74
- this.#preferences = new Preferences(this);
75
- const codecs = [
76
- new GroupUpdatedCodec(),
77
- new TextCodec(),
78
- ...(options?.codecs ?? []),
79
- ];
80
- this.#codecs = new Map(
81
- codecs.map((codec) => [codec.contentType.toString(), codec]),
82
- );
61
+ this.#codecRegistry = new CodecRegistry([...(options?.codecs ?? [])]);
62
+ this.#conversations = new Conversations(this.#worker, this.#codecRegistry);
63
+ this.#debugInformation = new DebugInformation(this.#worker);
64
+ this.#preferences = new Preferences(this.#worker);
83
65
  }
84
66
 
85
67
  /**
@@ -91,17 +73,27 @@ export class Client<
91
73
  * @param identifier - The identifier to initialize the client with
92
74
  */
93
75
  async init(identifier: Identifier) {
94
- const result = await this.sendMessage("client.init", {
76
+ const result = await this.#worker.action("client.init", {
95
77
  identifier,
96
78
  options: this.#options,
97
79
  });
80
+ this.#appVersion = result.appVersion;
98
81
  this.#identifier = identifier;
99
82
  this.#inboxId = result.inboxId;
100
83
  this.#installationId = result.installationId;
101
84
  this.#installationIdBytes = result.installationIdBytes;
85
+ this.#libxmtpVersion = result.libxmtpVersion;
102
86
  this.#isReady = true;
103
87
  }
104
88
 
89
+ /**
90
+ * Shutdown the client
91
+ */
92
+ close() {
93
+ this.#worker.close();
94
+ this.#isReady = false;
95
+ }
96
+
105
97
  /**
106
98
  * Creates a new client instance with a signer
107
99
  *
@@ -224,15 +216,15 @@ export class Client<
224
216
  /**
225
217
  * Gets the version of libxmtp used in the bindings
226
218
  */
227
- async libxmtpVersion() {
228
- return this.sendMessage("client.libxmtpVersion", undefined);
219
+ get libxmtpVersion() {
220
+ return this.#libxmtpVersion;
229
221
  }
230
222
 
231
223
  /**
232
224
  * Gets the app version used by the client
233
225
  */
234
- async appVersion() {
235
- return this.sendMessage("client.appVersion", undefined);
226
+ get appVersion() {
227
+ return this.#appVersion;
236
228
  }
237
229
 
238
230
  /**
@@ -247,8 +239,8 @@ export class Client<
247
239
  * @returns The signature text and signature request ID
248
240
  */
249
241
  async unsafe_createInboxSignatureText() {
250
- return this.sendMessage("client.createInboxSignatureText", {
251
- signatureRequestId: v4(),
242
+ return this.#worker.action("client.createInboxSignatureText", {
243
+ signatureRequestId: uuid(),
252
244
  });
253
245
  }
254
246
 
@@ -274,9 +266,9 @@ export class Client<
274
266
  throw new InboxReassignError();
275
267
  }
276
268
 
277
- return this.sendMessage("client.addAccountSignatureText", {
269
+ return this.#worker.action("client.addAccountSignatureText", {
278
270
  newIdentifier,
279
- signatureRequestId: v4(),
271
+ signatureRequestId: uuid(),
280
272
  });
281
273
  }
282
274
 
@@ -293,9 +285,9 @@ export class Client<
293
285
  * @returns The signature text and signature request ID
294
286
  */
295
287
  async unsafe_removeAccountSignatureText(identifier: Identifier) {
296
- return this.sendMessage("client.removeAccountSignatureText", {
288
+ return this.#worker.action("client.removeAccountSignatureText", {
297
289
  identifier,
298
- signatureRequestId: v4(),
290
+ signatureRequestId: uuid(),
299
291
  });
300
292
  }
301
293
 
@@ -312,9 +304,12 @@ export class Client<
312
304
  * @returns The signature text and signature request ID
313
305
  */
314
306
  async unsafe_revokeAllOtherInstallationsSignatureText() {
315
- return this.sendMessage("client.revokeAllOtherInstallationsSignatureText", {
316
- signatureRequestId: v4(),
317
- });
307
+ return this.#worker.action(
308
+ "client.revokeAllOtherInstallationsSignatureText",
309
+ {
310
+ signatureRequestId: uuid(),
311
+ },
312
+ );
318
313
  }
319
314
 
320
315
  /**
@@ -331,9 +326,9 @@ export class Client<
331
326
  * @returns The signature text and signature request ID
332
327
  */
333
328
  async unsafe_revokeInstallationsSignatureText(installationIds: Uint8Array[]) {
334
- return this.sendMessage("client.revokeInstallationsSignatureText", {
329
+ return this.#worker.action("client.revokeInstallationsSignatureText", {
335
330
  installationIds,
336
- signatureRequestId: v4(),
331
+ signatureRequestId: uuid(),
337
332
  });
338
333
  }
339
334
 
@@ -351,9 +346,9 @@ export class Client<
351
346
  * @returns The signature text and signature request ID
352
347
  */
353
348
  async unsafe_changeRecoveryIdentifierSignatureText(identifier: Identifier) {
354
- return this.sendMessage("client.changeRecoveryIdentifierSignatureText", {
349
+ return this.#worker.action("client.changeRecoveryIdentifierSignatureText", {
355
350
  identifier,
356
- signatureRequestId: v4(),
351
+ signatureRequestId: uuid(),
357
352
  });
358
353
  }
359
354
 
@@ -375,7 +370,7 @@ export class Client<
375
370
  signer: SafeSigner,
376
371
  signatureRequestId: string,
377
372
  ) {
378
- return this.sendMessage("client.applySignatureRequest", {
373
+ return this.#worker.action("client.applySignatureRequest", {
379
374
  signer,
380
375
  signatureRequestId,
381
376
  });
@@ -404,7 +399,7 @@ export class Client<
404
399
  const signature = await this.#signer.signMessage(signatureText);
405
400
  const signer = await toSafeSigner(this.#signer, signature);
406
401
 
407
- return this.sendMessage("client.registerIdentity", {
402
+ return this.#worker.action("client.registerIdentity", {
408
403
  signer,
409
404
  signatureRequestId,
410
405
  });
@@ -441,7 +436,7 @@ export class Client<
441
436
  }
442
437
 
443
438
  // check for existing inbox id
444
- const existingInboxId = await this.findInboxIdByIdentifier(
439
+ const existingInboxId = await this.fetchInboxIdByIdentifier(
445
440
  await newAccountSigner.getIdentifier(),
446
441
  );
447
442
 
@@ -456,7 +451,7 @@ export class Client<
456
451
  );
457
452
  const signature = await newAccountSigner.signMessage(signatureText);
458
453
  const signer = await toSafeSigner(newAccountSigner, signature);
459
- return this.sendMessage("client.addAccount", {
454
+ return this.#worker.action("client.addAccount", {
460
455
  identifier: signer.identifier,
461
456
  signer,
462
457
  signatureRequestId,
@@ -481,7 +476,7 @@ export class Client<
481
476
  const signature = await this.#signer.signMessage(signatureText);
482
477
  const signer = await toSafeSigner(this.#signer, signature);
483
478
 
484
- return this.sendMessage("client.removeAccount", {
479
+ return this.#worker.action("client.removeAccount", {
485
480
  identifier,
486
481
  signer,
487
482
  signatureRequestId,
@@ -511,7 +506,7 @@ export class Client<
511
506
  const signature = await this.#signer.signMessage(signatureText);
512
507
  const signer = await toSafeSigner(this.#signer, signature);
513
508
 
514
- return this.sendMessage("client.revokeAllOtherInstallations", {
509
+ return this.#worker.action("client.revokeAllOtherInstallations", {
515
510
  signer,
516
511
  signatureRequestId,
517
512
  });
@@ -535,7 +530,7 @@ export class Client<
535
530
  const signature = await this.#signer.signMessage(signatureText);
536
531
  const signer = await toSafeSigner(this.#signer, signature);
537
532
 
538
- return this.sendMessage("client.revokeInstallations", {
533
+ return this.#worker.action("client.revokeInstallations", {
539
534
  installationIds,
540
535
  signer,
541
536
  signatureRequestId,
@@ -556,42 +551,30 @@ export class Client<
556
551
  installationIds: Uint8Array[],
557
552
  env?: XmtpEnv,
558
553
  gatewayHost?: string,
559
- enableLogging?: boolean,
560
554
  ) {
561
- const utils = new Utils(enableLogging);
562
- await utils.init();
563
- await utils.revokeInstallations(
555
+ await utilsRevokeInstallations(
564
556
  signer,
565
557
  inboxId,
566
558
  installationIds,
567
559
  env,
568
560
  gatewayHost,
569
561
  );
570
- utils.close();
571
562
  }
572
563
 
573
564
  /**
574
- * Gets the inbox state for the specified inbox IDs without a client
565
+ * Fetches the inbox states for the specified inbox IDs from the network
566
+ * without a client
575
567
  *
576
568
  * @param inboxIds - The inbox IDs to get the state for
577
569
  * @param env - The environment to use
578
- * @returns The inbox state for the specified inbox IDs
570
+ * @returns The inbox states for the specified inbox IDs
579
571
  */
580
- static async inboxStateFromInboxIds(
572
+ static async fetchInboxStates(
581
573
  inboxIds: string[],
582
574
  env?: XmtpEnv,
583
- enableLogging?: boolean,
584
575
  gatewayHost?: string,
585
576
  ) {
586
- const utils = new Utils(enableLogging);
587
- await utils.init();
588
- const result = await utils.inboxStateFromInboxIds(
589
- inboxIds,
590
- env,
591
- gatewayHost,
592
- );
593
- utils.close();
594
- return result;
577
+ return utilsInboxStateFromInboxIds(inboxIds, env, gatewayHost);
595
578
  }
596
579
 
597
580
  /**
@@ -612,7 +595,7 @@ export class Client<
612
595
  const signature = await this.#signer.signMessage(signatureText);
613
596
  const signer = await toSafeSigner(this.#signer, signature);
614
597
 
615
- return this.sendMessage("client.changeRecoveryIdentifier", {
598
+ return this.#worker.action("client.changeRecoveryIdentifier", {
616
599
  identifier,
617
600
  signer,
618
601
  signatureRequestId,
@@ -625,7 +608,7 @@ export class Client<
625
608
  * @returns Whether the client is registered
626
609
  */
627
610
  async isRegistered() {
628
- return this.sendMessage("client.isRegistered", undefined);
611
+ return this.#worker.action("client.isRegistered");
629
612
  }
630
613
 
631
614
  /**
@@ -635,7 +618,7 @@ export class Client<
635
618
  * @returns Whether the client can message the identifiers
636
619
  */
637
620
  async canMessage(identifiers: Identifier[]) {
638
- return this.sendMessage("client.canMessage", { identifiers });
621
+ return this.#worker.action("client.canMessage", { identifiers });
639
622
  }
640
623
 
641
624
  /**
@@ -647,136 +630,25 @@ export class Client<
647
630
  */
648
631
  static async canMessage(identifiers: Identifier[], env?: XmtpEnv) {
649
632
  const canMessageMap = new Map<string, boolean>();
650
- const utils = new Utils();
651
633
  for (const identifier of identifiers) {
652
- const inboxId = await utils.getInboxIdForIdentifier(identifier, env);
634
+ const inboxId = await getInboxIdForIdentifier(identifier, env);
653
635
  canMessageMap.set(
654
636
  identifier.identifier.toLowerCase(),
655
637
  inboxId !== undefined,
656
638
  );
657
639
  }
658
- utils.close();
659
640
  return canMessageMap;
660
641
  }
661
642
 
662
643
  /**
663
- * Finds the inbox ID for a given identifier
644
+ * Fetches the inbox ID for a given identifier from the local database
645
+ * If not found, fetches from the network
664
646
  *
665
647
  * @param identifier - The identifier to look up
666
648
  * @returns The inbox ID, if found
667
649
  */
668
- async findInboxIdByIdentifier(identifier: Identifier) {
669
- return this.sendMessage("client.findInboxIdByIdentifier", { identifier });
670
- }
671
-
672
- /**
673
- * Gets the codec for a given content type
674
- *
675
- * @param contentType - The content type to get the codec for
676
- * @returns The codec, if found
677
- */
678
- codecFor<ContentType = unknown>(contentType: ContentTypeId) {
679
- return this.#codecs.get(contentType.toString()) as
680
- | ContentCodec<ContentType>
681
- | undefined;
682
- }
683
-
684
- /**
685
- * Encodes content for a given content type
686
- *
687
- * @param content - The content to encode
688
- * @param contentType - The content type to encode for
689
- * @returns The encoded content
690
- * @throws {CodecNotFoundError} if no codec is found for the content type
691
- */
692
- encodeContent(content: ContentTypes, contentType: ContentTypeId) {
693
- const codec = this.codecFor(contentType);
694
- if (!codec) {
695
- throw new CodecNotFoundError(contentType);
696
- }
697
-
698
- return this.#encodeWithCodec(content, codec);
699
- }
700
-
701
- /**
702
- * Prepares content for sending by encoding it and generating send options from the codec
703
- *
704
- * @param content - The message content to prepare for sending
705
- * @param contentType - The content type identifier for the appropriate codec
706
- * @returns An object containing the encoded content and send options
707
- * @throws {CodecNotFoundError} When no codec is registered for the specified content type
708
- */
709
- prepareForSend(content: ContentTypes, contentType: ContentTypeId) {
710
- const codec = this.codecFor(contentType);
711
- if (!codec) {
712
- throw new CodecNotFoundError(contentType);
713
- }
714
-
715
- return {
716
- encodedContent: this.#encodeWithCodec(content, codec),
717
- sendOptions: this.#sendMessageOpts(content, codec),
718
- };
719
- }
720
-
721
- /**
722
- * Encodes content using a specific codec and adds fallback information if available
723
- *
724
- * @param content - The content to encode
725
- * @param codec - The codec to use for encoding
726
- * @returns The encoded content with optional fallback
727
- */
728
- #encodeWithCodec(content: ContentTypes, codec: ContentCodec) {
729
- const encoded = codec.encode(content, this);
730
- const fallback = codec.fallback(content);
731
- if (fallback) {
732
- encoded.fallback = fallback;
733
- }
734
- return toSafeEncodedContent(encoded);
735
- }
736
-
737
- /**
738
- * Generates send options based on the content and codec
739
- *
740
- * @param content - The content being sent
741
- * @param codec - The codec used for the content
742
- * @returns Send options including whether to push notify recipients
743
- */
744
- #sendMessageOpts(
745
- content: ContentTypes,
746
- codec: ContentCodec,
747
- ): { shouldPush: boolean } {
748
- return { shouldPush: codec.shouldPush(content) };
749
- }
750
-
751
- /**
752
- * Decodes a message for a given content type
753
- *
754
- * @param message - The message to decode
755
- * @param contentType - The content type to decode for
756
- * @returns The decoded content
757
- * @throws {CodecNotFoundError} if no codec is found for the content type
758
- * @throws {InvalidGroupMembershipChangeError} if the message is an invalid group membership change
759
- */
760
- decodeContent<ContentType = unknown>(
761
- message: SafeMessage,
762
- contentType: ContentTypeId,
763
- ) {
764
- const codec = this.codecFor<ContentType>(contentType);
765
- if (!codec) {
766
- throw new CodecNotFoundError(contentType);
767
- }
768
-
769
- // throw an error if there's an invalid group membership change message
770
- if (
771
- contentType.sameAs(ContentTypeGroupUpdated) &&
772
- message.kind !== GroupMessageKind.MembershipChange
773
- ) {
774
- throw new InvalidGroupMembershipChangeError(message.id);
775
- }
776
-
777
- const encodedContent = fromSafeEncodedContent(message.content);
778
-
779
- return codec.decode(encodedContent, this);
650
+ async fetchInboxIdByIdentifier(identifier: Identifier) {
651
+ return this.#worker.action("client.getInboxIdByIdentifier", { identifier });
780
652
  }
781
653
 
782
654
  /**
@@ -786,7 +658,7 @@ export class Client<
786
658
  * @returns The signature
787
659
  */
788
660
  signWithInstallationKey(signatureText: string) {
789
- return this.sendMessage("client.signWithInstallationKey", {
661
+ return this.#worker.action("client.signWithInstallationKey", {
790
662
  signatureText,
791
663
  });
792
664
  }
@@ -802,7 +674,7 @@ export class Client<
802
674
  signatureText: string,
803
675
  signatureBytes: Uint8Array,
804
676
  ) {
805
- return this.sendMessage("client.verifySignedWithInstallationKey", {
677
+ return this.#worker.action("client.verifySignedWithInstallationKey", {
806
678
  signatureText,
807
679
  signatureBytes,
808
680
  });
@@ -821,7 +693,7 @@ export class Client<
821
693
  signatureBytes: Uint8Array,
822
694
  publicKey: Uint8Array,
823
695
  ) {
824
- return this.sendMessage("client.verifySignedWithPublicKey", {
696
+ return this.#worker.action("client.verifySignedWithPublicKey", {
825
697
  signatureText,
826
698
  signatureBytes,
827
699
  publicKey,
@@ -829,13 +701,14 @@ export class Client<
829
701
  }
830
702
 
831
703
  /**
832
- * Gets the key package statuses for the specified installation IDs
704
+ * Fetches the key package statuses from the network for the specified
705
+ * installation IDs
833
706
  *
834
707
  * @param installationIds - The installation IDs to check
835
708
  * @returns The key package statuses
836
709
  */
837
- async getKeyPackageStatusesForInstallationIds(installationIds: string[]) {
838
- return this.sendMessage("client.getKeyPackageStatusesForInstallationIds", {
710
+ async fetchKeyPackageStatuses(installationIds: string[]) {
711
+ return this.#worker.action("client.fetchKeyPackageStatuses", {
839
712
  installationIds,
840
713
  });
841
714
  }
@@ -0,0 +1,27 @@
1
+ import {
2
+ contentTypeToString,
3
+ type ContentCodec,
4
+ type ContentTypeId,
5
+ } from "@xmtp/content-type-primitives";
6
+
7
+ export class CodecRegistry {
8
+ #codecs: Map<string, ContentCodec>;
9
+
10
+ constructor(codecs: ContentCodec[]) {
11
+ this.#codecs = new Map(
12
+ codecs.map((codec) => [contentTypeToString(codec.contentType), codec]),
13
+ );
14
+ }
15
+
16
+ /**
17
+ * Gets the codec for a given content type
18
+ *
19
+ * @param contentType - The content type to get the codec for
20
+ * @returns The codec, if found
21
+ */
22
+ getCodec<ContentType = unknown>(contentType: ContentTypeId) {
23
+ return this.#codecs.get(contentTypeToString(contentType)) as
24
+ | ContentCodec<ContentType>
25
+ | undefined;
26
+ }
27
+ }