@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/index.d.cts
CHANGED
|
@@ -1162,7 +1162,7 @@ interface TrackedAddress extends TrackedAddressEntry {
|
|
|
1162
1162
|
/** Primary nametag (from nametag cache, without @ prefix) */
|
|
1163
1163
|
readonly nametag?: string;
|
|
1164
1164
|
}
|
|
1165
|
-
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';
|
|
1165
|
+
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';
|
|
1166
1166
|
interface SphereEventMap {
|
|
1167
1167
|
'transfer:incoming': IncomingTransfer;
|
|
1168
1168
|
'transfer:confirmed': TransferResult;
|
|
@@ -1173,6 +1173,15 @@ interface SphereEventMap {
|
|
|
1173
1173
|
'payment_request:paid': IncomingPaymentRequest$1;
|
|
1174
1174
|
'payment_request:response': PaymentRequestResponse;
|
|
1175
1175
|
'message:dm': DirectMessage;
|
|
1176
|
+
'message:read': {
|
|
1177
|
+
messageIds: string[];
|
|
1178
|
+
peerPubkey: string;
|
|
1179
|
+
};
|
|
1180
|
+
'message:typing': {
|
|
1181
|
+
senderPubkey: string;
|
|
1182
|
+
senderNametag?: string;
|
|
1183
|
+
timestamp: number;
|
|
1184
|
+
};
|
|
1176
1185
|
'message:broadcast': BroadcastMessage;
|
|
1177
1186
|
'sync:started': {
|
|
1178
1187
|
source: string;
|
|
@@ -1542,6 +1551,27 @@ interface TransportProvider extends BaseProvider {
|
|
|
1542
1551
|
* @returns Unsubscribe function
|
|
1543
1552
|
*/
|
|
1544
1553
|
onPaymentRequestResponse?(handler: PaymentRequestResponseHandler): () => void;
|
|
1554
|
+
/**
|
|
1555
|
+
* Send a read receipt for a message
|
|
1556
|
+
* @param recipientTransportPubkey - Transport pubkey of the message sender
|
|
1557
|
+
* @param messageEventId - Event ID of the message being acknowledged
|
|
1558
|
+
*/
|
|
1559
|
+
sendReadReceipt?(recipientTransportPubkey: string, messageEventId: string): Promise<void>;
|
|
1560
|
+
/**
|
|
1561
|
+
* Subscribe to incoming read receipts
|
|
1562
|
+
* @returns Unsubscribe function
|
|
1563
|
+
*/
|
|
1564
|
+
onReadReceipt?(handler: ReadReceiptHandler): () => void;
|
|
1565
|
+
/**
|
|
1566
|
+
* Send typing indicator to a recipient
|
|
1567
|
+
* @param recipientTransportPubkey - Transport pubkey of the conversation partner
|
|
1568
|
+
*/
|
|
1569
|
+
sendTypingIndicator?(recipientTransportPubkey: string): Promise<void>;
|
|
1570
|
+
/**
|
|
1571
|
+
* Subscribe to incoming typing indicators
|
|
1572
|
+
* @returns Unsubscribe function
|
|
1573
|
+
*/
|
|
1574
|
+
onTypingIndicator?(handler: TypingIndicatorHandler): () => void;
|
|
1545
1575
|
/**
|
|
1546
1576
|
* Get list of configured relay URLs
|
|
1547
1577
|
*/
|
|
@@ -1631,6 +1661,10 @@ interface IncomingMessage {
|
|
|
1631
1661
|
content: string;
|
|
1632
1662
|
timestamp: number;
|
|
1633
1663
|
encrypted: boolean;
|
|
1664
|
+
/** Set when this is a self-wrap replay (sent message recovered from relay) */
|
|
1665
|
+
isSelfWrap?: boolean;
|
|
1666
|
+
/** Recipient pubkey — only present on self-wrap replays */
|
|
1667
|
+
recipientTransportPubkey?: string;
|
|
1634
1668
|
}
|
|
1635
1669
|
type MessageHandler = (message: IncomingMessage) => void;
|
|
1636
1670
|
interface TokenTransferPayload {
|
|
@@ -1752,6 +1786,24 @@ interface PeerInfo {
|
|
|
1752
1786
|
/** Event timestamp */
|
|
1753
1787
|
timestamp: number;
|
|
1754
1788
|
}
|
|
1789
|
+
interface IncomingReadReceipt {
|
|
1790
|
+
/** Transport-specific pubkey of the sender who read the message */
|
|
1791
|
+
senderTransportPubkey: string;
|
|
1792
|
+
/** Event ID of the message that was read */
|
|
1793
|
+
messageEventId: string;
|
|
1794
|
+
/** Timestamp */
|
|
1795
|
+
timestamp: number;
|
|
1796
|
+
}
|
|
1797
|
+
type ReadReceiptHandler = (receipt: IncomingReadReceipt) => void;
|
|
1798
|
+
interface IncomingTypingIndicator {
|
|
1799
|
+
/** Transport-specific pubkey of the sender who is typing */
|
|
1800
|
+
senderTransportPubkey: string;
|
|
1801
|
+
/** Sender's nametag (if known) */
|
|
1802
|
+
senderNametag?: string;
|
|
1803
|
+
/** Timestamp */
|
|
1804
|
+
timestamp: number;
|
|
1805
|
+
}
|
|
1806
|
+
type TypingIndicatorHandler = (indicator: IncomingTypingIndicator) => void;
|
|
1755
1807
|
|
|
1756
1808
|
/**
|
|
1757
1809
|
* L1 Payments Sub-Module
|
|
@@ -3170,6 +3222,10 @@ declare class CommunicationsModule {
|
|
|
3170
3222
|
* Get unread count
|
|
3171
3223
|
*/
|
|
3172
3224
|
getUnreadCount(peerPubkey?: string): number;
|
|
3225
|
+
/**
|
|
3226
|
+
* Send typing indicator to a peer
|
|
3227
|
+
*/
|
|
3228
|
+
sendTypingIndicator(peerPubkey: string): Promise<void>;
|
|
3173
3229
|
/**
|
|
3174
3230
|
* Subscribe to incoming DMs
|
|
3175
3231
|
*/
|
package/dist/index.d.ts
CHANGED
|
@@ -1162,7 +1162,7 @@ interface TrackedAddress extends TrackedAddressEntry {
|
|
|
1162
1162
|
/** Primary nametag (from nametag cache, without @ prefix) */
|
|
1163
1163
|
readonly nametag?: string;
|
|
1164
1164
|
}
|
|
1165
|
-
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';
|
|
1165
|
+
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';
|
|
1166
1166
|
interface SphereEventMap {
|
|
1167
1167
|
'transfer:incoming': IncomingTransfer;
|
|
1168
1168
|
'transfer:confirmed': TransferResult;
|
|
@@ -1173,6 +1173,15 @@ interface SphereEventMap {
|
|
|
1173
1173
|
'payment_request:paid': IncomingPaymentRequest$1;
|
|
1174
1174
|
'payment_request:response': PaymentRequestResponse;
|
|
1175
1175
|
'message:dm': DirectMessage;
|
|
1176
|
+
'message:read': {
|
|
1177
|
+
messageIds: string[];
|
|
1178
|
+
peerPubkey: string;
|
|
1179
|
+
};
|
|
1180
|
+
'message:typing': {
|
|
1181
|
+
senderPubkey: string;
|
|
1182
|
+
senderNametag?: string;
|
|
1183
|
+
timestamp: number;
|
|
1184
|
+
};
|
|
1176
1185
|
'message:broadcast': BroadcastMessage;
|
|
1177
1186
|
'sync:started': {
|
|
1178
1187
|
source: string;
|
|
@@ -1542,6 +1551,27 @@ interface TransportProvider extends BaseProvider {
|
|
|
1542
1551
|
* @returns Unsubscribe function
|
|
1543
1552
|
*/
|
|
1544
1553
|
onPaymentRequestResponse?(handler: PaymentRequestResponseHandler): () => void;
|
|
1554
|
+
/**
|
|
1555
|
+
* Send a read receipt for a message
|
|
1556
|
+
* @param recipientTransportPubkey - Transport pubkey of the message sender
|
|
1557
|
+
* @param messageEventId - Event ID of the message being acknowledged
|
|
1558
|
+
*/
|
|
1559
|
+
sendReadReceipt?(recipientTransportPubkey: string, messageEventId: string): Promise<void>;
|
|
1560
|
+
/**
|
|
1561
|
+
* Subscribe to incoming read receipts
|
|
1562
|
+
* @returns Unsubscribe function
|
|
1563
|
+
*/
|
|
1564
|
+
onReadReceipt?(handler: ReadReceiptHandler): () => void;
|
|
1565
|
+
/**
|
|
1566
|
+
* Send typing indicator to a recipient
|
|
1567
|
+
* @param recipientTransportPubkey - Transport pubkey of the conversation partner
|
|
1568
|
+
*/
|
|
1569
|
+
sendTypingIndicator?(recipientTransportPubkey: string): Promise<void>;
|
|
1570
|
+
/**
|
|
1571
|
+
* Subscribe to incoming typing indicators
|
|
1572
|
+
* @returns Unsubscribe function
|
|
1573
|
+
*/
|
|
1574
|
+
onTypingIndicator?(handler: TypingIndicatorHandler): () => void;
|
|
1545
1575
|
/**
|
|
1546
1576
|
* Get list of configured relay URLs
|
|
1547
1577
|
*/
|
|
@@ -1631,6 +1661,10 @@ interface IncomingMessage {
|
|
|
1631
1661
|
content: string;
|
|
1632
1662
|
timestamp: number;
|
|
1633
1663
|
encrypted: boolean;
|
|
1664
|
+
/** Set when this is a self-wrap replay (sent message recovered from relay) */
|
|
1665
|
+
isSelfWrap?: boolean;
|
|
1666
|
+
/** Recipient pubkey — only present on self-wrap replays */
|
|
1667
|
+
recipientTransportPubkey?: string;
|
|
1634
1668
|
}
|
|
1635
1669
|
type MessageHandler = (message: IncomingMessage) => void;
|
|
1636
1670
|
interface TokenTransferPayload {
|
|
@@ -1752,6 +1786,24 @@ interface PeerInfo {
|
|
|
1752
1786
|
/** Event timestamp */
|
|
1753
1787
|
timestamp: number;
|
|
1754
1788
|
}
|
|
1789
|
+
interface IncomingReadReceipt {
|
|
1790
|
+
/** Transport-specific pubkey of the sender who read the message */
|
|
1791
|
+
senderTransportPubkey: string;
|
|
1792
|
+
/** Event ID of the message that was read */
|
|
1793
|
+
messageEventId: string;
|
|
1794
|
+
/** Timestamp */
|
|
1795
|
+
timestamp: number;
|
|
1796
|
+
}
|
|
1797
|
+
type ReadReceiptHandler = (receipt: IncomingReadReceipt) => void;
|
|
1798
|
+
interface IncomingTypingIndicator {
|
|
1799
|
+
/** Transport-specific pubkey of the sender who is typing */
|
|
1800
|
+
senderTransportPubkey: string;
|
|
1801
|
+
/** Sender's nametag (if known) */
|
|
1802
|
+
senderNametag?: string;
|
|
1803
|
+
/** Timestamp */
|
|
1804
|
+
timestamp: number;
|
|
1805
|
+
}
|
|
1806
|
+
type TypingIndicatorHandler = (indicator: IncomingTypingIndicator) => void;
|
|
1755
1807
|
|
|
1756
1808
|
/**
|
|
1757
1809
|
* L1 Payments Sub-Module
|
|
@@ -3170,6 +3222,10 @@ declare class CommunicationsModule {
|
|
|
3170
3222
|
* Get unread count
|
|
3171
3223
|
*/
|
|
3172
3224
|
getUnreadCount(peerPubkey?: string): number;
|
|
3225
|
+
/**
|
|
3226
|
+
* Send typing indicator to a peer
|
|
3227
|
+
*/
|
|
3228
|
+
sendTypingIndicator(peerPubkey: string): Promise<void>;
|
|
3173
3229
|
/**
|
|
3174
3230
|
* Subscribe to incoming DMs
|
|
3175
3231
|
*/
|
package/dist/index.js
CHANGED
|
@@ -7550,6 +7550,28 @@ var CommunicationsModule = class {
|
|
|
7550
7550
|
this.unsubscribeMessages = deps.transport.onMessage((msg) => {
|
|
7551
7551
|
this.handleIncomingMessage(msg);
|
|
7552
7552
|
});
|
|
7553
|
+
if (deps.transport.onReadReceipt) {
|
|
7554
|
+
deps.transport.onReadReceipt((receipt) => {
|
|
7555
|
+
const msg = this.messages.get(receipt.messageEventId);
|
|
7556
|
+
if (msg && msg.senderPubkey === this.deps.identity.chainPubkey) {
|
|
7557
|
+
msg.isRead = true;
|
|
7558
|
+
this.save();
|
|
7559
|
+
this.deps.emitEvent("message:read", {
|
|
7560
|
+
messageIds: [receipt.messageEventId],
|
|
7561
|
+
peerPubkey: receipt.senderTransportPubkey
|
|
7562
|
+
});
|
|
7563
|
+
}
|
|
7564
|
+
});
|
|
7565
|
+
}
|
|
7566
|
+
if (deps.transport.onTypingIndicator) {
|
|
7567
|
+
deps.transport.onTypingIndicator((indicator) => {
|
|
7568
|
+
this.deps.emitEvent("message:typing", {
|
|
7569
|
+
senderPubkey: indicator.senderTransportPubkey,
|
|
7570
|
+
senderNametag: indicator.senderNametag,
|
|
7571
|
+
timestamp: indicator.timestamp
|
|
7572
|
+
});
|
|
7573
|
+
});
|
|
7574
|
+
}
|
|
7553
7575
|
}
|
|
7554
7576
|
/**
|
|
7555
7577
|
* Load messages from storage
|
|
@@ -7593,7 +7615,7 @@ var CommunicationsModule = class {
|
|
|
7593
7615
|
recipientPubkey,
|
|
7594
7616
|
content,
|
|
7595
7617
|
timestamp: Date.now(),
|
|
7596
|
-
isRead:
|
|
7618
|
+
isRead: false
|
|
7597
7619
|
};
|
|
7598
7620
|
this.messages.set(message.id, message);
|
|
7599
7621
|
if (this.config.autoSave) {
|
|
@@ -7639,6 +7661,16 @@ var CommunicationsModule = class {
|
|
|
7639
7661
|
if (this.config.autoSave) {
|
|
7640
7662
|
await this.save();
|
|
7641
7663
|
}
|
|
7664
|
+
if (this.config.readReceipts && this.deps?.transport.sendReadReceipt) {
|
|
7665
|
+
for (const id of messageIds) {
|
|
7666
|
+
const msg = this.messages.get(id);
|
|
7667
|
+
if (msg && msg.senderPubkey !== this.deps.identity.chainPubkey) {
|
|
7668
|
+
this.deps.transport.sendReadReceipt(msg.senderPubkey, id).catch((err) => {
|
|
7669
|
+
console.warn("[Communications] Failed to send read receipt:", err);
|
|
7670
|
+
});
|
|
7671
|
+
}
|
|
7672
|
+
}
|
|
7673
|
+
}
|
|
7642
7674
|
}
|
|
7643
7675
|
/**
|
|
7644
7676
|
* Get unread count
|
|
@@ -7652,6 +7684,15 @@ var CommunicationsModule = class {
|
|
|
7652
7684
|
}
|
|
7653
7685
|
return messages.length;
|
|
7654
7686
|
}
|
|
7687
|
+
/**
|
|
7688
|
+
* Send typing indicator to a peer
|
|
7689
|
+
*/
|
|
7690
|
+
async sendTypingIndicator(peerPubkey) {
|
|
7691
|
+
this.ensureInitialized();
|
|
7692
|
+
if (this.deps.transport.sendTypingIndicator) {
|
|
7693
|
+
await this.deps.transport.sendTypingIndicator(peerPubkey);
|
|
7694
|
+
}
|
|
7695
|
+
}
|
|
7655
7696
|
/**
|
|
7656
7697
|
* Subscribe to incoming DMs
|
|
7657
7698
|
*/
|
|
@@ -7721,7 +7762,26 @@ var CommunicationsModule = class {
|
|
|
7721
7762
|
// Private: Message Handling
|
|
7722
7763
|
// ===========================================================================
|
|
7723
7764
|
handleIncomingMessage(msg) {
|
|
7765
|
+
if (msg.isSelfWrap && msg.recipientTransportPubkey) {
|
|
7766
|
+
if (this.messages.has(msg.id)) return;
|
|
7767
|
+
const message2 = {
|
|
7768
|
+
id: msg.id,
|
|
7769
|
+
senderPubkey: this.deps.identity.chainPubkey,
|
|
7770
|
+
senderNametag: msg.senderNametag,
|
|
7771
|
+
recipientPubkey: msg.recipientTransportPubkey,
|
|
7772
|
+
content: msg.content,
|
|
7773
|
+
timestamp: msg.timestamp,
|
|
7774
|
+
isRead: false
|
|
7775
|
+
};
|
|
7776
|
+
this.messages.set(message2.id, message2);
|
|
7777
|
+
this.deps.emitEvent("message:dm", message2);
|
|
7778
|
+
if (this.config.autoSave) {
|
|
7779
|
+
this.save();
|
|
7780
|
+
}
|
|
7781
|
+
return;
|
|
7782
|
+
}
|
|
7724
7783
|
if (msg.senderTransportPubkey === this.deps?.identity.chainPubkey) return;
|
|
7784
|
+
if (this.messages.has(msg.id)) return;
|
|
7725
7785
|
const message = {
|
|
7726
7786
|
id: msg.id,
|
|
7727
7787
|
senderPubkey: msg.senderTransportPubkey,
|