feat: add xlm

This commit is contained in:
detherminal 2023-07-19 20:08:46 +03:00 committed by likho
parent 68af283033
commit e0df4723ae
21 changed files with 923 additions and 97 deletions

@ -1 +1 @@
Subproject commit f677dec0b34d3f9fe8fce2bc8ff5c508c3f3bb9a
Subproject commit cd12741de19e4faef39a23b7d543a2452524990a

@ -1 +1 @@
Subproject commit 9cd241b5ea142e21c01dd7639b42603281c43287
Subproject commit ec3cf5e8e1b90e006188aa8c323d4cd52dbfa9b9

@ -1 +1 @@
Subproject commit e48952185556a10f182184fd572bcb04365f5831
Subproject commit 26a152fea3ca4b8c3f1130392a02f579c2ff218c

View file

@ -196,6 +196,8 @@ class _AddEditNodeViewState extends ConsumerState<AddEditNodeView> {
case Coin.nano:
case Coin.banano:
case Coin.stellar:
throw UnimplementedError();
//TODO: check network/node
}
@ -736,6 +738,7 @@ class _NodeFormState extends ConsumerState<NodeForm> {
case Coin.nano:
case Coin.banano:
case Coin.eCash:
case Coin.stellar:
return false;
case Coin.ethereum:

View file

@ -172,6 +172,8 @@ class _NodeDetailsViewState extends ConsumerState<NodeDetailsView> {
case Coin.nano:
case Coin.banano:
case Coin.stellar:
throw UnimplementedError();
//TODO: check network/node
}

View file

@ -27,6 +27,7 @@ import 'package:stackwallet/services/coins/monero/monero_wallet.dart';
import 'package:stackwallet/services/coins/namecoin/namecoin_wallet.dart';
import 'package:stackwallet/services/coins/nano/nano_wallet.dart';
import 'package:stackwallet/services/coins/particl/particl_wallet.dart';
import 'package:stackwallet/services/coins/stellar/stellar_wallet.dart';
import 'package:stackwallet/services/coins/wownero/wownero_wallet.dart';
import 'package:stackwallet/services/transaction_notification_tracker.dart';
import 'package:stackwallet/utilities/amount/amount.dart';
@ -218,6 +219,15 @@ abstract class CoinServiceAPI {
cachedClient: cachedClient,
tracker: tracker);
case Coin.stellar:
return StellarWallet(
walletId: walletId,
walletName: walletName,
coin: coin,
secureStore: secureStorageInterface,
tracker: tracker,
);
case Coin.wownero:
return WowneroWallet(
walletId: walletId,

View file

@ -0,0 +1,656 @@
import 'dart:async';
import 'dart:io';
import 'package:decimal/decimal.dart';
import 'package:http/http.dart' as http;
import 'package:isar/isar.dart';
import 'package:stackwallet/models/balance.dart' as SWBalance;
import 'package:stackwallet/models/isar/models/blockchain_data/transaction.dart' as SWTransaction;
import 'package:stackwallet/models/isar/models/blockchain_data/address.dart' as SWAddress;
import 'package:stackwallet/models/isar/models/blockchain_data/utxo.dart';
import 'package:stackwallet/models/paymint/fee_object_model.dart';
import 'package:stackwallet/pages/wallet_view/sub_widgets/wallet_balance_toggle_sheet.dart';
import 'package:stackwallet/services/coins/coin_service.dart';
import 'package:stackwallet/services/mixins/coin_control_interface.dart';
import 'package:stackwallet/utilities/amount/amount.dart';
import 'package:stackwallet/utilities/enums/fee_rate_type_enum.dart';
import 'package:tuple/tuple.dart';
import '../../../db/isar/main_db.dart';
import '../../../models/node_model.dart';
import '../../../utilities/constants.dart';
import '../../../utilities/default_nodes.dart';
import '../../../utilities/enums/coin_enum.dart';
import '../../../utilities/flutter_secure_storage_interface.dart';
import '../../../utilities/logger.dart';
import '../../../utilities/prefs.dart';
import '../../event_bus/events/global/node_connection_status_changed_event.dart';
import '../../event_bus/events/global/updated_in_background_event.dart';
import '../../event_bus/events/global/wallet_sync_status_changed_event.dart';
import '../../event_bus/global_event_bus.dart';
import '../../mixins/wallet_cache.dart';
import '../../mixins/wallet_db.dart';
import '../../node_service.dart';
import '../../transaction_notification_tracker.dart';
import 'package:stellar_flutter_sdk/stellar_flutter_sdk.dart';
const int MINIMUM_CONFIRMATIONS = 1;
class StellarWallet extends CoinServiceAPI
with WalletCache, WalletDB, CoinControlInterface {
StellarWallet({
required String walletId,
required String walletName,
required Coin coin,
required TransactionNotificationTracker tracker,
required SecureStorageInterface secureStore,
MainDB? mockableOverride,
}) {
txTracker = tracker;
_walletId = walletId;
_walletName = walletName;
_coin = coin;
_secureStore = secureStore;
initCache(walletId, coin);
initWalletDB(mockableOverride: mockableOverride);
}
late final TransactionNotificationTracker txTracker;
late SecureStorageInterface _secureStore;
final StellarSDK stellarSdk = StellarSDK.PUBLIC;
@override
bool get isFavorite => _isFavorite ??= getCachedIsFavorite();
bool? _isFavorite;
@override
set isFavorite(bool isFavorite) {
_isFavorite = isFavorite;
updateCachedIsFavorite(isFavorite);
}
@override
bool get shouldAutoSync => _shouldAutoSync;
bool _shouldAutoSync = true;
Timer? timer;
final _prefs = Prefs.instance;
@override
set shouldAutoSync(bool shouldAutoSync) {
if (_shouldAutoSync != shouldAutoSync) {
_shouldAutoSync = shouldAutoSync;
if (!shouldAutoSync) {
timer?.cancel();
timer = null;
stopNetworkAlivePinging();
} else {
startNetworkAlivePinging();
refresh();
}
}
}
Timer? _networkAliveTimer;
void startNetworkAlivePinging() {
// call once on start right away
_periodicPingCheck();
// then periodically check
_networkAliveTimer = Timer.periodic(
Constants.networkAliveTimerDuration,
(_) async {
_periodicPingCheck();
},
);
}
void stopNetworkAlivePinging() {
_networkAliveTimer?.cancel();
_networkAliveTimer = null;
}
void _periodicPingCheck() async {
bool hasNetwork = await testNetworkConnection();
if (_isConnected != hasNetwork) {
NodeConnectionStatus status = hasNetwork
? NodeConnectionStatus.connected
: NodeConnectionStatus.disconnected;
GlobalEventBus.instance.fire(
NodeConnectionStatusChangedEvent(
status,
walletId,
coin,
),
);
_isConnected = hasNetwork;
if (hasNetwork) {
unawaited(refresh());
}
}
}
@override
String get walletName => _walletName;
late String _walletName;
@override
set walletName(String name) => _walletName = name;
@override
SWBalance.Balance get balance => _balance ??= getCachedBalance();
SWBalance.Balance? _balance;
@override
Coin get coin => _coin;
late Coin _coin;
@override
Future<String> confirmSend({required Map<String, dynamic> txData}) {
// TODO: implement confirmSend
throw UnimplementedError();
}
Future<SWAddress.Address?> get _currentReceivingAddress =>
db.getAddresses(walletId)
.filter()
.typeEqualTo(SWAddress.AddressType.unknown)
.and()
.subTypeEqualTo(SWAddress.AddressSubType.unknown)
.sortByDerivationIndexDesc()
.findFirst();
@override
Future<String> get currentReceivingAddress async =>
(await _currentReceivingAddress)?.value ?? await getAddressSW();
Future<int> getBaseFee() async {
final nodeURI = Uri.parse("${getCurrentNode().host}:${getCurrentNode().port}");
final httpClient = http.Client();
FeeStatsResponse fsp = await FeeStatsRequestBuilder(httpClient, nodeURI).execute();
return int.parse(fsp.lastLedgerBaseFee);
}
@override
Future<Amount> estimateFeeFor(Amount amount, int feeRate) async {
var baseFee = await getBaseFee();
int fee = 100;
switch (feeRate) {
case 0:
fee = baseFee * 10;
case 1:
case 2:
fee = baseFee * 50;
case 3:
fee = baseFee * 100;
case 4:
fee = baseFee * 200;
default:
fee = baseFee * 50;
}
return Amount(rawValue: BigInt.from(fee), fractionDigits: coin.decimals);
}
@override
Future<void> exit() {
// TODO: implement exit
throw UnimplementedError();
}
NodeModel? _xlmNode;
NodeModel getCurrentNode() {
if (_xlmNode != null) {
return _xlmNode!;
} else if (NodeService(secureStorageInterface: _secureStore).getPrimaryNodeFor(coin: coin) != null) {
return NodeService(secureStorageInterface: _secureStore).getPrimaryNodeFor(coin: coin)!;
} else {
return DefaultNodes.getNodeFor(coin);
}
}
@override
Future<FeeObject> get fees async {
final nodeURI = Uri.parse("${getCurrentNode().host}:${getCurrentNode().port}");
final httpClient = http.Client();
FeeStatsResponse fsp = await FeeStatsRequestBuilder(httpClient, nodeURI).execute();
return FeeObject(
numberOfBlocksFast: 0,
numberOfBlocksAverage: 0,
numberOfBlocksSlow: 0,
fast: int.parse(fsp.lastLedgerBaseFee) * 100,
medium: int.parse(fsp.lastLedgerBaseFee) * 50,
slow: int.parse(fsp.lastLedgerBaseFee) * 10
);
}
@override
Future<void> fullRescan(int maxUnusedAddressGap, int maxNumberOfIndexesToCheck) async {
await _prefs.init();
await updateTransactions();
await updateChainHeight();
await updateBalance();
}
@override
Future<bool> generateNewAddress() {
// TODO: implement generateNewAddress
throw UnimplementedError();
}
@override
bool get hasCalledExit => _hasCalledExit;
bool _hasCalledExit = false;
@override
Future<void> initializeExisting() async {
await _prefs.init();
}
@override
Future<void> initializeNew() async {
if ((await mnemonicString) != null || (await mnemonicPassphrase) != null) {
throw Exception(
"Attempted to overwrite mnemonic on generate new wallet!");
}
await _prefs.init();
String mnemonic = await Wallet.generate24WordsMnemonic();
final mnemonicArray = mnemonic.split(" ");
await _secureStore.write(
key: '${_walletId}_mnemonic',
value: mnemonicArray.join(" ")
);
await _secureStore.write(
key: '${_walletId}_mnemonicPassphrase',
value: ""
);
Wallet wallet = await Wallet.from(mnemonic);
KeyPair keyPair = await wallet.getKeyPair(index: 0);
String address = keyPair.accountId;
final swAddress = SWAddress.Address(
walletId: walletId,
value: address,
publicKey: keyPair.publicKey,
derivationIndex: 0,
derivationPath: null,
type: SWAddress.AddressType.unknown, // TODO: set type
subType: SWAddress.AddressSubType.unknown
);
await db.putAddress(swAddress);
await Future.wait([
updateCachedId(walletId),
updateCachedIsFavorite(false)
]);
}
Future<String> getAddressSW() async {
var mnemonic = await _secureStore.read(
key: '${_walletId}_mnemonic'
);
var wallet = await Wallet.from(mnemonic!);
var keyPair = await wallet.getKeyPair(index: 0);
return Future.value(keyPair.accountId);
}
@override
bool get isConnected => _isConnected;
bool _isConnected = false;
@override
bool get isRefreshing => refreshMutex;
bool refreshMutex = false;
@override
// TODO: implement maxFee
Future<int> get maxFee => throw UnimplementedError();
@override
Future<List<String>> get mnemonic => mnemonicString.then((value) => value!.split(" "));
@override
Future<String?> get mnemonicPassphrase => _secureStore.read(key: '${_walletId}_mnemonicPassphrase');
@override
Future<String?> get mnemonicString => _secureStore.read(key: '${_walletId}_mnemonic');
@override
Future<Map<String, dynamic>> prepareSend({required String address, required Amount amount, Map<String, dynamic>? args}) async {
try {
final feeRate = args?["feeRate"];
var fee = 1000;
if (feeRate is FeeRateType) {
final theFees = await fees;
switch (feeRate) {
case FeeRateType.fast:
fee = theFees.fast;
case FeeRateType.slow:
fee = theFees.slow;
case FeeRateType.average:
default:
fee = theFees.medium;
}
}
Map<String, dynamic> txData = {
"fee": fee,
"address": address,
"recipientAmt": amount,
};
Logging.instance.log("prepare send: $txData", level: LogLevel.Info);
return txData;
} catch (e, s) {
Logging.instance.log("Error getting fees $e - $s", level: LogLevel.Error);
rethrow;
}
}
@override
Future<void> recoverFromMnemonic({required String mnemonic, String? mnemonicPassphrase, required int maxUnusedAddressGap, required int maxNumberOfIndexesToCheck, required int height}) async {
if ((await mnemonicString) != null ||
(await this.mnemonicPassphrase) != null) {
throw Exception("Attempted to overwrite mnemonic on restore!");
}
var wallet = await Wallet.from(mnemonic);
var keyPair = await wallet.getKeyPair(index: 0);
var address = keyPair.accountId;
await _secureStore.write(
key: '${_walletId}_mnemonic', value: mnemonic.trim());
await _secureStore.write(
key: '${_walletId}_mnemonicPassphrase',
value: mnemonicPassphrase ?? "",
);
final swAddress = SWAddress.Address(
walletId: walletId,
value: address,
publicKey: keyPair.publicKey,
derivationIndex: 0,
derivationPath: null,
type: SWAddress.AddressType.unknown, // TODO: set type
subType: SWAddress.AddressSubType.unknown
);
await db.putAddress(swAddress);
await Future.wait([
updateCachedId(walletId),
updateCachedIsFavorite(false)
]);
}
Future<void> updateChainHeight() async {
final height = await stellarSdk.ledgers
.order(RequestBuilderOrder.DESC)
.limit(1)
.execute()
.then((value) => value.records!.first.sequence);
await updateCachedChainHeight(height);
}
Future<void> updateTransactions() async {
List<Tuple2<SWTransaction.Transaction, SWAddress.Address?>> transactionList = [];
Page<OperationResponse> payments = await stellarSdk.payments.forAccount(await getAddressSW()).order(RequestBuilderOrder.DESC).execute();
for (OperationResponse response in payments.records!) {
if (response is PaymentOperationResponse) {
var por = response;
SWTransaction.TransactionType type;
if (por.sourceAccount == await getAddressSW()) {
type = SWTransaction.TransactionType.outgoing;
} else {
type = SWTransaction.TransactionType.incoming;
}
final amount = Amount(
rawValue: BigInt.parse(float.parse(por.amount!).toStringAsFixed(7).replaceAll(".", "")),
fractionDigits: 7,
);
int fee = 0;
int height = 0;
var transaction = por.transaction;
if (transaction != null) {
fee = transaction.feeCharged!;
height = transaction.ledger;
}
var theTransaction = SWTransaction.Transaction(
walletId: walletId,
txid: por.transactionHash!,
timestamp: DateTime.parse(por.createdAt!).millisecondsSinceEpoch ~/ 1000,
type: type,
subType: SWTransaction.TransactionSubType.none,
amount: 0,
amountString: amount.toJsonString(),
fee: fee,
height: height,
isCancelled: false,
isLelantus: false,
slateId: "",
otherData: "",
inputs: [],
outputs: [],
nonce: 0,
numberOfMessages: null,
);
SWAddress.Address? receivingAddress = await _currentReceivingAddress;
SWAddress.Address address = type == SWTransaction.TransactionType.incoming
? receivingAddress!
: SWAddress.Address(
walletId: walletId,
value: por.sourceAccount!,
publicKey: KeyPair.fromAccountId(por.sourceAccount!).publicKey,
derivationIndex: 0,
derivationPath: null,
type: SWAddress.AddressType.unknown, // TODO: set type
subType: SWAddress.AddressSubType.unknown
);
Tuple2<SWTransaction.Transaction, SWAddress.Address> tuple = Tuple2(theTransaction, address);
transactionList.add(tuple);
} else if (response is CreateAccountOperationResponse) {
var caor = response;
SWTransaction.TransactionType type;
if (caor.sourceAccount == await getAddressSW()) {
type = SWTransaction.TransactionType.outgoing;
} else {
type = SWTransaction.TransactionType.incoming;
}
final amount = Amount(
rawValue: BigInt.parse(float.parse(caor.startingBalance!).toStringAsFixed(7).replaceAll(".", "")),
fractionDigits: 7,
);
int fee = 0;
int height = 0;
var transaction = caor.transaction;
if (transaction != null) {
fee = transaction.feeCharged!;
height = transaction.ledger;
}
var theTransaction = SWTransaction.Transaction(
walletId: walletId,
txid: caor.transactionHash!,
timestamp: DateTime.parse(caor.createdAt!).millisecondsSinceEpoch ~/ 1000,
type: type,
subType: SWTransaction.TransactionSubType.none,
amount: 0,
amountString: amount.toJsonString(),
fee: fee,
height: height,
isCancelled: false,
isLelantus: false,
slateId: "",
otherData: "",
inputs: [],
outputs: [],
nonce: 0,
numberOfMessages: null,
);
SWAddress.Address? receivingAddress = await _currentReceivingAddress;
SWAddress.Address address = type == SWTransaction.TransactionType.incoming
? receivingAddress!
: SWAddress.Address(
walletId: walletId,
value: caor.sourceAccount!,
publicKey: KeyPair.fromAccountId(caor.sourceAccount!).publicKey,
derivationIndex: 0,
derivationPath: null,
type: SWAddress.AddressType.unknown, // TODO: set type
subType: SWAddress.AddressSubType.unknown
);
Tuple2<SWTransaction.Transaction, SWAddress.Address> tuple = Tuple2(theTransaction, address);
transactionList.add(tuple);
}
}
await db.addNewTransactionData(transactionList, walletId);
}
Future<void> updateBalance() async {
AccountResponse accountResponse = await stellarSdk.accounts.account(await getAddressSW());
for (Balance balance in accountResponse.balances) {
switch (balance.assetType) {
case Asset.TYPE_NATIVE:
_balance = SWBalance.Balance(
total: Amount(
rawValue: BigInt.from(float.parse(balance.balance) * 10000000 - 10000000), // Minus 1 XLM for account activation fee
fractionDigits: 7,
),
spendable: Amount(
rawValue: BigInt.from(float.parse(balance.balance) * 10000000 - 10000000), // Minus 1 XLM for account activation fee
fractionDigits: 7,
),
blockedTotal: Amount(
rawValue: BigInt.from(0),
fractionDigits: 7,
),
pendingSpendable: Amount(
rawValue: BigInt.from(0),
fractionDigits: 7,
),
);
Logging.instance.log(_balance, level: LogLevel.Info);
await updateCachedBalance(_balance!);
}
}
}
@override
Future<void> refresh() async {
if (refreshMutex) {
Logging.instance.log(
"$walletId $walletName refreshMutex denied",
level: LogLevel.Info,
);
return;
} else {
refreshMutex = true;
}
try {
await _prefs.init();
GlobalEventBus.instance.fire(
WalletSyncStatusChangedEvent(
WalletSyncStatus.syncing,
walletId,
coin,
),
);
await updateChainHeight();
await updateTransactions();
await updateBalance();
GlobalEventBus.instance.fire(
WalletSyncStatusChangedEvent(
WalletSyncStatus.synced,
walletId,
coin,
),
);
if (shouldAutoSync) {
timer ??= Timer.periodic(const Duration(seconds: 30), (timer) async {
Logging.instance.log(
"Periodic refresh check for $walletId $walletName in object instance: $hashCode",
level: LogLevel.Info);
await refresh();
GlobalEventBus.instance.fire(
UpdatedInBackgroundEvent(
"New data found in $walletId $walletName in background!",
walletId,
),
);
});
}
} catch (e, s) {
Logging.instance.log(
"Failed to refresh stellar wallet $walletId: '$walletName': $e\n$s",
level: LogLevel.Warning,
);
GlobalEventBus.instance.fire(
WalletSyncStatusChangedEvent(
WalletSyncStatus.unableToSync,
walletId,
coin,
),
);
}
refreshMutex = false;
}
@override
int get storedChainHeight => getCachedChainHeight();
@override
Future<bool> testNetworkConnection() {
// TODO: implement testNetworkConnection
throw UnimplementedError();
}
@override
Future<List<SWTransaction.Transaction>> get transactions => db.getTransactions(walletId).findAll();
@override
Future<void> updateNode(bool shouldRefresh) async {
_xlmNode = NodeService(secureStorageInterface: _secureStore)
.getPrimaryNodeFor(coin: coin) ??
DefaultNodes.getNodeFor(coin);
if (shouldRefresh) {
unawaited(refresh());
}
}
@override
Future<void> updateSentCachedTxData(Map<String, dynamic> txData) {
// TODO: implement updateSentCachedTxData
throw UnimplementedError();
}
@override
// TODO: implement utxos
Future<List<UTXO>> get utxos => throw UnimplementedError();
@override
bool validateAddress(String address) {
return RegExp(r"^[G][A-Z0-9]{55}$").hasMatch(address);
}
@override
String get walletId => _walletId;
late String _walletId;
}

View file

@ -28,6 +28,7 @@ class CoinThemeColorDefault {
Color get namecoin => const Color(0xFF91B1E1);
Color get wownero => const Color(0xFFED80C1);
Color get particl => const Color(0xFF8175BD);
Color get stellar => const Color(0xFFE8E8E8); // TODO: find color
Color get nano => const Color(0xFF209CE9);
Color get banano => const Color(0xFFFBDD11);
@ -62,6 +63,8 @@ class CoinThemeColorDefault {
return wownero;
case Coin.particl:
return particl;
case Coin.stellar:
return stellar;
case Coin.nano:
return nano;
case Coin.banano:

View file

@ -1707,6 +1707,8 @@ class StackColors extends ThemeExtension<StackColors> {
return _coin.wownero;
case Coin.particl:
return _coin.particl;
case Coin.stellar:
return _coin.stellar;
case Coin.nano:
return _coin.nano;
case Coin.banano:

View file

@ -105,6 +105,8 @@ class AddressUtils {
return Address.validateAddress(address, namecoin, namecoin.bech32!);
case Coin.particl:
return Address.validateAddress(address, particl);
case Coin.stellar:
return RegExp(r"^[G][A-Z0-9]{55}$").hasMatch(address);
case Coin.nano:
return NanoAccounts.isValid(NanoAccountType.NANO, address);
case Coin.banano:

View file

@ -50,6 +50,7 @@ enum AmountUnit {
case Coin.dogecoin:
case Coin.eCash:
case Coin.epicCash:
case Coin.stellar: // TODO: check if this is correct
return AmountUnit.values.sublist(0, 4);
case Coin.monero:

View file

@ -54,6 +54,8 @@ Uri getDefaultBlockExplorerUrlFor({
return Uri.parse("https://chainz.cryptoid.info/nmc/tx.dws?$txid.htm");
case Coin.particl:
return Uri.parse("https://chainz.cryptoid.info/part/tx.dws?$txid.htm");
case Coin.stellar:
return Uri.parse("https://stellarchain.io/tx/$txid");
case Coin.nano:
return Uri.parse("https://www.nanolooker.com/block/$txid");
case Coin.banano:

View file

@ -43,6 +43,7 @@ abstract class Constants {
BigInt.parse("1000000000000000000000000000000"); // 1*10^30
static final BigInt _satsPerCoinBanano =
BigInt.parse("100000000000000000000000000000"); // 1*10^29
static final BigInt _satsPerCoinStellar = BigInt.from(10000000); // https://developers.stellar.org/docs/fundamentals-and-concepts/stellar-data-structures/assets#amount-precision
static final BigInt _satsPerCoin = BigInt.from(100000000);
static const int _decimalPlaces = 8;
static const int _decimalPlacesNano = 30;
@ -51,6 +52,7 @@ abstract class Constants {
static const int _decimalPlacesMonero = 12;
static const int _decimalPlacesEthereum = 18;
static const int _decimalPlacesECash = 2;
static const int _decimalPlacesStellar = 7;
static const int notificationsMax = 0xFFFFFFFF;
static const Duration networkAliveTimerDuration = Duration(seconds: 10);
@ -96,6 +98,9 @@ abstract class Constants {
case Coin.eCash:
return _satsPerCoinECash;
case Coin.stellar:
return _satsPerCoinStellar;
}
}
@ -133,6 +138,9 @@ abstract class Constants {
case Coin.eCash:
return _decimalPlacesECash;
case Coin.stellar:
return _decimalPlacesStellar;
}
}
@ -155,6 +163,7 @@ abstract class Constants {
case Coin.namecoin:
case Coin.particl:
case Coin.nano:
case Coin.stellar:
values.addAll([24, 12]);
break;
case Coin.banano:
@ -214,6 +223,9 @@ abstract class Constants {
case Coin.nano: // TODO: Verify this
case Coin.banano: // TODO: Verify this
return 1;
case Coin.stellar:
return 5;
}
}
@ -241,6 +253,7 @@ abstract class Constants {
case Coin.nano:
case Coin.banano:
case Coin.stellar:
return 24;
case Coin.monero:

View file

@ -181,6 +181,18 @@ abstract class DefaultNodes {
isFailover: true,
isDown: false);
static NodeModel get stellar => NodeModel(
host: "https://horizon.stellar.org",
port: 443,
name: defaultName,
id: _nodeId(Coin.stellar),
useSSL: true,
enabled: true,
coinName: Coin.stellar.name,
isFailover: true,
isDown: false
);
static NodeModel get nano => NodeModel(
host: "https://rainstorm.city/api",
port: 443,
@ -301,6 +313,9 @@ abstract class DefaultNodes {
case Coin.particl:
return particl;
case Coin.stellar:
return stellar;
case Coin.nano:
return nano;

View file

@ -27,6 +27,7 @@ import 'package:stackwallet/services/coins/namecoin/namecoin_wallet.dart'
import 'package:stackwallet/services/coins/nano/nano_wallet.dart' as nano;
import 'package:stackwallet/services/coins/particl/particl_wallet.dart'
as particl;
import 'package:stackwallet/services/coins/stellar/stellar_wallet.dart' as xlm;
import 'package:stackwallet/services/coins/wownero/wownero_wallet.dart' as wow;
import 'package:stackwallet/utilities/constants.dart';
@ -44,6 +45,7 @@ enum Coin {
namecoin,
nano,
particl,
stellar,
wownero,
///
@ -84,6 +86,8 @@ extension CoinExt on Coin {
return "Monero";
case Coin.particl:
return "Particl";
case Coin.stellar:
return "Stellar";
case Coin.wownero:
return "Wownero";
case Coin.namecoin:
@ -127,6 +131,8 @@ extension CoinExt on Coin {
return "XMR";
case Coin.particl:
return "PART";
case Coin.stellar:
return "XLM";
case Coin.wownero:
return "WOW";
case Coin.namecoin:
@ -171,6 +177,8 @@ extension CoinExt on Coin {
return "monero";
case Coin.particl:
return "particl";
case Coin.stellar:
return "stellar";
case Coin.wownero:
return "wownero";
case Coin.namecoin:
@ -215,6 +223,7 @@ extension CoinExt on Coin {
case Coin.wownero:
case Coin.nano:
case Coin.banano:
case Coin.stellar:
return false;
}
}
@ -242,6 +251,7 @@ extension CoinExt on Coin {
case Coin.firoTestNet:
case Coin.nano:
case Coin.banano:
case Coin.stellar:
return false;
}
}
@ -262,6 +272,7 @@ extension CoinExt on Coin {
case Coin.nano:
case Coin.banano:
case Coin.eCash:
case Coin.stellar:
return false;
case Coin.dogecoinTestNet:
@ -289,6 +300,7 @@ extension CoinExt on Coin {
case Coin.nano:
case Coin.banano:
case Coin.eCash:
case Coin.stellar:
return this;
case Coin.dogecoinTestNet:
@ -345,6 +357,9 @@ extension CoinExt on Coin {
case Coin.particl:
return particl.MINIMUM_CONFIRMATIONS;
case Coin.stellar:
return xlm.MINIMUM_CONFIRMATIONS;
case Coin.wownero:
return wow.MINIMUM_CONFIRMATIONS;
@ -404,6 +419,10 @@ Coin coinFromPrettyName(String name) {
case "particl":
return Coin.particl;
case "Stellar":
case "stellar":
return Coin.stellar;
case "Namecoin":
case "namecoin":
return Coin.namecoin;
@ -481,6 +500,8 @@ Coin coinFromTickerCaseInsensitive(String ticker) {
return Coin.namecoin;
case "part":
return Coin.particl;
case "xlm":
return Coin.stellar;
case "tltc":
return Coin.litecoinTestNet;
case "tbtc":

View file

@ -49,6 +49,7 @@ extension DerivePathTypeExt on DerivePathType {
case Coin.wownero:
case Coin.nano:
case Coin.banano:
case Coin.stellar:
throw UnsupportedError(
"$coin does not use bitcoin style derivation paths");
}

View file

@ -194,6 +194,8 @@ class _NodeCardState extends ConsumerState<NodeCard> {
case Coin.nano:
case Coin.banano:
case Coin.stellar:
throw UnimplementedError();
//TODO: check network/node
}

View file

@ -177,6 +177,8 @@ class NodeOptionsSheet extends ConsumerWidget {
case Coin.nano:
case Coin.banano:
case Coin.stellar:
throw UnimplementedError();
//TODO: check network/node
}

View file

@ -6,9 +6,6 @@ import FlutterMacOS
import Foundation
import connectivity_plus
import cw_monero
import cw_shared_external
import cw_wownero
import desktop_drop
import device_info_plus
import devicelocale
@ -16,10 +13,10 @@ import flutter_libepiccash
import flutter_local_notifications
import flutter_secure_storage_macos
import isar_flutter_libs
import lelantus
import package_info_plus
import path_provider_foundation
import share_plus
import shared_preferences_foundation
import stack_wallet_backup
import url_launcher_macos
import wakelock_macos
@ -27,9 +24,6 @@ import window_size
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
ConnectivityPlugin.register(with: registry.registrar(forPlugin: "ConnectivityPlugin"))
CwMoneroPlugin.register(with: registry.registrar(forPlugin: "CwMoneroPlugin"))
CwSharedExternalPlugin.register(with: registry.registrar(forPlugin: "CwSharedExternalPlugin"))
CwWowneroPlugin.register(with: registry.registrar(forPlugin: "CwWowneroPlugin"))
DesktopDropPlugin.register(with: registry.registrar(forPlugin: "DesktopDropPlugin"))
DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin"))
DevicelocalePlugin.register(with: registry.registrar(forPlugin: "DevicelocalePlugin"))
@ -37,10 +31,10 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
FlutterLocalNotificationsPlugin.register(with: registry.registrar(forPlugin: "FlutterLocalNotificationsPlugin"))
FlutterSecureStoragePlugin.register(with: registry.registrar(forPlugin: "FlutterSecureStoragePlugin"))
IsarFlutterLibsPlugin.register(with: registry.registrar(forPlugin: "IsarFlutterLibsPlugin"))
LelantusPlugin.register(with: registry.registrar(forPlugin: "LelantusPlugin"))
FLTPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FLTPackageInfoPlusPlugin"))
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
SharePlusMacosPlugin.register(with: registry.registrar(forPlugin: "SharePlusMacosPlugin"))
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
StackWalletBackupPlugin.register(with: registry.registrar(forPlugin: "StackWalletBackupPlugin"))
UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin"))
WakelockMacosPlugin.register(with: registry.registrar(forPlugin: "WakelockMacosPlugin"))

View file

@ -37,18 +37,18 @@ packages:
dependency: transitive
description:
name: args
sha256: c372bb384f273f0c2a8aaaa226dad84dc27c8519a691b888725dec59518ad53a
sha256: eef6c46b622e0494a36c5a12d10d77fb4e855501a91c1b9ef9339326e58f0596
url: "https://pub.dev"
source: hosted
version: "2.4.1"
version: "2.4.2"
asn1lib:
dependency: transitive
description:
name: asn1lib
sha256: ab96a1cb3beeccf8145c52e449233fe68364c9641623acd3adad66f8184f1039
sha256: b74e3842a52c61f8819a1ec8444b4de5419b41a7465e69d4aa681445377398b0
url: "https://pub.dev"
source: hosted
version: "1.4.0"
version: "1.4.1"
async:
dependency: "direct main"
description:
@ -146,10 +146,10 @@ packages:
dependency: transitive
description:
name: build
sha256: "43865b79fbb78532e4bff7c33087aa43b1d488c4fdef014eaef568af6d8016dc"
sha256: "80184af8b6cb3e5c1c4ec6d8544d27711700bc3e6d2efad04238c7b5290889f0"
url: "https://pub.dev"
source: hosted
version: "2.4.0"
version: "2.4.1"
build_config:
dependency: transitive
description:
@ -170,26 +170,26 @@ packages:
dependency: transitive
description:
name: build_resolvers
sha256: db49b8609ef8c81cca2b310618c3017c00f03a92af44c04d310b907b2d692d95
sha256: "6c4dd11d05d056e76320b828a1db0fc01ccd376922526f8e9d6c796a5adbac20"
url: "https://pub.dev"
source: hosted
version: "2.2.0"
version: "2.2.1"
build_runner:
dependency: "direct dev"
description:
name: build_runner
sha256: "220ae4553e50d7c21a17c051afc7b183d28a24a420502e842f303f8e4e6edced"
sha256: "10c6bcdbf9d049a0b666702cf1cee4ddfdc38f02a19d35ae392863b47519848b"
url: "https://pub.dev"
source: hosted
version: "2.4.4"
version: "2.4.6"
build_runner_core:
dependency: transitive
description:
name: build_runner_core
sha256: "88a57f2ac99849362e73878334caa9f06ee25f31d2adced882b8337838c84e1e"
sha256: "6d6ee4276b1c5f34f21fdf39425202712d2be82019983d52f351c94aafbc2c41"
url: "https://pub.dev"
source: hosted
version: "7.2.9"
version: "7.2.10"
built_collection:
dependency: transitive
description:
@ -202,10 +202,10 @@ packages:
dependency: transitive
description:
name: built_value
sha256: "7dd62d9faf105c434f3d829bbe9c4be02ec67f5ed94832222116122df67c5452"
sha256: "598a2a682e2a7a90f08ba39c0aaa9374c5112340f0a2e275f61b59389543d166"
url: "https://pub.dev"
source: hosted
version: "8.6.0"
version: "8.6.1"
characters:
dependency: transitive
description:
@ -242,10 +242,10 @@ packages:
dependency: transitive
description:
name: code_builder
sha256: "0d43dd1288fd145de1ecc9a3948ad4a6d5a82f0a14c4fdd0892260787d975cbe"
sha256: "4ad01d6e56db961d29661561effde45e519939fdaeb46c351275b182eac70189"
url: "https://pub.dev"
source: hosted
version: "4.4.0"
version: "4.5.0"
collection:
dependency: transitive
description:
@ -298,10 +298,10 @@ packages:
dependency: "direct main"
description:
name: crypto
sha256: aa274aa7774f8964e4f4f38cc994db7b6158dd36e9187aaceaddc994b35c6c67
sha256: ff625774173754681d66daaf4a448684fb04b78f902da9cb3d308c19cc5e8bab
url: "https://pub.dev"
source: hosted
version: "3.0.2"
version: "3.0.3"
cryptography:
dependency: transitive
description:
@ -314,10 +314,10 @@ packages:
dependency: transitive
description:
name: csslib
sha256: "831883fb353c8bdc1d71979e5b342c7d88acfbc643113c14ae51e2442ea0f20f"
sha256: "706b5707578e0c1b4b7550f64078f0a0f19dec3f50a178ffae7006b0a9ca58fb"
url: "https://pub.dev"
source: hosted
version: "0.17.3"
version: "1.0.0"
cw_core:
dependency: "direct main"
description:
@ -382,18 +382,18 @@ packages:
dependency: transitive
description:
name: dart_style
sha256: f4f1f73ab3fd2afcbcca165ee601fe980d966af6a21b5970c6c9376955c528ad
sha256: "1efa911ca7086affd35f463ca2fc1799584fb6aa89883cf0af8e3664d6a02d55"
url: "https://pub.dev"
source: hosted
version: "2.3.1"
version: "2.3.2"
dartx:
dependency: transitive
description:
name: dartx
sha256: "45d7176701f16c5a5e00a4798791c1964bc231491b879369c818dd9a9c764871"
sha256: "8b25435617027257d43e6508b5fe061012880ddfdaa75a71d607c3de2a13d244"
url: "https://pub.dev"
source: hosted
version: "1.1.0"
version: "1.2.0"
dbus:
dependency: transitive
description:
@ -406,10 +406,10 @@ packages:
dependency: "direct main"
description:
name: decimal
sha256: eece91944f523657c75a3a008a90ec7f7eb3986191153a78570c7d0ac8ef3d01
sha256: "24a261d5d5c87e86c7651c417a5dbdf8bcd7080dd592533910e8d0505a279f21"
url: "https://pub.dev"
source: hosted
version: "2.3.2"
version: "2.3.3"
dependency_validator:
dependency: "direct dev"
description:
@ -450,14 +450,22 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.6.0"
dio:
dependency: transitive
description:
name: dio
sha256: "3866d67f93523161b643187af65f5ac08bc991a5bcdaf41a2d587fe4ccb49993"
url: "https://pub.dev"
source: hosted
version: "5.3.0"
dropdown_button2:
dependency: "direct main"
description:
name: dropdown_button2
sha256: "374f2390161bf782b4896f0b1b24cbb2b5daaa1cfb11047c3307461dcdf44e07"
sha256: "83c54a5022f898d63e3abe21240b64b937e676103207287e6705d3f9bb04d654"
url: "https://pub.dev"
source: hosted
version: "2.1.3"
version: "2.3.6"
eip1559:
dependency: transitive
description:
@ -542,10 +550,10 @@ packages:
dependency: "direct main"
description:
name: file_picker
sha256: "9d6e95ec73abbd31ec54d0e0df8a961017e165aba1395e462e5b31ea0c165daf"
sha256: b1729fc96627dd44012d0a901558177418818d6bd428df59dcfeb594e5f66432
url: "https://pub.dev"
source: hosted
version: "5.3.1"
version: "5.3.2"
fixnum:
dependency: transitive
description:
@ -606,10 +614,10 @@ packages:
dependency: "direct dev"
description:
name: flutter_lints
sha256: aeb0b80a8b3709709c9cc496cdc027c5b3216796bc0af0ce1007eaf24464fd4c
sha256: "2118df84ef0c3ca93f96123a616ae8540879991b8b57af2f81b76a7ada49b2a4"
url: "https://pub.dev"
source: hosted
version: "2.0.1"
version: "2.0.2"
flutter_local_notifications:
dependency: "direct main"
description:
@ -670,10 +678,10 @@ packages:
dependency: "direct main"
description:
name: flutter_rounded_date_picker
sha256: e7143cc5cbf3aec1536286653e38b0809abc99fb76c91bd910dbd98ae003d890
sha256: e6aa2dc5d3b44e8bbe85ef901be69eac59ba4136427f11f4c8b2a303e1e774e7
url: "https://pub.dev"
source: hosted
version: "3.0.3"
version: "3.0.4"
flutter_secure_storage:
dependency: "direct main"
description:
@ -821,10 +829,10 @@ packages:
dependency: transitive
description:
name: html
sha256: "58e3491f7bf0b6a4ea5110c0c688877460d1a6366731155c4a4580e7ded773e8"
sha256: "3a7812d5bcd2894edf53dfaf8cd640876cf6cef50a8f238745c8b8120ea74d3a"
url: "https://pub.dev"
source: hosted
version: "0.15.3"
version: "0.15.4"
http:
dependency: "direct main"
description:
@ -948,15 +956,15 @@ packages:
path: "crypto_plugins/flutter_liblelantus"
relative: true
source: path
version: "0.0.2"
version: "0.0.1"
lints:
dependency: transitive
description:
name: lints
sha256: "6b0206b0bf4f04961fc5438198ccb3a885685cd67d4d4a32cc20ad7f8adbe015"
sha256: "0a217c6c989d21039f1498c3ed9f3ed71b354e69873f13a8dfc3c9fe76f1b452"
url: "https://pub.dev"
source: hosted
version: "2.1.0"
version: "2.1.1"
local_auth:
dependency: "direct main"
description:
@ -977,10 +985,10 @@ packages:
dependency: "direct main"
description:
name: lottie
sha256: "23522951540d20a57a60202ed7022e6376bed206a4eee1c347a91f58bd57eb9f"
sha256: "0793a5866062e5cc8a8b24892fa94c3095953ea914a7fdf790f550dd7537fe60"
url: "https://pub.dev"
source: hosted
version: "2.3.2"
version: "2.5.0"
matcher:
dependency: transitive
description:
@ -1033,10 +1041,10 @@ packages:
dependency: "direct dev"
description:
name: mockito
sha256: "8b46d7eb40abdda92d62edd01546051f0c27365e65608c284de336dccfef88cc"
sha256: "7d5b53bcd556c1bc7ffbe4e4d5a19c3e112b7e925e9e172dd7c6ad0630812616"
url: "https://pub.dev"
source: hosted
version: "5.4.1"
version: "5.4.2"
mocktail:
dependency: transitive
description:
@ -1145,10 +1153,10 @@ packages:
dependency: transitive
description:
name: path_provider_foundation
sha256: "1995d88ec2948dac43edf8fe58eb434d35d22a2940ecee1a9fefcd62beee6eb3"
sha256: "916731ccbdce44d545414dd9961f26ba5fbaa74bcbb55237d8e65a623a8c7297"
url: "https://pub.dev"
source: hosted
version: "2.2.3"
version: "2.2.4"
path_provider_linux:
dependency: transitive
description:
@ -1169,50 +1177,50 @@ packages:
dependency: transitive
description:
name: path_provider_windows
sha256: d3f80b32e83ec208ac95253e0cd4d298e104fbc63cb29c5c69edaed43b0c69d6
sha256: "1cb68ba4cd3a795033de62ba1b7b4564dace301f952de6bfb3cd91b202b6ee96"
url: "https://pub.dev"
source: hosted
version: "2.1.6"
version: "2.1.7"
permission_handler:
dependency: "direct main"
description:
name: permission_handler
sha256: "33c6a1253d1f95fd06fa74b65b7ba907ae9811f9d5c1d3150e51417d04b8d6a8"
sha256: "63e5216aae014a72fe9579ccd027323395ce7a98271d9defa9d57320d001af81"
url: "https://pub.dev"
source: hosted
version: "10.2.0"
version: "10.4.3"
permission_handler_android:
dependency: transitive
description:
name: permission_handler_android
sha256: d8cc6a62ded6d0f49c6eac337e080b066ee3bce4d405bd9439a61e1f1927bfe8
sha256: "2ffaf52a21f64ac9b35fe7369bb9533edbd4f698e5604db8645b1064ff4cf221"
url: "https://pub.dev"
source: hosted
version: "10.2.1"
version: "10.3.3"
permission_handler_apple:
dependency: transitive
description:
name: permission_handler_apple
sha256: ee96ac32f5a8e6f80756e25b25b9f8e535816c8e6665a96b6d70681f8c4f7e85
sha256: "99e220bce3f8877c78e4ace901082fb29fa1b4ebde529ad0932d8d664b34f3f5"
url: "https://pub.dev"
source: hosted
version: "9.0.8"
version: "9.1.4"
permission_handler_platform_interface:
dependency: transitive
description:
name: permission_handler_platform_interface
sha256: "68abbc472002b5e6dfce47fe9898c6b7d8328d58b5d2524f75e277c07a97eb84"
sha256: "7c6b1500385dd1d2ca61bb89e2488ca178e274a69144d26bbd65e33eae7c02a9"
url: "https://pub.dev"
source: hosted
version: "3.9.0"
version: "3.11.3"
permission_handler_windows:
dependency: transitive
description:
name: permission_handler_windows
sha256: f67cab14b4328574938ecea2db3475dad7af7ead6afab6338772c5f88963e38b
sha256: cc074aace208760f1eee6aa4fae766b45d947df85bc831cde77009cdb4720098
url: "https://pub.dev"
source: hosted
version: "0.1.2"
version: "0.1.3"
petitparser:
dependency: transitive
description:
@ -1221,6 +1229,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "5.4.0"
pinenacl:
dependency: transitive
description:
name: pinenacl
sha256: "3a5503637587d635647c93ea9a8fecf48a420cc7deebe6f1fc85c2a5637ab327"
url: "https://pub.dev"
source: hosted
version: "0.5.1"
platform:
dependency: transitive
description:
@ -1233,10 +1249,10 @@ packages:
dependency: transitive
description:
name: plugin_platform_interface
sha256: "6a2128648c854906c53fa8e33986fc0247a1116122f9534dd20e3ab9e16a32bc"
sha256: "43798d895c929056255600343db8f049921cbec94d31ec87f1dc5c16c01935dd"
url: "https://pub.dev"
source: hosted
version: "2.1.4"
version: "2.1.5"
pointycastle:
dependency: "direct main"
description:
@ -1349,6 +1365,62 @@ packages:
url: "https://pub.dev"
source: hosted
version: "3.2.1"
shared_preferences:
dependency: transitive
description:
name: shared_preferences
sha256: "0344316c947ffeb3a529eac929e1978fcd37c26be4e8468628bac399365a3ca1"
url: "https://pub.dev"
source: hosted
version: "2.2.0"
shared_preferences_android:
dependency: transitive
description:
name: shared_preferences_android
sha256: fe8401ec5b6dcd739a0fe9588802069e608c3fdbfd3c3c93e546cf2f90438076
url: "https://pub.dev"
source: hosted
version: "2.2.0"
shared_preferences_foundation:
dependency: transitive
description:
name: shared_preferences_foundation
sha256: f39696b83e844923b642ce9dd4bd31736c17e697f6731a5adf445b1274cf3cd4
url: "https://pub.dev"
source: hosted
version: "2.3.2"
shared_preferences_linux:
dependency: transitive
description:
name: shared_preferences_linux
sha256: "71d6806d1449b0a9d4e85e0c7a917771e672a3d5dc61149cc9fac871115018e1"
url: "https://pub.dev"
source: hosted
version: "2.3.0"
shared_preferences_platform_interface:
dependency: transitive
description:
name: shared_preferences_platform_interface
sha256: "23b052f17a25b90ff2b61aad4cc962154da76fb62848a9ce088efe30d7c50ab1"
url: "https://pub.dev"
source: hosted
version: "2.3.0"
shared_preferences_web:
dependency: transitive
description:
name: shared_preferences_web
sha256: "7347b194fb0bbeb4058e6a4e87ee70350b6b2b90f8ac5f8bd5b3a01548f6d33a"
url: "https://pub.dev"
source: hosted
version: "2.2.0"
shared_preferences_windows:
dependency: transitive
description:
name: shared_preferences_windows
sha256: f95e6a43162bce43c9c3405f3eb6f39e5b5d11f65fab19196cf8225e2777624d
url: "https://pub.dev"
source: hosted
version: "2.3.0"
shelf:
dependency: transitive
description:
@ -1390,18 +1462,18 @@ packages:
dependency: transitive
description:
name: source_gen
sha256: "373f96cf5a8744bc9816c1ff41cf5391bbdbe3d7a96fe98c622b6738a8a7bd33"
sha256: fc0da689e5302edb6177fdd964efcb7f58912f43c28c2047a808f5bfff643d16
url: "https://pub.dev"
source: hosted
version: "1.3.2"
version: "1.4.0"
source_helper:
dependency: transitive
description:
name: source_helper
sha256: "3b67aade1d52416149c633ba1bb36df44d97c6b51830c2198e934e3fca87ca1f"
sha256: "6adebc0006c37dd63fe05bca0a929b99f06402fc95aa35bf36d67f5c06de01fd"
url: "https://pub.dev"
source: hosted
version: "1.3.3"
version: "1.3.4"
source_map_stack_trace:
dependency: transitive
description:
@ -1451,6 +1523,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.7.2+1"
stellar_flutter_sdk:
dependency: "direct main"
description:
name: stellar_flutter_sdk
sha256: "7a9b7dc76018bbd0b9c828045cf0e26e07ec44208fb1a1733273de2390205475"
url: "https://pub.dev"
source: hosted
version: "1.6.0"
stream_channel:
dependency: transitive
description:
@ -1555,14 +1635,22 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.0.1"
toml:
dependency: transitive
description:
name: toml
sha256: "69756bc12eccf279b72217a87310d217efc4b3752f722e890f672801f19ac485"
url: "https://pub.dev"
source: hosted
version: "0.13.1"
tuple:
dependency: "direct main"
description:
name: tuple
sha256: "0ea99cd2f9352b2586583ab2ce6489d1f95a5f6de6fb9492faaf97ae2060f0aa"
sha256: a97ce2013f240b2f3807bcbaf218765b6f301c3eff91092bcfa23a039e7dd151
url: "https://pub.dev"
source: hosted
version: "2.0.1"
version: "2.0.2"
typed_data:
dependency: transitive
description:
@ -1579,22 +1667,30 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.2.2"
unorm_dart:
dependency: transitive
description:
name: unorm_dart
sha256: "5b35bff83fce4d76467641438f9e867dc9bcfdb8c1694854f230579d68cd8f4b"
url: "https://pub.dev"
source: hosted
version: "0.2.0"
url_launcher:
dependency: "direct main"
description:
name: url_launcher
sha256: eb1e00ab44303d50dd487aab67ebc575456c146c6af44422f9c13889984c00f3
sha256: "781bd58a1eb16069412365c98597726cd8810ae27435f04b3b4d3a470bacd61e"
url: "https://pub.dev"
source: hosted
version: "6.1.11"
version: "6.1.12"
url_launcher_android:
dependency: transitive
description:
name: url_launcher_android
sha256: eed4e6a1164aa9794409325c3b707ff424d4d1c2a785e7db67f8bbda00e36e51
sha256: "78cb6dea3e93148615109e58e42c35d1ffbf5ef66c44add673d0ab75f12ff3af"
url: "https://pub.dev"
source: hosted
version: "6.0.35"
version: "6.0.37"
url_launcher_ios:
dependency: transitive
description:
@ -1615,34 +1711,34 @@ packages:
dependency: transitive
description:
name: url_launcher_macos
sha256: "91ee3e75ea9dadf38036200c5d3743518f4a5eb77a8d13fda1ee5764373f185e"
sha256: "1c4fdc0bfea61a70792ce97157e5cc17260f61abbe4f39354513f39ec6fd73b1"
url: "https://pub.dev"
source: hosted
version: "3.0.5"
version: "3.0.6"
url_launcher_platform_interface:
dependency: transitive
description:
name: url_launcher_platform_interface
sha256: "6c9ca697a5ae218ce56cece69d46128169a58aa8653c1b01d26fcd4aad8c4370"
sha256: bfdfa402f1f3298637d71ca8ecfe840b4696698213d5346e9d12d4ab647ee2ea
url: "https://pub.dev"
source: hosted
version: "2.1.2"
version: "2.1.3"
url_launcher_web:
dependency: transitive
description:
name: url_launcher_web
sha256: "6bb1e5d7fe53daf02a8fee85352432a40b1f868a81880e99ec7440113d5cfcab"
sha256: cc26720eefe98c1b71d85f9dc7ef0cada5132617046369d9dc296b3ecaa5cbb4
url: "https://pub.dev"
source: hosted
version: "2.0.17"
version: "2.0.18"
url_launcher_windows:
dependency: transitive
description:
name: url_launcher_windows
sha256: "254708f17f7c20a9c8c471f67d86d76d4a3f9c1591aad1e15292008aceb82771"
sha256: "7967065dd2b5fccc18c653b97958fdf839c5478c28e767c61ee879f4e7882422"
url: "https://pub.dev"
source: hosted
version: "3.0.6"
version: "3.0.7"
uuid:
dependency: "direct main"
description:
@ -1768,18 +1864,18 @@ packages:
dependency: transitive
description:
name: win32
sha256: "5a751eddf9db89b3e5f9d50c20ab8612296e4e8db69009788d6c8b060a84191c"
sha256: dfdf0136e0aa7a1b474ea133e67cb0154a0acd2599c4f3ada3b49d38d38793ee
url: "https://pub.dev"
source: hosted
version: "4.1.4"
version: "5.0.5"
win32_registry:
dependency: transitive
description:
name: win32_registry
sha256: "1c52f994bdccb77103a6231ad4ea331a244dbcef5d1f37d8462f713143b0bfae"
sha256: e4506d60b7244251bc59df15656a3093501c37fb5af02105a944d73eb95be4c9
url: "https://pub.dev"
source: hosted
version: "1.1.0"
version: "1.1.1"
window_size:
dependency: "direct main"
description:
@ -1831,4 +1927,4 @@ packages:
version: "1.0.0"
sdks:
dart: ">=3.0.2 <4.0.0"
flutter: ">=3.10.3"
flutter: ">=3.10.0"

View file

@ -138,6 +138,7 @@ dependencies:
desktop_drop: ^0.4.1
nanodart: ^2.0.0
basic_utils: ^5.5.4
stellar_flutter_sdk: ^1.5.8
dev_dependencies:
flutter_test: