@unicitylabs/sphere-sdk 0.4.6 → 0.4.7

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.cjs CHANGED
@@ -8517,10 +8517,12 @@ var GroupChatModule = class {
8517
8517
  if (!this.client) return;
8518
8518
  const groupIds = Array.from(this.groups.keys());
8519
8519
  if (groupIds.length === 0) return;
8520
+ const latestTimestamp = this.getLatestMessageTimestamp(groupIds);
8520
8521
  this.trackSubscription(
8521
8522
  createNip29Filter({
8522
8523
  kinds: [NIP29_KINDS.CHAT_MESSAGE, NIP29_KINDS.THREAD_ROOT, NIP29_KINDS.THREAD_REPLY],
8523
- "#h": groupIds
8524
+ "#h": groupIds,
8525
+ ...latestTimestamp ? { since: latestTimestamp } : {}
8524
8526
  }),
8525
8527
  { onEvent: (event) => this.handleGroupEvent(event) }
8526
8528
  );
@@ -8541,10 +8543,12 @@ var GroupChatModule = class {
8541
8543
  }
8542
8544
  subscribeToGroup(groupId) {
8543
8545
  if (!this.client) return;
8546
+ const latestTimestamp = this.getLatestMessageTimestamp([groupId]);
8544
8547
  this.trackSubscription(
8545
8548
  createNip29Filter({
8546
8549
  kinds: [NIP29_KINDS.CHAT_MESSAGE, NIP29_KINDS.THREAD_ROOT, NIP29_KINDS.THREAD_REPLY],
8547
- "#h": [groupId]
8550
+ "#h": [groupId],
8551
+ ...latestTimestamp ? { since: latestTimestamp } : {}
8548
8552
  }),
8549
8553
  { onEvent: (event) => this.handleGroupEvent(event) }
8550
8554
  );
@@ -9236,6 +9240,23 @@ var GroupChatModule = class {
9236
9240
  getMyPublicKey() {
9237
9241
  return this.keyManager?.getPublicKeyHex() || null;
9238
9242
  }
9243
+ /**
9244
+ * Returns the latest message timestamp (in Nostr seconds) across the given groups,
9245
+ * or 0 if no messages exist. Used to set `since` on subscriptions so the relay
9246
+ * only sends events we don't already have.
9247
+ */
9248
+ getLatestMessageTimestamp(groupIds) {
9249
+ let latest = 0;
9250
+ for (const gid of groupIds) {
9251
+ const msgs = this.messages.get(gid);
9252
+ if (!msgs) continue;
9253
+ for (const m of msgs) {
9254
+ const ts = Math.floor(m.timestamp / 1e3);
9255
+ if (ts > latest) latest = ts;
9256
+ }
9257
+ }
9258
+ return latest;
9259
+ }
9239
9260
  // ===========================================================================
9240
9261
  // Private — Relay Admin
9241
9262
  // ===========================================================================
@@ -13682,55 +13703,44 @@ var Sphere = class _Sphere {
13682
13703
  * ```
13683
13704
  */
13684
13705
  static async importFromJSON(options) {
13706
+ const { jsonContent, password, ...baseOptions } = options;
13685
13707
  try {
13686
- const data = JSON.parse(options.jsonContent);
13708
+ const data = JSON.parse(jsonContent);
13687
13709
  if (data.version !== "1.0" || data.type !== "sphere-wallet") {
13688
13710
  return { success: false, error: "Invalid wallet format" };
13689
13711
  }
13690
13712
  let mnemonic = data.mnemonic;
13691
13713
  let masterKey = data.wallet.masterPrivateKey;
13692
- if (data.encrypted && options.password) {
13714
+ if (data.encrypted && password) {
13693
13715
  if (mnemonic) {
13694
- const decrypted = decryptSimple(mnemonic, options.password);
13716
+ const decrypted = decryptSimple(mnemonic, password);
13695
13717
  if (!decrypted) {
13696
13718
  return { success: false, error: "Failed to decrypt mnemonic - wrong password?" };
13697
13719
  }
13698
13720
  mnemonic = decrypted;
13699
13721
  }
13700
13722
  if (masterKey) {
13701
- const decrypted = decryptSimple(masterKey, options.password);
13723
+ const decrypted = decryptSimple(masterKey, password);
13702
13724
  if (!decrypted) {
13703
13725
  return { success: false, error: "Failed to decrypt master key - wrong password?" };
13704
13726
  }
13705
13727
  masterKey = decrypted;
13706
13728
  }
13707
- } else if (data.encrypted && !options.password) {
13729
+ } else if (data.encrypted && !password) {
13708
13730
  return { success: false, error: "Password required for encrypted wallet" };
13709
13731
  }
13710
13732
  const basePath = data.wallet.descriptorPath ? `m/${data.wallet.descriptorPath}` : DEFAULT_BASE_PATH;
13711
13733
  if (mnemonic) {
13712
- await _Sphere.import({
13713
- mnemonic,
13714
- basePath,
13715
- storage: options.storage,
13716
- transport: options.transport,
13717
- oracle: options.oracle,
13718
- tokenStorage: options.tokenStorage,
13719
- l1: options.l1
13720
- });
13734
+ await _Sphere.import({ ...baseOptions, mnemonic, basePath });
13721
13735
  return { success: true, mnemonic };
13722
13736
  }
13723
13737
  if (masterKey) {
13724
13738
  await _Sphere.import({
13739
+ ...baseOptions,
13725
13740
  masterKey,
13726
13741
  chainCode: data.wallet.chainCode,
13727
13742
  basePath,
13728
- derivationMode: data.derivationMode || (data.wallet.isBIP32 ? "bip32" : "wif_hmac"),
13729
- storage: options.storage,
13730
- transport: options.transport,
13731
- oracle: options.oracle,
13732
- tokenStorage: options.tokenStorage,
13733
- l1: options.l1
13743
+ derivationMode: data.derivationMode || (data.wallet.isBIP32 ? "bip32" : "wif_hmac")
13734
13744
  });
13735
13745
  return { success: true };
13736
13746
  }
@@ -13773,7 +13783,7 @@ var Sphere = class _Sphere {
13773
13783
  * ```
13774
13784
  */
13775
13785
  static async importFromLegacyFile(options) {
13776
- const { fileContent, fileName, password, onDecryptProgress } = options;
13786
+ const { fileContent, fileName, password, onDecryptProgress, ...baseOptions } = options;
13777
13787
  const fileType = _Sphere.detectLegacyFileType(fileName, fileContent);
13778
13788
  if (fileType === "unknown") {
13779
13789
  return { success: false, error: "Unknown file format" };
@@ -13783,15 +13793,7 @@ var Sphere = class _Sphere {
13783
13793
  if (!_Sphere.validateMnemonic(mnemonic)) {
13784
13794
  return { success: false, error: "Invalid mnemonic phrase" };
13785
13795
  }
13786
- const sphere = await _Sphere.import({
13787
- mnemonic,
13788
- storage: options.storage,
13789
- transport: options.transport,
13790
- oracle: options.oracle,
13791
- tokenStorage: options.tokenStorage,
13792
- nametag: options.nametag,
13793
- l1: options.l1
13794
- });
13796
+ const sphere = await _Sphere.import({ ...baseOptions, mnemonic });
13795
13797
  return { success: true, sphere, mnemonic };
13796
13798
  }
13797
13799
  if (fileType === "dat") {
@@ -13811,16 +13813,11 @@ var Sphere = class _Sphere {
13811
13813
  const { masterKey, chainCode, descriptorPath, derivationMode } = parseResult.data;
13812
13814
  const basePath = descriptorPath ? `m/${descriptorPath}` : DEFAULT_BASE_PATH;
13813
13815
  const sphere = await _Sphere.import({
13816
+ ...baseOptions,
13814
13817
  masterKey,
13815
13818
  chainCode,
13816
13819
  basePath,
13817
- derivationMode: derivationMode || (chainCode ? "bip32" : "wif_hmac"),
13818
- storage: options.storage,
13819
- transport: options.transport,
13820
- oracle: options.oracle,
13821
- tokenStorage: options.tokenStorage,
13822
- nametag: options.nametag,
13823
- l1: options.l1
13820
+ derivationMode: derivationMode || (chainCode ? "bip32" : "wif_hmac")
13824
13821
  });
13825
13822
  return { success: true, sphere };
13826
13823
  }
@@ -13843,16 +13840,11 @@ var Sphere = class _Sphere {
13843
13840
  const { masterKey, chainCode, descriptorPath, derivationMode } = parseResult.data;
13844
13841
  const basePath = descriptorPath ? `m/${descriptorPath}` : DEFAULT_BASE_PATH;
13845
13842
  const sphere = await _Sphere.import({
13843
+ ...baseOptions,
13846
13844
  masterKey,
13847
13845
  chainCode,
13848
13846
  basePath,
13849
- derivationMode: derivationMode || (chainCode ? "bip32" : "wif_hmac"),
13850
- storage: options.storage,
13851
- transport: options.transport,
13852
- oracle: options.oracle,
13853
- tokenStorage: options.tokenStorage,
13854
- nametag: options.nametag,
13855
- l1: options.l1
13847
+ derivationMode: derivationMode || (chainCode ? "bip32" : "wif_hmac")
13856
13848
  });
13857
13849
  return { success: true, sphere };
13858
13850
  }
@@ -13866,13 +13858,9 @@ var Sphere = class _Sphere {
13866
13858
  }
13867
13859
  if (parsed.type === "sphere-wallet") {
13868
13860
  const result = await _Sphere.importFromJSON({
13861
+ ...baseOptions,
13869
13862
  jsonContent: content,
13870
- password,
13871
- storage: options.storage,
13872
- transport: options.transport,
13873
- oracle: options.oracle,
13874
- tokenStorage: options.tokenStorage,
13875
- l1: options.l1
13863
+ password
13876
13864
  });
13877
13865
  if (result.success) {
13878
13866
  const sphere2 = _Sphere.getInstance();
@@ -13914,29 +13902,15 @@ var Sphere = class _Sphere {
13914
13902
  const isBIP32 = derivationMode === "bip32" || !!chainCode;
13915
13903
  const basePath = descriptorPath ? `m/${descriptorPath}` : isBIP32 ? "m/84'/1'/0'" : DEFAULT_BASE_PATH;
13916
13904
  if (mnemonic) {
13917
- const sphere2 = await _Sphere.import({
13918
- mnemonic,
13919
- basePath,
13920
- storage: options.storage,
13921
- transport: options.transport,
13922
- oracle: options.oracle,
13923
- tokenStorage: options.tokenStorage,
13924
- nametag: options.nametag,
13925
- l1: options.l1
13926
- });
13905
+ const sphere2 = await _Sphere.import({ ...baseOptions, mnemonic, basePath });
13927
13906
  return { success: true, sphere: sphere2, mnemonic };
13928
13907
  }
13929
13908
  const sphere = await _Sphere.import({
13909
+ ...baseOptions,
13930
13910
  masterKey,
13931
13911
  chainCode,
13932
13912
  basePath,
13933
- derivationMode: derivationMode || (chainCode ? "bip32" : "wif_hmac"),
13934
- storage: options.storage,
13935
- transport: options.transport,
13936
- oracle: options.oracle,
13937
- tokenStorage: options.tokenStorage,
13938
- nametag: options.nametag,
13939
- l1: options.l1
13913
+ derivationMode: derivationMode || (chainCode ? "bip32" : "wif_hmac")
13940
13914
  });
13941
13915
  return { success: true, sphere };
13942
13916
  }