@xmtp/node-sdk 5.5.0 → 6.0.0-dev.4b2b209
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 +214 -27
- package/dist/index.js +324 -97
- package/dist/index.js.map +1 -1
- package/package.json +5 -4
package/dist/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { generateInboxId as generateInboxId$1,
|
|
2
|
-
export { ActionStyle, ConsentEntityType, ConsentState, ContentType, ConversationType, DeliveryStatus, GroupMembershipState, GroupMessageKind, GroupPermissionsOptions, IdentifierKind, ListConversationsOrderBy, LogLevel, MessageSortBy, MetadataField, PermissionLevel, PermissionPolicy, PermissionUpdateType, ReactionAction, ReactionSchema, SortDirection, contentTypeActions, contentTypeAttachment, contentTypeGroupUpdated, contentTypeIntent, contentTypeLeaveRequest, contentTypeMarkdown, contentTypeMultiRemoteAttachment, contentTypeReaction, contentTypeReadReceipt, contentTypeRemoteAttachment, contentTypeReply, contentTypeText, contentTypeTransactionReference, contentTypeWalletSendCalls, decryptAttachment, encodeActions, encodeAttachment, encodeIntent, encodeMarkdown, encodeMultiRemoteAttachment, encodeReaction, encodeReadReceipt, encodeRemoteAttachment, encodeText, encodeTransactionReference, encodeWalletSendCalls, encryptAttachment } from '@xmtp/node-bindings';
|
|
1
|
+
import { BackendBuilder, generateInboxId as generateInboxId$1, getInboxIdByIdentity, contentTypeIntent, contentTypeActions, contentTypeWalletSendCalls, contentTypeLeaveRequest, contentTypeReadReceipt, contentTypeGroupUpdated, contentTypeTransactionReference, contentTypeMultiRemoteAttachment, contentTypeRemoteAttachment, contentTypeAttachment, contentTypeReaction, contentTypeReply, contentTypeMarkdown, contentTypeText, createClientWithBackend, revokeInstallationsSignatureRequest, applySignatureRequest, fetchInboxStatesByInboxIds, verifySignedWithPublicKey, isAddressAuthorized, isInstallationAuthorized, Backend } from '@xmtp/node-bindings';
|
|
2
|
+
export { ActionStyle, BackupElementSelectionOption, ConsentEntityType, ConsentState, ContentType, ConversationType, DeliveryStatus, GroupMembershipState, GroupMessageKind, GroupPermissionsOptions, IdentifierKind, ListConversationsOrderBy, LogLevel, MessageSortBy, MetadataField, PermissionLevel, PermissionPolicy, PermissionUpdateType, ReactionAction, ReactionSchema, SortDirection, contentTypeActions, contentTypeAttachment, contentTypeGroupUpdated, contentTypeIntent, contentTypeLeaveRequest, contentTypeMarkdown, contentTypeMultiRemoteAttachment, contentTypeReaction, contentTypeReadReceipt, contentTypeRemoteAttachment, contentTypeReply, contentTypeText, contentTypeTransactionReference, contentTypeWalletSendCalls, decryptAttachment, encodeActions, encodeAttachment, encodeIntent, encodeMarkdown, encodeMultiRemoteAttachment, encodeReaction, encodeReadReceipt, encodeRemoteAttachment, encodeText, encodeTransactionReference, encodeWalletSendCalls, encryptAttachment } from '@xmtp/node-bindings';
|
|
3
|
+
import { randomBytes } from 'node:crypto';
|
|
3
4
|
import { contentTypeToString } from '@xmtp/content-type-primitives';
|
|
4
5
|
import { isPromise } from 'node:util/types';
|
|
5
6
|
import { join } from 'node:path';
|
|
@@ -8,6 +9,7 @@ import process from 'node:process';
|
|
|
8
9
|
/**
|
|
9
10
|
* Pre-configured URLs for the XMTP network based on the environment
|
|
10
11
|
*
|
|
12
|
+
* @deprecated Use `createBackend()` instead.
|
|
11
13
|
* @constant
|
|
12
14
|
* @property {string} local - The local URL for the XMTP network
|
|
13
15
|
* @property {string} dev - The development URL for the XMTP network
|
|
@@ -30,6 +32,43 @@ const HistorySyncUrls = {
|
|
|
30
32
|
local: "http://localhost:5558",
|
|
31
33
|
dev: "https://message-history.dev.ephemera.network",
|
|
32
34
|
production: "https://message-history.production.ephemera.network",
|
|
35
|
+
"testnet-staging": "https://message-history.dev.ephemera.network",
|
|
36
|
+
"testnet-dev": "https://message-history.dev.ephemera.network",
|
|
37
|
+
testnet: "https://message-history.dev.ephemera.network",
|
|
38
|
+
mainnet: "https://message-history.production.ephemera.network",
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
const envMap = {
|
|
42
|
+
local: "Local" /* BindingsEnv.Local */,
|
|
43
|
+
dev: "Dev" /* BindingsEnv.Dev */,
|
|
44
|
+
production: "Production" /* BindingsEnv.Production */,
|
|
45
|
+
"testnet-staging": "TestnetStaging" /* BindingsEnv.TestnetStaging */,
|
|
46
|
+
"testnet-dev": "TestnetDev" /* BindingsEnv.TestnetDev */,
|
|
47
|
+
testnet: "Testnet" /* BindingsEnv.Testnet */,
|
|
48
|
+
mainnet: "Mainnet" /* BindingsEnv.Mainnet */,
|
|
49
|
+
};
|
|
50
|
+
const reverseEnvMap = {
|
|
51
|
+
["Local" /* BindingsEnv.Local */]: "local",
|
|
52
|
+
["Dev" /* BindingsEnv.Dev */]: "dev",
|
|
53
|
+
["Production" /* BindingsEnv.Production */]: "production",
|
|
54
|
+
["TestnetStaging" /* BindingsEnv.TestnetStaging */]: "testnet-staging",
|
|
55
|
+
["TestnetDev" /* BindingsEnv.TestnetDev */]: "testnet-dev",
|
|
56
|
+
["Testnet" /* BindingsEnv.Testnet */]: "testnet",
|
|
57
|
+
["Mainnet" /* BindingsEnv.Mainnet */]: "mainnet",
|
|
58
|
+
};
|
|
59
|
+
const envToString = (env) => {
|
|
60
|
+
return reverseEnvMap[env];
|
|
61
|
+
};
|
|
62
|
+
const createBackend = async (options) => {
|
|
63
|
+
const env = options?.env ?? "dev";
|
|
64
|
+
const builder = new BackendBuilder(envMap[env]);
|
|
65
|
+
if (options?.apiUrl)
|
|
66
|
+
builder.setApiUrl(options.apiUrl);
|
|
67
|
+
if (options?.gatewayHost)
|
|
68
|
+
builder.setGatewayHost(options.gatewayHost);
|
|
69
|
+
if (options?.appVersion)
|
|
70
|
+
builder.setAppVersion(options.appVersion);
|
|
71
|
+
return builder.build();
|
|
33
72
|
};
|
|
34
73
|
|
|
35
74
|
class InboxReassignError extends Error {
|
|
@@ -72,10 +111,8 @@ class StreamInvalidRetryAttemptsError extends Error {
|
|
|
72
111
|
const generateInboxId = (identifier, nonce) => {
|
|
73
112
|
return generateInboxId$1(identifier, nonce);
|
|
74
113
|
};
|
|
75
|
-
const getInboxIdForIdentifier = async (
|
|
76
|
-
|
|
77
|
-
const isSecure = host.startsWith("https");
|
|
78
|
-
return getInboxIdForIdentifier$1(host, gatewayHost, isSecure, identifier);
|
|
114
|
+
const getInboxIdForIdentifier = async (backend, identifier) => {
|
|
115
|
+
return getInboxIdByIdentity(backend, identifier);
|
|
79
116
|
};
|
|
80
117
|
|
|
81
118
|
function isHexString(value) {
|
|
@@ -709,7 +746,7 @@ class Conversation {
|
|
|
709
746
|
* @returns The HMAC keys for this conversation
|
|
710
747
|
*/
|
|
711
748
|
hmacKeys() {
|
|
712
|
-
return this.#conversation.
|
|
749
|
+
return this.#conversation.hmacKeys();
|
|
713
750
|
}
|
|
714
751
|
/**
|
|
715
752
|
* Gets the metadata for this conversation
|
|
@@ -922,7 +959,7 @@ class Conversation {
|
|
|
922
959
|
* @returns Promise that resolves with an array of decoded messages
|
|
923
960
|
*/
|
|
924
961
|
async messages(options) {
|
|
925
|
-
const messages = await this.#conversation.
|
|
962
|
+
const messages = await this.#conversation.listEnrichedMessages(options);
|
|
926
963
|
return messages.map((message) => new DecodedMessage(this.#codecRegistry, message));
|
|
927
964
|
}
|
|
928
965
|
/**
|
|
@@ -1016,7 +1053,7 @@ class Conversation {
|
|
|
1016
1053
|
* (nanoseconds since epoch)
|
|
1017
1054
|
*/
|
|
1018
1055
|
async lastReadTimes() {
|
|
1019
|
-
return this.#conversation.
|
|
1056
|
+
return this.#conversation.lastReadTimes();
|
|
1020
1057
|
}
|
|
1021
1058
|
}
|
|
1022
1059
|
|
|
@@ -1051,7 +1088,7 @@ class Dm extends Conversation {
|
|
|
1051
1088
|
return this.#conversation.dmPeerInboxId();
|
|
1052
1089
|
}
|
|
1053
1090
|
async duplicateDms() {
|
|
1054
|
-
const duplicateDms = await this.#conversation.
|
|
1091
|
+
const duplicateDms = await this.#conversation.duplicateDms();
|
|
1055
1092
|
return duplicateDms.map((dm) => new Dm(this.#client, this.#codecRegistry, dm));
|
|
1056
1093
|
}
|
|
1057
1094
|
}
|
|
@@ -1154,13 +1191,13 @@ class Group extends Conversation {
|
|
|
1154
1191
|
* The list of admins of the group
|
|
1155
1192
|
*/
|
|
1156
1193
|
listAdmins() {
|
|
1157
|
-
return this.#conversation.
|
|
1194
|
+
return this.#conversation.listAdmins();
|
|
1158
1195
|
}
|
|
1159
1196
|
/**
|
|
1160
1197
|
* The list of super admins of the group
|
|
1161
1198
|
*/
|
|
1162
1199
|
listSuperAdmins() {
|
|
1163
|
-
return this.#conversation.
|
|
1200
|
+
return this.#conversation.listSuperAdmins();
|
|
1164
1201
|
}
|
|
1165
1202
|
/**
|
|
1166
1203
|
* Checks if an inbox is an admin of the group
|
|
@@ -1186,7 +1223,7 @@ class Group extends Conversation {
|
|
|
1186
1223
|
* @param identifiers Array of member identifiers to add
|
|
1187
1224
|
*/
|
|
1188
1225
|
async addMembersByIdentifiers(identifiers) {
|
|
1189
|
-
return this.#conversation.
|
|
1226
|
+
return this.#conversation.addMembersByIdentity(identifiers);
|
|
1190
1227
|
}
|
|
1191
1228
|
/**
|
|
1192
1229
|
* Adds members to the group using inbox IDs
|
|
@@ -1194,7 +1231,7 @@ class Group extends Conversation {
|
|
|
1194
1231
|
* @param inboxIds Array of inbox IDs to add
|
|
1195
1232
|
*/
|
|
1196
1233
|
async addMembers(inboxIds) {
|
|
1197
|
-
return this.#conversation.
|
|
1234
|
+
return this.#conversation.addMembers(inboxIds);
|
|
1198
1235
|
}
|
|
1199
1236
|
/**
|
|
1200
1237
|
* Removes members from the group using identifiers
|
|
@@ -1202,7 +1239,7 @@ class Group extends Conversation {
|
|
|
1202
1239
|
* @param identifiers Array of member identifiers to remove
|
|
1203
1240
|
*/
|
|
1204
1241
|
async removeMembersByIdentifiers(identifiers) {
|
|
1205
|
-
return this.#conversation.
|
|
1242
|
+
return this.#conversation.removeMembersByIdentity(identifiers);
|
|
1206
1243
|
}
|
|
1207
1244
|
/**
|
|
1208
1245
|
* Removes members from the group using inbox IDs
|
|
@@ -1210,7 +1247,7 @@ class Group extends Conversation {
|
|
|
1210
1247
|
* @param inboxIds Array of inbox IDs to remove
|
|
1211
1248
|
*/
|
|
1212
1249
|
async removeMembers(inboxIds) {
|
|
1213
|
-
return this.#conversation.
|
|
1250
|
+
return this.#conversation.removeMembers(inboxIds);
|
|
1214
1251
|
}
|
|
1215
1252
|
/**
|
|
1216
1253
|
* Promotes a group member to admin status
|
|
@@ -1294,8 +1331,8 @@ class Conversations {
|
|
|
1294
1331
|
*/
|
|
1295
1332
|
async getConversationById(id) {
|
|
1296
1333
|
try {
|
|
1297
|
-
//
|
|
1298
|
-
const group = this.#conversations.
|
|
1334
|
+
// getConversationById will throw if group is not found
|
|
1335
|
+
const group = this.#conversations.getConversationById(id);
|
|
1299
1336
|
const metadata = await group.groupMetadata();
|
|
1300
1337
|
switch (metadata.conversationType()) {
|
|
1301
1338
|
case 1 /* ConversationType.Group */:
|
|
@@ -1319,8 +1356,8 @@ class Conversations {
|
|
|
1319
1356
|
*/
|
|
1320
1357
|
getDmByInboxId(inboxId) {
|
|
1321
1358
|
try {
|
|
1322
|
-
//
|
|
1323
|
-
const group = this.#conversations.
|
|
1359
|
+
// getDmByInboxId will throw if group is not found
|
|
1360
|
+
const group = this.#conversations.getDmByInboxId(inboxId);
|
|
1324
1361
|
return new Dm(this.#client, this.#codecRegistry, group);
|
|
1325
1362
|
}
|
|
1326
1363
|
catch {
|
|
@@ -1350,8 +1387,8 @@ class Conversations {
|
|
|
1350
1387
|
*/
|
|
1351
1388
|
getMessageById(id) {
|
|
1352
1389
|
try {
|
|
1353
|
-
//
|
|
1354
|
-
const message = this.#conversations.
|
|
1390
|
+
// getEnrichedMessageById will throw if message is not found
|
|
1391
|
+
const message = this.#conversations.getEnrichedMessageById(id);
|
|
1355
1392
|
return new DecodedMessage(this.#codecRegistry, message);
|
|
1356
1393
|
}
|
|
1357
1394
|
catch {
|
|
@@ -1378,7 +1415,7 @@ class Conversations {
|
|
|
1378
1415
|
* @see https://docs.xmtp.org/chat-apps/core-messaging/create-conversations#create-a-new-group-chat
|
|
1379
1416
|
*/
|
|
1380
1417
|
async createGroupWithIdentifiers(identifiers, options) {
|
|
1381
|
-
const group = await this.#conversations.
|
|
1418
|
+
const group = await this.#conversations.createGroupByIdentity(identifiers, options);
|
|
1382
1419
|
const conversation = new Group(this.#client, this.#codecRegistry, group);
|
|
1383
1420
|
return conversation;
|
|
1384
1421
|
}
|
|
@@ -1391,7 +1428,7 @@ class Conversations {
|
|
|
1391
1428
|
* @see https://docs.xmtp.org/chat-apps/core-messaging/create-conversations#create-a-new-group-chat
|
|
1392
1429
|
*/
|
|
1393
1430
|
async createGroup(inboxIds, options) {
|
|
1394
|
-
const group = await this.#conversations.
|
|
1431
|
+
const group = await this.#conversations.createGroup(inboxIds, options);
|
|
1395
1432
|
const conversation = new Group(this.#client, this.#codecRegistry, group);
|
|
1396
1433
|
return conversation;
|
|
1397
1434
|
}
|
|
@@ -1404,7 +1441,7 @@ class Conversations {
|
|
|
1404
1441
|
* @see https://docs.xmtp.org/agents/build-agents/create-conversations#by-ethereum-address-1
|
|
1405
1442
|
*/
|
|
1406
1443
|
async createDmWithIdentifier(identifier, options) {
|
|
1407
|
-
const group = await this.#conversations.
|
|
1444
|
+
const group = await this.#conversations.createDmByIdentity(identifier, options);
|
|
1408
1445
|
const conversation = new Dm(this.#client, this.#codecRegistry, group);
|
|
1409
1446
|
return conversation;
|
|
1410
1447
|
}
|
|
@@ -1417,7 +1454,7 @@ class Conversations {
|
|
|
1417
1454
|
* @see https://docs.xmtp.org/agents/build-agents/create-conversations#by-inbox-id-1
|
|
1418
1455
|
*/
|
|
1419
1456
|
async createDm(inboxId, options) {
|
|
1420
|
-
const group = await this.#conversations.
|
|
1457
|
+
const group = await this.#conversations.createDm(inboxId, options);
|
|
1421
1458
|
const conversation = new Dm(this.#client, this.#codecRegistry, group);
|
|
1422
1459
|
return conversation;
|
|
1423
1460
|
}
|
|
@@ -1496,7 +1533,7 @@ class Conversations {
|
|
|
1496
1533
|
* @see https://docs.xmtp.org/chat-apps/list-stream-sync/sync-and-syncall#sync-all-new-welcomes-conversations-messages-and-preferences
|
|
1497
1534
|
*/
|
|
1498
1535
|
async syncAll(consentStates) {
|
|
1499
|
-
return this.#conversations.
|
|
1536
|
+
return this.#conversations.syncAll(consentStates);
|
|
1500
1537
|
}
|
|
1501
1538
|
/**
|
|
1502
1539
|
* Creates a stream for new conversations
|
|
@@ -1664,7 +1701,7 @@ class Conversations {
|
|
|
1664
1701
|
* @see https://docs.xmtp.org/chat-apps/push-notifs/push-notifs#get-hmac-keys-for-a-conversation
|
|
1665
1702
|
*/
|
|
1666
1703
|
hmacKeys() {
|
|
1667
|
-
return this.#conversations.
|
|
1704
|
+
return this.#conversations.hmacKeys();
|
|
1668
1705
|
}
|
|
1669
1706
|
}
|
|
1670
1707
|
|
|
@@ -1711,7 +1748,7 @@ class Preferences {
|
|
|
1711
1748
|
this.#conversations = conversations;
|
|
1712
1749
|
}
|
|
1713
1750
|
sync() {
|
|
1714
|
-
return this.#
|
|
1751
|
+
return this.#conversations.syncPreferences();
|
|
1715
1752
|
}
|
|
1716
1753
|
/**
|
|
1717
1754
|
* Retrieves the current inbox state of this client from the local database
|
|
@@ -1737,7 +1774,7 @@ class Preferences {
|
|
|
1737
1774
|
* @returns Promise that resolves with the inbox states for the inbox IDs
|
|
1738
1775
|
*/
|
|
1739
1776
|
async getInboxStates(inboxIds) {
|
|
1740
|
-
return this.#client.
|
|
1777
|
+
return this.#client.fetchInboxStatesByInboxIds(inboxIds, false);
|
|
1741
1778
|
}
|
|
1742
1779
|
/**
|
|
1743
1780
|
* Retrieves the latest inbox states for specified inbox IDs from the network
|
|
@@ -1746,7 +1783,7 @@ class Preferences {
|
|
|
1746
1783
|
* @returns Promise that resolves with the inbox states for the inbox IDs
|
|
1747
1784
|
*/
|
|
1748
1785
|
async fetchInboxStates(inboxIds) {
|
|
1749
|
-
return this.#client.
|
|
1786
|
+
return this.#client.fetchInboxStatesByInboxIds(inboxIds, true);
|
|
1750
1787
|
}
|
|
1751
1788
|
/**
|
|
1752
1789
|
* Updates consent states for multiple records
|
|
@@ -1799,13 +1836,36 @@ class Preferences {
|
|
|
1799
1836
|
}
|
|
1800
1837
|
}
|
|
1801
1838
|
|
|
1839
|
+
const networkOptionKeys = [
|
|
1840
|
+
"env",
|
|
1841
|
+
"apiUrl",
|
|
1842
|
+
"gatewayHost",
|
|
1843
|
+
"appVersion",
|
|
1844
|
+
];
|
|
1845
|
+
const hasBackend = (options) => {
|
|
1846
|
+
return "backend" in options;
|
|
1847
|
+
};
|
|
1848
|
+
const resolveBackend$1 = async (options) => {
|
|
1849
|
+
if (!options) {
|
|
1850
|
+
return createBackend();
|
|
1851
|
+
}
|
|
1852
|
+
if (hasBackend(options)) {
|
|
1853
|
+
// Validate that no NetworkOptions fields are also set
|
|
1854
|
+
const conflicting = networkOptionKeys.filter((key) => key in options && options[key] != null);
|
|
1855
|
+
if (conflicting.length > 0) {
|
|
1856
|
+
throw new Error(`Cannot specify both 'backend' and network options (${conflicting.join(", ")}). ` +
|
|
1857
|
+
`Use either a pre-built Backend or network options, not both.`);
|
|
1858
|
+
}
|
|
1859
|
+
return options.backend;
|
|
1860
|
+
}
|
|
1861
|
+
// No backend provided — build one from NetworkOptions
|
|
1862
|
+
return createBackend(options);
|
|
1863
|
+
};
|
|
1802
1864
|
const createClient = async (identifier, options) => {
|
|
1803
|
-
const
|
|
1804
|
-
const
|
|
1805
|
-
const gatewayHost = options?.gatewayHost || undefined;
|
|
1806
|
-
const isSecure = host.startsWith("https");
|
|
1807
|
-
const inboxId = (await getInboxIdForIdentifier(identifier, env, gatewayHost)) ||
|
|
1865
|
+
const backend = await resolveBackend$1(options);
|
|
1866
|
+
const inboxId = (await getInboxIdForIdentifier(backend, identifier)) ||
|
|
1808
1867
|
generateInboxId(identifier, options?.nonce);
|
|
1868
|
+
const env = envToString(backend.env);
|
|
1809
1869
|
let dbPath;
|
|
1810
1870
|
if (options?.dbPath === undefined) {
|
|
1811
1871
|
// Default: auto-generated path
|
|
@@ -1823,18 +1883,43 @@ const createClient = async (identifier, options) => {
|
|
|
1823
1883
|
structured: options?.structuredLogging ?? false,
|
|
1824
1884
|
level: options?.loggingLevel ?? "Off" /* LogLevel.Off */,
|
|
1825
1885
|
};
|
|
1826
|
-
const historySyncUrl = options?.historySyncUrl === undefined
|
|
1827
|
-
? HistorySyncUrls[env]
|
|
1828
|
-
: options.historySyncUrl;
|
|
1829
1886
|
const deviceSyncWorkerMode = options?.disableDeviceSync
|
|
1830
1887
|
? "Disabled" /* SyncWorkerMode.Disabled */
|
|
1831
1888
|
: "Enabled" /* SyncWorkerMode.Enabled */;
|
|
1832
1889
|
const dbEncryptionKey = isHexString(options?.dbEncryptionKey)
|
|
1833
1890
|
? Buffer.from(options.dbEncryptionKey.replace(/^0x/, ""), "hex")
|
|
1834
1891
|
: options?.dbEncryptionKey;
|
|
1835
|
-
|
|
1892
|
+
const client = await createClientWithBackend(backend, {
|
|
1893
|
+
dbPath: dbPath ?? undefined,
|
|
1894
|
+
encryptionKey: dbEncryptionKey,
|
|
1895
|
+
}, inboxId, identifier, deviceSyncWorkerMode, logOptions, undefined, // allowOffline
|
|
1896
|
+
options?.nonce);
|
|
1897
|
+
return { client, env };
|
|
1836
1898
|
};
|
|
1837
1899
|
|
|
1900
|
+
/**
|
|
1901
|
+
* Resolves a `Backend` instance from either a `Backend` or an `XmtpEnv` string.
|
|
1902
|
+
*
|
|
1903
|
+
* @param envOrBackend - A `Backend` instance, or an `XmtpEnv` string
|
|
1904
|
+
* @param gatewayHost - Optional gateway host (only used when `envOrBackend` is an `XmtpEnv`)
|
|
1905
|
+
* @returns A `Backend` instance
|
|
1906
|
+
*/
|
|
1907
|
+
const resolveBackend = async (envOrBackend, gatewayHost) => {
|
|
1908
|
+
if (envOrBackend instanceof Backend) {
|
|
1909
|
+
return envOrBackend;
|
|
1910
|
+
}
|
|
1911
|
+
return createBackend({ env: envOrBackend, gatewayHost });
|
|
1912
|
+
};
|
|
1913
|
+
const createEphemeralIdentifier = () => ({
|
|
1914
|
+
identifier: `0x${randomBytes(20).toString("hex")}`,
|
|
1915
|
+
identifierKind: 0 /* IdentifierKind.Ethereum */,
|
|
1916
|
+
});
|
|
1917
|
+
const toInboxUpdatesCountMap = (value) => {
|
|
1918
|
+
if (value instanceof Map) {
|
|
1919
|
+
return value;
|
|
1920
|
+
}
|
|
1921
|
+
return new Map(Object.entries(value));
|
|
1922
|
+
};
|
|
1838
1923
|
/**
|
|
1839
1924
|
* Client for interacting with the XMTP network
|
|
1840
1925
|
*/
|
|
@@ -1843,6 +1928,7 @@ class Client {
|
|
|
1843
1928
|
#codecRegistry;
|
|
1844
1929
|
#conversations;
|
|
1845
1930
|
#debugInformation;
|
|
1931
|
+
#env;
|
|
1846
1932
|
#preferences;
|
|
1847
1933
|
#signer;
|
|
1848
1934
|
#identifier;
|
|
@@ -1872,7 +1958,9 @@ class Client {
|
|
|
1872
1958
|
return;
|
|
1873
1959
|
}
|
|
1874
1960
|
this.#identifier = identifier;
|
|
1875
|
-
|
|
1961
|
+
const { client, env } = await createClient(identifier, this.#options);
|
|
1962
|
+
this.#client = client;
|
|
1963
|
+
this.#env = env;
|
|
1876
1964
|
const conversations = this.#client.conversations();
|
|
1877
1965
|
this.#conversations = new Conversations(this, this.#codecRegistry, conversations);
|
|
1878
1966
|
this.#debugInformation = new DebugInformation(this.#client);
|
|
@@ -1925,6 +2013,17 @@ class Client {
|
|
|
1925
2013
|
get appVersion() {
|
|
1926
2014
|
return this.#client?.appVersion();
|
|
1927
2015
|
}
|
|
2016
|
+
/**
|
|
2017
|
+
* Gets the XMTP environment the client is connected to
|
|
2018
|
+
*
|
|
2019
|
+
* @throws {ClientNotInitializedError} if the client is not initialized
|
|
2020
|
+
*/
|
|
2021
|
+
get env() {
|
|
2022
|
+
if (!this.#env) {
|
|
2023
|
+
throw new ClientNotInitializedError();
|
|
2024
|
+
}
|
|
2025
|
+
return this.#env;
|
|
2026
|
+
}
|
|
1928
2027
|
/**
|
|
1929
2028
|
* Gets the client options
|
|
1930
2029
|
*/
|
|
@@ -2206,7 +2305,7 @@ class Client {
|
|
|
2206
2305
|
return;
|
|
2207
2306
|
}
|
|
2208
2307
|
await this.unsafe_addSignature(signatureRequest);
|
|
2209
|
-
await this.#client?.registerIdentity(signatureRequest);
|
|
2308
|
+
await this.#client?.registerIdentity(signatureRequest, this.#options?.waitForRegistrationVisible);
|
|
2210
2309
|
}
|
|
2211
2310
|
/**
|
|
2212
2311
|
* Adds a new account to the client inbox
|
|
@@ -2282,18 +2381,10 @@ class Client {
|
|
|
2282
2381
|
await this.unsafe_addSignature(signatureRequest);
|
|
2283
2382
|
await this.unsafe_applySignatureRequest(signatureRequest);
|
|
2284
2383
|
}
|
|
2285
|
-
|
|
2286
|
-
|
|
2287
|
-
*
|
|
2288
|
-
* @param env - The environment to use
|
|
2289
|
-
* @param signer - The signer to use
|
|
2290
|
-
* @param inboxId - The inbox ID to revoke installations for
|
|
2291
|
-
* @param installationIds - The installation IDs to revoke
|
|
2292
|
-
*/
|
|
2293
|
-
static async revokeInstallations(signer, inboxId, installationIds, env, gatewayHost) {
|
|
2294
|
-
const host = ApiUrls[env ?? "dev"];
|
|
2384
|
+
static async revokeInstallations(signer, inboxId, installationIds, envOrBackend, gatewayHost) {
|
|
2385
|
+
const backend = await resolveBackend(envOrBackend, gatewayHost);
|
|
2295
2386
|
const identifier = await signer.getIdentifier();
|
|
2296
|
-
const signatureRequest = await revokeInstallationsSignatureRequest(
|
|
2387
|
+
const signatureRequest = await revokeInstallationsSignatureRequest(backend, identifier, inboxId, installationIds);
|
|
2297
2388
|
const signatureText = await signatureRequest.signatureText();
|
|
2298
2389
|
const signature = await signer.signMessage(signatureText);
|
|
2299
2390
|
switch (signer.type) {
|
|
@@ -2304,7 +2395,7 @@ class Client {
|
|
|
2304
2395
|
await signatureRequest.addEcdsaSignature(signature);
|
|
2305
2396
|
break;
|
|
2306
2397
|
}
|
|
2307
|
-
await applySignatureRequest(
|
|
2398
|
+
await applySignatureRequest(backend, signatureRequest);
|
|
2308
2399
|
}
|
|
2309
2400
|
/**
|
|
2310
2401
|
* Changes the recovery identifier for the client's inbox
|
|
@@ -2334,6 +2425,34 @@ class Client {
|
|
|
2334
2425
|
const canMessage = await this.#client.canMessage(identifiers);
|
|
2335
2426
|
return new Map(Object.entries(canMessage));
|
|
2336
2427
|
}
|
|
2428
|
+
/**
|
|
2429
|
+
* Fetches the latest inbox updates count for the specified inbox IDs
|
|
2430
|
+
*
|
|
2431
|
+
* @param inboxIds - The inbox IDs to check
|
|
2432
|
+
* @param refreshFromNetwork - Whether to refresh from the network
|
|
2433
|
+
* @returns Map of inbox IDs to their updates count
|
|
2434
|
+
* @throws {ClientNotInitializedError} if the client is not initialized
|
|
2435
|
+
*/
|
|
2436
|
+
async fetchLatestInboxUpdatesCount(inboxIds, _refreshFromNetwork = true) {
|
|
2437
|
+
if (!this.#client) {
|
|
2438
|
+
throw new ClientNotInitializedError();
|
|
2439
|
+
}
|
|
2440
|
+
const result = await this.#client.fetchInboxUpdatesCount(inboxIds, true);
|
|
2441
|
+
return toInboxUpdatesCountMap(result);
|
|
2442
|
+
}
|
|
2443
|
+
/**
|
|
2444
|
+
* Fetches the latest inbox updates count for the client's inbox
|
|
2445
|
+
*
|
|
2446
|
+
* @param refreshFromNetwork - Whether to refresh from the network
|
|
2447
|
+
* @returns The latest inbox updates count
|
|
2448
|
+
* @throws {ClientNotInitializedError} if the client is not initialized
|
|
2449
|
+
*/
|
|
2450
|
+
async fetchOwnInboxUpdatesCount(_refreshFromNetwork = true) {
|
|
2451
|
+
if (!this.#client) {
|
|
2452
|
+
throw new ClientNotInitializedError();
|
|
2453
|
+
}
|
|
2454
|
+
return this.#client.fetchOwnInboxUpdatesCount(true);
|
|
2455
|
+
}
|
|
2337
2456
|
/**
|
|
2338
2457
|
* Fetches the key package statuses from the network for the specified
|
|
2339
2458
|
* installation IDs
|
|
@@ -2346,7 +2465,7 @@ class Client {
|
|
|
2346
2465
|
if (!this.#client) {
|
|
2347
2466
|
throw new ClientNotInitializedError();
|
|
2348
2467
|
}
|
|
2349
|
-
return this.#client.
|
|
2468
|
+
return this.#client.fetchKeyPackageStatusesByInstallationIds(installationIds);
|
|
2350
2469
|
}
|
|
2351
2470
|
/**
|
|
2352
2471
|
* Fetches the inbox ID for a given identifier from the local database
|
|
@@ -2360,7 +2479,7 @@ class Client {
|
|
|
2360
2479
|
if (!this.#client) {
|
|
2361
2480
|
throw new ClientNotInitializedError();
|
|
2362
2481
|
}
|
|
2363
|
-
return this.#client.
|
|
2482
|
+
return this.#client.getInboxIdByIdentity(identifier);
|
|
2364
2483
|
}
|
|
2365
2484
|
/**
|
|
2366
2485
|
* Signs a message with the installation key
|
|
@@ -2395,29 +2514,29 @@ class Client {
|
|
|
2395
2514
|
return false;
|
|
2396
2515
|
}
|
|
2397
2516
|
}
|
|
2398
|
-
|
|
2399
|
-
|
|
2400
|
-
|
|
2401
|
-
*
|
|
2402
|
-
* @param env - The environment to use
|
|
2403
|
-
* @param inboxIds - The inbox IDs to get the state for
|
|
2404
|
-
* @returns The inbox states for the specified inbox IDs
|
|
2405
|
-
*/
|
|
2406
|
-
static async fetchInboxStates(inboxIds, env, gatewayHost) {
|
|
2407
|
-
const host = ApiUrls[env ?? "dev"];
|
|
2408
|
-
return inboxStateFromInboxIds(host, gatewayHost, inboxIds);
|
|
2517
|
+
static async fetchInboxStates(inboxIds, envOrBackend, gatewayHost) {
|
|
2518
|
+
const backend = await resolveBackend(envOrBackend, gatewayHost);
|
|
2519
|
+
return fetchInboxStatesByInboxIds(backend, inboxIds);
|
|
2409
2520
|
}
|
|
2410
|
-
|
|
2411
|
-
|
|
2412
|
-
|
|
2413
|
-
|
|
2414
|
-
|
|
2415
|
-
|
|
2416
|
-
|
|
2417
|
-
|
|
2521
|
+
static async fetchLatestInboxUpdatesCount(inboxIds, envOrBackend, gatewayHostOrRefresh, _refreshFromNetwork = true) {
|
|
2522
|
+
const gatewayHost = typeof gatewayHostOrRefresh === "string"
|
|
2523
|
+
? gatewayHostOrRefresh
|
|
2524
|
+
: undefined;
|
|
2525
|
+
const backend = await resolveBackend(envOrBackend, gatewayHost);
|
|
2526
|
+
const { client } = await createClient(createEphemeralIdentifier(), {
|
|
2527
|
+
backend,
|
|
2528
|
+
dbPath: null,
|
|
2529
|
+
disableDeviceSync: true,
|
|
2530
|
+
});
|
|
2531
|
+
const result = await client.fetchInboxUpdatesCount(inboxIds, true);
|
|
2532
|
+
return toInboxUpdatesCountMap(result);
|
|
2533
|
+
}
|
|
2534
|
+
/* eslint-enable @typescript-eslint/unified-signatures */
|
|
2535
|
+
static async canMessage(identifiers, envOrBackend) {
|
|
2536
|
+
const backend = await resolveBackend(envOrBackend);
|
|
2418
2537
|
const canMessageMap = new Map();
|
|
2419
2538
|
for (const identifier of identifiers) {
|
|
2420
|
-
const inboxId = await getInboxIdForIdentifier(
|
|
2539
|
+
const inboxId = await getInboxIdForIdentifier(backend, identifier);
|
|
2421
2540
|
canMessageMap.set(identifier.identifier.toLowerCase(), inboxId !== null);
|
|
2422
2541
|
}
|
|
2423
2542
|
return canMessageMap;
|
|
@@ -2439,42 +2558,150 @@ class Client {
|
|
|
2439
2558
|
return false;
|
|
2440
2559
|
}
|
|
2441
2560
|
}
|
|
2561
|
+
static async isAddressAuthorized(inboxId, address, envOrBackend, gatewayHost) {
|
|
2562
|
+
const backend = await resolveBackend(envOrBackend, gatewayHost);
|
|
2563
|
+
return await isAddressAuthorized(backend, inboxId, address);
|
|
2564
|
+
}
|
|
2565
|
+
static async isInstallationAuthorized(inboxId, installation, envOrBackend, gatewayHost) {
|
|
2566
|
+
const backend = await resolveBackend(envOrBackend, gatewayHost);
|
|
2567
|
+
return await isInstallationAuthorized(backend, inboxId, installation);
|
|
2568
|
+
}
|
|
2569
|
+
/**
|
|
2570
|
+
* Get the default archive options (consent and messages)
|
|
2571
|
+
*/
|
|
2572
|
+
#getDefaultArchiveOptions() {
|
|
2573
|
+
return {
|
|
2574
|
+
elements: [
|
|
2575
|
+
"Consent" /* BackupElementSelectionOption.Consent */,
|
|
2576
|
+
"Messages" /* BackupElementSelectionOption.Messages */,
|
|
2577
|
+
],
|
|
2578
|
+
excludeDisappearingMessages: false,
|
|
2579
|
+
};
|
|
2580
|
+
}
|
|
2581
|
+
/**
|
|
2582
|
+
* Get the default server URL based on the environment
|
|
2583
|
+
*/
|
|
2584
|
+
#getDefaultServerUrl() {
|
|
2585
|
+
const env = this.env;
|
|
2586
|
+
return HistorySyncUrls[env];
|
|
2587
|
+
}
|
|
2588
|
+
/**
|
|
2589
|
+
* Send a sync request to other devices on the network
|
|
2590
|
+
*
|
|
2591
|
+
* @param options - Archive options specifying what to sync (defaults to consent and messages)
|
|
2592
|
+
* @param serverUrl - The server URL for the sync request (defaults to environment-specific URL)
|
|
2593
|
+
* @returns Promise that resolves when the sync request is sent
|
|
2594
|
+
*/
|
|
2595
|
+
async sendSyncRequest(options, serverUrl) {
|
|
2596
|
+
if (!this.#client) {
|
|
2597
|
+
throw new ClientNotInitializedError();
|
|
2598
|
+
}
|
|
2599
|
+
const resolvedOptions = options ?? this.#getDefaultArchiveOptions();
|
|
2600
|
+
const resolvedServerUrl = serverUrl ?? this.#getDefaultServerUrl();
|
|
2601
|
+
return this.#client
|
|
2602
|
+
.deviceSync()
|
|
2603
|
+
.sendSyncRequest(resolvedOptions, resolvedServerUrl);
|
|
2604
|
+
}
|
|
2442
2605
|
/**
|
|
2443
|
-
*
|
|
2606
|
+
* Send a sync archive to the sync group
|
|
2444
2607
|
*
|
|
2445
|
-
* @param
|
|
2446
|
-
* @param
|
|
2447
|
-
* @param
|
|
2448
|
-
* @returns
|
|
2608
|
+
* @param pin - The pin used for reference when importing
|
|
2609
|
+
* @param options - Archive options specifying what to sync (defaults to consent and messages)
|
|
2610
|
+
* @param serverUrl - The server URL for the sync archive (defaults to environment-specific URL)
|
|
2611
|
+
* @returns Promise that resolves when the sync archive is sent
|
|
2449
2612
|
*/
|
|
2450
|
-
|
|
2451
|
-
|
|
2452
|
-
|
|
2613
|
+
async sendSyncArchive(pin, options, serverUrl) {
|
|
2614
|
+
if (!this.#client) {
|
|
2615
|
+
throw new ClientNotInitializedError();
|
|
2616
|
+
}
|
|
2617
|
+
const resolvedOptions = options ?? this.#getDefaultArchiveOptions();
|
|
2618
|
+
const resolvedServerUrl = serverUrl ?? this.#getDefaultServerUrl();
|
|
2619
|
+
return this.#client
|
|
2620
|
+
.deviceSync()
|
|
2621
|
+
.sendSyncArchive(resolvedOptions, resolvedServerUrl, pin);
|
|
2453
2622
|
}
|
|
2454
2623
|
/**
|
|
2455
|
-
*
|
|
2624
|
+
* Process a sync archive that matches the pin given
|
|
2456
2625
|
*
|
|
2457
|
-
* @param
|
|
2458
|
-
* @
|
|
2459
|
-
* @param options - Optional network options
|
|
2460
|
-
* @returns Whether the installation is authorized
|
|
2626
|
+
* @param archivePin - Optional pin to match. If not provided, processes the last archive sent
|
|
2627
|
+
* @returns Promise that resolves when the archive is processed
|
|
2461
2628
|
*/
|
|
2462
|
-
|
|
2463
|
-
|
|
2464
|
-
|
|
2629
|
+
async processSyncArchive(archivePin) {
|
|
2630
|
+
if (!this.#client) {
|
|
2631
|
+
throw new ClientNotInitializedError();
|
|
2632
|
+
}
|
|
2633
|
+
return this.#client.deviceSync().processSyncArchive(archivePin);
|
|
2465
2634
|
}
|
|
2466
2635
|
/**
|
|
2467
|
-
*
|
|
2636
|
+
* List the archives available for import in the sync group
|
|
2468
2637
|
*
|
|
2469
|
-
*
|
|
2638
|
+
* You may need to manually sync the sync group before calling
|
|
2639
|
+
* this function to see recently uploaded archives.
|
|
2640
|
+
*
|
|
2641
|
+
* @param daysCutoff - Number of days to look back for archives
|
|
2642
|
+
* @returns Array of available archive information
|
|
2643
|
+
*/
|
|
2644
|
+
listAvailableArchives(daysCutoff) {
|
|
2645
|
+
if (!this.#client) {
|
|
2646
|
+
throw new ClientNotInitializedError();
|
|
2647
|
+
}
|
|
2648
|
+
return this.#client.deviceSync().listAvailableArchives(daysCutoff);
|
|
2649
|
+
}
|
|
2650
|
+
/**
|
|
2651
|
+
* Archive application elements to file for later restoration
|
|
2652
|
+
*
|
|
2653
|
+
* @param path - The file path to save the archive
|
|
2654
|
+
* @param key - Encryption key for the archive
|
|
2655
|
+
* @param opts - Archive options specifying what to include (defaults to consent and messages)
|
|
2656
|
+
* @returns Promise that resolves when the archive is created
|
|
2657
|
+
*/
|
|
2658
|
+
async createArchive(path, key, opts) {
|
|
2659
|
+
if (!this.#client) {
|
|
2660
|
+
throw new ClientNotInitializedError();
|
|
2661
|
+
}
|
|
2662
|
+
const resolvedOpts = opts ?? this.#getDefaultArchiveOptions();
|
|
2663
|
+
return this.#client.deviceSync().createArchive(path, resolvedOpts, key);
|
|
2664
|
+
}
|
|
2665
|
+
/**
|
|
2666
|
+
* Import a previous archive from a file
|
|
2667
|
+
*
|
|
2668
|
+
* @param path - The file path to the archive
|
|
2669
|
+
* @param key - Encryption key for the archive
|
|
2670
|
+
* @returns Promise that resolves when the archive is imported
|
|
2671
|
+
*/
|
|
2672
|
+
async importArchive(path, key) {
|
|
2673
|
+
if (!this.#client) {
|
|
2674
|
+
throw new ClientNotInitializedError();
|
|
2675
|
+
}
|
|
2676
|
+
return this.#client.deviceSync().importArchive(path, key);
|
|
2677
|
+
}
|
|
2678
|
+
/**
|
|
2679
|
+
* Load the metadata for an archive to see what it contains
|
|
2680
|
+
*
|
|
2681
|
+
* Reads only the metadata without loading the entire file, so this function is quick.
|
|
2682
|
+
*
|
|
2683
|
+
* @param path - The file path to the archive
|
|
2684
|
+
* @param key - Encryption key for the archive
|
|
2685
|
+
* @returns Promise that resolves with the archive metadata
|
|
2686
|
+
*/
|
|
2687
|
+
async archiveMetadata(path, key) {
|
|
2688
|
+
if (!this.#client) {
|
|
2689
|
+
throw new ClientNotInitializedError();
|
|
2690
|
+
}
|
|
2691
|
+
return this.#client.deviceSync().archiveMetadata(path, key);
|
|
2692
|
+
}
|
|
2693
|
+
/**
|
|
2694
|
+
* Manually sync all device sync groups
|
|
2695
|
+
*
|
|
2696
|
+
* @returns Promise that resolves with a summary of the sync operation
|
|
2470
2697
|
*/
|
|
2471
|
-
async
|
|
2698
|
+
async syncAllDeviceSyncGroups() {
|
|
2472
2699
|
if (!this.#client) {
|
|
2473
2700
|
throw new ClientNotInitializedError();
|
|
2474
2701
|
}
|
|
2475
|
-
return this.#client.
|
|
2702
|
+
return this.#client.deviceSync().syncAllDeviceSyncGroups();
|
|
2476
2703
|
}
|
|
2477
2704
|
}
|
|
2478
2705
|
|
|
2479
|
-
export { AccountAlreadyAssociatedError, ApiUrls, Client, ClientNotInitializedError, Conversation, Conversations, DecodedMessage, Dm, Group, HistorySyncUrls, InboxReassignError, MissingContentTypeError, SignerUnavailableError, StreamFailedError, StreamInvalidRetryAttemptsError, generateInboxId, getInboxIdForIdentifier, isActions, isAttachment, isGroupUpdated, isHexString, isIntent, isLeaveRequest, isMarkdown, isMultiRemoteAttachment, isReaction, isReadReceipt, isRemoteAttachment, isReply, isText, isTextReply, isTransactionReference, isWalletSendCalls, validHex };
|
|
2706
|
+
export { AccountAlreadyAssociatedError, ApiUrls, Client, ClientNotInitializedError, Conversation, Conversations, DecodedMessage, Dm, Group, HistorySyncUrls, InboxReassignError, MissingContentTypeError, SignerUnavailableError, StreamFailedError, StreamInvalidRetryAttemptsError, createBackend, envToString, generateInboxId, getInboxIdForIdentifier, isActions, isAttachment, isGroupUpdated, isHexString, isIntent, isLeaveRequest, isMarkdown, isMultiRemoteAttachment, isReaction, isReadReceipt, isRemoteAttachment, isReply, isText, isTextReply, isTransactionReference, isWalletSendCalls, validHex };
|
|
2480
2707
|
//# sourceMappingURL=index.js.map
|