|
| 1 | +--- |
| 2 | +title: "Stellar Event Schemas (v2)" |
| 3 | +description: "Soroban event topic schemas for stealth address announcements" |
| 4 | +--- |
| 5 | + |
| 6 | +The `stealth-announcer` contract emits events to notify indexers and clients about new stealth payments. In v2, the event topic schema has been updated to include indexed fields that allow clients to efficiently filter events before downloading the full metadata. |
| 7 | + |
| 8 | +This reference guide documents the v2 event schema, how it differs from v1, and how to query it. |
| 9 | + |
| 10 | +## v1 vs v2 Event Topic Comparison |
| 11 | + |
| 12 | +### v1 Schema (Legacy) |
| 13 | +In v1, the event emitted a single topic, requiring indexers to parse the data payload to extract routing information. |
| 14 | +- **Topic Layout**: `("announce")` |
| 15 | +- **Data Layout**: `(caller, scheme_id, stealth_address, ephemeral_pub_key, metadata)` |
| 16 | + |
| 17 | +### v2 Schema (Current) |
| 18 | +In v2, key routing fields have been moved to the event topics to enable native filtering via the Soroban RPC `getEvents` method. |
| 19 | +- **Topic Layout**: `("announce", scheme_id, view_tag_bucket, metadata_kind)` |
| 20 | +- **Data Layout**: `(caller, stealth_address, ephemeral_pub_key, metadata)` |
| 21 | + |
| 22 | +## v2 Topic Layout Details |
| 23 | + |
| 24 | +The v2 event emits exactly four topics: |
| 25 | + |
| 26 | +1. **`"announce"`**: The literal string identifier for the event. |
| 27 | +2. **`scheme_id`** (u32): The stealth address scheme being used (e.g., `1` for the standard ed25519 scheme). |
| 28 | +3. **`view_tag_bucket`** (u32): A deterministic bucket derived from the view tag to allow prefix filtering. |
| 29 | +4. **`metadata_kind`** (u32): The type of metadata attached to the event. |
| 30 | + |
| 31 | +### `view_tag_bucket` Derivation Rule |
| 32 | + |
| 33 | +To reduce false positives when scanning announcements, clients can filter by the `view_tag_bucket`. |
| 34 | +- **Rule**: The bucket is derived directly from the first byte of the metadata (`metadata[0]`). |
| 35 | +- **Stability**: This derivation is stable and guaranteed not to change for a given `metadata_kind`. |
| 36 | + |
| 37 | +When querying the RPC, indexers can specify their expected `view_tag_bucket` to dramatically reduce the number of events they need to fetch and process. |
| 38 | + |
| 39 | +### `metadata_kind` Values & Forward-Compat |
| 40 | + |
| 41 | +The `metadata_kind` field ensures forward compatibility for future upgrades to the announcement payload. |
| 42 | + |
| 43 | +- **`0`**: Standard stealth payment metadata (view tag included). |
| 44 | +- **`1+`**: Reserved for future use (e.g., encrypted amounts, multi-asset routing). |
| 45 | + |
| 46 | +**Forward-Compat Semantics**: Indexers and clients *must* gracefully ignore events with a `metadata_kind` they do not recognize. This allows new metadata formats to be deployed without breaking existing indexers. |
| 47 | + |
| 48 | +## Example `getEvents` Filter Queries |
| 49 | + |
| 50 | +You can use the Soroban RPC `getEvents` endpoint to filter for specific topics. |
| 51 | + |
| 52 | +### 1. Fetch all v2 announcements for Scheme 1 |
| 53 | +```json |
| 54 | +{ |
| 55 | + "startLedger": 123456, |
| 56 | + "filters": [ |
| 57 | + { |
| 58 | + "type": "contract", |
| 59 | + "contractIds": ["<v2-announcer-contract-id>"], |
| 60 | + "topics": [ |
| 61 | + ["announce"], |
| 62 | + ["1"], |
| 63 | + ["*"], |
| 64 | + ["*"] |
| 65 | + ] |
| 66 | + } |
| 67 | + ], |
| 68 | + "pagination": { "limit": 100 } |
| 69 | +} |
| 70 | +``` |
| 71 | + |
| 72 | +### 2. Filter by `view_tag_bucket` (e.g., Bucket 42) |
| 73 | +This is the recommended query for clients looking for their own transactions. |
| 74 | + |
| 75 | +```json |
| 76 | +{ |
| 77 | + "startLedger": 123456, |
| 78 | + "filters": [ |
| 79 | + { |
| 80 | + "type": "contract", |
| 81 | + "contractIds": ["<v2-announcer-contract-id>"], |
| 82 | + "topics": [ |
| 83 | + ["announce"], |
| 84 | + ["1"], |
| 85 | + ["42"], |
| 86 | + ["0"] |
| 87 | + ] |
| 88 | + } |
| 89 | + ], |
| 90 | + "pagination": { "limit": 100 } |
| 91 | +} |
| 92 | +``` |
| 93 | + |
| 94 | +## Migration & Indexer Recommendations |
| 95 | + |
| 96 | +The transition from v1 to v2 involves a new deployment of the `stealth-announcer` contract. |
| 97 | + |
| 98 | +- **Migration Timing**: v1 events remain readable and will not be deleted. v2 is a strictly new deployment with a new contract ID. |
| 99 | +- **Indexer Recommendations**: During the transition period, indexers and wallets *must* listen to both the v1 and v2 contract IDs to ensure no announcements are missed. |
| 100 | + |
| 101 | +You can query both simultaneously by including both contract IDs in your `getEvents` filter, or by executing parallel queries for the different topic structures. |
0 commit comments