mirror of
https://github.com/cypherstack/stack_wallet.git
synced 2025-01-11 05:04:35 +00:00
WIP database schema for spark coin data
This commit is contained in:
parent
734e9d90b1
commit
9ad723a5b2
3 changed files with 3023 additions and 12 deletions
126
lib/wallets/isar/models/spark_coin.dart
Normal file
126
lib/wallets/isar/models/spark_coin.dart
Normal file
|
@ -0,0 +1,126 @@
|
||||||
|
import 'package:isar/isar.dart';
|
||||||
|
|
||||||
|
part 'spark_coin.g.dart';
|
||||||
|
|
||||||
|
enum SparkCoinType {
|
||||||
|
mint(0),
|
||||||
|
spend(1);
|
||||||
|
|
||||||
|
const SparkCoinType(this.value);
|
||||||
|
|
||||||
|
final int value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Collection()
|
||||||
|
class SparkCoin {
|
||||||
|
Id id = Isar.autoIncrement;
|
||||||
|
|
||||||
|
@Index(
|
||||||
|
unique: true,
|
||||||
|
replace: true,
|
||||||
|
composite: [
|
||||||
|
CompositeIndex("lTagHash"),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
final String walletId;
|
||||||
|
|
||||||
|
@enumerated
|
||||||
|
final SparkCoinType type;
|
||||||
|
|
||||||
|
final bool isUsed;
|
||||||
|
|
||||||
|
final List<int>? k; // TODO: proper name (not single char!!) is this nonce???
|
||||||
|
|
||||||
|
final String address;
|
||||||
|
final String txHash;
|
||||||
|
|
||||||
|
final String valueIntString;
|
||||||
|
|
||||||
|
final String? memo;
|
||||||
|
final List<int>? serialContext;
|
||||||
|
|
||||||
|
final String diversifierIntString;
|
||||||
|
final List<int>? encryptedDiversifier;
|
||||||
|
|
||||||
|
final List<int>? serial;
|
||||||
|
final List<int>? tag;
|
||||||
|
|
||||||
|
final String lTagHash;
|
||||||
|
|
||||||
|
@ignore
|
||||||
|
BigInt get value => BigInt.parse(valueIntString);
|
||||||
|
|
||||||
|
@ignore
|
||||||
|
BigInt get diversifier => BigInt.parse(diversifierIntString);
|
||||||
|
|
||||||
|
SparkCoin({
|
||||||
|
required this.walletId,
|
||||||
|
required this.type,
|
||||||
|
required this.isUsed,
|
||||||
|
this.k,
|
||||||
|
required this.address,
|
||||||
|
required this.txHash,
|
||||||
|
required this.valueIntString,
|
||||||
|
this.memo,
|
||||||
|
this.serialContext,
|
||||||
|
required this.diversifierIntString,
|
||||||
|
this.encryptedDiversifier,
|
||||||
|
this.serial,
|
||||||
|
this.tag,
|
||||||
|
required this.lTagHash,
|
||||||
|
});
|
||||||
|
|
||||||
|
SparkCoin copyWith({
|
||||||
|
SparkCoinType? type,
|
||||||
|
bool? isUsed,
|
||||||
|
List<int>? k,
|
||||||
|
String? address,
|
||||||
|
String? txHash,
|
||||||
|
BigInt? value,
|
||||||
|
String? memo,
|
||||||
|
List<int>? serialContext,
|
||||||
|
BigInt? diversifier,
|
||||||
|
List<int>? encryptedDiversifier,
|
||||||
|
List<int>? serial,
|
||||||
|
List<int>? tag,
|
||||||
|
String? lTagHash,
|
||||||
|
}) {
|
||||||
|
return SparkCoin(
|
||||||
|
walletId: walletId,
|
||||||
|
type: type ?? this.type,
|
||||||
|
isUsed: isUsed ?? this.isUsed,
|
||||||
|
k: k ?? this.k,
|
||||||
|
address: address ?? this.address,
|
||||||
|
txHash: txHash ?? this.txHash,
|
||||||
|
valueIntString: value?.toString() ?? this.value.toString(),
|
||||||
|
memo: memo ?? this.memo,
|
||||||
|
serialContext: serialContext ?? this.serialContext,
|
||||||
|
diversifierIntString:
|
||||||
|
diversifier?.toString() ?? this.diversifier.toString(),
|
||||||
|
encryptedDiversifier: encryptedDiversifier ?? this.encryptedDiversifier,
|
||||||
|
serial: serial ?? this.serial,
|
||||||
|
tag: tag ?? this.tag,
|
||||||
|
lTagHash: lTagHash ?? this.lTagHash,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'SparkCoin('
|
||||||
|
', walletId: $walletId'
|
||||||
|
', type: $type'
|
||||||
|
', isUsed: $isUsed'
|
||||||
|
', k: $k'
|
||||||
|
', address: $address'
|
||||||
|
', txHash: $txHash'
|
||||||
|
', value: $value'
|
||||||
|
', memo: $memo'
|
||||||
|
', serialContext: $serialContext'
|
||||||
|
', diversifier: $diversifier'
|
||||||
|
', encryptedDiversifier: $encryptedDiversifier'
|
||||||
|
', serial: $serial'
|
||||||
|
', tag: $tag'
|
||||||
|
', lTagHash: $lTagHash'
|
||||||
|
')';
|
||||||
|
}
|
||||||
|
}
|
2828
lib/wallets/isar/models/spark_coin.g.dart
Normal file
2828
lib/wallets/isar/models/spark_coin.g.dart
Normal file
File diff suppressed because it is too large
Load diff
|
@ -4,7 +4,9 @@ import 'package:flutter_libsparkmobile/flutter_libsparkmobile.dart';
|
||||||
import 'package:isar/isar.dart';
|
import 'package:isar/isar.dart';
|
||||||
import 'package:stackwallet/models/isar/models/blockchain_data/address.dart';
|
import 'package:stackwallet/models/isar/models/blockchain_data/address.dart';
|
||||||
import 'package:stackwallet/utilities/amount/amount.dart';
|
import 'package:stackwallet/utilities/amount/amount.dart';
|
||||||
|
import 'package:stackwallet/utilities/extensions/impl/uint8_list.dart';
|
||||||
import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
|
import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
|
||||||
|
import 'package:stackwallet/wallets/isar/models/spark_coin.dart';
|
||||||
import 'package:stackwallet/wallets/models/tx_data.dart';
|
import 'package:stackwallet/wallets/models/tx_data.dart';
|
||||||
import 'package:stackwallet/wallets/wallet/intermediate/bip39_hd_wallet.dart';
|
import 'package:stackwallet/wallets/wallet/intermediate/bip39_hd_wallet.dart';
|
||||||
import 'package:stackwallet/wallets/wallet/wallet_mixin_interfaces/electrumx_interface.dart';
|
import 'package:stackwallet/wallets/wallet/wallet_mixin_interfaces/electrumx_interface.dart';
|
||||||
|
@ -151,26 +153,81 @@ mixin SparkInterface on Bip39HDWallet, ElectrumXInterface {
|
||||||
// have not yet parsed.
|
// have not yet parsed.
|
||||||
Future<void> refreshSparkData() async {
|
Future<void> refreshSparkData() async {
|
||||||
try {
|
try {
|
||||||
|
final privateKeyHex = "TODO";
|
||||||
|
final index = 0;
|
||||||
|
|
||||||
final latestSparkCoinId = await electrumXClient.getSparkLatestCoinId();
|
final latestSparkCoinId = await electrumXClient.getSparkLatestCoinId();
|
||||||
|
|
||||||
// TODO improve performance by adding this call to the cached client
|
// TODO improve performance by adding these calls to the cached client
|
||||||
final anonymitySet = await electrumXClient.getSparkAnonymitySet(
|
final futureResults = await Future.wait([
|
||||||
coinGroupId: latestSparkCoinId.toString(),
|
electrumXClient.getSparkAnonymitySet(
|
||||||
);
|
coinGroupId: latestSparkCoinId.toString(),
|
||||||
|
),
|
||||||
|
electrumXClient.getSparkUsedCoinsTags(
|
||||||
|
startNumber: 0,
|
||||||
|
),
|
||||||
|
]);
|
||||||
|
|
||||||
// TODO loop over set and see which coins are ours using the FFI call `identifyCoin`
|
final anonymitySet = futureResults[0];
|
||||||
List myCoins = [];
|
final spentCoinTags = List<String>.from(
|
||||||
|
futureResults[1]["tags"] as List,
|
||||||
|
).toSet();
|
||||||
|
|
||||||
// fetch metadata for myCoins
|
// find our coins
|
||||||
|
final List<SparkCoin> myCoins = [];
|
||||||
|
for (final data
|
||||||
|
in List<List<String>>.from(anonymitySet["coin"] as List)) {
|
||||||
|
if (data.length != 2) {
|
||||||
|
throw Exception("Unexpected serialized coin info found");
|
||||||
|
}
|
||||||
|
|
||||||
// check against spent list (this call could possibly also be cached later on)
|
final serializedCoin = data.first;
|
||||||
final spentCoinTags = await electrumXClient.getSparkUsedCoinsTags(
|
final txHash = data.last;
|
||||||
startNumber: 0,
|
|
||||||
);
|
|
||||||
|
|
||||||
// create list of Spark Coin isar objects
|
final coin = LibSpark.identifyAndRecoverCoin(
|
||||||
|
serializedCoin,
|
||||||
|
privateKeyHex: privateKeyHex,
|
||||||
|
index: index,
|
||||||
|
);
|
||||||
|
|
||||||
|
// its ours
|
||||||
|
if (coin != null) {
|
||||||
|
final SparkCoinType coinType;
|
||||||
|
switch (coin.type.value) {
|
||||||
|
case 0:
|
||||||
|
coinType = SparkCoinType.mint;
|
||||||
|
case 1:
|
||||||
|
coinType = SparkCoinType.spend;
|
||||||
|
default:
|
||||||
|
throw Exception("Unknown spark coin type detected");
|
||||||
|
}
|
||||||
|
myCoins.add(
|
||||||
|
SparkCoin(
|
||||||
|
walletId: walletId,
|
||||||
|
type: coinType,
|
||||||
|
isUsed: spentCoinTags
|
||||||
|
.contains(coin.lTagHash!.toHex), // TODO: is hex right?
|
||||||
|
address: coin.address!,
|
||||||
|
txHash: txHash,
|
||||||
|
valueIntString: coin.value!.toString(),
|
||||||
|
lTagHash: coin.lTagHash!.toHex, // TODO: is hex right?
|
||||||
|
tag: coin.tag,
|
||||||
|
memo: coin.memo,
|
||||||
|
serial: coin.serial,
|
||||||
|
serialContext: coin.serialContext,
|
||||||
|
diversifierIntString: coin.diversifier!.toString(),
|
||||||
|
encryptedDiversifier: coin.encryptedDiversifier,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// update wallet spark coins in isar
|
// update wallet spark coins in isar
|
||||||
|
if (myCoins.isNotEmpty) {
|
||||||
|
await mainDB.isar.writeTxn(() async {
|
||||||
|
await mainDB.isar.sparkCoins.putAll(myCoins);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// refresh spark balance?
|
// refresh spark balance?
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue