diff --git a/typescript/package.json b/typescript/package.json index ee40c8ba7..53233d1e1 100644 --- a/typescript/package.json +++ b/typescript/package.json @@ -28,7 +28,6 @@ "@bitcoinerlab/secp256k1": "^1.0.5", "@keep-network/ecdsa": "development", "@keep-network/tbtc-v2": "development", - "@ledgerhq/wallet-api-client": "^1.2.1", "bignumber.js": "^9.1.2", "bitcoinjs-lib": "^6.1.5", "bufio": "^1.0.6", diff --git a/typescript/src/lib/utils/index.ts b/typescript/src/lib/utils/index.ts index b51ccf033..d3e639c60 100644 --- a/typescript/src/lib/utils/index.ts +++ b/typescript/src/lib/utils/index.ts @@ -1,3 +1,2 @@ export * from "./backoff" export * from "./hex" -export * from "./ledger" diff --git a/typescript/src/lib/utils/ledger.ts b/typescript/src/lib/utils/ledger.ts deleted file mode 100644 index cde84b059..000000000 --- a/typescript/src/lib/utils/ledger.ts +++ /dev/null @@ -1,239 +0,0 @@ -import { ethers, Signer } from "ethers" -import { - Account, - EthereumTransaction, - WalletAPIClient, - WindowMessageTransport, -} from "@ledgerhq/wallet-api-client" -import { AddressZero } from "@ethersproject/constants" -import { Deferrable } from "@ethersproject/properties" -import { Hex } from "./hex" -import BigNumber from "bignumber.js" - -class AccountNotFoundError extends Error { - constructor() { - super( - "Account not found. Please use `requestAccount` method or set the signer account with `setAccount` method." - ) - } -} - -/** - * Ethereum signer extended from `ethers` Signer class. The main purpose of it - * is to allow the user to communicate with eth contracts through our tBTC SDK - * inside Ledger Live application, when the app is used there as a Live App. - */ -export class LedgerLiveEthereumSigner extends Signer { - private _walletApiClient: WalletAPIClient - private _windowMessageTransport: WindowMessageTransport - private _account: Account | undefined - - constructor(provider?: ethers.providers.Provider) { - super() - ethers.utils.defineReadOnly(this, "provider", provider) - this._windowMessageTransport = getWindowMessageTransport() - this._walletApiClient = getWalletAPIClient(this._windowMessageTransport) - } - - private _checkAccount(): void { - if (!this._account || !this._account.id) { - throw new AccountNotFoundError() - } - } - - private _checkProviderAndAccount(): void { - this._checkProvider() - this._checkAccount() - } - - private _catchWalletApiError(error?: any, defaultErrorMessage?: string) { - this._windowMessageTransport.disconnect() - - if (typeof error === "string" || error instanceof Error) { - throw new Error(error.toString()) - } - throw new Error( - defaultErrorMessage || - "Something went wrong when using ledger live singer to interact with out wallet." - ) - } - - get account() { - return this._account - } - - setAccount(account: Account | undefined): void { - this._account = account - } - - async requestAccount( - params: { currencyIds?: string[] | undefined } | undefined - ): Promise { - let account: Account - try { - this._windowMessageTransport.connect() - account = await this._walletApiClient.account.request(params) - this._windowMessageTransport.disconnect() - } catch (err) { - this._catchWalletApiError( - err, - "Something went wrong when requesting an account with ledger live signer!" - ) - } - - this._account = account! - return this._account - } - - getAccountId(): string { - this._checkAccount() - return this._account!.id - } - - async getAddress(): Promise { - this._checkAccount() - return this._account!.address - } - - private _getWalletApiEthereumTransaction( - transaction: ethers.providers.TransactionRequest - ): EthereumTransaction { - const { - value, - to, - nonce, - data, - gasPrice, - gasLimit, - maxFeePerGas, - maxPriorityFeePerGas, - } = transaction - - const ethereumTransaction: EthereumTransaction = { - family: "ethereum" as const, - amount: value ? new BigNumber(value.toString()) : new BigNumber(0), - recipient: to ? to : AddressZero, - } - - if (nonce) ethereumTransaction.nonce = Number(nonce) - if (data) - ethereumTransaction.data = Buffer.from( - Hex.from(data.toString()).toString(), - "hex" - ) - if (gasPrice) - ethereumTransaction.gasPrice = new BigNumber(gasPrice.toString()) - if (gasLimit) - ethereumTransaction.gasLimit = new BigNumber(gasLimit.toString()) - if (maxFeePerGas) - ethereumTransaction.maxFeePerGas = new BigNumber(maxFeePerGas.toString()) - if (maxPriorityFeePerGas) - ethereumTransaction.maxPriorityFeePerGas = new BigNumber( - maxPriorityFeePerGas.toString() - ) - - return ethereumTransaction - } - - async signMessage(message: string): Promise { - this._checkAccount() - - let buffer: Buffer - try { - this._windowMessageTransport.connect() - buffer = await this._walletApiClient.message.sign( - this._account!.id, - Buffer.from(message) - ) - this._windowMessageTransport.disconnect() - } catch (err) { - this._catchWalletApiError( - err, - "Something went wrong when signing a message with ledger live signer!" - ) - } - - return buffer!.toString() - } - - async signTransaction( - transaction: ethers.providers.TransactionRequest - ): Promise { - this._checkAccount() - - const ethereumTransaction = - this._getWalletApiEthereumTransaction(transaction) - - let buffer: Buffer - try { - this._windowMessageTransport.connect() - buffer = await this._walletApiClient.transaction.sign( - this._account!.id, - ethereumTransaction - ) - this._windowMessageTransport.disconnect() - } catch (err) { - this._catchWalletApiError( - err, - "Something went wrong when signing a transaction with ledger live signer!" - ) - } - - return buffer!.toString() - } - - async sendTransaction( - transaction: Deferrable - ): Promise { - this._checkProviderAndAccount() - - const pupulatedTransaction = await this.populateTransaction(transaction) - const ethereumTransaction = - this._getWalletApiEthereumTransaction(pupulatedTransaction) - - let transactionHash: string - try { - this._windowMessageTransport.connect() - transactionHash = - await this._walletApiClient.transaction.signAndBroadcast( - this._account!.id, - ethereumTransaction - ) - this._windowMessageTransport.disconnect() - } catch (err) { - this._catchWalletApiError( - err, - "Something went wrong when sending a transaction with ledger live signer!" - ) - } - - const transactionResponse = await this.provider?.getTransaction( - transactionHash! - ) - - if (!transactionResponse) { - throw new Error("Transaction response not found!") - } - - return transactionResponse - } - - connect(provider: ethers.providers.Provider): Signer { - const account = this._account - const newLedgerLiveEthereumSignerInstance = new LedgerLiveEthereumSigner( - provider - ) - newLedgerLiveEthereumSignerInstance.setAccount(account) - return newLedgerLiveEthereumSignerInstance - } -} - -const getWindowMessageTransport = () => { - return new WindowMessageTransport() -} - -const getWalletAPIClient = (windowMessageTransport: WindowMessageTransport) => { - const walletApiClient = new WalletAPIClient(windowMessageTransport) - - return walletApiClient -} diff --git a/typescript/yarn.lock b/typescript/yarn.lock index 50dcebc13..82e30e919 100644 --- a/typescript/yarn.lock +++ b/typescript/yarn.lock @@ -1644,26 +1644,11 @@ rxjs "6" semver "^7.3.5" -"@ledgerhq/devices@^8.0.7": - version "8.0.7" - resolved "https://registry.yarnpkg.com/@ledgerhq/devices/-/devices-8.0.7.tgz#206434dbd8a097529bbfc95f5eef94c2923c7578" - integrity sha512-BbPyET52lXnVs7CxJWrGYqmtGdbGzj+XnfCqLsDnA7QYr1CZREysxmie+Rr6BKpNDBRVesAovXjtaVaZOn+upw== - dependencies: - "@ledgerhq/errors" "^6.14.0" - "@ledgerhq/logs" "^6.10.1" - rxjs "6" - semver "^7.3.5" - "@ledgerhq/errors@^5.50.0": version "5.50.0" resolved "https://registry.yarnpkg.com/@ledgerhq/errors/-/errors-5.50.0.tgz#e3a6834cb8c19346efca214c1af84ed28e69dad9" integrity sha512-gu6aJ/BHuRlpU7kgVpy2vcYk6atjB4iauP2ymF7Gk0ez0Y/6VSMVSJvubeEQN+IV60+OBK0JgeIZG7OiHaw8ow== -"@ledgerhq/errors@^6.14.0": - version "6.14.0" - resolved "https://registry.yarnpkg.com/@ledgerhq/errors/-/errors-6.14.0.tgz#0bf253983773ef12eebce2091f463bc719223b37" - integrity sha512-ZWJw2Ti6Dq1Ott/+qYqJdDWeZm16qI3VNG5rFlb0TQ3UcAyLIQZbnnzzdcVVwVeZiEp66WIpINd/pBdqsHVyOA== - "@ledgerhq/hw-app-eth@^5.11.0": version "5.53.0" resolved "https://registry.yarnpkg.com/@ledgerhq/hw-app-eth/-/hw-app-eth-5.53.0.tgz#5df2d7427db9f387099d0cc437e9730101d7c404" @@ -1685,44 +1670,11 @@ "@ledgerhq/errors" "^5.50.0" events "^3.3.0" -"@ledgerhq/hw-transport@^6.28.8": - version "6.28.8" - resolved "https://registry.yarnpkg.com/@ledgerhq/hw-transport/-/hw-transport-6.28.8.tgz#f99a5c71c5c09591e9bfb1b970c42aafbe81351f" - integrity sha512-XxQVl4htd018u/M66r0iu5nlHi+J6QfdPsORzDF6N39jaz+tMqItb7tUlXM/isggcuS5lc7GJo7NOuJ8rvHZaQ== - dependencies: - "@ledgerhq/devices" "^8.0.7" - "@ledgerhq/errors" "^6.14.0" - events "^3.3.0" - "@ledgerhq/logs@^5.50.0": version "5.50.0" resolved "https://registry.yarnpkg.com/@ledgerhq/logs/-/logs-5.50.0.tgz#29c6419e8379d496ab6d0426eadf3c4d100cd186" integrity sha512-swKHYCOZUGyVt4ge0u8a7AwNcA//h4nx5wIi0sruGye1IJ5Cva0GyK9L2/WdX+kWVTKp92ZiEo1df31lrWGPgA== -"@ledgerhq/logs@^6.10.1": - version "6.10.1" - resolved "https://registry.yarnpkg.com/@ledgerhq/logs/-/logs-6.10.1.tgz#5bd16082261d7364eabb511c788f00937dac588d" - integrity sha512-z+ILK8Q3y+nfUl43ctCPuR4Y2bIxk/ooCQFwZxhtci1EhAtMDzMAx2W25qx8G1PPL9UUOdnUax19+F0OjXoj4w== - -"@ledgerhq/wallet-api-client@^1.2.1": - version "1.2.1" - resolved "https://registry.yarnpkg.com/@ledgerhq/wallet-api-client/-/wallet-api-client-1.2.1.tgz#b47fe5b4f431282f50ddb64c8abb911545593eba" - integrity sha512-uTBTZCpbLTM5y5Cd7ioQB0lcq0b3cbrU2bGzCiKuY1IEd0NUyFhr2dKliRrcLoMPDRtQRmRnSxeX0BFKinoo8Q== - dependencies: - "@ledgerhq/hw-transport" "^6.28.8" - "@ledgerhq/wallet-api-core" "1.3.1" - bignumber.js "^9.1.2" - -"@ledgerhq/wallet-api-core@1.3.1": - version "1.3.1" - resolved "https://registry.yarnpkg.com/@ledgerhq/wallet-api-core/-/wallet-api-core-1.3.1.tgz#092d027a6d9ce7139a2d4c157480e2feb7c88489" - integrity sha512-yOeb1tfdwF6NdxVEIVr8SVz5iOyh6asWa0bbuCyMpiLrfuVS/Wkr6OeDMBYSxWxXxRFmQDJ9XQxdtSS+MGNk1Q== - dependencies: - "@ledgerhq/errors" "^6.14.0" - bignumber.js "^9.1.2" - uuid "^9.0.0" - zod "^3.22.2" - "@noble/hashes@^1.1.5", "@noble/hashes@^1.2.0": version "1.3.2" resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.2.tgz#6f26dbc8fbc7205873ce3cee2f690eba0d421b39" @@ -7994,11 +7946,6 @@ uuid@^3.3.2: resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== -uuid@^9.0.0: - version "9.0.1" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-9.0.1.tgz#e188d4c8853cc722220392c424cd637f32293f30" - integrity sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA== - v8-compile-cache-lib@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf" @@ -9145,8 +9092,3 @@ yocto-queue@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== - -zod@^3.22.2: - version "3.22.4" - resolved "https://registry.yarnpkg.com/zod/-/zod-3.22.4.tgz#f31c3a9386f61b1f228af56faa9255e845cf3fff" - integrity sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==