What is @solana/web3.js?
@solana/web3.js is a JavaScript library for interacting with the Solana blockchain. It provides a set of tools and utilities for developers to build applications on Solana, including functionalities for managing accounts, sending transactions, interacting with smart contracts, and querying blockchain data.
What are @solana/web3.js's main functionalities?
Create and Manage Accounts
This feature allows you to create and manage Solana accounts. The code sample demonstrates how to generate a new keypair, which includes a public key and a secret key.
const solanaWeb3 = require('@solana/web3.js');
// Generate a new keypair
const keypair = solanaWeb3.Keypair.generate();
console.log('Public Key:', keypair.publicKey.toBase58());
console.log('Secret Key:', keypair.secretKey);
Send Transactions
This feature allows you to send transactions on the Solana blockchain. The code sample demonstrates how to create a connection to the Solana devnet, airdrop SOL to an account, create a transaction to transfer SOL, and send the transaction.
const solanaWeb3 = require('@solana/web3.js');
(async () => {
const connection = new solanaWeb3.Connection(solanaWeb3.clusterApiUrl('devnet'), 'confirmed');
const from = solanaWeb3.Keypair.generate();
const to = solanaWeb3.Keypair.generate();
// Airdrop SOL to the from account
await connection.requestAirdrop(from.publicKey, solanaWeb3.LAMPORTS_PER_SOL);
// Create a transaction
const transaction = new solanaWeb3.Transaction().add(
solanaWeb3.SystemProgram.transfer({
fromPubkey: from.publicKey,
toPubkey: to.publicKey,
lamports: solanaWeb3.LAMPORTS_PER_SOL / 100,
})
);
// Sign and send the transaction
const signature = await solanaWeb3.sendAndConfirmTransaction(connection, transaction, [from]);
console.log('Transaction signature:', signature);
})();
Interact with Smart Contracts
This feature allows you to interact with smart contracts deployed on the Solana blockchain. The code sample demonstrates how to create a transaction that calls a smart contract and send the transaction.
const solanaWeb3 = require('@solana/web3.js');
(async () => {
const connection = new solanaWeb3.Connection(solanaWeb3.clusterApiUrl('devnet'), 'confirmed');
const programId = new solanaWeb3.PublicKey('YourProgramIdHere');
const account = solanaWeb3.Keypair.generate();
// Create a transaction to call a smart contract
const transaction = new solanaWeb3.Transaction().add(
new solanaWeb3.TransactionInstruction({
keys: [{ pubkey: account.publicKey, isSigner: true, isWritable: true }],
programId,
data: Buffer.alloc(0), // Add your instruction data here
})
);
// Sign and send the transaction
const signature = await solanaWeb3.sendAndConfirmTransaction(connection, transaction, [account]);
console.log('Transaction signature:', signature);
})();
Query Blockchain Data
This feature allows you to query data from the Solana blockchain. The code sample demonstrates how to get account information and the recent blockhash from the blockchain.
const solanaWeb3 = require('@solana/web3.js');
(async () => {
const connection = new solanaWeb3.Connection(solanaWeb3.clusterApiUrl('devnet'), 'confirmed');
const publicKey = new solanaWeb3.PublicKey('YourPublicKeyHere');
// Get account info
const accountInfo = await connection.getAccountInfo(publicKey);
console.log('Account Info:', accountInfo);
// Get recent blockhash
const recentBlockhash = await connection.getRecentBlockhash();
console.log('Recent Blockhash:', recentBlockhash);
})();
Other packages similar to @solana/web3.js
web3
web3.js is a collection of libraries that allow you to interact with a local or remote Ethereum node using HTTP, IPC, or WebSocket. It provides similar functionalities to @solana/web3.js but is designed for the Ethereum blockchain.
ethers
ethers.js is a library for interacting with the Ethereum blockchain and its ecosystem. It provides a more lightweight and modular approach compared to web3.js and includes functionalities for managing accounts, sending transactions, and interacting with smart contracts.
near-api-js
near-api-js is a JavaScript library for interacting with the NEAR blockchain. It provides similar functionalities to @solana/web3.js, including account management, transaction handling, and smart contract interaction, but is designed specifically for the NEAR blockchain.
@solana/web3.js
This is the JavaScript SDK for building Solana apps for Node, web, and React Native.
Functions
In addition to reexporting functions from packages in the @solana/*
namespace, this package offers additional helpers for building Solana applications, with sensible defaults.
airdropFactory({rpc, rpcSubscriptions})
Returns a function that you can call to airdrop a certain amount of Lamports
to a Solana address.
import {
address,
airdropFactory,
createSolanaRpc,
createSolanaRpcSubscriptions,
devnet,
lamports,
} from '@solana/web3.js';
const rpc = createSolanaRpc(devnet('http://127.0.0.1:8899'));
const rpcSubscriptions = createSolanaRpcSubscriptions(devnet('ws://127.0.0.1:8900'));
const airdrop = airdropFactory({ rpc, rpcSubscriptions });
await airdrop({
commitment: 'confirmed',
recipientAddress: address('FnHyam9w4NZoWR6mKN1CuGBritdsEWZQa4Z4oawLZGxa'),
lamports: lamports(10_000_000n),
});
[!NOTE] This only works on test clusters.
decodeTransactionMessage(compiledTransactionMessage, rpc, config)
Returns a TransactionMessage
from a CompiledTransactionMessage
. If any of the accounts in the compiled message require an address lookup table to find their address, this function will use the supplied RPC instance to fetch the contents of the address lookup table from the network.
fetchLookupTables(lookupTableAddresses, rpc, config)
Given a list of addresses belonging to address lookup tables, returns a map of lookup table addresses to an ordered array of the addresses they contain.
getComputeUnitEstimateForTransactionMessageFactory({rpc})
Correctly budgeting a compute unit limit for your transaction message can increase the probability that your transaction will be accepted for processing. If you don't declare a compute unit limit on your transaction, validators will assume an upper limit of 200K compute units (CU) per instruction.
Since validators have an incentive to pack as many transactions into each block as possible, they may choose to include transactions that they know will fit into the remaining compute budget for the current block over transactions that might not. For this reason, you should set a compute unit limit on each of your transaction messages, whenever possible.
Use this utility to estimate the actual compute unit cost of a given transaction message.
import { getSetComputeUnitLimitInstruction } from '@solana-program/compute-budget';
import { createSolanaRpc, getComputeUnitEstimateForTransactionMessageFactory, pipe } from '@solana/web3.js';
const rpc = createSolanaRpc('http://127.0.0.1:8899');
const getComputeUnitEstimateForTransactionMessage = getComputeUnitEstimateForTransactionMessageFactory({
rpc,
});
const transactionMessage = pipe(
createTransactionMessage({ version: 'legacy' }),
);
const computeUnitsEstimate = await getComputeUnitEstimateForTransactionMessage(transactionMessage);
const transactionMessageWithComputeUnitLimit = prependTransactionMessageInstruction(
getSetComputeUnitLimitInstruction({ units: computeUnitsEstimate }),
transactionMessage,
);
[!WARNING]
The compute unit estimate is just that – an estimate. The compute unit consumption of the actual transaction might be higher or lower than what was observed in simulation. Unless you are confident that your particular transaction message will consume the same or fewer compute units as was estimated, you might like to augment the estimate by either a fixed number of CUs or a multiplier.
[!NOTE]
If you are preparing an unsigned transaction, destined to be signed and submitted to the network by a wallet, you might like to leave it up to the wallet to determine the compute unit limit. Consider that the wallet might have a more global view of how many compute units certain types of transactions consume, and might be able to make better estimates of an appropriate compute unit budget.
sendAndConfirmDurableNonceTransactionFactory({rpc, rpcSubscriptions})
Returns a function that you can call to send a nonce-based transaction to the network and to wait until it has been confirmed.
import {
isSolanaError,
sendAndConfirmDurableNonceTransactionFactory,
SOLANA_ERROR__INVALID_NONCE,
SOLANA_ERROR__NONCE_ACCOUNT_NOT_FOUND,
} from '@solana/web3.js';
const sendAndConfirmNonceTransaction = sendAndConfirmDurableNonceTransactionFactory({ rpc, rpcSubscriptions });
try {
await sendAndConfirmNonceTransaction(transaction, { commitment: 'confirmed' });
} catch (e) {
if (isSolanaError(e, SOLANA_ERROR__NONCE_ACCOUNT_NOT_FOUND)) {
console.error(
'The lifetime specified by this transaction refers to a nonce account ' +
`\`${e.context.nonceAccountAddress}\` that does not exist`,
);
} else if (isSolanaError(e, SOLANA_ERROR__INVALID_NONCE)) {
console.error('This transaction depends on a nonce that is no longer valid');
} else {
throw e;
}
}
sendAndConfirmTransactionFactory({rpc, rpcSubscriptions})
Returns a function that you can call to send a blockhash-based transaction to the network and to wait until it has been confirmed.
import { isSolanaError, sendAndConfirmTransactionFactory, SOLANA_ERROR__BLOCK_HEIGHT_EXCEEDED } from '@solana/web3.js';
const sendAndConfirmTransaction = sendAndConfirmTransactionFactory({ rpc, rpcSubscriptions });
try {
await sendAndConfirmTransaction(transaction, { commitment: 'confirmed' });
} catch (e) {
if (isSolanaError(e, SOLANA_ERROR__BLOCK_HEIGHT_EXCEEDED)) {
console.error('This transaction depends on a blockhash that has expired');
} else {
throw e;
}
}
sendTransactionWithoutConfirmingFactory({rpc, rpcSubscriptions})
Returns a function that you can call to send a transaction with any kind of lifetime to the network without waiting for it to be confirmed.
import {
sendTransactionWithoutConfirmingFactory,
SOLANA_ERROR__JSON_RPC__SERVER_ERROR_SEND_TRANSACTION_PREFLIGHT_FAILURE,
} from '@solana/web3.js';
const sendTransaction = sendTransactionWithoutConfirmingFactory({ rpc });
try {
await sendTransaction(transaction, { commitment: 'confirmed' });
} catch (e) {
if (isSolanaError(e, SOLANA_ERROR__JSON_RPC__SERVER_ERROR_SEND_TRANSACTION_PREFLIGHT_FAILURE)) {
console.error('The transaction failed in simulation', e.cause);
} else {
throw e;
}
}