diff --git a/docs/antora.yml b/docs/antora.yml
index 3c4ffb147..f13903da8 100644
--- a/docs/antora.yml
+++ b/docs/antora.yml
@@ -5,4 +5,4 @@ nav:
- modules/ROOT/nav.adoc
asciidoc:
attributes:
- page-sidebar-collapse-default: 'Access,Accounts,Introspection,Security,ERC20,ERC721,Upgrades'
+ page-sidebar-collapse-default: 'Access,Accounts,Introspection,Security,ERC20,ERC721,ERC1155,Upgrades'
diff --git a/docs/modules/ROOT/nav.adoc b/docs/modules/ROOT/nav.adoc
index 880d9c88b..dce0c8550 100644
--- a/docs/modules/ROOT/nav.adoc
+++ b/docs/modules/ROOT/nav.adoc
@@ -30,7 +30,8 @@
**** xref:/api/erc20.adoc[API Reference]
*** xref:erc721.adoc[ERC721]
**** xref:/api/erc721.adoc[API Reference]
-// *** xref:erc1155.adoc[ERC1155]
+*** xref:erc1155.adoc[ERC1155]
+**** xref:/api/erc1155.adoc[API Reference]
** xref:upgrades.adoc[Upgrades]
*** xref:/api/upgrades.adoc[API Reference]
diff --git a/docs/modules/ROOT/pages/api/access.adoc b/docs/modules/ROOT/pages/api/access.adoc
index 40b9b4593..62f8d9196 100644
--- a/docs/modules/ROOT/pages/api/access.adoc
+++ b/docs/modules/ROOT/pages/api/access.adoc
@@ -4,10 +4,11 @@
:src5: https://github.com/starknet-io/SNIPs/blob/main/SNIPS/snip-5.md[SRC5]
:inner-src5: xref:api/introspection.adoc#ISRC5[SRC5 ID]
:_set_role_admin: xref:#AccessControlComponent-_set_role_admin[_set_role_admin]
-:mixin-impls: xref:components.adoc#mixins[Embeddable Mixin Implementations]
= Access Control
+include::../utils/_common.adoc[]
+
This directory provides ways to restrict who can access the functions of a contract or when they can do it.
- {Ownable} is a simple mechanism with a single "owner" role that can be assigned to a single account.
@@ -405,7 +406,6 @@ Emitted when `account` is revoked `role`.
:assert_only_role: xref:#AccessControlComponent-assert_only_role
:grant_role: xref:#AccessControlComponent-grant_role[grant_role]
:revoke_role: xref:#AccessControlComponent-revoke_role[revoke_role]
-:mixin-impl: xref:components.adoc#mixins[Embeddable Mixin Implementation]
```javascript
use openzeppelin::access::accesscontrol::AccessControlComponent;
@@ -446,7 +446,7 @@ grant and revoke this role. Extra precautions should be taken to secure
accounts that have been granted it.
[.contract-index#AccessControl-Mixin-Impl]
-.{mixin-impl}
+.{mixin-impls}
--
.AccessControlMixinImpl
diff --git a/docs/modules/ROOT/pages/api/account.adoc b/docs/modules/ROOT/pages/api/account.adoc
index f1aaf0768..138cd77fd 100644
--- a/docs/modules/ROOT/pages/api/account.adoc
+++ b/docs/modules/ROOT/pages/api/account.adoc
@@ -1,7 +1,6 @@
:github-icon: pass:[]
:snip6: https://github.com/ericnordelo/SNIPs/blob/feat/standard-account/SNIPS/snip-6.md[SNIP-6]
:inner-src5: xref:api/introspection.adoc#ISRC5[SRC5 ID]
-:mixin-impl: xref:components.adoc#mixins[Embeddable Mixin Implementation]
= Account
@@ -9,6 +8,8 @@ Reference of interfaces, presets, and utilities related to account contracts.
== Core
+include::../utils/_common.adoc[]
+
[.contract]
[[ISRC6]]
=== `++ISRC6++` link:https://github.com/OpenZeppelin/cairo-contracts/blob/release-v0.9.0/src/account/interface.cairo[{github-icon},role=heading-link]
@@ -75,10 +76,10 @@ use openzeppelin::account::AccountComponent;
```
Account component implementing xref:ISRC6[`ISRC6`] for signatures over the {starknet-curve}.
-NOTE: Implementing xref:api/introspection.adoc#SRC5Component[SRC5Component] is a requirement for this component to be implemented.
+NOTE: {src5-component-required-note}
[.contract-index#AccountComponent-Embeddable-Mixin-Impl]
-.{mixin-impl}
+.{mixin-impls}
--
.AccountMixinImpl
@@ -292,12 +293,12 @@ use openzeppelin::account::eth_account::EthAccountComponent;
```
Account component implementing xref:ISRC6[`ISRC6`] for signatures over the {secp256k1-curve}.
-NOTE: Implementing xref:api/introspection.adoc#SRC5Component[SRC5Component] is a requirement for this component to be implemented.
+NOTE: {src5-component-required-note}
NOTE: The `EthPublicKey` type is an alias for `starknet::secp256k1::Secp256k1Point`.
[.contract-index#EthAccountComponent-Embeddable-Mixin-Impl]
-.{mixin-impl}
+.{mixin-impls}
--
.EthAccountMixinImpl
diff --git a/docs/modules/ROOT/pages/api/erc1155.adoc b/docs/modules/ROOT/pages/api/erc1155.adoc
new file mode 100644
index 000000000..bd4afdda1
--- /dev/null
+++ b/docs/modules/ROOT/pages/api/erc1155.adoc
@@ -0,0 +1,670 @@
+:github-icon: pass:[]
+:eip1155: https://eips.ethereum.org/EIPS/eip-1155[EIP1155]
+:eip1155-metadata: https://eips.ethereum.org/EIPS/eip-1155#metadata
+:receiving-tokens: xref:/erc1155.adoc#receiving_tokens[Receiving tokens]
+:inner-src5: xref:api/introspection.adoc#ISRC5[SRC5 ID]
+
+= ERC1155
+
+include::../utils/_common.adoc[]
+
+Reference of interfaces, presets, and utilities related to ERC1155 contracts.
+
+TIP: For an overview of ERC1155, read our xref:erc1155.adoc[ERC1155 guide].
+
+== Core
+
+[.contract]
+[[IERC1155]]
+=== `++IERC1155++` link:https://github.com/OpenZeppelin/cairo-contracts/blob/release-v0.9.0/src/token/erc1155/interface.cairo[{github-icon},role=heading-link]
+
+[.hljs-theme-dark]
+```javascript
+use openzeppelin::token::erc1155::interface::IERC1155;
+```
+Interface of the IERC1155 standard as defined in {eip1155}.
+
+[.contract-index]
+.{inner-src5}
+--
+0x6114a8f75559e1b39fcba08ce02961a1aa082d9256a158dd3e64964e4b1b52
+--
+
+[.contract-index]
+.Functions
+--
+* xref:#IERC1155-balance_of[`++balance_of(account, token_id)++`]
+* xref:#IERC1155-balance_of_batch[`++balance_of_batch(accounts, token_ids)++`]
+* xref:#IERC1155-safe_transfer_from[`++safe_transfer_from(from, to, token_id, value, data)++`]
+* xref:#IERC1155-safe_batch_transfer_from[`++safe_batch_transfer_from(from, to, token_ids, values, data)++`]
+* xref:#IERC1155-set_approval_for_all[`++set_approval_for_all(operator, approved)++`]
+* xref:#IERC1155-is_approved_for_all[`++is_approved_for_all(owner, operator)++`]
+--
+
+[.contract-index]
+.Events
+--
+* xref:#IERC1155-TransferSingle[`++TransferSingle(operator, from, to, id, value)++`]
+* xref:#IERC1155-TransferBatch[`++TransferBatch(operator, from, to, ids, values)++`]
+* xref:#IERC1155-ApprovalForAll[`++ApprovalForAll(owner, operator, approved)++`]
+* xref:#IERC1155-URI[`++URI(value, id)++`]
+--
+
+==== Functions
+
+[.contract-item]
+[[IERC1155-balance_of]]
+==== `[.contract-item-name]#++balance_of++#++(account: ContractAddress, token_id: u256) → u256++` [.item-kind]#external#
+
+Returns the amount of `token_id` tokens owned by `account`.
+
+[.contract-item]
+[[IERC1155-balance_of_batch]]
+==== `[.contract-item-name]#++balance_of_batch++#++(accounts: Span, token_ids: Span) → Span++` [.item-kind]#external#
+
+Returns a list of balances derived from the `accounts` and `token_ids` pairs.
+
+[.contract-item]
+[[IERC1155-safe_transfer_from]]
+==== `[.contract-item-name]#++safe_transfer_from++#++(from: ContractAddress, to: ContractAddress, token_id: u256, value: u256, data: Span)++` [.item-kind]#external#
+
+Transfers ownership of `value` amount of `token_id` from `from` if `to` is either `IERC1155Receiver` or an account.
+
+`data` is additional data, it has no specified format and it is passed to `to`.
+
+Emits a <> event.
+
+[.contract-item]
+[[IERC1155-safe_batch_transfer_from]]
+==== `[.contract-item-name]#++safe_batch_transfer_from++#++(from: ContractAddress, to: ContractAddress, token_ids: Span, values: Span, data: Span)++` [.item-kind]#external#
+
+Transfers ownership of `token_ids` and `values` pairs from `from` if `to` is either `IERC1155Receiver` or an account.
+
+`data` is additional data, it has no specified format and it is passed to `to`.
+
+Emits a <> event.
+
+[.contract-item]
+[[IERC1155-set_approval_for_all]]
+==== `[.contract-item-name]#++set_approval_for_all++#++(operator: ContractAddress, approved: bool)++` [.item-kind]#external#
+
+Enables or disables approval for `operator` to manage all of the caller's assets.
+
+Emits an <> event.
+
+[.contract-item]
+[[IERC1155-is_approved_for_all]]
+==== `[.contract-item-name]#++is_approved_for_all++#++(owner: ContractAddress, operator: ContractAddress) -> bool++` [.item-kind]#external#
+
+Queries if `operator` is an authorized operator for `owner`.
+
+==== Events
+
+[.contract-item]
+[[IERC1155-TransferSingle]]
+==== `[.contract-item-name]#++TransferSingle++#++(operator: ContractAddress, from: ContractAddress, to: ContractAddress, id: u256, value: u256)++` [.item-kind]#event#
+
+Emitted when `value` amount of `id` token is transferred from `from` to `to` through `operator`.
+
+[.contract-item]
+[[IERC1155-TransferBatch]]
+==== `[.contract-item-name]#++TransferBatch++#++(operator: ContractAddress, from: ContractAddress, to: ContractAddress, ids: Span, values: Span)++` [.item-kind]#event#
+
+Emitted when a batch of `values` amount of `ids` tokens are transferred from `from` to `to` through `operator`.
+
+[.contract-item]
+[[IERC1155-ApprovalForAll]]
+==== `[.contract-item-name]#++ApprovalForAll++#++(owner: ContractAddress, operator: ContractAddress, approved: bool)++` [.item-kind]#event#
+
+Emitted when `owner` enables or disables `operator` to manage all of the owner's assets.
+
+[.contract-item]
+[[IERC1155-URI]]
+==== `[.contract-item-name]#++URI++#++(value: ByteArray, id: u256)++` [.item-kind]#event#
+
+Emitted when the token URI is updated to `value` for the `id` token.
+
+[.contract]
+[[IERC1155MetadataURI]]
+=== `++IERC1155MetadataURI++` link:https://github.com/OpenZeppelin/cairo-contracts/blob/release-v0.9.0/src/token/erc1155/interface.cairo[{github-icon},role=heading-link]
+
+[.hljs-theme-dark]
+```javascript
+use openzeppelin::token::erc1155::interface::IERC1155MetadataURI;
+```
+Interface for the optional metadata function in {eip1155-metadata}[EIP1155].
+
+[.contract-index]
+.{inner-src5}
+--
+0xcabe2400d5fe509e1735ba9bad205ba5f3ca6e062da406f72f113feb889ef7
+--
+
+[.contract-index]
+.Functions
+--
+* xref:#IERC1155MetadataURI-uri[`++uri(token_id)++`]
+--
+
+==== Functions
+
+[.contract-item]
+[[IERC1155MetadataURI-uri]]
+==== `[.contract-item-name]#++uri++#++(token_id: u256) -> ByteArray++` [.item-kind]#external#
+
+Returns the Uniform Resource Identifier (URI) for the `token_id` token.
+
+[.contract]
+[[ERC1155Component]]
+=== `++ERC1155Component++` link:https://github.com/OpenZeppelin/cairo-contracts/blob/release-v0.9.0/src/token/erc1155/erc1155.cairo[{github-icon},role=heading-link]
+
+[.hljs-theme-dark]
+```javascript
+use openzeppelin::token::erc1155::ERC1155Component;
+```
+
+ERC1155 component implementing <> and <>.
+
+NOTE: {src5-component-required-note}
+
+[.contract-index#ERC1155Component-Embeddable-Impls]
+.Embeddable Implementations
+--
+[.sub-index#ERC1155Component-Embeddable-Impls-ERC1155Impl]
+.ERC1155Impl
+* xref:#ERC1155Component-balance_of[`++balance_of(self, account, token_id)++`]
+* xref:#ERC1155Component-balance_of_batch[`++balance_of_batch(self, accounts, token_ids)++`]
+* xref:#ERC1155Component-safe_transfer_from[`++safe_transfer_from(self, from, to, token_id, value, data)++`]
+* xref:#ERC1155Component-safe_batch_transfer_from[`++safe_batch_transfer_from(self, from, to, token_ids, values, data)++`]
+* xref:#ERC1155Component-set_approval_for_all[`++set_approval_for_all(self, operator, approved)++`]
+* xref:#ERC1155Component-is_approved_for_all[`++is_approved_for_all(self, owner, operator)++`]
+
+[.sub-index#ERC1155Component-Embeddable-Impls-ERC1155MetadataURIImpl]
+.ERC1155MetadataURIImpl
+* xref:#ERC1155Component-uri[`++uri(self, token_id)++`]
+--
+
+[.contract-index#ERC1155Component-Embeddable-Impls-camelCase]
+.Embeddable implementations (camelCase)
+--
+[.sub-index#ERC1155Component-Embeddable-Impls-ER1155CamelImpl]
+.ER1155CamelImpl
+* xref:#ERC1155Component-balanceOf[`++balanceOf(self, account, tokenId)++`]
+* xref:#ERC1155Component-balanceOfBatch[`++balanceOfBatch(self, accounts, tokenIds)++`]
+* xref:#ERC1155Component-safeTransferFrom[`++safeTransferFrom(self, from, to, tokenId, value, data)++`]
+* xref:#ERC1155Component-safeBatchTransferFrom[`++safeBatchTransferFrom(self, from, to, tokenIds, values, data)++`]
+* xref:#ERC1155Component-setApprovalForAll[`++setApprovalForAll(self, operator, approved)++`]
+* xref:#ERC1155Component-isApprovedForAll[`++isApprovedForAll(self, owner, operator)++`]
+--
+
+[.contract-index]
+.Internal Functions
+--
+.InternalImpl
+* xref:#ERC1155Component-initializer[`++initializer(self, base_uri)++`]
+* xref:#ERC1155Component-update[`++update(self, from, to, token_ids, values)++`]
+* xref:#ERC1155Component-update_with_acceptance_check[`++update_with_acceptance_check(self, from, to, token_ids, values, data)++`]
+* xref:#ERC1155Component-mint_with_acceptance_check[`++mint_with_acceptance_check(self, to, token_id, value, data)++`]
+* xref:#ERC1155Component-batch_mint_with_acceptance_check[`++batch_mint_with_acceptance_check(self, to, token_ids, values, data)++`]
+* xref:#ERC1155Component-burn[`++burn(self, from, token_id, value)++`]
+* xref:#ERC1155Component-batch_burn[`++batch_burn(self, from, token_ids, values)++`]
+* xref:#ERC1155Component-set_base_uri[`++set_base_uri(self, base_uri)++`]
+--
+
+[.contract-index]
+.Events
+--
+.IERC1155
+* xref:#ERC1155Component-TransferSingle[`++TransferSingle(operator, from, to, id, value)++`]
+* xref:#ERC1155Component-TransferBatch[`++TransferBatch(operator, from, to, ids, values)++`]
+* xref:#ERC1155Component-ApprovalForAll[`++ApprovalForAll(owner, operator, approved)++`]
+* xref:#ERC1155Component-URI[`++URI(value, id)++`]
+--
+
+==== Embeddable functions
+
+[.contract-item]
+[[ERC1155Component-balance_of]]
+==== `[.contract-item-name]#++balance_of++#++(self: @ContractState, account: ContractAddress, token_id: u256) → u256++` [.item-kind]#external#
+
+Returns the amount of `token_id` tokens owned by `account`.
+
+[.contract-item]
+[[ERC1155Component-balance_of_batch]]
+==== `[.contract-item-name]#++balance_of_batch++#++(self: @ContractState, accounts: Span, token_ids: Span) → Span++` [.item-kind]#external#
+
+Returns a list of balances derived from the `accounts` and `token_ids` pairs.
+
+Requirements:
+
+- `token_ids` and `accounts` must have the same length.
+
+[.contract-item]
+[[ERC1155Component-safe_transfer_from]]
+==== `[.contract-item-name]#++safe_transfer_from++#++(ref self: ContractState, from: ContractAddress, to: ContractAddress, token_id: u256, value: u256, data: Span)++` [.item-kind]#external#
+
+Transfers ownership of `value` amount of `token_id` from `from` if `to` is either an account or `IERC1155Receiver`.
+
+`data` is additional data, it has no specified format and it is passed to `to`.
+
+WARNING: This function can potentially allow a reentrancy attack when transferring tokens
+to an untrusted contract, when invoking `on_ERC1155_received` on the receiver.
+Ensure to follow the checks-effects-interactions pattern and consider employing
+reentrancy guards when interacting with untrusted contracts.
+
+Requirements:
+
+- Caller is either approved or the `token_id` owner.
+- `from` is not the zero address.
+- `to` is not the zero address.
+- If `to` refers to a non-account contract, it must implement `IERC1155Receiver::on_ERC1155_received`
+ and return the required magic value.
+
+Emits a <> event.
+
+[.contract-item]
+[[ERC1155Component-safe_batch_transfer_from]]
+==== `[.contract-item-name]#++safe_batch_transfer_from++#++(ref self: ContractState, from: ContractAddress, to: ContractAddress, token_ids: Span, values: Span, data: Span)++` [.item-kind]#external#
+
+Transfers ownership of `values` and `token_ids` pairs from `from` if `to` is either an account or `IERC1155Receiver`.
+
+`data` is additional data, it has no specified format and it is passed to `to`.
+
+WARNING: This function can potentially allow a reentrancy attack when transferring tokens
+to an untrusted contract, when invoking `on_ERC1155_batch_received` on the receiver.
+Ensure to follow the checks-effects-interactions pattern and consider employing
+reentrancy guards when interacting with untrusted contracts.
+
+Requirements:
+
+- Caller is either approved or the `token_id` owner.
+- `from` is not the zero address.
+- `to` is not the zero address.
+- `token_ids` and `values` must have the same length.
+- If `to` refers to a non-account contract, it must implement `IERC1155Receiver::on_ERC1155_batch_received`
+ and return the acceptance magic value.
+
+Emits a <> event if the arrays contain one element,
+and <> otherwise.
+
+[.contract-item]
+[[ERC1155Component-set_approval_for_all]]
+==== `[.contract-item-name]#++set_approval_for_all++#++(ref self: ContractState, operator: ContractAddress, approved: bool)++` [.item-kind]#external#
+
+Enables or disables approval for `operator` to manage all of the callers assets.
+
+Requirements:
+
+- `operator` cannot be the caller.
+
+Emits an <> event.
+
+[.contract-item]
+[[ERC1155Component-is_approved_for_all]]
+==== `[.contract-item-name]#++is_approved_for_all++#++(self: @ContractState, owner: ContractAddress, operator: ContractAddress) -> bool++` [.item-kind]#external#
+
+Queries if `operator` is an authorized operator for `owner`.
+
+[.contract-item]
+[[ERC1155Component-uri]]
+==== `[.contract-item-name]#++uri++#++(self: @ContractState, token_id: u256) -> ByteArray++` [.item-kind]#external#
+
+This implementation returns the same URI for *all* token types. It relies
+on the token type ID substitution mechanism
+{eip1155-metadata}[specified in the EIP].
+
+Clients calling this function must replace the `\{id\}` substring with the
+actual token type ID.
+
+==== camelCase Support
+
+[.contract-item]
+[[ERC1155Component-balanceOf]]
+==== `[.contract-item-name]#++balanceOf++#++(self: @ContractState, account: ContractAddress, tokenId: u256) → u256++` [.item-kind]#external#
+
+See <>.
+
+[.contract-item]
+[[ERC1155Component-balanceOfBatch]]
+==== `[.contract-item-name]#++balanceOfBatch++#++(self: @ContractState, accounts: Span, tokenIds: Span) → Span++` [.item-kind]#external#
+
+See <>.
+
+[.contract-item]
+[[ERC1155Component-safeTransferFrom]]
+==== `[.contract-item-name]#++safeTransferFrom++#++(ref self: ContractState, from: ContractAddress, to: ContractAddress, tokenId: u256, value: u256, data: Span)++` [.item-kind]#external#
+
+See <>.
+
+[.contract-item]
+[[ERC1155Component-safeBatchTransferFrom]]
+==== `[.contract-item-name]#++safeBatchTransferFrom++#++(ref self: ContractState, from: ContractAddress, to: ContractAddress, tokenIds: Span, values: Span, data: Span)++` [.item-kind]#external#
+
+See <>.
+
+[.contract-item]
+[[ERC1155Component-setApprovalForAll]]
+==== `[.contract-item-name]#++setApprovalForAll++#++(ref self: ContractState, operator: ContractAddress, approved: bool)++` [.item-kind]#external#
+
+See <>.
+
+[.contract-item]
+[[ERC1155Component-isApprovedForAll]]
+==== `[.contract-item-name]#++isApprovedForAll++#++(self: @ContractState, owner: ContractAddress, operator: ContractAddress) -> bool++` [.item-kind]#external#
+
+See <>.
+
+==== Internal functions
+
+[.contract-item]
+[[ERC1155Component-initializer]]
+==== `[.contract-item-name]#++initializer++#++(ref self: ContractState, base_uri: ByteArray)++` [.item-kind]#internal#
+
+Initializes the contract by setting the token's base URI as `base_uri`, and registering the supported interfaces.
+This should only be used inside the contract's constructor.
+
+[.contract-item]
+[[ERC1155Component-update]]
+==== `[.contract-item-name]#++update++#++(ref self: ContractState, from: ContractAddress, to: ContractAddress, token_ids: Span, values: Span)++` [.item-kind]#internal#
+
+Transfers a `value` amount of tokens of type `id` from `from` to `to`.
+Will mint (or burn) if `from` (or `to`) is the zero address.
+
+Requirements:
+
+- `token_ids` and `values` must have the same length.
+
+Emits a <> event if the arrays contain one element,
+and <> otherwise.
+
+NOTE: The ERC1155 acceptance check is not performed in this function.
+See <> instead.
+
+[.contract-item]
+[[ERC1155Component-update_with_acceptance_check]]
+==== `[.contract-item-name]#++update_with_acceptance_check++#++(ref self: ContractState, from: ContractAddress, to: ContractAddress, token_ids: Span, values: Span, data: Span)++` [.item-kind]#internal#
+
+Version of `update` that performs the token acceptance check by calling
+`onERC1155Received` or `onERC1155BatchReceived` in the receiver if
+it implements `IERC1155Receiver`, otherwise by checking if it is an account.
+
+Requirements:
+
+- `to` is either an account contract or supports the `IERC1155Receiver` interface.
+- `token_ids` and `values` must have the same length.
+
+Emits a <> event if the arrays contain one element,
+and <> otherwise.
+
+[.contract-item]
+[[ERC1155Component-mint_with_acceptance_check]]
+==== `[.contract-item-name]#++mint_with_acceptance_check++#++(ref self: ContractState, to: ContractAddress, token_id: u256, value: u256, data: Span)++` [.item-kind]#internal#
+
+Creates a `value` amount of tokens of type `token_id`, and assigns them to `to`.
+
+Requirements:
+
+- `to` cannot be the zero address.
+- If `to` refers to a smart contract, it must implement `IERC1155Receiver::on_ERC1155_received`
+and return the acceptance magic value.
+
+Emits a <> event.
+
+[.contract-item]
+[[ERC1155Component-batch_mint_with_acceptance_check]]
+==== `[.contract-item-name]#++batch_mint_with_acceptance_check++#++(ref self: ContractState, to: ContractAddress, token_ids: Span, values: Span, data: Span)++` [.item-kind]#internal#
+
+Batched version of <>.
+
+Requirements:
+
+- `to` cannot be the zero address.
+- `token_ids` and `values` must have the same length.
+- If `to` refers to a smart contract, it must implement `IERC1155Receiver::on_ERC1155_batch_received`
+and return the acceptance magic value.
+
+Emits a <> event.
+
+[.contract-item]
+[[ERC1155Component-burn]]
+==== `[.contract-item-name]#++burn++#++(ref self: ContractState, from: ContractAddress, token_id: u256, value: u256)++` [.item-kind]#internal#
+
+Destroys a `value` amount of tokens of type `token_id` from `from`.
+
+Requirements:
+
+- `from` cannot be the zero address.
+- `from` must have at least `value` amount of tokens of type `token_id`.
+
+Emits a <> event.
+
+[.contract-item]
+[[ERC1155Component-batch_burn]]
+==== `[.contract-item-name]#++batch_burn++#++(ref self: ContractState, from: ContractAddress, token_ids: Span, values: Span)++` [.item-kind]#internal#
+
+Batched version of <>.
+
+Requirements:
+
+- `from` cannot be the zero address.
+- `from` must have at least `value` amount of tokens of type `token_id`.
+- `token_ids` and `values` must have the same length.
+
+Emits a <> event.
+
+[.contract-item]
+[[ERC1155Component-set_base_uri]]
+==== `[.contract-item-name]#++set_base_uri++#++(ref self: ContractState, base_uri: ByteArray)++` [.item-kind]#internal#
+
+Sets a new URI for all token types, by relying on the token type ID
+substitution mechanism
+{eip1155-metadata}[specified in the EIP].
+
+By this mechanism, any occurrence of the `\{id\}` substring in either the
+URI or any of the values in the JSON file at said URI will be replaced by
+clients with the token type ID.
+
+For example, the pass:[https://token-cdn-domain/\{id\}.json] URI would be
+interpreted by clients as
+pass:[https://token-cdn-domain/000000000000...000000000000004cce0.json]
+for token type ID `0x4cce0`.
+
+Because these URIs cannot be meaningfully represented by the `URI` event,
+this function emits no events.
+
+==== Events
+
+[.contract-item]
+[[ERC1155Component-TransferSingle]]
+==== `[.contract-item-name]#++TransferSingle++#++(operator: ContractAddress, from: ContractAddress, to: ContractAddress, id: u256, value: u256)++` [.item-kind]#event#
+
+See <>.
+
+[.contract-item]
+[[ERC1155Component-TransferBatch]]
+==== `[.contract-item-name]#++TransferBatch++#++(operator: ContractAddress, from: ContractAddress, to: ContractAddress, ids: Span, values: Span)++` [.item-kind]#event#
+
+See <>.
+
+[.contract-item]
+[[ERC1155Component-ApprovalForAll]]
+==== `[.contract-item-name]#++ApprovalForAll++#++(owner: ContractAddress, operator: ContractAddress, approved: bool)++` [.item-kind]#event#
+
+See <>.
+
+[.contract-item]
+[[ERC1155Component-URI]]
+==== `[.contract-item-name]#++URI++#++(value: ByteArray, id: u256)++` [.item-kind]#event#
+
+See <>.
+
+== Receiver
+
+[.contract]
+[[IERC1155Receiver]]
+=== `++IERC1155Receiver++` link:https://github.com/OpenZeppelin/cairo-contracts/blob/release-v0.9.0/src/token/erc1155/interface.cairo[{github-icon},role=heading-link]
+
+[.hljs-theme-dark]
+```javascript
+use openzeppelin::token::erc1155::interface::IERC1155Receiver;
+```
+
+Interface for contracts that support receiving token transfers from `ERC1155` contracts.
+
+[.contract-index]
+.{inner-src5}
+--
+0x15e8665b5af20040c3af1670509df02eb916375cdf7d8cbaf7bd553a257515e
+--
+
+[.contract-index]
+.Functions
+--
+* xref:#IERC1155Receiver-on_erc1155_received[`++on_erc1155_received(operator, from, token_id, value, data)++`]
+* xref:#IERC1155Receiver-on_erc1155_batch_received[`++on_erc1155_batch_received(operator, from, token_ids, values, data)++`]
+--
+
+==== Functions
+
+[.contract-item]
+[[IERC1155Receiver-on_erc1155_received]]
+==== `[.contract-item-name]#++on_erc1155_received++#++(operator: ContractAddress, from: ContractAddress, token_id: u256, value: u256, data Span) -> felt252++` [.item-kind]#external#
+
+This function is called whenever an ERC1155 `token_id` token is transferred to this `IERC1155Receiver` implementer
+via <> by `operator` from `from`.
+
+[.contract-item]
+[[IERC1155Receiver-on_erc1155_batch_received]]
+==== `[.contract-item-name]#++on_erc1155_batch_received++#++(operator: ContractAddress, from: ContractAddress, token_ids: Span, values: Span, data Span) -> felt252++` [.item-kind]#external#
+
+This function is called whenever multiple ERC1155 `token_ids` tokens are transferred to this `IERC1155Receiver` implementer
+via <> by `operator` from `from`.
+
+[.contract]
+[[ERC1155ReceiverComponent]]
+=== `++ERC1155ReceiverComponent++` link:https://github.com/OpenZeppelin/cairo-contracts/blob/release-v0.9.0/src/token/erc1155/erc1155_receiver.cairo[{github-icon},role=heading-link]
+
+[.hljs-theme-dark]
+```javascript
+use openzeppelin::token::erc1155::ERC1155ReceiverComponent;
+```
+
+ERC1155Receiver component implementing <>.
+
+NOTE: {src5-component-required-note}
+
+[.contract-index#ERC1155ReceiverComponent-Embeddable-Impls]
+.Embeddable Implementations
+--
+.ERC1155ReceiverImpl
+* xref:#ERC1155ReceiverComponent-on_erc1155_received[`++on_erc1155_received(self, operator, from, token_id, value, data)++`]
+* xref:#ERC1155ReceiverComponent-on_erc1155_batch_received[`++on_erc1155_batch_received(self, operator, from, token_ids, values, data)++`]
+--
+
+[.contract-index#ERC1155ReceiverComponent-Embeddable-Impls-camelCase]
+.Embeddable implementations (camelCase)
+--
+.ERC1155ReceiverCamelImpl
+* xref:#ERC1155ReceiverComponent-onERC1155Received[`++onERC1155Received(self, operator, from, tokenId, value, data)++`]
+* xref:#ERC1155ReceiverComponent-onERC1155BatchReceived[`++onERC1155BatchReceived(self, operator, from, tokenIds, values, data)++`]
+--
+
+[.contract-index]
+.Internal Functions
+--
+.InternalImpl
+* xref:#ERC1155ReceiverComponent-initializer[`++initializer(self)++`]
+--
+
+==== Embeddable functions
+
+[.contract-item]
+[[ERC1155ReceiverComponent-on_erc1155_received]]
+==== `[.contract-item-name]#++on_erc1155_received++#++(operator: ContractAddress, from: ContractAddress, token_id: u256, value: u256, data Span) -> felt252++` [.item-kind]#external#
+
+Returns the `IERC1155Receiver` interface ID.
+
+[.contract-item]
+[[ERC1155ReceiverComponent-on_erc1155_batch_received]]
+==== `[.contract-item-name]#++on_erc1155_batch_received++#++(operator: ContractAddress, from: ContractAddress, token_ids: Span, values: Span, data Span) -> felt252++` [.item-kind]#external#
+
+Returns the `IERC1155Receiver` interface ID.
+
+==== camelCase Support
+
+
+[.contract-item]
+[[ERC1155ReceiverComponent-onERC1155Received]]
+==== `[.contract-item-name]#++onERC1155Received++#++(operator: ContractAddress, from: ContractAddress, token_id: u256, value: u256, data Span) -> felt252++` [.item-kind]#external#
+
+See <>.
+
+[.contract-item]
+[[ERC1155ReceiverComponent-onERC1155BatchReceived]]
+==== `[.contract-item-name]#++onERC1155BatchReceived++#++(operator: ContractAddress, from: ContractAddress, token_ids: Span, values: Span, data Span) -> felt252++` [.item-kind]#external#
+
+See <>.
+
+==== Internal functions
+
+[.contract-item]
+[[ERC1155ReceiverComponent-initializer]]
+==== `[.contract-item-name]#++initializer++#++(ref self: ContractState)++` [.item-kind]#internal#
+
+Registers the `IERC1155Receiver` interface ID as supported through introspection.
+
+== Presets
+
+[.contract]
+[[ERC1155]]
+=== `++ERC1155++` link:https://github.com/OpenZeppelin/cairo-contracts/blob/release-v0.9.0/src/presets/erc1155.cairo[{github-icon},role=heading-link]
+
+```javascript
+use openzeppelin::presets::ERC1155;
+```
+
+Basic ERC1155 contract leveraging xref:#ERC1155Component[ERC1155Component].
+
+include::../utils/_class_hashes.adoc[]
+
+[.contract-index]
+.{presets-page}
+--
+{ERC1155-class-hash}
+--
+
+[.contract-index]
+.Constructor
+--
+* xref:#ERC1155-constructor[`++constructor(self, base_uri, recipient, token_ids, values)++`]
+--
+
+[.contract-index]
+.Embedded Implementations
+--
+.ERC1155Component
+
+* xref:#ERC1155Component-Embeddable-Impls-ERC1155Impl[`++ERC1155Impl++`]
+* xref:#ERC1155Component-Embeddable-Impls-ERC1155MetadataURIImpl[`++ERC1155MetadataURIImpl++`]
+* xref:#ERC1155Component-Embeddable-Impls-ER1155CamelImpl[`++ERC1155CamelImpl++`]
+
+.SRC5Component
+
+* xref:api/introspection.adoc#SRC5Component-Embeddable-Impls-SRC5Impl[`++SRC5Impl++`]
+--
+
+[#ERC1155-constructor-section]
+==== Constructor
+
+[.contract-item]
+[[ERC1155-constructor]]
+==== `[.contract-item-name]#++constructor++#++(ref self: ContractState, base_uri: ByteArray, recipient: ContractAddress, token_ids: Span, values: Span)++` [.item-kind]#constructor#
+
+Sets the `base_uri` for all tokens and registers the supported interfaces.
+Mints the `values` for `token_ids` tokens to `recipient`.
+
+Requirements:
+
+- `to` is either an account contract (supporting ISRC6) or
+ supports the `IERC1155Receiver` interface.
+- `token_ids` and `values` must have the same length.
diff --git a/docs/modules/ROOT/pages/api/erc20.adoc b/docs/modules/ROOT/pages/api/erc20.adoc
index 2cdd32622..9f18c1d16 100644
--- a/docs/modules/ROOT/pages/api/erc20.adoc
+++ b/docs/modules/ROOT/pages/api/erc20.adoc
@@ -3,10 +3,11 @@
:erc20-guide: xref:erc20.adoc[ERC20 guide]
:casing-discussion: https://github.com/OpenZeppelin/cairo-contracts/discussions/34[here]
:custom-decimals: xref:/erc20.adoc#customizing_decimals[Customizing decimals]
-:mixin-impl: xref:components.adoc#mixins[Embeddable Mixin Implementation]
= ERC20
+include::../utils/_common.adoc[]
+
Reference of interfaces and utilities related to ERC20 contracts.
TIP: For an overview of ERC20, read our {erc20-guide}.
@@ -170,7 +171,7 @@ use openzeppelin::token::erc20::ERC20Component;
ERC20 component extending <> and <>.
[.contract-index#ERC20Component-Embeddable-Mixin-Impl]
-.{mixin-impl}
+.{mixin-impls}
--
.ERC20MixinImpl
diff --git a/docs/modules/ROOT/pages/api/erc721.adoc b/docs/modules/ROOT/pages/api/erc721.adoc
index dc9088402..321e1634d 100644
--- a/docs/modules/ROOT/pages/api/erc721.adoc
+++ b/docs/modules/ROOT/pages/api/erc721.adoc
@@ -3,10 +3,11 @@
:receiving-tokens: xref:/erc721.adoc#receiving_tokens[Receiving Tokens]
:casing-discussion: https://github.com/OpenZeppelin/cairo-contracts/discussions/34[here]
:inner-src5: xref:api/introspection.adoc#ISRC5[SRC5 ID]
-:mixin-impl: xref:components.adoc#mixins[Embeddable Mixin Implementation]
= ERC721
+include::../utils/_common.adoc[]
+
Reference of interfaces, presets, and utilities related to ERC721 contracts.
TIP: For an overview of ERC721, read our xref:erc721.adoc[ERC721 guide].
@@ -15,7 +16,7 @@ TIP: For an overview of ERC721, read our xref:erc721.adoc[ERC721 guide].
[.contract]
[[IERC721]]
-=== `++IERC721++` link:https://github.com/OpenZeppelin/cairo-contracts/blob/cairo-2/src/token/erc721/interface.cairo#L13-L31[{github-icon},role=heading-link]
+=== `++IERC721++` link:https://github.com/OpenZeppelin/cairo-contracts/blob/release-v0.9.0/src/token/erc721/interface.cairo#L13-L31[{github-icon},role=heading-link]
[.hljs-theme-dark]
```javascript
@@ -98,7 +99,7 @@ Emits an <> event.
Enable or disable approval for `operator` to manage all of the caller's assets.
-Emits an <> event.
+Emits an <> event.
[.contract-item]
[[IERC721-get_approved]]
@@ -124,7 +125,7 @@ Emitted when `owner` enables `approved` to manage the `token_id` token.
[[IERC721-ApprovalForAll]]
==== `[.contract-item-name]#++ApprovalForAll++#++(owner: ContractAddress, operator: ContractAddress, approved: bool)++` [.item-kind]#event#
-Emitted when `owner` enables `approved` to manage the `token_id` token.
+Emitted when `owner` enables or disables `operator` to manage the `token_id` token.
[.contract-item]
[[IERC721-Transfer]]
@@ -134,7 +135,7 @@ Emitted when `token_id` token is transferred from `from` to `to`.
[.contract]
[[IERC721Metadata]]
-=== `++IERC721Metadata++` link:https://github.com/OpenZeppelin/cairo-contracts/blob/cairo-2/src/token/erc721/interface.cairo#L54-L59[{github-icon},role=heading-link]
+=== `++IERC721Metadata++` link:https://github.com/OpenZeppelin/cairo-contracts/blob/release-v0.9.0/src/token/erc721/interface.cairo#L54-L59[{github-icon},role=heading-link]
[.hljs-theme-dark]
```javascript
@@ -180,7 +181,7 @@ If the URI is not set for `token_id`, the return value will be an empty `ByteArr
[.contract]
[[ERC721Component]]
-=== `++ERC721Component++` link:https://github.com/OpenZeppelin/cairo-contracts/blob/cairo-2/src/token/erc721/erc721.cairo#L7[{github-icon},role=heading-link]
+=== `++ERC721Component++` link:https://github.com/OpenZeppelin/cairo-contracts/blob/release-v0.9.0/src/token/erc721/erc721.cairo#L7[{github-icon},role=heading-link]
[.hljs-theme-dark]
```javascript
@@ -189,10 +190,10 @@ use openzeppelin::token::erc721::ERC721Component;
ERC721 component implementing <> and <>.
-NOTE: Implementing xref:api/introspection.adoc#SRC5Component[SRC5Component] is a requirement for this component to be implemented.
+NOTE: {src5-component-required-note}
[.contract-index#ERC721Component-Embeddable-Mixin-Impl]
-.{mixin-impl}
+.{mixin-impls}
--
.ERC721MixinImpl
@@ -590,7 +591,7 @@ See <>.
[.contract]
[[IERC721Receiver]]
-=== `++IERC721Receiver++` link:https://github.com/OpenZeppelin/cairo-contracts/blob/cairo-2/src/token/erc721/interface.cairo#L70-L79[{github-icon},role=heading-link]
+=== `++IERC721Receiver++` link:https://github.com/OpenZeppelin/cairo-contracts/blob/release-v0.9.0/src/token/erc721/interface.cairo#L70-L79[{github-icon},role=heading-link]
[.hljs-theme-dark]
```javascript
diff --git a/docs/modules/ROOT/pages/api/introspection.adoc b/docs/modules/ROOT/pages/api/introspection.adoc
index f4742d94d..16dbdc193 100644
--- a/docs/modules/ROOT/pages/api/introspection.adoc
+++ b/docs/modules/ROOT/pages/api/introspection.adoc
@@ -55,6 +55,7 @@ SRC5 component extending xref:ISRC5[`ISRC5`].
[.contract-index#SRC5Component-Embeddable-Impls]
.Embeddable Implementations
--
+[.sub-index#SRC5Component-Embeddable-Impls-SRC5Impl]
.SRC5Impl
* xref:#SRC5Component-supports_interface[`++supports_interface(self, interface_id)++`]
diff --git a/docs/modules/ROOT/pages/erc1155.adoc b/docs/modules/ROOT/pages/erc1155.adoc
index 19e0b5566..3889c042f 100644
--- a/docs/modules/ROOT/pages/erc1155.adoc
+++ b/docs/modules/ROOT/pages/erc1155.adoc
@@ -1,548 +1,277 @@
-= ERC1155
-
-The ERC1155 multi token standard is a specification for https://docs.openzeppelin.com/contracts/4.x/tokens#different-kinds-of-tokens[fungibility-agnostic] token contracts.
-The ERC1155 library implements an approximation of https://eips.ethereum.org/EIPS/eip-1155[EIP-1155] in Cairo for StarkNet.
-
-== Table of Contents
-
-* <>
-* <>
-* <>
- ** <>
- ** <>
- ** <>
-* <>
-* <>
- ** <>
-* <>
- ** <>
- ** <>
- ** <>
- ** <>
-
-== IERC1155
-
-[,cairo]
-----
-@contract_interface
-namespace IERC1155 {
- func balanceOf(account: felt, id: Uint256) -> (balance: Uint256) {
- }
-
- func balanceOfBatch(
- accounts_len: felt,
- accounts: felt*,
- ids_len: felt,
- ids: Uint256*
- ) -> (
- balances_len: felt,
- balances: Uint256*
- ) {
- }
-
- func isApprovedForAll(
- account: felt,
- operator: felt
- ) -> (approved: felt) {
- }
-
- func setApprovalForAll(operator: felt, approved: felt) {
- }
+:eip-1155: https://eips.ethereum.org/EIPS/eip-1155[EIP-1155]
+:fungibility-agnostic: https://docs.openzeppelin.com/contracts/5.x/tokens#different-kinds-of-tokens[fungibility-agnostic]
- func safeTransferFrom(
- from_: felt,
- to: felt,
- id: Uint256,
- value: Uint256,
- data_len: felt,
- data: felt*
- ) {
- }
-
- func safeBatchTransferFrom(
- from_: felt,
- to: felt,
- ids_len: felt,
- ids: Uint256*,
- values_len: felt,
- values: Uint256*,
- data_len: felt,
- data: felt*,
- ) {
- }
-
- --------------- IERC165 ---------------
+= ERC1155
- func supportsInterface(interfaceId: felt) -> (success: felt) {
- }
+The ERC1155 multi token standard is a specification for {fungibility-agnostic} token contracts.
+The ERC1155 library implements an approximation of {eip-1155} in Cairo for StarkNet.
+
+== Multi Token Standard
+
+:balance_of-api: xref:api/erc1155.adoc#IERC1155-balance_of[balance_of]
+:erc721-balance_of-api: xref:api/erc721.adoc#IERC721-balance_of[balance_of]
+
+The distinctive feature of ERC1155 is that it uses a single smart contract to represent multiple tokens at once. This
+is why its {balance_of-api} function differs from ERC20’s and ERC777’s: it has an additional ID argument for the
+identifier of the token that you want to query the balance of.
+
+This is similar to how ERC721 does things, but in that standard a token ID has no concept of balance: each token is
+non-fungible and exists or doesn’t. The ERC721 {erc721-balance_of-api} function refers to how many different tokens an account
+has, not how many of each. On the other hand, in ERC1155 accounts have a distinct balance for each token ID, and
+non-fungible tokens are implemented by simply minting a single one of them.
+
+This approach leads to massive gas savings for projects that require multiple tokens. Instead of deploying a new
+contract for each token type, a single ERC1155 token contract can hold the entire system state, reducing deployment
+costs and complexity.
+
+== Interface
+
+:compatibility: xref:/erc1155.adoc#erc1155_compatibility[ERC1155 Compatibility]
+:isrc5-interface: xref:/api/introspection.adoc#ISRC5[ISRC5]
+:ierc1155-interface: xref:/api/erc1155.adoc#IERC1155[IERC1155]
+:ierc1155metadata-interface: xref:/api/erc1155.adoc#IERC1155MetadataURI[IERC1155MetadataURI]
+:erc1155-component: xref:/api/erc1155.adoc#ERC1155Component[ERC1155Component]
+:dual-interfaces: xref:interfaces.adoc#dual_interfaces[Dual interfaces]
+
+The following interface represents the full ABI of the Contracts for Cairo {erc1155-component}.
+The interface includes the {ierc1155-interface} standard interface and the optional {ierc1155metadata-interface} interface together with {isrc5-interface}.
+
+To support older token deployments, as mentioned in {dual-interfaces}, the component also includes implementations of the interface written in camelCase.
+
+[,javascript]
+----
+trait ERC1155ABI {
+ // IERC1155
+ fn balance_of(account: ContractAddress, token_id: u256) -> u256;
+ fn balance_of_batch(
+ accounts: Span, token_ids: Span
+ ) -> Span;
+ fn safe_transfer_from(
+ from: ContractAddress,
+ to: ContractAddress,
+ token_id: u256,
+ value: u256,
+ data: Span
+ );
+ fn safe_batch_transfer_from(
+ from: ContractAddress,
+ to: ContractAddress,
+ token_ids: Span,
+ values: Span,
+ data: Span
+ );
+ fn is_approved_for_all(
+ owner: ContractAddress, operator: ContractAddress
+ ) -> bool;
+ fn set_approval_for_all(operator: ContractAddress, approved: bool);
+
+ // IERC1155MetadataURI
+ fn uri(token_id: u256) -> ByteArray;
+
+ // ISRC5
+ fn supports_interface(interface_id: felt252) -> bool;
+
+ // IERC1155Camel
+ fn balanceOf(account: ContractAddress, tokenId: u256) -> u256;
+ fn balanceOfBatch(
+ accounts: Span, tokenIds: Span
+ ) -> Span;
+ fn safeTransferFrom(
+ from: ContractAddress,
+ to: ContractAddress,
+ tokenId: u256,
+ value: u256,
+ data: Span
+ );
+ fn safeBatchTransferFrom(
+ from: ContractAddress,
+ to: ContractAddress,
+ tokenIds: Span,
+ values: Span,
+ data: Span
+ );
+ fn isApprovedForAll(owner: ContractAddress, operator: ContractAddress) -> bool;
+ fn setApprovalForAll(operator: ContractAddress, approved: bool);
}
----
=== ERC1155 Compatibility
-Although StarkNet is not EVM compatible, this implementation aims to be as close as possible to the ERC1155 standard in the following ways:
-
-* It uses Cairo's `uint256` instead of `felt`.
-* It returns `TRUE` as success.
-
-But some differences can still be found, such as:
+Although Starknet is not EVM compatible, this implementation aims to be as close as possible to the ERC1155 standard but some differences can still be found, such as:
-* It implements an `uri()` function that returns the same URI for *all* token types. It relies on the token type ID substitution mechanism https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP]. Clients calling this function must replace the `\{id\}` substring with the actual token type ID.
-* `safeTransferFrom` and `safeBatchTransferFrom` are specified such that the optional `data` argument should be of type bytes.
-In Solidity, this means a dynamically-sized array.
-To be as close as possible to the standard, the `data` argument accepts a dynamic array of felts.
-In Cairo, arrays are expressed with the array length preceding the actual array;
-hence, the method accepts `data_len` and `data` respectively as types `felt` and `felt*`.
-* `IERC1155Receiver` compliant contracts (`ERC1155Holder`) return a hardcoded selector id according to EVM selectors, since selectors are calculated differently in Cairo.
-This is in line with the ERC165 interfaces design choice towards EVM compatibility.
-See the xref:introspection.adoc[Introspection docs] for more info.
-* `IERC1155Receiver` compliant contracts (`ERC1155Holder`) must support ERC165 by registering the `IERC1155Receiver` selector id in its constructor and exposing the `supportsInterface` method.
-In doing so, recipient contracts (both accounts and non-accounts) can be verified that they support ERC1155 transfers.
+* The optional `data` argument in both `safe_transfer_from` and `safe_batch_transfer_from` is implemented as `Span`.
+* `IERC1155Receiver` compliant contracts must implement SRC5 and register the `IERC1155Receiver` interface ID.
+* `IERC1155Receiver::on_erc1155_received` must return that interface ID on success.
== Usage
-To show a standard use case, we'll use the `ERC1155MintableBurnable` preset which allows for only the owner to `mint` tokens.
-To create a token, you need to first deploy both Account and ERC1155 contracts respectively.
+Using Contracts for Cairo, constructing an ERC1155 contract requires integrating both `ERC1155Component` and `SRC5Component`.
+The contract should also set up the constructor to initialize the token's URI and interface support.
+Here's an example of a basic contract:
+
+[,javascript]
+----
+#[starknet::contract]
+mod MyERC1155 {
+ use openzeppelin::introspection::src5::SRC5Component;
+ use openzeppelin::token::erc1155::ERC1155Component;
+ use starknet::ContractAddress;
+
+ component!(path: ERC1155Component, storage: erc1155, event: ERC1155Event);
+ component!(path: SRC5Component, storage: src5, event: SRC5Event);
+
+ // ERC1155
+ #[abi(embed_v0)]
+ impl ERC1155Impl = ERC1155Component::ERC1155Impl;
+ #[abi(embed_v0)]
+ impl ERC1155MetadataURIImpl =
+ ERC1155Component::ERC1155MetadataURIImpl;
+ #[abi(embed_v0)]
+ impl ERC1155Camel = ERC1155Component::ERC1155CamelImpl;
+ impl ERC1155InternalImpl = ERC1155Component::InternalImpl;
+
+ // SRC5
+ #[abi(embed_v0)]
+ impl SRC5Impl = SRC5Component::SRC5Impl;
+
+ #[storage]
+ struct Storage {
+ #[substorage(v0)]
+ erc1155: ERC1155Component::Storage,
+ #[substorage(v0)]
+ src5: SRC5Component::Storage
+ }
-Considering that the ERC1155 constructor method looks like this:
+ #[event]
+ #[derive(Drop, starknet::Event)]
+ enum Event {
+ #[flat]
+ ERC1155Event: ERC1155Component::Event,
+ #[flat]
+ SRC5Event: SRC5Component::Event
+ }
-[,cairo]
-----
-func constructor(
- uri: felt, // Token URI as Cairo short string
- owner: felt // Address designated as the contract owner
-) {
+ #[constructor]
+ fn constructor(
+ ref self: ContractState,
+ token_uri: ByteArray,
+ recipient: ContractAddress,
+ token_ids: Span,
+ values: Span
+ ) {
+ self.erc1155.initializer(token_uri);
+ self
+ .erc1155
+ .batch_mint_with_acceptance_check(recipient, token_ids, values, array![].span());
+ }
}
----
-Deployment of both contracts looks like this:
+=== Batch operations
-[,python]
-----
-account = await starknet.deploy(
- "contracts/Account.cairo",
- constructor_calldata=[signer.public_key]
-)
-
-erc1155 = await starknet.deploy(
- "contracts/token/erc1155/presets/ERC1155MintableBurnable.cairo",
- constructor_calldata=[
- str_to_felt("http://my.uri/{id}"), # uri
- account.contract_address # owner
- ]
-)
-----
-
-To mint tokens, send a transaction like this:
-
-[,python]
-----
-signer = MockSigner(PRIVATE_KEY)
-token_id = uint(1)
-mint_value = uint(1000)
-
-await signer.send_transaction(
- account, erc1155.contract_address, 'mint', [
- recipient_address,
- *token_id,
- *mint_value,
- 0 # data
- ]
-)
-----
+:safe_transfer_from: xref:/api/erc1155.adoc#IERC1155-safe_transfer_from[safe_transfer_from]
+:balance_of_batch: xref:/api/erc1155.adoc#IERC1155-balance_of_batch[balance_of_batch]
+:safe_batch_transfer_from: xref:/api/erc1155.adoc#IERC1155-safe_batch_transfer_from[safe_batch_transfer_from]
+:batch_mint_with_acceptance_check: xref:/api/erc1155.adoc#ERC1155Component-batch_mint_with_acceptance_check[batch_mint_with_acceptance_check]
-=== Token Transfers
+Because all state is held in a single contract, it is possible to operate over multiple tokens in a single transaction very efficiently. The standard provides two functions, {balance_of_batch} and {safe_batch_transfer_from}, that make querying multiple balances and transferring multiple tokens simpler and less gas-intensive. We also have {safe_transfer_from} for non-batch operations.
-This library includes `safeTransferFrom` and `safeBatchTransferFrom` to transfer assets. These methods incorporate the following conditional logic:
+In the spirit of the standard, we’ve also included batch operations in the non-standard functions, such as
+{batch_mint_with_acceptance_check}.
-. If the receiving address xref:accounts.adoc#account_introspection_with_erc165[is identified as an account], the tokens will be transferred.
-. If the receiving address is not an account contract, the function will check that the receiver supports ERC1155 tokens before sending them.
+WARNING: While {safe_transfer_from} and {safe_batch_transfer_from} prevent loss by checking the receiver can handle the
+tokens, this yields execution to the receiver which can result in a xref:security.adoc#reentrancy_guard[reentrant call].
-The current implementation requires recipient contracts to support ERC165 and expose the `supportsInterface` method.
-See <>.
+=== Receiving tokens
-=== Interpreting ERC1155 URIs
+:src5: xref:introspection.adoc#src5[SRC5]
+:on_erc1155_received: xref:/api/erc1155.adoc#IERC1155Receiver-on_erc1155_received[on_erc1155_received]
+:on_erc1155_batch_received: xref:/api/erc1155.adoc#IERC1155Receiver-on_erc1155_batch_received[on_erc1155_batch_received]
+:computing-interface-id: xref:introspection.adoc#computing_the_interface_id[Computing the interface ID]
-Token URIs in Cairo are stored as single field elements.
-Each field element equates to 252-bits (or 31.5 bytes) which means that a token's URI can be no longer than 31 characters.
+In order to be sure a non-account contract can safely accept ERC1155 tokens, said contract must implement the `IERC1155Receiver` interface.
+The recipient contract must also implement the {src5} interface which supports interface introspection.
-NOTE: Storing the URI as an array of felts was considered to accommodate larger strings.
-While this approach is more flexible regarding URIs, a returned array further deviates from the standard. Therefore, this library's ERC1155 implementation sets URIs as a single field element.
+==== IERC1155Receiver
-The `utils.py` module includes utility methods for converting to/from Cairo field elements.
-To properly interpret a URI from ERC1155, simply trim the null bytes and decode the remaining bits as an ASCII string.
-For example:
+:receiver-id: xref:/api/erc1155.adoc#IERC1155Receiver[IERC1155Receiver interface ID]
-[,python]
+[,javascript]
----
-# HELPER METHODS
-def str_to_felt(text):
- b_text = bytes(text, 'ascii')
- return int.from_bytes(b_text, "big")
-
-def felt_to_str(felt):
- b_felt = felt.to_bytes(31, "big")
- return b_felt.decode()
-
-token_id = uint(1)
-sample_uri = str_to_felt('mock://mytoken')
-
-await signer.send_transaction(
- account, erc1155.contract_address, 'setTokenURI', [
- *token_id, sample_uri]
-)
-
-felt_uri = await erc1155.tokenURI(first_token_id).call()
-string_uri = felt_to_str(felt_uri)
-----
-
-=== ERC1155Received
-
-In order to be sure a contract can safely accept ERC1155 tokens, said contract must implement the <> interface (as expressed in the EIP1155 specification).
-Methods such as `safeTransferFrom` and `safeBatchTransferFrom` call the recipient contract's `onERC1155Received` or `onERC1155BatchReceived` method.
-If the contract fails to return the correct magic value, the transaction fails.
-
-StarkNet contracts that support safe transfers, however, must also support xref:introspection.adoc#erc165[ERC165] and include `supportsInterface` as proposed in https://github.com/OpenZeppelin/cairo-contracts/discussions/100[#100].
-Transfer functions require a means of differentiating between account and non-account contracts.
-Currently, StarkNet does not support error handling from the contract level;
-therefore, the current ERC1155 implementation requires that all contracts that support safe ERC1155 transfers (both accounts and non-accounts) include the `supportsInterface` method.
-Further, `supportsInterface` should return `TRUE` if the recipient contract supports the `IERC1155Receiver` magic value `00x4e2312e0` (which invokes `onERC1155Received` and `onERC1155BatchReceived`).
-If the recipient contract supports the `IAccount` magic value, `supportsInterface` should return `TRUE`.
-Otherwise, transfer functions should fail.
-
-== Presets
-
-=== ERC1155MintableBurnable
-
-The https://github.com/OpenZeppelin/cairo-contracts/blob/release-v0.6.1/src/openzeppelin/token/erc1155/presets/ERC1155MintableBurnable.cairo[`ERC1155MintableBurnable`] preset offers a quick and easy setup for creating ERC1155 tokens. Its constructor takes three arguments: `name`, `symbol`, and an `owner` address which will be capable of minting tokens.
-
-== Utilities
-
-=== ERC1155Holder
-
-Implementation of the `IERC1155Receiver` interface.
-
-Accepts all token transfers.
-Make sure the contract is able to use its token with `IERC1155.safeTransferFrom`, `IERC1155.approve` or `IERC1155.setApprovalForAll`.
-
-Also utilizes the ERC165 method `supportsInterface` to determine if the contract is an account.
-See <>.
-
-== API Specification
-
-=== IERC1155 API
-
-[,cairo]
-----
-func balanceOf(account: felt, id: Uint256) -> (balance: Uint256) {
+trait IERC1155Receiver {
+ fn on_erc1155_received(
+ operator: ContractAddress,
+ from: ContractAddress,
+ token_id: u256,
+ value: u256,
+ data: Span
+ ) -> felt252;
+ fn on_erc1155_batch_received(
+ operator: ContractAddress,
+ from: ContractAddress,
+ token_ids: Span,
+ values: Span,
+ data: Span
+ ) -> felt252;
}
-
-func balanceOfBatch(
- accounts_len: felt,
- accounts: felt*,
- ids_len: felt,
- ids: Uint256*
-) -> (
- balances_len: felt,
- balances: Uint256*
-) {
-}
-
-func isApprovedForAll(account: felt, operator: felt) -> (approved: felt) {
-}
-
-func setApprovalForAll(operator: felt, approved: felt) {
-}
-
-func safeTransferFrom(
- from_: felt,
- to: felt,
- id: Uint256,
- value: Uint256,
- data_len: felt,
- data: felt*
-) {
-}
-
-func safeBatchTransferFrom(
- from_: felt,
- to: felt,
- ids_len: felt,
- ids: Uint256*,
- values_len: felt,
- values: Uint256*,
- data_len: felt,
- data: felt*,
-) {
-}
-----
-
-==== `balanceOf`
-
-Returns the number of `id` tokens of ``account``.
-
-Parameters:
-
-[,cairo]
-----
-account: felt
-id: Uint256
-----
-
-Returns:
-
-[,cairo]
-----
-balance: Uint256
-----
-
-==== `balanceOfBatch`
-
-Get the balance of multiple account/token pairs.
-
-Parameters:
-
-[,cairo]
-----
-accounts_len: felt
-accounts: felt*
-ids_len: felt
-ids: Uint156*
-----
-
-Returns:
-
-[,cairo]
-----
-balances_len: felt
-balances: Uint256*
-----
-
-==== `isApprovedForAll`
-
-Get whether `operator` is approved by `account` for all tokens.
-
-Parameters:
-
-[,cairo]
-----
-account: felt
-operator: felt
-----
-
-Returns:
-
-[,cairo]
-----
-approved: felt
-----
-
-==== `setApprovalForAll`
-
-Enable or disable approval for a third party ("operator") to manage all of the caller's tokens.
-
-Parameters:
-
-[,cairo]
-----
-operator: felt
-approved: felt
-----
-
-Returns: None.
-
-==== `safeTransferFrom`
-
-Transfers `value` amount of token `id` from `from_` to `to`, checking first that contract recipients are aware and capable of handling ERC1155 tokens to prevent locking them forever.
-For information regarding how contracts communicate their awareness of the ERC1155 protocol, see <>.
-
-Emits a <> event.
-
-Parameters:
-
-[,cairo]
-----
-from_: felt
-to: felt
-id: Uint256
-value: Uint256
-data_len: felt
-data: felt*
----
-Returns: None.
-
-==== `safeBatchTransferFrom`
+Implementing the `IERC1155Receiver` interface exposes the {on_erc1155_received} and {on_erc1155_batch_received} methods.
+When {safe_transfer_from} and {safe_batch_transfer_from} are called, they invoke the recipient contract's `on_erc1155_received` or `on_erc1155_batch_received` methods respectively which *must* return the {receiver-id}.
+Otherwise, the transaction will fail.
-Batch version of <>. Emits a <> event.
+TIP: For information on how to calculate interface IDs, see {computing-interface-id}.
-Parameters:
-
-[,cairo]
-----
-from_: felt
-to: felt
-ids_len: felt
-ids: Uint256*
-values_len: felt
-values: Uint256*
-data_len: felt
-data: felt*
-----
+==== Creating a token receiver contract
-Returns: None.
+:ERC1155ReceiverComponent: xref:/api/erc1155.adoc#ERC1155ReceiverComponent[ERC1155ReceiverComponent]
-'''
+The Contracts for Cairo {ERC1155ReceiverComponent} already returns the correct interface ID for safe token transfers.
+To integrate the `IERC1155Receiver` interface into a contract, simply include the ABI embed directive to the implementations and add the `initializer` in the contract's constructor.
+Here's an example of a simple token receiver contract:
-=== Events
-
-==== `TransferSingle (Event)`
-
-Emitted when `operator` sends `value` amount of `id` token from `from_` to `to`.
-
-Parameters:
-
-[,cairo]
-----
-operator: felt
-from_: felt
-to: felt
-id: Uint256
-value: Uint256
+[,javascript]
----
+#[starknet::contract]
+mod MyTokenReceiver {
+ use openzeppelin::introspection::src5::SRC5Component;
+ use openzeppelin::token::erc1155::ERC1155ReceiverComponent;
+ use starknet::ContractAddress;
-==== `TransferBatch (Event)`
+ component!(path: ERC1155ReceiverComponent, storage: erc1155_receiver, event: ERC1155ReceiverEvent);
+ component!(path: SRC5Component, storage: src5, event: SRC5Event);
-Emitted when `operator` sends multiple `values` of multiple token `ids` from `from_` to `to`.
-
-Parameters:
-
-[,cairo]
-----
-operator: felt
-from_: felt
-to: felt
-ids_len: felt
-ids: Uint256*
-values_len: felt
-values: Uint256*
-----
-
-==== `ApprovalForAll (Event)`
-
-Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.
-
-Parameters:
-
-[,cairo]
-----
-account: felt
-operator: felt
-approved: felt
-----
+ // ERC1155Receiver
+ #[abi(embed_v0)]
+ impl ERC1155ReceiverImpl = ERC1155ReceiverComponent::ERC1155ReceiverImpl;
+ #[abi(embed_v0)]
+ impl ERC1155ReceiverCamelImpl = ERC1155ReceiverComponent::ERC1155ReceiverCamelImpl;
+ impl ERC1155ReceiverInternalImpl = ERC1155ReceiverComponent::InternalImpl;
-'''
+ // SRC5
+ #[abi(embed_v0)]
+ impl SRC5Impl = SRC5Component::SRC5Impl;
-=== IERC1155Metadata API
-
-[,cairo]
-----
-func uri(id: Uint256) -> (uri: felt) {
-}
-----
-
-==== `uri`
-
-Returns the Uniform Resource Identifier (URI) for a token `id`, although this implementation returns the same URI for *all* token types. It relies
-on the token type ID substitution mechanism
-https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].
-
-Parameters:
-
-[,cairo]
-----
-id: Uint256
-----
-
-Returns:
-
-[,cairo]
-----
-uri: felt
-----
-
-'''
-
-=== IERC1155Receiver API
+ #[storage]
+ struct Storage {
+ #[substorage(v0)]
+ erc1155_receiver: ERC1155ReceiverComponent::Storage,
+ #[substorage(v0)]
+ src5: SRC5Component::Storage
+ }
-[,cairo]
-----
-func onERC1155Received(
- operator: felt,
- from_: felt,
- tokenId: Uint256,
- data_len: felt,
- data: felt*
-) -> (selector: felt) {
-}
+ #[event]
+ #[derive(Drop, starknet::Event)]
+ enum Event {
+ #[flat]
+ ERC1155ReceiverEvent: ERC1155ReceiverComponent::Event,
+ #[flat]
+ SRC5Event: SRC5Component::Event
+ }
-func onERC1155BatchReceived(
- operator: felt,
- from_: felt,
- ids_len: felt,
- ids: Uint256*,
- values_len: felt,
- values: Uint256*,
- data_len: felt,
- data: felt*,
-) -> (selector: felt) {
+ #[constructor]
+ fn constructor(ref self: ContractState) {
+ self.erc721_receiver.initializer();
+ }
}
----
-
-==== `onERC1155Received`
-
-Whenever any IERC1155 token is transferred or minted to this non-account contract by `operator` from `from_`, this function is called.
-
-Parameters:
-
-[,cairo]
-----
-operator: felt
-from_: felt
-id: Uint256
-value: Uint156
-data_len: felt
-data: felt*
-----
-
-Returns:
-
-[,cairo]
-----
-selector: felt
-----
-
-==== `onERC1155BatchReceived`
-
-Whenever any IERC1155 token is transferred to this non-account contract via `safeBatchTransferFrom` by `operator` from `from_`, this function is called.
-
-Parameters:
-
-[,cairo]
-----
-operator: felt
-from_: felt
-ids_len: felt
-ids: Uint256*
-values_len: felt
-values: Uint156*
-data_len: felt
-data: felt*
-----
-
-Returns:
-
-[,cairo]
-----
-selector: felt
-----
diff --git a/docs/modules/ROOT/pages/erc20.adoc b/docs/modules/ROOT/pages/erc20.adoc
index afc26b452..7d260e47b 100644
--- a/docs/modules/ROOT/pages/erc20.adoc
+++ b/docs/modules/ROOT/pages/erc20.adoc
@@ -15,11 +15,15 @@ See the {custom-decimals} guide.
== Interface
:dual-interfaces: xref:/interfaces.adoc#dual_interfaces[Dual interfaces]
+:ierc20-interface: xref:/api/erc20.adoc#IERC20[IERC20]
+:ierc20metadata-interface: xref:/api/erc20.adoc#IERC20Metadata[IERC20Metadata]
+:erc20-component: xref:/api/erc20.adoc#ERC20Component[ERC20Component]
:erc20-supply: xref:/guides/erc20-supply.adoc[Creating ERC20 Supply]
-The following interface represents the full ABI of the Contracts for Cairo `ERC20` component.
-The interface includes the `IERC20` standard interface as well as `IERC20Camel` for backwards compatibility.
-To support older token deployments, as mentioned in {dual-interfaces}, the `ERC20` component also includes an implementation of the interface written in camelCase.
+The following interface represents the full ABI of the Contracts for Cairo {erc20-component}.
+The interface includes the {ierc20-interface} standard interface as well as the optional {ierc20metadata-interface}.
+
+To support older token deployments, as mentioned in {dual-interfaces}, the component also includes an implementation of the interface written in camelCase.
[,javascript]
----
diff --git a/docs/modules/ROOT/pages/erc721.adoc b/docs/modules/ROOT/pages/erc721.adoc
index d59351c5c..3b63ce67f 100644
--- a/docs/modules/ROOT/pages/erc721.adoc
+++ b/docs/modules/ROOT/pages/erc721.adoc
@@ -9,17 +9,19 @@ The ERC721 token standard is a specification for {token-types}, or more colloqui
== Interface
:compatibility: xref:/erc721.adoc#erc721_compatibility[ERC721 Compatibility]
-:ierc721-interface: xref:/erc721.adoc#ierc721[IERC721]
-:ierc721metadata-interface: xref:/erc721.adoc#ierc721metadata[IERC721Metadata]
+:ierc721-interface: xref:/api/erc721.adoc#IERC721[IERC721]
+:ierc721metadata-interface: xref:/api/erc721.adoc#IERC721Metadata[IERC721Metadata]
+:erc721-component: xref:/api/erc721.adoc#ERC721Component[ERC721Component]
:dual-interfaces: xref:interfaces.adoc#dual_interfaces[Dual interfaces]
-The following interface represents the full ABI of the Contracts for Cairo `ERC721Component`.
-The interface includes the <> standard interface and the optional <> interface.
+The following interface represents the full ABI of the Contracts for Cairo {erc721-component}.
+The interface includes the {ierc721-interface} standard interface and the optional {ierc721metadata-interface} interface.
+
To support older token deployments, as mentioned in {dual-interfaces}, the component also includes implementations of the interface written in camelCase.
[,javascript]
----
-trait IERC721ABI {
+trait ERC721ABI {
// IERC721
fn balance_of(account: ContractAddress) -> u256;
fn owner_of(token_id: u256) -> ContractAddress;
diff --git a/docs/modules/ROOT/pages/presets.adoc b/docs/modules/ROOT/pages/presets.adoc
index b353ddc3b..d3a20c69d 100644
--- a/docs/modules/ROOT/pages/presets.adoc
+++ b/docs/modules/ROOT/pages/presets.adoc
@@ -1,6 +1,7 @@
:account: xref:/api/account.adoc#Account[Account]
:erc20: xref:/api/erc20.adoc#ERC20[ERC20]
:erc721: xref:/api/erc721.adoc#ERC721[ERC721]
+:erc1155: xref:/api/erc1155.adoc#ERC1155[ERC1155]
:eth-account-upgradeable: xref:/api/account.adoc#EthAccountUpgradeable[EthAccountUpgradeable]
:sierra-class-hashes: https://docs.starknet.io/documentation/architecture_and_concepts/Smart_Contracts/class-hash[Sierra class hashes]
:starkli: https://book.starkli.rs/introduction[starkli]
@@ -29,14 +30,17 @@ NOTE: Class hashes were computed using {class-hash-cairo-version}.
| `{account}`
| `{Account-class-hash}`
-| `{eth-account-upgradeable}`
-| `{EthAccountUpgradeable-class-hash}`
-
| `{erc20}`
| `{ERC20-class-hash}`
| `{erc721}`
| `{ERC721-class-hash}`
+
+| `{erc1155}`
+| `{ERC1155-class-hash}`
+
+| `{eth-account-upgradeable}`
+| `{EthAccountUpgradeable-class-hash}`
|===
TIP: {starkli} class-hash command can be used to compute the class hash from a Sierra artifact.
diff --git a/docs/modules/ROOT/pages/utils/_class_hashes.adoc b/docs/modules/ROOT/pages/utils/_class_hashes.adoc
index 58f5ed728..234e715a3 100644
--- a/docs/modules/ROOT/pages/utils/_class_hashes.adoc
+++ b/docs/modules/ROOT/pages/utils/_class_hashes.adoc
@@ -5,6 +5,7 @@
:Account-class-hash: 0x01148c31dfa5c4708a4e9cf1eb0fd3d4d8ad9ccf09d0232cd6b56bee64a7de9d
:ERC20-class-hash: 0x07d94f28156c0dc3bfd9a07ca79b15b8da2b5b32093db79000fcd0f6f625d213
:ERC721-class-hash: 0x06b7c9efc5467c621f58d87995302d940a39b7217b5c5a7a55555c97cabf5cd8
+:ERC1155-class-hash: 0x518be7d9fa527c78d6929bf9e638e9c98b6077722e27e9546cc4342e830386e
:EthAccountUpgradeable-class-hash: 0x0580fe510cf07255540abda6f9d29aa07cb8944db444bca59e1573904c269844
// Presets page
diff --git a/docs/modules/ROOT/pages/utils/_common.adoc b/docs/modules/ROOT/pages/utils/_common.adoc
new file mode 100644
index 000000000..b69272b96
--- /dev/null
+++ b/docs/modules/ROOT/pages/utils/_common.adoc
@@ -0,0 +1,5 @@
+// Notes
+:src5-component-required-note: Implementing xref:api/introspection.adoc#SRC5Component[SRC5Component] is a requirement for this component to be implemented.
+
+// Links
+:mixin-impls: xref:components.adoc#mixins[Embeddable Mixin Implementations]
diff --git a/src/presets/erc1155.cairo b/src/presets/erc1155.cairo
index cbefb3a3a..b1c111e5f 100644
--- a/src/presets/erc1155.cairo
+++ b/src/presets/erc1155.cairo
@@ -48,7 +48,7 @@ mod ERC1155 {
SRC5Event: SRC5Component::Event
}
- /// Sets the `token_uri`.
+ /// Sets the `base_uri` for all tokens.
/// Mints the `values` for `token_ids` tokens to `recipient`.
///
/// Requirements:
@@ -59,12 +59,12 @@ mod ERC1155 {
#[constructor]
fn constructor(
ref self: ContractState,
- token_uri: ByteArray,
+ base_uri: ByteArray,
recipient: ContractAddress,
token_ids: Span,
values: Span
) {
- self.erc1155.initializer(token_uri);
+ self.erc1155.initializer(base_uri);
self
.erc1155
.batch_mint_with_acceptance_check(recipient, token_ids, values, array![].span());
diff --git a/src/tests/mocks/erc1155_mocks.cairo b/src/tests/mocks/erc1155_mocks.cairo
index 68da49228..976050426 100644
--- a/src/tests/mocks/erc1155_mocks.cairo
+++ b/src/tests/mocks/erc1155_mocks.cairo
@@ -41,12 +41,12 @@ mod DualCaseERC1155Mock {
#[constructor]
fn constructor(
ref self: ContractState,
+ base_uri: ByteArray,
recipient: ContractAddress,
token_id: u256,
- value: u256,
- uri: ByteArray
+ value: u256
) {
- self.erc1155.initializer(uri);
+ self.erc1155.initializer(base_uri);
self.erc1155.mint_with_acceptance_check(recipient, token_id, value, array![].span());
}
}
@@ -92,12 +92,12 @@ mod SnakeERC1155Mock {
#[constructor]
fn constructor(
ref self: ContractState,
+ base_uri: ByteArray,
recipient: ContractAddress,
token_id: u256,
- value: u256,
- uri: ByteArray
+ value: u256
) {
- self.erc1155.initializer(uri);
+ self.erc1155.initializer(base_uri);
self.erc1155.mint_with_acceptance_check(recipient, token_id, value, array![].span());
}
}
@@ -143,12 +143,12 @@ mod CamelERC1155Mock {
#[constructor]
fn constructor(
ref self: ContractState,
+ base_uri: ByteArray,
recipient: ContractAddress,
token_id: u256,
- value: u256,
- uri: ByteArray
+ value: u256
) {
- self.erc1155.initializer(uri);
+ self.erc1155.initializer(base_uri);
self.erc1155.mint_with_acceptance_check(recipient, token_id, value, array![].span());
}
}
diff --git a/src/tests/token/test_dual1155.cairo b/src/tests/token/test_dual1155.cairo
index 272072fd7..32962595b 100644
--- a/src/tests/token/test_dual1155.cairo
+++ b/src/tests/token/test_dual1155.cairo
@@ -21,13 +21,13 @@ use starknet::testing;
//
fn setup_snake() -> (DualCaseERC1155, IERC1155Dispatcher, ContractAddress) {
- let uri: ByteArray = "URI";
+ let base_uri: ByteArray = "URI";
let owner = setup_account();
let mut calldata = array![];
+ calldata.append_serde(base_uri);
calldata.append_serde(owner);
calldata.append_serde(TOKEN_ID);
calldata.append_serde(TOKEN_VALUE);
- calldata.append_serde(uri);
let target = utils::deploy(SnakeERC1155Mock::TEST_CLASS_HASH, calldata);
(
DualCaseERC1155 { contract_address: target },
@@ -37,13 +37,13 @@ fn setup_snake() -> (DualCaseERC1155, IERC1155Dispatcher, ContractAddress) {
}
fn setup_camel() -> (DualCaseERC1155, IERC1155CamelDispatcher, ContractAddress) {
- let uri: ByteArray = "URI";
+ let base_uri: ByteArray = "URI";
let owner = setup_account();
let mut calldata = array![];
+ calldata.append_serde(base_uri);
calldata.append_serde(owner);
calldata.append_serde(TOKEN_ID);
calldata.append_serde(TOKEN_VALUE);
- calldata.append_serde(uri);
let target = utils::deploy(CamelERC1155Mock::TEST_CLASS_HASH, calldata);
(
DualCaseERC1155 { contract_address: target },
diff --git a/src/token/erc1155/erc1155.cairo b/src/token/erc1155/erc1155.cairo
index b50079a20..138e3e58a 100644
--- a/src/token/erc1155/erc1155.cairo
+++ b/src/token/erc1155/erc1155.cairo
@@ -104,7 +104,7 @@ mod ERC1155Component {
+SRC5Component::HasComponent,
+Drop
> of interface::IERC1155> {
- /// Returns the number of NFTs owned by `account` for a specific `token_id`.
+ /// Returns the amount of `token_id` tokens owned by `account`.
fn balance_of(
self: @ComponentState, account: ContractAddress, token_id: u256
) -> u256 {
@@ -112,8 +112,7 @@ mod ERC1155Component {
}
- /// Returns a span of u256 values representing the batch balances of the
- /// `accounts` for the specified `token_ids`.
+ /// Returns a list of balances derived from the `accounts` and `token_ids` pairs.
///
/// Requirements:
///
@@ -138,7 +137,7 @@ mod ERC1155Component {
batch_balances.span()
}
- /// Transfers ownership of `token_id` from `from` if `to` is either an account or `IERC1155Receiver`.
+ /// Transfers ownership of `value` amount of `token_id` from `from` if `to` is either an account or `IERC1155Receiver`.
///
/// `data` is additional data, it has no specified format and it is passed to `to`.
///
@@ -169,7 +168,7 @@ mod ERC1155Component {
self.safe_batch_transfer_from(from, to, token_ids, values, data)
}
- /// Batched version of `safeTransferFrom`.
+ /// Batched version of `safe_transfer_from`.
///
/// WARNING: This function can potentially allow a reentrancy attack when transferring tokens
/// to an untrusted contract, when invoking `on_ERC1155_batch_received` on the receiver.
@@ -205,7 +204,7 @@ mod ERC1155Component {
self.update_with_acceptance_check(from, to, token_ids, values, data);
}
- /// Enable or disable approval for `operator` to manage all of the
+ /// Enables or disables approval for `operator` to manage all of the
/// callers assets.
///
/// Requirements:
@@ -223,7 +222,7 @@ mod ERC1155Component {
self.emit(ApprovalForAll { owner, operator, approved });
}
- /// Query if `operator` is an authorized operator for `owner`.
+ /// Queries if `operator` is an authorized operator for `owner`.
fn is_approved_for_all(
self: @ComponentState, owner: ContractAddress, operator: ContractAddress
) -> bool {
@@ -317,10 +316,11 @@ mod ERC1155Component {
impl SRC5: SRC5Component::HasComponent,
+Drop
> of InternalTrait {
- /// Initializes the contract by setting the token uri.
+ /// Initializes the contract by setting the `base_uri` for all tokens,
+ /// and registering the supported interfaces.
/// This should only be used inside the contract's constructor.
- fn initializer(ref self: ComponentState, uri: ByteArray) {
- self.set_uri(uri);
+ fn initializer(ref self: ComponentState, base_uri: ByteArray) {
+ self.set_base_uri(base_uri);
let mut src5_component = get_dep_component_mut!(ref self, SRC5);
src5_component.register_interface(interface::IERC1155_ID);
@@ -379,13 +379,15 @@ mod ERC1155Component {
}
/// Version of `update` that performs the token acceptance check by calling
- /// `IERC1155Receiver-onERC1155Received` or `IERC1155Receiver-onERC1155BatchReceived` if
+ /// `IERC1155Receiver::onERC1155Received` or `IERC1155Receiver::onERC1155BatchReceived` if
/// the receiver is not recognized as an account.
///
/// Requirements:
///
/// - `to` is either an account contract or supports the `IERC1155Receiver` interface.
/// - `token_ids` and `values` must have the same length.
+ ///
+ /// Emits a `TransferSingle` event if the arrays contain one element, and `TransferBatch` otherwise.
fn update_with_acceptance_check(
ref self: ComponentState,
from: ContractAddress,
@@ -502,8 +504,8 @@ mod ERC1155Component {
///
/// Because these URIs cannot be meaningfully represented by the `URI` event,
/// this function emits no events.
- fn set_uri(ref self: ComponentState, uri: ByteArray) {
- self.ERC1155_uri.write(uri);
+ fn set_base_uri(ref self: ComponentState, base_uri: ByteArray) {
+ self.ERC1155_uri.write(base_uri);
}
}