mirror of
https://github.com/cypherstack/stack_wallet.git
synced 2024-12-22 19:39:22 +00:00
WIP: Add namecoin
This commit is contained in:
parent
6a418c4215
commit
84694fa1dd
13 changed files with 183 additions and 104 deletions
1
assets/svg/coin_icons/Namecoin.svg
Normal file
1
assets/svg/coin_icons/Namecoin.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32"><g fill="none" fill-rule="evenodd"><circle cx="16" cy="16" r="16" fill="#186C9D"/><path fill="#FFF" fill-rule="nonzero" d="M19.261 23.5l.001-.002a1.8 1.8 0 0 0 .458-.05c.876-.205 1.617-.97 1.793-1.796L25 8.556l-2.772-.014-2.286 8.568-6.18-8.597-.004.004.003-.01L12.74 8.5v.001a1.9 1.9 0 0 0-.459.049c-.875.206-1.616.971-1.793 1.796L7 23.445l2.773.012 2.285-8.568 6.18 8.598h.003l1.02.013zm-6.593-10.894l.483-1.81 6.181 8.599-.483 1.81-6.18-8.6z"/></g></svg>
|
After Width: | Height: | Size: 520 B |
|
@ -116,6 +116,7 @@ class _AddEditNodeViewState extends ConsumerState<AddEditNodeView> {
|
|||
case Coin.bitcoincash:
|
||||
case Coin.dogecoin:
|
||||
case Coin.firo:
|
||||
case Coin.namecoin:
|
||||
case Coin.bitcoinTestNet:
|
||||
case Coin.firoTestNet:
|
||||
case Coin.dogecoinTestNet:
|
||||
|
@ -528,6 +529,7 @@ class _NodeFormState extends ConsumerState<NodeForm> {
|
|||
case Coin.bitcoin:
|
||||
case Coin.dogecoin:
|
||||
case Coin.firo:
|
||||
case Coin.namecoin:
|
||||
case Coin.bitcoincash:
|
||||
case Coin.bitcoinTestNet:
|
||||
case Coin.firoTestNet:
|
||||
|
|
|
@ -3040,6 +3040,36 @@ class BitcoinCashWallet extends CoinServiceAPI {
|
|||
|
||||
return available - estimatedFee;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<bool> generateNewAddress() async {
|
||||
try {
|
||||
await _incrementAddressIndexForChain(
|
||||
0, DerivePathType.bip44); // First increment the receiving index
|
||||
final newReceivingIndex = DB.instance.get<dynamic>(
|
||||
boxName: walletId,
|
||||
key: 'receivingIndexP2PKH') as int; // Check the new receiving index
|
||||
final newReceivingAddress = await _generateAddressForChain(
|
||||
0,
|
||||
newReceivingIndex,
|
||||
DerivePathType
|
||||
.bip44); // Use new index to derive a new receiving address
|
||||
await _addToAddressesArrayForChain(
|
||||
newReceivingAddress,
|
||||
0,
|
||||
DerivePathType
|
||||
.bip44); // Add that new receiving address to the array of receiving addresses
|
||||
_currentReceivingAddressP2PKH = Future(() =>
|
||||
newReceivingAddress); // Set the new receiving address that the service
|
||||
|
||||
return true;
|
||||
} catch (e, s) {
|
||||
Logging.instance.log(
|
||||
"Exception rethrown from generateNewAddress(): $e\n$s",
|
||||
level: LogLevel.Error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Bitcoincash Network
|
||||
|
|
|
@ -9,6 +9,7 @@ import 'package:stackwallet/services/coins/epiccash/epiccash_wallet.dart';
|
|||
import 'package:stackwallet/services/coins/firo/firo_wallet.dart';
|
||||
import 'package:stackwallet/services/coins/monero/monero_wallet.dart';
|
||||
import 'package:stackwallet/services/coins/bitcoincash/bitcoincash_wallet.dart';
|
||||
import 'package:stackwallet/services/coins/namecoin/namecoin_wallet.dart';
|
||||
import 'package:stackwallet/services/transaction_notification_tracker.dart';
|
||||
import 'package:stackwallet/utilities/enums/coin_enum.dart';
|
||||
import 'package:stackwallet/utilities/prefs.dart';
|
||||
|
@ -134,6 +135,16 @@ abstract class CoinServiceAPI {
|
|||
// tracker: tracker,
|
||||
);
|
||||
|
||||
case Coin.namecoin:
|
||||
return NamecoinWallet(
|
||||
walletId: walletId,
|
||||
walletName: walletName,
|
||||
coin: coin,
|
||||
tracker: tracker,
|
||||
cachedClient: cachedClient,
|
||||
client: client,
|
||||
);
|
||||
|
||||
case Coin.dogecoinTestNet:
|
||||
return DogecoinWallet(
|
||||
walletId: walletId,
|
||||
|
|
|
@ -46,9 +46,7 @@ const int MINIMUM_CONFIRMATIONS = 3;
|
|||
const int DUST_LIMIT = 1000000;
|
||||
|
||||
const String GENESIS_HASH_MAINNET =
|
||||
"000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f";
|
||||
const String GENESIS_HASH_TESTNET =
|
||||
"000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943";
|
||||
"000000000062b72c5e2ceb45fbc8587e807c155b0da735e6483dfba2f0a9c770";
|
||||
|
||||
enum DerivePathType { bip44 }
|
||||
|
||||
|
@ -77,11 +75,11 @@ bip32.BIP32 getBip32NodeFromRoot(
|
|||
int chain, int index, bip32.BIP32 root, DerivePathType derivePathType) {
|
||||
String coinType;
|
||||
switch (root.network.wif) {
|
||||
case 0x80: // bch mainnet wif
|
||||
coinType = "145"; // bch mainnet
|
||||
case 0x80: // nmc mainnet wif
|
||||
coinType = "7"; // nmc mainnet
|
||||
break;
|
||||
default:
|
||||
throw Exception("Invalid Bitcoincash network type used!");
|
||||
throw Exception("Invalid Namecoin network type used!");
|
||||
}
|
||||
switch (derivePathType) {
|
||||
case DerivePathType.bip44:
|
||||
|
@ -122,7 +120,7 @@ bip32.BIP32 getBip32RootWrapper(Tuple2<String, NetworkType> args) {
|
|||
return getBip32Root(args.item1, args.item2);
|
||||
}
|
||||
|
||||
class NamecoinCashWallet extends CoinServiceAPI {
|
||||
class NamecoinWallet extends CoinServiceAPI {
|
||||
static const integrationTestFlag =
|
||||
bool.fromEnvironment("IS_INTEGRATION_TEST");
|
||||
final _prefs = Prefs.instance;
|
||||
|
@ -134,10 +132,10 @@ class NamecoinCashWallet extends CoinServiceAPI {
|
|||
|
||||
NetworkType get _network {
|
||||
switch (coin) {
|
||||
case Coin.bitcoincash:
|
||||
return bitcoincash;
|
||||
case Coin.namecoin:
|
||||
return namecoin;
|
||||
default:
|
||||
throw Exception("Bitcoincash network type not set!");
|
||||
throw Exception("Namecoin network type not set!");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -298,14 +296,14 @@ class NamecoinCashWallet extends CoinServiceAPI {
|
|||
final features = await electrumXClient.getServerFeatures();
|
||||
Logging.instance.log("features: $features", level: LogLevel.Info);
|
||||
switch (coin) {
|
||||
case Coin.bitcoincash:
|
||||
case Coin.namecoin:
|
||||
if (features['genesis_hash'] != GENESIS_HASH_MAINNET) {
|
||||
throw Exception("genesis hash does not match main net!");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw Exception(
|
||||
"Attempted to generate a BitcoinCashWallet using a non bch coin type: ${coin.name}");
|
||||
"Attempted to generate a NamecoinWallet using a non namecoin coin type: ${coin.name}");
|
||||
}
|
||||
}
|
||||
// check to make sure we aren't overwriting a mnemonic
|
||||
|
@ -730,9 +728,6 @@ class NamecoinCashWallet extends CoinServiceAPI {
|
|||
/// Refreshes display data for the wallet
|
||||
@override
|
||||
Future<void> refresh() async {
|
||||
final bchaddr = Bitbox.Address.toCashAddress(await currentReceivingAddress);
|
||||
print("bchaddr: $bchaddr ${await currentReceivingAddress}");
|
||||
|
||||
if (refreshMutex) {
|
||||
Logging.instance.log("$walletId $walletName refreshMutex denied",
|
||||
level: LogLevel.Info);
|
||||
|
@ -1048,14 +1043,7 @@ class NamecoinCashWallet extends CoinServiceAPI {
|
|||
|
||||
@override
|
||||
bool validateAddress(String address) {
|
||||
try {
|
||||
// 0 for bitcoincash: address scheme, 1 for legacy address
|
||||
final format = Bitbox.Address.detectFormat(address);
|
||||
print("format $format");
|
||||
return true;
|
||||
} catch (e, s) {
|
||||
return false;
|
||||
}
|
||||
return Address.validateAddress(address, _network);
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -1082,7 +1070,7 @@ class NamecoinCashWallet extends CoinServiceAPI {
|
|||
|
||||
late PriceAPI _priceAPI;
|
||||
|
||||
BitcoinCashWallet({
|
||||
NamecoinWallet({
|
||||
required String walletId,
|
||||
required String walletName,
|
||||
required Coin coin,
|
||||
|
@ -1222,14 +1210,14 @@ class NamecoinCashWallet extends CoinServiceAPI {
|
|||
final features = await electrumXClient.getServerFeatures();
|
||||
Logging.instance.log("features: $features", level: LogLevel.Info);
|
||||
switch (coin) {
|
||||
case Coin.bitcoincash:
|
||||
case Coin.namecoin:
|
||||
if (features['genesis_hash'] != GENESIS_HASH_MAINNET) {
|
||||
throw Exception("genesis hash does not match main net!");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw Exception(
|
||||
"Attempted to generate a BitcoinWallet using a non bitcoin coin type: ${coin.name}");
|
||||
"Attempted to generate a NamecoinWallet using a non namecoin coin type: ${coin.name}");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1840,10 +1828,10 @@ class NamecoinCashWallet extends CoinServiceAPI {
|
|||
|
||||
/// attempts to convert a string to a valid scripthash
|
||||
///
|
||||
/// Returns the scripthash or throws an exception on invalid bch address
|
||||
String _convertToScriptHash(String bchAddress, NetworkType network) {
|
||||
/// Returns the scripthash or throws an exception on invalid namecoin address
|
||||
String _convertToScriptHash(String namecoinAddress, NetworkType network) {
|
||||
try {
|
||||
final output = Address.addressToOutputScript(bchAddress, network);
|
||||
final output = Address.addressToOutputScript(namecoinAddress, network);
|
||||
final hash = sha256.convert(output.toList(growable: false)).toString();
|
||||
|
||||
final chars = hash.split("");
|
||||
|
@ -1937,7 +1925,6 @@ class NamecoinCashWallet extends CoinServiceAPI {
|
|||
unconfirmedCachedTransactions
|
||||
.removeWhere((key, value) => value.confirmedStatus);
|
||||
|
||||
print("CACHED_TRANSACTIONS_IS $cachedTransactions");
|
||||
if (cachedTransactions != null) {
|
||||
for (final tx in allTxHashes.toList(growable: false)) {
|
||||
final txHeight = tx["height"] as int;
|
||||
|
@ -1953,7 +1940,6 @@ class NamecoinCashWallet extends CoinServiceAPI {
|
|||
List<Map<String, dynamic>> allTransactions = [];
|
||||
|
||||
for (final txHash in allTxHashes) {
|
||||
Logging.instance.log("bch: $txHash", level: LogLevel.Info);
|
||||
final tx = await cachedElectrumXClient.getTransaction(
|
||||
txHash: txHash["tx_hash"] as String,
|
||||
verbose: true,
|
||||
|
@ -2325,8 +2311,8 @@ class NamecoinCashWallet extends CoinServiceAPI {
|
|||
vSize: vSizeForOneOutput,
|
||||
feeRatePerKB: selectedTxFeeRate,
|
||||
);
|
||||
if (feeForOneOutput < (vSizeForOneOutput + 1)) {
|
||||
feeForOneOutput = (vSizeForOneOutput + 1);
|
||||
if (feeForOneOutput < (vSizeForOneOutput + 1) * 1000) {
|
||||
feeForOneOutput = (vSizeForOneOutput + 1) * 1000;
|
||||
}
|
||||
|
||||
final int amount = satoshiAmountToSend - feeForOneOutput;
|
||||
|
@ -2382,11 +2368,11 @@ class NamecoinCashWallet extends CoinServiceAPI {
|
|||
.log("feeForTwoOutputs: $feeForTwoOutputs", level: LogLevel.Info);
|
||||
Logging.instance
|
||||
.log("feeForOneOutput: $feeForOneOutput", level: LogLevel.Info);
|
||||
if (feeForOneOutput < (vSizeForOneOutput + 1)) {
|
||||
feeForOneOutput = (vSizeForOneOutput + 1);
|
||||
if (feeForOneOutput < (vSizeForOneOutput + 1) * 1000) {
|
||||
feeForOneOutput = (vSizeForOneOutput + 1) * 1000;
|
||||
}
|
||||
if (feeForTwoOutputs < ((vSizeForTwoOutPuts + 1))) {
|
||||
feeForTwoOutputs = ((vSizeForTwoOutPuts + 1));
|
||||
if (feeForTwoOutputs < ((vSizeForTwoOutPuts + 1) * 1000)) {
|
||||
feeForTwoOutputs = ((vSizeForTwoOutPuts + 1) * 1000);
|
||||
}
|
||||
|
||||
Logging.instance
|
||||
|
@ -2686,76 +2672,45 @@ class NamecoinCashWallet extends CoinServiceAPI {
|
|||
required List<String> recipients,
|
||||
required List<int> satoshiAmounts,
|
||||
}) async {
|
||||
final builder = Bitbox.Bitbox.transactionBuilder();
|
||||
Logging.instance
|
||||
.log("Starting buildTransaction ----------", level: LogLevel.Info);
|
||||
|
||||
// retrieve address' utxos from the rest api
|
||||
List<Bitbox.Utxo> _utxos =
|
||||
[]; // await Bitbox.Address.utxo(address) as List<Bitbox.Utxo>;
|
||||
utxosToUse.forEach((element) {
|
||||
_utxos.add(Bitbox.Utxo(
|
||||
element.txid,
|
||||
element.vout,
|
||||
Bitbox.BitcoinCash.fromSatoshi(element.value),
|
||||
element.value,
|
||||
0,
|
||||
MINIMUM_CONFIRMATIONS + 1));
|
||||
});
|
||||
Logger.print("bch utxos: ${_utxos}");
|
||||
final txb = TransactionBuilder(network: _network);
|
||||
txb.setVersion(1);
|
||||
|
||||
// placeholder for input signatures
|
||||
final signatures = <Map>[];
|
||||
|
||||
// placeholder for total input balance
|
||||
int totalBalance = 0;
|
||||
|
||||
// iterate through the list of address _utxos and use them as inputs for the
|
||||
// withdrawal transaction
|
||||
_utxos.forEach((Bitbox.Utxo utxo) {
|
||||
// add the utxo as an input for the transaction
|
||||
builder.addInput(utxo.txid, utxo.vout);
|
||||
final ec = utxoSigningData[utxo.txid]["keyPair"] as ECPair;
|
||||
|
||||
final bitboxEC = Bitbox.ECPair.fromWIF(ec.toWIF());
|
||||
|
||||
// add a signature to the list to be used later
|
||||
signatures.add({
|
||||
"vin": signatures.length,
|
||||
"key_pair": bitboxEC,
|
||||
"original_amount": utxo.satoshis
|
||||
});
|
||||
|
||||
totalBalance += utxo.satoshis;
|
||||
});
|
||||
|
||||
// calculate the fee based on number of inputs and one expected output
|
||||
final fee =
|
||||
Bitbox.BitcoinCash.getByteCount(signatures.length, recipients.length);
|
||||
|
||||
// calculate how much balance will be left over to spend after the fee
|
||||
final sendAmount = totalBalance - fee;
|
||||
|
||||
// add the output based on the address provided in the testing data
|
||||
for (int i = 0; i < recipients.length; i++) {
|
||||
String recipient = recipients[i];
|
||||
int satoshiAmount = satoshiAmounts[i];
|
||||
builder.addOutput(recipient, satoshiAmount);
|
||||
// Add transaction inputs
|
||||
for (var i = 0; i < utxosToUse.length; i++) {
|
||||
final txid = utxosToUse[i].txid;
|
||||
txb.addInput(txid, utxosToUse[i].vout, null,
|
||||
utxoSigningData[txid]["output"] as Uint8List);
|
||||
}
|
||||
|
||||
// sign all inputs
|
||||
signatures.forEach((signature) {
|
||||
builder.sign(
|
||||
signature["vin"] as int,
|
||||
signature["key_pair"] as Bitbox.ECPair,
|
||||
signature["original_amount"] as int);
|
||||
});
|
||||
// Add transaction output
|
||||
for (var i = 0; i < recipients.length; i++) {
|
||||
txb.addOutput(recipients[i], satoshiAmounts[i]);
|
||||
}
|
||||
|
||||
// build the transaction
|
||||
final tx = builder.build();
|
||||
final txHex = tx.toHex();
|
||||
final vSize = tx.virtualSize();
|
||||
Logger.print("bch raw hex: $txHex");
|
||||
try {
|
||||
// Sign the transaction accordingly
|
||||
for (var i = 0; i < utxosToUse.length; i++) {
|
||||
final txid = utxosToUse[i].txid;
|
||||
txb.sign(
|
||||
vin: i,
|
||||
keyPair: utxoSigningData[txid]["keyPair"] as ECPair,
|
||||
witnessValue: utxosToUse[i].value,
|
||||
redeemScript: utxoSigningData[txid]["redeemScript"] as Uint8List?,
|
||||
);
|
||||
}
|
||||
} catch (e, s) {
|
||||
Logging.instance.log("Caught exception while signing transaction: $e\n$s",
|
||||
level: LogLevel.Error);
|
||||
rethrow;
|
||||
}
|
||||
|
||||
return {"hex": txHex, "vSize": vSize};
|
||||
final builtTx = txb.build();
|
||||
final vSize = builtTx.virtualSize();
|
||||
|
||||
return {"hex": builtTx.toHex(), "vSize": vSize};
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -3018,7 +2973,7 @@ class NamecoinCashWallet extends CoinServiceAPI {
|
|||
}
|
||||
}
|
||||
|
||||
// TODO: correct formula for bch?
|
||||
// TODO: correct formula for nmc?
|
||||
int roughFeeEstimate(int inputCount, int outputCount, int feeRatePerKB) {
|
||||
return ((181 * inputCount) + (34 * outputCount) + 10) *
|
||||
(feeRatePerKB / 1000).ceil();
|
||||
|
@ -3039,10 +2994,39 @@ class NamecoinCashWallet extends CoinServiceAPI {
|
|||
|
||||
return available - estimatedFee;
|
||||
}
|
||||
|
||||
Future<bool> generateNewAddress() async {
|
||||
try {
|
||||
await _incrementAddressIndexForChain(
|
||||
0, DerivePathType.bip44); // First increment the receiving index
|
||||
final newReceivingIndex = DB.instance.get<dynamic>(
|
||||
boxName: walletId,
|
||||
key: 'receivingIndexP2PKH') as int; // Check the new receiving index
|
||||
final newReceivingAddress = await _generateAddressForChain(
|
||||
0,
|
||||
newReceivingIndex,
|
||||
DerivePathType
|
||||
.bip44); // Use new index to derive a new receiving address
|
||||
await _addToAddressesArrayForChain(
|
||||
newReceivingAddress,
|
||||
0,
|
||||
DerivePathType
|
||||
.bip44); // Add that new receiving address to the array of receiving addresses
|
||||
_currentReceivingAddressP2PKH = Future(() =>
|
||||
newReceivingAddress); // Set the new receiving address that the service
|
||||
|
||||
return true;
|
||||
} catch (e, s) {
|
||||
Logging.instance.log(
|
||||
"Exception rethrown from generateNewAddress(): $e\n$s",
|
||||
level: LogLevel.Error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Bitcoincash Network
|
||||
final bitcoincash = NetworkType(
|
||||
// Namecoin Network
|
||||
final namecoin = NetworkType(
|
||||
messagePrefix: '\x18Bitcoin Signed Message:\n',
|
||||
bech32: 'bc',
|
||||
bip32: Bip32Type(public: 0x0488b21e, private: 0x0488ade4),
|
||||
|
|
|
@ -6,6 +6,7 @@ import 'package:flutter_libepiccash/epic_cash.dart';
|
|||
import 'package:stackwallet/services/coins/dogecoin/dogecoin_wallet.dart';
|
||||
import 'package:stackwallet/services/coins/firo/firo_wallet.dart';
|
||||
import 'package:stackwallet/services/coins/bitcoincash/bitcoincash_wallet.dart';
|
||||
import 'package:stackwallet/services/coins/namecoin/namecoin_wallet.dart';
|
||||
import 'package:stackwallet/utilities/enums/coin_enum.dart';
|
||||
import 'package:stackwallet/utilities/logger.dart';
|
||||
|
||||
|
@ -52,6 +53,8 @@ class AddressUtils {
|
|||
case Coin.monero:
|
||||
return RegExp("[a-zA-Z0-9]{95}").hasMatch(address) ||
|
||||
RegExp("[a-zA-Z0-9]{106}").hasMatch(address);
|
||||
case Coin.namecoin:
|
||||
return Address.validateAddress(address, namecoin);
|
||||
case Coin.bitcoinTestNet:
|
||||
return Address.validateAddress(address, testnet);
|
||||
case Coin.firoTestNet:
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import 'package:stackwallet/services/coins/namecoin/namecoin_wallet.dart';
|
||||
import 'package:stackwallet/utilities/enums/coin_enum.dart';
|
||||
|
||||
abstract class Assets {
|
||||
|
@ -110,6 +111,7 @@ class _SVG {
|
|||
String get epicCash => "assets/svg/coin_icons/EpicCash.svg";
|
||||
String get firo => "assets/svg/coin_icons/Firo.svg";
|
||||
String get monero => "assets/svg/coin_icons/Monero.svg";
|
||||
String get namecoin => "assets/svg/coin_icons/Namecoin.svg";
|
||||
|
||||
// TODO provide proper assets
|
||||
String get bitcoinTestnet => "assets/svg/coin_icons/Bitcoin.svg";
|
||||
|
@ -130,6 +132,8 @@ class _SVG {
|
|||
return firo;
|
||||
case Coin.monero:
|
||||
return monero;
|
||||
case Coin.namecoin:
|
||||
return namecoin;
|
||||
case Coin.bitcoinTestNet:
|
||||
return bitcoinTestnet;
|
||||
case Coin.firoTestNet:
|
||||
|
@ -152,6 +156,7 @@ class _PNG {
|
|||
String get bitcoin => "assets/images/bitcoin.png";
|
||||
String get epicCash => "assets/images/epic-cash.png";
|
||||
String get bitcoincash => "assets/images/bitcoincash.png";
|
||||
String get namecoin => "assets/images/bitcoincash.png";
|
||||
|
||||
String imageFor({required Coin coin}) {
|
||||
switch (coin) {
|
||||
|
@ -171,6 +176,8 @@ class _PNG {
|
|||
return firo;
|
||||
case Coin.monero:
|
||||
return monero;
|
||||
case Coin.namecoin:
|
||||
return namecoin;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,5 +24,7 @@ Uri getBlockExplorerTransactionUrlFor({
|
|||
return Uri.parse("https://testexplorer.firo.org/tx/$txid");
|
||||
case Coin.bitcoincash:
|
||||
return Uri.parse("https://blockchair.com/bitcoin-cash/transaction/$txid");
|
||||
case Coin.namecoin:
|
||||
return Uri.parse("uri");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ class _CoinThemeColor {
|
|||
Color get dogecoin => const Color(0xFFFFE079);
|
||||
Color get epicCash => const Color(0xFFC5C7CB);
|
||||
Color get monero => const Color(0xFFFF9E6B);
|
||||
Color get namecoin => const Color(0xFFFCC17B);
|
||||
|
||||
Color forCoin(Coin coin) {
|
||||
switch (coin) {
|
||||
|
@ -29,6 +30,8 @@ class _CoinThemeColor {
|
|||
return firo;
|
||||
case Coin.monero:
|
||||
return monero;
|
||||
case Coin.namecoin:
|
||||
return namecoin;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,6 +46,7 @@ abstract class Constants {
|
|||
case Coin.dogecoinTestNet:
|
||||
case Coin.firoTestNet:
|
||||
case Coin.epicCash:
|
||||
case Coin.namecoin:
|
||||
values.addAll([24, 21, 18, 15, 12]);
|
||||
break;
|
||||
|
||||
|
@ -79,6 +80,9 @@ abstract class Constants {
|
|||
|
||||
case Coin.monero:
|
||||
return 120;
|
||||
|
||||
case Coin.namecoin:
|
||||
return 600;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import 'dart:convert';
|
||||
|
||||
import 'package:stackwallet/models/node_model.dart';
|
||||
import 'package:stackwallet/services/coins/namecoin/namecoin_wallet.dart';
|
||||
import 'package:stackwallet/utilities/enums/coin_enum.dart';
|
||||
|
||||
abstract class DefaultNodes {
|
||||
|
@ -14,6 +15,7 @@ abstract class DefaultNodes {
|
|||
monero,
|
||||
epicCash,
|
||||
bitcoincash,
|
||||
namecoin,
|
||||
bitcoinTestnet,
|
||||
dogecoinTestnet,
|
||||
firoTestnet,
|
||||
|
@ -93,6 +95,18 @@ abstract class DefaultNodes {
|
|||
isDown: false,
|
||||
);
|
||||
|
||||
static NodeModel get namecoin => NodeModel(
|
||||
host: "46.229.238.187",
|
||||
port: 57002,
|
||||
name: defaultName,
|
||||
id: _nodeId(Coin.namecoin),
|
||||
useSSL: true,
|
||||
enabled: true,
|
||||
coinName: Coin.namecoin.name,
|
||||
isFailover: true,
|
||||
isDown: false,
|
||||
);
|
||||
|
||||
static NodeModel get bitcoinTestnet => NodeModel(
|
||||
host: "electrumx-testnet.cypherstack.com",
|
||||
port: 51002,
|
||||
|
@ -149,6 +163,9 @@ abstract class DefaultNodes {
|
|||
case Coin.monero:
|
||||
return monero;
|
||||
|
||||
case Coin.namecoin:
|
||||
return namecoin;
|
||||
|
||||
case Coin.bitcoinTestNet:
|
||||
return bitcoinTestnet;
|
||||
|
||||
|
|
|
@ -7,6 +7,8 @@ import 'package:stackwallet/services/coins/firo/firo_wallet.dart' as firo;
|
|||
import 'package:stackwallet/services/coins/monero/monero_wallet.dart' as xmr;
|
||||
import 'package:stackwallet/services/coins/bitcoincash/bitcoincash_wallet.dart'
|
||||
as bch;
|
||||
import 'package:stackwallet/services/coins/namecoin/namecoin_wallet.dart'
|
||||
as nmc;
|
||||
|
||||
enum Coin {
|
||||
bitcoin,
|
||||
|
@ -69,6 +71,8 @@ extension CoinExt on Coin {
|
|||
return "FIRO";
|
||||
case Coin.monero:
|
||||
return "XMR";
|
||||
case Coin.namecoin:
|
||||
return "NMC";
|
||||
case Coin.bitcoinTestNet:
|
||||
return "tBTC";
|
||||
case Coin.firoTestNet:
|
||||
|
@ -93,6 +97,8 @@ extension CoinExt on Coin {
|
|||
return "firo";
|
||||
case Coin.monero:
|
||||
return "monero";
|
||||
case Coin.namecoin:
|
||||
return "namecoin";
|
||||
case Coin.bitcoinTestNet:
|
||||
return "bitcoin";
|
||||
case Coin.firoTestNet:
|
||||
|
@ -108,6 +114,7 @@ extension CoinExt on Coin {
|
|||
case Coin.bitcoincash:
|
||||
case Coin.dogecoin:
|
||||
case Coin.firo:
|
||||
case Coin.namecoin:
|
||||
case Coin.bitcoinTestNet:
|
||||
case Coin.firoTestNet:
|
||||
case Coin.dogecoinTestNet:
|
||||
|
@ -141,6 +148,8 @@ extension CoinExt on Coin {
|
|||
|
||||
case Coin.monero:
|
||||
return xmr.MINIMUM_CONFIRMATIONS;
|
||||
case Coin.namecoin:
|
||||
return nmc.MINIMUM_CONFIRMATIONS;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -166,6 +175,9 @@ Coin coinFromPrettyName(String name) {
|
|||
case "Monero":
|
||||
case "monero":
|
||||
return Coin.monero;
|
||||
case "Namecoin":
|
||||
case "namecoin":
|
||||
return Coin.namecoin;
|
||||
case "Bitcoin Testnet":
|
||||
case "tBitcoin":
|
||||
case "bitcoinTestNet":
|
||||
|
@ -198,6 +210,8 @@ Coin coinFromTickerCaseInsensitive(String ticker) {
|
|||
return Coin.firo;
|
||||
case "xmr":
|
||||
return Coin.monero;
|
||||
case "nmc":
|
||||
return Coin.namecoin;
|
||||
case "tbtc":
|
||||
return Coin.bitcoinTestNet;
|
||||
case "tfiro":
|
||||
|
|
|
@ -271,6 +271,7 @@ flutter:
|
|||
- assets/svg/coin_icons/EpicCash.svg
|
||||
- assets/svg/coin_icons/Firo.svg
|
||||
- assets/svg/coin_icons/Monero.svg
|
||||
- assets/svg/coin_icons/Namecoin.svg
|
||||
# lottie animations
|
||||
- assets/lottie/test.json
|
||||
- assets/lottie/test2.json
|
||||
|
|
Loading…
Reference in a new issue