ox 0.14.41 → 0.14.43

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.
Files changed (73) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/_cjs/tempo/MultisigOperation.js +27 -0
  3. package/_cjs/tempo/MultisigOperation.js.map +1 -1
  4. package/_cjs/tempo/MultisigSimulation.js +115 -0
  5. package/_cjs/tempo/MultisigSimulation.js.map +1 -0
  6. package/_cjs/tempo/SignatureEnvelope.js +12 -21
  7. package/_cjs/tempo/SignatureEnvelope.js.map +1 -1
  8. package/_cjs/tempo/TransactionRequest.js +7 -7
  9. package/_cjs/tempo/TransactionRequest.js.map +1 -1
  10. package/_cjs/tempo/index.js +2 -2
  11. package/_cjs/tempo/index.js.map +1 -1
  12. package/_cjs/version.js +1 -1
  13. package/_esm/tempo/MultisigOperation.js +48 -0
  14. package/_esm/tempo/MultisigOperation.js.map +1 -1
  15. package/_esm/tempo/MultisigSimulation.js +145 -0
  16. package/_esm/tempo/MultisigSimulation.js.map +1 -0
  17. package/_esm/tempo/SignatureEnvelope.js +12 -21
  18. package/_esm/tempo/SignatureEnvelope.js.map +1 -1
  19. package/_esm/tempo/TransactionRequest.js +7 -7
  20. package/_esm/tempo/TransactionRequest.js.map +1 -1
  21. package/_esm/tempo/index.js +4 -4
  22. package/_esm/tempo/index.js.map +1 -1
  23. package/_esm/version.js +1 -1
  24. package/_types/tempo/KeyAuthorization.d.ts +1 -1
  25. package/_types/tempo/KeyAuthorization.d.ts.map +1 -1
  26. package/_types/tempo/MultisigOperation.d.ts +36 -0
  27. package/_types/tempo/MultisigOperation.d.ts.map +1 -1
  28. package/_types/tempo/MultisigSimulation.d.ts +132 -0
  29. package/_types/tempo/MultisigSimulation.d.ts.map +1 -0
  30. package/_types/tempo/RpcSchemaTempo.d.ts +10 -0
  31. package/_types/tempo/RpcSchemaTempo.d.ts.map +1 -1
  32. package/_types/tempo/SignatureEnvelope.d.ts +10 -34
  33. package/_types/tempo/SignatureEnvelope.d.ts.map +1 -1
  34. package/_types/tempo/TransactionRequest.d.ts +9 -9
  35. package/_types/tempo/TransactionRequest.d.ts.map +1 -1
  36. package/_types/tempo/index.d.ts +4 -4
  37. package/_types/tempo/index.d.ts.map +1 -1
  38. package/_types/version.d.ts +1 -1
  39. package/package.json +9 -9
  40. package/tempo/AuthorizationTempo.test.ts +4 -0
  41. package/tempo/KeyAuthorization.test-d.ts +1 -12
  42. package/tempo/KeyAuthorization.test.ts +34 -6
  43. package/tempo/KeyAuthorization.ts +3 -3
  44. package/tempo/MultisigOperation.test.ts +94 -0
  45. package/tempo/MultisigOperation.ts +83 -0
  46. package/tempo/MultisigSimulation/package.json +6 -0
  47. package/tempo/MultisigSimulation.test-d/package.json +6 -0
  48. package/tempo/MultisigSimulation.test-d.ts +33 -0
  49. package/tempo/MultisigSimulation.test.ts +284 -0
  50. package/tempo/MultisigSimulation.ts +266 -0
  51. package/tempo/RpcSchemaTempo.test-d.ts +14 -4
  52. package/tempo/RpcSchemaTempo.ts +9 -0
  53. package/tempo/SignatureEnvelope.test-d.ts +8 -44
  54. package/tempo/SignatureEnvelope.test.ts +92 -51
  55. package/tempo/SignatureEnvelope.ts +27 -61
  56. package/tempo/Transaction.test.ts +61 -0
  57. package/tempo/TransactionRequest.test-d.ts +9 -9
  58. package/tempo/TransactionRequest.test.ts +122 -49
  59. package/tempo/TransactionRequest.ts +20 -16
  60. package/tempo/index.ts +4 -4
  61. package/tempo/multisig.e2e.test.ts +51 -1
  62. package/version.ts +1 -1
  63. package/_cjs/tempo/MultisigWitness.js +0 -92
  64. package/_cjs/tempo/MultisigWitness.js.map +0 -1
  65. package/_esm/tempo/MultisigWitness.js +0 -123
  66. package/_esm/tempo/MultisigWitness.js.map +0 -1
  67. package/_types/tempo/MultisigWitness.d.ts +0 -106
  68. package/_types/tempo/MultisigWitness.d.ts.map +0 -1
  69. package/tempo/MultisigWitness/package.json +0 -6
  70. package/tempo/MultisigWitness.test-d/package.json +0 -6
  71. package/tempo/MultisigWitness.test-d.ts +0 -42
  72. package/tempo/MultisigWitness.test.ts +0 -289
  73. package/tempo/MultisigWitness.ts +0 -210
@@ -53,8 +53,6 @@ type SignatureEnvelopeKey =
53
53
  | 'version'
54
54
 
55
55
  type SignatureEnvelopeRpcKey =
56
- | 'account'
57
- | 'config'
58
56
  | 'keyId'
59
57
  | 'metadata'
60
58
  | 'preHash'
@@ -63,7 +61,6 @@ type SignatureEnvelopeRpcKey =
63
61
  | 'r'
64
62
  | 's'
65
63
  | 'signature'
66
- | 'signatures'
67
64
  | 'type'
68
65
  | 'userAddress'
69
66
  | 'v'
@@ -161,7 +158,7 @@ export type SignatureEnvelopeRpc =
161
158
  Secp256k1Rpc | P256Rpc | WebAuthnRpc | KeychainRpc,
162
159
  SignatureEnvelopeRpcKey
163
160
  >
164
- | MultisigRpcOneOf
161
+ | MultisigRpc
165
162
 
166
163
  /** Primitive signature envelope accepted by protocol sidecars. */
167
164
  export type Primitive<bigintType = bigint, numberType = number> = OneOf<
@@ -215,7 +212,7 @@ export type KeychainRpc = {
215
212
  export interface Multisig<bigintType = bigint, numberType = number> {
216
213
  /** Native multisig account address. */
217
214
  account: Address.Address
218
- /** Complete applicable multisig configuration witness. */
215
+ /** Complete applicable multisig configuration. */
219
216
  config: MultisigConfig.Config<bigintType, numberType>
220
217
  /**
221
218
  * Owner approvals over the multisig owner approval digest. Each approval is
@@ -240,33 +237,8 @@ type MultisigOneOf<bigintType = bigint, numberType = number> = Multisig<
240
237
  version?: undefined
241
238
  }
242
239
 
243
- /** RPC-formatted native multisig signature. */
244
- export type MultisigRpc = {
245
- /** Native multisig account address. */
246
- account: Address.Address
247
- /** Complete applicable multisig configuration witness. */
248
- config: MultisigConfig.Config<number>
249
- /** Structured owner approvals. */
250
- signatures: readonly SignatureEnvelopeRpc[]
251
- /** Multisig RPC signatures are untagged. */
252
- type?: undefined
253
- }
254
-
255
- type MultisigRpcOneOf = MultisigRpc & {
256
- keyId?: undefined
257
- metadata?: undefined
258
- preHash?: undefined
259
- pubKeyX?: undefined
260
- pubKeyY?: undefined
261
- r?: undefined
262
- s?: undefined
263
- signature?: undefined
264
- userAddress?: undefined
265
- v?: undefined
266
- version?: undefined
267
- webauthnData?: undefined
268
- yParity?: undefined
269
- }
240
+ /** Canonical RLP-encoded native multisig signature without the `0x05` type byte. */
241
+ export type MultisigRpc = Hex.Hex
270
242
 
271
243
  export type P256<bigintType = bigint, numberType = number> = {
272
244
  prehash: boolean
@@ -1081,7 +1053,7 @@ export declare namespace from {
1081
1053
  | {
1082
1054
  /** Initial native multisig account, derived from config when omitted. */
1083
1055
  account?: Address.Address | undefined
1084
- /** Initial version-0 multisig configuration witness. */
1056
+ /** Initial version-0 multisig configuration. */
1085
1057
  config: MultisigConfig.Input<0 | 0n>
1086
1058
  /** Primitive or nested owner approvals. */
1087
1059
  signatures: readonly SignatureEnvelope[]
@@ -1090,7 +1062,7 @@ export declare namespace from {
1090
1062
  | {
1091
1063
  /** Native multisig account. */
1092
1064
  account: Address.Address
1093
- /** Complete applicable multisig configuration witness. */
1065
+ /** Complete applicable multisig configuration. */
1094
1066
  config: MultisigConfig.Input
1095
1067
  /** Primitive or nested owner approvals. */
1096
1068
  signatures: readonly SignatureEnvelope[]
@@ -1140,6 +1112,20 @@ export declare namespace from {
1140
1112
  * @returns The signature envelope with bigint values.
1141
1113
  */
1142
1114
  export function fromRpc(envelope: SignatureEnvelopeRpc): SignatureEnvelope {
1115
+ if (typeof envelope === 'string') {
1116
+ const serialized = Hex.concat(serializedMultisigType, envelope)
1117
+ const result = deserialize(serialized)
1118
+ if (
1119
+ result.type !== 'multisig' ||
1120
+ !Hex.isEqual(serialize(result), serialized)
1121
+ )
1122
+ throw new InvalidSerializedError({
1123
+ reason: 'invalid multisig RPC signature',
1124
+ serialized: envelope,
1125
+ })
1126
+ return result
1127
+ }
1128
+
1143
1129
  if (envelope.type === 'secp256k1')
1144
1130
  return {
1145
1131
  signature: Signature.fromRpc(envelope),
@@ -1222,21 +1208,6 @@ export function fromRpc(envelope: SignatureEnvelopeRpc): SignatureEnvelope {
1222
1208
  }
1223
1209
  }
1224
1210
 
1225
- if (
1226
- (envelope as { type?: string | undefined }).type === 'multisig' ||
1227
- ('config' in envelope && 'signatures' in envelope)
1228
- ) {
1229
- const multisig = envelope as MultisigRpc
1230
- const result = {
1231
- account: multisig.account,
1232
- config: MultisigConfig.from(multisig.config),
1233
- signatures: multisig.signatures.map((signature) => fromRpc(signature)),
1234
- type: 'multisig',
1235
- } satisfies Multisig
1236
- assert(result)
1237
- return result
1238
- }
1239
-
1240
1211
  throw new CoercionError({ envelope })
1241
1212
  }
1242
1213
 
@@ -1244,8 +1215,10 @@ export declare namespace fromRpc {
1244
1215
  type ErrorType =
1245
1216
  | assert.ErrorType
1246
1217
  | CoercionError
1218
+ | Hex.concat.ErrorType
1219
+ | Hex.isEqual.ErrorType
1247
1220
  | InvalidSerializedError
1248
- | MultisigConfig.assert.ErrorType
1221
+ | serialize.ErrorType
1249
1222
  | Signature.fromRpc.ErrorType
1250
1223
  | Errors.GlobalErrorType
1251
1224
  }
@@ -1526,7 +1499,7 @@ export declare namespace sortMultisigApprovals {
1526
1499
  type Value = {
1527
1500
  /** The native multisig account address. */
1528
1501
  account: Address.Address
1529
- /** Complete applicable multisig configuration witness. */
1502
+ /** Complete applicable multisig configuration. */
1530
1503
  config: MultisigConfig.Input
1531
1504
  /** The inner transaction sign payload (`tx.signature_hash()`). */
1532
1505
  payload: Hex.Hex | Bytes.Bytes
@@ -1611,15 +1584,7 @@ export function toRpc<const envelope extends toRpc.Input>(
1611
1584
 
1612
1585
  if (type === 'multisig') {
1613
1586
  const multisig = envelope as Multisig
1614
- assert(multisig)
1615
- return {
1616
- account: multisig.account,
1617
- config: {
1618
- ...multisig.config,
1619
- version: Hex.toNumber(Hex.fromNumber(multisig.config.version)),
1620
- },
1621
- signatures: multisig.signatures.map((signature) => toRpc(signature)),
1622
- } as never
1587
+ return Hex.slice(serialize(multisig), 1) as never
1623
1588
  }
1624
1589
 
1625
1590
  throw new CoercionError({ envelope })
@@ -1647,7 +1612,8 @@ export declare namespace toRpc {
1647
1612
  | assert.ErrorType
1648
1613
  | CoercionError
1649
1614
  | Hex.fromNumber.ErrorType
1650
- | Hex.toNumber.ErrorType
1615
+ | Hex.slice.ErrorType
1616
+ | serialize.ErrorType
1651
1617
  | Signature.toRpc.ErrorType
1652
1618
  | Errors.GlobalErrorType
1653
1619
  }
@@ -1,6 +1,9 @@
1
1
  import { Transaction } from 'ox/tempo'
2
2
  import { describe, expect, test } from 'vitest'
3
3
 
4
+ const multisigRpcSignature =
5
+ '0xf897949dba7f426b711d4893c11611eacf7cc334e7146bf83ba000000000000000000000000000000000000000000000000000000000000000008001d7d6947e5f4552091a69125d5dfcb7b8c2659029395bdf01f843b841869437e01f64bebeb78a8a6b30bfd3a993819c8cad82c807515d9b9e9b36f98535dfaa5eebc597715d05f6ce4927747f14fa4cd2acc717fdcd3877146437f8f41b' as const
6
+
4
7
  describe('fromRpc', () => {
5
8
  test('default', () => {
6
9
  const transaction = Transaction.fromRpc({
@@ -527,3 +530,61 @@ describe('toRpc', () => {
527
530
  `)
528
531
  })
529
532
  })
533
+
534
+ describe('roundtrip', () => {
535
+ test('behavior: multisig RPC signature', () => {
536
+ const rpc = {
537
+ accessList: [],
538
+ blockHash:
539
+ '0xc350d807505fb835650f0013632c5515592987ba169bbc6626d9fc54d91f0f0b',
540
+ blockNumber: '0x12f296f',
541
+ calls: [],
542
+ chainId: '0x1',
543
+ feeToken: '0x20c0000000000000000000000000000000000000',
544
+ from: '0x9dba7f426b711d4893c11611eacf7cc334e7146b',
545
+ gas: '0x43f5d',
546
+ hash: '0x353fdfc38a2f26115daadee9f5b8392ce62b84f410957967e2ed56b35338cdd0',
547
+ maxFeePerGas: '0x2',
548
+ maxPriorityFeePerGas: '0x1',
549
+ nonce: '0x357',
550
+ signature: multisigRpcSignature,
551
+ transactionIndex: '0x2',
552
+ type: '0x76',
553
+ } as const satisfies Transaction.TempoRpc
554
+ const transaction = Transaction.fromRpc(rpc)
555
+
556
+ expect({
557
+ rpc: Transaction.toRpc(transaction).signature,
558
+ signature: transaction.signature,
559
+ }).toMatchInlineSnapshot(`
560
+ {
561
+ "rpc": "0xf897949dba7f426b711d4893c11611eacf7cc334e7146bf83ba000000000000000000000000000000000000000000000000000000000000000008001d7d6947e5f4552091a69125d5dfcb7b8c2659029395bdf01f843b841869437e01f64bebeb78a8a6b30bfd3a993819c8cad82c807515d9b9e9b36f98535dfaa5eebc597715d05f6ce4927747f14fa4cd2acc717fdcd3877146437f8f41b",
562
+ "signature": {
563
+ "account": "0x9dba7f426b711d4893c11611eacf7cc334e7146b",
564
+ "config": {
565
+ "owners": [
566
+ {
567
+ "owner": "0x7e5f4552091a69125d5dfcb7b8c2659029395bdf",
568
+ "weight": 1,
569
+ },
570
+ ],
571
+ "salt": "0x0000000000000000000000000000000000000000000000000000000000000000",
572
+ "threshold": 1,
573
+ "version": 0n,
574
+ },
575
+ "signatures": [
576
+ {
577
+ "signature": {
578
+ "r": 60871800714128149016591846789173983752390955456021923556141688418770269698437n,
579
+ "s": 24367763726302312398084372528434045669788111037623467391175388828437596076276n,
580
+ "yParity": 0,
581
+ },
582
+ "type": "secp256k1",
583
+ },
584
+ ],
585
+ "type": "multisig",
586
+ },
587
+ }
588
+ `)
589
+ })
590
+ })
@@ -1,24 +1,24 @@
1
1
  import { expectTypeOf, test } from 'vitest'
2
- import type * as MultisigWitness from './MultisigWitness.js'
2
+ import type * as MultisigSimulation from './MultisigSimulation.js'
3
3
  import type * as TransactionRequest from './TransactionRequest.js'
4
4
 
5
5
  declare const request: TransactionRequest.TransactionRequest
6
6
  declare const rpc: TransactionRequest.Rpc
7
7
 
8
- test('transaction requests use domain multisig witnesses', () => {
9
- expectTypeOf(request.multisigWitness?.config.version).toEqualTypeOf<
8
+ test('transaction requests use domain multisig simulation specs', () => {
9
+ expectTypeOf(request.multisigSimulation?.config.version).toEqualTypeOf<
10
10
  bigint | undefined
11
11
  >()
12
12
 
13
- const approval = request.multisigWitness?.approvals[0]
13
+ const approval = request.multisigSimulation?.approvals[0]
14
14
  if (approval?.type === 'multisig')
15
- expectTypeOf(approval.witness.approvals[0]?.keyType).toEqualTypeOf<
16
- MultisigWitness.NestedPrimitiveApproval['keyType']
15
+ expectTypeOf(approval.spec.approvals[0]?.keyType).toEqualTypeOf<
16
+ MultisigSimulation.NestedPrimitiveApproval['keyType']
17
17
  >()
18
18
  })
19
19
 
20
- test('RPC requests use numeric multisig config versions', () => {
21
- expectTypeOf(rpc.multisigWitness?.config.version).toEqualTypeOf<
22
- number | undefined
20
+ test('RPC requests use encoded multisig configurations', () => {
21
+ expectTypeOf(rpc.multisigSimulation?.config).toEqualTypeOf<
22
+ `0x${string}` | undefined
23
23
  >()
24
24
  })
@@ -1,7 +1,11 @@
1
- import { type MultisigWitness, TransactionRequest } from 'ox/tempo'
1
+ import {
2
+ MultisigConfig,
3
+ type MultisigSimulation,
4
+ TransactionRequest,
5
+ } from 'ox/tempo'
2
6
  import { describe, expect, test } from 'vitest'
3
7
 
4
- const multisigWitnessRpc = {
8
+ const multisigSimulationRpc = {
5
9
  account: '0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
6
10
  approvals: [
7
11
  {
@@ -10,8 +14,7 @@ const multisigWitnessRpc = {
10
14
  type: 'primitive',
11
15
  },
12
16
  {
13
- type: 'multisig',
14
- witness: {
17
+ spec: {
15
18
  account: '0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb',
16
19
  approvals: [
17
20
  {
@@ -20,7 +23,25 @@ const multisigWitnessRpc = {
20
23
  owner: '0x2222222222222222222222222222222222222222',
21
24
  },
22
25
  ],
23
- config: {
26
+ config:
27
+ '0xf83ba022222222222222222222222222222222222222222222222222222222222222220101d7d694222222222222222222222222222222222222222201',
28
+ },
29
+ type: 'multisig',
30
+ },
31
+ ],
32
+ config:
33
+ '0xf852a011111111111111111111111111111111111111111111111111111111111111118002eed694111111111111111111111111111111111111111101d694bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb01',
34
+ } as const satisfies MultisigSimulation.Rpc
35
+
36
+ const multisigSimulation = {
37
+ account: multisigSimulationRpc.account,
38
+ approvals: [
39
+ multisigSimulationRpc.approvals[0],
40
+ {
41
+ spec: {
42
+ account: multisigSimulationRpc.approvals[1].spec.account,
43
+ approvals: multisigSimulationRpc.approvals[1].spec.approvals,
44
+ config: MultisigConfig.from({
24
45
  owners: [
25
46
  {
26
47
  owner: '0x2222222222222222222222222222222222222222',
@@ -29,12 +50,13 @@ const multisigWitnessRpc = {
29
50
  ],
30
51
  salt: `0x${'22'.repeat(32)}`,
31
52
  threshold: 1,
32
- version: 1,
33
- },
53
+ version: 1n,
54
+ }),
34
55
  },
56
+ type: 'multisig',
35
57
  },
36
58
  ],
37
- config: {
59
+ config: MultisigConfig.from({
38
60
  owners: [
39
61
  {
40
62
  owner: '0x1111111111111111111111111111111111111111',
@@ -47,27 +69,8 @@ const multisigWitnessRpc = {
47
69
  ],
48
70
  salt: `0x${'11'.repeat(32)}`,
49
71
  threshold: 2,
50
- version: 0,
51
- },
52
- } as const satisfies MultisigWitness.Rpc
53
-
54
- const multisigWitness = {
55
- ...multisigWitnessRpc,
56
- approvals: [
57
- multisigWitnessRpc.approvals[0],
58
- {
59
- ...multisigWitnessRpc.approvals[1],
60
- witness: {
61
- ...multisigWitnessRpc.approvals[1].witness,
62
- config: {
63
- ...multisigWitnessRpc.approvals[1].witness.config,
64
- version: 1n,
65
- },
66
- },
67
- },
68
- ],
69
- config: { ...multisigWitnessRpc.config, version: 0n },
70
- } as const satisfies MultisigWitness.MultisigWitness
72
+ }),
73
+ } as const satisfies MultisigSimulation.Spec
71
74
 
72
75
  describe('fromRpc', () => {
73
76
  test('default', () => {
@@ -137,19 +140,64 @@ describe('fromRpc', () => {
137
140
  expect(request.nonceKey).toBe(255n)
138
141
  })
139
142
 
140
- test('behavior: multisig witness', () => {
143
+ test('behavior: multisig simulation', () => {
141
144
  const request = TransactionRequest.fromRpc({
142
145
  from: '0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
143
- multisigWitness: multisigWitnessRpc,
146
+ multisigSimulation: multisigSimulationRpc,
144
147
  type: '0x76',
145
148
  })
146
149
 
147
- expect(request.multisigWitness?.config.version).toBe(0n)
148
- const nested = request.multisigWitness?.approvals[1]
149
- expect(nested?.type).toBe('multisig')
150
- if (nested?.type !== 'multisig') throw new Error('expected multisig')
151
- expect(nested.witness.config.version).toBe(1n)
152
- expect(nested.witness.approvals[0]?.keyType).toBe('webAuthn')
150
+ expect(request.multisigSimulation).toMatchInlineSnapshot(`
151
+ {
152
+ "account": "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
153
+ "approvals": [
154
+ {
155
+ "keyType": "secp256k1",
156
+ "owner": "0x1111111111111111111111111111111111111111",
157
+ "type": "primitive",
158
+ },
159
+ {
160
+ "spec": {
161
+ "account": "0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
162
+ "approvals": [
163
+ {
164
+ "keyData": "0x0578",
165
+ "keyType": "webAuthn",
166
+ "owner": "0x2222222222222222222222222222222222222222",
167
+ },
168
+ ],
169
+ "config": {
170
+ "owners": [
171
+ {
172
+ "owner": "0x2222222222222222222222222222222222222222",
173
+ "weight": 1,
174
+ },
175
+ ],
176
+ "salt": "0x2222222222222222222222222222222222222222222222222222222222222222",
177
+ "threshold": 1,
178
+ "version": 1n,
179
+ },
180
+ },
181
+ "type": "multisig",
182
+ },
183
+ ],
184
+ "config": {
185
+ "owners": [
186
+ {
187
+ "owner": "0x1111111111111111111111111111111111111111",
188
+ "weight": 1,
189
+ },
190
+ {
191
+ "owner": "0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
192
+ "weight": 1,
193
+ },
194
+ ],
195
+ "salt": "0x1111111111111111111111111111111111111111111111111111111111111111",
196
+ "threshold": 2,
197
+ "version": 0n,
198
+ },
199
+ }
200
+ `)
153
201
  })
154
202
 
155
203
  test('behavior: empty', () => {
@@ -206,18 +254,43 @@ describe('toRpc', () => {
206
254
  `)
207
255
  })
208
256
 
209
- test('behavior: multisig witness', () => {
257
+ test('behavior: multisig simulation', () => {
210
258
  const request = TransactionRequest.toRpc({
211
259
  from: '0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
212
- multisigWitness,
260
+ multisigSimulation,
213
261
  })
214
262
 
215
- expect(request.multisigWitness?.config.version).toBe(0)
216
- const nested = request.multisigWitness?.approvals[1]
217
- expect(nested?.type).toBe('multisig')
218
- if (nested?.type !== 'multisig') throw new Error('expected multisig')
219
- expect(nested.witness.config.version).toBe(1)
220
- expect(request.type).toBe('0x76')
263
+ expect(request).toMatchInlineSnapshot(`
264
+ {
265
+ "from": "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
266
+ "multisigSimulation": {
267
+ "account": "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
268
+ "approvals": [
269
+ {
270
+ "keyType": "secp256k1",
271
+ "owner": "0x1111111111111111111111111111111111111111",
272
+ "type": "primitive",
273
+ },
274
+ {
275
+ "spec": {
276
+ "account": "0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
277
+ "approvals": [
278
+ {
279
+ "keyData": "0x0578",
280
+ "keyType": "webAuthn",
281
+ "owner": "0x2222222222222222222222222222222222222222",
282
+ },
283
+ ],
284
+ "config": "0xf83ba022222222222222222222222222222222222222222222222222222222222222220101d7d694222222222222222222222222222222222222222201",
285
+ },
286
+ "type": "multisig",
287
+ },
288
+ ],
289
+ "config": "0xf852a011111111111111111111111111111111111111111111111111111111111111118002eed694111111111111111111111111111111111111111101d694bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb01",
290
+ },
291
+ "type": "0x76",
292
+ }
293
+ `)
221
294
  })
222
295
  })
223
296
 
@@ -241,7 +314,7 @@ describe('roundtrip', () => {
241
314
  nonceKey: 255n,
242
315
  gas: 100000n,
243
316
  maxFeePerGas: 1000000000n,
244
- multisigWitness,
317
+ multisigSimulation,
245
318
  }
246
319
 
247
320
  const rpc = TransactionRequest.toRpc(original)
@@ -262,7 +335,7 @@ describe('roundtrip', () => {
262
335
  expect(converted.nonceKey).toBe(original.nonceKey)
263
336
  expect(converted.gas).toBe(original.gas)
264
337
  expect(converted.maxFeePerGas).toBe(original.maxFeePerGas)
265
- expect(converted.multisigWitness).toEqual(original.multisigWitness)
338
+ expect(converted.multisigSimulation).toEqual(original.multisigSimulation)
266
339
  expect(converted.type).toBe('tempo')
267
340
  })
268
341
 
@@ -280,7 +353,7 @@ describe('roundtrip', () => {
280
353
  validAfter: '0x32',
281
354
  nonceKey: '0xff',
282
355
  gas: '0x186a0',
283
- multisigWitness: multisigWitnessRpc,
356
+ multisigSimulation: multisigSimulationRpc,
284
357
  type: '0x76',
285
358
  }
286
359
 
@@ -293,7 +366,7 @@ describe('roundtrip', () => {
293
366
  expect(rpc.validAfter).toBe(original.validAfter)
294
367
  expect(rpc.nonceKey).toBe(original.nonceKey)
295
368
  expect(rpc.gas).toBe(original.gas)
296
- expect(rpc.multisigWitness).toEqual(original.multisigWitness)
369
+ expect(rpc.multisigSimulation).toEqual(original.multisigSimulation)
297
370
  expect(rpc.type).toBe('0x76')
298
371
  })
299
372
  })
@@ -4,7 +4,7 @@ import type { Compute } from '../core/internal/types.js'
4
4
  import * as ox_TransactionRequest from '../core/TransactionRequest.js'
5
5
  import * as AuthorizationTempo from './AuthorizationTempo.js'
6
6
  import * as KeyAuthorization from './KeyAuthorization.js'
7
- import * as MultisigWitness from './MultisigWitness.js'
7
+ import * as MultisigSimulation from './MultisigSimulation.js'
8
8
  import * as TempoAddress from './TempoAddress.js'
9
9
  import * as TokenId from './TokenId.js'
10
10
  import * as Transaction from './Transaction.js'
@@ -34,27 +34,27 @@ export type TransactionRequest<
34
34
  | AuthorizationTempo.ListSigned<bigintType, numberType>
35
35
  | undefined
36
36
  calls?: readonly Call<bigintType, addressType>[] | undefined
37
+ feePayer?: boolean | undefined
38
+ feeToken?: TokenId.TokenIdOrAddress<addressType> | undefined
37
39
  keyAuthorization?: KeyAuthorization.KeyAuthorization<true> | undefined
38
40
  keyData?: Hex.Hex | undefined
39
41
  keyType?: KeyType | undefined
40
- feePayer?: boolean | undefined
41
- feeToken?: TokenId.TokenIdOrAddress<addressType> | undefined
42
- multisigWitness?: MultisigWitness.MultisigWitness<bigintType> | undefined
42
+ multisigSimulation?: MultisigSimulation.Spec | undefined
43
43
  nonceKey?: 'random' | bigintType | undefined
44
- validBefore?: numberType | undefined
45
44
  validAfter?: numberType | undefined
45
+ validBefore?: numberType | undefined
46
46
  }
47
47
  >
48
48
 
49
49
  /** RPC representation of a {@link ox#TransactionRequest.TransactionRequest}. */
50
50
  export type Rpc = Omit<
51
51
  TransactionRequest<Hex.Hex, Hex.Hex, string, Hex.Hex>,
52
- 'authorizationList' | 'feeToken' | 'keyAuthorization' | 'multisigWitness'
52
+ 'authorizationList' | 'feeToken' | 'keyAuthorization' | 'multisigSimulation'
53
53
  > & {
54
54
  authorizationList?: AuthorizationTempo.ListRpc | undefined
55
55
  feeToken?: Hex.Hex | undefined
56
56
  keyAuthorization?: KeyAuthorization.Rpc | undefined
57
- multisigWitness?: MultisigWitness.Rpc | undefined
57
+ multisigSimulation?: MultisigSimulation.Rpc | undefined
58
58
  nonceKey?: Hex.Hex | undefined
59
59
  }
60
60
 
@@ -79,7 +79,7 @@ export type Rpc = Omit<
79
79
  * @returns A transaction request.
80
80
  */
81
81
  export function fromRpc(request: Rpc): TransactionRequest {
82
- const { authorizationList: _, multisigWitness: __, ...rest } = request
82
+ const { authorizationList: _, multisigSimulation: __, ...rest } = request
83
83
  const request_ = ox_TransactionRequest.fromRpc(
84
84
  rest as any,
85
85
  ) as TransactionRequest
@@ -110,8 +110,10 @@ export function fromRpc(request: Rpc): TransactionRequest {
110
110
  request_.keyAuthorization = KeyAuthorization.fromRpc(
111
111
  request.keyAuthorization,
112
112
  )
113
- if (request.multisigWitness)
114
- request_.multisigWitness = MultisigWitness.fromRpc(request.multisigWitness)
113
+ if (request.multisigSimulation)
114
+ request_.multisigSimulation = MultisigSimulation.fromRpc(
115
+ request.multisigSimulation,
116
+ )
115
117
  if (typeof request.validBefore !== 'undefined')
116
118
  request_.validBefore = Hex.toNumber(request.validBefore as Hex.Hex)
117
119
  if (typeof request.validAfter !== 'undefined')
@@ -125,9 +127,9 @@ export function fromRpc(request: Rpc): TransactionRequest {
125
127
  export declare namespace fromRpc {
126
128
  export type ErrorType =
127
129
  | AuthorizationTempo.fromRpcList.ErrorType
128
- | MultisigWitness.fromRpc.ErrorType
129
- | Hex.toNumber.ErrorType
130
130
  | Hex.toBigInt.ErrorType
131
+ | Hex.toNumber.ErrorType
132
+ | MultisigSimulation.fromRpc.ErrorType
131
133
  | Errors.GlobalErrorType
132
134
  }
133
135
 
@@ -210,8 +212,10 @@ export function toRpc(request: TransactionRequest): Rpc {
210
212
  request_rpc.keyAuthorization = KeyAuthorization.toRpc(
211
213
  request.keyAuthorization,
212
214
  )
213
- if (request.multisigWitness)
214
- request_rpc.multisigWitness = MultisigWitness.toRpc(request.multisigWitness)
215
+ if (request.multisigSimulation)
216
+ request_rpc.multisigSimulation = MultisigSimulation.toRpc(
217
+ request.multisigSimulation,
218
+ )
215
219
  if (typeof request.validBefore !== 'undefined')
216
220
  request_rpc.validBefore = Hex.fromNumber(request.validBefore)
217
221
  if (typeof request.validAfter !== 'undefined')
@@ -230,7 +234,7 @@ export function toRpc(request: TransactionRequest): Rpc {
230
234
  typeof request.feePayer !== 'undefined' ||
231
235
  typeof request.feeToken !== 'undefined' ||
232
236
  typeof request.keyAuthorization !== 'undefined' ||
233
- typeof request.multisigWitness !== 'undefined' ||
237
+ typeof request.multisigSimulation !== 'undefined' ||
234
238
  typeof request.nonceKey !== 'undefined' ||
235
239
  typeof request.validBefore !== 'undefined' ||
236
240
  typeof request.validAfter !== 'undefined' ||
@@ -249,7 +253,7 @@ export function toRpc(request: TransactionRequest): Rpc {
249
253
  export declare namespace toRpc {
250
254
  export type ErrorType =
251
255
  | AuthorizationTempo.toRpcList.ErrorType
252
- | MultisigWitness.toRpc.ErrorType
256
+ | MultisigSimulation.toRpc.ErrorType
253
257
  | Hex.fromNumber.ErrorType
254
258
  | Errors.GlobalErrorType
255
259
  }
package/tempo/index.ts CHANGED
@@ -160,14 +160,14 @@ export * as MultisigConfig from './MultisigConfig.js'
160
160
  */
161
161
  export * as MultisigOperation from './MultisigOperation.js'
162
162
  /**
163
- * Native multisig RPC simulation witness utilities.
163
+ * Native multisig RPC simulation utilities.
164
164
  *
165
- * Converts complete root and nested owner witnesses between their domain and
166
- * Tempo JSON-RPC representations.
165
+ * Converts complete root and nested owner specs between their domain and Tempo
166
+ * JSON-RPC representations.
167
167
  *
168
168
  * @category Reference
169
169
  */
170
- export * as MultisigWitness from './MultisigWitness.js'
170
+ export * as MultisigSimulation from './MultisigSimulation.js'
171
171
  /**
172
172
  * Utilities for constructing period durations (in seconds) for recurring spending limits.
173
173
  *