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.
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
- Mainnet
- Testnet
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";
};
const chainConfig: {
chainNamespace: CHAIN_NAMESPACES.SOLANA;
chainId: "0x2"; // Please use 0x1 for Mainnet, 0x2 for Testnet, 0x3 for Devnet
rpcTarget: "https://api.testnet.solana.com";
displayName: "Solana Testnet";
blockExplorerUrl: "https://explorer.solana.com";
ticker: "SOL";
tickerName: "Solana";
logo: "https://images.toruswallet.io/solana.svg";
};
Initializing and instantiating the Web3Auth SDK
- PnP Modal SDK
- PnP NoModal SDK
- Single Factor Auth JS 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,
});
import { Web3AuthNoModal } from "@web3auth/no-modal";
import { AuthAdapter } from "@web3auth/auth-adapter";
import { SolanaPrivateKeyProvider } from "@web3auth/solana-provider";
import { WEB3AUTH_NETWORK } from "@web3auth/base";
const privateKeyProvider = new SolanaPrivateKeyProvider({
config: { chainConfig },
});
const web3auth = new Web3AuthNoModal({
clientId, // Get it from Web3Auth Dashboard
web3AuthNetwork: WEB3AUTH_NETWORK.SAPPHIRE_MAINNET,
privateKeyProvider,
});
const authAdapter = new AuthAdapter({ privateKeyProvider });
web3auth.configureAdapter(authAdapter);
import { Web3Auth } from "@web3auth/single-factor-auth";
import { SolanaPrivateKeyProvider } from "@web3auth/solana-provider";
const privateKeyProvider = new SolanaPrivateKeyProvider({
config: { chainConfig },
});
const web3auth = new Web3Auth({
clientId, // Get your Client ID from Web3Auth Dashboard
web3AuthNetwork: "sapphire_mainnet",
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.