@dynamic-labs-wallet/browser 1.1.22 → 1.1.23
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 +20 -9
- package/index.esm.js +20 -9
- package/package.json +3 -3
- package/src/backup/password/errors.d.ts.map +1 -1
- package/src/services/signedSession.d.ts +2 -2
package/index.cjs
CHANGED
|
@@ -574,14 +574,14 @@ function meetsMinVersion(sdkVersion, { minVersionByNamespace, fallbackMinVersion
|
|
|
574
574
|
|
|
575
575
|
/**
|
|
576
576
|
* Datadog event name emitted on every signed-session nonce rejection (a 400 or
|
|
577
|
-
*
|
|
577
|
+
* 403 from the backup/recovery endpoints). Log-only: lets us split the failure
|
|
578
578
|
* bucket by `reason` and measure the true per-wallet unrecoverable rate
|
|
579
579
|
* without changing any retry behavior. See DYNT-1599.
|
|
580
580
|
*/ const NONCE_FAILURE_EVENT = 'waas.signed_session.nonce_failure';
|
|
581
581
|
/**
|
|
582
|
-
* Reasons that represent a genuine session-key signature mismatch (the
|
|
583
|
-
* server returns per DYNT-1282). Used to gate
|
|
584
|
-
* that reuse
|
|
582
|
+
* Reasons that represent a genuine session-key signature mismatch (the 403 the
|
|
583
|
+
* server returns per DYNT-1282). Used to gate 403 instrumentation so callers
|
|
584
|
+
* that reuse 403 for unrelated rejections don't pollute the failure metric.
|
|
585
585
|
*/ const SESSION_SIGNATURE_FAILURE_REASONS = new Set([
|
|
586
586
|
'invalid_nonce_signature',
|
|
587
587
|
'invalid_session_signature'
|
|
@@ -675,12 +675,12 @@ function meetsMinVersion(sdkVersion, { minVersionByNamespace, fallbackMinVersion
|
|
|
675
675
|
let hasRefreshed = false;
|
|
676
676
|
return async (error, attempt)=>{
|
|
677
677
|
const status = getHttpStatus(error);
|
|
678
|
-
// A 400 is a refreshable replay nonce; a
|
|
679
|
-
// server returns to break the refresh loop (DYNT-1282) — logged only
|
|
680
|
-
// body classifies as a genuine session-signature failure so unrelated
|
|
678
|
+
// A 400 is a refreshable replay nonce; a 403 is a session-key
|
|
679
|
+
// mismatch the server returns to break the refresh loop (DYNT-1282) — logged only
|
|
680
|
+
// when the body classifies as a genuine session-signature failure so unrelated 403s
|
|
681
681
|
// (e.g. an exhausted add-signer grant) don't pollute the DYNT-1599 metric.
|
|
682
682
|
// Only the 400 can actually refresh.
|
|
683
|
-
const isSessionSignatureFailure = status ===
|
|
683
|
+
const isSessionSignatureFailure = status === 403 && SESSION_SIGNATURE_FAILURE_REASONS.has(classifyNonceFailure(readErrorBody(error)));
|
|
684
684
|
const shouldInstrument = status === 400 || isSessionSignatureFailure;
|
|
685
685
|
if (shouldInstrument) {
|
|
686
686
|
const willRefresh = status === 400 && !hasRefreshed && this.canRefresh && this.supportsReverseChannel();
|
|
@@ -878,6 +878,13 @@ const SIGNED_SESSION_FAILURE_STATUSES = new Set([
|
|
|
878
878
|
400,
|
|
879
879
|
401
|
|
880
880
|
]);
|
|
881
|
+
// CKS returns a session-key mismatch as 403. Other 403s (e.g. a rejected grant)
|
|
882
|
+
// are unrelated, so a 403 only counts when the backend code names a signature failure.
|
|
883
|
+
const SESSION_KEY_MISMATCH_STATUS = 403;
|
|
884
|
+
const SESSION_KEY_MISMATCH_REASONS = new Set([
|
|
885
|
+
'invalid_nonce_signature',
|
|
886
|
+
'invalid_session_signature'
|
|
887
|
+
]);
|
|
881
888
|
const NONCE_REASON_TO_BACKUP_REASON = {
|
|
882
889
|
nonce_already_used: 'nonce_already_used',
|
|
883
890
|
invalid_nonce_signature: 'invalid_nonce_signature',
|
|
@@ -890,13 +897,17 @@ const classifyWalletApiError = (error)=>{
|
|
|
890
897
|
if (error.status === core.NETWORK_ERROR_STATUS) {
|
|
891
898
|
return 'network';
|
|
892
899
|
}
|
|
893
|
-
|
|
900
|
+
const isSignedSessionStatus = SIGNED_SESSION_FAILURE_STATUSES.has(error.status);
|
|
901
|
+
if (!isSignedSessionStatus && error.status !== SESSION_KEY_MISMATCH_STATUS) {
|
|
894
902
|
return 'upload_failure';
|
|
895
903
|
}
|
|
896
904
|
const nonceReason = classifyNonceFailure({
|
|
897
905
|
code: error.code,
|
|
898
906
|
message: error.message
|
|
899
907
|
});
|
|
908
|
+
if (!isSignedSessionStatus && !SESSION_KEY_MISMATCH_REASONS.has(nonceReason)) {
|
|
909
|
+
return 'upload_failure';
|
|
910
|
+
}
|
|
900
911
|
return NONCE_REASON_TO_BACKUP_REASON[nonceReason];
|
|
901
912
|
};
|
|
902
913
|
const isNetworkLikeError = (error)=>{
|
package/index.esm.js
CHANGED
|
@@ -575,14 +575,14 @@ function meetsMinVersion(sdkVersion, { minVersionByNamespace, fallbackMinVersion
|
|
|
575
575
|
|
|
576
576
|
/**
|
|
577
577
|
* Datadog event name emitted on every signed-session nonce rejection (a 400 or
|
|
578
|
-
*
|
|
578
|
+
* 403 from the backup/recovery endpoints). Log-only: lets us split the failure
|
|
579
579
|
* bucket by `reason` and measure the true per-wallet unrecoverable rate
|
|
580
580
|
* without changing any retry behavior. See DYNT-1599.
|
|
581
581
|
*/ const NONCE_FAILURE_EVENT = 'waas.signed_session.nonce_failure';
|
|
582
582
|
/**
|
|
583
|
-
* Reasons that represent a genuine session-key signature mismatch (the
|
|
584
|
-
* server returns per DYNT-1282). Used to gate
|
|
585
|
-
* that reuse
|
|
583
|
+
* Reasons that represent a genuine session-key signature mismatch (the 403 the
|
|
584
|
+
* server returns per DYNT-1282). Used to gate 403 instrumentation so callers
|
|
585
|
+
* that reuse 403 for unrelated rejections don't pollute the failure metric.
|
|
586
586
|
*/ const SESSION_SIGNATURE_FAILURE_REASONS = new Set([
|
|
587
587
|
'invalid_nonce_signature',
|
|
588
588
|
'invalid_session_signature'
|
|
@@ -676,12 +676,12 @@ function meetsMinVersion(sdkVersion, { minVersionByNamespace, fallbackMinVersion
|
|
|
676
676
|
let hasRefreshed = false;
|
|
677
677
|
return async (error, attempt)=>{
|
|
678
678
|
const status = getHttpStatus(error);
|
|
679
|
-
// A 400 is a refreshable replay nonce; a
|
|
680
|
-
// server returns to break the refresh loop (DYNT-1282) — logged only
|
|
681
|
-
// body classifies as a genuine session-signature failure so unrelated
|
|
679
|
+
// A 400 is a refreshable replay nonce; a 403 is a session-key
|
|
680
|
+
// mismatch the server returns to break the refresh loop (DYNT-1282) — logged only
|
|
681
|
+
// when the body classifies as a genuine session-signature failure so unrelated 403s
|
|
682
682
|
// (e.g. an exhausted add-signer grant) don't pollute the DYNT-1599 metric.
|
|
683
683
|
// Only the 400 can actually refresh.
|
|
684
|
-
const isSessionSignatureFailure = status ===
|
|
684
|
+
const isSessionSignatureFailure = status === 403 && SESSION_SIGNATURE_FAILURE_REASONS.has(classifyNonceFailure(readErrorBody(error)));
|
|
685
685
|
const shouldInstrument = status === 400 || isSessionSignatureFailure;
|
|
686
686
|
if (shouldInstrument) {
|
|
687
687
|
const willRefresh = status === 400 && !hasRefreshed && this.canRefresh && this.supportsReverseChannel();
|
|
@@ -879,6 +879,13 @@ const SIGNED_SESSION_FAILURE_STATUSES = new Set([
|
|
|
879
879
|
400,
|
|
880
880
|
401
|
|
881
881
|
]);
|
|
882
|
+
// CKS returns a session-key mismatch as 403. Other 403s (e.g. a rejected grant)
|
|
883
|
+
// are unrelated, so a 403 only counts when the backend code names a signature failure.
|
|
884
|
+
const SESSION_KEY_MISMATCH_STATUS = 403;
|
|
885
|
+
const SESSION_KEY_MISMATCH_REASONS = new Set([
|
|
886
|
+
'invalid_nonce_signature',
|
|
887
|
+
'invalid_session_signature'
|
|
888
|
+
]);
|
|
882
889
|
const NONCE_REASON_TO_BACKUP_REASON = {
|
|
883
890
|
nonce_already_used: 'nonce_already_used',
|
|
884
891
|
invalid_nonce_signature: 'invalid_nonce_signature',
|
|
@@ -891,13 +898,17 @@ const classifyWalletApiError = (error)=>{
|
|
|
891
898
|
if (error.status === NETWORK_ERROR_STATUS) {
|
|
892
899
|
return 'network';
|
|
893
900
|
}
|
|
894
|
-
|
|
901
|
+
const isSignedSessionStatus = SIGNED_SESSION_FAILURE_STATUSES.has(error.status);
|
|
902
|
+
if (!isSignedSessionStatus && error.status !== SESSION_KEY_MISMATCH_STATUS) {
|
|
895
903
|
return 'upload_failure';
|
|
896
904
|
}
|
|
897
905
|
const nonceReason = classifyNonceFailure({
|
|
898
906
|
code: error.code,
|
|
899
907
|
message: error.message
|
|
900
908
|
});
|
|
909
|
+
if (!isSignedSessionStatus && !SESSION_KEY_MISMATCH_REASONS.has(nonceReason)) {
|
|
910
|
+
return 'upload_failure';
|
|
911
|
+
}
|
|
901
912
|
return NONCE_REASON_TO_BACKUP_REASON[nonceReason];
|
|
902
913
|
};
|
|
903
914
|
const isNetworkLikeError = (error)=>{
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dynamic-labs-wallet/browser",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.23",
|
|
4
4
|
"license": "Licensed under the Dynamic Labs, Inc. Terms Of Service (https://www.dynamic.xyz/terms-conditions)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"dependencies": {
|
|
7
|
-
"@dynamic-labs-wallet/core": "1.1.
|
|
7
|
+
"@dynamic-labs-wallet/core": "1.1.23",
|
|
8
8
|
"@dynamic-labs-wallet/forward-mpc-client": "2.0.2",
|
|
9
|
-
"@dynamic-labs-wallet/primitives": "1.1.
|
|
9
|
+
"@dynamic-labs-wallet/primitives": "1.1.23",
|
|
10
10
|
"@dynamic-labs/sdk-api-core": "0.50.0",
|
|
11
11
|
"@noble/curves": "1.8.0",
|
|
12
12
|
"argon2id": "1.0.1",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../../src/backup/password/errors.ts"],"names":[],"mappings":"AAaA;;;GAGG;AACH,MAAM,MAAM,iBAAiB,GAAG,aAAa,GAAG,gBAAgB,GAAG,cAAc,CAAC;AAElF;;;;;;;GAOG;AACH,MAAM,MAAM,yBAAyB,GACjC,gBAAgB,GAChB,oBAAoB,GACpB,oBAAoB,GACpB,yBAAyB,GACzB,2BAA2B,GAC3B,gBAAgB,GAChB,oBAAoB,GACpB,oBAAoB,GACpB,gBAAgB,GAChB,oBAAoB,GACpB,mBAAmB,GACnB,2BAA2B,GAC3B,kBAAkB,GAClB,oBAAoB,GACpB,SAAS,GACT,SAAS,CAAC;AAEd;;;;;;;;;;GAUG;AACH,eAAO,MAAM,6CAA6C;;;;;;;;;;;;;;;;;CAiBK,CAAC;AAEhE,eAAO,MAAM,yCAAyC,WAAY,yBAAyB,KAAG,OACvC,CAAC;
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../../src/backup/password/errors.ts"],"names":[],"mappings":"AAaA;;;GAGG;AACH,MAAM,MAAM,iBAAiB,GAAG,aAAa,GAAG,gBAAgB,GAAG,cAAc,CAAC;AAElF;;;;;;;GAOG;AACH,MAAM,MAAM,yBAAyB,GACjC,gBAAgB,GAChB,oBAAoB,GACpB,oBAAoB,GACpB,yBAAyB,GACzB,2BAA2B,GAC3B,gBAAgB,GAChB,oBAAoB,GACpB,oBAAoB,GACpB,gBAAgB,GAChB,oBAAoB,GACpB,mBAAmB,GACnB,2BAA2B,GAC3B,kBAAkB,GAClB,oBAAoB,GACpB,SAAS,GACT,SAAS,CAAC;AAEd;;;;;;;;;;GAUG;AACH,eAAO,MAAM,6CAA6C;;;;;;;;;;;;;;;;;CAiBK,CAAC;AAEhE,eAAO,MAAM,yCAAyC,WAAY,yBAAyB,KAAG,OACvC,CAAC;AAwKxD;;;;;;;;;GASG;AACH,eAAO,MAAM,2BAA2B,UAAW,OAAO,KAAG,yBAM5D,CAAC"}
|
|
@@ -3,7 +3,7 @@ import type { ILogger } from '@dynamic-labs-wallet/core';
|
|
|
3
3
|
type ShouldRetry = (error: unknown, attempt: number) => boolean | Promise<boolean>;
|
|
4
4
|
/**
|
|
5
5
|
* Datadog event name emitted on every signed-session nonce rejection (a 400 or
|
|
6
|
-
*
|
|
6
|
+
* 403 from the backup/recovery endpoints). Log-only: lets us split the failure
|
|
7
7
|
* bucket by `reason` and measure the true per-wallet unrecoverable rate
|
|
8
8
|
* without changing any retry behavior. See DYNT-1599.
|
|
9
9
|
*/
|
|
@@ -11,7 +11,7 @@ export declare const NONCE_FAILURE_EVENT = "waas.signed_session.nonce_failure";
|
|
|
11
11
|
/**
|
|
12
12
|
* Coarse cause of a signed-session nonce rejection. `invalid_nonce_signature`
|
|
13
13
|
* and `invalid_session_signature` (a bad/stale signing key that diverged from
|
|
14
|
-
* the JWT-embedded session key — surfaced as a
|
|
14
|
+
* the JWT-embedded session key — surfaced as a 403 since DYNT-1282) cannot be
|
|
15
15
|
* fixed by refreshing the nonce, whereas `nonce_already_used` (a consumed
|
|
16
16
|
* replay nonce, a 400) can — so splitting them tells us whether the
|
|
17
17
|
* refresh-and-retry path can actually help.
|