initial commit

This commit is contained in:
Serhii 2023-08-13 19:17:33 +03:00
parent f4fad4d94d
commit ec1d565658
42 changed files with 993 additions and 6 deletions

View file

@ -93,6 +93,7 @@ jobs:
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_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
- name: Add secrets

1
.gitignore vendored
View file

@ -124,6 +124,7 @@ lib/bitcoin/bitcoin.dart
lib/monero/monero.dart
lib/haven/haven.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_120.png

30
cw_bitcoin_cash/.gitignore vendored Normal file
View 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
View 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

View file

@ -0,0 +1,3 @@
## 0.0.1
* TODO: Describe initial release.

1
cw_bitcoin_cash/LICENSE Normal file
View file

@ -0,0 +1 @@
TODO: Add your license here.

39
cw_bitcoin_cash/README.md Normal file
View 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.

View 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

View 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;
}

View 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();
}

View 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';

View file

@ -0,0 +1 @@
class BitcoinCashClient {}

View file

@ -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');
}

View file

@ -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);
}

View 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;
}
}

View file

@ -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');
}
}

View 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);
}
}

View 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!;
}

View file

@ -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;
}

View 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;
}
}

View file

@ -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.';
}

View file

@ -0,0 +1 @@
export 'bitcoin_cash_mnemonic_is_incorrect_exception.dart';

View 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);
}

View file

@ -0,0 +1 @@
C:/Users/borod/AppData/Local/Pub/Cache/hosted/pub.dev/path_provider_linux-2.2.0/

View file

@ -0,0 +1,11 @@
//
// Generated file. Do not edit.
//
// clang-format off
#include "generated_plugin_registrant.h"
void fl_register_plugins(FlPluginRegistry* registry) {
}

View 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_

View 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)

View file

@ -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"))
}

View file

@ -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

View file

@ -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"

View 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
#

View 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);
});
}

View file

@ -0,0 +1,11 @@
//
// Generated file. Do not edit.
//
// clang-format off
#include "generated_plugin_registrant.h"
void RegisterPlugins(flutter::PluginRegistry* registry) {
}

View file

@ -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_

View 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)

View file

@ -13,6 +13,8 @@ CryptoCurrency currencyForWalletType(WalletType type) {
return CryptoCurrency.xhv;
case WalletType.ethereum:
return CryptoCurrency.eth;
case WalletType.bitcoinCash:
return CryptoCurrency.bch;
default:
throw Exception('Unexpected wallet type: ${type.toString()} for CryptoCurrency currencyForWalletType');
}

View file

@ -10,6 +10,7 @@ const walletTypes = [
WalletType.litecoin,
WalletType.haven,
WalletType.ethereum,
WalletType.bitcoinCash,
];
@HiveType(typeId: WALLET_TYPE_TYPE_ID)
@ -31,6 +32,9 @@ enum WalletType {
@HiveField(5)
ethereum,
@HiveField(6)
bitcoinCash,
}
int serializeToInt(WalletType type) {
@ -45,6 +49,8 @@ int serializeToInt(WalletType type) {
return 3;
case WalletType.ethereum:
return 4;
case WalletType.bitcoinCash:
return 5;
default:
return -1;
}
@ -62,6 +68,8 @@ WalletType deserializeFromInt(int raw) {
return WalletType.haven;
case 4:
return WalletType.ethereum;
case 4:
return WalletType.bitcoinCash;
default:
throw Exception('Unexpected token: $raw for WalletType deserializeFromInt');
}
@ -79,6 +87,8 @@ String walletTypeToString(WalletType type) {
return 'Haven';
case WalletType.ethereum:
return 'Ethereum';
case WalletType.bitcoinCash:
return 'Bitcoin Cash';
default:
return '';
}
@ -96,6 +106,8 @@ String walletTypeToDisplayName(WalletType type) {
return 'Haven (XHV)';
case WalletType.ethereum:
return 'Ethereum (ETH)';
case WalletType.bitcoinCash:
return 'Bitcoin Cash (BCH)';
default:
return '';
}
@ -113,6 +125,8 @@ CryptoCurrency walletTypeToCryptoCurrency(WalletType type) {
return CryptoCurrency.xhv;
case WalletType.ethereum:
return CryptoCurrency.eth;
case WalletType.bitcoinCash:
return CryptoCurrency.bch;
default:
throw Exception('Unexpected wallet type: ${type.toString()} for CryptoCurrency walletTypeToCryptoCurrency');
}

View 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;
}

View file

@ -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_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_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

View file

@ -10,7 +10,7 @@ case $APP_ANDROID_TYPE in
CONFIG_ARGS="--monero"
;;
$CAKEWALLET)
CONFIG_ARGS="--monero --bitcoin --haven --ethereum"
CONFIG_ARGS="--monero --bitcoin --haven --ethereum --bitcoinCash"
;;
$HAVEN)
CONFIG_ARGS="--haven"

View file

@ -23,9 +23,11 @@ case $APP_IOS_TYPE in
CONFIG_ARGS="--monero"
;;
$CAKEWALLET)
CONFIG_ARGS="--monero --bitcoin --haven --ethereum"
CONFIG_ARGS="--monero --bitcoin --haven --ethereum --bitcoinCash"
;;
$HAVEN)
CONFIG_ARGS="--haven"
;;
esac

View file

@ -4,6 +4,7 @@ const bitcoinOutputPath = 'lib/bitcoin/bitcoin.dart';
const moneroOutputPath = 'lib/monero/monero.dart';
const havenOutputPath = 'lib/haven/haven.dart';
const ethereumOutputPath = 'lib/ethereum/ethereum.dart';
const bitcoinCashOutputPath = 'lib/bitcoin_cash/bitcoin_cash.dart';
const walletTypesPath = 'lib/wallet_types.g.dart';
const pubspecDefaultPath = 'pubspec_default.yaml';
const pubspecOutputPath = 'pubspec.yaml';
@ -14,12 +15,14 @@ Future<void> main(List<String> args) async {
final hasMonero = args.contains('${prefix}monero');
final hasHaven = args.contains('${prefix}haven');
final hasEthereum = args.contains('${prefix}ethereum');
final hasBitcoinCash = args.contains('${prefix}bitcoinCash');
await generateBitcoin(hasBitcoin);
await generateMonero(hasMonero);
await generateHaven(hasHaven);
await generateEthereum(hasEthereum);
await generatePubspec(hasMonero: hasMonero, hasBitcoin: hasBitcoin, hasHaven: hasHaven, hasEthereum: hasEthereum);
await generateWalletTypes(hasMonero: hasMonero, hasBitcoin: hasBitcoin, hasHaven: hasHaven, hasEthereum: hasEthereum);
await generateBitcoinCash(hasBitcoinCash);
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 {
@ -555,7 +558,49 @@ abstract class Ethereum {
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 = """
cw_core:
path: ./cw_core
@ -580,6 +625,10 @@ Future<void> generatePubspec({required bool hasMonero, required bool hasBitcoin,
cw_ethereum:
path: ./cw_ethereum
""";
const cwBitcoinCash = """
cw_bitcoin_cash:
path: ./cw_bitcoin_cash
""";
final inputFile = File(pubspecOutputPath);
final inputText = await inputFile.readAsString();
final inputLines = inputText.split('\n');
@ -604,6 +653,10 @@ Future<void> generatePubspec({required bool hasMonero, required bool hasBitcoin,
output += '\n$cwEthereum';
}
if (hasBitcoinCash) {
output += '\n$cwBitcoinCash';
}
final outputLines = output.split('\n');
inputLines.insertAll(dependenciesIndex + 1, outputLines);
final outputContent = inputLines.join('\n');
@ -616,7 +669,7 @@ Future<void> generatePubspec({required bool hasMonero, required bool hasBitcoin,
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);
if (walletTypesFile.existsSync()) {
@ -643,6 +696,10 @@ Future<void> generateWalletTypes({required bool hasMonero, required bool hasBitc
outputContent += '\tWalletType.litecoin,\n';
}
if (hasBitcoinCash) {
outputContent += '\tWalletType.bitcoinCash,\n';
}
if (hasHaven) {
outputContent += '\tWalletType.haven,\n';
}