@xmtp/node-sdk 1.2.1 → 2.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/README.md +29 -6
- package/dist/index.d.ts +742 -28
- package/dist/index.js +893 -62
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -126,6 +126,26 @@ function nsToDate(ns) {
|
|
|
126
126
|
return new Date(ns / 1_000_000);
|
|
127
127
|
}
|
|
128
128
|
|
|
129
|
+
/**
|
|
130
|
+
* Represents a decoded XMTP message
|
|
131
|
+
*
|
|
132
|
+
* This class transforms network messages into a structured format with
|
|
133
|
+
* content decoding.
|
|
134
|
+
*
|
|
135
|
+
* @class
|
|
136
|
+
* @property {any} content - The decoded content of the message
|
|
137
|
+
* @property {ContentTypeId} contentType - The content type of the message content
|
|
138
|
+
* @property {string} conversationId - Unique identifier for the conversation
|
|
139
|
+
* @property {MessageDeliveryStatus} deliveryStatus - Current delivery status of the message ("unpublished" | "published" | "failed")
|
|
140
|
+
* @property {string} [fallback] - Optional fallback text for the message
|
|
141
|
+
* @property {number} [compression] - Optional compression level applied to the message
|
|
142
|
+
* @property {string} id - Unique identifier for the message
|
|
143
|
+
* @property {MessageKind} kind - Type of message ("application" | "membership_change")
|
|
144
|
+
* @property {Record<string, string>} parameters - Additional parameters associated with the message
|
|
145
|
+
* @property {string} senderInboxId - Identifier for the sender's inbox
|
|
146
|
+
* @property {Date} sentAt - Timestamp when the message was sent
|
|
147
|
+
* @property {number} sentAtNs - Timestamp when the message was sent (in nanoseconds)
|
|
148
|
+
*/
|
|
129
149
|
class DecodedMessage {
|
|
130
150
|
#client;
|
|
131
151
|
content;
|
|
@@ -174,10 +194,15 @@ class DecodedMessage {
|
|
|
174
194
|
this.parameters = message.content.parameters;
|
|
175
195
|
this.fallback = message.content.fallback;
|
|
176
196
|
this.compression = message.content.compression;
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
197
|
+
this.content = undefined;
|
|
198
|
+
if (this.contentType) {
|
|
199
|
+
try {
|
|
200
|
+
this.content = this.#client.decodeContent(message, this.contentType);
|
|
201
|
+
}
|
|
202
|
+
catch {
|
|
203
|
+
this.content = undefined;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
181
206
|
}
|
|
182
207
|
}
|
|
183
208
|
|
|
@@ -229,11 +254,33 @@ class MissingContentTypeError extends Error {
|
|
|
229
254
|
super("Content type is required when sending content other than text");
|
|
230
255
|
}
|
|
231
256
|
}
|
|
257
|
+
class SignerUnavailableError extends Error {
|
|
258
|
+
constructor() {
|
|
259
|
+
super("Signer unavailable, use Client.create to create a client with a signer");
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
class ClientNotInitializedError extends Error {
|
|
263
|
+
constructor() {
|
|
264
|
+
super("Client not initialized, use Client.create or Client.build to create a client");
|
|
265
|
+
}
|
|
266
|
+
}
|
|
232
267
|
|
|
268
|
+
/**
|
|
269
|
+
* Represents a conversation
|
|
270
|
+
*
|
|
271
|
+
* This class is not intended to be initialized directly.
|
|
272
|
+
*/
|
|
233
273
|
class Conversation {
|
|
234
274
|
#client;
|
|
235
275
|
#conversation;
|
|
236
276
|
#lastMessage;
|
|
277
|
+
/**
|
|
278
|
+
* Creates a new conversation instance
|
|
279
|
+
*
|
|
280
|
+
* @param client - The client instance managing the conversation
|
|
281
|
+
* @param conversation - The underlying conversation instance
|
|
282
|
+
* @param lastMessage - Optional last message in the conversation
|
|
283
|
+
*/
|
|
237
284
|
constructor(client, conversation, lastMessage) {
|
|
238
285
|
this.#client = client;
|
|
239
286
|
this.#conversation = conversation;
|
|
@@ -241,21 +288,41 @@ class Conversation {
|
|
|
241
288
|
? new DecodedMessage(client, lastMessage)
|
|
242
289
|
: undefined;
|
|
243
290
|
}
|
|
291
|
+
/**
|
|
292
|
+
* Gets the unique identifier for this conversation
|
|
293
|
+
*/
|
|
244
294
|
get id() {
|
|
245
295
|
return this.#conversation.id();
|
|
246
296
|
}
|
|
297
|
+
/**
|
|
298
|
+
* Gets whether this conversation is currently active
|
|
299
|
+
*/
|
|
247
300
|
get isActive() {
|
|
248
301
|
return this.#conversation.isActive();
|
|
249
302
|
}
|
|
303
|
+
/**
|
|
304
|
+
* Gets the inbox ID that added this client's inbox to the conversation
|
|
305
|
+
*/
|
|
250
306
|
get addedByInboxId() {
|
|
251
307
|
return this.#conversation.addedByInboxId();
|
|
252
308
|
}
|
|
309
|
+
/**
|
|
310
|
+
* Gets the timestamp when the conversation was created in nanoseconds
|
|
311
|
+
*/
|
|
253
312
|
get createdAtNs() {
|
|
254
313
|
return this.#conversation.createdAtNs();
|
|
255
314
|
}
|
|
315
|
+
/**
|
|
316
|
+
* Gets the date when the conversation was created
|
|
317
|
+
*/
|
|
256
318
|
get createdAt() {
|
|
257
319
|
return nsToDate(this.createdAtNs);
|
|
258
320
|
}
|
|
321
|
+
/**
|
|
322
|
+
* Gets the metadata for this conversation
|
|
323
|
+
*
|
|
324
|
+
* @returns Promise that resolves with the conversation metadata
|
|
325
|
+
*/
|
|
259
326
|
async metadata() {
|
|
260
327
|
const metadata = await this.#conversation.groupMetadata();
|
|
261
328
|
return {
|
|
@@ -263,12 +330,28 @@ class Conversation {
|
|
|
263
330
|
conversationType: metadata.conversationType(),
|
|
264
331
|
};
|
|
265
332
|
}
|
|
333
|
+
/**
|
|
334
|
+
* Gets the members of this conversation
|
|
335
|
+
*
|
|
336
|
+
* @returns Promise that resolves with the conversation members
|
|
337
|
+
*/
|
|
266
338
|
async members() {
|
|
267
339
|
return this.#conversation.listMembers();
|
|
268
340
|
}
|
|
341
|
+
/**
|
|
342
|
+
* Synchronizes conversation data from the network
|
|
343
|
+
*
|
|
344
|
+
* @returns Promise that resolves when synchronization is complete
|
|
345
|
+
*/
|
|
269
346
|
async sync() {
|
|
270
347
|
return this.#conversation.sync();
|
|
271
348
|
}
|
|
349
|
+
/**
|
|
350
|
+
* Creates a stream for new messages in this conversation
|
|
351
|
+
*
|
|
352
|
+
* @param callback - Optional callback function for handling new stream values
|
|
353
|
+
* @returns Stream instance for new messages
|
|
354
|
+
*/
|
|
272
355
|
stream(callback) {
|
|
273
356
|
const asyncStream = new AsyncStream();
|
|
274
357
|
const stream = this.#conversation.stream((error, value) => {
|
|
@@ -288,9 +371,22 @@ class Conversation {
|
|
|
288
371
|
asyncStream.onReturn = stream.end.bind(stream);
|
|
289
372
|
return asyncStream;
|
|
290
373
|
}
|
|
374
|
+
/**
|
|
375
|
+
* Publishes pending messages that were sent optimistically
|
|
376
|
+
*
|
|
377
|
+
* @returns Promise that resolves when publishing is complete
|
|
378
|
+
*/
|
|
291
379
|
async publishMessages() {
|
|
292
380
|
return this.#conversation.publishMessages();
|
|
293
381
|
}
|
|
382
|
+
/**
|
|
383
|
+
* Prepares a message to be published
|
|
384
|
+
*
|
|
385
|
+
* @param content - The content to send
|
|
386
|
+
* @param contentType - Optional content type of the message content
|
|
387
|
+
* @returns Promise that resolves with the message ID
|
|
388
|
+
* @throws {MissingContentTypeError} if content type is required but not provided
|
|
389
|
+
*/
|
|
294
390
|
sendOptimistic(content, contentType) {
|
|
295
391
|
if (typeof content !== "string" && !contentType) {
|
|
296
392
|
throw new MissingContentTypeError();
|
|
@@ -301,6 +397,14 @@ class Conversation {
|
|
|
301
397
|
this.#client.encodeContent(content, contentType);
|
|
302
398
|
return this.#conversation.sendOptimistic(encodedContent);
|
|
303
399
|
}
|
|
400
|
+
/**
|
|
401
|
+
* Publishes a new message
|
|
402
|
+
*
|
|
403
|
+
* @param content - The content to send
|
|
404
|
+
* @param contentType - Optional content type of the message content
|
|
405
|
+
* @returns Promise that resolves with the message ID after it has been sent
|
|
406
|
+
* @throws {MissingContentTypeError} if content type is required but not provided
|
|
407
|
+
*/
|
|
304
408
|
async send(content, contentType) {
|
|
305
409
|
if (typeof content !== "string" && !contentType) {
|
|
306
410
|
throw new MissingContentTypeError();
|
|
@@ -311,80 +415,179 @@ class Conversation {
|
|
|
311
415
|
this.#client.encodeContent(content, contentType);
|
|
312
416
|
return this.#conversation.send(encodedContent);
|
|
313
417
|
}
|
|
418
|
+
/**
|
|
419
|
+
* Lists messages in this conversation
|
|
420
|
+
*
|
|
421
|
+
* @param options - Optional filtering and pagination options
|
|
422
|
+
* @returns Promise that resolves with an array of decoded messages
|
|
423
|
+
*/
|
|
314
424
|
async messages(options) {
|
|
315
425
|
const messages = await this.#conversation.findMessages(options);
|
|
316
|
-
return (
|
|
317
|
-
.map((message) => new DecodedMessage(this.#client, message))
|
|
318
|
-
// filter out messages without content
|
|
319
|
-
.filter((message) => message.content !== undefined));
|
|
426
|
+
return messages.map((message) => new DecodedMessage(this.#client, message));
|
|
320
427
|
}
|
|
428
|
+
/**
|
|
429
|
+
* Gets the last message in this conversation
|
|
430
|
+
*
|
|
431
|
+
* @returns Promise that resolves with the last message or undefined if none exists
|
|
432
|
+
*/
|
|
321
433
|
async lastMessage() {
|
|
322
434
|
return this.#lastMessage ?? (await this.messages({ limit: 1 }))[0];
|
|
323
435
|
}
|
|
436
|
+
/**
|
|
437
|
+
* Gets the consent state for this conversation
|
|
438
|
+
*/
|
|
324
439
|
get consentState() {
|
|
325
440
|
return this.#conversation.consentState();
|
|
326
441
|
}
|
|
442
|
+
/**
|
|
443
|
+
* Updates the consent state for this conversation
|
|
444
|
+
*
|
|
445
|
+
* @param consentState - The new consent state to set
|
|
446
|
+
*/
|
|
327
447
|
updateConsentState(consentState) {
|
|
328
448
|
this.#conversation.updateConsentState(consentState);
|
|
329
449
|
}
|
|
450
|
+
/**
|
|
451
|
+
* Gets the message disappearing settings for this conversation
|
|
452
|
+
*
|
|
453
|
+
* @returns The current message disappearing settings or undefined if not set
|
|
454
|
+
*/
|
|
330
455
|
messageDisappearingSettings() {
|
|
331
456
|
return this.#conversation.messageDisappearingSettings() ?? undefined;
|
|
332
457
|
}
|
|
458
|
+
/**
|
|
459
|
+
* Updates message disappearing settings for this conversation
|
|
460
|
+
*
|
|
461
|
+
* @param fromNs - The timestamp from which messages should start disappearing
|
|
462
|
+
* @param inNs - The duration after which messages should disappear
|
|
463
|
+
* @returns Promise that resolves when the update is complete
|
|
464
|
+
*/
|
|
333
465
|
async updateMessageDisappearingSettings(fromNs, inNs) {
|
|
334
466
|
return this.#conversation.updateMessageDisappearingSettings({
|
|
335
467
|
fromNs,
|
|
336
468
|
inNs,
|
|
337
469
|
});
|
|
338
470
|
}
|
|
471
|
+
/**
|
|
472
|
+
* Removes message disappearing settings from this conversation
|
|
473
|
+
*
|
|
474
|
+
* @returns Promise that resolves when the settings are removed
|
|
475
|
+
*/
|
|
339
476
|
async removeMessageDisappearingSettings() {
|
|
340
477
|
return this.#conversation.removeMessageDisappearingSettings();
|
|
341
478
|
}
|
|
479
|
+
/**
|
|
480
|
+
* Checks if message disappearing is enabled for this conversation
|
|
481
|
+
*
|
|
482
|
+
* @returns Whether message disappearing is enabled
|
|
483
|
+
*/
|
|
342
484
|
isMessageDisappearingEnabled() {
|
|
343
485
|
return this.#conversation.isMessageDisappearingEnabled();
|
|
344
486
|
}
|
|
345
487
|
pausedForVersion() {
|
|
346
488
|
return this.#conversation.pausedForVersion() ?? undefined;
|
|
347
489
|
}
|
|
490
|
+
/**
|
|
491
|
+
* Retrieves HMAC keys for this conversation
|
|
492
|
+
*
|
|
493
|
+
* @returns The HMAC keys for this conversation
|
|
494
|
+
*/
|
|
348
495
|
getHmacKeys() {
|
|
349
496
|
return this.#conversation.getHmacKeys();
|
|
350
497
|
}
|
|
351
498
|
}
|
|
352
499
|
|
|
500
|
+
/**
|
|
501
|
+
* Represents a direct message conversation between two inboxes
|
|
502
|
+
*
|
|
503
|
+
* This class is not intended to be initialized directly.
|
|
504
|
+
*/
|
|
353
505
|
class Dm extends Conversation {
|
|
354
506
|
#conversation;
|
|
507
|
+
/**
|
|
508
|
+
* Creates a new direct message conversation instance
|
|
509
|
+
*
|
|
510
|
+
* @param client - The client instance managing this direct message conversation
|
|
511
|
+
* @param conversation - The underlying conversation instance
|
|
512
|
+
* @param lastMessage - Optional last message in the conversation
|
|
513
|
+
*/
|
|
355
514
|
constructor(client, conversation, lastMessage) {
|
|
356
515
|
super(client, conversation, lastMessage);
|
|
357
516
|
this.#conversation = conversation;
|
|
358
517
|
}
|
|
518
|
+
/**
|
|
519
|
+
* Retrieves the inbox ID of the other participant in the DM
|
|
520
|
+
*
|
|
521
|
+
* @returns Promise that resolves with the peer's inbox ID
|
|
522
|
+
*/
|
|
359
523
|
get peerInboxId() {
|
|
360
524
|
return this.#conversation.dmPeerInboxId();
|
|
361
525
|
}
|
|
362
526
|
}
|
|
363
527
|
|
|
528
|
+
/**
|
|
529
|
+
* Represents a group conversation between multiple inboxes
|
|
530
|
+
*
|
|
531
|
+
* This class is not intended to be initialized directly.
|
|
532
|
+
*/
|
|
364
533
|
class Group extends Conversation {
|
|
365
534
|
#conversation;
|
|
535
|
+
/**
|
|
536
|
+
* Creates a new group conversation instance
|
|
537
|
+
*
|
|
538
|
+
* @param client - The client instance managing this group conversation
|
|
539
|
+
* @param conversation - The underlying conversation object
|
|
540
|
+
* @param lastMessage - Optional last message in the conversation
|
|
541
|
+
*/
|
|
366
542
|
constructor(client, conversation, lastMessage) {
|
|
367
543
|
super(client, conversation, lastMessage);
|
|
368
544
|
this.#conversation = conversation;
|
|
369
545
|
}
|
|
546
|
+
/**
|
|
547
|
+
* The name of the group
|
|
548
|
+
*/
|
|
370
549
|
get name() {
|
|
371
550
|
return this.#conversation.groupName();
|
|
372
551
|
}
|
|
552
|
+
/**
|
|
553
|
+
* Updates the group's name
|
|
554
|
+
*
|
|
555
|
+
* @param name The new name for the group
|
|
556
|
+
*/
|
|
373
557
|
async updateName(name) {
|
|
374
558
|
return this.#conversation.updateGroupName(name);
|
|
375
559
|
}
|
|
560
|
+
/**
|
|
561
|
+
* The image URL of the group
|
|
562
|
+
*/
|
|
376
563
|
get imageUrl() {
|
|
377
564
|
return this.#conversation.groupImageUrlSquare();
|
|
378
565
|
}
|
|
566
|
+
/**
|
|
567
|
+
* Updates the group's image URL
|
|
568
|
+
*
|
|
569
|
+
* @param imageUrl The new image URL for the group
|
|
570
|
+
*/
|
|
379
571
|
async updateImageUrl(imageUrl) {
|
|
380
572
|
return this.#conversation.updateGroupImageUrlSquare(imageUrl);
|
|
381
573
|
}
|
|
574
|
+
/**
|
|
575
|
+
* The description of the group
|
|
576
|
+
*/
|
|
382
577
|
get description() {
|
|
383
578
|
return this.#conversation.groupDescription();
|
|
384
579
|
}
|
|
580
|
+
/**
|
|
581
|
+
* Updates the group's description
|
|
582
|
+
*
|
|
583
|
+
* @param description The new description for the group
|
|
584
|
+
*/
|
|
385
585
|
async updateDescription(description) {
|
|
386
586
|
return this.#conversation.updateGroupDescription(description);
|
|
387
587
|
}
|
|
588
|
+
/**
|
|
589
|
+
* The permissions of the group
|
|
590
|
+
*/
|
|
388
591
|
get permissions() {
|
|
389
592
|
const permissions = this.#conversation.groupPermissions();
|
|
390
593
|
return {
|
|
@@ -392,54 +595,136 @@ class Group extends Conversation {
|
|
|
392
595
|
policySet: permissions.policySet(),
|
|
393
596
|
};
|
|
394
597
|
}
|
|
598
|
+
/**
|
|
599
|
+
* Updates a specific permission policy for the group
|
|
600
|
+
*
|
|
601
|
+
* @param permissionType The type of permission to update
|
|
602
|
+
* @param policy The new permission policy
|
|
603
|
+
* @param metadataField Optional metadata field for the permission
|
|
604
|
+
*/
|
|
395
605
|
async updatePermission(permissionType, policy, metadataField) {
|
|
396
606
|
return this.#conversation.updatePermissionPolicy(permissionType, policy, metadataField);
|
|
397
607
|
}
|
|
608
|
+
/**
|
|
609
|
+
* The list of admins of the group
|
|
610
|
+
*/
|
|
398
611
|
get admins() {
|
|
399
612
|
return this.#conversation.adminList();
|
|
400
613
|
}
|
|
614
|
+
/**
|
|
615
|
+
* The list of super admins of the group
|
|
616
|
+
*/
|
|
401
617
|
get superAdmins() {
|
|
402
618
|
return this.#conversation.superAdminList();
|
|
403
619
|
}
|
|
620
|
+
/**
|
|
621
|
+
* Checks if an inbox is an admin of the group
|
|
622
|
+
*
|
|
623
|
+
* @param inboxId The inbox ID to check
|
|
624
|
+
* @returns Boolean indicating if the inbox is an admin
|
|
625
|
+
*/
|
|
404
626
|
isAdmin(inboxId) {
|
|
405
627
|
return this.#conversation.isAdmin(inboxId);
|
|
406
628
|
}
|
|
629
|
+
/**
|
|
630
|
+
* Checks if an inbox is a super admin of the group
|
|
631
|
+
*
|
|
632
|
+
* @param inboxId The inbox ID to check
|
|
633
|
+
* @returns Boolean indicating if the inbox is a super admin
|
|
634
|
+
*/
|
|
407
635
|
isSuperAdmin(inboxId) {
|
|
408
636
|
return this.#conversation.isSuperAdmin(inboxId);
|
|
409
637
|
}
|
|
638
|
+
/**
|
|
639
|
+
* Adds members to the group using identifiers
|
|
640
|
+
*
|
|
641
|
+
* @param identifiers Array of member identifiers to add
|
|
642
|
+
*/
|
|
410
643
|
async addMembersByIdentifiers(identifiers) {
|
|
411
644
|
return this.#conversation.addMembers(identifiers);
|
|
412
645
|
}
|
|
646
|
+
/**
|
|
647
|
+
* Adds members to the group using inbox IDs
|
|
648
|
+
*
|
|
649
|
+
* @param inboxIds Array of inbox IDs to add
|
|
650
|
+
*/
|
|
413
651
|
async addMembers(inboxIds) {
|
|
414
652
|
return this.#conversation.addMembersByInboxId(inboxIds);
|
|
415
653
|
}
|
|
654
|
+
/**
|
|
655
|
+
* Removes members from the group using identifiers
|
|
656
|
+
*
|
|
657
|
+
* @param identifiers Array of member identifiers to remove
|
|
658
|
+
*/
|
|
416
659
|
async removeMembersByIdentifiers(identifiers) {
|
|
417
660
|
return this.#conversation.removeMembers(identifiers);
|
|
418
661
|
}
|
|
662
|
+
/**
|
|
663
|
+
* Removes members from the group using inbox IDs
|
|
664
|
+
*
|
|
665
|
+
* @param inboxIds Array of inbox IDs to remove
|
|
666
|
+
*/
|
|
419
667
|
async removeMembers(inboxIds) {
|
|
420
668
|
return this.#conversation.removeMembersByInboxId(inboxIds);
|
|
421
669
|
}
|
|
670
|
+
/**
|
|
671
|
+
* Promotes a group member to admin status
|
|
672
|
+
*
|
|
673
|
+
* @param inboxId The inbox ID of the member to promote
|
|
674
|
+
*/
|
|
422
675
|
async addAdmin(inboxId) {
|
|
423
676
|
return this.#conversation.addAdmin(inboxId);
|
|
424
677
|
}
|
|
678
|
+
/**
|
|
679
|
+
* Removes admin status from a group member
|
|
680
|
+
*
|
|
681
|
+
* @param inboxId The inbox ID of the admin to demote
|
|
682
|
+
*/
|
|
425
683
|
async removeAdmin(inboxId) {
|
|
426
684
|
return this.#conversation.removeAdmin(inboxId);
|
|
427
685
|
}
|
|
686
|
+
/**
|
|
687
|
+
* Promotes a group member to super admin status
|
|
688
|
+
*
|
|
689
|
+
* @param inboxId The inbox ID of the member to promote
|
|
690
|
+
*/
|
|
428
691
|
async addSuperAdmin(inboxId) {
|
|
429
692
|
return this.#conversation.addSuperAdmin(inboxId);
|
|
430
693
|
}
|
|
694
|
+
/**
|
|
695
|
+
* Removes super admin status from a group member
|
|
696
|
+
*
|
|
697
|
+
* @param inboxId The inbox ID of the super admin to demote
|
|
698
|
+
*/
|
|
431
699
|
async removeSuperAdmin(inboxId) {
|
|
432
700
|
return this.#conversation.removeSuperAdmin(inboxId);
|
|
433
701
|
}
|
|
434
702
|
}
|
|
435
703
|
|
|
704
|
+
/**
|
|
705
|
+
* Manages conversations
|
|
706
|
+
*
|
|
707
|
+
* This class is not intended to be initialized directly.
|
|
708
|
+
*/
|
|
436
709
|
class Conversations {
|
|
437
710
|
#client;
|
|
438
711
|
#conversations;
|
|
712
|
+
/**
|
|
713
|
+
* Creates a new conversations instance
|
|
714
|
+
*
|
|
715
|
+
* @param client - The client instance managing the conversations
|
|
716
|
+
* @param conversations - The underlying conversations instance
|
|
717
|
+
*/
|
|
439
718
|
constructor(client, conversations) {
|
|
440
719
|
this.#client = client;
|
|
441
720
|
this.#conversations = conversations;
|
|
442
721
|
}
|
|
722
|
+
/**
|
|
723
|
+
* Retrieves a conversation by its ID
|
|
724
|
+
*
|
|
725
|
+
* @param id - The conversation ID to look up
|
|
726
|
+
* @returns The conversation if found, undefined otherwise
|
|
727
|
+
*/
|
|
443
728
|
async getConversationById(id) {
|
|
444
729
|
try {
|
|
445
730
|
// findGroupById will throw if group is not found
|
|
@@ -453,6 +738,12 @@ class Conversations {
|
|
|
453
738
|
return undefined;
|
|
454
739
|
}
|
|
455
740
|
}
|
|
741
|
+
/**
|
|
742
|
+
* Retrieves a DM by inbox ID
|
|
743
|
+
*
|
|
744
|
+
* @param inboxId - The inbox ID to look up
|
|
745
|
+
* @returns The DM if found, undefined otherwise
|
|
746
|
+
*/
|
|
456
747
|
getDmByInboxId(inboxId) {
|
|
457
748
|
try {
|
|
458
749
|
// findDmByTargetInboxId will throw if group is not found
|
|
@@ -463,6 +754,12 @@ class Conversations {
|
|
|
463
754
|
return undefined;
|
|
464
755
|
}
|
|
465
756
|
}
|
|
757
|
+
/**
|
|
758
|
+
* Retrieves a message by its ID
|
|
759
|
+
*
|
|
760
|
+
* @param id - The message ID to look up
|
|
761
|
+
* @returns The decoded message if found, undefined otherwise
|
|
762
|
+
*/
|
|
466
763
|
getMessageById(id) {
|
|
467
764
|
try {
|
|
468
765
|
// findMessageById will throw if message is not found
|
|
@@ -473,26 +770,60 @@ class Conversations {
|
|
|
473
770
|
return undefined;
|
|
474
771
|
}
|
|
475
772
|
}
|
|
773
|
+
/**
|
|
774
|
+
* Creates a new group conversation with the specified identifiers
|
|
775
|
+
*
|
|
776
|
+
* @param identifiers - Array of identifiers for group members
|
|
777
|
+
* @param options - Optional group creation options
|
|
778
|
+
* @returns The new group
|
|
779
|
+
*/
|
|
476
780
|
async newGroupWithIdentifiers(identifiers, options) {
|
|
477
781
|
const group = await this.#conversations.createGroup(identifiers, options);
|
|
478
782
|
const conversation = new Group(this.#client, group);
|
|
479
783
|
return conversation;
|
|
480
784
|
}
|
|
785
|
+
/**
|
|
786
|
+
* Creates a new group conversation with the specified inbox IDs
|
|
787
|
+
*
|
|
788
|
+
* @param inboxIds - Array of inbox IDs for group members
|
|
789
|
+
* @param options - Optional group creation options
|
|
790
|
+
* @returns The new group
|
|
791
|
+
*/
|
|
481
792
|
async newGroup(inboxIds, options) {
|
|
482
793
|
const group = await this.#conversations.createGroupByInboxId(inboxIds, options);
|
|
483
794
|
const conversation = new Group(this.#client, group);
|
|
484
795
|
return conversation;
|
|
485
796
|
}
|
|
797
|
+
/**
|
|
798
|
+
* Creates a new DM conversation with the specified identifier
|
|
799
|
+
*
|
|
800
|
+
* @param identifier - Identifier for the DM recipient
|
|
801
|
+
* @param options - Optional DM creation options
|
|
802
|
+
* @returns The new DM
|
|
803
|
+
*/
|
|
486
804
|
async newDmWithIdentifier(identifier, options) {
|
|
487
805
|
const group = await this.#conversations.createDm(identifier, options);
|
|
488
806
|
const conversation = new Dm(this.#client, group);
|
|
489
807
|
return conversation;
|
|
490
808
|
}
|
|
809
|
+
/**
|
|
810
|
+
* Creates a new DM conversation with the specified inbox ID
|
|
811
|
+
*
|
|
812
|
+
* @param inboxId - Inbox ID for the DM recipient
|
|
813
|
+
* @param options - Optional DM creation options
|
|
814
|
+
* @returns The new DM
|
|
815
|
+
*/
|
|
491
816
|
async newDm(inboxId, options) {
|
|
492
817
|
const group = await this.#conversations.createDmByInboxId(inboxId, options);
|
|
493
818
|
const conversation = new Dm(this.#client, group);
|
|
494
819
|
return conversation;
|
|
495
820
|
}
|
|
821
|
+
/**
|
|
822
|
+
* Lists all conversations with optional filtering
|
|
823
|
+
*
|
|
824
|
+
* @param options - Optional filtering and pagination options
|
|
825
|
+
* @returns Array of conversations
|
|
826
|
+
*/
|
|
496
827
|
async list(options) {
|
|
497
828
|
const groups = this.#conversations.list(options);
|
|
498
829
|
return Promise.all(groups.map(async (item) => {
|
|
@@ -502,6 +833,12 @@ class Conversations {
|
|
|
502
833
|
: new Group(this.#client, item.conversation, item.lastMessage);
|
|
503
834
|
}));
|
|
504
835
|
}
|
|
836
|
+
/**
|
|
837
|
+
* Lists all groups with optional filtering
|
|
838
|
+
*
|
|
839
|
+
* @param options - Optional filtering and pagination options
|
|
840
|
+
* @returns Array of groups
|
|
841
|
+
*/
|
|
505
842
|
listGroups(options) {
|
|
506
843
|
const groups = this.#conversations.listGroups(options);
|
|
507
844
|
return groups.map((item) => {
|
|
@@ -509,6 +846,12 @@ class Conversations {
|
|
|
509
846
|
return conversation;
|
|
510
847
|
});
|
|
511
848
|
}
|
|
849
|
+
/**
|
|
850
|
+
* Lists all DMs with optional filtering
|
|
851
|
+
*
|
|
852
|
+
* @param options - Optional filtering and pagination options
|
|
853
|
+
* @returns Array of DMs
|
|
854
|
+
*/
|
|
512
855
|
listDms(options) {
|
|
513
856
|
const groups = this.#conversations.listDms(options);
|
|
514
857
|
return groups.map((item) => {
|
|
@@ -516,12 +859,30 @@ class Conversations {
|
|
|
516
859
|
return conversation;
|
|
517
860
|
});
|
|
518
861
|
}
|
|
862
|
+
/**
|
|
863
|
+
* Synchronizes conversations for the current client from the network
|
|
864
|
+
*
|
|
865
|
+
* @returns Promise that resolves when sync is complete
|
|
866
|
+
*/
|
|
519
867
|
async sync() {
|
|
520
868
|
return this.#conversations.sync();
|
|
521
869
|
}
|
|
870
|
+
/**
|
|
871
|
+
* Synchronizes all conversations and messages from the network with optional
|
|
872
|
+
* consent state filtering
|
|
873
|
+
*
|
|
874
|
+
* @param consentStates - Optional array of consent states to filter by
|
|
875
|
+
* @returns Promise that resolves when sync is complete
|
|
876
|
+
*/
|
|
522
877
|
async syncAll(consentStates) {
|
|
523
878
|
return this.#conversations.syncAllConversations(consentStates);
|
|
524
879
|
}
|
|
880
|
+
/**
|
|
881
|
+
* Creates a stream for new conversations
|
|
882
|
+
*
|
|
883
|
+
* @param callback - Optional callback function for handling new stream value
|
|
884
|
+
* @returns Stream instance for new conversations
|
|
885
|
+
*/
|
|
525
886
|
stream(callback) {
|
|
526
887
|
const asyncStream = new AsyncStream();
|
|
527
888
|
const stream = this.#conversations.stream((err, value) => {
|
|
@@ -547,6 +908,12 @@ class Conversations {
|
|
|
547
908
|
asyncStream.onReturn = stream.end.bind(stream);
|
|
548
909
|
return asyncStream;
|
|
549
910
|
}
|
|
911
|
+
/**
|
|
912
|
+
* Creates a stream for new group conversations
|
|
913
|
+
*
|
|
914
|
+
* @param callback - Optional callback function for handling new stream value
|
|
915
|
+
* @returns Stream instance for new group conversations
|
|
916
|
+
*/
|
|
550
917
|
streamGroups(callback) {
|
|
551
918
|
const asyncStream = new AsyncStream();
|
|
552
919
|
const stream = this.#conversations.streamGroups((error, value) => {
|
|
@@ -566,6 +933,12 @@ class Conversations {
|
|
|
566
933
|
asyncStream.onReturn = stream.end.bind(stream);
|
|
567
934
|
return asyncStream;
|
|
568
935
|
}
|
|
936
|
+
/**
|
|
937
|
+
* Creates a stream for new DM conversations
|
|
938
|
+
*
|
|
939
|
+
* @param callback - Optional callback function for handling new stream value
|
|
940
|
+
* @returns Stream instance for new DM conversations
|
|
941
|
+
*/
|
|
569
942
|
streamDms(callback) {
|
|
570
943
|
const asyncStream = new AsyncStream();
|
|
571
944
|
const stream = this.#conversations.streamDms((error, value) => {
|
|
@@ -585,6 +958,12 @@ class Conversations {
|
|
|
585
958
|
asyncStream.onReturn = stream.end.bind(stream);
|
|
586
959
|
return asyncStream;
|
|
587
960
|
}
|
|
961
|
+
/**
|
|
962
|
+
* Creates a stream for all new messages
|
|
963
|
+
*
|
|
964
|
+
* @param callback - Optional callback function for handling new stream value
|
|
965
|
+
* @returns Stream instance for new messages
|
|
966
|
+
*/
|
|
588
967
|
async streamAllMessages(callback) {
|
|
589
968
|
// sync conversations first
|
|
590
969
|
await this.sync();
|
|
@@ -606,6 +985,12 @@ class Conversations {
|
|
|
606
985
|
asyncStream.onReturn = stream.end.bind(stream);
|
|
607
986
|
return asyncStream;
|
|
608
987
|
}
|
|
988
|
+
/**
|
|
989
|
+
* Creates a stream for all new group messages
|
|
990
|
+
*
|
|
991
|
+
* @param callback - Optional callback function for handling new stream value
|
|
992
|
+
* @returns Stream instance for new group messages
|
|
993
|
+
*/
|
|
609
994
|
async streamAllGroupMessages(callback) {
|
|
610
995
|
// sync conversations first
|
|
611
996
|
await this.sync();
|
|
@@ -627,6 +1012,12 @@ class Conversations {
|
|
|
627
1012
|
asyncStream.onReturn = stream.end.bind(stream);
|
|
628
1013
|
return asyncStream;
|
|
629
1014
|
}
|
|
1015
|
+
/**
|
|
1016
|
+
* Creates a stream for all new DM messages
|
|
1017
|
+
*
|
|
1018
|
+
* @param callback - Optional callback function for handling new stream value
|
|
1019
|
+
* @returns Stream instance for new DM messages
|
|
1020
|
+
*/
|
|
630
1021
|
async streamAllDmMessages(callback) {
|
|
631
1022
|
// sync conversations first
|
|
632
1023
|
await this.sync();
|
|
@@ -648,33 +1039,87 @@ class Conversations {
|
|
|
648
1039
|
asyncStream.onReturn = stream.end.bind(stream);
|
|
649
1040
|
return asyncStream;
|
|
650
1041
|
}
|
|
1042
|
+
/**
|
|
1043
|
+
* Retrieves HMAC keys for all conversations
|
|
1044
|
+
*
|
|
1045
|
+
* @returns The HMAC keys for all conversations
|
|
1046
|
+
*/
|
|
651
1047
|
hmacKeys() {
|
|
652
1048
|
return this.#conversations.getHmacKeys();
|
|
653
1049
|
}
|
|
654
1050
|
}
|
|
655
1051
|
|
|
1052
|
+
/**
|
|
1053
|
+
* Manages user preferences and consent states
|
|
1054
|
+
*
|
|
1055
|
+
* This class is not intended to be initialized directly.
|
|
1056
|
+
*/
|
|
656
1057
|
class Preferences {
|
|
657
1058
|
#client;
|
|
658
1059
|
#conversations;
|
|
1060
|
+
/**
|
|
1061
|
+
* Creates a new preferences instance
|
|
1062
|
+
*
|
|
1063
|
+
* @param client - The client instance managing preferences
|
|
1064
|
+
* @param conversations - The underlying conversations instance
|
|
1065
|
+
*/
|
|
659
1066
|
constructor(client, conversations) {
|
|
660
1067
|
this.#client = client;
|
|
661
1068
|
this.#conversations = conversations;
|
|
662
1069
|
}
|
|
1070
|
+
/**
|
|
1071
|
+
* Retrieves the current inbox state
|
|
1072
|
+
*
|
|
1073
|
+
* @param refreshFromNetwork - Optional flag to force refresh from network
|
|
1074
|
+
* @returns Promise that resolves with the inbox state
|
|
1075
|
+
*/
|
|
663
1076
|
async inboxState(refreshFromNetwork = false) {
|
|
664
1077
|
return this.#client.inboxState(refreshFromNetwork);
|
|
665
1078
|
}
|
|
1079
|
+
/**
|
|
1080
|
+
* Gets the latest inbox state for a specific inbox
|
|
1081
|
+
*
|
|
1082
|
+
* @param inboxId - The inbox ID to get state for
|
|
1083
|
+
* @returns Promise that resolves with the latest inbox state
|
|
1084
|
+
*/
|
|
666
1085
|
async getLatestInboxState(inboxId) {
|
|
667
1086
|
return this.#client.getLatestInboxState(inboxId);
|
|
668
1087
|
}
|
|
1088
|
+
/**
|
|
1089
|
+
* Retrieves inbox state for specific inbox IDs
|
|
1090
|
+
*
|
|
1091
|
+
* @param inboxIds - Array of inbox IDs to get state for
|
|
1092
|
+
* @param refreshFromNetwork - Optional flag to force refresh from network
|
|
1093
|
+
* @returns Promise that resolves with the inbox state for the inbox IDs
|
|
1094
|
+
*/
|
|
669
1095
|
async inboxStateFromInboxIds(inboxIds, refreshFromNetwork) {
|
|
670
1096
|
return this.#client.addressesFromInboxId(refreshFromNetwork ?? false, inboxIds);
|
|
671
1097
|
}
|
|
1098
|
+
/**
|
|
1099
|
+
* Updates consent states for multiple records
|
|
1100
|
+
*
|
|
1101
|
+
* @param consentStates - Array of consent records to update
|
|
1102
|
+
* @returns Promise that resolves when consent states are updated
|
|
1103
|
+
*/
|
|
672
1104
|
async setConsentStates(consentStates) {
|
|
673
1105
|
return this.#client.setConsentStates(consentStates);
|
|
674
1106
|
}
|
|
1107
|
+
/**
|
|
1108
|
+
* Retrieves consent state for a specific entity
|
|
1109
|
+
*
|
|
1110
|
+
* @param entityType - Type of entity to get consent for
|
|
1111
|
+
* @param entity - Entity identifier
|
|
1112
|
+
* @returns Promise that resolves with the consent state
|
|
1113
|
+
*/
|
|
675
1114
|
async getConsentState(entityType, entity) {
|
|
676
1115
|
return this.#client.getConsentState(entityType, entity);
|
|
677
1116
|
}
|
|
1117
|
+
/**
|
|
1118
|
+
* Creates a stream of consent state updates
|
|
1119
|
+
*
|
|
1120
|
+
* @param callback - Optional callback function for handling stream updates
|
|
1121
|
+
* @returns Stream instance for consent updates
|
|
1122
|
+
*/
|
|
678
1123
|
streamConsent(callback) {
|
|
679
1124
|
const asyncStream = new AsyncStream();
|
|
680
1125
|
const stream = this.#conversations.streamConsent((err, value) => {
|
|
@@ -689,6 +1134,12 @@ class Preferences {
|
|
|
689
1134
|
asyncStream.onReturn = stream.end.bind(stream);
|
|
690
1135
|
return asyncStream;
|
|
691
1136
|
}
|
|
1137
|
+
/**
|
|
1138
|
+
* Creates a stream of user preference updates
|
|
1139
|
+
*
|
|
1140
|
+
* @param callback - Optional callback function for handling stream updates
|
|
1141
|
+
* @returns Stream instance for preference updates
|
|
1142
|
+
*/
|
|
692
1143
|
streamPreferences(callback) {
|
|
693
1144
|
const asyncStream = new AsyncStream();
|
|
694
1145
|
const stream = this.#conversations.streamPreferences((err, value) => {
|
|
@@ -715,81 +1166,202 @@ const getInboxIdForIdentifier = async (identifier, env = "dev") => {
|
|
|
715
1166
|
return getInboxIdForIdentifier$1(host, isSecure, identifier);
|
|
716
1167
|
};
|
|
717
1168
|
|
|
718
|
-
const createClient = async (identifier,
|
|
1169
|
+
const createClient = async (identifier, options) => {
|
|
719
1170
|
const env = options?.env || "dev";
|
|
720
1171
|
const host = options?.apiUrl || ApiUrls[env];
|
|
721
1172
|
const isSecure = host.startsWith("https");
|
|
722
1173
|
const inboxId = (await getInboxIdForIdentifier(identifier, env)) ||
|
|
723
1174
|
generateInboxId(identifier);
|
|
724
|
-
const dbPath = options?.dbPath
|
|
1175
|
+
const dbPath = options?.dbPath === undefined
|
|
1176
|
+
? join(process.cwd(), `xmtp-${env}-${inboxId}.db3`)
|
|
1177
|
+
: options.dbPath;
|
|
725
1178
|
const logOptions = {
|
|
726
1179
|
structured: options?.structuredLogging ?? false,
|
|
727
1180
|
level: options?.loggingLevel ?? "off" /* LogLevel.off */,
|
|
728
1181
|
};
|
|
729
1182
|
const historySyncUrl = options?.historySyncUrl || HistorySyncUrls[env];
|
|
730
|
-
return createClient$1(host, isSecure, dbPath, inboxId, identifier,
|
|
1183
|
+
return createClient$1(host, isSecure, dbPath, inboxId, identifier, options?.dbEncryptionKey, historySyncUrl, logOptions);
|
|
731
1184
|
};
|
|
732
1185
|
|
|
733
1186
|
const version = `${bindingsVersion.branch}@${bindingsVersion.version} (${bindingsVersion.date})`;
|
|
734
1187
|
|
|
1188
|
+
/**
|
|
1189
|
+
* Client for interacting with the XMTP network
|
|
1190
|
+
*/
|
|
735
1191
|
class Client {
|
|
736
|
-
#
|
|
1192
|
+
#client;
|
|
737
1193
|
#conversations;
|
|
738
1194
|
#preferences;
|
|
739
1195
|
#signer;
|
|
740
1196
|
#codecs;
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
1197
|
+
#identifier;
|
|
1198
|
+
#options;
|
|
1199
|
+
/**
|
|
1200
|
+
* Creates a new XMTP client instance
|
|
1201
|
+
*
|
|
1202
|
+
* This class is not intended to be initialized directly.
|
|
1203
|
+
* Use `Client.create` or `Client.build` instead.
|
|
1204
|
+
*
|
|
1205
|
+
* @param options - Optional configuration for the client
|
|
1206
|
+
*/
|
|
1207
|
+
constructor(options) {
|
|
1208
|
+
this.#options = options;
|
|
1209
|
+
const codecs = [
|
|
753
1210
|
new GroupUpdatedCodec(),
|
|
754
1211
|
new TextCodec(),
|
|
755
1212
|
...(options?.codecs ?? []),
|
|
756
|
-
]
|
|
1213
|
+
];
|
|
1214
|
+
this.#codecs = new Map(codecs.map((codec) => [codec.contentType.toString(), codec]));
|
|
1215
|
+
}
|
|
1216
|
+
/**
|
|
1217
|
+
* Initializes the client with the provided identifier
|
|
1218
|
+
*
|
|
1219
|
+
* This is not meant to be called directly.
|
|
1220
|
+
* Use `Client.create` or `Client.build` instead.
|
|
1221
|
+
*
|
|
1222
|
+
* @param identifier - The identifier to initialize the client with
|
|
1223
|
+
*/
|
|
1224
|
+
async init(identifier) {
|
|
1225
|
+
if (this.#client) {
|
|
1226
|
+
return;
|
|
1227
|
+
}
|
|
1228
|
+
this.#identifier = identifier;
|
|
1229
|
+
this.#client = await createClient(identifier, this.#options);
|
|
1230
|
+
const conversations = this.#client.conversations();
|
|
1231
|
+
this.#conversations = new Conversations(this, conversations);
|
|
1232
|
+
this.#preferences = new Preferences(this.#client, conversations);
|
|
1233
|
+
}
|
|
1234
|
+
/**
|
|
1235
|
+
* Creates a new client instance with a signer
|
|
1236
|
+
*
|
|
1237
|
+
* @param signer - The signer to use for authentication
|
|
1238
|
+
* @param options - Optional configuration for the client
|
|
1239
|
+
* @returns A new client instance
|
|
1240
|
+
*/
|
|
1241
|
+
static async create(signer, options) {
|
|
1242
|
+
const identifier = await signer.getIdentifier();
|
|
1243
|
+
const client = new Client(options);
|
|
1244
|
+
client.#signer = signer;
|
|
1245
|
+
await client.init(identifier);
|
|
757
1246
|
if (!options?.disableAutoRegister) {
|
|
758
|
-
await
|
|
1247
|
+
await client.register();
|
|
759
1248
|
}
|
|
760
|
-
return
|
|
1249
|
+
return client;
|
|
761
1250
|
}
|
|
762
|
-
|
|
763
|
-
|
|
1251
|
+
/**
|
|
1252
|
+
* Creates a new client instance with an identifier
|
|
1253
|
+
*
|
|
1254
|
+
* Clients created with this method must already be registered.
|
|
1255
|
+
* Any methods called that require a signer will throw an error.
|
|
1256
|
+
*
|
|
1257
|
+
* @param identifier - The identifier to use
|
|
1258
|
+
* @param options - Optional configuration for the client
|
|
1259
|
+
* @returns A new client instance
|
|
1260
|
+
*/
|
|
1261
|
+
static async build(identifier, options) {
|
|
1262
|
+
const client = new Client({
|
|
1263
|
+
...options,
|
|
1264
|
+
disableAutoRegister: true,
|
|
1265
|
+
});
|
|
1266
|
+
await client.init(identifier);
|
|
1267
|
+
return client;
|
|
1268
|
+
}
|
|
1269
|
+
/**
|
|
1270
|
+
* Gets the client options
|
|
1271
|
+
*/
|
|
1272
|
+
get options() {
|
|
1273
|
+
return this.#options;
|
|
1274
|
+
}
|
|
1275
|
+
/**
|
|
1276
|
+
* Gets the signer associated with this client
|
|
1277
|
+
*/
|
|
1278
|
+
get signer() {
|
|
1279
|
+
return this.#signer;
|
|
1280
|
+
}
|
|
1281
|
+
/**
|
|
1282
|
+
* Gets the account identifier for this client
|
|
1283
|
+
*/
|
|
1284
|
+
get accountIdentifier() {
|
|
1285
|
+
return this.#identifier;
|
|
764
1286
|
}
|
|
1287
|
+
/**
|
|
1288
|
+
* Gets the inbox ID associated with this client
|
|
1289
|
+
*/
|
|
765
1290
|
get inboxId() {
|
|
766
|
-
|
|
1291
|
+
if (!this.#client) {
|
|
1292
|
+
throw new ClientNotInitializedError();
|
|
1293
|
+
}
|
|
1294
|
+
return this.#client.inboxId();
|
|
767
1295
|
}
|
|
1296
|
+
/**
|
|
1297
|
+
* Gets the installation ID for this client
|
|
1298
|
+
*/
|
|
768
1299
|
get installationId() {
|
|
769
|
-
|
|
1300
|
+
if (!this.#client) {
|
|
1301
|
+
throw new ClientNotInitializedError();
|
|
1302
|
+
}
|
|
1303
|
+
return this.#client.installationId();
|
|
770
1304
|
}
|
|
1305
|
+
/**
|
|
1306
|
+
* Gets the installation ID bytes for this client
|
|
1307
|
+
*/
|
|
771
1308
|
get installationIdBytes() {
|
|
772
|
-
|
|
1309
|
+
if (!this.#client) {
|
|
1310
|
+
throw new ClientNotInitializedError();
|
|
1311
|
+
}
|
|
1312
|
+
return this.#client.installationIdBytes();
|
|
773
1313
|
}
|
|
1314
|
+
/**
|
|
1315
|
+
* Gets whether the client is registered with the XMTP network
|
|
1316
|
+
*
|
|
1317
|
+
* @throws {ClientNotInitializedError} if the client is not initialized
|
|
1318
|
+
*/
|
|
774
1319
|
get isRegistered() {
|
|
775
|
-
|
|
1320
|
+
if (!this.#client) {
|
|
1321
|
+
throw new ClientNotInitializedError();
|
|
1322
|
+
}
|
|
1323
|
+
return this.#client.isRegistered();
|
|
776
1324
|
}
|
|
1325
|
+
/**
|
|
1326
|
+
* Gets the conversations manager for this client
|
|
1327
|
+
*
|
|
1328
|
+
* @throws {ClientNotInitializedError} if the client is not initialized
|
|
1329
|
+
*/
|
|
777
1330
|
get conversations() {
|
|
1331
|
+
if (!this.#conversations) {
|
|
1332
|
+
throw new ClientNotInitializedError();
|
|
1333
|
+
}
|
|
778
1334
|
return this.#conversations;
|
|
779
1335
|
}
|
|
1336
|
+
/**
|
|
1337
|
+
* Gets the preferences manager for this client
|
|
1338
|
+
*
|
|
1339
|
+
* @throws {ClientNotInitializedError} if the client is not initialized
|
|
1340
|
+
*/
|
|
780
1341
|
get preferences() {
|
|
1342
|
+
if (!this.#preferences) {
|
|
1343
|
+
throw new ClientNotInitializedError();
|
|
1344
|
+
}
|
|
781
1345
|
return this.#preferences;
|
|
782
1346
|
}
|
|
783
1347
|
/**
|
|
1348
|
+
* Creates signature text for creating a new inbox
|
|
1349
|
+
*
|
|
784
1350
|
* WARNING: This function should be used with caution. It is only provided
|
|
785
1351
|
* for use in special cases where the provided workflows do not meet the
|
|
786
1352
|
* requirements of an application.
|
|
787
1353
|
*
|
|
788
|
-
* It is highly recommended to use the `register`
|
|
1354
|
+
* It is highly recommended to use the `register` method instead.
|
|
1355
|
+
*
|
|
1356
|
+
* @returns The signature text
|
|
1357
|
+
* @throws {ClientNotInitializedError} if the client is not initialized
|
|
789
1358
|
*/
|
|
790
1359
|
async unsafe_createInboxSignatureText() {
|
|
1360
|
+
if (!this.#client) {
|
|
1361
|
+
throw new ClientNotInitializedError();
|
|
1362
|
+
}
|
|
791
1363
|
try {
|
|
792
|
-
const signatureText = await this.#
|
|
1364
|
+
const signatureText = await this.#client.createInboxSignatureText();
|
|
793
1365
|
return signatureText;
|
|
794
1366
|
}
|
|
795
1367
|
catch {
|
|
@@ -797,21 +1369,31 @@ class Client {
|
|
|
797
1369
|
}
|
|
798
1370
|
}
|
|
799
1371
|
/**
|
|
1372
|
+
* Creates signature text for adding a new account to the client's inbox
|
|
1373
|
+
*
|
|
800
1374
|
* WARNING: This function should be used with caution. It is only provided
|
|
801
1375
|
* for use in special cases where the provided workflows do not meet the
|
|
802
1376
|
* requirements of an application.
|
|
803
1377
|
*
|
|
804
|
-
* It is highly recommended to use the `unsafe_addAccount`
|
|
1378
|
+
* It is highly recommended to use the `unsafe_addAccount` method instead.
|
|
805
1379
|
*
|
|
806
1380
|
* The `allowInboxReassign` parameter must be true or this function will
|
|
807
1381
|
* throw an error.
|
|
1382
|
+
*
|
|
1383
|
+
* @param newAccountIdentifier - The identifier of the new account
|
|
1384
|
+
* @param allowInboxReassign - Whether to allow inbox reassignment
|
|
1385
|
+
* @returns The signature text
|
|
1386
|
+
* @throws {ClientNotInitializedError} if the client is not initialized
|
|
808
1387
|
*/
|
|
809
1388
|
async unsafe_addAccountSignatureText(newAccountIdentifier, allowInboxReassign = false) {
|
|
1389
|
+
if (!this.#client) {
|
|
1390
|
+
throw new ClientNotInitializedError();
|
|
1391
|
+
}
|
|
810
1392
|
if (!allowInboxReassign) {
|
|
811
1393
|
throw new InboxReassignError();
|
|
812
1394
|
}
|
|
813
1395
|
try {
|
|
814
|
-
const signatureText = await this.#
|
|
1396
|
+
const signatureText = await this.#client.addIdentifierSignatureText(newAccountIdentifier);
|
|
815
1397
|
return signatureText;
|
|
816
1398
|
}
|
|
817
1399
|
catch {
|
|
@@ -819,15 +1401,24 @@ class Client {
|
|
|
819
1401
|
}
|
|
820
1402
|
}
|
|
821
1403
|
/**
|
|
1404
|
+
* Creates signature text for removing an account from the client's inbox
|
|
1405
|
+
*
|
|
822
1406
|
* WARNING: This function should be used with caution. It is only provided
|
|
823
1407
|
* for use in special cases where the provided workflows do not meet the
|
|
824
1408
|
* requirements of an application.
|
|
825
1409
|
*
|
|
826
|
-
* It is highly recommended to use the `removeAccount`
|
|
1410
|
+
* It is highly recommended to use the `removeAccount` method instead.
|
|
1411
|
+
*
|
|
1412
|
+
* @param identifier - The identifier of the account to remove
|
|
1413
|
+
* @returns The signature text
|
|
1414
|
+
* @throws {ClientNotInitializedError} if the client is not initialized
|
|
827
1415
|
*/
|
|
828
1416
|
async unsafe_removeAccountSignatureText(identifier) {
|
|
1417
|
+
if (!this.#client) {
|
|
1418
|
+
throw new ClientNotInitializedError();
|
|
1419
|
+
}
|
|
829
1420
|
try {
|
|
830
|
-
const signatureText = await this.#
|
|
1421
|
+
const signatureText = await this.#client.revokeIdentifierSignatureText(identifier);
|
|
831
1422
|
return signatureText;
|
|
832
1423
|
}
|
|
833
1424
|
catch {
|
|
@@ -835,16 +1426,24 @@ class Client {
|
|
|
835
1426
|
}
|
|
836
1427
|
}
|
|
837
1428
|
/**
|
|
1429
|
+
* Creates signature text for revoking all other installations of the
|
|
1430
|
+
* client's inbox
|
|
1431
|
+
*
|
|
838
1432
|
* WARNING: This function should be used with caution. It is only provided
|
|
839
1433
|
* for use in special cases where the provided workflows do not meet the
|
|
840
1434
|
* requirements of an application.
|
|
841
1435
|
*
|
|
842
|
-
* It is highly recommended to use the `revokeAllOtherInstallations`
|
|
843
|
-
*
|
|
1436
|
+
* It is highly recommended to use the `revokeAllOtherInstallations` method instead.
|
|
1437
|
+
*
|
|
1438
|
+
* @returns The signature text
|
|
1439
|
+
* @throws {ClientNotInitializedError} if the client is not initialized
|
|
844
1440
|
*/
|
|
845
1441
|
async unsafe_revokeAllOtherInstallationsSignatureText() {
|
|
1442
|
+
if (!this.#client) {
|
|
1443
|
+
throw new ClientNotInitializedError();
|
|
1444
|
+
}
|
|
846
1445
|
try {
|
|
847
|
-
const signatureText = await this.#
|
|
1446
|
+
const signatureText = await this.#client.revokeAllOtherInstallationsSignatureText();
|
|
848
1447
|
return signatureText;
|
|
849
1448
|
}
|
|
850
1449
|
catch {
|
|
@@ -852,15 +1451,25 @@ class Client {
|
|
|
852
1451
|
}
|
|
853
1452
|
}
|
|
854
1453
|
/**
|
|
1454
|
+
* Creates signature text for revoking specific installations of the
|
|
1455
|
+
* client's inbox
|
|
1456
|
+
*
|
|
855
1457
|
* WARNING: This function should be used with caution. It is only provided
|
|
856
1458
|
* for use in special cases where the provided workflows do not meet the
|
|
857
1459
|
* requirements of an application.
|
|
858
1460
|
*
|
|
859
|
-
* It is highly recommended to use the `revokeInstallations`
|
|
1461
|
+
* It is highly recommended to use the `revokeInstallations` method instead.
|
|
1462
|
+
*
|
|
1463
|
+
* @param installationIds - The installation IDs to revoke
|
|
1464
|
+
* @returns The signature text
|
|
1465
|
+
* @throws {ClientNotInitializedError} if the client is not initialized
|
|
860
1466
|
*/
|
|
861
1467
|
async unsafe_revokeInstallationsSignatureText(installationIds) {
|
|
1468
|
+
if (!this.#client) {
|
|
1469
|
+
throw new ClientNotInitializedError();
|
|
1470
|
+
}
|
|
862
1471
|
try {
|
|
863
|
-
const signatureText = await this.#
|
|
1472
|
+
const signatureText = await this.#client.revokeInstallationsSignatureText(installationIds);
|
|
864
1473
|
return signatureText;
|
|
865
1474
|
}
|
|
866
1475
|
catch {
|
|
@@ -868,15 +1477,25 @@ class Client {
|
|
|
868
1477
|
}
|
|
869
1478
|
}
|
|
870
1479
|
/**
|
|
1480
|
+
* Creates signature text for changing the recovery identifier for this
|
|
1481
|
+
* client's inbox
|
|
1482
|
+
*
|
|
871
1483
|
* WARNING: This function should be used with caution. It is only provided
|
|
872
1484
|
* for use in special cases where the provided workflows do not meet the
|
|
873
1485
|
* requirements of an application.
|
|
874
1486
|
*
|
|
875
|
-
* It is highly recommended to use the `
|
|
1487
|
+
* It is highly recommended to use the `changeRecoveryIdentifier` method instead.
|
|
1488
|
+
*
|
|
1489
|
+
* @param identifier - The new recovery identifier
|
|
1490
|
+
* @returns The signature text
|
|
1491
|
+
* @throws {ClientNotInitializedError} if the client is not initialized
|
|
876
1492
|
*/
|
|
877
1493
|
async unsafe_changeRecoveryIdentifierSignatureText(identifier) {
|
|
1494
|
+
if (!this.#client) {
|
|
1495
|
+
throw new ClientNotInitializedError();
|
|
1496
|
+
}
|
|
878
1497
|
try {
|
|
879
|
-
const signatureText = await this.#
|
|
1498
|
+
const signatureText = await this.#client.changeRecoveryIdentifierSignatureText(identifier);
|
|
880
1499
|
return signatureText;
|
|
881
1500
|
}
|
|
882
1501
|
catch {
|
|
@@ -884,54 +1503,99 @@ class Client {
|
|
|
884
1503
|
}
|
|
885
1504
|
}
|
|
886
1505
|
/**
|
|
1506
|
+
* Adds a signature for a specific request type
|
|
1507
|
+
*
|
|
887
1508
|
* WARNING: This function should be used with caution. It is only provided
|
|
888
1509
|
* for use in special cases where the provided workflows do not meet the
|
|
889
1510
|
* requirements of an application.
|
|
890
1511
|
*
|
|
891
1512
|
* It is highly recommended to use the `register`, `unsafe_addAccount`,
|
|
892
1513
|
* `removeAccount`, `revokeAllOtherInstallations`, or `revokeInstallations`
|
|
893
|
-
*
|
|
1514
|
+
* methods instead.
|
|
1515
|
+
*
|
|
1516
|
+
* @param signatureType - The type of signature request
|
|
1517
|
+
* @param signatureText - The text to sign
|
|
1518
|
+
* @param signer - The signer to use
|
|
1519
|
+
* @throws {ClientNotInitializedError} if the client is not initialized
|
|
894
1520
|
*/
|
|
895
1521
|
async unsafe_addSignature(signatureType, signatureText, signer) {
|
|
1522
|
+
if (!this.#client) {
|
|
1523
|
+
throw new ClientNotInitializedError();
|
|
1524
|
+
}
|
|
896
1525
|
switch (signer.type) {
|
|
897
1526
|
case "SCW":
|
|
898
|
-
await this.#
|
|
1527
|
+
await this.#client.addScwSignature(signatureType, await signer.signMessage(signatureText), signer.getChainId(), signer.getBlockNumber?.());
|
|
899
1528
|
break;
|
|
900
1529
|
case "EOA":
|
|
901
|
-
await this.#
|
|
1530
|
+
await this.#client.addEcdsaSignature(signatureType, await signer.signMessage(signatureText));
|
|
902
1531
|
break;
|
|
903
1532
|
}
|
|
904
1533
|
}
|
|
905
1534
|
/**
|
|
1535
|
+
* Applies all pending signatures
|
|
1536
|
+
*
|
|
906
1537
|
* WARNING: This function should be used with caution. It is only provided
|
|
907
1538
|
* for use in special cases where the provided workflows do not meet the
|
|
908
1539
|
* requirements of an application.
|
|
909
1540
|
*
|
|
910
1541
|
* It is highly recommended to use the `register`, `unsafe_addAccount`,
|
|
911
1542
|
* `removeAccount`, `revokeAllOtherInstallations`, or `revokeInstallations`
|
|
912
|
-
*
|
|
1543
|
+
* methods instead.
|
|
1544
|
+
*
|
|
1545
|
+
* @throws {ClientNotInitializedError} if the client is not initialized
|
|
913
1546
|
*/
|
|
914
1547
|
async unsafe_applySignatures() {
|
|
915
|
-
|
|
1548
|
+
if (!this.#client) {
|
|
1549
|
+
throw new ClientNotInitializedError();
|
|
1550
|
+
}
|
|
1551
|
+
return this.#client.applySignatureRequests();
|
|
916
1552
|
}
|
|
1553
|
+
/**
|
|
1554
|
+
* Registers the client with the XMTP network
|
|
1555
|
+
*
|
|
1556
|
+
* Requires a signer, use `Client.create` to create a client with a signer.
|
|
1557
|
+
*
|
|
1558
|
+
* @throws {ClientNotInitializedError} if the client is not initialized
|
|
1559
|
+
* @throws {SignerUnavailableError} if no signer is available
|
|
1560
|
+
*/
|
|
917
1561
|
async register() {
|
|
1562
|
+
if (!this.#client) {
|
|
1563
|
+
throw new ClientNotInitializedError();
|
|
1564
|
+
}
|
|
1565
|
+
if (!this.#signer) {
|
|
1566
|
+
throw new SignerUnavailableError();
|
|
1567
|
+
}
|
|
918
1568
|
const signatureText = await this.unsafe_createInboxSignatureText();
|
|
919
1569
|
// if the signature text is not available, the client is already registered
|
|
920
1570
|
if (!signatureText) {
|
|
921
1571
|
return;
|
|
922
1572
|
}
|
|
923
1573
|
await this.unsafe_addSignature(1 /* SignatureRequestType.CreateInbox */, signatureText, this.#signer);
|
|
924
|
-
return this.#
|
|
1574
|
+
return this.#client.registerIdentity();
|
|
925
1575
|
}
|
|
926
1576
|
/**
|
|
1577
|
+
* Adds a new account to the client inbox
|
|
1578
|
+
*
|
|
927
1579
|
* WARNING: This function should be used with caution. Adding a wallet already
|
|
928
|
-
* associated with an
|
|
1580
|
+
* associated with an inbox ID will cause the wallet to lose access to
|
|
929
1581
|
* that inbox.
|
|
930
1582
|
*
|
|
931
1583
|
* The `allowInboxReassign` parameter must be true to reassign an inbox
|
|
932
1584
|
* already associated with a different account.
|
|
1585
|
+
*
|
|
1586
|
+
* Requires a signer, use `Client.create` to create a client with a signer.
|
|
1587
|
+
*
|
|
1588
|
+
* @param newAccountSigner - The signer for the new account
|
|
1589
|
+
* @param allowInboxReassign - Whether to allow inbox reassignment
|
|
1590
|
+
* @throws {ClientNotInitializedError} if the client is not initialized
|
|
1591
|
+
* @throws {AccountAlreadyAssociatedError} if the account is already associated with an inbox ID
|
|
1592
|
+
* @throws {GenerateSignatureError} if the signature cannot be generated
|
|
1593
|
+
* @throws {SignerUnavailableError} if no signer is available
|
|
933
1594
|
*/
|
|
934
1595
|
async unsafe_addAccount(newAccountSigner, allowInboxReassign = false) {
|
|
1596
|
+
if (!this.#client) {
|
|
1597
|
+
throw new ClientNotInitializedError();
|
|
1598
|
+
}
|
|
935
1599
|
// check for existing inbox id
|
|
936
1600
|
const identifier = await newAccountSigner.getIdentifier();
|
|
937
1601
|
const existingInboxId = await this.getInboxIdByIdentifier(identifier);
|
|
@@ -945,7 +1609,23 @@ class Client {
|
|
|
945
1609
|
await this.unsafe_addSignature(0 /* SignatureRequestType.AddWallet */, signatureText, newAccountSigner);
|
|
946
1610
|
await this.unsafe_applySignatures();
|
|
947
1611
|
}
|
|
1612
|
+
/**
|
|
1613
|
+
* Removes an account from the client's inbox
|
|
1614
|
+
*
|
|
1615
|
+
* Requires a signer, use `Client.create` to create a client with a signer.
|
|
1616
|
+
*
|
|
1617
|
+
* @param identifier - The identifier of the account to remove
|
|
1618
|
+
* @throws {ClientNotInitializedError} if the client is not initialized
|
|
1619
|
+
* @throws {GenerateSignatureError} if the signature cannot be generated
|
|
1620
|
+
* @throws {SignerUnavailableError} if no signer is available
|
|
1621
|
+
*/
|
|
948
1622
|
async removeAccount(identifier) {
|
|
1623
|
+
if (!this.#client) {
|
|
1624
|
+
throw new ClientNotInitializedError();
|
|
1625
|
+
}
|
|
1626
|
+
if (!this.#signer) {
|
|
1627
|
+
throw new SignerUnavailableError();
|
|
1628
|
+
}
|
|
949
1629
|
const signatureText = await this.unsafe_removeAccountSignatureText(identifier);
|
|
950
1630
|
if (!signatureText) {
|
|
951
1631
|
throw new GenerateSignatureError(2 /* SignatureRequestType.RevokeWallet */);
|
|
@@ -953,7 +1633,22 @@ class Client {
|
|
|
953
1633
|
await this.unsafe_addSignature(2 /* SignatureRequestType.RevokeWallet */, signatureText, this.#signer);
|
|
954
1634
|
await this.unsafe_applySignatures();
|
|
955
1635
|
}
|
|
1636
|
+
/**
|
|
1637
|
+
* Revokes all other installations of the client's inbox
|
|
1638
|
+
*
|
|
1639
|
+
* Requires a signer, use `Client.create` to create a client with a signer.
|
|
1640
|
+
*
|
|
1641
|
+
* @throws {ClientNotInitializedError} if the client is not initialized
|
|
1642
|
+
* @throws {GenerateSignatureError} if the signature cannot be generated
|
|
1643
|
+
* @throws {SignerUnavailableError} if no signer is available
|
|
1644
|
+
*/
|
|
956
1645
|
async revokeAllOtherInstallations() {
|
|
1646
|
+
if (!this.#client) {
|
|
1647
|
+
throw new ClientNotInitializedError();
|
|
1648
|
+
}
|
|
1649
|
+
if (!this.#signer) {
|
|
1650
|
+
throw new SignerUnavailableError();
|
|
1651
|
+
}
|
|
957
1652
|
const signatureText = await this.unsafe_revokeAllOtherInstallationsSignatureText();
|
|
958
1653
|
if (!signatureText) {
|
|
959
1654
|
throw new GenerateSignatureError(3 /* SignatureRequestType.RevokeInstallations */);
|
|
@@ -961,7 +1656,23 @@ class Client {
|
|
|
961
1656
|
await this.unsafe_addSignature(3 /* SignatureRequestType.RevokeInstallations */, signatureText, this.#signer);
|
|
962
1657
|
await this.unsafe_applySignatures();
|
|
963
1658
|
}
|
|
1659
|
+
/**
|
|
1660
|
+
* Revokes specific installations of the client's inbox
|
|
1661
|
+
*
|
|
1662
|
+
* Requires a signer, use `Client.create` to create a client with a signer.
|
|
1663
|
+
*
|
|
1664
|
+
* @param installationIds - The installation IDs to revoke
|
|
1665
|
+
* @throws {ClientNotInitializedError} if the client is not initialized
|
|
1666
|
+
* @throws {SignerUnavailableError} if no signer is available
|
|
1667
|
+
* @throws {GenerateSignatureError} if the signature cannot be generated
|
|
1668
|
+
*/
|
|
964
1669
|
async revokeInstallations(installationIds) {
|
|
1670
|
+
if (!this.#client) {
|
|
1671
|
+
throw new ClientNotInitializedError();
|
|
1672
|
+
}
|
|
1673
|
+
if (!this.#signer) {
|
|
1674
|
+
throw new SignerUnavailableError();
|
|
1675
|
+
}
|
|
965
1676
|
const signatureText = await this.unsafe_revokeInstallationsSignatureText(installationIds);
|
|
966
1677
|
if (!signatureText) {
|
|
967
1678
|
throw new GenerateSignatureError(3 /* SignatureRequestType.RevokeInstallations */);
|
|
@@ -969,7 +1680,23 @@ class Client {
|
|
|
969
1680
|
await this.unsafe_addSignature(3 /* SignatureRequestType.RevokeInstallations */, signatureText, this.#signer);
|
|
970
1681
|
await this.unsafe_applySignatures();
|
|
971
1682
|
}
|
|
1683
|
+
/**
|
|
1684
|
+
* Changes the recovery identifier for the client's inbox
|
|
1685
|
+
*
|
|
1686
|
+
* Requires a signer, use `Client.create` to create a client with a signer.
|
|
1687
|
+
*
|
|
1688
|
+
* @param identifier - The new recovery identifier
|
|
1689
|
+
* @throws {ClientNotInitializedError} if the client is not initialized
|
|
1690
|
+
* @throws {SignerUnavailableError} if no signer is available
|
|
1691
|
+
* @throws {GenerateSignatureError} if the signature cannot be generated
|
|
1692
|
+
*/
|
|
972
1693
|
async changeRecoveryIdentifier(identifier) {
|
|
1694
|
+
if (!this.#client) {
|
|
1695
|
+
throw new ClientNotInitializedError();
|
|
1696
|
+
}
|
|
1697
|
+
if (!this.#signer) {
|
|
1698
|
+
throw new SignerUnavailableError();
|
|
1699
|
+
}
|
|
973
1700
|
const signatureText = await this.unsafe_changeRecoveryIdentifierSignatureText(identifier);
|
|
974
1701
|
if (!signatureText) {
|
|
975
1702
|
throw new GenerateSignatureError(4 /* SignatureRequestType.ChangeRecoveryIdentifier */);
|
|
@@ -977,10 +1704,27 @@ class Client {
|
|
|
977
1704
|
await this.unsafe_addSignature(4 /* SignatureRequestType.ChangeRecoveryIdentifier */, signatureText, this.#signer);
|
|
978
1705
|
await this.unsafe_applySignatures();
|
|
979
1706
|
}
|
|
1707
|
+
/**
|
|
1708
|
+
* Checks if the client can message the specified identifiers
|
|
1709
|
+
*
|
|
1710
|
+
* @param identifiers - The identifiers to check
|
|
1711
|
+
* @returns Whether the client can message the identifiers
|
|
1712
|
+
* @throws {ClientNotInitializedError} if the client is not initialized
|
|
1713
|
+
*/
|
|
980
1714
|
async canMessage(identifiers) {
|
|
981
|
-
|
|
1715
|
+
if (!this.#client) {
|
|
1716
|
+
throw new ClientNotInitializedError();
|
|
1717
|
+
}
|
|
1718
|
+
const canMessage = await this.#client.canMessage(identifiers);
|
|
982
1719
|
return new Map(Object.entries(canMessage));
|
|
983
1720
|
}
|
|
1721
|
+
/**
|
|
1722
|
+
* Checks if the specified identifiers can be messaged
|
|
1723
|
+
*
|
|
1724
|
+
* @param identifiers - The identifiers to check
|
|
1725
|
+
* @param env - Optional XMTP environment
|
|
1726
|
+
* @returns Map of identifiers to whether they can be messaged
|
|
1727
|
+
*/
|
|
984
1728
|
static async canMessage(identifiers, env) {
|
|
985
1729
|
const canMessageMap = new Map();
|
|
986
1730
|
for (const identifier of identifiers) {
|
|
@@ -989,12 +1733,36 @@ class Client {
|
|
|
989
1733
|
}
|
|
990
1734
|
return canMessageMap;
|
|
991
1735
|
}
|
|
1736
|
+
/**
|
|
1737
|
+
* Gets the key package statuses for the specified installation IDs
|
|
1738
|
+
*
|
|
1739
|
+
* @param installationIds - The installation IDs to check
|
|
1740
|
+
* @returns The key package statuses
|
|
1741
|
+
* @throws {ClientNotInitializedError} if the client is not initialized
|
|
1742
|
+
*/
|
|
992
1743
|
async getKeyPackageStatusesForInstallationIds(installationIds) {
|
|
993
|
-
|
|
1744
|
+
if (!this.#client) {
|
|
1745
|
+
throw new ClientNotInitializedError();
|
|
1746
|
+
}
|
|
1747
|
+
return this.#client.getKeyPackageStatusesForInstallationIds(installationIds);
|
|
994
1748
|
}
|
|
1749
|
+
/**
|
|
1750
|
+
* Gets the codec for a given content type
|
|
1751
|
+
*
|
|
1752
|
+
* @param contentType - The content type to get the codec for
|
|
1753
|
+
* @returns The codec, if found
|
|
1754
|
+
*/
|
|
995
1755
|
codecFor(contentType) {
|
|
996
1756
|
return this.#codecs.get(contentType.toString());
|
|
997
1757
|
}
|
|
1758
|
+
/**
|
|
1759
|
+
* Encodes content for a given content type
|
|
1760
|
+
*
|
|
1761
|
+
* @param content - The content to encode
|
|
1762
|
+
* @param contentType - The content type to encode for
|
|
1763
|
+
* @returns The encoded content
|
|
1764
|
+
* @throws {CodecNotFoundError} if no codec is found for the content type
|
|
1765
|
+
*/
|
|
998
1766
|
encodeContent(content, contentType) {
|
|
999
1767
|
const codec = this.codecFor(contentType);
|
|
1000
1768
|
if (!codec) {
|
|
@@ -1007,6 +1775,15 @@ class Client {
|
|
|
1007
1775
|
}
|
|
1008
1776
|
return encoded;
|
|
1009
1777
|
}
|
|
1778
|
+
/**
|
|
1779
|
+
* Decodes a message for a given content type
|
|
1780
|
+
*
|
|
1781
|
+
* @param message - The message to decode
|
|
1782
|
+
* @param contentType - The content type to decode for
|
|
1783
|
+
* @returns The decoded content
|
|
1784
|
+
* @throws {CodecNotFoundError} if no codec is found for the content type
|
|
1785
|
+
* @throws {InvalidGroupMembershipChangeError} if the message is an invalid group membership change
|
|
1786
|
+
*/
|
|
1010
1787
|
decodeContent(message, contentType) {
|
|
1011
1788
|
const codec = this.codecFor(contentType);
|
|
1012
1789
|
if (!codec) {
|
|
@@ -1017,27 +1794,62 @@ class Client {
|
|
|
1017
1794
|
message.kind !== 1 /* GroupMessageKind.MembershipChange */) {
|
|
1018
1795
|
throw new InvalidGroupMembershipChangeError(message.id);
|
|
1019
1796
|
}
|
|
1020
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
1021
1797
|
return codec.decode(message.content, this);
|
|
1022
1798
|
}
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1799
|
+
/**
|
|
1800
|
+
* Finds the inbox ID for a given identifier
|
|
1801
|
+
*
|
|
1802
|
+
* @param identifier - The identifier to look up
|
|
1803
|
+
* @returns The inbox ID, if found
|
|
1804
|
+
* @throws {ClientNotInitializedError} if the client is not initialized
|
|
1805
|
+
*/
|
|
1026
1806
|
async getInboxIdByIdentifier(identifier) {
|
|
1027
|
-
|
|
1807
|
+
if (!this.#client) {
|
|
1808
|
+
throw new ClientNotInitializedError();
|
|
1809
|
+
}
|
|
1810
|
+
return this.#client.findInboxIdByIdentifier(identifier);
|
|
1028
1811
|
}
|
|
1812
|
+
/**
|
|
1813
|
+
* Signs a message with the installation key
|
|
1814
|
+
*
|
|
1815
|
+
* @param signatureText - The text to sign
|
|
1816
|
+
* @returns The signature
|
|
1817
|
+
* @throws {ClientNotInitializedError} if the client is not initialized
|
|
1818
|
+
*/
|
|
1029
1819
|
signWithInstallationKey(signatureText) {
|
|
1030
|
-
|
|
1820
|
+
if (!this.#client) {
|
|
1821
|
+
throw new ClientNotInitializedError();
|
|
1822
|
+
}
|
|
1823
|
+
return this.#client.signWithInstallationKey(signatureText);
|
|
1031
1824
|
}
|
|
1825
|
+
/**
|
|
1826
|
+
* Verifies a signature was made with the installation key
|
|
1827
|
+
*
|
|
1828
|
+
* @param signatureText - The text that was signed
|
|
1829
|
+
* @param signatureBytes - The signature bytes to verify
|
|
1830
|
+
* @returns Whether the signature is valid
|
|
1831
|
+
* @throws {ClientNotInitializedError} if the client is not initialized
|
|
1832
|
+
*/
|
|
1032
1833
|
verifySignedWithInstallationKey(signatureText, signatureBytes) {
|
|
1834
|
+
if (!this.#client) {
|
|
1835
|
+
throw new ClientNotInitializedError();
|
|
1836
|
+
}
|
|
1033
1837
|
try {
|
|
1034
|
-
this.#
|
|
1838
|
+
this.#client.verifySignedWithInstallationKey(signatureText, signatureBytes);
|
|
1035
1839
|
return true;
|
|
1036
1840
|
}
|
|
1037
1841
|
catch {
|
|
1038
1842
|
return false;
|
|
1039
1843
|
}
|
|
1040
1844
|
}
|
|
1845
|
+
/**
|
|
1846
|
+
* Verifies a signature was made with a public key
|
|
1847
|
+
*
|
|
1848
|
+
* @param signatureText - The text that was signed
|
|
1849
|
+
* @param signatureBytes - The signature bytes to verify
|
|
1850
|
+
* @param publicKey - The public key to verify against
|
|
1851
|
+
* @returns Whether the signature is valid
|
|
1852
|
+
*/
|
|
1041
1853
|
static verifySignedWithPublicKey(signatureText, signatureBytes, publicKey) {
|
|
1042
1854
|
try {
|
|
1043
1855
|
verifySignedWithPublicKey(signatureText, signatureBytes, publicKey);
|
|
@@ -1047,14 +1859,33 @@ class Client {
|
|
|
1047
1859
|
return false;
|
|
1048
1860
|
}
|
|
1049
1861
|
}
|
|
1862
|
+
/**
|
|
1863
|
+
* Checks if an address is authorized for an inbox
|
|
1864
|
+
*
|
|
1865
|
+
* @param inboxId - The inbox ID to check
|
|
1866
|
+
* @param address - The address to check
|
|
1867
|
+
* @param options - Optional network options
|
|
1868
|
+
* @returns Whether the address is authorized
|
|
1869
|
+
*/
|
|
1050
1870
|
static async isAddressAuthorized(inboxId, address, options) {
|
|
1051
1871
|
const host = options?.apiUrl || ApiUrls[options?.env || "dev"];
|
|
1052
1872
|
return await isAddressAuthorized(host, inboxId, address);
|
|
1053
1873
|
}
|
|
1874
|
+
/**
|
|
1875
|
+
* Checks if an installation is authorized for an inbox
|
|
1876
|
+
*
|
|
1877
|
+
* @param inboxId - The inbox ID to check
|
|
1878
|
+
* @param installation - The installation to check
|
|
1879
|
+
* @param options - Optional network options
|
|
1880
|
+
* @returns Whether the installation is authorized
|
|
1881
|
+
*/
|
|
1054
1882
|
static async isInstallationAuthorized(inboxId, installation, options) {
|
|
1055
1883
|
const host = options?.apiUrl || ApiUrls[options?.env || "dev"];
|
|
1056
1884
|
return await isInstallationAuthorized(host, inboxId, installation);
|
|
1057
1885
|
}
|
|
1886
|
+
/**
|
|
1887
|
+
* Gets the version of the Node bindings
|
|
1888
|
+
*/
|
|
1058
1889
|
static get version() {
|
|
1059
1890
|
return version;
|
|
1060
1891
|
}
|