mirror of
https://github.com/MAGICGrants/flutter_libsparkmobile.git
synced 2026-01-09 21:17:56 -05:00
Simplify lib api and clean up duplicate code
This commit is contained in:
23
lib/extensions.dart
Normal file
23
lib/extensions.dart
Normal file
@@ -0,0 +1,23 @@
|
||||
import 'dart:typed_data';
|
||||
|
||||
extension Uint8ListExt on Uint8List {
|
||||
String toHexString() {
|
||||
return map((byte) => byte.toRadixString(16).padLeft(2, '0')).join();
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert a hex string to a list of bytes, padded to 32 bytes if necessary.
|
||||
extension StringExt on String {
|
||||
Uint8List toBytes() {
|
||||
// Pad the string to 64 characters with zeros if it's shorter.
|
||||
String hexString = padLeft(64, '0');
|
||||
|
||||
List<int> bytes = [];
|
||||
for (int i = 0; i < hexString.length; i += 2) {
|
||||
var byteString = hexString.substring(i, i + 2);
|
||||
var byteValue = int.parse(byteString, radix: 16);
|
||||
bytes.add(byteValue);
|
||||
}
|
||||
return Uint8List.fromList(bytes);
|
||||
}
|
||||
}
|
||||
@@ -1,37 +1,86 @@
|
||||
import 'dart:ffi';
|
||||
import 'dart:io';
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:ffi/ffi.dart';
|
||||
import 'package:flutter_libsparkmobile/extensions.dart';
|
||||
|
||||
import 'flutter_libsparkmobile_bindings.dart';
|
||||
import 'flutter_libsparkmobile_platform_interface.dart';
|
||||
|
||||
class FlutterLibsparkmobile {
|
||||
final SparkMobileBindings _bindings;
|
||||
const kSparkChain = 6;
|
||||
const kSparkBaseDerivationPath = "m/44'/136'/0'/$kSparkChain/";
|
||||
|
||||
FlutterLibsparkmobile(DynamicLibrary dynamicLibrary)
|
||||
: _bindings = SparkMobileBindings(dynamicLibrary);
|
||||
abstract final class LibSpark {
|
||||
static SparkMobileBindings? _bindings;
|
||||
|
||||
Future<String?> getPlatformVersion() {
|
||||
return FlutterLibsparkmobilePlatform.instance.getPlatformVersion();
|
||||
static void _checkLoaded() {
|
||||
_bindings ??= SparkMobileBindings(_loadLibrary());
|
||||
}
|
||||
|
||||
static DynamicLibrary _loadLibrary() {
|
||||
// hack in prefix for test env
|
||||
String testPrefix = "";
|
||||
if (Platform.environment.containsKey('FLUTTER_TEST')) {
|
||||
if (Platform.isLinux) {
|
||||
testPrefix = 'scripts/linux/build/';
|
||||
} else if (Platform.isMacOS) {
|
||||
testPrefix = 'scripts/macos/build/';
|
||||
} else if (Platform.isWindows) {
|
||||
testPrefix = 'scripts/windows/build/';
|
||||
} else {
|
||||
throw UnsupportedError('This platform is not supported');
|
||||
}
|
||||
}
|
||||
|
||||
if (Platform.isLinux) {
|
||||
return DynamicLibrary.open('${testPrefix}libsparkmobile.so');
|
||||
} else if (Platform.isAndroid) {
|
||||
// return DynamicLibrary.open('${testPrefix}libsparkmobile.so');
|
||||
} else if (Platform.isIOS) {
|
||||
// return DynamicLibrary.open('${testPrefix}libsparkmobile.dylib');
|
||||
} else if (Platform.isMacOS) {
|
||||
// return DynamicLibrary.open('${testPrefix}libsparkmobile.dylib');
|
||||
} else if (Platform.isWindows) {
|
||||
// return DynamicLibrary.open('${testPrefix}sparkmobile.dll');
|
||||
}
|
||||
throw UnsupportedError('This platform is not supported');
|
||||
}
|
||||
|
||||
// SparkMobileBindings methods:
|
||||
|
||||
/// Derive an address from the keyData (mnemonic).
|
||||
Future<String> getAddress(
|
||||
List<int> keyData, int index, int diversifier, bool isTestNet) async {
|
||||
// Validate that the keyData is 32 bytes.
|
||||
if (keyData.length != 32) {
|
||||
throw 'Key data must be 32 bytes.';
|
||||
static Future<String> getAddress({
|
||||
required Uint8List privateKey,
|
||||
required int index,
|
||||
required int diversifier,
|
||||
bool isTestNet = false,
|
||||
}) async {
|
||||
_checkLoaded();
|
||||
|
||||
if (index < 0) {
|
||||
throw Exception("Index must not be negative.");
|
||||
}
|
||||
|
||||
if (diversifier < 0) {
|
||||
throw Exception("Diversifier must not be negative.");
|
||||
}
|
||||
|
||||
if (privateKey.length != 32) {
|
||||
throw Exception(
|
||||
"Invalid private key length: ${privateKey.length}. Must be 32 bytes.",
|
||||
);
|
||||
}
|
||||
|
||||
// Allocate memory for the hex string on the native heap.
|
||||
final keyDataHex = keyData.toHexString();
|
||||
final keyDataPointer = keyDataHex.toNativeUtf8().cast<Char>();
|
||||
final keyDataPointer = privateKey.toHexString().toNativeUtf8().cast<Char>();
|
||||
|
||||
// Call the native method with the pointer.
|
||||
final addressPointer = _bindings.getAddress(
|
||||
keyDataPointer, index, diversifier, isTestNet ? 1 : 0);
|
||||
final addressPointer = _bindings!.getAddress(
|
||||
keyDataPointer,
|
||||
index,
|
||||
diversifier,
|
||||
isTestNet ? 1 : 0,
|
||||
);
|
||||
|
||||
// Convert the Pointer<Char> to a Dart String.
|
||||
final addressString = addressPointer.cast<Utf8>().toDartString();
|
||||
@@ -43,10 +92,3 @@ class FlutterLibsparkmobile {
|
||||
return addressString;
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert List<int> keyData to a hex string.
|
||||
extension on List<int> {
|
||||
String toHexString() {
|
||||
return map((byte) => byte.toRadixString(16).padLeft(2, '0')).join();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user