Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/frol/near-connect-ios/llms.txt

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

Overview

This guide demonstrates how to send NEAR tokens from the connected wallet to another account. The example includes a complete UI with form validation, loading states, and error handling.
This code is extracted from the working TransactionDemoView in the NEAR Connect iOS example app.

Complete Token Transfer Example

import SwiftUI
import NEARConnect

struct TransactionDemoView: View {
    @EnvironmentObject var walletManager: NEARWalletManager
    @Environment(\.dismiss) private var dismiss
    var onLog: ((_ action: String, _ params: String, _ output: String, _ isError: Bool) -> Void)?

    @State private var receiverId = ""
    @State private var amount = "0.01"
    @State private var isProcessing = false
    @State private var showError = false
    @State private var errorMessage = ""

    var body: some View {
        NavigationView {
            Form {
                Section {
                    Text("Send NEAR tokens to another account via your connected wallet")
                        .font(.subheadline)
                        .foregroundColor(.secondary)
                }

                Section(header: Text("Transfer Details")) {
                    HStack {
                        Text("From")
                            .foregroundColor(.secondary)
                        Spacer()
                        Text(walletManager.currentAccount?.accountId ?? "")
                            .font(.caption)
                    }

                    TextField("Receiver (e.g., bob.near)", text: $receiverId)
                        .textInputAutocapitalization(.never)
                        .autocorrectionDisabled()

                    HStack {
                        TextField("Amount", text: $amount)
                            .keyboardType(.decimalPad)
                        Text("NEAR")
                            .foregroundColor(.secondary)
                    }
                }

                Section {
                    Button(action: sendTransaction) {
                        HStack {
                            Spacer()
                            if isProcessing {
                                ProgressView()
                                    .padding(.trailing, 8)
                            }
                            Text(isProcessing ? "Sending..." : "Send NEAR")
                            Spacer()
                        }
                    }
                    .disabled(isProcessing || receiverId.isEmpty || amount.isEmpty)
                }

                Section {
                    Text("The wallet will open to confirm the transaction. The transaction is signed and broadcast by the wallet.")
                        .font(.caption)
                        .foregroundColor(.secondary)
                }
            }
            .navigationTitle("Send NEAR")
            .navigationBarTitleDisplayMode(.inline)
            .toolbar {
                ToolbarItem(placement: .navigationBarTrailing) {
                    Button("Done") { dismiss() }
                        .disabled(isProcessing)
                }
            }
            .alert("Error", isPresented: $showError) {
                Button("OK", role: .cancel) { }
            } message: {
                Text(errorMessage)
            }
        }
    }

    private func sendTransaction() {
        guard let yocto = NEARWalletManager.toYoctoNEAR(amount) else {
            errorMessage = "Invalid amount"
            showError = true
            return
        }

        let params = "to: \(receiverId), amount: \(amount) NEAR"
        Task {
            isProcessing = true
            defer { isProcessing = false }

            do {
                let txResult = try await walletManager.sendNEAR(
                    to: receiverId,
                    amountYocto: yocto
                )
                let hashes = txResult.transactionHashes.joined(separator: ", ")
                onLog?("sendNEAR", params, "Hashes: \(hashes)", false)
            } catch {
                onLog?("sendNEAR", params, error.localizedDescription, true)
                errorMessage = error.localizedDescription
                showError = true
            }
        }
    }
}

Step-by-Step Breakdown

1
Access the Wallet Manager
2
@EnvironmentObject var walletManager: NEARWalletManager
3
Get the wallet manager from the environment to access the sendNEAR method.
4
Define State Variables
5
@State private var receiverId = ""
@State private var amount = "0.01"
@State private var isProcessing = false
@State private var showError = false
@State private var errorMessage = ""
6
Track the form inputs, loading state, and error state.
7
Convert NEAR to Yocto
8
guard let yocto = NEARWalletManager.toYoctoNEAR(amount) else {
    errorMessage = "Invalid amount"
    showError = true
    return
}
9
NEAR amounts must be converted to yoctoNEAR (1 NEAR = 10^24 yoctoNEAR) before sending. The toYoctoNEAR helper handles this conversion.
10
Send the Transaction
11
let txResult = try await walletManager.sendNEAR(
    to: receiverId,
    amountYocto: yocto
)
let hashes = txResult.transactionHashes.joined(separator: ", ")
12
Call sendNEAR with the receiver account ID and amount in yoctoNEAR. The method returns transaction hashes upon success.
13
Handle Errors
14
catch {
    errorMessage = error.localizedDescription
    showError = true
}
15
Display any errors to the user with an alert.

Key Methods and Types

func sendNEAR(
    to receiverId: String,
    amountYocto: String
) async throws -> TransactionResult
Sends NEAR tokens to another account.Parameters:
  • receiverId: The recipient’s NEAR account ID (e.g., “bob.near”)
  • amountYocto: Amount in yoctoNEAR (use toYoctoNEAR to convert)
Returns:
  • TransactionResult containing transaction hashes and status
Throws:
  • Error if the transaction fails or user cancels

User Flow

1

User enters recipient and amount

The form collects the receiver’s account ID and amount in NEAR tokens.
2

App converts amount to yoctoNEAR

The toYoctoNEAR helper converts the human-readable amount to the blockchain format.
3

User taps Send NEAR button

The app calls sendNEAR which triggers the wallet UI to appear.
4

User approves in wallet

The WalletBridgeSheet shows the wallet’s approval screen where the user can review and sign the transaction.
5

Transaction is broadcast

The wallet signs and broadcasts the transaction to the NEAR network.
6

App receives transaction hashes

The sendNEAR method returns with transaction hashes that can be used to track the transaction.
Always use the defer pattern to reset loading states, ensuring the UI is updated even if an error occurs:
Task {
    isProcessing = true
    defer { isProcessing = false }
    
    // Your async code here
}

Common Use Cases

Send a Fixed Amount

let txResult = try await walletManager.sendNEAR(
    to: "recipient.near",
    amountYocto: "10000000000000000000000" // 0.01 NEAR
)

Send with User Input Validation

func sendWithValidation(to: String, amount: String) async throws {
    guard !to.isEmpty else {
        throw TransferError.emptyReceiver
    }
    
    guard let yocto = NEARWalletManager.toYoctoNEAR(amount) else {
        throw TransferError.invalidAmount
    }
    
    guard Double(amount) ?? 0 > 0 else {
        throw TransferError.zeroAmount
    }
    
    let result = try await walletManager.sendNEAR(
        to: to,
        amountYocto: yocto
    )
}

Track Transaction Status

let txResult = try await walletManager.sendNEAR(
    to: receiverId,
    amountYocto: yocto
)

for hash in txResult.transactionHashes {
    print("Transaction: https://explorer.near.org/transactions/\(hash)")
}

Next Steps

Smart Contracts

Learn how to call smart contract functions

Authentication

Implement connect and sign message flows

API Reference

Full NEARWalletManager documentation

Error Handling

Handle errors gracefully