Stripe onboarding service
The StripeOnboardingService has been refactored to follow the standardized Riverpod pattern used throughout the codebase, with proper integration with the AppStore singleton.
- Before: Had a separate
@riverpodprovider forStripeOnboardingPersistenceService - After: Creates the persistence service directly in the build method
- Reason: The persistence service is an implementation detail and doesn’t need to be a provider
- Uses
AppStore.instancedirectly (singleton pattern) - Properly calls
ensureSetup()before using AppStore - Falls back to default state if AppStore setup fails
- Before: Attempted to use
AsyncNotifier(incomplete refactor) - After: Uses synchronous
Notifier<StripeOnboardingState> - Reason: Matches the pattern used in other services (
ChatService,PledgeService,HomeFilterService) - Async initialization happens in background via
_initializeAsync()
@override
StripeOnboardingState build() {
// Initialize AppStore
final appStore = AppStore.instance;
if (!appStore.ensureSetup()) {
return StripeOnboardingState.defaultState();
}
// Create persistence service
_persistenceService = StripeOnboardingPersistenceService(appStore);
// Load async in background
if (!_isInitialized) {
_initializeAsync();
}
// Return default immediately
return StripeOnboardingState.defaultState();
}
All persistence operations properly use the _persistenceService:
updateState()- Updates state and persistssetCurrency()- Updates currency and persistssetAccount()- Updates account and persistsresetToDefault()- Resets and persistsclearPersistedState()- Clears storagerefresh()- Reloads from storage
Provides consistent methods matching other services:
updateState()- Main state update methodclearError()- No-op for consistency (Stripe state has no errors)refresh()- Reload from persistencereset()- Reset to default without persistenceisModified- Check if state differs from default
┌─────────────────────────────────────┐
│ StripeOnboardingService │
│ (Riverpod Notifier) │
│ │
│ - build() - Sync initialization │
│ - _initializeAsync() - Load data │
│ - updateState() - Update & persist │
│ - setCurrency() - Update currency │
│ - setAccount() - Update account │
└──────────────┬──────────────────────┘
│
│ uses
▼
┌─────────────────────────────────────┐
│ StripeOnboardingPersistenceService │
│ │
│ - saveStripeState() │
│ - loadStripeState() │
│ - clearStripeState() │
└──────────────┬──────────────────────┘
│
│ uses
▼
┌─────────────────────────────────────┐
│ AppStore (Singleton) │
│ │
│ - ensureSetup() │
│ - read(key) │
│ - write(key, value) │
│ - delete(key) │
└─────────────────────────────────────┘
The service includes several convenience providers for easy state access:
// Loading state
@riverpod bool stripeOnboardingIsLoading(Ref ref)
// Error state
@riverpod String? stripeOnboardingError(Ref ref)
// Modified check
@riverpod bool stripeOnboardingIsModified(Ref ref)
// Currency access
@riverpod StoredCurrencyModel stripeOnboardingCurrency(Ref ref)
// Account access
@riverpod StoredAccount stripeOnboardingAccount(Ref ref)
// Selection checks
@riverpod bool stripeOnboardingCurrencySelected(Ref ref)
@riverpod bool stripeOnboardingAccountSelected(Ref ref)
@riverpod bool stripeOnboardingReadyToProceed(Ref ref)
// Watch the state
final state = ref.watch(stripeOnboardingServiceProvider);
// Access notifier for updates
final notifier = ref.read(stripeOnboardingServiceProvider.notifier);
// Update currency
await notifier.setCurrency(newCurrency);
// Update account
await notifier.setAccount(newAccount);
// Check if ready to proceed
final isReady = ref.watch(stripeOnboardingReadyToProceedProvider);
// Reset state
await notifier.resetToDefault();
// Clear persisted data
await notifier.clearPersistedState();
The alias stripeOnboardStartProvider is maintained for existing code:
/// Backward compatibility alias
final stripeOnboardStartProvider = stripeOnboardingServiceProvider;
- Consistent Pattern: Matches other service providers in the codebase
- Proper AppStore Integration: Uses singleton pattern correctly
- Async Safety: Background loading doesn’t block initialization
- Persistence: Automatic state persistence on updates
- Type Safety: Full type safety with Riverpod code generation
- Convenience: Multiple convenience providers for common operations
- Error Handling: Graceful handling of storage failures
- The service uses synchronous
build()with async background loading - Storage failures are logged but don’t break the app
- Default state is always available immediately
- Persisted state loads in background and updates UI reactively
- The
AppStoresingleton is still used (not converted to provider)