Skip to content

Commit a73becc

Browse files
committed
rework the main readme for ttp
1 parent 89d3939 commit a73becc

1 file changed

Lines changed: 143 additions & 78 deletions

File tree

  • docs/data/indexers/build-your-own/token-transfer-processor

docs/data/indexers/build-your-own/token-transfer-processor/README.mdx

Lines changed: 143 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,16 @@ sidebar_position: 0
55

66
## Overview
77

8-
The token transfer processor is a [package](https://github.com/stellar/go/tree/ttp-v1.0.0/ingest/processors/token_transfer) which uses the [ingest-sdk](../ingest-sdk/README.mdx) to parse Stellar network transaction data and derive events representing token transfers, mints, burns, clawbacks, and fees.
8+
The Token Transfer Processor (TTP) is a [package](https://github.com/stellar/go/tree/ttp-v1.0.0/ingest/processors/token_transfer) which uses the [ingest-sdk](../ingest-sdk/README.mdx) to parse Stellar network transaction data and derive token transfer events. Before TTP, developers had to manually parse complex ledger data, operation results, and ledger entry changes to understand when and how assets moved between accounts, contracts, and other entities on the network.
99

10-
The token_transfer package consumes Stellar network transaction data and emits [CAP-67, Unified Events](https://stellar.org/protocol/cap-67) which represent all token movements on the network.
10+
Prior to [CAP-67 Unified Events](https://stellar.org/protocol/cap-67), tracking token transfers required significant custom logic to handle different operation types, interpret ledger changes, and reconstruct the flow of assets. CAP-67 introduced a standardized event format that simplifies this process by providing a unified way to represent all token transfer activities.
11+
12+
TTP serves as the implementation bridge for CAP-67, automatically generating these standardized events from Stellar ledger data. It can operate in two modes:
13+
14+
- **Standalone mode**: TTP analyzes operations, operation results, and ledger entry changes to derive transfer events
15+
- **Unified events mode**: TTP reads directly from CAP-67 compliant unified events when available in the ledger data
16+
17+
For more details on operational modes, see the [Modes of Operation](#modes-of-operation) section.
1118

1219
## Key Features
1320

@@ -30,134 +37,192 @@ The token_transfer package consumes Stellar network transaction data and emits [
3037
- Clawback: Asset issuer reclaiming tokens
3138
- Fee: Network fees paid
3239

33-
- Handles muxed account information for compliance with CAP-67 multiplexing support
40+
- Handles muxed account information in compliance with CAP-67 multiplexing support
3441

3542
- Reconciliation for older protocol versions to ensure consistency between operation changes and generated events
3643

37-
## Event Structure
44+
## Types of Events and Modeling
3845

39-
Token transfer events follow the CAP-67 model and a golang binding to the event model is provided as `TokenTransferEvent` in the `token_transfer` package that is generated from this [proto3 definition](https://github.com/stellar/go/blob/ttp-v1.0.0/protos/ingest/processors/token_transfer/token_transfer_event.proto).
46+
TTP generates events based on [protobuf definitions](https://github.com/stellar/go/blob/ttp-v1.0.0/protos/ingest/processors/token_transfer/token_transfer_event.proto) that align closely with the CAP-67 specification. Each event contains metadata and type-specific information structured as follows:
4047

41-
## Chronological Event Ordering
48+
### Event Metadata
4249

43-
As of protocol 22, events in a ledger follow a specific chronological order:
50+
Every token transfer event includes comprehensive metadata to provide context about when and where the event occurred:
4451

45-
1. Fee events from all transactions upfront
46-
2. For each transaction:
52+
| Field | Type | Description |
53+
| --- | --- | --- |
54+
| `ledgerSequence` | `uint32` | The ledger number where this event occurred. This provides chronological ordering across the entire network. |
55+
| `txHash` | `string` | The transaction hash that generated this event. This allows you to trace events back to their originating transaction. |
56+
| `operationIndex` | `uint32*` | The zero-based index of the operation within the transaction that caused this event. This field is `nil` for transaction-level events like fees. |
57+
| `contractAddress` | `string` | The contract address asociated with the asset/token being moved. For classic operations or Stellar Asset Contract Events, this field will be the contractId of the underlying classic asset. This enables integration with Stellar's smart contract ecosystem. |
4758

48-
- Events from each operation within the transaction
49-
- Fee refund for the transaction (if any)
59+
:::note
5060

51-
## Smart Contract Events
61+
The `contractAddress` field is particularly important for DeFi applications as it provides the bridge between classic Stellar assets and their smart contract representations.
5262

53-
This processor supports both deriving events from classic operations and parsing smart contract events emitted in the ledger.
63+
:::
5464

55-
For smart contract events, the parsing logic is as follows:
65+
### Event Types
5666

57-
- Check if the smart contract event is a SEP-41 compliant event.
58-
- If yes, attempt to further validate if these are Stellar Asset Contract (SAC) tokens
67+
TTP generates five distinct types of token transfer events, each modeling different aspects of asset movement:
5968

60-
## Usage
69+
| Event Type | Description | Key Fields | When Generated |
70+
| --- | --- | --- | --- |
71+
| **Transfer** | Asset movement between two entities | `from`, `to`, `amount`, `asset`, `toMuxedInfo` | When assets move between accounts, contracts, or other entities |
72+
| **Mint** | Asset creation by the issuer | `to`, `amount`, `asset`, `toMuxedInfo` | When an issuer creates new tokens or when assets are sent from the issuer |
73+
| **Burn** | Asset destruction to the issuer | `from`, `amount`, `asset` | When assets are returned to the issuer for destruction |
74+
| **Clawback** | Forced asset recovery by issuer | `from`, `amount`, `asset` | When an issuer uses clawback operations to recover assets |
75+
| **Fee** | Network fee payment or refund | `account`, `amount` | For all transaction fees and Soroban fee refunds |
6176

62-
### Creating a Processor
77+
:::note
6378

64-
<CodeExample>
79+
The `toMuxedInfo` field is included in Transfer and Mint events when the destination uses a muxed account (M-address) and/or when transaction-level memo is set (in the case of non smart contract transactions), providing additional routing information.
6580

66-
`````go
67-
// Create a processor with the network passphrase
68-
processor := token_transfer.NewEventsProcessor(networkPassphrase)
81+
:::
6982

70-
// Optionally disable contract events
71-
processor := token_transfer.NewEventsProcessor(networkPassphrase, token_transfer.DisableContractEvents) ````
72-
`````
83+
For more information on what to expect in the `toMuxedInfo` field, please refer to [this](https://github.com/stellar/stellar-protocol/blob/master/core/cap-0067.md#prohibit-the-transaction-memo-and-muxed-source-accounts-from-being-set-on-soroban-transactions) section in CAP-67.
7384

74-
</CodeExample>
85+
## Functions
7586

76-
### Processing a Ledger
87+
TTP provides three main processing functions that operate at different levels of granularity:
7788

78-
<CodeExample>
89+
### EventsFromLedger
7990

8091
```go
81-
// Process all events in a ledger
82-
var ledgerCloseMeta xdr.LedgerCloseMeta
83-
...
84-
...
85-
events, err := processor.EventsFromLedger(ledgerCloseMeta)
92+
func (p *EventsProcessor) EventsFromLedger(lcm xdr.LedgerCloseMeta) ([]*TokenTransferEvent, error)
8693
```
8794

88-
</CodeExample>
95+
This function processes an entire ledger and returns a flattened list of `TokenTransferEvent` objects. The order of events in the returned slice represents the chronological ordering of debits, credits, and fees as they were applied to accounts, trustlines, and contracts during ledger processing.
8996

90-
### Processing a Transaction
97+
The chronological ordering is critical for applications that need to maintain accurate balance tracking or audit trails. For detailed information about how events are ordered, see the [Event Ordering](#event-ordering) section.
9198

92-
<CodeExample>
99+
### EventsFromTransaction
93100

94101
```go
95-
// Process events from a transaction
96-
var tx ingest.LedgerTransaction
97-
...
98-
...
99-
txEvents, err := processor.EventsFromTransaction(tx)
100-
// txEvents.FeeEvents contains fee-related events
101-
// txEvents.OperationEvents contains operation-related events
102+
func (p *EventsProcessor) EventsFromTransaction(tx ingest.LedgerTransaction) (TransactionEvents, error)
102103
```
103104

104-
</CodeExample>
105+
This function processes a single transaction and returns a `TransactionEvents` structure that separates fee-related events from operation-related events:
106+
107+
- `FeeEvents`: Contains fee charges and refunds associated with the transaction
108+
- `OperationEvents`: Contains all events generated by the transaction's operations
105109

106-
### Processing an Operation
110+
This separation is useful when you need to handle fees differently from operational transfers, such as for accounting or analytics purposes.
107111

108-
<CodeExample>
112+
### EventsFromOperation
109113

110114
```go
111-
// Process events from a specific operation
112-
var tx ingest.LedgerTransaction
113-
var op xdr.Operation
114-
var opResult xdr.OperationResult
115-
...
116-
...
117-
events, err := processor.EventsFromOperation(tx, opIndex, op, opResult)
115+
func (p *EventsProcessor) EventsFromOperation(tx ingest.LedgerTransaction, opIndex uint32, op xdr.Operation, opResult xdr.OperationResult) ([]*TokenTransferEvent, error)
118116
```
119117

120-
</CodeExample>
118+
This function processes a single operation within a transaction and returns a list of events generated by that specific operation. This granular approach is useful for applications that need to analyze or react to specific types of operations.
119+
120+
## Modes of Operation
121121

122-
### Event Verification
122+
TTP can operate in two distinct modes depending on how the ledger data was generated and what information is available:
123123

124-
The package includes functionality to verify the consistency of events with ledger changes:
124+
### Default Mode (Recommended)
125125

126-
<CodeExample>
126+
In default mode, TTP analyzes three sources of information to derive token transfer events:
127+
128+
- **Operations**: The actual operations submitted in transactions
129+
- **Operation Results**: The success/failure results of each operation
130+
- **Ledger Entry Changes**: The actual changes made to the ledger state
131+
132+
This mode works with all Stellar ledgers regardless of how they were generated or which stellar-core version produced them. It is the safest and most compatible option.
127133

128134
```go
129-
// Verify events for a ledger
130-
err := token_transfer.VerifyEvents(ledgerCloseMeta, networkPassphrase)
135+
// Default mode - works with all ledgers
136+
processor := token_transfer.NewEventsProcessor(networkPassphrase)
131137
```
132138

133-
</CodeExample>
139+
### Unified Events Stream Mode
140+
141+
In unified events stream mode, TTP reads token transfer events directly from the unified events stream embedded in the ledger data. This mode is more efficient but requires ledgers that were generated with specific stellar-core configuration flags.
142+
143+
```go
144+
// Unified events mode - only for specially configured ledgers
145+
processor := token_transfer.NewEventsProcessorForUnifiedEvents(networkPassphrase)
146+
```
147+
148+
:::caution
149+
150+
Only use unified events stream mode if you are certain that your ledgers contain unified events. These ledgers must be generated by stellar-core with both `EMIT_CLASSIC_EVENTS=true` and `BACKFILL_STELLAR_ASSET_EVENTS=true` configuration flags enabled. TTP cannot dynamically determine whether a ledger contains unified events or not. If you configure TTP for unified events mode and then feed it ledgers without unified events, processing will fail with errors.
151+
152+
:::
153+
154+
**When in doubt, always use the default mode**, as it works reliably with all ledger types.
155+
156+
## Fee Event Types
157+
158+
TTP generates fee events to track network fees associated with transaction processing. Understanding the different types of fee events is important for accurate accounting:
159+
160+
### Fee Charges
161+
162+
Fee events are generated for all transactions, whether they succeed or fail. These represent the network fees that accounts pay to submit transactions to the Stellar network.
163+
164+
- **Present for**: Every transaction
165+
- **Amount representation**: Positive values indicating fees paid
166+
- **Asset**: Always XLM (Stellar's native asset)
167+
168+
### Fee Refunds
134169

135-
## Implementation Details
170+
Fee refund events are generated only for Soroban (smart contract) transactions, and only when there are unused resources that qualify for a refund.
136171

137-
The processor handles various special cases:
172+
- **Present for**: Soroban transactions with unused resource fees
173+
- **Amount representation**: Negative values to indicate money being returned
174+
- **Asset**: Always XLM
175+
- **Event type**: Uses the same `Fee` event type, distinguished by the negative amount
138176

139-
1. **Minting and Burning**: Determined by checking if the source or destination is the asset issuer
140-
2. **Liquidity Pools**: Specialized handling for pool deposits, withdrawals, and revoked trustlines
141-
3. **Claimable Balances**: Tracks creation, claiming, and clawback operations
142-
4. **Path Payments**: Processes complex paths with multiple asset conversions
143-
5. **Muxed Accounts**: Preserves multiplexed account information in relevant events
144-
6. **Soroban Fees**: Special handling for Soroban transaction fees and refunds
177+
:::note
145178

146-
## Event Reconciliation (Legacy Protocol Support)
179+
TTP uses negative amounts in fee events to represent refunds rather than creating a separate refund event type. This approach maintains consistency with the CAP-67 specification while clearly indicating the direction of the fee transaction.
147180

148-
For ledgers with protocol version less than 8, the processor performs additional reconciliation to ensure consistency between observed balance changes and emitted events. This helps with retroactive event generation for older operations.
181+
:::
182+
183+
## Event Ordering
184+
185+
The order of events returned by TTP depends on the Stellar protocol version that was active when the ledger was created. This ordering is crucial for maintaining accurate chronological records of asset movements.
186+
187+
### Pre-Protocol 23 Ordering
188+
189+
Before Protocol 23, events follow this chronological pattern:
190+
191+
```
192+
All Fee Events (from all transactions)
193+
194+
For each transaction in ledger:
195+
- Operation Events (from all operations in the transaction)
196+
- Fee Refund Event (if applicable, immediately after operation events)
197+
```
198+
199+
In this ordering, fee refunds appear immediately after the operation events for each individual transaction.
200+
201+
### Protocol 23+ Ordering
202+
203+
Starting with Protocol 23, events follow this chronological pattern:
204+
205+
```
206+
All Fee Events (from all transactions)
207+
208+
All Operation Events (from all transactions, maintaining transaction and operation order)
209+
210+
All Fee Refund Events (from all transactions)
211+
```
212+
213+
In this newer ordering, all fee refunds are grouped together at the end, after all transactions have been processed.
214+
215+
:::note
216+
217+
TTP automatically detects the protocol version and applies the correct ordering rules. You don't need to configure this manually, but understanding the ordering differences is important for applications that depend on event sequence.
218+
219+
:::
220+
221+
The chronological ordering ensures that when you process events in the order returned by TTP, you're following the exact sequence in which debits and credits were applied to accounts during ledger processing. This is essential for maintaining accurate balance calculations and audit trails.
149222

150223
## References
151224

152225
- [CAP-67: Unified Events](https://stellar.org/protocol/cap-67)
153226
- [SEP-41: Asset Token Contract Specification](https://stellar.org/protocol/sep-41)
154227
- [CAP-38: Automated Market Makers](https://stellar.org/protocol/cap-38)
155228
- [SEP-35: ID Scheme for Stellar Operations](https://stellar.org/protocol/sep-35)
156-
157-
## Testing
158-
159-
The package includes extensive tests for all supported operations and edge cases. Run tests with:
160-
161-
```bash
162-
go test ./ingest/processors/token_transfer -v
163-
```

0 commit comments

Comments
 (0)