ox 0.14.29 → 0.14.30

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.
@@ -6,7 +6,13 @@ import * as Hex from '../core/Hex.js'
6
6
  import type { Compute, OneOf } from '../core/internal/types.js'
7
7
 
8
8
  /** Maximum number of owners allowed in a native multisig config. */
9
- export const maxOwners = 10
9
+ export const maxOwners = 255
10
+
11
+ /**
12
+ * Maximum number of native multisig signatures in one nested authorization
13
+ * path, including the top-level transaction signature.
14
+ */
15
+ export const maxNestingDepth = 3
10
16
 
11
17
  /** Maximum encoded byte length for one primitive owner approval. */
12
18
  export const maxOwnerSignatureBytes = 2049
@@ -20,20 +26,17 @@ export const zeroSalt = `0x${'00'.repeat(32)}` as const
20
26
  /** Domain prefix for the native multisig account address derivation. */
21
27
  const accountDomain = 'tempo:multisig:account'
22
28
 
23
- /** Domain prefix for the native multisig config ID derivation. */
24
- const configDomain = 'tempo:multisig:config'
25
-
26
29
  /** Domain prefix for native multisig owner approvals. */
27
30
  const signatureDomain = 'tempo:multisig:signature'
28
31
 
29
32
  /**
30
- * Native multisig configuration. Determines the permanent config ID and the
31
- * stable multisig account address.
33
+ * Native multisig configuration. Determines the stable multisig account
34
+ * address.
32
35
  */
33
36
  export type Config<numberType = number> = Compute<{
34
37
  /**
35
- * Caller-chosen 32-byte salt mixed into the permanent config ID. Defaults to
36
- * the zero salt (`MultisigConfig.zeroSalt`) when omitted.
38
+ * Caller-chosen 32-byte salt mixed into the derived account address.
39
+ * Defaults to the zero salt (`MultisigConfig.zeroSalt`) when omitted.
37
40
  */
38
41
  salt?: Hex.Hex | undefined
39
42
  /** Minimum total owner weight required to authorize a transaction. */
@@ -44,7 +47,7 @@ export type Config<numberType = number> = Compute<{
44
47
 
45
48
  /** Native multisig owner entry. */
46
49
  export type Owner<numberType = number> = {
47
- /** Owner address (recovered from the owner's primitive signature). */
50
+ /** Owner address (recovered from the owner's approval). */
48
51
  owner: Address.Address
49
52
  /** Nonzero owner weight. */
50
53
  weight: numberType
@@ -60,9 +63,9 @@ export type Tuple = readonly [
60
63
  /**
61
64
  * Asserts that a native multisig {@link ox#MultisigConfig.Config} is valid.
62
65
  *
63
- * Mirrors the Tempo `validate_multisig_config` rules: owners non-empty and
66
+ * Mirrors the Tempo `InitMultisig::validate` rules: owners non-empty and
64
67
  * `<= maxOwners`, strictly ascending unique nonzero owner addresses, nonzero
65
- * owner weights, `threshold >= 1`, total weight `<= u32::MAX`, and
68
+ * owner weights, `threshold >= 1`, total weight `<= 255` (u8 max), and
66
69
  * `threshold <= total weight`.
67
70
  *
68
71
  * @example
@@ -109,9 +112,9 @@ export function assert<numberType = number>(config: Config<numberType>): void {
109
112
  totalWeight += Number(owner.weight)
110
113
  }
111
114
 
112
- if (totalWeight > 0xffffffff)
115
+ if (totalWeight > 0xff)
113
116
  throw new InvalidConfigError({
114
- reason: 'total owner weight exceeds u32 max',
117
+ reason: 'total owner weight exceeds u8 max',
115
118
  })
116
119
  if (Number(threshold) > totalWeight)
117
120
  throw new InvalidConfigError({
@@ -127,7 +130,7 @@ export declare namespace assert {
127
130
  * Normalizes a native multisig {@link ox#MultisigConfig.Config}.
128
131
  *
129
132
  * Sorts owners into strictly ascending `owner` address order (the canonical
130
- * form required for config ID derivation) and asserts the config is valid.
133
+ * form required for account derivation) and asserts the config is valid.
131
134
  *
132
135
  * @example
133
136
  * ```ts twoslash
@@ -197,7 +200,11 @@ export function fromTuple(tuple: Tuple): Config {
197
200
  /**
198
201
  * Derives the stable native multisig account address.
199
202
  *
200
- * `keccak256("tempo:multisig:account" || config_id)[12:32]`.
203
+ * Preimage (fixed-width big-endian, **not** RLP):
204
+ * `keccak256("tempo:multisig:account" || salt || u8(threshold) || u8(owners.length) || (owner || u8(weight)) for each owner)[12:32]`.
205
+ *
206
+ * The address is derived once from the initial (bootstrap) config and never
207
+ * changes — config updates do not affect it.
201
208
  *
202
209
  * @example
203
210
  * ```ts twoslash
@@ -213,49 +220,37 @@ export function fromTuple(tuple: Tuple): Config {
213
220
  * const address = MultisigConfig.getAddress(genesisConfig)
214
221
  * ```
215
222
  *
216
- * @example
217
- * ### From an genesis config ID
218
- *
219
- * If you already have the permanent `genesisConfigId`, pass it directly:
220
- *
221
- * ```ts twoslash
222
- * import { MultisigConfig } from 'ox/tempo'
223
- *
224
- * const genesisConfigId =
225
- * `0x${'00'.repeat(32)}` as const
226
- *
227
- * const address = MultisigConfig.getAddress({ genesisConfigId })
228
- * ```
229
- *
230
- * @param value - The genesis config (positional) or `{ genesisConfigId }`.
223
+ * @param config - The initial (bootstrap) multisig config.
231
224
  * @returns The multisig account address.
232
225
  */
233
- export function getAddress(value: getAddress.Value): Address.Address {
234
- const id =
235
- typeof value === 'object' && 'genesisConfigId' in value
236
- ? value.genesisConfigId
237
- : toId(value)
238
- const hash = Hash.keccak256(Hex.concat(Hex.fromString(accountDomain), id))
239
- return Address.from(Hex.slice(hash, 12, 32))
226
+ export function getAddress(config: Config): Address.Address {
227
+ assert(config)
228
+ const hash = Hash.keccak256(
229
+ Hex.concat(
230
+ Hex.fromString(accountDomain),
231
+ Hex.padLeft(config.salt ?? zeroSalt, 32),
232
+ Hex.fromNumber(config.threshold, { size: 1 }),
233
+ Hex.fromNumber(config.owners.length, { size: 1 }),
234
+ ...config.owners.flatMap((owner) => [
235
+ owner.owner,
236
+ Hex.fromNumber(owner.weight, { size: 1 }),
237
+ ]),
238
+ ),
239
+ )
240
+ const account = Address.from(Hex.slice(hash, 12, 32))
241
+ if (Hex.toBigInt(account) === 0n)
242
+ throw new InvalidConfigError({ reason: 'derived account cannot be zero' })
243
+ return account
240
244
  }
241
245
 
242
246
  export declare namespace getAddress {
243
- type Value =
244
- | Config
245
- | {
246
- /**
247
- * The permanent genesis config ID (`MultisigConfig.toId(genesisConfig)`).
248
- * Config updates never change this value, so it identifies the
249
- * account permanently.
250
- */
251
- genesisConfigId: Hex.Hex
252
- }
253
-
254
247
  type ErrorType =
255
- | toId.ErrorType
248
+ | assert.ErrorType
256
249
  | Address.from.ErrorType
257
250
  | Hash.keccak256.ErrorType
258
251
  | Hex.concat.ErrorType
252
+ | Hex.fromNumber.ErrorType
253
+ | Hex.fromString.ErrorType
259
254
  | Hex.slice.ErrorType
260
255
  | Errors.GlobalErrorType
261
256
  }
@@ -263,14 +258,16 @@ export declare namespace getAddress {
263
258
  /**
264
259
  * Computes the digest a native multisig owner approves (signs).
265
260
  *
266
- * `keccak256("tempo:multisig:signature" || inner_digest || account || config_id)`,
261
+ * `keccak256("tempo:multisig:signature" || inner_digest || account)`,
267
262
  * where `inner_digest` is the transaction sign payload
268
263
  * ({@link ox#TxEnvelopeTempo.(getSignPayload:function)}).
269
264
  *
270
- * The digest is always keyed on the permanent `account`/`genesisConfigId`
271
- * derived from the genesis (bootstrap) config — config updates never change
272
- * these values, so the genesis config is the correct input even for
273
- * post-update transactions.
265
+ * The digest is keyed on the permanent `account` derived from the genesis
266
+ * (bootstrap) config — config updates never change it, so the genesis config
267
+ * is the correct input even for post-update transactions.
268
+ *
269
+ * For a nested multisig owner approval, the parent digest becomes the nested
270
+ * approval's `payload`, with the nested multisig `account`.
274
271
  *
275
272
  * @example
276
273
  * ```ts twoslash
@@ -295,10 +292,10 @@ export declare namespace getAddress {
295
292
  * ```
296
293
  *
297
294
  * @example
298
- * ### From `account` + `genesisConfigId`
295
+ * ### From `account`
299
296
  *
300
- * If you already have the permanent `account` and `genesisConfigId` (for
301
- * example, recovered from a stored envelope), pass them directly:
297
+ * If you already have the permanent `account` (for example, recovered from a
298
+ * stored envelope), pass it directly:
302
299
  *
303
300
  * ```ts twoslash
304
301
  * import { MultisigConfig, TxEnvelopeTempo } from 'ox/tempo'
@@ -309,15 +306,13 @@ export declare namespace getAddress {
309
306
  * { owner: '0x1111111111111111111111111111111111111111', weight: 1 },
310
307
  * ],
311
308
  * })
312
- * const genesisConfigId = MultisigConfig.toId(genesisConfig)
313
309
  * const account = MultisigConfig.getAddress(genesisConfig)
314
310
  *
315
311
  * const envelope = TxEnvelopeTempo.from({ chainId: 1, calls: [] })
316
312
  *
317
313
  * const digest = MultisigConfig.getSignPayload({
318
314
  * payload: TxEnvelopeTempo.getSignPayload(envelope),
319
- * account,
320
- * genesisConfigId,
315
+ * account
321
316
  * })
322
317
  * ```
323
318
  *
@@ -330,17 +325,8 @@ export function getSignPayload(value: getSignPayload.Value): Hex.Hex {
330
325
  'account' in value && value.account
331
326
  ? value.account
332
327
  : getAddress((value as { genesisConfig: Config }).genesisConfig)
333
- const genesisConfigId =
334
- 'genesisConfigId' in value && value.genesisConfigId
335
- ? value.genesisConfigId
336
- : toId((value as { genesisConfig: Config }).genesisConfig)
337
328
  return Hash.keccak256(
338
- Hex.concat(
339
- Hex.fromString(signatureDomain),
340
- Hex.from(payload),
341
- account,
342
- genesisConfigId,
343
- ),
329
+ Hex.concat(Hex.fromString(signatureDomain), Hex.from(payload), account),
344
330
  )
345
331
  }
346
332
 
@@ -352,16 +338,13 @@ export declare namespace getSignPayload {
352
338
  | {
353
339
  /** The native multisig account address. */
354
340
  account: Address.Address
355
- /** The permanent config ID. */
356
- genesisConfigId: Hex.Hex
357
341
  }
358
342
  | {
359
343
  /**
360
344
  * The initial multisig config (the bootstrap config that derived the
361
- * permanent `account` and `genesisConfigId`). Used to derive both values
362
- * automatically. Config updates never change `account`/`genesisConfigId`,
363
- * so the genesis config is also the correct input for post-update
364
- * transactions.
345
+ * permanent `account`). Used to derive the account automatically.
346
+ * Config updates never change `account`, so the genesis config is
347
+ * also the correct input for post-update transactions.
365
348
  */
366
349
  genesisConfig: Config
367
350
  }
@@ -369,66 +352,12 @@ export declare namespace getSignPayload {
369
352
 
370
353
  type ErrorType =
371
354
  | getAddress.ErrorType
372
- | toId.ErrorType
373
355
  | Hash.keccak256.ErrorType
374
356
  | Hex.concat.ErrorType
375
357
  | Hex.from.ErrorType
376
358
  | Errors.GlobalErrorType
377
359
  }
378
360
 
379
- /**
380
- * Derives the permanent config ID for a native multisig
381
- * {@link ox#MultisigConfig.Config}.
382
- *
383
- * Preimage (fixed-width big-endian, **not** RLP):
384
- * `keccak256("tempo:multisig:config" || salt || be_u32(threshold) || be_u32(owners.length) || (owner || be_u32(weight)) for each owner)`.
385
- *
386
- * @example
387
- * ```ts twoslash
388
- * import { MultisigConfig } from 'ox/tempo'
389
- *
390
- * const config = MultisigConfig.from({
391
- * threshold: 1,
392
- * owners: [
393
- * { owner: '0x1111111111111111111111111111111111111111', weight: 1 },
394
- * ],
395
- * })
396
- *
397
- * const genesisConfigId = MultisigConfig.toId(config)
398
- * ```
399
- *
400
- * @param config - The multisig config.
401
- * @returns The 32-byte config ID.
402
- */
403
- export function toId(config: Config): Hex.Hex {
404
- assert(config)
405
- const id = Hash.keccak256(
406
- Hex.concat(
407
- Hex.fromString(configDomain),
408
- Hex.padLeft(config.salt ?? zeroSalt, 32),
409
- Hex.fromNumber(config.threshold, { size: 4 }),
410
- Hex.fromNumber(config.owners.length, { size: 4 }),
411
- ...config.owners.flatMap((owner) => [
412
- owner.owner,
413
- Hex.fromNumber(owner.weight, { size: 4 }),
414
- ]),
415
- ),
416
- )
417
- if (Hex.toBigInt(id) === 0n)
418
- throw new InvalidConfigError({ reason: 'config ID cannot be zero' })
419
- return id
420
- }
421
-
422
- export declare namespace toId {
423
- type ErrorType =
424
- | assert.ErrorType
425
- | Hash.keccak256.ErrorType
426
- | Hex.concat.ErrorType
427
- | Hex.fromNumber.ErrorType
428
- | Hex.fromString.ErrorType
429
- | Errors.GlobalErrorType
430
- }
431
-
432
361
  /**
433
362
  * Converts a {@link ox#MultisigConfig.Config} to its RLP tuple form (carried
434
363
  * by the multisig signature `init`).
@@ -3,6 +3,7 @@ import {
3
3
  Hex,
4
4
  P256,
5
5
  PublicKey,
6
+ Rlp,
6
7
  Secp256k1,
7
8
  Signature,
8
9
  WebAuthnP256,
@@ -1109,7 +1110,7 @@ describe('from', () => {
1109
1110
  ],
1110
1111
  })
1111
1112
 
1112
- test('behavior: derives `account`/`genesisConfigId` from `genesisConfig`', () => {
1113
+ test('behavior: derives `account` from `genesisConfig`', () => {
1113
1114
  const envelope = SignatureEnvelope.from({
1114
1115
  genesisConfig,
1115
1116
  signatures: [SignatureEnvelope.from(signature_secp256k1)],
@@ -1118,7 +1119,6 @@ describe('from', () => {
1118
1119
  expect(envelope).toMatchObject({
1119
1120
  type: 'multisig',
1120
1121
  account: MultisigConfig.getAddress(genesisConfig),
1121
- genesisConfigId: MultisigConfig.toId(genesisConfig),
1122
1122
  })
1123
1123
  expect('genesisConfig' in envelope).toBe(false)
1124
1124
  expect((envelope as SignatureEnvelope.Multisig).init).toBeUndefined()
@@ -1155,19 +1155,16 @@ describe('from', () => {
1155
1155
  expect((envelope as SignatureEnvelope.Multisig).init).toEqual(otherConfig)
1156
1156
  })
1157
1157
 
1158
- test('behavior: `{account, genesisConfigId}` form still works', () => {
1158
+ test('behavior: `{ account }` form still works', () => {
1159
1159
  const account = MultisigConfig.getAddress(genesisConfig)
1160
- const genesisConfigId = MultisigConfig.toId(genesisConfig)
1161
1160
  const envelope = SignatureEnvelope.from({
1162
1161
  account,
1163
- genesisConfigId,
1164
1162
  signatures: [SignatureEnvelope.from(signature_secp256k1)],
1165
1163
  })
1166
1164
 
1167
1165
  expect(envelope).toMatchObject({
1168
1166
  type: 'multisig',
1169
1167
  account,
1170
- genesisConfigId,
1171
1168
  })
1172
1169
  })
1173
1170
  })
@@ -1836,9 +1833,8 @@ describe('sortMultisigApprovals', () => {
1836
1833
  expect(recovered).toEqual(ascending.map((owner) => owner.address))
1837
1834
  })
1838
1835
 
1839
- test('behavior: `genesisConfig` and `{account, genesisConfigId}` produce identical ordering', () => {
1836
+ test('behavior: `genesisConfig` and `{ account }` produce identical ordering', () => {
1840
1837
  const account = MultisigConfig.getAddress(genesisConfig)
1841
- const genesisConfigId = MultisigConfig.toId(genesisConfig)
1842
1838
  const signatures = owners.map((owner) => owner.signature)
1843
1839
 
1844
1840
  const fromConfig = SignatureEnvelope.sortMultisigApprovals({
@@ -1846,13 +1842,12 @@ describe('sortMultisigApprovals', () => {
1846
1842
  payload,
1847
1843
  signatures,
1848
1844
  })
1849
- const fromIds = SignatureEnvelope.sortMultisigApprovals({
1845
+ const fromAccount = SignatureEnvelope.sortMultisigApprovals({
1850
1846
  account,
1851
- genesisConfigId,
1852
1847
  payload,
1853
1848
  signatures,
1854
1849
  })
1855
- expect(fromConfig).toEqual(fromIds)
1850
+ expect(fromConfig).toEqual(fromAccount)
1856
1851
  })
1857
1852
  })
1858
1853
 
@@ -2855,8 +2850,6 @@ describe('CoercionError', () => {
2855
2850
 
2856
2851
  describe('multisig', () => {
2857
2852
  const account = '0x8ba6d26ff5c4e82ba0c8caf8c8ca794e1489a7ae'
2858
- const genesisConfigId =
2859
- '0x01781fe551182476f2422c759e82d81c92e3263737afbbad57def6e8b69d21f5'
2860
2853
 
2861
2854
  // P256 signatures do not carry `yParity` in the wire format, so use a clean
2862
2855
  // inner signature for round-trip equality checks.
@@ -2869,7 +2862,6 @@ describe('multisig', () => {
2869
2862
  const envelope = SignatureEnvelope.from({
2870
2863
  type: 'multisig',
2871
2864
  account,
2872
- genesisConfigId,
2873
2865
  signatures: [SignatureEnvelope.from(signature_secp256k1), innerP256],
2874
2866
  })
2875
2867
 
@@ -2878,11 +2870,32 @@ describe('multisig', () => {
2878
2870
  expect(serialized.startsWith('0x05')).toBe(true)
2879
2871
  })
2880
2872
 
2873
+ test('serialize: wire shape is `0x05 || rlp([account, signatures])`', () => {
2874
+ const deterministic = SignatureEnvelope.from({
2875
+ type: 'multisig',
2876
+ account,
2877
+ signatures: [innerP256],
2878
+ })
2879
+ expect(SignatureEnvelope.serialize(deterministic)).toMatchInlineSnapshot(
2880
+ `"0x05f89b948ba6d26ff5c4e82ba0c8caf8c8ca794e1489a7aef884b88201ccbb3485d4726235f13cb15ef394fb7158179fb7b1925eccec0147671090c52e77c3c53373cc1e3b05e7c23f609deb17cea8fe097300c45411237e9fe4166b35ad8ac16e167d6992c3e120d7f17d2376bc1cbcf30c46ba6dd00ce07303e742f511edf6ce1c32de66846f56afa7be1cbd729bc35750b6d0cdcf3ec9d75461aba001"`,
2881
+ )
2882
+ })
2883
+
2881
2884
  test('serialize/deserialize round-trip', () => {
2882
2885
  const serialized = SignatureEnvelope.serialize(envelope)
2883
2886
  expect(SignatureEnvelope.deserialize(serialized)).toEqual(envelope)
2884
2887
  })
2885
2888
 
2889
+ test('deserialize: rejects the empty `init` placeholder (`0x80`)', () => {
2890
+ const withPlaceholder = Hex.concat(
2891
+ '0x05',
2892
+ Rlp.fromHex([account, [SignatureEnvelope.serialize(innerP256)], '0x']),
2893
+ )
2894
+ expect(() => SignatureEnvelope.deserialize(withPlaceholder)).toThrowError(
2895
+ SignatureEnvelope.InvalidSerializedError,
2896
+ )
2897
+ })
2898
+
2886
2899
  test('getType', () => {
2887
2900
  expect(SignatureEnvelope.getType(envelope)).toBe('multisig')
2888
2901
  })
@@ -2908,6 +2921,97 @@ describe('multisig', () => {
2908
2921
  ).toThrowError()
2909
2922
  })
2910
2923
 
2924
+ test('assert: rejects keychain owner approvals', () => {
2925
+ expect(() =>
2926
+ SignatureEnvelope.assert({
2927
+ type: 'multisig',
2928
+ account,
2929
+ signatures: [signature_keychain_secp256k1],
2930
+ } as never),
2931
+ ).toThrowErrorMatchingInlineSnapshot(
2932
+ `[SignatureEnvelope.InvalidMultisigApprovalError: Invalid native multisig owner approval: keychain owner approvals are not allowed.]`,
2933
+ )
2934
+ })
2935
+
2936
+ describe('nested approvals', () => {
2937
+ const nestedAccount = '0x1111111111111111111111111111111111111111'
2938
+ const nested = SignatureEnvelope.from({
2939
+ type: 'multisig',
2940
+ account: nestedAccount,
2941
+ signatures: [innerP256],
2942
+ })
2943
+
2944
+ test('serialize/deserialize round-trip with a nested multisig approval', () => {
2945
+ const parent = SignatureEnvelope.from({
2946
+ type: 'multisig',
2947
+ account,
2948
+ signatures: [innerP256, nested],
2949
+ })
2950
+ const serialized = SignatureEnvelope.serialize(parent)
2951
+ expect(SignatureEnvelope.deserialize(serialized)).toEqual(parent)
2952
+ })
2953
+
2954
+ test('assert: accepts the maximum nesting depth', () => {
2955
+ const depth3 = SignatureEnvelope.from({
2956
+ type: 'multisig',
2957
+ account,
2958
+ signatures: [
2959
+ SignatureEnvelope.from({
2960
+ type: 'multisig',
2961
+ account: nestedAccount,
2962
+ signatures: [nested],
2963
+ }),
2964
+ ],
2965
+ })
2966
+ expect(() => SignatureEnvelope.assert(depth3)).not.toThrowError()
2967
+ })
2968
+
2969
+ test('assert: rejects nesting deeper than the maximum', () => {
2970
+ const depth4 = SignatureEnvelope.from({
2971
+ type: 'multisig',
2972
+ account,
2973
+ signatures: [
2974
+ SignatureEnvelope.from({
2975
+ type: 'multisig',
2976
+ account: nestedAccount,
2977
+ signatures: [
2978
+ SignatureEnvelope.from({
2979
+ type: 'multisig',
2980
+ account: nestedAccount,
2981
+ signatures: [nested],
2982
+ }),
2983
+ ],
2984
+ }),
2985
+ ],
2986
+ })
2987
+ expect(() =>
2988
+ SignatureEnvelope.assert(depth4),
2989
+ ).toThrowErrorMatchingInlineSnapshot(
2990
+ `[SignatureEnvelope.InvalidMultisigApprovalError: Invalid native multisig owner approval: multisig nesting depth exceeds 3.]`,
2991
+ )
2992
+ })
2993
+
2994
+ test('assert: rejects nested approvals carrying `init`', () => {
2995
+ expect(() =>
2996
+ SignatureEnvelope.assert({
2997
+ type: 'multisig',
2998
+ account,
2999
+ signatures: [
3000
+ {
3001
+ ...nested,
3002
+ init: {
3003
+ threshold: 1,
3004
+ owners: [{ owner: nestedAccount, weight: 1 }],
3005
+ },
3006
+ },
3007
+ ],
3008
+ } as never),
3009
+ ).toThrowErrorMatchingInlineSnapshot(
3010
+ `[SignatureEnvelope.InvalidMultisigApprovalError: Invalid native multisig owner approval: nested multisig owner approvals cannot carry \`init\`.]`,
3011
+ )
3012
+ })
3013
+ })
3014
+
2911
3015
  describe('init (bootstrap)', () => {
2912
3016
  const init = {
2913
3017
  salt: `0x${'00'.repeat(32)}` as const,
@@ -2923,7 +3027,6 @@ describe('multisig', () => {
2923
3027
  const bootstrapEnvelope = SignatureEnvelope.from({
2924
3028
  type: 'multisig',
2925
3029
  account,
2926
- genesisConfigId,
2927
3030
  signatures: [SignatureEnvelope.from(signature_secp256k1), innerP256],
2928
3031
  init,
2929
3032
  })
@@ -2939,7 +3042,6 @@ describe('multisig', () => {
2939
3042
  const salted = SignatureEnvelope.from({
2940
3043
  type: 'multisig',
2941
3044
  account,
2942
- genesisConfigId,
2943
3045
  signatures: [SignatureEnvelope.from(signature_secp256k1), innerP256],
2944
3046
  init: { ...init, salt: `0x${'42'.repeat(32)}` },
2945
3047
  })
@@ -2993,7 +3095,6 @@ describe('multisig', () => {
2993
3095
  SignatureEnvelope.assert({
2994
3096
  type: 'multisig',
2995
3097
  account,
2996
- genesisConfigId,
2997
3098
  signatures: [],
2998
3099
  init: { threshold: 1, owners: [] },
2999
3100
  } as never),