diff --git a/packages/keyring-eth-hd/jest.config.js b/packages/keyring-eth-hd/jest.config.js index a8cb232da..e5d1182c4 100644 --- a/packages/keyring-eth-hd/jest.config.js +++ b/packages/keyring-eth-hd/jest.config.js @@ -26,7 +26,7 @@ module.exports = merge(baseConfig, { branches: 83.87, functions: 100, lines: 95, - statements: 97.93, + statements: 97.91, }, }, }); diff --git a/packages/keyring-eth-hd/package.json b/packages/keyring-eth-hd/package.json index fb7bb0714..8af3805f0 100644 --- a/packages/keyring-eth-hd/package.json +++ b/packages/keyring-eth-hd/package.json @@ -43,7 +43,7 @@ "test:clean": "jest --clearCache" }, "dependencies": { - "@ethereumjs/util": "^8.1.0", + "@ethereumjs/util": "^9.1.0", "@metamask/eth-sig-util": "^8.2.0", "@metamask/key-tree": "^10.0.2", "@metamask/scure-bip39": "^2.1.1", @@ -51,7 +51,7 @@ "ethereum-cryptography": "^2.1.2" }, "devDependencies": { - "@ethereumjs/tx": "^4.2.0", + "@ethereumjs/tx": "^5.4.0", "@lavamoat/allow-scripts": "^3.2.1", "@lavamoat/preinstall-always-fail": "^2.1.0", "@metamask/auto-changelog": "^3.4.4", diff --git a/packages/keyring-eth-hd/src/hd-keyring.test.ts b/packages/keyring-eth-hd/src/hd-keyring.test.ts index 653357803..dc3d185b0 100644 --- a/packages/keyring-eth-hd/src/hd-keyring.test.ts +++ b/packages/keyring-eth-hd/src/hd-keyring.test.ts @@ -1,11 +1,9 @@ -import { TransactionFactory, Transaction as EthereumTx } from '@ethereumjs/tx'; import { - isValidAddress, - bufferToHex, - toBuffer, - ecrecover, - pubToAddress, -} from '@ethereumjs/util'; + TransactionFactory, + LegacyTransaction, + type TypedTxData, +} from '@ethereumjs/tx'; +import { isValidAddress, ecrecover, pubToAddress } from '@ethereumjs/util'; import * as oldMMForkBIP39 from '@metamask/bip39'; import { normalize, @@ -22,7 +20,7 @@ import { type EIP7702Authorization, } from '@metamask/eth-sig-util'; import { wordlist } from '@metamask/scure-bip39/dist/wordlists/english'; -import { assert, type Hex } from '@metamask/utils'; +import { assert, bytesToHex, hexToBytes, type Hex } from '@metamask/utils'; import { webcrypto } from 'crypto'; import { keccak256 } from 'ethereum-cryptography/keccak'; // eslint-disable-next-line @typescript-eslint/naming-convention @@ -642,7 +640,7 @@ describe('hd-keyring', () => { numberOfAccounts: 1, }); const localMessage = 'hello there!'; - const msgHashHex = bufferToHex( + const msgHashHex = bytesToHex( Buffer.from(keccak256(Buffer.from(localMessage))), ); await keyring.addAccounts(9); @@ -655,12 +653,12 @@ describe('hd-keyring', () => { signatures.forEach((sgn, index) => { const accountAddress = addresses[index]; - const signatureR = toBuffer(sgn.slice(0, 66)); - const signatureS = toBuffer(`0x${sgn.slice(66, 130)}`); + const signatureR = hexToBytes(sgn.slice(0, 66)); + const signatureS = hexToBytes(`0x${sgn.slice(66, 130)}`); const signatureV = BigInt(`0x${sgn.slice(130, 132)}`); - const messageHash = toBuffer(msgHashHex); + const messageHash = hexToBytes(msgHashHex); const pub = ecrecover(messageHash, signatureV, signatureR, signatureS); - const adr = `0x${pubToAddress(pub).toString('hex')}`; + const adr = bytesToHex(pubToAddress(pub)); expect(adr).toBe(accountAddress); }); @@ -1055,8 +1053,7 @@ describe('hd-keyring', () => { }); }); - const txParams = { - from: firstAcct, + const txParams: TypedTxData = { nonce: '0x00', gasPrice: '0x09184e72a000', gasLimit: '0x2710', @@ -1065,7 +1062,7 @@ describe('hd-keyring', () => { }; it('returns a signed legacy tx object', async function () { - const tx = new EthereumTx(txParams); + const tx = LegacyTransaction.fromTxData(txParams); expect(tx.isSigned()).toBe(false); const signed = await keyring.signTransaction(firstAcct, tx); diff --git a/packages/keyring-eth-hd/src/hd-keyring.ts b/packages/keyring-eth-hd/src/hd-keyring.ts index 0b2d46056..8511e9a83 100644 --- a/packages/keyring-eth-hd/src/hd-keyring.ts +++ b/packages/keyring-eth-hd/src/hd-keyring.ts @@ -1,11 +1,5 @@ import type { TypedTransaction } from '@ethereumjs/tx'; -import { - privateToPublic, - publicToAddress, - ecsign, - arrToBufArr, - bufferToHex, -} from '@ethereumjs/util'; +import { privateToPublic, publicToAddress, ecsign } from '@ethereumjs/util'; import { concatSig, decrypt, @@ -31,12 +25,13 @@ import { add0x, assert, assertIsHexString, + bigIntToBytes, + bytesToHex, type Hex, remove0x, } from '@metamask/utils'; import { HDKey } from 'ethereum-cryptography/hdkey'; import { keccak256 } from 'ethereum-cryptography/keccak'; -import { bytesToHex } from 'ethereum-cryptography/utils'; // Options: const hdPathString = `m/44'/60'/0'/0`; @@ -227,7 +222,7 @@ export class HdKeyring { }); assert(wallet.publicKey, 'Expected public key to be set'); const appKeyAddress = this.#normalizeAddress( - publicToAddress(wallet.publicKey).toString('hex'), + bytesToHex(publicToAddress(wallet.publicKey)), ); return appKeyAddress; } @@ -253,7 +248,7 @@ export class HdKeyring { privateKey instanceof Uint8Array, 'Expected private key to be of type Uint8Array', ); - return bytesToHex(privateKey); + return remove0x(bytesToHex(privateKey)); } /** @@ -293,10 +288,9 @@ export class HdKeyring { const privKey = this.#getPrivateKeyFor(address, opts); const msgSig = ecsign(Buffer.from(message, 'hex'), Buffer.from(privKey)); const rawMsgSig = concatSig( - // WARN: verify this cast to Buffer - msgSig.v as unknown as Buffer, - msgSig.r, - msgSig.s, + Buffer.from(bigIntToBytes(msgSig.v)), + Buffer.from(msgSig.r), + Buffer.from(msgSig.s), ); return rawMsgSig; } @@ -425,7 +419,7 @@ export class HdKeyring { opts: HDKeyringAccountSelectionOptions = {}, ): Promise { const privKey = this.#getPrivateKeyFor(withAccount, opts); - const publicKey = getEncryptionPublicKey(bytesToHex(privKey)); + const publicKey = getEncryptionPublicKey(remove0x(bytesToHex(privKey))); return publicKey; } @@ -567,8 +561,8 @@ export class HdKeyring { assert(privateKey, 'Expected private key to be set'); const appKeyOriginBuffer = Buffer.from(withAppKeyOrigin, 'utf8'); const appKeyBuffer = Buffer.concat([privateKey, appKeyOriginBuffer]); - const appKeyPrivateKey = arrToBufArr(keccak256(appKeyBuffer)); - const appKeyPublicKey = privateToPublic(appKeyPrivateKey); + const appKeyPrivateKey = Buffer.from(keccak256(appKeyBuffer)); + const appKeyPublicKey = Buffer.from(privateToPublic(appKeyPrivateKey)); return { privateKey: appKeyPrivateKey, publicKey: appKeyPublicKey }; } @@ -611,7 +605,7 @@ export class HdKeyring { */ #addressfromPublicKey(publicKey: Uint8Array): Hex { return add0x( - bufferToHex(publicToAddress(Buffer.from(publicKey), true)).toLowerCase(), + bytesToHex(publicToAddress(Buffer.from(publicKey), true)).toLowerCase(), ); } diff --git a/packages/keyring-eth-ledger-bridge/package.json b/packages/keyring-eth-ledger-bridge/package.json index 3fd5c1916..7bdb67f6d 100644 --- a/packages/keyring-eth-ledger-bridge/package.json +++ b/packages/keyring-eth-ledger-bridge/package.json @@ -47,14 +47,14 @@ }, "dependencies": { "@ethereumjs/rlp": "^5.0.2", - "@ethereumjs/tx": "^4.2.0", - "@ethereumjs/util": "^8.1.0", + "@ethereumjs/tx": "^5.4.0", + "@ethereumjs/util": "^9.1.0", "@ledgerhq/hw-app-eth": "^6.42.0", "@metamask/eth-sig-util": "^8.2.0", "hdkey": "^2.1.0" }, "devDependencies": { - "@ethereumjs/common": "^3.2.0", + "@ethereumjs/common": "^4.4.0", "@lavamoat/allow-scripts": "^3.2.1", "@lavamoat/preinstall-always-fail": "^2.1.0", "@ledgerhq/hw-transport": "^6.31.3", diff --git a/packages/keyring-eth-ledger-bridge/src/ledger-keyring.test.ts b/packages/keyring-eth-ledger-bridge/src/ledger-keyring.test.ts index 0297a89be..18e8fbacd 100644 --- a/packages/keyring-eth-ledger-bridge/src/ledger-keyring.test.ts +++ b/packages/keyring-eth-ledger-bridge/src/ledger-keyring.test.ts @@ -3,7 +3,7 @@ import { RLP } from '@ethereumjs/rlp'; import { TransactionFactory } from '@ethereumjs/tx'; import * as ethUtil from '@ethereumjs/util'; import * as sigUtil from '@metamask/eth-sig-util'; -import { Hex } from '@metamask/utils'; +import { bytesToHex, Hex } from '@metamask/utils'; import EthereumTx from 'ethereumjs-tx'; import HDKey from 'hdkey'; @@ -49,7 +49,7 @@ const fakeTx = new EthereumTx({ value: '0x00', data: '0x7f7465737432000000000000000000000000000000000000000000000000000000600057', // EIP 155 chainId - mainnet: 1, ropsten: 3 - chainId: 1, + chainId: '0x1', }); const common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Berlin }); @@ -646,7 +646,7 @@ describe('LedgerKeyring', function () { v: '0x26', r: '0xf3a7718999d1b87beda810b25cc025153e74df0745279826b9b2f3d1d1b6318', s: '0x7e33bdfbf5272dc4f55649e9ba729849670171a68ef8c0fbeed3b879b90b8954', - }; + } as const; await basicSetupToUnlockOneAccount(); @@ -672,7 +672,7 @@ describe('LedgerKeyring', function () { expect(params).toStrictEqual({ hdPath: "m/44'/60'/0'/0", tx: Buffer.from( - RLP.encode(newFakeTx.getMessageToSign(false)), + RLP.encode(newFakeTx.getMessageToSign()), ).toString('hex'), }); return expectedRSV; @@ -694,7 +694,7 @@ describe('LedgerKeyring', function () { v: '0x0', r: '0x5ffb3adeaec80e430e7a7b02d95c5108b6f09a0bdf3cf69869dc1b38d0fb8d3a', s: '0x28b234a5403d31564e18258df84c51a62683e3f54fa2b106fdc1a9058006a112', - }; + } as const; await basicSetupToUnlockOneAccount(); @@ -719,7 +719,7 @@ describe('LedgerKeyring', function () { .mockImplementation(async (params) => { expect(params).toStrictEqual({ hdPath: "m/44'/60'/0'/0", - tx: fakeTypeTwoTx.getMessageToSign(false).toString('hex'), + tx: bytesToHex(fakeTypeTwoTx.getMessageToSign() as Uint8Array), }); return expectedRSV; }); diff --git a/packages/keyring-eth-ledger-bridge/src/ledger-keyring.ts b/packages/keyring-eth-ledger-bridge/src/ledger-keyring.ts index 4155a3843..ab123efdb 100644 --- a/packages/keyring-eth-ledger-bridge/src/ledger-keyring.ts +++ b/packages/keyring-eth-ledger-bridge/src/ledger-keyring.ts @@ -1,6 +1,10 @@ import { RLP } from '@ethereumjs/rlp'; -import { TransactionFactory, TxData, TypedTransaction } from '@ethereumjs/tx'; -import { bufferToHex, publicToAddress } from '@ethereumjs/util'; +import { + TransactionFactory, + TypedTxData, + type TypedTransaction, +} from '@ethereumjs/tx'; +import { publicToAddress } from '@ethereumjs/util'; import type { MessageTypes, TypedMessage } from '@metamask/eth-sig-util'; import { recoverPersonalSignature, @@ -9,7 +13,13 @@ import { TypedDataUtils, } from '@metamask/eth-sig-util'; import type { Keyring } from '@metamask/keyring-utils'; -import { add0x, getChecksumAddress, Hex, remove0x } from '@metamask/utils'; +import { + add0x, + bytesToHex, + getChecksumAddress, + Hex, + remove0x, +} from '@metamask/utils'; import { Buffer } from 'buffer'; import type OldEthJsTransaction from 'ethereumjs-tx'; import HDKey from 'hdkey'; @@ -216,7 +226,7 @@ export class LedgerKeyring implements Keyring { // we return the checksummed address of the public key stored in // `this.hdk`, which is the root address of the last unlocked path. return this.#getChecksumHexAddress( - publicToAddress(this.hdk.publicKey, true).toString('hex'), + bytesToHex(publicToAddress(this.hdk.publicKey, true)), ); } const path = hdPath ? this.#toLedgerPath(hdPath) : this.hdPath; @@ -333,8 +343,7 @@ export class LedgerKeyring implements Keyring { // transaction which is only communicated to ethereumjs-tx in this // value. In newer versions the chainId is communicated via the 'Common' // object. - // @ts-expect-error tx.v should be a Buffer, but we are assigning a string - tx.v = bufferToHex(tx.getChainId()); + tx.v = tx.getChainId(); // @ts-expect-error tx.r should be a Buffer, but we are assigning a string tx.r = '0x00'; // @ts-expect-error tx.s should be a Buffer, but we are assigning a string @@ -358,17 +367,17 @@ export class LedgerKeyring implements Keyring { // Note also that `getMessageToSign` will return valid RLP for all transaction types, whereas the // `serialize` method will not for any transaction type except legacy. This is because `serialize` includes // empty r, s and v values in the encoded rlp. This is why we use `getMessageToSign` here instead of `serialize`. - const messageToSign = tx.getMessageToSign(false); + const messageToSign = tx.getMessageToSign(); - rawTxHex = Buffer.isBuffer(messageToSign) - ? messageToSign.toString('hex') - : Buffer.from(RLP.encode(messageToSign)).toString('hex'); + rawTxHex = Array.isArray(messageToSign) + ? Buffer.from(RLP.encode(messageToSign)).toString('hex') + : bytesToHex(messageToSign); return this.#signTransaction(address, rawTxHex, (payload) => { // Because tx will be immutable, first get a plain javascript object that // represents the transaction. Using txData here as it aligns with the // nomenclature of ethereumjs/tx. - const txData: TxData = tx.toJSON(); + const txData: TypedTxData = tx.toJSON(); // The fromTxData utility expects a type to support transactions with a type other than 0 txData.type = tx.type; // The fromTxData utility expects v,r and s to be hex prefixed @@ -632,8 +641,8 @@ export class LedgerKeyring implements Keyring { #addressFromIndex(basePath: string, i: number): Hex { const dkey = this.hdk.derive(`${basePath}/${i}`); - const address = publicToAddress(dkey.publicKey, true).toString('hex'); - return this.#getChecksumHexAddress(add0x(address)); + const address = bytesToHex(publicToAddress(dkey.publicKey, true)); + return this.#getChecksumHexAddress(address); } #pathFromAddress(address: string): string { diff --git a/packages/keyring-eth-simple/package.json b/packages/keyring-eth-simple/package.json index 80af4beec..d2218450f 100644 --- a/packages/keyring-eth-simple/package.json +++ b/packages/keyring-eth-simple/package.json @@ -44,14 +44,14 @@ "test:watch": "jest --watch" }, "dependencies": { - "@ethereumjs/util": "^8.1.0", + "@ethereumjs/util": "^9.1.0", "@metamask/eth-sig-util": "^8.2.0", "@metamask/utils": "^11.1.0", "ethereum-cryptography": "^2.1.2", "randombytes": "^2.1.0" }, "devDependencies": { - "@ethereumjs/tx": "^4.2.0", + "@ethereumjs/tx": "^5.4.0", "@lavamoat/allow-scripts": "^3.2.1", "@lavamoat/preinstall-always-fail": "^2.1.0", "@metamask/auto-changelog": "^3.4.4", diff --git a/packages/keyring-eth-simple/src/simple-keyring.test.ts b/packages/keyring-eth-simple/src/simple-keyring.test.ts index 6a35b429e..3eaab107f 100644 --- a/packages/keyring-eth-simple/src/simple-keyring.test.ts +++ b/packages/keyring-eth-simple/src/simple-keyring.test.ts @@ -1,12 +1,14 @@ -import { Transaction as EthereumTx, TransactionFactory } from '@ethereumjs/tx'; import { - bufferToHex, + LegacyTransaction, + TransactionFactory, + TypedTxData, +} from '@ethereumjs/tx'; +import { ecrecover, isValidAddress, privateToAddress, pubToAddress, stripHexPrefix, - toBuffer, } from '@ethereumjs/util'; import { EIP7702Authorization, @@ -21,7 +23,7 @@ import { SignTypedDataVersion, TypedMessage, } from '@metamask/eth-sig-util'; -import { add0x, Hex } from '@metamask/utils'; +import { add0x, bytesToHex, Hex, hexToBytes } from '@metamask/utils'; import assert from 'assert'; import { keccak256 } from 'ethereum-cryptography/keccak'; // eslint-disable-next-line @typescript-eslint/naming-convention @@ -101,8 +103,7 @@ describe('simple-keyring', function () { const address = '0x9858e7d8b79fc3e6d989636721584498926da38a'; const privateKey = '0x7dd98753d7b4394095de7d176c58128e2ed6ee600abe97c9f6d9fd65015d9b18'; - const txParams = { - from: address, + const txParams: TypedTxData = { nonce: '0x00', gasPrice: '0x09184e72a000', gasLimit: '0x2710', @@ -112,7 +113,7 @@ describe('simple-keyring', function () { it('returns a signed legacy tx object (using @ethereumjs/tx)', async function () { await keyring.deserialize([privateKey]); - const tx = new EthereumTx(txParams); + const tx = LegacyTransaction.fromTxData(txParams); expect(tx.isSigned()).toBe(false); const signed = await keyring.signTransaction(address, tx); @@ -177,9 +178,7 @@ describe('simple-keyring', function () { it('reliably can decode messages it signs', async function () { await keyring.deserialize([privateKey]); const localMessage = 'hello there!'; - const msgHashHex = bufferToHex( - Buffer.from(keccak256(Buffer.from(localMessage))), - ); + const msgHashHex = bytesToHex(keccak256(Buffer.from(localMessage))); await keyring.addAccounts(9); const addresses = await keyring.getAccounts(); @@ -192,14 +191,14 @@ describe('simple-keyring', function () { const accountAddress = addresses[index]; /* eslint-disable id-length */ - const r = toBuffer(sgn.slice(0, 66)); - const s = toBuffer(`0x${sgn.slice(66, 130)}`); + const r = hexToBytes(sgn.slice(0, 66)); + const s = hexToBytes(`0x${sgn.slice(66, 130)}`); const v = BigInt(`0x${sgn.slice(130, 132)}`); - const m = toBuffer(msgHashHex); + const m = hexToBytes(msgHashHex); /* eslint-enable id-length */ const pub = ecrecover(m, v, r, s); - const adr = `0x${pubToAddress(pub).toString('hex')}`; + const adr = bytesToHex(pubToAddress(pub)); expect(adr).toBe(accountAddress); }); @@ -296,7 +295,7 @@ describe('simple-keyring', function () { '6969696969696969696969696969696969696969696969696969696969696969', 'hex', ); - const privKeyHex = bufferToHex(privateKey); + const privKeyHex = bytesToHex(privateKey); const message = '0x68656c6c6f20776f726c64'; const expectedSignature = '0xce909e8ea6851bc36c007a0072d0524b07a3ff8d4e623aca4c71ca8e57250c4d0a3fc38fa8fbaaa81ead4b9f6bd03356b6f8bf18bccad167d78891636e1d69561b'; @@ -550,9 +549,7 @@ describe('simple-keyring', function () { const address = '0x29c76e6ad8f28bb1004902578fb108c507be341b'; const privKeyHex = '0x4af1bceebf7f3634ec3cff8a2c38e51178d5d4ce585c52d6043e5e2cc3418bb0'; - const signerAddress = `0x${privateToAddress( - Buffer.from(privKeyHex.slice(2), 'hex'), - ).toString('hex')}`; + const signerAddress = bytesToHex(privateToAddress(hexToBytes(privKeyHex))); const chainId = 1; const nonce = 1; @@ -593,14 +590,11 @@ describe('simple-keyring', function () { describe('#decryptMessage', function () { const address = '0xbe93f9bacbcffc8ee6663f2647917ed7a20a57bb'; - const privateKey = Buffer.from( - '6969696969696969696969696969696969696969696969696969696969696969', - 'hex', - ); - const privKeyHex = bufferToHex(privateKey); + const privKeyHex = + '6969696969696969696969696969696969696969696969696969696969696969'; const message = 'Hello world!'; const encryptedMessage = encrypt({ - publicKey: getEncryptionPublicKey(privateKey.toString('hex')), + publicKey: getEncryptionPublicKey(privKeyHex), data: message, version: 'x25519-xsalsa20-poly1305', }); @@ -633,12 +627,9 @@ describe('simple-keyring', function () { describe('#encryptionPublicKey', function () { const address = '0xbe93f9bacbcffc8ee6663f2647917ed7a20a57bb'; - const privateKey = Buffer.from( - '6969696969696969696969696969696969696969696969696969696969696969', - 'hex', - ); + const privKeyHex = + '0x6969696969696969696969696969696969696969696969696969696969696969'; const publicKey = 'GxuMqoE2oHsZzcQtv/WMNB3gCH2P6uzynuwO1P0MM1U='; - const privKeyHex = bufferToHex(privateKey); it('returns the expected value', async function () { await keyring.deserialize([privKeyHex]); diff --git a/packages/keyring-eth-simple/src/simple-keyring.ts b/packages/keyring-eth-simple/src/simple-keyring.ts index 8b7410bdc..ff0ee7b6b 100644 --- a/packages/keyring-eth-simple/src/simple-keyring.ts +++ b/packages/keyring-eth-simple/src/simple-keyring.ts @@ -1,13 +1,10 @@ import { TypedTransaction } from '@ethereumjs/tx'; import { - arrToBufArr, - bufferToHex, ecsign, isValidPrivate, privateToPublic, publicToAddress, stripHexPrefix, - toBuffer, } from '@ethereumjs/util'; import { concatSig, @@ -21,7 +18,13 @@ import { SignTypedDataVersion, } from '@metamask/eth-sig-util'; import { Keyring } from '@metamask/keyring-utils'; -import { add0x, Eip1024EncryptedData, Hex } from '@metamask/utils'; +import { + add0x, + bigIntToBytes, + bytesToHex, + Eip1024EncryptedData, + Hex, +} from '@metamask/utils'; import { keccak256 } from 'ethereum-cryptography/keccak'; import randombytes from 'randombytes'; @@ -63,7 +66,7 @@ export default class SimpleKeyring implements Keyring { this.#wallets = privateKeys.map((hexPrivateKey) => { const strippedHexPrivateKey = stripHexPrefix(hexPrivateKey); const privateKey = Buffer.from(strippedHexPrivateKey, 'hex'); - const publicKey = privateToPublic(privateKey); + const publicKey = Buffer.from(privateToPublic(privateKey)); return { privateKey, publicKey }; }); } @@ -72,19 +75,19 @@ export default class SimpleKeyring implements Keyring { const newWallets = []; for (let i = 0; i < numAccounts; i++) { const privateKey = generateKey(); - const publicKey = privateToPublic(privateKey); + const publicKey = Buffer.from(privateToPublic(privateKey)); newWallets.push({ privateKey, publicKey }); } this.#wallets = this.#wallets.concat(newWallets); const hexWallets = newWallets.map(({ publicKey }) => - add0x(bufferToHex(publicToAddress(publicKey))), + add0x(bytesToHex(publicToAddress(publicKey))), ); return hexWallets; } async getAccounts(): Promise { return this.#wallets.map(({ publicKey }) => - add0x(bufferToHex(publicToAddress(publicKey))), + add0x(bytesToHex(publicToAddress(publicKey))), ); } @@ -123,7 +126,11 @@ export default class SimpleKeyring implements Keyring { } const privKey = this.#getPrivateKeyFor(address, opts); const msgSig = ecsign(Buffer.from(message, 'hex'), privKey); - const rawMsgSig = concatSig(toBuffer(msgSig.v), msgSig.r, msgSig.s); + const rawMsgSig = concatSig( + Buffer.from(bigIntToBytes(msgSig.v)), + Buffer.from(msgSig.r), + Buffer.from(msgSig.s), + ); return rawMsgSig; } @@ -193,7 +200,7 @@ export default class SimpleKeyring implements Keyring { const wallet = this.#getWalletForAccount(address, { withAppKeyOrigin: origin, }); - const appKeyAddress = add0x(bufferToHex(publicToAddress(wallet.publicKey))); + const appKeyAddress = add0x(bytesToHex(publicToAddress(wallet.publicKey))); return appKeyAddress; } @@ -210,7 +217,7 @@ export default class SimpleKeyring implements Keyring { if ( !this.#wallets .map(({ publicKey }) => - bufferToHex(publicToAddress(publicKey)).toLowerCase(), + bytesToHex(publicToAddress(publicKey)).toLowerCase(), ) .includes(address.toLowerCase()) ) { @@ -219,7 +226,7 @@ export default class SimpleKeyring implements Keyring { this.#wallets = this.#wallets.filter( ({ publicKey }) => - bufferToHex(publicToAddress(publicKey)).toLowerCase() !== + bytesToHex(publicToAddress(publicKey)).toLowerCase() !== address.toLowerCase(), ); } @@ -230,7 +237,7 @@ export default class SimpleKeyring implements Keyring { ): Wallet { const address = normalize(account); let wallet = this.#wallets.find( - ({ publicKey }) => bufferToHex(publicToAddress(publicKey)) === address, + ({ publicKey }) => bytesToHex(publicToAddress(publicKey)) === address, ); if (!wallet) { throw new Error('Simple Keyring - Unable to find matching address.'); @@ -240,9 +247,12 @@ export default class SimpleKeyring implements Keyring { const { privateKey } = wallet; const appKeyOriginBuffer = Buffer.from(opts.withAppKeyOrigin, 'utf8'); const appKeyBuffer = Buffer.concat([privateKey, appKeyOriginBuffer]); - const appKeyPrivateKey = arrToBufArr(keccak256(appKeyBuffer)); + const appKeyPrivateKey = keccak256(appKeyBuffer); const appKeyPublicKey = privateToPublic(appKeyPrivateKey); - wallet = { privateKey: appKeyPrivateKey, publicKey: appKeyPublicKey }; + wallet = { + privateKey: Buffer.from(appKeyPrivateKey), + publicKey: Buffer.from(appKeyPublicKey), + }; } return wallet; diff --git a/packages/keyring-eth-trezor/jest.config.js b/packages/keyring-eth-trezor/jest.config.js index c7c45a072..34ecf6872 100644 --- a/packages/keyring-eth-trezor/jest.config.js +++ b/packages/keyring-eth-trezor/jest.config.js @@ -23,7 +23,7 @@ module.exports = merge(baseConfig, { // An object that configures minimum threshold enforcement for coverage results coverageThreshold: { global: { - branches: 48.24, + branches: 51.63, functions: 91.22, lines: 90.1, statements: 90.3, diff --git a/packages/keyring-eth-trezor/package.json b/packages/keyring-eth-trezor/package.json index 186dedd2a..b49083765 100644 --- a/packages/keyring-eth-trezor/package.json +++ b/packages/keyring-eth-trezor/package.json @@ -46,8 +46,8 @@ "test:watch": "jest --watch" }, "dependencies": { - "@ethereumjs/tx": "^4.2.0", - "@ethereumjs/util": "^8.1.0", + "@ethereumjs/tx": "^5.4.0", + "@ethereumjs/util": "^9.1.0", "@metamask/eth-sig-util": "^8.2.0", "@metamask/utils": "^11.1.0", "@trezor/connect-plugin-ethereum": "^9.0.3", @@ -56,7 +56,7 @@ "tslib": "^2.6.2" }, "devDependencies": { - "@ethereumjs/common": "^3.2.0", + "@ethereumjs/common": "^4.4.0", "@lavamoat/allow-scripts": "^3.2.1", "@lavamoat/preinstall-always-fail": "^2.1.0", "@metamask/auto-changelog": "^3.4.4", diff --git a/packages/keyring-eth-trezor/src/trezor-keyring.test.ts b/packages/keyring-eth-trezor/src/trezor-keyring.test.ts index ca8120dca..2747b5079 100644 --- a/packages/keyring-eth-trezor/src/trezor-keyring.test.ts +++ b/packages/keyring-eth-trezor/src/trezor-keyring.test.ts @@ -412,7 +412,9 @@ describe('TrezorKeyring', function () { sinon.stub(fakeTx, 'verifySignature').callsFake(() => true); sinon .stub(fakeTx, 'getSenderAddress') - .callsFake(() => Address.fromString(fakeAccounts[0]).toBuffer()); + .callsFake(() => + Buffer.from(Address.fromString(fakeAccounts[0]).bytes), + ); const returnedTx = await keyring.signTransaction(fakeAccounts[0], fakeTx); // assert that the v,r,s values got assigned to tx. @@ -533,6 +535,7 @@ describe('TrezorKeyring', function () { sinon.assert.calledWithExactly(ethereumSignTransactionStub, { path: "m/44'/60'/0'/0/0", transaction: { + type: '0x2', chainId: 1, nonce: '0x0', maxPriorityFeePerGas: '0x9184e72a000', diff --git a/packages/keyring-eth-trezor/src/trezor-keyring.ts b/packages/keyring-eth-trezor/src/trezor-keyring.ts index 203864c1c..7d1fe5dfd 100644 --- a/packages/keyring-eth-trezor/src/trezor-keyring.ts +++ b/packages/keyring-eth-trezor/src/trezor-keyring.ts @@ -1,13 +1,19 @@ import { TransactionFactory } from '@ethereumjs/tx'; -import type { TypedTransaction, TxData } from '@ethereumjs/tx'; -import { bufferToHex, publicToAddress, toBuffer } from '@ethereumjs/util'; +import type { TypedTransaction, TypedTxData } from '@ethereumjs/tx'; +import { publicToAddress, toChecksumAddress } from '@ethereumjs/util'; import { TypedMessage, SignTypedDataVersion, MessageTypes, } from '@metamask/eth-sig-util'; import type { Keyring } from '@metamask/keyring-utils'; -import { add0x, getChecksumAddress, Hex, remove0x } from '@metamask/utils'; +import { + add0x, + bytesToHex, + getChecksumAddress, + Hex, + remove0x, +} from '@metamask/utils'; import { transformTypedData } from '@trezor/connect-plugin-ethereum'; import type { EthereumTransactionEIP1559, @@ -317,7 +323,7 @@ export class TrezorKeyring implements Keyring { // Because tx will be immutable, first get a plain javascript object that // represents the transaction. Using txData here as it aligns with the // nomenclature of ethereumjs/tx. - const txData: TxData = tx.toJSON(); + const txData: TypedTxData = tx.toJSON(); // The fromTxData utility expects a type to support transactions with a type other than 0 txData.type = tx.type; // The fromTxData utility expects v,r and s to be hex prefixed @@ -369,7 +375,7 @@ export class TrezorKeyring implements Keyring { transaction = { ...tx.toJSON(), chainId, - to: this.#normalize(toBuffer(tx.to)), + to: this.#normalize(Buffer.from(tx.to?.bytes ?? [])), } as EthereumTransaction | EthereumTransactionEIP1559; } @@ -542,13 +548,13 @@ export class TrezorKeyring implements Keyring { } #normalize(buf: Buffer): string { - return bufferToHex(buf).toString(); + return bytesToHex(buf); } #addressFromIndex(basePath: string, i: number): Hex { const dkey = this.hdk.derive(`${basePath}/${i}`); - const address = publicToAddress(dkey.publicKey, true).toString('hex'); - return getChecksumAddress(add0x(address)); + const address = bytesToHex(publicToAddress(dkey.publicKey, true)); + return toChecksumAddress(address); } #pathFromAddress(address: Hex): string { diff --git a/packages/keyring-snap-bridge/package.json b/packages/keyring-snap-bridge/package.json index e14ece275..1dd0a5581 100644 --- a/packages/keyring-snap-bridge/package.json +++ b/packages/keyring-snap-bridge/package.json @@ -37,7 +37,7 @@ "test:watch": "jest --watch" }, "dependencies": { - "@ethereumjs/tx": "^4.2.0", + "@ethereumjs/tx": "^5.4.0", "@metamask/base-controller": "^7.1.1", "@metamask/eth-sig-util": "^8.2.0", "@metamask/keyring-api": "workspace:^", diff --git a/packages/keyring-snap-bridge/src/SnapKeyring.test.ts b/packages/keyring-snap-bridge/src/SnapKeyring.test.ts index 1f430fcf9..dad31de48 100644 --- a/packages/keyring-snap-bridge/src/SnapKeyring.test.ts +++ b/packages/keyring-snap-bridge/src/SnapKeyring.test.ts @@ -1,4 +1,4 @@ -import { TransactionFactory } from '@ethereumjs/tx'; +import { TransactionFactory, type TypedTxData } from '@ethereumjs/tx'; import { Messenger } from '@metamask/base-controller'; import { SignTypedDataVersion } from '@metamask/eth-sig-util'; import type { @@ -838,7 +838,7 @@ describe('SnapKeyring', () => { expect(keyring.listAccounts()[0]?.methods).toStrictEqual( updatedMethods, ); - const mockTx = { + const mockTx: TypedTxData = { data: '0x0', gasLimit: '0x26259fe', gasPrice: '0x1', @@ -1343,7 +1343,7 @@ describe('SnapKeyring', () => { describe('signTransaction', () => { it('signs a ethereum transaction synchronously', async () => { - const mockTx = { + const mockTx: TypedTxData = { data: '0x00', gasLimit: '0x26259fe', gasPrice: '0x1', @@ -1353,7 +1353,7 @@ describe('SnapKeyring', () => { chainId: '0x1', type: '0x0', }; - const mockSignedTx = { + const mockSignedTx: TypedTxData = { ...mockTx, r: '0x0', s: '0x0', diff --git a/packages/keyring-snap-bridge/src/SnapKeyring.ts b/packages/keyring-snap-bridge/src/SnapKeyring.ts index dcf652956..aafff6da9 100644 --- a/packages/keyring-snap-bridge/src/SnapKeyring.ts +++ b/packages/keyring-snap-bridge/src/SnapKeyring.ts @@ -36,7 +36,7 @@ import { strictMask } from '@metamask/keyring-utils'; import type { SnapId } from '@metamask/snaps-sdk'; import { type Snap } from '@metamask/snaps-utils'; import { assert, mask, object, string } from '@metamask/superstruct'; -import type { Json } from '@metamask/utils'; +import type { Hex, Json } from '@metamask/utils'; import { bigIntToHex, KnownCaipNamespace, @@ -963,9 +963,9 @@ export class SnapKeyring extends EventEmitter { return TransactionFactory.fromTxData({ ...(tx as Record), - r: signature.r, - s: signature.s, - v: signature.v, + r: signature.r as Hex, + s: signature.s as Hex, + v: signature.v as Hex, }); } diff --git a/packages/keyring-utils/package.json b/packages/keyring-utils/package.json index c93eef156..ec4a3a0cb 100644 --- a/packages/keyring-utils/package.json +++ b/packages/keyring-utils/package.json @@ -45,7 +45,7 @@ "test:watch": "jest --watch" }, "dependencies": { - "@ethereumjs/tx": "^4.2.0", + "@ethereumjs/tx": "^5.4.0", "@metamask/superstruct": "^3.1.0", "@metamask/utils": "^11.1.0", "bitcoin-address-validation": "^2.2.3" diff --git a/packages/keyring-utils/src/keyring.ts b/packages/keyring-utils/src/keyring.ts index a523e3cee..8be5157d3 100644 --- a/packages/keyring-utils/src/keyring.ts +++ b/packages/keyring-utils/src/keyring.ts @@ -1,4 +1,4 @@ -import type { TypedTransaction, TxData } from '@ethereumjs/tx'; +import type { TypedTransaction, TypedTxData } from '@ethereumjs/tx'; import type { Eip1024EncryptedData, Hex, Json } from '@metamask/utils'; /** @@ -140,7 +140,7 @@ export type Keyring = { address: Hex, transaction: TypedTransaction, options?: Record, - ): Promise; + ): Promise; /** * Sign a message. This is equivalent to an older version of the the diff --git a/yarn.lock b/yarn.lock index f7aa80eae..ba9a48aa4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -643,7 +643,7 @@ __metadata: languageName: node linkType: hard -"@ethereumjs/tx@npm:^5.2.1": +"@ethereumjs/tx@npm:^5.2.1, @ethereumjs/tx@npm:^5.4.0": version: 5.4.0 resolution: "@ethereumjs/tx@npm:5.4.0" dependencies: @@ -1661,8 +1661,8 @@ __metadata: version: 0.0.0-use.local resolution: "@metamask/eth-hd-keyring@workspace:packages/keyring-eth-hd" dependencies: - "@ethereumjs/tx": "npm:^4.2.0" - "@ethereumjs/util": "npm:^8.1.0" + "@ethereumjs/tx": "npm:^5.4.0" + "@ethereumjs/util": "npm:^9.1.0" "@lavamoat/allow-scripts": "npm:^3.2.1" "@lavamoat/preinstall-always-fail": "npm:^2.1.0" "@metamask/auto-changelog": "npm:^3.4.4" @@ -1684,10 +1684,10 @@ __metadata: version: 0.0.0-use.local resolution: "@metamask/eth-ledger-bridge-keyring@workspace:packages/keyring-eth-ledger-bridge" dependencies: - "@ethereumjs/common": "npm:^3.2.0" + "@ethereumjs/common": "npm:^4.4.0" "@ethereumjs/rlp": "npm:^5.0.2" - "@ethereumjs/tx": "npm:^4.2.0" - "@ethereumjs/util": "npm:^8.1.0" + "@ethereumjs/tx": "npm:^5.4.0" + "@ethereumjs/util": "npm:^9.1.0" "@lavamoat/allow-scripts": "npm:^3.2.1" "@lavamoat/preinstall-always-fail": "npm:^2.1.0" "@ledgerhq/hw-app-eth": "npm:^6.42.0" @@ -1760,8 +1760,8 @@ __metadata: version: 0.0.0-use.local resolution: "@metamask/eth-simple-keyring@workspace:packages/keyring-eth-simple" dependencies: - "@ethereumjs/tx": "npm:^4.2.0" - "@ethereumjs/util": "npm:^8.1.0" + "@ethereumjs/tx": "npm:^5.4.0" + "@ethereumjs/util": "npm:^9.1.0" "@lavamoat/allow-scripts": "npm:^3.2.1" "@lavamoat/preinstall-always-fail": "npm:^2.1.0" "@metamask/auto-changelog": "npm:^3.4.4" @@ -1790,7 +1790,7 @@ __metadata: version: 0.0.0-use.local resolution: "@metamask/eth-snap-keyring@workspace:packages/keyring-snap-bridge" dependencies: - "@ethereumjs/tx": "npm:^4.2.0" + "@ethereumjs/tx": "npm:^5.4.0" "@lavamoat/allow-scripts": "npm:^3.2.1" "@lavamoat/preinstall-always-fail": "npm:^2.1.0" "@metamask/auto-changelog": "npm:^3.4.4" @@ -1828,9 +1828,9 @@ __metadata: version: 0.0.0-use.local resolution: "@metamask/eth-trezor-keyring@workspace:packages/keyring-eth-trezor" dependencies: - "@ethereumjs/common": "npm:^3.2.0" - "@ethereumjs/tx": "npm:^4.2.0" - "@ethereumjs/util": "npm:^8.1.0" + "@ethereumjs/common": "npm:^4.4.0" + "@ethereumjs/tx": "npm:^5.4.0" + "@ethereumjs/util": "npm:^9.1.0" "@lavamoat/allow-scripts": "npm:^3.2.1" "@lavamoat/preinstall-always-fail": "npm:^2.1.0" "@metamask/auto-changelog": "npm:^3.4.4" @@ -2063,7 +2063,7 @@ __metadata: version: 0.0.0-use.local resolution: "@metamask/keyring-utils@workspace:packages/keyring-utils" dependencies: - "@ethereumjs/tx": "npm:^4.2.0" + "@ethereumjs/tx": "npm:^5.4.0" "@lavamoat/allow-scripts": "npm:^3.2.1" "@lavamoat/preinstall-always-fail": "npm:^2.1.0" "@metamask/auto-changelog": "npm:^3.4.4"