Instant Exchange Service Development

We design and develop full-cycle blockchain solutions: from smart contract architecture to launching DeFi protocols, NFT marketplaces and crypto exchanges. Security audits, tokenomics, integration with existing infrastructure.
Showing 1 of 1 servicesAll 1306 services
Instant Exchange Service Development
Medium
~1-2 weeks
FAQ
Blockchain Development Services
Blockchain Development Stages
Latest works
  • image_website-b2b-advance_0.png
    B2B ADVANCE company website development
    1214
  • image_web-applications_feedme_466_0.webp
    Development of a web application for FEEDME
    1161
  • image_websites_belfingroup_462_0.webp
    Website development for BELFINGROUP
    852
  • image_ecommerce_furnoro_435_0.webp
    Development of an online store for the company FURNORO
    1041
  • image_logo-advance_0.png
    B2B Advance company logo design
    561
  • image_crm_enviok_479_0.webp
    Development of a web application for Enviok
    823

KYC/AML Development for Crypto Exchanger

KYC (Know Your Customer) and AML (Anti-Money Laundering) are regulatory requirements that become mandatory for crypto exchangers in most jurisdictions. FATF (Financial Action Task Force) and the EU require verification for transactions above certain thresholds. Without KYC/AML, the exchanger risks payment provider blocking and legal problems.

KYC/AML System Architecture

Verification Tiers (KYC Tiers)

type KYCTier int

const (
    TierUnverified  KYCTier = 0  // unverified
    TierBasic       KYCTier = 1  // email + phone
    TierStandard    KYCTier = 2  // ID document + selfie
    TierEnhanced    KYCTier = 3  // + source of funds
)

type TierLimits struct {
    DailyLimitUSD   decimal.Decimal
    TxLimitUSD      decimal.Decimal
    RequiredKYC     KYCTier
}

var DefaultLimits = map[KYCTier]TierLimits{
    TierUnverified: {DailyLimitUSD: decimal.New(1000, 0),  TxLimitUSD: decimal.New(500, 0)},
    TierBasic:      {DailyLimitUSD: decimal.New(3000, 0),  TxLimitUSD: decimal.New(1500, 0)},
    TierStandard:   {DailyLimitUSD: decimal.New(15000, 0), TxLimitUSD: decimal.New(5000, 0)},
    TierEnhanced:   {DailyLimitUSD: decimal.New(100000, 0), TxLimitUSD: decimal.New(50000, 0)},
}

Integration with KYC Providers

Developing OCR for documents and liveness detection yourself is not cost-effective. Use KYC-as-a-Service:

Sumsub — popular choice for crypto. Document verification for 80+ countries, liveness detection, Watchlist database:

import axios from 'axios';
import crypto from 'crypto';

class SumsubKYC {
  private appToken: string;
  private secretKey: string;
  
  private signRequest(method: string, url: string, body?: string): string {
    const ts = Math.floor(Date.now() / 1000).toString();
    const payload = ts + method.toUpperCase() + url + (body || '');
    const hmac = crypto.createHmac('sha256', this.secretKey).update(payload).digest('hex');
    return `${ts}:${hmac}`;
  }
  
  async createApplicant(externalUserId: string, levelName: string = 'basic-kyc-level') {
    const url = '/resources/applicants';
    const body = JSON.stringify({ externalUserId, levelName });
    
    const response = await axios.post(`https://api.sumsub.com${url}`, body, {
      headers: {
        'X-App-Token': this.appToken,
        'X-App-Access-Sig': this.signRequest('POST', url, body),
        'Content-Type': 'application/json',
      },
    });
    
    return response.data;  // applicantId
  }
  
  async generateAccessToken(applicantId: string): Promise<string> {
    const url = `/resources/accessTokens?userId=${applicantId}`;
    const response = await axios.post(`https://api.sumsub.com${url}`, '', {
      headers: {
        'X-App-Token': this.appToken,
        'X-App-Access-Sig': this.signRequest('POST', url),
      },
    });
    return response.data.token;
  }
  
  // Webhook from Sumsub on verification status change
  async handleWebhook(payload: SumsubWebhook) {
    const { applicantId, reviewResult } = payload;
    
    switch (reviewResult.reviewAnswer) {
      case 'GREEN':  // verified
        await this.updateUserKYCStatus(applicantId, 'verified');
        break;
      case 'RED':    // rejected
        const reasons = reviewResult.rejectLabels;
        await this.updateUserKYCStatus(applicantId, 'rejected', reasons);
        break;
    }
  }
}

Frontend integration — Sumsub WebSDK embedded in verification page:

// React verification component
import SumsubWebSdk from '@sumsub/websdk-react';

function KYCVerification({ userId }: { userId: string }) {
  const [accessToken, setAccessToken] = useState<string | null>(null);
  
  useEffect(() => {
    api.getKYCToken(userId).then(setAccessToken);
  }, [userId]);
  
  if (!accessToken) return <Loading />;
  
  return (
    <SumsubWebSdk
      accessToken={accessToken}
      expirationHandler={() => api.getKYCToken(userId)}
      onMessage={(type, payload) => {
        if (type === 'idCheck.applicantReviewComplete') {
          router.push('/kyc/pending');
        }
      }}
      onError={(error) => console.error('KYC error:', error)}
    />
  );
}

AML: Transaction Monitoring

Blockchain Analytics

For crypto transactions, you need to check source of funds. Sending from mixer, darknet marketplace, or sanctioned address — red flag.

Blockchain analytics providers:

class ChainAnalysisAML {
  async checkAddress(address: string, currency: string): Promise<RiskScore> {
    const response = await this.client.post('/v2/users', {
      userId: `check-${Date.now()}`,
      currency,
      address,
    });
    
    return {
      risk: response.data.risk,          // "low" | "medium" | "high" | "severe"
      riskScore: response.data.riskScore, // 0-10
      exposures: response.data.exposures, // [{category, value}]
      flags: response.data.flags,         // specific risk reasons
    };
  }
}

// Example integration into exchange process
async function checkIncomingDeposit(txHash: string, fromAddress: string, currency: string) {
  const riskScore = await chainAnalysis.checkAddress(fromAddress, currency);
  
  if (riskScore.risk === 'severe') {
    await freezeTransaction(txHash, 'HIGH_RISK_ADDRESS');
    await notifyCompliance(txHash, riskScore);
    return false;
  }
  
  if (riskScore.risk === 'high') {
    await flagForReview(txHash, riskScore);
    // Continue, but mark for manual review
  }
  
  return true;
}

Elliptic and TRM Labs — Chainalysis alternatives, with different coverage and pricing.

AML Rules

type AMLRule struct {
    Name      string
    Check     func(tx Transaction, user User) AMLResult
    Action    AMLAction  // ALLOW, FLAG, BLOCK
}

var AMLRules = []AMLRule{
    {
        Name: "structuring_detection",
        Check: func(tx Transaction, user User) AMLResult {
            // Suspicious: several transactions just below KYC threshold
            recentTxs := db.GetUserTransactions(user.ID, 24*time.Hour)
            totalValue := sum(recentTxs)
            
            // Several ~$990 transactions in a row — attempt to bypass KYC limit
            if len(recentTxs) > 3 && totalValue > KYCThreshold*0.8 {
                return AMLResult{Risk: "high", Reason: "potential_structuring"}
            }
            return AMLResult{Risk: "low"}
        },
        Action: FLAG,
    },
    {
        Name: "high_risk_country",
        Check: func(tx Transaction, user User) AMLResult {
            highRiskCountries := []string{"KP", "IR", "SY", "CU"}
            if contains(highRiskCountries, user.Country) {
                return AMLResult{Risk: "severe", Reason: "sanctioned_jurisdiction"}
            }
            return AMLResult{Risk: "low"}
        },
        Action: BLOCK,
    },
    {
        Name: "pep_screening",
        Check: func(tx Transaction, user User) AMLResult {
            // PEP = Politically Exposed Person
            isPEP := pepDatabase.CheckName(user.FullName, user.DateOfBirth)
            if isPEP {
                return AMLResult{Risk: "medium", Reason: "pep_detected"}
            }
            return AMLResult{Risk: "low"}
        },
        Action: FLAG,
    },
}

Watchlist Screening

Checking against sanctions lists (OFAC SDN, EU Consolidated List, UN Sanctions):

type WatchlistScreener struct {
    ofacList   []SanctionEntry
    euList     []SanctionEntry
    updateFreq time.Duration
}

func (ws *WatchlistScreener) ScreenName(name, dob string) []SanctionMatch {
    // Fuzzy matching — names can be transliterated differently
    var matches []SanctionMatch
    
    for _, entry := range append(ws.ofacList, ws.euList...) {
        similarity := fuzzy.MatchScore(name, entry.Name)
        if similarity > 0.85 {  // 85% similarity
            matches = append(matches, SanctionMatch{
                Entry:      entry,
                Similarity: similarity,
                ListSource: entry.ListSource,
            })
        }
    }
    return matches
}

SAR (Suspicious Activity Report)

When suspicious activity is detected — mandatory SAR filing to regulator (FinCEN in US, Rosfinmonitoring in Russia):

type SAR struct {
    UserID          int64
    TransactionID   string
    Amount          decimal.Decimal
    Currency        string
    SuspiciousType  string   // structuring, layering, unusual_pattern, etc.
    Description     string
    SupportingDocs  []string
    FiledAt         time.Time
}

// Auto-generate SAR draft on alert
func (c *ComplianceEngine) GenerateSARDraft(alert AMLAlert) *SAR {
    user := c.db.GetUser(alert.UserID)
    txHistory := c.db.GetTransactionHistory(alert.UserID, 90*24*time.Hour)
    
    return &SAR{
        UserID:         alert.UserID,
        TransactionID:  alert.TxID,
        SuspiciousType: alert.RuleTriggered,
        Description: fmt.Sprintf(
            "User %s (KYC: %s) made transaction %s %s "+
            "from high-risk address (score: %.1f). "+
            "90-day transaction history: %d operations for %s",
            user.FullName, user.KYCTier, alert.Amount, alert.Currency,
            alert.RiskScore, len(txHistory), totalVolume(txHistory),
        ),
    }
}

Compliance Dashboard

For compliance team — separate interface:

  • Queue for manual review (high/medium risk transactions)
  • History of all AML alerts with details
  • Statistics: transactions blocked, SARs filed
  • AML rule and threshold management

Timeline and Integrations

Component Timeline
KYC tiers + Sumsub integration 2–3 weeks
AML rules + transaction monitoring 2–3 weeks
Blockchain analytics (Chainalysis/Elliptic) 1–2 weeks
Watchlist screening 1–2 weeks
Compliance dashboard 2–3 weeks

Complete KYC/AML system for exchanger: 2–3 months. Requires legal consultation for target jurisdictions to configure thresholds and requirements.