KAKUNIN

Quickstart: Deploy MiCA-Compliant Trading Bot in 30 Minutes

This quickstart takes you from zero to a production-ready, MiCA-compliant trading bot.

Time: ~30 minutes
Prerequisites: Node.js 18+, Kubernetes cluster or Docker, Kakunin account


Step 1: Create Kakunin Account (5 min)

Go to dashboard.kakunin.ai and sign up. You'll get:

Set up environment variables:

# .env.local
KAKUNIN_API_KEY=sk_live_xxxxxxxxxxxxxxxx
KAKUNIN_PROJECT_ID=proj_1234567890
AWS_REGION=eu-west-1  # Use EU region for GDPR
KMS_CA_KEY_ARN=arn:aws:kms:eu-west-1:123456789:key/12345678-1234-1234-1234-123456789012

Step 2: Define MiCA Scope (5 min)

Create a policy file that matches your regulatory requirements:

// mica-policy.ts
const micaPolicy = {
  agentName: 'algo_trader_v2',
  operatorName: 'your_company_ltd',
  operatorRegulatorId: 'FINMA-123456',  // Your regulatory registration
  
  // MiCA scope limits
  scope: {
    maxTradeSize: 25000,  // EUR per trade
    maxDailyVolume: 500000,  // EUR per day
    allowedMarkets: ['EUR_USD', 'GBP_EUR'],  // Only these pairs
    tradingHours: {
      start: '08:00',
      end: '17:00',
      tz: 'UTC',
      excludeWeekends: true,
    },
    allowedRegions: ['eu-west-1'],  // GDPR compliance
  },

  // Risk controls
  riskControls: {
    killSwitchAutomatic: 'anomaly_0.85',  // Revoke if anomaly > 0.85
    circuitBreakerThreshold: 0.75,
    maxConsecutiveFailures: 3,
  },

  // Documentation (for regulators)
  governance: {
    boardApprovedDate: '2026-05-01',
    nextAuditDate: '2026-08-01',
  },
};

export default micaPolicy;

Step 3: Install Dependencies (2 min)

npm install @kakunin/sdk @kakunin/trading-bot axios dotenv

Step 4: Initialize Agent (5 min)

// src/agent/bootstrap.ts
import { KakuninClient } from '@kakunin/sdk';
import micaPolicy from '../mica-policy';

const kakunin = new KakuninClient({
  apiKey: process.env.KAKUNIN_API_KEY,
  baseUrl: 'https://api.kakunin.ai',
});

export async function bootstrapAgent() {
  // Create or retrieve agent
  const agent = await kakunin.agents.create({
    name: micaPolicy.agentName,
    metadata: {
      version: '2.1.0',
      deployment: 'kubernetes',
      operator: micaPolicy.operatorName,
      regulatorId: micaPolicy.operatorRegulatorId,
    },
  });

  console.log(`✓ Agent created: ${agent.id}`);

  // Issue X.509 certificate with MiCA scope
  const cert = await kakunin.agents.getCertificate(agent.id, {
    validityDays: 365,
    scope: micaPolicy.scope,
  });

  console.log(`✓ Certificate issued: ${cert.serial_number}`);

  // Store certificate and KMS ARN
  const identity = {
    agentId: agent.id,
    certificatePem: cert.certificate_pem,
    kmsKeyArn: cert.kms_key_arn,
    serialNumber: cert.serial_number,
  };

  // Save to secure location (not in code!)
  await saveToSecretManager(identity);

  return identity;
}

async function saveToSecretManager(identity: any) {
  // Use Kubernetes Secrets, AWS Secrets Manager, or equivalent
  // NEVER hardcode credentials
  console.log('Saving identity to secret manager...');
}

Step 5: Implement Trading Logic (8 min)

// src/agent/trading-engine.ts
import { KakuninClient } from '@kakunin/sdk';
import axios from 'axios';

const kakunin = new KakuninClient({
  apiKey: process.env.KAKUNIN_API_KEY,
});

export async function executeTrade(
  identity: any,
  tradeRequest: {
    market: string;
    side: 'BUY' | 'SELL';
    size: number;
  }
) {
  // Step 1: Serialize trade request deterministically
  const payload = JSON.stringify(tradeRequest, Object.keys(tradeRequest).sort());

  // Step 2: Pre-trade risk check (run before signing)
  const preTradeCheck = await kakunin.trading.preTradeRiskCheck({
    agentId: identity.agentId,
    payload,
  });

  if (!preTradeCheck.allowed) {
    console.error(`❌ Trade blocked: ${preTradeCheck.reason}`, preTradeCheck);
    return { error: preTradeCheck.reason };
  }

  console.log(`✓ Pre-trade check passed, anomaly score: ${preTradeCheck.anomalyScore}`);

  // Step 3: Sign the trade with agent's identity
  const signed = await kakunin.actions.sign({
    agentId: identity.agentId,
    payload,
    metadata: {
      actionType: 'trade.execute',
      timestamp: Date.now(),
    },
  });

  console.log(`✓ Trade signed (signature: ${signed.signature.substring(0, 20)}...)`);

  // Step 4: Submit to exchange with proof of identity
  const response = await axios.post('https://api.exchange.com/v1/trades', tradeRequest, {
    headers: {
      'Content-Type': 'application/json',
      'X-Agent-Certificate': identity.certificatePem,
      'X-Agent-Signature': signed.signature,
      'X-Agent-Timestamp': signed.timestamp.toString(),
      'Authorization': `Bearer ${process.env.EXCHANGE_API_KEY}`,
    },
  });

  if (response.status !== 200) {
    console.error(`❌ Exchange rejected trade: ${response.data}`);
    return { error: 'exchange_rejected' };
  }

  // Step 5: Log the trade (for MiCA audit trail)
  await logTrade(identity, tradeRequest, signed, response.data);

  console.log(`✓ Trade executed: ${response.data.orderId}`);
  return response.data;
}

async function logTrade(identity: any, request: any, signed: any, result: any) {
  const auditEntry = {
    timestamp: new Date().toISOString(),
    agentId: identity.agentId,
    agentCertSerial: identity.serialNumber,
    orderId: result.orderId,
    market: request.market,
    side: request.side,
    size: request.size,
    executionPrice: result.executionPrice,
    signature: signed.signature.substring(0, 50) + '...',
    signatureVerified: true,
  };

  console.log('📋 Audit log:', JSON.stringify(auditEntry, null, 2));

  // Store in audit log (WORM — write-once, read-many)
  // This is your evidence for regulators
}

Step 6: Set Up KYA Baseline (3 min)

// src/agent/kya-setup.ts
import { KakuninClient } from '@kakunin/sdk';

const kakunin = new KakuninClient({
  apiKey: process.env.KAKUNIN_API_KEY,
});

export async function setupKYABaseline(agentId: string) {
  // Define baseline (based on your trading algorithm's expected behavior)
  const baseline = {
    agentId,
    
    // Median trade size from historical testing
    transactionSizeP50: 18500,  // EUR
    transactionSizeP99: 24000,  // EUR (approach limit)
    
    // Expected frequency
    transactionsPerHour: 6,  // Median
    transactionsPerHourP95: 15,  // Peak
    
    // Market preferences
    preferredMarkets: ['EUR_USD', 'GBP_EUR'],
    
    // Time patterns
    tradingHours: {
      start: 8,  // 08:00 UTC
      end: 17,   // 17:00 UTC
      excludeWeekends: true,
    },
  };

  // Register baseline
  const result = await kakunin.monitoring.setBaseline(agentId, baseline);
  console.log(`✓ KYA baseline set, anomaly detection armed`);

  return baseline;
}

Step 7: Deploy to Kubernetes (2 min)

# k8s/trading-bot.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: algo-trader
spec:
  replicas: 1
  selector:
    matchLabels:
      app: algo-trader
  template:
    metadata:
      labels:
        app: algo-trader
    spec:
      serviceAccountName: algo-trader
      containers:
      - name: trading-bot
        image: myrepo/algo-trader:v2
        env:
        - name: KAKUNIN_API_KEY
          valueFrom:
            secretKeyRef:
              name: kakunin-secrets
              key: api-key
        - name: KAKUNIN_PROJECT_ID
          value: proj_1234567890
        - name: EXCHANGE_API_KEY
          valueFrom:
            secretKeyRef:
              name: exchange-secrets
              key: api-key
        volumeMounts:
        - name: agent-identity
          mountPath: /var/secrets/agent
          readOnly: true
        - name: audit-logs
          mountPath: /var/audit
        livenessProbe:
          httpGet:
            path: /health
            port: 8080
          initialDelaySeconds: 30
          periodSeconds: 10
      
      volumes:
      - name: agent-identity
        secret:
          secretName: agent-certificate
      - name: audit-logs
        persistentVolumeClaim:
          claimName: audit-logs-pvc

Deploy:

kubectl apply -f k8s/trading-bot.yaml
kubectl rollout status deployment/algo-trader -w

Step 8: Verify Deployment (2 min)

# Check agent is running
kubectl logs -f deployment/algo-trader

# Expected output:
# ✓ Agent created: agent_12345
# ✓ Certificate issued: F1D4E8C7B2A9F3E6
# ✓ KYA baseline set, anomaly detection armed
# Waiting for trading signals...

# Port forward to local for testing
kubectl port-forward svc/algo-trader 8080:8080

# Test health check
curl http://localhost:8080/health
# Expected: {"status": "ok", "anomalyScore": 0.05}

Step 9: Prepare Regulatory Documentation

Create a folder with:

/regulatory-docs
├── board-resolution.pdf          # Board approved this deployment
├── mica-policy.json              # Scope policy + governance framework
├── baseline-profile.json         # Behavioral baseline (7-day period)
├── certificate-chain.pem         # Full X.509 certificate chain
├── sample-audit-logs.json        # First 10 trades with signatures
├── incident-response-plan.md     # What happens if anomaly detected
└── testing-schedule.md           # Annual fitness tests scheduled

Submit to your regulator. You now have:


Step 10: Monitor & Adjust (Ongoing)

// src/monitoring/dashboard.ts
import { KakuninClient } from '@kakunin/sdk';

const kakunin = new KakuninClient({
  apiKey: process.env.KAKUNIN_API_KEY,
});

setInterval(async () => {
  const agentStatus = await kakunin.monitoring.getAgentStatus(agentId);

  console.log(`
Agent: ${agentStatus.agentId}
Cert: ${agentStatus.certificateStatus}  (valid/${agentStatus.daysUntilExpiry} days)
Anomaly Score: ${agentStatus.anomalyScore}
Trades Today: ${agentStatus.tradesExecuted}/${agentStatus.dailyLimit}
Median Size: €${agentStatus.medianTradeSize}
Last Trade: ${agentStatus.lastTradeTime}
  `);

  // If anomaly score rises above 0.75, you'll get a warning
  if (agentStatus.anomalyScore > 0.75) {
    console.warn('⚠️ Anomaly threshold exceeded. Check logs.');
  }
}, 60000);  // Check every minute

You're Done! 🎉

Your trading bot is now:

Next: Go through the MiCA case study to see what happens when the bot behaves anomalously.

Questions? See the MiCA compliance deep dive for regulatory details.