@openclaw/gateway-client 2026.7.2-beta.7 → 2026.8.1-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -88,6 +88,7 @@ The host is responsible for:
88
88
  - creating a `GatewayProtocolSocket` adapter around the browser WebSocket;
89
89
  - loading and storing browser device identity and issued device tokens;
90
90
  - signing the challenge-bound device payload;
91
+ - using the Gateway challenge `ts` as the device proof's `signedAt` value;
91
92
  - supplying the client identity, role, scopes, and authentication selection;
92
93
  - choosing close and reconnect behavior for product-specific errors.
93
94
 
@@ -1,6 +1,6 @@
1
- import { A as GatewayBrowserDeviceAuthLifecycle, B as buildDeviceAuthPayload, C as normalizeSessionProjectionRunId, D as reconcileSessionProjectionSnapshot, E as readSessionMessageSequence, F as GatewayConnectAuthSelection, H as normalizeDeviceMetadataForAuth, I as buildGatewayConnectAuth, L as resolveGatewayConnectScopes, M as GatewayBrowserDeviceIdentity, N as GatewayBrowserDeviceTokenRecord, O as reduceSessionProjection, P as GatewayBrowserDeviceTokenStore, R as selectGatewayConnectAuth, S as isLocallyOptimisticSessionMessage, T as readSessionMessageIdentity, V as buildDeviceAuthPayloadV3, _ as SessionProjectionScope, a as GatewaySessionMessageSubscriptionOptions, b as createSessionProjection, c as resetGatewaySessionMessageSubscriptionCoordinator, d as SessionProjectionEntry, f as SessionProjectionEvent, g as SessionProjectionRunTransition, h as SessionProjectionRunStatus, i as GatewaySessionMessageSubscriptionCoordinatorOptions, j as GatewayBrowserDeviceAuthPlan, k as reduceSessionProjectionRunEvent, l as SessionMessageEnvelope, m as SessionProjectionRun, n as GatewaySessionMessageSubscription, o as getGatewaySessionMessageSubscriptionCoordinator, p as SessionProjectionGatewayRunEvent, r as GatewaySessionMessageSubscriptionCoordinator, s as releaseGatewaySessionMessageSubscription, t as GatewaySessionMessageRequestClient, u as SessionMessageIdentity, v as SessionProjectionSnapshotOptions, w as projectLiveSessionMessage, x as hasSessionProjectionAcceptedFinal, y as SessionProjectionState, z as shouldRetryGatewayWithDeviceToken } from "./session-subscriptions-DrhzqL6v.mjs";
2
- import { a as GatewayProtocolRequestTiming, c as GatewayProtocolTiming, i as GatewayProtocolRequestOptions, n as GatewayProtocolCloseContext, o as GatewayProtocolSocket, r as GatewayProtocolRequestError, s as GatewayProtocolSocketHandlers, t as GatewayProtocolClient } from "./protocol-client-BfBHwA5H.mjs";
3
- import { DEFAULT_PREAUTH_HANDSHAKE_TIMEOUT_MS, resolveSafeTimeoutDelayMs } from "./timeouts.mjs";
1
+ import { A as GatewayBrowserDeviceAuthLifecycle, B as buildDeviceAuthPayload, C as normalizeSessionProjectionRunId, D as reconcileSessionProjectionSnapshot, E as readSessionMessageSequence, F as GatewayConnectAuthSelection, H as normalizeDeviceMetadataForAuth, I as buildGatewayConnectAuth, L as resolveGatewayConnectScopes, M as GatewayBrowserDeviceIdentity, N as GatewayBrowserDeviceTokenRecord, O as reduceSessionProjection, P as GatewayBrowserDeviceTokenStore, R as selectGatewayConnectAuth, S as isLocallyOptimisticSessionMessage, T as readSessionMessageIdentity, V as buildDeviceAuthPayloadV3, _ as SessionProjectionScope, a as GatewaySessionMessageSubscriptionOptions, b as createSessionProjection, c as resetGatewaySessionMessageSubscriptionCoordinator, d as SessionProjectionEntry, f as SessionProjectionEvent, g as SessionProjectionRunTransition, h as SessionProjectionRunStatus, i as GatewaySessionMessageSubscriptionCoordinatorOptions, j as GatewayBrowserDeviceAuthPlan, k as reduceSessionProjectionRunEvent, l as SessionMessageEnvelope, m as SessionProjectionRun, n as GatewaySessionMessageSubscription, o as getGatewaySessionMessageSubscriptionCoordinator, p as SessionProjectionGatewayRunEvent, r as GatewaySessionMessageSubscriptionCoordinator, s as releaseGatewaySessionMessageSubscription, t as GatewaySessionMessageRequestClient, u as SessionMessageIdentity, v as SessionProjectionSnapshotOptions, w as projectLiveSessionMessage, x as hasSessionProjectionAcceptedFinal, y as SessionProjectionState, z as shouldRetryGatewayWithDeviceToken } from "./session-subscriptions-Das1PATe.mjs";
2
+ import { a as GatewayProtocolSocketHandlers, c as GatewayProtocolRequestOptions, i as GatewayProtocolSocket, n as GatewayProtocolCloseContext, o as GatewayProtocolTiming, r as GatewayProtocolRequestTiming, s as GatewayProtocolRequestError, t as GatewayProtocolClient } from "./protocol-client-U142L0j3.mjs";
3
+ import { DEFAULT_GATEWAY_REQUEST_TIMEOUT_MS, DEFAULT_PREAUTH_HANDSHAKE_TIMEOUT_MS, resolveSafeTimeoutDelayMs } from "./timeouts.mjs";
4
4
  import { ConnectParams, ErrorShape, EventFrame, HelloOk } from "@openclaw/gateway-protocol";
5
5
  export * from "@openclaw/gateway-protocol/connect-error-details";
6
6
  export * from "@openclaw/gateway-protocol/client-info";
@@ -17,4 +17,4 @@ declare function shouldPauseGatewayReconnect(params: {
17
17
  clientVersionMismatchIsTerminal?: boolean;
18
18
  }): boolean;
19
19
  //#endregion
20
- export { type ConnectParams, DEFAULT_PREAUTH_HANDSHAKE_TIMEOUT_MS, type ErrorShape, type EventFrame, GatewayBrowserDeviceAuthLifecycle, GatewayBrowserDeviceAuthPlan, GatewayBrowserDeviceIdentity, GatewayBrowserDeviceTokenRecord, GatewayBrowserDeviceTokenStore, GatewayConnectAuthSelection, GatewayProtocolClient, GatewayProtocolCloseContext, GatewayProtocolRequestError, GatewayProtocolRequestOptions, GatewayProtocolRequestTiming, GatewayProtocolSocket, GatewayProtocolSocketHandlers, GatewayProtocolTiming, GatewaySessionMessageRequestClient, GatewaySessionMessageSubscription, GatewaySessionMessageSubscriptionCoordinator, GatewaySessionMessageSubscriptionCoordinatorOptions, GatewaySessionMessageSubscriptionOptions, type HelloOk, SessionMessageEnvelope, SessionMessageIdentity, SessionProjectionEntry, SessionProjectionEvent, SessionProjectionGatewayRunEvent, SessionProjectionRun, SessionProjectionRunStatus, SessionProjectionRunTransition, SessionProjectionScope, SessionProjectionSnapshotOptions, SessionProjectionState, buildDeviceAuthPayload, buildDeviceAuthPayloadV3, buildGatewayConnectAuth, createSessionProjection, getGatewaySessionMessageSubscriptionCoordinator, hasSessionProjectionAcceptedFinal, isLocallyOptimisticSessionMessage, normalizeDeviceMetadataForAuth, normalizeSessionProjectionRunId, projectLiveSessionMessage, readSessionMessageIdentity, readSessionMessageSequence, reconcileSessionProjectionSnapshot, reduceSessionProjection, reduceSessionProjectionRunEvent, releaseGatewaySessionMessageSubscription, resetGatewaySessionMessageSubscriptionCoordinator, resolveGatewayConnectScopes, resolveSafeTimeoutDelayMs, selectGatewayConnectAuth, shouldPauseGatewayReconnect, shouldRetryGatewayWithDeviceToken };
20
+ export { type ConnectParams, DEFAULT_GATEWAY_REQUEST_TIMEOUT_MS, DEFAULT_PREAUTH_HANDSHAKE_TIMEOUT_MS, type ErrorShape, type EventFrame, GatewayBrowserDeviceAuthLifecycle, GatewayBrowserDeviceAuthPlan, GatewayBrowserDeviceIdentity, GatewayBrowserDeviceTokenRecord, GatewayBrowserDeviceTokenStore, GatewayConnectAuthSelection, GatewayProtocolClient, GatewayProtocolCloseContext, GatewayProtocolRequestError, type GatewayProtocolRequestOptions, GatewayProtocolRequestTiming, GatewayProtocolSocket, GatewayProtocolSocketHandlers, GatewayProtocolTiming, GatewaySessionMessageRequestClient, GatewaySessionMessageSubscription, GatewaySessionMessageSubscriptionCoordinator, GatewaySessionMessageSubscriptionCoordinatorOptions, GatewaySessionMessageSubscriptionOptions, type HelloOk, SessionMessageEnvelope, SessionMessageIdentity, SessionProjectionEntry, SessionProjectionEvent, SessionProjectionGatewayRunEvent, SessionProjectionRun, SessionProjectionRunStatus, SessionProjectionRunTransition, SessionProjectionScope, SessionProjectionSnapshotOptions, SessionProjectionState, buildDeviceAuthPayload, buildDeviceAuthPayloadV3, buildGatewayConnectAuth, createSessionProjection, getGatewaySessionMessageSubscriptionCoordinator, hasSessionProjectionAcceptedFinal, isLocallyOptimisticSessionMessage, normalizeDeviceMetadataForAuth, normalizeSessionProjectionRunId, projectLiveSessionMessage, readSessionMessageIdentity, readSessionMessageSequence, reconcileSessionProjectionSnapshot, reduceSessionProjection, reduceSessionProjectionRunEvent, releaseGatewaySessionMessageSubscription, resetGatewaySessionMessageSubscriptionCoordinator, resolveGatewayConnectScopes, resolveSafeTimeoutDelayMs, selectGatewayConnectAuth, shouldPauseGatewayReconnect, shouldRetryGatewayWithDeviceToken };
package/dist/browser.mjs CHANGED
@@ -1,8 +1,8 @@
1
- import { C as buildDeviceAuthPayload, S as shouldRetryGatewayWithDeviceToken, T as normalizeDeviceMetadataForAuth, _ as GatewayProtocolRequestError, a as createSessionProjection, b as resolveGatewayConnectScopes, c as normalizeSessionProjectionRunId, d as readSessionMessageSequence, f as reconcileSessionProjectionSnapshot, g as GatewayProtocolClient, h as shouldPauseGatewayReconnect, i as resetGatewaySessionMessageSubscriptionCoordinator, l as projectLiveSessionMessage, m as reduceSessionProjectionRunEvent, n as getGatewaySessionMessageSubscriptionCoordinator, o as hasSessionProjectionAcceptedFinal, p as reduceSessionProjection, r as releaseGatewaySessionMessageSubscription, s as isLocallyOptimisticSessionMessage, t as GatewaySessionMessageSubscriptionCoordinator, u as readSessionMessageIdentity, v as GatewayBrowserDeviceAuthLifecycle, w as buildDeviceAuthPayloadV3, x as selectGatewayConnectAuth, y as buildGatewayConnectAuth } from "./session-subscriptions-BV7MxYiL.mjs";
2
- import { DEFAULT_PREAUTH_HANDSHAKE_TIMEOUT_MS, resolveSafeTimeoutDelayMs } from "./timeouts.mjs";
1
+ import { C as buildDeviceAuthPayload, S as shouldRetryGatewayWithDeviceToken, T as normalizeDeviceMetadataForAuth, _ as GatewayProtocolRequestError, a as createSessionProjection, b as resolveGatewayConnectScopes, c as normalizeSessionProjectionRunId, d as readSessionMessageSequence, f as reconcileSessionProjectionSnapshot, g as GatewayProtocolClient, h as shouldPauseGatewayReconnect, i as resetGatewaySessionMessageSubscriptionCoordinator, l as projectLiveSessionMessage, m as reduceSessionProjectionRunEvent, n as getGatewaySessionMessageSubscriptionCoordinator, o as hasSessionProjectionAcceptedFinal, p as reduceSessionProjection, r as releaseGatewaySessionMessageSubscription, s as isLocallyOptimisticSessionMessage, t as GatewaySessionMessageSubscriptionCoordinator, u as readSessionMessageIdentity, v as GatewayBrowserDeviceAuthLifecycle, w as buildDeviceAuthPayloadV3, x as selectGatewayConnectAuth, y as buildGatewayConnectAuth } from "./session-subscriptions-D4Xv60cN.mjs";
2
+ import { DEFAULT_GATEWAY_REQUEST_TIMEOUT_MS, DEFAULT_PREAUTH_HANDSHAKE_TIMEOUT_MS, resolveSafeTimeoutDelayMs } from "./timeouts.mjs";
3
3
  export * from "@openclaw/gateway-protocol/connect-error-details";
4
4
  export * from "@openclaw/gateway-protocol/client-info";
5
5
  export * from "@openclaw/gateway-protocol/gateway-error-details";
6
6
  export * from "@openclaw/gateway-protocol/startup-unavailable";
7
7
  export * from "@openclaw/gateway-protocol/version";
8
- export { DEFAULT_PREAUTH_HANDSHAKE_TIMEOUT_MS, GatewayBrowserDeviceAuthLifecycle, GatewayProtocolClient, GatewayProtocolRequestError, GatewaySessionMessageSubscriptionCoordinator, buildDeviceAuthPayload, buildDeviceAuthPayloadV3, buildGatewayConnectAuth, createSessionProjection, getGatewaySessionMessageSubscriptionCoordinator, hasSessionProjectionAcceptedFinal, isLocallyOptimisticSessionMessage, normalizeDeviceMetadataForAuth, normalizeSessionProjectionRunId, projectLiveSessionMessage, readSessionMessageIdentity, readSessionMessageSequence, reconcileSessionProjectionSnapshot, reduceSessionProjection, reduceSessionProjectionRunEvent, releaseGatewaySessionMessageSubscription, resetGatewaySessionMessageSubscriptionCoordinator, resolveGatewayConnectScopes, resolveSafeTimeoutDelayMs, selectGatewayConnectAuth, shouldPauseGatewayReconnect, shouldRetryGatewayWithDeviceToken };
8
+ export { DEFAULT_GATEWAY_REQUEST_TIMEOUT_MS, DEFAULT_PREAUTH_HANDSHAKE_TIMEOUT_MS, GatewayBrowserDeviceAuthLifecycle, GatewayProtocolClient, GatewayProtocolRequestError, GatewaySessionMessageSubscriptionCoordinator, buildDeviceAuthPayload, buildDeviceAuthPayloadV3, buildGatewayConnectAuth, createSessionProjection, getGatewaySessionMessageSubscriptionCoordinator, hasSessionProjectionAcceptedFinal, isLocallyOptimisticSessionMessage, normalizeDeviceMetadataForAuth, normalizeSessionProjectionRunId, projectLiveSessionMessage, readSessionMessageIdentity, readSessionMessageSequence, reconcileSessionProjectionSnapshot, reduceSessionProjection, reduceSessionProjectionRunEvent, releaseGatewaySessionMessageSubscription, resetGatewaySessionMessageSubscriptionCoordinator, resolveGatewayConnectScopes, resolveSafeTimeoutDelayMs, selectGatewayConnectAuth, shouldPauseGatewayReconnect, shouldRetryGatewayWithDeviceToken };
package/dist/index.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { A as GatewayBrowserDeviceAuthLifecycle, B as buildDeviceAuthPayload, C as normalizeSessionProjectionRunId, D as reconcileSessionProjectionSnapshot, E as readSessionMessageSequence, F as GatewayConnectAuthSelection, H as normalizeDeviceMetadataForAuth, I as buildGatewayConnectAuth, L as resolveGatewayConnectScopes, M as GatewayBrowserDeviceIdentity, N as GatewayBrowserDeviceTokenRecord, O as reduceSessionProjection, P as GatewayBrowserDeviceTokenStore, R as selectGatewayConnectAuth, S as isLocallyOptimisticSessionMessage, T as readSessionMessageIdentity, V as buildDeviceAuthPayloadV3, _ as SessionProjectionScope, a as GatewaySessionMessageSubscriptionOptions, b as createSessionProjection, c as resetGatewaySessionMessageSubscriptionCoordinator, d as SessionProjectionEntry, f as SessionProjectionEvent, g as SessionProjectionRunTransition, h as SessionProjectionRunStatus, i as GatewaySessionMessageSubscriptionCoordinatorOptions, j as GatewayBrowserDeviceAuthPlan, k as reduceSessionProjectionRunEvent, l as SessionMessageEnvelope, m as SessionProjectionRun, n as GatewaySessionMessageSubscription, o as getGatewaySessionMessageSubscriptionCoordinator, p as SessionProjectionGatewayRunEvent, r as GatewaySessionMessageSubscriptionCoordinator, s as releaseGatewaySessionMessageSubscription, t as GatewaySessionMessageRequestClient, u as SessionMessageIdentity, v as SessionProjectionSnapshotOptions, w as projectLiveSessionMessage, x as hasSessionProjectionAcceptedFinal, y as SessionProjectionState, z as shouldRetryGatewayWithDeviceToken } from "./session-subscriptions-DrhzqL6v.mjs";
1
+ import { A as GatewayBrowserDeviceAuthLifecycle, B as buildDeviceAuthPayload, C as normalizeSessionProjectionRunId, D as reconcileSessionProjectionSnapshot, E as readSessionMessageSequence, F as GatewayConnectAuthSelection, H as normalizeDeviceMetadataForAuth, I as buildGatewayConnectAuth, L as resolveGatewayConnectScopes, M as GatewayBrowserDeviceIdentity, N as GatewayBrowserDeviceTokenRecord, O as reduceSessionProjection, P as GatewayBrowserDeviceTokenStore, R as selectGatewayConnectAuth, S as isLocallyOptimisticSessionMessage, T as readSessionMessageIdentity, V as buildDeviceAuthPayloadV3, _ as SessionProjectionScope, a as GatewaySessionMessageSubscriptionOptions, b as createSessionProjection, c as resetGatewaySessionMessageSubscriptionCoordinator, d as SessionProjectionEntry, f as SessionProjectionEvent, g as SessionProjectionRunTransition, h as SessionProjectionRunStatus, i as GatewaySessionMessageSubscriptionCoordinatorOptions, j as GatewayBrowserDeviceAuthPlan, k as reduceSessionProjectionRunEvent, l as SessionMessageEnvelope, m as SessionProjectionRun, n as GatewaySessionMessageSubscription, o as getGatewaySessionMessageSubscriptionCoordinator, p as SessionProjectionGatewayRunEvent, r as GatewaySessionMessageSubscriptionCoordinator, s as releaseGatewaySessionMessageSubscription, t as GatewaySessionMessageRequestClient, u as SessionMessageIdentity, v as SessionProjectionSnapshotOptions, w as projectLiveSessionMessage, x as hasSessionProjectionAcceptedFinal, y as SessionProjectionState, z as shouldRetryGatewayWithDeviceToken } from "./session-subscriptions-Das1PATe.mjs";
2
2
  import { DEFAULT_GATEWAY_REQUEST_TIMEOUT_MS, DEFAULT_PREAUTH_HANDSHAKE_TIMEOUT_MS, MAX_CONNECT_CHALLENGE_TIMEOUT_MS, MAX_SAFE_TIMEOUT_DELAY_MS, MIN_CONNECT_CHALLENGE_TIMEOUT_MS, addSafeTimeoutDelayGraceMs, clampConnectChallengeTimeoutMs, clearGatewayConnectTimeout, getConnectChallengeTimeoutMsFromEnv, resolveConnectChallengeTimeoutMs, resolveFiniteTimeoutDelayMs, resolvePreauthHandshakeTimeoutMs, resolveSafeTimeoutDelayMs, startGatewayConnectTimeout } from "./timeouts.mjs";
3
- import { _ as GatewayClientRequestOptions, a as startGatewayClientWithReadinessWait, c as waitForEventLoopReady, d as GatewayClient, f as GatewayClientCloseInfo, g as GatewayClientRequestError, h as GatewayClientOptions, i as startGatewayClientWhenEventLoopReady, l as DeviceAuthTokenRecord, m as GatewayClientHostDeps, n as GatewayClientStartReadinessOptions, o as EventLoopReadyOptions, p as GatewayClientConnectionMetadata, r as GatewayClientStartable, s as EventLoopReadyResult, t as EventLoopReadyWaiter, u as DeviceIdentity, v as GatewayReconnectPausedInfo, y as isGatewayConnectAssemblyError } from "./readiness-BJT_oUZE.mjs";
4
- export { DEFAULT_GATEWAY_REQUEST_TIMEOUT_MS, DEFAULT_PREAUTH_HANDSHAKE_TIMEOUT_MS, DeviceAuthTokenRecord, DeviceIdentity, EventLoopReadyOptions, EventLoopReadyResult, EventLoopReadyWaiter, GatewayBrowserDeviceAuthLifecycle, GatewayBrowserDeviceAuthPlan, GatewayBrowserDeviceIdentity, GatewayBrowserDeviceTokenRecord, GatewayBrowserDeviceTokenStore, GatewayClient, GatewayClientCloseInfo, GatewayClientConnectionMetadata, GatewayClientHostDeps, GatewayClientOptions, GatewayClientRequestError, GatewayClientRequestOptions, GatewayClientStartReadinessOptions, GatewayClientStartable, GatewayConnectAuthSelection, GatewayReconnectPausedInfo, GatewaySessionMessageRequestClient, GatewaySessionMessageSubscription, GatewaySessionMessageSubscriptionCoordinator, GatewaySessionMessageSubscriptionCoordinatorOptions, GatewaySessionMessageSubscriptionOptions, MAX_CONNECT_CHALLENGE_TIMEOUT_MS, MAX_SAFE_TIMEOUT_DELAY_MS, MIN_CONNECT_CHALLENGE_TIMEOUT_MS, SessionMessageEnvelope, SessionMessageIdentity, SessionProjectionEntry, SessionProjectionEvent, SessionProjectionGatewayRunEvent, SessionProjectionRun, SessionProjectionRunStatus, SessionProjectionRunTransition, SessionProjectionScope, SessionProjectionSnapshotOptions, SessionProjectionState, addSafeTimeoutDelayGraceMs, buildDeviceAuthPayload, buildDeviceAuthPayloadV3, buildGatewayConnectAuth, clampConnectChallengeTimeoutMs, clearGatewayConnectTimeout, createSessionProjection, getConnectChallengeTimeoutMsFromEnv, getGatewaySessionMessageSubscriptionCoordinator, hasSessionProjectionAcceptedFinal, isGatewayConnectAssemblyError, isLocallyOptimisticSessionMessage, normalizeDeviceMetadataForAuth, normalizeSessionProjectionRunId, projectLiveSessionMessage, readSessionMessageIdentity, readSessionMessageSequence, reconcileSessionProjectionSnapshot, reduceSessionProjection, reduceSessionProjectionRunEvent, releaseGatewaySessionMessageSubscription, resetGatewaySessionMessageSubscriptionCoordinator, resolveConnectChallengeTimeoutMs, resolveFiniteTimeoutDelayMs, resolveGatewayConnectScopes, resolvePreauthHandshakeTimeoutMs, resolveSafeTimeoutDelayMs, selectGatewayConnectAuth, shouldRetryGatewayWithDeviceToken, startGatewayClientWhenEventLoopReady, startGatewayClientWithReadinessWait, startGatewayConnectTimeout, waitForEventLoopReady };
3
+ import { _ as GatewayClientRequestOptions, a as startGatewayClientWithReadinessWait, b as isGatewayConnectAssemblyError, c as waitForEventLoopReady, d as GatewayClient, f as GatewayClientCloseInfo, g as GatewayClientRequestError, h as GatewayClientOptions, i as startGatewayClientWhenEventLoopReady, l as DeviceAuthTokenRecord, m as GatewayClientHostDeps, n as GatewayClientStartReadinessOptions, o as EventLoopReadyOptions, p as GatewayClientConnectionMetadata, r as GatewayClientStartable, s as EventLoopReadyResult, t as EventLoopReadyWaiter, u as DeviceIdentity, v as GatewayClientRequestTimeoutError, y as GatewayReconnectPausedInfo } from "./readiness-uSDrqxDM.mjs";
4
+ export { DEFAULT_GATEWAY_REQUEST_TIMEOUT_MS, DEFAULT_PREAUTH_HANDSHAKE_TIMEOUT_MS, DeviceAuthTokenRecord, DeviceIdentity, EventLoopReadyOptions, EventLoopReadyResult, EventLoopReadyWaiter, GatewayBrowserDeviceAuthLifecycle, GatewayBrowserDeviceAuthPlan, GatewayBrowserDeviceIdentity, GatewayBrowserDeviceTokenRecord, GatewayBrowserDeviceTokenStore, GatewayClient, GatewayClientCloseInfo, GatewayClientConnectionMetadata, GatewayClientHostDeps, GatewayClientOptions, GatewayClientRequestError, GatewayClientRequestOptions, GatewayClientRequestTimeoutError, GatewayClientStartReadinessOptions, GatewayClientStartable, GatewayConnectAuthSelection, GatewayReconnectPausedInfo, GatewaySessionMessageRequestClient, GatewaySessionMessageSubscription, GatewaySessionMessageSubscriptionCoordinator, GatewaySessionMessageSubscriptionCoordinatorOptions, GatewaySessionMessageSubscriptionOptions, MAX_CONNECT_CHALLENGE_TIMEOUT_MS, MAX_SAFE_TIMEOUT_DELAY_MS, MIN_CONNECT_CHALLENGE_TIMEOUT_MS, SessionMessageEnvelope, SessionMessageIdentity, SessionProjectionEntry, SessionProjectionEvent, SessionProjectionGatewayRunEvent, SessionProjectionRun, SessionProjectionRunStatus, SessionProjectionRunTransition, SessionProjectionScope, SessionProjectionSnapshotOptions, SessionProjectionState, addSafeTimeoutDelayGraceMs, buildDeviceAuthPayload, buildDeviceAuthPayloadV3, buildGatewayConnectAuth, clampConnectChallengeTimeoutMs, clearGatewayConnectTimeout, createSessionProjection, getConnectChallengeTimeoutMsFromEnv, getGatewaySessionMessageSubscriptionCoordinator, hasSessionProjectionAcceptedFinal, isGatewayConnectAssemblyError, isLocallyOptimisticSessionMessage, normalizeDeviceMetadataForAuth, normalizeSessionProjectionRunId, projectLiveSessionMessage, readSessionMessageIdentity, readSessionMessageSequence, reconcileSessionProjectionSnapshot, reduceSessionProjection, reduceSessionProjectionRunEvent, releaseGatewaySessionMessageSubscription, resetGatewaySessionMessageSubscriptionCoordinator, resolveConnectChallengeTimeoutMs, resolveFiniteTimeoutDelayMs, resolveGatewayConnectScopes, resolvePreauthHandshakeTimeoutMs, resolveSafeTimeoutDelayMs, selectGatewayConnectAuth, shouldRetryGatewayWithDeviceToken, startGatewayClientWhenEventLoopReady, startGatewayClientWithReadinessWait, startGatewayConnectTimeout, waitForEventLoopReady };
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { C as buildDeviceAuthPayload, S as shouldRetryGatewayWithDeviceToken, T as normalizeDeviceMetadataForAuth, _ as GatewayProtocolRequestError, a as createSessionProjection, b as resolveGatewayConnectScopes, c as normalizeSessionProjectionRunId, d as readSessionMessageSequence, f as reconcileSessionProjectionSnapshot, g as GatewayProtocolClient, h as shouldPauseGatewayReconnect, i as resetGatewaySessionMessageSubscriptionCoordinator, l as projectLiveSessionMessage, m as reduceSessionProjectionRunEvent, n as getGatewaySessionMessageSubscriptionCoordinator, o as hasSessionProjectionAcceptedFinal, p as reduceSessionProjection, r as releaseGatewaySessionMessageSubscription, s as isLocallyOptimisticSessionMessage, t as GatewaySessionMessageSubscriptionCoordinator, u as readSessionMessageIdentity, v as GatewayBrowserDeviceAuthLifecycle, w as buildDeviceAuthPayloadV3, x as selectGatewayConnectAuth, y as buildGatewayConnectAuth } from "./session-subscriptions-BV7MxYiL.mjs";
1
+ import { C as buildDeviceAuthPayload, S as shouldRetryGatewayWithDeviceToken, T as normalizeDeviceMetadataForAuth, _ as GatewayProtocolRequestError, a as createSessionProjection, b as resolveGatewayConnectScopes, c as normalizeSessionProjectionRunId, d as readSessionMessageSequence, f as reconcileSessionProjectionSnapshot, g as GatewayProtocolClient, h as shouldPauseGatewayReconnect, i as resetGatewaySessionMessageSubscriptionCoordinator, l as projectLiveSessionMessage, m as reduceSessionProjectionRunEvent, n as getGatewaySessionMessageSubscriptionCoordinator, o as hasSessionProjectionAcceptedFinal, p as reduceSessionProjection, r as releaseGatewaySessionMessageSubscription, s as isLocallyOptimisticSessionMessage, t as GatewaySessionMessageSubscriptionCoordinator, u as readSessionMessageIdentity, v as GatewayBrowserDeviceAuthLifecycle, w as buildDeviceAuthPayloadV3, x as selectGatewayConnectAuth, y as buildGatewayConnectAuth } from "./session-subscriptions-D4Xv60cN.mjs";
2
2
  import { DEFAULT_GATEWAY_REQUEST_TIMEOUT_MS, DEFAULT_PREAUTH_HANDSHAKE_TIMEOUT_MS, MAX_CONNECT_CHALLENGE_TIMEOUT_MS, MAX_SAFE_TIMEOUT_DELAY_MS, MIN_CONNECT_CHALLENGE_TIMEOUT_MS, addSafeTimeoutDelayGraceMs, clampConnectChallengeTimeoutMs, clearGatewayConnectTimeout, getConnectChallengeTimeoutMsFromEnv, resolveConnectChallengeTimeoutMs, resolveFiniteTimeoutDelayMs, resolvePreauthHandshakeTimeoutMs, resolveSafeTimeoutDelayMs, startGatewayConnectTimeout } from "./timeouts.mjs";
3
3
  import { n as startGatewayClientWithReadinessWait, r as waitForEventLoopReady, t as startGatewayClientWhenEventLoopReady } from "./readiness-CrWxd4TI.mjs";
4
4
  import { ConnectErrorDetailCodes, formatConnectErrorMessage, readConnectErrorDetailCode } from "@openclaw/gateway-protocol/connect-error-details";
@@ -1035,6 +1035,19 @@ function isLoopbackIpAddress(raw) {
1035
1035
  return normalizeIpv4MappedAddress(parsed).range() === "loopback";
1036
1036
  }
1037
1037
  //#endregion
1038
+ //#region packages/net-policy/src/url-protocol.ts
1039
+ function parseUrl(value) {
1040
+ if (value instanceof URL) return value;
1041
+ try {
1042
+ return new URL(value);
1043
+ } catch {
1044
+ return null;
1045
+ }
1046
+ }
1047
+ function isWssUrl(value) {
1048
+ return parseUrl(value)?.protocol === "wss:";
1049
+ }
1050
+ //#endregion
1038
1051
  //#region packages/gateway-client/src/client-address-utils.ts
1039
1052
  function normalizeLowercaseStringOrEmpty(value) {
1040
1053
  return typeof value === "string" ? value.trim().toLowerCase() : "";
@@ -1155,6 +1168,15 @@ var GatewayClientRequestError = class extends GatewayProtocolRequestError {
1155
1168
  this.name = "GatewayClientRequestError";
1156
1169
  }
1157
1170
  };
1171
+ var GatewayClientRequestTimeoutError = class extends Error {
1172
+ constructor(params) {
1173
+ super(`gateway request timeout for ${params.method}`);
1174
+ this.name = "GatewayClientRequestTimeoutError";
1175
+ this.method = params.method;
1176
+ this.timeoutMs = params.timeoutMs;
1177
+ this.requestSent = params.requestSent;
1178
+ }
1179
+ };
1158
1180
  var GatewayClientTransientPreHelloCloseError = class extends Error {
1159
1181
  constructor() {
1160
1182
  super("gateway transient pre-hello clean close");
@@ -1212,13 +1234,19 @@ var GatewayClient = class {
1212
1234
  createSocket: (handlers) => this.createSocket(handlers),
1213
1235
  createRequestId: randomUUID,
1214
1236
  createRequestError: (error) => new GatewayClientRequestError(error),
1215
- createRequestTimeoutError: (method) => /* @__PURE__ */ new Error(`gateway request timeout for ${method}`),
1237
+ createRequestTimeoutError: (method, timeoutMs, requestSent) => new GatewayClientRequestTimeoutError({
1238
+ method,
1239
+ timeoutMs,
1240
+ requestSent
1241
+ }),
1216
1242
  createRequestAbortError: createGatewayRequestAbortError,
1217
- buildConnectPlan: ({ nonce }) => {
1243
+ buildConnectPlan: ({ nonce, challengeTs }) => {
1218
1244
  if (!nonce) throw new Error("gateway connect challenge missing nonce");
1245
+ if (this.opts.deviceIdentity && challengeTs == null) throw new Error("gateway connect challenge timestamp invalid");
1219
1246
  return this.assembleConnectParams({
1220
1247
  role: this.opts.role ?? "operator",
1221
- nonce
1248
+ nonce,
1249
+ signedAtMs: challengeTs ?? Date.now()
1222
1250
  });
1223
1251
  },
1224
1252
  buildConnectParams: (assembled) => assembled.params,
@@ -1292,7 +1320,8 @@ var GatewayClient = class {
1292
1320
  }
1293
1321
  createSocket(handlers) {
1294
1322
  const url = this.opts.url ?? DEFAULT_GATEWAY_CLIENT_URL;
1295
- if (this.opts.tlsFingerprint && !url.startsWith("wss://")) throw new GatewayClientSocketFactoryConfigurationError("gateway tls fingerprint requires wss:// gateway url");
1323
+ const usesTls = isWssUrl(url);
1324
+ if (this.opts.tlsFingerprint && !usesTls) throw new GatewayClientSocketFactoryConfigurationError("gateway tls fingerprint requires wss:// gateway url");
1296
1325
  const allowPrivateWs = (this.opts.env ?? process.env).OPENCLAW_ALLOW_INSECURE_PRIVATE_WS === "1";
1297
1326
  if (!isSecureWebSocketUrl(url, { allowPrivateWs })) {
1298
1327
  let displayHost = url;
@@ -1310,7 +1339,7 @@ var GatewayClient = class {
1310
1339
  }),
1311
1340
  ...this.opts.origin ? { origin: this.opts.origin } : {}
1312
1341
  };
1313
- if (url.startsWith("wss://") && this.opts.tlsFingerprint) {
1342
+ if (usesTls && this.opts.tlsFingerprint) {
1314
1343
  wsOptions.rejectUnauthorized = false;
1315
1344
  wsOptions.checkServerIdentity = (_hostValue, cert) => {
1316
1345
  const fingerprintValue = typeof cert === "object" && cert && "fingerprint256" in cert ? cert.fingerprint256 ?? "" : "";
@@ -1340,7 +1369,7 @@ var GatewayClient = class {
1340
1369
  this.transportValidated = false;
1341
1370
  ws.on("open", () => {
1342
1371
  handlers.open();
1343
- if (url.startsWith("wss://") && this.opts.tlsFingerprint) {
1372
+ if (usesTls && this.opts.tlsFingerprint) {
1344
1373
  const tlsError = this.validateTlsFingerprint();
1345
1374
  if (tlsError) {
1346
1375
  handlers.error(tlsError);
@@ -1446,12 +1475,11 @@ var GatewayClient = class {
1446
1475
  this.deps.logError(this.deps.redactForLog(message));
1447
1476
  }
1448
1477
  assembleConnectParams(params) {
1449
- const { role, nonce } = params;
1478
+ const { role, nonce, signedAtMs } = params;
1450
1479
  const selectedAuth = this.selectConnectAuth(role);
1451
1480
  const { authDeviceToken, authApprovalRuntimeToken, authAgentRuntimeIdentityToken, signatureToken, resolvedDeviceToken, storedToken, storedScopes, usingStoredDeviceToken } = selectedAuth;
1452
1481
  if (this.pendingDeviceTokenRetry && authDeviceToken) this.pendingDeviceTokenRetry = false;
1453
1482
  const auth = buildGatewayConnectAuth(selectedAuth);
1454
- const signedAtMs = Date.now();
1455
1483
  const scopes = resolveGatewayConnectScopes({
1456
1484
  requestedScopes: this.opts.scopes,
1457
1485
  usingStoredDeviceToken,
@@ -1780,4 +1808,4 @@ function createGatewayRequestAbortError(method) {
1780
1808
  return err;
1781
1809
  }
1782
1810
  //#endregion
1783
- export { DEFAULT_GATEWAY_REQUEST_TIMEOUT_MS, DEFAULT_PREAUTH_HANDSHAKE_TIMEOUT_MS, GatewayBrowserDeviceAuthLifecycle, GatewayClient, GatewayClientRequestError, GatewaySessionMessageSubscriptionCoordinator, MAX_CONNECT_CHALLENGE_TIMEOUT_MS, MAX_SAFE_TIMEOUT_DELAY_MS, MIN_CONNECT_CHALLENGE_TIMEOUT_MS, addSafeTimeoutDelayGraceMs, buildDeviceAuthPayload, buildDeviceAuthPayloadV3, buildGatewayConnectAuth, clampConnectChallengeTimeoutMs, clearGatewayConnectTimeout, createSessionProjection, getConnectChallengeTimeoutMsFromEnv, getGatewaySessionMessageSubscriptionCoordinator, hasSessionProjectionAcceptedFinal, isGatewayConnectAssemblyError, isLocallyOptimisticSessionMessage, normalizeDeviceMetadataForAuth, normalizeSessionProjectionRunId, projectLiveSessionMessage, readSessionMessageIdentity, readSessionMessageSequence, reconcileSessionProjectionSnapshot, reduceSessionProjection, reduceSessionProjectionRunEvent, releaseGatewaySessionMessageSubscription, resetGatewaySessionMessageSubscriptionCoordinator, resolveConnectChallengeTimeoutMs, resolveFiniteTimeoutDelayMs, resolveGatewayConnectScopes, resolvePreauthHandshakeTimeoutMs, resolveSafeTimeoutDelayMs, selectGatewayConnectAuth, shouldRetryGatewayWithDeviceToken, startGatewayClientWhenEventLoopReady, startGatewayClientWithReadinessWait, startGatewayConnectTimeout, waitForEventLoopReady };
1811
+ export { DEFAULT_GATEWAY_REQUEST_TIMEOUT_MS, DEFAULT_PREAUTH_HANDSHAKE_TIMEOUT_MS, GatewayBrowserDeviceAuthLifecycle, GatewayClient, GatewayClientRequestError, GatewayClientRequestTimeoutError, GatewaySessionMessageSubscriptionCoordinator, MAX_CONNECT_CHALLENGE_TIMEOUT_MS, MAX_SAFE_TIMEOUT_DELAY_MS, MIN_CONNECT_CHALLENGE_TIMEOUT_MS, addSafeTimeoutDelayGraceMs, buildDeviceAuthPayload, buildDeviceAuthPayloadV3, buildGatewayConnectAuth, clampConnectChallengeTimeoutMs, clearGatewayConnectTimeout, createSessionProjection, getConnectChallengeTimeoutMsFromEnv, getGatewaySessionMessageSubscriptionCoordinator, hasSessionProjectionAcceptedFinal, isGatewayConnectAssemblyError, isLocallyOptimisticSessionMessage, normalizeDeviceMetadataForAuth, normalizeSessionProjectionRunId, projectLiveSessionMessage, readSessionMessageIdentity, readSessionMessageSequence, reconcileSessionProjectionSnapshot, reduceSessionProjection, reduceSessionProjectionRunEvent, releaseGatewaySessionMessageSubscription, resetGatewaySessionMessageSubscriptionCoordinator, resolveConnectChallengeTimeoutMs, resolveFiniteTimeoutDelayMs, resolveGatewayConnectScopes, resolvePreauthHandshakeTimeoutMs, resolveSafeTimeoutDelayMs, selectGatewayConnectAuth, shouldRetryGatewayWithDeviceToken, startGatewayClientWhenEventLoopReady, startGatewayClientWithReadinessWait, startGatewayConnectTimeout, waitForEventLoopReady };
@@ -1,5 +1,22 @@
1
1
  import { ErrorShape, EventFrame, HelloOk } from "@openclaw/gateway-protocol";
2
2
 
3
+ //#region packages/gateway-client/src/protocol-request.d.ts
4
+ type GatewayProtocolRequestOptions = {
5
+ timeoutMs?: number | null;
6
+ expectFinal?: boolean;
7
+ onSent?: () => void;
8
+ onAccepted?: (payload: unknown) => void;
9
+ signal?: AbortSignal;
10
+ };
11
+ declare class GatewayProtocolRequestError extends Error {
12
+ readonly code: string;
13
+ readonly gatewayCode: string;
14
+ readonly details?: unknown;
15
+ readonly retryable: boolean;
16
+ readonly retryAfterMs?: number;
17
+ constructor(error: Partial<ErrorShape>);
18
+ }
19
+ //#endregion
3
20
  //#region packages/gateway-client/src/protocol-client.d.ts
4
21
  type GatewayProtocolSocket = {
5
22
  isOpen: () => boolean;
@@ -12,16 +29,10 @@ type GatewayProtocolSocketHandlers = {
12
29
  close: (code: number, reason: string) => void;
13
30
  error: (error: Error) => void;
14
31
  };
15
- type GatewayProtocolRequestOptions = {
16
- timeoutMs?: number | null;
17
- expectFinal?: boolean;
18
- onSent?: () => void;
19
- onAccepted?: (payload: unknown) => void;
20
- signal?: AbortSignal;
21
- };
22
32
  type GatewayProtocolConnectContext<TPlan> = {
23
33
  generation: number;
24
34
  nonce: string | null;
35
+ challengeTs: number | null | undefined;
25
36
  plan: TPlan;
26
37
  };
27
38
  type GatewayProtocolCloseContext = {
@@ -72,10 +83,11 @@ type GatewayProtocolClientOptions<TPlan> = {
72
83
  createSocket: (handlers: GatewayProtocolSocketHandlers) => GatewayProtocolSocket;
73
84
  createRequestId: () => string;
74
85
  createRequestError?: (error: Partial<ErrorShape>) => GatewayProtocolRequestError;
75
- createRequestTimeoutError?: (method: string, timeoutMs: number) => Error;
86
+ createRequestTimeoutError?: (method: string, timeoutMs: number, requestSent: boolean) => Error;
76
87
  createRequestAbortError?: (method: string) => Error;
77
88
  buildConnectPlan: (params: {
78
89
  nonce: string | null;
90
+ challengeTs: number | null | undefined;
79
91
  generation: number;
80
92
  }) => TPlan | Promise<TPlan>;
81
93
  buildConnectParams: (plan: TPlan) => unknown;
@@ -116,14 +128,6 @@ type GatewayProtocolClientOptions<TPlan> = {
116
128
  shouldRetrySocketFactoryError?: (error: Error) => boolean;
117
129
  rethrowSocketFactoryError?: (error: Error) => boolean;
118
130
  };
119
- declare class GatewayProtocolRequestError extends Error {
120
- readonly code: string;
121
- readonly gatewayCode: string;
122
- readonly details?: unknown;
123
- readonly retryable: boolean;
124
- readonly retryAfterMs?: number;
125
- constructor(error: Partial<ErrorShape>);
126
- }
127
131
  /**
128
132
  * Browser-safe gateway wire client. Environment adapters own transport and auth
129
133
  * policy; this class owns the single socket/handshake/reconnect/frame state machine.
@@ -137,6 +141,7 @@ declare class GatewayProtocolClient<TPlan> {
137
141
  private generation;
138
142
  private lastSeq;
139
143
  private connectNonce;
144
+ private connectChallengeTs;
140
145
  private connectSent;
141
146
  private connectRequestSent;
142
147
  private handshakeTimer;
@@ -179,4 +184,4 @@ declare class GatewayProtocolClient<TPlan> {
179
184
  private invoke;
180
185
  }
181
186
  //#endregion
182
- export { GatewayProtocolRequestTiming as a, GatewayProtocolTiming as c, GatewayProtocolRequestOptions as i, GatewayProtocolCloseContext as n, GatewayProtocolSocket as o, GatewayProtocolRequestError as r, GatewayProtocolSocketHandlers as s, GatewayProtocolClient as t };
187
+ export { GatewayProtocolSocketHandlers as a, GatewayProtocolRequestOptions as c, GatewayProtocolSocket as i, GatewayProtocolCloseContext as n, GatewayProtocolTiming as o, GatewayProtocolRequestTiming as r, GatewayProtocolRequestError as s, GatewayProtocolClient as t };
@@ -1,4 +1,4 @@
1
- import { i as GatewayProtocolRequestOptions, r as GatewayProtocolRequestError } from "./protocol-client-BfBHwA5H.mjs";
1
+ import { c as GatewayProtocolRequestOptions, s as GatewayProtocolRequestError } from "./protocol-client-U142L0j3.mjs";
2
2
  import { ErrorShape, EventFrame, HelloOk } from "@openclaw/gateway-protocol/frame-guards";
3
3
  import { GatewayClientMode, GatewayClientName } from "@openclaw/gateway-protocol/client-info";
4
4
 
@@ -55,6 +55,16 @@ type GatewayClientCloseInfo = {
55
55
  declare class GatewayClientRequestError extends GatewayProtocolRequestError {
56
56
  constructor(error: Partial<ErrorShape>);
57
57
  }
58
+ declare class GatewayClientRequestTimeoutError extends Error {
59
+ readonly method: string;
60
+ readonly timeoutMs: number;
61
+ readonly requestSent: boolean;
62
+ constructor(params: {
63
+ method: string;
64
+ timeoutMs: number;
65
+ requestSent: boolean;
66
+ });
67
+ }
58
68
  declare function isGatewayConnectAssemblyError(value: unknown): value is Error;
59
69
  type GatewayClientOptions = {
60
70
  url?: string;
@@ -198,4 +208,4 @@ declare function startGatewayClientWithReadinessWait(waitForReady: EventLoopRead
198
208
  /** Starts a gateway client after the default event-loop readiness probe succeeds. */
199
209
  declare function startGatewayClientWhenEventLoopReady(client: GatewayClientStartable, options?: GatewayClientStartReadinessOptions): Promise<EventLoopReadyResult>;
200
210
  //#endregion
201
- export { GatewayClientRequestOptions as _, startGatewayClientWithReadinessWait as a, waitForEventLoopReady as c, GatewayClient as d, GatewayClientCloseInfo as f, GatewayClientRequestError as g, GatewayClientOptions as h, startGatewayClientWhenEventLoopReady as i, DeviceAuthTokenRecord as l, GatewayClientHostDeps as m, GatewayClientStartReadinessOptions as n, EventLoopReadyOptions as o, GatewayClientConnectionMetadata as p, GatewayClientStartable as r, EventLoopReadyResult as s, EventLoopReadyWaiter as t, DeviceIdentity as u, GatewayReconnectPausedInfo as v, isGatewayConnectAssemblyError as y };
211
+ export { GatewayClientRequestOptions as _, startGatewayClientWithReadinessWait as a, isGatewayConnectAssemblyError as b, waitForEventLoopReady as c, GatewayClient as d, GatewayClientCloseInfo as f, GatewayClientRequestError as g, GatewayClientOptions as h, startGatewayClientWhenEventLoopReady as i, DeviceAuthTokenRecord as l, GatewayClientHostDeps as m, GatewayClientStartReadinessOptions as n, EventLoopReadyOptions as o, GatewayClientConnectionMetadata as p, GatewayClientStartable as r, EventLoopReadyResult as s, EventLoopReadyWaiter as t, DeviceIdentity as u, GatewayClientRequestTimeoutError as v, GatewayReconnectPausedInfo as y };
@@ -1,2 +1,2 @@
1
- import { a as startGatewayClientWithReadinessWait, i as startGatewayClientWhenEventLoopReady, n as GatewayClientStartReadinessOptions, r as GatewayClientStartable, t as EventLoopReadyWaiter } from "./readiness-BJT_oUZE.mjs";
1
+ import { a as startGatewayClientWithReadinessWait, i as startGatewayClientWhenEventLoopReady, n as GatewayClientStartReadinessOptions, r as GatewayClientStartable, t as EventLoopReadyWaiter } from "./readiness-uSDrqxDM.mjs";
2
2
  export { EventLoopReadyWaiter, GatewayClientStartReadinessOptions, GatewayClientStartable, startGatewayClientWhenEventLoopReady, startGatewayClientWithReadinessWait };
@@ -139,7 +139,8 @@ var GatewayBrowserDeviceAuthLifecycle = class {
139
139
  scopes,
140
140
  auth: buildGatewayConnectAuth(selectedAuth)
141
141
  };
142
- const signedAtMs = this.deps.nowMs?.() ?? Date.now();
142
+ const signedAtMs = params.challengeTs === void 0 ? this.deps.nowMs?.() ?? Date.now() : params.challengeTs;
143
+ if (typeof signedAtMs !== "number" || !Number.isSafeInteger(signedAtMs) || signedAtMs < 0) throw new Error("gateway connect challenge timestamp invalid");
143
144
  const nonce = params.nonce ?? "";
144
145
  const { authBootstrapToken: primary, signatureToken: signed } = selectedAuth;
145
146
  let token = null;
@@ -403,7 +404,7 @@ var GatewayEventListeners = class {
403
404
  }
404
405
  };
405
406
  //#endregion
406
- //#region packages/gateway-client/src/protocol-client.ts
407
+ //#region packages/gateway-client/src/protocol-request.ts
407
408
  var GatewayProtocolRequestError = class extends Error {
408
409
  constructor(error) {
409
410
  super(error.message ?? "request failed");
@@ -415,6 +416,8 @@ var GatewayProtocolRequestError = class extends Error {
415
416
  this.retryAfterMs = error.retryAfterMs;
416
417
  }
417
418
  };
419
+ //#endregion
420
+ //#region packages/gateway-client/src/protocol-client.ts
418
421
  /**
419
422
  * Browser-safe gateway wire client. Environment adapters own transport and auth
420
423
  * policy; this class owns the single socket/handshake/reconnect/frame state machine.
@@ -485,6 +488,7 @@ var GatewayProtocolClient = class {
485
488
  const timeoutMs = options?.timeoutMs === null ? void 0 : options?.timeoutMs ?? this.opts.requestTimeoutMs;
486
489
  return new Promise((resolve, reject) => {
487
490
  let timeout;
491
+ let requestSent = false;
488
492
  const pending = {
489
493
  resolve: (value) => resolve(value),
490
494
  reject,
@@ -497,7 +501,7 @@ var GatewayProtocolClient = class {
497
501
  };
498
502
  const onAbort = () => {
499
503
  this.pending.delete(id);
500
- if (timeout) clearTimeout(timeout);
504
+ pending.cleanup?.();
501
505
  this.finishRequestTiming(id, pending, false, "CLIENT_ABORTED");
502
506
  reject(this.opts.createRequestAbortError?.(method) ?? /* @__PURE__ */ new Error(`gateway request aborted for ${method}`));
503
507
  };
@@ -512,10 +516,11 @@ var GatewayProtocolClient = class {
512
516
  pending.cleanup = cleanup;
513
517
  if (timeoutMs !== void 0 && timeoutMs >= 0) {
514
518
  timeout = setTimeout(() => {
519
+ if (this.pending.get(id) !== pending) return;
515
520
  this.pending.delete(id);
516
521
  options?.signal?.removeEventListener("abort", onAbort);
517
522
  this.finishRequestTiming(id, pending, false, "CLIENT_TIMEOUT");
518
- reject(this.opts.createRequestTimeoutError?.(method, timeoutMs) ?? /* @__PURE__ */ new Error(`gateway request timed out after ${timeoutMs}ms: ${method}`));
523
+ reject(this.opts.createRequestTimeoutError?.(method, timeoutMs, requestSent) ?? /* @__PURE__ */ new Error(`gateway request timed out after ${timeoutMs}ms: ${method}`));
519
524
  }, timeoutMs);
520
525
  timeout.unref?.();
521
526
  }
@@ -528,6 +533,7 @@ var GatewayProtocolClient = class {
528
533
  method,
529
534
  params
530
535
  }));
536
+ requestSent = true;
531
537
  this.invoke("sent", () => options?.onSent?.());
532
538
  } catch (error) {
533
539
  this.pending.delete(id);
@@ -571,6 +577,7 @@ var GatewayProtocolClient = class {
571
577
  const generation = this.generation + 1;
572
578
  this.lastSeq = null;
573
579
  this.connectNonce = null;
580
+ this.connectChallengeTs = void 0;
574
581
  this.connectSent = this.connectRequestSent = false;
575
582
  this.socketOpened = false;
576
583
  this.helloReceived = false;
@@ -641,6 +648,7 @@ var GatewayProtocolClient = class {
641
648
  try {
642
649
  planOrPromise = this.opts.buildConnectPlan({
643
650
  nonce: this.connectNonce,
651
+ challengeTs: this.connectChallengeTs,
644
652
  generation
645
653
  });
646
654
  } catch (error) {
@@ -669,6 +677,7 @@ var GatewayProtocolClient = class {
669
677
  const context = {
670
678
  generation,
671
679
  nonce: this.connectNonce,
680
+ challengeTs: this.connectChallengeTs,
672
681
  plan
673
682
  };
674
683
  this.recordTiming("connect-plan-ready", generation, plan);
@@ -721,6 +730,8 @@ var GatewayProtocolClient = class {
721
730
  return;
722
731
  }
723
732
  this.connectNonce = nonce;
733
+ const challengeTs = payload?.ts;
734
+ this.connectChallengeTs = typeof challengeTs === "number" && Number.isSafeInteger(challengeTs) && challengeTs >= 0 ? challengeTs : null;
724
735
  this.recordTiming("challenge", generation);
725
736
  this.sendConnect(socket, generation);
726
737
  return;
@@ -122,6 +122,7 @@ declare class GatewayBrowserDeviceAuthLifecycle {
122
122
  trustedDeviceTokenRetry?: boolean;
123
123
  preferBootstrapToken?: boolean;
124
124
  nonce: string | null;
125
+ challengeTs?: number | null;
125
126
  }): Promise<GatewayBrowserDeviceAuthPlan>;
126
127
  acceptHello(hello: Pick<HelloOk, "auth">, plan: GatewayBrowserDeviceAuthPlan): Promise<void>;
127
128
  clearStoredToken(plan: GatewayBrowserDeviceAuthPlan): Promise<void>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openclaw/gateway-client",
3
- "version": "2026.7.2-beta.7",
3
+ "version": "2026.8.1-beta.1",
4
4
  "description": "Reference WebSocket client for the OpenClaw Gateway protocol",
5
5
  "keywords": [
6
6
  "client",
@@ -54,7 +54,7 @@
54
54
  "dependencies": {
55
55
  "ipaddr.js": "2.4.0",
56
56
  "ws": "8.21.1",
57
- "@openclaw/gateway-protocol": "2026.7.2-beta.7"
57
+ "@openclaw/gateway-protocol": "2026.8.1-beta.1"
58
58
  },
59
59
  "engines": {
60
60
  "node": ">=22.19.0"