@aztec/wallet-sdk 4.0.0-nightly.20260115 → 4.0.0-nightly.20260116

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.
@@ -1,8 +1,9 @@
1
1
  export { WalletManager } from './wallet_manager.js';
2
- export type { WalletManagerConfig, ExtensionWalletConfig, WebWalletConfig, WalletProviderType, WalletProvider, DiscoverWalletsOptions, } from './types.js';
2
+ export type { WalletManagerConfig, ExtensionWalletConfig, WebWalletConfig, WalletProviderType, WalletProvider, ProviderDisconnectionCallback, DiscoverWalletsOptions, } from './types.js';
3
+ export { WalletMessageType } from '../types.js';
3
4
  export type { WalletInfo, WalletMessage, WalletResponse, DiscoveryRequest, DiscoveryResponse } from '../types.js';
4
5
  export { ChainInfoSchema } from '@aztec/aztec.js/account';
5
6
  export type { ChainInfo } from '@aztec/aztec.js/account';
6
7
  export { WalletSchema } from '@aztec/aztec.js/wallet';
7
8
  export { jsonStringify } from '@aztec/foundation/json-rpc';
8
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9tYW5hZ2VyL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUNwRCxZQUFZLEVBQ1YsbUJBQW1CLEVBQ25CLHFCQUFxQixFQUNyQixlQUFlLEVBQ2Ysa0JBQWtCLEVBQ2xCLGNBQWMsRUFDZCxzQkFBc0IsR0FDdkIsTUFBTSxZQUFZLENBQUM7QUFHcEIsWUFBWSxFQUFFLFVBQVUsRUFBRSxhQUFhLEVBQUUsY0FBYyxFQUFFLGdCQUFnQixFQUFFLGlCQUFpQixFQUFFLE1BQU0sYUFBYSxDQUFDO0FBR2xILE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUMxRCxZQUFZLEVBQUUsU0FBUyxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDekQsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQ3RELE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQyJ9
9
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9tYW5hZ2VyL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUNwRCxZQUFZLEVBQ1YsbUJBQW1CLEVBQ25CLHFCQUFxQixFQUNyQixlQUFlLEVBQ2Ysa0JBQWtCLEVBQ2xCLGNBQWMsRUFDZCw2QkFBNkIsRUFDN0Isc0JBQXNCLEdBQ3ZCLE1BQU0sWUFBWSxDQUFDO0FBR3BCLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUNoRCxZQUFZLEVBQUUsVUFBVSxFQUFFLGFBQWEsRUFBRSxjQUFjLEVBQUUsZ0JBQWdCLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFHbEgsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQzFELFlBQVksRUFBRSxTQUFTLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUN6RCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDdEQsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLDRCQUE0QixDQUFDIn0=
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/manager/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,YAAY,EACV,mBAAmB,EACnB,qBAAqB,EACrB,eAAe,EACf,kBAAkB,EAClB,cAAc,EACd,sBAAsB,GACvB,MAAM,YAAY,CAAC;AAGpB,YAAY,EAAE,UAAU,EAAE,aAAa,EAAE,cAAc,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAGlH,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,YAAY,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/manager/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,YAAY,EACV,mBAAmB,EACnB,qBAAqB,EACrB,eAAe,EACf,kBAAkB,EAClB,cAAc,EACd,6BAA6B,EAC7B,sBAAsB,GACvB,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAChD,YAAY,EAAE,UAAU,EAAE,aAAa,EAAE,cAAc,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAGlH,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,YAAY,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC"}
@@ -1,4 +1,6 @@
1
1
  export { WalletManager } from './wallet_manager.js';
2
+ // Re-export types and enums from providers for convenience
3
+ export { WalletMessageType } from '../types.js';
2
4
  // Re-export commonly needed utilities for wallet integration
3
5
  export { ChainInfoSchema } from '@aztec/aztec.js/account';
4
6
  export { WalletSchema } from '@aztec/aztec.js/wallet';
@@ -31,6 +31,10 @@ export interface WalletManagerConfig {
31
31
  * Type of wallet provider
32
32
  */
33
33
  export type WalletProviderType = 'extension' | 'web' | 'embedded';
34
+ /**
35
+ * Callback type for wallet disconnect events at the provider level.
36
+ */
37
+ export type ProviderDisconnectionCallback = () => void;
34
38
  /**
35
39
  * A wallet provider that can connect to create a wallet instance.
36
40
  * Chain information is already baked in from the discovery process.
@@ -51,6 +55,23 @@ export interface WalletProvider {
51
55
  * @param appId - Application identifier for the requesting dapp
52
56
  */
53
57
  connect(appId: string): Promise<Wallet>;
58
+ /**
59
+ * Disconnects the current wallet and cleans up resources.
60
+ * After calling this, the wallet returned from connect() should no longer be used.
61
+ * @returns A promise that resolves when disconnection is complete
62
+ */
63
+ disconnect?(): Promise<void>;
64
+ /**
65
+ * Registers a callback to be invoked when the wallet disconnects unexpectedly.
66
+ * @param callback - Function to call when wallet disconnects
67
+ * @returns A function to unregister the callback
68
+ */
69
+ onDisconnect?(callback: ProviderDisconnectionCallback): () => void;
70
+ /**
71
+ * Returns whether the provider's wallet connection has been disconnected.
72
+ * @returns true if the wallet is no longer connected
73
+ */
74
+ isDisconnected?(): boolean;
54
75
  }
55
76
  /**
56
77
  * Options for discovering wallets
@@ -61,4 +82,4 @@ export interface DiscoverWalletsOptions {
61
82
  /** Discovery timeout in milliseconds */
62
83
  timeout?: number;
63
84
  }
64
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9tYW5hZ2VyL3R5cGVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxFQUFFLFNBQVMsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQ3pELE9BQU8sS0FBSyxFQUFFLE1BQU0sRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBRXJEOztHQUVHO0FBQ0gsTUFBTSxXQUFXLHFCQUFxQjtJQUNwQyw0Q0FBNEM7SUFDNUMsT0FBTyxFQUFFLE9BQU8sQ0FBQztJQUNqQix5REFBeUQ7SUFDekQsU0FBUyxDQUFDLEVBQUUsTUFBTSxFQUFFLENBQUM7SUFDckIseURBQXlEO0lBQ3pELFNBQVMsQ0FBQyxFQUFFLE1BQU0sRUFBRSxDQUFDO0NBQ3RCO0FBRUQ7O0dBRUc7QUFDSCxNQUFNLFdBQVcsZUFBZTtJQUM5QixrQ0FBa0M7SUFDbEMsSUFBSSxFQUFFLE1BQU0sRUFBRSxDQUFDO0NBQ2hCO0FBRUQ7O0dBRUc7QUFDSCxNQUFNLFdBQVcsbUJBQW1CO0lBQ2xDLHFDQUFxQztJQUNyQyxVQUFVLENBQUMsRUFBRSxxQkFBcUIsQ0FBQztJQUNuQywrQkFBK0I7SUFDL0IsVUFBVSxDQUFDLEVBQUUsZUFBZSxDQUFDO0NBQzlCO0FBRUQ7O0dBRUc7QUFDSCxNQUFNLE1BQU0sa0JBQWtCLEdBQUcsV0FBVyxHQUFHLEtBQUssR0FBRyxVQUFVLENBQUM7QUFFbEU7OztHQUdHO0FBQ0gsTUFBTSxXQUFXLGNBQWM7SUFDN0IseUNBQXlDO0lBQ3pDLEVBQUUsRUFBRSxNQUFNLENBQUM7SUFDWCw4QkFBOEI7SUFDOUIsSUFBSSxFQUFFLGtCQUFrQixDQUFDO0lBQ3pCLG1CQUFtQjtJQUNuQixJQUFJLEVBQUUsTUFBTSxDQUFDO0lBQ2IsZUFBZTtJQUNmLElBQUksQ0FBQyxFQUFFLE1BQU0sQ0FBQztJQUNkLDBCQUEwQjtJQUMxQixRQUFRLENBQUMsRUFBRSxNQUFNLENBQUMsTUFBTSxFQUFFLE9BQU8sQ0FBQyxDQUFDO0lBQ25DOzs7T0FHRztJQUNILE9BQU8sQ0FBQyxLQUFLLEVBQUUsTUFBTSxHQUFHLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQztDQUN6QztBQUVEOztHQUVHO0FBQ0gsTUFBTSxXQUFXLHNCQUFzQjtJQUNyQyxxQ0FBcUM7SUFDckMsU0FBUyxFQUFFLFNBQVMsQ0FBQztJQUNyQix3Q0FBd0M7SUFDeEMsT0FBTyxDQUFDLEVBQUUsTUFBTSxDQUFDO0NBQ2xCIn0=
85
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9tYW5hZ2VyL3R5cGVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxFQUFFLFNBQVMsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQ3pELE9BQU8sS0FBSyxFQUFFLE1BQU0sRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBRXJEOztHQUVHO0FBQ0gsTUFBTSxXQUFXLHFCQUFxQjtJQUNwQyw0Q0FBNEM7SUFDNUMsT0FBTyxFQUFFLE9BQU8sQ0FBQztJQUNqQix5REFBeUQ7SUFDekQsU0FBUyxDQUFDLEVBQUUsTUFBTSxFQUFFLENBQUM7SUFDckIseURBQXlEO0lBQ3pELFNBQVMsQ0FBQyxFQUFFLE1BQU0sRUFBRSxDQUFDO0NBQ3RCO0FBRUQ7O0dBRUc7QUFDSCxNQUFNLFdBQVcsZUFBZTtJQUM5QixrQ0FBa0M7SUFDbEMsSUFBSSxFQUFFLE1BQU0sRUFBRSxDQUFDO0NBQ2hCO0FBRUQ7O0dBRUc7QUFDSCxNQUFNLFdBQVcsbUJBQW1CO0lBQ2xDLHFDQUFxQztJQUNyQyxVQUFVLENBQUMsRUFBRSxxQkFBcUIsQ0FBQztJQUNuQywrQkFBK0I7SUFDL0IsVUFBVSxDQUFDLEVBQUUsZUFBZSxDQUFDO0NBQzlCO0FBRUQ7O0dBRUc7QUFDSCxNQUFNLE1BQU0sa0JBQWtCLEdBQUcsV0FBVyxHQUFHLEtBQUssR0FBRyxVQUFVLENBQUM7QUFFbEU7O0dBRUc7QUFDSCxNQUFNLE1BQU0sNkJBQTZCLEdBQUcsTUFBTSxJQUFJLENBQUM7QUFFdkQ7OztHQUdHO0FBQ0gsTUFBTSxXQUFXLGNBQWM7SUFDN0IseUNBQXlDO0lBQ3pDLEVBQUUsRUFBRSxNQUFNLENBQUM7SUFDWCw4QkFBOEI7SUFDOUIsSUFBSSxFQUFFLGtCQUFrQixDQUFDO0lBQ3pCLG1CQUFtQjtJQUNuQixJQUFJLEVBQUUsTUFBTSxDQUFDO0lBQ2IsZUFBZTtJQUNmLElBQUksQ0FBQyxFQUFFLE1BQU0sQ0FBQztJQUNkLDBCQUEwQjtJQUMxQixRQUFRLENBQUMsRUFBRSxNQUFNLENBQUMsTUFBTSxFQUFFLE9BQU8sQ0FBQyxDQUFDO0lBQ25DOzs7T0FHRztJQUNILE9BQU8sQ0FBQyxLQUFLLEVBQUUsTUFBTSxHQUFHLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUN4Qzs7OztPQUlHO0lBQ0gsVUFBVSxDQUFDLElBQUksT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQzdCOzs7O09BSUc7SUFDSCxZQUFZLENBQUMsQ0FBQyxRQUFRLEVBQUUsNkJBQTZCLEdBQUcsTUFBTSxJQUFJLENBQUM7SUFDbkU7OztPQUdHO0lBQ0gsY0FBYyxDQUFDLElBQUksT0FBTyxDQUFDO0NBQzVCO0FBRUQ7O0dBRUc7QUFDSCxNQUFNLFdBQVcsc0JBQXNCO0lBQ3JDLHFDQUFxQztJQUNyQyxTQUFTLEVBQUUsU0FBUyxDQUFDO0lBQ3JCLHdDQUF3QztJQUN4QyxPQUFPLENBQUMsRUFBRSxNQUFNLENBQUM7Q0FDbEIifQ==
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/manager/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAErD;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,4CAA4C;IAC5C,OAAO,EAAE,OAAO,CAAC;IACjB,yDAAyD;IACzD,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,yDAAyD;IACzD,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,kCAAkC;IAClC,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,qCAAqC;IACrC,UAAU,CAAC,EAAE,qBAAqB,CAAC;IACnC,+BAA+B;IAC/B,UAAU,CAAC,EAAE,eAAe,CAAC;CAC9B;AAED;;GAEG;AACH,MAAM,MAAM,kBAAkB,GAAG,WAAW,GAAG,KAAK,GAAG,UAAU,CAAC;AAElE;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B,yCAAyC;IACzC,EAAE,EAAE,MAAM,CAAC;IACX,8BAA8B;IAC9B,IAAI,EAAE,kBAAkB,CAAC;IACzB,mBAAmB;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,eAAe;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,0BAA0B;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC;;;OAGG;IACH,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CACzC;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,qCAAqC;IACrC,SAAS,EAAE,SAAS,CAAC;IACrB,wCAAwC;IACxC,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/manager/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAErD;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,4CAA4C;IAC5C,OAAO,EAAE,OAAO,CAAC;IACjB,yDAAyD;IACzD,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,yDAAyD;IACzD,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,kCAAkC;IAClC,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,qCAAqC;IACrC,UAAU,CAAC,EAAE,qBAAqB,CAAC;IACnC,+BAA+B;IAC/B,UAAU,CAAC,EAAE,eAAe,CAAC;CAC9B;AAED;;GAEG;AACH,MAAM,MAAM,kBAAkB,GAAG,WAAW,GAAG,KAAK,GAAG,UAAU,CAAC;AAElE;;GAEG;AACH,MAAM,MAAM,6BAA6B,GAAG,MAAM,IAAI,CAAC;AAEvD;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B,yCAAyC;IACzC,EAAE,EAAE,MAAM,CAAC;IACX,8BAA8B;IAC9B,IAAI,EAAE,kBAAkB,CAAC;IACzB,mBAAmB;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,eAAe;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,0BAA0B;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC;;;OAGG;IACH,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACxC;;;;OAIG;IACH,UAAU,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7B;;;;OAIG;IACH,YAAY,CAAC,CAAC,QAAQ,EAAE,6BAA6B,GAAG,MAAM,IAAI,CAAC;IACnE;;;OAGG;IACH,cAAc,CAAC,IAAI,OAAO,CAAC;CAC5B;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,qCAAqC;IACrC,SAAS,EAAE,SAAS,CAAC;IACrB,wCAAwC;IACxC,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB"}
@@ -24,4 +24,4 @@ export declare class WalletManager {
24
24
  */
25
25
  private isExtensionAllowed;
26
26
  }
27
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2FsbGV0X21hbmFnZXIuZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9tYW5hZ2VyL3dhbGxldF9tYW5hZ2VyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUNBLE9BQU8sS0FBSyxFQUFFLHNCQUFzQixFQUF5QixtQkFBbUIsRUFBRSxjQUFjLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFFckg7O0dBRUc7QUFDSCxxQkFBYSxhQUFhO0lBQ3hCLE9BQU8sQ0FBQyxNQUFNLENBR1o7SUFFRixPQUFPLGVBQWlCO0lBRXhCOzs7T0FHRztJQUNILE1BQU0sQ0FBQyxTQUFTLENBQUMsTUFBTSxFQUFFLG1CQUFtQixHQUFHLGFBQWEsQ0FPM0Q7SUFFRDs7Ozs7T0FLRztJQUNHLG1CQUFtQixDQUFDLE9BQU8sRUFBRSxzQkFBc0IsR0FBRyxPQUFPLENBQUMsY0FBYyxFQUFFLENBQUMsQ0E4QnBGO0lBRUQ7Ozs7T0FJRztJQUNILE9BQU8sQ0FBQyxrQkFBa0I7Q0FXM0IifQ==
27
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2FsbGV0X21hbmFnZXIuZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9tYW5hZ2VyL3dhbGxldF9tYW5hZ2VyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUNBLE9BQU8sS0FBSyxFQUNWLHNCQUFzQixFQUd0QixtQkFBbUIsRUFDbkIsY0FBYyxFQUNmLE1BQU0sWUFBWSxDQUFDO0FBRXBCOztHQUVHO0FBQ0gscUJBQWEsYUFBYTtJQUN4QixPQUFPLENBQUMsTUFBTSxDQUdaO0lBRUYsT0FBTyxlQUFpQjtJQUV4Qjs7O09BR0c7SUFDSCxNQUFNLENBQUMsU0FBUyxDQUFDLE1BQU0sRUFBRSxtQkFBbUIsR0FBRyxhQUFhLENBTzNEO0lBRUQ7Ozs7O09BS0c7SUFDRyxtQkFBbUIsQ0FBQyxPQUFPLEVBQUUsc0JBQXNCLEdBQUcsT0FBTyxDQUFDLGNBQWMsRUFBRSxDQUFDLENBdURwRjtJQUVEOzs7O09BSUc7SUFDSCxPQUFPLENBQUMsa0JBQWtCO0NBVzNCIn0=
@@ -1 +1 @@
1
- {"version":3,"file":"wallet_manager.d.ts","sourceRoot":"","sources":["../../src/manager/wallet_manager.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,sBAAsB,EAAyB,mBAAmB,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAErH;;GAEG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAGZ;IAEF,OAAO,eAAiB;IAExB;;;OAGG;IACH,MAAM,CAAC,SAAS,CAAC,MAAM,EAAE,mBAAmB,GAAG,aAAa,CAO3D;IAED;;;;;OAKG;IACG,mBAAmB,CAAC,OAAO,EAAE,sBAAsB,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC,CA8BpF;IAED;;;;OAIG;IACH,OAAO,CAAC,kBAAkB;CAW3B"}
1
+ {"version":3,"file":"wallet_manager.d.ts","sourceRoot":"","sources":["../../src/manager/wallet_manager.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,sBAAsB,EAGtB,mBAAmB,EACnB,cAAc,EACf,MAAM,YAAY,CAAC;AAEpB;;GAEG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAGZ;IAEF,OAAO,eAAiB;IAExB;;;OAGG;IACH,MAAM,CAAC,SAAS,CAAC,MAAM,EAAE,mBAAmB,GAAG,aAAa,CAO3D;IAED;;;;;OAKG;IACG,mBAAmB,CAAC,OAAO,EAAE,sBAAsB,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC,CAuDpF;IAED;;;;OAIG;IACH,OAAO,CAAC,kBAAkB;CAW3B"}
@@ -41,7 +41,8 @@ import { ExtensionProvider, ExtensionWallet } from '../providers/extension/index
41
41
  if (!this.isExtensionAllowed(info.id, extensionConfig)) {
42
42
  continue;
43
43
  }
44
- providers.push({
44
+ let extensionWallet = null;
45
+ const provider = {
45
46
  id: info.id,
46
47
  type: 'extension',
47
48
  name: info.name,
@@ -50,8 +51,30 @@ import { ExtensionProvider, ExtensionWallet } from '../providers/extension/index
50
51
  version: info.version,
51
52
  verificationHash: info.verificationHash
52
53
  },
53
- connect: (appId)=>Promise.resolve(ExtensionWallet.create(info, chainInfo, port, sharedKey, appId))
54
- });
54
+ connect: (appId)=>{
55
+ extensionWallet = ExtensionWallet.create(info, chainInfo, port, sharedKey, appId);
56
+ return Promise.resolve(extensionWallet.getWallet());
57
+ },
58
+ disconnect: async ()=>{
59
+ if (extensionWallet) {
60
+ await extensionWallet.disconnect();
61
+ extensionWallet = null;
62
+ }
63
+ },
64
+ onDisconnect: (callback)=>{
65
+ if (extensionWallet) {
66
+ return extensionWallet.onDisconnect(callback);
67
+ }
68
+ return ()=>{};
69
+ },
70
+ isDisconnected: ()=>{
71
+ if (extensionWallet) {
72
+ return extensionWallet.isDisconnected();
73
+ }
74
+ return true;
75
+ }
76
+ };
77
+ providers.push(provider);
55
78
  }
56
79
  }
57
80
  // TODO: Add web wallet discovery when implemented
@@ -1,5 +1,5 @@
1
1
  import type { ChainInfo } from '@aztec/aztec.js/account';
2
- import type { WalletInfo } from '../../types.js';
2
+ import { type WalletInfo } from '../../types.js';
3
3
  /**
4
4
  * A discovered wallet with its secure channel components.
5
5
  * Returned by {@link ExtensionProvider.discoverExtensions}.
@@ -60,4 +60,4 @@ export declare class ExtensionProvider {
60
60
  */
61
61
  static discoverExtensions(chainInfo: ChainInfo, timeout?: number): Promise<DiscoveredWallet[]>;
62
62
  }
63
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXh0ZW5zaW9uX3Byb3ZpZGVyLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvcHJvdmlkZXJzL2V4dGVuc2lvbi9leHRlbnNpb25fcHJvdmlkZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLEVBQUUsU0FBUyxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFLekQsT0FBTyxLQUFLLEVBQXVDLFVBQVUsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRXRGOzs7R0FHRztBQUNILE1BQU0sV0FBVyxnQkFBZ0I7SUFDL0Isc0ZBQXNGO0lBQ3RGLElBQUksRUFBRSxVQUFVLENBQUM7SUFDakIsZ0VBQWdFO0lBQ2hFLElBQUksRUFBRSxXQUFXLENBQUM7SUFDbEIsd0RBQXdEO0lBQ3hELFNBQVMsRUFBRSxTQUFTLENBQUM7Q0FDdEI7QUFXRDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FvQkc7QUFDSCxxQkFBYSxpQkFBaUI7SUFDNUIsT0FBTyxDQUFDLE1BQU0sQ0FBQyxtQkFBbUIsQ0FBUztJQUUzQzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztPQXNCRztJQUNILE9BQWEsa0JBQWtCLENBQUMsU0FBUyxFQUFFLFNBQVMsRUFBRSxPQUFPLEdBQUUsTUFBYSxHQUFHLE9BQU8sQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDLENBeUZ6RztDQUNGIn0=
63
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXh0ZW5zaW9uX3Byb3ZpZGVyLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvcHJvdmlkZXJzL2V4dGVuc2lvbi9leHRlbnNpb25fcHJvdmlkZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLEVBQUUsU0FBUyxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFLekQsT0FBTyxFQUFpRCxLQUFLLFVBQVUsRUFBcUIsTUFBTSxnQkFBZ0IsQ0FBQztBQUVuSDs7O0dBR0c7QUFDSCxNQUFNLFdBQVcsZ0JBQWdCO0lBQy9CLHNGQUFzRjtJQUN0RixJQUFJLEVBQUUsVUFBVSxDQUFDO0lBQ2pCLGdFQUFnRTtJQUNoRSxJQUFJLEVBQUUsV0FBVyxDQUFDO0lBQ2xCLHdEQUF3RDtJQUN4RCxTQUFTLEVBQUUsU0FBUyxDQUFDO0NBQ3RCO0FBV0Q7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBb0JHO0FBQ0gscUJBQWEsaUJBQWlCO0lBQzVCLE9BQU8sQ0FBQyxNQUFNLENBQUMsbUJBQW1CLENBQVM7SUFFM0M7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7T0FzQkc7SUFDSCxPQUFhLGtCQUFrQixDQUFDLFNBQVMsRUFBRSxTQUFTLEVBQUUsT0FBTyxHQUFFLE1BQWEsR0FBRyxPQUFPLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQyxDQXlGekc7Q0FDRiJ9
@@ -1 +1 @@
1
- {"version":3,"file":"extension_provider.d.ts","sourceRoot":"","sources":["../../../src/providers/extension/extension_provider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAKzD,OAAO,KAAK,EAAuC,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAEtF;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC/B,sFAAsF;IACtF,IAAI,EAAE,UAAU,CAAC;IACjB,gEAAgE;IAChE,IAAI,EAAE,WAAW,CAAC;IAClB,wDAAwD;IACxD,SAAS,EAAE,SAAS,CAAC;CACtB;AAWD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,MAAM,CAAC,mBAAmB,CAAS;IAE3C;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACH,OAAa,kBAAkB,CAAC,SAAS,EAAE,SAAS,EAAE,OAAO,GAAE,MAAa,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAyFzG;CACF"}
1
+ {"version":3,"file":"extension_provider.d.ts","sourceRoot":"","sources":["../../../src/providers/extension/extension_provider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAKzD,OAAO,EAAiD,KAAK,UAAU,EAAqB,MAAM,gBAAgB,CAAC;AAEnH;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC/B,sFAAsF;IACtF,IAAI,EAAE,UAAU,CAAC;IACjB,gEAAgE;IAChE,IAAI,EAAE,WAAW,CAAC;IAClB,wDAAwD;IACxD,SAAS,EAAE,SAAS,CAAC;CACtB;AAWD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,MAAM,CAAC,mBAAmB,CAAS;IAE3C;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACH,OAAa,kBAAkB,CAAC,SAAS,EAAE,SAAS,EAAE,OAAO,GAAE,MAAa,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAyFzG;CACF"}
@@ -1,6 +1,7 @@
1
1
  import { jsonStringify } from '@aztec/foundation/json-rpc';
2
2
  import { promiseWithResolvers } from '@aztec/foundation/promise';
3
3
  import { deriveSharedKey, exportPublicKey, generateKeyPair, hashSharedSecret, importPublicKey } from '../../crypto.js';
4
+ import { WalletMessageType } from '../../types.js';
4
5
  /**
5
6
  * Provider for discovering Aztec wallet extensions.
6
7
  *
@@ -70,7 +71,7 @@ import { deriveSharedKey, exportPublicKey, generateKeyPair, hashSharedSecret, im
70
71
  } catch {
71
72
  return;
72
73
  }
73
- if (data.type === 'aztec-wallet-discovery-response' && data.requestId === requestId) {
74
+ if (data.type === WalletMessageType.DISCOVERY_RESPONSE && data.requestId === requestId) {
74
75
  // Get the MessagePort from the event
75
76
  const port = event.ports?.[0];
76
77
  if (!port) {
@@ -106,7 +107,7 @@ import { deriveSharedKey, exportPublicKey, generateKeyPair, hashSharedSecret, im
106
107
  window.addEventListener('message', handleMessage);
107
108
  // Send discovery message with our public key
108
109
  const discoveryMessage = {
109
- type: 'aztec-wallet-discovery',
110
+ type: WalletMessageType.DISCOVERY,
110
111
  requestId,
111
112
  chainInfo,
112
113
  publicKey: exportedPublicKey
@@ -1,6 +1,10 @@
1
1
  import type { ChainInfo } from '@aztec/aztec.js/account';
2
2
  import { type Wallet } from '@aztec/aztec.js/wallet';
3
- import type { WalletInfo } from '../../types.js';
3
+ import { type WalletInfo } from '../../types.js';
4
+ /**
5
+ * Callback type for wallet disconnect events.
6
+ */
7
+ export type DisconnectCallback = () => void;
4
8
  /**
5
9
  * A wallet implementation that communicates with browser extension wallets
6
10
  * using a secure encrypted MessageChannel.
@@ -40,6 +44,8 @@ export declare class ExtensionWallet {
40
44
  private sharedKey;
41
45
  /** Map of pending requests awaiting responses, keyed by message ID */
42
46
  private inFlight;
47
+ private disconnected;
48
+ private disconnectCallbacks;
43
49
  /**
44
50
  * Private constructor - use {@link ExtensionWallet.create} to instantiate.
45
51
  * @param chainInfo - The chain information (chainId and version)
@@ -49,8 +55,10 @@ export declare class ExtensionWallet {
49
55
  * @param sharedKey - The derived AES-256-GCM shared key for encryption
50
56
  */
51
57
  private constructor();
58
+ /** Cached Wallet proxy instance */
59
+ private walletProxy;
52
60
  /**
53
- * Creates an ExtensionWallet instance that proxies wallet calls to a browser extension
61
+ * Creates an ExtensionWallet instance that communicates with a browser extension
54
62
  * over a secure encrypted MessageChannel.
55
63
  *
56
64
  * @param walletInfo - The wallet info from ExtensionProvider.discoverExtensions()
@@ -58,38 +66,90 @@ export declare class ExtensionWallet {
58
66
  * @param port - The MessagePort for private communication with the wallet
59
67
  * @param sharedKey - The derived AES-256-GCM shared key for encryption
60
68
  * @param appId - Application identifier used to identify the requesting dApp to the wallet
61
- * @returns A Promise resolving to a Wallet implementation that encrypts all communication
69
+ * @returns The ExtensionWallet instance. Use {@link getWallet} to get the Wallet interface.
62
70
  *
63
71
  * @example
64
72
  * ```typescript
65
73
  * const wallets = await ExtensionProvider.discoverExtensions(chainInfo);
66
74
  * const { info, port, sharedKey } = wallets[0];
67
- * const wallet = await ExtensionWallet.create(
75
+ * const extensionWallet = ExtensionWallet.create(
68
76
  * info,
69
77
  * { chainId: Fr(31337), version: Fr(0) },
70
78
  * port,
71
79
  * sharedKey,
72
80
  * 'my-defi-app'
73
81
  * );
82
+ *
83
+ * // Register disconnect handler
84
+ * extensionWallet.onDisconnect(() => console.log('Disconnected!'));
85
+ *
86
+ * // Get the Wallet interface for dApp usage
87
+ * const wallet = extensionWallet.getWallet();
88
+ * const accounts = await wallet.getAccounts();
74
89
  * ```
75
90
  */
76
- static create(walletInfo: WalletInfo, chainInfo: ChainInfo, port: MessagePort, sharedKey: CryptoKey, appId: string): Wallet;
91
+ static create(walletInfo: WalletInfo, chainInfo: ChainInfo, port: MessagePort, sharedKey: CryptoKey, appId: string): ExtensionWallet;
92
+ /**
93
+ * Returns a Wallet interface that proxies all method calls through the secure channel.
94
+ *
95
+ * The returned Wallet can be used directly by dApps - all method calls are automatically
96
+ * encrypted and sent to the wallet extension.
97
+ *
98
+ * @returns A Wallet implementation that encrypts all communication
99
+ *
100
+ * @example
101
+ * ```typescript
102
+ * const extensionWallet = ExtensionWallet.create(info, chainInfo, port, sharedKey, 'my-app');
103
+ * const wallet = extensionWallet.getWallet();
104
+ * const accounts = await wallet.getAccounts();
105
+ * ```
106
+ */
107
+ getWallet(): Wallet;
77
108
  private handleEncryptedResponse;
78
109
  private postMessage;
79
110
  /**
80
- * Closes the secure channel and cleans up resources.
111
+ * Handles wallet disconnection.
112
+ * Rejects all pending requests and notifies registered callbacks.
113
+ * @internal
114
+ */
115
+ private handleDisconnect;
116
+ /**
117
+ * Registers a callback to be invoked when the wallet disconnects.
81
118
  *
82
- * After calling this method, the wallet instance can no longer be used.
83
- * Any pending requests will not receive responses.
119
+ * @param callback - Function to call when wallet disconnects
120
+ * @returns A function to unregister the callback
84
121
  *
85
122
  * @example
86
123
  * ```typescript
87
- * const { info, port, sharedKey } = wallets[0];
88
- * const wallet = await ExtensionWallet.create(info, chainInfo, port, sharedKey, 'my-app');
124
+ * const wallet = await ExtensionWallet.create(...);
125
+ * const unsubscribe = wallet.onDisconnect(() => {
126
+ * console.log('Wallet disconnected! Please reconnect.');
127
+ * // Clean up UI, prompt user to reconnect, etc.
128
+ * });
129
+ * // Later: unsubscribe(); to stop receiving notifications
130
+ * ```
131
+ */
132
+ onDisconnect(callback: DisconnectCallback): () => void;
133
+ /**
134
+ * Returns whether the wallet has been disconnected.
135
+ *
136
+ * @returns true if the wallet is no longer connected
137
+ */
138
+ isDisconnected(): boolean;
139
+ /**
140
+ * Disconnects from the wallet and cleans up resources.
141
+ *
142
+ * This method notifies the wallet extension that the session is ending,
143
+ * allowing it to clean up its state. After calling this method, the wallet
144
+ * instance can no longer be used and any pending requests will be rejected.
145
+ *
146
+ * @example
147
+ * ```typescript
148
+ * const wallet = await provider.connect('my-app');
89
149
  * // ... use wallet ...
90
- * wallet.close(); // Clean up when done
150
+ * await wallet.disconnect(); // Clean disconnect when done
91
151
  * ```
92
152
  */
93
- close(): void;
153
+ disconnect(): Promise<void>;
94
154
  }
95
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXh0ZW5zaW9uX3dhbGxldC5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL3Byb3ZpZGVycy9leHRlbnNpb24vZXh0ZW5zaW9uX3dhbGxldC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssRUFBRSxTQUFTLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUN6RCxPQUFPLEVBQUUsS0FBSyxNQUFNLEVBQWdCLE1BQU0sd0JBQXdCLENBQUM7QUFPbkUsT0FBTyxLQUFLLEVBQUUsVUFBVSxFQUFpQyxNQUFNLGdCQUFnQixDQUFDO0FBYWhGOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0E4Qkc7QUFDSCxxQkFBYSxlQUFlO0lBYXhCLE9BQU8sQ0FBQyxTQUFTO0lBQ2pCLE9BQU8sQ0FBQyxLQUFLO0lBQ2IsT0FBTyxDQUFDLFdBQVc7SUFDbkIsT0FBTyxDQUFDLElBQUk7SUFDWixPQUFPLENBQUMsU0FBUztJQWhCbkIsc0VBQXNFO0lBQ3RFLE9BQU8sQ0FBQyxRQUFRLENBQW9EO0lBRXBFOzs7Ozs7O09BT0c7SUFDSCxPQUFPLGVBTUg7SUFFSjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7T0F1Qkc7SUFDSCxNQUFNLENBQUMsTUFBTSxDQUNYLFVBQVUsRUFBRSxVQUFVLEVBQ3RCLFNBQVMsRUFBRSxTQUFTLEVBQ3BCLElBQUksRUFBRSxXQUFXLEVBQ2pCLFNBQVMsRUFBRSxTQUFTLEVBQ3BCLEtBQUssRUFBRSxNQUFNLEdBQ1osTUFBTSxDQTBCUjtZQVVhLHVCQUF1QjtZQThDdkIsV0FBVztJQXdCekI7Ozs7Ozs7Ozs7Ozs7T0FhRztJQUNILEtBQUssSUFBSSxJQUFJLENBS1o7Q0FDRiJ9
155
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXh0ZW5zaW9uX3dhbGxldC5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL3Byb3ZpZGVycy9leHRlbnNpb24vZXh0ZW5zaW9uX3dhbGxldC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssRUFBRSxTQUFTLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUN6RCxPQUFPLEVBQUUsS0FBSyxNQUFNLEVBQWdCLE1BQU0sd0JBQXdCLENBQUM7QUFPbkUsT0FBTyxFQUFFLEtBQUssVUFBVSxFQUE4RCxNQUFNLGdCQUFnQixDQUFDO0FBYTdHOztHQUVHO0FBQ0gsTUFBTSxNQUFNLGtCQUFrQixHQUFHLE1BQU0sSUFBSSxDQUFDO0FBRTVDOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0E4Qkc7QUFDSCxxQkFBYSxlQUFlO0lBZXhCLE9BQU8sQ0FBQyxTQUFTO0lBQ2pCLE9BQU8sQ0FBQyxLQUFLO0lBQ2IsT0FBTyxDQUFDLFdBQVc7SUFDbkIsT0FBTyxDQUFDLElBQUk7SUFDWixPQUFPLENBQUMsU0FBUztJQWxCbkIsc0VBQXNFO0lBQ3RFLE9BQU8sQ0FBQyxRQUFRLENBQW9EO0lBQ3BFLE9BQU8sQ0FBQyxZQUFZLENBQVM7SUFDN0IsT0FBTyxDQUFDLG1CQUFtQixDQUE0QjtJQUV2RDs7Ozs7OztPQU9HO0lBQ0gsT0FBTyxlQU1IO0lBRUosbUNBQW1DO0lBQ25DLE9BQU8sQ0FBQyxXQUFXLENBQXVCO0lBRTFDOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7T0E4Qkc7SUFDSCxNQUFNLENBQUMsTUFBTSxDQUNYLFVBQVUsRUFBRSxVQUFVLEVBQ3RCLFNBQVMsRUFBRSxTQUFTLEVBQ3BCLElBQUksRUFBRSxXQUFXLEVBQ2pCLFNBQVMsRUFBRSxTQUFTLEVBQ3BCLEtBQUssRUFBRSxNQUFNLEdBQ1osZUFBZSxDQVdqQjtJQUVEOzs7Ozs7Ozs7Ozs7OztPQWNHO0lBQ0gsU0FBUyxJQUFJLE1BQU0sQ0F1QmxCO1lBVWEsdUJBQXVCO1lBMER2QixXQUFXO0lBMkJ6Qjs7OztPQUlHO0lBQ0gsT0FBTyxDQUFDLGdCQUFnQjtJQStCeEI7Ozs7Ozs7Ozs7Ozs7OztPQWVHO0lBQ0gsWUFBWSxDQUFDLFFBQVEsRUFBRSxrQkFBa0IsR0FBRyxNQUFNLElBQUksQ0FRckQ7SUFFRDs7OztPQUlHO0lBQ0gsY0FBYyxJQUFJLE9BQU8sQ0FFeEI7SUFFRDs7Ozs7Ozs7Ozs7OztPQWFHO0lBQ0csVUFBVSxJQUFJLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0EyQmhDO0NBQ0YifQ==
@@ -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;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"}
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,EAAE,KAAK,UAAU,EAA8D,MAAM,gBAAgB,CAAC;AAa7G;;GAEG;AACH,MAAM,MAAM,kBAAkB,GAAG,MAAM,IAAI,CAAC;AAE5C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,qBAAa,eAAe;IAexB,OAAO,CAAC,SAAS;IACjB,OAAO,CAAC,KAAK;IACb,OAAO,CAAC,WAAW;IACnB,OAAO,CAAC,IAAI;IACZ,OAAO,CAAC,SAAS;IAlBnB,sEAAsE;IACtE,OAAO,CAAC,QAAQ,CAAoD;IACpE,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,mBAAmB,CAA4B;IAEvD;;;;;;;OAOG;IACH,OAAO,eAMH;IAEJ,mCAAmC;IACnC,OAAO,CAAC,WAAW,CAAuB;IAE1C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA8BG;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,eAAe,CAWjB;IAED;;;;;;;;;;;;;;OAcG;IACH,SAAS,IAAI,MAAM,CAuBlB;YAUa,uBAAuB;YA0DvB,WAAW;IA2BzB;;;;OAIG;IACH,OAAO,CAAC,gBAAgB;IA+BxB;;;;;;;;;;;;;;;OAeG;IACH,YAAY,CAAC,QAAQ,EAAE,kBAAkB,GAAG,MAAM,IAAI,CAQrD;IAED;;;;OAIG;IACH,cAAc,IAAI,OAAO,CAExB;IAED;;;;;;;;;;;;;OAaG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CA2BhC;CACF"}
@@ -3,6 +3,7 @@ import { jsonStringify } from '@aztec/foundation/json-rpc';
3
3
  import { promiseWithResolvers } from '@aztec/foundation/promise';
4
4
  import { schemaHasMethod } from '@aztec/foundation/schemas';
5
5
  import { decrypt, encrypt } from '../../crypto.js';
6
+ import { WalletMessageType } from '../../types.js';
6
7
  /**
7
8
  * A wallet implementation that communicates with browser extension wallets
8
9
  * using a secure encrypted MessageChannel.
@@ -40,6 +41,8 @@ import { decrypt, encrypt } from '../../crypto.js';
40
41
  port;
41
42
  sharedKey;
42
43
  /** Map of pending requests awaiting responses, keyed by message ID */ inFlight;
44
+ disconnected;
45
+ disconnectCallbacks;
43
46
  /**
44
47
  * Private constructor - use {@link ExtensionWallet.create} to instantiate.
45
48
  * @param chainInfo - The chain information (chainId and version)
@@ -54,9 +57,13 @@ import { decrypt, encrypt } from '../../crypto.js';
54
57
  this.port = port;
55
58
  this.sharedKey = sharedKey;
56
59
  this.inFlight = new Map();
60
+ this.disconnected = false;
61
+ this.disconnectCallbacks = [];
62
+ this.walletProxy = null;
57
63
  }
64
+ /** Cached Wallet proxy instance */ walletProxy;
58
65
  /**
59
- * Creates an ExtensionWallet instance that proxies wallet calls to a browser extension
66
+ * Creates an ExtensionWallet instance that communicates with a browser extension
60
67
  * over a secure encrypted MessageChannel.
61
68
  *
62
69
  * @param walletInfo - The wallet info from ExtensionProvider.discoverExtensions()
@@ -64,29 +71,56 @@ import { decrypt, encrypt } from '../../crypto.js';
64
71
  * @param port - The MessagePort for private communication with the wallet
65
72
  * @param sharedKey - The derived AES-256-GCM shared key for encryption
66
73
  * @param appId - Application identifier used to identify the requesting dApp to the wallet
67
- * @returns A Promise resolving to a Wallet implementation that encrypts all communication
74
+ * @returns The ExtensionWallet instance. Use {@link getWallet} to get the Wallet interface.
68
75
  *
69
76
  * @example
70
77
  * ```typescript
71
78
  * const wallets = await ExtensionProvider.discoverExtensions(chainInfo);
72
79
  * const { info, port, sharedKey } = wallets[0];
73
- * const wallet = await ExtensionWallet.create(
80
+ * const extensionWallet = ExtensionWallet.create(
74
81
  * info,
75
82
  * { chainId: Fr(31337), version: Fr(0) },
76
83
  * port,
77
84
  * sharedKey,
78
85
  * 'my-defi-app'
79
86
  * );
87
+ *
88
+ * // Register disconnect handler
89
+ * extensionWallet.onDisconnect(() => console.log('Disconnected!'));
90
+ *
91
+ * // Get the Wallet interface for dApp usage
92
+ * const wallet = extensionWallet.getWallet();
93
+ * const accounts = await wallet.getAccounts();
80
94
  * ```
81
95
  */ static create(walletInfo, chainInfo, port, sharedKey, appId) {
82
96
  const wallet = new ExtensionWallet(chainInfo, appId, walletInfo.id, port, sharedKey);
83
- // Set up message handler
97
+ // Set up message handler - all messages are now encrypted
84
98
  wallet.port.onmessage = (event)=>{
85
99
  void wallet.handleEncryptedResponse(event.data);
86
100
  };
87
101
  wallet.port.start();
102
+ return wallet;
103
+ }
104
+ /**
105
+ * Returns a Wallet interface that proxies all method calls through the secure channel.
106
+ *
107
+ * The returned Wallet can be used directly by dApps - all method calls are automatically
108
+ * encrypted and sent to the wallet extension.
109
+ *
110
+ * @returns A Wallet implementation that encrypts all communication
111
+ *
112
+ * @example
113
+ * ```typescript
114
+ * const extensionWallet = ExtensionWallet.create(info, chainInfo, port, sharedKey, 'my-app');
115
+ * const wallet = extensionWallet.getWallet();
116
+ * const accounts = await wallet.getAccounts();
117
+ * ```
118
+ */ getWallet() {
119
+ if (this.walletProxy) {
120
+ return this.walletProxy;
121
+ }
88
122
  // Create a Proxy that intercepts wallet method calls and forwards them to the extension
89
- return new Proxy(wallet, {
123
+ this.walletProxy = new Proxy(this, {
90
124
  get: (target, prop)=>{
91
125
  if (schemaHasMethod(WalletSchema, prop.toString())) {
92
126
  return async (...args)=>{
@@ -101,6 +135,7 @@ import { decrypt, encrypt } from '../../crypto.js';
101
135
  }
102
136
  }
103
137
  });
138
+ return this.walletProxy;
104
139
  }
105
140
  /**
106
141
  * Handles an encrypted response received from the wallet extension.
@@ -116,6 +151,12 @@ import { decrypt, encrypt } from '../../crypto.js';
116
151
  try {
117
152
  const response = await decrypt(this.sharedKey, encrypted);
118
153
  const { messageId, result, error, walletId: responseWalletId } = response;
154
+ // Check for disconnect notification from the wallet backend
155
+ // This is sent as an encrypted error response with a special type
156
+ if (error && typeof error === 'object' && 'type' in error && error.type === WalletMessageType.SESSION_DISCONNECTED) {
157
+ this.handleDisconnect();
158
+ return;
159
+ }
119
160
  if (!messageId || !responseWalletId) {
120
161
  return;
121
162
  }
@@ -145,8 +186,11 @@ import { decrypt, encrypt } from '../../crypto.js';
145
186
  * @param call - The wallet method call containing method name and arguments
146
187
  * @returns A Promise that resolves with the decrypted result from the wallet
147
188
  *
148
- * @throws Error if the secure channel has not been established
189
+ * @throws Error if the secure channel has not been established or wallet is disconnected
149
190
  */ async postMessage(call) {
191
+ if (this.disconnected) {
192
+ throw new Error('Wallet has been disconnected');
193
+ }
150
194
  if (!this.port || !this.sharedKey) {
151
195
  throw new Error('Secure channel not established');
152
196
  }
@@ -171,22 +215,104 @@ import { decrypt, encrypt } from '../../crypto.js';
171
215
  return promise;
172
216
  }
173
217
  /**
174
- * Closes the secure channel and cleans up resources.
218
+ * Handles wallet disconnection.
219
+ * Rejects all pending requests and notifies registered callbacks.
220
+ * @internal
221
+ */ handleDisconnect() {
222
+ if (this.disconnected) {
223
+ return;
224
+ }
225
+ this.disconnected = true;
226
+ // Close the port to prevent any further messages
227
+ if (this.port) {
228
+ this.port.onmessage = null;
229
+ this.port.close();
230
+ }
231
+ // Reject all pending requests
232
+ // Note: These rejections should be caught by the callers, but we log them
233
+ // here to help with debugging if they become unhandled
234
+ const error = new Error('Wallet disconnected');
235
+ for (const { reject } of this.inFlight.values()){
236
+ reject(error);
237
+ }
238
+ this.inFlight.clear();
239
+ // Notify registered callbacks
240
+ for (const callback of this.disconnectCallbacks){
241
+ try {
242
+ callback();
243
+ } catch {
244
+ // Ignore errors in callbacks
245
+ }
246
+ }
247
+ }
248
+ /**
249
+ * Registers a callback to be invoked when the wallet disconnects.
175
250
  *
176
- * After calling this method, the wallet instance can no longer be used.
177
- * Any pending requests will not receive responses.
251
+ * @param callback - Function to call when wallet disconnects
252
+ * @returns A function to unregister the callback
178
253
  *
179
254
  * @example
180
255
  * ```typescript
181
- * const { info, port, sharedKey } = wallets[0];
182
- * const wallet = await ExtensionWallet.create(info, chainInfo, port, sharedKey, 'my-app');
256
+ * const wallet = await ExtensionWallet.create(...);
257
+ * const unsubscribe = wallet.onDisconnect(() => {
258
+ * console.log('Wallet disconnected! Please reconnect.');
259
+ * // Clean up UI, prompt user to reconnect, etc.
260
+ * });
261
+ * // Later: unsubscribe(); to stop receiving notifications
262
+ * ```
263
+ */ onDisconnect(callback) {
264
+ this.disconnectCallbacks.push(callback);
265
+ return ()=>{
266
+ const index = this.disconnectCallbacks.indexOf(callback);
267
+ if (index !== -1) {
268
+ this.disconnectCallbacks.splice(index, 1);
269
+ }
270
+ };
271
+ }
272
+ /**
273
+ * Returns whether the wallet has been disconnected.
274
+ *
275
+ * @returns true if the wallet is no longer connected
276
+ */ isDisconnected() {
277
+ return this.disconnected;
278
+ }
279
+ /**
280
+ * Disconnects from the wallet and cleans up resources.
281
+ *
282
+ * This method notifies the wallet extension that the session is ending,
283
+ * allowing it to clean up its state. After calling this method, the wallet
284
+ * instance can no longer be used and any pending requests will be rejected.
285
+ *
286
+ * @example
287
+ * ```typescript
288
+ * const wallet = await provider.connect('my-app');
183
289
  * // ... use wallet ...
184
- * wallet.close(); // Clean up when done
290
+ * await wallet.disconnect(); // Clean disconnect when done
185
291
  * ```
186
- */ close() {
292
+ */ async disconnect() {
293
+ if (this.disconnected) {
294
+ return;
295
+ }
296
+ // Send disconnect message to extension before closing
297
+ if (this.port && this.sharedKey) {
298
+ try {
299
+ const message = {
300
+ type: WalletMessageType.DISCONNECT,
301
+ messageId: globalThis.crypto.randomUUID(),
302
+ chainInfo: this.chainInfo,
303
+ appId: this.appId,
304
+ walletId: this.extensionId,
305
+ args: []
306
+ };
307
+ const encrypted = await encrypt(this.sharedKey, message);
308
+ this.port.postMessage(encrypted);
309
+ } catch {
310
+ // Ignore errors sending disconnect message
311
+ }
312
+ }
313
+ this.handleDisconnect();
187
314
  if (this.port) {
188
315
  this.port.close();
189
316
  }
190
- this.inFlight.clear();
191
317
  }
192
318
  }
@@ -1,5 +1,6 @@
1
- export { ExtensionWallet } from './extension_wallet.js';
1
+ export { ExtensionWallet, type DisconnectCallback } from './extension_wallet.js';
2
2
  export { ExtensionProvider, type DiscoveredWallet } from './extension_provider.js';
3
3
  export * from '../../crypto.js';
4
+ export { WalletMessageType } from '../../types.js';
4
5
  export type { WalletInfo, WalletMessage, WalletResponse, DiscoveryRequest, DiscoveryResponse } from '../../types.js';
5
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9wcm92aWRlcnMvZXh0ZW5zaW9uL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUN4RCxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsS0FBSyxnQkFBZ0IsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQ25GLGNBQWMsaUJBQWlCLENBQUM7QUFDaEMsWUFBWSxFQUFFLFVBQVUsRUFBRSxhQUFhLEVBQUUsY0FBYyxFQUFFLGdCQUFnQixFQUFFLGlCQUFpQixFQUFFLE1BQU0sZ0JBQWdCLENBQUMifQ==
6
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9wcm92aWRlcnMvZXh0ZW5zaW9uL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxlQUFlLEVBQUUsS0FBSyxrQkFBa0IsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBQ2pGLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxLQUFLLGdCQUFnQixFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDbkYsY0FBYyxpQkFBaUIsQ0FBQztBQUNoQyxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUNuRCxZQUFZLEVBQUUsVUFBVSxFQUFFLGFBQWEsRUFBRSxjQUFjLEVBQUUsZ0JBQWdCLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQyJ9
@@ -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,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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/providers/extension/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,KAAK,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AACjF,OAAO,EAAE,iBAAiB,EAAE,KAAK,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AACnF,cAAc,iBAAiB,CAAC;AAChC,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACnD,YAAY,EAAE,UAAU,EAAE,aAAa,EAAE,cAAc,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC"}
@@ -1,3 +1,4 @@
1
1
  export { ExtensionWallet } from './extension_wallet.js';
2
2
  export { ExtensionProvider } from './extension_provider.js';
3
3
  export * from '../../crypto.js';
4
+ export { WalletMessageType } from '../../types.js';
package/dest/types.d.ts CHANGED
@@ -1,5 +1,19 @@
1
1
  import type { ChainInfo } from '@aztec/aztec.js/account';
2
2
  import type { ExportedPublicKey } from './crypto.js';
3
+ /**
4
+ * Message types for wallet SDK communication.
5
+ * All types are prefixed with 'aztec-wallet-' for namespacing.
6
+ */
7
+ export declare enum WalletMessageType {
8
+ /** Discovery request to find installed wallets */
9
+ DISCOVERY = "aztec-wallet-discovery",
10
+ /** Discovery response from a wallet */
11
+ DISCOVERY_RESPONSE = "aztec-wallet-discovery-response",
12
+ /** Session disconnected notification (unencrypted control message) */
13
+ SESSION_DISCONNECTED = "aztec-wallet-session-disconnected",
14
+ /** Explicit disconnect request from dApp */
15
+ DISCONNECT = "aztec-wallet-disconnect"
16
+ }
3
17
  /**
4
18
  * Information about an installed Aztec wallet
5
19
  */
@@ -56,7 +70,7 @@ export interface WalletResponse {
56
70
  */
57
71
  export interface DiscoveryRequest {
58
72
  /** Message type for discovery */
59
- type: 'aztec-wallet-discovery';
73
+ type: WalletMessageType.DISCOVERY;
60
74
  /** Request ID */
61
75
  requestId: string;
62
76
  /** Chain information to check if wallet supports this network */
@@ -69,10 +83,10 @@ export interface DiscoveryRequest {
69
83
  */
70
84
  export interface DiscoveryResponse {
71
85
  /** Message type for discovery response */
72
- type: 'aztec-wallet-discovery-response';
86
+ type: WalletMessageType.DISCOVERY_RESPONSE;
73
87
  /** Request ID matching the discovery request */
74
88
  requestId: string;
75
89
  /** Wallet information */
76
90
  walletInfo: WalletInfo;
77
91
  }
78
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy90eXBlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssRUFBRSxTQUFTLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUV6RCxPQUFPLEtBQUssRUFBRSxpQkFBaUIsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUVyRDs7R0FFRztBQUNILE1BQU0sV0FBVyxVQUFVO0lBQ3pCLHVDQUF1QztJQUN2QyxFQUFFLEVBQUUsTUFBTSxDQUFDO0lBQ1gsaUNBQWlDO0lBQ2pDLElBQUksRUFBRSxNQUFNLENBQUM7SUFDYiwrQkFBK0I7SUFDL0IsSUFBSSxDQUFDLEVBQUUsTUFBTSxDQUFDO0lBQ2QscUJBQXFCO0lBQ3JCLE9BQU8sRUFBRSxNQUFNLENBQUM7SUFDaEIsZ0VBQWdFO0lBQ2hFLFNBQVMsRUFBRSxpQkFBaUIsQ0FBQztJQUM3Qjs7OztPQUlHO0lBQ0gsZ0JBQWdCLENBQUMsRUFBRSxNQUFNLENBQUM7Q0FDM0I7QUFFRDs7R0FFRztBQUNILE1BQU0sV0FBVyxhQUFhO0lBQzVCLCtDQUErQztJQUMvQyxTQUFTLEVBQUUsTUFBTSxDQUFDO0lBQ2xCLGdDQUFnQztJQUNoQyxJQUFJLEVBQUUsTUFBTSxDQUFDO0lBQ2IsK0JBQStCO0lBQy9CLElBQUksRUFBRSxPQUFPLEVBQUUsQ0FBQztJQUNoQix3QkFBd0I7SUFDeEIsU0FBUyxFQUFFLFNBQVMsQ0FBQztJQUNyQix3Q0FBd0M7SUFDeEMsS0FBSyxFQUFFLE1BQU0sQ0FBQztJQUNkLDRDQUE0QztJQUM1QyxRQUFRLEVBQUUsTUFBTSxDQUFDO0NBQ2xCO0FBRUQ7O0dBRUc7QUFDSCxNQUFNLFdBQVcsY0FBYztJQUM3QixzQ0FBc0M7SUFDdEMsU0FBUyxFQUFFLE1BQU0sQ0FBQztJQUNsQixrQ0FBa0M7SUFDbEMsTUFBTSxDQUFDLEVBQUUsT0FBTyxDQUFDO0lBQ2pCLDZCQUE2QjtJQUM3QixLQUFLLENBQUMsRUFBRSxPQUFPLENBQUM7SUFDaEIsdUNBQXVDO0lBQ3ZDLFFBQVEsRUFBRSxNQUFNLENBQUM7Q0FDbEI7QUFFRDs7R0FFRztBQUNILE1BQU0sV0FBVyxnQkFBZ0I7SUFDL0IsaUNBQWlDO0lBQ2pDLElBQUksRUFBRSx3QkFBd0IsQ0FBQztJQUMvQixpQkFBaUI7SUFDakIsU0FBUyxFQUFFLE1BQU0sQ0FBQztJQUNsQixpRUFBaUU7SUFDakUsU0FBUyxFQUFFLFNBQVMsQ0FBQztJQUNyQix3REFBd0Q7SUFDeEQsU0FBUyxFQUFFLGlCQUFpQixDQUFDO0NBQzlCO0FBRUQ7O0dBRUc7QUFDSCxNQUFNLFdBQVcsaUJBQWlCO0lBQ2hDLDBDQUEwQztJQUMxQyxJQUFJLEVBQUUsaUNBQWlDLENBQUM7SUFDeEMsZ0RBQWdEO0lBQ2hELFNBQVMsRUFBRSxNQUFNLENBQUM7SUFDbEIseUJBQXlCO0lBQ3pCLFVBQVUsRUFBRSxVQUFVLENBQUM7Q0FDeEIifQ==
92
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy90eXBlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssRUFBRSxTQUFTLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUV6RCxPQUFPLEtBQUssRUFBRSxpQkFBaUIsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUVyRDs7O0dBR0c7QUFDSCxvQkFBWSxpQkFBaUI7SUFDM0Isa0RBQWtEO0lBQ2xELFNBQVMsMkJBQTJCO0lBQ3BDLHVDQUF1QztJQUN2QyxrQkFBa0Isb0NBQW9DO0lBQ3RELHNFQUFzRTtJQUN0RSxvQkFBb0Isc0NBQXNDO0lBQzFELDRDQUE0QztJQUM1QyxVQUFVLDRCQUE0QjtDQUN2QztBQUVEOztHQUVHO0FBQ0gsTUFBTSxXQUFXLFVBQVU7SUFDekIsdUNBQXVDO0lBQ3ZDLEVBQUUsRUFBRSxNQUFNLENBQUM7SUFDWCxpQ0FBaUM7SUFDakMsSUFBSSxFQUFFLE1BQU0sQ0FBQztJQUNiLCtCQUErQjtJQUMvQixJQUFJLENBQUMsRUFBRSxNQUFNLENBQUM7SUFDZCxxQkFBcUI7SUFDckIsT0FBTyxFQUFFLE1BQU0sQ0FBQztJQUNoQixnRUFBZ0U7SUFDaEUsU0FBUyxFQUFFLGlCQUFpQixDQUFDO0lBQzdCOzs7O09BSUc7SUFDSCxnQkFBZ0IsQ0FBQyxFQUFFLE1BQU0sQ0FBQztDQUMzQjtBQUVEOztHQUVHO0FBQ0gsTUFBTSxXQUFXLGFBQWE7SUFDNUIsK0NBQStDO0lBQy9DLFNBQVMsRUFBRSxNQUFNLENBQUM7SUFDbEIsZ0NBQWdDO0lBQ2hDLElBQUksRUFBRSxNQUFNLENBQUM7SUFDYiwrQkFBK0I7SUFDL0IsSUFBSSxFQUFFLE9BQU8sRUFBRSxDQUFDO0lBQ2hCLHdCQUF3QjtJQUN4QixTQUFTLEVBQUUsU0FBUyxDQUFDO0lBQ3JCLHdDQUF3QztJQUN4QyxLQUFLLEVBQUUsTUFBTSxDQUFDO0lBQ2QsNENBQTRDO0lBQzVDLFFBQVEsRUFBRSxNQUFNLENBQUM7Q0FDbEI7QUFFRDs7R0FFRztBQUNILE1BQU0sV0FBVyxjQUFjO0lBQzdCLHNDQUFzQztJQUN0QyxTQUFTLEVBQUUsTUFBTSxDQUFDO0lBQ2xCLGtDQUFrQztJQUNsQyxNQUFNLENBQUMsRUFBRSxPQUFPLENBQUM7SUFDakIsNkJBQTZCO0lBQzdCLEtBQUssQ0FBQyxFQUFFLE9BQU8sQ0FBQztJQUNoQix1Q0FBdUM7SUFDdkMsUUFBUSxFQUFFLE1BQU0sQ0FBQztDQUNsQjtBQUVEOztHQUVHO0FBQ0gsTUFBTSxXQUFXLGdCQUFnQjtJQUMvQixpQ0FBaUM7SUFDakMsSUFBSSxFQUFFLGlCQUFpQixDQUFDLFNBQVMsQ0FBQztJQUNsQyxpQkFBaUI7SUFDakIsU0FBUyxFQUFFLE1BQU0sQ0FBQztJQUNsQixpRUFBaUU7SUFDakUsU0FBUyxFQUFFLFNBQVMsQ0FBQztJQUNyQix3REFBd0Q7SUFDeEQsU0FBUyxFQUFFLGlCQUFpQixDQUFDO0NBQzlCO0FBRUQ7O0dBRUc7QUFDSCxNQUFNLFdBQVcsaUJBQWlCO0lBQ2hDLDBDQUEwQztJQUMxQyxJQUFJLEVBQUUsaUJBQWlCLENBQUMsa0JBQWtCLENBQUM7SUFDM0MsZ0RBQWdEO0lBQ2hELFNBQVMsRUFBRSxNQUFNLENBQUM7SUFDbEIseUJBQXlCO0lBQ3pCLFVBQVUsRUFBRSxVQUFVLENBQUM7Q0FDeEIifQ==
@@ -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;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"}
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;;;GAGG;AACH,oBAAY,iBAAiB;IAC3B,kDAAkD;IAClD,SAAS,2BAA2B;IACpC,uCAAuC;IACvC,kBAAkB,oCAAoC;IACtD,sEAAsE;IACtE,oBAAoB,sCAAsC;IAC1D,4CAA4C;IAC5C,UAAU,4BAA4B;CACvC;AAED;;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,iBAAiB,CAAC,SAAS,CAAC;IAClC,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,iBAAiB,CAAC,kBAAkB,CAAC;IAC3C,gDAAgD;IAChD,SAAS,EAAE,MAAM,CAAC;IAClB,yBAAyB;IACzB,UAAU,EAAE,UAAU,CAAC;CACxB"}
package/dest/types.js CHANGED
@@ -1,3 +1,10 @@
1
1
  /**
2
- * Discovery response from a wallet (public, unencrypted)
3
- */ export { };
2
+ * Message types for wallet SDK communication.
3
+ * All types are prefixed with 'aztec-wallet-' for namespacing.
4
+ */ export var WalletMessageType = /*#__PURE__*/ function(WalletMessageType) {
5
+ /** Discovery request to find installed wallets */ WalletMessageType["DISCOVERY"] = "aztec-wallet-discovery";
6
+ /** Discovery response from a wallet */ WalletMessageType["DISCOVERY_RESPONSE"] = "aztec-wallet-discovery-response";
7
+ /** Session disconnected notification (unencrypted control message) */ WalletMessageType["SESSION_DISCONNECTED"] = "aztec-wallet-session-disconnected";
8
+ /** Explicit disconnect request from dApp */ WalletMessageType["DISCONNECT"] = "aztec-wallet-disconnect";
9
+ return WalletMessageType;
10
+ }({});
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.20260115",
4
+ "version": "4.0.0-nightly.20260116",
5
5
  "type": "module",
6
6
  "exports": {
7
7
  "./base-wallet": "./dest/base-wallet/index.js",
@@ -64,15 +64,15 @@
64
64
  ]
65
65
  },
66
66
  "dependencies": {
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"
67
+ "@aztec/aztec.js": "4.0.0-nightly.20260116",
68
+ "@aztec/constants": "4.0.0-nightly.20260116",
69
+ "@aztec/entrypoints": "4.0.0-nightly.20260116",
70
+ "@aztec/foundation": "4.0.0-nightly.20260116",
71
+ "@aztec/pxe": "4.0.0-nightly.20260116",
72
+ "@aztec/stdlib": "4.0.0-nightly.20260116"
73
73
  },
74
74
  "devDependencies": {
75
- "@aztec/noir-contracts.js": "4.0.0-nightly.20260115",
75
+ "@aztec/noir-contracts.js": "4.0.0-nightly.20260116",
76
76
  "@jest/globals": "^30.0.0",
77
77
  "@types/jest": "^30.0.0",
78
78
  "@types/node": "^22.15.17",
@@ -5,10 +5,12 @@ export type {
5
5
  WebWalletConfig,
6
6
  WalletProviderType,
7
7
  WalletProvider,
8
+ ProviderDisconnectionCallback,
8
9
  DiscoverWalletsOptions,
9
10
  } from './types.js';
10
11
 
11
- // Re-export types from providers for convenience
12
+ // Re-export types and enums from providers for convenience
13
+ export { WalletMessageType } from '../types.js';
12
14
  export type { WalletInfo, WalletMessage, WalletResponse, DiscoveryRequest, DiscoveryResponse } from '../types.js';
13
15
 
14
16
  // Re-export commonly needed utilities for wallet integration
@@ -36,6 +36,11 @@ export interface WalletManagerConfig {
36
36
  */
37
37
  export type WalletProviderType = 'extension' | 'web' | 'embedded';
38
38
 
39
+ /**
40
+ * Callback type for wallet disconnect events at the provider level.
41
+ */
42
+ export type ProviderDisconnectionCallback = () => void;
43
+
39
44
  /**
40
45
  * A wallet provider that can connect to create a wallet instance.
41
46
  * Chain information is already baked in from the discovery process.
@@ -56,6 +61,23 @@ export interface WalletProvider {
56
61
  * @param appId - Application identifier for the requesting dapp
57
62
  */
58
63
  connect(appId: string): Promise<Wallet>;
64
+ /**
65
+ * Disconnects the current wallet and cleans up resources.
66
+ * After calling this, the wallet returned from connect() should no longer be used.
67
+ * @returns A promise that resolves when disconnection is complete
68
+ */
69
+ disconnect?(): Promise<void>;
70
+ /**
71
+ * Registers a callback to be invoked when the wallet disconnects unexpectedly.
72
+ * @param callback - Function to call when wallet disconnects
73
+ * @returns A function to unregister the callback
74
+ */
75
+ onDisconnect?(callback: ProviderDisconnectionCallback): () => void;
76
+ /**
77
+ * Returns whether the provider's wallet connection has been disconnected.
78
+ * @returns true if the wallet is no longer connected
79
+ */
80
+ isDisconnected?(): boolean;
59
81
  }
60
82
 
61
83
  /**
@@ -1,5 +1,11 @@
1
1
  import { ExtensionProvider, ExtensionWallet } from '../providers/extension/index.js';
2
- import type { DiscoverWalletsOptions, ExtensionWalletConfig, WalletManagerConfig, WalletProvider } from './types.js';
2
+ import type {
3
+ DiscoverWalletsOptions,
4
+ ExtensionWalletConfig,
5
+ ProviderDisconnectionCallback,
6
+ WalletManagerConfig,
7
+ WalletProvider,
8
+ } from './types.js';
3
9
 
4
10
  /**
5
11
  * Manager for wallet discovery, configuration, and connection
@@ -44,7 +50,9 @@ export class WalletManager {
44
50
  continue;
45
51
  }
46
52
 
47
- providers.push({
53
+ let extensionWallet: ExtensionWallet | null = null;
54
+
55
+ const provider: WalletProvider = {
48
56
  id: info.id,
49
57
  type: 'extension',
50
58
  name: info.name,
@@ -53,8 +61,31 @@ export class WalletManager {
53
61
  version: info.version,
54
62
  verificationHash: info.verificationHash,
55
63
  },
56
- connect: (appId: string) => Promise.resolve(ExtensionWallet.create(info, chainInfo, port, sharedKey, appId)),
57
- });
64
+ connect: (appId: string) => {
65
+ extensionWallet = ExtensionWallet.create(info, chainInfo, port, sharedKey, appId);
66
+ return Promise.resolve(extensionWallet.getWallet());
67
+ },
68
+ disconnect: async () => {
69
+ if (extensionWallet) {
70
+ await extensionWallet.disconnect();
71
+ extensionWallet = null;
72
+ }
73
+ },
74
+ onDisconnect: (callback: ProviderDisconnectionCallback) => {
75
+ if (extensionWallet) {
76
+ return extensionWallet.onDisconnect(callback);
77
+ }
78
+ return () => {};
79
+ },
80
+ isDisconnected: () => {
81
+ if (extensionWallet) {
82
+ return extensionWallet.isDisconnected();
83
+ }
84
+ return true;
85
+ },
86
+ };
87
+
88
+ providers.push(provider);
58
89
  }
59
90
  }
60
91
 
@@ -3,7 +3,7 @@ import { jsonStringify } from '@aztec/foundation/json-rpc';
3
3
  import { promiseWithResolvers } from '@aztec/foundation/promise';
4
4
 
5
5
  import { deriveSharedKey, exportPublicKey, generateKeyPair, hashSharedSecret, importPublicKey } from '../../crypto.js';
6
- import type { DiscoveryRequest, DiscoveryResponse, WalletInfo } from '../../types.js';
6
+ import { type DiscoveryRequest, type DiscoveryResponse, type WalletInfo, WalletMessageType } from '../../types.js';
7
7
 
8
8
  /**
9
9
  * A discovered wallet with its secure channel components.
@@ -105,7 +105,7 @@ export class ExtensionProvider {
105
105
  return;
106
106
  }
107
107
 
108
- if (data.type === 'aztec-wallet-discovery-response' && data.requestId === requestId) {
108
+ if (data.type === WalletMessageType.DISCOVERY_RESPONSE && data.requestId === requestId) {
109
109
  // Get the MessagePort from the event
110
110
  const port = event.ports?.[0];
111
111
  if (!port) {
@@ -148,7 +148,7 @@ export class ExtensionProvider {
148
148
 
149
149
  // Send discovery message with our public key
150
150
  const discoveryMessage: DiscoveryRequest = {
151
- type: 'aztec-wallet-discovery',
151
+ type: WalletMessageType.DISCOVERY,
152
152
  requestId,
153
153
  chainInfo,
154
154
  publicKey: exportedPublicKey,
@@ -6,7 +6,7 @@ import { schemaHasMethod } from '@aztec/foundation/schemas';
6
6
  import type { FunctionsOf } from '@aztec/foundation/types';
7
7
 
8
8
  import { type EncryptedPayload, decrypt, encrypt } from '../../crypto.js';
9
- import type { WalletInfo, WalletMessage, WalletResponse } from '../../types.js';
9
+ import { type WalletInfo, type WalletMessage, WalletMessageType, type WalletResponse } from '../../types.js';
10
10
 
11
11
  /**
12
12
  * Internal type representing a wallet method call before encryption.
@@ -19,6 +19,11 @@ type WalletMethodCall = {
19
19
  args: unknown[];
20
20
  };
21
21
 
22
+ /**
23
+ * Callback type for wallet disconnect events.
24
+ */
25
+ export type DisconnectCallback = () => void;
26
+
22
27
  /**
23
28
  * A wallet implementation that communicates with browser extension wallets
24
29
  * using a secure encrypted MessageChannel.
@@ -53,6 +58,8 @@ type WalletMethodCall = {
53
58
  export class ExtensionWallet {
54
59
  /** Map of pending requests awaiting responses, keyed by message ID */
55
60
  private inFlight = new Map<string, PromiseWithResolvers<unknown>>();
61
+ private disconnected = false;
62
+ private disconnectCallbacks: DisconnectCallback[] = [];
56
63
 
57
64
  /**
58
65
  * Private constructor - use {@link ExtensionWallet.create} to instantiate.
@@ -70,8 +77,11 @@ export class ExtensionWallet {
70
77
  private sharedKey: CryptoKey,
71
78
  ) {}
72
79
 
80
+ /** Cached Wallet proxy instance */
81
+ private walletProxy: Wallet | null = null;
82
+
73
83
  /**
74
- * Creates an ExtensionWallet instance that proxies wallet calls to a browser extension
84
+ * Creates an ExtensionWallet instance that communicates with a browser extension
75
85
  * over a secure encrypted MessageChannel.
76
86
  *
77
87
  * @param walletInfo - The wallet info from ExtensionProvider.discoverExtensions()
@@ -79,19 +89,26 @@ export class ExtensionWallet {
79
89
  * @param port - The MessagePort for private communication with the wallet
80
90
  * @param sharedKey - The derived AES-256-GCM shared key for encryption
81
91
  * @param appId - Application identifier used to identify the requesting dApp to the wallet
82
- * @returns A Promise resolving to a Wallet implementation that encrypts all communication
92
+ * @returns The ExtensionWallet instance. Use {@link getWallet} to get the Wallet interface.
83
93
  *
84
94
  * @example
85
95
  * ```typescript
86
96
  * const wallets = await ExtensionProvider.discoverExtensions(chainInfo);
87
97
  * const { info, port, sharedKey } = wallets[0];
88
- * const wallet = await ExtensionWallet.create(
98
+ * const extensionWallet = ExtensionWallet.create(
89
99
  * info,
90
100
  * { chainId: Fr(31337), version: Fr(0) },
91
101
  * port,
92
102
  * sharedKey,
93
103
  * 'my-defi-app'
94
104
  * );
105
+ *
106
+ * // Register disconnect handler
107
+ * extensionWallet.onDisconnect(() => console.log('Disconnected!'));
108
+ *
109
+ * // Get the Wallet interface for dApp usage
110
+ * const wallet = extensionWallet.getWallet();
111
+ * const accounts = await wallet.getAccounts();
95
112
  * ```
96
113
  */
97
114
  static create(
@@ -100,18 +117,41 @@ export class ExtensionWallet {
100
117
  port: MessagePort,
101
118
  sharedKey: CryptoKey,
102
119
  appId: string,
103
- ): Wallet {
120
+ ): ExtensionWallet {
104
121
  const wallet = new ExtensionWallet(chainInfo, appId, walletInfo.id, port, sharedKey);
105
122
 
106
- // Set up message handler
123
+ // Set up message handler - all messages are now encrypted
107
124
  wallet.port.onmessage = (event: MessageEvent<EncryptedPayload>) => {
108
125
  void wallet.handleEncryptedResponse(event.data);
109
126
  };
110
127
 
111
128
  wallet.port.start();
112
129
 
130
+ return wallet;
131
+ }
132
+
133
+ /**
134
+ * Returns a Wallet interface that proxies all method calls through the secure channel.
135
+ *
136
+ * The returned Wallet can be used directly by dApps - all method calls are automatically
137
+ * encrypted and sent to the wallet extension.
138
+ *
139
+ * @returns A Wallet implementation that encrypts all communication
140
+ *
141
+ * @example
142
+ * ```typescript
143
+ * const extensionWallet = ExtensionWallet.create(info, chainInfo, port, sharedKey, 'my-app');
144
+ * const wallet = extensionWallet.getWallet();
145
+ * const accounts = await wallet.getAccounts();
146
+ * ```
147
+ */
148
+ getWallet(): Wallet {
149
+ if (this.walletProxy) {
150
+ return this.walletProxy;
151
+ }
152
+
113
153
  // Create a Proxy that intercepts wallet method calls and forwards them to the extension
114
- return new Proxy(wallet, {
154
+ this.walletProxy = new Proxy(this, {
115
155
  get: (target, prop) => {
116
156
  if (schemaHasMethod(WalletSchema, prop.toString())) {
117
157
  return async (...args: unknown[]) => {
@@ -126,6 +166,8 @@ export class ExtensionWallet {
126
166
  }
127
167
  },
128
168
  }) as unknown as Wallet;
169
+
170
+ return this.walletProxy;
129
171
  }
130
172
 
131
173
  /**
@@ -146,6 +188,18 @@ export class ExtensionWallet {
146
188
 
147
189
  const { messageId, result, error, walletId: responseWalletId } = response;
148
190
 
191
+ // Check for disconnect notification from the wallet backend
192
+ // This is sent as an encrypted error response with a special type
193
+ if (
194
+ error &&
195
+ typeof error === 'object' &&
196
+ 'type' in error &&
197
+ (error.type as WalletMessageType) === WalletMessageType.SESSION_DISCONNECTED
198
+ ) {
199
+ this.handleDisconnect();
200
+ return;
201
+ }
202
+
149
203
  if (!messageId || !responseWalletId) {
150
204
  return;
151
205
  }
@@ -180,9 +234,12 @@ export class ExtensionWallet {
180
234
  * @param call - The wallet method call containing method name and arguments
181
235
  * @returns A Promise that resolves with the decrypted result from the wallet
182
236
  *
183
- * @throws Error if the secure channel has not been established
237
+ * @throws Error if the secure channel has not been established or wallet is disconnected
184
238
  */
185
239
  private async postMessage(call: WalletMethodCall): Promise<unknown> {
240
+ if (this.disconnected) {
241
+ throw new Error('Wallet has been disconnected');
242
+ }
186
243
  if (!this.port || !this.sharedKey) {
187
244
  throw new Error('Secure channel not established');
188
245
  }
@@ -207,23 +264,116 @@ export class ExtensionWallet {
207
264
  }
208
265
 
209
266
  /**
210
- * Closes the secure channel and cleans up resources.
267
+ * Handles wallet disconnection.
268
+ * Rejects all pending requests and notifies registered callbacks.
269
+ * @internal
270
+ */
271
+ private handleDisconnect(): void {
272
+ if (this.disconnected) {
273
+ return;
274
+ }
275
+ this.disconnected = true;
276
+
277
+ // Close the port to prevent any further messages
278
+ if (this.port) {
279
+ this.port.onmessage = null;
280
+ this.port.close();
281
+ }
282
+
283
+ // Reject all pending requests
284
+ // Note: These rejections should be caught by the callers, but we log them
285
+ // here to help with debugging if they become unhandled
286
+ const error = new Error('Wallet disconnected');
287
+ for (const { reject } of this.inFlight.values()) {
288
+ reject(error);
289
+ }
290
+ this.inFlight.clear();
291
+
292
+ // Notify registered callbacks
293
+ for (const callback of this.disconnectCallbacks) {
294
+ try {
295
+ callback();
296
+ } catch {
297
+ // Ignore errors in callbacks
298
+ }
299
+ }
300
+ }
301
+
302
+ /**
303
+ * Registers a callback to be invoked when the wallet disconnects.
211
304
  *
212
- * After calling this method, the wallet instance can no longer be used.
213
- * Any pending requests will not receive responses.
305
+ * @param callback - Function to call when wallet disconnects
306
+ * @returns A function to unregister the callback
214
307
  *
215
308
  * @example
216
309
  * ```typescript
217
- * const { info, port, sharedKey } = wallets[0];
218
- * const wallet = await ExtensionWallet.create(info, chainInfo, port, sharedKey, 'my-app');
310
+ * const wallet = await ExtensionWallet.create(...);
311
+ * const unsubscribe = wallet.onDisconnect(() => {
312
+ * console.log('Wallet disconnected! Please reconnect.');
313
+ * // Clean up UI, prompt user to reconnect, etc.
314
+ * });
315
+ * // Later: unsubscribe(); to stop receiving notifications
316
+ * ```
317
+ */
318
+ onDisconnect(callback: DisconnectCallback): () => void {
319
+ this.disconnectCallbacks.push(callback);
320
+ return () => {
321
+ const index = this.disconnectCallbacks.indexOf(callback);
322
+ if (index !== -1) {
323
+ this.disconnectCallbacks.splice(index, 1);
324
+ }
325
+ };
326
+ }
327
+
328
+ /**
329
+ * Returns whether the wallet has been disconnected.
330
+ *
331
+ * @returns true if the wallet is no longer connected
332
+ */
333
+ isDisconnected(): boolean {
334
+ return this.disconnected;
335
+ }
336
+
337
+ /**
338
+ * Disconnects from the wallet and cleans up resources.
339
+ *
340
+ * This method notifies the wallet extension that the session is ending,
341
+ * allowing it to clean up its state. After calling this method, the wallet
342
+ * instance can no longer be used and any pending requests will be rejected.
343
+ *
344
+ * @example
345
+ * ```typescript
346
+ * const wallet = await provider.connect('my-app');
219
347
  * // ... use wallet ...
220
- * wallet.close(); // Clean up when done
348
+ * await wallet.disconnect(); // Clean disconnect when done
221
349
  * ```
222
350
  */
223
- close(): void {
351
+ async disconnect(): Promise<void> {
352
+ if (this.disconnected) {
353
+ return;
354
+ }
355
+
356
+ // Send disconnect message to extension before closing
357
+ if (this.port && this.sharedKey) {
358
+ try {
359
+ const message = {
360
+ type: WalletMessageType.DISCONNECT,
361
+ messageId: globalThis.crypto.randomUUID(),
362
+ chainInfo: this.chainInfo,
363
+ appId: this.appId,
364
+ walletId: this.extensionId,
365
+ args: [],
366
+ };
367
+ const encrypted = await encrypt(this.sharedKey, message);
368
+ this.port.postMessage(encrypted);
369
+ } catch {
370
+ // Ignore errors sending disconnect message
371
+ }
372
+ }
373
+
374
+ this.handleDisconnect();
224
375
  if (this.port) {
225
376
  this.port.close();
226
377
  }
227
- this.inFlight.clear();
228
378
  }
229
379
  }
@@ -1,4 +1,5 @@
1
- export { ExtensionWallet } from './extension_wallet.js';
1
+ export { ExtensionWallet, type DisconnectCallback } from './extension_wallet.js';
2
2
  export { ExtensionProvider, type DiscoveredWallet } from './extension_provider.js';
3
3
  export * from '../../crypto.js';
4
+ export { WalletMessageType } from '../../types.js';
4
5
  export type { WalletInfo, WalletMessage, WalletResponse, DiscoveryRequest, DiscoveryResponse } from '../../types.js';
package/src/types.ts CHANGED
@@ -2,6 +2,21 @@ import type { ChainInfo } from '@aztec/aztec.js/account';
2
2
 
3
3
  import type { ExportedPublicKey } from './crypto.js';
4
4
 
5
+ /**
6
+ * Message types for wallet SDK communication.
7
+ * All types are prefixed with 'aztec-wallet-' for namespacing.
8
+ */
9
+ export enum WalletMessageType {
10
+ /** Discovery request to find installed wallets */
11
+ DISCOVERY = 'aztec-wallet-discovery',
12
+ /** Discovery response from a wallet */
13
+ DISCOVERY_RESPONSE = 'aztec-wallet-discovery-response',
14
+ /** Session disconnected notification (unencrypted control message) */
15
+ SESSION_DISCONNECTED = 'aztec-wallet-session-disconnected',
16
+ /** Explicit disconnect request from dApp */
17
+ DISCONNECT = 'aztec-wallet-disconnect',
18
+ }
19
+
5
20
  /**
6
21
  * Information about an installed Aztec wallet
7
22
  */
@@ -61,7 +76,7 @@ export interface WalletResponse {
61
76
  */
62
77
  export interface DiscoveryRequest {
63
78
  /** Message type for discovery */
64
- type: 'aztec-wallet-discovery';
79
+ type: WalletMessageType.DISCOVERY;
65
80
  /** Request ID */
66
81
  requestId: string;
67
82
  /** Chain information to check if wallet supports this network */
@@ -75,7 +90,7 @@ export interface DiscoveryRequest {
75
90
  */
76
91
  export interface DiscoveryResponse {
77
92
  /** Message type for discovery response */
78
- type: 'aztec-wallet-discovery-response';
93
+ type: WalletMessageType.DISCOVERY_RESPONSE;
79
94
  /** Request ID matching the discovery request */
80
95
  requestId: string;
81
96
  /** Wallet information */