@verbeth/sdk 0.1.4 → 0.1.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/README.md +20 -168
- package/dist/esm/src/addresses.d.ts +20 -0
- package/dist/esm/src/addresses.d.ts.map +1 -0
- package/dist/esm/src/addresses.js +33 -0
- package/dist/esm/src/client/HsrTagIndex.d.ts +77 -0
- package/dist/esm/src/client/HsrTagIndex.d.ts.map +1 -0
- package/dist/esm/src/client/HsrTagIndex.js +157 -0
- package/dist/esm/src/client/PendingManager.d.ts +65 -0
- package/dist/esm/src/client/PendingManager.d.ts.map +1 -0
- package/dist/esm/src/client/PendingManager.js +84 -0
- package/dist/esm/src/client/SessionManager.d.ts +65 -0
- package/dist/esm/src/client/SessionManager.d.ts.map +1 -0
- package/dist/esm/src/client/SessionManager.js +146 -0
- package/dist/esm/src/client/VerbethClient.d.ts +153 -99
- package/dist/esm/src/client/VerbethClient.d.ts.map +1 -1
- package/dist/esm/src/client/VerbethClient.js +429 -123
- package/dist/esm/src/client/VerbethClientBuilder.d.ts +105 -0
- package/dist/esm/src/client/VerbethClientBuilder.d.ts.map +1 -0
- package/dist/esm/src/client/VerbethClientBuilder.js +146 -0
- package/dist/esm/src/client/hsrMatcher.d.ts +22 -0
- package/dist/esm/src/client/hsrMatcher.d.ts.map +1 -0
- package/dist/esm/src/client/hsrMatcher.js +31 -0
- package/dist/esm/src/client/index.d.ts +6 -1
- package/dist/esm/src/client/index.d.ts.map +1 -1
- package/dist/esm/src/client/index.js +2 -0
- package/dist/esm/src/client/types.d.ts +151 -10
- package/dist/esm/src/client/types.d.ts.map +1 -1
- package/dist/esm/src/crypto(old).d.ts +46 -0
- package/dist/esm/src/crypto(old).d.ts.map +1 -0
- package/dist/esm/src/crypto(old).js +137 -0
- package/dist/esm/src/crypto.d.ts +7 -29
- package/dist/esm/src/crypto.d.ts.map +1 -1
- package/dist/esm/src/crypto.js +36 -72
- package/dist/esm/src/executor.d.ts +17 -18
- package/dist/esm/src/executor.d.ts.map +1 -1
- package/dist/esm/src/executor.js +54 -70
- package/dist/esm/src/handshake.d.ts +51 -0
- package/dist/esm/src/handshake.d.ts.map +1 -0
- package/dist/esm/src/handshake.js +105 -0
- package/dist/esm/src/identity.d.ts +24 -18
- package/dist/esm/src/identity.d.ts.map +1 -1
- package/dist/esm/src/identity.js +126 -31
- package/dist/esm/src/index.d.ts +11 -7
- package/dist/esm/src/index.d.ts.map +1 -1
- package/dist/esm/src/index.js +10 -7
- package/dist/esm/src/payload.d.ts +3 -30
- package/dist/esm/src/payload.d.ts.map +1 -1
- package/dist/esm/src/payload.js +3 -77
- package/dist/esm/src/pq/kem.d.ts +33 -0
- package/dist/esm/src/pq/kem.d.ts.map +1 -0
- package/dist/esm/src/pq/kem.js +40 -0
- package/dist/esm/src/ratchet/auth.d.ts +34 -0
- package/dist/esm/src/ratchet/auth.d.ts.map +1 -0
- package/dist/esm/src/ratchet/auth.js +88 -0
- package/dist/esm/src/ratchet/codec.d.ts +52 -0
- package/dist/esm/src/ratchet/codec.d.ts.map +1 -0
- package/dist/esm/src/ratchet/codec.js +127 -0
- package/dist/esm/src/ratchet/decrypt.d.ts +28 -0
- package/dist/esm/src/ratchet/decrypt.d.ts.map +1 -0
- package/dist/esm/src/ratchet/decrypt.js +255 -0
- package/dist/esm/src/ratchet/encrypt.d.ts +17 -0
- package/dist/esm/src/ratchet/encrypt.d.ts.map +1 -0
- package/dist/esm/src/ratchet/encrypt.js +78 -0
- package/dist/esm/src/ratchet/index.d.ts +8 -0
- package/dist/esm/src/ratchet/index.d.ts.map +1 -0
- package/dist/esm/src/ratchet/index.js +8 -0
- package/dist/esm/src/ratchet/kdf.d.ts +60 -0
- package/dist/esm/src/ratchet/kdf.d.ts.map +1 -0
- package/dist/esm/src/ratchet/kdf.js +91 -0
- package/dist/esm/src/ratchet/session.d.ts +43 -0
- package/dist/esm/src/ratchet/session.d.ts.map +1 -0
- package/dist/esm/src/ratchet/session.js +139 -0
- package/dist/esm/src/ratchet/types.d.ts +168 -0
- package/dist/esm/src/ratchet/types.d.ts.map +1 -0
- package/dist/esm/src/ratchet/types.js +27 -0
- package/dist/esm/src/safeSessionSigner.d.ts +35 -0
- package/dist/esm/src/safeSessionSigner.d.ts.map +1 -0
- package/dist/esm/src/safeSessionSigner.js +59 -0
- package/dist/esm/src/send.d.ts +32 -24
- package/dist/esm/src/send.d.ts.map +1 -1
- package/dist/esm/src/send.js +84 -39
- package/dist/esm/src/types.d.ts +8 -13
- package/dist/esm/src/types.d.ts.map +1 -1
- package/dist/esm/src/utils/safeSessionSigner.d.ts +23 -0
- package/dist/esm/src/utils/safeSessionSigner.d.ts.map +1 -0
- package/dist/esm/src/utils/safeSessionSigner.js +59 -0
- package/dist/esm/src/utils/txQueue.d.ts +12 -0
- package/dist/esm/src/utils/txQueue.d.ts.map +1 -0
- package/dist/esm/src/utils/txQueue.js +25 -0
- package/dist/esm/src/utils.d.ts +2 -3
- package/dist/esm/src/utils.d.ts.map +1 -1
- package/dist/esm/src/utils.js +5 -5
- package/dist/esm/src/verify.d.ts +9 -25
- package/dist/esm/src/verify.d.ts.map +1 -1
- package/dist/esm/src/verify.js +49 -50
- package/dist/src/addresses.d.ts +20 -0
- package/dist/src/addresses.d.ts.map +1 -0
- package/dist/src/addresses.js +33 -0
- package/dist/src/client/HsrTagIndex.d.ts +77 -0
- package/dist/src/client/HsrTagIndex.d.ts.map +1 -0
- package/dist/src/client/HsrTagIndex.js +157 -0
- package/dist/src/client/PendingManager.d.ts +65 -0
- package/dist/src/client/PendingManager.d.ts.map +1 -0
- package/dist/src/client/PendingManager.js +84 -0
- package/dist/src/client/SessionManager.d.ts +65 -0
- package/dist/src/client/SessionManager.d.ts.map +1 -0
- package/dist/src/client/SessionManager.js +146 -0
- package/dist/src/client/VerbethClient.d.ts +153 -99
- package/dist/src/client/VerbethClient.d.ts.map +1 -1
- package/dist/src/client/VerbethClient.js +429 -123
- package/dist/src/client/VerbethClientBuilder.d.ts +105 -0
- package/dist/src/client/VerbethClientBuilder.d.ts.map +1 -0
- package/dist/src/client/VerbethClientBuilder.js +146 -0
- package/dist/src/client/hsrMatcher.d.ts +22 -0
- package/dist/src/client/hsrMatcher.d.ts.map +1 -0
- package/dist/src/client/hsrMatcher.js +31 -0
- package/dist/src/client/index.d.ts +6 -1
- package/dist/src/client/index.d.ts.map +1 -1
- package/dist/src/client/index.js +2 -0
- package/dist/src/client/types.d.ts +151 -10
- package/dist/src/client/types.d.ts.map +1 -1
- package/dist/src/crypto(old).d.ts +46 -0
- package/dist/src/crypto(old).d.ts.map +1 -0
- package/dist/src/crypto(old).js +137 -0
- package/dist/src/crypto.d.ts +7 -29
- package/dist/src/crypto.d.ts.map +1 -1
- package/dist/src/crypto.js +36 -72
- package/dist/src/executor.d.ts +17 -18
- package/dist/src/executor.d.ts.map +1 -1
- package/dist/src/executor.js +54 -70
- package/dist/src/handshake.d.ts +51 -0
- package/dist/src/handshake.d.ts.map +1 -0
- package/dist/src/handshake.js +105 -0
- package/dist/src/identity.d.ts +24 -18
- package/dist/src/identity.d.ts.map +1 -1
- package/dist/src/identity.js +126 -31
- package/dist/src/index.d.ts +11 -7
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +10 -7
- package/dist/src/payload.d.ts +3 -30
- package/dist/src/payload.d.ts.map +1 -1
- package/dist/src/payload.js +3 -77
- package/dist/src/pq/kem.d.ts +33 -0
- package/dist/src/pq/kem.d.ts.map +1 -0
- package/dist/src/pq/kem.js +40 -0
- package/dist/src/ratchet/auth.d.ts +34 -0
- package/dist/src/ratchet/auth.d.ts.map +1 -0
- package/dist/src/ratchet/auth.js +88 -0
- package/dist/src/ratchet/codec.d.ts +52 -0
- package/dist/src/ratchet/codec.d.ts.map +1 -0
- package/dist/src/ratchet/codec.js +127 -0
- package/dist/src/ratchet/decrypt.d.ts +28 -0
- package/dist/src/ratchet/decrypt.d.ts.map +1 -0
- package/dist/src/ratchet/decrypt.js +255 -0
- package/dist/src/ratchet/encrypt.d.ts +17 -0
- package/dist/src/ratchet/encrypt.d.ts.map +1 -0
- package/dist/src/ratchet/encrypt.js +78 -0
- package/dist/src/ratchet/index.d.ts +8 -0
- package/dist/src/ratchet/index.d.ts.map +1 -0
- package/dist/src/ratchet/index.js +8 -0
- package/dist/src/ratchet/kdf.d.ts +60 -0
- package/dist/src/ratchet/kdf.d.ts.map +1 -0
- package/dist/src/ratchet/kdf.js +91 -0
- package/dist/src/ratchet/session.d.ts +43 -0
- package/dist/src/ratchet/session.d.ts.map +1 -0
- package/dist/src/ratchet/session.js +139 -0
- package/dist/src/ratchet/types.d.ts +168 -0
- package/dist/src/ratchet/types.d.ts.map +1 -0
- package/dist/src/ratchet/types.js +27 -0
- package/dist/src/safeSessionSigner.d.ts +35 -0
- package/dist/src/safeSessionSigner.d.ts.map +1 -0
- package/dist/src/safeSessionSigner.js +59 -0
- package/dist/src/send.d.ts +32 -24
- package/dist/src/send.d.ts.map +1 -1
- package/dist/src/send.js +84 -39
- package/dist/src/types.d.ts +8 -13
- package/dist/src/types.d.ts.map +1 -1
- package/dist/src/utils/safeSessionSigner.d.ts +23 -0
- package/dist/src/utils/safeSessionSigner.d.ts.map +1 -0
- package/dist/src/utils/safeSessionSigner.js +59 -0
- package/dist/src/utils/txQueue.d.ts +12 -0
- package/dist/src/utils/txQueue.d.ts.map +1 -0
- package/dist/src/utils/txQueue.js +25 -0
- package/dist/src/utils.d.ts +2 -3
- package/dist/src/utils.d.ts.map +1 -1
- package/dist/src/utils.js +5 -5
- package/dist/src/verify.d.ts +9 -25
- package/dist/src/verify.d.ts.map +1 -1
- package/dist/src/verify.js +49 -50
- package/package.json +2 -1
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Internal Session Coordinator.
|
|
3
|
+
*
|
|
4
|
+
* Handles:
|
|
5
|
+
* - Session caching for performance
|
|
6
|
+
* - Topic matching (current, next, previous)
|
|
7
|
+
* - Automatic topic promotion when next topic is used
|
|
8
|
+
* - Cache invalidation
|
|
9
|
+
*/
|
|
10
|
+
import { RatchetSession } from '../ratchet/types.js';
|
|
11
|
+
import { SessionStore } from './types.js';
|
|
12
|
+
export interface TopicLookupResult {
|
|
13
|
+
session: RatchetSession;
|
|
14
|
+
topicMatch: 'current' | 'next' | 'previous';
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Internal session manager that wraps a SessionStore with caching
|
|
18
|
+
* and topic promotion logic.
|
|
19
|
+
*/
|
|
20
|
+
export declare class SessionManager {
|
|
21
|
+
private store;
|
|
22
|
+
private cache;
|
|
23
|
+
constructor(store: SessionStore);
|
|
24
|
+
/**
|
|
25
|
+
* Get session by conversation ID, checking cache first.
|
|
26
|
+
*/
|
|
27
|
+
getByConversationId(conversationId: string): Promise<RatchetSession | null>;
|
|
28
|
+
/**
|
|
29
|
+
* Find session by inbound topic with automatic topic promotion.
|
|
30
|
+
*
|
|
31
|
+
* Checks topics in order:
|
|
32
|
+
* 1. currentTopicInbound - standard case
|
|
33
|
+
* 2. nextTopicInbound - DH ratchet advanced, promotes topics
|
|
34
|
+
* 3. previousTopicInbound - grace period for late messages
|
|
35
|
+
*
|
|
36
|
+
* @param topic - The topic to look up
|
|
37
|
+
* @returns Session and match type, or null if not found
|
|
38
|
+
*/
|
|
39
|
+
getByInboundTopic(topic: string): Promise<TopicLookupResult | null>;
|
|
40
|
+
/**
|
|
41
|
+
* Update session in cache and persist to store.
|
|
42
|
+
*/
|
|
43
|
+
save(session: RatchetSession): Promise<void>;
|
|
44
|
+
/**
|
|
45
|
+
* Update cache without persisting (for batch operations).
|
|
46
|
+
*/
|
|
47
|
+
updateCache(session: RatchetSession): void;
|
|
48
|
+
/**
|
|
49
|
+
* Persist all cached sessions to store.
|
|
50
|
+
*/
|
|
51
|
+
flushCache(): Promise<void>;
|
|
52
|
+
/**
|
|
53
|
+
* Invalidate cache entry (e.g., on session reset).
|
|
54
|
+
*/
|
|
55
|
+
invalidate(conversationId: string): void;
|
|
56
|
+
clearCache(): void;
|
|
57
|
+
getCacheSize(): number;
|
|
58
|
+
isCached(conversationId: string): boolean;
|
|
59
|
+
/**
|
|
60
|
+
* Promote next topics to current (internal helper).
|
|
61
|
+
* Called when a message arrives on nextTopicInbound.
|
|
62
|
+
*/
|
|
63
|
+
private promoteTopics;
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=SessionManager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SessionManager.d.ts","sourceRoot":"","sources":["../../../../src/client/SessionManager.ts"],"names":[],"mappings":"AAEA;;;;;;;;GAQG;AAEH,OAAO,EAAE,cAAc,EAA8B,MAAM,qBAAqB,CAAC;AACjF,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE1C,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,cAAc,CAAC;IACxB,UAAU,EAAE,SAAS,GAAG,MAAM,GAAG,UAAU,CAAC;CAC7C;AAED;;;GAGG;AACH,qBAAa,cAAc;IAGb,OAAO,CAAC,KAAK;IAFzB,OAAO,CAAC,KAAK,CAAqC;gBAE9B,KAAK,EAAE,YAAY;IAMvC;;OAEG;IACG,mBAAmB,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;IAajF;;;;;;;;;;OAUG;IACG,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC;IA6CzE;;OAEG;IACG,IAAI,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAKlD;;OAEG;IACH,WAAW,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI;IAI1C;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IASjC;;OAEG;IACH,UAAU,CAAC,cAAc,EAAE,MAAM,GAAG,IAAI;IAIxC,UAAU,IAAI,IAAI;IAIlB,YAAY,IAAI,MAAM;IAItB,QAAQ,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO;IAIzC;;;OAGG;IACH,OAAO,CAAC,aAAa;CAqBtB"}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
// packages/sdk/src/client/SessionManager.ts
|
|
2
|
+
/**
|
|
3
|
+
* Internal Session Coordinator.
|
|
4
|
+
*
|
|
5
|
+
* Handles:
|
|
6
|
+
* - Session caching for performance
|
|
7
|
+
* - Topic matching (current, next, previous)
|
|
8
|
+
* - Automatic topic promotion when next topic is used
|
|
9
|
+
* - Cache invalidation
|
|
10
|
+
*/
|
|
11
|
+
import { TOPIC_TRANSITION_WINDOW_MS } from '../ratchet/types.js';
|
|
12
|
+
/**
|
|
13
|
+
* Internal session manager that wraps a SessionStore with caching
|
|
14
|
+
* and topic promotion logic.
|
|
15
|
+
*/
|
|
16
|
+
export class SessionManager {
|
|
17
|
+
constructor(store) {
|
|
18
|
+
this.store = store;
|
|
19
|
+
this.cache = new Map();
|
|
20
|
+
}
|
|
21
|
+
// ===========================================================================
|
|
22
|
+
// Session Retrieval
|
|
23
|
+
// ===========================================================================
|
|
24
|
+
/**
|
|
25
|
+
* Get session by conversation ID, checking cache first.
|
|
26
|
+
*/
|
|
27
|
+
async getByConversationId(conversationId) {
|
|
28
|
+
const cached = this.cache.get(conversationId);
|
|
29
|
+
if (cached) {
|
|
30
|
+
return cached;
|
|
31
|
+
}
|
|
32
|
+
const session = await this.store.get(conversationId);
|
|
33
|
+
if (session) {
|
|
34
|
+
this.cache.set(conversationId, session);
|
|
35
|
+
}
|
|
36
|
+
return session;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Find session by inbound topic with automatic topic promotion.
|
|
40
|
+
*
|
|
41
|
+
* Checks topics in order:
|
|
42
|
+
* 1. currentTopicInbound - standard case
|
|
43
|
+
* 2. nextTopicInbound - DH ratchet advanced, promotes topics
|
|
44
|
+
* 3. previousTopicInbound - grace period for late messages
|
|
45
|
+
*
|
|
46
|
+
* @param topic - The topic to look up
|
|
47
|
+
* @returns Session and match type, or null if not found
|
|
48
|
+
*/
|
|
49
|
+
async getByInboundTopic(topic) {
|
|
50
|
+
const topicLower = topic.toLowerCase();
|
|
51
|
+
const session = await this.store.getByInboundTopic(topic);
|
|
52
|
+
if (!session) {
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
// Check cache for more recent state (e.g. for batched operations)
|
|
56
|
+
const cached = this.cache.get(session.conversationId);
|
|
57
|
+
let workingSession = cached || session;
|
|
58
|
+
if (workingSession.currentTopicInbound.toLowerCase() === topicLower) {
|
|
59
|
+
if (!cached) {
|
|
60
|
+
this.cache.set(workingSession.conversationId, workingSession);
|
|
61
|
+
}
|
|
62
|
+
return { session: workingSession, topicMatch: 'current' };
|
|
63
|
+
}
|
|
64
|
+
if (workingSession.nextTopicInbound?.toLowerCase() === topicLower) {
|
|
65
|
+
// Promote next topics to current
|
|
66
|
+
workingSession = this.promoteTopics(workingSession);
|
|
67
|
+
this.cache.set(workingSession.conversationId, workingSession);
|
|
68
|
+
return { session: workingSession, topicMatch: 'next' };
|
|
69
|
+
}
|
|
70
|
+
if (workingSession.previousTopicInbound?.toLowerCase() === topicLower &&
|
|
71
|
+
workingSession.previousTopicExpiry &&
|
|
72
|
+
Date.now() < workingSession.previousTopicExpiry) {
|
|
73
|
+
if (!cached) {
|
|
74
|
+
this.cache.set(workingSession.conversationId, workingSession);
|
|
75
|
+
}
|
|
76
|
+
return { session: workingSession, topicMatch: 'previous' };
|
|
77
|
+
}
|
|
78
|
+
// Topic found in store but doesn't match current session state (this shouldn't happen normally, but handle gracefully)
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
// ===========================================================================
|
|
82
|
+
// Session Persistence
|
|
83
|
+
// ===========================================================================
|
|
84
|
+
/**
|
|
85
|
+
* Update session in cache and persist to store.
|
|
86
|
+
*/
|
|
87
|
+
async save(session) {
|
|
88
|
+
this.cache.set(session.conversationId, session);
|
|
89
|
+
await this.store.save(session);
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Update cache without persisting (for batch operations).
|
|
93
|
+
*/
|
|
94
|
+
updateCache(session) {
|
|
95
|
+
this.cache.set(session.conversationId, session);
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Persist all cached sessions to store.
|
|
99
|
+
*/
|
|
100
|
+
async flushCache() {
|
|
101
|
+
const saves = Array.from(this.cache.values()).map(s => this.store.save(s));
|
|
102
|
+
await Promise.all(saves);
|
|
103
|
+
}
|
|
104
|
+
// ===========================================================================
|
|
105
|
+
// Cache Management
|
|
106
|
+
// ===========================================================================
|
|
107
|
+
/**
|
|
108
|
+
* Invalidate cache entry (e.g., on session reset).
|
|
109
|
+
*/
|
|
110
|
+
invalidate(conversationId) {
|
|
111
|
+
this.cache.delete(conversationId);
|
|
112
|
+
}
|
|
113
|
+
clearCache() {
|
|
114
|
+
this.cache.clear();
|
|
115
|
+
}
|
|
116
|
+
getCacheSize() {
|
|
117
|
+
return this.cache.size;
|
|
118
|
+
}
|
|
119
|
+
isCached(conversationId) {
|
|
120
|
+
return this.cache.has(conversationId);
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Promote next topics to current (internal helper).
|
|
124
|
+
* Called when a message arrives on nextTopicInbound.
|
|
125
|
+
*/
|
|
126
|
+
promoteTopics(session) {
|
|
127
|
+
if (!session.nextTopicInbound || !session.nextTopicOutbound) {
|
|
128
|
+
return session;
|
|
129
|
+
}
|
|
130
|
+
return {
|
|
131
|
+
...session,
|
|
132
|
+
// Move current to previous (for grace period)
|
|
133
|
+
previousTopicInbound: session.currentTopicInbound,
|
|
134
|
+
previousTopicExpiry: Date.now() + TOPIC_TRANSITION_WINDOW_MS,
|
|
135
|
+
// Promote next to current
|
|
136
|
+
currentTopicInbound: session.nextTopicInbound,
|
|
137
|
+
currentTopicOutbound: session.nextTopicOutbound,
|
|
138
|
+
// Clear next (will be computed on next DH ratchet)
|
|
139
|
+
nextTopicInbound: undefined,
|
|
140
|
+
nextTopicOutbound: undefined,
|
|
141
|
+
// Increment epoch
|
|
142
|
+
topicEpoch: session.topicEpoch + 1,
|
|
143
|
+
updatedAt: Date.now(),
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
}
|
|
@@ -1,134 +1,188 @@
|
|
|
1
|
-
import type { VerbethClientConfig, HandshakeResult, HandshakeResponseResult } from './types.js';
|
|
2
1
|
import type { IExecutor } from '../executor.js';
|
|
3
|
-
import type { IdentityKeyPair } from '../types.js';
|
|
2
|
+
import type { IdentityKeyPair, IdentityProof } from '../types.js';
|
|
4
3
|
import * as crypto from '../crypto.js';
|
|
5
4
|
import * as payload from '../payload.js';
|
|
6
5
|
import * as verify from '../verify.js';
|
|
7
6
|
import * as utils from '../utils.js';
|
|
8
7
|
import * as identity from '../identity.js';
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
* 'Hello Bob!'
|
|
29
|
-
* );
|
|
30
|
-
*
|
|
31
|
-
* // Send a message
|
|
32
|
-
* await client.sendMessage(
|
|
33
|
-
* contact.topicOutbound,
|
|
34
|
-
* contact.identityPubKey,
|
|
35
|
-
* 'Hello again!'
|
|
36
|
-
* );
|
|
37
|
-
* ```
|
|
38
|
-
*/
|
|
8
|
+
import * as ratchet from '../ratchet/index.js';
|
|
9
|
+
import type { RatchetSession } from '../ratchet/types.js';
|
|
10
|
+
import type { VerbethClientConfig, HandshakeResult, HandshakeResponseResult, SessionStore, PendingStore, PreparedMessage, DecryptedMessage, SendResult, ConfirmResult, CreateInitiatorSessionFromHsrParams } from './types.js';
|
|
11
|
+
export interface CreateInitiatorSessionParams {
|
|
12
|
+
contactAddress: string;
|
|
13
|
+
initiatorEphemeralSecret: Uint8Array;
|
|
14
|
+
responderEphemeralPubKey: Uint8Array;
|
|
15
|
+
inResponseToTag: `0x${string}`;
|
|
16
|
+
kemCiphertext?: Uint8Array;
|
|
17
|
+
initiatorKemSecret?: Uint8Array;
|
|
18
|
+
}
|
|
19
|
+
export interface CreateResponderSessionParams {
|
|
20
|
+
contactAddress: string;
|
|
21
|
+
responderEphemeralSecret: Uint8Array;
|
|
22
|
+
responderEphemeralPublic: Uint8Array;
|
|
23
|
+
initiatorEphemeralPubKey: Uint8Array;
|
|
24
|
+
salt: Uint8Array;
|
|
25
|
+
kemSharedSecret?: Uint8Array;
|
|
26
|
+
}
|
|
39
27
|
export declare class VerbethClient {
|
|
40
28
|
private readonly executor;
|
|
41
29
|
private readonly identityKeyPair;
|
|
42
30
|
private readonly identityProof;
|
|
43
31
|
private readonly signer;
|
|
44
32
|
private readonly address;
|
|
33
|
+
private readonly callbacks?;
|
|
34
|
+
private sessionManager?;
|
|
35
|
+
private pendingManager?;
|
|
36
|
+
constructor(config: VerbethClientConfig);
|
|
45
37
|
/**
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
* @param config - Client configuration with session-level parameters
|
|
38
|
+
* to be called before using prepareMessage/decryptMessage/sendMessage.
|
|
49
39
|
*/
|
|
50
|
-
|
|
40
|
+
setSessionStore(store: SessionStore): void;
|
|
51
41
|
/**
|
|
52
|
-
*
|
|
42
|
+
* to be called before using sendMessage/confirmTx/revertTx.
|
|
43
|
+
*/
|
|
44
|
+
setPendingStore(store: PendingStore): void;
|
|
45
|
+
hasSessionStore(): boolean;
|
|
46
|
+
hasPendingStore(): boolean;
|
|
47
|
+
/**
|
|
48
|
+
* Initiates a handshake with a recipient.
|
|
53
49
|
*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
50
|
+
* Generates an ephemeral keypair and ML-KEM keypair for this handshake.
|
|
51
|
+
* Both secretKeys must be stored for ratchet session initialization
|
|
52
|
+
* when the response arrives.
|
|
56
53
|
*
|
|
57
54
|
* @param recipientAddress - Blockchain address of the recipient
|
|
58
55
|
* @param message - Plaintext message to include in the handshake
|
|
59
|
-
* @returns Transaction response
|
|
60
|
-
*
|
|
61
|
-
* @example
|
|
62
|
-
* ```typescript
|
|
63
|
-
* const { tx, ephemeralKeyPair } = await client.sendHandshake(
|
|
64
|
-
* '0xBob...',
|
|
65
|
-
* 'Hi Bob!'
|
|
66
|
-
* );
|
|
67
|
-
*
|
|
68
|
-
* // Store ephemeralKeyPair.secretKey to decrypt Bob's response
|
|
69
|
-
* await storage.saveContact({
|
|
70
|
-
* address: '0xBob...',
|
|
71
|
-
* ephemeralKey: ephemeralKeyPair.secretKey,
|
|
72
|
-
* // ...
|
|
73
|
-
* });
|
|
74
|
-
* ```
|
|
56
|
+
* @returns Transaction response, ephemeral keypair, and KEM keypair
|
|
75
57
|
*/
|
|
76
58
|
sendHandshake(recipientAddress: string, message: string): Promise<HandshakeResult>;
|
|
77
59
|
/**
|
|
78
|
-
* Accepts a handshake from an initiator
|
|
79
|
-
*
|
|
80
|
-
*
|
|
81
|
-
*
|
|
82
|
-
*
|
|
83
|
-
*
|
|
84
|
-
*
|
|
85
|
-
*
|
|
86
|
-
*
|
|
87
|
-
* @
|
|
88
|
-
*
|
|
89
|
-
*
|
|
90
|
-
* handshake.ephemeralPubKey,
|
|
91
|
-
* handshake.identityPubKey,
|
|
92
|
-
* 'Hello Alice!'
|
|
93
|
-
* );
|
|
94
|
-
*
|
|
95
|
-
* // Store the topics for future messaging
|
|
96
|
-
* await storage.saveContact({
|
|
97
|
-
* address: handshake.sender,
|
|
98
|
-
* topicOutbound: duplexTopics.topicIn, // Responder writes to topicIn
|
|
99
|
-
* topicInbound: duplexTopics.topicOut, // Responder reads from topicOut
|
|
100
|
-
* // ...
|
|
101
|
-
* });
|
|
102
|
-
* ```
|
|
60
|
+
* Accepts a handshake from an initiator.
|
|
61
|
+
*
|
|
62
|
+
* Derives topics from ephemeral DH shared secret (same approach
|
|
63
|
+
* as post-handshake topic ratcheting). Returns topicOutbound/topicInbound
|
|
64
|
+
* directly instead of duplexTopics structure.
|
|
65
|
+
*
|
|
66
|
+
* Supports PQ-hybrid: if initiator includes ML-KEM public key (1216 bytes),
|
|
67
|
+
* performs KEM encapsulation and returns kemSharedSecret.
|
|
68
|
+
*
|
|
69
|
+
* @param initiatorEphemeralPubKey - Initiator's ephemeral key (32 bytes X25519 or 1216 bytes with KEM)
|
|
70
|
+
* @param note - Response message to send back
|
|
71
|
+
* @returns Transaction, derived topics, ephemeral keys for ratchet, and KEM shared secret
|
|
103
72
|
*/
|
|
104
|
-
acceptHandshake(initiatorEphemeralPubKey: Uint8Array,
|
|
73
|
+
acceptHandshake(initiatorEphemeralPubKey: Uint8Array, note: string): Promise<HandshakeResponseResult>;
|
|
105
74
|
/**
|
|
106
|
-
*
|
|
107
|
-
*
|
|
108
|
-
*
|
|
109
|
-
*
|
|
110
|
-
*
|
|
111
|
-
*
|
|
112
|
-
*
|
|
113
|
-
*
|
|
114
|
-
*
|
|
115
|
-
* @
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
*
|
|
120
|
-
*
|
|
121
|
-
*
|
|
122
|
-
*
|
|
75
|
+
* Create a ratchet session as the handshake initiator.
|
|
76
|
+
*
|
|
77
|
+
* Call this after receiving and validating a handshake response.
|
|
78
|
+
* Handles topic derivation from ephemeral DH internally.
|
|
79
|
+
*
|
|
80
|
+
* If KEM ciphertext and secret are provided (PQ-hybrid), decapsulates
|
|
81
|
+
* to derive hybrid shared secret for post-quantum security.
|
|
82
|
+
*
|
|
83
|
+
* @param params - Session creation parameters
|
|
84
|
+
* @returns Ready-to-save RatchetSession
|
|
85
|
+
*/
|
|
86
|
+
createInitiatorSession(params: CreateInitiatorSessionParams): RatchetSession;
|
|
87
|
+
/**
|
|
88
|
+
* Create a ratchet session as the handshake responder.
|
|
89
|
+
*
|
|
90
|
+
* Call this after sending a handshake response.
|
|
91
|
+
* Handles topic derivation from ephemeral DH internally.
|
|
92
|
+
*
|
|
93
|
+
* If kemSharedSecret is provided (PQ-hybrid), uses hybrid KDF
|
|
94
|
+
* for post-quantum security.
|
|
95
|
+
*
|
|
96
|
+
* @param params - Session creation parameters
|
|
97
|
+
* @returns Ready-to-save RatchetSession
|
|
98
|
+
*/
|
|
99
|
+
createResponderSession(params: CreateResponderSessionParams): RatchetSession;
|
|
100
|
+
/**
|
|
101
|
+
* Accepting a structured HSR event object instead of individual parameters scattered across variables.
|
|
102
|
+
*/
|
|
103
|
+
createInitiatorSessionFromHsr(params: CreateInitiatorSessionFromHsrParams): RatchetSession;
|
|
104
|
+
private deriveTopicsFromDH;
|
|
105
|
+
/**
|
|
106
|
+
* Prepare a message for sending (encrypt without submitting).
|
|
107
|
+
*
|
|
108
|
+
* Two-phase commit pattern:
|
|
109
|
+
* 1. prepareMessage() - encrypts and persists session state immediately
|
|
110
|
+
* 2. Submit transaction using prepared.payload and prepared.topic
|
|
111
|
+
* 3. On confirmation, call confirmTx() to clean up pending record
|
|
112
|
+
*
|
|
113
|
+
* Session state is committed immediately for forward secrecy.
|
|
114
|
+
* If tx fails, the ratchet slot is "burned" (receiver handles via skip keys).
|
|
115
|
+
*
|
|
116
|
+
* @param conversationId - The conversation to send in
|
|
117
|
+
* @param plaintext - Message text to encrypt
|
|
118
|
+
* @returns PreparedMessage with payload ready for on-chain submission
|
|
119
|
+
*/
|
|
120
|
+
prepareMessage(conversationId: string, plaintext: string): Promise<PreparedMessage>;
|
|
121
|
+
commitMessage(_prepared: PreparedMessage): Promise<void>;
|
|
122
|
+
/**
|
|
123
|
+
* Decrypt an incoming message.
|
|
124
|
+
*
|
|
125
|
+
* Handles:
|
|
126
|
+
* - Topic routing (current, next, previous)
|
|
127
|
+
* - Signature verification (DoS protection)
|
|
128
|
+
* - Ratchet decryption
|
|
129
|
+
* - Session state updates
|
|
130
|
+
* - Automatic topic promotion
|
|
131
|
+
*
|
|
132
|
+
* @param topic - The topic the message arrived on
|
|
133
|
+
* @param payload - Raw message payload (Uint8Array)
|
|
134
|
+
* @param senderSigningKey - Sender's Ed25519 signing public key
|
|
135
|
+
* @param isOwnMessage - Whether this is our own outbound message (echo)
|
|
136
|
+
* @returns DecryptedMessage or null if decryption fails
|
|
137
|
+
*/
|
|
138
|
+
decryptMessage(topic: string, payload: Uint8Array, senderSigningKey: Uint8Array, isOwnMessage?: boolean): Promise<DecryptedMessage | null>;
|
|
139
|
+
/**
|
|
140
|
+
* Send a message with full lifecycle management.
|
|
141
|
+
*
|
|
142
|
+
* This is the high-level API that handles:
|
|
143
|
+
* 1. Encryption (with session commit)
|
|
144
|
+
* 2. Pending record creation
|
|
145
|
+
* 3. Transaction submission
|
|
146
|
+
* 4. Status tracking
|
|
147
|
+
*
|
|
148
|
+
* After calling this, wait for on-chain confirmation and call confirmTx().
|
|
149
|
+
*
|
|
150
|
+
* @param conversationId - Conversation to send in
|
|
151
|
+
* @param plaintext - Message text
|
|
152
|
+
* @returns SendResult with txHash and metadata
|
|
153
|
+
*/
|
|
154
|
+
sendMessage(conversationId: string, plaintext: string): Promise<SendResult>;
|
|
155
|
+
/**
|
|
156
|
+
* Confirm a transaction after on-chain confirmation.
|
|
157
|
+
* Call this when you see your MessageSent event on-chain.
|
|
158
|
+
*
|
|
159
|
+
* @param txHash - Transaction hash to confirm
|
|
160
|
+
* @returns ConfirmResult or null if not found
|
|
161
|
+
*/
|
|
162
|
+
confirmTx(txHash: string): Promise<ConfirmResult | null>;
|
|
163
|
+
/**
|
|
164
|
+
* Handle transaction failure/revert.
|
|
165
|
+
*
|
|
166
|
+
* The ratchet slot is already burned (session was persisted in prepareMessage).
|
|
167
|
+
* This just cleans up the pending record.
|
|
168
|
+
*
|
|
169
|
+
* @param txHash - Transaction hash that failed
|
|
123
170
|
*/
|
|
124
|
-
|
|
171
|
+
revertTx(txHash: string): Promise<void>;
|
|
172
|
+
invalidateSessionCache(conversationId: string): void;
|
|
173
|
+
clearSessionCache(): void;
|
|
174
|
+
getSession(conversationId: string): Promise<RatchetSession | null>;
|
|
125
175
|
get crypto(): typeof crypto;
|
|
126
176
|
get payload(): typeof payload;
|
|
127
177
|
get verify(): typeof verify;
|
|
128
178
|
get utils(): typeof utils;
|
|
129
179
|
get identity(): typeof identity;
|
|
180
|
+
get ratchet(): typeof ratchet;
|
|
130
181
|
get executorInstance(): IExecutor;
|
|
131
182
|
get identityKeyPairInstance(): IdentityKeyPair;
|
|
132
183
|
get userAddress(): string;
|
|
184
|
+
get identityProofInstance(): IdentityProof;
|
|
185
|
+
private generatePreparedId;
|
|
186
|
+
private serializeSessionInfo;
|
|
133
187
|
}
|
|
134
188
|
//# sourceMappingURL=VerbethClient.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VerbethClient.d.ts","sourceRoot":"","sources":["../../../../src/client/VerbethClient.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"VerbethClient.d.ts","sourceRoot":"","sources":["../../../../src/client/VerbethClient.ts"],"names":[],"mappings":"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"}
|