Open this lesson in your favourite AI. It'll walk you through the why, explain the demo, and quiz you on the try-it list.
Nothing teaches you the model like shipping a transaction. This closing task of Module 1 walks you through sending a real transaction on devnet, reading it in an explorer, and confirming every piece you've learned matches the on-wire reality. By the end you should be able to open any random Solana transaction in solscan.io and read it like a native.
Send 0.01 SOL to a friend. Watch it land. Open the transaction in the explorer. Identify: the signers, the instructions, the accounts loaded, the fee, the slot, the confirmation status. That's the whole picture.
Use these three in order. Each builds on the one before.
In one paragraph, explain what happens end-to-end when you send a transaction on Solana — from signing in your wallet to it landing on-chain.
Walk me through the confirmation lifecycle: 'processed' vs 'confirmed' vs 'finalized' — what each means, how long each takes in practice, and when an application should treat a transaction as final.
I'm building a high-throughput bot that sends 100 transactions per second on mainnet. Walk me through the architecture: priority fee strategy, jito bundles for MEV protection, RPC provider redundancy, and how to handle transient blockhash-expiration errors.
// main.go — send 0.01 SOL and inspect the result
// dep: github.com/gagliardetto/solana-go (go get github.com/gagliardetto/solana-go)
package main
import (
"context"
"fmt"
"os"
"github.com/gagliardetto/solana-go"
"github.com/gagliardetto/solana-go/programs/system"
"github.com/gagliardetto/solana-go/rpc"
confirm "github.com/gagliardetto/solana-go/rpc/sendAndConfirmTransaction"
"github.com/gagliardetto/solana-go/rpc/ws"
)
const LAMPORTS_PER_SOL = 1_000_000_000
func main() {
ctx := context.Background()
// Connect to devnet
client := rpc.New(rpc.DevNet_RPC)
wsClient, err := ws.Connect(ctx, rpc.DevNet_WS)
if err != nil {
panic(err)
}
// Load your local keypair (~/.config/solana/id.json)
from, err := solana.PrivateKeyFromSolanaKeygenFile(
os.Getenv("HOME") + "/.config/solana/id.json",
)
if err != nil {
panic(err)
}
// A random friend (replace with theirs)
to := solana.MustPublicKeyFromBase58("SomeFriendPubkeyHere1111111111111111111111")
// Build the transfer instruction
recent, err := client.GetLatestBlockhash(ctx, rpc.CommitmentConfirmed)
if err != nil {
panic(err)
}
tx, err := solana.NewTransaction(
[]solana.Instruction{
system.NewTransferInstruction(
uint64(0.01*LAMPORTS_PER_SOL),
from.PublicKey(),
to,
).Build(),
},
recent.Value.Blockhash,
solana.TransactionPayer(from.PublicKey()),
)
if err != nil {
panic(err)
}
_, err = tx.Sign(func(key solana.PublicKey) *solana.PrivateKey {
if key.Equals(from.PublicKey()) {
return &from
}
return nil
})
if err != nil {
panic(err)
}
sig, err := confirm.SendAndConfirmTransaction(ctx, client, wsClient, tx)
if err != nil {
panic(err)
}
fmt.Println("Tx:", sig)
fmt.Println("Explorer: https://solscan.io/tx/" + sig.String() + "?cluster=devnet")
// Fetch and inspect the confirmed transaction
version := uint64(0)
full, err := client.GetTransaction(ctx, sig, &rpc.GetTransactionOpts{
MaxSupportedTransactionVersion: &version,
Commitment: rpc.CommitmentConfirmed,
})
if err != nil {
panic(err)
}
fmt.Println("Fee paid:", full.Meta.Fee, "lamports")
fmt.Println("Pre-balances:", full.Meta.PreBalances)
fmt.Println("Post-balances:", full.Meta.PostBalances)
}
go run main.go