@unicitylabs/sphere-sdk 0.3.6 → 0.3.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/core/index.cjs +61 -1
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.cts +57 -1
- package/dist/core/index.d.ts +57 -1
- package/dist/core/index.js +61 -1
- package/dist/core/index.js.map +1 -1
- package/dist/impl/browser/index.cjs +167 -32
- package/dist/impl/browser/index.cjs.map +1 -1
- package/dist/impl/browser/index.js +170 -33
- package/dist/impl/browser/index.js.map +1 -1
- package/dist/impl/nodejs/index.cjs +114 -4
- package/dist/impl/nodejs/index.cjs.map +1 -1
- package/dist/impl/nodejs/index.d.cts +49 -0
- package/dist/impl/nodejs/index.d.ts +49 -0
- package/dist/impl/nodejs/index.js +117 -5
- package/dist/impl/nodejs/index.js.map +1 -1
- package/dist/index.cjs +61 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +57 -1
- package/dist/index.d.ts +57 -1
- package/dist/index.js +61 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/core/index.d.cts
CHANGED
|
@@ -685,7 +685,7 @@ interface TrackedAddress extends TrackedAddressEntry {
|
|
|
685
685
|
/** Primary nametag (from nametag cache, without @ prefix) */
|
|
686
686
|
readonly nametag?: string;
|
|
687
687
|
}
|
|
688
|
-
type SphereEventType = 'transfer:incoming' | 'transfer:confirmed' | 'transfer:failed' | 'payment_request:incoming' | 'payment_request:accepted' | 'payment_request:rejected' | 'payment_request:paid' | 'payment_request:response' | 'message:dm' | 'message:broadcast' | 'sync:started' | 'sync:completed' | 'sync:provider' | 'sync:error' | 'connection:changed' | 'nametag:registered' | 'nametag:recovered' | 'identity:changed' | 'address:activated' | 'address:hidden' | 'address:unhidden' | 'sync:remote-update' | 'groupchat:message' | 'groupchat:joined' | 'groupchat:left' | 'groupchat:kicked' | 'groupchat:group_deleted' | 'groupchat:updated' | 'groupchat:connection';
|
|
688
|
+
type SphereEventType = 'transfer:incoming' | 'transfer:confirmed' | 'transfer:failed' | 'payment_request:incoming' | 'payment_request:accepted' | 'payment_request:rejected' | 'payment_request:paid' | 'payment_request:response' | 'message:dm' | 'message:read' | 'message:typing' | 'message:broadcast' | 'sync:started' | 'sync:completed' | 'sync:provider' | 'sync:error' | 'connection:changed' | 'nametag:registered' | 'nametag:recovered' | 'identity:changed' | 'address:activated' | 'address:hidden' | 'address:unhidden' | 'sync:remote-update' | 'groupchat:message' | 'groupchat:joined' | 'groupchat:left' | 'groupchat:kicked' | 'groupchat:group_deleted' | 'groupchat:updated' | 'groupchat:connection';
|
|
689
689
|
interface SphereEventMap {
|
|
690
690
|
'transfer:incoming': IncomingTransfer;
|
|
691
691
|
'transfer:confirmed': TransferResult;
|
|
@@ -696,6 +696,15 @@ interface SphereEventMap {
|
|
|
696
696
|
'payment_request:paid': IncomingPaymentRequest$1;
|
|
697
697
|
'payment_request:response': PaymentRequestResponse;
|
|
698
698
|
'message:dm': DirectMessage;
|
|
699
|
+
'message:read': {
|
|
700
|
+
messageIds: string[];
|
|
701
|
+
peerPubkey: string;
|
|
702
|
+
};
|
|
703
|
+
'message:typing': {
|
|
704
|
+
senderPubkey: string;
|
|
705
|
+
senderNametag?: string;
|
|
706
|
+
timestamp: number;
|
|
707
|
+
};
|
|
699
708
|
'message:broadcast': BroadcastMessage;
|
|
700
709
|
'sync:started': {
|
|
701
710
|
source: string;
|
|
@@ -1023,6 +1032,27 @@ interface TransportProvider extends BaseProvider {
|
|
|
1023
1032
|
* @returns Unsubscribe function
|
|
1024
1033
|
*/
|
|
1025
1034
|
onPaymentRequestResponse?(handler: PaymentRequestResponseHandler): () => void;
|
|
1035
|
+
/**
|
|
1036
|
+
* Send a read receipt for a message
|
|
1037
|
+
* @param recipientTransportPubkey - Transport pubkey of the message sender
|
|
1038
|
+
* @param messageEventId - Event ID of the message being acknowledged
|
|
1039
|
+
*/
|
|
1040
|
+
sendReadReceipt?(recipientTransportPubkey: string, messageEventId: string): Promise<void>;
|
|
1041
|
+
/**
|
|
1042
|
+
* Subscribe to incoming read receipts
|
|
1043
|
+
* @returns Unsubscribe function
|
|
1044
|
+
*/
|
|
1045
|
+
onReadReceipt?(handler: ReadReceiptHandler): () => void;
|
|
1046
|
+
/**
|
|
1047
|
+
* Send typing indicator to a recipient
|
|
1048
|
+
* @param recipientTransportPubkey - Transport pubkey of the conversation partner
|
|
1049
|
+
*/
|
|
1050
|
+
sendTypingIndicator?(recipientTransportPubkey: string): Promise<void>;
|
|
1051
|
+
/**
|
|
1052
|
+
* Subscribe to incoming typing indicators
|
|
1053
|
+
* @returns Unsubscribe function
|
|
1054
|
+
*/
|
|
1055
|
+
onTypingIndicator?(handler: TypingIndicatorHandler): () => void;
|
|
1026
1056
|
/**
|
|
1027
1057
|
* Get list of configured relay URLs
|
|
1028
1058
|
*/
|
|
@@ -1112,6 +1142,10 @@ interface IncomingMessage {
|
|
|
1112
1142
|
content: string;
|
|
1113
1143
|
timestamp: number;
|
|
1114
1144
|
encrypted: boolean;
|
|
1145
|
+
/** Set when this is a self-wrap replay (sent message recovered from relay) */
|
|
1146
|
+
isSelfWrap?: boolean;
|
|
1147
|
+
/** Recipient pubkey — only present on self-wrap replays */
|
|
1148
|
+
recipientTransportPubkey?: string;
|
|
1115
1149
|
}
|
|
1116
1150
|
type MessageHandler = (message: IncomingMessage) => void;
|
|
1117
1151
|
interface TokenTransferPayload {
|
|
@@ -1225,6 +1259,24 @@ interface PeerInfo {
|
|
|
1225
1259
|
/** Event timestamp */
|
|
1226
1260
|
timestamp: number;
|
|
1227
1261
|
}
|
|
1262
|
+
interface IncomingReadReceipt {
|
|
1263
|
+
/** Transport-specific pubkey of the sender who read the message */
|
|
1264
|
+
senderTransportPubkey: string;
|
|
1265
|
+
/** Event ID of the message that was read */
|
|
1266
|
+
messageEventId: string;
|
|
1267
|
+
/** Timestamp */
|
|
1268
|
+
timestamp: number;
|
|
1269
|
+
}
|
|
1270
|
+
type ReadReceiptHandler = (receipt: IncomingReadReceipt) => void;
|
|
1271
|
+
interface IncomingTypingIndicator {
|
|
1272
|
+
/** Transport-specific pubkey of the sender who is typing */
|
|
1273
|
+
senderTransportPubkey: string;
|
|
1274
|
+
/** Sender's nametag (if known) */
|
|
1275
|
+
senderNametag?: string;
|
|
1276
|
+
/** Timestamp */
|
|
1277
|
+
timestamp: number;
|
|
1278
|
+
}
|
|
1279
|
+
type TypingIndicatorHandler = (indicator: IncomingTypingIndicator) => void;
|
|
1228
1280
|
|
|
1229
1281
|
/**
|
|
1230
1282
|
* L1 Payments Sub-Module
|
|
@@ -2556,6 +2608,10 @@ declare class CommunicationsModule {
|
|
|
2556
2608
|
* Get unread count
|
|
2557
2609
|
*/
|
|
2558
2610
|
getUnreadCount(peerPubkey?: string): number;
|
|
2611
|
+
/**
|
|
2612
|
+
* Send typing indicator to a peer
|
|
2613
|
+
*/
|
|
2614
|
+
sendTypingIndicator(peerPubkey: string): Promise<void>;
|
|
2559
2615
|
/**
|
|
2560
2616
|
* Subscribe to incoming DMs
|
|
2561
2617
|
*/
|
package/dist/core/index.d.ts
CHANGED
|
@@ -685,7 +685,7 @@ interface TrackedAddress extends TrackedAddressEntry {
|
|
|
685
685
|
/** Primary nametag (from nametag cache, without @ prefix) */
|
|
686
686
|
readonly nametag?: string;
|
|
687
687
|
}
|
|
688
|
-
type SphereEventType = 'transfer:incoming' | 'transfer:confirmed' | 'transfer:failed' | 'payment_request:incoming' | 'payment_request:accepted' | 'payment_request:rejected' | 'payment_request:paid' | 'payment_request:response' | 'message:dm' | 'message:broadcast' | 'sync:started' | 'sync:completed' | 'sync:provider' | 'sync:error' | 'connection:changed' | 'nametag:registered' | 'nametag:recovered' | 'identity:changed' | 'address:activated' | 'address:hidden' | 'address:unhidden' | 'sync:remote-update' | 'groupchat:message' | 'groupchat:joined' | 'groupchat:left' | 'groupchat:kicked' | 'groupchat:group_deleted' | 'groupchat:updated' | 'groupchat:connection';
|
|
688
|
+
type SphereEventType = 'transfer:incoming' | 'transfer:confirmed' | 'transfer:failed' | 'payment_request:incoming' | 'payment_request:accepted' | 'payment_request:rejected' | 'payment_request:paid' | 'payment_request:response' | 'message:dm' | 'message:read' | 'message:typing' | 'message:broadcast' | 'sync:started' | 'sync:completed' | 'sync:provider' | 'sync:error' | 'connection:changed' | 'nametag:registered' | 'nametag:recovered' | 'identity:changed' | 'address:activated' | 'address:hidden' | 'address:unhidden' | 'sync:remote-update' | 'groupchat:message' | 'groupchat:joined' | 'groupchat:left' | 'groupchat:kicked' | 'groupchat:group_deleted' | 'groupchat:updated' | 'groupchat:connection';
|
|
689
689
|
interface SphereEventMap {
|
|
690
690
|
'transfer:incoming': IncomingTransfer;
|
|
691
691
|
'transfer:confirmed': TransferResult;
|
|
@@ -696,6 +696,15 @@ interface SphereEventMap {
|
|
|
696
696
|
'payment_request:paid': IncomingPaymentRequest$1;
|
|
697
697
|
'payment_request:response': PaymentRequestResponse;
|
|
698
698
|
'message:dm': DirectMessage;
|
|
699
|
+
'message:read': {
|
|
700
|
+
messageIds: string[];
|
|
701
|
+
peerPubkey: string;
|
|
702
|
+
};
|
|
703
|
+
'message:typing': {
|
|
704
|
+
senderPubkey: string;
|
|
705
|
+
senderNametag?: string;
|
|
706
|
+
timestamp: number;
|
|
707
|
+
};
|
|
699
708
|
'message:broadcast': BroadcastMessage;
|
|
700
709
|
'sync:started': {
|
|
701
710
|
source: string;
|
|
@@ -1023,6 +1032,27 @@ interface TransportProvider extends BaseProvider {
|
|
|
1023
1032
|
* @returns Unsubscribe function
|
|
1024
1033
|
*/
|
|
1025
1034
|
onPaymentRequestResponse?(handler: PaymentRequestResponseHandler): () => void;
|
|
1035
|
+
/**
|
|
1036
|
+
* Send a read receipt for a message
|
|
1037
|
+
* @param recipientTransportPubkey - Transport pubkey of the message sender
|
|
1038
|
+
* @param messageEventId - Event ID of the message being acknowledged
|
|
1039
|
+
*/
|
|
1040
|
+
sendReadReceipt?(recipientTransportPubkey: string, messageEventId: string): Promise<void>;
|
|
1041
|
+
/**
|
|
1042
|
+
* Subscribe to incoming read receipts
|
|
1043
|
+
* @returns Unsubscribe function
|
|
1044
|
+
*/
|
|
1045
|
+
onReadReceipt?(handler: ReadReceiptHandler): () => void;
|
|
1046
|
+
/**
|
|
1047
|
+
* Send typing indicator to a recipient
|
|
1048
|
+
* @param recipientTransportPubkey - Transport pubkey of the conversation partner
|
|
1049
|
+
*/
|
|
1050
|
+
sendTypingIndicator?(recipientTransportPubkey: string): Promise<void>;
|
|
1051
|
+
/**
|
|
1052
|
+
* Subscribe to incoming typing indicators
|
|
1053
|
+
* @returns Unsubscribe function
|
|
1054
|
+
*/
|
|
1055
|
+
onTypingIndicator?(handler: TypingIndicatorHandler): () => void;
|
|
1026
1056
|
/**
|
|
1027
1057
|
* Get list of configured relay URLs
|
|
1028
1058
|
*/
|
|
@@ -1112,6 +1142,10 @@ interface IncomingMessage {
|
|
|
1112
1142
|
content: string;
|
|
1113
1143
|
timestamp: number;
|
|
1114
1144
|
encrypted: boolean;
|
|
1145
|
+
/** Set when this is a self-wrap replay (sent message recovered from relay) */
|
|
1146
|
+
isSelfWrap?: boolean;
|
|
1147
|
+
/** Recipient pubkey — only present on self-wrap replays */
|
|
1148
|
+
recipientTransportPubkey?: string;
|
|
1115
1149
|
}
|
|
1116
1150
|
type MessageHandler = (message: IncomingMessage) => void;
|
|
1117
1151
|
interface TokenTransferPayload {
|
|
@@ -1225,6 +1259,24 @@ interface PeerInfo {
|
|
|
1225
1259
|
/** Event timestamp */
|
|
1226
1260
|
timestamp: number;
|
|
1227
1261
|
}
|
|
1262
|
+
interface IncomingReadReceipt {
|
|
1263
|
+
/** Transport-specific pubkey of the sender who read the message */
|
|
1264
|
+
senderTransportPubkey: string;
|
|
1265
|
+
/** Event ID of the message that was read */
|
|
1266
|
+
messageEventId: string;
|
|
1267
|
+
/** Timestamp */
|
|
1268
|
+
timestamp: number;
|
|
1269
|
+
}
|
|
1270
|
+
type ReadReceiptHandler = (receipt: IncomingReadReceipt) => void;
|
|
1271
|
+
interface IncomingTypingIndicator {
|
|
1272
|
+
/** Transport-specific pubkey of the sender who is typing */
|
|
1273
|
+
senderTransportPubkey: string;
|
|
1274
|
+
/** Sender's nametag (if known) */
|
|
1275
|
+
senderNametag?: string;
|
|
1276
|
+
/** Timestamp */
|
|
1277
|
+
timestamp: number;
|
|
1278
|
+
}
|
|
1279
|
+
type TypingIndicatorHandler = (indicator: IncomingTypingIndicator) => void;
|
|
1228
1280
|
|
|
1229
1281
|
/**
|
|
1230
1282
|
* L1 Payments Sub-Module
|
|
@@ -2556,6 +2608,10 @@ declare class CommunicationsModule {
|
|
|
2556
2608
|
* Get unread count
|
|
2557
2609
|
*/
|
|
2558
2610
|
getUnreadCount(peerPubkey?: string): number;
|
|
2611
|
+
/**
|
|
2612
|
+
* Send typing indicator to a peer
|
|
2613
|
+
*/
|
|
2614
|
+
sendTypingIndicator(peerPubkey: string): Promise<void>;
|
|
2559
2615
|
/**
|
|
2560
2616
|
* Subscribe to incoming DMs
|
|
2561
2617
|
*/
|
package/dist/core/index.js
CHANGED
|
@@ -7258,6 +7258,28 @@ var CommunicationsModule = class {
|
|
|
7258
7258
|
this.unsubscribeMessages = deps.transport.onMessage((msg) => {
|
|
7259
7259
|
this.handleIncomingMessage(msg);
|
|
7260
7260
|
});
|
|
7261
|
+
if (deps.transport.onReadReceipt) {
|
|
7262
|
+
deps.transport.onReadReceipt((receipt) => {
|
|
7263
|
+
const msg = this.messages.get(receipt.messageEventId);
|
|
7264
|
+
if (msg && msg.senderPubkey === this.deps.identity.chainPubkey) {
|
|
7265
|
+
msg.isRead = true;
|
|
7266
|
+
this.save();
|
|
7267
|
+
this.deps.emitEvent("message:read", {
|
|
7268
|
+
messageIds: [receipt.messageEventId],
|
|
7269
|
+
peerPubkey: receipt.senderTransportPubkey
|
|
7270
|
+
});
|
|
7271
|
+
}
|
|
7272
|
+
});
|
|
7273
|
+
}
|
|
7274
|
+
if (deps.transport.onTypingIndicator) {
|
|
7275
|
+
deps.transport.onTypingIndicator((indicator) => {
|
|
7276
|
+
this.deps.emitEvent("message:typing", {
|
|
7277
|
+
senderPubkey: indicator.senderTransportPubkey,
|
|
7278
|
+
senderNametag: indicator.senderNametag,
|
|
7279
|
+
timestamp: indicator.timestamp
|
|
7280
|
+
});
|
|
7281
|
+
});
|
|
7282
|
+
}
|
|
7261
7283
|
}
|
|
7262
7284
|
/**
|
|
7263
7285
|
* Load messages from storage
|
|
@@ -7301,7 +7323,7 @@ var CommunicationsModule = class {
|
|
|
7301
7323
|
recipientPubkey,
|
|
7302
7324
|
content,
|
|
7303
7325
|
timestamp: Date.now(),
|
|
7304
|
-
isRead:
|
|
7326
|
+
isRead: false
|
|
7305
7327
|
};
|
|
7306
7328
|
this.messages.set(message.id, message);
|
|
7307
7329
|
if (this.config.autoSave) {
|
|
@@ -7347,6 +7369,16 @@ var CommunicationsModule = class {
|
|
|
7347
7369
|
if (this.config.autoSave) {
|
|
7348
7370
|
await this.save();
|
|
7349
7371
|
}
|
|
7372
|
+
if (this.config.readReceipts && this.deps?.transport.sendReadReceipt) {
|
|
7373
|
+
for (const id of messageIds) {
|
|
7374
|
+
const msg = this.messages.get(id);
|
|
7375
|
+
if (msg && msg.senderPubkey !== this.deps.identity.chainPubkey) {
|
|
7376
|
+
this.deps.transport.sendReadReceipt(msg.senderPubkey, id).catch((err) => {
|
|
7377
|
+
console.warn("[Communications] Failed to send read receipt:", err);
|
|
7378
|
+
});
|
|
7379
|
+
}
|
|
7380
|
+
}
|
|
7381
|
+
}
|
|
7350
7382
|
}
|
|
7351
7383
|
/**
|
|
7352
7384
|
* Get unread count
|
|
@@ -7360,6 +7392,15 @@ var CommunicationsModule = class {
|
|
|
7360
7392
|
}
|
|
7361
7393
|
return messages.length;
|
|
7362
7394
|
}
|
|
7395
|
+
/**
|
|
7396
|
+
* Send typing indicator to a peer
|
|
7397
|
+
*/
|
|
7398
|
+
async sendTypingIndicator(peerPubkey) {
|
|
7399
|
+
this.ensureInitialized();
|
|
7400
|
+
if (this.deps.transport.sendTypingIndicator) {
|
|
7401
|
+
await this.deps.transport.sendTypingIndicator(peerPubkey);
|
|
7402
|
+
}
|
|
7403
|
+
}
|
|
7363
7404
|
/**
|
|
7364
7405
|
* Subscribe to incoming DMs
|
|
7365
7406
|
*/
|
|
@@ -7429,7 +7470,26 @@ var CommunicationsModule = class {
|
|
|
7429
7470
|
// Private: Message Handling
|
|
7430
7471
|
// ===========================================================================
|
|
7431
7472
|
handleIncomingMessage(msg) {
|
|
7473
|
+
if (msg.isSelfWrap && msg.recipientTransportPubkey) {
|
|
7474
|
+
if (this.messages.has(msg.id)) return;
|
|
7475
|
+
const message2 = {
|
|
7476
|
+
id: msg.id,
|
|
7477
|
+
senderPubkey: this.deps.identity.chainPubkey,
|
|
7478
|
+
senderNametag: msg.senderNametag,
|
|
7479
|
+
recipientPubkey: msg.recipientTransportPubkey,
|
|
7480
|
+
content: msg.content,
|
|
7481
|
+
timestamp: msg.timestamp,
|
|
7482
|
+
isRead: false
|
|
7483
|
+
};
|
|
7484
|
+
this.messages.set(message2.id, message2);
|
|
7485
|
+
this.deps.emitEvent("message:dm", message2);
|
|
7486
|
+
if (this.config.autoSave) {
|
|
7487
|
+
this.save();
|
|
7488
|
+
}
|
|
7489
|
+
return;
|
|
7490
|
+
}
|
|
7432
7491
|
if (msg.senderTransportPubkey === this.deps?.identity.chainPubkey) return;
|
|
7492
|
+
if (this.messages.has(msg.id)) return;
|
|
7433
7493
|
const message = {
|
|
7434
7494
|
id: msg.id,
|
|
7435
7495
|
senderPubkey: msg.senderTransportPubkey,
|