Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.dynamic.xyz/docs/llms.txt

Use this file to discover all available pages before exploring further.

Overview

The Solana connection allows you to interact with the Solana blockchain, query data, and prepare transactions using the Flutter Solana package.

Prerequisites

  • Dynamic SDK initialized (see Quickstart)
  • User authenticated (see Authentication)
  • Solana wallets enabled in your Dynamic dashboard
  • dynamic_sdk_solana package installed

Create Connection

import 'package:dynamic_sdk/dynamic_sdk.dart';

final sdk = DynamicSDK.instance;

void createConnection() {
  final connection = sdk.solana.createConnection();
  print('Solana connection created');
}

Get Latest Blockhash

Required for building transactions:
import 'package:dynamic_sdk/dynamic_sdk.dart';
import 'package:solana/solana.dart';

final sdk = DynamicSDK.instance;

Future<String> getBlockhash() async {
  final connection = sdk.solana.createConnection();
  final result = await connection.getLatestBlockhash();
  print('Latest blockhash: ${result.blockhash}');
  return result.blockhash;
}

Query Account Balance

import 'package:dynamic_sdk/dynamic_sdk.dart';
import 'package:solana/solana.dart';

final sdk = DynamicSDK.instance;

Future<int> getBalance(String address) async {
  try {
    final connection = sdk.solana.createConnection();
    final pubkey = Pubkey.fromString(address);
    final balance = await connection.getBalance(pubkey);
    return balance;
  } catch (e) {
    print('Failed to get balance: $e');
    rethrow;
  }
}

Get Solana Wallets

import 'package:dynamic_sdk/dynamic_sdk.dart';

final sdk = DynamicSDK.instance;

List<BaseWallet> getSolanaWallets() {
  final solanaWallets = sdk.wallets.userWallets.where(
    (wallet) => wallet.chain.toUpperCase() == 'SOL',
  ).toList();

  for (final wallet in solanaWallets) {
    print('Address: ${wallet.address}');
  }

  return solanaWallets;
}

Solana Networks

Access configured Solana networks:
final sdk = DynamicSDK.instance;

void displaySolanaNetworks() {
  final solanaNetworks = sdk.networks.solana;

  for (final network in solanaNetworks) {
    print('Network: ${network.name}');
  }
}

Flutter Widget Example

import 'package:flutter/material.dart';
import 'package:dynamic_sdk/dynamic_sdk.dart';
import 'package:solana/solana.dart';

class SolanaBalanceWidget extends StatefulWidget {
  final BaseWallet wallet;

  const SolanaBalanceWidget({Key? key, required this.wallet}) : super(key: key);

  @override
  State<SolanaBalanceWidget> createState() => _SolanaBalanceWidgetState();
}

class _SolanaBalanceWidgetState extends State<SolanaBalanceWidget> {
  final sdk = DynamicSDK.instance;
  int? balance;
  bool isLoading = false;
  String? error;

  @override
  void initState() {
    super.initState();
    _fetchBalance();
  }

  Future<void> _fetchBalance() async {
    setState(() {
      isLoading = true;
      error = null;
    });

    try {
      final connection = sdk.solana.createConnection();
      final pubkey = Pubkey.fromString(widget.wallet.address);
      final balanceValue = await connection.getBalance(pubkey);

      setState(() => balance = balanceValue);
    } catch (e) {
      setState(() => error = 'Failed to fetch balance: $e');
    } finally {
      setState(() => isLoading = false);
    }
  }

  String formatBalance(int lamports) {
    final sol = lamports / 1e9;
    return '${sol.toStringAsFixed(4)} SOL';
  }

  @override
  Widget build(BuildContext context) {
    return Card(
      child: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: [
                const Text(
                  'Balance',
                  style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
                ),
                IconButton(
                  icon: const Icon(Icons.refresh),
                  onPressed: _fetchBalance,
                ),
              ],
            ),
            const SizedBox(height: 8),
            if (isLoading)
              const Center(child: CircularProgressIndicator())
            else if (balance != null)
              Text(
                formatBalance(balance!),
                style: const TextStyle(
                  fontSize: 24,
                  fontWeight: FontWeight.bold,
                ),
              )
            else if (error != null)
              Text(
                error!,
                style: const TextStyle(color: Colors.red, fontSize: 12),
              ),
          ],
        ),
      ),
    );
  }
}

Connection Methods

MethodDescription
createConnection()Create a Solana connection instance
getLatestBlockhash()Get the latest blockhash for transactions
getBalance(pubkey)Get account balance in lamports
getAccountInfo(pubkey)Get detailed account information

Balance Conversion Helpers

class SolanaConverter {
  /// Convert lamports to SOL
  static double lamportsToSol(int lamports) {
    return lamports / 1e9;
  }

  /// Convert SOL to lamports
  static int solToLamports(double sol) {
    return (sol * 1e9).toInt();
  }

  /// Format balance for display
  static String formatBalance(int lamports, {int decimals = 4}) {
    final sol = lamportsToSol(lamports);
    return '${sol.toStringAsFixed(decimals)} SOL';
  }
}

// Usage
final lamports = 1500000000; // 1.5 SOL
final formatted = SolanaConverter.formatBalance(lamports);
print(formatted); // "1.5000 SOL"

Complete Balance Display

import 'package:flutter/material.dart';
import 'package:dynamic_sdk/dynamic_sdk.dart';
import 'package:solana/solana.dart';

class SolanaAccountInfo extends StatelessWidget {
  final BaseWallet wallet;

  const SolanaAccountInfo({Key? key, required this.wallet}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return FutureBuilder<Map<String, dynamic>>(
      future: _getAccountInfo(),
      builder: (context, snapshot) {
        if (snapshot.connectionState == ConnectionState.waiting) {
          return const Center(child: CircularProgressIndicator());
        }

        if (snapshot.hasError) {
          return Text(
            'Error: ${snapshot.error}',
            style: const TextStyle(color: Colors.red),
          );
        }

        if (snapshot.hasData) {
          final data = snapshot.data!;
          return Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Text('Address: ${data['address']}'),
              const SizedBox(height: 8),
              Text(
                'Balance: ${data['balance']}',
                style: const TextStyle(
                  fontSize: 20,
                  fontWeight: FontWeight.bold,
                ),
              ),
              const SizedBox(height: 8),
              Text('Blockhash: ${data['blockhash']}'),
            ],
          );
        }

        return const Text('No data available');
      },
    );
  }

  Future<Map<String, dynamic>> _getAccountInfo() async {
    final sdk = DynamicSDK.instance;
    final connection = sdk.solana.createConnection();

    final pubkey = Pubkey.fromString(wallet.address);
    final balance = await connection.getBalance(pubkey);
    final blockhash = await connection.getLatestBlockhash();

    return {
      'address': wallet.address,
      'balance': SolanaConverter.formatBalance(balance),
      'blockhash': blockhash.blockhash,
    };
  }
}

Error Handling

Future<int?> getBalanceSafely(String address) async {
  try {
    final sdk = DynamicSDK.instance;
    final connection = sdk.solana.createConnection();
    final pubkey = Pubkey.fromString(address);
    return await connection.getBalance(pubkey);
  } catch (e) {
    print('Failed to get balance: $e');
    return null;
  }
}

Dependencies

To build Solana transactions, ensure you have the required package:
dependencies:
  dynamic_sdk_solana: ^1.0.0
  solana: ^0.30.0

Next Steps