shield_consent
Flutter plugin for DPDPA Shield — collect and manage user consent under India's Digital Personal Data Protection Act 2023 (DPDPA) from your Flutter app.
Android only for now. iOS support is on the roadmap. The consent logic, offline queue, and localisation are all pure Dart — only the platform bridge is Android-specific.
Requirements
- Flutter 3.10+
- Dart 3.0+
- Android 7.0+ (minSdk 24)
- A DPDPA Shield account → dpdpashield.in
Installation
dependencies:
shield_consent: ^1.0.0-beta.1
flutter pub get
Quick Start
1. Initialise before runApp
import 'package:shield_consent/shield_consent.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await ShieldConsent.init(apiKey: 'dpdpa_live_YOUR_KEY');
runApp(const MyApp());
}
2. Load the notice and show your consent UI
// Check if the user has already answered
final existing = await ShieldConsent.restoredDecision();
if (existing == null) {
// Fetch the published consent notice
final notice = await ShieldConsent.loadNotice();
// Localise for the device language (falls back to English per field)
final localized = ShieldConsent.localize(notice, languageCode: 'HI');
// Build your consent UI from localized.purposes
// then record the user's decision:
await ShieldConsent.recordDecision(
ConsentDecision(
noticeId: notice.id,
given: { 'analytics-purpose-id': true, 'marketing-purpose-id': false },
languageShown: 'HI',
decidedAtEpochMs: DateTime.now().millisecondsSinceEpoch,
),
identifier: 'user@example.com', // hashed on-device, never sent raw
languageShown: 'HI',
);
}
3. Gate third-party SDKs on consent
// Run a block only if the user has consented to a purpose
await ShieldGate.runIfConsented('analytics-purpose-id', () async {
await FirebaseAnalytics.instance.setAnalyticsCollectionEnabled(true);
});
// Or observe consent state reactively
ShieldGate.observeConsented('marketing-purpose-id').listen((given) {
if (!given) stopMarketingTrackers();
});
4. Flush queued writes on app resume
// Call when connectivity returns, e.g. in AppLifecycleState.resumed
await ShieldConsent.flushQueue();
API Reference
ShieldConsent
| Method | Description |
|---|---|
init(apiKey, cmpId?) |
Initialise the SDK. Call once before any other method. |
loadNotice({noticeId?}) |
Fetch the tenant's published consent notice from the backend. |
localize(notice, {languageCode}) |
Localise a notice into the given language. Per-field fallback to English. Pure Dart — no network call. |
recordDecision(decision, identifier, languageShown) |
Record the user's decision. The identifier is hashed on-device before anything is sent or stored. |
restoredDecision() |
Return the last decision persisted locally, or null if the user hasn't decided yet. |
flushQueue() |
Retry any decisions queued while offline. Call on app foreground or connectivity events. |
ShieldGate
| Method | Description |
|---|---|
isConsented(purposeId) |
Returns true if the user has consented to this purpose. Fail-closed — absent decisions are treated as not consented. |
runIfConsented(purposeId, block) |
Runs block only if consented. Returns true if it ran. |
observeConsented(purposeId) |
Stream of consent state — emits current state immediately, then on every change. |
Offline Support
Consent decisions are written to local storage before the network call, so restoredDecision() reflects the user's choice immediately regardless of connectivity. If the sync fails (no signal, server briefly down), the decision is queued and retried automatically the next time flushQueue() is called.
22 Languages
The SDK falls back per-field, not per-notice. If a Hindi translation exists for the notice title but not for a specific purpose description, that description falls back to English while everything else stays in Hindi.
Supported: English, Hindi, Bengali, Tamil, Telugu, Marathi, Gujarati, Kannada, Malayalam, Odia, Punjabi, Urdu, Assamese, and more.
Architecture
Flutter (Dart)
ShieldConsent / ShieldGate ← public API
NoticeLocalizer ← 22-language fallback, pure Dart
MethodChannel / EventChannel ← platform bridge
│
Android (Kotlin)
ShieldConsentPlugin.kt ← MethodChannel handler
Serializers.kt ← model conversion
│
DPDPA Shield Android SDK ← full consent engine
ShieldConsentManager ← facade
ShieldGate ← fail-closed purpose gating
OfflineConsentQueue ← exponential-backoff queue
IAB TCF writer ← writes IABTCF_TCString
Support
- Docs: dpdpashield.in/docs/flutter
- Email: hello@dpdpashield.in
- Issues: github.com/DPDPA-Shield/flutter-plugin/issues
License
BSD 3-Clause — see LICENSE.
Libraries
- shield_consent
- DPDPA Shield — Flutter plugin public API.