Skip to main content

Crypto portfolio and statement data

What is crypto portfolio and statement data?

Crypto portfolio and statement data is the record of what a customer holds across all their wallets and chains, and every transfer that got them there, shown on a portfolio screen or a periodic statement.

Wallet apps and wealth platforms need it to match the chain, because a missing token or an out-of-date balance is the first thing a customer notices.

Goldsky loads each wallet’s history and keeps balances and transfers current in your database or behind an API, while valuing holdings, adding up periods and issuing statements stay with you.

You can build it three ways: stream each customer’s wallets into your own database with Turbo Pipelines, call the Feeds balances and transfers API from your app, or have Feeds sync those rows into your database.

Who uses crypto portfolio and statement data?

Self-custody wallet apps, neobanks with a crypto tab and wealth platforms that show clients their onchain holdings next to their other accounts.

How crypto portfolio and statement data is built

The diagram follows one customer from linking their wallets to seeing their holdings and history in your app, and shows who does each step. Your setup may differ.

Your business, step 1: Customer links walletsAddresses added to their profile
Goldsky, step 2: TurboBackfill their historyA one-off job loads past transfers
Blockchains, step 3: Funds moveNew transfers in and out
Goldsky, steps 4–5: TurboKeep it currentNew transfers and balances as they land
Your business, steps 6–7: Show the portfolioYour API serves holdings and statements
  • Goldsky

Ways to get crypto portfolio and statement data

The pipeline and the synced feeds keep every wallet’s data in your database, with the pipeline’s SQL yours to shape; the API keeps nothing on your side and returns one wallet per request.

Best for
Many customer wallets, kept in your own database
Products
Turbo
What you run
The destination: your database, queue or bucket, or a Postgres database Goldsky hosts
What you write
Pipeline YAML and SQL; TypeScript transforms when needed
Where your data lives
In your own database or systems
How results reach you
Pushed to you
Best for
Portfolio screens with no pipeline, one wallet per call
Products
Feeds
What you run
Nothing; you call an endpoint and keep what you need
What you write
REST requests
Where your data lives
Hosted by Goldsky
How results reach you
Returned when you call
Best for
Local SQL reads, with no pipeline to define
Products
Feeds
What you run
The destination database or endpoint
What you write
Nothing to get the rows; your own SQL to use them
Where your data lives
In your own database or systems
How results reach you
Pushed to you

Option 1: Build crypto portfolio data by streaming wallets to your database

A pipeline loads each linked wallet’s past transfers, then keeps its transfers and balances current in your database as new blocks arrive. Your own API serves the portfolio and statement screens from those tables.

When to stream portfolio data with a pipeline

You have many customers with many wallets, the screens read more often than you’d want to call out for, or customer data has to stay in your own systems.

What you’ll need

  • Goldsky Turbo
  • A database for the wallet list, transfers and balances
  • A price source for valuing holdings
  • An API and app screens that read from your database
  1. Link the customer’s wallets to their profile

    A portfolio covers every wallet a customer owns, so you first need to know which addresses are theirs.

    The customer adds each address, or your app connects it, and you store the address, its chain and the customer ID together. An address saved without its owner shows up as holdings nobody can see, and one saved against the wrong customer shows one person’s money to another.

  2. Load each wallet’s past transfers

    Handled by Goldsky Turbo

    A new customer expects to see their whole history on day one, including everything before they linked the wallet.

    Every past transfer in and out of the wallet has to be loaded once, from the wallet’s first activity up to now. A load that starts too late leaves early holdings unexplained, and the statement’s opening balance won’t match the chain.

    With Goldsky, you can run a Turbo Pipelines job (job: true) over a bounded block range, filtered to the customer’s addresses, that writes past transfers to your database and exits once the range is done.

    Run a one-time backfill job (opens in a new tab)
  3. Record new transfers on the chain

    Holdings change whenever money moves in or out of a wallet, and the chain is where that’s recorded.

    Each transfer lands in a block on its chain. For a short time the newest blocks can be replaced (a reorg), so a transfer seen once can still disappear or move to another block.

  4. Keep transfers and balances current

    Handled by Goldsky Turbo

    Holdings on the screen have to change when the chain does, without anyone refreshing them.

    Each new transfer touching a linked wallet is recorded, and that wallet’s balance is read again at the transfer’s block. Re-reading every wallet on every block costs more as customers grow, while most wallets haven’t moved.

    A long-running pipeline in Turbo Pipelines can keep only transfers that touch a linked address, using dynamic_table_check(), then read the new balance at that block with _gs_evm_get_balances for native tokens or _gs_eth_call with balanceOf for other tokens.

    Track balances for a set of addresses (opens in a new tab)
  5. Correct rows the chain rewrites

    Handled by Goldsky Turbo

    When the chain replaces its newest blocks (a reorg), a transfer you recorded can disappear or move.

    Your tables have to follow the chain when that happens. If they don’t, a customer sees a transfer that never settled, or a balance that counts it twice.

    Goldsky’s Turbo Pipelines passes reorg corrections through as deletes and updates, and a database sink with a primary_key applies them to the same rows.

    How reorgs reach your sinks (opens in a new tab)
  6. Value the holdings and build the statement

    Customers read a portfolio in money, and a statement adds up a period: what they held at the start and end, and what moved in between.

    Your system sums holdings per customer across wallets and chains, applies the prices your policy names and works out each period’s totals in your database. Prices and totals change after the fact, so store the figures a statement was issued with instead of recalculating them when the customer opens it again.

  7. Show the portfolio in your app

    The customer sees their holdings and history on a screen you control, behind your own login.

    Your API reads the stored holdings and transfers for the signed-in customer and nothing else. Screens that read the chain for every page view get slower as customers add wallets, and they show a different answer from the statement.

What to know about streaming portfolio data

  • Goldsky runs the pipeline; you own the database, the totals and the API your app calls.
  • History is loaded once per wallet, then kept current, so screens never wait on a chain lookup.
  • Tables keyed on a primary key take reorg corrections as updates and deletes.
  • Totals per customer need your record of which wallets are theirs, and period totals need prices at a date, so both are queries in your database.

Option 2: Get crypto portfolio data from a balances and transfers API

Your app calls the Feeds Balances endpoint for the holdings screen and the Transfers endpoint for the activity list, one wallet per request, with dollar values on every row. There’s no pipeline or database to run for the chain data.

When to use a wallet balances and transfers API

An app team without data engineers wants portfolio screens, and the chains your customers use are ones the API covers.

What you’ll need

  • Goldsky Feeds
  • A record of which wallets belong to which customer
  • Storage for statements once they’re issued
  1. Link the customer’s wallets to their profile

    A portfolio covers every wallet a customer owns, so you first need to know which addresses are theirs.

    The customer adds each address, or your app connects it, and you store the address, its chain and the customer ID together. An address saved without its owner shows up as holdings nobody can see, and one saved against the wrong customer shows one person’s money to another.

  2. Record new transfers on the chain

    Holdings change whenever money moves in or out of a wallet, and the chain is where that’s recorded.

    Each transfer lands in a block on its chain. For a short time the newest blocks can be replaced (a reorg), so a transfer seen once can still disappear or move to another block.

  3. Fetch current holdings for the portfolio screen

    Handled by Goldsky Feeds

    The portfolio screen opens on what the customer holds now, usually with a total at the top.

    The lookup has to cover every chain and token the customer holds, including tokens with no market price. Tokens left out make the total look smaller than it is, and the customer sees money missing.

    Feeds returns a wallet’s native and ERC-20 balances across chains from its Balances endpoint, each with a USD value and a total_value_usd for the wallet. Add include_unknown_price=true so tokens without a price still appear.

    Read the balances endpoint reference (opens in a new tab)
  4. Fetch the activity list for the period

    Handled by Goldsky Feeds

    The activity list and the statement show every transfer in and out, with what it was worth then.

    The lookup covers the period the screen or statement shows, in both directions. Without a value at the time of each transfer, the statement can’t show what the customer gained or spent.

    Your app can call the Feeds Transfers endpoint for one wallet with from and to set to the statement period, and each row comes back with amount_usd at the time of the transfer.

    Read the transfers endpoint reference (opens in a new tab)
  5. Value the holdings and build the statement

    Customers read a portfolio in money, and a statement adds up a period: what they held at the start and end, and what moved in between.

    Your system sums holdings per customer across wallets and chains, applies the prices your policy names and works out each period’s totals in your database. Prices and totals change after the fact, so store the figures a statement was issued with instead of recalculating them when the customer opens it again.

  6. Show the portfolio in your app

    The customer sees their holdings and history on a screen you control, behind your own login.

    Your API reads the stored holdings and transfers for the signed-in customer and nothing else. Screens that read the chain for every page view get slower as customers add wallets, and they show a different answer from the statement.

What to know about using a balances and transfers API

  • Your app pulls, so the screen is as fresh as the last call.
  • Balances are current only; holdings at a past date are rebuilt from the transfer history.
  • Dollar values are worked out at request time, so store the figures a statement was issued with.
  • A transfer undone by a reorg stops appearing in responses, with no flag to tell you.

Option 3: Get crypto portfolio data with synced balance and transfer feeds

Feeds pushes balance and transfer rows into your database or to a webhook as they land, so your API serves the portfolio from your own tables without calling out or running a pipeline.

When to sync balance and transfer feeds

You want portfolio data in your own database for local queries or data residency, and the feeds’ ready-made columns are enough for your screens.

What you’ll need

  • Goldsky Feeds
  • A database or webhook endpoint to receive the rows
  • A record of which wallets belong to which customer
  • An API and app screens that read from your database
  1. Link the customer’s wallets to their profile

    A portfolio covers every wallet a customer owns, so you first need to know which addresses are theirs.

    The customer adds each address, or your app connects it, and you store the address, its chain and the customer ID together. An address saved without its owner shows up as holdings nobody can see, and one saved against the wrong customer shows one person’s money to another.

  2. Record new transfers on the chain

    Holdings change whenever money moves in or out of a wallet, and the chain is where that’s recorded.

    Each transfer lands in a block on its chain. For a short time the newest blocks can be replaced (a reorg), so a transfer seen once can still disappear or move to another block.

  3. Sync balances and transfers into your database

    Handled by Goldsky Feeds

    Your screens read from your own tables, so the chain data has to arrive there on its own.

    New balance and transfer rows have to reach your database as they land, with enough detail to tie each to a wallet. A sync that falls behind shows customers yesterday’s holdings.

    Feeds data sync pushes rows from any feed, including Balances and Transfers, to a database you own or a webhook as they land.

    Sync Feeds to your database (opens in a new tab)
  4. Group the rows by customer

    Feed rows are keyed by wallet, and a portfolio is a customer’s view across all of theirs.

    Join the synced rows to your wallet table by address and chain. A wallet that changes owner, or is shared by two profiles, needs a rule here, or its holdings show up twice.

  5. Value the holdings and build the statement

    Customers read a portfolio in money, and a statement adds up a period: what they held at the start and end, and what moved in between.

    Your system sums holdings per customer across wallets and chains, applies the prices your policy names and works out each period’s totals in your database. Prices and totals change after the fact, so store the figures a statement was issued with instead of recalculating them when the customer opens it again.

  6. Show the portfolio in your app

    The customer sees their holdings and history on a screen you control, behind your own login.

    Your API reads the stored holdings and transfers for the signed-in customer and nothing else. Screens that read the chain for every page view get slower as customers add wallets, and they show a different answer from the statement.

What to know about syncing balance and transfer feeds

  • Rows are pushed to you as they land, so nothing in your app polls.
  • Rows arrive in the feeds’ own schema, so your queries read those columns as they are.
  • Goldsky runs the sync; you own the destination and keep it reachable.
  • Grouping rows by customer and adding up periods stay in your database.

Filter spam tokens by streaming transfers to your database

Hide spam and scam tokens from wallet balances and payment flows.

A pipeline Goldsky runs streams token transfers into your database as they happen. Each new token is checked against a spam token list, and your app hides the ones on it.

What you’ll need

  • Goldsky Turbo
  • A database for transfers and token labels
  • A spam token list from a provider, or one you keep from user reports
  • The balance and history service behind your app
  1. An unknown token lands in a user’s wallet

    Anyone can send any token to any wallet, so users receive tokens they never asked for.

    Spam tokens often arrive in bulk sends to many wallets, with names or links that point to scam sites. The token appears in the wallet’s balance unless your app decides to hide it.

  2. Stream token transfers into your database

    Handled by Goldsky Turbo

    You can only label a token once you know it reached a user’s wallet, and from whom.

    Every token transfer, with token, sender, recipient, amount and transaction, has to land in your database as it happens, keyed so a repeated delivery overwrites the same row. A gap in the stream means a spam token can show before you’ve seen it.

    Turbo Pipelines can stream a chain’s decoded erc20_transfers dataset to your database, keyed on each transfer’s id, so corrections from a reorg update the same rows.

    Stream ERC-20 transfers (opens in a new tab)
  3. Classify each token

    Someone has to decide which tokens count as spam, and wallets do it with a list of known spam tokens.

    Each token that reaches a user is matched against the list and marked spam, legitimate or unknown. Let users report a token as spam and correct a wrong label, because a real token marked as spam hides money from its owner.

  4. Hide spam from balances and history

    The point is that users never see the spam next to their real balance.

    Your balance and history service leaves spam tokens out of totals, lists and payment screens, and can keep them behind a “hidden tokens” view. Totals that still count a hidden token show users a balance they can’t find.

What you control

Your team
  • Link the customer’s wallets to their profile
  • Value the holdings and build the statement
  • Show the portfolio in your app

Security and deployment

  • SOC 2 Type IIIndependently audited security controls.
  • Dedicated infrastructureSingle-tenant options for production workloads.
  • Data residencyCloud, on-premises or co-located.

Build crypto portfolio and statement data with Goldsky

We’ll map it to your systems and show you what Goldsky runs, so your team builds the product, not the pipelines underneath it.

© Endless Sky Inc. All rights reserved.

PrivacyTermsSecurity

System status