web3swift icon indicating copy to clipboard operation
web3swift copied to clipboard

Regular Send ETH

Open ZefsAl opened this issue 11 months ago • 0 comments

Hello, web3swift!

I have a lot of trouble writing a minimal representation example code manager. In the future, I want to use eth-mainnet.alchemyapi.

The goal is to write a simple method that will send ETH to ETH.

After a long search, here is what I managed to do based on old documentation.

My compiler does not see these methods: ( contract.method, .call(options: ...), TransactionOptions.defaultOptions, Web3.Utils, Web3Options.defaultOptions, tx.gasPrice = .automatic, contract.read(...) and contract.write(...)) etc.

import Foundation
import web3swift
import Web3Core
import BigInt
class Web3Manager {
    
    // MARK: - Instances
    let walletPrivateKey = "9b16ebb.........c534f"
    
    // MARK: - send_eth_Keystore ➡️🟢
    func send_eth_Keystore(to toAddress: String, amountEth: String) async {
        
        let web3_infura = try? await Web3.InfuraMainnetWeb3()
        guard let web3_infura else { print("❌ error get web3_infura"); return }
        
        // 1) Params
        guard
            let recipientAddress = EthereumAddress(toAddress),
            let value = Utilities.parseToBigUInt(amountEth, units: .ether)
        else { print("❌ invalid address or sum"); return }
        
        // 2) Local keystore (EthereumKeystoreV3)
        let privateKeyHex = walletPrivateKey.trimmingCharacters(in: .whitespacesAndNewlines)
        guard let privateKeyData = Data.fromHex(privateKeyHex) else { fatalError("❌ Invalid private key!") }
        
        // 3) init keystore
        let keystore = try? EthereumKeystoreV3(privateKey: privateKeyData, password: "PASSWORD")
        guard let keystore else { print("❌ Error getting keystore"); return }
        let keystoreManager = KeystoreManager([keystore])
        web3_infura.addKeystoreManager(keystoreManager)
        
        // 4) Get user address
        let userAddress = keystore.addresses!.first!
        print("fromAddress = ", userAddress)
        
        // 5) Nonce
        let nonce = try? await web3_infura.eth.getTransactionCount(for: userAddress, onBlock: .latest)
        guard let nonce else { print("❌ nonce error", nonce); return }
        print("Nonce: \(nonce)")
        
        // 6) Make tx
        var tx: CodableTransaction = .emptyTransaction
        tx.from = userAddress                                       
        tx.to = recipientAddress                                    
        tx.value = value                                                   
        tx.nonce = nonce                                                   
        tx.chainID = web3_infura.provider.network?.chainID ?? BigUInt(1)   
        
        // 7) Set gas Limit
        let estimatedGas = try! await web3_infura.eth.estimateGas(for: tx)
        tx.gasLimit = estimatedGas + BigUInt(1_000)
        
        // 8) Set gas Price
        let fallbackGasPrice = try! await web3_infura.eth.gasPrice()
        tx.gasPrice = fallbackGasPrice
        
        print("Estimated Gas Limit: \(tx.gasLimit)")
        print("Current Gas Price: \(tx.gasPrice)")
        
        // 9) Sign
        do {
            try tx.sign(privateKey: privateKeyData)
        } catch { print("❌ error sign TX",error); return }
        
        // 10)  Send + get HASH
        do {
            let result = try await web3_infura.eth.send(tx)
            print("✅ Tx Hash:", result.hash)
        } catch {
            print("❌ Error sending:", error)
        }
        
    }
}
    // 1 Result - from eth-mainnet.alchemyapi: ❌ Error sending: clientError(code: 400)
    
    // 2 Result - infura Mainnet Web3:
    // ❌ Error sending: processingError(desc: "Method not found. Error code: -32601. The method eth_sendTransaction does not exist/is not available")

ZefsAl avatar May 02 '25 19:05 ZefsAl