Skip to content
Open
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
4 changes: 0 additions & 4 deletions contract/contracts/hello-world/src/autoshare_logic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -336,8 +336,6 @@ pub fn pause(env: Env, admin: Address) -> Result<(), Error> {
}

env.storage().instance().set(&INSTANCE_PAUSED, &true);
ContractPaused {}.publish(&env);
env.storage().persistent().set(&pause_key, &true);
ContractPaused {
category: NotificationCategory::Admin,
priority: NotificationPriority::High,
Expand All @@ -361,8 +359,6 @@ pub fn unpause(env: Env, admin: Address) -> Result<(), Error> {
}

env.storage().instance().set(&INSTANCE_PAUSED, &false);
ContractUnpaused {}.publish(&env);
env.storage().persistent().set(&pause_key, &false);
ContractUnpaused {
category: NotificationCategory::Admin,
priority: NotificationPriority::High,
Expand Down
3 changes: 3 additions & 0 deletions contract/contracts/hello-world/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -431,4 +431,7 @@ mod tests {

#[path = "../tests/revocation_test.rs"]
mod revocation_test;

#[path = "../tests/edge_case_test.rs"]
mod edge_case_test;
}
15 changes: 15 additions & 0 deletions contract/contracts/hello-world/src/tests/autoshare_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1080,6 +1080,21 @@ fn test_is_group_active_on_nonexistent_group_fails() {
client.is_group_active(&id);
}

#[test]
fn test_create_group_with_zero_usages_fails() {
let test_env = setup_test_env();
let client = AutoShareContractClient::new(&test_env.env, &test_env.autoshare_contract);

let creator = test_env.users.get(0).unwrap().clone();
let token = test_env.mock_tokens.get(0).unwrap().clone();
let id = BytesN::from_array(&test_env.env, &[1u8; 32]);
let name = String::from_str(&test_env.env, "Zero Usages");

crate::test_utils::mint_tokens(&test_env.env, &token, &creator, 10_000_000);
let result = client.try_create(&id, &name, &creator, &0u32, &token);
assert!(result.is_err(), "Creating group with 0 usages should fail");
}

#[test]
fn test_get_all_groups_includes_inactive() {
let test_env = setup_test_env();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ mod preferences_tests {
};
use crate::test_utils::setup_test_env;
use crate::{AutoShareContract, AutoShareContractClient};
use soroban_sdk::{testutils::Address as _, Address, Env, Vec};
use soroban_sdk::{testutils::Address as _, Address, Env, IntoVal, Vec};

// ============================================================================
// Default preferences
Expand Down
3 changes: 1 addition & 2 deletions listener/jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,5 @@ module.exports = {
transform: {
'^.+\\.tsx?$': 'ts-jest'
},
setupFilesAfterEnv: ['<rootDir>/jest.setup.js']
}
setupFilesAfterEnv: ['<rootDir>/jest.setup.js'],
};
10 changes: 0 additions & 10 deletions listener/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 11 additions & 3 deletions listener/src/api/events-server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import {
collectRawBody,
} from '../services/webhook-verifier';
import { WebhookSecret, RateLimitConfig, ContractConfig } from '../types';
import { WebhookSecret, RateLimitConfig } from '../types';
import { RateLimiter } from './rate-limiter';
import {
getNotificationAnalyticsAggregator,
Expand Down Expand Up @@ -177,10 +176,16 @@ async function getContractPauseStatus(

const simulation = await server.simulateTransaction(tx);

if (!StellarSDK.rpc.isSuccessfulSim(simulation) || !simulation.result) {
if (!('result' in simulation) || !simulation.result) {
let errorMsg = 'Failed to simulate contract call';
if ('error' in simulation && simulation.error) {
errorMsg = typeof simulation.error === 'string'
? simulation.error
: String(simulation.error);
}
return {
paused: false,
error: simulation.error ? simulation.error.message : 'Failed to simulate contract call'
error: errorMsg
};
}

Expand Down Expand Up @@ -215,6 +220,9 @@ async function buildStatusResponse(options: EventsServerOptions): Promise<{
return {
timestamp: new Date().toISOString(),
contracts: contractStatuses
};
}

async function fetchNetworkTipLedger(rpcUrl: string): Promise<{
ledger: number | null;
errorDetail?: string;
Expand Down
5 changes: 2 additions & 3 deletions listener/src/config.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { Config, ContractConfig, DiscordConfig, WebhookSecret, AppCleanupConfig, EventQueueConfig } from './types';
import { Config, ContractConfig, DiscordConfig, WebhookSecret, AppCleanupConfig, RetrySchedulerOptions } from './types';
import { Config, ContractConfig, DiscordConfig, WebhookSecret, AppCleanupConfig, EventQueueConfig, RetrySchedulerOptions } from './types';

export class ConfigError extends Error {
constructor(message: string) {
Expand Down Expand Up @@ -140,7 +139,7 @@ export function loadConfig(): Config {
const discord = loadDiscordConfig();
const rawContractAddresses = parseJsonEnv<unknown>('CONTRACT_ADDRESSES', '[]');
const rawWebhookSecrets = parseJsonEnv<unknown>('WEBHOOK_SECRETS', '[]');
const clientOverrides = parseJsonEnv<Record<string, { maxRequests: number; windowMs?: number>>(

const clientOverrides = parseJsonEnv<Record<string, { maxRequests: number; windowMs?: number }>>(
'RATE_LIMIT_CLIENT_OVERRIDES',
'{}'
Expand Down
7 changes: 6 additions & 1 deletion listener/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { ArchiveStore } from './services/archive-store';
import { loadArchiveConfig } from './services/archive-config';
import { initializeDatabase } from './database/database';
import { DiscordNotificationService } from './services/discord-notification';
import { EventDeduplicationService } from './services/event-deduplication-service';
import { eventRegistry } from './store/event-registry';
import logger from './utils/logger';
import { loadConfig, ConfigError } from './config';
Expand All @@ -32,11 +33,15 @@ async function main() {
let cleanupService: CleanupService | null = null;
let archiveService: ArchiveService | null = null;
let archiveStore: ArchiveStore | null = null;
let deduplicationService: EventDeduplicationService | null = null;

try {
logger.info('Initializing database');
const db = await initializeDatabase(config.databasePath);

// Initialize deduplication service
deduplicationService = new EventDeduplicationService(db);

// Rebuild registry with configured event TTL
if (config.cleanup) {
(eventRegistry as any).ttlMs = config.cleanup.eventRetentionMs;
Expand Down Expand Up @@ -104,7 +109,7 @@ async function main() {
archiveService,
});

const subscriber = new EventSubscriber(config);
const subscriber = new EventSubscriber(config, deduplicationService);
await subscriber.start();

const shutdown = async () => {
Expand Down
Loading