Skip to main content

Integrate Embedded Wallets with the Solana Blockchain in Javascript

While using the Embedded Wallets Web SDK (formerly Web3Auth) for Solana, you get a Solana provider with functions to help you make blockchain calls via the @solana/web3.js library. We’ve highlighted a few methods here to get you started quickly.

note

The SDKs are now branded as MetaMask Embedded Wallet SDKs (formerly Web3Auth Plug and Play SDKs). Package names and APIs remain Web3Auth (for example, Web3Auth React SDK), and code snippets may reference web3auth identifiers.

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

Initializing and instantiating the Web3Auth SDK

Post V10 release, Web3Auth Web SDK does not need any additional setup on the code side for Solana. All is handled on the Dashboard.

import { Web3Auth, WEB3AUTH_NETWORK } from "@web3auth/modal";

const web3AuthOptions: Web3AuthOptions = {
clientId,
web3AuthNetwork: WEB3AUTH_NETWORK.SAPPHIRE_MAINNET,
};

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.