@mattrglobal/verifier-sdk-web 1.0.2-unstable.99 → 2.0.0-preview-digital-credential-api.1
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/dist/lib/verifier-js-no-deps.cjs.js +157 -8
- package/dist/lib/verifier-js-no-deps.cjs.js.map +1 -1
- package/dist/lib/verifier-js.cjs.js +157 -8
- package/dist/lib/verifier-js.cjs.js.map +1 -1
- package/dist/typings/index.d.ts +1 -0
- package/dist/typings/verifier/requestCredentialsViaDigitalCredentialsApi.d.ts +7 -0
- package/dist/typings/verifier/types/credential-presentation.d.ts +8 -0
- package/dist/typings/verifier/types/verifier-web-sdk.d.ts +17 -1
- package/dist/typings/verifier/utils.d.ts +33 -1
- package/dist/verifier-js.development.js +150 -8
- package/dist/verifier-js.development.js.map +1 -1
- package/dist/verifier-js.production.esm.js +3 -3
- package/dist/verifier-js.production.esm.js.map +1 -1
- package/dist/verifier-js.production.js +3 -3
- package/dist/verifier-js.production.js.map +1 -1
- package/package.json +2 -2
package/dist/typings/index.d.ts
CHANGED
|
@@ -7,5 +7,6 @@ export type { InitialiseOptions, RequestCredentialsOptions, RequestCredentialsSa
|
|
|
7
7
|
declare const utils: {
|
|
8
8
|
generateChallenge: () => string;
|
|
9
9
|
unwrap: <T = unknown>(result: import("neverthrow").Result<T, unknown>, errMessage?: string) => T;
|
|
10
|
+
isDigitalCredentialsApiSupported: () => boolean;
|
|
10
11
|
};
|
|
11
12
|
export { initialise, requestCredentials, handleRedirectCallback, utils };
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { Result } from "neverthrow";
|
|
2
|
+
import { RequestCredentialsError, DigitalCredentialsApiRequestOptions, DigitalCredentialsApiRequestCredentialsResponse } from "./types";
|
|
3
|
+
export declare enum SameDeviceRequestCredentialsErrorMessage {
|
|
4
|
+
FailedToStoreChallenge = "Failed to store challenge",
|
|
5
|
+
FailedToCreateSession = "Failed to create session"
|
|
6
|
+
}
|
|
7
|
+
export declare const requestCredentialsDigitalCredentialsApi: (options: DigitalCredentialsApiRequestOptions) => Promise<Result<DigitalCredentialsApiRequestCredentialsResponse, RequestCredentialsError>>;
|
|
@@ -255,3 +255,11 @@ export declare const CreateSessionResponseValidator: v.ObjectSchema<{
|
|
|
255
255
|
readonly sessionUrl: v.StringSchema<undefined>;
|
|
256
256
|
}, undefined>;
|
|
257
257
|
/*** session end ***/
|
|
258
|
+
export type CreateDigitalCredentialsApiSessionResponse = {
|
|
259
|
+
sessionId: string;
|
|
260
|
+
request: any;
|
|
261
|
+
};
|
|
262
|
+
export declare const CreateDigitalCredentialsApiSessionResponseValidator: v.ObjectSchema<{
|
|
263
|
+
readonly sessionId: v.StringSchema<undefined>;
|
|
264
|
+
readonly request: v.ObjectSchema<{}, undefined>;
|
|
265
|
+
}, undefined>;
|
|
@@ -61,6 +61,11 @@ export type CrossDeviceRequestCredentialsOptions = {
|
|
|
61
61
|
mode: Mode.crossDevice;
|
|
62
62
|
initialiseOptions: InitialiseOptions;
|
|
63
63
|
};
|
|
64
|
+
export type DigitalCredentialsApiRequestOptions = {
|
|
65
|
+
credentialQuery: CredentialQuery[];
|
|
66
|
+
challenge: string;
|
|
67
|
+
initialiseOptions: InitialiseOptions;
|
|
68
|
+
};
|
|
64
69
|
/**
|
|
65
70
|
* Options for the same device requestCredentials function
|
|
66
71
|
*/
|
|
@@ -265,10 +270,17 @@ export type MessageEvent = {
|
|
|
265
270
|
export type CrossDeviceRequestCredentialsResponse = {
|
|
266
271
|
sessionId: string;
|
|
267
272
|
};
|
|
273
|
+
/**
|
|
274
|
+
* The response from the digital credentials api requestCredentials function
|
|
275
|
+
*/
|
|
276
|
+
export type DigitalCredentialsApiRequestCredentialsResponse = {
|
|
277
|
+
sessionId: string;
|
|
278
|
+
result: PresentationSessionResult;
|
|
279
|
+
};
|
|
268
280
|
/**
|
|
269
281
|
* The response from the requestCredentials function
|
|
270
282
|
*/
|
|
271
|
-
export type RequestCredentialsResponse = SameDeviceRequestCredentialsResponse | CrossDeviceRequestCredentialsResponse;
|
|
283
|
+
export type RequestCredentialsResponse = SameDeviceRequestCredentialsResponse | CrossDeviceRequestCredentialsResponse | DigitalCredentialsApiRequestCredentialsResponse;
|
|
272
284
|
/**
|
|
273
285
|
* The error type for the requestCredentials function
|
|
274
286
|
*/
|
|
@@ -296,7 +308,11 @@ export type HandleRedirectCallbackResponse = {
|
|
|
296
308
|
*/
|
|
297
309
|
export type InitialiseOptions = {
|
|
298
310
|
apiBaseUrl: string;
|
|
311
|
+
enableDigitalCredentialsApiSameDeviceFlow?: boolean;
|
|
312
|
+
enableDigitalCredentialsApiCrossDeviceFlow?: boolean;
|
|
299
313
|
};
|
|
300
314
|
export declare const InitialiseOptionsValidator: v.ObjectSchema<{
|
|
301
315
|
readonly apiBaseUrl: v.StringSchema<undefined>;
|
|
316
|
+
readonly enableDigitalCredentialsApiSameDeviceFlow: v.OptionalSchema<v.BooleanSchema<undefined>, never>;
|
|
317
|
+
readonly enableDigitalCredentialsApiCrossDeviceFlow: v.OptionalSchema<v.BooleanSchema<undefined>, never>;
|
|
302
318
|
}, undefined>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Result } from "neverthrow";
|
|
2
2
|
import { SafeFetchValidateRespondError } from "../common/safeFetch";
|
|
3
|
-
import { CreateSessionRequest, CreateSessionResponse, ExchangeSessionResultResponse } from "./types";
|
|
3
|
+
import { CreateSessionRequest, CreateSessionResponse, ExchangeSessionResultResponse, CreateDigitalCredentialsApiSessionResponse } from "./types";
|
|
4
4
|
/**
|
|
5
5
|
* Generates a challenge string using the window.crypto API.
|
|
6
6
|
*
|
|
@@ -50,3 +50,35 @@ export declare const exchangeSessionResult: ({ challenge, responseCode, sessionI
|
|
|
50
50
|
* @returns A boolean indicating whether the user agent is a mobile device.
|
|
51
51
|
*/
|
|
52
52
|
export declare const isMobileDetect: (userAgent: string) => boolean;
|
|
53
|
+
/**
|
|
54
|
+
* Detects if digital credentials api is available.
|
|
55
|
+
*
|
|
56
|
+
* @returns A boolean indicating whether the user agent supports the digital credential api.
|
|
57
|
+
*/
|
|
58
|
+
export declare const isDigitalCredentialsApiSupported: () => boolean;
|
|
59
|
+
/**
|
|
60
|
+
* Creates a new digital credentials api session with the provided parameters.
|
|
61
|
+
*
|
|
62
|
+
* @param credentialQuery - The credential query for the session.
|
|
63
|
+
* @param challenge - The challenge for the session.
|
|
64
|
+
* @param apiBaseUrl - The base URL of the API.
|
|
65
|
+
* @returns A promise that resolves to a result containing either the created session response or an error.
|
|
66
|
+
*/
|
|
67
|
+
export declare const createDigitalCredentialsApiSession: ({ credentialQuery, challenge, apiBaseUrl, }: CreateSessionRequest & {
|
|
68
|
+
apiBaseUrl: string;
|
|
69
|
+
}) => Promise<Result<CreateDigitalCredentialsApiSessionResponse, SafeFetchValidateRespondError>>;
|
|
70
|
+
/**
|
|
71
|
+
* Retrieves the result of a session using the provided parameters.
|
|
72
|
+
*
|
|
73
|
+
* @param challenge - The challenge for the session.
|
|
74
|
+
* @param sessionId - The ID of the session.
|
|
75
|
+
* @param response - The response from the digital credentials api.
|
|
76
|
+
* @param apiBaseUrl - The base URL of the API.
|
|
77
|
+
* @returns A promise that resolves to a result containing either the session result response or an error.
|
|
78
|
+
*/
|
|
79
|
+
export declare const getDigitalCredentialsApiSessionResult: ({ challenge, sessionId, response, apiBaseUrl, }: {
|
|
80
|
+
challenge: string;
|
|
81
|
+
sessionId: string;
|
|
82
|
+
response: any;
|
|
83
|
+
apiBaseUrl: string;
|
|
84
|
+
}) => Promise<Result<any, SafeFetchValidateRespondError>>;
|
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
* Do Not Translate or Localize
|
|
8
8
|
*
|
|
9
9
|
* Bundle of @mattrglobal/verifier-sdk-web
|
|
10
|
-
* Generated: 2024-10-
|
|
11
|
-
* Version:
|
|
10
|
+
* Generated: 2024-10-21
|
|
11
|
+
* Version: 2.0.0-preview-digital-credential-api.1
|
|
12
12
|
* Dependencies:
|
|
13
13
|
*
|
|
14
14
|
* neverthrow -- 4.3.0
|
|
@@ -1332,6 +1332,10 @@
|
|
|
1332
1332
|
sessionId: string(),
|
|
1333
1333
|
sessionUrl: string()
|
|
1334
1334
|
});
|
|
1335
|
+
const CreateDigitalCredentialsApiSessionResponseValidator = object({
|
|
1336
|
+
sessionId: string(),
|
|
1337
|
+
request: object({})
|
|
1338
|
+
});
|
|
1335
1339
|
var LocalStorageKey;
|
|
1336
1340
|
(function(LocalStorageKey) {
|
|
1337
1341
|
LocalStorageKey["challenge"] = "mattr_chg";
|
|
@@ -1382,7 +1386,9 @@
|
|
|
1382
1386
|
RequestCredentialsErrorType["RequestCredentialsFailed"] = "RequestCredentialsFailed";
|
|
1383
1387
|
})(exports.RequestCredentialsErrorType || (exports.RequestCredentialsErrorType = {}));
|
|
1384
1388
|
const InitialiseOptionsValidator = object({
|
|
1385
|
-
apiBaseUrl: string()
|
|
1389
|
+
apiBaseUrl: string(),
|
|
1390
|
+
enableDigitalCredentialsApiSameDeviceFlow: optional(_boolean()),
|
|
1391
|
+
enableDigitalCredentialsApiCrossDeviceFlow: optional(_boolean())
|
|
1386
1392
|
});
|
|
1387
1393
|
let initialiseOptions = undefined;
|
|
1388
1394
|
var InitialiseErrorMessage;
|
|
@@ -1506,6 +1512,61 @@
|
|
|
1506
1512
|
ua: userAgent,
|
|
1507
1513
|
tablet: false
|
|
1508
1514
|
});
|
|
1515
|
+
const isDigitalCredentialsApiSupported = () => {
|
|
1516
|
+
var _a;
|
|
1517
|
+
try {
|
|
1518
|
+
return typeof ((_a = navigator === null || navigator === void 0 ? void 0 : navigator.identity) === null || _a === void 0 ? void 0 : _a.get) === "function";
|
|
1519
|
+
} catch (error) {
|
|
1520
|
+
return false;
|
|
1521
|
+
}
|
|
1522
|
+
};
|
|
1523
|
+
const createDigitalCredentialsApiSession = async ({credentialQuery: credentialQuery, challenge: challenge, apiBaseUrl: apiBaseUrl}) => {
|
|
1524
|
+
const postData = {
|
|
1525
|
+
credentialQuery: credentialQuery,
|
|
1526
|
+
challenge: challenge
|
|
1527
|
+
};
|
|
1528
|
+
const responseResult = await safeFetch(`${apiBaseUrl}/v2/presentations/sessions/browserApi/request`, {
|
|
1529
|
+
method: "POST",
|
|
1530
|
+
headers: {
|
|
1531
|
+
"Content-Type": "application/json"
|
|
1532
|
+
},
|
|
1533
|
+
body: JSON.stringify(postData)
|
|
1534
|
+
});
|
|
1535
|
+
if (responseResult.isErr()) {
|
|
1536
|
+
return err(responseResult.error);
|
|
1537
|
+
}
|
|
1538
|
+
const data = await responseResult.value.json();
|
|
1539
|
+
if (!isType(CreateDigitalCredentialsApiSessionResponseValidator)(data)) {
|
|
1540
|
+
return err({
|
|
1541
|
+
type: SafeFetchCommonRespondErrorType.UnexpectedRespond,
|
|
1542
|
+
message: "Create digital credentials api session return unsupported response"
|
|
1543
|
+
});
|
|
1544
|
+
}
|
|
1545
|
+
return ok(data);
|
|
1546
|
+
};
|
|
1547
|
+
const getDigitalCredentialsApiSessionResult = async ({challenge: challenge, sessionId: sessionId, response: response, apiBaseUrl: apiBaseUrl}) => {
|
|
1548
|
+
const postData = {
|
|
1549
|
+
challenge: challenge,
|
|
1550
|
+
sessionId: sessionId,
|
|
1551
|
+
response: response
|
|
1552
|
+
};
|
|
1553
|
+
const fetchResultFn = async () => await safeFetch(`${apiBaseUrl}/v2/presentations/sessions/browserApi/response`, {
|
|
1554
|
+
method: "POST",
|
|
1555
|
+
headers: {
|
|
1556
|
+
"Content-Type": "application/json"
|
|
1557
|
+
},
|
|
1558
|
+
body: JSON.stringify(postData)
|
|
1559
|
+
});
|
|
1560
|
+
const responseResult = await withRetrySafeFetch(fetchResultFn, {
|
|
1561
|
+
retries: 2,
|
|
1562
|
+
retryHttpStatus: 404
|
|
1563
|
+
});
|
|
1564
|
+
if (responseResult.isErr()) {
|
|
1565
|
+
return err(responseResult.error);
|
|
1566
|
+
}
|
|
1567
|
+
const data = await responseResult.value.json();
|
|
1568
|
+
return ok(data);
|
|
1569
|
+
};
|
|
1509
1570
|
exports.CrossDeviceCallbackErrorType = void 0;
|
|
1510
1571
|
(function(CrossDeviceCallbackErrorType) {
|
|
1511
1572
|
CrossDeviceCallbackErrorType["Timeout"] = "Timeout";
|
|
@@ -1635,11 +1696,11 @@
|
|
|
1635
1696
|
sessionId: sessionId
|
|
1636
1697
|
});
|
|
1637
1698
|
};
|
|
1638
|
-
var SameDeviceRequestCredentialsErrorMessage;
|
|
1699
|
+
var SameDeviceRequestCredentialsErrorMessage$1;
|
|
1639
1700
|
(function(SameDeviceRequestCredentialsErrorMessage) {
|
|
1640
1701
|
SameDeviceRequestCredentialsErrorMessage["FailedToStoreChallenge"] = "Failed to store challenge";
|
|
1641
1702
|
SameDeviceRequestCredentialsErrorMessage["FailedToCreateSession"] = "Failed to create session";
|
|
1642
|
-
})(SameDeviceRequestCredentialsErrorMessage || (SameDeviceRequestCredentialsErrorMessage = {}));
|
|
1703
|
+
})(SameDeviceRequestCredentialsErrorMessage$1 || (SameDeviceRequestCredentialsErrorMessage$1 = {}));
|
|
1643
1704
|
const requestCredentialsSameDevice = async options => {
|
|
1644
1705
|
const {challenge: challenge, credentialQuery: credentialQuery, redirectUri: redirectUri, walletProviderId: walletProviderId, initialiseOptions: initialiseOptions} = options;
|
|
1645
1706
|
const {apiBaseUrl: apiBaseUrl} = initialiseOptions;
|
|
@@ -1648,7 +1709,7 @@
|
|
|
1648
1709
|
if (!storedChallenge) {
|
|
1649
1710
|
return err({
|
|
1650
1711
|
type: exports.RequestCredentialsErrorType.RequestCredentialsFailed,
|
|
1651
|
-
message: SameDeviceRequestCredentialsErrorMessage.FailedToStoreChallenge
|
|
1712
|
+
message: SameDeviceRequestCredentialsErrorMessage$1.FailedToStoreChallenge
|
|
1652
1713
|
});
|
|
1653
1714
|
}
|
|
1654
1715
|
const createSessionResult = await createSession({
|
|
@@ -1661,7 +1722,7 @@
|
|
|
1661
1722
|
if (createSessionResult.isErr()) {
|
|
1662
1723
|
return err({
|
|
1663
1724
|
type: exports.RequestCredentialsErrorType.RequestCredentialsFailed,
|
|
1664
|
-
message: SameDeviceRequestCredentialsErrorMessage.FailedToCreateSession,
|
|
1725
|
+
message: SameDeviceRequestCredentialsErrorMessage$1.FailedToCreateSession,
|
|
1665
1726
|
cause: createSessionResult.error
|
|
1666
1727
|
});
|
|
1667
1728
|
}
|
|
@@ -1672,6 +1733,68 @@
|
|
|
1672
1733
|
sessionId: sessionId
|
|
1673
1734
|
});
|
|
1674
1735
|
};
|
|
1736
|
+
var SameDeviceRequestCredentialsErrorMessage;
|
|
1737
|
+
(function(SameDeviceRequestCredentialsErrorMessage) {
|
|
1738
|
+
SameDeviceRequestCredentialsErrorMessage["FailedToStoreChallenge"] = "Failed to store challenge";
|
|
1739
|
+
SameDeviceRequestCredentialsErrorMessage["FailedToCreateSession"] = "Failed to create session";
|
|
1740
|
+
})(SameDeviceRequestCredentialsErrorMessage || (SameDeviceRequestCredentialsErrorMessage = {}));
|
|
1741
|
+
const requestCredentialsDigitalCredentialsApi = async options => {
|
|
1742
|
+
const {challenge: challenge, credentialQuery: credentialQuery, initialiseOptions: initialiseOptions} = options;
|
|
1743
|
+
const {apiBaseUrl: apiBaseUrl} = initialiseOptions;
|
|
1744
|
+
window.localStorage.setItem(LocalStorageKey.challenge, challenge);
|
|
1745
|
+
const storedChallenge = window.localStorage.getItem(LocalStorageKey.challenge);
|
|
1746
|
+
if (!storedChallenge) {
|
|
1747
|
+
return err({
|
|
1748
|
+
type: exports.RequestCredentialsErrorType.RequestCredentialsFailed,
|
|
1749
|
+
message: SameDeviceRequestCredentialsErrorMessage.FailedToStoreChallenge
|
|
1750
|
+
});
|
|
1751
|
+
}
|
|
1752
|
+
const createSessionResult = await createDigitalCredentialsApiSession({
|
|
1753
|
+
credentialQuery: credentialQuery,
|
|
1754
|
+
challenge: storedChallenge,
|
|
1755
|
+
apiBaseUrl: apiBaseUrl
|
|
1756
|
+
});
|
|
1757
|
+
if (createSessionResult.isErr()) {
|
|
1758
|
+
return err({
|
|
1759
|
+
type: exports.RequestCredentialsErrorType.RequestCredentialsFailed,
|
|
1760
|
+
message: SameDeviceRequestCredentialsErrorMessage.FailedToCreateSession,
|
|
1761
|
+
cause: createSessionResult.error
|
|
1762
|
+
});
|
|
1763
|
+
}
|
|
1764
|
+
const {request: request, sessionId: sessionId} = createSessionResult.value;
|
|
1765
|
+
window.localStorage.setItem(LocalStorageKey.sessionId, sessionId);
|
|
1766
|
+
let rawResponse;
|
|
1767
|
+
try {
|
|
1768
|
+
rawResponse = await navigator.identity.get(request);
|
|
1769
|
+
} catch (_a) {
|
|
1770
|
+
return err({
|
|
1771
|
+
type: exports.RequestCredentialsErrorType.RequestCredentialsFailed,
|
|
1772
|
+
message: "Failed call to digital credentials api"
|
|
1773
|
+
});
|
|
1774
|
+
}
|
|
1775
|
+
let response;
|
|
1776
|
+
try {
|
|
1777
|
+
response = JSON.parse(rawResponse.data);
|
|
1778
|
+
} catch (_b) {
|
|
1779
|
+
response = rawResponse.data;
|
|
1780
|
+
}
|
|
1781
|
+
const result = await getDigitalCredentialsApiSessionResult({
|
|
1782
|
+
challenge: challenge,
|
|
1783
|
+
sessionId: sessionId,
|
|
1784
|
+
response: response,
|
|
1785
|
+
apiBaseUrl: apiBaseUrl
|
|
1786
|
+
});
|
|
1787
|
+
if (result.isOk()) {
|
|
1788
|
+
return ok({
|
|
1789
|
+
sessionId: sessionId,
|
|
1790
|
+
result: result.value
|
|
1791
|
+
});
|
|
1792
|
+
}
|
|
1793
|
+
return err({
|
|
1794
|
+
type: exports.RequestCredentialsErrorType.RequestCredentialsFailed,
|
|
1795
|
+
message: "Invalid response from digital credentials api"
|
|
1796
|
+
});
|
|
1797
|
+
};
|
|
1675
1798
|
const requestCredentials = async options => {
|
|
1676
1799
|
var _a;
|
|
1677
1800
|
const initialiseOptions = getInitialiseOptions();
|
|
@@ -1681,6 +1804,24 @@
|
|
|
1681
1804
|
assertType(RequestCredentialsOptionsValidator, "Invalid request credential options")(options);
|
|
1682
1805
|
const {challenge: challenge = generateChallenge()} = options;
|
|
1683
1806
|
const mode = (_a = options.mode) !== null && _a !== void 0 ? _a : isMobileDetect(navigator.userAgent) ? exports.Mode.sameDevice : exports.Mode.crossDevice;
|
|
1807
|
+
if (initialiseOptions.enableDigitalCredentialsApiCrossDeviceFlow && isDigitalCredentialsApiSupported() && mode === exports.Mode.crossDevice) {
|
|
1808
|
+
console.log("Digital Credentials API support found, proceeding with request using API in cross device flow");
|
|
1809
|
+
return await requestCredentialsDigitalCredentialsApi(Object.assign(Object.assign({}, options), {
|
|
1810
|
+
initialiseOptions: initialiseOptions,
|
|
1811
|
+
challenge: challenge
|
|
1812
|
+
}));
|
|
1813
|
+
} else if (initialiseOptions.enableDigitalCredentialsApiCrossDeviceFlow) {
|
|
1814
|
+
console.log("Digital Credentials API support not found, falling back to OpenID4VP");
|
|
1815
|
+
}
|
|
1816
|
+
if (initialiseOptions.enableDigitalCredentialsApiSameDeviceFlow && isDigitalCredentialsApiSupported() && mode === exports.Mode.sameDevice) {
|
|
1817
|
+
console.log("Digital Credentials API support found, proceeding with request using API in same device flow");
|
|
1818
|
+
return await requestCredentialsDigitalCredentialsApi(Object.assign(Object.assign({}, options), {
|
|
1819
|
+
initialiseOptions: initialiseOptions,
|
|
1820
|
+
challenge: challenge
|
|
1821
|
+
}));
|
|
1822
|
+
} else if (initialiseOptions.enableDigitalCredentialsApiSameDeviceFlow) {
|
|
1823
|
+
console.log("Digital Credentials API support not found, falling back to OpenID4VP");
|
|
1824
|
+
}
|
|
1684
1825
|
if (mode === exports.Mode.sameDevice && "redirectUri" in options) {
|
|
1685
1826
|
return await requestCredentialsSameDevice(Object.assign(Object.assign({}, options), {
|
|
1686
1827
|
initialiseOptions: initialiseOptions,
|
|
@@ -1757,7 +1898,8 @@
|
|
|
1757
1898
|
};
|
|
1758
1899
|
const utils = {
|
|
1759
1900
|
generateChallenge: generateChallenge,
|
|
1760
|
-
unwrap: unwrap
|
|
1901
|
+
unwrap: unwrap,
|
|
1902
|
+
isDigitalCredentialsApiSupported: isDigitalCredentialsApiSupported
|
|
1761
1903
|
};
|
|
1762
1904
|
exports.handleRedirectCallback = handleRedirectCallback;
|
|
1763
1905
|
exports.initialise = initialise;
|