Mixins
The FA2 library provides small classes from which you can inherit separately in order to add additional features. They are called mixins.
INFO
In SmartPy the order in which superclasses are listed is important.
The expected order of inheritance for the FA2 lib classes is: Admin
, policy, base class, followed by any others. Only the base class is mandatory.
Examples
Examples with almost all mixins activated.
NFT
class ExampleFa2Nft(
main.Admin,
main.Nft,
main.ChangeMetadata,
main.WithdrawMutez,
main.MintNft,
main.BurnNft,
main.OffchainviewTokenMetadata,
main.OnchainviewBalanceOf,
):
def __init__(self, administrator, metadata, ledger, token_metadata):
main.OnchainviewBalanceOf.__init__(self)
main.OffchainviewTokenMetadata.__init__(self)
main.BurnNft.__init__(self)
main.MintNft.__init__(self)
main.WithdrawMutez.__init__(self)
main.ChangeMetadata.__init__(self)
main.Nft.__init__(self, metadata, ledger, token_metadata)
main.Admin.__init__(self, administrator)
Fungible
class ExampleFa2Fungible(
main.Admin,
main.Fungible,
main.ChangeMetadata,
main.WithdrawMutez,
main.MintFungible,
main.BurnFungible,
main.OffchainviewTokenMetadata,
main.OnchainviewBalanceOf,
):
def __init__(self, administrator, metadata, ledger, token_metadata):
main.OnchainviewBalanceOf.__init__(self)
main.OffchainviewTokenMetadata.__init__(self)
main.BurnFungible.__init__(self)
main.MintFungible.__init__(self)
main.WithdrawMutez.__init__(self)
main.ChangeMetadata.__init__(self)
main.Fungible.__init__(self, metadata, ledger, token_metadata)
main.Admin.__init__(self, administrator)
Single Asset
class SingleAssetTestFull(
main.Admin,
main.SingleAsset,
main.ChangeMetadata,
main.WithdrawMutez,
main.MintSingleAsset,
main.BurnSingleAsset,
main.OffchainviewTokenMetadata,
main.OnchainviewBalanceOf,
):
def __init__(self, administrator, metadata, ledger, token_metadata):
main.OnchainviewBalanceOf.__init__(self)
main.OffchainviewTokenMetadata.__init__(self)
main.BurnSingleAsset.__init__(self)
main.MintSingleAsset.__init__(self)
main.WithdrawMutez.__init__(self)
main.ChangeMetadata.__init__(self)
main.SingleAsset.__init__(self, metadata, ledger, token_metadata)
main.Admin.__init__(self, administrator)
All mixins
Here are all the available mixins:
mixin | description |
---|---|
Admin | is_administrator method and set_administrator entrypoint. |
BurnNft | An example of a burn entrypoint that relies on the transfer policy permissions for the Nft base class. The entrypoint does remove the token_metadata when burning a token. |
BurnFungible | Same for the Fungible base class. The entrypoint does not remove the token_metadata when burning a token. |
BurnSingleAsset | Same for the SingleAsset base class. The entrypoint does not remove the token_metadata when burning a token. |
ChangeMetadata | set_metadata entrypoint to change contract's metadata. Requires Admin mixin. |
MintNft | An example of a mint entrypoint for the Nft base class. |
MintFungible | Same for the Fungible base class. |
MintSingleAsset | Same for the Fungible base class. |
OnchainviewBalanceOf | Non-standard get_balance_of on-chain view that mimics balance_of entrypoint logic with a view. |
OffChainViewTokenMetadata | token_metadata off-chain view. If present indexers use it to retrieve the token's metadata. Warning ⚠️ If someone can change the contract's metadata, he can change how indexers see every token metadata. |
WithdrawMutez | withdraw_mutez entrypoint for withdrawal of Tez from the contract's balance. Requires Admin mixin. |
More detail on the mixins can be found in FA2 lib's pdoc.
Mint mixins
Mint and burn entrypoints are not standard. One can imagine many different types of mint operations.
The mint logic could even be partially delegated to another contract "minter" contract. In this case, the mint entrypoint is simply verifying the minter permission and register the mint without any other logic.
We provide mint and burn mixins that can be used as an example.
WARNING
The Mint*
mixins we provide don't provide a way of modifying the metadata of tokens after they are minted.
The Mint*
mixins need the Admin
mixin to work.
Example:
class NftWithMint(FA2.Admin, FA2.MintNft, FA2.Fa2Nft):
def __init__(self, admin, **kwargs):
Fa2Nft.__init__(self, **kwargs)
Admin.__init__(self, admin)
Mint (NFT)
The MintNft
mixin provides a mint
entrypoint that takes a list of mint actions. Each mint action is a record of:
to_
: address of who receives the minted tokensmetadata
: the token metadata
Example:
fa2_admin = sp.test_account("fa2_admin")
NFT0 = fa2.make_metadata(
name = "Example FA2",
decimals = 0,
symbol = "EFA2" )
NFT1 = fa2.make_metadata(
name = "Example FA2",
decimals = 0,
symbol = "EFA2-2" )
example_fa2_nft.mint(
[
sp.record(
to_ = fa2_admin.address, # Who will receive the original mint
metadata = NFT0
),
sp.record(
to_ = fa2_admin.address,
metadata = NFT1
),
],
_sender=fa2_admin)
The token id is an incremental sp.nat
.
Mint (fungible)
The MintFungible
mixin provides a mint
entrypoint that takes a list of mint actions. Each mint action is a record of:
amount
: the amount of token to mintto_
: address of who receives the minttoken
: variant with 2 possible values:"new"
: the token metadata"existing"
: the token id of an existing token.
Example:
fa2_admin = sp.test_account("fa2_admin")
TOKEN0 = fa2.make_metadata(
name = "Example FA2",
decimals = 0,
symbol = "EFA2" )
example_fa2_fungible.mint(
[
sp.record(
to_ = fa2_admin.address, # Who will receive the original mint
amount = 100_000_000_000,
token = variant("new", TOKEN0)
),
sp.record(
to_ = fa2_admin.address
amount = 100_000_000_000,
token = variant("existing", 0)
),
],
_sender=FA2_admin)
The token id is an incremental sp.nat
.
Mint (single asset)
The MintSingleAsset
mixin provides a mint
entrypoint that takes a list of mint actions. Each mint action is a record of:
amount
: the amount of token to mintto_
: address of who receives the mint
Example:
fa2_admin = sp.test_account("fa2_admin")
alice = sp.test_account("alice")
TOKEN0 = fa2.make_metadata(
name = "Example FA2",
decimals = 0,
symbol = "EFA2" )
example_fa2_fungible.mint(
[
sp.record(
to_ = fa2_admin.address, # Who will receive the original mint
amount = 100_000_000_000,
),
sp.record(
to_ = alice.address
amount = 100_000_000_000,
),
],
_sender=fa2_admin)