ox 0.14.39 → 0.14.41

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 (54) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/_cjs/tempo/MultisigOperation.js +30 -45
  3. package/_cjs/tempo/MultisigOperation.js.map +1 -1
  4. package/_cjs/tempo/MultisigWitness.js +92 -0
  5. package/_cjs/tempo/MultisigWitness.js.map +1 -0
  6. package/_cjs/tempo/SignatureEnvelope.js +5 -2
  7. package/_cjs/tempo/SignatureEnvelope.js.map +1 -1
  8. package/_cjs/tempo/TransactionRequest.js +7 -1
  9. package/_cjs/tempo/TransactionRequest.js.map +1 -1
  10. package/_cjs/tempo/index.js +2 -1
  11. package/_cjs/tempo/index.js.map +1 -1
  12. package/_cjs/version.js +1 -1
  13. package/_esm/tempo/MultisigOperation.js +31 -48
  14. package/_esm/tempo/MultisigOperation.js.map +1 -1
  15. package/_esm/tempo/MultisigWitness.js +123 -0
  16. package/_esm/tempo/MultisigWitness.js.map +1 -0
  17. package/_esm/tempo/SignatureEnvelope.js +5 -2
  18. package/_esm/tempo/SignatureEnvelope.js.map +1 -1
  19. package/_esm/tempo/TransactionRequest.js +7 -1
  20. package/_esm/tempo/TransactionRequest.js.map +1 -1
  21. package/_esm/tempo/index.js +9 -0
  22. package/_esm/tempo/index.js.map +1 -1
  23. package/_esm/version.js +1 -1
  24. package/_types/tempo/MultisigOperation.d.ts +4 -25
  25. package/_types/tempo/MultisigOperation.d.ts.map +1 -1
  26. package/_types/tempo/MultisigWitness.d.ts +106 -0
  27. package/_types/tempo/MultisigWitness.d.ts.map +1 -0
  28. package/_types/tempo/SignatureEnvelope.d.ts +3 -3
  29. package/_types/tempo/SignatureEnvelope.d.ts.map +1 -1
  30. package/_types/tempo/TransactionRequest.d.ts +6 -3
  31. package/_types/tempo/TransactionRequest.d.ts.map +1 -1
  32. package/_types/tempo/index.d.ts +9 -0
  33. package/_types/tempo/index.d.ts.map +1 -1
  34. package/_types/version.d.ts +1 -1
  35. package/package.json +16 -1
  36. package/tempo/KeyAuthorization.test-d.ts +1 -1
  37. package/tempo/MultisigOperation.test-d.ts +0 -6
  38. package/tempo/MultisigOperation.test.ts +196 -145
  39. package/tempo/MultisigOperation.ts +40 -83
  40. package/tempo/MultisigWitness/package.json +6 -0
  41. package/tempo/MultisigWitness.test-d/package.json +6 -0
  42. package/tempo/MultisigWitness.test-d.ts +42 -0
  43. package/tempo/MultisigWitness.test.ts +289 -0
  44. package/tempo/MultisigWitness.ts +210 -0
  45. package/tempo/RpcSchemaTempo.test-d.ts +25 -0
  46. package/tempo/SignatureEnvelope.test-d.ts +4 -4
  47. package/tempo/SignatureEnvelope.test.ts +2 -2
  48. package/tempo/SignatureEnvelope.ts +9 -5
  49. package/tempo/TransactionRequest.test-d/package.json +6 -0
  50. package/tempo/TransactionRequest.test-d.ts +24 -0
  51. package/tempo/TransactionRequest.test.ts +102 -1
  52. package/tempo/TransactionRequest.ts +12 -2
  53. package/tempo/index.ts +9 -0
  54. package/version.ts +1 -1
@@ -0,0 +1,210 @@
1
+ import type * as Address from '../core/Address.js'
2
+ import * as Errors from '../core/Errors.js'
3
+ import * as Hex from '../core/Hex.js'
4
+ import type { Compute } from '../core/internal/types.js'
5
+ import * as MultisigConfig from './MultisigConfig.js'
6
+ import type * as SignatureEnvelope from './SignatureEnvelope.js'
7
+
8
+ /** Native multisig owner approval used for RPC simulation. */
9
+ export type Approval<versionType = bigint> =
10
+ | NestedApproval<versionType>
11
+ | PrimitiveApproval
12
+
13
+ /** Native multisig witness used to construct an RPC simulation signature. */
14
+ export type MultisigWitness<versionType = bigint> = Compute<{
15
+ /** Account authorized by this witness. */
16
+ account: Address.Address
17
+ /** Owner approvals to model. */
18
+ approvals: readonly Approval<versionType>[]
19
+ /** Complete applicable configuration. */
20
+ config: MultisigConfig.Config<versionType>
21
+ }>
22
+
23
+ /** Nested native multisig owner approval used for RPC simulation. */
24
+ export type NestedApproval<versionType = bigint> = {
25
+ /** Approval type. */
26
+ type: 'multisig'
27
+ /** Depth-2 multisig witness. */
28
+ witness: NestedWitness<versionType>
29
+ }
30
+
31
+ /** Primitive approval in a depth-2 multisig simulation witness. */
32
+ export type NestedPrimitiveApproval = {
33
+ /** Optional signature-specific gas-estimation data. */
34
+ keyData?: Hex.Hex | undefined
35
+ /** Signature type to model. Omission uses a maximum-size WebAuthn signature. */
36
+ keyType?: SignatureEnvelope.Type | undefined
37
+ /** Configured owner address. */
38
+ owner: Address.Address
39
+ }
40
+
41
+ /** Depth-2 native multisig witness used for RPC simulation. */
42
+ export type NestedWitness<versionType = bigint> = {
43
+ /** Nested multisig account. */
44
+ account: Address.Address
45
+ /** Primitive owner approvals to model. */
46
+ approvals: readonly NestedPrimitiveApproval[]
47
+ /** Complete applicable configuration. */
48
+ config: MultisigConfig.Config<versionType>
49
+ }
50
+
51
+ /** Primitive owner approval used for RPC simulation. */
52
+ export type PrimitiveApproval = {
53
+ /** Optional signature-specific gas-estimation data. */
54
+ keyData?: Hex.Hex | undefined
55
+ /** Signature type to model. Omission uses a maximum-size WebAuthn signature. */
56
+ keyType?: SignatureEnvelope.Type | undefined
57
+ /** Configured owner address. */
58
+ owner: Address.Address
59
+ /** Approval type. */
60
+ type: 'primitive'
61
+ }
62
+
63
+ /** JSON-RPC representation of a native multisig simulation witness. */
64
+ export type Rpc = MultisigWitness<number>
65
+
66
+ /**
67
+ * Converts a JSON-RPC multisig witness to its domain representation.
68
+ *
69
+ * @example
70
+ * ```ts twoslash
71
+ * // @noErrors
72
+ * import { MultisigWitness } from 'ox/tempo'
73
+ *
74
+ * const witness = MultisigWitness.fromRpc(witnessRpc)
75
+ * ```
76
+ *
77
+ * @param witness - JSON-RPC multisig witness.
78
+ * @returns The multisig witness with bigint configuration versions.
79
+ */
80
+ export function fromRpc(witness: Rpc): MultisigWitness {
81
+ const { account, approvals, config } = witness
82
+ assertApprovalCount(approvals)
83
+ return {
84
+ account,
85
+ approvals: approvals.map((approval) => {
86
+ if (approval.type === 'primitive') return approval
87
+ assertApprovalCount(approval.witness.approvals)
88
+ return {
89
+ type: 'multisig',
90
+ witness: {
91
+ account: approval.witness.account,
92
+ approvals: approval.witness.approvals,
93
+ config: MultisigConfig.from(approval.witness.config),
94
+ },
95
+ }
96
+ }),
97
+ config: MultisigConfig.from(config),
98
+ }
99
+ }
100
+
101
+ export declare namespace fromRpc {
102
+ /** Error type for `fromRpc`. */
103
+ export type ErrorType =
104
+ | InvalidWitnessError
105
+ | MultisigConfig.assert.ErrorType
106
+ | Errors.GlobalErrorType
107
+ }
108
+
109
+ /**
110
+ * Converts a multisig witness to its JSON-RPC representation.
111
+ *
112
+ * @example
113
+ * ```ts twoslash
114
+ * // @noErrors
115
+ * import { MultisigWitness } from 'ox/tempo'
116
+ *
117
+ * const witnessRpc = MultisigWitness.toRpc(witness)
118
+ * ```
119
+ *
120
+ * @param witness - Multisig witness.
121
+ * @returns The JSON-RPC multisig witness with numeric configuration versions.
122
+ */
123
+ export function toRpc(witness: MultisigWitness): Rpc {
124
+ const { account, approvals, config } = witness
125
+ assertApprovalCount(approvals)
126
+ return {
127
+ account,
128
+ approvals: approvals.map((approval) => {
129
+ if (approval.type === 'primitive')
130
+ return {
131
+ ...approval,
132
+ ...(typeof approval.keyData !== 'undefined'
133
+ ? { keyData: shimKeyData(approval.keyData) }
134
+ : {}),
135
+ }
136
+ assertApprovalCount(approval.witness.approvals)
137
+ return {
138
+ type: 'multisig',
139
+ witness: {
140
+ account: approval.witness.account,
141
+ approvals: approval.witness.approvals.map((approval) => ({
142
+ ...approval,
143
+ ...(typeof approval.keyData !== 'undefined'
144
+ ? { keyData: shimKeyData(approval.keyData) }
145
+ : {}),
146
+ })),
147
+ config: configToRpc(approval.witness.config),
148
+ },
149
+ }
150
+ }),
151
+ config: configToRpc(config),
152
+ }
153
+ }
154
+
155
+ export declare namespace toRpc {
156
+ /** Error type for `toRpc`. */
157
+ export type ErrorType =
158
+ | Hex.fromNumber.ErrorType
159
+ | Hex.toNumber.ErrorType
160
+ | InvalidWitnessError
161
+ | MultisigConfig.assert.ErrorType
162
+ | Errors.GlobalErrorType
163
+ }
164
+
165
+ /** @internal */
166
+ function assertApprovalCount(approvals: readonly unknown[]) {
167
+ if (approvals.length > MultisigConfig.maxSignatures)
168
+ throw new InvalidWitnessError({
169
+ reason: `approval count exceeds ${MultisigConfig.maxSignatures}`,
170
+ })
171
+ }
172
+
173
+ /** @internal */
174
+ function configToRpc(
175
+ config: MultisigConfig.Config,
176
+ ): MultisigConfig.Config<number> {
177
+ const value = MultisigConfig.from(config)
178
+ return {
179
+ ...value,
180
+ version: Hex.toNumber(Hex.fromNumber(Number(value.version))),
181
+ }
182
+ }
183
+
184
+ /**
185
+ * Shims key data longer than 4 bytes into a 2-byte big-endian length hint.
186
+ * The node's gas estimator only accepts 1, 2, or 4-byte key data as a
187
+ * signature-size hint; anything else silently falls back to the default.
188
+ * @internal
189
+ */
190
+ function shimKeyData(data: Hex.Hex): Hex.Hex {
191
+ const size = Hex.size(data)
192
+ if (size <= 4) return data
193
+ return Hex.fromNumber(size, { size: 2 })
194
+ }
195
+
196
+ /** Thrown when a native multisig witness is invalid. */
197
+ export class InvalidWitnessError extends Errors.BaseError {
198
+ override readonly name = 'MultisigWitness.InvalidWitnessError'
199
+ constructor(options: InvalidWitnessError.Options) {
200
+ super(`Invalid multisig witness: ${options.reason}.`)
201
+ }
202
+ }
203
+
204
+ export declare namespace InvalidWitnessError {
205
+ /** Error construction options. */
206
+ export type Options = {
207
+ /** Validation failure. */
208
+ reason: string
209
+ }
210
+ }
@@ -2,14 +2,19 @@ import type { Provider } from 'ox'
2
2
  import type {
3
3
  KeyAuthorization,
4
4
  MultisigOperation,
5
+ MultisigWitness,
5
6
  RpcSchemaTempo,
6
7
  } from 'ox/tempo'
7
8
  import { expectTypeOf, test } from 'vitest'
8
9
  import type * as Hex from '../core/Hex.js'
9
10
 
10
11
  declare const provider: Provider.Provider<{ schema: RpcSchemaTempo.Multisig }>
12
+ declare const tempoProvider: Provider.Provider<{
13
+ schema: RpcSchemaTempo.Tempo
14
+ }>
11
15
  declare const hash: Hex.Hex
12
16
  declare const keyAuthorization: KeyAuthorization.Rpc
17
+ declare const multisigWitness: MultisigWitness.Rpc
13
18
  declare const serializedTransaction: Hex.Hex
14
19
  declare const signature: Hex.Hex
15
20
 
@@ -54,3 +59,23 @@ test('multisig provider methods', () => {
54
59
  }),
55
60
  ).resolves.toEqualTypeOf<MultisigOperation.Rpc | null>()
56
61
  })
62
+
63
+ test('tempo simulation accepts multisig witnesses', () => {
64
+ tempoProvider.request({
65
+ method: 'tempo_simulateV1',
66
+ params: [
67
+ {
68
+ blockStateCalls: [
69
+ {
70
+ calls: [
71
+ {
72
+ multisigWitness,
73
+ },
74
+ ],
75
+ },
76
+ ],
77
+ },
78
+ 'latest',
79
+ ],
80
+ })
81
+ })
@@ -37,11 +37,11 @@ test('toRpc preserves the signature type', () => {
37
37
  test('MultisigRpc carries one complete witness shape', () => {
38
38
  const rpc = {
39
39
  account: '0x1111111111111111111111111111111111111111',
40
- config: MultisigConfig.toRpc(config),
40
+ config: { ...config, version: 0 },
41
41
  signatures: [signatureRpc],
42
42
  } as const satisfies SignatureEnvelope.MultisigRpc
43
43
 
44
- expectTypeOf(rpc.config).toMatchTypeOf<MultisigConfig.Rpc>()
44
+ expectTypeOf(rpc.config).toMatchTypeOf<MultisigConfig.Config<number>>()
45
45
  expectTypeOf(rpc.signatures).toMatchTypeOf<
46
46
  readonly SignatureEnvelope.SignatureEnvelopeRpc[]
47
47
  >()
@@ -92,7 +92,7 @@ test('MultisigRpc rejects old witness shapes', () => {
92
92
 
93
93
  const serialized = {
94
94
  account: '0x1111111111111111111111111111111111111111',
95
- config: MultisigConfig.toRpc(config),
95
+ config: { ...config, version: 0 },
96
96
  signatures: ['0x1234'],
97
97
  } as const
98
98
  // @ts-expect-error Owner approvals use structured RPC envelopes.
@@ -100,7 +100,7 @@ test('MultisigRpc rejects old witness shapes', () => {
100
100
 
101
101
  const tagged = {
102
102
  account: '0x1111111111111111111111111111111111111111',
103
- config: MultisigConfig.toRpc(config),
103
+ config: { ...config, version: 0 },
104
104
  signatures: [signatureRpc],
105
105
  type: 'multisig',
106
106
  } as const
@@ -3035,7 +3035,7 @@ describe('multisig', () => {
3035
3035
  ],
3036
3036
  "salt": "0x0000000000000000000000000000000000000000000000000000000000000000",
3037
3037
  "threshold": 1,
3038
- "version": "0x1",
3038
+ "version": 1,
3039
3039
  },
3040
3040
  "signatures": [
3041
3041
  {
@@ -3057,7 +3057,7 @@ describe('multisig', () => {
3057
3057
  ],
3058
3058
  "salt": "0x0000000000000000000000000000000000000000000000000000000000000000",
3059
3059
  "threshold": 1,
3060
- "version": "0x0",
3060
+ "version": 0,
3061
3061
  },
3062
3062
  "signatures": [
3063
3063
  {
@@ -245,7 +245,7 @@ export type MultisigRpc = {
245
245
  /** Native multisig account address. */
246
246
  account: Address.Address
247
247
  /** Complete applicable multisig configuration witness. */
248
- config: MultisigConfig.Rpc
248
+ config: MultisigConfig.Config<number>
249
249
  /** Structured owner approvals. */
250
250
  signatures: readonly SignatureEnvelopeRpc[]
251
251
  /** Multisig RPC signatures are untagged. */
@@ -1229,7 +1229,7 @@ export function fromRpc(envelope: SignatureEnvelopeRpc): SignatureEnvelope {
1229
1229
  const multisig = envelope as MultisigRpc
1230
1230
  const result = {
1231
1231
  account: multisig.account,
1232
- config: MultisigConfig.fromRpc(multisig.config),
1232
+ config: MultisigConfig.from(multisig.config),
1233
1233
  signatures: multisig.signatures.map((signature) => fromRpc(signature)),
1234
1234
  type: 'multisig',
1235
1235
  } satisfies Multisig
@@ -1245,7 +1245,7 @@ export declare namespace fromRpc {
1245
1245
  | assert.ErrorType
1246
1246
  | CoercionError
1247
1247
  | InvalidSerializedError
1248
- | MultisigConfig.fromRpc.ErrorType
1248
+ | MultisigConfig.assert.ErrorType
1249
1249
  | Signature.fromRpc.ErrorType
1250
1250
  | Errors.GlobalErrorType
1251
1251
  }
@@ -1614,7 +1614,10 @@ export function toRpc<const envelope extends toRpc.Input>(
1614
1614
  assert(multisig)
1615
1615
  return {
1616
1616
  account: multisig.account,
1617
- config: MultisigConfig.toRpc(multisig.config),
1617
+ config: {
1618
+ ...multisig.config,
1619
+ version: Hex.toNumber(Hex.fromNumber(multisig.config.version)),
1620
+ },
1618
1621
  signatures: multisig.signatures.map((signature) => toRpc(signature)),
1619
1622
  } as never
1620
1623
  }
@@ -1643,7 +1646,8 @@ export declare namespace toRpc {
1643
1646
  type ErrorType =
1644
1647
  | assert.ErrorType
1645
1648
  | CoercionError
1646
- | MultisigConfig.toRpc.ErrorType
1649
+ | Hex.fromNumber.ErrorType
1650
+ | Hex.toNumber.ErrorType
1647
1651
  | Signature.toRpc.ErrorType
1648
1652
  | Errors.GlobalErrorType
1649
1653
  }
@@ -0,0 +1,6 @@
1
+ {
2
+ "type": "module",
3
+ "types": "../../_types/tempo/TransactionRequest.test-d.d.ts",
4
+ "main": "../../_cjs/tempo/TransactionRequest.test-d.js",
5
+ "module": "../../_esm/tempo/TransactionRequest.test-d.js"
6
+ }
@@ -0,0 +1,24 @@
1
+ import { expectTypeOf, test } from 'vitest'
2
+ import type * as MultisigWitness from './MultisigWitness.js'
3
+ import type * as TransactionRequest from './TransactionRequest.js'
4
+
5
+ declare const request: TransactionRequest.TransactionRequest
6
+ declare const rpc: TransactionRequest.Rpc
7
+
8
+ test('transaction requests use domain multisig witnesses', () => {
9
+ expectTypeOf(request.multisigWitness?.config.version).toEqualTypeOf<
10
+ bigint | undefined
11
+ >()
12
+
13
+ const approval = request.multisigWitness?.approvals[0]
14
+ if (approval?.type === 'multisig')
15
+ expectTypeOf(approval.witness.approvals[0]?.keyType).toEqualTypeOf<
16
+ MultisigWitness.NestedPrimitiveApproval['keyType']
17
+ >()
18
+ })
19
+
20
+ test('RPC requests use numeric multisig config versions', () => {
21
+ expectTypeOf(rpc.multisigWitness?.config.version).toEqualTypeOf<
22
+ number | undefined
23
+ >()
24
+ })
@@ -1,6 +1,74 @@
1
- import { TransactionRequest } from 'ox/tempo'
1
+ import { type MultisigWitness, TransactionRequest } from 'ox/tempo'
2
2
  import { describe, expect, test } from 'vitest'
3
3
 
4
+ const multisigWitnessRpc = {
5
+ account: '0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
6
+ approvals: [
7
+ {
8
+ keyType: 'secp256k1',
9
+ owner: '0x1111111111111111111111111111111111111111',
10
+ type: 'primitive',
11
+ },
12
+ {
13
+ type: 'multisig',
14
+ witness: {
15
+ account: '0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb',
16
+ approvals: [
17
+ {
18
+ keyData: '0x0578',
19
+ keyType: 'webAuthn',
20
+ owner: '0x2222222222222222222222222222222222222222',
21
+ },
22
+ ],
23
+ config: {
24
+ owners: [
25
+ {
26
+ owner: '0x2222222222222222222222222222222222222222',
27
+ weight: 1,
28
+ },
29
+ ],
30
+ salt: `0x${'22'.repeat(32)}`,
31
+ threshold: 1,
32
+ version: 1,
33
+ },
34
+ },
35
+ },
36
+ ],
37
+ config: {
38
+ owners: [
39
+ {
40
+ owner: '0x1111111111111111111111111111111111111111',
41
+ weight: 1,
42
+ },
43
+ {
44
+ owner: '0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb',
45
+ weight: 1,
46
+ },
47
+ ],
48
+ salt: `0x${'11'.repeat(32)}`,
49
+ 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
71
+
4
72
  describe('fromRpc', () => {
5
73
  test('default', () => {
6
74
  const request = TransactionRequest.fromRpc({
@@ -69,6 +137,21 @@ describe('fromRpc', () => {
69
137
  expect(request.nonceKey).toBe(255n)
70
138
  })
71
139
 
140
+ test('behavior: multisig witness', () => {
141
+ const request = TransactionRequest.fromRpc({
142
+ from: '0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
143
+ multisigWitness: multisigWitnessRpc,
144
+ type: '0x76',
145
+ })
146
+
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')
153
+ })
154
+
72
155
  test('behavior: empty', () => {
73
156
  const request = TransactionRequest.fromRpc({})
74
157
  expect(request).toMatchInlineSnapshot('{}')
@@ -122,6 +205,20 @@ describe('toRpc', () => {
122
205
  }
123
206
  `)
124
207
  })
208
+
209
+ test('behavior: multisig witness', () => {
210
+ const request = TransactionRequest.toRpc({
211
+ from: '0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
212
+ multisigWitness,
213
+ })
214
+
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')
221
+ })
125
222
  })
126
223
 
127
224
  describe('roundtrip', () => {
@@ -144,6 +241,7 @@ describe('roundtrip', () => {
144
241
  nonceKey: 255n,
145
242
  gas: 100000n,
146
243
  maxFeePerGas: 1000000000n,
244
+ multisigWitness,
147
245
  }
148
246
 
149
247
  const rpc = TransactionRequest.toRpc(original)
@@ -164,6 +262,7 @@ describe('roundtrip', () => {
164
262
  expect(converted.nonceKey).toBe(original.nonceKey)
165
263
  expect(converted.gas).toBe(original.gas)
166
264
  expect(converted.maxFeePerGas).toBe(original.maxFeePerGas)
265
+ expect(converted.multisigWitness).toEqual(original.multisigWitness)
167
266
  expect(converted.type).toBe('tempo')
168
267
  })
169
268
 
@@ -181,6 +280,7 @@ describe('roundtrip', () => {
181
280
  validAfter: '0x32',
182
281
  nonceKey: '0xff',
183
282
  gas: '0x186a0',
283
+ multisigWitness: multisigWitnessRpc,
184
284
  type: '0x76',
185
285
  }
186
286
 
@@ -193,6 +293,7 @@ describe('roundtrip', () => {
193
293
  expect(rpc.validAfter).toBe(original.validAfter)
194
294
  expect(rpc.nonceKey).toBe(original.nonceKey)
195
295
  expect(rpc.gas).toBe(original.gas)
296
+ expect(rpc.multisigWitness).toEqual(original.multisigWitness)
196
297
  expect(rpc.type).toBe('0x76')
197
298
  })
198
299
  })
@@ -4,6 +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
8
  import * as TempoAddress from './TempoAddress.js'
8
9
  import * as TokenId from './TokenId.js'
9
10
  import * as Transaction from './Transaction.js'
@@ -38,6 +39,7 @@ export type TransactionRequest<
38
39
  keyType?: KeyType | undefined
39
40
  feePayer?: boolean | undefined
40
41
  feeToken?: TokenId.TokenIdOrAddress<addressType> | undefined
42
+ multisigWitness?: MultisigWitness.MultisigWitness<bigintType> | undefined
41
43
  nonceKey?: 'random' | bigintType | undefined
42
44
  validBefore?: numberType | undefined
43
45
  validAfter?: numberType | undefined
@@ -47,11 +49,12 @@ export type TransactionRequest<
47
49
  /** RPC representation of a {@link ox#TransactionRequest.TransactionRequest}. */
48
50
  export type Rpc = Omit<
49
51
  TransactionRequest<Hex.Hex, Hex.Hex, string, Hex.Hex>,
50
- 'authorizationList' | 'feeToken' | 'keyAuthorization'
52
+ 'authorizationList' | 'feeToken' | 'keyAuthorization' | 'multisigWitness'
51
53
  > & {
52
54
  authorizationList?: AuthorizationTempo.ListRpc | undefined
53
55
  feeToken?: Hex.Hex | undefined
54
56
  keyAuthorization?: KeyAuthorization.Rpc | undefined
57
+ multisigWitness?: MultisigWitness.Rpc | undefined
55
58
  nonceKey?: Hex.Hex | undefined
56
59
  }
57
60
 
@@ -76,7 +79,7 @@ export type Rpc = Omit<
76
79
  * @returns A transaction request.
77
80
  */
78
81
  export function fromRpc(request: Rpc): TransactionRequest {
79
- const { authorizationList: _, ...rest } = request
82
+ const { authorizationList: _, multisigWitness: __, ...rest } = request
80
83
  const request_ = ox_TransactionRequest.fromRpc(
81
84
  rest as any,
82
85
  ) as TransactionRequest
@@ -107,6 +110,8 @@ export function fromRpc(request: Rpc): TransactionRequest {
107
110
  request_.keyAuthorization = KeyAuthorization.fromRpc(
108
111
  request.keyAuthorization,
109
112
  )
113
+ if (request.multisigWitness)
114
+ request_.multisigWitness = MultisigWitness.fromRpc(request.multisigWitness)
110
115
  if (typeof request.validBefore !== 'undefined')
111
116
  request_.validBefore = Hex.toNumber(request.validBefore as Hex.Hex)
112
117
  if (typeof request.validAfter !== 'undefined')
@@ -120,6 +125,7 @@ export function fromRpc(request: Rpc): TransactionRequest {
120
125
  export declare namespace fromRpc {
121
126
  export type ErrorType =
122
127
  | AuthorizationTempo.fromRpcList.ErrorType
128
+ | MultisigWitness.fromRpc.ErrorType
123
129
  | Hex.toNumber.ErrorType
124
130
  | Hex.toBigInt.ErrorType
125
131
  | Errors.GlobalErrorType
@@ -204,6 +210,8 @@ export function toRpc(request: TransactionRequest): Rpc {
204
210
  request_rpc.keyAuthorization = KeyAuthorization.toRpc(
205
211
  request.keyAuthorization,
206
212
  )
213
+ if (request.multisigWitness)
214
+ request_rpc.multisigWitness = MultisigWitness.toRpc(request.multisigWitness)
207
215
  if (typeof request.validBefore !== 'undefined')
208
216
  request_rpc.validBefore = Hex.fromNumber(request.validBefore)
209
217
  if (typeof request.validAfter !== 'undefined')
@@ -222,6 +230,7 @@ export function toRpc(request: TransactionRequest): Rpc {
222
230
  typeof request.feePayer !== 'undefined' ||
223
231
  typeof request.feeToken !== 'undefined' ||
224
232
  typeof request.keyAuthorization !== 'undefined' ||
233
+ typeof request.multisigWitness !== 'undefined' ||
225
234
  typeof request.nonceKey !== 'undefined' ||
226
235
  typeof request.validBefore !== 'undefined' ||
227
236
  typeof request.validAfter !== 'undefined' ||
@@ -240,6 +249,7 @@ export function toRpc(request: TransactionRequest): Rpc {
240
249
  export declare namespace toRpc {
241
250
  export type ErrorType =
242
251
  | AuthorizationTempo.toRpcList.ErrorType
252
+ | MultisigWitness.toRpc.ErrorType
243
253
  | Hex.fromNumber.ErrorType
244
254
  | Errors.GlobalErrorType
245
255
  }
package/tempo/index.ts CHANGED
@@ -159,6 +159,15 @@ export * as MultisigConfig from './MultisigConfig.js'
159
159
  * @category Reference
160
160
  */
161
161
  export * as MultisigOperation from './MultisigOperation.js'
162
+ /**
163
+ * Native multisig RPC simulation witness utilities.
164
+ *
165
+ * Converts complete root and nested owner witnesses between their domain and
166
+ * Tempo JSON-RPC representations.
167
+ *
168
+ * @category Reference
169
+ */
170
+ export * as MultisigWitness from './MultisigWitness.js'
162
171
  /**
163
172
  * Utilities for constructing period durations (in seconds) for recurring spending limits.
164
173
  *
package/version.ts CHANGED
@@ -1,2 +1,2 @@
1
1
  /** @internal */
2
- export const version = '0.14.39'
2
+ export const version = '0.14.41'