# Manage Wallets

An agent needs a secure persistent place to store their cryptographic keys, credentials, protocol data and more. Before using most agent APIs, a wallet must be created and opened for usage. The important wallet management functionality is highlighted below.

Note that all "wallet" functionality is found under the agent's `WalletModule` implementation (within `agent.wallet`).

## Creating a Wallet

To effectively manage a user's DI data, a wallet must be created to securely store that data.

Each wallet must be created with a unique `id` along with a secure `passphrase`. To create a new wallet on the user's device, call the `wallet.create` method with those parameters. The chosen unique `id` should be remembered by consuming apps, as it is required to [open the wallet](#opening-a-wallet).

Configurable `id`s allow for developers to create "multi-wallet" applications if desired.

The chosen passphrase is used to encrypt the wallet's data, and as such, should be a secure value. Passphrase's also cannot be changed after wallet creation. Due to these reasons, an application may wish to consider a flow such as:&#x20;

1. Randomly generate a secure permanent passphrase for the wallet, &#x20;
2. Store this passphrase in the app's secure device storage,&#x20;
3. add some "user friendly" authentication to the app to protect access to the passphrase: e.g. biometrics etc.

{% tabs %}
{% tab title="Swift" %}

<pre class="language-swift"><code class="lang-swift"><strong>let id: String // the unique id for the wallet
</strong><strong>let passphrase: String // the secure passphrase used to open the wallet
</strong><strong>let agent: SudoDIEdgeAgent // the instantiated agent
</strong><strong>
</strong><strong>let walletConfiguration = WalletConfiguration(id: id, passphrase: passphrase)
</strong>do {
    try await agent.wallet.create(walletConfiguration: walletConfiguration)
} catch {
    // handle error
}
</code></pre>

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
val id: String // Unique wallet identifier
val passphrase: String // Secure passphrase
val agent: SudoDIEdgeAgent // Instantiated agent

launch {
    try {
        val walletConfig = WalletConfiguration(id, passphrase)
        agent.wallet.create(walletConfig)
    } catch (e: WalletModule.CreateException) {
        // Handle exception
    }
}
```

{% endtab %}
{% endtabs %}

## Opening a Wallet

To access and manage the data within a wallet, it must first be opened successfully by calling `agent.open` with the correct `id` and `passphrase` used when the wallet was created. If the wallet is not successfully opened, an exception/error will be thrown.

{% tabs %}
{% tab title="Swift" %}

```swift
let id: String // the existing id of the wallet
let passphrase: String // the existing passphrase used to open the wallet
let agent: SudoDIEdgeAgent // the instantiated agent

let walletConfiguration = WalletConfiguration(id: id, passphrase: passphrase)
do {
    try await agent.wallet.open(walletConfiguration: walletConfiguration)
} catch {
    // handle error
}
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
val id: String // Existing wallet identifier
val passphrase: String // Secure passphrase
val agent: SudoDIEdgeAgent // Instantiated agent

launch {
    try {
        val walletConfig = WalletConfiguration(id, passphrase)
        agent.wallet.open(walletConfig)
    } catch (e: WalletModule.OpenException) {
        // Handle exception
    }
}
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
An instance of `SudoDIEdgeAgent` can only have 1 wallet open at a time. To "switch wallets", close the current wallet and re-open a different one.
{% endhint %}

## Closing a Wallet

The currently open wallet can be closed by calling `wallet.close`. Closing a wallet will disallow read and write operations to the wallet until it is subsequently opened again. A wallet may be deleted once closed via the `wallet.delete` API.&#x20;

{% tabs %}
{% tab title="Swift" %}

```swift
let agent: SudoDIEdgeAgent // the instantiated agent

do {
    try await agent.wallet.close()
} catch {
    // handle error
}
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
val agent: SudoDIEdgeAgent // Instantiated agent

launch {
    try {
        agent.wallet.close()
    } catch (e: WalletModule.CloseException) {
        // Handle exception
    }
}
```

{% endtab %}
{% endtabs %}

## Deleting a Wallet

To delete a wallet from storage on the user's device, call `wallet.delete` with the `id` and `passphrase` that was used to originally create the wallet. Deleting the wallet will erase all of the user's DI data within that wallet. The wallet must be closed before deleting it.

{% tabs %}
{% tab title="Swift" %}

```swift
let id: String // the existing id of the wallet
let passphrase: String // the existing passphrase used to open the wallet
let agent: SudoDIEdgeAgent // the instantiated agent

do {
    let walletConfiguration = WalletConfiguration(id: id, passphrase: passphrase)
    try await agent.wallet.delete(walletConfiguration: walletConfiguration)
} catch {
    // handle error
}
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
val id: String = // Existing wallet identifier
val passphrase: String // Secure passphrase
val agent: SudoDIEdgeAgent = // Instantiated agent

launch {
    try {
        val walletConfig = WalletConfiguration(id, passphrase)
        agent.wallet.delete(walletConfig)
    } catch (e: WalletModule.DeleteException) {
        // Handle exception
    }
}
```

{% endtab %}
{% endtabs %}

## Check if a Wallet Exists

The existence of a wallet identified by `id` can be checked using `wallet.exists`.

{% tabs %}
{% tab title="Swift" %}

```swift
let id: String // the id of the wallet
let agent: SudoDIEdgeAgent // the instantiated agent

do {
    let exists = try await agent.wallet.exists(walletId: id)
    if exists {
        // handle wallet existing
    } else {
        // handle wallet not existing
    }
} catch {
    // handle error
}
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
val id: String = // Wallet identifier
val agent: SudoDIEdgeAgent = // Instantiated agent

launch {
    try {
        val exists: Boolean = agent.wallet.exists(id)
        if (exists) {
            // Handle wallet existing
        } else {
            // Handle wallet not existing
        }
    } catch (e: WalletModule.ExistsException) {
        // Handle/notify user of exception
    }
}
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
Note that all `wallet` module operations are performed within the environment of the `storageDirectory` selected during [agent configuration](/guides/decentralized-identity/decentralized-identity/edge-agent-sdk/agent-management.md#configuration). As such, custom behavior with changing `storageDirectory` may lead to wallets no longer "existing" according to the API (until the original `storageDirectory` is chosen again).
{% endhint %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.sudoplatform.com/guides/decentralized-identity/decentralized-identity/edge-agent-sdk/manage-wallets.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
