shield_consent 1.0.0-beta.1
shield_consent: ^1.0.0-beta.1 copied to clipboard
DPDPA Shield consent management for Flutter — DPDPA 2023 (India) compliant consent collection, guardian-OTP parental consent, offline queue, and ShieldGate purpose gating.
shield_consent — Flutter plugin #
DPDPA Shield consent management for Flutter apps.
A thin MethodChannel/EventChannel bridge over the Kotlin :android core module.
All consent logic lives in Kotlin; this plugin is pure glue.
Verification status #
| Layer | Status |
|---|---|
| Dart models + NoticeLocalizer | ✅ 12/12 tests passing (pure Dart, flutter test) |
Android Kotlin plugin (ShieldConsentPlugin.kt) |
✅ Written, compiles as part of a host app's Gradle build |
| End-to-end (real device / emulator) | ⬜ Not yet run |
Installing locally (development) #
Step 1 — publish the Kotlin SDK to Maven Local #
cd mobile/android-sdk
gradle --no-daemon :android:publishToMavenLocal
This produces ~/.m2/repository/com/dpdpashield/sdk/android/0.1.0-SNAPSHOT/.
Step 2 — add the plugin to your Flutter app #
In your app's pubspec.yaml:
dependencies:
shield_consent:
path: /path/to/dpdpa-complianceos/mobile/flutter-plugin
Or via git:
dependencies:
shield_consent:
git:
url: https://github.com/icybersanjay/dpdpa-complianceos
path: mobile/flutter-plugin
Step 3 — add mavenLocal() to your app's android/build.gradle #
allprojects {
repositories {
google()
mavenCentral()
mavenLocal() // required until the SDK is published to Maven Central / JitPack
}
}
Usage #
import 'package:shield_consent/shield_consent.dart';
// 1. Initialise — once, before any UI
await ShieldConsent.init(apiKey: 'dpdpa_live_xxx', cmpId: 1);
// 2. Load the published consent notice
final notice = await ShieldConsent.loadNotice();
// 3. Localise for the device language
final localized = ShieldConsent.localize(notice, languageCode: 'HI');
// 4. Record the user's decision
await ShieldConsent.recordDecision(
ConsentDecision(
noticeId: notice.id,
given: {'analytics': true, 'marketing': false},
languageShown: 'HI',
decidedAtEpochMs: DateTime.now().millisecondsSinceEpoch,
),
identifier: 'user@example.com',
languageShown: 'HI',
);
// 5. Gate a third-party SDK on a specific purpose
await ShieldGate.runIfConsented('analytics', () async {
FirebaseAnalytics.instance.setAnalyticsCollectionEnabled(true);
});
// 6. Observe consent changes (fires immediately with current state)
ShieldGate.observeConsented('marketing').listen((given) {
if (!given) stopMarketingTrackers();
});
// 7. Flush the offline queue when connectivity returns
await ShieldConsent.flushQueue();
Architecture #
Flutter (Dart)
ShieldConsent / ShieldGate ← public API, pure Dart
NoticeLocalizer ← 22-language per-field fallback, pure Dart
MethodChannel / EventChannel ← Flutter platform bridge
│
Android (Kotlin)
ShieldConsentPlugin.kt ← MethodChannel handler, this plugin
Serializers.kt ← ConsentNotice/Decision ↔ HashMap
│
com.dpdpashield.sdk:android ← the full Kotlin SDK (:android module)
ShieldConsentManager ← facade (EncryptedSharedPreferences, OkHttp)
ShieldGate ← fail-closed purpose gating
OfflineConsentQueue ← exponential-backoff local queue
IAB TCF writer ← writes IABTCF_TCString to SharedPreferences
Running tests #
cd mobile/flutter-plugin
flutter test