@unicitylabs/sphere-sdk 0.4.4 → 0.4.6
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/connect/index.cjs +27 -10
- package/dist/connect/index.cjs.map +1 -1
- package/dist/connect/index.js +27 -10
- package/dist/connect/index.js.map +1 -1
- package/dist/core/index.cjs +72 -25
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.cts +12 -0
- package/dist/core/index.d.ts +12 -0
- package/dist/core/index.js +72 -25
- package/dist/core/index.js.map +1 -1
- package/dist/impl/browser/connect/index.cjs +10 -10
- package/dist/impl/browser/connect/index.cjs.map +1 -1
- package/dist/impl/browser/connect/index.js +10 -10
- package/dist/impl/browser/connect/index.js.map +1 -1
- package/dist/impl/browser/index.cjs +10 -10
- package/dist/impl/browser/index.cjs.map +1 -1
- package/dist/impl/browser/index.js +10 -10
- package/dist/impl/browser/index.js.map +1 -1
- package/dist/impl/browser/ipfs.cjs +10 -10
- package/dist/impl/browser/ipfs.cjs.map +1 -1
- package/dist/impl/browser/ipfs.js +10 -10
- package/dist/impl/browser/ipfs.js.map +1 -1
- package/dist/impl/nodejs/connect/index.cjs +10 -10
- package/dist/impl/nodejs/connect/index.cjs.map +1 -1
- package/dist/impl/nodejs/connect/index.js +10 -10
- package/dist/impl/nodejs/connect/index.js.map +1 -1
- package/dist/impl/nodejs/index.cjs +10 -10
- package/dist/impl/nodejs/index.cjs.map +1 -1
- package/dist/impl/nodejs/index.js +10 -10
- package/dist/impl/nodejs/index.js.map +1 -1
- package/dist/index.cjs +72 -25
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +30 -18
- package/dist/index.d.ts +30 -18
- package/dist/index.js +72 -25
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/core/index.d.cts
CHANGED
|
@@ -2621,6 +2621,7 @@ declare class CommunicationsModule {
|
|
|
2621
2621
|
private dmHandlers;
|
|
2622
2622
|
private composingHandlers;
|
|
2623
2623
|
private broadcastHandlers;
|
|
2624
|
+
private initializedAt;
|
|
2624
2625
|
constructor(config?: CommunicationsModuleConfig);
|
|
2625
2626
|
/**
|
|
2626
2627
|
* Initialize module with dependencies
|
|
@@ -2699,6 +2700,12 @@ declare class CommunicationsModule {
|
|
|
2699
2700
|
* Subscribe to incoming broadcasts
|
|
2700
2701
|
*/
|
|
2701
2702
|
onBroadcast(handler: (message: BroadcastMessage) => void): () => void;
|
|
2703
|
+
/**
|
|
2704
|
+
* Resolve a peer's nametag by their transport pubkey.
|
|
2705
|
+
* Uses transport.resolveTransportPubkeyInfo() for live lookup from relay binding events.
|
|
2706
|
+
* Returns undefined if transport doesn't support resolution or peer has no nametag.
|
|
2707
|
+
*/
|
|
2708
|
+
resolvePeerNametag(peerPubkey: string): Promise<string | undefined>;
|
|
2702
2709
|
private handleIncomingMessage;
|
|
2703
2710
|
private handleComposingIndicator;
|
|
2704
2711
|
private handleIncomingBroadcast;
|
|
@@ -2748,6 +2755,11 @@ declare class GroupChatModule {
|
|
|
2748
2755
|
private destroyConnection;
|
|
2749
2756
|
connect(): Promise<void>;
|
|
2750
2757
|
getConnectionStatus(): boolean;
|
|
2758
|
+
/**
|
|
2759
|
+
* Refresh subscriptions after load() switched to a different address.
|
|
2760
|
+
* Clears old subscriptions, restores groups if needed, and re-subscribes.
|
|
2761
|
+
*/
|
|
2762
|
+
private refreshSubscriptions;
|
|
2751
2763
|
private doConnect;
|
|
2752
2764
|
private scheduleReconnect;
|
|
2753
2765
|
private subscribeToJoinedGroups;
|
package/dist/core/index.d.ts
CHANGED
|
@@ -2621,6 +2621,7 @@ declare class CommunicationsModule {
|
|
|
2621
2621
|
private dmHandlers;
|
|
2622
2622
|
private composingHandlers;
|
|
2623
2623
|
private broadcastHandlers;
|
|
2624
|
+
private initializedAt;
|
|
2624
2625
|
constructor(config?: CommunicationsModuleConfig);
|
|
2625
2626
|
/**
|
|
2626
2627
|
* Initialize module with dependencies
|
|
@@ -2699,6 +2700,12 @@ declare class CommunicationsModule {
|
|
|
2699
2700
|
* Subscribe to incoming broadcasts
|
|
2700
2701
|
*/
|
|
2701
2702
|
onBroadcast(handler: (message: BroadcastMessage) => void): () => void;
|
|
2703
|
+
/**
|
|
2704
|
+
* Resolve a peer's nametag by their transport pubkey.
|
|
2705
|
+
* Uses transport.resolveTransportPubkeyInfo() for live lookup from relay binding events.
|
|
2706
|
+
* Returns undefined if transport doesn't support resolution or peer has no nametag.
|
|
2707
|
+
*/
|
|
2708
|
+
resolvePeerNametag(peerPubkey: string): Promise<string | undefined>;
|
|
2702
2709
|
private handleIncomingMessage;
|
|
2703
2710
|
private handleComposingIndicator;
|
|
2704
2711
|
private handleIncomingBroadcast;
|
|
@@ -2748,6 +2755,11 @@ declare class GroupChatModule {
|
|
|
2748
2755
|
private destroyConnection;
|
|
2749
2756
|
connect(): Promise<void>;
|
|
2750
2757
|
getConnectionStatus(): boolean;
|
|
2758
|
+
/**
|
|
2759
|
+
* Refresh subscriptions after load() switched to a different address.
|
|
2760
|
+
* Clears old subscriptions, restores groups if needed, and re-subscribes.
|
|
2761
|
+
*/
|
|
2762
|
+
private refreshSubscriptions;
|
|
2751
2763
|
private doConnect;
|
|
2752
2764
|
private scheduleReconnect;
|
|
2753
2765
|
private subscribeToJoinedGroups;
|
package/dist/core/index.js
CHANGED
|
@@ -2348,15 +2348,7 @@ var STORAGE_KEYS_GLOBAL = {
|
|
|
2348
2348
|
TRACKED_ADDRESSES: "tracked_addresses",
|
|
2349
2349
|
/** Last processed Nostr wallet event timestamp (unix seconds), keyed per pubkey */
|
|
2350
2350
|
LAST_WALLET_EVENT_TS: "last_wallet_event_ts",
|
|
2351
|
-
/** Group chat:
|
|
2352
|
-
GROUP_CHAT_GROUPS: "group_chat_groups",
|
|
2353
|
-
/** Group chat: messages */
|
|
2354
|
-
GROUP_CHAT_MESSAGES: "group_chat_messages",
|
|
2355
|
-
/** Group chat: members */
|
|
2356
|
-
GROUP_CHAT_MEMBERS: "group_chat_members",
|
|
2357
|
-
/** Group chat: processed event IDs for deduplication */
|
|
2358
|
-
GROUP_CHAT_PROCESSED_EVENTS: "group_chat_processed_events",
|
|
2359
|
-
/** Group chat: last used relay URL (stale data detection) */
|
|
2351
|
+
/** Group chat: last used relay URL (stale data detection) — global, same relay for all addresses */
|
|
2360
2352
|
GROUP_CHAT_RELAY_URL: "group_chat_relay_url",
|
|
2361
2353
|
/** Cached token registry JSON (fetched from remote) */
|
|
2362
2354
|
TOKEN_REGISTRY_CACHE: "token_registry_cache",
|
|
@@ -2379,7 +2371,15 @@ var STORAGE_KEYS_ADDRESS = {
|
|
|
2379
2371
|
/** Transaction history for this address */
|
|
2380
2372
|
TRANSACTION_HISTORY: "transaction_history",
|
|
2381
2373
|
/** Pending V5 finalization tokens (unconfirmed instant split tokens) */
|
|
2382
|
-
PENDING_V5_TOKENS: "pending_v5_tokens"
|
|
2374
|
+
PENDING_V5_TOKENS: "pending_v5_tokens",
|
|
2375
|
+
/** Group chat: joined groups for this address */
|
|
2376
|
+
GROUP_CHAT_GROUPS: "group_chat_groups",
|
|
2377
|
+
/** Group chat: messages for this address */
|
|
2378
|
+
GROUP_CHAT_MESSAGES: "group_chat_messages",
|
|
2379
|
+
/** Group chat: members for this address */
|
|
2380
|
+
GROUP_CHAT_MEMBERS: "group_chat_members",
|
|
2381
|
+
/** Group chat: processed event IDs for deduplication */
|
|
2382
|
+
GROUP_CHAT_PROCESSED_EVENTS: "group_chat_processed_events"
|
|
2383
2383
|
};
|
|
2384
2384
|
var STORAGE_KEYS = {
|
|
2385
2385
|
...STORAGE_KEYS_GLOBAL,
|
|
@@ -7350,6 +7350,8 @@ var CommunicationsModule = class {
|
|
|
7350
7350
|
dmHandlers = /* @__PURE__ */ new Set();
|
|
7351
7351
|
composingHandlers = /* @__PURE__ */ new Set();
|
|
7352
7352
|
broadcastHandlers = /* @__PURE__ */ new Set();
|
|
7353
|
+
// Timestamp of module initialization — messages older than this are historical
|
|
7354
|
+
initializedAt = 0;
|
|
7353
7355
|
constructor(config) {
|
|
7354
7356
|
this.config = {
|
|
7355
7357
|
autoSave: config?.autoSave ?? true,
|
|
@@ -7368,6 +7370,7 @@ var CommunicationsModule = class {
|
|
|
7368
7370
|
this.unsubscribeMessages?.();
|
|
7369
7371
|
this.unsubscribeComposing?.();
|
|
7370
7372
|
this.deps = deps;
|
|
7373
|
+
this.initializedAt = Date.now();
|
|
7371
7374
|
this.unsubscribeMessages = deps.transport.onMessage((msg) => {
|
|
7372
7375
|
this.handleIncomingMessage(msg);
|
|
7373
7376
|
});
|
|
@@ -7656,9 +7659,27 @@ var CommunicationsModule = class {
|
|
|
7656
7659
|
return () => this.broadcastHandlers.delete(handler);
|
|
7657
7660
|
}
|
|
7658
7661
|
// ===========================================================================
|
|
7662
|
+
// Public API - Peer Resolution
|
|
7663
|
+
// ===========================================================================
|
|
7664
|
+
/**
|
|
7665
|
+
* Resolve a peer's nametag by their transport pubkey.
|
|
7666
|
+
* Uses transport.resolveTransportPubkeyInfo() for live lookup from relay binding events.
|
|
7667
|
+
* Returns undefined if transport doesn't support resolution or peer has no nametag.
|
|
7668
|
+
*/
|
|
7669
|
+
async resolvePeerNametag(peerPubkey) {
|
|
7670
|
+
if (!this.deps?.transport.resolveTransportPubkeyInfo) return void 0;
|
|
7671
|
+
try {
|
|
7672
|
+
const info = await this.deps.transport.resolveTransportPubkeyInfo(peerPubkey);
|
|
7673
|
+
return info?.nametag;
|
|
7674
|
+
} catch {
|
|
7675
|
+
return void 0;
|
|
7676
|
+
}
|
|
7677
|
+
}
|
|
7678
|
+
// ===========================================================================
|
|
7659
7679
|
// Private: Message Handling
|
|
7660
7680
|
// ===========================================================================
|
|
7661
7681
|
handleIncomingMessage(msg) {
|
|
7682
|
+
const isHistorical = msg.timestamp < this.initializedAt;
|
|
7662
7683
|
if (msg.isSelfWrap && msg.recipientTransportPubkey) {
|
|
7663
7684
|
if (this.messages.has(msg.id)) return;
|
|
7664
7685
|
const message2 = {
|
|
@@ -7668,7 +7689,7 @@ var CommunicationsModule = class {
|
|
|
7668
7689
|
recipientPubkey: msg.recipientTransportPubkey,
|
|
7669
7690
|
content: msg.content,
|
|
7670
7691
|
timestamp: msg.timestamp,
|
|
7671
|
-
isRead:
|
|
7692
|
+
isRead: isHistorical
|
|
7672
7693
|
};
|
|
7673
7694
|
this.messages.set(message2.id, message2);
|
|
7674
7695
|
this.deps.emitEvent("message:dm", message2);
|
|
@@ -7686,7 +7707,7 @@ var CommunicationsModule = class {
|
|
|
7686
7707
|
recipientPubkey: this.deps.identity.chainPubkey,
|
|
7687
7708
|
content: msg.content,
|
|
7688
7709
|
timestamp: msg.timestamp,
|
|
7689
|
-
isRead:
|
|
7710
|
+
isRead: isHistorical
|
|
7690
7711
|
};
|
|
7691
7712
|
this.messages.set(message.id, message);
|
|
7692
7713
|
this.deps.emitEvent("message:dm", message);
|
|
@@ -7862,22 +7883,24 @@ var GroupChatModule = class {
|
|
|
7862
7883
|
async load() {
|
|
7863
7884
|
this.ensureInitialized();
|
|
7864
7885
|
const storage = this.deps.storage;
|
|
7865
|
-
|
|
7886
|
+
this.groups.clear();
|
|
7887
|
+
this.messages.clear();
|
|
7888
|
+
this.members.clear();
|
|
7889
|
+
this.processedEventIds.clear();
|
|
7890
|
+
const groupsJson = await storage.get(STORAGE_KEYS_ADDRESS.GROUP_CHAT_GROUPS);
|
|
7866
7891
|
if (groupsJson) {
|
|
7867
7892
|
try {
|
|
7868
7893
|
const parsed = JSON.parse(groupsJson);
|
|
7869
|
-
this.groups.clear();
|
|
7870
7894
|
for (const g of parsed) {
|
|
7871
7895
|
this.groups.set(g.id, g);
|
|
7872
7896
|
}
|
|
7873
7897
|
} catch {
|
|
7874
7898
|
}
|
|
7875
7899
|
}
|
|
7876
|
-
const messagesJson = await storage.get(
|
|
7900
|
+
const messagesJson = await storage.get(STORAGE_KEYS_ADDRESS.GROUP_CHAT_MESSAGES);
|
|
7877
7901
|
if (messagesJson) {
|
|
7878
7902
|
try {
|
|
7879
7903
|
const parsed = JSON.parse(messagesJson);
|
|
7880
|
-
this.messages.clear();
|
|
7881
7904
|
for (const m of parsed) {
|
|
7882
7905
|
const groupId = m.groupId;
|
|
7883
7906
|
if (!this.messages.has(groupId)) {
|
|
@@ -7888,11 +7911,10 @@ var GroupChatModule = class {
|
|
|
7888
7911
|
} catch {
|
|
7889
7912
|
}
|
|
7890
7913
|
}
|
|
7891
|
-
const membersJson = await storage.get(
|
|
7914
|
+
const membersJson = await storage.get(STORAGE_KEYS_ADDRESS.GROUP_CHAT_MEMBERS);
|
|
7892
7915
|
if (membersJson) {
|
|
7893
7916
|
try {
|
|
7894
7917
|
const parsed = JSON.parse(membersJson);
|
|
7895
|
-
this.members.clear();
|
|
7896
7918
|
for (const m of parsed) {
|
|
7897
7919
|
const groupId = m.groupId;
|
|
7898
7920
|
if (!this.members.has(groupId)) {
|
|
@@ -7903,7 +7925,7 @@ var GroupChatModule = class {
|
|
|
7903
7925
|
} catch {
|
|
7904
7926
|
}
|
|
7905
7927
|
}
|
|
7906
|
-
const processedJson = await storage.get(
|
|
7928
|
+
const processedJson = await storage.get(STORAGE_KEYS_ADDRESS.GROUP_CHAT_PROCESSED_EVENTS);
|
|
7907
7929
|
if (processedJson) {
|
|
7908
7930
|
try {
|
|
7909
7931
|
const parsed = JSON.parse(processedJson);
|
|
@@ -7957,7 +7979,10 @@ var GroupChatModule = class {
|
|
|
7957
7979
|
// Connection
|
|
7958
7980
|
// ===========================================================================
|
|
7959
7981
|
async connect() {
|
|
7960
|
-
if (this.connected)
|
|
7982
|
+
if (this.connected) {
|
|
7983
|
+
await this.refreshSubscriptions();
|
|
7984
|
+
return;
|
|
7985
|
+
}
|
|
7961
7986
|
if (this.connectPromise) {
|
|
7962
7987
|
return this.connectPromise;
|
|
7963
7988
|
}
|
|
@@ -7971,6 +7996,28 @@ var GroupChatModule = class {
|
|
|
7971
7996
|
getConnectionStatus() {
|
|
7972
7997
|
return this.connected;
|
|
7973
7998
|
}
|
|
7999
|
+
/**
|
|
8000
|
+
* Refresh subscriptions after load() switched to a different address.
|
|
8001
|
+
* Clears old subscriptions, restores groups if needed, and re-subscribes.
|
|
8002
|
+
*/
|
|
8003
|
+
async refreshSubscriptions() {
|
|
8004
|
+
if (!this.client) return;
|
|
8005
|
+
for (const subId of this.subscriptionIds) {
|
|
8006
|
+
try {
|
|
8007
|
+
this.client.unsubscribe(subId);
|
|
8008
|
+
} catch {
|
|
8009
|
+
}
|
|
8010
|
+
}
|
|
8011
|
+
this.subscriptionIds = [];
|
|
8012
|
+
const secretKey = Buffer.from(this.deps.identity.privateKey, "hex");
|
|
8013
|
+
this.keyManager = NostrKeyManager.fromPrivateKey(secretKey);
|
|
8014
|
+
if (this.groups.size === 0) {
|
|
8015
|
+
await this.restoreJoinedGroups();
|
|
8016
|
+
} else {
|
|
8017
|
+
await this.subscribeToJoinedGroups();
|
|
8018
|
+
}
|
|
8019
|
+
this.deps.emitEvent("groupchat:connection", { connected: true });
|
|
8020
|
+
}
|
|
7974
8021
|
async doConnect() {
|
|
7975
8022
|
this.ensureInitialized();
|
|
7976
8023
|
if (!this.keyManager) {
|
|
@@ -7986,12 +8033,12 @@ var GroupChatModule = class {
|
|
|
7986
8033
|
await this.client.connect(...this.config.relays);
|
|
7987
8034
|
this.connected = true;
|
|
7988
8035
|
this.reconnectAttempts = 0;
|
|
7989
|
-
this.deps.emitEvent("groupchat:connection", { connected: true });
|
|
7990
8036
|
if (this.groups.size === 0) {
|
|
7991
8037
|
await this.restoreJoinedGroups();
|
|
7992
8038
|
} else {
|
|
7993
8039
|
await this.subscribeToJoinedGroups();
|
|
7994
8040
|
}
|
|
8041
|
+
this.deps.emitEvent("groupchat:connection", { connected: true });
|
|
7995
8042
|
} catch (error) {
|
|
7996
8043
|
console.error("[GroupChat] Failed to connect to relays", error);
|
|
7997
8044
|
this.deps.emitEvent("groupchat:connection", { connected: false });
|
|
@@ -8974,7 +9021,7 @@ var GroupChatModule = class {
|
|
|
8974
9021
|
async persistGroups() {
|
|
8975
9022
|
if (!this.deps) return;
|
|
8976
9023
|
const data = Array.from(this.groups.values());
|
|
8977
|
-
await this.deps.storage.set(
|
|
9024
|
+
await this.deps.storage.set(STORAGE_KEYS_ADDRESS.GROUP_CHAT_GROUPS, JSON.stringify(data));
|
|
8978
9025
|
}
|
|
8979
9026
|
async persistMessages() {
|
|
8980
9027
|
if (!this.deps) return;
|
|
@@ -8982,7 +9029,7 @@ var GroupChatModule = class {
|
|
|
8982
9029
|
for (const msgs of this.messages.values()) {
|
|
8983
9030
|
allMessages.push(...msgs);
|
|
8984
9031
|
}
|
|
8985
|
-
await this.deps.storage.set(
|
|
9032
|
+
await this.deps.storage.set(STORAGE_KEYS_ADDRESS.GROUP_CHAT_MESSAGES, JSON.stringify(allMessages));
|
|
8986
9033
|
}
|
|
8987
9034
|
async persistMembers() {
|
|
8988
9035
|
if (!this.deps) return;
|
|
@@ -8990,12 +9037,12 @@ var GroupChatModule = class {
|
|
|
8990
9037
|
for (const mems of this.members.values()) {
|
|
8991
9038
|
allMembers.push(...mems);
|
|
8992
9039
|
}
|
|
8993
|
-
await this.deps.storage.set(
|
|
9040
|
+
await this.deps.storage.set(STORAGE_KEYS_ADDRESS.GROUP_CHAT_MEMBERS, JSON.stringify(allMembers));
|
|
8994
9041
|
}
|
|
8995
9042
|
async persistProcessedEvents() {
|
|
8996
9043
|
if (!this.deps) return;
|
|
8997
9044
|
const arr = Array.from(this.processedEventIds);
|
|
8998
|
-
await this.deps.storage.set(
|
|
9045
|
+
await this.deps.storage.set(STORAGE_KEYS_ADDRESS.GROUP_CHAT_PROCESSED_EVENTS, JSON.stringify(arr));
|
|
8999
9046
|
}
|
|
9000
9047
|
// ===========================================================================
|
|
9001
9048
|
// Private — Relay URL Change Detection
|