ox 0.14.55 → 0.14.57

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 (97) hide show
  1. package/CHANGELOG.md +48 -0
  2. package/_cjs/tempo/{MultisigConfig.js → AccountConfig.js} +32 -9
  3. package/_cjs/tempo/AccountConfig.js.map +1 -0
  4. package/_cjs/tempo/{MultisigOperation.js → AccountOperation.js} +29 -29
  5. package/_cjs/tempo/AccountOperation.js.map +1 -0
  6. package/_cjs/tempo/{MultisigSimulation.js → AccountSimulation.js} +22 -13
  7. package/_cjs/tempo/AccountSimulation.js.map +1 -0
  8. package/_cjs/tempo/KeyAuthorization.js +10 -18
  9. package/_cjs/tempo/KeyAuthorization.js.map +1 -1
  10. package/_cjs/tempo/SignatureEnvelope.js +64 -64
  11. package/_cjs/tempo/SignatureEnvelope.js.map +1 -1
  12. package/_cjs/tempo/TransactionRequest.js +15 -10
  13. package/_cjs/tempo/TransactionRequest.js.map +1 -1
  14. package/_cjs/tempo/index.js +4 -4
  15. package/_cjs/tempo/index.js.map +1 -1
  16. package/_cjs/version.js +1 -1
  17. package/_esm/tempo/{MultisigConfig.js → AccountConfig.js} +161 -64
  18. package/_esm/tempo/AccountConfig.js.map +1 -0
  19. package/_esm/tempo/{MultisigOperation.js → AccountOperation.js} +64 -64
  20. package/_esm/tempo/AccountOperation.js.map +1 -0
  21. package/_esm/tempo/{MultisigSimulation.js → AccountSimulation.js} +35 -25
  22. package/_esm/tempo/AccountSimulation.js.map +1 -0
  23. package/_esm/tempo/KeyAuthorization.js +16 -19
  24. package/_esm/tempo/KeyAuthorization.js.map +1 -1
  25. package/_esm/tempo/SignatureEnvelope.js +71 -71
  26. package/_esm/tempo/SignatureEnvelope.js.map +1 -1
  27. package/_esm/tempo/TransactionRequest.js +15 -10
  28. package/_esm/tempo/TransactionRequest.js.map +1 -1
  29. package/_esm/tempo/index.js +50 -48
  30. package/_esm/tempo/index.js.map +1 -1
  31. package/_esm/version.js +1 -1
  32. package/_types/tempo/{MultisigConfig.d.ts → AccountConfig.d.ts} +156 -66
  33. package/_types/tempo/AccountConfig.d.ts.map +1 -0
  34. package/_types/tempo/{MultisigOperation.d.ts → AccountOperation.d.ts} +62 -62
  35. package/_types/tempo/AccountOperation.d.ts.map +1 -0
  36. package/_types/tempo/{MultisigSimulation.d.ts → AccountSimulation.d.ts} +25 -21
  37. package/_types/tempo/AccountSimulation.d.ts.map +1 -0
  38. package/_types/tempo/KeyAuthorization.d.ts +28 -23
  39. package/_types/tempo/KeyAuthorization.d.ts.map +1 -1
  40. package/_types/tempo/RpcSchemaTempo.d.ts +13 -13
  41. package/_types/tempo/RpcSchemaTempo.d.ts.map +1 -1
  42. package/_types/tempo/SignatureEnvelope.d.ts +36 -33
  43. package/_types/tempo/SignatureEnvelope.d.ts.map +1 -1
  44. package/_types/tempo/TransactionRequest.d.ts +11 -9
  45. package/_types/tempo/TransactionRequest.d.ts.map +1 -1
  46. package/_types/tempo/index.d.ts +50 -48
  47. package/_types/tempo/index.d.ts.map +1 -1
  48. package/_types/version.d.ts +1 -1
  49. package/package.json +31 -31
  50. package/tempo/AccountConfig/package.json +6 -0
  51. package/tempo/AccountConfig.test-d/package.json +6 -0
  52. package/tempo/AccountConfig.test-d.ts +72 -0
  53. package/tempo/AccountConfig.test.ts +642 -0
  54. package/tempo/{MultisigConfig.ts → AccountConfig.ts} +212 -75
  55. package/tempo/AccountOperation/package.json +6 -0
  56. package/tempo/AccountOperation.test-d/package.json +6 -0
  57. package/tempo/AccountOperation.test-d.ts +71 -0
  58. package/tempo/{MultisigOperation.test.ts → AccountOperation.test.ts} +129 -129
  59. package/tempo/{MultisigOperation.ts → AccountOperation.ts} +95 -97
  60. package/tempo/AccountSimulation/package.json +6 -0
  61. package/tempo/AccountSimulation.test-d/package.json +6 -0
  62. package/tempo/{MultisigSimulation.test-d.ts → AccountSimulation.test-d.ts} +7 -9
  63. package/tempo/{MultisigSimulation.test.ts → AccountSimulation.test.ts} +73 -29
  64. package/tempo/{MultisigSimulation.ts → AccountSimulation.ts} +47 -35
  65. package/tempo/KeyAuthorization.test-d.ts +19 -29
  66. package/tempo/KeyAuthorization.test.ts +151 -74
  67. package/tempo/KeyAuthorization.ts +40 -61
  68. package/tempo/RpcSchemaTempo.test-d.ts +20 -20
  69. package/tempo/RpcSchemaTempo.ts +13 -13
  70. package/tempo/SignatureEnvelope.test-d.ts +7 -7
  71. package/tempo/SignatureEnvelope.test.ts +34 -34
  72. package/tempo/SignatureEnvelope.ts +107 -103
  73. package/tempo/Transaction.test.ts +4 -4
  74. package/tempo/TransactionRequest.test-d.ts +17 -8
  75. package/tempo/TransactionRequest.test.ts +31 -21
  76. package/tempo/TransactionRequest.ts +29 -20
  77. package/tempo/{multisig.e2e.test.ts → configurableAccounts.e2e.test.ts} +16 -16
  78. package/tempo/index.ts +50 -48
  79. package/version.ts +1 -1
  80. package/_cjs/tempo/MultisigConfig.js.map +0 -1
  81. package/_cjs/tempo/MultisigOperation.js.map +0 -1
  82. package/_cjs/tempo/MultisigSimulation.js.map +0 -1
  83. package/_esm/tempo/MultisigConfig.js.map +0 -1
  84. package/_esm/tempo/MultisigOperation.js.map +0 -1
  85. package/_esm/tempo/MultisigSimulation.js.map +0 -1
  86. package/_types/tempo/MultisigConfig.d.ts.map +0 -1
  87. package/_types/tempo/MultisigOperation.d.ts.map +0 -1
  88. package/_types/tempo/MultisigSimulation.d.ts.map +0 -1
  89. package/tempo/MultisigConfig/package.json +0 -6
  90. package/tempo/MultisigConfig.test-d/package.json +0 -6
  91. package/tempo/MultisigConfig.test-d.ts +0 -52
  92. package/tempo/MultisigConfig.test.ts +0 -391
  93. package/tempo/MultisigOperation/package.json +0 -6
  94. package/tempo/MultisigOperation.test-d/package.json +0 -6
  95. package/tempo/MultisigOperation.test-d.ts +0 -71
  96. package/tempo/MultisigSimulation/package.json +0 -6
  97. package/tempo/MultisigSimulation.test-d/package.json +0 -6
@@ -1,4 +1,4 @@
1
- import { MultisigConfig, MultisigSimulation } from 'ox/tempo'
1
+ import { AccountConfig, AccountSimulation } from 'ox/tempo'
2
2
  import { describe, expect, test } from 'vitest'
3
3
 
4
4
  const config =
@@ -12,11 +12,11 @@ const rpc = {
12
12
  },
13
13
  ],
14
14
  config,
15
- } as const satisfies MultisigSimulation.Rpc
15
+ } as const satisfies AccountSimulation.Rpc
16
16
 
17
17
  describe('fromRpc', () => {
18
18
  test('behavior: decodes the configuration', () => {
19
- expect(MultisigSimulation.fromRpc(rpc)).toMatchInlineSnapshot(`
19
+ expect(AccountSimulation.fromRpc(rpc)).toMatchInlineSnapshot(`
20
20
  {
21
21
  "approvals": [
22
22
  {
@@ -49,43 +49,43 @@ describe('fromRpc', () => {
49
49
  '0xf843a0000000000000000000000000000000000000000000000000000000000000000088ffffffffffffffff01d7d694111111111111111111111111111111111111111101' as const
50
50
 
51
51
  expect(
52
- MultisigSimulation.fromRpc({ ...rpc, approvals: [], config }).config
52
+ AccountSimulation.fromRpc({ ...rpc, approvals: [], config }).config
53
53
  .version,
54
54
  ).toMatchInlineSnapshot(`18446744073709551615n`)
55
55
  })
56
56
 
57
57
  test('error: rejects excess root approvals', () => {
58
58
  expect(() =>
59
- MultisigSimulation.fromRpc({
59
+ AccountSimulation.fromRpc({
60
60
  ...rpc,
61
61
  approvals: Array.from({ length: 9 }, () => rpc.approvals[0]),
62
62
  }),
63
63
  ).toThrowErrorMatchingInlineSnapshot(
64
- `[MultisigSimulation.InvalidSimulationError: Invalid multisig simulation: approval count exceeds 8.]`,
64
+ `[AccountSimulation.InvalidSimulationError: Invalid account simulation: approval count exceeds 8.]`,
65
65
  )
66
66
  })
67
67
  test('error: rejects nested approvals', () => {
68
68
  expect(() =>
69
- MultisigSimulation.fromRpc({
69
+ AccountSimulation.fromRpc({
70
70
  ...rpc,
71
- approvals: [{ type: 'multisig', spec: rpc }],
71
+ approvals: [{ type: 'configurable', spec: rpc }],
72
72
  } as never),
73
73
  ).toThrowErrorMatchingInlineSnapshot(
74
- `[MultisigSimulation.InvalidSimulationError: Invalid multisig simulation: only untagged primitive owner approvals are allowed.]`,
74
+ `[AccountSimulation.InvalidSimulationError: Invalid account simulation: only untagged primitive owner approvals are allowed.]`,
75
75
  )
76
76
  })
77
77
 
78
78
  test('error: rejects trailing configuration bytes', () => {
79
79
  expect(() =>
80
- MultisigSimulation.fromRpc({ ...rpc, config: `${config}00` }),
80
+ AccountSimulation.fromRpc({ ...rpc, config: `${config}00` }),
81
81
  ).toThrowErrorMatchingInlineSnapshot(
82
- `[MultisigSimulation.InvalidSimulationError: Invalid multisig simulation: noncanonical config encoding.]`,
82
+ `[AccountSimulation.InvalidSimulationError: Invalid account simulation: noncanonical config encoding.]`,
83
83
  )
84
84
  })
85
85
 
86
86
  test('error: rejects malformed configuration RLP', () => {
87
87
  expect(() =>
88
- MultisigSimulation.fromRpc({ ...rpc, config: '0xf8' }),
88
+ AccountSimulation.fromRpc({ ...rpc, config: '0xf8' }),
89
89
  ).toThrowErrorMatchingInlineSnapshot(
90
90
  `[Cursor.PositionOutOfBoundsError: Position \`1\` is out of bounds (\`0 < position < 1\`).]`,
91
91
  )
@@ -93,9 +93,9 @@ describe('fromRpc', () => {
93
93
 
94
94
  test('error: rejects a non-list configuration', () => {
95
95
  expect(() =>
96
- MultisigSimulation.fromRpc({ ...rpc, config: '0x01' }),
96
+ AccountSimulation.fromRpc({ ...rpc, config: '0x01' }),
97
97
  ).toThrowErrorMatchingInlineSnapshot(
98
- `[MultisigSimulation.InvalidSimulationError: Invalid multisig simulation: invalid config encoding.]`,
98
+ `[AccountSimulation.InvalidSimulationError: Invalid account simulation: invalid config encoding.]`,
99
99
  )
100
100
  })
101
101
 
@@ -105,17 +105,37 @@ describe('fromRpc', () => {
105
105
  .replace('118002', '11810002') as `0x${string}`
106
106
 
107
107
  expect(() =>
108
- MultisigSimulation.fromRpc({ ...rpc, config: noncanonical }),
108
+ AccountSimulation.fromRpc({ ...rpc, config: noncanonical }),
109
109
  ).toThrowErrorMatchingInlineSnapshot(
110
- `[MultisigSimulation.InvalidSimulationError: Invalid multisig simulation: invalid config encoding.]`,
110
+ `[AccountSimulation.InvalidSimulationError: Invalid account simulation: invalid config encoding.]`,
111
111
  )
112
112
  })
113
113
  })
114
114
 
115
115
  describe('toRpc', () => {
116
+ test('behavior: round-trips the grant signer', () => {
117
+ const signer = '0x2222222222222222222222222222222222222222'
118
+ const spec = AccountSimulation.fromRpc({ ...rpc, signer })
119
+ expect(spec.signer).toBe(signer)
120
+ expect(AccountSimulation.toRpc(spec).signer).toBe(signer)
121
+ expect(
122
+ 'signer' in AccountSimulation.toRpc(AccountSimulation.fromRpc(rpc)),
123
+ ).toBe(false)
124
+ })
125
+
126
+ test('error: rejects an invalid grant signer', () => {
127
+ expect(() =>
128
+ AccountSimulation.fromRpc({ ...rpc, signer: '0x1234' }),
129
+ ).toThrowErrorMatchingInlineSnapshot(`
130
+ [Address.InvalidAddressError: Address "0x1234" is invalid.
131
+
132
+ Details: Address is not a 20 byte (40 hexadecimal character) value.]
133
+ `)
134
+ })
135
+
116
136
  test('behavior: encodes configurations and shims long key data', () => {
117
137
  expect(
118
- MultisigSimulation.toRpc(MultisigSimulation.fromRpc(rpc)),
138
+ AccountSimulation.toRpc(AccountSimulation.fromRpc(rpc)),
119
139
  ).toMatchInlineSnapshot(`
120
140
  {
121
141
  "approvals": [
@@ -131,12 +151,12 @@ describe('toRpc', () => {
131
151
  })
132
152
 
133
153
  test('behavior: preserves short key data', () => {
134
- const spec = MultisigSimulation.fromRpc({
154
+ const spec = AccountSimulation.fromRpc({
135
155
  ...rpc,
136
156
  approvals: [{ ...rpc.approvals[0], keyData: '0x0102' }],
137
157
  })
138
158
 
139
- expect(MultisigSimulation.toRpc(spec).approvals).toMatchInlineSnapshot(`
159
+ expect(AccountSimulation.toRpc(spec).approvals).toMatchInlineSnapshot(`
140
160
  [
141
161
  {
142
162
  "keyData": "0x0102",
@@ -147,14 +167,38 @@ describe('toRpc', () => {
147
167
  `)
148
168
  })
149
169
 
170
+ test('behavior: shims key data that is not a valid length hint', () => {
171
+ const keyData = (keyData: `0x${string}`) =>
172
+ AccountSimulation.toRpc(
173
+ AccountSimulation.fromRpc({
174
+ ...rpc,
175
+ approvals: [{ ...rpc.approvals[0], keyData }],
176
+ }),
177
+ ).approvals[0]?.keyData
178
+
179
+ expect({
180
+ empty: keyData('0x'),
181
+ four: keyData('0x01020304'),
182
+ one: keyData('0x01'),
183
+ three: keyData('0x010203'),
184
+ }).toMatchInlineSnapshot(`
185
+ {
186
+ "empty": "0x0000",
187
+ "four": "0x01020304",
188
+ "one": "0x01",
189
+ "three": "0x0003",
190
+ }
191
+ `)
192
+ })
193
+
150
194
  test('behavior: encodes the maximum uint64 configuration version', () => {
151
- const spec = MultisigSimulation.fromRpc(rpc)
195
+ const spec = AccountSimulation.fromRpc(rpc)
152
196
 
153
197
  expect(
154
- MultisigSimulation.toRpc({
198
+ AccountSimulation.toRpc({
155
199
  ...spec,
156
200
  approvals: [],
157
- config: MultisigConfig.from({
201
+ config: AccountConfig.from({
158
202
  owners: [
159
203
  {
160
204
  owner: '0x1111111111111111111111111111111111111111',
@@ -162,7 +206,7 @@ describe('toRpc', () => {
162
206
  },
163
207
  ],
164
208
  threshold: 1,
165
- version: MultisigConfig.maxVersion,
209
+ version: AccountConfig.maxVersion,
166
210
  }),
167
211
  }).config,
168
212
  ).toMatchInlineSnapshot(
@@ -171,25 +215,25 @@ describe('toRpc', () => {
171
215
  })
172
216
 
173
217
  test('error: rejects excess root approvals', () => {
174
- const spec = MultisigSimulation.fromRpc(rpc)
218
+ const spec = AccountSimulation.fromRpc(rpc)
175
219
 
176
220
  expect(() =>
177
- MultisigSimulation.toRpc({
221
+ AccountSimulation.toRpc({
178
222
  ...spec,
179
223
  approvals: Array.from({ length: 9 }, () => spec.approvals[0]!),
180
224
  }),
181
225
  ).toThrowErrorMatchingInlineSnapshot(
182
- `[MultisigSimulation.InvalidSimulationError: Invalid multisig simulation: approval count exceeds 8.]`,
226
+ `[AccountSimulation.InvalidSimulationError: Invalid account simulation: approval count exceeds 8.]`,
183
227
  )
184
228
  })
185
229
  test('error: rejects nested approvals', () => {
186
230
  expect(() =>
187
- MultisigSimulation.toRpc({
231
+ AccountSimulation.toRpc({
188
232
  ...rpc,
189
- approvals: [{ type: 'multisig', spec: rpc }],
233
+ approvals: [{ type: 'configurable', spec: rpc }],
190
234
  } as never),
191
235
  ).toThrowErrorMatchingInlineSnapshot(
192
- `[MultisigSimulation.InvalidSimulationError: Invalid multisig simulation: only untagged primitive owner approvals are allowed.]`,
236
+ `[AccountSimulation.InvalidSimulationError: Invalid account simulation: only untagged primitive owner approvals are allowed.]`,
193
237
  )
194
238
  })
195
239
  })
@@ -3,13 +3,13 @@ import * as Errors from '../core/Errors.js'
3
3
  import * as Hex from '../core/Hex.js'
4
4
  import type { Compute } from '../core/internal/types.js'
5
5
  import * as Rlp from '../core/Rlp.js'
6
- import * as MultisigConfig from './MultisigConfig.js'
6
+ import * as AccountConfig from './AccountConfig.js'
7
7
  import type * as SignatureEnvelope from './SignatureEnvelope.js'
8
8
 
9
- /** Native multisig owner approval used for RPC simulation. */
9
+ /** Configurable account owner approval used for RPC simulation. */
10
10
  export type Approval = PrimitiveApproval
11
11
 
12
- /** JSON-RPC native multisig owner approval used for RPC simulation. */
12
+ /** JSON-RPC configurable account owner approval used for RPC simulation. */
13
13
  export type ApprovalRpc = PrimitiveApproval
14
14
 
15
15
  /** Primitive owner approval used for RPC simulation. */
@@ -22,70 +22,81 @@ export type PrimitiveApproval = {
22
22
  owner: Address.Address
23
23
  }
24
24
 
25
- /** JSON-RPC representation of a native multisig simulation spec. */
25
+ /** JSON-RPC representation of an account simulation spec. */
26
26
  export type Rpc = Compute<{
27
27
  /** Owner approvals to model. */
28
28
  approvals: readonly ApprovalRpc[]
29
29
  /** Canonical RLP-encoded applicable configuration. */
30
30
  config: Hex.Hex
31
+ /** Account that signs the modeled key authorization. Omitted for a direct signature. */
32
+ signer?: Address.Address | undefined
31
33
  }>
32
34
 
33
- /** Native multisig spec used to construct an RPC simulation signature. */
35
+ /** Account simulation spec used to construct an RPC simulation signature. */
34
36
  export type Spec = Compute<{
35
37
  /** Owner approvals to model. */
36
38
  approvals: readonly Approval[]
37
39
  /** Complete applicable configuration. */
38
- config: MultisigConfig.Config
40
+ config: AccountConfig.Config
41
+ /** Account that signs the modeled key authorization. Omitted for a direct signature. */
42
+ signer?: Address.Address | undefined
39
43
  }>
40
44
 
41
45
  /**
42
- * Converts a JSON-RPC multisig simulation spec to its domain representation.
46
+ * Converts a JSON-RPC account simulation spec to its domain representation.
43
47
  *
44
48
  * @example
45
49
  * ```ts twoslash
46
50
  * // @noErrors
47
- * import { MultisigSimulation } from 'ox/tempo'
51
+ * import { AccountSimulation } from 'ox/tempo'
48
52
  *
49
- * const spec = MultisigSimulation.fromRpc(specRpc)
53
+ * const spec = AccountSimulation.fromRpc(specRpc)
50
54
  * ```
51
55
  *
52
- * @param spec - JSON-RPC multisig simulation spec.
53
- * @returns The multisig simulation spec with decoded configurations.
56
+ * @param spec - JSON-RPC account simulation spec.
57
+ * @returns The account simulation spec with decoded configurations.
54
58
  */
55
59
  export function fromRpc(spec: Rpc): Spec {
56
- const { approvals, config } = spec
60
+ const { approvals, config, signer } = spec
57
61
  assertApprovals(approvals)
58
- return { approvals, config: deserializeConfig(config) }
62
+ if (signer !== undefined) Address.assert(signer)
63
+ return {
64
+ approvals,
65
+ config: deserializeConfig(config),
66
+ ...(signer !== undefined ? { signer } : {}),
67
+ }
59
68
  }
60
69
 
61
70
  export declare namespace fromRpc {
62
71
  /** Error type for `fromRpc`. */
63
72
  export type ErrorType =
73
+ | Address.assert.ErrorType
64
74
  | Hex.isEqual.ErrorType
65
75
  | InvalidSimulationError
66
- | MultisigConfig.assert.ErrorType
76
+ | AccountConfig.assert.ErrorType
67
77
  | Rlp.fromHex.ErrorType
68
78
  | Rlp.toHex.ErrorType
69
79
  | Errors.GlobalErrorType
70
80
  }
71
81
 
72
82
  /**
73
- * Converts a multisig simulation spec to its JSON-RPC representation.
83
+ * Converts an account simulation spec to its JSON-RPC representation.
74
84
  *
75
85
  * @example
76
86
  * ```ts twoslash
77
87
  * // @noErrors
78
- * import { MultisigSimulation } from 'ox/tempo'
88
+ * import { AccountSimulation } from 'ox/tempo'
79
89
  *
80
- * const specRpc = MultisigSimulation.toRpc(spec)
90
+ * const specRpc = AccountSimulation.toRpc(spec)
81
91
  * ```
82
92
  *
83
- * @param spec - Multisig simulation spec.
84
- * @returns The JSON-RPC multisig simulation spec with encoded configurations.
93
+ * @param spec - Account simulation spec.
94
+ * @returns The JSON-RPC account simulation spec with encoded configurations.
85
95
  */
86
96
  export function toRpc(spec: Spec): Rpc {
87
- const { approvals, config } = spec
97
+ const { approvals, config, signer } = spec
88
98
  assertApprovals(approvals)
99
+ if (signer !== undefined) Address.assert(signer)
89
100
  return {
90
101
  approvals: approvals.map(({ keyData, keyType, owner }) => ({
91
102
  ...(keyData !== undefined ? { keyData: shimKeyData(keyData) } : {}),
@@ -93,15 +104,17 @@ export function toRpc(spec: Spec): Rpc {
93
104
  owner,
94
105
  })),
95
106
  config: serializeConfig(config),
107
+ ...(signer !== undefined ? { signer } : {}),
96
108
  }
97
109
  }
98
110
 
99
111
  export declare namespace toRpc {
100
112
  /** Error type for `toRpc`. */
101
113
  export type ErrorType =
114
+ | Address.assert.ErrorType
102
115
  | Hex.fromNumber.ErrorType
103
116
  | InvalidSimulationError
104
- | MultisigConfig.assert.ErrorType
117
+ | AccountConfig.assert.ErrorType
105
118
  | Rlp.fromHex.ErrorType
106
119
  | Errors.GlobalErrorType
107
120
  }
@@ -120,14 +133,14 @@ function assertApprovals(approvals: readonly unknown[]) {
120
133
  throw new InvalidSimulationError({
121
134
  reason: 'only untagged primitive owner approvals are allowed',
122
135
  })
123
- if (approvals.length > MultisigConfig.maxSignatures)
136
+ if (approvals.length > AccountConfig.maxSignatures)
124
137
  throw new InvalidSimulationError({
125
- reason: `approval count exceeds ${MultisigConfig.maxSignatures}`,
138
+ reason: `approval count exceeds ${AccountConfig.maxSignatures}`,
126
139
  })
127
140
  }
128
141
 
129
142
  /** @internal */
130
- function deserializeConfig(config: Hex.Hex): MultisigConfig.Config {
143
+ function deserializeConfig(config: Hex.Hex): AccountConfig.Config {
131
144
  const tuple = Rlp.toHex(config)
132
145
  if (!Array.isArray(tuple) || tuple.length !== 4)
133
146
  throw new InvalidSimulationError({ reason: 'invalid config encoding' })
@@ -151,35 +164,34 @@ function deserializeConfig(config: Hex.Hex): MultisigConfig.Config {
151
164
  )
152
165
  )
153
166
  throw new InvalidSimulationError({ reason: 'invalid config encoding' })
154
- const value = MultisigConfig.fromTuple(
155
- tuple as unknown as MultisigConfig.Tuple,
156
- )
157
- MultisigConfig.assert(value)
167
+ const value = AccountConfig.fromTuple(tuple as unknown as AccountConfig.Tuple)
168
+ AccountConfig.assert(value)
158
169
  if (!Hex.isEqual(config, serializeConfig(value)))
159
170
  throw new InvalidSimulationError({ reason: 'noncanonical config encoding' })
160
171
  return value
161
172
  }
162
173
 
163
174
  /** @internal */
164
- function serializeConfig(config: MultisigConfig.Input): Hex.Hex {
165
- return Rlp.fromHex(MultisigConfig.toTuple(config))
175
+ function serializeConfig(config: AccountConfig.Input): Hex.Hex {
176
+ return Rlp.fromHex(AccountConfig.toTuple(config))
166
177
  }
167
178
 
168
179
  /**
169
- * Shims long key data into the length hint accepted by Tempo's gas estimator.
180
+ * Shims key data into the 1-, 2-, or 4-byte length hint accepted by Tempo's
181
+ * gas estimator. Other sizes are replaced by a 2-byte hint of their length.
170
182
  * @internal
171
183
  */
172
184
  function shimKeyData(data: Hex.Hex): Hex.Hex {
173
185
  const size = Hex.size(data)
174
- if (size <= 4) return data
186
+ if (size === 1 || size === 2 || size === 4) return data
175
187
  return Hex.fromNumber(size, { size: 2 })
176
188
  }
177
189
 
178
- /** Thrown when a native multisig simulation spec is invalid. */
190
+ /** Thrown when an account simulation spec is invalid. */
179
191
  export class InvalidSimulationError extends Errors.BaseError {
180
- override readonly name = 'MultisigSimulation.InvalidSimulationError'
192
+ override readonly name = 'AccountSimulation.InvalidSimulationError'
181
193
  constructor(options: InvalidSimulationError.Options) {
182
- super(`Invalid multisig simulation: ${options.reason}.`)
194
+ super(`Invalid account simulation: ${options.reason}.`)
183
195
  }
184
196
  }
185
197
 
@@ -18,7 +18,7 @@ const signature = {
18
18
  type: 'secp256k1',
19
19
  } as const satisfies SignatureEnvelope.Secp256k1
20
20
 
21
- const multisig = {
21
+ const configurable = {
22
22
  account: '0x2222222222222222222222222222222222222222',
23
23
  config: {
24
24
  salt: `0x${'00'.repeat(32)}`,
@@ -29,8 +29,8 @@ const multisig = {
29
29
  ],
30
30
  },
31
31
  signatures: [signature],
32
- type: 'multisig',
33
- } as const satisfies SignatureEnvelope.Multisig
32
+ type: 'configurable',
33
+ } as const satisfies SignatureEnvelope.Configurable
34
34
 
35
35
  test('accepts primitive signatures', () => {
36
36
  const signed = KeyAuthorization.from(authorization, { signature })
@@ -40,10 +40,10 @@ test('accepts primitive signatures', () => {
40
40
  >()
41
41
  })
42
42
 
43
- test('accepts multisig signatures and account-bound grants', () => {
43
+ test('accepts configurable signatures and account-bound grants', () => {
44
44
  const signed = KeyAuthorization.from(
45
- { ...authorization, account: multisig.account, type: 'multisig' },
46
- { signature: multisig },
45
+ { ...authorization, account: configurable.account, type: 'configurable' },
46
+ { signature: configurable },
47
47
  )
48
48
  expectTypeOf(signed).toMatchTypeOf<KeyAuthorization.Signed>()
49
49
  expectTypeOf(
@@ -51,37 +51,27 @@ test('accepts multisig signatures and account-bound grants', () => {
51
51
  ).toMatchTypeOf<KeyAuthorization.Rpc>()
52
52
  })
53
53
 
54
- test('requires an account for multisig grants', () => {
55
- type Multisig = Extract<KeyAuthorization.Input, { type: 'multisig' }>
56
- expectTypeOf<Multisig['account']>().toEqualTypeOf<TempoAddress.Address>()
57
- expectTypeOf<
58
- Extract<KeyAuthorization.Signed, { type: 'multisig' }>['account']
59
- >().toEqualTypeOf<`0x${string}`>()
54
+ test('allows configurable grants without an account', () => {
55
+ type Configurable = Extract<KeyAuthorization.Input, { type: 'configurable' }>
56
+ expectTypeOf<Configurable['account']>().toEqualTypeOf<
57
+ TempoAddress.Address | undefined
58
+ >()
60
59
  expectTypeOf<
61
- Omit<Extract<KeyAuthorization.Rpc, { keyType: 'multisig' }>, 'account'>
62
- >().not.toExtend<KeyAuthorization.Rpc>()
63
- expectTypeOf<{
64
- address: `0x${string}`
65
- chainId: bigint
66
- type: 'multisig'
67
- }>().not.toExtend<KeyAuthorization.Input>()
60
+ Extract<KeyAuthorization.Signed, { type: 'configurable' }>['account']
61
+ >().toEqualTypeOf<`0x${string}` | undefined>()
68
62
  expectTypeOf<{
69
- account: undefined
70
63
  address: `0x${string}`
71
64
  chainId: bigint
72
- type: 'multisig'
73
- }>().not.toExtend<KeyAuthorization.Input>()
65
+ type: 'configurable'
66
+ }>().toExtend<KeyAuthorization.Input>()
74
67
  expectTypeOf<{
75
68
  account: null
76
69
  chainId: '0x1'
77
70
  expiry: null
78
71
  keyId: `0x${string}`
79
- keyType: 'multisig'
72
+ keyType: 'configurableAccount'
80
73
  signature: KeyAuthorization.SignatureRpc
81
- }>().not.toExtend<KeyAuthorization.Rpc>()
82
- expectTypeOf<
83
- Extract<KeyAuthorization.Rpc, { keyType: 'multisig' }>['account']
84
- >().toEqualTypeOf<`0x${string}`>()
74
+ }>().toExtend<KeyAuthorization.Rpc>()
85
75
  })
86
76
 
87
77
  test('rejects keychain signatures', () => {
@@ -118,13 +108,13 @@ test('rejects keychain signatures', () => {
118
108
  expectTypeOf(rpc).toMatchTypeOf<KeyAuthorization.Rpc>()
119
109
  })
120
110
 
121
- test('resolves Tempo address bindings for multisig grants', () => {
111
+ test('resolves Tempo address bindings for configurable grants', () => {
122
112
  const signed = KeyAuthorization.from(
123
113
  {
124
114
  account: TempoAddress.format(authorization.address),
125
115
  address: TempoAddress.format(authorization.address),
126
116
  chainId: 1n,
127
- type: 'multisig',
117
+ type: 'configurable',
128
118
  },
129
119
  { signature },
130
120
  )