mirror of
https://github.com/cypherstack/stack_wallet.git
synced 2024-11-17 01:37:54 +00:00
Merge pull request #803 from cypherstack/staging
Update main to v1.10.2
This commit is contained in:
commit
368c4055ee
12 changed files with 131 additions and 92 deletions
|
@ -1 +1 @@
|
|||
Subproject commit 9eb24dd00cd0e1df08624ece1ca47090c158c08c
|
||||
Subproject commit cef5d3aa8c74c8dc9a466f803c964b243ad653a3
|
|
@ -1020,6 +1020,18 @@ class ElectrumXClient {
|
|||
],
|
||||
);
|
||||
try {
|
||||
// If the response is -1 or null, return a temporary hardcoded value for
|
||||
// Dogecoin. This is a temporary fix until the fee estimation is fixed.
|
||||
if (coin == Coin.dogecoin &&
|
||||
(response == null ||
|
||||
response == -1 ||
|
||||
Decimal.parse(response.toString()) == Decimal.parse("-1"))) {
|
||||
// Return 0.05 for slow, 0.2 for average, and 1 for fast txs.
|
||||
// These numbers produce tx fees in line with txs in the wild on
|
||||
// https://dogechain.info/
|
||||
return Decimal.parse((1 / blocks).toString());
|
||||
// TODO [prio=med]: Fix fee estimation.
|
||||
}
|
||||
return Decimal.parse(response.toString());
|
||||
} catch (e, s) {
|
||||
final String msg = "Error parsing fee rate. Response: $response"
|
||||
|
|
|
@ -724,15 +724,10 @@ class _RestoreWalletViewState extends ConsumerState<RestoreWalletView> {
|
|||
],
|
||||
),
|
||||
body: Container(
|
||||
color: Theme.of(context).extension<StackColors>()!.background,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(12.0),
|
||||
child: ConditionalParent(
|
||||
condition: isDesktop,
|
||||
builder: (child) => Expanded(
|
||||
child: child,
|
||||
),
|
||||
child: SingleChildScrollView(
|
||||
color: Theme.of(context).extension<StackColors>()!.background,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(12.0),
|
||||
child: SingleChildScrollView(
|
||||
controller: controller,
|
||||
child: Column(
|
||||
children: [
|
||||
|
@ -1203,7 +1198,6 @@ class _RestoreWalletViewState extends ConsumerState<RestoreWalletView> {
|
|||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1048,7 +1048,7 @@ class _TransactionV2DetailsViewState
|
|||
pTransactionNote(
|
||||
(
|
||||
txid: (coin == Coin.epicCash) ?
|
||||
_transaction.slateId as String
|
||||
_transaction.slateId.toString()
|
||||
: _transaction.txid,
|
||||
walletId: walletId
|
||||
),
|
||||
|
|
|
@ -612,7 +612,7 @@ abstract class EthereumAPI {
|
|||
final response = await client.get(
|
||||
url: Uri.parse(
|
||||
// "$stackBaseServer/tokens?addrs=$contractAddress&parts=all",
|
||||
"$stackBaseServer/names?terms=$contractAddress",
|
||||
"$stackBaseServer/names?terms=$contractAddress&all",
|
||||
),
|
||||
proxyInfo: Prefs.instance.useTor
|
||||
? TorService.sharedInstance.getProxyInfo()
|
||||
|
|
|
@ -17,7 +17,7 @@ abstract class DefaultEpicBoxes {
|
|||
static List<String> get defaultIds => ['americas', 'asia', 'europe'];
|
||||
|
||||
static EpicBoxServerModel get americas => EpicBoxServerModel(
|
||||
host: 'stackwallet.epicbox.com',
|
||||
host: 'epicbox.stackwallet.com',
|
||||
port: 443,
|
||||
name: 'Americas',
|
||||
id: 'americas',
|
||||
|
|
|
@ -5,6 +5,7 @@ import 'package:stackwallet/models/isar/models/isar_models.dart';
|
|||
import 'package:stackwallet/models/paynym/paynym_account_lite.dart';
|
||||
import 'package:stackwallet/utilities/amount/amount.dart';
|
||||
import 'package:stackwallet/utilities/enums/fee_rate_type_enum.dart';
|
||||
import 'package:stackwallet/wallets/isar/models/spark_coin.dart';
|
||||
import 'package:tezart/tezart.dart' as tezart;
|
||||
import 'package:web3dart/web3dart.dart' as web3dart;
|
||||
|
||||
|
@ -69,6 +70,7 @@ class TxData {
|
|||
bool isChange,
|
||||
})>? sparkRecipients;
|
||||
final List<TxData>? sparkMints;
|
||||
final List<SparkCoin>? usedSparkCoins;
|
||||
|
||||
final TransactionV2? tempTx;
|
||||
|
||||
|
@ -105,6 +107,7 @@ class TxData {
|
|||
this.tezosOperationsList,
|
||||
this.sparkRecipients,
|
||||
this.sparkMints,
|
||||
this.usedSparkCoins,
|
||||
this.tempTx,
|
||||
});
|
||||
|
||||
|
@ -187,6 +190,7 @@ class TxData {
|
|||
})>?
|
||||
sparkRecipients,
|
||||
List<TxData>? sparkMints,
|
||||
List<SparkCoin>? usedSparkCoins,
|
||||
TransactionV2? tempTx,
|
||||
}) {
|
||||
return TxData(
|
||||
|
@ -224,6 +228,7 @@ class TxData {
|
|||
tezosOperationsList: tezosOperationsList ?? this.tezosOperationsList,
|
||||
sparkRecipients: sparkRecipients ?? this.sparkRecipients,
|
||||
sparkMints: sparkMints ?? this.sparkMints,
|
||||
usedSparkCoins: usedSparkCoins ?? this.usedSparkCoins,
|
||||
tempTx: tempTx ?? this.tempTx,
|
||||
);
|
||||
}
|
||||
|
@ -262,6 +267,7 @@ class TxData {
|
|||
'tezosOperationsList: $tezosOperationsList, '
|
||||
'sparkRecipients: $sparkRecipients, '
|
||||
'sparkMints: $sparkMints, '
|
||||
'usedSparkCoins: $usedSparkCoins, '
|
||||
'tempTx: $tempTx, '
|
||||
'}';
|
||||
}
|
||||
|
|
|
@ -103,46 +103,30 @@ class EpiccashWallet extends Bip39Wallet {
|
|||
}
|
||||
|
||||
Future<EpicBoxConfigModel> getEpicBoxConfig() async {
|
||||
EpicBoxConfigModel? _epicBoxConfig;
|
||||
// read epicbox config from secure store
|
||||
String? storedConfig =
|
||||
await secureStorageInterface.read(key: '${walletId}_epicboxConfig');
|
||||
EpicBoxConfigModel? _epicBoxConfig =
|
||||
EpicBoxConfigModel.fromServer(DefaultEpicBoxes.defaultEpicBoxServer);
|
||||
|
||||
// we should move to storing the primary server model like we do with nodes, and build the config from that (see epic-mobile)
|
||||
// EpicBoxServerModel? _epicBox = epicBox ??
|
||||
// DB.instance.get<EpicBoxServerModel>(
|
||||
// boxName: DB.boxNamePrimaryEpicBox, key: 'primary');
|
||||
// Logging.instance.log(
|
||||
// "Read primary Epic Box config: ${jsonEncode(_epicBox)}",
|
||||
// level: LogLevel.Info);
|
||||
//Get the default Epicbox server and check if it's conected
|
||||
// bool isEpicboxConnected = await _testEpicboxServer(
|
||||
// DefaultEpicBoxes.defaultEpicBoxServer.host, DefaultEpicBoxes.defaultEpicBoxServer.port ?? 443);
|
||||
|
||||
if (storedConfig == null) {
|
||||
// if no config stored, use the default epicbox server as config
|
||||
_epicBoxConfig =
|
||||
EpicBoxConfigModel.fromServer(DefaultEpicBoxes.defaultEpicBoxServer);
|
||||
} else {
|
||||
// if a config is stored, test it
|
||||
// if (isEpicboxConnected) {
|
||||
//Use default server for as Epicbox config
|
||||
|
||||
_epicBoxConfig = EpicBoxConfigModel.fromString(
|
||||
storedConfig); // fromString handles checking old config formats
|
||||
}
|
||||
|
||||
bool isEpicboxConnected = await _testEpicboxServer(
|
||||
_epicBoxConfig.host, _epicBoxConfig.port ?? 443);
|
||||
|
||||
if (!isEpicboxConnected) {
|
||||
// default Epicbox is not connected, default to Europe
|
||||
_epicBoxConfig = EpicBoxConfigModel.fromServer(DefaultEpicBoxes.europe);
|
||||
|
||||
// example of selecting another random server from the default list
|
||||
// alternative servers: copy list of all default EB servers but remove the default default
|
||||
// List<EpicBoxServerModel> alternativeServers = DefaultEpicBoxes.all;
|
||||
// alternativeServers.removeWhere((opt) => opt.name == DefaultEpicBoxes.defaultEpicBoxServer.name);
|
||||
// alternativeServers.shuffle(); // randomize which server is used
|
||||
// _epicBoxConfig = EpicBoxConfigModel.fromServer(alternativeServers.first);
|
||||
|
||||
// TODO test this connection before returning it
|
||||
}
|
||||
// }
|
||||
// else {
|
||||
// //Use Europe config
|
||||
// _epicBoxConfig = EpicBoxConfigModel.fromServer(DefaultEpicBoxes.europe);
|
||||
// }
|
||||
// // example of selecting another random server from the default list
|
||||
// // alternative servers: copy list of all default EB servers but remove the default default
|
||||
// // List<EpicBoxServerModel> alternativeServers = DefaultEpicBoxes.all;
|
||||
// // alternativeServers.removeWhere((opt) => opt.name == DefaultEpicBoxes.defaultEpicBoxServer.name);
|
||||
// // alternativeServers.shuffle(); // randomize which server is used
|
||||
// // _epicBoxConfig = EpicBoxConfigModel.fromServer(alternativeServers.first);
|
||||
//
|
||||
// // TODO test this connection before returning it
|
||||
// }
|
||||
|
||||
return _epicBoxConfig;
|
||||
}
|
||||
|
@ -334,36 +318,50 @@ class EpiccashWallet extends Bip39Wallet {
|
|||
int index,
|
||||
) async {
|
||||
Address? address = await getCurrentReceivingAddress();
|
||||
EpicBoxConfigModel epicboxConfig = await getEpicBoxConfig();
|
||||
|
||||
if (address == null) {
|
||||
final wallet =
|
||||
await secureStorageInterface.read(key: '${walletId}_wallet');
|
||||
EpicBoxConfigModel epicboxConfig = await getEpicBoxConfig();
|
||||
|
||||
final walletAddress = await epiccash.LibEpiccash.getAddressInfo(
|
||||
wallet: wallet!,
|
||||
index: index,
|
||||
epicboxConfig: epicboxConfig.toString(),
|
||||
);
|
||||
|
||||
Logging.instance.log(
|
||||
"WALLET_ADDRESS_IS $walletAddress",
|
||||
level: LogLevel.Info,
|
||||
);
|
||||
|
||||
address = Address(
|
||||
walletId: walletId,
|
||||
value: walletAddress,
|
||||
derivationIndex: index,
|
||||
derivationPath: null,
|
||||
type: AddressType.mimbleWimble,
|
||||
subType: AddressSubType.receiving,
|
||||
publicKey: [], // ??
|
||||
);
|
||||
|
||||
await mainDB.updateOrPutAddresses([address]);
|
||||
if (address != null) {
|
||||
final splitted = address.value.split('@');
|
||||
//Check if the address is the same as the current epicbox domain
|
||||
//Since we're only using one epicbpox now this doesn't apply but will be
|
||||
// useful in the future
|
||||
if (splitted[1] != epicboxConfig.host) {
|
||||
//Update the address
|
||||
address = await thisWalletAddress(index, epicboxConfig);
|
||||
}
|
||||
} else {
|
||||
address = await thisWalletAddress(index, epicboxConfig);
|
||||
}
|
||||
return address;
|
||||
}
|
||||
|
||||
Future<Address> thisWalletAddress(int index, EpicBoxConfigModel epicboxConfig) async {
|
||||
final wallet =
|
||||
await secureStorageInterface.read(key: '${walletId}_wallet');
|
||||
// EpicBoxConfigModel epicboxConfig = await getEpicBoxConfig();
|
||||
|
||||
final walletAddress = await epiccash.LibEpiccash.getAddressInfo(
|
||||
wallet: wallet!,
|
||||
index: index,
|
||||
epicboxConfig: epicboxConfig.toString(),
|
||||
);
|
||||
|
||||
Logging.instance.log(
|
||||
"WALLET_ADDRESS_IS $walletAddress",
|
||||
level: LogLevel.Info,
|
||||
);
|
||||
|
||||
final address = Address(
|
||||
walletId: walletId,
|
||||
value: walletAddress,
|
||||
derivationIndex: index,
|
||||
derivationPath: null,
|
||||
type: AddressType.mimbleWimble,
|
||||
subType: AddressSubType.receiving,
|
||||
publicKey: [], // ??
|
||||
);
|
||||
|
||||
await mainDB.updateOrPutAddresses([address]);
|
||||
return address;
|
||||
}
|
||||
|
||||
|
@ -936,6 +934,7 @@ class EpiccashWallet extends Bip39Wallet {
|
|||
.findAll();
|
||||
final myAddressesSet = myAddresses.toSet();
|
||||
|
||||
|
||||
final transactions = await epiccash.LibEpiccash.getTransactions(
|
||||
wallet: wallet!,
|
||||
refreshFromNode: refreshFromNode,
|
||||
|
|
|
@ -499,6 +499,27 @@ mixin SparkInterface on Bip39HDWallet, ElectrumXInterface {
|
|||
),
|
||||
);
|
||||
|
||||
final List<SparkCoin> usedSparkCoins = [];
|
||||
|
||||
for (final usedCoin in spend.usedCoins) {
|
||||
try {
|
||||
usedSparkCoins.add(coins
|
||||
.firstWhere((e) =>
|
||||
usedCoin.height == e.height &&
|
||||
usedCoin.groupId == e.groupId &&
|
||||
base64Decode(e.serializedCoinB64!)
|
||||
.toHex
|
||||
.startsWith(base64Decode(usedCoin.serializedCoin).toHex))
|
||||
.copyWith(
|
||||
isUsed: true,
|
||||
));
|
||||
} catch (_) {
|
||||
throw Exception(
|
||||
"Unexpectedly did not find used spark coin. This should never happen.",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return txData.copyWith(
|
||||
raw: rawTxHex,
|
||||
vSize: extractedTx.virtualSize(),
|
||||
|
@ -523,7 +544,7 @@ mixin SparkInterface on Bip39HDWallet, ElectrumXInterface {
|
|||
height: null,
|
||||
version: 3,
|
||||
),
|
||||
// TODO used coins
|
||||
usedSparkCoins: usedSparkCoins,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -540,17 +561,17 @@ mixin SparkInterface on Bip39HDWallet, ElectrumXInterface {
|
|||
Logging.instance.log("Sent txHash: $txHash", level: LogLevel.Info);
|
||||
|
||||
txData = txData.copyWith(
|
||||
// TODO mark spark coins as spent locally and update balance before waiting to check via electrumx?
|
||||
|
||||
// usedUTXOs:
|
||||
// txData.usedUTXOs!.map((e) => e.copyWith(used: true)).toList(),
|
||||
|
||||
// TODO revisit setting these both
|
||||
txHash: txHash,
|
||||
txid: txHash,
|
||||
);
|
||||
// // mark utxos as used
|
||||
// await mainDB.putUTXOs(txData.usedUTXOs!);
|
||||
|
||||
// Update used spark coins as used in database. They should already have
|
||||
// been marked as isUsed.
|
||||
// TODO: [prio=med] Could (probably should) throw an exception here if txData.usedSparkCoins is null or empty
|
||||
if (txData.usedSparkCoins != null && txData.usedSparkCoins!.isNotEmpty) {
|
||||
await _addOrUpdateSparkCoins(txData.usedSparkCoins!);
|
||||
}
|
||||
|
||||
return await updateSentCachedTxData(txData: txData);
|
||||
} catch (e, s) {
|
||||
|
@ -1499,6 +1520,13 @@ Future<
|
|||
Uint8List serializedSpendPayload,
|
||||
List<Uint8List> outputScripts,
|
||||
int fee,
|
||||
List<
|
||||
({
|
||||
int groupId,
|
||||
int height,
|
||||
String serializedCoin,
|
||||
String serializedCoinContext
|
||||
})> usedCoins,
|
||||
})> _createSparkSend(
|
||||
({
|
||||
String privateKeyHex,
|
||||
|
|
|
@ -674,8 +674,8 @@ packages:
|
|||
dependency: "direct main"
|
||||
description:
|
||||
path: "."
|
||||
ref: fb50031056fbea0326f7dd76ad59d165c1e5eee5
|
||||
resolved-ref: fb50031056fbea0326f7dd76ad59d165c1e5eee5
|
||||
ref: "3f986ca1a94bdac5d31373454c989cc2f5842de8"
|
||||
resolved-ref: "3f986ca1a94bdac5d31373454c989cc2f5842de8"
|
||||
url: "https://github.com/cypherstack/flutter_libsparkmobile.git"
|
||||
source: git
|
||||
version: "0.0.1"
|
||||
|
|
|
@ -11,7 +11,7 @@ description: Stack Wallet
|
|||
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
|
||||
# Read more about iOS versioning at
|
||||
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
||||
version: 1.10.1+212
|
||||
version: 1.10.2+214
|
||||
|
||||
environment:
|
||||
sdk: ">=3.0.2 <4.0.0"
|
||||
|
@ -30,7 +30,7 @@ dependencies:
|
|||
flutter_libsparkmobile:
|
||||
git:
|
||||
url: https://github.com/cypherstack/flutter_libsparkmobile.git
|
||||
ref: fb50031056fbea0326f7dd76ad59d165c1e5eee5
|
||||
ref: 3f986ca1a94bdac5d31373454c989cc2f5842de8
|
||||
|
||||
flutter_libmonero:
|
||||
path: ./crypto_plugins/flutter_libmonero
|
||||
|
|
|
@ -11,7 +11,7 @@ mkdir -p build
|
|||
./install_ndk.sh
|
||||
|
||||
(cd ../../crypto_plugins/flutter_liblelantus/scripts/android && ./build_all.sh ) &
|
||||
(cd ../../crypto_plugins/flutter_libepiccash/scripts/android && ./install_ndk.sh && ./build_all.sh ) &
|
||||
(cd ../../crypto_plugins/flutter_libepiccash/scripts/android && ./install_ndk.sh && ./build_opensll.sh && ./build_all.sh ) &
|
||||
(cd ../../crypto_plugins/flutter_libmonero/scripts/android/ && ./build_all.sh ) &
|
||||
|
||||
wait
|
||||
|
|
Loading…
Reference in a new issue