Socket
Socket
Sign inDemoInstall

@ethereumjs/util

Package Overview
Dependencies
Maintainers
4
Versions
18
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@ethereumjs/util - npm Package Compare versions

Comparing version 8.1.0 to 9.0.0-rc.1

dist/cjs/account.d.ts

41

package.json
{
"name": "@ethereumjs/util",
"version": "8.1.0",
"version": "9.0.0-rc.1",
"description": "A collection of utility functions for Ethereum",

@@ -64,4 +64,11 @@ "keywords": [

],
"main": "dist/index.js",
"types": "dist/index.d.ts",
"type": "commonjs",
"main": "dist/cjs/index.js",
"module": "dist/esm/index.js",
"exports": {
".": {
"import": "./dist/esm/index.js",
"require": "./dist/cjs/index.js"
}
},
"files": [

@@ -74,4 +81,5 @@ "dist",

"clean": "../../config/cli/clean-package.sh",
"coverage": "../../config/cli/coverage.sh",
"docs:build": "npx typedoc --options typedoc.js",
"coverage": "npx vitest run --coverage.enabled --coverage.reporter=lcov",
"docs:build": "npx typedoc --options typedoc.cjs",
"examples": "ts-node ../../scripts/examples-runner.ts -- util",
"lint": "../../config/cli/lint.sh",

@@ -81,20 +89,23 @@ "lint:diff": "../../config/cli/lint-diff.sh",

"prepublishOnly": "../../config/cli/prepublish.sh",
"tape": "tape -r ts-node/register",
"test": "npm run test:node && npm run test:browser",
"test:browser": "karma start karma.conf.js",
"test:node": "npm run tape -- test/*.spec.ts",
"test:browser": "npx vitest run --config=./vitest.config.browser.ts --browser.name=chrome --browser.headless",
"test:node": "npx vitest run",
"tsc": "../../config/cli/ts-compile.sh"
},
"dependencies": {
"@ethereumjs/rlp": "^4.0.1",
"ethereum-cryptography": "^2.0.0",
"micro-ftch": "^0.3.1"
"@ethereumjs/rlp": "5.0.0-rc.1",
"ethereum-cryptography": "^2.1.2"
},
"devDependencies": {
"@types/bn.js": "^5.1.0",
"@types/secp256k1": "^4.0.1"
"devDependencies": {},
"peerDependencies": {
"c-kzg": "^2.1.0"
},
"peerDependenciesMeta": {
"c-kzg": {
"optional": true
}
},
"engines": {
"node": ">=14"
"node": ">=18"
}
}

@@ -9,4 +9,7 @@ # @ethereumjs/util

A collection of utility functions for Ethereum. It can be used in Node.js and in the browser with [browserify](http://browserify.org/).
Note: this README has been updated containing the changes from our next breaking release round [UNRELEASED] targeted for Summer 2023. See the README files from the [maintenance-v6](https://github.com/ethereumjs/ethereumjs-monorepo/tree/maintenance-v6/) branch for documentation matching our latest releases.
| A collection of utility functions for Ethereum. |
| ----------------------------------------------- |
## Installation

@@ -23,10 +26,15 @@

```js
import assert from 'assert'
import { isValidChecksumAddress, unpadBuffer } from '@ethereumjs/util'
import { hexToBytes, isValidChecksumAddress } from '@ethereumjs/util'
assert.ok(isValidChecksumAddress('0x2F015C60E0be116B1f0CD534704Db9c92118FB6A'))
isValidChecksumAddress('0x2F015C60E0be116B1f0CD534704Db9c92118FB6A') // true
assert.ok(unpadBuffer(Buffer.from('000000006600', 'hex')).equals(Buffer.from('6600', 'hex')))
hexToBytes('0x342770c0')
```
## Browser
With the breaking release round in Summer 2023 we have added hybrid ESM/CJS builds for all our libraries (see section below) and have eliminated many of the caveats which had previously prevented a frictionless browser usage.
It is now easily possible to run a browser build of one of the EthereumJS libraries within a modern browser using the provided ESM build. For a setup example see [./examples/browser.html](./examples/browser.html).
## API

@@ -45,9 +53,18 @@

- Address class and type
- [blobs](src/blobs.ts)
- Helpers for 4844 blobs and versioned hashes
- [bytes](src/bytes.ts)
- Byte-related helper and conversion functions
- [constants](src/constants.ts)
- Exposed constants
- e.g. `KECCAK256_NULL_S` for string representation of Keccak-256 hash of null
- hash
- This module has been removed with `v8`, please use [ethereum-cryptography](https://github.com/ethereum/js-ethereum-cryptography) directly instead
- Exposed constants (e.g. `KECCAK256_NULL_S` for string representation of Keccak-256 hash of null)
- [db](src/db.ts)
- DB interface for database abstraction (Blockchain, Trie)
- [genesis](src/genesis.ts)
- Genesis related interfaces and helpers
- [internal](src/internal.ts)
- Internalized helper methods
- [kzg](src/kzg.ts)
- KZG interface (used for 4844 blob txs)
- [mapDB](src/mapDB.ts)
- Simple map DB implementation using the `DB` interface
- [signature](src/signature.ts)

@@ -57,10 +74,68 @@ - Signing, signature validation, conversion, recovery

- Helpful TypeScript types
- [internal](src/internal.ts)
- Internalized helper methods
- [withdrawal](src/withdrawal.ts)
- Withdrawal class (EIP-4895)
### Upgrade Helpers in bytes-Module
Depending on the extend of `Buffer` usage within your own libraries and other planning considerations, there are the two upgrade options to do the switch to `Uint8Array` yourself or keep `Buffer` and do transitions for input and output values.
We have updated the `@ethereumjs/util` `bytes` module with helpers for the most common conversions:
```typescript
Buffer.alloc(97) // Allocate a Buffer with length 97
new Uint8Array(97) // Allocate a Uint8Array with length 97
Buffer.from('342770c0', 'hex') // Convert a hex string to a Buffer
hexToBytes('0x342770c0') // Convert a prefixed hex string to a Uint8Array, Util.hexToBytes()
`0x${myBuffer.toString('hex')}` // Convert a Buffer to a prefixed hex string
bytesToHex(myUint8Array) // Convert a Uint8Array to a prefixed hex string
intToBuffer(9) // Convert an integer to a Buffer, old (removed)
intToBytes(9) // Convert an integer to a Uint8Array, Util.intToBytes()
bytesToInt(myUint8Array) // Convert a Uint8Array to an integer, Util.bytesToInt()
bigIntToBytes(myBigInt) // Convert a BigInt to a Uint8Array, Util.bigIntToBytes()
bytesToBigInt(myUint8Array) // Convert a Uint8Array to a BigInt, Util.bytesToInt()
utf8ToBytes(myUtf8String) // Converts a UTF-8 string to a Uint8Array, Util.utf8ToBytes()
bytesToUtf8(myUint8Array) // Converts a Uint8Array to a UTF-8 string, Util.bytesToUtf8()
toBuffer(v: ToBufferInputTypes) // Converts various byte compatible types to Buffer, old (removed)
toBytes(v: ToBytesInputTypes) // Converts various byte compatible types to Uint8Array, Util.toBytes()
```
Helper methods can be imported like this:
```typescript
import { hexToBytes } from '@ethereumjs/util'
```
### Hybrid CJS/ESM Builds
With the breaking releases from Summer 2023 we have started to ship our libraries with both CommonJS (`cjs` folder) and ESM builds (`esm` folder), see `package.json` for the detailed setup.
If you use an ES6-style `import` in your code files from the ESM build will be used:
```typescript
import { EthereumJSClass } from '@ethereumjs/[PACKAGE_NAME]'
```
If you use Node.js specific `require` the CJS build will be used:
```typescript
const { EthereumJSClass } = require('@ethereumjs/[PACKAGE_NAME]')
```
Using ESM will give you additional advantages over CJS beyond browser usage like static code analysis / Tree Shaking which CJS can not provide.
### Buffer -> Uint8Array
With the breaking releases from Summer 2023 we have removed all Node.js specific `Buffer` usages from our libraries and replace these with [Uint8Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) representations, which are available both in Node.js and the browser (`Buffer` is a subclass of `Uint8Array`).
We have converted existing Buffer conversion methods to Uint8Array conversion methods in the [@ethereumjs/util](https://github.com/ethereumjs/ethereumjs-monorepo/tree/master/packages/util) `bytes` module, see the respective README section for guidance.
### BigInt Support
Starting with v8 the usage of [BN.js](https://github.com/indutny/bn.js/) for big numbers has been removed from the library and replaced with the usage of the native JS [BigInt](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt) data type (introduced in `ES2020`).
Starting with Util v8 the usage of [BN.js](https://github.com/indutny/bn.js/) for big numbers has been removed from the library and replaced with the usage of the native JS [BigInt](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt) data type (introduced in `ES2020`).

@@ -67,0 +142,0 @@ Please note that number-related API signatures have changed along with this version update and the minimal build target has been updated to `ES2020`.

import { RLP } from '@ethereumjs/rlp'
import { keccak256 } from 'ethereum-cryptography/keccak'
import { secp256k1 } from 'ethereum-cryptography/secp256k1'
import { bytesToHex } from 'ethereum-cryptography/utils'
import { keccak256 } from 'ethereum-cryptography/keccak.js'
import { secp256k1 } from 'ethereum-cryptography/secp256k1.js'
import {
arrToBufArr,
bigIntToUnpaddedBuffer,
bufArrToArr,
bufferToBigInt,
bufferToHex,
toBuffer,
bigIntToUnpaddedBytes,
bytesToBigInt,
bytesToHex,
concatBytes,
equalsBytes,
hexToBytes,
toBytes,
utf8ToBytes,
zeros,
} from './bytes'
import { KECCAK256_NULL, KECCAK256_RLP } from './constants'
import { assertIsBuffer, assertIsHexString, assertIsString } from './helpers'
import { stripHexPrefix } from './internal'
} from './bytes.js'
import { KECCAK256_NULL, KECCAK256_RLP } from './constants.js'
import { assertIsBytes, assertIsHexString, assertIsString } from './helpers.js'
import { stripHexPrefix } from './internal.js'
import type { BigIntLike, BufferLike } from './types'
import type { BigIntLike, BytesLike } from './types.js'

@@ -26,7 +27,7 @@ const _0n = BigInt(0)

balance?: BigIntLike
storageRoot?: BufferLike
codeHash?: BufferLike
storageRoot?: BytesLike
codeHash?: BytesLike
}
export type AccountBodyBuffer = [Buffer, Buffer, Buffer | Uint8Array, Buffer | Uint8Array]
export type AccountBodyBytes = [Uint8Array, Uint8Array, Uint8Array, Uint8Array]

@@ -36,4 +37,4 @@ export class Account {

balance: bigint
storageRoot: Buffer
codeHash: Buffer
storageRoot: Uint8Array
codeHash: Uint8Array

@@ -44,11 +45,11 @@ static fromAccountData(accountData: AccountData) {

return new Account(
nonce !== undefined ? bufferToBigInt(toBuffer(nonce)) : undefined,
balance !== undefined ? bufferToBigInt(toBuffer(balance)) : undefined,
storageRoot !== undefined ? toBuffer(storageRoot) : undefined,
codeHash !== undefined ? toBuffer(codeHash) : undefined
nonce !== undefined ? bytesToBigInt(toBytes(nonce)) : undefined,
balance !== undefined ? bytesToBigInt(toBytes(balance)) : undefined,
storageRoot !== undefined ? toBytes(storageRoot) : undefined,
codeHash !== undefined ? toBytes(codeHash) : undefined
)
}
public static fromRlpSerializedAccount(serialized: Buffer) {
const values = arrToBufArr(RLP.decode(Uint8Array.from(serialized)) as Uint8Array[]) as Buffer[]
public static fromRlpSerializedAccount(serialized: Uint8Array) {
const values = RLP.decode(serialized) as Uint8Array[]

@@ -62,6 +63,6 @@ if (!Array.isArray(values)) {

public static fromValuesArray(values: Buffer[]) {
public static fromValuesArray(values: Uint8Array[]) {
const [nonce, balance, storageRoot, codeHash] = values
return new Account(bufferToBigInt(nonce), bufferToBigInt(balance), storageRoot, codeHash)
return new Account(bytesToBigInt(nonce), bytesToBigInt(balance), storageRoot, codeHash)
}

@@ -98,8 +99,8 @@

/**
* Returns a Buffer Array of the raw Buffers for the account, in order.
* Returns an array of Uint8Arrays of the raw bytes for the account, in order.
*/
raw(): Buffer[] {
raw(): Uint8Array[] {
return [
bigIntToUnpaddedBuffer(this.nonce),
bigIntToUnpaddedBuffer(this.balance),
bigIntToUnpaddedBytes(this.nonce),
bigIntToUnpaddedBytes(this.balance),
this.storageRoot,

@@ -111,6 +112,6 @@ this.codeHash,

/**
* Returns the RLP serialization of the account as a `Buffer`.
* Returns the RLP serialization of the account as a `Uint8Array`.
*/
serialize(): Buffer {
return Buffer.from(RLP.encode(bufArrToArr(this.raw())))
serialize(): Uint8Array {
return RLP.encode(this.raw())
}

@@ -122,3 +123,3 @@

isContract(): boolean {
return !this.codeHash.equals(KECCAK256_NULL)
return !equalsBytes(this.codeHash, KECCAK256_NULL)
}

@@ -132,3 +133,3 @@

isEmpty(): boolean {
return this.balance === _0n && this.nonce === _0n && this.codeHash.equals(KECCAK256_NULL)
return this.balance === _0n && this.nonce === _0n && equalsBytes(this.codeHash, KECCAK256_NULL)
}

@@ -171,8 +172,8 @@ }

if (eip1191ChainId !== undefined) {
const chainId = bufferToBigInt(toBuffer(eip1191ChainId))
const chainId = bytesToBigInt(toBytes(eip1191ChainId))
prefix = chainId.toString() + '0x'
}
const buf = Buffer.from(prefix + address, 'utf8')
const hash = bytesToHex(keccak256(buf))
const bytes = utf8ToBytes(prefix + address)
const hash = bytesToHex(keccak256(bytes)).slice(2)
let ret = '0x'

@@ -208,14 +209,14 @@

*/
export const generateAddress = function (from: Buffer, nonce: Buffer): Buffer {
assertIsBuffer(from)
assertIsBuffer(nonce)
export const generateAddress = function (from: Uint8Array, nonce: Uint8Array): Uint8Array {
assertIsBytes(from)
assertIsBytes(nonce)
if (bufferToBigInt(nonce) === BigInt(0)) {
if (bytesToBigInt(nonce) === BigInt(0)) {
// in RLP we want to encode null in the case of zero nonce
// read the RLP documentation for an answer if you dare
return Buffer.from(keccak256(RLP.encode(bufArrToArr([from, null] as any)))).slice(-20)
return keccak256(RLP.encode([from, Uint8Array.from([])])).subarray(-20)
}
// Only take the lower 160bits of the hash
return Buffer.from(keccak256(RLP.encode(bufArrToArr([from, nonce])))).slice(-20)
return keccak256(RLP.encode([from, nonce])).subarray(-20)
}

@@ -229,6 +230,10 @@

*/
export const generateAddress2 = function (from: Buffer, salt: Buffer, initCode: Buffer): Buffer {
assertIsBuffer(from)
assertIsBuffer(salt)
assertIsBuffer(initCode)
export const generateAddress2 = function (
from: Uint8Array,
salt: Uint8Array,
initCode: Uint8Array
): Uint8Array {
assertIsBytes(from)
assertIsBytes(salt)
assertIsBytes(initCode)

@@ -242,7 +247,5 @@ if (from.length !== 20) {

const address = keccak256(
Buffer.concat([Buffer.from('ff', 'hex'), from, salt, keccak256(initCode)])
)
const address = keccak256(concatBytes(hexToBytes('0xff'), from, salt, keccak256(initCode)))
return toBuffer(address).slice(-20)
return address.subarray(-20)
}

@@ -253,3 +256,3 @@

*/
export const isValidPrivate = function (privateKey: Buffer): boolean {
export const isValidPrivate = function (privateKey: Uint8Array): boolean {
return secp256k1.utils.isValidPrivateKey(privateKey)

@@ -264,4 +267,4 @@ }

*/
export const isValidPublic = function (publicKey: Buffer, sanitize: boolean = false): boolean {
assertIsBuffer(publicKey)
export const isValidPublic = function (publicKey: Uint8Array, sanitize: boolean = false): boolean {
assertIsBytes(publicKey)
if (publicKey.length === 64) {

@@ -271,3 +274,3 @@ // Convert to SEC1 for secp256k1

try {
secp256k1.ProjectivePoint.fromHex(Buffer.concat([Buffer.from([4]), publicKey]))
secp256k1.ProjectivePoint.fromHex(concatBytes(Uint8Array.from([4]), publicKey))
return true

@@ -297,6 +300,6 @@ } catch (e) {

*/
export const pubToAddress = function (pubKey: Buffer, sanitize: boolean = false): Buffer {
assertIsBuffer(pubKey)
export const pubToAddress = function (pubKey: Uint8Array, sanitize: boolean = false): Uint8Array {
assertIsBytes(pubKey)
if (sanitize && pubKey.length !== 64) {
pubKey = Buffer.from(secp256k1.ProjectivePoint.fromHex(pubKey).toRawBytes(false).slice(1))
pubKey = secp256k1.ProjectivePoint.fromHex(pubKey).toRawBytes(false).slice(1)
}

@@ -307,3 +310,3 @@ if (pubKey.length !== 64) {

// Only take the lower 160bits of the hash
return Buffer.from(keccak256(pubKey)).slice(-20)
return keccak256(pubKey).subarray(-20)
}

@@ -316,8 +319,6 @@ export const publicToAddress = pubToAddress

*/
export const privateToPublic = function (privateKey: Buffer): Buffer {
assertIsBuffer(privateKey)
export const privateToPublic = function (privateKey: Uint8Array): Uint8Array {
assertIsBytes(privateKey)
// skip the type flag and use the X, Y points
return Buffer.from(
secp256k1.ProjectivePoint.fromPrivateKey(privateKey).toRawBytes(false).slice(1)
)
return secp256k1.ProjectivePoint.fromPrivateKey(privateKey).toRawBytes(false).slice(1)
}

@@ -329,3 +330,3 @@

*/
export const privateToAddress = function (privateKey: Buffer): Buffer {
export const privateToAddress = function (privateKey: Uint8Array): Uint8Array {
return publicToAddress(privateToPublic(privateKey))

@@ -337,6 +338,6 @@ }

*/
export const importPublic = function (publicKey: Buffer): Buffer {
assertIsBuffer(publicKey)
export const importPublic = function (publicKey: Uint8Array): Uint8Array {
assertIsBytes(publicKey)
if (publicKey.length !== 64) {
publicKey = Buffer.from(secp256k1.ProjectivePoint.fromHex(publicKey).toRawBytes(false).slice(1))
publicKey = secp256k1.ProjectivePoint.fromHex(publicKey).toRawBytes(false).slice(1)
}

@@ -352,3 +353,3 @@ return publicKey

const addr = zeros(addressLength)
return bufferToHex(addr)
return bytesToHex(addr)
}

@@ -370,3 +371,3 @@

export function accountBodyFromSlim(body: AccountBodyBuffer) {
export function accountBodyFromSlim(body: AccountBodyBytes) {
const [nonce, balance, storageRoot, codeHash] = body

@@ -376,4 +377,4 @@ return [

balance,
arrToBufArr(storageRoot).length === 0 ? KECCAK256_RLP : storageRoot,
arrToBufArr(codeHash).length === 0 ? KECCAK256_NULL : codeHash,
storageRoot.length === 0 ? KECCAK256_RLP : storageRoot,
codeHash.length === 0 ? KECCAK256_NULL : codeHash,
]

@@ -383,3 +384,3 @@ }

const emptyUint8Arr = new Uint8Array(0)
export function accountBodyToSlim(body: AccountBodyBuffer) {
export function accountBodyToSlim(body: AccountBodyBytes) {
const [nonce, balance, storageRoot, codeHash] = body

@@ -389,4 +390,4 @@ return [

balance,
arrToBufArr(storageRoot).equals(KECCAK256_RLP) ? emptyUint8Arr : storageRoot,
arrToBufArr(codeHash).equals(KECCAK256_NULL) ? emptyUint8Arr : codeHash,
equalsBytes(storageRoot, KECCAK256_RLP) ? emptyUint8Arr : storageRoot,
equalsBytes(codeHash, KECCAK256_NULL) ? emptyUint8Arr : codeHash,
]

@@ -397,8 +398,8 @@ }

* Converts a slim account (per snap protocol spec) to the RLP encoded version of the account
* @param body Array of 4 Buffer-like items to represent the account
* @param body Array of 4 Uint8Array-like items to represent the account
* @returns RLP encoded version of the account
*/
export function accountBodyToRLP(body: AccountBodyBuffer, couldBeSlim = true) {
export function accountBodyToRLP(body: AccountBodyBytes, couldBeSlim = true) {
const accountBody = couldBeSlim ? accountBodyFromSlim(body) : body
return arrToBufArr(RLP.encode(accountBody))
return RLP.encode(accountBody)
}

@@ -7,4 +7,4 @@ import {

pubToAddress,
} from './account'
import { bigIntToBuffer, bufferToBigInt, toBuffer, zeros } from './bytes'
} from './account.js'
import { bigIntToBytes, bytesToBigInt, bytesToHex, equalsBytes, toBytes, zeros } from './bytes.js'

@@ -15,9 +15,9 @@ /**

export class Address {
public readonly buf: Buffer
public readonly bytes: Uint8Array
constructor(buf: Buffer) {
if (buf.length !== 20) {
constructor(bytes: Uint8Array) {
if (bytes.length !== 20) {
throw new Error('Invalid address length')
}
this.buf = buf
this.bytes = bytes
}

@@ -40,3 +40,3 @@

}
return new Address(toBuffer(str))
return new Address(toBytes(str))
}

@@ -48,8 +48,8 @@

*/
static fromPublicKey(pubKey: Buffer): Address {
if (!Buffer.isBuffer(pubKey)) {
throw new Error('Public key should be Buffer')
static fromPublicKey(pubKey: Uint8Array): Address {
if (!(pubKey instanceof Uint8Array)) {
throw new Error('Public key should be Uint8Array')
}
const buf = pubToAddress(pubKey)
return new Address(buf)
const bytes = pubToAddress(pubKey)
return new Address(bytes)
}

@@ -61,8 +61,8 @@

*/
static fromPrivateKey(privateKey: Buffer): Address {
if (!Buffer.isBuffer(privateKey)) {
throw new Error('Private key should be Buffer')
static fromPrivateKey(privateKey: Uint8Array): Address {
if (!(privateKey instanceof Uint8Array)) {
throw new Error('Private key should be Uint8Array')
}
const buf = privateToAddress(privateKey)
return new Address(buf)
const bytes = privateToAddress(privateKey)
return new Address(bytes)
}

@@ -79,3 +79,3 @@

}
return new Address(generateAddress(from.buf, bigIntToBuffer(nonce)))
return new Address(generateAddress(from.bytes, bigIntToBytes(nonce)))
}

@@ -89,10 +89,10 @@

*/
static generate2(from: Address, salt: Buffer, initCode: Buffer): Address {
if (!Buffer.isBuffer(salt)) {
throw new Error('Expected salt to be a Buffer')
static generate2(from: Address, salt: Uint8Array, initCode: Uint8Array): Address {
if (!(salt instanceof Uint8Array)) {
throw new Error('Expected salt to be a Uint8Array')
}
if (!Buffer.isBuffer(initCode)) {
throw new Error('Expected initCode to be a Buffer')
if (!(initCode instanceof Uint8Array)) {
throw new Error('Expected initCode to be a Uint8Array')
}
return new Address(generateAddress2(from.buf, salt, initCode))
return new Address(generateAddress2(from.bytes, salt, initCode))
}

@@ -104,3 +104,3 @@

equals(address: Address): boolean {
return this.buf.equals(address.buf)
return equalsBytes(this.bytes, address.bytes)
}

@@ -120,3 +120,3 @@

isPrecompileOrSystemAddress(): boolean {
const address = bufferToBigInt(this.buf)
const address = bytesToBigInt(this.bytes)
const rangeMin = BigInt(0)

@@ -131,11 +131,11 @@ const rangeMax = BigInt('0xffff')

toString(): string {
return '0x' + this.buf.toString('hex')
return bytesToHex(this.bytes)
}
/**
* Returns Buffer representation of address.
* Returns a new Uint8Array representation of address.
*/
toBuffer(): Buffer {
return Buffer.from(this.buf)
toBytes(): Uint8Array {
return new Uint8Array(this.bytes)
}
}

@@ -1,18 +0,99 @@

import { assertIsArray, assertIsBuffer, assertIsHexString } from './helpers'
import { isHexPrefixed, isHexString, padToEven, stripHexPrefix } from './internal'
import { getRandomBytesSync } from 'ethereum-cryptography/random.js'
// eslint-disable-next-line no-restricted-imports
import {
bytesToHex as _bytesToUnprefixedHex,
hexToBytes as _unprefixedHexToBytes,
} from 'ethereum-cryptography/utils.js'
import type {
NestedBufferArray,
NestedUint8Array,
PrefixedHexString,
TransformableToArray,
TransformableToBuffer,
} from './types'
import { assertIsArray, assertIsBytes, assertIsHexString } from './helpers.js'
import { isHexPrefixed, isHexString, padToEven, stripHexPrefix } from './internal.js'
import type { PrefixedHexString, TransformabletoBytes } from './types.js'
/**
* Converts a `Number` into a hex `String`
* @param {Number} i
* @return {String}
* @deprecated
*/
export const intToHex = function (i: number) {
export const bytesToUnprefixedHex = _bytesToUnprefixedHex
/**
* @deprecated
*/
export const unprefixedHexToBytes = (inp: string) => {
if (inp.slice(0, 2) === '0x') {
throw new Error('hex string is prefixed with 0x, should be unprefixed')
} else {
return _unprefixedHexToBytes(padToEven(inp))
}
}
/**************** Borrowed from @chainsafe/ssz */
// Caching this info costs about ~1000 bytes and speeds up toHexString() by x6
const hexByByte = Array.from({ length: 256 }, (v, i) => i.toString(16).padStart(2, '0'))
export const bytesToHex = (bytes: Uint8Array): string => {
let hex = '0x'
if (bytes === undefined || bytes.length === 0) return hex
for (const byte of bytes) {
hex += hexByByte[byte]
}
return hex
}
/**
* Converts a {@link Uint8Array} to a {@link bigint}
* @param {Uint8Array} bytes the bytes to convert
* @returns {bigint}
*/
export const bytesToBigInt = (bytes: Uint8Array): bigint => {
const hex = bytesToHex(bytes)
if (hex === '0x') {
return BigInt(0)
}
return BigInt(hex)
}
/**
* Converts a {@link Uint8Array} to a {@link number}.
* @param {Uint8Array} bytes the bytes to convert
* @return {number}
* @throws If the input number exceeds 53 bits.
*/
export const bytesToInt = (bytes: Uint8Array): number => {
const res = Number(bytesToBigInt(bytes))
if (!Number.isSafeInteger(res)) throw new Error('Number exceeds 53 bits')
return res
}
export const hexToBytes = (hex: string): Uint8Array => {
if (typeof hex !== 'string') {
throw new Error(`hex argument type ${typeof hex} must be of type string`)
}
if (!hex.startsWith('0x')) {
throw new Error(`prefixed hex input should start with 0x, got ${hex.substring(0, 2)}`)
}
hex = hex.slice(2)
if (hex.length % 2 !== 0) {
hex = padToEven(hex)
}
const byteLen = hex.length / 2
const bytes = new Uint8Array(byteLen)
for (let i = 0; i < byteLen; i++) {
const byte = parseInt(hex.slice(i * 2, (i + 1) * 2), 16)
bytes[i] = byte
}
return bytes
}
/******************************************/
/**
* Converts a {@link number} into a {@link PrefixedHexString}
* @param {number} i
* @return {PrefixedHexString}
*/
export const intToHex = (i: number): PrefixedHexString => {
if (!Number.isSafeInteger(i) || i < 0) {

@@ -25,41 +106,49 @@ throw new Error(`Received an invalid integer type: ${i}`)

/**
* Converts an `Number` to a `Buffer`
* Converts an {@link number} to a {@link Uint8Array}
* @param {Number} i
* @return {Buffer}
* @return {Uint8Array}
*/
export const intToBuffer = function (i: number) {
export const intToBytes = (i: number): Uint8Array => {
const hex = intToHex(i)
return Buffer.from(padToEven(hex.slice(2)), 'hex')
return hexToBytes(hex)
}
/**
* Returns a buffer filled with 0s.
* @param bytes the number of bytes the buffer should be
* Converts a {@link bigint} to a {@link Uint8Array}
* * @param {bigint} num the bigint to convert
* @returns {Uint8Array}
*/
export const zeros = function (bytes: number): Buffer {
return Buffer.allocUnsafe(bytes).fill(0)
export const bigIntToBytes = (num: bigint): Uint8Array => {
// eslint-disable-next-line @typescript-eslint/no-use-before-define
return toBytes('0x' + padToEven(num.toString(16)))
}
/**
* Pads a `Buffer` with zeros till it has `length` bytes.
* Returns a Uint8Array filled with 0s.
* @param {number} bytes the number of bytes of the Uint8Array
* @return {Uint8Array}
*/
export const zeros = (bytes: number): Uint8Array => {
return new Uint8Array(bytes)
}
/**
* Pads a `Uint8Array` with zeros till it has `length` bytes.
* Truncates the beginning or end of input if its length exceeds `length`.
* @param msg the value to pad (Buffer)
* @param length the number of bytes the output should be
* @param right whether to start padding form the left or right
* @return (Buffer)
* @param {Uint8Array} msg the value to pad
* @param {number} length the number of bytes the output should be
* @param {boolean} right whether to start padding form the left or right
* @return {Uint8Array}
*/
const setLength = function (msg: Buffer, length: number, right: boolean) {
const buf = zeros(length)
const setLength = (msg: Uint8Array, length: number, right: boolean): Uint8Array => {
if (right) {
if (msg.length < length) {
msg.copy(buf)
return buf
return new Uint8Array([...msg, ...zeros(length - msg.length)])
}
return msg.slice(0, length)
return msg.subarray(0, length)
} else {
if (msg.length < length) {
msg.copy(buf, length - msg.length)
return buf
return new Uint8Array([...zeros(length - msg.length), ...msg])
}
return msg.slice(-length)
return msg.subarray(-length)
}

@@ -69,10 +158,10 @@ }

/**
* Left Pads a `Buffer` with leading zeros till it has `length` bytes.
* Left Pads a `Uint8Array` with leading zeros till it has `length` bytes.
* Or it truncates the beginning if it exceeds.
* @param msg the value to pad (Buffer)
* @param length the number of bytes the output should be
* @return (Buffer)
* @param {Uint8Array} msg the value to pad
* @param {number} length the number of bytes the output should be
* @return {Uint8Array}
*/
export const setLengthLeft = function (msg: Buffer, length: number) {
assertIsBuffer(msg)
export const setLengthLeft = (msg: Uint8Array, length: number): Uint8Array => {
assertIsBytes(msg)
return setLength(msg, length, false)

@@ -82,10 +171,10 @@ }

/**
* Right Pads a `Buffer` with trailing zeros till it has `length` bytes.
* Right Pads a `Uint8Array` with trailing zeros till it has `length` bytes.
* it truncates the end if it exceeds.
* @param msg the value to pad (Buffer)
* @param length the number of bytes the output should be
* @return (Buffer)
* @param {Uint8Array} msg the value to pad
* @param {number} length the number of bytes the output should be
* @return {Uint8Array}
*/
export const setLengthRight = function (msg: Buffer, length: number) {
assertIsBuffer(msg)
export const setLengthRight = (msg: Uint8Array, length: number): Uint8Array => {
assertIsBytes(msg)
return setLength(msg, length, true)

@@ -95,10 +184,14 @@ }

/**
* Trims leading zeros from a `Buffer`, `String` or `Number[]`.
* @param a (Buffer|Array|String)
* @return (Buffer|Array|String)
* Trims leading zeros from a `Uint8Array`, `number[]` or PrefixedHexString`.
* @param {Uint8Array|number[]|PrefixedHexString} a
* @return {Uint8Array|number[]|PrefixedHexString}
*/
const stripZeros = function (a: any): Buffer | number[] | string {
const stripZeros = <
T extends Uint8Array | number[] | PrefixedHexString = Uint8Array | number[] | PrefixedHexString
>(
a: T
): T => {
let first = a[0]
while (a.length > 0 && first.toString() === '0') {
a = a.slice(1)
a = a.slice(1) as T
first = a[0]

@@ -110,9 +203,9 @@ }

/**
* Trims leading zeros from a `Buffer`.
* @param a (Buffer)
* @return (Buffer)
* Trims leading zeros from a `Uint8Array`.
* @param {Uint8Array} a
* @return {Uint8Array}
*/
export const unpadBuffer = function (a: Buffer): Buffer {
assertIsBuffer(a)
return stripZeros(a) as Buffer
export const unpadBytes = (a: Uint8Array): Uint8Array => {
assertIsBytes(a)
return stripZeros(a)
}

@@ -122,30 +215,28 @@

* Trims leading zeros from an `Array` (of numbers).
* @param a (number[])
* @return (number[])
* @param {number[]} a
* @return {number[]}
*/
export const unpadArray = function (a: number[]): number[] {
export const unpadArray = (a: number[]): number[] => {
assertIsArray(a)
return stripZeros(a) as number[]
return stripZeros(a)
}
/**
* Trims leading zeros from a hex-prefixed `String`.
* @param a (String)
* @return (String)
* Trims leading zeros from a `PrefixedHexString`.
* @param {PrefixedHexString} a
* @return {PrefixedHexString}
*/
export const unpadHexString = function (a: string): string {
export const unpadHex = (a: string): PrefixedHexString => {
assertIsHexString(a)
a = stripHexPrefix(a)
return ('0x' + stripZeros(a)) as string
return '0x' + stripZeros(a)
}
export type ToBufferInputTypes =
export type ToBytesInputTypes =
| PrefixedHexString
| number
| bigint
| Buffer
| Uint8Array
| number[]
| TransformableToArray
| TransformableToBuffer
| TransformabletoBytes
| null

@@ -155,18 +246,16 @@ | undefined

/**
* Attempts to turn a value into a `Buffer`.
* Inputs supported: `Buffer`, `String` (hex-prefixed), `Number`, null/undefined, `BigInt` and other objects
* with a `toArray()` or `toBuffer()` method.
* @param v the value
* Attempts to turn a value into a `Uint8Array`.
* Inputs supported: `Buffer`, `Uint8Array`, `String` (hex-prefixed), `Number`, null/undefined, `BigInt` and other objects
* with a `toArray()` or `toBytes()` method.
* @param {ToBytesInputTypes} v the value
* @return {Uint8Array}
*/
export const toBuffer = function (v: ToBufferInputTypes): Buffer {
export const toBytes = (v: ToBytesInputTypes): Uint8Array => {
if (v === null || v === undefined) {
return Buffer.allocUnsafe(0)
return new Uint8Array()
}
if (Buffer.isBuffer(v)) {
return Buffer.from(v)
}
if (Array.isArray(v) || v instanceof Uint8Array) {
return Buffer.from(v as Uint8Array)
return Uint8Array.from(v)
}

@@ -177,10 +266,10 @@

throw new Error(
`Cannot convert string to buffer. toBuffer only supports 0x-prefixed hex strings and this string was given: ${v}`
`Cannot convert string to Uint8Array. toBytes only supports 0x-prefixed hex strings and this string was given: ${v}`
)
}
return Buffer.from(padToEven(stripHexPrefix(v)), 'hex')
return hexToBytes(v)
}
if (typeof v === 'number') {
return intToBuffer(v)
return intToBytes(v)
}

@@ -190,18 +279,14 @@

if (v < BigInt(0)) {
throw new Error(`Cannot convert negative bigint to buffer. Given: ${v}`)
throw new Error(`Cannot convert negative bigint to Uint8Array. Given: ${v}`)
}
let n = v.toString(16)
if (n.length % 2) n = '0' + n
return Buffer.from(n, 'hex')
return unprefixedHexToBytes(n)
}
if (v.toArray) {
// converts a BN to a Buffer
return Buffer.from(v.toArray())
if (v.toBytes !== undefined) {
// converts a `TransformableToBytes` object to a Uint8Array
return v.toBytes()
}
if (v.toBuffer) {
return Buffer.from(v.toBuffer())
}
throw new Error('invalid type')

@@ -211,59 +296,25 @@ }

/**
* Converts a `Buffer` into a `0x`-prefixed hex `String`.
* @param buf `Buffer` object to convert
* Interprets a `Uint8Array` as a signed integer and returns a `BigInt`. Assumes 256-bit numbers.
* @param {Uint8Array} num Signed integer value
* @returns {bigint}
*/
export const bufferToHex = function (buf: Buffer): string {
buf = toBuffer(buf)
return '0x' + buf.toString('hex')
export const fromSigned = (num: Uint8Array): bigint => {
return BigInt.asIntN(256, bytesToBigInt(num))
}
/**
* Converts a {@link Buffer} to a {@link bigint}
* Converts a `BigInt` to an unsigned integer and returns it as a `Uint8Array`. Assumes 256-bit numbers.
* @param {bigint} num
* @returns {Uint8Array}
*/
export function bufferToBigInt(buf: Buffer) {
const hex = bufferToHex(buf)
if (hex === '0x') {
return BigInt(0)
}
return BigInt(hex)
export const toUnsigned = (num: bigint): Uint8Array => {
return bigIntToBytes(BigInt.asUintN(256, num))
}
/**
* Converts a {@link bigint} to a {@link Buffer}
* Adds "0x" to a given `string` if it does not already start with "0x".
* @param {string} str
* @return {PrefixedHexString}
*/
export function bigIntToBuffer(num: bigint) {
return toBuffer('0x' + num.toString(16))
}
/**
* Converts a `Buffer` to a `Number`.
* @param buf `Buffer` object to convert
* @throws If the input number exceeds 53 bits.
*/
export const bufferToInt = function (buf: Buffer): number {
const res = Number(bufferToBigInt(buf))
if (!Number.isSafeInteger(res)) throw new Error('Number exceeds 53 bits')
return res
}
/**
* Interprets a `Buffer` as a signed integer and returns a `BigInt`. Assumes 256-bit numbers.
* @param num Signed integer value
*/
export const fromSigned = function (num: Buffer): bigint {
return BigInt.asIntN(256, bufferToBigInt(num))
}
/**
* Converts a `BigInt` to an unsigned integer and returns it as a `Buffer`. Assumes 256-bit numbers.
* @param num
*/
export const toUnsigned = function (num: bigint): Buffer {
return bigIntToBuffer(BigInt.asUintN(256, num))
}
/**
* Adds "0x" to a given `String` if it does not already start with "0x".
*/
export const addHexPrefix = function (str: string): string {
export const addHexPrefix = (str: string): PrefixedHexString => {
if (typeof str !== 'string') {

@@ -277,3 +328,3 @@ return str

/**
* Shortens a string or buffer's hex string representation to maxLength (default 50).
* Shortens a string or Uint8Array's hex string representation to maxLength (default 50).
*

@@ -284,61 +335,20 @@ * Examples:

* Output: '657468657265756d0000000000000000000000000000000000…'
* @param {Uint8Array | string} bytes
* @param {number} maxLength
* @return {string}
*/
export function short(buffer: Buffer | string, maxLength: number = 50): string {
const bufferStr = Buffer.isBuffer(buffer) ? buffer.toString('hex') : buffer
if (bufferStr.length <= maxLength) {
return bufferStr
export const short = (bytes: Uint8Array | string, maxLength: number = 50): string => {
const byteStr = bytes instanceof Uint8Array ? bytesToHex(bytes) : bytes
const len = byteStr.slice(0, 2) === '0x' ? maxLength + 2 : maxLength
if (byteStr.length <= len) {
return byteStr
}
return bufferStr.slice(0, maxLength) + '…'
return byteStr.slice(0, len) + '…'
}
/**
* Returns the utf8 string representation from a hex string.
* Checks provided Uint8Array for leading zeroes and throws if found.
*
* Examples:
*
* Input 1: '657468657265756d000000000000000000000000000000000000000000000000'
* Input 2: '657468657265756d'
* Input 3: '000000000000000000000000000000000000000000000000657468657265756d'
*
* Output (all 3 input variants): 'ethereum'
*
* Note that this method is not intended to be used with hex strings
* representing quantities in both big endian or little endian notation.
*
* @param string Hex string, should be `0x` prefixed
* @return Utf8 string
*/
export const toUtf8 = function (hex: string): string {
const zerosRegexp = /^(00)+|(00)+$/g
hex = stripHexPrefix(hex)
if (hex.length % 2 !== 0) {
throw new Error('Invalid non-even hex string input for toUtf8() provided')
}
const bufferVal = Buffer.from(hex.replace(zerosRegexp, ''), 'hex')
return bufferVal.toString('utf8')
}
/**
* Converts a `Buffer` or `Array` to JSON.
* @param ba (Buffer|Array)
* @return (Array|String|null)
*/
export const baToJSON = function (ba: any): any {
if (Buffer.isBuffer(ba)) {
return `0x${ba.toString('hex')}`
} else if (ba instanceof Array) {
const array = []
for (let i = 0; i < ba.length; i++) {
array.push(baToJSON(ba[i]))
}
return array
}
}
/**
* Checks provided Buffers for leading zeroes and throws if found.
*
* Examples:
*
* Valid values: 0x1, 0x, 0x01, 0x1234

@@ -349,9 +359,9 @@ * Invalid values: 0x0, 0x00, 0x001, 0x0001

* integer values encoded to RLP must be in the most compact form and contain no leading zero bytes
* @param values An object containing string keys and Buffer values
* @param values An object containing string keys and Uint8Array values
* @throws if any provided value is found to have leading zero bytes
*/
export const validateNoLeadingZeroes = function (values: { [key: string]: Buffer | undefined }) {
export const validateNoLeadingZeroes = (values: { [key: string]: Uint8Array | undefined }) => {
for (const [k, v] of Object.entries(values)) {
if (v !== undefined && v.length > 0 && v[0] === 0) {
throw new Error(`${k} cannot have leading zeroes, received: ${v.toString('hex')}`)
throw new Error(`${k} cannot have leading zeroes, received: ${bytesToHex(v)}`)
}

@@ -362,45 +372,76 @@ }

/**
* Converts a {@link Uint8Array} or {@link NestedUint8Array} to {@link Buffer} or {@link NestedBufferArray}
* Converts a {@link bigint} to a `0x` prefixed hex string
* @param {bigint} num the bigint to convert
* @returns {PrefixedHexString}
*/
export function arrToBufArr(arr: Uint8Array): Buffer
export function arrToBufArr(arr: NestedUint8Array): NestedBufferArray
export function arrToBufArr(arr: Uint8Array | NestedUint8Array): Buffer | NestedBufferArray
export function arrToBufArr(arr: Uint8Array | NestedUint8Array): Buffer | NestedBufferArray {
if (!Array.isArray(arr)) {
return Buffer.from(arr)
}
return arr.map((a) => arrToBufArr(a))
export const bigIntToHex = (num: bigint): PrefixedHexString => {
return '0x' + num.toString(16)
}
/**
* Converts a {@link Buffer} or {@link NestedBufferArray} to {@link Uint8Array} or {@link NestedUint8Array}
* Convert value from bigint to an unpadded Uint8Array
* (useful for RLP transport)
* @param {bigint} value the bigint to convert
* @returns {Uint8Array}
*/
export function bufArrToArr(arr: Buffer): Uint8Array
export function bufArrToArr(arr: NestedBufferArray): NestedUint8Array
export function bufArrToArr(arr: Buffer | NestedBufferArray): Uint8Array | NestedUint8Array
export function bufArrToArr(arr: Buffer | NestedBufferArray): Uint8Array | NestedUint8Array {
if (!Array.isArray(arr)) {
return Uint8Array.from(arr ?? [])
}
return arr.map((a) => bufArrToArr(a))
export const bigIntToUnpaddedBytes = (value: bigint): Uint8Array => {
return unpadBytes(bigIntToBytes(value))
}
/**
* Converts a {@link bigint} to a `0x` prefixed hex string
* Convert value from number to an unpadded Uint8Array
* (useful for RLP transport)
* @param {number} value the bigint to convert
* @returns {Uint8Array}
*/
export const bigIntToHex = (num: bigint) => {
return '0x' + num.toString(16)
export const intToUnpaddedBytes = (value: number): Uint8Array => {
return unpadBytes(intToBytes(value))
}
/**
* Convert value from bigint to an unpadded Buffer
* (useful for RLP transport)
* @param value value to convert
* Compares two Uint8Arrays and returns a number indicating their order in a sorted array.
*
* @param {Uint8Array} value1 - The first Uint8Array to compare.
* @param {Uint8Array} value2 - The second Uint8Array to compare.
* @returns {number} A positive number if value1 is larger than value2,
* A negative number if value1 is smaller than value2,
* or 0 if value1 and value2 are equal.
*/
export function bigIntToUnpaddedBuffer(value: bigint): Buffer {
return unpadBuffer(bigIntToBuffer(value))
export const compareBytes = (value1: Uint8Array, value2: Uint8Array): number => {
const bigIntValue1 = bytesToBigInt(value1)
const bigIntValue2 = bytesToBigInt(value2)
return bigIntValue1 > bigIntValue2 ? 1 : bigIntValue1 < bigIntValue2 ? -1 : 0
}
export function intToUnpaddedBuffer(value: number): Buffer {
return unpadBuffer(intToBuffer(value))
/**
* Generates a Uint8Array of random bytes of specified length.
*
* @param {number} length - The length of the Uint8Array.
* @returns {Uint8Array} A Uint8Array of random bytes of specified length.
*/
export const randomBytes = (length: number): Uint8Array => {
return getRandomBytesSync(length)
}
/**
* This mirrors the functionality of the `ethereum-cryptography` export except
* it skips the check to validate that every element of `arrays` is indead a `uint8Array`
* Can give small performance gains on large arrays
* @param {Uint8Array[]} arrays an array of Uint8Arrays
* @returns {Uint8Array} one Uint8Array with all the elements of the original set
* works like `Buffer.concat`
*/
export const concatBytes = (...arrays: Uint8Array[]): Uint8Array => {
if (arrays.length === 1) return arrays[0]
const length = arrays.reduce((a, arr) => a + arr.length, 0)
const result = new Uint8Array(length)
for (let i = 0, pad = 0; i < arrays.length; i++) {
const arr = arrays[i]
result.set(arr, pad)
pad += arr.length
}
return result
}
// eslint-disable-next-line no-restricted-imports
export { bytesToUtf8, equalsBytes, utf8ToBytes } from 'ethereum-cryptography/utils.js'

@@ -1,4 +0,5 @@

import { Buffer } from 'buffer'
import { secp256k1 } from 'ethereum-cryptography/secp256k1'
import { secp256k1 } from 'ethereum-cryptography/secp256k1.js'
import { hexToBytes } from './bytes.js'
/**

@@ -38,3 +39,3 @@ * 2^64-1

*/
export const KECCAK256_NULL_S = 'c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470'
export const KECCAK256_NULL_S = '0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470'

@@ -44,3 +45,3 @@ /**

*/
export const KECCAK256_NULL = Buffer.from(KECCAK256_NULL_S, 'hex')
export const KECCAK256_NULL = hexToBytes(KECCAK256_NULL_S)

@@ -51,3 +52,3 @@ /**

export const KECCAK256_RLP_ARRAY_S =
'1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347'
'0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347'

@@ -57,3 +58,3 @@ /**

*/
export const KECCAK256_RLP_ARRAY = Buffer.from(KECCAK256_RLP_ARRAY_S, 'hex')
export const KECCAK256_RLP_ARRAY = hexToBytes(KECCAK256_RLP_ARRAY_S)

@@ -63,3 +64,3 @@ /**

*/
export const KECCAK256_RLP_S = '56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421'
export const KECCAK256_RLP_S = '0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421'

@@ -69,3 +70,3 @@ /**

*/
export const KECCAK256_RLP = Buffer.from(KECCAK256_RLP_S, 'hex')
export const KECCAK256_RLP = hexToBytes(KECCAK256_RLP_S)

@@ -75,4 +76,6 @@ /**

*/
export const RLP_EMPTY_STRING = Buffer.from([0x80])
export const RLP_EMPTY_STRING = Uint8Array.from([0x80])
export const MAX_WITHDRAWALS_PER_PAYLOAD = 16
export const RIPEMD160_ADDRESS_STRING = '0000000000000000000000000000000000000003'

@@ -1,2 +0,2 @@

import { isHexString } from './internal'
import { isHexString } from './internal.js'

@@ -18,5 +18,5 @@ /**

*/
export const assertIsBuffer = function (input: Buffer): void {
if (!Buffer.isBuffer(input)) {
const msg = `This method only supports Buffer but input was: ${input}`
export const assertIsBytes = function (input: Uint8Array): void {
if (!(input instanceof Uint8Array)) {
const msg = `This method only supports Uint8Array but input was: ${input}`
throw new Error(msg)

@@ -23,0 +23,0 @@ }

/**
* Constants
*/
export * from './constants'
export * from './constants.js'

@@ -9,3 +9,3 @@ /**

*/
export * from './units'
export * from './units.js'

@@ -15,3 +15,3 @@ /**

*/
export * from './account'
export * from './account.js'

@@ -21,8 +21,13 @@ /**

*/
export * from './address'
export * from './address.js'
/**
* DB type
*/
export * from './db.js'
/**
* Withdrawal type
*/
export * from './withdrawal'
export * from './withdrawal.js'

@@ -32,8 +37,8 @@ /**

*/
export * from './signature'
export * from './signature.js'
/**
* Utilities for manipulating Buffers, byte arrays, etc.
* Utilities for manipulating bytes, Uint8Arrays, etc.
*/
export * from './bytes'
export * from './bytes.js'

@@ -43,13 +48,10 @@ /**

*/
export * from './types'
export * from './types.js'
/**
* Helper function for working with compact encoding
*/
export * from './encoding'
/**
* Export ethjs-util methods
*/
export * from './asyncEventEmitter'
export * from './asyncEventEmitter.js'
export * from './blobs.js'
export * from './genesis.js'
export {

@@ -66,4 +68,6 @@ arrayContainsArray,

toAscii,
} from './internal'
export * from './lock'
export * from './provider'
} from './internal.js'
export * from './kzg.js'
export * from './lock.js'
export * from './mapDB.js'
export * from './provider.js'

@@ -25,2 +25,4 @@ /*

import { bytesToHex, utf8ToBytes } from './bytes.js'
/**

@@ -79,3 +81,3 @@ * Returns a `Boolean` on whether or not the a `String` starts with '0x'

return Buffer.byteLength(str, 'utf8')
return utf8ToBytes(str).byteLength
}

@@ -139,5 +141,5 @@

export function fromUtf8(stringValue: string) {
const str = Buffer.from(stringValue, 'utf8')
const str = utf8ToBytes(stringValue)
return `0x${padToEven(str.toString('hex')).replace(/^0+|0+$/g, '')}`
return `0x${padToEven(bytesToHex(str)).replace(/^0+|0+$/g, '')}`
}

@@ -144,0 +146,0 @@

@@ -1,3 +0,1 @@

import fetch from 'micro-ftch'
type rpcParams = {

@@ -7,3 +5,20 @@ method: string

}
/**
* Makes a simple RPC call to a remote Ethereum JSON-RPC provider and passes through the response.
* No parameter or response validation is done.
*
* @param url the URL for the JSON RPC provider
* @param params the parameters for the JSON-RPC method - refer to
* https://ethereum.org/en/developers/docs/apis/json-rpc/ for details on RPC methods
* @returns the `result` field from the JSON-RPC response
*/
export const fetchFromProvider = async (url: string, params: rpcParams) => {
const data = JSON.stringify({
method: params.method,
params: params.params,
jsonrpc: '2.0',
id: 1,
})
const res = await fetch(url, {

@@ -13,19 +28,19 @@ headers: {

},
type: 'json',
data: {
method: params.method,
params: params.params,
jsonrpc: '2.0',
id: 1,
},
method: 'POST',
body: data,
})
return res.result
const json = await res.json()
return json.result
}
export const getProvider = (provider: string | any) => {
/**
*
* @param provider a URL string or {@link EthersProvider}
* @returns the extracted URL string for the JSON-RPC Provider
*/
export const getProvider = (provider: string | EthersProvider) => {
if (typeof provider === 'string') {
return provider
} else if (provider?.connection?.url !== undefined) {
return provider.connection.url
} else if (typeof provider === 'object' && provider._getConnection !== undefined) {
return provider._getConnection().url
} else {

@@ -35,1 +50,12 @@ throw new Error('Must provide valid provider URL or Web3Provider')

}
/**
* A partial interface for an `ethers` `JsonRpcProvider`
* We only use the url string since we do raw `fetch` calls to
* retrieve the necessary data
*/
export interface EthersProvider {
_getConnection: () => {
url: string
}
}

@@ -1,12 +0,20 @@

import { keccak256 } from 'ethereum-cryptography/keccak'
import { secp256k1 } from 'ethereum-cryptography/secp256k1'
import { keccak256 } from 'ethereum-cryptography/keccak.js'
import { secp256k1 } from 'ethereum-cryptography/secp256k1.js'
import { bufferToBigInt, bufferToHex, bufferToInt, setLengthLeft, toBuffer } from './bytes'
import { SECP256K1_ORDER, SECP256K1_ORDER_DIV_2 } from './constants'
import { assertIsBuffer } from './helpers'
import {
bytesToBigInt,
bytesToHex,
bytesToInt,
concatBytes,
setLengthLeft,
toBytes,
utf8ToBytes,
} from './bytes.js'
import { SECP256K1_ORDER, SECP256K1_ORDER_DIV_2 } from './constants.js'
import { assertIsBytes } from './helpers.js'
export interface ECDSASignature {
v: bigint
r: Buffer
s: Buffer
r: Uint8Array
s: Uint8Array
}

@@ -20,7 +28,11 @@

*/
export function ecsign(msgHash: Buffer, privateKey: Buffer, chainId?: bigint): ECDSASignature {
export function ecsign(
msgHash: Uint8Array,
privateKey: Uint8Array,
chainId?: bigint
): ECDSASignature {
const sig = secp256k1.sign(msgHash, privateKey)
const buf = sig.toCompactRawBytes()
const r = Buffer.from(buf.slice(0, 32))
const s = Buffer.from(buf.slice(32, 64))
const r = buf.slice(0, 32)
const s = buf.slice(32, 64)

@@ -54,9 +66,9 @@ const v =

export const ecrecover = function (
msgHash: Buffer,
msgHash: Uint8Array,
v: bigint,
r: Buffer,
s: Buffer,
r: Uint8Array,
s: Uint8Array,
chainId?: bigint
): Buffer {
const signature = Buffer.concat([setLengthLeft(r, 32), setLengthLeft(s, 32)], 64)
): Uint8Array {
const signature = concatBytes(setLengthLeft(r, 32), setLengthLeft(s, 32))
const recovery = calculateSigRecovery(v, chainId)

@@ -69,3 +81,3 @@ if (!isValidSigRecovery(recovery)) {

const senderPubKey = sig.recoverPublicKey(msgHash)
return Buffer.from(senderPubKey.toRawBytes(false).slice(1))
return senderPubKey.toRawBytes(false).slice(1)
}

@@ -78,3 +90,8 @@

*/
export const toRpcSig = function (v: bigint, r: Buffer, s: Buffer, chainId?: bigint): string {
export const toRpcSig = function (
v: bigint,
r: Uint8Array,
s: Uint8Array,
chainId?: bigint
): string {
const recovery = calculateSigRecovery(v, chainId)

@@ -86,3 +103,4 @@ if (!isValidSigRecovery(recovery)) {

// geth (and the RPC eth_sign method) uses the 65 byte format used by Bitcoin
return bufferToHex(Buffer.concat([setLengthLeft(r, 32), setLengthLeft(s, 32), toBuffer(v)]))
return bytesToHex(concatBytes(setLengthLeft(r, 32), setLengthLeft(s, 32), toBytes(v)))
}

@@ -95,3 +113,8 @@

*/
export const toCompactSig = function (v: bigint, r: Buffer, s: Buffer, chainId?: bigint): string {
export const toCompactSig = function (
v: bigint,
r: Uint8Array,
s: Uint8Array,
chainId?: bigint
): string {
const recovery = calculateSigRecovery(v, chainId)

@@ -102,9 +125,8 @@ if (!isValidSigRecovery(recovery)) {

let ss = s
const ss = Uint8Array.from([...s])
if ((v > BigInt(28) && v % BigInt(2) === BigInt(1)) || v === BigInt(1) || v === BigInt(28)) {
ss = Buffer.from(s)
ss[0] |= 0x80
}
return bufferToHex(Buffer.concat([setLengthLeft(r, 32), setLengthLeft(ss, 32)]))
return bytesToHex(concatBytes(setLengthLeft(r, 32), setLengthLeft(ss, 32)))
}

@@ -121,16 +143,16 @@

export const fromRpcSig = function (sig: string): ECDSASignature {
const buf: Buffer = toBuffer(sig)
const bytes: Uint8Array = toBytes(sig)
let r: Buffer
let s: Buffer
let r: Uint8Array
let s: Uint8Array
let v: bigint
if (buf.length >= 65) {
r = buf.slice(0, 32)
s = buf.slice(32, 64)
v = bufferToBigInt(buf.slice(64))
} else if (buf.length === 64) {
if (bytes.length >= 65) {
r = bytes.subarray(0, 32)
s = bytes.subarray(32, 64)
v = bytesToBigInt(bytes.subarray(64))
} else if (bytes.length === 64) {
// Compact Signature Representation (https://eips.ethereum.org/EIPS/eip-2098)
r = buf.slice(0, 32)
s = buf.slice(32, 64)
v = BigInt(bufferToInt(buf.slice(32, 33)) >> 7)
r = bytes.subarray(0, 32)
s = bytes.subarray(32, 64)
v = BigInt(bytesToInt(bytes.subarray(32, 33)) >> 7)
s[0] &= 0x7f

@@ -160,4 +182,4 @@ } else {

v: bigint,
r: Buffer,
s: Buffer,
r: Uint8Array,
s: Uint8Array,
homesteadOrLater: boolean = true,

@@ -174,4 +196,4 @@ chainId?: bigint

const rBigInt = bufferToBigInt(r)
const sBigInt = bufferToBigInt(s)
const rBigInt = bytesToBigInt(r)
const sBigInt = bytesToBigInt(s)

@@ -200,6 +222,6 @@ if (

*/
export const hashPersonalMessage = function (message: Buffer): Buffer {
assertIsBuffer(message)
const prefix = Buffer.from(`\u0019Ethereum Signed Message:\n${message.length}`, 'utf-8')
return Buffer.from(keccak256(Buffer.concat([prefix, message])))
export const hashPersonalMessage = function (message: Uint8Array): Uint8Array {
assertIsBytes(message)
const prefix = utf8ToBytes(`\u0019Ethereum Signed Message:\n${message.length}`)
return keccak256(concatBytes(prefix, message))
}

@@ -1,6 +0,6 @@

import { bufferToBigInt, bufferToHex, toBuffer } from './bytes'
import { isHexString } from './internal'
import { bytesToBigInt, bytesToHex, toBytes } from './bytes.js'
import { isHexString } from './internal.js'
import type { Address } from './address'
import type { ToBufferInputTypes } from './bytes'
import type { Address } from './address.js'
import type { ToBytesInputTypes } from './bytes.js'

@@ -10,9 +10,8 @@ /*

*/
export type BigIntLike = bigint | PrefixedHexString | number | Buffer
export type BigIntLike = bigint | PrefixedHexString | number | Uint8Array
/*
* A type that represents an input that can be converted to a Buffer.
* A type that represents an input that can be converted to a Uint8Array.
*/
export type BufferLike =
| Buffer
export type BytesLike =
| Uint8Array

@@ -22,3 +21,3 @@ | number[]

| bigint
| TransformableToBuffer
| TransformabletoBytes
| PrefixedHexString

@@ -34,22 +33,9 @@

*/
export type AddressLike = Address | Buffer | PrefixedHexString
export type AddressLike = Address | Uint8Array | PrefixedHexString
/*
* A type that represents an object that has a `toArray()` method.
*/
export interface TransformableToArray {
toArray(): Uint8Array
toBuffer?(): Buffer
export interface TransformabletoBytes {
toBytes?(): Uint8Array
}
/*
* A type that represents an object that has a `toBuffer()` method.
*/
export interface TransformableToBuffer {
toBuffer(): Buffer
toArray?(): Uint8Array
}
export type NestedUint8Array = Array<Uint8Array | NestedUint8Array>
export type NestedBufferArray = Array<Buffer | NestedBufferArray>

@@ -62,3 +48,3 @@ /**

BigInt,
Buffer,
Uint8Array,
PrefixedHexString,

@@ -70,3 +56,3 @@ }

[TypeOutput.BigInt]: bigint
[TypeOutput.Buffer]: Buffer
[TypeOutput.Uint8Array]: Uint8Array
[TypeOutput.PrefixedHexString]: PrefixedHexString

@@ -84,7 +70,7 @@ }

export function toType<T extends TypeOutput>(
input: ToBufferInputTypes,
input: ToBytesInputTypes,
outputType: T
): TypeOutputReturnType[T]
export function toType<T extends TypeOutput>(
input: ToBufferInputTypes,
input: ToBytesInputTypes,
outputType: T

@@ -107,11 +93,11 @@ ): TypeOutputReturnType[T] | undefined | null {

const output = toBuffer(input)
const output = toBytes(input)
switch (outputType) {
case TypeOutput.Buffer:
case TypeOutput.Uint8Array:
return output as TypeOutputReturnType[T]
case TypeOutput.BigInt:
return bufferToBigInt(output) as TypeOutputReturnType[T]
return bytesToBigInt(output) as TypeOutputReturnType[T]
case TypeOutput.Number: {
const bigInt = bufferToBigInt(output)
const bigInt = bytesToBigInt(output)
if (bigInt > BigInt(Number.MAX_SAFE_INTEGER)) {

@@ -125,3 +111,3 @@ throw new Error(

case TypeOutput.PrefixedHexString:
return bufferToHex(output) as TypeOutputReturnType[T]
return bytesToHex(output) as TypeOutputReturnType[T]
default:

@@ -128,0 +114,0 @@ throw new Error('unknown outputType')

@@ -1,6 +0,6 @@

import { Address } from './address'
import { bigIntToHex } from './bytes'
import { TypeOutput, toType } from './types'
import { Address } from './address.js'
import { bigIntToHex, bytesToHex, toBytes } from './bytes.js'
import { TypeOutput, toType } from './types.js'
import type { AddressLike, BigIntLike } from './types'
import type { AddressLike, BigIntLike } from './types.js'

@@ -29,3 +29,3 @@ /**

export type WithdrawalBuffer = [Buffer, Buffer, Buffer, Buffer]
export type WithdrawalBytes = [Uint8Array, Uint8Array, Uint8Array, Uint8Array]

@@ -60,3 +60,3 @@ /**

const validatorIndex = toType(validatorIndexData, TypeOutput.BigInt)
const address = new Address(toType(addressData, TypeOutput.Buffer))
const address = addressData instanceof Address ? addressData : new Address(toBytes(addressData))
const amount = toType(amountData, TypeOutput.BigInt)

@@ -67,3 +67,3 @@

public static fromValuesArray(withdrawalArray: WithdrawalBuffer) {
public static fromValuesArray(withdrawalArray: WithdrawalBytes) {
if (withdrawalArray.length !== 4) {

@@ -81,28 +81,25 @@ throw Error(`Invalid withdrawalArray length expected=4 actual=${withdrawalArray.length}`)

*/
public static toBufferArray(withdrawal: Withdrawal | WithdrawalData): WithdrawalBuffer {
public static toBytesArray(withdrawal: Withdrawal | WithdrawalData): WithdrawalBytes {
const { index, validatorIndex, address, amount } = withdrawal
const indexBuffer =
const indexBytes =
toType(index, TypeOutput.BigInt) === BigInt(0)
? Buffer.alloc(0)
: toType(index, TypeOutput.Buffer)
const validatorIndexBuffer =
? new Uint8Array()
: toType(index, TypeOutput.Uint8Array)
const validatorIndexBytes =
toType(validatorIndex, TypeOutput.BigInt) === BigInt(0)
? Buffer.alloc(0)
: toType(validatorIndex, TypeOutput.Buffer)
let addressBuffer
if (address instanceof Address) {
addressBuffer = (<Address>address).buf
} else {
addressBuffer = toType(address, TypeOutput.Buffer)
}
const amountBuffer =
? new Uint8Array()
: toType(validatorIndex, TypeOutput.Uint8Array)
const addressBytes =
address instanceof Address ? (<Address>address).bytes : toType(address, TypeOutput.Uint8Array)
const amountBytes =
toType(amount, TypeOutput.BigInt) === BigInt(0)
? Buffer.alloc(0)
: toType(amount, TypeOutput.Buffer)
? new Uint8Array()
: toType(amount, TypeOutput.Uint8Array)
return [indexBuffer, validatorIndexBuffer, addressBuffer, amountBuffer]
return [indexBytes, validatorIndexBytes, addressBytes, amountBytes]
}
raw() {
return Withdrawal.toBufferArray(this)
return Withdrawal.toBytesArray(this)
}

@@ -114,3 +111,3 @@

validatorIndex: this.validatorIndex,
address: this.address.buf,
address: this.address.bytes,
amount: this.amount,

@@ -124,3 +121,3 @@ }

validatorIndex: bigIntToHex(this.validatorIndex),
address: '0x' + this.address.buf.toString('hex'),
address: bytesToHex(this.address.bytes),
amount: bigIntToHex(this.amount),

@@ -127,0 +124,0 @@ }

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc