diff --git a/README.md b/README.md
index f2c2a843f..c3257711c 100644
--- a/README.md
+++ b/README.md
@@ -6,7 +6,9 @@ Contracts Wizard is a web application to interactively build a contract out of c
## Development
-`packages/core` contains the code generation logic.
+`packages/core` contains the code generation logic for Solidity.
+
+`packages/core-cairo` contains the code generation logic for Cairo.
`packages/ui` is the interface built in Svelte. `yarn dev` spins up a local server to develop the UI.
@@ -22,4 +24,8 @@ Then place `` in the body where you want Contracts Wizard
Optionally focus on specific tab with the `data-tab` attribute as in ``.
-For Cairo, use the `data-lang` attribute: ``.
\ No newline at end of file
+For Cairo, use the `data-lang` attribute: ``.
+
+## API
+
+See [API documentation](docs/API.md) for provided APIs.
\ No newline at end of file
diff --git a/docs/API.md b/docs/API.md
new file mode 100644
index 000000000..45a3dccf6
--- /dev/null
+++ b/docs/API.md
@@ -0,0 +1,41 @@
+# API
+
+The following describes how to use the Contracts Wizard programmatic API in your own applications.
+
+## Cairo
+
+### Installation
+
+`npm install @openzeppelin/wizard-cairo`
+
+### Functions
+
+#### `printERC20`
+```js
+function printERC20(opts?: ERC20Options): string
+```
+Returns a string representation of an ERC20 contract generated using the provided options. If `opts` is not provided, uses [`erc20defaults`](#erc20defaults).
+
+#### `printERC721`
+```js
+function printERC721(opts?: ERC721Options): string
+```
+Returns a string representation of an ERC721 contract generated using the provided options. If `opts` is not provided, uses [`erc721defaults`](#erc721defaults).
+
+### Defaults
+
+#### `erc20defaults`
+```js
+const erc20defaults: Required
+```
+The default options that are used for [`printERC20`](#printerc20).
+
+#### `erc721defaults`
+```js
+const erc721defaults: Required
+```
+The default options that are used for [`printERC721`](#printerc721).
+
+## Solidity
+
+Contracts Wizard API for Solidity is not available yet. Please reach out to us on [issue #129](https://github.com/OpenZeppelin/contracts-wizard/issues/129) if you would be interested in it.
diff --git a/packages/core-cairo/CHANGELOG.md b/packages/core-cairo/CHANGELOG.md
new file mode 100644
index 000000000..a0c40d8b8
--- /dev/null
+++ b/packages/core-cairo/CHANGELOG.md
@@ -0,0 +1,5 @@
+# Changelog
+
+## Unreleased
+
+- Initial API for Cairo. ([#127](https://github.com/OpenZeppelin/contracts-wizard/pull/127))
diff --git a/packages/core-cairo/package.json b/packages/core-cairo/package.json
index dc3200880..753ebb947 100644
--- a/packages/core-cairo/package.json
+++ b/packages/core-cairo/package.json
@@ -1,9 +1,9 @@
{
- "name": "core-cairo",
- "version": "0.0.1",
+ "name": "@openzeppelin/wizard-cairo",
+ "version": "0.1.0",
"description": "A boilerplate generator to get started with OpenZeppelin Contracts for Cairo",
"license": "MIT",
- "repository": "github:OpenZeppelin/wizard",
+ "repository": "github:OpenZeppelin/contracts-wizard",
"main": "dist/index.js",
"ts:main": "src/index.ts",
"files": [
diff --git a/packages/core-cairo/src/common-options.ts b/packages/core-cairo/src/common-options.ts
index 5cca69d08..f46a76196 100644
--- a/packages/core-cairo/src/common-options.ts
+++ b/packages/core-cairo/src/common-options.ts
@@ -1,8 +1,15 @@
import type { Argument } from "./contract";
import type { Access } from "./set-access-control";
import type { Info } from "./set-info";
+import { defaults as infoDefaults } from "./set-info";
import type { Upgradeable } from "./set-upgradeable";
+export const defaults: Required = {
+ access: 'ownable',
+ upgradeable: false,
+ info: infoDefaults,
+} as const;
+
export interface CommonOptions {
access?: Access;
upgradeable?: Upgradeable;
@@ -11,9 +18,9 @@ export interface CommonOptions {
export function withCommonDefaults(opts: CommonOptions): Required {
return {
- access: opts.access ?? 'ownable',
- upgradeable: opts.upgradeable ?? false,
- info: opts.info ?? {},
+ access: opts.access ?? defaults.access,
+ upgradeable: opts.upgradeable ?? defaults.upgradeable,
+ info: opts.info ?? defaults.info,
};
}
diff --git a/packages/core-cairo/src/erc20.test.ts b/packages/core-cairo/src/erc20.test.ts
index c91c1fd8d..17425ea68 100644
--- a/packages/core-cairo/src/erc20.test.ts
+++ b/packages/core-cairo/src/erc20.test.ts
@@ -3,6 +3,8 @@ import test from 'ava';
import { buildERC20, ERC20Options } from './erc20';
import { printContract } from './print';
+import { printERC20, erc20defaults } from '.';
+
function testERC20(title: string, opts: Partial) {
test(title, t => {
const c = buildERC20({
@@ -14,6 +16,12 @@ function testERC20(title: string, opts: Partial) {
});
}
+function testERC20API(title: string, opts?: ERC20Options) {
+ test(title, t => {
+ t.snapshot(printERC20(opts));
+ });
+}
+
testERC20('basic erc20', {});
testERC20('erc20 burnable', {
@@ -43,18 +51,30 @@ testERC20('erc20 mintable', {
access: 'ownable',
});
-testERC20('erc20 full upgradeable transparent', {
+testERC20('erc20 full upgradeable', {
premint: '2000',
+ decimals: '9',
burnable: true,
mintable: true,
pausable: true,
upgradeable: true,
});
-testERC20('erc20 full upgradeable uups', {
+testERC20API('erc20 API default');
+
+testERC20API('erc20 API basic', { name: 'CustomToken', symbol: 'CTK' });
+
+testERC20API('erc20 API full upgradeable', {
+ name: 'CustomToken',
+ symbol: 'CTK',
premint: '2000',
+ decimals: '9',
burnable: true,
mintable: true,
pausable: true,
upgradeable: true,
});
+
+test('erc20 API assert defaults', async t => {
+ t.is(printERC20(erc20defaults), printERC20());
+});
\ No newline at end of file
diff --git a/packages/core-cairo/src/erc20.test.ts.md b/packages/core-cairo/src/erc20.test.ts.md
index efd6bb036..635de8e4b 100644
--- a/packages/core-cairo/src/erc20.test.ts.md
+++ b/packages/core-cairo/src/erc20.test.ts.md
@@ -1239,7 +1239,7 @@ Generated by [AVA](https://avajs.dev).
end␊
`
-## erc20 full upgradeable transparent
+## erc20 full upgradeable
> Snapshot 1
@@ -1290,11 +1290,11 @@ Generated by [AVA](https://avajs.dev).
pedersen_ptr: HashBuiltin*,␊
range_check_ptr␊
}(owner: felt, recipient: felt, proxy_admin: felt):␊
- ERC20_initializer('MyToken', 'MTK', 18)␊
+ ERC20_initializer('MyToken', 'MTK', 9)␊
Ownable_initializer(owner)␊
Proxy_initializer(proxy_admin)␊
␊
- ERC20_mint(recipient, Uint256(2000000000000000000000, 0))␊
+ ERC20_mint(recipient, Uint256(2000000000000, 0))␊
return ()␊
end␊
␊
@@ -1488,7 +1488,319 @@ Generated by [AVA](https://avajs.dev).
end␊
`
-## erc20 full upgradeable uups
+## erc20 API default
+
+> Snapshot 1
+
+ `# SPDX-License-Identifier: MIT␊
+ ␊
+ %lang starknet␊
+ ␊
+ from starkware.cairo.common.cairo_builtins import HashBuiltin␊
+ from starkware.cairo.common.uint256 import Uint256␊
+ from starkware.cairo.common.bool import TRUE␊
+ ␊
+ from openzeppelin.token.erc20.library import (␊
+ ERC20_name,␊
+ ERC20_symbol,␊
+ ERC20_totalSupply,␊
+ ERC20_decimals,␊
+ ERC20_balanceOf,␊
+ ERC20_allowance,␊
+ ERC20_transfer,␊
+ ERC20_transferFrom,␊
+ ERC20_approve,␊
+ ERC20_increaseAllowance,␊
+ ERC20_decreaseAllowance,␊
+ ERC20_initializer,␊
+ )␊
+ ␊
+ @constructor␊
+ func constructor{␊
+ syscall_ptr: felt*,␊
+ pedersen_ptr: HashBuiltin*,␊
+ range_check_ptr␊
+ }():␊
+ ERC20_initializer('MyToken', 'MTK', 18)␊
+ return ()␊
+ end␊
+ ␊
+ #␊
+ # Getters␊
+ #␊
+ ␊
+ @view␊
+ func name{␊
+ syscall_ptr: felt*,␊
+ pedersen_ptr: HashBuiltin*,␊
+ range_check_ptr␊
+ }() -> (name: felt):␊
+ let (name) = ERC20_name()␊
+ return (name)␊
+ end␊
+ ␊
+ @view␊
+ func symbol{␊
+ syscall_ptr: felt*,␊
+ pedersen_ptr: HashBuiltin*,␊
+ range_check_ptr␊
+ }() -> (symbol: felt):␊
+ let (symbol) = ERC20_symbol()␊
+ return (symbol)␊
+ end␊
+ ␊
+ @view␊
+ func totalSupply{␊
+ syscall_ptr: felt*,␊
+ pedersen_ptr: HashBuiltin*,␊
+ range_check_ptr␊
+ }() -> (totalSupply: Uint256):␊
+ let (totalSupply) = ERC20_totalSupply()␊
+ return (totalSupply)␊
+ end␊
+ ␊
+ @view␊
+ func decimals{␊
+ syscall_ptr: felt*,␊
+ pedersen_ptr: HashBuiltin*,␊
+ range_check_ptr␊
+ }() -> (decimals: felt):␊
+ let (decimals) = ERC20_decimals()␊
+ return (decimals)␊
+ end␊
+ ␊
+ @view␊
+ func balanceOf{␊
+ syscall_ptr: felt*,␊
+ pedersen_ptr: HashBuiltin*,␊
+ range_check_ptr␊
+ }(account: felt) -> (balance: Uint256):␊
+ let (balance) = ERC20_balanceOf(account)␊
+ return (balance)␊
+ end␊
+ ␊
+ @view␊
+ func allowance{␊
+ syscall_ptr: felt*,␊
+ pedersen_ptr: HashBuiltin*,␊
+ range_check_ptr␊
+ }(owner: felt, spender: felt) -> (remaining: Uint256):␊
+ let (remaining) = ERC20_allowance(owner, spender)␊
+ return (remaining)␊
+ end␊
+ ␊
+ #␊
+ # Externals␊
+ #␊
+ ␊
+ @external␊
+ func transfer{␊
+ syscall_ptr: felt*,␊
+ pedersen_ptr: HashBuiltin*,␊
+ range_check_ptr␊
+ }(recipient: felt, amount: Uint256) -> (success: felt):␊
+ ERC20_transfer(recipient, amount)␊
+ return (TRUE)␊
+ end␊
+ ␊
+ @external␊
+ func transferFrom{␊
+ syscall_ptr: felt*,␊
+ pedersen_ptr: HashBuiltin*,␊
+ range_check_ptr␊
+ }(sender: felt, recipient: felt, amount: Uint256) -> (success: felt):␊
+ ERC20_transferFrom(sender, recipient, amount)␊
+ return (TRUE)␊
+ end␊
+ ␊
+ @external␊
+ func approve{␊
+ syscall_ptr: felt*,␊
+ pedersen_ptr: HashBuiltin*,␊
+ range_check_ptr␊
+ }(spender: felt, amount: Uint256) -> (success: felt):␊
+ ERC20_approve(spender, amount)␊
+ return (TRUE)␊
+ end␊
+ ␊
+ @external␊
+ func increaseAllowance{␊
+ syscall_ptr: felt*,␊
+ pedersen_ptr: HashBuiltin*,␊
+ range_check_ptr␊
+ }(spender: felt, added_value: Uint256) -> (success: felt):␊
+ ERC20_increaseAllowance(spender, added_value)␊
+ return (TRUE)␊
+ end␊
+ ␊
+ @external␊
+ func decreaseAllowance{␊
+ syscall_ptr: felt*,␊
+ pedersen_ptr: HashBuiltin*,␊
+ range_check_ptr␊
+ }(spender: felt, subtracted_value: Uint256) -> (success: felt):␊
+ ERC20_decreaseAllowance(spender, subtracted_value)␊
+ return (TRUE)␊
+ end␊
+ `
+
+## erc20 API basic
+
+> Snapshot 1
+
+ `# SPDX-License-Identifier: MIT␊
+ ␊
+ %lang starknet␊
+ ␊
+ from starkware.cairo.common.cairo_builtins import HashBuiltin␊
+ from starkware.cairo.common.uint256 import Uint256␊
+ from starkware.cairo.common.bool import TRUE␊
+ ␊
+ from openzeppelin.token.erc20.library import (␊
+ ERC20_name,␊
+ ERC20_symbol,␊
+ ERC20_totalSupply,␊
+ ERC20_decimals,␊
+ ERC20_balanceOf,␊
+ ERC20_allowance,␊
+ ERC20_transfer,␊
+ ERC20_transferFrom,␊
+ ERC20_approve,␊
+ ERC20_increaseAllowance,␊
+ ERC20_decreaseAllowance,␊
+ ERC20_initializer,␊
+ )␊
+ ␊
+ @constructor␊
+ func constructor{␊
+ syscall_ptr: felt*,␊
+ pedersen_ptr: HashBuiltin*,␊
+ range_check_ptr␊
+ }():␊
+ ERC20_initializer('CustomToken', 'CTK', 18)␊
+ return ()␊
+ end␊
+ ␊
+ #␊
+ # Getters␊
+ #␊
+ ␊
+ @view␊
+ func name{␊
+ syscall_ptr: felt*,␊
+ pedersen_ptr: HashBuiltin*,␊
+ range_check_ptr␊
+ }() -> (name: felt):␊
+ let (name) = ERC20_name()␊
+ return (name)␊
+ end␊
+ ␊
+ @view␊
+ func symbol{␊
+ syscall_ptr: felt*,␊
+ pedersen_ptr: HashBuiltin*,␊
+ range_check_ptr␊
+ }() -> (symbol: felt):␊
+ let (symbol) = ERC20_symbol()␊
+ return (symbol)␊
+ end␊
+ ␊
+ @view␊
+ func totalSupply{␊
+ syscall_ptr: felt*,␊
+ pedersen_ptr: HashBuiltin*,␊
+ range_check_ptr␊
+ }() -> (totalSupply: Uint256):␊
+ let (totalSupply) = ERC20_totalSupply()␊
+ return (totalSupply)␊
+ end␊
+ ␊
+ @view␊
+ func decimals{␊
+ syscall_ptr: felt*,␊
+ pedersen_ptr: HashBuiltin*,␊
+ range_check_ptr␊
+ }() -> (decimals: felt):␊
+ let (decimals) = ERC20_decimals()␊
+ return (decimals)␊
+ end␊
+ ␊
+ @view␊
+ func balanceOf{␊
+ syscall_ptr: felt*,␊
+ pedersen_ptr: HashBuiltin*,␊
+ range_check_ptr␊
+ }(account: felt) -> (balance: Uint256):␊
+ let (balance) = ERC20_balanceOf(account)␊
+ return (balance)␊
+ end␊
+ ␊
+ @view␊
+ func allowance{␊
+ syscall_ptr: felt*,␊
+ pedersen_ptr: HashBuiltin*,␊
+ range_check_ptr␊
+ }(owner: felt, spender: felt) -> (remaining: Uint256):␊
+ let (remaining) = ERC20_allowance(owner, spender)␊
+ return (remaining)␊
+ end␊
+ ␊
+ #␊
+ # Externals␊
+ #␊
+ ␊
+ @external␊
+ func transfer{␊
+ syscall_ptr: felt*,␊
+ pedersen_ptr: HashBuiltin*,␊
+ range_check_ptr␊
+ }(recipient: felt, amount: Uint256) -> (success: felt):␊
+ ERC20_transfer(recipient, amount)␊
+ return (TRUE)␊
+ end␊
+ ␊
+ @external␊
+ func transferFrom{␊
+ syscall_ptr: felt*,␊
+ pedersen_ptr: HashBuiltin*,␊
+ range_check_ptr␊
+ }(sender: felt, recipient: felt, amount: Uint256) -> (success: felt):␊
+ ERC20_transferFrom(sender, recipient, amount)␊
+ return (TRUE)␊
+ end␊
+ ␊
+ @external␊
+ func approve{␊
+ syscall_ptr: felt*,␊
+ pedersen_ptr: HashBuiltin*,␊
+ range_check_ptr␊
+ }(spender: felt, amount: Uint256) -> (success: felt):␊
+ ERC20_approve(spender, amount)␊
+ return (TRUE)␊
+ end␊
+ ␊
+ @external␊
+ func increaseAllowance{␊
+ syscall_ptr: felt*,␊
+ pedersen_ptr: HashBuiltin*,␊
+ range_check_ptr␊
+ }(spender: felt, added_value: Uint256) -> (success: felt):␊
+ ERC20_increaseAllowance(spender, added_value)␊
+ return (TRUE)␊
+ end␊
+ ␊
+ @external␊
+ func decreaseAllowance{␊
+ syscall_ptr: felt*,␊
+ pedersen_ptr: HashBuiltin*,␊
+ range_check_ptr␊
+ }(spender: felt, subtracted_value: Uint256) -> (success: felt):␊
+ ERC20_decreaseAllowance(spender, subtracted_value)␊
+ return (TRUE)␊
+ end␊
+ `
+
+## erc20 API full upgradeable
> Snapshot 1
@@ -1539,11 +1851,11 @@ Generated by [AVA](https://avajs.dev).
pedersen_ptr: HashBuiltin*,␊
range_check_ptr␊
}(owner: felt, recipient: felt, proxy_admin: felt):␊
- ERC20_initializer('MyToken', 'MTK', 18)␊
+ ERC20_initializer('CustomToken', 'CTK', 9)␊
Ownable_initializer(owner)␊
Proxy_initializer(proxy_admin)␊
␊
- ERC20_mint(recipient, Uint256(2000000000000000000000, 0))␊
+ ERC20_mint(recipient, Uint256(2000000000000, 0))␊
return ()␊
end␊
␊
diff --git a/packages/core-cairo/src/erc20.test.ts.snap b/packages/core-cairo/src/erc20.test.ts.snap
index 0dd03a891..10f662123 100644
Binary files a/packages/core-cairo/src/erc20.test.ts.snap and b/packages/core-cairo/src/erc20.test.ts.snap differ
diff --git a/packages/core-cairo/src/erc20.ts b/packages/core-cairo/src/erc20.ts
index dfad166b4..dd9c3bff4 100644
--- a/packages/core-cairo/src/erc20.ts
+++ b/packages/core-cairo/src/erc20.ts
@@ -8,15 +8,26 @@ import { setInfo } from './set-info';
import { OptionsError } from './error';
import BN from 'bn.js';
import { defineModules } from './utils/define-modules';
+import { defaults as commonDefaults } from './common-options';
+import { printContract } from './print';
-export const defaults = {
+export const defaults: Required = {
+ name: 'MyToken',
+ symbol: 'MTK',
burnable: false,
pausable: false,
premint: '0',
- mintable: false,
decimals: '18',
+ mintable: false,
+ access: commonDefaults.access,
+ upgradeable: commonDefaults.upgradeable,
+ info: commonDefaults.info
} as const;
+export function printERC20(opts: ERC20Options = defaults): string {
+ return printContract(buildERC20(opts));
+}
+
export interface ERC20Options extends CommonOptions {
name: string;
symbol: string;
diff --git a/packages/core-cairo/src/erc721.test.ts b/packages/core-cairo/src/erc721.test.ts
index 35f7ed6cb..481ff40c6 100644
--- a/packages/core-cairo/src/erc721.test.ts
+++ b/packages/core-cairo/src/erc721.test.ts
@@ -3,6 +3,8 @@ import test from 'ava';
import { buildERC721, ERC721Options } from './erc721';
import { printContract } from './print';
+import { printERC721, erc721defaults } from '.';
+
function testERC721(title: string, opts: Partial) {
test(title, t => {
const c = buildERC721({
@@ -14,6 +16,12 @@ function testERC721(title: string, opts: Partial) {
});
}
+function testERC721API(title: string, opts?: ERC721Options) {
+ test(title, t => {
+ t.snapshot(printERC721(opts));
+ });
+}
+
testERC721('basic', {});
testERC721('burnable', {
@@ -34,3 +42,20 @@ testERC721('full upgradeable', {
burnable: true,
upgradeable: true,
});
+
+testERC721API('API default');
+
+testERC721API('API basic', { name: 'CustomToken', symbol: 'CTK' });
+
+testERC721API('API full upgradeable', {
+ name: 'CustomToken',
+ symbol: 'CTK',
+ burnable: true,
+ mintable: true,
+ pausable: true,
+ upgradeable: true,
+});
+
+test('API assert defaults', async t => {
+ t.is(printERC721(erc721defaults), printERC721());
+});
\ No newline at end of file
diff --git a/packages/core-cairo/src/erc721.test.ts.md b/packages/core-cairo/src/erc721.test.ts.md
index 567bc6db0..e3219f110 100644
--- a/packages/core-cairo/src/erc721.test.ts.md
+++ b/packages/core-cairo/src/erc721.test.ts.md
@@ -1005,3 +1005,594 @@ Generated by [AVA](https://avajs.dev).
return ()␊
end␊
`
+
+## API default
+
+> Snapshot 1
+
+ `# SPDX-License-Identifier: MIT␊
+ ␊
+ %lang starknet␊
+ ␊
+ from starkware.cairo.common.cairo_builtins import HashBuiltin␊
+ from starkware.cairo.common.uint256 import Uint256␊
+ ␊
+ from openzeppelin.token.erc721.library import (␊
+ ERC721_name,␊
+ ERC721_symbol,␊
+ ERC721_balanceOf,␊
+ ERC721_ownerOf,␊
+ ERC721_getApproved,␊
+ ERC721_isApprovedForAll,␊
+ ERC721_tokenURI,␊
+ ERC721_approve,␊
+ ERC721_setApprovalForAll,␊
+ ERC721_transferFrom,␊
+ ERC721_safeTransferFrom,␊
+ ERC721_initializer,␊
+ )␊
+ from openzeppelin.introspection.ERC165 import ERC165_supports_interface␊
+ ␊
+ @constructor␊
+ func constructor{␊
+ syscall_ptr: felt*,␊
+ pedersen_ptr: HashBuiltin*,␊
+ range_check_ptr␊
+ }():␊
+ ERC721_initializer('MyToken', 'MTK')␊
+ return ()␊
+ end␊
+ ␊
+ #␊
+ # Getters␊
+ #␊
+ ␊
+ @view␊
+ func supportsInterface{␊
+ syscall_ptr: felt*,␊
+ pedersen_ptr: HashBuiltin*,␊
+ range_check_ptr␊
+ }(interfaceId: felt) -> (success: felt):␊
+ let (success) = ERC165_supports_interface(interfaceId)␊
+ return (success)␊
+ end␊
+ ␊
+ @view␊
+ func name{␊
+ syscall_ptr: felt*,␊
+ pedersen_ptr: HashBuiltin*,␊
+ range_check_ptr␊
+ }() -> (name: felt):␊
+ let (name) = ERC721_name()␊
+ return (name)␊
+ end␊
+ ␊
+ @view␊
+ func symbol{␊
+ syscall_ptr: felt*,␊
+ pedersen_ptr: HashBuiltin*,␊
+ range_check_ptr␊
+ }() -> (symbol: felt):␊
+ let (symbol) = ERC721_symbol()␊
+ return (symbol)␊
+ end␊
+ ␊
+ @view␊
+ func balanceOf{␊
+ syscall_ptr: felt*,␊
+ pedersen_ptr: HashBuiltin*,␊
+ range_check_ptr␊
+ }(owner: felt) -> (balance: Uint256):␊
+ let (balance) = ERC721_balanceOf(owner)␊
+ return (balance)␊
+ end␊
+ ␊
+ @view␊
+ func ownerOf{␊
+ syscall_ptr: felt*,␊
+ pedersen_ptr: HashBuiltin*,␊
+ range_check_ptr␊
+ }(token_id: Uint256) -> (owner: felt):␊
+ let (owner) = ERC721_ownerOf(token_id)␊
+ return (owner)␊
+ end␊
+ ␊
+ @view␊
+ func getApproved{␊
+ syscall_ptr: felt*,␊
+ pedersen_ptr: HashBuiltin*,␊
+ range_check_ptr␊
+ }(token_id: Uint256) -> (approved: felt):␊
+ let (approved) = ERC721_getApproved(token_id)␊
+ return (approved)␊
+ end␊
+ ␊
+ @view␊
+ func isApprovedForAll{␊
+ syscall_ptr: felt*,␊
+ pedersen_ptr: HashBuiltin*,␊
+ range_check_ptr␊
+ }(owner: felt, operator: felt) -> (isApproved: felt):␊
+ let (isApproved) = ERC721_isApprovedForAll(owner, operator)␊
+ return (isApproved)␊
+ end␊
+ ␊
+ @view␊
+ func tokenURI{␊
+ syscall_ptr: felt*,␊
+ pedersen_ptr: HashBuiltin*,␊
+ range_check_ptr␊
+ }(tokenId: Uint256) -> (tokenURI: felt):␊
+ let (tokenURI) = ERC721_tokenURI(tokenId)␊
+ return (tokenURI)␊
+ end␊
+ ␊
+ #␊
+ # Externals␊
+ #␊
+ ␊
+ @external␊
+ func approve{␊
+ syscall_ptr: felt*,␊
+ pedersen_ptr: HashBuiltin*,␊
+ range_check_ptr␊
+ }(to: felt, tokenId: Uint256):␊
+ ERC721_approve(to, tokenId)␊
+ return ()␊
+ end␊
+ ␊
+ @external␊
+ func setApprovalForAll{␊
+ syscall_ptr: felt*,␊
+ pedersen_ptr: HashBuiltin*,␊
+ range_check_ptr␊
+ }(operator: felt, approved: felt):␊
+ ERC721_setApprovalForAll(operator, approved)␊
+ return ()␊
+ end␊
+ ␊
+ @external␊
+ func transferFrom{␊
+ syscall_ptr: felt*,␊
+ pedersen_ptr: HashBuiltin*,␊
+ range_check_ptr␊
+ }(from_: felt, to: felt, tokenId: Uint256):␊
+ ERC721_transferFrom(from_, to, tokenId)␊
+ return ()␊
+ end␊
+ ␊
+ @external␊
+ func safeTransferFrom{␊
+ syscall_ptr: felt*,␊
+ pedersen_ptr: HashBuiltin*,␊
+ range_check_ptr␊
+ }(from_: felt, to: felt, tokenId: Uint256, data_len: felt, data: felt*):␊
+ ERC721_safeTransferFrom(from_, to, tokenId, data_len, data)␊
+ return ()␊
+ end␊
+ `
+
+## API basic
+
+> Snapshot 1
+
+ `# SPDX-License-Identifier: MIT␊
+ ␊
+ %lang starknet␊
+ ␊
+ from starkware.cairo.common.cairo_builtins import HashBuiltin␊
+ from starkware.cairo.common.uint256 import Uint256␊
+ ␊
+ from openzeppelin.token.erc721.library import (␊
+ ERC721_name,␊
+ ERC721_symbol,␊
+ ERC721_balanceOf,␊
+ ERC721_ownerOf,␊
+ ERC721_getApproved,␊
+ ERC721_isApprovedForAll,␊
+ ERC721_tokenURI,␊
+ ERC721_approve,␊
+ ERC721_setApprovalForAll,␊
+ ERC721_transferFrom,␊
+ ERC721_safeTransferFrom,␊
+ ERC721_initializer,␊
+ )␊
+ from openzeppelin.introspection.ERC165 import ERC165_supports_interface␊
+ ␊
+ @constructor␊
+ func constructor{␊
+ syscall_ptr: felt*,␊
+ pedersen_ptr: HashBuiltin*,␊
+ range_check_ptr␊
+ }():␊
+ ERC721_initializer('CustomToken', 'CTK')␊
+ return ()␊
+ end␊
+ ␊
+ #␊
+ # Getters␊
+ #␊
+ ␊
+ @view␊
+ func supportsInterface{␊
+ syscall_ptr: felt*,␊
+ pedersen_ptr: HashBuiltin*,␊
+ range_check_ptr␊
+ }(interfaceId: felt) -> (success: felt):␊
+ let (success) = ERC165_supports_interface(interfaceId)␊
+ return (success)␊
+ end␊
+ ␊
+ @view␊
+ func name{␊
+ syscall_ptr: felt*,␊
+ pedersen_ptr: HashBuiltin*,␊
+ range_check_ptr␊
+ }() -> (name: felt):␊
+ let (name) = ERC721_name()␊
+ return (name)␊
+ end␊
+ ␊
+ @view␊
+ func symbol{␊
+ syscall_ptr: felt*,␊
+ pedersen_ptr: HashBuiltin*,␊
+ range_check_ptr␊
+ }() -> (symbol: felt):␊
+ let (symbol) = ERC721_symbol()␊
+ return (symbol)␊
+ end␊
+ ␊
+ @view␊
+ func balanceOf{␊
+ syscall_ptr: felt*,␊
+ pedersen_ptr: HashBuiltin*,␊
+ range_check_ptr␊
+ }(owner: felt) -> (balance: Uint256):␊
+ let (balance) = ERC721_balanceOf(owner)␊
+ return (balance)␊
+ end␊
+ ␊
+ @view␊
+ func ownerOf{␊
+ syscall_ptr: felt*,␊
+ pedersen_ptr: HashBuiltin*,␊
+ range_check_ptr␊
+ }(token_id: Uint256) -> (owner: felt):␊
+ let (owner) = ERC721_ownerOf(token_id)␊
+ return (owner)␊
+ end␊
+ ␊
+ @view␊
+ func getApproved{␊
+ syscall_ptr: felt*,␊
+ pedersen_ptr: HashBuiltin*,␊
+ range_check_ptr␊
+ }(token_id: Uint256) -> (approved: felt):␊
+ let (approved) = ERC721_getApproved(token_id)␊
+ return (approved)␊
+ end␊
+ ␊
+ @view␊
+ func isApprovedForAll{␊
+ syscall_ptr: felt*,␊
+ pedersen_ptr: HashBuiltin*,␊
+ range_check_ptr␊
+ }(owner: felt, operator: felt) -> (isApproved: felt):␊
+ let (isApproved) = ERC721_isApprovedForAll(owner, operator)␊
+ return (isApproved)␊
+ end␊
+ ␊
+ @view␊
+ func tokenURI{␊
+ syscall_ptr: felt*,␊
+ pedersen_ptr: HashBuiltin*,␊
+ range_check_ptr␊
+ }(tokenId: Uint256) -> (tokenURI: felt):␊
+ let (tokenURI) = ERC721_tokenURI(tokenId)␊
+ return (tokenURI)␊
+ end␊
+ ␊
+ #␊
+ # Externals␊
+ #␊
+ ␊
+ @external␊
+ func approve{␊
+ syscall_ptr: felt*,␊
+ pedersen_ptr: HashBuiltin*,␊
+ range_check_ptr␊
+ }(to: felt, tokenId: Uint256):␊
+ ERC721_approve(to, tokenId)␊
+ return ()␊
+ end␊
+ ␊
+ @external␊
+ func setApprovalForAll{␊
+ syscall_ptr: felt*,␊
+ pedersen_ptr: HashBuiltin*,␊
+ range_check_ptr␊
+ }(operator: felt, approved: felt):␊
+ ERC721_setApprovalForAll(operator, approved)␊
+ return ()␊
+ end␊
+ ␊
+ @external␊
+ func transferFrom{␊
+ syscall_ptr: felt*,␊
+ pedersen_ptr: HashBuiltin*,␊
+ range_check_ptr␊
+ }(from_: felt, to: felt, tokenId: Uint256):␊
+ ERC721_transferFrom(from_, to, tokenId)␊
+ return ()␊
+ end␊
+ ␊
+ @external␊
+ func safeTransferFrom{␊
+ syscall_ptr: felt*,␊
+ pedersen_ptr: HashBuiltin*,␊
+ range_check_ptr␊
+ }(from_: felt, to: felt, tokenId: Uint256, data_len: felt, data: felt*):␊
+ ERC721_safeTransferFrom(from_, to, tokenId, data_len, data)␊
+ return ()␊
+ end␊
+ `
+
+## API full upgradeable
+
+> Snapshot 1
+
+ `# SPDX-License-Identifier: MIT␊
+ ␊
+ %lang starknet␊
+ ␊
+ from starkware.cairo.common.cairo_builtins import HashBuiltin␊
+ from starkware.cairo.common.uint256 import Uint256␊
+ ␊
+ from openzeppelin.token.erc721.library import (␊
+ ERC721_name,␊
+ ERC721_symbol,␊
+ ERC721_balanceOf,␊
+ ERC721_ownerOf,␊
+ ERC721_getApproved,␊
+ ERC721_isApprovedForAll,␊
+ ERC721_tokenURI,␊
+ ERC721_approve,␊
+ ERC721_setApprovalForAll,␊
+ ERC721_transferFrom,␊
+ ERC721_safeTransferFrom,␊
+ ERC721_burn,␊
+ ERC721_safeMint,␊
+ ERC721_initializer,␊
+ ERC721_only_token_owner,␊
+ ERC721_setTokenURI,␊
+ )␊
+ from openzeppelin.introspection.ERC165 import ERC165_supports_interface␊
+ from openzeppelin.security.pausable import (␊
+ Pausable_paused,␊
+ Pausable_pause,␊
+ Pausable_unpause,␊
+ Pausable_when_not_paused,␊
+ )␊
+ from openzeppelin.access.ownable import (␊
+ Ownable_initializer,␊
+ Ownable_only_owner,␊
+ )␊
+ from openzeppelin.upgrades.library import (␊
+ Proxy_initializer,␊
+ Proxy_only_admin,␊
+ Proxy_set_implementation,␊
+ )␊
+ ␊
+ @external␊
+ func initializer{␊
+ syscall_ptr: felt*,␊
+ pedersen_ptr: HashBuiltin*,␊
+ range_check_ptr␊
+ }(owner: felt, proxy_admin: felt):␊
+ ERC721_initializer('CustomToken', 'CTK')␊
+ Ownable_initializer(owner)␊
+ Proxy_initializer(proxy_admin)␊
+ return ()␊
+ end␊
+ ␊
+ #␊
+ # Getters␊
+ #␊
+ ␊
+ @view␊
+ func supportsInterface{␊
+ syscall_ptr: felt*,␊
+ pedersen_ptr: HashBuiltin*,␊
+ range_check_ptr␊
+ }(interfaceId: felt) -> (success: felt):␊
+ let (success) = ERC165_supports_interface(interfaceId)␊
+ return (success)␊
+ end␊
+ ␊
+ @view␊
+ func name{␊
+ syscall_ptr: felt*,␊
+ pedersen_ptr: HashBuiltin*,␊
+ range_check_ptr␊
+ }() -> (name: felt):␊
+ let (name) = ERC721_name()␊
+ return (name)␊
+ end␊
+ ␊
+ @view␊
+ func symbol{␊
+ syscall_ptr: felt*,␊
+ pedersen_ptr: HashBuiltin*,␊
+ range_check_ptr␊
+ }() -> (symbol: felt):␊
+ let (symbol) = ERC721_symbol()␊
+ return (symbol)␊
+ end␊
+ ␊
+ @view␊
+ func balanceOf{␊
+ syscall_ptr: felt*,␊
+ pedersen_ptr: HashBuiltin*,␊
+ range_check_ptr␊
+ }(owner: felt) -> (balance: Uint256):␊
+ let (balance) = ERC721_balanceOf(owner)␊
+ return (balance)␊
+ end␊
+ ␊
+ @view␊
+ func ownerOf{␊
+ syscall_ptr: felt*,␊
+ pedersen_ptr: HashBuiltin*,␊
+ range_check_ptr␊
+ }(token_id: Uint256) -> (owner: felt):␊
+ let (owner) = ERC721_ownerOf(token_id)␊
+ return (owner)␊
+ end␊
+ ␊
+ @view␊
+ func getApproved{␊
+ syscall_ptr: felt*,␊
+ pedersen_ptr: HashBuiltin*,␊
+ range_check_ptr␊
+ }(token_id: Uint256) -> (approved: felt):␊
+ let (approved) = ERC721_getApproved(token_id)␊
+ return (approved)␊
+ end␊
+ ␊
+ @view␊
+ func isApprovedForAll{␊
+ syscall_ptr: felt*,␊
+ pedersen_ptr: HashBuiltin*,␊
+ range_check_ptr␊
+ }(owner: felt, operator: felt) -> (isApproved: felt):␊
+ let (isApproved) = ERC721_isApprovedForAll(owner, operator)␊
+ return (isApproved)␊
+ end␊
+ ␊
+ @view␊
+ func tokenURI{␊
+ syscall_ptr: felt*,␊
+ pedersen_ptr: HashBuiltin*,␊
+ range_check_ptr␊
+ }(tokenId: Uint256) -> (tokenURI: felt):␊
+ let (tokenURI) = ERC721_tokenURI(tokenId)␊
+ return (tokenURI)␊
+ end␊
+ ␊
+ @view␊
+ func paused{␊
+ syscall_ptr: felt*,␊
+ pedersen_ptr: HashBuiltin*,␊
+ range_check_ptr␊
+ }() -> (paused: felt):␊
+ let (paused) = Pausable_paused.read()␊
+ return (paused)␊
+ end␊
+ ␊
+ #␊
+ # Externals␊
+ #␊
+ ␊
+ @external␊
+ func approve{␊
+ syscall_ptr: felt*,␊
+ pedersen_ptr: HashBuiltin*,␊
+ range_check_ptr␊
+ }(to: felt, tokenId: Uint256):␊
+ Pausable_when_not_paused()␊
+ ERC721_approve(to, tokenId)␊
+ return ()␊
+ end␊
+ ␊
+ @external␊
+ func setApprovalForAll{␊
+ syscall_ptr: felt*,␊
+ pedersen_ptr: HashBuiltin*,␊
+ range_check_ptr␊
+ }(operator: felt, approved: felt):␊
+ Pausable_when_not_paused()␊
+ ERC721_setApprovalForAll(operator, approved)␊
+ return ()␊
+ end␊
+ ␊
+ @external␊
+ func transferFrom{␊
+ syscall_ptr: felt*,␊
+ pedersen_ptr: HashBuiltin*,␊
+ range_check_ptr␊
+ }(from_: felt, to: felt, tokenId: Uint256):␊
+ Pausable_when_not_paused()␊
+ ERC721_transferFrom(from_, to, tokenId)␊
+ return ()␊
+ end␊
+ ␊
+ @external␊
+ func safeTransferFrom{␊
+ syscall_ptr: felt*,␊
+ pedersen_ptr: HashBuiltin*,␊
+ range_check_ptr␊
+ }(from_: felt, to: felt, tokenId: Uint256, data_len: felt, data: felt*):␊
+ Pausable_when_not_paused()␊
+ ERC721_safeTransferFrom(from_, to, tokenId, data_len, data)␊
+ return ()␊
+ end␊
+ ␊
+ @external␊
+ func pause{␊
+ syscall_ptr: felt*,␊
+ pedersen_ptr: HashBuiltin*,␊
+ range_check_ptr␊
+ }():␊
+ Ownable_only_owner()␊
+ Pausable_pause()␊
+ return ()␊
+ end␊
+ ␊
+ @external␊
+ func unpause{␊
+ syscall_ptr: felt*,␊
+ pedersen_ptr: HashBuiltin*,␊
+ range_check_ptr␊
+ }():␊
+ Ownable_only_owner()␊
+ Pausable_unpause()␊
+ return ()␊
+ end␊
+ ␊
+ @external␊
+ func burn{␊
+ syscall_ptr: felt*,␊
+ pedersen_ptr: HashBuiltin*,␊
+ range_check_ptr␊
+ }(tokenId: Uint256):␊
+ Pausable_when_not_paused()␊
+ ERC721_only_token_owner(tokenId)␊
+ ERC721_burn(tokenId)␊
+ return ()␊
+ end␊
+ ␊
+ @external␊
+ func safeMint{␊
+ syscall_ptr: felt*,␊
+ pedersen_ptr: HashBuiltin*,␊
+ range_check_ptr␊
+ }(to: felt, tokenId: Uint256, data_len: felt, data: felt*, tokenURI: felt):␊
+ Pausable_when_not_paused()␊
+ Ownable_only_owner()␊
+ ERC721_safeMint(to, tokenId, data_len, data)␊
+ ERC721_setTokenURI(tokenId, tokenURI)␊
+ return ()␊
+ end␊
+ ␊
+ @external␊
+ func upgrade{␊
+ syscall_ptr: felt*,␊
+ pedersen_ptr: HashBuiltin*,␊
+ range_check_ptr␊
+ }(new_implementation: felt) -> ():␊
+ Proxy_only_admin()␊
+ Proxy_set_implementation(new_implementation)␊
+ return ()␊
+ end␊
+ `
diff --git a/packages/core-cairo/src/erc721.test.ts.snap b/packages/core-cairo/src/erc721.test.ts.snap
index 32df87386..9736bf90d 100644
Binary files a/packages/core-cairo/src/erc721.test.ts.snap and b/packages/core-cairo/src/erc721.test.ts.snap differ
diff --git a/packages/core-cairo/src/erc721.ts b/packages/core-cairo/src/erc721.ts
index 02ae0a69e..4c8e879d2 100644
--- a/packages/core-cairo/src/erc721.ts
+++ b/packages/core-cairo/src/erc721.ts
@@ -6,6 +6,23 @@ import { CommonOptions, withCommonDefaults, withImplicitArgs } from './common-op
import { setUpgradeable } from './set-upgradeable';
import { setInfo } from './set-info';
import { defineModules } from './utils/define-modules';
+import { defaults as commonDefaults } from './common-options';
+import { printContract } from './print';
+
+export const defaults: Required = {
+ name: 'MyToken',
+ symbol: 'MTK',
+ burnable: false,
+ pausable: false,
+ mintable: false,
+ access: commonDefaults.access,
+ upgradeable: commonDefaults.upgradeable,
+ info: commonDefaults.info
+} as const;
+
+export function printERC721(opts: ERC721Options = defaults): string {
+ return printContract(buildERC721(opts));
+}
export interface ERC721Options extends CommonOptions {
name: string;
@@ -15,12 +32,22 @@ export interface ERC721Options extends CommonOptions {
mintable?: boolean;
}
+function withDefaults(opts: ERC721Options): Required {
+ return {
+ ...opts,
+ ...withCommonDefaults(opts),
+ burnable: opts.burnable ?? defaults.burnable,
+ pausable: opts.pausable ?? defaults.pausable,
+ mintable: opts.mintable ?? defaults.mintable,
+ };
+}
+
export function buildERC721(opts: ERC721Options): Contract {
const c = new ContractBuilder();
- const { access, upgradeable, info } = withCommonDefaults(opts);
+ const allOpts = withDefaults(opts);
- addBase(c, opts.name, opts.symbol);
+ addBase(c, allOpts.name, allOpts.symbol);
addSupportsInterface(c);
c.addFunction(functions.name);
@@ -36,27 +63,27 @@ export function buildERC721(opts: ERC721Options): Contract {
c.addFunction(functions.transferFrom);
c.addFunction(functions.safeTransferFrom);
- if (opts.pausable) {
- addPausable(c, access, [functions.approve, functions.setApprovalForAll, functions.transferFrom, functions.safeTransferFrom]);
- if (opts.burnable) {
+ if (allOpts.pausable) {
+ addPausable(c, allOpts.access, [functions.approve, functions.setApprovalForAll, functions.transferFrom, functions.safeTransferFrom]);
+ if (allOpts.burnable) {
setPausable(c, functions.burn);
}
- if (opts.mintable) {
+ if (allOpts.mintable) {
setPausable(c, functions.safeMint);
}
}
- if (opts.burnable) {
+ if (allOpts.burnable) {
addBurnable(c);
}
- if (opts.mintable) {
- addMintable(c, access);
+ if (allOpts.mintable) {
+ addMintable(c, allOpts.access);
}
- setUpgradeable(c, upgradeable);
+ setUpgradeable(c, allOpts.upgradeable);
- setInfo(c, info);
+ setInfo(c, allOpts.info);
return c;
}
diff --git a/packages/core-cairo/src/index.ts b/packages/core-cairo/src/index.ts
index bb122798f..52a129d4c 100644
--- a/packages/core-cairo/src/index.ts
+++ b/packages/core-cairo/src/index.ts
@@ -10,7 +10,9 @@ export type { Access } from './set-access-control';
export type { Upgradeable } from './set-upgradeable';
export type { Info } from './set-info';
-export { premintPattern } from './erc20';
+export { premintPattern, defaults as erc20defaults, printERC20 } from './erc20';
+export { defaults as erc721defaults, printERC721 } from './erc721';
+
export { defaults as infoDefaults } from './set-info';
export type { OptionsErrorMessages } from './error';
diff --git a/packages/core/package.json b/packages/core/package.json
index 4d1419a36..521c32e4e 100644
--- a/packages/core/package.json
+++ b/packages/core/package.json
@@ -3,7 +3,7 @@
"version": "0.1.0",
"description": "A boilerplate generator to get started with OpenZeppelin Contracts",
"license": "MIT",
- "repository": "github:OpenZeppelin/wizard",
+ "repository": "github:OpenZeppelin/contracts-wizard",
"main": "dist/index.js",
"ts:main": "src/index.ts",
"files": [
diff --git a/packages/ui/src/cairo/App.svelte b/packages/ui/src/cairo/App.svelte
index dc58f5309..36579f82c 100644
--- a/packages/ui/src/cairo/App.svelte
+++ b/packages/ui/src/cairo/App.svelte
@@ -13,8 +13,8 @@
import OverflowMenu from '../OverflowMenu.svelte';
import FileIcon from '../icons/FileIcon.svelte';
- import type { KindedOptions, Kind, Contract, OptionsErrorMessages } from 'core-cairo';
- import { ContractBuilder, buildGeneric, printContract, sanitizeKind, OptionsError } from 'core-cairo';
+ import type { KindedOptions, Kind, Contract, OptionsErrorMessages } from '@openzeppelin/wizard-cairo';
+ import { ContractBuilder, buildGeneric, printContract, sanitizeKind, OptionsError } from '@openzeppelin/wizard-cairo';
import { postConfig } from '../post-config';
import { saveAs } from 'file-saver';
diff --git a/packages/ui/src/cairo/ERC20Controls.svelte b/packages/ui/src/cairo/ERC20Controls.svelte
index ecb69e9f7..1b7ffe74b 100644
--- a/packages/ui/src/cairo/ERC20Controls.svelte
+++ b/packages/ui/src/cairo/ERC20Controls.svelte
@@ -1,9 +1,8 @@
diff --git a/packages/ui/src/cairo/InfoSection.svelte b/packages/ui/src/cairo/InfoSection.svelte
index e5c7b77fc..adeb1db74 100644
--- a/packages/ui/src/cairo/InfoSection.svelte
+++ b/packages/ui/src/cairo/InfoSection.svelte
@@ -1,6 +1,6 @@
diff --git a/packages/ui/src/cairo/UpgradeabilitySection.svelte b/packages/ui/src/cairo/UpgradeabilitySection.svelte
index 35864e61d..d0885cb18 100644
--- a/packages/ui/src/cairo/UpgradeabilitySection.svelte
+++ b/packages/ui/src/cairo/UpgradeabilitySection.svelte
@@ -1,5 +1,5 @@