Skip to content

Commit 705924a

Browse files
authored
Cairo: Use mixins (#348)
1 parent a594e07 commit 705924a

13 files changed

+97
-184
lines changed

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+
## 0.10.1 (2024-03-27)
4+
5+
- Use mixins. ([#348](https://github.com/OpenZeppelin/contracts-wizard/pull/348))
6+
37
## 0.10.0 (2024-03-12)
48

59
- **Breaking changes**:

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": "0.10.0",
3+
"version": "0.10.1",
44
"description": "A boilerplate generator to get started with OpenZeppelin Contracts for Cairo",
55
"license": "MIT",
66
"repository": "github:OpenZeppelin/contracts-wizard",

packages/core-cairo/src/common-components.ts

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,18 @@ const components = defineComponents( {
1212
name: 'SRC5Event',
1313
type: 'SRC5Component::Event',
1414
},
15-
impls: [
16-
{
17-
name: 'SRC5Impl',
18-
value: 'SRC5Component::SRC5Impl<ContractState>',
19-
},
20-
],
15+
impls: [],
2116
},
2217
})
2318

2419
export function addSRC5Component(c: ContractBuilder) {
2520
c.addComponent(components.SRC5Component, [], false);
21+
22+
if (!c.interfaceFlags.has('ISRC5')) {
23+
c.addImplToComponent(components.SRC5Component, {
24+
name: 'SRC5Impl',
25+
value: 'SRC5Component::SRC5Impl<ContractState>',
26+
});
27+
c.addInterfaceFlag('ISRC5');
28+
}
2629
}

packages/core-cairo/src/contract.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ export class ContractBuilder implements Contract {
8989
private implementedTraitsMap: Map<string, ImplementedTrait> = new Map<string, ImplementedTrait>();
9090
private superVariablesMap: Map<string, Variable> = new Map<string, Variable>();
9191
private standaloneImportsSet: Set<string> = new Set();
92+
private interfaceFlagsSet: Set<string> = new Set();
9293

9394
constructor(name: string) {
9495
this.name = toIdentifier(name, true);
@@ -110,6 +111,13 @@ export class ContractBuilder implements Contract {
110111
return [...this.standaloneImportsSet];
111112
}
112113

114+
/**
115+
* Custom flags to denote that the contract implements a specific interface, e.g. ISRC5, to avoid duplicates
116+
**/
117+
get interfaceFlags(): Set<string> {
118+
return this.interfaceFlagsSet;
119+
}
120+
113121
addStandaloneImport(fullyQualified: string) {
114122
this.standaloneImportsSet.add(fullyQualified);
115123
}
@@ -208,4 +216,8 @@ export class ContractBuilder implements Contract {
208216
addConstructorCode(code: string) {
209217
this.constructorCode.push(code);
210218
}
219+
220+
addInterfaceFlag(flag: string) {
221+
this.interfaceFlagsSet.add(flag);
222+
}
211223
}

packages/core-cairo/src/custom.test.ts.md

Lines changed: 5 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,7 @@ Generated by [AVA](https://avajs.dev).
3838
#[abi(embed_v0)]␊
3939
impl PausableImpl = PausableComponent::PausableImpl<ContractState>;␊
4040
#[abi(embed_v0)]␊
41-
impl OwnableImpl = OwnableComponent::OwnableImpl<ContractState>;␊
42-
#[abi(embed_v0)]␊
43-
impl OwnableCamelOnlyImpl = OwnableComponent::OwnableCamelOnlyImpl<ContractState>;␊
41+
impl OwnableMixinImpl = OwnableComponent::OwnableMixinImpl<ContractState>;␊
4442
4543
impl PausableInternalImpl = PausableComponent::InternalImpl<ContractState>;␊
4644
impl OwnableInternalImpl = OwnableComponent::InternalImpl<ContractState>;␊
@@ -104,9 +102,7 @@ Generated by [AVA](https://avajs.dev).
104102
component!(path: OwnableComponent, storage: ownable, event: OwnableEvent);␊
105103
106104
#[abi(embed_v0)]␊
107-
impl OwnableImpl = OwnableComponent::OwnableImpl<ContractState>;␊
108-
#[abi(embed_v0)]␊
109-
impl OwnableCamelOnlyImpl = OwnableComponent::OwnableCamelOnlyImpl<ContractState>;␊
105+
impl OwnableMixinImpl = OwnableComponent::OwnableMixinImpl<ContractState>;␊
110106
111107
impl UpgradeableInternalImpl = UpgradeableComponent::InternalImpl<ContractState>;␊
112108
impl OwnableInternalImpl = OwnableComponent::InternalImpl<ContractState>;␊
@@ -173,9 +169,7 @@ Generated by [AVA](https://avajs.dev).
173169
component!(path: OwnableComponent, storage: ownable, event: OwnableEvent);␊
174170
175171
#[abi(embed_v0)]␊
176-
impl OwnableImpl = OwnableComponent::OwnableImpl<ContractState>;␊
177-
#[abi(embed_v0)]␊
178-
impl OwnableCamelOnlyImpl = OwnableComponent::OwnableCamelOnlyImpl<ContractState>;␊
172+
impl OwnableMixinImpl = OwnableComponent::OwnableMixinImpl<ContractState>;␊
179173
180174
impl OwnableInternalImpl = OwnableComponent::InternalImpl<ContractState>;␊
181175
@@ -217,11 +211,7 @@ Generated by [AVA](https://avajs.dev).
217211
component!(path: SRC5Component, storage: src5, event: SRC5Event);␊
218212
219213
#[abi(embed_v0)]␊
220-
impl AccessControlImpl = AccessControlComponent::AccessControlImpl<ContractState>;␊
221-
#[abi(embed_v0)]␊
222-
impl AccessControlCamelImpl = AccessControlComponent::AccessControlCamelImpl<ContractState>;␊
223-
#[abi(embed_v0)]␊
224-
impl SRC5Impl = SRC5Component::SRC5Impl<ContractState>;␊
214+
impl AccessControlMixinImpl = AccessControlComponent::AccessControlMixinImpl<ContractState>;␊
225215
226216
impl AccessControlInternalImpl = AccessControlComponent::InternalImpl<ContractState>;␊
227217
@@ -270,9 +260,7 @@ Generated by [AVA](https://avajs.dev).
270260
#[abi(embed_v0)]␊
271261
impl PausableImpl = PausableComponent::PausableImpl<ContractState>;␊
272262
#[abi(embed_v0)]␊
273-
impl OwnableImpl = OwnableComponent::OwnableImpl<ContractState>;␊
274-
#[abi(embed_v0)]␊
275-
impl OwnableCamelOnlyImpl = OwnableComponent::OwnableCamelOnlyImpl<ContractState>;␊
263+
impl OwnableMixinImpl = OwnableComponent::OwnableMixinImpl<ContractState>;␊
276264
277265
impl PausableInternalImpl = PausableComponent::InternalImpl<ContractState>;␊
278266
impl OwnableInternalImpl = OwnableComponent::InternalImpl<ContractState>;␊
-47 Bytes
Binary file not shown.

packages/core-cairo/src/erc20.test.ts.md

Lines changed: 13 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,7 @@ Generated by [AVA](https://avajs.dev).
1818
component!(path: ERC20Component, storage: erc20, event: ERC20Event);␊
1919
2020
#[abi(embed_v0)]␊
21-
impl ERC20MetadataImpl = ERC20Component::ERC20MetadataImpl<ContractState>;␊
22-
#[abi(embed_v0)]␊
23-
impl ERC20Impl = ERC20Component::ERC20Impl<ContractState>;␊
24-
#[abi(embed_v0)]␊
25-
impl ERC20CamelOnlyImpl = ERC20Component::ERC20CamelOnlyImpl<ContractState>;␊
21+
impl ERC20MixinImpl = ERC20Component::ERC20ABI<ContractState>;␊
2622
2723
impl ERC20InternalImpl = ERC20Component::InternalImpl<ContractState>;␊
2824
@@ -61,11 +57,7 @@ Generated by [AVA](https://avajs.dev).
6157
component!(path: ERC20Component, storage: erc20, event: ERC20Event);␊
6258
6359
#[abi(embed_v0)]␊
64-
impl ERC20MetadataImpl = ERC20Component::ERC20MetadataImpl<ContractState>;␊
65-
#[abi(embed_v0)]␊
66-
impl ERC20Impl = ERC20Component::ERC20Impl<ContractState>;␊
67-
#[abi(embed_v0)]␊
68-
impl ERC20CamelOnlyImpl = ERC20Component::ERC20CamelOnlyImpl<ContractState>;␊
60+
impl ERC20MixinImpl = ERC20Component::ERC20ABI<ContractState>;␊
6961
7062
impl ERC20InternalImpl = ERC20Component::InternalImpl<ContractState>;␊
7163
@@ -123,9 +115,7 @@ Generated by [AVA](https://avajs.dev).
123115
#[abi(embed_v0)]␊
124116
impl PausableImpl = PausableComponent::PausableImpl<ContractState>;␊
125117
#[abi(embed_v0)]␊
126-
impl OwnableImpl = OwnableComponent::OwnableImpl<ContractState>;␊
127-
#[abi(embed_v0)]␊
128-
impl OwnableCamelOnlyImpl = OwnableComponent::OwnableCamelOnlyImpl<ContractState>;␊
118+
impl OwnableMixinImpl = OwnableComponent::OwnableMixinImpl<ContractState>;␊
129119
130120
impl ERC20InternalImpl = ERC20Component::InternalImpl<ContractState>;␊
131121
impl PausableInternalImpl = PausableComponent::InternalImpl<ContractState>;␊
@@ -262,11 +252,7 @@ Generated by [AVA](https://avajs.dev).
262252
#[abi(embed_v0)]␊
263253
impl PausableImpl = PausableComponent::PausableImpl<ContractState>;␊
264254
#[abi(embed_v0)]␊
265-
impl AccessControlImpl = AccessControlComponent::AccessControlImpl<ContractState>;␊
266-
#[abi(embed_v0)]␊
267-
impl AccessControlCamelImpl = AccessControlComponent::AccessControlCamelImpl<ContractState>;␊
268-
#[abi(embed_v0)]␊
269-
impl SRC5Impl = SRC5Component::SRC5Impl<ContractState>;␊
255+
impl AccessControlMixinImpl = AccessControlComponent::AccessControlMixinImpl<ContractState>;␊
270256
271257
impl ERC20InternalImpl = ERC20Component::InternalImpl<ContractState>;␊
272258
impl PausableInternalImpl = PausableComponent::InternalImpl<ContractState>;␊
@@ -405,9 +391,7 @@ Generated by [AVA](https://avajs.dev).
405391
#[abi(embed_v0)]␊
406392
impl PausableImpl = PausableComponent::PausableImpl<ContractState>;␊
407393
#[abi(embed_v0)]␊
408-
impl OwnableImpl = OwnableComponent::OwnableImpl<ContractState>;␊
409-
#[abi(embed_v0)]␊
410-
impl OwnableCamelOnlyImpl = OwnableComponent::OwnableCamelOnlyImpl<ContractState>;␊
394+
impl OwnableMixinImpl = OwnableComponent::OwnableMixinImpl<ContractState>;␊
411395
412396
impl ERC20InternalImpl = ERC20Component::InternalImpl<ContractState>;␊
413397
impl PausableInternalImpl = PausableComponent::InternalImpl<ContractState>;␊
@@ -536,11 +520,7 @@ Generated by [AVA](https://avajs.dev).
536520
component!(path: ERC20Component, storage: erc20, event: ERC20Event);␊
537521
538522
#[abi(embed_v0)]␊
539-
impl ERC20MetadataImpl = ERC20Component::ERC20MetadataImpl<ContractState>;␊
540-
#[abi(embed_v0)]␊
541-
impl ERC20Impl = ERC20Component::ERC20Impl<ContractState>;␊
542-
#[abi(embed_v0)]␊
543-
impl ERC20CamelOnlyImpl = ERC20Component::ERC20CamelOnlyImpl<ContractState>;␊
523+
impl ERC20MixinImpl = ERC20Component::ERC20ABI<ContractState>;␊
544524
545525
impl ERC20InternalImpl = ERC20Component::InternalImpl<ContractState>;␊
546526
@@ -580,11 +560,7 @@ Generated by [AVA](https://avajs.dev).
580560
component!(path: ERC20Component, storage: erc20, event: ERC20Event);␊
581561
582562
#[abi(embed_v0)]␊
583-
impl ERC20MetadataImpl = ERC20Component::ERC20MetadataImpl<ContractState>;␊
584-
#[abi(embed_v0)]␊
585-
impl ERC20Impl = ERC20Component::ERC20Impl<ContractState>;␊
586-
#[abi(embed_v0)]␊
587-
impl ERC20CamelOnlyImpl = ERC20Component::ERC20CamelOnlyImpl<ContractState>;␊
563+
impl ERC20MixinImpl = ERC20Component::ERC20ABI<ContractState>;␊
588564
589565
impl ERC20InternalImpl = ERC20Component::InternalImpl<ContractState>;␊
590566
@@ -625,15 +601,9 @@ Generated by [AVA](https://avajs.dev).
625601
component!(path: OwnableComponent, storage: ownable, event: OwnableEvent);␊
626602
627603
#[abi(embed_v0)]␊
628-
impl ERC20MetadataImpl = ERC20Component::ERC20MetadataImpl<ContractState>;␊
629-
#[abi(embed_v0)]␊
630-
impl ERC20Impl = ERC20Component::ERC20Impl<ContractState>;␊
604+
impl ERC20MixinImpl = ERC20Component::ERC20ABI<ContractState>;␊
631605
#[abi(embed_v0)]␊
632-
impl ERC20CamelOnlyImpl = ERC20Component::ERC20CamelOnlyImpl<ContractState>;␊
633-
#[abi(embed_v0)]␊
634-
impl OwnableImpl = OwnableComponent::OwnableImpl<ContractState>;␊
635-
#[abi(embed_v0)]␊
636-
impl OwnableCamelOnlyImpl = OwnableComponent::OwnableCamelOnlyImpl<ContractState>;␊
606+
impl OwnableMixinImpl = OwnableComponent::OwnableMixinImpl<ContractState>;␊
637607
638608
impl ERC20InternalImpl = ERC20Component::InternalImpl<ContractState>;␊
639609
impl OwnableInternalImpl = OwnableComponent::InternalImpl<ContractState>;␊
@@ -696,17 +666,9 @@ Generated by [AVA](https://avajs.dev).
696666
component!(path: SRC5Component, storage: src5, event: SRC5Event);␊
697667
698668
#[abi(embed_v0)]␊
699-
impl ERC20MetadataImpl = ERC20Component::ERC20MetadataImpl<ContractState>;␊
700-
#[abi(embed_v0)]␊
701-
impl ERC20Impl = ERC20Component::ERC20Impl<ContractState>;␊
702-
#[abi(embed_v0)]␊
703-
impl ERC20CamelOnlyImpl = ERC20Component::ERC20CamelOnlyImpl<ContractState>;␊
704-
#[abi(embed_v0)]␊
705-
impl AccessControlImpl = AccessControlComponent::AccessControlImpl<ContractState>;␊
706-
#[abi(embed_v0)]␊
707-
impl AccessControlCamelImpl = AccessControlComponent::AccessControlCamelImpl<ContractState>;␊
669+
impl ERC20MixinImpl = ERC20Component::ERC20ABI<ContractState>;␊
708670
#[abi(embed_v0)]␊
709-
impl SRC5Impl = SRC5Component::SRC5Impl<ContractState>;␊
671+
impl AccessControlMixinImpl = AccessControlComponent::AccessControlMixinImpl<ContractState>;␊
710672
711673
impl ERC20InternalImpl = ERC20Component::InternalImpl<ContractState>;␊
712674
impl AccessControlInternalImpl = AccessControlComponent::InternalImpl<ContractState>;␊
@@ -782,9 +744,7 @@ Generated by [AVA](https://avajs.dev).
782744
#[abi(embed_v0)]␊
783745
impl PausableImpl = PausableComponent::PausableImpl<ContractState>;␊
784746
#[abi(embed_v0)]␊
785-
impl OwnableImpl = OwnableComponent::OwnableImpl<ContractState>;␊
786-
#[abi(embed_v0)]␊
787-
impl OwnableCamelOnlyImpl = OwnableComponent::OwnableCamelOnlyImpl<ContractState>;␊
747+
impl OwnableMixinImpl = OwnableComponent::OwnableMixinImpl<ContractState>;␊
788748
789749
impl ERC20InternalImpl = ERC20Component::InternalImpl<ContractState>;␊
790750
impl PausableInternalImpl = PausableComponent::InternalImpl<ContractState>;␊
@@ -957,11 +917,7 @@ Generated by [AVA](https://avajs.dev).
957917
#[abi(embed_v0)]␊
958918
impl PausableImpl = PausableComponent::PausableImpl<ContractState>;␊
959919
#[abi(embed_v0)]␊
960-
impl AccessControlImpl = AccessControlComponent::AccessControlImpl<ContractState>;␊
961-
#[abi(embed_v0)]␊
962-
impl AccessControlCamelImpl = AccessControlComponent::AccessControlCamelImpl<ContractState>;␊
963-
#[abi(embed_v0)]␊
964-
impl SRC5Impl = SRC5Component::SRC5Impl<ContractState>;␊
920+
impl AccessControlMixinImpl = AccessControlComponent::AccessControlMixinImpl<ContractState>;␊
965921
966922
impl ERC20InternalImpl = ERC20Component::InternalImpl<ContractState>;␊
967923
impl PausableInternalImpl = PausableComponent::InternalImpl<ContractState>;␊
-42 Bytes
Binary file not shown.

packages/core-cairo/src/erc20.ts

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ export function buildERC20(opts: ERC20Options): Contract {
5858
const allOpts = withDefaults(opts);
5959

6060
addBase(c, toStringLiteral(allOpts.name), toStringLiteral(allOpts.symbol));
61-
addERC20ImplAndCamelOnlyImpl(c, allOpts.pausable);
61+
addERC20MixinOrImpls(c, allOpts.pausable);
6262

6363
if (allOpts.premint) {
6464
addPremint(c, allOpts.premint);
@@ -93,10 +93,15 @@ function addERC20Interface(c: ContractBuilder) {
9393
c.addStandaloneImport('openzeppelin::token::erc20::interface');
9494
}
9595

96-
function addERC20ImplAndCamelOnlyImpl(c: ContractBuilder, pausable: boolean) {
96+
function addERC20MixinOrImpls(c: ContractBuilder, pausable: boolean) {
9797
if (pausable) {
9898
addERC20Interface(c);
9999

100+
c.addImplToComponent(components.ERC20Component, {
101+
name: 'ERC20MetadataImpl',
102+
value: 'ERC20Component::ERC20MetadataImpl<ContractState>',
103+
});
104+
100105
const ERC20Impl: BaseImplementedTrait = {
101106
name: 'ERC20Impl',
102107
of: 'interface::IERC20<ContractState>',
@@ -123,12 +128,8 @@ function addERC20ImplAndCamelOnlyImpl(c: ContractBuilder, pausable: boolean) {
123128
setPausable(c, ERC20CamelOnlyImpl, functions.transferFrom);
124129
} else {
125130
c.addImplToComponent(components.ERC20Component, {
126-
name: 'ERC20Impl',
127-
value: 'ERC20Component::ERC20Impl<ContractState>',
128-
});
129-
c.addImplToComponent(components.ERC20Component, {
130-
name: 'ERC20CamelOnlyImpl',
131-
value: 'ERC20Component::ERC20CamelOnlyImpl<ContractState>',
131+
name: 'ERC20MixinImpl',
132+
value: 'ERC20Component::ERC20ABI<ContractState>',
132133
});
133134
}
134135
}
@@ -223,12 +224,7 @@ const components = defineComponents( {
223224
name: 'ERC20Event',
224225
type: 'ERC20Component::Event',
225226
},
226-
impls: [
227-
{
228-
name: 'ERC20MetadataImpl',
229-
value: 'ERC20Component::ERC20MetadataImpl<ContractState>',
230-
},
231-
],
227+
impls: [],
232228
internalImpl: {
233229
name: 'ERC20InternalImpl',
234230
value: 'ERC20Component::InternalImpl<ContractState>',

0 commit comments

Comments
 (0)