I'm making a dApp and I want to add a button where a user (the one with their wallet connected) can send exactly 0.01 SOL to another user. I already wrote the function in my Rust program and after testing it with anchor test
it seems to be working when I use my own personal wallet's Keypair to sign the transaction. However, now I am writing the event handler function in my web app's frontend and I'm not sure what to pass for the signers
parameter if I want the user to sign the transaction. What do I pass if I don't know their secret key? Is there a way that I can generate a user's Keypair from their public key alone or would I need to use the Solana Wallet Adapter for this? Any help would be appreciated. This is my first time working with Solana!
This is the function:
const tipSol = async (receiverAddress) => {
try {
const provider = getProvider();
const program = new Program(idl, programID, provider);
const lamportsToSend = LAMPORTS_PER_SOL / 100;
const amount = new anchor.BN(lamportsToSend);
await program.rpc.sendSol(amount, {
accounts: {
from: walletAddress,
to: receiverAddress,
systemProgram: SystemProgram.programId,
},
signers: ?
})
console.log('Successfully sent 0.01 SOL!')
window.alert(`You successfully tipped ${receiverAddress} 0.01 SOL!`)
} catch (error) {
console.error('Failed to send SOL:', error);
window.alert('Failed to send SOL:', error);
}
}
Frontends never access private keys. Instead the flow is something like:
You can use the @solana/wallet-adapter
to implement this on your frontend https://github.com/solana-labs/wallet-adapter
In practice it would be something like this in your frontend
export const Component = () => {
const { connection } = useConnection();
const { sendTransaction } = useWallet();
const handle = async () => {
const ix: TransactionInstruction = await tipSol(receiverKey);
const tx = new Transaction().add(ix);
const sig = await sendTransaction(tx, connection);
};
// ...
};