Skip to content
Merged
2 changes: 1 addition & 1 deletion packages/keyring-eth-hd/jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ module.exports = merge(baseConfig, {
branches: 83.87,
functions: 100,
lines: 95,
statements: 97.93,
statements: 97.91,
},
},
});
4 changes: 2 additions & 2 deletions packages/keyring-eth-hd/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,15 +43,15 @@
"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",
"@metamask/utils": "^11.1.0",
"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",
Expand Down
29 changes: 13 additions & 16 deletions packages/keyring-eth-hd/src/hd-keyring.test.ts
Original file line number Diff line number Diff line change
@@ -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,
Expand All @@ -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
Expand Down Expand Up @@ -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);
Expand All @@ -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);
});
Expand Down Expand Up @@ -1055,8 +1053,7 @@ describe('hd-keyring', () => {
});
});

const txParams = {
from: firstAcct,
const txParams: TypedTxData = {
nonce: '0x00',
gasPrice: '0x09184e72a000',
gasLimit: '0x2710',
Expand All @@ -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);
Expand Down
30 changes: 12 additions & 18 deletions packages/keyring-eth-hd/src/hd-keyring.ts
Original file line number Diff line number Diff line change
@@ -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,
Expand All @@ -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`;
Expand Down Expand Up @@ -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;
}
Expand All @@ -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));
}

/**
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -425,7 +419,7 @@ export class HdKeyring {
opts: HDKeyringAccountSelectionOptions = {},
): Promise<string> {
const privKey = this.#getPrivateKeyFor(withAccount, opts);
const publicKey = getEncryptionPublicKey(bytesToHex(privKey));
const publicKey = getEncryptionPublicKey(remove0x(bytesToHex(privKey)));
return publicKey;
}

Expand Down Expand Up @@ -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 };
}

Expand Down Expand Up @@ -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(),
);
}

Expand Down
6 changes: 3 additions & 3 deletions packages/keyring-eth-ledger-bridge/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
12 changes: 6 additions & 6 deletions packages/keyring-eth-ledger-bridge/src/ledger-keyring.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';

Expand Down Expand Up @@ -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 });
Expand Down Expand Up @@ -646,7 +646,7 @@ describe('LedgerKeyring', function () {
v: '0x26',
r: '0xf3a7718999d1b87beda810b25cc025153e74df0745279826b9b2f3d1d1b6318',
s: '0x7e33bdfbf5272dc4f55649e9ba729849670171a68ef8c0fbeed3b879b90b8954',
};
} as const;

await basicSetupToUnlockOneAccount();

Expand All @@ -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;
Expand All @@ -694,7 +694,7 @@ describe('LedgerKeyring', function () {
v: '0x0',
r: '0x5ffb3adeaec80e430e7a7b02d95c5108b6f09a0bdf3cf69869dc1b38d0fb8d3a',
s: '0x28b234a5403d31564e18258df84c51a62683e3f54fa2b106fdc1a9058006a112',
};
} as const;

await basicSetupToUnlockOneAccount();

Expand All @@ -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;
});
Expand Down
35 changes: 22 additions & 13 deletions packages/keyring-eth-ledger-bridge/src/ledger-keyring.ts
Original file line number Diff line number Diff line change
@@ -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,
Expand All @@ -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';
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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 {
Expand Down
4 changes: 2 additions & 2 deletions packages/keyring-eth-simple/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
Loading
Loading