tempo.ts 0.9.0 → 0.10.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/CHANGELOG.md +14 -0
- package/dist/ox/AuthorizationTempo.d.ts +450 -0
- package/dist/ox/AuthorizationTempo.d.ts.map +1 -0
- package/dist/ox/AuthorizationTempo.js +433 -0
- package/dist/ox/AuthorizationTempo.js.map +1 -0
- package/dist/ox/KeyAuthorization.d.ts +1 -1
- package/dist/ox/KeyAuthorization.d.ts.map +1 -1
- package/dist/ox/KeyAuthorization.js +3 -4
- package/dist/ox/KeyAuthorization.js.map +1 -1
- package/dist/ox/Transaction.d.ts +4 -3
- package/dist/ox/Transaction.d.ts.map +1 -1
- package/dist/ox/Transaction.js +7 -0
- package/dist/ox/Transaction.js.map +1 -1
- package/dist/ox/TransactionEnvelopeTempo.d.ts +3 -3
- package/dist/ox/TransactionEnvelopeTempo.d.ts.map +1 -1
- package/dist/ox/TransactionEnvelopeTempo.js +8 -4
- package/dist/ox/TransactionEnvelopeTempo.js.map +1 -1
- package/dist/ox/TransactionRequest.d.ts +6 -4
- package/dist/ox/TransactionRequest.d.ts.map +1 -1
- package/dist/ox/TransactionRequest.js +7 -1
- package/dist/ox/TransactionRequest.js.map +1 -1
- package/dist/ox/index.d.ts +1 -0
- package/dist/ox/index.d.ts.map +1 -1
- package/dist/ox/index.js +1 -0
- package/dist/ox/index.js.map +1 -1
- package/dist/viem/Chain.d.ts +8 -3
- package/dist/viem/Chain.d.ts.map +1 -1
- package/dist/viem/Chain.js +1 -0
- package/dist/viem/Chain.js.map +1 -1
- package/dist/viem/Formatters.d.ts.map +1 -1
- package/dist/viem/Formatters.js +0 -13
- package/dist/viem/Formatters.js.map +1 -1
- package/dist/viem/Transaction.d.ts +5 -5
- package/dist/viem/Transaction.d.ts.map +1 -1
- package/dist/viem/Transaction.js +2 -15
- package/dist/viem/Transaction.js.map +1 -1
- package/dist/wagmi/Connector.d.ts +6 -12
- package/dist/wagmi/Connector.d.ts.map +1 -1
- package/dist/wagmi/Connector.js +73 -18
- package/dist/wagmi/Connector.js.map +1 -1
- package/package.json +1 -1
- package/src/ox/AuthorizationTempo.test.ts +1256 -0
- package/src/ox/AuthorizationTempo.ts +648 -0
- package/src/ox/KeyAuthorization.ts +5 -7
- package/src/ox/Transaction.ts +14 -3
- package/src/ox/TransactionEnvelopeTempo.test.ts +172 -2
- package/src/ox/TransactionEnvelopeTempo.ts +15 -5
- package/src/ox/TransactionRequest.ts +19 -5
- package/src/ox/e2e.test.ts +80 -8
- package/src/ox/index.ts +1 -0
- package/src/viem/Chain.ts +1 -0
- package/src/viem/Formatters.ts +0 -13
- package/src/viem/Transaction.ts +8 -29
- package/src/viem/e2e.test.ts +14 -28
- package/src/wagmi/Connector.ts +104 -31
package/src/ox/Transaction.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import type * as AccessList from 'ox/AccessList'
|
|
2
2
|
import type * as Address from 'ox/Address'
|
|
3
|
-
import type * as Authorization from 'ox/Authorization'
|
|
4
3
|
import type * as Errors from 'ox/Errors'
|
|
5
4
|
import * as Hex from 'ox/Hex'
|
|
6
5
|
import * as Signature from 'ox/Signature'
|
|
7
6
|
import * as ox_Transaction from 'ox/Transaction'
|
|
8
7
|
import type { Compute, OneOf, UnionCompute } from '../internal/types.js'
|
|
8
|
+
import * as AuthorizationTempo from './AuthorizationTempo.js'
|
|
9
9
|
import * as KeyAuthorization from './KeyAuthorization.js'
|
|
10
10
|
import * as SignatureEnvelope from './SignatureEnvelope.js'
|
|
11
11
|
import type { Call } from './TransactionEnvelopeTempo.js'
|
|
@@ -49,7 +49,7 @@ export type Tempo<
|
|
|
49
49
|
accessList: AccessList.AccessList
|
|
50
50
|
/** EIP-7702 Authorization list for the transaction. */
|
|
51
51
|
authorizationList?:
|
|
52
|
-
|
|
|
52
|
+
| AuthorizationTempo.ListSigned<bigintType, numberType>
|
|
53
53
|
| undefined
|
|
54
54
|
/** Array of calls to execute. */
|
|
55
55
|
calls: readonly Call<bigintType>[]
|
|
@@ -95,8 +95,9 @@ export type Tempo<
|
|
|
95
95
|
export type TempoRpc<pending extends boolean = false> = Compute<
|
|
96
96
|
Omit<
|
|
97
97
|
Tempo<pending, Hex.Hex, Hex.Hex, ToRpcType['tempo']>,
|
|
98
|
-
'calls' | 'keyAuthorization' | 'signature'
|
|
98
|
+
'authorizationList' | 'calls' | 'keyAuthorization' | 'signature'
|
|
99
99
|
> & {
|
|
100
|
+
aaAuthorizationList?: AuthorizationTempo.ListRpc | undefined
|
|
100
101
|
calls:
|
|
101
102
|
| readonly {
|
|
102
103
|
input?: Hex.Hex | undefined
|
|
@@ -191,6 +192,12 @@ export function fromRpc<
|
|
|
191
192
|
|
|
192
193
|
transaction_.type = fromRpcType[transaction.type as keyof typeof fromRpcType]
|
|
193
194
|
|
|
195
|
+
if (transaction.aaAuthorizationList) {
|
|
196
|
+
transaction_.authorizationList = AuthorizationTempo.fromRpcList(
|
|
197
|
+
transaction.aaAuthorizationList,
|
|
198
|
+
)
|
|
199
|
+
delete (transaction_ as any).aaAuthorizationList
|
|
200
|
+
}
|
|
194
201
|
if (transaction.calls)
|
|
195
202
|
transaction_.calls = transaction.calls.map((call) => ({
|
|
196
203
|
to: call.to,
|
|
@@ -285,6 +292,10 @@ export function toRpc<pending extends boolean = false>(
|
|
|
285
292
|
|
|
286
293
|
rpc.type = toRpcType[transaction.type as keyof typeof toRpcType]
|
|
287
294
|
|
|
295
|
+
if (transaction.authorizationList)
|
|
296
|
+
rpc.aaAuthorizationList = AuthorizationTempo.toRpcList(
|
|
297
|
+
transaction.authorizationList as AuthorizationTempo.ListSigned,
|
|
298
|
+
)
|
|
288
299
|
if (transaction.calls)
|
|
289
300
|
rpc.calls = transaction.calls.map((call) => ({
|
|
290
301
|
to: call.to,
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Hex, P256, Rlp, Secp256k1, Value, WebAuthnP256 } from 'ox'
|
|
2
2
|
import { describe, expect, test } from 'vitest'
|
|
3
|
+
import * as AuthorizationTempo from './AuthorizationTempo.js'
|
|
3
4
|
import { SignatureEnvelope } from './index.js'
|
|
4
5
|
import * as KeyAuthorization from './KeyAuthorization.js'
|
|
5
6
|
import * as TransactionEnvelopeTempo from './TransactionEnvelopeTempo.js'
|
|
@@ -294,6 +295,58 @@ describe('deserialize', () => {
|
|
|
294
295
|
)
|
|
295
296
|
})
|
|
296
297
|
|
|
298
|
+
test('authorizationList', () => {
|
|
299
|
+
const authorizationList = [
|
|
300
|
+
AuthorizationTempo.from({
|
|
301
|
+
address: '0xbe95c3f554e9fc85ec51be69a3d807a0d55bcf2c',
|
|
302
|
+
chainId: 1,
|
|
303
|
+
nonce: 40n,
|
|
304
|
+
signature: SignatureEnvelope.from({
|
|
305
|
+
r: 49782753348462494199823712700004552394425719014458918871452329774910450607807n,
|
|
306
|
+
s: 33726695977844476214676913201140481102225469284307016937915595756355928419768n,
|
|
307
|
+
yParity: 0,
|
|
308
|
+
}),
|
|
309
|
+
}),
|
|
310
|
+
AuthorizationTempo.from({
|
|
311
|
+
address: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8',
|
|
312
|
+
chainId: 1,
|
|
313
|
+
nonce: 55n,
|
|
314
|
+
signature: SignatureEnvelope.from({
|
|
315
|
+
r: 12345678901234567890n,
|
|
316
|
+
s: 98765432109876543210n,
|
|
317
|
+
yParity: 1,
|
|
318
|
+
}),
|
|
319
|
+
}),
|
|
320
|
+
] as const
|
|
321
|
+
|
|
322
|
+
const transaction_authorizationList = TransactionEnvelopeTempo.from({
|
|
323
|
+
...transaction,
|
|
324
|
+
authorizationList,
|
|
325
|
+
})
|
|
326
|
+
|
|
327
|
+
const serialized = TransactionEnvelopeTempo.serialize(
|
|
328
|
+
transaction_authorizationList,
|
|
329
|
+
)
|
|
330
|
+
expect(TransactionEnvelopeTempo.deserialize(serialized)).toEqual(
|
|
331
|
+
transaction_authorizationList,
|
|
332
|
+
)
|
|
333
|
+
})
|
|
334
|
+
|
|
335
|
+
test('authorizationList (empty)', () => {
|
|
336
|
+
const transaction_authorizationList = TransactionEnvelopeTempo.from({
|
|
337
|
+
...transaction,
|
|
338
|
+
authorizationList: [],
|
|
339
|
+
})
|
|
340
|
+
|
|
341
|
+
const serialized = TransactionEnvelopeTempo.serialize(
|
|
342
|
+
transaction_authorizationList,
|
|
343
|
+
)
|
|
344
|
+
const deserialized = TransactionEnvelopeTempo.deserialize(serialized)
|
|
345
|
+
|
|
346
|
+
// Empty authorizationList should be undefined after deserialization
|
|
347
|
+
expect(deserialized.authorizationList).toBeUndefined()
|
|
348
|
+
})
|
|
349
|
+
|
|
297
350
|
describe('signature', () => {
|
|
298
351
|
test('secp256k1', () => {
|
|
299
352
|
const signature = Secp256k1.sign({
|
|
@@ -496,7 +549,7 @@ describe('deserialize', () => {
|
|
|
496
549
|
[TransactionEnvelope.InvalidSerializedError: Invalid serialized transaction of type "tempo" was provided.
|
|
497
550
|
|
|
498
551
|
Serialized Transaction: "0x76c0"
|
|
499
|
-
Missing Attributes: chainId, maxPriorityFeePerGas, maxFeePerGas, gas, calls, accessList, keyAuthorization, nonceKey, nonce, validBefore, validAfter, feeToken, feePayerSignatureOrSender]
|
|
552
|
+
Missing Attributes: authorizationList, chainId, maxPriorityFeePerGas, maxFeePerGas, gas, calls, accessList, keyAuthorization, nonceKey, nonce, validBefore, validAfter, feeToken, feePayerSignatureOrSender]
|
|
500
553
|
`)
|
|
501
554
|
})
|
|
502
555
|
|
|
@@ -509,7 +562,7 @@ describe('deserialize', () => {
|
|
|
509
562
|
[TransactionEnvelope.InvalidSerializedError: Invalid serialized transaction of type "tempo" was provided.
|
|
510
563
|
|
|
511
564
|
Serialized Transaction: "0x76c20001"
|
|
512
|
-
Missing Attributes: maxFeePerGas, gas, calls, accessList, keyAuthorization, nonceKey, nonce, validBefore, validAfter, feeToken, feePayerSignatureOrSender]
|
|
565
|
+
Missing Attributes: authorizationList, maxFeePerGas, gas, calls, accessList, keyAuthorization, nonceKey, nonce, validBefore, validAfter, feeToken, feePayerSignatureOrSender]
|
|
513
566
|
`)
|
|
514
567
|
})
|
|
515
568
|
|
|
@@ -936,6 +989,123 @@ describe('serialize', () => {
|
|
|
936
989
|
expect(deserialized.keyAuthorization).toEqual(keyAuthorization)
|
|
937
990
|
})
|
|
938
991
|
|
|
992
|
+
test('authorizationList (secp256k1)', () => {
|
|
993
|
+
const authorizationList = [
|
|
994
|
+
AuthorizationTempo.from({
|
|
995
|
+
address: '0xbe95c3f554e9fc85ec51be69a3d807a0d55bcf2c',
|
|
996
|
+
chainId: 1,
|
|
997
|
+
nonce: 40n,
|
|
998
|
+
signature: SignatureEnvelope.from({
|
|
999
|
+
r: 49782753348462494199823712700004552394425719014458918871452329774910450607807n,
|
|
1000
|
+
s: 33726695977844476214676913201140481102225469284307016937915595756355928419768n,
|
|
1001
|
+
yParity: 0,
|
|
1002
|
+
}),
|
|
1003
|
+
}),
|
|
1004
|
+
AuthorizationTempo.from({
|
|
1005
|
+
address: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8',
|
|
1006
|
+
chainId: 1,
|
|
1007
|
+
nonce: 55n,
|
|
1008
|
+
signature: SignatureEnvelope.from({
|
|
1009
|
+
r: 12345678901234567890n,
|
|
1010
|
+
s: 98765432109876543210n,
|
|
1011
|
+
yParity: 1,
|
|
1012
|
+
}),
|
|
1013
|
+
}),
|
|
1014
|
+
] as const
|
|
1015
|
+
|
|
1016
|
+
const transaction = TransactionEnvelopeTempo.from({
|
|
1017
|
+
chainId: 1,
|
|
1018
|
+
calls: [{ to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8' }],
|
|
1019
|
+
nonce: 0n,
|
|
1020
|
+
authorizationList,
|
|
1021
|
+
})
|
|
1022
|
+
|
|
1023
|
+
const serialized = TransactionEnvelopeTempo.serialize(transaction)
|
|
1024
|
+
expect(serialized).toMatchInlineSnapshot(
|
|
1025
|
+
`"0x76f8de01808080d8d79470997970c51812dc3a010c7d01b50e0d17dc79c88080c0808080808080f8b8f85a0194be95c3f554e9fc85ec51be69a3d807a0d55bcf2c28b8416e100a352ec6ad1b70802290e18aeed190704973570f3b8ed42cb9808e2ea6bf4a90a229a244495b41890987806fcbd2d5d23fc0dbe5f5256c2613c039d76db81bf85a019470997970c51812dc3a010c7d01b50e0d17dc79c837b841000000000000000000000000000000000000000000000000ab54a98ceb1f0ad20000000000000000000000000000000000000000000000055aa54d38e5267eea1c"`,
|
|
1026
|
+
)
|
|
1027
|
+
|
|
1028
|
+
const deserialized = TransactionEnvelopeTempo.deserialize(serialized)
|
|
1029
|
+
expect(deserialized.authorizationList).toEqual(authorizationList)
|
|
1030
|
+
})
|
|
1031
|
+
|
|
1032
|
+
test('authorizationList (multiple types)', () => {
|
|
1033
|
+
const privateKey = P256.randomPrivateKey()
|
|
1034
|
+
const publicKey = P256.getPublicKey({ privateKey })
|
|
1035
|
+
|
|
1036
|
+
const authorization1 = AuthorizationTempo.from({
|
|
1037
|
+
address: '0xbe95c3f554e9fc85ec51be69a3d807a0d55bcf2c',
|
|
1038
|
+
chainId: 1,
|
|
1039
|
+
nonce: 40n,
|
|
1040
|
+
})
|
|
1041
|
+
const secp256k1Signature = Secp256k1.sign({
|
|
1042
|
+
payload: AuthorizationTempo.getSignPayload(authorization1),
|
|
1043
|
+
privateKey,
|
|
1044
|
+
})
|
|
1045
|
+
|
|
1046
|
+
const authorization2 = AuthorizationTempo.from({
|
|
1047
|
+
address: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8',
|
|
1048
|
+
chainId: 1,
|
|
1049
|
+
nonce: 55n,
|
|
1050
|
+
})
|
|
1051
|
+
const p256Signature = P256.sign({
|
|
1052
|
+
payload: AuthorizationTempo.getSignPayload(authorization2),
|
|
1053
|
+
privateKey,
|
|
1054
|
+
})
|
|
1055
|
+
|
|
1056
|
+
const authorizationList = [
|
|
1057
|
+
AuthorizationTempo.from(authorization1, {
|
|
1058
|
+
signature: SignatureEnvelope.from({ signature: secp256k1Signature }),
|
|
1059
|
+
}),
|
|
1060
|
+
AuthorizationTempo.from(authorization2, {
|
|
1061
|
+
signature: SignatureEnvelope.from({
|
|
1062
|
+
signature: p256Signature,
|
|
1063
|
+
publicKey,
|
|
1064
|
+
prehash: true,
|
|
1065
|
+
}),
|
|
1066
|
+
}),
|
|
1067
|
+
]
|
|
1068
|
+
|
|
1069
|
+
const transaction = TransactionEnvelopeTempo.from({
|
|
1070
|
+
chainId: 1,
|
|
1071
|
+
calls: [{ to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8' }],
|
|
1072
|
+
nonce: 0n,
|
|
1073
|
+
authorizationList,
|
|
1074
|
+
})
|
|
1075
|
+
|
|
1076
|
+
const serialized = TransactionEnvelopeTempo.serialize(transaction)
|
|
1077
|
+
const deserialized = TransactionEnvelopeTempo.deserialize(serialized)
|
|
1078
|
+
|
|
1079
|
+
expect(deserialized.authorizationList).toHaveLength(2)
|
|
1080
|
+
expect(deserialized.authorizationList?.[0]?.address).toBe(
|
|
1081
|
+
'0xbe95c3f554e9fc85ec51be69a3d807a0d55bcf2c',
|
|
1082
|
+
)
|
|
1083
|
+
expect(deserialized.authorizationList?.[0]?.signature?.type).toBe(
|
|
1084
|
+
'secp256k1',
|
|
1085
|
+
)
|
|
1086
|
+
expect(deserialized.authorizationList?.[1]?.address).toBe(
|
|
1087
|
+
'0x70997970c51812dc3a010c7d01b50e0d17dc79c8',
|
|
1088
|
+
)
|
|
1089
|
+
expect(deserialized.authorizationList?.[1]?.signature?.type).toBe('p256')
|
|
1090
|
+
})
|
|
1091
|
+
|
|
1092
|
+
test('authorizationList (empty)', () => {
|
|
1093
|
+
const transaction = TransactionEnvelopeTempo.from({
|
|
1094
|
+
chainId: 1,
|
|
1095
|
+
calls: [{ to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8' }],
|
|
1096
|
+
nonce: 0n,
|
|
1097
|
+
authorizationList: [],
|
|
1098
|
+
})
|
|
1099
|
+
|
|
1100
|
+
const serialized = TransactionEnvelopeTempo.serialize(transaction)
|
|
1101
|
+
expect(serialized).toMatchInlineSnapshot(
|
|
1102
|
+
`"0x76e501808080d8d79470997970c51812dc3a010c7d01b50e0d17dc79c88080c0808080808080c0"`,
|
|
1103
|
+
)
|
|
1104
|
+
|
|
1105
|
+
const deserialized = TransactionEnvelopeTempo.deserialize(serialized)
|
|
1106
|
+
expect(deserialized.authorizationList).toBeUndefined()
|
|
1107
|
+
})
|
|
1108
|
+
|
|
939
1109
|
describe('with signature', () => {
|
|
940
1110
|
test('secp256k1', () => {
|
|
941
1111
|
const transaction = TransactionEnvelopeTempo.from({
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import * as AccessList from 'ox/AccessList'
|
|
2
2
|
import * as Address from 'ox/Address'
|
|
3
|
-
import type * as Authorization from 'ox/Authorization'
|
|
4
3
|
import * as Errors from 'ox/Errors'
|
|
5
4
|
import * as Hash from 'ox/Hash'
|
|
6
5
|
import * as Hex from 'ox/Hex'
|
|
@@ -14,6 +13,7 @@ import type {
|
|
|
14
13
|
PartialBy,
|
|
15
14
|
UnionPartialBy,
|
|
16
15
|
} from '../internal/types.js'
|
|
16
|
+
import * as AuthorizationTempo from './AuthorizationTempo.js'
|
|
17
17
|
import * as KeyAuthorization from './KeyAuthorization.js'
|
|
18
18
|
import * as SignatureEnvelope from './SignatureEnvelope.js'
|
|
19
19
|
import * as TokenId from './TokenId.js'
|
|
@@ -39,9 +39,9 @@ export type TransactionEnvelopeTempo<
|
|
|
39
39
|
{
|
|
40
40
|
/** EIP-2930 Access List. */
|
|
41
41
|
accessList?: AccessList.AccessList | undefined
|
|
42
|
-
/** EIP-7702 Authorization list for the transaction. */
|
|
42
|
+
/** EIP-7702 (Tempo) Authorization list for the transaction. */
|
|
43
43
|
authorizationList?:
|
|
44
|
-
|
|
|
44
|
+
| AuthorizationTempo.ListSigned<bigintType, numberType>
|
|
45
45
|
| undefined
|
|
46
46
|
/** Array of calls to execute. */
|
|
47
47
|
calls: readonly Call<bigintType>[]
|
|
@@ -226,7 +226,7 @@ export function deserialize(
|
|
|
226
226
|
validAfter,
|
|
227
227
|
feeToken,
|
|
228
228
|
feePayerSignatureOrSender,
|
|
229
|
-
|
|
229
|
+
authorizationList,
|
|
230
230
|
keyAuthorizationOrSignature,
|
|
231
231
|
maybeSignature,
|
|
232
232
|
] = transactionArray as readonly Hex.Hex[]
|
|
@@ -247,6 +247,7 @@ export function deserialize(
|
|
|
247
247
|
)
|
|
248
248
|
throw new TransactionEnvelope.InvalidSerializedError({
|
|
249
249
|
attributes: {
|
|
250
|
+
authorizationList,
|
|
250
251
|
chainId,
|
|
251
252
|
maxPriorityFeePerGas,
|
|
252
253
|
maxFeePerGas,
|
|
@@ -307,6 +308,11 @@ export function deserialize(
|
|
|
307
308
|
if (accessList?.length !== 0 && accessList !== '0x')
|
|
308
309
|
transaction.accessList = AccessList.fromTupleList(accessList as never)
|
|
309
310
|
|
|
311
|
+
if (authorizationList?.length !== 0 && authorizationList !== '0x')
|
|
312
|
+
transaction.authorizationList = AuthorizationTempo.fromTupleList(
|
|
313
|
+
authorizationList as never,
|
|
314
|
+
)
|
|
315
|
+
|
|
310
316
|
if (
|
|
311
317
|
feePayerSignatureOrSender !== '0x' &&
|
|
312
318
|
feePayerSignatureOrSender !== undefined
|
|
@@ -543,6 +549,7 @@ export function serialize(
|
|
|
543
549
|
): Serialized {
|
|
544
550
|
const {
|
|
545
551
|
accessList,
|
|
552
|
+
authorizationList,
|
|
546
553
|
calls,
|
|
547
554
|
chainId,
|
|
548
555
|
feeToken,
|
|
@@ -561,6 +568,9 @@ export function serialize(
|
|
|
561
568
|
const accessTupleList = AccessList.toTupleList(accessList)
|
|
562
569
|
const signature = options.signature || envelope.signature
|
|
563
570
|
|
|
571
|
+
const authorizationTupleList =
|
|
572
|
+
AuthorizationTempo.toTupleList(authorizationList)
|
|
573
|
+
|
|
564
574
|
// Encode calls as RLP list of [to, value, data] tuples
|
|
565
575
|
const callsTupleList = calls.map((call) => [
|
|
566
576
|
call.to ?? '0x',
|
|
@@ -594,7 +604,7 @@ export function serialize(
|
|
|
594
604
|
? TokenId.toAddress(feeToken)
|
|
595
605
|
: '0x',
|
|
596
606
|
feePayerSignatureOrSender,
|
|
597
|
-
|
|
607
|
+
authorizationTupleList,
|
|
598
608
|
...(keyAuthorization ? [KeyAuthorization.toTuple(keyAuthorization)] : []),
|
|
599
609
|
...(signature
|
|
600
610
|
? [SignatureEnvelope.serialize(SignatureEnvelope.from(signature))]
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import type * as Authorization from 'ox/Authorization'
|
|
2
1
|
import type * as Errors from 'ox/Errors'
|
|
3
2
|
import * as Hex from 'ox/Hex'
|
|
4
3
|
import * as ox_TransactionRequest from 'ox/TransactionRequest'
|
|
5
4
|
import type { Compute } from '../internal/types.js'
|
|
5
|
+
import * as AuthorizationTempo from './AuthorizationTempo.js'
|
|
6
6
|
import * as KeyAuthorization from './KeyAuthorization.js'
|
|
7
7
|
import * as TokenId from './TokenId.js'
|
|
8
8
|
import * as Transaction from './Transaction.js'
|
|
@@ -16,7 +16,13 @@ export type TransactionRequest<
|
|
|
16
16
|
numberType = number,
|
|
17
17
|
type extends string = string,
|
|
18
18
|
> = Compute<
|
|
19
|
-
|
|
19
|
+
Omit<
|
|
20
|
+
ox_TransactionRequest.TransactionRequest<bigintType, numberType, type>,
|
|
21
|
+
'authorizationList'
|
|
22
|
+
> & {
|
|
23
|
+
authorizationList?:
|
|
24
|
+
| AuthorizationTempo.ListSigned<bigintType, numberType>
|
|
25
|
+
| undefined
|
|
20
26
|
calls?: readonly Call<bigintType>[] | undefined
|
|
21
27
|
keyAuthorization?: KeyAuthorization.KeyAuthorization<true> | undefined
|
|
22
28
|
keyData?: Hex.Hex | undefined
|
|
@@ -31,8 +37,9 @@ export type TransactionRequest<
|
|
|
31
37
|
/** RPC representation of a {@link ox#TransactionRequest.TransactionRequest}. */
|
|
32
38
|
export type Rpc = Omit<
|
|
33
39
|
TransactionRequest<Hex.Hex, Hex.Hex, string>,
|
|
34
|
-
'keyAuthorization'
|
|
40
|
+
'authorizationList' | 'keyAuthorization'
|
|
35
41
|
> & {
|
|
42
|
+
authorizationList?: AuthorizationTempo.ListRpc | undefined
|
|
36
43
|
keyAuthorization?: KeyAuthorization.Rpc | undefined
|
|
37
44
|
nonceKey?: Hex.Hex | undefined
|
|
38
45
|
}
|
|
@@ -81,8 +88,15 @@ export type Rpc = Omit<
|
|
|
81
88
|
* @returns An RPC request.
|
|
82
89
|
*/
|
|
83
90
|
export function toRpc(request: TransactionRequest): Rpc {
|
|
84
|
-
const request_rpc = ox_TransactionRequest.toRpc(
|
|
91
|
+
const request_rpc = ox_TransactionRequest.toRpc({
|
|
92
|
+
...request,
|
|
93
|
+
authorizationList: undefined,
|
|
94
|
+
}) as Rpc
|
|
85
95
|
|
|
96
|
+
if (request.authorizationList)
|
|
97
|
+
request_rpc.authorizationList = AuthorizationTempo.toRpcList(
|
|
98
|
+
request.authorizationList,
|
|
99
|
+
)
|
|
86
100
|
if (request.calls)
|
|
87
101
|
request_rpc.calls = request.calls.map((call) => ({
|
|
88
102
|
to: call.to ?? '0x',
|
|
@@ -127,7 +141,7 @@ export function toRpc(request: TransactionRequest): Rpc {
|
|
|
127
141
|
|
|
128
142
|
export declare namespace toRpc {
|
|
129
143
|
export type ErrorType =
|
|
130
|
-
|
|
|
144
|
+
| AuthorizationTempo.toRpcList.ErrorType
|
|
131
145
|
| Hex.fromNumber.ErrorType
|
|
132
146
|
| Errors.GlobalErrorType
|
|
133
147
|
}
|
package/src/ox/e2e.test.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
Address,
|
|
3
|
+
Hex,
|
|
3
4
|
P256,
|
|
4
5
|
Secp256k1,
|
|
5
6
|
Value,
|
|
@@ -10,7 +11,11 @@ import { getTransactionCount } from 'viem/actions'
|
|
|
10
11
|
import { beforeEach, describe, expect, test } from 'vitest'
|
|
11
12
|
import { chainId } from '../../test/config.js'
|
|
12
13
|
import { client, fundAddress } from '../../test/viem/config.js'
|
|
13
|
-
import {
|
|
14
|
+
import {
|
|
15
|
+
AuthorizationTempo,
|
|
16
|
+
KeyAuthorization,
|
|
17
|
+
SignatureEnvelope,
|
|
18
|
+
} from './index.js'
|
|
14
19
|
import * as Transaction from './Transaction.js'
|
|
15
20
|
import * as TransactionEnvelopeTempo from './TransactionEnvelopeTempo.js'
|
|
16
21
|
import * as TransactionReceipt from './TransactionReceipt.js'
|
|
@@ -96,8 +101,8 @@ test('behavior: default (secp256k1)', async () => {
|
|
|
96
101
|
expect(transactionIndex).toBeDefined()
|
|
97
102
|
expect(rest).toMatchInlineSnapshot(`
|
|
98
103
|
{
|
|
99
|
-
"aaAuthorizationList": [],
|
|
100
104
|
"accessList": [],
|
|
105
|
+
"authorizationList": [],
|
|
101
106
|
"calls": [
|
|
102
107
|
{
|
|
103
108
|
"data": "0x",
|
|
@@ -154,6 +159,73 @@ test('behavior: default (secp256k1)', async () => {
|
|
|
154
159
|
`)
|
|
155
160
|
})
|
|
156
161
|
|
|
162
|
+
test('behavior: authorizationList (secp256k1)', async () => {
|
|
163
|
+
const privateKey = Secp256k1.randomPrivateKey()
|
|
164
|
+
const address = Address.fromPublicKey(Secp256k1.getPublicKey({ privateKey }))
|
|
165
|
+
|
|
166
|
+
await fundAddress(client, {
|
|
167
|
+
address,
|
|
168
|
+
})
|
|
169
|
+
|
|
170
|
+
const nonce = await getTransactionCount(client, {
|
|
171
|
+
address,
|
|
172
|
+
blockTag: 'pending',
|
|
173
|
+
})
|
|
174
|
+
|
|
175
|
+
const authorization = AuthorizationTempo.from({
|
|
176
|
+
address: '0x0000000000000000000000000000000000000001',
|
|
177
|
+
chainId: 0,
|
|
178
|
+
nonce: BigInt(nonce + 1),
|
|
179
|
+
})
|
|
180
|
+
|
|
181
|
+
const authorizationSigned = AuthorizationTempo.from(authorization, {
|
|
182
|
+
signature: SignatureEnvelope.from(
|
|
183
|
+
Secp256k1.sign({
|
|
184
|
+
payload: AuthorizationTempo.getSignPayload(authorization),
|
|
185
|
+
privateKey,
|
|
186
|
+
}),
|
|
187
|
+
),
|
|
188
|
+
})
|
|
189
|
+
|
|
190
|
+
const transaction = TransactionEnvelopeTempo.from({
|
|
191
|
+
authorizationList: [authorizationSigned],
|
|
192
|
+
calls: [
|
|
193
|
+
{
|
|
194
|
+
to: '0x0000000000000000000000000000000000000000',
|
|
195
|
+
},
|
|
196
|
+
],
|
|
197
|
+
chainId,
|
|
198
|
+
feeToken: '0x20c0000000000000000000000000000000000001',
|
|
199
|
+
nonce: BigInt(nonce),
|
|
200
|
+
gas: 100_000n,
|
|
201
|
+
maxFeePerGas: Value.fromGwei('20'),
|
|
202
|
+
maxPriorityFeePerGas: Value.fromGwei('10'),
|
|
203
|
+
})
|
|
204
|
+
|
|
205
|
+
const signature = Secp256k1.sign({
|
|
206
|
+
payload: TransactionEnvelopeTempo.getSignPayload(transaction),
|
|
207
|
+
privateKey,
|
|
208
|
+
})
|
|
209
|
+
|
|
210
|
+
const serialized_signed = TransactionEnvelopeTempo.serialize(transaction, {
|
|
211
|
+
signature: SignatureEnvelope.from(signature),
|
|
212
|
+
})
|
|
213
|
+
|
|
214
|
+
const receipt = (await client
|
|
215
|
+
.request({
|
|
216
|
+
method: 'eth_sendRawTransactionSync',
|
|
217
|
+
params: [serialized_signed],
|
|
218
|
+
})
|
|
219
|
+
.then((tx) => TransactionReceipt.fromRpc(tx as any)))!
|
|
220
|
+
expect(receipt).toBeDefined()
|
|
221
|
+
|
|
222
|
+
const code = await client.request({
|
|
223
|
+
method: 'eth_getCode',
|
|
224
|
+
params: [address, 'latest'],
|
|
225
|
+
})
|
|
226
|
+
expect(Hex.slice(code, 3)).toBe('0x0000000000000000000000000000000000000001')
|
|
227
|
+
})
|
|
228
|
+
|
|
157
229
|
test('behavior: default (p256)', async () => {
|
|
158
230
|
const privateKey = P256.randomPrivateKey()
|
|
159
231
|
const publicKey = P256.getPublicKey({ privateKey })
|
|
@@ -236,8 +308,8 @@ test('behavior: default (p256)', async () => {
|
|
|
236
308
|
expect(transactionIndex).toBeDefined()
|
|
237
309
|
expect(rest).toMatchInlineSnapshot(`
|
|
238
310
|
{
|
|
239
|
-
"aaAuthorizationList": [],
|
|
240
311
|
"accessList": [],
|
|
312
|
+
"authorizationList": [],
|
|
241
313
|
"calls": [
|
|
242
314
|
{
|
|
243
315
|
"data": "0x",
|
|
@@ -375,8 +447,8 @@ test('behavior: default (p256 - webcrypto)', async () => {
|
|
|
375
447
|
expect(transactionIndex).toBeDefined()
|
|
376
448
|
expect(rest).toMatchInlineSnapshot(`
|
|
377
449
|
{
|
|
378
|
-
"aaAuthorizationList": [],
|
|
379
450
|
"accessList": [],
|
|
451
|
+
"authorizationList": [],
|
|
380
452
|
"calls": [
|
|
381
453
|
{
|
|
382
454
|
"data": "0x",
|
|
@@ -521,8 +593,8 @@ test('behavior: default (webauthn)', async () => {
|
|
|
521
593
|
expect(transactionIndex).toBeDefined()
|
|
522
594
|
expect(rest).toMatchInlineSnapshot(`
|
|
523
595
|
{
|
|
524
|
-
"aaAuthorizationList": [],
|
|
525
596
|
"accessList": [],
|
|
597
|
+
"authorizationList": [],
|
|
526
598
|
"calls": [
|
|
527
599
|
{
|
|
528
600
|
"data": "0x",
|
|
@@ -818,8 +890,8 @@ describe('behavior: keyAuthorization', () => {
|
|
|
818
890
|
expect(transactionIndex).toBeDefined()
|
|
819
891
|
expect(rest).toMatchInlineSnapshot(`
|
|
820
892
|
{
|
|
821
|
-
"aaAuthorizationList": [],
|
|
822
893
|
"accessList": [],
|
|
894
|
+
"authorizationList": [],
|
|
823
895
|
"calls": [
|
|
824
896
|
{
|
|
825
897
|
"data": "0x",
|
|
@@ -1031,8 +1103,8 @@ describe('behavior: keyAuthorization', () => {
|
|
|
1031
1103
|
expect(transactionIndex).toBeDefined()
|
|
1032
1104
|
expect(rest).toMatchInlineSnapshot(`
|
|
1033
1105
|
{
|
|
1034
|
-
"aaAuthorizationList": [],
|
|
1035
1106
|
"accessList": [],
|
|
1107
|
+
"authorizationList": [],
|
|
1036
1108
|
"calls": [
|
|
1037
1109
|
{
|
|
1038
1110
|
"data": "0x",
|
|
@@ -1246,8 +1318,8 @@ describe('behavior: keyAuthorization', () => {
|
|
|
1246
1318
|
expect(transactionIndex).toBeDefined()
|
|
1247
1319
|
expect(rest).toMatchInlineSnapshot(`
|
|
1248
1320
|
{
|
|
1249
|
-
"aaAuthorizationList": [],
|
|
1250
1321
|
"accessList": [],
|
|
1322
|
+
"authorizationList": [],
|
|
1251
1323
|
"calls": [
|
|
1252
1324
|
{
|
|
1253
1325
|
"data": "0x",
|
package/src/ox/index.ts
CHANGED
package/src/viem/Chain.ts
CHANGED
package/src/viem/Formatters.ts
CHANGED
|
@@ -39,12 +39,6 @@ export function formatTransaction(
|
|
|
39
39
|
return {
|
|
40
40
|
...tx,
|
|
41
41
|
accessList: tx.accessList!,
|
|
42
|
-
authorizationList: tx.authorizationList?.map((auth) => ({
|
|
43
|
-
...auth,
|
|
44
|
-
nonce: Number(auth.nonce),
|
|
45
|
-
r: Hex.fromNumber(auth.r, { size: 32 }),
|
|
46
|
-
s: Hex.fromNumber(auth.s, { size: 32 }),
|
|
47
|
-
})),
|
|
48
42
|
feePayerSignature: feePayerSignature
|
|
49
43
|
? {
|
|
50
44
|
r: Hex.fromNumber(feePayerSignature.r, { size: 32 }),
|
|
@@ -105,13 +99,6 @@ export function formatTransactionRequest<chain extends Chain | undefined>(
|
|
|
105
99
|
|
|
106
100
|
const rpc = ox_TransactionRequest.toRpc({
|
|
107
101
|
...request,
|
|
108
|
-
authorizationList: request.authorizationList?.map((auth) => ({
|
|
109
|
-
...auth,
|
|
110
|
-
nonce: BigInt(auth.nonce),
|
|
111
|
-
r: BigInt(auth.r!),
|
|
112
|
-
s: BigInt(auth.s!),
|
|
113
|
-
yParity: Number(auth.yParity),
|
|
114
|
-
})),
|
|
115
102
|
type: 'tempo',
|
|
116
103
|
} as never)
|
|
117
104
|
|