@ledgerhq/revault-sdk 0.28.10 → 0.28.13
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/lib/bake.cjs +3 -3
- package/lib/bake.cjs.map +1 -1
- package/lib/bake.d.cts +2 -2
- package/lib/bake.d.ts +2 -2
- package/lib/bake.js +3 -3
- package/lib/bake.js.map +1 -1
- package/lib/{crypto-BTN8FS8v.cjs → crypto-CKLQSwr3.cjs} +48 -12
- package/lib/crypto-CKLQSwr3.cjs.map +1 -0
- package/lib/{crypto-BcqzGi2f.js → crypto-hrnmToQa.js} +48 -11
- package/lib/crypto-hrnmToQa.js.map +1 -0
- package/lib/crypto.cjs +1 -1
- package/lib/crypto.js +1 -1
- package/lib/{device-DQyYUWPl.js → device-BnO26Hlr.js} +90 -34
- package/lib/device-BnO26Hlr.js.map +1 -0
- package/lib/{device-DQ32fSI-.cjs → device-CvgFoib2.cjs} +113 -33
- package/lib/device-CvgFoib2.cjs.map +1 -0
- package/lib/device.cjs +3 -1
- package/lib/device.d.cts +2 -2
- package/lib/device.d.ts +2 -2
- package/lib/device.js +2 -2
- package/lib/engine.cjs +93 -53
- package/lib/engine.cjs.map +1 -1
- package/lib/engine.d.cts +2 -2
- package/lib/engine.d.ts +2 -2
- package/lib/engine.js +94 -54
- package/lib/engine.js.map +1 -1
- package/lib/{index-xlQiIxlX.d.ts → index-16zV3onR.d.ts} +1 -1
- package/lib/{index-B3IUJM2r.d.cts → index-BAb2WCcL.d.cts} +25 -14
- package/lib/{index-Doiqe3tk.d.cts → index-CliA8Mh-.d.cts} +1 -1
- package/lib/{index-B1WQdM71.d.ts → index-DQgupTPR.d.ts} +25 -14
- package/lib/index.cjs +1 -1
- package/lib/index.cjs.map +1 -1
- package/lib/index.js +1 -1
- package/lib/index.js.map +1 -1
- package/lib/onboarding.cjs +6 -2
- package/lib/onboarding.cjs.map +1 -1
- package/lib/onboarding.d.cts +2 -2
- package/lib/onboarding.d.ts +2 -2
- package/lib/onboarding.js +6 -2
- package/lib/onboarding.js.map +1 -1
- package/lib/{types-DzZQZPXO.d.cts → types-bfqkmpgo.d.cts} +2 -1
- package/lib/{types-DqjcDy4H.d.ts → types-tRODcWIL.d.ts} +2 -1
- package/package.json +4 -5
- package/lib/crypto-BTN8FS8v.cjs.map +0 -1
- package/lib/crypto-BcqzGi2f.js.map +0 -1
- package/lib/device-DQ32fSI-.cjs.map +0 -1
- package/lib/device-DQyYUWPl.js.map +0 -1
package/lib/engine.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"engine.js","names":[],"sources":["../src/device/real-device.ts","../src/trpc.ts","../src/engine/index.ts"],"sourcesContent":["import { DisconnectedDevice, LockedDeviceError } from \"@ledgerhq/errors\";\nimport type Transport from \"@ledgerhq/hw-transport\";\nimport type { HsmCertificate, PubKey, RefreshPskData } from \"@ledgerhq/revault-api\";\nimport invariant from \"invariant\";\nimport { from, lastValueFrom } from \"rxjs\";\n\nimport type { Logger } from \"@/logger\";\n\nimport {\n APPID_VAULT_ADMINISTRATOR,\n PAGINATED_STATUS,\n PATHS,\n SCRIPT_IDS,\n STATUS_LENGTH,\n STR_ROLES,\n STREAMING_NEXT_ACTION,\n STREAMING_RESPONSE,\n} from \"./constants\";\nimport { withDevicePolling } from \"./device-access\";\nimport type { Device, PairingStatus } from \"./types\";\nimport { isTransportStatusError } from \"./utils\";\n\nconst MAX_CHUNK_LENGTH = 250;\n\ntype Options = {\n transportId: string;\n};\n\nconst getPathFromPathString = (pathString: string): number[] => {\n const parts = pathString.split(\"'/\").map((part) => Number.parseInt(part, 10));\n return parts.map((part) => (part | 0x80000000) >>> 0);\n};\n\nconst splitChunks = (chunk: number, buffer: Buffer): Buffer[] => {\n const chunks = [];\n for (let i = 0, size = chunk; i < buffer.length; i += size, size = chunk) {\n chunks.push(buffer.slice(i, i + size));\n }\n return chunks;\n};\n\nconst removeStatus = (result: Buffer): Buffer => result.slice(0, result.length - STATUS_LENGTH);\n\nconst sendByChunk = async (\n transport: Transport,\n command: number[], // eg [0xe0, 0x45, 0x00, 0x00]\n data: Buffer,\n chunkSize: number = MAX_CHUNK_LENGTH,\n): Promise<Buffer> => {\n const chunks = splitChunks(chunkSize, data);\n let response = Buffer.from([]);\n for (let i = 0; i < chunks.length; i++) {\n const chunk = chunks[i];\n const apdu = [...command];\n // command is 0xe0,0x45,0x00,0x00 for first chunk, then it's 0xe0,0x45,0x80,0x00\n /* v8 ignore next -- @preserve */\n apdu[2] = i && 0x80;\n response = (await transport.send(apdu[0]!, apdu[1]!, apdu[2], apdu[3]!, chunk, [\n 0x9000,\n ...PAGINATED_STATUS,\n ])) as Buffer<ArrayBuffer>;\n }\n return response;\n};\n\nconst buildAttestation = (params: {\n handshake: string;\n handshakeAttestation: HsmCertificate;\n partitionId: string;\n}): Buffer => {\n const sigBuffer = Buffer.from(params.handshakeAttestation.signature, \"base64\");\n const sigLengthBuffer = Buffer.alloc(1);\n sigLengthBuffer.writeUIntBE(sigBuffer.length, 0, 1);\n\n const certBuffer = Buffer.from(params.handshakeAttestation.certificate, \"base64\");\n const certLengthBuffer = Buffer.alloc(1);\n certLengthBuffer.writeUIntBE(certBuffer.length, 0, 1);\n\n const pubBuffer = Buffer.from(params.handshakeAttestation.attestationPub, \"base64\");\n\n const certChainData = Buffer.concat([\n sigLengthBuffer,\n sigBuffer,\n pubBuffer,\n certLengthBuffer,\n certBuffer,\n ]);\n\n const cliMsgBuffer = Buffer.from(params.handshake, \"hex\");\n const cliMsgLengthBuffer = Buffer.alloc(1);\n cliMsgLengthBuffer.writeUIntBE(cliMsgBuffer.length, 0, 1);\n\n const pidBuffer = Buffer.from(params.partitionId, \"hex\");\n const pidLengthBuffer = Buffer.alloc(1);\n pidLengthBuffer.writeUIntBE(pidBuffer.length, 0, 1);\n\n const certChainDataLengthBuff = Buffer.alloc(2);\n certChainDataLengthBuff.writeUInt16BE(certChainData.length, 0);\n\n const data = Buffer.concat([\n cliMsgLengthBuffer,\n cliMsgBuffer,\n certChainDataLengthBuff,\n certChainData,\n pidLengthBuffer,\n pidBuffer,\n ]);\n\n const totalLengthBuffer = Buffer.alloc(2);\n totalLengthBuffer.writeUInt16BE(data.length, 0);\n\n const toSend = Buffer.concat([totalLengthBuffer, data]);\n\n return toSend;\n};\n\n// Wire-format builder for FINALIZE_PSK_REFRESH (`0xE0 0x53`). Same layout as `buildAttestation`\n// (consumed by the device's `parse_nn_handshake_payload`), but the trailing TLV carries the\n// encrypted PairingPayload from `RefreshPsk` instead of a partition ID.\n//\n// Layout after the leading 2-byte total length:\n// [1] handshake length (the NN responder handshake, written from its actual decoded length)\n// [N] handshake bytes\n// [2] cert-chain-data length (BE)\n// [1] handshake-cert (DER signature) length\n// [N] handshake-cert bytes\n// [65] vault attestation pubkey (raw 0x04|x|y, no length prefix)\n// [1] att-cert length\n// [M] att-cert bytes\n// [1] ciphered-payload length\n// [K] encrypted PairingPayload bytes\nconst buildPskRefreshPayload = (params: RefreshPskData): Buffer => {\n const sigBuffer = Buffer.from(params.handshakeAttestation.signature, \"base64\");\n const sigLengthBuffer = Buffer.alloc(1);\n sigLengthBuffer.writeUIntBE(sigBuffer.length, 0, 1);\n\n const certBuffer = Buffer.from(params.handshakeAttestation.certificate, \"base64\");\n const certLengthBuffer = Buffer.alloc(1);\n certLengthBuffer.writeUIntBE(certBuffer.length, 0, 1);\n\n const pubBuffer = Buffer.from(params.handshakeAttestation.attestationPub, \"base64\");\n\n const certChainData = Buffer.concat([\n sigLengthBuffer,\n sigBuffer,\n pubBuffer,\n certLengthBuffer,\n certBuffer,\n ]);\n\n const handshakeBuffer = Buffer.from(params.handshake, \"base64\");\n invariant(\n handshakeBuffer.length <= 255,\n `PSK refresh handshake too long: ${handshakeBuffer.length} bytes (max 255)`,\n );\n const handshakeLengthBuffer = Buffer.alloc(1);\n handshakeLengthBuffer.writeUInt8(handshakeBuffer.length, 0);\n\n const encryptedPayloadBuffer = Buffer.from(params.encryptedPairingPayload, \"base64\");\n invariant(\n encryptedPayloadBuffer.length <= 255,\n `PSK encrypted payload too long: ${encryptedPayloadBuffer.length} bytes (max 255)`,\n );\n const encryptedPayloadLengthBuffer = Buffer.alloc(1);\n encryptedPayloadLengthBuffer.writeUInt8(encryptedPayloadBuffer.length, 0);\n\n const certChainDataLengthBuff = Buffer.alloc(2);\n certChainDataLengthBuff.writeUInt16BE(certChainData.length, 0);\n\n const data = Buffer.concat([\n handshakeLengthBuffer,\n handshakeBuffer,\n certChainDataLengthBuff,\n certChainData,\n encryptedPayloadLengthBuffer,\n encryptedPayloadBuffer,\n ]);\n\n const totalLengthBuffer = Buffer.alloc(2);\n totalLengthBuffer.writeUInt16BE(data.length, 0);\n\n return Buffer.concat([totalLengthBuffer, data]);\n};\n\ntype RetryOnError = (err: Error) => boolean;\n/* v8 ignore next -- @preserve */\nconst genericRetryOnError: RetryOnError = (err) => {\n // device is locked\n if (err instanceof LockedDeviceError) return true;\n // user is on dashboard when receiving a Vault app apdu\n if (isTransportStatusError(err) && err.statusCode === 0x6d09) return true;\n // VG-24797 error that can happen in BLE in some situations (still unclear)\n if (err instanceof DisconnectedDevice) return true;\n\n // for everything else, we don't want to retry\n return false;\n};\n\nexport function createRealDevice(options: Options, logger: Logger): Device {\n const { transportId } = options;\n\n async function run<T>(\n job: (transport: Transport) => Promise<T>,\n retryOnError: RetryOnError = genericRetryOnError,\n ): Promise<T> {\n return lastValueFrom(\n withDevicePolling(transportId)<T>((transport) => from(job(transport)), retryOnError),\n );\n }\n\n /* v8 ignore next -- @preserve */\n const noRetry = (): boolean => false;\n /* v8 ignore next -- @preserve */\n const alwaysRetry = (): boolean => true;\n const poll = async (\n opts: { retryOnError?: RetryOnError } = {},\n ): Promise<{ isAppOpened: boolean }> => {\n // waiting for device to be turned on\n await run(\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n async (_transport) => {},\n opts.retryOnError ?? alwaysRetry,\n );\n // checking if app is opened: should return directly on getPubKey\n try {\n await getPublicKey(PATHS.U2F, { secp256k1: true, retryOnError: noRetry });\n return { isAppOpened: true };\n } catch (err) {\n if (isTransportStatusError(err) && genericRetryOnError(err)) {\n return { isAppOpened: false };\n }\n throw err;\n }\n };\n\n const pollApp = async (appName: string): Promise<string> => {\n const res = await run((transport) =>\n transport.send(0xe0, 0xd8, 0x00, 0x00, Buffer.from(appName, \"utf8\")),\n );\n // little delay to give time to the app to be fully opened\n await new Promise((r) => setTimeout(r, 1e3));\n return res.toString(\"hex\");\n };\n\n const getPublicKey = async (\n pathString: string,\n { secp256k1, retryOnError }: { secp256k1: boolean; retryOnError?: RetryOnError },\n ): Promise<{ pubKey: string; signature: string }> => {\n logger.info(`[device] getPublicKey (${pathString})`);\n const path = getPathFromPathString(pathString);\n const data = Buffer.concat([\n Buffer.from([path.length]),\n ...path.map((derivation) => {\n const buf = Buffer.alloc(4);\n buf.writeUInt32BE(derivation, 0);\n return buf;\n }),\n ]);\n const curve = secp256k1 ? 0x01 : 0x02;\n const response = await run(\n (transport) => transport.send(0xe0, 0x40, curve, 0x00, data),\n retryOnError ?? genericRetryOnError,\n );\n const pubKeyLength = response.readInt8(0);\n const pubKey = response\n .slice(1, pubKeyLength + 1)\n .toString(\"hex\")\n .toUpperCase();\n const signature = response\n .slice(pubKeyLength + 1, response.length - STATUS_LENGTH)\n .toString(\"base64\");\n return { pubKey, signature };\n };\n\n const device: Device = {\n authenticate: async ({ challenge: { challenge, name, role, keyHandle }, workspaceName }) => {\n logger.info(`[device] Authenticate`);\n invariant(role !== \"READ_ONLY_API_KEY\", \"Invalid role for authenticate: READ_ONLY_API_KEY\");\n const applicationBuffer = Buffer.from(APPID_VAULT_ADMINISTRATOR, \"hex\");\n const nameBuffer = Buffer.from(name);\n const workspaceBuffer = Buffer.from(workspaceName);\n\n const keyHandleData = Buffer.concat([\n Buffer.from(STR_ROLES[role], \"hex\"),\n Buffer.from([nameBuffer.length]),\n nameBuffer,\n Buffer.from([workspaceBuffer.length]),\n workspaceBuffer,\n ]);\n\n const keyHandleDataLength = Buffer.alloc(2);\n keyHandleDataLength.writeUInt16BE(keyHandleData.length, 0);\n\n const data = Buffer.concat([\n Buffer.from(challenge, \"base64\"),\n applicationBuffer,\n Buffer.from([keyHandle.length]),\n Buffer.from(keyHandle, \"hex\"),\n keyHandleDataLength,\n keyHandleData,\n ]);\n\n const authentication = await run((transport) =>\n sendByChunk(transport, [0xe0, 0x02, 0x00, 0x00], data),\n );\n\n return removeStatus(authentication).toString(\"hex\");\n },\n\n finalizePairingHandshake: async (params: {\n handshake: string;\n partitionId: string;\n handshakeAttestation: HsmCertificate;\n }): Promise<string> => {\n const bufWithStatus = await run((transport) =>\n sendByChunk(transport, [0xe0, 0x47, 0x00, 0x02], buildAttestation(params)),\n );\n return removeStatus(bufWithStatus).toString(\"hex\");\n },\n\n generateSeedFragment: async (): Promise<string> => {\n logger.info(`[device] generateSeedFragment`);\n const path = getPathFromPathString(PATHS.KEY_MATERIAL);\n const data = Buffer.concat([\n Buffer.from([path.length]),\n ...path.map((derivation) => {\n const buf = Buffer.alloc(4);\n buf.writeUInt32BE(derivation, 0);\n return buf;\n }),\n ]);\n const response = await run((transport) => transport.send(0xe0, 0x44, 0x00, 0x00, data));\n return removeStatus(response).toString(\"base64\");\n },\n generateWrappingKeyFragment: async (): Promise<string> => {\n logger.info(`[device] generateWrappingKeyFragment`);\n const path = getPathFromPathString(PATHS.KEY_MATERIAL);\n const data = Buffer.concat([\n Buffer.from([path.length]),\n ...path.map((derivation) => {\n const buf = Buffer.alloc(4);\n buf.writeUInt32BE(derivation, 0);\n return buf;\n }),\n ]);\n const response = await run((transport) => transport.send(0xe0, 0x44, 0x01, 0x00, data));\n return removeStatus(response).toString(\"base64\");\n },\n getAttestation: async (): Promise<{\n attestation: {\n codeHash: string;\n attestationPub: string;\n certificate: string;\n };\n buffer: Buffer;\n }> => {\n const bufWithStatus = await run((transport) => transport.send(0xe0, 0x41, 0x00, 0x00));\n const buffer = removeStatus(bufWithStatus);\n const certLen = buffer.readInt8(32 + 65 + 1);\n return {\n attestation: {\n codeHash: buffer.slice(0, 32).toString(\"base64\"),\n attestationPub: buffer.slice(32, 32 + 65).toString(\"base64\"),\n certificate: buffer.slice(32 + 65, 32 + 65 + 2 + certLen).toString(\"base64\"),\n },\n buffer,\n };\n },\n getConfidentialityKey: async () => {\n logger.info(`[device] getConfidentialityKey`);\n const bufWithStatus = await run((transport) => transport.send(0xe0, 0x4d, 0x00, 0x00));\n const buf = removeStatus(bufWithStatus);\n const keyLength = buf[0]!;\n const key = buf.slice(1, 1 + keyLength);\n const sig = buf.slice(1 + keyLength + 1);\n return {\n confidentialityKeyCurve25519: key.toString(\"hex\"),\n confidentialityKeySignature: sig.toString(\"hex\"),\n };\n },\n getConfidentialityPubKey: () => getPublicKey(PATHS.CONFIDENTIALITY, { secp256k1: true }),\n getDeviceUserId: async (): Promise<string> => {\n logger.info(`[device] getDeviceUserId`);\n const response = await run((transport) => transport.send(0xe0, 0x52, 0x00, 0x00));\n return removeStatus(response).toString(\"hex\").toUpperCase();\n },\n getU2FPubKey: () => getPublicKey(PATHS.U2F, { secp256k1: false }),\n getValidationPubKey: () => getPublicKey(PATHS.VALIDATION, { secp256k1: true }),\n hasPairing: async (): Promise<PairingStatus> => {\n logger.info(`[device] hasPairing`);\n const apdu = [0xe0, 0x51, 0x00, 0x00, 0xb5];\n const res = await run((transport) => transport.exchange(Buffer.from(apdu)));\n\n // GET_PARTITION_IDS returns the partition list followed by a 2-byte SW. Inspect only\n // the trailing SW; the device may return data alongside non-`9000` SWs (notably 0x6065\n // — see below).\n const swHex = res.subarray(res.length - 2).toString(\"hex\");\n\n // 6f45 => no partition ID on the device (SW_NO_PARTITION_ID).\n // 6a87 => TEMPORARY hack: some firmware revs don't implement the APDU and return\n // \"incorrect length\"; treat as no pairing so revault drives the full pair-from-\n // scratch flow.\n if (swHex === \"6f45\" || swHex === \"6a87\") return \"NO_PAIRING\";\n\n // 6065 => SW_PSK_MISSING: a valid pairing record exists but its PSK field is the all-\n // zero sentinel. Skip the full pairing chain and run the refresh sub-chain.\n if (swHex === \"6065\") return \"PSK_MISSING\";\n\n // Anything else (typically 9000) => fully provisioned pairing with PSK.\n return \"OK\";\n },\n\n initPairingHandshake: async (): Promise<{ pubKey: string; signature: string }> => {\n const res = await run((transport) => transport.send(0xe0, 0x46, 0x00, 0x00));\n const pubKeyLength = res.readInt8(0);\n const pubKey = res\n .slice(1, pubKeyLength + 1)\n .toString(\"hex\")\n .toUpperCase();\n const signature = res.slice(pubKeyLength + 1, res.length - STATUS_LENGTH).toString(\"base64\");\n return { pubKey, signature };\n },\n\n openSession: async (params: {\n secureChannel: { pubKey: PubKey; certificate: HsmCertificate };\n }): Promise<void> => {\n logger.info(`[device] openSession`);\n const { secureChannel } = params;\n\n const path = getPathFromPathString(PATHS.CONFIDENTIALITY);\n const dataDerivation = Buffer.concat([\n Buffer.from([path.length]),\n ...path.map((derivation) => {\n const buf = Buffer.alloc(4);\n buf.writeUInt32BE(derivation, 0);\n return buf;\n }),\n ]);\n\n const pubKey = Buffer.from(secureChannel.pubKey, \"hex\");\n\n const sigBuffer = Buffer.from(secureChannel.certificate.signature, \"base64\");\n const attestationPubBuffer = Buffer.from(secureChannel.certificate.attestationPub, \"base64\");\n const certBuffer = Buffer.from(secureChannel.certificate.certificate, \"base64\");\n const attestation = Buffer.concat([\n Buffer.from([sigBuffer.length]),\n sigBuffer,\n attestationPubBuffer,\n Buffer.from([certBuffer.length]),\n certBuffer,\n ]);\n\n const lengthAttestation = Buffer.alloc(2);\n lengthAttestation.writeUInt16BE(attestation.length, 0);\n\n const data = Buffer.concat([dataDerivation, pubKey, lengthAttestation, attestation]);\n\n await run((transport) =>\n sendByChunk(transport, [0xe0, 0x42, 0x00, SCRIPT_IDS.INIT_SESSION], data),\n );\n },\n\n register: async (params: {\n challenge: string;\n u2fRegisterData: string;\n name: string;\n role: \"ADMIN\" | \"SHARED_OWNER\" | \"OPERATOR\";\n }): Promise<{\n u2fRegister: Buffer;\n keyHandle: Buffer;\n rfu: number;\n pubKey: string;\n }> => {\n const { challenge: strChallenge, u2fRegisterData: _, name, role } = params;\n const challenge = Buffer.from(strChallenge, \"hex\");\n\n invariant(challenge.length === 32, \"challenge hex is expected to have 32 bytes\");\n const applicationBuf = Buffer.from(APPID_VAULT_ADMINISTRATOR, \"hex\");\n invariant(applicationBuf.length === 32, \"application hex is expected to have 32 bytes\");\n\n const userNameBuff = Buffer.from(name);\n\n const keyHandleData = Buffer.concat([\n Buffer.from(STR_ROLES[role], \"hex\"),\n Buffer.from([userNameBuff.length]),\n userNameBuff,\n ]);\n\n const keyHandleDataLength = Buffer.alloc(2);\n keyHandleDataLength.writeUInt16BE(keyHandleData.length, 0);\n\n const data = Buffer.concat([challenge, applicationBuf, keyHandleDataLength, keyHandleData]);\n\n const response = await run((transport) =>\n sendByChunk(transport, [0xe0, 0x01, 0x00, 0x00], data),\n );\n\n let i = 0;\n const rfu = response.slice(i, i + 1)[0]!;\n i += 1;\n const pubKey = response.slice(i, i + 65).toString(\"hex\");\n i += 65;\n const keyHandleLength = response.slice(i, i + 1)[0]!;\n i++;\n const keyHandle = response.slice(i, i + keyHandleLength);\n i += keyHandleLength;\n return {\n u2fRegister: removeStatus(response),\n keyHandle,\n rfu,\n pubKey,\n };\n },\n registerData: async (params: { challenge: string }): Promise<string> => {\n const { challenge: strChallenge } = params;\n const challenge = Buffer.from(strChallenge, \"hex\");\n invariant(challenge.length === 32, \"challenge hex is expected to have 32 bytes\");\n const response = await run((transport) => transport.send(0xe0, 0x03, 0x00, 0x00, challenge));\n return removeStatus(response).toString(\"hex\");\n },\n\n setPairing: async ({ pairing }) => {\n logger.info(`[device] setPairing`);\n const psdPayload = Buffer.from(pairing.blob, \"base64\");\n const length = Buffer.alloc(2);\n length.writeUInt16BE(psdPayload.length, 0);\n const final = Buffer.concat([length, psdPayload]);\n await run((transport) => sendByChunk(transport, [0xe0, 0x4e, 0x00, 0x00], final));\n },\n\n // `ephemeralKey` is unused here: the firmware signs over the ephemeral it captured in its own\n // `G_nn_initiator_eph_pubkey` global at INITIALIZE_NN_HANDSHAKE, and INS 0x55 rejects any\n // payload. The arg only exists for the stateless device-api (see api-device.ts).\n signRefreshPskAuth: async (): Promise<string> => {\n logger.info(`[device] signRefreshPskAuth`);\n const res = await run((transport) => transport.send(0xe0, 0x55, 0x00, 0x00));\n return res.slice(0, res.length - STATUS_LENGTH).toString(\"base64\");\n },\n\n finalizePskRefresh: async (params: RefreshPskData): Promise<void> => {\n logger.info(`[device] finalizePskRefresh`);\n const payload = buildPskRefreshPayload(params);\n await run((transport) => sendByChunk(transport, [0xe0, 0x53, 0x00, 0x00], payload));\n },\n startKKPatternAsResponder: async (params: {\n handshake: string;\n handshakeAttestation: HsmCertificate;\n partitionId: string;\n }): Promise<{ handshake: string; signature: string }> => {\n logger.info(`[device] startKKPatternAsResponder`);\n const data = buildAttestation(params);\n const bufWithStatus = await run((transport) =>\n sendByChunk(transport, [0xe0, 0x4c, 0x00, SCRIPT_IDS.ACCOUNT_MANAGER_SESSION], data),\n );\n const buffer = removeStatus(bufWithStatus);\n const dataLength = buffer.readInt8(0);\n return {\n handshake: buffer.slice(1, dataLength + 1).toString(\"base64\"),\n signature: buffer.slice(dataLength + 1).toString(\"base64\"),\n };\n },\n startKPatternAsResponder: async (params) => {\n logger.info(`[device] startKPatternAsResponder`);\n const data = buildAttestation(params);\n await run((transport) =>\n sendByChunk(transport, [0xe0, 0x49, 0x00, SCRIPT_IDS.ACCOUNT_MANAGER_SESSION], data),\n );\n },\n startPskSession: async (params) => {\n logger.info(`[device] startPskSession`);\n // START_PSK_SESSION (0xe0 0x50): the device reads a raw `nonce(32) || partitionId(16)`\n // payload straight from cmd->data (lc must be exactly 48) — no length prefixes and no\n // attestation. The dispatcher also rejects any non-zero P1/P2 with SW_WRONG_P1P2, so\n // both stay 0 (unlike the K handshake, which ignores P2 = ACCOUNT_MANAGER_SESSION).\n invariant(\n params.nonce.length === 64,\n `PSK nonce must be 32 bytes (64 hex chars), got ${params.nonce.length} chars`,\n );\n invariant(\n params.partitionId.length === 32,\n `partitionId must be 16 bytes (32 hex chars), got ${params.partitionId.length} chars`,\n );\n const data = Buffer.concat([\n Buffer.from(params.nonce, \"hex\"),\n Buffer.from(params.partitionId, \"hex\"),\n ]);\n await run((transport) => sendByChunk(transport, [0xe0, 0x50, 0x00, 0x00], data));\n },\n validateVaultOperation: async (params) => {\n logger.info(`[device] validateVaultOperation`);\n const path = getPathFromPathString(PATHS.VALIDATION);\n const paths = Buffer.concat([\n Buffer.from([path.length]),\n ...path.map((derivation) => {\n const buf = Buffer.alloc(4);\n buf.writeUInt32BE(derivation, 0);\n return buf;\n }),\n ]);\n\n let nextActionId = 1;\n let finalResponse: Buffer | null = null;\n\n while (!finalResponse) {\n const screen = Buffer.from(params.actions[nextActionId - 1]!, \"base64\");\n const length = Buffer.alloc(2);\n length.writeUInt16BE(screen.length, 0);\n const data = Buffer.concat([paths, length, screen]);\n const response = await run((transport) =>\n sendByChunk(transport, [0xe0, 0x45, 0x00, 0x00], data),\n );\n const responseType = response.readInt8(0);\n let responseStatus = response.readUInt16BE(response.length - 2);\n switch (responseType) {\n case STREAMING_NEXT_ACTION:\n nextActionId = response.readUIntBE(1, 2);\n break;\n case STREAMING_RESPONSE:\n finalResponse = response.slice(3, response.length - 2);\n while (responseStatus !== 0x9000) {\n /* v8 ignore next -- @preserve */ {\n const resp = await run((transport) => transport.send(0x00, 0xc0, 0x00, 0x00));\n responseStatus = resp.readUInt16BE(resp.length - 2);\n finalResponse = Buffer.concat([finalResponse, removeStatus(resp)]);\n }\n }\n break;\n /* v8 ignore next -- @preserve */\n default:\n throw new Error(`Invalid response type: ${responseType}`);\n }\n }\n return finalResponse.toString(\"base64\");\n },\n\n sendAPDU: async (apduCommand: string) => {\n const res = await run((transport) => transport.exchange(Buffer.from(apduCommand, \"hex\")));\n return Buffer.from(res).toString(\"hex\");\n },\n getVersion: async () => {\n const res = await run((transport) => transport.send(0xb0, 0x01, 0x00, 0x00));\n const appNameLen = res.readInt8(1);\n const appVersionLen = res.readInt8(2 + appNameLen);\n const appVersionHex = res.slice(2 + 1 + appNameLen, 2 + appNameLen + appVersionLen + 1);\n\n const appVersion = Buffer.from(appVersionHex).toString();\n\n return appVersion;\n },\n poll,\n pollApp,\n };\n return device;\n}\n","import type { AppRouter } from \"@ledgerhq/revault-api\";\nimport { createTRPCClient, httpLink, type TRPCClient } from \"@trpc/client\";\nimport type { inferRouterInputs, inferRouterOutputs } from \"@trpc/server\";\nimport superjson from \"superjson\";\n\nexport type TRPCClientOptions = {\n baseUrl: string;\n debugAuthToken?: string;\n rootAuthToken?: string;\n apiAccessToken?: string;\n psdAuth?: string;\n};\n\nexport type RevaultApiTRPCClient = TRPCClient<AppRouter>;\n\nexport type RouterInputs = inferRouterInputs<AppRouter>;\nexport type RouterOutputs = inferRouterOutputs<AppRouter>;\n\nexport type TRPCContext = { context: Record<string, unknown> } | undefined;\n\nexport const createClient = (options: TRPCClientOptions): RevaultApiTRPCClient => {\n const trpc = createTRPCClient<AppRouter>({\n links: [\n httpLink({\n url: `${options.baseUrl}/trpc`,\n transformer: superjson,\n headers(opts) {\n // Extract headers from the operation context\n const contextHeaders = (opts.op.context?.headers as Record<string, string>) || {};\n\n return {\n ...(options.debugAuthToken\n ? { \"x-revault-debug-auth-token\": options.debugAuthToken }\n : {}),\n ...(options.rootAuthToken\n ? { \"x-revault-root-auth-token\": options.rootAuthToken }\n : {}),\n ...(options.psdAuth ? { Authorization: `PsdAuth ${options.psdAuth}` } : {}),\n ...(options.apiAccessToken\n ? { Authorization: `Bearer ${options.apiAccessToken}` }\n : {}),\n // Merge in any headers passed via context\n ...contextHeaders,\n };\n },\n }),\n ],\n });\n return trpc;\n};\n","import type {\n ApiChallenge,\n ClaimedRole,\n OnboardingSeedChallenge,\n PsdChallenge,\n UserRegistrationChallenge,\n UserRegistrationChallengeResponse,\n UserRegistrationDeviceData,\n UserRegistrationResponse,\n VaultRequestResponse,\n WrappingKeyResponse,\n} from \"@ledgerhq/revault-api\";\nimport invariant from \"invariant\";\n\nimport { createApiDevice, type Device, isPskMissingError } from \"@/device\";\nimport { createRealDevice } from \"@/device/real-device\";\nimport type { Logger } from \"@/logger\";\nimport { createClient, type RouterOutputs, type TRPCClientOptions } from \"@/trpc\";\n\nimport { buildTrpcContext } from \"../utils\";\nimport type {\n ApproveRequestParams,\n CorrelationIdOpts,\n DecorateWithApiUserAndWorkspaceUnauthenticated,\n DecorateWithDevice,\n DecorateWithDeviceAndOnboarding,\n DecorateWithDeviceAndWorkspaceUnauthenticated,\n DecorateWithWorkspaceApiAuthenticated,\n DecorateWithWorkspacePsdAuthenticated,\n DecorateWithWorkspaceUnauthenticated,\n Engine,\n EngineBase,\n EngineOptions,\n OnboardingOperationParams,\n RegisterOnboardingDeviceParams,\n WithApiAuth,\n WithApiUser,\n WithDevice,\n WithOnboarding,\n WithPsdAuth,\n WithWorkspace,\n} from \"./types\";\n\nexport { fetchAll, fetchAllCursor } from \"../utils\";\nexport type * from \"./types\";\n\nconst PSK_NONCE_BYTE_LEN = 32;\n\n// Open the per-operation secure channel matching the crypto the HSM used at Prepare, branching\n// on the challenge shape. A 32-byte `handshake` (hex, 64 chars) is the PSK HKDF nonce;\n// longer is legacy Noise-K.\nconst openSecureChannel = (\n device: Device,\n challenge: Pick<PsdChallenge, \"handshake\" | \"handshakeAttestation\" | \"partitionId\">,\n): Promise<void> => {\n if (challenge.handshake.length === PSK_NONCE_BYTE_LEN * 2) {\n return device.startPskSession({\n nonce: challenge.handshake,\n partitionId: challenge.partitionId,\n });\n }\n return device.startKPatternAsResponder({\n handshake: challenge.handshake,\n handshakeAttestation: challenge.handshakeAttestation,\n partitionId: challenge.partitionId,\n });\n};\n\ntype DeviceConfidentialityKey = Awaited<ReturnType<Device[\"getConfidentialityKey\"]>>;\ntype DevicePairing = Parameters<Device[\"setPairing\"]>[0][\"pairing\"];\ntype DeviceRefreshPskData = Parameters<Device[\"finalizePskRefresh\"]>[0];\n\ntype RefreshPskInput = {\n psdEphemeralKey: string;\n psdEphemeralKeyAttestation: {\n codeHash: string;\n attestationPub: string;\n certificate: string;\n signature: string;\n };\n validationKeySignature: string;\n};\n\nconst pairDevice = async ({\n device,\n getPairing,\n}: {\n device: Pick<Device, \"getConfidentialityKey\" | \"setPairing\">;\n getPairing: (confidentialityKey: DeviceConfidentialityKey) => Promise<DevicePairing>;\n}): Promise<void> => {\n const confidentialityKey = await device.getConfidentialityKey();\n const pairing = await getPairing(confidentialityKey);\n await device.setPairing({ pairing });\n};\n\nconst refreshPsk = async ({\n device,\n getRefreshPskData,\n}: {\n device: Pick<\n Device,\n \"finalizePskRefresh\" | \"getAttestation\" | \"initPairingHandshake\" | \"signRefreshPskAuth\"\n >;\n getRefreshPskData: (input: RefreshPskInput) => Promise<DeviceRefreshPskData>;\n}): Promise<void> => {\n // Shared refresh sub-chain: 0x46 (device NN init) + 0x55 (validation-key auth signature)\n // → HSM refresh-psk (single read-only re-delivery) → 0x53 (finalize). The HSM verifies\n // the device-attested ephemeral key and the validation-key signature, so we stitch the\n // per-ephemeral signature from INITIALIZE_NN_HANDSHAKE onto the device's static attestation\n // chain (INS_GET_ATTESTATION_CERTIFICATE) and pass the SIGN_REFRESH_PSK_AUTH signature\n // alongside. initPairingHandshake (0x46) must resolve first: the soft-device\n // signRefreshPskAuth needs the ephemeral it returns, and the firmware FSM requires 0x46\n // before 0x55.\n const eph = await device.initPairingHandshake();\n const [deviceAttestation, validationKeySignature] = await Promise.all([\n device.getAttestation(),\n device.signRefreshPskAuth({ ephemeralKey: eph.pubKey }),\n ]);\n const refresh = await getRefreshPskData({\n psdEphemeralKey: Buffer.from(eph.pubKey, \"hex\").toString(\"base64\"),\n psdEphemeralKeyAttestation: {\n codeHash: deviceAttestation.attestation.codeHash,\n attestationPub: deviceAttestation.attestation.attestationPub,\n certificate: deviceAttestation.attestation.certificate,\n signature: eph.signature,\n },\n validationKeySignature,\n });\n await device.finalizePskRefresh(refresh);\n};\n\nasync function genericRegister<T>({\n device,\n name,\n role,\n getChallenge,\n submitChallenge,\n onScreenDisplayed,\n}: {\n device: Device;\n name: string;\n role: \"ADMIN\" | \"SHARED_OWNER\" | \"OPERATOR\";\n getChallenge: (p: {\n pubKey: string;\n deviceData: UserRegistrationDeviceData;\n }) => Promise<UserRegistrationChallenge>;\n submitChallenge: (p: {\n pubKey: string;\n challengeResponse: UserRegistrationChallengeResponse;\n }) => Promise<T>;\n onScreenDisplayed?: () => void | Promise<void>;\n}): Promise<T> {\n const [attestation, u2fPubKey, confidentialityKey] = await Promise.all([\n device.getAttestation(),\n device.getU2FPubKey(),\n device.getConfidentialityPubKey(),\n ]);\n const ephemeralPubKey = await device.initPairingHandshake();\n const deviceData: UserRegistrationDeviceData = {\n name,\n pubKey: u2fPubKey.pubKey,\n psdModel: \"STAX\",\n confidentialityKey: confidentialityKey.pubKey,\n psdEphemeralKey: ephemeralPubKey.pubKey,\n psdEphemeralKeyAttestation: {\n ...attestation.attestation,\n signature: ephemeralPubKey.signature,\n },\n };\n const challenge = await getChallenge({ pubKey: u2fPubKey.pubKey, deviceData });\n const pairingPayload = await device.finalizePairingHandshake({\n handshake: challenge.handshake,\n partitionId: challenge.ciphertext,\n handshakeAttestation: challenge.handshakeAttestation,\n });\n await onScreenDisplayed?.();\n const register = await device.register({\n challenge: challenge.challenge,\n u2fRegisterData: challenge.u2fRegisterData,\n name,\n role,\n });\n const validationPubKey = await device.getValidationPubKey();\n const registerData = await device.registerData({ challenge: challenge.challenge });\n const attestationOffset = 67 + register.u2fRegister.readInt8(66);\n const u2fRegister = Buffer.concat([\n register.u2fRegister.slice(0, attestationOffset),\n Buffer.from([attestation.buffer.length]),\n attestation.buffer,\n register.u2fRegister.slice(attestationOffset),\n ]).toString(\"hex\");\n const challengeResponse: UserRegistrationChallengeResponse = {\n registerData,\n certificate: {\n ...attestation.attestation,\n signature: validationPubKey.signature,\n },\n u2fRegister,\n u2fKeyHandle: register.keyHandle.toString(\"hex\"),\n validationKey: validationPubKey.pubKey,\n pairingPayload,\n };\n return submitChallenge({ pubKey: u2fPubKey.pubKey, challengeResponse });\n}\n\nexport function createEngine(options: EngineOptions, logger: Logger): Engine {\n const clientOptions: TRPCClientOptions = {\n baseUrl: options.baseUrl,\n };\n const client = createClient(clientOptions);\n const apiDevice = createApiDevice(options, logger);\n\n const base: EngineBase = {\n client,\n createClient: (overrides) => createClient({ ...clientOptions, ...overrides }),\n __options: options,\n };\n\n const withDeviceIndex: Engine[\"withDeviceIndex\"] = function <T>(\n this: Engine<T>,\n deviceIndex: number,\n ) {\n const device = apiDevice.with(deviceIndex);\n const withPsd: WithDevice = { device };\n return decorateEngine({ ...this, ...withPsd } as Engine<T & WithDevice>);\n };\n\n const withTransportId: Engine[\"withTransportId\"] = function <T>(\n this: Engine<T>,\n transportId: string,\n ) {\n const device = createRealDevice({ transportId }, logger);\n const withPsd: WithDevice = { device };\n return decorateEngine({ ...this, ...withPsd } as Engine<T & WithDevice>);\n };\n\n const withApiUser: Engine[\"withApiUser\"] = function <T>(this: Engine<T>) {\n const withApiUser: WithApiUser = { __isApiUser: true };\n return decorateEngine({ ...this, ...withApiUser } as Engine<T & WithApiUser>);\n };\n\n const withWorkspace: Engine[\"withWorkspace\"] = function <T>(\n this: Engine<T>,\n workspaceName: string,\n ) {\n const withWorkspace: WithWorkspace = { __workspaceName: workspaceName };\n return decorateEngine({ ...this, ...withWorkspace } as Engine<T & WithWorkspace>);\n };\n\n const withOnboarding: Engine[\"withOnboarding\"] = function <T>(\n this: Engine<T>,\n onboardingId: string,\n ) {\n const withOnboarding: WithOnboarding = { __onboardingId: onboardingId };\n return decorateEngine({ ...this, ...withOnboarding } as Engine<T & WithOnboarding>);\n };\n\n function decorateEngine<T>(\n engine: Engine<\n T &\n Partial<\n WithDevice & WithOnboarding & WithWorkspace & WithPsdAuth & WithApiUser & WithApiAuth\n >\n >,\n ): Engine<T> {\n function decorate<TEnhanced, TDecoration>(\n decorator: (engine: EngineBase & TEnhanced) => TDecoration,\n ): void {\n Object.assign(engine, decorator(engine as EngineBase & TEnhanced));\n }\n\n // DecorateWithDevice\n // -------------------------------------------------------------------------\n if (engine.device) {\n decorate<WithDevice, DecorateWithDevice<T>>(\n (engine) =>\n ({\n getWorkspaces: async (): Promise<string[]> => {\n const { device, client } = engine;\n const { pubKey } = await device.getU2FPubKey();\n const { workspaceNames } = await client.auth.psd.findWorkspaceNames.query({ pubKey });\n return workspaceNames;\n },\n\n getWorkspacesForSso: async (): Promise<\n RouterOutputs[\"auth\"][\"sso\"][\"findWorkspaces\"][\"workspaces\"]\n > => {\n const { device, client } = engine;\n const { pubKey } = await device.getU2FPubKey();\n const { workspaces } = await client.auth.sso.findWorkspaces.query({ pubKey });\n return workspaces;\n },\n }) satisfies DecorateWithDevice<T>,\n );\n }\n\n // DecorateWithWorkspaceUnauthenticated\n // -------------------------------------------------------------------------\n if (engine.__workspaceName && !engine.__psdToken && !engine.__apiAuth) {\n decorate<WithWorkspace, DecorateWithWorkspaceUnauthenticated<T>>((engine) => {\n const { __workspaceName } = engine;\n return {\n withPsdToken: function <T>(this: Engine<T>, token: string): Engine<T & WithPsdAuth> {\n const withPsdAuth: WithPsdAuth = { __psdToken: token };\n const psdAuth = `${__workspaceName}:${token}`;\n const client = engine.createClient({ psdAuth });\n return decorateEngine({ ...this, client, ...withPsdAuth } as Engine<T & WithPsdAuth>);\n },\n } satisfies DecorateWithWorkspaceUnauthenticated<T>;\n });\n }\n\n // DecorateWithDeviceAndOnboarding\n // -------------------------------------------------------------------------\n if (engine.device && engine.__onboardingId) {\n decorate<WithDevice & WithOnboarding, DecorateWithDeviceAndOnboarding>((engine) => {\n const { device, client, __onboardingId } = engine;\n\n // Drive the device's pairing record + PSK to a fully-provisioned state.\n // - \"OK\" → nothing to do.\n // - \"NO_PAIRING\" → run the full pairing chain, then deliver a PSK via refresh.\n // - \"PSK_MISSING\" → pairing already exists; only run the PSK refresh sub-chain.\n async function enforcePairing(): Promise<void> {\n const status = await device.hasPairing();\n if (status === \"OK\") return;\n\n let pubKeyPromise: Promise<string> | undefined;\n const getPubKey = async (): Promise<string> => {\n pubKeyPromise ??= device.getU2FPubKey().then(({ pubKey }) => pubKey);\n return pubKeyPromise;\n };\n const refreshCurrentPsk = async (): Promise<void> => {\n const pubKey = await getPubKey();\n await refreshPsk({\n device,\n getRefreshPskData: (data) =>\n client.onboarding.refreshPsk.mutate({\n pubKey,\n onboardingId: __onboardingId,\n data,\n }),\n });\n };\n\n if (status === \"NO_PAIRING\") {\n const pubKey = await getPubKey();\n await pairDevice({\n device,\n getPairing: (confidentialityKey) =>\n client.onboarding.pairDevicePartition.mutate({\n pubKey,\n onboardingId: __onboardingId,\n data: {\n confidentialityKeyCurve25519: confidentialityKey.confidentialityKeyCurve25519,\n confidentialityKeySignature: confidentialityKey.confidentialityKeySignature,\n },\n }),\n });\n }\n\n await refreshCurrentPsk();\n }\n\n return {\n claimDevice: async (params: { role: ClaimedRole; deviceName: string }): Promise<void> => {\n const { role, deviceName } = params;\n const [{ pubKey }, { pubKey: confidentialityKey }] = await Promise.all([\n device.getU2FPubKey(),\n device.getConfidentialityPubKey(),\n ]);\n await client.onboarding.claimDevice.mutate({\n onboardingId: __onboardingId,\n claim: { role, pubKey, deviceName, confidentialityKey },\n });\n },\n\n collectWrappingKeyFragment: async (\n wrappingKey: WrappingKeyResponse,\n params?: OnboardingOperationParams,\n ): Promise<void> => {\n const [{ pubKey }, confidentialityKey] = await Promise.all([\n device.getU2FPubKey(),\n device.getConfidentialityPubKey(),\n ]);\n await device.openSession({\n secureChannel: {\n pubKey: wrappingKey.ephemeralPubKey,\n certificate: wrappingKey.ephemeralCertificate,\n },\n });\n const { attestation } = await device.getAttestation();\n await params?.onScreenDisplayed?.();\n const blob = await device.generateWrappingKeyFragment();\n await client.onboarding.submitWrappingKeyFragment.mutate({\n pubKey,\n onboardingId: __onboardingId,\n fragment: {\n blob,\n ephemeralPubKey: confidentialityKey.pubKey,\n ephemeralCertificate: {\n ...attestation,\n signature: confidentialityKey.signature,\n },\n },\n });\n },\n\n registerDevice: async (\n registerParams: RegisterOnboardingDeviceParams,\n params?: OnboardingOperationParams,\n ): Promise<void> => {\n const { role, name } = registerParams;\n const getChallengeMutation =\n role === \"ADMIN\"\n ? client.onboarding.generateMasterAdminRegistrationChallenge\n : client.onboarding.generateSharedOwnerRegistrationChallenge;\n const submitChallengeMutation =\n role === \"ADMIN\"\n ? client.onboarding.submitMasterAdminRegistration\n : client.onboarding.submitSharedOwnerRegistration;\n await genericRegister({\n device: device,\n name,\n role,\n getChallenge: ({ pubKey, deviceData }) =>\n getChallengeMutation.mutate({\n onboardingId: __onboardingId,\n pubKey,\n deviceData,\n }),\n submitChallenge: ({ pubKey, challengeResponse }) =>\n submitChallengeMutation.mutate({\n onboardingId: engine.__onboardingId,\n pubKey,\n // FIXME this should be renamed to `challengeResponse` on backend side\n response: challengeResponse,\n }),\n onScreenDisplayed: params?.onScreenDisplayed,\n });\n },\n\n reviewSharedOwner: async (\n challenge: PsdChallenge,\n params?: OnboardingOperationParams,\n ): Promise<void> => {\n await enforcePairing();\n const { pubKey } = await device.getU2FPubKey();\n await openSecureChannel(device, challenge);\n await params?.onScreenDisplayed?.();\n const signature = await device.validateVaultOperation({\n actions: challenge.wActions,\n });\n await client.onboarding.submitReviewByMasterAdminSignature.mutate({\n onboardingId: __onboardingId,\n pubKey,\n signature,\n });\n },\n\n reviewExternalSigners: async (\n challenge: PsdChallenge,\n params?: OnboardingOperationParams,\n ): Promise<void> => {\n await enforcePairing();\n const { pubKey } = await device.getU2FPubKey();\n await openSecureChannel(device, challenge);\n await params?.onScreenDisplayed?.();\n const signature = await device.validateVaultOperation({\n actions: challenge.wActions,\n });\n await client.onboarding.submitExternalSignersRegistration.mutate({\n onboardingId: __onboardingId,\n pubKey,\n signature,\n });\n },\n\n collectSeedFragment: async (\n challenge: OnboardingSeedChallenge,\n params?: OnboardingOperationParams,\n ): Promise<void> => {\n await enforcePairing();\n const [{ pubKey }, { attestation }] = await Promise.all([\n device.getU2FPubKey(),\n device.getAttestation(),\n ]);\n await openSecureChannel(device, challenge);\n await params?.onScreenDisplayed?.();\n const challengeResponse = await device.validateVaultOperation({\n actions: challenge.wActions,\n });\n const kkPattern = await device.startKKPatternAsResponder({\n partitionId: challenge.partitionId,\n handshake: challenge.kkHandshake,\n handshakeAttestation: challenge.kkHandshakeAttestation,\n });\n const approverBlob = await device.generateSeedFragment();\n await client.onboarding.submitSeedFragment.mutate({\n onboardingId: __onboardingId,\n pubKey,\n seedFragment: {\n challengeResponse,\n approverBlob,\n handshake: kkPattern.handshake,\n handshakeAttestation: {\n ...attestation,\n signature: kkPattern.signature,\n },\n },\n });\n },\n } satisfies DecorateWithDeviceAndOnboarding;\n });\n }\n\n // DecorateWithDeviceAndWorkspaceUnauthenticated\n // -------------------------------------------------------------------------\n if (engine.device && engine.__workspaceName && !engine.__psdToken) {\n decorate<WithDevice & WithWorkspace, DecorateWithDeviceAndWorkspaceUnauthenticated<T>>(\n (engine) => {\n const { device, client, __workspaceName } = engine;\n return {\n login: async function <T>(\n this: Engine<T>,\n opts?: {\n validityDurationSecs?: number;\n onScreenDisplayed?: () => void | Promise<void>;\n correlationId?: string;\n },\n ): Promise<Engine<T & WithPsdAuth>> {\n const { pubKey } = await device.getU2FPubKey();\n const challenge = await client.auth.psd.generateChallenge.mutate(\n {\n pubKey,\n workspaceName: __workspaceName,\n },\n buildTrpcContext({ correlationId: opts?.correlationId }),\n );\n await opts?.onScreenDisplayed?.();\n const authentication = await device.authenticate({\n challenge,\n workspaceName: __workspaceName,\n });\n const authPayload = {\n workspaceName: __workspaceName,\n pubKey,\n authentication,\n challengeId: challenge.challengeId,\n validityDurationSecs: opts?.validityDurationSecs,\n };\n const { token } = await client.auth.psd.authenticate.mutate(\n { ...authPayload },\n buildTrpcContext({ correlationId: opts?.correlationId }),\n );\n const withPsdAuth: WithPsdAuth = {\n __psdToken: token,\n };\n const psdAuth = `${engine.__workspaceName}:${token}`;\n const __authClient = engine.createClient({ psdAuth });\n return decorateEngine({ ...this, client: __authClient, ...withPsdAuth } as Engine<\n T & WithPsdAuth\n >);\n },\n\n register: (\n registration: UserRegistrationResponse,\n params?: OnboardingOperationParams,\n ): Promise<UserRegistrationResponse> => {\n return genericRegister({\n device,\n name: registration.name,\n role: registration.role,\n getChallenge: async ({ deviceData }) => {\n const challenge = await client.userRegistrations.generateChallenge.mutate({\n id: registration.id,\n workspaceName: __workspaceName,\n deviceData,\n });\n return challenge;\n },\n submitChallenge: ({ challengeResponse }) =>\n client.userRegistrations.submitChallenge.mutate({\n workspaceName: __workspaceName,\n id: registration.id,\n challengeResponse,\n }),\n onScreenDisplayed: params?.onScreenDisplayed,\n });\n },\n } satisfies DecorateWithDeviceAndWorkspaceUnauthenticated<T>;\n },\n );\n }\n\n // DecorateWithApiUserAndWorkspaceUnauthenticated\n // -------------------------------------------------------------------------\n if (engine.__workspaceName && engine.__isApiUser && !engine.__apiAuth) {\n decorate<WithWorkspace & WithApiUser, DecorateWithApiUserAndWorkspaceUnauthenticated<T>>(\n (engine) => {\n const { client, __workspaceName } = engine;\n return {\n login: async function <T>(\n this: Engine<T>,\n credentials: {\n apiKeyId: string;\n apiKeySecret: string;\n },\n opts?: { correlationId?: string },\n ): Promise<Engine<T & WithApiAuth>> {\n const res = await client.auth.authenticate.mutate(\n {\n apiKeyId: credentials.apiKeyId,\n apiKeySecret: credentials.apiKeySecret,\n workspace: __workspaceName,\n },\n buildTrpcContext({ correlationId: opts?.correlationId }),\n );\n const withApiAuth: WithApiAuth = {\n __apiAuth: res,\n };\n const __authClient = engine.createClient({ apiAccessToken: res.accessToken });\n return decorateEngine({ ...this, client: __authClient, ...withApiAuth } as Engine<\n T & WithApiAuth\n >);\n },\n } satisfies DecorateWithApiUserAndWorkspaceUnauthenticated<T>;\n },\n );\n }\n\n // DecorateWithWorkspacePsdAuthenticated\n // -------------------------------------------------------------------------\n if (engine.device && engine.__workspaceName && engine.__psdToken) {\n decorate<WithDevice & WithWorkspace, DecorateWithWorkspacePsdAuthenticated>((engine) => {\n const { client, device } = engine;\n\n // Drive the device's pairing record + PSK to a fully-provisioned state. Same tri-state\n // switch as the onboarding decorator; routes through `client.debug.*` instead of\n // `client.onboarding.*` and pulls workspace context implicitly from `__psdToken`.\n async function enforcePairing(): Promise<void> {\n const status = await device.hasPairing();\n if (status === \"OK\") return;\n\n const refreshCurrentPsk = async (): Promise<void> => {\n await refreshPsk({\n device,\n getRefreshPskData: (data) => client.debug.refreshPsk.mutate(data),\n });\n };\n\n if (status === \"NO_PAIRING\") {\n await pairDevice({\n device,\n getPairing: (confidentialityKey) =>\n client.debug.pairDevicePartition.mutate({\n confidentialityKeyCurve25519: confidentialityKey.confidentialityKeyCurve25519,\n confidentialityKeySignature: confidentialityKey.confidentialityKeySignature,\n }),\n });\n }\n\n await refreshCurrentPsk();\n }\n\n const approveChallenge = async (\n challenge: PsdChallenge,\n params?: ApproveRequestParams,\n ): Promise<string> => {\n await enforcePairing();\n try {\n await openSecureChannel(device, challenge);\n } catch (err) {\n if (!isPskMissingError(err)) throw err;\n // Defense-in-depth: a session opened before the PSK was wiped still hits\n // SW_PSK_MISSING here. Re-run enforcePairing() — it now sees PSK_MISSING and drives\n // the refresh sub-chain — then retry the secure-channel APDU once.\n await enforcePairing();\n await openSecureChannel(device, challenge);\n }\n await params?.onScreenDisplayed?.();\n const signature = await device.validateVaultOperation({\n actions: challenge.wActions,\n });\n return signature;\n };\n\n return {\n approve: async (\n request: VaultRequestResponse,\n params?: ApproveRequestParams,\n ): Promise<VaultRequestResponse> => {\n const { challenge } = await client.requests.getChallenge.query({ id: request.id });\n if (challenge.challengeType === \"PSD\") {\n const signature = await approveChallenge(challenge, params);\n await params?.onPsdChallengeSigned?.();\n return client.requests.approve.mutate(\n {\n id: request.id,\n data: { challengeType: \"PSD\", signature },\n },\n buildTrpcContext(params),\n );\n }\n if (challenge.challengeType === \"SOFT\") {\n return client.requests.approve.mutate(\n {\n id: request.id,\n data: { challengeType: \"SOFT\" },\n },\n buildTrpcContext(params),\n );\n }\n throw new Error(\"Challenge type must be either PSD or SOFT\");\n },\n\n approveChallenge,\n\n reject: (\n request: VaultRequestResponse,\n opts?: CorrelationIdOpts,\n ): Promise<VaultRequestResponse> => {\n return client.requests.reject.mutate(\n { id: request.id, data: null },\n buildTrpcContext(opts),\n );\n },\n } satisfies DecorateWithWorkspacePsdAuthenticated;\n });\n }\n\n // DecorateWithWorkspaceApiAuthenticated\n // -------------------------------------------------------------------------\n if (engine.__workspaceName && engine.__apiAuth) {\n decorate<WithWorkspace & WithApiAuth, DecorateWithWorkspaceApiAuthenticated>((engine) => {\n const { client } = engine;\n return {\n getChallenge: async (request: VaultRequestResponse): Promise<ApiChallenge[\"payload\"]> => {\n const { challenge } = await client.requests.getChallenge.query({ id: request.id });\n invariant(challenge.challengeType === \"API\", \"Challenge type must be API\");\n return challenge.payload;\n },\n\n approve: (\n request: VaultRequestResponse,\n signature: string,\n ): Promise<VaultRequestResponse> => {\n return client.requests.approve.mutate({\n id: request.id,\n data: { challengeType: \"API\", signature },\n });\n },\n\n reject: (\n request: VaultRequestResponse,\n signature: string,\n ): Promise<VaultRequestResponse> => {\n return client.requests.reject.mutate({\n id: request.id,\n data: { challengeType: \"API\", signature },\n });\n },\n } satisfies DecorateWithWorkspaceApiAuthenticated;\n });\n }\n\n return engine;\n }\n\n return {\n ...base,\n withDeviceIndex,\n withTransportId,\n withApiUser,\n withWorkspace,\n withOnboarding,\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"engine.js","names":[],"sources":["../src/device/real-device.ts","../src/trpc.ts","../src/engine/index.ts"],"sourcesContent":["import { DisconnectedDevice, LockedDeviceError } from \"@ledgerhq/errors\";\nimport type Transport from \"@ledgerhq/hw-transport\";\nimport type { HsmCertificate, PubKey, RefreshPskData } from \"@ledgerhq/revault-api\";\nimport invariant from \"invariant\";\nimport { from, lastValueFrom, Observable } from \"rxjs\";\n\nimport type { Logger } from \"@/logger\";\n\nimport {\n DeviceOperationAbortedError,\n deviceOperationDelay,\n throwIfDeviceOperationAborted,\n} from \"./abort\";\nimport {\n APPID_VAULT_ADMINISTRATOR,\n PAGINATED_STATUS,\n PATHS,\n SCRIPT_IDS,\n STATUS_LENGTH,\n STR_ROLES,\n STREAMING_NEXT_ACTION,\n STREAMING_RESPONSE,\n} from \"./constants\";\nimport { withDevicePolling } from \"./device-access\";\nimport type { Device, PairingStatus } from \"./types\";\nimport { isTransportStatusError } from \"./utils\";\n\nconst MAX_CHUNK_LENGTH = 250;\n\ntype Options = {\n transportId: string;\n};\n\nconst getPathFromPathString = (pathString: string): number[] => {\n const parts = pathString.split(\"'/\").map((part) => Number.parseInt(part, 10));\n return parts.map((part) => (part | 0x80000000) >>> 0);\n};\n\nconst splitChunks = (chunk: number, buffer: Buffer): Buffer[] => {\n const chunks = [];\n for (let i = 0, size = chunk; i < buffer.length; i += size, size = chunk) {\n chunks.push(buffer.slice(i, i + size));\n }\n return chunks;\n};\n\nconst removeStatus = (result: Buffer): Buffer => result.slice(0, result.length - STATUS_LENGTH);\n\nconst sendByChunk = async (\n transport: Transport,\n command: number[], // eg [0xe0, 0x45, 0x00, 0x00]\n data: Buffer,\n signal?: AbortSignal,\n chunkSize: number = MAX_CHUNK_LENGTH,\n): Promise<Buffer> => {\n const chunks = splitChunks(chunkSize, data);\n let response = Buffer.from([]);\n for (let i = 0; i < chunks.length; i++) {\n throwIfDeviceOperationAborted(signal);\n const chunk = chunks[i];\n const apdu = [...command];\n // command is 0xe0,0x45,0x00,0x00 for first chunk, then it's 0xe0,0x45,0x80,0x00\n /* v8 ignore next -- @preserve */\n apdu[2] = i && 0x80;\n response = (await transport.send(apdu[0]!, apdu[1]!, apdu[2], apdu[3]!, chunk, [\n 0x9000,\n ...PAGINATED_STATUS,\n ])) as Buffer<ArrayBuffer>;\n }\n return response;\n};\n\nconst buildAttestation = (params: {\n handshake: string;\n handshakeAttestation: HsmCertificate;\n partitionId: string;\n}): Buffer => {\n const sigBuffer = Buffer.from(params.handshakeAttestation.signature, \"base64\");\n const sigLengthBuffer = Buffer.alloc(1);\n sigLengthBuffer.writeUIntBE(sigBuffer.length, 0, 1);\n\n const certBuffer = Buffer.from(params.handshakeAttestation.certificate, \"base64\");\n const certLengthBuffer = Buffer.alloc(1);\n certLengthBuffer.writeUIntBE(certBuffer.length, 0, 1);\n\n const pubBuffer = Buffer.from(params.handshakeAttestation.attestationPub, \"base64\");\n\n const certChainData = Buffer.concat([\n sigLengthBuffer,\n sigBuffer,\n pubBuffer,\n certLengthBuffer,\n certBuffer,\n ]);\n\n const cliMsgBuffer = Buffer.from(params.handshake, \"hex\");\n const cliMsgLengthBuffer = Buffer.alloc(1);\n cliMsgLengthBuffer.writeUIntBE(cliMsgBuffer.length, 0, 1);\n\n const pidBuffer = Buffer.from(params.partitionId, \"hex\");\n const pidLengthBuffer = Buffer.alloc(1);\n pidLengthBuffer.writeUIntBE(pidBuffer.length, 0, 1);\n\n const certChainDataLengthBuff = Buffer.alloc(2);\n certChainDataLengthBuff.writeUInt16BE(certChainData.length, 0);\n\n const data = Buffer.concat([\n cliMsgLengthBuffer,\n cliMsgBuffer,\n certChainDataLengthBuff,\n certChainData,\n pidLengthBuffer,\n pidBuffer,\n ]);\n\n const totalLengthBuffer = Buffer.alloc(2);\n totalLengthBuffer.writeUInt16BE(data.length, 0);\n\n const toSend = Buffer.concat([totalLengthBuffer, data]);\n\n return toSend;\n};\n\n// Wire-format builder for FINALIZE_PSK_REFRESH (`0xE0 0x53`). Same layout as `buildAttestation`\n// (consumed by the device's `parse_nn_handshake_payload`), but the trailing TLV carries the\n// encrypted PairingPayload from `RefreshPsk` instead of a partition ID.\n//\n// Layout after the leading 2-byte total length:\n// [1] handshake length (the NN responder handshake, written from its actual decoded length)\n// [N] handshake bytes\n// [2] cert-chain-data length (BE)\n// [1] handshake-cert (DER signature) length\n// [N] handshake-cert bytes\n// [65] vault attestation pubkey (raw 0x04|x|y, no length prefix)\n// [1] att-cert length\n// [M] att-cert bytes\n// [1] ciphered-payload length\n// [K] encrypted PairingPayload bytes\nconst buildPskRefreshPayload = (params: RefreshPskData): Buffer => {\n const sigBuffer = Buffer.from(params.handshakeAttestation.signature, \"base64\");\n const sigLengthBuffer = Buffer.alloc(1);\n sigLengthBuffer.writeUIntBE(sigBuffer.length, 0, 1);\n\n const certBuffer = Buffer.from(params.handshakeAttestation.certificate, \"base64\");\n const certLengthBuffer = Buffer.alloc(1);\n certLengthBuffer.writeUIntBE(certBuffer.length, 0, 1);\n\n const pubBuffer = Buffer.from(params.handshakeAttestation.attestationPub, \"base64\");\n\n const certChainData = Buffer.concat([\n sigLengthBuffer,\n sigBuffer,\n pubBuffer,\n certLengthBuffer,\n certBuffer,\n ]);\n\n const handshakeBuffer = Buffer.from(params.handshake, \"base64\");\n invariant(\n handshakeBuffer.length <= 255,\n `PSK refresh handshake too long: ${handshakeBuffer.length} bytes (max 255)`,\n );\n const handshakeLengthBuffer = Buffer.alloc(1);\n handshakeLengthBuffer.writeUInt8(handshakeBuffer.length, 0);\n\n const encryptedPayloadBuffer = Buffer.from(params.encryptedPairingPayload, \"base64\");\n invariant(\n encryptedPayloadBuffer.length <= 255,\n `PSK encrypted payload too long: ${encryptedPayloadBuffer.length} bytes (max 255)`,\n );\n const encryptedPayloadLengthBuffer = Buffer.alloc(1);\n encryptedPayloadLengthBuffer.writeUInt8(encryptedPayloadBuffer.length, 0);\n\n const certChainDataLengthBuff = Buffer.alloc(2);\n certChainDataLengthBuff.writeUInt16BE(certChainData.length, 0);\n\n const data = Buffer.concat([\n handshakeLengthBuffer,\n handshakeBuffer,\n certChainDataLengthBuff,\n certChainData,\n encryptedPayloadLengthBuffer,\n encryptedPayloadBuffer,\n ]);\n\n const totalLengthBuffer = Buffer.alloc(2);\n totalLengthBuffer.writeUInt16BE(data.length, 0);\n\n return Buffer.concat([totalLengthBuffer, data]);\n};\n\ntype RetryOnError = (err: Error) => boolean;\n/* v8 ignore next -- @preserve */\nconst genericRetryOnError: RetryOnError = (err) => {\n // device is locked\n if (err instanceof LockedDeviceError) return true;\n // user is on dashboard when receiving a Vault app apdu\n if (isTransportStatusError(err) && err.statusCode === 0x6d09) return true;\n // VG-24797 error that can happen in BLE in some situations (still unclear)\n if (err instanceof DisconnectedDevice) return true;\n\n // for everything else, we don't want to retry\n return false;\n};\n\nexport function createRealDevice(options: Options, logger: Logger): Device {\n const { transportId } = options;\n\n async function run<T>(\n job: (transport: Transport) => Promise<T>,\n retryOnError: RetryOnError = genericRetryOnError,\n signal?: AbortSignal,\n ): Promise<T> {\n throwIfDeviceOperationAborted(signal);\n const polling = withDevicePolling(transportId)<T>(\n (transport) => from(job(transport)),\n retryOnError,\n );\n const abortablePolling = new Observable<T>((subscriber) => {\n const subscription = polling.subscribe(subscriber);\n const onAbort = (): void => subscriber.error(new DeviceOperationAbortedError());\n signal?.addEventListener(\"abort\", onAbort, { once: true });\n return () => {\n signal?.removeEventListener(\"abort\", onAbort);\n subscription.unsubscribe();\n };\n });\n return lastValueFrom(abortablePolling);\n }\n\n /* v8 ignore next -- @preserve */\n const noRetry = (): boolean => false;\n /* v8 ignore next -- @preserve */\n const alwaysRetry = (): boolean => true;\n const poll = async (\n opts: { retryOnError?: RetryOnError; signal?: AbortSignal } = {},\n ): Promise<{ isAppOpened: boolean }> => {\n // waiting for device to be turned on\n await run(\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n async (_transport) => {},\n opts.retryOnError ?? alwaysRetry,\n opts.signal,\n );\n // checking if app is opened: should return directly on getPubKey\n try {\n await getPublicKey(PATHS.U2F, {\n secp256k1: true,\n retryOnError: noRetry,\n signal: opts.signal,\n });\n return { isAppOpened: true };\n } catch (err) {\n if (isTransportStatusError(err) && genericRetryOnError(err)) {\n return { isAppOpened: false };\n }\n throw err;\n }\n };\n\n const pollApp = async (appName: string, opts: { signal?: AbortSignal } = {}): Promise<string> => {\n const res = await run(\n (transport) => transport.send(0xe0, 0xd8, 0x00, 0x00, Buffer.from(appName, \"utf8\")),\n genericRetryOnError,\n opts.signal,\n );\n // little delay to give time to the app to be fully opened\n await deviceOperationDelay(1e3, opts.signal);\n return res.toString(\"hex\");\n };\n\n const getPublicKey = async (\n pathString: string,\n {\n secp256k1,\n retryOnError,\n signal,\n }: { secp256k1: boolean; retryOnError?: RetryOnError; signal?: AbortSignal },\n ): Promise<{ pubKey: string; signature: string }> => {\n logger.info(`[device] getPublicKey (${pathString})`);\n const path = getPathFromPathString(pathString);\n const data = Buffer.concat([\n Buffer.from([path.length]),\n ...path.map((derivation) => {\n const buf = Buffer.alloc(4);\n buf.writeUInt32BE(derivation, 0);\n return buf;\n }),\n ]);\n const curve = secp256k1 ? 0x01 : 0x02;\n const response = await run(\n (transport) => transport.send(0xe0, 0x40, curve, 0x00, data),\n retryOnError ?? genericRetryOnError,\n signal,\n );\n const pubKeyLength = response.readInt8(0);\n const pubKey = response\n .slice(1, pubKeyLength + 1)\n .toString(\"hex\")\n .toUpperCase();\n const signature = response\n .slice(pubKeyLength + 1, response.length - STATUS_LENGTH)\n .toString(\"base64\");\n return { pubKey, signature };\n };\n\n const device: Device = {\n authenticate: async ({ challenge: { challenge, name, role, keyHandle }, workspaceName }) => {\n logger.info(`[device] Authenticate`);\n invariant(role !== \"READ_ONLY_API_KEY\", \"Invalid role for authenticate: READ_ONLY_API_KEY\");\n const applicationBuffer = Buffer.from(APPID_VAULT_ADMINISTRATOR, \"hex\");\n const nameBuffer = Buffer.from(name);\n const workspaceBuffer = Buffer.from(workspaceName);\n\n const keyHandleData = Buffer.concat([\n Buffer.from(STR_ROLES[role], \"hex\"),\n Buffer.from([nameBuffer.length]),\n nameBuffer,\n Buffer.from([workspaceBuffer.length]),\n workspaceBuffer,\n ]);\n\n const keyHandleDataLength = Buffer.alloc(2);\n keyHandleDataLength.writeUInt16BE(keyHandleData.length, 0);\n\n const data = Buffer.concat([\n Buffer.from(challenge, \"base64\"),\n applicationBuffer,\n Buffer.from([keyHandle.length]),\n Buffer.from(keyHandle, \"hex\"),\n keyHandleDataLength,\n keyHandleData,\n ]);\n\n const authentication = await run((transport) =>\n sendByChunk(transport, [0xe0, 0x02, 0x00, 0x00], data),\n );\n\n return removeStatus(authentication).toString(\"hex\");\n },\n\n finalizePairingHandshake: async (params: {\n handshake: string;\n partitionId: string;\n handshakeAttestation: HsmCertificate;\n }): Promise<string> => {\n const bufWithStatus = await run((transport) =>\n sendByChunk(transport, [0xe0, 0x47, 0x00, 0x02], buildAttestation(params)),\n );\n return removeStatus(bufWithStatus).toString(\"hex\");\n },\n\n generateSeedFragment: async (): Promise<string> => {\n logger.info(`[device] generateSeedFragment`);\n const path = getPathFromPathString(PATHS.KEY_MATERIAL);\n const data = Buffer.concat([\n Buffer.from([path.length]),\n ...path.map((derivation) => {\n const buf = Buffer.alloc(4);\n buf.writeUInt32BE(derivation, 0);\n return buf;\n }),\n ]);\n const response = await run((transport) => transport.send(0xe0, 0x44, 0x00, 0x00, data));\n return removeStatus(response).toString(\"base64\");\n },\n generateWrappingKeyFragment: async (): Promise<string> => {\n logger.info(`[device] generateWrappingKeyFragment`);\n const path = getPathFromPathString(PATHS.KEY_MATERIAL);\n const data = Buffer.concat([\n Buffer.from([path.length]),\n ...path.map((derivation) => {\n const buf = Buffer.alloc(4);\n buf.writeUInt32BE(derivation, 0);\n return buf;\n }),\n ]);\n const response = await run((transport) => transport.send(0xe0, 0x44, 0x01, 0x00, data));\n return removeStatus(response).toString(\"base64\");\n },\n getAttestation: async (\n opts = {},\n ): Promise<{\n attestation: {\n codeHash: string;\n attestationPub: string;\n certificate: string;\n };\n buffer: Buffer;\n }> => {\n const bufWithStatus = await run(\n (transport) => transport.send(0xe0, 0x41, 0x00, 0x00),\n genericRetryOnError,\n opts.signal,\n );\n const buffer = removeStatus(bufWithStatus);\n const certLen = buffer.readInt8(32 + 65 + 1);\n return {\n attestation: {\n codeHash: buffer.slice(0, 32).toString(\"base64\"),\n attestationPub: buffer.slice(32, 32 + 65).toString(\"base64\"),\n certificate: buffer.slice(32 + 65, 32 + 65 + 2 + certLen).toString(\"base64\"),\n },\n buffer,\n };\n },\n getConfidentialityKey: async (opts = {}) => {\n logger.info(`[device] getConfidentialityKey`);\n const bufWithStatus = await run(\n (transport) => transport.send(0xe0, 0x4d, 0x00, 0x00),\n genericRetryOnError,\n opts.signal,\n );\n const buf = removeStatus(bufWithStatus);\n const keyLength = buf[0]!;\n const key = buf.slice(1, 1 + keyLength);\n const sig = buf.slice(1 + keyLength + 1);\n return {\n confidentialityKeyCurve25519: key.toString(\"hex\"),\n confidentialityKeySignature: sig.toString(\"hex\"),\n };\n },\n getConfidentialityPubKey: () => getPublicKey(PATHS.CONFIDENTIALITY, { secp256k1: true }),\n getDeviceUserId: async (): Promise<string> => {\n logger.info(`[device] getDeviceUserId`);\n const response = await run((transport) => transport.send(0xe0, 0x52, 0x00, 0x00));\n return removeStatus(response).toString(\"hex\").toUpperCase();\n },\n getU2FPubKey: () => getPublicKey(PATHS.U2F, { secp256k1: false }),\n getValidationPubKey: () => getPublicKey(PATHS.VALIDATION, { secp256k1: true }),\n hasPairing: async (opts = {}): Promise<PairingStatus> => {\n logger.info(`[device] hasPairing`);\n const apdu = [0xe0, 0x51, 0x00, 0x00, 0xb5];\n const res = await run(\n (transport) => transport.exchange(Buffer.from(apdu)),\n genericRetryOnError,\n opts.signal,\n );\n\n // GET_PARTITION_IDS returns the partition list followed by a 2-byte SW. Inspect only\n // the trailing SW; the device may return data alongside non-`9000` SWs (notably 0x6065\n // — see below).\n const swHex = res.subarray(res.length - 2).toString(\"hex\");\n\n // 6f45 => no partition ID on the device (SW_NO_PARTITION_ID).\n // 6a87 => TEMPORARY hack: some firmware revs don't implement the APDU and return\n // \"incorrect length\"; treat as no pairing so revault drives the full pair-from-\n // scratch flow.\n if (swHex === \"6f45\" || swHex === \"6a87\") return \"NO_PAIRING\";\n\n // 6065 => SW_PSK_MISSING: a valid pairing record exists but its PSK field is the all-\n // zero sentinel. Skip the full pairing chain and run the refresh sub-chain.\n if (swHex === \"6065\") return \"PSK_MISSING\";\n\n // Anything else (typically 9000) => fully provisioned pairing with PSK.\n return \"OK\";\n },\n\n initPairingHandshake: async (opts = {}): Promise<{ pubKey: string; signature: string }> => {\n const res = await run(\n (transport) => transport.send(0xe0, 0x46, 0x00, 0x00),\n genericRetryOnError,\n opts.signal,\n );\n const pubKeyLength = res.readInt8(0);\n const pubKey = res\n .slice(1, pubKeyLength + 1)\n .toString(\"hex\")\n .toUpperCase();\n const signature = res.slice(pubKeyLength + 1, res.length - STATUS_LENGTH).toString(\"base64\");\n return { pubKey, signature };\n },\n\n openSession: async (params: {\n secureChannel: { pubKey: PubKey; certificate: HsmCertificate };\n }): Promise<void> => {\n logger.info(`[device] openSession`);\n const { secureChannel } = params;\n\n const path = getPathFromPathString(PATHS.CONFIDENTIALITY);\n const dataDerivation = Buffer.concat([\n Buffer.from([path.length]),\n ...path.map((derivation) => {\n const buf = Buffer.alloc(4);\n buf.writeUInt32BE(derivation, 0);\n return buf;\n }),\n ]);\n\n const pubKey = Buffer.from(secureChannel.pubKey, \"hex\");\n\n const sigBuffer = Buffer.from(secureChannel.certificate.signature, \"base64\");\n const attestationPubBuffer = Buffer.from(secureChannel.certificate.attestationPub, \"base64\");\n const certBuffer = Buffer.from(secureChannel.certificate.certificate, \"base64\");\n const attestation = Buffer.concat([\n Buffer.from([sigBuffer.length]),\n sigBuffer,\n attestationPubBuffer,\n Buffer.from([certBuffer.length]),\n certBuffer,\n ]);\n\n const lengthAttestation = Buffer.alloc(2);\n lengthAttestation.writeUInt16BE(attestation.length, 0);\n\n const data = Buffer.concat([dataDerivation, pubKey, lengthAttestation, attestation]);\n\n await run((transport) =>\n sendByChunk(transport, [0xe0, 0x42, 0x00, SCRIPT_IDS.INIT_SESSION], data),\n );\n },\n\n register: async (params: {\n challenge: string;\n u2fRegisterData: string;\n name: string;\n role: \"ADMIN\" | \"SHARED_OWNER\" | \"OPERATOR\";\n }): Promise<{\n u2fRegister: Buffer;\n keyHandle: Buffer;\n rfu: number;\n pubKey: string;\n }> => {\n const { challenge: strChallenge, u2fRegisterData: _, name, role } = params;\n const challenge = Buffer.from(strChallenge, \"hex\");\n\n invariant(challenge.length === 32, \"challenge hex is expected to have 32 bytes\");\n const applicationBuf = Buffer.from(APPID_VAULT_ADMINISTRATOR, \"hex\");\n invariant(applicationBuf.length === 32, \"application hex is expected to have 32 bytes\");\n\n const userNameBuff = Buffer.from(name);\n\n const keyHandleData = Buffer.concat([\n Buffer.from(STR_ROLES[role], \"hex\"),\n Buffer.from([userNameBuff.length]),\n userNameBuff,\n ]);\n\n const keyHandleDataLength = Buffer.alloc(2);\n keyHandleDataLength.writeUInt16BE(keyHandleData.length, 0);\n\n const data = Buffer.concat([challenge, applicationBuf, keyHandleDataLength, keyHandleData]);\n\n const response = await run((transport) =>\n sendByChunk(transport, [0xe0, 0x01, 0x00, 0x00], data),\n );\n\n let i = 0;\n const rfu = response.slice(i, i + 1)[0]!;\n i += 1;\n const pubKey = response.slice(i, i + 65).toString(\"hex\");\n i += 65;\n const keyHandleLength = response.slice(i, i + 1)[0]!;\n i++;\n const keyHandle = response.slice(i, i + keyHandleLength);\n i += keyHandleLength;\n return {\n u2fRegister: removeStatus(response),\n keyHandle,\n rfu,\n pubKey,\n };\n },\n registerData: async (params: { challenge: string }): Promise<string> => {\n const { challenge: strChallenge } = params;\n const challenge = Buffer.from(strChallenge, \"hex\");\n invariant(challenge.length === 32, \"challenge hex is expected to have 32 bytes\");\n const response = await run((transport) => transport.send(0xe0, 0x03, 0x00, 0x00, challenge));\n return removeStatus(response).toString(\"hex\");\n },\n\n setPairing: async ({ pairing, signal }) => {\n logger.info(`[device] setPairing`);\n const psdPayload = Buffer.from(pairing.blob, \"base64\");\n const length = Buffer.alloc(2);\n length.writeUInt16BE(psdPayload.length, 0);\n const final = Buffer.concat([length, psdPayload]);\n await run(\n (transport) => sendByChunk(transport, [0xe0, 0x4e, 0x00, 0x00], final, signal),\n genericRetryOnError,\n signal,\n );\n },\n\n // `ephemeralKey` is unused here: the firmware signs over the ephemeral it captured in its own\n // `G_nn_initiator_eph_pubkey` global at INITIALIZE_NN_HANDSHAKE, and INS 0x55 rejects any\n // payload. The arg only exists for the stateless device-api (see api-device.ts).\n signRefreshPskAuth: async ({ signal }): Promise<string> => {\n logger.info(`[device] signRefreshPskAuth`);\n const res = await run(\n (transport) => transport.send(0xe0, 0x55, 0x00, 0x00),\n genericRetryOnError,\n signal,\n );\n return res.slice(0, res.length - STATUS_LENGTH).toString(\"base64\");\n },\n\n finalizePskRefresh: async (\n params: RefreshPskData & { signal?: AbortSignal },\n ): Promise<void> => {\n logger.info(`[device] finalizePskRefresh`);\n const payload = buildPskRefreshPayload(params);\n await run(\n (transport) => sendByChunk(transport, [0xe0, 0x53, 0x00, 0x00], payload, params.signal),\n genericRetryOnError,\n params.signal,\n );\n },\n startKKPatternAsResponder: async (params: {\n handshake: string;\n handshakeAttestation: HsmCertificate;\n partitionId: string;\n }): Promise<{ handshake: string; signature: string }> => {\n logger.info(`[device] startKKPatternAsResponder`);\n const data = buildAttestation(params);\n const bufWithStatus = await run((transport) =>\n sendByChunk(transport, [0xe0, 0x4c, 0x00, SCRIPT_IDS.ACCOUNT_MANAGER_SESSION], data),\n );\n const buffer = removeStatus(bufWithStatus);\n const dataLength = buffer.readInt8(0);\n return {\n handshake: buffer.slice(1, dataLength + 1).toString(\"base64\"),\n signature: buffer.slice(dataLength + 1).toString(\"base64\"),\n };\n },\n startKPatternAsResponder: async (params) => {\n logger.info(`[device] startKPatternAsResponder`);\n const data = buildAttestation(params);\n await run(\n (transport) =>\n sendByChunk(\n transport,\n [0xe0, 0x49, 0x00, SCRIPT_IDS.ACCOUNT_MANAGER_SESSION],\n data,\n params.signal,\n ),\n genericRetryOnError,\n params.signal,\n );\n },\n startPskSession: async (params) => {\n logger.info(`[device] startPskSession`);\n // START_PSK_SESSION (0xe0 0x50): the device reads a raw `nonce(32) || partitionId(16)`\n // payload straight from cmd->data (lc must be exactly 48) — no length prefixes and no\n // attestation. The dispatcher also rejects any non-zero P1/P2 with SW_WRONG_P1P2, so\n // both stay 0 (unlike the K handshake, which ignores P2 = ACCOUNT_MANAGER_SESSION).\n invariant(\n params.nonce.length === 64,\n `PSK nonce must be 32 bytes (64 hex chars), got ${params.nonce.length} chars`,\n );\n invariant(\n params.partitionId.length === 32,\n `partitionId must be 16 bytes (32 hex chars), got ${params.partitionId.length} chars`,\n );\n const data = Buffer.concat([\n Buffer.from(params.nonce, \"hex\"),\n Buffer.from(params.partitionId, \"hex\"),\n ]);\n await run(\n (transport) => sendByChunk(transport, [0xe0, 0x50, 0x00, 0x00], data, params.signal),\n genericRetryOnError,\n params.signal,\n );\n },\n validateVaultOperation: async (params) => {\n logger.info(`[device] validateVaultOperation`);\n const path = getPathFromPathString(PATHS.VALIDATION);\n const paths = Buffer.concat([\n Buffer.from([path.length]),\n ...path.map((derivation) => {\n const buf = Buffer.alloc(4);\n buf.writeUInt32BE(derivation, 0);\n return buf;\n }),\n ]);\n\n let nextActionId = 1;\n let finalResponse: Buffer | null = null;\n\n while (!finalResponse) {\n const screen = Buffer.from(params.actions[nextActionId - 1]!, \"base64\");\n const length = Buffer.alloc(2);\n length.writeUInt16BE(screen.length, 0);\n const data = Buffer.concat([paths, length, screen]);\n const response = await run(\n (transport) => sendByChunk(transport, [0xe0, 0x45, 0x00, 0x00], data, params.signal),\n genericRetryOnError,\n params.signal,\n );\n const responseType = response.readInt8(0);\n let responseStatus = response.readUInt16BE(response.length - 2);\n switch (responseType) {\n case STREAMING_NEXT_ACTION:\n nextActionId = response.readUIntBE(1, 2);\n break;\n case STREAMING_RESPONSE:\n finalResponse = response.slice(3, response.length - 2);\n while (responseStatus !== 0x9000) {\n /* v8 ignore next -- @preserve */ {\n const resp = await run(\n (transport) => transport.send(0x00, 0xc0, 0x00, 0x00),\n genericRetryOnError,\n params.signal,\n );\n responseStatus = resp.readUInt16BE(resp.length - 2);\n finalResponse = Buffer.concat([finalResponse, removeStatus(resp)]);\n }\n }\n break;\n /* v8 ignore next -- @preserve */\n default:\n throw new Error(`Invalid response type: ${responseType}`);\n }\n }\n return finalResponse.toString(\"base64\");\n },\n\n sendAPDU: async (apduCommand: string) => {\n const res = await run((transport) => transport.exchange(Buffer.from(apduCommand, \"hex\")));\n return Buffer.from(res).toString(\"hex\");\n },\n getVersion: async (opts = {}) => {\n const res = await run(\n (transport) => transport.send(0xb0, 0x01, 0x00, 0x00),\n genericRetryOnError,\n opts.signal,\n );\n const appNameLen = res.readInt8(1);\n const appVersionLen = res.readInt8(2 + appNameLen);\n const appVersionHex = res.slice(2 + 1 + appNameLen, 2 + appNameLen + appVersionLen + 1);\n\n const appVersion = Buffer.from(appVersionHex).toString();\n\n return appVersion;\n },\n poll,\n pollApp,\n };\n return device;\n}\n","import type { AppRouter } from \"@ledgerhq/revault-api\";\nimport { createTRPCClient, httpLink, type TRPCClient } from \"@trpc/client\";\nimport type { inferRouterInputs, inferRouterOutputs } from \"@trpc/server\";\nimport superjson from \"superjson\";\n\nexport type TRPCClientOptions = {\n baseUrl: string;\n debugAuthToken?: string;\n rootAuthToken?: string;\n apiAccessToken?: string;\n psdAuth?: string;\n};\n\nexport type RevaultApiTRPCClient = TRPCClient<AppRouter>;\n\nexport type RouterInputs = inferRouterInputs<AppRouter>;\nexport type RouterOutputs = inferRouterOutputs<AppRouter>;\n\nexport type TRPCContext = { context: Record<string, unknown> } | undefined;\n\nexport const createClient = (options: TRPCClientOptions): RevaultApiTRPCClient => {\n const trpc = createTRPCClient<AppRouter>({\n links: [\n httpLink({\n url: `${options.baseUrl}/trpc`,\n transformer: superjson,\n headers(opts) {\n // Extract headers from the operation context\n const contextHeaders = (opts.op.context?.headers as Record<string, string>) || {};\n\n return {\n ...(options.debugAuthToken\n ? { \"x-revault-debug-auth-token\": options.debugAuthToken }\n : {}),\n ...(options.rootAuthToken\n ? { \"x-revault-root-auth-token\": options.rootAuthToken }\n : {}),\n ...(options.psdAuth ? { Authorization: `PsdAuth ${options.psdAuth}` } : {}),\n ...(options.apiAccessToken\n ? { Authorization: `Bearer ${options.apiAccessToken}` }\n : {}),\n // Merge in any headers passed via context\n ...contextHeaders,\n };\n },\n }),\n ],\n });\n return trpc;\n};\n","import type {\n ApiChallenge,\n ClaimedRole,\n OnboardingSeedChallenge,\n PsdChallenge,\n UserRegistrationChallenge,\n UserRegistrationChallengeResponse,\n UserRegistrationDeviceData,\n UserRegistrationResponse,\n VaultRequestResponse,\n WrappingKeyResponse,\n} from \"@ledgerhq/revault-api\";\nimport invariant from \"invariant\";\n\nimport { createApiDevice, type Device, isPskMissingError } from \"@/device\";\nimport { throwIfDeviceOperationAborted } from \"@/device/abort\";\nimport { createRealDevice } from \"@/device/real-device\";\nimport type { Logger } from \"@/logger\";\nimport { createClient, type RouterOutputs, type TRPCClientOptions } from \"@/trpc\";\n\nimport { buildTrpcContext } from \"../utils\";\nimport type {\n ApproveRequestParams,\n CorrelationIdOpts,\n DecorateWithApiUserAndWorkspaceUnauthenticated,\n DecorateWithDevice,\n DecorateWithDeviceAndOnboarding,\n DecorateWithDeviceAndWorkspaceUnauthenticated,\n DecorateWithWorkspaceApiAuthenticated,\n DecorateWithWorkspacePsdAuthenticated,\n DecorateWithWorkspaceUnauthenticated,\n Engine,\n EngineBase,\n EngineOptions,\n OnboardingOperationParams,\n RegisterOnboardingDeviceParams,\n WithApiAuth,\n WithApiUser,\n WithDevice,\n WithOnboarding,\n WithPsdAuth,\n WithWorkspace,\n} from \"./types\";\n\nexport { fetchAll, fetchAllCursor } from \"../utils\";\nexport type * from \"./types\";\n\nconst PSK_NONCE_BYTE_LEN = 32;\n\n// Open the per-operation secure channel matching the crypto the HSM used at Prepare, branching\n// on the challenge shape. A 32-byte `handshake` (hex, 64 chars) is the PSK HKDF nonce;\n// longer is legacy Noise-K.\nconst openSecureChannel = (\n device: Device,\n challenge: Pick<PsdChallenge, \"handshake\" | \"handshakeAttestation\" | \"partitionId\">,\n signal?: AbortSignal,\n): Promise<void> => {\n if (challenge.handshake.length === PSK_NONCE_BYTE_LEN * 2) {\n return device.startPskSession({\n nonce: challenge.handshake,\n partitionId: challenge.partitionId,\n signal,\n });\n }\n return device.startKPatternAsResponder({\n handshake: challenge.handshake,\n handshakeAttestation: challenge.handshakeAttestation,\n partitionId: challenge.partitionId,\n signal,\n });\n};\n\ntype DeviceConfidentialityKey = Awaited<ReturnType<Device[\"getConfidentialityKey\"]>>;\ntype DevicePairing = Parameters<Device[\"setPairing\"]>[0][\"pairing\"];\ntype DeviceRefreshPskData = Parameters<Device[\"finalizePskRefresh\"]>[0];\n\ntype RefreshPskInput = {\n psdEphemeralKey: string;\n psdEphemeralKeyAttestation: {\n codeHash: string;\n attestationPub: string;\n certificate: string;\n signature: string;\n };\n validationKeySignature: string;\n};\n\nconst pairDevice = async ({\n device,\n getPairing,\n signal,\n}: {\n device: Pick<Device, \"getConfidentialityKey\" | \"setPairing\">;\n getPairing: (confidentialityKey: DeviceConfidentialityKey) => Promise<DevicePairing>;\n signal?: AbortSignal;\n}): Promise<void> => {\n const confidentialityKey = await device.getConfidentialityKey({ signal });\n const pairing = await getPairing(confidentialityKey);\n throwIfDeviceOperationAborted(signal);\n await device.setPairing({ pairing, signal });\n};\n\nconst refreshPsk = async ({\n device,\n getRefreshPskData,\n signal,\n}: {\n device: Pick<\n Device,\n \"finalizePskRefresh\" | \"getAttestation\" | \"initPairingHandshake\" | \"signRefreshPskAuth\"\n >;\n getRefreshPskData: (input: RefreshPskInput) => Promise<DeviceRefreshPskData>;\n signal?: AbortSignal;\n}): Promise<void> => {\n // Shared refresh sub-chain: 0x46 (device NN init) + 0x55 (validation-key auth signature)\n // → HSM refresh-psk (single read-only re-delivery) → 0x53 (finalize). The HSM verifies\n // the device-attested ephemeral key and the validation-key signature, so we stitch the\n // per-ephemeral signature from INITIALIZE_NN_HANDSHAKE onto the device's static attestation\n // chain (INS_GET_ATTESTATION_CERTIFICATE) and pass the SIGN_REFRESH_PSK_AUTH signature\n // alongside. initPairingHandshake (0x46) must resolve first: the soft-device\n // signRefreshPskAuth needs the ephemeral it returns, and the firmware FSM requires 0x46\n // before 0x55.\n const eph = await device.initPairingHandshake({ signal });\n const [deviceAttestation, validationKeySignature] = await Promise.all([\n device.getAttestation({ signal }),\n device.signRefreshPskAuth({ ephemeralKey: eph.pubKey, signal }),\n ]);\n throwIfDeviceOperationAborted(signal);\n const refresh = await getRefreshPskData({\n psdEphemeralKey: Buffer.from(eph.pubKey, \"hex\").toString(\"base64\"),\n psdEphemeralKeyAttestation: {\n codeHash: deviceAttestation.attestation.codeHash,\n attestationPub: deviceAttestation.attestation.attestationPub,\n certificate: deviceAttestation.attestation.certificate,\n signature: eph.signature,\n },\n validationKeySignature,\n });\n throwIfDeviceOperationAborted(signal);\n await device.finalizePskRefresh({ ...refresh, signal });\n};\n\nasync function genericRegister<T>({\n device,\n name,\n role,\n getChallenge,\n submitChallenge,\n onScreenDisplayed,\n}: {\n device: Device;\n name: string;\n role: \"ADMIN\" | \"SHARED_OWNER\" | \"OPERATOR\";\n getChallenge: (p: {\n pubKey: string;\n deviceData: UserRegistrationDeviceData;\n }) => Promise<UserRegistrationChallenge>;\n submitChallenge: (p: {\n pubKey: string;\n challengeResponse: UserRegistrationChallengeResponse;\n }) => Promise<T>;\n onScreenDisplayed?: () => void | Promise<void>;\n}): Promise<T> {\n const [attestation, u2fPubKey, confidentialityKey] = await Promise.all([\n device.getAttestation(),\n device.getU2FPubKey(),\n device.getConfidentialityPubKey(),\n ]);\n const ephemeralPubKey = await device.initPairingHandshake();\n const deviceData: UserRegistrationDeviceData = {\n name,\n pubKey: u2fPubKey.pubKey,\n psdModel: \"STAX\",\n confidentialityKey: confidentialityKey.pubKey,\n psdEphemeralKey: ephemeralPubKey.pubKey,\n psdEphemeralKeyAttestation: {\n ...attestation.attestation,\n signature: ephemeralPubKey.signature,\n },\n };\n const challenge = await getChallenge({ pubKey: u2fPubKey.pubKey, deviceData });\n const pairingPayload = await device.finalizePairingHandshake({\n handshake: challenge.handshake,\n partitionId: challenge.ciphertext,\n handshakeAttestation: challenge.handshakeAttestation,\n });\n await onScreenDisplayed?.();\n const register = await device.register({\n challenge: challenge.challenge,\n u2fRegisterData: challenge.u2fRegisterData,\n name,\n role,\n });\n const validationPubKey = await device.getValidationPubKey();\n const registerData = await device.registerData({ challenge: challenge.challenge });\n const attestationOffset = 67 + register.u2fRegister.readInt8(66);\n const u2fRegister = Buffer.concat([\n register.u2fRegister.slice(0, attestationOffset),\n Buffer.from([attestation.buffer.length]),\n attestation.buffer,\n register.u2fRegister.slice(attestationOffset),\n ]).toString(\"hex\");\n const challengeResponse: UserRegistrationChallengeResponse = {\n registerData,\n certificate: {\n ...attestation.attestation,\n signature: validationPubKey.signature,\n },\n u2fRegister,\n u2fKeyHandle: register.keyHandle.toString(\"hex\"),\n validationKey: validationPubKey.pubKey,\n pairingPayload,\n };\n return submitChallenge({ pubKey: u2fPubKey.pubKey, challengeResponse });\n}\n\nexport function createEngine(options: EngineOptions, logger: Logger): Engine {\n const clientOptions: TRPCClientOptions = {\n baseUrl: options.baseUrl,\n };\n const client = createClient(clientOptions);\n const apiDevice = createApiDevice(options, logger);\n\n const base: EngineBase = {\n client,\n createClient: (overrides) => createClient({ ...clientOptions, ...overrides }),\n __options: options,\n };\n\n const withDeviceIndex: Engine[\"withDeviceIndex\"] = function <T>(\n this: Engine<T>,\n deviceIndex: number,\n ) {\n const device = apiDevice.with(deviceIndex);\n const withPsd: WithDevice = { device };\n return decorateEngine({ ...this, ...withPsd } as Engine<T & WithDevice>);\n };\n\n const withTransportId: Engine[\"withTransportId\"] = function <T>(\n this: Engine<T>,\n transportId: string,\n ) {\n const device = createRealDevice({ transportId }, logger);\n const withPsd: WithDevice = { device };\n return decorateEngine({ ...this, ...withPsd } as Engine<T & WithDevice>);\n };\n\n const withApiUser: Engine[\"withApiUser\"] = function <T>(this: Engine<T>) {\n const withApiUser: WithApiUser = { __isApiUser: true };\n return decorateEngine({ ...this, ...withApiUser } as Engine<T & WithApiUser>);\n };\n\n const withWorkspace: Engine[\"withWorkspace\"] = function <T>(\n this: Engine<T>,\n workspaceName: string,\n ) {\n const withWorkspace: WithWorkspace = { __workspaceName: workspaceName };\n return decorateEngine({ ...this, ...withWorkspace } as Engine<T & WithWorkspace>);\n };\n\n const withOnboarding: Engine[\"withOnboarding\"] = function <T>(\n this: Engine<T>,\n onboardingId: string,\n ) {\n const withOnboarding: WithOnboarding = { __onboardingId: onboardingId };\n return decorateEngine({ ...this, ...withOnboarding } as Engine<T & WithOnboarding>);\n };\n\n function decorateEngine<T>(\n engine: Engine<\n T &\n Partial<\n WithDevice & WithOnboarding & WithWorkspace & WithPsdAuth & WithApiUser & WithApiAuth\n >\n >,\n ): Engine<T> {\n function decorate<TEnhanced, TDecoration>(\n decorator: (engine: EngineBase & TEnhanced) => TDecoration,\n ): void {\n Object.assign(engine, decorator(engine as EngineBase & TEnhanced));\n }\n\n // DecorateWithDevice\n // -------------------------------------------------------------------------\n if (engine.device) {\n decorate<WithDevice, DecorateWithDevice<T>>(\n (engine) =>\n ({\n getWorkspaces: async (): Promise<string[]> => {\n const { device, client } = engine;\n const { pubKey } = await device.getU2FPubKey();\n const { workspaceNames } = await client.auth.psd.findWorkspaceNames.query({ pubKey });\n return workspaceNames;\n },\n\n getWorkspacesForSso: async (): Promise<\n RouterOutputs[\"auth\"][\"sso\"][\"findWorkspaces\"][\"workspaces\"]\n > => {\n const { device, client } = engine;\n const { pubKey } = await device.getU2FPubKey();\n const { workspaces } = await client.auth.sso.findWorkspaces.query({ pubKey });\n return workspaces;\n },\n }) satisfies DecorateWithDevice<T>,\n );\n }\n\n // DecorateWithWorkspaceUnauthenticated\n // -------------------------------------------------------------------------\n if (engine.__workspaceName && !engine.__psdToken && !engine.__apiAuth) {\n decorate<WithWorkspace, DecorateWithWorkspaceUnauthenticated<T>>((engine) => {\n const { __workspaceName } = engine;\n return {\n withPsdToken: function <T>(this: Engine<T>, token: string): Engine<T & WithPsdAuth> {\n const withPsdAuth: WithPsdAuth = { __psdToken: token };\n const psdAuth = `${__workspaceName}:${token}`;\n const client = engine.createClient({ psdAuth });\n return decorateEngine({ ...this, client, ...withPsdAuth } as Engine<T & WithPsdAuth>);\n },\n } satisfies DecorateWithWorkspaceUnauthenticated<T>;\n });\n }\n\n // DecorateWithDeviceAndOnboarding\n // -------------------------------------------------------------------------\n if (engine.device && engine.__onboardingId) {\n decorate<WithDevice & WithOnboarding, DecorateWithDeviceAndOnboarding>((engine) => {\n const { device, client, __onboardingId } = engine;\n\n // Drive the device's pairing record + PSK to a fully-provisioned state.\n // - \"OK\" → nothing to do.\n // - \"NO_PAIRING\" → run the full pairing chain, then deliver a PSK via refresh.\n // - \"PSK_MISSING\" → pairing already exists; only run the PSK refresh sub-chain.\n async function enforcePairing(): Promise<void> {\n const status = await device.hasPairing();\n if (status === \"OK\") return;\n\n let pubKeyPromise: Promise<string> | undefined;\n const getPubKey = async (): Promise<string> => {\n pubKeyPromise ??= device.getU2FPubKey().then(({ pubKey }) => pubKey);\n return pubKeyPromise;\n };\n const refreshCurrentPsk = async (): Promise<void> => {\n const pubKey = await getPubKey();\n await refreshPsk({\n device,\n getRefreshPskData: (data) =>\n client.onboarding.refreshPsk.mutate({\n pubKey,\n onboardingId: __onboardingId,\n data,\n }),\n });\n };\n\n if (status === \"NO_PAIRING\") {\n const pubKey = await getPubKey();\n await pairDevice({\n device,\n getPairing: (confidentialityKey) =>\n client.onboarding.pairDevicePartition.mutate({\n pubKey,\n onboardingId: __onboardingId,\n data: {\n confidentialityKeyCurve25519: confidentialityKey.confidentialityKeyCurve25519,\n confidentialityKeySignature: confidentialityKey.confidentialityKeySignature,\n },\n }),\n });\n }\n\n await refreshCurrentPsk();\n }\n\n return {\n claimDevice: async (params: { role: ClaimedRole; deviceName: string }): Promise<void> => {\n const { role, deviceName } = params;\n const [{ pubKey }, { pubKey: confidentialityKey }] = await Promise.all([\n device.getU2FPubKey(),\n device.getConfidentialityPubKey(),\n ]);\n await client.onboarding.claimDevice.mutate({\n onboardingId: __onboardingId,\n claim: { role, pubKey, deviceName, confidentialityKey },\n });\n },\n\n collectWrappingKeyFragment: async (\n wrappingKey: WrappingKeyResponse,\n params?: OnboardingOperationParams,\n ): Promise<void> => {\n const [{ pubKey }, confidentialityKey] = await Promise.all([\n device.getU2FPubKey(),\n device.getConfidentialityPubKey(),\n ]);\n await device.openSession({\n secureChannel: {\n pubKey: wrappingKey.ephemeralPubKey,\n certificate: wrappingKey.ephemeralCertificate,\n },\n });\n const { attestation } = await device.getAttestation();\n await params?.onScreenDisplayed?.();\n const blob = await device.generateWrappingKeyFragment();\n await client.onboarding.submitWrappingKeyFragment.mutate({\n pubKey,\n onboardingId: __onboardingId,\n fragment: {\n blob,\n ephemeralPubKey: confidentialityKey.pubKey,\n ephemeralCertificate: {\n ...attestation,\n signature: confidentialityKey.signature,\n },\n },\n });\n },\n\n registerDevice: async (\n registerParams: RegisterOnboardingDeviceParams,\n params?: OnboardingOperationParams,\n ): Promise<void> => {\n const { role, name } = registerParams;\n const getChallengeMutation =\n role === \"ADMIN\"\n ? client.onboarding.generateMasterAdminRegistrationChallenge\n : client.onboarding.generateSharedOwnerRegistrationChallenge;\n const submitChallengeMutation =\n role === \"ADMIN\"\n ? client.onboarding.submitMasterAdminRegistration\n : client.onboarding.submitSharedOwnerRegistration;\n await genericRegister({\n device: device,\n name,\n role,\n getChallenge: ({ pubKey, deviceData }) =>\n getChallengeMutation.mutate({\n onboardingId: __onboardingId,\n pubKey,\n deviceData,\n }),\n submitChallenge: ({ pubKey, challengeResponse }) =>\n submitChallengeMutation.mutate({\n onboardingId: engine.__onboardingId,\n pubKey,\n // FIXME this should be renamed to `challengeResponse` on backend side\n response: challengeResponse,\n }),\n onScreenDisplayed: params?.onScreenDisplayed,\n });\n },\n\n reviewSharedOwner: async (\n challenge: PsdChallenge,\n params?: OnboardingOperationParams,\n ): Promise<void> => {\n await enforcePairing();\n const { pubKey } = await device.getU2FPubKey();\n await openSecureChannel(device, challenge);\n await params?.onScreenDisplayed?.();\n const signature = await device.validateVaultOperation({\n actions: challenge.wActions,\n });\n await client.onboarding.submitReviewByMasterAdminSignature.mutate({\n onboardingId: __onboardingId,\n pubKey,\n signature,\n });\n },\n\n reviewExternalSigners: async (\n challenge: PsdChallenge,\n params?: OnboardingOperationParams,\n ): Promise<void> => {\n await enforcePairing();\n const { pubKey } = await device.getU2FPubKey();\n await openSecureChannel(device, challenge);\n await params?.onScreenDisplayed?.();\n const signature = await device.validateVaultOperation({\n actions: challenge.wActions,\n });\n await client.onboarding.submitExternalSignersRegistration.mutate({\n onboardingId: __onboardingId,\n pubKey,\n signature,\n });\n },\n\n collectSeedFragment: async (\n challenge: OnboardingSeedChallenge,\n params?: OnboardingOperationParams,\n ): Promise<void> => {\n await enforcePairing();\n const [{ pubKey }, { attestation }] = await Promise.all([\n device.getU2FPubKey(),\n device.getAttestation(),\n ]);\n await openSecureChannel(device, challenge);\n await params?.onScreenDisplayed?.();\n const challengeResponse = await device.validateVaultOperation({\n actions: challenge.wActions,\n });\n const kkPattern = await device.startKKPatternAsResponder({\n partitionId: challenge.partitionId,\n handshake: challenge.kkHandshake,\n handshakeAttestation: challenge.kkHandshakeAttestation,\n });\n const approverBlob = await device.generateSeedFragment();\n await client.onboarding.submitSeedFragment.mutate({\n onboardingId: __onboardingId,\n pubKey,\n seedFragment: {\n challengeResponse,\n approverBlob,\n handshake: kkPattern.handshake,\n handshakeAttestation: {\n ...attestation,\n signature: kkPattern.signature,\n },\n },\n });\n },\n } satisfies DecorateWithDeviceAndOnboarding;\n });\n }\n\n // DecorateWithDeviceAndWorkspaceUnauthenticated\n // -------------------------------------------------------------------------\n if (engine.device && engine.__workspaceName && !engine.__psdToken) {\n decorate<WithDevice & WithWorkspace, DecorateWithDeviceAndWorkspaceUnauthenticated<T>>(\n (engine) => {\n const { device, client, __workspaceName } = engine;\n return {\n login: async function <T>(\n this: Engine<T>,\n opts?: {\n validityDurationSecs?: number;\n onScreenDisplayed?: () => void | Promise<void>;\n correlationId?: string;\n },\n ): Promise<Engine<T & WithPsdAuth>> {\n const { pubKey } = await device.getU2FPubKey();\n const challenge = await client.auth.psd.generateChallenge.mutate(\n {\n pubKey,\n workspaceName: __workspaceName,\n },\n buildTrpcContext({ correlationId: opts?.correlationId }),\n );\n await opts?.onScreenDisplayed?.();\n const authentication = await device.authenticate({\n challenge,\n workspaceName: __workspaceName,\n });\n const authPayload = {\n workspaceName: __workspaceName,\n pubKey,\n authentication,\n challengeId: challenge.challengeId,\n validityDurationSecs: opts?.validityDurationSecs,\n };\n const { token } = await client.auth.psd.authenticate.mutate(\n { ...authPayload },\n buildTrpcContext({ correlationId: opts?.correlationId }),\n );\n const withPsdAuth: WithPsdAuth = {\n __psdToken: token,\n };\n const psdAuth = `${engine.__workspaceName}:${token}`;\n const __authClient = engine.createClient({ psdAuth });\n return decorateEngine({ ...this, client: __authClient, ...withPsdAuth } as Engine<\n T & WithPsdAuth\n >);\n },\n\n register: (\n registration: UserRegistrationResponse,\n params?: OnboardingOperationParams,\n ): Promise<UserRegistrationResponse> => {\n return genericRegister({\n device,\n name: registration.name,\n role: registration.role,\n getChallenge: async ({ deviceData }) => {\n const challenge = await client.userRegistrations.generateChallenge.mutate({\n id: registration.id,\n workspaceName: __workspaceName,\n deviceData,\n });\n return challenge;\n },\n submitChallenge: ({ challengeResponse }) =>\n client.userRegistrations.submitChallenge.mutate({\n workspaceName: __workspaceName,\n id: registration.id,\n challengeResponse,\n }),\n onScreenDisplayed: params?.onScreenDisplayed,\n });\n },\n } satisfies DecorateWithDeviceAndWorkspaceUnauthenticated<T>;\n },\n );\n }\n\n // DecorateWithApiUserAndWorkspaceUnauthenticated\n // -------------------------------------------------------------------------\n if (engine.__workspaceName && engine.__isApiUser && !engine.__apiAuth) {\n decorate<WithWorkspace & WithApiUser, DecorateWithApiUserAndWorkspaceUnauthenticated<T>>(\n (engine) => {\n const { client, __workspaceName } = engine;\n return {\n login: async function <T>(\n this: Engine<T>,\n credentials: {\n apiKeyId: string;\n apiKeySecret: string;\n },\n opts?: { correlationId?: string },\n ): Promise<Engine<T & WithApiAuth>> {\n const res = await client.auth.authenticate.mutate(\n {\n apiKeyId: credentials.apiKeyId,\n apiKeySecret: credentials.apiKeySecret,\n workspace: __workspaceName,\n },\n buildTrpcContext({ correlationId: opts?.correlationId }),\n );\n const withApiAuth: WithApiAuth = {\n __apiAuth: res,\n };\n const __authClient = engine.createClient({ apiAccessToken: res.accessToken });\n return decorateEngine({ ...this, client: __authClient, ...withApiAuth } as Engine<\n T & WithApiAuth\n >);\n },\n } satisfies DecorateWithApiUserAndWorkspaceUnauthenticated<T>;\n },\n );\n }\n\n // DecorateWithWorkspacePsdAuthenticated\n // -------------------------------------------------------------------------\n if (engine.device && engine.__workspaceName && engine.__psdToken) {\n decorate<WithDevice & WithWorkspace, DecorateWithWorkspacePsdAuthenticated>((engine) => {\n const { client, device } = engine;\n\n // Drive the device's pairing record + PSK to a fully-provisioned state. Same tri-state\n // switch as the onboarding decorator; routes through `client.debug.*` instead of\n // `client.onboarding.*` and pulls workspace context implicitly from `__psdToken`.\n async function enforcePairing(signal?: AbortSignal): Promise<void> {\n const status = await device.hasPairing({ signal });\n if (status === \"OK\") return;\n\n const refreshCurrentPsk = async (): Promise<void> => {\n await refreshPsk({\n device,\n getRefreshPskData: (data) => client.debug.refreshPsk.mutate(data),\n signal,\n });\n };\n\n if (status === \"NO_PAIRING\") {\n await pairDevice({\n device,\n getPairing: (confidentialityKey) =>\n client.debug.pairDevicePartition.mutate({\n confidentialityKeyCurve25519: confidentialityKey.confidentialityKeyCurve25519,\n confidentialityKeySignature: confidentialityKey.confidentialityKeySignature,\n }),\n signal,\n });\n }\n\n await refreshCurrentPsk();\n }\n\n const approveChallenge = async (\n challenge: PsdChallenge,\n params?: ApproveRequestParams,\n ): Promise<string> => {\n await enforcePairing(params?.signal);\n try {\n await openSecureChannel(device, challenge, params?.signal);\n } catch (err) {\n if (!isPskMissingError(err)) throw err;\n // Defense-in-depth: a session opened before the PSK was wiped still hits\n // SW_PSK_MISSING here. Re-run enforcePairing() — it now sees PSK_MISSING and drives\n // the refresh sub-chain — then retry the secure-channel APDU once.\n await enforcePairing(params?.signal);\n await openSecureChannel(device, challenge, params?.signal);\n }\n throwIfDeviceOperationAborted(params?.signal);\n await params?.onScreenDisplayed?.();\n throwIfDeviceOperationAborted(params?.signal);\n const signature = await device.validateVaultOperation({\n actions: challenge.wActions,\n signal: params?.signal,\n });\n return signature;\n };\n\n return {\n approve: async (\n request: VaultRequestResponse,\n params?: ApproveRequestParams,\n ): Promise<VaultRequestResponse> => {\n throwIfDeviceOperationAborted(params?.signal);\n const { challenge } = await client.requests.getChallenge.query({ id: request.id });\n if (challenge.challengeType === \"PSD\") {\n const signature = await approveChallenge(challenge, params);\n throwIfDeviceOperationAborted(params?.signal);\n await params?.onPsdChallengeSigned?.();\n throwIfDeviceOperationAborted(params?.signal);\n return client.requests.approve.mutate(\n {\n id: request.id,\n data: { challengeType: \"PSD\", signature },\n },\n buildTrpcContext(params),\n );\n }\n if (challenge.challengeType === \"SOFT\") {\n throwIfDeviceOperationAborted(params?.signal);\n return client.requests.approve.mutate(\n {\n id: request.id,\n data: { challengeType: \"SOFT\" },\n },\n buildTrpcContext(params),\n );\n }\n throw new Error(\"Challenge type must be either PSD or SOFT\");\n },\n\n approveChallenge,\n\n reject: (\n request: VaultRequestResponse,\n opts?: CorrelationIdOpts,\n ): Promise<VaultRequestResponse> => {\n return client.requests.reject.mutate(\n { id: request.id, data: null },\n buildTrpcContext(opts),\n );\n },\n } satisfies DecorateWithWorkspacePsdAuthenticated;\n });\n }\n\n // DecorateWithWorkspaceApiAuthenticated\n // -------------------------------------------------------------------------\n if (engine.__workspaceName && engine.__apiAuth) {\n decorate<WithWorkspace & WithApiAuth, DecorateWithWorkspaceApiAuthenticated>((engine) => {\n const { client } = engine;\n return {\n getChallenge: async (request: VaultRequestResponse): Promise<ApiChallenge[\"payload\"]> => {\n const { challenge } = await client.requests.getChallenge.query({ id: request.id });\n invariant(challenge.challengeType === \"API\", \"Challenge type must be API\");\n return challenge.payload;\n },\n\n approve: (\n request: VaultRequestResponse,\n signature: string,\n ): Promise<VaultRequestResponse> => {\n return client.requests.approve.mutate({\n id: request.id,\n data: { challengeType: \"API\", signature },\n });\n },\n\n reject: (\n request: VaultRequestResponse,\n signature: string,\n ): Promise<VaultRequestResponse> => {\n return client.requests.reject.mutate({\n id: request.id,\n data: { challengeType: \"API\", signature },\n });\n },\n } satisfies DecorateWithWorkspaceApiAuthenticated;\n });\n }\n\n return engine;\n }\n\n return {\n ...base,\n withDeviceIndex,\n withTransportId,\n withApiUser,\n withWorkspace,\n withOnboarding,\n };\n}\n"],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { t as Logger } from "./logger-DHtgWA66.js";
|
|
2
2
|
import { a as TRPCContext } from "./trpc-BCwyqVKi.js";
|
|
3
|
-
import { d as Engine, p as EngineOptions } from "./types-
|
|
3
|
+
import { d as Engine, p as EngineOptions } from "./types-tRODcWIL.js";
|
|
4
4
|
import { CursorPaginated, Paginated } from "@ledgerhq/revault-api";
|
|
5
5
|
//#region src/utils.d.ts
|
|
6
6
|
/**
|
|
@@ -2,6 +2,17 @@ import { t as Logger } from "./logger-DHtgWA66.cjs";
|
|
|
2
2
|
import { HsmCertificate, PsdAuthChallengeResponse, PsdPairingData, PubKey, RefreshPskData } from "@ledgerhq/revault-api";
|
|
3
3
|
import Transport from "@ledgerhq/hw-transport";
|
|
4
4
|
import { Observable } from "rxjs";
|
|
5
|
+
//#region src/device/abort.d.ts
|
|
6
|
+
/** Error returned when the application aborts a device operation. */
|
|
7
|
+
declare class DeviceOperationAbortedError extends Error {
|
|
8
|
+
constructor();
|
|
9
|
+
}
|
|
10
|
+
type DeviceOperationOptions = {
|
|
11
|
+
/** Stops this operation when the application no longer owns the interaction. */
|
|
12
|
+
signal?: AbortSignal;
|
|
13
|
+
};
|
|
14
|
+
declare const isDeviceOperationAbortedError: (error: unknown) => error is DeviceOperationAbortedError;
|
|
15
|
+
//#endregion
|
|
5
16
|
//#region src/device/types.d.ts
|
|
6
17
|
/**
|
|
7
18
|
* Tri-state result of {@link Device.hasPairing}. Replaces the legacy boolean so callers can
|
|
@@ -36,7 +47,7 @@ type Device = {
|
|
|
36
47
|
/**
|
|
37
48
|
* Get device attestation
|
|
38
49
|
*/
|
|
39
|
-
getAttestation: () => Promise<{
|
|
50
|
+
getAttestation: (opts?: DeviceOperationOptions) => Promise<{
|
|
40
51
|
attestation: {
|
|
41
52
|
codeHash: string;
|
|
42
53
|
attestationPub: string;
|
|
@@ -47,7 +58,7 @@ type Device = {
|
|
|
47
58
|
/**
|
|
48
59
|
* Get device confidentiality key
|
|
49
60
|
*/
|
|
50
|
-
getConfidentialityKey: () => Promise<{
|
|
61
|
+
getConfidentialityKey: (opts?: DeviceOperationOptions) => Promise<{
|
|
51
62
|
confidentialityKeyCurve25519: string;
|
|
52
63
|
confidentialityKeySignature: string;
|
|
53
64
|
}>;
|
|
@@ -85,11 +96,11 @@ type Device = {
|
|
|
85
96
|
* sub-chain only (skip the full pairing flow).
|
|
86
97
|
* - `"NO_PAIRING"` — no pairing at all; run the full pairing chain followed by a refresh.
|
|
87
98
|
*/
|
|
88
|
-
hasPairing: () => Promise<PairingStatus>;
|
|
99
|
+
hasPairing: (opts?: DeviceOperationOptions) => Promise<PairingStatus>;
|
|
89
100
|
/**
|
|
90
101
|
* Initialize pairing handshake
|
|
91
102
|
*/
|
|
92
|
-
initPairingHandshake: () => Promise<{
|
|
103
|
+
initPairingHandshake: (opts?: DeviceOperationOptions) => Promise<{
|
|
93
104
|
pubKey: string;
|
|
94
105
|
signature: string;
|
|
95
106
|
}>;
|
|
@@ -127,7 +138,7 @@ type Device = {
|
|
|
127
138
|
*/
|
|
128
139
|
setPairing: (opts: {
|
|
129
140
|
pairing: PsdPairingData;
|
|
130
|
-
}) => Promise<void>;
|
|
141
|
+
} & DeviceOperationOptions) => Promise<void>;
|
|
131
142
|
/**
|
|
132
143
|
* Sign the PSK-refresh authentication challenge (`SIGN_REFRESH_PSK_AUTH`, INS `0x55`).
|
|
133
144
|
*
|
|
@@ -143,7 +154,7 @@ type Device = {
|
|
|
143
154
|
*/
|
|
144
155
|
signRefreshPskAuth: (opts: {
|
|
145
156
|
ephemeralKey: string;
|
|
146
|
-
}) => Promise<string>;
|
|
157
|
+
} & DeviceOperationOptions) => Promise<string>;
|
|
147
158
|
/**
|
|
148
159
|
* Finalize a PSK refresh (`FINALIZE_PSK_REFRESH`, INS `0x53`).
|
|
149
160
|
*
|
|
@@ -151,7 +162,7 @@ type Device = {
|
|
|
151
162
|
* stores the re-delivered (static) PSK in NVM. Throws when the device already holds a different
|
|
152
163
|
* PSK for the partition (`SW_PSK_MISMATCH`, `0x6067`).
|
|
153
164
|
*/
|
|
154
|
-
finalizePskRefresh: (opts: RefreshPskData) => Promise<void>;
|
|
165
|
+
finalizePskRefresh: (opts: RefreshPskData & DeviceOperationOptions) => Promise<void>;
|
|
155
166
|
/**
|
|
156
167
|
* Start KK pattern (related to noise channel)
|
|
157
168
|
*/
|
|
@@ -170,20 +181,20 @@ type Device = {
|
|
|
170
181
|
handshake: string;
|
|
171
182
|
handshakeAttestation: HsmCertificate;
|
|
172
183
|
partitionId: string;
|
|
173
|
-
}) => Promise<void>;
|
|
184
|
+
} & DeviceOperationOptions) => Promise<void>;
|
|
174
185
|
/**
|
|
175
186
|
* Start a PSK session (Secure channel)
|
|
176
187
|
*/
|
|
177
188
|
startPskSession(opts: {
|
|
178
189
|
nonce: string;
|
|
179
190
|
partitionId: string;
|
|
180
|
-
}): Promise<void>;
|
|
191
|
+
} & DeviceOperationOptions): Promise<void>;
|
|
181
192
|
/**
|
|
182
193
|
* Approve with device
|
|
183
194
|
*/
|
|
184
195
|
validateVaultOperation: (opts: {
|
|
185
196
|
actions: string[];
|
|
186
|
-
}) => Promise<string>;
|
|
197
|
+
} & DeviceOperationOptions) => Promise<string>;
|
|
187
198
|
/**
|
|
188
199
|
* Send arbitrary APDU
|
|
189
200
|
* apduCommand in HEX string format
|
|
@@ -193,21 +204,21 @@ type Device = {
|
|
|
193
204
|
* Get app version
|
|
194
205
|
*
|
|
195
206
|
*/
|
|
196
|
-
getVersion: () => Promise<string>;
|
|
207
|
+
getVersion: (opts?: DeviceOperationOptions) => Promise<string>;
|
|
197
208
|
/**
|
|
198
209
|
* Poll device until it's plugged-on
|
|
199
210
|
*
|
|
200
211
|
*/
|
|
201
212
|
poll: (opts?: {
|
|
202
213
|
retryOnError?: (err: Error) => boolean;
|
|
203
|
-
}) => Promise<{
|
|
214
|
+
} & DeviceOperationOptions) => Promise<{
|
|
204
215
|
isAppOpened: boolean;
|
|
205
216
|
}>;
|
|
206
217
|
/**
|
|
207
218
|
* Returned when app is opened
|
|
208
219
|
* appName in string format
|
|
209
220
|
*/
|
|
210
|
-
pollApp: (name: string) => Promise<string>;
|
|
221
|
+
pollApp: (name: string, opts?: DeviceOperationOptions) => Promise<string>;
|
|
211
222
|
};
|
|
212
223
|
//#endregion
|
|
213
224
|
//#region src/device/api-device.d.ts
|
|
@@ -278,4 +289,4 @@ declare const isLockedDeviceError: (error: unknown) => boolean;
|
|
|
278
289
|
declare const isPskMissingError: (error: unknown) => boolean;
|
|
279
290
|
declare const isPskMismatchError: (error: unknown) => boolean;
|
|
280
291
|
//#endregion
|
|
281
|
-
export { isPskMissingError as a, ApiDevice as c, PairingStatus as d, isPskMismatchError as i, createApiDevice as l, isDeviceCancelError as n, isTransportStatusError as o, isLockedDeviceError as r, registerTransportModule as s, isCantOpenDeviceError as t, Device as u };
|
|
292
|
+
export { isPskMissingError as a, ApiDevice as c, PairingStatus as d, DeviceOperationAbortedError as f, isPskMismatchError as i, createApiDevice as l, isDeviceOperationAbortedError as m, isDeviceCancelError as n, isTransportStatusError as o, DeviceOperationOptions as p, isLockedDeviceError as r, registerTransportModule as s, isCantOpenDeviceError as t, Device as u };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { t as Logger } from "./logger-DHtgWA66.cjs";
|
|
2
2
|
import { a as TRPCContext } from "./trpc-BCwyqVKi.cjs";
|
|
3
|
-
import { d as Engine, p as EngineOptions } from "./types-
|
|
3
|
+
import { d as Engine, p as EngineOptions } from "./types-bfqkmpgo.cjs";
|
|
4
4
|
import { CursorPaginated, Paginated } from "@ledgerhq/revault-api";
|
|
5
5
|
//#region src/utils.d.ts
|
|
6
6
|
/**
|