untested: ltc refactor

This commit is contained in:
julian 2024-01-04 18:37:46 -06:00
parent 611237ecdf
commit af25da5a59
20 changed files with 3899 additions and 3674 deletions

View file

@ -13,11 +13,11 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_svg/svg.dart';
import 'package:stackwallet/pages/ordinals/widgets/ordinals_list.dart';
import 'package:stackwallet/providers/global/wallets_provider.dart';
import 'package:stackwallet/services/mixins/ordinals_interface.dart';
import 'package:stackwallet/themes/stack_colors.dart';
import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/show_loading.dart';
import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/wallets/wallet/wallet_mixin_interfaces/ordinals_interface.dart';
import 'package:stackwallet/widgets/background.dart';
import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';

View file

@ -13,11 +13,11 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_svg/svg.dart';
import 'package:stackwallet/pages/ordinals/widgets/ordinals_list.dart';
import 'package:stackwallet/providers/providers.dart';
import 'package:stackwallet/services/mixins/ordinals_interface.dart';
import 'package:stackwallet/themes/stack_colors.dart';
import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/show_loading.dart';
import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/wallets/wallet/wallet_mixin_interfaces/ordinals_interface.dart';
import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
import 'package:stackwallet/widgets/desktop/desktop_app_bar.dart';
import 'package:stackwallet/widgets/desktop/desktop_scaffold.dart';
@ -213,7 +213,6 @@ class _DesktopOrdinals extends ConsumerState<DesktopOrdinalsView> {
isDesktop: true,
whileFuture: Future.wait<void>([
Future.delayed(const Duration(seconds: 2)),
// TODO: [prio=high] FIX CAST as ISSUE
(ref.read(pWallets).getWallet(widget.walletId)
as OrdinalsInterface)
.refreshInscriptions()

View file

@ -16,7 +16,6 @@ import 'package:stackwallet/models/node_model.dart';
import 'package:stackwallet/models/paymint/fee_object_model.dart';
import 'package:stackwallet/services/coins/epiccash/epiccash_wallet.dart';
import 'package:stackwallet/services/coins/ethereum/ethereum_wallet.dart';
import 'package:stackwallet/services/coins/litecoin/litecoin_wallet.dart';
import 'package:stackwallet/services/coins/monero/monero_wallet.dart';
import 'package:stackwallet/services/coins/namecoin/namecoin_wallet.dart';
import 'package:stackwallet/services/coins/particl/particl_wallet.dart';
@ -85,26 +84,10 @@ abstract class CoinServiceAPI {
throw UnimplementedError("moved");
case Coin.litecoin:
return LitecoinWallet(
walletId: walletId,
walletName: walletName,
coin: coin,
secureStore: secureStorageInterface,
client: client,
cachedClient: cachedClient,
tracker: tracker,
);
throw UnimplementedError("moved");
case Coin.litecoinTestNet:
return LitecoinWallet(
walletId: walletId,
walletName: walletName,
coin: coin,
secureStore: secureStorageInterface,
client: client,
cachedClient: cachedClient,
tracker: tracker,
);
throw UnimplementedError("moved");
case Coin.bitcoinTestNet:
throw UnimplementedError("moved");

File diff suppressed because it is too large Load diff

View file

@ -1,94 +1,48 @@
import 'dart:async';
import 'package:isar/isar.dart';
import 'package:stackwallet/db/isar/main_db.dart';
import 'package:stackwallet/dto/ordinals/inscription_data.dart';
import 'package:stackwallet/models/isar/models/blockchain_data/utxo.dart';
import 'package:stackwallet/models/isar/ordinal.dart';
import 'package:stackwallet/services/litescribe_api.dart';
import 'package:stackwallet/utilities/enums/coin_enum.dart';
mixin OrdinalsInterface {
late final String _walletId;
late final Coin _coin;
late final MainDB _db;
void initOrdinalsInterface({
required String walletId,
required Coin coin,
required MainDB db,
}) {
_walletId = walletId;
_coin = coin;
_db = db;
}
final LitescribeAPI litescribeAPI =
LitescribeAPI(baseUrl: 'https://litescribe.io/api');
Future<void> refreshInscriptions() async {
final uniqueAddresses = await _db
.getUTXOs(_walletId)
.filter()
.addressIsNotNull()
.distinctByAddress()
.addressProperty()
.findAll();
final inscriptions =
await _getInscriptionDataFromAddresses(uniqueAddresses.cast<String>());
final ords = inscriptions
.map((e) => Ordinal.fromInscriptionData(e, _walletId))
.toList();
await _db.isar.writeTxn(() async {
await _db.isar.ordinals
.where()
.filter()
.walletIdEqualTo(_walletId)
.deleteAll();
await _db.isar.ordinals.putAll(ords);
});
}
Future<List<InscriptionData>> _getInscriptionDataFromAddresses(
List<String> addresses) async {
List<InscriptionData> allInscriptions = [];
for (String address in addresses) {
try {
var inscriptions =
await litescribeAPI.getInscriptionsByAddress(address);
allInscriptions.addAll(inscriptions);
} catch (e) {
throw Exception("Error fetching inscriptions for address $address: $e");
}
}
return allInscriptions;
}
// check if an inscription is in a given <UTXO> output
Future<bool> inscriptionInOutput(UTXO output) async {
if (output.address != null) {
var inscriptions =
await litescribeAPI.getInscriptionsByAddress("${output.address}");
if (inscriptions.isNotEmpty) {
return true;
} else {
return false;
}
} else {
throw UnimplementedError(
'TODO look up utxo without address. utxo->txid:output->address');
}
}
// check if an inscription is in a given <UTXO> output
Future<bool> inscriptionInAddress(String address) async {
var inscriptions = await litescribeAPI.getInscriptionsByAddress(address);
if (inscriptions.isNotEmpty) {
return true;
} else {
return false;
}
}
// late final String _walletId;
// late final Coin _coin;
// late final MainDB _db;
//
// void initOrdinalsInterface({
// required String walletId,
// required Coin coin,
// required MainDB db,
// }) {
// _walletId = walletId;
// _coin = coin;
// _db = db;
// }
//
// final LitescribeAPI litescribeAPI =
// LitescribeAPI(baseUrl: 'https://litescribe.io/api');
//
//
//
//
//
// // // check if an inscription is in a given <UTXO> output
// // Future<bool> inscriptionInOutput(UTXO output) async {
// // if (output.address != null) {
// // var inscriptions =
// // await litescribeAPI.getInscriptionsByAddress("${output.address}");
// // if (inscriptions.isNotEmpty) {
// // return true;
// // } else {
// // return false;
// // }
// // } else {
// // throw UnimplementedError(
// // 'TODO look up utxo without address. utxo->txid:output->address');
// // }
// // }
//
// // check if an inscription is in a given <UTXO> output
// Future<bool> inscriptionInAddress(String address) async {
// var inscriptions = await litescribeAPI.getInscriptionsByAddress(address);
// if (inscriptions.isNotEmpty) {
// return true;
// } else {
// return false;
// }
// }
}

View file

@ -67,11 +67,13 @@ class BitcoinWallet extends Bip39HDWallet
}
@override
({String? blockedReason, bool blocked}) checkBlockUTXO(
Future<({String? blockedReason, bool blocked, String? utxoLabel})>
checkBlockUTXO(
Map<String, dynamic> jsonUTXO,
String? scriptPubKeyHex,
Map<String, dynamic>? jsonTX,
) {
String? utxoOwnerAddress,
) async {
bool blocked = false;
String? blockedReason;
@ -97,7 +99,7 @@ class BitcoinWallet extends Bip39HDWallet
}
}
return (blockedReason: blockedReason, blocked: blocked);
return (blockedReason: blockedReason, blocked: blocked, utxoLabel: null);
}
@override

View file

@ -303,11 +303,13 @@ class BitcoincashWallet extends Bip39HDWallet
}
@override
({String? blockedReason, bool blocked}) checkBlockUTXO(
Future<({String? blockedReason, bool blocked, String? utxoLabel})>
checkBlockUTXO(
Map<String, dynamic> jsonUTXO,
String? scriptPubKeyHex,
Map<String, dynamic> jsonTX,
) {
String? utxoOwnerAddress,
) async {
bool blocked = false;
String? blockedReason;
@ -337,7 +339,7 @@ class BitcoincashWallet extends Bip39HDWallet
}
}
return (blockedReason: blockedReason, blocked: blocked);
return (blockedReason: blockedReason, blocked: blocked, utxoLabel: null);
}
// TODO: correct formula for bch?

View file

@ -63,11 +63,13 @@ class DogecoinWallet extends Bip39HDWallet
}
@override
({String? blockedReason, bool blocked}) checkBlockUTXO(
Future<({String? blockedReason, bool blocked, String? utxoLabel})>
checkBlockUTXO(
Map<String, dynamic> jsonUTXO,
String? scriptPubKeyHex,
Map<String, dynamic> jsonTX,
) {
String? utxoOwnerAddress,
) async {
bool blocked = false;
String? blockedReason;
@ -91,7 +93,7 @@ class DogecoinWallet extends Bip39HDWallet
}
}
return (blockedReason: blockedReason, blocked: blocked);
return (blockedReason: blockedReason, blocked: blocked, utxoLabel: null);
}
@override

View file

@ -298,11 +298,13 @@ class EcashWallet extends Bip39HDWallet
}
@override
({String? blockedReason, bool blocked}) checkBlockUTXO(
Future<({String? blockedReason, bool blocked, String? utxoLabel})>
checkBlockUTXO(
Map<String, dynamic> jsonUTXO,
String? scriptPubKeyHex,
Map<String, dynamic> jsonTX,
) {
String? utxoOwnerAddress,
) async {
bool blocked = false;
String? blockedReason;
@ -332,7 +334,7 @@ class EcashWallet extends Bip39HDWallet
}
}
return (blockedReason: blockedReason, blocked: blocked);
return (blockedReason: blockedReason, blocked: blocked, utxoLabel: null);
}
// TODO: correct formula for ecash?

View file

@ -57,13 +57,13 @@ class EpiccashWallet extends Bip39Wallet {
}
@override
Future<void> updateUTXOs() {
Future<bool> updateUTXOs() {
// TODO: implement updateUTXOs
throw UnimplementedError();
}
@override
Future<void> updateNode() {
Future<bool> updateNode() {
// TODO: implement updateNode
throw UnimplementedError();
}

View file

@ -494,11 +494,13 @@ class FiroWallet extends Bip39HDWallet
}
@override
({String? blockedReason, bool blocked}) checkBlockUTXO(
Future<({String? blockedReason, bool blocked, String? utxoLabel})>
checkBlockUTXO(
Map<String, dynamic> jsonUTXO,
String? scriptPubKeyHex,
Map<String, dynamic>? jsonTX,
) {
String? utxoOwnerAddress,
) async {
bool blocked = false;
String? blockedReason;
//
@ -524,7 +526,7 @@ class FiroWallet extends Bip39HDWallet
// }
// }
//
return (blockedReason: blockedReason, blocked: blocked);
return (blockedReason: blockedReason, blocked: blocked, utxoLabel: null);
}
@override

View file

@ -0,0 +1,143 @@
import 'package:isar/isar.dart';
import 'package:stackwallet/models/isar/models/blockchain_data/address.dart';
import 'package:stackwallet/utilities/amount/amount.dart';
import 'package:stackwallet/wallets/crypto_currency/coins/litecoin.dart';
import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
import 'package:stackwallet/wallets/wallet/intermediate/bip39_hd_wallet.dart';
import 'package:stackwallet/wallets/wallet/wallet_mixin_interfaces/coin_control_interface.dart';
import 'package:stackwallet/wallets/wallet/wallet_mixin_interfaces/electrumx_interface.dart';
import 'package:stackwallet/wallets/wallet/wallet_mixin_interfaces/ordinals_interface.dart';
import 'package:tuple/tuple.dart';
class LitecoinWallet extends Bip39HDWallet
with ElectrumXInterface, CoinControlInterface, OrdinalsInterface {
@override
int get isarTransactionVersion => 1; // TODO actually set this to 2
LitecoinWallet(CryptoCurrencyNetwork network) : super(Litecoin(network));
@override
FilterOperation? get changeAddressFilterOperation =>
FilterGroup.and(standardChangeAddressFilters);
@override
FilterOperation? get receivingAddressFilterOperation =>
FilterGroup.and(standardReceivingAddressFilters);
// ===========================================================================
@override
Future<List<Address>> fetchAddressesForElectrumXScan() async {
final allAddresses = await mainDB
.getAddresses(walletId)
.filter()
.not()
.group(
(q) => q
.typeEqualTo(AddressType.nonWallet)
.or()
.subTypeEqualTo(AddressSubType.nonWallet),
)
.findAll();
return allAddresses;
}
// ===========================================================================
@override
Future<void> updateTransactions() async {
final currentChainHeight = await fetchChainHeight();
// TODO: [prio=med] switch to V2 transactions
final data = await fetchTransactionsV1(
addresses: await fetchAddressesForElectrumXScan(),
currentChainHeight: currentChainHeight,
);
await mainDB.addNewTransactionData(
data
.map((e) => Tuple2(
e.transaction,
e.address,
))
.toList(),
walletId,
);
}
@override
Amount roughFeeEstimate(int inputCount, int outputCount, int feeRatePerKB) {
return Amount(
rawValue: BigInt.from(
((42 + (272 * inputCount) + (128 * outputCount)) / 4).ceil() *
(feeRatePerKB / 1000).ceil()),
fractionDigits: cryptoCurrency.fractionDigits,
);
}
@override
int estimateTxFee({required int vSize, required int feeRatePerKB}) {
return vSize * (feeRatePerKB / 1000).ceil();
}
//
// @override
// Future<TxData> coinSelection({required TxData txData}) async {
// final isCoinControl = txData.utxos != null;
// final isSendAll = txData.amount == info.cachedBalance.spendable;
//
// final utxos =
// txData.utxos?.toList() ?? await mainDB.getUTXOs(walletId).findAll();
//
// final currentChainHeight = await chainHeight;
// final List<UTXO> spendableOutputs = [];
// int spendableSatoshiValue = 0;
//
// // Build list of spendable outputs and totaling their satoshi amount
// for (final utxo in utxos) {
// if (utxo.isBlocked == false &&
// utxo.isConfirmed(currentChainHeight, cryptoCurrency.minConfirms) &&
// utxo.used != true) {
// spendableOutputs.add(utxo);
// spendableSatoshiValue += utxo.value;
// }
// }
//
// if (isCoinControl && spendableOutputs.length < utxos.length) {
// throw ArgumentError("Attempted to use an unavailable utxo");
// }
//
// if (spendableSatoshiValue < txData.amount!.raw.toInt()) {
// throw Exception("Insufficient balance");
// } else if (spendableSatoshiValue == txData.amount!.raw.toInt() &&
// !isSendAll) {
// throw Exception("Insufficient balance to pay transaction fee");
// }
//
// if (isCoinControl) {
// } else {
// final selection = cs.coinSelection(
// spendableOutputs
// .map((e) => cs.InputModel(
// i: e.vout,
// txid: e.txid,
// value: e.value,
// address: e.address,
// ))
// .toList(),
// txData.recipients!
// .map((e) => cs.OutputModel(
// address: e.address,
// value: e.amount.raw.toInt(),
// ))
// .toList(),
// txData.feeRateAmount!,
// 10, // TODO: ???????????????????????????????
// );
//
// // .inputs and .outputs will be null if no solution was found
// if (selection.inputs!.isEmpty || selection.outputs!.isEmpty) {
// throw Exception("coin selection failed");
// }
// }
// }
}

View file

@ -599,7 +599,8 @@ class TezosWallet extends Bip39Wallet<Tezos> {
}
@override
Future<void> updateUTXOs() async {
Future<bool> updateUTXOs() async {
// do nothing. Not used in tezos
return false;
}
}

View file

@ -1,7 +1,7 @@
import 'package:stackwallet/wallets/crypto_currency/intermediate/cryptonote_currency.dart';
import 'package:stackwallet/wallets/models/tx_data.dart';
import 'package:stackwallet/wallets/wallet/wallet_mixin_interfaces/mnemonic_interface.dart';
import 'package:stackwallet/wallets/wallet/wallet.dart';
import 'package:stackwallet/wallets/wallet/wallet_mixin_interfaces/mnemonic_interface.dart';
abstract class CryptonoteWallet<T extends CryptonoteCurrency> extends Wallet<T>
with MnemonicInterface<T> {
@ -28,7 +28,8 @@ abstract class CryptonoteWallet<T extends CryptonoteCurrency> extends Wallet<T>
}
@override
Future<void> updateUTXOs() async {
Future<bool> updateUTXOs() async {
// do nothing for now
return false;
}
}

View file

@ -29,6 +29,7 @@ import 'package:stackwallet/wallets/wallet/impl/dogecoin_wallet.dart';
import 'package:stackwallet/wallets/wallet/impl/ecash_wallet.dart';
import 'package:stackwallet/wallets/wallet/impl/epiccash_wallet.dart';
import 'package:stackwallet/wallets/wallet/impl/firo_wallet.dart';
import 'package:stackwallet/wallets/wallet/impl/litecoin_wallet.dart';
import 'package:stackwallet/wallets/wallet/impl/nano_wallet.dart';
import 'package:stackwallet/wallets/wallet/impl/tezos_wallet.dart';
import 'package:stackwallet/wallets/wallet/impl/wownero_wallet.dart';
@ -273,6 +274,11 @@ abstract class Wallet<T extends CryptoCurrency> {
case Coin.firoTestNet:
return FiroWallet(CryptoCurrencyNetwork.test);
case Coin.litecoin:
return LitecoinWallet(CryptoCurrencyNetwork.main);
case Coin.litecoinTestNet:
return LitecoinWallet(CryptoCurrencyNetwork.test);
case Coin.nano:
return NanoWallet(CryptoCurrencyNetwork.main);
@ -360,9 +366,11 @@ abstract class Wallet<T extends CryptoCurrency> {
Future<void> updateNode();
Future<void> updateTransactions();
Future<void> updateUTXOs();
Future<void> updateBalance();
// returns true if new utxos were added to local db
Future<bool> updateUTXOs();
/// updates the wallet info's cachedChainHeight
Future<void> updateChainHeight();

View file

@ -647,6 +647,7 @@ mixin ElectrumXInterface on Bip39HDWallet {
utxoSigningData[i].utxo.vout,
null,
utxoSigningData[i].output!,
cryptoCurrency.networkParams.bech32Hrp,
);
}
@ -655,6 +656,7 @@ mixin ElectrumXInterface on Bip39HDWallet {
txb.addOutput(
txData.recipients![i].address,
txData.recipients![i].amount.raw.toInt(),
cryptoCurrency.networkParams.bech32Hrp,
);
}
@ -666,6 +668,7 @@ mixin ElectrumXInterface on Bip39HDWallet {
keyPair: utxoSigningData[i].keyPair!,
witnessValue: utxoSigningData[i].utxo.value,
redeemScript: utxoSigningData[i].redeemScript,
overridePrefix: cryptoCurrency.networkParams.bech32Hrp,
);
}
} catch (e, s) {
@ -674,7 +677,7 @@ mixin ElectrumXInterface on Bip39HDWallet {
rethrow;
}
final builtTx = txb.build();
final builtTx = txb.build(cryptoCurrency.networkParams.bech32Hrp);
final vSize = builtTx.virtualSize();
return txData.copyWith(
@ -1051,14 +1054,19 @@ mixin ElectrumXInterface on Bip39HDWallet {
}
}
final checkBlockResult = checkBlockUTXO(jsonUTXO, scriptPubKey, txn);
final checkBlockResult = await checkBlockUTXO(
jsonUTXO,
scriptPubKey,
txn,
utxoOwnerAddress,
);
final utxo = UTXO(
walletId: walletId,
txid: txn["txid"] as String,
vout: vout,
value: jsonUTXO["value"] as int,
name: "",
name: checkBlockResult.utxoLabel ?? "",
isBlocked: checkBlockResult.blocked,
blockedReason: checkBlockResult.blockedReason,
isCoinbase: txn["is_coinbase"] as bool? ?? false,
@ -1650,7 +1658,7 @@ mixin ElectrumXInterface on Bip39HDWallet {
}
@override
Future<void> updateUTXOs() async {
Future<bool> updateUTXOs() async {
final allAddresses = await fetchAddressesForElectrumXScan();
try {
@ -1710,12 +1718,13 @@ mixin ElectrumXInterface on Bip39HDWallet {
}
}
await mainDB.updateUTXOs(walletId, outputArray);
return await mainDB.updateUTXOs(walletId, outputArray);
} catch (e, s) {
Logging.instance.log(
"Output fetch unsuccessful: $e\n$s",
level: LogLevel.Error,
);
return false;
}
}
@ -1870,10 +1879,12 @@ mixin ElectrumXInterface on Bip39HDWallet {
/// Certain coins need to check if the utxo should be marked
/// as blocked as well as give a reason.
({String? blockedReason, bool blocked}) checkBlockUTXO(
Future<({String? blockedReason, bool blocked, String? utxoLabel})>
checkBlockUTXO(
Map<String, dynamic> jsonUTXO,
String? scriptPubKeyHex,
Map<String, dynamic> jsonTX,
String? utxoOwnerAddress,
);
// ===========================================================================

View file

@ -651,8 +651,9 @@ mixin NanoInterface<T extends NanoCurrency> on Bip39Wallet<T> {
FilterGroup.and(standardReceivingAddressFilters);
@override
Future<void> updateUTXOs() async {
Future<bool> updateUTXOs() async {
// do nothing for nano based coins
return false;
}
@override

View file

@ -0,0 +1,109 @@
import 'package:isar/isar.dart';
import 'package:stackwallet/dto/ordinals/inscription_data.dart';
import 'package:stackwallet/models/isar/models/blockchain_data/utxo.dart';
import 'package:stackwallet/models/isar/ordinal.dart';
import 'package:stackwallet/services/litescribe_api.dart';
import 'package:stackwallet/wallets/wallet/wallet_mixin_interfaces/electrumx_interface.dart';
mixin OrdinalsInterface on ElectrumXInterface {
final LitescribeAPI litescribeAPI =
LitescribeAPI(baseUrl: 'https://litescribe.io/api');
// check if an inscription is in a given <UTXO> output
Future<bool> _inscriptionInAddress(String address) async {
var inscriptions = await litescribeAPI.getInscriptionsByAddress(address);
if (inscriptions.isNotEmpty) {
return true;
} else {
return false;
}
}
Future<void> refreshInscriptions() async {
final uniqueAddresses = await mainDB
.getUTXOs(walletId)
.filter()
.addressIsNotNull()
.distinctByAddress()
.addressProperty()
.findAll();
final inscriptions =
await _getInscriptionDataFromAddresses(uniqueAddresses.cast<String>());
final ords = inscriptions
.map((e) => Ordinal.fromInscriptionData(e, walletId))
.toList();
await mainDB.isar.writeTxn(() async {
await mainDB.isar.ordinals
.where()
.filter()
.walletIdEqualTo(walletId)
.deleteAll();
await mainDB.isar.ordinals.putAll(ords);
});
}
// =================== Overrides =============================================
@override
Future<({bool blocked, String? blockedReason, String? utxoLabel})>
checkBlockUTXO(
Map<String, dynamic> jsonUTXO,
String? scriptPubKeyHex,
Map<String, dynamic> jsonTX,
String? utxoOwnerAddress,
) async {
bool shouldBlock = false;
String? blockReason;
String? label;
final utxoAmount = jsonUTXO["value"] as int;
// TODO: [prio=med] check following 3 todos
// TODO check the specific output, not just the address in general
// TODO optimize by freezing output in OrdinalsInterface, so one ordinal API calls is made (or at least many less)
if (utxoOwnerAddress != null) {
if (await _inscriptionInAddress(utxoOwnerAddress)) {
shouldBlock = true;
blockReason = "Ordinal";
label = "Ordinal detected at address";
}
} else {
// TODO implement inscriptionInOutput
if (utxoAmount <= 10000) {
shouldBlock = true;
blockReason = "May contain ordinal";
label = "Possible ordinal";
}
}
return (blockedReason: blockReason, blocked: shouldBlock, utxoLabel: label);
}
@override
Future<bool> updateUTXOs() async {
final newUtxosAdded = await super.updateUTXOs();
if (newUtxosAdded) {
await refreshInscriptions();
}
return newUtxosAdded;
}
// ===================== Private =============================================
Future<List<InscriptionData>> _getInscriptionDataFromAddresses(
List<String> addresses) async {
List<InscriptionData> allInscriptions = [];
for (String address in addresses) {
try {
var inscriptions =
await litescribeAPI.getInscriptionsByAddress(address);
allInscriptions.addAll(inscriptions);
} catch (e) {
throw Exception("Error fetching inscriptions for address $address: $e");
}
}
return allInscriptions;
}
}

View file

@ -280,7 +280,7 @@ packages:
source: git
version: "1.1.0"
coinlib_flutter:
dependency: "direct overridden"
dependency: "direct dev"
description:
path: coinlib_flutter
ref: "4f549b8b511a63fdc1f44796ab43b10f586635cd"

View file

@ -186,6 +186,11 @@ dev_dependencies:
import_sorter: ^4.6.0
flutter_lints: ^2.0.1
isar_generator: 3.0.5
coinlib_flutter:
git:
url: https://github.com/cypherstack/coinlib.git
path: coinlib_flutter
ref: 4f549b8b511a63fdc1f44796ab43b10f586635cd
flutter_launcher_icons:
android: true