@ledgerhq/revault-sdk 0.25.0 → 0.26.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. package/lib/bake.cjs +1214 -1361
  2. package/lib/bake.cjs.map +1 -1
  3. package/lib/bake.d.cts +564 -562
  4. package/lib/bake.d.ts +564 -562
  5. package/lib/bake.js +1204 -1359
  6. package/lib/bake.js.map +1 -1
  7. package/lib/chunk-CKQMccvm.cjs +28 -0
  8. package/lib/crypto-BDBF_rfw.cjs +266 -0
  9. package/lib/crypto-BDBF_rfw.cjs.map +1 -0
  10. package/lib/crypto-CPCBrCSZ.js +245 -0
  11. package/lib/crypto-CPCBrCSZ.js.map +1 -0
  12. package/lib/crypto.cjs +5 -11
  13. package/lib/crypto.d.cts +10 -7
  14. package/lib/crypto.d.ts +10 -7
  15. package/lib/crypto.js +2 -11
  16. package/lib/device-0lcfYGHr.cjs +791 -0
  17. package/lib/device-0lcfYGHr.cjs.map +1 -0
  18. package/lib/device-B8Fww8_6.js +719 -0
  19. package/lib/device-B8Fww8_6.js.map +1 -0
  20. package/lib/device.cjs +6 -13
  21. package/lib/device.d.cts +2 -50
  22. package/lib/device.d.ts +2 -50
  23. package/lib/device.js +2 -13
  24. package/lib/engine.cjs +851 -888
  25. package/lib/engine.cjs.map +1 -1
  26. package/lib/engine.d.cts +3 -25
  27. package/lib/engine.d.ts +3 -25
  28. package/lib/engine.js +844 -885
  29. package/lib/engine.js.map +1 -1
  30. package/lib/index--fscLDTT.d.ts +237 -0
  31. package/lib/index-BE7oUpCb.d.cts +237 -0
  32. package/lib/index-DOn7RPPt.d.cts +23 -0
  33. package/lib/index-U0iFMp3g.d.ts +23 -0
  34. package/lib/index.cjs +0 -1
  35. package/lib/index.d.cts +10 -5
  36. package/lib/index.d.ts +10 -5
  37. package/lib/index.js +1 -1
  38. package/lib/logger-Cme0iL1f.d.cts +10 -0
  39. package/lib/logger-DWLViq7U.d.ts +10 -0
  40. package/lib/onboarding.cjs +215 -183
  41. package/lib/onboarding.cjs.map +1 -1
  42. package/lib/onboarding.d.cts +1918 -1722
  43. package/lib/onboarding.d.ts +1918 -1722
  44. package/lib/onboarding.js +211 -181
  45. package/lib/onboarding.js.map +1 -1
  46. package/lib/trpc-CWGPr8Ox.d.ts +20 -0
  47. package/lib/trpc-C_dUOB1u.d.cts +20 -0
  48. package/lib/types-BXkDuD6i.d.ts +207 -0
  49. package/lib/types-CQROu0nu.d.cts +6 -0
  50. package/lib/types-Ngwgtu_U.d.cts +207 -0
  51. package/lib/types-_QeBv1U4.d.ts +6 -0
  52. package/lib/types.cjs +0 -1
  53. package/lib/types.d.cts +3 -4
  54. package/lib/types.d.ts +3 -4
  55. package/lib/types.js +1 -1
  56. package/lib/utils-BGbdjOP9.js +61 -0
  57. package/lib/utils-BGbdjOP9.js.map +1 -0
  58. package/lib/utils-DbSFXp4c.cjs +84 -0
  59. package/lib/utils-DbSFXp4c.cjs.map +1 -0
  60. package/package.json +6 -6
  61. package/lib/chunk-2WGM7EWA.cjs +0 -282
  62. package/lib/chunk-2WGM7EWA.cjs.map +0 -1
  63. package/lib/chunk-AXI72NFY.js +0 -50
  64. package/lib/chunk-AXI72NFY.js.map +0 -1
  65. package/lib/chunk-DRMYBKL3.cjs +0 -820
  66. package/lib/chunk-DRMYBKL3.cjs.map +0 -1
  67. package/lib/chunk-KV5FO7N5.js +0 -282
  68. package/lib/chunk-KV5FO7N5.js.map +0 -1
  69. package/lib/chunk-LH4QQXUH.cjs +0 -50
  70. package/lib/chunk-LH4QQXUH.cjs.map +0 -1
  71. package/lib/chunk-PFZIW6UP.js +0 -820
  72. package/lib/chunk-PFZIW6UP.js.map +0 -1
  73. package/lib/crypto.cjs.map +0 -1
  74. package/lib/crypto.js.map +0 -1
  75. package/lib/device.cjs.map +0 -1
  76. package/lib/device.js.map +0 -1
  77. package/lib/index.cjs.map +0 -1
  78. package/lib/index.js.map +0 -1
  79. package/lib/logger-C-TPbnjv.d.cts +0 -9
  80. package/lib/logger-C-TPbnjv.d.ts +0 -9
  81. package/lib/types-C-ngtI5m.d.ts +0 -202
  82. package/lib/types-CpGEbAxh.d.cts +0 -19
  83. package/lib/types-CpGEbAxh.d.ts +0 -19
  84. package/lib/types-CryvY9pW.d.cts +0 -202
  85. package/lib/types-DJfbanPz.d.cts +0 -167
  86. package/lib/types-DJfbanPz.d.ts +0 -167
  87. package/lib/types.cjs.map +0 -1
  88. package/lib/types.js.map +0 -1
@@ -1,282 +0,0 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } } function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }// src/crypto/gen-seed.ts
2
- var _sha2js = require('@noble/hashes/sha2.js');
3
- var _bip39 = require('@scure/bip39');
4
- var _englishjs = require('@scure/bip39/wordlists/english.js');
5
- function genSeed(salt, index) {
6
- const input = new TextEncoder().encode(`${salt}_${index}`);
7
- const entropy = _sha2js.sha256.call(void 0, input);
8
- return _bip39.entropyToMnemonic.call(void 0, entropy, _englishjs.wordlist);
9
- }
10
-
11
- // src/crypto/utils.ts
12
- var _elliptic = require('elliptic'); var _elliptic2 = _interopRequireDefault(_elliptic);
13
- var _jose = require('jose'); var jose = _interopRequireWildcard(_jose);
14
-
15
- // src/crypto/key-encoder.ts
16
- var _asn1js = require('asn1.js'); var _asn1js2 = _interopRequireDefault(_asn1js);
17
- var _bnjs = require('bn.js'); var _bnjs2 = _interopRequireDefault(_bnjs);
18
-
19
- var ECPrivateKeyASN = _asn1js2.default.define("ECPrivateKey", function() {
20
- const self = this;
21
- self.seq().obj(
22
- self.key("version").int(),
23
- self.key("privateKey").octstr(),
24
- self.key("parameters").explicit(0).objid().optional(),
25
- self.key("publicKey").explicit(1).bitstr().optional()
26
- );
27
- });
28
- var ECPrivateKey8ASN = _asn1js2.default.define(
29
- "ECPrivateKey",
30
- /* v8 ignore next -- @preserve */
31
- function() {
32
- const self = this;
33
- self.seq().obj(
34
- self.key("version").int(),
35
- self.key("privateKeyAlgorithm").seq().obj(self.key("ecPublicKey").objid(), self.key("curve").objid()),
36
- self.key("privateKey").octstr().contains(ECPrivateKeyASN),
37
- self.key("attributes").explicit(0).bitstr().optional()
38
- );
39
- }
40
- );
41
- var SubjectPublicKeyInfoASN = _asn1js2.default.define("SubjectPublicKeyInfo", function() {
42
- const self = this;
43
- self.seq().obj(
44
- self.key("algorithm").seq().obj(self.key("id").objid(), self.key("curve").objid()),
45
- self.key("pub").bitstr()
46
- );
47
- });
48
- var curves = {
49
- secp256k1: {
50
- curveParameters: [1, 3, 132, 0, 10],
51
- privatePEMOptions: { label: "EC PRIVATE KEY" },
52
- publicPEMOptions: { label: "PUBLIC KEY" },
53
- curve: new _elliptic2.default.ec("secp256k1")
54
- },
55
- p256: {
56
- curveParameters: [1, 2, 840, 10045, 3, 1, 7],
57
- // OID for p256 curve
58
- privatePEMOptions: { label: "EC PRIVATE KEY" },
59
- publicPEMOptions: { label: "PUBLIC KEY" },
60
- curve: new _elliptic2.default.ec("p256")
61
- }
62
- };
63
- var KeyEncoder = class {
64
-
65
-
66
- constructor(options) {
67
- if (typeof options === "string") {
68
- if (options !== "secp256k1" && options !== "p256") {
69
- throw new Error(`Unknown curve ${options}`);
70
- }
71
- options = curves[options];
72
- }
73
- this.options = options;
74
- this.algorithmID = [1, 2, 840, 10045, 2, 1];
75
- }
76
- /* v8 ignore next -- @preserve */
77
- PKCS1toPKCS8(privateKey) {
78
- return {
79
- version: new (0, _bnjs2.default)(0),
80
- privateKey,
81
- privateKeyAlgorithm: {
82
- ecPublicKey: this.algorithmID,
83
- curve: privateKey.parameters
84
- }
85
- };
86
- }
87
- privateKeyObject(rawPrivateKey, rawPublicKey) {
88
- const privateKeyObject = {
89
- version: new (0, _bnjs2.default)(1),
90
- privateKey: Buffer.from(rawPrivateKey, "hex"),
91
- parameters: this.options.curveParameters
92
- };
93
- if (rawPublicKey) {
94
- privateKeyObject.publicKey = {
95
- unused: 0,
96
- data: Buffer.from(rawPublicKey, "hex")
97
- };
98
- }
99
- return privateKeyObject;
100
- }
101
- publicKeyObject(rawPublicKey) {
102
- return {
103
- algorithm: {
104
- id: this.algorithmID,
105
- curve: this.options.curveParameters
106
- },
107
- pub: {
108
- unused: 0,
109
- data: Buffer.from(rawPublicKey, "hex")
110
- }
111
- };
112
- }
113
- encodePrivate(privateKey, originalFormat, destinationFormat, destinationFormatType = "pkcs1") {
114
- let privateKeyObject;
115
- switch (originalFormat) {
116
- case "raw": {
117
- if (typeof privateKey !== "string") {
118
- throw new Error("private key must be a string");
119
- }
120
- const keyPair = this.options.curve.keyFromPrivate(privateKey, "hex");
121
- const rawPublicKey = keyPair.getPublic("hex");
122
- privateKeyObject = this.privateKeyObject(privateKey, rawPublicKey);
123
- break;
124
- }
125
- /* v8 ignore next -- @preserve */
126
- case "der":
127
- if (typeof privateKey === "string") {
128
- privateKey = Buffer.from(privateKey, "hex");
129
- }
130
- privateKeyObject = ECPrivateKeyASN.decode(privateKey, "der");
131
- break;
132
- case "pem":
133
- if (typeof privateKey !== "string") {
134
- throw new Error("private key must be a string");
135
- }
136
- privateKeyObject = ECPrivateKeyASN.decode(
137
- privateKey,
138
- "pem",
139
- this.options.privatePEMOptions
140
- );
141
- break;
142
- /* v8 ignore next -- @preserve */
143
- default:
144
- throw new Error("invalid private key format");
145
- }
146
- switch (destinationFormat) {
147
- case "raw":
148
- if (destinationFormatType === "pkcs1") {
149
- return privateKeyObject.privateKey.toString("hex");
150
- } else if (destinationFormatType === "pkcs8") {
151
- return this.PKCS1toPKCS8(privateKeyObject).privateKey.privateKey.toString("hex");
152
- }
153
- break;
154
- case "der":
155
- if (destinationFormatType === "pkcs1") {
156
- return ECPrivateKeyASN.encode(privateKeyObject, "der").toString("hex");
157
- } else if (destinationFormatType === "pkcs8") {
158
- return ECPrivateKey8ASN.encode(this.PKCS1toPKCS8(privateKeyObject), "der").toString(
159
- "hex"
160
- );
161
- }
162
- break;
163
- case "pem":
164
- if (destinationFormatType === "pkcs1") {
165
- return ECPrivateKeyASN.encode(privateKeyObject, "pem", this.options.privatePEMOptions);
166
- } else if (destinationFormatType === "pkcs8") {
167
- return ECPrivateKey8ASN.encode(this.PKCS1toPKCS8(privateKeyObject), "pem", {
168
- ...this.options.privatePEMOptions,
169
- label: "PRIVATE KEY"
170
- });
171
- }
172
- break;
173
- /* v8 ignore next -- @preserve */
174
- default:
175
- throw new Error("invalid destination format for private key");
176
- }
177
- throw new Error("unsupported destination format or type");
178
- }
179
- encodePublic(publicKey, originalFormat, destinationFormat) {
180
- let publicKeyObject;
181
- switch (originalFormat) {
182
- case "raw":
183
- if (typeof publicKey !== "string") {
184
- throw new Error("public key must be a string");
185
- }
186
- publicKeyObject = this.publicKeyObject(publicKey);
187
- break;
188
- /* v8 ignore next -- @preserve */
189
- case "der":
190
- if (typeof publicKey === "string") {
191
- publicKey = Buffer.from(publicKey, "hex");
192
- }
193
- publicKeyObject = SubjectPublicKeyInfoASN.decode(publicKey, "der");
194
- break;
195
- case "pem":
196
- if (typeof publicKey !== "string") {
197
- throw new Error("public key must be a string");
198
- }
199
- publicKeyObject = SubjectPublicKeyInfoASN.decode(
200
- publicKey,
201
- "pem",
202
- this.options.publicPEMOptions
203
- );
204
- break;
205
- /* v8 ignore next -- @preserve */
206
- default:
207
- throw new Error("invalid public key format");
208
- }
209
- switch (destinationFormat) {
210
- case "raw":
211
- return publicKeyObject.pub.data.toString("hex");
212
- case "der":
213
- return SubjectPublicKeyInfoASN.encode(publicKeyObject, "der").toString("hex");
214
- case "pem":
215
- return SubjectPublicKeyInfoASN.encode(
216
- publicKeyObject,
217
- "pem",
218
- this.options.publicPEMOptions
219
- );
220
- /* v8 ignore next -- @preserve */
221
- default:
222
- throw new Error("invalid destination format for public key");
223
- }
224
- }
225
- };
226
-
227
- // src/crypto/utils.ts
228
- var _crypto = require('crypto'); var _crypto2 = _interopRequireDefault(_crypto);
229
- function extractPublicKey(pemKey) {
230
- const pem = pemKey.split("\n");
231
- pem.shift();
232
- pem.pop();
233
- const keyBuffer = Buffer.from(pem.join(""), "base64");
234
- const actualKeyBuffer = keyBuffer.slice(26);
235
- return actualKeyBuffer.toString("hex").toUpperCase();
236
- }
237
- function hexToPem(hexString, { isPrivate = true } = {}) {
238
- const keyEncoder = new KeyEncoder("p256");
239
- if (isPrivate) {
240
- return keyEncoder.encodePrivate(hexString, "raw", "pem");
241
- }
242
- return keyEncoder.encodePublic(hexString, "raw", "pem");
243
- }
244
- function genKeys(entropy) {
245
- if (entropy) {
246
- const ec = new _elliptic2.default.ec("p256");
247
- const hashedEntropy = _crypto2.default.createHash("sha256").update(entropy).digest("hex");
248
- const keyPair = ec.genKeyPair({
249
- entropy: Buffer.from(hashedEntropy, "hex")
250
- });
251
- return {
252
- privateKey: String(hexToPem(keyPair.getPrivate("hex"))),
253
- publicKey: String(hexToPem(keyPair.getPublic("hex"), { isPrivate: false })),
254
- hexPubKey: extractPublicKey(String(hexToPem(keyPair.getPublic("hex"), { isPrivate: false })))
255
- };
256
- }
257
- const { publicKey, privateKey } = _crypto2.default.generateKeyPairSync("ec", {
258
- namedCurve: "P-256",
259
- publicKeyEncoding: { type: "spki", format: "pem" },
260
- privateKeyEncoding: { type: "sec1", format: "pem" }
261
- });
262
- const hexPubKey = extractPublicKey(publicKey);
263
- return {
264
- privateKey,
265
- publicKey,
266
- hexPubKey
267
- };
268
- }
269
- var sign = async (privateKeyPem, base64Challenge) => {
270
- const challengeDataBytes = jose.base64url.decode(base64Challenge);
271
- const privateKey = _crypto2.default.createPrivateKey(privateKeyPem);
272
- return await new jose.CompactSign(challengeDataBytes).setProtectedHeader({ alg: "ES256", typ: "JWT" }).sign(privateKey);
273
- };
274
-
275
-
276
-
277
-
278
-
279
- exports.genSeed = genSeed; exports.genKeys = genKeys; exports.sign = sign;
280
- /* v8 ignore else -- @preserve */
281
- /* v8 ignore if -- @preserve */
282
- //# sourceMappingURL=chunk-2WGM7EWA.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["/home/runner/_work/revault/revault/packages/sdk/lib/chunk-2WGM7EWA.cjs","../src/crypto/gen-seed.ts","../src/crypto/utils.ts","../src/crypto/key-encoder.ts"],"names":[],"mappings":"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","file":"/home/runner/_work/revault/revault/packages/sdk/lib/chunk-2WGM7EWA.cjs","sourcesContent":[null,"import { sha256 } from \"@noble/hashes/sha2.js\";\nimport { entropyToMnemonic } from \"@scure/bip39\";\nimport { wordlist } from \"@scure/bip39/wordlists/english.js\";\n\n/**\n * Generate a deterministic BIP39 mnemonic from a salt and device index.\n *\n * Produces `entropyToMnemonic(SHA256(salt + \"_\" + index))`, matching\n * the behavior of `@ledgerhq/vault-common`'s `genSeed`.\n *\n * @param salt The workspace salt\n * @param index The device index (1-based)\n * @returns A 24-word BIP39 mnemonic string\n */\nexport function genSeed(salt: string, index: number): string {\n const input = new TextEncoder().encode(`${salt}_${index}`);\n const entropy = sha256(input);\n return entropyToMnemonic(entropy, wordlist);\n}\n","import elliptic from \"elliptic\";\nimport * as jose from \"jose\";\n\nimport { KeyEncoder } from \"./key-encoder\";\nimport type { GeneratedKeys } from \"./types\";\nimport crypto from \"node:crypto\";\n\nfunction extractPublicKey(pemKey: string): string {\n // convert the PEM formatted public key to raw public key in X9.62 uncompressed format\n // this is an oversimplified method and may not work with different curves or PEM formats\n const pem = pemKey.split(\"\\n\");\n pem.shift(); // remove the first line (BEGIN PUBLIC KEY)\n pem.pop(); // remove the last line (END PUBLIC KEY)\n // convert base64 to buffer\n const keyBuffer = Buffer.from(pem.join(\"\"), \"base64\");\n // assuming the first 26 bytes are the header for the SPKI formatted key.\n // the actual key should begin after this header.\n const actualKeyBuffer = keyBuffer.slice(26);\n return actualKeyBuffer.toString(\"hex\").toUpperCase();\n}\n\nfunction hexToPem(hexString: string, { isPrivate = true } = {}): string {\n const keyEncoder = new KeyEncoder(\"p256\");\n if (isPrivate) {\n return keyEncoder.encodePrivate(hexString, \"raw\", \"pem\");\n }\n return keyEncoder.encodePublic(hexString, \"raw\", \"pem\");\n}\n\n/**\n * If `entropy` is passed, will generate keys pair deterministically\n * else, random keys pair generated\n */\nexport function genKeys(entropy?: string): GeneratedKeys {\n if (entropy) {\n const ec = new elliptic.ec(\"p256\");\n const hashedEntropy = crypto.createHash(\"sha256\").update(entropy).digest(\"hex\");\n const keyPair = ec.genKeyPair({\n entropy: Buffer.from(hashedEntropy, \"hex\"),\n });\n return {\n privateKey: String(hexToPem(keyPair.getPrivate(\"hex\"))),\n publicKey: String(hexToPem(keyPair.getPublic(\"hex\"), { isPrivate: false })),\n hexPubKey: extractPublicKey(String(hexToPem(keyPair.getPublic(\"hex\"), { isPrivate: false }))),\n };\n }\n const { publicKey, privateKey } = crypto.generateKeyPairSync(\"ec\", {\n namedCurve: \"P-256\",\n publicKeyEncoding: { type: \"spki\", format: \"pem\" },\n privateKeyEncoding: { type: \"sec1\", format: \"pem\" },\n });\n const hexPubKey = extractPublicKey(publicKey);\n return {\n privateKey,\n publicKey,\n hexPubKey,\n };\n}\n\nexport const sign = async (privateKeyPem: string, base64Challenge: string): Promise<string> => {\n // Decode base64url challenge to bytes\n const challengeDataBytes = jose.base64url.decode(base64Challenge);\n\n // For EC private key format, we need to use a different import method\n // Since jose doesn't support SEC1 format directly, let's use Node.js crypto\n // Create a KeyObject from the EC private key\n const privateKey = crypto.createPrivateKey(privateKeyPem);\n\n // Use jose with the KeyObject\n return await new jose.CompactSign(challengeDataBytes)\n .setProtectedHeader({ alg: \"ES256\", typ: \"JWT\" })\n .sign(privateKey);\n};\n","// ========================================================================== //\n// //\n// DISCLAIMER //\n// //\n// This code has been blindly copy-pasted from: //\n// https://github.com/LedgerHQ/pkey-ts //\n// //\n// ========================================================================== //\n//\n// @ts-expect-error this library does not ship types\nimport asn1 from \"asn1.js\";\nimport BN from \"bn.js\";\nimport elliptic from \"elliptic\";\n\n/* cspell:disable */\nconst ECPrivateKeyASN = asn1.define(\"ECPrivateKey\", function () {\n // @ts-expect-error pure black box\n // biome-ignore lint/suspicious/noExplicitAny: black box\n const self = this as any;\n self\n .seq()\n .obj(\n self.key(\"version\").int(),\n self.key(\"privateKey\").octstr(),\n self.key(\"parameters\").explicit(0).objid().optional(),\n self.key(\"publicKey\").explicit(1).bitstr().optional(),\n );\n});\n\nconst ECPrivateKey8ASN = asn1.define(\n \"ECPrivateKey\",\n /* v8 ignore next -- @preserve */\n function () {\n // @ts-expect-error pure black box\n // biome-ignore lint/suspicious/noExplicitAny: black box\n const self = this as any;\n self\n .seq()\n .obj(\n self.key(\"version\").int(),\n self\n .key(\"privateKeyAlgorithm\")\n .seq()\n .obj(self.key(\"ecPublicKey\").objid(), self.key(\"curve\").objid()),\n self.key(\"privateKey\").octstr().contains(ECPrivateKeyASN),\n self.key(\"attributes\").explicit(0).bitstr().optional(),\n );\n },\n);\n\nconst SubjectPublicKeyInfoASN = asn1.define(\"SubjectPublicKeyInfo\", function () {\n // @ts-expect-error pure black box\n // biome-ignore lint/suspicious/noExplicitAny: black box\n const self = this as any;\n self\n .seq()\n .obj(\n self.key(\"algorithm\").seq().obj(self.key(\"id\").objid(), self.key(\"curve\").objid()),\n self.key(\"pub\").bitstr(),\n );\n});\n\ntype CurveOptions = {\n curveParameters: number[];\n privatePEMOptions: { label: string };\n publicPEMOptions: { label: string };\n curve: elliptic.ec;\n};\n\nconst curves: Record<string, CurveOptions> = {\n secp256k1: {\n curveParameters: [1, 3, 132, 0, 10],\n privatePEMOptions: { label: \"EC PRIVATE KEY\" },\n publicPEMOptions: { label: \"PUBLIC KEY\" },\n curve: new elliptic.ec(\"secp256k1\"),\n },\n p256: {\n curveParameters: [1, 2, 840, 10045, 3, 1, 7], // OID for p256 curve\n privatePEMOptions: { label: \"EC PRIVATE KEY\" },\n publicPEMOptions: { label: \"PUBLIC KEY\" },\n curve: new elliptic.ec(\"p256\"),\n },\n};\n\ntype PrivateKeyPKCS1 = {\n version: BN;\n privateKey: Buffer;\n parameters: number[];\n publicKey?: {\n unused: number;\n data: Buffer;\n };\n};\n\ntype PrivateKeyPKCS8 = {\n version: BN;\n privateKey: PrivateKeyPKCS1;\n privateKeyAlgorithm: { ecPublicKey: number[]; curve: number[] };\n};\n\nexport type KeyFormat = \"raw\" | \"pem\" | \"der\";\n\nexport class KeyEncoder {\n algorithmID: number[];\n options: CurveOptions;\n\n constructor(options: string | CurveOptions) {\n /* v8 ignore else -- @preserve */\n if (typeof options === \"string\") {\n /* v8 ignore if -- @preserve */\n if (options !== \"secp256k1\" && options !== \"p256\") {\n throw new Error(`Unknown curve ${options}`);\n }\n options = curves[options]!;\n }\n this.options = options;\n this.algorithmID = [1, 2, 840, 10045, 2, 1];\n }\n\n /* v8 ignore next -- @preserve */\n private PKCS1toPKCS8(privateKey: PrivateKeyPKCS1): PrivateKeyPKCS8 {\n return {\n version: new BN(0),\n privateKey,\n privateKeyAlgorithm: {\n ecPublicKey: this.algorithmID,\n curve: privateKey.parameters,\n },\n };\n }\n\n privateKeyObject(rawPrivateKey: string, rawPublicKey: string): PrivateKeyPKCS1 {\n const privateKeyObject: PrivateKeyPKCS1 = {\n version: new BN(1),\n privateKey: Buffer.from(rawPrivateKey, \"hex\"),\n parameters: this.options.curveParameters,\n };\n\n /* v8 ignore else -- @preserve */\n if (rawPublicKey) {\n privateKeyObject.publicKey = {\n unused: 0,\n data: Buffer.from(rawPublicKey, \"hex\"),\n };\n }\n\n return privateKeyObject;\n }\n\n publicKeyObject(rawPublicKey: string): {\n algorithm: { id: number[]; curve: number[] };\n pub: { unused: number; data: Buffer };\n } {\n return {\n algorithm: {\n id: this.algorithmID,\n curve: this.options.curveParameters,\n },\n pub: {\n unused: 0,\n data: Buffer.from(rawPublicKey, \"hex\"),\n },\n };\n }\n\n encodePrivate(\n privateKey: string | Buffer,\n originalFormat: KeyFormat,\n destinationFormat: KeyFormat,\n destinationFormatType: \"pkcs8\" | \"pkcs1\" = \"pkcs1\",\n ): string {\n let privateKeyObject: PrivateKeyPKCS1;\n\n /* Parse the incoming private key and convert it to a private key object */\n switch (originalFormat) {\n case \"raw\": {\n if (typeof privateKey !== \"string\") {\n throw new Error(\"private key must be a string\");\n }\n const keyPair = this.options.curve.keyFromPrivate(privateKey, \"hex\");\n const rawPublicKey = keyPair.getPublic(\"hex\");\n privateKeyObject = this.privateKeyObject(privateKey, rawPublicKey);\n break;\n }\n /* v8 ignore next -- @preserve */\n case \"der\":\n if (typeof privateKey === \"string\") {\n privateKey = Buffer.from(privateKey, \"hex\");\n }\n privateKeyObject = ECPrivateKeyASN.decode(privateKey, \"der\");\n break;\n case \"pem\":\n if (typeof privateKey !== \"string\") {\n throw new Error(\"private key must be a string\");\n }\n privateKeyObject = ECPrivateKeyASN.decode(\n privateKey,\n \"pem\",\n this.options.privatePEMOptions,\n );\n break;\n /* v8 ignore next -- @preserve */\n default:\n throw new Error(\"invalid private key format\");\n }\n\n /* Export the private key object to the desired format */\n switch (destinationFormat) {\n case \"raw\":\n if (destinationFormatType === \"pkcs1\") {\n return privateKeyObject.privateKey.toString(\"hex\");\n } else if (destinationFormatType === \"pkcs8\") {\n return this.PKCS1toPKCS8(privateKeyObject).privateKey.privateKey.toString(\"hex\");\n }\n break;\n case \"der\":\n if (destinationFormatType === \"pkcs1\") {\n return ECPrivateKeyASN.encode(privateKeyObject, \"der\").toString(\"hex\");\n } else if (destinationFormatType === \"pkcs8\") {\n return ECPrivateKey8ASN.encode(this.PKCS1toPKCS8(privateKeyObject), \"der\").toString(\n \"hex\",\n );\n }\n break;\n case \"pem\":\n if (destinationFormatType === \"pkcs1\") {\n return ECPrivateKeyASN.encode(privateKeyObject, \"pem\", this.options.privatePEMOptions);\n } else if (destinationFormatType === \"pkcs8\") {\n return ECPrivateKey8ASN.encode(this.PKCS1toPKCS8(privateKeyObject), \"pem\", {\n ...this.options.privatePEMOptions,\n label: \"PRIVATE KEY\",\n });\n }\n break;\n /* v8 ignore next -- @preserve */\n default:\n throw new Error(\"invalid destination format for private key\");\n }\n\n throw new Error(\"unsupported destination format or type\");\n }\n\n encodePublic(\n publicKey: string | Buffer,\n originalFormat: KeyFormat,\n destinationFormat: KeyFormat,\n ): string {\n // biome-ignore lint/suspicious/noImplicitAnyLet: melting pot object\n let publicKeyObject;\n\n switch (originalFormat) {\n case \"raw\":\n if (typeof publicKey !== \"string\") {\n throw new Error(\"public key must be a string\");\n }\n publicKeyObject = this.publicKeyObject(publicKey);\n break;\n /* v8 ignore next -- @preserve */\n case \"der\":\n if (typeof publicKey === \"string\") {\n publicKey = Buffer.from(publicKey, \"hex\");\n }\n publicKeyObject = SubjectPublicKeyInfoASN.decode(publicKey, \"der\");\n break;\n case \"pem\":\n if (typeof publicKey !== \"string\") {\n throw new Error(\"public key must be a string\");\n }\n publicKeyObject = SubjectPublicKeyInfoASN.decode(\n publicKey,\n \"pem\",\n this.options.publicPEMOptions,\n );\n break;\n /* v8 ignore next -- @preserve */\n default:\n throw new Error(\"invalid public key format\");\n }\n\n /* Export the private key object to the desired format */\n switch (destinationFormat) {\n case \"raw\":\n return publicKeyObject.pub.data.toString(\"hex\");\n case \"der\":\n return SubjectPublicKeyInfoASN.encode(publicKeyObject, \"der\").toString(\"hex\");\n case \"pem\":\n return SubjectPublicKeyInfoASN.encode(\n publicKeyObject,\n \"pem\",\n this.options.publicPEMOptions,\n );\n /* v8 ignore next -- @preserve */\n default:\n throw new Error(\"invalid destination format for public key\");\n }\n }\n}\n/* cspell:enable */\n"]}
@@ -1,50 +0,0 @@
1
- // src/utils.ts
2
- import invariant from "invariant";
3
- async function fetchAll(queryFn, query, trpcContext) {
4
- const res = [];
5
- let page = 1;
6
- while (page) {
7
- const partial = await queryFn({ ...query, page }, trpcContext);
8
- res.push(...partial.results);
9
- page = partial.next;
10
- }
11
- return res;
12
- }
13
- async function fetchAllCursor(queryFn, query) {
14
- const res = [];
15
- let cursor = null;
16
- do {
17
- const partial = await queryFn({ ...query, ...cursor === null ? {} : { cursor } });
18
- res.push(...partial.results);
19
- cursor = partial.next;
20
- } while (cursor);
21
- return res;
22
- }
23
- function createDeviceIndexResolver(engine) {
24
- const _deviceUserIdByDeviceIndexCache = {};
25
- return async function findDeviceIndex(deviceUserId) {
26
- let deviceIndex = null;
27
- for (let i = 4; i < 50; i++) {
28
- const promise = i in _deviceUserIdByDeviceIndexCache ? _deviceUserIdByDeviceIndexCache[i] : engine.withDeviceIndex(i).device.getDeviceUserId();
29
- _deviceUserIdByDeviceIndexCache[i] = promise;
30
- const candidate = await promise;
31
- if (candidate.toUpperCase() === deviceUserId.toUpperCase()) {
32
- deviceIndex = i;
33
- break;
34
- }
35
- }
36
- invariant(deviceIndex, `Could not find index for device user id ${deviceUserId}`);
37
- return deviceIndex;
38
- };
39
- }
40
- function buildTrpcContext(opts) {
41
- return opts?.correlationId ? { context: { headers: { "x-correlation-id": opts.correlationId } } } : void 0;
42
- }
43
-
44
- export {
45
- fetchAll,
46
- fetchAllCursor,
47
- createDeviceIndexResolver,
48
- buildTrpcContext
49
- };
50
- //# sourceMappingURL=chunk-AXI72NFY.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/utils.ts"],"sourcesContent":["import type { CursorPaginated, Paginated } from \"@ledgerhq/revault-api\";\nimport invariant from \"invariant\";\n\nimport type { CorrelationIdOpts, Engine, WithWorkspace } from \"./engine/types\";\nimport type { TRPCContext } from \"./trpc\";\n\n/**\n * Utility function that collect results on all pages until there is no more next page\n */\nexport async function fetchAll<TData, TQuery extends { page?: number }>(\n queryFn: (query: TQuery, trpcContext?: TRPCContext) => Promise<Paginated<TData>>,\n query: TQuery,\n trpcContext?: TRPCContext,\n): Promise<TData[]> {\n const res: TData[] = [];\n let page: number | null = 1;\n while (page) {\n const partial = await queryFn({ ...query, page }, trpcContext);\n res.push(...partial.results);\n page = partial.next;\n }\n return res;\n}\n\n/**\n * Utility function that collect results on all cursors until cursor is null\n */\nexport async function fetchAllCursor<TData, TQuery extends { cursor?: number | string }>(\n queryFn: (query: TQuery) => Promise<CursorPaginated<TData>>,\n query: TQuery,\n): Promise<TData[]> {\n const res: TData[] = [];\n let cursor: number | string | null = null;\n do {\n const partial = await queryFn({ ...query, ...(cursor === null ? {} : { cursor }) });\n res.push(...partial.results);\n cursor = partial.next;\n } while (cursor);\n return res;\n}\n\n/**\n * Return a function that retrieve a device index based on a given deviceUserId\n * Holds a cache of found indexes to avoid spamming device-api\n */\nexport function createDeviceIndexResolver(engine: Engine<WithWorkspace>) {\n // Cache to avoid spamming device-api when seeking for same index multiple times\n const _deviceUserIdByDeviceIndexCache: Record<string, Promise<string>> = {};\n\n return async function findDeviceIndex(deviceUserId: string): Promise<number> {\n let deviceIndex: number | null = null;\n for (let i = 4; i < 50; i++) {\n const promise =\n i in _deviceUserIdByDeviceIndexCache\n ? _deviceUserIdByDeviceIndexCache[i]!\n : engine.withDeviceIndex(i).device.getDeviceUserId();\n _deviceUserIdByDeviceIndexCache[i] = promise;\n const candidate = await promise;\n // /!\\ we need to decide in which casing we want this information\n // -> device-api returns it in uppercase\n // -> we save it in lowercase in revault-api DB\n // -> doing \"safe\" comparison here by always user the uppercase version, but hey!\n if (candidate.toUpperCase() === deviceUserId.toUpperCase()) {\n deviceIndex = i;\n break;\n }\n }\n invariant(deviceIndex, `Could not find index for device user id ${deviceUserId}`);\n return deviceIndex;\n };\n}\n\nexport function buildTrpcContext(opts?: CorrelationIdOpts) {\n return opts?.correlationId\n ? { context: { headers: { \"x-correlation-id\": opts.correlationId } } }\n : undefined;\n}\n"],"mappings":";AACA,OAAO,eAAe;AAQtB,eAAsB,SACpB,SACA,OACA,aACkB;AAClB,QAAM,MAAe,CAAC;AACtB,MAAI,OAAsB;AAC1B,SAAO,MAAM;AACX,UAAM,UAAU,MAAM,QAAQ,EAAE,GAAG,OAAO,KAAK,GAAG,WAAW;AAC7D,QAAI,KAAK,GAAG,QAAQ,OAAO;AAC3B,WAAO,QAAQ;AAAA,EACjB;AACA,SAAO;AACT;AAKA,eAAsB,eACpB,SACA,OACkB;AAClB,QAAM,MAAe,CAAC;AACtB,MAAI,SAAiC;AACrC,KAAG;AACD,UAAM,UAAU,MAAM,QAAQ,EAAE,GAAG,OAAO,GAAI,WAAW,OAAO,CAAC,IAAI,EAAE,OAAO,EAAG,CAAC;AAClF,QAAI,KAAK,GAAG,QAAQ,OAAO;AAC3B,aAAS,QAAQ;AAAA,EACnB,SAAS;AACT,SAAO;AACT;AAMO,SAAS,0BAA0B,QAA+B;AAEvE,QAAM,kCAAmE,CAAC;AAE1E,SAAO,eAAe,gBAAgB,cAAuC;AAC3E,QAAI,cAA6B;AACjC,aAAS,IAAI,GAAG,IAAI,IAAI,KAAK;AAC3B,YAAM,UACJ,KAAK,kCACD,gCAAgC,CAAC,IACjC,OAAO,gBAAgB,CAAC,EAAE,OAAO,gBAAgB;AACvD,sCAAgC,CAAC,IAAI;AACrC,YAAM,YAAY,MAAM;AAKxB,UAAI,UAAU,YAAY,MAAM,aAAa,YAAY,GAAG;AAC1D,sBAAc;AACd;AAAA,MACF;AAAA,IACF;AACA,cAAU,aAAa,2CAA2C,YAAY,EAAE;AAChF,WAAO;AAAA,EACT;AACF;AAEO,SAAS,iBAAiB,MAA0B;AACzD,SAAO,MAAM,gBACT,EAAE,SAAS,EAAE,SAAS,EAAE,oBAAoB,KAAK,cAAc,EAAE,EAAE,IACnE;AACN;","names":[]}