---
title: "Sonr Vault Plugin with Dexie.js Persistence"
description: "Comprehensive guide to using the Sonr Vault Plugin with persistent storage and multi-account support"
sidebarTitle: "Vault Plugin Usage"
icon: "lock"
---

# Sonr Vault Plugin: Persistent Storage and Account Management

## Overview

The Sonr Vault Plugin provides a powerful, secure, and flexible way to manage cryptographic operations with persistent storage using Dexie.js and IndexedDB. This guide will walk you through the plugin's features, setup, and advanced usage patterns.

<Callout type="info">
  **Key Features**
  - 🔐 Account-based database separation
  - 💾 Automatic token persistence
  - 🔄 Cross-browser IndexedDB support
  - ⚡ Backward compatibility
  - 🧹 Automatic token and session cleanup
</Callout>

## Installation

Install the Sonr Vault Plugin in your project:

<CodeGroup>
```bash npm
npm install @sonr.io/es
```

```bash yarn
yarn add @sonr.io/es
```

```bash pnpm
pnpm add @sonr.io/es
```
</CodeGroup>

## Basic Usage

### Without Persistence (Default)

The vault plugin is designed to be backward compatible. By default, it operates without persistent storage:

```typescript
import { createVaultClient } from '@sonr.io/es/plugins/vault';

// Create a vault client without persistence
const vault = createVaultClient();

// Initialize the vault
await vault.initialize();

// Create tokens and perform operations as before
const token = await vault.newOriginToken({
  audience_did: 'did:example:123',
});
```

### With Persistence Enabled

Enable persistent storage with a simple configuration:

```typescript
import { createVaultClient } from '@sonr.io/es/plugins/vault';

// Create a vault client with persistence
const vault = createVaultClient({
  enablePersistence: true,
  autoCleanup: true,      // Automatically clean up expired tokens
  cleanupInterval: 3600000 // Cleanup every hour (in milliseconds)
});

// Initialize with an account address for database separation
const accountAddress = 'sonr1abc123...';
await vault.initialize('/plugin.wasm', accountAddress);

// Tokens are now automatically persisted
const token = await vault.newOriginToken({
  audience_did: 'did:example:123',
});
```

## Advanced Features

### Multi-Account Support

Seamlessly switch between accounts and manage their individual databases:

```typescript
// Switch to a different account
await vault.switchAccount('sonr1account2');

// List all accounts with persisted data
const accounts = await vault.listPersistedAccounts();

// Remove an account's data
await vault.removeAccount('sonr1account1');
```

### Token Management

Manually manage persisted tokens:

```typescript
// Get all saved tokens
const tokens = await vault.getPersistedTokens();

// Save a specific token
await vault.saveToken({
  token: 'eyJ...',
  issuer: 'did:sonr:example',
  address: 'sonr1abc...',
});

// Remove expired tokens
await vault.removeExpiredTokens();
```

### State Management

Control vault state persistence:

```typescript
// Manually save current state
await vault.persistState();

// Load persisted state
const state = await vault.loadPersistedState();

// Clear all persisted data for the current account
await vault.clearPersistedState();
```

## Storage Management

Use the `VaultStorageManager` for advanced storage operations:

```typescript
import { VaultStorageManager } from '@sonr.io/es/plugins/vault';

const storageManager = new VaultStorageManager({
  enablePersistence: true,
});

// Request persistent storage
const isPersisted = await storageManager.requestPersistentStorage();

// Check storage status and estimate
const status = await storageManager.tryPersistWithoutPromptingUser();
const estimate = await storageManager.getStorageEstimate();
```

## Configuration Options

Customize the vault's storage behavior:

<TypeTable
  columns={[
    { name: 'enablePersistence', type: 'boolean', description: 'Enable IndexedDB storage' },
    { name: 'storageQuotaRequest', type: 'number', description: 'Storage quota to request in bytes' },
    { name: 'autoCleanup', type: 'boolean', description: 'Enable automatic token/session cleanup' },
    { name: 'cleanupInterval', type: 'number', description: 'Cleanup interval in milliseconds' }
  ]}
/>

## Browser Compatibility

The Vault Plugin works with most modern browsers:

<Table>
  <TableHead>
    <TableRow>
      <TableCell>Browser</TableCell>
      <TableCell>Minimum Version</TableCell>
    </TableRow>
  </TableHead>
  <TableBody>
    <TableRow>
      <TableCell>Chrome/Edge</TableCell>
      <TableCell>23+</TableCell>
    </TableRow>
    <TableRow>
      <TableCell>Firefox</TableCell>
      <TableCell>16+</TableCell>
    </TableRow>
    <TableRow>
      <TableCell>Safari</TableCell>
      <TableCell>10+</TableCell>
    </TableRow>
    <TableRow>
      <TableCell>Opera</TableCell>
      <TableCell>15+</TableCell>
    </TableRow>
    <TableRow>
      <TableCell>iOS Safari</TableCell>
      <TableCell>10+</TableCell>
    </TableRow>
    <TableRow>
      <TableCell>Chrome for Android</TableCell>
      <TableCell>All versions</TableCell>
    </TableRow>
  </TableBody>
</Table>

## Storage Limits

Storage availability varies by browser:

<Table>
  <TableHead>
    <TableRow>
      <TableCell>Browser</TableCell>
      <TableCell>Storage Limit</TableCell>
    </TableRow>
  </TableHead>
  <TableBody>
    <TableRow>
      <TableCell>Chrome/Edge</TableCell>
      <TableCell>60% of total disk space</TableCell>
    </TableRow>
    <TableRow>
      <TableCell>Firefox</TableCell>
      <TableCell>50% of free disk space</TableCell>
    </TableRow>
    <TableRow>
      <TableCell>Safari</TableCell>
      <TableCell>Starts at 1GB, can request more</TableCell>
    </TableRow>
    <TableRow>
      <TableCell>Mobile Browsers</TableCell>
      <TableCell>Varies by device</TableCell>
    </TableRow>
  </TableBody>
</Table>

## Security Considerations

<Callout type="warning">
  - Databases are isolated by account address
  - No private keys or sensitive cryptographic material are stored
  - Only UCAN tokens and metadata are persisted
  - Always use HTTPS in production
  - Consider encrypting sensitive data before storage
</Callout>

## Troubleshooting

### Storage Not Persisting

1. Verify you're running on HTTPS
2. Check that IndexedDB is enabled in browser settings
3. Confirm available storage quota
4. Explicitly request persistent storage

```typescript
try {
  await vault.initialize('/plugin.wasm', accountAddress);
} catch (error) {
  if (error.code === 'VAULT_NOT_INITIALIZED') {
    // Handle initialization error
  }
}
```

## Migration Guide

To migrate from non-persistent to persistent storage:

```typescript
// Before (non-persistent)
const vault = createVaultClient();
await vault.initialize();

// After (with persistence)
const vault = createVaultClient({
  enablePersistence: true,
});
await vault.initialize('/plugin.wasm', accountAddress);
```

<Callout type="success">
  **No other code changes are required!** All existing methods work the same way.
</Callout>