Merge branch 'electrum_adapter' into testing

This commit is contained in:
sneurlax 2024-02-14 11:20:29 -06:00
commit c9754c2739
6 changed files with 117 additions and 141 deletions

View file

@ -11,6 +11,7 @@
import 'dart:convert'; import 'dart:convert';
import 'dart:math'; import 'dart:math';
import 'package:electrum_adapter/electrum_adapter.dart' as electrum_adapter;
import 'package:stackwallet/db/hive/db.dart'; import 'package:stackwallet/db/hive/db.dart';
import 'package:stackwallet/electrumx_rpc/electrumx_client.dart'; import 'package:stackwallet/electrumx_rpc/electrumx_client.dart';
import 'package:stackwallet/utilities/enums/coin_enum.dart'; import 'package:stackwallet/utilities/enums/coin_enum.dart';
@ -188,8 +189,11 @@ class CachedElectrumXClient {
final cachedTx = box.get(txHash) as Map?; final cachedTx = box.get(txHash) as Map?;
if (cachedTx == null) { if (cachedTx == null) {
final Map<String, dynamic> result = await electrumXClient var channel = await electrum_adapter.connect(electrumXClient.host,
.getTransaction(txHash: txHash, verbose: verbose); port: electrumXClient.port); // TODO pass useSLL.
var client = electrum_adapter.ElectrumClient(
channel, electrumXClient.host, electrumXClient.port);
final Map<String, dynamic> result = await client.getTransaction(txHash);
result.remove("hex"); result.remove("hex");
result.remove("lelantusData"); result.remove("lelantusData");

View file

@ -14,6 +14,8 @@ import 'dart:io';
import 'package:connectivity_plus/connectivity_plus.dart'; import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:decimal/decimal.dart'; import 'package:decimal/decimal.dart';
import 'package:electrum_adapter/electrum_adapter.dart' as electrum_adapter;
import 'package:electrum_adapter/methods/specific/firo.dart';
import 'package:event_bus/event_bus.dart'; import 'package:event_bus/event_bus.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter_libsparkmobile/flutter_libsparkmobile.dart'; import 'package:flutter_libsparkmobile/flutter_libsparkmobile.dart';
@ -741,41 +743,20 @@ class ElectrumXClient {
bool verbose = true, bool verbose = true,
String? requestID, String? requestID,
}) async { }) async {
dynamic response; Logging.instance.log("attempting to fetch blockchain.transaction.get...",
try { level: LogLevel.Info);
response = await request( var channel =
requestID: requestID, await electrum_adapter.connect(host, port: port); // TODO pass useSLL.
command: 'blockchain.transaction.get', var client = electrum_adapter.ElectrumClient(channel, host, port);
args: [ dynamic response = await client.getTransaction(txHash);
txHash, Logging.instance.log("Fetching blockchain.transaction.get finished",
verbose, level: LogLevel.Info);
],
);
if (!verbose) { if (!verbose) {
return {"rawtx": response["result"] as String}; return {"rawtx": response as String};
} }
if (response is! Map) { return Map<String, dynamic>.from(response as Map);
final String msg = "getTransaction($txHash) returned a non-Map response"
" of type ${response.runtimeType}.\nResponse: $response";
Logging.instance.log(msg, level: LogLevel.Fatal);
throw Exception(msg);
}
if (response["result"] == null) {
final String msg = "getTransaction($txHash) returned null result."
"\nResponse: $response";
Logging.instance.log(msg, level: LogLevel.Fatal);
throw Exception(msg);
}
return Map<String, dynamic>.from(response["result"] as Map);
} catch (e, s) {
Logging.instance.log(
"getTransaction($txHash) response: $response"
"\nError: $e\nStack trace: $s",
level: LogLevel.Error);
rethrow;
}
} }
/// Returns the whole Lelantus anonymity set for denomination in the groupId. /// Returns the whole Lelantus anonymity set for denomination in the groupId.
@ -797,23 +778,15 @@ class ElectrumXClient {
String blockhash = "", String blockhash = "",
String? requestID, String? requestID,
}) async { }) async {
try {
Logging.instance.log("attempting to fetch lelantus.getanonymityset...", Logging.instance.log("attempting to fetch lelantus.getanonymityset...",
level: LogLevel.Info); level: LogLevel.Info);
final response = await request( var channel = await electrum_adapter.connect(host, port: port);
requestID: requestID, var client = electrum_adapter.FiroElectrumClient(channel);
command: 'lelantus.getanonymityset', Map<String, dynamic> anonymitySet = await client.getLelantusAnonymitySet(
args: [ groupId: groupId, blockHash: blockhash);
groupId,
blockhash,
],
);
Logging.instance.log("Fetching lelantus.getanonymityset finished", Logging.instance.log("Fetching lelantus.getanonymityset finished",
level: LogLevel.Info); level: LogLevel.Info);
return Map<String, dynamic>.from(response["result"] as Map); return anonymitySet;
} catch (e) {
rethrow;
}
} }
//TODO add example to docs //TODO add example to docs
@ -824,18 +797,14 @@ class ElectrumXClient {
dynamic mints, dynamic mints,
String? requestID, String? requestID,
}) async { }) async {
try { Logging.instance.log("attempting to fetch lelantus.getmintmetadata...",
final response = await request( level: LogLevel.Info);
requestID: requestID, var channel = await electrum_adapter.connect(host, port: port);
command: 'lelantus.getmintmetadata', var client = electrum_adapter.FiroElectrumClient(channel);
args: [ dynamic mintData = await client.getLelantusMintData(mints: mints);
mints, Logging.instance.log("Fetching lelantus.getmintmetadata finished",
], level: LogLevel.Info);
); return mintData;
return response["result"];
} catch (e) {
rethrow;
}
} }
//TODO add example to docs //TODO add example to docs
@ -844,45 +813,39 @@ class ElectrumXClient {
String? requestID, String? requestID,
required int startNumber, required int startNumber,
}) async { }) async {
try { Logging.instance.log("attempting to fetch lelantus.getusedcoinserials...",
level: LogLevel.Info);
var channel = await electrum_adapter.connect('firo.stackwallet.com');
var client = electrum_adapter.FiroElectrumClient(channel);
int retryCount = 3; int retryCount = 3;
dynamic result; dynamic usedCoinSerials;
while (retryCount > 0 && result is! List) { while (retryCount > 0 && usedCoinSerials is! List) {
final response = await request( usedCoinSerials =
requestID: requestID, await client.getLelantusUsedCoinSerials(startNumber: startNumber);
command: 'lelantus.getusedcoinserials', // TODO add 2 minute timeout.
args: [ Logging.instance.log("Fetching lelantus.getusedcoinserials finished",
"$startNumber", level: LogLevel.Info);
],
requestTimeout: const Duration(minutes: 2),
);
result = response["result"];
retryCount--; retryCount--;
} }
return Map<String, dynamic>.from(result as Map); return Map<String, dynamic>.from(usedCoinSerials as Map);
} catch (e) {
Logging.instance.log(e, level: LogLevel.Error);
rethrow;
}
} }
/// Returns the latest Lelantus set id /// Returns the latest Lelantus set id
/// ///
/// ex: 1 /// ex: 1
Future<int> getLelantusLatestCoinId({String? requestID}) async { Future<int> getLelantusLatestCoinId({String? requestID}) async {
try { Logging.instance.log("attempting to fetch lelantus.getlatestcoinid...",
final response = await request( level: LogLevel.Info);
requestID: requestID, var channel = await electrum_adapter.connect('firo.stackwallet.com');
command: 'lelantus.getlatestcoinid', var client = electrum_adapter.FiroElectrumClient(channel);
); int latestCoinId = await client.getLatestCoinId();
return response["result"] as int; Logging.instance.log("Fetching lelantus.getlatestcoinid finished",
} catch (e) { level: LogLevel.Info);
Logging.instance.log(e, level: LogLevel.Error); return latestCoinId;
rethrow;
}
} }
// ============== Spark ====================================================== // ============== Spark ======================================================
@ -908,17 +871,13 @@ class ElectrumXClient {
try { try {
Logging.instance.log("attempting to fetch spark.getsparkanonymityset...", Logging.instance.log("attempting to fetch spark.getsparkanonymityset...",
level: LogLevel.Info); level: LogLevel.Info);
final response = await request( var channel = await electrum_adapter.connect('firo.stackwallet.com');
requestID: requestID, var client = electrum_adapter.FiroElectrumClient(channel);
command: 'spark.getsparkanonymityset', Map<String, dynamic> anonymitySet = await client.getSparkAnonymitySet(
args: [ coinGroupId: coinGroupId, startBlockHash: startBlockHash);
coinGroupId,
startBlockHash,
],
);
Logging.instance.log("Fetching spark.getsparkanonymityset finished", Logging.instance.log("Fetching spark.getsparkanonymityset finished",
level: LogLevel.Info); level: LogLevel.Info);
return Map<String, dynamic>.from(response["result"] as Map); return anonymitySet;
} catch (e) { } catch (e) {
rethrow; rethrow;
} }
@ -931,15 +890,17 @@ class ElectrumXClient {
required int startNumber, required int startNumber,
}) async { }) async {
try { try {
final response = await request( // Use electrum_adapter package's getSparkUsedCoinsTags method.
requestID: requestID, Logging.instance.log("attempting to fetch spark.getusedcoinstags...",
command: 'spark.getusedcoinstags', level: LogLevel.Info);
args: [ var channel = await electrum_adapter.connect('firo.stackwallet.com');
"$startNumber", var client = electrum_adapter.FiroElectrumClient(channel);
], Map<String, dynamic> usedCoinsTags =
requestTimeout: const Duration(minutes: 2), await client.getUsedCoinsTags(startNumber: startNumber);
); // TODO: Add 2 minute timeout.
final map = Map<String, dynamic>.from(response["result"] as Map); Logging.instance.log("Fetching spark.getusedcoinstags finished",
level: LogLevel.Info);
final map = Map<String, dynamic>.from(usedCoinsTags);
final set = Set<String>.from(map["tags"] as List); final set = Set<String>.from(map["tags"] as List);
return await compute(_ffiHashTagsComputeWrapper, set); return await compute(_ffiHashTagsComputeWrapper, set);
} catch (e) { } catch (e) {
@ -963,16 +924,15 @@ class ElectrumXClient {
required List<String> sparkCoinHashes, required List<String> sparkCoinHashes,
}) async { }) async {
try { try {
final response = await request( Logging.instance.log("attempting to fetch spark.getsparkmintmetadata...",
requestID: requestID, level: LogLevel.Info);
command: 'spark.getsparkmintmetadata', var channel = await electrum_adapter.connect('firo.stackwallet.com');
args: [ var client = electrum_adapter.FiroElectrumClient(channel);
{ List<dynamic> mintMetaData =
"coinHashes": sparkCoinHashes, await client.getSparkMintMetaData(sparkCoinHashes: sparkCoinHashes);
}, Logging.instance.log("Fetching spark.getsparkmintmetadata finished",
], level: LogLevel.Info);
); return List<Map<String, dynamic>>.from(mintMetaData);
return List<Map<String, dynamic>>.from(response["result"] as List);
} catch (e) { } catch (e) {
Logging.instance.log(e, level: LogLevel.Error); Logging.instance.log(e, level: LogLevel.Error);
rethrow; rethrow;
@ -986,11 +946,14 @@ class ElectrumXClient {
String? requestID, String? requestID,
}) async { }) async {
try { try {
final response = await request( Logging.instance.log("attempting to fetch spark.getsparklatestcoinid...",
requestID: requestID, level: LogLevel.Info);
command: 'spark.getsparklatestcoinid', var channel = await electrum_adapter.connect(host, port: port);
); var client = electrum_adapter.FiroElectrumClient(channel);
return response["result"] as int; int latestCoinId = await client.getSparkLatestCoinId();
Logging.instance.log("Fetching spark.getsparklatestcoinid finished",
level: LogLevel.Info);
return latestCoinId;
} catch (e) { } catch (e) {
Logging.instance.log(e, level: LogLevel.Error); Logging.instance.log(e, level: LogLevel.Error);
rethrow; rethrow;
@ -1007,15 +970,9 @@ class ElectrumXClient {
/// "rate": 1000, /// "rate": 1000,
/// } /// }
Future<Map<String, dynamic>> getFeeRate({String? requestID}) async { Future<Map<String, dynamic>> getFeeRate({String? requestID}) async {
try { var channel = await electrum_adapter.connect(host, port: port);
final response = await request( var client = electrum_adapter.FiroElectrumClient(channel);
requestID: requestID, return await client.getFeeRate();
command: 'blockchain.getfeerate',
);
return Map<String, dynamic>.from(response["result"] as Map);
} catch (e) {
rethrow;
}
} }
/// Return the estimated transaction fee per kilobyte for a transaction to be confirmed within a certain number of [blocks]. /// Return the estimated transaction fee per kilobyte for a transaction to be confirmed within a certain number of [blocks].

View file

@ -1250,6 +1250,8 @@ mixin ElectrumXInterface<T extends Bip39HDCurrency> on Bip39HDWallet<T> {
coin: cryptoCurrency.coin, coin: cryptoCurrency.coin,
); );
print("txn: $txn");
final vout = jsonUTXO["tx_pos"] as int; final vout = jsonUTXO["tx_pos"] as int;
final outputs = txn["vout"] as List; final outputs = txn["vout"] as List;

View file

@ -524,6 +524,15 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.0.2" version: "1.0.2"
electrum_adapter:
dependency: "direct main"
description:
path: "."
ref: dd443e293feb3b37eb494ab7c8dadef9205de14c
resolved-ref: dd443e293feb3b37eb494ab7c8dadef9205de14c
url: "https://github.com/cypherstack/electrum_adapter.git"
source: git
version: "3.0.0"
emojis: emojis:
dependency: "direct main" dependency: "direct main"
description: description:
@ -674,10 +683,10 @@ packages:
dependency: "direct dev" dependency: "direct dev"
description: description:
name: flutter_lints name: flutter_lints
sha256: a25a15ebbdfc33ab1cd26c63a6ee519df92338a9c10f122adda92938253bef04 sha256: e2a421b7e59244faef694ba7b30562e489c2b489866e505074eb005cd7060db7
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.0.3" version: "3.0.1"
flutter_local_notifications: flutter_local_notifications:
dependency: "direct main" dependency: "direct main"
description: description:
@ -1038,10 +1047,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: lints name: lints
sha256: "0a217c6c989d21039f1498c3ed9f3ed71b354e69873f13a8dfc3c9fe76f1b452" sha256: cbf8d4b858bb0134ef3ef87841abdf8d63bfc255c266b7bf6b39daa1085c4290
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.1.1" version: "3.0.0"
local_auth: local_auth:
dependency: "direct main" dependency: "direct main"
description: description:

View file

@ -173,6 +173,10 @@ dependencies:
url: https://github.com/cypherstack/coinlib.git url: https://github.com/cypherstack/coinlib.git
path: coinlib_flutter path: coinlib_flutter
ref: 376d520b4516d4eb7c3f0bd4b1522f7769f3f2a7 ref: 376d520b4516d4eb7c3f0bd4b1522f7769f3f2a7
electrum_adapter:
git:
url: https://github.com/cypherstack/electrum_adapter.git
ref: dd443e293feb3b37eb494ab7c8dadef9205de14c
dev_dependencies: dev_dependencies:
flutter_test: flutter_test:
@ -189,7 +193,7 @@ dev_dependencies:
# lint: ^1.10.0 # lint: ^1.10.0
analyzer: ^5.13.0 analyzer: ^5.13.0
import_sorter: ^4.6.0 import_sorter: ^4.6.0
flutter_lints: ^2.0.1 flutter_lints: ^3.0.1
isar_generator: 3.0.5 isar_generator: 3.0.5
flutter_launcher_icons: flutter_launcher_icons: