Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
108 commits
Select commit Hold shift + click to select a range
35aa51c
Add Multisig contract
immrsd Jan 28, 2025
a2b498f
Add Multisig UI controls
immrsd Jan 28, 2025
2064ade
Support Multisig throughout the app
immrsd Jan 28, 2025
3b0fae5
Add generators for Multisig
immrsd Jan 28, 2025
0f1e76f
Add tests for Multisig
immrsd Jan 28, 2025
e1055f3
Generate Multisig tests snapshots
immrsd Jan 28, 2025
9036217
Add changelog entry
immrsd Jan 28, 2025
a519546
Merge remote-tracking branch 'upstream/master' into multisig-wallet
ericglau Feb 5, 2025
c5427cb
Fix merge
ericglau Feb 5, 2025
bd1e135
Update Cairo API readme
ericglau Feb 5, 2025
6e96877
Add isNaturalNumber helper function
immrsd Feb 11, 2025
85cbf13
Merge branch 'multisig-wallet' of github.com:immrsd/contracts-wizard …
immrsd Feb 11, 2025
4234d3b
Add name customization for Vesting and Multisig
immrsd Feb 18, 2025
10c0931
Merge main
immrsd Feb 18, 2025
f8be222
Duplicate Cairo folder for alpha version support
immrsd Mar 11, 2025
7709e5a
Update Cairo alpha package settings
immrsd Mar 11, 2025
572d3ea
Duplicate Cairo UI components for alpha support
immrsd Mar 11, 2025
23e341d
Introduce VersionSwitch control
immrsd Mar 11, 2025
8ec076e
Update heigh calculation logic in Cairo UI apps
immrsd Mar 11, 2025
be29b93
Update main page to support Cairo alpha version
immrsd Mar 11, 2025
7390cd5
Handle params for switching app, version, and contract tab
ericglau Mar 11, 2025
2cc1ee8
Fix lint
ericglau Mar 11, 2025
063f01a
Move version switcher to language bar
ericglau Mar 12, 2025
5ab8529
Use stable and alpha as version aliases
ericglau Mar 12, 2025
6930a16
Dynamically resize version dropdown
ericglau Mar 12, 2025
6e46f3b
Remove unused param
ericglau Mar 12, 2025
e56aff3
Bake cairo versions for ui
ericglau Mar 12, 2025
df53e1d
Fix script
ericglau Mar 12, 2025
e359437
Only append version if not default
ericglau Mar 12, 2025
6781b8c
Update Cairo alpha snapshots
immrsd Mar 15, 2025
c9f2c2e
Make isDefaultVersion param explicit
immrsd Mar 15, 2025
6840c89
Revert height calculation changes
immrsd Mar 15, 2025
d750a94
Make cairo-alpha package private
immrsd Mar 15, 2025
63c533e
Merge master
immrsd Mar 15, 2025
cf087a2
Add DefaultConfig import
immrsd Mar 19, 2025
e3be449
Update Cairo & Scarb versions
immrsd Mar 19, 2025
88fd218
Update Cairo Alpha test project dependencies
immrsd Mar 19, 2025
3ff1c56
Add parsing logic for Kind type
immrsd Mar 19, 2025
49b7733
Update Cairo test project script
immrsd Mar 19, 2025
1a1c905
Add github workflow checking Cairo test project
immrsd Mar 19, 2025
91783f7
Fix workflow
immrsd Mar 19, 2025
959b738
Fix workflow
immrsd Mar 19, 2025
3e3e2f6
Add other contract kinds to CI job
immrsd Mar 19, 2025
eddccf7
Transform into a single CI job
immrsd Mar 19, 2025
f039ce1
Make improvements to workflow logs
immrsd Mar 19, 2025
2053191
Minor improvements + enable testing ERC1155
immrsd Mar 19, 2025
bd30c72
Remove ERC1155, add concurrency
immrsd Mar 19, 2025
744d608
Make workflow run only when there's a change
immrsd Mar 19, 2025
69d86b4
Remove check for push events
immrsd Mar 19, 2025
5200690
Support Cairo alpha version (#481)
immrsd Mar 24, 2025
927f29f
Update Cairo lib source
immrsd Mar 24, 2025
dd83f73
Merge UI changes
immrsd Mar 24, 2025
264673e
Revert unnecessary changes
immrsd Mar 24, 2025
7b379d0
Leave only ERC1155 for testing
immrsd Mar 24, 2025
cb8a638
Revert unnecessary UI changes
immrsd Mar 25, 2025
e53a7e8
Update cairo-alpha readme
immrsd Mar 25, 2025
95687f8
Update cairo-alpha package version
immrsd Mar 25, 2025
e9708b9
Add changelog entry for new Cairo Alpha version
immrsd Mar 25, 2025
a892321
Update Cairo Alpha versions
immrsd Mar 25, 2025
71de942
Update version in snapshots
immrsd Mar 25, 2025
57ca078
Merge changes
immrsd Mar 25, 2025
3386bae
Add workflow for Cairo Alpha
immrsd Mar 25, 2025
54b7a2c
Introduce RoyaltyInfo subsets
immrsd Mar 25, 2025
48c04d4
Update ERC721 generator logic
immrsd Mar 25, 2025
5126a62
Update ERC1155 generator logic
immrsd Mar 25, 2025
55c21ea
Update Cairo sources generator logic
immrsd Mar 25, 2025
aaf4d52
Update update-scarb-project script
immrsd Mar 25, 2025
d200297
Add logging option for generator
immrsd Mar 25, 2025
d1cc312
Turn on generator logging in scripts
immrsd Mar 25, 2025
1df721f
Update Cairo test files
immrsd Mar 25, 2025
38a2283
Update workflow script for Cairo-Stable
immrsd Mar 25, 2025
b7366de
Fix scripts in workflow files
immrsd Mar 25, 2025
edac5bc
Fix scripts
immrsd Mar 25, 2025
e1154e9
Fix script variables
immrsd Mar 25, 2025
b21dcda
Fix kinds in Cairo workflow scripts
immrsd Mar 25, 2025
f6a52a0
Fix working dir in Cairo workflow
immrsd Mar 25, 2025
b0ae446
Fix royalty options in workflow scripts
immrsd Mar 25, 2025
0ac1a01
Turn on test workflow for all contract kinds
immrsd Mar 25, 2025
bd0bbee
Run linter
immrsd Mar 25, 2025
4a60844
Reduce number of info options for ERC721
immrsd Mar 25, 2025
01bfb11
Merge master
immrsd Mar 26, 2025
beb8f27
Merge changes
immrsd Mar 26, 2025
24ee19f
Update tests
immrsd Mar 26, 2025
1b34de9
Support Multisig in CI workflow
immrsd Mar 26, 2025
5f2d688
Remove unused parseKind function
immrsd Mar 26, 2025
4220191
Update wizard-cairo version
immrsd Mar 26, 2025
c2cc0e9
Add Multisig to Cairo-alpha workflow
immrsd Mar 27, 2025
6c5aa4c
Add Multisig to cairo-alpha
immrsd Mar 28, 2025
db87f20
Support multisig in upgradeable
immrsd Mar 28, 2025
c696bf9
Add function for natural number validation
immrsd Mar 28, 2025
e9c1e1a
Add MultisigControls to cairo-alpha UI
immrsd Mar 28, 2025
5e5fada
Merge master
immrsd Mar 30, 2025
0519f56
Update new wizard-cairo version
immrsd Mar 30, 2025
6fc1c9b
Update Cairo readme
immrsd Mar 30, 2025
3af06b4
Update Cairo-alpha Readme and Changelog
immrsd Mar 30, 2025
079806b
Support Multisig for Cairo-alpha
immrsd Mar 31, 2025
94dc744
Add generator logic for Multisig for Cairo-alpha
immrsd Mar 31, 2025
ca0174e
Add Multisig to tests and generators for Cairo-alpha
immrsd Mar 31, 2025
7bc9f05
Add Multisig tab to Cairo-alpha
immrsd Mar 31, 2025
61a6a8a
Add name attribute to Cairo-alpha for Vesting
immrsd Mar 31, 2025
b7e7c09
Update natural number validation
immrsd Mar 31, 2025
220b69f
Add Multisig tests to Cairo-alpha
immrsd Mar 31, 2025
03ce16f
Fix Kind cases order
immrsd Mar 31, 2025
7d022eb
Support parsing Multisig kind in Cairo-alpha script
immrsd Mar 31, 2025
412a7cd
Generate Multisig test snapshots for Cairo-alpha
immrsd Mar 31, 2025
d711c6e
Run linter
immrsd Mar 31, 2025
ff09061
Update OZ version in Multisig snapshots
immrsd Mar 31, 2025
eaee1b5
Update version date in changelog
immrsd Mar 31, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/compile-cairo-alpha-project.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ jobs:
# Exit immediately if a command exits with a non-zero status
set -e

declare -a all_kinds=("ERC20" "ERC721" "ERC1155" "Account" "Vesting" "Governor" "Custom")
declare -a all_kinds=("ERC20" "ERC721" "ERC1155" "Account" "Multisig" "Governor" "Vesting" "Custom")
declare -a all_royalty_info_options=("disabled" "enabled_default" "enabled_custom")
for kind in "${all_kinds[@]}"; do
scarb clean
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/compile-cairo-project.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ jobs:
# Exit immediately if a command exits with a non-zero status
set -e

declare -a all_kinds=("ERC20" "ERC721" "ERC1155" "Account" "Vesting" "Governor" "Custom")
declare -a all_kinds=("ERC20" "ERC721" "ERC1155" "Account" "Multisig" "Governor" "Vesting" "Custom")
declare -a all_royalty_info_options=("disabled" "enabled_default" "enabled_custom")
for kind in "${all_kinds[@]}"; do
scarb clean
Expand Down
4 changes: 4 additions & 0 deletions packages/core/cairo/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changelog

## 1.1.0 (2025-04-01)

- Add Multisig tab. ([#433](https://github.com/OpenZeppelin/contracts-wizard/pull/433))

## 1.0.0 (2025-02-25)

- **Breaking changes**:
Expand Down
7 changes: 7 additions & 0 deletions packages/core/cairo/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ The following contract types are supported:
- `erc1155`
- `account`
- `governor`
- `multisig`
- `vesting`
- `custom`

Expand All @@ -39,6 +40,9 @@ function print(opts?: ERC1155Options): string
function print(opts?: AccountOptions): string
```
```js
function print(opts?: MultisigOptions): string
```
```js
function print(opts?: GovernorOptions): string
```
```js
Expand All @@ -63,6 +67,9 @@ const defaults: Required<ERC1155Options>
const defaults: Required<AccountOptions>
```
```js
const defaults: Required<MultisigOptions>
```
```js
const defaults: Required<GovernorOptions>
```
```js
Expand Down
2 changes: 1 addition & 1 deletion packages/core/cairo/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@openzeppelin/wizard-cairo",
"version": "1.0.0",
"version": "1.1.0",
"description": "A boilerplate generator to get started with OpenZeppelin Contracts for Cairo",
"license": "AGPL-3.0-only",
"repository": "https://github.com/OpenZeppelin/contracts-wizard",
Expand Down
7 changes: 7 additions & 0 deletions packages/core/cairo/src/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import type { AccountOptions } from './account';
import { printAccount, defaults as accountDefaults } from './account';
import type { GovernorOptions } from './governor';
import { printGovernor, defaults as governorDefaults } from './governor';
import type { MultisigOptions } from './multisig';
import { printMultisig, defaults as multisigDefaults } from './multisig';
import type { CustomOptions } from './custom';
import {
printCustom,
Expand Down Expand Up @@ -66,6 +68,7 @@ export type ERC20 = WizardContractAPI<ERC20Options> & AccessControlAPI<ERC20Opti
export type ERC721 = WizardContractAPI<ERC721Options> & AccessControlAPI<ERC721Options>;
export type ERC1155 = WizardContractAPI<ERC1155Options> & AccessControlAPI<ERC1155Options>;
export type Account = WizardAccountAPI<AccountOptions>;
export type Multisig = WizardContractAPI<MultisigOptions>;
export type Governor = WizardContractAPI<GovernorOptions>;
export type Vesting = WizardContractAPI<VestingOptions>;
export type Custom = WizardContractAPI<CustomOptions> & AccessControlAPI<CustomOptions>;
Expand All @@ -89,6 +92,10 @@ export const account: Account = {
print: printAccount,
defaults: accountDefaults,
};
export const multisig: Multisig = {
print: printMultisig,
defaults: multisigDefaults,
};
export const governor: Governor = {
print: printGovernor,
defaults: governorDefaults,
Expand Down
6 changes: 6 additions & 0 deletions packages/core/cairo/src/build-generic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import type { AccountOptions } from './account';
import { buildAccount } from './account';
import type { GovernorOptions } from './governor';
import { buildGovernor } from './governor';
import type { MultisigOptions } from './multisig';
import { buildMultisig } from './multisig';
import type { VestingOptions } from './vesting';
import { buildVesting } from './vesting';

Expand All @@ -18,6 +20,7 @@ export interface KindedOptions {
ERC721: { kind: 'ERC721' } & ERC721Options;
ERC1155: { kind: 'ERC1155' } & ERC1155Options;
Account: { kind: 'Account' } & AccountOptions;
Multisig: { kind: 'Multisig' } & MultisigOptions;
Governor: { kind: 'Governor' } & GovernorOptions;
Vesting: { kind: 'Vesting' } & VestingOptions;
Custom: { kind: 'Custom' } & CustomOptions;
Expand All @@ -39,6 +42,9 @@ export function buildGeneric(opts: GenericOptions) {
case 'Account':
return buildAccount(opts);

case 'Multisig':
return buildMultisig(opts);

case 'Governor':
return buildGovernor(opts);

Expand Down
14 changes: 14 additions & 0 deletions packages/core/cairo/src/generate/multisig.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { infoOptions } from '../set-info';
import type { MultisigOptions } from '../multisig';
import { generateAlternatives } from './alternatives';

const blueprint = {
name: ['MyMultisig'],
quorum: ['1', '2', '42'],
upgradeable: [true, false],
info: infoOptions,
};

export function* generateMultisigOptions(): Generator<Required<MultisigOptions>> {
yield* generateAlternatives(blueprint);
}
19 changes: 14 additions & 5 deletions packages/core/cairo/src/generate/sources.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { generateERC1155Options } from './erc1155';
import { generateAccountOptions } from './account';
import { generateCustomOptions } from './custom';
import { generateGovernorOptions } from './governor';
import { generateMultisigOptions } from './multisig';
import { generateVestingOptions } from './vesting';
import type { GenericOptions, KindedOptions } from '../build-generic';
import { buildGeneric } from '../build-generic';
Expand Down Expand Up @@ -50,9 +51,9 @@ export function* generateOptions(params: {
}
}

if (kind === 'all' || kind === 'Custom') {
for (const kindOpts of generateCustomOptions()) {
yield { kind: 'Custom', ...kindOpts };
if (kind === 'all' || kind === 'Multisig') {
for (const kindOpts of generateMultisigOptions()) {
yield { kind: 'Multisig', ...kindOpts };
}
}

Expand All @@ -67,6 +68,12 @@ export function* generateOptions(params: {
yield { kind: 'Vesting', ...kindOpts };
}
}

if (kind === 'all' || kind === 'Custom') {
for (const kindOpts of generateCustomOptions()) {
yield { kind: 'Custom', ...kindOpts };
}
}
}

interface GeneratedContract {
Expand Down Expand Up @@ -110,10 +117,11 @@ function generateContractSubset(params: {
switch (c.options.kind) {
case 'Vesting':
return isUpgradeable === false;
case 'Account':
case 'ERC20':
case 'ERC721':
case 'ERC1155':
case 'Account':
case 'Multisig':
case 'Governor':
case 'Custom':
return c.options.upgradeable === isUpgradeable;
Expand Down Expand Up @@ -183,8 +191,9 @@ function resolveSourceLabel(params: { kind: KindSubset; royaltyInfo: RoyaltyInfo
return 'All contract kinds';
case 'ERC20':
case 'Account':
case 'Vesting':
case 'Multisig':
case 'Governor':
case 'Vesting':
case 'Custom':
return kind;
default: {
Expand Down
6 changes: 2 additions & 4 deletions packages/core/cairo/src/governor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { setUpgradeableGovernor } from './set-upgradeable';
import { defineComponents } from './utils/define-components';
import { durationToTimestamp } from './utils/duration';
import { addSNIP12Metadata, addSRC5Component } from './common-components';
import { toUint } from './utils/convert-strings';
import { toUint, isNaturalNumber } from './utils/convert-strings';
export const clockModeOptions = ['timestamp'] as const;
export const clockModeDefault = 'timestamp' as const;
export type ClockMode = (typeof clockModeOptions)[number];
Expand Down Expand Up @@ -436,7 +436,7 @@ function addQuorumAndVotes(c: ContractBuilder, allOpts: Required<GovernorOptions

addVotesQuorumFractionComponent(c, allOpts.quorumPercent);
} else if (allOpts.quorumMode === 'absolute') {
if (!numberPattern.test(allOpts.quorumAbsolute)) {
if (!isNaturalNumber(allOpts.quorumAbsolute)) {
throw new OptionsError({
quorumAbsolute: 'Not a valid number',
});
Expand Down Expand Up @@ -534,5 +534,3 @@ function addExecution(c: ContractBuilder, { timelock }: Required<GovernorOptions
c.addComponent(components.GovernorTimelockExecutionComponent, [{ lit: 'timelock_controller' }], true);
}
}

export const numberPattern = /^(?!$)(\d*)(?:\.(\d+))?(?:e(\d+))?$/;
2 changes: 1 addition & 1 deletion packages/core/cairo/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,4 @@ export { sanitizeKind } from './kind';

export { contractsVersion, contractsVersionTag, compatibleContractsSemver } from './utils/version';

export { erc20, erc721, erc1155, account, governor, vesting, custom } from './api';
export { erc20, erc721, erc1155, account, multisig, governor, vesting, custom } from './api';
1 change: 1 addition & 0 deletions packages/core/cairo/src/kind.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ function isKind<T>(value: Kind | T): value is Kind {
case 'ERC721':
case 'ERC1155':
case 'Account':
case 'Multisig':
case 'Governor':
case 'Vesting':
case 'Custom':
Expand Down
120 changes: 120 additions & 0 deletions packages/core/cairo/src/multisig.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
import test from 'ava';
import type { OptionsError } from '.';
import { multisig } from '.';
import type { MultisigOptions } from './multisig';
import { buildMultisig } from './multisig';
import { contractDefaults as commonDefaults } from './common-options';
import { printContract } from './print';

const defaults: MultisigOptions = {
name: 'MyMultisig',
quorum: '2',
upgradeable: commonDefaults.upgradeable,
info: commonDefaults.info,
};

const CUSTOM_NAME = 'CustomMultisig';
const CUSTOM_QUORUM = '42';

//
// Test helpers
//

function testMultisig(title: string, opts: Partial<MultisigOptions>) {
test(title, t => {
const c = buildMultisig({
...defaults,
...opts,
});
t.snapshot(printContract(c));
});
}

function testAPIEquivalence(title: string, opts?: MultisigOptions) {
test(title, t => {
t.is(
multisig.print(opts),
printContract(
buildMultisig({
...defaults,
...opts,
}),
),
);
});
}

//
// Snapshot tests
//

testMultisig('custom name', {
name: CUSTOM_NAME,
});

testMultisig('custom quorum', {
quorum: CUSTOM_QUORUM,
});

testMultisig('all custom settings', {
name: CUSTOM_NAME,
quorum: CUSTOM_QUORUM,
});

testMultisig('upgradeable', {
upgradeable: true,
});

testMultisig('non-upgradeable', {
upgradeable: false,
});

//
// API tests
//

testAPIEquivalence('API custom name', {
...defaults,
name: CUSTOM_NAME,
});

testAPIEquivalence('API custom quorum', {
...defaults,
quorum: CUSTOM_QUORUM,
});

testAPIEquivalence('API all custom settings', {
...defaults,
name: CUSTOM_NAME,
quorum: CUSTOM_QUORUM,
});

testAPIEquivalence('API upgradeable', {
...defaults,
upgradeable: true,
});

testAPIEquivalence('API non-upgradeable', {
...defaults,
upgradeable: false,
});

test('quorum is 0', async t => {
const error = t.throws(() =>
buildMultisig({
...defaults,
quorum: '0',
}),
);
t.is((error as OptionsError).messages.quorum, 'Quorum cannot be 0');
});

test('negative quorum', async t => {
const error = t.throws(() =>
buildMultisig({
...defaults,
quorum: '-1',
}),
);
t.is((error as OptionsError).messages.quorum, 'Not a valid number');
});
Loading
Loading