Aller au contenu principal

Storage API Reference

API reference for storage adapters and utilities.

GenericStringStorage

Base storage interface that all adapters must implement.

Interface

interface GenericStringStorage {
getItem(key: string): string | Promise<string | null> | null;
setItem(key: string, value: string): void | Promise<void>;
removeItem(key: string): void | Promise<void>;
}

Methods

getItem

Retrieve a value by key.

getItem(key: string): string | Promise<string | null> | null

Parameters:

  • key: Storage key

Returns:

  • Synchronously: string | null
  • Asynchronously: Promise<string | null>

Example:

const value = await storage.getItem('myKey');
if (value) {
const data = JSON.parse(value);
}

setItem

Store a value with a key.

setItem(key: string, value: string): void | Promise<void>

Parameters:

  • key: Storage key
  • value: String value to store

Returns:

  • Synchronously: void
  • Asynchronously: Promise<void>

Example:

await storage.setItem('myKey', JSON.stringify(data));

removeItem

Remove a value by key.

removeItem(key: string): void | Promise<void>

Parameters:

  • key: Storage key

Returns:

  • Synchronously: void
  • Asynchronously: Promise<void>

Example:

await storage.removeItem('myKey');

Built-in Adapters

GenericStringInMemoryStorage

In-memory storage adapter (session-only).

class GenericStringInMemoryStorage implements GenericStringStorage {
getItem(key: string): string | null;
setItem(key: string, value: string): void;
removeItem(key: string): void;
}

Example:

import { GenericStringInMemoryStorage } from '@fhevm/sdk';

const storage = new GenericStringInMemoryStorage();

storage.setItem('key', 'value');
const value = storage.getItem('key'); // "value"
storage.removeItem('key');

Characteristics:

  • Synchronous operations
  • Data lost on page refresh
  • Fast performance
  • Good for testing

Custom Implementations

LocalStorage Adapter

Browser localStorage implementation:

class LocalStorageAdapter implements GenericStringStorage {
getItem(key: string): string | null {
return localStorage.getItem(key);
}

setItem(key: string, value: string): void {
localStorage.setItem(key, value);
}

removeItem(key: string): void {
localStorage.removeItem(key);
}
}

AsyncStorage Adapter

React Native AsyncStorage implementation:

import AsyncStorage from '@react-native-async-storage/async-storage';

class AsyncStorageAdapter implements GenericStringStorage {
async getItem(key: string): Promise<string | null> {
return await AsyncStorage.getItem(key);
}

async setItem(key: string, value: string): Promise<void> {
await AsyncStorage.setItem(key, value);
}

async removeItem(key: string): Promise<void> {
await AsyncStorage.removeItem(key);
}
}

IndexedDB Adapter

IndexedDB implementation:

class IndexedDBStorage implements GenericStringStorage {
private db: IDBDatabase | null = null;

async init(): Promise<void> {
// Initialize database
}

async getItem(key: string): Promise<string | null> {
// Get from IndexedDB
}

async setItem(key: string, value: string): Promise<void> {
// Save to IndexedDB
}

async removeItem(key: string): Promise<void> {
// Remove from IndexedDB
}
}

See IndexedDB Storage for complete implementation.

Storage Keys

Key Format

Storage keys follow this pattern:

userAddress:contractHash

Example Keys

// Key for a signature
"0x1234567890123456789012345678901234567890:0xabcdef..."

// Key for cached decryption
"8009:0x1234...:0x5678...:0x9abc..."

Key Generation

Keys are automatically generated by the SDK:

class FhevmDecryptionSignatureStorageKey {
constructor(
instance: FhevmInstance,
contractAddresses: string[],
userAddress: string,
publicKey?: string
)

get key(): string // Returns generated key
}

Data Format

Decryption Signature

{
publicKey: "0x...",
privateKey: "0x...",
signature: "0x...",
startTimestamp: 1234567890,
durationDays: 365,
userAddress: "0x...",
contractAddresses: ["0x123...", "0x456..."],
eip712: { ... }
}

Cached Decryption

{
value: "100",
timestamp: 1234567890,
chainId: 8009,
account: "0x..."
}

Best Practices

1. Handle Async Storage

async function useStorage(storage: GenericStringStorage, key: string) {
// Always await async operations
const value = await storage.getItem(key);
if (value) {
return JSON.parse(value);
}
return null;
}

2. Error Handling

async function safeGet(storage: GenericStringStorage, key: string) {
try {
return await storage.getItem(key);
} catch (error) {
console.error('Storage error:', error);
return null;
}
}

3. Serialization

// Always serialize/deserialize
const data = { foo: 'bar' };

// Save
await storage.setItem(key, JSON.stringify(data));

// Load
const raw = await storage.getItem(key);
const parsed = raw ? JSON.parse(raw) : null;

4. Cleanup

async function cleanup(storage: GenericStringStorage, keys: string[]) {
await Promise.all(
keys.map(key => storage.removeItem(key))
);
}

Testing

Mock Storage

class MockStorage implements GenericStringStorage {
private data = new Map<string, string>();
public calls: any[] = [];

getItem(key: string): string | null {
this.calls.push({ method: 'getItem', args: [key] });
return this.data.get(key) || null;
}

setItem(key: string, value: string): void {
this.calls.push({ method: 'setItem', args: [key, value] });
this.data.set(key, value);
}

removeItem(key: string): void {
this.calls.push({ method: 'removeItem', args: [key] });
this.data.delete(key);
}

reset(): void {
this.data.clear();
this.calls = [];
}
}

Usage in Tests

describe('Storage', () => {
let storage: MockStorage;

beforeEach(() => {
storage = new MockStorage();
});

it('should store and retrieve values', () => {
storage.setItem('key', 'value');
expect(storage.getItem('key')).toBe('value');
expect(storage.calls).toHaveLength(2);
});

it('should remove values', () => {
storage.setItem('key', 'value');
storage.removeItem('key');
expect(storage.getItem('key')).toBeNull();
});
});

Next Steps