Skip to content

Implement Streak Reconciliation Between StreaksService and the Smart Contract #310

@phertyameen

Description

@phertyameen

Description:

The backend has a fully featured streak system in StreaksService and UpdateStreakProvider. It tracks currentStreak, longestStreak, lastActivityDate, streakDates array, and handles timezone awareness. The smart contract has a simple current_streak counter. Currently these two are completely out of sync. This issue makes the backend the authority and pushes verified streak updates to the contract.

Current Behavior:

StreaksService.updateStreak() correctly updates the Postgres streak record
The contract's current_streak on the player profile is never updated after registration
CompleteDailyQuestProvider calls updateStreakProvider.updateStreak() after quest completion but nothing propagates that to the chain

Expected Behavior:

After UpdateStreakProvider successfully updates a streak in Postgres, the contract's player streak is updated to match. The backend Postgres record is always the source of truth — the contract reflects it, not the other way around.

Requirements:
New file:

backend/src/blockchain/providers/sync-streak.provider.ts

Method to implement:

syncStreakOnChain(stellarWallet: string, currentStreak: number): Promise

  • Connects to Stellar testnet via the oracle wallet
  • Calls the contract's update_iq_level function is not appropriate here, note to contributor: the contract currently has no dedicated streak update function. Check if Issue 2 in the contracts repo (automatic streak reset) has been resolved and whether a sync_streak function has been added. If not, this provider should be built and ready but gated behind a feature flag or environment variable until the contract catches up
  • Document this dependency clearly in the provider file

Wire into BlockchainService:
Add syncStreakOnChain as a passthrough method on BlockchainService following the same pattern as the other providers.

Wire into UpdateStreakProvider:

  • Inject BlockchainService into UpdateStreakProvider (available after Issue Configure BlockchainModule and Export BlockchainService to Dependent Modules #307 - StreakModule must import BlockchainModule)
  • After streak is saved to Postgres, retrieve the user's stellarWallet
  • If wallet exists, call blockchainService.syncStreakOnChain(stellarWallet, streak.currentStreak)
  • Non-blocking, try/catch, no disruption to existing streak logic

Update StreakModule:
Add BlockchainModule to StreakModule imports so BlockchainService is injectable into UpdateStreakProvider.

Important note for contributors:
This issue has a soft dependency on contract Issue 2 (automatic streak reset) being resolved. The provider should be fully implemented and wired, but if the contract does not yet have a dedicated streak sync function, the actual contract call inside the provider should be wrapped in a check against an environment variable STREAK_SYNC_ENABLED=true/false so it can be toggled on once the contract is ready without requiring another backend deployment.

Acceptance Criteria:

  • sync-streak.provider.ts exists in blockchain/providers/
  • BlockchainService exposes syncStreakOnChain as a passthrough
  • StreakModule imports BlockchainModule
  • UpdateStreakProvider calls syncStreakOnChain after every successful Postgres streak update
  • Users without a stellarWallet are skipped gracefully
  • The call is non-blocking and wrapped in try/catch
  • A STREAK_SYNC_ENABLED environment variable gates the actual contract call
  • STREAK_SYNC_ENABLED is documented in .env.example
  • A unit test confirming the sync is triggered after a streak update is included

Metadata

Metadata

Assignees

No one assigned

    Labels

    No fields configured for Feature.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions