UNPKG

@zondax/ledger-substrate

Version:

TS / Node API for Substrate/Polkadot based apps running on Ledger devices

191 lines 6.9 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ERROR_DESCRIPTION = exports.ECDSA_PUBKEY_LEN = exports.ED25519_PUBKEY_LEN = exports.CHUNK_SIZE = void 0; exports.toBuffer = toBuffer; exports.errorCodeToString = errorCodeToString; exports.processErrorResponse = processErrorResponse; exports.getVersion = getVersion; exports.serializePath = serializePath; const buffer_1 = require("buffer/"); /** ****************************************************************************** * (c) 2019 - 2022 Zondax AG * (c) 2016-2017 Ledger * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. ******************************************************************************* */ // Use global Buffer if available (Node.js), otherwise use polyfill (browser) const BufferImpl = typeof Buffer !== 'undefined' ? Buffer : buffer_1.Buffer; /** * Converts various input types to Buffer * @param input - Buffer, Uint8Array, or hex string * @returns Buffer */ function toBuffer(input) { if (BufferImpl.isBuffer(input)) { return input; } if (input instanceof Uint8Array) { return BufferImpl.from(input); } // Assume hex string const hex = input.startsWith('0x') ? input.slice(2) : input; return BufferImpl.from(hex, 'hex'); } /** * @deprecated Moved to @zondax/ledger-js */ exports.CHUNK_SIZE = 250; /** * Address lengths for different schemes */ exports.ED25519_PUBKEY_LEN = 32; exports.ECDSA_PUBKEY_LEN = 33; /** * @deprecated Moved to @zondax/ledger-js */ exports.ERROR_DESCRIPTION = { 1: 'U2F: Unknown', 2: 'U2F: Bad request', 3: 'U2F: Configuration unsupported', 4: 'U2F: Device Ineligible', 5: 'U2F: Timeout', 14: 'Timeout', 0x9000: 'No errors', 0x9001: 'Device is busy', 0x6802: 'Error deriving keys', 0x6400: 'Execution Error', 0x6700: 'Wrong Length', 0x6982: 'Empty Buffer', 0x6983: 'Output buffer too small', 0x6984: 'Data is invalid', 0x6985: 'Conditions not satisfied', 0x6986: 'Transaction rejected', 0x6a80: 'Bad key handle', 0x6b00: 'Invalid P1/P2', 0x6d00: 'Instruction not supported', 0x6e01: 'App does not seem to be open', 0x6f00: 'Unknown error', 0x6f01: 'Sign/verify error', }; /** * @deprecated Moved to @zondax/ledger-js */ function errorCodeToString(statusCode) { if (statusCode in exports.ERROR_DESCRIPTION) return exports.ERROR_DESCRIPTION[statusCode]; return `Unknown Status Code: ${statusCode}`; } /** * @deprecated Moved to @zondax/ledger-js */ function isDict(v) { return typeof v === 'object' && v !== null && !(v instanceof Array) && !(v instanceof Date); } /** * @deprecated Moved to @zondax/ledger-js */ function processErrorResponse(response) { if (response != null) { if (isDict(response)) { if (Object.prototype.hasOwnProperty.call(response, 'returnCode')) { return { return_code: response.returnCode, error_message: errorCodeToString(response.returnCode), }; } if (Object.prototype.hasOwnProperty.call(response, 'statusCode')) { return { return_code: response.statusCode, error_message: errorCodeToString(response.statusCode), }; } if (Object.prototype.hasOwnProperty.call(response, 'return_code') && Object.prototype.hasOwnProperty.call(response, 'error_message')) { return response; } } return { return_code: 0xffff, error_message: response.toString(), }; } return { return_code: 0xffff, error_message: response.toString(), }; } async function getVersion(transport, cla) { try { const response = await transport.send(cla, 0 /* INS.GET_VERSION */, 0, 0); const errorCodeData = response.subarray(-2); const returnCode = errorCodeData[0] * 256 + errorCodeData[1]; // 12 bytes + 2 error code (2 bytes per value on version) // 18 bytes + 2 error code (4 bytes per value on version) if (response.length !== 14 && response.length !== 20) { return { return_code: 27012 /* ERROR_CODE.InvalidData */, error_message: errorCodeToString(27012 /* ERROR_CODE.InvalidData */), }; } let major, minor, patch, deviceLocked, targetId; if (response.length === 14) { // 12 bytes + 2 error code (2 bytes per value on version) major = response.readUInt16BE(1); minor = response.readUInt16BE(3); patch = response.readUInt16BE(5); deviceLocked = response[7] === 1; targetId = (response[8] << 24) + (response[9] << 16) + (response[10] << 8) + (response[11] << 0); } else { // 18 bytes + 2 error code (4 bytes per value on version) major = response.readUInt32BE(1); minor = response.readUInt32BE(5); patch = response.readUInt32BE(9); deviceLocked = response[13] === 1; targetId = (response[14] << 24) + (response[15] << 16) + (response[16] << 8) + (response[17] << 0); } return { return_code: returnCode, error_message: errorCodeToString(returnCode), // /// test_mode: response[0] !== 0, major, minor, patch, deviceLocked, target_id: targetId.toString(16), }; } catch (e) { return processErrorResponse(e); } } /** * @deprecated This function is deprecated and will be removed in future versions. */ function serializePath(slip0044, account, change, addressIndex) { if (!Number.isInteger(account)) throw new Error('Input must be an integer'); if (!Number.isInteger(change)) throw new Error('Input must be an integer'); if (!Number.isInteger(addressIndex)) throw new Error('Input must be an integer'); const buf = Buffer.alloc(20); buf.writeUInt32LE(0x8000002c, 0); buf.writeUInt32LE(slip0044, 4); buf.writeUInt32LE(account, 8); buf.writeUInt32LE(change, 12); buf.writeUInt32LE(addressIndex, 16); return buf; } //# sourceMappingURL=common.js.map