Shyft
Start BuildingSupportWebsite
  • Welcome
    • 👋Introducing Shyft
    • 🏗️Start Building
  • Solana Infrastructure
    • 🚁Shyft RPCs
  • Yellowstone gRPC Network
    • Decoding gRPC Latency
    • ⚡gRPC Docs
      • Introduction
      • Authentication
      • Subscribe Requests
      • FAQ
      • Getting Started
        • Initializing the Yellowstone Client
        • Making a gRPC connection
        • Adding a Reconnection Mechanism
        • 🔥Replaying Slots with Solana yellowstone gRPCs
        • Modifying your Subscribe Request
        • Closing a gRPC Connection
      • Subscribing to Transactions
        • All Transactions of an address
        • Subscribing to all transactions of a Liquidity Pool
        • Subscribing to all transactions of multiple addresses
        • Subscribing to all transactions of a Token
      • Subscribing to Accounts
        • Account Updates for a Program
        • Account Updates for an Address
        • Account updates using memcmp
      • Streaming Blocks & BlocksMeta
        • Streaming Block Updates
        • Subscribing to BlocksMeta
      • Modifying & Unsubscribing
  • Solana defi data
    • DeFI APIs
      • Get Pool By Address
      • Get Pools By Token Pair
      • Get All Pools for a Token
      • Get Liquidity Details of a Pool
  • Callbacks
    • ☎️What are Callbacks?
      • Transaction Callbacks
      • Account Callbacks
    • 📔Callback APIs
      • Response Structure
      • List Callbacks
      • Register callback
      • Remove callback
      • 🔥Pause a callback
      • 🔥Resume a callback
      • Update Callbacks
      • Add Addresses
      • Remove addresses
  • Solana Super Indexers
    • 🌩️GraphQL APIs
      • Getting Started
      • Building Queries
      • Paginating Response
      • Applying Filters
      • Ordering and Sorting Data
    • 📀Case Studies
      • Tensor
        • Get Active Listings of a Wallet
        • Get Active Bids of a Wallet
        • Get Active Listings of a Collection
        • Get all Bids of a Collection
        • Get all Pools of a Margin Account
        • Get all Pools by Owner
      • Raydium
        • Get Pool By Address
        • Get Pools By Token Address
        • Get Pools Created Between Time
        • Get Pool Burn Percentage
        • Get Liquidity Details of a Pool
        • Get Pool and OpenBook Market Info
        • Get Token Supply Percentage In Pool
      • Orca Whirlpool
        • Get Pool by Address
        • Get Pool by Token Address
        • Get Positions for a Pool
        • Get Positions for a Wallet
        • Get Liquidity Details of a Pool
      • Kamino
        • Get Borrow Details of a Wallet
        • Get Deposit Details of a Wallet
        • Get Reserve Details
      • Cross Marketplace Queries
        • Get active listings across marketplaces for a wallet
        • Get listings for a collection across marketplaces
        • Get floor price of a collection
      • Cross Defi Queries
        • Fetch Liquidity Pools for Token
      • Native Staking
        • Get Stakes for a Wallet
        • Get Stakes For Validator
      • Governance/Realms
        • Get DAO Token Owners
        • Get Proposals For Governing Mint
        • Get All Proposals For DAO
        • Get DAO Treasury Info
        • Get All Active Proposals For Wallet
      • Meteora
        • Get All LB Position Pairs
        • Get Position of a User Wallet
        • Get Pool by Token Addresses
        • Get All Deposits for a User
        • Get All Withdraws for a User
        • Get All Fees Claimed by a User
        • Get All User Positions and Deposits for a Pool
        • Get All User Positions and Withdrawals for a Pool
      • Fluxbeam
        • Get Pool by Address
        • Get Pool by Token Addresses
      • Drift
        • Get User account for Delegate
        • Get User accounts based on authority
        • Get User details based on Referrer
        • Get Borrow/Deposit Amount for an User
        • Get PrepPositions for an User Account
        • Getting OrderId and userOrderId
        • Get OpenOrders for a User Account
      • 🔥Pumpswap
        • 🔥Get Pool by Address
        • 🔥Get Pool by Creator Address
        • 🔥Get Pools by Token Addresses
      • Raydium Launchpad
        • Get Bonding Curve Details by Pool Address
        • Get All Pools for a Creator
        • Get Pools by Token Addresses
        • Get Migration details of a Pool
  • Solana APIs
    • API Reference
    • Transactions
      • Parsed Transaction Structure
      • Transaction APIs
        • History
        • Parse Signature
        • Parse Multiple Signatures
        • Send
        • Send Multiple
    • NFT
      • 🔥Create Gasless
      • Create
      • Read All
      • Burn
      • 🔥Burn Multiple NFTs V2
      • Update
      • 🔥Create NFT from Metadata
      • 🔥Read Wallet Nfts
      • 🔥Read Selected NFTs
      • 🔥Get NFT Owners
      • 🔥Update NFT Metadata Uri
      • 🔥Update V2
      • Search
      • Transfer
      • Transfer Multiple NFTs
      • Mint
      • Read
    • Wallet
      • Get Balance
      • Get Token Balance
      • Get All Tokens Balance
      • Get Portfolio
      • Resolve Address
      • Get All Domains
      • Get Stake Accounts
    • Fungible Tokens
      • Create
      • Mint
      • Burn
      • 🔥Update
      • Get Token Info
      • Transfer
      • Airdrop
  • 📘Dev Guides
    • 📀gRPC Case Studies
      • Pumpfun
        • Streaming and Parsing Pump.fun Transactions
        • Streaming and Parsing Pump.fun Accounts
        • Detecting new Token launches on Pump.fun
        • Detecting Buy/Sell Transactions on Pump.fun
        • Detecting tokens migrating from Pump.fun to Pump Swap AMM
      • PumpSwap AMM
        • Streaming and Parsing Pump Swap Transactions
        • Streaming and Parsing Pump Swap AMM Accounts
        • Detecting Buy/Sell Transactions on Pump Swap AMM
        • Detecting tokens migrating from Pump.fun to Pump Swap AMM
      • Raydium AMM
        • Streaming and Parsing Raydium AMM Transactions
        • Streaming and Parsing Raydium AMM Accounts
        • Detecting Buy/Sell Transactions on Raydium AMM
        • Detecting new Pools on Raydium AMM
      • Raydium CLMM
        • Streaming and Parsing Raydium CLMM Transactions
        • Streaming and Parsing Raydium CLMM Accounts
      • Raydium CPMM
        • Streaming and Parsing Raydium CPMM Transactions
        • Streaming and Parsing Raydium CPMM Accounts
      • Raydium Launchpad
        • Streaming and Parsing Raydium Launchpad Transactions
        • Streaming and Parsing Raydium Launchpad Accounts
Powered by GitBook
On this page
  • Pre-requisites
  • Setup
  • Let's dive into code
  • Making the API call
  • Signing the Encoded Transaction
  • Ending Notes
  • Resources

Was this helpful?

  1. Tutorials

Build your First NFT Dapp

With Shyft's API you can create applications to mint NFTs.

Last updated 2 years ago

Was this helpful?

In this tutorial we will build a simple dapp that allows you to create an NFT on Solana blockchain, using Shyft APIs. At the end of this tutorial your newly minted NFT will be available in your own wallet.

Pre-requisites

To get started first thing first, let's install a browser extension of Phantom Wallet from below links:

Once installed, open Phantom in your browser, and follow the on-screen steps to create a new wallet. Refer to this , if you need help. Now, you have a public-private key pair that serves as an identity on blockchain.

Install nodeJs and npxx (node package executor)

Steps for mac:

//type the following commands on your terminal:
$ brew update
$ brew install node

//once completed, check if installed properly:
$ node -v
v18.0.0    // if installed properly, should output the node installed version

// install npx:
$ npm i -g npx

Setup

Alright, now we are all set to create our first NFT minting dapp. We will use ReactJs to build a simple front end to allow you to interactively create a NFT. We will use VS Code to walk through the tutorial.

Authentication: Get your Shyft API key

Setup react project

$ npx create-react-app my-first-nft-dapp

This creates the boilerplate code for your dapp, and file structure looks like below:

Let's dive into code

Let's create a new form for accepting all the details(parameters) we will require to create a new NFT. We have created a new component for the form, but you can also put this code directly under App.js

  const [file, setfile] = useState();
  const [network, setnetwork] = useState("devnet");
  const [publicKey, setPublicKey] = useState(''); //your wallet's public key
  const [name, setName] = useState();
  const [symbol, setSymbol] = useState();
  const [desc, setDesc] = useState();
  const [attr, setAttr] = useState();
  const [extUrl, setExtUrl] = useState();
  const [maxSup, setMaxSup] = useState(0);
  const [roy, setRoy] = useState(1);
  
  const [status, setStatus] = useState("Awaiting Upload");
  const [dispResponse, setDispResp] = useState("");
  
  return (
    <div className="App">
      <form>
        <label htmlFor="file">Select File</label>
        <input name="file" type="file" onChange={(e) => {
          setfile(e.target.files[0]));
        }} />
        <br />

        <label htmlFor="network">
          Network <span>(network: string)</span>
        </label>
        <select name="network" onChange={(e) => { setnetwork(e.target.value) }}>
          <option value="devnet">Devnet</option>
          <option value="testnet">Testnet</option>
          <option value="mainnet-beta">Mainnet Beta</option>
        </select>
        <br />

        <label>Public Key (wallet:string)</label>
        <input type="text" value={publicKey} onChange={(e) => setPublicKey(e.target.value)} required />
        <br />

        <label htmlFor="name">Name (name:string)</label>
        <input type="text" name="name" value={name} onChange={(e) => setName(e.target.value)} required />
        <br />

        <label htmlFor="symbol">Symbol (symbol:string)</label>
        <input type="text" name="symbol" value={symbol} onChange={(e) => setSymbol(e.target.value)} required />
        <br />

        <label htmlFor="desc">Description (description:string)</label>
        <textarea name="desc" value={desc} onChange={(e) => setDesc(e.target.value)} required></textarea>
        <br />

        <label htmlFor="attributes">Attributes (attributes:string)</label>
        <textarea name="attributes" value={attr} onChange={(e) => setAttr(e.target.value)} required></textarea>
        <br />

        <label htmlFor="external_url">External Url (external_url:string)</label>
        <input type="text" name="external_url" value={extUrl} onChange={(e) => setExtUrl(e.target.value)} />
        <br />

        <label htmlFor="max_supply">Max Supply (max_supply:number)</label>
        <input type="number" name="max_supply" value={maxSup} onChange={(e) => { setMaxSup(e.target.value) }} required />
        <br />

        <label htmlFor="royalty">Royalty (royalty:number)</label>
        <input type="number" name="royalty" value={roy} onChange={(e) => { setRoy(e.target.value) }} required />
        <br />

        <button type="submit" onClick={mintNow}>
          Submit
        </button>
      </form>

      <textarea
        className="form-control"
        name=""
        value={JSON.stringify(dispResponse)}
        id=""
        cols="30"
        rows="10"
      ></textarea>
    </div>
  );

This is a simple form with takes in the following parameters:

  1. Choose an image file that you want to mint as an NFT

  2. Select the network (testnet, devnet, mainnet-beta)

  3. Your phantom wallet's public key

  4. NFT Name

  5. NFT symbol

  6. NFT description

  7. External_Url, this can be link to any website that you want to put in. This will be visible in the phantom wallet account for navigation.

  8. Number of editions of one particular NFT that can be minted. can be set to zero, if you want to create an one-of-a-kind NFT.

  9. Royalty percentage of the NFT creator. Can be any value between 0 - 100.

  10. Attributes associated to the NFT. It's a json array string, don't forget to Stringify as done in below code snippet.

let attrib = [{"trait_type": "speed", "value": 100},
{"trait_type": "aggression", "value": "crazy"},
{"trait_type": "energy", "value": "very high"}];

let paramsToPass = JSON.stringify(attrib);

//Here we have created 3 attributes for our NFT, namely:
//1. speed = 100
//2. aggression = "crazy"
//3. energy = "very high"

Making the API call

Once we have the data, we are ready to make the API call. For this tutorial, we have used the axios package to make the API call, but you can use any other methods including JavaScript's very own fetch.

"dependencies": {
    ...
    "axios": "^0.27.2"
    ....
  },

axios will allow your react application to make http request to Shyft's server and create your NFT.

Now, let's create a function for making the API call using the data we have collected using the form we created in this tutorial.

const mintNow = (e) => {
e.preventDefault();
setStatus("Loading");
let formData = new FormData();
formData.append("network", network);
formData.append("wallet", publicKey);
formData.append("name", name);
formData.append("symbol", symbol);
formData.append("description", desc);
formData.append("attributes", JSON.stringify(attr));
formData.append("external_url", extUrl);
formData.append("max_supply", maxSup);
formData.append("royalty", roy);
formData.append("file", file);

axios({
	// Endpoint to send files
	url: "https://api.shyft.to/sol/v1/nft/create_detach",
	method: "POST",
	headers: {
		"Content-Type": "multipart/form-data",
		"x-api-key": "Your-api-key",
		Accept: "*/*",
		"Access-Control-Allow-Origin": "*",
	},

	// Attaching the form data
	data: formData,
})
	// Handle the response from backend here
	.then(async (res) => {
		console.log(res);
		if(res.data.success === true)
		{
			setStatus("success: Transaction Created. Signing Transactions. Please Wait.");
			const transaction = res.data.result.encoded_transaction; //encoded transaction
			setSaveMinted(res.data.result.mint);
			const ret_result = await signAndConfirmTransactionFe(network,transaction,callback); //signing the encoded transaction
    			console.log(ret_result);
			setDispResp(res.data);
			
		}
	})

	// Catch errors if any
	.catch((err) => {
		console.warn(err);
		setStatus("success: false");
	});

}

The API Endpoint used:

POST https://api.shyft.to/sol/v1/nft/create_detach

Signing the Encoded Transaction

Now you are all set to mint your first NFT. Please note that this API does not require the private key, instead it uses the public key to sign the transaction required for the create operation.

Head over to the terminal and start the react app, by running:

npm run start

Your basic app will look like this:

All you have to do is enter the information in the fields and hit submit button.

Response :

{
  "success": true,
  "message": "NFT create request generated successfully",
  "result": {
    "encoded_transaction": "AgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC1sWheB4cuv/Q2+0jo6buiunKcPGhvFP0MkPZKAqEaKsIdRPXcFkiLuiIa/pyUVrKUczLjr1Hs9QG5Y5iDBksMAgAFChjKn1HFRx7tvpclOYMfcFNqxsZNjaEl7aHTEnXr/g8Vvb/IjgDJjQVC1f/ryBRhD4ahT7Q1HBYM6DpJ0WUTWn4RAfrhLTPnJMqAy/QLpEQpZFP+r95vFI1kPxccS3tj+xQxDOha6hFwbvC1+bl1KPipyhIpii09w/bWfkdcNqLoa6h4uighckbsoxU8cDYR7skYHVwb90kZsVS8bPEVzOEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIyXJY9OJInxuz0QKRSODYMLWhOZ2v8QhASOe9jb6fhZC3BlsePRfEU4nVJ/awTDzVi4bHMaoP21SbbRvAP4KUYGp9UXGSxcUSGMyUw9SvF/WNruCJuh/UTj29mKAAAAAAbd9uHXZaGT2cvhRs7reawctIXtX1s3kTqM9YV+/wCpOUrCSjEODK7K+JCY0PfeMucSKkHyBEhkHVSHEcaSI5MGBQIAATQAAAAAYE0WAAAAAABSAAAAAAAAAAbd9uHXZaGT2cvhRs7reawctIXtX1s3kTqM9YV+/wCpCQIBCEMAABjKn1HFRx7tvpclOYMfcFNqxsZNjaEl7aHTEnXr/g8VARjKn1HFRx7tvpclOYMfcFNqxsZNjaEl7aHTEnXr/g8VBgcAAwABBQkIAAkDAQMACQcBAAAAAAAAAAcHAgEAAAAFCJ0BEAkAAABmaXNoIGV5ZXMDAAAARllFWAAAAGh0dHBzOi8vbmZ0c3RvcmFnZS5saW5rL2lwZnMvYmFma3JlaWVmamF6cnhpcGpwYmFwNjZkejQ3ZW80ZWdkdzdscHUzY2tvZW43NXZhdGhvaTRtaWszM2n0AQEBAAAAGMqfUcVHHu2+lyU5gx9wU2rGxk2NoSXtodMSdev+DxUBZAAAAQcJBAEAAAACCQUIChEBAQAAAAAAAAA=",
    "mint": "Pmhfos1S2sipnz3UPgAjHQeeYzFn1pbEqpdissS2fZbj"
  }
}

Once we receive the encoded_transaction in the response, the last and final step is to sign the transaction. We can sign encoded_transactionin two ways, either using the wallet from the frontend, or by using the wallet's private key from the backend.

To check, if the NFT is created on the blockchain.

  1. Paste the mint value (the on-chain address of your token) returned in the response in the search bar, you should get the details of the created NFT.

  2. Details of the transaction can be checked by pasting txnId from the response in the previous search bar on Solana explorer.

By now, NFT has already been received in your wallet!! Go to Your Collectibles tab of your phantom wallet, and you should see the newly created NFT.

Ending Notes

I hope you enjoyed this tutorial and are excited to dive deep into web3 awesomeness. Stay tuned for more such tutorials. If you want the complete code for this project with good looking UI, please checkout/fork and play with the code at this Repository.:

Resources

x-api-key is an authentication parameter, which gives you access to SHYFT APIs. You can get your own API Key from the . Just signup with your email id and you can get it for free.

We need to include the obtained from the SHYFT website in the header section of this API call. For details about this API and the parameters used, read the API Documentation . Link to complete App.js file, after making the above changes: .

As soon as you hit submit the request is sent to the Shyft server, and you have successfully created a new NFT transaction. Now, all you need to do is sign this transaction using your wallet and voila! Your newly created NFT will be added to your wallet.

You can read more about signing transactions on Solana , or you can use our online dev tool for signing this encoded transaction available in the below link.

Once successfully signed, your NFT will be created and added to your wallet.

Go to , select the network. (Devenet for this tutorial)

Feel free to check out our other tutorials on and on as well.

Join our

Thank you for your time. We hope you have a great time building dApps with . Happy hacking.

🎉
🎉
chrome/brave browser
firefox
guide
SHYFT website
here
here
https://shyft-insider.vercel.app/
https://explorer.solana.com/
https://github.com/Shyft-to/example-projects/tree/main/example-projects-on-NFTs/my-first-nft-dapp-create-nft
Reading all NFTs from a wallet
Building NFT gated dApp
SHYFT API Documentation
Shyft Website
Get API Key
Github
Solana Transaction Signing tool
Discord
😇
SHYFT APIs
API key
https://github.com/Shyft-to/example-projects/blob/main/example-projects-on-NFTs/my-first-nft-dapp-create-nft/src/create_nft.js
Page cover image
Basic NFT dApp
Newly Minted NFT visible in your Phantom wallet
Attributes of the NFT passed in the request
Creating a new dApp on React with
SHYFT APIs
here