We refreshed our doc site!
Bookmarked links may have changed
Read release notesCircle’s Smart Contract Templates make it easy to integrate smart contracts into your application without writing Solidity code. Deploy contracts in minutes using our curated and audited templates, which support popular on-chain use cases. You can deploy these templates through the console or APIs.
This guide will show you how to deploy an ERC-721 contract using Circle's NFT template.
You’ll learn to use both the Web3 Services Console and API paths. The console is ideal for beginners to explore and understand contract functions.
To learn more about the NFT template or any other template, go to the Web3 Services Console or the Templates Glossary guide.
Console Wallets are Smart Contract Accounts specifically designed to be used within the Console and cannot be utilized with the APIs. Console Wallets leverage Gas Station, eliminating the need to maintain gas in the wallet to cover transaction fees. To learn more about the Gas Station, please refer to the Gas Station overview.
If you do not already have a Console Wallet, you will be prompted to create one during the deployment of your first smart contract.
Console Wallet Deploy Cost
Unlike Externally Owned Accounts (EOAs), SCAs cost gas to “deploy”. With our process of lazy deployment, you won't have to pay the gas fee at the time of wallet creation. Instead, the fee will be charged when you initiate your first outbound transaction.
In the console:
Navigate to the Templates tab via the left navigation.
Select NFT ERC-721**.**
Fill in the contract template deployment parameters:
Name: The off-chain name of the contract. This will only be represented on Circle’s systems, such as the APIs and Web3 Services Console. In this case, you can use “My First NFT Contract” or any other name you prefer.
Contract Name: The on-chain name for the contract. In this case, you can use “My First NFT Contract” or any other name you prefer.
Default Admin: The address of the default admin. This address can execute permissions functions on the contract. This should be an address you control or the address of a user if deploying on their behalf. In this case, use the console wallet’s address from step one.
DEFAULT_ADMIN_ROLE
, MINTER_ROLE
, TRANSFER_ROLE
. The defaultAdmin
will also be set as the contract's owner. All of these roles can be updated by the defaultAdmin later. Primary Sale Recipient: The recipient's address for first-time sales. All first-time sale proceeds will go to this address. In this case, use the console wallet’s address from step one.
Royalty Recipient: The recipient address for all royalties. Any proceeds from secondary sales will go to this address. In this case, use the console wallet’s address from step one.
Royalty Percent: The percentage of secondary sales that go to the royalty recipient. There should be a value between 0 and 100. In this case, use “0”.
Network: The network to deploy onto. In this case, select “Polygon Amoy”.
Select Wallet: The wallet to deploy the smart contract from. In this case, select “Console Wallet 1”
Deployment Speed: A fee level setting (FAST, AVERAGE, SLOW). This affects how quickly the network will process your deployment transaction. In this case, you will use “AVERAGE”.
Select Deploy.
Console Wallet Creation
After selecting a network, you will prompted to create a Console Wallet for deployment. This wallet will automatically be created on all available networks. On testnet, this will also automatically create a Policy for Gas Station. For more information on sponsoring transactions, see Gas Station Policy Management .
Once deployed, you will be placed back on the Contracts dashboard. Here, you can check the deployment status of the contract. When you land on the page, expect the deployment status to be Pending. Give it several seconds, and then refresh the page. At this point, the deployment status should be set to Complete.
Let's dive into the Console UI to explore the full range of capabilities it offers and mint an NFT. With the Console, you can seamlessly explore the NFT contract you deployed. Gain insights into its ABI functions, inspect their inputs, and easily execute functions. In this example, we will directly execute the mintTo function from the console - which mints an NFT to a user without a sale.
In the console:
Navigate to the Contracts tab.
Select the My First NFT Contract within the console.
Select ABI Functions sub tab. This should be selected by default.
Select Write.
Select mintTo.
On the mintTo ABI function, provide the following parameters:
Select Execute Function and ensure Console Wallet 1 is selected.
Select Execute.
Once executed, select View Transaction History to access the Console Wallet's transaction dashboard. Here, you can easily monitor the progress and status of the transaction. Once the transaction state is marked as Complete, the NFT has been successfully transferred on-chain to the designated address mentioned above.
Inbound Transaction
In the transaction history view, you will also notice an inbound transfer indicating that the NFT has been minted to the Console Wallet.
Congratulations, you have deployed a smart contract and minted an NFT!
Next Steps
To deploy a smart contract, you must provide a wallet to deploy from. If you don’t have the walletId
, you can use the GET /wallets
API to acquire the wallet ID. Ensure the wallet custody type is Developer-Controlled and the blockchain is Polygon Amoy. We recommend the account type be SCA - removing the need for gas in your wallet for deployment. Lastly, note down the wallet’s address. This will be used in the subsequent steps.
Deployment Request Parameters:
My First NFT Contract
or any other name you prefer.76b83278-50e2-4006-8b63-5b1a2a814533
as the ID for the NFT template. This templateId
and other template-specific details are listed in the Templates Glossary.MATIC-AMOY
.MEDIUM
.Template parameters are the inputs for initializing and deploying the template on-chain. Each template will have its own set of parameters.
For the NFT template, the required properties are:
My First NFT Contract
or any other name you prefer.GET /wallets
API above.
DEFAULT_ADMIN_ROLE
, MINTER_ROLE
, TRANSFER_ROLE
. The defaultAdmin
will also be set as the contract's owner. All of these roles can be updated by the defaultAdmin later.GET /wallets
API above.0
.GET /wallets
API above.There are additional properties and configurations available for more advanced use cases. Please see the Templates Glossary for more information on configuring the NFT Template and for extended use cases of all template types.
Now that you have all your request parameters in order, you can deploy the smart contract by making a request to the POST /templates/{id}/deploy
API. You must also pass your entity secret ciphertext in the request body. The full request is as follows:
// Import and configure the developer-controlled wallet SDK
const { initiateDeveloperControlledWalletsClient } = require('@circle-fin/developer-controlled-wallets');
const circleDeveloperSdk = initiateDeveloperControlledWalletsClient({
apiKey: '<API_KEY>',
entitySecret: '<ENTITY_SECRET>'
});
// Import and configure the smart contract SDK
const { initiateSmartContractPlatformClient } = require('@circle-fin/smart-contract-platform');
const circleContractSdk = initiateSmartContractPlatformClient({
apiKey: '<API_KEY>',
entitySecret: '<ENTITY_SECRET>'
});
const response = await circleContractSdk.deployContractTemplate({
id: 'aea21da6-0aa2-4971-9a1a-5098842b1248',
blockchain: 'MATIC-AMOY',
name: 'My First NFT Contract',
walletId: '<WALLET_ID>',
templateParameters: {
name: 'My First NFT Contract',
defaultAdmin: '<ADDRESS>',
primarySaleRecipient: '<ADDRESS>',
royaltyRecipient: '<ADDRESS>',
royaltyPercent: 0
},
fee: {
type: 'level',
config: {
feeLevel: 'MEDIUM'
}
}
});
{
"data": {
"contractIds": ["b7c35372-ce69-4ccd-bfaa-504c14634f0d"],
"transactionId": "601a0815-f749-41d8-b193-22cadd2a8977"
}
}
A successful API response indicates that the deployment process has been initiated but does not guarantee that the deployment will be successful. The returned transactionId
can be used to check the status of the deployment transaction using get a transaction.
To validate that your contract has deployed successfully, make a request to GET /transactions/{id}, providing the ID of the transaction received in the response above.
const response = await circleDeveloperSdk.listTransactions({});
{
"data": {
"transaction": {
"id": "601a0815-f749-41d8-b193-22cadd2a8977",
"blockchain": "MATIC-AMOY",
"state": "COMPLETE",
...
[other fields truncated]
}
}
}
The returned contractId
can be used to perform further management and interaction with the deployed smart contract, such as minting an NFT.
Let's dive into the Web3 Services Console to explore its full range of capabilities. With the Console, you can seamlessly explore the NFT contract you deployed. Gain insights into its ABI functions, inspect their inputs, and easily execute functions through an API call by conveniently copying the required code.
Alternatively, you can retrieve detailed information about the contract using theGet contract by ID
response, which includes all the available functions and events.
In this example, we will use the code snippet generator to build the contract execution request for the mintTo
function - which mints an NFT to a user without a sale. This can be done by selecting the contract within the Console, then in the ABI functions tab, selecting write, and selecting mintTo.
As you fill in the parameters for the mintTo
function, the code to make a contract execution API request and mint the NFT is automatically generated. Make sure to select your preferred wallet type and code generated, in this case, select a Developer Controlled wallet and Shell to create a cURL request example.
mintTo function parameters:
As a result of plugging these parameters in, you will be provided with a code block similar to the one below. Once copied to your preferred API client, add your walletId
and entitySecretCiphertext
to the API request.
const response = await circleDeveloperSdk.createContractExecutionTransaction({
walletId: '<WALLET_ID>',
abiFunctionSignature: 'mintTo(address,string)',
abiParameters: [
'0x6E5eAf34c73D1CD0be4e24f923b97CF38e10d1f3',
'ipfs://bafkreibdi6623n3xpf7ymk62ckb4bo75o3qemwkpfvp5i25j66itxvsoei'
],
contractAddress: '0xf7761519cf2d84c31f634e249790b4757c10a103',
fee: {
type: 'level',
config: {
feeLevel: 'MEDIUM'
}
}
});
Note that the address of the walletId
must have the MINTER_ROLE
on the contract to mint an NFT. Make sure you use the appropriate walletId
.
{
"data": {
"id": "601a0815-f749-41d8-b193-22cadd2a8977",
"state": "INITIATED"
}
}
Transaction Processing
A successful API response indicates that the mintTo
transaction has been initiated but does not guarantee that the deployment will be successful.
To validate that your contract has deployed successfully, make a request to GET /transactions/{id}
providing the ID of the transaction received in the response above.
const response = await circleDeveloperSdk.getTransaction({
id: '601a0815-f749-41d8-b193-22cadd2a8977'
});
{
"data": {
"transaction": {
"id": "601a0815-f749-41d8-b193-22cadd2a8977",
"blockchain": "MATIC-AMOY",
"state": "COMPLETE",
...
[other fields truncated]
}
}
}
Once the transaction is complete, the receiver - the _to
address that you previously specified - will now be able to use and interact with the minted NFT.
Congratulations, you have deployed a smart contract and minted an NFT!
Next Steps