mirror of
https://github.com/Such-Software/hash-wallet.git
synced 2026-10-17 05:41:29 +02:00
CW-1099-Add-Doge-coin-to-Cake-Wallet (#2396)
* add wallet create, restore and server integration * update transaction fee calculation * Updated tool/configure.dart * Add dogecoin support to app_config * minor fix [skip ci] * Update model_generator.sh * remove cw_bitcoin import from lib/ directory * update bitcoin base * update default node * add passphrase an QR restore option * add Dogecoin support for message signing * add Dogecoin support across wallet features * fix edit subaddress Updated the isElectrum getter to include WalletType.dogecoin, ensuring Dogecoin wallets are correctly identified as Electrum-compatible. * Update configure.dart * fix: address label not saved * remove unused derivationPath Co-authored-by: Omar Hatem <omarh.ismail1@gmail.com> * address review comments * fix generateInitialAddresses type * enable auto switching for Dogecoin nodes --------- Co-authored-by: Omar Hatem <omarh.ismail1@gmail.com>
This commit is contained in:
@@ -140,6 +140,7 @@ lib/tron/tron.dart
|
||||
lib/wownero/wownero.dart
|
||||
lib/zano/zano.dart
|
||||
lib/decred/decred.dart
|
||||
lib/dogecoin/dogecoin.dart
|
||||
|
||||
ios/Runner/Assets.xcassets/AppIcon.appiconset/AppIcon@2x.png
|
||||
ios/Runner/Assets.xcassets/AppIcon.appiconset/AppIcon@2x~ipad.png
|
||||
|
||||
@@ -103,6 +103,9 @@
|
||||
<data android:scheme="decred" />
|
||||
<data android:scheme="decred-wallet" />
|
||||
<data android:scheme="decred_wallet" />
|
||||
<data android:scheme="dogecoin" />
|
||||
<data android:scheme="dogecoin-wallet" />
|
||||
<data android:scheme="dogecoin_wallet" />
|
||||
</intent-filter>
|
||||
<!-- nano-gpt link scheme -->
|
||||
<intent-filter android:autoVerify="true">
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
-
|
||||
uri: dogecoin.stackwallet.com:50022
|
||||
is_default: true
|
||||
useSSL: true
|
||||
isEnabledForAutoSwitching: true
|
||||
-
|
||||
uri: doge.aftrek.org:50002
|
||||
useSSL: true
|
||||
isEnabledForAutoSwitching: true
|
||||
-
|
||||
uri: electrum1.cipig.net:20060
|
||||
useSSL: true
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
@echo off
|
||||
set cw_win_app_config=--monero --bitcoin --ethereum --polygon --nano --bitcoinCash --solana --tron
|
||||
set cw_win_app_config=--monero --bitcoin --ethereum --polygon --nano --bitcoinCash --solana --tron --dogecoin
|
||||
set cw_root=%cd%
|
||||
set cw_archive_name=Cake Wallet.zip
|
||||
set cw_archive_path=%cw_root%\%cw_archive_name%
|
||||
|
||||
@@ -130,6 +130,8 @@ abstract class ElectrumWalletBase
|
||||
as Bip32Slip10Secp256k1;
|
||||
case CryptoCurrency.bch:
|
||||
return bitcoinCashHDWallet(seedBytes);
|
||||
case CryptoCurrency.doge:
|
||||
return dogecoinHDWallet(seedBytes);
|
||||
default:
|
||||
throw Exception("Unsupported currency");
|
||||
}
|
||||
@@ -141,6 +143,9 @@ abstract class ElectrumWalletBase
|
||||
static Bip32Slip10Secp256k1 bitcoinCashHDWallet(Uint8List seedBytes) =>
|
||||
Bip32Slip10Secp256k1.fromSeed(seedBytes).derivePath("m/44'/145'/0'") as Bip32Slip10Secp256k1;
|
||||
|
||||
static Bip32Slip10Secp256k1 dogecoinHDWallet(Uint8List seedBytes) =>
|
||||
Bip32Slip10Secp256k1.fromSeed(seedBytes).derivePath("m/44'/3'/0'") as Bip32Slip10Secp256k1;
|
||||
|
||||
static int estimatedTransactionSize(int inputsCount, int outputsCounts) =>
|
||||
inputsCount * 68 + outputsCounts * 34 + 10;
|
||||
|
||||
@@ -629,9 +634,9 @@ abstract class ElectrumWalletBase
|
||||
}
|
||||
}
|
||||
|
||||
int get _dustAmount => 546;
|
||||
int get networkDustAmount => 546;
|
||||
|
||||
bool _isBelowDust(int amount) => amount <= _dustAmount && network != BitcoinNetwork.testnet;
|
||||
bool _isBelowDust(int amount) => amount <= networkDustAmount && network != BitcoinNetwork.testnet;
|
||||
|
||||
UtxoDetails _createUTXOS({
|
||||
required bool sendAll,
|
||||
@@ -1685,7 +1690,7 @@ abstract class ElectrumWalletBase
|
||||
var currentFee = allInputsAmount - totalOutAmount;
|
||||
|
||||
int remainingFee = (newFee - currentFee > 0) ? newFee - currentFee : newFee;
|
||||
return totalBalance - receiverAmount - remainingFee >= _dustAmount;
|
||||
return totalBalance - receiverAmount - remainingFee >= networkDustAmount;
|
||||
}
|
||||
|
||||
Future<PendingBitcoinTransaction> replaceByFee(String hash, int newFee) async {
|
||||
@@ -1773,10 +1778,10 @@ abstract class ElectrumWalletBase
|
||||
|
||||
if (isChange) {
|
||||
int outputAmount = output.value.toInt();
|
||||
if (outputAmount > _dustAmount) {
|
||||
int deduction = (outputAmount - _dustAmount >= remainingFee)
|
||||
if (outputAmount > networkDustAmount) {
|
||||
int deduction = (outputAmount - networkDustAmount >= remainingFee)
|
||||
? remainingFee
|
||||
: outputAmount - _dustAmount;
|
||||
: outputAmount - networkDustAmount;
|
||||
outputs[i] = BitcoinOutput(
|
||||
address: output.address, value: BigInt.from(outputAmount - deduction));
|
||||
remainingFee -= deduction;
|
||||
@@ -1845,10 +1850,10 @@ abstract class ElectrumWalletBase
|
||||
final output = outputs[i];
|
||||
int outputAmount = output.value.toInt();
|
||||
|
||||
if (outputAmount > _dustAmount) {
|
||||
int deduction = (outputAmount - _dustAmount >= remainingFee)
|
||||
if (outputAmount > networkDustAmount) {
|
||||
int deduction = (outputAmount - networkDustAmount >= remainingFee)
|
||||
? remainingFee
|
||||
: outputAmount - _dustAmount;
|
||||
: outputAmount - networkDustAmount;
|
||||
|
||||
outputs[i] = BitcoinOutput(
|
||||
address: output.address, value: BigInt.from(outputAmount - deduction));
|
||||
@@ -2051,6 +2056,9 @@ abstract class ElectrumWalletBase
|
||||
await Future.wait(LITECOIN_ADDRESS_TYPES
|
||||
.where((type) => type != SegwitAddresType.mweb)
|
||||
.map((type) => fetchTransactionsForAddressType(historiesWithDetails, type)));
|
||||
} else if (type == WalletType.dogecoin) {
|
||||
await Future.wait(DOGECOIN_ADDRESS_TYPES.map(
|
||||
(type) => fetchTransactionsForAddressType(historiesWithDetails, type)));
|
||||
}
|
||||
|
||||
transactionHistory.transactions.values.forEach((tx) async {
|
||||
|
||||
@@ -3,7 +3,6 @@ import 'dart:io' show Platform;
|
||||
import 'package:bitcoin_base/bitcoin_base.dart';
|
||||
import 'package:blockchain_utils/blockchain_utils.dart';
|
||||
import 'package:cw_bitcoin/bitcoin_address_record.dart';
|
||||
import 'package:cw_bitcoin/electrum_wallet.dart';
|
||||
import 'package:cw_core/unspent_coin_type.dart';
|
||||
import 'package:cw_core/utils/print_verbose.dart';
|
||||
import 'package:cw_bitcoin/bitcoin_unspent.dart';
|
||||
@@ -33,6 +32,10 @@ const List<BitcoinAddressType> BITCOIN_CASH_ADDRESS_TYPES = [
|
||||
P2pkhAddressType.p2pkh,
|
||||
];
|
||||
|
||||
const List<BitcoinAddressType> DOGECOIN_ADDRESS_TYPES = [
|
||||
P2pkhAddressType.p2pkh,
|
||||
];
|
||||
|
||||
abstract class ElectrumWalletAddressesBase extends WalletAddresses with Store {
|
||||
ElectrumWalletAddressesBase(
|
||||
WalletInfo walletInfo, {
|
||||
@@ -253,6 +256,8 @@ abstract class ElectrumWalletAddressesBase extends WalletAddresses with Store {
|
||||
if ((Platform.isAndroid || Platform.isIOS) && !isHardwareWallet) {
|
||||
await _generateInitialAddresses(type: SegwitAddresType.mweb);
|
||||
}
|
||||
} else if (walletInfo.type == WalletType.dogecoin) {
|
||||
await _generateInitialAddresses(type: P2pkhAddressType.p2pkh);
|
||||
} else if (walletInfo.type == WalletType.bitcoin) {
|
||||
await _generateInitialAddresses();
|
||||
if (!isHardwareWallet) {
|
||||
@@ -458,7 +463,7 @@ abstract class ElectrumWalletAddressesBase extends WalletAddresses with Store {
|
||||
}
|
||||
}
|
||||
|
||||
void addBitcoinCashAddressTypes() {
|
||||
void addP2PKHAddressTypes() {
|
||||
final lastP2pkh = _addresses.firstWhere(
|
||||
(addressRecord) => _isUnusedReceiveAddressByType(addressRecord, P2pkhAddressType.p2pkh));
|
||||
if (lastP2pkh.address != address) {
|
||||
@@ -487,7 +492,10 @@ abstract class ElectrumWalletAddressesBase extends WalletAddresses with Store {
|
||||
addLitecoinAddressTypes();
|
||||
break;
|
||||
case WalletType.bitcoinCash:
|
||||
addBitcoinCashAddressTypes();
|
||||
addP2PKHAddressTypes();
|
||||
break;
|
||||
case WalletType.dogecoin:
|
||||
addP2PKHAddressTypes();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
@@ -81,12 +81,15 @@ class PendingBitcoinTransaction with PendingTransaction {
|
||||
return "LTC";
|
||||
case WalletType.bitcoinCash:
|
||||
return "BCH";
|
||||
case WalletType.dogecoin:
|
||||
return "DOGE";
|
||||
default:
|
||||
return type.name;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
String get feeFormattedValue => bitcoinAmountToString(amount: fee);
|
||||
|
||||
@@ -104,8 +107,7 @@ class PendingBitcoinTransaction with PendingTransaction {
|
||||
return PendingChange(
|
||||
changeAddressOverride!, BtcUtils.fromSatoshi(change.amount));
|
||||
}
|
||||
return PendingChange(
|
||||
change.scriptPubKey.toAddress(), BtcUtils.fromSatoshi(change.amount));
|
||||
return PendingChange(change.scriptPubKey.toAddress(network: network), BtcUtils.fromSatoshi(change.amount));
|
||||
} catch (_) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -142,6 +142,7 @@ abstract class BitcoinCashWalletBase extends ElectrumWallet with Store {
|
||||
addr.address,
|
||||
index: addr.index,
|
||||
isHidden: addr.isHidden,
|
||||
name: addr.name,
|
||||
type: P2pkhAddressType.p2pkh,
|
||||
network: BitcoinCashNetwork.mainnet,
|
||||
);
|
||||
@@ -150,6 +151,7 @@ abstract class BitcoinCashWalletBase extends ElectrumWallet with Store {
|
||||
AddressUtils.getCashAddrFormat(addr.address),
|
||||
index: addr.index,
|
||||
isHidden: addr.isHidden,
|
||||
name: addr.name,
|
||||
type: P2pkhAddressType.p2pkh,
|
||||
network: BitcoinCashNetwork.mainnet,
|
||||
);
|
||||
|
||||
@@ -30,6 +30,7 @@ class AmountConverter {
|
||||
case CryptoCurrency.bch:
|
||||
case CryptoCurrency.ltc:
|
||||
case CryptoCurrency.dcr:
|
||||
case CryptoCurrency.doge:
|
||||
return _bitcoinAmountToString(amount);
|
||||
case CryptoCurrency.xhv:
|
||||
case CryptoCurrency.xag:
|
||||
|
||||
@@ -34,6 +34,8 @@ CryptoCurrency currencyForWalletType(WalletType type, {bool? isTestnet}) {
|
||||
return CryptoCurrency.zano;
|
||||
case WalletType.decred:
|
||||
return CryptoCurrency.dcr;
|
||||
case WalletType.dogecoin:
|
||||
return CryptoCurrency.doge;
|
||||
case WalletType.none:
|
||||
throw Exception(
|
||||
'Unexpected wallet type: ${type.toString()} for CryptoCurrency currencyForWalletType');
|
||||
|
||||
@@ -100,6 +100,7 @@ class Node extends HiveObject with Keyable {
|
||||
case WalletType.bitcoin:
|
||||
case WalletType.litecoin:
|
||||
case WalletType.bitcoinCash:
|
||||
case WalletType.dogecoin:
|
||||
return createUriFromElectrumAddress(uriRaw, path!);
|
||||
case WalletType.nano:
|
||||
case WalletType.banano:
|
||||
@@ -170,6 +171,7 @@ class Node extends HiveObject with Keyable {
|
||||
case WalletType.polygon:
|
||||
case WalletType.solana:
|
||||
case WalletType.tron:
|
||||
case WalletType.dogecoin:
|
||||
return requestElectrumServer();
|
||||
case WalletType.zano:
|
||||
return requestZanoNode();
|
||||
|
||||
@@ -18,6 +18,7 @@ const walletTypes = [
|
||||
WalletType.tron,
|
||||
WalletType.zano,
|
||||
WalletType.decred,
|
||||
WalletType.dogecoin,
|
||||
];
|
||||
|
||||
@HiveType(typeId: WALLET_TYPE_TYPE_ID)
|
||||
@@ -65,7 +66,10 @@ enum WalletType {
|
||||
zano,
|
||||
|
||||
@HiveField(14)
|
||||
decred
|
||||
decred,
|
||||
|
||||
@HiveField(15)
|
||||
dogecoin
|
||||
}
|
||||
|
||||
int serializeToInt(WalletType type) {
|
||||
@@ -98,6 +102,8 @@ int serializeToInt(WalletType type) {
|
||||
return 12;
|
||||
case WalletType.decred:
|
||||
return 13;
|
||||
case WalletType.dogecoin:
|
||||
return 14;
|
||||
case WalletType.none:
|
||||
return -1;
|
||||
}
|
||||
@@ -133,6 +139,8 @@ WalletType deserializeFromInt(int raw) {
|
||||
return WalletType.zano;
|
||||
case 13:
|
||||
return WalletType.decred;
|
||||
case 14:
|
||||
return WalletType.dogecoin;
|
||||
default:
|
||||
throw Exception(
|
||||
'Unexpected token: $raw for WalletType deserializeFromInt');
|
||||
@@ -169,6 +177,8 @@ String walletTypeToString(WalletType type) {
|
||||
return 'Zano';
|
||||
case WalletType.decred:
|
||||
return 'Decred';
|
||||
case WalletType.dogecoin:
|
||||
return 'Dogecoin';
|
||||
case WalletType.none:
|
||||
return '';
|
||||
}
|
||||
@@ -204,6 +214,8 @@ String walletTypeToDisplayName(WalletType type) {
|
||||
return 'Zano (ZANO)';
|
||||
case WalletType.decred:
|
||||
return 'Decred (DCR)';
|
||||
case WalletType.dogecoin:
|
||||
return 'Dogecoin (DOGE)';
|
||||
case WalletType.none:
|
||||
return '';
|
||||
}
|
||||
@@ -242,6 +254,8 @@ CryptoCurrency walletTypeToCryptoCurrency(WalletType type, {bool isTestnet = fal
|
||||
return CryptoCurrency.zano;
|
||||
case WalletType.decred:
|
||||
return CryptoCurrency.dcr;
|
||||
case WalletType.dogecoin:
|
||||
return CryptoCurrency.doge;
|
||||
case WalletType.none:
|
||||
throw Exception(
|
||||
'Unexpected wallet type: ${type.toString()} for CryptoCurrency walletTypeToCryptoCurrency');
|
||||
@@ -278,6 +292,8 @@ WalletType? cryptoCurrencyToWalletType(CryptoCurrency type) {
|
||||
return WalletType.zano;
|
||||
case CryptoCurrency.dcr:
|
||||
return WalletType.decred;
|
||||
case CryptoCurrency.doge:
|
||||
return WalletType.dogecoin;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
# 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/
|
||||
.flutter-plugins
|
||||
.flutter-plugins-dependencies
|
||||
build/
|
||||
@@ -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: "c23637390482d4cf9598c3ce3f2be31aa7332daf"
|
||||
channel: "stable"
|
||||
|
||||
project_type: package
|
||||
@@ -0,0 +1,3 @@
|
||||
## 0.0.1
|
||||
|
||||
* TODO: Describe initial release.
|
||||
@@ -0,0 +1 @@
|
||||
TODO: Add your license here.
|
||||
@@ -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/tools/pub/writing-package-pages).
|
||||
|
||||
For general information about developing packages, see the Dart guide for
|
||||
[creating packages](https://dart.dev/guides/libraries/create-packages)
|
||||
and the Flutter guide for
|
||||
[developing packages and plugins](https://flutter.dev/to/develop-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.
|
||||
@@ -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
|
||||
@@ -0,0 +1,6 @@
|
||||
export 'src/dogecoin_wallet.dart';
|
||||
export 'src/dogecoin_wallet_addresses.dart';
|
||||
export 'src/dogecoin_wallet_creation_credentials.dart';
|
||||
export 'src/dogecoin_wallet_service.dart';
|
||||
export 'src/dogecoin_transaction_priority.dart';
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
import 'package:cw_bitcoin/bitcoin_transaction_priority.dart';
|
||||
|
||||
class DogecoinTransactionPriority extends BitcoinTransactionPriority {
|
||||
const DogecoinTransactionPriority({required String title, required int raw})
|
||||
: super(title: title, raw: raw);
|
||||
|
||||
static const List<DogecoinTransactionPriority> all = [fast, medium, slow];
|
||||
static const DogecoinTransactionPriority slow =
|
||||
DogecoinTransactionPriority(title: 'Slow', raw: 0);
|
||||
static const DogecoinTransactionPriority medium =
|
||||
DogecoinTransactionPriority(title: 'Medium', raw: 1);
|
||||
static const DogecoinTransactionPriority fast =
|
||||
DogecoinTransactionPriority(title: 'Fast', raw: 2);
|
||||
|
||||
static DogecoinTransactionPriority deserialize({required int raw}) {
|
||||
switch (raw) {
|
||||
case 0:
|
||||
return slow;
|
||||
case 1:
|
||||
return medium;
|
||||
case 2:
|
||||
return fast;
|
||||
default:
|
||||
throw Exception('Unexpected token: $raw for DogecoinTransactionPriority deserialize');
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
String get units => 'koinu';
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
var label = '';
|
||||
|
||||
switch (this) {
|
||||
case DogecoinTransactionPriority.slow:
|
||||
label = 'Slow'; // S.current.transaction_priority_slow;
|
||||
break;
|
||||
case DogecoinTransactionPriority.medium:
|
||||
label = 'Medium'; // S.current.transaction_priority_medium;
|
||||
break;
|
||||
case DogecoinTransactionPriority.fast:
|
||||
label = 'Fast'; // S.current.transaction_priority_fast;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return label;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,164 @@
|
||||
import 'package:bitcoin_base/bitcoin_base.dart';
|
||||
import 'package:blockchain_utils/blockchain_utils.dart';
|
||||
import 'package:cw_bitcoin/bitcoin_address_record.dart';
|
||||
import 'package:cw_bitcoin/bitcoin_mnemonics_bip39.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/encryption_file_utils.dart';
|
||||
import 'package:cw_core/unspent_coins_info.dart';
|
||||
import 'package:cw_core/wallet_info.dart';
|
||||
import 'package:cw_core/wallet_keys_file.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
|
||||
import 'dogecoin_wallet_addresses.dart';
|
||||
|
||||
part 'dogecoin_wallet.g.dart';
|
||||
|
||||
class DogeCoinWallet = DogeCoinWalletBase with _$DogeCoinWallet;
|
||||
|
||||
abstract class DogeCoinWalletBase extends ElectrumWallet with Store {
|
||||
DogeCoinWalletBase({
|
||||
required String mnemonic,
|
||||
required String password,
|
||||
required WalletInfo walletInfo,
|
||||
required Box<UnspentCoinsInfo> unspentCoinsInfo,
|
||||
required Uint8List seedBytes,
|
||||
required EncryptionFileUtils encryptionFileUtils,
|
||||
String? passphrase,
|
||||
BitcoinAddressType? addressPageType,
|
||||
List<BitcoinAddressRecord>? initialAddresses,
|
||||
ElectrumBalance? initialBalance,
|
||||
Map<String, int>? initialRegularAddressIndex,
|
||||
Map<String, int>? initialChangeAddressIndex,
|
||||
}) : super(
|
||||
mnemonic: mnemonic,
|
||||
password: password,
|
||||
walletInfo: walletInfo,
|
||||
unspentCoinsInfo: unspentCoinsInfo,
|
||||
network: DogecoinNetwork.mainnet,
|
||||
initialAddresses: initialAddresses,
|
||||
initialBalance: initialBalance,
|
||||
seedBytes: seedBytes,
|
||||
currency: CryptoCurrency.doge,
|
||||
encryptionFileUtils: encryptionFileUtils,
|
||||
passphrase: passphrase) {
|
||||
walletAddresses = DogeCoinWalletAddresses(
|
||||
walletInfo,
|
||||
initialAddresses: initialAddresses,
|
||||
initialRegularAddressIndex: initialRegularAddressIndex,
|
||||
initialChangeAddressIndex: initialChangeAddressIndex,
|
||||
mainHd: hd,
|
||||
sideHd: accountHD.childKey(Bip32KeyIndex(1)),
|
||||
network: network,
|
||||
initialAddressPageType: addressPageType,
|
||||
isHardwareWallet: walletInfo.isHardwareWallet,
|
||||
);
|
||||
autorun((_) {
|
||||
this.walletAddresses.isEnabledAutoGenerateSubaddress = this.isEnabledAutoGenerateSubaddress;
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
int get networkDustAmount => 100000000; // 1 DOGE = 1e8 koinu
|
||||
|
||||
static Future<DogeCoinWallet> create(
|
||||
{required String mnemonic,
|
||||
required String password,
|
||||
required WalletInfo walletInfo,
|
||||
required Box<UnspentCoinsInfo> unspentCoinsInfo,
|
||||
required EncryptionFileUtils encryptionFileUtils,
|
||||
String? passphrase,
|
||||
String? addressPageType,
|
||||
List<BitcoinAddressRecord>? initialAddresses,
|
||||
ElectrumBalance? initialBalance,
|
||||
Map<String, int>? initialRegularAddressIndex,
|
||||
Map<String, int>? initialChangeAddressIndex}) async {
|
||||
return DogeCoinWallet(
|
||||
mnemonic: mnemonic,
|
||||
password: password,
|
||||
walletInfo: walletInfo,
|
||||
unspentCoinsInfo: unspentCoinsInfo,
|
||||
initialAddresses: initialAddresses,
|
||||
initialBalance: initialBalance,
|
||||
seedBytes: MnemonicBip39.toSeed(mnemonic, passphrase: passphrase),
|
||||
encryptionFileUtils: encryptionFileUtils,
|
||||
initialRegularAddressIndex: initialRegularAddressIndex,
|
||||
initialChangeAddressIndex: initialChangeAddressIndex,
|
||||
addressPageType: P2pkhAddressType.p2pkh,
|
||||
passphrase: passphrase,
|
||||
);
|
||||
}
|
||||
|
||||
static Future<DogeCoinWallet> open({
|
||||
required String name,
|
||||
required WalletInfo walletInfo,
|
||||
required Box<UnspentCoinsInfo> unspentCoinsInfo,
|
||||
required String password,
|
||||
required EncryptionFileUtils encryptionFileUtils,
|
||||
}) async {
|
||||
final hasKeysFile = await WalletKeysFile.hasKeysFile(name, walletInfo.type);
|
||||
|
||||
ElectrumWalletSnapshot? snp = null;
|
||||
|
||||
try {
|
||||
snp = await ElectrumWalletSnapshot.load(
|
||||
encryptionFileUtils,
|
||||
name,
|
||||
walletInfo.type,
|
||||
password,
|
||||
DogecoinNetwork.mainnet,
|
||||
);
|
||||
} catch (e) {
|
||||
if (!hasKeysFile) rethrow;
|
||||
}
|
||||
|
||||
final WalletKeysData keysData;
|
||||
// Migrate wallet from the old scheme to then new .keys file scheme
|
||||
if (!hasKeysFile) {
|
||||
keysData =
|
||||
WalletKeysData(mnemonic: snp!.mnemonic, xPub: snp.xpub, passphrase: snp.passphrase);
|
||||
} else {
|
||||
keysData = await WalletKeysFile.readKeysFile(
|
||||
name,
|
||||
walletInfo.type,
|
||||
password,
|
||||
encryptionFileUtils,
|
||||
);
|
||||
}
|
||||
|
||||
return DogeCoinWallet(
|
||||
mnemonic: keysData.mnemonic!,
|
||||
password: password,
|
||||
walletInfo: walletInfo,
|
||||
unspentCoinsInfo: unspentCoinsInfo,
|
||||
initialAddresses: snp?.addresses,
|
||||
initialBalance: snp?.balance,
|
||||
seedBytes: await MnemonicBip39.toSeed(keysData.mnemonic!, passphrase: keysData.passphrase),
|
||||
encryptionFileUtils: encryptionFileUtils,
|
||||
initialRegularAddressIndex: snp?.regularAddressIndex,
|
||||
initialChangeAddressIndex: snp?.changeAddressIndex,
|
||||
addressPageType: P2pkhAddressType.p2pkh,
|
||||
passphrase: keysData.passphrase,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<String> signMessage(String message, {String? address = null}) async {
|
||||
int? index;
|
||||
try {
|
||||
index = address != null
|
||||
? walletAddresses.allAddresses.firstWhere((element) => element.address == address).index
|
||||
: null;
|
||||
} catch (_) {}
|
||||
final HD = index == null ? hd : hd.childKey(Bip32KeyIndex(index));
|
||||
final priv = ECPrivate.fromWif(
|
||||
WifEncoder.encode(HD.privateKey.raw, netVer: network.wifNetVer),
|
||||
netVersion: network.wifNetVer,
|
||||
);
|
||||
return priv.signMessage(StringUtils.encode(message));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
import 'package:bitcoin_base/bitcoin_base.dart';
|
||||
import 'package:blockchain_utils/blockchain_utils.dart';
|
||||
import 'package:cw_bitcoin/electrum_wallet_addresses.dart';
|
||||
import 'package:cw_bitcoin/utils.dart';
|
||||
import 'package:cw_core/wallet_info.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
|
||||
part 'dogecoin_wallet_addresses.g.dart';
|
||||
|
||||
class DogeCoinWalletAddresses = DogeCoinWalletAddressesBase with _$DogeCoinWalletAddresses;
|
||||
|
||||
abstract class DogeCoinWalletAddressesBase extends ElectrumWalletAddresses with Store {
|
||||
DogeCoinWalletAddressesBase(WalletInfo walletInfo, {
|
||||
required super.mainHd,
|
||||
required super.sideHd,
|
||||
required super.network,
|
||||
required super.isHardwareWallet,
|
||||
super.initialAddresses,
|
||||
super.initialRegularAddressIndex,
|
||||
super.initialChangeAddressIndex,
|
||||
super.initialAddressPageType
|
||||
}) : super(walletInfo);
|
||||
|
||||
@override
|
||||
String getAddress({required int index,
|
||||
required Bip32Slip10Secp256k1 hd,
|
||||
BitcoinAddressType? addressType}) =>
|
||||
generateP2PKHAddress(hd: hd, index: index, network: network);
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
import 'package:cw_core/wallet_credentials.dart';
|
||||
import 'package:cw_core/wallet_info.dart';
|
||||
|
||||
class DogeCoinNewWalletCredentials extends WalletCredentials {
|
||||
DogeCoinNewWalletCredentials({
|
||||
required String name,
|
||||
WalletInfo? walletInfo,
|
||||
String? password,
|
||||
String? passphrase,
|
||||
this.mnemonic,
|
||||
}) : super(
|
||||
name: name,
|
||||
walletInfo: walletInfo,
|
||||
password: password,
|
||||
passphrase: passphrase,
|
||||
);
|
||||
final String? mnemonic;
|
||||
}
|
||||
|
||||
class DogeCoinRestoreWalletFromSeedCredentials extends WalletCredentials {
|
||||
DogeCoinRestoreWalletFromSeedCredentials({
|
||||
required String name,
|
||||
required String password,
|
||||
required this.mnemonic,
|
||||
WalletInfo? walletInfo,
|
||||
String? passphrase,
|
||||
}) : super(name: name, password: password, walletInfo: walletInfo, passphrase: passphrase);
|
||||
|
||||
final String mnemonic;
|
||||
}
|
||||
|
||||
class DogeCoinRestoreWalletFromWIFCredentials extends WalletCredentials {
|
||||
DogeCoinRestoreWalletFromWIFCredentials(
|
||||
{required String name, required String password, required this.wif, WalletInfo? walletInfo})
|
||||
: super(name: name, password: password, walletInfo: walletInfo);
|
||||
|
||||
final String wif;
|
||||
}
|
||||
@@ -0,0 +1,151 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:bip39/bip39.dart';
|
||||
import 'package:collection/collection.dart';
|
||||
import 'package:cw_bitcoin/bitcoin_mnemonics_bip39.dart';
|
||||
import 'package:cw_core/encryption_file_utils.dart';
|
||||
import 'package:cw_core/pathForWallet.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:cw_dogecoin/cw_dogecoin.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
|
||||
class DogeCoinWalletService extends WalletService<
|
||||
DogeCoinNewWalletCredentials,
|
||||
DogeCoinRestoreWalletFromSeedCredentials,
|
||||
DogeCoinRestoreWalletFromWIFCredentials,
|
||||
DogeCoinNewWalletCredentials> {
|
||||
DogeCoinWalletService(this.walletInfoSource, this.unspentCoinsInfoSource, this.isDirect);
|
||||
|
||||
final Box<WalletInfo> walletInfoSource;
|
||||
final Box<UnspentCoinsInfo> unspentCoinsInfoSource;
|
||||
final bool isDirect;
|
||||
|
||||
@override
|
||||
WalletType getType() => WalletType.dogecoin;
|
||||
|
||||
@override
|
||||
Future<bool> isWalletExit(String name) async =>
|
||||
File(await pathForWallet(name: name, type: getType())).existsSync();
|
||||
|
||||
@override
|
||||
Future<DogeCoinWallet> create(credentials, {bool? isTestnet}) async {
|
||||
final strength = credentials.seedPhraseLength == 24 ? 256 : 128;
|
||||
|
||||
final wallet = await DogeCoinWalletBase.create(
|
||||
mnemonic: credentials.mnemonic ?? MnemonicBip39.generate(strength: strength),
|
||||
password: credentials.password!,
|
||||
walletInfo: credentials.walletInfo!,
|
||||
unspentCoinsInfo: unspentCoinsInfoSource,
|
||||
encryptionFileUtils: encryptionFileUtilsFor(isDirect),
|
||||
passphrase: credentials.passphrase,
|
||||
);
|
||||
await wallet.save();
|
||||
await wallet.init();
|
||||
|
||||
return wallet;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<DogeCoinWallet> openWallet(String name, String password) async {
|
||||
final walletInfo = walletInfoSource.values
|
||||
.firstWhereOrNull((info) => info.id == WalletBase.idFor(name, getType()))!;
|
||||
|
||||
try {
|
||||
final wallet = await DogeCoinWalletBase.open(
|
||||
password: password,
|
||||
name: name,
|
||||
walletInfo: walletInfo,
|
||||
unspentCoinsInfo: unspentCoinsInfoSource,
|
||||
encryptionFileUtils: encryptionFileUtilsFor(isDirect),
|
||||
);
|
||||
await wallet.init();
|
||||
saveBackup(name);
|
||||
return wallet;
|
||||
} catch (_) {
|
||||
await restoreWalletFilesFromBackup(name);
|
||||
final wallet = await DogeCoinWalletBase.open(
|
||||
password: password,
|
||||
name: name,
|
||||
walletInfo: walletInfo,
|
||||
unspentCoinsInfo: unspentCoinsInfoSource,
|
||||
encryptionFileUtils: encryptionFileUtilsFor(isDirect),
|
||||
);
|
||||
await wallet.init();
|
||||
return wallet;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> remove(String wallet) async {
|
||||
File(await pathForWalletDir(name: wallet, type: getType())).delete(recursive: true);
|
||||
final walletInfo = walletInfoSource.values
|
||||
.firstWhereOrNull((info) => info.id == WalletBase.idFor(wallet, getType()))!;
|
||||
await walletInfoSource.delete(walletInfo.key);
|
||||
|
||||
final unspentCoinsToDelete = unspentCoinsInfoSource.values
|
||||
.where((unspentCoin) => unspentCoin.walletId == walletInfo.id)
|
||||
.toList();
|
||||
|
||||
final keysToDelete = unspentCoinsToDelete.map((unspentCoin) => unspentCoin.key).toList();
|
||||
|
||||
if (keysToDelete.isNotEmpty) {
|
||||
await unspentCoinsInfoSource.deleteAll(keysToDelete);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> rename(String currentName, String password, String newName) async {
|
||||
final currentWalletInfo = walletInfoSource.values
|
||||
.firstWhereOrNull((info) => info.id == WalletBase.idFor(currentName, getType()))!;
|
||||
final currentWallet = await DogeCoinWalletBase.open(
|
||||
password: password,
|
||||
name: currentName,
|
||||
walletInfo: currentWalletInfo,
|
||||
unspentCoinsInfo: unspentCoinsInfoSource,
|
||||
encryptionFileUtils: encryptionFileUtilsFor(isDirect));
|
||||
|
||||
await currentWallet.renameWalletFiles(newName);
|
||||
await saveBackup(newName);
|
||||
|
||||
final newWalletInfo = currentWalletInfo;
|
||||
newWalletInfo.id = WalletBase.idFor(newName, getType());
|
||||
newWalletInfo.name = newName;
|
||||
|
||||
await walletInfoSource.put(currentWalletInfo.key, newWalletInfo);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<DogeCoinWallet> restoreFromHardwareWallet(DogeCoinNewWalletCredentials credentials) {
|
||||
throw UnimplementedError(
|
||||
"Restoring a Bitcoin Cash wallet from a hardware wallet is not yet supported!");
|
||||
}
|
||||
|
||||
@override
|
||||
Future<DogeCoinWallet> restoreFromKeys(credentials, {bool? isTestnet}) {
|
||||
// TODO: implement restoreFromKeys
|
||||
throw UnimplementedError('restoreFromKeys() is not implemented');
|
||||
}
|
||||
|
||||
@override
|
||||
Future<DogeCoinWallet> restoreFromSeed(DogeCoinRestoreWalletFromSeedCredentials credentials,
|
||||
{bool? isTestnet}) async {
|
||||
if (!validateMnemonic(credentials.mnemonic)) {
|
||||
throw Exception('Invalid mnemonic: ${credentials.mnemonic}');
|
||||
}
|
||||
|
||||
final wallet = await DogeCoinWalletBase.create(
|
||||
password: credentials.password!,
|
||||
mnemonic: credentials.mnemonic,
|
||||
walletInfo: credentials.walletInfo!,
|
||||
unspentCoinsInfo: unspentCoinsInfoSource,
|
||||
encryptionFileUtils: encryptionFileUtilsFor(isDirect),
|
||||
passphrase: credentials.passphrase);
|
||||
await wallet.save();
|
||||
await wallet.init();
|
||||
return wallet;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
name: cw_dogecoin
|
||||
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.20.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
|
||||
|
||||
blockchain_utils:
|
||||
git:
|
||||
url: https://github.com/cake-tech/blockchain_utils
|
||||
ref: cake-update-v2
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
sdk: flutter
|
||||
build_runner: ^2.4.15
|
||||
mobx_codegen: ^2.0.7
|
||||
hive_generator: ^2.0.1
|
||||
|
||||
dependency_overrides:
|
||||
watcher: ^1.1.0
|
||||
bitcoin_base:
|
||||
git:
|
||||
url: https://github.com/cake-tech/bitcoin_base
|
||||
ref: cake-update-v10
|
||||
|
||||
|
||||
# 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:
|
||||
uses-material-design: true
|
||||
|
||||
# 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/to/asset-from-package
|
||||
#
|
||||
# An image asset can refer to one or more resolution-specific "variants", see
|
||||
# https://flutter.dev/to/resolution-aware-images
|
||||
|
||||
# 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
|
||||
#
|
||||
# For details regarding fonts in packages, see
|
||||
# https://flutter.dev/to/font-from-package
|
||||
@@ -0,0 +1,8 @@
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import 'package:cw_dogecoin/cw_dogecoin.dart';
|
||||
|
||||
void main() {
|
||||
test('adds one to input values', () {
|
||||
});
|
||||
}
|
||||
@@ -282,6 +282,25 @@
|
||||
<string>decred-wallet</string>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Viewer</string>
|
||||
<key>CFBundleURLName</key>
|
||||
<string>dogecoin</string>
|
||||
<key>CFBundleURLSchemes</key>
|
||||
<array>
|
||||
<string>dash</string>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Viewer</string>
|
||||
<key>CFBundleURLName</key>
|
||||
<string>dogecoin-wallet</string>
|
||||
<key>CFBundleURLSchemes</key>
|
||||
<array>
|
||||
<string>dogecoin-wallet</string>
|
||||
</array>
|
||||
</array>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>$(CURRENT_PROJECT_VERSION)</string>
|
||||
|
||||
@@ -184,6 +184,18 @@ class CWBitcoin extends Bitcoin {
|
||||
return estimatedTx.amount;
|
||||
}
|
||||
|
||||
|
||||
if (wallet.type == WalletType.dogecoin) {
|
||||
final dogeAddr =
|
||||
sk.getPublic().toP2pkhAddress();
|
||||
final estimatedTx = await electrumWallet.estimateSendAllTx(
|
||||
[BitcoinOutput(address: dogeAddr, value: BigInt.zero)],
|
||||
getFeeRate(wallet, priority as BitcoinTransactionPriority),
|
||||
coinTypeToSpendFrom: coinTypeToSpendFrom,
|
||||
);
|
||||
return estimatedTx.amount;
|
||||
}
|
||||
|
||||
final p2shAddr = sk.getPublic().toP2pkhInP2sh();
|
||||
final estimatedTx = await electrumWallet.estimateSendAllTx(
|
||||
[BitcoinOutput(address: p2shAddr, value: BigInt.zero)],
|
||||
|
||||
@@ -29,6 +29,8 @@ class SeedValidator extends Validator<MnemonicItem> {
|
||||
return getBitcoinWordList(language);
|
||||
case WalletType.litecoin:
|
||||
return getBitcoinWordList(language);
|
||||
case WalletType.dogecoin:
|
||||
return getBitcoinWordList(language);
|
||||
case WalletType.monero:
|
||||
return monero!.getMoneroWordList(language);
|
||||
case WalletType.ethereum:
|
||||
|
||||
@@ -82,6 +82,7 @@ class WalletCreationService {
|
||||
case WalletType.polygon:
|
||||
case WalletType.solana:
|
||||
case WalletType.tron:
|
||||
case WalletType.dogecoin:
|
||||
return true;
|
||||
case WalletType.monero:
|
||||
case WalletType.wownero:
|
||||
|
||||
@@ -274,6 +274,7 @@ import 'package:mobx/mobx.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'buy/kryptonim/kryptonim.dart';
|
||||
import 'buy/meld/meld_buy_provider.dart';
|
||||
import 'dogecoin/dogecoin.dart';
|
||||
import 'src/screens/buy/buy_sell_page.dart';
|
||||
import 'package:cake_wallet/view_model/dev/background_sync_logs_view_model.dart';
|
||||
import 'package:cake_wallet/src/screens/dev/background_sync_logs_page.dart';
|
||||
@@ -1147,6 +1148,9 @@ Future<void> setup({
|
||||
case WalletType.bitcoinCash:
|
||||
return bitcoinCash!.createBitcoinCashWalletService(_walletInfoSource,
|
||||
_unspentCoinsInfoSource, SettingsStoreBase.walletPasswordDirectInput);
|
||||
case WalletType.dogecoin:
|
||||
return dogecoin!.createDogeCoinWalletService(_walletInfoSource,
|
||||
_unspentCoinsInfoSource, SettingsStoreBase.walletPasswordDirectInput);
|
||||
case WalletType.nano:
|
||||
case WalletType.banano:
|
||||
return nano!.createNanoWalletService(_walletInfoSource, SettingsStoreBase.walletPasswordDirectInput);
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
part of 'dogecoin.dart';
|
||||
|
||||
|
||||
class CWDogeCoin extends DogeCoin {
|
||||
|
||||
@override
|
||||
WalletService createDogeCoinWalletService(
|
||||
Box<WalletInfo> walletInfoSource, Box<UnspentCoinsInfo> unspentCoinSource, bool isDirect) {
|
||||
return DogeCoinWalletService(walletInfoSource, unspentCoinSource, isDirect);
|
||||
}
|
||||
|
||||
@override
|
||||
WalletCredentials createDogeCoinNewWalletCredentials({
|
||||
required String name,
|
||||
WalletInfo? walletInfo,
|
||||
String? password,
|
||||
String? passphrase,
|
||||
String? mnemonic,
|
||||
}) =>
|
||||
DogeCoinNewWalletCredentials(
|
||||
name: name,
|
||||
walletInfo: walletInfo,
|
||||
password: password,
|
||||
passphrase: passphrase,
|
||||
mnemonic: mnemonic,
|
||||
);
|
||||
|
||||
@override
|
||||
WalletCredentials createDogeCoinRestoreWalletFromSeedCredentials({
|
||||
required String name,
|
||||
required String mnemonic,
|
||||
required String password,
|
||||
String? passphrase,
|
||||
}) =>
|
||||
DogeCoinRestoreWalletFromSeedCredentials(
|
||||
name: name, mnemonic: mnemonic, password: password, passphrase: passphrase);
|
||||
|
||||
@override
|
||||
TransactionPriority deserializeDogeCoinTransactionPriority(int raw) =>
|
||||
DogecoinTransactionPriority.deserialize(raw: raw);
|
||||
|
||||
@override
|
||||
TransactionPriority getDefaultTransactionPriority() => DogecoinTransactionPriority.medium;
|
||||
@override
|
||||
List<TransactionPriority> getTransactionPriorities() => DogecoinTransactionPriority.all;
|
||||
@override
|
||||
TransactionPriority getDogeCoinTransactionPrioritySlow() => DogecoinTransactionPriority.slow;
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
import 'package:cw_core/transaction_priority.dart';
|
||||
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';
|
||||
|
||||
import 'package:cw_dogecoin/cw_dogecoin.dart';
|
||||
|
||||
part 'cw_dogecoin.dart';
|
||||
|
||||
DogeCoin? dogecoin = CWDogeCoin();
|
||||
|
||||
abstract class DogeCoin {
|
||||
|
||||
WalletService createDogeCoinWalletService(
|
||||
Box<WalletInfo> walletInfoSource, Box<UnspentCoinsInfo> unspentCoinSource, bool isDirect);
|
||||
|
||||
WalletCredentials createDogeCoinNewWalletCredentials(
|
||||
{required String name, WalletInfo? walletInfo, String? password, String? passphrase, String? mnemonic});
|
||||
|
||||
WalletCredentials createDogeCoinRestoreWalletFromSeedCredentials(
|
||||
{required String name, required String mnemonic, required String password, String? passphrase});
|
||||
|
||||
TransactionPriority deserializeDogeCoinTransactionPriority(int raw);
|
||||
|
||||
TransactionPriority getDefaultTransactionPriority();
|
||||
|
||||
List<TransactionPriority> getTransactionPriorities();
|
||||
|
||||
TransactionPriority getDogeCoinTransactionPrioritySlow();
|
||||
}
|
||||
@@ -46,6 +46,7 @@ const wowneroDefaultNodeUri = 'node3.monerodevs.org:34568';
|
||||
const zanoDefaultNodeUri = 'zano.cakewallet.com:11211';
|
||||
const moneroWorldNodeUri = '.moneroworld.com';
|
||||
const decredDefaultUri = "default-spv-nodes";
|
||||
const dogecoinDefaultNodeUri = 'dogecoin.stackwallet.com:50022';
|
||||
|
||||
Future<void> defaultSettingsMigration(
|
||||
{required int version,
|
||||
@@ -514,6 +515,15 @@ Future<void> defaultSettingsMigration(
|
||||
case 50:
|
||||
migrateExistingNodesToUseAutoSwitching(nodes: nodes, powNodes: powNodes);
|
||||
break;
|
||||
case 51:
|
||||
await addWalletNodeList(nodes: nodes, type: WalletType.dogecoin);
|
||||
await _changeDefaultNode(
|
||||
nodes: nodes,
|
||||
sharedPreferences: sharedPreferences,
|
||||
type: WalletType.dogecoin,
|
||||
currentNodePreferenceKey: PreferencesKey.currentDogecoinNodeIdKey,
|
||||
);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -620,6 +630,8 @@ String _getDefaultNodeUri(WalletType type) {
|
||||
return zanoDefaultNodeUri;
|
||||
case WalletType.decred:
|
||||
return decredDefaultUri;
|
||||
case WalletType.dogecoin:
|
||||
return dogecoinDefaultNodeUri;
|
||||
case WalletType.banano:
|
||||
case WalletType.none:
|
||||
return '';
|
||||
@@ -1050,6 +1062,8 @@ Future<void> checkCurrentNodes(
|
||||
final currentDecredNodeId = sharedPreferences.getInt(PreferencesKey.currentDecredNodeIdKey);
|
||||
final currentBitcoinCashNodeId =
|
||||
sharedPreferences.getInt(PreferencesKey.currentBitcoinCashNodeIdKey);
|
||||
final currentDogecoinNodeId =
|
||||
sharedPreferences.getInt(PreferencesKey.currentDogecoinNodeIdKey);
|
||||
final currentSolanaNodeId = sharedPreferences.getInt(PreferencesKey.currentSolanaNodeIdKey);
|
||||
final currentTronNodeId = sharedPreferences.getInt(PreferencesKey.currentTronNodeIdKey);
|
||||
final currentWowneroNodeId = sharedPreferences.getInt(PreferencesKey.currentWowneroNodeIdKey);
|
||||
@@ -1074,6 +1088,8 @@ Future<void> checkCurrentNodes(
|
||||
powNodeSource.values.firstWhereOrNull((node) => node.key == currentNanoPowNodeId);
|
||||
final currentBitcoinCashNodeServer =
|
||||
nodeSource.values.firstWhereOrNull((node) => node.key == currentBitcoinCashNodeId);
|
||||
final currentDogecoinNodeServer =
|
||||
nodeSource.values.firstWhereOrNull((node) => node.key == currentDogecoinNodeId);
|
||||
final currentSolanaNodeServer =
|
||||
nodeSource.values.firstWhereOrNull((node) => node.key == currentSolanaNodeId);
|
||||
final currentTronNodeServer =
|
||||
@@ -1143,6 +1159,12 @@ Future<void> checkCurrentNodes(
|
||||
await sharedPreferences.setInt(PreferencesKey.currentBitcoinCashNodeIdKey, node.key as int);
|
||||
}
|
||||
|
||||
if (currentDogecoinNodeServer == null) {
|
||||
final node = Node(uri: dogecoinDefaultNodeUri, type: WalletType.dogecoin, useSSL: true);
|
||||
await nodeSource.add(node);
|
||||
await sharedPreferences.setInt(PreferencesKey.currentDogecoinNodeIdKey, node.key as int);
|
||||
}
|
||||
|
||||
if (currentPolygonNodeServer == null) {
|
||||
final node = Node(uri: polygonDefaultNodeUri, type: WalletType.polygon);
|
||||
await nodeSource.add(node);
|
||||
|
||||
@@ -46,6 +46,9 @@ Future<List<Node>> loadDefaultNodes(WalletType type) async {
|
||||
case WalletType.decred:
|
||||
path = 'assets/decred_node_list.yml';
|
||||
break;
|
||||
case WalletType.dogecoin:
|
||||
path = 'assets/dogecoin_electrum_server_list.yml';
|
||||
break;
|
||||
case WalletType.banano:
|
||||
case WalletType.none:
|
||||
path = '';
|
||||
@@ -96,6 +99,7 @@ Future<void> resetToDefault(Box<Node> nodeSource) async {
|
||||
final tronNodes = await loadDefaultNodes(WalletType.tron);
|
||||
final decredNodes = await loadDefaultNodes(WalletType.decred);
|
||||
final zanoNodes = await loadDefaultNodes(WalletType.zano);
|
||||
final dogecoinElectrumServerList = await loadDefaultNodes(WalletType.dogecoin);
|
||||
|
||||
final nodes = moneroNodes +
|
||||
bitcoinElectrumServerList +
|
||||
@@ -108,7 +112,8 @@ Future<void> resetToDefault(Box<Node> nodeSource) async {
|
||||
solanaNodes +
|
||||
tronNodes +
|
||||
zanoNodes +
|
||||
decredNodes;
|
||||
decredNodes +
|
||||
dogecoinElectrumServerList;
|
||||
|
||||
await nodeSource.clear();
|
||||
await nodeSource.addAll(nodes);
|
||||
|
||||
@@ -11,6 +11,7 @@ class PreferencesKey {
|
||||
static const currentNanoNodeIdKey = 'current_node_id_nano';
|
||||
static const currentNanoPowNodeIdKey = 'current_node_id_nano_pow';
|
||||
static const currentDecredNodeIdKey = 'current_node_id_decred';
|
||||
static const currentDogecoinNodeIdKey = 'current_node_id_doge';
|
||||
static const currentBananoNodeIdKey = 'current_node_id_banano';
|
||||
static const currentBananoPowNodeIdKey = 'current_node_id_banano_pow';
|
||||
static const currentFiatCurrencyKey = 'current_fiat_currency';
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import 'package:cake_wallet/bitcoin/bitcoin.dart';
|
||||
import 'package:cake_wallet/bitcoin_cash/bitcoin_cash.dart';
|
||||
import 'package:cake_wallet/dogecoin/dogecoin.dart';
|
||||
import 'package:cake_wallet/ethereum/ethereum.dart';
|
||||
import 'package:cake_wallet/monero/monero.dart';
|
||||
import 'package:cake_wallet/polygon/polygon.dart';
|
||||
@@ -23,6 +24,8 @@ List<TransactionPriority> priorityForWalletType(WalletType type) {
|
||||
return ethereum!.getTransactionPriorities();
|
||||
case WalletType.bitcoinCash:
|
||||
return bitcoinCash!.getTransactionPriorities();
|
||||
case WalletType.dogecoin:
|
||||
return dogecoin!.getTransactionPriorities();
|
||||
case WalletType.polygon:
|
||||
return polygon!.getTransactionPriorities();
|
||||
// no such thing for nano/banano/solana/tron:
|
||||
|
||||
+1
-1
@@ -250,7 +250,7 @@ Future<void> initializeAppConfigs({bool loadWallet = true}) async {
|
||||
payjoinSessionSource: payjoinSessionSource,
|
||||
anonpayInvoiceInfo: anonpayInvoiceInfo,
|
||||
havenSeedStore: havenSeedStore,
|
||||
initialMigrationVersion: 50,
|
||||
initialMigrationVersion: 51,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -76,6 +76,7 @@ void startCurrentWalletChangeReaction(
|
||||
wallet.type == WalletType.bitcoin ||
|
||||
wallet.type == WalletType.litecoin ||
|
||||
wallet.type == WalletType.bitcoinCash ||
|
||||
wallet.type == WalletType.dogecoin ||
|
||||
wallet.type == WalletType.decred) {
|
||||
_setAutoGenerateSubaddressStatus(wallet, settingsStore);
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ bool isBIP39Wallet(WalletType walletType) {
|
||||
case WalletType.nano:
|
||||
case WalletType.banano:
|
||||
case WalletType.monero:
|
||||
case WalletType.dogecoin:
|
||||
return true;
|
||||
case WalletType.wownero:
|
||||
case WalletType.haven:
|
||||
|
||||
@@ -37,7 +37,8 @@ class MenuWidgetState extends State<MenuWidget> {
|
||||
this.tronIcon = Image.asset('assets/images/trx_icon.png'),
|
||||
this.wowneroIcon = Image.asset('assets/images/wownero_icon.png'),
|
||||
this.zanoIcon = Image.asset('assets/images/zano_icon.png'),
|
||||
this.decredIcon = Image.asset('assets/images/decred_menu.png');
|
||||
this.decredIcon = Image.asset('assets/images/decred_menu.png'),
|
||||
this.dogecoinIcon = Image.asset('assets/images/doge_icon.png');
|
||||
|
||||
final largeScreen = 731;
|
||||
|
||||
@@ -64,6 +65,7 @@ class MenuWidgetState extends State<MenuWidget> {
|
||||
Image wowneroIcon;
|
||||
Image zanoIcon;
|
||||
Image decredIcon;
|
||||
Image dogecoinIcon;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
@@ -255,6 +257,8 @@ class MenuWidgetState extends State<MenuWidget> {
|
||||
return zanoIcon;
|
||||
case WalletType.decred:
|
||||
return decredIcon;
|
||||
case WalletType.dogecoin:
|
||||
return dogecoinIcon;
|
||||
default:
|
||||
throw Exception('No icon for ${type.toString()}');
|
||||
}
|
||||
|
||||
@@ -1070,6 +1070,7 @@ abstract class SettingsStoreBase with Store {
|
||||
final wowneroNodeId = sharedPreferences.getInt(PreferencesKey.currentWowneroNodeIdKey);
|
||||
final zanoNodeId = sharedPreferences.getInt(PreferencesKey.currentZanoNodeIdKey);
|
||||
final decredNodeId = sharedPreferences.getInt(PreferencesKey.currentDecredNodeIdKey);
|
||||
final dogecoinNodeId = sharedPreferences.getInt(PreferencesKey.currentDogecoinNodeIdKey);
|
||||
|
||||
/// get the selected node, if null, then use the default
|
||||
final moneroNode = nodeSource.get(nodeId) ??
|
||||
@@ -1098,6 +1099,8 @@ abstract class SettingsStoreBase with Store {
|
||||
nodeSource.values.firstWhereOrNull((e) => e.uriRaw == wowneroDefaultNodeUri);
|
||||
final zanoNode = nodeSource.get(zanoNodeId) ??
|
||||
nodeSource.values.firstWhereOrNull((e) => e.uriRaw == zanoDefaultNodeUri);
|
||||
final dogecoinNode = nodeSource.get(dogecoinNodeId) ??
|
||||
nodeSource.values.firstWhereOrNull((e) => e.uriRaw == dogecoinDefaultNodeUri);
|
||||
|
||||
final packageInfo = await PackageInfo.fromPlatform();
|
||||
final deviceName = await _getDeviceName() ?? '';
|
||||
@@ -1185,6 +1188,10 @@ abstract class SettingsStoreBase with Store {
|
||||
nodes[WalletType.decred] = decredNode;
|
||||
}
|
||||
|
||||
if (dogecoinNode != null) {
|
||||
nodes[WalletType.dogecoin] = dogecoinNode;
|
||||
}
|
||||
|
||||
final savedSyncMode = SyncMode.all.firstWhere((element) {
|
||||
return element.type.index == (sharedPreferences.getInt(PreferencesKey.syncModeKey) ?? 2); // default to 2 - daily sync
|
||||
});
|
||||
@@ -1549,6 +1556,7 @@ abstract class SettingsStoreBase with Store {
|
||||
final wowneroNodeId = sharedPreferences.getInt(PreferencesKey.currentWowneroNodeIdKey);
|
||||
final zanoNodeId = sharedPreferences.getInt(PreferencesKey.currentZanoNodeIdKey);
|
||||
final decredNodeId = sharedPreferences.getInt(PreferencesKey.currentDecredNodeIdKey);
|
||||
final dogecoinNodeId = sharedPreferences.getInt(PreferencesKey.currentDogecoinNodeIdKey);
|
||||
final moneroNode = nodeSource.get(nodeId);
|
||||
final bitcoinElectrumServer = nodeSource.get(bitcoinElectrumServerId);
|
||||
final litecoinElectrumServer = nodeSource.get(litecoinElectrumServerId);
|
||||
@@ -1562,6 +1570,7 @@ abstract class SettingsStoreBase with Store {
|
||||
final wowneroNode = nodeSource.get(wowneroNodeId);
|
||||
final zanoNode = nodeSource.get(zanoNodeId);
|
||||
final decredNode = nodeSource.get(decredNodeId);
|
||||
final dogecoinNode = nodeSource.get(dogecoinNodeId);
|
||||
|
||||
if (moneroNode != null) {
|
||||
nodes[WalletType.monero] = moneroNode;
|
||||
@@ -1616,6 +1625,10 @@ abstract class SettingsStoreBase with Store {
|
||||
nodes[WalletType.decred] = decredNode;
|
||||
}
|
||||
|
||||
if (dogecoinNode != null) {
|
||||
nodes[WalletType.dogecoin] = dogecoinNode;
|
||||
}
|
||||
|
||||
// MIGRATED:
|
||||
|
||||
useTOTP2FA = await SecureKey.getBool(
|
||||
@@ -1757,6 +1770,10 @@ abstract class SettingsStoreBase with Store {
|
||||
break;
|
||||
case WalletType.zano:
|
||||
await _sharedPreferences.setInt(PreferencesKey.currentZanoNodeIdKey, node.key as int);
|
||||
break;
|
||||
case WalletType.dogecoin:
|
||||
await _sharedPreferences.setInt(PreferencesKey.currentDogecoinNodeIdKey, node.key as int);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -37,6 +37,7 @@ abstract class AdvancedPrivacySettingsViewModelBase with Store {
|
||||
switch (type) {
|
||||
case WalletType.ethereum:
|
||||
case WalletType.bitcoinCash:
|
||||
case WalletType.dogecoin:
|
||||
case WalletType.polygon:
|
||||
case WalletType.solana:
|
||||
case WalletType.tron:
|
||||
@@ -83,6 +84,7 @@ abstract class AdvancedPrivacySettingsViewModelBase with Store {
|
||||
WalletType.monero,
|
||||
WalletType.wownero,
|
||||
WalletType.zano,
|
||||
WalletType.dogecoin,
|
||||
].contains(type);
|
||||
|
||||
@computed
|
||||
|
||||
@@ -865,6 +865,7 @@ abstract class DashboardViewModelBase with Store {
|
||||
case WalletType.tron:
|
||||
case WalletType.wownero:
|
||||
case WalletType.decred:
|
||||
case WalletType.dogecoin:
|
||||
return true;
|
||||
case WalletType.zano:
|
||||
case WalletType.haven:
|
||||
|
||||
@@ -242,6 +242,7 @@ abstract class HomeSettingsViewModelBase with Store {
|
||||
case WalletType.wownero:
|
||||
case WalletType.bitcoinCash:
|
||||
case WalletType.decred:
|
||||
case WalletType.dogecoin:
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ abstract class SignViewModelBase with Store {
|
||||
WalletType.bitcoin,
|
||||
WalletType.bitcoinCash,
|
||||
WalletType.litecoin,
|
||||
WalletType.dogecoin,
|
||||
WalletType.haven,
|
||||
].contains(wallet.type);
|
||||
|
||||
|
||||
@@ -167,6 +167,7 @@ class TransactionListItem extends ActionListItem with Keyable {
|
||||
case WalletType.bitcoin:
|
||||
case WalletType.litecoin:
|
||||
case WalletType.bitcoinCash:
|
||||
case WalletType.dogecoin:
|
||||
amount = calculateFiatAmountRaw(
|
||||
cryptoAmount: bitcoin!.formatterBitcoinAmountToDouble(amount: transaction.amount),
|
||||
price: price);
|
||||
|
||||
@@ -166,7 +166,7 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with
|
||||
}
|
||||
|
||||
bool get isElectrumWallet =>
|
||||
[WalletType.bitcoin, WalletType.litecoin, WalletType.bitcoinCash].contains(wallet.type);
|
||||
[WalletType.bitcoin, WalletType.litecoin, WalletType.bitcoinCash,WalletType.dogecoin ].contains(wallet.type);
|
||||
|
||||
bool get hideAddressAfterExchange =>
|
||||
[WalletType.monero, WalletType.wownero].contains(wallet.type);
|
||||
@@ -314,6 +314,7 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with
|
||||
WalletType.bitcoin,
|
||||
WalletType.litecoin,
|
||||
WalletType.bitcoinCash,
|
||||
WalletType.dogecoin,
|
||||
].contains(wallet.type) &&
|
||||
depositCurrency == wallet.currency;
|
||||
|
||||
@@ -673,6 +674,7 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with
|
||||
WalletType.litecoin,
|
||||
WalletType.bitcoin,
|
||||
WalletType.bitcoinCash,
|
||||
WalletType.dogecoin,
|
||||
].contains(wallet.type)) {
|
||||
final priority = _settingsStore.priority[wallet.type]!;
|
||||
|
||||
@@ -751,6 +753,10 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with
|
||||
depositCurrency = CryptoCurrency.bch;
|
||||
receiveCurrency = CryptoCurrency.xmr;
|
||||
break;
|
||||
case WalletType.dogecoin:
|
||||
depositCurrency = CryptoCurrency.doge;
|
||||
receiveCurrency = CryptoCurrency.xmr;
|
||||
break;
|
||||
case WalletType.haven:
|
||||
depositCurrency = CryptoCurrency.xhv;
|
||||
receiveCurrency = CryptoCurrency.btc;
|
||||
|
||||
@@ -93,6 +93,7 @@ abstract class NodeCreateOrEditViewModelBase with Store {
|
||||
case WalletType.litecoin:
|
||||
case WalletType.bitcoinCash:
|
||||
case WalletType.bitcoin:
|
||||
case WalletType.dogecoin:
|
||||
case WalletType.zano:
|
||||
case WalletType.decred:
|
||||
return false;
|
||||
|
||||
@@ -47,6 +47,9 @@ class WalletRestoreFromQRCode {
|
||||
'decred': WalletType.decred,
|
||||
'decred-wallet': WalletType.decred,
|
||||
'decred_wallet': WalletType.decred,
|
||||
'dogecoin': WalletType.dogecoin,
|
||||
'dogecoin-wallet': WalletType.dogecoin,
|
||||
'dogecoin_wallet': WalletType.dogecoin
|
||||
};
|
||||
|
||||
static WalletType? _extractWalletType(String code) {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import 'package:cake_wallet/bitcoin_cash/bitcoin_cash.dart';
|
||||
import 'package:cake_wallet/decred/decred.dart';
|
||||
import 'package:cake_wallet/dogecoin/dogecoin.dart';
|
||||
import 'package:cake_wallet/entities/priority_for_wallet_type.dart';
|
||||
import 'package:cake_wallet/core/wallet_change_listener_view_model.dart';
|
||||
import 'package:cake_wallet/ethereum/ethereum.dart';
|
||||
@@ -91,6 +92,8 @@ abstract class FeesViewModelBase extends WalletChangeListenerViewModel with Stor
|
||||
return transactionPriority == polygon!.getPolygonTransactionPrioritySlow();
|
||||
case WalletType.decred:
|
||||
return transactionPriority == decred!.getDecredTransactionPrioritySlow();
|
||||
case WalletType.dogecoin:
|
||||
return transactionPriority == dogecoin!.getDogeCoinTransactionPrioritySlow();
|
||||
case WalletType.none:
|
||||
case WalletType.nano:
|
||||
case WalletType.banano:
|
||||
@@ -119,7 +122,8 @@ abstract class FeesViewModelBase extends WalletChangeListenerViewModel with Stor
|
||||
bool get isElectrumWallet =>
|
||||
wallet.type == WalletType.bitcoin ||
|
||||
wallet.type == WalletType.litecoin ||
|
||||
wallet.type == WalletType.bitcoinCash;
|
||||
wallet.type == WalletType.bitcoinCash ||
|
||||
wallet.type == WalletType.dogecoin;
|
||||
|
||||
String? get walletCurrencyName => wallet.currency.fullName?.toLowerCase() ?? wallet.currency.name;
|
||||
|
||||
@@ -188,6 +192,9 @@ abstract class FeesViewModelBase extends WalletChangeListenerViewModel with Stor
|
||||
case WalletType.bitcoinCash:
|
||||
_settingsStore.priority[wallet.type] = bitcoinCash!.getDefaultTransactionPriority();
|
||||
break;
|
||||
case WalletType.dogecoin:
|
||||
_settingsStore.priority[wallet.type] = dogecoin!.getDefaultTransactionPriority();
|
||||
break;
|
||||
case WalletType.polygon:
|
||||
_settingsStore.priority[wallet.type] = polygon!.getDefaultTransactionPriority();
|
||||
break;
|
||||
|
||||
@@ -99,6 +99,7 @@ abstract class OutputBase with Store {
|
||||
case WalletType.bitcoin:
|
||||
case WalletType.litecoin:
|
||||
case WalletType.bitcoinCash:
|
||||
case WalletType.dogecoin:
|
||||
_amount = bitcoin!.formatterStringDoubleToBitcoinAmount(_cryptoAmount);
|
||||
break;
|
||||
case WalletType.decred:
|
||||
@@ -166,7 +167,8 @@ abstract class OutputBase with Store {
|
||||
return bitcoin!.formatterBitcoinAmountToDouble(amount: fee);
|
||||
}
|
||||
|
||||
if (_wallet.type == WalletType.litecoin || _wallet.type == WalletType.bitcoinCash) {
|
||||
if (_wallet.type == WalletType.litecoin || _wallet.type == WalletType.bitcoinCash ||
|
||||
_wallet.type == WalletType.dogecoin) {
|
||||
return bitcoin!.formatterBitcoinAmountToDouble(amount: fee);
|
||||
}
|
||||
|
||||
@@ -316,6 +318,7 @@ abstract class OutputBase with Store {
|
||||
case WalletType.bitcoin:
|
||||
case WalletType.litecoin:
|
||||
case WalletType.bitcoinCash:
|
||||
case WalletType.dogecoin:
|
||||
maximumFractionDigits = 8;
|
||||
break;
|
||||
case WalletType.wownero:
|
||||
|
||||
@@ -269,6 +269,7 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
|
||||
case WalletType.bitcoin:
|
||||
case WalletType.litecoin:
|
||||
case WalletType.bitcoinCash:
|
||||
case WalletType.dogecoin:
|
||||
case WalletType.monero:
|
||||
case WalletType.wownero:
|
||||
case WalletType.decred:
|
||||
@@ -317,12 +318,13 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
|
||||
WalletType.monero,
|
||||
WalletType.wownero,
|
||||
WalletType.decred,
|
||||
WalletType.bitcoinCash
|
||||
WalletType.bitcoinCash,
|
||||
WalletType.dogecoin
|
||||
].contains(wallet.type);
|
||||
|
||||
@computed
|
||||
bool get isElectrumWallet =>
|
||||
[WalletType.bitcoin, WalletType.litecoin, WalletType.bitcoinCash].contains(wallet.type);
|
||||
[WalletType.bitcoin, WalletType.litecoin, WalletType.bitcoinCash, WalletType.dogecoin].contains(wallet.type);
|
||||
|
||||
@observable
|
||||
CryptoCurrency selectedCryptoCurrency;
|
||||
@@ -652,6 +654,7 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
|
||||
switch (wallet.type) {
|
||||
case WalletType.bitcoin:
|
||||
case WalletType.bitcoinCash:
|
||||
case WalletType.dogecoin:
|
||||
return bitcoin!.createBitcoinTransactionCredentials(
|
||||
outputs,
|
||||
priority: priority!,
|
||||
|
||||
@@ -70,7 +70,8 @@ abstract class OtherSettingsViewModelBase with Store {
|
||||
|
||||
if (_wallet.type == WalletType.bitcoin ||
|
||||
_wallet.type == WalletType.litecoin ||
|
||||
_wallet.type == WalletType.bitcoinCash) {
|
||||
_wallet.type == WalletType.bitcoinCash ||
|
||||
_wallet.type == WalletType.dogecoin) {
|
||||
final rate = bitcoin!.getFeeRate(_wallet, _priority);
|
||||
return bitcoin!.bitcoinTransactionPriorityWithLabel(_priority, rate);
|
||||
}
|
||||
@@ -83,7 +84,8 @@ abstract class OtherSettingsViewModelBase with Store {
|
||||
|
||||
if (_wallet.type == WalletType.bitcoin ||
|
||||
_wallet.type == WalletType.litecoin ||
|
||||
_wallet.type == WalletType.bitcoinCash) {
|
||||
_wallet.type == WalletType.bitcoinCash ||
|
||||
_wallet.type == WalletType.dogecoin) {
|
||||
final rate = bitcoin!.getFeeRate(_wallet, _priority);
|
||||
return bitcoin!.bitcoinTransactionPriorityWithLabel(_priority, rate,
|
||||
customRate: customValue);
|
||||
|
||||
@@ -43,6 +43,7 @@ abstract class PrivacySettingsViewModelBase with Store {
|
||||
WalletType.bitcoin,
|
||||
WalletType.litecoin,
|
||||
WalletType.bitcoinCash,
|
||||
WalletType.dogecoin,
|
||||
WalletType.decred
|
||||
].contains(_wallet.type);
|
||||
|
||||
|
||||
@@ -88,6 +88,9 @@ abstract class TransactionDetailsViewModelBase with Store {
|
||||
case WalletType.decred:
|
||||
_addDecredListItems(tx, dateFormat);
|
||||
break;
|
||||
case WalletType.dogecoin:
|
||||
_addDogecoinListItems(tx, dateFormat);
|
||||
break;
|
||||
case WalletType.none:
|
||||
case WalletType.banano:
|
||||
break;
|
||||
@@ -193,6 +196,8 @@ abstract class TransactionDetailsViewModelBase with Store {
|
||||
return 'https://explorer.zano.org/transaction/${txId}';
|
||||
case WalletType.decred:
|
||||
return 'https://${wallet.isTestnet ? "testnet" : "dcrdata"}.decred.org/tx/${txId.split(':')[0]}';
|
||||
case WalletType.dogecoin:
|
||||
return 'https://blockchair.com/dogecoin/transaction/${txId}';
|
||||
case WalletType.none:
|
||||
return '';
|
||||
}
|
||||
@@ -206,6 +211,7 @@ abstract class TransactionDetailsViewModelBase with Store {
|
||||
return S.current.view_transaction_on + 'mempool.space';
|
||||
case WalletType.litecoin:
|
||||
case WalletType.bitcoinCash:
|
||||
case WalletType.dogecoin:
|
||||
return S.current.view_transaction_on + 'Blockchair.com';
|
||||
case WalletType.haven:
|
||||
return S.current.view_transaction_on + 'explorer.havenprotocol.org';
|
||||
@@ -750,6 +756,51 @@ abstract class TransactionDetailsViewModelBase with Store {
|
||||
items.addAll(_items);
|
||||
}
|
||||
|
||||
void _addDogecoinListItems(TransactionInfo tx, DateFormat dateFormat) {
|
||||
final _items = [
|
||||
StandartListItem(
|
||||
title: S.current.transaction_details_transaction_id,
|
||||
value: tx.txHash,
|
||||
key: ValueKey('standard_list_item_transaction_details_id_key'),
|
||||
),
|
||||
StandartListItem(
|
||||
title: S.current.transaction_details_date,
|
||||
value: dateFormat.format(tx.date),
|
||||
key: ValueKey('standard_list_item_transaction_details_date_key'),
|
||||
),
|
||||
StandartListItem(
|
||||
title: S.current.transaction_details_height,
|
||||
value: '${tx.height}',
|
||||
key: ValueKey('standard_list_item_transaction_details_height_key'),
|
||||
),
|
||||
StandartListItem(
|
||||
title: S.current.transaction_details_amount,
|
||||
value: tx.amountFormatted(),
|
||||
key: ValueKey('standard_list_item_transaction_details_amount_key'),
|
||||
),
|
||||
if (tx.feeFormatted()?.isNotEmpty ?? false)
|
||||
StandartListItem(
|
||||
title: S.current.transaction_details_fee,
|
||||
value: tx.feeFormatted()!,
|
||||
key: ValueKey('standard_list_item_transaction_details_fee_key'),
|
||||
),
|
||||
if (showRecipientAddress && tx.to != null)
|
||||
StandartListItem(
|
||||
title: S.current.transaction_details_recipient_address,
|
||||
value: tx.to!,
|
||||
key: ValueKey('standard_list_item_transaction_details_recipient_address_key'),
|
||||
),
|
||||
if (tx.from != null)
|
||||
StandartListItem(
|
||||
title: S.current.transaction_details_source_address,
|
||||
value: tx.from!,
|
||||
key: ValueKey('standard_list_item_transaction_details_source_address_key'),
|
||||
),
|
||||
];
|
||||
|
||||
items.addAll(_items);
|
||||
}
|
||||
|
||||
@action
|
||||
Future<void> _checkForRBF(TransactionInfo tx) async {
|
||||
if (wallet.type == WalletType.bitcoin &&
|
||||
|
||||
@@ -49,7 +49,7 @@ abstract class UnspentCoinsDetailsViewModelBase with Store {
|
||||
})
|
||||
];
|
||||
|
||||
if ([WalletType.bitcoin, WalletType.litecoin, WalletType.bitcoinCash].contains(_type)) {
|
||||
if ([WalletType.bitcoin, WalletType.litecoin, WalletType.bitcoinCash, WalletType.dogecoin].contains(_type)) {
|
||||
items.add(BlockExplorerListItem(
|
||||
title: S.current.view_in_block_explorer,
|
||||
value: _explorerDescription(_type),
|
||||
@@ -71,6 +71,8 @@ abstract class UnspentCoinsDetailsViewModelBase with Store {
|
||||
return 'https://litecoin.earlyordies.com/tx/${txId}';
|
||||
case WalletType.bitcoinCash:
|
||||
return 'https://blockchair.com/bitcoin-cash/transaction/${txId}';
|
||||
case WalletType.dogecoin:
|
||||
return 'https://dogechain.info/tx/${txId}';
|
||||
default:
|
||||
return '';
|
||||
}
|
||||
@@ -84,6 +86,8 @@ abstract class UnspentCoinsDetailsViewModelBase with Store {
|
||||
return S.current.view_transaction_on + 'Earlyordies.com';
|
||||
case WalletType.bitcoinCash:
|
||||
return S.current.view_transaction_on + 'Blockchair.com';
|
||||
case WalletType.dogecoin:
|
||||
return S.current.view_transaction_on + 'Dogechain.info';
|
||||
default:
|
||||
return '';
|
||||
}
|
||||
|
||||
@@ -91,7 +91,7 @@ abstract class UnspentCoinsListViewModelBase with Store {
|
||||
return monero!.formatterMoneroAmountToString(amount: fullBalance);
|
||||
if (wallet.type == WalletType.wownero)
|
||||
return wownero!.formatterWowneroAmountToString(amount: fullBalance);
|
||||
if ([WalletType.bitcoin, WalletType.litecoin, WalletType.bitcoinCash].contains(wallet.type))
|
||||
if ([WalletType.bitcoin, WalletType.litecoin, WalletType.bitcoinCash, WalletType.dogecoin].contains(wallet.type))
|
||||
return bitcoin!.formatterBitcoinAmountToString(amount: fullBalance);
|
||||
if (wallet.type == WalletType.decred)
|
||||
return decred!.formatterDecredAmountToString(amount: fullBalance);
|
||||
@@ -105,7 +105,7 @@ abstract class UnspentCoinsListViewModelBase with Store {
|
||||
if (wallet.type == WalletType.wownero) {
|
||||
await wownero!.updateUnspents(wallet);
|
||||
}
|
||||
if ([WalletType.bitcoin, WalletType.litecoin, WalletType.bitcoinCash].contains(wallet.type)) {
|
||||
if ([WalletType.bitcoin, WalletType.litecoin, WalletType.bitcoinCash, WalletType.dogecoin].contains(wallet.type)) {
|
||||
await bitcoin!.updateUnspents(wallet);
|
||||
}
|
||||
if (wallet.type == WalletType.decred) {
|
||||
@@ -123,6 +123,7 @@ abstract class UnspentCoinsListViewModelBase with Store {
|
||||
case WalletType.bitcoin:
|
||||
case WalletType.litecoin:
|
||||
case WalletType.bitcoinCash:
|
||||
case WalletType.dogecoin:
|
||||
return bitcoin!.getUnspents(wallet, coinTypeToSpendFrom: coinTypeToSpendFrom);
|
||||
case WalletType.decred:
|
||||
return decred!.getUnspents(wallet);
|
||||
@@ -140,6 +141,7 @@ abstract class UnspentCoinsListViewModelBase with Store {
|
||||
case WalletType.bitcoin:
|
||||
case WalletType.litecoin:
|
||||
case WalletType.bitcoinCash:
|
||||
case WalletType.dogecoin:
|
||||
return bitcoin!.getUnspents(wallet, coinTypeToSpendFrom: overrideCoinTypeToSpendFrom);
|
||||
case WalletType.decred:
|
||||
return decred!.getUnspents(wallet);
|
||||
|
||||
@@ -48,7 +48,8 @@ abstract class WalletAddressEditOrCreateViewModelBase with Store {
|
||||
bool get isElectrum =>
|
||||
_wallet.type == WalletType.bitcoin ||
|
||||
_wallet.type == WalletType.bitcoinCash ||
|
||||
_wallet.type == WalletType.litecoin;
|
||||
_wallet.type == WalletType.litecoin ||
|
||||
_wallet.type == WalletType.dogecoin;
|
||||
|
||||
Future<void> save() async {
|
||||
try {
|
||||
|
||||
@@ -242,6 +242,22 @@ class DecredURI extends PaymentURI {
|
||||
}
|
||||
}
|
||||
|
||||
class DogeURI extends PaymentURI {
|
||||
DogeURI({required String amount, required String address})
|
||||
: super(amount: amount, address: address);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
var base = 'doge:' + address;
|
||||
|
||||
if (amount.isNotEmpty) {
|
||||
base += '?amount=${amount.replaceAll(',', '.')}';
|
||||
}
|
||||
|
||||
return base;
|
||||
}
|
||||
}
|
||||
|
||||
abstract class WalletAddressListViewModelBase extends WalletChangeListenerViewModel with Store {
|
||||
WalletAddressListViewModelBase({
|
||||
required AppStore appStore,
|
||||
@@ -350,6 +366,8 @@ abstract class WalletAddressListViewModelBase extends WalletChangeListenerViewMo
|
||||
return ZanoURI(amount: amount, address: address.address);
|
||||
case WalletType.decred:
|
||||
return DecredURI(amount: amount, address: address.address);
|
||||
case WalletType.dogecoin:
|
||||
return DogeURI(amount: amount, address: address.address);
|
||||
case WalletType.none:
|
||||
throw Exception('Unexpected type: ${type.toString()}');
|
||||
}
|
||||
@@ -586,12 +604,13 @@ abstract class WalletAddressListViewModelBase extends WalletChangeListenerViewMo
|
||||
WalletType.bitcoinCash,
|
||||
WalletType.bitcoin,
|
||||
WalletType.litecoin,
|
||||
WalletType.decred
|
||||
WalletType.decred,
|
||||
WalletType.dogecoin,
|
||||
].contains(wallet.type);
|
||||
|
||||
@computed
|
||||
bool get isElectrumWallet =>
|
||||
[WalletType.bitcoin, WalletType.litecoin, WalletType.bitcoinCash].contains(wallet.type);
|
||||
[WalletType.bitcoin, WalletType.litecoin, WalletType.bitcoinCash, WalletType.dogecoin].contains(wallet.type);
|
||||
|
||||
@computed
|
||||
bool get isBalanceAvailable => isElectrumWallet;
|
||||
|
||||
@@ -164,6 +164,7 @@ abstract class WalletKeysViewModelBase with Store {
|
||||
case WalletType.bitcoin:
|
||||
case WalletType.litecoin:
|
||||
case WalletType.bitcoinCash:
|
||||
case WalletType.dogecoin:
|
||||
if (_wallet.type == WalletType.bitcoin) {
|
||||
keys = bitcoin!.getSilentPaymentKeys(_appStore.wallet!);
|
||||
}
|
||||
@@ -261,6 +262,8 @@ abstract class WalletKeysViewModelBase with Store {
|
||||
return 'zano-wallet';
|
||||
case WalletType.decred:
|
||||
return 'decred-wallet';
|
||||
case WalletType.dogecoin:
|
||||
return 'dogecoin-wallet';
|
||||
default:
|
||||
throw Exception('Unexpected wallet type: ${_wallet.type.toString()}');
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'package:cake_wallet/core/new_wallet_arguments.dart';
|
||||
import 'package:cake_wallet/dogecoin/dogecoin.dart';
|
||||
import 'package:cake_wallet/ethereum/ethereum.dart';
|
||||
import 'package:cake_wallet/zano/zano.dart';
|
||||
import 'package:cake_wallet/bitcoin_cash/bitcoin_cash.dart';
|
||||
@@ -96,6 +97,13 @@ abstract class WalletNewVMBase extends WalletCreationVM with Store {
|
||||
passphrase: passphrase,
|
||||
mnemonic: newWalletArguments!.mnemonic,
|
||||
);
|
||||
case WalletType.dogecoin:
|
||||
return dogecoin!.createDogeCoinNewWalletCredentials(
|
||||
name: name,
|
||||
password: walletPassword,
|
||||
passphrase: passphrase,
|
||||
mnemonic: newWalletArguments!.mnemonic,
|
||||
);
|
||||
case WalletType.nano:
|
||||
case WalletType.banano:
|
||||
return nano!.createNanoNewWalletCredentials(
|
||||
|
||||
@@ -3,6 +3,7 @@ import 'package:cake_wallet/bitcoin_cash/bitcoin_cash.dart';
|
||||
import 'package:cake_wallet/core/generate_wallet_password.dart';
|
||||
import 'package:cake_wallet/core/wallet_creation_service.dart';
|
||||
import 'package:cake_wallet/di.dart';
|
||||
import 'package:cake_wallet/dogecoin/dogecoin.dart';
|
||||
import 'package:cake_wallet/ethereum/ethereum.dart';
|
||||
import 'package:cake_wallet/monero/monero.dart';
|
||||
import 'package:cake_wallet/nano/nano.dart';
|
||||
@@ -58,6 +59,7 @@ abstract class WalletRestoreViewModelBase extends WalletCreationVM with Store {
|
||||
case WalletType.bitcoinCash:
|
||||
case WalletType.zano:
|
||||
case WalletType.none:
|
||||
case WalletType.dogecoin:
|
||||
availableModes = [WalletRestoreMode.seed];
|
||||
break;
|
||||
}
|
||||
@@ -148,6 +150,13 @@ abstract class WalletRestoreViewModelBase extends WalletCreationVM with Store {
|
||||
password: password,
|
||||
passphrase: passphrase,
|
||||
);
|
||||
case WalletType.dogecoin:
|
||||
return dogecoin!.createDogeCoinRestoreWalletFromSeedCredentials(
|
||||
name: name,
|
||||
mnemonic: seed,
|
||||
password: password,
|
||||
passphrase: passphrase,
|
||||
);
|
||||
case WalletType.nano:
|
||||
case WalletType.banano:
|
||||
return nano!.createNanoRestoreWalletFromSeedCredentials(
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
#!/bin/bash
|
||||
set -x -e
|
||||
|
||||
for cwcoin in cw_{core,evm,monero,bitcoin,nano,bitcoin_cash,solana,tron,wownero,zano,decred}
|
||||
for cwcoin in cw_{core,evm,monero,bitcoin,nano,bitcoin_cash,solana,tron,wownero,zano,decred,dogecoin}
|
||||
do
|
||||
if [[ "x$1" == "xasync" ]];
|
||||
then
|
||||
|
||||
+2
-1
@@ -177,7 +177,7 @@ dependency_overrides:
|
||||
bitcoin_base:
|
||||
git:
|
||||
url: https://github.com/cake-tech/bitcoin_base
|
||||
ref: cake-update-v10
|
||||
ref: cake-update-v11
|
||||
ffi: 2.1.0
|
||||
ledger_flutter_plus:
|
||||
git:
|
||||
@@ -223,6 +223,7 @@ flutter:
|
||||
- assets/wownero_node_list.yml
|
||||
- assets/zano_node_list.yml
|
||||
- assets/decred_node_list.yml
|
||||
- assets/dogecoin_electrum_server_list.yml
|
||||
- assets/text/
|
||||
- assets/faq/
|
||||
- assets/animation/
|
||||
|
||||
@@ -10,7 +10,7 @@ case $APP_ANDROID_TYPE in
|
||||
CONFIG_ARGS="--monero"
|
||||
;;
|
||||
$CAKEWALLET)
|
||||
CONFIG_ARGS="--monero --bitcoin --ethereum --polygon --nano --bitcoinCash --solana --tron --wownero --zano --decred"
|
||||
CONFIG_ARGS="--monero --bitcoin --ethereum --polygon --nano --bitcoinCash --solana --tron --wownero --zano --decred --dogecoin"
|
||||
;;
|
||||
esac
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ case $APP_IOS_TYPE in
|
||||
;;
|
||||
|
||||
$CAKEWALLET)
|
||||
CONFIG_ARGS="--monero --bitcoin --ethereum --polygon --nano --bitcoinCash --solana --tron --wownero --zano --decred"
|
||||
CONFIG_ARGS="--monero --bitcoin --ethereum --polygon --nano --bitcoinCash --solana --tron --wownero --zano --decred --dogecoin"
|
||||
;;
|
||||
esac
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ CONFIG_ARGS=""
|
||||
|
||||
case $APP_LINUX_TYPE in
|
||||
$CAKEWALLET)
|
||||
CONFIG_ARGS="--monero --bitcoin --ethereum --polygon --nano --bitcoinCash --solana --tron --wownero --excludeFlutterSecureStorage";;
|
||||
CONFIG_ARGS="--monero --bitcoin --ethereum --polygon --nano --bitcoinCash --solana --tron --wownero --dogecoin --excludeFlutterSecureStorage";;
|
||||
esac
|
||||
|
||||
cp -rf pubspec_description.yaml pubspec.yaml
|
||||
|
||||
@@ -36,7 +36,7 @@ case $APP_MACOS_TYPE in
|
||||
$MONERO_COM)
|
||||
CONFIG_ARGS="--monero";;
|
||||
$CAKEWALLET)
|
||||
CONFIG_ARGS="--monero --bitcoin --ethereum --polygon --nano --bitcoinCash --solana --tron --wownero";;
|
||||
CONFIG_ARGS="--monero --bitcoin --ethereum --polygon --nano --bitcoinCash --solana --tron --wownero --dogecoin";;
|
||||
esac
|
||||
|
||||
cp -rf pubspec_description.yaml pubspec.yaml
|
||||
|
||||
@@ -11,6 +11,7 @@ const tronOutputPath = 'lib/tron/tron.dart';
|
||||
const wowneroOutputPath = 'lib/wownero/wownero.dart';
|
||||
const zanoOutputPath = 'lib/zano/zano.dart';
|
||||
const decredOutputPath = 'lib/decred/decred.dart';
|
||||
const dogecoinOutputPath = 'lib/dogecoin/dogecoin.dart';
|
||||
const walletTypesPath = 'lib/wallet_types.g.dart';
|
||||
const secureStoragePath = 'lib/core/secure_storage.dart';
|
||||
const pubspecDefaultPath = 'pubspec_default.yaml';
|
||||
@@ -30,6 +31,7 @@ Future<void> main(List<String> args) async {
|
||||
final hasWownero = args.contains('${prefix}wownero');
|
||||
final hasZano = args.contains('${prefix}zano');
|
||||
final hasDecred = args.contains('${prefix}decred');
|
||||
final hasDogecoin = args.contains('${prefix}dogecoin');
|
||||
final excludeFlutterSecureStorage = args.contains('${prefix}excludeFlutterSecureStorage');
|
||||
|
||||
await generateBitcoin(hasBitcoin);
|
||||
@@ -44,6 +46,7 @@ Future<void> main(List<String> args) async {
|
||||
await generateZano(hasZano);
|
||||
// await generateBanano(hasEthereum);
|
||||
await generateDecred(hasDecred);
|
||||
await generateDogecoin(hasDogecoin);
|
||||
|
||||
await generatePubspec(
|
||||
hasMonero: hasMonero,
|
||||
@@ -59,6 +62,7 @@ Future<void> main(List<String> args) async {
|
||||
hasWownero: hasWownero,
|
||||
hasZano: hasZano,
|
||||
hasDecred: hasDecred,
|
||||
hasDogecoin: hasDogecoin,
|
||||
);
|
||||
await generateWalletTypes(
|
||||
hasMonero: hasMonero,
|
||||
@@ -73,6 +77,7 @@ Future<void> main(List<String> args) async {
|
||||
hasWownero: hasWownero,
|
||||
hasZano: hasZano,
|
||||
hasDecred: hasDecred,
|
||||
hasDogecoin: hasDogecoin,
|
||||
);
|
||||
await injectSecureStorage(!excludeFlutterSecureStorage);
|
||||
}
|
||||
@@ -1414,6 +1419,61 @@ abstract class Decred {
|
||||
await outputFile.writeAsString(output);
|
||||
}
|
||||
|
||||
Future<void> generateDogecoin(bool hasImplementation) async {
|
||||
final outputFile = File(dogecoinOutputPath);
|
||||
const dogecoinCommonHeaders = """
|
||||
import 'package:cw_core/transaction_priority.dart';
|
||||
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 dogecoinCWHeaders = """
|
||||
import 'package:cw_dogecoin/cw_dogecoin.dart';
|
||||
""";
|
||||
const dogecoinCwPart = "part 'cw_dogecoin.dart';";
|
||||
const dogecoinContent = """
|
||||
abstract class DogeCoin {
|
||||
|
||||
WalletService createDogeCoinWalletService(
|
||||
Box<WalletInfo> walletInfoSource, Box<UnspentCoinsInfo> unspentCoinSource, bool isDirect);
|
||||
|
||||
WalletCredentials createDogeCoinNewWalletCredentials(
|
||||
{required String name, WalletInfo? walletInfo, String? password, String? passphrase, String? mnemonic});
|
||||
|
||||
WalletCredentials createDogeCoinRestoreWalletFromSeedCredentials(
|
||||
{required String name, required String mnemonic, required String password, String? passphrase});
|
||||
|
||||
TransactionPriority deserializeDogeCoinTransactionPriority(int raw);
|
||||
|
||||
TransactionPriority getDefaultTransactionPriority();
|
||||
|
||||
List<TransactionPriority> getTransactionPriorities();
|
||||
|
||||
TransactionPriority getDogeCoinTransactionPrioritySlow();
|
||||
}
|
||||
""";
|
||||
|
||||
const dogecoinEmptyDefinition = 'DogeCoin? dogecoin;\n';
|
||||
const dogecoinCWDefinition = 'DogeCoin? dogecoin = CWDogeCoin();\n';
|
||||
|
||||
final output = '$dogecoinCommonHeaders\n' +
|
||||
(hasImplementation ? '$dogecoinCWHeaders\n' : '\n') +
|
||||
(hasImplementation ? '$dogecoinCwPart\n\n' : '\n') +
|
||||
(hasImplementation
|
||||
? dogecoinCWDefinition
|
||||
: dogecoinEmptyDefinition) +
|
||||
'\n' +
|
||||
dogecoinContent;
|
||||
|
||||
if (outputFile.existsSync()) {
|
||||
await outputFile.delete();
|
||||
}
|
||||
|
||||
await outputFile.writeAsString(output);
|
||||
}
|
||||
|
||||
Future<void> generatePubspec({
|
||||
required bool hasMonero,
|
||||
required bool hasBitcoin,
|
||||
@@ -1428,6 +1488,7 @@ Future<void> generatePubspec({
|
||||
required bool hasWownero,
|
||||
required bool hasZano,
|
||||
required bool hasDecred,
|
||||
required bool hasDogecoin,
|
||||
}) async {
|
||||
const cwCore = """
|
||||
cw_core:
|
||||
@@ -1492,6 +1553,10 @@ Future<void> generatePubspec({
|
||||
cw_decred:
|
||||
path: ./cw_decred
|
||||
""";
|
||||
const cwDogecoin = """
|
||||
cw_dogecoin:
|
||||
path: ./cw_dogecoin
|
||||
""";
|
||||
final inputFile = File(pubspecOutputPath);
|
||||
final inputText = await inputFile.readAsString();
|
||||
final inputLines = inputText.split('\n');
|
||||
@@ -1557,6 +1622,10 @@ Future<void> generatePubspec({
|
||||
output += '\n$cwZano';
|
||||
}
|
||||
|
||||
if (hasDogecoin) {
|
||||
output += '\n$cwDogecoin';
|
||||
}
|
||||
|
||||
final outputLines = output.split('\n');
|
||||
inputLines.insertAll(dependenciesIndex + 1, outputLines);
|
||||
final outputContent = inputLines.join('\n');
|
||||
@@ -1582,6 +1651,7 @@ Future<void> generateWalletTypes({
|
||||
required bool hasWownero,
|
||||
required bool hasZano,
|
||||
required bool hasDecred,
|
||||
required bool hasDogecoin,
|
||||
}) async {
|
||||
final walletTypesFile = File(walletTypesPath);
|
||||
|
||||
@@ -1609,6 +1679,10 @@ Future<void> generateWalletTypes({
|
||||
outputContent += '\tWalletType.litecoin,\n';
|
||||
}
|
||||
|
||||
if (hasDogecoin) {
|
||||
outputContent += '\tWalletType.dogecoin,\n';
|
||||
}
|
||||
|
||||
if (hasBitcoinCash) {
|
||||
outputContent += '\tWalletType.bitcoinCash,\n';
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user