ox 0.14.26 → 0.14.28
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 +12 -0
- package/_cjs/tempo/MultisigConfig.js +127 -0
- package/_cjs/tempo/MultisigConfig.js.map +1 -0
- package/_cjs/tempo/ReceivePolicyReceipt.js +80 -0
- package/_cjs/tempo/ReceivePolicyReceipt.js.map +1 -0
- package/_cjs/tempo/SignatureEnvelope.js +107 -6
- package/_cjs/tempo/SignatureEnvelope.js.map +1 -1
- package/_cjs/tempo/index.js +3 -1
- package/_cjs/tempo/index.js.map +1 -1
- package/_cjs/version.js +1 -1
- package/_esm/tempo/MultisigConfig.js +312 -0
- package/_esm/tempo/MultisigConfig.js.map +1 -0
- package/_esm/tempo/ReceivePolicyReceipt.js +176 -0
- package/_esm/tempo/ReceivePolicyReceipt.js.map +1 -0
- package/_esm/tempo/SignatureEnvelope.js +170 -6
- package/_esm/tempo/SignatureEnvelope.js.map +1 -1
- package/_esm/tempo/index.js +48 -0
- package/_esm/tempo/index.js.map +1 -1
- package/_esm/version.js +1 -1
- package/_types/tempo/MultisigConfig.d.ts +270 -0
- package/_types/tempo/MultisigConfig.d.ts.map +1 -0
- package/_types/tempo/ReceivePolicyReceipt.d.ts +168 -0
- package/_types/tempo/ReceivePolicyReceipt.d.ts.map +1 -0
- package/_types/tempo/SignatureEnvelope.d.ts +106 -6
- package/_types/tempo/SignatureEnvelope.d.ts.map +1 -1
- package/_types/tempo/index.d.ts +48 -0
- package/_types/tempo/index.d.ts.map +1 -1
- package/_types/version.d.ts +1 -1
- package/package.json +11 -1
- package/tempo/MultisigConfig/package.json +6 -0
- package/tempo/MultisigConfig.test.ts +227 -0
- package/tempo/MultisigConfig.ts +423 -0
- package/tempo/ReceivePolicyReceipt/package.json +6 -0
- package/tempo/ReceivePolicyReceipt.test.ts +198 -0
- package/tempo/ReceivePolicyReceipt.ts +263 -0
- package/tempo/SignatureEnvelope.test.ts +213 -2
- package/tempo/SignatureEnvelope.ts +257 -9
- package/tempo/e2e.test.ts +217 -0
- package/tempo/index.ts +48 -0
- package/version.ts +1 -1
package/_types/tempo/index.d.ts
CHANGED
|
@@ -100,6 +100,32 @@ export * as Channel from './Channel.js';
|
|
|
100
100
|
* @category Reference
|
|
101
101
|
*/
|
|
102
102
|
export * as KeyAuthorization from './KeyAuthorization.js';
|
|
103
|
+
/**
|
|
104
|
+
* Native multisig account utilities (TIP-1061).
|
|
105
|
+
*
|
|
106
|
+
* Derives stable multisig account addresses and permanent config IDs from a weighted
|
|
107
|
+
* owner configuration, and computes the owner approval digest that owners sign.
|
|
108
|
+
*
|
|
109
|
+
* [TIP-1061](https://tips.sh/1061)
|
|
110
|
+
*
|
|
111
|
+
* @example
|
|
112
|
+
* ```ts twoslash
|
|
113
|
+
* import { MultisigConfig } from 'ox/tempo'
|
|
114
|
+
*
|
|
115
|
+
* const config = MultisigConfig.from({
|
|
116
|
+
* threshold: 2,
|
|
117
|
+
* owners: [
|
|
118
|
+
* { owner: '0x1111111111111111111111111111111111111111', weight: 1 },
|
|
119
|
+
* { owner: '0x2222222222222222222222222222222222222222', weight: 1 },
|
|
120
|
+
* ],
|
|
121
|
+
* })
|
|
122
|
+
*
|
|
123
|
+
* const account = MultisigConfig.getAddress({ config })
|
|
124
|
+
* ```
|
|
125
|
+
*
|
|
126
|
+
* @category Reference
|
|
127
|
+
*/
|
|
128
|
+
export * as MultisigConfig from './MultisigConfig.js';
|
|
103
129
|
/**
|
|
104
130
|
* Utilities for constructing period durations (in seconds) for recurring spending limits.
|
|
105
131
|
*
|
|
@@ -150,6 +176,28 @@ export * as Period from './Period.js';
|
|
|
150
176
|
* @category Reference
|
|
151
177
|
*/
|
|
152
178
|
export * as PoolId from './PoolId.js';
|
|
179
|
+
/**
|
|
180
|
+
* TIP-1028 receive-policy claim receipt utilities.
|
|
181
|
+
*
|
|
182
|
+
* When an inbound transfer or mint violates the recipient's receive policy, the
|
|
183
|
+
* funds are redirected to the `ReceivePolicyGuard` and a `ClaimReceiptV1`
|
|
184
|
+
* witness is emitted. This module decodes those witnesses (required to later
|
|
185
|
+
* `claim` or `burn` the blocked funds) from raw bytes or transaction receipts.
|
|
186
|
+
*
|
|
187
|
+
* [TIP-1028](https://docs.tempo.xyz/protocol/tips/tip-1028)
|
|
188
|
+
*
|
|
189
|
+
* @example
|
|
190
|
+
* ```ts twoslash
|
|
191
|
+
* // @noErrors
|
|
192
|
+
* import { ReceivePolicyReceipt } from 'ox/tempo'
|
|
193
|
+
*
|
|
194
|
+
* const receipts = ReceivePolicyReceipt.fromTransactionReceipt(receipt)
|
|
195
|
+
* const decoded = ReceivePolicyReceipt.decode('0x...')
|
|
196
|
+
* ```
|
|
197
|
+
*
|
|
198
|
+
* @category Reference
|
|
199
|
+
*/
|
|
200
|
+
export * as ReceivePolicyReceipt from './ReceivePolicyReceipt.js';
|
|
153
201
|
/**
|
|
154
202
|
* Union of all JSON-RPC Methods for the `tempo_` namespace.
|
|
155
203
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../tempo/index.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAEhC,YAAY,EAAE,CAAA;AAEd;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,OAAO,KAAK,kBAAkB,MAAM,yBAAyB,CAAA;AAC7D;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,OAAO,KAAK,OAAO,MAAM,cAAc,CAAA;AACvC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,OAAO,KAAK,gBAAgB,MAAM,uBAAuB,CAAA;AACzD;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA;AAErC;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA;AACrC;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,KAAK,cAAc,MAAM,qBAAqB,CAAA;AAErD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,OAAO,KAAK,iBAAiB,MAAM,wBAAwB,CAAA;AAC3D;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,KAAK,YAAY,MAAM,mBAAmB,CAAA;AACjD;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,KAAK,IAAI,MAAM,WAAW,CAAA;AACjC;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,KAAK,OAAO,MAAM,cAAc,CAAA;AACvC;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,KAAK,SAAS,MAAM,gBAAgB,CAAA;AAC3C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgDG;AACH,OAAO,KAAK,WAAW,MAAM,kBAAkB,CAAA;AAC/C;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,OAAO,KAAK,kBAAkB,MAAM,yBAAyB,CAAA;AAC7D;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,KAAK,kBAAkB,MAAM,yBAAyB,CAAA;AAC7D;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,OAAO,KAAK,eAAe,MAAM,sBAAsB,CAAA;AACvD;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,OAAO,KAAK,cAAc,MAAM,qBAAqB,CAAA;AACrD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,OAAO,KAAK,aAAa,MAAM,oBAAoB,CAAA;AAEnD;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA;AACrC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,OAAO,KAAK,qBAAqB,MAAM,4BAA4B,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../tempo/index.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAEhC,YAAY,EAAE,CAAA;AAEd;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,OAAO,KAAK,kBAAkB,MAAM,yBAAyB,CAAA;AAC7D;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,OAAO,KAAK,OAAO,MAAM,cAAc,CAAA;AACvC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,OAAO,KAAK,gBAAgB,MAAM,uBAAuB,CAAA;AACzD;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,OAAO,KAAK,cAAc,MAAM,qBAAqB,CAAA;AACrD;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA;AAErC;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA;AACrC;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,OAAO,KAAK,oBAAoB,MAAM,2BAA2B,CAAA;AACjE;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,KAAK,cAAc,MAAM,qBAAqB,CAAA;AAErD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,OAAO,KAAK,iBAAiB,MAAM,wBAAwB,CAAA;AAC3D;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,KAAK,YAAY,MAAM,mBAAmB,CAAA;AACjD;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,KAAK,IAAI,MAAM,WAAW,CAAA;AACjC;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,KAAK,OAAO,MAAM,cAAc,CAAA;AACvC;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,KAAK,SAAS,MAAM,gBAAgB,CAAA;AAC3C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgDG;AACH,OAAO,KAAK,WAAW,MAAM,kBAAkB,CAAA;AAC/C;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,OAAO,KAAK,kBAAkB,MAAM,yBAAyB,CAAA;AAC7D;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,KAAK,kBAAkB,MAAM,yBAAyB,CAAA;AAC7D;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,OAAO,KAAK,eAAe,MAAM,sBAAsB,CAAA;AACvD;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,OAAO,KAAK,cAAc,MAAM,qBAAqB,CAAA;AACrD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,OAAO,KAAK,aAAa,MAAM,oBAAoB,CAAA;AAEnD;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA;AACrC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,OAAO,KAAK,qBAAqB,MAAM,4BAA4B,CAAA"}
|
package/_types/version.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ox",
|
|
3
3
|
"description": "Ethereum Standard Library",
|
|
4
|
-
"version": "0.14.
|
|
4
|
+
"version": "0.14.28",
|
|
5
5
|
"main": "./_cjs/index.js",
|
|
6
6
|
"module": "./_esm/index.js",
|
|
7
7
|
"types": "./_types/index.d.ts",
|
|
@@ -513,6 +513,11 @@
|
|
|
513
513
|
"import": "./_esm/tempo/KeyAuthorization.js",
|
|
514
514
|
"default": "./_cjs/tempo/KeyAuthorization.js"
|
|
515
515
|
},
|
|
516
|
+
"./tempo/MultisigConfig": {
|
|
517
|
+
"types": "./_types/tempo/MultisigConfig.d.ts",
|
|
518
|
+
"import": "./_esm/tempo/MultisigConfig.js",
|
|
519
|
+
"default": "./_cjs/tempo/MultisigConfig.js"
|
|
520
|
+
},
|
|
516
521
|
"./tempo/Period": {
|
|
517
522
|
"types": "./_types/tempo/Period.d.ts",
|
|
518
523
|
"import": "./_esm/tempo/Period.js",
|
|
@@ -523,6 +528,11 @@
|
|
|
523
528
|
"import": "./_esm/tempo/PoolId.js",
|
|
524
529
|
"default": "./_cjs/tempo/PoolId.js"
|
|
525
530
|
},
|
|
531
|
+
"./tempo/ReceivePolicyReceipt": {
|
|
532
|
+
"types": "./_types/tempo/ReceivePolicyReceipt.d.ts",
|
|
533
|
+
"import": "./_esm/tempo/ReceivePolicyReceipt.js",
|
|
534
|
+
"default": "./_cjs/tempo/ReceivePolicyReceipt.js"
|
|
535
|
+
},
|
|
526
536
|
"./tempo/RpcSchemaTempo": {
|
|
527
537
|
"types": "./_types/tempo/RpcSchemaTempo.d.ts",
|
|
528
538
|
"import": "./_esm/tempo/RpcSchemaTempo.js",
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
import { MultisigConfig } from 'ox/tempo'
|
|
2
|
+
import { describe, expect, test } from 'vitest'
|
|
3
|
+
|
|
4
|
+
// Ground-truth vectors independently computed via `cast keccak` over the exact
|
|
5
|
+
// preimages defined by TIP-1061 / the Tempo reference implementation.
|
|
6
|
+
const owner1 = '0x1111111111111111111111111111111111111111'
|
|
7
|
+
const owner2 = '0x2222222222222222222222222222222222222222'
|
|
8
|
+
|
|
9
|
+
const singleOwnerConfig = {
|
|
10
|
+
threshold: 1,
|
|
11
|
+
owners: [{ owner: owner1, weight: 1 }],
|
|
12
|
+
} as const
|
|
13
|
+
|
|
14
|
+
describe('from', () => {
|
|
15
|
+
test('sorts owners ascending by address', () => {
|
|
16
|
+
const config = MultisigConfig.from({
|
|
17
|
+
threshold: 2,
|
|
18
|
+
owners: [
|
|
19
|
+
{ owner: owner2, weight: 1 },
|
|
20
|
+
{ owner: owner1, weight: 1 },
|
|
21
|
+
],
|
|
22
|
+
})
|
|
23
|
+
expect(config.owners.map((o) => o.owner)).toEqual([owner1, owner2])
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
test('asserts validity', () => {
|
|
27
|
+
expect(() =>
|
|
28
|
+
MultisigConfig.from({ threshold: 0, owners: [] }),
|
|
29
|
+
).toThrowError()
|
|
30
|
+
})
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
describe('configId', () => {
|
|
34
|
+
test('matches independent ground truth', () => {
|
|
35
|
+
expect(MultisigConfig.toId(singleOwnerConfig)).toMatchInlineSnapshot(
|
|
36
|
+
`"0xd1f20e1a5bfdd89488f57f68db5bd1aae9a51b510f4a042b2604b57a0b7b471d"`,
|
|
37
|
+
)
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
test('is stable across calls', () => {
|
|
41
|
+
expect(MultisigConfig.toId(singleOwnerConfig)).toBe(
|
|
42
|
+
MultisigConfig.toId(singleOwnerConfig),
|
|
43
|
+
)
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
test('differs for a different salt', () => {
|
|
47
|
+
expect(MultisigConfig.toId(singleOwnerConfig)).not.toBe(
|
|
48
|
+
MultisigConfig.toId({
|
|
49
|
+
...singleOwnerConfig,
|
|
50
|
+
salt: `0x${'42'.repeat(32)}`,
|
|
51
|
+
}),
|
|
52
|
+
)
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
test('throws on invalid config', () => {
|
|
56
|
+
expect(() =>
|
|
57
|
+
MultisigConfig.toId({
|
|
58
|
+
threshold: 5,
|
|
59
|
+
owners: singleOwnerConfig.owners,
|
|
60
|
+
}),
|
|
61
|
+
).toThrowError()
|
|
62
|
+
})
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
describe('getAddress', () => {
|
|
66
|
+
test('matches independent ground truth', () => {
|
|
67
|
+
expect(
|
|
68
|
+
MultisigConfig.getAddress({ config: singleOwnerConfig }),
|
|
69
|
+
).toMatchInlineSnapshot(`"0x6ca655065b1de473d903eebd50e5cb4996e10468"`)
|
|
70
|
+
})
|
|
71
|
+
|
|
72
|
+
test('derives from config or configId identically', () => {
|
|
73
|
+
const configId = MultisigConfig.toId(singleOwnerConfig)
|
|
74
|
+
expect(MultisigConfig.getAddress({ configId })).toBe(
|
|
75
|
+
MultisigConfig.getAddress({ config: singleOwnerConfig }),
|
|
76
|
+
)
|
|
77
|
+
})
|
|
78
|
+
|
|
79
|
+
test('config ID and address are chain-independent', () => {
|
|
80
|
+
// Derivation does not include chain ID; identical config → identical id/address.
|
|
81
|
+
const a = MultisigConfig.toId(singleOwnerConfig)
|
|
82
|
+
const b = MultisigConfig.toId(MultisigConfig.from(singleOwnerConfig))
|
|
83
|
+
expect(a).toBe(b)
|
|
84
|
+
})
|
|
85
|
+
})
|
|
86
|
+
|
|
87
|
+
describe('getSignPayload', () => {
|
|
88
|
+
test('matches independent ground truth', () => {
|
|
89
|
+
const configId = MultisigConfig.toId(singleOwnerConfig)
|
|
90
|
+
const account = MultisigConfig.getAddress({ configId })
|
|
91
|
+
expect(
|
|
92
|
+
MultisigConfig.getSignPayload({
|
|
93
|
+
payload: `0x${'42'.repeat(32)}`,
|
|
94
|
+
account,
|
|
95
|
+
configId,
|
|
96
|
+
}),
|
|
97
|
+
).toMatchInlineSnapshot(
|
|
98
|
+
`"0xe3d66f6118b89a67c71c8137c46abf0c829056a46ee6a038a1b42c84529fc17e"`,
|
|
99
|
+
)
|
|
100
|
+
})
|
|
101
|
+
})
|
|
102
|
+
|
|
103
|
+
describe('toTuple / fromTuple', () => {
|
|
104
|
+
test('round-trips', () => {
|
|
105
|
+
const config = MultisigConfig.from({
|
|
106
|
+
threshold: 3,
|
|
107
|
+
owners: [
|
|
108
|
+
{ owner: owner1, weight: 1 },
|
|
109
|
+
{ owner: owner2, weight: 2 },
|
|
110
|
+
],
|
|
111
|
+
})
|
|
112
|
+
const tuple = MultisigConfig.toTuple(config)
|
|
113
|
+
expect(MultisigConfig.fromTuple(tuple)).toEqual(config)
|
|
114
|
+
})
|
|
115
|
+
|
|
116
|
+
test('encodes each owner as `[owner, weight]`', () => {
|
|
117
|
+
const [, , owners] = MultisigConfig.toTuple(singleOwnerConfig)
|
|
118
|
+
expect(owners[0]).toEqual([owner1, '0x1'])
|
|
119
|
+
})
|
|
120
|
+
|
|
121
|
+
test('encodes salt as a full 32-byte string (first element)', () => {
|
|
122
|
+
const [salt] = MultisigConfig.toTuple(singleOwnerConfig)
|
|
123
|
+
expect(salt).toBe(MultisigConfig.zeroSalt)
|
|
124
|
+
})
|
|
125
|
+
|
|
126
|
+
test('round-trips a non-zero salt', () => {
|
|
127
|
+
const config = MultisigConfig.from({
|
|
128
|
+
...singleOwnerConfig,
|
|
129
|
+
salt: `0x${'42'.repeat(32)}`,
|
|
130
|
+
})
|
|
131
|
+
const tuple = MultisigConfig.toTuple(config)
|
|
132
|
+
expect(tuple[0]).toBe(`0x${'42'.repeat(32)}`)
|
|
133
|
+
expect(MultisigConfig.fromTuple(tuple)).toEqual(config)
|
|
134
|
+
})
|
|
135
|
+
})
|
|
136
|
+
|
|
137
|
+
describe('assert / validate', () => {
|
|
138
|
+
test('valid config', () => {
|
|
139
|
+
expect(MultisigConfig.validate(singleOwnerConfig)).toBe(true)
|
|
140
|
+
})
|
|
141
|
+
|
|
142
|
+
test('empty owners', () => {
|
|
143
|
+
expect(MultisigConfig.validate({ threshold: 1, owners: [] })).toBe(false)
|
|
144
|
+
})
|
|
145
|
+
|
|
146
|
+
test('too many owners', () => {
|
|
147
|
+
const owners = Array.from({ length: 11 }, (_, i) => ({
|
|
148
|
+
owner: `0x${(i + 1).toString(16).padStart(40, '0')}` as `0x${string}`,
|
|
149
|
+
weight: 1,
|
|
150
|
+
}))
|
|
151
|
+
expect(MultisigConfig.validate({ threshold: 1, owners })).toBe(false)
|
|
152
|
+
})
|
|
153
|
+
|
|
154
|
+
test('zero threshold', () => {
|
|
155
|
+
expect(
|
|
156
|
+
MultisigConfig.validate({
|
|
157
|
+
threshold: 0,
|
|
158
|
+
owners: singleOwnerConfig.owners,
|
|
159
|
+
}),
|
|
160
|
+
).toBe(false)
|
|
161
|
+
})
|
|
162
|
+
|
|
163
|
+
test('threshold exceeds total weight', () => {
|
|
164
|
+
expect(
|
|
165
|
+
MultisigConfig.validate({
|
|
166
|
+
threshold: 2,
|
|
167
|
+
owners: singleOwnerConfig.owners,
|
|
168
|
+
}),
|
|
169
|
+
).toBe(false)
|
|
170
|
+
})
|
|
171
|
+
|
|
172
|
+
test('zero owner weight', () => {
|
|
173
|
+
expect(
|
|
174
|
+
MultisigConfig.validate({
|
|
175
|
+
threshold: 1,
|
|
176
|
+
owners: [{ owner: owner1, weight: 0 }],
|
|
177
|
+
}),
|
|
178
|
+
).toBe(false)
|
|
179
|
+
})
|
|
180
|
+
|
|
181
|
+
test('zero owner address', () => {
|
|
182
|
+
expect(
|
|
183
|
+
MultisigConfig.validate({
|
|
184
|
+
threshold: 1,
|
|
185
|
+
owners: [
|
|
186
|
+
{
|
|
187
|
+
owner: '0x0000000000000000000000000000000000000000',
|
|
188
|
+
weight: 1,
|
|
189
|
+
},
|
|
190
|
+
],
|
|
191
|
+
}),
|
|
192
|
+
).toBe(false)
|
|
193
|
+
})
|
|
194
|
+
|
|
195
|
+
test('unsorted owners', () => {
|
|
196
|
+
expect(
|
|
197
|
+
MultisigConfig.validate({
|
|
198
|
+
threshold: 1,
|
|
199
|
+
owners: [
|
|
200
|
+
{ owner: owner2, weight: 1 },
|
|
201
|
+
{ owner: owner1, weight: 1 },
|
|
202
|
+
],
|
|
203
|
+
}),
|
|
204
|
+
).toBe(false)
|
|
205
|
+
})
|
|
206
|
+
|
|
207
|
+
test('duplicate owners', () => {
|
|
208
|
+
expect(
|
|
209
|
+
MultisigConfig.validate({
|
|
210
|
+
threshold: 1,
|
|
211
|
+
owners: [
|
|
212
|
+
{ owner: owner1, weight: 1 },
|
|
213
|
+
{ owner: owner1, weight: 1 },
|
|
214
|
+
],
|
|
215
|
+
}),
|
|
216
|
+
).toBe(false)
|
|
217
|
+
})
|
|
218
|
+
|
|
219
|
+
test('invalid salt size', () => {
|
|
220
|
+
expect(
|
|
221
|
+
MultisigConfig.validate({
|
|
222
|
+
...singleOwnerConfig,
|
|
223
|
+
salt: '0x42',
|
|
224
|
+
}),
|
|
225
|
+
).toBe(false)
|
|
226
|
+
})
|
|
227
|
+
})
|