'use client';
import { useCallback, useState } from 'react';
import {
useConnection as useSolanaConnection,
useWallet as useSolanaWallet,
} from '@solana/wallet-adapter-react';
import { PublicKey, SystemProgram, Transaction } from '@solana/web3.js';
import { Button } from '../Button';
import { truncateAddress } from '../../../lib/truncateAddress';
import { renderError } from '../../../lib/errorUtils';
/**
* SendSolana component handles sending SOL transactions on Solana.
*
* This component provides a simple interface for users to send SOL transactions
* using their connected Solana wallet. It includes transaction status tracking
* and error handling.
*
* Features:
* - SOL transaction sending
* - Transaction status tracking
* - Error handling and display
* - Loading state management
*
* Note: This component is a placeholder implementation. In a real application,
* you would integrate with a Solana wallet adapter and transaction library
* like @solana/web3.js to handle actual transactions.
*
* @example
* ```tsx
*
* ```
*/
export function SendSolana() {
const [solanaTransactionState, setSolanaTransactionState] = useState<
| { status: 'none' }
| { status: 'pending' }
| { status: 'error'; error: Error }
| { status: 'success'; signature: string }
>({ status: 'none' });
const { connection: solanaConnection } = useSolanaConnection();
const { sendTransaction, publicKey } = useSolanaWallet();
// This should be replaced but including it from the original demo
// https://github.com/farcasterxyz/frames-v2-demo/blob/main/src/components/Demo.tsx#L718
const ashoatsPhantomSolanaWallet =
'Ao3gLNZAsbrmnusWVqQCPMrcqNi6jdYgu8T6NCoXXQu1';
/**
* Handles sending the Solana transaction
*/
const sendSolanaTransaction = useCallback(async () => {
setSolanaTransactionState({ status: 'pending' });
try {
if (!publicKey) {
throw new Error('no Solana publicKey');
}
const { blockhash } = await solanaConnection.getLatestBlockhash();
if (!blockhash) {
throw new Error('failed to fetch latest Solana blockhash');
}
const fromPubkeyStr = publicKey.toBase58();
const toPubkeyStr = ashoatsPhantomSolanaWallet;
const transaction = new Transaction();
transaction.add(
SystemProgram.transfer({
fromPubkey: new PublicKey(fromPubkeyStr),
toPubkey: new PublicKey(toPubkeyStr),
lamports: 0n,
})
);
transaction.recentBlockhash = blockhash;
transaction.feePayer = new PublicKey(fromPubkeyStr);
const simulation =
await solanaConnection.simulateTransaction(transaction);
if (simulation.value.err) {
// Gather logs and error details for debugging
const logs = simulation.value.logs?.join('\n') ?? 'No logs';
const errDetail = JSON.stringify(simulation.value.err);
throw new Error(`Simulation failed: ${errDetail}\nLogs:\n${logs}`);
}
const signature = await sendTransaction(transaction, solanaConnection);
setSolanaTransactionState({ status: 'success', signature });
} catch (e) {
if (e instanceof Error) {
setSolanaTransactionState({ status: 'error', error: e });
} else {
setSolanaTransactionState({ status: 'none' });
}
}
}, [sendTransaction, publicKey, solanaConnection]);
return (
<>
{solanaTransactionState.status === 'error' &&
renderError(solanaTransactionState.error)}
{solanaTransactionState.status === 'success' && (
Hash: {truncateAddress(solanaTransactionState.signature)}
)}
>
);
}