@metamask-previews/kyc-controller 0.0.0-preview-8bfa290fb → 0.2.0-preview-0a30e47
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 +30 -49
- package/dist/{KycController-method-action-types.d.mts → KycController-method-action-types.d.ts} +35 -7
- package/dist/KycController-method-action-types.d.ts.map +1 -0
- package/dist/{KycController-method-action-types.mjs → KycController-method-action-types.js} +1 -1
- package/dist/KycController-method-action-types.js.map +1 -0
- package/dist/{KycController.d.mts → KycController.d.ts} +87 -45
- package/dist/KycController.d.ts.map +1 -0
- package/dist/KycController.js +1991 -0
- package/dist/KycController.js.map +1 -0
- package/dist/{KycService-method-action-types.d.mts → KycService-method-action-types.d.ts} +16 -16
- package/dist/KycService-method-action-types.d.ts.map +1 -0
- package/dist/{KycService-method-action-types.mjs → KycService-method-action-types.js} +1 -1
- package/dist/KycService-method-action-types.js.map +1 -0
- package/dist/{KycService.d.mts → KycService.d.ts} +23 -23
- package/dist/KycService.d.ts.map +1 -0
- package/dist/{KycService.mjs → KycService.js} +194 -185
- package/dist/KycService.js.map +1 -0
- package/dist/{countryCodes.d.cts → countryCodes.d.ts} +1 -1
- package/dist/countryCodes.d.ts.map +1 -0
- package/dist/{countryCodes.mjs → countryCodes.js} +1 -1
- package/dist/countryCodes.js.map +1 -0
- package/dist/{crypto.d.mts → crypto.d.ts} +1 -1
- package/dist/crypto.d.ts.map +1 -0
- package/dist/{crypto.mjs → crypto.js} +7 -7
- package/dist/crypto.js.map +1 -0
- package/dist/{encoding.d.mts → encoding.d.ts} +1 -1
- package/dist/encoding.d.ts.map +1 -0
- package/dist/{encoding.mjs → encoding.js} +2 -2
- package/dist/encoding.js.map +1 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -0
- package/dist/{logger.d.cts → logger.d.ts} +2 -3
- package/dist/logger.d.ts.map +1 -0
- package/dist/{logger.mjs → logger.js} +2 -2
- package/dist/logger.js.map +1 -0
- package/dist/{selectors.d.mts → selectors.d.ts} +4 -4
- package/dist/selectors.d.ts.map +1 -0
- package/dist/{selectors.mjs → selectors.js} +2 -2
- package/dist/selectors.js.map +1 -0
- package/dist/{types.d.cts → types.d.ts} +72 -13
- package/dist/types.d.ts.map +1 -0
- package/dist/{types.mjs → types.js} +1 -1
- package/dist/types.js.map +1 -0
- package/dist/ukyc/{constants.d.mts → constants.d.ts} +9 -9
- package/dist/ukyc/constants.d.ts.map +1 -0
- package/dist/ukyc/{constants.mjs → constants.js} +1 -1
- package/dist/ukyc/constants.js.map +1 -0
- package/dist/ukyc/{deriveClientMaterial.d.cts → deriveClientMaterial.d.ts} +1 -1
- package/dist/ukyc/deriveClientMaterial.d.ts.map +1 -0
- package/dist/ukyc/{deriveClientMaterial.mjs → deriveClientMaterial.js} +7 -7
- package/dist/ukyc/deriveClientMaterial.js.map +1 -0
- package/dist/ukyc/{jwtChain.d.mts → jwtChain.d.ts} +1 -1
- package/dist/ukyc/jwtChain.d.ts.map +1 -0
- package/dist/ukyc/{jwtChain.mjs → jwtChain.js} +4 -4
- package/dist/ukyc/jwtChain.js.map +1 -0
- package/dist/ukyc/{localUserSecret.d.mts → localUserSecret.d.ts} +1 -1
- package/dist/ukyc/localUserSecret.d.ts.map +1 -0
- package/dist/ukyc/{localUserSecret.mjs → localUserSecret.js} +4 -4
- package/dist/ukyc/localUserSecret.js.map +1 -0
- package/dist/ukyc/{storageAccessToken.d.mts → storageAccessToken.d.ts} +2 -2
- package/dist/ukyc/storageAccessToken.d.ts.map +1 -0
- package/dist/ukyc/{storageAccessToken.mjs → storageAccessToken.js} +5 -5
- package/dist/ukyc/storageAccessToken.js.map +1 -0
- package/dist/ukyc/{testToken.d.mts → testToken.d.ts} +2 -2
- package/dist/ukyc/testToken.d.ts.map +1 -0
- package/dist/ukyc/{testToken.mjs → testToken.js} +5 -5
- package/dist/ukyc/testToken.js.map +1 -0
- package/dist/ukyc/{wrapEncryptionKey.d.mts → wrapEncryptionKey.d.ts} +1 -1
- package/dist/ukyc/wrapEncryptionKey.d.ts.map +1 -0
- package/dist/ukyc/{wrapEncryptionKey.mjs → wrapEncryptionKey.js} +3 -4
- package/dist/ukyc/wrapEncryptionKey.js.map +1 -0
- package/dist/ukyc/{wrappedRelayPayload.d.mts → wrappedRelayPayload.d.ts} +3 -3
- package/dist/ukyc/wrappedRelayPayload.d.ts.map +1 -0
- package/dist/ukyc/{wrappedRelayPayload.mjs → wrappedRelayPayload.js} +2 -2
- package/dist/ukyc/wrappedRelayPayload.js.map +1 -0
- package/dist/vendorDisclaimerAcceptance.d.ts +39 -0
- package/dist/vendorDisclaimerAcceptance.d.ts.map +1 -0
- package/dist/vendorDisclaimerAcceptance.js +67 -0
- package/dist/vendorDisclaimerAcceptance.js.map +1 -0
- package/dist/vendors/MoonPayFrameHandler.d.ts +74 -0
- package/dist/vendors/MoonPayFrameHandler.d.ts.map +1 -0
- package/dist/vendors/MoonPayFrameHandler.js +218 -0
- package/dist/vendors/MoonPayFrameHandler.js.map +1 -0
- package/package.json +19 -23
- package/dist/KycController-method-action-types.cjs +0 -7
- package/dist/KycController-method-action-types.cjs.map +0 -1
- package/dist/KycController-method-action-types.d.cts +0 -239
- package/dist/KycController-method-action-types.d.cts.map +0 -1
- package/dist/KycController-method-action-types.d.mts.map +0 -1
- package/dist/KycController-method-action-types.mjs.map +0 -1
- package/dist/KycController.cjs +0 -1882
- package/dist/KycController.cjs.map +0 -1
- package/dist/KycController.d.cts +0 -395
- package/dist/KycController.d.cts.map +0 -1
- package/dist/KycController.d.mts.map +0 -1
- package/dist/KycController.mjs +0 -1877
- package/dist/KycController.mjs.map +0 -1
- package/dist/KycService-method-action-types.cjs +0 -7
- package/dist/KycService-method-action-types.cjs.map +0 -1
- package/dist/KycService-method-action-types.d.cts +0 -220
- package/dist/KycService-method-action-types.d.cts.map +0 -1
- package/dist/KycService-method-action-types.d.mts.map +0 -1
- package/dist/KycService-method-action-types.mjs.map +0 -1
- package/dist/KycService.cjs +0 -637
- package/dist/KycService.cjs.map +0 -1
- package/dist/KycService.d.cts +0 -552
- package/dist/KycService.d.cts.map +0 -1
- package/dist/KycService.d.mts.map +0 -1
- package/dist/KycService.mjs.map +0 -1
- package/dist/countryCodes.cjs +0 -274
- package/dist/countryCodes.cjs.map +0 -1
- package/dist/countryCodes.d.cts.map +0 -1
- package/dist/countryCodes.d.mts +0 -18
- package/dist/countryCodes.d.mts.map +0 -1
- package/dist/countryCodes.mjs.map +0 -1
- package/dist/crypto.cjs +0 -154
- package/dist/crypto.cjs.map +0 -1
- package/dist/crypto.d.cts +0 -84
- package/dist/crypto.d.cts.map +0 -1
- package/dist/crypto.d.mts.map +0 -1
- package/dist/crypto.mjs.map +0 -1
- package/dist/encoding.cjs +0 -40
- package/dist/encoding.cjs.map +0 -1
- package/dist/encoding.d.cts +0 -24
- package/dist/encoding.d.cts.map +0 -1
- package/dist/encoding.d.mts.map +0 -1
- package/dist/encoding.mjs.map +0 -1
- package/dist/index.cjs +0 -37
- package/dist/index.cjs.map +0 -1
- package/dist/index.d.cts +0 -19
- package/dist/index.d.cts.map +0 -1
- package/dist/index.d.mts +0 -19
- package/dist/index.d.mts.map +0 -1
- package/dist/index.mjs +0 -12
- package/dist/index.mjs.map +0 -1
- package/dist/logger.cjs +0 -9
- package/dist/logger.cjs.map +0 -1
- package/dist/logger.d.cts.map +0 -1
- package/dist/logger.d.mts +0 -6
- package/dist/logger.d.mts.map +0 -1
- package/dist/logger.mjs.map +0 -1
- package/dist/selectors.cjs +0 -30
- package/dist/selectors.cjs.map +0 -1
- package/dist/selectors.d.cts +0 -24
- package/dist/selectors.d.cts.map +0 -1
- package/dist/selectors.d.mts.map +0 -1
- package/dist/selectors.mjs.map +0 -1
- package/dist/types.cjs +0 -10
- package/dist/types.cjs.map +0 -1
- package/dist/types.d.cts.map +0 -1
- package/dist/types.d.mts +0 -217
- package/dist/types.d.mts.map +0 -1
- package/dist/types.mjs.map +0 -1
- package/dist/ukyc/constants.cjs +0 -75
- package/dist/ukyc/constants.cjs.map +0 -1
- package/dist/ukyc/constants.d.cts +0 -69
- package/dist/ukyc/constants.d.cts.map +0 -1
- package/dist/ukyc/constants.d.mts.map +0 -1
- package/dist/ukyc/constants.mjs.map +0 -1
- package/dist/ukyc/deriveClientMaterial.cjs +0 -65
- package/dist/ukyc/deriveClientMaterial.cjs.map +0 -1
- package/dist/ukyc/deriveClientMaterial.d.cts.map +0 -1
- package/dist/ukyc/deriveClientMaterial.d.mts +0 -54
- package/dist/ukyc/deriveClientMaterial.d.mts.map +0 -1
- package/dist/ukyc/deriveClientMaterial.mjs.map +0 -1
- package/dist/ukyc/jwtChain.cjs +0 -54
- package/dist/ukyc/jwtChain.cjs.map +0 -1
- package/dist/ukyc/jwtChain.d.cts +0 -40
- package/dist/ukyc/jwtChain.d.cts.map +0 -1
- package/dist/ukyc/jwtChain.d.mts.map +0 -1
- package/dist/ukyc/jwtChain.mjs.map +0 -1
- package/dist/ukyc/localUserSecret.cjs +0 -98
- package/dist/ukyc/localUserSecret.cjs.map +0 -1
- package/dist/ukyc/localUserSecret.d.cts +0 -65
- package/dist/ukyc/localUserSecret.d.cts.map +0 -1
- package/dist/ukyc/localUserSecret.d.mts.map +0 -1
- package/dist/ukyc/localUserSecret.mjs.map +0 -1
- package/dist/ukyc/storageAccessToken.cjs +0 -139
- package/dist/ukyc/storageAccessToken.cjs.map +0 -1
- package/dist/ukyc/storageAccessToken.d.cts +0 -99
- package/dist/ukyc/storageAccessToken.d.cts.map +0 -1
- package/dist/ukyc/storageAccessToken.d.mts.map +0 -1
- package/dist/ukyc/storageAccessToken.mjs.map +0 -1
- package/dist/ukyc/testToken.cjs +0 -61
- package/dist/ukyc/testToken.cjs.map +0 -1
- package/dist/ukyc/testToken.d.cts +0 -50
- package/dist/ukyc/testToken.d.cts.map +0 -1
- package/dist/ukyc/testToken.d.mts.map +0 -1
- package/dist/ukyc/testToken.mjs.map +0 -1
- package/dist/ukyc/wrapEncryptionKey.cjs +0 -31
- package/dist/ukyc/wrapEncryptionKey.cjs.map +0 -1
- package/dist/ukyc/wrapEncryptionKey.d.cts +0 -36
- package/dist/ukyc/wrapEncryptionKey.d.cts.map +0 -1
- package/dist/ukyc/wrapEncryptionKey.d.mts.map +0 -1
- package/dist/ukyc/wrapEncryptionKey.mjs.map +0 -1
- package/dist/ukyc/wrappedRelayPayload.cjs +0 -32
- package/dist/ukyc/wrappedRelayPayload.cjs.map +0 -1
- package/dist/ukyc/wrappedRelayPayload.d.cts +0 -35
- package/dist/ukyc/wrappedRelayPayload.d.cts.map +0 -1
- package/dist/ukyc/wrappedRelayPayload.d.mts.map +0 -1
- package/dist/ukyc/wrappedRelayPayload.mjs.map +0 -1
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* Fully-qualified key path for the `local_user_secret` in Encrypted User
|
|
7
7
|
* Storage.
|
|
8
8
|
*/
|
|
9
|
-
export declare const UKYC_LOCAL_USER_SECRET_PATH:
|
|
9
|
+
export declare const UKYC_LOCAL_USER_SECRET_PATH: `ukyc.local_user_secret`;
|
|
10
10
|
/**
|
|
11
11
|
* Size of the `local_user_secret` in bytes. 32 bytes (256 bits) provides high
|
|
12
12
|
* entropy and matches the input length expected by the HKDF-SHA256 derivations
|
|
@@ -30,10 +30,10 @@ export declare const UKYC_DERIVED_KEY_SIZES: {
|
|
|
30
30
|
* from `local_user_secret`.
|
|
31
31
|
*/
|
|
32
32
|
export declare const UKYC_KDF_INFO: {
|
|
33
|
-
readonly storageId:
|
|
34
|
-
readonly dataEncryptionKey:
|
|
35
|
-
readonly signingKey:
|
|
36
|
-
readonly relayTunnelKey:
|
|
33
|
+
readonly storageId: 'metamask.ukyc.storage.v1.storage_id';
|
|
34
|
+
readonly dataEncryptionKey: 'metamask.ukyc.storage.v1.data_encryption_key';
|
|
35
|
+
readonly signingKey: 'metamask.ukyc.storage.v1.signing_key';
|
|
36
|
+
readonly relayTunnelKey: 'metamask.ukyc.storage.v1.relay_tunnel_key';
|
|
37
37
|
};
|
|
38
38
|
/**
|
|
39
39
|
* Version bound into every `storage_access_token` payload.
|
|
@@ -43,12 +43,12 @@ export declare const UKYC_STORAGE_ACCESS_TOKEN_VERSION = 1;
|
|
|
43
43
|
* Audience identifying the UKYC user-storage service. Required by UKYC Storage
|
|
44
44
|
* when it verifies a `storage_access_token`.
|
|
45
45
|
*/
|
|
46
|
-
export declare const UKYC_STORAGE_ACCESS_TOKEN_AUDIENCE:
|
|
46
|
+
export declare const UKYC_STORAGE_ACCESS_TOKEN_AUDIENCE: 'metamask:user-storage:ukyc';
|
|
47
47
|
/**
|
|
48
48
|
* Audience identifying the idOS Kwil credential-registry nodes. Required by
|
|
49
49
|
* idOS Kwil when it verifies a `storage_access_token`.
|
|
50
50
|
*/
|
|
51
|
-
export declare const UKYC_KWIL_AUDIENCE:
|
|
51
|
+
export declare const UKYC_KWIL_AUDIENCE: 'idos:kwil';
|
|
52
52
|
/**
|
|
53
53
|
* Full audience list bound into every `storage_access_token` payload. `aud`
|
|
54
54
|
* lists every verifier that may accept the token, so both UKYC Storage and
|
|
@@ -60,10 +60,10 @@ export declare const UKYC_STORAGE_ACCESS_TOKEN_AUDIENCES: readonly ["metamask:us
|
|
|
60
60
|
* carried to UKYC Storage: `Authorization: AccessToken <base64url(envelope)>`.
|
|
61
61
|
* The credentials portion is what `encodeStorageAccessTokenForHeader` returns.
|
|
62
62
|
*/
|
|
63
|
-
export declare const UKYC_CAPABILITY_AUTH_SCHEME:
|
|
63
|
+
export declare const UKYC_CAPABILITY_AUTH_SCHEME: 'AccessToken';
|
|
64
64
|
/**
|
|
65
65
|
* Standard well-known path where the idOS enclave and the idOS relay publish their JWKS
|
|
66
66
|
* (the Ed25519 public keys used to sign encryption-schema `jwtChain`s).
|
|
67
67
|
*/
|
|
68
68
|
export declare const UKYC_JWKS_PATH = "/.well-known/jwks.json";
|
|
69
|
-
//# sourceMappingURL=constants.d.
|
|
69
|
+
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/ukyc/constants.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;GAGG;AACH,eAAO,MAAM,2BAA2B,EAAG,wBAAiC,CAAC;AAE7E;;;;GAIG;AACH,eAAO,MAAM,iCAAiC,KAAK,CAAC;AAEpD;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB;aACjC,SAAS,EAAE,EAAE;aACb,iBAAiB,EAAE,EAAE;aACrB,UAAU,EAAE,EAAE;aACd,cAAc,EAAE,EAAE;CACV,CAAC;AAEX;;;GAGG;AACH,eAAO,MAAM,aAAa;aACxB,SAAS,EAAE,qCAAqC;aAChD,iBAAiB,EAAE,8CAA8C;aACjE,UAAU,EAAE,sCAAsC;aAClD,cAAc,EAAE,2CAA2C;CACnD,CAAC;AAEX;;GAEG;AACH,eAAO,MAAM,iCAAiC,IAAI,CAAC;AAEnD;;;GAGG;AACH,eAAO,MAAM,kCAAkC,EAC7C,4BAAqC,CAAC;AAExC;;;GAGG;AACH,eAAO,MAAM,kBAAkB,EAAG,WAAoB,CAAC;AAEvD;;;;GAIG;AACH,eAAO,MAAM,mCAAmC,sDAGtC,CAAC;AAEX;;;;GAIG;AACH,eAAO,MAAM,2BAA2B,EAAG,aAAsB,CAAC;AAElE;;;GAGG;AACH,eAAO,MAAM,cAAc,2BAA2B,CAAC"}
|
|
@@ -69,4 +69,4 @@ export const UKYC_CAPABILITY_AUTH_SCHEME = 'AccessToken';
|
|
|
69
69
|
* (the Ed25519 public keys used to sign encryption-schema `jwtChain`s).
|
|
70
70
|
*/
|
|
71
71
|
export const UKYC_JWKS_PATH = '/.well-known/jwks.json';
|
|
72
|
-
//# sourceMappingURL=constants.
|
|
72
|
+
//# sourceMappingURL=constants.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/ukyc/constants.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;GAGG;AACH,MAAM,CAAC,MAAM,2BAA2B,GAAG,wBAAiC,CAAC;AAE7E;;;;GAIG;AACH,MAAM,CAAC,MAAM,iCAAiC,GAAG,EAAE,CAAC;AAEpD;;;;;GAKG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG;IACpC,SAAS,EAAE,EAAE;IACb,iBAAiB,EAAE,EAAE;IACrB,UAAU,EAAE,EAAE;IACd,cAAc,EAAE,EAAE;CACV,CAAC;AAEX;;;GAGG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B,SAAS,EAAE,qCAAqC;IAChD,iBAAiB,EAAE,8CAA8C;IACjE,UAAU,EAAE,sCAAsC;IAClD,cAAc,EAAE,2CAA2C;CACnD,CAAC;AAEX;;GAEG;AACH,MAAM,CAAC,MAAM,iCAAiC,GAAG,CAAC,CAAC;AAEnD;;;GAGG;AACH,MAAM,CAAC,MAAM,kCAAkC,GAC7C,4BAAqC,CAAC;AAExC;;;GAGG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,WAAoB,CAAC;AAEvD;;;;GAIG;AACH,MAAM,CAAC,MAAM,mCAAmC,GAAG;IACjD,kCAAkC;IAClC,kBAAkB;CACV,CAAC;AAEX;;;;GAIG;AACH,MAAM,CAAC,MAAM,2BAA2B,GAAG,aAAsB,CAAC;AAElE;;;GAGG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,wBAAwB,CAAC","sourcesContent":["/**\n * Constants for the UKYC client-derived key material and storage-authorization\n * layer. See the architecture doc, section \"Client-Derived Material\".\n */\n\n/**\n * Fully-qualified key path for the `local_user_secret` in Encrypted User\n * Storage.\n */\nexport const UKYC_LOCAL_USER_SECRET_PATH = `ukyc.local_user_secret` as const;\n\n/**\n * Size of the `local_user_secret` in bytes. 32 bytes (256 bits) provides high\n * entropy and matches the input length expected by the HKDF-SHA256 derivations\n * below.\n */\nexport const UKYC_LOCAL_USER_SECRET_SIZE_BYTES = 32;\n\n/**\n * Byte length of each value derived from `local_user_secret`.\n *\n * `signingKey` is 32 bytes because it is used directly as the Ed25519\n * private key (for Ed25519 the 32-byte seed *is* the private key).\n */\nexport const UKYC_DERIVED_KEY_SIZES = {\n storageId: 32,\n dataEncryptionKey: 32,\n signingKey: 32,\n relayTunnelKey: 32,\n} as const;\n\n/**\n * HKDF `info` labels providing domain separation between the values derived\n * from `local_user_secret`.\n */\nexport const UKYC_KDF_INFO = {\n storageId: 'metamask.ukyc.storage.v1.storage_id',\n dataEncryptionKey: 'metamask.ukyc.storage.v1.data_encryption_key',\n signingKey: 'metamask.ukyc.storage.v1.signing_key',\n relayTunnelKey: 'metamask.ukyc.storage.v1.relay_tunnel_key',\n} as const;\n\n/**\n * Version bound into every `storage_access_token` payload.\n */\nexport const UKYC_STORAGE_ACCESS_TOKEN_VERSION = 1;\n\n/**\n * Audience identifying the UKYC user-storage service. Required by UKYC Storage\n * when it verifies a `storage_access_token`.\n */\nexport const UKYC_STORAGE_ACCESS_TOKEN_AUDIENCE =\n 'metamask:user-storage:ukyc' as const;\n\n/**\n * Audience identifying the idOS Kwil credential-registry nodes. Required by\n * idOS Kwil when it verifies a `storage_access_token`.\n */\nexport const UKYC_KWIL_AUDIENCE = 'idos:kwil' as const;\n\n/**\n * Full audience list bound into every `storage_access_token` payload. `aud`\n * lists every verifier that may accept the token, so both UKYC Storage and\n * idOS Kwil can each find their own entry.\n */\nexport const UKYC_STORAGE_ACCESS_TOKEN_AUDIENCES = [\n UKYC_STORAGE_ACCESS_TOKEN_AUDIENCE,\n UKYC_KWIL_AUDIENCE,\n] as const;\n\n/**\n * Authorization scheme under which a signed `storage_access_token` envelope is\n * carried to UKYC Storage: `Authorization: AccessToken <base64url(envelope)>`.\n * The credentials portion is what `encodeStorageAccessTokenForHeader` returns.\n */\nexport const UKYC_CAPABILITY_AUTH_SCHEME = 'AccessToken' as const;\n\n/**\n * Standard well-known path where the idOS enclave and the idOS relay publish their JWKS\n * (the Ed25519 public keys used to sign encryption-schema `jwtChain`s).\n */\nexport const UKYC_JWKS_PATH = '/.well-known/jwks.json';\n"]}
|
|
@@ -51,4 +51,4 @@ export declare function deriveClientMaterial(localUserSecret: Uint8Array): UkycC
|
|
|
51
51
|
* @returns The base64url-encoded, non-secret fields.
|
|
52
52
|
*/
|
|
53
53
|
export declare function encodeClientMaterial(material: UkycClientMaterial): EncodedUkycClientMaterial;
|
|
54
|
-
//# sourceMappingURL=deriveClientMaterial.d.
|
|
54
|
+
//# sourceMappingURL=deriveClientMaterial.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deriveClientMaterial.d.ts","sourceRoot":"","sources":["../../src/ukyc/deriveClientMaterial.ts"],"names":[],"mappings":"AAQA;;;;GAIG;AAEH;;GAEG;AACH,MAAM,MAAM,kBAAkB,GAAG;IAC/B,sDAAsD;IACtD,SAAS,EAAE,UAAU,CAAC;IACtB,iFAAiF;IACjF,iBAAiB,EAAE,UAAU,CAAC;IAC9B;;;;OAIG;IACH,UAAU,EAAE,UAAU,CAAC;IACvB,8EAA8E;IAC9E,gBAAgB,EAAE,UAAU,CAAC;IAC7B,mFAAmF;IACnF,cAAc,EAAE,UAAU,CAAC;CAC5B,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,yBAAyB,GAAG;IACtC,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB,EAAE,MAAM,CAAC;CAC1B,CAAC;AAsBF;;;;;;;;;;GAUG;AACH,wBAAgB,oBAAoB,CAClC,eAAe,EAAE,UAAU,GAC1B,kBAAkB,CAkCpB;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,kBAAkB,GAC3B,yBAAyB,CAK3B"}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { stringToBytes } from
|
|
2
|
-
import { ed25519 } from
|
|
3
|
-
import { hkdf } from
|
|
4
|
-
import { sha256 } from
|
|
5
|
-
import { toBase64Url } from
|
|
6
|
-
import { UKYC_DERIVED_KEY_SIZES, UKYC_KDF_INFO } from
|
|
1
|
+
import { stringToBytes } from '@metamask/utils';
|
|
2
|
+
import { ed25519 } from '@noble/curves/ed25519';
|
|
3
|
+
import { hkdf } from '@noble/hashes/hkdf';
|
|
4
|
+
import { sha256 } from '@noble/hashes/sha2';
|
|
5
|
+
import { toBase64Url } from '../encoding.js';
|
|
6
|
+
import { UKYC_DERIVED_KEY_SIZES, UKYC_KDF_INFO } from './constants.js';
|
|
7
7
|
/**
|
|
8
8
|
* Derives a single labeled value from `local_user_secret`.
|
|
9
9
|
*
|
|
@@ -57,4 +57,4 @@ export function encodeClientMaterial(material) {
|
|
|
57
57
|
signingPublicKey: toBase64Url(material.signingPublicKey),
|
|
58
58
|
};
|
|
59
59
|
}
|
|
60
|
-
//# sourceMappingURL=deriveClientMaterial.
|
|
60
|
+
//# sourceMappingURL=deriveClientMaterial.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deriveClientMaterial.js","sourceRoot":"","sources":["../../src/ukyc/deriveClientMaterial.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAChD,OAAO,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAC1C,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAE5C,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,EAAE,sBAAsB,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAsCvE;;;;;;;;;;;GAWG;AACH,SAAS,aAAa,CACpB,eAA2B,EAC3B,IAAY,EACZ,MAAc;IAEd,OAAO,IAAI,CAAC,MAAM,EAAE,eAAe,EAAE,SAAS,EAAE,aAAa,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,CAAC;AAC/E,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,oBAAoB,CAClC,eAA2B;IAE3B,MAAM,SAAS,GAAG,aAAa,CAC7B,eAAe,EACf,aAAa,CAAC,SAAS,EACvB,sBAAsB,CAAC,SAAS,CACjC,CAAC;IAEF,MAAM,iBAAiB,GAAG,aAAa,CACrC,eAAe,EACf,aAAa,CAAC,iBAAiB,EAC/B,sBAAsB,CAAC,iBAAiB,CACzC,CAAC;IAEF,MAAM,UAAU,GAAG,aAAa,CAC9B,eAAe,EACf,aAAa,CAAC,UAAU,EACxB,sBAAsB,CAAC,UAAU,CAClC,CAAC;IAEF,MAAM,cAAc,GAAG,aAAa,CAClC,eAAe,EACf,aAAa,CAAC,cAAc,EAC5B,sBAAsB,CAAC,cAAc,CACtC,CAAC;IAEF,MAAM,gBAAgB,GAAG,OAAO,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC;IAE1D,OAAO;QACL,SAAS;QACT,iBAAiB;QACjB,UAAU;QACV,gBAAgB;QAChB,cAAc;KACf,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,oBAAoB,CAClC,QAA4B;IAE5B,OAAO;QACL,SAAS,EAAE,WAAW,CAAC,QAAQ,CAAC,SAAS,CAAC;QAC1C,gBAAgB,EAAE,WAAW,CAAC,QAAQ,CAAC,gBAAgB,CAAC;KACzD,CAAC;AACJ,CAAC","sourcesContent":["import { stringToBytes } from '@metamask/utils';\nimport { ed25519 } from '@noble/curves/ed25519';\nimport { hkdf } from '@noble/hashes/hkdf';\nimport { sha256 } from '@noble/hashes/sha2';\n\nimport { toBase64Url } from '../encoding.js';\nimport { UKYC_DERIVED_KEY_SIZES, UKYC_KDF_INFO } from './constants.js';\n\n/**\n * Derives UKYC client material from the root `local_user_secret` using\n * HKDF-SHA256 with domain-separated `info` labels — see the architecture doc,\n * section \"Client-Derived Material\".\n */\n\n/**\n * The set of values derived from `local_user_secret`.\n */\nexport type UkycClientMaterial = {\n /** Opaque lookup key for the encrypted KYC object. */\n storageId: Uint8Array;\n /** Symmetric key that encrypts `encrypted_kyc_data` (or wraps per-blob keys). */\n dataEncryptionKey: Uint8Array;\n /**\n * Ed25519 private key used to sign `storage_access_token` capabilities. For\n * Ed25519 the 32-byte HKDF output *is* the private key. The private half\n * never leaves the device.\n */\n signingKey: Uint8Array;\n /** Public half of `signingKey`, registered with the object on first write. */\n signingPublicKey: Uint8Array;\n /** Key for establishing/authenticating the encrypted tunnel to idOS, if needed. */\n relayTunnelKey: Uint8Array;\n};\n\n/**\n * The same material with byte fields base64url-encoded, matching the wire\n * shapes in the architecture doc (`storage_id` as an opaque id, public key as a\n * \"base64url public key\"). Secret material is intentionally omitted.\n */\nexport type EncodedUkycClientMaterial = {\n storageId: string;\n signingPublicKey: string;\n};\n\n/**\n * Derives a single labeled value from `local_user_secret`.\n *\n * No salt is used: `local_user_secret` is already a high-entropy\n * uniformly-random secret, so per-output domain separation comes entirely from\n * the `info` label.\n *\n * @param localUserSecret - The root `local_user_secret` bytes.\n * @param info - Domain-separation label for this output.\n * @param length - Desired output length in bytes.\n * @returns The derived bytes.\n */\nfunction deriveLabeled(\n localUserSecret: Uint8Array,\n info: string,\n length: number,\n): Uint8Array {\n return hkdf(sha256, localUserSecret, undefined, stringToBytes(info), length);\n}\n\n/**\n * Derives all UKYC client material from the root `local_user_secret`.\n *\n * This is a pure function of `local_user_secret`: the same input always yields\n * the same outputs, which is what makes `storage_id` and `signing_key` stable\n * across sessions and devices.\n *\n * @param localUserSecret - The `local_user_secret` produced by\n * `getOrCreateLocalUserSecret`.\n * @returns The derived {@link UkycClientMaterial}.\n */\nexport function deriveClientMaterial(\n localUserSecret: Uint8Array,\n): UkycClientMaterial {\n const storageId = deriveLabeled(\n localUserSecret,\n UKYC_KDF_INFO.storageId,\n UKYC_DERIVED_KEY_SIZES.storageId,\n );\n\n const dataEncryptionKey = deriveLabeled(\n localUserSecret,\n UKYC_KDF_INFO.dataEncryptionKey,\n UKYC_DERIVED_KEY_SIZES.dataEncryptionKey,\n );\n\n const signingKey = deriveLabeled(\n localUserSecret,\n UKYC_KDF_INFO.signingKey,\n UKYC_DERIVED_KEY_SIZES.signingKey,\n );\n\n const relayTunnelKey = deriveLabeled(\n localUserSecret,\n UKYC_KDF_INFO.relayTunnelKey,\n UKYC_DERIVED_KEY_SIZES.relayTunnelKey,\n );\n\n const signingPublicKey = ed25519.getPublicKey(signingKey);\n\n return {\n storageId,\n dataEncryptionKey,\n signingKey,\n signingPublicKey,\n relayTunnelKey,\n };\n}\n\n/**\n * Encodes the non-secret client material into the base64url wire shapes used by\n * the UKYC storage API (`storage_id` and `signing_public_key`).\n *\n * @param material - The derived client material.\n * @returns The base64url-encoded, non-secret fields.\n */\nexport function encodeClientMaterial(\n material: UkycClientMaterial,\n): EncodedUkycClientMaterial {\n return {\n storageId: toBase64Url(material.storageId),\n signingPublicKey: toBase64Url(material.signingPublicKey),\n };\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jwtChain.d.ts","sourceRoot":"","sources":["../../src/ukyc/jwtChain.ts"],"names":[],"mappings":"AAKA;;;;;;;;GAQG;AAEH;;GAEG;AACH,MAAM,MAAM,GAAG,GAAG;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,CAAC,EAAE,MAAM,CAAC;IACV,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,eAAe,GAAG;IAC5B,uBAAuB,EAAE,MAAM,CAAC;IAChC,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AA2BF;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE,QAAQ,EAAE,MAAM,GAAG,eAAe,CAyC7E"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { bytesToString } from
|
|
2
|
-
import { ed25519 } from
|
|
3
|
-
import { base64UrlToBytes } from
|
|
1
|
+
import { bytesToString } from '@metamask/utils';
|
|
2
|
+
import { ed25519 } from '@noble/curves/ed25519';
|
|
3
|
+
import { base64UrlToBytes } from '../encoding.js';
|
|
4
4
|
/**
|
|
5
5
|
* Decodes a base64url JWT segment into a parsed JSON object.
|
|
6
6
|
*
|
|
@@ -47,4 +47,4 @@ export function verifyJwtChain(keys, jwtChain) {
|
|
|
47
47
|
}
|
|
48
48
|
return decodeJsonSegment(payloadSegment, 'payload');
|
|
49
49
|
}
|
|
50
|
-
//# sourceMappingURL=jwtChain.
|
|
50
|
+
//# sourceMappingURL=jwtChain.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jwtChain.js","sourceRoot":"","sources":["../../src/ukyc/jwtChain.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAEhD,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AA0ClD;;;;;;GAMG;AACH,SAAS,iBAAiB,CAAO,OAAe,EAAE,KAAa;IAC7D,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAS,CAAC;IACtE,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CACb,mCAAmC,KAAK,KAAK,MAAM,CAAC,KAAK,CAAC,EAAE,CAC7D,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,cAAc,CAAC,IAAW,EAAE,QAAgB;IAC1D,MAAM,CAAC,aAAa,EAAE,cAAc,EAAE,gBAAgB,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC9E,IAAI,CAAC,aAAa,IAAI,CAAC,cAAc,IAAI,CAAC,gBAAgB,EAAE,CAAC;QAC3D,MAAM,IAAI,KAAK,CACb,gEAAgE,CACjE,CAAC;IACJ,CAAC;IAED,MAAM,MAAM,GAAG,iBAAiB,CAAY,aAAa,EAAE,QAAQ,CAAC,CAAC;IACrE,IAAI,MAAM,CAAC,GAAG,KAAK,OAAO,EAAE,CAAC;QAC3B,MAAM,IAAI,KAAK,CACb,mCAAmC,MAAM,CACvC,MAAM,CAAC,GAAG,CACX,qBAAqB,CACvB,CAAC;IACJ,CAAC;IAED,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,GAAG,KAAK,MAAM,CAAC,GAAG,CAAC,CAAC;IACvD,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,MAAM,IAAI,KAAK,CACb,2CAA2C,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAClE,CAAC;IACJ,CAAC;IACD,IAAI,GAAG,CAAC,GAAG,KAAK,KAAK,IAAI,GAAG,CAAC,GAAG,KAAK,SAAS,EAAE,CAAC;QAC/C,MAAM,IAAI,KAAK,CACb,kBAAkB,GAAG,CAAC,GAAG,mCAAmC,GAAG,CAAC,GAAG,SAAS,GAAG,CAAC,GAAG,IAAI,CACxF,CAAC;IACJ,CAAC;IAED,MAAM,OAAO,GAAG,OAAO,CAAC,MAAM,CAC5B,gBAAgB,CAAC,gBAAgB,CAAC,EAClC,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,GAAG,aAAa,IAAI,cAAc,EAAE,CAAC,EAC9D,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC,CACxB,CAAC;IACF,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CACb,4DAA4D,CAC7D,CAAC;IACJ,CAAC;IAED,OAAO,iBAAiB,CAAkB,cAAc,EAAE,SAAS,CAAC,CAAC;AACvE,CAAC","sourcesContent":["import { bytesToString } from '@metamask/utils';\nimport { ed25519 } from '@noble/curves/ed25519';\n\nimport { base64UrlToBytes } from '../encoding.js';\n\n/**\n * Verifies an encryption-schema `jwtChain` against the issuer's published JWKS\n * (idOS enclave for `encryptionDataKey`, idOS relay for `ukycCapabilityToken`).\n *\n * The signature check is done with `@noble/curves` (rather than WebCrypto\n * `subtle`) because not every MetaMask runtime exposes a `subtle`\n * implementation for Ed25519; JWT parsing is a plain base64url/JSON decode, so\n * no `jose` dependency is required.\n */\n\n/**\n * A single Ed25519 (OKP) JSON Web Key from an issuer JWKS.\n */\nexport type Jwk = {\n kty: string;\n crv: string;\n x: string;\n kid: string;\n use?: string;\n alg?: string;\n};\n\n/**\n * The verified `jwtChain` payload. `sessionServerPublicKeyX` attests the\n * server's X25519 public key so the client can confirm the value returned\n * out-of-band in an encryption schema was not tampered with.\n */\nexport type JwtChainPayload = {\n sessionServerPublicKeyX: string;\n nonce: string;\n};\n\n/**\n * The protected header of a compact JWT.\n */\ntype JwtHeader = {\n alg?: string;\n kid?: string;\n};\n\n/**\n * Decodes a base64url JWT segment into a parsed JSON object.\n *\n * @param segment - The base64url-encoded segment.\n * @param label - Human-readable segment name for error messages.\n * @returns The parsed JSON object.\n */\nfunction decodeJsonSegment<Type>(segment: string, label: string): Type {\n try {\n return JSON.parse(bytesToString(base64UrlToBytes(segment))) as Type;\n } catch (error) {\n throw new Error(\n `UKYC: failed to decode jwtChain ${label}: ${String(error)}`,\n );\n }\n}\n\n/**\n * Verifies `jwtChain` against `keys`: matches the JWT header `kid` to a\n * published Ed25519 signing key and checks the EdDSA signature over the\n * `header.payload` input. Returns the decoded, verified payload.\n *\n * @param keys - The issuer JWKS keys used to verify the chain.\n * @param jwtChain - The compact-serialized EdDSA JWT from an encryption schema.\n * @returns The verified JWT payload.\n */\nexport function verifyJwtChain(keys: Jwk[], jwtChain: string): JwtChainPayload {\n const [headerSegment, payloadSegment, signatureSegment] = jwtChain.split('.');\n if (!headerSegment || !payloadSegment || !signatureSegment) {\n throw new Error(\n 'UKYC: jwtChain is not a well-formed JWT (expected 3 segments).',\n );\n }\n\n const header = decodeJsonSegment<JwtHeader>(headerSegment, 'header');\n if (header.alg !== 'EdDSA') {\n throw new Error(\n `UKYC: unsupported jwtChain alg \"${String(\n header.alg,\n )}\" (expected EdDSA).`,\n );\n }\n\n const jwk = keys.find((key) => key.kid === header.kid);\n if (!jwk) {\n throw new Error(\n `UKYC: no JWKS key matches jwtChain kid \"${String(header.kid)}\".`,\n );\n }\n if (jwk.kty !== 'OKP' || jwk.crv !== 'Ed25519') {\n throw new Error(\n `UKYC: JWKS key ${jwk.kid} is not an Ed25519 OKP key (kty=${jwk.kty}, crv=${jwk.crv}).`,\n );\n }\n\n const isValid = ed25519.verify(\n base64UrlToBytes(signatureSegment),\n new TextEncoder().encode(`${headerSegment}.${payloadSegment}`),\n base64UrlToBytes(jwk.x),\n );\n if (!isValid) {\n throw new Error(\n 'UKYC: jwtChain signature verification failed against JWKS.',\n );\n }\n\n return decodeJsonSegment<JwtChainPayload>(payloadSegment, 'payload');\n}\n"]}
|
|
@@ -62,4 +62,4 @@ export declare function getOrCreateLocalUserSecret(store: UkycLocalUserSecretSto
|
|
|
62
62
|
* @returns `true` if a `local_user_secret` exists in Encrypted User Storage.
|
|
63
63
|
*/
|
|
64
64
|
export declare function hasLocalUserSecret(store: UkycLocalUserSecretStore, entropySourceId?: string): Promise<boolean>;
|
|
65
|
-
//# sourceMappingURL=localUserSecret.d.
|
|
65
|
+
//# sourceMappingURL=localUserSecret.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"localUserSecret.d.ts","sourceRoot":"","sources":["../../src/ukyc/localUserSecret.ts"],"names":[],"mappings":"AAQA;;;;;;;;;;;;;GAaG;AAEH;;;;GAIG;AACH,MAAM,MAAM,wBAAwB,GAAG;IACrC;;OAEG;IACH,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,eAAe,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IACxE;;OAEG;IACH,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,eAAe,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/E,CAAC;AASF;;;;;;;;;GASG;AACH,wBAAsB,mBAAmB,CACvC,KAAK,EAAE,wBAAwB,EAC/B,eAAe,CAAC,EAAE,MAAM,GACvB,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAgB5B;AAqBD;;;;;;;;;;;;;GAaG;AACH,wBAAsB,0BAA0B,CAC9C,KAAK,EAAE,wBAAwB,EAC/B,eAAe,CAAC,EAAE,MAAM,GACvB,OAAO,CAAC,UAAU,CAAC,CAgCrB;AAED;;;;;;;GAOG;AACH,wBAAsB,kBAAkB,CACtC,KAAK,EAAE,wBAAwB,EAC/B,eAAe,CAAC,EAAE,MAAM,GACvB,OAAO,CAAC,OAAO,CAAC,CAElB"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { base64ToBytes, bytesToBase64 } from
|
|
2
|
-
import { randomBytes } from
|
|
3
|
-
import { UKYC_LOCAL_USER_SECRET_PATH, UKYC_LOCAL_USER_SECRET_SIZE_BYTES } from
|
|
1
|
+
import { base64ToBytes, bytesToBase64 } from '@metamask/utils';
|
|
2
|
+
import { randomBytes } from '@noble/hashes/utils';
|
|
3
|
+
import { UKYC_LOCAL_USER_SECRET_PATH, UKYC_LOCAL_USER_SECRET_SIZE_BYTES, } from './constants.js';
|
|
4
4
|
/**
|
|
5
5
|
* In-flight `getOrCreateLocalUserSecret` calls, keyed by entropy source.
|
|
6
6
|
* Deduplicates concurrent enrollments in a single client session so we never
|
|
@@ -89,4 +89,4 @@ export async function getOrCreateLocalUserSecret(store, entropySourceId) {
|
|
|
89
89
|
export async function hasLocalUserSecret(store, entropySourceId) {
|
|
90
90
|
return (await loadLocalUserSecret(store, entropySourceId)) !== null;
|
|
91
91
|
}
|
|
92
|
-
//# sourceMappingURL=localUserSecret.
|
|
92
|
+
//# sourceMappingURL=localUserSecret.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"localUserSecret.js","sourceRoot":"","sources":["../../src/ukyc/localUserSecret.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAC/D,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAElD,OAAO,EACL,2BAA2B,EAC3B,iCAAiC,GAClC,MAAM,gBAAgB,CAAC;AAiCxB;;;;GAIG;AACH,MAAM,iBAAiB,GAAG,IAAI,GAAG,EAA+B,CAAC;AAEjE;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,KAA+B,EAC/B,eAAwB;IAExB,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,2BAA2B,EAAE,eAAe,CAAC,CAAC;IAE7E,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,eAAe,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;IAE9C,IAAI,eAAe,CAAC,MAAM,KAAK,iCAAiC,EAAE,CAAC;QACjE,MAAM,IAAI,KAAK,CACb,wDAAwD,eAAe,CAAC,MAAM,cAAc,iCAAiC,GAAG,CACjI,CAAC;IACJ,CAAC;IAED,OAAO,eAAe,CAAC;AACzB,CAAC;AAED;;;;;;GAMG;AACH,KAAK,UAAU,sBAAsB,CACnC,KAA+B,EAC/B,eAA2B,EAC3B,eAAwB;IAExB,MAAM,KAAK,CAAC,GAAG,CACb,2BAA2B,EAC3B,aAAa,CAAC,eAAe,CAAC,EAC9B,eAAe,CAChB,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,KAAK,UAAU,0BAA0B,CAC9C,KAA+B,EAC/B,eAAwB;IAExB,MAAM,QAAQ,GAAG,eAAe,IAAI,EAAE,CAAC;IAEvC,MAAM,OAAO,GAAG,iBAAiB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAChD,IAAI,OAAO,EAAE,CAAC;QACZ,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,MAAM,QAAQ,GAAG,CAAC,KAAK,IAAyB,EAAE;QAChD,MAAM,QAAQ,GAAG,MAAM,mBAAmB,CAAC,KAAK,EAAE,eAAe,CAAC,CAAC;QACnE,IAAI,QAAQ,EAAE,CAAC;YACb,OAAO,QAAQ,CAAC;QAClB,CAAC;QAED,MAAM,eAAe,GAAG,WAAW,CAAC,iCAAiC,CAAC,CAAC;QACvE,MAAM,sBAAsB,CAAC,KAAK,EAAE,eAAe,EAAE,eAAe,CAAC,CAAC;QAEtE,0EAA0E;QAC1E,yEAAyE;QACzE,yEAAyE;QACzE,OAAO,CACL,CAAC,MAAM,mBAAmB,CAAC,KAAK,EAAE,eAAe,CAAC,CAAC,IAAI,eAAe,CACvE,CAAC;IACJ,CAAC,CAAC,EAAE,CAAC;IAEL,iBAAiB,CAAC,GAAG,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IAE1C,IAAI,CAAC;QACH,OAAO,MAAM,QAAQ,CAAC;IACxB,CAAC;YAAS,CAAC;QACT,iBAAiB,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IACrC,CAAC;AACH,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,KAA+B,EAC/B,eAAwB;IAExB,OAAO,CAAC,MAAM,mBAAmB,CAAC,KAAK,EAAE,eAAe,CAAC,CAAC,KAAK,IAAI,CAAC;AACtE,CAAC","sourcesContent":["import { base64ToBytes, bytesToBase64 } from '@metamask/utils';\nimport { randomBytes } from '@noble/hashes/utils';\n\nimport {\n UKYC_LOCAL_USER_SECRET_PATH,\n UKYC_LOCAL_USER_SECRET_SIZE_BYTES,\n} from './constants.js';\n\n/**\n * Orchestrates creation and loading of the UKYC `local_user_secret`.\n *\n * The `local_user_secret` is the root secret for all UKYC client-derived\n * material. It is generated once, on first enrollment, and persisted to\n * MetaMask Encrypted User Storage. It is never transmitted off the device, not\n * even to the idOS Relay. Every subsequent value (`storage_id`,\n * `data_encryption_key`, `signing_key`, `relay_tunnel_key`) is derived from it\n * via HKDF — see `deriveClientMaterial`.\n *\n * This module is platform-agnostic: the Encrypted User Storage backing is\n * injected as a {@link UkycLocalUserSecretStore} so the controller (which owns\n * the messenger) supplies the concrete `UserStorageController` calls.\n */\n\n/**\n * The Encrypted User Storage operations this module needs. On MetaMask clients\n * these are backed by `UserStorageController:performGetStorage` /\n * `performSetStorage`.\n */\nexport type UkycLocalUserSecretStore = {\n /**\n * Reads the base64 string stored at `path`, or `null` if none exists.\n */\n get: (path: string, entropySourceId?: string) => Promise<string | null>;\n /**\n * Writes the base64 string `value` at `path`.\n */\n set: (path: string, value: string, entropySourceId?: string) => Promise<void>;\n};\n\n/**\n * In-flight `getOrCreateLocalUserSecret` calls, keyed by entropy source.\n * Deduplicates concurrent enrollments in a single client session so we never\n * generate and persist two competing `local_user_secret`s for the same source.\n */\nconst inFlightCreations = new Map<string, Promise<Uint8Array>>();\n\n/**\n * Loads the persisted `local_user_secret` from Encrypted User Storage, if one\n * exists.\n *\n * @param store - The Encrypted User Storage adapter.\n * @param entropySourceId - Optional HD keyring entropy source id, used to scope\n * the secret to a specific SRP in multi-SRP wallets. Defaults to the primary SRP.\n * @returns The decoded `local_user_secret` bytes, or `null` if none has been\n * enrolled.\n */\nexport async function loadLocalUserSecret(\n store: UkycLocalUserSecretStore,\n entropySourceId?: string,\n): Promise<Uint8Array | null> {\n const stored = await store.get(UKYC_LOCAL_USER_SECRET_PATH, entropySourceId);\n\n if (!stored) {\n return null;\n }\n\n const localUserSecret = base64ToBytes(stored);\n\n if (localUserSecret.length !== UKYC_LOCAL_USER_SECRET_SIZE_BYTES) {\n throw new Error(\n `UKYC: stored local_user_secret has unexpected length ${localUserSecret.length}, expected ${UKYC_LOCAL_USER_SECRET_SIZE_BYTES}.`,\n );\n }\n\n return localUserSecret;\n}\n\n/**\n * Persists a freshly generated `local_user_secret` to Encrypted User Storage.\n *\n * @param store - The Encrypted User Storage adapter.\n * @param localUserSecret - The `local_user_secret` bytes to persist.\n * @param entropySourceId - Optional HD keyring entropy source id.\n */\nasync function persistLocalUserSecret(\n store: UkycLocalUserSecretStore,\n localUserSecret: Uint8Array,\n entropySourceId?: string,\n): Promise<void> {\n await store.set(\n UKYC_LOCAL_USER_SECRET_PATH,\n bytesToBase64(localUserSecret),\n entropySourceId,\n );\n}\n\n/**\n * Creates the UKYC `local_user_secret` if it does not already exist, otherwise\n * loads the existing one. This is the single entry point used on UKYC\n * enrollment.\n *\n * The operation is idempotent and safe against concurrent callers in the same\n * session: repeated or parallel calls resolve to the same `local_user_secret`\n * and never generate more than one secret for a given entropy source.\n *\n * @param store - The Encrypted User Storage adapter.\n * @param entropySourceId - Optional HD keyring entropy source id, used to scope\n * the secret to a specific SRP in multi-SRP wallets. Defaults to the primary SRP.\n * @returns The `local_user_secret` bytes (existing or newly created).\n */\nexport async function getOrCreateLocalUserSecret(\n store: UkycLocalUserSecretStore,\n entropySourceId?: string,\n): Promise<Uint8Array> {\n const cacheKey = entropySourceId ?? '';\n\n const pending = inFlightCreations.get(cacheKey);\n if (pending) {\n return pending;\n }\n\n const creation = (async (): Promise<Uint8Array> => {\n const existing = await loadLocalUserSecret(store, entropySourceId);\n if (existing) {\n return existing;\n }\n\n const localUserSecret = randomBytes(UKYC_LOCAL_USER_SECRET_SIZE_BYTES);\n await persistLocalUserSecret(store, localUserSecret, entropySourceId);\n\n // Re-read after persisting so that all callers converge on whatever value\n // actually landed in storage (defends against a competing write that may\n // have won the race, e.g. from another device syncing the same feature).\n return (\n (await loadLocalUserSecret(store, entropySourceId)) ?? localUserSecret\n );\n })();\n\n inFlightCreations.set(cacheKey, creation);\n\n try {\n return await creation;\n } finally {\n inFlightCreations.delete(cacheKey);\n }\n}\n\n/**\n * Whether a `local_user_secret` has already been enrolled for the given entropy\n * source.\n *\n * @param store - The Encrypted User Storage adapter.\n * @param entropySourceId - Optional HD keyring entropy source id.\n * @returns `true` if a `local_user_secret` exists in Encrypted User Storage.\n */\nexport async function hasLocalUserSecret(\n store: UkycLocalUserSecretStore,\n entropySourceId?: string,\n): Promise<boolean> {\n return (await loadLocalUserSecret(store, entropySourceId)) !== null;\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { UkycClientMaterial } from
|
|
1
|
+
import type { UkycClientMaterial } from './deriveClientMaterial.js';
|
|
2
2
|
/**
|
|
3
3
|
* Mints `storage_access_token` capabilities — the client-signed, scoped,
|
|
4
4
|
* session-bound proofs that authorize UKYC storage operations. See the
|
|
@@ -96,4 +96,4 @@ export declare function signStorageAccessToken(params: SignStorageAccessTokenPar
|
|
|
96
96
|
*/
|
|
97
97
|
export declare function encodeStorageAccessTokenForHeader(token: UkycStorageAccessToken): string;
|
|
98
98
|
export {};
|
|
99
|
-
//# sourceMappingURL=storageAccessToken.d.
|
|
99
|
+
//# sourceMappingURL=storageAccessToken.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storageAccessToken.d.ts","sourceRoot":"","sources":["../../src/ukyc/storageAccessToken.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAEpE;;;;;;;;;GASG;AAEH;;GAEG;AACH,MAAM,MAAM,oBAAoB,GAAG,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAC;AAE/D;;;GAGG;AACH,MAAM,MAAM,kBAAkB,GAAG,QAAQ,GAAG,YAAY,CAAC;AAEzD;;;GAGG;AACH,MAAM,MAAM,6BAA6B,GAAG;IAC1C,OAAO,EAAE,MAAM,CAAC;IAChB,iFAAiF;IACjF,GAAG,EAAE,MAAM,EAAE,CAAC;IAId,UAAU,EAAE,MAAM,CAAC;IACnB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,UAAU,EAAE,oBAAoB,EAAE,CAAC;IACnC,SAAS,EAAE,kBAAkB,CAAC;IAC9B,mFAAmF;IACnF,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CAEpB,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,sBAAsB,GAAG;IACnC,OAAO,EAAE,6BAA6B,CAAC;IACvC,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,4BAA4B,GAAG;IACzC,wDAAwD;IACxD,QAAQ,EAAE,kBAAkB,CAAC;IAC7B,4EAA4E;IAC5E,UAAU,EAAE,oBAAoB,EAAE,CAAC;IACnC,wDAAwD;IACxD,SAAS,CAAC,EAAE,kBAAkB,CAAC;IAC/B,gEAAgE;IAChE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,yCAAyC;IACzC,QAAQ,CAAC,EAAE,IAAI,CAAC;IAChB,uDAAuD;IACvD,SAAS,EAAE,IAAI,CAAC;CACjB,CAAC;AAEF,KAAK,SAAS,GACV,IAAI,GACJ,OAAO,GACP,MAAM,GACN,MAAM,GACN,SAAS,EAAE,GACX;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,CAAA;CAAE,CAAC;AAE7C;;;;;;;;;;;;;GAaG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,SAAS,GAAG,MAAM,CAqCzD;AAeD;;;;;GAKG;AACH,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,4BAA4B,GACnC,sBAAsB,CAwDxB;AAED;;;;;;;;GAQG;AACH,wBAAgB,iCAAiC,CAC/C,KAAK,EAAE,sBAAsB,GAC5B,MAAM,CAER"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { stringToBytes } from
|
|
2
|
-
import { ed25519 } from
|
|
3
|
-
import { toBase64Url } from
|
|
4
|
-
import { UKYC_STORAGE_ACCESS_TOKEN_AUDIENCES, UKYC_STORAGE_ACCESS_TOKEN_VERSION } from
|
|
1
|
+
import { stringToBytes } from '@metamask/utils';
|
|
2
|
+
import { ed25519 } from '@noble/curves/ed25519';
|
|
3
|
+
import { toBase64Url } from '../encoding.js';
|
|
4
|
+
import { UKYC_STORAGE_ACCESS_TOKEN_AUDIENCES, UKYC_STORAGE_ACCESS_TOKEN_VERSION, } from './constants.js';
|
|
5
5
|
/**
|
|
6
6
|
* Serializes a JSON value to RFC 8785 (JCS) canonical form.
|
|
7
7
|
*
|
|
@@ -130,4 +130,4 @@ function assertValidOperations(operations) {
|
|
|
130
130
|
throw new Error('UKYC: a delete-scoped storage_access_token must contain only "delete".');
|
|
131
131
|
}
|
|
132
132
|
}
|
|
133
|
-
//# sourceMappingURL=storageAccessToken.
|
|
133
|
+
//# sourceMappingURL=storageAccessToken.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storageAccessToken.js","sourceRoot":"","sources":["../../src/ukyc/storageAccessToken.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAEhD,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,EACL,mCAAmC,EACnC,iCAAiC,GAClC,MAAM,gBAAgB,CAAC;AAkFxB;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAAgB;IAC/C,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;QACnB,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,IAAI,OAAO,KAAK,KAAK,SAAS,EAAE,CAAC;QAC/B,OAAO,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC;IAClC,CAAC;IAED,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC;YAC7B,MAAM,IAAI,KAAK,CACb,yDAAyD,CAC1D,CAAC;QACJ,CAAC;QACD,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IAC/B,CAAC;IAED,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IAC/B,CAAC;IAED,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,IAAI,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;IACtE,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC;SAC/B,IAAI,EAAE;SACN,MAAM,CAAW,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;QAC7B,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC;QACzB,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,GAAG,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,gBAAgB,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAChE,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC,EAAE,EAAE,CAAC,CAAC;IAET,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;AAClC,CAAC;AAED;;;;;;;;GAQG;AACH,SAAS,gBAAgB,CAAC,IAAU;IAClC,OAAO,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC;AAC/C,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,sBAAsB,CACpC,MAAoC;IAEpC,MAAM,EACJ,QAAQ,EACR,UAAU,EACV,SAAS,GAAG,QAAQ,EACpB,SAAS,EACT,QAAQ,GAAG,IAAI,IAAI,EAAE,EACrB,SAAS,GACV,GAAG,MAAM,CAAC;IAEX,qBAAqB,CAAC,UAAU,CAAC,CAAC;IAElC,IAAI,SAAS,CAAC,OAAO,EAAE,IAAI,QAAQ,CAAC,OAAO,EAAE,EAAE,CAAC;QAC9C,MAAM,IAAI,KAAK,CACb,gEAAgE,CACjE,CAAC;IACJ,CAAC;IAED,MAAM,QAAQ,GAAG,UAAU,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAE/C,IAAI,SAAS,KAAK,YAAY,IAAI,QAAQ,EAAE,CAAC;QAC3C,MAAM,IAAI,KAAK,CACb,8EAA8E,CAC/E,CAAC;IACJ,CAAC;IAED,IAAI,SAAS,KAAK,YAAY,IAAI,CAAC,SAAS,EAAE,CAAC;QAC7C,MAAM,IAAI,KAAK,CACb,qEAAqE,CACtE,CAAC;IACJ,CAAC;IAED,MAAM,OAAO,GAAkC;QAC7C,OAAO,EAAE,iCAAiC;QAC1C,GAAG,EAAE,CAAC,GAAG,mCAAmC,CAAC;QAC7C,UAAU,EAAE,WAAW,CAAC,QAAQ,CAAC,SAAS,CAAC;QAC3C,kBAAkB,EAAE,WAAW,CAAC,QAAQ,CAAC,gBAAgB,CAAC;QAC1D,UAAU;QACV,SAAS;QACT,SAAS,EAAE,gBAAgB,CAAC,QAAQ,CAAC;QACrC,UAAU,EAAE,gBAAgB,CAAC,SAAS,CAAC;KACxC,CAAC;IAEF,6EAA6E;IAC7E,8EAA8E;IAC9E,IAAI,SAAS,KAAK,YAAY,EAAE,CAAC;QAC/B,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC;IACjC,CAAC;IAED,MAAM,OAAO,GAAG,aAAa,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAC;IACzD,MAAM,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,CAAC;IAE7D,OAAO;QACL,OAAO;QACP,SAAS,EAAE,WAAW,CAAC,SAAS,CAAC;KAClC,CAAC;AACJ,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,iCAAiC,CAC/C,KAA6B;IAE7B,OAAO,WAAW,CAAC,aAAa,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAC3D,CAAC;AAED;;;;;;GAMG;AACH,SAAS,qBAAqB,CAAC,UAAkC;IAC/D,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC5B,MAAM,IAAI,KAAK,CACb,6DAA6D,CAC9D,CAAC;IACJ,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,UAAU,CAAC,CAAC;IAEnC,IAAI,MAAM,CAAC,IAAI,KAAK,UAAU,CAAC,MAAM,EAAE,CAAC;QACtC,MAAM,IAAI,KAAK,CAAC,uDAAuD,CAAC,CAAC;IAC3E,CAAC;IAED,IAAI,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAClD,MAAM,IAAI,KAAK,CACb,wEAAwE,CACzE,CAAC;IACJ,CAAC;AACH,CAAC","sourcesContent":["import { stringToBytes } from '@metamask/utils';\nimport { ed25519 } from '@noble/curves/ed25519';\n\nimport { toBase64Url } from '../encoding.js';\nimport {\n UKYC_STORAGE_ACCESS_TOKEN_AUDIENCES,\n UKYC_STORAGE_ACCESS_TOKEN_VERSION,\n} from './constants.js';\nimport type { UkycClientMaterial } from './deriveClientMaterial.js';\n\n/**\n * Mints `storage_access_token` capabilities — the client-signed, scoped,\n * session-bound proofs that authorize UKYC storage operations. See the\n * architecture doc, section \"Storage Authentication\".\n *\n * The token is Ed25519 over RFC 8785 (JCS) canonical JSON of the payload. Only\n * the client holds the private `signing_key`, so only the client can mint a\n * token; a `read`/`write`-scoped token may then be handed to the Relay to\n * present, but `delete` is never delegated.\n */\n\n/**\n * Storage operations a `storage_access_token` can authorize.\n */\nexport type UkycStorageOperation = 'read' | 'write' | 'delete';\n\n/**\n * Who presents the token to UKYC storage. The Relay may only present\n * `read`/`write` tokens; `delete` is always client-presented.\n */\nexport type UkycTokenPresenter = 'client' | 'idos-relay';\n\n/**\n * The signed `storage_access_token` payload. Field names are snake_case because\n * they are canonicalized and hashed exactly as they appear on the wire.\n */\nexport type UkycStorageAccessTokenPayload = {\n version: number;\n /** Every verifier that may accept the token, e.g. UKYC Storage and idOS Kwil. */\n aud: string[];\n // Wire-shape fields are snake_case; they are canonicalized and signed exactly\n // as they appear on the wire.\n /* eslint-disable @typescript-eslint/naming-convention */\n storage_id: string;\n signing_public_key: string;\n operations: UkycStorageOperation[];\n presenter: UkycTokenPresenter;\n /** UKYC session id. Required (and only present) when presenter is `idos-relay`. */\n session_id?: string;\n issued_at: string;\n expires_at: string;\n /* eslint-enable @typescript-eslint/naming-convention */\n};\n\n/**\n * The on-the-wire envelope: the payload plus its detached Ed25519 signature\n * (base64url) over the JCS canonicalization of the payload.\n */\nexport type UkycStorageAccessToken = {\n payload: UkycStorageAccessTokenPayload;\n signature: string;\n};\n\n/**\n * Inputs for minting a `storage_access_token`.\n */\nexport type SignStorageAccessTokenParams = {\n /** Client material derived from `local_user_secret`. */\n material: UkycClientMaterial;\n /** Operations the token authorizes. `delete` must be the sole operation. */\n operations: UkycStorageOperation[];\n /** Who will present the token. Defaults to `client`. */\n presenter?: UkycTokenPresenter;\n /** UKYC session id. Required when presenter is `idos-relay`. */\n sessionId?: string;\n /** Token issue time. Defaults to now. */\n issuedAt?: Date;\n /** Token expiry. Must be strictly after `issuedAt`. */\n expiresAt: Date;\n};\n\ntype JsonValue =\n | null\n | boolean\n | number\n | string\n | JsonValue[]\n | { [key: string]: JsonValue | undefined };\n\n/**\n * Serializes a JSON value to RFC 8785 (JCS) canonical form.\n *\n * Scope note: this implementation covers the JSON shapes used by UKYC storage\n * payloads — objects, arrays, strings, integers, booleans, and null. Object\n * members are sorted by their UTF-16 code units (matching JS default string\n * ordering, which is what JCS requires) and `undefined` members are dropped.\n * Non-finite and non-integer numbers are rejected, since the payloads never\n * contain them and correct JCS number formatting for the general case is\n * intentionally out of scope here.\n *\n * @param value - The value to canonicalize.\n * @returns The canonical JSON string.\n */\nexport function canonicalizeJson(value: JsonValue): string {\n if (value === null) {\n return 'null';\n }\n\n if (typeof value === 'boolean') {\n return value ? 'true' : 'false';\n }\n\n if (typeof value === 'number') {\n if (!Number.isInteger(value)) {\n throw new Error(\n 'UKYC: cannot canonicalize a non-integer number for JCS.',\n );\n }\n return JSON.stringify(value);\n }\n\n if (typeof value === 'string') {\n return JSON.stringify(value);\n }\n\n if (Array.isArray(value)) {\n return `[${value.map((item) => canonicalizeJson(item)).join(',')}]`;\n }\n\n const entries = Object.keys(value)\n .sort()\n .reduce<string[]>((acc, key) => {\n const child = value[key];\n if (child !== undefined) {\n acc.push(`${JSON.stringify(key)}:${canonicalizeJson(child)}`);\n }\n return acc;\n }, []);\n\n return `{${entries.join(',')}}`;\n}\n\n/**\n * Formats a date as RFC 3339 UTC with whole-second precision (e.g.\n * `2026-07-07T00:00:00Z`). `Date.prototype.toISOString` always emits\n * milliseconds (`...:00.000Z`); the `storage_access_token` wire format omits\n * fractional seconds, so the sub-second component is truncated (not rounded).\n *\n * @param date - The date to format.\n * @returns The RFC 3339 timestamp without fractional seconds.\n */\nfunction toRfc3339Seconds(date: Date): string {\n return `${date.toISOString().slice(0, 19)}Z`;\n}\n\n/**\n * Builds and signs a `storage_access_token`.\n *\n * @param params - See {@link SignStorageAccessTokenParams}.\n * @returns The signed token envelope.\n */\nexport function signStorageAccessToken(\n params: SignStorageAccessTokenParams,\n): UkycStorageAccessToken {\n const {\n material,\n operations,\n presenter = 'client',\n sessionId,\n issuedAt = new Date(),\n expiresAt,\n } = params;\n\n assertValidOperations(operations);\n\n if (expiresAt.getTime() <= issuedAt.getTime()) {\n throw new Error(\n 'UKYC: storage_access_token expires_at must be after issued_at.',\n );\n }\n\n const isDelete = operations.includes('delete');\n\n if (presenter === 'idos-relay' && isDelete) {\n throw new Error(\n 'UKYC: a delete-scoped storage_access_token cannot be delegated to the Relay.',\n );\n }\n\n if (presenter === 'idos-relay' && !sessionId) {\n throw new Error(\n 'UKYC: a Relay-presented storage_access_token requires a session_id.',\n );\n }\n\n const payload: UkycStorageAccessTokenPayload = {\n version: UKYC_STORAGE_ACCESS_TOKEN_VERSION,\n aud: [...UKYC_STORAGE_ACCESS_TOKEN_AUDIENCES],\n storage_id: toBase64Url(material.storageId),\n signing_public_key: toBase64Url(material.signingPublicKey),\n operations,\n presenter,\n issued_at: toRfc3339Seconds(issuedAt),\n expires_at: toRfc3339Seconds(expiresAt),\n };\n\n // Only bind session_id for Relay-presented tokens; omit the key entirely for\n // client-presented tokens so it does not appear in the canonicalized payload.\n if (presenter === 'idos-relay') {\n payload.session_id = sessionId;\n }\n\n const message = stringToBytes(canonicalizeJson(payload));\n const signature = ed25519.sign(message, material.signingKey);\n\n return {\n payload,\n signature: toBase64Url(signature),\n };\n}\n\n/**\n * Serializes a signed token to a compact string suitable for header transport\n * (`Authorization: AccessToken <token>`, see `UKYC_CAPABILITY_AUTH_SCHEME`). The\n * complete envelope is base64url-encoded; the private `signing_key` is never\n * included.\n *\n * @param token - The signed token envelope.\n * @returns The base64url-encoded envelope string.\n */\nexport function encodeStorageAccessTokenForHeader(\n token: UkycStorageAccessToken,\n): string {\n return toBase64Url(stringToBytes(JSON.stringify(token)));\n}\n\n/**\n * Validates that an operations list is one storage understands: a non-empty set\n * of `read`/`write`, or exactly `['delete']`. `delete` is never combined with\n * other operations.\n *\n * @param operations - The requested operations.\n */\nfunction assertValidOperations(operations: UkycStorageOperation[]): void {\n if (operations.length === 0) {\n throw new Error(\n 'UKYC: storage_access_token requires at least one operation.',\n );\n }\n\n const unique = new Set(operations);\n\n if (unique.size !== operations.length) {\n throw new Error('UKYC: storage_access_token operations must be unique.');\n }\n\n if (unique.has('delete') && operations.length > 1) {\n throw new Error(\n 'UKYC: a delete-scoped storage_access_token must contain only \"delete\".',\n );\n }\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { UkycStorageAccessToken, UkycStorageOperation, UkycTokenPresenter } from
|
|
1
|
+
import type { UkycStorageAccessToken, UkycStorageOperation, UkycTokenPresenter } from './storageAccessToken.js';
|
|
2
2
|
/**
|
|
3
3
|
* Inputs for {@link mintUkycTestToken}. All fields are optional; the only value
|
|
4
4
|
* a caller usually pins is `localUserSecret`, so `storage_id` and the signing
|
|
@@ -47,4 +47,4 @@ export type MintedUkycTestToken = {
|
|
|
47
47
|
* @returns The token, its `Authorization` header, and the derived identifiers.
|
|
48
48
|
*/
|
|
49
49
|
export declare function mintUkycTestToken(params?: MintUkycTestTokenParams): MintedUkycTestToken;
|
|
50
|
-
//# sourceMappingURL=testToken.d.
|
|
50
|
+
//# sourceMappingURL=testToken.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"testToken.d.ts","sourceRoot":"","sources":["../../src/ukyc/testToken.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EACV,sBAAsB,EACtB,oBAAoB,EACpB,kBAAkB,EACnB,MAAM,yBAAyB,CAAC;AAgBjC;;;;GAIG;AACH,MAAM,MAAM,uBAAuB,GAAG;IACpC;;;;OAIG;IACH,eAAe,CAAC,EAAE,UAAU,GAAG,MAAM,CAAC;IACtC,+DAA+D;IAC/D,UAAU,CAAC,EAAE,oBAAoB,EAAE,CAAC;IACpC,wDAAwD;IACxD,SAAS,CAAC,EAAE,kBAAkB,CAAC;IAC/B,kEAAkE;IAClE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,yCAAyC;IACzC,QAAQ,CAAC,EAAE,IAAI,CAAC;IAChB,sDAAsD;IACtD,SAAS,CAAC,EAAE,IAAI,CAAC;CAClB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,mBAAmB,GAAG;IAChC,6EAA6E;IAC7E,eAAe,EAAE,MAAM,CAAC;IACxB,0EAA0E;IAC1E,SAAS,EAAE,MAAM,CAAC;IAClB,gEAAgE;IAChE,gBAAgB,EAAE,MAAM,CAAC;IACzB,uDAAuD;IACvD,KAAK,EAAE,sBAAsB,CAAC;IAC9B;;;OAGG;IACH,mBAAmB,EAAE,MAAM,CAAC;CAC7B,CAAC;AAgBF;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,GAAE,uBAA4B,GACnC,mBAAmB,CAgCrB"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { bytesToHex, hexToBytes, randomBytes } from
|
|
2
|
-
import { UKYC_CAPABILITY_AUTH_SCHEME, UKYC_LOCAL_USER_SECRET_SIZE_BYTES } from
|
|
3
|
-
import { deriveClientMaterial, encodeClientMaterial } from
|
|
4
|
-
import { encodeStorageAccessTokenForHeader, signStorageAccessToken } from
|
|
1
|
+
import { bytesToHex, hexToBytes, randomBytes } from '@noble/hashes/utils';
|
|
2
|
+
import { UKYC_CAPABILITY_AUTH_SCHEME, UKYC_LOCAL_USER_SECRET_SIZE_BYTES, } from './constants.js';
|
|
3
|
+
import { deriveClientMaterial, encodeClientMaterial, } from './deriveClientMaterial.js';
|
|
4
|
+
import { encodeStorageAccessTokenForHeader, signStorageAccessToken, } from './storageAccessToken.js';
|
|
5
5
|
/**
|
|
6
6
|
* Mints ready-to-use UKYC `storage_access_token`s for testing UKYC Storage.
|
|
7
7
|
*
|
|
@@ -54,4 +54,4 @@ export function mintUkycTestToken(params = {}) {
|
|
|
54
54
|
authorizationHeader: `${UKYC_CAPABILITY_AUTH_SCHEME} ${encodeStorageAccessTokenForHeader(token)}`,
|
|
55
55
|
};
|
|
56
56
|
}
|
|
57
|
-
//# sourceMappingURL=testToken.
|
|
57
|
+
//# sourceMappingURL=testToken.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"testToken.js","sourceRoot":"","sources":["../../src/ukyc/testToken.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAE1E,OAAO,EACL,2BAA2B,EAC3B,iCAAiC,GAClC,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,oBAAoB,EACpB,oBAAoB,GACrB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EACL,iCAAiC,EACjC,sBAAsB,GACvB,MAAM,yBAAyB,CAAC;AAOjC;;;;;;;;;GASG;AAEH,yEAAyE;AACzE,MAAM,yBAAyB,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;AA6CrD;;;;;;GAMG;AACH,SAAS,sBAAsB,CAAC,MAA4B;IAC1D,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QACzB,OAAO,WAAW,CAAC,iCAAiC,CAAC,CAAC;IACxD,CAAC;IACD,OAAO,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;AAClE,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAC/B,MAAM,GAA4B,EAAE;IAEpC,MAAM,EACJ,UAAU,GAAG,CAAC,MAAM,CAAC,EACrB,SAAS,EACT,SAAS,EACT,QAAQ,GAAG,IAAI,IAAI,EAAE,EACrB,SAAS,GAAG,IAAI,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,GAAG,yBAAyB,CAAC,GACrE,GAAG,MAAM,CAAC;IAEX,MAAM,eAAe,GAAG,sBAAsB,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC;IACvE,MAAM,QAAQ,GAAG,oBAAoB,CAAC,eAAe,CAAC,CAAC;IAEvD,MAAM,KAAK,GAAG,sBAAsB,CAAC;QACnC,QAAQ;QACR,UAAU;QACV,SAAS;QACT,SAAS;QACT,QAAQ;QACR,SAAS;KACV,CAAC,CAAC;IAEH,MAAM,EAAE,SAAS,EAAE,gBAAgB,EAAE,GAAG,oBAAoB,CAAC,QAAQ,CAAC,CAAC;IAEvE,OAAO;QACL,eAAe,EAAE,UAAU,CAAC,eAAe,CAAC;QAC5C,SAAS;QACT,gBAAgB;QAChB,KAAK;QACL,mBAAmB,EAAE,GAAG,2BAA2B,IAAI,iCAAiC,CACtF,KAAK,CACN,EAAE;KACJ,CAAC;AACJ,CAAC","sourcesContent":["import { bytesToHex, hexToBytes, randomBytes } from '@noble/hashes/utils';\n\nimport {\n UKYC_CAPABILITY_AUTH_SCHEME,\n UKYC_LOCAL_USER_SECRET_SIZE_BYTES,\n} from './constants.js';\nimport {\n deriveClientMaterial,\n encodeClientMaterial,\n} from './deriveClientMaterial.js';\nimport {\n encodeStorageAccessTokenForHeader,\n signStorageAccessToken,\n} from './storageAccessToken.js';\nimport type {\n UkycStorageAccessToken,\n UkycStorageOperation,\n UkycTokenPresenter,\n} from './storageAccessToken.js';\n\n/**\n * Mints ready-to-use UKYC `storage_access_token`s for testing UKYC Storage.\n *\n * This composes the same pure functions the MetaMask client uses in production\n * (`deriveClientMaterial` + `signStorageAccessToken`), so a third party such as\n * idOS can produce a valid, signed token without deriving one on-device. No\n * server \"fills in\" the `signing_public_key`: it is derived from a\n * `local_user_secret` the caller controls and registered on first write, so\n * reusing the same secret yields a stable `storage_id` and controlling key.\n */\n\n/** Default token lifetime when `expiresAt` is not supplied (4 hours). */\nconst DEFAULT_TOKEN_LIFETIME_MS = 4 * 60 * 60 * 1000;\n\n/**\n * Inputs for {@link mintUkycTestToken}. All fields are optional; the only value\n * a caller usually pins is `localUserSecret`, so `storage_id` and the signing\n * key stay stable across runs.\n */\nexport type MintUkycTestTokenParams = {\n /**\n * The root `local_user_secret`, as raw 32 bytes or a hex string. When omitted\n * a fresh random secret is generated (returned in the result so it can be\n * reused).\n */\n localUserSecret?: Uint8Array | string;\n /** Operations the token authorizes. Defaults to `['read']`. */\n operations?: UkycStorageOperation[];\n /** Who will present the token. Defaults to `client`. */\n presenter?: UkycTokenPresenter;\n /** UKYC session id. Required when `presenter` is `idos-relay`. */\n sessionId?: string;\n /** Token issue time. Defaults to now. */\n issuedAt?: Date;\n /** Token expiry. Defaults to `issuedAt` + 4 hours. */\n expiresAt?: Date;\n};\n\n/**\n * The minted token plus everything needed to exercise UKYC Storage with it.\n */\nexport type MintedUkycTestToken = {\n /** The `local_user_secret` used, hex-encoded, so the caller can reuse it. */\n localUserSecret: string;\n /** base64url `storage_id` — use it as the `{storage_id}` path segment. */\n storageId: string;\n /** base64url `signing_public_key` registered on first write. */\n signingPublicKey: string;\n /** The signed token envelope (payload + signature). */\n token: UkycStorageAccessToken;\n /**\n * The full `Authorization` header value, e.g.\n * `AccessToken <base64url(envelope)>`, ready to send to UKYC Storage.\n */\n authorizationHeader: string;\n};\n\n/**\n * Resolves the caller-supplied secret into raw bytes, generating a random one\n * when none is provided.\n *\n * @param secret - Raw 32 bytes, a hex string, or undefined for a random secret.\n * @returns The `local_user_secret` bytes.\n */\nfunction resolveLocalUserSecret(secret?: Uint8Array | string): Uint8Array {\n if (secret === undefined) {\n return randomBytes(UKYC_LOCAL_USER_SECRET_SIZE_BYTES);\n }\n return typeof secret === 'string' ? hexToBytes(secret) : secret;\n}\n\n/**\n * Mints a signed UKYC `storage_access_token` for testing.\n *\n * @param params - See {@link MintUkycTestTokenParams}.\n * @returns The token, its `Authorization` header, and the derived identifiers.\n */\nexport function mintUkycTestToken(\n params: MintUkycTestTokenParams = {},\n): MintedUkycTestToken {\n const {\n operations = ['read'],\n presenter,\n sessionId,\n issuedAt = new Date(),\n expiresAt = new Date(issuedAt.getTime() + DEFAULT_TOKEN_LIFETIME_MS),\n } = params;\n\n const localUserSecret = resolveLocalUserSecret(params.localUserSecret);\n const material = deriveClientMaterial(localUserSecret);\n\n const token = signStorageAccessToken({\n material,\n operations,\n presenter,\n sessionId,\n issuedAt,\n expiresAt,\n });\n\n const { storageId, signingPublicKey } = encodeClientMaterial(material);\n\n return {\n localUserSecret: bytesToHex(localUserSecret),\n storageId,\n signingPublicKey,\n token,\n authorizationHeader: `${UKYC_CAPABILITY_AUTH_SCHEME} ${encodeStorageAccessTokenForHeader(\n token,\n )}`,\n };\n}\n"]}
|
|
@@ -33,4 +33,4 @@ export type WrappedEncryptionKeyParts = {
|
|
|
33
33
|
* @returns The base64url `data` (ciphertext+tag) and `nonce`.
|
|
34
34
|
*/
|
|
35
35
|
export declare function wrapEncryptionKey(sessionClientPrivateKey: Uint8Array, sessionServerPublicKey: string, plaintext: Uint8Array): WrappedEncryptionKeyParts;
|
|
36
|
-
//# sourceMappingURL=wrapEncryptionKey.d.
|
|
36
|
+
//# sourceMappingURL=wrapEncryptionKey.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wrapEncryptionKey.d.ts","sourceRoot":"","sources":["../../src/ukyc/wrapEncryptionKey.ts"],"names":[],"mappings":"AAIA;;;;;;;;;GASG;AAEH;;;;GAIG;AACH,MAAM,MAAM,yBAAyB,GAAG;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,iBAAiB,CAC/B,uBAAuB,EAAE,UAAU,EACnC,sBAAsB,EAAE,MAAM,EAC9B,SAAS,EAAE,UAAU,GACpB,yBAAyB,CAa3B"}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
import { base64UrlToBytes, toBase64Url } from "../encoding.mjs";
|
|
1
|
+
import { randomBytes, box } from 'tweetnacl';
|
|
2
|
+
import { base64UrlToBytes, toBase64Url } from '../encoding.js';
|
|
4
3
|
/**
|
|
5
4
|
* Wraps `plaintext` for the UKYC session server.
|
|
6
5
|
*
|
|
@@ -25,4 +24,4 @@ export function wrapEncryptionKey(sessionClientPrivateKey, sessionServerPublicKe
|
|
|
25
24
|
nonce: toBase64Url(nonce),
|
|
26
25
|
};
|
|
27
26
|
}
|
|
28
|
-
//# sourceMappingURL=wrapEncryptionKey.
|
|
27
|
+
//# sourceMappingURL=wrapEncryptionKey.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wrapEncryptionKey.js","sourceRoot":"","sources":["../../src/ukyc/wrapEncryptionKey.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AAE7C,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAuB/D;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,iBAAiB,CAC/B,uBAAmC,EACnC,sBAA8B,EAC9B,SAAqB;IAErB,MAAM,eAAe,GAAG,gBAAgB,CAAC,sBAAsB,CAAC,CAAC;IACjE,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IAC3C,MAAM,UAAU,GAAG,GAAG,CACpB,SAAS,EACT,KAAK,EACL,eAAe,EACf,uBAAuB,CACxB,CAAC;IACF,OAAO;QACL,IAAI,EAAE,WAAW,CAAC,UAAU,CAAC;QAC7B,KAAK,EAAE,WAAW,CAAC,KAAK,CAAC;KAC1B,CAAC;AACJ,CAAC","sourcesContent":["import { randomBytes, box } from 'tweetnacl';\n\nimport { base64UrlToBytes, toBase64Url } from '../encoding.js';\n\n/**\n * Wraps a secret for the UKYC session server using NaCl's `crypto_box`\n * (X25519 + XSalsa20-Poly1305) established with a per-secret wrapping key\n * returned inside an encryption schema from `createUkycSession`.\n *\n * Reuses a session client keypair whose public half is registered on\n * `createUkycSession`. `data` is the ciphertext+tag only; the server already\n * knows the client public key from session creation. Used for both the\n * `data_encryption_key` and the `ukyc_capability_token`.\n */\n\n/**\n * The transmitted portion of a wrapped secret: the `crypto_box` ciphertext\n * (which includes the 16-byte Poly1305 auth tag) and the nonce, both unpadded\n * base64url-encoded. Matches the KYC API `CapabilityAuthorization` wire shape.\n */\nexport type WrappedEncryptionKeyParts = {\n data: string;\n nonce: string;\n};\n\n/**\n * Wraps `plaintext` for the UKYC session server.\n *\n * The box is sealed with NaCl's `crypto_box`, keyed by the X25519 shared secret\n * between our session client private key and the session server public key\n * from an encryption schema (`encryptionDataKey` or `ukycCapabilityToken`)\n * returned by `createUkycSession`. The client public key is not embedded in\n * `data`; it was already registered on `createUkycSession`.\n *\n * @param sessionClientPrivateKey - Our session's X25519 private key.\n * @param sessionServerPublicKey - The server's X25519 public key (base64url).\n * @param plaintext - The raw bytes to encrypt (e.g. the `data_encryption_key`\n * or the encoded `ukyc_capability_token`).\n * @returns The base64url `data` (ciphertext+tag) and `nonce`.\n */\nexport function wrapEncryptionKey(\n sessionClientPrivateKey: Uint8Array,\n sessionServerPublicKey: string,\n plaintext: Uint8Array,\n): WrappedEncryptionKeyParts {\n const serverPublicKey = base64UrlToBytes(sessionServerPublicKey);\n const nonce = randomBytes(box.nonceLength);\n const ciphertext = box(\n plaintext,\n nonce,\n serverPublicKey,\n sessionClientPrivateKey,\n );\n return {\n data: toBase64Url(ciphertext),\n nonce: toBase64Url(nonce),\n };\n}\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { UkycClientMaterial } from
|
|
2
|
-
import type { UkycStorageAccessToken } from
|
|
1
|
+
import type { UkycClientMaterial } from './deriveClientMaterial.js';
|
|
2
|
+
import type { UkycStorageAccessToken } from './storageAccessToken.js';
|
|
3
3
|
/**
|
|
4
4
|
* Builds the `wrapped_relay_payload` — the only client-derived material that
|
|
5
5
|
* leaves the device. It is sent to the idOS Relay (through the UKYC API) so the
|
|
@@ -32,4 +32,4 @@ export type UkycWrappedRelayPayload = {
|
|
|
32
32
|
* @returns The `wrapped_relay_payload` to send to the Relay via the UKYC API.
|
|
33
33
|
*/
|
|
34
34
|
export declare function buildWrappedRelayPayload(material: UkycClientMaterial, storageAccessToken: UkycStorageAccessToken): UkycWrappedRelayPayload;
|
|
35
|
-
//# sourceMappingURL=wrappedRelayPayload.d.
|
|
35
|
+
//# sourceMappingURL=wrappedRelayPayload.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wrappedRelayPayload.d.ts","sourceRoot":"","sources":["../../src/ukyc/wrappedRelayPayload.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AACpE,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAC;AAEtE;;;;;;;;;GASG;AAEH;;;GAGG;AACH,MAAM,MAAM,uBAAuB,GAAG;IAGpC,UAAU,EAAE,MAAM,CAAC;IACnB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,oBAAoB,EAAE,sBAAsB,CAAC;CAE9C,CAAC;AAEF;;;;;;;;;;GAUG;AACH,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,kBAAkB,EAC5B,kBAAkB,EAAE,sBAAsB,GACzC,uBAAuB,CAqBzB"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { toBase64Url } from
|
|
1
|
+
import { toBase64Url } from '../encoding.js';
|
|
2
2
|
/**
|
|
3
3
|
* Assembles the `wrapped_relay_payload` from derived client material and a
|
|
4
4
|
* Relay-presented `storage_access_token`.
|
|
@@ -25,4 +25,4 @@ export function buildWrappedRelayPayload(material, storageAccessToken) {
|
|
|
25
25
|
storage_access_token: storageAccessToken,
|
|
26
26
|
};
|
|
27
27
|
}
|
|
28
|
-
//# sourceMappingURL=wrappedRelayPayload.
|
|
28
|
+
//# sourceMappingURL=wrappedRelayPayload.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wrappedRelayPayload.js","sourceRoot":"","sources":["../../src/ukyc/wrappedRelayPayload.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AA6B7C;;;;;;;;;;GAUG;AACH,MAAM,UAAU,wBAAwB,CACtC,QAA4B,EAC5B,kBAA0C;IAE1C,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,GAAG,kBAAkB,CAAC,OAAO,CAAC;IAE7D,IAAI,SAAS,KAAK,YAAY,EAAE,CAAC;QAC/B,MAAM,IAAI,KAAK,CACb,8EAA8E,CAC/E,CAAC;IACJ,CAAC;IAED,IAAI,UAAU,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;QAClC,MAAM,IAAI,KAAK,CACb,kFAAkF,CACnF,CAAC;IACJ,CAAC;IAED,OAAO;QACL,UAAU,EAAE,WAAW,CAAC,QAAQ,CAAC,SAAS,CAAC;QAC3C,mBAAmB,EAAE,WAAW,CAAC,QAAQ,CAAC,iBAAiB,CAAC;QAC5D,kBAAkB,EAAE,WAAW,CAAC,QAAQ,CAAC,gBAAgB,CAAC;QAC1D,oBAAoB,EAAE,kBAAkB;KACzC,CAAC;AACJ,CAAC","sourcesContent":["import { toBase64Url } from '../encoding.js';\nimport type { UkycClientMaterial } from './deriveClientMaterial.js';\nimport type { UkycStorageAccessToken } from './storageAccessToken.js';\n\n/**\n * Builds the `wrapped_relay_payload` — the only client-derived material that\n * leaves the device. It is sent to the idOS Relay (through the UKYC API) so the\n * Relay can encrypt/decrypt and store KYC payloads on the user's behalf. See the\n * architecture doc, section \"Client-Derived Material\".\n *\n * Neither `local_user_secret` nor the private `signing_key` are ever included.\n * The `data_encryption_key` *is* included: it is intentionally shared with the\n * Relay so it can encrypt/decrypt payloads transiently.\n */\n\n/**\n * The Relay-facing bundle. `data_encryption_key` is base64url-encoded secret\n * material shared with the Relay; the other fields are non-secret.\n */\nexport type UkycWrappedRelayPayload = {\n // Wire-shape fields are snake_case.\n /* eslint-disable @typescript-eslint/naming-convention */\n storage_id: string;\n data_encryption_key: string;\n signing_public_key: string;\n storage_access_token: UkycStorageAccessToken;\n /* eslint-enable @typescript-eslint/naming-convention */\n};\n\n/**\n * Assembles the `wrapped_relay_payload` from derived client material and a\n * Relay-presented `storage_access_token`.\n *\n * The token must be scoped for the Relay to present (`presenter: 'idos-relay'`)\n * and must not authorize `delete`, which is never delegated to the Relay.\n *\n * @param material - Client material derived from `local_user_secret`.\n * @param storageAccessToken - A `read`/`write`-scoped, Relay-presented token.\n * @returns The `wrapped_relay_payload` to send to the Relay via the UKYC API.\n */\nexport function buildWrappedRelayPayload(\n material: UkycClientMaterial,\n storageAccessToken: UkycStorageAccessToken,\n): UkycWrappedRelayPayload {\n const { presenter, operations } = storageAccessToken.payload;\n\n if (presenter !== 'idos-relay') {\n throw new Error(\n 'UKYC: wrapped_relay_payload requires a Relay-presented storage_access_token.',\n );\n }\n\n if (operations.includes('delete')) {\n throw new Error(\n 'UKYC: wrapped_relay_payload must not carry a delete-scoped storage_access_token.',\n );\n }\n\n return {\n storage_id: toBase64Url(material.storageId),\n data_encryption_key: toBase64Url(material.dataEncryptionKey),\n signing_public_key: toBase64Url(material.signingPublicKey),\n storage_access_token: storageAccessToken,\n };\n}\n"]}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { KycVendor, KycVendorDisclaimersAccepted } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Returns whether persisted vendor disclaimer acceptance exists for `vendor`.
|
|
4
|
+
*
|
|
5
|
+
* @param accepted - Vendor-disclaimer acceptance map.
|
|
6
|
+
* @param vendor - Identity vendor to inspect.
|
|
7
|
+
* @returns Whether acceptance is present for the vendor.
|
|
8
|
+
*/
|
|
9
|
+
export declare function hasVendorDisclaimerAcceptance(accepted: KycVendorDisclaimersAccepted, vendor: KycVendor): boolean;
|
|
10
|
+
/**
|
|
11
|
+
* Returns persisted Iron disclaimer ids, if any.
|
|
12
|
+
*
|
|
13
|
+
* @param accepted - Vendor-disclaimer acceptance map.
|
|
14
|
+
* @returns The accepted disclaimer ids, or an empty array.
|
|
15
|
+
*/
|
|
16
|
+
export declare function ironDisclaimerIds(accepted: KycVendorDisclaimersAccepted): string[];
|
|
17
|
+
/**
|
|
18
|
+
* Records vendor disclaimer acceptance for the active vendor.
|
|
19
|
+
*
|
|
20
|
+
* @param accepted - Existing vendor-disclaimer acceptance map.
|
|
21
|
+
* @param vendor - Identity vendor being accepted.
|
|
22
|
+
* @param params - Acceptance payload for the vendor.
|
|
23
|
+
* @param params.termsAcceptedAt - MoonPay acceptance timestamp.
|
|
24
|
+
* @param params.disclaimerIds - Iron disclaimer ids.
|
|
25
|
+
* @returns The updated acceptance map.
|
|
26
|
+
*/
|
|
27
|
+
export declare function recordVendorDisclaimerAcceptance(accepted: KycVendorDisclaimersAccepted, vendor: KycVendor, params: {
|
|
28
|
+
termsAcceptedAt: string;
|
|
29
|
+
disclaimerIds: string[];
|
|
30
|
+
}): KycVendorDisclaimersAccepted;
|
|
31
|
+
/**
|
|
32
|
+
* Clears persisted vendor disclaimer acceptance for one vendor.
|
|
33
|
+
*
|
|
34
|
+
* @param accepted - Existing vendor-disclaimer acceptance map.
|
|
35
|
+
* @param vendor - Identity vendor whose acceptance should be cleared.
|
|
36
|
+
* @returns The updated acceptance map.
|
|
37
|
+
*/
|
|
38
|
+
export declare function clearVendorDisclaimerAcceptance(accepted: KycVendorDisclaimersAccepted, vendor: KycVendor): KycVendorDisclaimersAccepted;
|
|
39
|
+
//# sourceMappingURL=vendorDisclaimerAcceptance.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vendorDisclaimerAcceptance.d.ts","sourceRoot":"","sources":["../src/vendorDisclaimerAcceptance.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,4BAA4B,EAAE,MAAM,YAAY,CAAC;AAE1E;;;;;;GAMG;AACH,wBAAgB,6BAA6B,CAC3C,QAAQ,EAAE,4BAA4B,EACtC,MAAM,EAAE,SAAS,GAChB,OAAO,CAQT;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,4BAA4B,GACrC,MAAM,EAAE,CAEV;AAED;;;;;;;;;GASG;AACH,wBAAgB,gCAAgC,CAC9C,QAAQ,EAAE,4BAA4B,EACtC,MAAM,EAAE,SAAS,EACjB,MAAM,EAAE;IAAE,eAAe,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,EAAE,CAAA;CAAE,GAC3D,4BAA4B,CAc9B;AAED;;;;;;GAMG;AACH,wBAAgB,+BAA+B,CAC7C,QAAQ,EAAE,4BAA4B,EACtC,MAAM,EAAE,SAAS,GAChB,4BAA4B,CAQ9B"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Returns whether persisted vendor disclaimer acceptance exists for `vendor`.
|
|
3
|
+
*
|
|
4
|
+
* @param accepted - Vendor-disclaimer acceptance map.
|
|
5
|
+
* @param vendor - Identity vendor to inspect.
|
|
6
|
+
* @returns Whether acceptance is present for the vendor.
|
|
7
|
+
*/
|
|
8
|
+
export function hasVendorDisclaimerAcceptance(accepted, vendor) {
|
|
9
|
+
if (vendor === 'moonpay') {
|
|
10
|
+
return Boolean(accepted.moonpay?.termsAcceptedAt);
|
|
11
|
+
}
|
|
12
|
+
if (vendor === 'iron') {
|
|
13
|
+
return Boolean(accepted.iron?.disclaimerIds.length);
|
|
14
|
+
}
|
|
15
|
+
return false;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Returns persisted Iron disclaimer ids, if any.
|
|
19
|
+
*
|
|
20
|
+
* @param accepted - Vendor-disclaimer acceptance map.
|
|
21
|
+
* @returns The accepted disclaimer ids, or an empty array.
|
|
22
|
+
*/
|
|
23
|
+
export function ironDisclaimerIds(accepted) {
|
|
24
|
+
return accepted.iron?.disclaimerIds ?? [];
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Records vendor disclaimer acceptance for the active vendor.
|
|
28
|
+
*
|
|
29
|
+
* @param accepted - Existing vendor-disclaimer acceptance map.
|
|
30
|
+
* @param vendor - Identity vendor being accepted.
|
|
31
|
+
* @param params - Acceptance payload for the vendor.
|
|
32
|
+
* @param params.termsAcceptedAt - MoonPay acceptance timestamp.
|
|
33
|
+
* @param params.disclaimerIds - Iron disclaimer ids.
|
|
34
|
+
* @returns The updated acceptance map.
|
|
35
|
+
*/
|
|
36
|
+
export function recordVendorDisclaimerAcceptance(accepted, vendor, params) {
|
|
37
|
+
if (vendor === 'moonpay') {
|
|
38
|
+
return {
|
|
39
|
+
...accepted,
|
|
40
|
+
moonpay: { termsAcceptedAt: params.termsAcceptedAt },
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
if (vendor === 'iron') {
|
|
44
|
+
return {
|
|
45
|
+
...accepted,
|
|
46
|
+
iron: { disclaimerIds: params.disclaimerIds },
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
return accepted;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Clears persisted vendor disclaimer acceptance for one vendor.
|
|
53
|
+
*
|
|
54
|
+
* @param accepted - Existing vendor-disclaimer acceptance map.
|
|
55
|
+
* @param vendor - Identity vendor whose acceptance should be cleared.
|
|
56
|
+
* @returns The updated acceptance map.
|
|
57
|
+
*/
|
|
58
|
+
export function clearVendorDisclaimerAcceptance(accepted, vendor) {
|
|
59
|
+
if (vendor === 'moonpay') {
|
|
60
|
+
return { ...accepted, moonpay: null };
|
|
61
|
+
}
|
|
62
|
+
if (vendor === 'iron') {
|
|
63
|
+
return { ...accepted, iron: null };
|
|
64
|
+
}
|
|
65
|
+
return accepted;
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=vendorDisclaimerAcceptance.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vendorDisclaimerAcceptance.js","sourceRoot":"","sources":["../src/vendorDisclaimerAcceptance.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,MAAM,UAAU,6BAA6B,CAC3C,QAAsC,EACtC,MAAiB;IAEjB,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QACzB,OAAO,OAAO,CAAC,QAAQ,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC;IACpD,CAAC;IACD,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;QACtB,OAAO,OAAO,CAAC,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IACtD,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAC/B,QAAsC;IAEtC,OAAO,QAAQ,CAAC,IAAI,EAAE,aAAa,IAAI,EAAE,CAAC;AAC5C,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,gCAAgC,CAC9C,QAAsC,EACtC,MAAiB,EACjB,MAA4D;IAE5D,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QACzB,OAAO;YACL,GAAG,QAAQ;YACX,OAAO,EAAE,EAAE,eAAe,EAAE,MAAM,CAAC,eAAe,EAAE;SACrD,CAAC;IACJ,CAAC;IACD,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;QACtB,OAAO;YACL,GAAG,QAAQ;YACX,IAAI,EAAE,EAAE,aAAa,EAAE,MAAM,CAAC,aAAa,EAAE;SAC9C,CAAC;IACJ,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,+BAA+B,CAC7C,QAAsC,EACtC,MAAiB;IAEjB,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QACzB,OAAO,EAAE,GAAG,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IACxC,CAAC;IACD,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;QACtB,OAAO,EAAE,GAAG,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IACrC,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC","sourcesContent":["import type { KycVendor, KycVendorDisclaimersAccepted } from './types.js';\n\n/**\n * Returns whether persisted vendor disclaimer acceptance exists for `vendor`.\n *\n * @param accepted - Vendor-disclaimer acceptance map.\n * @param vendor - Identity vendor to inspect.\n * @returns Whether acceptance is present for the vendor.\n */\nexport function hasVendorDisclaimerAcceptance(\n accepted: KycVendorDisclaimersAccepted,\n vendor: KycVendor,\n): boolean {\n if (vendor === 'moonpay') {\n return Boolean(accepted.moonpay?.termsAcceptedAt);\n }\n if (vendor === 'iron') {\n return Boolean(accepted.iron?.disclaimerIds.length);\n }\n return false;\n}\n\n/**\n * Returns persisted Iron disclaimer ids, if any.\n *\n * @param accepted - Vendor-disclaimer acceptance map.\n * @returns The accepted disclaimer ids, or an empty array.\n */\nexport function ironDisclaimerIds(\n accepted: KycVendorDisclaimersAccepted,\n): string[] {\n return accepted.iron?.disclaimerIds ?? [];\n}\n\n/**\n * Records vendor disclaimer acceptance for the active vendor.\n *\n * @param accepted - Existing vendor-disclaimer acceptance map.\n * @param vendor - Identity vendor being accepted.\n * @param params - Acceptance payload for the vendor.\n * @param params.termsAcceptedAt - MoonPay acceptance timestamp.\n * @param params.disclaimerIds - Iron disclaimer ids.\n * @returns The updated acceptance map.\n */\nexport function recordVendorDisclaimerAcceptance(\n accepted: KycVendorDisclaimersAccepted,\n vendor: KycVendor,\n params: { termsAcceptedAt: string; disclaimerIds: string[] },\n): KycVendorDisclaimersAccepted {\n if (vendor === 'moonpay') {\n return {\n ...accepted,\n moonpay: { termsAcceptedAt: params.termsAcceptedAt },\n };\n }\n if (vendor === 'iron') {\n return {\n ...accepted,\n iron: { disclaimerIds: params.disclaimerIds },\n };\n }\n return accepted;\n}\n\n/**\n * Clears persisted vendor disclaimer acceptance for one vendor.\n *\n * @param accepted - Existing vendor-disclaimer acceptance map.\n * @param vendor - Identity vendor whose acceptance should be cleared.\n * @returns The updated acceptance map.\n */\nexport function clearVendorDisclaimerAcceptance(\n accepted: KycVendorDisclaimersAccepted,\n vendor: KycVendor,\n): KycVendorDisclaimersAccepted {\n if (vendor === 'moonpay') {\n return { ...accepted, moonpay: null };\n }\n if (vendor === 'iron') {\n return { ...accepted, iron: null };\n }\n return accepted;\n}\n"]}
|