# Ethereum provider

The Ethereum provider is your primary interface to the blockchain from an embedded wallet. It is a standard [EIP-1193 provider](https://eips.ethereum.org/EIPS/eip-1193): you make familiar JSON-RPC calls like `eth_sendTransaction`, `personal_sign`, or `eth_chainId`, and the embedded wallet handles signing securely inside the SDK — the private key never leaves Openfort's signer.

Most wallet actions on iOS go through this provider, including [sending transactions](/docs/products/embedded-wallet/swift/wallet/send) and [switching chains](/docs/products/embedded-wallet/swift/wallet/switch-chains).

:::note
Get the provider only after the wallet is [`.ready`](/docs/products/embedded-wallet/swift/wallet/state). Requesting it earlier returns a provider that can't reach the embedded wallet.
:::

## Get the provider

Call `getEthereumProvider`. Pass a sponsorship `policy` if you want Openfort to pay gas; omit it for a self-paid flow:

```swift
do {
    guard let provider = try await OFSDK.shared.getEthereumProvider(
        params: OFGetEthereumProviderParams(policy: "YOUR_POLICY_ID") // optional — omit to pay your own gas
    ) else {
        print("Provider not available")
        return
    }
    // Use `provider` to make JSON-RPC calls.
} catch {
    print("Error getting Ethereum provider: \(error.localizedDescription)")
}
```

## Make requests

The provider exposes an `async` `request(method:params:)` that returns the result as a `String` — a transaction hash for `eth_sendTransaction`, a hex value for `eth_call` / `eth_chainId`, or a JSON string for object results. This is how you call the provider; the SDK has no third-party Web3 dependency.

```swift
// Read the current chain id (hex string, e.g. "0x14a34")
let chainId = try await provider.request(method: "eth_chainId", params: [])

// Send a transaction — returns the transaction hash
let txHash = try await provider.request(
    method: "eth_sendTransaction",
    params: [[
        "from": fromAddress,
        "to": toAddress,
        "value": "0x0",
        "data": "0x", // ABI-encoded calldata for a contract, or "0x" for a plain transfer
    ]]
)

// Read-only contract call (returns hex)
let result = try await provider.request(
    method: "eth_call",
    params: [["to": tokenAddress, "data": balanceOfCalldata], "latest"]
)
```

`params` is `[Any]` and mirrors the JSON-RPC shape of each method: for `eth_sendTransaction` it's an array containing one transaction object; for `eth_chainId` it's empty.

:::tip
On error the call throws an `OFProviderError` whose `localizedDescription` carries the underlying provider message — wrap calls in `do/catch` and surface that to the user or your logs.
:::

## Parameters

```swift
public struct OFGetEthereumProviderParams: OFCodableSendable {
    public let policy: String?            // sponsorship policy id for gasless tx
    public let chains: [Int: String]?     // chainId -> RPC URL overrides
    public let providerInfo: ProviderInfo?
    public let announceProvider: Bool?

    public struct ProviderInfo: OFCodableSendable {
        public let icon: String?
        public let name: String?
        public let rdns: String?
    }
}
// Build provider info as: OFGetEthereumProviderParams.ProviderInfo(name: "My App")
```

## Returns

`getEthereumProvider` returns an optional `OpenfortEIP1193Web3Provider`.

## Next steps

* [Send a transaction](/docs/products/embedded-wallet/swift/wallet/send)
* [Sponsored (gasless) transactions](/docs/products/embedded-wallet/swift/wallet/eip-7702)
* [Switch chains](/docs/products/embedded-wallet/swift/wallet/switch-chains)
