@metamask-previews/kyc-controller 0.0.0-preview-11d78534e

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.
Files changed (78) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/LICENSE +6 -0
  3. package/LICENSE.APACHE2 +201 -0
  4. package/LICENSE.MIT +21 -0
  5. package/README.md +648 -0
  6. package/dist/KycController-method-action-types.cjs +7 -0
  7. package/dist/KycController-method-action-types.cjs.map +1 -0
  8. package/dist/KycController-method-action-types.d.cts +143 -0
  9. package/dist/KycController-method-action-types.d.cts.map +1 -0
  10. package/dist/KycController-method-action-types.d.mts +143 -0
  11. package/dist/KycController-method-action-types.d.mts.map +1 -0
  12. package/dist/KycController-method-action-types.mjs +6 -0
  13. package/dist/KycController-method-action-types.mjs.map +1 -0
  14. package/dist/KycController.cjs +800 -0
  15. package/dist/KycController.cjs.map +1 -0
  16. package/dist/KycController.d.cts +219 -0
  17. package/dist/KycController.d.cts.map +1 -0
  18. package/dist/KycController.d.mts +219 -0
  19. package/dist/KycController.d.mts.map +1 -0
  20. package/dist/KycController.mjs +795 -0
  21. package/dist/KycController.mjs.map +1 -0
  22. package/dist/KycService-method-action-types.cjs +7 -0
  23. package/dist/KycService-method-action-types.cjs.map +1 -0
  24. package/dist/KycService-method-action-types.d.cts +74 -0
  25. package/dist/KycService-method-action-types.d.cts.map +1 -0
  26. package/dist/KycService-method-action-types.d.mts +74 -0
  27. package/dist/KycService-method-action-types.d.mts.map +1 -0
  28. package/dist/KycService-method-action-types.mjs +6 -0
  29. package/dist/KycService-method-action-types.mjs.map +1 -0
  30. package/dist/KycService.cjs +238 -0
  31. package/dist/KycService.cjs.map +1 -0
  32. package/dist/KycService.d.cts +169 -0
  33. package/dist/KycService.d.cts.map +1 -0
  34. package/dist/KycService.d.mts +169 -0
  35. package/dist/KycService.d.mts.map +1 -0
  36. package/dist/KycService.mjs +234 -0
  37. package/dist/KycService.mjs.map +1 -0
  38. package/dist/countryCodes.cjs +274 -0
  39. package/dist/countryCodes.cjs.map +1 -0
  40. package/dist/countryCodes.d.cts +18 -0
  41. package/dist/countryCodes.d.cts.map +1 -0
  42. package/dist/countryCodes.d.mts +18 -0
  43. package/dist/countryCodes.d.mts.map +1 -0
  44. package/dist/countryCodes.mjs +270 -0
  45. package/dist/countryCodes.mjs.map +1 -0
  46. package/dist/crypto.cjs +165 -0
  47. package/dist/crypto.cjs.map +1 -0
  48. package/dist/crypto.d.cts +83 -0
  49. package/dist/crypto.d.cts.map +1 -0
  50. package/dist/crypto.d.mts +83 -0
  51. package/dist/crypto.d.mts.map +1 -0
  52. package/dist/crypto.mjs +160 -0
  53. package/dist/crypto.mjs.map +1 -0
  54. package/dist/index.cjs +21 -0
  55. package/dist/index.cjs.map +1 -0
  56. package/dist/index.d.cts +12 -0
  57. package/dist/index.d.cts.map +1 -0
  58. package/dist/index.d.mts +12 -0
  59. package/dist/index.d.mts.map +1 -0
  60. package/dist/index.mjs +6 -0
  61. package/dist/index.mjs.map +1 -0
  62. package/dist/selectors.cjs +30 -0
  63. package/dist/selectors.cjs.map +1 -0
  64. package/dist/selectors.d.cts +24 -0
  65. package/dist/selectors.d.cts.map +1 -0
  66. package/dist/selectors.d.mts +24 -0
  67. package/dist/selectors.d.mts.map +1 -0
  68. package/dist/selectors.mjs +24 -0
  69. package/dist/selectors.mjs.map +1 -0
  70. package/dist/types.cjs +10 -0
  71. package/dist/types.cjs.map +1 -0
  72. package/dist/types.d.cts +93 -0
  73. package/dist/types.d.cts.map +1 -0
  74. package/dist/types.d.mts +93 -0
  75. package/dist/types.d.mts.map +1 -0
  76. package/dist/types.mjs +9 -0
  77. package/dist/types.mjs.map +1 -0
  78. package/package.json +89 -0
@@ -0,0 +1,165 @@
1
+ "use strict";
2
+ /**
3
+ * Check / Auth frame key exchange and credential decryption.
4
+ *
5
+ * The identity vendor's Check and Auth frames return encrypted credentials.
6
+ * The confirmed protocol is X25519 ECDH + AES-256-GCM (an "ECDH-ES" pattern
7
+ * signalled by a 12-byte IV):
8
+ *
9
+ * 1. Client generates an X25519 keypair, sends `publicKey` (hex) into the
10
+ * frame as a URL param.
11
+ * 2. Frame generates its own ephemeral X25519 keypair and encrypts the
12
+ * credentials, returning `{ ephemeralPublicKey, iv, ciphertext }`.
13
+ * 3. Client reverses:
14
+ * shared = X25519(ourPrivate, theirEphemeralPublic)
15
+ * key = HKDF-SHA256(shared, salt=none, info=none, 32 bytes)
16
+ * plain = AES-256-GCM.decrypt(key, iv, ciphertext || 16-byte tag)
17
+ *
18
+ * This module is platform-agnostic: it uses `@noble/*` + `@scure/base` and
19
+ * avoids `Buffer` / `atob` so it runs unchanged on mobile, extension, and web.
20
+ */
21
+ Object.defineProperty(exports, "__esModule", { value: true });
22
+ exports.decryptCredentials = exports.generateKeyPair = void 0;
23
+ const aes_1 = require("@noble/ciphers/aes");
24
+ const ed25519_1 = require("@noble/curves/ed25519");
25
+ const hkdf_1 = require("@noble/hashes/hkdf");
26
+ const sha2_1 = require("@noble/hashes/sha2");
27
+ const utils_1 = require("@noble/hashes/utils");
28
+ const base_1 = require("@scure/base");
29
+ /**
30
+ * Generate a fresh X25519 keypair. The private key never leaves the device;
31
+ * only `publicKeyHex` is sent to the vendor via the frame URL.
32
+ *
33
+ * @returns The generated keypair.
34
+ */
35
+ function generateKeyPair() {
36
+ const privateKey = ed25519_1.x25519.utils.randomSecretKey();
37
+ const publicKey = ed25519_1.x25519.getPublicKey(privateKey);
38
+ return {
39
+ privateKey,
40
+ publicKey,
41
+ publicKeyHex: (0, utils_1.bytesToHex)(publicKey),
42
+ };
43
+ }
44
+ exports.generateKeyPair = generateKeyPair;
45
+ /**
46
+ * Decode a base64 / base64url string to bytes without relying on `atob` or
47
+ * `Buffer`.
48
+ *
49
+ * @param value - The (possibly url-safe, possibly unpadded) base64 string.
50
+ * @returns The decoded bytes.
51
+ */
52
+ function base64ToBytes(value) {
53
+ const normalized = value.replace(/-/gu, '+').replace(/_/gu, '/');
54
+ const padded = normalized.padEnd(normalized.length + ((4 - (normalized.length % 4)) % 4), '=');
55
+ return base_1.base64.decode(padded);
56
+ }
57
+ /**
58
+ * Decode a binary envelope field that may be hex or base64.
59
+ *
60
+ * @param value - The encoded field.
61
+ * @param encoding - Optional explicit encoding; auto-detected when omitted.
62
+ * @returns The decoded bytes.
63
+ */
64
+ function decodeBinary(value, encoding) {
65
+ const isHex = encoding === 'hex' ||
66
+ (encoding === undefined && /^[0-9a-fA-F]+$/u.test(value));
67
+ if (isHex) {
68
+ return (0, utils_1.hexToBytes)(value);
69
+ }
70
+ return base64ToBytes(value);
71
+ }
72
+ /**
73
+ * Coerce the `credentials` field into a structured envelope. The frame may
74
+ * deliver it as an object, a JSON string, or base64(JSON).
75
+ *
76
+ * @param input - The raw credentials value.
77
+ * @returns The normalized envelope.
78
+ * @throws If the value is not a structured or base64(JSON) envelope, or is
79
+ * missing required fields.
80
+ */
81
+ function normalizeEnvelope(input) {
82
+ let value = input;
83
+ if (typeof value === 'string') {
84
+ const trimmed = value.trim();
85
+ if (trimmed.startsWith('{')) {
86
+ try {
87
+ value = JSON.parse(trimmed);
88
+ }
89
+ catch {
90
+ throw new Error(`credentials looked like JSON but failed to parse (preview: "${trimmed.slice(0, 64)}").`);
91
+ }
92
+ }
93
+ else {
94
+ let decodedText = null;
95
+ try {
96
+ decodedText = new TextDecoder().decode(base64ToBytes(trimmed));
97
+ }
98
+ catch {
99
+ decodedText = null;
100
+ }
101
+ const decodedTrimmed = decodedText?.trim();
102
+ if (decodedTrimmed?.startsWith('{')) {
103
+ try {
104
+ value = JSON.parse(decodedTrimmed);
105
+ }
106
+ catch {
107
+ throw new Error(`credentials base64-decoded to non-JSON (preview: "${decodedTrimmed.slice(0, 64)}").`);
108
+ }
109
+ }
110
+ else {
111
+ throw new Error(`credentials is an opaque string, not a structured or base64(JSON) envelope (preview: "${trimmed.slice(0, 64)}").`);
112
+ }
113
+ }
114
+ }
115
+ const env = value;
116
+ if (!env.ephemeralPublicKey || !(env.iv ?? env.nonce) || !env.ciphertext) {
117
+ const keys = value && typeof value === 'object'
118
+ ? Object.keys(value).join(', ')
119
+ : typeof value;
120
+ throw new Error(`credentials envelope missing required fields (ephemeralPublicKey/iv/ciphertext). Got: ${keys}`);
121
+ }
122
+ return env;
123
+ }
124
+ /**
125
+ * X25519 ECDH to AES-256-GCM decryption.
126
+ *
127
+ * @param theirPublicKey - The frame's ephemeral public key.
128
+ * @param iv - The 12-byte GCM IV.
129
+ * @param ciphertext - The ciphertext including the 16-byte auth tag.
130
+ * @param ourPrivateKey - Our X25519 private key.
131
+ * @returns The decrypted credentials and method.
132
+ */
133
+ function aesGcmDecrypt(theirPublicKey, iv, ciphertext, ourPrivateKey) {
134
+ const shared = ed25519_1.x25519.getSharedSecret(ourPrivateKey, theirPublicKey);
135
+ const key = (0, hkdf_1.hkdf)(sha2_1.sha256, shared, undefined, undefined, 32);
136
+ const plaintext = (0, aes_1.gcm)(key, iv).decrypt(ciphertext);
137
+ const text = new TextDecoder().decode(plaintext);
138
+ return {
139
+ credentials: JSON.parse(text),
140
+ method: 'aes-256-gcm/hkdf-sha256',
141
+ };
142
+ }
143
+ /**
144
+ * Decrypt a Check/Auth frame credentials envelope using our X25519 private
145
+ * key.
146
+ *
147
+ * @param rawEnvelope - The raw envelope (object, JSON string, or base64(JSON)).
148
+ * @param ourPrivateKey - Our X25519 private key.
149
+ * @returns The parsed credentials and the method that authenticated.
150
+ * @throws If the envelope is malformed or the IV length is not 12 bytes.
151
+ */
152
+ function decryptCredentials(rawEnvelope, ourPrivateKey) {
153
+ const envelope = normalizeEnvelope(rawEnvelope);
154
+ const theirPublicKey = decodeBinary(envelope.ephemeralPublicKey, envelope.encoding);
155
+ // `normalizeEnvelope` guarantees one of `iv` / `nonce` is present.
156
+ const ivField = (envelope.iv ?? envelope.nonce);
157
+ const iv = decodeBinary(ivField, envelope.encoding);
158
+ const ciphertext = decodeBinary(envelope.ciphertext, envelope.encoding);
159
+ if (iv.length !== 12) {
160
+ throw new Error(`Unexpected IV length ${iv.length} (expected 12 for AES-256-GCM).`);
161
+ }
162
+ return aesGcmDecrypt(theirPublicKey, iv, ciphertext, ourPrivateKey);
163
+ }
164
+ exports.decryptCredentials = decryptCredentials;
165
+ //# sourceMappingURL=crypto.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crypto.cjs","sourceRoot":"","sources":["../src/crypto.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Check / Auth frame key exchange and credential decryption.\n *\n * The identity vendor's Check and Auth frames return encrypted credentials.\n * The confirmed protocol is X25519 ECDH + AES-256-GCM (an \"ECDH-ES\" pattern\n * signalled by a 12-byte IV):\n *\n * 1. Client generates an X25519 keypair, sends `publicKey` (hex) into the\n * frame as a URL param.\n * 2. Frame generates its own ephemeral X25519 keypair and encrypts the\n * credentials, returning `{ ephemeralPublicKey, iv, ciphertext }`.\n * 3. Client reverses:\n * shared = X25519(ourPrivate, theirEphemeralPublic)\n * key = HKDF-SHA256(shared, salt=none, info=none, 32 bytes)\n * plain = AES-256-GCM.decrypt(key, iv, ciphertext || 16-byte tag)\n *\n * This module is platform-agnostic: it uses `@noble/*` + `@scure/base` and\n * avoids `Buffer` / `atob` so it runs unchanged on mobile, extension, and web.\n */\n\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 { bytesToHex, hexToBytes } from '@noble/hashes/utils';\nimport { base64 } from '@scure/base';\n\n/**\n * An X25519 keypair used for the Check/Auth frame key exchange.\n */\nexport type X25519KeyPair = {\n /** Raw 32-byte X25519 private (scalar) key. Never leaves the device. */\n privateKey: Uint8Array;\n /** Raw 32-byte X25519 public key. */\n publicKey: Uint8Array;\n /** Hex-encoded public key, ready to drop into a Check/Auth frame URL. */\n publicKeyHex: string;\n};\n\n/**\n * The encrypted-credentials envelope returned by the Check/Auth frames. Binary\n * fields may be hex or base64; the IV field may be named `iv` or `nonce`.\n */\nexport type EncryptedCredentialsEnvelope = {\n /** Ephemeral public key produced by the frame for this exchange (32 bytes). */\n ephemeralPublicKey: string;\n /** Per-message IV. May be provided as `iv` or `nonce`. */\n iv?: string;\n nonce?: string;\n /** Ciphertext (plaintext + 16-byte GCM auth tag). */\n ciphertext: string;\n /** Optional explicit encoding hint. Defaults to auto-detect. */\n encoding?: 'hex' | 'base64';\n};\n\n/**\n * Decrypted Check/Auth frame credentials.\n *\n * - `accessToken` is the Bearer token for the identity API.\n * - `clientToken` is the short-lived token consumed by the Auth frame when the\n * Check frame returns `connectionRequired`.\n */\nexport type DecryptedCredentials = {\n accessToken?: string;\n clientToken?: string;\n [key: string]: unknown;\n};\n\n/**\n * Result of a successful decryption — the credentials plus the `method` that\n * authenticated.\n */\nexport type DecryptResult = {\n credentials: DecryptedCredentials;\n method: string;\n};\n\n/**\n * Generate a fresh X25519 keypair. The private key never leaves the device;\n * only `publicKeyHex` is sent to the vendor via the frame URL.\n *\n * @returns The generated keypair.\n */\nexport function generateKeyPair(): X25519KeyPair {\n const privateKey = x25519.utils.randomSecretKey();\n const publicKey = x25519.getPublicKey(privateKey);\n return {\n privateKey,\n publicKey,\n publicKeyHex: bytesToHex(publicKey),\n };\n}\n\n/**\n * Decode a base64 / base64url string to bytes without relying on `atob` or\n * `Buffer`.\n *\n * @param value - The (possibly url-safe, possibly unpadded) base64 string.\n * @returns The decoded bytes.\n */\nfunction base64ToBytes(value: string): Uint8Array {\n const normalized = value.replace(/-/gu, '+').replace(/_/gu, '/');\n const padded = normalized.padEnd(\n normalized.length + ((4 - (normalized.length % 4)) % 4),\n '=',\n );\n return base64.decode(padded);\n}\n\n/**\n * Decode a binary envelope field that may be hex or base64.\n *\n * @param value - The encoded field.\n * @param encoding - Optional explicit encoding; auto-detected when omitted.\n * @returns The decoded bytes.\n */\nfunction decodeBinary(value: string, encoding?: 'hex' | 'base64'): Uint8Array {\n const isHex =\n encoding === 'hex' ||\n (encoding === undefined && /^[0-9a-fA-F]+$/u.test(value));\n if (isHex) {\n return hexToBytes(value);\n }\n return base64ToBytes(value);\n}\n\n/**\n * Coerce the `credentials` field into a structured envelope. The frame may\n * deliver it as an object, a JSON string, or base64(JSON).\n *\n * @param input - The raw credentials value.\n * @returns The normalized envelope.\n * @throws If the value is not a structured or base64(JSON) envelope, or is\n * missing required fields.\n */\nfunction normalizeEnvelope(\n input: EncryptedCredentialsEnvelope | string,\n): EncryptedCredentialsEnvelope {\n let value: unknown = input;\n\n if (typeof value === 'string') {\n const trimmed = value.trim();\n if (trimmed.startsWith('{')) {\n try {\n value = JSON.parse(trimmed);\n } catch {\n throw new Error(\n `credentials looked like JSON but failed to parse (preview: \"${trimmed.slice(\n 0,\n 64,\n )}\").`,\n );\n }\n } else {\n let decodedText: string | null = null;\n try {\n decodedText = new TextDecoder().decode(base64ToBytes(trimmed));\n } catch {\n decodedText = null;\n }\n const decodedTrimmed = decodedText?.trim();\n if (decodedTrimmed?.startsWith('{')) {\n try {\n value = JSON.parse(decodedTrimmed);\n } catch {\n throw new Error(\n `credentials base64-decoded to non-JSON (preview: \"${decodedTrimmed.slice(\n 0,\n 64,\n )}\").`,\n );\n }\n } else {\n throw new Error(\n `credentials is an opaque string, not a structured or base64(JSON) envelope (preview: \"${trimmed.slice(\n 0,\n 64,\n )}\").`,\n );\n }\n }\n }\n\n const env = value as Partial<EncryptedCredentialsEnvelope>;\n if (!env.ephemeralPublicKey || !(env.iv ?? env.nonce) || !env.ciphertext) {\n const keys =\n value && typeof value === 'object'\n ? Object.keys(value).join(', ')\n : typeof value;\n throw new Error(\n `credentials envelope missing required fields (ephemeralPublicKey/iv/ciphertext). Got: ${keys}`,\n );\n }\n return env as EncryptedCredentialsEnvelope;\n}\n\n/**\n * X25519 ECDH to AES-256-GCM decryption.\n *\n * @param theirPublicKey - The frame's ephemeral public key.\n * @param iv - The 12-byte GCM IV.\n * @param ciphertext - The ciphertext including the 16-byte auth tag.\n * @param ourPrivateKey - Our X25519 private key.\n * @returns The decrypted credentials and method.\n */\nfunction aesGcmDecrypt(\n theirPublicKey: Uint8Array,\n iv: Uint8Array,\n ciphertext: Uint8Array,\n ourPrivateKey: Uint8Array,\n): DecryptResult {\n const shared = x25519.getSharedSecret(ourPrivateKey, theirPublicKey);\n const key = hkdf(sha256, shared, undefined, undefined, 32);\n const plaintext = gcm(key, iv).decrypt(ciphertext);\n const text = new TextDecoder().decode(plaintext);\n return {\n credentials: JSON.parse(text) as DecryptedCredentials,\n method: 'aes-256-gcm/hkdf-sha256',\n };\n}\n\n/**\n * Decrypt a Check/Auth frame credentials envelope using our X25519 private\n * key.\n *\n * @param rawEnvelope - The raw envelope (object, JSON string, or base64(JSON)).\n * @param ourPrivateKey - Our X25519 private key.\n * @returns The parsed credentials and the method that authenticated.\n * @throws If the envelope is malformed or the IV length is not 12 bytes.\n */\nexport function decryptCredentials(\n rawEnvelope: EncryptedCredentialsEnvelope | string,\n ourPrivateKey: Uint8Array,\n): DecryptResult {\n const envelope = normalizeEnvelope(rawEnvelope);\n const theirPublicKey = decodeBinary(\n envelope.ephemeralPublicKey,\n envelope.encoding,\n );\n // `normalizeEnvelope` guarantees one of `iv` / `nonce` is present.\n const ivField = (envelope.iv ?? envelope.nonce) as string;\n const iv = decodeBinary(ivField, envelope.encoding);\n const ciphertext = decodeBinary(envelope.ciphertext, envelope.encoding);\n\n if (iv.length !== 12) {\n throw new Error(\n `Unexpected IV length ${iv.length} (expected 12 for AES-256-GCM).`,\n );\n }\n\n return aesGcmDecrypt(theirPublicKey, iv, ciphertext, ourPrivateKey);\n}\n"]}
@@ -0,0 +1,83 @@
1
+ /**
2
+ * Check / Auth frame key exchange and credential decryption.
3
+ *
4
+ * The identity vendor's Check and Auth frames return encrypted credentials.
5
+ * The confirmed protocol is X25519 ECDH + AES-256-GCM (an "ECDH-ES" pattern
6
+ * signalled by a 12-byte IV):
7
+ *
8
+ * 1. Client generates an X25519 keypair, sends `publicKey` (hex) into the
9
+ * frame as a URL param.
10
+ * 2. Frame generates its own ephemeral X25519 keypair and encrypts the
11
+ * credentials, returning `{ ephemeralPublicKey, iv, ciphertext }`.
12
+ * 3. Client reverses:
13
+ * shared = X25519(ourPrivate, theirEphemeralPublic)
14
+ * key = HKDF-SHA256(shared, salt=none, info=none, 32 bytes)
15
+ * plain = AES-256-GCM.decrypt(key, iv, ciphertext || 16-byte tag)
16
+ *
17
+ * This module is platform-agnostic: it uses `@noble/*` + `@scure/base` and
18
+ * avoids `Buffer` / `atob` so it runs unchanged on mobile, extension, and web.
19
+ */
20
+ /**
21
+ * An X25519 keypair used for the Check/Auth frame key exchange.
22
+ */
23
+ export type X25519KeyPair = {
24
+ /** Raw 32-byte X25519 private (scalar) key. Never leaves the device. */
25
+ privateKey: Uint8Array;
26
+ /** Raw 32-byte X25519 public key. */
27
+ publicKey: Uint8Array;
28
+ /** Hex-encoded public key, ready to drop into a Check/Auth frame URL. */
29
+ publicKeyHex: string;
30
+ };
31
+ /**
32
+ * The encrypted-credentials envelope returned by the Check/Auth frames. Binary
33
+ * fields may be hex or base64; the IV field may be named `iv` or `nonce`.
34
+ */
35
+ export type EncryptedCredentialsEnvelope = {
36
+ /** Ephemeral public key produced by the frame for this exchange (32 bytes). */
37
+ ephemeralPublicKey: string;
38
+ /** Per-message IV. May be provided as `iv` or `nonce`. */
39
+ iv?: string;
40
+ nonce?: string;
41
+ /** Ciphertext (plaintext + 16-byte GCM auth tag). */
42
+ ciphertext: string;
43
+ /** Optional explicit encoding hint. Defaults to auto-detect. */
44
+ encoding?: 'hex' | 'base64';
45
+ };
46
+ /**
47
+ * Decrypted Check/Auth frame credentials.
48
+ *
49
+ * - `accessToken` is the Bearer token for the identity API.
50
+ * - `clientToken` is the short-lived token consumed by the Auth frame when the
51
+ * Check frame returns `connectionRequired`.
52
+ */
53
+ export type DecryptedCredentials = {
54
+ accessToken?: string;
55
+ clientToken?: string;
56
+ [key: string]: unknown;
57
+ };
58
+ /**
59
+ * Result of a successful decryption — the credentials plus the `method` that
60
+ * authenticated.
61
+ */
62
+ export type DecryptResult = {
63
+ credentials: DecryptedCredentials;
64
+ method: string;
65
+ };
66
+ /**
67
+ * Generate a fresh X25519 keypair. The private key never leaves the device;
68
+ * only `publicKeyHex` is sent to the vendor via the frame URL.
69
+ *
70
+ * @returns The generated keypair.
71
+ */
72
+ export declare function generateKeyPair(): X25519KeyPair;
73
+ /**
74
+ * Decrypt a Check/Auth frame credentials envelope using our X25519 private
75
+ * key.
76
+ *
77
+ * @param rawEnvelope - The raw envelope (object, JSON string, or base64(JSON)).
78
+ * @param ourPrivateKey - Our X25519 private key.
79
+ * @returns The parsed credentials and the method that authenticated.
80
+ * @throws If the envelope is malformed or the IV length is not 12 bytes.
81
+ */
82
+ export declare function decryptCredentials(rawEnvelope: EncryptedCredentialsEnvelope | string, ourPrivateKey: Uint8Array): DecryptResult;
83
+ //# sourceMappingURL=crypto.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crypto.d.cts","sourceRoot":"","sources":["../src/crypto.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AASH;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG;IAC1B,wEAAwE;IACxE,UAAU,EAAE,UAAU,CAAC;IACvB,qCAAqC;IACrC,SAAS,EAAE,UAAU,CAAC;IACtB,yEAAyE;IACzE,YAAY,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,4BAA4B,GAAG;IACzC,+EAA+E;IAC/E,kBAAkB,EAAE,MAAM,CAAC;IAC3B,0DAA0D;IAC1D,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,qDAAqD;IACrD,UAAU,EAAE,MAAM,CAAC;IACnB,gEAAgE;IAChE,QAAQ,CAAC,EAAE,KAAK,GAAG,QAAQ,CAAC;CAC7B,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,MAAM,oBAAoB,GAAG;IACjC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,aAAa,GAAG;IAC1B,WAAW,EAAE,oBAAoB,CAAC;IAClC,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,eAAe,IAAI,aAAa,CAQ/C;AAkID;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAChC,WAAW,EAAE,4BAA4B,GAAG,MAAM,EAClD,aAAa,EAAE,UAAU,GACxB,aAAa,CAkBf"}
@@ -0,0 +1,83 @@
1
+ /**
2
+ * Check / Auth frame key exchange and credential decryption.
3
+ *
4
+ * The identity vendor's Check and Auth frames return encrypted credentials.
5
+ * The confirmed protocol is X25519 ECDH + AES-256-GCM (an "ECDH-ES" pattern
6
+ * signalled by a 12-byte IV):
7
+ *
8
+ * 1. Client generates an X25519 keypair, sends `publicKey` (hex) into the
9
+ * frame as a URL param.
10
+ * 2. Frame generates its own ephemeral X25519 keypair and encrypts the
11
+ * credentials, returning `{ ephemeralPublicKey, iv, ciphertext }`.
12
+ * 3. Client reverses:
13
+ * shared = X25519(ourPrivate, theirEphemeralPublic)
14
+ * key = HKDF-SHA256(shared, salt=none, info=none, 32 bytes)
15
+ * plain = AES-256-GCM.decrypt(key, iv, ciphertext || 16-byte tag)
16
+ *
17
+ * This module is platform-agnostic: it uses `@noble/*` + `@scure/base` and
18
+ * avoids `Buffer` / `atob` so it runs unchanged on mobile, extension, and web.
19
+ */
20
+ /**
21
+ * An X25519 keypair used for the Check/Auth frame key exchange.
22
+ */
23
+ export type X25519KeyPair = {
24
+ /** Raw 32-byte X25519 private (scalar) key. Never leaves the device. */
25
+ privateKey: Uint8Array;
26
+ /** Raw 32-byte X25519 public key. */
27
+ publicKey: Uint8Array;
28
+ /** Hex-encoded public key, ready to drop into a Check/Auth frame URL. */
29
+ publicKeyHex: string;
30
+ };
31
+ /**
32
+ * The encrypted-credentials envelope returned by the Check/Auth frames. Binary
33
+ * fields may be hex or base64; the IV field may be named `iv` or `nonce`.
34
+ */
35
+ export type EncryptedCredentialsEnvelope = {
36
+ /** Ephemeral public key produced by the frame for this exchange (32 bytes). */
37
+ ephemeralPublicKey: string;
38
+ /** Per-message IV. May be provided as `iv` or `nonce`. */
39
+ iv?: string;
40
+ nonce?: string;
41
+ /** Ciphertext (plaintext + 16-byte GCM auth tag). */
42
+ ciphertext: string;
43
+ /** Optional explicit encoding hint. Defaults to auto-detect. */
44
+ encoding?: 'hex' | 'base64';
45
+ };
46
+ /**
47
+ * Decrypted Check/Auth frame credentials.
48
+ *
49
+ * - `accessToken` is the Bearer token for the identity API.
50
+ * - `clientToken` is the short-lived token consumed by the Auth frame when the
51
+ * Check frame returns `connectionRequired`.
52
+ */
53
+ export type DecryptedCredentials = {
54
+ accessToken?: string;
55
+ clientToken?: string;
56
+ [key: string]: unknown;
57
+ };
58
+ /**
59
+ * Result of a successful decryption — the credentials plus the `method` that
60
+ * authenticated.
61
+ */
62
+ export type DecryptResult = {
63
+ credentials: DecryptedCredentials;
64
+ method: string;
65
+ };
66
+ /**
67
+ * Generate a fresh X25519 keypair. The private key never leaves the device;
68
+ * only `publicKeyHex` is sent to the vendor via the frame URL.
69
+ *
70
+ * @returns The generated keypair.
71
+ */
72
+ export declare function generateKeyPair(): X25519KeyPair;
73
+ /**
74
+ * Decrypt a Check/Auth frame credentials envelope using our X25519 private
75
+ * key.
76
+ *
77
+ * @param rawEnvelope - The raw envelope (object, JSON string, or base64(JSON)).
78
+ * @param ourPrivateKey - Our X25519 private key.
79
+ * @returns The parsed credentials and the method that authenticated.
80
+ * @throws If the envelope is malformed or the IV length is not 12 bytes.
81
+ */
82
+ export declare function decryptCredentials(rawEnvelope: EncryptedCredentialsEnvelope | string, ourPrivateKey: Uint8Array): DecryptResult;
83
+ //# sourceMappingURL=crypto.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crypto.d.mts","sourceRoot":"","sources":["../src/crypto.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AASH;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG;IAC1B,wEAAwE;IACxE,UAAU,EAAE,UAAU,CAAC;IACvB,qCAAqC;IACrC,SAAS,EAAE,UAAU,CAAC;IACtB,yEAAyE;IACzE,YAAY,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,4BAA4B,GAAG;IACzC,+EAA+E;IAC/E,kBAAkB,EAAE,MAAM,CAAC;IAC3B,0DAA0D;IAC1D,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,qDAAqD;IACrD,UAAU,EAAE,MAAM,CAAC;IACnB,gEAAgE;IAChE,QAAQ,CAAC,EAAE,KAAK,GAAG,QAAQ,CAAC;CAC7B,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,MAAM,oBAAoB,GAAG;IACjC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,aAAa,GAAG;IAC1B,WAAW,EAAE,oBAAoB,CAAC;IAClC,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,eAAe,IAAI,aAAa,CAQ/C;AAkID;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAChC,WAAW,EAAE,4BAA4B,GAAG,MAAM,EAClD,aAAa,EAAE,UAAU,GACxB,aAAa,CAkBf"}
@@ -0,0 +1,160 @@
1
+ /**
2
+ * Check / Auth frame key exchange and credential decryption.
3
+ *
4
+ * The identity vendor's Check and Auth frames return encrypted credentials.
5
+ * The confirmed protocol is X25519 ECDH + AES-256-GCM (an "ECDH-ES" pattern
6
+ * signalled by a 12-byte IV):
7
+ *
8
+ * 1. Client generates an X25519 keypair, sends `publicKey` (hex) into the
9
+ * frame as a URL param.
10
+ * 2. Frame generates its own ephemeral X25519 keypair and encrypts the
11
+ * credentials, returning `{ ephemeralPublicKey, iv, ciphertext }`.
12
+ * 3. Client reverses:
13
+ * shared = X25519(ourPrivate, theirEphemeralPublic)
14
+ * key = HKDF-SHA256(shared, salt=none, info=none, 32 bytes)
15
+ * plain = AES-256-GCM.decrypt(key, iv, ciphertext || 16-byte tag)
16
+ *
17
+ * This module is platform-agnostic: it uses `@noble/*` + `@scure/base` and
18
+ * avoids `Buffer` / `atob` so it runs unchanged on mobile, extension, and web.
19
+ */
20
+ import { gcm } from "@noble/ciphers/aes";
21
+ import { x25519 } from "@noble/curves/ed25519";
22
+ import { hkdf } from "@noble/hashes/hkdf";
23
+ import { sha256 } from "@noble/hashes/sha2";
24
+ import { bytesToHex, hexToBytes } from "@noble/hashes/utils";
25
+ import { base64 } from "@scure/base";
26
+ /**
27
+ * Generate a fresh X25519 keypair. The private key never leaves the device;
28
+ * only `publicKeyHex` is sent to the vendor via the frame URL.
29
+ *
30
+ * @returns The generated keypair.
31
+ */
32
+ export function generateKeyPair() {
33
+ const privateKey = x25519.utils.randomSecretKey();
34
+ const publicKey = x25519.getPublicKey(privateKey);
35
+ return {
36
+ privateKey,
37
+ publicKey,
38
+ publicKeyHex: bytesToHex(publicKey),
39
+ };
40
+ }
41
+ /**
42
+ * Decode a base64 / base64url string to bytes without relying on `atob` or
43
+ * `Buffer`.
44
+ *
45
+ * @param value - The (possibly url-safe, possibly unpadded) base64 string.
46
+ * @returns The decoded bytes.
47
+ */
48
+ function base64ToBytes(value) {
49
+ const normalized = value.replace(/-/gu, '+').replace(/_/gu, '/');
50
+ const padded = normalized.padEnd(normalized.length + ((4 - (normalized.length % 4)) % 4), '=');
51
+ return base64.decode(padded);
52
+ }
53
+ /**
54
+ * Decode a binary envelope field that may be hex or base64.
55
+ *
56
+ * @param value - The encoded field.
57
+ * @param encoding - Optional explicit encoding; auto-detected when omitted.
58
+ * @returns The decoded bytes.
59
+ */
60
+ function decodeBinary(value, encoding) {
61
+ const isHex = encoding === 'hex' ||
62
+ (encoding === undefined && /^[0-9a-fA-F]+$/u.test(value));
63
+ if (isHex) {
64
+ return hexToBytes(value);
65
+ }
66
+ return base64ToBytes(value);
67
+ }
68
+ /**
69
+ * Coerce the `credentials` field into a structured envelope. The frame may
70
+ * deliver it as an object, a JSON string, or base64(JSON).
71
+ *
72
+ * @param input - The raw credentials value.
73
+ * @returns The normalized envelope.
74
+ * @throws If the value is not a structured or base64(JSON) envelope, or is
75
+ * missing required fields.
76
+ */
77
+ function normalizeEnvelope(input) {
78
+ let value = input;
79
+ if (typeof value === 'string') {
80
+ const trimmed = value.trim();
81
+ if (trimmed.startsWith('{')) {
82
+ try {
83
+ value = JSON.parse(trimmed);
84
+ }
85
+ catch {
86
+ throw new Error(`credentials looked like JSON but failed to parse (preview: "${trimmed.slice(0, 64)}").`);
87
+ }
88
+ }
89
+ else {
90
+ let decodedText = null;
91
+ try {
92
+ decodedText = new TextDecoder().decode(base64ToBytes(trimmed));
93
+ }
94
+ catch {
95
+ decodedText = null;
96
+ }
97
+ const decodedTrimmed = decodedText?.trim();
98
+ if (decodedTrimmed?.startsWith('{')) {
99
+ try {
100
+ value = JSON.parse(decodedTrimmed);
101
+ }
102
+ catch {
103
+ throw new Error(`credentials base64-decoded to non-JSON (preview: "${decodedTrimmed.slice(0, 64)}").`);
104
+ }
105
+ }
106
+ else {
107
+ throw new Error(`credentials is an opaque string, not a structured or base64(JSON) envelope (preview: "${trimmed.slice(0, 64)}").`);
108
+ }
109
+ }
110
+ }
111
+ const env = value;
112
+ if (!env.ephemeralPublicKey || !(env.iv ?? env.nonce) || !env.ciphertext) {
113
+ const keys = value && typeof value === 'object'
114
+ ? Object.keys(value).join(', ')
115
+ : typeof value;
116
+ throw new Error(`credentials envelope missing required fields (ephemeralPublicKey/iv/ciphertext). Got: ${keys}`);
117
+ }
118
+ return env;
119
+ }
120
+ /**
121
+ * X25519 ECDH to AES-256-GCM decryption.
122
+ *
123
+ * @param theirPublicKey - The frame's ephemeral public key.
124
+ * @param iv - The 12-byte GCM IV.
125
+ * @param ciphertext - The ciphertext including the 16-byte auth tag.
126
+ * @param ourPrivateKey - Our X25519 private key.
127
+ * @returns The decrypted credentials and method.
128
+ */
129
+ function aesGcmDecrypt(theirPublicKey, iv, ciphertext, ourPrivateKey) {
130
+ const shared = x25519.getSharedSecret(ourPrivateKey, theirPublicKey);
131
+ const key = hkdf(sha256, shared, undefined, undefined, 32);
132
+ const plaintext = gcm(key, iv).decrypt(ciphertext);
133
+ const text = new TextDecoder().decode(plaintext);
134
+ return {
135
+ credentials: JSON.parse(text),
136
+ method: 'aes-256-gcm/hkdf-sha256',
137
+ };
138
+ }
139
+ /**
140
+ * Decrypt a Check/Auth frame credentials envelope using our X25519 private
141
+ * key.
142
+ *
143
+ * @param rawEnvelope - The raw envelope (object, JSON string, or base64(JSON)).
144
+ * @param ourPrivateKey - Our X25519 private key.
145
+ * @returns The parsed credentials and the method that authenticated.
146
+ * @throws If the envelope is malformed or the IV length is not 12 bytes.
147
+ */
148
+ export function decryptCredentials(rawEnvelope, ourPrivateKey) {
149
+ const envelope = normalizeEnvelope(rawEnvelope);
150
+ const theirPublicKey = decodeBinary(envelope.ephemeralPublicKey, envelope.encoding);
151
+ // `normalizeEnvelope` guarantees one of `iv` / `nonce` is present.
152
+ const ivField = (envelope.iv ?? envelope.nonce);
153
+ const iv = decodeBinary(ivField, envelope.encoding);
154
+ const ciphertext = decodeBinary(envelope.ciphertext, envelope.encoding);
155
+ if (iv.length !== 12) {
156
+ throw new Error(`Unexpected IV length ${iv.length} (expected 12 for AES-256-GCM).`);
157
+ }
158
+ return aesGcmDecrypt(theirPublicKey, iv, ciphertext, ourPrivateKey);
159
+ }
160
+ //# sourceMappingURL=crypto.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crypto.mjs","sourceRoot":"","sources":["../src/crypto.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Check / Auth frame key exchange and credential decryption.\n *\n * The identity vendor's Check and Auth frames return encrypted credentials.\n * The confirmed protocol is X25519 ECDH + AES-256-GCM (an \"ECDH-ES\" pattern\n * signalled by a 12-byte IV):\n *\n * 1. Client generates an X25519 keypair, sends `publicKey` (hex) into the\n * frame as a URL param.\n * 2. Frame generates its own ephemeral X25519 keypair and encrypts the\n * credentials, returning `{ ephemeralPublicKey, iv, ciphertext }`.\n * 3. Client reverses:\n * shared = X25519(ourPrivate, theirEphemeralPublic)\n * key = HKDF-SHA256(shared, salt=none, info=none, 32 bytes)\n * plain = AES-256-GCM.decrypt(key, iv, ciphertext || 16-byte tag)\n *\n * This module is platform-agnostic: it uses `@noble/*` + `@scure/base` and\n * avoids `Buffer` / `atob` so it runs unchanged on mobile, extension, and web.\n */\n\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 { bytesToHex, hexToBytes } from '@noble/hashes/utils';\nimport { base64 } from '@scure/base';\n\n/**\n * An X25519 keypair used for the Check/Auth frame key exchange.\n */\nexport type X25519KeyPair = {\n /** Raw 32-byte X25519 private (scalar) key. Never leaves the device. */\n privateKey: Uint8Array;\n /** Raw 32-byte X25519 public key. */\n publicKey: Uint8Array;\n /** Hex-encoded public key, ready to drop into a Check/Auth frame URL. */\n publicKeyHex: string;\n};\n\n/**\n * The encrypted-credentials envelope returned by the Check/Auth frames. Binary\n * fields may be hex or base64; the IV field may be named `iv` or `nonce`.\n */\nexport type EncryptedCredentialsEnvelope = {\n /** Ephemeral public key produced by the frame for this exchange (32 bytes). */\n ephemeralPublicKey: string;\n /** Per-message IV. May be provided as `iv` or `nonce`. */\n iv?: string;\n nonce?: string;\n /** Ciphertext (plaintext + 16-byte GCM auth tag). */\n ciphertext: string;\n /** Optional explicit encoding hint. Defaults to auto-detect. */\n encoding?: 'hex' | 'base64';\n};\n\n/**\n * Decrypted Check/Auth frame credentials.\n *\n * - `accessToken` is the Bearer token for the identity API.\n * - `clientToken` is the short-lived token consumed by the Auth frame when the\n * Check frame returns `connectionRequired`.\n */\nexport type DecryptedCredentials = {\n accessToken?: string;\n clientToken?: string;\n [key: string]: unknown;\n};\n\n/**\n * Result of a successful decryption — the credentials plus the `method` that\n * authenticated.\n */\nexport type DecryptResult = {\n credentials: DecryptedCredentials;\n method: string;\n};\n\n/**\n * Generate a fresh X25519 keypair. The private key never leaves the device;\n * only `publicKeyHex` is sent to the vendor via the frame URL.\n *\n * @returns The generated keypair.\n */\nexport function generateKeyPair(): X25519KeyPair {\n const privateKey = x25519.utils.randomSecretKey();\n const publicKey = x25519.getPublicKey(privateKey);\n return {\n privateKey,\n publicKey,\n publicKeyHex: bytesToHex(publicKey),\n };\n}\n\n/**\n * Decode a base64 / base64url string to bytes without relying on `atob` or\n * `Buffer`.\n *\n * @param value - The (possibly url-safe, possibly unpadded) base64 string.\n * @returns The decoded bytes.\n */\nfunction base64ToBytes(value: string): Uint8Array {\n const normalized = value.replace(/-/gu, '+').replace(/_/gu, '/');\n const padded = normalized.padEnd(\n normalized.length + ((4 - (normalized.length % 4)) % 4),\n '=',\n );\n return base64.decode(padded);\n}\n\n/**\n * Decode a binary envelope field that may be hex or base64.\n *\n * @param value - The encoded field.\n * @param encoding - Optional explicit encoding; auto-detected when omitted.\n * @returns The decoded bytes.\n */\nfunction decodeBinary(value: string, encoding?: 'hex' | 'base64'): Uint8Array {\n const isHex =\n encoding === 'hex' ||\n (encoding === undefined && /^[0-9a-fA-F]+$/u.test(value));\n if (isHex) {\n return hexToBytes(value);\n }\n return base64ToBytes(value);\n}\n\n/**\n * Coerce the `credentials` field into a structured envelope. The frame may\n * deliver it as an object, a JSON string, or base64(JSON).\n *\n * @param input - The raw credentials value.\n * @returns The normalized envelope.\n * @throws If the value is not a structured or base64(JSON) envelope, or is\n * missing required fields.\n */\nfunction normalizeEnvelope(\n input: EncryptedCredentialsEnvelope | string,\n): EncryptedCredentialsEnvelope {\n let value: unknown = input;\n\n if (typeof value === 'string') {\n const trimmed = value.trim();\n if (trimmed.startsWith('{')) {\n try {\n value = JSON.parse(trimmed);\n } catch {\n throw new Error(\n `credentials looked like JSON but failed to parse (preview: \"${trimmed.slice(\n 0,\n 64,\n )}\").`,\n );\n }\n } else {\n let decodedText: string | null = null;\n try {\n decodedText = new TextDecoder().decode(base64ToBytes(trimmed));\n } catch {\n decodedText = null;\n }\n const decodedTrimmed = decodedText?.trim();\n if (decodedTrimmed?.startsWith('{')) {\n try {\n value = JSON.parse(decodedTrimmed);\n } catch {\n throw new Error(\n `credentials base64-decoded to non-JSON (preview: \"${decodedTrimmed.slice(\n 0,\n 64,\n )}\").`,\n );\n }\n } else {\n throw new Error(\n `credentials is an opaque string, not a structured or base64(JSON) envelope (preview: \"${trimmed.slice(\n 0,\n 64,\n )}\").`,\n );\n }\n }\n }\n\n const env = value as Partial<EncryptedCredentialsEnvelope>;\n if (!env.ephemeralPublicKey || !(env.iv ?? env.nonce) || !env.ciphertext) {\n const keys =\n value && typeof value === 'object'\n ? Object.keys(value).join(', ')\n : typeof value;\n throw new Error(\n `credentials envelope missing required fields (ephemeralPublicKey/iv/ciphertext). Got: ${keys}`,\n );\n }\n return env as EncryptedCredentialsEnvelope;\n}\n\n/**\n * X25519 ECDH to AES-256-GCM decryption.\n *\n * @param theirPublicKey - The frame's ephemeral public key.\n * @param iv - The 12-byte GCM IV.\n * @param ciphertext - The ciphertext including the 16-byte auth tag.\n * @param ourPrivateKey - Our X25519 private key.\n * @returns The decrypted credentials and method.\n */\nfunction aesGcmDecrypt(\n theirPublicKey: Uint8Array,\n iv: Uint8Array,\n ciphertext: Uint8Array,\n ourPrivateKey: Uint8Array,\n): DecryptResult {\n const shared = x25519.getSharedSecret(ourPrivateKey, theirPublicKey);\n const key = hkdf(sha256, shared, undefined, undefined, 32);\n const plaintext = gcm(key, iv).decrypt(ciphertext);\n const text = new TextDecoder().decode(plaintext);\n return {\n credentials: JSON.parse(text) as DecryptedCredentials,\n method: 'aes-256-gcm/hkdf-sha256',\n };\n}\n\n/**\n * Decrypt a Check/Auth frame credentials envelope using our X25519 private\n * key.\n *\n * @param rawEnvelope - The raw envelope (object, JSON string, or base64(JSON)).\n * @param ourPrivateKey - Our X25519 private key.\n * @returns The parsed credentials and the method that authenticated.\n * @throws If the envelope is malformed or the IV length is not 12 bytes.\n */\nexport function decryptCredentials(\n rawEnvelope: EncryptedCredentialsEnvelope | string,\n ourPrivateKey: Uint8Array,\n): DecryptResult {\n const envelope = normalizeEnvelope(rawEnvelope);\n const theirPublicKey = decodeBinary(\n envelope.ephemeralPublicKey,\n envelope.encoding,\n );\n // `normalizeEnvelope` guarantees one of `iv` / `nonce` is present.\n const ivField = (envelope.iv ?? envelope.nonce) as string;\n const iv = decodeBinary(ivField, envelope.encoding);\n const ciphertext = decodeBinary(envelope.ciphertext, envelope.encoding);\n\n if (iv.length !== 12) {\n throw new Error(\n `Unexpected IV length ${iv.length} (expected 12 for AES-256-GCM).`,\n );\n }\n\n return aesGcmDecrypt(theirPublicKey, iv, ciphertext, ourPrivateKey);\n}\n"]}
package/dist/index.cjs ADDED
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generateKeyPair = exports.decryptCredentials = exports.ALPHA2_TO_ALPHA3 = exports.alpha2ToAlpha3 = exports.selectKycSumSub = exports.selectKycPhase = exports.selectIsKycRequiredForProduct = exports.serviceName = exports.KycService = exports.controllerName = exports.getDefaultKycControllerState = exports.KycController = void 0;
4
+ var KycController_1 = require("./KycController.cjs");
5
+ Object.defineProperty(exports, "KycController", { enumerable: true, get: function () { return KycController_1.KycController; } });
6
+ Object.defineProperty(exports, "getDefaultKycControllerState", { enumerable: true, get: function () { return KycController_1.getDefaultKycControllerState; } });
7
+ Object.defineProperty(exports, "controllerName", { enumerable: true, get: function () { return KycController_1.controllerName; } });
8
+ var KycService_1 = require("./KycService.cjs");
9
+ Object.defineProperty(exports, "KycService", { enumerable: true, get: function () { return KycService_1.KycService; } });
10
+ Object.defineProperty(exports, "serviceName", { enumerable: true, get: function () { return KycService_1.serviceName; } });
11
+ var selectors_1 = require("./selectors.cjs");
12
+ Object.defineProperty(exports, "selectIsKycRequiredForProduct", { enumerable: true, get: function () { return selectors_1.selectIsKycRequiredForProduct; } });
13
+ Object.defineProperty(exports, "selectKycPhase", { enumerable: true, get: function () { return selectors_1.selectKycPhase; } });
14
+ Object.defineProperty(exports, "selectKycSumSub", { enumerable: true, get: function () { return selectors_1.selectKycSumSub; } });
15
+ var countryCodes_1 = require("./countryCodes.cjs");
16
+ Object.defineProperty(exports, "alpha2ToAlpha3", { enumerable: true, get: function () { return countryCodes_1.alpha2ToAlpha3; } });
17
+ Object.defineProperty(exports, "ALPHA2_TO_ALPHA3", { enumerable: true, get: function () { return countryCodes_1.ALPHA2_TO_ALPHA3; } });
18
+ var crypto_1 = require("./crypto.cjs");
19
+ Object.defineProperty(exports, "decryptCredentials", { enumerable: true, get: function () { return crypto_1.decryptCredentials; } });
20
+ Object.defineProperty(exports, "generateKeyPair", { enumerable: true, get: function () { return crypto_1.generateKeyPair; } });
21
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.cjs","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,qDAIyB;AAHvB,8GAAA,aAAa,OAAA;AACb,6HAAA,4BAA4B,OAAA;AAC5B,+GAAA,cAAc,OAAA;AA0BhB,+CAAuD;AAA9C,wGAAA,UAAU,OAAA;AAAE,yGAAA,WAAW,OAAA;AAuBhC,6CAIqB;AAHnB,0HAAA,6BAA6B,OAAA;AAC7B,2GAAA,cAAc,OAAA;AACd,4GAAA,eAAe,OAAA;AAGjB,mDAAkE;AAAzD,8GAAA,cAAc,OAAA;AAAE,gHAAA,gBAAgB,OAAA;AACzC,uCAA+D;AAAtD,4GAAA,kBAAkB,OAAA;AAAE,yGAAA,eAAe,OAAA","sourcesContent":["export {\n KycController,\n getDefaultKycControllerState,\n controllerName,\n} from './KycController';\nexport type {\n KycControllerActions,\n KycControllerEvents,\n KycControllerGetStateAction,\n KycControllerMessenger,\n KycControllerOptions,\n KycControllerState,\n KycControllerStateChangeEvent,\n} from './KycController';\nexport type {\n KycControllerAcceptTermsAndStartSessionAction,\n KycControllerBuildAuthFrameUrlAction,\n KycControllerBuildCheckFrameUrlAction,\n KycControllerBuildResetFrameUrlAction,\n KycControllerCheckKycRequiredAction,\n KycControllerClearSavedTermsAction,\n KycControllerGetKycStatusAction,\n KycControllerHandleFrameMessageAction,\n KycControllerInitializeAction,\n KycControllerLoadDisclaimersAction,\n KycControllerResetAction,\n KycControllerStartSumSubAction,\n} from './KycController-method-action-types';\n\nexport { KycService, serviceName } from './KycService';\nexport type {\n CheckKycRequiredParams,\n CreateSessionParams,\n CreateUkycSessionParams,\n KycServiceActions,\n KycServiceEnvironment,\n KycServiceEvents,\n KycServiceMessenger,\n KycServiceOptions,\n SubmitWrappedKeyParams,\n UkycSessionResponse,\n WrappedKeyResponse,\n} from './KycService';\nexport type {\n KycServiceCheckKycRequiredAction,\n KycServiceCreateSessionAction,\n KycServiceCreateUkycSessionAction,\n KycServiceFetchDisclaimersAction,\n KycServiceGetGeoCountryAction,\n KycServiceSubmitWrappedKeyAction,\n} from './KycService-method-action-types';\n\nexport {\n selectIsKycRequiredForProduct,\n selectKycPhase,\n selectKycSumSub,\n} from './selectors';\n\nexport { alpha2ToAlpha3, ALPHA2_TO_ALPHA3 } from './countryCodes';\nexport { decryptCredentials, generateKeyPair } from './crypto';\nexport type {\n DecryptedCredentials,\n DecryptResult,\n EncryptedCredentialsEnvelope,\n X25519KeyPair,\n} from './crypto';\n\nexport type {\n KycDisclaimer,\n KycPhase,\n KycProduct,\n KycSumSubLaunchParams,\n KycSumSubLauncher,\n KycSumSubStatus,\n KycVendor,\n} from './types';\n"]}
@@ -0,0 +1,12 @@
1
+ export { KycController, getDefaultKycControllerState, controllerName, } from "./KycController.cjs";
2
+ export type { KycControllerActions, KycControllerEvents, KycControllerGetStateAction, KycControllerMessenger, KycControllerOptions, KycControllerState, KycControllerStateChangeEvent, } from "./KycController.cjs";
3
+ export type { KycControllerAcceptTermsAndStartSessionAction, KycControllerBuildAuthFrameUrlAction, KycControllerBuildCheckFrameUrlAction, KycControllerBuildResetFrameUrlAction, KycControllerCheckKycRequiredAction, KycControllerClearSavedTermsAction, KycControllerGetKycStatusAction, KycControllerHandleFrameMessageAction, KycControllerInitializeAction, KycControllerLoadDisclaimersAction, KycControllerResetAction, KycControllerStartSumSubAction, } from "./KycController-method-action-types.cjs";
4
+ export { KycService, serviceName } from "./KycService.cjs";
5
+ export type { CheckKycRequiredParams, CreateSessionParams, CreateUkycSessionParams, KycServiceActions, KycServiceEnvironment, KycServiceEvents, KycServiceMessenger, KycServiceOptions, SubmitWrappedKeyParams, UkycSessionResponse, WrappedKeyResponse, } from "./KycService.cjs";
6
+ export type { KycServiceCheckKycRequiredAction, KycServiceCreateSessionAction, KycServiceCreateUkycSessionAction, KycServiceFetchDisclaimersAction, KycServiceGetGeoCountryAction, KycServiceSubmitWrappedKeyAction, } from "./KycService-method-action-types.cjs";
7
+ export { selectIsKycRequiredForProduct, selectKycPhase, selectKycSumSub, } from "./selectors.cjs";
8
+ export { alpha2ToAlpha3, ALPHA2_TO_ALPHA3 } from "./countryCodes.cjs";
9
+ export { decryptCredentials, generateKeyPair } from "./crypto.cjs";
10
+ export type { DecryptedCredentials, DecryptResult, EncryptedCredentialsEnvelope, X25519KeyPair, } from "./crypto.cjs";
11
+ export type { KycDisclaimer, KycPhase, KycProduct, KycSumSubLaunchParams, KycSumSubLauncher, KycSumSubStatus, KycVendor, } from "./types.cjs";
12
+ //# sourceMappingURL=index.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.cts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EACb,4BAA4B,EAC5B,cAAc,GACf,4BAAwB;AACzB,YAAY,EACV,oBAAoB,EACpB,mBAAmB,EACnB,2BAA2B,EAC3B,sBAAsB,EACtB,oBAAoB,EACpB,kBAAkB,EAClB,6BAA6B,GAC9B,4BAAwB;AACzB,YAAY,EACV,6CAA6C,EAC7C,oCAAoC,EACpC,qCAAqC,EACrC,qCAAqC,EACrC,mCAAmC,EACnC,kCAAkC,EAClC,+BAA+B,EAC/B,qCAAqC,EACrC,6BAA6B,EAC7B,kCAAkC,EAClC,wBAAwB,EACxB,8BAA8B,GAC/B,gDAA4C;AAE7C,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,yBAAqB;AACvD,YAAY,EACV,sBAAsB,EACtB,mBAAmB,EACnB,uBAAuB,EACvB,iBAAiB,EACjB,qBAAqB,EACrB,gBAAgB,EAChB,mBAAmB,EACnB,iBAAiB,EACjB,sBAAsB,EACtB,mBAAmB,EACnB,kBAAkB,GACnB,yBAAqB;AACtB,YAAY,EACV,gCAAgC,EAChC,6BAA6B,EAC7B,iCAAiC,EACjC,gCAAgC,EAChC,6BAA6B,EAC7B,gCAAgC,GACjC,6CAAyC;AAE1C,OAAO,EACL,6BAA6B,EAC7B,cAAc,EACd,eAAe,GAChB,wBAAoB;AAErB,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,2BAAuB;AAClE,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,qBAAiB;AAC/D,YAAY,EACV,oBAAoB,EACpB,aAAa,EACb,4BAA4B,EAC5B,aAAa,GACd,qBAAiB;AAElB,YAAY,EACV,aAAa,EACb,QAAQ,EACR,UAAU,EACV,qBAAqB,EACrB,iBAAiB,EACjB,eAAe,EACf,SAAS,GACV,oBAAgB"}
@@ -0,0 +1,12 @@
1
+ export { KycController, getDefaultKycControllerState, controllerName, } from "./KycController.mjs";
2
+ export type { KycControllerActions, KycControllerEvents, KycControllerGetStateAction, KycControllerMessenger, KycControllerOptions, KycControllerState, KycControllerStateChangeEvent, } from "./KycController.mjs";
3
+ export type { KycControllerAcceptTermsAndStartSessionAction, KycControllerBuildAuthFrameUrlAction, KycControllerBuildCheckFrameUrlAction, KycControllerBuildResetFrameUrlAction, KycControllerCheckKycRequiredAction, KycControllerClearSavedTermsAction, KycControllerGetKycStatusAction, KycControllerHandleFrameMessageAction, KycControllerInitializeAction, KycControllerLoadDisclaimersAction, KycControllerResetAction, KycControllerStartSumSubAction, } from "./KycController-method-action-types.mjs";
4
+ export { KycService, serviceName } from "./KycService.mjs";
5
+ export type { CheckKycRequiredParams, CreateSessionParams, CreateUkycSessionParams, KycServiceActions, KycServiceEnvironment, KycServiceEvents, KycServiceMessenger, KycServiceOptions, SubmitWrappedKeyParams, UkycSessionResponse, WrappedKeyResponse, } from "./KycService.mjs";
6
+ export type { KycServiceCheckKycRequiredAction, KycServiceCreateSessionAction, KycServiceCreateUkycSessionAction, KycServiceFetchDisclaimersAction, KycServiceGetGeoCountryAction, KycServiceSubmitWrappedKeyAction, } from "./KycService-method-action-types.mjs";
7
+ export { selectIsKycRequiredForProduct, selectKycPhase, selectKycSumSub, } from "./selectors.mjs";
8
+ export { alpha2ToAlpha3, ALPHA2_TO_ALPHA3 } from "./countryCodes.mjs";
9
+ export { decryptCredentials, generateKeyPair } from "./crypto.mjs";
10
+ export type { DecryptedCredentials, DecryptResult, EncryptedCredentialsEnvelope, X25519KeyPair, } from "./crypto.mjs";
11
+ export type { KycDisclaimer, KycPhase, KycProduct, KycSumSubLaunchParams, KycSumSubLauncher, KycSumSubStatus, KycVendor, } from "./types.mjs";
12
+ //# sourceMappingURL=index.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.mts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EACb,4BAA4B,EAC5B,cAAc,GACf,4BAAwB;AACzB,YAAY,EACV,oBAAoB,EACpB,mBAAmB,EACnB,2BAA2B,EAC3B,sBAAsB,EACtB,oBAAoB,EACpB,kBAAkB,EAClB,6BAA6B,GAC9B,4BAAwB;AACzB,YAAY,EACV,6CAA6C,EAC7C,oCAAoC,EACpC,qCAAqC,EACrC,qCAAqC,EACrC,mCAAmC,EACnC,kCAAkC,EAClC,+BAA+B,EAC/B,qCAAqC,EACrC,6BAA6B,EAC7B,kCAAkC,EAClC,wBAAwB,EACxB,8BAA8B,GAC/B,gDAA4C;AAE7C,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,yBAAqB;AACvD,YAAY,EACV,sBAAsB,EACtB,mBAAmB,EACnB,uBAAuB,EACvB,iBAAiB,EACjB,qBAAqB,EACrB,gBAAgB,EAChB,mBAAmB,EACnB,iBAAiB,EACjB,sBAAsB,EACtB,mBAAmB,EACnB,kBAAkB,GACnB,yBAAqB;AACtB,YAAY,EACV,gCAAgC,EAChC,6BAA6B,EAC7B,iCAAiC,EACjC,gCAAgC,EAChC,6BAA6B,EAC7B,gCAAgC,GACjC,6CAAyC;AAE1C,OAAO,EACL,6BAA6B,EAC7B,cAAc,EACd,eAAe,GAChB,wBAAoB;AAErB,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,2BAAuB;AAClE,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,qBAAiB;AAC/D,YAAY,EACV,oBAAoB,EACpB,aAAa,EACb,4BAA4B,EAC5B,aAAa,GACd,qBAAiB;AAElB,YAAY,EACV,aAAa,EACb,QAAQ,EACR,UAAU,EACV,qBAAqB,EACrB,iBAAiB,EACjB,eAAe,EACf,SAAS,GACV,oBAAgB"}
package/dist/index.mjs ADDED
@@ -0,0 +1,6 @@
1
+ export { KycController, getDefaultKycControllerState, controllerName } from "./KycController.mjs";
2
+ export { KycService, serviceName } from "./KycService.mjs";
3
+ export { selectIsKycRequiredForProduct, selectKycPhase, selectKycSumSub } from "./selectors.mjs";
4
+ export { alpha2ToAlpha3, ALPHA2_TO_ALPHA3 } from "./countryCodes.mjs";
5
+ export { decryptCredentials, generateKeyPair } from "./crypto.mjs";
6
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EACb,4BAA4B,EAC5B,cAAc,EACf,4BAAwB;AAyBzB,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,yBAAqB;AAuBvD,OAAO,EACL,6BAA6B,EAC7B,cAAc,EACd,eAAe,EAChB,wBAAoB;AAErB,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,2BAAuB;AAClE,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,qBAAiB","sourcesContent":["export {\n KycController,\n getDefaultKycControllerState,\n controllerName,\n} from './KycController';\nexport type {\n KycControllerActions,\n KycControllerEvents,\n KycControllerGetStateAction,\n KycControllerMessenger,\n KycControllerOptions,\n KycControllerState,\n KycControllerStateChangeEvent,\n} from './KycController';\nexport type {\n KycControllerAcceptTermsAndStartSessionAction,\n KycControllerBuildAuthFrameUrlAction,\n KycControllerBuildCheckFrameUrlAction,\n KycControllerBuildResetFrameUrlAction,\n KycControllerCheckKycRequiredAction,\n KycControllerClearSavedTermsAction,\n KycControllerGetKycStatusAction,\n KycControllerHandleFrameMessageAction,\n KycControllerInitializeAction,\n KycControllerLoadDisclaimersAction,\n KycControllerResetAction,\n KycControllerStartSumSubAction,\n} from './KycController-method-action-types';\n\nexport { KycService, serviceName } from './KycService';\nexport type {\n CheckKycRequiredParams,\n CreateSessionParams,\n CreateUkycSessionParams,\n KycServiceActions,\n KycServiceEnvironment,\n KycServiceEvents,\n KycServiceMessenger,\n KycServiceOptions,\n SubmitWrappedKeyParams,\n UkycSessionResponse,\n WrappedKeyResponse,\n} from './KycService';\nexport type {\n KycServiceCheckKycRequiredAction,\n KycServiceCreateSessionAction,\n KycServiceCreateUkycSessionAction,\n KycServiceFetchDisclaimersAction,\n KycServiceGetGeoCountryAction,\n KycServiceSubmitWrappedKeyAction,\n} from './KycService-method-action-types';\n\nexport {\n selectIsKycRequiredForProduct,\n selectKycPhase,\n selectKycSumSub,\n} from './selectors';\n\nexport { alpha2ToAlpha3, ALPHA2_TO_ALPHA3 } from './countryCodes';\nexport { decryptCredentials, generateKeyPair } from './crypto';\nexport type {\n DecryptedCredentials,\n DecryptResult,\n EncryptedCredentialsEnvelope,\n X25519KeyPair,\n} from './crypto';\n\nexport type {\n KycDisclaimer,\n KycPhase,\n KycProduct,\n KycSumSubLaunchParams,\n KycSumSubLauncher,\n KycSumSubStatus,\n KycVendor,\n} from './types';\n"]}