From 4e011d5b91db01d0a2f779d99145334ef361c88d Mon Sep 17 00:00:00 2001 From: gomes <17035424+gomesalexandre@users.noreply.github.com> Date: Wed, 25 Oct 2023 11:13:46 +0200 Subject: [PATCH] perf: don't import * as ethers --- packages/hdwallet-keepkey/src/ethereum.ts | 8 +-- packages/hdwallet-ledger/src/ethereum.ts | 6 +-- .../src/adapter.ts | 4 +- packages/hdwallet-metamask/src/adapter.ts | 4 +- .../src/crypto/isolation/adapters/ethereum.ts | 50 +++++++++++-------- packages/hdwallet-native/src/ethereum.test.ts | 6 +-- packages/hdwallet-native/src/ethereum.ts | 8 +-- packages/hdwallet-tallyho/src/adapter.ts | 4 +- .../hdwallet-tallyho/src/ethereum.test.ts | 20 ++++---- packages/hdwallet-xdefi/src/adapter.ts | 4 +- packages/hdwallet-xdefi/src/ethereum.test.ts | 22 ++++---- 11 files changed, 72 insertions(+), 64 deletions(-) diff --git a/packages/hdwallet-keepkey/src/ethereum.ts b/packages/hdwallet-keepkey/src/ethereum.ts index 4c2d0ddd4..cc374595a 100644 --- a/packages/hdwallet-keepkey/src/ethereum.ts +++ b/packages/hdwallet-keepkey/src/ethereum.ts @@ -6,7 +6,7 @@ import * as Types from "@keepkey/device-protocol/lib/types_pb"; import * as core from "@shapeshiftoss/hdwallet-core"; import { getMessage, getTypeHash } from "eip-712"; import * as eip55 from "eip55"; -import * as ethers from "ethers"; +import { arrayify, isBytes, isHexString } from "ethers/lib/utils.js"; import { Transport } from "./transport"; import { toUTF8Array } from "./utils"; @@ -173,10 +173,10 @@ export async function ethGetAddress(transport: Transport, msg: core.ETHGetAddres export async function ethSignMessage(transport: Transport, msg: core.ETHSignMessage): Promise { const { addressNList, message } = msg; - if (!ethers.utils.isHexString(message)) throw new Error("data is not an hex string"); + if (!isHexString(message)) throw new Error("data is not an hex string"); const m = new Ethereum.EthereumSignMessage(); m.setAddressNList(addressNList); - const messageBytes = ethers.utils.arrayify(message); + const messageBytes = arrayify(message); m.setMessage(messageBytes); const response = await transport.call(Messages.MessageType.MESSAGETYPE_ETHEREUMSIGNMESSAGE, m, { msgTimeout: core.LONG_TIMEOUT, @@ -272,7 +272,7 @@ export async function ethVerifyMessage(transport: Transport, msg: core.ETHVerify const m = new Ethereum.EthereumVerifyMessage(); m.setAddress(core.arrayify(msg.address)); m.setSignature(core.arrayify(msg.signature)); - m.setMessage(ethers.utils.isBytes(msg.message) ? ethers.utils.arrayify(msg.message) : toUTF8Array(msg.message)); + m.setMessage(isBytes(msg.message) ? arrayify(msg.message) : toUTF8Array(msg.message)); let event: core.Event; try { event = await transport.call(Messages.MessageType.MESSAGETYPE_ETHEREUMVERIFYMESSAGE, m, { diff --git a/packages/hdwallet-ledger/src/ethereum.ts b/packages/hdwallet-ledger/src/ethereum.ts index 314c02bfa..bb7ff5a2b 100644 --- a/packages/hdwallet-ledger/src/ethereum.ts +++ b/packages/hdwallet-ledger/src/ethereum.ts @@ -6,7 +6,7 @@ import EthereumTx from "ethereumjs-tx"; // @ts-ignore // TODO: fix ts-ignore import * as ethereumUtil from "ethereumjs-util"; -import * as ethers from "ethers"; +import { arrayify, isBytes } from "ethers/lib/utils.js"; import { isHexString } from "ethjs-util"; import { LedgerTransport } from "./transport"; @@ -189,9 +189,7 @@ export async function ethVerifyMessage(msg: core.ETHVerifyMessage): Promise { const nodeAdapter = await this.nodeAdapter.derivePath(core.addressNListToBIP32(addressNList)); - return ethers.utils.computeAddress(SecP256K1.UncompressedPoint.from(nodeAdapter.getPublicKey())); + return computeAddress(SecP256K1.UncompressedPoint.from(nodeAdapter.getPublicKey())); } - async signDigest(digest: ethers.BytesLike, addressNList: core.BIP32Path): Promise { + async signDigest(digest: BytesLike, addressNList: core.BIP32Path): Promise { const nodeAdapter = await this.nodeAdapter.derivePath(core.addressNListToBIP32(addressNList)); const recoverableSig = await SecP256K1.RecoverableSignature.signCanonically( nodeAdapter.node, null, - digest instanceof Uint8Array ? digest : ethers.utils.arrayify(digest) + digest instanceof Uint8Array ? digest : arrayify(digest) ); const sig = SecP256K1.RecoverableSignature.sig(recoverableSig); const recoveryParam = SecP256K1.RecoverableSignature.recoveryParam(recoverableSig); - return ethers.utils.splitSignature(core.compatibleBufferConcat([sig, Buffer.from([recoveryParam])])); + return splitSignature(core.compatibleBufferConcat([sig, Buffer.from([recoveryParam])])); } async signTransaction( - transaction: ethers.utils.Deferrable, + transaction: Deferrable, addressNList: core.BIP32Path ): Promise { - const tx = await ethers.utils.resolveProperties(transaction); + const tx = await resolveProperties(transaction); if (tx.from != null) { - if (ethers.utils.getAddress(tx.from) !== (await this.getAddress(addressNList))) { + if (getAddress(tx.from) !== (await this.getAddress(addressNList))) { throw new Error("transaction from address mismatch"); } delete tx.from; } - const unsignedTx: ethers.UnsignedTransaction = { + const unsignedTx: UnsignedTransaction = { ...tx, - nonce: tx.nonce !== undefined ? ethers.BigNumber.from(tx.nonce).toNumber() : undefined, + nonce: tx.nonce !== undefined ? BigNumber.from(tx.nonce).toNumber() : undefined, }; const nodeAdapter = await this.nodeAdapter.derivePath(core.addressNListToBIP32(addressNList)); - const txBuf = ethers.utils.arrayify(ethers.utils.serializeTransaction(unsignedTx)); + const txBuf = arrayify(serializeTransaction(unsignedTx)); const rawSig = await SecP256K1.RecoverableSignature.signCanonically(nodeAdapter.node, "keccak256", txBuf); - return ethers.utils.serializeTransaction(unsignedTx, ethSigFromRecoverableSig(rawSig)); + return serializeTransaction(unsignedTx, ethSigFromRecoverableSig(rawSig)); } - async signMessage(messageData: ethers.BytesLike, addressNList: core.BIP32Path): Promise { + async signMessage(messageData: BytesLike, addressNList: core.BIP32Path): Promise { const messageBuf = buildMessage(messageData); const nodeAdapter = await this.nodeAdapter.derivePath(core.addressNListToBIP32(addressNList)); const rawSig = await SecP256K1.RecoverableSignature.signCanonically(nodeAdapter.node, "keccak256", messageBuf); - return ethers.utils.joinSignature(ethSigFromRecoverableSig(rawSig)); + return joinSignature(ethSigFromRecoverableSig(rawSig)); } async signTypedData(typedData: TypedData, addressNList: core.BIP32Path): Promise { @@ -81,7 +91,7 @@ export class SignerAdapter { const messageArray = getMessage(typedData); const nodeAdapter = await this.nodeAdapter.derivePath(core.addressNListToBIP32(addressNList)); const rawSig = await SecP256K1.RecoverableSignature.signCanonically(nodeAdapter.node, "keccak256", messageArray); - const signature = ethers.utils.joinSignature(ethSigFromRecoverableSig(rawSig)); + const signature = joinSignature(ethSigFromRecoverableSig(rawSig)); return { address, signature }; } } diff --git a/packages/hdwallet-native/src/ethereum.test.ts b/packages/hdwallet-native/src/ethereum.test.ts index 224278c6a..b3ce44d88 100644 --- a/packages/hdwallet-native/src/ethereum.test.ts +++ b/packages/hdwallet-native/src/ethereum.test.ts @@ -1,5 +1,5 @@ import * as core from "@shapeshiftoss/hdwallet-core"; -import * as ethers from "ethers"; +import { parseTransaction } from "ethers/lib/utils.js"; import * as native from "./native"; @@ -143,7 +143,7 @@ describe("NativeETHWallet", () => { "v": 38, } `);*/ - expect(ethers.utils.parseTransaction(sig!.serialized).from).toEqual("0x73d0385F4d8E00C5e6504C6030F47BF6212736A8"); + expect(parseTransaction(sig!.serialized).from).toEqual("0x73d0385F4d8E00C5e6504C6030F47BF6212736A8"); }); it("should sign a EIP-1559 transaction correctly", async () => { @@ -177,7 +177,7 @@ describe("NativeETHWallet", () => { "v": 38, } `);*/ - expect(ethers.utils.parseTransaction(sig!.serialized).from).toEqual("0x73d0385F4d8E00C5e6504C6030F47BF6212736A8"); + expect(parseTransaction(sig!.serialized).from).toEqual("0x73d0385F4d8E00C5e6504C6030F47BF6212736A8"); }); describe("sign and verify message", () => { diff --git a/packages/hdwallet-native/src/ethereum.ts b/packages/hdwallet-native/src/ethereum.ts index 3a7d8710e..ff35ea5ff 100644 --- a/packages/hdwallet-native/src/ethereum.ts +++ b/packages/hdwallet-native/src/ethereum.ts @@ -1,5 +1,5 @@ import * as core from "@shapeshiftoss/hdwallet-core"; -import * as ethers from "ethers"; +import { keccak256, parseTransaction, recoverAddress } from "ethers/lib/utils.js"; import * as Isolation from "./crypto/isolation"; import SignerAdapter from "./crypto/isolation/adapters/ethereum"; @@ -111,7 +111,7 @@ export function MixinNativeETHWallet { if (!signature.startsWith("0x")) signature = `0x${signature}`; - const digest = ethers.utils.keccak256(buildMessage(message)); - return ethers.utils.recoverAddress(digest, signature) === address; + const digest = keccak256(buildMessage(message)); + return recoverAddress(digest, signature) === address; } }; } diff --git a/packages/hdwallet-tallyho/src/adapter.ts b/packages/hdwallet-tallyho/src/adapter.ts index d04ba9369..530de6cb6 100644 --- a/packages/hdwallet-tallyho/src/adapter.ts +++ b/packages/hdwallet-tallyho/src/adapter.ts @@ -1,10 +1,10 @@ import * as core from "@shapeshiftoss/hdwallet-core"; -import * as ethers from "ethers"; +import { providers } from "ethers"; import TallyHoOnboarding from "tallyho-onboarding"; import { TallyHoHDWallet } from "./tallyho"; -interface TallyHoEthereumProvider extends ethers.providers.ExternalProvider { +interface TallyHoEthereumProvider extends providers.ExternalProvider { isTally?: boolean; } diff --git a/packages/hdwallet-tallyho/src/ethereum.test.ts b/packages/hdwallet-tallyho/src/ethereum.test.ts index 99d465539..9ccaada1b 100644 --- a/packages/hdwallet-tallyho/src/ethereum.test.ts +++ b/packages/hdwallet-tallyho/src/ethereum.test.ts @@ -1,11 +1,11 @@ import * as core from "@shapeshiftoss/hdwallet-core"; -import * as ethers from "ethers"; +import { providers } from "ethers"; import * as ethereum from "./ethereum"; describe("Tally Ho - Ethereum Adapter", () => { it("ethVerifyMessage returns null as its not implemented", async () => { - const ethereumProvider: ethers.providers.ExternalProvider = { + const ethereumProvider: providers.ExternalProvider = { request: jest.fn().mockReturnValue("0x3f2329C9ADFbcCd9A84f52c906E936A42dA18CB8"), }; expect( @@ -36,7 +36,7 @@ describe("Tally Ho - Ethereum Adapter", () => { expect(paths).toMatchObject([]); }); it("ethSignTx returns null as its not implemented", async () => { - const ethereumProvider: ethers.providers.ExternalProvider = { + const ethereumProvider: providers.ExternalProvider = { request: jest.fn().mockReturnValue({ r: "0x63db3dd3bf3e1fe7dde1969c0fc8850e34116d0b501c0483a0e08c0f77b8ce0a", s: "0x28297d012cccf389f6332415e96ee3fc0bbf8474d05f646e029cd281a031464b", @@ -63,7 +63,7 @@ describe("Tally Ho - Ethereum Adapter", () => { ).toEqual(null); }); it("ethSendTx returns a valid hash", async () => { - const ethereumProvider: ethers.providers.ExternalProvider = { + const ethereumProvider: providers.ExternalProvider = { request: jest.fn().mockReturnValue("0x123"), }; @@ -85,7 +85,7 @@ describe("Tally Ho - Ethereum Adapter", () => { expect(hash).toMatchObject({ hash: "0x123" }); }); it("ethSendTx returns a valid hash if maxFeePerGas is present in msg", async () => { - const ethereumProvider: ethers.providers.ExternalProvider = { + const ethereumProvider: providers.ExternalProvider = { request: jest.fn().mockReturnValue("0x123"), }; @@ -107,7 +107,7 @@ describe("Tally Ho - Ethereum Adapter", () => { expect(hash).toMatchObject({ hash: "0x123" }); }); it("ethSendTx returns null on error", async () => { - const ethereumProvider: ethers.providers.ExternalProvider = { + const ethereumProvider: providers.ExternalProvider = { request: jest.fn().mockRejectedValue(new Error("An Error has occurred")), }; @@ -130,7 +130,7 @@ describe("Tally Ho - Ethereum Adapter", () => { }); it("ethSignMessage returns a valid signature object", async () => { - const ethereumProvider: ethers.providers.ExternalProvider = { + const ethereumProvider: providers.ExternalProvider = { request: jest.fn().mockReturnValue( `Object { "address": "0x73d0385F4d8E00C5e6504C6030F47BF6212736A8", @@ -201,7 +201,7 @@ describe("Tally Ho - Ethereum Adapter", () => { }); it("ethSignMessage returns null on error", async () => { - const ethereumProvider: ethers.providers.ExternalProvider = { + const ethereumProvider: providers.ExternalProvider = { request: jest.fn().mockRejectedValue(new Error("An Error has occurred")), }; @@ -219,7 +219,7 @@ describe("Tally Ho - Ethereum Adapter", () => { }); it("ethGetAddress returns a valid address", async () => { - const ethereumProvider: ethers.providers.ExternalProvider = { + const ethereumProvider: providers.ExternalProvider = { request: jest.fn().mockReturnValue(["0x73d0385F4d8E00C5e6504C6030F47BF6212736A8"]), }; @@ -228,7 +228,7 @@ describe("Tally Ho - Ethereum Adapter", () => { expect(address).toBe("0x73d0385F4d8E00C5e6504C6030F47BF6212736A8"); }); it("ethGetAddress returns null on error", async () => { - const ethereumProvider: ethers.providers.ExternalProvider = { + const ethereumProvider: providers.ExternalProvider = { request: jest.fn().mockRejectedValue(new Error("An error has occurred")), }; diff --git a/packages/hdwallet-xdefi/src/adapter.ts b/packages/hdwallet-xdefi/src/adapter.ts index 61608bd7f..df3d710e4 100644 --- a/packages/hdwallet-xdefi/src/adapter.ts +++ b/packages/hdwallet-xdefi/src/adapter.ts @@ -1,5 +1,5 @@ import * as core from "@shapeshiftoss/hdwallet-core"; -import * as ethers from "ethers"; +import { providers } from "ethers"; import { XDEFIHDWallet } from "./xdefi"; @@ -7,7 +7,7 @@ declare global { // https://stackoverflow.com/questions/59459312/using-globalthis-in-typescript // Global declarations require the use of var // eslint-disable-next-line no-var - var xfi: { ethereum: ethers.providers.ExternalProvider } | null; + var xfi: { ethereum: providers.ExternalProvider } | null; } export class XDEFIAdapter { diff --git a/packages/hdwallet-xdefi/src/ethereum.test.ts b/packages/hdwallet-xdefi/src/ethereum.test.ts index 1643c591f..a615e6e4a 100644 --- a/packages/hdwallet-xdefi/src/ethereum.test.ts +++ b/packages/hdwallet-xdefi/src/ethereum.test.ts @@ -1,11 +1,11 @@ import * as core from "@shapeshiftoss/hdwallet-core"; -import * as ethers from "ethers"; +import { providers } from "ethers"; import * as ethereum from "./ethereum"; describe("XDEFI - Ethereum Adapter", () => { it("ethVerifyMessage returns null as its not implemented", async () => { - const ethereumProvider: ethers.providers.ExternalProvider = { + const ethereumProvider: providers.ExternalProvider = { request: jest.fn().mockReturnValue("0x3f2329C9ADFbcCd9A84f52c906E936A42dA18CB8"), }; expect( @@ -36,7 +36,7 @@ describe("XDEFI - Ethereum Adapter", () => { expect(paths).toMatchObject([]); }); it("ethSignTx returns null as its not implemented", async () => { - const ethereumProvider: ethers.providers.ExternalProvider = { + const ethereumProvider: providers.ExternalProvider = { request: jest.fn().mockReturnValue({ r: "0x63db3dd3bf3e1fe7dde1969c0fc8850e34116d0b501c0483a0e08c0f77b8ce0a", s: "0x28297d012cccf389f6332415e96ee3fc0bbf8474d05f646e029cd281a031464b", @@ -69,7 +69,7 @@ describe("XDEFI - Ethereum Adapter", () => { }); }); it("ethSendTx returns a valid hash", async () => { - const ethereumProvider: ethers.providers.ExternalProvider = { + const ethereumProvider: providers.ExternalProvider = { request: jest.fn().mockReturnValue("0x123"), }; @@ -91,7 +91,7 @@ describe("XDEFI - Ethereum Adapter", () => { expect(hash).toMatchObject({ hash: "0x123" }); }); it("ethSendTx returns a valid hash if maxFeePerGas is present in msg", async () => { - const ethereumProvider: ethers.providers.ExternalProvider = { + const ethereumProvider: providers.ExternalProvider = { request: jest.fn().mockReturnValue("0x123"), }; @@ -114,7 +114,7 @@ describe("XDEFI - Ethereum Adapter", () => { expect(hash).toMatchObject({ hash: "0x123" }); }); it("ethSendTx returns null on error", async () => { - const ethereumProvider: ethers.providers.ExternalProvider = { + const ethereumProvider: providers.ExternalProvider = { request: jest.fn().mockRejectedValue(new Error("An Error has occurred")), }; @@ -179,7 +179,7 @@ describe("XDEFI - Ethereum Adapter", () => { }); it("ethSignMessage returns a valid signature object", async () => { - const ethereumProvider: ethers.providers.ExternalProvider = { + const ethereumProvider: providers.ExternalProvider = { request: jest.fn().mockReturnValue( `Object { "address": "0x73d0385F4d8E00C5e6504C6030F47BF6212736A8", @@ -210,7 +210,7 @@ describe("XDEFI - Ethereum Adapter", () => { }); it("ethSignMessage returns null on error", async () => { - const ethereumProvider: ethers.providers.ExternalProvider = { + const ethereumProvider: providers.ExternalProvider = { request: jest.fn().mockRejectedValue(new Error("An Error has occurred")), }; @@ -228,7 +228,7 @@ describe("XDEFI - Ethereum Adapter", () => { }); it("ethGetAddress returns a valid address", async () => { - const ethereumProvider: ethers.providers.ExternalProvider = { + const ethereumProvider: providers.ExternalProvider = { request: jest.fn().mockReturnValue(["0x73d0385F4d8E00C5e6504C6030F47BF6212736A8"]), }; @@ -237,7 +237,7 @@ describe("XDEFI - Ethereum Adapter", () => { expect(address).toBe("0x73d0385F4d8E00C5e6504C6030F47BF6212736A8"); }); it("ethGetAddress returns null on error", async () => { - const ethereumProvider: ethers.providers.ExternalProvider = { + const ethereumProvider: providers.ExternalProvider = { request: jest.fn().mockRejectedValue(new Error("An error has occurred")), }; @@ -246,7 +246,7 @@ describe("XDEFI - Ethereum Adapter", () => { expect(address).toBe(null); }); it("ethGetAddress returns null if no provider", async () => { - const ethereumProvider: ethers.providers.ExternalProvider = {}; + const ethereumProvider: providers.ExternalProvider = {}; const address = await ethereum.ethGetAddress(ethereumProvider);