ox 0.14.28 → 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.
- package/CHANGELOG.md +24 -0
- package/_cjs/tempo/MultisigConfig.js +19 -21
- package/_cjs/tempo/MultisigConfig.js.map +1 -1
- package/_cjs/tempo/SignatureEnvelope.js +62 -28
- package/_cjs/tempo/SignatureEnvelope.js.map +1 -1
- package/_cjs/version.js +1 -1
- package/_esm/tempo/MultisigConfig.js +60 -49
- package/_esm/tempo/MultisigConfig.js.map +1 -1
- package/_esm/tempo/SignatureEnvelope.js +118 -41
- package/_esm/tempo/SignatureEnvelope.js.map +1 -1
- package/_esm/tempo/index.js +4 -4
- package/_esm/version.js +1 -1
- package/_types/tempo/MultisigConfig.d.ts +68 -56
- package/_types/tempo/MultisigConfig.d.ts.map +1 -1
- package/_types/tempo/SignatureEnvelope.d.ts +90 -26
- package/_types/tempo/SignatureEnvelope.d.ts.map +1 -1
- package/_types/tempo/index.d.ts +4 -4
- package/_types/version.d.ts +1 -1
- package/package.json +1 -1
- package/tempo/MultisigConfig.test.ts +62 -36
- package/tempo/MultisigConfig.ts +102 -95
- package/tempo/SignatureEnvelope.test.ts +226 -27
- package/tempo/SignatureEnvelope.ts +174 -69
- package/tempo/e2e.test.ts +263 -48
- package/tempo/index.ts +4 -4
- package/version.ts +1 -1
|
@@ -74,7 +74,6 @@ export type GetType<
|
|
|
74
74
|
? 'keychain'
|
|
75
75
|
: envelope extends {
|
|
76
76
|
account: Address.Address
|
|
77
|
-
configId: `0x${string}`
|
|
78
77
|
signatures: any
|
|
79
78
|
}
|
|
80
79
|
? 'multisig'
|
|
@@ -150,9 +149,10 @@ export type KeychainRpc = {
|
|
|
150
149
|
/**
|
|
151
150
|
* Native multisig signature (type `0x05`).
|
|
152
151
|
*
|
|
153
|
-
* Wraps a set of
|
|
154
|
-
* multisig owner approval digest. The transaction sender is
|
|
155
|
-
* authorized once the recovered owner weights meet the
|
|
152
|
+
* Wraps a set of owner approvals (secp256k1, p256, webAuthn, or nested
|
|
153
|
+
* multisig) over the multisig owner approval digest. The transaction sender is
|
|
154
|
+
* the derived `account`, authorized once the recovered owner weights meet the
|
|
155
|
+
* configured threshold.
|
|
156
156
|
*
|
|
157
157
|
* [TIP-1061](https://tips.sh/1061)
|
|
158
158
|
*/
|
|
@@ -160,9 +160,11 @@ export type Multisig<bigintType = bigint, numberType = number> = {
|
|
|
160
160
|
type: 'multisig'
|
|
161
161
|
/** Native multisig account address. */
|
|
162
162
|
account: Address.Address
|
|
163
|
-
/**
|
|
164
|
-
|
|
165
|
-
|
|
163
|
+
/**
|
|
164
|
+
* Owner approvals over the multisig owner approval digest. Each approval is
|
|
165
|
+
* either a primitive signature or a nested multisig signature (keychain
|
|
166
|
+
* approvals are invalid).
|
|
167
|
+
*/
|
|
166
168
|
signatures: readonly SignatureEnvelope<bigintType, numberType>[]
|
|
167
169
|
/**
|
|
168
170
|
* Initial native multisig config for bootstrapping this account. Present only on
|
|
@@ -175,10 +177,9 @@ export type Multisig<bigintType = bigint, numberType = number> = {
|
|
|
175
177
|
export type MultisigRpc = {
|
|
176
178
|
type: 'multisig'
|
|
177
179
|
account: Address.Address
|
|
178
|
-
configId: Hex.Hex
|
|
179
180
|
/**
|
|
180
|
-
* Encoded
|
|
181
|
-
*
|
|
181
|
+
* Encoded owner approvals (raw serialized signatures), matching the node's
|
|
182
|
+
* `Vec<Bytes>` representation.
|
|
182
183
|
*/
|
|
183
184
|
signatures: readonly Serialized[]
|
|
184
185
|
init?: MultisigConfig.Config | undefined
|
|
@@ -328,11 +329,24 @@ export function assert(envelope: PartialBy<SignatureEnvelope, 'type'>): void {
|
|
|
328
329
|
const multisig = envelope as Multisig
|
|
329
330
|
const missing: string[] = []
|
|
330
331
|
if (!multisig.account) missing.push('account')
|
|
331
|
-
if (!multisig.configId) missing.push('configId')
|
|
332
332
|
if (!Array.isArray(multisig.signatures)) missing.push('signatures')
|
|
333
333
|
if (missing.length > 0)
|
|
334
334
|
throw new MissingPropertiesError({ envelope, missing, type: 'multisig' })
|
|
335
|
-
|
|
335
|
+
if (getNestingDepth(multisig) > MultisigConfig.maxNestingDepth)
|
|
336
|
+
throw new InvalidMultisigApprovalError({
|
|
337
|
+
reason: `multisig nesting depth exceeds ${MultisigConfig.maxNestingDepth}`,
|
|
338
|
+
})
|
|
339
|
+
for (const inner of multisig.signatures) {
|
|
340
|
+
if (inner.type === 'keychain')
|
|
341
|
+
throw new InvalidMultisigApprovalError({
|
|
342
|
+
reason: 'keychain owner approvals are not allowed',
|
|
343
|
+
})
|
|
344
|
+
if (inner.type === 'multisig' && inner.init)
|
|
345
|
+
throw new InvalidMultisigApprovalError({
|
|
346
|
+
reason: 'nested multisig owner approvals cannot carry `init`',
|
|
347
|
+
})
|
|
348
|
+
assert(inner)
|
|
349
|
+
}
|
|
336
350
|
if (multisig.init) MultisigConfig.assert(multisig.init)
|
|
337
351
|
return
|
|
338
352
|
}
|
|
@@ -341,12 +355,22 @@ export function assert(envelope: PartialBy<SignatureEnvelope, 'type'>): void {
|
|
|
341
355
|
export declare namespace assert {
|
|
342
356
|
type ErrorType =
|
|
343
357
|
| CoercionError
|
|
358
|
+
| InvalidMultisigApprovalError
|
|
344
359
|
| MissingPropertiesError
|
|
345
360
|
| MultisigConfig.assert.ErrorType
|
|
346
361
|
| Signature.assert.ErrorType
|
|
347
362
|
| Errors.GlobalErrorType
|
|
348
363
|
}
|
|
349
364
|
|
|
365
|
+
// Returns the deepest multisig path length within a multisig envelope.
|
|
366
|
+
function getNestingDepth(envelope: Multisig): number {
|
|
367
|
+
let deepest = 0
|
|
368
|
+
for (const inner of envelope.signatures)
|
|
369
|
+
if (inner.type === 'multisig')
|
|
370
|
+
deepest = Math.max(deepest, getNestingDepth(inner))
|
|
371
|
+
return 1 + deepest
|
|
372
|
+
}
|
|
373
|
+
|
|
350
374
|
/**
|
|
351
375
|
* Extracts the address of the signer from a {@link ox#SignatureEnvelope.SignatureEnvelope}.
|
|
352
376
|
*
|
|
@@ -613,24 +637,26 @@ export function deserialize(value: Serialized): SignatureEnvelope {
|
|
|
613
637
|
}
|
|
614
638
|
|
|
615
639
|
if (typeId === serializedMultisigType) {
|
|
616
|
-
// Wire format: `0x05 || rlp([account,
|
|
617
|
-
//
|
|
618
|
-
//
|
|
619
|
-
const [account,
|
|
620
|
-
Hex.Hex,
|
|
640
|
+
// Wire format: `0x05 || rlp([account, signatures, init?])`. `init` is a
|
|
641
|
+
// trailing optional: the bootstrap config list when present, otherwise
|
|
642
|
+
// omitted entirely (the empty `0x80` placeholder is rejected).
|
|
643
|
+
const [account, signatures, init] = Rlp.toHex(data) as [
|
|
621
644
|
Hex.Hex,
|
|
622
645
|
readonly Hex.Hex[],
|
|
623
646
|
(Hex.Hex | MultisigConfig.Tuple)?,
|
|
624
647
|
]
|
|
648
|
+
if (typeof init !== 'undefined' && !Array.isArray(init))
|
|
649
|
+
throw new InvalidSerializedError({
|
|
650
|
+
reason:
|
|
651
|
+
'Invalid multisig `init`: expected the bootstrap config list or an omitted trailing element',
|
|
652
|
+
serialized,
|
|
653
|
+
})
|
|
625
654
|
return {
|
|
626
655
|
type: 'multisig',
|
|
627
656
|
account,
|
|
628
|
-
configId,
|
|
629
657
|
signatures: signatures.map((signature) => deserialize(signature)),
|
|
630
|
-
...(init
|
|
631
|
-
? {
|
|
632
|
-
init: MultisigConfig.fromTuple(init as MultisigConfig.Tuple),
|
|
633
|
-
}
|
|
658
|
+
...(init
|
|
659
|
+
? { init: MultisigConfig.fromTuple(init as MultisigConfig.Tuple) }
|
|
634
660
|
: {}),
|
|
635
661
|
} satisfies Multisig
|
|
636
662
|
}
|
|
@@ -753,6 +779,43 @@ export function deserialize(value: Serialized): SignatureEnvelope {
|
|
|
753
779
|
* })
|
|
754
780
|
* ```
|
|
755
781
|
*
|
|
782
|
+
* @example
|
|
783
|
+
* ### Multisig (from genesis config)
|
|
784
|
+
*
|
|
785
|
+
* Pass `genesisConfig` to derive `account` automatically. Set `init: true` to
|
|
786
|
+
* opt into bootstrap (uses `genesisConfig` as the bootstrap `init`); omit
|
|
787
|
+
* `init` for subsequent (non-bootstrap) transactions.
|
|
788
|
+
*
|
|
789
|
+
* ```ts twoslash
|
|
790
|
+
* import { Secp256k1 } from 'ox'
|
|
791
|
+
* import { MultisigConfig, SignatureEnvelope } from 'ox/tempo'
|
|
792
|
+
*
|
|
793
|
+
* const genesisConfig = MultisigConfig.from({
|
|
794
|
+
* threshold: 1,
|
|
795
|
+
* owners: [
|
|
796
|
+
* { owner: '0x1111111111111111111111111111111111111111', weight: 1 },
|
|
797
|
+
* ],
|
|
798
|
+
* })
|
|
799
|
+
*
|
|
800
|
+
* const privateKey = Secp256k1.randomPrivateKey()
|
|
801
|
+
* const signature = SignatureEnvelope.from(
|
|
802
|
+
* Secp256k1.sign({ payload: '0xdeadbeef', privateKey }),
|
|
803
|
+
* )
|
|
804
|
+
*
|
|
805
|
+
* // Bootstrap transaction
|
|
806
|
+
* const bootstrap = SignatureEnvelope.from({
|
|
807
|
+
* genesisConfig,
|
|
808
|
+
* signatures: [signature],
|
|
809
|
+
* init: true,
|
|
810
|
+
* })
|
|
811
|
+
*
|
|
812
|
+
* // Subsequent (non-bootstrap) transactions
|
|
813
|
+
* const subsequent = SignatureEnvelope.from({
|
|
814
|
+
* genesisConfig,
|
|
815
|
+
* signatures: [signature],
|
|
816
|
+
* })
|
|
817
|
+
* ```
|
|
818
|
+
*
|
|
756
819
|
* @param value - The value to coerce (either a hex string or signature envelope).
|
|
757
820
|
* @returns The signature envelope.
|
|
758
821
|
*/
|
|
@@ -774,20 +837,35 @@ export function from<const value extends from.Value>(
|
|
|
774
837
|
const type = getType(value)
|
|
775
838
|
|
|
776
839
|
if (type === 'multisig') {
|
|
777
|
-
const multisig = value as Multisig
|
|
840
|
+
const multisig = value as Multisig & {
|
|
841
|
+
genesisConfig?: MultisigConfig.Config | undefined
|
|
842
|
+
init?: MultisigConfig.Config | boolean | undefined
|
|
843
|
+
}
|
|
844
|
+
const { genesisConfig, init, ...rest } = multisig
|
|
845
|
+
// Derive `account` from `genesisConfig` when not provided explicitly.
|
|
846
|
+
const account = (() => {
|
|
847
|
+
if (rest.account) return rest.account
|
|
848
|
+
if (genesisConfig) return MultisigConfig.getAddress(genesisConfig)
|
|
849
|
+
return rest.account
|
|
850
|
+
})()
|
|
851
|
+
// `init: true` opts into bootstrap using the supplied `genesisConfig`.
|
|
852
|
+
// Otherwise, `init` is treated as the explicit bootstrap config (or
|
|
853
|
+
// omitted).
|
|
854
|
+
const initSource = init === true ? genesisConfig : init || undefined
|
|
778
855
|
return {
|
|
779
|
-
...
|
|
780
|
-
|
|
856
|
+
...rest,
|
|
857
|
+
account,
|
|
858
|
+
signatures: rest.signatures.map((signature) => from(signature)),
|
|
781
859
|
// Normalize the bootstrap config (sorts owners, defaults the salt) so the
|
|
782
860
|
// in-memory envelope matches what `deserialize` reconstructs.
|
|
783
|
-
...(
|
|
861
|
+
...(initSource ? { init: MultisigConfig.from(initSource) } : {}),
|
|
784
862
|
type,
|
|
785
863
|
} as never
|
|
786
864
|
}
|
|
787
865
|
|
|
788
866
|
return {
|
|
789
867
|
...value,
|
|
790
|
-
...(type === 'p256' ? { prehash: value.prehash } : {}),
|
|
868
|
+
...(type === 'p256' ? { prehash: (value as P256).prehash } : {}),
|
|
791
869
|
...(type === 'keychain'
|
|
792
870
|
? {
|
|
793
871
|
...(!(
|
|
@@ -827,10 +905,24 @@ export declare namespace from {
|
|
|
827
905
|
payload?: Hex.Hex | Bytes.Bytes | undefined
|
|
828
906
|
}
|
|
829
907
|
|
|
908
|
+
/**
|
|
909
|
+
* Multisig envelope input variant where `account` is derived from the
|
|
910
|
+
* supplied `genesisConfig`. Pass `init: true` to opt into bootstrap (uses
|
|
911
|
+
* `genesisConfig` as the bootstrap `init`); omit `init` for subsequent
|
|
912
|
+
* (non-bootstrap) transactions.
|
|
913
|
+
*/
|
|
914
|
+
type MultisigFromGenesisConfig = {
|
|
915
|
+
type?: 'multisig' | undefined
|
|
916
|
+
genesisConfig: MultisigConfig.Config
|
|
917
|
+
signatures: readonly SignatureEnvelope[]
|
|
918
|
+
init?: MultisigConfig.Config | boolean | undefined
|
|
919
|
+
}
|
|
920
|
+
|
|
830
921
|
type Value =
|
|
831
922
|
| UnionPartialBy<SignatureEnvelope, 'prehash' | 'type'>
|
|
832
923
|
| Secp256k1Flat
|
|
833
924
|
| Serialized
|
|
925
|
+
| MultisigFromGenesisConfig
|
|
834
926
|
|
|
835
927
|
type ReturnValue<value extends Value> = Compute<
|
|
836
928
|
OneOf<
|
|
@@ -838,16 +930,18 @@ export declare namespace from {
|
|
|
838
930
|
? SignatureEnvelope
|
|
839
931
|
: value extends Secp256k1Flat
|
|
840
932
|
? Secp256k1
|
|
841
|
-
:
|
|
842
|
-
?
|
|
843
|
-
:
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
933
|
+
: value extends MultisigFromGenesisConfig
|
|
934
|
+
? Multisig
|
|
935
|
+
: IsNarrowable<value, SignatureEnvelope> extends true
|
|
936
|
+
? SignatureEnvelope
|
|
937
|
+
: Assign<
|
|
938
|
+
value,
|
|
939
|
+
{
|
|
940
|
+
readonly type: GetType<value>
|
|
941
|
+
} & (GetType<value> extends 'keychain'
|
|
942
|
+
? { keyId?: Address.Address | undefined }
|
|
943
|
+
: {})
|
|
944
|
+
>
|
|
851
945
|
>
|
|
852
946
|
>
|
|
853
947
|
}
|
|
@@ -955,15 +1049,12 @@ export function fromRpc(envelope: SignatureEnvelopeRpc): SignatureEnvelope {
|
|
|
955
1049
|
|
|
956
1050
|
if (
|
|
957
1051
|
envelope.type === 'multisig' ||
|
|
958
|
-
('account' in envelope &&
|
|
959
|
-
'configId' in envelope &&
|
|
960
|
-
'signatures' in envelope)
|
|
1052
|
+
('account' in envelope && 'signatures' in envelope)
|
|
961
1053
|
) {
|
|
962
1054
|
const multisig = envelope as MultisigRpc
|
|
963
1055
|
return {
|
|
964
1056
|
type: 'multisig',
|
|
965
1057
|
account: multisig.account,
|
|
966
|
-
configId: multisig.configId,
|
|
967
1058
|
// Owner approvals are raw serialized signatures (node `Vec<Bytes>`).
|
|
968
1059
|
signatures: multisig.signatures.map((signature) =>
|
|
969
1060
|
deserialize(signature),
|
|
@@ -1050,8 +1141,7 @@ export function getType<
|
|
|
1050
1141
|
|
|
1051
1142
|
// Detect Multisig signature
|
|
1052
1143
|
if (
|
|
1053
|
-
'account' in envelope &&
|
|
1054
|
-
'configId' in envelope &&
|
|
1144
|
+
('account' in envelope || 'genesisConfig' in envelope) &&
|
|
1055
1145
|
'signatures' in envelope
|
|
1056
1146
|
)
|
|
1057
1147
|
return 'multisig' as never
|
|
@@ -1151,17 +1241,15 @@ export function serialize(
|
|
|
1151
1241
|
|
|
1152
1242
|
if (type === 'multisig') {
|
|
1153
1243
|
const multisig = envelope as Multisig
|
|
1154
|
-
// Format: `0x05 || rlp([account,
|
|
1155
|
-
//
|
|
1156
|
-
// config
|
|
1157
|
-
// placeholder (`0x` → RLP `0x80`).
|
|
1244
|
+
// Format: `0x05 || rlp([account, signatures, init?])`, where each owner
|
|
1245
|
+
// approval is an encoded signature. `init` is a trailing optional: the
|
|
1246
|
+
// bootstrap config list when present, otherwise omitted entirely.
|
|
1158
1247
|
return Hex.concat(
|
|
1159
1248
|
serializedMultisigType,
|
|
1160
1249
|
Rlp.fromHex([
|
|
1161
1250
|
multisig.account,
|
|
1162
|
-
multisig.configId,
|
|
1163
1251
|
multisig.signatures.map((signature) => serialize(signature)),
|
|
1164
|
-
multisig.init ? MultisigConfig.toTuple(multisig.init) :
|
|
1252
|
+
...(multisig.init ? [MultisigConfig.toTuple(multisig.init)] : []),
|
|
1165
1253
|
]),
|
|
1166
1254
|
options.magic ? magicBytes : '0x',
|
|
1167
1255
|
)
|
|
@@ -1189,35 +1277,35 @@ export declare namespace serialize {
|
|
|
1189
1277
|
* ({@link ox#MultisigConfig.(getSignPayload:function)}), so the signer of
|
|
1190
1278
|
* every approval is recovered against that digest and the list is sorted by the
|
|
1191
1279
|
* recovered owner address. Works for any owner key type (secp256k1, p256,
|
|
1192
|
-
* webAuthn
|
|
1280
|
+
* webAuthn).
|
|
1281
|
+
*
|
|
1282
|
+
* Config updates never change `account`, so the genesis config is the correct
|
|
1283
|
+
* input even for post-update transactions.
|
|
1193
1284
|
*
|
|
1194
1285
|
* @example
|
|
1195
1286
|
* ```ts twoslash
|
|
1196
1287
|
* import { Secp256k1 } from 'ox'
|
|
1197
1288
|
* import { MultisigConfig, SignatureEnvelope, TxEnvelopeTempo } from 'ox/tempo'
|
|
1198
1289
|
*
|
|
1199
|
-
* const
|
|
1290
|
+
* const genesisConfig = MultisigConfig.from({
|
|
1200
1291
|
* threshold: 2,
|
|
1201
1292
|
* owners: [
|
|
1202
1293
|
* { owner: '0x1111111111111111111111111111111111111111', weight: 1 },
|
|
1203
1294
|
* { owner: '0x2222222222222222222222222222222222222222', weight: 1 },
|
|
1204
1295
|
* ],
|
|
1205
1296
|
* })
|
|
1206
|
-
* const configId = MultisigConfig.toId(config)
|
|
1207
|
-
* const account = MultisigConfig.getAddress({ configId })
|
|
1208
1297
|
*
|
|
1209
1298
|
* const tx = TxEnvelopeTempo.from({ chainId: 1, calls: [] })
|
|
1210
1299
|
* const payload = TxEnvelopeTempo.getSignPayload(tx)
|
|
1211
|
-
* const digest = MultisigConfig.getSignPayload({ payload, account, configId })
|
|
1212
1300
|
*
|
|
1213
1301
|
* const privateKeys = [Secp256k1.randomPrivateKey(), Secp256k1.randomPrivateKey()]
|
|
1302
|
+
* const digest = MultisigConfig.getSignPayload({ payload, genesisConfig })
|
|
1214
1303
|
* const signatures = privateKeys.map((privateKey) =>
|
|
1215
1304
|
* SignatureEnvelope.from(Secp256k1.sign({ payload: digest, privateKey })),
|
|
1216
1305
|
* )
|
|
1217
1306
|
*
|
|
1218
1307
|
* const ordered = SignatureEnvelope.sortMultisigApprovals({ // [!code focus]
|
|
1219
|
-
*
|
|
1220
|
-
* configId, // [!code focus]
|
|
1308
|
+
* genesisConfig, // [!code focus]
|
|
1221
1309
|
* payload, // [!code focus]
|
|
1222
1310
|
* signatures, // [!code focus]
|
|
1223
1311
|
* }) // [!code focus]
|
|
@@ -1229,12 +1317,12 @@ export declare namespace serialize {
|
|
|
1229
1317
|
export function sortMultisigApprovals(
|
|
1230
1318
|
value: sortMultisigApprovals.Value,
|
|
1231
1319
|
): readonly SignatureEnvelope[] {
|
|
1232
|
-
const {
|
|
1233
|
-
const digest = MultisigConfig.getSignPayload(
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1320
|
+
const { payload, signatures } = value
|
|
1321
|
+
const digest = MultisigConfig.getSignPayload(
|
|
1322
|
+
'genesisConfig' in value && value.genesisConfig
|
|
1323
|
+
? { payload, genesisConfig: value.genesisConfig }
|
|
1324
|
+
: { payload, account: (value as { account: Address.Address }).account },
|
|
1325
|
+
)
|
|
1238
1326
|
// Recover each signer once (decorate–sort–undecorate) rather than inside the
|
|
1239
1327
|
// comparator.
|
|
1240
1328
|
return signatures
|
|
@@ -1248,15 +1336,23 @@ export function sortMultisigApprovals(
|
|
|
1248
1336
|
|
|
1249
1337
|
export declare namespace sortMultisigApprovals {
|
|
1250
1338
|
type Value = {
|
|
1251
|
-
/** The native multisig account address. */
|
|
1252
|
-
account: Address.Address
|
|
1253
|
-
/** The permanent config ID. */
|
|
1254
|
-
configId: Hex.Hex
|
|
1255
1339
|
/** The inner transaction sign payload (`tx.signature_hash()`). */
|
|
1256
1340
|
payload: Hex.Hex | Bytes.Bytes
|
|
1257
|
-
/** The
|
|
1341
|
+
/** The owner approvals to order. */
|
|
1258
1342
|
signatures: readonly SignatureEnvelope[]
|
|
1259
|
-
}
|
|
1343
|
+
} & OneOf<
|
|
1344
|
+
| {
|
|
1345
|
+
/** The native multisig account address. */
|
|
1346
|
+
account: Address.Address
|
|
1347
|
+
}
|
|
1348
|
+
| {
|
|
1349
|
+
/**
|
|
1350
|
+
* The initial multisig config (the bootstrap config that derived the
|
|
1351
|
+
* permanent `account`). Used to derive the account automatically.
|
|
1352
|
+
*/
|
|
1353
|
+
genesisConfig: MultisigConfig.Config
|
|
1354
|
+
}
|
|
1355
|
+
>
|
|
1260
1356
|
|
|
1261
1357
|
type ErrorType =
|
|
1262
1358
|
| MultisigConfig.getSignPayload.ErrorType
|
|
@@ -1336,7 +1432,6 @@ export function toRpc(envelope: SignatureEnvelope): SignatureEnvelopeRpc {
|
|
|
1336
1432
|
return {
|
|
1337
1433
|
type: 'multisig',
|
|
1338
1434
|
account: multisig.account,
|
|
1339
|
-
configId: multisig.configId,
|
|
1340
1435
|
// Owner approvals are raw serialized signatures (node `Vec<Bytes>`).
|
|
1341
1436
|
signatures: multisig.signatures.map((signature) => serialize(signature)),
|
|
1342
1437
|
...(multisig.init ? { init: multisig.init } : {}),
|
|
@@ -1606,6 +1701,16 @@ export class InvalidSerializedError extends Errors.BaseError {
|
|
|
1606
1701
|
}
|
|
1607
1702
|
}
|
|
1608
1703
|
|
|
1704
|
+
/**
|
|
1705
|
+
* Error thrown when a native multisig owner approval is invalid.
|
|
1706
|
+
*/
|
|
1707
|
+
export class InvalidMultisigApprovalError extends Errors.BaseError {
|
|
1708
|
+
override readonly name = 'SignatureEnvelope.InvalidMultisigApprovalError'
|
|
1709
|
+
constructor({ reason }: { reason: string }) {
|
|
1710
|
+
super(`Invalid native multisig owner approval: ${reason}.`)
|
|
1711
|
+
}
|
|
1712
|
+
}
|
|
1713
|
+
|
|
1609
1714
|
/**
|
|
1610
1715
|
* Error thrown when a signature envelope fails to verify.
|
|
1611
1716
|
*/
|