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
  • 📀gRPC Case Studies
    • Pumpfun
      • Streaming and Parsing Real-Time Pump.fun Transactions with Solana Yellowstone gRPC
Powered by GitBook
On this page
  • Pre-requisites
  • Initial Setup
  • Form for accepting data
  • The API Call
  • The JS SDK
  • Bonus tip: How to sign transactions locally with the secret key
  • Resources

Was this helpful?

  1. Tutorials

Mint and reward users with edition NFTs

In this sample project tutorial, we will learn how we can mint an edition NFT from a master NFT directly to the user's wallet.

Last updated 1 year ago

Was this helpful?

In this sample project tutorial, we will demonstrate how we can mint a copy of a master NFT to the receiver's wallet using APIs.

This can be useful when we want to reward edition NFTs for certain user actions. For example, winning a game, getting enough scores, completing certain tasks, etc.

Creator/Holder of the master NFT will be referred to as sender_wallet and the user receiving the edition NFT will be referred to as receiver_wallet. Master NFT is the original master edition whose copies we will mint and the minted NFTs will be referred to as edition NFTs.

Pre-requisites

To get started, we will need a few things.

Authentication: Get your Shyft API key

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.

Phantom Wallet

We will need the Phantom wallet browser extension, you can download it from the link below.

  • .

  • .

Once done, set up your Phantom wallet account. On-screen tips are available, which will guide you through setting up and getting started. You can also find a detailed guide related to this .

We will use to develop this project but you can choose any language of your choice. As we are using react we will need Node.js installed on our computer. You can download node.js from .

Initial Setup

Let's start building, we will use to build this application, but you can use any scripting language of your choice. Let's start with creating a new react application. Fire up the terminal in the directory in which you want to create the project and execute the following command

npx create-react-app mint-detach

If this command executes successfully, a React frontend build pipeline should be ready inside the directory with the project name (project folder) you have chosen. Here, we have chosen to call our app mint-detach but you can name it anything you want. Once done, open the project folder with a code editor of your choice.

** Code Editor **

Form for accepting data

Let's create a very preliminary form for accepting data that we need for minting the NFT. We would need the sender wallet address, receiver wallet address, network in which the NFT exists (be it devnet, testnet or mainnet), and the master_nft_address (the address of the NFT which is being minted). So let's create a form with the respective fields in it.

Note that the last field in the form refers to whether or not the sender_wallet (the one who currently has the update_authority of the NFT being transferred) wants to transfer the update_authority of the NFT being transferred to the receiver_wallet.

The API Call

Before the API call

We will need to pass X-API-KEY in the header, this key is used for authentication purposes.

Getting Your Own X-API-KEY

Now, once we have the wallet address, we are ready to make the API call.

Our API endpoint:

https://api.shyft.to/sol/v1/nft/mint_detach
axios({
        // Endpoint to get NFTs
        url: 'https://api.shyft.to/sol/v1/nft/mint_detach',
        method: "POST",
        headers: {
          "Content-Type": "application/json",
          "x-api-key": "YOUR_X_API_KEY",
        },
        data: {
          network: network,
          wallet: sender,
          master_nft_address: nftAddress,
          receiver: receiver,
          transfer_authority: auth
        }
      })

Details of the data to be sent

  • network: devnet, testnet or mainnet-beta

  • wallet: sender wallet address(public)

  • master_nft_address: Address of the NFT

  • receiver: receiver wallet address(public)

  • transfer_authority: if set to true, the receiver wallet will get update_authority of the NFT

If successful, we should get a response with the encoded transaction in it. The response looks somewhat like this.

{
  "success": true,
  "message": "NFT Edition mint request generated successfully",
  "result": {
    "encoded_transaction": "AgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADd/kZ7nuc7bHY1UZVoVPsZ2Slp+9Sz9dwdHYG7/EP0XTgUn5L1oPWrbCiWyhASqoz4vROwbl2Neo1exHuYvnYIAgAID0mioYxx/asdasdsSls7U3Uq1cPiWEWioadmJJkpfEpJj1IRPDYHVKLFdzmKAhEV5ABsw3PbAIcv3yNkm3z5V2dA0oNsKtkdrxCZh81eIaZc6sHtpoVRDXqCwk2sxG3tUhDS4Opo80GCvyIr4gr+MfwhU03cnO9eEM/I2BvSTn8atGSgv4jEnlxkrsXIO3WpLa65+YPE+hVbcdZfoTSlkuSZace5SwBw7BnI9z9u9hPXYCyNkAAWPPPEqUQJe24xjrsbmyqqUL4gQg6etSyylLP4PMcsG5bcYK4xg9sKxkzNEVAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYyp9RxUce7b6XJTmDH3BTasbGTY2hJe2h0xJ16/4PFYyXJY9OJInxuz0QKRSODYMLWhOZ2v8QhASOe9jb6fhZzgOeiS4FIAsM7m2Xp1OR42r2qbdt9WblPm7k6dy0XkQLcGWx49F8RTidUn9rBMPNWLhscxqg/bVJttG8A/gpRgan1RcZLFxRIYzJTD1K8X9Y2u4Im6H9ROPb2YoAAAAABt324ddloZPZy+FGzut5rBy0he1fWzeROoz1hX7/AKkOmNc6v7OEyaYVVIa6Sv4A/AgVM+wz147I5bRZEbS74yKOCI5qZRvBPiwWe60BzPA23jIRrCRiPj2oAj/VJbo9BQcCAAE0AAAAAGBNFgAAAAAAUgAAAAAAAAAG3fbh12Whk9nL4UbO63msHLSF7V9bN5E6jPWFfv8AqQ0CAQxDAABJoqGMcf65O3NEpbO1N1KtXD4lhFoqGnZiSZKXxKSY9QFJoqGMcf65O3NEpbO1N1KtXD4lhFoqGnZiSZKXxKSY9QkHAAMIAQcNDAANAwEDAAkHAQAAAAAAAAALDgYFAgEEAAAADggKDQcMCQsCAAAAAAAAAA==",
    "mint": "D3DWxLFj3LHXcTHFcN7DDXyxFNEJsdsadXsKDukmrfos5H9R"
  }
}

As discussed before, it returns an encoded transaction in result.encoded_transaction. This encoded_transaction will require authentication from the user before it can successfully perform the operation. To perform this transaction authentication, we will use SHYFT's JS SDK. Once we receive the encoded transaction, we will pass it on to the JS SDK which will allow the users to approve and authenticate using a popup on their wallet. You can learn more about our JS SDK in our upcoming releases or blogs.

axios({
        // Endpoint to mint NFTs
        url: 'https://api.shyft.to/sol/v1/nft/mint_detach',
        method: "POST",
        headers: {
          "Content-Type": "application/json",
          "x-api-key": "YOUR_X_API_KEY",
        },
        data: {
          network: network,
          wallet: sender,
          master_nft_address: nftAddress,
          receiver: receiver,
          transfer_authority: auth
        }
      })
        // Handle the response from backend here
        .then(async (res) => {
          console.log(res.data);
          if(res.data.success === true)
          {
            const transaction = res.data.result.encoded_transaction;
            console.log(ret_result);
            //send this transaction to the SHYFT JS SDK which will authenticate the transaction after approval from the sender
          }
          else
          {
            console.log('Some Error Occurred');
          }
          
        })
        // Catch errors if any
        .catch((err) => {
          console.warn(err);
          setMssg("Failed! Some error occurred");
          
        });

The JS SDK

  • confirmTransactionFromFrontend()

  • confirmTransactionFromBackend()

These two functions are used for the same purpose but have different use case scenarios. For this project, we have used the function confirmTransactionFromFrontend()

  1. Confirming transactions from the frontend

function confirmTransactionFromFrontend(connection, encodedTransaction, wallet)

This is the function that we have used in this project for signing the encoded transactions. This asynchronous function takes the following parameters:

  • connection : This parameter takes in the connection object which contains the JSON RPC connection to a RPC API URL for the specified cluster.

const rpcUrl = clusterApiUrl(network); //network here maybe devnet, testnet or mainnet-beta
const connection = new Connection(rpcUrl,"confirmed");
  • encodedTransaction : This parameter accepts the encoded_transaction which we received in the response of the API call.

{
  "success": true,
  "message": "NFT Edition mint request generated successfully",
  "result": {
    "encoded_transaction": "THE_ENCODED_TRANSACTION_RECEIVED",
    "mint": "MINT_ADDRESS"
  }
}

Once successfully executed, this should display a popup to the user so they can approve (or reject) the transaction.

  1. Confirming transaction from the backend using private keys

function confirmTransactionFromBackend(network, encodedTransaction, privateKey)

This asynchronous function has similar functionality as the previous one. But is used in a different scenario, where private_keyof an authorizing wallet (in this case the sender_wallet) is available. This function has the following parameters:

  • network: Takes in the network in which the token exists. It can be any of the following values: 'devnet', 'testnet' or 'mainnet-beta'

  • encodedTransaction : This parameter accepts aencoded_transaction which we receive in the response of any of the SHYFT's _detach API call.

{
  "success": true,
  "message": "NFT Edition mint request generated successfully",
  "result": {
    "encoded_transaction": "THE_ENCODED_TRANSACTION_RECEIVED",
    "mint": "MINT_ADDRESS"
  }
}

privateKey : This parameter accepts the private_key of the wallet which has the authority to perform the action which is being performed in the respective API call. In simpler terms, Let's suppose we are trying to mint an already created NFT whose update_authority is with 'WALLET #1'. So, for this function to work we need to pass the private key of 'WALLET #1'.

Packages required for the JS SDK to work

Some of the packages that are required for the JS SDK to work and sign transactions locally:

  • @solana/web3.js

  • @metaplex/js

  • @solana/wallet-adapter-phantom (used only in signing transactions from the frontend)

To install these packages, open the terminal in the project folder and execute the following command:

npm i <package_name>

Note: every time we install a package, we have to stop and re-run the server using the npm run start command.

Once approved, the NFT will be minted and added to the receiver_wallet. You can use our read_all API to check the NFT that you have just added to the receiver_wallet. Want to know how you can do that? Click here to know more.

Bonus tip: How to sign transactions locally with the secret key

Let's consider this same example where we are minting and adding an NFT, whose update_authority is with WALLET#1 (will be referred here as the sender_wallet), to WALLET#2 (will be referred here as the receiver_wallet), but instead of signing and approving the transaction using the popup in the frontend, we will use the Private Key of the sender_wallet to sign and approve the transaction locally.

Let's go back a few steps to the point where we were making the API call and getting the encoded_transaction in the response.

axios({
        // Endpoint to mint NFTs
        url: 'https://api.shyft.to/sol/v1/nft/mint_detach',
        method: "POST",
        headers: {
          "Content-Type": "application/json",
          "x-api-key": "YOUR_X_API_KEY",
        },
        data: {
          network: network,
          wallet: sender,
          master_nft_address: nftAddress,
          receiver: receiver,
          transfer_authority: auth
        }
      })
        // Handle the response from backend here
        .then(async (res) => {
          console.log(res.data);
          //We get the encoded_transaction here 
          //which we will sign from the backend using the JS SDK
          if(res.data.success === true)
          {
            const transaction = res.data.result.encoded_transaction;
            console.log(ret_result);
            
          }
          else
          {
            console.log('Some Error Occurred');
          }
          
        })
        // Catch errors if any
        .catch((err) => {
          console.warn(err);
          setMssg("Failed! Some error occurred");
          
        });

Once we have the encoded_transaction, we will use the confirmTransactionFromBackend() function from the JS SDK to sign and authenticate the transaction. This function accepts the Private Key of the sender_wallet as one of the parameters. We can accept this Private Key using a form field from the sender in this project, or we can also load it from a .env file.

await confirmTransactionFromBackend('devnet','THE_ENCODED_TRANSACTION','THE_PRIVATE_KEY_OF_THE_SENDER_WALLET');

Once successfully executed, this should sign and approve the transaction, and the intended operation, which in this case is the NFT minting operation will be complete.

Resources

We have used as our code editor for this project but you can use any editor of your choice such as Sublime Text, Notepad++, Atom, or any editor of your choice. Once decided, let's open up the project in our code editor. It should look something like this.

You can find more about our APIs .

x-api-key is an important parameter we pass on to the header while making the API call for authentication purposes. You can get your own x-api-key from our own . Just signup with your email id and you can get it for free.

Unlike other , these APIs (ending with _detach) are a special kind of APIs, which do not perform the action directly, instead it returns a transaction that requires a signature and approval from the user. Once approved, then the intended action gets updated on the blockchain.

We will use the axios package to make the API call, but you can use any other packages, or javascript's very own fetch API. You can learn more about the axios package .

You can learn more about our APIs and their payload in detail .

The JS SDK consists of two functions and is used for approving and authenticating encoded transactions generated by the (_detach APIs). The two functions are:

wallet : This parameter accepts the wallet object which is being used for performing this transaction, in this case, the sender_wallet. We have used the to connect to the sender wallet for this sample project.

Once we have the private key, we are ready to make the function call. , the asynchronous confirmTransactionFromBackend()the function accepts 3 parameters: network, encoded_transaction and privateKey, the function call would look something like

We have used this API call and confirmTransactionFromBackend() function for minting tokens when the users do not have access. Feel free to try it out .

That's pretty much everything about this sample project tutorial. If you enjoyed it, and want to try out our code, you can from our GitHub repository.

Join our

If you liked this, you can also read our tutorials on or .

Hope you have a great time building Dapps with APIs. Happy Hacking!!

SHYFT
SHYFT website
here
Chrome/Brave
Firefox
here
React
here
React - Javascript Library
VScode
here
SHYFT website
here
SHYFT APIs
here
here
SHYFT
SHYFT APIs
Phantom Wallet Adapter
here
clone the code
SHYFT API Documentation
Shyft Website
Get API Key
Github
Discord
Read all NFTs from a wallet
Build NFT Gated App
😇
SHYFT
As explained before
Creating a new react app and opening it with your code editor
Simple form to accept the various details required for the API call
The transaction will be successful once this is approved
After the NFT has been added to the wallet
An application of mint API, in the
NFT Gated Access Dapp