Using Solana Standard Wallets
This guide will help you integrate and use Solana standard wallets in your application. We’ll cover everything from basic setup to advanced features like message signing and transaction handling.
To learn more about the wallet standard, you can read more about it here!
Basic Setup
First, import the necessary hooks and types from Privy:
import {useSolanaStandardWallets, type SolanaStandardWallet} from '@privy-io/react-auth/solana';
Available Features
Standard wallets provide these core features:
standard:connect
: Connect the wallet
standard:disconnect
: Disconnect the wallet
solana:signMessage
: Sign messages
solana:signTransaction
: Sign transactions
solana:signAndSendTransaction
: Sign and send transactions
Core Wallet Features
Here’s how to use the core features of any Solana standard wallet:
function WalletComponent() {
const {ready, wallets} = useSolanaStandardWallets();
// Connect/Disconnect
const connect = (wallet: SolanaStandardWallet) => wallet.features['standard:connect']!.connect();
const disconnect = (wallet: SolanaStandardWallet) =>
wallet.features['standard:disconnect']!.disconnect();
// Sign Message
const signMessage = async (
wallet: SolanaStandardWallet,
address: string,
message: Uint8Array
) => {
const account = wallet.accounts.find((a) => a.address === address)!;
const [result] = await wallet.features['solana:signMessage']!.signMessage({
account,
message
});
return result;
};
// Sign Transaction
const signTransaction = async (
wallet: SolanaStandardWallet,
address: string,
transaction: Uint8Array
) => {
const account = wallet.accounts.find((a) => a.address === address)!;
const [result] = await wallet.features['solana:signTransaction']!.signTransaction({
transaction,
chain: 'solana:devnet',
account
});
return result;
};
// Sign and Send Transaction
const signAndSendTransaction = async (
wallet: SolanaStandardWallet,
address: string,
transaction: Uint8Array
) => {
const account = wallet.accounts.find((a) => a.address === address)!;
return wallet.features['solana:signAndSendTransaction']!.signAndSendTransaction({
transaction,
chain: 'solana:devnet',
account
});
};
}
Registering the Privy Embedded Wallet
To make your Privy embedded wallet compatible with other Solana applications, register it with the window object.
The registration function dispatches the appropriate events to make the wallet available to other applications:
// This is copied from @wallet-standard/wallet
import type {
Wallet,
WalletEventsWindow,
WindowRegisterWalletEvent,
WindowRegisterWalletEventCallback
} from '@wallet-standard/base';
class RegisterWalletEvent extends Event implements WindowRegisterWalletEvent {
readonly #detail: WindowRegisterWalletEventCallback;
get detail() {
return this.#detail;
}
override get type() {
return 'wallet-standard:register-wallet' as const;
}
constructor(callback: WindowRegisterWalletEventCallback) {
super('wallet-standard:register-wallet', {
bubbles: false,
cancelable: false,
composed: false
});
this.#detail = callback;
}
}
export function registerWallet(wallet: Wallet): void {
const callback: WindowRegisterWalletEventCallback = ({register}) => register(wallet);
try {
(window as WalletEventsWindow).dispatchEvent(new RegisterWalletEvent(callback));
} catch (error) {
console.error('wallet-standard:register-wallet event could not be dispatched\n', error);
}
try {
(window as WalletEventsWindow).addEventListener('wallet-standard:app-ready', ({detail: api}) =>
callback(api)
);
} catch (error) {
console.error('wallet-standard:app-ready event listener could not be added\n', error);
}
}
After this code is implemented in your application, you can then register the Privy embedded wallet by calling:
registerWallet(wallets.find((wallet) => wallet.name === 'Privy' && 'privy:' in wallet.features));
That’s it! You now have a fully functional Solana standard wallet integration in your application. You can use these features to connect wallets, sign messages, and handle transactions in a standardized way.
Basic Setup
First, import the necessary hooks and types from Privy:
import {useSolanaStandardWallets, type SolanaStandardWallet} from '@privy-io/react-auth/solana';
Available Features
Standard wallets provide these core features:
standard:connect
: Connect the wallet
standard:disconnect
: Disconnect the wallet
solana:signMessage
: Sign messages
solana:signTransaction
: Sign transactions
solana:signAndSendTransaction
: Sign and send transactions
Core Wallet Features
Here’s how to use the core features of any Solana standard wallet:
function WalletComponent() {
const {ready, wallets} = useSolanaStandardWallets();
// Connect/Disconnect
const connect = (wallet: SolanaStandardWallet) => wallet.features['standard:connect']!.connect();
const disconnect = (wallet: SolanaStandardWallet) =>
wallet.features['standard:disconnect']!.disconnect();
// Sign Message
const signMessage = async (
wallet: SolanaStandardWallet,
address: string,
message: Uint8Array
) => {
const account = wallet.accounts.find((a) => a.address === address)!;
const [result] = await wallet.features['solana:signMessage']!.signMessage({
account,
message
});
return result;
};
// Sign Transaction
const signTransaction = async (
wallet: SolanaStandardWallet,
address: string,
transaction: Uint8Array
) => {
const account = wallet.accounts.find((a) => a.address === address)!;
const [result] = await wallet.features['solana:signTransaction']!.signTransaction({
transaction,
chain: 'solana:devnet',
account
});
return result;
};
// Sign and Send Transaction
const signAndSendTransaction = async (
wallet: SolanaStandardWallet,
address: string,
transaction: Uint8Array
) => {
const account = wallet.accounts.find((a) => a.address === address)!;
return wallet.features['solana:signAndSendTransaction']!.signAndSendTransaction({
transaction,
chain: 'solana:devnet',
account
});
};
}
Registering the Privy Embedded Wallet
To make your Privy embedded wallet compatible with other Solana applications, register it with the window object.
The registration function dispatches the appropriate events to make the wallet available to other applications:
// This is copied from @wallet-standard/wallet
import type {
Wallet,
WalletEventsWindow,
WindowRegisterWalletEvent,
WindowRegisterWalletEventCallback
} from '@wallet-standard/base';
class RegisterWalletEvent extends Event implements WindowRegisterWalletEvent {
readonly #detail: WindowRegisterWalletEventCallback;
get detail() {
return this.#detail;
}
override get type() {
return 'wallet-standard:register-wallet' as const;
}
constructor(callback: WindowRegisterWalletEventCallback) {
super('wallet-standard:register-wallet', {
bubbles: false,
cancelable: false,
composed: false
});
this.#detail = callback;
}
}
export function registerWallet(wallet: Wallet): void {
const callback: WindowRegisterWalletEventCallback = ({register}) => register(wallet);
try {
(window as WalletEventsWindow).dispatchEvent(new RegisterWalletEvent(callback));
} catch (error) {
console.error('wallet-standard:register-wallet event could not be dispatched\n', error);
}
try {
(window as WalletEventsWindow).addEventListener('wallet-standard:app-ready', ({detail: api}) =>
callback(api)
);
} catch (error) {
console.error('wallet-standard:app-ready event listener could not be added\n', error);
}
}
After this code is implemented in your application, you can then register the Privy embedded wallet by calling:
registerWallet(wallets.find((wallet) => wallet.name === 'Privy' && 'privy:' in wallet.features));
That’s it! You now have a fully functional Solana standard wallet integration in your application. You can use these features to connect wallets, sign messages, and handle transactions in a standardized way.