@dynamic-labs/waas 5.6.1 → 5.8.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.
package/CHANGELOG.md CHANGED
@@ -1,4 +1,32 @@
1
1
 
2
+ ## [5.8.0](https://github.com/dynamic-labs/dynamic-auth/compare/v5.7.0...v5.8.0) (2026-09-09)
3
+
4
+
5
+ ### Features
6
+
7
+ * **solana-core:** standalone sponsored ATA creation ([#12365](https://github.com/dynamic-labs/dynamic-auth/issues/12365)) ([ac2e776](https://github.com/dynamic-labs/dynamic-auth/commit/ac2e7769fcf91c868e961a227b8acb6347bf3f13))
8
+
9
+
10
+ ### Bug Fixes
11
+
12
+ * do not report wallets installed from a provider selection router ([#12340](https://github.com/dynamic-labs/dynamic-auth/issues/12340)) ([dac5546](https://github.com/dynamic-labs/dynamic-auth/commit/dac5546edf6004c37bd84dd2089d94952949230b))
13
+ * **screening:** soften the blocked-wallet copy to be provider-neutral ([#12358](https://github.com/dynamic-labs/dynamic-auth/issues/12358)) ([b4854d8](https://github.com/dynamic-labs/dynamic-auth/commit/b4854d88fa67f684be0e133edd5fd4a4bf5c7f37))
14
+ * show transaction amount when simulation returns no transfers ([#12355](https://github.com/dynamic-labs/dynamic-auth/issues/12355)) ([bfaf337](https://github.com/dynamic-labs/dynamic-auth/commit/bfaf337e5350970f71255baff065e0cdbccdc7ca))
15
+
16
+ ## [5.7.0](https://github.com/dynamic-labs/dynamic-auth/compare/v5.6.1...v5.7.0) (2026-09-08)
17
+
18
+
19
+ ### Features
20
+
21
+ * **social:** add gemini social provider ([#12292](https://github.com/dynamic-labs/dynamic-auth/issues/12292)) ([fa72cb0](https://github.com/dynamic-labs/dynamic-auth/commit/fa72cb09f678506a5f34188eb7d62415bcb7073b))
22
+
23
+
24
+ ### Bug Fixes
25
+
26
+ * **locale:** add missing dyn_upgrade_wallet.no_legacy_wallets and .close keys ([#12350](https://github.com/dynamic-labs/dynamic-auth/issues/12350)) ([50da3fa](https://github.com/dynamic-labs/dynamic-auth/commit/50da3fa3078de4ecbd88031a3e533a4ff6ced89b))
27
+ * **sdk-react-core:** expose SDK i18next instance for extension packages ([#12351](https://github.com/dynamic-labs/dynamic-auth/issues/12351)) ([f3d95b1](https://github.com/dynamic-labs/dynamic-auth/commit/f3d95b1bb1c30114d32d93dec4e9c2455ab4fdbb))
28
+ * **sdk-react-core:** publish ./icons and ./components subpath exports ([#12334](https://github.com/dynamic-labs/dynamic-auth/issues/12334)) ([519487c](https://github.com/dynamic-labs/dynamic-auth/commit/519487cf5f4f7abe895a125c5bf38800cae04bb5))
29
+
2
30
  ### [5.6.1](https://github.com/dynamic-labs/dynamic-auth/compare/v5.6.0...v5.6.1) (2026-09-01)
3
31
 
4
32
 
package/package.cjs CHANGED
@@ -3,6 +3,6 @@
3
3
 
4
4
  Object.defineProperty(exports, '__esModule', { value: true });
5
5
 
6
- var version = "5.6.1";
6
+ var version = "5.8.0";
7
7
 
8
8
  exports.version = version;
package/package.js CHANGED
@@ -1,4 +1,4 @@
1
1
  'use client'
2
- var version = "5.6.1";
2
+ var version = "5.8.0";
3
3
 
4
4
  export { version };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dynamic-labs/waas",
3
- "version": "5.6.1",
3
+ "version": "5.8.0",
4
4
  "type": "module",
5
5
  "author": "Dynamic Labs, Inc.",
6
6
  "license": "MIT",
@@ -17,18 +17,18 @@
17
17
  },
18
18
  "dependencies": {
19
19
  "@dynamic-labs-sdk/client": "1.31.0",
20
- "@dynamic-labs/assert-package-version": "5.6.1",
21
- "@dynamic-labs/sdk-api-core": "0.12.0",
20
+ "@dynamic-labs/assert-package-version": "5.8.0",
21
+ "@dynamic-labs/sdk-api-core": "0.32.0",
22
22
  "@dynamic-labs-wallet/browser-wallet-client": "1.0.118",
23
23
  "@dynamic-labs-wallet/forward-mpc-client": "1.0.2",
24
24
  "zod": "4.0.5",
25
- "@dynamic-labs/ethereum-core": "5.6.1",
26
- "@dynamic-labs/logger": "5.6.1",
27
- "@dynamic-labs/solana-core": "5.6.1",
28
- "@dynamic-labs/sui-core": "5.6.1",
29
- "@dynamic-labs/utils": "5.6.1",
30
- "@dynamic-labs/wallet-book": "5.6.1",
31
- "@dynamic-labs/wallet-connector-core": "5.6.1"
25
+ "@dynamic-labs/ethereum-core": "5.8.0",
26
+ "@dynamic-labs/logger": "5.8.0",
27
+ "@dynamic-labs/solana-core": "5.8.0",
28
+ "@dynamic-labs/sui-core": "5.8.0",
29
+ "@dynamic-labs/utils": "5.8.0",
30
+ "@dynamic-labs/wallet-book": "5.8.0",
31
+ "@dynamic-labs/wallet-connector-core": "5.8.0"
32
32
  },
33
33
  "peerDependencies": {}
34
34
  }
@@ -262,6 +262,31 @@ const withDynamicWaas = (BaseClass) => {
262
262
  return client;
263
263
  });
264
264
  }
265
+ /**
266
+ * Stops the client answering the iframe's session-scoped reverse-channel
267
+ * requests — the signed session and the 401 notification. Its key-share
268
+ * handlers stay attached until the client's own cleanup() has its ACK, so
269
+ * the iframe can still clear shares on logout.
270
+ *
271
+ * Returns false only if the attempt threw: the client may still be
272
+ * registered, so the caller must not revoke it. Never rethrows — this runs
273
+ * on the rotation and logout paths, where throwing would leave the caller
274
+ * with no client at all.
275
+ */
276
+ detachWaasClient(client, reason) {
277
+ var _a;
278
+ // The pinned browser-wallet-client predates detach(); this goes away with
279
+ // the version bump.
280
+ const detachable = client;
281
+ try {
282
+ (_a = detachable === null || detachable === void 0 ? void 0 : detachable.detach) === null || _a === void 0 ? void 0 : _a.call(detachable);
283
+ return true;
284
+ }
285
+ catch (error) {
286
+ this.instrument('[DynamicWaasMixin] WaaS client detach failed', Object.assign({ key: 'waas-client-detach-failed', operation: 'detachWaasClient', reason, time: 0 }, this.buildErrorInstrumentContext(error)));
287
+ return false;
288
+ }
289
+ }
265
290
  getWaasWalletClient(traceContext_1) {
266
291
  return _tslib.__awaiter(this, arguments, void 0, function* (traceContext, { forceRebuild = false } = {}) {
267
292
  var _a, _b;
@@ -271,11 +296,19 @@ const withDynamicWaas = (BaseClass) => {
271
296
  // available (see getWaasWalletConnector's live-token guard); otherwise
272
297
  // createDynamicWaasClient would throw "Auth token is required".
273
298
  if (forceRebuild) {
274
- // Revoke the previous client's nonce callback before dropping it.
275
- // The old DynamicWalletClient is not destroyed — it has no cancellation
276
- // API — but revoking its reverse-channel callback prevents it from
277
- // fetching fresh nonces and competing with the new client's recovery.
278
- (_a = this.revokeSignedSession) === null || _a === void 0 ? void 0 : _a.call(this, 'force-rebuild');
299
+ // Detach the superseded client, then revoke it — and never revoke one we
300
+ // did not detach. The reverse channel is page-wide and
301
+ // first-response-wins, so a revoked-but-still-attached client rejects
302
+ // instantly, beats the live client to every getSignedSessionId and
303
+ // poisons wallet creation for the life of the iframe. Two cases land
304
+ // there: a failed detach, and a concurrent rebuild, where
305
+ // createDynamicWaasClient has installed the new revoker but not yet
306
+ // returned the client it belongs to. The revoke stays as a guard for a
307
+ // caller still holding a direct reference.
308
+ const superseded = this.dynamicWaasClient;
309
+ if (superseded && this.detachWaasClient(superseded, 'force-rebuild')) {
310
+ (_a = this.revokeSignedSession) === null || _a === void 0 ? void 0 : _a.call(this, 'force-rebuild');
311
+ }
279
312
  this.revokeSignedSession = undefined;
280
313
  this.dynamicWaasClient = undefined;
281
314
  }
@@ -877,7 +910,28 @@ const withDynamicWaas = (BaseClass) => {
877
910
  });
878
911
  }
879
912
  }
880
- (_a = this.revokeSignedSession) === null || _a === void 0 ? void 0 : _a.call(this, 'end-session');
913
+ // Detach synchronously: the cleanup() above removes the handlers too, but
914
+ // it is un-awaited and can sit on the channel's 5s timeout first, leaving
915
+ // this client in the race with its callback already revoked.
916
+ //
917
+ // Same guard as the rebuild path: never revoke a client we did not detach.
918
+ // waasClient is undefined whenever getWaasWalletClient threw (pending-auth
919
+ // scope, or a failed build), and a client installed concurrently would own
920
+ // the revoke we still hold — revoking that one while it is attached is the
921
+ // original bug.
922
+ const superseded = waasClient !== null && waasClient !== void 0 ? waasClient : this.dynamicWaasClient;
923
+ const detached = superseded
924
+ ? this.detachWaasClient(superseded, 'end-session')
925
+ : false;
926
+ // Revoke only while the revoker still belongs to the client we detached.
927
+ // endSession awaits the client, the active address and the key-share
928
+ // removal, and a rotation completing in any of those windows swaps both
929
+ // fields — revoking the live replacement while it is attached is the
930
+ // original bug. Detaching the captured client is unconditional: it is
931
+ // always safe, and it is the half that actually leaves the race.
932
+ if (detached && superseded === this.dynamicWaasClient) {
933
+ (_a = this.revokeSignedSession) === null || _a === void 0 ? void 0 : _a.call(this, 'end-session');
934
+ }
881
935
  this.revokeSignedSession = undefined;
882
936
  this.dynamicWaasClient = undefined;
883
937
  });
@@ -83,6 +83,18 @@ export declare const withDynamicWaas: <T extends abstract new (...args: any[]) =
83
83
  getSignedSessionId: () => Promise<string>;
84
84
  };
85
85
  createDynamicWaasClient(traceContext?: TraceContext): Promise<DynamicWalletClient>;
86
+ /**
87
+ * Stops the client answering the iframe's session-scoped reverse-channel
88
+ * requests — the signed session and the 401 notification. Its key-share
89
+ * handlers stay attached until the client's own cleanup() has its ACK, so
90
+ * the iframe can still clear shares on logout.
91
+ *
92
+ * Returns false only if the attempt threw: the client may still be
93
+ * registered, so the caller must not revoke it. Never rethrows — this runs
94
+ * on the rotation and logout paths, where throwing would leave the caller
95
+ * with no client at all.
96
+ */
97
+ detachWaasClient(client: DynamicWalletClient | undefined, reason: string): boolean;
86
98
  getWaasWalletClient(traceContext?: TraceContext, { forceRebuild }?: {
87
99
  forceRebuild?: boolean;
88
100
  }): Promise<DynamicWalletClient>;
@@ -258,6 +258,31 @@ const withDynamicWaas = (BaseClass) => {
258
258
  return client;
259
259
  });
260
260
  }
261
+ /**
262
+ * Stops the client answering the iframe's session-scoped reverse-channel
263
+ * requests — the signed session and the 401 notification. Its key-share
264
+ * handlers stay attached until the client's own cleanup() has its ACK, so
265
+ * the iframe can still clear shares on logout.
266
+ *
267
+ * Returns false only if the attempt threw: the client may still be
268
+ * registered, so the caller must not revoke it. Never rethrows — this runs
269
+ * on the rotation and logout paths, where throwing would leave the caller
270
+ * with no client at all.
271
+ */
272
+ detachWaasClient(client, reason) {
273
+ var _a;
274
+ // The pinned browser-wallet-client predates detach(); this goes away with
275
+ // the version bump.
276
+ const detachable = client;
277
+ try {
278
+ (_a = detachable === null || detachable === void 0 ? void 0 : detachable.detach) === null || _a === void 0 ? void 0 : _a.call(detachable);
279
+ return true;
280
+ }
281
+ catch (error) {
282
+ this.instrument('[DynamicWaasMixin] WaaS client detach failed', Object.assign({ key: 'waas-client-detach-failed', operation: 'detachWaasClient', reason, time: 0 }, this.buildErrorInstrumentContext(error)));
283
+ return false;
284
+ }
285
+ }
261
286
  getWaasWalletClient(traceContext_1) {
262
287
  return __awaiter(this, arguments, void 0, function* (traceContext, { forceRebuild = false } = {}) {
263
288
  var _a, _b;
@@ -267,11 +292,19 @@ const withDynamicWaas = (BaseClass) => {
267
292
  // available (see getWaasWalletConnector's live-token guard); otherwise
268
293
  // createDynamicWaasClient would throw "Auth token is required".
269
294
  if (forceRebuild) {
270
- // Revoke the previous client's nonce callback before dropping it.
271
- // The old DynamicWalletClient is not destroyed — it has no cancellation
272
- // API — but revoking its reverse-channel callback prevents it from
273
- // fetching fresh nonces and competing with the new client's recovery.
274
- (_a = this.revokeSignedSession) === null || _a === void 0 ? void 0 : _a.call(this, 'force-rebuild');
295
+ // Detach the superseded client, then revoke it — and never revoke one we
296
+ // did not detach. The reverse channel is page-wide and
297
+ // first-response-wins, so a revoked-but-still-attached client rejects
298
+ // instantly, beats the live client to every getSignedSessionId and
299
+ // poisons wallet creation for the life of the iframe. Two cases land
300
+ // there: a failed detach, and a concurrent rebuild, where
301
+ // createDynamicWaasClient has installed the new revoker but not yet
302
+ // returned the client it belongs to. The revoke stays as a guard for a
303
+ // caller still holding a direct reference.
304
+ const superseded = this.dynamicWaasClient;
305
+ if (superseded && this.detachWaasClient(superseded, 'force-rebuild')) {
306
+ (_a = this.revokeSignedSession) === null || _a === void 0 ? void 0 : _a.call(this, 'force-rebuild');
307
+ }
275
308
  this.revokeSignedSession = undefined;
276
309
  this.dynamicWaasClient = undefined;
277
310
  }
@@ -873,7 +906,28 @@ const withDynamicWaas = (BaseClass) => {
873
906
  });
874
907
  }
875
908
  }
876
- (_a = this.revokeSignedSession) === null || _a === void 0 ? void 0 : _a.call(this, 'end-session');
909
+ // Detach synchronously: the cleanup() above removes the handlers too, but
910
+ // it is un-awaited and can sit on the channel's 5s timeout first, leaving
911
+ // this client in the race with its callback already revoked.
912
+ //
913
+ // Same guard as the rebuild path: never revoke a client we did not detach.
914
+ // waasClient is undefined whenever getWaasWalletClient threw (pending-auth
915
+ // scope, or a failed build), and a client installed concurrently would own
916
+ // the revoke we still hold — revoking that one while it is attached is the
917
+ // original bug.
918
+ const superseded = waasClient !== null && waasClient !== void 0 ? waasClient : this.dynamicWaasClient;
919
+ const detached = superseded
920
+ ? this.detachWaasClient(superseded, 'end-session')
921
+ : false;
922
+ // Revoke only while the revoker still belongs to the client we detached.
923
+ // endSession awaits the client, the active address and the key-share
924
+ // removal, and a rotation completing in any of those windows swaps both
925
+ // fields — revoking the live replacement while it is attached is the
926
+ // original bug. Detaching the captured client is unconditional: it is
927
+ // always safe, and it is the half that actually leaves the race.
928
+ if (detached && superseded === this.dynamicWaasClient) {
929
+ (_a = this.revokeSignedSession) === null || _a === void 0 ? void 0 : _a.call(this, 'end-session');
930
+ }
877
931
  this.revokeSignedSession = undefined;
878
932
  this.dynamicWaasClient = undefined;
879
933
  });