Skip to content

Commit eb87bd6

Browse files
committed
Address code review comments
1 parent de180bd commit eb87bd6

4 files changed

Lines changed: 46 additions & 84 deletions

File tree

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

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

66
## Overview
77

8-
The Token Transfer Processor (TTP) is a [Go 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.
8+
The Token Transfer Processor (TTP) is a [Go 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 value moved between accounts, contracts, and other entities on the network.
99

1010
Prior to [CAP-67 Unified Events][cap67], 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.
1111

12-
TTP serves provides a facade to CAP-67, automatically generating these standardized events from Stellar ledger data. It can operate in two modes:
12+
TTP serves as a facade to CAP-67, automatically generating these standardized events from Stellar ledger data. It can operate in two modes:
1313

1414
- **Standalone mode**: TTP analyzes operations, operation results, and ledger entry changes to derive transfer events
1515
- **Unified events mode**: TTP reads directly from CAP-67 compliant unified events when available in the ledger data
@@ -18,7 +18,7 @@ For more details on operational modes, see the [Modes of Operation](#modes-of-op
1818

1919
## Key Features
2020

21-
- Processes all classic and [SEP-41][sep41] token movements from classic operations and smart contract invocations:
21+
- Captures token movements resulting from:
2222

2323
- Simple payments
2424
- Path payments
@@ -28,7 +28,8 @@ For more details on operational modes, see the [Modes of Operation](#modes-of-op
2828
- Claimable balance operations
2929
- Liquidity pool operations
3030
- Clawback operations
31-
- Events from smart contract transactions - Stellar Asset Contract events + SEP-41 compliant token events
31+
- Stellar Asset Contract events
32+
- [SEP-41][sep41] compliant token events
3233

3334
- Generates CAP-67 standardized token events:
3435

@@ -106,7 +107,7 @@ For events from classic transactions and SAC events from smart contract transact
106107

107108
:::
108109

109-
## Go Usage
110+
## Go API Overview
110111

111112
TTP provides three distinct functions which derive events from different levels of granularity from the underlying Stellar network data.
112113

@@ -148,15 +149,15 @@ This function processes a single operation within a transaction and returns a li
148149

149150
## Modes of Operation
150151

151-
TTP can operate in two distinct modes depending on how the ledger data was generated and what information is available:
152+
TTP can operate in two distinct modes depending on how the ledger data was generated and what information is available.
152153

153154
### Default Mode (Recommended)
154155

155156
In default mode, TTP analyzes three sources of information to derive token transfer events:
156157

157-
- **Operations**: The actual operations submitted in transactions
158+
- **Operations**: The operations submitted in transactions
158159
- **Operation Results**: The success/failure results of each operation
159-
- **Ledger Entry Changes**: The actual changes made to the ledger state
160+
- **Ledger Entry Changes**: The changes made to the ledger state
160161

161162
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.
162163

@@ -174,9 +175,11 @@ In unified events stream mode, TTP reads token transfer events directly from the
174175
processor := token_transfer.NewEventsProcessorForUnifiedEvents(networkPassphrase)
175176
```
176177

178+
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.
179+
177180
:::caution
178181

179-
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 provide it ledgers without unified events, TTP will silently produce no events.
182+
If you configure TTP for unified events mode and then provide it ledgers without unified events, TTP will silently produce no events.
180183

181184
:::
182185

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

Lines changed: 19 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,12 @@ This section contains examples of how Token Transfer Processor can be used in yo
77

88
## Prerequisites
99

10-
Some of the examples listed here might invoke the `stellar-core` binary. Refer [this section](../../../ingest-sdk/developer_guide/ledgerbackends/captivecore.mdx) for more details on how to compile `stellar-core` for your platform.
11-
1210
```
1311
//filename: go.mod
1412
1513
require (
14+
// This currently points to a RC release of Protocol-23.
15+
// Please update it to use the latest stable version once P23 is released to pubnet.
1616
github.com/stellar/go horizonclient-v23.0.0-rc
1717
)
1818
@@ -32,12 +32,13 @@ package main
3232
import (
3333
"context"
3434
"fmt"
35-
"github.com/sirupsen/logrus"
35+
3636
"github.com/stellar/go/ingest/ledgerbackend"
37-
"github.com/stellar/go/network"
37+
"github.com/stellar/go/processors/token_transfer"
3838
"github.com/stellar/go/support/log"
3939
"github.com/stellar/go/xdr"
40-
"os"
40+
41+
"google.golang.org/protobuf/encoding/protojson"
4142
)
4243

4344
func panicIf(err error) {
@@ -46,51 +47,29 @@ func panicIf(err error) {
4647
}
4748
}
4849

49-
// This example runs a captive core instance to get a ledger.
50-
// You can just as easily replace it with a BufferedStorageBackend to read from GCS.
51-
func fetchLedger(ledgerSeq uint32, unifiedEventsEnabled bool) xdr.LedgerCloseMeta {
52-
archiveURLs := network.PublicNetworkhistoryArchiveURLs
53-
networkPassphrase := network.PublicNetworkPassphrase
54-
captiveCoreToml, err := ledgerbackend.NewCaptiveCoreToml(ledgerbackend.CaptiveCoreTomlParams{
55-
EmitUnifiedEvents: unifiedEventsEnabled,
56-
NetworkPassphrase: networkPassphrase,
57-
HistoryArchiveURLs: archiveURLs,
58-
})
59-
panicIf(err)
60-
61-
config := ledgerbackend.CaptiveCoreConfig{
62-
// Change these based on your environment:
63-
BinaryPath: "/Users/karthik/WS/stellar-core-2/src/stellar-core",
64-
NetworkPassphrase: networkPassphrase,
65-
HistoryArchiveURLs: archiveURLs,
66-
Toml: captiveCoreToml,
67-
}
50+
// fetchLedgerFromRPC retrieves a ledger using RPCLedgerBackend
51+
func fetchLedgerFromRPC(ledgerSeq uint32) xdr.LedgerCloseMeta {
52+
ctx := context.Background()
6853

69-
// Log Captive Core straight to stdout by default
70-
if config.Log == nil {
71-
config.Log = log.New()
72-
config.Log.SetOutput(os.Stdout)
73-
config.Log.SetLevel(logrus.ErrorLevel)
74-
}
54+
// Using a publicly hosted RPC instance
55+
endpoint := "https://mainnet.sorobanrpc.com"
7556

76-
// Prepare backend connection
77-
ctx := context.Background()
78-
backend, err := ledgerbackend.NewCaptive(config)
79-
panicIf(err)
57+
// Configure the RPC Ledger Backend
58+
backend := ledgerbackend.NewRPCLedgerBackend(ledgerbackend.RPCLedgerBackendOptions{
59+
RPCServerURL: endpoint,
60+
})
8061
defer backend.Close()
8162

82-
fmt.Printf("Fetching ledgerSequence: %v\n", ledgerSeq)
83-
// Prepare and retrieve the ledger
84-
err = backend.PrepareRange(ctx, ledgerbackend.BoundedRange(ledgerSeq, ledgerSeq))
85-
panicIf(err)
63+
// Prepare an unbounded range starting from the latest ledger
64+
if err := backend.PrepareRange(ctx, ledgerbackend.BoundedRange(ledgerSeq, ledgerSeq)); err != nil {
65+
log.Fatalf("Failed to prepare range: %v", err)
66+
}
8667

8768
ledger, err := backend.GetLedger(ctx, ledgerSeq)
8869
panicIf(err)
89-
9070
return ledger
9171
}
9272

93-
// Helper function to print the protobuf event.
9473
func printProtoEvent(event *token_transfer.TokenTransferEvent) {
9574
jsonBytes, _ := protojson.MarshalOptions{
9675
Multiline: true,
@@ -100,7 +79,6 @@ func printProtoEvent(event *token_transfer.TokenTransferEvent) {
10079
fmt.Printf("### Event Type : %v\n", event.GetEventType())
10180
fmt.Println(string(jsonBytes))
10281
}
103-
10482
```
10583

10684
</CodeExample>

docs/data/indexers/build-your-own/processors/token-transfer-processor/examples/event_stats.mdx

Lines changed: 5 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -12,33 +12,20 @@ package main
1212

1313
import (
1414
"fmt"
15+
"strings"
16+
1517
"github.com/stellar/go/network"
1618
"github.com/stellar/go/processors/token_transfer"
17-
"log"
18-
"strings"
1919
)
2020

2121
func main() {
2222
ledgerSeq := uint32(58155263)
23-
24-
// Toggle this flag to read from ledgerEntrychanges or from P23 unified events stream
25-
unifiedEventsEnabled := false
26-
27-
ledger := fetchLedger(ledgerSeq, unifiedEventsEnabled)
28-
29-
var ttp *token_transfer.EventsProcessor
30-
31-
if unifiedEventsEnabled {
32-
ttp = token_transfer.NewEventsProcessorForUnifiedEvents(network.PublicNetworkPassphrase)
33-
} else {
34-
ttp = token_transfer.NewEventsProcessor(network.PublicNetworkPassphrase)
35-
}
23+
ledger := fetchLedgerFromRPC(ledgerSeq)
24+
ttp := token_transfer.NewEventsProcessor(network.PublicNetworkPassphrase)
3625

3726
// Process events from a single ledger
3827
events, err := ttp.EventsFromLedger(ledger)
39-
if err != nil {
40-
log.Fatal("Error processing ledger:", err)
41-
}
28+
panicIf(err)
4229

4330
// Statistics counters
4431
var transferCount, mintCount, burnCount, clawbackCount, feeCount, refundCount int

docs/data/indexers/build-your-own/processors/token-transfer-processor/examples/filter_events.mdx

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ package main
2727

2828
import (
2929
"fmt"
30-
"github.com/stellar/go/xdr"
3130
"io"
3231
"log"
3332
"strings"
@@ -36,6 +35,7 @@ import (
3635
"github.com/stellar/go/ingest"
3736
"github.com/stellar/go/network"
3837
"github.com/stellar/go/processors/token_transfer"
38+
"github.com/stellar/go/xdr"
3939
)
4040

4141
// FilterOptions defines the filtering criteria
@@ -47,14 +47,9 @@ type FilterOptions struct {
4747
}
4848

4949
// filterEvents processes a ledger and returns events matching the filter criteria
50-
func filterEvents(ledger xdr.LedgerCloseMeta, unifiedEventsEnabled bool, filter FilterOptions) {
50+
func filterEvents(ledger xdr.LedgerCloseMeta, filter FilterOptions) {
5151

52-
var ttp *token_transfer.EventsProcessor
53-
if unifiedEventsEnabled {
54-
ttp = token_transfer.NewEventsProcessorForUnifiedEvents(network.PublicNetworkPassphrase)
55-
} else {
56-
ttp = token_transfer.NewEventsProcessor(network.PublicNetworkPassphrase)
57-
}
52+
ttp := token_transfer.NewEventsProcessor(network.PublicNetworkPassphrase)
5853

5954
// Create transaction reader
6055
txReader, err := ingest.NewLedgerTransactionReaderFromLedgerCloseMeta(
@@ -179,26 +174,25 @@ func matchesAsset(event *token_transfer.TokenTransferEvent, asset xdr.Asset) boo
179174

180175
func main() {
181176
ledgerSeq := uint32(58155263)
182-
unifiedEventsEnabled := true
183177

184-
ledger := fetchLedger(ledgerSeq, unifiedEventsEnabled)
178+
ledger := fetchLedgerFromRPC(ledgerSeq)
185179

186180
// Example 1: Filter by event type only
187181
fmt.Println("=== Example 1: Only Transfer Events ===")
188-
filterEvents(ledger, unifiedEventsEnabled, FilterOptions{
182+
filterEvents(ledger, FilterOptions{
189183
EventType: "transfer",
190184
})
191185

192186
// Example 2: Filter by custom token (asset code + issuer)
193187
fmt.Println("\n=== Example 2: Only USDC Events ===")
194-
filterEvents(ledger, unifiedEventsEnabled, FilterOptions{
188+
filterEvents(ledger, FilterOptions{
195189
AssetCode: "USDC",
196190
Issuer: "GA5ZSEJYB37JRC5AVCIA5MOP4RHTM335X2KGX3IHOJAPP5RE34K4KZVN",
197191
})
198192

199193
// Example 3: Filter by event type + contract ID
200194
fmt.Println("\n=== Example 3: Transfer Events from Specific Contract (USDC in this case) ===")
201-
filterEvents(ledger, unifiedEventsEnabled, FilterOptions{
195+
filterEvents(ledger, FilterOptions{
202196
EventType: "transfer",
203197
// This is the SAC id for the USDC asset on pubnet
204198
// https://stellar.expert/explorer/public/contract/CCW67TSZV3SSS2HXMBQ5JFGCKJNXKZM7UQUWUZPUTHXSTZLEO7SJMI75
@@ -207,21 +201,21 @@ func main() {
207201

208202
// Example 4: Filter by event type + asset code + issuer
209203
fmt.Println("\n=== Example 4: Only KALE mints ===")
210-
filterEvents(ledger, unifiedEventsEnabled, FilterOptions{
204+
filterEvents(ledger, FilterOptions{
211205
EventType: "mint",
212206
AssetCode: "KALE",
213207
Issuer: "GBDVX4VELCDSQ54KQJYTNHXAHFLBCA77ZY2USQBM4CSHTTV7DME7KALE",
214208
})
215209

216210
// Example 5: Filter by XLM events only
217211
fmt.Println("\n=== Example 5: Only XLM Events ===")
218-
filterEvents(ledger, unifiedEventsEnabled, FilterOptions{
212+
filterEvents(ledger, FilterOptions{
219213
AssetCode: "native",
220214
})
221215

222216
// Example 6: Filter by fee events only
223217
fmt.Println("\n=== Example 6: Only Fee Events ===")
224-
filterEvents(ledger, unifiedEventsEnabled, FilterOptions{
218+
filterEvents(ledger, FilterOptions{
225219
EventType: "fee",
226220
})
227221
}

0 commit comments

Comments
 (0)