@feelyourprotocol/util 8141.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +373 -0
- package/README.md +297 -0
- package/dist/cjs/account.d.ts +165 -0
- package/dist/cjs/account.d.ts.map +1 -0
- package/dist/cjs/account.js +530 -0
- package/dist/cjs/account.js.map +1 -0
- package/dist/cjs/address.d.ts +67 -0
- package/dist/cjs/address.d.ts.map +1 -0
- package/dist/cjs/address.js +136 -0
- package/dist/cjs/address.js.map +1 -0
- package/dist/cjs/authorization.d.ts +41 -0
- package/dist/cjs/authorization.d.ts.map +1 -0
- package/dist/cjs/authorization.js +135 -0
- package/dist/cjs/authorization.js.map +1 -0
- package/dist/cjs/bal.d.ts +129 -0
- package/dist/cjs/bal.d.ts.map +1 -0
- package/dist/cjs/bal.js +529 -0
- package/dist/cjs/bal.js.map +1 -0
- package/dist/cjs/binaryTree.d.ts +148 -0
- package/dist/cjs/binaryTree.d.ts.map +1 -0
- package/dist/cjs/binaryTree.js +240 -0
- package/dist/cjs/binaryTree.js.map +1 -0
- package/dist/cjs/blobs.d.ts +76 -0
- package/dist/cjs/blobs.d.ts.map +1 -0
- package/dist/cjs/blobs.js +175 -0
- package/dist/cjs/blobs.js.map +1 -0
- package/dist/cjs/bytes.d.ts +291 -0
- package/dist/cjs/bytes.d.ts.map +1 -0
- package/dist/cjs/bytes.js +606 -0
- package/dist/cjs/bytes.js.map +1 -0
- package/dist/cjs/constants.d.ts +91 -0
- package/dist/cjs/constants.d.ts.map +1 -0
- package/dist/cjs/constants.js +97 -0
- package/dist/cjs/constants.js.map +1 -0
- package/dist/cjs/db.d.ts +65 -0
- package/dist/cjs/db.d.ts.map +1 -0
- package/dist/cjs/db.js +14 -0
- package/dist/cjs/db.js.map +1 -0
- package/dist/cjs/env.d.ts +9 -0
- package/dist/cjs/env.d.ts.map +1 -0
- package/dist/cjs/env.js +13 -0
- package/dist/cjs/env.js.map +1 -0
- package/dist/cjs/errors.d.ts +3 -0
- package/dist/cjs/errors.d.ts.map +1 -0
- package/dist/cjs/errors.js +19 -0
- package/dist/cjs/errors.js.map +1 -0
- package/dist/cjs/helpers.d.ts +21 -0
- package/dist/cjs/helpers.d.ts.map +1 -0
- package/dist/cjs/helpers.js +50 -0
- package/dist/cjs/helpers.js.map +1 -0
- package/dist/cjs/index.d.ts +67 -0
- package/dist/cjs/index.d.ts.map +1 -0
- package/dist/cjs/index.js +93 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/internal.d.ts +72 -0
- package/dist/cjs/internal.d.ts.map +1 -0
- package/dist/cjs/internal.js +182 -0
- package/dist/cjs/internal.js.map +1 -0
- package/dist/cjs/kzg.d.ts +14 -0
- package/dist/cjs/kzg.d.ts.map +1 -0
- package/dist/cjs/kzg.js +3 -0
- package/dist/cjs/kzg.js.map +1 -0
- package/dist/cjs/lock.d.ts +15 -0
- package/dist/cjs/lock.d.ts.map +1 -0
- package/dist/cjs/lock.js +45 -0
- package/dist/cjs/lock.js.map +1 -0
- package/dist/cjs/mapDB.d.ts +17 -0
- package/dist/cjs/mapDB.d.ts.map +1 -0
- package/dist/cjs/mapDB.js +46 -0
- package/dist/cjs/mapDB.js.map +1 -0
- package/dist/cjs/package.json +3 -0
- package/dist/cjs/provider.d.ts +46 -0
- package/dist/cjs/provider.d.ts.map +1 -0
- package/dist/cjs/provider.js +84 -0
- package/dist/cjs/provider.js.map +1 -0
- package/dist/cjs/request.d.ts +20 -0
- package/dist/cjs/request.d.ts.map +1 -0
- package/dist/cjs/request.js +35 -0
- package/dist/cjs/request.js.map +1 -0
- package/dist/cjs/signature.d.ts +47 -0
- package/dist/cjs/signature.d.ts.map +1 -0
- package/dist/cjs/signature.js +147 -0
- package/dist/cjs/signature.js.map +1 -0
- package/dist/cjs/tasks.d.ts +32 -0
- package/dist/cjs/tasks.d.ts.map +1 -0
- package/dist/cjs/tasks.js +51 -0
- package/dist/cjs/tasks.js.map +1 -0
- package/dist/cjs/types.d.ts +64 -0
- package/dist/cjs/types.d.ts.map +1 -0
- package/dist/cjs/types.js +78 -0
- package/dist/cjs/types.js.map +1 -0
- package/dist/cjs/units.d.ts +22 -0
- package/dist/cjs/units.d.ts.map +1 -0
- package/dist/cjs/units.js +51 -0
- package/dist/cjs/units.js.map +1 -0
- package/dist/cjs/withdrawal.d.ts +72 -0
- package/dist/cjs/withdrawal.d.ts.map +1 -0
- package/dist/cjs/withdrawal.js +93 -0
- package/dist/cjs/withdrawal.js.map +1 -0
- package/dist/esm/account.d.ts +165 -0
- package/dist/esm/account.d.ts.map +1 -0
- package/dist/esm/account.js +505 -0
- package/dist/esm/account.js.map +1 -0
- package/dist/esm/address.d.ts +67 -0
- package/dist/esm/address.d.ts.map +1 -0
- package/dist/esm/address.js +125 -0
- package/dist/esm/address.js.map +1 -0
- package/dist/esm/authorization.d.ts +41 -0
- package/dist/esm/authorization.d.ts.map +1 -0
- package/dist/esm/authorization.js +126 -0
- package/dist/esm/authorization.js.map +1 -0
- package/dist/esm/bal.d.ts +129 -0
- package/dist/esm/bal.d.ts.map +1 -0
- package/dist/esm/bal.js +522 -0
- package/dist/esm/bal.js.map +1 -0
- package/dist/esm/binaryTree.d.ts +148 -0
- package/dist/esm/binaryTree.d.ts.map +1 -0
- package/dist/esm/binaryTree.js +226 -0
- package/dist/esm/binaryTree.js.map +1 -0
- package/dist/esm/blobs.d.ts +76 -0
- package/dist/esm/blobs.d.ts.map +1 -0
- package/dist/esm/blobs.js +163 -0
- package/dist/esm/blobs.js.map +1 -0
- package/dist/esm/bytes.d.ts +291 -0
- package/dist/esm/bytes.d.ts.map +1 -0
- package/dist/esm/bytes.js +562 -0
- package/dist/esm/bytes.js.map +1 -0
- package/dist/esm/constants.d.ts +91 -0
- package/dist/esm/constants.d.ts.map +1 -0
- package/dist/esm/constants.js +94 -0
- package/dist/esm/constants.js.map +1 -0
- package/dist/esm/db.d.ts +65 -0
- package/dist/esm/db.d.ts.map +1 -0
- package/dist/esm/db.js +11 -0
- package/dist/esm/db.js.map +1 -0
- package/dist/esm/env.d.ts +9 -0
- package/dist/esm/env.d.ts.map +1 -0
- package/dist/esm/env.js +9 -0
- package/dist/esm/env.js.map +1 -0
- package/dist/esm/errors.d.ts +3 -0
- package/dist/esm/errors.d.ts.map +1 -0
- package/dist/esm/errors.js +14 -0
- package/dist/esm/errors.js.map +1 -0
- package/dist/esm/helpers.d.ts +21 -0
- package/dist/esm/helpers.d.ts.map +1 -0
- package/dist/esm/helpers.js +43 -0
- package/dist/esm/helpers.js.map +1 -0
- package/dist/esm/index.d.ts +67 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js +67 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/internal.d.ts +72 -0
- package/dist/esm/internal.d.ts.map +1 -0
- package/dist/esm/internal.js +170 -0
- package/dist/esm/internal.js.map +1 -0
- package/dist/esm/kzg.d.ts +14 -0
- package/dist/esm/kzg.d.ts.map +1 -0
- package/dist/esm/kzg.js +2 -0
- package/dist/esm/kzg.js.map +1 -0
- package/dist/esm/lock.d.ts +15 -0
- package/dist/esm/lock.d.ts.map +1 -0
- package/dist/esm/lock.js +41 -0
- package/dist/esm/lock.js.map +1 -0
- package/dist/esm/mapDB.d.ts +17 -0
- package/dist/esm/mapDB.d.ts.map +1 -0
- package/dist/esm/mapDB.js +42 -0
- package/dist/esm/mapDB.js.map +1 -0
- package/dist/esm/package.json +3 -0
- package/dist/esm/provider.d.ts +46 -0
- package/dist/esm/provider.d.ts.map +1 -0
- package/dist/esm/provider.js +79 -0
- package/dist/esm/provider.js.map +1 -0
- package/dist/esm/request.d.ts +20 -0
- package/dist/esm/request.d.ts.map +1 -0
- package/dist/esm/request.js +30 -0
- package/dist/esm/request.js.map +1 -0
- package/dist/esm/signature.d.ts +47 -0
- package/dist/esm/signature.d.ts.map +1 -0
- package/dist/esm/signature.js +137 -0
- package/dist/esm/signature.js.map +1 -0
- package/dist/esm/tasks.d.ts +32 -0
- package/dist/esm/tasks.d.ts.map +1 -0
- package/dist/esm/tasks.js +47 -0
- package/dist/esm/tasks.js.map +1 -0
- package/dist/esm/types.d.ts +64 -0
- package/dist/esm/types.d.ts.map +1 -0
- package/dist/esm/types.js +71 -0
- package/dist/esm/types.js.map +1 -0
- package/dist/esm/units.d.ts +22 -0
- package/dist/esm/units.d.ts.map +1 -0
- package/dist/esm/units.js +46 -0
- package/dist/esm/units.js.map +1 -0
- package/dist/esm/withdrawal.d.ts +72 -0
- package/dist/esm/withdrawal.d.ts.map +1 -0
- package/dist/esm/withdrawal.js +86 -0
- package/dist/esm/withdrawal.js.map +1 -0
- package/dist/tsconfig.prod.cjs.tsbuildinfo +1 -0
- package/dist/tsconfig.prod.esm.tsbuildinfo +1 -0
- package/package.json +116 -0
- package/src/account.ts +630 -0
- package/src/address.ts +158 -0
- package/src/authorization.ts +180 -0
- package/src/bal.ts +761 -0
- package/src/binaryTree.ts +353 -0
- package/src/blobs.ts +209 -0
- package/src/bytes.ts +659 -0
- package/src/constants.ts +125 -0
- package/src/db.ts +86 -0
- package/src/env.ts +9 -0
- package/src/errors.ts +28 -0
- package/src/helpers.ts +46 -0
- package/src/index.ts +88 -0
- package/src/internal.ts +212 -0
- package/src/kzg.ts +24 -0
- package/src/lock.ts +42 -0
- package/src/mapDB.ts +57 -0
- package/src/provider.ts +109 -0
- package/src/request.ts +48 -0
- package/src/signature.ts +202 -0
- package/src/tasks.ts +59 -0
- package/src/types.ts +177 -0
- package/src/units.ts +56 -0
- package/src/withdrawal.ts +133 -0
package/src/address.ts
ADDED
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
import {
|
|
2
|
+
generateAddress,
|
|
3
|
+
generateAddress2,
|
|
4
|
+
isValidAddress,
|
|
5
|
+
privateToAddress,
|
|
6
|
+
pubToAddress,
|
|
7
|
+
} from './account.ts'
|
|
8
|
+
import {
|
|
9
|
+
bigIntToBytes,
|
|
10
|
+
bytesToBigInt,
|
|
11
|
+
bytesToHex,
|
|
12
|
+
equalsBytes,
|
|
13
|
+
hexToBytes,
|
|
14
|
+
setLengthLeft,
|
|
15
|
+
} from './bytes.ts'
|
|
16
|
+
import { BIGINT_0 } from './constants.ts'
|
|
17
|
+
import { EthereumJSErrorWithoutCode } from './errors.ts'
|
|
18
|
+
|
|
19
|
+
import type { PrefixedHexString } from './types.ts'
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Handling and generating Ethereum addresses
|
|
23
|
+
*/
|
|
24
|
+
export class Address {
|
|
25
|
+
public readonly bytes: Uint8Array
|
|
26
|
+
|
|
27
|
+
constructor(bytes: Uint8Array) {
|
|
28
|
+
if (bytes.length !== 20) {
|
|
29
|
+
throw EthereumJSErrorWithoutCode('Invalid address length')
|
|
30
|
+
}
|
|
31
|
+
this.bytes = bytes
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Is address equal to another.
|
|
36
|
+
*/
|
|
37
|
+
equals(address: Address): boolean {
|
|
38
|
+
return equalsBytes(this.bytes, address.bytes)
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Is address zero.
|
|
43
|
+
*/
|
|
44
|
+
isZero(): boolean {
|
|
45
|
+
return this.equals(new Address(new Uint8Array(20)))
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* True if address is in the address range defined
|
|
50
|
+
* by EIP-1352
|
|
51
|
+
*/
|
|
52
|
+
isPrecompileOrSystemAddress(): boolean {
|
|
53
|
+
const address = bytesToBigInt(this.bytes)
|
|
54
|
+
const rangeMin = BIGINT_0
|
|
55
|
+
const rangeMax = BigInt('0xffff')
|
|
56
|
+
return address >= rangeMin && address <= rangeMax
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Returns hex encoding of address.
|
|
61
|
+
*/
|
|
62
|
+
toString(): PrefixedHexString {
|
|
63
|
+
return bytesToHex(this.bytes)
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Returns a new Uint8Array representation of address.
|
|
68
|
+
*/
|
|
69
|
+
toBytes(): Uint8Array {
|
|
70
|
+
return new Uint8Array(this.bytes)
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Returns the zero address.
|
|
76
|
+
*/
|
|
77
|
+
export function createZeroAddress(): Address {
|
|
78
|
+
return new Address(new Uint8Array(20))
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Returns an Address object from a bigint address (they are stored as bigints on the stack)
|
|
83
|
+
* @param value The bigint address
|
|
84
|
+
*/
|
|
85
|
+
export function createAddressFromBigInt(value: bigint): Address {
|
|
86
|
+
const bytes = bigIntToBytes(value)
|
|
87
|
+
if (bytes.length > 20) {
|
|
88
|
+
throw EthereumJSErrorWithoutCode(`Invalid address, too long: ${bytes.length}`)
|
|
89
|
+
}
|
|
90
|
+
return new Address(setLengthLeft(bytes, 20))
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Returns an Address object from a hex-encoded string.
|
|
95
|
+
* @param str - Hex-encoded address
|
|
96
|
+
*/
|
|
97
|
+
export function createAddressFromString(str: string): Address {
|
|
98
|
+
if (!isValidAddress(str)) {
|
|
99
|
+
throw EthereumJSErrorWithoutCode(`Invalid address input=${str}`)
|
|
100
|
+
}
|
|
101
|
+
return new Address(hexToBytes(str))
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Returns an address for a given public key.
|
|
106
|
+
* @param pubKey The two points of an uncompressed key
|
|
107
|
+
*/
|
|
108
|
+
export function createAddressFromPublicKey(pubKey: Uint8Array): Address {
|
|
109
|
+
if (!(pubKey instanceof Uint8Array)) {
|
|
110
|
+
throw EthereumJSErrorWithoutCode('Public key should be Uint8Array')
|
|
111
|
+
}
|
|
112
|
+
const bytes = pubToAddress(pubKey)
|
|
113
|
+
return new Address(bytes)
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Returns an address for a given private key.
|
|
118
|
+
* @param privateKey A private key must be 256 bits wide
|
|
119
|
+
*/
|
|
120
|
+
export function createAddressFromPrivateKey(privateKey: Uint8Array): Address {
|
|
121
|
+
if (!(privateKey instanceof Uint8Array)) {
|
|
122
|
+
throw EthereumJSErrorWithoutCode('Private key should be Uint8Array')
|
|
123
|
+
}
|
|
124
|
+
const bytes = privateToAddress(privateKey)
|
|
125
|
+
return new Address(bytes)
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Generates an address for a newly created contract.
|
|
130
|
+
* @param from The address which is creating this new address
|
|
131
|
+
* @param nonce The nonce of the from account
|
|
132
|
+
*/
|
|
133
|
+
export function createContractAddress(from: Address, nonce: bigint): Address {
|
|
134
|
+
if (typeof nonce !== 'bigint') {
|
|
135
|
+
throw EthereumJSErrorWithoutCode('Expected nonce to be a bigint')
|
|
136
|
+
}
|
|
137
|
+
return new Address(generateAddress(from.bytes, bigIntToBytes(nonce)))
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Generates an address for a contract created using CREATE2.
|
|
142
|
+
* @param from The address which is creating this new address
|
|
143
|
+
* @param salt A salt
|
|
144
|
+
* @param initCode The init code of the contract being created
|
|
145
|
+
*/
|
|
146
|
+
export function createContractAddress2(
|
|
147
|
+
from: Address,
|
|
148
|
+
salt: Uint8Array,
|
|
149
|
+
initCode: Uint8Array,
|
|
150
|
+
): Address {
|
|
151
|
+
if (!(salt instanceof Uint8Array)) {
|
|
152
|
+
throw EthereumJSErrorWithoutCode('Expected salt to be a Uint8Array')
|
|
153
|
+
}
|
|
154
|
+
if (!(initCode instanceof Uint8Array)) {
|
|
155
|
+
throw EthereumJSErrorWithoutCode('Expected initCode to be a Uint8Array')
|
|
156
|
+
}
|
|
157
|
+
return new Address(generateAddress2(from.bytes, salt, initCode))
|
|
158
|
+
}
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
// Utility helpers to convert authorization lists from the byte format and JSON format and vice versa
|
|
2
|
+
|
|
3
|
+
import { EthereumJSErrorWithoutCode, RLP } from '@feelyourprotocol/rlp'
|
|
4
|
+
import { secp256k1 } from '@noble/curves/secp256k1.js'
|
|
5
|
+
import { keccak_256 } from '@noble/hashes/sha3.js'
|
|
6
|
+
import { publicToAddress } from './account.ts'
|
|
7
|
+
import { Address } from './address.ts'
|
|
8
|
+
import {
|
|
9
|
+
bigIntToUnpaddedBytes,
|
|
10
|
+
bytesToBigInt,
|
|
11
|
+
bytesToHex,
|
|
12
|
+
concatBytes,
|
|
13
|
+
hexToBytes,
|
|
14
|
+
setLengthLeft,
|
|
15
|
+
unpadBytes,
|
|
16
|
+
} from './bytes.ts'
|
|
17
|
+
import { ecrecover } from './signature.ts'
|
|
18
|
+
import type {
|
|
19
|
+
EOACode7702AuthorizationListBytesItem,
|
|
20
|
+
EOACode7702AuthorizationListBytesItemUnsigned,
|
|
21
|
+
EOACode7702AuthorizationListItem,
|
|
22
|
+
EOACode7702AuthorizationListItemUnsigned,
|
|
23
|
+
} from './types.ts'
|
|
24
|
+
|
|
25
|
+
export const EOA_CODE_7702_AUTHORITY_SIGNING_MAGIC = hexToBytes('0x05')
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Converts an authorization list to a JSON format
|
|
29
|
+
* @param authorizationList
|
|
30
|
+
* @returns authorizationList in JSON format
|
|
31
|
+
*/
|
|
32
|
+
export function eoaCode7702AuthorizationListBytesItemToJSON(
|
|
33
|
+
authorizationList: EOACode7702AuthorizationListBytesItem,
|
|
34
|
+
): EOACode7702AuthorizationListItem {
|
|
35
|
+
const [chainId, address, nonce, yParity, r, s] = authorizationList
|
|
36
|
+
return {
|
|
37
|
+
chainId: bytesToHex(chainId),
|
|
38
|
+
address: bytesToHex(address),
|
|
39
|
+
nonce: bytesToHex(nonce),
|
|
40
|
+
yParity: bytesToHex(yParity),
|
|
41
|
+
r: bytesToHex(r),
|
|
42
|
+
s: bytesToHex(s),
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Converts an authority list in JSON to a bytes format
|
|
48
|
+
* @param authorizationList
|
|
49
|
+
* @returns bytes format of the authority list
|
|
50
|
+
*/
|
|
51
|
+
export function eoaCode7702AuthorizationListJSONItemToBytes(
|
|
52
|
+
authorizationList: EOACode7702AuthorizationListItem,
|
|
53
|
+
): EOACode7702AuthorizationListBytesItem {
|
|
54
|
+
const requiredFields = ['chainId', 'address', 'nonce', 'yParity', 'r', 's'] as const
|
|
55
|
+
|
|
56
|
+
// Validate all required fields are present
|
|
57
|
+
for (const field of requiredFields) {
|
|
58
|
+
if (authorizationList[field] === undefined) {
|
|
59
|
+
throw EthereumJSErrorWithoutCode(
|
|
60
|
+
`EIP-7702 authorization list invalid: ${field} is not defined`,
|
|
61
|
+
)
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return [
|
|
66
|
+
unpadBytes(hexToBytes(authorizationList.chainId)),
|
|
67
|
+
hexToBytes(authorizationList.address),
|
|
68
|
+
unpadBytes(hexToBytes(authorizationList.nonce)),
|
|
69
|
+
unpadBytes(hexToBytes(authorizationList.yParity)),
|
|
70
|
+
unpadBytes(hexToBytes(authorizationList.r)),
|
|
71
|
+
unpadBytes(hexToBytes(authorizationList.s)),
|
|
72
|
+
]
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/** Authorization signing utility methods */
|
|
76
|
+
function unsignedAuthorizationListToBytes(input: EOACode7702AuthorizationListItemUnsigned) {
|
|
77
|
+
const { chainId: chainIdHex, address: addressHex, nonce: nonceHex } = input
|
|
78
|
+
const chainId = unpadBytes(hexToBytes(chainIdHex))
|
|
79
|
+
const address = setLengthLeft(hexToBytes(addressHex), 20)
|
|
80
|
+
const nonce = unpadBytes(hexToBytes(nonceHex))
|
|
81
|
+
return [chainId, address, nonce]
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Returns the bytes (RLP-encoded) to sign
|
|
86
|
+
* @param input Either the bytes or the object format of the authorization list item
|
|
87
|
+
* @returns
|
|
88
|
+
*/
|
|
89
|
+
export function eoaCode7702AuthorizationMessageToSign(
|
|
90
|
+
input: EOACode7702AuthorizationListItemUnsigned | EOACode7702AuthorizationListBytesItemUnsigned,
|
|
91
|
+
) {
|
|
92
|
+
if (Array.isArray(input)) {
|
|
93
|
+
// The address is validated, the chainId and nonce will be `unpadBytes` such that these are valid
|
|
94
|
+
const [chainId, address, nonce] = input
|
|
95
|
+
if (address.length !== 20) {
|
|
96
|
+
throw EthereumJSErrorWithoutCode('Cannot sign authority: address length should be 20 bytes')
|
|
97
|
+
}
|
|
98
|
+
return concatBytes(
|
|
99
|
+
EOA_CODE_7702_AUTHORITY_SIGNING_MAGIC,
|
|
100
|
+
RLP.encode([unpadBytes(chainId), address, unpadBytes(nonce)]),
|
|
101
|
+
)
|
|
102
|
+
} else {
|
|
103
|
+
const [chainId, address, nonce] = unsignedAuthorizationListToBytes(input)
|
|
104
|
+
return concatBytes(EOA_CODE_7702_AUTHORITY_SIGNING_MAGIC, RLP.encode([chainId, address, nonce]))
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Hashes the RLP-encoded message to sign
|
|
110
|
+
* @param input
|
|
111
|
+
* @returns
|
|
112
|
+
*/
|
|
113
|
+
export function eoaCode7702AuthorizationHashedMessageToSign(
|
|
114
|
+
input: EOACode7702AuthorizationListItemUnsigned | EOACode7702AuthorizationListBytesItemUnsigned,
|
|
115
|
+
) {
|
|
116
|
+
return keccak_256(eoaCode7702AuthorizationMessageToSign(input))
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Signs an authorization list item and returns it in `bytes` format.
|
|
121
|
+
* To get the JSON format, use `authorizationListBytesToJSON([signed])[0] to convert it`
|
|
122
|
+
* @param input
|
|
123
|
+
* @param privateKey
|
|
124
|
+
* @param ecSign
|
|
125
|
+
* @returns
|
|
126
|
+
*/
|
|
127
|
+
export function eoaCode7702SignAuthorization(
|
|
128
|
+
input: EOACode7702AuthorizationListItemUnsigned | EOACode7702AuthorizationListBytesItemUnsigned,
|
|
129
|
+
privateKey: Uint8Array,
|
|
130
|
+
ecSign?: (
|
|
131
|
+
msg: Uint8Array,
|
|
132
|
+
pk: Uint8Array,
|
|
133
|
+
ecSignOpts?: { extraEntropy?: Uint8Array | boolean },
|
|
134
|
+
) => Pick<ReturnType<typeof secp256k1.Signature.fromBytes>, 'recovery' | 'r' | 's'>,
|
|
135
|
+
): EOACode7702AuthorizationListBytesItem {
|
|
136
|
+
const msgHash = eoaCode7702AuthorizationHashedMessageToSign(input)
|
|
137
|
+
const secp256k1Sign = (msgHash: Uint8Array, pk: Uint8Array) => {
|
|
138
|
+
return (
|
|
139
|
+
ecSign?.(msgHash, pk) ??
|
|
140
|
+
secp256k1.Signature.fromBytes(
|
|
141
|
+
secp256k1.sign(msgHash, pk, { prehash: false, format: 'recovered' }),
|
|
142
|
+
'recovered',
|
|
143
|
+
)
|
|
144
|
+
)
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
const signed = secp256k1Sign(msgHash, privateKey)
|
|
148
|
+
|
|
149
|
+
const [chainId, address, nonce] = Array.isArray(input)
|
|
150
|
+
? input
|
|
151
|
+
: unsignedAuthorizationListToBytes(input)
|
|
152
|
+
|
|
153
|
+
return [
|
|
154
|
+
unpadBytes(chainId),
|
|
155
|
+
address,
|
|
156
|
+
unpadBytes(nonce),
|
|
157
|
+
bigIntToUnpaddedBytes(BigInt(signed.recovery!)),
|
|
158
|
+
bigIntToUnpaddedBytes(signed.r),
|
|
159
|
+
bigIntToUnpaddedBytes(signed.s),
|
|
160
|
+
]
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
export function eoaCode7702RecoverAuthority(
|
|
164
|
+
input: EOACode7702AuthorizationListItem | EOACode7702AuthorizationListBytesItem,
|
|
165
|
+
): Address {
|
|
166
|
+
const inputBytes = Array.isArray(input)
|
|
167
|
+
? input
|
|
168
|
+
: eoaCode7702AuthorizationListJSONItemToBytes(input)
|
|
169
|
+
const [chainId, address, nonce, yParity, r, s] = [
|
|
170
|
+
unpadBytes(inputBytes[0]),
|
|
171
|
+
inputBytes[1],
|
|
172
|
+
unpadBytes(inputBytes[2]),
|
|
173
|
+
unpadBytes(inputBytes[3]),
|
|
174
|
+
unpadBytes(inputBytes[4]),
|
|
175
|
+
unpadBytes(inputBytes[5]),
|
|
176
|
+
]
|
|
177
|
+
const msgHash = eoaCode7702AuthorizationHashedMessageToSign([chainId, address, nonce])
|
|
178
|
+
const pubKey = ecrecover(msgHash, bytesToBigInt(yParity), r, s)
|
|
179
|
+
return new Address(publicToAddress(pubKey))
|
|
180
|
+
}
|