> For the complete documentation index, see [llms.txt](/llms.txt).

# Integrate Embedded Wallets with the Shardeum Blockchain in iOS/Swift Applications

While using the Web3Auth iOS SDK, you get the private key within the user scope after successful authorization. This private key can be used to retrieve the user's address, and interact with [Shardeum](https://ethereum.org/) to make any blockchain calls. We have highlighted a few here for getting you started quickly on that.

## Chain details for Shardeum[​](#chain-details-for-shardeum "Direct link to Chain details for Shardeum")

- Testnet

- **Chain ID:** 0x1F92
- **Public RPC URL:** `https://atomium.shardeum.org`
- **Display Name:** Shardeum Atomium Testnet
- **Block Explorer Link:** `https://explorer-atomium.shardeum.org`
- **Ticker:** SHM
- **Ticker Name:** Shardeum

## Prerequisites[​](#prerequisites "Direct link to Prerequisites")

- Project is set up in the MetaMask Developer Dashboard
- Web3Auth is [integrated in your iOS app](/embedded-wallets/sdk/ios/)

## Installation[​](#installation "Direct link to Installation")

To interact with the Ethereum compatible blockchains in Swift, you can use any [EIP1193](https://eips.ethereum.org/EIPS/eip-1193) compatible package. Here, we're using [web3swift](https://github.com/argentlabs/web3.swift) to demonstrate how to make blockchain calls using it with Web3Auth.

To install the `web3swift` package, you have two options. You can either use Swift Package Manager or CocoaPods.

- Swift Package Manager
- CocoaPods

1. In Xcode, with your app project open, navigate to **File > Add Packages**.
2. When prompted, add the single-factor-auth-swift iOS SDK repository:  
```  
https://github.com/argentlabs/web3.swift  
```
3. When finished, Xcode will automatically begin resolving and downloading your dependencies in the background.

To install the Web3Auth SingleFactorAuth SDK using Cocoapods, follow the below steps:

1. Open the Podfile, and add the SingleFactorAuth pod:  
```  
pod 'web3.swift'  
```
2. Once added, use `pod install` command to download the dependency.

## Initialize[​](#initialize "Direct link to Initialize")

Initialize the `EthereumHttpClient` with the RPC URL and chain id of the network you want to connect to, to interact with the blockchain. To get the public RPC URL, and other details as chain id, see [ChainList](https://chainlist.org/).

```
import web3

let client = EthereumHttpClient(
    // Please avoid using public RPC URL in production, use services
    // like Infura.
    url: URL.init(string: rpcUrl)!,
    // Replace with the chain id of the network you want to connect to
    network: .custom(chainId)
)

```

## Get account[​](#get-account "Direct link to Get account")

Use the `EthereumAccount` class to retrieve the user's Ethereum address. This account can also be used to sign transactions and messages.

The package doesn't provides any direct way to consume the the private key and create an account. Hence, we'll create an extension for the `Web3AuthState` extending the `EthereumSingleKeyStorageProtocol` to retrieve the private key and create an account.

```
import web3
import Web3Auth

extension Web3AuthState: EthereumSingleKeyStorageProtocol {
    public func storePrivateKey(key: Data) throws {

    }

    public func loadPrivateKey() throws -> Data {
        guard let data = self.privKey?.web3.hexData else {
            throw PlaygroundError.decodingError
        }

        return data
    }
}

```

Once we have created the extension, we can use the Web3AuthState to create an `EthereumAccount`. Please note, that this assumes that the user has already logged in and the state is available.

```
import web3

// Use your existing Web3Auth instance
let web3authState = web3Auth.state!

let account = try EthereumAccount(keyStorage: web3authState)
let address = account.address

```

## Get balance[​](#get-balance "Direct link to Get balance")

Use the `EthereumClient.eth_getBalance` method to retrieve the balance of an Ethereum address.

The result we get from Web3Client is in wei, the smallest unit of ether. To convert wei to ether, divide by 10^18, where 18 denotes the decimals for wei.

```
import web3

let etherInWei = pow(Double(10), 18)

/// Convert Wei(BInt) unit to Ether(Decimal) unit
public func toEther(wei: Wei) -> Ether {
    guard let decimalWei = Double(wei.description) else {
        return 0
    }
    return decimalWei / etherInWei
}

let balanceResponse = try await client.eth_getBalance(
    // Use the address from previous step
    address: address,
    block: .Latest
)

let balance = toEther(wei: balanceResponse)

```

## Sign a message[​](#sign-a-message "Direct link to Sign a message")

To sign the message, you can use the `EthereumAccount.sign` method. The sign method takes in the data of the message, and returns the signature.

```
import web3

let message = "Hello World"
// Use the account from previous step
guard let data = message.data(using: .ascii) else {
    // throw error
}

let signature = try ethereumAccount.signMessage(message: data)

```

## Send transaction[​](#send-transaction "Direct link to Send transaction")

For signing and sending the transaction, we'll create helper methods to get the nonce, gas price, estimate the gas and send the transaction:

- nonce is the number of transactions sent from the sender's address
- gas price is the unit of account for the transaction
- gas limit is the maximum amount of gas that the sender is willing to pay for the transaction

The gas values are in ether. We'll also create a helper method to convert the amount to wei.

Once the transaction object is created, we'll estimate the gas and create a new transaction object with the gas limit. Finally, we'll send the transaction using `EthereumHttpClient.eth_sendRawTransaction` method and get the hash.

```
import web3

private let etherInWei = pow(Double(10), 18)

private func getNonce() async throws -> Int {
    let nonce = try await client.eth_getTransactionCount(address: account.address, block: .Latest)
    return nonce
}

private func getGasPrice() async throws -> BigUInt {
    return try await client.eth_gasPrice()
}

private func estimateGas(ethereumTransaction: EthereumTransaction) async throws -> BigUInt {
    return try await client.eth_estimateGas(ethereumTransaction)
}

public func toWei(ether: Ether) -> Wei {
    let wei = Wei(ether * etherInWei)
    return wei
}

let nonce = try await getNonce()
let gasPrice = try await getGasPrice()

// Convert the amount to Wei
let value = toWei(ether: Ether(floatLiteral: 0.001))

let ethereumTransaction = EthereumTransaction(
    // Use the account from previous step
    from: account.address,
    to: EthereumAddress.init(stringLiteral: "RECIPIENT_ADDRESS_IN_HEX_FORMAT"),
    value: value,
    // Empty data, 0x
    data: Data(),
    nonce: nonce,
    gasPrice: gasPrice,
    gasLimit: nil,
    // Use the chain id from previous step
    chainId: CHAIN_ID_IN_INTEGER
)

// Estimate the gas
let gasLimit = try await estimateGas(ethereumTransaction: ethereumTransaction)

let transaction = EthereumTransaction(
    // Use the account from previous step
    from: account.address,
    to: EthereumAddress.init(stringLiteral: "RECIPIENT_ADDRESS_IN_HEX_FORMAT"),
    value: value,
    // Empty data, 0x
    data: Data(),
    nonce: nonce,
    gasPrice: gasPrice,
    gasLimit: gasLimit,
    // Use the chain id from previous step
    chainId: CHAIN_ID_IN_INTEGER
)

// Use the account from previous step
let hash = try await client.eth_sendRawTransaction(transaction, withAccount: account)

```
