mirror of
https://github.com/cake-tech/cake_wallet.git
synced 2025-01-24 03:26:38 +00:00
initial commit
This commit is contained in:
parent
f4fad4d94d
commit
ec1d565658
42 changed files with 993 additions and 6 deletions
1
.github/workflows/pr_test_build.yml
vendored
1
.github/workflows/pr_test_build.yml
vendored
|
@ -93,6 +93,7 @@ jobs:
|
||||||
cd cw_bitcoin && flutter pub get && flutter packages pub run build_runner build --delete-conflicting-outputs && cd ..
|
cd cw_bitcoin && flutter pub get && flutter packages pub run build_runner build --delete-conflicting-outputs && cd ..
|
||||||
cd cw_haven && flutter pub get && flutter packages pub run build_runner build --delete-conflicting-outputs && cd ..
|
cd cw_haven && flutter pub get && flutter packages pub run build_runner build --delete-conflicting-outputs && cd ..
|
||||||
cd cw_ethereum && flutter pub get && flutter packages pub run build_runner build --delete-conflicting-outputs && cd ..
|
cd cw_ethereum && flutter pub get && flutter packages pub run build_runner build --delete-conflicting-outputs && cd ..
|
||||||
|
cd cw_bitcoin_cash && flutter pub get && flutter packages pub run build_runner build --delete-conflicting-outputs && cd ..
|
||||||
flutter packages pub run build_runner build --delete-conflicting-outputs
|
flutter packages pub run build_runner build --delete-conflicting-outputs
|
||||||
|
|
||||||
- name: Add secrets
|
- name: Add secrets
|
||||||
|
|
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -124,6 +124,7 @@ lib/bitcoin/bitcoin.dart
|
||||||
lib/monero/monero.dart
|
lib/monero/monero.dart
|
||||||
lib/haven/haven.dart
|
lib/haven/haven.dart
|
||||||
lib/ethereum/ethereum.dart
|
lib/ethereum/ethereum.dart
|
||||||
|
lib/bitcoin_cash/bitcoin_cash.dart
|
||||||
|
|
||||||
ios/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_180.png
|
ios/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_180.png
|
||||||
ios/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_120.png
|
ios/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_120.png
|
||||||
|
|
30
cw_bitcoin_cash/.gitignore
vendored
Normal file
30
cw_bitcoin_cash/.gitignore
vendored
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
# Miscellaneous
|
||||||
|
*.class
|
||||||
|
*.log
|
||||||
|
*.pyc
|
||||||
|
*.swp
|
||||||
|
.DS_Store
|
||||||
|
.atom/
|
||||||
|
.buildlog/
|
||||||
|
.history
|
||||||
|
.svn/
|
||||||
|
migrate_working_dir/
|
||||||
|
|
||||||
|
# IntelliJ related
|
||||||
|
*.iml
|
||||||
|
*.ipr
|
||||||
|
*.iws
|
||||||
|
.idea/
|
||||||
|
|
||||||
|
# The .vscode folder contains launch configuration and tasks you configure in
|
||||||
|
# VS Code which you may wish to be included in version control, so this line
|
||||||
|
# is commented out by default.
|
||||||
|
#.vscode/
|
||||||
|
|
||||||
|
# Flutter/Dart/Pub related
|
||||||
|
# Libraries should not include pubspec.lock, per https://dart.dev/guides/libraries/private-files#pubspeclock.
|
||||||
|
/pubspec.lock
|
||||||
|
**/doc/api/
|
||||||
|
.dart_tool/
|
||||||
|
.packages
|
||||||
|
build/
|
10
cw_bitcoin_cash/.metadata
Normal file
10
cw_bitcoin_cash/.metadata
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
# This file tracks properties of this Flutter project.
|
||||||
|
# Used by Flutter tool to assess capabilities and perform upgrades etc.
|
||||||
|
#
|
||||||
|
# This file should be version controlled and should not be manually edited.
|
||||||
|
|
||||||
|
version:
|
||||||
|
revision: b06b8b2710955028a6b562f5aa6fe62941d6febf
|
||||||
|
channel: stable
|
||||||
|
|
||||||
|
project_type: package
|
3
cw_bitcoin_cash/CHANGELOG.md
Normal file
3
cw_bitcoin_cash/CHANGELOG.md
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
## 0.0.1
|
||||||
|
|
||||||
|
* TODO: Describe initial release.
|
1
cw_bitcoin_cash/LICENSE
Normal file
1
cw_bitcoin_cash/LICENSE
Normal file
|
@ -0,0 +1 @@
|
||||||
|
TODO: Add your license here.
|
39
cw_bitcoin_cash/README.md
Normal file
39
cw_bitcoin_cash/README.md
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
<!--
|
||||||
|
This README describes the package. If you publish this package to pub.dev,
|
||||||
|
this README's contents appear on the landing page for your package.
|
||||||
|
|
||||||
|
For information about how to write a good package README, see the guide for
|
||||||
|
[writing package pages](https://dart.dev/guides/libraries/writing-package-pages).
|
||||||
|
|
||||||
|
For general information about developing packages, see the Dart guide for
|
||||||
|
[creating packages](https://dart.dev/guides/libraries/create-library-packages)
|
||||||
|
and the Flutter guide for
|
||||||
|
[developing packages and plugins](https://flutter.dev/developing-packages).
|
||||||
|
-->
|
||||||
|
|
||||||
|
TODO: Put a short description of the package here that helps potential users
|
||||||
|
know whether this package might be useful for them.
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
TODO: List what your package can do. Maybe include images, gifs, or videos.
|
||||||
|
|
||||||
|
## Getting started
|
||||||
|
|
||||||
|
TODO: List prerequisites and provide or point to information on how to
|
||||||
|
start using the package.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
TODO: Include short and useful examples for package users. Add longer examples
|
||||||
|
to `/example` folder.
|
||||||
|
|
||||||
|
```dart
|
||||||
|
const like = 'sample';
|
||||||
|
```
|
||||||
|
|
||||||
|
## Additional information
|
||||||
|
|
||||||
|
TODO: Tell users more about the package: where to find more information, how to
|
||||||
|
contribute to the package, how to file issues, what response they can expect
|
||||||
|
from the package authors, and more.
|
4
cw_bitcoin_cash/analysis_options.yaml
Normal file
4
cw_bitcoin_cash/analysis_options.yaml
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
include: package:flutter_lints/flutter.yaml
|
||||||
|
|
||||||
|
# Additional information about this file can be found at
|
||||||
|
# https://dart.dev/guides/language/analysis-options
|
9
cw_bitcoin_cash/lib/cw_bitcoin_cash.dart
Normal file
9
cw_bitcoin_cash/lib/cw_bitcoin_cash.dart
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
library cw_bitcoin_cash;
|
||||||
|
|
||||||
|
export 'src/bitcoin_cash_base.dart';
|
||||||
|
|
||||||
|
/// A Calculator.
|
||||||
|
class Calculator {
|
||||||
|
/// Returns [value] plus 1.
|
||||||
|
int addOne(int value) => value + 1;
|
||||||
|
}
|
13
cw_bitcoin_cash/lib/src/bitcoin_cash_balance.dart
Normal file
13
cw_bitcoin_cash/lib/src/bitcoin_cash_balance.dart
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
import 'package:cw_core/balance.dart';
|
||||||
|
|
||||||
|
class BitcoinCashBalance extends Balance {
|
||||||
|
BitcoinCashBalance(this.balance) : super(balance, balance);
|
||||||
|
|
||||||
|
final int balance;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get formattedAdditionalBalance => balance.toString();
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get formattedAvailableBalance => balance.toString();
|
||||||
|
}
|
11
cw_bitcoin_cash/lib/src/bitcoin_cash_base.dart
Normal file
11
cw_bitcoin_cash/lib/src/bitcoin_cash_base.dart
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
export 'bitcoin_cash_balance.dart';
|
||||||
|
export 'bitcoin_cash_client.dart';
|
||||||
|
export 'bitcoin_cash_transaction_history.dart';
|
||||||
|
export 'bitcoin_cash_transaction_info.dart';
|
||||||
|
export 'bitcoin_cash_transaction_priority.dart';
|
||||||
|
export 'bitcoin_cash_wallet.dart';
|
||||||
|
export 'bitcoin_cash_wallet_addresses.dart';
|
||||||
|
export 'bitcoin_cash_wallet_creation_credentials.dart';
|
||||||
|
export 'bitcoin_cash_wallet_service.dart';
|
||||||
|
export 'exceptions/exceptions.dart';
|
||||||
|
export 'mnemonic.dart';
|
1
cw_bitcoin_cash/lib/src/bitcoin_cash_client.dart
Normal file
1
cw_bitcoin_cash/lib/src/bitcoin_cash_client.dart
Normal file
|
@ -0,0 +1 @@
|
||||||
|
class BitcoinCashClient {}
|
|
@ -0,0 +1,25 @@
|
||||||
|
import 'package:cw_core/pending_transaction.dart';
|
||||||
|
|
||||||
|
class BitcoinCashPendingTransaction with PendingTransaction {
|
||||||
|
@override
|
||||||
|
// TODO: implement amountFormatted
|
||||||
|
String get amountFormatted => throw UnimplementedError('amountFormatted is not implemented');
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> commit() {
|
||||||
|
// TODO: implement commit
|
||||||
|
throw UnimplementedError('commit is not implemented');
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
// TODO: implement feeFormatted
|
||||||
|
String get feeFormatted => throw UnimplementedError('feeFormatted is not implemented');
|
||||||
|
|
||||||
|
@override
|
||||||
|
// TODO: implement hex
|
||||||
|
String get hex => throw UnimplementedError('hex is not implemented');
|
||||||
|
|
||||||
|
@override
|
||||||
|
// TODO: implement id
|
||||||
|
String get id => throw UnimplementedError('id is not implemented');
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
import 'dart:core';
|
||||||
|
|
||||||
|
import 'package:cw_core/transaction_history.dart';
|
||||||
|
import 'package:cw_core/wallet_info.dart';
|
||||||
|
import 'package:mobx/mobx.dart';
|
||||||
|
|
||||||
|
import 'bitcoin_cash_transaction_info.dart';
|
||||||
|
|
||||||
|
part 'bitcoin_cash_transaction_history.g.dart';
|
||||||
|
|
||||||
|
class BitcoinCashTransactionHistory = BitcoinCashTransactionHistoryBase
|
||||||
|
with _$BitcoinCashTransactionHistory;
|
||||||
|
|
||||||
|
abstract class BitcoinCashTransactionHistoryBase
|
||||||
|
extends TransactionHistoryBase<BitcoinCashTransactionInfo> with Store {
|
||||||
|
BitcoinCashTransactionHistoryBase({required this.walletInfo, required String password})
|
||||||
|
: _password = password,
|
||||||
|
_height = 0 {
|
||||||
|
transactions = ObservableMap<String, BitcoinCashTransactionInfo>();
|
||||||
|
}
|
||||||
|
|
||||||
|
final WalletInfo walletInfo;
|
||||||
|
String _password;
|
||||||
|
int _height;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> save() async {
|
||||||
|
// TODO: implement
|
||||||
|
UnimplementedError('save() is not implemented');
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void addOne(BitcoinCashTransactionInfo transaction) => transactions[transaction.id] = transaction;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void addMany(Map<String, BitcoinCashTransactionInfo> transactions) =>
|
||||||
|
this.transactions.addAll(transactions);
|
||||||
|
}
|
68
cw_bitcoin_cash/lib/src/bitcoin_cash_transaction_info.dart
Normal file
68
cw_bitcoin_cash/lib/src/bitcoin_cash_transaction_info.dart
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
import 'package:cw_core/format_amount.dart';
|
||||||
|
import 'package:cw_core/transaction_direction.dart';
|
||||||
|
import 'package:cw_core/transaction_info.dart';
|
||||||
|
|
||||||
|
class BitcoinCashTransactionInfo extends TransactionInfo {
|
||||||
|
BitcoinCashTransactionInfo({
|
||||||
|
required this.id,
|
||||||
|
required this.height,
|
||||||
|
required this.amount,
|
||||||
|
required this.fee,
|
||||||
|
this.tokenSymbol = "BCH",
|
||||||
|
this.exponent = 18,
|
||||||
|
required this.direction,
|
||||||
|
required this.isPending,
|
||||||
|
required this.date,
|
||||||
|
required this.confirmations,
|
||||||
|
});
|
||||||
|
|
||||||
|
final String id;
|
||||||
|
final int height;
|
||||||
|
final int amount;
|
||||||
|
final int exponent;
|
||||||
|
final TransactionDirection direction;
|
||||||
|
final DateTime date;
|
||||||
|
final bool isPending;
|
||||||
|
final int fee;
|
||||||
|
final int confirmations;
|
||||||
|
final String tokenSymbol;
|
||||||
|
String? _fiatAmount;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String amountFormatted() =>
|
||||||
|
'${formatAmount((BigInt.from(amount) / BigInt.from(10).pow(exponent)).toString())} $tokenSymbol';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String fiatAmount() => _fiatAmount ?? '';
|
||||||
|
|
||||||
|
@override
|
||||||
|
void changeFiatAmount(String amount) => _fiatAmount = formatAmount(amount);
|
||||||
|
|
||||||
|
@override
|
||||||
|
String feeFormatted() => '${(BigInt.from(fee) / BigInt.from(10).pow(exponent)).toString()} BCH';
|
||||||
|
|
||||||
|
factory BitcoinCashTransactionInfo.fromJson(Map<String, dynamic> data) {
|
||||||
|
return BitcoinCashTransactionInfo(
|
||||||
|
id: data['id'] as String,
|
||||||
|
height: data['height'] as int,
|
||||||
|
amount: data['amount'] as int,
|
||||||
|
fee: data['fee'] as int,
|
||||||
|
direction: parseTransactionDirectionFromInt(data['direction'] as int),
|
||||||
|
date: DateTime.fromMillisecondsSinceEpoch(data['date'] as int),
|
||||||
|
isPending: data['isPending'] as bool,
|
||||||
|
confirmations: data['confirmations'] as int);
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
final m = <String, dynamic>{};
|
||||||
|
m['id'] = id;
|
||||||
|
m['height'] = height;
|
||||||
|
m['amount'] = amount;
|
||||||
|
m['direction'] = direction.index;
|
||||||
|
m['date'] = date.millisecondsSinceEpoch;
|
||||||
|
m['isPending'] = isPending;
|
||||||
|
m['confirmations'] = confirmations;
|
||||||
|
m['fee'] = fee;
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
import 'package:cw_core/transaction_priority.dart';
|
||||||
|
|
||||||
|
class BitcoinCashTransactionPriority extends TransactionPriority{
|
||||||
|
BitcoinCashTransactionPriority({required super.title, required super.raw});
|
||||||
|
|
||||||
|
static BitcoinCashTransactionPriority deserialize ({required int raw}) {
|
||||||
|
throw UnimplementedError('BitcoinCashTransactionPriority.deserialize() is not implemented');
|
||||||
|
}
|
||||||
|
}
|
90
cw_bitcoin_cash/lib/src/bitcoin_cash_wallet.dart
Normal file
90
cw_bitcoin_cash/lib/src/bitcoin_cash_wallet.dart
Normal file
|
@ -0,0 +1,90 @@
|
||||||
|
import 'package:bitcoin_flutter/bitcoin_flutter.dart' as bitcoin;
|
||||||
|
import 'package:cw_bitcoin/bitcoin_address_record.dart';
|
||||||
|
import 'package:cw_bitcoin/electrum_balance.dart';
|
||||||
|
import 'package:cw_bitcoin/electrum_wallet.dart';
|
||||||
|
import 'package:cw_bitcoin/electrum_wallet_snapshot.dart';
|
||||||
|
import 'package:cw_core/crypto_currency.dart';
|
||||||
|
import 'package:cw_core/unspent_coins_info.dart';
|
||||||
|
import 'package:cw_core/wallet_info.dart';
|
||||||
|
import 'package:flutter/foundation.dart';
|
||||||
|
import 'package:hive/hive.dart';
|
||||||
|
import 'package:mobx/mobx.dart';
|
||||||
|
|
||||||
|
import 'bitcoin_cash_base.dart';
|
||||||
|
|
||||||
|
part 'bitcoin_cash_wallet.g.dart';
|
||||||
|
|
||||||
|
class BitcoinCashWallet = BitcoinCashWalletBase with _$BitcoinCashWallet;
|
||||||
|
|
||||||
|
abstract class BitcoinCashWalletBase extends ElectrumWallet with Store {
|
||||||
|
BitcoinCashWalletBase(
|
||||||
|
{required String mnemonic,
|
||||||
|
required String password,
|
||||||
|
required WalletInfo walletInfo,
|
||||||
|
required Box<UnspentCoinsInfo> unspentCoinsInfo,
|
||||||
|
required Uint8List seedBytes,
|
||||||
|
List<BitcoinAddressRecord>? initialAddresses,
|
||||||
|
ElectrumBalance? initialBalance,
|
||||||
|
int initialRegularAddressIndex = 0,
|
||||||
|
int initialChangeAddressIndex = 0})
|
||||||
|
: super(
|
||||||
|
mnemonic: mnemonic,
|
||||||
|
password: password,
|
||||||
|
walletInfo: walletInfo,
|
||||||
|
unspentCoinsInfo: unspentCoinsInfo,
|
||||||
|
networkType: bitcoin.bitcoin,
|
||||||
|
initialAddresses: initialAddresses,
|
||||||
|
initialBalance: initialBalance,
|
||||||
|
seedBytes: seedBytes,
|
||||||
|
currency: CryptoCurrency.bch) {
|
||||||
|
walletAddresses = BitcoinCashWalletAddresses(walletInfo,
|
||||||
|
electrumClient: electrumClient,
|
||||||
|
initialAddresses: initialAddresses,
|
||||||
|
initialRegularAddressIndex: initialRegularAddressIndex,
|
||||||
|
initialChangeAddressIndex: initialChangeAddressIndex,
|
||||||
|
mainHd: hd,
|
||||||
|
sideHd: hd,
|
||||||
|
//TODO: BCH check if this is correct
|
||||||
|
networkType: networkType);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Future<BitcoinCashWallet> create(
|
||||||
|
{required String mnemonic,
|
||||||
|
required String password,
|
||||||
|
required WalletInfo walletInfo,
|
||||||
|
required Box<UnspentCoinsInfo> unspentCoinsInfo,
|
||||||
|
List<BitcoinAddressRecord>? initialAddresses,
|
||||||
|
ElectrumBalance? initialBalance,
|
||||||
|
int initialRegularAddressIndex = 0,
|
||||||
|
int initialChangeAddressIndex = 0}) async {
|
||||||
|
return BitcoinCashWallet(
|
||||||
|
mnemonic: mnemonic,
|
||||||
|
password: password,
|
||||||
|
walletInfo: walletInfo,
|
||||||
|
unspentCoinsInfo: unspentCoinsInfo,
|
||||||
|
initialAddresses: initialAddresses,
|
||||||
|
initialBalance: initialBalance,
|
||||||
|
seedBytes: await Mnemonic.toSeed(mnemonic),
|
||||||
|
initialRegularAddressIndex: initialRegularAddressIndex,
|
||||||
|
initialChangeAddressIndex: initialChangeAddressIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Future<BitcoinCashWallet> open({
|
||||||
|
required String name,
|
||||||
|
required WalletInfo walletInfo,
|
||||||
|
required Box<UnspentCoinsInfo> unspentCoinsInfo,
|
||||||
|
required String password,
|
||||||
|
}) async {
|
||||||
|
final snp = await ElectrumWallletSnapshot.load(name, walletInfo.type, password);
|
||||||
|
return BitcoinCashWallet(
|
||||||
|
mnemonic: snp.mnemonic,
|
||||||
|
password: password,
|
||||||
|
walletInfo: walletInfo,
|
||||||
|
unspentCoinsInfo: unspentCoinsInfo,
|
||||||
|
initialAddresses: snp.addresses,
|
||||||
|
initialBalance: snp.balance,
|
||||||
|
seedBytes: await Mnemonic.toSeed(snp.mnemonic),
|
||||||
|
initialRegularAddressIndex: snp.regularAddressIndex,
|
||||||
|
initialChangeAddressIndex: snp.changeAddressIndex);
|
||||||
|
}
|
||||||
|
}
|
34
cw_bitcoin_cash/lib/src/bitcoin_cash_wallet_addresses.dart
Normal file
34
cw_bitcoin_cash/lib/src/bitcoin_cash_wallet_addresses.dart
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
import 'package:bitbox/bitbox.dart' as Bitbox;
|
||||||
|
import 'package:bitcoin_flutter/bitcoin_flutter.dart' as bitcoin;
|
||||||
|
import 'package:cw_bitcoin/bitcoin_address_record.dart';
|
||||||
|
import 'package:cw_bitcoin/electrum.dart';
|
||||||
|
import 'package:cw_bitcoin/electrum_wallet_addresses.dart';
|
||||||
|
import 'package:cw_core/wallet_info.dart';
|
||||||
|
import 'package:mobx/mobx.dart';
|
||||||
|
|
||||||
|
part 'bitcoin_cash_wallet_addresses.g.dart';
|
||||||
|
|
||||||
|
class BitcoinCashWalletAddresses = BitcoinCashWalletAddressesBase with _$BitcoinCashWalletAddresses;
|
||||||
|
|
||||||
|
abstract class BitcoinCashWalletAddressesBase extends ElectrumWalletAddresses with Store {
|
||||||
|
BitcoinCashWalletAddressesBase(WalletInfo walletInfo,
|
||||||
|
{required bitcoin.HDWallet mainHd,
|
||||||
|
required bitcoin.HDWallet sideHd,
|
||||||
|
required bitcoin.NetworkType networkType,
|
||||||
|
required ElectrumClient electrumClient,
|
||||||
|
List<BitcoinAddressRecord>? initialAddresses,
|
||||||
|
int initialRegularAddressIndex = 0,
|
||||||
|
int initialChangeAddressIndex = 0})
|
||||||
|
: super(walletInfo,
|
||||||
|
initialAddresses: initialAddresses,
|
||||||
|
initialRegularAddressIndex: initialRegularAddressIndex,
|
||||||
|
initialChangeAddressIndex: initialChangeAddressIndex,
|
||||||
|
mainHd: mainHd,
|
||||||
|
sideHd: sideHd,
|
||||||
|
electrumClient: electrumClient,
|
||||||
|
networkType: networkType);
|
||||||
|
|
||||||
|
@override
|
||||||
|
String getAddress({required int index, required bitcoin.HDWallet hd}) =>
|
||||||
|
hd.address!;
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
import 'package:cw_core/wallet_credentials.dart';
|
||||||
|
import 'package:cw_core/wallet_info.dart';
|
||||||
|
|
||||||
|
class BitcoinCashNewWalletCredentials extends WalletCredentials {
|
||||||
|
BitcoinCashNewWalletCredentials({required String name, WalletInfo? walletInfo})
|
||||||
|
: super(name: name, walletInfo: walletInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
class BitcoinCashRestoreWalletFromSeedCredentials extends WalletCredentials {
|
||||||
|
BitcoinCashRestoreWalletFromSeedCredentials(
|
||||||
|
{required String name,
|
||||||
|
required String password,
|
||||||
|
required this.mnemonic,
|
||||||
|
WalletInfo? walletInfo})
|
||||||
|
: super(name: name, password: password, walletInfo: walletInfo);
|
||||||
|
|
||||||
|
final String mnemonic;
|
||||||
|
}
|
||||||
|
|
||||||
|
class BitcoinCashRestoreWalletFromWIFCredentials extends WalletCredentials {
|
||||||
|
BitcoinCashRestoreWalletFromWIFCredentials(
|
||||||
|
{required String name, required String password, required this.wif, WalletInfo? walletInfo})
|
||||||
|
: super(name: name, password: password, walletInfo: walletInfo);
|
||||||
|
|
||||||
|
final String wif;
|
||||||
|
}
|
91
cw_bitcoin_cash/lib/src/bitcoin_cash_wallet_service.dart
Normal file
91
cw_bitcoin_cash/lib/src/bitcoin_cash_wallet_service.dart
Normal file
|
@ -0,0 +1,91 @@
|
||||||
|
import 'dart:io';
|
||||||
|
|
||||||
|
import 'package:bip39/bip39.dart';
|
||||||
|
import 'package:cw_bitcoin_cash/cw_bitcoin_cash.dart';
|
||||||
|
import 'package:cw_core/balance.dart';
|
||||||
|
import 'package:cw_core/pathForWallet.dart';
|
||||||
|
import 'package:cw_core/transaction_history.dart';
|
||||||
|
import 'package:cw_core/transaction_info.dart';
|
||||||
|
import 'package:cw_core/unspent_coins_info.dart';
|
||||||
|
import 'package:cw_core/wallet_base.dart';
|
||||||
|
import 'package:cw_core/wallet_info.dart';
|
||||||
|
import 'package:cw_core/wallet_service.dart';
|
||||||
|
import 'package:cw_core/wallet_type.dart';
|
||||||
|
import 'package:collection/collection.dart';
|
||||||
|
import 'package:hive/hive.dart';
|
||||||
|
|
||||||
|
class BitcoinCashWalletService extends WalletService<BitcoinCashNewWalletCredentials,
|
||||||
|
BitcoinCashRestoreWalletFromSeedCredentials,
|
||||||
|
BitcoinCashRestoreWalletFromWIFCredentials> {
|
||||||
|
BitcoinCashWalletService(this.walletInfoSource, this.unspentCoinsInfoSource);
|
||||||
|
|
||||||
|
final Box<WalletInfo> walletInfoSource;
|
||||||
|
final Box<UnspentCoinsInfo> unspentCoinsInfoSource;
|
||||||
|
|
||||||
|
@override
|
||||||
|
WalletType getType() => WalletType.bitcoinCash;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<bool> isWalletExit(String name) async =>
|
||||||
|
File(await pathForWallet(name: name, type: getType())).existsSync();
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<BitcoinCashWallet> create(
|
||||||
|
credentials) async {
|
||||||
|
final wallet = await BitcoinCashWalletBase.create(
|
||||||
|
mnemonic: await Mnemonic.generate(),
|
||||||
|
password: credentials.password!,
|
||||||
|
walletInfo: credentials.walletInfo!,
|
||||||
|
unspentCoinsInfo: unspentCoinsInfoSource);
|
||||||
|
await wallet.save();
|
||||||
|
await wallet.init();
|
||||||
|
return wallet;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<BitcoinCashWallet> openWallet(String name, String password) async {
|
||||||
|
final walletInfo = walletInfoSource.values.firstWhereOrNull(
|
||||||
|
(info) => info.id == WalletBase.idFor(name, getType()))!;
|
||||||
|
final wallet = await BitcoinCashWalletBase.open(
|
||||||
|
password: password, name: name, walletInfo: walletInfo,
|
||||||
|
unspentCoinsInfo: unspentCoinsInfoSource);
|
||||||
|
await wallet.init();
|
||||||
|
return wallet;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> remove(String wallet) {
|
||||||
|
// TODO: implement remove
|
||||||
|
throw UnimplementedError('remove() is not implemented');
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> rename(String currentName, String password, String newName) {
|
||||||
|
// TODO: implement rename
|
||||||
|
throw UnimplementedError('rename() is not implemented');
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<BitcoinCashWallet>
|
||||||
|
restoreFromKeys(credentials) {
|
||||||
|
// TODO: implement restoreFromKeys
|
||||||
|
throw UnimplementedError('restoreFromKeys() is not implemented');
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<BitcoinCashWallet> restoreFromSeed(
|
||||||
|
BitcoinCashRestoreWalletFromSeedCredentials credentials) async {
|
||||||
|
if (!validateMnemonic(credentials.mnemonic)) {
|
||||||
|
throw BitcoinCashMnemonicIsIncorrectException();
|
||||||
|
}
|
||||||
|
|
||||||
|
final wallet = await BitcoinCashWalletBase.create(
|
||||||
|
password: credentials.password!,
|
||||||
|
mnemonic: credentials.mnemonic,
|
||||||
|
walletInfo: credentials.walletInfo!,
|
||||||
|
unspentCoinsInfo: unspentCoinsInfoSource);
|
||||||
|
await wallet.save();
|
||||||
|
await wallet.init();
|
||||||
|
return wallet;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
class BitcoinCashMnemonicIsIncorrectException implements Exception {
|
||||||
|
@override
|
||||||
|
String toString() =>
|
||||||
|
'Bitcoin Cash mnemonic has incorrect format. Mnemonic should contain 12 or 24 words separated by space.';
|
||||||
|
}
|
1
cw_bitcoin_cash/lib/src/exceptions/exceptions.dart
Normal file
1
cw_bitcoin_cash/lib/src/exceptions/exceptions.dart
Normal file
|
@ -0,0 +1 @@
|
||||||
|
export 'bitcoin_cash_mnemonic_is_incorrect_exception.dart';
|
11
cw_bitcoin_cash/lib/src/mnemonic.dart
Normal file
11
cw_bitcoin_cash/lib/src/mnemonic.dart
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
import 'dart:typed_data';
|
||||||
|
|
||||||
|
import 'package:bip39/bip39.dart' as bip39;
|
||||||
|
|
||||||
|
class Mnemonic {
|
||||||
|
/// Generate bip39 mnemonic
|
||||||
|
static String generate({int strength = 128}) => bip39.generateMnemonic(strength: strength);
|
||||||
|
|
||||||
|
/// Create root seed from mnemonic
|
||||||
|
static Uint8List toSeed(String mnemonic) => bip39.mnemonicToSeed(mnemonic);
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
C:/Users/borod/AppData/Local/Pub/Cache/hosted/pub.dev/path_provider_linux-2.2.0/
|
11
cw_bitcoin_cash/linux/flutter/generated_plugin_registrant.cc
Normal file
11
cw_bitcoin_cash/linux/flutter/generated_plugin_registrant.cc
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
//
|
||||||
|
// Generated file. Do not edit.
|
||||||
|
//
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
|
|
||||||
|
#include "generated_plugin_registrant.h"
|
||||||
|
|
||||||
|
|
||||||
|
void fl_register_plugins(FlPluginRegistry* registry) {
|
||||||
|
}
|
15
cw_bitcoin_cash/linux/flutter/generated_plugin_registrant.h
Normal file
15
cw_bitcoin_cash/linux/flutter/generated_plugin_registrant.h
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
//
|
||||||
|
// Generated file. Do not edit.
|
||||||
|
//
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
|
|
||||||
|
#ifndef GENERATED_PLUGIN_REGISTRANT_
|
||||||
|
#define GENERATED_PLUGIN_REGISTRANT_
|
||||||
|
|
||||||
|
#include <flutter_linux/flutter_linux.h>
|
||||||
|
|
||||||
|
// Registers Flutter plugins.
|
||||||
|
void fl_register_plugins(FlPluginRegistry* registry);
|
||||||
|
|
||||||
|
#endif // GENERATED_PLUGIN_REGISTRANT_
|
23
cw_bitcoin_cash/linux/flutter/generated_plugins.cmake
Normal file
23
cw_bitcoin_cash/linux/flutter/generated_plugins.cmake
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
#
|
||||||
|
# Generated file, do not edit.
|
||||||
|
#
|
||||||
|
|
||||||
|
list(APPEND FLUTTER_PLUGIN_LIST
|
||||||
|
)
|
||||||
|
|
||||||
|
list(APPEND FLUTTER_FFI_PLUGIN_LIST
|
||||||
|
)
|
||||||
|
|
||||||
|
set(PLUGIN_BUNDLED_LIBRARIES)
|
||||||
|
|
||||||
|
foreach(plugin ${FLUTTER_PLUGIN_LIST})
|
||||||
|
add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/linux plugins/${plugin})
|
||||||
|
target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin)
|
||||||
|
list(APPEND PLUGIN_BUNDLED_LIBRARIES $<TARGET_FILE:${plugin}_plugin>)
|
||||||
|
list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries})
|
||||||
|
endforeach(plugin)
|
||||||
|
|
||||||
|
foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST})
|
||||||
|
add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/linux plugins/${ffi_plugin})
|
||||||
|
list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries})
|
||||||
|
endforeach(ffi_plugin)
|
|
@ -0,0 +1,12 @@
|
||||||
|
//
|
||||||
|
// Generated file. Do not edit.
|
||||||
|
//
|
||||||
|
|
||||||
|
import FlutterMacOS
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
import path_provider_foundation
|
||||||
|
|
||||||
|
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
||||||
|
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
// This is a generated file; do not edit or check into version control.
|
||||||
|
FLUTTER_ROOT=C:\Users\borod\flutter
|
||||||
|
FLUTTER_APPLICATION_PATH=C:\cake_wallet\cw_bitcoin_cash
|
||||||
|
COCOAPODS_PARALLEL_CODE_SIGN=true
|
||||||
|
FLUTTER_BUILD_DIR=build
|
||||||
|
FLUTTER_BUILD_NAME=0.0.1
|
||||||
|
FLUTTER_BUILD_NUMBER=0.0.1
|
||||||
|
DART_OBFUSCATION=false
|
||||||
|
TRACK_WIDGET_CREATION=true
|
||||||
|
TREE_SHAKE_ICONS=false
|
||||||
|
PACKAGE_CONFIG=.dart_tool/package_config.json
|
|
@ -0,0 +1,12 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# This is a generated file; do not edit or check into version control.
|
||||||
|
export "FLUTTER_ROOT=C:\Users\borod\flutter"
|
||||||
|
export "FLUTTER_APPLICATION_PATH=C:\cake_wallet\cw_bitcoin_cash"
|
||||||
|
export "COCOAPODS_PARALLEL_CODE_SIGN=true"
|
||||||
|
export "FLUTTER_BUILD_DIR=build"
|
||||||
|
export "FLUTTER_BUILD_NAME=0.0.1"
|
||||||
|
export "FLUTTER_BUILD_NUMBER=0.0.1"
|
||||||
|
export "DART_OBFUSCATION=false"
|
||||||
|
export "TRACK_WIDGET_CREATION=true"
|
||||||
|
export "TREE_SHAKE_ICONS=false"
|
||||||
|
export "PACKAGE_CONFIG=.dart_tool/package_config.json"
|
76
cw_bitcoin_cash/pubspec.yaml
Normal file
76
cw_bitcoin_cash/pubspec.yaml
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
name: cw_bitcoin_cash
|
||||||
|
description: A new Flutter package project.
|
||||||
|
version: 0.0.1
|
||||||
|
publish_to: none
|
||||||
|
author: Cake Wallet
|
||||||
|
homepage: https://cakewallet.com
|
||||||
|
|
||||||
|
environment:
|
||||||
|
sdk: '>=2.19.0 <3.0.0'
|
||||||
|
flutter: ">=1.17.0"
|
||||||
|
|
||||||
|
dependencies:
|
||||||
|
flutter:
|
||||||
|
sdk: flutter
|
||||||
|
bip39: ^1.0.6
|
||||||
|
bip32: ^2.0.0
|
||||||
|
path_provider: ^2.0.11
|
||||||
|
mobx: ^2.0.7+4
|
||||||
|
flutter_mobx: ^2.0.6+1
|
||||||
|
cw_core:
|
||||||
|
path: ../cw_core
|
||||||
|
cw_bitcoin:
|
||||||
|
path: ../cw_bitcoin
|
||||||
|
bitcoin_flutter:
|
||||||
|
git:
|
||||||
|
url: https://github.com/cake-tech/bitcoin_flutter.git
|
||||||
|
ref: cake-update-v2
|
||||||
|
bitbox:
|
||||||
|
git:
|
||||||
|
url: https://github.com/Serhii-Borodenko/cw_bitbox.git
|
||||||
|
ref: main
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
dev_dependencies:
|
||||||
|
flutter_test:
|
||||||
|
sdk: flutter
|
||||||
|
build_runner: ^2.1.11
|
||||||
|
mobx_codegen: ^2.0.7
|
||||||
|
hive_generator: ^1.1.3
|
||||||
|
|
||||||
|
# For information on the generic Dart part of this file, see the
|
||||||
|
# following page: https://dart.dev/tools/pub/pubspec
|
||||||
|
|
||||||
|
# The following section is specific to Flutter packages.
|
||||||
|
flutter:
|
||||||
|
|
||||||
|
# To add assets to your package, add an assets section, like this:
|
||||||
|
# assets:
|
||||||
|
# - images/a_dot_burr.jpeg
|
||||||
|
# - images/a_dot_ham.jpeg
|
||||||
|
#
|
||||||
|
# For details regarding assets in packages, see
|
||||||
|
# https://flutter.dev/assets-and-images/#from-packages
|
||||||
|
#
|
||||||
|
# An image asset can refer to one or more resolution-specific "variants", see
|
||||||
|
# https://flutter.dev/assets-and-images/#resolution-aware
|
||||||
|
|
||||||
|
# To add custom fonts to your package, add a fonts section here,
|
||||||
|
# in this "flutter" section. Each entry in this list should have a
|
||||||
|
# "family" key with the font family name, and a "fonts" key with a
|
||||||
|
# list giving the asset and other descriptors for the font. For
|
||||||
|
# example:
|
||||||
|
# fonts:
|
||||||
|
# - family: Schyler
|
||||||
|
# fonts:
|
||||||
|
# - asset: fonts/Schyler-Regular.ttf
|
||||||
|
# - asset: fonts/Schyler-Italic.ttf
|
||||||
|
# style: italic
|
||||||
|
# - family: Trajan Pro
|
||||||
|
# fonts:
|
||||||
|
# - asset: fonts/TrajanPro.ttf
|
||||||
|
# - asset: fonts/TrajanPro_Bold.ttf
|
||||||
|
# weight: 700
|
||||||
|
#
|
||||||
|
|
12
cw_bitcoin_cash/test/cw_bitcoin_cash_test.dart
Normal file
12
cw_bitcoin_cash/test/cw_bitcoin_cash_test.dart
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
|
||||||
|
import 'package:cw_bitcoin_cash/cw_bitcoin_cash.dart';
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
test('adds one to input values', () {
|
||||||
|
final calculator = Calculator();
|
||||||
|
expect(calculator.addOne(2), 3);
|
||||||
|
expect(calculator.addOne(-7), -6);
|
||||||
|
expect(calculator.addOne(0), 1);
|
||||||
|
});
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
//
|
||||||
|
// Generated file. Do not edit.
|
||||||
|
//
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
|
|
||||||
|
#include "generated_plugin_registrant.h"
|
||||||
|
|
||||||
|
|
||||||
|
void RegisterPlugins(flutter::PluginRegistry* registry) {
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
//
|
||||||
|
// Generated file. Do not edit.
|
||||||
|
//
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
|
|
||||||
|
#ifndef GENERATED_PLUGIN_REGISTRANT_
|
||||||
|
#define GENERATED_PLUGIN_REGISTRANT_
|
||||||
|
|
||||||
|
#include <flutter/plugin_registry.h>
|
||||||
|
|
||||||
|
// Registers Flutter plugins.
|
||||||
|
void RegisterPlugins(flutter::PluginRegistry* registry);
|
||||||
|
|
||||||
|
#endif // GENERATED_PLUGIN_REGISTRANT_
|
23
cw_bitcoin_cash/windows/flutter/generated_plugins.cmake
Normal file
23
cw_bitcoin_cash/windows/flutter/generated_plugins.cmake
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
#
|
||||||
|
# Generated file, do not edit.
|
||||||
|
#
|
||||||
|
|
||||||
|
list(APPEND FLUTTER_PLUGIN_LIST
|
||||||
|
)
|
||||||
|
|
||||||
|
list(APPEND FLUTTER_FFI_PLUGIN_LIST
|
||||||
|
)
|
||||||
|
|
||||||
|
set(PLUGIN_BUNDLED_LIBRARIES)
|
||||||
|
|
||||||
|
foreach(plugin ${FLUTTER_PLUGIN_LIST})
|
||||||
|
add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/windows plugins/${plugin})
|
||||||
|
target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin)
|
||||||
|
list(APPEND PLUGIN_BUNDLED_LIBRARIES $<TARGET_FILE:${plugin}_plugin>)
|
||||||
|
list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries})
|
||||||
|
endforeach(plugin)
|
||||||
|
|
||||||
|
foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST})
|
||||||
|
add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/windows plugins/${ffi_plugin})
|
||||||
|
list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries})
|
||||||
|
endforeach(ffi_plugin)
|
|
@ -13,6 +13,8 @@ CryptoCurrency currencyForWalletType(WalletType type) {
|
||||||
return CryptoCurrency.xhv;
|
return CryptoCurrency.xhv;
|
||||||
case WalletType.ethereum:
|
case WalletType.ethereum:
|
||||||
return CryptoCurrency.eth;
|
return CryptoCurrency.eth;
|
||||||
|
case WalletType.bitcoinCash:
|
||||||
|
return CryptoCurrency.bch;
|
||||||
default:
|
default:
|
||||||
throw Exception('Unexpected wallet type: ${type.toString()} for CryptoCurrency currencyForWalletType');
|
throw Exception('Unexpected wallet type: ${type.toString()} for CryptoCurrency currencyForWalletType');
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@ const walletTypes = [
|
||||||
WalletType.litecoin,
|
WalletType.litecoin,
|
||||||
WalletType.haven,
|
WalletType.haven,
|
||||||
WalletType.ethereum,
|
WalletType.ethereum,
|
||||||
|
WalletType.bitcoinCash,
|
||||||
];
|
];
|
||||||
|
|
||||||
@HiveType(typeId: WALLET_TYPE_TYPE_ID)
|
@HiveType(typeId: WALLET_TYPE_TYPE_ID)
|
||||||
|
@ -31,6 +32,9 @@ enum WalletType {
|
||||||
|
|
||||||
@HiveField(5)
|
@HiveField(5)
|
||||||
ethereum,
|
ethereum,
|
||||||
|
|
||||||
|
@HiveField(6)
|
||||||
|
bitcoinCash,
|
||||||
}
|
}
|
||||||
|
|
||||||
int serializeToInt(WalletType type) {
|
int serializeToInt(WalletType type) {
|
||||||
|
@ -45,6 +49,8 @@ int serializeToInt(WalletType type) {
|
||||||
return 3;
|
return 3;
|
||||||
case WalletType.ethereum:
|
case WalletType.ethereum:
|
||||||
return 4;
|
return 4;
|
||||||
|
case WalletType.bitcoinCash:
|
||||||
|
return 5;
|
||||||
default:
|
default:
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -62,6 +68,8 @@ WalletType deserializeFromInt(int raw) {
|
||||||
return WalletType.haven;
|
return WalletType.haven;
|
||||||
case 4:
|
case 4:
|
||||||
return WalletType.ethereum;
|
return WalletType.ethereum;
|
||||||
|
case 4:
|
||||||
|
return WalletType.bitcoinCash;
|
||||||
default:
|
default:
|
||||||
throw Exception('Unexpected token: $raw for WalletType deserializeFromInt');
|
throw Exception('Unexpected token: $raw for WalletType deserializeFromInt');
|
||||||
}
|
}
|
||||||
|
@ -79,6 +87,8 @@ String walletTypeToString(WalletType type) {
|
||||||
return 'Haven';
|
return 'Haven';
|
||||||
case WalletType.ethereum:
|
case WalletType.ethereum:
|
||||||
return 'Ethereum';
|
return 'Ethereum';
|
||||||
|
case WalletType.bitcoinCash:
|
||||||
|
return 'Bitcoin Cash';
|
||||||
default:
|
default:
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
@ -96,6 +106,8 @@ String walletTypeToDisplayName(WalletType type) {
|
||||||
return 'Haven (XHV)';
|
return 'Haven (XHV)';
|
||||||
case WalletType.ethereum:
|
case WalletType.ethereum:
|
||||||
return 'Ethereum (ETH)';
|
return 'Ethereum (ETH)';
|
||||||
|
case WalletType.bitcoinCash:
|
||||||
|
return 'Bitcoin Cash (BCH)';
|
||||||
default:
|
default:
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
@ -113,6 +125,8 @@ CryptoCurrency walletTypeToCryptoCurrency(WalletType type) {
|
||||||
return CryptoCurrency.xhv;
|
return CryptoCurrency.xhv;
|
||||||
case WalletType.ethereum:
|
case WalletType.ethereum:
|
||||||
return CryptoCurrency.eth;
|
return CryptoCurrency.eth;
|
||||||
|
case WalletType.bitcoinCash:
|
||||||
|
return CryptoCurrency.bch;
|
||||||
default:
|
default:
|
||||||
throw Exception('Unexpected wallet type: ${type.toString()} for CryptoCurrency walletTypeToCryptoCurrency');
|
throw Exception('Unexpected wallet type: ${type.toString()} for CryptoCurrency walletTypeToCryptoCurrency');
|
||||||
}
|
}
|
||||||
|
|
168
lib/bitcoin_cash/cw_bitcoin_cash.dart
Normal file
168
lib/bitcoin_cash/cw_bitcoin_cash.dart
Normal file
|
@ -0,0 +1,168 @@
|
||||||
|
part of 'bitcoin_cash.dart';
|
||||||
|
|
||||||
|
class CWBitcoinCash extends BitcoinCash {
|
||||||
|
@override
|
||||||
|
String getMnemonic(int? strength) => Mnemonic.generate();
|
||||||
|
|
||||||
|
@override
|
||||||
|
Uint8List getSeedFromMnemonic(String seed) => Mnemonic.toSeed(seed);
|
||||||
|
|
||||||
|
@override
|
||||||
|
WalletService createBitcoinCashWalletService(
|
||||||
|
Box<WalletInfo> walletInfoSource, Box<UnspentCoinsInfo> unspentCoinSource) {
|
||||||
|
return BitcoinCashWalletService(walletInfoSource, unspentCoinSource);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
WalletCredentials createBitcoinCashNewWalletCredentials({
|
||||||
|
required String name,
|
||||||
|
WalletInfo? walletInfo,
|
||||||
|
}) =>
|
||||||
|
BitcoinCashNewWalletCredentials(name: name, walletInfo: walletInfo);
|
||||||
|
|
||||||
|
// @override
|
||||||
|
// TransactionPriority getMediumTransactionPriority() => BitcoinTransactionPriority.medium;
|
||||||
|
//
|
||||||
|
// @override
|
||||||
|
// WalletCredentials createBitcoinRestoreWalletFromSeedCredentials({
|
||||||
|
// required String name,
|
||||||
|
// required String mnemonic,
|
||||||
|
// required String password})
|
||||||
|
// => BitcoinRestoreWalletFromSeedCredentials(name: name, mnemonic: mnemonic, password: password);
|
||||||
|
//
|
||||||
|
// @override
|
||||||
|
// WalletCredentials createBitcoinRestoreWalletFromWIFCredentials({
|
||||||
|
// required String name,
|
||||||
|
// required String password,
|
||||||
|
// required String wif,
|
||||||
|
// WalletInfo? walletInfo})
|
||||||
|
// => BitcoinRestoreWalletFromWIFCredentials(name: name, password: password, wif: wif, walletInfo: walletInfo);
|
||||||
|
//
|
||||||
|
// @override
|
||||||
|
// WalletCredentials createBitcoinNewWalletCredentials({
|
||||||
|
// required String name,
|
||||||
|
// WalletInfo? walletInfo})
|
||||||
|
// => BitcoinNewWalletCredentials(name: name, walletInfo: walletInfo);
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// @override
|
||||||
|
// Map<String, String> getWalletKeys(Object wallet) {
|
||||||
|
// final bitcoinWallet = wallet as ElectrumWallet;
|
||||||
|
// final keys = bitcoinWallet.keys;
|
||||||
|
//
|
||||||
|
// return <String, String>{
|
||||||
|
// 'wif': keys.wif,
|
||||||
|
// 'privateKey': keys.privateKey,
|
||||||
|
// 'publicKey': keys.publicKey
|
||||||
|
// };
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @override
|
||||||
|
// List<TransactionPriority> getTransactionPriorities()
|
||||||
|
// => BitcoinTransactionPriority.all;
|
||||||
|
//
|
||||||
|
// List<TransactionPriority> getLitecoinTransactionPriorities()
|
||||||
|
// => LitecoinTransactionPriority.all;
|
||||||
|
//
|
||||||
|
// @override
|
||||||
|
// TransactionPriority deserializeBitcoinTransactionPriority(int raw)
|
||||||
|
// => BitcoinTransactionPriority.deserialize(raw: raw);
|
||||||
|
//
|
||||||
|
// @override
|
||||||
|
// TransactionPriority deserializeLitecoinTransactionPriority(int raw)
|
||||||
|
// => LitecoinTransactionPriority.deserialize(raw: raw);
|
||||||
|
//
|
||||||
|
// @override
|
||||||
|
// int getFeeRate(Object wallet, TransactionPriority priority) {
|
||||||
|
// final bitcoinWallet = wallet as ElectrumWallet;
|
||||||
|
// return bitcoinWallet.feeRate(priority);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @override
|
||||||
|
// Future<void> generateNewAddress(Object wallet) async {
|
||||||
|
// final bitcoinWallet = wallet as ElectrumWallet;
|
||||||
|
// await bitcoinWallet.walletAddresses.generateNewAddress();
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @override
|
||||||
|
// Object createBitcoinTransactionCredentials(List<Output> outputs, {required TransactionPriority priority, int? feeRate})
|
||||||
|
// => BitcoinTransactionCredentials(
|
||||||
|
// outputs.map((out) => OutputInfo(
|
||||||
|
// fiatAmount: out.fiatAmount,
|
||||||
|
// cryptoAmount: out.cryptoAmount,
|
||||||
|
// address: out.address,
|
||||||
|
// note: out.note,
|
||||||
|
// sendAll: out.sendAll,
|
||||||
|
// extractedAddress: out.extractedAddress,
|
||||||
|
// isParsedAddress: out.isParsedAddress,
|
||||||
|
// formattedCryptoAmount: out.formattedCryptoAmount))
|
||||||
|
// .toList(),
|
||||||
|
// priority: priority as BitcoinTransactionPriority,
|
||||||
|
// feeRate: feeRate);
|
||||||
|
//
|
||||||
|
// @override
|
||||||
|
// Object createBitcoinTransactionCredentialsRaw(List<OutputInfo> outputs, {TransactionPriority? priority, required int feeRate})
|
||||||
|
// => BitcoinTransactionCredentials(
|
||||||
|
// outputs,
|
||||||
|
// priority: priority != null ? priority as BitcoinTransactionPriority : null,
|
||||||
|
// feeRate: feeRate);
|
||||||
|
//
|
||||||
|
// @override
|
||||||
|
// List<String> getAddresses(Object wallet) {
|
||||||
|
// final bitcoinWallet = wallet as ElectrumWallet;
|
||||||
|
// return bitcoinWallet.walletAddresses.addresses
|
||||||
|
// .map((BitcoinAddressRecord addr) => addr.address)
|
||||||
|
// .toList();
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @override
|
||||||
|
// String getAddress(Object wallet) {
|
||||||
|
// final bitcoinWallet = wallet as ElectrumWallet;
|
||||||
|
// return bitcoinWallet.walletAddresses.address;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @override
|
||||||
|
// String formatterBitcoinAmountToString({required int amount})
|
||||||
|
// => bitcoinAmountToString(amount: amount);
|
||||||
|
//
|
||||||
|
// @override
|
||||||
|
// double formatterBitcoinAmountToDouble({required int amount})
|
||||||
|
// => bitcoinAmountToDouble(amount: amount);
|
||||||
|
//
|
||||||
|
// @override
|
||||||
|
// int formatterStringDoubleToBitcoinAmount(String amount)
|
||||||
|
// => stringDoubleToBitcoinAmount(amount);
|
||||||
|
//
|
||||||
|
// @override
|
||||||
|
// String bitcoinTransactionPriorityWithLabel(TransactionPriority priority, int rate)
|
||||||
|
// => (priority as BitcoinTransactionPriority).labelWithRate(rate);
|
||||||
|
//
|
||||||
|
// void updateUnspents(Object wallet) async {
|
||||||
|
// final bitcoinWallet = wallet as ElectrumWallet;
|
||||||
|
// await bitcoinWallet.updateUnspent();
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// WalletService createBitcoinWalletService(Box<WalletInfo> walletInfoSource, Box<UnspentCoinsInfo> unspentCoinSource) {
|
||||||
|
// return BitcoinWalletService(walletInfoSource, unspentCoinSource);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// WalletService createLitecoinWalletService(Box<WalletInfo> walletInfoSource, Box<UnspentCoinsInfo> unspentCoinSource) {
|
||||||
|
// return LitecoinWalletService(walletInfoSource, unspentCoinSource);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @override
|
||||||
|
// TransactionPriority getBitcoinTransactionPriorityMedium()
|
||||||
|
// => BitcoinTransactionPriority.medium;
|
||||||
|
//
|
||||||
|
// @override
|
||||||
|
// TransactionPriority getLitecoinTransactionPriorityMedium()
|
||||||
|
// => LitecoinTransactionPriority.medium;
|
||||||
|
//
|
||||||
|
// @override
|
||||||
|
// TransactionPriority getBitcoinTransactionPrioritySlow()
|
||||||
|
// => BitcoinTransactionPriority.slow;
|
||||||
|
//
|
||||||
|
// @override
|
||||||
|
// TransactionPriority getLitecoinTransactionPrioritySlow()
|
||||||
|
// => LitecoinTransactionPriority.slow;
|
||||||
|
}
|
|
@ -3,4 +3,5 @@ cd cw_monero && flutter pub get && flutter packages pub run build_runner build -
|
||||||
cd cw_bitcoin && flutter pub get && flutter packages pub run build_runner build --delete-conflicting-outputs && cd ..
|
cd cw_bitcoin && flutter pub get && flutter packages pub run build_runner build --delete-conflicting-outputs && cd ..
|
||||||
cd cw_haven && flutter pub get && flutter packages pub run build_runner build --delete-conflicting-outputs && cd ..
|
cd cw_haven && flutter pub get && flutter packages pub run build_runner build --delete-conflicting-outputs && cd ..
|
||||||
cd cw_ethereum && flutter pub get && flutter packages pub run build_runner build --delete-conflicting-outputs && cd ..
|
cd cw_ethereum && flutter pub get && flutter packages pub run build_runner build --delete-conflicting-outputs && cd ..
|
||||||
|
cd cw_bitcoin_cash && flutter pub get && flutter packages pub run build_runner build --delete-conflicting-outputs && cd ..
|
||||||
flutter packages pub run build_runner build --delete-conflicting-outputs
|
flutter packages pub run build_runner build --delete-conflicting-outputs
|
|
@ -10,7 +10,7 @@ case $APP_ANDROID_TYPE in
|
||||||
CONFIG_ARGS="--monero"
|
CONFIG_ARGS="--monero"
|
||||||
;;
|
;;
|
||||||
$CAKEWALLET)
|
$CAKEWALLET)
|
||||||
CONFIG_ARGS="--monero --bitcoin --haven --ethereum"
|
CONFIG_ARGS="--monero --bitcoin --haven --ethereum --bitcoinCash"
|
||||||
;;
|
;;
|
||||||
$HAVEN)
|
$HAVEN)
|
||||||
CONFIG_ARGS="--haven"
|
CONFIG_ARGS="--haven"
|
||||||
|
|
|
@ -23,9 +23,11 @@ case $APP_IOS_TYPE in
|
||||||
CONFIG_ARGS="--monero"
|
CONFIG_ARGS="--monero"
|
||||||
;;
|
;;
|
||||||
$CAKEWALLET)
|
$CAKEWALLET)
|
||||||
CONFIG_ARGS="--monero --bitcoin --haven --ethereum"
|
CONFIG_ARGS="--monero --bitcoin --haven --ethereum --bitcoinCash"
|
||||||
;;
|
;;
|
||||||
$HAVEN)
|
$HAVEN)
|
||||||
|
|
||||||
|
|
||||||
CONFIG_ARGS="--haven"
|
CONFIG_ARGS="--haven"
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
|
@ -4,6 +4,7 @@ const bitcoinOutputPath = 'lib/bitcoin/bitcoin.dart';
|
||||||
const moneroOutputPath = 'lib/monero/monero.dart';
|
const moneroOutputPath = 'lib/monero/monero.dart';
|
||||||
const havenOutputPath = 'lib/haven/haven.dart';
|
const havenOutputPath = 'lib/haven/haven.dart';
|
||||||
const ethereumOutputPath = 'lib/ethereum/ethereum.dart';
|
const ethereumOutputPath = 'lib/ethereum/ethereum.dart';
|
||||||
|
const bitcoinCashOutputPath = 'lib/bitcoin_cash/bitcoin_cash.dart';
|
||||||
const walletTypesPath = 'lib/wallet_types.g.dart';
|
const walletTypesPath = 'lib/wallet_types.g.dart';
|
||||||
const pubspecDefaultPath = 'pubspec_default.yaml';
|
const pubspecDefaultPath = 'pubspec_default.yaml';
|
||||||
const pubspecOutputPath = 'pubspec.yaml';
|
const pubspecOutputPath = 'pubspec.yaml';
|
||||||
|
@ -14,12 +15,14 @@ Future<void> main(List<String> args) async {
|
||||||
final hasMonero = args.contains('${prefix}monero');
|
final hasMonero = args.contains('${prefix}monero');
|
||||||
final hasHaven = args.contains('${prefix}haven');
|
final hasHaven = args.contains('${prefix}haven');
|
||||||
final hasEthereum = args.contains('${prefix}ethereum');
|
final hasEthereum = args.contains('${prefix}ethereum');
|
||||||
|
final hasBitcoinCash = args.contains('${prefix}bitcoinCash');
|
||||||
await generateBitcoin(hasBitcoin);
|
await generateBitcoin(hasBitcoin);
|
||||||
await generateMonero(hasMonero);
|
await generateMonero(hasMonero);
|
||||||
await generateHaven(hasHaven);
|
await generateHaven(hasHaven);
|
||||||
await generateEthereum(hasEthereum);
|
await generateEthereum(hasEthereum);
|
||||||
await generatePubspec(hasMonero: hasMonero, hasBitcoin: hasBitcoin, hasHaven: hasHaven, hasEthereum: hasEthereum);
|
await generateBitcoinCash(hasBitcoinCash);
|
||||||
await generateWalletTypes(hasMonero: hasMonero, hasBitcoin: hasBitcoin, hasHaven: hasHaven, hasEthereum: hasEthereum);
|
await generatePubspec(hasMonero: hasMonero, hasBitcoin: hasBitcoin, hasHaven: hasHaven, hasEthereum: hasEthereum, hasBitcoinCash: hasBitcoinCash);
|
||||||
|
await generateWalletTypes(hasMonero: hasMonero, hasBitcoin: hasBitcoin, hasHaven: hasHaven, hasEthereum: hasEthereum, hasBitcoinCash: hasBitcoinCash);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> generateBitcoin(bool hasImplementation) async {
|
Future<void> generateBitcoin(bool hasImplementation) async {
|
||||||
|
@ -555,7 +558,49 @@ abstract class Ethereum {
|
||||||
await outputFile.writeAsString(output);
|
await outputFile.writeAsString(output);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> generatePubspec({required bool hasMonero, required bool hasBitcoin, required bool hasHaven, required bool hasEthereum}) async {
|
Future<void> generateBitcoinCash(bool hasImplementation) async {
|
||||||
|
|
||||||
|
final outputFile = File(bitcoinCashOutputPath);
|
||||||
|
const bitcoinCashCommonHeaders = """
|
||||||
|
import 'dart:typed_data';
|
||||||
|
|
||||||
|
import 'package:cw_core/unspent_coins_info.dart';
|
||||||
|
import 'package:cw_core/wallet_credentials.dart';
|
||||||
|
import 'package:cw_core/wallet_info.dart';
|
||||||
|
import 'package:cw_core/wallet_service.dart';
|
||||||
|
import 'package:hive/hive.dart';
|
||||||
|
""";
|
||||||
|
const bitcoinCashCWHeaders = """
|
||||||
|
import 'package:cw_bitcoin_cash/cw_bitcoin_cash.dart';
|
||||||
|
""";
|
||||||
|
const bitcoinCashCwPart = "part 'cw_bitcoin_cash.dart';";
|
||||||
|
const bitcoinCashContent = """
|
||||||
|
abstract class BitcoinCash {
|
||||||
|
String getMnemonic(int? strength);
|
||||||
|
Uint8List getSeedFromMnemonic(String seed);
|
||||||
|
WalletService createBitcoinCashWalletService(Box<WalletInfo> walletInfoSource, Box<UnspentCoinsInfo> unspentCoinSource);
|
||||||
|
WalletCredentials createBitcoinCashNewWalletCredentials({required String name, WalletInfo? walletInfo});
|
||||||
|
}
|
||||||
|
""";
|
||||||
|
|
||||||
|
const bitcoinCashEmptyDefinition = 'BitcoinCash? bitcoinCash;\n';
|
||||||
|
const bitcoinCashCWDefinition = 'BitcoinCash? bitcoinCash = CWBitcoinCash();\n';
|
||||||
|
|
||||||
|
final output = '$bitcoinCashCommonHeaders\n'
|
||||||
|
+ (hasImplementation ? '$bitcoinCashCWHeaders\n' : '\n')
|
||||||
|
+ (hasImplementation ? '$bitcoinCashCwPart\n\n' : '\n')
|
||||||
|
+ (hasImplementation ? bitcoinCashCWDefinition : bitcoinCashEmptyDefinition)
|
||||||
|
+ '\n'
|
||||||
|
+ bitcoinCashContent;
|
||||||
|
|
||||||
|
if (outputFile.existsSync()) {
|
||||||
|
await outputFile.delete();
|
||||||
|
}
|
||||||
|
|
||||||
|
await outputFile.writeAsString(output);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> generatePubspec({required bool hasMonero, required bool hasBitcoin, required bool hasHaven, required bool hasEthereum, required bool hasBitcoinCash}) async {
|
||||||
const cwCore = """
|
const cwCore = """
|
||||||
cw_core:
|
cw_core:
|
||||||
path: ./cw_core
|
path: ./cw_core
|
||||||
|
@ -580,6 +625,10 @@ Future<void> generatePubspec({required bool hasMonero, required bool hasBitcoin,
|
||||||
cw_ethereum:
|
cw_ethereum:
|
||||||
path: ./cw_ethereum
|
path: ./cw_ethereum
|
||||||
""";
|
""";
|
||||||
|
const cwBitcoinCash = """
|
||||||
|
cw_bitcoin_cash:
|
||||||
|
path: ./cw_bitcoin_cash
|
||||||
|
""";
|
||||||
final inputFile = File(pubspecOutputPath);
|
final inputFile = File(pubspecOutputPath);
|
||||||
final inputText = await inputFile.readAsString();
|
final inputText = await inputFile.readAsString();
|
||||||
final inputLines = inputText.split('\n');
|
final inputLines = inputText.split('\n');
|
||||||
|
@ -604,6 +653,10 @@ Future<void> generatePubspec({required bool hasMonero, required bool hasBitcoin,
|
||||||
output += '\n$cwEthereum';
|
output += '\n$cwEthereum';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (hasBitcoinCash) {
|
||||||
|
output += '\n$cwBitcoinCash';
|
||||||
|
}
|
||||||
|
|
||||||
final outputLines = output.split('\n');
|
final outputLines = output.split('\n');
|
||||||
inputLines.insertAll(dependenciesIndex + 1, outputLines);
|
inputLines.insertAll(dependenciesIndex + 1, outputLines);
|
||||||
final outputContent = inputLines.join('\n');
|
final outputContent = inputLines.join('\n');
|
||||||
|
@ -616,7 +669,7 @@ Future<void> generatePubspec({required bool hasMonero, required bool hasBitcoin,
|
||||||
await outputFile.writeAsString(outputContent);
|
await outputFile.writeAsString(outputContent);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> generateWalletTypes({required bool hasMonero, required bool hasBitcoin, required bool hasHaven, required bool hasEthereum}) async {
|
Future<void> generateWalletTypes({required bool hasMonero, required bool hasBitcoin, required bool hasHaven, required bool hasEthereum, required bool hasBitcoinCash}) async {
|
||||||
final walletTypesFile = File(walletTypesPath);
|
final walletTypesFile = File(walletTypesPath);
|
||||||
|
|
||||||
if (walletTypesFile.existsSync()) {
|
if (walletTypesFile.existsSync()) {
|
||||||
|
@ -643,6 +696,10 @@ Future<void> generateWalletTypes({required bool hasMonero, required bool hasBitc
|
||||||
outputContent += '\tWalletType.litecoin,\n';
|
outputContent += '\tWalletType.litecoin,\n';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (hasBitcoinCash) {
|
||||||
|
outputContent += '\tWalletType.bitcoinCash,\n';
|
||||||
|
}
|
||||||
|
|
||||||
if (hasHaven) {
|
if (hasHaven) {
|
||||||
outputContent += '\tWalletType.haven,\n';
|
outputContent += '\tWalletType.haven,\n';
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue