@xmtp/browser-sdk 5.2.0 → 6.0.0
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/dist/index.d.ts +587 -670
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/workers/client.js +1 -1
- package/dist/workers/client.js.map +1 -1
- package/dist/workers/opfs.js +2 -0
- package/dist/workers/opfs.js.map +1 -0
- package/package.json +12 -16
- package/src/Client.ts +92 -219
- package/src/CodecRegistry.ts +27 -0
- package/src/Conversation.ts +275 -104
- package/src/Conversations.ts +188 -99
- package/src/DebugInformation.ts +10 -27
- package/src/DecodedMessage.ts +155 -58
- package/src/Dm.ts +25 -9
- package/src/Group.ts +69 -26
- package/src/Opfs.ts +63 -0
- package/src/Preferences.ts +68 -52
- package/src/WorkerClient.ts +5 -5
- package/src/WorkerConversation.ts +119 -44
- package/src/WorkerConversations.ts +35 -74
- package/src/WorkerDebugInformation.ts +1 -12
- package/src/WorkerPreferences.ts +6 -14
- package/src/index.ts +53 -24
- package/src/types/actions/client.ts +6 -17
- package/src/types/actions/conversation.ts +160 -31
- package/src/types/actions/conversations.ts +21 -24
- package/src/types/actions/debugInformation.ts +3 -11
- package/src/types/actions/dm.ts +1 -1
- package/src/types/actions/group.ts +25 -0
- package/src/types/actions/opfs.ts +66 -0
- package/src/types/actions/preferences.ts +6 -13
- package/src/types/actions/streams.ts +8 -8
- package/src/types/actions.ts +11 -9
- package/src/types/options.ts +47 -6
- package/src/{ClientWorkerClass.ts → utils/WorkerBridge.ts} +35 -45
- package/src/utils/contentTypes.ts +77 -0
- package/src/utils/conversions.ts +18 -588
- package/src/utils/createClient.ts +16 -11
- package/src/utils/errors.ts +13 -19
- package/src/utils/inboxId.ts +46 -0
- package/src/utils/inboxState.ts +23 -0
- package/src/utils/installations.ts +95 -0
- package/src/utils/metadata.ts +15 -0
- package/src/utils/signer.ts +4 -4
- package/src/utils/uuid.ts +8 -0
- package/src/workers/client.ts +191 -132
- package/src/workers/opfs.ts +127 -0
- package/dist/workers/utils.js +0 -2
- package/dist/workers/utils.js.map +0 -1
- package/src/Utils.ts +0 -143
- package/src/UtilsWorkerClass.ts +0 -121
- package/src/types/actions/utils.ts +0 -69
- package/src/workers/utils.ts +0 -155
package/src/Client.ts
CHANGED
|
@@ -1,56 +1,45 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
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 {
|
|
17
|
-
import {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
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
|
-
|
|
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
|
-
|
|
42
|
-
|
|
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
|
|
32
|
+
#debugInformation: DebugInformation;
|
|
46
33
|
#identifier?: Identifier;
|
|
47
|
-
#inboxId
|
|
48
|
-
#installationId
|
|
49
|
-
#installationIdBytes
|
|
34
|
+
#inboxId?: string;
|
|
35
|
+
#installationId?: string;
|
|
36
|
+
#installationIdBytes?: Uint8Array;
|
|
50
37
|
#isReady = false;
|
|
51
|
-
#
|
|
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
|
-
|
|
68
|
-
|
|
69
|
-
options
|
|
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.#
|
|
73
|
-
this.#
|
|
74
|
-
this.#
|
|
75
|
-
|
|
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.
|
|
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
|
-
|
|
228
|
-
return this
|
|
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
|
-
|
|
235
|
-
return this
|
|
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.
|
|
251
|
-
signatureRequestId:
|
|
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.
|
|
269
|
+
return this.#worker.action("client.addAccountSignatureText", {
|
|
278
270
|
newIdentifier,
|
|
279
|
-
signatureRequestId:
|
|
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.
|
|
288
|
+
return this.#worker.action("client.removeAccountSignatureText", {
|
|
297
289
|
identifier,
|
|
298
|
-
signatureRequestId:
|
|
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.
|
|
316
|
-
|
|
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.
|
|
329
|
+
return this.#worker.action("client.revokeInstallationsSignatureText", {
|
|
335
330
|
installationIds,
|
|
336
|
-
signatureRequestId:
|
|
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.
|
|
349
|
+
return this.#worker.action("client.changeRecoveryIdentifierSignatureText", {
|
|
355
350
|
identifier,
|
|
356
|
-
signatureRequestId:
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
-
|
|
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
|
-
*
|
|
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
|
|
570
|
+
* @returns The inbox states for the specified inbox IDs
|
|
579
571
|
*/
|
|
580
|
-
static async
|
|
572
|
+
static async fetchInboxStates(
|
|
581
573
|
inboxIds: string[],
|
|
582
574
|
env?: XmtpEnv,
|
|
583
|
-
enableLogging?: boolean,
|
|
584
575
|
gatewayHost?: string,
|
|
585
576
|
) {
|
|
586
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
|
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
|
-
*
|
|
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
|
|
669
|
-
return this.
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
-
*
|
|
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
|
|
838
|
-
return this.
|
|
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
|
+
}
|