Skip to content

coinbase-samples/prime-recon-go

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Prime Reconciliation Reference Application

This reference application reconciles balances against fills and transactions over a time window.

Why Reconciliation is Important

Balances on Coinbase Prime can for a variety of reasons, including order fills, deposits, withdrawals, and rewards. Reconciling these balances against direct activities verifies that your actual balances match what you expect based on recorded activity. This helps detect:

  • Missing or duplicate transactions
  • Incorrect fill amounts
  • API timing issues
  • System discrepancies

How It Works

This application runs a reconciliation window:

  1. Capture starting balances for all assets
  2. Wait for the configured window duration
  3. Capture ending balances and query all fills/transactions during the window
  4. Calculate expected balances for each asset
  5. Compare expected vs actual balances
  6. Report any discrepancies (delta = actual - expected)

If the delta is zero (or negligible within tolerance), the asset reconciles. Otherwise, a discrepancy is flagged for investigation.

For continuous coverage, run this application on a schedule (e.g., hourly via cron or a task scheduler) with WINDOW_DURATION set to match the interval. This creates back-to-back reconciliation windows that verify all activity over time.

Balance Calculation

Expected = Starting Balance + Credits - Debits

Fills affect two assets (base and quote):

BUY BTC-USD:   BTC +quantity     USD -(value + commission)
SELL BTC-USD:  BTC -quantity     USD +(value - commission)

Transactions affect one asset (except conversions):

DEPOSIT, INTERNAL_DEPOSIT, COINBASE_DEPOSIT, REWARD  →  Credit
WITHDRAWAL, INTERNAL_WITHDRAWAL                       →  Debit (absolute value)
CONVERSION                                            →  Debit source, credit destination

Setup

go mod download
cp .env.example .env
# Edit .env with your credentials

Required:

  • PRIME_ACCESS_KEY
  • PRIME_PASSPHRASE
  • PRIME_SIGNING_KEY
  • PRIME_PORTFOLIO

Optional:

  • WINDOW_DURATION - Observation window in seconds (default: 300)
  • RECONCILIATION_TOLERANCE - Decimal places for negligible threshold (default: 8)
  • RETRY_ON_FAILURE - Retry failed assets after delay (default: false)
  • RETRY_DELAY - Seconds to wait before retry (default: 2)
  • RECENT_ACTIVITY_THRESHOLD - Seconds before window end to flag recent activity (default: 5)

Usage

go run ./cmd/recon

Or build and run:

go build -o bin/recon ./cmd/recon
./bin/recon

Interpreting Results

Each asset with activity during the window is logged with reconciliation details:

{"msg":"Asset reconciled","asset":"btc","start_balance":"0.01627","fills_net":"0.00003","transactions_net":"0","total_net":"0.00003","expected_end":"0.01630","actual_end":"0.01630","reconciled":true}
  • start_balance: Balance at window start
  • fills_net: Net change from trades (credits - debits)
  • transactions_net: Net change from deposits/withdrawals
  • total_net: Combined net change
  • expected_end: Calculated balance (start + total_net)
  • actual_end: Balance returned by API at window end
  • reconciled: true if expected matches actual (within tolerance)

A successful run ends with:

{"msg":"Reconciliation successful - all balances match","reconciled_assets":3}

A failed reconciliation shows the discrepancy:

{"msg":"Reconciliation failed - discrepancies detected","failed_asset_count":1,"btc":{"delta":"0.001","expected":"1.5","actual":"1.501"}}

Known Limitation

The Prime balances API does not include timestamps in its response. This means there's inherent ambiguity about when a balance snapshot was taken relative to fills and transactions.

The problem: If a fill or deposit occurs immediately before the ending balance query, the returned balance may not yet reflect that activity, causing a false discrepancy.

Mitigations built into this app:

  • Retry mechanism: Enable RETRY_ON_FAILURE=true to automatically re-check balances after a brief delay, giving the API time to catch up
  • Recent activity warning: When discrepancies occur alongside activity near the window end, a warning explains the likely cause
  • Longer windows: Using WINDOW_DURATION with longer windows reduces the proportion of edge-case timing issues

About

Reference application that showcases how to implement reconciliation

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages