wowok 2.1.41 → 2.2.1

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.
Files changed (69) hide show
  1. package/dist/cjs/w/call/guard.d.ts +2 -0
  2. package/dist/cjs/w/call/guard.js +1 -1
  3. package/dist/cjs/w/call/repository.js +1 -1
  4. package/dist/cjs/w/call/util.js +1 -1
  5. package/dist/cjs/w/messenger/messenger-manager.js +1 -1
  6. package/dist/cjs/w/messenger/messenger.js +1 -1
  7. package/dist/cjs/w/messenger/pq/crypto.d.ts +39 -0
  8. package/dist/cjs/w/messenger/pq/crypto.js +1 -0
  9. package/dist/cjs/w/messenger/pq/erasure.d.ts +17 -0
  10. package/dist/cjs/w/messenger/pq/erasure.js +1 -0
  11. package/dist/cjs/w/messenger/pq/index.d.ts +9 -0
  12. package/dist/cjs/w/messenger/pq/index.js +1 -0
  13. package/dist/cjs/w/messenger/pq/keycombiner.d.ts +1 -0
  14. package/dist/cjs/w/messenger/pq/keycombiner.js +1 -0
  15. package/dist/cjs/w/messenger/pq/pqxdh.d.ts +41 -0
  16. package/dist/cjs/w/messenger/pq/pqxdh.js +1 -0
  17. package/dist/cjs/w/messenger/pq/ratchet.d.ts +12 -0
  18. package/dist/cjs/w/messenger/pq/ratchet.js +1 -0
  19. package/dist/cjs/w/messenger/pq/session.d.ts +39 -0
  20. package/dist/cjs/w/messenger/pq/session.js +1 -0
  21. package/dist/cjs/w/messenger/pq/spqr.d.ts +23 -0
  22. package/dist/cjs/w/messenger/pq/spqr.js +1 -0
  23. package/dist/cjs/w/messenger/pq/store-adapter.d.ts +33 -0
  24. package/dist/cjs/w/messenger/pq/store-adapter.js +1 -0
  25. package/dist/cjs/w/messenger/pq/types.d.ts +181 -0
  26. package/dist/cjs/w/messenger/pq/types.js +1 -0
  27. package/dist/cjs/w/messenger/session.d.ts +15 -16
  28. package/dist/cjs/w/messenger/session.js +1 -1
  29. package/dist/cjs/w/messenger/storage.d.ts +2 -0
  30. package/dist/cjs/w/messenger/storage.js +1 -1
  31. package/dist/cjs/w/messenger/types.d.ts +15 -1
  32. package/dist/cjs/w/messenger/types.js +1 -1
  33. package/dist/cjs/w/messenger/utils.js +1 -1
  34. package/dist/cjs/w/query/object.js +1 -1
  35. package/dist/esm/w/call/guard.d.ts +2 -0
  36. package/dist/esm/w/call/guard.js +1 -1
  37. package/dist/esm/w/call/repository.js +1 -1
  38. package/dist/esm/w/call/util.js +1 -1
  39. package/dist/esm/w/messenger/messenger-manager.js +1 -1
  40. package/dist/esm/w/messenger/messenger.js +1 -1
  41. package/dist/esm/w/messenger/pq/crypto.d.ts +39 -0
  42. package/dist/esm/w/messenger/pq/crypto.js +1 -0
  43. package/dist/esm/w/messenger/pq/erasure.d.ts +17 -0
  44. package/dist/esm/w/messenger/pq/erasure.js +1 -0
  45. package/dist/esm/w/messenger/pq/index.d.ts +9 -0
  46. package/dist/esm/w/messenger/pq/index.js +1 -0
  47. package/dist/esm/w/messenger/pq/keycombiner.d.ts +1 -0
  48. package/dist/esm/w/messenger/pq/keycombiner.js +1 -0
  49. package/dist/esm/w/messenger/pq/pqxdh.d.ts +41 -0
  50. package/dist/esm/w/messenger/pq/pqxdh.js +1 -0
  51. package/dist/esm/w/messenger/pq/ratchet.d.ts +12 -0
  52. package/dist/esm/w/messenger/pq/ratchet.js +1 -0
  53. package/dist/esm/w/messenger/pq/session.d.ts +39 -0
  54. package/dist/esm/w/messenger/pq/session.js +1 -0
  55. package/dist/esm/w/messenger/pq/spqr.d.ts +23 -0
  56. package/dist/esm/w/messenger/pq/spqr.js +1 -0
  57. package/dist/esm/w/messenger/pq/store-adapter.d.ts +33 -0
  58. package/dist/esm/w/messenger/pq/store-adapter.js +1 -0
  59. package/dist/esm/w/messenger/pq/types.d.ts +181 -0
  60. package/dist/esm/w/messenger/pq/types.js +1 -0
  61. package/dist/esm/w/messenger/session.d.ts +15 -16
  62. package/dist/esm/w/messenger/session.js +1 -1
  63. package/dist/esm/w/messenger/storage.d.ts +2 -0
  64. package/dist/esm/w/messenger/storage.js +1 -1
  65. package/dist/esm/w/messenger/types.d.ts +15 -1
  66. package/dist/esm/w/messenger/types.js +1 -1
  67. package/dist/esm/w/messenger/utils.js +1 -1
  68. package/dist/esm/w/query/object.js +1 -1
  69. package/package.json +43 -3
@@ -0,0 +1,181 @@
1
+ export interface KeyPair {
2
+ publicKey: Uint8Array;
3
+ secretKey: Uint8Array;
4
+ }
5
+ export interface X25519KeyPair {
6
+ publicKey: Uint8Array;
7
+ privateKey: Uint8Array;
8
+ }
9
+ export interface Ed25519KeyPair {
10
+ publicKey: Uint8Array;
11
+ privateKey: Uint8Array;
12
+ }
13
+ export interface MLKEMKeyPair {
14
+ publicKey: Uint8Array;
15
+ secretKey: Uint8Array;
16
+ }
17
+ export interface PQPreKeyBundle {
18
+ registrationId: number;
19
+ deviceId: number;
20
+ identityKey: Uint8Array;
21
+ ed25519PublicKey: Uint8Array;
22
+ signedPreKey: {
23
+ keyId: number;
24
+ publicKey: Uint8Array;
25
+ signature: Uint8Array;
26
+ };
27
+ oneTimePreKey?: {
28
+ keyId: number;
29
+ publicKey: Uint8Array;
30
+ };
31
+ pqPreKey: {
32
+ keyId: number;
33
+ publicKey: Uint8Array;
34
+ signature: Uint8Array;
35
+ };
36
+ }
37
+ export interface PQXDHResult {
38
+ rootKey: Uint8Array;
39
+ chainKey: Uint8Array;
40
+ ourDHKeyPair: X25519KeyPair;
41
+ peerDHPublicKey: Uint8Array;
42
+ peerIdentityKey: Uint8Array;
43
+ pqSharedSecret: Uint8Array;
44
+ }
45
+ export interface RatchetState {
46
+ rootKey: Uint8Array;
47
+ sendingChainKey: Uint8Array;
48
+ sendingMessageCount: number;
49
+ receivingChainKey: Uint8Array;
50
+ receivingMessageCount: number;
51
+ ourDHKeyPair: X25519KeyPair;
52
+ peerDHPublicKey: Uint8Array | null;
53
+ previousSendingCount: number;
54
+ skipMessageKeys: Map<string, Uint8Array>;
55
+ }
56
+ export interface EncryptedMessage {
57
+ type: MessageType;
58
+ body: Uint8Array;
59
+ registrationId?: number;
60
+ }
61
+ export declare enum MessageType {
62
+ PREKEY_MESSAGE = 3,
63
+ NORMAL_MESSAGE = 1
64
+ }
65
+ export type SPQRPhase = "idle" | "sending_pk" | "sending_ct_no_pk" | "sending_ct_pk" | "done";
66
+ export type SPQRReceivePhase = "idle" | "receiving_pk" | "receiving_ct" | "done";
67
+ export interface SPQRState {
68
+ cycleId: number;
69
+ sendingPQKeys: MLKEMKeyPair | null;
70
+ sendingChunks: Uint8Array[];
71
+ sendingChunkIndex: number;
72
+ sendingPhase: SPQRPhase;
73
+ receivedChunks: Map<number, Uint8Array>;
74
+ receivingPhase: SPQRReceivePhase;
75
+ expectedTotalChunks: number;
76
+ receivedSharedSecret: Uint8Array | null;
77
+ currentSPQRKey: Uint8Array;
78
+ spqrChainKey: Uint8Array;
79
+ spqrMessageCount: number;
80
+ }
81
+ export interface SPQRChunk {
82
+ cycleId: number;
83
+ chunkIndex: number;
84
+ totalChunks: number;
85
+ data: Uint8Array;
86
+ }
87
+ export interface PQSessionState {
88
+ pqxdhComplete: boolean;
89
+ ratchetState: RatchetState;
90
+ spqrState: SPQRState;
91
+ peerIdentityKey: Uint8Array;
92
+ peerRegistrationId: number;
93
+ peerDeviceId: number;
94
+ pendingInitialMessage?: {
95
+ ephemeralPublicKey: Uint8Array;
96
+ mlkemCiphertext: Uint8Array;
97
+ identityKey: Uint8Array;
98
+ signedPreKeyId: number;
99
+ oneTimePreKeyId: number | null;
100
+ pqPreKeyId: number;
101
+ };
102
+ }
103
+ export interface PQIdentity {
104
+ x25519KeyPair: X25519KeyPair;
105
+ ed25519KeyPair: Ed25519KeyPair;
106
+ registrationId: number;
107
+ }
108
+ export interface SerializedRatchetState {
109
+ rootKey: string;
110
+ sendingChainKey: string;
111
+ sendingMessageCount: number;
112
+ receivingChainKey: string;
113
+ receivingMessageCount: number;
114
+ ourDHPrivateKey: string;
115
+ ourDHPublicKey: string;
116
+ peerDHPublicKey: string | null;
117
+ previousSendingCount: number;
118
+ skipMessageKeys: Record<string, string>;
119
+ }
120
+ export interface SerializedSPQRState {
121
+ cycleId: number;
122
+ sendingPQPublicKey: string | null;
123
+ sendingPQSecretKey: string | null;
124
+ sendingChunks: string[];
125
+ sendingChunkIndex: number;
126
+ sendingPhase: string;
127
+ receivedChunks: Record<string, string>;
128
+ receivingPhase: string;
129
+ expectedTotalChunks: number;
130
+ receivedSharedSecret: string | null;
131
+ currentSPQRKey: string;
132
+ spqrChainKey: string;
133
+ spqrMessageCount: number;
134
+ }
135
+ export interface SerializedPQSessionState {
136
+ pqxdhComplete: boolean;
137
+ ratchetState: SerializedRatchetState;
138
+ spqrState: SerializedSPQRState;
139
+ peerIdentityKey: string;
140
+ peerRegistrationId: number;
141
+ peerDeviceId: number;
142
+ pendingInitialMessage?: {
143
+ ephemeralPublicKey: string;
144
+ mlkemCiphertext: string;
145
+ identityKey: string;
146
+ signedPreKeyId: number;
147
+ oneTimePreKeyId: number | null;
148
+ pqPreKeyId: number;
149
+ };
150
+ }
151
+ export declare enum PQErrorCode {
152
+ INVALID_KEY = "INVALID_KEY",
153
+ HANDSHAKE_FAILED = "HANDSHAKE_FAILED",
154
+ ENCRYPTION_FAILED = "ENCRYPTION_FAILED",
155
+ DECRYPTION_FAILED = "DECRYPTION_FAILED",
156
+ SESSION_NOT_FOUND = "SESSION_NOT_FOUND",
157
+ SPQR_ERROR = "SPQR_ERROR",
158
+ ERASURE_ERROR = "ERASURE_ERROR",
159
+ SERIALIZATION_ERROR = "SERIALIZATION_ERROR"
160
+ }
161
+ export declare class PQError extends Error {
162
+ code: PQErrorCode;
163
+ constructor(code: PQErrorCode, message: string);
164
+ }
165
+ export declare const DEFAULT_DEVICE_ID = 1;
166
+ export declare const ROOT_KEY_SIZE = 32;
167
+ export declare const CHAIN_KEY_SIZE = 32;
168
+ export declare const MESSAGE_KEY_SIZE = 32;
169
+ export declare const DH_KEY_SIZE = 32;
170
+ export declare const SIGNATURE_SIZE = 64;
171
+ export declare const MLKEM_PUBLIC_KEY_SIZE = 1184;
172
+ export declare const MLKEM_SECRET_KEY_SIZE = 2400;
173
+ export declare const MLKEM_CIPHERTEXT_SIZE = 1088;
174
+ export declare const MLKEM_SHARED_SECRET_SIZE = 32;
175
+ export declare const AES_GCM_IV_SIZE = 12;
176
+ export declare const AES_GCM_TAG_SIZE = 16;
177
+ export declare const SPQR_CHUNK_DATA_SIZE = 34;
178
+ export declare const SPQR_CHUNK_HEADER_SIZE = 8;
179
+ export declare const SPQR_CHUNK_SIZE: number;
180
+ export declare const SPQR_DATA_CHUNKS = 28;
181
+ export declare const SPQR_TOTAL_CHUNKS = 56;
@@ -0,0 +1 @@
1
+ export var MessageType;(function(a){a[a['PREKEY_MESSAGE']=0x3]='PREKEY_MESSAGE',a[a['NORMAL_MESSAGE']=0x1]='NORMAL_MESSAGE';}(MessageType||(MessageType={})));export var PQErrorCode;(function(a){a['INVALID_KEY']='INVALID_KEY',a['HANDSHAKE_FAILED']='HANDSHAKE_FAILED',a['ENCRYPTION_FAILED']='ENCRYPTION_FAILED',a['DECRYPTION_FAILED']='DECRYPTION_FAILED',a['SESSION_NOT_FOUND']='SESSION_NOT_FOUND',a['SPQR_ERROR']='SPQR_ERROR',a['ERASURE_ERROR']='ERASURE_ERROR',a['SERIALIZATION_ERROR']='SERIALIZATION_ERROR';}(PQErrorCode||(PQErrorCode={})));export class PQError extends Error{['code'];constructor(a,b){super(b),this['code']=a,this['name']='PQError';}}export const DEFAULT_DEVICE_ID=0x1;export const ROOT_KEY_SIZE=0x20;export const CHAIN_KEY_SIZE=0x20;export const MESSAGE_KEY_SIZE=0x20;export const DH_KEY_SIZE=0x20;export const SIGNATURE_SIZE=0x40;export const MLKEM_PUBLIC_KEY_SIZE=0x4a0;export const MLKEM_SECRET_KEY_SIZE=0x960;export const MLKEM_CIPHERTEXT_SIZE=0x440;export const MLKEM_SHARED_SECRET_SIZE=0x20;export const AES_GCM_IV_SIZE=0xc;export const AES_GCM_TAG_SIZE=0x10;export const SPQR_CHUNK_DATA_SIZE=0x22;export const SPQR_CHUNK_HEADER_SIZE=0x8;export const SPQR_CHUNK_SIZE=SPQR_CHUNK_DATA_SIZE+SPQR_CHUNK_HEADER_SIZE;export const SPQR_DATA_CHUNKS=0x1c;export const SPQR_TOTAL_CHUNKS=0x38;
@@ -1,12 +1,11 @@
1
- import { SignalProtocolStorage } from "./storage.js";
1
+ import { PQSessionCipher } from "./pq/index.js";
2
+ import type { PQSessionStore } from "./pq/session.js";
2
3
  import type { Xed25519KeyPair, MessengerConfig, RemoteBundle } from "./types.js";
3
- type KeyPairType = {
4
- pubKey: ArrayBuffer;
5
- privKey: ArrayBuffer;
6
- };
4
+ import type { X25519KeyPair, Ed25519KeyPair } from "./pq/types.js";
7
5
  export interface LocalIdentity {
8
6
  xed25519: Xed25519KeyPair;
9
- signalIdentity: KeyPairType;
7
+ x25519KeyPair: X25519KeyPair;
8
+ ed25519KeyPair: Ed25519KeyPair;
10
9
  registrationId: number;
11
10
  }
12
11
  export interface EncryptedMessage {
@@ -15,11 +14,14 @@ export interface EncryptedMessage {
15
14
  registrationId?: number;
16
15
  }
17
16
  export declare class MessengerSession {
18
- private store;
17
+ private pqStore;
18
+ private pqCipher;
19
19
  private serverClient;
20
20
  private config;
21
21
  private identity;
22
22
  constructor(userAddress: string, config?: Partial<MessengerConfig>);
23
+ get store(): PQSessionStore;
24
+ get cipher(): PQSessionCipher;
23
25
  ensureIdentity(userAddress?: string): Promise<LocalIdentity>;
24
26
  private deriveRegistrationId;
25
27
  registerDevice(userAddress: string): Promise<void>;
@@ -40,10 +42,10 @@ export interface SessionSnapshot {
40
42
  }
41
43
  export declare class SessionStateManager {
42
44
  private store;
43
- constructor(store: SignalProtocolStorage);
44
- snapshotSession(sessionKey: string): Promise<SessionSnapshot>;
45
- rollbackSession(sessionKey: string, snapshot: SessionSnapshot): Promise<void>;
46
- commitSession(_sessionKey: string): Promise<void>;
45
+ constructor(store: PQSessionStore);
46
+ snapshotSession(peerAddress: string, peerDeviceId: number): Promise<SessionSnapshot>;
47
+ rollbackSession(peerAddress: string, peerDeviceId: number, snapshot: SessionSnapshot): Promise<void>;
48
+ commitSession(_peerAddress: string, _peerDeviceId: number): Promise<void>;
47
49
  }
48
50
  export interface DecryptResult {
49
51
  success: boolean;
@@ -56,12 +58,9 @@ export interface DecryptResult {
56
58
  export declare class DecryptionEngine {
57
59
  private sessionManager;
58
60
  private store;
59
- constructor(store: SignalProtocolStorage);
60
- private getRecvSessionKey;
61
- private getSendSessionKey;
61
+ private cipher;
62
+ constructor(store: PQSessionStore);
62
63
  decryptMessage(myAddress: string, peerAddress: string, ciphertext: ArrayBuffer, msgType: number, peerDeviceId?: number): Promise<DecryptResult>;
63
64
  private handlePreKeyMessage;
64
65
  private handleWhisperMessage;
65
- private arrayBufferToBinary;
66
66
  }
67
- export {};
@@ -1 +1 @@
1
- import{KeyHelper,SessionBuilder,SessionCipher,SignalProtocolAddress}from'libsignal-protocol-typescript';import{SignalProtocolStorage}from'./storage.js';import{MessengerServerClient}from'./server.js';import{recoverXed25519FromX25519PrivateKey,arrayBufferToUint8Array,bytesToBase64,base64ToBytes}from'./crypto.js';import{MessageType,DEFAULT_MESSENGER_CONFIG,MessengerError,MessengerErrorCode,DEFAULT_DEVICE_ID}from'./types.js';async function getAccount(){const {Account:a}=await import('../local/account.js');return a['Instance']();}export class MessengerSession{['store'];['serverClient'];['config'];['identity']=null;constructor(a,b){this['store']=new SignalProtocolStorage(a),this['config']={...DEFAULT_MESSENGER_CONFIG,...b},this['serverClient']=new MessengerServerClient(this['config']);}async['ensureIdentity'](a){if(this['identity'])return this['identity'];const b=await this['store']['getIdentityKeyPair'](),c=await this['store']['getLocalRegistrationId']();if(b&&c){const j=new Uint8Array(b['privKey']),k=recoverXed25519FromX25519PrivateKey(j);return this['identity']={'xed25519':k,'signalIdentity':b,'registrationId':c},this['identity'];}if(!a)throw new MessengerError(MessengerErrorCode['IDENTITY_NOT_FOUND'],'userAddress\x20is\x20required\x20to\x20derive\x20identity');const {privateKey:d,publicKey:e}=await(await getAccount())['deriveX25519KeyPair'](a),f=this['deriveRegistrationId'](e),g=new Uint8Array(0x21);g[0x0]=0x5,g['set'](e,0x1);const h={'privKey':d['slice']()['buffer'],'pubKey':g['slice']()['buffer']};await this['store']['setIdentity'](h,f);const i=recoverXed25519FromX25519PrivateKey(d);return this['identity']={'xed25519':i,'signalIdentity':h,'registrationId':f},this['identity'];}['deriveRegistrationId'](a){const b=a[0x0]<<0x8|a[0x1];return b===0x0?0x1:b;}async['registerDevice'](a){const b=await this['ensureIdentity'](a),c=0x1;let d,e,f,g=![];const h=await this['store']['loadSignedPreKeyWithSignature'](c);h?(e=arrayBufferToUint8Array(h['pubKey']),f=arrayBufferToUint8Array(h['signature']),d={'keyId':c,'keyPair':{'pubKey':h['pubKey'],'privKey':h['privKey']},'signature':h['signature']}):(d=await KeyHelper['generateSignedPreKey'](b['signalIdentity'],c),e=arrayBufferToUint8Array(d['keyPair']['pubKey']),f=arrayBufferToUint8Array(d['signature']),g=!![]);const i=await this['generatePreKeyBatch'](this['config']['prekey_count'],a),j=arrayBufferToUint8Array(b['signalIdentity']['pubKey']),k=await(await getAccount())['get'](a,![]);if(!k?.['pubkey'])throw new MessengerError(MessengerErrorCode['IDENTITY_NOT_FOUND'],'Account\x20not\x20found\x20for\x20'+a);const l=Date['now'](),m=this['generateNonce'](),n='register:'+k['pubkey']+':'+l+':'+m,o=await(await getAccount())['signData'](a,n),p=Buffer['from'](o['signature']['slice'](0x2),'hex'),q={'userAddress':a,'deviceId':DEFAULT_DEVICE_ID,'registrationId':b['registrationId'],'identityKey':bytesToBase64(j),'signedPrekey':{'keyId':c,'publicKey':bytesToBase64(e),'signature':bytesToBase64(f)},'prekeys':i,'publicKey':k['pubkey'],'signatureScheme':'ED25519','signature':bytesToBase64(p),'timestamp':l,'nonce':m};console['log']('[Session\x20Debug]\x20Sending\x20register\x20request\x20to\x20server...'),await this['serverClient']['registerDevice'](q),console['log']('[Session\x20Debug]\x20Server\x20register\x20request\x20successful!'),console['log']('[Session\x20Debug]\x20Verifying\x20registration\x20complete...'),await this['verifyRegistrationComplete'](a),console['log']('[Session\x20Debug]\x20Registration\x20verification\x20complete!'),g&&await this['store']['storeSignedPreKeyWithSignature'](c,d['keyPair'],f['buffer']['slice'](0x0));}async['verifyRegistrationComplete'](a,b=0xa,c=0x1f4){for(let d=0x0;d<b;d++){try{const e=await this['serverClient']['getPrekeyStatus'](a);console['log']('Registration\x20verified\x20for\x20'+a+',\x20prekeys:\x20'+e['currentCount']+'/'+e['maxAllowed']);return;}catch(f){if(f?.['message']?.['includes']('404')||f?.['status']===0x194){if(d<b-0x1){console['log']('Waiting\x20for\x20registration\x20to\x20complete...\x20('+(d+0x1)+'/'+b+')'),await new Promise(g=>setTimeout(g,c));continue;}}throw f;}}throw new MessengerError(MessengerErrorCode['REGISTRATION_FAILED'],'Registration\x20verification\x20failed\x20after\x20'+b+'\x20attempts');}async['isDeviceRegistered'](a){try{const b=await this['store']['loadSignedPreKeyWithSignature'](0x1);if(!b)return![];const c=await this['serverClient']['getPrekeyStatus'](a);return!![];}catch(d){if(d?.['message']?.['includes']('404')||d?.['status']===0x194)return![];return![];}}async['generatePreKeyBatch'](a,b){if(a<=0x0)return[];const c=await this['store']['getMeta']();let d=c['nextPreKeyId']||0x1;const e=[];for(let f=0x0;f<a;f++){const g=d+f,h=await this['store']['loadPreKey'](g);if(h){const n=new Uint8Array(h['pubKey']),o=bytesToBase64(n),p=await(await getAccount())['signData'](b,n),q=Buffer['from'](p['signature']['slice'](0x2),'hex');e['push']({'keyId':g,'publicKey':o,'signature':bytesToBase64(q)});continue;}const j=await KeyHelper['generatePreKey'](g),k=new Uint8Array(j['keyPair']['pubKey']),l=await(await getAccount())['signData'](b,k),m=Buffer['from'](l['signature']['slice'](0x2),'hex');await this['store']['storePreKey'](g,j['keyPair']),e['push']({'keyId':g,'publicKey':bytesToBase64(k),'signature':bytesToBase64(m)});}return d+=a,await this['store']['setMeta']({'nextPreKeyId':d}),e;}async['ensurePreKeys'](a,b=![]){const c=await this['serverClient']['getPrekeyStatus'](a);if(!b&&c['currentCount']>=c['maxAllowed'])return;const d=c['maxAllowed']-c['currentCount'];if(d<=0x0)return;await this['ensureIdentity'](a);const e=await this['generatePreKeyBatch'](d,a);if(e['length']===0x0)return;const f=await(await getAccount())['get'](a,![]);if(!f?.['pubkey'])throw new MessengerError(MessengerErrorCode['IDENTITY_NOT_FOUND'],'Account\x20not\x20found\x20for\x20'+a);const g=Date['now'](),h=this['generateNonce'](),i='upload_prekeys:'+f['pubkey']+':'+g+':'+h,j=await(await getAccount())['signData'](a,i),k=Buffer['from'](j['signature']['slice'](0x2),'hex');await this['serverClient']['uploadPreKeys']({'userAddress':a,'prekeys':e,'publicKey':f['pubkey'],'signatureScheme':'ED25519','signature':bytesToBase64(k),'timestamp':g,'nonce':h});}['generateNonce'](){const a=new Uint8Array(0x10);return crypto['getRandomValues'](a),Array['from'](a,c=>c['toString'](0x10)['padStart'](0x2,'0'))['join']('');}async['establishSession'](a,b,c=DEFAULT_DEVICE_ID,d){const e=new SignalProtocolAddress(b,c),f=await this['store']['loadSession'](e['toString']());if(f)return;if(!d){const t=await(await getAccount())['get'](a,![]);if(!t?.['pubkey'])throw new MessengerError(MessengerErrorCode['IDENTITY_NOT_FOUND'],'Account\x20not\x20found\x20for\x20'+a);const u=Date['now'](),v=this['generateNonce'](),w=t['pubkey'],x='get_bundle:'+a+':'+u+':'+v,y=await(await getAccount())['signData'](a,x),z=Buffer['from'](y['signature']['slice'](0x2),'hex');d=await this['serverClient']['fetchRemoteBundle'](b,a,w,{'signatureScheme':'ED25519','signature':bytesToBase64(new Uint8Array(z)),'timestamp':u,'nonce':v},c);}const g=d['oneTimePrekey'],h=d['signedPrekey'];if(!h)throw new MessengerError(MessengerErrorCode['IDENTITY_NOT_FOUND'],'No\x20signed\x20prekey\x20available\x20for\x20'+b);const i=base64ToBytes(d['identityKey']),j=new Uint8Array(i),k=base64ToBytes(h['publicKey']),l=base64ToBytes(h['signature']),m=new Uint8Array(k);let n=undefined;if(g){const A=base64ToBytes(g['publicKey']),B=new Uint8Array(A);n={'keyId':g['keyId'],'publicKey':B['buffer']['slice'](B['byteOffset'],B['byteOffset']+B['byteLength'])};}const o={'registrationId':d['registrationId'],'identityKey':j['buffer']['slice'](j['byteOffset'],j['byteOffset']+j['byteLength']),'signedPreKey':{'keyId':h['keyId'],'publicKey':m['buffer']['slice'](m['byteOffset'],m['byteOffset']+m['byteLength']),'signature':new Uint8Array(l)['buffer']['slice'](l['byteOffset'],l['byteOffset']+l['byteLength'])},'preKey':n},p=new SessionBuilder(this['store'],e);await p['processPreKey'](o),await this['store']['saveIdentity'](e['toString'](),o['identityKey']);const q=e['toString'](),r='send:'+b+'.'+c,s=await this['store']['loadSession'](q);s&&(await this['store']['storeSession'](r,s),console['log']('[Session]\x20会话已保存到发送key:\x20'+r));}async['encryptMessage'](a,b,c,d=DEFAULT_DEVICE_ID){const e=new SignalProtocolAddress(b,d),f=e['toString'](),g='send:'+b+'.'+d,h='recv:'+b+'.'+d;let i=await this['store']['loadSession'](f),j=await this['store']['loadSession'](g);const k=await this['store']['loadSession'](h);!i&&k&&(console['log']('[Session]\x20复制接收会话到默认key:\x20'+b),await this['store']['storeSession'](f,k),i=k);!j&&k&&(console['log']('[Session]\x20复制接收会话到发送会话:\x20'+b),await this['store']['storeSession'](g,k),j=k);let l=i||j,m=!l,n=0x0;const o=0x5;while(n<=o){try{if(m){console['log']('[Session]\x20建立新会话\x20(尝试\x20'+(n+0x1)+'/'+(o+0x1)+')');const t=await(await getAccount())['get'](a,![]);if(!t?.['pubkey'])throw new MessengerError(MessengerErrorCode['IDENTITY_NOT_FOUND'],'Account\x20not\x20found\x20for\x20'+a);const u=Date['now'](),v=this['generateNonce'](),w=t['pubkey'],x='get_bundle:'+a+':'+u+':'+v,y=await(await getAccount())['signData'](a,x),z=Buffer['from'](y['signature']['slice'](0x2),'hex'),A=await this['serverClient']['fetchRemoteBundle'](b,a,w,{'signatureScheme':'ED25519','signature':bytesToBase64(new Uint8Array(z)),'timestamp':u,'nonce':v},d);await this['establishSession'](a,b,d,A);}const p=new SessionCipher(this['store'],e),q=new TextEncoder(),r=await p['encrypt'](q['encode'](c)['buffer']);let s;if(typeof r['body']==='string'){const B=Buffer['from'](r['body'],'binary');s=new Uint8Array(B)['buffer'];}else{if(r['body'])s=r['body'];else throw new MessengerError(MessengerErrorCode['ENCRYPTION_FAILED'],'Cipher\x20message\x20body\x20is\x20empty');}return{'type':r['type'],'body':s,'registrationId':r['registrationId']};}catch(C){console['error']('[Session]\x20加密失败\x20(尝试\x20'+(n+0x1)+'/'+(o+0x1)+'):',C);if(n>=o)throw C;console['log']('[Session]\x20尝试删除旧会话并重新建立...');try{l&&(await this['store']['removeSession'](f),await this['store']['removeSession'](g),await this['store']['removeSession'](h),l=undefined),m=!![],n++,await new Promise(D=>setTimeout(D,0x64));}catch(D){console['error']('[Session]\x20重新建立会话失败:',D);throw C;}}}throw new MessengerError(MessengerErrorCode['ENCRYPTION_FAILED'],'Encryption\x20failed\x20after\x20multiple\x20attempts');}async['decryptMessage'](a,b,c,d,e=DEFAULT_DEVICE_ID){const f=new SignalProtocolAddress(b,e),g=f['toString']();let h=await this['store']['loadSession'](g);const j=new TextDecoder();let k='';const l=new Uint8Array(c);for(let o=0x0;o<l['length'];o++){k+=String['fromCharCode'](l[o]);}let m=0x0;const n=0x5;if(d!==MessageType['PREKEY_MESSAGE']&&!h){console['log']('[Session]\x20收到\x20WHISPER_MESSAGE\x20但无现有会话,需要等待\x20PREKEY_MESSAGE');throw new Error('收到\x20WHISPER_MESSAGE\x20但无现有会话,需要等待\x20PREKEY_MESSAGE');}while(m<=n){try{const p=new SessionCipher(this['store'],f);let q;if(d===MessageType['PREKEY_MESSAGE']){console['log']('[Session]\x20收到\x20PREKEY_MESSAGE,尝试解密\x20(尝试\x20'+(m+0x1)+'/'+(n+0x1)+')');try{return q=await p['decryptPreKeyWhisperMessage'](k,'binary'),console['log']('[Session]\x20PREKEY_MESSAGE\x20解密成功!'),j['decode'](q);}catch(r){console['log']('[Session]\x20直接解密\x20PREKEY_MESSAGE\x20失败:\x20'+(r instanceof Error?r['message']:String(r)));if(h&&m===0x0){const s=a['toLowerCase'](),t=b['toLowerCase']();if(s<t){console['log']('[Session]\x20我的地址较小\x20('+s+'\x20<\x20'+t+'),保留我的会话,稍后重试');throw new Error('PREKEY\x20竞争:我的地址较小,保留我的会话');}else return console['log']('[Session]\x20我的地址较大\x20('+s+'\x20>\x20'+t+'),删除我的会话,用对方的\x20PREKEY_MESSAGE\x20建立新会话'),await this['store']['removeSession'](g),h=undefined,console['log']('[Session]\x20已删除旧会话,重新尝试解密...'),q=await p['decryptPreKeyWhisperMessage'](k,'binary'),console['log']('[Session]\x20PREKEY_MESSAGE\x20解密成功,新会话已建立'),j['decode'](q);}else throw r;}}else q=await p['decryptWhisperMessage'](k,'binary');return j['decode'](q);}catch(u){console['error']('[Session\x20Debug]\x20解密失败\x20(尝试\x20'+(m+0x1)+'/'+(n+0x1)+'):'),console['error']('\x20\x20错误类型:\x20'+(u instanceof Error?u['constructor']['name']:typeof u)),console['error']('\x20\x20错误消息:\x20'+(u instanceof Error?u['message']:String(u)));u instanceof Error&&u['stack']&&console['error']('\x20\x20堆栈:\x20'+u['stack']['split']('\x0a')[0x0]);console['error']('\x20\x20上下文:'),console['error']('\x20\x20\x20\x20-\x20myAddress:\x20'+a),console['error']('\x20\x20\x20\x20-\x20peerAddress:\x20'+b),console['error']('\x20\x20\x20\x20-\x20msgType:\x20'+d+'\x20('+(d===MessageType['PREKEY_MESSAGE']?'PREKEY':'WHISPER')+')'),console['error']('\x20\x20\x20\x20-\x20sessionKey:\x20'+g),console['error']('\x20\x20\x20\x20-\x20existingSession:\x20'+(h?'存在':'不存在')),console['error']('\x20\x20\x20\x20-\x20ciphertext.length:\x20'+c['byteLength']);const v=await this['store']['getIdentityKeyPair'](),w=await this['store']['getLocalRegistrationId']();console['error']('\x20\x20\x20\x20-\x20identityKey:\x20'+(v?'存在':'缺失')),console['error']('\x20\x20\x20\x20-\x20registrationId:\x20'+w);if(m>=n)throw u;console['log']('[Session]\x20尝试重新建立会话...');try{h&&(console['log']('[Session]\x20删除旧会话'),await this['store']['removeSession'](g),h=undefined),d===MessageType['PREKEY_MESSAGE']?console['log']('[Session]\x20收到的是\x20PREKEY_MESSAGE,等待发送方的\x20PreKey\x20即可重建会话'):console['log']('[Session]\x20收到的是\x20WHISPER_MESSAGE,需要让对方重新发送\x20PREKEY_MESSAGE'),m++,await new Promise(x=>setTimeout(x,0x64));}catch(x){console['error']('[Session]\x20重新建立会话失败:',x);throw u;}}}throw new MessengerError(MessengerErrorCode['DECRYPTION_FAILED'],'Decryption\x20failed\x20after\x20multiple\x20attempts');}async['getIdentityKey'](){const a=await this['ensureIdentity']();return bytesToBase64(arrayBufferToUint8Array(a['signalIdentity']['pubKey']));}async['getRegistrationId'](){const a=await this['ensureIdentity']();return a['registrationId'];}}export class SessionStateManager{['store'];constructor(a){this['store']=a;}async['snapshotSession'](a){const b=await this['store']['loadSession'](a);return{'sessionData':b||null,'timestamp':Date['now']()};}async['rollbackSession'](a,b){b['sessionData']?(await this['store']['storeSession'](a,b['sessionData']),console['log']('[SessionState]\x20回滚会话:\x20'+a)):(await this['store']['removeSession'](a),console['log']('[SessionState]\x20清除会话:\x20'+a));}async['commitSession'](a){console['log']('[SessionState]\x20提交新会话');}}export class DecryptionEngine{['sessionManager'];['store'];constructor(a){this['store']=a,this['sessionManager']=new SessionStateManager(a);}['getRecvSessionKey'](a,b){return'recv:'+a+'.'+b;}['getSendSessionKey'](a,b){return'send:'+a+'.'+b;}async['decryptMessage'](a,b,c,d,e=DEFAULT_DEVICE_ID){const f=this['getRecvSessionKey'](b,e),g=new SignalProtocolAddress(b,e),h=await this['sessionManager']['snapshotSession'](f);try{return d===MessageType['PREKEY_MESSAGE']?await this['handlePreKeyMessage'](a,b,c,g,f,h):await this['handleWhisperMessage'](a,b,c,g,f,h);}catch(i){return await this['sessionManager']['rollbackSession'](f,h),{'success':![],'sessionUpdated':![],'sessionRolledBack':!![],'messageType':d===MessageType['PREKEY_MESSAGE']?'PREKEY':'WHISPER','error':i instanceof Error?i['message']:String(i)};}}async['handlePreKeyMessage'](a,b,c,d,e,f){console['log']('[Decrypt]\x20处理\x20PREKEY_MESSAGE\x20from\x20'+b);const g=new SessionCipher(this['store'],d),h=new TextDecoder(),i=this['arrayBufferToBinary'](c),j=await g['decryptPreKeyWhisperMessage'](i,'binary'),k=h['decode'](j);console['log']('[Decrypt]\x20PREKEY_MESSAGE\x20解密成功'),await this['sessionManager']['commitSession'](e);const l=a['toLowerCase'](),m=b['toLowerCase']();return l<m?console['log']('[Decrypt]\x20小地址('+l+')保存接收会话用于解密,发送会话保持不变'):console['log']('[Decrypt]\x20大地址('+l+')接受新会话'),{'success':!![],'plaintext':k,'sessionUpdated':!![],'sessionRolledBack':![],'messageType':'PREKEY'};}async['handleWhisperMessage'](a,b,c,d,e,f){console['log']('[Decrypt]\x20处理\x20WHISPER_MESSAGE\x20from\x20'+b);const g=await this['store']['loadSession'](e);if(!g)return console['log']('[Decrypt]\x20无接收会话,WHISPER_MESSAGE\x20需要等待\x20PREKEY'),await this['sessionManager']['rollbackSession'](e,f),{'success':![],'sessionUpdated':![],'sessionRolledBack':![],'messageType':'WHISPER','error':'NO_SESSION'};const h=new SessionCipher(this['store'],d),i=new TextDecoder(),j=this['arrayBufferToBinary'](c),k=await h['decryptWhisperMessage'](j,'binary');return console['log']('[Decrypt]\x20WHISPER_MESSAGE\x20解密成功'),{'success':!![],'plaintext':i['decode'](k),'sessionUpdated':!![],'sessionRolledBack':![],'messageType':'WHISPER'};}['arrayBufferToBinary'](a){const b=new Uint8Array(a);let c='';for(let d=0x0;d<b['length'];d++){c+=String['fromCharCode'](b[d]);}return c;}}
1
+ import{PQSessionCipher,PQSessionStoreAdapter}from'./pq/index.js';import{MessengerServerClient}from'./server.js';import{getDatabase}from'./storage.js';import{recoverXed25519FromX25519PrivateKey,bytesToBase64,base64ToBytes}from'./crypto.js';import{MessageType,DEFAULT_MESSENGER_CONFIG,MessengerError,MessengerErrorCode,DEFAULT_DEVICE_ID}from'./types.js';async function getAccount(){const {Account:a}=await import('../local/account.js');return a['Instance']();}export class MessengerSession{['pqStore'];['pqCipher'];['serverClient'];['config'];['identity']=null;constructor(a,b){this['config']={...DEFAULT_MESSENGER_CONFIG,...b},this['serverClient']=new MessengerServerClient(this['config']);const c=getDatabase(a);this['pqStore']=new PQSessionStoreAdapter(c,a),this['pqCipher']=new PQSessionCipher(this['pqStore']);}get['store'](){return this['pqStore'];}get['cipher'](){return this['pqCipher'];}async['ensureIdentity'](a){if(this['identity'])return this['identity'];const b=await this['pqStore']['getIdentityKeyPair'](),c=await this['pqStore']['getEd25519KeyPair'](),d=await this['pqStore']['getRegistrationId']();if(b&&c&&d){const k=recoverXed25519FromX25519PrivateKey(b['privateKey']);return this['identity']={'xed25519':k,'x25519KeyPair':b,'ed25519KeyPair':c,'registrationId':d},this['identity'];}if(!a)throw new MessengerError(MessengerErrorCode['IDENTITY_NOT_FOUND'],'userAddress\x20is\x20required\x20to\x20derive\x20identity');const {privateKey:e,publicKey:f}=await(await getAccount())['deriveX25519KeyPair'](a),g=this['deriveRegistrationId'](f),h={'publicKey':f,'privateKey':e},i=recoverXed25519FromX25519PrivateKey(e),j={'publicKey':i['ed25519PublicKey'],'privateKey':i['ed25519PrivateKey']};return await this['pqStore']['setIdentityKeyPair'](h),await this['pqStore']['setEd25519KeyPair'](j),await this['pqStore']['setRegistrationId'](g),this['identity']={'xed25519':i,'x25519KeyPair':h,'ed25519KeyPair':j,'registrationId':g},this['identity'];}['deriveRegistrationId'](a){const b=a[0x0]<<0x8|a[0x1];return b===0x0?0x1:b;}async['registerDevice'](a){const b=await this['ensureIdentity'](a),c=0x1,d=0x1;let e,f;const g=await this['pqStore']['getSignedPreKeySignature'](c),h=await this['pqStore']['getSignedPreKey'](c),i=await this['pqStore']['getPQPreKey'](d),j=await this['pqStore']['getPQPreKeySignature'](d);if(h&&g&&i&&j)e=h['publicKey'],f=g;else{const u=await this['pqCipher']['generatePreKeyBundle'](c,d,this['config']['prekey_count']);e=u['signedPreKey']['keyPair']['publicKey'],f=u['signedPreKey']['signature'];}const k=await this['generatePreKeyBatch'](this['config']['prekey_count'],a),l=await(await getAccount())['get'](a,![]);if(!l?.['pubkey'])throw new MessengerError(MessengerErrorCode['IDENTITY_NOT_FOUND'],'Account\x20not\x20found\x20for\x20'+a);const m=Date['now'](),n=this['generateNonce'](),o='register:'+l['pubkey']+':'+m+':'+n,p=await(await getAccount())['signData'](a,o),q=Buffer['from'](p['signature']['slice'](0x2),'hex'),r=await this['pqStore']['getPQPreKey'](d),s=await this['pqStore']['getPQPreKeySignature'](d),t={'userAddress':a,'deviceId':DEFAULT_DEVICE_ID,'registrationId':b['registrationId'],'identityKey':bytesToBase64(b['x25519KeyPair']['publicKey']),'ed25519PublicKey':bytesToBase64(b['ed25519KeyPair']['publicKey']),'signedPrekey':{'keyId':c,'publicKey':bytesToBase64(e),'signature':bytesToBase64(f)},'prekeys':k,'publicKey':l['pubkey'],'signatureScheme':'ED25519','signature':bytesToBase64(q),'timestamp':m,'nonce':n};r&&s&&(t['pqPrekey']={'keyId':d,'publicKey':bytesToBase64(r['publicKey']),'signature':bytesToBase64(s)}),await this['serverClient']['registerDevice'](t),await this['verifyRegistrationComplete'](a);}async['verifyRegistrationComplete'](a,b=0xa,c=0x1f4){for(let d=0x0;d<b;d++){try{const e=await this['serverClient']['getPrekeyStatus'](a);return;}catch(f){if(f?.['message']?.['includes']('404')||f?.['status']===0x194){if(d<b-0x1){await new Promise(g=>setTimeout(g,c));continue;}}throw f;}}throw new MessengerError(MessengerErrorCode['REGISTRATION_FAILED'],'Registration\x20verification\x20failed\x20after\x20'+b+'\x20attempts');}async['isDeviceRegistered'](a){try{const b=await this['pqStore']['getSignedPreKeySignature'](0x1);if(!b)return![];const c=await this['serverClient']['getPrekeyStatus'](a);return!![];}catch(d){if(d?.['message']?.['includes']('404')||d?.['status']===0x194)return![];return![];}}async['generatePreKeyBatch'](a,b){if(a<=0x0)return[];const c=[],{generateX25519KeyPair:d}=await import('./pq/crypto.js'),e=Math['floor'](Math['random']()*0x7fffff00);for(let f=0x0;f<a;f++){const g=e+f,h=await this['pqStore']['getOneTimePreKey'](g);if(h){const m=bytesToBase64(h['publicKey']),n=await(await getAccount())['signData'](b,h['publicKey']),o=Buffer['from'](n['signature']['slice'](0x2),'hex');c['push']({'keyId':g,'publicKey':m,'signature':bytesToBase64(o)});continue;}const j=d(),k=await(await getAccount())['signData'](b,j['publicKey']),l=Buffer['from'](k['signature']['slice'](0x2),'hex');await this['pqStore']['setOneTimePreKey'](g,j),c['push']({'keyId':g,'publicKey':bytesToBase64(j['publicKey']),'signature':bytesToBase64(l)});}return c;}async['ensurePreKeys'](a,b=![]){const c=await this['serverClient']['getPrekeyStatus'](a);if(!b&&c['currentCount']>=c['maxAllowed'])return;const d=c['maxAllowed']-c['currentCount'];if(d<=0x0)return;await this['ensureIdentity'](a);const e=await this['generatePreKeyBatch'](d,a);if(e['length']===0x0)return;const f=await(await getAccount())['get'](a,![]);if(!f?.['pubkey'])throw new MessengerError(MessengerErrorCode['IDENTITY_NOT_FOUND'],'Account\x20not\x20found\x20for\x20'+a);const g=Date['now'](),h=this['generateNonce'](),i='upload_prekeys:'+f['pubkey']+':'+g+':'+h,j=await(await getAccount())['signData'](a,i),k=Buffer['from'](j['signature']['slice'](0x2),'hex');await this['serverClient']['uploadPreKeys']({'userAddress':a,'prekeys':e,'publicKey':f['pubkey'],'signatureScheme':'ED25519','signature':bytesToBase64(k),'timestamp':g,'nonce':h});}['generateNonce'](){const a=new Uint8Array(0x10);return crypto['getRandomValues'](a),Array['from'](a,c=>c['toString'](0x10)['padStart'](0x2,'0'))['join']('');}async['establishSession'](a,b,c=DEFAULT_DEVICE_ID,d){const e=await this['pqCipher']['hasSession'](b,c);if(e)return;if(!d){const l=await(await getAccount())['get'](a,![]);if(!l?.['pubkey'])throw new MessengerError(MessengerErrorCode['IDENTITY_NOT_FOUND'],'Account\x20not\x20found\x20for\x20'+a);const m=Date['now'](),n=this['generateNonce'](),o=l['pubkey'],p='get_bundle:'+a+':'+m+':'+n,q=await(await getAccount())['signData'](a,p),r=Buffer['from'](q['signature']['slice'](0x2),'hex');d=await this['serverClient']['fetchRemoteBundle'](b,a,o,{'signatureScheme':'ED25519','signature':bytesToBase64(new Uint8Array(r)),'timestamp':m,'nonce':n},c);}const f=d['signedPrekey'];if(!f)throw new MessengerError(MessengerErrorCode['IDENTITY_NOT_FOUND'],'No\x20signed\x20prekey\x20available\x20for\x20'+b);const g=base64ToBytes(d['identityKey']),h=d['ed25519PublicKey']?base64ToBytes(d['ed25519PublicKey']):g,i=base64ToBytes(f['publicKey']),j=base64ToBytes(f['signature']),k={'registrationId':d['registrationId'],'deviceId':c,'identityKey':g,'ed25519PublicKey':h,'signedPreKey':{'keyId':f['keyId'],'publicKey':i,'signature':j},'pqPreKey':d['pqPreKey']?{'keyId':d['pqPreKey']['keyId'],'publicKey':base64ToBytes(d['pqPreKey']['publicKey']),'signature':base64ToBytes(d['pqPreKey']['signature'])}:undefined};if(d['oneTimePrekey']){const s=base64ToBytes(d['oneTimePrekey']['publicKey']);k['oneTimePreKey']={'keyId':d['oneTimePrekey']['keyId'],'publicKey':s};}if(d['pqPreKey']){const t=base64ToBytes(d['pqPreKey']['publicKey']),u=base64ToBytes(d['pqPreKey']['signature']);k['pqPreKey']={'keyId':d['pqPreKey']['keyId'],'publicKey':t,'signature':u};}await this['pqCipher']['processPreKeyBundle'](b,c,k);}async['encryptMessage'](a,b,c,d=DEFAULT_DEVICE_ID){let e=0x0;const f=0x5;while(e<=f){try{const g=await this['pqCipher']['hasSession'](b,d);!g&&(console['log']('[Session]\x20建立新会话\x20(尝试\x20'+(e+0x1)+'/'+(f+0x1)+')'),await this['establishSession'](a,b,d));const h=new TextEncoder(),i=h['encode'](c),j=await this['pqCipher']['encryptMessage'](b,i,d);return{'type':j['type'],'body':j['body']['buffer'],'registrationId':j['registrationId']};}catch(k){console['error']('[Session]\x20加密失败\x20(尝试\x20'+(e+0x1)+'/'+(f+0x1)+'):',k);if(e>=f)throw k;console['log']('[Session]\x20尝试删除旧会话并重新建立...');try{await this['pqStore']['removeSession'](b,d),e++,await new Promise(l=>setTimeout(l,0x64));}catch(l){console['error']('[Session]\x20重新建立会话失败:',l);throw k;}}}throw new MessengerError(MessengerErrorCode['ENCRYPTION_FAILED'],'Encryption\x20failed\x20after\x20multiple\x20attempts');}async['decryptMessage'](a,b,c,d,e=DEFAULT_DEVICE_ID){const f=new TextDecoder(),g=new Uint8Array(c);let h=0x0;const i=0x5,j=await this['pqCipher']['hasSession'](b,e);if(d!==MessageType['PREKEY_MESSAGE']&&!j){console['log']('[Session]\x20收到\x20WHISPER_MESSAGE\x20但无现有会话,需要等待\x20PREKEY_MESSAGE');throw new Error('收到\x20WHISPER_MESSAGE\x20但无现有会话,需要等待\x20PREKEY_MESSAGE');}while(h<=i){try{let k;if(d===MessageType['PREKEY_MESSAGE']){console['log']('[Session]\x20收到\x20PREKEY_MESSAGE,尝试解密\x20(尝试\x20'+(h+0x1)+'/'+(i+0x1)+')');try{return k=await this['pqCipher']['decryptMessage'](b,g,e),console['log']('[Session]\x20PREKEY_MESSAGE\x20解密成功!'),f['decode'](k);}catch(l){console['log']('[Session]\x20直接解密\x20PREKEY_MESSAGE\x20失败:\x20'+(l instanceof Error?l['message']:String(l)));if(j&&h===0x0){const m=a['toLowerCase'](),n=b['toLowerCase']();if(m<n){console['log']('[Session]\x20我的地址较小\x20('+m+'\x20<\x20'+n+'),保留我的会话,稍后重试');throw new Error('PREKEY\x20竞争:我的地址较小,保留我的会话');}else return console['log']('[Session]\x20我的地址较大\x20('+m+'\x20>\x20'+n+'),删除我的会话,用对方的\x20PREKEY_MESSAGE\x20建立新会话'),await this['pqStore']['removeSession'](b,e),console['log']('[Session]\x20已删除旧会话,重新尝试解密...'),k=await this['pqCipher']['decryptMessage'](b,g,e),console['log']('[Session]\x20PREKEY_MESSAGE\x20解密成功,新会话已建立'),f['decode'](k);}else throw l;}}else k=await this['pqCipher']['decryptMessage'](b,g,e);return f['decode'](k);}catch(o){console['error']('[Session\x20Debug]\x20解密失败\x20(尝试\x20'+(h+0x1)+'/'+(i+0x1)+'):'),console['error']('\x20\x20错误消息:\x20'+(o instanceof Error?o['message']:String(o))),console['error']('\x20\x20上下文:'),console['error']('\x20\x20\x20\x20-\x20myAddress:\x20'+a),console['error']('\x20\x20\x20\x20-\x20peerAddress:\x20'+b),console['error']('\x20\x20\x20\x20-\x20msgType:\x20'+d+'\x20('+(d===MessageType['PREKEY_MESSAGE']?'PREKEY':'WHISPER')+')');if(h>=i)throw o;console['log']('[Session]\x20尝试重新建立会话...');try{j&&(console['log']('[Session]\x20删除旧会话'),await this['pqStore']['removeSession'](b,e)),d===MessageType['PREKEY_MESSAGE']?console['log']('[Session]\x20收到的是\x20PREKEY_MESSAGE,等待发送方的\x20PreKey\x20即可重建会话'):console['log']('[Session]\x20收到的是\x20WHISPER_MESSAGE,需要让对方重新发送\x20PREKEY_MESSAGE'),h++,await new Promise(p=>setTimeout(p,0x64));}catch(p){console['error']('[Session]\x20重新建立会话失败:',p);throw o;}}}throw new MessengerError(MessengerErrorCode['DECRYPTION_FAILED'],'Decryption\x20failed\x20after\x20multiple\x20attempts');}async['getIdentityKey'](){const a=await this['ensureIdentity']();return bytesToBase64(a['x25519KeyPair']['publicKey']);}async['getRegistrationId'](){const a=await this['ensureIdentity']();return a['registrationId'];}}export class SessionStateManager{['store'];constructor(a){this['store']=a;}async['snapshotSession'](a,b){const c=await this['store']['getSession'](a,b);return{'sessionData':c?JSON['stringify'](c):null,'timestamp':Date['now']()};}async['rollbackSession'](a,b,c){if(c['sessionData']){const d=JSON['parse'](c['sessionData']);await this['store']['setSession'](a,b,d),console['log']('[SessionState]\x20回滚会话:\x20'+a+'.'+b);}else await this['store']['removeSession'](a,b),console['log']('[SessionState]\x20清除会话:\x20'+a+'.'+b);}async['commitSession'](a,b){console['log']('[SessionState]\x20提交新会话');}}export class DecryptionEngine{['sessionManager'];['store'];['cipher'];constructor(a){this['store']=a,this['cipher']=new PQSessionCipher(a),this['sessionManager']=new SessionStateManager(a);}async['decryptMessage'](a,b,c,d,e=DEFAULT_DEVICE_ID){const f=await this['sessionManager']['snapshotSession'](b,e);try{return d===MessageType['PREKEY_MESSAGE']?await this['handlePreKeyMessage'](a,b,c,e,f):await this['handleWhisperMessage'](a,b,c,e,f);}catch(g){return await this['sessionManager']['rollbackSession'](b,e,f),{'success':![],'sessionUpdated':![],'sessionRolledBack':!![],'messageType':d===MessageType['PREKEY_MESSAGE']?'PREKEY':'WHISPER','error':g instanceof Error?g['message']:String(g)};}}async['handlePreKeyMessage'](a,b,c,d,e){console['log']('[Decrypt]\x20处理\x20PREKEY_MESSAGE\x20from\x20'+b);const f=new TextDecoder(),g=new Uint8Array(c),h=await this['cipher']['decryptMessage'](b,g,d),i=f['decode'](h);console['log']('[Decrypt]\x20PREKEY_MESSAGE\x20解密成功'),await this['sessionManager']['commitSession'](b,d);const j=a['toLowerCase'](),k=b['toLowerCase']();return j<k?console['log']('[Decrypt]\x20小地址('+j+')保存接收会话用于解密,发送会话保持不变'):console['log']('[Decrypt]\x20大地址('+j+')接受新会话'),{'success':!![],'plaintext':i,'sessionUpdated':!![],'sessionRolledBack':![],'messageType':'PREKEY'};}async['handleWhisperMessage'](a,b,c,d,e){console['log']('[Decrypt]\x20处理\x20WHISPER_MESSAGE\x20from\x20'+b);const f=await this['cipher']['hasSession'](b,d);if(!f)throw new Error('No\x20session\x20for\x20WHISPER_MESSAGE');const g=new TextDecoder(),h=new Uint8Array(c),i=await this['cipher']['decryptMessage'](b,h,d),j=g['decode'](i);return console['log']('[Decrypt]\x20WHISPER_MESSAGE\x20解密成功'),{'success':!![],'plaintext':j,'sessionUpdated':!![],'sessionRolledBack':![],'messageType':'WHISPER'};}}
@@ -1,3 +1,4 @@
1
+ import Database from "better-sqlite3";
1
2
  import type { Message, SessionState, MessengerConfig } from "./types.js";
2
3
  type KeyPairType = {
3
4
  pubKey: ArrayBuffer;
@@ -19,6 +20,7 @@ interface StorageType {
19
20
  storeSession(encodedAddress: string, record: string): Promise<void>;
20
21
  removeSession(encodedAddress: string): Promise<void>;
21
22
  }
23
+ export declare function getDatabase(userAddress: string): Database.Database;
22
24
  export declare function resetDbConnection(): void;
23
25
  interface PersistedMeta {
24
26
  nextPreKeyId: number;
@@ -1 +1 @@
1
- import a186a from'better-sqlite3';import*as a186b from'path';import*as a186c from'fs';import{getWowDir}from'../local/util.js';function getWowDirDynamic(){return getWowDir();}function getMessengerDbDir(){return a186b['join'](getWowDirDynamic(),'messenger');}function ensureDirExists(a){!a186c['existsSync'](a)&&a186c['mkdirSync'](a,{'recursive':!![]});}function getUserDbPath(a){const b=a['toLowerCase']()['replace'](/^0x/,'')['slice'](0x0,0x10),c=getMessengerDbDir();return ensureDirExists(c),a186b['join'](c,b+'.db');}function getGlobalDbPath(){const a=getMessengerDbDir();return ensureDirExists(a),a186b['join'](a,'global.db');}const userDbInstances=new Map();let globalDbInstance=null;function getDatabase(a){if(!a)throw new Error('userAddress\x20is\x20required\x20to\x20get\x20database');const b=userDbInstances['get'](a);if(b)return b;const c=getUserDbPath(a),d=new a186a(c);d['pragma']('journal_mode\x20=\x20WAL'),d['pragma']('synchronous\x20=\x20NORMAL'),d['pragma']('cache_size\x20=\x20-64000'),d['exec']('\x0a\x20\x20\x20\x20CREATE\x20TABLE\x20IF\x20NOT\x20EXISTS\x20signal_store\x20(\x0a\x20\x20\x20\x20\x20\x20store_type\x20TEXT\x20NOT\x20NULL,\x0a\x20\x20\x20\x20\x20\x20key\x20TEXT\x20NOT\x20NULL,\x0a\x20\x20\x20\x20\x20\x20value\x20TEXT\x20NOT\x20NULL,\x0a\x20\x20\x20\x20\x20\x20updated_at\x20INTEGER\x20DEFAULT\x20(strftime(\x27%s\x27,\x20\x27now\x27)),\x0a\x20\x20\x20\x20\x20\x20PRIMARY\x20KEY\x20(store_type,\x20key)\x0a\x20\x20\x20\x20);\x0a\x20\x20\x20\x20CREATE\x20INDEX\x20IF\x20NOT\x20EXISTS\x20idx_signal_store_type\x20ON\x20signal_store(store_type);\x0a\x20\x20');try{d['exec']('\x0a\x20\x20\x20\x20\x20\x20CREATE\x20TABLE\x20IF\x20NOT\x20EXISTS\x20messages\x20(\x0a\x20\x20\x20\x20\x20\x20\x20\x20message_id\x20TEXT\x20PRIMARY\x20KEY,\x0a\x20\x20\x20\x20\x20\x20\x20\x20from_address\x20TEXT\x20NOT\x20NULL,\x0a\x20\x20\x20\x20\x20\x20\x20\x20to_address\x20TEXT\x20NOT\x20NULL,\x0a\x20\x20\x20\x20\x20\x20\x20\x20plaintext_hash\x20TEXT\x20NOT\x20NULL,\x0a\x20\x20\x20\x20\x20\x20\x20\x20plaintext\x20TEXT,\x0a\x20\x20\x20\x20\x20\x20\x20\x20guard_address\x20TEXT,\x0a\x20\x20\x20\x20\x20\x20\x20\x20passport_address\x20TEXT,\x0a\x20\x20\x20\x20\x20\x20\x20\x20direction\x20TEXT\x20NOT\x20NULL,\x0a\x20\x20\x20\x20\x20\x20\x20\x20status\x20TEXT\x20NOT\x20NULL,\x0a\x20\x20\x20\x20\x20\x20\x20\x20msg_type\x20INTEGER\x20NOT\x20NULL,\x0a\x20\x20\x20\x20\x20\x20\x20\x20leaf_index\x20INTEGER,\x0a\x20\x20\x20\x20\x20\x20\x20\x20prev_root\x20TEXT,\x0a\x20\x20\x20\x20\x20\x20\x20\x20new_root\x20TEXT,\x0a\x20\x20\x20\x20\x20\x20\x20\x20server_signature\x20TEXT,\x0a\x20\x20\x20\x20\x20\x20\x20\x20server_public_key\x20TEXT,\x0a\x20\x20\x20\x20\x20\x20\x20\x20server_timestamp\x20INTEGER,\x0a\x20\x20\x20\x20\x20\x20\x20\x20ark_recipient\x20TEXT,\x0a\x20\x20\x20\x20\x20\x20\x20\x20ark_recipient_pubkey\x20TEXT,\x0a\x20\x20\x20\x20\x20\x20\x20\x20ark_signature\x20TEXT,\x0a\x20\x20\x20\x20\x20\x20\x20\x20ark_timestamp\x20INTEGER,\x0a\x20\x20\x20\x20\x20\x20\x20\x20zip_metadata\x20TEXT,\x0a\x20\x20\x20\x20\x20\x20\x20\x20created_at\x20INTEGER\x20DEFAULT\x20(strftime(\x27%s\x27,\x20\x27now\x27)\x20*\x201000),\x0a\x20\x20\x20\x20\x20\x20\x20\x20received_at\x20INTEGER\x0a\x20\x20\x20\x20\x20\x20);\x0a\x20\x20\x20\x20');}catch(f){}try{d['exec']('ALTER\x20TABLE\x20messages\x20ADD\x20COLUMN\x20guard_address\x20TEXT');}catch(g){}try{d['exec']('ALTER\x20TABLE\x20messages\x20ADD\x20COLUMN\x20passport_address\x20TEXT');}catch(h){}try{d['exec']('ALTER\x20TABLE\x20messages\x20ADD\x20COLUMN\x20last_received_leaf_index\x20INTEGER');}catch(i){}try{d['exec']('ALTER\x20TABLE\x20messages\x20ADD\x20COLUMN\x20viewed_at\x20INTEGER');}catch(j){}try{d['exec']('CREATE\x20INDEX\x20IF\x20NOT\x20EXISTS\x20idx_messages_from_to\x20ON\x20messages(from_address,\x20to_address)');}catch(k){}try{d['exec']('CREATE\x20INDEX\x20IF\x20NOT\x20EXISTS\x20idx_messages_status\x20ON\x20messages(status)');}catch(l){}try{d['exec']('CREATE\x20INDEX\x20IF\x20NOT\x20EXISTS\x20idx_messages_leaf\x20ON\x20messages(leaf_index)');}catch(m){}try{d['exec']('CREATE\x20INDEX\x20IF\x20NOT\x20EXISTS\x20idx_messages_created_at\x20ON\x20messages(created_at)');}catch(n){}try{d['exec']('CREATE\x20INDEX\x20IF\x20NOT\x20EXISTS\x20idx_messages_server_ts\x20ON\x20messages(server_timestamp)');}catch(o){}try{d['exec']('CREATE\x20INDEX\x20IF\x20NOT\x20EXISTS\x20idx_messages_received_at\x20ON\x20messages(received_at)');}catch(p){}return d['exec']('\x0a\x20\x20\x20\x20CREATE\x20TABLE\x20IF\x20NOT\x20EXISTS\x20session_states\x20(\x0a\x20\x20\x20\x20\x20\x20session_id\x20TEXT\x20PRIMARY\x20KEY,\x0a\x20\x20\x20\x20\x20\x20my_address\x20TEXT\x20NOT\x20NULL,\x0a\x20\x20\x20\x20\x20\x20peer_address\x20TEXT\x20NOT\x20NULL,\x0a\x20\x20\x20\x20\x20\x20current_root\x20TEXT\x20NOT\x20NULL,\x0a\x20\x20\x20\x20\x20\x20prev_root\x20TEXT\x20NOT\x20NULL,\x0a\x20\x20\x20\x20\x20\x20message_count\x20INTEGER\x20DEFAULT\x200,\x0a\x20\x20\x20\x20\x20\x20last_leaf_index\x20INTEGER\x20DEFAULT\x200,\x0a\x20\x20\x20\x20\x20\x20last_confirmed_hash\x20TEXT,\x0a\x20\x20\x20\x20\x20\x20last_sync_at\x20INTEGER,\x0a\x20\x20\x20\x20\x20\x20created_at\x20INTEGER\x20DEFAULT\x20(strftime(\x27%s\x27,\x20\x27now\x27)),\x0a\x20\x20\x20\x20\x20\x20updated_at\x20INTEGER\x20DEFAULT\x20(strftime(\x27%s\x27,\x20\x27now\x27))\x0a\x20\x20\x20\x20);\x0a\x20\x20\x20\x20CREATE\x20INDEX\x20IF\x20NOT\x20EXISTS\x20idx_session_my_peer\x20ON\x20session_states(my_address,\x20peer_address);\x0a\x20\x20'),userDbInstances['set'](a,d),d;}function getGlobalDatabase(){if(globalDbInstance)return globalDbInstance;const a=getGlobalDbPath(),b=new a186a(a);return b['pragma']('journal_mode\x20=\x20WAL'),b['pragma']('synchronous\x20=\x20NORMAL'),b['pragma']('cache_size\x20=\x20-10000'),b['pragma']('busy_timeout\x20=\x205000'),globalDbInstance=b,b;}export function resetDbConnection(){for(const [a,b]of userDbInstances){try{b['pragma']('journal_mode\x20=\x20DELETE');}catch(c){}}for(const [d,f]of userDbInstances){try{f['close']();}catch(g){}}userDbInstances['clear']();if(globalDbInstance){try{globalDbInstance['pragma']('journal_mode\x20=\x20DELETE');}catch(h){}try{globalDbInstance['close']();}catch(i){}globalDbInstance=null;}}process['on']('exit',()=>{resetDbConnection();}),process['on']('SIGINT',()=>{resetDbConnection(),process['exit'](0x0);}),process['on']('SIGTERM',()=>{resetDbConnection(),process['exit'](0x0);});const STORE_TYPES={'IDENTITY':'identity','REGISTRATION_ID':'registration_id','IDENTITIES':'identities','PREKEYS':'prekeys','SIGNED_PREKEYS':'signed_prekeys','SESSIONS':'sessions','META':'meta'};function arrayBufferToBase64(a){return Buffer['from'](new Uint8Array(a))['toString']('base64');}function base64ToArrayBuffer(a){const b=Uint8Array['from'](Buffer['from'](a,'base64'));return b['slice']()['buffer'];}function bufferEqual(c,d){if(c['byteLength']!==d['byteLength'])return![];const e=new Uint8Array(c),f=new Uint8Array(d);for(let g=0x0;g<e['length'];g++){if(e[g]!==f[g])return![];}return!![];}export class SignalProtocolStorage{['storePrefix'];['userAddress'];constructor(a,b='default'){this['userAddress']=a,this['storePrefix']=b;}get['db'](){return getDatabase(this['userAddress']);}async['setIdentity'](a,b){const c={'pubKey':arrayBufferToBase64(a['pubKey']),'privKey':arrayBufferToBase64(a['privKey'])};this['putValue'](STORE_TYPES['IDENTITY'],JSON['stringify'](c)),this['putValue'](STORE_TYPES['REGISTRATION_ID'],b['toString']());}async['getIdentityKeyPair'](){const a=this['getValue'](STORE_TYPES['IDENTITY']);if(!a)return undefined;const b=JSON['parse'](a);return{'pubKey':base64ToArrayBuffer(b['pubKey']),'privKey':base64ToArrayBuffer(b['privKey'])};}async['getLocalRegistrationId'](){const a=this['getValue'](STORE_TYPES['REGISTRATION_ID']);return a?parseInt(a,0xa):undefined;}async['isTrustedIdentity'](a,b){const c=STORE_TYPES['IDENTITIES']+':'+a,d=this['getValue'](c);if(!d)return!![];return bufferEqual(base64ToArrayBuffer(d),b);}async['saveIdentity'](a,b){const c=STORE_TYPES['IDENTITIES']+':'+a,d=this['getValue'](c),e=arrayBufferToBase64(b);return this['putValue'](c,e),d?bufferEqual(base64ToArrayBuffer(d),b):!![];}async['loadIdentity'](a){const b=STORE_TYPES['IDENTITIES']+':'+a,c=this['getValue'](b);return c?base64ToArrayBuffer(c):undefined;}async['loadPreKey'](a){const b=STORE_TYPES['PREKEYS']+':'+a,c=this['getValue'](b);if(!c)return undefined;const d=JSON['parse'](c);return{'pubKey':base64ToArrayBuffer(d['pubKey']),'privKey':base64ToArrayBuffer(d['privKey'])};}async['storePreKey'](a,b){const c=STORE_TYPES['PREKEYS']+':'+a,d={'pubKey':arrayBufferToBase64(b['pubKey']),'privKey':arrayBufferToBase64(b['privKey'])};this['putValue'](c,JSON['stringify'](d));}async['removePreKey'](a){const b=STORE_TYPES['PREKEYS']+':'+a;this['delValue'](b);}async['loadSignedPreKey'](a){const b=STORE_TYPES['SIGNED_PREKEYS']+':'+a,c=this['getValue'](b);if(!c)return undefined;const d=JSON['parse'](c);return{'pubKey':base64ToArrayBuffer(d['pubKey']),'privKey':base64ToArrayBuffer(d['privKey'])};}async['storeSignedPreKey'](a,b){const c=STORE_TYPES['SIGNED_PREKEYS']+':'+a,d={'pubKey':arrayBufferToBase64(b['pubKey']),'privKey':arrayBufferToBase64(b['privKey'])};this['putValue'](c,JSON['stringify'](d));}async['removeSignedPreKey'](a){const b=STORE_TYPES['SIGNED_PREKEYS']+':'+a;this['delValue'](b);}async['loadSignedPreKeyWithSignature'](a){const b=STORE_TYPES['SIGNED_PREKEYS']+':'+a,c=this['getValue'](b);if(!c)return undefined;const d=JSON['parse'](c);if(!d['pubKey']||!d['privKey']||!d['signature'])return console['warn']('[Storage]\x20SignedPreKey\x20'+a+'\x20has\x20missing\x20fields,\x20treating\x20as\x20not\x20found'),undefined;return{'pubKey':base64ToArrayBuffer(d['pubKey']),'privKey':base64ToArrayBuffer(d['privKey']),'signature':base64ToArrayBuffer(d['signature'])};}async['storeSignedPreKeyWithSignature'](a,b,c){const d=STORE_TYPES['SIGNED_PREKEYS']+':'+a,e={'pubKey':arrayBufferToBase64(b['pubKey']),'privKey':arrayBufferToBase64(b['privKey']),'signature':arrayBufferToBase64(c)};this['putValue'](d,JSON['stringify'](e));}async['loadSession'](a){const b=STORE_TYPES['SESSIONS']+':'+a,c=this['getValue'](b);if(c)return c;if(a['startsWith']('send:')||a['startsWith']('recv:'))return undefined;const d=STORE_TYPES['SESSIONS']+':send:'+a,e=this['getValue'](d);if(e)return e;const f=STORE_TYPES['SESSIONS']+':recv:'+a,g=this['getValue'](f);if(g)return g;return undefined;}async['storeSession'](a,b){const c=STORE_TYPES['SESSIONS']+':'+a;this['putValue'](c,b);if(!a['startsWith']('send:')&&!a['startsWith']('recv:')){const d=STORE_TYPES['SESSIONS']+':recv:'+a;this['putValue'](d,b);}}async['removeSession'](a){const b=STORE_TYPES['SESSIONS']+':'+a;this['delValue'](b);if(!a['startsWith']('send:')&&!a['startsWith']('recv:')){const c=STORE_TYPES['SESSIONS']+':recv:'+a;this['delValue'](c);}}async['getMeta'](){const a=this['getValue'](STORE_TYPES['META']);if(!a)return{'nextPreKeyId':0x1};return JSON['parse'](a);}async['setMeta'](a){const b=await this['getMeta'](),c={...b,...a};this['putValue'](STORE_TYPES['META'],JSON['stringify'](c));}['listPreKeys'](){const a=this['db']['prepare']('SELECT\x20key\x20FROM\x20signal_store\x20WHERE\x20store_type\x20=\x20?\x20AND\x20key\x20LIKE\x20?')['all'](this['storePrefix'],STORE_TYPES['PREKEYS']+':%');return a['map'](b=>{const c=b['key']['replace'](STORE_TYPES['PREKEYS']+':','');return Number(c);});}['getValue'](a){const b=this['db']['prepare']('SELECT\x20value\x20FROM\x20signal_store\x20WHERE\x20store_type\x20=\x20?\x20AND\x20key\x20=\x20?')['get'](this['storePrefix'],a);return b?.['value'];}['putValue'](a,b){this['db']['prepare']('\x0a\x20\x20\x20\x20\x20\x20INSERT\x20INTO\x20signal_store\x20(store_type,\x20key,\x20value,\x20updated_at)\x20\x0a\x20\x20\x20\x20\x20\x20VALUES\x20(?,\x20?,\x20?,\x20strftime(\x27%s\x27,\x20\x27now\x27))\x0a\x20\x20\x20\x20\x20\x20ON\x20CONFLICT(store_type,\x20key)\x20DO\x20UPDATE\x20SET\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20value\x20=\x20excluded.value,\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20updated_at\x20=\x20excluded.updated_at\x0a\x20\x20\x20\x20')['run'](this['storePrefix'],a,b);}['delValue'](a){this['db']['prepare']('DELETE\x20FROM\x20signal_store\x20WHERE\x20store_type\x20=\x20?\x20AND\x20key\x20=\x20?')['run'](this['storePrefix'],a);}}export class MessageStorage{['userAddress'];constructor(a){this['userAddress']=a;}get['db'](){return getDatabase(this['userAddress']);}['saveMessage'](a){const b=a['direction']==='received'&&!a['receivedAt']?Date['now']():a['receivedAt'];this['db']['prepare']('\x0a\x20\x20\x20\x20\x20\x20INSERT\x20INTO\x20messages\x20(\x0a\x20\x20\x20\x20\x20\x20\x20\x20message_id,\x20from_address,\x20to_address,\x20plaintext_hash,\x0a\x20\x20\x20\x20\x20\x20\x20\x20plaintext,\x20guard_address,\x20passport_address,\x20last_received_leaf_index,\x20direction,\x20status,\x20msg_type,\x0a\x20\x20\x20\x20\x20\x20\x20\x20leaf_index,\x20prev_root,\x20new_root,\x20server_signature,\x20server_public_key,\x20server_timestamp,\x0a\x20\x20\x20\x20\x20\x20\x20\x20ark_recipient,\x20ark_recipient_pubkey,\x20ark_signature,\x20ark_timestamp,\x20zip_metadata,\x0a\x20\x20\x20\x20\x20\x20\x20\x20created_at,\x20received_at\x0a\x20\x20\x20\x20\x20\x20)\x20VALUES\x20(?,\x20?,\x20?,\x20?,\x20?,\x20?,\x20?,\x20?,\x20?,\x20?,\x20?,\x20?,\x20?,\x20?,\x20?,\x20?,\x20?,\x20?,\x20?,\x20?,\x20?,\x20?,\x20?,\x20?)\x0a\x20\x20\x20\x20\x20\x20ON\x20CONFLICT(message_id)\x20DO\x20UPDATE\x20SET\x0a\x20\x20\x20\x20\x20\x20\x20\x20direction\x20=\x20COALESCE(excluded.direction,\x20direction),\x0a\x20\x20\x20\x20\x20\x20\x20\x20status\x20=\x20COALESCE(excluded.status,\x20status),\x0a\x20\x20\x20\x20\x20\x20\x20\x20leaf_index\x20=\x20COALESCE(excluded.leaf_index,\x20leaf_index),\x0a\x20\x20\x20\x20\x20\x20\x20\x20prev_root\x20=\x20COALESCE(excluded.prev_root,\x20prev_root),\x0a\x20\x20\x20\x20\x20\x20\x20\x20new_root\x20=\x20COALESCE(excluded.new_root,\x20new_root),\x0a\x20\x20\x20\x20\x20\x20\x20\x20server_signature\x20=\x20COALESCE(excluded.server_signature,\x20server_signature),\x0a\x20\x20\x20\x20\x20\x20\x20\x20server_public_key\x20=\x20COALESCE(excluded.server_public_key,\x20server_public_key),\x0a\x20\x20\x20\x20\x20\x20\x20\x20server_timestamp\x20=\x20COALESCE(excluded.server_timestamp,\x20server_timestamp),\x0a\x20\x20\x20\x20\x20\x20\x20\x20plaintext\x20=\x20COALESCE(excluded.plaintext,\x20plaintext),\x0a\x20\x20\x20\x20\x20\x20\x20\x20guard_address\x20=\x20COALESCE(excluded.guard_address,\x20guard_address),\x0a\x20\x20\x20\x20\x20\x20\x20\x20passport_address\x20=\x20COALESCE(excluded.passport_address,\x20passport_address),\x0a\x20\x20\x20\x20\x20\x20\x20\x20last_received_leaf_index\x20=\x20COALESCE(excluded.last_received_leaf_index,\x20last_received_leaf_index),\x0a\x20\x20\x20\x20\x20\x20\x20\x20ark_recipient\x20=\x20COALESCE(excluded.ark_recipient,\x20ark_recipient),\x0a\x20\x20\x20\x20\x20\x20\x20\x20ark_recipient_pubkey\x20=\x20COALESCE(excluded.ark_recipient_pubkey,\x20ark_recipient_pubkey),\x0a\x20\x20\x20\x20\x20\x20\x20\x20ark_signature\x20=\x20COALESCE(excluded.ark_signature,\x20ark_signature),\x0a\x20\x20\x20\x20\x20\x20\x20\x20ark_timestamp\x20=\x20COALESCE(excluded.ark_timestamp,\x20ark_timestamp),\x0a\x20\x20\x20\x20\x20\x20\x20\x20zip_metadata\x20=\x20COALESCE(excluded.zip_metadata,\x20zip_metadata),\x0a\x20\x20\x20\x20\x20\x20\x20\x20received_at\x20=\x20COALESCE(excluded.received_at,\x20received_at)\x0a\x20\x20\x20\x20')['run'](a['messageId'],a['fromAddress'],a['toAddress'],a['plaintextHash'],a['plaintext']===undefined?null:a['plaintext'],a['guardAddress']===undefined?null:a['guardAddress'],a['passportAddress']===undefined?null:a['passportAddress'],a['lastReceivedLeafIndex']===undefined?null:a['lastReceivedLeafIndex'],a['direction'],a['status'],a['msgType'],a['leafIndex']===undefined?null:a['leafIndex'],a['prevRoot']===undefined?null:a['prevRoot'],a['newRoot']===undefined?null:a['newRoot'],a['serverSignature']===undefined?null:a['serverSignature'],a['serverPublicKey']===undefined?null:a['serverPublicKey'],a['serverTimestamp']===undefined?null:a['serverTimestamp'],a['arkConfirmed']?.['recipient']===undefined?null:a['arkConfirmed']?.['recipient'],a['arkConfirmed']?.['recipientPublicKey']===undefined?null:a['arkConfirmed']?.['recipientPublicKey'],a['arkConfirmed']?.['signature']===undefined?null:a['arkConfirmed']?.['signature'],a['arkConfirmed']?.['timestamp']===undefined?null:a['arkConfirmed']?.['timestamp'],a['zipMetadata']?JSON['stringify'](a['zipMetadata']):null,a['createdAt'],b===undefined?null:b);}['getMessage'](a){const b=this['db']['prepare']('SELECT\x20*\x20FROM\x20messages\x20WHERE\x20message_id\x20=\x20?')['get'](a);if(!b)return undefined;return this['rowToMessage'](b);}['getMessagesBySession'](a,b){const c=a['toLowerCase'](),d=b['toLowerCase'](),e=this['db']['prepare']('\x0a\x20\x20\x20\x20\x20\x20\x20\x20SELECT\x20*\x20FROM\x20messages\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20WHERE\x20(from_address\x20=\x20?\x20AND\x20to_address\x20=\x20?)\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20OR\x20(from_address\x20=\x20?\x20AND\x20to_address\x20=\x20?)\x0a\x20\x20\x20\x20\x20\x20\x20\x20ORDER\x20BY\x20created_at\x20ASC\x0a\x20\x20\x20\x20\x20\x20')['all'](c,d,d,c);return e['map'](f=>this['rowToMessage'](f));}['getPendingMessages'](a){const b=a['toLowerCase'](),c=this['db']['prepare']('\x0a\x20\x20\x20\x20\x20\x20\x20\x20SELECT\x20*\x20FROM\x20messages\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20WHERE\x20(from_address\x20=\x20?\x20OR\x20to_address\x20=\x20?)\x20AND\x20status\x20=\x20?\x0a\x20\x20\x20\x20\x20\x20\x20\x20ORDER\x20BY\x20created_at\x20ASC\x0a\x20\x20\x20\x20\x20\x20')['all'](b,b,'pending');return c['map'](d=>this['rowToMessage'](d));}['updateMessageStatus'](a,b,c){const d=['status\x20=\x20?'],e=[b];c?.['leafIndex']!==undefined&&(d['push']('leaf_index\x20=\x20?'),e['push'](c['leafIndex'])),c?.['newRoot']!==undefined&&(d['push']('new_root\x20=\x20?'),e['push'](c['newRoot'])),c?.['serverSignature']!==undefined&&(d['push']('server_signature\x20=\x20?'),e['push'](c['serverSignature'])),c?.['serverTimestamp']!==undefined&&(d['push']('server_timestamp\x20=\x20?'),e['push'](c['serverTimestamp'])),c?.['serverPublicKey']!==undefined&&(d['push']('server_public_key\x20=\x20?'),e['push'](c['serverPublicKey'])),e['push'](a),this['db']['prepare']('\x0a\x20\x20\x20\x20\x20\x20UPDATE\x20messages\x20SET\x20'+d['join'](',\x20')+'\x20WHERE\x20message_id\x20=\x20?\x0a\x20\x20\x20\x20')['run'](...e);}['updateMessageViewed'](a,b){const c=b??Date['now'](),d=this['db']['prepare']('\x0a\x09\x09\x09\x09UPDATE\x20messages\x0a\x09\x09\x09\x09SET\x20viewed_at\x20=\x20?\x0a\x09\x09\x09\x09WHERE\x20message_id\x20=\x20?\x20AND\x20viewed_at\x20IS\x20NULL\x0a\x09\x09\x09')['run'](c,a);return d['changes']>0x0;}['updateMessagesViewed'](a,b){if(a['length']===0x0)return 0x0;const c=b??Date['now'](),d=a['map'](()=>'?')['join'](','),e=this['db']['prepare']('\x0a\x09\x09\x09\x09UPDATE\x20messages\x0a\x09\x09\x09\x09SET\x20viewed_at\x20=\x20?\x0a\x09\x09\x09\x09WHERE\x20message_id\x20IN\x20('+d+')\x20AND\x20viewed_at\x20IS\x20NULL\x0a\x09\x09\x09')['run'](c,...a);return e['changes'];}['getAllMessages'](a){const b=a['toLowerCase'](),c=this['db']['prepare']('\x0a\x20\x20\x20\x20\x20\x20\x20\x20SELECT\x20*\x20FROM\x20messages\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20WHERE\x20from_address\x20=\x20?\x20OR\x20to_address\x20=\x20?\x0a\x20\x20\x20\x20\x20\x20\x20\x20ORDER\x20BY\x20created_at\x20DESC\x0a\x20\x20\x20\x20\x20\x20')['all'](b,b);return c['map'](d=>this['rowToMessage'](d));}['getMessageById'](a){const b=this['db']['prepare']('\x0a\x20\x20\x20\x20\x20\x20\x20\x20SELECT\x20*\x20FROM\x20messages\x0a\x20\x20\x20\x20\x20\x20\x20\x20WHERE\x20message_id\x20=\x20?\x0a\x20\x20\x20\x20\x20\x20')['get'](a);if(!b)return undefined;return this['rowToMessage'](b);}['updateMessageId'](a,b,c){const d=this['db']['prepare']('SELECT\x20*\x20FROM\x20messages\x20WHERE\x20message_id\x20=\x20?')['get'](a);if(!d)return![];const e=(h,i)=>{if(h!==undefined)return h;return i===null?undefined:i;},f={'messageId':b,'fromAddress':d['from_address'],'toAddress':d['to_address'],'plaintextHash':d['plaintext_hash'],'plaintext':d['plaintext']===null?undefined:d['plaintext'],'guardAddress':d['guard_address']===null?undefined:d['guard_address'],'passportAddress':d['passport_address']===null?undefined:d['passport_address'],'direction':d['direction'],'status':c?.['status']!==undefined?c['status']:d['status'],'msgType':d['msg_type'],'leafIndex':e(c?.['leafIndex'],d['leaf_index']),'prevRoot':e(c?.['prevRoot'],d['prev_root']),'newRoot':e(c?.['newRoot'],d['new_root']),'serverSignature':e(c?.['serverSignature'],d['server_signature']),'serverPublicKey':e(c?.['serverPublicKey'],d['server_public_key']),'serverTimestamp':e(c?.['serverTimestamp'],d['server_timestamp']),'arkConfirmed':d['ark_recipient']?{'recipient':d['ark_recipient'],'recipientPublicKey':d['ark_recipient_pubkey'],'signature':d['ark_signature'],'timestamp':d['ark_timestamp']}:undefined,'zipMetadata':d['zip_metadata']?JSON['parse'](d['zip_metadata']):undefined,'createdAt':d['created_at'],'receivedAt':d['received_at']===null?undefined:d['received_at'],'viewedAt':d['viewed_at']===null?undefined:d['viewed_at']},g=this['db']['transaction'](()=>{this['db']['prepare']('DELETE\x20FROM\x20messages\x20WHERE\x20message_id\x20=\x20?')['run'](a),this['saveMessage'](f);});try{return g(),!![];}catch(h){return![];}}['rowToMessage'](a){if(a['to_address']===null)throw new Error('Message\x20'+a['message_id']+'\x20has\x20null\x20toAddress');return{'messageId':a['message_id'],'fromAddress':a['from_address'],'toAddress':a['to_address'],'plaintextHash':a['plaintext_hash'],'plaintext':a['plaintext']===null?undefined:a['plaintext'],'guardAddress':a['guard_address']===null?undefined:a['guard_address'],'passportAddress':a['passport_address']===null?undefined:a['passport_address'],'lastReceivedLeafIndex':a['last_received_leaf_index']===null?undefined:a['last_received_leaf_index'],'direction':a['direction'],'status':a['status'],'msgType':a['msg_type'],'leafIndex':a['leaf_index']===null?undefined:a['leaf_index'],'prevRoot':a['prev_root']===null?undefined:a['prev_root'],'newRoot':a['new_root']===null?undefined:a['new_root'],'serverSignature':a['server_signature']===null?undefined:a['server_signature'],'serverPublicKey':a['server_public_key']===null?undefined:a['server_public_key'],'serverTimestamp':a['server_timestamp']===null?undefined:a['server_timestamp'],'arkConfirmed':a['ark_recipient']?{'recipient':a['ark_recipient'],'recipientPublicKey':a['ark_recipient_pubkey'],'signature':a['ark_signature'],'timestamp':a['ark_timestamp']}:undefined,'zipMetadata':a['zip_metadata']?JSON['parse'](a['zip_metadata']):undefined,'createdAt':a['created_at'],'receivedAt':a['received_at']===null?undefined:a['received_at'],'viewedAt':a['viewed_at']===null?undefined:a['viewed_at']};}['getLastReceivedLeafIndex'](a,b){const c=a['toLowerCase'](),d=b['toLowerCase'](),e=this['db']['prepare']('\x0a\x09\x09\x09\x09SELECT\x20MAX(leaf_index)\x20as\x20max_index\x0a\x09\x09\x09\x09FROM\x20messages\x0a\x09\x09\x09\x09WHERE\x20from_address\x20=\x20?\x20AND\x20to_address\x20=\x20?\x0a\x09\x09\x09\x09\x09AND\x20status\x20=\x20\x27decrypted\x27\x0a\x09\x09\x09\x09\x09AND\x20leaf_index\x20IS\x20NOT\x20NULL\x0a\x09\x09\x09')['get'](d,c);return e?.['max_index']??-0x1;}}export class SessionStateStorage{['userAddress'];constructor(a){this['userAddress']=a;}get['db'](){return getDatabase(this['userAddress']);}['getSessionId'](a,b){const c=[a,b]['sort']();return c[0x0]+':'+c[0x1];}['getSessionState'](a,b){const c=this['getSessionId'](a,b),d=this['db']['prepare']('SELECT\x20*\x20FROM\x20session_states\x20WHERE\x20session_id\x20=\x20?')['get'](c);if(!d)return undefined;return{'sessionId':d['session_id'],'myAddress':d['my_address'],'peerAddress':d['peer_address'],'currentRoot':d['current_root'],'prevRoot':d['prev_root'],'messageCount':d['message_count'],'lastLeafIndex':d['last_leaf_index'],'lastConfirmedHash':d['last_confirmed_hash']===null?'':d['last_confirmed_hash'],'lastSyncAt':d['last_sync_at']===null?0x0:d['last_sync_at'],'createdAt':d['created_at'],'updatedAt':d['updated_at']};}['updateSessionState'](a,b,c){const d=this['getSessionId'](a,b),e=this['getSessionState'](a,b),f=Date['now']();if(e){const g={...e,...c,'updatedAt':f};this['db']['prepare']('\x0a\x20\x20\x20\x20\x20\x20\x20\x20UPDATE\x20session_states\x20SET\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20current_root\x20=\x20?,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20prev_root\x20=\x20?,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20message_count\x20=\x20?,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20last_leaf_index\x20=\x20?,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20last_confirmed_hash\x20=\x20?,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20last_sync_at\x20=\x20?,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20updated_at\x20=\x20?\x0a\x20\x20\x20\x20\x20\x20\x20\x20WHERE\x20session_id\x20=\x20?\x0a\x20\x20\x20\x20\x20\x20')['run'](g['currentRoot'],g['prevRoot'],g['messageCount'],g['lastLeafIndex'],g['lastConfirmedHash'],g['lastSyncAt'],g['updatedAt'],d);}else{const h='0'['repeat'](0x40);this['db']['prepare']('\x0a\x20\x20\x20\x20\x20\x20\x20\x20INSERT\x20INTO\x20session_states\x20(\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20session_id,\x20my_address,\x20peer_address,\x20current_root,\x20prev_root,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20message_count,\x20last_leaf_index,\x20last_confirmed_hash,\x20last_sync_at,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20created_at,\x20updated_at\x0a\x20\x20\x20\x20\x20\x20\x20\x20)\x20VALUES\x20(?,\x20?,\x20?,\x20?,\x20?,\x20?,\x20?,\x20?,\x20?,\x20?,\x20?)\x0a\x20\x20\x20\x20\x20\x20')['run'](d,a,b,c['currentRoot']??h,c['prevRoot']??h,c['messageCount']??0x0,c['lastLeafIndex']??0x0,c['lastConfirmedHash']??'',c['lastSyncAt']??0x0,f,f);}}['getCurrentRoot'](a,b){const c=this['getSessionState'](a,b);return c?.['currentRoot']??'0'['repeat'](0x40);}}export class MessengerPersistStorage{['initialized']=![];get['db'](){const a=getGlobalDatabase();return!this['initialized']&&(this['initTable'](a),this['initialized']=!![]),a;}['initTable'](a){a['exec']('\x0a\x09\x09\x09CREATE\x20TABLE\x20IF\x20NOT\x20EXISTS\x20messenger_manager_state\x20(\x0a\x09\x09\x09\x09instance_id\x20TEXT\x20PRIMARY\x20KEY,\x0a\x09\x09\x09\x09state_data\x20TEXT\x20NOT\x20NULL,\x0a\x09\x09\x09\x09updated_at\x20INTEGER\x20NOT\x20NULL\x0a\x09\x09\x09);\x0a\x09\x09\x09CREATE\x20INDEX\x20IF\x20NOT\x20EXISTS\x20idx_messenger_state_updated\x20ON\x20messenger_manager_state(updated_at);\x0a\x09\x09'),a['exec']('\x0a\x09\x09\x09CREATE\x20TABLE\x20IF\x20NOT\x20EXISTS\x20sse_connection_locks\x20(\x0a\x09\x09\x09\x09account_address\x20TEXT\x20PRIMARY\x20KEY,\x0a\x09\x09\x09\x09process_id\x20TEXT\x20NOT\x20NULL,\x0a\x09\x09\x09\x09instance_id\x20TEXT\x20NOT\x20NULL,\x0a\x09\x09\x09\x09last_heartbeat\x20INTEGER\x20NOT\x20NULL,\x0a\x09\x09\x09\x09created_at\x20INTEGER\x20NOT\x20NULL\x0a\x09\x09\x09);\x0a\x09\x09\x09CREATE\x20INDEX\x20IF\x20NOT\x20EXISTS\x20idx_sse_lock_heartbeat\x20ON\x20sse_connection_locks(last_heartbeat);\x0a\x09\x09'),a['exec']('\x0a\x09\x09\x09CREATE\x20TABLE\x20IF\x20NOT\x20EXISTS\x20polling_connection_locks\x20(\x0a\x09\x09\x09\x09account_address\x20TEXT\x20PRIMARY\x20KEY,\x0a\x09\x09\x09\x09process_id\x20TEXT\x20NOT\x20NULL,\x0a\x09\x09\x09\x09instance_id\x20TEXT\x20NOT\x20NULL,\x0a\x09\x09\x09\x09last_heartbeat\x20INTEGER\x20NOT\x20NULL,\x0a\x09\x09\x09\x09created_at\x20INTEGER\x20NOT\x20NULL\x0a\x09\x09\x09);\x0a\x09\x09\x09CREATE\x20INDEX\x20IF\x20NOT\x20EXISTS\x20idx_polling_lock_heartbeat\x20ON\x20polling_connection_locks(last_heartbeat);\x0a\x09\x09');}['saveState'](a,b){const c=JSON['stringify'](b),d=Date['now']();this['db']['prepare']('\x0a\x09\x09\x09\x09INSERT\x20INTO\x20messenger_manager_state\x20(instance_id,\x20state_data,\x20updated_at)\x0a\x09\x09\x09\x09VALUES\x20(?,\x20?,\x20?)\x0a\x09\x09\x09\x09ON\x20CONFLICT(instance_id)\x20DO\x20UPDATE\x20SET\x0a\x09\x09\x09\x09\x09state_data\x20=\x20excluded.state_data,\x0a\x09\x09\x09\x09\x09updated_at\x20=\x20excluded.updated_at\x0a\x09\x09\x09')['run'](a,c,d);}['loadState'](a){const b=this['db']['prepare']('SELECT\x20state_data\x20FROM\x20messenger_manager_state\x20WHERE\x20instance_id\x20=\x20?')['get'](a);if(!b?.['state_data'])return null;try{return JSON['parse'](b['state_data']);}catch(c){return null;}}['deleteState'](a){this['db']['prepare']('DELETE\x20FROM\x20messenger_manager_state\x20WHERE\x20instance_id\x20=\x20?')['run'](a);}['getAllInstanceIds'](){const a=this['db']['prepare']('SELECT\x20instance_id\x20FROM\x20messenger_manager_state\x20ORDER\x20BY\x20updated_at\x20DESC')['all']();return a['map'](b=>b['instance_id']);}get['processId'](){return'pid_'+process['pid']+'_'+Date['now']();}['tryAcquireSSELock'](a,b){const c=Date['now'](),d=0x3a98,e=this['db']['transaction'](()=>{const f=this['db']['prepare']('SELECT\x20*\x20FROM\x20sse_connection_locks\x20WHERE\x20account_address\x20=\x20?')['get'](a['toLowerCase']());if(f){if(f['instance_id']===b)return this['db']['prepare']('UPDATE\x20sse_connection_locks\x20SET\x20last_heartbeat\x20=\x20?\x20WHERE\x20account_address\x20=\x20?')['run'](c,a['toLowerCase']()),!![];if(c-f['last_heartbeat']<d)return![];}return this['db']['prepare']('\x0a\x09\x09\x09\x09\x09INSERT\x20INTO\x20sse_connection_locks\x20(\x0a\x09\x09\x09\x09\x09\x09account_address,\x20process_id,\x20instance_id,\x20last_heartbeat,\x20created_at\x0a\x09\x09\x09\x09\x09)\x20VALUES\x20(?,\x20?,\x20?,\x20?,\x20?)\x0a\x09\x09\x09\x09\x09ON\x20CONFLICT(account_address)\x20DO\x20UPDATE\x20SET\x0a\x09\x09\x09\x09\x09\x09process_id\x20=\x20excluded.process_id,\x0a\x09\x09\x09\x09\x09\x09instance_id\x20=\x20excluded.instance_id,\x0a\x09\x09\x09\x09\x09\x09last_heartbeat\x20=\x20excluded.last_heartbeat\x0a\x09\x09\x09\x09')['run'](a['toLowerCase'](),this['processId'],b,c,c),!![];});try{return e();}catch(f){return console['warn']('Failed\x20to\x20acquire\x20SSE\x20lock:',f),![];}}['updateSSELockHeartbeat'](a,b){const c=Date['now']();try{this['db']['prepare']('UPDATE\x20sse_connection_locks\x20SET\x20last_heartbeat\x20=\x20?\x20WHERE\x20account_address\x20=\x20?\x20AND\x20instance_id\x20=\x20?')['run'](c,a['toLowerCase'](),b);}catch(d){console['warn']('Failed\x20to\x20update\x20SSE\x20lock\x20heartbeat:',d);}}['releaseSSELock'](a,b){try{this['db']['prepare']('DELETE\x20FROM\x20sse_connection_locks\x20WHERE\x20account_address\x20=\x20?\x20AND\x20instance_id\x20=\x20?')['run'](a['toLowerCase'](),b);}catch(c){console['warn']('Failed\x20to\x20release\x20SSE\x20lock:',c);}}['holdsSSELock'](a,b){const c=this['db']['prepare']('SELECT\x20*\x20FROM\x20sse_connection_locks\x20WHERE\x20account_address\x20=\x20?\x20AND\x20instance_id\x20=\x20?')['get'](a['toLowerCase'](),b);return!!c;}['tryAcquirePollingLock'](a,b){const c=Date['now'](),d=0xea60,e=this['db']['transaction'](()=>{const f=this['db']['prepare']('SELECT\x20*\x20FROM\x20polling_connection_locks\x20WHERE\x20account_address\x20=\x20?')['get'](a['toLowerCase']());if(f){if(f['instance_id']===b)return this['db']['prepare']('UPDATE\x20polling_connection_locks\x20SET\x20last_heartbeat\x20=\x20?\x20WHERE\x20account_address\x20=\x20?')['run'](c,a['toLowerCase']()),!![];if(c-f['last_heartbeat']<d)return![];}return this['db']['prepare']('\x0a\x09\x09\x09\x09\x09INSERT\x20INTO\x20polling_connection_locks\x20(\x0a\x09\x09\x09\x09\x09\x09account_address,\x20process_id,\x20instance_id,\x20last_heartbeat,\x20created_at\x0a\x09\x09\x09\x09\x09)\x20VALUES\x20(?,\x20?,\x20?,\x20?,\x20?)\x0a\x09\x09\x09\x09\x09ON\x20CONFLICT(account_address)\x20DO\x20UPDATE\x20SET\x0a\x09\x09\x09\x09\x09\x09process_id\x20=\x20excluded.process_id,\x0a\x09\x09\x09\x09\x09\x09instance_id\x20=\x20excluded.instance_id,\x0a\x09\x09\x09\x09\x09\x09last_heartbeat\x20=\x20excluded.last_heartbeat\x0a\x09\x09\x09\x09')['run'](a['toLowerCase'](),this['processId'],b,c,c),!![];});try{return e();}catch(f){return console['warn']('Failed\x20to\x20acquire\x20polling\x20lock:',f),![];}}['updatePollingLockHeartbeat'](a,b){const c=Date['now']();try{this['db']['prepare']('UPDATE\x20polling_connection_locks\x20SET\x20last_heartbeat\x20=\x20?\x20WHERE\x20account_address\x20=\x20?\x20AND\x20instance_id\x20=\x20?')['run'](c,a['toLowerCase'](),b);}catch(d){console['warn']('Failed\x20to\x20update\x20polling\x20lock\x20heartbeat:',d);}}['releasePollingLock'](a,b){try{this['db']['prepare']('DELETE\x20FROM\x20polling_connection_locks\x20WHERE\x20account_address\x20=\x20?\x20AND\x20instance_id\x20=\x20?')['run'](a['toLowerCase'](),b);}catch(c){console['warn']('Failed\x20to\x20release\x20polling\x20lock:',c);}}['holdsPollingLock'](a,b){const c=this['db']['prepare']('SELECT\x20*\x20FROM\x20polling_connection_locks\x20WHERE\x20account_address\x20=\x20?\x20AND\x20instance_id\x20=\x20?')['get'](a['toLowerCase'](),b);return!!c;}}export const defaultPersistStorage=new MessengerPersistStorage();
1
+ import a196a from'better-sqlite3';import*as a196b from'path';import*as a196c from'fs';import{getWowDir}from'../local/util.js';function getWowDirDynamic(){return getWowDir();}function getMessengerDbDir(){return a196b['join'](getWowDirDynamic(),'messenger');}function ensureDirExists(a){!a196c['existsSync'](a)&&a196c['mkdirSync'](a,{'recursive':!![]});}function getUserDbPath(a){const b=a['toLowerCase']()['replace'](/^0x/,'')['slice'](0x0,0x10),c=getMessengerDbDir();return ensureDirExists(c),a196b['join'](c,b+'.db');}function getGlobalDbPath(){const a=getMessengerDbDir();return ensureDirExists(a),a196b['join'](a,'global.db');}const userDbInstances=new Map();let globalDbInstance=null;export function getDatabase(a){if(!a)throw new Error('userAddress\x20is\x20required\x20to\x20get\x20database');const b=userDbInstances['get'](a);if(b)return b;const c=getUserDbPath(a),d=new a196a(c);d['pragma']('journal_mode\x20=\x20WAL'),d['pragma']('synchronous\x20=\x20NORMAL'),d['pragma']('cache_size\x20=\x20-64000'),d['exec']('\x0a\x20\x20\x20\x20CREATE\x20TABLE\x20IF\x20NOT\x20EXISTS\x20signal_store\x20(\x0a\x20\x20\x20\x20\x20\x20store_type\x20TEXT\x20NOT\x20NULL,\x0a\x20\x20\x20\x20\x20\x20key\x20TEXT\x20NOT\x20NULL,\x0a\x20\x20\x20\x20\x20\x20value\x20TEXT\x20NOT\x20NULL,\x0a\x20\x20\x20\x20\x20\x20updated_at\x20INTEGER\x20DEFAULT\x20(strftime(\x27%s\x27,\x20\x27now\x27)),\x0a\x20\x20\x20\x20\x20\x20PRIMARY\x20KEY\x20(store_type,\x20key)\x0a\x20\x20\x20\x20);\x0a\x20\x20\x20\x20CREATE\x20INDEX\x20IF\x20NOT\x20EXISTS\x20idx_signal_store_type\x20ON\x20signal_store(store_type);\x0a\x20\x20');try{d['exec']('\x0a\x20\x20\x20\x20\x20\x20CREATE\x20TABLE\x20IF\x20NOT\x20EXISTS\x20messages\x20(\x0a\x20\x20\x20\x20\x20\x20\x20\x20message_id\x20TEXT\x20PRIMARY\x20KEY,\x0a\x20\x20\x20\x20\x20\x20\x20\x20from_address\x20TEXT\x20NOT\x20NULL,\x0a\x20\x20\x20\x20\x20\x20\x20\x20to_address\x20TEXT\x20NOT\x20NULL,\x0a\x20\x20\x20\x20\x20\x20\x20\x20plaintext_hash\x20TEXT\x20NOT\x20NULL,\x0a\x20\x20\x20\x20\x20\x20\x20\x20plaintext\x20TEXT,\x0a\x20\x20\x20\x20\x20\x20\x20\x20guard_address\x20TEXT,\x0a\x20\x20\x20\x20\x20\x20\x20\x20passport_address\x20TEXT,\x0a\x20\x20\x20\x20\x20\x20\x20\x20direction\x20TEXT\x20NOT\x20NULL,\x0a\x20\x20\x20\x20\x20\x20\x20\x20status\x20TEXT\x20NOT\x20NULL,\x0a\x20\x20\x20\x20\x20\x20\x20\x20msg_type\x20INTEGER\x20NOT\x20NULL,\x0a\x20\x20\x20\x20\x20\x20\x20\x20leaf_index\x20INTEGER,\x0a\x20\x20\x20\x20\x20\x20\x20\x20prev_root\x20TEXT,\x0a\x20\x20\x20\x20\x20\x20\x20\x20new_root\x20TEXT,\x0a\x20\x20\x20\x20\x20\x20\x20\x20server_signature\x20TEXT,\x0a\x20\x20\x20\x20\x20\x20\x20\x20server_public_key\x20TEXT,\x0a\x20\x20\x20\x20\x20\x20\x20\x20server_timestamp\x20INTEGER,\x0a\x20\x20\x20\x20\x20\x20\x20\x20ark_recipient\x20TEXT,\x0a\x20\x20\x20\x20\x20\x20\x20\x20ark_recipient_pubkey\x20TEXT,\x0a\x20\x20\x20\x20\x20\x20\x20\x20ark_signature\x20TEXT,\x0a\x20\x20\x20\x20\x20\x20\x20\x20ark_timestamp\x20INTEGER,\x0a\x20\x20\x20\x20\x20\x20\x20\x20zip_metadata\x20TEXT,\x0a\x20\x20\x20\x20\x20\x20\x20\x20created_at\x20INTEGER\x20DEFAULT\x20(strftime(\x27%s\x27,\x20\x27now\x27)\x20*\x201000),\x0a\x20\x20\x20\x20\x20\x20\x20\x20received_at\x20INTEGER\x0a\x20\x20\x20\x20\x20\x20);\x0a\x20\x20\x20\x20');}catch(f){}try{d['exec']('ALTER\x20TABLE\x20messages\x20ADD\x20COLUMN\x20guard_address\x20TEXT');}catch(g){}try{d['exec']('ALTER\x20TABLE\x20messages\x20ADD\x20COLUMN\x20passport_address\x20TEXT');}catch(h){}try{d['exec']('ALTER\x20TABLE\x20messages\x20ADD\x20COLUMN\x20last_received_leaf_index\x20INTEGER');}catch(i){}try{d['exec']('ALTER\x20TABLE\x20messages\x20ADD\x20COLUMN\x20viewed_at\x20INTEGER');}catch(j){}try{d['exec']('CREATE\x20INDEX\x20IF\x20NOT\x20EXISTS\x20idx_messages_from_to\x20ON\x20messages(from_address,\x20to_address)');}catch(k){}try{d['exec']('CREATE\x20INDEX\x20IF\x20NOT\x20EXISTS\x20idx_messages_status\x20ON\x20messages(status)');}catch(l){}try{d['exec']('CREATE\x20INDEX\x20IF\x20NOT\x20EXISTS\x20idx_messages_leaf\x20ON\x20messages(leaf_index)');}catch(m){}try{d['exec']('CREATE\x20INDEX\x20IF\x20NOT\x20EXISTS\x20idx_messages_created_at\x20ON\x20messages(created_at)');}catch(n){}try{d['exec']('CREATE\x20INDEX\x20IF\x20NOT\x20EXISTS\x20idx_messages_server_ts\x20ON\x20messages(server_timestamp)');}catch(o){}try{d['exec']('CREATE\x20INDEX\x20IF\x20NOT\x20EXISTS\x20idx_messages_received_at\x20ON\x20messages(received_at)');}catch(p){}return d['exec']('\x0a\x20\x20\x20\x20CREATE\x20TABLE\x20IF\x20NOT\x20EXISTS\x20session_states\x20(\x0a\x20\x20\x20\x20\x20\x20session_id\x20TEXT\x20PRIMARY\x20KEY,\x0a\x20\x20\x20\x20\x20\x20my_address\x20TEXT\x20NOT\x20NULL,\x0a\x20\x20\x20\x20\x20\x20peer_address\x20TEXT\x20NOT\x20NULL,\x0a\x20\x20\x20\x20\x20\x20current_root\x20TEXT\x20NOT\x20NULL,\x0a\x20\x20\x20\x20\x20\x20prev_root\x20TEXT\x20NOT\x20NULL,\x0a\x20\x20\x20\x20\x20\x20message_count\x20INTEGER\x20DEFAULT\x200,\x0a\x20\x20\x20\x20\x20\x20last_leaf_index\x20INTEGER\x20DEFAULT\x200,\x0a\x20\x20\x20\x20\x20\x20last_confirmed_hash\x20TEXT,\x0a\x20\x20\x20\x20\x20\x20last_sync_at\x20INTEGER,\x0a\x20\x20\x20\x20\x20\x20created_at\x20INTEGER\x20DEFAULT\x20(strftime(\x27%s\x27,\x20\x27now\x27)),\x0a\x20\x20\x20\x20\x20\x20updated_at\x20INTEGER\x20DEFAULT\x20(strftime(\x27%s\x27,\x20\x27now\x27))\x0a\x20\x20\x20\x20);\x0a\x20\x20\x20\x20CREATE\x20INDEX\x20IF\x20NOT\x20EXISTS\x20idx_session_my_peer\x20ON\x20session_states(my_address,\x20peer_address);\x0a\x20\x20'),userDbInstances['set'](a,d),d;}function getGlobalDatabase(){if(globalDbInstance)return globalDbInstance;const a=getGlobalDbPath(),b=new a196a(a);return b['pragma']('journal_mode\x20=\x20WAL'),b['pragma']('synchronous\x20=\x20NORMAL'),b['pragma']('cache_size\x20=\x20-10000'),b['pragma']('busy_timeout\x20=\x205000'),globalDbInstance=b,b;}export function resetDbConnection(){for(const [a,b]of userDbInstances){try{b['pragma']('journal_mode\x20=\x20DELETE');}catch(c){}}for(const [d,f]of userDbInstances){try{f['close']();}catch(g){}}userDbInstances['clear']();if(globalDbInstance){try{globalDbInstance['pragma']('journal_mode\x20=\x20DELETE');}catch(h){}try{globalDbInstance['close']();}catch(i){}globalDbInstance=null;}}process['on']('exit',()=>{resetDbConnection();}),process['on']('SIGINT',()=>{resetDbConnection(),process['exit'](0x0);}),process['on']('SIGTERM',()=>{resetDbConnection(),process['exit'](0x0);});const STORE_TYPES={'IDENTITY':'identity','REGISTRATION_ID':'registration_id','IDENTITIES':'identities','PREKEYS':'prekeys','SIGNED_PREKEYS':'signed_prekeys','SESSIONS':'sessions','META':'meta'};function arrayBufferToBase64(a){return Buffer['from'](new Uint8Array(a))['toString']('base64');}function base64ToArrayBuffer(a){const b=Uint8Array['from'](Buffer['from'](a,'base64'));return b['slice']()['buffer'];}function bufferEqual(c,d){if(c['byteLength']!==d['byteLength'])return![];const e=new Uint8Array(c),f=new Uint8Array(d);for(let g=0x0;g<e['length'];g++){if(e[g]!==f[g])return![];}return!![];}export class SignalProtocolStorage{['storePrefix'];['userAddress'];constructor(a,b='default'){this['userAddress']=a,this['storePrefix']=b;}get['db'](){return getDatabase(this['userAddress']);}async['setIdentity'](a,b){const c={'pubKey':arrayBufferToBase64(a['pubKey']),'privKey':arrayBufferToBase64(a['privKey'])};this['putValue'](STORE_TYPES['IDENTITY'],JSON['stringify'](c)),this['putValue'](STORE_TYPES['REGISTRATION_ID'],b['toString']());}async['getIdentityKeyPair'](){const a=this['getValue'](STORE_TYPES['IDENTITY']);if(!a)return undefined;const b=JSON['parse'](a);return{'pubKey':base64ToArrayBuffer(b['pubKey']),'privKey':base64ToArrayBuffer(b['privKey'])};}async['getLocalRegistrationId'](){const a=this['getValue'](STORE_TYPES['REGISTRATION_ID']);return a?parseInt(a,0xa):undefined;}async['isTrustedIdentity'](a,b){const c=STORE_TYPES['IDENTITIES']+':'+a,d=this['getValue'](c);if(!d)return!![];return bufferEqual(base64ToArrayBuffer(d),b);}async['saveIdentity'](a,b){const c=STORE_TYPES['IDENTITIES']+':'+a,d=this['getValue'](c),e=arrayBufferToBase64(b);return this['putValue'](c,e),d?bufferEqual(base64ToArrayBuffer(d),b):!![];}async['loadIdentity'](a){const b=STORE_TYPES['IDENTITIES']+':'+a,c=this['getValue'](b);return c?base64ToArrayBuffer(c):undefined;}async['loadPreKey'](a){const b=STORE_TYPES['PREKEYS']+':'+a,c=this['getValue'](b);if(!c)return undefined;const d=JSON['parse'](c);return{'pubKey':base64ToArrayBuffer(d['pubKey']),'privKey':base64ToArrayBuffer(d['privKey'])};}async['storePreKey'](a,b){const c=STORE_TYPES['PREKEYS']+':'+a,d={'pubKey':arrayBufferToBase64(b['pubKey']),'privKey':arrayBufferToBase64(b['privKey'])};this['putValue'](c,JSON['stringify'](d));}async['removePreKey'](a){const b=STORE_TYPES['PREKEYS']+':'+a;this['delValue'](b);}async['loadSignedPreKey'](a){const b=STORE_TYPES['SIGNED_PREKEYS']+':'+a,c=this['getValue'](b);if(!c)return undefined;const d=JSON['parse'](c);return{'pubKey':base64ToArrayBuffer(d['pubKey']),'privKey':base64ToArrayBuffer(d['privKey'])};}async['storeSignedPreKey'](a,b){const c=STORE_TYPES['SIGNED_PREKEYS']+':'+a,d={'pubKey':arrayBufferToBase64(b['pubKey']),'privKey':arrayBufferToBase64(b['privKey'])};this['putValue'](c,JSON['stringify'](d));}async['removeSignedPreKey'](a){const b=STORE_TYPES['SIGNED_PREKEYS']+':'+a;this['delValue'](b);}async['loadSignedPreKeyWithSignature'](a){const b=STORE_TYPES['SIGNED_PREKEYS']+':'+a,c=this['getValue'](b);if(!c)return undefined;const d=JSON['parse'](c);if(!d['pubKey']||!d['privKey']||!d['signature'])return undefined;return{'pubKey':base64ToArrayBuffer(d['pubKey']),'privKey':base64ToArrayBuffer(d['privKey']),'signature':base64ToArrayBuffer(d['signature'])};}async['storeSignedPreKeyWithSignature'](a,b,c){const d=STORE_TYPES['SIGNED_PREKEYS']+':'+a,e={'pubKey':arrayBufferToBase64(b['pubKey']),'privKey':arrayBufferToBase64(b['privKey']),'signature':arrayBufferToBase64(c)};this['putValue'](d,JSON['stringify'](e));}async['loadSession'](a){const b=STORE_TYPES['SESSIONS']+':'+a,c=this['getValue'](b);if(c)return c;if(a['startsWith']('send:')||a['startsWith']('recv:'))return undefined;const d=STORE_TYPES['SESSIONS']+':send:'+a,e=this['getValue'](d);if(e)return e;const f=STORE_TYPES['SESSIONS']+':recv:'+a,g=this['getValue'](f);if(g)return g;return undefined;}async['storeSession'](a,b){const c=STORE_TYPES['SESSIONS']+':'+a;this['putValue'](c,b);if(!a['startsWith']('send:')&&!a['startsWith']('recv:')){const d=STORE_TYPES['SESSIONS']+':recv:'+a;this['putValue'](d,b);}}async['removeSession'](a){const b=STORE_TYPES['SESSIONS']+':'+a;this['delValue'](b);if(!a['startsWith']('send:')&&!a['startsWith']('recv:')){const c=STORE_TYPES['SESSIONS']+':recv:'+a;this['delValue'](c);}}async['getMeta'](){const a=this['getValue'](STORE_TYPES['META']);if(!a)return{'nextPreKeyId':0x1};return JSON['parse'](a);}async['setMeta'](a){const b=await this['getMeta'](),c={...b,...a};this['putValue'](STORE_TYPES['META'],JSON['stringify'](c));}['listPreKeys'](){const a=this['db']['prepare']('SELECT\x20key\x20FROM\x20signal_store\x20WHERE\x20store_type\x20=\x20?\x20AND\x20key\x20LIKE\x20?')['all'](this['storePrefix'],STORE_TYPES['PREKEYS']+':%');return a['map'](b=>{const c=b['key']['replace'](STORE_TYPES['PREKEYS']+':','');return Number(c);});}['getValue'](a){const b=this['db']['prepare']('SELECT\x20value\x20FROM\x20signal_store\x20WHERE\x20store_type\x20=\x20?\x20AND\x20key\x20=\x20?')['get'](this['storePrefix'],a);return b?.['value'];}['putValue'](a,b){this['db']['prepare']('\x0a\x20\x20\x20\x20\x20\x20INSERT\x20INTO\x20signal_store\x20(store_type,\x20key,\x20value,\x20updated_at)\x20\x0a\x20\x20\x20\x20\x20\x20VALUES\x20(?,\x20?,\x20?,\x20strftime(\x27%s\x27,\x20\x27now\x27))\x0a\x20\x20\x20\x20\x20\x20ON\x20CONFLICT(store_type,\x20key)\x20DO\x20UPDATE\x20SET\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20value\x20=\x20excluded.value,\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20updated_at\x20=\x20excluded.updated_at\x0a\x20\x20\x20\x20')['run'](this['storePrefix'],a,b);}['delValue'](a){this['db']['prepare']('DELETE\x20FROM\x20signal_store\x20WHERE\x20store_type\x20=\x20?\x20AND\x20key\x20=\x20?')['run'](this['storePrefix'],a);}}export class MessageStorage{['userAddress'];constructor(a){this['userAddress']=a;}get['db'](){return getDatabase(this['userAddress']);}['saveMessage'](a){const b=a['direction']==='received'&&!a['receivedAt']?Date['now']():a['receivedAt'];this['db']['prepare']('\x0a\x20\x20\x20\x20\x20\x20INSERT\x20INTO\x20messages\x20(\x0a\x20\x20\x20\x20\x20\x20\x20\x20message_id,\x20from_address,\x20to_address,\x20plaintext_hash,\x0a\x20\x20\x20\x20\x20\x20\x20\x20plaintext,\x20guard_address,\x20passport_address,\x20last_received_leaf_index,\x20direction,\x20status,\x20msg_type,\x0a\x20\x20\x20\x20\x20\x20\x20\x20leaf_index,\x20prev_root,\x20new_root,\x20server_signature,\x20server_public_key,\x20server_timestamp,\x0a\x20\x20\x20\x20\x20\x20\x20\x20ark_recipient,\x20ark_recipient_pubkey,\x20ark_signature,\x20ark_timestamp,\x20zip_metadata,\x0a\x20\x20\x20\x20\x20\x20\x20\x20created_at,\x20received_at\x0a\x20\x20\x20\x20\x20\x20)\x20VALUES\x20(?,\x20?,\x20?,\x20?,\x20?,\x20?,\x20?,\x20?,\x20?,\x20?,\x20?,\x20?,\x20?,\x20?,\x20?,\x20?,\x20?,\x20?,\x20?,\x20?,\x20?,\x20?,\x20?,\x20?)\x0a\x20\x20\x20\x20\x20\x20ON\x20CONFLICT(message_id)\x20DO\x20UPDATE\x20SET\x0a\x20\x20\x20\x20\x20\x20\x20\x20direction\x20=\x20COALESCE(excluded.direction,\x20direction),\x0a\x20\x20\x20\x20\x20\x20\x20\x20status\x20=\x20COALESCE(excluded.status,\x20status),\x0a\x20\x20\x20\x20\x20\x20\x20\x20leaf_index\x20=\x20COALESCE(excluded.leaf_index,\x20leaf_index),\x0a\x20\x20\x20\x20\x20\x20\x20\x20prev_root\x20=\x20COALESCE(excluded.prev_root,\x20prev_root),\x0a\x20\x20\x20\x20\x20\x20\x20\x20new_root\x20=\x20COALESCE(excluded.new_root,\x20new_root),\x0a\x20\x20\x20\x20\x20\x20\x20\x20server_signature\x20=\x20COALESCE(excluded.server_signature,\x20server_signature),\x0a\x20\x20\x20\x20\x20\x20\x20\x20server_public_key\x20=\x20COALESCE(excluded.server_public_key,\x20server_public_key),\x0a\x20\x20\x20\x20\x20\x20\x20\x20server_timestamp\x20=\x20COALESCE(excluded.server_timestamp,\x20server_timestamp),\x0a\x20\x20\x20\x20\x20\x20\x20\x20plaintext\x20=\x20COALESCE(excluded.plaintext,\x20plaintext),\x0a\x20\x20\x20\x20\x20\x20\x20\x20guard_address\x20=\x20COALESCE(excluded.guard_address,\x20guard_address),\x0a\x20\x20\x20\x20\x20\x20\x20\x20passport_address\x20=\x20COALESCE(excluded.passport_address,\x20passport_address),\x0a\x20\x20\x20\x20\x20\x20\x20\x20last_received_leaf_index\x20=\x20COALESCE(excluded.last_received_leaf_index,\x20last_received_leaf_index),\x0a\x20\x20\x20\x20\x20\x20\x20\x20ark_recipient\x20=\x20COALESCE(excluded.ark_recipient,\x20ark_recipient),\x0a\x20\x20\x20\x20\x20\x20\x20\x20ark_recipient_pubkey\x20=\x20COALESCE(excluded.ark_recipient_pubkey,\x20ark_recipient_pubkey),\x0a\x20\x20\x20\x20\x20\x20\x20\x20ark_signature\x20=\x20COALESCE(excluded.ark_signature,\x20ark_signature),\x0a\x20\x20\x20\x20\x20\x20\x20\x20ark_timestamp\x20=\x20COALESCE(excluded.ark_timestamp,\x20ark_timestamp),\x0a\x20\x20\x20\x20\x20\x20\x20\x20zip_metadata\x20=\x20COALESCE(excluded.zip_metadata,\x20zip_metadata),\x0a\x20\x20\x20\x20\x20\x20\x20\x20received_at\x20=\x20COALESCE(excluded.received_at,\x20received_at)\x0a\x20\x20\x20\x20')['run'](a['messageId'],a['fromAddress'],a['toAddress'],a['plaintextHash'],a['plaintext']===undefined?null:a['plaintext'],a['guardAddress']===undefined?null:a['guardAddress'],a['passportAddress']===undefined?null:a['passportAddress'],a['lastReceivedLeafIndex']===undefined?null:a['lastReceivedLeafIndex'],a['direction'],a['status'],a['msgType'],a['leafIndex']===undefined?null:a['leafIndex'],a['prevRoot']===undefined?null:a['prevRoot'],a['newRoot']===undefined?null:a['newRoot'],a['serverSignature']===undefined?null:a['serverSignature'],a['serverPublicKey']===undefined?null:a['serverPublicKey'],a['serverTimestamp']===undefined?null:a['serverTimestamp'],a['arkConfirmed']?.['recipient']===undefined?null:a['arkConfirmed']?.['recipient'],a['arkConfirmed']?.['recipientPublicKey']===undefined?null:a['arkConfirmed']?.['recipientPublicKey'],a['arkConfirmed']?.['signature']===undefined?null:a['arkConfirmed']?.['signature'],a['arkConfirmed']?.['timestamp']===undefined?null:a['arkConfirmed']?.['timestamp'],a['zipMetadata']?JSON['stringify'](a['zipMetadata']):null,a['createdAt'],b===undefined?null:b);}['getMessage'](a){const b=this['db']['prepare']('SELECT\x20*\x20FROM\x20messages\x20WHERE\x20message_id\x20=\x20?')['get'](a);if(!b)return undefined;return this['rowToMessage'](b);}['getMessagesBySession'](a,b){const c=a['toLowerCase'](),d=b['toLowerCase'](),e=this['db']['prepare']('\x0a\x20\x20\x20\x20\x20\x20\x20\x20SELECT\x20*\x20FROM\x20messages\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20WHERE\x20(from_address\x20=\x20?\x20AND\x20to_address\x20=\x20?)\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20OR\x20(from_address\x20=\x20?\x20AND\x20to_address\x20=\x20?)\x0a\x20\x20\x20\x20\x20\x20\x20\x20ORDER\x20BY\x20created_at\x20ASC\x0a\x20\x20\x20\x20\x20\x20')['all'](c,d,d,c);return e['map'](f=>this['rowToMessage'](f));}['getPendingMessages'](a){const b=a['toLowerCase'](),c=this['db']['prepare']('\x0a\x20\x20\x20\x20\x20\x20\x20\x20SELECT\x20*\x20FROM\x20messages\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20WHERE\x20(from_address\x20=\x20?\x20OR\x20to_address\x20=\x20?)\x20AND\x20status\x20=\x20?\x0a\x20\x20\x20\x20\x20\x20\x20\x20ORDER\x20BY\x20created_at\x20ASC\x0a\x20\x20\x20\x20\x20\x20')['all'](b,b,'pending');return c['map'](d=>this['rowToMessage'](d));}['updateMessageStatus'](a,b,c){const d=['status\x20=\x20?'],e=[b];c?.['leafIndex']!==undefined&&(d['push']('leaf_index\x20=\x20?'),e['push'](c['leafIndex'])),c?.['newRoot']!==undefined&&(d['push']('new_root\x20=\x20?'),e['push'](c['newRoot'])),c?.['serverSignature']!==undefined&&(d['push']('server_signature\x20=\x20?'),e['push'](c['serverSignature'])),c?.['serverTimestamp']!==undefined&&(d['push']('server_timestamp\x20=\x20?'),e['push'](c['serverTimestamp'])),c?.['serverPublicKey']!==undefined&&(d['push']('server_public_key\x20=\x20?'),e['push'](c['serverPublicKey'])),e['push'](a),this['db']['prepare']('\x0a\x20\x20\x20\x20\x20\x20UPDATE\x20messages\x20SET\x20'+d['join'](',\x20')+'\x20WHERE\x20message_id\x20=\x20?\x0a\x20\x20\x20\x20')['run'](...e);}['updateMessageViewed'](a,b){const c=b??Date['now'](),d=this['db']['prepare']('\x0a\x09\x09\x09\x09UPDATE\x20messages\x0a\x09\x09\x09\x09SET\x20viewed_at\x20=\x20?\x0a\x09\x09\x09\x09WHERE\x20message_id\x20=\x20?\x20AND\x20viewed_at\x20IS\x20NULL\x0a\x09\x09\x09')['run'](c,a);return d['changes']>0x0;}['updateMessagesViewed'](a,b){if(a['length']===0x0)return 0x0;const c=b??Date['now'](),d=a['map'](()=>'?')['join'](','),e=this['db']['prepare']('\x0a\x09\x09\x09\x09UPDATE\x20messages\x0a\x09\x09\x09\x09SET\x20viewed_at\x20=\x20?\x0a\x09\x09\x09\x09WHERE\x20message_id\x20IN\x20('+d+')\x20AND\x20viewed_at\x20IS\x20NULL\x0a\x09\x09\x09')['run'](c,...a);return e['changes'];}['getAllMessages'](a){const b=a['toLowerCase'](),c=this['db']['prepare']('\x0a\x20\x20\x20\x20\x20\x20\x20\x20SELECT\x20*\x20FROM\x20messages\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20WHERE\x20from_address\x20=\x20?\x20OR\x20to_address\x20=\x20?\x0a\x20\x20\x20\x20\x20\x20\x20\x20ORDER\x20BY\x20created_at\x20DESC\x0a\x20\x20\x20\x20\x20\x20')['all'](b,b);return c['map'](d=>this['rowToMessage'](d));}['getMessageById'](a){const b=this['db']['prepare']('\x0a\x20\x20\x20\x20\x20\x20\x20\x20SELECT\x20*\x20FROM\x20messages\x0a\x20\x20\x20\x20\x20\x20\x20\x20WHERE\x20message_id\x20=\x20?\x0a\x20\x20\x20\x20\x20\x20')['get'](a);if(!b)return undefined;return this['rowToMessage'](b);}['updateMessageId'](a,b,c){const d=this['db']['prepare']('SELECT\x20*\x20FROM\x20messages\x20WHERE\x20message_id\x20=\x20?')['get'](a);if(!d)return![];const e=(h,i)=>{if(h!==undefined)return h;return i===null?undefined:i;},f={'messageId':b,'fromAddress':d['from_address'],'toAddress':d['to_address'],'plaintextHash':d['plaintext_hash'],'plaintext':d['plaintext']===null?undefined:d['plaintext'],'guardAddress':d['guard_address']===null?undefined:d['guard_address'],'passportAddress':d['passport_address']===null?undefined:d['passport_address'],'direction':d['direction'],'status':c?.['status']!==undefined?c['status']:d['status'],'msgType':d['msg_type'],'leafIndex':e(c?.['leafIndex'],d['leaf_index']),'prevRoot':e(c?.['prevRoot'],d['prev_root']),'newRoot':e(c?.['newRoot'],d['new_root']),'serverSignature':e(c?.['serverSignature'],d['server_signature']),'serverPublicKey':e(c?.['serverPublicKey'],d['server_public_key']),'serverTimestamp':e(c?.['serverTimestamp'],d['server_timestamp']),'arkConfirmed':d['ark_recipient']?{'recipient':d['ark_recipient'],'recipientPublicKey':d['ark_recipient_pubkey'],'signature':d['ark_signature'],'timestamp':d['ark_timestamp']}:undefined,'zipMetadata':d['zip_metadata']?JSON['parse'](d['zip_metadata']):undefined,'createdAt':d['created_at'],'receivedAt':d['received_at']===null?undefined:d['received_at'],'viewedAt':d['viewed_at']===null?undefined:d['viewed_at']},g=this['db']['transaction'](()=>{this['db']['prepare']('DELETE\x20FROM\x20messages\x20WHERE\x20message_id\x20=\x20?')['run'](a),this['saveMessage'](f);});try{return g(),!![];}catch(h){return![];}}['rowToMessage'](a){if(a['to_address']===null)throw new Error('Message\x20'+a['message_id']+'\x20has\x20null\x20toAddress');return{'messageId':a['message_id'],'fromAddress':a['from_address'],'toAddress':a['to_address'],'plaintextHash':a['plaintext_hash'],'plaintext':a['plaintext']===null?undefined:a['plaintext'],'guardAddress':a['guard_address']===null?undefined:a['guard_address'],'passportAddress':a['passport_address']===null?undefined:a['passport_address'],'lastReceivedLeafIndex':a['last_received_leaf_index']===null?undefined:a['last_received_leaf_index'],'direction':a['direction'],'status':a['status'],'msgType':a['msg_type'],'leafIndex':a['leaf_index']===null?undefined:a['leaf_index'],'prevRoot':a['prev_root']===null?undefined:a['prev_root'],'newRoot':a['new_root']===null?undefined:a['new_root'],'serverSignature':a['server_signature']===null?undefined:a['server_signature'],'serverPublicKey':a['server_public_key']===null?undefined:a['server_public_key'],'serverTimestamp':a['server_timestamp']===null?undefined:a['server_timestamp'],'arkConfirmed':a['ark_recipient']?{'recipient':a['ark_recipient'],'recipientPublicKey':a['ark_recipient_pubkey'],'signature':a['ark_signature'],'timestamp':a['ark_timestamp']}:undefined,'zipMetadata':a['zip_metadata']?JSON['parse'](a['zip_metadata']):undefined,'createdAt':a['created_at'],'receivedAt':a['received_at']===null?undefined:a['received_at'],'viewedAt':a['viewed_at']===null?undefined:a['viewed_at']};}['getLastReceivedLeafIndex'](a,b){const c=a['toLowerCase'](),d=b['toLowerCase'](),e=this['db']['prepare']('\x0a\x09\x09\x09\x09SELECT\x20MAX(leaf_index)\x20as\x20max_index\x0a\x09\x09\x09\x09FROM\x20messages\x0a\x09\x09\x09\x09WHERE\x20from_address\x20=\x20?\x20AND\x20to_address\x20=\x20?\x0a\x09\x09\x09\x09\x09AND\x20status\x20=\x20\x27decrypted\x27\x0a\x09\x09\x09\x09\x09AND\x20leaf_index\x20IS\x20NOT\x20NULL\x0a\x09\x09\x09')['get'](d,c);return e?.['max_index']??-0x1;}}export class SessionStateStorage{['userAddress'];constructor(a){this['userAddress']=a;}get['db'](){return getDatabase(this['userAddress']);}['getSessionId'](a,b){const c=[a,b]['sort']();return c[0x0]+':'+c[0x1];}['getSessionState'](a,b){const c=this['getSessionId'](a,b),d=this['db']['prepare']('SELECT\x20*\x20FROM\x20session_states\x20WHERE\x20session_id\x20=\x20?')['get'](c);if(!d)return undefined;return{'sessionId':d['session_id'],'myAddress':d['my_address'],'peerAddress':d['peer_address'],'currentRoot':d['current_root'],'prevRoot':d['prev_root'],'messageCount':d['message_count'],'lastLeafIndex':d['last_leaf_index'],'lastConfirmedHash':d['last_confirmed_hash']===null?'':d['last_confirmed_hash'],'lastSyncAt':d['last_sync_at']===null?0x0:d['last_sync_at'],'createdAt':d['created_at'],'updatedAt':d['updated_at']};}['updateSessionState'](a,b,c){const d=this['getSessionId'](a,b),e=this['getSessionState'](a,b),f=Date['now']();if(e){const g={...e,...c,'updatedAt':f};this['db']['prepare']('\x0a\x20\x20\x20\x20\x20\x20\x20\x20UPDATE\x20session_states\x20SET\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20current_root\x20=\x20?,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20prev_root\x20=\x20?,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20message_count\x20=\x20?,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20last_leaf_index\x20=\x20?,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20last_confirmed_hash\x20=\x20?,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20last_sync_at\x20=\x20?,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20updated_at\x20=\x20?\x0a\x20\x20\x20\x20\x20\x20\x20\x20WHERE\x20session_id\x20=\x20?\x0a\x20\x20\x20\x20\x20\x20')['run'](g['currentRoot'],g['prevRoot'],g['messageCount'],g['lastLeafIndex'],g['lastConfirmedHash'],g['lastSyncAt'],g['updatedAt'],d);}else{const h='0'['repeat'](0x40);this['db']['prepare']('\x0a\x20\x20\x20\x20\x20\x20\x20\x20INSERT\x20INTO\x20session_states\x20(\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20session_id,\x20my_address,\x20peer_address,\x20current_root,\x20prev_root,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20message_count,\x20last_leaf_index,\x20last_confirmed_hash,\x20last_sync_at,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20created_at,\x20updated_at\x0a\x20\x20\x20\x20\x20\x20\x20\x20)\x20VALUES\x20(?,\x20?,\x20?,\x20?,\x20?,\x20?,\x20?,\x20?,\x20?,\x20?,\x20?)\x0a\x20\x20\x20\x20\x20\x20')['run'](d,a,b,c['currentRoot']??h,c['prevRoot']??h,c['messageCount']??0x0,c['lastLeafIndex']??0x0,c['lastConfirmedHash']??'',c['lastSyncAt']??0x0,f,f);}}['getCurrentRoot'](a,b){const c=this['getSessionState'](a,b);return c?.['currentRoot']??'0'['repeat'](0x40);}}export class MessengerPersistStorage{['initialized']=![];get['db'](){const a=getGlobalDatabase();return!this['initialized']&&(this['initTable'](a),this['initialized']=!![]),a;}['initTable'](a){a['exec']('\x0a\x09\x09\x09CREATE\x20TABLE\x20IF\x20NOT\x20EXISTS\x20messenger_manager_state\x20(\x0a\x09\x09\x09\x09instance_id\x20TEXT\x20PRIMARY\x20KEY,\x0a\x09\x09\x09\x09state_data\x20TEXT\x20NOT\x20NULL,\x0a\x09\x09\x09\x09updated_at\x20INTEGER\x20NOT\x20NULL\x0a\x09\x09\x09);\x0a\x09\x09\x09CREATE\x20INDEX\x20IF\x20NOT\x20EXISTS\x20idx_messenger_state_updated\x20ON\x20messenger_manager_state(updated_at);\x0a\x09\x09'),a['exec']('\x0a\x09\x09\x09CREATE\x20TABLE\x20IF\x20NOT\x20EXISTS\x20sse_connection_locks\x20(\x0a\x09\x09\x09\x09account_address\x20TEXT\x20PRIMARY\x20KEY,\x0a\x09\x09\x09\x09process_id\x20TEXT\x20NOT\x20NULL,\x0a\x09\x09\x09\x09instance_id\x20TEXT\x20NOT\x20NULL,\x0a\x09\x09\x09\x09last_heartbeat\x20INTEGER\x20NOT\x20NULL,\x0a\x09\x09\x09\x09created_at\x20INTEGER\x20NOT\x20NULL\x0a\x09\x09\x09);\x0a\x09\x09\x09CREATE\x20INDEX\x20IF\x20NOT\x20EXISTS\x20idx_sse_lock_heartbeat\x20ON\x20sse_connection_locks(last_heartbeat);\x0a\x09\x09'),a['exec']('\x0a\x09\x09\x09CREATE\x20TABLE\x20IF\x20NOT\x20EXISTS\x20polling_connection_locks\x20(\x0a\x09\x09\x09\x09account_address\x20TEXT\x20PRIMARY\x20KEY,\x0a\x09\x09\x09\x09process_id\x20TEXT\x20NOT\x20NULL,\x0a\x09\x09\x09\x09instance_id\x20TEXT\x20NOT\x20NULL,\x0a\x09\x09\x09\x09last_heartbeat\x20INTEGER\x20NOT\x20NULL,\x0a\x09\x09\x09\x09created_at\x20INTEGER\x20NOT\x20NULL\x0a\x09\x09\x09);\x0a\x09\x09\x09CREATE\x20INDEX\x20IF\x20NOT\x20EXISTS\x20idx_polling_lock_heartbeat\x20ON\x20polling_connection_locks(last_heartbeat);\x0a\x09\x09');}['saveState'](a,b){const c=JSON['stringify'](b),d=Date['now']();this['db']['prepare']('\x0a\x09\x09\x09\x09INSERT\x20INTO\x20messenger_manager_state\x20(instance_id,\x20state_data,\x20updated_at)\x0a\x09\x09\x09\x09VALUES\x20(?,\x20?,\x20?)\x0a\x09\x09\x09\x09ON\x20CONFLICT(instance_id)\x20DO\x20UPDATE\x20SET\x0a\x09\x09\x09\x09\x09state_data\x20=\x20excluded.state_data,\x0a\x09\x09\x09\x09\x09updated_at\x20=\x20excluded.updated_at\x0a\x09\x09\x09')['run'](a,c,d);}['loadState'](a){const b=this['db']['prepare']('SELECT\x20state_data\x20FROM\x20messenger_manager_state\x20WHERE\x20instance_id\x20=\x20?')['get'](a);if(!b?.['state_data'])return null;try{return JSON['parse'](b['state_data']);}catch(c){return null;}}['deleteState'](a){this['db']['prepare']('DELETE\x20FROM\x20messenger_manager_state\x20WHERE\x20instance_id\x20=\x20?')['run'](a);}['getAllInstanceIds'](){const a=this['db']['prepare']('SELECT\x20instance_id\x20FROM\x20messenger_manager_state\x20ORDER\x20BY\x20updated_at\x20DESC')['all']();return a['map'](b=>b['instance_id']);}get['processId'](){return'pid_'+process['pid']+'_'+Date['now']();}['tryAcquireSSELock'](a,b){const c=Date['now'](),d=0x3a98,e=this['db']['transaction'](()=>{const f=this['db']['prepare']('SELECT\x20*\x20FROM\x20sse_connection_locks\x20WHERE\x20account_address\x20=\x20?')['get'](a['toLowerCase']());if(f){if(f['instance_id']===b)return this['db']['prepare']('UPDATE\x20sse_connection_locks\x20SET\x20last_heartbeat\x20=\x20?\x20WHERE\x20account_address\x20=\x20?')['run'](c,a['toLowerCase']()),!![];if(c-f['last_heartbeat']<d)return![];}return this['db']['prepare']('\x0a\x09\x09\x09\x09\x09INSERT\x20INTO\x20sse_connection_locks\x20(\x0a\x09\x09\x09\x09\x09\x09account_address,\x20process_id,\x20instance_id,\x20last_heartbeat,\x20created_at\x0a\x09\x09\x09\x09\x09)\x20VALUES\x20(?,\x20?,\x20?,\x20?,\x20?)\x0a\x09\x09\x09\x09\x09ON\x20CONFLICT(account_address)\x20DO\x20UPDATE\x20SET\x0a\x09\x09\x09\x09\x09\x09process_id\x20=\x20excluded.process_id,\x0a\x09\x09\x09\x09\x09\x09instance_id\x20=\x20excluded.instance_id,\x0a\x09\x09\x09\x09\x09\x09last_heartbeat\x20=\x20excluded.last_heartbeat\x0a\x09\x09\x09\x09')['run'](a['toLowerCase'](),this['processId'],b,c,c),!![];});try{return e();}catch(f){return![];}}['updateSSELockHeartbeat'](a,b){const c=Date['now']();try{this['db']['prepare']('UPDATE\x20sse_connection_locks\x20SET\x20last_heartbeat\x20=\x20?\x20WHERE\x20account_address\x20=\x20?\x20AND\x20instance_id\x20=\x20?')['run'](c,a['toLowerCase'](),b);}catch(d){}}['releaseSSELock'](a,b){try{this['db']['prepare']('DELETE\x20FROM\x20sse_connection_locks\x20WHERE\x20account_address\x20=\x20?\x20AND\x20instance_id\x20=\x20?')['run'](a['toLowerCase'](),b);}catch(c){}}['holdsSSELock'](a,b){const c=this['db']['prepare']('SELECT\x20*\x20FROM\x20sse_connection_locks\x20WHERE\x20account_address\x20=\x20?\x20AND\x20instance_id\x20=\x20?')['get'](a['toLowerCase'](),b);return!!c;}['tryAcquirePollingLock'](a,b){const c=Date['now'](),d=0xea60,e=this['db']['transaction'](()=>{const f=this['db']['prepare']('SELECT\x20*\x20FROM\x20polling_connection_locks\x20WHERE\x20account_address\x20=\x20?')['get'](a['toLowerCase']());if(f){if(f['instance_id']===b)return this['db']['prepare']('UPDATE\x20polling_connection_locks\x20SET\x20last_heartbeat\x20=\x20?\x20WHERE\x20account_address\x20=\x20?')['run'](c,a['toLowerCase']()),!![];if(c-f['last_heartbeat']<d)return![];}return this['db']['prepare']('\x0a\x09\x09\x09\x09\x09INSERT\x20INTO\x20polling_connection_locks\x20(\x0a\x09\x09\x09\x09\x09\x09account_address,\x20process_id,\x20instance_id,\x20last_heartbeat,\x20created_at\x0a\x09\x09\x09\x09\x09)\x20VALUES\x20(?,\x20?,\x20?,\x20?,\x20?)\x0a\x09\x09\x09\x09\x09ON\x20CONFLICT(account_address)\x20DO\x20UPDATE\x20SET\x0a\x09\x09\x09\x09\x09\x09process_id\x20=\x20excluded.process_id,\x0a\x09\x09\x09\x09\x09\x09instance_id\x20=\x20excluded.instance_id,\x0a\x09\x09\x09\x09\x09\x09last_heartbeat\x20=\x20excluded.last_heartbeat\x0a\x09\x09\x09\x09')['run'](a['toLowerCase'](),this['processId'],b,c,c),!![];});try{return e();}catch(f){return![];}}['updatePollingLockHeartbeat'](a,b){const c=Date['now']();try{this['db']['prepare']('UPDATE\x20polling_connection_locks\x20SET\x20last_heartbeat\x20=\x20?\x20WHERE\x20account_address\x20=\x20?\x20AND\x20instance_id\x20=\x20?')['run'](c,a['toLowerCase'](),b);}catch(d){}}['releasePollingLock'](a,b){try{this['db']['prepare']('DELETE\x20FROM\x20polling_connection_locks\x20WHERE\x20account_address\x20=\x20?\x20AND\x20instance_id\x20=\x20?')['run'](a['toLowerCase'](),b);}catch(c){}}['holdsPollingLock'](a,b){const c=this['db']['prepare']('SELECT\x20*\x20FROM\x20polling_connection_locks\x20WHERE\x20account_address\x20=\x20?\x20AND\x20instance_id\x20=\x20?')['get'](a['toLowerCase'](),b);return!!c;}}export const defaultPersistStorage=new MessengerPersistStorage();
@@ -103,12 +103,18 @@ export interface ServerRegisterRequest {
103
103
  registrationId: number;
104
104
  identityKey: string;
105
105
  prekeys: PreKeyPublic[];
106
+ pqPrekey?: PQPreKeyPublic;
106
107
  publicKey: string;
107
108
  signatureScheme: SignatureScheme;
108
109
  signature: string;
109
110
  timestamp: number;
110
111
  nonce: string;
111
112
  }
113
+ export interface PQPreKeyPublic {
114
+ keyId: number;
115
+ publicKey: string;
116
+ signature: string;
117
+ }
112
118
  export interface PreKeyPublic {
113
119
  keyId: number;
114
120
  publicKey: string;
@@ -144,6 +150,7 @@ export interface UploadPreKeysResponse {
144
150
  export interface RemoteBundle {
145
151
  registrationId: number;
146
152
  identityKey: string;
153
+ ed25519PublicKey?: string;
147
154
  signedPrekey?: {
148
155
  keyId: number;
149
156
  publicKey: string;
@@ -154,6 +161,11 @@ export interface RemoteBundle {
154
161
  publicKey: string;
155
162
  signature: string;
156
163
  };
164
+ pqPreKey?: {
165
+ keyId: number;
166
+ publicKey: string;
167
+ signature: string;
168
+ };
157
169
  }
158
170
  export interface SendMessageRequest {
159
171
  sender: string;
@@ -177,6 +189,7 @@ export interface SendMessageResponse {
177
189
  status: "confirmed" | "pending";
178
190
  merkleData?: {
179
191
  leafIndex: number;
192
+ leafHash: string;
180
193
  prevRoot: string;
181
194
  newRoot: string;
182
195
  serverSignature: string;
@@ -218,6 +231,7 @@ export interface ServerMessage {
218
231
  zipMetadata?: ZipMetadata;
219
232
  guardAddress?: string;
220
233
  passportAddress?: string;
234
+ verificationStatus?: string;
221
235
  lastReceivedLeafIndex?: number;
222
236
  }
223
237
  export interface ChainProofRequest {
@@ -237,7 +251,7 @@ export declare const NORMAL_MESSAGE_BYTES_LIMIT: number;
237
251
  export declare const DEFAULT_QUERY_LIMIT = 50;
238
252
  export declare const MAX_QUERY_LIMIT = 1000;
239
253
  export declare const DEFAULT_DEVICE_ID = 1;
240
- export declare const SERVER_URL = "https://messenger.wowok.net";
254
+ export declare const SERVER_URL = "http://127.0.0.1:3000";
241
255
  export declare const CHAIN_PROOF_TYPE = 1;
242
256
  export declare const CURRENT_NETWORK = ENTRYPOINT.Testnet;
243
257
  export interface MessengerConfig {
@@ -1 +1 @@
1
- import{ENTRYPOINT}from'../../client/network.js';export var MessageType;(function(a){a[a['PREKEY_MESSAGE']=0x3]='PREKEY_MESSAGE',a[a['NORMAL_MESSAGE']=0x1]='NORMAL_MESSAGE';}(MessageType||(MessageType={})));export var MessageDirection;(function(a){a['SENT']='sent',a['RECEIVED']='received';}(MessageDirection||(MessageDirection={})));export var MessageStatus;(function(a){a['PENDING']='pending',a['CONFIRMED']='confirmed',a['READ']='read',a['FAILED']='failed',a['REJECTED']='rejected',a['DECRYPTED']='decrypted',a['DECRYPT_FAILED']='decrypt_failed';}(MessageStatus||(MessageStatus={})));export const WTS_FILE_BYTES_LIMIT=0x5*0x400*0x400;export const WTS_MAX_MESSAGE_COUNT=0x1f4;export const NORMAL_MESSAGE_BYTES_LIMIT=0xa*0x400;export const DEFAULT_QUERY_LIMIT=0x32;export const MAX_QUERY_LIMIT=0x3e8;export const DEFAULT_DEVICE_ID=0x1;export const SERVER_URL='https://messenger.wowok.net';export const CHAIN_PROOF_TYPE=0x1;export const CURRENT_NETWORK=ENTRYPOINT['Testnet'];export const DEFAULT_MESSENGER_CONFIG={'prekey_count':0x28,'watch_interval_ms':0x3c*0x3e8,'serverUrl':SERVER_URL,'network':CURRENT_NETWORK,'prekeyCheckIntervalMs':0x18*0x3c*0x3c*0x3e8,'defaultQueryLimit':DEFAULT_QUERY_LIMIT,'message_poll_default_interval_ms':0x6*0x3c*0x3e8,'message_poll_fast_interval_ms':0x6*0x3e8,'prekey_poll_default_interval_ms':0x3c*0x3c*0x3e8,'prekey_poll_fast_interval_ms':0x1e*0x3e8,'account_poll_delay_ms':0xc8,'message_poll_consecutive_empty_limit':0x3,'prekey_poll_consecutive_ok_limit':0x3};export var MessengerErrorCode;(function(a){a['PREKEYS_FULL']='PREKEYS_FULL',a['ACCOUNT_NOT_FOUND']='ACCOUNT_NOT_FOUND',a['IDENTITY_NOT_FOUND']='IDENTITY_NOT_FOUND',a['IDENTITY_CONFLICT']='IDENTITY_CONFLICT',a['SESSION_NOT_ESTABLISHED']='SESSION_NOT_ESTABLISHED',a['ENCRYPTION_FAILED']='ENCRYPTION_FAILED',a['DECRYPTION_FAILED']='DECRYPTION_FAILED',a['SERVER_ERROR']='SERVER_ERROR',a['INVALID_PROOF']='INVALID_PROOF',a['NETWORK_ERROR']='NETWORK_ERROR',a['INVALID_INPUT']='INVALID_INPUT',a['FILE_NOT_FOUND']='FILE_NOT_FOUND',a['INVALID_MESSAGE_TYPE']='INVALID_MESSAGE_TYPE',a['MESSAGE_NOT_DECRYPTED']='MESSAGE_NOT_DECRYPTED',a['HASH_MISMATCH']='HASH_MISMATCH',a['ACCOUNT_MESSENGER_NOT_ENABLED']='ACCOUNT_MESSENGER_NOT_ENABLED',a['REGISTRATION_FAILED']='REGISTRATION_FAILED';}(MessengerErrorCode||(MessengerErrorCode={})));export class MessengerError extends Error{['code'];['cause'];constructor(a,b,c){super(b),this['code']=a,this['cause']=c,this['name']='MessengerError';}}export const WTS_SCHEMA_URL='https://schema.wowok.net/wts/v1';
1
+ import{ENTRYPOINT}from'../../client/network.js';export var MessageType;(function(a){a[a['PREKEY_MESSAGE']=0x3]='PREKEY_MESSAGE',a[a['NORMAL_MESSAGE']=0x1]='NORMAL_MESSAGE';}(MessageType||(MessageType={})));export var MessageDirection;(function(a){a['SENT']='sent',a['RECEIVED']='received';}(MessageDirection||(MessageDirection={})));export var MessageStatus;(function(a){a['PENDING']='pending',a['CONFIRMED']='confirmed',a['READ']='read',a['FAILED']='failed',a['REJECTED']='rejected',a['DECRYPTED']='decrypted',a['DECRYPT_FAILED']='decrypt_failed';}(MessageStatus||(MessageStatus={})));export const WTS_FILE_BYTES_LIMIT=0x5*0x400*0x400;export const WTS_MAX_MESSAGE_COUNT=0x1f4;export const NORMAL_MESSAGE_BYTES_LIMIT=0xa*0x400;export const DEFAULT_QUERY_LIMIT=0x32;export const MAX_QUERY_LIMIT=0x3e8;export const DEFAULT_DEVICE_ID=0x1;export const SERVER_URL='http://127.0.0.1:3000';export const CHAIN_PROOF_TYPE=0x1;export const CURRENT_NETWORK=ENTRYPOINT['Testnet'];export const DEFAULT_MESSENGER_CONFIG={'prekey_count':0x28,'watch_interval_ms':0x3c*0x3e8,'serverUrl':SERVER_URL,'network':CURRENT_NETWORK,'prekeyCheckIntervalMs':0x18*0x3c*0x3c*0x3e8,'defaultQueryLimit':DEFAULT_QUERY_LIMIT,'message_poll_default_interval_ms':0x6*0x3c*0x3e8,'message_poll_fast_interval_ms':0x6*0x3e8,'prekey_poll_default_interval_ms':0x3c*0x3c*0x3e8,'prekey_poll_fast_interval_ms':0x1e*0x3e8,'account_poll_delay_ms':0xc8,'message_poll_consecutive_empty_limit':0x3,'prekey_poll_consecutive_ok_limit':0x3};export var MessengerErrorCode;(function(a){a['PREKEYS_FULL']='PREKEYS_FULL',a['ACCOUNT_NOT_FOUND']='ACCOUNT_NOT_FOUND',a['IDENTITY_NOT_FOUND']='IDENTITY_NOT_FOUND',a['IDENTITY_CONFLICT']='IDENTITY_CONFLICT',a['SESSION_NOT_ESTABLISHED']='SESSION_NOT_ESTABLISHED',a['ENCRYPTION_FAILED']='ENCRYPTION_FAILED',a['DECRYPTION_FAILED']='DECRYPTION_FAILED',a['SERVER_ERROR']='SERVER_ERROR',a['INVALID_PROOF']='INVALID_PROOF',a['NETWORK_ERROR']='NETWORK_ERROR',a['INVALID_INPUT']='INVALID_INPUT',a['FILE_NOT_FOUND']='FILE_NOT_FOUND',a['INVALID_MESSAGE_TYPE']='INVALID_MESSAGE_TYPE',a['MESSAGE_NOT_DECRYPTED']='MESSAGE_NOT_DECRYPTED',a['HASH_MISMATCH']='HASH_MISMATCH',a['ACCOUNT_MESSENGER_NOT_ENABLED']='ACCOUNT_MESSENGER_NOT_ENABLED',a['REGISTRATION_FAILED']='REGISTRATION_FAILED';}(MessengerErrorCode||(MessengerErrorCode={})));export class MessengerError extends Error{['code'];['cause'];constructor(a,b,c){super(b),this['code']=a,this['cause']=c,this['name']='MessengerError';}}export const WTS_SCHEMA_URL='https://schema.wowok.net/wts/v1';