@haex-space/vault-sdk 2.9.3 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -198,7 +198,10 @@ declare class DatabaseAPI {
198
198
  query<T>(query: string, params?: unknown[]): Promise<T[]>;
199
199
  queryOne<T = unknown>(query: string, params?: unknown[]): Promise<T | null>;
200
200
  execute(query: string, params?: unknown[]): Promise<DatabaseQueryResult>;
201
- transaction(statements: string[]): Promise<void>;
201
+ transaction(statements: Array<{
202
+ sql: string;
203
+ params?: unknown[];
204
+ }>): Promise<void>;
202
205
  createTable(tableName: string, columns: string): Promise<void>;
203
206
  dropTable(tableName: string): Promise<void>;
204
207
  /**
@@ -1204,6 +1207,13 @@ declare class HaexVaultSdk {
1204
1207
  private readonly externalRequestHandlers;
1205
1208
  private readonly reactiveSubscribers;
1206
1209
  private messageHandler;
1210
+ /**
1211
+ * MessagePort obtained from the main window during iframe-mode handshake.
1212
+ * `null` until `initIframe()` completes successfully. Every outbound
1213
+ * request in iframe mode flows through this port; `sendPostMessage` rejects
1214
+ * if called before the handshake finishes.
1215
+ */
1216
+ private hostPort;
1207
1217
  private readyPromise;
1208
1218
  private resolveReady;
1209
1219
  private setupPromise;
@@ -198,7 +198,10 @@ declare class DatabaseAPI {
198
198
  query<T>(query: string, params?: unknown[]): Promise<T[]>;
199
199
  queryOne<T = unknown>(query: string, params?: unknown[]): Promise<T | null>;
200
200
  execute(query: string, params?: unknown[]): Promise<DatabaseQueryResult>;
201
- transaction(statements: string[]): Promise<void>;
201
+ transaction(statements: Array<{
202
+ sql: string;
203
+ params?: unknown[];
204
+ }>): Promise<void>;
202
205
  createTable(tableName: string, columns: string): Promise<void>;
203
206
  dropTable(tableName: string): Promise<void>;
204
207
  /**
@@ -1204,6 +1207,13 @@ declare class HaexVaultSdk {
1204
1207
  private readonly externalRequestHandlers;
1205
1208
  private readonly reactiveSubscribers;
1206
1209
  private messageHandler;
1210
+ /**
1211
+ * MessagePort obtained from the main window during iframe-mode handshake.
1212
+ * `null` until `initIframe()` completes successfully. Every outbound
1213
+ * request in iframe mode flows through this port; `sendPostMessage` rejects
1214
+ * if called before the handshake finishes.
1215
+ */
1216
+ private hostPort;
1207
1217
  private readyPromise;
1208
1218
  private resolveReady;
1209
1219
  private setupPromise;
package/dist/index.d.mts CHANGED
@@ -1,5 +1,5 @@
1
- import { H as HaexVaultSdk } from './client-CUZX5oKJ.mjs';
2
- export { A as AuthorizedClient, B as BlockedClient, D as DatabaseAPI, a as DecryptedSpace, b as Device, c as DeviceInfo, d as DeviceType, e as DirEntry, E as ExternalAuthDecision, f as ExternalConnection, g as ExternalConnectionErrorCode, h as ExternalConnectionState, i as ExternalRequest, j as ExternalRequestEvent, k as ExternalRequestHandler, l as ExternalRequestPayload, m as ExternalResponse, F as FileStat, n as FilesystemAPI, K as KnownPath, o as KnownPaths, L as LOCALSEND_EVENTS, p as LocalSendAPI, q as LocalSendEvent, r as LocalSendFileInfo, s as LocalSendSettings, P as PendingAuthorization, t as PendingTransfer, u as PermissionsAPI, v as RemoteAddBackendRequest, w as RemoteS3Config, x as RemoteS3PublicConfig, R as RemoteStorageAPI, y as RemoteStorageBackendInfo, z as RemoteStorageObjectInfo, U as RemoteUpdateBackendRequest, C as RequestedExtension, G as SelectFileOptions, I as SelectFolderOptions, J as ServerInfo, M as ServerStatus, N as SessionAuthorization, O as SharedSpace, Q as ShellAPI, T as ShellCreateOptions, V as ShellCreateResponse, W as ShellExitEvent, X as ShellOutputEvent, Y as SpaceAccessTokenInfo, Z as SpaceAssignment, _ as SpaceInvite, $ as SpaceKeyGrantInfo, a0 as SpaceMemberInfo, a1 as SpacesAPI, a2 as SyncBackendInfo, a3 as TransferDirection, a4 as TransferProgress, a5 as TransferState, a6 as WebAPI, a7 as canExternalClientSendRequests, a8 as isExternalClientConnected } from './client-CUZX5oKJ.mjs';
1
+ import { H as HaexVaultSdk } from './client-C0DPNG62.mjs';
2
+ export { A as AuthorizedClient, B as BlockedClient, D as DatabaseAPI, a as DecryptedSpace, b as Device, c as DeviceInfo, d as DeviceType, e as DirEntry, E as ExternalAuthDecision, f as ExternalConnection, g as ExternalConnectionErrorCode, h as ExternalConnectionState, i as ExternalRequest, j as ExternalRequestEvent, k as ExternalRequestHandler, l as ExternalRequestPayload, m as ExternalResponse, F as FileStat, n as FilesystemAPI, K as KnownPath, o as KnownPaths, L as LOCALSEND_EVENTS, p as LocalSendAPI, q as LocalSendEvent, r as LocalSendFileInfo, s as LocalSendSettings, P as PendingAuthorization, t as PendingTransfer, u as PermissionsAPI, v as RemoteAddBackendRequest, w as RemoteS3Config, x as RemoteS3PublicConfig, R as RemoteStorageAPI, y as RemoteStorageBackendInfo, z as RemoteStorageObjectInfo, U as RemoteUpdateBackendRequest, C as RequestedExtension, G as SelectFileOptions, I as SelectFolderOptions, J as ServerInfo, M as ServerStatus, N as SessionAuthorization, O as SharedSpace, Q as ShellAPI, T as ShellCreateOptions, V as ShellCreateResponse, W as ShellExitEvent, X as ShellOutputEvent, Y as SpaceAccessTokenInfo, Z as SpaceAssignment, _ as SpaceInvite, $ as SpaceKeyGrantInfo, a0 as SpaceMemberInfo, a1 as SpacesAPI, a2 as SyncBackendInfo, a3 as TransferDirection, a4 as TransferProgress, a5 as TransferState, a6 as WebAPI, a7 as canExternalClientSendRequests, a8 as isExternalClientConnected } from './client-C0DPNG62.mjs';
3
3
  import { E as ExtensionManifest, h as SignedClaimPresentation, H as HaexHubConfig } from './types-DmCSegdY.mjs';
4
4
  export { A as ApplicationContext, C as ClaimRequirement, i as ContextChangedEvent, j as DEFAULT_TIMEOUT, k as DatabaseColumnInfo, l as DatabaseExecuteParams, m as DatabasePermission, g as DatabasePermissionRequest, n as DatabaseQueryParams, D as DatabaseQueryResult, o as DatabaseTableInfo, c as EXTERNAL_EVENTS, p as ErrorCode, f as EventCallback, a as ExtensionInfo, q as ExtensionRuntimeMode, r as ExternalEvent, F as FileChangeEvent, s as FileChangePayload, t as FileChangeType, u as FilteredSyncTablesResult, v as HAEXTENSION_EVENTS, b as HaexHubEvent, w as HaexHubRequest, x as HaexHubResponse, y as HaexVaultSdkError, z as HaextensionEvent, I as IdentityClaim, B as ManifestI18nEntry, G as PermissionDeniedError, J as PermissionErrorBase, K as PermissionErrorCode, L as PermissionPromptError, P as PermissionResponse, N as PermissionStatus, O as SHELL_EVENTS, Q as SearchQuery, R as SearchRequestEvent, S as SearchResult, T as ShellEvent, U as SyncTablesUpdatedEvent, V as TABLE_SEPARATOR, W as WebRequestOptions, e as WebResponse, X as getTableName, Y as isPermissionDeniedError, Z as isPermissionError, _ as isPermissionPromptError } from './types-DmCSegdY.mjs';
5
5
  export { H as HaextensionConfig } from './config-D_HXjsEV.mjs';
@@ -228,6 +228,23 @@ declare const HAEXSPACE_MESSAGE_TYPES: {
228
228
  readonly DEBUG: "haexspace:debug";
229
229
  /** Console forwarding from extension iframe */
230
230
  readonly CONSOLE_FORWARD: "console.forward";
231
+ /**
232
+ * Sent from main window to iframe on the shared window listener, carrying
233
+ * one `MessagePort` in `event.ports[0]`. Once received, the SDK switches
234
+ * to port-based messaging and never reads the window listener again.
235
+ *
236
+ * Payload: `{ type: PORT_INIT }` — no data. The port itself is the payload.
237
+ */
238
+ readonly PORT_INIT: "haexspace:port:init";
239
+ /**
240
+ * Sent from SDK to main window *over the MessagePort* after the port is
241
+ * installed. Main uses this to mark the iframe as ready and flush any
242
+ * events buffered during the handshake window. Only valid on the port —
243
+ * a READY sent over window.postMessage is ignored.
244
+ *
245
+ * Payload: `{ type: PORT_READY }` — no data.
246
+ */
247
+ readonly PORT_READY: "haexspace:port:ready";
231
248
  };
232
249
  type HaexspaceMessageType = (typeof HAEXSPACE_MESSAGE_TYPES)[keyof typeof HAEXSPACE_MESSAGE_TYPES];
233
250
 
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { H as HaexVaultSdk } from './client-BRsLRztg.js';
2
- export { A as AuthorizedClient, B as BlockedClient, D as DatabaseAPI, a as DecryptedSpace, b as Device, c as DeviceInfo, d as DeviceType, e as DirEntry, E as ExternalAuthDecision, f as ExternalConnection, g as ExternalConnectionErrorCode, h as ExternalConnectionState, i as ExternalRequest, j as ExternalRequestEvent, k as ExternalRequestHandler, l as ExternalRequestPayload, m as ExternalResponse, F as FileStat, n as FilesystemAPI, K as KnownPath, o as KnownPaths, L as LOCALSEND_EVENTS, p as LocalSendAPI, q as LocalSendEvent, r as LocalSendFileInfo, s as LocalSendSettings, P as PendingAuthorization, t as PendingTransfer, u as PermissionsAPI, v as RemoteAddBackendRequest, w as RemoteS3Config, x as RemoteS3PublicConfig, R as RemoteStorageAPI, y as RemoteStorageBackendInfo, z as RemoteStorageObjectInfo, U as RemoteUpdateBackendRequest, C as RequestedExtension, G as SelectFileOptions, I as SelectFolderOptions, J as ServerInfo, M as ServerStatus, N as SessionAuthorization, O as SharedSpace, Q as ShellAPI, T as ShellCreateOptions, V as ShellCreateResponse, W as ShellExitEvent, X as ShellOutputEvent, Y as SpaceAccessTokenInfo, Z as SpaceAssignment, _ as SpaceInvite, $ as SpaceKeyGrantInfo, a0 as SpaceMemberInfo, a1 as SpacesAPI, a2 as SyncBackendInfo, a3 as TransferDirection, a4 as TransferProgress, a5 as TransferState, a6 as WebAPI, a7 as canExternalClientSendRequests, a8 as isExternalClientConnected } from './client-BRsLRztg.js';
1
+ import { H as HaexVaultSdk } from './client-B_B6rLIw.js';
2
+ export { A as AuthorizedClient, B as BlockedClient, D as DatabaseAPI, a as DecryptedSpace, b as Device, c as DeviceInfo, d as DeviceType, e as DirEntry, E as ExternalAuthDecision, f as ExternalConnection, g as ExternalConnectionErrorCode, h as ExternalConnectionState, i as ExternalRequest, j as ExternalRequestEvent, k as ExternalRequestHandler, l as ExternalRequestPayload, m as ExternalResponse, F as FileStat, n as FilesystemAPI, K as KnownPath, o as KnownPaths, L as LOCALSEND_EVENTS, p as LocalSendAPI, q as LocalSendEvent, r as LocalSendFileInfo, s as LocalSendSettings, P as PendingAuthorization, t as PendingTransfer, u as PermissionsAPI, v as RemoteAddBackendRequest, w as RemoteS3Config, x as RemoteS3PublicConfig, R as RemoteStorageAPI, y as RemoteStorageBackendInfo, z as RemoteStorageObjectInfo, U as RemoteUpdateBackendRequest, C as RequestedExtension, G as SelectFileOptions, I as SelectFolderOptions, J as ServerInfo, M as ServerStatus, N as SessionAuthorization, O as SharedSpace, Q as ShellAPI, T as ShellCreateOptions, V as ShellCreateResponse, W as ShellExitEvent, X as ShellOutputEvent, Y as SpaceAccessTokenInfo, Z as SpaceAssignment, _ as SpaceInvite, $ as SpaceKeyGrantInfo, a0 as SpaceMemberInfo, a1 as SpacesAPI, a2 as SyncBackendInfo, a3 as TransferDirection, a4 as TransferProgress, a5 as TransferState, a6 as WebAPI, a7 as canExternalClientSendRequests, a8 as isExternalClientConnected } from './client-B_B6rLIw.js';
3
3
  import { E as ExtensionManifest, h as SignedClaimPresentation, H as HaexHubConfig } from './types-DmCSegdY.js';
4
4
  export { A as ApplicationContext, C as ClaimRequirement, i as ContextChangedEvent, j as DEFAULT_TIMEOUT, k as DatabaseColumnInfo, l as DatabaseExecuteParams, m as DatabasePermission, g as DatabasePermissionRequest, n as DatabaseQueryParams, D as DatabaseQueryResult, o as DatabaseTableInfo, c as EXTERNAL_EVENTS, p as ErrorCode, f as EventCallback, a as ExtensionInfo, q as ExtensionRuntimeMode, r as ExternalEvent, F as FileChangeEvent, s as FileChangePayload, t as FileChangeType, u as FilteredSyncTablesResult, v as HAEXTENSION_EVENTS, b as HaexHubEvent, w as HaexHubRequest, x as HaexHubResponse, y as HaexVaultSdkError, z as HaextensionEvent, I as IdentityClaim, B as ManifestI18nEntry, G as PermissionDeniedError, J as PermissionErrorBase, K as PermissionErrorCode, L as PermissionPromptError, P as PermissionResponse, N as PermissionStatus, O as SHELL_EVENTS, Q as SearchQuery, R as SearchRequestEvent, S as SearchResult, T as ShellEvent, U as SyncTablesUpdatedEvent, V as TABLE_SEPARATOR, W as WebRequestOptions, e as WebResponse, X as getTableName, Y as isPermissionDeniedError, Z as isPermissionError, _ as isPermissionPromptError } from './types-DmCSegdY.js';
5
5
  export { H as HaextensionConfig } from './config-D_HXjsEV.js';
@@ -228,6 +228,23 @@ declare const HAEXSPACE_MESSAGE_TYPES: {
228
228
  readonly DEBUG: "haexspace:debug";
229
229
  /** Console forwarding from extension iframe */
230
230
  readonly CONSOLE_FORWARD: "console.forward";
231
+ /**
232
+ * Sent from main window to iframe on the shared window listener, carrying
233
+ * one `MessagePort` in `event.ports[0]`. Once received, the SDK switches
234
+ * to port-based messaging and never reads the window listener again.
235
+ *
236
+ * Payload: `{ type: PORT_INIT }` — no data. The port itself is the payload.
237
+ */
238
+ readonly PORT_INIT: "haexspace:port:init";
239
+ /**
240
+ * Sent from SDK to main window *over the MessagePort* after the port is
241
+ * installed. Main uses this to mark the iframe as ready and flush any
242
+ * events buffered during the handshake window. Only valid on the port —
243
+ * a READY sent over window.postMessage is ignored.
244
+ *
245
+ * Payload: `{ type: PORT_READY }` — no data.
246
+ */
247
+ readonly PORT_READY: "haexspace:port:ready";
231
248
  };
232
249
  type HaexspaceMessageType = (typeof HAEXSPACE_MESSAGE_TYPES)[keyof typeof HAEXSPACE_MESSAGE_TYPES];
233
250
 
package/dist/index.js CHANGED
@@ -541,7 +541,24 @@ var HAEXSPACE_MESSAGE_TYPES = {
541
541
  /** Debug message for development/troubleshooting */
542
542
  DEBUG: "haexspace:debug",
543
543
  /** Console forwarding from extension iframe */
544
- CONSOLE_FORWARD: "console.forward"
544
+ CONSOLE_FORWARD: "console.forward",
545
+ /**
546
+ * Sent from main window to iframe on the shared window listener, carrying
547
+ * one `MessagePort` in `event.ports[0]`. Once received, the SDK switches
548
+ * to port-based messaging and never reads the window listener again.
549
+ *
550
+ * Payload: `{ type: PORT_INIT }` — no data. The port itself is the payload.
551
+ */
552
+ PORT_INIT: "haexspace:port:init",
553
+ /**
554
+ * Sent from SDK to main window *over the MessagePort* after the port is
555
+ * installed. Main uses this to mark the iframe as ready and flush any
556
+ * events buffered during the handshake window. Only valid on the port —
557
+ * a READY sent over window.postMessage is ignored.
558
+ *
559
+ * Payload: `{ type: PORT_READY }` — no data.
560
+ */
561
+ PORT_READY: "haexspace:port:ready"
545
562
  };
546
563
 
547
564
  // src/polyfills/debug.ts
@@ -1096,7 +1113,7 @@ var DatabaseAPI = class {
1096
1113
  }
1097
1114
  async transaction(statements) {
1098
1115
  await this.client.request(DATABASE_COMMANDS.transaction, {
1099
- statements
1116
+ statements: statements.map((s) => [s.sql, s.params || []])
1100
1117
  });
1101
1118
  }
1102
1119
  async createTable(tableName, columns) {
@@ -2074,6 +2091,7 @@ function parseTableName(fullTableName) {
2074
2091
  }
2075
2092
 
2076
2093
  // src/client/init.ts
2094
+ var PORT_HANDSHAKE_TIMEOUT_MS = 1e4;
2077
2095
  function isInIframe() {
2078
2096
  return window.self !== window.top;
2079
2097
  }
@@ -2330,11 +2348,14 @@ async function initIframeMode(ctx, log, messageHandler, request) {
2330
2348
  if (!isInIframe()) {
2331
2349
  throw new HaexVaultSdkError("NOT_IN_IFRAME" /* NOT_IN_IFRAME */, "errors.not_in_iframe");
2332
2350
  }
2351
+ const port = await waitForHostPortAsync(log);
2333
2352
  ctx.handlers.messageHandler = messageHandler;
2334
- window.addEventListener("message", messageHandler);
2353
+ port.addEventListener("message", messageHandler);
2354
+ port.start();
2355
+ port.postMessage({ type: HAEXSPACE_MESSAGE_TYPES.PORT_READY });
2335
2356
  ctx.state.isNativeWindow = false;
2336
2357
  ctx.state.initialized = true;
2337
- log("HaexVault SDK initialized in iframe mode");
2358
+ log("HaexVault SDK initialized in iframe mode (MessagePort transport)");
2338
2359
  if (ctx.config.manifest) {
2339
2360
  ctx.state.extensionInfo = {
2340
2361
  publicKey: ctx.config.manifest.publicKey,
@@ -2348,7 +2369,42 @@ async function initIframeMode(ctx, log, messageHandler, request) {
2348
2369
  const context = await request(EXTENSION_COMMANDS.getContext);
2349
2370
  ctx.state.context = context;
2350
2371
  log("Application context received:", context);
2351
- return { context };
2372
+ return { context, port };
2373
+ }
2374
+ function waitForHostPortAsync(log) {
2375
+ return new Promise((resolve, reject) => {
2376
+ let settled = false;
2377
+ const cleanup = () => {
2378
+ window.removeEventListener("message", handler);
2379
+ };
2380
+ const timeoutId = setTimeout(() => {
2381
+ if (settled) return;
2382
+ settled = true;
2383
+ cleanup();
2384
+ reject(
2385
+ new HaexVaultSdkError(
2386
+ "TIMEOUT" /* TIMEOUT */,
2387
+ "errors.port_handshake_timeout",
2388
+ { timeout: PORT_HANDSHAKE_TIMEOUT_MS }
2389
+ )
2390
+ );
2391
+ }, PORT_HANDSHAKE_TIMEOUT_MS);
2392
+ const handler = (event) => {
2393
+ const type = event.data?.type;
2394
+ if (type !== HAEXSPACE_MESSAGE_TYPES.PORT_INIT) return;
2395
+ const port = event.ports[0];
2396
+ if (!port) {
2397
+ log("PORT_INIT received but event.ports is empty \u2014 ignoring");
2398
+ return;
2399
+ }
2400
+ if (settled) return;
2401
+ settled = true;
2402
+ clearTimeout(timeoutId);
2403
+ cleanup();
2404
+ resolve(port);
2405
+ };
2406
+ window.addEventListener("message", handler);
2407
+ });
2352
2408
  }
2353
2409
  function sendDebugInfo(config) {
2354
2410
  if (!config.debug) return;
@@ -2372,7 +2428,15 @@ postMessage error: ${e}`);
2372
2428
  function generateRequestId(counter) {
2373
2429
  return `req_${counter}`;
2374
2430
  }
2375
- function sendPostMessage(method, params, requestId, config, extensionInfo, pendingRequests) {
2431
+ function sendPostMessage(method, params, requestId, config, extensionInfo, pendingRequests, port) {
2432
+ if (!port) {
2433
+ return Promise.reject(
2434
+ new HaexVaultSdkError(
2435
+ "EXTENSION_NOT_INITIALIZED" /* EXTENSION_NOT_INITIALIZED */,
2436
+ "errors.port_not_connected"
2437
+ )
2438
+ );
2439
+ }
2376
2440
  const request = {
2377
2441
  method,
2378
2442
  params,
@@ -2388,17 +2452,16 @@ function sendPostMessage(method, params, requestId, config, extensionInfo, pendi
2388
2452
  );
2389
2453
  }, config.timeout);
2390
2454
  pendingRequests.set(requestId, { resolve, reject, timeout });
2391
- const targetOrigin = "*";
2392
2455
  if (config.debug) {
2393
2456
  console.log("[SDK Debug] ========== Sending Request ==========");
2394
2457
  console.log("[SDK Debug] Request ID:", requestId);
2395
2458
  console.log("[SDK Debug] Method:", request.method);
2396
2459
  console.log("[SDK Debug] Params:", request.params);
2397
- console.log("[SDK Debug] Target origin:", targetOrigin);
2460
+ console.log("[SDK Debug] Transport: MessagePort");
2398
2461
  console.log("[SDK Debug] Extension info:", extensionInfo);
2399
2462
  console.log("[SDK Debug] ========================================");
2400
2463
  }
2401
- window.parent.postMessage({ id: requestId, ...request }, targetOrigin);
2464
+ port.postMessage({ id: requestId, ...request });
2402
2465
  });
2403
2466
  }
2404
2467
  async function sendInvoke(method, params, config, _log) {
@@ -2417,11 +2480,6 @@ function createMessageHandler(config, pendingRequests, extensionInfo, onEvent) {
2417
2480
  return (event) => {
2418
2481
  if (config.debug) {
2419
2482
  console.log("[SDK Debug] ========== Message Received ==========");
2420
- console.log("[SDK Debug] Event origin:", event.origin);
2421
- console.log(
2422
- "[SDK Debug] Event source:",
2423
- event.source === window.parent ? "parent window" : "unknown"
2424
- );
2425
2483
  console.log("[SDK Debug] Event data:", event.data);
2426
2484
  console.log("[SDK Debug] Extension info loaded:", !!extensionInfo());
2427
2485
  console.log(
@@ -2429,12 +2487,6 @@ function createMessageHandler(config, pendingRequests, extensionInfo, onEvent) {
2429
2487
  pendingRequests.size
2430
2488
  );
2431
2489
  }
2432
- if (event.source !== window.parent) {
2433
- if (config.debug) {
2434
- console.error("[SDK Debug] \u274C REJECTED: Message not from parent window!");
2435
- }
2436
- return;
2437
- }
2438
2490
  const data = event.data;
2439
2491
  if ("id" in data && pendingRequests.has(data.id)) {
2440
2492
  if (config.debug) {
@@ -2656,6 +2708,13 @@ var HaexVaultSdk = class {
2656
2708
  this.reactiveSubscribers = /* @__PURE__ */ new Set();
2657
2709
  // Handlers
2658
2710
  this.messageHandler = null;
2711
+ /**
2712
+ * MessagePort obtained from the main window during iframe-mode handshake.
2713
+ * `null` until `initIframe()` completes successfully. Every outbound
2714
+ * request in iframe mode flows through this port; `sendPostMessage` rejects
2715
+ * if called before the handshake finishes.
2716
+ */
2717
+ this.hostPort = null;
2659
2718
  this.setupPromise = null;
2660
2719
  this.setupHook = null;
2661
2720
  // Public APIs
@@ -2829,7 +2888,15 @@ var HaexVaultSdk = class {
2829
2888
  return sendInvoke(method, paramsWithCredentials, this.config, this.log.bind(this));
2830
2889
  }
2831
2890
  const requestId = generateRequestId(++this.requestCounter);
2832
- return sendPostMessage(method, resolvedParams, requestId, this.config, this._extensionInfo, this.pendingRequests);
2891
+ return sendPostMessage(
2892
+ method,
2893
+ resolvedParams,
2894
+ requestId,
2895
+ this.config,
2896
+ this._extensionInfo,
2897
+ this.pendingRequests,
2898
+ this.hostPort
2899
+ );
2833
2900
  }
2834
2901
  // ==========================================================================
2835
2902
  // Private: Initialization
@@ -2896,7 +2963,7 @@ var HaexVaultSdk = class {
2896
2963
  () => this._extensionInfo,
2897
2964
  this.handleEvent.bind(this)
2898
2965
  );
2899
- const { context } = await initIframeMode(
2966
+ const { context, port } = await initIframeMode(
2900
2967
  {
2901
2968
  config: this.config,
2902
2969
  state: {
@@ -2928,6 +2995,7 @@ var HaexVaultSdk = class {
2928
2995
  this.messageHandler,
2929
2996
  this.request.bind(this)
2930
2997
  );
2998
+ this.hostPort = port;
2931
2999
  if (this.config.manifest) {
2932
3000
  this._extensionInfo = {
2933
3001
  publicKey: this.config.manifest.publicKey,