Simplify lib api and clean up duplicate code

This commit is contained in:
julian
2023-11-28 09:26:10 -06:00
parent 1ae8d15c3c
commit b76033ffca
5 changed files with 118 additions and 174 deletions

23
lib/extensions.dart Normal file
View 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);
}
}

View File

@@ -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();
}
}