Introduction
All endpoints that require a Transaction to be sent to the Solana network will return a list of serialized transactions.
Before you're able to send them to the network you will need to deserialize and sign them with the necessary wallets.
All transaction endpoints have two fields: tx and txV0.
If
txV0
is non-null, then you MUST useVersionedTransaction
otherwise it will fail due to Solana tx size limits.If
txV0
isnull
, you may safely send thetx
as a legacyTransaction
.
Example - Buy the Floor Listing of a Collection
const {
Connection,
Transaction,
VersionedTransaction,
Keypair
} = require("@solana/web3.js");
const path = require("path");
const fs = require("fs");
// Load Environment Values
const TENSOR_API_KEY = process.env.TENSOR_API_KEY
const COLLECTION_SLUG = process.env.COLLECTION_SLUG
const SOLANA_RPC = process.env.SOLANA_RPC
// Connect to Solana and Load Local Wallet
const connection = new Connection(SOLANA_RPC);
const walletPath = path.join(process.env.HOME, ".config", "solana", "id.json");
const walletData = fs.readFileSync(walletPath, "utf8");
let wallet = Keypair.fromSecretKey(Uint8Array.from(JSON.parse(walletData)));
// Configure Tensor API Fetch Options
const options = {
method: "GET",
headers: {
accept: "application/json",
"x-tensor-api-key": TENSOR_API_KEY,
},
};
// API Endpoint for Collection active Listings
const url = "https://api.mainnet.tensordev.io/api/v1/mint/collection";
// Configure Query Parameters and construct API URL
const queryParams = new URLSearchParams();
queryParams.append("slug", COLLECTION_SLUG);
queryParams.append("sortBy", "ListingPriceAsc");
queryParams.append("limit", 1);
queryParams.append("onlyListings", "true");
const fullUrl = `${url}?${queryParams.toString()}`;
// Fetch Listings
fetch(fullUrl, options)
.then((response) => response.json())
.then(async (response) => {
// Fetch Latest Blockhash, needed to send Transaction
const blockhash = await connection.getLatestBlockhash();
return {
response,
blockhash
};
})
.then(async ({
response,
blockhash
}) => {
// API Endpoint for NFT BUY, construct request URL
const buyUrl = "https://api.mainnet.tensordev.io/api/v1/tx/buy";
const buyParams = new URLSearchParams();
buyParams.append("buyer", wallet.publicKey.toString());
buyParams.append("mint", response.mints[0].mint);
buyParams.append("owner", response.mints[0].listing.seller);
buyParams.append("maxPrice", response.mints[0].listing.price);
buyParams.append("blockhash", blockhash.blockhash);
const fullBuyUrl = `${buyUrl}?${buyParams.toString()}`;
// Fetch BUY NFT Tr
const buyResponse = await fetch(fullBuyUrl, options);
return buyResponse.json();
})
.then(async (response) => {
// Deserialize the transactions
const txsToSign = response.txs.map((tx) =>
tx.txV0 ?
VersionedTransaction.deserialize(response.txs[0].txV0.data) :
Transaction.from(tx.tx.data)
);
// Sign Transactions
txsToSign.map((tx) =>
tx instanceof VersionedTransaction ?
tx.sign([wallet]) :
tx.sign(wallet)
);
// Send Transactions to Network
for (const tx of txsToSign) {
const sig = await connection.sendTransaction(tx);
await connection.confirmTransaction(sig, "confirmed");
console.log(`Transaction confirmed. https://solscan.io/tx/${sig}`);
}
})
.catch((err) => console.error(err));
Additional Examples
Be sure to check out the recipes page for additional examples on API calls and Transaction deserialization!
📊
Place a bid within 5% of Floor Price
Open Recipe