diff --git a/packages/web3-eth-accounts/package.json b/packages/web3-eth-accounts/package.json index e1e34e71a99..ec28624b803 100644 --- a/packages/web3-eth-accounts/package.json +++ b/packages/web3-eth-accounts/package.json @@ -42,8 +42,7 @@ "dependencies": { "web3-errors": "1.0.0-alpha.0", "@ethereumjs/tx": "^3.4.0", - "ethereum-cryptography": "^0.2.1", - "secp256k1": "^4.0.2", + "ethereum-cryptography": "^1.1.0", "web3-common": "^1.0.0-alpha.0", "web3-utils": "^4.0.0-alpha.1", "web3-validator": "^0.1.0-alpha.0" diff --git a/packages/web3-eth-accounts/src/account.ts b/packages/web3-eth-accounts/src/account.ts index d3dd7b31611..231c095b63b 100644 --- a/packages/web3-eth-accounts/src/account.ts +++ b/packages/web3-eth-accounts/src/account.ts @@ -15,55 +15,83 @@ You should have received a copy of the GNU Lesser General Public License along with web3.js. If not, see . */ +import { TransactionFactory, TypedTransaction } from '@ethereumjs/tx'; +import { decrypt as createDecipheriv, encrypt as createCipheriv } from 'ethereum-cryptography/aes'; +import { pbkdf2Sync } from 'ethereum-cryptography/pbkdf2'; +import { scryptSync } from 'ethereum-cryptography/scrypt'; +import { getPublicKey, recoverPublicKey, signSync, utils } from 'ethereum-cryptography/secp256k1'; import { + InvalidKdfError, + InvalidPasswordError, InvalidPrivateKeyError, - PrivateKeyLengthError, - UndefinedRawTransactionError, - SignerError, InvalidSignatureError, - InvalidKdfError, + IVLengthError, KeyDerivationError, KeyStoreVersionError, - InvalidPasswordError, - IVLengthError, PBKDF2IterationsError, + PrivateKeyLengthError, + SignerError, + UndefinedRawTransactionError, } from 'web3-errors'; -import { utils, getPublicKey } from 'ethereum-cryptography/secp256k1'; -import { keccak256 } from 'ethereum-cryptography/keccak'; -import { TransactionFactory, TypedTransaction } from '@ethereumjs/tx'; -import { ecdsaSign, ecdsaRecover } from 'secp256k1'; -import { pbkdf2Sync } from 'ethereum-cryptography/pbkdf2'; -import { scryptSync } from 'ethereum-cryptography/scrypt'; -import { encrypt as createCipheriv, decrypt as createDecipheriv } from 'ethereum-cryptography/aes'; import { - toChecksumAddress, + Address, + Bytes, + bytesToBuffer, bytesToHex, - sha3Raw, HexString, - randomBytes, hexToBytes, - Address, isHexStrict, + numberToHex, + randomBytes, + sha3Raw, + toChecksumAddress, utf8ToHex, } from 'web3-utils'; -import { validator, isBuffer, isHexString32Bytes, isString, isNullish } from 'web3-validator'; +import { isBuffer, isNullish, isString, validator } from 'web3-validator'; +import { keyStoreSchema } from './schemas'; import { + CipherOptions, + KeyStore, + PBKDF2SHA256Params, + ScryptParams, SignatureObject, SignResult, SignTransactionResult, - KeyStore, - ScryptParams, - PBKDF2SHA256Params, - CipherOptions, Web3Account, } from './types'; -import { keyStoreSchema } from './schemas'; + +/** + * Get the private key buffer after the validation + * + * @param data - The data in any bytes format + * @returns + */ +export const parseAndValidatePrivateKey = (data: Bytes): Buffer => { + let privateKeyBuffer: Buffer; + + // To avoid the case of 1 character less in a hex string which is prefixed with '0' by using 'bytesToBuffer' + if (typeof data === 'string' && isHexStrict(data) && data.length !== 66) { + throw new PrivateKeyLengthError(); + } + + try { + privateKeyBuffer = Buffer.isBuffer(data) ? data : bytesToBuffer(data); + } catch { + throw new InvalidPrivateKeyError(); + } + + if (privateKeyBuffer.byteLength !== 32) { + throw new PrivateKeyLengthError(); + } + + return privateKeyBuffer; +}; /** * * Hashes the given message. The data will be UTF-8 HEX decoded and enveloped as follows: "\x19Ethereum Signed Message:\n" + message.length + message and hashed using keccak256. * - * @param message A message to hash, if its HEX it will be UTF8 decoded. + * @param message - A message to hash, if its HEX it will be UTF8 decoded. * @returns The hashed message * ```ts * hashMessage("Hello world") @@ -77,11 +105,14 @@ export const hashMessage = (message: string): string => { const messageBytes = hexToBytes(messageHex); - const preamble = `\x19Ethereum Signed Message:\n${messageBytes.length}`; + const preamble = Buffer.from( + `\x19Ethereum Signed Message:\n${messageBytes.byteLength}`, + 'utf8', + ); - const ethMessage = Buffer.concat([Buffer.from(preamble), Buffer.from(messageBytes)]); + const ethMessage = Buffer.concat([preamble, messageBytes]); - return `0x${Buffer.from(keccak256(ethMessage)).toString('hex')}`; + return sha3Raw(ethMessage); // using keccak in web3-utils.sha3Raw instead of SHA3 (NIST Standard) as both are different }; /** @@ -103,31 +134,30 @@ export const hashMessage = (message: string): string => { * } * ``` */ -export const sign = (data: string, privateKey: HexString): SignResult => { - const privateKeyParam = privateKey.startsWith('0x') ? privateKey.substring(2) : privateKey; - - if (!isHexString32Bytes(privateKeyParam, false)) { - throw new PrivateKeyLengthError(); - } +export const sign = (data: string, privateKey: Bytes): SignResult => { + const privateKeyBuffer = parseAndValidatePrivateKey(privateKey); const hash = hashMessage(data); - const signObj = ecdsaSign( - Buffer.from(hash.substring(2), 'hex'), - Buffer.from(privateKeyParam, 'hex'), - ); + const [signature, recoverId] = signSync(hash.substring(2), privateKeyBuffer, { + // Makes signatures compatible with libsecp256k1 + recovered: true, + + // Returned signature should be in DER format ( non compact ) + der: false, + }); - const r = Buffer.from(signObj.signature.slice(0, 32)); - const s = Buffer.from(signObj.signature.slice(32, 64)); - const v = signObj.recid + 27; + const r = Buffer.from(signature.slice(0, 32)); + const s = Buffer.from(signature.slice(32, 64)); + const v = recoverId + 27; return { message: data, messageHash: hash, - v: `0x${v.toString(16)}`, - r: `0x${r.toString('hex')}`, - s: `0x${s.toString('hex')}`, - signature: `0x${Buffer.from(signObj.signature).toString('hex')}${v.toString(16)}`, + v: numberToHex(v), + r: bytesToHex(r), + s: bytesToHex(s), + signature: `0x${Buffer.from(signature).toString('hex')}${v.toString(16)}`, }; }; @@ -234,7 +264,7 @@ export const signTransaction = async ( } const rawTx = bytesToHex(signedTx.serialize()); - const txHash = keccak256(hexToBytes(rawTx)); + const txHash = sha3Raw(rawTx); // using keccak in web3-utils.sha3Raw instead of SHA3 (NIST Standard) as both are different return { messageHash: bytesToHex(Buffer.from(signedTx.getMessageToSign(true))), @@ -302,10 +332,10 @@ export const recover = ( const v = signature.substring(V_INDEX); // 0x + r + s + v - const ecPublicKey = ecdsaRecover( + const ecPublicKey = recoverPublicKey( + Buffer.from(hashedMessage.substring(2), 'hex'), Buffer.from(signature.substring(2, V_INDEX), 'hex'), parseInt(v, 16) - 27, - Buffer.from(hashedMessage.substring(2), 'hex'), false, ); @@ -360,29 +390,20 @@ const uuidV4 = (): string => { * > "0xEB014f8c8B418Db6b45774c326A0E64C78914dC0" * ``` */ -export const privateKeyToAddress = (privateKey: string | Buffer): string => { - if (!(isString(privateKey) || isBuffer(privateKey))) { - throw new InvalidPrivateKeyError(); - } +export const privateKeyToAddress = (privateKey: Bytes): string => { + const privateKeyBuffer = parseAndValidatePrivateKey(privateKey); - const stringPrivateKey = Buffer.isBuffer(privateKey) - ? Buffer.from(privateKey).toString('hex') - : privateKey; + // Get public key from private key in compressed format + const publicKey = getPublicKey(privateKeyBuffer); - const stringPrivateKeyNoPrefix = stringPrivateKey.startsWith('0x') - ? stringPrivateKey.slice(2) - : stringPrivateKey; - - if (!isHexString32Bytes(stringPrivateKeyNoPrefix, false)) { - throw new PrivateKeyLengthError(); - } + // Uncompressed ECDSA public key contains the prefix `0x04` which is not used in the Ethereum public key + const publicKeyHash = sha3Raw(publicKey.slice(1)); - const publicKey = getPublicKey(stringPrivateKeyNoPrefix); + // The hash is returned as 256 bits (32 bytes) or 64 hex characters + // To get the address, take the last 20 bytes of the public hash + const address = publicKeyHash.slice(-40); - const publicKeyString = `0x${publicKey.slice(2)}`; - const publicHash = sha3Raw(publicKeyString); - const publicHashHex = bytesToHex(publicHash); - return toChecksumAddress(publicHashHex.slice(-40)); // To get the address, take the last 20 bytes of the public hash + return toChecksumAddress(`0x${address}`); }; /** @@ -460,21 +481,11 @@ export const privateKeyToAddress = (privateKey: string | Buffer): string => { *``` */ export const encrypt = async ( - privateKey: HexString, + privateKey: Bytes, password: string | Buffer, options?: CipherOptions, ): Promise => { - if (!(isString(privateKey) || isBuffer(privateKey))) { - throw new InvalidPrivateKeyError(); - } - - const stringPrivateKey = Buffer.isBuffer(privateKey) - ? Buffer.from(privateKey).toString('hex') - : privateKey; - - if (!isHexString32Bytes(stringPrivateKey)) { - throw new PrivateKeyLengthError(); - } + const privateKeyBuffer = parseAndValidatePrivateKey(privateKey); // if given salt or iv is a string, convert it to a Uint8Array let salt; @@ -546,10 +557,8 @@ export const encrypt = async ( throw new InvalidKdfError(); } - const cipherKey = Buffer.from(stringPrivateKey.replace('0x', ''), 'hex'); - const cipher = await createCipheriv( - cipherKey, + privateKeyBuffer, Buffer.from(derivedKey.slice(0, 16)), initializationVector, 'aes-128-ctr', @@ -562,7 +571,7 @@ export const encrypt = async ( return { version: 3, id: uuidV4(), - address: privateKeyToAddress(stringPrivateKey).toLowerCase().replace('0x', ''), + address: privateKeyToAddress(privateKeyBuffer).toLowerCase().replace('0x', ''), crypto: { ciphertext, cipherparams: { @@ -596,19 +605,19 @@ export const encrypt = async ( * } * ``` */ -export const privateKeyToAccount = (privateKey: string | Buffer): Web3Account => { - const pKey = Buffer.isBuffer(privateKey) ? Buffer.from(privateKey).toString('hex') : privateKey; +export const privateKeyToAccount = (privateKey: Bytes): Web3Account => { + const privateKeyBuffer = parseAndValidatePrivateKey(privateKey); return { - address: privateKeyToAddress(pKey), - privateKey: pKey, + address: privateKeyToAddress(privateKeyBuffer), + privateKey: bytesToHex(privateKeyBuffer), signTransaction: (_tx: Record) => { throw new SignerError('Do not have network access to sign the transaction'); }, sign: (data: Record | string) => - sign(typeof data === 'string' ? data : JSON.stringify(data), pKey), + sign(typeof data === 'string' ? data : JSON.stringify(data), privateKeyBuffer), encrypt: async (password: string, options?: Record) => { - const data = await encrypt(pKey, password, options); + const data = await encrypt(privateKeyBuffer, password, options); return JSON.stringify(data); }, diff --git a/packages/web3-eth-accounts/test/fixtures/account.ts b/packages/web3-eth-accounts/test/fixtures/account.ts index b79a406d2a7..63048fb18b8 100644 --- a/packages/web3-eth-accounts/test/fixtures/account.ts +++ b/packages/web3-eth-accounts/test/fixtures/account.ts @@ -28,6 +28,33 @@ import { import { sign, signTransaction, encrypt } from '../../src/account'; import { CipherOptions, KeyStore } from '../../src/types'; +export const validPrivateKeyToAddressData: [string, string][] = [ + [ + '0x348ce564d427a3311b6536bbcff9390d69395b06ed6c486954e971d960fe8709', + '0xb8CE9ab6943e0eCED004cDe8e3bBed6568B2Fa01', + ], + [ + '0x9e93921f9bca358a96aa66efcccbde12850473be95f63c1453e29656feafeb35', + '0x118C2E5F57FD62C2B5b46a5ae9216F4FF4011a07', + ], + [ + '0xf44e0436edb0afd26b09f7b9f1e7a280d2365fc530aebccf893f1158a449d20a', + '0x8824eEA7A9FF8E051e63ACAc443460151CB6fd92', + ], + [ + '0xf4a2b939592564feb35ab10a8e04f6f2fe0943579fb3c9c33505298978b74893', + '0xd5e099c71B797516c10ED0F0d895f429C2781142', + ], +]; + +export const invalidPrivateKeyToAddressData: [ + any, + PrivateKeyLengthError | InvalidPrivateKeyError, +][] = [ + ['', new InvalidPrivateKeyError()], + [Buffer.from([]), new PrivateKeyLengthError()], +]; + export const validPrivateKeytoAccountData: [string, any][] = [ [ '0x348ce564d427a3311b6536bbcff9390d69395b06ed6c486954e971d960fe8709', @@ -52,6 +79,17 @@ export const validPrivateKeytoAccountData: [string, any][] = [ ]; export const signatureRecoverData: [string, any][] = [ + [ + 'Some long text with integers 1233 and special characters and unicode \u1234 as well.', + { + address: '0x6E599DA0bfF7A6598AC1224E4985430Bf16458a4', + privateKey: '0xcb89ec4b01771c6c8272f4c0aafba2f8ee0b101afb22273b786939a8af7c1912', + data: 'Some long text with integers 1233 and special characters and unicode \u1234 as well.', + // signature done with personal_sign + signature: + '0x2ac888726c80494b80b63996455d109aef5db27e673dd92f277ac6e48dc300db3dfc7549744c2a33a03a2eaa0f2837f54c5951b80d5e05257d605bc695c2ae7f1c', + }, + ], [ 'Some data', { @@ -129,7 +167,7 @@ export const invalidPrivateKeytoAccountData: [ any, PrivateKeyLengthError | InvalidPrivateKeyError, ][] = [ - ['', new PrivateKeyLengthError()], + ['', new InvalidPrivateKeyError()], [Buffer.from([]), new PrivateKeyLengthError()], ]; @@ -392,3 +430,13 @@ export const invalidDecryptData: [[any, string], InvalidKdfError | KeyDerivation new KeyDerivationError(), ], ]; + +export const validHashMessageData: [string, string][] = [ + ['🤗', '0x716ce69c5d2d629c168bc02e24a961456bdc5a362d366119305aea73978a0332'], + [ + 'Some long text with integers 1233 and special characters and unicode \u1234 as well.', + '0xff21294f27c6b1e416215feb0b0b904c552c874c4e11b2314dd3afc1714ed8a8', + ], + ['non utf8 string', '0x8862c6a425a83c082216090e4f0e03b64106189e93c29b11d0112e77b477cce2'], + ['', '0x5f35dce98ba4fba25530a026ed80b2cecdaa31091ba4958b99b52ea1d068adad'], +]; diff --git a/packages/web3-eth-accounts/test/unit/account.test.ts b/packages/web3-eth-accounts/test/unit/account.test.ts index 38ec5a52c0f..666bfcf03be 100644 --- a/packages/web3-eth-accounts/test/unit/account.test.ts +++ b/packages/web3-eth-accounts/test/unit/account.test.ts @@ -16,29 +16,33 @@ along with web3.js. If not, see . */ import { TransactionFactory } from '@ethereumjs/tx'; +import { Address, isHexStrict } from 'web3-utils'; import { Web3ValidatorError } from 'web3-validator'; -import { isHexStrict, Address, utf8ToHex } from 'web3-utils'; import { create, + decrypt, + encrypt, + hashMessage, privateKeyToAccount, - signTransaction, + privateKeyToAddress, + recover, recoverTransaction, - hashMessage, sign, - recover, - encrypt, - decrypt, + signTransaction, } from '../../src/account'; import { + invalidDecryptData, + invalidEncryptData, + invalidKeyStore, + invalidPrivateKeytoAccountData, + invalidPrivateKeyToAddressData, signatureRecoverData, transactionsTestData, - validPrivateKeytoAccountData, - invalidPrivateKeytoAccountData, - validEncryptData, validDecryptData, - invalidDecryptData, - invalidKeyStore, - invalidEncryptData, + validEncryptData, + validHashMessageData, + validPrivateKeytoAccountData, + validPrivateKeyToAddressData, } from '../fixtures/account'; describe('accounts', () => { @@ -56,6 +60,20 @@ describe('accounts', () => { }); }); + describe('privateKeyToAddress', () => { + describe('valid cases', () => { + it.each(validPrivateKeyToAddressData)('%s', (input, output) => { + expect(privateKeyToAddress(input)).toEqual(output); + }); + }); + + describe('invalid cases', () => { + it.each(invalidPrivateKeyToAddressData)('%s', (input, output) => { + expect(() => privateKeyToAddress(input)).toThrow(output); + }); + }); + }); + describe('privateKeyToAccount', () => { describe('valid cases', () => { it.each(validPrivateKeytoAccountData)('%s', (input, output) => { @@ -103,27 +121,24 @@ describe('accounts', () => { }); describe('Hash Message', () => { - it('should hash data correctly using an emoji character', () => { - const message = '🤗'; - const dataHash = '0x716ce69c5d2d629c168bc02e24a961456bdc5a362d366119305aea73978a0332'; - - const hashedMessage = hashMessage(message); - expect(hashedMessage).toEqual(dataHash); - - const hashedMessageHex = hashMessage(utf8ToHex(message)); - expect(hashedMessageHex).toEqual(dataHash); + it.each(validHashMessageData)('%s', (message, hash) => { + expect(hashMessage(message)).toEqual(hash); }); }); describe('Sign Message', () => { - it.each(signatureRecoverData)('sign test %s', (data, testObj) => { - const result = sign(data, testObj.privateKey); - expect(result.signature).toEqual(testObj.signature); + describe('sign', () => { + it.each(signatureRecoverData)('%s', (data, testObj) => { + const result = sign(data, testObj.privateKey); + expect(result.signature).toEqual(testObj.signature); + }); }); - it.each(signatureRecoverData)('recover test %s', (data, testObj) => { - const address = recover(data, testObj.signature); - expect(address).toEqual(testObj.address); + describe('recover', () => { + it.each(signatureRecoverData)('%s', (data, testObj) => { + const address = recover(data, testObj.signature); + expect(address).toEqual(testObj.address); + }); }); }); @@ -165,7 +180,7 @@ describe('accounts', () => { const result = await decrypt(keystore, input[1]); expect(JSON.stringify(result)).toEqual( - JSON.stringify(privateKeyToAccount(input[3].slice(2))), + JSON.stringify(privateKeyToAccount(input[3])), ); const keystoreString = JSON.stringify(keystore); @@ -173,7 +188,7 @@ describe('accounts', () => { const stringResult = await decrypt(keystoreString, input[1], true); expect(JSON.stringify(stringResult)).toEqual( - JSON.stringify(privateKeyToAccount(input[3].slice(2))), + JSON.stringify(privateKeyToAccount(input[3])), ); }); }); diff --git a/packages/web3-utils/package.json b/packages/web3-utils/package.json index 3800e10a257..8111b24d807 100644 --- a/packages/web3-utils/package.json +++ b/packages/web3-utils/package.json @@ -42,6 +42,6 @@ "dependencies": { "web3-errors": "1.0.0-alpha.0", "web3-validator": "^0.1.0-alpha.0", - "ethereum-cryptography": "^1.0.3" + "ethereum-cryptography": "^1.1.0" } } diff --git a/packages/web3-validator/package.json b/packages/web3-validator/package.json index f1758ed9220..95399aa10e3 100644 --- a/packages/web3-validator/package.json +++ b/packages/web3-validator/package.json @@ -28,7 +28,7 @@ }, "dependencies": { "ajv": "^8.8.2", - "ethereum-cryptography": "^0.2.1" + "ethereum-cryptography": "^1.1.0" }, "devDependencies": { "@types/jest": "^27.0.3", diff --git a/yarn.lock b/yarn.lock index 33a55938446..213aa9ac467 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1686,25 +1686,20 @@ resolved "https://registry.yarnpkg.com/@microsoft/tsdoc/-/tsdoc-0.14.1.tgz#155ef21065427901994e765da8a0ba0eaae8b8bd" integrity sha512-6Wci+Tp3CgPt/B9B0a3J4s3yMgLNSku6w5TV6mN+61C71UqsRBv2FUibBf3tPGlNxebgPHMEUzKpb1ggE8KCKw== -"@noble/hashes@1.0.0", "@noble/hashes@~1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.0.0.tgz#d5e38bfbdaba174805a4e649f13be9a9ed3351ae" - integrity sha512-DZVbtY62kc3kkBtMHqwCOfXrT/hnoORy5BJ4+HU1IR59X0KWAOqsfzQPcUl/lQLlG7qXbe/fZ3r/emxtAl+sqg== - -"@noble/hashes@^0.4.4": - version "0.4.5" - resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-0.4.5.tgz#f69a963b0c59c1145bc5aca1f3eef58a48bf9a59" - integrity sha512-oK/2b9gHb1CfiFwpPHQs010WgROn4ioilT7TFwxMVwuDaXEJP3QPhyedYbOpgM4JDBgT9n5gaispBQlkaAgT6g== +"@noble/hashes@1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.1.1.tgz#c056d9b7166c1e7387a7453c2aff199bf7d88e5f" + integrity sha512-Lkp9+NijmV7eSVZqiUvt3UCuuHeJpUVmRrvh430gyJjJiuJMqkeHf6/A9lQ/smmbWV/0spDeJscscPzyB4waZg== -"@noble/secp256k1@1.5.5", "@noble/secp256k1@~1.5.2": - version "1.5.5" - resolved "https://registry.yarnpkg.com/@noble/secp256k1/-/secp256k1-1.5.5.tgz#315ab5745509d1a8c8e90d0bdf59823ccf9bcfc3" - integrity sha512-sZ1W6gQzYnu45wPrWx8D3kwI2/U29VYTx9OjbDAd7jwRItJ0cSTMPRL/C8AWZFn9kWFLQGqEXVEE86w4Z8LpIQ== +"@noble/hashes@~1.1.1": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.1.2.tgz#e9e035b9b166ca0af657a7848eb2718f0f22f183" + integrity sha512-KYRCASVTv6aeUi1tsF8/vpyR7zpfs3FUzy2Jqm+MU+LmUKhQ0y2FpfwqkCcxSg2ua4GALJd8k2R76WxwZGbQpA== -"@noble/secp256k1@^1.3.3": - version "1.3.4" - resolved "https://registry.yarnpkg.com/@noble/secp256k1/-/secp256k1-1.3.4.tgz#158ded712d09237c0d3428be60dc01ce8ebab9fb" - integrity sha512-ZVRouDO5mbdCiDg4zCd3ZZABduRtpy4tCnB33Gh9upHe9tRzpiqbRSN1VTjrj/2g8u2c6MBi0YLNnNQpBYOiWg== +"@noble/secp256k1@1.6.0", "@noble/secp256k1@~1.6.0": + version "1.6.0" + resolved "https://registry.yarnpkg.com/@noble/secp256k1/-/secp256k1-1.6.0.tgz#602afbbfcfb7e169210469b697365ef740d7e930" + integrity sha512-DWSsg8zMHOYMYBqIQi96BQuthZrp98LCeMNcUOaffCIVYQ5yxDbNikLF+H7jEnmNNmXbtVic46iCuVWzar+MgA== "@nodelib/fs.scandir@2.1.5": version "2.1.5" @@ -1903,27 +1898,27 @@ resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-4.6.0.tgz#c91cf64bc27f573836dba4122758b4743418c1b3" integrity sha512-8vi4d50NNya/bQqCmaVzvHNmwHvS0OBKb7HNtuNwEE3scXWrP31fKQoGxNMT+KbzmrNZzatE3QK5p2gFONI/hg== -"@scure/base@~1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@scure/base/-/base-1.0.0.tgz#109fb595021de285f05a7db6806f2f48296fcee7" - integrity sha512-gIVaYhUsy+9s58m/ETjSJVKHhKTBMmcRb9cEV5/5dwvfDlfORjKrFsDeDHWRrm6RjcPvCLZFwGJjAjLj1gg4HA== +"@scure/base@~1.1.0": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@scure/base/-/base-1.1.1.tgz#ebb651ee52ff84f420097055f4bf46cfba403938" + integrity sha512-ZxOhsSyxYwLJj3pLZCefNitxsj093tb2vq90mp2txoYeBqbcjDjqFhyM8eUjq/uFm6zJ+mUuqxlS2FkuSY1MTA== -"@scure/bip32@1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@scure/bip32/-/bip32-1.0.1.tgz#1409bdf9f07f0aec99006bb0d5827693418d3aa5" - integrity sha512-AU88KKTpQ+YpTLoicZ/qhFhRRIo96/tlb+8YmDDHR9yiKVjSsFZiefJO4wjS2PMTkz5/oIcw84uAq/8pleQURA== +"@scure/bip32@1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@scure/bip32/-/bip32-1.1.0.tgz#dea45875e7fbc720c2b4560325f1cf5d2246d95b" + integrity sha512-ftTW3kKX54YXLCxH6BB7oEEoJfoE2pIgw7MINKAs5PsS6nqKPuKk1haTF/EuHmYqG330t5GSrdmtRuHaY1a62Q== dependencies: - "@noble/hashes" "~1.0.0" - "@noble/secp256k1" "~1.5.2" - "@scure/base" "~1.0.0" + "@noble/hashes" "~1.1.1" + "@noble/secp256k1" "~1.6.0" + "@scure/base" "~1.1.0" -"@scure/bip39@1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@scure/bip39/-/bip39-1.0.0.tgz#47504e58de9a56a4bbed95159d2d6829fa491bb0" - integrity sha512-HrtcikLbd58PWOkl02k9V6nXWQyoa7A0+Ek9VF7z17DDk9XZAFUcIdqfh0jJXLypmizc5/8P6OxoUeKliiWv4w== +"@scure/bip39@1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@scure/bip39/-/bip39-1.1.0.tgz#92f11d095bae025f166bef3defcc5bf4945d419a" + integrity sha512-pwrPOS16VeTKg98dYXQyIjJEcWfz7/1YJIwxUEPFfQPtc86Ym/1sVgQ2RLoD43AazMk2l/unK4ITySSpW2+82w== dependencies: - "@noble/hashes" "~1.0.0" - "@scure/base" "~1.0.0" + "@noble/hashes" "~1.1.1" + "@scure/base" "~1.1.0" "@sinonjs/commons@^1.7.0": version "1.8.3" @@ -4881,24 +4876,15 @@ ethereum-cryptography@^0.1.3: secp256k1 "^4.0.1" setimmediate "^1.0.5" -ethereum-cryptography@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/ethereum-cryptography/-/ethereum-cryptography-0.2.1.tgz#7a2cce5c47157eb6992229cf26ccd889d5ee4754" - integrity sha512-hZkrGoL/LkL8OtrXJkCsNJkOs7ONplB1wvAq8pfagpHC5KVGJHWx2xFbRGuWP2zbMKBdxKBcbzMOG4v/ejSulw== - dependencies: - "@noble/hashes" "^0.4.4" - "@noble/secp256k1" "^1.3.3" - micro-base "^0.10.0" - -ethereum-cryptography@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/ethereum-cryptography/-/ethereum-cryptography-1.0.3.tgz#b1f8f4e702434b2016248dbb2f9fdd60c54772d8" - integrity sha512-NQLTW0x0CosoVb/n79x/TRHtfvS3hgNUPTUSCu0vM+9k6IIhHFFrAOJReneexjZsoZxMjJHnJn4lrE8EbnSyqQ== +ethereum-cryptography@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/ethereum-cryptography/-/ethereum-cryptography-1.1.0.tgz#7048d184ff365a5255ced5cc9eb7682a273c4db7" + integrity sha512-wyNVTBR4wIR2yoXdMv4Qt44mTVBpPgSW/DQCTmNO6nQluwpyrAIvmL4mxPbziFuc6VWJQa3rwUxn0nUFU03nyQ== dependencies: - "@noble/hashes" "1.0.0" - "@noble/secp256k1" "1.5.5" - "@scure/bip32" "1.0.1" - "@scure/bip39" "1.0.0" + "@noble/hashes" "1.1.1" + "@noble/secp256k1" "1.6.0" + "@scure/bip32" "1.1.0" + "@scure/bip39" "1.1.0" ethereum-protocol@^1.0.1: version "1.0.1" @@ -7768,11 +7754,6 @@ methods@~1.1.2: resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= -micro-base@^0.10.0: - version "0.10.0" - resolved "https://registry.yarnpkg.com/micro-base/-/micro-base-0.10.0.tgz#2a324c7836920b2cbca674f46d0644b7e56e4012" - integrity sha512-huKVznyEDZVO7pcYoVZMBR6prkxzkJSTT96T2tyHY1Wk3Sywcpb7NwxHAwKf/fmfqsdFuY2rDRR3UYkY6Uh9LQ== - micromatch@^3.1.10: version "3.1.10" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" @@ -9494,7 +9475,7 @@ scrypt-js@^3.0.0, scrypt-js@^3.0.1: resolved "https://registry.yarnpkg.com/scrypt-js/-/scrypt-js-3.0.1.tgz#d314a57c2aef69d1ad98a138a21fe9eafa9ee312" integrity sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA== -secp256k1@^4.0.1, secp256k1@^4.0.2: +secp256k1@^4.0.1: version "4.0.2" resolved "https://registry.yarnpkg.com/secp256k1/-/secp256k1-4.0.2.tgz#15dd57d0f0b9fdb54ac1fa1694f40e5e9a54f4a1" integrity sha512-UDar4sKvWAksIlfX3xIaQReADn+WFnHvbVujpcbr+9Sf/69odMwy2MUsz5CKLQgX9nsIyrjuxL2imVyoNHa3fg==