Skip to content

Commit 7ab6026

Browse files
immrsdericglauPatrick-Ehimen
authored
Add Multisig (#433)
Co-authored-by: Eric Lau <[email protected]> Co-authored-by: 0xOse <[email protected]>
1 parent 8790c0e commit 7ab6026

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+1356
-39
lines changed

.github/workflows/compile-cairo-alpha-project.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ jobs:
4444
# Exit immediately if a command exits with a non-zero status
4545
set -e
4646
47-
declare -a all_kinds=("ERC20" "ERC721" "ERC1155" "Account" "Vesting" "Governor" "Custom")
47+
declare -a all_kinds=("ERC20" "ERC721" "ERC1155" "Account" "Multisig" "Governor" "Vesting" "Custom")
4848
declare -a all_royalty_info_options=("disabled" "enabled_default" "enabled_custom")
4949
for kind in "${all_kinds[@]}"; do
5050
scarb clean

.github/workflows/compile-cairo-project.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ jobs:
4444
# Exit immediately if a command exits with a non-zero status
4545
set -e
4646
47-
declare -a all_kinds=("ERC20" "ERC721" "ERC1155" "Account" "Vesting" "Governor" "Custom")
47+
declare -a all_kinds=("ERC20" "ERC721" "ERC1155" "Account" "Multisig" "Governor" "Vesting" "Custom")
4848
declare -a all_royalty_info_options=("disabled" "enabled_default" "enabled_custom")
4949
for kind in "${all_kinds[@]}"; do
5050
scarb clean

packages/core/cairo/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Changelog
22

3+
## 1.1.0 (2025-04-01)
4+
5+
- Add Multisig tab. ([#433](https://github.com/OpenZeppelin/contracts-wizard/pull/433))
6+
37
## 1.0.0 (2025-02-25)
48

59
- **Breaking changes**:

packages/core/cairo/README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ The following contract types are supported:
1818
- `erc1155`
1919
- `account`
2020
- `governor`
21+
- `multisig`
2122
- `vesting`
2223
- `custom`
2324

@@ -39,6 +40,9 @@ function print(opts?: ERC1155Options): string
3940
function print(opts?: AccountOptions): string
4041
```
4142
```js
43+
function print(opts?: MultisigOptions): string
44+
```
45+
```js
4246
function print(opts?: GovernorOptions): string
4347
```
4448
```js
@@ -63,6 +67,9 @@ const defaults: Required<ERC1155Options>
6367
const defaults: Required<AccountOptions>
6468
```
6569
```js
70+
const defaults: Required<MultisigOptions>
71+
```
72+
```js
6673
const defaults: Required<GovernorOptions>
6774
```
6875
```js

packages/core/cairo/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@openzeppelin/wizard-cairo",
3-
"version": "1.0.0",
3+
"version": "1.1.0",
44
"description": "A boilerplate generator to get started with OpenZeppelin Contracts for Cairo",
55
"license": "AGPL-3.0-only",
66
"repository": "https://github.com/OpenZeppelin/contracts-wizard",

packages/core/cairo/src/api.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ import type { AccountOptions } from './account';
2121
import { printAccount, defaults as accountDefaults } from './account';
2222
import type { GovernorOptions } from './governor';
2323
import { printGovernor, defaults as governorDefaults } from './governor';
24+
import type { MultisigOptions } from './multisig';
25+
import { printMultisig, defaults as multisigDefaults } from './multisig';
2426
import type { CustomOptions } from './custom';
2527
import {
2628
printCustom,
@@ -66,6 +68,7 @@ export type ERC20 = WizardContractAPI<ERC20Options> & AccessControlAPI<ERC20Opti
6668
export type ERC721 = WizardContractAPI<ERC721Options> & AccessControlAPI<ERC721Options>;
6769
export type ERC1155 = WizardContractAPI<ERC1155Options> & AccessControlAPI<ERC1155Options>;
6870
export type Account = WizardAccountAPI<AccountOptions>;
71+
export type Multisig = WizardContractAPI<MultisigOptions>;
6972
export type Governor = WizardContractAPI<GovernorOptions>;
7073
export type Vesting = WizardContractAPI<VestingOptions>;
7174
export type Custom = WizardContractAPI<CustomOptions> & AccessControlAPI<CustomOptions>;
@@ -89,6 +92,10 @@ export const account: Account = {
8992
print: printAccount,
9093
defaults: accountDefaults,
9194
};
95+
export const multisig: Multisig = {
96+
print: printMultisig,
97+
defaults: multisigDefaults,
98+
};
9299
export const governor: Governor = {
93100
print: printGovernor,
94101
defaults: governorDefaults,

packages/core/cairo/src/build-generic.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ import type { AccountOptions } from './account';
1010
import { buildAccount } from './account';
1111
import type { GovernorOptions } from './governor';
1212
import { buildGovernor } from './governor';
13+
import type { MultisigOptions } from './multisig';
14+
import { buildMultisig } from './multisig';
1315
import type { VestingOptions } from './vesting';
1416
import { buildVesting } from './vesting';
1517

@@ -18,6 +20,7 @@ export interface KindedOptions {
1820
ERC721: { kind: 'ERC721' } & ERC721Options;
1921
ERC1155: { kind: 'ERC1155' } & ERC1155Options;
2022
Account: { kind: 'Account' } & AccountOptions;
23+
Multisig: { kind: 'Multisig' } & MultisigOptions;
2124
Governor: { kind: 'Governor' } & GovernorOptions;
2225
Vesting: { kind: 'Vesting' } & VestingOptions;
2326
Custom: { kind: 'Custom' } & CustomOptions;
@@ -39,6 +42,9 @@ export function buildGeneric(opts: GenericOptions) {
3942
case 'Account':
4043
return buildAccount(opts);
4144

45+
case 'Multisig':
46+
return buildMultisig(opts);
47+
4248
case 'Governor':
4349
return buildGovernor(opts);
4450

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { infoOptions } from '../set-info';
2+
import type { MultisigOptions } from '../multisig';
3+
import { generateAlternatives } from './alternatives';
4+
5+
const blueprint = {
6+
name: ['MyMultisig'],
7+
quorum: ['1', '2', '42'],
8+
upgradeable: [true, false],
9+
info: infoOptions,
10+
};
11+
12+
export function* generateMultisigOptions(): Generator<Required<MultisigOptions>> {
13+
yield* generateAlternatives(blueprint);
14+
}

packages/core/cairo/src/generate/sources.ts

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { generateERC1155Options } from './erc1155';
88
import { generateAccountOptions } from './account';
99
import { generateCustomOptions } from './custom';
1010
import { generateGovernorOptions } from './governor';
11+
import { generateMultisigOptions } from './multisig';
1112
import { generateVestingOptions } from './vesting';
1213
import type { GenericOptions, KindedOptions } from '../build-generic';
1314
import { buildGeneric } from '../build-generic';
@@ -50,9 +51,9 @@ export function* generateOptions(params: {
5051
}
5152
}
5253

53-
if (kind === 'all' || kind === 'Custom') {
54-
for (const kindOpts of generateCustomOptions()) {
55-
yield { kind: 'Custom', ...kindOpts };
54+
if (kind === 'all' || kind === 'Multisig') {
55+
for (const kindOpts of generateMultisigOptions()) {
56+
yield { kind: 'Multisig', ...kindOpts };
5657
}
5758
}
5859

@@ -67,6 +68,12 @@ export function* generateOptions(params: {
6768
yield { kind: 'Vesting', ...kindOpts };
6869
}
6970
}
71+
72+
if (kind === 'all' || kind === 'Custom') {
73+
for (const kindOpts of generateCustomOptions()) {
74+
yield { kind: 'Custom', ...kindOpts };
75+
}
76+
}
7077
}
7178

7279
interface GeneratedContract {
@@ -110,10 +117,11 @@ function generateContractSubset(params: {
110117
switch (c.options.kind) {
111118
case 'Vesting':
112119
return isUpgradeable === false;
113-
case 'Account':
114120
case 'ERC20':
115121
case 'ERC721':
116122
case 'ERC1155':
123+
case 'Account':
124+
case 'Multisig':
117125
case 'Governor':
118126
case 'Custom':
119127
return c.options.upgradeable === isUpgradeable;
@@ -183,8 +191,9 @@ function resolveSourceLabel(params: { kind: KindSubset; royaltyInfo: RoyaltyInfo
183191
return 'All contract kinds';
184192
case 'ERC20':
185193
case 'Account':
186-
case 'Vesting':
194+
case 'Multisig':
187195
case 'Governor':
196+
case 'Vesting':
188197
case 'Custom':
189198
return kind;
190199
default: {

packages/core/cairo/src/governor.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import { setUpgradeableGovernor } from './set-upgradeable';
99
import { defineComponents } from './utils/define-components';
1010
import { durationToTimestamp } from './utils/duration';
1111
import { addSNIP12Metadata, addSRC5Component } from './common-components';
12-
import { toUint } from './utils/convert-strings';
12+
import { toUint, isNaturalNumber } from './utils/convert-strings';
1313
export const clockModeOptions = ['timestamp'] as const;
1414
export const clockModeDefault = 'timestamp' as const;
1515
export type ClockMode = (typeof clockModeOptions)[number];
@@ -436,7 +436,7 @@ function addQuorumAndVotes(c: ContractBuilder, allOpts: Required<GovernorOptions
436436

437437
addVotesQuorumFractionComponent(c, allOpts.quorumPercent);
438438
} else if (allOpts.quorumMode === 'absolute') {
439-
if (!numberPattern.test(allOpts.quorumAbsolute)) {
439+
if (!isNaturalNumber(allOpts.quorumAbsolute)) {
440440
throw new OptionsError({
441441
quorumAbsolute: 'Not a valid number',
442442
});
@@ -534,5 +534,3 @@ function addExecution(c: ContractBuilder, { timelock }: Required<GovernorOptions
534534
c.addComponent(components.GovernorTimelockExecutionComponent, [{ lit: 'timelock_controller' }], true);
535535
}
536536
}
537-
538-
export const numberPattern = /^(?!$)(\d*)(?:\.(\d+))?(?:e(\d+))?$/;

0 commit comments

Comments
 (0)