Event Indexing
The indexer monitors Sui blockchain events from the Iyup smart contracts and stores them in a structured database for efficient querying.
Event Subscription
The indexer uses cursor-based event polling to track blockchain events. It maintains cursors in the database to resume indexing after failures.
Indexed Events
Marketplace Events
ListingCreated
Emitted when a new listing is created.
Event Structure:public struct ListingCreated has copy, drop {
listing_id: ID,
token_id: ID,
seller: address,
price: u64,
timestamp: u64,
}- Creates new
Listingrecord - Sets status to
active - Links to token metadata
ListingUpdated
Emitted when listing price is updated.
Event Structure:public struct ListingUpdated has copy, drop {
listing_id: ID,
new_price: u64,
timestamp: u64,
}- Updates existing
Listingrecord - Updates price field
- Preserves history
ListingCancelled
Emitted when seller cancels listing.
Event Structure:public struct ListingCancelled has copy, drop {
listing_id: ID,
seller: address,
timestamp: u64,
}- Updates
Listingstatus tocancelled - Preserves listing history
ListingPurchased
Emitted when token is purchased.
Event Structure:public struct ListingPurchased has copy, drop {
listing_id: ID,
token_id: ID,
seller: address,
buyer: address,
price: u64,
fee: u64,
timestamp: u64,
}- Updates
Listingstatus tosold - Records buyer address
- Records purchase price and fee
- Links to purchase transaction
Document Vault Events
DocumentRegistered
Emitted when document is first registered.
Event Structure:public struct DocumentRegistered has copy, drop {
token_address: address,
issuer: address,
blob_id: String,
version_index: u64,
timestamp: u64,
}- Creates new
Documentrecord - Creates initial
DocumentVersionrecord - Links to token address
VersionUpdated
Emitted when new document version is added.
Event Structure:public struct VersionUpdated has copy, drop {
token_address: address,
version_index: u64,
blob_id: String,
timestamp: u64,
}- Creates new
DocumentVersionrecord - Links to existing
Documentrecord - Updates document
updatedAttimestamp
DocumentEndorsed
Emitted when auditor endorses document.
Event Structure:public struct DocumentEndorsed has copy, drop {
token_address: address,
auditor: address,
timestamp: u64,
}- Creates
DocumentAuditorrecord - Links to
Documentrecord - Records auditor address
ZK Vault Events
ZKCommitmentRegistered
Emitted when ZK commitment is registered.
Event Structure:public struct ZKCommitmentRegistered has copy, drop {
token_address: address,
commitment: vector<u8>,
timestamp: u64,
}- Creates
ZKCommitmentrecord - Stores commitment hash
- Links to token address
ZKProofVerified
Emitted when ZK proof is verified.
Event Structure:public struct ZKProofVerified has copy, drop {
token_address: address,
commitment: vector<u8>,
verified: bool,
timestamp: u64,
}- Creates
ZKProofVerificationrecord - Updates
ZKCommitmentproof count - Updates last verification timestamp
Event Processing Flow
1. Event Polling
// Poll events from Sui blockchain
const events = await suiClient.queryEvents({
query: { Package: PACKAGE_ID },
cursor: lastCursor,
limit: 100,
});2. Event Filtering
// Filter events by type
const listingEvents = events.filter(e => e.type.includes('ListingCreated'));
const documentEvents = events.filter(e => e.type.includes('DocumentRegistered'));3. Event Processing
// Process each event
for (const event of events) {
if (event.type.includes('ListingCreated')) {
await processListingCreated(event);
} else if (event.type.includes('DocumentRegistered')) {
await processDocumentRegistered(event);
}
// ...
}4. Cursor Update
// Update cursor after processing
await db.cursor.upsert({
where: { id: 'iyup_events' },
update: { cursor: events[events.length - 1].id.id },
create: { id: 'iyup_events', cursor: events[events.length - 1].id.id },
});Error Handling
Event Processing Errors
If an event fails to process:
- Log error with event details
- Continue processing other events
- Alert monitoring system
- Retry failed events later
Cursor Recovery
If cursor is lost or corrupted:
- Query latest events from blockchain
- Rebuild cursor from event IDs
- Resume normal processing
Database Errors
If database write fails:
- Log error
- Retry with exponential backoff
- Alert if retries exhausted
- Preserve event data for later processing
Performance Optimization
Batch Processing
Process multiple events in batches:
const batchSize = 100;
for (let i = 0; i < events.length; i += batchSize) {
const batch = events.slice(i, i + batchSize);
await processBatch(batch);
}Concurrent Processing
Process different event types concurrently:
await Promise.all([
processMarketplaceEvents(events),
processDocumentEvents(events),
processZKEvents(events),
]);Database Indexing
Ensure proper database indexes:
- Token addresses
- Event timestamps
- Listing IDs
- Status fields
Monitoring
Metrics to Track
- Events processed per second
- Processing latency
- Error rate
- Cursor lag (behind blockchain)
- Database query performance
Health Checks
- Cursor freshness (should be recent)
- Database connectivity
- RPC endpoint availability
- Event processing success rate
Resync Strategy
Full Resync
To rebuild database from scratch:
- Delete all indexed data
- Delete cursors
- Restart indexer
- Indexer will start from genesis
Partial Resync
To resync specific time range:
- Delete data for time range
- Delete/update cursor to earlier point
- Restart indexer
- Indexer will resume from cursor
Next Steps
- Learn about Indexer API
- Review Indexer Overview
- Check Examples