@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.js CHANGED
@@ -1,5 +1,6 @@
1
- import { generateInboxId as generateInboxId$1, getInboxIdForIdentifier as getInboxIdForIdentifier$1, contentTypeIntent, contentTypeActions, contentTypeWalletSendCalls, contentTypeLeaveRequest, contentTypeReadReceipt, contentTypeGroupUpdated, contentTypeTransactionReference, contentTypeMultiRemoteAttachment, contentTypeRemoteAttachment, contentTypeAttachment, contentTypeReaction, contentTypeReply, contentTypeMarkdown, contentTypeText, createClient as createClient$1, revokeInstallationsSignatureRequest, applySignatureRequest, inboxStateFromInboxIds, verifySignedWithPublicKey, isAddressAuthorized, isInstallationAuthorized } from '@xmtp/node-bindings';
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 (identifier, env = "dev", gatewayHost) => {
76
- const host = ApiUrls[env];
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.getHmacKeys();
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.findEnrichedMessages(options);
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.getLastReadTimes();
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.findDuplicateDms();
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.adminList();
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.superAdminList();
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.addMembers(identifiers);
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.addMembersByInboxId(inboxIds);
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.removeMembers(identifiers);
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.removeMembersByInboxId(inboxIds);
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
- // findGroupById will throw if group is not found
1298
- const group = this.#conversations.findGroupById(id);
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
- // findDmByTargetInboxId will throw if group is not found
1323
- const group = this.#conversations.findDmByTargetInboxId(inboxId);
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
- // findEnrichedMessageById will throw if message is not found
1354
- const message = this.#conversations.findEnrichedMessageById(id);
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.createGroup(identifiers, options);
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.createGroupByInboxId(inboxIds, options);
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.createDm(identifier, options);
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.createDmByInboxId(inboxId, options);
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.syncAllConversations(consentStates);
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.getHmacKeys();
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.#client.syncPreferences();
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.addressesFromInboxId(false, inboxIds);
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.addressesFromInboxId(true, inboxIds);
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 env = options?.env || "dev";
1804
- const host = options?.apiUrl || ApiUrls[env];
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
- return createClient$1(host, gatewayHost, isSecure, dbPath, inboxId, identifier, dbEncryptionKey, historySyncUrl, deviceSyncWorkerMode, logOptions, undefined, options?.appVersion);
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
- this.#client = await createClient(identifier, this.#options);
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
- * Revokes specific installations of the client's inbox without a client
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(host, gatewayHost, identifier, inboxId, installationIds);
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(host, gatewayHost, signatureRequest);
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.getKeyPackageStatusesForInstallationIds(installationIds);
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.findInboxIdByIdentifier(identifier);
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
- * Fetches the inbox states for the specified inbox IDs from the network
2400
- * without a client
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
- * Checks if the specified identifiers can be messaged
2412
- *
2413
- * @param identifiers - The identifiers to check
2414
- * @param env - Optional XMTP environment
2415
- * @returns Map of identifiers to whether they can be messaged
2416
- */
2417
- static async canMessage(identifiers, env) {
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(identifier, env);
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
- * Checks if an address is authorized for an inbox
2606
+ * Send a sync archive to the sync group
2444
2607
  *
2445
- * @param inboxId - The inbox ID to check
2446
- * @param address - The address to check
2447
- * @param options - Optional network options
2448
- * @returns Whether the address is authorized
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
- static async isAddressAuthorized(inboxId, address, env, gatewayHost) {
2451
- const host = ApiUrls[env ?? "dev"];
2452
- return await isAddressAuthorized(host, gatewayHost, inboxId, address);
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
- * Checks if an installation is authorized for an inbox
2624
+ * Process a sync archive that matches the pin given
2456
2625
  *
2457
- * @param inboxId - The inbox ID to check
2458
- * @param installation - The installation to check
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
- static async isInstallationAuthorized(inboxId, installation, env, gatewayHost) {
2463
- const host = ApiUrls[env ?? "dev"];
2464
- return await isInstallationAuthorized(host, gatewayHost, inboxId, installation);
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
- * Send a sync request to other devices on the network
2636
+ * List the archives available for import in the sync group
2468
2637
  *
2469
- * @returns Promise that resolves when the sync request is sent
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 sendSyncRequest() {
2698
+ async syncAllDeviceSyncGroups() {
2472
2699
  if (!this.#client) {
2473
2700
  throw new ClientNotInitializedError();
2474
2701
  }
2475
- return this.#client.sendSyncRequest();
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