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); } }
Advertisement
Answer
Frontends never access private keys. Instead the flow is something like:
- Frontend creates the transaction
- Frontend sends the transaction to the wallet
- Wallet signs the transaction
- Wallet returns the signed transaction to the frontend
- Frontend send the transaction
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); }; // ... };