Skip to content
This repository has been archived by the owner on Oct 7, 2024. It is now read-only.

Commit

Permalink
bump @ethereumjs/util, @ethereumjs/tx & @metamask/eth-sig-util versio…
Browse files Browse the repository at this point in the history
…ns (#109)

* bump @ethereumjs/util, @ethereumjs/tx  & @metamask/eth-sig-util versions

* bump minimum required node version to 14

* address feedback
  • Loading branch information
adonesky1 authored Sep 16, 2022
1 parent f8c9105 commit 78bade8
Show file tree
Hide file tree
Showing 5 changed files with 154 additions and 395 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/lint-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
runs-on: ubuntu-20.04
strategy:
matrix:
node-version: [12.x, 14.x, 16.x]
node-version: [14.x, 16.x, 18.x]
steps:
- uses: actions/checkout@v2
- name: Use Node.js ${{ matrix.node-version }}
Expand Down
45 changes: 26 additions & 19 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
const { EventEmitter } = require('events');
const ethUtil = require('ethereumjs-util');
const {
isValidPrivate,
stripHexPrefix,
privateToPublic,
bufferToHex,
publicToAddress,
ecsign,
arrToBufArr,
} = require('@ethereumjs/util');
const randomBytes = require('randombytes');
const { keccak256 } = require('ethereum-cryptography/keccak');

const type = 'Simple Key Pair';
const {
Expand All @@ -18,7 +27,7 @@ function generateKey() {
// I don't think this is possible, but this validation was here previously,
// so it has been preserved just in case.
// istanbul ignore next
if (!ethUtil.isValidPrivate(privateKey)) {
if (!isValidPrivate(privateKey)) {
throw new Error(
'Private key does not satisfy the curve requirements (ie. it is invalid)',
);
Expand All @@ -40,9 +49,9 @@ class SimpleKeyring extends EventEmitter {

async deserialize(privateKeys = []) {
this._wallets = privateKeys.map((hexPrivateKey) => {
const strippedHexPrivateKey = ethUtil.stripHexPrefix(hexPrivateKey);
const strippedHexPrivateKey = stripHexPrefix(hexPrivateKey);
const privateKey = Buffer.from(strippedHexPrivateKey, 'hex');
const publicKey = ethUtil.privateToPublic(privateKey);
const publicKey = privateToPublic(privateKey);
return { privateKey, publicKey };
});
}
Expand All @@ -51,19 +60,19 @@ class SimpleKeyring extends EventEmitter {
const newWallets = [];
for (let i = 0; i < n; i++) {
const privateKey = generateKey();
const publicKey = ethUtil.privateToPublic(privateKey);
const publicKey = privateToPublic(privateKey);
newWallets.push({ privateKey, publicKey });
}
this._wallets = this._wallets.concat(newWallets);
const hexWallets = newWallets.map(({ publicKey }) =>
ethUtil.bufferToHex(ethUtil.publicToAddress(publicKey)),
bufferToHex(publicToAddress(publicKey)),
);
return hexWallets;
}

async getAccounts() {
return this._wallets.map(({ publicKey }) =>
ethUtil.bufferToHex(ethUtil.publicToAddress(publicKey)),
bufferToHex(publicToAddress(publicKey)),
);
}

Expand All @@ -77,9 +86,9 @@ class SimpleKeyring extends EventEmitter {

// For eth_sign, we need to sign arbitrary data:
async signMessage(address, data, opts = {}) {
const message = ethUtil.stripHexPrefix(data);
const message = stripHexPrefix(data);
const privKey = this._getPrivateKeyFor(address, opts);
const msgSig = ethUtil.ecsign(Buffer.from(message, 'hex'), privKey);
const msgSig = ecsign(Buffer.from(message, 'hex'), privKey);
const rawMsgSig = concatSig(msgSig.v, msgSig.r, msgSig.s);
return rawMsgSig;
}
Expand All @@ -95,7 +104,7 @@ class SimpleKeyring extends EventEmitter {
// For eth_decryptMessage:
async decryptMessage(withAccount, encryptedData) {
const wallet = this._getWalletForAccount(withAccount);
const privateKey = ethUtil.stripHexPrefix(wallet.privateKey);
const { privateKey } = wallet;
const sig = decrypt({ privateKey, encryptedData });
return sig;
}
Expand Down Expand Up @@ -139,7 +148,7 @@ class SimpleKeyring extends EventEmitter {
withAppKeyOrigin: origin,
});
const appKeyAddress = normalize(
ethUtil.publicToAddress(wallet.publicKey).toString('hex'),
publicToAddress(wallet.publicKey).toString('hex'),
);
return appKeyAddress;
}
Expand All @@ -154,7 +163,7 @@ class SimpleKeyring extends EventEmitter {
if (
!this._wallets
.map(({ publicKey }) =>
ethUtil.bufferToHex(ethUtil.publicToAddress(publicKey)).toLowerCase(),
bufferToHex(publicToAddress(publicKey)).toLowerCase(),
)
.includes(address.toLowerCase())
) {
Expand All @@ -163,9 +172,8 @@ class SimpleKeyring extends EventEmitter {

this._wallets = this._wallets.filter(
({ publicKey }) =>
ethUtil
.bufferToHex(ethUtil.publicToAddress(publicKey))
.toLowerCase() !== address.toLowerCase(),
bufferToHex(publicToAddress(publicKey)).toLowerCase() !==
address.toLowerCase(),
);
}

Expand All @@ -175,8 +183,7 @@ class SimpleKeyring extends EventEmitter {
_getWalletForAccount(account, opts = {}) {
const address = normalize(account);
let wallet = this._wallets.find(
({ publicKey }) =>
ethUtil.bufferToHex(ethUtil.publicToAddress(publicKey)) === address,
({ publicKey }) => bufferToHex(publicToAddress(publicKey)) === address,
);
if (!wallet) {
throw new Error('Simple Keyring - Unable to find matching address.');
Expand All @@ -186,8 +193,8 @@ class SimpleKeyring extends EventEmitter {
const { privateKey } = wallet;
const appKeyOriginBuffer = Buffer.from(opts.withAppKeyOrigin, 'utf8');
const appKeyBuffer = Buffer.concat([privateKey, appKeyOriginBuffer]);
const appKeyPrivateKey = ethUtil.keccak(appKeyBuffer, 256);
const appKeyPublicKey = ethUtil.privateToPublic(appKeyPrivateKey);
const appKeyPrivateKey = arrToBufArr(keccak256(appKeyBuffer, 256));
const appKeyPublicKey = privateToPublic(appKeyPrivateKey);
wallet = { privateKey: appKeyPrivateKey, publicKey: appKeyPublicKey };
}

Expand Down
9 changes: 5 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,13 @@
"lint:fix": "yarn lint:eslint --fix && yarn lint:misc --write"
},
"dependencies": {
"@metamask/eth-sig-util": "^4.0.0",
"ethereumjs-util": "^7.0.9",
"@ethereumjs/util": "^8.0.0",
"@metamask/eth-sig-util": "^5.0.0",
"ethereum-cryptography": "^1.1.2",
"randombytes": "^2.1.0"
},
"devDependencies": {
"@ethereumjs/tx": "^3.1.1",
"@ethereumjs/tx": "^4.0.0",
"@lavamoat/allow-scripts": "^1.0.6",
"@metamask/auto-changelog": "^2.5.0",
"@metamask/eslint-config": "^8.0.0",
Expand All @@ -53,7 +54,7 @@
"prettier-plugin-packagejson": "^2.2.11"
},
"engines": {
"node": ">=12.0.0"
"node": ">=14.0.0"
},
"lavamoat": {
"allowScripts": {
Expand Down
48 changes: 26 additions & 22 deletions test/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
const ethUtil = require('ethereumjs-util');
const {
stripHexPrefix,
bufferToHex,
toBuffer,
ecrecover,
pubToAddress,
isValidAddress,
} = require('@ethereumjs/util');
const { keccak256 } = require('ethereum-cryptography/keccak');
const {
encrypt,
getEncryptionPublicKey,
Expand Down Expand Up @@ -49,7 +57,7 @@ describe('simple-keyring', function () {
await keyring.deserialize([testAccount.key]);
const serialized = await keyring.serialize();
expect(serialized).toHaveLength(1);
expect(serialized[0]).toBe(ethUtil.stripHexPrefix(testAccount.key));
expect(serialized[0]).toBe(stripHexPrefix(testAccount.key));
});
});

Expand Down Expand Up @@ -127,9 +135,7 @@ describe('simple-keyring', function () {
it('reliably can decode messages it signs', async function () {
await keyring.deserialize([privateKey]);
const localMessage = 'hello there!';
const msgHashHex = ethUtil.bufferToHex(
ethUtil.keccak(Buffer.from(localMessage)),
);
const msgHashHex = bufferToHex(keccak256(Buffer.from(localMessage)));

await keyring.addAccounts(9);
const addresses = await keyring.getAccounts();
Expand All @@ -141,14 +147,12 @@ describe('simple-keyring', function () {
signatures.forEach((sgn, index) => {
const accountAddress = addresses[index];

const r = ethUtil.toBuffer(sgn.slice(0, 66));
const s = ethUtil.toBuffer(`0x${sgn.slice(66, 130)}`);
const v = ethUtil.bufferToInt(
ethUtil.toBuffer(`0x${sgn.slice(130, 132)}`),
);
const m = ethUtil.toBuffer(msgHashHex);
const pub = ethUtil.ecrecover(m, v, r, s);
const adr = `0x${ethUtil.pubToAddress(pub).toString('hex')}`;
const r = toBuffer(sgn.slice(0, 66));
const s = toBuffer(`0x${sgn.slice(66, 130)}`);
const v = BigInt(`0x${sgn.slice(130, 132)}`);
const m = toBuffer(msgHashHex);
const pub = ecrecover(m, v, r, s);
const adr = `0x${pubToAddress(pub).toString('hex')}`;

expect(adr).toBe(accountAddress);
});
Expand All @@ -157,7 +161,7 @@ describe('simple-keyring', function () {
it('throw error for invalid message', async function () {
await keyring.deserialize([privateKey]);
await expect(keyring.signMessage(address, '')).rejects.toThrow(
'Expected message to be an Uint8Array with length 32',
'Cannot convert 0x to a BigInt',
);
});

Expand Down Expand Up @@ -233,7 +237,7 @@ describe('simple-keyring', function () {
'6969696969696969696969696969696969696969696969696969696969696969',
'hex',
);
const privKeyHex = ethUtil.bufferToHex(privateKey);
const privKeyHex = bufferToHex(privateKey);
const message = '0x68656c6c6f20776f726c64';
const expectedSignature =
'0xce909e8ea6851bc36c007a0072d0524b07a3ff8d4e623aca4c71ca8e57250c4d0a3fc38fa8fbaaa81ead4b9f6bd03356b6f8bf18bccad167d78891636e1d69561b';
Expand Down Expand Up @@ -472,7 +476,7 @@ describe('simple-keyring', function () {
'6969696969696969696969696969696969696969696969696969696969696969',
'hex',
);
const privKeyHex = ethUtil.bufferToHex(privateKey);
const privKeyHex = bufferToHex(privateKey);
const message = 'Hello world!';
const encryptedMessage = encrypt({
publicKey: getEncryptionPublicKey(privateKey),
Expand Down Expand Up @@ -511,7 +515,7 @@ describe('simple-keyring', function () {
'hex',
);
const publicKey = 'GxuMqoE2oHsZzcQtv/WMNB3gCH2P6uzynuwO1P0MM1U=';
const privKeyHex = ethUtil.bufferToHex(privateKey);
const privKeyHex = bufferToHex(privateKey);

it('returns the expected value', async function () {
await keyring.deserialize([privKeyHex]);
Expand Down Expand Up @@ -624,7 +628,7 @@ describe('simple-keyring', function () {
);

expect(address).not.toBe(appKeyAddress);
expect(ethUtil.isValidAddress(appKeyAddress)).toBe(true);
expect(isValidAddress(appKeyAddress)).toBe(true);
});

it('should return different addresses when provided different app key origins', async function () {
Expand All @@ -636,14 +640,14 @@ describe('simple-keyring', function () {
'someapp.origin.io',
);

expect(ethUtil.isValidAddress(appKeyAddress1)).toBe(true);
expect(isValidAddress(appKeyAddress1)).toBe(true);

const appKeyAddress2 = await simpleKeyring.getAppKeyAddress(
address,
'anotherapp.origin.io',
);

expect(ethUtil.isValidAddress(appKeyAddress2)).toBe(true);
expect(isValidAddress(appKeyAddress2)).toBe(true);
expect(appKeyAddress1).not.toBe(appKeyAddress2);
});

Expand All @@ -656,14 +660,14 @@ describe('simple-keyring', function () {
'someapp.origin.io',
);

expect(ethUtil.isValidAddress(appKeyAddress1)).toBe(true);
expect(isValidAddress(appKeyAddress1)).toBe(true);

const appKeyAddress2 = await simpleKeyring.getAppKeyAddress(
address,
'someapp.origin.io',
);

expect(ethUtil.isValidAddress(appKeyAddress2)).toBe(true);
expect(isValidAddress(appKeyAddress2)).toBe(true);
expect(appKeyAddress1).toBe(appKeyAddress2);
});

Expand Down
Loading

0 comments on commit 78bade8

Please sign in to comment.