Exchange Hot Wallet 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
Exchange Hot Wallet Development
Complex
~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

Hot Wallet Development

Exchange hot wallet is online crypto storage system that automatically processes user withdrawals. It's always internet-connected, so it represents main attack vector. Compromise between convenience and security solved through proper architecture: minimal hot balances, main reserve in cold.

Architecture

HD Wallet for Ethereum and EVM Networks

Hot wallet is master hot wallet address where funds from deposit addresses consolidate. For Ethereum-based networks — one address for entire exchange or multiple for parallel withdrawal processing.

type HotWallet struct {
    address    common.Address
    keyManager KeyManager        // abstraction over HSM or keystore
    client     *ethclient.Client
    nonceTrack *NonceTracker     // nonce management
    gasTrack   *GasTracker
}

// NonceTracker — critical component
// PostgreSQL stores last used nonce
// For parallel withdrawals need atomic nonce issuance
type NonceTracker struct {
    db   *DB
    mu   sync.Mutex
    pool chan uint64  // pre-fetched nonce pool
}

func (nt *NonceTracker) Next(ctx context.Context) (uint64, error) {
    nt.mu.Lock()
    defer nt.mu.Unlock()
    
    // Get next nonce atomically
    var nonce uint64
    err := nt.db.QueryRow(ctx, 
        "UPDATE hot_wallet SET nonce = nonce + 1 RETURNING nonce - 1"
    ).Scan(&nonce)
    return nonce, err
}

Nonce management is one of main technical complexities. With parallel transactions, guarantee two workers don't get same nonce. Solution: atomic increment in database with mutex protection.

Multi-Currency Hot Wallet

Different assets require different approaches.

Network Wallet Type Specifics
Ethereum / EVM EOA or Smart Contract Wallet ERC-20 via transfer/transferFrom
Bitcoin P2WPKH (SegWit) UTXO model, coin selection
Tron TRX/TRC-20 Bandwidth/Energy model
Solana ED25519 keypair SPL tokens, compute units
Ripple Shared address + destination tag Tag mandatory
# Bitcoin hot wallet — UTXO coin selection
class BitcoinHotWallet:
    def create_withdrawal(self, to_address: str, amount_sat: int, fee_rate: int):
        # Coin selection — select minimum UTXO set to cover amount + fee
        utxos = self.wallet.utxos()
        selected, change = self.select_coins(utxos, amount_sat, fee_rate)
        
        tx = self.wallet.transaction_create(
            outputs=[(to_address, amount_sat)],
            utxos=selected,
            fee=self.estimate_fee(len(selected), fee_rate),
            replace_by_fee=True,  # RBF for fee bump ability
        )
        return tx
    
    def select_coins(self, utxos, amount, fee_rate):
        # Simple strategy: smallest first (minimize UTXO set)
        utxos.sort(key=lambda u: u.value)
        selected = []
        total = 0
        for utxo in utxos:
            selected.append(utxo)
            total += utxo.value
            fee = self.estimate_fee(len(selected), fee_rate)
            if total >= amount + fee:
                change = total - amount - fee
                return selected, change
        raise InsufficientFunds()

Hot Wallet Security

HSM Integration

Hot wallet private key should never be plain text in server memory. Protection levels:

Level 1 (minimal): Encrypted keystore on disk (AES-256), password from environment variable or secrets manager. Key decrypted on startup and stored in memory.

Level 2 (recommended): HashiCorp Vault Transit Secrets Engine. Key never leaves Vault — server sends data to sign, receives signed transaction back.

import vault "github.com/hashicorp/vault/api"

type VaultSigner struct {
    client  *vault.Client
    keyName string
}

func (vs *VaultSigner) SignTransaction(txHash []byte) ([]byte, error) {
    // Vault Transit: sign data without key export
    path := fmt.Sprintf("transit/sign/%s", vs.keyName)
    secret, err := vs.client.Logical().Write(path, map[string]interface{}{
        "input":                base64.StdEncoding.EncodeToString(txHash),
        "hash_algorithm":       "sha2-256",
        "signature_algorithm":  "pkcs1v15",
        "prehashed":            true,
    })
    // Parse ECDSA signature and convert to Ethereum format
    return parseVaultSignature(secret.Data["signature"].(string))
}

Level 3 (maximum): Hardware HSM (Thales Luna, AWS CloudHSM, YubiHSM). Signature executed in hardware chip, private key physically unextractable. Cost from $20,000/year. For most exchanges Vault is optimal compromise.

Limits and Control

type WithdrawalLimiter struct {
    db    *DB
    cache *redis.Client
}

// Daily limit of automatic withdrawals from hot wallet
func (wl *WithdrawalLimiter) CheckAndConsume(amount decimal.Decimal, currency string) error {
    key := fmt.Sprintf("hot_wallet:daily_limit:%s:%s", currency, today())
    
    // Atomic increment with limit check
    script := redis.NewScript(`
        local current = redis.call('GET', KEYS[1])
        if current == false then current = 0 end
        local new_val = tonumber(current) + tonumber(ARGV[1])
        if new_val > tonumber(ARGV[2]) then
            return redis.error_reply("LIMIT_EXCEEDED")
        end
        redis.call('SETEX', KEYS[1], 86400, new_val)
        return new_val
    `)
    
    _, err := script.Run(context.Background(), wl.cache, 
                         []string{key}, amount.String(), DAILY_LIMIT.String()).Result()
    return err
}

On limit exceed — withdrawal goes to queue requiring manual operator approval (refill from warm wallet).

Balance Management and Refilling

Hot Wallet Balance Monitoring

type BalanceWatcher struct {
    hotWallet *HotWallet
    threshold decimal.Decimal  // minimum threshold
    target    decimal.Decimal  // target balance after refill
    alerter   Alerter
}

func (bw *BalanceWatcher) Watch(ctx context.Context) {
    ticker := time.NewTicker(5 * time.Minute)
    for {
        select {
        case <-ticker.C:
            balance := bw.hotWallet.GetBalance()
            if balance.LessThan(bw.threshold) {
                bw.alerter.Alert(Alert{
                    Level:   "CRITICAL",
                    Message: fmt.Sprintf("Hot wallet balance low: %s. Need topup from warm wallet", balance),
                })
                // Automatic refill from warm wallet
                bw.requestTopup(bw.target.Sub(balance))
            }
        case <-ctx.Done():
            return
        }
    }
}

ERC-20 Token Consolidation

Deposit addresses accumulate tokens. Sweep process consolidates them.

Development Timeline

Component Timeline
ETH/ERC-20 hot wallet 3–4 weeks
Bitcoin UTXO wallet 3–4 weeks
HSM/Vault integration 1–2 weeks
Sweep automation 2–3 weeks
Monitoring dashboard 1–2 weeks
Testnet testing 2–3 weeks

Full multi-currency hot wallet with HSM — 3–4 months.