GuidesFlutter (Dart SDK)

Flutter Integration Guide

Installation

Add the Aldero SDK to your pubspec.yaml:

dependencies:
  aldero:
    path: ../sdks/dart/aldero

Initialize

import 'package:aldero/aldero.dart';
 
final aldero = AlderoClient(
  config: AlderoConfig(
    domain: 'aldero.io',
    tenantSlug: 'myapp',
    environment: 'production', // or 'sandbox' for dev
  ),
);

With persistent token storage

import 'package:flutter_secure_storage/flutter_secure_storage.dart';
 
class SecureTokenStorage implements TokenStorage {
  final _storage = const FlutterSecureStorage();
 
  @override
  Future<String?> getAccessToken() => _storage.read(key: 'access_token');
  @override
  Future<String?> getRefreshToken() => _storage.read(key: 'refresh_token');
  @override
  Future<void> saveTokens(String access, String refresh) async {
    await _storage.write(key: 'access_token', value: access);
    await _storage.write(key: 'refresh_token', value: refresh);
  }
  @override
  Future<void> clear() async {
    await _storage.delete(key: 'access_token');
    await _storage.delete(key: 'refresh_token');
  }
}
 
final aldero = AlderoClient(
  config: AlderoConfig(domain: 'aldero.io', tenantSlug: 'myapp'),
  tokenStorage: SecureTokenStorage(),
);

Authentication

// Sign up
try {
  final result = await aldero.auth.signup(
    email: email,
    password: password,
    displayName: name,
  );
  // Tokens automatically stored
} on AlderoException catch (e) {
  if (e.code == 'CONFLICT') {
    // Email already exists
  }
}
 
// Login
final result = await aldero.auth.login(email: email, password: password);
 
// Profile
final user = await aldero.auth.getProfile();
 
// Logout
await aldero.auth.logout();
 
// Check session
if (await aldero.auth.hasSession) {
  // User is logged in
}

Entitlements & Feature Gating

final entitlements = await aldero.billing.getEntitlements(userId);
 
// Check features
if (entitlements.hasFeature('pro_features')) {
  // Show pro content
}
 
// Check grants
final credits = entitlements.sendCredits; // shorthand for grants['send_credits']
final pages = entitlements.receivePages;
 
// Check subscription status
if (entitlements.hasActiveSubscription) {
  // User has an active recurring subscription
}

Products

// List products (for paywall/pricing screen)
final products = await aldero.billing.listProducts();
for (final p in products) {
  print('${p.name}: \$${(p.price / 100).toStringAsFixed(2)}/${p.interval}');
  print('  Features: ${p.features}');
  print('  Grants: ${p.grants}');
}

Push Notifications

// After getting the APNS/FCM token
await aldero.notifications.registerDevice(
  userId: userId,
  token: deviceToken,
  platform: 'ios', // or 'android'
);
 
// On logout or token refresh
await aldero.notifications.unregisterDevice(oldToken);

Riverpod Integration

final alderoProvider = Provider<AlderoClient>((ref) {
  return AlderoClient(
    config: AlderoConfig(
      domain: Env.apiDomain,
      tenantSlug: Env.tenantSlug,
      environment: Env.environment,
    ),
    tokenStorage: SecureTokenStorage(),
  );
});
 
final entitlementsProvider = FutureProvider<EntitlementResponse>((ref) async {
  final aldero = ref.watch(alderoProvider);
  final userId = ref.watch(currentUserIdProvider);
  return aldero.billing.getEntitlements(userId);
});
 
final hasFeatureProvider = Provider.family<bool, String>((ref, feature) {
  return ref.watch(entitlementsProvider).valueOrNull?.hasFeature(feature) ?? false;
});

Error Handling

try {
  await aldero.auth.login(email: email, password: password);
} on AlderoException catch (e) {
  switch (e.code) {
    case 'AUTH_ERROR':
      // Invalid credentials
    case 'RATE_LIMIT':
      // Too many attempts
    case 'ACCOUNT_LOCKED':
      // Account locked
    default:
      // Show e.message to user
  }
}