@k9o/react-native-matrix-crypto 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/android/RNMatrixCryptoModule.kt +20 -0
- package/android/build.gradle +62 -0
- package/android/proguard-rules.pro +16 -0
- package/ios/RNMatrixCryptoModule.swift +20 -0
- package/lib/CryptoAPI.d.ts +83 -0
- package/lib/CryptoAPI.js +220 -0
- package/lib/NativeMatrixCrypto.d.ts +87 -0
- package/lib/NativeMatrixCrypto.js +38 -0
- package/lib/index.d.ts +116 -0
- package/lib/index.js +267 -0
- package/package.json +74 -0
- package/react-native-matrix-crypto.podspec +25 -0
- package/src/CryptoAPI.ts +256 -0
- package/src/NativeMatrixCrypto.ts +157 -0
- package/src/index.ts +369 -0
package/lib/index.js
ADDED
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MatrixCrypto = void 0;
|
|
4
|
+
const react_native_1 = require("react-native");
|
|
5
|
+
const LINKING_ERROR = `The package 'react-native-matrix-crypto' doesn't seem to be linked. Make sure: \n\n` +
|
|
6
|
+
react_native_1.Platform.select({ ios: "- You have run 'pod install'\n", default: '' }) +
|
|
7
|
+
'- You rebuilt the app after installing the package\n' +
|
|
8
|
+
'- You are not using Expo Go\n';
|
|
9
|
+
const MatrixCryptoModule = react_native_1.NativeModules.MatrixCrypto
|
|
10
|
+
? react_native_1.NativeModules.MatrixCrypto
|
|
11
|
+
: new Proxy({}, {
|
|
12
|
+
get() {
|
|
13
|
+
throw new Error(LINKING_ERROR);
|
|
14
|
+
},
|
|
15
|
+
});
|
|
16
|
+
class MatrixCrypto {
|
|
17
|
+
constructor() {
|
|
18
|
+
this.handle = null;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Get or create singleton instance
|
|
22
|
+
*/
|
|
23
|
+
static getInstance() {
|
|
24
|
+
if (!MatrixCrypto.instance) {
|
|
25
|
+
MatrixCrypto.instance = new MatrixCrypto();
|
|
26
|
+
}
|
|
27
|
+
return MatrixCrypto.instance;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Initialize the crypto machine
|
|
31
|
+
*/
|
|
32
|
+
async initialize(userId, deviceId, pickleKey) {
|
|
33
|
+
try {
|
|
34
|
+
this.handle = await MatrixCryptoModule.initialize(userId, deviceId, pickleKey);
|
|
35
|
+
}
|
|
36
|
+
catch (error) {
|
|
37
|
+
throw new Error(`Failed to initialize Matrix crypto: ${error}`);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Get the device fingerprint
|
|
42
|
+
*/
|
|
43
|
+
async getDeviceFingerprint() {
|
|
44
|
+
if (!this.handle) {
|
|
45
|
+
throw new Error('Crypto not initialized');
|
|
46
|
+
}
|
|
47
|
+
try {
|
|
48
|
+
return await MatrixCryptoModule.getDeviceFingerprint(this.handle);
|
|
49
|
+
}
|
|
50
|
+
catch (error) {
|
|
51
|
+
throw new Error(`Failed to get device fingerprint: ${error}`);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Get the user ID
|
|
56
|
+
*/
|
|
57
|
+
async getUserId() {
|
|
58
|
+
if (!this.handle) {
|
|
59
|
+
throw new Error('Crypto not initialized');
|
|
60
|
+
}
|
|
61
|
+
try {
|
|
62
|
+
return await MatrixCryptoModule.getUserId(this.handle);
|
|
63
|
+
}
|
|
64
|
+
catch (error) {
|
|
65
|
+
throw new Error(`Failed to get user ID: ${error}`);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Get the device ID
|
|
70
|
+
*/
|
|
71
|
+
async getDeviceId() {
|
|
72
|
+
if (!this.handle) {
|
|
73
|
+
throw new Error('Crypto not initialized');
|
|
74
|
+
}
|
|
75
|
+
try {
|
|
76
|
+
return await MatrixCryptoModule.getDeviceId(this.handle);
|
|
77
|
+
}
|
|
78
|
+
catch (error) {
|
|
79
|
+
throw new Error(`Failed to get device ID: ${error}`);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Get devices for a user
|
|
84
|
+
*/
|
|
85
|
+
async getUserDevices(userId) {
|
|
86
|
+
if (!this.handle) {
|
|
87
|
+
throw new Error('Crypto not initialized');
|
|
88
|
+
}
|
|
89
|
+
try {
|
|
90
|
+
return await MatrixCryptoModule.getUserDevices(this.handle, userId);
|
|
91
|
+
}
|
|
92
|
+
catch (error) {
|
|
93
|
+
throw new Error(`Failed to get user devices: ${error}`);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Add a device
|
|
98
|
+
*/
|
|
99
|
+
async addDevice(device) {
|
|
100
|
+
if (!this.handle) {
|
|
101
|
+
throw new Error('Crypto not initialized');
|
|
102
|
+
}
|
|
103
|
+
try {
|
|
104
|
+
await MatrixCryptoModule.addDevice(this.handle, device);
|
|
105
|
+
}
|
|
106
|
+
catch (error) {
|
|
107
|
+
throw new Error(`Failed to add device: ${error}`);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Start device verification
|
|
112
|
+
*/
|
|
113
|
+
async startVerification(otherUserId, otherDeviceId) {
|
|
114
|
+
if (!this.handle) {
|
|
115
|
+
throw new Error('Crypto not initialized');
|
|
116
|
+
}
|
|
117
|
+
try {
|
|
118
|
+
return await MatrixCryptoModule.startVerification(this.handle, otherUserId, otherDeviceId);
|
|
119
|
+
}
|
|
120
|
+
catch (error) {
|
|
121
|
+
throw new Error(`Failed to start verification: ${error}`);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Get SAS emojis
|
|
126
|
+
*/
|
|
127
|
+
async getSASEmojis(verificationId) {
|
|
128
|
+
if (!this.handle) {
|
|
129
|
+
throw new Error('Crypto not initialized');
|
|
130
|
+
}
|
|
131
|
+
try {
|
|
132
|
+
return await MatrixCryptoModule.getSASEmojis(this.handle, verificationId);
|
|
133
|
+
}
|
|
134
|
+
catch (error) {
|
|
135
|
+
throw new Error(`Failed to get SAS emojis: ${error}`);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Confirm SAS
|
|
140
|
+
*/
|
|
141
|
+
async confirmSAS(verificationId) {
|
|
142
|
+
if (!this.handle) {
|
|
143
|
+
throw new Error('Crypto not initialized');
|
|
144
|
+
}
|
|
145
|
+
try {
|
|
146
|
+
await MatrixCryptoModule.confirmSAS(this.handle, verificationId);
|
|
147
|
+
}
|
|
148
|
+
catch (error) {
|
|
149
|
+
throw new Error(`Failed to confirm SAS: ${error}`);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Complete verification
|
|
154
|
+
*/
|
|
155
|
+
async completeVerification(verificationId) {
|
|
156
|
+
if (!this.handle) {
|
|
157
|
+
throw new Error('Crypto not initialized');
|
|
158
|
+
}
|
|
159
|
+
try {
|
|
160
|
+
await MatrixCryptoModule.completeVerification(this.handle, verificationId);
|
|
161
|
+
}
|
|
162
|
+
catch (error) {
|
|
163
|
+
throw new Error(`Failed to complete verification: ${error}`);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Cancel verification
|
|
168
|
+
*/
|
|
169
|
+
async cancelVerification(verificationId) {
|
|
170
|
+
if (!this.handle) {
|
|
171
|
+
throw new Error('Crypto not initialized');
|
|
172
|
+
}
|
|
173
|
+
try {
|
|
174
|
+
await MatrixCryptoModule.cancelVerification(this.handle, verificationId);
|
|
175
|
+
}
|
|
176
|
+
catch (error) {
|
|
177
|
+
throw new Error(`Failed to cancel verification: ${error}`);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Get verification state
|
|
182
|
+
*/
|
|
183
|
+
async getVerificationState(verificationId) {
|
|
184
|
+
if (!this.handle) {
|
|
185
|
+
throw new Error('Crypto not initialized');
|
|
186
|
+
}
|
|
187
|
+
try {
|
|
188
|
+
return await MatrixCryptoModule.getVerificationState(this.handle, verificationId);
|
|
189
|
+
}
|
|
190
|
+
catch (error) {
|
|
191
|
+
throw new Error(`Failed to get verification state: ${error}`);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Enable room encryption
|
|
196
|
+
*/
|
|
197
|
+
async enableRoomEncryption(roomId, algorithm) {
|
|
198
|
+
if (!this.handle) {
|
|
199
|
+
throw new Error('Crypto not initialized');
|
|
200
|
+
}
|
|
201
|
+
try {
|
|
202
|
+
await MatrixCryptoModule.enableRoomEncryption(this.handle, roomId, algorithm);
|
|
203
|
+
}
|
|
204
|
+
catch (error) {
|
|
205
|
+
throw new Error(`Failed to enable room encryption: ${error}`);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Get room encryption state
|
|
210
|
+
*/
|
|
211
|
+
async getRoomEncryptionState(roomId) {
|
|
212
|
+
if (!this.handle) {
|
|
213
|
+
throw new Error('Crypto not initialized');
|
|
214
|
+
}
|
|
215
|
+
try {
|
|
216
|
+
return await MatrixCryptoModule.getRoomEncryptionState(this.handle, roomId);
|
|
217
|
+
}
|
|
218
|
+
catch (error) {
|
|
219
|
+
throw new Error(`Failed to get room encryption state: ${error}`);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Encrypt event
|
|
224
|
+
*/
|
|
225
|
+
async encryptEvent(roomId, eventType, content) {
|
|
226
|
+
if (!this.handle) {
|
|
227
|
+
throw new Error('Crypto not initialized');
|
|
228
|
+
}
|
|
229
|
+
try {
|
|
230
|
+
return await MatrixCryptoModule.encryptEvent(this.handle, roomId, eventType, content);
|
|
231
|
+
}
|
|
232
|
+
catch (error) {
|
|
233
|
+
throw new Error(`Failed to encrypt event: ${error}`);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* Decrypt event
|
|
238
|
+
*/
|
|
239
|
+
async decryptEvent(roomId, encryptedContent) {
|
|
240
|
+
if (!this.handle) {
|
|
241
|
+
throw new Error('Crypto not initialized');
|
|
242
|
+
}
|
|
243
|
+
try {
|
|
244
|
+
return await MatrixCryptoModule.decryptEvent(this.handle, roomId, encryptedContent);
|
|
245
|
+
}
|
|
246
|
+
catch (error) {
|
|
247
|
+
throw new Error(`Failed to decrypt event: ${error}`);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* Cleanup
|
|
252
|
+
*/
|
|
253
|
+
async destroy() {
|
|
254
|
+
if (this.handle) {
|
|
255
|
+
try {
|
|
256
|
+
await MatrixCryptoModule.destroy(this.handle);
|
|
257
|
+
}
|
|
258
|
+
catch (error) {
|
|
259
|
+
console.error(`Failed to destroy crypto: ${error}`);
|
|
260
|
+
}
|
|
261
|
+
this.handle = null;
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
exports.MatrixCrypto = MatrixCrypto;
|
|
266
|
+
MatrixCrypto.instance = null;
|
|
267
|
+
exports.default = MatrixCrypto.getInstance();
|
package/package.json
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@k9o/react-native-matrix-crypto",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Native Rust crypto bridge for React Native Matrix client with End-to-End Encryption support",
|
|
5
|
+
"main": "lib/index.js",
|
|
6
|
+
"types": "lib/index.d.ts",
|
|
7
|
+
"files": [
|
|
8
|
+
"lib",
|
|
9
|
+
"src",
|
|
10
|
+
"ios",
|
|
11
|
+
"android",
|
|
12
|
+
"react-native-matrix-crypto.podspec"
|
|
13
|
+
],
|
|
14
|
+
"scripts": {
|
|
15
|
+
"build": "tsc",
|
|
16
|
+
"test": "jest",
|
|
17
|
+
"prepare": "npm run build",
|
|
18
|
+
"type-check": "tsc --noEmit",
|
|
19
|
+
"lint": "eslint src --ext .ts,.tsx"
|
|
20
|
+
},
|
|
21
|
+
"keywords": [
|
|
22
|
+
"matrix",
|
|
23
|
+
"crypto",
|
|
24
|
+
"e2ee",
|
|
25
|
+
"encryption",
|
|
26
|
+
"react-native",
|
|
27
|
+
"ios",
|
|
28
|
+
"android",
|
|
29
|
+
"rust",
|
|
30
|
+
"uniffi"
|
|
31
|
+
],
|
|
32
|
+
"author": "Matrix Chat Contributors",
|
|
33
|
+
"license": "Apache-2.0",
|
|
34
|
+
"repository": {
|
|
35
|
+
"type": "git",
|
|
36
|
+
"url": "https://github.com/k9o-dev/matrix-crypto-bridge.git",
|
|
37
|
+
"directory": "react-native-matrix-crypto"
|
|
38
|
+
},
|
|
39
|
+
"bugs": {
|
|
40
|
+
"url": "https://github.com/k9o-dev/matrix-crypto-bridge/issues"
|
|
41
|
+
},
|
|
42
|
+
"homepage": "https://github.com/k9o-dev/matrix-crypto-bridge#readme",
|
|
43
|
+
"peerDependencies": {
|
|
44
|
+
"react": ">=16.8.0",
|
|
45
|
+
"react-native": ">=0.71.0"
|
|
46
|
+
},
|
|
47
|
+
"peerDependenciesMeta": {
|
|
48
|
+
"react": {
|
|
49
|
+
"optional": true
|
|
50
|
+
},
|
|
51
|
+
"react-native": {
|
|
52
|
+
"optional": true
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
"devDependencies": {
|
|
56
|
+
"react": "^19.2.4",
|
|
57
|
+
"react-native": "^0.84.1",
|
|
58
|
+
"@types/react": "^19.2.0",
|
|
59
|
+
"@types/react-native": "^0.73.0",
|
|
60
|
+
"typescript": "^5.3.3",
|
|
61
|
+
"jest": "^29.7.0",
|
|
62
|
+
"eslint": "^8.50.0",
|
|
63
|
+
"@typescript-eslint/eslint-plugin": "^6.7.0",
|
|
64
|
+
"@typescript-eslint/parser": "^6.7.0"
|
|
65
|
+
},
|
|
66
|
+
"engines": {
|
|
67
|
+
"node": ">=16.0.0",
|
|
68
|
+
"npm": ">=8.0.0"
|
|
69
|
+
},
|
|
70
|
+
"publishConfig": {
|
|
71
|
+
"access": "public",
|
|
72
|
+
"registry": "https://registry.npmjs.org/"
|
|
73
|
+
}
|
|
74
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
require "json"
|
|
2
|
+
|
|
3
|
+
package = JSON.parse(File.read(File.join(__dir__, "package.json")))
|
|
4
|
+
|
|
5
|
+
Pod::Spec.new do |s|
|
|
6
|
+
s.name = "react-native-matrix-crypto"
|
|
7
|
+
s.version = package["version"]
|
|
8
|
+
s.summary = package["description"]
|
|
9
|
+
s.homepage = package["homepage"]
|
|
10
|
+
s.license = package["license"]
|
|
11
|
+
s.authors = package["author"]
|
|
12
|
+
s.platforms = { :ios => "11.0" }
|
|
13
|
+
s.source = { :git => package["repository"]["url"], :tag => "#{s.version}" }
|
|
14
|
+
|
|
15
|
+
s.source_files = "ios/**/*.{h,m,mm,swift}"
|
|
16
|
+
s.requires_arc = true
|
|
17
|
+
|
|
18
|
+
s.dependency "React-Core"
|
|
19
|
+
s.dependency "MatrixCryptoBridge"
|
|
20
|
+
|
|
21
|
+
s.pod_target_xcconfig = {
|
|
22
|
+
"DEFINES_MODULE" => "YES",
|
|
23
|
+
"SWIFT_VERSION" => "5.9"
|
|
24
|
+
}
|
|
25
|
+
end
|
package/src/CryptoAPI.ts
ADDED
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
import { NativeMatrixCrypto } from './NativeMatrixCrypto';
|
|
2
|
+
import {
|
|
3
|
+
DeviceInfo,
|
|
4
|
+
EmojiSASPair,
|
|
5
|
+
VerificationState,
|
|
6
|
+
RoomEncryptionState,
|
|
7
|
+
} from './index';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* High-level API for Matrix crypto operations
|
|
11
|
+
* Provides a clean, easy-to-use interface for encryption, device verification, and key management
|
|
12
|
+
*/
|
|
13
|
+
export class CryptoAPI {
|
|
14
|
+
private initialized: boolean = false;
|
|
15
|
+
private userId: string = '';
|
|
16
|
+
private deviceId: string = '';
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Initialize the crypto API
|
|
20
|
+
*/
|
|
21
|
+
async initialize(
|
|
22
|
+
userId: string,
|
|
23
|
+
deviceId: string,
|
|
24
|
+
pickleKey: string
|
|
25
|
+
): Promise<void> {
|
|
26
|
+
try {
|
|
27
|
+
await NativeMatrixCrypto.initialize(userId, deviceId, pickleKey);
|
|
28
|
+
this.initialized = true;
|
|
29
|
+
this.userId = userId;
|
|
30
|
+
this.deviceId = deviceId;
|
|
31
|
+
} catch (error) {
|
|
32
|
+
throw new Error(`Failed to initialize crypto: ${error}`);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Check if crypto is initialized
|
|
38
|
+
*/
|
|
39
|
+
isInitialized(): boolean {
|
|
40
|
+
return this.initialized;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Get device information
|
|
45
|
+
*/
|
|
46
|
+
async getDeviceInfo(): Promise<{
|
|
47
|
+
fingerprint: string;
|
|
48
|
+
userId: string;
|
|
49
|
+
deviceId: string;
|
|
50
|
+
}> {
|
|
51
|
+
this.assertInitialized();
|
|
52
|
+
try {
|
|
53
|
+
const [fingerprint, userId, deviceId] = await Promise.all([
|
|
54
|
+
NativeMatrixCrypto.getDeviceFingerprint(),
|
|
55
|
+
NativeMatrixCrypto.getUserId(),
|
|
56
|
+
NativeMatrixCrypto.getDeviceId(),
|
|
57
|
+
]);
|
|
58
|
+
return { fingerprint, userId, deviceId };
|
|
59
|
+
} catch (error) {
|
|
60
|
+
throw new Error(`Failed to get device info: ${error}`);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Get all devices for a user
|
|
66
|
+
*/
|
|
67
|
+
async getUserDevices(userId: string): Promise<DeviceInfo[]> {
|
|
68
|
+
this.assertInitialized();
|
|
69
|
+
try {
|
|
70
|
+
return await NativeMatrixCrypto.getUserDevices(userId);
|
|
71
|
+
} catch (error) {
|
|
72
|
+
throw new Error(`Failed to get user devices: ${error}`);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Add a device to the device store
|
|
78
|
+
*/
|
|
79
|
+
async addDevice(device: DeviceInfo): Promise<void> {
|
|
80
|
+
this.assertInitialized();
|
|
81
|
+
try {
|
|
82
|
+
await NativeMatrixCrypto.addDevice(device);
|
|
83
|
+
} catch (error) {
|
|
84
|
+
throw new Error(`Failed to add device: ${error}`);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Start device verification with another device
|
|
90
|
+
*/
|
|
91
|
+
async startVerification(
|
|
92
|
+
otherUserId: string,
|
|
93
|
+
otherDeviceId: string
|
|
94
|
+
): Promise<VerificationState> {
|
|
95
|
+
this.assertInitialized();
|
|
96
|
+
try {
|
|
97
|
+
const result = await NativeMatrixCrypto.startVerification(
|
|
98
|
+
otherUserId,
|
|
99
|
+
otherDeviceId
|
|
100
|
+
);
|
|
101
|
+
return result as VerificationState;
|
|
102
|
+
} catch (error) {
|
|
103
|
+
throw new Error(`Failed to start verification: ${error}`);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Get SAS emoji pairs for verification
|
|
109
|
+
*/
|
|
110
|
+
async getSASEmojis(verificationId: string): Promise<EmojiSASPair[]> {
|
|
111
|
+
this.assertInitialized();
|
|
112
|
+
try {
|
|
113
|
+
return await NativeMatrixCrypto.getSASEmojis(verificationId);
|
|
114
|
+
} catch (error) {
|
|
115
|
+
throw new Error(`Failed to get SAS emojis: ${error}`);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Confirm SAS verification
|
|
121
|
+
*/
|
|
122
|
+
async confirmSAS(verificationId: string): Promise<void> {
|
|
123
|
+
this.assertInitialized();
|
|
124
|
+
try {
|
|
125
|
+
await NativeMatrixCrypto.confirmSAS(verificationId);
|
|
126
|
+
} catch (error) {
|
|
127
|
+
throw new Error(`Failed to confirm SAS: ${error}`);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Complete device verification
|
|
133
|
+
*/
|
|
134
|
+
async completeVerification(verificationId: string): Promise<void> {
|
|
135
|
+
this.assertInitialized();
|
|
136
|
+
try {
|
|
137
|
+
await NativeMatrixCrypto.completeVerification(verificationId);
|
|
138
|
+
} catch (error) {
|
|
139
|
+
throw new Error(`Failed to complete verification: ${error}`);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Cancel device verification
|
|
145
|
+
*/
|
|
146
|
+
async cancelVerification(verificationId: string): Promise<void> {
|
|
147
|
+
this.assertInitialized();
|
|
148
|
+
try {
|
|
149
|
+
await NativeMatrixCrypto.cancelVerification(verificationId);
|
|
150
|
+
} catch (error) {
|
|
151
|
+
throw new Error(`Failed to cancel verification: ${error}`);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Get the current state of a verification
|
|
157
|
+
*/
|
|
158
|
+
async getVerificationState(
|
|
159
|
+
verificationId: string
|
|
160
|
+
): Promise<VerificationState> {
|
|
161
|
+
this.assertInitialized();
|
|
162
|
+
try {
|
|
163
|
+
const result = await NativeMatrixCrypto.getVerificationState(verificationId);
|
|
164
|
+
return result as VerificationState;
|
|
165
|
+
} catch (error) {
|
|
166
|
+
throw new Error(`Failed to get verification state: ${error}`);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Enable encryption for a room
|
|
172
|
+
*/
|
|
173
|
+
async enableRoomEncryption(
|
|
174
|
+
roomId: string,
|
|
175
|
+
algorithm: string = 'm.megolm.v1.aes-sha2'
|
|
176
|
+
): Promise<void> {
|
|
177
|
+
this.assertInitialized();
|
|
178
|
+
try {
|
|
179
|
+
await NativeMatrixCrypto.enableRoomEncryption(roomId, algorithm);
|
|
180
|
+
} catch (error) {
|
|
181
|
+
throw new Error(`Failed to enable room encryption: ${error}`);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Get encryption state for a room
|
|
187
|
+
*/
|
|
188
|
+
async getRoomEncryptionState(roomId: string): Promise<RoomEncryptionState> {
|
|
189
|
+
this.assertInitialized();
|
|
190
|
+
try {
|
|
191
|
+
return await NativeMatrixCrypto.getRoomEncryptionState(roomId);
|
|
192
|
+
} catch (error) {
|
|
193
|
+
throw new Error(`Failed to get room encryption state: ${error}`);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Encrypt an event
|
|
199
|
+
*/
|
|
200
|
+
async encryptEvent(
|
|
201
|
+
roomId: string,
|
|
202
|
+
eventType: string,
|
|
203
|
+
content: string
|
|
204
|
+
): Promise<string> {
|
|
205
|
+
this.assertInitialized();
|
|
206
|
+
try {
|
|
207
|
+
return await NativeMatrixCrypto.encryptEvent(
|
|
208
|
+
roomId,
|
|
209
|
+
eventType,
|
|
210
|
+
content
|
|
211
|
+
);
|
|
212
|
+
} catch (error) {
|
|
213
|
+
throw new Error(`Failed to encrypt event: ${error}`);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* Decrypt an event
|
|
219
|
+
*/
|
|
220
|
+
async decryptEvent(
|
|
221
|
+
roomId: string,
|
|
222
|
+
encryptedContent: string
|
|
223
|
+
): Promise<string> {
|
|
224
|
+
this.assertInitialized();
|
|
225
|
+
try {
|
|
226
|
+
return await NativeMatrixCrypto.decryptEvent(roomId, encryptedContent);
|
|
227
|
+
} catch (error) {
|
|
228
|
+
throw new Error(`Failed to decrypt event: ${error}`);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* Cleanup and destroy the crypto instance
|
|
234
|
+
*/
|
|
235
|
+
async destroy(): Promise<void> {
|
|
236
|
+
try {
|
|
237
|
+
await NativeMatrixCrypto.destroy();
|
|
238
|
+
this.initialized = false;
|
|
239
|
+
} catch (error) {
|
|
240
|
+
throw new Error(`Failed to destroy crypto: ${error}`);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* Helper method to ensure crypto is initialized
|
|
246
|
+
*/
|
|
247
|
+
private assertInitialized(): void {
|
|
248
|
+
if (!this.initialized) {
|
|
249
|
+
throw new Error(
|
|
250
|
+
'Crypto not initialized. Call initialize() first.'
|
|
251
|
+
);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
export default CryptoAPI;
|