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
The sendNEAR() method provides a simple way to transfer NEAR tokens from the connected account to any receiver. The wallet handles transaction signing and broadcasting.
Basic Transfer
Send NEAR tokens to another account:
do {
let result = try await walletManager. sendNEAR (
to : "bob.near" ,
amountYocto : "1000000000000000000000000" // 1 NEAR
)
print ( "Transaction hash: \( result. transactionHashes . first ?? "" ) " )
} catch {
print ( "Transfer failed: \( error. localizedDescription ) " )
}
NEAR amounts must be specified in yoctoNEAR (1 NEAR = 10²⁴ yoctoNEAR). Use the conversion utilities to convert from human-readable amounts.
Amount Conversion
Convert between NEAR and yoctoNEAR:
NEAR to yoctoNEAR
yoctoNEAR to NEAR
// Convert "1.5" NEAR to yoctoNEAR
if let yocto = NEARWalletManager. toYoctoNEAR ( "1.5" ) {
print (yocto) // "1500000000000000000000000"
}
Complete Example
Here’s the real transfer flow from the example app:
import SwiftUI
import NEARConnect
struct TransactionDemoView : View {
@EnvironmentObject var walletManager: NEARWalletManager
@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 {
Form {
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 )
}
}
. 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
}
Task {
isProcessing = true
defer { isProcessing = false }
do {
let txResult = try await walletManager. sendNEAR (
to : receiverId,
amountYocto : yocto
)
let hashes = txResult. transactionHashes . joined ( separator : ", " )
print ( "✅ Transaction hashes: \( hashes ) " )
} catch {
errorMessage = error. localizedDescription
showError = true
}
}
}
}
Transaction Result
The sendNEAR() method returns a TransactionResult:
public struct TransactionResult {
public let transactionHashes: [ String ]
public let rawResult: String ?
}
Accessing Transaction Data
let result = try await walletManager. sendNEAR (
to : "receiver.near" ,
amountYocto : yoctoAmount
)
// Get transaction hash(es)
if let hash = result.transactionHashes. first {
print ( "Transaction hash: \( hash ) " )
// Build NEAR Explorer URL
let explorerURL: String
if walletManager.network == .mainnet {
explorerURL = "https://nearblocks.io/txns/ \( hash ) "
} else {
explorerURL = "https://testnet.nearblocks.io/txns/ \( hash ) "
}
print ( "View on explorer: \( explorerURL ) " )
}
// Raw result from wallet (if available)
if let raw = result.rawResult {
print ( "Raw result: \( raw ) " )
}
Error Handling
Handle common transfer errors:
do {
let result = try await walletManager. sendNEAR (
to : receiverId,
amountYocto : yoctoAmount
)
print ( "✅ Transfer successful" )
} catch NEARError. notSignedIn {
print ( "❌ Please connect a wallet first" )
} catch NEARError. operationInProgress {
print ( "❌ Another operation is in progress" )
} catch NEARError. webViewNotReady {
print ( "❌ Wallet bridge not ready, please wait" )
} catch NEARError. walletError ( let message) {
print ( "❌ Wallet error: \( message ) " )
} catch {
print ( "❌ Unexpected error: \( error. localizedDescription ) " )
}
The sendNEAR() method requires an active wallet connection. Check walletManager.isSignedIn before calling.
Handling User Rejection
Users can reject transactions in the wallet UI:
Task {
do {
let result = try await walletManager. sendNEAR (
to : receiverId,
amountYocto : yoctoAmount
)
// Transaction approved and sent
showSuccessMessage ( "Transfer sent!" )
} catch NEARError. walletError ( let message) {
if message. contains ( "Cancelled" ) || message. contains ( "rejected" ) {
// User cancelled - this is not an error
print ( "User cancelled transaction" )
} else {
// Actual error
showErrorMessage (message)
}
} catch {
showErrorMessage (error. localizedDescription )
}
}
Validation Best Practices
Validate receiver account
Check that the receiver ID is not empty and follows NEAR account format: func isValidAccountId ( _ accountId : String ) -> Bool {
// Basic validation: non-empty, lowercase, contains valid characters
let pattern = "^[a-z0-9._-]+$"
return ! accountId. isEmpty &&
accountId. range ( of : pattern, options : . regularExpression ) != nil
}
Validate amount
Ensure the amount is valid and can be converted to yoctoNEAR: guard let yocto = NEARWalletManager. toYoctoNEAR (amount),
! yocto. isEmpty ,
yocto != "0" else {
showError ( "Invalid amount" )
return
}
Check sufficient balance (optional)
Query the account balance before sending: do {
let accountInfo = try await walletManager. viewAccount ()
if let balanceStr = accountInfo[ "amount" ] as? String ,
let balance = Decimal ( string : balanceStr),
let sendAmount = Decimal ( string : yocto),
sendAmount > balance {
showError ( "Insufficient balance" )
return
}
} catch {
// Balance check failed, proceed anyway (wallet will reject if insufficient)
}
Displaying Balance
Fetch and display the connected account’s balance:
struct BalanceView : View {
@EnvironmentObject var walletManager: NEARWalletManager
@State private var balance: String ?
var body: some View {
VStack {
if let balance {
Text ( " \( balance ) NEAR" )
. font (. title2 )
} else {
ProgressView ()
}
}
. task {
await fetchBalance ()
}
}
private func fetchBalance () async {
do {
let result = try await walletManager. viewAccount ()
if let amountStr = result[ "amount" ] as? String {
balance = NEARWalletManager. formatNEAR ( yoctoNEAR : amountStr)
}
} catch {
print ( "Failed to fetch balance: \( error ) " )
}
}
}
Advanced: Custom Actions
For more control, use signAndSendTransaction() with custom actions:
let actions: [[ String : Any ]] = [
[
"type" : "Transfer" ,
"params" : [ "deposit" : yoctoAmount]
]
]
let result = try await walletManager. signAndSendTransaction (
receiverId : receiverId,
actions : actions
)
This allows combining multiple actions in a single transaction (e.g., transfer + function call).
Next Steps