# Integrate Embedded Wallets with the Solana Blockchain in iOS

> Integrate Embedded Wallets with the Solana Blockchain in iOS | Embedded Wallets

While using the Embedded Wallets iOS SDK (formerly Web3Auth), you can retrieve the Ed25519 private key upon successful authentication. This private key can be used to derive the user's public address and interact with the [Solana](https://solana.org/) chain. We've highlighted a few methods here to get you started quickly.

:::note

The SDKs are now branded as MetaMask Embedded Wallet SDKs (formerly Web3Auth Plug and Play SDKs). Package names and APIs remain Web3Auth (for example, Web3Auth React SDK), and code snippets may reference `web3auth` identifiers.

:::

## Chain details for Solana

<Tabs
 defaultValue="mainnet"
  values={[
    { label: "Mainnet", value: "mainnet" },
    { label: "Testnet", value: "testnet" },
    { label: "Devnet", value: "devnet" },
  ]}
>
<TabItem value="mainnet">

- Chain Namespace: SOLANA
- Chain ID: 0x1
- Public RPC URL: `https://api.mainnet-beta.solana.com` (avoid public RPC in production; prefer managed services)
- Display Name: Solana Mainnet
- Block Explorer Link: `https://explorer.solana.com`
- Ticker: SOL
- Ticker Name: Solana
- Logo: https://images.toruswallet.io/solana.svg

</TabItem>

<TabItem value="testnet">

- Chain Namespace: SOLANA
- Chain ID: 0x2
- Public RPC URL: `https://api.testnet.solana.com` (avoid public RPC in production; prefer managed services)
- Display Name: Solana Testnet
- Block Explorer Link: `https://explorer.solana.com`
- Ticker: SOL
- Ticker Name: Solana
- Logo: https://images.toruswallet.io/solana.svg

</TabItem>

<TabItem value="devnet">

- Chain Namespace: SOLANA
- Chain ID: 0x3
- Public RPC URL: `https://api.devnet.solana.com` (avoid public RPC in production; prefer managed services)
- Display Name: Solana Devnet
- Block Explorer Link: `https://explorer.solana.com?cluster=devnet`
- Ticker: SOL
- Ticker Name: Solana
- Logo: https://images.toruswallet.io/solana.svg

</TabItem>
</Tabs>

## Installation

To interact with the Solana blockchain in iOS, you can use any Solana compatible SDK. Here, we're using [SolanaSwift](https://github.com/p2p-org/solana-swift) to demonstrate how to interact with Solana chain using Web3Auth.

<Tabs defaultValue = "spm"
  values={[
    { label: "Swift Package Manager", value: "spm", },
    { label: "CocoaPods", value: "cocoapods", },
  ]}
>

<TabItem value="spm">

To install `SolanaSwift` through Swift Package Manager, follow the below steps:

1. Open your project in Xcode, navigate to **File > Add Package Dependencies**.

2. When prompted, add the SolanaSwift SDK repository:

   ```sh
    https://github.com/p2p-org/solana-swift
   ```

   From the **Dependency Rule** dropdown, select **Exact Version** and enter **5.0.0** as the version.

Once finished, Xcode will automatically begin resolving and downloading your dependencies in the background.

</TabItem>

<TabItem value="cocoapods">

To install using CocoaPods, simply add the following line to your Podfile

```
pod 'SolanaSwift', '~> 5.0.0'
```

Once you have added SolanaSwift to Podfile, run the following command:

```bash
pod install
```

</TabItem>
</Tabs>

## Initialize

To Initialize the `JSONRPCAPIClient` we require a RPC URL. The `JSONRPCAPIClient` instance will provide a gateway & protocol to interact with Solana cluster while sending requests and receving response. For this example, we are using the RPC URL for Devnet-beta. To interact with Testnet or Mainnet, change the RPC URL.

### Initializing the Solana SDK

In the following code block, we'll create the `JSONRPCAPIClient` instance using the Devnet-beta RPC.

```swift

let endpoint = APIEndPoint(
    address: "https://api.devnet.solana.com",
    network: .devnet
)

// focus-next-line
let solanaJSONRPCClient = JSONRPCAPIClient(endpoint: endpoint)
```

### Initializing the Web3Auth SDK

In the following code block, we'll initialize the Web3Auth SDK and check whether the user has any Web3Auth session persisted or not. If the user is already authenticated, you can route them directly to home view, otherwise you can route them to login view for authentication purpose. For checking, if user is already authenticated, we can check whether `Web3Auth.state` is `nil` or not.

By default, the session is persisted for 1 day. You can modify it using `sessionTime` parameter during initialization.

:::note

The session can be persisted for up to 30 days max.

:::

```swift

// Initialize Web3Auth SDK
// focus-start
let web3Auth = await Web3Auth(
    W3AInitParams(
        clientId: "BPi5PB_UiIZ-cPz1GtV5i1I2iOSOHuimiXBI0e-Oe_u6X3oVAbCiAZOTEBtTXw4tsluTITPqA8zMsfxIKMjiqNQ",
        network: Network.sapphire_mainnet,
        redirectUrl: "com.w3a.ios-solana-example"
    )
)
// focus-end

// Check whether state is nil or not for user authentication status.
let isUserAuthenticated = web3Auth.state != nil

// Customize your logic to perform operations or navigation
```

## Get account

We can use `getEd25519PrivKey` method in Web3Auth to retrive the priavte key for the Solana ecosystem. In the following code block, we'll use the Ed25519 private key to retive user's public address by creating `KeyPair`. The `KeyPair` struct from `SolanaSwift` SDK once created can be used to sign the Solana transactions.

```swift
let ed25519PrivateKey = web3Auth.getEd25519PrivKey()
let keyPair = try KeyPair(secretKey: Data(hex: ed25519PrivateKey))

// focus-next-line
let userAccount = keyPair.publicKey.base58EncodedString
```

## Get User balance

Once we have retrived userAccount, we can use it to fetch user balance. We'll use `getBalance` method from `JSONRPCAPIClient` instance to interact with Solana cluster and fetch user balance. The response of `getBalance` is UInt64, we will need to divide it by 10^9, because Solana's token decimals is 9. To help us with the calculation, the SDK also provides a `convertToBalance` function.

```swift
// focus-start
let balanceResponse = try await solanaJSONRPCClient.getBalance(
     // Use userAccount from above
    account: userAccount
)
// focus-end

// We are dividing the balance by 10^9, because Solana's
// token decimals is set to be 9;
let userBalance = return balanceResponse.convertToBalance(decimals: 9)
```

## Sign a transaction

Let's now go through how can we sign the transaction. In the below codeblock, we'll create a new function `perpareTransaction` which can be used to retrive the Base58 signature as well as broadcast transaction to the cluster. We'll use `BlockchainClient.prepareSendingNativeSOL` to create the transaction to self transfer 0.01 Sol and sign it. You can also checkout `prepareSendingSPLTokens`, and `prepareTransaction` for other types of transaction.

```swift
let blockchainClient = BlockchainClient(apiClient: solanaJSONRPCClient)

 private func perpareTransaction() async throws -> PreparedTransaction {
    let transaction = try await blockchainClient.prepareSendingNativeSOL(
        from: keyPair,
        to: "2idRaWFin4Zn5WY9or6XBhcoF6cyfDWSbJQ26jAtptxD",
        amount: 0.01.toLamport(decimals: 9)
    )

    return transaction
}
```

Once we have created `perpareTransaction` function, we'll use it to prepare, sign the transaction, and retrive Base58 signature. You can use `findSignature` to retrive the signature for the respective signer.

```swift
do {
    var transaction = try await perpareTransaction()
    try transaction.sign()
    let signature = try transaction.findSignature(publicKey: keyPair.publicKey)

    // Perform your action
} catch let error {
    // Perform error handling
}
```

## Send transaction

For the send transaction, we'll use `sendTransaction` method from `BlockchainClient` instance to broadcast the result of `perpareTransaction` to the cluster.

```swift
do {
    let transaction = try await perpareTransaction()
    let hash = try await blockchainClient.sendTransaction(preparedTransaction: transaction)

    // Perform your action
} catch let error {
    // Perform error handling
}
```
