Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
5 changes: 5 additions & 0 deletions .changeset/cairo-alpha-erc1155-supply.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@openzeppelin/wizard-common": patch
---

Cairo: ERC1155 supply tracking description for AI prompts.
1 change: 1 addition & 0 deletions packages/common/src/ai/descriptions/cairo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ export const cairoERC1155Descriptions = {
baseUri:
'The location of the metadata for the token. Clients will replace any instance of {id} in this string with the tokenId.',
updatableUri: 'Whether privileged accounts will be able to set a new URI for all token types.',
supply: 'Whether to keep track of total supply of tokens.',
};

export const cairoGovernorDescriptions = {
Expand Down
7 changes: 7 additions & 0 deletions packages/core/cairo_alpha/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# Changelog

## 3.1.0 (Unreleased)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This says 3.1.0 but packages/core/cairo_alpha/package.json says 4.0.0-alpha.0 (the same occurs in the other PRs)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, I updated because I remembered you mentioned at some point that wizard releases and the version of the contracts library were not pegged, and also the rest of this file follow the format of not using alphas. We still need alpha in the package.json version because that is used in the alpha switch in the UI, right?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, the versions don't need to be pegged, but using Contracts for Cairo v4 is a breaking change.

We can just leave this line as

Suggested change
## 3.1.0 (Unreleased)
## Unreleased

More detailed explanation (we should document this process):

The alpha switch label uses contractsVersionTag from packages/core/cairo_alpha/src/utils/version.ts.

All packages use changesets, except for cairo_alpha (which is excluded from the NPM release process, so we manually keep track of changes in its CHANGELOG.md. Those entries need to be manually moved into a changeset when we eventually promote it from alpha to stable for release).

When we merge/promote alpha to stable, we'll need to do the following in the resulting PR:

  1. Move the contents of ## Unreleased section to a changeset (new .md file under .changeset), targeting a major version bump of @openzeppelin/wizard-cairo
  2. Ensure the version of packages/core/cairo/package.json is NOT bumped manually (e.g. it must remain 3.x when we want to release 4.0.0)
  3. The version packages workflow (prior to release) will: consume the changeset, move it to packages/core/cairo/CHANGELOG.md, and update the version in packages/core/cairo/package.json


- Add ERC1155 supply tracking extension ([#765](https://github.com/OpenZeppelin/contracts-wizard/pull/765))

- **Breaking changes**:
- Use OpenZeppelin Contracts for Cairo v4.0.0-alpha.0.

## 3.0.0 (2026-01-10)

- Add support for `with_components` macro. ([#703](https://github.com/OpenZeppelin/contracts-wizard/pull/703))
Expand Down
1 change: 1 addition & 0 deletions packages/core/cairo_alpha/ava.config.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
module.exports = {
extensions: ['ts'],
require: ['ts-node/register'],
files: ['src/**/*.test.ts'],
watchmode: {
ignoreChanges: ['contracts', 'artifacts', 'cache'],
},
Expand Down
2 changes: 1 addition & 1 deletion packages/core/cairo_alpha/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@openzeppelin/wizard-cairo-alpha",
"private": true,
"version": "3.0.0",
"version": "4.0.0-alpha.0",
"description": "A boilerplate generator to get started with the latest alpha version of OpenZeppelin Contracts for Cairo",
"license": "AGPL-3.0-only",
"repository": "https://github.com/OpenZeppelin/contracts-wizard",
Expand Down
87 changes: 72 additions & 15 deletions packages/core/cairo_alpha/src/erc1155.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ export const defaults: Required<ERC1155Options> = {
burnable: false,
pausable: false,
mintable: false,
supply: false,
updatableUri: true,
royaltyInfo: royaltyInfoDefaults,
access: commonDefaults.access,
Expand All @@ -41,6 +42,7 @@ export interface ERC1155Options extends CommonContractOptions {
burnable?: boolean;
pausable?: boolean;
mintable?: boolean;
supply?: boolean;
updatableUri?: boolean;
royaltyInfo?: RoyaltyInfoOptions;
}
Expand All @@ -52,6 +54,7 @@ function withDefaults(opts: ERC1155Options): Required<ERC1155Options> {
burnable: opts.burnable ?? defaults.burnable,
pausable: opts.pausable ?? defaults.pausable,
mintable: opts.mintable ?? defaults.mintable,
supply: opts.supply ?? defaults.supply,
updatableUri: opts.updatableUri ?? defaults.updatableUri,
royaltyInfo: opts.royaltyInfo ?? defaults.royaltyInfo,
};
Expand Down Expand Up @@ -86,6 +89,10 @@ export function buildERC1155(opts: ERC1155Options): Contract {
addMintable(c, allOpts.access);
}

if (allOpts.supply) {
addSupply(c);
}

if (allOpts.updatableUri) {
addSetBaseUri(c, allOpts.access);
}
Expand All @@ -101,7 +108,7 @@ export function buildERC1155(opts: ERC1155Options): Contract {
}

function addHooks(c: ContractBuilder, allOpts: Required<ERC1155Options>) {
const usesCustomHooks = allOpts.pausable;
const usesCustomHooks = allOpts.pausable || allOpts.supply;
if (usesCustomHooks) {
const hooksTrait = {
name: 'ERC1155HooksImpl',
Expand All @@ -112,20 +119,43 @@ function addHooks(c: ContractBuilder, allOpts: Required<ERC1155Options>) {
c.addImplementedTrait(hooksTrait);
c.addUseClause('starknet', 'ContractAddress');

c.addFunction(hooksTrait, {
name: 'before_update',
args: [
{
name: 'ref self',
type: `ERC1155Component::ComponentState<ContractState>`,
},
{ name: 'from', type: 'ContractAddress' },
{ name: 'to', type: 'ContractAddress' },
{ name: 'token_ids', type: 'Span<u256>' },
{ name: 'values', type: 'Span<u256>' },
],
code: ['let contract_state = self.get_contract()', 'contract_state.pausable.assert_not_paused()'],
});
if (allOpts.pausable) {
c.addFunction(hooksTrait, {
name: 'before_update',
args: [
{
name: 'ref self',
type: `ERC1155Component::ComponentState<ContractState>`,
},
{ name: 'from', type: 'ContractAddress' },
{ name: 'to', type: 'ContractAddress' },
{ name: 'token_ids', type: 'Span<u256>' },
{ name: 'values', type: 'Span<u256>' },
],
code: ['let contract_state = self.get_contract()', 'contract_state.pausable.assert_not_paused()'],
});
}

if (allOpts.supply) {
const afterUpdateFn = c.addFunction(hooksTrait, {
name: 'after_update',
args: [
{
name: 'ref self',
type: `ERC1155Component::ComponentState<ContractState>`,
},
{ name: 'from', type: 'ContractAddress' },
{ name: 'to', type: 'ContractAddress' },
{ name: 'token_ids', type: 'Span<u256>' },
{ name: 'values', type: 'Span<u256>' },
],
code: [],
});
afterUpdateFn.code.push(
'let mut contract_state = self.get_contract_mut();',
'contract_state.erc1155_supply.after_update(from, to, token_ids, values);',
);
}
} else {
c.addUseClause('openzeppelin_token::erc1155', 'ERC1155HooksEmptyImpl');
}
Expand Down Expand Up @@ -153,6 +183,10 @@ function addBurnable(c: ContractBuilder) {
c.addFunction(externalTrait, functions.batchBurn);
}

function addSupply(c: ContractBuilder) {
c.addComponent(components.ERC1155SupplyComponent, [], true);
}

function addMintable(c: ContractBuilder, access: Access) {
c.addUseClause('starknet', 'ContractAddress');
requireAccessControl(c, externalTrait, functions.mint, access, 'MINTER', 'minter');
Expand Down Expand Up @@ -188,6 +222,29 @@ const components = defineComponents({
},
],
},
ERC1155SupplyComponent: {
path: 'openzeppelin_token::erc1155::extensions',
substorage: {
name: 'erc1155_supply',
type: 'ERC1155SupplyComponent::Storage',
},
event: {
name: 'ERC1155SupplyEvent',
type: 'ERC1155SupplyComponent::Event',
},
impls: [
{
name: 'ERC1155SupplyImpl',
embed: true,
value: 'ERC1155SupplyComponent::ERC1155SupplyImpl<ContractState>',
},
{
name: 'ERC1155SupplyInternalImpl',
embed: false,
value: 'ERC1155SupplyComponent::InternalImpl<ContractState>',
},
],
},
});

const functions = defineFunctions({
Expand Down
1 change: 1 addition & 0 deletions packages/core/cairo_alpha/src/generate/erc1155.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ function prepareBlueprint(opts: GeneratorOptions) {
burnable: booleans,
pausable: booleans,
mintable: booleans,
supply: booleans,
updatableUri: booleans,
upgradeable: upgradeableOptions,
royaltyInfo: resolveRoyaltyOptionsSubset(opts.royaltyInfo),
Expand Down
Loading
Loading