MintMe is a decentralized application built on XPR Network, consisting of smart contracts and a web interface.
The user will connect their WebAuth.com wallet to the application front end, escrow some token for minting 'tickets' which the user can use to generate up to three images using txt2img api from Replicate with the current configuration, then the user can mint one of the images as an NFT to a pre-selected atomic assets collection on XPR Network.
/contract/xpr-ai-nft-mint
- Smart contract implementation/apps/web
- Web application frontend
The project use monorepo restructure that rely on package manager
On the project root run the install command, sub folder package installation are handled automatically.
Run npm install
Run yarn add
Run bun install
Your templates and asset need a collection on Atomic asset to be bound with.
Navigate to explorer mainnet or explorer testnet and fill the following form.
Make sure:
- You replace
yourcontract
by the name of the account where the contract is deployed. - You set a unique name for you collection: it must follow the same rule than Name (can only use a to z and 1 to 5 chars) and must be 12 chars length
- You can set
market_fee
up to 0.15 (mean 15%) to earn sale price share from future sale on soon market.
Next create the schema
Now navigate to explorer mainnet or explorer testnet and fill the following form.
Make sure:
- You replace
yourcontract
by the name of the account where the contract is deployed. collection_name
andschema_name
should be the same as the collection create before- Paste the following schema to the
schema
field
[
{ "name": "name", "type": "string" },
{ "name": "image", "type": "string" },
{ "name": "img", "type": "string" },
{ "name": "url", "type": "string" },
{ "name": "description", "type": "string" }
]
- Node.js (v18 or later)
- npm or yarn or bun package manager
- @proton/cli
- Create an account where you will deploy the contract.
- Make sure the created account private key is added to the wallets manager
- Open the file in ./contracts/xpr-ai-nft-mint/makefile
- Replace the fields
TESTNET_CONTRACT_NAME
/MAINNET_CONTRACT_NAME
with the account(s) you create. - Save and close the makefile.
- Add ram to your account using https://resources.xprnetwork.org/storage or @proton/cli
proton ram:buy
command.- For testnet you can use the
make feed-ram
command
- For testnet you can use the
- Open a terminal session on ./contracts/xpr-ai-nft-mint/
- Run
- For testnet: make push_testnet
- For mainnet: make push_mainnet
- Done !
The contract is a basic escrow like contract. When user transfer the amount (defined in the config table: see config section), the contract create a mint ticket owned by the account that sourced the transfer. The resulting ticket could be used to generate AI image and mint the selected one.
A ticket is the result of a transfer of corresponding tokens and quantity that match with the tokenPrice
field from the contract config (see config section)
A ticket is
- a entry for AI generation request (max generation is also defined in the config table: see config section)
- A older for IPFS hash generated after the image generation
- an entry to trigger the mint process.
Since it's not converted to a mint, a ticket is recoverable, it hold the images IPFS generatedHash
, the created templateId
and the assetId
during the process. Once the asset is minted, the ticket is destroyed.
Fields
public key: u64 = 0;
public account: Name = EMPTY_NAME;
public generatedHash: string[] = [];
public templateId: u64 = 0;
public assetId: u64 = 0;
The config section hold the global config for the smart contract. Through a special object type, it define the ticket price, the collection where the asset belong, and an account where all mint amount should land.
The contract alway get the last inserted config. Config could not be edited, to change the config, you push a new one.
public key: u64 = 0,
public config: XPRPalsConfig = new XPRPalsConfig(
EMPTY_NAME,
new Asset(
0,
new Symbol('XPR',4)
),
EMPTY_NAME,
)
The config contains a XPRPalsConfig
which is a special structure that allow configuration to evolve without constrain table structure.
public collectionName: Name = EMPTY_NAME,
public tokenPrice: Asset = new Asset(0, new Symbol("XPR", 4)),
public generationLimit:u8 = 0,
public transferAccount: Name = EMPTY_NAME,
@action("transfer", notify)
Handles incoming token transfers. Never invoked directly but triggered when the contract receive tokens. It creates mint tickets when correct payment is received
@action("ticket.adgen")
Adds a IPFS generated hash to a mint ticket. This action is invoked by the API, only the contract account is authorized to use it.
- Parameters:
account
: Account performing the actionmintTicketKey
: ID of the mint tickethash
: Generated image hash to add
@action("ticket.mint")
Mints an NFT using a generated hash from a ticket
- Parameters:
account
: Account performing the mintmintTicketKey
: ID of the mint tickethashIndex
: Index of the hash to use from the ticket's generated hashes
@action("lognewtempl", notify)
Triggered from the AtomicAsset contract when new templates is created. It run the mint process. Could not be invoked directly.
- Parameters:
template_id
: ID of the created templateauthorized_creator
: Account authorized to create the templatecollection_name
: Name of the collectionschema_name
: Name of the schema
@action("logmint", notify)
Triggered from the AtomicAsset contract when new asset is minted. Destroy the used ticket. Could not be invoked directly.
- Parameters:
asset_id
: ID of the minted assetauthorized_minter
: Account authorized to mintcollection_name
: Name of the collectionschema_name
: Name of the schematemplate_id
: ID of the template usednew_asset_owner
: Account that will own the assetimmutable_data
: Immutable attributes of the assetmutable_data
: Mutable attributes of the assetbacked_tokens
: Tokens backing the asset
@action("gov.chcfg")
Updates the contract configuration
- Parameters:
config
: New configuration to apply
- Node.js (v18 or later)
- npm or yarn or bun package manager
The front end is a NextJS App, it contain the front end and the API route for the AI generation image. The easiest way to deploy is using vercel (you can create a free hobby account). Make sure you have a github account to make your own copy.
- Locate the
env.template
file - Rename it
.env
- Open the file
REPLICATE_API_TOKEN=
The token from replicate service
PINATA_API_JWT=
The JWT token from pinata
AI_AGENT_ACTOR=youcontract
AI_AGENT_PERMISSION=active
AI_AGENT_SECRET=private_from_contract_account
The information from you smart contract, allow the backend to push IPFS hash from generated image to the user ticket
XPR_ENDPOINT=https://testnet.rockerone.io
NEXT_PUBLIC_XPR_ENDPOINT=https://testnet.rockerone.io
The XPRNetwork's endpoints
NEXT_PUBLIC_XPR_AA_ENDPOINT=https://aa-xprnetwork-test.saltant.io
The atomic assets endpoint
NEXT_PUBLIC_XPR_CHAIN_ID=71ee83bcf52142d61019d95f9cc5427ba6a0d7ff8accd9e2088ae2abeaf3d3dd
Chain id, see xprnetwork doc for mainnet or testnet.
NEXT_PUBLIC_REQUESTER_ACCOUNT=youcontract
NEXT_PUBLIC_DAPP_NAME=Your app cool name
Configuration for the proton web SDK
NEXT_PUBLIC_COLLECTION_NAME=yourowncollectionname
The collection you created from the "Create atomic asset collection and shcema"
NEXT_PUBLIC_IPFS_ENDPOINT=an_ipfs_url
Could be proton ipfs or your own pinata gateway
NEXT_PUBLIC_BASE_URL=http://localhost:3000
The current url where the project is deployed (change to vercel URL when deployed)
NEXT_PUBLIC_API_MODE=testnet_or_mainnet
- Open terminal on the root folder
- Open ./app/web
- run one of this command according to your package manager
- bun run dev
- npm run dev
- yarn dev
- On your browser open http://localhost:3000
The app could be deployed on vercel. Alternatively you can deploy on your own infrastructure.