Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add initializer_no_metadata to erc721 component #1278

Open
wants to merge 5 commits into
base: release-v1.0.0
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 4 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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added

- ERC721Component `initializer_no_metadata` (#)
- SRC9 (Outside Execution) integration to account presets (#1201)
- `SNIP12HashSpanImpl` to `openzeppelin_utils::cryptography::snip12` (#1180)
- GovernorComponent with the following extensions: (#1180)
Expand Down
20 changes: 20 additions & 0 deletions docs/modules/ROOT/pages/api/erc721.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,7 @@ NOTE: See xref:#ERC721Component-Hooks[Hooks] to understand how are hooks used.
--
.InternalImpl
* xref:#ERC721Component-initializer[`++initializer(self, name, symbol, base_uri)++`]
* xref:#ERC721Component-initializer_no_metadata[`++initializer_no_metadata(self)++`]
* xref:#ERC721Component-exists[`++exists(self, token_id)++`]
* xref:#ERC721Component-transfer[`++transfer(self, from, to, token_id)++`]
* xref:#ERC721Component-mint[`++mint(self, to, token_id)++`]
Expand Down Expand Up @@ -470,6 +471,25 @@ See <<ERC721Component-token_uri,ERC721Component::token_uri>>.
Initializes the contract by setting the token name and symbol.
This should be used inside the contract's constructor.

WARNING: Most ERC721 contracts expose the <<IERC721Metadata,IERC721Metadata>> interface which
is what this initializer is meant to support.
If the contract DOES NOT expose the <<IERC721Metadata,IERC721Metadata>> interface,
meaning the token does not have a name, symbol, or URI,
the contract must instead use <<ERC721Component-initializer_no_metadata,initializer_no_metadata>> in the constructor.
Failure to abide by these instructions can lead to unexpected issues especially with
UIs.

[.contract-item]
[[ERC721Component-initializer_no_metadata]]
==== `[.contract-item-name]#++initializer_no_metadata++#++(ref self: ContractState)++` [.item-kind]#internal#

Initializes the contract with no metadata by registering only the IERC721 interface.

WARNING: This initializer should ONLY be used during construction in the very
specific instance when the contract does NOT expose the <<IERC721Metadata,IERC721Metadata>> interface.
Initializing a contract with this initializer means that tokens will not
have a name, symbol, or URI.

[.contract-item]
[[ERC721Component-exists]]
==== `[.contract-item-name]#++exists++#++(self: @ContractState, token_id: u256) -> bool++` [.item-kind]#internal#
Expand Down
19 changes: 19 additions & 0 deletions packages/token/src/erc721/erc721.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -475,6 +475,14 @@ pub mod ERC721Component {
> of InternalTrait<TContractState> {
/// Initializes the contract by setting the token name, symbol, and base URI.
/// This should only be used inside the contract's constructor.
///
/// WARNING: Most ERC721 contracts expose the IERC721Metadata interface which
/// is what this initializer is meant to support.
/// If the contract DOES NOT expose the IERC721Metadata interface,
/// meaning the token does not have a name, symbol, or URI,
/// the contract must instead instead use `initializer_no_metadata` in the constructor.
/// Failure to abide by these instructions can lead to unexpected issues especially with
/// UIs.
fn initializer(
ref self: ComponentState<TContractState>,
name: ByteArray,
Expand All @@ -490,6 +498,17 @@ pub mod ERC721Component {
src5_component.register_interface(interface::IERC721_METADATA_ID);
}

/// Initializes the contract with no metadata by registering only the IERC721 interface.
///
/// WARNING: This initializer should ONLY be used during construction in the very
/// specific instance when the contract does NOT expose the IERC721Metadata interface.
/// Initializing a contract with this initializer means that tokens will not
/// have a name, symbol, or URI.
fn initializer_no_metadata(ref self: ComponentState<TContractState>) {
let mut src5_component = get_dep_component_mut!(ref self, SRC5);
src5_component.register_interface(interface::IERC721_ID);
}

/// Returns whether `token_id` exists.
fn exists(self: @ComponentState<TContractState>, token_id: u256) -> bool {
!self._owner_of(token_id).is_zero()
Expand Down
25 changes: 25 additions & 0 deletions packages/token/src/tests/erc721/test_erc721.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,31 @@ fn test_initializer() {
assert!(supports_isrc5);
}

#[test]
fn test_initializer_no_metadata() {
let mut state = COMPONENT_STATE();
let mock_state = CONTRACT_STATE();

state.initializer_no_metadata();

let empty_str = "";
assert_eq!(state.name(), empty_str);
assert_eq!(state.symbol(), empty_str);
assert_eq!(state._base_uri(), empty_str);
assert!(state.balance_of(OWNER()).is_zero());

let supports_ierc721 = mock_state.supports_interface(erc721::interface::IERC721_ID);
assert!(supports_ierc721);

let does_not_support_ierc721_metadata = !mock_state
.supports_interface(erc721::interface::IERC721_METADATA_ID);
assert!(does_not_support_ierc721_metadata);

let supports_isrc5 = mock_state
.supports_interface(openzeppelin_introspection::interface::ISRC5_ID);
assert!(supports_isrc5);
}

//
// Getters
//
Expand Down
Loading