@aztec/wallet-sdk 4.0.0-nightly.20260113 → 4.0.0-nightly.20260115
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 +211 -271
- package/dest/base-wallet/base_wallet.d.ts +14 -4
- package/dest/base-wallet/base_wallet.d.ts.map +1 -1
- package/dest/base-wallet/base_wallet.js +29 -10
- package/dest/crypto.d.ts +38 -1
- package/dest/crypto.d.ts.map +1 -1
- package/dest/crypto.js +85 -1
- package/dest/manager/wallet_manager.d.ts +1 -1
- package/dest/manager/wallet_manager.d.ts.map +1 -1
- package/dest/manager/wallet_manager.js +9 -13
- package/dest/providers/extension/extension_provider.d.ts +52 -6
- package/dest/providers/extension/extension_provider.d.ts.map +1 -1
- package/dest/providers/extension/extension_provider.js +78 -11
- package/dest/providers/extension/extension_wallet.d.ts +30 -30
- package/dest/providers/extension/extension_wallet.d.ts.map +1 -1
- package/dest/providers/extension/extension_wallet.js +40 -73
- package/dest/providers/extension/index.d.ts +3 -3
- package/dest/providers/extension/index.d.ts.map +1 -1
- package/dest/types.d.ts +9 -14
- package/dest/types.d.ts.map +1 -1
- package/dest/types.js +1 -1
- package/package.json +9 -9
- package/src/base-wallet/base_wallet.ts +37 -13
- package/src/crypto.ts +93 -1
- package/src/manager/wallet_manager.ts +9 -13
- package/src/providers/extension/extension_provider.ts +109 -14
- package/src/providers/extension/extension_wallet.ts +45 -91
- package/src/providers/extension/index.ts +2 -9
- package/src/types.ts +8 -14
|
@@ -5,26 +5,28 @@ import type { WalletInfo } from '../../types.js';
|
|
|
5
5
|
* A wallet implementation that communicates with browser extension wallets
|
|
6
6
|
* using a secure encrypted MessageChannel.
|
|
7
7
|
*
|
|
8
|
-
* This class
|
|
9
|
-
* using the following security mechanisms:
|
|
8
|
+
* This class uses a pre-established secure channel from the discovery phase:
|
|
10
9
|
*
|
|
11
|
-
* 1. **MessageChannel**:
|
|
12
|
-
* visible to other scripts on the page (unlike window.postMessage).
|
|
10
|
+
* 1. **MessageChannel**: A private communication channel created during discovery,
|
|
11
|
+
* not visible to other scripts on the page (unlike window.postMessage).
|
|
13
12
|
*
|
|
14
|
-
* 2. **ECDH Key Exchange**:
|
|
15
|
-
*
|
|
13
|
+
* 2. **ECDH Key Exchange**: The shared secret was derived during discovery using
|
|
14
|
+
* Elliptic Curve Diffie-Hellman key exchange.
|
|
16
15
|
*
|
|
17
|
-
* 3. **AES-GCM Encryption**: All messages
|
|
18
|
-
*
|
|
16
|
+
* 3. **AES-GCM Encryption**: All messages are encrypted using AES-256-GCM,
|
|
17
|
+
* providing both confidentiality and authenticity.
|
|
19
18
|
*
|
|
20
19
|
* @example
|
|
21
20
|
* ```typescript
|
|
22
|
-
* // Discovery returns
|
|
21
|
+
* // Discovery returns wallets with secure channel components
|
|
23
22
|
* const wallets = await ExtensionProvider.discoverExtensions(chainInfo);
|
|
24
|
-
* const
|
|
23
|
+
* const { info, port, sharedKey } = wallets[0];
|
|
25
24
|
*
|
|
26
|
-
* //
|
|
27
|
-
*
|
|
25
|
+
* // User can verify emoji if desired
|
|
26
|
+
* console.log('Verify:', hashToEmoji(info.verificationHash!));
|
|
27
|
+
*
|
|
28
|
+
* // Create wallet using the discovered components
|
|
29
|
+
* const wallet = await ExtensionWallet.create(info, chainInfo, port, sharedKey, 'my-dapp');
|
|
28
30
|
*
|
|
29
31
|
* // All subsequent calls are encrypted
|
|
30
32
|
* const accounts = await wallet.getAccounts();
|
|
@@ -34,47 +36,44 @@ export declare class ExtensionWallet {
|
|
|
34
36
|
private chainInfo;
|
|
35
37
|
private appId;
|
|
36
38
|
private extensionId;
|
|
37
|
-
/** Map of pending requests awaiting responses, keyed by message ID */
|
|
38
|
-
private inFlight;
|
|
39
|
-
/** The MessagePort for private communication with the extension */
|
|
40
39
|
private port;
|
|
41
|
-
/** The derived AES-GCM key for encrypting/decrypting messages */
|
|
42
40
|
private sharedKey;
|
|
41
|
+
/** Map of pending requests awaiting responses, keyed by message ID */
|
|
42
|
+
private inFlight;
|
|
43
43
|
/**
|
|
44
44
|
* Private constructor - use {@link ExtensionWallet.create} to instantiate.
|
|
45
45
|
* @param chainInfo - The chain information (chainId and version)
|
|
46
46
|
* @param appId - Application identifier for the requesting dApp
|
|
47
47
|
* @param extensionId - The unique identifier of the target wallet extension
|
|
48
|
+
* @param port - The MessagePort for private communication with the wallet
|
|
49
|
+
* @param sharedKey - The derived AES-256-GCM shared key for encryption
|
|
48
50
|
*/
|
|
49
51
|
private constructor();
|
|
50
52
|
/**
|
|
51
53
|
* Creates an ExtensionWallet instance that proxies wallet calls to a browser extension
|
|
52
54
|
* over a secure encrypted MessageChannel.
|
|
53
55
|
*
|
|
54
|
-
* The
|
|
55
|
-
* 1. Generates an ECDH key pair for this session
|
|
56
|
-
* 2. Derives a shared AES-256 key using the wallet's public key
|
|
57
|
-
* 3. Creates a MessageChannel and transfers one port to the extension
|
|
58
|
-
* 4. Returns a Proxy that encrypts all wallet method calls
|
|
59
|
-
*
|
|
60
|
-
* @param walletInfo - The discovered wallet information, including the wallet's ECDH public key
|
|
56
|
+
* @param walletInfo - The wallet info from ExtensionProvider.discoverExtensions()
|
|
61
57
|
* @param chainInfo - The chain information (chainId and version) for request context
|
|
58
|
+
* @param port - The MessagePort for private communication with the wallet
|
|
59
|
+
* @param sharedKey - The derived AES-256-GCM shared key for encryption
|
|
62
60
|
* @param appId - Application identifier used to identify the requesting dApp to the wallet
|
|
63
61
|
* @returns A Promise resolving to a Wallet implementation that encrypts all communication
|
|
64
62
|
*
|
|
65
|
-
* @throws Error if the secure channel cannot be established
|
|
66
|
-
*
|
|
67
63
|
* @example
|
|
68
64
|
* ```typescript
|
|
65
|
+
* const wallets = await ExtensionProvider.discoverExtensions(chainInfo);
|
|
66
|
+
* const { info, port, sharedKey } = wallets[0];
|
|
69
67
|
* const wallet = await ExtensionWallet.create(
|
|
70
|
-
*
|
|
68
|
+
* info,
|
|
71
69
|
* { chainId: Fr(31337), version: Fr(0) },
|
|
70
|
+
* port,
|
|
71
|
+
* sharedKey,
|
|
72
72
|
* 'my-defi-app'
|
|
73
73
|
* );
|
|
74
74
|
* ```
|
|
75
75
|
*/
|
|
76
|
-
static create(walletInfo: WalletInfo, chainInfo: ChainInfo, appId: string):
|
|
77
|
-
private establishSecureChannel;
|
|
76
|
+
static create(walletInfo: WalletInfo, chainInfo: ChainInfo, port: MessagePort, sharedKey: CryptoKey, appId: string): Wallet;
|
|
78
77
|
private handleEncryptedResponse;
|
|
79
78
|
private postMessage;
|
|
80
79
|
/**
|
|
@@ -85,11 +84,12 @@ export declare class ExtensionWallet {
|
|
|
85
84
|
*
|
|
86
85
|
* @example
|
|
87
86
|
* ```typescript
|
|
88
|
-
* const
|
|
87
|
+
* const { info, port, sharedKey } = wallets[0];
|
|
88
|
+
* const wallet = await ExtensionWallet.create(info, chainInfo, port, sharedKey, 'my-app');
|
|
89
89
|
* // ... use wallet ...
|
|
90
90
|
* wallet.close(); // Clean up when done
|
|
91
91
|
* ```
|
|
92
92
|
*/
|
|
93
93
|
close(): void;
|
|
94
94
|
}
|
|
95
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
95
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXh0ZW5zaW9uX3dhbGxldC5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL3Byb3ZpZGVycy9leHRlbnNpb24vZXh0ZW5zaW9uX3dhbGxldC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssRUFBRSxTQUFTLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUN6RCxPQUFPLEVBQUUsS0FBSyxNQUFNLEVBQWdCLE1BQU0sd0JBQXdCLENBQUM7QUFPbkUsT0FBTyxLQUFLLEVBQUUsVUFBVSxFQUFpQyxNQUFNLGdCQUFnQixDQUFDO0FBYWhGOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0E4Qkc7QUFDSCxxQkFBYSxlQUFlO0lBYXhCLE9BQU8sQ0FBQyxTQUFTO0lBQ2pCLE9BQU8sQ0FBQyxLQUFLO0lBQ2IsT0FBTyxDQUFDLFdBQVc7SUFDbkIsT0FBTyxDQUFDLElBQUk7SUFDWixPQUFPLENBQUMsU0FBUztJQWhCbkIsc0VBQXNFO0lBQ3RFLE9BQU8sQ0FBQyxRQUFRLENBQW9EO0lBRXBFOzs7Ozs7O09BT0c7SUFDSCxPQUFPLGVBTUg7SUFFSjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7T0F1Qkc7SUFDSCxNQUFNLENBQUMsTUFBTSxDQUNYLFVBQVUsRUFBRSxVQUFVLEVBQ3RCLFNBQVMsRUFBRSxTQUFTLEVBQ3BCLElBQUksRUFBRSxXQUFXLEVBQ2pCLFNBQVMsRUFBRSxTQUFTLEVBQ3BCLEtBQUssRUFBRSxNQUFNLEdBQ1osTUFBTSxDQTBCUjtZQVVhLHVCQUF1QjtZQThDdkIsV0FBVztJQXdCekI7Ozs7Ozs7Ozs7Ozs7T0FhRztJQUNILEtBQUssSUFBSSxJQUFJLENBS1o7Q0FDRiJ9
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extension_wallet.d.ts","sourceRoot":"","sources":["../../../src/providers/extension/extension_wallet.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,EAAE,KAAK,MAAM,EAAgB,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"extension_wallet.d.ts","sourceRoot":"","sources":["../../../src/providers/extension/extension_wallet.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,EAAE,KAAK,MAAM,EAAgB,MAAM,wBAAwB,CAAC;AAOnE,OAAO,KAAK,EAAE,UAAU,EAAiC,MAAM,gBAAgB,CAAC;AAahF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,qBAAa,eAAe;IAaxB,OAAO,CAAC,SAAS;IACjB,OAAO,CAAC,KAAK;IACb,OAAO,CAAC,WAAW;IACnB,OAAO,CAAC,IAAI;IACZ,OAAO,CAAC,SAAS;IAhBnB,sEAAsE;IACtE,OAAO,CAAC,QAAQ,CAAoD;IAEpE;;;;;;;OAOG;IACH,OAAO,eAMH;IAEJ;;;;;;;;;;;;;;;;;;;;;;;OAuBG;IACH,MAAM,CAAC,MAAM,CACX,UAAU,EAAE,UAAU,EACtB,SAAS,EAAE,SAAS,EACpB,IAAI,EAAE,WAAW,EACjB,SAAS,EAAE,SAAS,EACpB,KAAK,EAAE,MAAM,GACZ,MAAM,CA0BR;YAUa,uBAAuB;YA8CvB,WAAW;IAwBzB;;;;;;;;;;;;;OAaG;IACH,KAAK,IAAI,IAAI,CAKZ;CACF"}
|
|
@@ -2,31 +2,33 @@ import { WalletSchema } from '@aztec/aztec.js/wallet';
|
|
|
2
2
|
import { jsonStringify } from '@aztec/foundation/json-rpc';
|
|
3
3
|
import { promiseWithResolvers } from '@aztec/foundation/promise';
|
|
4
4
|
import { schemaHasMethod } from '@aztec/foundation/schemas';
|
|
5
|
-
import { decrypt,
|
|
5
|
+
import { decrypt, encrypt } from '../../crypto.js';
|
|
6
6
|
/**
|
|
7
7
|
* A wallet implementation that communicates with browser extension wallets
|
|
8
8
|
* using a secure encrypted MessageChannel.
|
|
9
9
|
*
|
|
10
|
-
* This class
|
|
11
|
-
* using the following security mechanisms:
|
|
10
|
+
* This class uses a pre-established secure channel from the discovery phase:
|
|
12
11
|
*
|
|
13
|
-
* 1. **MessageChannel**:
|
|
14
|
-
* visible to other scripts on the page (unlike window.postMessage).
|
|
12
|
+
* 1. **MessageChannel**: A private communication channel created during discovery,
|
|
13
|
+
* not visible to other scripts on the page (unlike window.postMessage).
|
|
15
14
|
*
|
|
16
|
-
* 2. **ECDH Key Exchange**:
|
|
17
|
-
*
|
|
15
|
+
* 2. **ECDH Key Exchange**: The shared secret was derived during discovery using
|
|
16
|
+
* Elliptic Curve Diffie-Hellman key exchange.
|
|
18
17
|
*
|
|
19
|
-
* 3. **AES-GCM Encryption**: All messages
|
|
20
|
-
*
|
|
18
|
+
* 3. **AES-GCM Encryption**: All messages are encrypted using AES-256-GCM,
|
|
19
|
+
* providing both confidentiality and authenticity.
|
|
21
20
|
*
|
|
22
21
|
* @example
|
|
23
22
|
* ```typescript
|
|
24
|
-
* // Discovery returns
|
|
23
|
+
* // Discovery returns wallets with secure channel components
|
|
25
24
|
* const wallets = await ExtensionProvider.discoverExtensions(chainInfo);
|
|
26
|
-
* const
|
|
25
|
+
* const { info, port, sharedKey } = wallets[0];
|
|
27
26
|
*
|
|
28
|
-
* //
|
|
29
|
-
*
|
|
27
|
+
* // User can verify emoji if desired
|
|
28
|
+
* console.log('Verify:', hashToEmoji(info.verificationHash!));
|
|
29
|
+
*
|
|
30
|
+
* // Create wallet using the discovered components
|
|
31
|
+
* const wallet = await ExtensionWallet.create(info, chainInfo, port, sharedKey, 'my-dapp');
|
|
30
32
|
*
|
|
31
33
|
* // All subsequent calls are encrypted
|
|
32
34
|
* const accounts = await wallet.getAccounts();
|
|
@@ -35,53 +37,54 @@ import { decrypt, deriveSharedKey, encrypt, exportPublicKey, generateKeyPair, im
|
|
|
35
37
|
chainInfo;
|
|
36
38
|
appId;
|
|
37
39
|
extensionId;
|
|
40
|
+
port;
|
|
41
|
+
sharedKey;
|
|
38
42
|
/** Map of pending requests awaiting responses, keyed by message ID */ inFlight;
|
|
39
|
-
/** The MessagePort for private communication with the extension */ port;
|
|
40
|
-
/** The derived AES-GCM key for encrypting/decrypting messages */ sharedKey;
|
|
41
43
|
/**
|
|
42
44
|
* Private constructor - use {@link ExtensionWallet.create} to instantiate.
|
|
43
45
|
* @param chainInfo - The chain information (chainId and version)
|
|
44
46
|
* @param appId - Application identifier for the requesting dApp
|
|
45
47
|
* @param extensionId - The unique identifier of the target wallet extension
|
|
46
|
-
|
|
48
|
+
* @param port - The MessagePort for private communication with the wallet
|
|
49
|
+
* @param sharedKey - The derived AES-256-GCM shared key for encryption
|
|
50
|
+
*/ constructor(chainInfo, appId, extensionId, port, sharedKey){
|
|
47
51
|
this.chainInfo = chainInfo;
|
|
48
52
|
this.appId = appId;
|
|
49
53
|
this.extensionId = extensionId;
|
|
54
|
+
this.port = port;
|
|
55
|
+
this.sharedKey = sharedKey;
|
|
50
56
|
this.inFlight = new Map();
|
|
51
|
-
this.port = null;
|
|
52
|
-
this.sharedKey = null;
|
|
53
57
|
}
|
|
54
58
|
/**
|
|
55
59
|
* Creates an ExtensionWallet instance that proxies wallet calls to a browser extension
|
|
56
60
|
* over a secure encrypted MessageChannel.
|
|
57
61
|
*
|
|
58
|
-
* The
|
|
59
|
-
* 1. Generates an ECDH key pair for this session
|
|
60
|
-
* 2. Derives a shared AES-256 key using the wallet's public key
|
|
61
|
-
* 3. Creates a MessageChannel and transfers one port to the extension
|
|
62
|
-
* 4. Returns a Proxy that encrypts all wallet method calls
|
|
63
|
-
*
|
|
64
|
-
* @param walletInfo - The discovered wallet information, including the wallet's ECDH public key
|
|
62
|
+
* @param walletInfo - The wallet info from ExtensionProvider.discoverExtensions()
|
|
65
63
|
* @param chainInfo - The chain information (chainId and version) for request context
|
|
64
|
+
* @param port - The MessagePort for private communication with the wallet
|
|
65
|
+
* @param sharedKey - The derived AES-256-GCM shared key for encryption
|
|
66
66
|
* @param appId - Application identifier used to identify the requesting dApp to the wallet
|
|
67
67
|
* @returns A Promise resolving to a Wallet implementation that encrypts all communication
|
|
68
68
|
*
|
|
69
|
-
* @throws Error if the secure channel cannot be established
|
|
70
|
-
*
|
|
71
69
|
* @example
|
|
72
70
|
* ```typescript
|
|
71
|
+
* const wallets = await ExtensionProvider.discoverExtensions(chainInfo);
|
|
72
|
+
* const { info, port, sharedKey } = wallets[0];
|
|
73
73
|
* const wallet = await ExtensionWallet.create(
|
|
74
|
-
*
|
|
74
|
+
* info,
|
|
75
75
|
* { chainId: Fr(31337), version: Fr(0) },
|
|
76
|
+
* port,
|
|
77
|
+
* sharedKey,
|
|
76
78
|
* 'my-defi-app'
|
|
77
79
|
* );
|
|
78
80
|
* ```
|
|
79
|
-
*/ static
|
|
80
|
-
const wallet = new ExtensionWallet(chainInfo, appId, walletInfo.id);
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
81
|
+
*/ static create(walletInfo, chainInfo, port, sharedKey, appId) {
|
|
82
|
+
const wallet = new ExtensionWallet(chainInfo, appId, walletInfo.id, port, sharedKey);
|
|
83
|
+
// Set up message handler
|
|
84
|
+
wallet.port.onmessage = (event)=>{
|
|
85
|
+
void wallet.handleEncryptedResponse(event.data);
|
|
86
|
+
};
|
|
87
|
+
wallet.port.start();
|
|
85
88
|
// Create a Proxy that intercepts wallet method calls and forwards them to the extension
|
|
86
89
|
return new Proxy(wallet, {
|
|
87
90
|
get: (target, prop)=>{
|
|
@@ -100,41 +103,6 @@ import { decrypt, deriveSharedKey, encrypt, exportPublicKey, generateKeyPair, im
|
|
|
100
103
|
});
|
|
101
104
|
}
|
|
102
105
|
/**
|
|
103
|
-
* Establishes a secure MessageChannel with ECDH key exchange.
|
|
104
|
-
*
|
|
105
|
-
* This method performs the cryptographic handshake:
|
|
106
|
-
* 1. Generates a new ECDH P-256 key pair for this session
|
|
107
|
-
* 2. Imports the wallet's public key and derives a shared secret
|
|
108
|
-
* 3. Creates a MessageChannel for private communication
|
|
109
|
-
* 4. Sends a connection request with our public key via window.postMessage
|
|
110
|
-
* (this is the only public message - subsequent communication uses the private channel)
|
|
111
|
-
*
|
|
112
|
-
* @param walletExportedPublicKey - The wallet's ECDH public key in JWK format
|
|
113
|
-
*/ async establishSecureChannel(walletExportedPublicKey) {
|
|
114
|
-
const keyPair = await generateKeyPair();
|
|
115
|
-
const exportedPublicKey = await exportPublicKey(keyPair.publicKey);
|
|
116
|
-
const walletPublicKey = await importPublicKey(walletExportedPublicKey);
|
|
117
|
-
this.sharedKey = await deriveSharedKey(keyPair.privateKey, walletPublicKey);
|
|
118
|
-
const channel = new MessageChannel();
|
|
119
|
-
this.port = channel.port1;
|
|
120
|
-
this.port.onmessage = async (event)=>{
|
|
121
|
-
await this.handleEncryptedResponse(event.data);
|
|
122
|
-
};
|
|
123
|
-
this.port.start();
|
|
124
|
-
// Send connection request with our public key and transfer port2 to content script
|
|
125
|
-
// This is the only public postMessage - it contains our public key (safe to expose)
|
|
126
|
-
// and transfers the MessagePort for subsequent private communication
|
|
127
|
-
const connectRequest = {
|
|
128
|
-
type: 'aztec-wallet-connect',
|
|
129
|
-
walletId: this.extensionId,
|
|
130
|
-
appId: this.appId,
|
|
131
|
-
publicKey: exportedPublicKey
|
|
132
|
-
};
|
|
133
|
-
window.postMessage(jsonStringify(connectRequest), '*', [
|
|
134
|
-
channel.port2
|
|
135
|
-
]);
|
|
136
|
-
}
|
|
137
|
-
/**
|
|
138
106
|
* Handles an encrypted response received from the wallet extension.
|
|
139
107
|
*
|
|
140
108
|
* Decrypts the response using the shared AES key and resolves or rejects
|
|
@@ -171,7 +139,7 @@ import { decrypt, deriveSharedKey, encrypt, exportPublicKey, generateKeyPair, im
|
|
|
171
139
|
* Sends an encrypted wallet method call over the secure MessageChannel.
|
|
172
140
|
*
|
|
173
141
|
* The message is encrypted using AES-256-GCM with the shared key derived
|
|
174
|
-
* during
|
|
142
|
+
* during discovery. A unique message ID is generated to correlate
|
|
175
143
|
* the response.
|
|
176
144
|
*
|
|
177
145
|
* @param call - The wallet method call containing method name and arguments
|
|
@@ -210,16 +178,15 @@ import { decrypt, deriveSharedKey, encrypt, exportPublicKey, generateKeyPair, im
|
|
|
210
178
|
*
|
|
211
179
|
* @example
|
|
212
180
|
* ```typescript
|
|
213
|
-
* const
|
|
181
|
+
* const { info, port, sharedKey } = wallets[0];
|
|
182
|
+
* const wallet = await ExtensionWallet.create(info, chainInfo, port, sharedKey, 'my-app');
|
|
214
183
|
* // ... use wallet ...
|
|
215
184
|
* wallet.close(); // Clean up when done
|
|
216
185
|
* ```
|
|
217
186
|
*/ close() {
|
|
218
187
|
if (this.port) {
|
|
219
188
|
this.port.close();
|
|
220
|
-
this.port = null;
|
|
221
189
|
}
|
|
222
|
-
this.sharedKey = null;
|
|
223
190
|
this.inFlight.clear();
|
|
224
191
|
}
|
|
225
192
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { ExtensionWallet } from './extension_wallet.js';
|
|
2
|
-
export { ExtensionProvider } from './extension_provider.js';
|
|
2
|
+
export { ExtensionProvider, type DiscoveredWallet } from './extension_provider.js';
|
|
3
3
|
export * from '../../crypto.js';
|
|
4
|
-
export type { WalletInfo, WalletMessage, WalletResponse, DiscoveryRequest, DiscoveryResponse
|
|
5
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
4
|
+
export type { WalletInfo, WalletMessage, WalletResponse, DiscoveryRequest, DiscoveryResponse } from '../../types.js';
|
|
5
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9wcm92aWRlcnMvZXh0ZW5zaW9uL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUN4RCxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsS0FBSyxnQkFBZ0IsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQ25GLGNBQWMsaUJBQWlCLENBQUM7QUFDaEMsWUFBWSxFQUFFLFVBQVUsRUFBRSxhQUFhLEVBQUUsY0FBYyxFQUFFLGdCQUFnQixFQUFFLGlCQUFpQixFQUFFLE1BQU0sZ0JBQWdCLENBQUMifQ==
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/providers/extension/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/providers/extension/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,iBAAiB,EAAE,KAAK,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AACnF,cAAc,iBAAiB,CAAC;AAChC,YAAY,EAAE,UAAU,EAAE,aAAa,EAAE,cAAc,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC"}
|
package/dest/types.d.ts
CHANGED
|
@@ -14,6 +14,12 @@ export interface WalletInfo {
|
|
|
14
14
|
version: string;
|
|
15
15
|
/** Wallet's ECDH public key for secure channel establishment */
|
|
16
16
|
publicKey: ExportedPublicKey;
|
|
17
|
+
/**
|
|
18
|
+
* Hash of the shared secret for anti-MITM verification.
|
|
19
|
+
* Both dApp and wallet independently compute this from the ECDH shared secret.
|
|
20
|
+
* Use {@link hashToEmoji} to convert to a visual representation for user verification.
|
|
21
|
+
*/
|
|
22
|
+
verificationHash?: string;
|
|
17
23
|
}
|
|
18
24
|
/**
|
|
19
25
|
* Message format for wallet communication (internal, before encryption)
|
|
@@ -55,6 +61,8 @@ export interface DiscoveryRequest {
|
|
|
55
61
|
requestId: string;
|
|
56
62
|
/** Chain information to check if wallet supports this network */
|
|
57
63
|
chainInfo: ChainInfo;
|
|
64
|
+
/** dApp's ECDH public key for deriving shared secret */
|
|
65
|
+
publicKey: ExportedPublicKey;
|
|
58
66
|
}
|
|
59
67
|
/**
|
|
60
68
|
* Discovery response from a wallet (public, unencrypted)
|
|
@@ -67,17 +75,4 @@ export interface DiscoveryResponse {
|
|
|
67
75
|
/** Wallet information */
|
|
68
76
|
walletInfo: WalletInfo;
|
|
69
77
|
}
|
|
70
|
-
|
|
71
|
-
* Connection request to establish secure channel
|
|
72
|
-
*/
|
|
73
|
-
export interface ConnectRequest {
|
|
74
|
-
/** Message type for connection */
|
|
75
|
-
type: 'aztec-wallet-connect';
|
|
76
|
-
/** Target wallet ID */
|
|
77
|
-
walletId: string;
|
|
78
|
-
/** Application ID */
|
|
79
|
-
appId: string;
|
|
80
|
-
/** dApp's ECDH public key for deriving shared secret */
|
|
81
|
-
publicKey: ExportedPublicKey;
|
|
82
|
-
}
|
|
83
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy90eXBlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssRUFBRSxTQUFTLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUV6RCxPQUFPLEtBQUssRUFBRSxpQkFBaUIsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUVyRDs7R0FFRztBQUNILE1BQU0sV0FBVyxVQUFVO0lBQ3pCLHVDQUF1QztJQUN2QyxFQUFFLEVBQUUsTUFBTSxDQUFDO0lBQ1gsaUNBQWlDO0lBQ2pDLElBQUksRUFBRSxNQUFNLENBQUM7SUFDYiwrQkFBK0I7SUFDL0IsSUFBSSxDQUFDLEVBQUUsTUFBTSxDQUFDO0lBQ2QscUJBQXFCO0lBQ3JCLE9BQU8sRUFBRSxNQUFNLENBQUM7SUFDaEIsZ0VBQWdFO0lBQ2hFLFNBQVMsRUFBRSxpQkFBaUIsQ0FBQztDQUM5QjtBQUVEOztHQUVHO0FBQ0gsTUFBTSxXQUFXLGFBQWE7SUFDNUIsK0NBQStDO0lBQy9DLFNBQVMsRUFBRSxNQUFNLENBQUM7SUFDbEIsZ0NBQWdDO0lBQ2hDLElBQUksRUFBRSxNQUFNLENBQUM7SUFDYiwrQkFBK0I7SUFDL0IsSUFBSSxFQUFFLE9BQU8sRUFBRSxDQUFDO0lBQ2hCLHdCQUF3QjtJQUN4QixTQUFTLEVBQUUsU0FBUyxDQUFDO0lBQ3JCLHdDQUF3QztJQUN4QyxLQUFLLEVBQUUsTUFBTSxDQUFDO0lBQ2QsNENBQTRDO0lBQzVDLFFBQVEsRUFBRSxNQUFNLENBQUM7Q0FDbEI7QUFFRDs7R0FFRztBQUNILE1BQU0sV0FBVyxjQUFjO0lBQzdCLHNDQUFzQztJQUN0QyxTQUFTLEVBQUUsTUFBTSxDQUFDO0lBQ2xCLGtDQUFrQztJQUNsQyxNQUFNLENBQUMsRUFBRSxPQUFPLENBQUM7SUFDakIsNkJBQTZCO0lBQzdCLEtBQUssQ0FBQyxFQUFFLE9BQU8sQ0FBQztJQUNoQix1Q0FBdUM7SUFDdkMsUUFBUSxFQUFFLE1BQU0sQ0FBQztDQUNsQjtBQUVEOztHQUVHO0FBQ0gsTUFBTSxXQUFXLGdCQUFnQjtJQUMvQixpQ0FBaUM7SUFDakMsSUFBSSxFQUFFLHdCQUF3QixDQUFDO0lBQy9CLGlCQUFpQjtJQUNqQixTQUFTLEVBQUUsTUFBTSxDQUFDO0lBQ2xCLGlFQUFpRTtJQUNqRSxTQUFTLEVBQUUsU0FBUyxDQUFDO0NBQ3RCO0FBRUQ7O0dBRUc7QUFDSCxNQUFNLFdBQVcsaUJBQWlCO0lBQ2hDLDBDQUEwQztJQUMxQyxJQUFJLEVBQUUsaUNBQWlDLENBQUM7SUFDeEMsZ0RBQWdEO0lBQ2hELFNBQVMsRUFBRSxNQUFNLENBQUM7SUFDbEIseUJBQXlCO0lBQ3pCLFVBQVUsRUFBRSxVQUFVLENBQUM7Q0FDeEI7QUFFRDs7R0FFRztBQUNILE1BQU0sV0FBVyxjQUFjO0lBQzdCLGtDQUFrQztJQUNsQyxJQUFJLEVBQUUsc0JBQXNCLENBQUM7SUFDN0IsdUJBQXVCO0lBQ3ZCLFFBQVEsRUFBRSxNQUFNLENBQUM7SUFDakIscUJBQXFCO0lBQ3JCLEtBQUssRUFBRSxNQUFNLENBQUM7SUFDZCx3REFBd0Q7SUFDeEQsU0FBUyxFQUFFLGlCQUFpQixDQUFDO0NBQzlCIn0=
|
|
78
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy90eXBlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssRUFBRSxTQUFTLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUV6RCxPQUFPLEtBQUssRUFBRSxpQkFBaUIsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUVyRDs7R0FFRztBQUNILE1BQU0sV0FBVyxVQUFVO0lBQ3pCLHVDQUF1QztJQUN2QyxFQUFFLEVBQUUsTUFBTSxDQUFDO0lBQ1gsaUNBQWlDO0lBQ2pDLElBQUksRUFBRSxNQUFNLENBQUM7SUFDYiwrQkFBK0I7SUFDL0IsSUFBSSxDQUFDLEVBQUUsTUFBTSxDQUFDO0lBQ2QscUJBQXFCO0lBQ3JCLE9BQU8sRUFBRSxNQUFNLENBQUM7SUFDaEIsZ0VBQWdFO0lBQ2hFLFNBQVMsRUFBRSxpQkFBaUIsQ0FBQztJQUM3Qjs7OztPQUlHO0lBQ0gsZ0JBQWdCLENBQUMsRUFBRSxNQUFNLENBQUM7Q0FDM0I7QUFFRDs7R0FFRztBQUNILE1BQU0sV0FBVyxhQUFhO0lBQzVCLCtDQUErQztJQUMvQyxTQUFTLEVBQUUsTUFBTSxDQUFDO0lBQ2xCLGdDQUFnQztJQUNoQyxJQUFJLEVBQUUsTUFBTSxDQUFDO0lBQ2IsK0JBQStCO0lBQy9CLElBQUksRUFBRSxPQUFPLEVBQUUsQ0FBQztJQUNoQix3QkFBd0I7SUFDeEIsU0FBUyxFQUFFLFNBQVMsQ0FBQztJQUNyQix3Q0FBd0M7SUFDeEMsS0FBSyxFQUFFLE1BQU0sQ0FBQztJQUNkLDRDQUE0QztJQUM1QyxRQUFRLEVBQUUsTUFBTSxDQUFDO0NBQ2xCO0FBRUQ7O0dBRUc7QUFDSCxNQUFNLFdBQVcsY0FBYztJQUM3QixzQ0FBc0M7SUFDdEMsU0FBUyxFQUFFLE1BQU0sQ0FBQztJQUNsQixrQ0FBa0M7SUFDbEMsTUFBTSxDQUFDLEVBQUUsT0FBTyxDQUFDO0lBQ2pCLDZCQUE2QjtJQUM3QixLQUFLLENBQUMsRUFBRSxPQUFPLENBQUM7SUFDaEIsdUNBQXVDO0lBQ3ZDLFFBQVEsRUFBRSxNQUFNLENBQUM7Q0FDbEI7QUFFRDs7R0FFRztBQUNILE1BQU0sV0FBVyxnQkFBZ0I7SUFDL0IsaUNBQWlDO0lBQ2pDLElBQUksRUFBRSx3QkFBd0IsQ0FBQztJQUMvQixpQkFBaUI7SUFDakIsU0FBUyxFQUFFLE1BQU0sQ0FBQztJQUNsQixpRUFBaUU7SUFDakUsU0FBUyxFQUFFLFNBQVMsQ0FBQztJQUNyQix3REFBd0Q7SUFDeEQsU0FBUyxFQUFFLGlCQUFpQixDQUFDO0NBQzlCO0FBRUQ7O0dBRUc7QUFDSCxNQUFNLFdBQVcsaUJBQWlCO0lBQ2hDLDBDQUEwQztJQUMxQyxJQUFJLEVBQUUsaUNBQWlDLENBQUM7SUFDeEMsZ0RBQWdEO0lBQ2hELFNBQVMsRUFBRSxNQUFNLENBQUM7SUFDbEIseUJBQXlCO0lBQ3pCLFVBQVUsRUFBRSxVQUFVLENBQUM7Q0FDeEIifQ==
|
package/dest/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAEzD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAErD;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,uCAAuC;IACvC,EAAE,EAAE,MAAM,CAAC;IACX,iCAAiC;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,+BAA+B;IAC/B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,qBAAqB;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,gEAAgE;IAChE,SAAS,EAAE,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAEzD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAErD;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,uCAAuC;IACvC,EAAE,EAAE,MAAM,CAAC;IACX,iCAAiC;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,+BAA+B;IAC/B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,qBAAqB;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,gEAAgE;IAChE,SAAS,EAAE,iBAAiB,CAAC;IAC7B;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,+CAA+C;IAC/C,SAAS,EAAE,MAAM,CAAC;IAClB,gCAAgC;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,+BAA+B;IAC/B,IAAI,EAAE,OAAO,EAAE,CAAC;IAChB,wBAAwB;IACxB,SAAS,EAAE,SAAS,CAAC;IACrB,wCAAwC;IACxC,KAAK,EAAE,MAAM,CAAC;IACd,4CAA4C;IAC5C,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,sCAAsC;IACtC,SAAS,EAAE,MAAM,CAAC;IAClB,kCAAkC;IAClC,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,6BAA6B;IAC7B,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,uCAAuC;IACvC,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,iCAAiC;IACjC,IAAI,EAAE,wBAAwB,CAAC;IAC/B,iBAAiB;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,iEAAiE;IACjE,SAAS,EAAE,SAAS,CAAC;IACrB,wDAAwD;IACxD,SAAS,EAAE,iBAAiB,CAAC;CAC9B;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,0CAA0C;IAC1C,IAAI,EAAE,iCAAiC,CAAC;IACxC,gDAAgD;IAChD,SAAS,EAAE,MAAM,CAAC;IAClB,yBAAyB;IACzB,UAAU,EAAE,UAAU,CAAC;CACxB"}
|
package/dest/types.js
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aztec/wallet-sdk",
|
|
3
3
|
"homepage": "https://github.com/AztecProtocol/aztec-packages/tree/master/yarn-project/wallet-sdk",
|
|
4
|
-
"version": "4.0.0-nightly.
|
|
4
|
+
"version": "4.0.0-nightly.20260115",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
7
7
|
"./base-wallet": "./dest/base-wallet/index.js",
|
|
@@ -64,19 +64,19 @@
|
|
|
64
64
|
]
|
|
65
65
|
},
|
|
66
66
|
"dependencies": {
|
|
67
|
-
"@aztec/aztec.js": "4.0.0-nightly.
|
|
68
|
-
"@aztec/constants": "4.0.0-nightly.
|
|
69
|
-
"@aztec/entrypoints": "4.0.0-nightly.
|
|
70
|
-
"@aztec/foundation": "4.0.0-nightly.
|
|
71
|
-
"@aztec/pxe": "4.0.0-nightly.
|
|
72
|
-
"@aztec/stdlib": "4.0.0-nightly.
|
|
67
|
+
"@aztec/aztec.js": "4.0.0-nightly.20260115",
|
|
68
|
+
"@aztec/constants": "4.0.0-nightly.20260115",
|
|
69
|
+
"@aztec/entrypoints": "4.0.0-nightly.20260115",
|
|
70
|
+
"@aztec/foundation": "4.0.0-nightly.20260115",
|
|
71
|
+
"@aztec/pxe": "4.0.0-nightly.20260115",
|
|
72
|
+
"@aztec/stdlib": "4.0.0-nightly.20260115"
|
|
73
73
|
},
|
|
74
74
|
"devDependencies": {
|
|
75
|
-
"@aztec/noir-contracts.js": "4.0.0-nightly.
|
|
75
|
+
"@aztec/noir-contracts.js": "4.0.0-nightly.20260115",
|
|
76
76
|
"@jest/globals": "^30.0.0",
|
|
77
77
|
"@types/jest": "^30.0.0",
|
|
78
78
|
"@types/node": "^22.15.17",
|
|
79
|
-
"@typescript/native-preview": "7.0.0-dev.
|
|
79
|
+
"@typescript/native-preview": "7.0.0-dev.20260113.1",
|
|
80
80
|
"jest": "^30.0.0",
|
|
81
81
|
"jest-mock-extended": "^4.0.0",
|
|
82
82
|
"resolve-typescript-plugin": "^2.0.1",
|
|
@@ -34,14 +34,13 @@ import {
|
|
|
34
34
|
import type { AuthWitness } from '@aztec/stdlib/auth-witness';
|
|
35
35
|
import type { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
36
36
|
import {
|
|
37
|
-
type ContractClassMetadata,
|
|
38
37
|
type ContractInstanceWithAddress,
|
|
39
|
-
type ContractMetadata,
|
|
40
38
|
computePartialAddress,
|
|
41
39
|
getContractClassFromArtifact,
|
|
42
40
|
} from '@aztec/stdlib/contract';
|
|
43
41
|
import { SimulationError } from '@aztec/stdlib/errors';
|
|
44
42
|
import { Gas, GasSettings } from '@aztec/stdlib/gas';
|
|
43
|
+
import { siloNullifier } from '@aztec/stdlib/hash';
|
|
45
44
|
import type { AztecNode } from '@aztec/stdlib/interfaces/client';
|
|
46
45
|
import type {
|
|
47
46
|
TxExecutionRequest,
|
|
@@ -227,7 +226,7 @@ export abstract class BaseWallet implements Wallet {
|
|
|
227
226
|
artifact?: ContractArtifact,
|
|
228
227
|
secretKey?: Fr,
|
|
229
228
|
): Promise<ContractInstanceWithAddress> {
|
|
230
|
-
const
|
|
229
|
+
const existingInstance = await this.pxe.getContractInstance(instance.address);
|
|
231
230
|
|
|
232
231
|
if (existingInstance) {
|
|
233
232
|
// Instance already registered in the wallet
|
|
@@ -244,13 +243,12 @@ export abstract class BaseWallet implements Wallet {
|
|
|
244
243
|
// Instance not registered yet
|
|
245
244
|
if (!artifact) {
|
|
246
245
|
// Try to get the artifact from the wallet's contract class storage
|
|
247
|
-
|
|
248
|
-
if (!
|
|
246
|
+
artifact = await this.pxe.getContractArtifact(instance.currentContractClassId);
|
|
247
|
+
if (!artifact) {
|
|
249
248
|
throw new Error(
|
|
250
249
|
`Cannot register contract at ${instance.address.toString()}: artifact is required but not provided, and wallet does not have the artifact for contract class ${instance.currentContractClassId.toString()}`,
|
|
251
250
|
);
|
|
252
251
|
}
|
|
253
|
-
artifact = classMetadata.artifact;
|
|
254
252
|
}
|
|
255
253
|
await this.pxe.registerContract({ artifact, instance });
|
|
256
254
|
}
|
|
@@ -315,13 +313,6 @@ export abstract class BaseWallet implements Wallet {
|
|
|
315
313
|
return this.pxe.simulateUtility(call, authwits);
|
|
316
314
|
}
|
|
317
315
|
|
|
318
|
-
getContractClassMetadata(id: Fr, includeArtifact: boolean = false): Promise<ContractClassMetadata> {
|
|
319
|
-
return this.pxe.getContractClassMetadata(id, includeArtifact);
|
|
320
|
-
}
|
|
321
|
-
getContractMetadata(address: AztecAddress): Promise<ContractMetadata> {
|
|
322
|
-
return this.pxe.getContractMetadata(address);
|
|
323
|
-
}
|
|
324
|
-
|
|
325
316
|
getTxReceipt(txHash: TxHash): Promise<TxReceipt> {
|
|
326
317
|
return this.aztecNode.getTxReceipt(txHash);
|
|
327
318
|
}
|
|
@@ -345,4 +336,37 @@ export abstract class BaseWallet implements Wallet {
|
|
|
345
336
|
|
|
346
337
|
return decodedEvents;
|
|
347
338
|
}
|
|
339
|
+
|
|
340
|
+
async getContractMetadata(address: AztecAddress) {
|
|
341
|
+
const instance = await this.pxe.getContractInstance(address);
|
|
342
|
+
const initNullifier = await siloNullifier(address, address.toField());
|
|
343
|
+
const publiclyRegisteredContract = await this.aztecNode.getContract(address);
|
|
344
|
+
const [initNullifierMembershipWitness, publiclyRegisteredContractClass] = await Promise.all([
|
|
345
|
+
this.aztecNode.getNullifierMembershipWitness('latest', initNullifier),
|
|
346
|
+
publiclyRegisteredContract
|
|
347
|
+
? this.aztecNode.getContractClass(
|
|
348
|
+
publiclyRegisteredContract.currentContractClassId || instance?.currentContractClassId,
|
|
349
|
+
)
|
|
350
|
+
: undefined,
|
|
351
|
+
]);
|
|
352
|
+
const isContractUpdated =
|
|
353
|
+
publiclyRegisteredContract &&
|
|
354
|
+
!publiclyRegisteredContract.currentContractClassId.equals(publiclyRegisteredContract.originalContractClassId);
|
|
355
|
+
return {
|
|
356
|
+
instance: instance ?? undefined,
|
|
357
|
+
isContractInitialized: !!initNullifierMembershipWitness,
|
|
358
|
+
isContractPublished: !!publiclyRegisteredContract,
|
|
359
|
+
isContractClassPubliclyRegistered: !!publiclyRegisteredContractClass,
|
|
360
|
+
isContractUpdated: !!isContractUpdated,
|
|
361
|
+
updatedContractClassId: isContractUpdated ? publiclyRegisteredContract.currentContractClassId : undefined,
|
|
362
|
+
};
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
async getContractClassMetadata(id: Fr) {
|
|
366
|
+
const publiclyRegisteredContractClass = await this.aztecNode.getContractClass(id);
|
|
367
|
+
return {
|
|
368
|
+
isArtifactRegistered: !!(await this.pxe.getContractArtifact(id)),
|
|
369
|
+
isContractClassPubliclyRegistered: !!publiclyRegisteredContractClass,
|
|
370
|
+
};
|
|
371
|
+
}
|
|
348
372
|
}
|
package/src/crypto.ts
CHANGED
|
@@ -192,7 +192,7 @@ export function deriveSharedKey(privateKey: CryptoKey, publicKey: CryptoKey): Pr
|
|
|
192
192
|
name: 'AES-GCM',
|
|
193
193
|
length: 256,
|
|
194
194
|
},
|
|
195
|
-
|
|
195
|
+
true, // extractable - needed for hashing
|
|
196
196
|
['encrypt', 'decrypt'],
|
|
197
197
|
);
|
|
198
198
|
}
|
|
@@ -281,3 +281,95 @@ function base64ToArrayBuffer(base64: string): ArrayBuffer {
|
|
|
281
281
|
}
|
|
282
282
|
return bytes.buffer;
|
|
283
283
|
}
|
|
284
|
+
|
|
285
|
+
/**
|
|
286
|
+
* Emoji alphabet for visual verification of shared secrets.
|
|
287
|
+
* 32 distinct, easily recognizable emojis for anti-spoofing verification.
|
|
288
|
+
* @internal
|
|
289
|
+
*/
|
|
290
|
+
const EMOJI_ALPHABET = [
|
|
291
|
+
'🔵',
|
|
292
|
+
'🟢',
|
|
293
|
+
'🔴',
|
|
294
|
+
'🟡',
|
|
295
|
+
'🟣',
|
|
296
|
+
'🟠',
|
|
297
|
+
'⚫',
|
|
298
|
+
'⚪',
|
|
299
|
+
'🌟',
|
|
300
|
+
'🌙',
|
|
301
|
+
'☀️',
|
|
302
|
+
'🌈',
|
|
303
|
+
'🔥',
|
|
304
|
+
'💧',
|
|
305
|
+
'🌸',
|
|
306
|
+
'🍀',
|
|
307
|
+
'🦋',
|
|
308
|
+
'🐬',
|
|
309
|
+
'🦊',
|
|
310
|
+
'🐼',
|
|
311
|
+
'🦁',
|
|
312
|
+
'🐯',
|
|
313
|
+
'🐸',
|
|
314
|
+
'🦉',
|
|
315
|
+
'🎵',
|
|
316
|
+
'🎨',
|
|
317
|
+
'🎯',
|
|
318
|
+
'🎲',
|
|
319
|
+
'🔔',
|
|
320
|
+
'💎',
|
|
321
|
+
'🔑',
|
|
322
|
+
'🏆',
|
|
323
|
+
];
|
|
324
|
+
|
|
325
|
+
/**
|
|
326
|
+
* Hashes a shared AES key to a hex string for verification.
|
|
327
|
+
*
|
|
328
|
+
* This extracts the raw key material and hashes it with SHA-256,
|
|
329
|
+
* returning the first 16 bytes as a hex string.
|
|
330
|
+
*
|
|
331
|
+
* @param sharedKey - The AES-GCM shared key (must be extractable)
|
|
332
|
+
* @returns A hex string representation of the hash
|
|
333
|
+
*
|
|
334
|
+
* @example
|
|
335
|
+
* ```typescript
|
|
336
|
+
* const hash = await hashSharedSecret(sharedKey);
|
|
337
|
+
* const emoji = hashToEmoji(hash);
|
|
338
|
+
* ```
|
|
339
|
+
*/
|
|
340
|
+
export async function hashSharedSecret(sharedKey: CryptoKey): Promise<string> {
|
|
341
|
+
const rawKey = await crypto.subtle.exportKey('raw', sharedKey);
|
|
342
|
+
const hash = await crypto.subtle.digest('SHA-256', rawKey);
|
|
343
|
+
const bytes = new Uint8Array(hash.slice(0, 16));
|
|
344
|
+
return Array.from(bytes)
|
|
345
|
+
.map(b => b.toString(16).padStart(2, '0'))
|
|
346
|
+
.join('');
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
/**
|
|
350
|
+
* Converts a hex hash to an emoji sequence for visual verification.
|
|
351
|
+
*
|
|
352
|
+
* This is used for anti-MITM verification - both the dApp and wallet
|
|
353
|
+
* independently compute the same emoji sequence from the shared secret.
|
|
354
|
+
* Users can visually compare the sequences to detect interception.
|
|
355
|
+
*
|
|
356
|
+
* Similar to SAS (Short Authentication String) in ZRTP/Signal.
|
|
357
|
+
*
|
|
358
|
+
* @param hash - Hex string from {@link hashSharedSecret}
|
|
359
|
+
* @param length - Number of emojis to generate (default: 4)
|
|
360
|
+
* @returns A string of emojis representing the hash
|
|
361
|
+
*
|
|
362
|
+
* @example
|
|
363
|
+
* ```typescript
|
|
364
|
+
* const hash = await hashSharedSecret(sharedKey);
|
|
365
|
+
* const emoji = hashToEmoji(hash); // e.g., "🔵🦋🎯🐼"
|
|
366
|
+
* // Display to user for verification
|
|
367
|
+
* ```
|
|
368
|
+
*/
|
|
369
|
+
export function hashToEmoji(hash: string, length: number = 4): string {
|
|
370
|
+
const bytes: number[] = [];
|
|
371
|
+
for (let i = 0; i < hash.length && bytes.length < length; i += 2) {
|
|
372
|
+
bytes.push(parseInt(hash.slice(i, i + 2), 16));
|
|
373
|
+
}
|
|
374
|
+
return bytes.map(b => EMOJI_ALPHABET[b % EMOJI_ALPHABET.length]).join('');
|
|
375
|
+
}
|