@dynamic-labs/waas 4.77.1 → 4.77.3

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/CHANGELOG.md CHANGED
@@ -1,4 +1,26 @@
1
1
 
2
+ ### [4.77.3](https://github.com/dynamic-labs/dynamic-auth/compare/v4.77.2...v4.77.3) (2026-04-18)
3
+
4
+
5
+ ### Bug Fixes
6
+
7
+ * **ton:** convert sendBalance amount to smallest units ([#10941](https://github.com/dynamic-labs/dynamic-auth/issues/10941)) ([5eac6be](https://github.com/dynamic-labs/dynamic-auth/commit/5eac6be1c3444525893e6e5e95ce65f6c9f9dea3))
8
+
9
+ ### [4.77.2](https://github.com/dynamic-labs/dynamic-auth/compare/v4.77.1...v4.77.2) (2026-04-16)
10
+
11
+
12
+ ### Bug Fixes
13
+
14
+ * add support for next 16 and dual-module-import breaking. ([#10926](https://github.com/dynamic-labs/dynamic-auth/issues/10926)) ([312c7b8](https://github.com/dynamic-labs/dynamic-auth/commit/312c7b83f7a39109c9a9950a6d45ea9a815dd800))
15
+ * **DYNT-399:** phantom btc missing public address ([#10914](https://github.com/dynamic-labs/dynamic-auth/issues/10914)) ([632ead1](https://github.com/dynamic-labs/dynamic-auth/commit/632ead1e3b500ff2e78915459d6764e4c4a49168))
16
+ * **playwright:** fix tests flakiness [DYNT-555] ([#10923](https://github.com/dynamic-labs/dynamic-auth/issues/10923)) ([6556884](https://github.com/dynamic-labs/dynamic-auth/commit/65568849580bb8549eb11a1c44fd22fbc56f624c))
17
+ * **playwright:** stabilize flaky tests (domain-access-control + embedded-wallet) DYNT-495 ([#10881](https://github.com/dynamic-labs/dynamic-auth/issues/10881)) ([4925e19](https://github.com/dynamic-labs/dynamic-auth/commit/4925e1903b5f6a37a550cb34ab900abff1cc9f23))
18
+ * remediate high-severity dependency vulnerabilities ([#10919](https://github.com/dynamic-labs/dynamic-auth/issues/10919)) ([7d7cfdd](https://github.com/dynamic-labs/dynamic-auth/commit/7d7cfdd162d9f7a3c8c2501d47b33ae8f4e4d26d))
19
+ * remediate high-severity dependency vulnerabilities ([#10925](https://github.com/dynamic-labs/dynamic-auth/issues/10925)) ([4039d25](https://github.com/dynamic-labs/dynamic-auth/commit/4039d25afea78c49999443caba65d42d4fc96c95))
20
+ * upgrade axios to 1.15.0 to fix CVE-2026-40175 ([#10918](https://github.com/dynamic-labs/dynamic-auth/issues/10918)) ([74751dc](https://github.com/dynamic-labs/dynamic-auth/commit/74751dcf4e7a918e39de2fb667ee6ead4a7a4602))
21
+ * **waas:** skip password prompt when wallet is not password-encrypted ([#10916](https://github.com/dynamic-labs/dynamic-auth/issues/10916)) ([e3dd403](https://github.com/dynamic-labs/dynamic-auth/commit/e3dd4035c447106d40baa5e7e12fa35fafa0808f))
22
+ * **walletconnect:** improve error logging and handle empty network configs ([#10897](https://github.com/dynamic-labs/dynamic-auth/issues/10897)) ([bea7a9f](https://github.com/dynamic-labs/dynamic-auth/commit/bea7a9fd4628e4fbca554f8eed4a0dc097fab83b))
23
+
2
24
  ### [4.77.1](https://github.com/dynamic-labs/dynamic-auth/compare/v4.77.0...v4.77.1) (2026-04-10)
3
25
 
4
26
  ### Bug Fixes
package/package.cjs CHANGED
@@ -3,6 +3,6 @@
3
3
 
4
4
  Object.defineProperty(exports, '__esModule', { value: true });
5
5
 
6
- var version = "4.77.1";
6
+ var version = "4.77.3";
7
7
 
8
8
  exports.version = version;
package/package.js CHANGED
@@ -1,4 +1,4 @@
1
1
  'use client'
2
- var version = "4.77.1";
2
+ var version = "4.77.3";
3
3
 
4
4
  export { version };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dynamic-labs/waas",
3
- "version": "4.77.1",
3
+ "version": "4.77.3",
4
4
  "type": "module",
5
5
  "author": "Dynamic Labs, Inc.",
6
6
  "license": "MIT",
@@ -17,16 +17,16 @@
17
17
  },
18
18
  "dependencies": {
19
19
  "@dynamic-labs-sdk/client": "0.24.0",
20
- "@dynamic-labs/assert-package-version": "4.77.1",
20
+ "@dynamic-labs/assert-package-version": "4.77.3",
21
21
  "@dynamic-labs/sdk-api-core": "0.0.927",
22
22
  "@dynamic-labs-wallet/browser-wallet-client": "0.0.314",
23
- "@dynamic-labs/ethereum-core": "4.77.1",
24
- "@dynamic-labs/logger": "4.77.1",
25
- "@dynamic-labs/solana-core": "4.77.1",
26
- "@dynamic-labs/sui-core": "4.77.1",
27
- "@dynamic-labs/utils": "4.77.1",
28
- "@dynamic-labs/wallet-book": "4.77.1",
29
- "@dynamic-labs/wallet-connector-core": "4.77.1"
23
+ "@dynamic-labs/ethereum-core": "4.77.3",
24
+ "@dynamic-labs/logger": "4.77.3",
25
+ "@dynamic-labs/solana-core": "4.77.3",
26
+ "@dynamic-labs/sui-core": "4.77.3",
27
+ "@dynamic-labs/utils": "4.77.3",
28
+ "@dynamic-labs/wallet-book": "4.77.3",
29
+ "@dynamic-labs/wallet-connector-core": "4.77.3"
30
30
  },
31
31
  "peerDependencies": {}
32
32
  }
@@ -57,7 +57,11 @@ const withDynamicWaas = (BaseClass) => {
57
57
  if (recoveryState.walletReadyState === 'ready') {
58
58
  return undefined;
59
59
  }
60
- // Wallet is encrypted and needs to be unlocked
60
+ // If wallet is not password-encrypted, no password needed for recovery
61
+ if (!recoveryState.isPasswordEncrypted) {
62
+ return undefined;
63
+ }
64
+ // Wallet is password-encrypted and needs to be unlocked
61
65
  if (!this.getWalletPassword) {
62
66
  throw new utils.DynamicError('Wallet is locked but no password provider is configured');
63
67
  }
@@ -66,25 +70,35 @@ const withDynamicWaas = (BaseClass) => {
66
70
  chainName: this.chainName,
67
71
  });
68
72
  if (!password) {
69
- throw new utils.DynamicError('Password is required to sign with this wallet');
73
+ throw new utils.UserRejectedRequestError();
70
74
  }
71
75
  return password;
72
76
  });
73
77
  }
74
78
  /**
75
- * Always prompts for the wallet password regardless of wallet state.
79
+ * Prompts for the wallet password if the wallet is password-encrypted.
76
80
  *
77
81
  * Unlike `getPasswordIfNeeded` (which skips the prompt when the wallet is
78
- * already unlocked in memory), this method always asks for the password.
79
- * Use it for operations that encrypt/decrypt data stored externally
80
- * (e.g. cloud backup/restore), where the password is required to
81
- * encrypt/decrypt the shares on disk — not just to unlock the wallet.
82
+ * already unlocked in memory), this method always asks for the password
83
+ * when the wallet is password-encrypted. Use it for operations that
84
+ * encrypt/decrypt data stored externally (e.g. cloud backup/restore),
85
+ * where the password is required to encrypt/decrypt the shares on disk.
86
+ *
87
+ * Returns undefined if the wallet is not password-encrypted or if no
88
+ * password provider is configured.
82
89
  */
83
90
  getPassword(_a) {
84
91
  return _tslib.__awaiter(this, arguments, void 0, function* ({ accountAddress, }) {
85
92
  if (!this.getWalletPassword) {
86
93
  return undefined;
87
94
  }
95
+ // Check if wallet is password-encrypted before prompting
96
+ const recoveryState = yield this.getWalletRecoveryState({
97
+ accountAddress,
98
+ });
99
+ if (!recoveryState.isPasswordEncrypted) {
100
+ return undefined;
101
+ }
88
102
  return this.getWalletPassword({
89
103
  accountAddress,
90
104
  chainName: this.chainName,
@@ -655,6 +669,7 @@ const withDynamicWaas = (BaseClass) => {
655
669
  }
656
670
  instrumentAsync(_a) {
657
671
  return _tslib.__awaiter(this, arguments, void 0, function* ({ operation, resource, fn, context, }) {
672
+ var _b, _c;
658
673
  const timing = new instrumentation.InstrumentationTimer(context === null || context === void 0 ? void 0 : context.startTime);
659
674
  if (context === null || context === void 0 ? void 0 : context.stepStartTime) {
660
675
  timing.setStepStartTime(context.stepStartTime);
@@ -669,7 +684,20 @@ const withDynamicWaas = (BaseClass) => {
669
684
  return result;
670
685
  }
671
686
  catch (error) {
672
- this.instrument(`[${operation}] ${resource} - failed`, Object.assign(Object.assign({ key: `${resource}-failed`, operation, stepTime: timing.getStepElapsed(), time: timing.getElapsed() }, context), { error }));
687
+ const isUserRejection = error instanceof utils.UserRejectedRequestError ||
688
+ (error === null || error === void 0 ? void 0 : error.code) === 'user_rejected_request';
689
+ const errorContext = {
690
+ errorCode: (_b = error === null || error === void 0 ? void 0 : error.code) !== null && _b !== void 0 ? _b : 'unknown',
691
+ errorMessage: error instanceof Error ? error.message : String(error),
692
+ errorType: (_c = error === null || error === void 0 ? void 0 : error.constructor) === null || _c === void 0 ? void 0 : _c.name,
693
+ };
694
+ if (isUserRejection) {
695
+ // User-initiated cancellations are expected — debug only, no backend noise
696
+ this.logger.debug(`[${operation}] ${resource} - cancelled`, Object.assign(Object.assign({ key: `${resource}-cancelled`, operation, stepTime: timing.getStepElapsed(), time: timing.getElapsed() }, context), errorContext));
697
+ }
698
+ else {
699
+ this.instrument(`[${operation}] ${resource} - failed`, Object.assign(Object.assign({ key: `${resource}-failed`, operation, stepTime: timing.getStepElapsed(), time: timing.getElapsed() }, context), errorContext));
700
+ }
673
701
  throw error;
674
702
  }
675
703
  });
@@ -50,13 +50,16 @@ export declare const withDynamicWaas: <T extends abstract new (...args: any[]) =
50
50
  accountAddress: string;
51
51
  }): Promise<string | undefined>;
52
52
  /**
53
- * Always prompts for the wallet password regardless of wallet state.
53
+ * Prompts for the wallet password if the wallet is password-encrypted.
54
54
  *
55
55
  * Unlike `getPasswordIfNeeded` (which skips the prompt when the wallet is
56
- * already unlocked in memory), this method always asks for the password.
57
- * Use it for operations that encrypt/decrypt data stored externally
58
- * (e.g. cloud backup/restore), where the password is required to
59
- * encrypt/decrypt the shares on disk — not just to unlock the wallet.
56
+ * already unlocked in memory), this method always asks for the password
57
+ * when the wallet is password-encrypted. Use it for operations that
58
+ * encrypt/decrypt data stored externally (e.g. cloud backup/restore),
59
+ * where the password is required to encrypt/decrypt the shares on disk.
60
+ *
61
+ * Returns undefined if the wallet is not password-encrypted or if no
62
+ * password provider is configured.
60
63
  */
61
64
  getPassword({ accountAddress, }: {
62
65
  accountAddress: string;
@@ -2,7 +2,7 @@
2
2
  import { __awaiter } from '../_virtual/_tslib.js';
3
3
  import { DynamicWalletClient } from '@dynamic-labs-wallet/browser-wallet-client';
4
4
  import { MFAAction, TokenScope } from '@dynamic-labs/sdk-api-core';
5
- import { DynamicError, PlatformService } from '@dynamic-labs/utils';
5
+ import { DynamicError, UserRejectedRequestError, PlatformService } from '@dynamic-labs/utils';
6
6
  import { version } from '../package.js';
7
7
  import { DEFAULT_BASE_API_URL, DEFAULT_BASE_MPC_RELAY_API_URL } from '../utils/constants.js';
8
8
  import { createWaasClientSecureStorage } from '../utils/createWaasClientSecureStorage.js';
@@ -53,7 +53,11 @@ const withDynamicWaas = (BaseClass) => {
53
53
  if (recoveryState.walletReadyState === 'ready') {
54
54
  return undefined;
55
55
  }
56
- // Wallet is encrypted and needs to be unlocked
56
+ // If wallet is not password-encrypted, no password needed for recovery
57
+ if (!recoveryState.isPasswordEncrypted) {
58
+ return undefined;
59
+ }
60
+ // Wallet is password-encrypted and needs to be unlocked
57
61
  if (!this.getWalletPassword) {
58
62
  throw new DynamicError('Wallet is locked but no password provider is configured');
59
63
  }
@@ -62,25 +66,35 @@ const withDynamicWaas = (BaseClass) => {
62
66
  chainName: this.chainName,
63
67
  });
64
68
  if (!password) {
65
- throw new DynamicError('Password is required to sign with this wallet');
69
+ throw new UserRejectedRequestError();
66
70
  }
67
71
  return password;
68
72
  });
69
73
  }
70
74
  /**
71
- * Always prompts for the wallet password regardless of wallet state.
75
+ * Prompts for the wallet password if the wallet is password-encrypted.
72
76
  *
73
77
  * Unlike `getPasswordIfNeeded` (which skips the prompt when the wallet is
74
- * already unlocked in memory), this method always asks for the password.
75
- * Use it for operations that encrypt/decrypt data stored externally
76
- * (e.g. cloud backup/restore), where the password is required to
77
- * encrypt/decrypt the shares on disk — not just to unlock the wallet.
78
+ * already unlocked in memory), this method always asks for the password
79
+ * when the wallet is password-encrypted. Use it for operations that
80
+ * encrypt/decrypt data stored externally (e.g. cloud backup/restore),
81
+ * where the password is required to encrypt/decrypt the shares on disk.
82
+ *
83
+ * Returns undefined if the wallet is not password-encrypted or if no
84
+ * password provider is configured.
78
85
  */
79
86
  getPassword(_a) {
80
87
  return __awaiter(this, arguments, void 0, function* ({ accountAddress, }) {
81
88
  if (!this.getWalletPassword) {
82
89
  return undefined;
83
90
  }
91
+ // Check if wallet is password-encrypted before prompting
92
+ const recoveryState = yield this.getWalletRecoveryState({
93
+ accountAddress,
94
+ });
95
+ if (!recoveryState.isPasswordEncrypted) {
96
+ return undefined;
97
+ }
84
98
  return this.getWalletPassword({
85
99
  accountAddress,
86
100
  chainName: this.chainName,
@@ -651,6 +665,7 @@ const withDynamicWaas = (BaseClass) => {
651
665
  }
652
666
  instrumentAsync(_a) {
653
667
  return __awaiter(this, arguments, void 0, function* ({ operation, resource, fn, context, }) {
668
+ var _b, _c;
654
669
  const timing = new InstrumentationTimer(context === null || context === void 0 ? void 0 : context.startTime);
655
670
  if (context === null || context === void 0 ? void 0 : context.stepStartTime) {
656
671
  timing.setStepStartTime(context.stepStartTime);
@@ -665,7 +680,20 @@ const withDynamicWaas = (BaseClass) => {
665
680
  return result;
666
681
  }
667
682
  catch (error) {
668
- this.instrument(`[${operation}] ${resource} - failed`, Object.assign(Object.assign({ key: `${resource}-failed`, operation, stepTime: timing.getStepElapsed(), time: timing.getElapsed() }, context), { error }));
683
+ const isUserRejection = error instanceof UserRejectedRequestError ||
684
+ (error === null || error === void 0 ? void 0 : error.code) === 'user_rejected_request';
685
+ const errorContext = {
686
+ errorCode: (_b = error === null || error === void 0 ? void 0 : error.code) !== null && _b !== void 0 ? _b : 'unknown',
687
+ errorMessage: error instanceof Error ? error.message : String(error),
688
+ errorType: (_c = error === null || error === void 0 ? void 0 : error.constructor) === null || _c === void 0 ? void 0 : _c.name,
689
+ };
690
+ if (isUserRejection) {
691
+ // User-initiated cancellations are expected — debug only, no backend noise
692
+ this.logger.debug(`[${operation}] ${resource} - cancelled`, Object.assign(Object.assign({ key: `${resource}-cancelled`, operation, stepTime: timing.getStepElapsed(), time: timing.getElapsed() }, context), errorContext));
693
+ }
694
+ else {
695
+ this.instrument(`[${operation}] ${resource} - failed`, Object.assign(Object.assign({ key: `${resource}-failed`, operation, stepTime: timing.getStepElapsed(), time: timing.getElapsed() }, context), errorContext));
696
+ }
669
697
  throw error;
670
698
  }
671
699
  });