@aztec/wallet-sdk 0.0.1-commit.fff30aa → 0.0.1-dev

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/dest/base-wallet/base_wallet.d.ts +10 -2
  2. package/dest/base-wallet/base_wallet.d.ts.map +1 -1
  3. package/dest/base-wallet/base_wallet.js +19 -4
  4. package/dest/extension/handlers/background_connection_handler.d.ts +12 -2
  5. package/dest/extension/handlers/background_connection_handler.d.ts.map +1 -1
  6. package/dest/extension/handlers/background_connection_handler.js +44 -8
  7. package/dest/extension/handlers/content_script_connection_handler.d.ts +2 -1
  8. package/dest/extension/handlers/content_script_connection_handler.d.ts.map +1 -1
  9. package/dest/extension/handlers/content_script_connection_handler.js +19 -0
  10. package/dest/extension/handlers/internal_message_types.d.ts +3 -1
  11. package/dest/extension/handlers/internal_message_types.d.ts.map +1 -1
  12. package/dest/extension/handlers/internal_message_types.js +3 -1
  13. package/dest/extension/provider/extension_wallet.d.ts +26 -3
  14. package/dest/extension/provider/extension_wallet.d.ts.map +1 -1
  15. package/dest/extension/provider/extension_wallet.js +78 -7
  16. package/dest/iframe/handlers/iframe_connection_handler.d.ts +6 -2
  17. package/dest/iframe/handlers/iframe_connection_handler.d.ts.map +1 -1
  18. package/dest/iframe/handlers/iframe_connection_handler.js +16 -4
  19. package/dest/iframe/provider/iframe_wallet.d.ts +20 -3
  20. package/dest/iframe/provider/iframe_wallet.d.ts.map +1 -1
  21. package/dest/iframe/provider/iframe_wallet.js +77 -8
  22. package/dest/types.d.ts +52 -2
  23. package/dest/types.d.ts.map +1 -1
  24. package/dest/types.js +25 -0
  25. package/package.json +8 -8
  26. package/src/base-wallet/base_wallet.ts +19 -2
  27. package/src/extension/handlers/background_connection_handler.ts +42 -9
  28. package/src/extension/handlers/content_script_connection_handler.ts +18 -0
  29. package/src/extension/handlers/internal_message_types.ts +2 -0
  30. package/src/extension/provider/extension_wallet.ts +92 -6
  31. package/src/iframe/handlers/iframe_connection_handler.ts +19 -5
  32. package/src/iframe/provider/iframe_wallet.ts +101 -7
  33. package/src/types.ts +59 -0
@@ -3,7 +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
+ import { DEFAULT_HEARTBEAT_DEAD_AFTER_MS, DEFAULT_HEARTBEAT_INTERVAL_MS, NOOP_LOGGER, WalletMessageType } from '../../types.js';
7
7
  /**
8
8
  * A wallet implementation that communicates with browser extension wallets
9
9
  * using an encrypted MessageChannel.
@@ -43,6 +43,11 @@ import { WalletMessageType } from '../../types.js';
43
43
  /** Map of pending requests awaiting responses, keyed by message ID */ inFlight;
44
44
  disconnected;
45
45
  disconnectCallbacks;
46
+ heartbeatTimer;
47
+ lastInboundAt;
48
+ log;
49
+ heartbeatIntervalMs;
50
+ heartbeatDeadAfterMs;
46
51
  /**
47
52
  * Private constructor - use {@link ExtensionWallet.create} to instantiate.
48
53
  * @param chainInfo - The chain information (chainId and version)
@@ -50,7 +55,9 @@ import { WalletMessageType } from '../../types.js';
50
55
  * @param extensionId - The unique identifier of the target wallet extension
51
56
  * @param port - The MessagePort for private communication with the wallet
52
57
  * @param sharedKey - The derived AES-256-GCM shared key for encryption
53
- */ constructor(chainInfo, appId, extensionId, port, sharedKey){
58
+ * @param logger - Optional logger; defaults to a no-op logger
59
+ * @param heartbeatOptions - Optional heartbeat tuning (mostly useful for tests)
60
+ */ constructor(chainInfo, appId, extensionId, port, sharedKey, logger, heartbeatOptions){
54
61
  this.chainInfo = chainInfo;
55
62
  this.appId = appId;
56
63
  this.extensionId = extensionId;
@@ -59,6 +66,11 @@ import { WalletMessageType } from '../../types.js';
59
66
  this.inFlight = new Map();
60
67
  this.disconnected = false;
61
68
  this.disconnectCallbacks = [];
69
+ this.heartbeatTimer = null;
70
+ this.lastInboundAt = 0;
71
+ this.log = logger ?? NOOP_LOGGER;
72
+ this.heartbeatIntervalMs = heartbeatOptions?.intervalMs ?? DEFAULT_HEARTBEAT_INTERVAL_MS;
73
+ this.heartbeatDeadAfterMs = heartbeatOptions?.deadAfterMs ?? DEFAULT_HEARTBEAT_DEAD_AFTER_MS;
62
74
  }
63
75
  /**
64
76
  * Creates a Wallet that communicates with a browser extension
@@ -69,6 +81,8 @@ import { WalletMessageType } from '../../types.js';
69
81
  * @param sharedKey - The derived AES-256-GCM shared key for encryption
70
82
  * @param chainInfo - The chain information (chainId and version) for request context
71
83
  * @param appId - Application identifier used to identify the requesting dApp to the wallet
84
+ * @param logger - Optional logger; defaults to a no-op logger to keep extension/page bundles small
85
+ * @param heartbeatOptions - Optional override for heartbeat tuning (mostly useful for tests)
72
86
  * @returns A Wallet interface where all method calls are encrypted
73
87
  *
74
88
  * @example
@@ -85,12 +99,13 @@ import { WalletMessageType } from '../../types.js';
85
99
  *
86
100
  * const accounts = await wallet.getAccounts();
87
101
  * ```
88
- */ static create(extensionId, port, sharedKey, chainInfo, appId) {
89
- const wallet = new ExtensionWallet(chainInfo, appId, extensionId, port, sharedKey);
102
+ */ static create(extensionId, port, sharedKey, chainInfo, appId, logger, heartbeatOptions) {
103
+ const wallet = new ExtensionWallet(chainInfo, appId, extensionId, port, sharedKey, logger, heartbeatOptions);
90
104
  // Set up message handler for encrypted responses and unencrypted control messages
91
105
  wallet.port.onmessage = (event)=>{
92
106
  const data = event.data;
93
- // Check for unencrypted disconnect notification
107
+ // Any inbound traffic counts as proof of liveness.
108
+ wallet.lastInboundAt = Date.now();
94
109
  if (data && typeof data === 'object' && 'type' in data && data.type === WalletMessageType.DISCONNECT) {
95
110
  wallet.handleDisconnect();
96
111
  return;
@@ -152,8 +167,12 @@ import { WalletMessageType } from '../../types.js';
152
167
  resolve(result);
153
168
  }
154
169
  this.inFlight.delete(messageId);
155
- // eslint-disable-next-line no-empty
156
- } catch {}
170
+ this.maybeStopHeartbeat();
171
+ } catch (err) {
172
+ this.log.warn('Failed to decrypt wallet response', {
173
+ err
174
+ });
175
+ }
157
176
  }
158
177
  /**
159
178
  * Sends an encrypted wallet method call over the secure MessageChannel.
@@ -190,9 +209,57 @@ import { WalletMessageType } from '../../types.js';
190
209
  resolve,
191
210
  reject
192
211
  });
212
+ this.startHeartbeat();
193
213
  return promise;
194
214
  }
195
215
  /**
216
+ * Start the heartbeat probe loop while at least one request is in flight.
217
+ * Idempotent — calling while already running is a no-op.
218
+ *
219
+ * Heartbeat is opt-in via wire protocol: PINGs are unencrypted control messages
220
+ * (like DISCONNECT). Older wallets that do not understand PING simply drop it,
221
+ * which is safe — we only declare disconnect when **no** inbound traffic of any
222
+ * kind (PONG, encrypted response, DISCONNECT) arrives within the dead window.
223
+ * A wallet that is processing a slow request will reset the timer when it
224
+ * eventually responds, so this never causes false disconnects on legacy peers.
225
+ */ startHeartbeat() {
226
+ if (this.heartbeatTimer !== null || this.disconnected) {
227
+ return;
228
+ }
229
+ this.lastInboundAt = Date.now();
230
+ this.heartbeatTimer = setInterval(()=>this.heartbeatTick(), this.heartbeatIntervalMs);
231
+ }
232
+ maybeStopHeartbeat() {
233
+ if (this.inFlight.size === 0 && this.heartbeatTimer !== null) {
234
+ clearInterval(this.heartbeatTimer);
235
+ this.heartbeatTimer = null;
236
+ }
237
+ }
238
+ heartbeatTick() {
239
+ if (this.disconnected || this.inFlight.size === 0) {
240
+ this.maybeStopHeartbeat();
241
+ return;
242
+ }
243
+ const idleMs = Date.now() - this.lastInboundAt;
244
+ if (idleMs >= this.heartbeatDeadAfterMs) {
245
+ this.log.warn('Wallet channel unresponsive — declaring disconnect', {
246
+ idleMs,
247
+ inFlight: this.inFlight.size
248
+ });
249
+ this.handleDisconnect();
250
+ return;
251
+ }
252
+ try {
253
+ this.port.postMessage({
254
+ type: WalletMessageType.PING
255
+ });
256
+ } catch (err) {
257
+ this.log.warn('Failed to send heartbeat PING', {
258
+ err
259
+ });
260
+ }
261
+ }
262
+ /**
196
263
  * Handles wallet disconnection.
197
264
  * Rejects all pending requests and notifies registered callbacks.
198
265
  * @internal
@@ -201,6 +268,10 @@ import { WalletMessageType } from '../../types.js';
201
268
  return;
202
269
  }
203
270
  this.disconnected = true;
271
+ if (this.heartbeatTimer !== null) {
272
+ clearInterval(this.heartbeatTimer);
273
+ this.heartbeatTimer = null;
274
+ }
204
275
  if (this.port) {
205
276
  this.port.onmessage = null;
206
277
  this.port.close();
@@ -15,6 +15,7 @@
15
15
  */
16
16
  import type { ChainInfo } from '@aztec/aztec.js/account';
17
17
  import type { Wallet } from '@aztec/aztec.js/wallet';
18
+ import { type WalletSdkLogger } from '../../types.js';
18
19
  /**
19
20
  * A pending discovery request from a dApp (before user approval).
20
21
  */
@@ -57,6 +58,8 @@ export interface IframeConnectionConfig {
57
58
  walletIcon?: string;
58
59
  /** Origins allowed to connect. If empty or undefined, all origins are allowed (dev mode). */
59
60
  allowedOrigins?: string[];
61
+ /** Logger used for diagnostics. */
62
+ logger: WalletSdkLogger;
60
63
  }
61
64
  /**
62
65
  * Event callbacks for the iframe connection handler.
@@ -85,7 +88,7 @@ export interface IframeConnectionCallbacks {
85
88
  * @example
86
89
  * ```typescript
87
90
  * const handler = new IframeConnectionHandler(
88
- * { walletId: 'my-wallet', walletName: 'My Wallet', walletVersion: '1.0.0' },
91
+ * { walletId: 'my-wallet', walletName: 'My Wallet', walletVersion: '1.0.0', logger: console },
89
92
  * {
90
93
  * onPendingDiscovery: (session) => showApprovalUI(session),
91
94
  * getWallet: (appId, chainInfo) => createWalletForApp(appId, chainInfo),
@@ -109,10 +112,11 @@ export declare class IframeConnectionHandler {
109
112
  getPendingSessions(): PendingSession[];
110
113
  private handleMessage;
111
114
  private handleMessageAsync;
115
+ private handlePing;
112
116
  private handleDiscoveryRequest;
113
117
  private handleKeyExchangeRequest;
114
118
  private handleSecureMessage;
115
119
  private postToParent;
116
120
  private postToOrigin;
117
121
  }
118
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaWZyYW1lX2Nvbm5lY3Rpb25faGFuZGxlci5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2lmcmFtZS9oYW5kbGVycy9pZnJhbWVfY29ubmVjdGlvbl9oYW5kbGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7OztHQWNHO0FBQ0gsT0FBTyxLQUFLLEVBQUUsU0FBUyxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFFekQsT0FBTyxLQUFLLEVBQUUsTUFBTSxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFnQnJEOztHQUVHO0FBQ0gsTUFBTSxXQUFXLGNBQWM7SUFDN0IsZ0NBQWdDO0lBQ2hDLFNBQVMsRUFBRSxNQUFNLENBQUM7SUFDbEIsNkJBQTZCO0lBQzdCLEtBQUssRUFBRSxNQUFNLENBQUM7SUFDZCx3Q0FBd0M7SUFDeEMsTUFBTSxFQUFFLE1BQU0sQ0FBQztJQUNmLHNCQUFzQjtJQUN0QixNQUFNLEVBQUUsU0FBUyxHQUFHLFVBQVUsQ0FBQztDQUNoQztBQUVEOztHQUVHO0FBQ0gsTUFBTSxXQUFXLGFBQWE7SUFDNUIsMkRBQTJEO0lBQzNELFNBQVMsRUFBRSxNQUFNLENBQUM7SUFDbEIsOENBQThDO0lBQzlDLFNBQVMsRUFBRSxTQUFTLENBQUM7SUFDckIsMENBQTBDO0lBQzFDLGdCQUFnQixFQUFFLE1BQU0sQ0FBQztJQUN6Qix1Q0FBdUM7SUFDdkMsTUFBTSxFQUFFLE1BQU0sQ0FBQztJQUNmLDZCQUE2QjtJQUM3QixLQUFLLEVBQUUsTUFBTSxDQUFDO0NBQ2Y7QUFFRDs7R0FFRztBQUNILE1BQU0sV0FBVyxzQkFBc0I7SUFDckMsK0JBQStCO0lBQy9CLFFBQVEsRUFBRSxNQUFNLENBQUM7SUFDakIsa0NBQWtDO0lBQ2xDLFVBQVUsRUFBRSxNQUFNLENBQUM7SUFDbkIsNEJBQTRCO0lBQzVCLGFBQWEsRUFBRSxNQUFNLENBQUM7SUFDdEIsK0JBQStCO0lBQy9CLFVBQVUsQ0FBQyxFQUFFLE1BQU0sQ0FBQztJQUNwQiw2RkFBNkY7SUFDN0YsY0FBYyxDQUFDLEVBQUUsTUFBTSxFQUFFLENBQUM7Q0FDM0I7QUFFRDs7R0FFRztBQUNILE1BQU0sV0FBVyx5QkFBeUI7SUFDeEMsa0ZBQWdGO0lBQ2hGLGtCQUFrQixDQUFDLEVBQUUsQ0FBQyxPQUFPLEVBQUUsY0FBYyxLQUFLLElBQUksQ0FBQztJQUN2RCxtRUFBbUU7SUFDbkUsb0JBQW9CLENBQUMsRUFBRSxDQUFDLE9BQU8sRUFBRSxhQUFhLEtBQUssSUFBSSxDQUFDO0lBQ3hELDBDQUEwQztJQUMxQyxtQkFBbUIsQ0FBQyxFQUFFLENBQUMsU0FBUyxFQUFFLE1BQU0sS0FBSyxJQUFJLENBQUM7SUFDbEQsMkZBQXlGO0lBQ3pGLGtCQUFrQixDQUFDLEVBQUUsQ0FBQyxnQkFBZ0IsRUFBRSxNQUFNLEtBQUssSUFBSSxDQUFDO0lBQ3hEOzs7T0FHRztJQUNILFNBQVMsRUFBRSxDQUFDLEtBQUssRUFBRSxNQUFNLEVBQUUsU0FBUyxFQUFFLFNBQVMsS0FBSyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUM7Q0FDckU7QUFFRDs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FpQkc7QUFDSCxxQkFBYSx1QkFBdUI7SUFNaEMsT0FBTyxDQUFDLE1BQU07SUFDZCxPQUFPLENBQUMsU0FBUztJQU5uQixPQUFPLENBQUMsZUFBZSxDQUFxQztJQUM1RCxPQUFPLENBQUMsY0FBYyxDQUFvQztJQUMxRCxPQUFPLENBQUMsR0FBRyxDQUF5QztJQUVwRCxZQUNVLE1BQU0sRUFBRSxzQkFBc0IsRUFDOUIsU0FBUyxFQUFFLHlCQUF5QixFQUMxQztJQUVKLEtBQUssSUFBSSxJQUFJLENBSVo7SUFFRCxJQUFJLElBQUksSUFBSSxDQUVYO0lBRUQsZ0JBQWdCLENBQUMsU0FBUyxFQUFFLE1BQU0sR0FBRyxJQUFJLENBa0J4QztJQUVELGVBQWUsQ0FBQyxTQUFTLEVBQUUsTUFBTSxHQUFHLElBQUksQ0FFdkM7SUFFRCxnQkFBZ0IsQ0FBQyxTQUFTLEVBQUUsTUFBTSxHQUFHLElBQUksQ0FVeEM7SUFFRCxrQkFBa0IsSUFBSSxjQUFjLEVBQUUsQ0FFckM7SUFFRCxPQUFPLENBQUMsYUFBYSxDQUVuQjtZQUVZLGtCQUFrQjtJQTRCaEMsT0FBTyxDQUFDLHNCQUFzQjtZQVNoQix3QkFBd0I7WUE2Q3hCLG1CQUFtQjtJQXNEakMsT0FBTyxDQUFDLFlBQVk7SUFNcEIsT0FBTyxDQUFDLFlBQVk7Q0FLckIifQ==
122
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaWZyYW1lX2Nvbm5lY3Rpb25faGFuZGxlci5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2lmcmFtZS9oYW5kbGVycy9pZnJhbWVfY29ubmVjdGlvbl9oYW5kbGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7OztHQWNHO0FBQ0gsT0FBTyxLQUFLLEVBQUUsU0FBUyxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDekQsT0FBTyxLQUFLLEVBQUUsTUFBTSxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFjckQsT0FBTyxFQUE4RCxLQUFLLGVBQWUsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRWxIOztHQUVHO0FBQ0gsTUFBTSxXQUFXLGNBQWM7SUFDN0IsZ0NBQWdDO0lBQ2hDLFNBQVMsRUFBRSxNQUFNLENBQUM7SUFDbEIsNkJBQTZCO0lBQzdCLEtBQUssRUFBRSxNQUFNLENBQUM7SUFDZCx3Q0FBd0M7SUFDeEMsTUFBTSxFQUFFLE1BQU0sQ0FBQztJQUNmLHNCQUFzQjtJQUN0QixNQUFNLEVBQUUsU0FBUyxHQUFHLFVBQVUsQ0FBQztDQUNoQztBQUVEOztHQUVHO0FBQ0gsTUFBTSxXQUFXLGFBQWE7SUFDNUIsMkRBQTJEO0lBQzNELFNBQVMsRUFBRSxNQUFNLENBQUM7SUFDbEIsOENBQThDO0lBQzlDLFNBQVMsRUFBRSxTQUFTLENBQUM7SUFDckIsMENBQTBDO0lBQzFDLGdCQUFnQixFQUFFLE1BQU0sQ0FBQztJQUN6Qix1Q0FBdUM7SUFDdkMsTUFBTSxFQUFFLE1BQU0sQ0FBQztJQUNmLDZCQUE2QjtJQUM3QixLQUFLLEVBQUUsTUFBTSxDQUFDO0NBQ2Y7QUFFRDs7R0FFRztBQUNILE1BQU0sV0FBVyxzQkFBc0I7SUFDckMsK0JBQStCO0lBQy9CLFFBQVEsRUFBRSxNQUFNLENBQUM7SUFDakIsa0NBQWtDO0lBQ2xDLFVBQVUsRUFBRSxNQUFNLENBQUM7SUFDbkIsNEJBQTRCO0lBQzVCLGFBQWEsRUFBRSxNQUFNLENBQUM7SUFDdEIsK0JBQStCO0lBQy9CLFVBQVUsQ0FBQyxFQUFFLE1BQU0sQ0FBQztJQUNwQiw2RkFBNkY7SUFDN0YsY0FBYyxDQUFDLEVBQUUsTUFBTSxFQUFFLENBQUM7SUFDMUIsbUNBQW1DO0lBQ25DLE1BQU0sRUFBRSxlQUFlLENBQUM7Q0FDekI7QUFFRDs7R0FFRztBQUNILE1BQU0sV0FBVyx5QkFBeUI7SUFDeEMsa0ZBQWdGO0lBQ2hGLGtCQUFrQixDQUFDLEVBQUUsQ0FBQyxPQUFPLEVBQUUsY0FBYyxLQUFLLElBQUksQ0FBQztJQUN2RCxtRUFBbUU7SUFDbkUsb0JBQW9CLENBQUMsRUFBRSxDQUFDLE9BQU8sRUFBRSxhQUFhLEtBQUssSUFBSSxDQUFDO0lBQ3hELDBDQUEwQztJQUMxQyxtQkFBbUIsQ0FBQyxFQUFFLENBQUMsU0FBUyxFQUFFLE1BQU0sS0FBSyxJQUFJLENBQUM7SUFDbEQsMkZBQXlGO0lBQ3pGLGtCQUFrQixDQUFDLEVBQUUsQ0FBQyxnQkFBZ0IsRUFBRSxNQUFNLEtBQUssSUFBSSxDQUFDO0lBQ3hEOzs7T0FHRztJQUNILFNBQVMsRUFBRSxDQUFDLEtBQUssRUFBRSxNQUFNLEVBQUUsU0FBUyxFQUFFLFNBQVMsS0FBSyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUM7Q0FDckU7QUFFRDs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FpQkc7QUFDSCxxQkFBYSx1QkFBdUI7SUFNaEMsT0FBTyxDQUFDLE1BQU07SUFDZCxPQUFPLENBQUMsU0FBUztJQU5uQixPQUFPLENBQUMsZUFBZSxDQUFxQztJQUM1RCxPQUFPLENBQUMsY0FBYyxDQUFvQztJQUMxRCxPQUFPLENBQUMsR0FBRyxDQUFrQjtJQUU3QixZQUNVLE1BQU0sRUFBRSxzQkFBc0IsRUFDOUIsU0FBUyxFQUFFLHlCQUF5QixFQUc3QztJQUVELEtBQUssSUFBSSxJQUFJLENBSVo7SUFFRCxJQUFJLElBQUksSUFBSSxDQUVYO0lBRUQsZ0JBQWdCLENBQUMsU0FBUyxFQUFFLE1BQU0sR0FBRyxJQUFJLENBa0J4QztJQUVELGVBQWUsQ0FBQyxTQUFTLEVBQUUsTUFBTSxHQUFHLElBQUksQ0FFdkM7SUFFRCxnQkFBZ0IsQ0FBQyxTQUFTLEVBQUUsTUFBTSxHQUFHLElBQUksQ0FVeEM7SUFFRCxrQkFBa0IsSUFBSSxjQUFjLEVBQUUsQ0FFckM7SUFFRCxPQUFPLENBQUMsYUFBYSxDQUVuQjtZQUVZLGtCQUFrQjtJQStCaEMsT0FBTyxDQUFDLFVBQVU7SUFRbEIsT0FBTyxDQUFDLHNCQUFzQjtZQVNoQix3QkFBd0I7WUE2Q3hCLG1CQUFtQjtJQXNEakMsT0FBTyxDQUFDLFlBQVk7SUFNcEIsT0FBTyxDQUFDLFlBQVk7Q0FLckIifQ==
@@ -1 +1 @@
1
- {"version":3,"file":"iframe_connection_handler.d.ts","sourceRoot":"","sources":["../../../src/iframe/handlers/iframe_connection_handler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAEzD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAgBrD;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,gCAAgC;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,6BAA6B;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,wCAAwC;IACxC,MAAM,EAAE,MAAM,CAAC;IACf,sBAAsB;IACtB,MAAM,EAAE,SAAS,GAAG,UAAU,CAAC;CAChC;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,2DAA2D;IAC3D,SAAS,EAAE,MAAM,CAAC;IAClB,8CAA8C;IAC9C,SAAS,EAAE,SAAS,CAAC;IACrB,0CAA0C;IAC1C,gBAAgB,EAAE,MAAM,CAAC;IACzB,uCAAuC;IACvC,MAAM,EAAE,MAAM,CAAC;IACf,6BAA6B;IAC7B,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,+BAA+B;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,kCAAkC;IAClC,UAAU,EAAE,MAAM,CAAC;IACnB,4BAA4B;IAC5B,aAAa,EAAE,MAAM,CAAC;IACtB,+BAA+B;IAC/B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,6FAA6F;IAC7F,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;CAC3B;AAED;;GAEG;AACH,MAAM,WAAW,yBAAyB;IACxC,kFAAgF;IAChF,kBAAkB,CAAC,EAAE,CAAC,OAAO,EAAE,cAAc,KAAK,IAAI,CAAC;IACvD,mEAAmE;IACnE,oBAAoB,CAAC,EAAE,CAAC,OAAO,EAAE,aAAa,KAAK,IAAI,CAAC;IACxD,0CAA0C;IAC1C,mBAAmB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAClD,2FAAyF;IACzF,kBAAkB,CAAC,EAAE,CAAC,gBAAgB,EAAE,MAAM,KAAK,IAAI,CAAC;IACxD;;;OAGG;IACH,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;CACrE;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAAa,uBAAuB;IAMhC,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,SAAS;IANnB,OAAO,CAAC,eAAe,CAAqC;IAC5D,OAAO,CAAC,cAAc,CAAoC;IAC1D,OAAO,CAAC,GAAG,CAAyC;IAEpD,YACU,MAAM,EAAE,sBAAsB,EAC9B,SAAS,EAAE,yBAAyB,EAC1C;IAEJ,KAAK,IAAI,IAAI,CAIZ;IAED,IAAI,IAAI,IAAI,CAEX;IAED,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAkBxC;IAED,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAEvC;IAED,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAUxC;IAED,kBAAkB,IAAI,cAAc,EAAE,CAErC;IAED,OAAO,CAAC,aAAa,CAEnB;YAEY,kBAAkB;IA4BhC,OAAO,CAAC,sBAAsB;YAShB,wBAAwB;YA6CxB,mBAAmB;IAsDjC,OAAO,CAAC,YAAY;IAMpB,OAAO,CAAC,YAAY;CAKrB"}
1
+ {"version":3,"file":"iframe_connection_handler.d.ts","sourceRoot":"","sources":["../../../src/iframe/handlers/iframe_connection_handler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAcrD,OAAO,EAA8D,KAAK,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAElH;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,gCAAgC;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,6BAA6B;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,wCAAwC;IACxC,MAAM,EAAE,MAAM,CAAC;IACf,sBAAsB;IACtB,MAAM,EAAE,SAAS,GAAG,UAAU,CAAC;CAChC;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,2DAA2D;IAC3D,SAAS,EAAE,MAAM,CAAC;IAClB,8CAA8C;IAC9C,SAAS,EAAE,SAAS,CAAC;IACrB,0CAA0C;IAC1C,gBAAgB,EAAE,MAAM,CAAC;IACzB,uCAAuC;IACvC,MAAM,EAAE,MAAM,CAAC;IACf,6BAA6B;IAC7B,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,+BAA+B;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,kCAAkC;IAClC,UAAU,EAAE,MAAM,CAAC;IACnB,4BAA4B;IAC5B,aAAa,EAAE,MAAM,CAAC;IACtB,+BAA+B;IAC/B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,6FAA6F;IAC7F,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,mCAAmC;IACnC,MAAM,EAAE,eAAe,CAAC;CACzB;AAED;;GAEG;AACH,MAAM,WAAW,yBAAyB;IACxC,kFAAgF;IAChF,kBAAkB,CAAC,EAAE,CAAC,OAAO,EAAE,cAAc,KAAK,IAAI,CAAC;IACvD,mEAAmE;IACnE,oBAAoB,CAAC,EAAE,CAAC,OAAO,EAAE,aAAa,KAAK,IAAI,CAAC;IACxD,0CAA0C;IAC1C,mBAAmB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAClD,2FAAyF;IACzF,kBAAkB,CAAC,EAAE,CAAC,gBAAgB,EAAE,MAAM,KAAK,IAAI,CAAC;IACxD;;;OAGG;IACH,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;CACrE;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAAa,uBAAuB;IAMhC,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,SAAS;IANnB,OAAO,CAAC,eAAe,CAAqC;IAC5D,OAAO,CAAC,cAAc,CAAoC;IAC1D,OAAO,CAAC,GAAG,CAAkB;IAE7B,YACU,MAAM,EAAE,sBAAsB,EAC9B,SAAS,EAAE,yBAAyB,EAG7C;IAED,KAAK,IAAI,IAAI,CAIZ;IAED,IAAI,IAAI,IAAI,CAEX;IAED,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAkBxC;IAED,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAEvC;IAED,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAUxC;IAED,kBAAkB,IAAI,cAAc,EAAE,CAErC;IAED,OAAO,CAAC,aAAa,CAEnB;YAEY,kBAAkB;IA+BhC,OAAO,CAAC,UAAU;IAQlB,OAAO,CAAC,sBAAsB;YAShB,wBAAwB;YA6CxB,mBAAmB;IAsDjC,OAAO,CAAC,YAAY;IAMpB,OAAO,CAAC,YAAY;CAKrB"}
@@ -12,8 +12,7 @@
12
12
  *
13
13
  * The wallet announces itself by posting WALLET_READY as soon as the handler starts,
14
14
  * so the dApp knows it can send a discovery request.
15
- */ import { createLogger } from '@aztec/aztec.js/log';
16
- import { WalletSchema } from '@aztec/aztec.js/wallet';
15
+ */ import { WalletSchema } from '@aztec/aztec.js/wallet';
17
16
  import { jsonStringify } from '@aztec/foundation/json-rpc';
18
17
  import { parseWithOptionals, schemaHasMethod } from '@aztec/foundation/schemas';
19
18
  import { decrypt, deriveSessionKeys, encrypt, exportPublicKey, generateKeyPair, importPublicKey } from '../../crypto.js';
@@ -27,7 +26,7 @@ import { WalletMessageType } from '../../types.js';
27
26
  * @example
28
27
  * ```typescript
29
28
  * const handler = new IframeConnectionHandler(
30
- * { walletId: 'my-wallet', walletName: 'My Wallet', walletVersion: '1.0.0' },
29
+ * { walletId: 'my-wallet', walletName: 'My Wallet', walletVersion: '1.0.0', logger: console },
31
30
  * {
32
31
  * onPendingDiscovery: (session) => showApprovalUI(session),
33
32
  * getWallet: (appId, chainInfo) => createWalletForApp(appId, chainInfo),
@@ -46,10 +45,10 @@ import { WalletMessageType } from '../../types.js';
46
45
  this.callbacks = callbacks;
47
46
  this.pendingSessions = new Map();
48
47
  this.activeSessions = new Map();
49
- this.log = createLogger('wallet:iframe-handler');
50
48
  this.handleMessage = (event)=>{
51
49
  void this.handleMessageAsync(event);
52
50
  };
51
+ this.log = config.logger;
53
52
  }
54
53
  start() {
55
54
  window.addEventListener('message', this.handleMessage);
@@ -120,8 +119,21 @@ import { WalletMessageType } from '../../types.js';
120
119
  case WalletMessageType.DISCONNECT:
121
120
  this.terminateSession(msg.sessionId);
122
121
  break;
122
+ case WalletMessageType.PING:
123
+ this.handlePing(msg.sessionId);
124
+ break;
123
125
  }
124
126
  }
127
+ handlePing(sessionId) {
128
+ const session = this.activeSessions.get(sessionId);
129
+ if (!session) {
130
+ return;
131
+ }
132
+ this.postToOrigin(session.origin, {
133
+ type: WalletMessageType.PONG,
134
+ sessionId
135
+ });
136
+ }
125
137
  handleDiscoveryRequest(msg, origin) {
126
138
  // eslint-disable-next-line jsdoc/require-jsdoc
127
139
  const { requestId, appId } = msg;
@@ -8,7 +8,7 @@
8
8
  */
9
9
  import type { ChainInfo } from '@aztec/aztec.js/account';
10
10
  import { type Wallet } from '@aztec/aztec.js/wallet';
11
- import { type DisconnectCallback } from '../../types.js';
11
+ import { type DisconnectCallback, type HeartbeatOptions, type WalletSdkLogger } from '../../types.js';
12
12
  /**
13
13
  * A wallet implementation that communicates with a web wallet loaded in an iframe
14
14
  * using encrypted postMessage.
@@ -35,6 +35,11 @@ export declare class IframeWallet {
35
35
  private disconnected;
36
36
  private disconnectCallbacks;
37
37
  private messageListener;
38
+ private heartbeatTimer;
39
+ private lastInboundAt;
40
+ private log;
41
+ private heartbeatIntervalMs;
42
+ private heartbeatDeadAfterMs;
38
43
  private constructor();
39
44
  /**
40
45
  * Creates a proxied IframeWallet that implements the {@link Wallet} interface.
@@ -50,9 +55,11 @@ export declare class IframeWallet {
50
55
  * @param sharedKey - AES-256-GCM key derived from ECDH key exchange
51
56
  * @param chainInfo - Network information (chainId and version)
52
57
  * @param appId - Application identifier for the requesting dApp
58
+ * @param logger - Optional logger; defaults to a no-op logger to keep extension/page bundles small
59
+ * @param heartbeatOptions - Optional override for heartbeat tuning (mostly useful for tests)
53
60
  * @returns A proxied IframeWallet — call `.asWallet()` to get the typed `Wallet`
54
61
  */
55
- static create(walletId: string, sessionId: string, iframeWindow: Window, walletOrigin: string, sharedKey: CryptoKey, chainInfo: ChainInfo, appId: string): IframeWallet;
62
+ static create(walletId: string, sessionId: string, iframeWindow: Window, walletOrigin: string, sharedKey: CryptoKey, chainInfo: ChainInfo, appId: string, logger?: WalletSdkLogger, heartbeatOptions?: HeartbeatOptions): IframeWallet;
56
63
  /**
57
64
  * Returns this wallet as a typed {@link Wallet} interface.
58
65
  * When accessed through the Proxy (via `create()`), returns the proxy itself.
@@ -60,9 +67,19 @@ export declare class IframeWallet {
60
67
  asWallet(): Wallet;
61
68
  private handleEncryptedResponse;
62
69
  private postMessage;
70
+ /**
71
+ * Start liveness probing while at least one request is in flight. PINGs are
72
+ * unencrypted control messages — older wallet handlers that don't understand
73
+ * them simply drop them, but any inbound traffic (PONG, encrypted response,
74
+ * disconnect notice) resets the idle timer, so a slow-but-alive legacy wallet
75
+ * never trips a false disconnect.
76
+ */
77
+ private startHeartbeat;
78
+ private maybeStopHeartbeat;
79
+ private heartbeatTick;
63
80
  private handleDisconnect;
64
81
  onDisconnect(callback: DisconnectCallback): () => void;
65
82
  isDisconnected(): boolean;
66
83
  disconnect(): void;
67
84
  }
68
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaWZyYW1lX3dhbGxldC5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2lmcmFtZS9wcm92aWRlci9pZnJhbWVfd2FsbGV0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7O0dBT0c7QUFDSCxPQUFPLEtBQUssRUFBRSxTQUFTLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUN6RCxPQUFPLEVBQUUsS0FBSyxNQUFNLEVBQWdCLE1BQU0sd0JBQXdCLENBQUM7QUFPbkUsT0FBTyxFQUFFLEtBQUssa0JBQWtCLEVBQThELE1BQU0sZ0JBQWdCLENBQUM7QUFhckg7Ozs7Ozs7Ozs7Ozs7R0FhRztBQUNILHFCQUFhLFlBQVk7SUFPckIsT0FBTyxDQUFDLFNBQVM7SUFDakIsT0FBTyxDQUFDLEtBQUs7SUFDYixPQUFPLENBQUMsUUFBUTtJQUNoQixPQUFPLENBQUMsU0FBUztJQUNqQixPQUFPLENBQUMsWUFBWTtJQUNwQixPQUFPLENBQUMsWUFBWTtJQUNwQixPQUFPLENBQUMsU0FBUztJQVpuQixPQUFPLENBQUMsUUFBUSxDQUFvRDtJQUNwRSxPQUFPLENBQUMsWUFBWSxDQUFTO0lBQzdCLE9BQU8sQ0FBQyxtQkFBbUIsQ0FBNEI7SUFDdkQsT0FBTyxDQUFDLGVBQWUsQ0FBNEM7SUFFbkUsT0FBTyxlQVFIO0lBRUo7Ozs7Ozs7Ozs7Ozs7OztPQWVHO0lBQ0gsTUFBTSxDQUFDLE1BQU0sQ0FDWCxRQUFRLEVBQUUsTUFBTSxFQUNoQixTQUFTLEVBQUUsTUFBTSxFQUNqQixZQUFZLEVBQUUsTUFBTSxFQUNwQixZQUFZLEVBQUUsTUFBTSxFQUNwQixTQUFTLEVBQUUsU0FBUyxFQUNwQixTQUFTLEVBQUUsU0FBUyxFQUNwQixLQUFLLEVBQUUsTUFBTSxHQUNaLFlBQVksQ0FxQ2Q7SUFFRDs7O09BR0c7SUFDSCxRQUFRLElBQUksTUFBTSxDQUVqQjtZQUVhLHVCQUF1QjtZQXlCdkIsV0FBVztJQTBCekIsT0FBTyxDQUFDLGdCQUFnQjtJQTBCeEIsWUFBWSxDQUFDLFFBQVEsRUFBRSxrQkFBa0IsR0FBRyxNQUFNLElBQUksQ0FRckQ7SUFFRCxjQUFjLElBQUksT0FBTyxDQUV4QjtJQUVELFVBQVUsSUFBSSxJQUFJLENBTWpCO0NBQ0YifQ==
85
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaWZyYW1lX3dhbGxldC5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2lmcmFtZS9wcm92aWRlci9pZnJhbWVfd2FsbGV0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7O0dBT0c7QUFDSCxPQUFPLEtBQUssRUFBRSxTQUFTLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUN6RCxPQUFPLEVBQUUsS0FBSyxNQUFNLEVBQWdCLE1BQU0sd0JBQXdCLENBQUM7QUFPbkUsT0FBTyxFQUdMLEtBQUssa0JBQWtCLEVBQ3ZCLEtBQUssZ0JBQWdCLEVBS3JCLEtBQUssZUFBZSxFQUNyQixNQUFNLGdCQUFnQixDQUFDO0FBYXhCOzs7Ozs7Ozs7Ozs7O0dBYUc7QUFDSCxxQkFBYSxZQUFZO0lBWXJCLE9BQU8sQ0FBQyxTQUFTO0lBQ2pCLE9BQU8sQ0FBQyxLQUFLO0lBQ2IsT0FBTyxDQUFDLFFBQVE7SUFDaEIsT0FBTyxDQUFDLFNBQVM7SUFDakIsT0FBTyxDQUFDLFlBQVk7SUFDcEIsT0FBTyxDQUFDLFlBQVk7SUFDcEIsT0FBTyxDQUFDLFNBQVM7SUFqQm5CLE9BQU8sQ0FBQyxRQUFRLENBQW9EO0lBQ3BFLE9BQU8sQ0FBQyxZQUFZLENBQVM7SUFDN0IsT0FBTyxDQUFDLG1CQUFtQixDQUE0QjtJQUN2RCxPQUFPLENBQUMsZUFBZSxDQUE0QztJQUNuRSxPQUFPLENBQUMsY0FBYyxDQUErQztJQUNyRSxPQUFPLENBQUMsYUFBYSxDQUFLO0lBQzFCLE9BQU8sQ0FBQyxHQUFHLENBQWtCO0lBQzdCLE9BQU8sQ0FBQyxtQkFBbUIsQ0FBUztJQUNwQyxPQUFPLENBQUMsb0JBQW9CLENBQVM7SUFFckMsT0FBTyxlQWNOO0lBRUQ7Ozs7Ozs7Ozs7Ozs7Ozs7O09BaUJHO0lBQ0gsTUFBTSxDQUFDLE1BQU0sQ0FDWCxRQUFRLEVBQUUsTUFBTSxFQUNoQixTQUFTLEVBQUUsTUFBTSxFQUNqQixZQUFZLEVBQUUsTUFBTSxFQUNwQixZQUFZLEVBQUUsTUFBTSxFQUNwQixTQUFTLEVBQUUsU0FBUyxFQUNwQixTQUFTLEVBQUUsU0FBUyxFQUNwQixLQUFLLEVBQUUsTUFBTSxFQUNiLE1BQU0sQ0FBQyxFQUFFLGVBQWUsRUFDeEIsZ0JBQWdCLENBQUMsRUFBRSxnQkFBZ0IsR0FDbEMsWUFBWSxDQXNEZDtJQUVEOzs7T0FHRztJQUNILFFBQVEsSUFBSSxNQUFNLENBRWpCO1lBRWEsdUJBQXVCO1lBMEJ2QixXQUFXO0lBMkJ6Qjs7Ozs7O09BTUc7SUFDSCxPQUFPLENBQUMsY0FBYztJQVF0QixPQUFPLENBQUMsa0JBQWtCO0lBTzFCLE9BQU8sQ0FBQyxhQUFhO0lBdUJyQixPQUFPLENBQUMsZ0JBQWdCO0lBK0J4QixZQUFZLENBQUMsUUFBUSxFQUFFLGtCQUFrQixHQUFHLE1BQU0sSUFBSSxDQVFyRDtJQUVELGNBQWMsSUFBSSxPQUFPLENBRXhCO0lBRUQsVUFBVSxJQUFJLElBQUksQ0FNakI7Q0FDRiJ9
@@ -1 +1 @@
1
- {"version":3,"file":"iframe_wallet.d.ts","sourceRoot":"","sources":["../../../src/iframe/provider/iframe_wallet.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,EAAE,KAAK,MAAM,EAAgB,MAAM,wBAAwB,CAAC;AAOnE,OAAO,EAAE,KAAK,kBAAkB,EAA8D,MAAM,gBAAgB,CAAC;AAarH;;;;;;;;;;;;;GAaG;AACH,qBAAa,YAAY;IAOrB,OAAO,CAAC,SAAS;IACjB,OAAO,CAAC,KAAK;IACb,OAAO,CAAC,QAAQ;IAChB,OAAO,CAAC,SAAS;IACjB,OAAO,CAAC,YAAY;IACpB,OAAO,CAAC,YAAY;IACpB,OAAO,CAAC,SAAS;IAZnB,OAAO,CAAC,QAAQ,CAAoD;IACpE,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,mBAAmB,CAA4B;IACvD,OAAO,CAAC,eAAe,CAA4C;IAEnE,OAAO,eAQH;IAEJ;;;;;;;;;;;;;;;OAeG;IACH,MAAM,CAAC,MAAM,CACX,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,MAAM,EACpB,YAAY,EAAE,MAAM,EACpB,SAAS,EAAE,SAAS,EACpB,SAAS,EAAE,SAAS,EACpB,KAAK,EAAE,MAAM,GACZ,YAAY,CAqCd;IAED;;;OAGG;IACH,QAAQ,IAAI,MAAM,CAEjB;YAEa,uBAAuB;YAyBvB,WAAW;IA0BzB,OAAO,CAAC,gBAAgB;IA0BxB,YAAY,CAAC,QAAQ,EAAE,kBAAkB,GAAG,MAAM,IAAI,CAQrD;IAED,cAAc,IAAI,OAAO,CAExB;IAED,UAAU,IAAI,IAAI,CAMjB;CACF"}
1
+ {"version":3,"file":"iframe_wallet.d.ts","sourceRoot":"","sources":["../../../src/iframe/provider/iframe_wallet.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,EAAE,KAAK,MAAM,EAAgB,MAAM,wBAAwB,CAAC;AAOnE,OAAO,EAGL,KAAK,kBAAkB,EACvB,KAAK,gBAAgB,EAKrB,KAAK,eAAe,EACrB,MAAM,gBAAgB,CAAC;AAaxB;;;;;;;;;;;;;GAaG;AACH,qBAAa,YAAY;IAYrB,OAAO,CAAC,SAAS;IACjB,OAAO,CAAC,KAAK;IACb,OAAO,CAAC,QAAQ;IAChB,OAAO,CAAC,SAAS;IACjB,OAAO,CAAC,YAAY;IACpB,OAAO,CAAC,YAAY;IACpB,OAAO,CAAC,SAAS;IAjBnB,OAAO,CAAC,QAAQ,CAAoD;IACpE,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,mBAAmB,CAA4B;IACvD,OAAO,CAAC,eAAe,CAA4C;IACnE,OAAO,CAAC,cAAc,CAA+C;IACrE,OAAO,CAAC,aAAa,CAAK;IAC1B,OAAO,CAAC,GAAG,CAAkB;IAC7B,OAAO,CAAC,mBAAmB,CAAS;IACpC,OAAO,CAAC,oBAAoB,CAAS;IAErC,OAAO,eAcN;IAED;;;;;;;;;;;;;;;;;OAiBG;IACH,MAAM,CAAC,MAAM,CACX,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,MAAM,EACpB,YAAY,EAAE,MAAM,EACpB,SAAS,EAAE,SAAS,EACpB,SAAS,EAAE,SAAS,EACpB,KAAK,EAAE,MAAM,EACb,MAAM,CAAC,EAAE,eAAe,EACxB,gBAAgB,CAAC,EAAE,gBAAgB,GAClC,YAAY,CAsDd;IAED;;;OAGG;IACH,QAAQ,IAAI,MAAM,CAEjB;YAEa,uBAAuB;YA0BvB,WAAW;IA2BzB;;;;;;OAMG;IACH,OAAO,CAAC,cAAc;IAQtB,OAAO,CAAC,kBAAkB;IAO1B,OAAO,CAAC,aAAa;IAuBrB,OAAO,CAAC,gBAAgB;IA+BxB,YAAY,CAAC,QAAQ,EAAE,kBAAkB,GAAG,MAAM,IAAI,CAQrD;IAED,cAAc,IAAI,OAAO,CAExB;IAED,UAAU,IAAI,IAAI,CAMjB;CACF"}
@@ -10,7 +10,7 @@ import { jsonStringify } from '@aztec/foundation/json-rpc';
10
10
  import { promiseWithResolvers } from '@aztec/foundation/promise';
11
11
  import { schemaHasMethod } from '@aztec/foundation/schemas';
12
12
  import { decrypt, encrypt } from '../../crypto.js';
13
- import { WalletMessageType } from '../../types.js';
13
+ import { DEFAULT_HEARTBEAT_DEAD_AFTER_MS, DEFAULT_HEARTBEAT_INTERVAL_MS, NOOP_LOGGER, WalletMessageType } from '../../types.js';
14
14
  /**
15
15
  * A wallet implementation that communicates with a web wallet loaded in an iframe
16
16
  * using encrypted postMessage.
@@ -36,7 +36,12 @@ import { WalletMessageType } from '../../types.js';
36
36
  disconnected;
37
37
  disconnectCallbacks;
38
38
  messageListener;
39
- constructor(chainInfo, appId, walletId, sessionId, iframeWindow, walletOrigin, sharedKey){
39
+ heartbeatTimer;
40
+ lastInboundAt;
41
+ log;
42
+ heartbeatIntervalMs;
43
+ heartbeatDeadAfterMs;
44
+ constructor(chainInfo, appId, walletId, sessionId, iframeWindow, walletOrigin, sharedKey, logger, heartbeatOptions){
40
45
  this.chainInfo = chainInfo;
41
46
  this.appId = appId;
42
47
  this.walletId = walletId;
@@ -48,6 +53,11 @@ import { WalletMessageType } from '../../types.js';
48
53
  this.disconnected = false;
49
54
  this.disconnectCallbacks = [];
50
55
  this.messageListener = null;
56
+ this.heartbeatTimer = null;
57
+ this.lastInboundAt = 0;
58
+ this.log = logger ?? NOOP_LOGGER;
59
+ this.heartbeatIntervalMs = heartbeatOptions?.intervalMs ?? DEFAULT_HEARTBEAT_INTERVAL_MS;
60
+ this.heartbeatDeadAfterMs = heartbeatOptions?.deadAfterMs ?? DEFAULT_HEARTBEAT_DEAD_AFTER_MS;
51
61
  }
52
62
  /**
53
63
  * Creates a proxied IframeWallet that implements the {@link Wallet} interface.
@@ -63,9 +73,11 @@ import { WalletMessageType } from '../../types.js';
63
73
  * @param sharedKey - AES-256-GCM key derived from ECDH key exchange
64
74
  * @param chainInfo - Network information (chainId and version)
65
75
  * @param appId - Application identifier for the requesting dApp
76
+ * @param logger - Optional logger; defaults to a no-op logger to keep extension/page bundles small
77
+ * @param heartbeatOptions - Optional override for heartbeat tuning (mostly useful for tests)
66
78
  * @returns A proxied IframeWallet — call `.asWallet()` to get the typed `Wallet`
67
- */ static create(walletId, sessionId, iframeWindow, walletOrigin, sharedKey, chainInfo, appId) {
68
- const wallet = new IframeWallet(chainInfo, appId, walletId, sessionId, iframeWindow, walletOrigin, sharedKey);
79
+ */ static create(walletId, sessionId, iframeWindow, walletOrigin, sharedKey, chainInfo, appId, logger, heartbeatOptions) {
80
+ const wallet = new IframeWallet(chainInfo, appId, walletId, sessionId, iframeWindow, walletOrigin, sharedKey, logger, heartbeatOptions);
69
81
  wallet.messageListener = (event)=>{
70
82
  if (event.origin !== walletOrigin) {
71
83
  return;
@@ -74,9 +86,14 @@ import { WalletMessageType } from '../../types.js';
74
86
  if (!msg || typeof msg !== 'object') {
75
87
  return;
76
88
  }
77
- if (msg.type === WalletMessageType.SECURE_RESPONSE && msg.sessionId === sessionId) {
89
+ if (msg.sessionId !== sessionId) {
90
+ return;
91
+ }
92
+ // Any inbound traffic on our session counts as proof of liveness.
93
+ wallet.lastInboundAt = Date.now();
94
+ if (msg.type === WalletMessageType.SECURE_RESPONSE) {
78
95
  void wallet.handleEncryptedResponse(msg.encrypted);
79
- } else if (msg.type === WalletMessageType.SESSION_DISCONNECTED && msg.sessionId === sessionId) {
96
+ } else if (msg.type === WalletMessageType.SESSION_DISCONNECTED) {
80
97
  wallet.handleDisconnect();
81
98
  }
82
99
  };
@@ -122,8 +139,11 @@ import { WalletMessageType } from '../../types.js';
122
139
  pending.resolve(result);
123
140
  }
124
141
  this.inFlight.delete(messageId);
125
- } catch {
126
- // Decryption errors are silently ignored (message not for us or corrupted)
142
+ this.maybeStopHeartbeat();
143
+ } catch (err) {
144
+ this.log.warn('Failed to decrypt wallet response', {
145
+ err
146
+ });
127
147
  }
128
148
  }
129
149
  async postMessage(call) {
@@ -151,13 +171,62 @@ import { WalletMessageType } from '../../types.js';
151
171
  resolve,
152
172
  reject
153
173
  });
174
+ this.startHeartbeat();
154
175
  return promise;
155
176
  }
177
+ /**
178
+ * Start liveness probing while at least one request is in flight. PINGs are
179
+ * unencrypted control messages — older wallet handlers that don't understand
180
+ * them simply drop them, but any inbound traffic (PONG, encrypted response,
181
+ * disconnect notice) resets the idle timer, so a slow-but-alive legacy wallet
182
+ * never trips a false disconnect.
183
+ */ startHeartbeat() {
184
+ if (this.heartbeatTimer !== null || this.disconnected) {
185
+ return;
186
+ }
187
+ this.lastInboundAt = Date.now();
188
+ this.heartbeatTimer = setInterval(()=>this.heartbeatTick(), this.heartbeatIntervalMs);
189
+ }
190
+ maybeStopHeartbeat() {
191
+ if (this.inFlight.size === 0 && this.heartbeatTimer !== null) {
192
+ clearInterval(this.heartbeatTimer);
193
+ this.heartbeatTimer = null;
194
+ }
195
+ }
196
+ heartbeatTick() {
197
+ if (this.disconnected || this.inFlight.size === 0) {
198
+ this.maybeStopHeartbeat();
199
+ return;
200
+ }
201
+ const idleMs = Date.now() - this.lastInboundAt;
202
+ if (idleMs >= this.heartbeatDeadAfterMs) {
203
+ this.log.warn('Iframe wallet channel unresponsive — declaring disconnect', {
204
+ idleMs,
205
+ inFlight: this.inFlight.size
206
+ });
207
+ this.handleDisconnect();
208
+ return;
209
+ }
210
+ try {
211
+ this.iframeWindow.postMessage({
212
+ type: WalletMessageType.PING,
213
+ sessionId: this.sessionId
214
+ }, this.walletOrigin);
215
+ } catch (err) {
216
+ this.log.warn('Failed to send heartbeat PING', {
217
+ err
218
+ });
219
+ }
220
+ }
156
221
  handleDisconnect() {
157
222
  if (this.disconnected) {
158
223
  return;
159
224
  }
160
225
  this.disconnected = true;
226
+ if (this.heartbeatTimer !== null) {
227
+ clearInterval(this.heartbeatTimer);
228
+ this.heartbeatTimer = null;
229
+ }
161
230
  if (this.messageListener) {
162
231
  window.removeEventListener('message', this.messageListener);
163
232
  this.messageListener = null;
package/dest/types.d.ts CHANGED
@@ -22,7 +22,14 @@ export declare enum WalletMessageType {
22
22
  /** Encrypted wallet response wrapper */
23
23
  SECURE_RESPONSE = "aztec-wallet-secure-response",
24
24
  /** Session disconnected notification */
25
- SESSION_DISCONNECTED = "aztec-wallet-session-disconnected"
25
+ SESSION_DISCONNECTED = "aztec-wallet-session-disconnected",
26
+ /** Liveness probe sent by the dApp while a request is in flight */
27
+ PING = "aztec-wallet-ping",
28
+ /** Liveness response from the wallet. Any inbound message (including a regular
29
+ * encrypted response) is treated as proof of liveness, so a missing PONG alone
30
+ * never trips disconnect — the dApp also resets its liveness timer on traffic.
31
+ */
32
+ PONG = "aztec-wallet-pong"
26
33
  }
27
34
  /**
28
35
  * Information about an installed Aztec wallet.
@@ -132,4 +139,47 @@ export interface KeyExchangeResponse {
132
139
  * Callback invoked when a wallet connection is disconnected.
133
140
  */
134
141
  export type DisconnectCallback = () => void;
135
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy90eXBlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssRUFBRSxTQUFTLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUV6RCxPQUFPLEtBQUssRUFBRSxpQkFBaUIsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUVyRDs7O0dBR0c7QUFDSCxvQkFBWSxpQkFBaUI7SUFDM0Isa0RBQWtEO0lBQ2xELFNBQVMsMkJBQTJCO0lBQ3BDLHVDQUF1QztJQUN2QyxrQkFBa0Isb0NBQW9DO0lBQ3RELHNFQUFzRTtJQUN0RSxVQUFVLDRCQUE0QjtJQUN0QyxvREFBb0Q7SUFDcEQsb0JBQW9CLHNDQUFzQztJQUMxRCxxREFBcUQ7SUFDckQscUJBQXFCLHVDQUF1QztJQUM1RCwwQkFBMEI7SUFDMUIsWUFBWSx1QkFBdUI7SUFDbkMsdUNBQXVDO0lBQ3ZDLGNBQWMsZ0NBQWdDO0lBQzlDLHdDQUF3QztJQUN4QyxlQUFlLGlDQUFpQztJQUNoRCx3Q0FBd0M7SUFDeEMsb0JBQW9CLHNDQUFzQztDQUMzRDtBQUVEOzs7R0FHRztBQUNILE1BQU0sV0FBVyxVQUFVO0lBQ3pCLHVDQUF1QztJQUN2QyxFQUFFLEVBQUUsTUFBTSxDQUFDO0lBQ1gsaUNBQWlDO0lBQ2pDLElBQUksRUFBRSxNQUFNLENBQUM7SUFDYiwrQkFBK0I7SUFDL0IsSUFBSSxDQUFDLEVBQUUsTUFBTSxDQUFDO0lBQ2QscUJBQXFCO0lBQ3JCLE9BQU8sRUFBRSxNQUFNLENBQUM7Q0FDakI7QUFFRDs7O0dBR0c7QUFDSCxNQUFNLFdBQVcsbUJBQW9CLFNBQVEsVUFBVTtJQUNyRCxnRUFBZ0U7SUFDaEUsU0FBUyxFQUFFLGlCQUFpQixDQUFDO0lBQzdCOzs7O09BSUc7SUFDSCxnQkFBZ0IsQ0FBQyxFQUFFLE1BQU0sQ0FBQztDQUMzQjtBQUVEOztHQUVHO0FBQ0gsTUFBTSxXQUFXLGFBQWE7SUFDNUIsK0NBQStDO0lBQy9DLFNBQVMsRUFBRSxNQUFNLENBQUM7SUFDbEIsZ0NBQWdDO0lBQ2hDLElBQUksRUFBRSxNQUFNLENBQUM7SUFDYiwrQkFBK0I7SUFDL0IsSUFBSSxFQUFFLE9BQU8sRUFBRSxDQUFDO0lBQ2hCLHdCQUF3QjtJQUN4QixTQUFTLEVBQUUsU0FBUyxDQUFDO0lBQ3JCLHdDQUF3QztJQUN4QyxLQUFLLEVBQUUsTUFBTSxDQUFDO0lBQ2QsNENBQTRDO0lBQzVDLFFBQVEsRUFBRSxNQUFNLENBQUM7Q0FDbEI7QUFFRDs7R0FFRztBQUNILE1BQU0sV0FBVyxjQUFjO0lBQzdCLHNDQUFzQztJQUN0QyxTQUFTLEVBQUUsTUFBTSxDQUFDO0lBQ2xCLGtDQUFrQztJQUNsQyxNQUFNLENBQUMsRUFBRSxPQUFPLENBQUM7SUFDakIsNkJBQTZCO0lBQzdCLEtBQUssQ0FBQyxFQUFFLE9BQU8sQ0FBQztJQUNoQix1Q0FBdUM7SUFDdkMsUUFBUSxFQUFFLE1BQU0sQ0FBQztDQUNsQjtBQUVEOztHQUVHO0FBQ0gsTUFBTSxXQUFXLGdCQUFnQjtJQUMvQixpQ0FBaUM7SUFDakMsSUFBSSxFQUFFLGlCQUFpQixDQUFDLFNBQVMsQ0FBQztJQUNsQyxpQkFBaUI7SUFDakIsU0FBUyxFQUFFLE1BQU0sQ0FBQztJQUNsQix3Q0FBd0M7SUFDeEMsS0FBSyxFQUFFLE1BQU0sQ0FBQztJQUNkLGlFQUFpRTtJQUNqRSxTQUFTLEVBQUUsU0FBUyxDQUFDO0NBQ3RCO0FBRUQ7O0dBRUc7QUFDSCxNQUFNLFdBQVcsaUJBQWlCO0lBQ2hDLDBDQUEwQztJQUMxQyxJQUFJLEVBQUUsaUJBQWlCLENBQUMsa0JBQWtCLENBQUM7SUFDM0MsZ0RBQWdEO0lBQ2hELFNBQVMsRUFBRSxNQUFNLENBQUM7SUFDbEIsK0JBQStCO0lBQy9CLFVBQVUsRUFBRSxVQUFVLENBQUM7Q0FDeEI7QUFFRDs7R0FFRztBQUNILE1BQU0sV0FBVyxrQkFBa0I7SUFDakMsbUJBQW1CO0lBQ25CLElBQUksRUFBRSxpQkFBaUIsQ0FBQyxvQkFBb0IsQ0FBQztJQUM3QyxnREFBZ0Q7SUFDaEQsU0FBUyxFQUFFLE1BQU0sQ0FBQztJQUNsQix3REFBd0Q7SUFDeEQsU0FBUyxFQUFFLGlCQUFpQixDQUFDO0NBQzlCO0FBRUQ7O0dBRUc7QUFDSCxNQUFNLFdBQVcsbUJBQW1CO0lBQ2xDLG1CQUFtQjtJQUNuQixJQUFJLEVBQUUsaUJBQWlCLENBQUMscUJBQXFCLENBQUM7SUFDOUMsZ0RBQWdEO0lBQ2hELFNBQVMsRUFBRSxNQUFNLENBQUM7SUFDbEIsMERBQTBEO0lBQzFELFNBQVMsRUFBRSxpQkFBaUIsQ0FBQztDQUM5QjtBQUVEOztHQUVHO0FBQ0gsTUFBTSxNQUFNLGtCQUFrQixHQUFHLE1BQU0sSUFBSSxDQUFDIn0=
142
+ /**
143
+ * Default heartbeat tuning shared by both transports.
144
+ *
145
+ * - `intervalMs`: how often the dApp sends PING probes while a request is in flight.
146
+ * - `deadAfterMs`: how long the channel can stay silent (no PONG, no encrypted
147
+ * response, no DISCONNECT) before the dApp declares the wallet unreachable
148
+ * and rejects all in-flight requests. Generous enough that long-running
149
+ * operations (proveTx, sendTx) on legacy wallets that don't reply to PING
150
+ * still succeed — any inbound traffic resets the timer.
151
+ */
152
+ export declare const DEFAULT_HEARTBEAT_INTERVAL_MS = 5000;
153
+ export declare const DEFAULT_HEARTBEAT_DEAD_AFTER_MS = 300000;
154
+ /** Override knobs for the heartbeat — mostly useful for tests. */
155
+ export interface HeartbeatOptions {
156
+ /** How often to send PING probes while a request is in flight (ms). */
157
+ intervalMs?: number;
158
+ /** Idle ceiling before declaring disconnect (ms). */
159
+ deadAfterMs?: number;
160
+ }
161
+ /**
162
+ * Minimal logger surface used by the wallet SDK.
163
+ *
164
+ * Defined locally so that wallet hosts (browser extensions, iframe wallet pages)
165
+ * can pass a simple `console`-backed logger without pulling in the full
166
+ * `@aztec/foundation` logging runtime, which is non-trivial to bundle in those
167
+ * contexts. Structurally compatible with `Logger` from `@aztec/foundation/log`,
168
+ * so dApp-side callers can pass that type directly.
169
+ */
170
+ export interface WalletSdkLogger {
171
+ /** Diagnostic messages — typically discarded in production. */
172
+ debug: (message: string, data?: unknown) => void;
173
+ /** Informational messages — significant lifecycle events. */
174
+ info: (message: string, data?: unknown) => void;
175
+ /** Recoverable problems — channel decryption failure, missed heartbeats, etc. */
176
+ warn: (message: string, data?: unknown) => void;
177
+ /** Errors that prevent normal operation. */
178
+ error: (message: string, errOrData?: unknown, data?: unknown) => void;
179
+ }
180
+ /**
181
+ * No-op logger used as the default when callers don't provide one. Discards all
182
+ * messages — wallet hosts that want diagnostics should pass their own logger.
183
+ */
184
+ export declare const NOOP_LOGGER: WalletSdkLogger;
185
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy90eXBlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssRUFBRSxTQUFTLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUV6RCxPQUFPLEtBQUssRUFBRSxpQkFBaUIsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUVyRDs7O0dBR0c7QUFDSCxvQkFBWSxpQkFBaUI7SUFDM0Isa0RBQWtEO0lBQ2xELFNBQVMsMkJBQTJCO0lBQ3BDLHVDQUF1QztJQUN2QyxrQkFBa0Isb0NBQW9DO0lBQ3RELHNFQUFzRTtJQUN0RSxVQUFVLDRCQUE0QjtJQUN0QyxvREFBb0Q7SUFDcEQsb0JBQW9CLHNDQUFzQztJQUMxRCxxREFBcUQ7SUFDckQscUJBQXFCLHVDQUF1QztJQUM1RCwwQkFBMEI7SUFDMUIsWUFBWSx1QkFBdUI7SUFDbkMsdUNBQXVDO0lBQ3ZDLGNBQWMsZ0NBQWdDO0lBQzlDLHdDQUF3QztJQUN4QyxlQUFlLGlDQUFpQztJQUNoRCx3Q0FBd0M7SUFDeEMsb0JBQW9CLHNDQUFzQztJQUMxRCxtRUFBbUU7SUFDbkUsSUFBSSxzQkFBc0I7SUFDMUI7OztPQUdHO0lBQ0gsSUFBSSxzQkFBc0I7Q0FDM0I7QUFFRDs7O0dBR0c7QUFDSCxNQUFNLFdBQVcsVUFBVTtJQUN6Qix1Q0FBdUM7SUFDdkMsRUFBRSxFQUFFLE1BQU0sQ0FBQztJQUNYLGlDQUFpQztJQUNqQyxJQUFJLEVBQUUsTUFBTSxDQUFDO0lBQ2IsK0JBQStCO0lBQy9CLElBQUksQ0FBQyxFQUFFLE1BQU0sQ0FBQztJQUNkLHFCQUFxQjtJQUNyQixPQUFPLEVBQUUsTUFBTSxDQUFDO0NBQ2pCO0FBRUQ7OztHQUdHO0FBQ0gsTUFBTSxXQUFXLG1CQUFvQixTQUFRLFVBQVU7SUFDckQsZ0VBQWdFO0lBQ2hFLFNBQVMsRUFBRSxpQkFBaUIsQ0FBQztJQUM3Qjs7OztPQUlHO0lBQ0gsZ0JBQWdCLENBQUMsRUFBRSxN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
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dest/types.js CHANGED
@@ -11,5 +11,30 @@
11
11
  /** Encrypted wallet message wrapper */ WalletMessageType["SECURE_MESSAGE"] = "aztec-wallet-secure-message";
12
12
  /** Encrypted wallet response wrapper */ WalletMessageType["SECURE_RESPONSE"] = "aztec-wallet-secure-response";
13
13
  /** Session disconnected notification */ WalletMessageType["SESSION_DISCONNECTED"] = "aztec-wallet-session-disconnected";
14
+ /** Liveness probe sent by the dApp while a request is in flight */ WalletMessageType["PING"] = "aztec-wallet-ping";
15
+ /** Liveness response from the wallet. Any inbound message (including a regular
16
+ * encrypted response) is treated as proof of liveness, so a missing PONG alone
17
+ * never trips disconnect — the dApp also resets its liveness timer on traffic.
18
+ */ WalletMessageType["PONG"] = "aztec-wallet-pong";
14
19
  return WalletMessageType;
15
20
  }({});
21
+ /**
22
+ * Default heartbeat tuning shared by both transports.
23
+ *
24
+ * - `intervalMs`: how often the dApp sends PING probes while a request is in flight.
25
+ * - `deadAfterMs`: how long the channel can stay silent (no PONG, no encrypted
26
+ * response, no DISCONNECT) before the dApp declares the wallet unreachable
27
+ * and rejects all in-flight requests. Generous enough that long-running
28
+ * operations (proveTx, sendTx) on legacy wallets that don't reply to PING
29
+ * still succeed — any inbound traffic resets the timer.
30
+ */ export const DEFAULT_HEARTBEAT_INTERVAL_MS = 5_000;
31
+ export const DEFAULT_HEARTBEAT_DEAD_AFTER_MS = 300_000;
32
+ /**
33
+ * No-op logger used as the default when callers don't provide one. Discards all
34
+ * messages — wallet hosts that want diagnostics should pass their own logger.
35
+ */ export const NOOP_LOGGER = {
36
+ debug: ()=>{},
37
+ info: ()=>{},
38
+ warn: ()=>{},
39
+ error: ()=>{}
40
+ };
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": "0.0.1-commit.fff30aa",
4
+ "version": "0.0.1-dev",
5
5
  "type": "module",
6
6
  "exports": {
7
7
  "./base-wallet": "./dest/base-wallet/index.js",
@@ -75,15 +75,15 @@
75
75
  ]
76
76
  },
77
77
  "dependencies": {
78
- "@aztec/aztec.js": "0.0.1-commit.fff30aa",
79
- "@aztec/constants": "0.0.1-commit.fff30aa",
80
- "@aztec/entrypoints": "0.0.1-commit.fff30aa",
81
- "@aztec/foundation": "0.0.1-commit.fff30aa",
82
- "@aztec/pxe": "0.0.1-commit.fff30aa",
83
- "@aztec/stdlib": "0.0.1-commit.fff30aa"
78
+ "@aztec/aztec.js": "0.0.1-dev",
79
+ "@aztec/constants": "0.0.1-dev",
80
+ "@aztec/entrypoints": "0.0.1-dev",
81
+ "@aztec/foundation": "0.0.1-dev",
82
+ "@aztec/pxe": "0.0.1-dev",
83
+ "@aztec/stdlib": "0.0.1-dev"
84
84
  },
85
85
  "devDependencies": {
86
- "@aztec/noir-contracts.js": "0.0.1-commit.fff30aa",
86
+ "@aztec/noir-contracts.js": "0.0.1-dev",
87
87
  "@jest/globals": "^30.0.0",
88
88
  "@types/jest": "^30.0.0",
89
89
  "@types/node": "^22.15.17",