> ## Documentation Index
> Fetch the complete documentation index at: https://docs.turnkey.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Using wallets

> Learn how to create and manage wallets in your Swift app using the Turnkey Swift SDK.

## Overview

The Turnkey Swift SDK provides a straightforward way to create and manage wallets in your Swift application. You can create wallets, derive accounts, import/export, and refresh wallet state from `TurnkeyContext`.

Before you start, make sure you're familiar with [Wallets](/concepts/wallets) and [Wallet Accounts](/concepts/wallets#accounts).

## Creation

There are two ways to create wallets and accounts:

* During signup (sub-organization creation): Configure default wallet/accounts in your signup parameters so users get a wallet at account creation time. See [Sub-organization customization](/sdks/swift/sub-organization-customization) for how to set `CreateSubOrgParams` globally or per auth method.
* After authentication (active session): Create wallets programmatically using the `TurnkeyContext` once the user is authenticated.

### Wallet

Create a wallet with one Ethereum account using an active session:

```swift CreateWalletButton.swift focus={2,5,11-22} theme={"system"}
import SwiftUI
import TurnkeySwift

struct CreateWalletButton: View {
  @EnvironmentObject private var turnkey: TurnkeyContext

  var body: some View {
    Button("Create Wallet") {
      Task {
        do {
          let accounts: [WalletAccountParams] = [
            WalletAccountParams(
              addressFormat: .address_format_ethereum,
              curve: .curve_secp256k1,
              path: "m/44'/60'/0'/0/0",
              pathFormat: .path_format_bip32
            )
          ]
          try await turnkey.createWallet(
            walletName: "My New Wallet",
            accounts: accounts
          )
        } catch {
          print("Error creating wallet:", error)
        }
      }
    }
  }
}
```

### Wallet accounts

You can derive additional addresses for an existing wallet using the HTTP client:

```swift theme={"system"}
import TurnkeyHttp
import TurnkeyTypes
import TurnkeySwift

guard
  let client = TurnkeyContext.shared.client,
  let orgId = TurnkeyContext.shared.session?.organizationId
else { return }

let newAccounts: [WalletAccountParams] = [
  WalletAccountParams(
    addressFormat: .address_format_ethereum,
    curve: .curve_secp256k1,
    path: "m/44'/60'/0'/0/1",
    pathFormat: .path_format_bip32
  )
]

_ = try await client.createWalletAccounts(TCreateWalletAccountsBody(
  organizationId: orgId,
  accounts: newAccounts,
  walletId: "<wallet_id_here>"
))
```

### Private keys

Private keys are typically created when creating wallet accounts or by importing existing key material. See Importing → Private key.

## Listing wallets in the UI

The `TurnkeyContext` maintains `wallets` for the active session. You can render them in your views:

```swift theme={"system"}
import SwiftUI
import TurnkeySwift

struct WalletList: View {
  @EnvironmentObject private var turnkey: TurnkeyContext

  var body: some View {
    List(turnkey.wallets, id: \.walletId) { wallet in
      VStack(alignment: .leading) {
        Text(wallet.walletName)
        Text(wallet.walletId).font(.caption).foregroundColor(.gray)
      }
    }
  }
}
```

## Refreshing wallets

Call `refreshWallets()` to re-fetch wallets and accounts for the current session:

```swift theme={"system"}
Task {
  try? await turnkey.refreshWallets()
}
```

## Exporting

The Swift SDK lets you securely import/export wallets, accounts, and private keys. You can return decrypted values for developer workflows or handle encrypted bundles explicitly.

### Wallet

Default: decrypt locally and return the mnemonic (developer-friendly).

```swift theme={"system"}
import TurnkeySwift

let mnemonic = try await turnkey.exportWallet(walletId: "<wallet_id>")
// Do not display secrets in production UIs
```

### Wallet account

```swift theme={"system"}
import TurnkeyHttp
import TurnkeyCrypto
import TurnkeySwift

let (targetPublicKey, _, _) = TurnkeyCrypto.generateP256KeyPair()

guard
  let client = TurnkeyContext.shared.client,
  let orgId = TurnkeyContext.shared.session?.organizationId
else { return }

let resp = try await client.exportWalletAccount(TExportWalletAccountBody(
  organizationId: orgId,
  address: "<wallet_account_address>",
  targetPublicKey: targetPublicKey
))

let exportBundle = resp.exportBundle
```

### Private key

```swift theme={"system"}
import TurnkeyHttp
import TurnkeyCrypto
import TurnkeySwift

let (targetPublicKey, _, _) = TurnkeyCrypto.generateP256KeyPair()

guard
  let client = TurnkeyContext.shared.client,
  let orgId = TurnkeyContext.shared.session?.organizationId
else { return }

let resp = try await client.exportPrivateKey(TExportPrivateKeyBody(
  organizationId: orgId,
  privateKeyId: "<private_key_id>",
  targetPublicKey: targetPublicKey
))

let exportBundle = resp.exportBundle
```

## Importing

### Wallet

Imports a wallet from a mnemonic and automatically refreshes local state.

```swift theme={"system"}
import TurnkeySwift

let accounts: [WalletAccountParams] = [
  WalletAccountParams(
    addressFormat: .address_format_ethereum,
    curve: .curve_secp256k1,
    path: "m/44'/60'/0'/0/0",
    pathFormat: .path_format_bip32
  )
]

let walletId = try await turnkey.importWallet(
  walletName: "Imported Wallet",
  mnemonic: "<mnemonic>",
  accounts: accounts
)
```

### Private key

Imports a private key from plaintext key material and automatically refreshes local state.

```swift theme={"system"}
import TurnkeyHttp
import TurnkeySwift

guard
  let client = TurnkeyContext.shared.client,
  let orgId = TurnkeyContext.shared.session?.organizationId
else { return }

let resp = try await client.importPrivateKey(TImportPrivateKeyBody(
  organizationId: orgId,
  privateKey: "<hex-or-base58-key>",
  privateKeyName: "My Key",
  addressFormats: [.address_format_ethereum]
))
let privateKeyId = resp.privateKeyId
```

## Deleting

<Note>
  If a wallet, wallet account, or private key has not been exported, you must
  either export it first or pass the `deleteWithoutExport: true` flag in the
  delete request.
</Note>

### Wallet

```swift theme={"system"}
import TurnkeyHttp
import TurnkeyTypes
import TurnkeySwift

guard
  let client = TurnkeyContext.shared.client,
  let orgId = TurnkeyContext.shared.session?.organizationId
else { return }

let deleteResp = try await client.deleteWallets(TDeleteWalletsBody(
  organizationId: orgId,
  deleteWithoutExport: true, // set to true if the wallet hasn't been exported
  walletIds: ["<wallet_id_1>", "<wallet_id_2>"]
))

let removedWalletIds = deleteResp.walletIds
```

### Wallet accounts

```swift theme={"system"}
import TurnkeyHttp
import TurnkeyTypes
import TurnkeySwift

guard
  let client = TurnkeyContext.shared.client,
  let orgId = TurnkeyContext.shared.session?.organizationId
else { return }

let deleteResp = try await client.deleteWalletAccounts(TDeleteWalletAccountsBody(
  organizationId: orgId,
  deleteWithoutExport: true, // set to true if the accounts haven't been exported
  walletAccountIds: ["<wallet_account_id_1>", "<wallet_account_id_2>"]
))

let removedAccountIds = deleteResp.walletAccountIds
```

### Private keys

```swift theme={"system"}
import TurnkeyHttp
import TurnkeyTypes
import TurnkeySwift

guard
  let client = TurnkeyContext.shared.client,
  let orgId = TurnkeyContext.shared.session?.organizationId
else { return }

let deleteResp = try await client.deletePrivateKeys(TDeletePrivateKeysBody(
  organizationId: orgId,
  deleteWithoutExport: true, // set to true if the keys haven't been exported
  privateKeyIds: ["<private_key_id_1>", "<private_key_id_2>"]
))

let removedKeyIds = deleteResp.privateKeyIds
```
