Skip to main content

sdk.solana

Solana blockchain operations module for interacting with the Solana network.

createConnection

Create a connection to the Solana network.
try sdk.solana.createConnection() -> SolanaConnection

Returns

  • SolanaConnection - Connection to the configured Solana network

Example

import DynamicSDKSwift

let sdk = DynamicSDK.instance()

let connection = try sdk.solana.createConnection()

// Get latest blockhash
let blockhashResult = try await connection.getLatestBlockhash()
print("Latest blockhash: \(blockhashResult.blockhash)")

createSigner

Create a signer for a Solana wallet. The signer is used to sign messages and transactions.
sdk.solana.createSigner(wallet: BaseWallet) -> SolanaSigner

Parameters

  • wallet (BaseWallet) - Solana wallet to create signer for

Returns

  • SolanaSigner - Signer instance for the wallet

Example

import DynamicSDKSwift

let sdk = DynamicSDK.instance()

// Get Solana wallet
let solanaWallets = sdk.wallets.userWallets.filter { $0.chain.uppercased() == "SOL" }

if let wallet = solanaWallets.first {
    let signer = sdk.solana.createSigner(wallet: wallet)

    // Use signer for operations
    let signature = try await signer.signMessage(message: "Hello, Solana!")
    print("Signature: \(signature)")
}

SolanaConnection

Connection instance for Solana network operations.

getLatestBlockhash

Get the latest blockhash from the network. Required for building transactions.
try await connection.getLatestBlockhash() -> BlockhashResult

Returns

  • BlockhashResult - Object containing blockhash string property

Example

let connection = try sdk.solana.createConnection()
let result = try await connection.getLatestBlockhash()

// Access the blockhash string
let blockhash = result.blockhash
print("Blockhash: \(blockhash)")

getBalance

Get the balance of a Solana account in lamports.
try await connection.getBalance(publicKey: PublicKey) -> UInt64

Parameters

  • publicKey (PublicKey) - Public key of the account

Returns

  • UInt64 - Balance in lamports (1 SOL = 1,000,000,000 lamports)

Example

import SolanaWeb3

let connection = try sdk.solana.createConnection()

guard let pubkey = try? PublicKey(string: wallet.address) else {
    throw SolanaError.invalidAddress
}

let balance = try await connection.getBalance(publicKey: pubkey)
let solBalance = Double(balance) / 1_000_000_000
print("Balance: \(solBalance) SOL")

SolanaSigner

Signer for Solana wallet operations including message signing and transaction handling.

signMessage

Sign an arbitrary message with the wallet.
try await signer.signMessage(message: String) -> String

Parameters

  • message (String) - Message to sign

Returns

  • String - Base58-encoded signature

Example

let sdk = DynamicSDK.instance()

let signer = sdk.solana.createSigner(wallet: wallet)
let signature = try await signer.signMessage(message: "Hello from Dynamic SDK!")

print("Signature: \(signature)")

signEncodedTransaction

Sign a base64-encoded transaction without broadcasting it.
try await signer.signEncodedTransaction(base64Transaction: String) -> String

Parameters

  • base64Transaction (String) - Base64-encoded serialized transaction

Returns

  • String - Base64-encoded signed transaction

Example

let sdk = DynamicSDK.instance()

let signer = sdk.solana.createSigner(wallet: wallet)

// Sign without sending
let signedTransaction = try await signer.signEncodedTransaction(
    base64Transaction: base64EncodedTx
)

print("Signed transaction: \(signedTransaction)")

signAndSendEncodedTransaction

Sign and broadcast a base64-encoded transaction to the network.
try await signer.signAndSendEncodedTransaction(base64Transaction: String) -> String

Parameters

  • base64Transaction (String) - Base64-encoded serialized transaction

Returns

  • String - Transaction signature (can be used to track on explorer)

Example

let sdk = DynamicSDK.instance()

let signer = sdk.solana.createSigner(wallet: wallet)

// Sign and send
let signature = try await signer.signAndSendEncodedTransaction(
    base64Transaction: base64EncodedTx
)

print("Transaction signature: \(signature)")
// View on explorer: https://explorer.solana.com/tx/\(signature)

sdk.networks.solana

Access configured Solana networks.
let solanaNetworks = sdk.networks.solana  // [GenericNetwork]

Example

let sdk = DynamicSDK.instance()

for network in sdk.networks.solana {
    print("Network: \(network.name)")
}

Building Transactions

Solana transactions require the SolanaWeb3 package for construction.

Dependencies

Add the SolanaWeb3 package to your project:
// Package.swift
dependencies: [
    .package(url: "https://github.com/solana-mobile/SolanaSwift", from: "1.0.0")
]

Using SolanaTransactionBuilder

The SDK provides a transaction builder for common operations:
import SolanaWeb3

// Create a SOL transfer transaction
let transaction = try SolanaWeb3.SolanaTransactionBuilder.createVersionedTransferTransaction(
    from: wallet.address,
    to: recipientAddress,
    lamports: lamports,
    recentBlockhash: blockhashResult.blockhash
)

// Serialize to base64 for signing
let base64Transaction = transaction.serializeToBase64()

Complete Send SOL Example

import DynamicSDKSwift
import SolanaWeb3

let sdk = DynamicSDK.instance()

func sendSOL(
    wallet: BaseWallet,
    recipient: String,
    amountInSOL: Double
) async throws -> String {
    // Create connection and signer
    let connection = try sdk.solana.createConnection()
    let signer = sdk.solana.createSigner(wallet: wallet)

    // Get latest blockhash
    let blockhashResult = try await connection.getLatestBlockhash()

    // Convert SOL to lamports (1 SOL = 10^9 lamports)
    let lamports = UInt64(amountInSOL * 1_000_000_000)

    // Create versioned transfer transaction
    let transaction = try SolanaWeb3.SolanaTransactionBuilder.createVersionedTransferTransaction(
        from: wallet.address,
        to: recipient,
        lamports: lamports,
        recentBlockhash: blockhashResult.blockhash
    )

    // Sign and send
    return try await signer.signAndSendEncodedTransaction(
        base64Transaction: transaction.serializeToBase64()
    )
}

// Usage
let solanaWallet = sdk.wallets.userWallets.first { $0.chain.uppercased() == "SOL" }!
let signature = try await sendSOL(
    wallet: solanaWallet,
    recipient: "4ybGGu1vxysaZrBBSLVGfsxLydHREkHDYHUCnFk6os5D",
    amountInSOL: 0.001
)
print("Transaction sent: \(signature)")

Complete Sign Message Example

import DynamicSDKSwift

let sdk = DynamicSDK.instance()

func signSolanaMessage(wallet: BaseWallet, message: String) async throws -> String {
    let signer = sdk.solana.createSigner(wallet: wallet)
    return try await signer.signMessage(message: message)
}

// Usage
let solanaWallet = sdk.wallets.userWallets.first { $0.chain.uppercased() == "SOL" }!
let signature = try await signSolanaMessage(
    wallet: solanaWallet,
    message: "Sign to authenticate with MyApp"
)
print("Signature: \(signature)")

Complete Sign Transaction Example

import DynamicSDKSwift

let sdk = DynamicSDK.instance()

func signSolanaTransaction(
    wallet: BaseWallet,
    base64Transaction: String
) async throws -> String {
    let signer = sdk.solana.createSigner(wallet: wallet)
    return try await signer.signEncodedTransaction(base64Transaction: base64Transaction)
}

// Usage
let solanaWallet = sdk.wallets.userWallets.first { $0.chain.uppercased() == "SOL" }!
let signedTx = try await signSolanaTransaction(
    wallet: solanaWallet,
    base64Transaction: preBuiltBase64Transaction
)
print("Signed transaction: \(signedTx)")

SwiftUI Integration

Send SOL View

import SwiftUI
import DynamicSDKSwift
import SolanaWeb3

struct SolanaSendView: View {
    let wallet: BaseWallet

    @State private var recipient = ""
    @State private var amount = "0.001"
    @State private var signature: String?
    @State private var isLoading = false
    @State private var error: String?

    var body: some View {
        ScrollView {
            VStack(spacing: 20) {
                TextField("Recipient Address", text: $recipient)
                    .textFieldStyle(.roundedBorder)
                    .autocapitalization(.none)

                TextField("Amount (SOL)", text: $amount)
                    .textFieldStyle(.roundedBorder)
                    .keyboardType(.decimalPad)

                Button("Send SOL") {
                    Task { await sendTransaction() }
                }
                .buttonStyle(.borderedProminent)
                .disabled(recipient.isEmpty || amount.isEmpty || isLoading)

                if isLoading {
                    ProgressView("Sending...")
                }

                if let signature = signature {
                    VStack(spacing: 8) {
                        Text("Success!")
                            .foregroundColor(.green)
                            .fontWeight(.semibold)

                        Text("Signature: \(signature)")
                            .font(.caption)
                            .lineLimit(1)
                    }
                    .padding()
                    .background(Color.green.opacity(0.1))
                    .cornerRadius(8)
                }

                if let error = error {
                    Text(error)
                        .foregroundColor(.red)
                        .font(.caption)
                }
            }
            .padding()
        }
        .navigationTitle("Send SOL")
    }

    private func sendTransaction() async {
        guard let amountValue = Double(amount) else {
            error = "Invalid amount"
            return
        }

        isLoading = true
        error = nil
        signature = nil

        do {
            let sdk = DynamicSDK.instance()

            // Convert SOL to lamports
            let lamports = UInt64(amountValue * 1_000_000_000)

            // Create connection and signer
            let connection = try sdk.solana.createConnection()
            let signer = sdk.solana.createSigner(wallet: wallet)

            // Get latest blockhash
            let blockhash = try await connection.getLatestBlockhash()

            // Create transaction
            let transaction = try SolanaWeb3.SolanaTransactionBuilder.createVersionedTransferTransaction(
                from: wallet.address,
                to: recipient,
                lamports: lamports,
                recentBlockhash: blockhash.blockhash
            )

            // Sign and send
            signature = try await signer.signAndSendEncodedTransaction(
                base64Transaction: transaction.serializeToBase64()
            )
        } catch {
            self.error = error.localizedDescription
        }

        isLoading = false
    }
}

Sign Message View

import SwiftUI
import DynamicSDKSwift

struct SolanaSignMessageView: View {
    let wallet: BaseWallet

    @State private var message = "Hello from Dynamic SDK!"
    @State private var signature: String?
    @State private var isLoading = false
    @State private var error: String?

    var body: some View {
        ScrollView {
            VStack(spacing: 20) {
                TextField("Message to sign", text: $message)
                    .textFieldStyle(.roundedBorder)

                Button("Sign Message") {
                    Task { await signMessage() }
                }
                .buttonStyle(.borderedProminent)
                .disabled(message.isEmpty || isLoading)

                if isLoading {
                    ProgressView("Signing...")
                }

                if let signature = signature {
                    VStack(alignment: .leading, spacing: 8) {
                        Text("Signature:")
                            .font(.headline)

                        Text(signature)
                            .font(.system(.caption, design: .monospaced))
                            .textSelection(.enabled)
                    }
                    .padding()
                    .background(Color.green.opacity(0.1))
                    .cornerRadius(8)
                }

                if let error = error {
                    Text(error)
                        .foregroundColor(.red)
                        .font(.caption)
                }
            }
            .padding()
        }
        .navigationTitle("Sign Message")
    }

    private func signMessage() async {
        isLoading = true
        error = nil
        signature = nil

        do {
            let signer = DynamicSDK.instance().solana.createSigner(wallet: wallet)
            signature = try await signer.signMessage(message: message)
        } catch {
            self.error = error.localizedDescription
        }

        isLoading = false
    }
}

Lamports Conversion

Solana uses lamports as its smallest unit:
// 1 SOL = 1,000,000,000 lamports

func solToLamports(_ sol: Double) -> UInt64 {
    return UInt64(sol * 1_000_000_000)
}

func lamportsToSol(_ lamports: UInt64) -> Double {
    return Double(lamports) / 1_000_000_000
}

// Examples
let lamports = solToLamports(1.5)     // 1,500,000,000
let sol = lamportsToSol(500_000_000)  // 0.5

Transaction Explorer

func solanaExplorerURL(signature: String, cluster: String = "devnet") -> URL? {
    URL(string: "https://explorer.solana.com/tx/\(signature)?cluster=\(cluster)")
}

// Clusters: "mainnet-beta", "devnet", "testnet"

Error Handling

do {
    let signature = try await signer.signAndSendEncodedTransaction(
        base64Transaction: base64Tx
    )
    print("Success: \(signature)")
} catch {
    let errorDesc = error.localizedDescription.lowercased()

    if errorDesc.contains("insufficient") {
        print("Insufficient SOL balance")
    } else if errorDesc.contains("blockhash") {
        print("Blockhash expired - try again")
    } else if errorDesc.contains("rejected") || errorDesc.contains("denied") {
        print("User rejected the transaction")
    } else {
        print("Transaction failed: \(error)")
    }
}

Signer Methods Summary

MethodDescription
signMessage(message:)Sign an arbitrary message
signEncodedTransaction(base64Transaction:)Sign a transaction without sending
signAndSendEncodedTransaction(base64Transaction:)Sign and broadcast a transaction

Connection Methods Summary

MethodDescription
getLatestBlockhash()Get latest blockhash for transactions
getBalance(publicKey:)Get account balance in lamports
getAccountInfo(publicKey:)Get detailed account information

Next Steps