Skip to content

Commit

Permalink
Cw 453 (#1306)
Browse files Browse the repository at this point in the history
* feat: rebase btc-addr-types, migrate to bitcoin_base

* feat: allow scanning elect-rs using get_tweaks

* feat: scanning and adding addresses working with getTweaks, add btc SP address type

* chore: pubspec.lock

* chore: pubspec.lock

* fix: scan when switching, fix multiple unspents in same tx

* fix: initial scan

* fix: initial scan

* fix: scanning issues

* fix: sync, storing silent unspents

* chore: deps

* fix: label issues, clear spent utxo

* chore: deps

* fix: build

* fix: missing types

* feat: new electrs API & changes, fixes for last block scanning

* feat: Scan Silent Payments homepage toggle

* chore: build configure

* feat: generic fixes, testnet UI improvements, useSSL on bitcoin nodes

* fix: invalid Object in sendData

* feat: improve addresses page & address book displays

* feat: silent payments labeled addresses disclaimer

* fix: missing i18n

* chore: print

* feat: single block scan, rescan by date working for btc mainnet

* feat: new cake features page replace market page, move sp scan toggle, auto switch node pop up alert

* feat: delete silent addresses

* fix: red dot in non ssl nodes

* fix: inconsistent connection states, fix tx history

* fix: tx & balance displays, cpfp sending

* feat: new rust lib

* chore: node path

* fix: check node based on network

* fix: missing txcount from addresses

* style: padding in feature page cards

* fix: restore not getting all wallet addresses by type

* fix: auto switch node broken

* fix: silent payment txs not being restored

* feat: change scanning to subscription model, sync improvements

* fix: scan re-subscription

* fix: default nodes

* fix: improve scanning by date, fix single block scan

* refactor: common function for input tx selection

* fix: nodes & build

* fix: send all with multiple outs

* refactor: unchanged file

* Update pr_test_build.yml

* chore: upgrade

* chore: merge changes

* refactor: unchanged files [skip ci]

* fix: scan fixes, add date, allow sending while scanning

* feat: sync fixes, sp settings

* feat: fix resyncing

* fix: date from height logic, status disconnected & chain tip get

* fix: params

* feat: electrum migration if using cake electrum

* fix nodes
update versions

* re-enable tron

* update sp_scanner to work on iOS [skip ci]

* fix: wrong socket for old electrum nodes

* Fix unchecked wallet type call

* fix: double balance

* feat: node domain

* fix: menu name

* fix: update tip on set scanning

* fix: connection switching back and forth

* feat: check if node is electrs, and supports sp

* chore: fix build

* minor enhancements

* fixes and enhancements

* solve conflicts with main

* fix: status toggle

* minor enhancement

* Monero.com fixes

* update sp_scanner to include windows and linux

---------

Co-authored-by: Omar Hatem <omarh.ismail1@gmail.com>
  • Loading branch information
rafael-xmr and OmarHatem28 committed May 29, 2024
1 parent faa49d2 commit 96b9b60
Show file tree
Hide file tree
Showing 122 changed files with 3,879 additions and 1,242 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/pr_test_build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ jobs:
- name: Flutter action
uses: subosito/flutter-action@v1
with:
flutter-version: "3.19.5"
flutter-version: "3.19.6"
channel: stable

- name: Install package dependencies
Expand Down
65 changes: 65 additions & 0 deletions assets/images/cards.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/images/tbtc.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 2 additions & 3 deletions assets/text/Release_Notes.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
Add Tron wallet
Hardware wallets enhancements
Bug fixes
Bitcoin Silent Payments
Bug fixes and generic enhancements
132 changes: 102 additions & 30 deletions cw_bitcoin/lib/bitcoin_address_record.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import 'dart:convert';
import 'package:bitcoin_base/bitcoin_base.dart';
import 'package:cw_bitcoin/script_hash.dart' as sh;

class BitcoinAddressRecord {
BitcoinAddressRecord(
abstract class BaseBitcoinAddressRecord {
BaseBitcoinAddressRecord(
this.address, {
required this.index,
this.isHidden = false,
Expand All @@ -13,36 +13,14 @@ class BitcoinAddressRecord {
String name = '',
bool isUsed = false,
required this.type,
String? scriptHash,
required this.network,
}) : _txCount = txCount,
_balance = balance,
_name = name,
_isUsed = isUsed,
scriptHash = scriptHash ?? sh.scriptHash(address, network: network);

factory BitcoinAddressRecord.fromJSON(String jsonSource, BasedUtxoNetwork network) {
final decoded = json.decode(jsonSource) as Map;

return BitcoinAddressRecord(
decoded['address'] as String,
index: decoded['index'] as int,
isHidden: decoded['isHidden'] as bool? ?? false,
isUsed: decoded['isUsed'] as bool? ?? false,
txCount: decoded['txCount'] as int? ?? 0,
name: decoded['name'] as String? ?? '',
balance: decoded['balance'] as int? ?? 0,
type: decoded['type'] != null && decoded['type'] != ''
? BitcoinAddressType.values
.firstWhere((type) => type.toString() == decoded['type'] as String)
: SegwitAddresType.p2wpkh,
scriptHash: decoded['scriptHash'] as String?,
network: network,
);
}
_isUsed = isUsed;

@override
bool operator ==(Object o) => o is BitcoinAddressRecord && address == o.address;
bool operator ==(Object o) => o is BaseBitcoinAddressRecord && address == o.address;

final String address;
bool isHidden;
Expand All @@ -51,8 +29,7 @@ class BitcoinAddressRecord {
int _balance;
String _name;
bool _isUsed;
String? scriptHash;
BasedUtxoNetwork network;
BasedUtxoNetwork? network;

int get txCount => _txCount;

Expand All @@ -69,16 +46,57 @@ class BitcoinAddressRecord {
void setAsUsed() => _isUsed = true;
void setNewName(String label) => _name = label;

@override
int get hashCode => address.hashCode;

BitcoinAddressType type;

String updateScriptHash(BasedUtxoNetwork network) {
String toJSON();
}

class BitcoinAddressRecord extends BaseBitcoinAddressRecord {
BitcoinAddressRecord(
super.address, {
required super.index,
super.isHidden = false,
super.txCount = 0,
super.balance = 0,
super.name = '',
super.isUsed = false,
required super.type,
String? scriptHash,
required super.network,
}) : scriptHash =
scriptHash ?? (network != null ? sh.scriptHash(address, network: network) : null);

factory BitcoinAddressRecord.fromJSON(String jsonSource, {BasedUtxoNetwork? network}) {
final decoded = json.decode(jsonSource) as Map;

return BitcoinAddressRecord(
decoded['address'] as String,
index: decoded['index'] as int,
isHidden: decoded['isHidden'] as bool? ?? false,
isUsed: decoded['isUsed'] as bool? ?? false,
txCount: decoded['txCount'] as int? ?? 0,
name: decoded['name'] as String? ?? '',
balance: decoded['balance'] as int? ?? 0,
type: decoded['type'] != null && decoded['type'] != ''
? BitcoinAddressType.values
.firstWhere((type) => type.toString() == decoded['type'] as String)
: SegwitAddresType.p2wpkh,
scriptHash: decoded['scriptHash'] as String?,
network: network,
);
}

String? scriptHash;

String getScriptHash(BasedUtxoNetwork network) {
if (scriptHash != null) return scriptHash!;
scriptHash = sh.scriptHash(address, network: network);
return scriptHash!;
}

@override
String toJSON() => json.encode({
'address': address,
'index': index,
Expand All @@ -91,3 +109,57 @@ class BitcoinAddressRecord {
'scriptHash': scriptHash,
});
}

class BitcoinSilentPaymentAddressRecord extends BaseBitcoinAddressRecord {
BitcoinSilentPaymentAddressRecord(
super.address, {
required super.index,
super.isHidden = false,
super.txCount = 0,
super.balance = 0,
super.name = '',
super.isUsed = false,
required this.silentPaymentTweak,
required super.network,
required super.type,
}) : super();

factory BitcoinSilentPaymentAddressRecord.fromJSON(String jsonSource,
{BasedUtxoNetwork? network}) {
final decoded = json.decode(jsonSource) as Map;

return BitcoinSilentPaymentAddressRecord(
decoded['address'] as String,
index: decoded['index'] as int,
isHidden: decoded['isHidden'] as bool? ?? false,
isUsed: decoded['isUsed'] as bool? ?? false,
txCount: decoded['txCount'] as int? ?? 0,
name: decoded['name'] as String? ?? '',
balance: decoded['balance'] as int? ?? 0,
network: (decoded['network'] as String?) == null
? network
: BasedUtxoNetwork.fromName(decoded['network'] as String),
silentPaymentTweak: decoded['silent_payment_tweak'] as String?,
type: decoded['type'] != null && decoded['type'] != ''
? BitcoinAddressType.values
.firstWhere((type) => type.toString() == decoded['type'] as String)
: SilentPaymentsAddresType.p2sp,
);
}

final String? silentPaymentTweak;

@override
String toJSON() => json.encode({
'address': address,
'index': index,
'isHidden': isHidden,
'isUsed': isUsed,
'txCount': txCount,
'name': name,
'balance': balance,
'type': type.toString(),
'network': network?.value,
'silent_payment_tweak': silentPaymentTweak,
});
}
23 changes: 23 additions & 0 deletions cw_bitcoin/lib/bitcoin_receive_page_option.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ class BitcoinReceivePageOption implements ReceivePageOption {
static const p2wsh = BitcoinReceivePageOption._('Segwit (P2WSH)');
static const p2pkh = BitcoinReceivePageOption._('Legacy (P2PKH)');

static const silent_payments = BitcoinReceivePageOption._('Silent Payments');

const BitcoinReceivePageOption._(this.value);

final String value;
Expand All @@ -17,13 +19,32 @@ class BitcoinReceivePageOption implements ReceivePageOption {
}

static const all = [
BitcoinReceivePageOption.silent_payments,
BitcoinReceivePageOption.p2wpkh,
BitcoinReceivePageOption.p2tr,
BitcoinReceivePageOption.p2wsh,
BitcoinReceivePageOption.p2sh,
BitcoinReceivePageOption.p2pkh
];

BitcoinAddressType toType() {
switch (this) {
case BitcoinReceivePageOption.p2tr:
return SegwitAddresType.p2tr;
case BitcoinReceivePageOption.p2wsh:
return SegwitAddresType.p2wsh;
case BitcoinReceivePageOption.p2pkh:
return P2pkhAddressType.p2pkh;
case BitcoinReceivePageOption.p2sh:
return P2shAddressType.p2wpkhInP2sh;
case BitcoinReceivePageOption.silent_payments:
return SilentPaymentsAddresType.p2sp;
case BitcoinReceivePageOption.p2wpkh:
default:
return SegwitAddresType.p2wpkh;
}
}

factory BitcoinReceivePageOption.fromType(BitcoinAddressType type) {
switch (type) {
case SegwitAddresType.p2tr:
Expand All @@ -34,6 +55,8 @@ class BitcoinReceivePageOption implements ReceivePageOption {
return BitcoinReceivePageOption.p2pkh;
case P2shAddressType.p2wpkhInP2sh:
return BitcoinReceivePageOption.p2sh;
case SilentPaymentsAddresType.p2sp:
return BitcoinReceivePageOption.silent_payments;
case SegwitAddresType.p2wpkh:
default:
return BitcoinReceivePageOption.p2wpkh;
Expand Down
61 changes: 57 additions & 4 deletions cw_bitcoin/lib/bitcoin_unspent.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,66 @@ import 'package:cw_bitcoin/bitcoin_address_record.dart';
import 'package:cw_core/unspent_transaction_output.dart';

class BitcoinUnspent extends Unspent {
BitcoinUnspent(BitcoinAddressRecord addressRecord, String hash, int value, int vout)
BitcoinUnspent(BaseBitcoinAddressRecord addressRecord, String hash, int value, int vout)
: bitcoinAddressRecord = addressRecord,
super(addressRecord.address, hash, value, vout, null);

factory BitcoinUnspent.fromJSON(BitcoinAddressRecord address, Map<String, dynamic> json) =>
factory BitcoinUnspent.fromJSON(BaseBitcoinAddressRecord? address, Map<String, dynamic> json) =>
BitcoinUnspent(
address, json['tx_hash'] as String, json['value'] as int, json['tx_pos'] as int);
address ?? BitcoinAddressRecord.fromJSON(json['address_record'].toString()),
json['tx_hash'] as String,
json['value'] as int,
json['tx_pos'] as int,
);

final BitcoinAddressRecord bitcoinAddressRecord;
Map<String, dynamic> toJson() {
final json = <String, dynamic>{
'address_record': bitcoinAddressRecord.toJSON(),
'tx_hash': hash,
'value': value,
'tx_pos': vout,
};
return json;
}

final BaseBitcoinAddressRecord bitcoinAddressRecord;
}

class BitcoinSilentPaymentsUnspent extends BitcoinUnspent {
BitcoinSilentPaymentsUnspent(
BitcoinSilentPaymentAddressRecord addressRecord,
String hash,
int value,
int vout, {
required this.silentPaymentTweak,
required this.silentPaymentLabel,
}) : super(addressRecord, hash, value, vout);

@override
factory BitcoinSilentPaymentsUnspent.fromJSON(
BitcoinSilentPaymentAddressRecord? address, Map<String, dynamic> json) =>
BitcoinSilentPaymentsUnspent(
address ?? BitcoinSilentPaymentAddressRecord.fromJSON(json['address_record'].toString()),
json['tx_hash'] as String,
json['value'] as int,
json['tx_pos'] as int,
silentPaymentTweak: json['silent_payment_tweak'] as String?,
silentPaymentLabel: json['silent_payment_label'] as String?,
);

@override
Map<String, dynamic> toJson() {
final json = <String, dynamic>{
'address_record': bitcoinAddressRecord.toJSON(),
'tx_hash': hash,
'value': value,
'tx_pos': vout,
'silent_payment_tweak': silentPaymentTweak,
'silent_payment_label': silentPaymentLabel,
};
return json;
}

String? silentPaymentTweak;
String? silentPaymentLabel;
}
Loading

0 comments on commit 96b9b60

Please sign in to comment.