mirror of
https://github.com/cypherstack/stack_wallet.git
synced 2024-11-17 09:47:37 +00:00
commit
a0ce2cef72
3 changed files with 43 additions and 536 deletions
|
@ -1 +1 @@
|
|||
Subproject commit 9a150d8cd2c3625424b0059e6b7306f3659fdbe0
|
||||
Subproject commit e71995ada3a0675fbce94609e56a7d335f59437c
|
|
@ -86,46 +86,6 @@ Future<void> executeNative(Map<String, dynamic> arguments) async {
|
|||
sendPort.send(result);
|
||||
return;
|
||||
}
|
||||
} else if (function == "getPendingSlates") {
|
||||
final wallet = arguments['wallet'] as String?;
|
||||
final secretKeyIndex = arguments['secretKeyIndex'] as int?;
|
||||
final slates = arguments['slates'] as String;
|
||||
Map<String, dynamic> result = {};
|
||||
|
||||
if (!(wallet == null || secretKeyIndex == null)) {
|
||||
Logging.instance
|
||||
.log("SECRET_KEY_INDEX_IS $secretKeyIndex", level: LogLevel.Info);
|
||||
result['result'] =
|
||||
await getPendingSlates(wallet, secretKeyIndex, slates);
|
||||
sendPort.send(result);
|
||||
return;
|
||||
}
|
||||
} else if (function == "subscribeRequest") {
|
||||
final wallet = arguments['wallet'] as String?;
|
||||
final secretKeyIndex = arguments['secretKeyIndex'] as int?;
|
||||
final epicboxConfig = arguments['epicboxConfig'] as String?;
|
||||
Map<String, dynamic> result = {};
|
||||
|
||||
if (!(wallet == null ||
|
||||
secretKeyIndex == null ||
|
||||
epicboxConfig == null)) {
|
||||
Logging.instance
|
||||
.log("SECRET_KEY_INDEX_IS $secretKeyIndex", level: LogLevel.Info);
|
||||
result['result'] =
|
||||
await getSubscribeRequest(wallet, secretKeyIndex, epicboxConfig);
|
||||
sendPort.send(result);
|
||||
return;
|
||||
}
|
||||
} else if (function == "processSlates") {
|
||||
final wallet = arguments['wallet'] as String?;
|
||||
final slates = arguments['slates'];
|
||||
Map<String, dynamic> result = {};
|
||||
|
||||
if (!(wallet == null || slates == null)) {
|
||||
result['result'] = await processSlates(wallet, slates.toString());
|
||||
sendPort.send(result);
|
||||
return;
|
||||
}
|
||||
} else if (function == "getWalletInfo") {
|
||||
final wallet = arguments['wallet'] as String?;
|
||||
final refreshFromNode = arguments['refreshFromNode'] as int?;
|
||||
|
@ -216,6 +176,17 @@ Future<void> executeNative(Map<String, dynamic> arguments) async {
|
|||
sendPort.send(result);
|
||||
return;
|
||||
}
|
||||
} else if (function == "listenForSlates") {
|
||||
final wallet = arguments['wallet'] as String?;
|
||||
final epicboxConfig = arguments['epicboxConfig'] as String?;
|
||||
|
||||
Map<String, dynamic> result = {};
|
||||
if (!(wallet == null || epicboxConfig == null)) {
|
||||
var res = await epicboxListen(wallet, epicboxConfig);
|
||||
result['result'] = res;
|
||||
sendPort.send(result);
|
||||
return;
|
||||
}
|
||||
}
|
||||
Logging.instance.log(
|
||||
"Error Arguments for $function not formatted correctly",
|
||||
|
@ -320,204 +291,6 @@ Future<int> _getChainHeightWrapper(String config) async {
|
|||
return chainHeight;
|
||||
}
|
||||
|
||||
const String EPICPOST_ADDRESS = 'https://epicpost.stackwallet.com';
|
||||
|
||||
Future<bool> postSlate(String receiveAddress, String slate) async {
|
||||
Logging.instance.log("postSlate", level: LogLevel.Info);
|
||||
final Client client = Client();
|
||||
try {
|
||||
final uri = Uri.parse("$EPICPOST_ADDRESS/postSlate");
|
||||
|
||||
final epicpost = await client.post(
|
||||
uri,
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: jsonEncode({
|
||||
"jsonrpc": "2.0",
|
||||
"id": "0",
|
||||
'receivingAddress': receiveAddress,
|
||||
'slate': slate
|
||||
}),
|
||||
);
|
||||
|
||||
// TODO: should the following be removed for security reasons in production?
|
||||
Logging.instance.log(epicpost.statusCode.toString(), level: LogLevel.Info);
|
||||
Logging.instance.log(epicpost.body.toString(), level: LogLevel.Info);
|
||||
final response = jsonDecode(epicpost.body.toString());
|
||||
if (response['status'] == 'success') {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} catch (e, s) {
|
||||
Logging.instance.log("$e $s", level: LogLevel.Error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Future<dynamic> getSlates(String receiveAddress, String signature) async {
|
||||
Logging.instance.log("getslates", level: LogLevel.Info);
|
||||
final Client client = Client();
|
||||
try {
|
||||
final uri = Uri.parse("$EPICPOST_ADDRESS/getSlates");
|
||||
|
||||
final epicpost = await client.post(
|
||||
uri,
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: jsonEncode({
|
||||
"jsonrpc": "2.0",
|
||||
"id": "0",
|
||||
'receivingAddress': receiveAddress,
|
||||
'signature': signature,
|
||||
}),
|
||||
);
|
||||
|
||||
// TODO: should the following be removed for security reasons in production?
|
||||
Logging.instance.log(epicpost.statusCode.toString(), level: LogLevel.Info);
|
||||
Logging.instance.log(epicpost.body.toString(), level: LogLevel.Info);
|
||||
final response = jsonDecode(epicpost.body.toString());
|
||||
if (response['status'] == 'success') {
|
||||
return response['slates'];
|
||||
} else {
|
||||
return response['error'];
|
||||
}
|
||||
} catch (e, s) {
|
||||
Logging.instance.log("$e $s", level: LogLevel.Error);
|
||||
return 'Error $e $s';
|
||||
}
|
||||
}
|
||||
|
||||
Future<bool> postCancel(String receiveAddress, String slateId,
|
||||
String? signature, String sendersAddress) async {
|
||||
Logging.instance.log("postCancel", level: LogLevel.Info);
|
||||
final Client client = Client();
|
||||
try {
|
||||
final uri = Uri.parse("$EPICPOST_ADDRESS/postCancel");
|
||||
|
||||
final body = jsonEncode({
|
||||
"jsonrpc": "2.0",
|
||||
"id": "0",
|
||||
'receivingAddress': receiveAddress,
|
||||
"signature": signature,
|
||||
'slate': slateId,
|
||||
"sendersAddress": sendersAddress,
|
||||
});
|
||||
final epicPost = await client.post(
|
||||
uri,
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: body,
|
||||
);
|
||||
// TODO: should the following be removed for security reasons in production?
|
||||
Logging.instance.log(epicPost.statusCode.toString(), level: LogLevel.Info);
|
||||
Logging.instance.log(epicPost.body.toString(), level: LogLevel.Info);
|
||||
final response = jsonDecode(epicPost.body.toString());
|
||||
if (response['status'] == 'success') {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} catch (e, s) {
|
||||
Logging.instance.log("$e $s", level: LogLevel.Error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Future<dynamic> getCancels(String receiveAddress, String signature) async {
|
||||
Logging.instance.log("getCancels", level: LogLevel.Info);
|
||||
final Client client = Client();
|
||||
try {
|
||||
final uri = Uri.parse("$EPICPOST_ADDRESS/getCancels");
|
||||
|
||||
final epicpost = await client.post(
|
||||
uri,
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: jsonEncode({
|
||||
"jsonrpc": "2.0",
|
||||
"id": "0",
|
||||
'receivingAddress': receiveAddress,
|
||||
'signature': signature,
|
||||
}),
|
||||
);
|
||||
// TODO: should the following be removed for security reasons in production?
|
||||
Logging.instance.log(epicpost.statusCode.toString(), level: LogLevel.Info);
|
||||
Logging.instance.log(epicpost.body.toString(), level: LogLevel.Info);
|
||||
final response = jsonDecode(epicpost.body.toString());
|
||||
if (response['status'] == 'success') {
|
||||
return response['canceled_slates'];
|
||||
} else {
|
||||
return response['error'];
|
||||
}
|
||||
} catch (e, s) {
|
||||
Logging.instance.log("$e $s", level: LogLevel.Error);
|
||||
return 'Error $e $s';
|
||||
}
|
||||
}
|
||||
|
||||
Future<dynamic> deleteCancels(
|
||||
String receiveAddress, String signature, String slate) async {
|
||||
Logging.instance.log("deleteCancels", level: LogLevel.Info);
|
||||
final Client client = Client();
|
||||
try {
|
||||
final uri = Uri.parse("$EPICPOST_ADDRESS/deleteCancels");
|
||||
|
||||
final epicpost = await client.post(
|
||||
uri,
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: jsonEncode({
|
||||
"jsonrpc": "2.0",
|
||||
"id": "0",
|
||||
'receivingAddress': receiveAddress,
|
||||
'signature': signature,
|
||||
'slate': slate,
|
||||
}),
|
||||
);
|
||||
// TODO: should the following be removed for security reasons in production?
|
||||
Logging.instance.log(epicpost.statusCode.toString(), level: LogLevel.Info);
|
||||
Logging.instance.log(epicpost.body.toString(), level: LogLevel.Info);
|
||||
final response = jsonDecode(epicpost.body.toString());
|
||||
if (response['status'] == 'success') {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} catch (e, s) {
|
||||
Logging.instance.log("$e $s", level: LogLevel.Error);
|
||||
return 'Error $e $s';
|
||||
}
|
||||
}
|
||||
|
||||
Future<dynamic> deleteSlate(
|
||||
String receiveAddress, String signature, String slate) async {
|
||||
Logging.instance.log("deleteSlate", level: LogLevel.Info);
|
||||
final Client client = Client();
|
||||
try {
|
||||
final uri = Uri.parse("$EPICPOST_ADDRESS/deleteSlate");
|
||||
|
||||
final epicpost = await client.post(
|
||||
uri,
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: jsonEncode({
|
||||
"jsonrpc": "2.0",
|
||||
"id": "0",
|
||||
'receivingAddress': receiveAddress,
|
||||
'signature': signature,
|
||||
'slate': slate,
|
||||
}),
|
||||
);
|
||||
// TODO: should the following be removed for security reasons in production?
|
||||
Logging.instance.log(epicpost.statusCode.toString(), level: LogLevel.Info);
|
||||
Logging.instance.log(epicpost.body.toString(), level: LogLevel.Info);
|
||||
final response = jsonDecode(epicpost.body.toString());
|
||||
if (response['status'] == 'success') {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} catch (e, s) {
|
||||
Logging.instance.log("$e $s", level: LogLevel.Info);
|
||||
return 'Error $e $s';
|
||||
}
|
||||
}
|
||||
|
||||
class EpicCashWallet extends CoinServiceAPI
|
||||
with WalletCache, WalletDB, EpicCashHive {
|
||||
EpicCashWallet({
|
||||
|
@ -650,53 +423,10 @@ class EpicCashWallet extends CoinServiceAPI
|
|||
late SecureStorageInterface _secureStore;
|
||||
|
||||
Future<String> cancelPendingTransactionAndPost(String txSlateId) async {
|
||||
final wallet = await _secureStore.read(key: '${_walletId}_wallet');
|
||||
final int? receivingIndex = epicGetReceivingIndex();
|
||||
final epicboxConfig =
|
||||
await _secureStore.read(key: '${_walletId}_epicboxConfig');
|
||||
|
||||
final slatesToCommits = await getSlatesToCommits();
|
||||
final receiveAddress = slatesToCommits[txSlateId]['to'] as String;
|
||||
final sendersAddress = slatesToCommits[txSlateId]['from'] as String;
|
||||
|
||||
int? currentReceivingIndex;
|
||||
for (int i = 0; i <= receivingIndex!; i++) {
|
||||
final indexesAddress = await _getReceivingAddressForIndex(i);
|
||||
if (indexesAddress.value == sendersAddress) {
|
||||
currentReceivingIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
dynamic subscribeRequest;
|
||||
await m.protect(() async {
|
||||
ReceivePort receivePort = await getIsolate({
|
||||
"function": "subscribeRequest",
|
||||
"wallet": wallet,
|
||||
"secretKeyIndex": currentReceivingIndex!,
|
||||
"epicboxConfig": epicboxConfig,
|
||||
}, name: walletName);
|
||||
|
||||
var result = await receivePort.first;
|
||||
if (result is String) {
|
||||
Logging.instance.log("this is a message $result", level: LogLevel.Info);
|
||||
stop(receivePort);
|
||||
throw Exception("subscribeRequest isolate failed");
|
||||
}
|
||||
subscribeRequest = jsonDecode(result['result'] as String);
|
||||
stop(receivePort);
|
||||
Logging.instance.log('Closing subscribeRequest! $subscribeRequest',
|
||||
level: LogLevel.Info);
|
||||
});
|
||||
// TODO, once server adds signature, give this signature to the getSlates method.
|
||||
String? signature = subscribeRequest['signature'] as String?;
|
||||
String? result;
|
||||
try {
|
||||
result = await cancelPendingTransaction(txSlateId);
|
||||
Logging.instance.log("result?: $result", level: LogLevel.Info);
|
||||
if (!(result.toLowerCase().contains("error"))) {
|
||||
await postCancel(receiveAddress, txSlateId, signature, sendersAddress);
|
||||
}
|
||||
} catch (e, s) {
|
||||
Logging.instance.log("$e, $s", level: LogLevel.Error);
|
||||
}
|
||||
|
@ -797,16 +527,6 @@ class EpicCashWallet extends CoinServiceAPI
|
|||
String errorMessage = decodeData[1] as String;
|
||||
throw Exception("Transaction failed with error code $errorMessage");
|
||||
} else {
|
||||
//If it's HTTP send no need to post to epicbox
|
||||
if (!(receiverAddress.startsWith("http://") ||
|
||||
receiverAddress.startsWith("https://"))) {
|
||||
final postSlateRequest = decodeData[1];
|
||||
final postToServer = await postSlate(
|
||||
txData['addresss'] as String, postSlateRequest as String);
|
||||
Logging.instance
|
||||
.log("POST_SLATE_IS $postToServer", level: LogLevel.Info);
|
||||
}
|
||||
|
||||
final txCreateResult = decodeData[0];
|
||||
// //TODO: second problem
|
||||
final transaction = json.decode(txCreateResult as String);
|
||||
|
@ -999,6 +719,8 @@ class EpicCashWallet extends CoinServiceAPI
|
|||
await _prefs.init();
|
||||
await updateNode(false);
|
||||
await _refreshBalance();
|
||||
//Open Epicbox listener in the background
|
||||
await listenForSlates();
|
||||
// TODO: is there anything else that should be set up here whenever this wallet is first loaded again?
|
||||
}
|
||||
|
||||
|
@ -1093,6 +815,9 @@ class EpicCashWallet extends CoinServiceAPI
|
|||
epicUpdateChangeIndex(0),
|
||||
]);
|
||||
|
||||
//Open Epicbox listener in the background
|
||||
await listenForSlates();
|
||||
|
||||
final initialReceivingAddress = await _getReceivingAddressForIndex(0);
|
||||
|
||||
await db.putAddress(initialReceivingAddress);
|
||||
|
@ -1289,8 +1014,10 @@ class EpicCashWallet extends CoinServiceAPI
|
|||
|
||||
Future<void> updateEpicboxConfig(String host, int port) async {
|
||||
String stringConfig = jsonEncode({
|
||||
"domain": host,
|
||||
"port": port,
|
||||
"epicbox_domain": host,
|
||||
"epicbox_port": port,
|
||||
"epicbox_protocol_unsecure": false,
|
||||
"epicbox_address_index": 0,
|
||||
});
|
||||
await _secureStore.write(
|
||||
key: '${_walletId}_epicboxConfig', value: stringConfig);
|
||||
|
@ -1413,6 +1140,9 @@ class EpicCashWallet extends CoinServiceAPI
|
|||
|
||||
//Store Epic box address info
|
||||
await storeEpicboxInfo();
|
||||
|
||||
//Open Epicbox listener in the background
|
||||
await listenForSlates();
|
||||
} catch (e, s) {
|
||||
Logging.instance
|
||||
.log("Error recovering wallet $e\n$s", level: LogLevel.Error);
|
||||
|
@ -1583,249 +1313,28 @@ class EpicCashWallet extends CoinServiceAPI
|
|||
}
|
||||
}
|
||||
|
||||
Future<bool> processAllSlates() async {
|
||||
final int? receivingIndex = epicGetReceivingIndex();
|
||||
for (int currentReceivingIndex = 0;
|
||||
receivingIndex != null && currentReceivingIndex <= receivingIndex;
|
||||
currentReceivingIndex++) {
|
||||
final currentAddress =
|
||||
await _getReceivingAddressForIndex(currentReceivingIndex);
|
||||
final wallet = await _secureStore.read(key: '${_walletId}_wallet');
|
||||
final epicboxConfig =
|
||||
await _secureStore.read(key: '${_walletId}_epicboxConfig');
|
||||
dynamic subscribeRequest;
|
||||
await m.protect(() async {
|
||||
ReceivePort receivePort = await getIsolate({
|
||||
"function": "subscribeRequest",
|
||||
"wallet": wallet,
|
||||
"secretKeyIndex": currentReceivingIndex,
|
||||
"epicboxConfig": epicboxConfig,
|
||||
}, name: walletName);
|
||||
|
||||
var result = await receivePort.first;
|
||||
if (result is String) {
|
||||
Logging.instance
|
||||
.log("this is a message $result", level: LogLevel.Error);
|
||||
stop(receivePort);
|
||||
throw Exception("subscribeRequest isolate failed");
|
||||
}
|
||||
subscribeRequest = jsonDecode(result['result'] as String);
|
||||
stop(receivePort);
|
||||
Logging.instance.log('Closing subscribeRequest! $subscribeRequest',
|
||||
level: LogLevel.Info);
|
||||
});
|
||||
// TODO, once server adds signature, give this signature to the getSlates method.
|
||||
Logging.instance
|
||||
.log(subscribeRequest['signature'], level: LogLevel.Info); //
|
||||
final unprocessedSlates = await getSlates(
|
||||
currentAddress.value, subscribeRequest['signature'] as String);
|
||||
if (unprocessedSlates == null || unprocessedSlates is! List) {
|
||||
Logging.instance.log(
|
||||
"index $currentReceivingIndex at ${await currentReceivingAddress} does not have any slates",
|
||||
level: LogLevel.Info);
|
||||
continue;
|
||||
}
|
||||
for (var slate in unprocessedSlates) {
|
||||
final encoded = jsonEncode([slate]);
|
||||
Logging.instance
|
||||
.log("Received Slates is $encoded", level: LogLevel.Info);
|
||||
|
||||
//Decrypt Slates
|
||||
dynamic slates;
|
||||
dynamic response;
|
||||
await m.protect(() async {
|
||||
ReceivePort receivePort = await getIsolate({
|
||||
"function": "getPendingSlates",
|
||||
"wallet": wallet!,
|
||||
"secretKeyIndex": currentReceivingIndex,
|
||||
"slates": encoded,
|
||||
}, name: walletName);
|
||||
|
||||
var result = await receivePort.first;
|
||||
if (result is String) {
|
||||
Logging.instance
|
||||
.log("this is a message $slates", level: LogLevel.Info);
|
||||
stop(receivePort);
|
||||
throw Exception("getPendingSlates isolate failed");
|
||||
}
|
||||
slates = result['result'];
|
||||
stop(receivePort);
|
||||
});
|
||||
|
||||
var decoded = jsonDecode(slates as String);
|
||||
|
||||
for (var decodedSlate in decoded as List) {
|
||||
//Process slates
|
||||
var decodedResponse = json.decode(decodedSlate as String);
|
||||
String slateMessage = decodedResponse[0] as String;
|
||||
await putSlatesToCommits(slateMessage, encoded);
|
||||
String slateSender = decodedResponse[1] as String;
|
||||
Logging.instance.log("SLATE_MESSAGE $slateMessage",
|
||||
printFullLength: true, level: LogLevel.Info);
|
||||
Logging.instance
|
||||
.log("SLATE_SENDER $slateSender", level: LogLevel.Info);
|
||||
await m.protect(() async {
|
||||
ReceivePort receivePort = await getIsolate({
|
||||
"function": "processSlates",
|
||||
"wallet": wallet!,
|
||||
"slates": slateMessage
|
||||
}, name: walletName);
|
||||
|
||||
var message = await receivePort.first;
|
||||
if (message is String) {
|
||||
Logging.instance.log("this is PROCESS_SLATES message $message",
|
||||
level: LogLevel.Error);
|
||||
stop(receivePort);
|
||||
throw Exception("processSlates isolate failed");
|
||||
}
|
||||
|
||||
try {
|
||||
final String response = message['result'] as String;
|
||||
if (response == "") {
|
||||
Logging.instance.log("response: ${response.runtimeType}",
|
||||
level: LogLevel.Info);
|
||||
await deleteSlate(currentAddress.value,
|
||||
subscribeRequest['signature'] as String, slate as String);
|
||||
}
|
||||
|
||||
if (response
|
||||
.contains("Error Wallet store error: DB Not Found Error")) {
|
||||
//Already processed - to be deleted
|
||||
Logging.instance
|
||||
.log("DELETING_PROCESSED_SLATE", level: LogLevel.Info);
|
||||
final slateDelete = await deleteSlate(currentAddress.value,
|
||||
subscribeRequest['signature'] as String, slate as String);
|
||||
Logging.instance.log("DELETE_SLATE_RESPONSE $slateDelete",
|
||||
level: LogLevel.Info);
|
||||
} else {
|
||||
var decodedResponse = json.decode(response);
|
||||
final processStatus = json.decode(decodedResponse[0] as String);
|
||||
String slateStatus = processStatus['status'] as String;
|
||||
if (slateStatus == "PendingProcessing") {
|
||||
//Encrypt slate
|
||||
String encryptedSlate = await getEncryptedSlate(
|
||||
wallet,
|
||||
slateSender,
|
||||
currentReceivingIndex,
|
||||
epicboxConfig!,
|
||||
decodedResponse[1] as String);
|
||||
|
||||
final postSlateToServer =
|
||||
await postSlate(slateSender, encryptedSlate);
|
||||
|
||||
await deleteSlate(currentAddress.value,
|
||||
subscribeRequest['signature'] as String, slate as String);
|
||||
Logging.instance.log("POST_SLATE_RESPONSE $postSlateToServer",
|
||||
level: LogLevel.Info);
|
||||
} else {
|
||||
//Finalise Slate
|
||||
final processSlate =
|
||||
json.decode(decodedResponse[1] as String);
|
||||
Logging.instance.log(
|
||||
"PROCESSED_SLATE_TO_FINALIZE $processSlate",
|
||||
level: LogLevel.Info);
|
||||
final tx = json.decode(processSlate[0] as String);
|
||||
Logging.instance.log("TX_IS $tx", level: LogLevel.Info);
|
||||
String txSlateId = tx[0]['tx_slate_id'] as String;
|
||||
Logging.instance
|
||||
.log("TX_SLATE_ID_IS $txSlateId", level: LogLevel.Info);
|
||||
final postToNode = await postSlateToNode(wallet, txSlateId);
|
||||
await deleteSlate(currentAddress.value,
|
||||
subscribeRequest['signature'] as String, slate as String);
|
||||
Logging.instance.log("POST_SLATE_RESPONSE $postToNode",
|
||||
level: LogLevel.Info);
|
||||
//Post Slate to Node
|
||||
Logging.instance.log("Finalise slate", level: LogLevel.Info);
|
||||
}
|
||||
}
|
||||
} catch (e, s) {
|
||||
Logging.instance.log("$e\n$s", level: LogLevel.Info);
|
||||
return false;
|
||||
}
|
||||
stop(receivePort);
|
||||
Logging.instance
|
||||
.log('Closing processSlates! $response', level: LogLevel.Info);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
Future<bool> processAllCancels() async {
|
||||
Logging.instance.log("processAllCancels", level: LogLevel.Info);
|
||||
Future<void> listenForSlates() async {
|
||||
final wallet = await _secureStore.read(key: '${_walletId}_wallet');
|
||||
final epicboxConfig =
|
||||
await _secureStore.read(key: '${_walletId}_epicboxConfig');
|
||||
final int? receivingIndex = epicGetReceivingIndex();
|
||||
|
||||
for (int currentReceivingIndex = 0;
|
||||
receivingIndex != null && currentReceivingIndex <= receivingIndex;
|
||||
currentReceivingIndex++) {
|
||||
final receiveAddress =
|
||||
await _getReceivingAddressForIndex(currentReceivingIndex);
|
||||
await m.protect(() async {
|
||||
Logging.instance.log("CALLING LISTEN FOR SLATES", level: LogLevel.Info);
|
||||
ReceivePort receivePort = await getIsolate({
|
||||
"function": "listenForSlates",
|
||||
"wallet": wallet,
|
||||
"epicboxConfig": epicboxConfig,
|
||||
}, name: walletName);
|
||||
|
||||
dynamic subscribeRequest;
|
||||
await m.protect(() async {
|
||||
ReceivePort receivePort = await getIsolate({
|
||||
"function": "subscribeRequest",
|
||||
"wallet": wallet!,
|
||||
"secretKeyIndex": currentReceivingIndex,
|
||||
"epicboxConfig": epicboxConfig,
|
||||
}, name: walletName);
|
||||
|
||||
var result = await receivePort.first;
|
||||
if (result is String) {
|
||||
Logging.instance
|
||||
.log("this is a message $result", level: LogLevel.Info);
|
||||
stop(receivePort);
|
||||
throw Exception("subscribeRequest isolate failed");
|
||||
}
|
||||
subscribeRequest = jsonDecode(result['result'] as String);
|
||||
var result = await receivePort.first;
|
||||
if (result is String) {
|
||||
Logging.instance
|
||||
.log("this is a message $result", level: LogLevel.Error);
|
||||
stop(receivePort);
|
||||
Logging.instance.log('Closing subscribeRequest! $subscribeRequest',
|
||||
level: LogLevel.Info);
|
||||
});
|
||||
String? signature = subscribeRequest['signature'] as String?;
|
||||
final cancels = await getCancels(receiveAddress.value, signature!);
|
||||
|
||||
final slatesToCommits = await getSlatesToCommits();
|
||||
for (final cancel in cancels as List<dynamic>) {
|
||||
final txSlateId = cancel.keys.first as String;
|
||||
if (slatesToCommits[txSlateId] == null) {
|
||||
continue;
|
||||
}
|
||||
final cancelRequestSender = ((cancel as Map).values.first) as String;
|
||||
final receiveAddressFromMap =
|
||||
slatesToCommits[txSlateId]['to'] as String;
|
||||
final sendersAddressFromMap =
|
||||
slatesToCommits[txSlateId]['from'] as String;
|
||||
final commitId = slatesToCommits[txSlateId]['commitId'] as String;
|
||||
|
||||
if (sendersAddressFromMap != cancelRequestSender) {
|
||||
Logging.instance.log("this was not signed by the correct address",
|
||||
level: LogLevel.Error);
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
await cancelPendingTransaction(txSlateId);
|
||||
final tx = await db
|
||||
.getTransactions(walletId)
|
||||
.filter()
|
||||
.txidEqualTo(commitId)
|
||||
.findFirst();
|
||||
if ((tx?.isCancelled ?? false) == true) {
|
||||
await deleteCancels(receiveAddressFromMap, signature, txSlateId);
|
||||
}
|
||||
} catch (e, s) {
|
||||
Logging.instance.log("$e, $s", level: LogLevel.Error);
|
||||
return false;
|
||||
}
|
||||
throw Exception("subscribeRequest isolate failed");
|
||||
}
|
||||
continue;
|
||||
}
|
||||
return true;
|
||||
stop(receivePort);
|
||||
});
|
||||
}
|
||||
|
||||
/// Refreshes display data for the wallet
|
||||
|
@ -1876,9 +1385,6 @@ class EpicCashWallet extends CoinServiceAPI
|
|||
return;
|
||||
}
|
||||
|
||||
await processAllSlates();
|
||||
await processAllCancels();
|
||||
|
||||
unawaited(startSync());
|
||||
|
||||
GlobalEventBus.instance.fire(RefreshPercentChangedEvent(0.0, walletId));
|
||||
|
@ -1915,7 +1421,6 @@ class EpicCashWallet extends CoinServiceAPI
|
|||
),
|
||||
);
|
||||
refreshMutex = false;
|
||||
|
||||
if (shouldAutoSync) {
|
||||
timer ??= Timer.periodic(const Duration(seconds: 60), (timer) async {
|
||||
Logging.instance.log(
|
||||
|
|
|
@ -257,7 +257,9 @@ abstract class DefaultNodes {
|
|||
}
|
||||
|
||||
static final String defaultEpicBoxConfig = jsonEncode({
|
||||
"domain": "209.127.179.199",
|
||||
"port": 13420,
|
||||
"epicbox_domain": "epicbox.epic.tech",
|
||||
"epicbox_port": 443,
|
||||
"epicbox_protocol_unsecure": false,
|
||||
"epicbox_address_index": 0,
|
||||
});
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue