Skip to main content

Integrate Web3Auth with the Solana Blockchain in Javascript

While using the Web3Auth Web SDK for Solana you get a standard provider for Solana containing functions to help you make blockchain calls via the @solana/web3.js library. We have highlighted a few methods here for getting you started quickly on that.

note

This reference is for the Web, however, you can use Solana on React Native, as well, quite similarly. Please follow our reference for EVM Chains, and similarly use Solana libraries that support the platforms to use the private key and make blockchain calls accordingly.

Installation

To interact with the Solana blockchain, you can use @solana/web3.js library with Web3Auth along with @web3auth/solana-provider package.

Getting the chainConfig

const chainConfig: {
chainNamespace: CHAIN_NAMESPACES.SOLANA;
chainId: "0x1"; // Please use 0x1 for Mainnet, 0x2 for Testnet, 0x3 for Devnet
rpcTarget: "https://rpc.ankr.com/solana";
displayName: "Solana Mainnet";
blockExplorerUrl: "https://explorer.solana.com";
ticker: "SOL";
tickerName: "Solana";
logo: "https://images.toruswallet.io/solana.svg";
};

Initializing and instantiating the Web3Auth SDK

import { Web3Auth } from "@web3auth/modal";
import { SolanaPrivateKeyProvider } from "@web3auth/solana-provider";
import { WEB3AUTH_NETWORK } from "@web3auth/base";

const privateKeyProvider = new SolanaPrivateKeyProvider({
config: { chainConfig: chainConfig },
});

const web3auth = new Web3Auth({
// Get it from Web3Auth Dashboard
clientId,
web3AuthNetwork: WEB3AUTH_NETWORK.SAPPHIRE_MAINNET,
privateKeyProvider: privateKeyProvider,
});

Get User Info

After logging in, the Web3Auth instance will provide you with information regarding the user that is logged in. This information is obtained directly from the JWT token and is not stored by Web3Auth. Therefore, this information can only be accessed through social logins after the user has logged into your application.

const user = await web3auth.getUserInfo(); // web3auth instance

Get Account and Balance

import {
Connection,
LAMPORTS_PER_SOL,
PublicKey,
SystemProgram,
Transaction,
} from "@solana/web3.js";

const solanaWallet = new SolanaWallet(web3auth.provider);

// Get user's Solana public address
const accounts = await solanaWallet.requestAccounts();

const connectionConfig = await solanaWallet.request<string[], CustomChainConfig>({
method: "solana_provider_config",
params: [],
});

const connection = new Connection(connectionConfig.rpcTarget);

// Fetch the balance for the specified public key
const balance = await connection.getBalance(new PublicKey(accounts[0]));

Sign a Transaction

import {
Connection,
LAMPORTS_PER_SOL,
PublicKey,
SystemProgram,
Transaction,
} from "@solana/web3.js";

// solanaWallet is from above
const connectionConfig = await solanaWallet.request({
method: "solana_provider_config",
params: [],
});

const connectionConfig = await solanaWallet.request<string[], CustomChainConfig>({
method: "solana_provider_config",
params: [],
});

const connection = new Connection(connectionConfig.rpcTarget);

const pubKey = await solanaWallet.requestAccounts();
const { blockhash } = await connection.getRecentBlockhash("finalized");

const TransactionInstruction = SystemProgram.transfer({
fromPubkey: new PublicKey(pubKey[0]),
toPubkey: new PublicKey(pubKey[0]),
lamports: 0.01 * LAMPORTS_PER_SOL,
});

const transaction = new Transaction({
recentBlockhash: blockhash,
feePayer: new PublicKey(pubKey[0]),
}).add(TransactionInstruction);

const signedTx = await solanaWallet.signTransaction(transaction);
console.log(signedTx.signature);

Sign all Transactions

import {
Connection,
LAMPORTS_PER_SOL,
PublicKey,
SystemProgram,
Transaction,
} from "@solana/web3.js";

// solanaWallet is from above
const connectionConfig = await solanaWallet.request<string[], CustomChainConfig>({
method: "solana_provider_config",
params: [],
});

const connection = new Connection(connectionConfig.rpcTarget);

const pubKey = await solanaWallet.requestAccounts();
const { blockhash } = await connection.getRecentBlockhash("finalized");

// First transaction
const TransactionInstruction1 = SystemProgram.transfer({
fromPubkey: new PublicKey(pubKey[0]),
toPubkey: new PublicKey(pubKey[0]),
lamports: 0.01 * LAMPORTS_PER_SOL,
});

// Second transaction
const TransactionInstruction2 = SystemProgram.transfer({
fromPubkey: new PublicKey(pubKey[0]),
toPubkey: new PublicKey(pubKey[0]),
lamports: 0.02 * LAMPORTS_PER_SOL,
});

const transaction1 = new Transaction({
recentBlockhash: blockhash,
feePayer: new PublicKey(pubKey[0]),
}).add(TransactionInstruction1);
const transaction2 = new Transaction({
recentBlockhash: blockhash,
feePayer: new PublicKey(pubKey[0]),
}).add(TransactionInstruction2);

const signedTx = await solanaWallet.signAllTransactions([transaction1, transaction2]);
console.log(signedTx);

Sign and Send a Transaction

import {
Connection,
LAMPORTS_PER_SOL,
PublicKey,
SystemProgram,
Transaction,
} from "@solana/web3.js";

// solanaWallet is from above
const connectionConfig = await solanaWallet.request<string[], CustomChainConfig>({
method: "solana_provider_config",
params: [],
});

const connection = new Connection(connectionConfig.rpcTarget);

const accounts = await solanaWallet.requestAccounts();
const block = await connection.getLatestBlockhash("finalized");

const TransactionInstruction = SystemProgram.transfer({
fromPubkey: new PublicKey(accounts[0]),
toPubkey: new PublicKey(accounts[0]),
lamports: 0.01 * LAMPORTS_PER_SOL,
});

const transaction = new Transaction({
blockhash: block.blockhash,
lastValidBlockHeight: block.lastValidBlockHeight,
feePayer: new PublicKey(accounts[0]),
}).add(TransactionInstruction);

const { signature } = await solanaWallet.signAndSendTransaction(transaction);

console.log(signature);

Sign Message

import {
Connection,
LAMPORTS_PER_SOL,
PublicKey,
SystemProgram,
Transaction,
} from "@solana/web3.js";

// solanaWallet is from above
const msg = Buffer.from("Test Signing Message", "utf8");
const result = await solanaWallet.signMessage(msg);
console.log(result.toString());

Fetch User's Private Key

solanaPrivateKey is used to fetch the private key of the logged in user. It is only available for in-app adapters like auth.

// Assuming user is already logged in.
async getPrivateKey() {
const privateKey = await web3auth.provider.request({
method: "solanaPrivateKey"
});

// Do something with privateKey
}

Gasless Transactions

To do gasless transactions in Solana, use Solana labs's Octane.

Octane is a gasless transaction relayer for Solana. Octane accepts transactions via an HTTP API, signs them if they satisfy certain conditions and broadcasts to the network.

Follow this guide to run your first transaction through Octane.