SkillAgentSearch skills...

EtherWallet

以太坊钱包 web3swift lib、Generate Account、Import Account、ETH Transfer、ERC20 Transfer、Get ETH Balance、ERC20 Balance、Estimate Transaction Fee with Swift.

Install / Use

/learn @smithSophiav/EtherWallet
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

EtherWallet

EtherWallet is an iOS toolbelt for interaction with the Ethereum network.

language CocoaPods

For more specific usage, please refer to the demo

Swift Package Manager

dependencies: [
    .package(url: "https://github.com/smithSophiav/EtherWallet.git", .upToNextMajor(from: "1.1.6"))
]

Example usage in Swift Package Manager

import EtherWallet

Quick Start

  1. Create and setup (must be called before any other API; loads the JS bundle).
let etherWeb = EtherWeb()

// Async (recommended)
Task { @MainActor in
    let ready = await etherWeb.setup(showLog: false)
    if ready {
        // Call any EtherWeb API
    }
}

// Or with completion
etherWeb.setup(showLog: true) { success in
    if success {
        // Call any EtherWeb API
    }
}
  1. Call APIs — All methods have both completion-handler and async variants. Use async when you are in an async context (e.g. Task or async function).

API Reference

Wallet

| Method | Description | Returns | |--------|-------------|--------| | generateAccount(password: String?) | Create new wallet (mnemonic + derived key). Optional password returns keystore in result. | [String: Any]? → address, privateKey, mnemonic, keystore? | | importAccountFromPrivateKey(privateKey:) | Import from hex private key. | address, privateKey | | importAccountFromMnemonic(mnemonic:) | Import from 12/24-word mnemonic (first account). | address, privateKey, mnemonic | | importAccountFromKeystore(json:password:) | Import from Keystore JSON string. | address, privateKey, keystore | | privateKeyToKeystore(privateKey:password:) | Encrypt private key to Keystore JSON (light PBKDF2). | Keystore JSON string or nil | | getAddressFromPrivateKey(privateKey:) | Get Ethereum address from private key. | Address string or nil |

Example

// Generate wallet (optional password for keystore)
let result = await etherWeb.generateAccount(password: "myPassword")
if let r = result {
    print(r["address"] as? String ?? "")
    print(r["privateKey"] as? String ?? "")
    print(r["keystore"] as? String ?? "")
}

// Import from mnemonic
let imported = await etherWeb.importAccountFromMnemonicAsync(mnemonic: "abandon abandon ...")

Sign & Verify Message (EIP-191)

| Method | Description | Returns | |--------|-------------|--------| | signMessage(privateKey:message:) | Sign message with private key (personal_sign). | Signature hex or nil | | verifyMessage(message:signature:) | Recover signer address from message + signature. | Recovered address or nil | | verifyMessageSignature(message:signature:expectedAddress:) | Check if signature was produced by expected address. | Bool |

Example

let signature = await etherWeb.signMessage(privateKey: pk, message: "Hello")
let recovered = await etherWeb.verifyMessage(message: "Hello", signature: signature ?? "")
let isValid = await etherWeb.verifyMessageSignature(message: "Hello", signature: sig, expectedAddress: "0x...")

Balance & Gas

All of these require rpcUrl and chainId from the caller (e.g. from your NetworkManager).

| Method | Description | Returns | |--------|-------------|--------| | getETHBalance(address:rpcUrl:chainId:) | Native ETH balance. | Human-readable ETH string or nil | | getERC20TokenBalance(tokenAddress:walletAddress:rpcUrl:chainId:) | ERC20 balance. | Dict: balance, decimals | | getGasPrice(rpcUrl:chainId:) | Current gas price (legacy). | gasPriceWei, gasPriceGwei | | getSuggestedFees(rpcUrl:chainId:) | EIP-1559 style fees. | gasPrice?, maxFeePerGas?, maxPriorityFeePerGas? |

Example

let rpcUrl = NetworkManager.shared.currentRpcUrl   // your source of RPC URL
let chainId = NetworkManager.shared.currentChainId

let ethBalance = await etherWeb.getETHBalance(address: "0x...", rpcUrl: rpcUrl, chainId: chainId)
let tokenBalance = await etherWeb.getERC20TokenBalance(
    tokenAddress: "0x...", walletAddress: "0x...", rpcUrl: rpcUrl, chainId: chainId
)
let gasPrice = await etherWeb.getGasPrice(rpcUrl: rpcUrl, chainId: chainId)
let fees = await etherWeb.getSuggestedFees(rpcUrl: rpcUrl, chainId: chainId)

Transfer

| Method | Description | Returns | |--------|-------------|--------| | getAddressFromPrivateKey(privateKey:) | Resolve address from private key (e.g. for estimate). | Address string or nil | | estimateEthTransferGas(fromAddress:to:valueEth:rpcUrl:chainId:) | Estimate gas for ETH transfer. | gasLimit, gasPrice, estimatedFeeWei, estimatedFeeEth | | ethTransfer(privateKey:to:valueEth:gasLimit:gasPrice:maxFeePerGas:maxPriorityFeePerGas:rpcUrl:chainId:) | Send ETH. Gas params optional (pass nil to let provider decide). | hash, from, to | | estimateErc20TransferGas(fromAddress:tokenAddress:to:amountHuman:decimals:rpcUrl:chainId:) | Estimate gas for ERC20 transfer. | gasLimit, gasPrice, estimatedFeeWei, estimatedFeeEth | | erc20Transfer(privateKey:tokenAddress:to:amountHuman:decimals:gasLimit:gasPrice:maxFeePerGas:maxPriorityFeePerGas:rpcUrl:chainId:) | Send ERC20. Gas params optional. | hash, from, to |

Example

let rpcUrl = NetworkManager.shared.currentRpcUrl
let chainId = NetworkManager.shared.currentChainId

// 1) Estimate ETH transfer
let from = await etherWeb.getAddressFromPrivateKey(privateKey: privateKey)
let estimate = await etherWeb.estimateEthTransferGas(
    fromAddress: from!, to: "0x...", valueEth: "0.01", rpcUrl: rpcUrl, chainId: chainId
)
let gasLimit = estimate?["gasLimit"] as? String
let gasPrice = estimate?["gasPrice"] as? String

// 2) Send ETH (optionally use estimated gas)
let tx = await etherWeb.ethTransfer(
    privateKey: privateKey, to: "0x...", valueEth: "0.01",
    gasLimit: gasLimit, gasPrice: gasPrice, maxFeePerGas: nil, maxPriorityFeePerGas: nil,
    rpcUrl: rpcUrl, chainId: chainId
)
let txHash = tx?["hash"] as? String

// ERC20 transfer
let erc20Tx = await etherWeb.erc20Transfer(
    privateKey: pk, tokenAddress: "0x...", to: "0x...", amountHuman: "10", decimals: 18,
    gasLimit: nil, gasPrice: nil, maxFeePerGas: nil, maxPriorityFeePerGas: nil,
    rpcUrl: rpcUrl, chainId: chainId
)

Conventions

  • MainActor: EtherWeb is @MainActor; call its methods from the main thread or from Swift concurrency (e.g. Task { @MainActor in ... }).
  • rpcUrl + chainId: For balance, gas, and transfer APIs you must supply the current chain's RPC URL and chain ID. EtherWeb does not store or choose networks; your app does (e.g. via a NetworkManager).
  • Async vs completion: Prefer the async overloads when writing async Swift code; use the completion versions from callback-based code.
  • Errors: Failed bridge calls typically return nil (or false for verifyMessageSignature). Ensure your JS bundle returns { state: true, result } on success and { state: false, error } on failure so the native side can distinguish.

License

EtherWallet is released under the MIT license. See LICENSE for details.

Related Skills

View on GitHub
GitHub Stars29
CategoryDevelopment
Updated1mo ago
Forks0

Languages

Swift

Security Score

95/100

Audited on Feb 19, 2026

No findings