nostr-double-ratchet 0.0.38 → 0.0.48
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/README.md +52 -15
- package/dist/AppKeys.d.ts +52 -0
- package/dist/AppKeys.d.ts.map +1 -0
- package/dist/AppKeysManager.d.ts +136 -0
- package/dist/AppKeysManager.d.ts.map +1 -0
- package/dist/Invite.d.ts +5 -6
- package/dist/Invite.d.ts.map +1 -1
- package/dist/Session.d.ts +29 -0
- package/dist/Session.d.ts.map +1 -1
- package/dist/SessionManager.d.ts +15 -8
- package/dist/SessionManager.d.ts.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/inviteUtils.d.ts +6 -6
- package/dist/inviteUtils.d.ts.map +1 -1
- package/dist/nostr-double-ratchet.es.js +2518 -2168
- package/dist/nostr-double-ratchet.umd.js +1 -1
- package/dist/types.d.ts +24 -5
- package/dist/types.d.ts.map +1 -1
- package/dist/utils.d.ts +20 -2
- package/dist/utils.d.ts.map +1 -1
- package/package.json +5 -19
- package/src/AppKeys.ts +210 -0
- package/src/AppKeysManager.ts +405 -0
- package/src/Invite.ts +9 -8
- package/src/Session.ts +46 -3
- package/src/SessionManager.ts +341 -174
- package/src/index.ts +3 -3
- package/src/inviteUtils.ts +12 -11
- package/src/types.ts +28 -5
- package/src/utils.ts +42 -5
- package/LICENSE +0 -21
- package/dist/DeviceManager.d.ts +0 -127
- package/dist/DeviceManager.d.ts.map +0 -1
- package/dist/InviteList.d.ts +0 -43
- package/dist/InviteList.d.ts.map +0 -1
- package/dist/UserRecord.d.ts +0 -117
- package/dist/UserRecord.d.ts.map +0 -1
- package/src/DeviceManager.ts +0 -565
- package/src/InviteList.ts +0 -333
- package/src/UserRecord.ts +0 -338
package/src/index.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
export * from "./Session"
|
|
2
2
|
export * from "./Invite"
|
|
3
|
-
export * from "./
|
|
3
|
+
export * from "./AppKeys"
|
|
4
4
|
export * from "./inviteUtils"
|
|
5
5
|
export * from "./types"
|
|
6
6
|
export * from "./utils"
|
|
7
7
|
export * from "./SessionManager"
|
|
8
|
-
export * from "./
|
|
9
|
-
export * from "./StorageAdapter"
|
|
8
|
+
export * from "./AppKeysManager"
|
|
9
|
+
export * from "./StorageAdapter"
|
package/src/inviteUtils.ts
CHANGED
|
@@ -49,7 +49,7 @@ export function generateDeviceId(): string {
|
|
|
49
49
|
export interface EncryptInviteResponseParams {
|
|
50
50
|
/** The invitee's session public key */
|
|
51
51
|
inviteeSessionPublicKey: string
|
|
52
|
-
/** The invitee's identity public key */
|
|
52
|
+
/** The invitee's identity public key (also serves as device ID) */
|
|
53
53
|
inviteePublicKey: string
|
|
54
54
|
/** The invitee's identity private key (optional if encrypt function provided) */
|
|
55
55
|
inviteePrivateKey?: Uint8Array
|
|
@@ -59,8 +59,8 @@ export interface EncryptInviteResponseParams {
|
|
|
59
59
|
inviterEphemeralPublicKey: string
|
|
60
60
|
/** The shared secret for the invite */
|
|
61
61
|
sharedSecret: string
|
|
62
|
-
/**
|
|
63
|
-
|
|
62
|
+
/** The invitee's owner/Nostr identity public key (optional for single-device users) */
|
|
63
|
+
ownerPublicKey?: string
|
|
64
64
|
/** Optional custom encrypt function */
|
|
65
65
|
encrypt?: EncryptFunction
|
|
66
66
|
}
|
|
@@ -104,7 +104,7 @@ export async function encryptInviteResponse(params: EncryptInviteResponseParams)
|
|
|
104
104
|
inviterPublicKey,
|
|
105
105
|
inviterEphemeralPublicKey,
|
|
106
106
|
sharedSecret,
|
|
107
|
-
|
|
107
|
+
ownerPublicKey,
|
|
108
108
|
encrypt,
|
|
109
109
|
} = params
|
|
110
110
|
|
|
@@ -119,9 +119,10 @@ export async function encryptInviteResponse(params: EncryptInviteResponseParams)
|
|
|
119
119
|
})
|
|
120
120
|
|
|
121
121
|
// Create the payload
|
|
122
|
+
// Note: deviceId is no longer needed - inviteePublicKey (identity) serves as device ID
|
|
122
123
|
const payload = JSON.stringify({
|
|
123
124
|
sessionKey: inviteeSessionPublicKey,
|
|
124
|
-
|
|
125
|
+
...(ownerPublicKey && { ownerPublicKey }),
|
|
125
126
|
})
|
|
126
127
|
|
|
127
128
|
// Encrypt with DH key (invitee -> inviter)
|
|
@@ -172,12 +173,12 @@ export interface DecryptInviteResponseParams {
|
|
|
172
173
|
}
|
|
173
174
|
|
|
174
175
|
export interface DecryptedInviteResponse {
|
|
175
|
-
/** The invitee's identity public key */
|
|
176
|
+
/** The invitee's identity public key (also serves as device ID) */
|
|
176
177
|
inviteeIdentity: string
|
|
177
178
|
/** The invitee's session public key */
|
|
178
179
|
inviteeSessionPublicKey: string
|
|
179
|
-
/**
|
|
180
|
-
|
|
180
|
+
/** The invitee's owner/Nostr identity public key (optional for backward compat) */
|
|
181
|
+
ownerPublicKey?: string
|
|
181
182
|
}
|
|
182
183
|
|
|
183
184
|
/**
|
|
@@ -219,12 +220,12 @@ export async function decryptInviteResponse(params: DecryptInviteResponseParams)
|
|
|
219
220
|
const decryptedPayload = await decryptFn(dhEncrypted, inviteeIdentity)
|
|
220
221
|
|
|
221
222
|
let inviteeSessionPublicKey: string
|
|
222
|
-
let
|
|
223
|
+
let ownerPublicKey: string | undefined
|
|
223
224
|
|
|
224
225
|
try {
|
|
225
226
|
const parsed = JSON.parse(decryptedPayload)
|
|
226
227
|
inviteeSessionPublicKey = parsed.sessionKey
|
|
227
|
-
|
|
228
|
+
ownerPublicKey = parsed.ownerPublicKey
|
|
228
229
|
} catch {
|
|
229
230
|
// Backward compatibility: plain session key
|
|
230
231
|
inviteeSessionPublicKey = decryptedPayload
|
|
@@ -233,7 +234,7 @@ export async function decryptInviteResponse(params: DecryptInviteResponseParams)
|
|
|
233
234
|
return {
|
|
234
235
|
inviteeIdentity,
|
|
235
236
|
inviteeSessionPublicKey,
|
|
236
|
-
|
|
237
|
+
ownerPublicKey,
|
|
237
238
|
}
|
|
238
239
|
}
|
|
239
240
|
|
package/src/types.ts
CHANGED
|
@@ -98,14 +98,10 @@ export const INVITE_EVENT_KIND = 30078;
|
|
|
98
98
|
|
|
99
99
|
export const INVITE_RESPONSE_KIND = 1059;
|
|
100
100
|
|
|
101
|
-
|
|
102
|
-
* Invite list event kind (replaceable - one per user)
|
|
103
|
-
*/
|
|
104
|
-
export const INVITE_LIST_EVENT_KIND = 10078;
|
|
101
|
+
export const APP_KEYS_EVENT_KIND = 30078;
|
|
105
102
|
|
|
106
103
|
export const CHAT_MESSAGE_KIND = 14;
|
|
107
104
|
|
|
108
|
-
export const MAX_SKIP = 100;
|
|
109
105
|
|
|
110
106
|
export type NostrEvent = {
|
|
111
107
|
id: string;
|
|
@@ -116,3 +112,30 @@ export type NostrEvent = {
|
|
|
116
112
|
content: string;
|
|
117
113
|
sig: string;
|
|
118
114
|
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Payload for reaction messages sent through NDR.
|
|
118
|
+
* Reactions are regular messages with a JSON payload indicating they're a reaction.
|
|
119
|
+
*/
|
|
120
|
+
export interface ReactionPayload {
|
|
121
|
+
type: 'reaction';
|
|
122
|
+
/** ID of the message being reacted to */
|
|
123
|
+
messageId: string;
|
|
124
|
+
/** Emoji or reaction content */
|
|
125
|
+
emoji: string;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Kind constant for reaction inner events
|
|
130
|
+
*/
|
|
131
|
+
export const REACTION_KIND = 7;
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Kind constant for read/delivery receipt inner events
|
|
135
|
+
*/
|
|
136
|
+
export const RECEIPT_KIND = 15;
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Kind constant for typing indicator inner events
|
|
140
|
+
*/
|
|
141
|
+
export const TYPING_KIND = 25;
|
package/src/utils.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { hexToBytes, bytesToHex } from "@noble/hashes/utils";
|
|
2
|
-
import { Rumor, SessionState } from "./types";
|
|
2
|
+
import { Rumor, SessionState, ReactionPayload } from "./types";
|
|
3
3
|
import { Session } from "./Session.ts";
|
|
4
4
|
import { extract as hkdf_extract, expand as hkdf_expand } from '@noble/hashes/hkdf';
|
|
5
5
|
import { sha256 } from '@noble/hashes/sha256';
|
|
@@ -188,10 +188,6 @@ export function kdf(input1: Uint8Array, input2: Uint8Array = new Uint8Array(32),
|
|
|
188
188
|
return outputs;
|
|
189
189
|
}
|
|
190
190
|
|
|
191
|
-
export function skippedMessageIndexKey(_nostrSender: string, _number: number): string {
|
|
192
|
-
return `${_nostrSender}:${_number}`;
|
|
193
|
-
}
|
|
194
|
-
|
|
195
191
|
export function getMillisecondTimestamp(event: Rumor) {
|
|
196
192
|
const msTag = event.tags?.find((tag: string[]) => tag[0] === "ms");
|
|
197
193
|
if (msTag) {
|
|
@@ -199,3 +195,44 @@ export function getMillisecondTimestamp(event: Rumor) {
|
|
|
199
195
|
}
|
|
200
196
|
return event.created_at * 1000;
|
|
201
197
|
}
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Check if a message content is a reaction payload.
|
|
201
|
+
* @param content The message content to check
|
|
202
|
+
* @returns The parsed ReactionPayload if valid, null otherwise
|
|
203
|
+
*/
|
|
204
|
+
export function parseReaction(content: string): ReactionPayload | null {
|
|
205
|
+
try {
|
|
206
|
+
const parsed = JSON.parse(content);
|
|
207
|
+
if (parsed.type === 'reaction' && typeof parsed.messageId === 'string' && typeof parsed.emoji === 'string') {
|
|
208
|
+
return parsed as ReactionPayload;
|
|
209
|
+
}
|
|
210
|
+
} catch {
|
|
211
|
+
// Not JSON or invalid structure
|
|
212
|
+
}
|
|
213
|
+
return null;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
/**
|
|
217
|
+
* Check if a message content is a reaction.
|
|
218
|
+
* @param content The message content to check
|
|
219
|
+
* @returns true if the content is a reaction payload
|
|
220
|
+
*/
|
|
221
|
+
export function isReaction(content: string): boolean {
|
|
222
|
+
return parseReaction(content) !== null;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* Create a reaction payload JSON string.
|
|
227
|
+
* @param messageId The ID of the message being reacted to
|
|
228
|
+
* @param emoji The emoji or reaction content
|
|
229
|
+
* @returns JSON string of the reaction payload
|
|
230
|
+
*/
|
|
231
|
+
export function createReactionPayload(messageId: string, emoji: string): string {
|
|
232
|
+
const payload: ReactionPayload = {
|
|
233
|
+
type: 'reaction',
|
|
234
|
+
messageId,
|
|
235
|
+
emoji
|
|
236
|
+
};
|
|
237
|
+
return JSON.stringify(payload);
|
|
238
|
+
}
|
package/LICENSE
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2024 Martti Malmi
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|
package/dist/DeviceManager.d.ts
DELETED
|
@@ -1,127 +0,0 @@
|
|
|
1
|
-
import { InviteList, DeviceEntry } from "./InviteList";
|
|
2
|
-
import { DevicePayload } from "./inviteUtils";
|
|
3
|
-
import { NostrSubscribe, NostrPublish, IdentityKey } from "./types";
|
|
4
|
-
import { StorageAdapter } from "./StorageAdapter";
|
|
5
|
-
import { SessionManager } from "./SessionManager";
|
|
6
|
-
export interface OwnerDeviceOptions {
|
|
7
|
-
ownerPublicKey: string;
|
|
8
|
-
identityKey: IdentityKey;
|
|
9
|
-
deviceId: string;
|
|
10
|
-
deviceLabel: string;
|
|
11
|
-
nostrSubscribe: NostrSubscribe;
|
|
12
|
-
nostrPublish: NostrPublish;
|
|
13
|
-
storage?: StorageAdapter;
|
|
14
|
-
}
|
|
15
|
-
export interface DelegateDeviceOptions {
|
|
16
|
-
deviceId: string;
|
|
17
|
-
deviceLabel: string;
|
|
18
|
-
nostrSubscribe: NostrSubscribe;
|
|
19
|
-
nostrPublish: NostrPublish;
|
|
20
|
-
storage?: StorageAdapter;
|
|
21
|
-
}
|
|
22
|
-
export interface RestoreDelegateOptions {
|
|
23
|
-
deviceId: string;
|
|
24
|
-
devicePublicKey: string;
|
|
25
|
-
devicePrivateKey: Uint8Array;
|
|
26
|
-
ephemeralPublicKey: string;
|
|
27
|
-
ephemeralPrivateKey: Uint8Array;
|
|
28
|
-
sharedSecret: string;
|
|
29
|
-
nostrSubscribe: NostrSubscribe;
|
|
30
|
-
nostrPublish: NostrPublish;
|
|
31
|
-
storage?: StorageAdapter;
|
|
32
|
-
}
|
|
33
|
-
export interface CreateDelegateResult {
|
|
34
|
-
manager: DelegateDeviceManager;
|
|
35
|
-
payload: DevicePayload;
|
|
36
|
-
}
|
|
37
|
-
export interface IDeviceManager {
|
|
38
|
-
init(): Promise<void>;
|
|
39
|
-
getDeviceId(): string;
|
|
40
|
-
getIdentityPublicKey(): string;
|
|
41
|
-
getIdentityKey(): IdentityKey;
|
|
42
|
-
getEphemeralKeypair(): {
|
|
43
|
-
publicKey: string;
|
|
44
|
-
privateKey: Uint8Array;
|
|
45
|
-
} | null;
|
|
46
|
-
getSharedSecret(): string | null;
|
|
47
|
-
getOwnerPublicKey(): string | null;
|
|
48
|
-
close(): void;
|
|
49
|
-
createSessionManager(sessionStorage?: StorageAdapter): SessionManager;
|
|
50
|
-
}
|
|
51
|
-
/** Owner's main device. Has identity key and can manage InviteList. */
|
|
52
|
-
export declare class OwnerDeviceManager implements IDeviceManager {
|
|
53
|
-
private readonly deviceId;
|
|
54
|
-
private readonly deviceLabel;
|
|
55
|
-
private readonly nostrSubscribe;
|
|
56
|
-
private readonly nostrPublish;
|
|
57
|
-
private readonly storage;
|
|
58
|
-
private readonly ownerPublicKey;
|
|
59
|
-
private readonly identityKey;
|
|
60
|
-
private inviteList;
|
|
61
|
-
private initialized;
|
|
62
|
-
private subscriptions;
|
|
63
|
-
private readonly storageVersion;
|
|
64
|
-
private get versionPrefix();
|
|
65
|
-
constructor(options: OwnerDeviceOptions);
|
|
66
|
-
init(): Promise<void>;
|
|
67
|
-
getDeviceId(): string;
|
|
68
|
-
getIdentityPublicKey(): string;
|
|
69
|
-
getIdentityKey(): IdentityKey;
|
|
70
|
-
getEphemeralKeypair(): {
|
|
71
|
-
publicKey: string;
|
|
72
|
-
privateKey: Uint8Array;
|
|
73
|
-
} | null;
|
|
74
|
-
getSharedSecret(): string | null;
|
|
75
|
-
getOwnerPublicKey(): string;
|
|
76
|
-
getInviteList(): InviteList | null;
|
|
77
|
-
getOwnDevices(): DeviceEntry[];
|
|
78
|
-
addDevice(payload: DevicePayload): Promise<void>;
|
|
79
|
-
revokeDevice(deviceId: string): Promise<void>;
|
|
80
|
-
updateDeviceLabel(deviceId: string, label: string): Promise<void>;
|
|
81
|
-
close(): void;
|
|
82
|
-
createSessionManager(sessionStorage?: StorageAdapter): SessionManager;
|
|
83
|
-
private inviteListKey;
|
|
84
|
-
private loadInviteList;
|
|
85
|
-
private saveInviteList;
|
|
86
|
-
private fetchInviteList;
|
|
87
|
-
private mergeInviteLists;
|
|
88
|
-
private modifyInviteList;
|
|
89
|
-
private subscribeToOwnInviteList;
|
|
90
|
-
}
|
|
91
|
-
/** Delegate device. Has own identity key, waits for activation, checks revocation. */
|
|
92
|
-
export declare class DelegateDeviceManager implements IDeviceManager {
|
|
93
|
-
private readonly deviceId;
|
|
94
|
-
private readonly nostrSubscribe;
|
|
95
|
-
private readonly nostrPublish;
|
|
96
|
-
private readonly storage;
|
|
97
|
-
private readonly devicePublicKey;
|
|
98
|
-
private readonly devicePrivateKey;
|
|
99
|
-
private readonly ephemeralPublicKey;
|
|
100
|
-
private readonly ephemeralPrivateKey;
|
|
101
|
-
private readonly sharedSecret;
|
|
102
|
-
private ownerPubkeyFromActivation?;
|
|
103
|
-
private initialized;
|
|
104
|
-
private subscriptions;
|
|
105
|
-
private readonly storageVersion;
|
|
106
|
-
private get versionPrefix();
|
|
107
|
-
private constructor();
|
|
108
|
-
static create(options: DelegateDeviceOptions): CreateDelegateResult;
|
|
109
|
-
static restore(options: RestoreDelegateOptions): DelegateDeviceManager;
|
|
110
|
-
init(): Promise<void>;
|
|
111
|
-
getDeviceId(): string;
|
|
112
|
-
getIdentityPublicKey(): string;
|
|
113
|
-
getIdentityKey(): Uint8Array;
|
|
114
|
-
getEphemeralKeypair(): {
|
|
115
|
-
publicKey: string;
|
|
116
|
-
privateKey: Uint8Array;
|
|
117
|
-
};
|
|
118
|
-
getSharedSecret(): string;
|
|
119
|
-
getOwnerPublicKey(): string | null;
|
|
120
|
-
waitForActivation(timeoutMs?: number): Promise<string>;
|
|
121
|
-
isRevoked(): Promise<boolean>;
|
|
122
|
-
close(): void;
|
|
123
|
-
createSessionManager(sessionStorage?: StorageAdapter): SessionManager;
|
|
124
|
-
private ownerPubkeyKey;
|
|
125
|
-
private fetchInviteList;
|
|
126
|
-
}
|
|
127
|
-
//# sourceMappingURL=DeviceManager.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"DeviceManager.d.ts","sourceRoot":"","sources":["../src/DeviceManager.ts"],"names":[],"mappings":"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"}
|
package/dist/InviteList.d.ts
DELETED
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import { VerifiedEvent, UnsignedEvent } from "nostr-tools";
|
|
2
|
-
import { NostrSubscribe, Unsubscribe, EncryptFunction, DecryptFunction } from "./types";
|
|
3
|
-
import { Session } from "./Session";
|
|
4
|
-
export interface DeviceEntry {
|
|
5
|
-
ephemeralPublicKey: string;
|
|
6
|
-
/** Only stored locally, not published */
|
|
7
|
-
ephemeralPrivateKey?: Uint8Array;
|
|
8
|
-
sharedSecret: string;
|
|
9
|
-
deviceId: string;
|
|
10
|
-
deviceLabel: string;
|
|
11
|
-
createdAt: number;
|
|
12
|
-
/** Owner's pubkey for owner devices, delegate's own pubkey for delegate devices */
|
|
13
|
-
identityPubkey: string;
|
|
14
|
-
}
|
|
15
|
-
/**
|
|
16
|
-
* Manages a consolidated list of device invites (kind 10078).
|
|
17
|
-
* Single atomic event containing all device invites for a user.
|
|
18
|
-
* Uses union merge strategy for conflict resolution.
|
|
19
|
-
*/
|
|
20
|
-
export declare class InviteList {
|
|
21
|
-
readonly ownerPublicKey: string;
|
|
22
|
-
private devices;
|
|
23
|
-
private removedDeviceIds;
|
|
24
|
-
constructor(ownerPublicKey: string, devices?: DeviceEntry[], removedDeviceIds?: string[]);
|
|
25
|
-
createDevice(label: string, deviceId?: string): DeviceEntry;
|
|
26
|
-
addDevice(device: DeviceEntry): void;
|
|
27
|
-
removeDevice(deviceId: string): void;
|
|
28
|
-
getDevice(deviceId: string): DeviceEntry | undefined;
|
|
29
|
-
getAllDevices(): DeviceEntry[];
|
|
30
|
-
getRemovedDeviceIds(): string[];
|
|
31
|
-
updateDeviceLabel(deviceId: string, newLabel: string): void;
|
|
32
|
-
getEvent(): UnsignedEvent;
|
|
33
|
-
static fromEvent(event: VerifiedEvent): InviteList;
|
|
34
|
-
serialize(): string;
|
|
35
|
-
static deserialize(json: string): InviteList;
|
|
36
|
-
merge(other: InviteList): InviteList;
|
|
37
|
-
accept(deviceId: string, nostrSubscribe: NostrSubscribe, inviteePublicKey: string, encryptor: Uint8Array | EncryptFunction, inviteeDeviceId?: string): Promise<{
|
|
38
|
-
session: Session;
|
|
39
|
-
event: VerifiedEvent;
|
|
40
|
-
}>;
|
|
41
|
-
listen(decryptor: Uint8Array | DecryptFunction, nostrSubscribe: NostrSubscribe, onSession: (session: Session, identity: string, deviceId?: string, ourDeviceId?: string) => void): Unsubscribe;
|
|
42
|
-
}
|
|
43
|
-
//# sourceMappingURL=InviteList.d.ts.map
|
package/dist/InviteList.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"InviteList.d.ts","sourceRoot":"","sources":["../src/InviteList.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,aAAa,EAAE,aAAa,EAAe,MAAM,aAAa,CAAA;AACtF,OAAO,EACL,cAAc,EACd,WAAW,EACX,eAAe,EACf,eAAe,EAGhB,MAAM,SAAS,CAAA;AAChB,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAiCnC,MAAM,WAAW,WAAW;IAC1B,kBAAkB,EAAE,MAAM,CAAA;IAC1B,yCAAyC;IACzC,mBAAmB,CAAC,EAAE,UAAU,CAAA;IAChC,YAAY,EAAE,MAAM,CAAA;IACpB,QAAQ,EAAE,MAAM,CAAA;IAChB,WAAW,EAAE,MAAM,CAAA;IACnB,SAAS,EAAE,MAAM,CAAA;IACjB,mFAAmF;IACnF,cAAc,EAAE,MAAM,CAAA;CACvB;AAMD;;;;GAIG;AACH,qBAAa,UAAU;aAKH,cAAc,EAAE,MAAM;IAJxC,OAAO,CAAC,OAAO,CAAsC;IACrD,OAAO,CAAC,gBAAgB,CAAyB;gBAG/B,cAAc,EAAE,MAAM,EACtC,OAAO,GAAE,WAAW,EAAO,EAC3B,gBAAgB,GAAE,MAAM,EAAO;IAQjC,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,WAAW;IAa3D,SAAS,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI;IASpC,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAKpC,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS;IAIpD,aAAa,IAAI,WAAW,EAAE;IAI9B,mBAAmB,IAAI,MAAM,EAAE;IAI/B,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI;IAO3D,QAAQ,IAAI,aAAa;IA6BzB,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE,aAAa,GAAG,UAAU;IA0BlD,SAAS,IAAI,MAAM;IAenB,MAAM,CAAC,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU;IAY5C,KAAK,CAAC,KAAK,EAAE,UAAU,GAAG,UAAU;IA0B9B,MAAM,CACV,QAAQ,EAAE,MAAM,EAChB,cAAc,EAAE,cAAc,EAC9B,gBAAgB,EAAE,MAAM,EACxB,SAAS,EAAE,UAAU,GAAG,eAAe,EACvC,eAAe,CAAC,EAAE,MAAM,GACvB,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,KAAK,EAAE,aAAa,CAAA;KAAE,CAAC;IAoCtD,MAAM,CACJ,SAAS,EAAE,UAAU,GAAG,eAAe,EACvC,cAAc,EAAE,cAAc,EAC9B,SAAS,EAAE,CACT,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,MAAM,EAChB,QAAQ,CAAC,EAAE,MAAM,EACjB,WAAW,CAAC,EAAE,MAAM,KACjB,IAAI,GACR,WAAW;CAiDf"}
|
package/dist/UserRecord.d.ts
DELETED
|
@@ -1,117 +0,0 @@
|
|
|
1
|
-
import { Session } from './Session';
|
|
2
|
-
import { NostrSubscribe } from './types';
|
|
3
|
-
interface DeviceRecord {
|
|
4
|
-
deviceId: string;
|
|
5
|
-
publicKey: string;
|
|
6
|
-
activeSession?: Session;
|
|
7
|
-
inactiveSessions: Session[];
|
|
8
|
-
isStale: boolean;
|
|
9
|
-
staleTimestamp?: number;
|
|
10
|
-
lastActivity?: number;
|
|
11
|
-
}
|
|
12
|
-
/**
|
|
13
|
-
* Manages sessions for a single user across multiple devices
|
|
14
|
-
* Structure: UserRecord → DeviceRecord → Sessions
|
|
15
|
-
*/
|
|
16
|
-
export declare class UserRecord {
|
|
17
|
-
readonly userId: string;
|
|
18
|
-
private readonly nostrSubscribe;
|
|
19
|
-
private deviceRecords;
|
|
20
|
-
private isStale;
|
|
21
|
-
private staleTimestamp?;
|
|
22
|
-
constructor(userId: string, nostrSubscribe: NostrSubscribe);
|
|
23
|
-
/**
|
|
24
|
-
* Creates or updates a device record for this user
|
|
25
|
-
*/
|
|
26
|
-
upsertDevice(deviceId: string, publicKey: string): DeviceRecord;
|
|
27
|
-
/**
|
|
28
|
-
* Gets a device record by deviceId
|
|
29
|
-
*/
|
|
30
|
-
getDevice(deviceId: string): DeviceRecord | undefined;
|
|
31
|
-
/**
|
|
32
|
-
* Gets all device records for this user
|
|
33
|
-
*/
|
|
34
|
-
getAllDevices(): DeviceRecord[];
|
|
35
|
-
/**
|
|
36
|
-
* Gets all active (non-stale) device records
|
|
37
|
-
*/
|
|
38
|
-
getActiveDevices(): DeviceRecord[];
|
|
39
|
-
/**
|
|
40
|
-
* Removes a device record and closes all its sessions
|
|
41
|
-
*/
|
|
42
|
-
removeDevice(deviceId: string): boolean;
|
|
43
|
-
/**
|
|
44
|
-
* Adds or updates a session for a specific device
|
|
45
|
-
*/
|
|
46
|
-
upsertSession(deviceId: string, session: Session, publicKey?: string): void;
|
|
47
|
-
/**
|
|
48
|
-
* Gets the active session for a specific device
|
|
49
|
-
*/
|
|
50
|
-
getActiveSession(deviceId: string): Session | undefined;
|
|
51
|
-
/**
|
|
52
|
-
* Gets all sessions (active + inactive) for a specific device
|
|
53
|
-
*/
|
|
54
|
-
getDeviceSessions(deviceId: string): Session[];
|
|
55
|
-
/**
|
|
56
|
-
* Gets all active sessions across all devices for this user
|
|
57
|
-
*/
|
|
58
|
-
getActiveSessions(): Session[];
|
|
59
|
-
/**
|
|
60
|
-
* Gets all sessions (active + inactive) across all devices
|
|
61
|
-
*/
|
|
62
|
-
getAllSessions(): Session[];
|
|
63
|
-
/**
|
|
64
|
-
* Gets sessions that are ready to send messages
|
|
65
|
-
*/
|
|
66
|
-
getSendableSessions(): Session[];
|
|
67
|
-
/**
|
|
68
|
-
* Marks a specific device as stale
|
|
69
|
-
*/
|
|
70
|
-
markDeviceStale(deviceId: string): void;
|
|
71
|
-
/**
|
|
72
|
-
* Marks the entire user record as stale
|
|
73
|
-
*/
|
|
74
|
-
markUserStale(): void;
|
|
75
|
-
/**
|
|
76
|
-
* Removes stale devices and sessions older than maxLatency
|
|
77
|
-
*/
|
|
78
|
-
pruneStaleRecords(maxLatency: number): void;
|
|
79
|
-
/**
|
|
80
|
-
* Gets the most recently active device
|
|
81
|
-
*/
|
|
82
|
-
getMostActiveDevice(): DeviceRecord | undefined;
|
|
83
|
-
/**
|
|
84
|
-
* Gets the preferred session (from most active device)
|
|
85
|
-
*/
|
|
86
|
-
getPreferredSession(): Session | undefined;
|
|
87
|
-
/**
|
|
88
|
-
* Checks if this user has any active sessions
|
|
89
|
-
*/
|
|
90
|
-
hasActiveSessions(): boolean;
|
|
91
|
-
/**
|
|
92
|
-
* Gets total count of devices
|
|
93
|
-
*/
|
|
94
|
-
getDeviceCount(): number;
|
|
95
|
-
/**
|
|
96
|
-
* Gets total count of active sessions
|
|
97
|
-
*/
|
|
98
|
-
getActiveSessionCount(): number;
|
|
99
|
-
/**
|
|
100
|
-
* Cleanup when destroying the user record
|
|
101
|
-
*/
|
|
102
|
-
close(): void;
|
|
103
|
-
/**
|
|
104
|
-
* @deprecated Use upsertDevice instead
|
|
105
|
-
*/
|
|
106
|
-
conditionalUpdate(deviceId: string, publicKey: string): void;
|
|
107
|
-
/**
|
|
108
|
-
* @deprecated Use upsertSession instead
|
|
109
|
-
*/
|
|
110
|
-
insertSession(deviceId: string, session: Session): void;
|
|
111
|
-
/**
|
|
112
|
-
* Creates a new session for a device
|
|
113
|
-
*/
|
|
114
|
-
createSession(deviceId: string, sharedSecret: Uint8Array, ourCurrentPrivateKey: Uint8Array, isInitiator: boolean, name?: string): Session;
|
|
115
|
-
}
|
|
116
|
-
export {};
|
|
117
|
-
//# sourceMappingURL=UserRecord.d.ts.map
|
package/dist/UserRecord.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"UserRecord.d.ts","sourceRoot":"","sources":["../src/UserRecord.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAEzC,UAAU,YAAY;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,gBAAgB,EAAE,OAAO,EAAE,CAAC;IAC5B,OAAO,EAAE,OAAO,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;GAGG;AACH,qBAAa,UAAU;aAMH,MAAM,EAAE,MAAM;IAC9B,OAAO,CAAC,QAAQ,CAAC,cAAc;IANjC,OAAO,CAAC,aAAa,CAAwC;IAC7D,OAAO,CAAC,OAAO,CAAkB;IACjC,OAAO,CAAC,cAAc,CAAC,CAAS;gBAGd,MAAM,EAAE,MAAM,EACb,cAAc,EAAE,cAAc;IAQjD;;OAEG;IACI,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,YAAY;IAyBtE;;OAEG;IACI,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS;IAI5D;;OAEG;IACI,aAAa,IAAI,YAAY,EAAE;IAItC;;OAEG;IACI,gBAAgB,IAAI,YAAY,EAAE;IAKzC;;OAEG;IACI,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;IAe9C;;OAEG;IACI,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI;IAclF;;OAEG;IACI,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS;IAK9D;;OAEG;IACI,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,EAAE;IAYrD;;OAEG;IACI,iBAAiB,IAAI,OAAO,EAAE;IAsBrC;;OAEG;IACI,cAAc,IAAI,OAAO,EAAE;IAalC;;OAEG;IACI,mBAAmB,IAAI,OAAO,EAAE;IAUvC;;OAEG;IACI,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAQ9C;;OAEG;IACI,aAAa,IAAI,IAAI;IAK5B;;OAEG;IACI,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;IAsBlD;;OAEG;IACI,mBAAmB,IAAI,YAAY,GAAG,SAAS;IAWtD;;OAEG;IACI,mBAAmB,IAAI,OAAO,GAAG,SAAS;IAKjD;;OAEG;IACI,iBAAiB,IAAI,OAAO;IAInC;;OAEG;IACI,cAAc,IAAI,MAAM;IAI/B;;OAEG;IACI,qBAAqB,IAAI,MAAM;IAItC;;OAEG;IACI,KAAK,IAAI,IAAI;IAYpB;;OAEG;IACI,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI;IAInE;;OAEG;IACI,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI;IAI9D;;OAEG;IACI,aAAa,CAClB,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,UAAU,EACxB,oBAAoB,EAAE,UAAU,EAChC,WAAW,EAAE,OAAO,EACpB,IAAI,CAAC,EAAE,MAAM,GACZ,OAAO;CAkBX"}
|