Embedded wallet balances and history
What are embedded wallet balances and history?
Embedded wallet balances and history are what an app shows a user about the wallet built into it: what it holds now and every transfer in and out, the way a bank app shows an account.
Fintech apps that give each user an embedded wallet need the balance right the moment money moves, because users spend from what the screen says they have.
Goldsky watches each new wallet from the moment it’s created and keeps its transfers and balance current, while the wallet provider, the account records and the app screens stay yours.
You can build it three ways: stream each user’s wallet into your own database with Turbo Pipelines, call the Feeds balances and transfers API when the app opens, or have Feeds sync those rows into your database.
Who shows embedded wallet balances and history?
Payroll and payments apps, card programs and wallet infrastructure firms that give each customer a wallet inside their own product.
How embedded wallet balances work
The diagram follows one user from signing up to seeing their wallet’s balance and history in your app, and shows who does each step. Your setup may differ.
Ways to show embedded wallet balances and history
Changes reach your database as they happen with the pipeline, which watches every user wallet, and with the synced feeds, on their own schema; the API returns balances only when your app calls it.
- Best for
- Many user wallets, balances kept in your 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
- An app team, 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
- Balances in your database, 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
| Usual setupOption 1: Stream to your database | Option 2: Balances and transfers API | Option 3: Synced feeds | |
|---|---|---|---|
| Best for | Many user wallets, balances kept in your database | An app team, one wallet per call | Balances in your database, with no pipeline to define |
| Products | Turbo | Feeds | Feeds |
| What you run | The destination: your database, queue or bucket, or a Postgres database Goldsky hosts | Nothing; you call an endpoint and keep what you need | The destination database or endpoint |
| What you write | Pipeline YAML and SQL; TypeScript transforms when needed | REST requests | Nothing to get the rows; your own SQL to use them |
| Where your data lives | In your own database or systems | Hosted by Goldsky | In your own database or systems |
| How results reach you | Pushed to you | Returned when you call | Pushed to you |
Sign up the user
Every wallet balance in your app belongs to a customer account, so the account comes first.
Your app creates the customer record that the wallet, its balance and its history will hang off. Without a stable account ID, a balance you find can’t be shown to anyone.
Create the user’s embedded wallet
An embedded wallet is one built into your app, so the user holds funds without installing anything else.
Your wallet provider creates the wallet and holds its keys under your policy, then returns its address (the wallet’s account number on the chain). That address has to reach your systems as soon as it exists, or the user’s first deposit arrives before you’re looking.
Add the wallet to your watch list
Handled by Goldsky TurboYou only see activity for wallets you’re watching, so each new one has to go on the list straight away.
The list has to update the moment a wallet is created, without restarting anything. A gap between creating the wallet and watching it means the first deposit can be missed.
With Goldsky, you can keep the watch list in a Turbo Pipelines dynamic table, which lives in a Postgres database. Insert the address and the running pipeline starts matching it, with no redeploy.
Learn about dynamic tables (opens in a new tab)Move funds in and out of the wallet
The balance changes when the user receives money, pays someone or moves funds to another account.
Each transfer is recorded in a block on the chain. The newest blocks can still be replaced for a short time (a reorg), so a transfer the user just made isn’t final yet.
Record each transfer and the new balance
Handled by Goldsky TurboThe app shows both the running balance and the list of transfers behind it, and they have to agree.
Every transfer in or out of a watched wallet is recorded with its token, amount and transaction, and that wallet’s balance is read again at the same block. Reading balances on a timer instead leaves the screen showing an old number after the user has just paid.
In Turbo Pipelines, a SQL transform can keep transfers to or from watched wallets with
Track balances for a set of addresses (opens in a new tab)dynamic_table_check()and read the new balance at that block with_gs_evm_get_balancesor_gs_eth_call, writing both to your database.Correct rows the chain rewrites
Handled by Goldsky TurboWhen the chain replaces its newest blocks (a reorg), a transfer you recorded can disappear or move.
Balance and history have to follow the chain when that happens. Otherwise the user spends money that the chain says they never received.
Goldsky passes reorg corrections through Turbo Pipelines as deletes and updates, and a database sink with a
How reorgs reach your sinks (opens in a new tab)primary_keyapplies them to the rows it wrote.Show the balance and history in the app
The user checks what they have and what they spent, the way they would in a bank app.
Your API serves the stored balance and transfer list for the signed-in user. If the balance and the history come from different sources, they can disagree, and a user who adds up their history and gets a different number calls support.
What to know about streaming embedded wallet balances
- A new wallet goes on the watch list as a row, so it’s followed from its first transfer.
- Changes are pushed to your database, so the app never polls the chain.
- Tables keyed on a primary key take reorg corrections as updates and deletes.
- Goldsky runs the pipeline; you own the database and the API on top of it.
Sign up the user
Every wallet balance in your app belongs to a customer account, so the account comes first.
Your app creates the customer record that the wallet, its balance and its history will hang off. Without a stable account ID, a balance you find can’t be shown to anyone.
Create the user’s embedded wallet
An embedded wallet is one built into your app, so the user holds funds without installing anything else.
Your wallet provider creates the wallet and holds its keys under your policy, then returns its address (the wallet’s account number on the chain). That address has to reach your systems as soon as it exists, or the user’s first deposit arrives before you’re looking.
Store the wallet against the account
To show a balance, your app needs to know which address belongs to which user.
Keep each user’s address, chain and account ID together in your own records. A wallet missing from that table never shows a balance, however much it holds.
Move funds in and out of the wallet
The balance changes when the user receives money, pays someone or moves funds to another account.
Each transfer is recorded in a block on the chain. The newest blocks can still be replaced for a short time (a reorg), so a transfer the user just made isn’t final yet.
Fetch the wallet’s balance
Handled by Goldsky FeedsThe app’s home screen opens on what the user holds now.
The lookup has to cover every chain and token the wallet can hold, including tokens with no market price. A token left out looks like money that vanished.
Feeds’ Balances endpoint returns the wallet’s native and ERC-20 holdings across chains with a USD value for each and a total. Set
Read the balances endpoint reference (opens in a new tab)include_unknown_price=trueto keep tokens that have no price.Fetch the wallet’s transfer history
Handled by Goldsky FeedsUsers check what came in and what went out, the way they’d scan a bank statement.
The history has to show both directions, newest first, with the other party and the value at the time. Transfers have no ID of their own, so storing them means choosing how to tell repeats apart.
With Goldsky, your app can call the Feeds Transfers endpoint for the wallet and page through its native and ERC-20 transfers, newest first, each with
Read the transfers endpoint reference (opens in a new tab)amount_usdat transfer time.Show the balance and history in the app
The user checks what they have and what they spent, the way they would in a bank app.
Your API serves the stored balance and transfer list for the signed-in user. If the balance and the history come from different sources, they can disagree, and a user who adds up their history and gets a different number calls support.
What to know about using a wallet balances and transfers API
- Your app pulls, so the balance is as fresh as the last call.
- Transfers come back without their own ID, so your code decides how to tell a repeat from a second, identical transfer.
- A transfer undone by a reorg stops appearing in responses, with no flag to tell you.
- The response shape is fixed; storing or reshaping it is your code.
Sign up the user
Every wallet balance in your app belongs to a customer account, so the account comes first.
Your app creates the customer record that the wallet, its balance and its history will hang off. Without a stable account ID, a balance you find can’t be shown to anyone.
Create the user’s embedded wallet
An embedded wallet is one built into your app, so the user holds funds without installing anything else.
Your wallet provider creates the wallet and holds its keys under your policy, then returns its address (the wallet’s account number on the chain). That address has to reach your systems as soon as it exists, or the user’s first deposit arrives before you’re looking.
Store the wallet against the account
To show a balance, your app needs to know which address belongs to which user.
Keep each user’s address, chain and account ID together in your own records. A wallet missing from that table never shows a balance, however much it holds.
Move funds in and out of the wallet
The balance changes when the user receives money, pays someone or moves funds to another account.
Each transfer is recorded in a block on the chain. The newest blocks can still be replaced for a short time (a reorg), so a transfer the user just made isn’t final yet.
Sync balances and transfers into your database
Handled by Goldsky FeedsYour app reads from its own tables, so the chain data has to arrive there without being asked for.
New balance and transfer rows have to reach your database as they land, with the wallet address on each. If the sync falls behind, users see a balance that doesn’t include what they just received.
Feeds data sync pushes rows from the Balances and Transfers feeds to a database you own or a webhook, so your app never polls the API.
Sync Feeds to your database (opens in a new tab)Tie each row to its user
Feed rows are keyed by wallet, and the app shows them by user.
Join the synced rows to your wallet table by address and chain. Rows for a wallet you don’t have on file mean a wallet was created without being stored, which is worth an alert of its own.
Show the balance and history in the app
The user checks what they have and what they spent, the way they would in a bank app.
Your API serves the stored balance and transfer list for the signed-in user. If the balance and the history come from different sources, they can disagree, and a user who adds up their history and gets a different number calls support.
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.
- Tying rows to users stays in your database.
What you control
- Your team
- Sign up the user
- Show the balance and history in the app
- Your providers
- Wallet provider
Security and deployment
- SOC 2 Type IIIndependently audited security controls.
- Dedicated infrastructureSingle-tenant options for production workloads.
- Data residencyCloud, on-premises or co-located.
More use cases that show balances and history
- Wallet balances and historyShow customers their balances and transaction history across wallets and chains.
- Crypto portfolio and statement dataShow customers their holdings and history across chains in an app or statement.
- Crypto custody statementsProduce custody statements from onchain balances at a statement date.
- Token vesting and unlock trackingIndex vesting contracts so platforms, custodians and funds can show each grant, what has vested, what was claimed and the next unlock.
Use cases built the same way
- Stablecoin dollar accountsOffer dollar accounts held in stablecoins, with balances and history kept in step with the chain.
- Stablecoin card program operationsWatch card-backing wallets and read balances at authorization time for stablecoin-linked cards.
- Stablecoin card programsDetect stablecoin top-ups to the wallets that back a card program so spend limits update.
- Stablecoin treasury management across chainsSee stablecoin cash across every wallet and chain in one place.
Show embedded wallet balances and history 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.