ConfigStore
The config storage layer defines how verification configurations are persisted and retrieved on the backend. These configurations represent the same disclosure/verification rules that the frontend and smart contracts enforce. Keeping them consistent is critical.
This @selfxyz/core
library exposes an interface (IConfigStorage
) and two default implementations (DefaultConfigStore
, InMemoryConfigStore
).
IConfigStorage
IConfigStorage
export interface IConfigStorage {
getConfig(id: string): Promise<VerificationConfig>
setConfig(id: string, config: VerificationConfig): Promise<boolean>
getActionId(userIdentifier: string, data: string): Promise<string>
}
Methods
getConfig(id)
Returns the
VerificationConfig
associated with a given id.This id is typically the
configId
referenced by your contract/backend/frontend.
setConfig(id, config)
Stores a new verification config under the given id.
Returns
true
if an existing config was replaced,false
if it was newly set.
getActionId(userIdentifier, data)
Computes or retrieves an action id based on user context data from the frontend.
This action id links user activity with a registered config and is later used by
getConfig(id)
DefaultConfigStore
A simple implementation that always returns the same config regardless of id.
export class DefaultConfigStore implements IConfigStorage {
constructor(private config: VerificationConfig) {}
//other methods
}
Example
const defaultConfigStore = new DefaultConfigStore({
minimumAge: 18,
excludedCountries: ['US', 'CA'],
ofac: true,
});
InMemoryConfigStore
A more flexible implementation that can hold multiple configs in memory.
export class InMemoryConfigStore implements IConfigStorage {
private configs: Map<string, VerificationConfig> = new Map();
private getActionIdFunc: IConfigStorage['getActionId'];
constructor(getActionIdFunc: IConfigStorage['getActionId']) {
this.getActionIdFunc = getActionIdFunc;
}
//other methods
}
Example
const inMemoryHandler = async (userIdentifier: string, userDefinedData: string) => {
return userDefinedData === 'high_value' ? 'strict' : 'standard';
};
const inMemory = new InMemoryConfigStore(inMemoryHandler);
inMemory.setConfig('strict', {
minimumAge: 18,
excludedCountries: ['USA', 'CAN'],
ofac: true,
});
inMemory.setConfig('standard', {
minimumAge: 18,
excludedCountries: ['USA', 'CAN'],
ofac: true,
});
Use cases:
Backends that need to manage multiple verification configurations at once.
Scenarios where action ids must be computed dynamically per user.
Good for prototyping before connecting to a persistent store (DB, KV, etc.).
Custom Implementations
Here's an example of a KVConfigStore
that is used in the playground.
import {
IConfigStorage,
VerificationConfig,
} from "@selfxyz/core";
import { Redis } from "@upstash/redis";
export class KVConfigStore implements IConfigStorage {
private redis: Redis;
constructor(url: string, token: string) {
this.redis = new Redis({
url: url,
token: token,
});
}
async getActionId(userIdentifier: string, data: string): Promise<string> {
return userIdentifier;
}
async setConfig(id: string, config: VerificationConfig): Promise<boolean> {
await this.redis.set(id, JSON.stringify(config));
return true;
}
async getConfig(id: string): Promise<VerificationConfig> {
const config = (await this.redis.get(id)) as VerificationConfig;
return config;
}
}
Integration with Frontend
The userDefinedData
parameter in the frontend's SelfAppBuilder
is passed to your getActionId
method:
// Frontend
const selfApp = new SelfAppBuilder({
// ... other config
version: 2,
userDefinedData: Buffer.from(JSON.stringify({
action: "high_value_transaction",
amount: 50000,
merchant: "merchant_123"
})).toString('hex'),
// ...
}).build();
// Backend - getActionId receives this data
async getActionId(userIdentifier: string, userDefinedData: string): Promise<string> {
const data = JSON.parse(Buffer.from(userDefinedData, 'hex').toString());
if (data.action === 'high_value_transaction' && data.amount > 10000) {
return 'strict_verification';
}
return 'standard_verification';
}
Summary
IConfigStorage
defines a contract for working with verification configs.The library ships with
DefaultConfigStore
(static) andInMemoryConfigStore
(multi‑config, dynamic).Backend verifiers (like
SelfBackendVerifier
) depend onIConfigStorage
to fetch configs and action ids.You can plug in your own storage backend by implementing the same interface.
Last updated