UNPKG

@metamask/eth-ledger-bridge-keyring

Version:
204 lines 10.4 kB
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) { if (kind === "m") throw new TypeError("Private method is not writable"); if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value; }; var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) { if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); }; var _LedgerMobileBridge_instances, _a, _LedgerMobileBridge_transportMiddleware, _LedgerMobileBridge_opts, _LedgerMobileBridge_getTransportMiddleWare, _LedgerMobileBridge_getEthApp, _LedgerMobileBridge_isLedgerUserRejection; import { TransportStatusError } from "@ledgerhq/hw-transport"; import { ERC20_WRITE_SELECTORS, NFT_ONLY_SELECTORS } from "./constants.mjs"; import { MetaMaskLedgerHwAppEth } from "./ledger-hw-app.mjs"; import { getTransactionSelector } from "./utils.mjs"; /** Ledger APDU: CONDITIONS_OF_USE_NOT_SATISFIED (user rejected on device). */ const LEDGER_USER_REJECTION_STATUS = 0x6985; /** * LedgerMobileBridge is a bridge between the LedgerKeyring and the LedgerTransportMiddleware. */ export class LedgerMobileBridge { constructor(transportMiddleware, opts = {}) { _LedgerMobileBridge_instances.add(this); _LedgerMobileBridge_transportMiddleware.set(this, void 0); _LedgerMobileBridge_opts.set(this, void 0); this.isDeviceConnected = false; __classPrivateFieldSet(this, _LedgerMobileBridge_opts, opts, "f"); __classPrivateFieldSet(this, _LedgerMobileBridge_transportMiddleware, transportMiddleware, "f"); } /** * Method to initializes the keyring. * Mobile ledger doesnt not require init. * * @returns A promise that will resolve once the bridge is initialized. */ async init() { return Promise.resolve(); } /** * Method to destroy the keyring. * It will dispose the transportmiddleware and set isDeviceConnected to false. */ async destroy() { try { await __classPrivateFieldGet(this, _LedgerMobileBridge_instances, "m", _LedgerMobileBridge_getTransportMiddleWare).call(this).dispose(); } catch (error) { console.error(error); } this.isDeviceConnected = false; } /** * Method to sign a string Message. * Sending the string message to the device and returning the signed message. * * @param params - An object contains hdPath and message. * @param params.hdPath - The BIP 32 path of the account. * @param params.message - The message to sign. * @returns Retrieve v, r, s from the signed message. */ async deviceSignMessage({ hdPath, message, }) { return __classPrivateFieldGet(this, _LedgerMobileBridge_instances, "m", _LedgerMobileBridge_getEthApp).call(this).signPersonalMessage(hdPath, message); } /** * Method to sign a EIP712 Message. * Sending the typed data message to the device and returning the signed message. * * @param params - An object contains hdPath, domainSeparatorHex and hashStructMessageHex. * @param params.hdPath - The BIP 32 path of the account. * @param params.message - The EIP712 message to sign. * @returns Retrieve v, r, s from the signed message. */ async deviceSignTypedData({ hdPath, message, }) { return __classPrivateFieldGet(this, _LedgerMobileBridge_instances, "m", _LedgerMobileBridge_getEthApp).call(this).signEIP712Message(hdPath, message); } async deviceSignDelegationAuthorization({ hdPath: _hdPath, chainId: _chainId, contractAddress: _contractAddress, nonce: _nonce, }) { throw new Error('Ledger: signDelegationAuthorization is not supported via mobile bridge'); } /** * Method to sign a transaction * Sending the hexadecimal transaction message to the device and returning the signed transaction. * * Tries clear-signing first. If resolution fails (e.g. no Ledger plugin for the chain or contract), * falls back to blind signing via `signTransaction(..., null)` unless the user rejected on the device. * * @param params - An object contains tx, hdPath. * @param params.tx - The raw ethereum transaction in hexadecimal to sign. * @param params.hdPath - The BIP 32 path of the account. * @returns Retrieve v, r, s from the signed transaction. */ async deviceSignTransaction({ tx, hdPath, }) { const selector = getTransactionSelector(tx); const nft = Boolean(selector && NFT_ONLY_SELECTORS.has(selector)); const erc20 = Boolean(selector && ERC20_WRITE_SELECTORS.has(selector)); const ethApp = __classPrivateFieldGet(this, _LedgerMobileBridge_instances, "m", _LedgerMobileBridge_getEthApp).call(this); try { return await ethApp.clearSignTransaction(hdPath, tx, { externalPlugins: true, erc20, nft, }); } catch (error) { if (__classPrivateFieldGet(_a, _a, "m", _LedgerMobileBridge_isLedgerUserRejection).call(_a, error)) { throw error; } console.warn('Ledger clear-sign failed; falling back to blind signing.', error); return ethApp.signTransaction(hdPath, tx, null); } } /** * Method to retrieve the ethereum address for a given BIP 32 path. * * @param params - An object contains hdPath. * @param params.hdPath - The BIP 32 path of the account. * @returns An object contains publicKey, address and chainCode. */ async getPublicKey({ hdPath, }) { return await __classPrivateFieldGet(this, _LedgerMobileBridge_instances, "m", _LedgerMobileBridge_getEthApp).call(this).getAddress(hdPath, false, true); } /** * Method to retrieve the current configuration. * * @returns Retrieve current configuration. */ async getOptions() { return __classPrivateFieldGet(this, _LedgerMobileBridge_opts, "f"); } /** * Method to set the current configuration. * * @param opts - An configuration object. */ async setOptions(opts) { __classPrivateFieldSet(this, _LedgerMobileBridge_opts, opts, "f"); } /** * Method to set the transport object to communicate with the device. * * @param transport - The communication interface with the Ledger hardware wallet. There are different kind of transports based on the technology (channels like U2F, HID, Bluetooth, Webusb). * @returns Retrieve boolean. */ async updateTransportMethod(transport) { if (!transport.deviceModel) { throw new Error('Property `deviceModel` is not defined in `transport`.'); } if (!transport.deviceModel.id) { throw new Error('Property `deviceModel.id` is not defined in `transport`.'); } __classPrivateFieldGet(this, _LedgerMobileBridge_instances, "m", _LedgerMobileBridge_getTransportMiddleWare).call(this).setTransport(transport); this.isDeviceConnected = true; return Promise.resolve(true); } /** * Method to init eth app object on ledger device. * This method is not supported on mobile. */ async attemptMakeApp() { throw new Error('Method not supported.'); } /** * Method to open ethereum application on ledger device. * */ async openEthApp() { await __classPrivateFieldGet(this, _LedgerMobileBridge_instances, "m", _LedgerMobileBridge_getEthApp).call(this).openEthApp(); } /** * Method to close all running application on ledger device. * */ async closeApps() { await __classPrivateFieldGet(this, _LedgerMobileBridge_instances, "m", _LedgerMobileBridge_getEthApp).call(this).closeApps(); } /** * Method to retrieve the name and version of the running application in ledger device. * * @returns An object contains appName and version. */ async getAppNameAndVersion() { return __classPrivateFieldGet(this, _LedgerMobileBridge_instances, "m", _LedgerMobileBridge_getEthApp).call(this).getAppNameAndVersion(); } /** * Method to retrieve the current configuration of the Ethereum application on the Ledger device. * * @returns An object containing the application configuration including blind signing support, ERC20 provisioning status, Stark support, and version. */ async getAppConfiguration() { return __classPrivateFieldGet(this, _LedgerMobileBridge_instances, "m", _LedgerMobileBridge_getEthApp).call(this).getAppConfiguration(); } } _a = LedgerMobileBridge, _LedgerMobileBridge_transportMiddleware = new WeakMap(), _LedgerMobileBridge_opts = new WeakMap(), _LedgerMobileBridge_instances = new WeakSet(), _LedgerMobileBridge_getTransportMiddleWare = function _LedgerMobileBridge_getTransportMiddleWare() { if (__classPrivateFieldGet(this, _LedgerMobileBridge_transportMiddleware, "f")) { return __classPrivateFieldGet(this, _LedgerMobileBridge_transportMiddleware, "f"); } throw new Error('Instance `transportMiddleware` is not initialized.'); }, _LedgerMobileBridge_getEthApp = function _LedgerMobileBridge_getEthApp() { return __classPrivateFieldGet(this, _LedgerMobileBridge_instances, "m", _LedgerMobileBridge_getTransportMiddleWare).call(this).getEthApp(); }, _LedgerMobileBridge_isLedgerUserRejection = function _LedgerMobileBridge_isLedgerUserRejection(error) { return (error instanceof TransportStatusError && error.statusCode === LEDGER_USER_REJECTION_STATUS); }; //# sourceMappingURL=ledger-mobile-bridge.mjs.map