tagion_dart_api 1.0.7 tagion_dart_api: ^1.0.7 copied to clipboard
This plugin serves as a Dart interface to the existing Tagion API, designed to streamline its integration and usage within the Dart/Flutter ecosystem.
import 'dart:ffi';
import 'package:crypto/crypto.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:tagion_dart_api/enums/document_error_code.dart';
import 'package:tagion_dart_api/enums/text_format.dart';
import 'package:tagion_dart_api/exception/crypto_exception.dart';
import 'package:tagion_dart_api/module/basic/basic.dart';
import 'package:tagion_dart_api/module/crypto/crypto.dart';
import 'package:tagion_dart_api/module/crypto/crypto_interface.dart';
import 'package:tagion_dart_api/module/crypto/ffi/crypto_ffi.dart';
import 'package:tagion_dart_api/module/document/document.dart';
import 'package:tagion_dart_api/module/hibon/hibon.dart';
import 'package:tagion_dart_api/pointer_manager/pointer_manager.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({super.key});
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
//
late final TGNBasic _basic;
late final ICrypto _crypto;
//
final TextEditingController _passPhraseCtrl =
TextEditingController(text: 'pass phrase example');
final TextEditingController _pinCodeCtrl =
TextEditingController(text: '123456');
final TextEditingController _keyPairCtrl = TextEditingController();
final TextEditingController _hibonCtrl = TextEditingController();
final TextEditingController _signatureCtrl = TextEditingController();
//
final FocusNode _passPhraseFN = FocusNode();
final FocusNode _pinCodeFN = FocusNode();
final FocusNode _keyPairFN = FocusNode();
final FocusNode _hibonFN = FocusNode();
final FocusNode _signatureFN = FocusNode();
//
late final Pointer<SecureNet> _secureNetPtr;
//
Uint8List? _keyPair;
Uint8List? _hibon;
String? _hibonStatus;
String? _signatureStatus;
//
final Map<String, bool> _collapsedState = {
'keyPair': false,
'hibon': false,
'signature': false,
};
@override
void initState() {
super.initState();
//
_secureNetPtr = const PointerManager().allocate<SecureNet>();
//
_basic = TGNBasic.init();
_basic.startDRuntime();
//
_crypto = TGNCrypto.init();
}
void _generateKeypair() {
_keyPair = _crypto.generateKeypair(
_passPhraseCtrl.text,
_pinCodeCtrl.text,
'',
_secureNetPtr,
);
_keyPairCtrl.text = _toBase64Url(_keyPair);
_unfocus();
}
void _signData() {
setState(() {
try {
if (_hibon == null) {
_signatureStatus = 'Create hibon first';
return;
}
List<int> dataHash = sha256.convert(_hibon!).bytes;
_signatureCtrl.text = _toBase64Url(
_crypto.sign(Uint8List.fromList(dataHash), _secureNetPtr));
_signatureStatus = 'Signed';
} on CryptoApiException catch (e) {
_signatureStatus =
'Failed: ${e.runtimeType}: ${e.errorCode.toString()} - ${e.message}';
}
});
}
String _toBase64Url(Uint8List? data) {
if (data == null) return 'No data';
return _basic.encodeBase64Url(data);
}
// Create a hibon.
void _createHibon() {
TGNHibon bill = TGNHibon.init();
bill.create();
bill.addString("\$@", "TGN");
TGNHibon value = TGNHibon.init();
value.create();
value.addInt<Uint64>("\$", 1000);
bill.addHibonByKey("\$V", value);
bill.addArrayByKey("\$Y", Uint8List.fromList([1, 2, 3, 4, 5]));
bill.addTime("\$t", DateTime.now().millisecondsSinceEpoch);
_hibon = bill.getAsDocumentBuffer();
_representHibon(_hibon, TextFormat.prettyJson);
}
void _representHibon(Uint8List? hibon, TextFormat textFormat) {
if (hibon == null) return;
TGNDocument doc = TGNDocument.init(hibon);
_hibonCtrl.text = doc.getAsString(textFormat);
}
// Read the hibon with a Document.
void _validateHibon() {
if (_hibon == null) {
setState(() {
_hibonStatus = 'No hibon';
});
return;
}
TGNDocument doc = TGNDocument.init(_hibon!);
DocumentErrorCode code = doc.validate();
setState(() {
if (code == DocumentErrorCode.none) {
_hibonStatus = 'Valid';
} else {
_hibonStatus = code.toString();
}
});
}
void _clearKeyPair() {
_passPhraseCtrl.clear();
_pinCodeCtrl.clear();
_keyPairCtrl.clear();
_keyPair = null;
const PointerManager().zeroOutAndFree(_secureNetPtr, 1);
}
void _clearHibon() {
_hibonCtrl.clear();
_hibon = null;
}
void _unfocus() {
_passPhraseFN.unfocus();
_pinCodeFN.unfocus();
_keyPairFN.unfocus();
}
Widget _buildCollapsableContainer({
required String key,
required String title,
required Widget child,
}) {
return GestureDetector(
onTap: () {
setState(() {
_collapsedState[key] = !_collapsedState[key]!;
});
},
child: Container(
key: Key(key),
padding: const EdgeInsets.all(10),
width: double.infinity,
margin: const EdgeInsets.only(bottom: 10),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(10),
),
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(title, style: const TextStyle(fontSize: 16)),
Icon(_collapsedState[key]!
? Icons.arrow_drop_down
: Icons.arrow_drop_up),
],
),
Visibility(
visible: _collapsedState[key]!,
child: child,
),
],
),
));
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
backgroundColor: Colors.white70,
appBar: AppBar(
title: const Text('Example'),
),
body: Padding(
padding: const EdgeInsets.all(8.0),
child: GestureDetector(
onTap: _unfocus,
child: SingleChildScrollView(
child: Center(
child: Column(
children: [
_buildCollapsableContainer(
key: 'keyPair',
title: 'Key pair',
child: Column(
children: [
TextField(
decoration:
const InputDecoration(labelText: 'Pass phrase'),
controller: _passPhraseCtrl,
focusNode: _passPhraseFN,
minLines: 1,
maxLines: 3,
onChanged: (value) {
_passPhraseCtrl.text = value;
},
),
TextField(
decoration:
const InputDecoration(labelText: 'Pin code'),
controller: _pinCodeCtrl,
focusNode: _pinCodeFN,
onChanged: (value) {
_pinCodeCtrl.text = value;
},
),
TextField(
decoration:
const InputDecoration(labelText: 'Result'),
controller: _keyPairCtrl,
focusNode: _keyPairFN,
readOnly: true,
minLines: 1,
maxLines: 8,
),
const SizedBox(height: 10),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
OutlinedButton(
onPressed: _generateKeypair,
child: const Text('Generate'),
),
const SizedBox(width: 10),
OutlinedButton(
onPressed: _clearKeyPair,
child: const Text('Clear'),
),
],
),
],
),
),
_buildCollapsableContainer(
key: 'hibon',
title: 'Hibon',
child: Column(
children: [
TextField(
decoration:
const InputDecoration(labelText: 'Hibon'),
controller: _hibonCtrl,
focusNode: _hibonFN,
minLines: 1,
maxLines: 100,
onChanged: (value) {
_passPhraseCtrl.text = value;
},
),
const SizedBox(height: 10),
Text(_hibonStatus ?? ''),
const SizedBox(height: 10),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
OutlinedButton(
onPressed: _createHibon,
child: const Text('Generate'),
),
const SizedBox(width: 10),
OutlinedButton(
onPressed: _validateHibon,
child: const Text('Validate'),
),
const SizedBox(width: 10),
OutlinedButton(
onPressed: _clearHibon,
child: const Text('Clear'),
),
],
),
],
),
),
_buildCollapsableContainer(
key: 'signature',
title: 'Sign a hibon',
child: Column(
children: [
TextField(
decoration:
const InputDecoration(labelText: 'Result'),
controller: _signatureCtrl,
focusNode: _signatureFN,
readOnly: true,
minLines: 1,
maxLines: 10,
),
const SizedBox(height: 10),
Text(_signatureStatus ?? ''),
const SizedBox(height: 10),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
OutlinedButton(
onPressed: _signData,
child: const Text('Sign'),
),
const SizedBox(width: 10),
OutlinedButton(
onPressed: _clearHibon,
child: const Text('Clear'),
),
],
),
],
),
),
],
),
),
),
),
),
),
);
}
}