Skip to content

Transaction

Ethereum

To send a transaction from the embedded wallet, send an eth_sendTransaction JSON-RPC request to the wallet provider. In the request's params, specify your transaction data as a hexadecimal string encoding of your transaction request.

By default, embedded wallets are connected to the Ethereum mainnet. To send a transaction on a different network, simply set the wallet's chainId in the transaction request.

Before calling this method, be sure to check the embeddedWalletState is connected.

swift
func sendTransaction() async throws {
    guard case .connected(let wallets) = privy.embeddedWallet.embeddedWalletState else {
        print("Wallet not connected")
        return
    }

    guard let wallet = wallets.first, wallet.chainType == .ethereum else {
        print("No Ethereum wallets available")
        return
    }

    let tx = try JSONEncoder().encode([
        "value": toHexString(100000000000000), // use a wei value in hex format
        "to": "0x52a4f8E69A12C36EF43d23DfA4d13D9c3bCae844", // destination address
        "chainId": "0xaa36a7", // Sepolia chainId as hex, defaults to mainnet (1) if omitted
        "from": wallet.address, // logged in user's embedded wallet address
    ])

    guard let txString = String(data: tx, encoding: .utf8) else {
        print("Data parse error")
        return
    }

    // Get RPC provider for wallet
    let provider = try privy.embeddedWallet.getEthereumProvider(for: wallet.address)

    let transactionHash = try await provider.request(
        RpcRequest(
            method: "eth_sendTransaction",
            params: [txString]
        )
    )

    print(transactionHash)
}

Solana

The Privy SDK supports signing transactions on the Solana blockchain to be sent with either the Solana JSON-RPC API or a Swift SDK built for Solana.

To do this, you can serialize the transaction to a message and use the signMessage method on the Solana embedded wallet provider.

INFO

The following sample code uses SolanaSwift, but Privy supports any Solana SDK that can build and send transaction, or even a manual implementation against a Solana JSON-RPC API.

swift
import SolanaSwift

// Create a Solana RPC client
let solana = JSONRPCAPIClient(...)

func signAndSendSolanaTransaction() async throws {
    guard case .connected(let wallets) = privy.embeddedWallet.embeddedWalletState else {
        print("Wallet not connected")
        return
    }

    // Replace this with your desired wallet, ensure it's a Solana wallet
    guard let wallet = wallets.first, wallet.chainType == .solana else {
        print("No Solana wallets available")
        return
    }

    // Get the provider for wallet. Wallet chainType MUST be .solana
    let provider = try privy.embeddedWallet.getSolanaProvider(for: wallet.address)

    // Build the transaction using your preferred method
    let latestBlockhash = try await solana.getLatestBlockhash()
    let walletPK = try PublicKey(string: wallet.address)
    var tx = Transaction()
    tx.instructions.append(
        SystemProgram.transferInstruction(
            from: walletPK,
            to: try PublicKey(string: "9NvE68JVWHHHGLp5NNELtM5fiBw6SXHrzqQJjUqaykC1"),
            lamports: 100000000000000
        )
    )
    tx.recentBlockhash = recentBlockhash
    tx.feePayer = originPK

    // Serialize the transaction for signing as base64
    let message = try tx.compileMessage().serialize().base64EncodedString()

    // Sign using the Privy Embedded Wallet.
    let signature = try await provider.signMessage(message: message)

    // Add the signature back to the transaction
    try tx.addSignature(signature: Data(base64Encoded: signature), publicKey: walletPK)

    // Send the transaction via a JSON-RPC call
    try await solana.sendTransaction(transaction: tx.serialize().base64EncodedString())
}