Automatic Exchange Transaction Import System for Accounting

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
Automatic Exchange Transaction Import System for Accounting
Medium
~3-5 business days
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

Automated Exchange Transaction Import System for Accounting

Manual CSV export from each exchange is an inconvenient process: users forget, exchanges change formats, data gets lost. Automated import via API solves this: transactions are synced in the background without user intervention.

Exchange API Integrations

Binance API

class BinanceImporter implements ExchangeImporter {
  private client: Binance;
  
  async importTransactions(apiKey: string, secretKey: string, since: Date): Promise<RawTransaction[]> {
    this.client = new Binance({ apiKey, secretKey });
    
    const results = await Promise.all([
      this.getSpotTrades(since),
      this.getConversions(since),
      this.getStakingHistory(since),
      this.getSavingsInterest(since),
      this.getFlexibleEarnings(since),
      this.getDustConversions(since),
    ]);
    
    return results.flat();
  }
  
  private async getSpotTrades(since: Date): Promise<RawTransaction[]> {
    const symbols = await this.client.exchangeInfo().then(info => 
      info.symbols.map(s => s.symbol)
    );
    
    const trades: RawTransaction[] = [];
    
    // Binance requires request per trading pair
    for (const symbol of symbols) {
      const symbolTrades = await this.client.myTrades({
        symbol,
        startTime: since.getTime(),
        limit: 1000,
      });
      
      trades.push(...symbolTrades.map(t => this.normalizeBinanceTrade(t)));
      
      // Rate limiting
      await sleep(100);
    }
    
    return trades;
  }
  
  private normalizeBinanceTrade(trade: any): RawTransaction {
    const baseAsset = trade.symbol.replace(/(USDT|BTC|ETH|BNB)$/, "");
    const quoteAsset = trade.symbol.slice(baseAsset.length);
    
    return {
      id: trade.id.toString(),
      timestamp: new Date(trade.time),
      type: trade.isBuyer ? "buy" : "sell",
      assetIn: trade.isBuyer ? baseAsset : quoteAsset,
      amountIn: trade.isBuyer ? parseFloat(trade.qty) : parseFloat(trade.quoteQty),
      assetOut: trade.isBuyer ? quoteAsset : baseAsset,
      amountOut: trade.isBuyer ? parseFloat(trade.quoteQty) : parseFloat(trade.qty),
      fee: parseFloat(trade.commission),
      feeCurrency: trade.commissionAsset,
      exchange: "BINANCE",
      txId: trade.orderId.toString(),
    };
  }
}

Coinbase Advanced Trade API

class CoinbaseImporter implements ExchangeImporter {
  async importTransactions(apiKey: string, secret: string, since: Date): Promise<RawTransaction[]> {
    const results = await Promise.all([
      this.getFills(apiKey, secret, since),
      this.getConversions(apiKey, secret, since),
      this.getRewards(apiKey, secret, since), // staking rewards
    ]);
    
    return results.flat();
  }
  
  private async getFills(apiKey: string, secret: string, since: Date): Promise<RawTransaction[]> {
    let cursor: string | undefined;
    const fills: any[] = [];
    
    do {
      const response = await this.request(apiKey, secret, "/brokerage/orders/historical/fills", {
        start_sequence_timestamp: since.toISOString(),
        cursor,
      });
      
      fills.push(...response.fills);
      cursor = response.cursor;
    } while (cursor);
    
    return fills.map(this.normalizeCoinbaseFill);
  }
}

Refresh Scheduler

@Injectable()
class ExchangeSyncScheduler {
  // Sync every 4 hours for active users
  @Cron("0 */4 * * *")
  async syncActiveUsers() {
    const users = await this.db.getUsersWithApiKeys({
      lastSyncBefore: new Date(Date.now() - 3 * 60 * 60 * 1000), // > 3 hours ago
      isActive: true,
    });
    
    // Use queue for parallel processing without overload
    for (const user of users) {
      await this.syncQueue.add("sync-exchange", {
        userId: user.id,
        since: user.lastSyncAt,
      }, {
        attempts: 3,
        backoff: { type: "exponential", delay: 5000 },
      });
    }
  }
}

class ExchangeSyncWorker {
  async processJob(job: Job<SyncJobData>) {
    const { userId, since } = job.data;
    const exchangeConnections = await this.db.getUserExchanges(userId);
    
    for (const connection of exchangeConnections) {
      try {
        const importer = this.importerFactory.create(connection.exchange);
        const transactions = await importer.importTransactions(
          connection.apiKey,
          connection.secretKey,
          since
        );
        
        const normalized = transactions.map(tx => this.normalizer.normalize(tx));
        const classified = await this.classifier.classifyBatch(normalized, userId);
        
        await this.db.upsertTransactions(userId, classified);
        await this.db.updateLastSync(userId, connection.exchange);
        
      } catch (err) {
        if (err instanceof ApiKeyExpiredError) {
          await this.notifyUserApiKeyExpired(userId, connection.exchange);
        }
        throw err;
      }
    }
  }
}

Supported Exchanges

Exchange Method Limitations
Binance REST API (HMAC) Rate limits, requires request per pair
Coinbase OAuth 2.0 or API Key History limits
Kraken REST API History limited
OKX REST API Good API
Bybit REST API Requires history permissions
KuCoin REST API Custom pagination

Automated import system with 6+ exchanges, background sync and rate limit handling — 3-4 weeks development.