@dynamic-labs-wallet/core 1.0.118 → 1.0.120

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/index.cjs CHANGED
@@ -954,8 +954,23 @@ const getRequiredExternalKeyShareId = (ks)=>{
954
954
  * before it is posted and surfaces in Datadog exactly as the recovery path does.
955
955
  */ const assertDynamicLocationsHaveExternalKeyShareId = (locations)=>locations.filter((location)=>location.location === BackupLocation.DYNAMIC).forEach((location)=>getRequiredExternalKeyShareId(location));
956
956
 
957
- var version = "1.0.118";
957
+ var version = "1.0.120";
958
958
 
959
+ /**
960
+ * Reads the Authorization header off an axios request config, which stores
961
+ * headers either as a plain object or as an `AxiosHeaders` instance.
962
+ */ const readAuthorizationHeader = (requestHeaders)=>{
963
+ if (typeof requestHeaders !== 'object' || requestHeaders === null) {
964
+ return undefined;
965
+ }
966
+ const headers = requestHeaders;
967
+ var _headers_Authorization;
968
+ const authorization = (_headers_Authorization = headers['Authorization']) != null ? _headers_Authorization : headers['authorization'];
969
+ if (typeof authorization !== 'string') {
970
+ return undefined;
971
+ }
972
+ return authorization;
973
+ };
959
974
  class BaseClient {
960
975
  /**
961
976
  * Fire {@link onUnauthorized} whenever a request on this axios instance sees a
@@ -969,27 +984,47 @@ class BaseClient {
969
984
  * response/error; it only signals out-of-band, leaving existing error
970
985
  * handling unchanged.
971
986
  */ installUnauthorizedInterceptor(client) {
972
- const fireIfUnauthorized = (status)=>{
973
- if (status === 401) {
974
- try {
975
- this.onUnauthorized == null ? void 0 : this.onUnauthorized.call(this);
976
- } catch (error) {
977
- this.logger.error('[BaseClient] onUnauthorized handler threw', {
978
- error
979
- });
980
- }
987
+ const fireIfUnauthorized = (status, requestHeaders)=>{
988
+ if (status !== 401) {
989
+ return;
990
+ }
991
+ if (this.isSupersededAuthHeader(requestHeaders)) {
992
+ this.logger.info('[BaseClient] ignoring 401 for a request that carried a superseded auth token');
993
+ return;
994
+ }
995
+ try {
996
+ this.onUnauthorized == null ? void 0 : this.onUnauthorized.call(this);
997
+ } catch (error) {
998
+ this.logger.error('[BaseClient] onUnauthorized handler threw', {
999
+ error
1000
+ });
981
1001
  }
982
1002
  };
983
1003
  client.interceptors.response.use((response)=>{
984
- fireIfUnauthorized(response == null ? void 0 : response.status);
1004
+ var _response_config;
1005
+ fireIfUnauthorized(response == null ? void 0 : response.status, response == null ? void 0 : (_response_config = response.config) == null ? void 0 : _response_config.headers);
985
1006
  return response;
986
1007
  }, (error)=>{
987
- var _error_response;
1008
+ var _error_response, _error_config;
988
1009
  var _error_response_status;
989
- fireIfUnauthorized((_error_response_status = error == null ? void 0 : (_error_response = error.response) == null ? void 0 : _error_response.status) != null ? _error_response_status : error == null ? void 0 : error.status);
1010
+ fireIfUnauthorized((_error_response_status = error == null ? void 0 : (_error_response = error.response) == null ? void 0 : _error_response.status) != null ? _error_response_status : error == null ? void 0 : error.status, error == null ? void 0 : (_error_config = error.config) == null ? void 0 : _error_config.headers);
990
1011
  return Promise.reject(error);
991
1012
  });
992
1013
  }
1014
+ /**
1015
+ * Whether a request was sent with an auth token that {@link syncAuthToken} has
1016
+ * since replaced. Its 401 says nothing about the token the client holds now,
1017
+ * so it must not reach {@link onUnauthorized} and log the user out.
1018
+ */ isSupersededAuthHeader(requestHeaders) {
1019
+ if (this.authMode !== AuthMode.HEADER || !this.currentAuthHeader) {
1020
+ return false;
1021
+ }
1022
+ const requestAuthHeader = readAuthorizationHeader(requestHeaders);
1023
+ if (!requestAuthHeader) {
1024
+ return false;
1025
+ }
1026
+ return requestAuthHeader !== this.currentAuthHeader;
1027
+ }
993
1028
  get forwardMPCClient() {
994
1029
  if (!this._forwardMpcClient) {
995
1030
  throw new Error('Forward MPC client is not initialized');
@@ -1007,6 +1042,7 @@ class BaseClient {
1007
1042
  throw new Error('Auth token is required for header authentication');
1008
1043
  }
1009
1044
  const authHeader = `Bearer ${authToken}`;
1045
+ this.currentAuthHeader = authHeader;
1010
1046
  this.apiClient.defaults.headers['Authorization'] = authHeader;
1011
1047
  this.clientRelayApiClient.defaults.headers['Authorization'] = authHeader;
1012
1048
  this.apiClient.defaults.headers.common['Authorization'] = authHeader;
@@ -1033,6 +1069,7 @@ class BaseClient {
1033
1069
  // Only set Authorization header if using header auth mode and token is provided
1034
1070
  if (authMode === AuthMode.HEADER && authToken) {
1035
1071
  headers['Authorization'] = `Bearer ${authToken}`;
1072
+ this.currentAuthHeader = headers['Authorization'];
1036
1073
  }
1037
1074
  headers['x-dyn-wallet-sdk-version'] = version;
1038
1075
  headers['x-dyn-version'] = sdkVersion;
package/index.esm.js CHANGED
@@ -954,8 +954,23 @@ const getRequiredExternalKeyShareId = (ks)=>{
954
954
  * before it is posted and surfaces in Datadog exactly as the recovery path does.
955
955
  */ const assertDynamicLocationsHaveExternalKeyShareId = (locations)=>locations.filter((location)=>location.location === BackupLocation.DYNAMIC).forEach((location)=>getRequiredExternalKeyShareId(location));
956
956
 
957
- var version = "1.0.118";
957
+ var version = "1.0.120";
958
958
 
959
+ /**
960
+ * Reads the Authorization header off an axios request config, which stores
961
+ * headers either as a plain object or as an `AxiosHeaders` instance.
962
+ */ const readAuthorizationHeader = (requestHeaders)=>{
963
+ if (typeof requestHeaders !== 'object' || requestHeaders === null) {
964
+ return undefined;
965
+ }
966
+ const headers = requestHeaders;
967
+ var _headers_Authorization;
968
+ const authorization = (_headers_Authorization = headers['Authorization']) != null ? _headers_Authorization : headers['authorization'];
969
+ if (typeof authorization !== 'string') {
970
+ return undefined;
971
+ }
972
+ return authorization;
973
+ };
959
974
  class BaseClient {
960
975
  /**
961
976
  * Fire {@link onUnauthorized} whenever a request on this axios instance sees a
@@ -969,27 +984,47 @@ class BaseClient {
969
984
  * response/error; it only signals out-of-band, leaving existing error
970
985
  * handling unchanged.
971
986
  */ installUnauthorizedInterceptor(client) {
972
- const fireIfUnauthorized = (status)=>{
973
- if (status === 401) {
974
- try {
975
- this.onUnauthorized == null ? void 0 : this.onUnauthorized.call(this);
976
- } catch (error) {
977
- this.logger.error('[BaseClient] onUnauthorized handler threw', {
978
- error
979
- });
980
- }
987
+ const fireIfUnauthorized = (status, requestHeaders)=>{
988
+ if (status !== 401) {
989
+ return;
990
+ }
991
+ if (this.isSupersededAuthHeader(requestHeaders)) {
992
+ this.logger.info('[BaseClient] ignoring 401 for a request that carried a superseded auth token');
993
+ return;
994
+ }
995
+ try {
996
+ this.onUnauthorized == null ? void 0 : this.onUnauthorized.call(this);
997
+ } catch (error) {
998
+ this.logger.error('[BaseClient] onUnauthorized handler threw', {
999
+ error
1000
+ });
981
1001
  }
982
1002
  };
983
1003
  client.interceptors.response.use((response)=>{
984
- fireIfUnauthorized(response == null ? void 0 : response.status);
1004
+ var _response_config;
1005
+ fireIfUnauthorized(response == null ? void 0 : response.status, response == null ? void 0 : (_response_config = response.config) == null ? void 0 : _response_config.headers);
985
1006
  return response;
986
1007
  }, (error)=>{
987
- var _error_response;
1008
+ var _error_response, _error_config;
988
1009
  var _error_response_status;
989
- fireIfUnauthorized((_error_response_status = error == null ? void 0 : (_error_response = error.response) == null ? void 0 : _error_response.status) != null ? _error_response_status : error == null ? void 0 : error.status);
1010
+ fireIfUnauthorized((_error_response_status = error == null ? void 0 : (_error_response = error.response) == null ? void 0 : _error_response.status) != null ? _error_response_status : error == null ? void 0 : error.status, error == null ? void 0 : (_error_config = error.config) == null ? void 0 : _error_config.headers);
990
1011
  return Promise.reject(error);
991
1012
  });
992
1013
  }
1014
+ /**
1015
+ * Whether a request was sent with an auth token that {@link syncAuthToken} has
1016
+ * since replaced. Its 401 says nothing about the token the client holds now,
1017
+ * so it must not reach {@link onUnauthorized} and log the user out.
1018
+ */ isSupersededAuthHeader(requestHeaders) {
1019
+ if (this.authMode !== AuthMode.HEADER || !this.currentAuthHeader) {
1020
+ return false;
1021
+ }
1022
+ const requestAuthHeader = readAuthorizationHeader(requestHeaders);
1023
+ if (!requestAuthHeader) {
1024
+ return false;
1025
+ }
1026
+ return requestAuthHeader !== this.currentAuthHeader;
1027
+ }
993
1028
  get forwardMPCClient() {
994
1029
  if (!this._forwardMpcClient) {
995
1030
  throw new Error('Forward MPC client is not initialized');
@@ -1007,6 +1042,7 @@ class BaseClient {
1007
1042
  throw new Error('Auth token is required for header authentication');
1008
1043
  }
1009
1044
  const authHeader = `Bearer ${authToken}`;
1045
+ this.currentAuthHeader = authHeader;
1010
1046
  this.apiClient.defaults.headers['Authorization'] = authHeader;
1011
1047
  this.clientRelayApiClient.defaults.headers['Authorization'] = authHeader;
1012
1048
  this.apiClient.defaults.headers.common['Authorization'] = authHeader;
@@ -1033,6 +1069,7 @@ class BaseClient {
1033
1069
  // Only set Authorization header if using header auth mode and token is provided
1034
1070
  if (authMode === AuthMode.HEADER && authToken) {
1035
1071
  headers['Authorization'] = `Bearer ${authToken}`;
1072
+ this.currentAuthHeader = headers['Authorization'];
1036
1073
  }
1037
1074
  headers['x-dyn-wallet-sdk-version'] = version;
1038
1075
  headers['x-dyn-version'] = sdkVersion;
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "@dynamic-labs-wallet/core",
3
- "version": "1.0.118",
3
+ "version": "1.0.120",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "dependencies": {
7
7
  "@dynamic-labs/sdk-api-core": "^0.16.0",
8
- "@dynamic-labs-wallet/primitives": "1.0.118",
8
+ "@dynamic-labs-wallet/primitives": "1.0.120",
9
9
  "axios": "1.16.0",
10
10
  "uuid": "11.1.0"
11
11
  },
@@ -13,6 +13,8 @@ export declare class BaseClient {
13
13
  protected backupServiceAuthToken?: string;
14
14
  /** Notifies the host (via the reverse channel) when a 401 is seen. */
15
15
  protected onUnauthorized?: () => void;
16
+ /** Authorization header this client presents on header-auth requests. */
17
+ protected currentAuthHeader?: string;
16
18
  constructor({ environmentId, baseApiUrl, authToken, backupServiceAuthToken, baseClientKeysharesRelayApiUrl, authMode, sdkVersion, forwardMPCClient, logger, onUnauthorized, }: {
17
19
  environmentId: string;
18
20
  baseApiUrl?: string;
@@ -43,6 +45,12 @@ export declare class BaseClient {
43
45
  * handling unchanged.
44
46
  */
45
47
  private installUnauthorizedInterceptor;
48
+ /**
49
+ * Whether a request was sent with an auth token that {@link syncAuthToken} has
50
+ * since replaced. Its 401 says nothing about the token the client holds now,
51
+ * so it must not reach {@link onUnauthorized} and log the user out.
52
+ */
53
+ private isSupersededAuthHeader;
46
54
  get forwardMPCClient(): ForwardMPCClientV2;
47
55
  set forwardMPCClient(forwardMPCClient: ForwardMPCClientV2 | undefined);
48
56
  syncAuthToken(authToken: string): void;
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/api/client.ts"],"names":[],"mappings":"AAAA,OAAc,EAAE,KAAK,aAAa,EAAE,MAAM,OAAO,CAAC;AAWlD,OAAO,EAAE,QAAQ,EAAc,KAAK,OAAO,EAAE,MAAM,aAAa,CAAC;AACjE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yCAAyC,CAAC;AAElF,qBAAa,UAAU;IACd,SAAS,EAAE,aAAa,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,8BAA8B,EAAE,MAAM,CAAC;IACvC,oBAAoB,EAAE,aAAa,CAAC;IACpC,iBAAiB,EAAE,kBAAkB,GAAG,SAAS,CAAC;IAClD,MAAM,EAAE,OAAO,CAAC;IACvB,SAAS,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC7B,SAAS,CAAC,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAC1C,sEAAsE;IACtE,SAAS,CAAC,cAAc,CAAC,EAAE,MAAM,IAAI,CAAC;gBAE1B,EACV,aAAa,EACb,UAAU,EACV,SAAS,EACT,sBAAsB,EACtB,8BAA8B,EAC9B,QAA0B,EAE1B,UAAU,EACV,gBAAgB,EAChB,MAAM,EACN,cAAc,GACf,EAAE;QACD,aAAa,EAAE,MAAM,CAAC;QACtB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,sBAAsB,CAAC,EAAE,MAAM,CAAC;QAChC,8BAA8B,CAAC,EAAE,MAAM,CAAC;QACxC,QAAQ,CAAC,EAAE,QAAQ,CAAC;QACpB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,gBAAgB,CAAC,EAAE,kBAAkB,CAAC;QACtC,MAAM,CAAC,EAAE,OAAO,CAAC;QACjB;;;;WAIG;QACH,cAAc,CAAC,EAAE,MAAM,IAAI,CAAC;KAC7B;IAmDD;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,8BAA8B;IAuBtC,IAAI,gBAAgB,IAAI,kBAAkB,CAKzC;IAED,IAAI,gBAAgB,CAAC,gBAAgB,EAAE,kBAAkB,GAAG,SAAS,EAEpE;IAED,aAAa,CAAC,SAAS,EAAE,MAAM;IA2B/B,0BAA0B,CAAC,sBAAsB,EAAE,MAAM;CAW1D"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/api/client.ts"],"names":[],"mappings":"AAAA,OAAc,EAAE,KAAK,aAAa,EAAE,MAAM,OAAO,CAAC;AAWlD,OAAO,EAAE,QAAQ,EAAc,KAAK,OAAO,EAAE,MAAM,aAAa,CAAC;AACjE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yCAAyC,CAAC;AAqBlF,qBAAa,UAAU;IACd,SAAS,EAAE,aAAa,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,8BAA8B,EAAE,MAAM,CAAC;IACvC,oBAAoB,EAAE,aAAa,CAAC;IACpC,iBAAiB,EAAE,kBAAkB,GAAG,SAAS,CAAC;IAClD,MAAM,EAAE,OAAO,CAAC;IACvB,SAAS,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC7B,SAAS,CAAC,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAC1C,sEAAsE;IACtE,SAAS,CAAC,cAAc,CAAC,EAAE,MAAM,IAAI,CAAC;IACtC,yEAAyE;IACzE,SAAS,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;gBAEzB,EACV,aAAa,EACb,UAAU,EACV,SAAS,EACT,sBAAsB,EACtB,8BAA8B,EAC9B,QAA0B,EAE1B,UAAU,EACV,gBAAgB,EAChB,MAAM,EACN,cAAc,GACf,EAAE;QACD,aAAa,EAAE,MAAM,CAAC;QACtB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,sBAAsB,CAAC,EAAE,MAAM,CAAC;QAChC,8BAA8B,CAAC,EAAE,MAAM,CAAC;QACxC,QAAQ,CAAC,EAAE,QAAQ,CAAC;QACpB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,gBAAgB,CAAC,EAAE,kBAAkB,CAAC;QACtC,MAAM,CAAC,EAAE,OAAO,CAAC;QACjB;;;;WAIG;QACH,cAAc,CAAC,EAAE,MAAM,IAAI,CAAC;KAC7B;IAoDD;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,8BAA8B;IA8BtC;;;;OAIG;IACH,OAAO,CAAC,sBAAsB;IAa9B,IAAI,gBAAgB,IAAI,kBAAkB,CAKzC;IAED,IAAI,gBAAgB,CAAC,gBAAgB,EAAE,kBAAkB,GAAG,SAAS,EAEpE;IAED,aAAa,CAAC,SAAS,EAAE,MAAM;IA4B/B,0BAA0B,CAAC,sBAAsB,EAAE,MAAM;CAW1D"}