NERO
Wallets

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

AspectDKLSPedersen DKG
Parties2-party threshold ECDSAMulti-party (typically 2+)
Wallet TypeEOA (Externally Owned Account)Smart Wallet (ERC-4337)
Configurationprotocol: "dkls"protocol: "pedersen"
Key GenerationDKLSClient.executeKeygen()DKGClient.execute()
Storage KeysecretShare in DKLS storageprivateShare in KeyManager
Account AbstractionNoYes (via SimpleAccount)
DefaultYes (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:

  1. Initialize keygen session on backend
  2. Execute protocol rounds with server
  3. Store client's key share in browser storage
  4. Derive wallet address from public key

DKLS Storage

Storage TypeUse CasePersistence
IndexedDBStorageStandard browser environmentPersistent across sessions
MemoryStorageFallback or testingSession-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:

  1. Initialize DKG session via API
  2. Exchange commitments and shares through WebSocket
  3. Verify VSSS commitments locally
  4. Store cryptographic material in ClientKeyManager
  5. Create SmartWallet instance

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 RateLimitError when exceeded

State Machine Properties

PropertyTypeDescription
isAuthenticatedbooleanUser is logged in with valid tokens
hasWalletbooleanWallet generation complete and usable
walletReadybooleanWallet loaded and initialization complete
keyShareStoredbooleanClient key share persisted locally

Error Handling

ErrorCauseRecovery
RECOVERY_REQUIREDClient key share missing from storageCall setupSelfCustodyRecovery()
DKG_FAILEDProtocol rounds failed or timeoutRetry wallet generation
INVALID_STATEWallet already existsCall getWalletInfo() to retrieve
NETWORK_ERRORBackend unreachableCheck 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);
  }
}

On this page