{"id":6023,"date":"2022-07-19T10:50:24","date_gmt":"2022-07-19T10:50:24","guid":{"rendered":"https:\/\/atmecs.com\/?p=6023"},"modified":"2022-08-02T10:43:38","modified_gmt":"2022-08-02T05:13:38","slug":"minting-nfts-through-api-using-truffle-rinkeby","status":"publish","type":"post","link":"https:\/\/atmecs.com\/minting-nfts-through-api-using-truffle-rinkeby\/","title":{"rendered":"Minting NFTs through API using Truffle &#038; Rinkeby"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-post\" data-elementor-id=\"6023\" class=\"elementor elementor-6023\" data-elementor-settings=\"{&quot;ha_cmc_init_switcher&quot;:&quot;no&quot;}\">\n\t\t\t\t\t\t<section class=\"elementor-section elementor-top-section elementor-element elementor-element-c20906d elementor-section-height-min-height elementor-section-boxed elementor-section-height-default elementor-section-items-middle wpr-particle-no wpr-jarallax-no wpr-parallax-no wpr-sticky-section-no\" data-id=\"c20906d\" data-element_type=\"section\" data-settings=\"{&quot;background_background&quot;:&quot;classic&quot;,&quot;_ha_eqh_enable&quot;:false}\">\n\t\t\t\t\t\t<div class=\"elementor-container elementor-column-gap-default\">\n\t\t\t\t\t<div class=\"elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-1d829e3\" data-id=\"1d829e3\" data-element_type=\"column\">\n\t\t\t<div class=\"elementor-widget-wrap elementor-element-populated\">\n\t\t\t\t\t\t<div class=\"elementor-element elementor-element-edced7c elementor-widget elementor-widget-heading\" data-id=\"edced7c\" data-element_type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<h1 class=\"elementor-heading-title elementor-size-default\">Minting NFTs through API using Truffle &amp; Rinkeby<\/h1>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-65409f4 elementor-icon-list--layout-traditional elementor-list-item-link-full_width elementor-widget elementor-widget-icon-list\" data-id=\"65409f4\" data-element_type=\"widget\" data-widget_type=\"icon-list.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<ul class=\"elementor-icon-list-items\">\n\t\t\t\t\t\t\t<li class=\"elementor-icon-list-item\">\n\t\t\t\t\t\t\t\t\t\t\t<span class=\"elementor-icon-list-icon\">\n\t\t\t\t\t\t\t<i aria-hidden=\"true\" class=\"fas fa-user\"><\/i>\t\t\t\t\t\t<\/span>\n\t\t\t\t\t\t\t\t\t\t<span class=\"elementor-icon-list-text\">BHANU MOKKALA<\/span>\n\t\t\t\t\t\t\t\t\t<\/li>\n\t\t\t\t\t\t<\/ul>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t<section class=\"elementor-section elementor-top-section elementor-element elementor-element-1b7737c elementor-section-boxed elementor-section-height-default elementor-section-height-default wpr-particle-no wpr-jarallax-no wpr-parallax-no wpr-sticky-section-no\" data-id=\"1b7737c\" data-element_type=\"section\" data-settings=\"{&quot;background_background&quot;:&quot;classic&quot;,&quot;_ha_eqh_enable&quot;:false}\">\n\t\t\t\t\t\t<div class=\"elementor-container elementor-column-gap-default\">\n\t\t\t\t\t<div class=\"elementor-column elementor-col-50 elementor-top-column elementor-element elementor-element-d551519\" data-id=\"d551519\" data-element_type=\"column\">\n\t\t\t<div class=\"elementor-widget-wrap elementor-element-populated\">\n\t\t\t\t\t\t<div class=\"elementor-element elementor-element-8a179ff elementor-widget elementor-widget-text-editor\" data-id=\"8a179ff\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p><br \/>You need the image \/ art work \/ clip to be uploaded to IPFS. You can use any of the IPFS clients that allow you to upload the asset and pin it which will make the asset available for anyone to access through a link. I am using Pinata Cloud for IPFS<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-2b79c83 elementor-widget elementor-widget-image\" data-id=\"2b79c83\" data-element_type=\"widget\" data-widget_type=\"image.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<img fetchpriority=\"high\" decoding=\"async\" width=\"1024\" height=\"486\" src=\"https:\/\/atmecs.com\/wp-content\/uploads\/2022\/07\/nftreact-1024x486.png\" class=\"attachment-large size-large wp-image-6072\" alt=\"\" srcset=\"https:\/\/atmecs.com\/wp-content\/uploads\/2022\/07\/nftreact-1024x486.png 1024w, https:\/\/atmecs.com\/wp-content\/uploads\/2022\/07\/nftreact-300x142.png 300w, https:\/\/atmecs.com\/wp-content\/uploads\/2022\/07\/nftreact-768x365.png 768w, https:\/\/atmecs.com\/wp-content\/uploads\/2022\/07\/nftreact-1536x730.png 1536w, https:\/\/atmecs.com\/wp-content\/uploads\/2022\/07\/nftreact.png 1280w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/>\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-b21a015 elementor-widget elementor-widget-text-editor\" data-id=\"b21a015\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>It is the season of NFTs and DeFi. In case you have been living under a rock then you need read more about NFTs and DeFi using the following links.<\/p><ul><li><a href=\"https:\/\/ethereum.org\/en\/nft\/\" target=\"_blank\" rel=\"noopener\">Non-fungible tokens (NFT)<\/a><\/li><li><a href=\"https:\/\/ethereum.org\/en\/defi\/\" target=\"_blank\" rel=\"noopener\">Decentralized finance (DeFi)<\/a><\/li><\/ul><p>Now that you understand the terms, let us understand how NFTs are minted. NFT market is definitely moving from a few minters to tools &amp; techniques for content creators to mint NFTs on their own.<br \/>The following are the key steps in minting a NFT.<\/p><ul><li>You need the image \/ art work \/ clip to be uploaded to <a href=\"https:\/\/ipfs.io\/\" target=\"_blank\" rel=\"noopener\">IPFS<\/a>. You can use any of the IPFS clients that allow you to upload the asset and pin it which will make the asset available for any one to access it through a link. I am using <a href=\"https:\/\/www.pinata.cloud\/\" target=\"_blank\" rel=\"noopener\">Pinata<\/a> Cloud for IPFS.<\/li><li>You need some test ethers on your <a href=\"https:\/\/metamask.io\/\" target=\"_blank\" rel=\"noopener\">Metamask<\/a> Wallet. Once you installed Metamask Google Extension, load test ethers using the <a href=\"https:\/\/faucet.rinkeby.io\/\" target=\"_blank\" rel=\"noopener\">Rinkeby faucet<\/a>. Also, load some <a href=\"https:\/\/faucets.chain.link\/\" target=\"_blank\" rel=\"noopener\">LINK<\/a> on your Rinkeby testnet address.<\/li><\/ul><p>I built these APIs on top of an existing repo by <a href=\"https:\/\/github.com\/PatrickAlphaC\" target=\"_blank\" rel=\"noopener\">Patrick Collins<\/a>. Check out the repo in the below GitHub link.<\/p><ul><li><a href=\"https:\/\/github.com\/PatrickAlphaC\/dungeons-and-dragons-nft\" target=\"_blank\" rel=\"noopener\">Chainlink Random Character Creation<\/a><\/li><\/ul><p>The above example deals with minting a collection of \u2018Dungeons and Dragons\u2019 to Rinkeby. It has the following key steps.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-24e622c elementor-widget elementor-widget-heading\" data-id=\"24e622c\" data-element_type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<h4 class=\"elementor-heading-title elementor-size-default\">Step 1:<\/h4>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-f4394e4 ha-has-bg-overlay elementor-widget elementor-widget-text-editor\" data-id=\"f4394e4\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>truffle migrate &#8211;reset &#8211;network rinkeby<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-e4fbec5 elementor-widget elementor-widget-heading\" data-id=\"e4fbec5\" data-element_type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<h4 class=\"elementor-heading-title elementor-size-default\">Step 2:<\/h4>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-ec7d7b9 ha-has-bg-overlay elementor-widget elementor-widget-text-editor\" data-id=\"ec7d7b9\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>truffle exec scripts\/fund-contract.js &#8211;network rinkeby<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-31c1ad2 elementor-widget elementor-widget-heading\" data-id=\"31c1ad2\" data-element_type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<h4 class=\"elementor-heading-title elementor-size-default\">Step 3:<\/h4>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-5ac9f13 ha-has-bg-overlay elementor-widget elementor-widget-text-editor\" data-id=\"5ac9f13\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>truffle exec scripts\/generate-character.js &#8211;network rinkeby<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-c2f1e04 elementor-widget elementor-widget-heading\" data-id=\"c2f1e04\" data-element_type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<h4 class=\"elementor-heading-title elementor-size-default\">Step 4:<\/h4>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-865c38f ha-has-bg-overlay elementor-widget elementor-widget-text-editor\" data-id=\"865c38f\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>truffle exec scripts\/get-character.js &#8211;network rinkeby<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-ae35642 elementor-widget elementor-widget-heading\" data-id=\"ae35642\" data-element_type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<h4 class=\"elementor-heading-title elementor-size-default\">Step 5:<\/h4>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-7be0cde ha-has-bg-overlay elementor-widget elementor-widget-text-editor\" data-id=\"7be0cde\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>truffle exec scripts\/set-token-uri.js &#8211;network rinkeby<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-61490c6 elementor-widget elementor-widget-text-editor\" data-id=\"61490c6\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>Steps 1 &amp; 2 deal with setting up Rinkeby connection and migrating the contracts related to NFT creation to Rinkeby Testnet. Steps 3, 4 &amp; 5 include executing appropriate functions on the migrated contracts to randomly select characters and setting up metadata URI for the minted NFT. Please go through the README.md of the above repo to understand other set up details.<\/p><p>The idea is to build a NodeJS application that will use the above discussed steps. We can a user Node\u2019s Child Process to execute truffle commands on the CLI. Below is an example of wrapping up the first step in the Child Process call.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-e31e1ee ha-has-bg-overlay elementor-widget elementor-widget-text-editor\" data-id=\"e31e1ee\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>app.get(&#8216;\/pushcontract&#8217;, async(req, res) =&gt; {<br \/>try {<br \/>const child = await spawn1(&#8216;truffle migrate &#8211;reset &#8211;network rinkeby&#8217;, [], {shell: true});<br \/>console.log(child.toString());<br \/>res.send(&#8216;Migrate contracts&#8217;);<br \/>} catch (e) {<br \/>console.log(e.stderr.toString())<br \/>}<br \/>})<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-c9be1f0 elementor-widget elementor-widget-text-editor\" data-id=\"c9be1f0\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>Sample code of executing child process<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-462ae80 elementor-widget elementor-widget-text-editor\" data-id=\"462ae80\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>Just like above sample, we can create code to execute the remaining steps mentioned above to complete the minting process. Prior to executing these steps, we need to create the required contract and migrate it to Rinkeby testnet.<\/p><p>We can also create contract needed for minting the NFT using file manipulation in NodeJS. We make changes to the \u2018template\u2019 contract on the fly using NodeJS fs library and then execute the truffle commands to migrate the contracts.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-0c62bba ha-has-bg-overlay elementor-widget elementor-widget-text-editor\" data-id=\"0c62bba\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>app.post(&#8216;\/createcontract&#8217;, async(req, res) =&gt; {<\/p><p>console.log(&#8216;filename&#8217;, req.body.filename);<br \/>files = fs.readdirSync(&#8216;.\/contracts&#8217;);<br \/>console.log(files);<br \/>files.forEach(file =&gt; {<br \/>const fileDir = path.join(&#8216;.\/contracts\/&#8217;, file);<br \/>console.log(fileDir);<br \/>if (file !== &#8216;Migrations.sol&#8217;) {<br \/>try {<br \/>fs.unlinkSync(fileDir);<br \/>} catch (error) {<br \/>console.log(error);<br \/>}<br \/><br \/>}<br \/>})<br \/>fs.copyFileSync(&#8216;sample.sol&#8217;, &#8216;.\/contracts\/&#8217; + req.body.filename + &#8216;.sol&#8217;);<br \/>const data = fs.readFileSync(&#8216;.\/contracts\/&#8217; + req.body.filename + &#8216;.sol&#8217;, &#8216;utf8&#8217;);<br \/>let result = data.replace(\/DungeonsAndDragonsCharacter\/g, req.body.filename);<br \/>fs.writeFileSync(&#8216;.\/contracts\/&#8217; + req.body.filename + &#8216;.sol&#8217;, result, &#8216;utf8&#8217;);<br \/><br \/>fs.unlinkSync(&#8216;.\/migrations\/2_mycontract_migration.js&#8217;);<br \/>fs.copyFileSync(&#8216;2_mycontract_migration_backup.js&#8217;, &#8216;.\/migrations\/2_mycontract_migration.js&#8217;);<br \/>const data1 = fs.readFileSync(&#8216;.\/migrations\/2_mycontract_migration.js&#8217;, &#8216;utf8&#8217;);<br \/>let result1 = data1.replace(\/DungeonsAndDragonsCharacter\/g, req.body.filename);<br \/>fs.writeFileSync(&#8216;.\/migrations\/2_mycontract_migration.js&#8217;, result1, &#8216;utf8&#8217;);<br \/>res.send(&#8216;created contract&#8217;);<\/p><p>})<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-dff8ebd elementor-widget elementor-widget-text-editor\" data-id=\"dff8ebd\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>Sample code of creating Contracts from the sample<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-367a2ae elementor-widget elementor-widget-text-editor\" data-id=\"367a2ae\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>In the above code block, we are copying sample.sol to contracts folder after deleting all the other existing contracts from the contracts folder. After copying sample.sol to contracts folder with desired name, we selectively replace contents of the newly created contract based on the request received in the express API call. The NFTs minted through the above process can be viewed on the opensea Rinkeby testnet gallery.<\/p><p>As discussed above, before we get ready with minting, we need to pin the image \/ art work to IPFS. We can build APIs for uploading and pinning the image to IPFS using Pinata, there are other ways as well. Please go through their docs to identify the APIs for uploading and pinning the image. Once the image is successfully uploaded Pinata APIs return CID which is a unique identifier for the uploaded file \/ image.<\/p><p>https:\/\/ipfs.io\/ipfs\/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx?filename=filename.png<br \/>The final URI looks something like above. The \u2018XXX\u2019 is where the unique CID will be. We need to embed the image URI inside metadata JSON file before uploading the JSON file to IPFS. Please go through metadata folder in Dungeon &amp; Dragons GitHub repo for more details on how the metadata JSON file should look like.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-4d1e3ad ha-has-bg-overlay elementor-widget elementor-widget-text-editor\" data-id=\"4d1e3ad\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>app.post(&#8216;\/upload&#8217;, upload.single(&#8216;File&#8217;),function(req, res) {<\/p><p>console.log(req.file);<br \/><br \/>data.append(&#8216;file&#8217;, fs.createReadStream(req.file.path));<br \/>data.append(&#8216;pinataMetadata&#8217;, &#8216;{&#8220;name&#8221;:&#8221;&#8216; + req.file.filename + &#8216;&#8221;}&#8217;);<\/p><p>var config = {<br \/>method: &#8216;post&#8217;,<br \/>url: &#8216;https:\/\/api.pinata.cloud\/pinning\/pinFileToIPFS&#8217;,<br \/>headers: { <br \/>&#8216;Content-Type&#8217;: &#8216;multipart\/form-data&#8217;, <br \/>&#8216;pinata_api_key&#8217;: &lt;pinata api key&gt;, <br \/>&#8216;pinata_secret_api_key&#8217;: &lt;pinata secret key&gt;, <br \/>&#8230;data.getHeaders()<br \/>},<br \/>data : data<br \/>};<\/p><p>axios(config)<br \/>.then(function (response) {<br \/>console.log(JSON.stringify(response.data));<br \/>res.send(JSON.stringify(response.data));<br \/>})<br \/>.catch(function (error) {<br \/>console.log(error);<br \/>});<\/p><p>});<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-5c7ebfe elementor-widget elementor-widget-text-editor\" data-id=\"5c7ebfe\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>Sample code of uploading file to IPFS using Pinata<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-da94e53 elementor-widget elementor-widget-text-editor\" data-id=\"da94e53\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>Apart from the above, you can also plugin the market place from the opensea using the opensea api. Below is the sample ReactJS code to fetch the NFTs from opensea and display in a NFT Gallery.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-f44d523 ha-has-bg-overlay elementor-widget elementor-widget-text-editor\" data-id=\"f44d523\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>import React, {useState, useEffect } from &#8216;react&#8217;;<br \/>import { Container, Row, Col, Card, Button } from &#8216;react-bootstrap&#8217;;<br \/>import Imgix from &#8216;react-imgix&#8217;;<\/p><p>function MarketPlace() {<br \/>const [isLoading, setIsLoading] = useState(true);<br \/>const [NFTs, setNFTs] = useState([]);<\/p><p>useEffect(() =&gt; {<br \/>setIsLoading(true);<br \/>var requestOptions = {<br \/>method: &#8216;GET&#8217;,<br \/>redirect: &#8216;follow&#8217;<br \/>};<br \/><br \/>fetch(&#8220;https:\/\/testnets-api.opensea.io\/api\/v1\/assets?owner=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx&amp;offset=0&amp;limit=50&#8221;, requestOptions)<br \/>.then(response =&gt; response.json())<br \/>.then((result) =&gt; {<br \/>console.log(&#8216;Success:&#8217;, result);<br \/>setIsLoading(false);<br \/>const result1 = result.assets.filter(d =&gt; d.image_thumbnail_url !== null)<br \/>setNFTs(result1);<br \/>})<br \/>.catch(error =&gt; console.log(&#8216;error&#8217;, error));<br \/>}, []);<\/p><p>if (isLoading) {<br \/>return (<br \/>&lt;section&gt;<br \/>Loading&#8230;.<br \/>&lt;\/section&gt;<br \/>)<br \/>}<\/p><p>return (<br \/>&lt;div style={{ backgroundColor: &#8216;#111&#8217;}}&gt;<br \/>&lt;Container className=&#8217;mt-4&#8242;&gt;<br \/>&lt;Row&gt;<br \/>{NFTs.map(plan =&gt; (<br \/>&lt;Col md={3}&gt;<br \/>&lt;Card bg=&#8221;dark&#8221; text=&#8221;white&#8221;&gt;<br \/>&lt;div style={{ textAlign: &#8216;center&#8217;}}&gt;<br \/>{\/* &lt;Card.Img variant=&#8221;top&#8221; src={plan.image_thumbnail_url} style={{ width: &#8220;18rem&#8221;, height: &#8220;20rem&#8221; }} \/&gt; *\/}<br \/>&lt;Imgix src={plan.image_thumbnail_url} sizes=&#8221;800vw&#8221; \/&gt;;<br \/>&lt;\/div&gt;<br \/>&lt;Card.Body&gt;<br \/>&lt;Card.Title&gt;{plan.name}&lt;\/Card.Title&gt;<br \/>&lt;Card.Text&gt;{plan.description.replace(\/^(.{20}[^\\s]*).*\/, &#8220;$1&#8221;)}&lt;\/Card.Text&gt;<br \/>&lt;Button variant=&#8221;primary&#8221; onClick={() =&gt; window.open(plan.permalink, &#8220;_blank&#8221;)}&gt;Buy This NFT&lt;\/Button&gt;<br \/>&lt;\/Card.Body&gt;<br \/>&lt;\/Card&gt;<br \/>&lt;Card style={{ backgroundColor: &#8216;#111&#8217; }}&gt;&lt;br&gt;&lt;\/br&gt;&lt;\/Card&gt;<br \/>&lt;\/Col&gt; <br \/>))}<br \/>&lt;\/Row&gt;<br \/>&lt;\/Container&gt;<br \/>&lt;\/div&gt;<br \/>);<\/p><p>}<\/p><p>export default MarketPlace<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-419512d elementor-widget elementor-widget-text-editor\" data-id=\"419512d\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>Code to extract minted NFTs from Opensea and display as a NFT Gallery<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-76d2b7d elementor-widget elementor-widget-text-editor\" data-id=\"76d2b7d\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>This approach gives a better understanding of what goes into minting an NFT. This is definitely not a production ready code. For that, we may have to take out truffle and build using <a href=\"https:\/\/web3js.readthedocs.io\/en\/v1.5.2\/\" target=\"_blank\" rel=\"noopener\">web3js<\/a>.<\/p><p>Happy Minting!!<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t<div class=\"elementor-column elementor-col-50 elementor-top-column elementor-element elementor-element-58cfecf\" data-id=\"58cfecf\" data-element_type=\"column\">\n\t\t\t<div class=\"elementor-widget-wrap\">\n\t\t\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"<p>Minting NFTs through API using Truffle &#038; Rinkeby BHANU MOKKALA You need the image \/ art work \/ clip to be uploaded to IPFS. You can use any of the IPFS clients that allow you to upload the asset and pin it which will make the asset available for anyone to access through a link. I am using Pinata Cloud for IPFS It is the season of NFTs and DeFi. In case you have been living under a rock then you need read more about NFTs and DeFi using the following links. Non-fungible tokens (NFT) Decentralized finance (DeFi) Now that you understand the terms, let us understand how NFTs are minted. NFT market is definitely moving from a few minters to tools &amp; techniques for content creators to mint NFTs on their own.The following are the key steps in minting a NFT. You need the image \/ art work \/ clip to be uploaded to IPFS. You can use any of the IPFS clients that allow you to upload the asset and pin it which will make the asset available for any one to access it through a link. I am using Pinata Cloud for IPFS. You need some test ethers on your Metamask Wallet. Once you installed Metamask Google Extension, load test ethers using the Rinkeby faucet. Also, load some LINK on your Rinkeby testnet address. I built these APIs on top of an existing repo by Patrick Collins. Check out the repo in the below GitHub link. Chainlink Random Character Creation The above example deals with minting a collection of \u2018Dungeons and Dragons\u2019 to Rinkeby. It has the following key steps. Step 1: truffle migrate &#8211;reset &#8211;network rinkeby Step 2: truffle exec scripts\/fund-contract.js &#8211;network rinkeby Step 3: truffle exec scripts\/generate-character.js &#8211;network rinkeby Step 4: truffle exec scripts\/get-character.js &#8211;network rinkeby Step 5: truffle exec scripts\/set-token-uri.js &#8211;network rinkeby Steps 1 &amp; 2 deal with setting up Rinkeby connection and migrating the contracts related to NFT creation to Rinkeby Testnet. Steps 3, 4 &amp; 5 include executing appropriate functions on the migrated contracts to randomly select characters and setting up metadata URI for the minted NFT. Please go through the README.md of the above repo to understand other set up details. The idea is to build a NodeJS application that will use the above discussed steps. We can a user Node\u2019s Child Process to execute truffle commands on the CLI. Below is an example of wrapping up the first step in the Child Process call. app.get(&#8216;\/pushcontract&#8217;, async(req, res) =&gt; {try {const child = await spawn1(&#8216;truffle migrate &#8211;reset &#8211;network rinkeby&#8217;, [], {shell: true});console.log(child.toString());res.send(&#8216;Migrate contracts&#8217;);} catch (e) {console.log(e.stderr.toString())}}) Sample code of executing child process Just like above sample, we can create code to execute the remaining steps mentioned above to complete the minting process. Prior to executing these steps, we need to create the required contract and migrate it to Rinkeby testnet. We can also create contract needed for minting the NFT using file manipulation in NodeJS. We make changes to the \u2018template\u2019 contract on the fly using NodeJS fs library and then execute the truffle commands to migrate the contracts. app.post(&#8216;\/createcontract&#8217;, async(req, res) =&gt; { console.log(&#8216;filename&#8217;, req.body.filename);files = fs.readdirSync(&#8216;.\/contracts&#8217;);console.log(files);files.forEach(file =&gt; {const fileDir = path.join(&#8216;.\/contracts\/&#8217;, file);console.log(fileDir);if (file !== &#8216;Migrations.sol&#8217;) {try {fs.unlinkSync(fileDir);} catch (error) {console.log(error);} }})fs.copyFileSync(&#8216;sample.sol&#8217;, &#8216;.\/contracts\/&#8217; + req.body.filename + &#8216;.sol&#8217;);const data = fs.readFileSync(&#8216;.\/contracts\/&#8217; + req.body.filename + &#8216;.sol&#8217;, &#8216;utf8&#8217;);let result = data.replace(\/DungeonsAndDragonsCharacter\/g, req.body.filename);fs.writeFileSync(&#8216;.\/contracts\/&#8217; + req.body.filename + &#8216;.sol&#8217;, result, &#8216;utf8&#8217;); fs.unlinkSync(&#8216;.\/migrations\/2_mycontract_migration.js&#8217;);fs.copyFileSync(&#8216;2_mycontract_migration_backup.js&#8217;, &#8216;.\/migrations\/2_mycontract_migration.js&#8217;);const data1 = fs.readFileSync(&#8216;.\/migrations\/2_mycontract_migration.js&#8217;, &#8216;utf8&#8217;);let result1 = data1.replace(\/DungeonsAndDragonsCharacter\/g, req.body.filename);fs.writeFileSync(&#8216;.\/migrations\/2_mycontract_migration.js&#8217;, result1, &#8216;utf8&#8217;);res.send(&#8216;created contract&#8217;); }) Sample code of creating Contracts from the sample In the above code block, we are copying sample.sol to contracts folder after deleting all the other existing contracts from the contracts folder. After copying sample.sol to contracts folder with desired name, we selectively replace contents of the newly created contract based on the request received in the express API call. The NFTs minted through the above process can be viewed on the opensea Rinkeby testnet gallery. As discussed above, before we get ready with minting, we need to pin the image \/ art work to IPFS. We can build APIs for uploading and pinning the image to IPFS using Pinata, there are other ways as well. Please go through their docs to identify the APIs for uploading and pinning the image. Once the image is successfully uploaded Pinata APIs return CID which is a unique identifier for the uploaded file \/ image. https:\/\/ipfs.io\/ipfs\/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx?filename=filename.pngThe final URI looks something like above. The \u2018XXX\u2019 is where the unique CID will be. We need to embed the image URI inside metadata JSON file before uploading the JSON file to IPFS. Please go through metadata folder in Dungeon &amp; Dragons GitHub repo for more details on how the metadata JSON file should look like. app.post(&#8216;\/upload&#8217;, upload.single(&#8216;File&#8217;),function(req, res) { console.log(req.file); data.append(&#8216;file&#8217;, fs.createReadStream(req.file.path));data.append(&#8216;pinataMetadata&#8217;, &#8216;{&#8220;name&#8221;:&#8221;&#8216; + req.file.filename + &#8216;&#8221;}&#8217;); var config = {method: &#8216;post&#8217;,url: &#8216;https:\/\/api.pinata.cloud\/pinning\/pinFileToIPFS&#8217;,headers: { &#8216;Content-Type&#8217;: &#8216;multipart\/form-data&#8217;, &#8216;pinata_api_key&#8217;: &lt;pinata api key&gt;, &#8216;pinata_secret_api_key&#8217;: &lt;pinata secret key&gt;, &#8230;data.getHeaders()},data : data}; axios(config).then(function (response) {console.log(JSON.stringify(response.data));res.send(JSON.stringify(response.data));}).catch(function (error) {console.log(error);}); }); Sample code of uploading file to IPFS using Pinata Apart from the above, you can also plugin the market place from the opensea using the opensea api. Below is the sample ReactJS code to fetch the NFTs from opensea and display in a NFT Gallery. import React, {useState, useEffect } from &#8216;react&#8217;;import { Container, Row, Col, Card, Button } from &#8216;react-bootstrap&#8217;;import Imgix from &#8216;react-imgix&#8217;; function MarketPlace() {const [isLoading, setIsLoading] = useState(true);const [NFTs, setNFTs] = useState([]); useEffect(() =&gt; {setIsLoading(true);var requestOptions = {method: &#8216;GET&#8217;,redirect: &#8216;follow&#8217;}; fetch(&#8220;https:\/\/testnets-api.opensea.io\/api\/v1\/assets?owner=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx&amp;offset=0&amp;limit=50&#8221;, requestOptions).then(response =&gt; response.json()).then((result) =&gt; {console.log(&#8216;Success:&#8217;, result);setIsLoading(false);const result1 = result.assets.filter(d =&gt; d.image_thumbnail_url !== null)setNFTs(result1);}).catch(error =&gt; console.log(&#8216;error&#8217;, error));}, []); if (isLoading) {return (&lt;section&gt;Loading&#8230;.&lt;\/section&gt;)} return (&lt;div style={{ backgroundColor: &#8216;#111&#8217;}}&gt;&lt;Container className=&#8217;mt-4&#8242;&gt;&lt;Row&gt;{NFTs.map(plan =&gt; (&lt;Col md={3}&gt;&lt;Card bg=&#8221;dark&#8221; text=&#8221;white&#8221;&gt;&lt;div style={{ textAlign: &#8216;center&#8217;}}&gt;{\/* &lt;Card.Img variant=&#8221;top&#8221; src={plan.image_thumbnail_url} style={{ width: &#8220;18rem&#8221;, height: &#8220;20rem&#8221; }} \/&gt; *\/}&lt;Imgix src={plan.image_thumbnail_url} sizes=&#8221;800vw&#8221; \/&gt;;&lt;\/div&gt;&lt;Card.Body&gt;&lt;Card.Title&gt;{plan.name}&lt;\/Card.Title&gt;&lt;Card.Text&gt;{plan.description.replace(\/^(.{20}[^s]*).*\/, &#8220;$1&#8221;)}&lt;\/Card.Text&gt;&lt;Button variant=&#8221;primary&#8221; onClick={() =&gt; window.open(plan.permalink, &#8220;_blank&#8221;)}&gt;Buy This NFT&lt;\/Button&gt;&lt;\/Card.Body&gt;&lt;\/Card&gt;&lt;Card style={{ backgroundColor: &#8216;#111&#8217; }}&gt;&lt;br&gt;&lt;\/br&gt;&lt;\/Card&gt;&lt;\/Col&gt; ))}&lt;\/Row&gt;&lt;\/Container&gt;&lt;\/div&gt;); } export default MarketPlace Code to extract minted NFTs from Opensea and display as a NFT Gallery This approach gives a better understanding of what goes into minting<\/p>\n","protected":false},"author":1,"featured_media":8198,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"site-sidebar-layout":"no-sidebar","site-content-layout":"page-builder","ast-site-content-layout":"default","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"disabled","ast-breadcrumbs-content":"","ast-featured-img":"disabled","footer-sml-layout":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"default","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"footnotes":""},"categories":[102],"tags":[116,117,118,119],"class_list":["post-6023","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-atmecs-blog","tag-blockchain","tag-cryptocurrency","tag-nft","tag-non-fungible-token"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v26.0 (Yoast SEO v26.0) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Minting NFTs through API using Truffle &#038; Rinkeby - ATMECS<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/atmecs.com\/minting-nfts-through-api-using-truffle-rinkeby\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Minting NFTs through API using Truffle &#038; Rinkeby\" \/>\n<meta property=\"og:description\" content=\"Minting NFTs through API using Truffle &#038; Rinkeby BHANU MOKKALA You need the image \/ art work \/ clip to be uploaded to IPFS. You can use any of the IPFS clients that allow you to upload the asset and pin it which will make the asset available for anyone to access through a link. I am using Pinata Cloud for IPFS It is the season of NFTs and DeFi. In case you have been living under a rock then you need read more about NFTs and DeFi using the following links. Non-fungible tokens (NFT) Decentralized finance (DeFi) Now that you understand the terms, let us understand how NFTs are minted. NFT market is definitely moving from a few minters to tools &amp; techniques for content creators to mint NFTs on their own.The following are the key steps in minting a NFT. You need the image \/ art work \/ clip to be uploaded to IPFS. You can use any of the IPFS clients that allow you to upload the asset and pin it which will make the asset available for any one to access it through a link. I am using Pinata Cloud for IPFS. You need some test ethers on your Metamask Wallet. Once you installed Metamask Google Extension, load test ethers using the Rinkeby faucet. Also, load some LINK on your Rinkeby testnet address. I built these APIs on top of an existing repo by Patrick Collins. Check out the repo in the below GitHub link. Chainlink Random Character Creation The above example deals with minting a collection of \u2018Dungeons and Dragons\u2019 to Rinkeby. It has the following key steps. Step 1: truffle migrate &#8211;reset &#8211;network rinkeby Step 2: truffle exec scripts\/fund-contract.js &#8211;network rinkeby Step 3: truffle exec scripts\/generate-character.js &#8211;network rinkeby Step 4: truffle exec scripts\/get-character.js &#8211;network rinkeby Step 5: truffle exec scripts\/set-token-uri.js &#8211;network rinkeby Steps 1 &amp; 2 deal with setting up Rinkeby connection and migrating the contracts related to NFT creation to Rinkeby Testnet. Steps 3, 4 &amp; 5 include executing appropriate functions on the migrated contracts to randomly select characters and setting up metadata URI for the minted NFT. Please go through the README.md of the above repo to understand other set up details. The idea is to build a NodeJS application that will use the above discussed steps. We can a user Node\u2019s Child Process to execute truffle commands on the CLI. Below is an example of wrapping up the first step in the Child Process call. app.get(&#8216;\/pushcontract&#8217;, async(req, res) =&gt; {try {const child = await spawn1(&#8216;truffle migrate &#8211;reset &#8211;network rinkeby&#8217;, [], {shell: true});console.log(child.toString());res.send(&#8216;Migrate contracts&#8217;);} catch (e) {console.log(e.stderr.toString())}}) Sample code of executing child process Just like above sample, we can create code to execute the remaining steps mentioned above to complete the minting process. Prior to executing these steps, we need to create the required contract and migrate it to Rinkeby testnet. We can also create contract needed for minting the NFT using file manipulation in NodeJS. We make changes to the \u2018template\u2019 contract on the fly using NodeJS fs library and then execute the truffle commands to migrate the contracts. app.post(&#8216;\/createcontract&#8217;, async(req, res) =&gt; { console.log(&#8216;filename&#8217;, req.body.filename);files = fs.readdirSync(&#8216;.\/contracts&#8217;);console.log(files);files.forEach(file =&gt; {const fileDir = path.join(&#8216;.\/contracts\/&#8217;, file);console.log(fileDir);if (file !== &#8216;Migrations.sol&#8217;) {try {fs.unlinkSync(fileDir);} catch (error) {console.log(error);} }})fs.copyFileSync(&#8216;sample.sol&#8217;, &#8216;.\/contracts\/&#8217; + req.body.filename + &#8216;.sol&#8217;);const data = fs.readFileSync(&#8216;.\/contracts\/&#8217; + req.body.filename + &#8216;.sol&#8217;, &#8216;utf8&#8217;);let result = data.replace(\/DungeonsAndDragonsCharacter\/g, req.body.filename);fs.writeFileSync(&#8216;.\/contracts\/&#8217; + req.body.filename + &#8216;.sol&#8217;, result, &#8216;utf8&#8217;); fs.unlinkSync(&#8216;.\/migrations\/2_mycontract_migration.js&#8217;);fs.copyFileSync(&#8216;2_mycontract_migration_backup.js&#8217;, &#8216;.\/migrations\/2_mycontract_migration.js&#8217;);const data1 = fs.readFileSync(&#8216;.\/migrations\/2_mycontract_migration.js&#8217;, &#8216;utf8&#8217;);let result1 = data1.replace(\/DungeonsAndDragonsCharacter\/g, req.body.filename);fs.writeFileSync(&#8216;.\/migrations\/2_mycontract_migration.js&#8217;, result1, &#8216;utf8&#8217;);res.send(&#8216;created contract&#8217;); }) Sample code of creating Contracts from the sample In the above code block, we are copying sample.sol to contracts folder after deleting all the other existing contracts from the contracts folder. After copying sample.sol to contracts folder with desired name, we selectively replace contents of the newly created contract based on the request received in the express API call. The NFTs minted through the above process can be viewed on the opensea Rinkeby testnet gallery. As discussed above, before we get ready with minting, we need to pin the image \/ art work to IPFS. We can build APIs for uploading and pinning the image to IPFS using Pinata, there are other ways as well. Please go through their docs to identify the APIs for uploading and pinning the image. Once the image is successfully uploaded Pinata APIs return CID which is a unique identifier for the uploaded file \/ image. https:\/\/ipfs.io\/ipfs\/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx?filename=filename.pngThe final URI looks something like above. The \u2018XXX\u2019 is where the unique CID will be. We need to embed the image URI inside metadata JSON file before uploading the JSON file to IPFS. Please go through metadata folder in Dungeon &amp; Dragons GitHub repo for more details on how the metadata JSON file should look like. app.post(&#8216;\/upload&#8217;, upload.single(&#8216;File&#8217;),function(req, res) { console.log(req.file); data.append(&#8216;file&#8217;, fs.createReadStream(req.file.path));data.append(&#8216;pinataMetadata&#8217;, &#8216;{&#8220;name&#8221;:&#8221;&#8216; + req.file.filename + &#8216;&#8221;}&#8217;); var config = {method: &#8216;post&#8217;,url: &#8216;https:\/\/api.pinata.cloud\/pinning\/pinFileToIPFS&#8217;,headers: { &#8216;Content-Type&#8217;: &#8216;multipart\/form-data&#8217;, &#8216;pinata_api_key&#8217;: &lt;pinata api key&gt;, &#8216;pinata_secret_api_key&#8217;: &lt;pinata secret key&gt;, &#8230;data.getHeaders()},data : data}; axios(config).then(function (response) {console.log(JSON.stringify(response.data));res.send(JSON.stringify(response.data));}).catch(function (error) {console.log(error);}); }); Sample code of uploading file to IPFS using Pinata Apart from the above, you can also plugin the market place from the opensea using the opensea api. Below is the sample ReactJS code to fetch the NFTs from opensea and display in a NFT Gallery. import React, {useState, useEffect } from &#8216;react&#8217;;import { Container, Row, Col, Card, Button } from &#8216;react-bootstrap&#8217;;import Imgix from &#8216;react-imgix&#8217;; function MarketPlace() {const [isLoading, setIsLoading] = useState(true);const [NFTs, setNFTs] = useState([]); useEffect(() =&gt; {setIsLoading(true);var requestOptions = {method: &#8216;GET&#8217;,redirect: &#8216;follow&#8217;}; fetch(&#8220;https:\/\/testnets-api.opensea.io\/api\/v1\/assets?owner=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx&amp;offset=0&amp;limit=50&#8221;, requestOptions).then(response =&gt; response.json()).then((result) =&gt; {console.log(&#8216;Success:&#8217;, result);setIsLoading(false);const result1 = result.assets.filter(d =&gt; d.image_thumbnail_url !== null)setNFTs(result1);}).catch(error =&gt; console.log(&#8216;error&#8217;, error));}, []); if (isLoading) {return (&lt;section&gt;Loading&#8230;.&lt;\/section&gt;)} return (&lt;div style={{ backgroundColor: &#8216;#111&#8217;}}&gt;&lt;Container className=&#8217;mt-4&#8242;&gt;&lt;Row&gt;{NFTs.map(plan =&gt; (&lt;Col md={3}&gt;&lt;Card bg=&#8221;dark&#8221; text=&#8221;white&#8221;&gt;&lt;div style={{ textAlign: &#8216;center&#8217;}}&gt;{\/* &lt;Card.Img variant=&#8221;top&#8221; src={plan.image_thumbnail_url} style={{ width: &#8220;18rem&#8221;, height: &#8220;20rem&#8221; }} \/&gt; *\/}&lt;Imgix src={plan.image_thumbnail_url} sizes=&#8221;800vw&#8221; \/&gt;;&lt;\/div&gt;&lt;Card.Body&gt;&lt;Card.Title&gt;{plan.name}&lt;\/Card.Title&gt;&lt;Card.Text&gt;{plan.description.replace(\/^(.{20}[^s]*).*\/, &#8220;$1&#8221;)}&lt;\/Card.Text&gt;&lt;Button variant=&#8221;primary&#8221; onClick={() =&gt; window.open(plan.permalink, &#8220;_blank&#8221;)}&gt;Buy This NFT&lt;\/Button&gt;&lt;\/Card.Body&gt;&lt;\/Card&gt;&lt;Card style={{ backgroundColor: &#8216;#111&#8217; }}&gt;&lt;br&gt;&lt;\/br&gt;&lt;\/Card&gt;&lt;\/Col&gt; ))}&lt;\/Row&gt;&lt;\/Container&gt;&lt;\/div&gt;); } export default MarketPlace Code to extract minted NFTs from Opensea and display as a NFT Gallery This approach gives a better understanding of what goes into minting\" \/>\n<meta property=\"og:url\" content=\"https:\/\/atmecs.com\/minting-nfts-through-api-using-truffle-rinkeby\/\" \/>\n<meta property=\"og:site_name\" content=\"ATMECS\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/ATMECS\" \/>\n<meta property=\"article:published_time\" content=\"2022-07-19T10:50:24+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2022-08-02T05:13:38+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/atmecs.com\/wp-content\/uploads\/2022\/07\/NFT_sports.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"1140\" \/>\n\t<meta property=\"og:image:height\" content=\"760\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Team Atmecs\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@atmecs\" \/>\n<meta name=\"twitter:site\" content=\"@atmecs\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Team Atmecs\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"7 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/atmecs.com\/minting-nfts-through-api-using-truffle-rinkeby\/\",\"url\":\"https:\/\/atmecs.com\/minting-nfts-through-api-using-truffle-rinkeby\/\",\"name\":\"Minting NFTs through API using Truffle &#038; Rinkeby - ATMECS\",\"isPartOf\":{\"@id\":\"https:\/\/atmecs.com\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/atmecs.com\/minting-nfts-through-api-using-truffle-rinkeby\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/atmecs.com\/minting-nfts-through-api-using-truffle-rinkeby\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/atmecs.com\/wp-content\/uploads\/2022\/07\/NFT_sports.jpg\",\"datePublished\":\"2022-07-19T10:50:24+00:00\",\"dateModified\":\"2022-08-02T05:13:38+00:00\",\"author\":{\"@id\":\"https:\/\/atmecs.com\/#\/schema\/person\/1033d72581d5f10351657dfd8d267318\"},\"breadcrumb\":{\"@id\":\"https:\/\/atmecs.com\/minting-nfts-through-api-using-truffle-rinkeby\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/atmecs.com\/minting-nfts-through-api-using-truffle-rinkeby\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/atmecs.com\/minting-nfts-through-api-using-truffle-rinkeby\/#primaryimage\",\"url\":\"https:\/\/atmecs.com\/wp-content\/uploads\/2022\/07\/NFT_sports.jpg\",\"contentUrl\":\"https:\/\/atmecs.com\/wp-content\/uploads\/2022\/07\/NFT_sports.jpg\",\"width\":1140,\"height\":760,\"caption\":\"Atmecs Blog\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/atmecs.com\/minting-nfts-through-api-using-truffle-rinkeby\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/atmecs.com\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Minting NFTs through API using Truffle &#038; Rinkeby\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/atmecs.com\/#website\",\"url\":\"https:\/\/atmecs.com\/\",\"name\":\"ATMECS\",\"description\":\":: A True R&amp;D Services Company\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/atmecs.com\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/atmecs.com\/#\/schema\/person\/1033d72581d5f10351657dfd8d267318\",\"name\":\"Team Atmecs\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/atmecs.com\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/59823930fdf2c4fc577109b8c928f57ee469a527be5b3882973d26a06d497874?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/59823930fdf2c4fc577109b8c928f57ee469a527be5b3882973d26a06d497874?s=96&d=mm&r=g\",\"caption\":\"Team Atmecs\"},\"sameAs\":[\"https:\/\/atmecs.com\"],\"url\":\"https:\/\/atmecs.com\/author\/admin\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Minting NFTs through API using Truffle &#038; Rinkeby - ATMECS","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/atmecs.com\/minting-nfts-through-api-using-truffle-rinkeby\/","og_locale":"en_US","og_type":"article","og_title":"Minting NFTs through API using Truffle &#038; Rinkeby","og_description":"Minting NFTs through API using Truffle &#038; Rinkeby BHANU MOKKALA You need the image \/ art work \/ clip to be uploaded to IPFS. You can use any of the IPFS clients that allow you to upload the asset and pin it which will make the asset available for anyone to access through a link. I am using Pinata Cloud for IPFS It is the season of NFTs and DeFi. In case you have been living under a rock then you need read more about NFTs and DeFi using the following links. Non-fungible tokens (NFT) Decentralized finance (DeFi) Now that you understand the terms, let us understand how NFTs are minted. NFT market is definitely moving from a few minters to tools &amp; techniques for content creators to mint NFTs on their own.The following are the key steps in minting a NFT. You need the image \/ art work \/ clip to be uploaded to IPFS. You can use any of the IPFS clients that allow you to upload the asset and pin it which will make the asset available for any one to access it through a link. I am using Pinata Cloud for IPFS. You need some test ethers on your Metamask Wallet. Once you installed Metamask Google Extension, load test ethers using the Rinkeby faucet. Also, load some LINK on your Rinkeby testnet address. I built these APIs on top of an existing repo by Patrick Collins. Check out the repo in the below GitHub link. Chainlink Random Character Creation The above example deals with minting a collection of \u2018Dungeons and Dragons\u2019 to Rinkeby. It has the following key steps. Step 1: truffle migrate &#8211;reset &#8211;network rinkeby Step 2: truffle exec scripts\/fund-contract.js &#8211;network rinkeby Step 3: truffle exec scripts\/generate-character.js &#8211;network rinkeby Step 4: truffle exec scripts\/get-character.js &#8211;network rinkeby Step 5: truffle exec scripts\/set-token-uri.js &#8211;network rinkeby Steps 1 &amp; 2 deal with setting up Rinkeby connection and migrating the contracts related to NFT creation to Rinkeby Testnet. Steps 3, 4 &amp; 5 include executing appropriate functions on the migrated contracts to randomly select characters and setting up metadata URI for the minted NFT. Please go through the README.md of the above repo to understand other set up details. The idea is to build a NodeJS application that will use the above discussed steps. We can a user Node\u2019s Child Process to execute truffle commands on the CLI. Below is an example of wrapping up the first step in the Child Process call. app.get(&#8216;\/pushcontract&#8217;, async(req, res) =&gt; {try {const child = await spawn1(&#8216;truffle migrate &#8211;reset &#8211;network rinkeby&#8217;, [], {shell: true});console.log(child.toString());res.send(&#8216;Migrate contracts&#8217;);} catch (e) {console.log(e.stderr.toString())}}) Sample code of executing child process Just like above sample, we can create code to execute the remaining steps mentioned above to complete the minting process. Prior to executing these steps, we need to create the required contract and migrate it to Rinkeby testnet. We can also create contract needed for minting the NFT using file manipulation in NodeJS. We make changes to the \u2018template\u2019 contract on the fly using NodeJS fs library and then execute the truffle commands to migrate the contracts. app.post(&#8216;\/createcontract&#8217;, async(req, res) =&gt; { console.log(&#8216;filename&#8217;, req.body.filename);files = fs.readdirSync(&#8216;.\/contracts&#8217;);console.log(files);files.forEach(file =&gt; {const fileDir = path.join(&#8216;.\/contracts\/&#8217;, file);console.log(fileDir);if (file !== &#8216;Migrations.sol&#8217;) {try {fs.unlinkSync(fileDir);} catch (error) {console.log(error);} }})fs.copyFileSync(&#8216;sample.sol&#8217;, &#8216;.\/contracts\/&#8217; + req.body.filename + &#8216;.sol&#8217;);const data = fs.readFileSync(&#8216;.\/contracts\/&#8217; + req.body.filename + &#8216;.sol&#8217;, &#8216;utf8&#8217;);let result = data.replace(\/DungeonsAndDragonsCharacter\/g, req.body.filename);fs.writeFileSync(&#8216;.\/contracts\/&#8217; + req.body.filename + &#8216;.sol&#8217;, result, &#8216;utf8&#8217;); fs.unlinkSync(&#8216;.\/migrations\/2_mycontract_migration.js&#8217;);fs.copyFileSync(&#8216;2_mycontract_migration_backup.js&#8217;, &#8216;.\/migrations\/2_mycontract_migration.js&#8217;);const data1 = fs.readFileSync(&#8216;.\/migrations\/2_mycontract_migration.js&#8217;, &#8216;utf8&#8217;);let result1 = data1.replace(\/DungeonsAndDragonsCharacter\/g, req.body.filename);fs.writeFileSync(&#8216;.\/migrations\/2_mycontract_migration.js&#8217;, result1, &#8216;utf8&#8217;);res.send(&#8216;created contract&#8217;); }) Sample code of creating Contracts from the sample In the above code block, we are copying sample.sol to contracts folder after deleting all the other existing contracts from the contracts folder. After copying sample.sol to contracts folder with desired name, we selectively replace contents of the newly created contract based on the request received in the express API call. The NFTs minted through the above process can be viewed on the opensea Rinkeby testnet gallery. As discussed above, before we get ready with minting, we need to pin the image \/ art work to IPFS. We can build APIs for uploading and pinning the image to IPFS using Pinata, there are other ways as well. Please go through their docs to identify the APIs for uploading and pinning the image. Once the image is successfully uploaded Pinata APIs return CID which is a unique identifier for the uploaded file \/ image. https:\/\/ipfs.io\/ipfs\/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx?filename=filename.pngThe final URI looks something like above. The \u2018XXX\u2019 is where the unique CID will be. We need to embed the image URI inside metadata JSON file before uploading the JSON file to IPFS. Please go through metadata folder in Dungeon &amp; Dragons GitHub repo for more details on how the metadata JSON file should look like. app.post(&#8216;\/upload&#8217;, upload.single(&#8216;File&#8217;),function(req, res) { console.log(req.file); data.append(&#8216;file&#8217;, fs.createReadStream(req.file.path));data.append(&#8216;pinataMetadata&#8217;, &#8216;{&#8220;name&#8221;:&#8221;&#8216; + req.file.filename + &#8216;&#8221;}&#8217;); var config = {method: &#8216;post&#8217;,url: &#8216;https:\/\/api.pinata.cloud\/pinning\/pinFileToIPFS&#8217;,headers: { &#8216;Content-Type&#8217;: &#8216;multipart\/form-data&#8217;, &#8216;pinata_api_key&#8217;: &lt;pinata api key&gt;, &#8216;pinata_secret_api_key&#8217;: &lt;pinata secret key&gt;, &#8230;data.getHeaders()},data : data}; axios(config).then(function (response) {console.log(JSON.stringify(response.data));res.send(JSON.stringify(response.data));}).catch(function (error) {console.log(error);}); }); Sample code of uploading file to IPFS using Pinata Apart from the above, you can also plugin the market place from the opensea using the opensea api. Below is the sample ReactJS code to fetch the NFTs from opensea and display in a NFT Gallery. import React, {useState, useEffect } from &#8216;react&#8217;;import { Container, Row, Col, Card, Button } from &#8216;react-bootstrap&#8217;;import Imgix from &#8216;react-imgix&#8217;; function MarketPlace() {const [isLoading, setIsLoading] = useState(true);const [NFTs, setNFTs] = useState([]); useEffect(() =&gt; {setIsLoading(true);var requestOptions = {method: &#8216;GET&#8217;,redirect: &#8216;follow&#8217;}; fetch(&#8220;https:\/\/testnets-api.opensea.io\/api\/v1\/assets?owner=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx&amp;offset=0&amp;limit=50&#8221;, requestOptions).then(response =&gt; response.json()).then((result) =&gt; {console.log(&#8216;Success:&#8217;, result);setIsLoading(false);const result1 = result.assets.filter(d =&gt; d.image_thumbnail_url !== null)setNFTs(result1);}).catch(error =&gt; console.log(&#8216;error&#8217;, error));}, []); if (isLoading) {return (&lt;section&gt;Loading&#8230;.&lt;\/section&gt;)} return (&lt;div style={{ backgroundColor: &#8216;#111&#8217;}}&gt;&lt;Container className=&#8217;mt-4&#8242;&gt;&lt;Row&gt;{NFTs.map(plan =&gt; (&lt;Col md={3}&gt;&lt;Card bg=&#8221;dark&#8221; text=&#8221;white&#8221;&gt;&lt;div style={{ textAlign: &#8216;center&#8217;}}&gt;{\/* &lt;Card.Img variant=&#8221;top&#8221; src={plan.image_thumbnail_url} style={{ width: &#8220;18rem&#8221;, height: &#8220;20rem&#8221; }} \/&gt; *\/}&lt;Imgix src={plan.image_thumbnail_url} sizes=&#8221;800vw&#8221; \/&gt;;&lt;\/div&gt;&lt;Card.Body&gt;&lt;Card.Title&gt;{plan.name}&lt;\/Card.Title&gt;&lt;Card.Text&gt;{plan.description.replace(\/^(.{20}[^s]*).*\/, &#8220;$1&#8221;)}&lt;\/Card.Text&gt;&lt;Button variant=&#8221;primary&#8221; onClick={() =&gt; window.open(plan.permalink, &#8220;_blank&#8221;)}&gt;Buy This NFT&lt;\/Button&gt;&lt;\/Card.Body&gt;&lt;\/Card&gt;&lt;Card style={{ backgroundColor: &#8216;#111&#8217; }}&gt;&lt;br&gt;&lt;\/br&gt;&lt;\/Card&gt;&lt;\/Col&gt; ))}&lt;\/Row&gt;&lt;\/Container&gt;&lt;\/div&gt;); } export default MarketPlace Code to extract minted NFTs from Opensea and display as a NFT Gallery This approach gives a better understanding of what goes into minting","og_url":"https:\/\/atmecs.com\/minting-nfts-through-api-using-truffle-rinkeby\/","og_site_name":"ATMECS","article_publisher":"https:\/\/www.facebook.com\/ATMECS","article_published_time":"2022-07-19T10:50:24+00:00","article_modified_time":"2022-08-02T05:13:38+00:00","og_image":[{"width":1140,"height":760,"url":"https:\/\/atmecs.com\/wp-content\/uploads\/2022\/07\/NFT_sports.jpg","type":"image\/jpeg"}],"author":"Team Atmecs","twitter_card":"summary_large_image","twitter_creator":"@atmecs","twitter_site":"@atmecs","twitter_misc":{"Written by":"Team Atmecs","Est. reading time":"7 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/atmecs.com\/minting-nfts-through-api-using-truffle-rinkeby\/","url":"https:\/\/atmecs.com\/minting-nfts-through-api-using-truffle-rinkeby\/","name":"Minting NFTs through API using Truffle &#038; Rinkeby - ATMECS","isPartOf":{"@id":"https:\/\/atmecs.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/atmecs.com\/minting-nfts-through-api-using-truffle-rinkeby\/#primaryimage"},"image":{"@id":"https:\/\/atmecs.com\/minting-nfts-through-api-using-truffle-rinkeby\/#primaryimage"},"thumbnailUrl":"https:\/\/atmecs.com\/wp-content\/uploads\/2022\/07\/NFT_sports.jpg","datePublished":"2022-07-19T10:50:24+00:00","dateModified":"2022-08-02T05:13:38+00:00","author":{"@id":"https:\/\/atmecs.com\/#\/schema\/person\/1033d72581d5f10351657dfd8d267318"},"breadcrumb":{"@id":"https:\/\/atmecs.com\/minting-nfts-through-api-using-truffle-rinkeby\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/atmecs.com\/minting-nfts-through-api-using-truffle-rinkeby\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/atmecs.com\/minting-nfts-through-api-using-truffle-rinkeby\/#primaryimage","url":"https:\/\/atmecs.com\/wp-content\/uploads\/2022\/07\/NFT_sports.jpg","contentUrl":"https:\/\/atmecs.com\/wp-content\/uploads\/2022\/07\/NFT_sports.jpg","width":1140,"height":760,"caption":"Atmecs Blog"},{"@type":"BreadcrumbList","@id":"https:\/\/atmecs.com\/minting-nfts-through-api-using-truffle-rinkeby\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/atmecs.com\/"},{"@type":"ListItem","position":2,"name":"Minting NFTs through API using Truffle &#038; Rinkeby"}]},{"@type":"WebSite","@id":"https:\/\/atmecs.com\/#website","url":"https:\/\/atmecs.com\/","name":"ATMECS","description":":: A True R&amp;D Services Company","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/atmecs.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/atmecs.com\/#\/schema\/person\/1033d72581d5f10351657dfd8d267318","name":"Team Atmecs","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/atmecs.com\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/59823930fdf2c4fc577109b8c928f57ee469a527be5b3882973d26a06d497874?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/59823930fdf2c4fc577109b8c928f57ee469a527be5b3882973d26a06d497874?s=96&d=mm&r=g","caption":"Team Atmecs"},"sameAs":["https:\/\/atmecs.com"],"url":"https:\/\/atmecs.com\/author\/admin\/"}]}},"_links":{"self":[{"href":"https:\/\/atmecs.com\/wp-json\/wp\/v2\/posts\/6023","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/atmecs.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/atmecs.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/atmecs.com\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/atmecs.com\/wp-json\/wp\/v2\/comments?post=6023"}],"version-history":[{"count":0,"href":"https:\/\/atmecs.com\/wp-json\/wp\/v2\/posts\/6023\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/atmecs.com\/wp-json\/wp\/v2\/media\/8198"}],"wp:attachment":[{"href":"https:\/\/atmecs.com\/wp-json\/wp\/v2\/media?parent=6023"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/atmecs.com\/wp-json\/wp\/v2\/categories?post=6023"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/atmecs.com\/wp-json\/wp\/v2\/tags?post=6023"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}