How to create an NFT collection in Cardano with Tangocrypto JS SDK
In this tutorial, I’m going to show you how to create an NFT collection in Cardano.
The first step is to create an account in Tangocrypto (https://dashboard.tangocrypto.com/register)
To use Tangocrypto’s products, you need an API key to authenticate your requests.
You can create API keys from the dashboard, just click on Create App, name it and click create a new app:
Once the app is created, it will generate an APP ID and an API Key. With those values, you can start consuming the API with the SDK.
Install the SDK
Check out the full Github repo here:
https://github.com/tango-crypto/tangocrypto-js
Install the SDK:
npm i @tango-crypto/tangocrypto-js
After installing the app, you can then import and use the SDK:
import { Tangocrypto, Network } from '@tango-crypto/tangocrypto-js';// or CommonJS// const { Tangocrypto, Network } = require('@tango-crypto/tangocrypto-js');const client = new Tangocrypto({apiKey: process.env.API_KEY, // your account idappId: process.env.APP_ID, // your app idnetwork: Network.CARDANO_MAINNET, // Network to determine the base URL, default to https://cardano-mainnet.tangocrypto.comversion: process.env.VERSION, // API version, default to v1maxAttempts: 5 // maximmum retry attemps when request fails and is retryable (e.g. status 429)})
The Tangocrypto
object returned provides access to the Tangocrypto API. An optional config object can be passed in when initializing to set your API key, change the network, or specify the max number of retries.
Create the collection object
A collection is a way to create a group of individual NFTs with similar attributes. All the NFTs belonging to the same collection share attributes like the artist, year of creation, social networks, name of the collection, etc
const collection = { "name": "Tangocrypto SKD", "description": "Testing SKD", "url": "https://www.tango.com", "payout_address": "addr_test1qp9mj7vnenx4v99hw7ztfq03n7dmmujpgtlyfjhhel9w67nk72usllcew208n60ym94xcptfrgytuy5apwp565x28jgsg0ztq3", "policy": { "lock": true, "lock_time": "2023-02-24" }, "metadata": { "asset_name": "<asset_name>", "name": "<name>", "image": "<image_link>", "media_type": "<mime_type>", "description": "<description>", "attributes": { "color": "<color>", "right_eye": "<right_eye>", "left_eye": "<left_eye>", "mouth": "<mouth>", "collection": "Faces Collection", "artist": "Tangocrypto", "twitter": "https://twitter.com/tango_crypto", "copyright": "Tangocrypto 2022" }, "version": "1.0" }};
Create the Tokens object
Once the collection is created you can start adding what will become a NFTs (technically speaking to be an NFT it needs to be minted in the blockchain). Therefore the next step is to upload the images and define the metadata for each NFT in the collection.
Note: The image has to be converted to base64
const tokensArr = { "tokens": [{ "asset_name": "FACE#01", "name": "FACE 01", "description": "Faces collection", "media_type": "image/png", "custom_attributes": { "md5checksum": "b58e62a83802b2bf0792a4e983dd2ff3cf9e0c1e", "artist": "Pepe", }, "metadata_attributes": [{ "tag": "<color>", "name": "Attribute color", "value": "Light Blue" }, { "tag": "<left_eye>", "name": "Attribute left eye", "value": "Open" }, { "tag": "<right_eye>", "name": "Attribute right eye", "value": "Half" }, { "tag": "<mouth>", "name": "Attribute mouth", "value": "Astonishmed" } ], "image": "iVBORw0KGg...oAAAANSUhEUgAAAfQAAAH0" }, { "asset_name": "FACE#02", "name": "FACE 02", "description": "Faces collection", "media_type": "image/jpg", "custom_attributes": { "md5checksum": "bee6ddb26d7d9b5f7dccba997ec575d272d6981f", "artist": "Pepe", }, "metadata_attributes": [{ "tag": "<color>", "name": "Attribute color", "value": "Light Purple" }, { "tag": "<left_eye>", "name": "Attribute left eye", "value": "Closed" }, { "tag": "<right_eye>", "name": "Attribute right eye", "value": "Half" }, { "tag": "<mouth>", "name": "Attribute mouth", "value": "Happy" } ], "image": "iVBORw0KGgo..gEASABIAAD/2wBDAAEBAQEBAQEBAQEBAQEBAQEBA" }]};
Create the sale phase object
A sale phase is a control mechanism that defines how you will sell the collection. You can add different phases to control how you will sell the collection. For example, you might have a total of 5000 NFTs, and you want to sell them in three phases.
You can create a pre-sale phase to sell the first 1000 NFTs to previous customers at a special price and within a specific time range. You can identify these customers with a condition; that would be an NFT with one particular policy id on their wallets. Then you create another sale phase for the public drop with 3900 NFTs and no conditions, and last, you leave 100 NFTs as a reserve to mint in the last phase.
Now you have the collection created and uploaded the files and metadata, it’s time to define how you are going to sell the NFTs.
Here we are going to create a sale phase for a pre-sale where we want to sell 100 random NFTs. We have 2 price tiers and the buyers can select the tier they want to buy. For example, if a buyer want’s to get 2 random NFTs they can select the Golden plan tier and pay 20 Ada.
const salePhase = { "type": "random", "total_tokens": 100, "reservation_time": 1800, "name": "pre sale", "active": true, "price_tiers": [{ "name": "Silver plan", "quantity": 1, "supply": 1, "price": 15000000 }, { "name": "Golden plan", "quantity": 2, "supply": 1, "price": 20000000 }]};
Now we just have to put all the pieces together, the 3 objects we created earlier and the methods to create the collection, upload the NFTs and then create a sale phase.
let col = await tc.nft().createCollection(collection);let nfts = await tc.nft().createNft(col.result.id, tokensArr);let phase = await tc.nft().createSalePhase(col.result.id, salePhase);
In the response from the sale phase, we can see that each price tier has an associated payment link. Then we copy that link and embed it in the button. When the buyer clicks on the button a new window with Tangopay will open and once the payment is done the NFTs are sent to the wallet.
{
"result": {
"id": "01gcwxw5mn4rhd8s525z1hgf61",
"type": "random",
"name": "pre sale 1",
"active": true,
"reservation_time": 1800,
"total_tokens": 6,
"remaining_tokens": 6,
"price_tiers": [
{
"id": "01gcwxw5mn30vw4sb49pynsj1c",
"name": "Golden plan",
"price": 20000000,
"quantity": 2,
"supply": 1,
"token_sold_count": 0,
"payment_link": "https://buy.tangocrypto.com?q=test_eyJjb2xsZWN0aW9uX2lkIjoiMDFnY3d4dzR3YTRtdGJoODFjcHhyeDZldHkiLCJwaGFzZV9pZCI6IjAxZ2N3eHc1bW40cmhkOHM1MjV6MWhnZjYxIiwic3RhcnRfZGF0ZSI6IjIwMjItMDYtMDEiLCJlbmRfZGF0ZSI6IjIwMjItMTItMDEiLCJydWxlcyI6W10sInByaWNlIjoyMDAwMDAwMCwicHJpY2VfaWQiOiIwMWdjd3h3NW1uMzB2dzRzYjQ5cHluc2oxYyIsInF1YW50aXR5IjoyLCJzdXBwbHkiOjEsInR5cGUiOiJQaGFzZVNhbGUiLCJpc19yYW5kb20iOnRydWUsInRpdGxlIjoiVGVzdGluZyBTS0QgMyIsInRjYyI6InFYK3BnSVJtNEJuYlVUdlJxc3hrTExIMkNLa2xVM2xPbW1LbzE3RFRqc0RIYzFYYitHcGw0TEF1VWlOc092clFKUVBHekhVVXZvQXRHT21NekxBUWNpT1Rha2F3MGtZOWJ4TC92OC84RGNFczJMaE5sSGtqelV2VUExUFZBZz09IiwibWF4X3R4X2ZlZSI6ODc2Mjc3LCJyZXNlcnZhdGlvbl90aW1lIjoxODAwLCJuZnRfY29zdCI6MzQ0ODJ9"
},
{
"id": "01gcwxw5mmdmgfbhnj2tqh9qyx",
"name": "Silver plan",
"price": 15000000,
"quantity": 1,
"supply": 1,
"token_sold_count": 0,
"payment_link": "https://buy.tangocrypto.com?q=test_eyJjb2xsZWN0aW9uX2lkIjoiMDFnY3d4dzR3YTRtdGJoODFjcHhyeDZldHkiLCJwaGFzZV9pZCI6IjAxZ2N3eHc1bW40cmhkOHM1MjV6MWhnZjYxIiwic3RhcnRfZGF0ZSI6IjIwMjItMDYtMDEiLCJlbmRfZGF0ZSI6IjIwMjItMTItMDEiLCJydWxlcyI6W10sInByaWNlIjoxNTAwMDAwMCwicHJpY2VfaWQiOiIwMWdjd3h3NW1tZG1nZmJobmoydHFoOXF5eCIsInF1YW50aXR5IjoxLCJzdXBwbHkiOjEsInR5cGUiOiJQaGFzZVNhbGUiLCJpc19yYW5kb20iOnRydWUsInRpdGxlIjoiVGVzdGluZyBTS0QgMyIsInRjYyI6InFYK3BnSVJtNEJuYlVUdlJxc3hrTExIMkNLa2xVM2xPbW1LbzE3RFRqc0RIYzFYYitHcGw0TEF1VWlOc092clFKUVBHekhVVXZvQXRHT21NekxBUWNpT1Rha2F3MGtZOWJ4TC92OC84RGNFczJMaE5sSGtqelV2VUExUFZBZz09IiwibWF4X3R4X2ZlZSI6ODc2Mjc3LCJyZXNlcnZhdGlvbl90aW1lIjoxODAwLCJuZnRfY29zdCI6MzQ0ODJ9"
}
],
"affiliates": [],
"start_date": "2022-06-01",
"end_date": "2022-12-01",
"created_at": "2022-09-14T02:39:59.637Z",
"updated_at": "2022-09-14T02:39:59.637Z"
},
"$metadata": {
"attempts": 1,
"totalRetryDelay": 0
}
}
Here is a code example showing a demo website with a dropdown for the buyer to select how many NFTs they want to purchase.
<!DOCTYPE html><html><head><meta charset="utf-8"><title>Minting Site</title></head><body><div class="container"><div><div><p style="text-align:center;">My minting website</p><p style="text-align:center;"><br>Please Select the number of NFT that you will be Minting<br><br><br><select id="NFT"><option value="None">-- Select --</option><option value="https://buy.tangocrypto.com?q=test_eyJjb2xsZWN0aW9uX2lkIjoiMDFnY3d4dzR3YTRtdGJoODFjcHhyeDZldHkiLCJwaGFzZV9pZCI6IjAxZ2N3eHc1bW40cmhkOHM1MjV6MWhnZjYxIiwic3RhcnRfZGF0ZSI6IjIwMjItMDYtMDEiLCJlbmRfZGF0ZSI6IjIwMjItMTItMDEiLCJydWxlcyI6W10sInByaWNlIjoyMDAwMDAwMCwicHJpY2VfaWQiOiIwMWdjd3h3NW1uMzB2dzRzYjQ5cHluc2oxYyIsInF1YW50aXR5IjoyLCJzdXBwbHkiOjEsInR5cGUiOiJQaGFzZVNhbGUiLCJpc19yYW5kb20iOnRydWUsInRpdGxlIjoiVGVzdGluZyBTS0QgMyIsInRjYyI6InFYK3BnSVJtNEJuYlVUdlJxc3hrTExIMkNLa2xVM2xPbW1LbzE3RFRqc0RIYzFYYitHcGw0TEF1VWlOc092clFKUVBHekhVVXZvQXRHT21NekxBUWNpT1Rha2F3MGtZOWJ4TC92OC84RGNFczJMaE5sSGtqelV2VUExUFZBZz09IiwibWF4X3R4X2ZlZSI6ODc2Mjc3LCJyZXNlcnZhdGlvbl90aW1lIjoxODAwLCJuZnRfY29zdCI6MzQ0ODJ9">1</option><option value="https://buy.tangocrypto.com?q=test_eyJjb2xsZWN0aW9uX2lkIjoiMDFnY3d4dzR3YTRtdGJoODFjcHhyeDZldHkiLCJwaGFzZV9pZCI6IjAxZ2N3eHc1bW40cmhkOHM1MjV6MWhnZjYxIiwic3RhcnRfZGF0ZSI6IjIwMjItMDYtMDEiLCJlbmRfZGF0ZSI6IjIwMjItMTItMDEiLCJydWxlcyI6W10sInByaWNlIjoxNTAwMDAwMCwicHJpY2VfaWQiOiIwMWdjd3h3NW1tZG1nZmJobmoydHFoOXF5eCIsInF1YW50aXR5IjoxLCJzdXBwbHkiOjEsInR5cGUiOiJQaGFzZVNhbGUiLCJpc19yYW5kb20iOnRydWUsInRpdGxlIjoiVGVzdGluZyBTS0QgMyIsInRjYyI6InFYK3BnSVJtNEJuYlVUdlJxc3hrTExIMkNLa2xVM2xPbW1LbzE3RFRqc0RIYzFYYitHcGw0TEF1VWlOc092clFKUVBHekhVVXZvQXRHT21NekxBUWNpT1Rha2F3MGtZOWJ4TC92OC84RGNFczJMaE5sSGtqelV2VUExUFZBZz09IiwibWF4X3R4X2ZlZSI6ODc2Mjc3LCJyZXNlcnZhdGlvbl90aW1lIjoxODAwLCJuZnRfY29zdCI6MzQ0ODJ">2</option></select><br><br></script> </p><p style="text-align:center;"><button onclick="javascript:tangoPay()"> Pay </button></div></div></div><script type="text/javascript">function tangoPay() {const paymentUrl = NFT.value;// Specify the popup width and heightconst width = 500;const height = 910;// Calculate the center of the screenconst left = window.top.outerWidth / 2 + window.top.screenX - ( width / 2);const top = window.top.outerHeight / 2 + window.top.screenY - ( height / 2);const popup = window.open(paymentUrl, "Tangopay", `popup=1, location=1, width=${width}, height=${height}, left=${left}, top=${top}`);}</script></body></html>
That will render the following page. In this example, the buyer selected 2 NFTs and then clicked on the pay button. That will launch the payment gateway where the buyer can buy with their wallet or send Ada to an address.
When the buyer clicks on the buy button a new window with Tangopay will be opened and from there the buyer can pay with any of the most used wallets in Cardano.
Code
Check the full code of the example here https://github.com/tango-crypto/tangocrypto-js/tree/main/examples/nfts
Conclusion
And that’s all, if you made it to the end you should have an NFTs in your wallet. For updates follow us on https://twitter.com/tango_crypto