Developers
Author
Simon Chow
Publishing date
Have you ever wondered what happens under the hood when a transaction or smart contract executes? Not the Wasm bytecode or instruction, but things like:
Good news. CAP-67 introduces a single, structured event stream to get this exact information for every token-value movement on Stellar, classic and smart contract alike.
Today, token movements on Stellar are tracked using different methods: non-smart contract operations rely on computing differences in ledger state, while Soroban smart contracts emit their own event logs. This split forces anyone who wants the full picture to juggle multiple data sources with overly complex logic to merge these data streams.
Let’s walk through a “simple” USDC example. Imagine you need to trace every movement of USDC for an account. They execute a straightforward payment, a multi-step path payment, and a DeFi Protocol swap, and you want to know the account holdings at each stage:
To get the full picture you must:
That’s three separate pipelines that you have to stitch together. Yuck!
All token value movements now flow through one stream of events:
You no longer need custom scraping logic to track token movements. All you need to do is aggregate the above events for the token you want to track.
For example, calculating total circulating supply of a token is as easy as:
SUM(token mint events) - SUM(token burn events)
-- Total circulating supply of USDC
SELECT
SUM(CASE WHEN topic = 'mint' THEN $value.amount ELSE 0 END) -
SUM(CASE WHEN topic = 'burn' THEN $value.amount ELSE 0 END)
AS circulating_supply
FROM stellar_events
WHERE asset = 'USDC'
Here are concrete examples of the events you’ll see. The exact event format for operations can be found in CAP-67
For transfer events, the order of the addresses denotes the sender and receiver. The first address in the topic represents the source account, from, that is sending the asset. The second address is the destination, or to. Stellar assets details will be found in the optional 4th topic, string.
Transfer with SAC (Stellar Asset Contract)
ContractEventXDR
{
"ext": "v0",
"contract_id": "CA...6LF5",
"type_": "contract",
"body": {
"v0": {
"topics": [
{
"symbol": "transfer"
},
{
"address": "GC...F33H"
},
{
"address": "CA...NIBU"
},
{
"string": "USDC:GA..AGER"
}
],
"data": {
"i128": "10000000"
}
}
}
}
Transfer with a liquidity pool
CAP-67 introduces a new SCAddressType for liquidity pool and claimable balances. Liquidity pool addresses will start with “L,” and claimable balances will follow the same convention with “B”. In this example, the from address is a liquidity pool using the new SCAddressType:
ContractEventXDR
{
"ext": "v0",
"contract_id": "CA...6LF5",
"type_": "contract",
"body": {
"v0": {
"topics": [
{
"symbol": "transfer"
},
{
"address": "LC...F33H"
},
{
"address": "CA...NIBU"
},
{
"string": "USDC:GA..AGER"
}
],
"data": {
"i128": "10000000"
}
}
}
}
Transfer with a contract token
Note that the “asset” is omitted. Custom contracts don’t natively have the concept of an asset_code:asset_issuer. The “asset” is represented by the contract_id
ContractEventXDR
{
"ext": "v0",
"contract_id": "CA...6LF5",
"type_": "contract",
"body": {
"v0": {
"topics": [
{
"symbol": "transfer"
},
{
"address": "GC...F33H"
},
{
"address": "CA...NIBU"
}
],
"data": {
"i128": "10000000"
}
}
}
}
Every value movement–whether it’s simple transfers between Stellar accounts, smart contract events, liquidity-pool deposits and withdrawals, or claimable balance actions–flows through this unified format. You’ll never miss a step in a token’s journey again.
At the end of the day, nothing really changes for the final end user. A payment is still a payment.
This change is important because it is now infinitely simpler for backend developers and users to track token value movement holistically on the network regardless of where the operation originated.
A unified event stream makes it so:
It just makes everything we love easier to do. Visibility, interoperability, security, and trust. For full P23 release details, check out the Protocol 23 Announcement and corresponding Upgrade Guide.