@mattrglobal/verifier-sdk-web 2.2.1-unstable.9 → 2.3.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.
@@ -7,8 +7,8 @@
7
7
  * Do Not Translate or Localize
8
8
  *
9
9
  * Bundle of @mattrglobal/verifier-sdk-web
10
- * Generated: 2026-06-19
11
- * Version: 2.2.0
10
+ * Generated: 2026-08-17
11
+ * Version: 2.3.0
12
12
  * Dependencies:
13
13
  *
14
14
  * neverthrow -- 4.3.0
@@ -1463,6 +1463,7 @@ const CreateSessionOpenId4vpResponseValidator = object({
1463
1463
  sessionId: string(),
1464
1464
  sessionKey: string(),
1465
1465
  sessionUrl: string(),
1466
+ authRequestUri: string(),
1466
1467
  state: optional(string())
1467
1468
  });
1468
1469
 
@@ -1485,7 +1486,7 @@ var LocalStorageKey;
1485
1486
 
1486
1487
  const MATTR_SDK_VERSION_HEADER = "x-mattr-sdk-version";
1487
1488
 
1488
- const MATTR_SDK_VERSION_VALUE = "2.2.0";
1489
+ const MATTR_SDK_VERSION_VALUE = "2.3.0";
1489
1490
 
1490
1491
  var MessageEventDataType;
1491
1492
 
@@ -1493,6 +1494,7 @@ var MessageEventDataType;
1493
1494
  MessageEventDataType["PresentationCompleted"] = "PresentationCompleted";
1494
1495
  MessageEventDataType["PresentationTimeout"] = "PresentationTimeout";
1495
1496
  MessageEventDataType["PresentationAbort"] = "PresentationAbort";
1497
+ MessageEventDataType["PresentationRequestUpdated"] = "PresentationRequestUpdated";
1496
1498
  })(MessageEventDataType || (MessageEventDataType = {}));
1497
1499
 
1498
1500
  const OpenId4vpConfigSameDeviceOptionsValidator = object({
@@ -1525,6 +1527,7 @@ exports.RequestCredentialsErrorType = void 0;
1525
1527
  RequestCredentialsErrorType["RequestCredentialsFailed"] = "RequestCredentialsFailed";
1526
1528
  RequestCredentialsErrorType["Timeout"] = "Timeout";
1527
1529
  RequestCredentialsErrorType["Abort"] = "Abort";
1530
+ RequestCredentialsErrorType["OnPresentationRequestFailed"] = "OnPresentationRequestFailed";
1528
1531
  })(exports.RequestCredentialsErrorType || (exports.RequestCredentialsErrorType = {}));
1529
1532
 
1530
1533
  var RequestCredentialsErrorMessage;
@@ -1540,6 +1543,7 @@ var RequestCredentialsErrorMessage;
1540
1543
  RequestCredentialsErrorMessage["Abort"] = "User aborted the session";
1541
1544
  RequestCredentialsErrorMessage["Timeout"] = "User session timeout";
1542
1545
  RequestCredentialsErrorMessage["StateMismatch"] = "State mismatch between requested session and back-channel result";
1546
+ RequestCredentialsErrorMessage["OnPresentationRequestFailed"] = "The onPresentationRequest hook threw an error or rejected";
1543
1547
  })(RequestCredentialsErrorMessage || (RequestCredentialsErrorMessage = {}));
1544
1548
 
1545
1549
  exports.AbortSessionErrorType = void 0;
@@ -1841,7 +1845,7 @@ const exchangeSessionResult = async ({challenge: challenge, responseCode: respon
1841
1845
  body: JSON.stringify(postData)
1842
1846
  });
1843
1847
  const responseResult = await withRetrySafeFetch(fetchResultFn, {
1844
- retries: 2,
1848
+ retries: 4,
1845
1849
  retryHttpStatus: 404
1846
1850
  });
1847
1851
  if (responseResult.isErr()) {
@@ -1890,71 +1894,111 @@ const closeCrossDeviceModal = options => {
1890
1894
  removeWindowMessageEventListener();
1891
1895
  };
1892
1896
 
1893
- const receiveMessageHandler = options => async event => {
1894
- const {onComplete: onComplete, onFailure: onFailure, container: container, sessionId: sessionId, apiBaseUrl: apiBaseUrl, challenge: challenge, state: state} = options;
1895
- if (event.origin !== apiBaseUrl) {
1896
- return;
1897
- }
1898
- if (event.data.type === MessageEventDataType.PresentationCompleted && event.data.responseCode && event.data.sessionId) {
1899
- const responseCode = event.data.responseCode;
1900
- const result = await exchangeSessionResult({
1901
- challenge: challenge,
1902
- responseCode: responseCode,
1903
- sessionId: sessionId,
1904
- apiBaseUrl: apiBaseUrl
1905
- });
1906
- if (result.isErr()) {
1897
+ const receiveMessageHandler = options => {
1898
+ let queue = Promise.resolve();
1899
+ const processEvent = async event => {
1900
+ const {onComplete: onComplete, onFailure: onFailure, container: container, sessionId: sessionId, sessionKey: sessionKey, apiBaseUrl: apiBaseUrl, challenge: challenge, state: state, onPresentationRequest: onPresentationRequest, isSettled: isSettled} = options;
1901
+ if (isSettled() || event.origin !== apiBaseUrl) {
1902
+ return;
1903
+ }
1904
+ if (event.data.type === MessageEventDataType.PresentationRequestUpdated && event.data.authRequestUri) {
1905
+ if (onPresentationRequest) {
1906
+ try {
1907
+ await onPresentationRequest({
1908
+ type: SessionType.Openid4vp,
1909
+ sessionId: sessionId,
1910
+ authRequestUri: event.data.authRequestUri
1911
+ });
1912
+ } catch (cause) {
1913
+ if (isSettled()) {
1914
+ return;
1915
+ }
1916
+ onFailure({
1917
+ type: exports.RequestCredentialsErrorType.OnPresentationRequestFailed,
1918
+ message: RequestCredentialsErrorMessage.OnPresentationRequestFailed,
1919
+ cause: cause
1920
+ });
1921
+ closeCrossDeviceModal({
1922
+ container: container
1923
+ });
1924
+ await abortSession({
1925
+ apiBaseUrl: apiBaseUrl,
1926
+ sessionId: sessionId,
1927
+ sessionKey: sessionKey
1928
+ });
1929
+ }
1930
+ }
1931
+ return;
1932
+ }
1933
+ if (event.data.type === MessageEventDataType.PresentationCompleted && event.data.responseCode && event.data.sessionId) {
1934
+ const responseCode = event.data.responseCode;
1935
+ const result = await exchangeSessionResult({
1936
+ challenge: challenge,
1937
+ responseCode: responseCode,
1938
+ sessionId: sessionId,
1939
+ apiBaseUrl: apiBaseUrl
1940
+ });
1941
+ if (isSettled()) {
1942
+ return;
1943
+ }
1944
+ if (result.isErr()) {
1945
+ onFailure({
1946
+ type: exports.RequestCredentialsErrorType.RequestCredentialsFailed,
1947
+ message: RequestCredentialsErrorMessage.FailedToGetSessionResult
1948
+ });
1949
+ closeCrossDeviceModal({
1950
+ container: container
1951
+ });
1952
+ return;
1953
+ }
1954
+ const resultState = "challenge" in result.value ? result.value.state : undefined;
1955
+ if (state !== undefined && resultState !== undefined && state !== resultState) {
1956
+ onFailure({
1957
+ type: exports.RequestCredentialsErrorType.RequestCredentialsFailed,
1958
+ message: RequestCredentialsErrorMessage.StateMismatch
1959
+ });
1960
+ closeCrossDeviceModal({
1961
+ container: container
1962
+ });
1963
+ return;
1964
+ }
1965
+ onComplete({
1966
+ result: "challenge" in result.value ? result.value : undefined,
1967
+ sessionId: result.value.sessionId,
1968
+ sessionCompletedInRedirect: false,
1969
+ state: resultState !== null && resultState !== void 0 ? resultState : state
1970
+ });
1971
+ closeCrossDeviceModal({
1972
+ container: container
1973
+ });
1974
+ return;
1975
+ }
1976
+ if (event.data.type === MessageEventDataType.PresentationTimeout) {
1907
1977
  onFailure({
1908
- type: exports.RequestCredentialsErrorType.RequestCredentialsFailed,
1909
- message: RequestCredentialsErrorMessage.FailedToGetSessionResult
1978
+ type: exports.RequestCredentialsErrorType.Timeout,
1979
+ message: RequestCredentialsErrorMessage.Timeout
1910
1980
  });
1911
1981
  closeCrossDeviceModal({
1912
1982
  container: container
1913
1983
  });
1914
1984
  return;
1915
1985
  }
1916
- const resultState = "challenge" in result.value ? result.value.state : undefined;
1917
- if (state !== undefined && resultState !== undefined && state !== resultState) {
1986
+ if (event.data.type === MessageEventDataType.PresentationAbort) {
1918
1987
  onFailure({
1919
- type: exports.RequestCredentialsErrorType.RequestCredentialsFailed,
1920
- message: RequestCredentialsErrorMessage.StateMismatch
1988
+ type: exports.RequestCredentialsErrorType.Abort,
1989
+ message: RequestCredentialsErrorMessage.Abort
1921
1990
  });
1922
1991
  closeCrossDeviceModal({
1923
1992
  container: container
1924
1993
  });
1925
1994
  return;
1926
1995
  }
1927
- onComplete({
1928
- result: "challenge" in result.value ? result.value : undefined,
1929
- sessionId: result.value.sessionId,
1930
- sessionCompletedInRedirect: false,
1931
- state: resultState !== null && resultState !== void 0 ? resultState : state
1932
- });
1933
- closeCrossDeviceModal({
1934
- container: container
1935
- });
1936
- return;
1937
- }
1938
- if (event.data.type === MessageEventDataType.PresentationTimeout) {
1939
- onFailure({
1940
- type: exports.RequestCredentialsErrorType.Timeout,
1941
- message: RequestCredentialsErrorMessage.Timeout
1942
- });
1943
- closeCrossDeviceModal({
1944
- container: container
1945
- });
1946
- return;
1947
- }
1948
- if (event.data.type === MessageEventDataType.PresentationAbort) {
1949
- onFailure({
1950
- type: exports.RequestCredentialsErrorType.Abort,
1951
- message: RequestCredentialsErrorMessage.Abort
1952
- });
1953
- closeCrossDeviceModal({
1954
- container: container
1955
- });
1956
- return;
1957
- }
1996
+ };
1997
+ return event => {
1998
+ const next = queue.then((() => processEvent(event)));
1999
+ queue = next.catch((() => undefined));
2000
+ return next;
2001
+ };
1958
2002
  };
1959
2003
 
1960
2004
  const openCrossDeviceModal = options => {
@@ -1974,16 +2018,18 @@ const openCrossDeviceModal = options => {
1974
2018
  };
1975
2019
 
1976
2020
  const requestCredentialsWithCrossDevice = async options => {
1977
- const {challenge: challenge, apiBaseUrl: apiBaseUrl, sessionUrl: sessionUrl, sessionId: sessionId, sessionKey: sessionKey, state: state} = options;
2021
+ const {challenge: challenge, apiBaseUrl: apiBaseUrl, sessionUrl: sessionUrl, sessionId: sessionId, sessionKey: sessionKey, state: state, onPresentationRequest: onPresentationRequest} = options;
1978
2022
  const container = openCrossDeviceModal({
1979
2023
  sessionUrl: sessionUrl
1980
2024
  });
2025
+ let settled = false;
1981
2026
  return await new Promise((resolve => {
1982
2027
  const abortController = setActiveSession({
1983
2028
  sessionId: sessionId,
1984
2029
  sessionKey: sessionKey
1985
2030
  });
1986
2031
  abortController.signal.addEventListener("abort", (() => {
2032
+ settled = true;
1987
2033
  closeCrossDeviceModal({
1988
2034
  container: container
1989
2035
  });
@@ -1996,11 +2042,20 @@ const requestCredentialsWithCrossDevice = async options => {
1996
2042
  listener = receiveMessageHandler({
1997
2043
  container: container,
1998
2044
  sessionId: sessionId,
2045
+ sessionKey: sessionKey,
1999
2046
  apiBaseUrl: apiBaseUrl,
2000
2047
  challenge: challenge,
2001
2048
  state: state,
2002
- onComplete: data => resolve(ok(data)),
2003
- onFailure: error => resolve(err(error))
2049
+ onPresentationRequest: onPresentationRequest,
2050
+ isSettled: () => settled,
2051
+ onComplete: data => {
2052
+ settled = true;
2053
+ resolve(ok(data));
2054
+ },
2055
+ onFailure: error => {
2056
+ settled = true;
2057
+ resolve(err(error));
2058
+ }
2004
2059
  });
2005
2060
  window.addEventListener(WindowEventListenerType.message, listener, false);
2006
2061
  }));
@@ -2248,7 +2303,7 @@ const requestCredentials = async options => {
2248
2303
  }
2249
2304
  assertType(RequestCredentialsOptionsValidator, "Invalid request credential options")(options);
2250
2305
  const {apiBaseUrl: apiBaseUrl, applicationId: applicationId} = initializeOptions;
2251
- const {challenge: challenge = generateChallenge(), credentialQuery: credentialQuery, openid4vpConfiguration: openid4vpConfiguration, state: state} = options;
2306
+ const {challenge: challenge = generateChallenge(), credentialQuery: credentialQuery, openid4vpConfiguration: openid4vpConfiguration, state: state, onPresentationRequest: onPresentationRequest} = options;
2252
2307
  const dcApiSupported = isDigitalCredentialsApiSupported();
2253
2308
  const openId4VpRedirectUri = deriveOpenId4vpRedirectUri(openid4vpConfiguration);
2254
2309
  const createSessionResult = await createSession({
@@ -2270,6 +2325,30 @@ const requestCredentials = async options => {
2270
2325
  }
2271
2326
  const session = createSessionResult.value;
2272
2327
  const {sessionKey: sessionKey, sessionId: sessionId} = session;
2328
+ if (onPresentationRequest) {
2329
+ const presentationRequest = session.type === SessionType.DigitalCredentialsApi ? {
2330
+ type: SessionType.DigitalCredentialsApi,
2331
+ sessionId: sessionId
2332
+ } : {
2333
+ type: SessionType.Openid4vp,
2334
+ sessionId: sessionId,
2335
+ authRequestUri: session.authRequestUri
2336
+ };
2337
+ try {
2338
+ await onPresentationRequest(presentationRequest);
2339
+ } catch (cause) {
2340
+ await abortSession({
2341
+ apiBaseUrl: apiBaseUrl,
2342
+ sessionId: sessionId,
2343
+ sessionKey: sessionKey
2344
+ });
2345
+ return err({
2346
+ type: exports.RequestCredentialsErrorType.OnPresentationRequestFailed,
2347
+ message: RequestCredentialsErrorMessage.OnPresentationRequestFailed,
2348
+ cause: cause
2349
+ });
2350
+ }
2351
+ }
2273
2352
  if (session.type === SessionType.DigitalCredentialsApi) {
2274
2353
  const {request: request, sessionTtl: sessionTtl} = session;
2275
2354
  return await requestCredentialsWithDigitalCredentialsApi({
@@ -2305,7 +2384,8 @@ const requestCredentials = async options => {
2305
2384
  sessionUrl: sessionUrl,
2306
2385
  sessionKey: sessionKey,
2307
2386
  sessionId: sessionId,
2308
- state: state
2387
+ state: state,
2388
+ onPresentationRequest: onPresentationRequest
2309
2389
  });
2310
2390
  };
2311
2391