ox 0.14.37 → 0.14.39

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 (43) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/_cjs/tempo/MultisigConfig.js +71 -15
  3. package/_cjs/tempo/MultisigConfig.js.map +1 -1
  4. package/_cjs/tempo/MultisigOperation.js +241 -19
  5. package/_cjs/tempo/MultisigOperation.js.map +1 -1
  6. package/_cjs/tempo/SignatureEnvelope.js +71 -108
  7. package/_cjs/tempo/SignatureEnvelope.js.map +1 -1
  8. package/_cjs/version.js +1 -1
  9. package/_esm/tempo/MultisigConfig.js +140 -71
  10. package/_esm/tempo/MultisigConfig.js.map +1 -1
  11. package/_esm/tempo/MultisigOperation.js +331 -19
  12. package/_esm/tempo/MultisigOperation.js.map +1 -1
  13. package/_esm/tempo/SignatureEnvelope.js +84 -143
  14. package/_esm/tempo/SignatureEnvelope.js.map +1 -1
  15. package/_esm/tempo/index.js +2 -2
  16. package/_esm/version.js +1 -1
  17. package/_types/tempo/KeyAuthorization.d.ts +1 -1
  18. package/_types/tempo/KeyAuthorization.d.ts.map +1 -1
  19. package/_types/tempo/MultisigConfig.d.ts +137 -73
  20. package/_types/tempo/MultisigConfig.d.ts.map +1 -1
  21. package/_types/tempo/MultisigOperation.d.ts +169 -1
  22. package/_types/tempo/MultisigOperation.d.ts.map +1 -1
  23. package/_types/tempo/SignatureEnvelope.d.ts +81 -75
  24. package/_types/tempo/SignatureEnvelope.d.ts.map +1 -1
  25. package/_types/tempo/index.d.ts +2 -2
  26. package/_types/version.d.ts +1 -1
  27. package/package.json +6 -1
  28. package/tempo/KeyAuthorization.test-d.ts +12 -0
  29. package/tempo/KeyAuthorization.test.ts +54 -0
  30. package/tempo/KeyAuthorization.ts +1 -1
  31. package/tempo/MultisigConfig.test-d/package.json +6 -0
  32. package/tempo/MultisigConfig.test-d.ts +52 -0
  33. package/tempo/MultisigConfig.test.ts +291 -263
  34. package/tempo/MultisigConfig.ts +250 -95
  35. package/tempo/MultisigOperation.test-d.ts +25 -0
  36. package/tempo/MultisigOperation.test.ts +754 -22
  37. package/tempo/MultisigOperation.ts +548 -17
  38. package/tempo/SignatureEnvelope.test-d.ts +57 -40
  39. package/tempo/SignatureEnvelope.test.ts +523 -480
  40. package/tempo/SignatureEnvelope.ts +250 -257
  41. package/tempo/index.ts +2 -2
  42. package/tempo/multisig.e2e.test.ts +113 -86
  43. package/version.ts +1 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,34 @@
1
1
  # ox
2
2
 
3
+ ## 0.14.39
4
+
5
+ ### Patch Changes
6
+
7
+ - [#412](https://github.com/wevm/ox/pull/412) [`200d9a7`](https://github.com/wevm/ox/commit/200d9a7832b676880d296b5b03fe1dde548b9f37) Thanks [@jxom](https://github.com/jxom)! - Changed native multisig configuration and signature APIs to require complete TIP-1061 witnesses with a `version`.
8
+
9
+ ```ts
10
+ const config = MultisigConfig.from({
11
+ owners,
12
+ threshold: 2,
13
+ version: 1,
14
+ });
15
+ ```
16
+
17
+ ## 0.14.38
18
+
19
+ ### Patch Changes
20
+
21
+ - [#409](https://github.com/wevm/ox/pull/409) [`8f25490`](https://github.com/wevm/ox/commit/8f254906699e008e3d70ca172f27afda1a8e269a) Thanks [@jxom](https://github.com/jxom)! - Added multisig operation hashing, approval selection, and transaction serialization helpers.
22
+
23
+ ```ts
24
+ import { MultisigOperation } from "ox/tempo";
25
+
26
+ const selection = await MultisigOperation.selectApprovals(options);
27
+ const transaction = MultisigOperation.serializeTransaction(operation, {
28
+ approvals: selection.selectedApprovals,
29
+ });
30
+ ```
31
+
3
32
  ## 0.14.37
4
33
 
5
34
  ### Patch Changes
@@ -1,30 +1,36 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.InvalidConfigError = exports.zeroSalt = exports.signatureTypeByte = exports.maxOwnerSignatureBytes = exports.maxNestingDepth = exports.maxSignatures = exports.maxThreshold = exports.maxOwners = void 0;
3
+ exports.InvalidConfigError = exports.zeroSalt = exports.signatureTypeByte = exports.maxVersion = exports.maxThreshold = exports.maxSignatures = exports.maxOwners = exports.maxOwnerSignatureBytes = exports.maxNestingDepth = void 0;
4
4
  exports.assert = assert;
5
5
  exports.from = from;
6
+ exports.fromRpc = fromRpc;
6
7
  exports.fromTuple = fromTuple;
7
8
  exports.getAddress = getAddress;
9
+ exports.getCommitment = getCommitment;
8
10
  exports.getSignPayload = getSignPayload;
11
+ exports.toRpc = toRpc;
9
12
  exports.toTuple = toTuple;
10
13
  exports.validate = validate;
11
14
  const Address = require("../core/Address.js");
12
15
  const Errors = require("../core/Errors.js");
13
16
  const Hash = require("../core/Hash.js");
14
17
  const Hex = require("../core/Hex.js");
15
- exports.maxOwners = 48;
16
- exports.maxThreshold = 0xff;
17
- exports.maxSignatures = 8;
18
18
  exports.maxNestingDepth = 2;
19
19
  exports.maxOwnerSignatureBytes = 2049;
20
+ exports.maxOwners = 48;
21
+ exports.maxSignatures = 8;
22
+ exports.maxThreshold = 0xff;
23
+ exports.maxVersion = 2n ** 64n - 1n;
20
24
  exports.signatureTypeByte = '0x05';
21
25
  exports.zeroSalt = `0x${'00'.repeat(32)}`;
22
26
  const accountDomain = 'tempo:multisig:account';
27
+ const configDomain = 'tempo:multisig:config';
23
28
  const signatureDomain = 'tempo:multisig:signature';
24
29
  function assert(config) {
25
- const { salt, threshold, owners } = config;
30
+ const { owners, salt, threshold, version = 0n } = config;
26
31
  if (typeof salt !== 'undefined' && Hex.size(salt) !== 32)
27
32
  throw new InvalidConfigError({ reason: 'salt must be 32 bytes' });
33
+ assertVersion(version);
28
34
  if (owners.length === 0)
29
35
  throw new InvalidConfigError({ reason: 'owners cannot be empty' });
30
36
  if (owners.length > exports.maxOwners)
@@ -75,20 +81,27 @@ function assert(config) {
75
81
  });
76
82
  }
77
83
  function from(config) {
84
+ const version = config.version ?? 0n;
85
+ assertVersion(version);
78
86
  const owners = [...config.owners].sort((a, b) => Hex.toBigInt(a.owner) < Hex.toBigInt(b.owner) ? -1 : 1);
79
87
  const normalized = {
88
+ owners,
80
89
  salt: config.salt ? Hex.padLeft(config.salt, 32) : exports.zeroSalt,
81
90
  threshold: config.threshold,
82
- owners,
91
+ version: BigInt(version),
83
92
  };
84
93
  assert(normalized);
85
94
  return normalized;
86
95
  }
96
+ function fromRpc(config) {
97
+ return from({
98
+ ...config,
99
+ version: Hex.toBigInt(config.version),
100
+ });
101
+ }
87
102
  function fromTuple(tuple) {
88
- const [salt, threshold, owners] = tuple;
103
+ const [salt, version, threshold, owners] = tuple;
89
104
  return {
90
- salt: salt && salt !== '0x' ? Hex.padLeft(salt, 32) : exports.zeroSalt,
91
- threshold: threshold === '0x' ? 0 : Hex.toNumber(threshold),
92
105
  owners: owners.map((owner) => {
93
106
  const [ownerAddress, weight] = owner;
94
107
  return {
@@ -96,10 +109,17 @@ function fromTuple(tuple) {
96
109
  weight: !weight || weight === '0x' ? 0 : Hex.toNumber(weight),
97
110
  };
98
111
  }),
112
+ salt: salt && salt !== '0x' ? Hex.padLeft(salt, 32) : exports.zeroSalt,
113
+ threshold: threshold === '0x' ? 0 : Hex.toNumber(threshold),
114
+ version: version === '0x' ? 0n : Hex.toBigInt(version),
99
115
  };
100
116
  }
101
117
  function getAddress(config) {
102
118
  assert(config);
119
+ if (BigInt(config.version ?? 0) !== 0n)
120
+ throw new InvalidConfigError({
121
+ reason: 'account address requires version zero',
122
+ });
103
123
  const hash = Hash.keccak256(Hex.concat(Hex.fromString(accountDomain), Hex.padLeft(config.salt ?? exports.zeroSalt, 32), Hex.fromNumber(config.threshold, { size: 1 }), Hex.fromNumber(config.owners.length, { size: 1 }), ...config.owners.flatMap((owner) => [
104
124
  owner.owner,
105
125
  Hex.fromNumber(owner.weight, { size: 1 }),
@@ -107,20 +127,47 @@ function getAddress(config) {
107
127
  const account = Address.from(Hex.slice(hash, 12, 32));
108
128
  if (Hex.toBigInt(account) === 0n)
109
129
  throw new InvalidConfigError({ reason: 'derived account cannot be zero' });
130
+ if (config.owners.some((owner) => Address.isEqual(owner.owner, account)))
131
+ throw new InvalidConfigError({
132
+ reason: 'derived account cannot be an owner',
133
+ });
110
134
  return account;
111
135
  }
136
+ function getCommitment(config) {
137
+ assert(config);
138
+ return Hash.keccak256(Hex.concat(Hex.fromString(configDomain), Hex.padLeft(config.salt ?? exports.zeroSalt, 32), Hex.fromNumber(config.version ?? 0n, { size: 8 }), Hex.fromNumber(config.threshold, { size: 1 }), Hex.fromNumber(config.owners.length, { size: 1 }), ...config.owners.flatMap((owner) => [
139
+ owner.owner,
140
+ Hex.fromNumber(owner.weight, { size: 1 }),
141
+ ])));
142
+ }
112
143
  function getSignPayload(value) {
113
- const { payload, version = 0n } = value;
114
- const account = 'account' in value && value.account
115
- ? value.account
116
- : getAddress(value.initialConfig);
117
- return Hash.keccak256(Hex.concat(Hex.fromString(signatureDomain), Hex.from(payload), account, Hex.fromNumber(version, { size: 8 })));
144
+ const { account, config, payload } = value;
145
+ assertVersion(config.version);
146
+ return Hash.keccak256(Hex.concat(Hex.fromString(signatureDomain), Hex.from(payload), account, Hex.fromNumber(config.version ?? 0n, { size: 8 })));
147
+ }
148
+ function toRpc(config) {
149
+ const value = from(config);
150
+ return {
151
+ owners: value.owners.map((owner) => ({
152
+ owner: owner.owner,
153
+ weight: Number(owner.weight),
154
+ })),
155
+ salt: value.salt,
156
+ threshold: Number(value.threshold),
157
+ version: Hex.fromNumber(value.version),
158
+ };
118
159
  }
119
160
  function toTuple(config) {
120
161
  assert(config);
121
162
  const owners = config.owners.map((owner) => [owner.owner, Hex.fromNumber(owner.weight)]);
122
163
  const salt = config.salt ? Hex.padLeft(config.salt, 32) : exports.zeroSalt;
123
- return [salt, Hex.fromNumber(config.threshold), owners];
164
+ const version = BigInt(config.version ?? 0);
165
+ return [
166
+ salt,
167
+ version === 0n ? '0x' : Hex.fromNumber(version),
168
+ Hex.fromNumber(config.threshold),
169
+ owners,
170
+ ];
124
171
  }
125
172
  function validate(config) {
126
173
  try {
@@ -143,4 +190,13 @@ class InvalidConfigError extends Errors.BaseError {
143
190
  }
144
191
  }
145
192
  exports.InvalidConfigError = InvalidConfigError;
193
+ function assertVersion(version) {
194
+ if ((typeof version !== 'bigint' && typeof version !== 'number') ||
195
+ (typeof version === 'number' && !Number.isSafeInteger(version)) ||
196
+ BigInt(version) < 0n ||
197
+ BigInt(version) > exports.maxVersion)
198
+ throw new InvalidConfigError({
199
+ reason: 'version must be an unsigned 64-bit integer',
200
+ });
201
+ }
146
202
  //# sourceMappingURL=MultisigConfig.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"MultisigConfig.js","sourceRoot":"","sources":["../../tempo/MultisigConfig.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"MultisigConfig.js","sourceRoot":"","sources":["../../tempo/MultisigConfig.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.InvalidOperationError = void 0;
3
+ exports.InvalidOperationError = exports.InvalidApprovalError = void 0;
4
+ exports.getHash = getHash;
5
+ exports.selectApprovals = selectApprovals;
6
+ exports.serializeTransaction = serializeTransaction;
4
7
  exports.from = from;
5
8
  exports.fromRpc = fromRpc;
6
9
  exports.toRpc = toRpc;
@@ -13,22 +16,75 @@ const MultisigConfig = require("./MultisigConfig.js");
13
16
  const SignatureEnvelope = require("./SignatureEnvelope.js");
14
17
  const TxEnvelopeTempo = require("./TxEnvelopeTempo.js");
15
18
  const maxConfigVersion = 2n ** 64n - 1n;
19
+ function getHash(options) {
20
+ const { account, configVersion } = options;
21
+ const payload = options.type === 'transaction'
22
+ ? TxEnvelopeTempo.getSignPayload(TxEnvelopeTempo.deserialize(options.transaction))
23
+ : KeyAuthorization_.getSignPayload(KeyAuthorization_.deserialize(options.keyAuthorization));
24
+ return MultisigConfig.getSignPayload({
25
+ account,
26
+ config: { version: configVersion },
27
+ payload,
28
+ });
29
+ }
30
+ async function selectApprovals(options) {
31
+ const { account, approvals, hash, resolveConfig } = options;
32
+ if (!Address.validate(account) || Hex.toBigInt(account) === 0n)
33
+ throw new InvalidApprovalError({ reason: 'account is invalid' });
34
+ if (!Hash.validate(hash))
35
+ throw new InvalidApprovalError({ reason: 'hash is invalid' });
36
+ return selectApprovals_internal({
37
+ account,
38
+ approvals,
39
+ config: MultisigConfig.from(options.config),
40
+ hash,
41
+ resolveConfig,
42
+ }, [account.toLowerCase()]);
43
+ }
44
+ function serializeTransaction(operation, options) {
45
+ const value = from(operation);
46
+ const envelope = TxEnvelopeTempo.deserialize(value.transaction);
47
+ const approvals = options.approvals.map((approval) => SignatureEnvelope.from(approval));
48
+ assertRetainedApprovals(value, approvals);
49
+ const signatures = SignatureEnvelope.sortMultisigApprovals({
50
+ account: value.account,
51
+ config: value.config,
52
+ payload: TxEnvelopeTempo.getSignPayload(envelope),
53
+ signatures: approvals,
54
+ });
55
+ const signature = SignatureEnvelope.from({
56
+ account: value.account,
57
+ config: value.config,
58
+ signatures,
59
+ });
60
+ return TxEnvelopeTempo.serialize(envelope, value.transaction.startsWith(TxEnvelopeTempo.feePayerMagic)
61
+ ? {
62
+ format: 'feePayer',
63
+ sender: envelope.from,
64
+ signature,
65
+ }
66
+ : { signature });
67
+ }
16
68
  function from(operation) {
17
69
  try {
18
- const config = MultisigConfig.from(operation.config);
70
+ const config = MultisigConfig.from({
71
+ ...operation.config,
72
+ version: operation.configVersion,
73
+ });
19
74
  if (typeof config.threshold !== 'number' ||
20
75
  config.owners.some((owner) => typeof owner.weight !== 'number'))
21
76
  throw new InvalidOperationError({
22
77
  reason: 'config threshold and owner weights must be numbers',
23
78
  });
24
- assertBase(operation, config);
25
- if (operation.type === 'transaction')
26
- assertTransaction(operation);
27
- else if (operation.type === 'keyAuthorization')
28
- assertKeyAuthorization(operation, config);
79
+ const value = { ...operation, config };
80
+ assertBase(value, config);
81
+ if (value.type === 'transaction')
82
+ assertTransaction(value);
83
+ else if (value.type === 'keyAuthorization')
84
+ assertKeyAuthorization(value, config);
29
85
  else
30
86
  throw new InvalidOperationError({ reason: 'unknown operation type' });
31
- return { ...operation, config };
87
+ return value;
32
88
  }
33
89
  catch (cause) {
34
90
  if (cause instanceof InvalidOperationError)
@@ -48,7 +104,11 @@ function fromRpc(operation) {
48
104
  throw new InvalidOperationError({
49
105
  reason: 'configVersion must use canonical quantity encoding',
50
106
  });
51
- return from({ ...operation, configVersion });
107
+ return from({
108
+ ...operation,
109
+ config: MultisigConfig.fromRpc(operation.config),
110
+ configVersion,
111
+ });
52
112
  }
53
113
  catch (cause) {
54
114
  if (cause instanceof InvalidOperationError)
@@ -60,9 +120,146 @@ function toRpc(operation) {
60
120
  const value = from(operation);
61
121
  return {
62
122
  ...value,
123
+ config: MultisigConfig.toRpc(value.config),
63
124
  configVersion: Hex.fromNumber(value.configVersion),
64
125
  };
65
126
  }
127
+ async function selectApprovals_internal(options, path) {
128
+ const owners = new Map(options.config.owners.map((owner) => [
129
+ owner.owner.toLowerCase(),
130
+ { address: owner.owner, weight: Number(owner.weight) },
131
+ ]));
132
+ const groups = new Map();
133
+ for (const serialized of options.approvals) {
134
+ const signature = SignatureEnvelope.from(serialized);
135
+ if (signature.type === 'keychain')
136
+ throw new InvalidApprovalError({
137
+ reason: 'keychain signatures cannot approve a multisig operation',
138
+ });
139
+ const address = signature.type === 'multisig'
140
+ ? signature.account
141
+ : SignatureEnvelope.extractAddress({
142
+ payload: options.hash,
143
+ signature,
144
+ });
145
+ const owner = owners.get(address.toLowerCase());
146
+ if (!owner)
147
+ throw new InvalidApprovalError({
148
+ reason: `signature is from non-owner ${address}`,
149
+ });
150
+ const key = address.toLowerCase();
151
+ const group = groups.get(key);
152
+ if (group)
153
+ group.signatures.push(signature);
154
+ else
155
+ groups.set(key, {
156
+ address: owner.address,
157
+ signatures: [signature],
158
+ weight: owner.weight,
159
+ });
160
+ }
161
+ const valid = [];
162
+ const retained = [];
163
+ for (const group of groups.values()) {
164
+ const nested = group.signatures.filter((signature) => signature.type === 'multisig');
165
+ if (nested.length > 0) {
166
+ if (nested.length !== group.signatures.length)
167
+ throw new InvalidApprovalError({
168
+ reason: `owner ${group.address} has conflicting signature types`,
169
+ });
170
+ if (path.length >= MultisigConfig.maxNestingDepth ||
171
+ path.includes(group.address.toLowerCase()))
172
+ throw new InvalidApprovalError({
173
+ reason: `nested multisig owner ${group.address} is invalid`,
174
+ });
175
+ if (!options.resolveConfig)
176
+ throw new InvalidApprovalError({
177
+ reason: `nested multisig owner ${group.address} requires a config resolver`,
178
+ });
179
+ const resolved = await options.resolveConfig({ account: group.address });
180
+ const config = MultisigConfig.from({
181
+ ...resolved.config,
182
+ version: resolved.version,
183
+ });
184
+ const selected = await selectApprovals_internal({
185
+ account: group.address,
186
+ approvals: nested.flatMap((signature) => signature.signatures.map((approval) => SignatureEnvelope.serialize(approval))),
187
+ config,
188
+ hash: MultisigConfig.getSignPayload({
189
+ account: group.address,
190
+ config,
191
+ payload: options.hash,
192
+ }),
193
+ resolveConfig: options.resolveConfig,
194
+ }, [...path, group.address.toLowerCase()]);
195
+ retained.push({
196
+ address: group.address,
197
+ signature: SignatureEnvelope.serialize(SignatureEnvelope.from({
198
+ account: group.address,
199
+ config,
200
+ signatures: selected.approvals.map((approval) => SignatureEnvelope.from(approval)),
201
+ })),
202
+ });
203
+ if (selected.weight >= selected.threshold)
204
+ valid.push({
205
+ address: group.address,
206
+ signature: SignatureEnvelope.serialize(SignatureEnvelope.from({
207
+ account: group.address,
208
+ config,
209
+ signatures: selected.selectedApprovals.map((approval) => SignatureEnvelope.from(approval)),
210
+ })),
211
+ weight: group.weight,
212
+ });
213
+ continue;
214
+ }
215
+ const signatures = group.signatures.map((signature) => {
216
+ if (!SignatureEnvelope.verify(signature, {
217
+ address: group.address,
218
+ payload: options.hash,
219
+ }))
220
+ throw new InvalidApprovalError({
221
+ reason: `signature from owner ${group.address} is invalid`,
222
+ });
223
+ return SignatureEnvelope.serialize(signature);
224
+ });
225
+ const signature = signatures.sort(compareHex)[0];
226
+ valid.push({
227
+ address: group.address,
228
+ signature,
229
+ weight: group.weight,
230
+ });
231
+ retained.push({ address: group.address, signature });
232
+ }
233
+ const ranked = valid.sort((a, b) => b.weight - a.weight || compareApprovalAddress(a, b));
234
+ const selected = [];
235
+ let weight = 0;
236
+ for (const approval of ranked.slice(0, MultisigConfig.maxSignatures)) {
237
+ if (weight >= Number(options.config.threshold))
238
+ break;
239
+ selected.push(approval);
240
+ weight += approval.weight;
241
+ }
242
+ selected.sort(compareApprovalAddress);
243
+ return {
244
+ approvals: retained
245
+ .sort(compareApprovalAddress)
246
+ .map((approval) => approval.signature),
247
+ selectedApprovals: selected.map((approval) => approval.signature),
248
+ signatureCount: selected.length,
249
+ threshold: Number(options.config.threshold),
250
+ weight,
251
+ };
252
+ }
253
+ function compareApprovalAddress(a, b) {
254
+ const addressA = Hex.toBigInt(a.address);
255
+ const addressB = Hex.toBigInt(b.address);
256
+ return addressA < addressB ? -1 : addressA > addressB ? 1 : 0;
257
+ }
258
+ function compareHex(a, b) {
259
+ const hexA = a.toLowerCase();
260
+ const hexB = b.toLowerCase();
261
+ return hexA < hexB ? -1 : hexA > hexB ? 1 : 0;
262
+ }
66
263
  function assertBase(operation, config) {
67
264
  if (!Address.validate(operation.account))
68
265
  throw new InvalidOperationError({ reason: 'account is invalid' });
@@ -117,7 +314,7 @@ function assertBase(operation, config) {
117
314
  if (typeof approval !== 'string' ||
118
315
  !Hex.validate(approval, { strict: true }))
119
316
  throw new InvalidOperationError({ reason: 'approval is invalid' });
120
- const signature = assertApproval(operation.account, approval);
317
+ const signature = assertApproval(operation.account, approval, config);
121
318
  const address = SignatureEnvelope.extractAddress({
122
319
  payload: operation.hash,
123
320
  signature,
@@ -271,13 +468,9 @@ function assertKeyAuthorization(operation, config) {
271
468
  reason: 'key authorization signatureCount does not match its signature',
272
469
  });
273
470
  assertSelectedApprovals(operation, signature.signatures, authorization);
274
- if (!!signature.init !== operation.init)
275
- throw new InvalidOperationError({
276
- reason: 'key authorization bootstrap state does not match',
277
- });
278
- if (signature.init && !sameConfig(signature.init, config))
471
+ if (!sameConfig(signature.config, config))
279
472
  throw new InvalidOperationError({
280
- reason: 'key authorization bootstrap config does not match',
473
+ reason: 'key authorization config does not match',
281
474
  });
282
475
  }
283
476
  assertOperationHash(operation, KeyAuthorization_.getSignPayload(authorization));
@@ -287,10 +480,11 @@ function assertKeyAuthorization(operation, config) {
287
480
  reason: 'keyAuthorization is not canonically serialized',
288
481
  });
289
482
  }
290
- function assertApproval(account, serialized) {
483
+ function assertApproval(account, serialized, config) {
291
484
  const approval = SignatureEnvelope.deserialize(serialized);
292
485
  SignatureEnvelope.assert({
293
486
  account,
487
+ config,
294
488
  signatures: [approval],
295
489
  type: 'multisig',
296
490
  });
@@ -299,6 +493,17 @@ function assertApproval(account, serialized) {
299
493
  throw new InvalidOperationError({ reason: 'approval is not canonical' });
300
494
  return approval;
301
495
  }
496
+ function assertRetainedApprovals(operation, selected) {
497
+ const retained = operation.approvals.map((approval) => SignatureEnvelope.deserialize(approval));
498
+ for (const approval of selected) {
499
+ const index = retained.findIndex((candidate) => includesApproval(candidate, approval));
500
+ if (index === -1)
501
+ throw new InvalidOperationError({
502
+ reason: 'transaction signature is not a retained approval',
503
+ });
504
+ retained.splice(index, 1);
505
+ }
506
+ }
302
507
  function assertSelectedApprovals(operation, selected, authorization) {
303
508
  const retained = operation.approvals.map((approval) => SignatureEnvelope.deserialize(approval));
304
509
  for (const approval of selected) {
@@ -311,8 +516,8 @@ function assertSelectedApprovals(operation, selected, authorization) {
311
516
  }
312
517
  const digest = MultisigConfig.getSignPayload({
313
518
  account: operation.account,
519
+ config: operation.config,
314
520
  payload: KeyAuthorization_.getSignPayload(authorization),
315
- version: operation.configVersion,
316
521
  });
317
522
  const addresses = selected.map((signature) => SignatureEnvelope.extractAddress({ payload: digest, signature }));
318
523
  for (let index = 1; index < addresses.length; index++) {
@@ -334,6 +539,8 @@ function includesApproval(retained, selected) {
334
539
  SignatureEnvelope.serialize(selected).toLowerCase());
335
540
  if (retained.account.toLowerCase() !== selected.account.toLowerCase())
336
541
  return false;
542
+ if (!sameConfig(retained.config, selected.config))
543
+ return false;
337
544
  let index = 0;
338
545
  for (const approval of selected.signatures) {
339
546
  while (index < retained.signatures.length &&
@@ -357,8 +564,8 @@ function isWeightReachable(weights, signatureCount, weight) {
357
564
  function assertOperationHash(operation, payload) {
358
565
  const hash = MultisigConfig.getSignPayload({
359
566
  account: operation.account,
567
+ config: operation.config,
360
568
  payload,
361
- version: operation.configVersion,
362
569
  });
363
570
  if (hash.toLowerCase() !== operation.hash.toLowerCase())
364
571
  throw new InvalidOperationError({
@@ -376,6 +583,7 @@ function sameConfig(a, b) {
376
583
  const configB = MultisigConfig.from(b);
377
584
  return (Hex.isEqual(configA.salt ?? MultisigConfig.zeroSalt, configB.salt ?? MultisigConfig.zeroSalt) &&
378
585
  configA.threshold === configB.threshold &&
586
+ configA.version === configB.version &&
379
587
  configA.owners.length === configB.owners.length &&
380
588
  configA.owners.every((owner, index) => {
381
589
  const other = configB.owners[index];
@@ -383,6 +591,20 @@ function sameConfig(a, b) {
383
591
  owner.weight === other.weight);
384
592
  }));
385
593
  }
594
+ class InvalidApprovalError extends Errors.BaseError {
595
+ constructor(options = {}) {
596
+ super(options.reason
597
+ ? `Invalid multisig approval: ${options.reason}.`
598
+ : 'Invalid multisig approval.', { cause: options.cause });
599
+ Object.defineProperty(this, "name", {
600
+ enumerable: true,
601
+ configurable: true,
602
+ writable: true,
603
+ value: 'MultisigOperation.InvalidApprovalError'
604
+ });
605
+ }
606
+ }
607
+ exports.InvalidApprovalError = InvalidApprovalError;
386
608
  class InvalidOperationError extends Errors.BaseError {
387
609
  constructor(options = {}) {
388
610
  super(options.reason