Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Stellar Configuration
STELLAR_HORIZON_URL=https://horizon-testnet.stellar.org
CONTRACT_ID=CCYU3LOQI34VHVN3ZOSEBHHKL4YK36FMTOEGLRYDUDRGS7JOLLRKCEQM

# Database Configuration (existing)
DB_HOST=localhost
DB_PORT=5432
DB_USERNAME=postgres
DB_PASSWORD=password
DB_DATABASE=tradeflow
3 changes: 2 additions & 1 deletion src/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@ import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { HealthModule } from './health/health.module';
import { IndexerService } from './indexer.service';

@Module({
imports: [HealthModule],
controllers: [AppController],
providers: [AppService],
providers: [AppService, IndexerService],
})
export class AppModule {}
82 changes: 82 additions & 0 deletions src/indexer.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import { Injectable, OnModuleInit } from '@nestjs/common';
import { Server } from '@stellar/stellar-sdk';

@Injectable()
export class IndexerService implements OnModuleInit {
private server: Server;
private readonly POLLING_INTERVAL = 5000; // 5 seconds
private readonly CONTRACT_ID = process.env.CONTRACT_ID || '';
private readonly INVOICE_MINTED_TOPIC = 'InvoiceMinted';

constructor() {
// Initialize Stellar server (using testnet by default, can be configured via env)
this.server = new Server(
process.env.STELLAR_HORIZON_URL || 'https://horizon-testnet.stellar.org'
);
}

async onModuleInit() {
console.log('IndexerService starting...');

if (!this.CONTRACT_ID) {
console.warn('CONTRACT_ID not set in environment variables');
return;
}

// Start polling for events
this.startPolling();
}

private startPolling() {
console.log(`Starting to poll for ${this.INVOICE_MINTED_TOPIC} events from contract ${this.CONTRACT_ID}`);

setInterval(async () => {
try {
await this.pollForEvents();
} catch (error) {
console.error('Error polling for events:', error);
}
}, this.POLLING_INTERVAL);
}

private async pollForEvents() {
try {
// Get events from the Stellar server
const events = await this.server.getEvents({
contract: this.CONTRACT_ID,
topics: [[this.INVOICE_MINTED_TOPIC]],
});

if (events.records.length > 0) {
console.log(`Found ${events.records.length} events`);

for (const event of events.records) {
this.processInvoiceMintedEvent(event);
}
}
} catch (error) {
console.error('Error fetching events:', error);
}
}

private processInvoiceMintedEvent(event: any) {
try {
// Extract event data
const eventData = event.value;

// Assuming the event structure contains invoice_id and amount
// This may need adjustment based on actual event structure
const invoiceId = eventData.invoice_id || eventData.invoiceId || 'N/A';
const amount = eventData.amount || 'N/A';

console.log(`InvoiceMinted Event Detected:`);
console.log(` - Invoice ID: ${invoiceId}`);
console.log(` - Amount: ${amount}`);
console.log(` - Transaction Hash: ${event.transaction_hash}`);
console.log(` - Timestamp: ${event.created_at}`);
console.log('---');
} catch (error) {
console.error('Error processing InvoiceMinted event:', error);
}
}
}
Loading