Skip to main content

What are crypto custody statements?

Crypto custody statements are the periodic reports a custodian sends each client listing the digital assets held for them at a statement date and the transactions in the period, also called digital asset custody reporting.

Custodian banks issue them to clients and auditors who rely on the figures, so every balance has to be the one that stood at the cutoff, not today’s, and has to tie back to what moved.

Goldsky keeps every transfer in and out of your client wallets in your warehouse, turns the statement time into a block on each chain and reads every balance at it, while the wallet list, the prices and the statements stay with you.

You can build it two ways: keep each client wallet’s transfer history in your warehouse with Turbo Pipelines and read balances at the statement block, or read balances at the statement block alone with Feeds and Edge RPC.

Who sends crypto custody statements?

Custodian banks, trust companies, exchanges and wallet infrastructure providers that hold digital assets for institutional and private clients, and for public holders such as a state’s bitcoin reserve.

How crypto custody statements are produced

The diagram follows one statement period from closing the period to sending clients their holdings as of the date, and shows who does each step. Your setup may differ.

Your business, step 1: Close the periodThe statement date arrives
Your business, step 2: CustodianExport client walletsWallet list from your custody platform
Goldsky, step 3: FeedsFind the blockStatement time mapped to a block per chain
Goldsky, step 4: EdgeRead balances at itExact holdings for each client wallet
Your business, step 6: Tie balances to activityEach balance checked against its transfers
Goldsky, step 5: TurboKeep each wallet’s transfersEvery transfer in and out, in your warehouse
Your business, step 7: Value each holdingYour pricing source, as of the date
Your business, step 8: Send the statementsHoldings at the date, plus the period’s transactions
  • Goldsky
  • Your provider

Ways to produce crypto custody statements

Both read each balance at the statement block, but only the pipeline also keeps every transfer between statements, so you can list the period’s activity and tie each closing balance back to it.

Best for
Statements with activity, tied back to every transfer
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
Known custody wallets, once per statement period
Products
FeedsEdge
What you run
Your own client code
What you write
JSON-RPC calls, and the decoding of what comes back
Where your data lives
Read from the chain
How results reach you
Returned when you call

Option 1: Produce crypto custody statements from a transfer history and reads at a date

A pipeline keeps every transfer in and out of your client wallets in your warehouse. At each statement date you find the block for the cutoff, read every balance at it, and check the balance against the history.

When to keep a transfer history for custody statements

Statements list the period’s activity as well as closing holdings, or your auditors expect each balance tied back to the transfers that produced it.

What you’ll need

  • Goldsky Turbo
  • Goldsky Feeds
  • Goldsky Edge
  • A custody platform that exports client wallets
  • A warehouse for the transfer history
  • A pricing source for values at the statement date
  • A statement generator
  1. Set the statement date and time

    A custody statement shows what each client held at one moment, so everyone has to agree on that moment first.

    Your operations team fixes the cutoff, including its time zone, for every chain the statement covers. A statement taken at midnight in one zone and read as midnight in another shows holdings from the wrong hours.

  2. Export the client wallets from custody

    The statement covers every address you hold for each client, and the custody platform is the record of which those are.

    Export each client’s addresses and chains as of the statement date. A wallet opened or closed during the period and left out of the export is missing from the client’s statement, with nothing on the page to say so.

  3. Find the block at the statement time on each chain

    Handled by Goldsky Feeds

    Chains count time in blocks, so the statement time has to become a block number before you can read anything at it.

    Each chain needs the last block at or before the cutoff, found separately because chains produce blocks at different rates. Using the first block after the cutoff includes transfers that happened after the statement date.

    The Feeds Blocks endpoint returns the newest block at or before a time when you pass timestamp_lte with sort=number_desc and limit=1, one request per chain.

    Turn a timestamp into a block (opens in a new tab)
  4. Read each balance at that block

    Handled by Goldsky Edge

    The statement has to show what each wallet held at the cutoff, even when it’s produced days later.

    Every token balance is read as it stood at the chosen block, not as it stands today. Reading current balances for a past date moves every transfer since the cutoff onto the statement.

    With Goldsky, you can send eth_call to Edge RPC with the token’s balanceOf call and the statement block as blockNumber, so each read returns the balance at that block. Native balances come from eth_getBalance at the same block.

    Read contract state at a block (opens in a new tab)
  5. Keep each client wallet’s transfer history

    Handled by Goldsky Turbo

    A statement often lists what moved in the period, and the history is how a closing balance is explained.

    Every transfer in and out of every client wallet has to be in your warehouse, from before the first statement to now. Gaps in the history leave balances you can read but can’t account for.

    With Goldsky, a Turbo Pipelines pipeline can match transfers against a dynamic table of client addresses and write them to a warehouse sink such as ClickHouse, keyed on each transfer’s id.

    Choose a warehouse sink (opens in a new tab)
  6. Tie each balance to the transfer history

    A balance that matches the sum of its transfers is one you can explain to a client or an auditor.

    For each wallet, your warehouse compares the sum of transfers up to the statement block with the balance read at it; a gap means a missing transfer, the wrong block or a token that changes balances without transfers. Airdrops and token migrations that reach client wallets show up here too, and your custody terms decide whether they go on the statement.

  7. Value each holding as of the statement date

    Clients and auditors expect a value next to each holding, taken at the same moment as the balance.

    Your pricing source, the one your valuation policy names, supplies each asset’s price at the cutoff. A price from today, or from the last time the token moved, gives a value that doesn’t match the date printed on the statement.

  8. Issue the statements

    Each client receives a record of what you held for them, which they and their auditors rely on.

    Store each statement with the block numbers, balances and prices it was built from before sending it. When a client questions a figure months later, you can show where it came from without rebuilding it.

What to know about keeping a transfer history for statements

  • The pipeline runs all the time, so the history is there when the period closes.
  • The balance read at the block and the sum of transfers up to it should agree; a gap is a break to explain before statements go out.
  • Valuing holdings at the date stays with your pricing source.
  • Goldsky runs the pipeline; you own the warehouse and the statements.

Option 2: Produce crypto custody statements by reading balances at a date

At each statement date you look up the block for the cutoff on every chain, then read each client wallet’s balances at that block. Nothing runs between statements.

When to read balances at a date for custody statements

You hold a known set of client wallets and issue holdings statements once a period, without listing every transfer in between.

What you’ll need

  • Goldsky Feeds
  • Goldsky Edge
  • A custody platform that exports client wallets
  • A pricing source for values at the statement date
  • A statement generator
  1. Set the statement date and time

    A custody statement shows what each client held at one moment, so everyone has to agree on that moment first.

    Your operations team fixes the cutoff, including its time zone, for every chain the statement covers. A statement taken at midnight in one zone and read as midnight in another shows holdings from the wrong hours.

  2. Export the client wallets from custody

    The statement covers every address you hold for each client, and the custody platform is the record of which those are.

    Export each client’s addresses and chains as of the statement date. A wallet opened or closed during the period and left out of the export is missing from the client’s statement, with nothing on the page to say so.

  3. Find the block at the statement time on each chain

    Handled by Goldsky Feeds

    Chains count time in blocks, so the statement time has to become a block number before you can read anything at it.

    Each chain needs the last block at or before the cutoff, found separately because chains produce blocks at different rates. Using the first block after the cutoff includes transfers that happened after the statement date.

    The Feeds Blocks endpoint returns the newest block at or before a time when you pass timestamp_lte with sort=number_desc and limit=1, one request per chain.

    Turn a timestamp into a block (opens in a new tab)
  4. Read each balance at that block

    Handled by Goldsky Edge

    The statement has to show what each wallet held at the cutoff, even when it’s produced days later.

    Every token balance is read as it stood at the chosen block, not as it stands today. Reading current balances for a past date moves every transfer since the cutoff onto the statement.

    Edge RPC answers eth_call at any block you name, so a balanceOf call with the statement block returns each token balance as it stood then; eth_getBalance does the same for the native token.

    Read contract state at a block (opens in a new tab)
  5. Value each holding as of the statement date

    Clients and auditors expect a value next to each holding, taken at the same moment as the balance.

    Your pricing source, the one your valuation policy names, supplies each asset’s price at the cutoff. A price from today, or from the last time the token moved, gives a value that doesn’t match the date printed on the statement.

  6. Issue the statements

    Each client receives a record of what you held for them, which they and their auditors rely on.

    Store each statement with the block numbers, balances and prices it was built from before sending it. When a client questions a figure months later, you can show where it came from without rebuilding it.

What to know about reading balances at a date

  • Nothing runs between statements; each one is a batch of lookups and reads.
  • You get closing holdings, not the transfers that led to them.
  • Every token contract you hold is read on its own, so the token list has to be complete.
  • Valuing holdings at the date stays with your pricing source.

What you control

Your team
  • Set the statement date and time
  • Tie each balance to the transfer history
  • Value each holding as of the statement date
  • Issue the statements
Your providers
  • Custodian

Security and deployment

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

Produce crypto custody statements 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