Skip to content

Commit 17852b5

Browse files
authored
util: refactor 7702 authorization lists to util package (#4032)
* util: refactor 7702 authorization lists to util package * chore: type issues * chore: lint fix * chore: merge * chore: prefix with EOACode7702 * chore: adjust type * tx: fix last type issue * Fix examples * Update packages/util/src/types.ts * Merge branch 'master' into refactor/auth-list-utils
1 parent 30c2491 commit 17852b5

File tree

13 files changed

+186
-170
lines changed

13 files changed

+186
-170
lines changed

packages/tx/examples/setEOATx.ts

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,33 +9,38 @@
99
// It will self-delegate. Note that in a 7702-tx, you are free to include any authorization item.
1010
// If the authorization item is valid (it has the correct nonce, and matches the chainId (or the chainId is 0))
1111
// then it will delegate the code of the account **who signed that authorization item** to the address in that authority item
12+
import { createEOACode7702Tx } from '@ethereumjs/tx'
13+
import type { EOACode7702AuthorizationListItemUnsigned } from '@ethereumjs/util'
1214
import {
13-
authorizationListBytesItemToJSON,
14-
createEOACode7702Tx,
15-
signAuthorization,
16-
} from '@ethereumjs/tx'
17-
import { Address, privateToAddress } from '@ethereumjs/util'
15+
Address,
16+
eoaCode7702AuthorizationListBytesItemToJSON,
17+
eoaCode7702SignAuthorization,
18+
privateToAddress,
19+
} from '@ethereumjs/util'
1820

1921
const privateKey = new Uint8Array(32).fill(0x20)
2022
const privateKeyOther = new Uint8Array(32).fill(0x99)
2123

2224
const myAddress = new Address(privateToAddress(privateKey))
2325

24-
const unsignedAuthorizationListItemSelf = {
26+
const unsignedAuthorizationListItemSelf: EOACode7702AuthorizationListItemUnsigned = {
2527
chainId: '0x1337', // This delegation will only work on the chain with chainId 0x1337
2628
address: '0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
2729
nonce: '0x01', // Since we are self-delegating we need account for the nonce being bumped of the account
2830
}
29-
const signedSelf = signAuthorization(unsignedAuthorizationListItemSelf, privateKey)
30-
// To convert the bytes array to a human-readable form, use `authorizationListBytesItemToJSON`
31-
console.log(authorizationListBytesItemToJSON(signedSelf))
31+
const signedSelf = eoaCode7702SignAuthorization(unsignedAuthorizationListItemSelf, privateKey)
32+
// To convert the bytes array to a human-readable form, use `eoaCode7702AuthorizationListBytesItemToJSON`
33+
console.log(eoaCode7702AuthorizationListBytesItemToJSON(signedSelf))
3234

33-
const unsignedAuthorizationListItemOther = {
35+
const unsignedAuthorizationListItemOther: EOACode7702AuthorizationListItemUnsigned = {
3436
chainId: '0x', // The chainId 0 is special: this authorization will work on any chain which supports EIP-7702
3537
address: '0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb',
3638
nonce: '0x',
3739
}
38-
const signedOther = signAuthorization(unsignedAuthorizationListItemOther, privateKeyOther)
40+
const signedOther = eoaCode7702SignAuthorization(
41+
unsignedAuthorizationListItemOther,
42+
privateKeyOther,
43+
)
3944

4045
const authorizationList = [signedSelf, signedOther]
4146

packages/tx/src/7702/tx.ts

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,19 @@ import {
55
bigIntToHex,
66
bigIntToUnpaddedBytes,
77
bytesToBigInt,
8+
eoaCode7702AuthorizationListBytesItemToJSON,
9+
eoaCode7702AuthorizationListJSONItemToBytes,
10+
isEOACode7702AuthorizationList,
811
toBytes,
912
} from '@ethereumjs/util'
13+
import type { Address, EOACode7702AuthorizationListBytes } from '@ethereumjs/util'
1014

1115
import * as EIP1559 from '../capabilities/eip1559.ts'
1216
import * as EIP2718 from '../capabilities/eip2718.ts'
1317
import * as EIP2930 from '../capabilities/eip2930.ts'
1418
import * as EIP7702 from '../capabilities/eip7702.ts'
1519
import * as Legacy from '../capabilities/legacy.ts'
16-
import { TransactionType, isAccessList, isAuthorizationList } from '../types.ts'
20+
import { TransactionType, isAccessList } from '../types.ts'
1721
import {
1822
getBaseJSON,
1923
sharedConstructor,
@@ -24,23 +28,18 @@ import {
2428
import { createEOACode7702Tx } from './constructors.ts'
2529

2630
import type { Common } from '@ethereumjs/common'
27-
import type { Address } from '@ethereumjs/util'
31+
2832
import type {
2933
AccessListBytes,
3034
TxData as AllTypesTxData,
3135
TxValuesArray as AllTypesTxValuesArray,
32-
AuthorizationListBytes,
3336
Capability,
3437
JSONTx,
3538
TransactionCache,
3639
TransactionInterface,
3740
TxOptions,
3841
} from '../types.ts'
3942
import { accessListBytesToJSON, accessListJSONToBytes } from '../util/access.ts'
40-
import {
41-
authorizationListBytesItemToJSON,
42-
authorizationListJSONItemToBytes,
43-
} from '../util/authorization.ts'
4443

4544
export type TxData = AllTypesTxData[typeof TransactionType.EOACodeEIP7702]
4645
export type TxValuesArray = AllTypesTxValuesArray[typeof TransactionType.EOACodeEIP7702]
@@ -61,7 +60,7 @@ export class EOACode7702Tx implements TransactionInterface<typeof TransactionTyp
6160
public readonly data!: Uint8Array
6261
public readonly to?: Address
6362
public readonly accessList: AccessListBytes
64-
public readonly authorizationList: AuthorizationListBytes
63+
public readonly authorizationList: EOACode7702AuthorizationListBytes
6564
public readonly chainId: bigint
6665
public readonly maxPriorityFeePerGas: bigint
6766
public readonly maxFeePerGas: bigint
@@ -123,8 +122,8 @@ export class EOACode7702Tx implements TransactionInterface<typeof TransactionTyp
123122
EIP2930.verifyAccessList(this)
124123

125124
// Populate the authority list fields
126-
this.authorizationList = isAuthorizationList(authorizationList)
127-
? authorizationList.map((item) => authorizationListJSONItemToBytes(item))
125+
this.authorizationList = isEOACode7702AuthorizationList(authorizationList)
126+
? authorizationList.map((item) => eoaCode7702AuthorizationListJSONItemToBytes(item))
128127
: authorizationList
129128
// Verify the authority list format.
130129
EIP7702.verifyAuthorizationList(this)
@@ -359,7 +358,7 @@ export class EOACode7702Tx implements TransactionInterface<typeof TransactionTyp
359358
toJSON(): JSONTx {
360359
const accessListJSON = accessListBytesToJSON(this.accessList)
361360
const authorizationList = this.authorizationList.map((item) =>
362-
authorizationListBytesItemToJSON(item),
361+
eoaCode7702AuthorizationListBytesItemToJSON(item),
363362
)
364363

365364
const baseJSON = getBaseJSON(this)

packages/tx/src/constants.ts

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,8 @@
11
/** EIP-4844 constants */
22

3-
import { hexToBytes } from '@ethereumjs/util'
4-
53
export const MAX_CALLDATA_SIZE = 16777216 // 2 ** 24
64
export const MAX_ACCESS_LIST_SIZE = 16777216 // 2 ** 24
75
export const MAX_VERSIONED_HASHES_LIST_SIZE = 16777216 // 2 ** 24
86
export const MAX_TX_WRAP_KZG_COMMITMENTS = 16777216 // 2 ** 24
97
export const FIELD_ELEMENTS_PER_BLOB = 4096 // This is also in the Common 4844 parameters but needed here since types can't access Common params
108
export const BYTES_PER_FIELD_ELEMENT = 32
11-
12-
/** EIP-7702 constants */
13-
14-
export const AUTHORITY_SIGNING_MAGIC = hexToBytes('0x05')

packages/tx/src/types.ts

Lines changed: 7 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import type {
66
AddressLike,
77
BigIntLike,
88
BytesLike,
9+
EOACode7702AuthorizationList,
10+
EOACode7702AuthorizationListBytes,
911
PrefixedHexString,
1012
} from '@ethereumjs/util'
1113
import type { FeeMarket1559Tx } from './1559/tx.ts'
@@ -118,25 +120,6 @@ export function isAccessList(input: AccessListBytes | AccessList): input is Acce
118120
return !isAccessListBytes(input) // This is exactly the same method, except the output is negated.
119121
}
120122

121-
export function isAuthorizationListBytes(
122-
input: AuthorizationListBytes | AuthorizationList,
123-
): input is AuthorizationListBytes {
124-
if (input.length === 0) {
125-
return true
126-
}
127-
const firstItem = input[0]
128-
if (Array.isArray(firstItem)) {
129-
return true
130-
}
131-
return false
132-
}
133-
134-
export function isAuthorizationList(
135-
input: AuthorizationListBytes | AuthorizationList,
136-
): input is AuthorizationList {
137-
return !isAuthorizationListBytes(input) // This is exactly the same method, except the output is negated.
138-
}
139-
140123
export interface TransactionCache {
141124
hash?: Uint8Array
142125
dataFee?: {
@@ -147,7 +130,7 @@ export interface TransactionCache {
147130
// TODO: re-add these cache items for the JSON
148131
// See: https://github.com/ethereumjs/ethereumjs-monorepo/issues/3932
149132
//accessListJSON?: AccessList
150-
//authorityListJSON?: AuthorizationList
133+
//authorityListJSON?: EOACode7702AuthorizationList
151134
}
152135

153136
export type TransactionType = (typeof TransactionType)[keyof typeof TransactionType]
@@ -266,7 +249,7 @@ export interface EIP4844CompatibleTx<T extends TransactionType = TransactionType
266249
export interface EIP7702CompatibleTx<T extends TransactionType = TransactionType>
267250
extends EIP1559CompatibleTx<T> {
268251
// ChainID, Address, [nonce], y_parity, r, s
269-
readonly authorizationList: AuthorizationListBytes
252+
readonly authorizationList: EOACode7702AuthorizationListBytes
270253
}
271254

272255
export interface TxData {
@@ -428,7 +411,7 @@ export interface BlobEIP4844TxData extends FeeMarketEIP1559TxData {
428411
* {@link EOACode7702Tx} data.
429412
*/
430413
export interface EOACode7702TxData extends FeeMarketEIP1559TxData {
431-
authorizationList?: AuthorizationListBytes | AuthorizationList | never
414+
authorizationList?: EOACode7702AuthorizationListBytes | EOACode7702AuthorizationList | never
432415
}
433416

434417
export interface TxValuesArray {
@@ -492,7 +475,7 @@ type EOACode7702TxValuesArray = [
492475
Uint8Array,
493476
Uint8Array,
494477
AccessListBytes,
495-
AuthorizationListBytes,
478+
EOACode7702AuthorizationListBytes,
496479
Uint8Array?,
497480
Uint8Array?,
498481
Uint8Array?,
@@ -547,7 +530,7 @@ export interface JSONTx {
547530
value?: PrefixedHexString
548531
chainId?: PrefixedHexString
549532
accessList?: JSONAccessListItem[] // TODO should this not be AccessList?
550-
authorizationList?: AuthorizationList
533+
authorizationList?: EOACode7702AuthorizationList
551534
type?: PrefixedHexString
552535
maxPriorityFeePerGas?: PrefixedHexString
553536
maxFeePerGas?: PrefixedHexString
@@ -605,32 +588,3 @@ export type AccessListItem = {
605588
export type AccessListBytesItem = [Uint8Array, Uint8Array[]]
606589
export type AccessListBytes = AccessListBytesItem[]
607590
export type AccessList = AccessListItem[]
608-
609-
/**
610-
* Authorization list types
611-
*/
612-
export type AuthorizationListItemUnsigned = {
613-
chainId: PrefixedHexString
614-
address: PrefixedHexString
615-
nonce: PrefixedHexString
616-
}
617-
618-
export type AuthorizationListItem = {
619-
yParity: PrefixedHexString
620-
r: PrefixedHexString
621-
s: PrefixedHexString
622-
} & AuthorizationListItemUnsigned
623-
624-
// Tuple of [chain_id, address, [nonce], y_parity, r, s]
625-
export type AuthorizationListBytesItem = [
626-
Uint8Array,
627-
Uint8Array,
628-
Uint8Array,
629-
Uint8Array,
630-
Uint8Array,
631-
Uint8Array,
632-
]
633-
export type AuthorizationListBytes = AuthorizationListBytesItem[]
634-
export type AuthorizationList = AuthorizationListItem[]
635-
636-
export type AuthorizationListBytesItemUnsigned = [Uint8Array, Uint8Array, Uint8Array]

packages/tx/src/util/index.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
11
// Do not add `./internal.ts`, this will export the internal helpers also at package level
22
export * from './general.ts'
33
export * from './access.ts'
4-
export * from './authorization.ts'

packages/tx/test/eip7702.spec.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,8 @@ import { assert, describe, it } from 'vitest'
1313

1414
import { createEOACode7702Tx } from '../src/index.ts'
1515

16-
import type { PrefixedHexString } from '@ethereumjs/util'
16+
import type { EOACode7702AuthorizationListItem, PrefixedHexString } from '@ethereumjs/util'
1717
import type { TxData } from '../src/7702/tx.ts'
18-
import type { AuthorizationListItem } from '../src/index.ts'
1918

2019
const common = new Common({ chain: Mainnet, hardfork: Hardfork.Cancun, eips: [7702] })
2120

@@ -24,8 +23,8 @@ const addr = createAddressFromPrivateKey(pkey)
2423

2524
const ones32: PrefixedHexString = `0x${'01'.repeat(32)}`
2625

27-
function getTxData(override: Partial<AuthorizationListItem> = {}): TxData {
28-
const validAuthorizationList: AuthorizationListItem = {
26+
function getTxData(override: Partial<EOACode7702AuthorizationListItem> = {}): TxData {
27+
const validAuthorizationList: EOACode7702AuthorizationListItem = {
2928
chainId: '0x',
3029
address: `0x${'20'.repeat(20)}`,
3130
nonce: '0x1',
@@ -78,7 +77,7 @@ describe('[EOACode7702Transaction]', () => {
7877
})
7978

8079
it('valid and invalid authorizationList values', () => {
81-
const tests: [Partial<AuthorizationListItem>, string][] = [
80+
const tests: [Partial<EOACode7702AuthorizationListItem>, string][] = [
8281
[
8382
{
8483
address: `0x${'20'.repeat(21)}`,

0 commit comments

Comments
 (0)