@metamask-previews/kyc-controller 0.0.0-preview-823dcff → 0.0.0-preview-e57e5c3dc
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 +8 -0
- package/README.md +10 -2
- package/dist/KycController-method-action-types.cjs +7 -0
- package/dist/KycController-method-action-types.cjs.map +1 -0
- package/dist/KycController-method-action-types.d.cts +168 -0
- package/dist/KycController-method-action-types.d.cts.map +1 -0
- package/dist/KycController-method-action-types.d.mts +168 -0
- package/dist/KycController-method-action-types.d.mts.map +1 -0
- package/dist/KycController-method-action-types.mjs +6 -0
- package/dist/KycController-method-action-types.mjs.map +1 -0
- package/dist/KycController.cjs +1085 -0
- package/dist/KycController.cjs.map +1 -0
- package/dist/KycController.d.cts +255 -0
- package/dist/KycController.d.cts.map +1 -0
- package/dist/KycController.d.mts +255 -0
- package/dist/KycController.d.mts.map +1 -0
- package/dist/KycController.mjs +1080 -0
- package/dist/KycController.mjs.map +1 -0
- package/dist/KycService-method-action-types.cjs +7 -0
- package/dist/KycService-method-action-types.cjs.map +1 -0
- package/dist/KycService-method-action-types.d.cts +121 -0
- package/dist/KycService-method-action-types.d.cts.map +1 -0
- package/dist/KycService-method-action-types.d.mts +121 -0
- package/dist/KycService-method-action-types.d.mts.map +1 -0
- package/dist/KycService-method-action-types.mjs +6 -0
- package/dist/KycService-method-action-types.mjs.map +1 -0
- package/dist/KycService.cjs +417 -0
- package/dist/KycService.cjs.map +1 -0
- package/dist/KycService.d.cts +307 -0
- package/dist/KycService.d.cts.map +1 -0
- package/dist/KycService.d.mts +307 -0
- package/dist/KycService.d.mts.map +1 -0
- package/dist/KycService.mjs +413 -0
- package/dist/KycService.mjs.map +1 -0
- package/dist/countryCodes.cjs +274 -0
- package/dist/countryCodes.cjs.map +1 -0
- package/dist/countryCodes.d.cts +18 -0
- package/dist/countryCodes.d.cts.map +1 -0
- package/dist/countryCodes.d.mts +18 -0
- package/dist/countryCodes.d.mts.map +1 -0
- package/dist/countryCodes.mjs +270 -0
- package/dist/countryCodes.mjs.map +1 -0
- package/dist/crypto.cjs +154 -0
- package/dist/crypto.cjs.map +1 -0
- package/dist/crypto.d.cts +84 -0
- package/dist/crypto.d.cts.map +1 -0
- package/dist/crypto.d.mts +84 -0
- package/dist/crypto.d.mts.map +1 -0
- package/dist/crypto.mjs +149 -0
- package/dist/crypto.mjs.map +1 -0
- package/dist/encoding.cjs +40 -0
- package/dist/encoding.cjs.map +1 -0
- package/dist/encoding.d.cts +24 -0
- package/dist/encoding.d.cts.map +1 -0
- package/dist/encoding.d.mts +24 -0
- package/dist/encoding.d.mts.map +1 -0
- package/dist/encoding.mjs +35 -0
- package/dist/encoding.mjs.map +1 -0
- package/dist/index.cjs +34 -10
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +18 -7
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +18 -7
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +11 -9
- package/dist/index.mjs.map +1 -1
- package/dist/selectors.cjs +30 -0
- package/dist/selectors.cjs.map +1 -0
- package/dist/selectors.d.cts +24 -0
- package/dist/selectors.d.cts.map +1 -0
- package/dist/selectors.d.mts +24 -0
- package/dist/selectors.d.mts.map +1 -0
- package/dist/selectors.mjs +24 -0
- package/dist/selectors.mjs.map +1 -0
- package/dist/types.cjs +10 -0
- package/dist/types.cjs.map +1 -0
- package/dist/types.d.cts +124 -0
- package/dist/types.d.cts.map +1 -0
- package/dist/types.d.mts +124 -0
- package/dist/types.d.mts.map +1 -0
- package/dist/types.mjs +9 -0
- package/dist/types.mjs.map +1 -0
- package/dist/ukyc/constants.cjs +75 -0
- package/dist/ukyc/constants.cjs.map +1 -0
- package/dist/ukyc/constants.d.cts +69 -0
- package/dist/ukyc/constants.d.cts.map +1 -0
- package/dist/ukyc/constants.d.mts +69 -0
- package/dist/ukyc/constants.d.mts.map +1 -0
- package/dist/ukyc/constants.mjs +72 -0
- package/dist/ukyc/constants.mjs.map +1 -0
- package/dist/ukyc/deriveClientMaterial.cjs +65 -0
- package/dist/ukyc/deriveClientMaterial.cjs.map +1 -0
- package/dist/ukyc/deriveClientMaterial.d.cts +54 -0
- package/dist/ukyc/deriveClientMaterial.d.cts.map +1 -0
- package/dist/ukyc/deriveClientMaterial.d.mts +54 -0
- package/dist/ukyc/deriveClientMaterial.d.mts.map +1 -0
- package/dist/ukyc/deriveClientMaterial.mjs +60 -0
- package/dist/ukyc/deriveClientMaterial.mjs.map +1 -0
- package/dist/ukyc/jwtChain.cjs +54 -0
- package/dist/ukyc/jwtChain.cjs.map +1 -0
- package/dist/ukyc/jwtChain.d.cts +40 -0
- package/dist/ukyc/jwtChain.d.cts.map +1 -0
- package/dist/ukyc/jwtChain.d.mts +40 -0
- package/dist/ukyc/jwtChain.d.mts.map +1 -0
- package/dist/ukyc/jwtChain.mjs +50 -0
- package/dist/ukyc/jwtChain.mjs.map +1 -0
- package/dist/ukyc/localUserSecret.cjs +98 -0
- package/dist/ukyc/localUserSecret.cjs.map +1 -0
- package/dist/ukyc/localUserSecret.d.cts +65 -0
- package/dist/ukyc/localUserSecret.d.cts.map +1 -0
- package/dist/ukyc/localUserSecret.d.mts +65 -0
- package/dist/ukyc/localUserSecret.d.mts.map +1 -0
- package/dist/ukyc/localUserSecret.mjs +92 -0
- package/dist/ukyc/localUserSecret.mjs.map +1 -0
- package/dist/ukyc/storageAccessToken.cjs +139 -0
- package/dist/ukyc/storageAccessToken.cjs.map +1 -0
- package/dist/ukyc/storageAccessToken.d.cts +99 -0
- package/dist/ukyc/storageAccessToken.d.cts.map +1 -0
- package/dist/ukyc/storageAccessToken.d.mts +99 -0
- package/dist/ukyc/storageAccessToken.d.mts.map +1 -0
- package/dist/ukyc/storageAccessToken.mjs +133 -0
- package/dist/ukyc/storageAccessToken.mjs.map +1 -0
- package/dist/ukyc/testToken.cjs +61 -0
- package/dist/ukyc/testToken.cjs.map +1 -0
- package/dist/ukyc/testToken.d.cts +50 -0
- package/dist/ukyc/testToken.d.cts.map +1 -0
- package/dist/ukyc/testToken.d.mts +50 -0
- package/dist/ukyc/testToken.d.mts.map +1 -0
- package/dist/ukyc/testToken.mjs +57 -0
- package/dist/ukyc/testToken.mjs.map +1 -0
- package/dist/ukyc/wrapEncryptionKey.cjs +28 -0
- package/dist/ukyc/wrapEncryptionKey.cjs.map +1 -0
- package/dist/ukyc/wrapEncryptionKey.d.cts +34 -0
- package/dist/ukyc/wrapEncryptionKey.d.cts.map +1 -0
- package/dist/ukyc/wrapEncryptionKey.d.mts +34 -0
- package/dist/ukyc/wrapEncryptionKey.d.mts.map +1 -0
- package/dist/ukyc/wrapEncryptionKey.mjs +25 -0
- package/dist/ukyc/wrapEncryptionKey.mjs.map +1 -0
- package/dist/ukyc/wrapUserKey.cjs +80 -0
- package/dist/ukyc/wrapUserKey.cjs.map +1 -0
- package/dist/ukyc/wrapUserKey.d.cts +26 -0
- package/dist/ukyc/wrapUserKey.d.cts.map +1 -0
- package/dist/ukyc/wrapUserKey.d.mts +26 -0
- package/dist/ukyc/wrapUserKey.d.mts.map +1 -0
- package/dist/ukyc/wrapUserKey.mjs +76 -0
- package/dist/ukyc/wrapUserKey.mjs.map +1 -0
- package/dist/ukyc/wrappedRelayPayload.cjs +32 -0
- package/dist/ukyc/wrappedRelayPayload.cjs.map +1 -0
- package/dist/ukyc/wrappedRelayPayload.d.cts +35 -0
- package/dist/ukyc/wrappedRelayPayload.d.cts.map +1 -0
- package/dist/ukyc/wrappedRelayPayload.d.mts +35 -0
- package/dist/ukyc/wrappedRelayPayload.d.mts.map +1 -0
- package/dist/ukyc/wrappedRelayPayload.mjs +28 -0
- package/dist/ukyc/wrappedRelayPayload.mjs.map +1 -0
- package/package.json +24 -3
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { base64ToBytes } from "@metamask/utils";
|
|
2
|
+
import { gcm } from "@noble/ciphers/aes";
|
|
3
|
+
import { x25519 } from "@noble/curves/ed25519";
|
|
4
|
+
import { hkdf } from "@noble/hashes/hkdf";
|
|
5
|
+
import { sha256 } from "@noble/hashes/sha2";
|
|
6
|
+
import { hexToBytes, randomBytes } from "@noble/hashes/utils";
|
|
7
|
+
import { toBase64Url } from "../encoding.mjs";
|
|
8
|
+
/**
|
|
9
|
+
* Wraps (encrypts) a symmetric key so that only the holder of a given X25519
|
|
10
|
+
* private key can recover it — used to seal the `data_encryption_key` for the
|
|
11
|
+
* idOS Relay before it is handed to the UKYC API as `wrappedUserKey`.
|
|
12
|
+
*/
|
|
13
|
+
/** X25519 public/private keys and AES-256-GCM keys are all 32 bytes. */
|
|
14
|
+
const X25519_KEY_SIZE_BYTES = 32;
|
|
15
|
+
/** 96-bit IV, the AES-GCM standard nonce size. */
|
|
16
|
+
const IV_SIZE_BYTES = 12;
|
|
17
|
+
/**
|
|
18
|
+
* Decodes an X25519 public key presented as either hex or base64/base64url.
|
|
19
|
+
*
|
|
20
|
+
* @param recipientPublicKey - The recipient's 32-byte X25519 public key.
|
|
21
|
+
* @returns The raw 32-byte public key.
|
|
22
|
+
*/
|
|
23
|
+
function decodePublicKey(recipientPublicKey) {
|
|
24
|
+
const isHex = recipientPublicKey.length === X25519_KEY_SIZE_BYTES * 2 &&
|
|
25
|
+
/^[0-9a-fA-F]+$/u.test(recipientPublicKey);
|
|
26
|
+
const bytes = isHex
|
|
27
|
+
? hexToBytes(recipientPublicKey)
|
|
28
|
+
: base64ToBytes(recipientPublicKey
|
|
29
|
+
.replace(/-/gu, '+')
|
|
30
|
+
.replace(/_/gu, '/')
|
|
31
|
+
.padEnd(recipientPublicKey.length +
|
|
32
|
+
((4 - (recipientPublicKey.length % 4)) % 4), '='));
|
|
33
|
+
if (bytes.length !== X25519_KEY_SIZE_BYTES) {
|
|
34
|
+
throw new Error(`UKYC: wrappingPublicKey has unexpected length ${bytes.length}, expected ${X25519_KEY_SIZE_BYTES}.`);
|
|
35
|
+
}
|
|
36
|
+
return bytes;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Wraps `keyToWrap` for the holder of `recipientPublicKey` using an
|
|
40
|
+
* ephemeral-static ECDH + AES-256-GCM sealed-box scheme:
|
|
41
|
+
*
|
|
42
|
+
* ephemeral = fresh X25519 keypair (one per call)
|
|
43
|
+
* shared = X25519(ephemeralPrivate, recipientPublic)
|
|
44
|
+
* aeadKey = HKDF-SHA256(shared, 32 bytes)
|
|
45
|
+
* iv = 12 random bytes
|
|
46
|
+
* ct = AES-256-GCM(aeadKey, iv).encrypt(keyToWrap) // ct includes tag
|
|
47
|
+
*
|
|
48
|
+
* The recipient reverses it with their private key:
|
|
49
|
+
*
|
|
50
|
+
* shared = X25519(recipientPrivate, ephemeralPublic)
|
|
51
|
+
* aeadKey = HKDF-SHA256(shared, 32 bytes)
|
|
52
|
+
* key = AES-256-GCM(aeadKey, iv).decrypt(ct)
|
|
53
|
+
*
|
|
54
|
+
* This mirrors the X25519 + AES-256-GCM/HKDF decryption used for MoonPay
|
|
55
|
+
* Check/Auth-frame credentials, so both directions share one primitive.
|
|
56
|
+
*
|
|
57
|
+
* @param recipientPublicKey - The recipient's X25519 public key (hex or base64).
|
|
58
|
+
* @param keyToWrap - The raw symmetric key bytes to encrypt (e.g. the
|
|
59
|
+
* `data_encryption_key`).
|
|
60
|
+
* @returns Base64url of `ephemeralPublicKey(32) || iv(12) || ciphertext+tag`.
|
|
61
|
+
*/
|
|
62
|
+
export function wrapUserKey(recipientPublicKey, keyToWrap) {
|
|
63
|
+
const recipient = decodePublicKey(recipientPublicKey);
|
|
64
|
+
const ephemeralPrivateKey = x25519.utils.randomSecretKey();
|
|
65
|
+
const ephemeralPublicKey = x25519.getPublicKey(ephemeralPrivateKey);
|
|
66
|
+
const shared = x25519.getSharedSecret(ephemeralPrivateKey, recipient);
|
|
67
|
+
const aeadKey = hkdf(sha256, shared, undefined, undefined, 32);
|
|
68
|
+
const iv = randomBytes(IV_SIZE_BYTES);
|
|
69
|
+
const ciphertext = gcm(aeadKey, iv).encrypt(keyToWrap);
|
|
70
|
+
const blob = new Uint8Array(ephemeralPublicKey.length + iv.length + ciphertext.length);
|
|
71
|
+
blob.set(ephemeralPublicKey, 0);
|
|
72
|
+
blob.set(iv, ephemeralPublicKey.length);
|
|
73
|
+
blob.set(ciphertext, ephemeralPublicKey.length + iv.length);
|
|
74
|
+
return toBase64Url(blob);
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=wrapUserKey.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wrapUserKey.mjs","sourceRoot":"","sources":["../../src/ukyc/wrapUserKey.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,wBAAwB;AAChD,OAAO,EAAE,GAAG,EAAE,2BAA2B;AACzC,OAAO,EAAE,MAAM,EAAE,8BAA8B;AAC/C,OAAO,EAAE,IAAI,EAAE,2BAA2B;AAC1C,OAAO,EAAE,MAAM,EAAE,2BAA2B;AAC5C,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,4BAA4B;AAE9D,OAAO,EAAE,WAAW,EAAE,wBAAuB;AAE7C;;;;GAIG;AAEH,wEAAwE;AACxE,MAAM,qBAAqB,GAAG,EAAE,CAAC;AAEjC,kDAAkD;AAClD,MAAM,aAAa,GAAG,EAAE,CAAC;AAEzB;;;;;GAKG;AACH,SAAS,eAAe,CAAC,kBAA0B;IACjD,MAAM,KAAK,GACT,kBAAkB,CAAC,MAAM,KAAK,qBAAqB,GAAG,CAAC;QACvD,iBAAiB,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;IAE7C,MAAM,KAAK,GAAG,KAAK;QACjB,CAAC,CAAC,UAAU,CAAC,kBAAkB,CAAC;QAChC,CAAC,CAAC,aAAa,CACX,kBAAkB;aACf,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC;aACnB,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC;aACnB,MAAM,CACL,kBAAkB,CAAC,MAAM;YACvB,CAAC,CAAC,CAAC,GAAG,CAAC,kBAAkB,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAC7C,GAAG,CACJ,CACJ,CAAC;IAEN,IAAI,KAAK,CAAC,MAAM,KAAK,qBAAqB,EAAE,CAAC;QAC3C,MAAM,IAAI,KAAK,CACb,iDAAiD,KAAK,CAAC,MAAM,cAAc,qBAAqB,GAAG,CACpG,CAAC;IACJ,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,UAAU,WAAW,CACzB,kBAA0B,EAC1B,SAAqB;IAErB,MAAM,SAAS,GAAG,eAAe,CAAC,kBAAkB,CAAC,CAAC;IAEtD,MAAM,mBAAmB,GAAG,MAAM,CAAC,KAAK,CAAC,eAAe,EAAE,CAAC;IAC3D,MAAM,kBAAkB,GAAG,MAAM,CAAC,YAAY,CAAC,mBAAmB,CAAC,CAAC;IAEpE,MAAM,MAAM,GAAG,MAAM,CAAC,eAAe,CAAC,mBAAmB,EAAE,SAAS,CAAC,CAAC;IACtE,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,EAAE,CAAC,CAAC;IAE/D,MAAM,EAAE,GAAG,WAAW,CAAC,aAAa,CAAC,CAAC;IACtC,MAAM,UAAU,GAAG,GAAG,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAEvD,MAAM,IAAI,GAAG,IAAI,UAAU,CACzB,kBAAkB,CAAC,MAAM,GAAG,EAAE,CAAC,MAAM,GAAG,UAAU,CAAC,MAAM,CAC1D,CAAC;IACF,IAAI,CAAC,GAAG,CAAC,kBAAkB,EAAE,CAAC,CAAC,CAAC;IAChC,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,kBAAkB,CAAC,MAAM,CAAC,CAAC;IACxC,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,kBAAkB,CAAC,MAAM,GAAG,EAAE,CAAC,MAAM,CAAC,CAAC;IAE5D,OAAO,WAAW,CAAC,IAAI,CAAC,CAAC;AAC3B,CAAC","sourcesContent":["import { base64ToBytes } from '@metamask/utils';\nimport { gcm } from '@noble/ciphers/aes';\nimport { x25519 } from '@noble/curves/ed25519';\nimport { hkdf } from '@noble/hashes/hkdf';\nimport { sha256 } from '@noble/hashes/sha2';\nimport { hexToBytes, randomBytes } from '@noble/hashes/utils';\n\nimport { toBase64Url } from '../encoding.js';\n\n/**\n * Wraps (encrypts) a symmetric key so that only the holder of a given X25519\n * private key can recover it — used to seal the `data_encryption_key` for the\n * idOS Relay before it is handed to the UKYC API as `wrappedUserKey`.\n */\n\n/** X25519 public/private keys and AES-256-GCM keys are all 32 bytes. */\nconst X25519_KEY_SIZE_BYTES = 32;\n\n/** 96-bit IV, the AES-GCM standard nonce size. */\nconst IV_SIZE_BYTES = 12;\n\n/**\n * Decodes an X25519 public key presented as either hex or base64/base64url.\n *\n * @param recipientPublicKey - The recipient's 32-byte X25519 public key.\n * @returns The raw 32-byte public key.\n */\nfunction decodePublicKey(recipientPublicKey: string): Uint8Array {\n const isHex =\n recipientPublicKey.length === X25519_KEY_SIZE_BYTES * 2 &&\n /^[0-9a-fA-F]+$/u.test(recipientPublicKey);\n\n const bytes = isHex\n ? hexToBytes(recipientPublicKey)\n : base64ToBytes(\n recipientPublicKey\n .replace(/-/gu, '+')\n .replace(/_/gu, '/')\n .padEnd(\n recipientPublicKey.length +\n ((4 - (recipientPublicKey.length % 4)) % 4),\n '=',\n ),\n );\n\n if (bytes.length !== X25519_KEY_SIZE_BYTES) {\n throw new Error(\n `UKYC: wrappingPublicKey has unexpected length ${bytes.length}, expected ${X25519_KEY_SIZE_BYTES}.`,\n );\n }\n return bytes;\n}\n\n/**\n * Wraps `keyToWrap` for the holder of `recipientPublicKey` using an\n * ephemeral-static ECDH + AES-256-GCM sealed-box scheme:\n *\n * ephemeral = fresh X25519 keypair (one per call)\n * shared = X25519(ephemeralPrivate, recipientPublic)\n * aeadKey = HKDF-SHA256(shared, 32 bytes)\n * iv = 12 random bytes\n * ct = AES-256-GCM(aeadKey, iv).encrypt(keyToWrap) // ct includes tag\n *\n * The recipient reverses it with their private key:\n *\n * shared = X25519(recipientPrivate, ephemeralPublic)\n * aeadKey = HKDF-SHA256(shared, 32 bytes)\n * key = AES-256-GCM(aeadKey, iv).decrypt(ct)\n *\n * This mirrors the X25519 + AES-256-GCM/HKDF decryption used for MoonPay\n * Check/Auth-frame credentials, so both directions share one primitive.\n *\n * @param recipientPublicKey - The recipient's X25519 public key (hex or base64).\n * @param keyToWrap - The raw symmetric key bytes to encrypt (e.g. the\n * `data_encryption_key`).\n * @returns Base64url of `ephemeralPublicKey(32) || iv(12) || ciphertext+tag`.\n */\nexport function wrapUserKey(\n recipientPublicKey: string,\n keyToWrap: Uint8Array,\n): string {\n const recipient = decodePublicKey(recipientPublicKey);\n\n const ephemeralPrivateKey = x25519.utils.randomSecretKey();\n const ephemeralPublicKey = x25519.getPublicKey(ephemeralPrivateKey);\n\n const shared = x25519.getSharedSecret(ephemeralPrivateKey, recipient);\n const aeadKey = hkdf(sha256, shared, undefined, undefined, 32);\n\n const iv = randomBytes(IV_SIZE_BYTES);\n const ciphertext = gcm(aeadKey, iv).encrypt(keyToWrap);\n\n const blob = new Uint8Array(\n ephemeralPublicKey.length + iv.length + ciphertext.length,\n );\n blob.set(ephemeralPublicKey, 0);\n blob.set(iv, ephemeralPublicKey.length);\n blob.set(ciphertext, ephemeralPublicKey.length + iv.length);\n\n return toBase64Url(blob);\n}\n"]}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.buildWrappedRelayPayload = void 0;
|
|
4
|
+
const encoding_js_1 = require("../encoding.cjs");
|
|
5
|
+
/**
|
|
6
|
+
* Assembles the `wrapped_relay_payload` from derived client material and a
|
|
7
|
+
* Relay-presented `storage_access_token`.
|
|
8
|
+
*
|
|
9
|
+
* The token must be scoped for the Relay to present (`presenter: 'idos-relay'`)
|
|
10
|
+
* and must not authorize `delete`, which is never delegated to the Relay.
|
|
11
|
+
*
|
|
12
|
+
* @param material - Client material derived from `local_user_secret`.
|
|
13
|
+
* @param storageAccessToken - A `read`/`write`-scoped, Relay-presented token.
|
|
14
|
+
* @returns The `wrapped_relay_payload` to send to the Relay via the UKYC API.
|
|
15
|
+
*/
|
|
16
|
+
function buildWrappedRelayPayload(material, storageAccessToken) {
|
|
17
|
+
const { presenter, operations } = storageAccessToken.payload;
|
|
18
|
+
if (presenter !== 'idos-relay') {
|
|
19
|
+
throw new Error('UKYC: wrapped_relay_payload requires a Relay-presented storage_access_token.');
|
|
20
|
+
}
|
|
21
|
+
if (operations.includes('delete')) {
|
|
22
|
+
throw new Error('UKYC: wrapped_relay_payload must not carry a delete-scoped storage_access_token.');
|
|
23
|
+
}
|
|
24
|
+
return {
|
|
25
|
+
storage_id: (0, encoding_js_1.toBase64Url)(material.storageId),
|
|
26
|
+
data_encryption_key: (0, encoding_js_1.toBase64Url)(material.dataEncryptionKey),
|
|
27
|
+
signing_public_key: (0, encoding_js_1.toBase64Url)(material.signingPublicKey),
|
|
28
|
+
storage_access_token: storageAccessToken,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
exports.buildWrappedRelayPayload = buildWrappedRelayPayload;
|
|
32
|
+
//# sourceMappingURL=wrappedRelayPayload.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wrappedRelayPayload.cjs","sourceRoot":"","sources":["../../src/ukyc/wrappedRelayPayload.ts"],"names":[],"mappings":";;;AACA,iDAA6C;AA4B7C;;;;;;;;;;GAUG;AACH,SAAgB,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,IAAA,yBAAW,EAAC,QAAQ,CAAC,SAAS,CAAC;QAC3C,mBAAmB,EAAE,IAAA,yBAAW,EAAC,QAAQ,CAAC,iBAAiB,CAAC;QAC5D,kBAAkB,EAAE,IAAA,yBAAW,EAAC,QAAQ,CAAC,gBAAgB,CAAC;QAC1D,oBAAoB,EAAE,kBAAkB;KACzC,CAAC;AACJ,CAAC;AAxBD,4DAwBC","sourcesContent":["import type { UkycClientMaterial } from './deriveClientMaterial.js';\nimport { toBase64Url } from '../encoding.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,35 @@
|
|
|
1
|
+
import type { UkycClientMaterial } from "./deriveClientMaterial.cjs";
|
|
2
|
+
import type { UkycStorageAccessToken } from "./storageAccessToken.cjs";
|
|
3
|
+
/**
|
|
4
|
+
* Builds the `wrapped_relay_payload` — the only client-derived material that
|
|
5
|
+
* leaves the device. It is sent to the idOS Relay (through the UKYC API) so the
|
|
6
|
+
* Relay can encrypt/decrypt and store KYC payloads on the user's behalf. See the
|
|
7
|
+
* architecture doc, section "Client-Derived Material".
|
|
8
|
+
*
|
|
9
|
+
* Neither `local_user_secret` nor the private `signing_key` are ever included.
|
|
10
|
+
* The `data_encryption_key` *is* included: it is intentionally shared with the
|
|
11
|
+
* Relay so it can encrypt/decrypt payloads transiently.
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* The Relay-facing bundle. `data_encryption_key` is base64url-encoded secret
|
|
15
|
+
* material shared with the Relay; the other fields are non-secret.
|
|
16
|
+
*/
|
|
17
|
+
export type UkycWrappedRelayPayload = {
|
|
18
|
+
storage_id: string;
|
|
19
|
+
data_encryption_key: string;
|
|
20
|
+
signing_public_key: string;
|
|
21
|
+
storage_access_token: UkycStorageAccessToken;
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Assembles the `wrapped_relay_payload` from derived client material and a
|
|
25
|
+
* Relay-presented `storage_access_token`.
|
|
26
|
+
*
|
|
27
|
+
* The token must be scoped for the Relay to present (`presenter: 'idos-relay'`)
|
|
28
|
+
* and must not authorize `delete`, which is never delegated to the Relay.
|
|
29
|
+
*
|
|
30
|
+
* @param material - Client material derived from `local_user_secret`.
|
|
31
|
+
* @param storageAccessToken - A `read`/`write`-scoped, Relay-presented token.
|
|
32
|
+
* @returns The `wrapped_relay_payload` to send to the Relay via the UKYC API.
|
|
33
|
+
*/
|
|
34
|
+
export declare function buildWrappedRelayPayload(material: UkycClientMaterial, storageAccessToken: UkycStorageAccessToken): UkycWrappedRelayPayload;
|
|
35
|
+
//# sourceMappingURL=wrappedRelayPayload.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wrappedRelayPayload.d.cts","sourceRoot":"","sources":["../../src/ukyc/wrappedRelayPayload.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,mCAAkC;AAEpE,OAAO,KAAK,EAAE,sBAAsB,EAAE,iCAAgC;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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { UkycClientMaterial } from "./deriveClientMaterial.mjs";
|
|
2
|
+
import type { UkycStorageAccessToken } from "./storageAccessToken.mjs";
|
|
3
|
+
/**
|
|
4
|
+
* Builds the `wrapped_relay_payload` — the only client-derived material that
|
|
5
|
+
* leaves the device. It is sent to the idOS Relay (through the UKYC API) so the
|
|
6
|
+
* Relay can encrypt/decrypt and store KYC payloads on the user's behalf. See the
|
|
7
|
+
* architecture doc, section "Client-Derived Material".
|
|
8
|
+
*
|
|
9
|
+
* Neither `local_user_secret` nor the private `signing_key` are ever included.
|
|
10
|
+
* The `data_encryption_key` *is* included: it is intentionally shared with the
|
|
11
|
+
* Relay so it can encrypt/decrypt payloads transiently.
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* The Relay-facing bundle. `data_encryption_key` is base64url-encoded secret
|
|
15
|
+
* material shared with the Relay; the other fields are non-secret.
|
|
16
|
+
*/
|
|
17
|
+
export type UkycWrappedRelayPayload = {
|
|
18
|
+
storage_id: string;
|
|
19
|
+
data_encryption_key: string;
|
|
20
|
+
signing_public_key: string;
|
|
21
|
+
storage_access_token: UkycStorageAccessToken;
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Assembles the `wrapped_relay_payload` from derived client material and a
|
|
25
|
+
* Relay-presented `storage_access_token`.
|
|
26
|
+
*
|
|
27
|
+
* The token must be scoped for the Relay to present (`presenter: 'idos-relay'`)
|
|
28
|
+
* and must not authorize `delete`, which is never delegated to the Relay.
|
|
29
|
+
*
|
|
30
|
+
* @param material - Client material derived from `local_user_secret`.
|
|
31
|
+
* @param storageAccessToken - A `read`/`write`-scoped, Relay-presented token.
|
|
32
|
+
* @returns The `wrapped_relay_payload` to send to the Relay via the UKYC API.
|
|
33
|
+
*/
|
|
34
|
+
export declare function buildWrappedRelayPayload(material: UkycClientMaterial, storageAccessToken: UkycStorageAccessToken): UkycWrappedRelayPayload;
|
|
35
|
+
//# sourceMappingURL=wrappedRelayPayload.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wrappedRelayPayload.d.mts","sourceRoot":"","sources":["../../src/ukyc/wrappedRelayPayload.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,mCAAkC;AAEpE,OAAO,KAAK,EAAE,sBAAsB,EAAE,iCAAgC;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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { toBase64Url } from "../encoding.mjs";
|
|
2
|
+
/**
|
|
3
|
+
* Assembles the `wrapped_relay_payload` from derived client material and a
|
|
4
|
+
* Relay-presented `storage_access_token`.
|
|
5
|
+
*
|
|
6
|
+
* The token must be scoped for the Relay to present (`presenter: 'idos-relay'`)
|
|
7
|
+
* and must not authorize `delete`, which is never delegated to the Relay.
|
|
8
|
+
*
|
|
9
|
+
* @param material - Client material derived from `local_user_secret`.
|
|
10
|
+
* @param storageAccessToken - A `read`/`write`-scoped, Relay-presented token.
|
|
11
|
+
* @returns The `wrapped_relay_payload` to send to the Relay via the UKYC API.
|
|
12
|
+
*/
|
|
13
|
+
export function buildWrappedRelayPayload(material, storageAccessToken) {
|
|
14
|
+
const { presenter, operations } = storageAccessToken.payload;
|
|
15
|
+
if (presenter !== 'idos-relay') {
|
|
16
|
+
throw new Error('UKYC: wrapped_relay_payload requires a Relay-presented storage_access_token.');
|
|
17
|
+
}
|
|
18
|
+
if (operations.includes('delete')) {
|
|
19
|
+
throw new Error('UKYC: wrapped_relay_payload must not carry a delete-scoped storage_access_token.');
|
|
20
|
+
}
|
|
21
|
+
return {
|
|
22
|
+
storage_id: toBase64Url(material.storageId),
|
|
23
|
+
data_encryption_key: toBase64Url(material.dataEncryptionKey),
|
|
24
|
+
signing_public_key: toBase64Url(material.signingPublicKey),
|
|
25
|
+
storage_access_token: storageAccessToken,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=wrappedRelayPayload.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wrappedRelayPayload.mjs","sourceRoot":"","sources":["../../src/ukyc/wrappedRelayPayload.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,wBAAuB;AA4B7C;;;;;;;;;;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 type { UkycClientMaterial } from './deriveClientMaterial.js';\nimport { toBase64Url } from '../encoding.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"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@metamask-previews/kyc-controller",
|
|
3
|
-
"version": "0.0.0-preview-
|
|
3
|
+
"version": "0.0.0-preview-e57e5c3dc",
|
|
4
4
|
"description": "Shared KYC / identity verification controller used across MetaMask clients",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"Ethereum",
|
|
@@ -42,24 +42,45 @@
|
|
|
42
42
|
"build": "ts-bridge --project tsconfig.build.json --verbose --clean --no-references",
|
|
43
43
|
"build:all": "ts-bridge --project tsconfig.build.json --verbose --clean",
|
|
44
44
|
"build:docs": "typedoc",
|
|
45
|
+
"build:watch": "yarn build && chokidar 'src/**/*.ts' -c 'ts-bridge --project tsconfig.build.json --verbose --no-references' --initial",
|
|
45
46
|
"changelog:update": "../../scripts/update-changelog.sh @metamask/kyc-controller",
|
|
46
47
|
"changelog:validate": "../../scripts/validate-changelog.sh @metamask/kyc-controller",
|
|
47
48
|
"lint:tsconfigs": "tsx ../../scripts/lint-tsconfigs/lint-tsconfigs.mts",
|
|
48
49
|
"lint:tsconfigs:fix": "tsx ../../scripts/lint-tsconfigs/lint-tsconfigs.mts --fix",
|
|
49
|
-
"messenger-action-types:check": "tsx ../../packages/messenger-cli/src/cli.ts --formatter oxfmt --check",
|
|
50
|
-
"messenger-action-types:generate": "tsx ../../packages/messenger-cli/src/cli.ts --formatter oxfmt --generate",
|
|
50
|
+
"messenger-action-types:check": "tsx ../../packages/messenger-cli/src/cli.ts --formatter oxfmt --esm --check",
|
|
51
|
+
"messenger-action-types:generate": "tsx ../../packages/messenger-cli/src/cli.ts --formatter oxfmt --esm --generate",
|
|
52
|
+
"mint:ukyc-token": "tsx scripts/mint-ukyc-test-token.ts",
|
|
51
53
|
"since-latest-release": "../../scripts/since-latest-release.sh",
|
|
52
54
|
"test": "NODE_OPTIONS=--experimental-vm-modules jest --reporters=jest-silent-reporter",
|
|
53
55
|
"test:clean": "NODE_OPTIONS=--experimental-vm-modules jest --clearCache",
|
|
54
56
|
"test:verbose": "NODE_OPTIONS=--experimental-vm-modules jest --verbose",
|
|
55
57
|
"test:watch": "NODE_OPTIONS=--experimental-vm-modules jest --watch"
|
|
56
58
|
},
|
|
59
|
+
"dependencies": {
|
|
60
|
+
"@metamask/base-controller": "^9.1.0",
|
|
61
|
+
"@metamask/base-data-service": "^0.1.3",
|
|
62
|
+
"@metamask/controller-utils": "^12.3.0",
|
|
63
|
+
"@metamask/geolocation-controller": "^1.0.0",
|
|
64
|
+
"@metamask/messenger": "^2.0.0",
|
|
65
|
+
"@metamask/profile-sync-controller": "^29.0.0",
|
|
66
|
+
"@metamask/superstruct": "^3.4.1",
|
|
67
|
+
"@metamask/utils": "^11.11.0",
|
|
68
|
+
"@noble/ciphers": "^1.3.0",
|
|
69
|
+
"@noble/curves": "^1.9.2",
|
|
70
|
+
"@noble/hashes": "^1.8.0",
|
|
71
|
+
"@scure/base": "^1.2.6",
|
|
72
|
+
"@tanstack/query-core": "^4.43.0",
|
|
73
|
+
"reselect": "^5.1.1",
|
|
74
|
+
"tweetnacl": "^1.0.3"
|
|
75
|
+
},
|
|
57
76
|
"devDependencies": {
|
|
58
77
|
"@metamask/auto-changelog": "^6.1.0",
|
|
59
78
|
"@ts-bridge/cli": "^0.6.4",
|
|
60
79
|
"@types/jest": "^30.0.0",
|
|
80
|
+
"chokidar-cli": "^3.0.0",
|
|
61
81
|
"deepmerge": "^4.2.2",
|
|
62
82
|
"jest": "^30.4.2",
|
|
83
|
+
"nock": "^13.3.1",
|
|
63
84
|
"ts-jest": "^29.4.11",
|
|
64
85
|
"tsx": "^4.20.5",
|
|
65
86
|
"typedoc": "^0.25.13",
|