@aztec/wallet-sdk 4.0.0-nightly.20260108 → 4.0.0-nightly.20260111
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +172 -138
- package/dest/crypto.d.ts +146 -0
- package/dest/crypto.d.ts.map +1 -0
- package/dest/crypto.js +216 -0
- package/dest/manager/index.d.ts +2 -2
- package/dest/manager/index.d.ts.map +1 -1
- package/dest/manager/wallet_manager.js +1 -1
- package/dest/providers/extension/extension_provider.d.ts +2 -2
- package/dest/providers/extension/extension_provider.d.ts.map +1 -1
- package/dest/providers/extension/extension_wallet.d.ts +79 -7
- package/dest/providers/extension/extension_wallet.d.ts.map +1 -1
- package/dest/providers/extension/extension_wallet.js +173 -44
- package/dest/providers/extension/index.d.ts +3 -2
- package/dest/providers/extension/index.d.ts.map +1 -1
- package/dest/providers/extension/index.js +1 -0
- package/dest/types.d.ts +83 -0
- package/dest/types.d.ts.map +1 -0
- package/dest/types.js +3 -0
- package/package.json +10 -8
- package/src/crypto.ts +283 -0
- package/src/manager/index.ts +1 -7
- package/src/manager/wallet_manager.ts +1 -1
- package/src/providers/extension/extension_provider.ts +1 -1
- package/src/providers/extension/extension_wallet.ts +206 -55
- package/src/providers/extension/index.ts +9 -1
- package/src/{providers/types.ts → types.ts} +22 -4
- package/dest/providers/types.d.ts +0 -67
- package/dest/providers/types.d.ts.map +0 -1
- package/dest/providers/types.js +0 -3
package/README.md
CHANGED
|
@@ -9,6 +9,7 @@ All types and utilities needed for wallet integration are exported from `@aztec/
|
|
|
9
9
|
```typescript
|
|
10
10
|
import type {
|
|
11
11
|
ChainInfo,
|
|
12
|
+
ConnectRequest,
|
|
12
13
|
DiscoveryRequest,
|
|
13
14
|
DiscoveryResponse,
|
|
14
15
|
WalletInfo,
|
|
@@ -18,15 +19,30 @@ import type {
|
|
|
18
19
|
import { ChainInfoSchema, WalletSchema, jsonStringify } from '@aztec/wallet-sdk/manager';
|
|
19
20
|
```
|
|
20
21
|
|
|
22
|
+
Cryptographic utilities for secure channel establishment are exported from `@aztec/wallet-sdk/crypto`:
|
|
23
|
+
|
|
24
|
+
```typescript
|
|
25
|
+
import type { EncryptedPayload, ExportedPublicKey } from '@aztec/wallet-sdk/crypto';
|
|
26
|
+
import {
|
|
27
|
+
decrypt,
|
|
28
|
+
deriveSharedKey,
|
|
29
|
+
encrypt,
|
|
30
|
+
exportPublicKey,
|
|
31
|
+
generateKeyPair,
|
|
32
|
+
importPublicKey,
|
|
33
|
+
} from '@aztec/wallet-sdk/crypto';
|
|
34
|
+
```
|
|
35
|
+
|
|
21
36
|
## Overview
|
|
22
37
|
|
|
23
|
-
The Wallet SDK uses a **request-based discovery** model
|
|
38
|
+
The Wallet SDK uses a **request-based discovery** model with **end-to-end encryption**:
|
|
24
39
|
|
|
25
40
|
1. **dApp requests wallets** for a specific chain/version via `WalletManager.getAvailableWallets({ chainInfo })`
|
|
26
41
|
2. **SDK broadcasts** a discovery message with chain information
|
|
27
|
-
3. **Your wallet responds** ONLY if it supports that specific network
|
|
42
|
+
3. **Your wallet responds** with its ECDH public key ONLY if it supports that specific network
|
|
28
43
|
4. **dApp receives** only compatible wallets
|
|
29
|
-
5. **dApp
|
|
44
|
+
5. **dApp establishes secure channel** via ECDH key exchange (see [Secure Channel](#secure-channel))
|
|
45
|
+
6. **All subsequent communication** is encrypted using AES-256-GCM
|
|
30
46
|
|
|
31
47
|
### Transport Mechanisms
|
|
32
48
|
|
|
@@ -116,7 +132,19 @@ If your wallet supports the network, respond with your wallet information:
|
|
|
116
132
|
```typescript
|
|
117
133
|
import { jsonStringify } from '@aztec/wallet-sdk/manager';
|
|
118
134
|
|
|
119
|
-
|
|
135
|
+
// Your wallet should generate a key pair on initialization.
|
|
136
|
+
// This keypair should be recreated each session
|
|
137
|
+
let walletKeyPair: CryptoKeyPair;
|
|
138
|
+
|
|
139
|
+
async function initializeWallet() {
|
|
140
|
+
// Generate ECDH key pair for secure channel establishment
|
|
141
|
+
walletKeyPair = await generateKeyPair();
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
async function respondToDiscovery(requestId: string) {
|
|
145
|
+
// Export the public key for sharing with dApps
|
|
146
|
+
const publicKey = await exportPublicKey(walletKeyPair.publicKey);
|
|
147
|
+
|
|
120
148
|
const response = {
|
|
121
149
|
type: 'aztec-wallet-discovery-response',
|
|
122
150
|
requestId,
|
|
@@ -125,6 +153,7 @@ function respondToDiscovery(requestId: string) {
|
|
|
125
153
|
name: 'My Aztec Wallet', // Display name
|
|
126
154
|
icon: 'https://example.com/icon.png', // Optional icon URL
|
|
127
155
|
version: '1.0.0', // Wallet version
|
|
156
|
+
publicKey, // ECDH public key for secure channel (required)
|
|
128
157
|
},
|
|
129
158
|
};
|
|
130
159
|
|
|
@@ -142,154 +171,184 @@ function respondToDiscovery(requestId: string) {
|
|
|
142
171
|
- Both the SDK and wallets must parse incoming JSON strings
|
|
143
172
|
- Always use `jsonStringify` from `@aztec/foundation/json-rpc` for sending messages
|
|
144
173
|
- Always parse incoming messages with `JSON.parse` and the proper schemas
|
|
174
|
+
- The `publicKey` field is required for secure channel establishment
|
|
145
175
|
|
|
146
|
-
##
|
|
176
|
+
## Secure Channel
|
|
147
177
|
|
|
148
|
-
|
|
178
|
+
After discovery, the dApp establishes a secure encrypted channel with your wallet using ECDH key exchange and AES-256-GCM encryption. This ensures all wallet method calls and responses are encrypted end-to-end.
|
|
149
179
|
|
|
150
|
-
|
|
180
|
+
### Security Model
|
|
151
181
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
args: unknown[], // Method arguments
|
|
157
|
-
chainInfo: {
|
|
158
|
-
chainId: Fr, // Same chain that was used in discovery
|
|
159
|
-
version: Fr
|
|
160
|
-
},
|
|
161
|
-
appId: string, // Application identifier
|
|
162
|
-
walletId: string // Your wallet's ID (from discovery response)
|
|
163
|
-
}
|
|
164
|
-
```
|
|
182
|
+
- **ECDH Key Exchange**: Uses P-256 (secp256r1) elliptic curve for key agreement
|
|
183
|
+
- **AES-256-GCM Encryption**: All messages after channel establishment are encrypted
|
|
184
|
+
- **Per-Session Keys**: Each connection derives a unique shared secret
|
|
185
|
+
- **MessageChannel (Extension wallets)**: Uses a private MessagePort for communication, not visible to other page scripts
|
|
165
186
|
|
|
166
|
-
|
|
187
|
+
### 1. Handle Connection Requests
|
|
167
188
|
|
|
168
|
-
|
|
169
|
-
- `type: 'getChainInfo'` - Get chain information
|
|
170
|
-
- `type: 'sendTx'` - Send a transaction
|
|
171
|
-
- `type: 'registerContract'` - Register a contract instance
|
|
172
|
-
|
|
173
|
-
### Wallet Method Response
|
|
174
|
-
|
|
175
|
-
Your wallet must respond with:
|
|
189
|
+
When a dApp connects, it sends a `ConnectRequest` containing its ECDH public key:
|
|
176
190
|
|
|
177
191
|
```typescript
|
|
178
|
-
{
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
192
|
+
interface ConnectRequest {
|
|
193
|
+
type: 'aztec-wallet-connect';
|
|
194
|
+
walletId: string; // Your wallet's ID
|
|
195
|
+
appId: string; // Application identifier
|
|
196
|
+
publicKey: ExportedPublicKey; // dApp's ECDH public key
|
|
183
197
|
}
|
|
184
198
|
```
|
|
185
199
|
|
|
186
|
-
## Handling Wallet Methods
|
|
187
|
-
|
|
188
|
-
### 1. Set Up Message Listener
|
|
189
|
-
|
|
190
200
|
**Extension wallet example:**
|
|
191
201
|
|
|
192
202
|
```typescript
|
|
193
|
-
|
|
194
|
-
if (event.source !== window) {
|
|
195
|
-
return;
|
|
196
|
-
}
|
|
203
|
+
import { decrypt, deriveSharedKey, encrypt, importPublicKey } from '@aztec/wallet-sdk/crypto';
|
|
197
204
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
data = JSON.parse(event.data);
|
|
201
|
-
} catch {
|
|
202
|
-
return; // Not a valid JSON message
|
|
203
|
-
}
|
|
205
|
+
// Store connections by appId
|
|
206
|
+
const connections = new Map<string, { sharedKey: CryptoKey }>();
|
|
204
207
|
|
|
205
|
-
|
|
206
|
-
if (
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
}
|
|
208
|
+
window.addEventListener('message', async event => {
|
|
209
|
+
if (event.source !== window) return;
|
|
210
|
+
|
|
211
|
+
const data = JSON.parse(event.data);
|
|
210
212
|
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
handleWalletMethod(data);
|
|
213
|
+
if (data.type === 'aztec-wallet-connect') {
|
|
214
|
+
await handleConnect(data, event.ports[0]);
|
|
214
215
|
}
|
|
215
216
|
});
|
|
216
217
|
|
|
217
|
-
|
|
218
|
-
//
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
//
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
//
|
|
225
|
-
|
|
218
|
+
async function handleConnect(request: ConnectRequest, port: MessagePort) {
|
|
219
|
+
// Import dApp's public key
|
|
220
|
+
const dappPublicKey = await importPublicKey(request.publicKey);
|
|
221
|
+
|
|
222
|
+
// Derive shared secret using our private key and dApp's public key
|
|
223
|
+
const sharedKey = await deriveSharedKey(walletKeyPair.privateKey, dappPublicKey);
|
|
224
|
+
|
|
225
|
+
// Store the connection
|
|
226
|
+
connections.set(request.appId, { sharedKey });
|
|
227
|
+
|
|
228
|
+
// Set up encrypted message handler on the MessagePort
|
|
229
|
+
port.onmessage = async event => {
|
|
230
|
+
await handleEncryptedMessage(request.appId, event.data);
|
|
231
|
+
};
|
|
232
|
+
|
|
233
|
+
port.start();
|
|
234
|
+
}
|
|
226
235
|
```
|
|
227
236
|
|
|
228
|
-
### 2.
|
|
237
|
+
### 2. Handle Encrypted Messages
|
|
238
|
+
|
|
239
|
+
All wallet method calls arrive as encrypted payloads:
|
|
229
240
|
|
|
230
241
|
```typescript
|
|
231
|
-
|
|
242
|
+
interface EncryptedPayload {
|
|
243
|
+
iv: string; // Base64-encoded initialization vector
|
|
244
|
+
ciphertext: string; // Base64-encoded encrypted data
|
|
245
|
+
}
|
|
246
|
+
```
|
|
232
247
|
|
|
233
|
-
|
|
234
|
-
const { type, messageId, args, chainInfo, appId, walletId } = message;
|
|
248
|
+
Decrypt incoming messages and encrypt responses:
|
|
235
249
|
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
250
|
+
```typescript
|
|
251
|
+
async function handleEncryptedMessage(appId: string, encrypted: EncryptedPayload) {
|
|
252
|
+
const connection = connections.get(appId);
|
|
253
|
+
if (!connection) {
|
|
254
|
+
console.error('Unknown connection');
|
|
255
|
+
return;
|
|
256
|
+
}
|
|
239
257
|
|
|
240
|
-
|
|
241
|
-
|
|
258
|
+
try {
|
|
259
|
+
// Decrypt the incoming message
|
|
260
|
+
const message = await decrypt<WalletMessage>(connection.sharedKey, encrypted);
|
|
242
261
|
|
|
243
|
-
|
|
244
|
-
if (typeof wallet[type] !== 'function') {
|
|
245
|
-
throw new Error(`Unknown wallet method: ${type}`);
|
|
246
|
-
}
|
|
262
|
+
const { type, messageId, args, chainInfo, walletId } = message;
|
|
247
263
|
|
|
248
|
-
//
|
|
264
|
+
// Process the wallet method call
|
|
265
|
+
const wallet = await getWalletForChain(chainInfo);
|
|
249
266
|
const result = await wallet[type](...args);
|
|
250
267
|
|
|
251
|
-
//
|
|
252
|
-
|
|
268
|
+
// Create response
|
|
269
|
+
const response: WalletResponse = {
|
|
270
|
+
messageId,
|
|
271
|
+
result,
|
|
272
|
+
walletId,
|
|
273
|
+
};
|
|
274
|
+
|
|
275
|
+
// Encrypt and send the response
|
|
276
|
+
const encryptedResponse = await encrypt(connection.sharedKey, response);
|
|
277
|
+
sendEncryptedResponse(appId, encryptedResponse);
|
|
253
278
|
} catch (error) {
|
|
254
|
-
// Send error response
|
|
255
|
-
|
|
279
|
+
// Send encrypted error response
|
|
280
|
+
const errorResponse: WalletResponse = {
|
|
281
|
+
messageId: message?.messageId ?? '',
|
|
282
|
+
error: { message: error.message },
|
|
283
|
+
walletId: message?.walletId ?? '',
|
|
284
|
+
};
|
|
285
|
+
|
|
286
|
+
const encryptedError = await encrypt(connection.sharedKey, errorResponse);
|
|
287
|
+
sendEncryptedResponse(appId, encryptedError);
|
|
256
288
|
}
|
|
257
289
|
}
|
|
258
290
|
```
|
|
259
291
|
|
|
260
|
-
### 3.
|
|
292
|
+
### 3. Extension Wallet Architecture
|
|
261
293
|
|
|
262
|
-
|
|
294
|
+
For browser extension wallets, the recommended architecture separates concerns:
|
|
263
295
|
|
|
264
|
-
```
|
|
265
|
-
|
|
296
|
+
```
|
|
297
|
+
┌─────────────┐ window.postMessage ┌─────────────────┐ browser.runtime ┌──────────────────┐
|
|
298
|
+
│ dApp │◄────────────────────────►│ Content Script │◄────────────────────►│ Background Script│
|
|
299
|
+
│ (web page) │ (discovery only) │ (message relay)│ (encrypted msgs) │ (decrypt+process)│
|
|
300
|
+
└─────────────┘ └─────────────────┘ └──────────────────┘
|
|
301
|
+
│ │
|
|
302
|
+
│ MessagePort (private channel) │
|
|
303
|
+
└────────────────────────────────────────────┘
|
|
304
|
+
(encrypted wallet method calls)
|
|
305
|
+
```
|
|
266
306
|
|
|
267
|
-
|
|
268
|
-
const response = {
|
|
269
|
-
messageId,
|
|
270
|
-
result,
|
|
271
|
-
walletId,
|
|
272
|
-
};
|
|
307
|
+
**Security benefits:**
|
|
273
308
|
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
309
|
+
- Content script never has access to private keys or shared secrets
|
|
310
|
+
- All cryptographic operations happen in the background script (service worker)
|
|
311
|
+
- MessagePort provides a private channel not visible to other page scripts
|
|
312
|
+
- Only the initial connection handshake uses `window.postMessage`
|
|
277
313
|
|
|
278
|
-
|
|
279
|
-
const response = {
|
|
280
|
-
messageId,
|
|
281
|
-
error: {
|
|
282
|
-
message: error.message,
|
|
283
|
-
stack: error.stack,
|
|
284
|
-
},
|
|
285
|
-
walletId,
|
|
286
|
-
};
|
|
314
|
+
## Message Format
|
|
287
315
|
|
|
288
|
-
|
|
316
|
+
### Wallet Method Request
|
|
317
|
+
|
|
318
|
+
After discovery, dApps will call wallet methods. These arrive as:
|
|
319
|
+
|
|
320
|
+
```typescript
|
|
321
|
+
{
|
|
322
|
+
type: string, // Wallet method name from the Wallet interface
|
|
323
|
+
messageId: string, // UUID for tracking this request
|
|
324
|
+
args: unknown[], // Method arguments
|
|
325
|
+
chainInfo: {
|
|
326
|
+
chainId: Fr, // Same chain that was used in discovery
|
|
327
|
+
version: Fr
|
|
328
|
+
},
|
|
329
|
+
appId: string, // Application identifier
|
|
330
|
+
walletId: string // Your wallet's ID (from discovery response)
|
|
289
331
|
}
|
|
332
|
+
```
|
|
290
333
|
|
|
291
|
-
|
|
292
|
-
|
|
334
|
+
Example method calls:
|
|
335
|
+
|
|
336
|
+
- `type: 'getAccounts'` - Get list of accounts
|
|
337
|
+
- `type: 'getChainInfo'` - Get chain information
|
|
338
|
+
- `type: 'sendTx'` - Send a transaction
|
|
339
|
+
- `type: 'registerContract'` - Register a contract instance
|
|
340
|
+
|
|
341
|
+
### Wallet Method Response
|
|
342
|
+
|
|
343
|
+
Your wallet must respond with:
|
|
344
|
+
|
|
345
|
+
```typescript
|
|
346
|
+
{
|
|
347
|
+
messageId: string, // MUST match the request's messageId
|
|
348
|
+
result?: unknown, // Method result (if successful)
|
|
349
|
+
error?: unknown, // Error (if failed)
|
|
350
|
+
walletId: string // Your wallet's ID
|
|
351
|
+
}
|
|
293
352
|
```
|
|
294
353
|
|
|
295
354
|
## Parsing Messages
|
|
@@ -331,37 +390,12 @@ Always send error responses with this structure:
|
|
|
331
390
|
|
|
332
391
|
### Common Error Scenarios
|
|
333
392
|
|
|
334
|
-
|
|
335
|
-
import { ChainInfoSchema } from '@aztec/wallet-sdk/manager';
|
|
336
|
-
|
|
337
|
-
async function handleWalletMethod(message: any) {
|
|
338
|
-
const { type, messageId, args, chainInfo, walletId } = message;
|
|
339
|
-
|
|
340
|
-
try {
|
|
341
|
-
// 1. Parse and validate chain info
|
|
342
|
-
const parsedChainInfo = ChainInfoSchema.parse(chainInfo);
|
|
393
|
+
Common errors to handle within the encrypted message handler:
|
|
343
394
|
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
// 3. Get wallet instance
|
|
350
|
-
const wallet = await getWalletForChain(parsedChainInfo);
|
|
351
|
-
|
|
352
|
-
// 4. Validate method exists
|
|
353
|
-
if (typeof wallet[type] !== 'function') {
|
|
354
|
-
throw new Error(`Unknown wallet method: ${type}`);
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
// 5. Execute method
|
|
358
|
-
const result = await wallet[type](...args);
|
|
359
|
-
sendResponse(messageId, walletId, result);
|
|
360
|
-
} catch (error) {
|
|
361
|
-
sendError(messageId, walletId, error);
|
|
362
|
-
}
|
|
363
|
-
}
|
|
364
|
-
```
|
|
395
|
+
- **Network not supported**: Chain info doesn't match wallet's supported networks
|
|
396
|
+
- **Unknown method**: The requested wallet method doesn't exist
|
|
397
|
+
- **Invalid arguments**: Method arguments fail validation
|
|
398
|
+
- **User rejection**: User declined the transaction or action
|
|
365
399
|
|
|
366
400
|
### User Rejection Handling
|
|
367
401
|
|
package/dest/crypto.d.ts
ADDED
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Exported public key in JWK format for transmission over untrusted channels.
|
|
3
|
+
*
|
|
4
|
+
* Contains only the public components of an ECDH P-256 key, safe to share.
|
|
5
|
+
*/
|
|
6
|
+
export interface ExportedPublicKey {
|
|
7
|
+
/** Key type - always "EC" for elliptic curve */
|
|
8
|
+
kty: string;
|
|
9
|
+
/** Curve name - always "P-256" */
|
|
10
|
+
crv: string;
|
|
11
|
+
/** X coordinate (base64url encoded) */
|
|
12
|
+
x: string;
|
|
13
|
+
/** Y coordinate (base64url encoded) */
|
|
14
|
+
y: string;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Encrypted message payload containing ciphertext and initialization vector.
|
|
18
|
+
*
|
|
19
|
+
* Both fields are base64-encoded for safe transmission as JSON.
|
|
20
|
+
*/
|
|
21
|
+
export interface EncryptedPayload {
|
|
22
|
+
/** Initialization vector (base64 encoded, 12 bytes) */
|
|
23
|
+
iv: string;
|
|
24
|
+
/** Ciphertext (base64 encoded) */
|
|
25
|
+
ciphertext: string;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* ECDH key pair for secure communication.
|
|
29
|
+
*
|
|
30
|
+
* The private key should never be exported or transmitted.
|
|
31
|
+
* The public key can be exported via {@link exportPublicKey} for exchange.
|
|
32
|
+
*/
|
|
33
|
+
export interface SecureKeyPair {
|
|
34
|
+
/** Public key - safe to share */
|
|
35
|
+
publicKey: CryptoKey;
|
|
36
|
+
/** Private key - keep secret, used for key derivation */
|
|
37
|
+
privateKey: CryptoKey;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Generates an ECDH P-256 key pair for key exchange.
|
|
41
|
+
*
|
|
42
|
+
* The generated key pair can be used to derive a shared secret with another
|
|
43
|
+
* party's public key using {@link deriveSharedKey}.
|
|
44
|
+
*
|
|
45
|
+
* @returns A new ECDH key pair
|
|
46
|
+
*
|
|
47
|
+
* @example
|
|
48
|
+
* ```typescript
|
|
49
|
+
* const keyPair = await generateKeyPair();
|
|
50
|
+
* const publicKey = await exportPublicKey(keyPair.publicKey);
|
|
51
|
+
* // Send publicKey to the other party
|
|
52
|
+
* ```
|
|
53
|
+
*/
|
|
54
|
+
export declare function generateKeyPair(): Promise<SecureKeyPair>;
|
|
55
|
+
/**
|
|
56
|
+
* Exports a public key to JWK format for transmission.
|
|
57
|
+
*
|
|
58
|
+
* The exported key contains only public components and is safe to transmit
|
|
59
|
+
* over untrusted channels.
|
|
60
|
+
*
|
|
61
|
+
* @param publicKey - The CryptoKey public key to export
|
|
62
|
+
* @returns The public key in JWK format
|
|
63
|
+
*
|
|
64
|
+
* @example
|
|
65
|
+
* ```typescript
|
|
66
|
+
* const keyPair = await generateKeyPair();
|
|
67
|
+
* const exported = await exportPublicKey(keyPair.publicKey);
|
|
68
|
+
* // exported can be JSON serialized and sent to another party
|
|
69
|
+
* ```
|
|
70
|
+
*/
|
|
71
|
+
export declare function exportPublicKey(publicKey: CryptoKey): Promise<ExportedPublicKey>;
|
|
72
|
+
/**
|
|
73
|
+
* Imports a public key from JWK format.
|
|
74
|
+
*
|
|
75
|
+
* Used to import the other party's public key for deriving a shared secret.
|
|
76
|
+
*
|
|
77
|
+
* @param exported - The public key in JWK format
|
|
78
|
+
* @returns A CryptoKey that can be used with {@link deriveSharedKey}
|
|
79
|
+
*
|
|
80
|
+
* @example
|
|
81
|
+
* ```typescript
|
|
82
|
+
* // Receive exported public key from other party
|
|
83
|
+
* const theirPublicKey = await importPublicKey(receivedPublicKey);
|
|
84
|
+
* const sharedKey = await deriveSharedKey(myPrivateKey, theirPublicKey);
|
|
85
|
+
* ```
|
|
86
|
+
*/
|
|
87
|
+
export declare function importPublicKey(exported: ExportedPublicKey): Promise<CryptoKey>;
|
|
88
|
+
/**
|
|
89
|
+
* Derives a shared AES-256-GCM key from ECDH key exchange.
|
|
90
|
+
*
|
|
91
|
+
* Both parties will derive the same shared key when using their own private key
|
|
92
|
+
* and the other party's public key. This is the core of ECDH key agreement.
|
|
93
|
+
*
|
|
94
|
+
* @param privateKey - Your ECDH private key
|
|
95
|
+
* @param publicKey - The other party's ECDH public key
|
|
96
|
+
* @returns An AES-256-GCM key for encryption/decryption
|
|
97
|
+
*
|
|
98
|
+
* @example
|
|
99
|
+
* ```typescript
|
|
100
|
+
* // Both parties derive the same key
|
|
101
|
+
* const sharedKeyA = await deriveSharedKey(privateKeyA, publicKeyB);
|
|
102
|
+
* const sharedKeyB = await deriveSharedKey(privateKeyB, publicKeyA);
|
|
103
|
+
* // sharedKeyA and sharedKeyB are equivalent
|
|
104
|
+
* ```
|
|
105
|
+
*/
|
|
106
|
+
export declare function deriveSharedKey(privateKey: CryptoKey, publicKey: CryptoKey): Promise<CryptoKey>;
|
|
107
|
+
/**
|
|
108
|
+
* Encrypts data using AES-256-GCM.
|
|
109
|
+
*
|
|
110
|
+
* The data is JSON serialized before encryption. A random 12-byte IV is
|
|
111
|
+
* generated for each encryption operation.
|
|
112
|
+
*
|
|
113
|
+
* AES-GCM provides both confidentiality and authenticity - any tampering
|
|
114
|
+
* with the ciphertext will cause decryption to fail.
|
|
115
|
+
*
|
|
116
|
+
* @param key - The AES-GCM key (from {@link deriveSharedKey})
|
|
117
|
+
* @param data - The data to encrypt (will be JSON serialized)
|
|
118
|
+
* @returns The encrypted payload with IV and ciphertext
|
|
119
|
+
*
|
|
120
|
+
* @example
|
|
121
|
+
* ```typescript
|
|
122
|
+
* const encrypted = await encrypt(sharedKey, { action: 'transfer', amount: 100 });
|
|
123
|
+
* // encrypted.iv and encrypted.ciphertext are base64 strings
|
|
124
|
+
* ```
|
|
125
|
+
*/
|
|
126
|
+
export declare function encrypt(key: CryptoKey, data: unknown): Promise<EncryptedPayload>;
|
|
127
|
+
/**
|
|
128
|
+
* Decrypts data using AES-256-GCM.
|
|
129
|
+
*
|
|
130
|
+
* The decrypted data is JSON parsed before returning.
|
|
131
|
+
*
|
|
132
|
+
* @typeParam T - The expected type of the decrypted data
|
|
133
|
+
* @param key - The AES-GCM key (from {@link deriveSharedKey})
|
|
134
|
+
* @param payload - The encrypted payload from {@link encrypt}
|
|
135
|
+
* @returns The decrypted and parsed data
|
|
136
|
+
*
|
|
137
|
+
* @throws Error if decryption fails (wrong key or tampered ciphertext)
|
|
138
|
+
*
|
|
139
|
+
* @example
|
|
140
|
+
* ```typescript
|
|
141
|
+
* const decrypted = await decrypt<{ action: string; amount: number }>(sharedKey, encrypted);
|
|
142
|
+
* console.log(decrypted.action); // 'transfer'
|
|
143
|
+
* ```
|
|
144
|
+
*/
|
|
145
|
+
export declare function decrypt<T = unknown>(key: CryptoKey, payload: EncryptedPayload): Promise<T>;
|
|
146
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3J5cHRvLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvY3J5cHRvLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQW1DQTs7OztHQUlHO0FBQ0gsTUFBTSxXQUFXLGlCQUFpQjtJQUNoQyxnREFBZ0Q7SUFDaEQsR0FBRyxFQUFFLE1BQU0sQ0FBQztJQUNaLGtDQUFrQztJQUNsQyxHQUFHLEVBQUUsTUFBTSxDQUFDO0lBQ1osdUNBQXVDO0lBQ3ZDLENBQUMsRUFBRSxNQUFNLENBQUM7SUFDVix1Q0FBdUM7SUFDdkMsQ0FBQyxFQUFFLE1BQU0sQ0FBQztDQUNYO0FBRUQ7Ozs7R0FJRztBQUNILE1BQU0sV0FBVyxnQkFBZ0I7SUFDL0IsdURBQXVEO0lBQ3ZELEVBQUUsRUFBRSxNQUFNLENBQUM7SUFDWCxrQ0FBa0M7SUFDbEMsVUFBVSxFQUFFLE1BQU0sQ0FBQztDQUNwQjtBQUVEOzs7OztHQUtHO0FBQ0gsTUFBTSxXQUFXLGFBQWE7SUFDNUIsaUNBQWlDO0lBQ2pDLFNBQVMsRUFBRSxTQUFTLENBQUM7SUFDckIseURBQXlEO0lBQ3pELFVBQVUsRUFBRSxTQUFTLENBQUM7Q0FDdkI7QUFFRDs7Ozs7Ozs7Ozs7Ozs7R0FjRztBQUNILHdCQUFzQixlQUFlLElBQUksT0FBTyxDQUFDLGFBQWEsQ0FBQyxDQWE5RDtBQUVEOzs7Ozs7Ozs7Ozs7Ozs7R0FlRztBQUNILHdCQUFzQixlQUFlLENBQUMsU0FBUyxFQUFFLFNBQVMsR0FBRyxPQUFPLENBQUMsaUJBQWlCLENBQUMsQ0FRdEY7QUFFRDs7Ozs7Ozs7Ozs7Ozs7R0FjRztBQUNILHdCQUFnQixlQUFlLENBQUMsUUFBUSxFQUFFLGlCQUFpQixHQUFHLE9BQU8sQ0FBQyxTQUFTLENBQUMsQ0FnQi9FO0FBRUQ7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBaUJHO0FBQ0gsd0JBQWdCLGVBQWUsQ0FBQyxVQUFVLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBRSxTQUFTLEdBQUcsT0FBTyxDQUFDLFNBQVMsQ0FBQyxDQWMvRjtBQUVEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FrQkc7QUFDSCx3QkFBc0IsT0FBTyxDQUFDLEdBQUcsRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFFLE9BQU8sR0FBRyxPQUFPLENBQUMsZ0JBQWdCLENBQUMsQ0FVdEY7QUFFRDs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FpQkc7QUFDSCx3QkFBc0IsT0FBTyxDQUFDLENBQUMsR0FBRyxPQUFPLEVBQUUsR0FBRyxFQUFFLFNBQVMsRUFBRSxPQUFPLEVBQUUsZ0JBQWdCLEdBQUcsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQVFoRyJ9
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crypto.d.ts","sourceRoot":"","sources":["../src/crypto.ts"],"names":[],"mappings":"AAmCA;;;;GAIG;AACH,MAAM,WAAW,iBAAiB;IAChC,gDAAgD;IAChD,GAAG,EAAE,MAAM,CAAC;IACZ,kCAAkC;IAClC,GAAG,EAAE,MAAM,CAAC;IACZ,uCAAuC;IACvC,CAAC,EAAE,MAAM,CAAC;IACV,uCAAuC;IACvC,CAAC,EAAE,MAAM,CAAC;CACX;AAED;;;;GAIG;AACH,MAAM,WAAW,gBAAgB;IAC/B,uDAAuD;IACvD,EAAE,EAAE,MAAM,CAAC;IACX,kCAAkC;IAClC,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;;;GAKG;AACH,MAAM,WAAW,aAAa;IAC5B,iCAAiC;IACjC,SAAS,EAAE,SAAS,CAAC;IACrB,yDAAyD;IACzD,UAAU,EAAE,SAAS,CAAC;CACvB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,eAAe,IAAI,OAAO,CAAC,aAAa,CAAC,CAa9D;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,eAAe,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAQtF;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,iBAAiB,GAAG,OAAO,CAAC,SAAS,CAAC,CAgB/E;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,eAAe,CAAC,UAAU,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC,CAc/F;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAsB,OAAO,CAAC,GAAG,EAAE,SAAS,EAAE,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAUtF;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,OAAO,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,EAAE,SAAS,EAAE,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,CAAC,CAAC,CAQhG"}
|