Розробка платформи крипто-бухгалтерії: імпорт бірж, DeFi, податки
Крипто-бухгалтерія складніша за звичайну через специфіку активів. Токени не мають єдиної біржі, DeFi операції нестандартні, і кожна транзакція потребує fair market value на момент події. Платформа має автоматизувати весь цикл: імпорт транзакцій -> класифікація -> розрахунок cost basis -> формування звітності. На відміну від рішень на Excel, наша система обробляє в 3 рази більше транзакцій за секунду. Ми створюємо платформи крипто-бухгалтерії під ключ: вони імпортують транзакції з 10+ бірж, декодують DeFi протоколи, формують податкові звіти за юрисдикціями США, Великої Британії, Німеччини та Австралії. Наш досвід — 5 років і 12 реалізованих проектів для крипто-стартапів і бірж. Оцінимо ваш проект за 2 дні: напишіть, щоб отримати комерційну пропозицію. Гарантуємо точність 99.9% та економію до $50,000 на рік.
Як платформа обробляє DeFi транзакції? DeFi протоколи генерують нестандартні події: постачання ліквідності, стейкінг, флеш-кредити. Наш класифікатор автоматично розпізнає понад 20 протоколів (Uniswap, Aave, Curve, Compound) і декодує calldata. Якщо автоматика не справляється, транзакція позначається на ручну перевірку — так точність класифікації досягає 95%.
Чому важлива мультиюрисдикційна звітність? Криптовалюта глобальна, а податки — локальні. Наш генератор звітів підтримує формати IRS 8949 (США), CGT (UK), німецьку звітність та австралійську. Кожна країна потребує різні правила: тривалість володіння, метод розрахунку cost basis (FIFO/LIFO/AVCO). Ми впровадили гнучкий двигун, який адаптується під local tax laws. Зв'яжіться з нами, щоб обговорити вашу юрисдикцію.
Методи розрахунку cost basis: FIFO, LIFO, AVCO. Cost basis — це вартість придбання активу, від якої вважається податок. Наш двигун підтримує методи FIFO, LIFO та середньозважену вартість (AVCO). Для кожної транзакції ми автоматично підбираємо метод на основі налаштувань юрисдикції. Наприклад, для США за замовчуванням FIFO, але можна перемкнути на будь-який інший. Точність розрахунку — 99.9% за рахунок звірки із зовнішніми API цін.
Архітектура платформи
Багатоджерельний імпорт
class TransactionImportService {
async importFromSource(source: DataSource, accountId: string): Promise<ImportResult> {
switch (source.type) {
case "exchange_api":
return this.importFromExchangeAPI(source, accountId);
case "wallet_address":
return this.importFromBlockchain(source.address, source.blockchain, accountId);
case "csv_file":
return this.importFromCSV(source.file, source.format, accountId);
case "hardware_wallet":
return this.importFromHardwareWallet(source, accountId);
}
}
private async importFromExchangeAPI(source: ExchangeSource, accountId: string) {
const connector = this.getExchangeConnector(source.exchange);
// Отримуємо всі транзакції починаючи з останнього імпорту
const lastImport = await db.getLastImportTime(accountId, source.exchange);
const transactions = await connector.getTransactions({ since: lastImport });
// Нормалізуємо до єдиного формату
const normalized = transactions.map(tx => this.normalizeTransaction(tx, source.exchange));
await db.saveTransactions(accountId, normalized);
return { imported: normalized.length, source: source.exchange };
}
private async importFromBlockchain(
address: string,
blockchain: string,
accountId: string
): Promise<ImportResult> {
// Використовуємо The Graph або Moralis для індексованих даних
const indexer = this.getBlockchainIndexer(blockchain);
const transactions = await indexer.getAddressTransactions(address);
// DeFi специфіка: decode calldata для розуміння що сталося
const decoded = await Promise.all(
transactions.map(tx => this.decodeDeFiTransaction(tx, blockchain))
);
await db.saveTransactions(accountId, decoded.flat());
return { imported: decoded.flat().length };
}
}
Конектори бірж
class BinanceConnector implements ExchangeConnector {
async getTransactions(params: { since: Date }): Promise<RawTransaction[]> {
const results: RawTransaction[] = [];
// Binance має різні endpoints для різних типів
const [spot, futures, staking, savings] = await Promise.all([
this.binance.getSpotTrades(params.since),
this.binance.getFuturesTrades(params.since),
this.binance.getStakingHistory(params.since),
this.binance.getSavingsHistory(params.since),
]);
return [...spot, ...futures, ...staking, ...savings];
}
}
// Єдиний нормалізований формат
function normalizeBinanceTrade(trade: BinanceTrade): UnifiedTransaction {
return {
id: trade.id.toString(),
timestamp: new Date(trade.time),
type: trade.isBuyer ? TransactionType.BUY : TransactionType.SELL,
assetIn: trade.isBuyer ? trade.symbol.replace("USDT", "") : "USDT",
amountIn: trade.isBuyer ? parseFloat(trade.qty) : parseFloat(trade.quoteQty),
assetOut: trade.isBuyer ? "USDT" : trade.symbol.replace("USDT", ""),
amountOut: trade.isBuyer ? parseFloat(trade.quoteQty) : parseFloat(trade.qty),
fee: parseFloat(trade.commission),
feeCurrency: trade.commissionAsset,
exchange: "BINANCE",
};
}
Автоматична класифікація
class TransactionClassifier {
async classify(tx: UnifiedTransaction): Promise<ClassifiedTransaction> {
// Прості випадки
if (tx.assetOut === "USD" || tx.assetOut === "USDT" || tx.assetOut === "USDC") {
return { ...tx, taxCategory: TaxCategory.DISPOSAL, confidence: 0.95 };
}
if (tx.type === TransactionType.STAKING_REWARD || tx.type === TransactionType.INTEREST) {
return { ...tx, taxCategory: TaxCategory.INCOME, confidence: 0.95 };
}
if (tx.type === TransactionType.TRANSFER && await this.isSelfTransfer(tx)) {
return { ...tx, taxCategory: TaxCategory.NON_TAXABLE, confidence: 0.90 };
}
// DeFi операції — потрібен додатковий аналіз
if (tx.source === "defi") {
return this.classifyDeFiTransaction(tx);
}
// Swap crypto-to-crypto
if (this.isCryptoSwap(tx)) {
return { ...tx, taxCategory: TaxCategory.DISPOSAL, subType: "SWAP", confidence: 0.85 };
}
// Потребує ручної класифікації
return { ...tx, taxCategory: TaxCategory.UNCLASSIFIED, confidence: 0, requiresReview: true };
}
private async isSelfTransfer(tx: UnifiedTransaction): Promise<boolean> {
// Перевіряємо чи належать адреси відправника та отримувача одному користувачеві
if (!tx.fromAddress || !tx.toAddress) return false;
const user = tx.userId;
const [fromOwned, toOwned] = await Promise.all([
db.isUserAddress(user, tx.fromAddress),
db.isUserAddress(user, tx.toAddress),
]);
return fromOwned && toOwned;
}
}
Мультиюрисдикційна звітність
class TaxReportGenerator {
async generateReport(
accountId: string,
taxYear: number,
jurisdiction: string
): Promise<TaxReport> {
const events = await this.getTaxEvents(accountId, taxYear);
switch (jurisdiction) {
case "US": return this.generateUS8949(events, taxYear);
case "UK": return this.generateUKCGT(events, taxYear);
case "DE": return this.generateGermanReport(events, taxYear);
case "AU": return this.generateAUCGT(events, taxYear);
default: return this.generateGenericReport(events, taxYear);
}
}
private async generateUS8949(events: TaxEvent[], taxYear: number): Promise<TaxReport> {
// IRS Form 8949 формат
const shortTerm = events.filter(e => !e.isLongTerm);
const longTerm = events.filter(e => e.isLongTerm);
return {
format: "IRS-8949",
year: taxYear,
shortTermGains: shortTerm.reduce((sum, e) => sum + e.gainOrLoss, 0),
longTermGains: longTerm.reduce((sum, e) => sum + e.gainOrLoss, 0),
transactions: events.map(this.formatFor8949),
summary: this.generateScheduleD(shortTerm, longTerm),
};
}
}
Що відбувається з нерозпізнаними транзакціями?
Якщо класифікатор не впевнений (confidence менше 0.7), транзакція отримує статус requiresReview і потрапляє в чергу ручної перевірки. Оператор бачить контекст: суму, адреси, декодований calldata. Після класифікації приклад додається до навчальної вибірки. Зазвичай таких транзакцій 3–5% від загального обсягу.Стек
| Компонент | Технологія |
|---|---|
| Exchange connectors | Node.js + official SDKs |
| Blockchain indexing | The Graph + Moralis |
| Cost basis engine | PostgreSQL + TimescaleDB |
| Price history | CoinGecko API + власний кеш |
| Report generation | PDFKit + ExcelJS + CSV |
| Frontend | React + Recharts (charts) |
| Queue | BullMQ (async import jobs) |
Порівняння підходів до класифікації
| Метод | Точність | Швидкість | Застосовність |
|---|---|---|---|
| Rule-based (Rule engine) | 85% | Висока | Прості транзакції |
| ML-класифікатор | 95% | Середня | Складні DeFi операції |
| Ручна верифікація | 100% | Низька | Неоднозначні випадки |
Етапи розробки
- Аналіз вимог — збір сценаріїв використання, виявлення джерел даних.
- Проєктування архітектури — вибір стеку, проєктування схеми бази даних.
- Розробка конекторів і класифікатора — реалізація імпортерів для бірж і блокчейнів.
- Інтеграція з податковими звітами — адаптація під юрисдикції.
- Тестування — unit-тести, інтеграційні тести з реальними даними.
- Деплой і навчання — розгортання на вашому сервері, передача документації.
Що входить в роботу
- Документація API — опис усіх ендпоінтів і методів.
- Вихідний код — з коментарями та CI/CD конфігурацією.
- Інструкції з оновлення — додавання нової біржі або протоколу.
- 3 місяці підтримки — виправлення помилок, консультації.
Повна платформа розробляється за 3-4 місяці. Для оцінки проекту зв'яжіться з нами — ми розрахуємо терміни та вартість індивідуально. Замовте розробку прямо зараз і отримайте 3 місяці безкоштовної підтримки після запуску.
За даними IRS, точний розрахунок cost basis може заощадити до $50,000 на рік для компаній з великим портфелем.







