Address Derivation
MPC wallet generation, protocol selection, key share management, and wallet information retrieval
Address Derivation
The Nero MPC SDK creates wallets using either DKLS or Pedersen DKG protocols. The protocol you choose determines the wallet type, key generation method, and storage strategy.
Protocol Comparison
| Aspect | DKLS | Pedersen DKG |
|---|---|---|
| Parties | 2-party threshold ECDSA | Multi-party (typically 2+) |
| Wallet Type | EOA (Externally Owned Account) | Smart Wallet (ERC-4337) |
| Configuration | protocol: "dkls" | protocol: "pedersen" |
| Key Generation | DKLSClient.executeKeygen() | DKGClient.execute() |
| Storage Key | secretShare in DKLS storage | privateShare in KeyManager |
| Account Abstraction | No | Yes (via SimpleAccount) |
| Default | Yes (since v2.0) | Legacy option |
Wallet Generation
The primary wallet generation method is NeroMpcSDK.generateWallet(), which routes to the appropriate protocol-specific implementation based on the configured protocol.
const wallet = await sdk.generateWallet();
console.log("EOA Address:", wallet.eoaAddress);
console.log("Smart Wallet:", wallet.smartWalletAddress);
console.log("Public Key:", wallet.publicKey);WalletInfo Interface
interface WalletInfo {
eoaAddress: string;
smartWalletAddress?: string;
publicKey: string;
protocol: 'dkls' | 'pedersen';
chainId: number;
createdAt: Date;
}DKLS Wallet Generation
DKLS wallet generation uses a 2-party threshold ECDSA protocol coordinated via the backend API:
- Initialize keygen session on backend
- Execute protocol rounds with server
- Store client's key share in browser storage
- Derive wallet address from public key
DKLS Storage
| Storage Type | Use Case | Persistence |
|---|---|---|
IndexedDBStorage | Standard browser environment | Persistent across sessions |
MemoryStorage | Fallback or testing | Session-only (cleared on page refresh) |
Storage uses the storagePrefix from your SDK configuration (default: "nero").
function createDKLSStorage(config: SDKConfig): StorageAdapter {
if (indexedDBAvailable()) {
return new IndexedDBStorage(config.storagePrefix);
}
return new MemoryStorage(config.storagePrefix);
}Pedersen DKG Wallet Generation
Pedersen DKG uses a distributed key generation protocol with Verifiable Secret Sharing Scheme (VSSS) commitments:
- Initialize DKG session via API
- Exchange commitments and shares through WebSocket
- Verify VSSS commitments locally
- Store cryptographic material in
ClientKeyManager - Create
SmartWalletinstance
Key Share Data
interface KeyShareData {
privateShare: string; // Hex-encoded
publicShare: string; // Hex-encoded
commitments: string[]; // VSS commitments
threshold: number;
totalParties: number;
partyId: number;
}Smart Wallet Creation
const smartWallet = new SmartWallet({
keyShare: dkgResult.keyShare,
publicKey: dkgResult.publicKey,
chainId: config.chainId,
bundlerUrl: config.bundlerUrl,
paymasterUrl: config.paymasterUrl,
});Wallet Restoration on SDK Startup
When the SDK initializes with existing authentication tokens, it attempts to restore wallet state from stored key material:
async initializeWallet(): Promise<void> {
if (this._protocol === 'dkls') {
const address = await this.dklsStorage.get('wallet_address');
this._dklsWalletAddress = address;
} else {
const keyShare = await this.keyManager.getKeyShare();
if (keyShare) {
this._wallet = await this.createSmartWallet(keyShare);
}
}
this.emit('wallet_restored');
}Listing Wallets
Retrieve all wallets associated with the authenticated user across projects:
const wallets: WalletInfo[] = await sdk.listWallets();Key Material Access
The getKeyMaterial() method reconstructs the full private key on the client, enabling instant offline signing. This method is rate-limited.
const key: ReconstructedKey = await sdk.getKeyMaterial();Rate limiting:
- Default limit: 5 calls per hour
- Configurable per application
- Throws
RateLimitErrorwhen exceeded
State Machine Properties
| Property | Type | Description |
|---|---|---|
isAuthenticated | boolean | User is logged in with valid tokens |
hasWallet | boolean | Wallet generation complete and usable |
walletReady | boolean | Wallet loaded and initialization complete |
keyShareStored | boolean | Client key share persisted locally |
Error Handling
| Error | Cause | Recovery |
|---|---|---|
RECOVERY_REQUIRED | Client key share missing from storage | Call setupSelfCustodyRecovery() |
DKG_FAILED | Protocol rounds failed or timeout | Retry wallet generation |
INVALID_STATE | Wallet already exists | Call getWalletInfo() to retrieve |
NETWORK_ERROR | Backend unreachable | Check connection and retry |
try {
const wallet = await sdk.generateWallet();
} catch (error) {
if (error.code === 'RECOVERY_REQUIRED') {
await sdk.setupSelfCustodyRecovery();
} else if (error.code === 'DKG_FAILED') {
setTimeout(() => sdk.generateWallet(), 5000);
}
}