ShareRing Vault SDK for Flutter
A comprehensive Flutter plugin for secure vault operations, supporting cryptographic functions, document management, and authentication.
Prerequisites
Before getting started, ensure you have the following installed:
- Flutter SDK: Version 3.3.0 or higher
- Dart SDK: Version 3.9.2 or higher
- Android Studio with Android SDK (API Level 24+)
- Xcode 14.0+ (for iOS development)
- CocoaPods (for iOS dependency management)
- Java Development Kit (JDK): Version 11 or higher
Verify your setup:
flutter doctorFeatures
- Secure cryptographic operations
- Document management and handling
- User authentication and vault access
- HD wallet support (SECP256K1)
- Merkle tree operations for data integrity
- GraphQL API integration
- Secure backup and restore functionality
Getting Started
This plugin provides platform-specific implementations for Android and iOS to enable ShareRing secure vault functionality in your Flutter application.
Installation
Add this to your pubspec.yaml:
dependencies:
shr_vault_flutter:
git:
url: https://github.com/ShareRing/sharering-vaults-flutter.gitThen run:
flutter pub getAndroid Configuration
1. Update build.gradle (Project-level)
Ensure your project-level android/build.gradle includes the required repositories and configurations:
allprojects {
repositories {
google()
mavenCentral()
}
}
subprojects {
project.afterEvaluate {
if (project.hasProperty("android")) {
android {
compileSdk = 36
}
}
}
}
tasks.register('clean', Delete) {
delete rootProject.buildDir
}2. Update android/app/build.gradle.kts (App-level)
Configure your app-level build file to reference the NFC AAR files and add dependencies using flatDir repository:
repositories {
flatDir {
dirs rootProject.file("android/libs")
}
}
android {
namespace = "com.sharering.shr_vault_flutter_example"
compileSdk = 36
defaultConfig {
minSdkVersion 24
targetSdkVersion 36
multiDexEnabled = true
}
buildTypes {
release {
signingConfig = signingConfigs.debug
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
}
}
// Add this to resolve META-INF conflicts
packaging {
resources {
excludes += "META-INF/versions/9/OSGI-INF/MANIFEST.MF"
}
}
}Add or verify these settings in android/gradle.properties:
android.useAndroidX=true
android.enableJetifier=true
org.gradle.jvmargs=-Xmx2048m3. AndroidManifest.xml Configuration
Ensure your android/app/src/main/AndroidManifest.xml includes the necessary permissions:
<manifest>
<!-- NFC Permissions -->
<uses-permission android:name="android.permission.NFC" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_CALENDAR" />
<uses-permission android:name="android.permission.READ_CALENDAR" />
<!-- NFC Feature Declaration -->
<uses-feature
android:name="android.hardware.nfc"
android:required="false" />
<application>
<!-- Your configuration -->
</application>
</manifest>iOS Configuration
1. Prerequisites for iOS
- Minimum iOS Version: 15.0
- CocoaPods: Latest version
- Xcode: 14.0 or later
2. Install CocoaPods Dependencies
Navigate to the iOS directory and install dependencies:
cd ios
pod repo update
pod install
cd ..3. Update Podfile
Update your ios/Podfile with the proper configuration for NFC support and performance optimization:
platform :ios, '15.0'
# CocoaPods analytics sends network stats synchronously affecting flutter build latency
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
# ... other configuration ...
target 'Runner' do
use_frameworks!
flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
target 'RunnerTests' do
inherit! :search_paths
end
end
post_install do |installer|
installer.pods_project.targets.each do |target|
flutter_additional_ios_build_settings(target)
# Performance optimization and NFC configuration
target.build_configurations.each do |config|
# Enable optimization for Release builds
if config.name == 'Release'
config.build_settings['GCC_OPTIMIZATION_LEVEL'] = '3'
config.build_settings['SWIFT_OPTIMIZATION_LEVEL'] = '-O'
end
# Exclude arm64 for simulator (fixes NFCPassportReader framework compatibility)
config.build_settings['EXCLUDED_ARCHS[sdk=iphonesimulator*]'] = 'arm64'
# NFC support
config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= [
'$(inherited)',
'PERMISSION_NFC=1',
]
end
end
endKey Configuration Points:
platform :ios, '15.0'ensures minimum iOS 15 compatibilityuse_frameworks!is required for NFC framework integrationEXCLUDED_ARCHS[sdk=iphonesimulator*] = 'arm64'fixes simulator build issues- Release optimization settings improve performance
PERMISSION_NFC=1enables NFC functionality
4. Info.plist Configuration
Add the following keys to your ios/Runner/Info.plist for NFC functionality:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<!-- NFC Configuration -->
<key>NFCReaderUsageDescription</key>
<string>This app uses NFC to securely read documents.</string>
<key>com.apple.developer.nfc.readersession.iso7816.select-identifiers</key>
<array>
<string>00000000000000</string>
</array>
<!-- Camera for Document Capture -->
<key>NSCameraUsageDescription</key>
<string>Camera access is needed to capture documents.</string>
<!-- Photo Library Access -->
<key>NSPhotoLibraryUsageDescription</key>
<string>Photo library access is needed to select documents.</string>
<!-- Calendar Access (if needed) -->
<key>NSCalendarsUsageDescription</key>
<string>Calendar access is needed for document dates.</string>
<!-- Other required keys -->
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>nfc</string>
</array>
</dict>
</plist>5. Add NFC Framework and Native Libraries
- Open
ios/Runner.xcworkspace(NOTRunner.xcodeproj) in Xcode - Select the Runner project
- Go to Build Phases > Link Binary With Libraries
- Verify that
CoreNFC.frameworkis added (should be included by default)
6. Code Signing & Capabilities
For development on physical devices:
- Open
ios/Runner.xcworkspacein Xcode - Select the Runner project
- Go to Signing & Capabilities
- Select your team from the dropdown
- Update the Bundle Identifier (e.g.,
com.sharering.shrVaultExample) - Click + Capability and add:
- NFC Tag Reading: Required for NFC functionality
- Keychain Sharing: For secure credential storage (if needed)
7. Troubleshooting iOS Setup
Error: “Pods directory not found”
cd ios
rm -rf Pods Podfile.lock
pod install
cd ..Error: “CoreNFC not available”
- Ensure Deployment Target is iOS 15.0 or higher
- Verify NFC capability is added in Xcode
Build & Run
Initial Setup
# Clean previous builds
flutter clean
# Get dependencies
flutter pub get
# iOS only: Install CocoaPods dependencies
cd ios && pod install && cd ..API Usage Guide
Authentication
Sign Up
Registers a new user and creates a vault account.
import 'package:shr_vault_flutter/shr_vault_flutter.dart';
// In your widget/screen
final UserInfo? user = await ShrVaultFlutter.signup(context);
if (user != null) {
print('Signup successful!');
print('Email: ${user.email}');
print('Wallet Address: ${user.walletAddress}');
} else {
print('Signup cancelled or failed');
}Parameters:
context: BuildContext – The current context for showing the modal
Returns:
UserInfo?– User information if signup succeeds, null if cancelled
UserInfo Properties:
- email: String
- authToken: String
- walletAddress: String
- pubKey: String
- mnemonic: String (12-word recovery phrase)
- vctToken: String?
- dvctToken: String?
- biometricEnabled: String?
- tempPin: String?Log In
Authenticates an existing user with their vault account using a recovery phrase.
final UserInfo? user = await ShrVaultFlutter.login(context);
if (user != null) {
print('Login successful!');
print('Welcome back: ${user.email}');
} else {
print('Login cancelled');
}Parameters:
context: BuildContext – The current context for showing the modal
Returns:
UserInfo?– User information if login succeeds, null if cancelled
Document Management
Add New Document
Navigates to document selection screen where users can choose and upload documents.
final bool success = await ShrVaultFlutter.gotoAddDoc(context);
if (success) {
print('Document added successfully');
// Refresh your document list
} else {
print('Document addition cancelled');
}Parameters:
context: BuildContext – The current context for navigation
Returns:
bool– True if document was added, false if cancelled
Supported Document Types:
- ID Card (with/without NFC)
- Passport (with/without NFC)
- Driver’s License
- Voter Card
- Aadhaar (India)
- PAN (India)
- TIN Card
- Resident Permit
- Student ID Card
Get Document List
Fetches all documents with their current processing status.
final List<DocumentItem>? documents = await ShrVaultFlutter.getListDoc(context);
if (documents != null && documents.isNotEmpty) {
for (var doc in documents) {
print('${doc.type}: ${doc.fullName} (${doc.status})');
}
} else {
print('No documents found');
}Parameters:
context: BuildContext – Required for internal operations
Returns:
List<DocumentItem>?– List of documents, null if error
DocumentItem Properties:
- documentId: String?
- document_id: String?
- type: String
- name: String
- subtitle: String
- status: String? (pending, processing, approved, declined, completed, blocked)
- hasDocument: bool
- archived: bool
- fullName: String?
- firstName: String?
- lastName: String?
- surname: String?
- number: String?
- dob: String?
- expiryDate: String?
- issuesDate: String?
- issuedDate: String?
- issuanceDate: String?
- documentPhotos: String? (JSON encoded)
- verificationLabel: String? (verified, checked)
- dvct: String? (Digital Verifiable Credential Token)
- docHash: String?
- address: String?
- placeOfBirth: String?
- gender: String?
- nationality: String?
- issuerAuthority: String?
- selfImage: String?
- category: String?
- document_type: String?
- issuing_country: String?
- metadata: String?
- lastUsedTime: String?
- verification: Map<String, dynamic>?
- attachments: List<AttachmentsDoc>?
- config: DocumentConfig?DocumentConfig Properties:
- country: String (country code)
- document_name: String (display name of document type)
- etsiv2_ready: bool (supports ETSIv2 verification)
- nfc_processable: bool (supports NFC reading)AttachmentsDoc Properties:
- source: String (e.g., 'cropped_face', 'document_front', 'document_back')
- mimetype: String (e.g., 'image/jpeg', 'image/png')
- data: String (base64 encoded image data)Get Document Details
Retrieves detailed information for a specific document and checks its processing status.
final DocumentItem? document = await ShrVaultFlutter.getDetailDocById(
documentId,
context,
);Status Flow & Behavior:
| Status | Behavior | Action |
|---|---|---|
processing | Shows “Document is being processed” message and returns null | User waits for processing to complete |
approved | Returns document and navigates to detail screen | User reviews document and must confirm to proceed |
completed | Returns full document details | Document is fully processed and approved |
declined | Returns document with rejection details | Document verification failed, user can resubmit |
Workflow:
- Call
getDetailDocById()to fetch document - If status is
processing, shows loading message, returnsnull - If status is
approved, navigates to confirmation screen where user confirms - After user confirms, status automatically changes to
completed - If status is
completed, returns document, shows success state
Parameters:
documentId: String – The ID of the document to retrievecontext: BuildContext – For showing dialogs and navigation
Returns:
DocumentItem?– Document details, null if not found or still processing
Recovery Phrase
Get Recovery Phrase
Retrieves the user’s 12-word mnemonic recovery phrase. Requires PIN or biometric authentication.
try {
final String? phrase = await ShrVaultFlutter.getPharse(context);
if (phrase != null) {
print('Recovery phrase retrieved');
// Display securely to user
}
} catch (e) {
print('Error: $e'); // 'User need to login first'
}Parameters:
context: BuildContext – For showing PIN dialog if biometric fails
Returns:
String?– The 12-word mnemonic phrase
Throws:
'User need to login first'if no user is logged in or authentication fails
NFC Operations
Start NFC Reader
Initializes the NFC reader session. Call this before attempting to read an ID card.
await ShrVaultFlutter.startRead();Behavior:
- If NFC is disabled, automatically opens NFC settings (does not throw)
- If NFC is not supported, logs debug message (does not throw)
- Exceptions are handled internally
Check NFC Support
final bool supported = await ShrVaultFlutter.isSupported();
if (supported) {
print('NFC is supported on this device');
}Check NFC Enabled
final bool enabled = await ShrVaultFlutter.isEnabled();
if (!enabled) {
print('NFC is disabled. Please enable it.');
}Open NFC Settings
await ShrVaultFlutter.goToNfcSettings();Read ID Card via NFC
try {
final Map<String, dynamic> data = await ShrVaultFlutter.readIdCard(
documentNumber: 'ABC123456',
dateOfBirth: '901215', // YYMMDD format
dateOfExpiry: '301215', // YYMMDD format
);
print('NFC data: $data');
} on PlatformException catch (e) {
if (e.code == 'NFC_DISABLED') {
print('NFC is disabled');
} else if (e.code == 'NFC_NOT_SUPPORTED') {
print('NFC is not supported');
}
}Listen to NFC Events
ShrVaultFlutter.onNfcEvents().listen((event) {
if (event is Map) {
switch (event['status']) {
case 'ready':
print('NFC ready: ${event['message']}');
break;
case 'reading':
print('Reading: ${event['message']}');
break;
case 'done':
print('Complete: ${event['message']}');
break;
case 'error':
print('Error: ${event['message']}');
break;
}
}
});Backup & Restore
Backup Vault
Exports encrypted backup file containing all vault data.
await ShrVaultFlutter.backupFile(context);
// File will be exported to device downloads/documents folder
print('Backup created successfully');Parameters:
context: BuildContext – For showing file picker/dialogs
Returns:
dynamic– Returnsfalseif user is not logged in or private key is unavailable
Backup Includes:
- All documents and their metadata
- User information
- Encryption keys
- Recovery data
Security:
- Encrypted with user’s private key
- Requires device authentication
Import Backup File
Restores vault data from a previously created backup file.
final bool success = await ShrVaultFlutter.importBackupFile(context);
if (success) {
print('Backup imported successfully');
} else {
print('Import failed or cancelled');
}Parameters:
context: BuildContext – For file picker dialog
Returns:
Future<bool>– Returnstrueif import succeeds,falseif cancelled or failed
Import Process:
- Select backup file from device
- Enter backup password
- Verify integrity
- Restore to local storage
- Sync with server
Requirements:
- Valid backup file (.bak format)
- Correct backup password
- Internet connection for verification
Document Status Constants
The SDK uses the following document status values:
class DOCUMENT_STATUS {
static const String pending = 'pending';
static const String processing = 'processing';
static const String approved = 'approved';
static const String declined = 'declined';
static const String completed = 'completed';
static const String blocked = 'blocked';
}Document Categories
class DOCUMENT_CATEGORY {
static const String goverment = 'GOVERNMENT';
static const String health = 'HEALTH';
static const String other = 'OTHER';
static const String customize = 'CUSTOMIZE';
}Document Name Constants
class DOCUMENT_NAME {
static const String id = 'ID Card';
static const String dl = 'Driver License';
static const String passport = 'Passport';
static const String aadhaar = 'Aadhaar';
static const String pan = 'PAN';
static const String tin = 'TIN Card';
static const String voterCard = 'Voter Card';
static const String residentPermit = 'Resident Permit';
static const String studentId = 'Student ID Card';
}DID Prefixes
The SDK uses the following DID (Decentralized Identifier) prefixes:
const didVCTPrefix = 'did:shr';
const didDVCTPrefix = 'did:dvct';
const didSBTPrefix = 'did:sbt';Example Usage
Complete Authentication Flow
import 'package:flutter/material.dart';
import 'package:shr_vault_flutter/shr_vault_flutter.dart';
import 'package:shr_vault_flutter/models/user/user.dart';
class WelcomeScreen extends StatefulWidget {
@override
State<WelcomeScreen> createState() => _WelcomeScreenState();
}
class _WelcomeScreenState extends State<WelcomeScreen> {
Future<void> _handleSignup() async {
final UserInfo? user = await ShrVaultFlutter.signup(context);
if (user != null) {
// Navigate to main app
print('Signup successful: ${user.email}');
}
}
Future<void> _handleLogin() async {
final UserInfo? user = await ShrVaultFlutter.login(context);
if (user != null) {
// Navigate to main app
print('Login successful: ${user.email}');
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: [
ElevatedButton(
onPressed: _handleSignup,
child: Text('Sign Up'),
),
ElevatedButton(
onPressed: _handleLogin,
child: Text('Login with Recovery Phrase'),
),
],
),
);
}
}Document Management Flow
import 'package:flutter/material.dart';
import 'package:shr_vault_flutter/shr_vault_flutter.dart';
import 'package:shr_vault_flutter/models/document/document_item.dart';
class VaultPage extends StatefulWidget {
@override
State<VaultPage> createState() => _VaultPageState();
}
class _VaultPageState extends State<VaultPage> {
List<DocumentItem>? _documents;
@override
void initState() {
super.initState();
_loadDocuments();
}
Future<void> _loadDocuments() async {
final docs = await ShrVaultFlutter.getListDoc(context);
setState(() {
_documents = docs;
});
}
Future<void> _addDocument() async {
final success = await ShrVaultFlutter.gotoAddDoc(context);
if (success) {
_loadDocuments(); // Refresh list
}
}
Future<void> _viewDocument(String? documentId) async {
if (documentId == null) return;
await ShrVaultFlutter.getDetailDocById(documentId, context);
_loadDocuments(); // Refresh in case status changed
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: _documents == null
? Center(child: CircularProgressIndicator())
: ListView.builder(
itemCount: _documents!.length,
itemBuilder: (context, index) {
final doc = _documents![index];
return ListTile(
title: Text(doc.name),
subtitle: Text('Status: ${doc.status}'),
onTap: () => _viewDocument(doc.document_id),
);
},
),
floatingActionButton: FloatingActionButton(
onPressed: _addDocument,
child: Icon(Icons.add),
),
);
}
}NFC Support by Country
The SDK supports NFC ID card reading for specific countries:
static const countrySupportNFCIDCard = ['BRB', 'VNM'];For passports, NFC reading is available more broadly through the standard ICAO 9303 protocol.
Support
If you need assistance with the ShareRing Vault SDK for Flutter or have any questions about integration, please contact ShareRing support at hello@sharering.network or via the chat button on our website.