ox 1.0.0-beta.13 → 1.0.0-beta.14
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/dist/tempo/TransactionRequest.d.ts +14 -0
- package/dist/tempo/TransactionRequest.d.ts.map +1 -1
- package/dist/tempo/TransactionRequest.js +64 -27
- package/dist/tempo/TransactionRequest.js.map +1 -1
- package/dist/zod/tempo/RpcSchemaTempo.d.ts +44 -0
- package/dist/zod/tempo/RpcSchemaTempo.d.ts.map +1 -1
- package/dist/zod/tempo/TransactionRequest.d.ts +77 -0
- package/dist/zod/tempo/TransactionRequest.d.ts.map +1 -1
- package/dist/zod/tempo/TransactionRequest.js +78 -11
- package/dist/zod/tempo/TransactionRequest.js.map +1 -1
- package/package.json +1 -1
- package/src/tempo/TransactionRequest.test.ts +174 -1
- package/src/tempo/TransactionRequest.ts +82 -29
- package/src/version.ts +1 -1
- package/src/zod/tempo/TransactionRequest.ts +83 -13
- package/src/zod/tempo/_test/TransactionRequest.test.ts +44 -0
|
@@ -57,6 +57,16 @@ const CallToRpc = z.object({
|
|
|
57
57
|
value: z.optional(uintBigintNumberish()),
|
|
58
58
|
})
|
|
59
59
|
|
|
60
|
+
const Capabilities = z.record(z.string(), z.unknown())
|
|
61
|
+
|
|
62
|
+
const MultisigInit = z.object({
|
|
63
|
+
salt: z_Hex.Hex,
|
|
64
|
+
threshold: z.number(),
|
|
65
|
+
owners: z.readonly(
|
|
66
|
+
z.array(z.object({ owner: z_Address.Address, weight: z.number() })),
|
|
67
|
+
),
|
|
68
|
+
})
|
|
69
|
+
|
|
60
70
|
/** RPC tempo transaction request schema. */
|
|
61
71
|
export const Rpc = z.object({
|
|
62
72
|
accessList: z.optional(z_AccessList.AccessList),
|
|
@@ -64,6 +74,7 @@ export const Rpc = z.object({
|
|
|
64
74
|
blobVersionedHashes: z.optional(z.readonly(z.array(z_Hex.Hex))),
|
|
65
75
|
blobs: z.optional(z.readonly(z.array(z_Hex.Hex))),
|
|
66
76
|
calls: z.optional(z.readonly(z.array(CallRpc))),
|
|
77
|
+
capabilities: z.optional(Capabilities),
|
|
67
78
|
chainId: z.optional(z_Hex.Hex),
|
|
68
79
|
data: z.optional(z_Hex.Hex),
|
|
69
80
|
feePayer: z.optional(z.boolean()),
|
|
@@ -75,10 +86,13 @@ export const Rpc = z.object({
|
|
|
75
86
|
input: z.optional(z_Hex.Hex),
|
|
76
87
|
keyAuthorization: z.optional(z_KeyAuthorization.Rpc),
|
|
77
88
|
keyData: z.optional(z_Hex.Hex),
|
|
89
|
+
keyId: z.optional(z_Address.Address),
|
|
78
90
|
keyType: z.optional(KeyType),
|
|
79
91
|
maxFeePerBlobGas: z.optional(z_Hex.Hex),
|
|
80
92
|
maxFeePerGas: z.optional(z_Hex.Hex),
|
|
81
93
|
maxPriorityFeePerGas: z.optional(z_Hex.Hex),
|
|
94
|
+
multisigInit: z.optional(MultisigInit),
|
|
95
|
+
multisigSignatureCount: z.optional(z.number()),
|
|
82
96
|
nonce: z.optional(z_Hex.Hex),
|
|
83
97
|
nonceKey: z.optional(z_Hex.Hex),
|
|
84
98
|
r: z.optional(z_Hex.Hex),
|
|
@@ -114,6 +128,7 @@ export const Domain = z.object({
|
|
|
114
128
|
blobVersionedHashes: z.optional(z.readonly(z.array(z_Hex.Hex))),
|
|
115
129
|
blobs: z.optional(z.readonly(z.array(z_Hex.Hex))),
|
|
116
130
|
calls: z.optional(z.readonly(z.array(Call))),
|
|
131
|
+
capabilities: z.optional(Capabilities),
|
|
117
132
|
chainId: z.optional(z.number()),
|
|
118
133
|
data: z.optional(z_Hex.Hex),
|
|
119
134
|
feePayer: z.optional(z.boolean()),
|
|
@@ -125,10 +140,13 @@ export const Domain = z.object({
|
|
|
125
140
|
input: z.optional(z_Hex.Hex),
|
|
126
141
|
keyAuthorization: z.optional(z_KeyAuthorization.Domain),
|
|
127
142
|
keyData: z.optional(z_Hex.Hex),
|
|
143
|
+
keyId: z.optional(z_Address.Address),
|
|
128
144
|
keyType: z.optional(KeyType),
|
|
129
145
|
maxFeePerBlobGas: z.optional(z.bigint()),
|
|
130
146
|
maxFeePerGas: z.optional(z.bigint()),
|
|
131
147
|
maxPriorityFeePerGas: z.optional(z.bigint()),
|
|
148
|
+
multisigInit: z.optional(MultisigInit),
|
|
149
|
+
multisigSignatureCount: z.optional(z.number()),
|
|
132
150
|
nonce: z.optional(z.bigint()),
|
|
133
151
|
nonceKey: z.optional(z.union([z.bigint(), z.literal('random')])),
|
|
134
152
|
r: z.optional(z_Hex.Hex),
|
|
@@ -150,6 +168,7 @@ export const DomainToRpc = z.object({
|
|
|
150
168
|
blobVersionedHashes: z.optional(z.readonly(z.array(z_Hex.Hex))),
|
|
151
169
|
blobs: z.optional(z.readonly(z.array(z_Hex.Hex))),
|
|
152
170
|
calls: z.optional(z.readonly(z.array(CallToRpc))),
|
|
171
|
+
capabilities: z.optional(Capabilities),
|
|
153
172
|
chainId: z.optional(uintNumberNumberish()),
|
|
154
173
|
data: z.optional(z_Hex.Hex),
|
|
155
174
|
feePayer: z.optional(z.boolean()),
|
|
@@ -161,10 +180,13 @@ export const DomainToRpc = z.object({
|
|
|
161
180
|
input: z.optional(z_Hex.Hex),
|
|
162
181
|
keyAuthorization: z.optional(z_KeyAuthorization.DomainToRpc),
|
|
163
182
|
keyData: z.optional(z_Hex.Hex),
|
|
183
|
+
keyId: z.optional(z_Address.Address),
|
|
164
184
|
keyType: z.optional(KeyType),
|
|
165
185
|
maxFeePerBlobGas: z.optional(uintBigintNumberish()),
|
|
166
186
|
maxFeePerGas: z.optional(uintBigintNumberish()),
|
|
167
187
|
maxPriorityFeePerGas: z.optional(uintBigintNumberish()),
|
|
188
|
+
multisigInit: z.optional(MultisigInit),
|
|
189
|
+
multisigSignatureCount: z.optional(z.number()),
|
|
168
190
|
nonce: z.optional(uintBigintNumberish()),
|
|
169
191
|
nonceKey: z.optional(z.union([uintBigintNumberish(), z.literal('random')])),
|
|
170
192
|
r: z.optional(z_Hex.Hex),
|
|
@@ -232,6 +254,17 @@ function fromRpc(
|
|
|
232
254
|
z_KeyAuthorization.KeyAuthorization,
|
|
233
255
|
request.keyAuthorization as never,
|
|
234
256
|
) as never
|
|
257
|
+
if (typeof request.capabilities !== 'undefined')
|
|
258
|
+
request_.capabilities = request.capabilities
|
|
259
|
+
if (typeof request.feePayer !== 'undefined')
|
|
260
|
+
request_.feePayer = request.feePayer
|
|
261
|
+
if (typeof request.keyData !== 'undefined') request_.keyData = request.keyData
|
|
262
|
+
if (typeof request.keyId !== 'undefined') request_.keyId = request.keyId
|
|
263
|
+
if (typeof request.keyType !== 'undefined') request_.keyType = request.keyType
|
|
264
|
+
if (typeof request.multisigInit !== 'undefined')
|
|
265
|
+
request_.multisigInit = request.multisigInit
|
|
266
|
+
if (typeof request.multisigSignatureCount !== 'undefined')
|
|
267
|
+
request_.multisigSignatureCount = request.multisigSignatureCount
|
|
235
268
|
if (typeof request.validBefore !== 'undefined')
|
|
236
269
|
request_.validBefore = core_Hex.toNumber(request.validBefore)
|
|
237
270
|
if (typeof request.validAfter !== 'undefined')
|
|
@@ -251,6 +284,22 @@ function toRpc(
|
|
|
251
284
|
authorizationList: undefined,
|
|
252
285
|
} as never) as core_TransactionRequest.Rpc
|
|
253
286
|
|
|
287
|
+
const tempo =
|
|
288
|
+
typeof request.calls !== 'undefined' ||
|
|
289
|
+
typeof request.capabilities !== 'undefined' ||
|
|
290
|
+
typeof request.feePayer !== 'undefined' ||
|
|
291
|
+
typeof request.feeToken !== 'undefined' ||
|
|
292
|
+
typeof request.keyAuthorization !== 'undefined' ||
|
|
293
|
+
typeof request.keyData !== 'undefined' ||
|
|
294
|
+
typeof request.keyId !== 'undefined' ||
|
|
295
|
+
typeof request.keyType !== 'undefined' ||
|
|
296
|
+
typeof request.multisigInit !== 'undefined' ||
|
|
297
|
+
typeof request.multisigSignatureCount !== 'undefined' ||
|
|
298
|
+
typeof request.nonceKey !== 'undefined' ||
|
|
299
|
+
typeof request.validBefore !== 'undefined' ||
|
|
300
|
+
typeof request.validAfter !== 'undefined' ||
|
|
301
|
+
request.type === 'tempo'
|
|
302
|
+
|
|
254
303
|
if (request.authorizationList)
|
|
255
304
|
request_rpc.authorizationList = z.encode(
|
|
256
305
|
z_AuthorizationTempo.ListSignedToRpc,
|
|
@@ -269,15 +318,22 @@ function toRpc(
|
|
|
269
318
|
value: call.value ? encodeNumberish(call.value) : '0x',
|
|
270
319
|
data: call.data ?? '0x',
|
|
271
320
|
}))
|
|
272
|
-
else if (request.to || request.data || request.value)
|
|
321
|
+
else if (request.to || request.data || request.value || tempo)
|
|
273
322
|
request_rpc.calls = [
|
|
274
323
|
{
|
|
275
|
-
to:
|
|
324
|
+
to:
|
|
325
|
+
request.to ||
|
|
326
|
+
(tempo && (!request.data || request.data === '0x')
|
|
327
|
+
? '0x0000000000000000000000000000000000000000'
|
|
328
|
+
: undefined),
|
|
276
329
|
value: request.value ? encodeNumberish(request.value) : '0x',
|
|
277
330
|
data: request.data ?? '0x',
|
|
278
331
|
},
|
|
279
332
|
]
|
|
280
|
-
if (
|
|
333
|
+
if (
|
|
334
|
+
typeof request.feeToken !== 'undefined' &&
|
|
335
|
+
!(request.feePayer === true && !request.feePayerSignature)
|
|
336
|
+
)
|
|
281
337
|
request_rpc.feeToken =
|
|
282
338
|
typeof request.feeToken === 'bigint'
|
|
283
339
|
? z.encode(z_TokenId.address, request.feeToken)
|
|
@@ -287,6 +343,19 @@ function toRpc(
|
|
|
287
343
|
z_KeyAuthorization.KeyAuthorizationToRpc,
|
|
288
344
|
request.keyAuthorization as never,
|
|
289
345
|
) as never
|
|
346
|
+
if (typeof request.capabilities !== 'undefined')
|
|
347
|
+
request_rpc.capabilities = request.capabilities
|
|
348
|
+
if (typeof request.feePayer !== 'undefined')
|
|
349
|
+
request_rpc.feePayer = request.feePayer
|
|
350
|
+
if (typeof request.keyData !== 'undefined')
|
|
351
|
+
request_rpc.keyData = shimKeyData(request.keyData)
|
|
352
|
+
if (typeof request.keyId !== 'undefined') request_rpc.keyId = request.keyId
|
|
353
|
+
if (typeof request.keyType !== 'undefined')
|
|
354
|
+
request_rpc.keyType = request.keyType
|
|
355
|
+
if (typeof request.multisigInit !== 'undefined')
|
|
356
|
+
request_rpc.multisigInit = request.multisigInit
|
|
357
|
+
if (typeof request.multisigSignatureCount !== 'undefined')
|
|
358
|
+
request_rpc.multisigSignatureCount = request.multisigSignatureCount
|
|
290
359
|
if (typeof request.validBefore !== 'undefined')
|
|
291
360
|
request_rpc.validBefore = encodeNumberish(request.validBefore)
|
|
292
361
|
if (typeof request.validAfter !== 'undefined')
|
|
@@ -300,16 +369,7 @@ function toRpc(
|
|
|
300
369
|
})()
|
|
301
370
|
if (nonceKey) request_rpc.nonceKey = nonceKey
|
|
302
371
|
|
|
303
|
-
if (
|
|
304
|
-
typeof request.calls !== 'undefined' ||
|
|
305
|
-
typeof request.feePayer !== 'undefined' ||
|
|
306
|
-
typeof request.feeToken !== 'undefined' ||
|
|
307
|
-
typeof request.keyAuthorization !== 'undefined' ||
|
|
308
|
-
typeof request.nonceKey !== 'undefined' ||
|
|
309
|
-
typeof request.validBefore !== 'undefined' ||
|
|
310
|
-
typeof request.validAfter !== 'undefined' ||
|
|
311
|
-
request.type === 'tempo'
|
|
312
|
-
) {
|
|
372
|
+
if (tempo) {
|
|
313
373
|
request_rpc.type = toRpcType.tempo
|
|
314
374
|
delete request_rpc.data
|
|
315
375
|
delete request_rpc.input
|
|
@@ -320,6 +380,16 @@ function toRpc(
|
|
|
320
380
|
return request_rpc
|
|
321
381
|
}
|
|
322
382
|
|
|
383
|
+
/**
|
|
384
|
+
* Shims key data longer than 4 bytes into a 2-byte big-endian length hint
|
|
385
|
+
* (the node's gas estimator only accepts 1, 2, or 4-byte key data).
|
|
386
|
+
*/
|
|
387
|
+
function shimKeyData(data: core_Hex.Hex): core_Hex.Hex {
|
|
388
|
+
const byteLength = core_Hex.size(data)
|
|
389
|
+
if (byteLength <= 4) return data
|
|
390
|
+
return core_Hex.fromNumber(byteLength, { size: 2 })
|
|
391
|
+
}
|
|
392
|
+
|
|
323
393
|
/** Decodes an RPC signature into a recovered signature. */
|
|
324
394
|
function signatureFromRpc(signature: {
|
|
325
395
|
r: core_Hex.Hex
|
|
@@ -44,6 +44,50 @@ describe('TransactionRequest', () => {
|
|
|
44
44
|
)
|
|
45
45
|
})
|
|
46
46
|
|
|
47
|
+
test('gas-model hints and capabilities round-trip', () => {
|
|
48
|
+
const hints = {
|
|
49
|
+
capabilities: { balanceDiffs: true },
|
|
50
|
+
keyData: '0x0578',
|
|
51
|
+
keyId: '0xcccccccccccccccccccccccccccccccccccccccc',
|
|
52
|
+
keyType: 'webAuthn',
|
|
53
|
+
multisigInit: {
|
|
54
|
+
salt: '0x0000000000000000000000000000000000000000000000000000000000000000',
|
|
55
|
+
threshold: 2,
|
|
56
|
+
owners: [
|
|
57
|
+
{
|
|
58
|
+
owner: '0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
|
|
59
|
+
weight: 1,
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
owner: '0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb',
|
|
63
|
+
weight: 1,
|
|
64
|
+
},
|
|
65
|
+
],
|
|
66
|
+
},
|
|
67
|
+
multisigSignatureCount: 2,
|
|
68
|
+
} as const
|
|
69
|
+
|
|
70
|
+
const decoded = z.decode(z_TransactionRequest.TransactionRequest, {
|
|
71
|
+
...rpc,
|
|
72
|
+
...hints,
|
|
73
|
+
})
|
|
74
|
+
expect(decoded).toMatchObject(hints)
|
|
75
|
+
|
|
76
|
+
const encoded = z.encode(z_TransactionRequest.TransactionRequest, decoded)
|
|
77
|
+
expect(encoded).toMatchObject(hints)
|
|
78
|
+
expect(encoded).toEqual(core_TransactionRequest.toRpc(decoded))
|
|
79
|
+
})
|
|
80
|
+
|
|
81
|
+
test('feeToken is withheld until the fee payer signs (TIP-76)', () => {
|
|
82
|
+
const decoded = z.decode(z_TransactionRequest.TransactionRequest, rpc)
|
|
83
|
+
const pending = z.encode(z_TransactionRequest.TransactionRequest, {
|
|
84
|
+
...decoded,
|
|
85
|
+
feePayer: true,
|
|
86
|
+
})
|
|
87
|
+
expect(pending.feeToken).toBeUndefined()
|
|
88
|
+
expect(pending.feePayer).toBe(true)
|
|
89
|
+
})
|
|
90
|
+
|
|
47
91
|
test('rejects an invalid request', () => {
|
|
48
92
|
expect(
|
|
49
93
|
z.safeDecode(z_TransactionRequest.TransactionRequest, {
|