ox 0.14.30 → 0.14.32
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 +25 -0
- package/_cjs/core/AbiParameters.js +2 -1
- package/_cjs/core/AbiParameters.js.map +1 -1
- package/_cjs/core/internal/abiParameters.js +10 -2
- package/_cjs/core/internal/abiParameters.js.map +1 -1
- package/_cjs/tempo/EarnShares.js +66 -0
- package/_cjs/tempo/EarnShares.js.map +1 -0
- package/_cjs/tempo/KeyAuthorization.js +39 -10
- package/_cjs/tempo/KeyAuthorization.js.map +1 -1
- package/_cjs/tempo/MultisigConfig.js +12 -2
- package/_cjs/tempo/MultisigConfig.js.map +1 -1
- package/_cjs/tempo/SignatureEnvelope.js +167 -46
- package/_cjs/tempo/SignatureEnvelope.js.map +1 -1
- package/_cjs/tempo/index.js +2 -1
- package/_cjs/tempo/index.js.map +1 -1
- package/_cjs/version.js +1 -1
- package/_esm/core/AbiParameters.js +4 -1
- package/_esm/core/AbiParameters.js.map +1 -1
- package/_esm/core/internal/abiParameters.js +17 -2
- package/_esm/core/internal/abiParameters.js.map +1 -1
- package/_esm/tempo/EarnShares.js +167 -0
- package/_esm/tempo/EarnShares.js.map +1 -0
- package/_esm/tempo/KeyAuthorization.js +41 -9
- package/_esm/tempo/KeyAuthorization.js.map +1 -1
- package/_esm/tempo/MultisigConfig.js +16 -4
- package/_esm/tempo/MultisigConfig.js.map +1 -1
- package/_esm/tempo/SignatureEnvelope.js +172 -55
- package/_esm/tempo/SignatureEnvelope.js.map +1 -1
- package/_esm/tempo/index.js +22 -0
- package/_esm/tempo/index.js.map +1 -1
- package/_esm/version.js +1 -1
- package/_types/core/AbiParameters.d.ts.map +1 -1
- package/_types/core/internal/abiParameters.d.ts.map +1 -1
- package/_types/core/internal/rpcSchemas/eth.d.ts +16 -0
- package/_types/core/internal/rpcSchemas/eth.d.ts.map +1 -1
- package/_types/tempo/EarnShares.d.ts +176 -0
- package/_types/tempo/EarnShares.d.ts.map +1 -0
- package/_types/tempo/KeyAuthorization.d.ts +22 -16
- package/_types/tempo/KeyAuthorization.d.ts.map +1 -1
- package/_types/tempo/MultisigConfig.d.ts +8 -4
- package/_types/tempo/MultisigConfig.d.ts.map +1 -1
- package/_types/tempo/SignatureEnvelope.d.ts +33 -13
- package/_types/tempo/SignatureEnvelope.d.ts.map +1 -1
- package/_types/tempo/index.d.ts +22 -0
- package/_types/tempo/index.d.ts.map +1 -1
- package/_types/version.d.ts +1 -1
- package/core/AbiParameters.ts +3 -1
- package/core/internal/abiParameters.ts +17 -2
- package/core/internal/rpcSchemas/eth.ts +16 -0
- package/package.json +16 -1
- package/tempo/EarnShares/package.json +6 -0
- package/tempo/EarnShares.test.ts +122 -0
- package/tempo/EarnShares.ts +232 -0
- package/tempo/KeyAuthorization.test-d/package.json +6 -0
- package/tempo/KeyAuthorization.test-d.ts +62 -0
- package/tempo/KeyAuthorization.test.ts +132 -0
- package/tempo/KeyAuthorization.ts +76 -29
- package/tempo/MultisigConfig.test.ts +34 -2
- package/tempo/MultisigConfig.ts +18 -4
- package/tempo/SignatureEnvelope.test-d/package.json +6 -0
- package/tempo/SignatureEnvelope.test-d.ts +97 -0
- package/tempo/SignatureEnvelope.test.ts +227 -36
- package/tempo/SignatureEnvelope.ts +276 -85
- package/tempo/e2e.test.ts +0 -416
- package/tempo/index.ts +22 -0
- package/tempo/multisig.e2e.test.ts +582 -0
- package/version.ts +1 -1
|
@@ -2886,18 +2886,45 @@ describe('multisig', () => {
|
|
|
2886
2886
|
expect(SignatureEnvelope.deserialize(serialized)).toEqual(envelope)
|
|
2887
2887
|
})
|
|
2888
2888
|
|
|
2889
|
-
test('deserialize: rejects the
|
|
2890
|
-
const
|
|
2889
|
+
test('deserialize: rejects the legacy three-field wire shape', () => {
|
|
2890
|
+
const init = MultisigConfig.toTuple({
|
|
2891
|
+
threshold: 1,
|
|
2892
|
+
owners: [
|
|
2893
|
+
{ owner: '0x1111111111111111111111111111111111111111', weight: 1 },
|
|
2894
|
+
],
|
|
2895
|
+
})
|
|
2896
|
+
const legacy = Hex.concat(
|
|
2897
|
+
'0x05',
|
|
2898
|
+
Rlp.fromHex([account, [SignatureEnvelope.serialize(innerP256)], init]),
|
|
2899
|
+
)
|
|
2900
|
+
expect(() => SignatureEnvelope.deserialize(legacy)).toThrowError(
|
|
2901
|
+
SignatureEnvelope.InvalidSerializedError,
|
|
2902
|
+
)
|
|
2903
|
+
})
|
|
2904
|
+
|
|
2905
|
+
test('deserialize: rejects an invalid initialized account', () => {
|
|
2906
|
+
const malformed = Hex.concat(
|
|
2891
2907
|
'0x05',
|
|
2892
|
-
Rlp.fromHex([
|
|
2908
|
+
Rlp.fromHex(['0x11', [SignatureEnvelope.serialize(innerP256)]]),
|
|
2893
2909
|
)
|
|
2894
|
-
expect(() => SignatureEnvelope.deserialize(
|
|
2910
|
+
expect(() => SignatureEnvelope.deserialize(malformed)).toThrowError(
|
|
2895
2911
|
SignatureEnvelope.InvalidSerializedError,
|
|
2896
2912
|
)
|
|
2897
2913
|
})
|
|
2898
2914
|
|
|
2899
2915
|
test('getType', () => {
|
|
2900
2916
|
expect(SignatureEnvelope.getType(envelope)).toBe('multisig')
|
|
2917
|
+
expect(
|
|
2918
|
+
SignatureEnvelope.getType({
|
|
2919
|
+
init: {
|
|
2920
|
+
threshold: 1,
|
|
2921
|
+
owners: [
|
|
2922
|
+
{ owner: '0x1111111111111111111111111111111111111111', weight: 1 },
|
|
2923
|
+
],
|
|
2924
|
+
},
|
|
2925
|
+
signatures: [innerP256],
|
|
2926
|
+
} as never),
|
|
2927
|
+
).toBe('multisig')
|
|
2901
2928
|
})
|
|
2902
2929
|
|
|
2903
2930
|
test('extractAddress returns the multisig account', () => {
|
|
@@ -2910,9 +2937,19 @@ describe('multisig', () => {
|
|
|
2910
2937
|
})
|
|
2911
2938
|
|
|
2912
2939
|
test('toRpc/fromRpc round-trip', () => {
|
|
2913
|
-
const rpc = SignatureEnvelope.toRpc(
|
|
2914
|
-
|
|
2940
|
+
const rpc = SignatureEnvelope.toRpc(
|
|
2941
|
+
envelope,
|
|
2942
|
+
) as SignatureEnvelope.MultisigRpc
|
|
2943
|
+
expect(rpc).toMatchObject({
|
|
2944
|
+
account,
|
|
2945
|
+
signatures: [{ type: 'secp256k1' }, { type: 'p256' }],
|
|
2946
|
+
})
|
|
2947
|
+
expect(rpc.init).toBeUndefined()
|
|
2948
|
+
expect('type' in rpc).toBe(false)
|
|
2915
2949
|
expect(SignatureEnvelope.fromRpc(rpc)).toEqual(envelope)
|
|
2950
|
+
expect(
|
|
2951
|
+
SignatureEnvelope.fromRpc({ ...rpc, type: 'multisig' } as never),
|
|
2952
|
+
).toEqual(envelope)
|
|
2916
2953
|
})
|
|
2917
2954
|
|
|
2918
2955
|
test('assert: missing properties', () => {
|
|
@@ -2921,6 +2958,63 @@ describe('multisig', () => {
|
|
|
2921
2958
|
).toThrowError()
|
|
2922
2959
|
})
|
|
2923
2960
|
|
|
2961
|
+
test('assert: rejects empty owner approvals', () => {
|
|
2962
|
+
expect(() =>
|
|
2963
|
+
SignatureEnvelope.assert({
|
|
2964
|
+
type: 'multisig',
|
|
2965
|
+
account,
|
|
2966
|
+
signatures: [],
|
|
2967
|
+
}),
|
|
2968
|
+
).toThrowErrorMatchingInlineSnapshot(
|
|
2969
|
+
`[SignatureEnvelope.InvalidMultisigApprovalError: Invalid native multisig owner approval: multisig signatures cannot be empty.]`,
|
|
2970
|
+
)
|
|
2971
|
+
})
|
|
2972
|
+
|
|
2973
|
+
test('assert: accepts at most eight owner approvals', () => {
|
|
2974
|
+
expect(() =>
|
|
2975
|
+
SignatureEnvelope.assert({
|
|
2976
|
+
type: 'multisig',
|
|
2977
|
+
account,
|
|
2978
|
+
signatures: Array.from(
|
|
2979
|
+
{ length: MultisigConfig.maxSignatures },
|
|
2980
|
+
() => innerP256,
|
|
2981
|
+
),
|
|
2982
|
+
}),
|
|
2983
|
+
).not.toThrow()
|
|
2984
|
+
|
|
2985
|
+
expect(() =>
|
|
2986
|
+
SignatureEnvelope.assert({
|
|
2987
|
+
type: 'multisig',
|
|
2988
|
+
account,
|
|
2989
|
+
signatures: Array.from(
|
|
2990
|
+
{ length: MultisigConfig.maxSignatures + 1 },
|
|
2991
|
+
() => innerP256,
|
|
2992
|
+
),
|
|
2993
|
+
}),
|
|
2994
|
+
).toThrowErrorMatchingInlineSnapshot(
|
|
2995
|
+
`[SignatureEnvelope.InvalidMultisigApprovalError: Invalid native multisig owner approval: multisig signatures exceed 8.]`,
|
|
2996
|
+
)
|
|
2997
|
+
})
|
|
2998
|
+
|
|
2999
|
+
test('assert: rejects oversized owner approvals', () => {
|
|
3000
|
+
const oversized = {
|
|
3001
|
+
...signature_webauthn,
|
|
3002
|
+
metadata: {
|
|
3003
|
+
...signature_webauthn.metadata,
|
|
3004
|
+
clientDataJSON: JSON.stringify({ value: 'x'.repeat(2048) }),
|
|
3005
|
+
},
|
|
3006
|
+
}
|
|
3007
|
+
expect(() =>
|
|
3008
|
+
SignatureEnvelope.assert({
|
|
3009
|
+
type: 'multisig',
|
|
3010
|
+
account,
|
|
3011
|
+
signatures: [oversized],
|
|
3012
|
+
}),
|
|
3013
|
+
).toThrowErrorMatchingInlineSnapshot(
|
|
3014
|
+
`[SignatureEnvelope.InvalidMultisigApprovalError: Invalid native multisig owner approval: multisig owner signature exceeds 2049 bytes.]`,
|
|
3015
|
+
)
|
|
3016
|
+
})
|
|
3017
|
+
|
|
2924
3018
|
test('assert: rejects keychain owner approvals', () => {
|
|
2925
3019
|
expect(() =>
|
|
2926
3020
|
SignatureEnvelope.assert({
|
|
@@ -2952,42 +3046,44 @@ describe('multisig', () => {
|
|
|
2952
3046
|
})
|
|
2953
3047
|
|
|
2954
3048
|
test('assert: accepts the maximum nesting depth', () => {
|
|
2955
|
-
const
|
|
3049
|
+
const depth2 = SignatureEnvelope.from({
|
|
2956
3050
|
type: 'multisig',
|
|
2957
3051
|
account,
|
|
2958
|
-
signatures: [
|
|
2959
|
-
SignatureEnvelope.from({
|
|
2960
|
-
type: 'multisig',
|
|
2961
|
-
account: nestedAccount,
|
|
2962
|
-
signatures: [nested],
|
|
2963
|
-
}),
|
|
2964
|
-
],
|
|
3052
|
+
signatures: [nested],
|
|
2965
3053
|
})
|
|
2966
|
-
expect(() => SignatureEnvelope.assert(
|
|
3054
|
+
expect(() => SignatureEnvelope.assert(depth2)).not.toThrowError()
|
|
2967
3055
|
})
|
|
2968
3056
|
|
|
2969
3057
|
test('assert: rejects nesting deeper than the maximum', () => {
|
|
2970
|
-
const
|
|
3058
|
+
const depth3 = SignatureEnvelope.from({
|
|
2971
3059
|
type: 'multisig',
|
|
2972
3060
|
account,
|
|
2973
3061
|
signatures: [
|
|
2974
3062
|
SignatureEnvelope.from({
|
|
2975
3063
|
type: 'multisig',
|
|
2976
3064
|
account: nestedAccount,
|
|
2977
|
-
signatures: [
|
|
2978
|
-
SignatureEnvelope.from({
|
|
2979
|
-
type: 'multisig',
|
|
2980
|
-
account: nestedAccount,
|
|
2981
|
-
signatures: [nested],
|
|
2982
|
-
}),
|
|
2983
|
-
],
|
|
3065
|
+
signatures: [nested],
|
|
2984
3066
|
}),
|
|
2985
3067
|
],
|
|
2986
3068
|
})
|
|
2987
3069
|
expect(() =>
|
|
2988
|
-
SignatureEnvelope.assert(
|
|
3070
|
+
SignatureEnvelope.assert(depth3),
|
|
2989
3071
|
).toThrowErrorMatchingInlineSnapshot(
|
|
2990
|
-
`[SignatureEnvelope.InvalidMultisigApprovalError: Invalid native multisig owner approval: multisig nesting depth exceeds
|
|
3072
|
+
`[SignatureEnvelope.InvalidMultisigApprovalError: Invalid native multisig owner approval: multisig nesting depth exceeds 2.]`,
|
|
3073
|
+
)
|
|
3074
|
+
})
|
|
3075
|
+
|
|
3076
|
+
test('deserialize: rejects nesting deeper than the maximum during decode', () => {
|
|
3077
|
+
const primitive = SignatureEnvelope.serialize(innerP256)
|
|
3078
|
+
const depth1 = Hex.concat(
|
|
3079
|
+
'0x05',
|
|
3080
|
+
Rlp.fromHex([nestedAccount, [primitive]]),
|
|
3081
|
+
)
|
|
3082
|
+
const depth2 = Hex.concat('0x05', Rlp.fromHex([nestedAccount, [depth1]]))
|
|
3083
|
+
const depth3 = Hex.concat('0x05', Rlp.fromHex([account, [depth2]]))
|
|
3084
|
+
|
|
3085
|
+
expect(() => SignatureEnvelope.deserialize(depth3)).toThrowError(
|
|
3086
|
+
SignatureEnvelope.InvalidSerializedError,
|
|
2991
3087
|
)
|
|
2992
3088
|
})
|
|
2993
3089
|
|
|
@@ -3023,10 +3119,11 @@ describe('multisig', () => {
|
|
|
3023
3119
|
},
|
|
3024
3120
|
],
|
|
3025
3121
|
}
|
|
3122
|
+
const bootstrapAccount = MultisigConfig.getAddress(init)
|
|
3026
3123
|
|
|
3027
3124
|
const bootstrapEnvelope = SignatureEnvelope.from({
|
|
3028
3125
|
type: 'multisig',
|
|
3029
|
-
account,
|
|
3126
|
+
account: bootstrapAccount,
|
|
3030
3127
|
signatures: [SignatureEnvelope.from(signature_secp256k1), innerP256],
|
|
3031
3128
|
init,
|
|
3032
3129
|
})
|
|
@@ -3038,12 +3135,68 @@ describe('multisig', () => {
|
|
|
3038
3135
|
)
|
|
3039
3136
|
})
|
|
3040
3137
|
|
|
3138
|
+
test('deserialize: validates bootstrap init semantics', () => {
|
|
3139
|
+
const invalid = Hex.concat(
|
|
3140
|
+
'0x05',
|
|
3141
|
+
Rlp.fromHex([
|
|
3142
|
+
[MultisigConfig.zeroSalt, '0x01', []],
|
|
3143
|
+
[SignatureEnvelope.serialize(innerP256)],
|
|
3144
|
+
]),
|
|
3145
|
+
)
|
|
3146
|
+
expect(() => SignatureEnvelope.deserialize(invalid)).toThrowError(
|
|
3147
|
+
MultisigConfig.InvalidConfigError,
|
|
3148
|
+
)
|
|
3149
|
+
})
|
|
3150
|
+
|
|
3151
|
+
test('deserialize: rejects noncanonical bootstrap field widths', () => {
|
|
3152
|
+
const signatures = [SignatureEnvelope.serialize(innerP256)]
|
|
3153
|
+
const shortSalt = Hex.concat(
|
|
3154
|
+
'0x05',
|
|
3155
|
+
Rlp.fromHex([
|
|
3156
|
+
[`0x${'00'.repeat(31)}`, '0x01', [[init.owners[0]!.owner, '0x01']]],
|
|
3157
|
+
signatures,
|
|
3158
|
+
]),
|
|
3159
|
+
)
|
|
3160
|
+
const wideThreshold = Hex.concat(
|
|
3161
|
+
'0x05',
|
|
3162
|
+
Rlp.fromHex([
|
|
3163
|
+
[init.salt, '0x0001', [[init.owners[0]!.owner, '0x01']]],
|
|
3164
|
+
signatures,
|
|
3165
|
+
]),
|
|
3166
|
+
)
|
|
3167
|
+
const wideWeight = Hex.concat(
|
|
3168
|
+
'0x05',
|
|
3169
|
+
Rlp.fromHex([
|
|
3170
|
+
[init.salt, '0x01', [[init.owners[0]!.owner, '0x0001']]],
|
|
3171
|
+
signatures,
|
|
3172
|
+
]),
|
|
3173
|
+
)
|
|
3174
|
+
|
|
3175
|
+
for (const serialized of [shortSalt, wideThreshold, wideWeight])
|
|
3176
|
+
expect(() => SignatureEnvelope.deserialize(serialized)).toThrowError(
|
|
3177
|
+
SignatureEnvelope.InvalidSerializedError,
|
|
3178
|
+
)
|
|
3179
|
+
})
|
|
3180
|
+
|
|
3181
|
+
test('serialize: wire shape is `0x05 || rlp([init, signatures])`', () => {
|
|
3182
|
+
const serialized = SignatureEnvelope.serialize(bootstrapEnvelope)
|
|
3183
|
+
const [address] = Rlp.toHex(Hex.slice(serialized, 1)) as readonly [
|
|
3184
|
+
MultisigConfig.Tuple,
|
|
3185
|
+
readonly Hex.Hex[],
|
|
3186
|
+
]
|
|
3187
|
+
expect(MultisigConfig.fromTuple(address)).toEqual(init)
|
|
3188
|
+
})
|
|
3189
|
+
|
|
3041
3190
|
test('serialize/deserialize round-trip preserves non-zero salt', () => {
|
|
3191
|
+
const saltedInit = {
|
|
3192
|
+
...init,
|
|
3193
|
+
salt: `0x${'42'.repeat(32)}` as const,
|
|
3194
|
+
}
|
|
3042
3195
|
const salted = SignatureEnvelope.from({
|
|
3043
3196
|
type: 'multisig',
|
|
3044
|
-
account,
|
|
3197
|
+
account: MultisigConfig.getAddress(saltedInit),
|
|
3045
3198
|
signatures: [SignatureEnvelope.from(signature_secp256k1), innerP256],
|
|
3046
|
-
init:
|
|
3199
|
+
init: saltedInit,
|
|
3047
3200
|
})
|
|
3048
3201
|
const serialized = SignatureEnvelope.serialize(salted)
|
|
3049
3202
|
const deserialized = SignatureEnvelope.deserialize(
|
|
@@ -3066,27 +3219,52 @@ describe('multisig', () => {
|
|
|
3066
3219
|
})
|
|
3067
3220
|
|
|
3068
3221
|
test('toRpc/fromRpc round-trip with init', () => {
|
|
3069
|
-
const rpc = SignatureEnvelope.toRpc(
|
|
3222
|
+
const rpc = SignatureEnvelope.toRpc(
|
|
3223
|
+
bootstrapEnvelope,
|
|
3224
|
+
) as SignatureEnvelope.MultisigRpc
|
|
3070
3225
|
expect(rpc.init).toEqual(init)
|
|
3226
|
+
expect(rpc.account).toBeUndefined()
|
|
3227
|
+
expect('type' in rpc).toBe(false)
|
|
3071
3228
|
expect(SignatureEnvelope.fromRpc(rpc)).toEqual(bootstrapEnvelope)
|
|
3072
3229
|
})
|
|
3073
3230
|
|
|
3074
|
-
test('toRpc encodes owner approvals as
|
|
3231
|
+
test('toRpc encodes owner approvals as structured RPC envelopes', () => {
|
|
3075
3232
|
const multisig = bootstrapEnvelope as SignatureEnvelope.Multisig
|
|
3076
3233
|
const rpc = SignatureEnvelope.toRpc(
|
|
3077
3234
|
multisig,
|
|
3078
3235
|
) as SignatureEnvelope.MultisigRpc
|
|
3079
3236
|
expect(rpc.signatures).toEqual(
|
|
3080
|
-
multisig.signatures.map((
|
|
3237
|
+
multisig.signatures.map((signature) =>
|
|
3238
|
+
SignatureEnvelope.toRpc(signature),
|
|
3239
|
+
),
|
|
3081
3240
|
)
|
|
3082
3241
|
})
|
|
3083
3242
|
|
|
3084
3243
|
test('fromRpc detects multisig by shape (no `type` field)', () => {
|
|
3085
3244
|
const rpc = SignatureEnvelope.toRpc(bootstrapEnvelope)
|
|
3086
|
-
|
|
3087
|
-
|
|
3088
|
-
|
|
3245
|
+
expect(SignatureEnvelope.fromRpc(rpc)).toEqual(bootstrapEnvelope)
|
|
3246
|
+
})
|
|
3247
|
+
|
|
3248
|
+
test('fromRpc accepts the opposite static property as undefined', () => {
|
|
3249
|
+
const rpc = SignatureEnvelope.toRpc(
|
|
3250
|
+
bootstrapEnvelope,
|
|
3251
|
+
) as SignatureEnvelope.MultisigRpc
|
|
3252
|
+
expect(
|
|
3253
|
+
SignatureEnvelope.fromRpc({ ...rpc, account: undefined } as never),
|
|
3254
|
+
).toEqual(bootstrapEnvelope)
|
|
3255
|
+
})
|
|
3256
|
+
|
|
3257
|
+
test('fromRpc rejects the legacy combined account and init shape', () => {
|
|
3258
|
+
const rpc = SignatureEnvelope.toRpc(
|
|
3089
3259
|
bootstrapEnvelope,
|
|
3260
|
+
) as SignatureEnvelope.MultisigRpc
|
|
3261
|
+
expect(() =>
|
|
3262
|
+
SignatureEnvelope.fromRpc({
|
|
3263
|
+
...rpc,
|
|
3264
|
+
account: bootstrapAccount,
|
|
3265
|
+
} as never),
|
|
3266
|
+
).toThrowErrorMatchingInlineSnapshot(
|
|
3267
|
+
`[SignatureEnvelope.InvalidMultisigApprovalError: Invalid native multisig owner approval: RPC multisig must contain exactly one of \`account\` or \`init\`.]`,
|
|
3090
3268
|
)
|
|
3091
3269
|
})
|
|
3092
3270
|
|
|
@@ -3094,11 +3272,24 @@ describe('multisig', () => {
|
|
|
3094
3272
|
expect(() =>
|
|
3095
3273
|
SignatureEnvelope.assert({
|
|
3096
3274
|
type: 'multisig',
|
|
3097
|
-
account,
|
|
3098
|
-
signatures: [],
|
|
3275
|
+
account: bootstrapAccount,
|
|
3276
|
+
signatures: [innerP256],
|
|
3099
3277
|
init: { threshold: 1, owners: [] },
|
|
3100
3278
|
} as never),
|
|
3101
3279
|
).toThrowError()
|
|
3102
3280
|
})
|
|
3281
|
+
|
|
3282
|
+
test('assert: init must derive the supplied account', () => {
|
|
3283
|
+
expect(() =>
|
|
3284
|
+
SignatureEnvelope.assert({
|
|
3285
|
+
type: 'multisig',
|
|
3286
|
+
account,
|
|
3287
|
+
signatures: [innerP256],
|
|
3288
|
+
init,
|
|
3289
|
+
}),
|
|
3290
|
+
).toThrowErrorMatchingInlineSnapshot(
|
|
3291
|
+
`[SignatureEnvelope.InvalidMultisigApprovalError: Invalid native multisig owner approval: multisig init does not derive account.]`,
|
|
3292
|
+
)
|
|
3293
|
+
})
|
|
3103
3294
|
})
|
|
3104
3295
|
})
|