@dcprotocol/core

The cryptographic foundation of DCP. Handles encryption, wallet management, storage, and budget enforcement.

Installation

npm install @dcprotocol/core

Overview

@dcprotocol/core is the foundational package that all other DCP packages depend on. It provides the core functionality for:

  • Cryptographic operations (encryption, key derivation, signing)
  • Wallet generation and management (Solana, Ethereum, Base)
  • SQLite-based encrypted storage
  • Budget enforcement and rate limiting
  • Session management and consent tracking
  • Audit logging
⚠️ Direct Usage Not Recommended
Unless you're building custom tooling or need low-level access, you should use one of the higher-level packages (@dcprotocol/cli, @dcprotocol/server, @dcprotocol/mcp, or @dcprotocol/client).

Main Modules

Crypto Engine

Implements XChaCha20-Poly1305 encryption and Argon2id key derivation:

import {
  generateKey,
  encrypt,
  decrypt,
  envelopeEncrypt,
  envelopeDecrypt,
  deriveKeyFromPassphrase,
  zeroize
} from '@dcprotocol/core';

// Generate master key
const masterKey = generateKey();

// Envelope encryption (two-layer)
const encrypted = envelopeEncrypt(data, masterKey);

// Decrypt
const decrypted = envelopeDecrypt(encrypted, masterKey);

// CRITICAL: Zeroize sensitive keys from memory
zeroize(masterKey);

Key Functions

FunctionPurpose
generateKey()Generate 256-bit random key
generateNonce()Generate 192-bit nonce for encryption
deriveKeyFromPassphrase(passphrase, salt)Derive key using Argon2id (64MB, 3 iterations)
encrypt(plaintext, key)XChaCha20-Poly1305 encryption
decrypt(ciphertext, nonce, key)XChaCha20-Poly1305 decryption
envelopeEncrypt(data, masterKey)Two-layer encryption (DEK + data)
envelopeDecrypt(encrypted, masterKey)Two-layer decryption
zeroize(buffer)Clear sensitive data from memory

Wallet Manager

Creates and manages blockchain wallets:

import {
  createWallet,
  signTransaction,
  signSolanaMessage,
  signEvmMessage,
  getPublicAddress
} from '@dcprotocol/core';

// Create Solana wallet
const { encrypted, info } = createWallet('solana', masterKey);
// info = { chain: 'solana', public_address: '5Yz...', operations: [...] }

// Sign Solana transaction
const result = signSolanaTransaction(
  encrypted,
  masterKey,
  unsignedTxBase64
);
// result = { signed_tx: '...', signature: '...', chain: 'solana' }

Supported Chains

ChainKey TypeOperations
SolanaEd25519sign_tx, sign_message, get_address
Ethereumsecp256k1sign_tx, sign_message, sign_typed_data, get_address
Basesecp256k1sign_tx, sign_message, sign_typed_data, get_address

Key Security Features

  • Private keys exist in plaintext for <5ms during signing
  • Immediate memory zeroization after use
  • No key export function (by design)
  • Envelope encryption for storage

Vault Storage

SQLite-based encrypted storage with keychain integration:

import { VaultStorage, getStorage } from '@dcprotocol/core';

// Get singleton storage instance
const storage = getStorage();

// Initialize vault
await storage.init(passphrase);

// Store encrypted record
await storage.storeRecord({
  scope: 'wallet:solana',
  itemType: 'WALLET_KEY',
  sensitivity: 'critical',
  encryptedPayload: encrypted,
  chain: 'solana',
  publicAddress: 'ABC123...'
});

// Read record
const record = await storage.getRecordByScope('wallet:solana');

// Create session
const session = await storage.createSession({
  agentName: 'my-trading-bot',
  grantedScopes: ['sign:solana'],
  consentMode: 'session'
});

Database Tables

  • vault_records - Encrypted wallets and data
  • sessions - Active agent sessions
  • pending_consents - Consent requests
  • spend_events - Transaction history
  • audit_events - Immutable operation log
  • config - Vault configuration

Budget Engine

Enforces spending limits and approval thresholds:

import { BudgetEngine, getBudgetEngine } from '@dcprotocol/core';

const budgetEngine = getBudgetEngine();

// Check if transaction is allowed
const check = await budgetEngine.checkBudget({
  chain: 'solana',
  amount: 1.5,
  currency: 'SOL',
  sessionId: 'session-123'
});

// check = {
//   allowed: true,
//   requiresApproval: false,  // Under auto-approve threshold
//   remainingDaily: 18.5,
//   remainingTx: 3.5
// }

Default Budget Limits

CurrencyPer TransactionDailyAuto-Approve Under
SOL5 SOL20 SOL2 SOL
ETH0.5 ETH1 ETH0.1 ETH
BASE_ETH0.2 ETH0.5 ETH0.05 ETH
USDC200 USDC500 USDC100 USDC

TypeScript Types

// Sensitivity levels
type SensitivityLevel = 'standard' | 'sensitive' | 'critical';

// Chains
type Chain = 'solana' | 'base' | 'ethereum';
type KeyType = 'ed25519' | 'secp256k1';

// Wallet info (public data only)
interface WalletInfo {
  chain: Chain;
  public_address: string;
  key_type: KeyType;
  operations: ('sign_tx' | 'sign_message' | 'get_address')[];
}

// Encrypted payload structure
interface EncryptedPayload {
  ciphertext: Buffer;
  nonce: Buffer;
  dek_wrapped: Buffer;
  dek_nonce: Buffer;
}

// Session
interface AgentSession {
  id: string;
  agent_name: string;
  granted_scopes: string[];
  consent_mode: 'once' | 'session';
  expires_at: string;
  created_at: string;
  last_used_at?: string;
}

// Budget check result
interface BudgetCheckResult {
  allowed: boolean;
  requires_approval: boolean;
  remaining_daily: number;
  remaining_tx: number;
  reason?: string;
}

Environment Variables

VariableDefaultPurpose
VAULT_DIR~/.dcpVault storage directory
DCP_CLI_SESSION_MINUTES30CLI unlock session duration

Security Considerations

Best Practices

  • ✅ Always call zeroize() on sensitive buffers after use
  • ✅ Use envelope encryption for all stored secrets
  • ✅ Store master key in OS keychain when available
  • ✅ Never log or expose plaintext keys
  • ✅ Use secure random generation for all keys and nonces
  • ✅ Validate all inputs before encryption/decryption

Common Mistakes to Avoid

  • ❌ DON'T reuse nonces - generate new one for each encryption
  • ❌ DON'T skip zeroization - sensitive keys must be cleared
  • ❌ DON'T use weak passphrases - minimum 12 characters recommended
  • ❌ DON'T store master key in plaintext files
  • ❌ DON'T create key export functions - this defeats the purpose

Advanced Usage

Custom Storage Backend

You can extend VaultStorage for custom backends (not recommended for most users):

import { VaultStorage } from '@dcprotocol/core';

class CloudVaultStorage extends VaultStorage {
  // Override storage methods to use cloud backend
  // WARNING: Must maintain encryption guarantees
}

Custom Budget Rules

import { BudgetEngine } from '@dcprotocol/core';

const budget = new BudgetEngine(storage);

// Update budget config
await budget.updateConfig({
  daily_budget: { SOL: 50, ETH: 2 },
  tx_limit: { SOL: 10, ETH: 0.5 },
  approval_threshold: { SOL: 5, ETH: 0.2 }
});

Testing

import { vi, test, expect } from 'vitest';
import { createWallet, signTransaction } from '@dcprotocol/core';

test('wallet creation and signing', async () => {
  const masterKey = generateKey();

  const { encrypted, info } = createWallet('solana', masterKey);
  expect(info.chain).toBe('solana');
  expect(info.public_address).toBeTruthy();

  // Sign a mock transaction
  const result = signSolanaTransaction(
    encrypted,
    masterKey,
    mockTransaction
  );

  expect(result.signature).toBeTruthy();

  // Clean up
  zeroize(masterKey);
});

See Also