@hazae41/ledger
Version:
Private and supply-chain hardened Ledger controller for TypeScript
1 lines • 16.7 kB
Source Map (JSON)
{"version":3,"file":"index.mjs","sources":["../../../../src/mods/ethereum/index.ts"],"sourcesContent":["import { Empty, Opaque, Readable, Writable } from \"@hazae41/binary\";\nimport type { Uint8Array } from \"@hazae41/bytes\";\nimport { Bytes } from \"@hazae41/bytes\";\nimport { Rlp, RsvSignature } from \"@hazae41/cubane\";\nimport { Cursor } from \"@hazae41/cursor\";\nimport { Connector } from \"../apdu/index.js\";\nimport { Paths } from \"../binary/paths.js\";\n\nexport interface AppConfigResult {\n readonly arbitraryDataEnabled: boolean,\n\n readonly erc20ProvisioningNecessary: boolean,\n\n readonly starkEnabled: boolean,\n\n readonly starkv2Supported: boolean,\n\n readonly version: string\n}\n\nexport async function getAppConfigOrThrow(device: Connector): Promise<AppConfigResult> {\n const request = { cla: 0xe0, ins: 0x06, p1: 0x00, p2: 0x00, fragment: new Empty() }\n const response = await device.requestOrThrow(request).then(r => r.getOrThrow().bytes)\n\n const arbitraryDataEnabled = Boolean(response[0] & 0x01)\n const erc20ProvisioningNecessary = Boolean(response[0] & 0x02)\n const starkEnabled = Boolean(response[0] & 0x04)\n const starkv2Supported = Boolean(response[0] & 0x08)\n\n const version = `${response[1]}.${response[2]}.${response[3]}`\n\n return { arbitraryDataEnabled, erc20ProvisioningNecessary, starkEnabled, starkv2Supported, version }\n}\n\nexport interface GetAddressResult {\n /**\n * 0x-prefixed hex address\n */\n readonly address: string\n\n /**\n * Raw uncompressed public key bytes\n */\n readonly uncompressedPublicKey: Uint8Array\n\n /**\n * Raw chaincode bytes\n */\n readonly chaincode: Uint8Array<32>\n}\n\n/**\n * Just get the address\n * @param device \n * @param path \n * @returns \n */\nexport async function getAddressOrThrow(device: Connector, path: string): Promise<GetAddressResult> {\n const paths = Paths.from(path)\n\n const bytes = Writable.writeToBytesOrThrow(paths)\n\n const request = { cla: 0xe0, ins: 0x02, p1: 0x00, p2: 0x01, fragment: new Opaque(bytes) }\n const response = await device.requestOrThrow(request).then(r => r.getOrThrow().bytes)\n\n const cursor = new Cursor(response)\n\n const uncompressedPublicKeyLength = cursor.readUint8OrThrow()\n const uncompressedPublicKey = cursor.readAndCopyOrThrow(uncompressedPublicKeyLength)\n\n const addressLength = cursor.readUint8OrThrow()\n const address = `0x${Bytes.toAscii(cursor.readOrThrow(addressLength))}`\n\n const chaincode = cursor.readAndCopyOrThrow(32)\n\n return { uncompressedPublicKey, address, chaincode }\n}\n\n/**\n * Ask the user to verify the address and get it\n * @param device \n * @param path \n * @returns \n */\nexport async function verifyAndGetAddressOrThrow(device: Connector, path: string): Promise<GetAddressResult> {\n const paths = Paths.from(path)\n\n const bytes = Writable.writeToBytesOrThrow(paths)\n\n const request = { cla: 0xe0, ins: 0x02, p1: 0x01, p2: 0x01, fragment: new Opaque(bytes) }\n const response = await device.requestOrThrow(request).then(r => r.getOrThrow().bytes)\n\n const cursor = new Cursor(response)\n\n const uncompressedPublicKeyLength = cursor.readUint8OrThrow()\n const uncompressedPublicKey = cursor.readAndCopyOrThrow(uncompressedPublicKeyLength)\n\n const addressLength = cursor.readUint8OrThrow()\n const address = `0x${Bytes.toAscii(cursor.readOrThrow(addressLength))}`\n\n const chaincode = cursor.readAndCopyOrThrow(32)\n\n return { uncompressedPublicKey, address, chaincode }\n}\n\nexport async function signPersonalMessageOrThrow(device: Connector, path: string, message: Uint8Array): Promise<RsvSignature> {\n const paths = Paths.from(path)\n\n const reader = new Cursor(message)\n\n let response: Uint8Array\n\n {\n const head = paths.sizeOrThrow() + 4\n const body = Math.min(150 - head, reader.remaining)\n\n const chunk = reader.readOrThrow(body)\n\n const writer = new Cursor(new Uint8Array(head + body))\n paths.writeOrThrow(writer)\n writer.writeUint32OrThrow(message.length)\n writer.writeOrThrow(chunk)\n\n const request = { cla: 0xe0, ins: 0x08, p1: 0x00, p2: 0x00, fragment: new Opaque(writer.bytes) }\n response = await device.requestOrThrow(request).then(r => r.getOrThrow().bytes)\n }\n\n while (reader.remaining) {\n const body = Math.min(150, reader.remaining)\n const chunk = reader.readOrThrow(body)\n\n const request = { cla: 0xe0, ins: 0x08, p1: 0x80, p2: 0x00, fragment: new Opaque(chunk) }\n response = await device.requestOrThrow(request).then(r => r.getOrThrow().bytes)\n }\n\n const cursor = new Cursor(response)\n const v = cursor.readUint8OrThrow() - 27\n const r = cursor.readAndCopyOrThrow(32)\n const s = cursor.readAndCopyOrThrow(32)\n\n return RsvSignature.create({ r, s, v })\n}\n\n/**\n * Get the unprotected part of a legacy replay-protected transaction\n * @param transaction \n * @returns \n */\nfunction readLegacyUnprotectedOrThrow(transaction: Uint8Array) {\n /**\n * This is not a legacy transaction (EIP-2718)\n */\n if (transaction[0] < 0x80)\n return undefined\n\n /**\n * Decode the bytes as RLP\n */\n const rlp = Readable.readFromBytesOrThrow(Rlp, transaction).intoOrThrow()\n\n if (!Array.isArray(rlp))\n throw new Error(`Wrong RLP type for transaction`)\n\n /**\n * This is not a replay-protected transaction (EIP-155)\n */\n if (rlp.length !== 9)\n return undefined\n\n /**\n * Take only the first 6 parameters instead of the 9\n */\n const [nonce, gasprice, startgas, to, value, data] = rlp\n\n /**\n * Encode them as RLP\n */\n return Writable.writeToBytesOrThrow(Rlp.fromOrThrow([nonce, gasprice, startgas, to, value, data]))\n}\n\nexport async function signTransactionOrThrow(device: Connector, path: string, transaction: Uint8Array): Promise<RsvSignature> {\n const paths = Paths.from(path)\n\n const reader = new Cursor(transaction)\n\n const unprotected = readLegacyUnprotectedOrThrow(transaction)\n\n let response: Uint8Array\n\n {\n const head = paths.sizeOrThrow()\n\n let body = Math.min(150 - head, reader.remaining)\n\n /**\n * Make sure that the chunk doesn't end right on the replay protection marker (EIP-155)\n * If it goes further than the unprotected part, then send the (few) remaining bytes of the protection\n */\n if (unprotected != null && reader.offset + body >= unprotected.length)\n body = reader.remaining\n\n const chunk = reader.readOrThrow(body)\n\n const writer = new Cursor(new Uint8Array(head + body))\n paths.writeOrThrow(writer)\n writer.writeOrThrow(chunk)\n\n const request = { cla: 0xe0, ins: 0x04, p1: 0x00, p2: 0x00, fragment: new Opaque(writer.bytes) }\n response = await device.requestOrThrow(request).then(r => r.getOrThrow().bytes)\n }\n\n while (reader.remaining) {\n let body = Math.min(150, reader.remaining)\n\n /**\n * Make sure that the chunk doesn't end right on the replay protection marker (EIP-155)\n * If it goes further than the unprotected part, then send the (few) remaining bytes of the protection\n */\n if (unprotected != null && reader.offset + body >= unprotected.length)\n body = reader.remaining\n\n const chunk = reader.readOrThrow(body)\n\n const request = { cla: 0xe0, ins: 0x04, p1: 0x80, p2: 0x00, fragment: new Opaque(chunk) }\n response = await device.requestOrThrow(request).then(r => r.getOrThrow().bytes)\n }\n\n const cursor = new Cursor(response)\n const v = cursor.readUint8OrThrow()\n const r = cursor.readAndCopyOrThrow(32)\n const s = cursor.readAndCopyOrThrow(32)\n\n // if ((((chainId * 2) + 35) + 1) > 255) {\n // const parity = Math.abs(v0 - (((chainId * 2) + 35) % 256))\n\n // if (transaction.type == null)\n // v = ((chainId * 2) + 35) + parity\n // else\n // v = (parity % 2) == 1 ? 0 : 1;\n // }\n\n return RsvSignature.create({ r, s, v })\n}\n\nexport async function signEIP712HashedMessageOrThrow(device: Connector, path: string, domain: Uint8Array<32>, message: Uint8Array<32>): Promise<RsvSignature> {\n const paths = Paths.from(path)\n\n const writer = new Cursor(new Uint8Array(paths.sizeOrThrow() + 32 + 32))\n paths.writeOrThrow(writer)\n writer.writeOrThrow(domain)\n writer.writeOrThrow(message)\n\n const request = { cla: 0xe0, ins: 0x0c, p1: 0x00, p2: 0x00, fragment: new Opaque(writer.bytes) }\n const response = await device.requestOrThrow(request).then(r => r.getOrThrow().bytes)\n\n const reader = new Cursor(response)\n const v = reader.readUint8OrThrow() - 27\n const r = reader.readAndCopyOrThrow(32)\n const s = reader.readAndCopyOrThrow(32)\n\n return RsvSignature.create({ r, s, v })\n}"],"names":[],"mappings":"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"}