Merge branch 'staging' into add-onchain-notes-for-epic

This commit is contained in:
julian-CStack 2023-07-05 11:58:29 -06:00 committed by GitHub
commit ebf67df3a9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
17 changed files with 55 additions and 93 deletions

View file

@ -29,13 +29,6 @@ Then in `File > Settings > Plugins`, install the **Flutter** and **Dart** plugin
Make a Pixel 4 (API 30) x86_64 emulator with 2GB of storage space for emulation Make a Pixel 4 (API 30) x86_64 emulator with 2GB of storage space for emulation
### Scripted setup
[`scripts/setup.sh`](./../scripts/setup.sh) is provided as a tool to set up installation for building: download the script and run it anywhere. This script should skip the entire [Manual setup](#manual-setup) section below and prepare you to [run the prebuild script](#run-prebuild-script), [build the plugins](#Build-plugins), and [run](#Running).
### Manual setup
> If you used the `setup.sh` script, skip to [running](#Running)
Install basic dependencies Install basic dependencies
``` ```
sudo apt-get install libssl-dev curl unzip automake build-essential file pkg-config git python libtool libtinfo5 cmake libgit2-dev clang libncurses5-dev libncursesw5-dev zlib1g-dev llvm python3-distutils sudo apt-get install libssl-dev curl unzip automake build-essential file pkg-config git python libtool libtinfo5 cmake libgit2-dev clang libncurses5-dev libncursesw5-dev zlib1g-dev llvm python3-distutils

View file

@ -66,7 +66,7 @@ class MainDB {
// contact entries // contact entries
List<ContactEntry> getContactEntries() { List<ContactEntry> getContactEntries() {
return isar.contactEntrys.where().findAllSync(); return isar.contactEntrys.where().sortByName().findAllSync();
} }
Future<bool> deleteContactEntry({required String id}) { Future<bool> deleteContactEntry({required String id}) {

View file

@ -146,7 +146,7 @@ class ElectrumX {
throw response.exception!; throw response.exception!;
} }
if (response.data["error"] != null) { if (response.data is Map && response.data["error"] != null) {
if (response.data["error"] if (response.data["error"]
.toString() .toString()
.contains("No such mempool or blockchain transaction")) { .contains("No such mempool or blockchain transaction")) {

View file

@ -33,6 +33,22 @@ class ContactEntry {
@Index(unique: true, replace: true) @Index(unique: true, replace: true)
late final String customId; late final String customId;
@ignore
List<ContactAddressEntry> get addressesSorted {
final List<ContactAddressEntry> sorted = [];
for (final coin in Coin.values) {
final slice = addresses.where((e) => e.coin == coin).toList();
if (slice.isNotEmpty) {
slice.sort(
(a, b) => (a.other ?? a.label).compareTo(b.other ?? b.label),
);
sorted.addAll(slice);
}
}
return sorted;
}
ContactEntry copyWith({ ContactEntry copyWith({
bool shouldCopyEmojiWithNull = false, bool shouldCopyEmojiWithNull = false,
String? emojiChar, String? emojiChar,

View file

@ -302,7 +302,7 @@ class _AddressBookViewState extends ConsumerState<AddressBookView> {
child: Column( child: Column(
children: [ children: [
...contacts ...contacts
.where((element) => element.addresses .where((element) => element.addressesSorted
.where((e) => ref.watch(addressBookFilterProvider .where((e) => ref.watch(addressBookFilterProvider
.select((value) => value.coins.contains(e.coin)))) .select((value) => value.coins.contains(e.coin))))
.isNotEmpty) .isNotEmpty)
@ -350,7 +350,7 @@ class _AddressBookViewState extends ConsumerState<AddressBookView> {
child: Column( child: Column(
children: [ children: [
...contacts ...contacts
.where((element) => element.addresses .where((element) => element.addressesSorted
.where((e) => ref.watch( .where((e) => ref.watch(
addressBookFilterProvider.select((value) => addressBookFilterProvider.select((value) =>
value.coins.contains(e.coin)))) value.coins.contains(e.coin))))

View file

@ -211,7 +211,8 @@ class _AddNewContactAddressViewState
const Duration(milliseconds: 75), const Duration(milliseconds: 75),
); );
} }
List<ContactAddressEntry> entries = contact.addresses; List<ContactAddressEntry> entries =
contact.addresses.toList();
entries.add(ref entries.add(ref
.read(addressEntryDataProvider(0)) .read(addressEntryDataProvider(0))

View file

@ -341,7 +341,7 @@ class _ContactDetailsViewState extends ConsumerState<ContactDetailsView> {
padding: const EdgeInsets.all(0), padding: const EdgeInsets.all(0),
child: Column( child: Column(
children: [ children: [
..._contact.addresses.map( ..._contact.addressesSorted.map(
(e) => Padding( (e) => Padding(
padding: const EdgeInsets.all(12), padding: const EdgeInsets.all(12),
child: Row( child: Row(

View file

@ -63,7 +63,7 @@ class ContactPopUp extends ConsumerWidget {
bool isExchangeFlow = bool isExchangeFlow =
ref.watch(exchangeFlowIsActiveStateProvider.state).state; ref.watch(exchangeFlowIsActiveStateProvider.state).state;
final addresses = contact.addresses.where((e) { final addresses = contact.addressesSorted.where((e) {
if (hasActiveWallet && !isExchangeFlow) { if (hasActiveWallet && !isExchangeFlow) {
return e.coin == active[0].coin; return e.coin == active[0].coin;
} else { } else {

View file

@ -2127,6 +2127,7 @@ class _SendViewState extends ConsumerState<SendView> {
top: 16, top: 16,
), ),
child: FeeSlider( child: FeeSlider(
coin: coin,
onSatVByteChanged: (rate) { onSatVByteChanged: (rate) {
customFeeRate = rate; customFeeRate = rate;
}, },

View file

@ -53,15 +53,6 @@ class DesktopContactDetails extends ConsumerStatefulWidget {
class _DesktopContactDetailsState extends ConsumerState<DesktopContactDetails> { class _DesktopContactDetailsState extends ConsumerState<DesktopContactDetails> {
List<Tuple2<String, Transaction>> _cachedTransactions = []; List<Tuple2<String, Transaction>> _cachedTransactions = [];
bool _contactHasAddress(String address, ContactEntry contact) {
for (final entry in contact.addresses) {
if (entry.address == address) {
return true;
}
}
return false;
}
Future<List<Tuple2<String, Transaction>>> _filteredTransactionsByContact( Future<List<Tuple2<String, Transaction>>> _filteredTransactionsByContact(
List<Manager> managers, List<Manager> managers,
) async { ) async {
@ -259,7 +250,9 @@ class _DesktopContactDetailsState extends ConsumerState<DesktopContactDetails> {
child: Column( child: Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
for (int i = 0; i < contact.addresses.length; i++) for (int i = 0;
i < contact.addressesSorted.length;
i++)
Column( Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
@ -273,7 +266,7 @@ class _DesktopContactDetailsState extends ConsumerState<DesktopContactDetails> {
Padding( Padding(
padding: const EdgeInsets.all(18), padding: const EdgeInsets.all(18),
child: DesktopAddressCard( child: DesktopAddressCard(
entry: contact.addresses[i], entry: contact.addressesSorted[i],
contactId: contact.customId, contactId: contact.customId,
), ),
), ),

View file

@ -69,8 +69,8 @@ class _AddressBookAddressChooserState extends State<AddressBookAddressChooser> {
List<ContactEntry> filter(List<ContactEntry> contacts, String searchTerm) { List<ContactEntry> filter(List<ContactEntry> contacts, String searchTerm) {
if (widget.coin != null) { if (widget.coin != null) {
contacts.removeWhere( contacts.removeWhere((e) =>
(e) => e.addresses.where((a) => a.coin == widget.coin!).isEmpty); e.addressesSorted.where((a) => a.coin == widget.coin!).isEmpty);
} }
contacts.retainWhere((e) => _matches(searchTerm, e)); contacts.retainWhere((e) => _matches(searchTerm, e));

View file

@ -78,7 +78,7 @@ class _ContactListItemState extends ConsumerState<ContactListItem> {
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
// filter addresses by coin is provided before building address list // filter addresses by coin is provided before building address list
...contact.addresses ...contact.addressesSorted
.where((e) => .where((e) =>
filterByCoin != null ? e.coin == filterByCoin! : true) filterByCoin != null ? e.coin == filterByCoin! : true)
.map( .map(

View file

@ -1564,6 +1564,7 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
top: 16, top: 16,
), ),
child: FeeSlider( child: FeeSlider(
coin: coin,
onSatVByteChanged: (rate) { onSatVByteChanged: (rate) {
customFeeRate = rate; customFeeRate = rate;
}, },

View file

@ -2665,7 +2665,10 @@ class DogecoinWallet extends CoinServiceAPI
Logging.instance Logging.instance
.log("Starting buildTransaction ----------", level: LogLevel.Info); .log("Starting buildTransaction ----------", level: LogLevel.Info);
final txb = TransactionBuilder(network: network); final txb = TransactionBuilder(
network: network,
maximumFeeRate: 2500000, // 1000x default value in bitcoindart lib
);
txb.setVersion(1); txb.setVersion(1);
// Add transaction inputs // Add transaction inputs

View file

@ -70,9 +70,10 @@ class _AddressBookCardState extends ConsumerState<AddressBookCard> {
final contact = _contact!; final contact = _contact!;
final List<Coin> coins = []; final List<Coin> coins = [];
for (var element in contact.addresses) {
if (!coins.contains(element.coin)) { for (final coin in Coin.values) {
coins.add(element.coin); if (contact.addresses.where((e) => e.coin == coin).isNotEmpty) {
coins.add(coin);
} }
} }

View file

@ -1,14 +1,17 @@
import 'dart:math'; import 'dart:math';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:stackwallet/utilities/enums/coin_enum.dart';
import 'package:stackwallet/utilities/text_styles.dart'; import 'package:stackwallet/utilities/text_styles.dart';
class FeeSlider extends StatefulWidget { class FeeSlider extends StatefulWidget {
const FeeSlider({ const FeeSlider({
super.key, super.key,
required this.onSatVByteChanged, required this.onSatVByteChanged,
required this.coin,
}); });
final Coin coin;
final void Function(int) onSatVByteChanged; final void Function(int) onSatVByteChanged;
@override @override
@ -16,12 +19,12 @@ class FeeSlider extends StatefulWidget {
} }
class _FeeSliderState extends State<FeeSlider> { class _FeeSliderState extends State<FeeSlider> {
static const int min = 1; static const double min = 1;
static const int max = 4; static const double max = 4;
double sliderValue = 0; double sliderValue = 0;
int rate = min; int rate = min.toInt();
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -45,7 +48,14 @@ class _FeeSliderState extends State<FeeSlider> {
onChanged: (value) { onChanged: (value) {
setState(() { setState(() {
sliderValue = value; sliderValue = value;
rate = pow(sliderValue * (max - min) + min, 4).toInt(); final number = pow(sliderValue * (max - min) + min, 4).toDouble();
switch (widget.coin) {
case Coin.dogecoin:
case Coin.dogecoinTestNet:
rate = (number * 1000).toInt();
default:
rate = number.toInt();
}
}); });
widget.onSatVByteChanged(rate); widget.onSatVByteChanged(rate);
}, },

View file

@ -1,57 +0,0 @@
#!/bin/bash
export SCRIPTS=$(pwd)
sudo apt update && sudo apt upgrade -y && sudo apt dist-upgrade -y
mkdir "$HOME/development"
mkdir "$HOME/projects"
sudo apt install -y git build-essential curl
export DEVELOPMENT=$HOME/development
export PROJECTS=$HOME/projects
# setup flutter
sudo apt install -y unzip pkg-config clang cmake ninja-build libgtk-3-dev
cd $DEVELOPMENT
git clone https://github.com/flutter/flutter.git
cd flutter
git checkout 3.10.5
export FLUTTER_DIR=$(pwd)/bin
echo 'export PATH="$PATH:'${FLUTTER_DIR}'"' >> ~/.bashrc
source ~/.bashrc
flutter doctor
# install stack wallet dependencies
sudo apt-get install -y unzip automake build-essential file pkg-config git python libtool libtinfo5 cmake openjdk-8-jre-headless libgit2-dev clang libncurses5-dev libncursesw5-dev zlib1g-dev llvm
sudo apt-get install -y debhelper libclang-dev cargo rustc opencl-headers libssl-dev ocl-icd-opencl-dev
sudo apt-get install -y unzip automake build-essential file pkg-config git python libtool libtinfo5 cmake openjdk-8-jre-headless
sudo apt install -y libc6-dev-i386
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
source "$HOME/.cargo/env"
cargo install cargo-ndk
rustup target add aarch64-linux-android armv7-linux-androideabi i686-linux-android x86_64-linux-android
# # setup stack_wallet github
# cd $PROJECTS
# git clone https://github.com/cypherstack/stack_wallet.git
# cd stack_wallet
# export STACK_WALLET=$(pwd)
# git submodule update --init --recursive
# # create template lib/external_api_keys.dart file if it doesn't already exist
# KEYS="$HOME/projects/stack_wallet/lib/external_api_keys.dart"
# if ! test -f "$KEYS"; then
# echo 'prebuild.sh: creating template lib/external_api_keys.dart file'
# printf 'const kChangeNowApiKey = "";\nconst kSimpleSwapApiKey = "";' > $KEYS
# fi
# build stack wallet plugins
cd $SCRIPTS
./prebuild.sh
cd android
./build_all.sh
cd ../linux
./build_all.sh