diff --git a/lib/dto/ordinals/address_inscription_response.dart b/lib/dto/ordinals/address_inscription_response.dart new file mode 100644 index 000000000..240374284 --- /dev/null +++ b/lib/dto/ordinals/address_inscription_response.dart @@ -0,0 +1,39 @@ +import 'package:stackwallet/dto/ordinals/litescribe_response.dart'; +import 'package:stackwallet/dto/ordinals/inscription_data.dart'; + +class AddressInscriptionResponse extends LitescribeResponse<AddressInscriptionResponse> { + final int status; + final String message; + final AddressInscriptionResult result; + + AddressInscriptionResponse({ + required this.status, + required this.message, + required this.result, + }); + + factory AddressInscriptionResponse.fromJson(Map<String, dynamic> json) { + return AddressInscriptionResponse( + status: json['status'] as int, + message: json['message'] as String, + result: AddressInscriptionResult.fromJson(json['result'] as Map<String, dynamic>), + ); + } +} + +class AddressInscriptionResult { + final List<InscriptionData> list; + final int total; + + AddressInscriptionResult({ + required this.list, + required this.total, + }); + + factory AddressInscriptionResult.fromJson(Map<String, dynamic> json) { + return AddressInscriptionResult( + list: (json['list'] as List).map((item) => InscriptionData.fromJson(item as Map<String, dynamic>)).toList(), + total: json['total'] as int, + ); + } +} diff --git a/lib/dto/ordinals/inscription_data.dart b/lib/dto/ordinals/inscription_data.dart new file mode 100644 index 000000000..b7bba8697 --- /dev/null +++ b/lib/dto/ordinals/inscription_data.dart @@ -0,0 +1,53 @@ +// inscription data from litescribe /address/inscriptions endpoint +class InscriptionData { + final String inscriptionId; + final int inscriptionNumber; + final String address; + final String preview; + final String content; + final int contentLength; + final String contentType; + final String contentBody; + final int timestamp; + final String genesisTransaction; + final String location; + final String output; + final int outputValue; + final int offset; + + InscriptionData({ + required this.inscriptionId, + required this.inscriptionNumber, + required this.address, + required this.preview, + required this.content, + required this.contentLength, + required this.contentType, + required this.contentBody, + required this.timestamp, + required this.genesisTransaction, + required this.location, + required this.output, + required this.outputValue, + required this.offset, + }); + + factory InscriptionData.fromJson(Map<String, dynamic> json) { + return InscriptionData( + inscriptionId: json['inscriptionId'] as String, + inscriptionNumber: json['inscriptionNumber'] as int, + address: json['address'] as String, + preview: json['preview'] as String, + content: json['content'] as String, + contentLength: json['contentLength'] as int, + contentType: json['contentType'] as String, + contentBody: json['contentBody'] as String, + timestamp: json['timestamp'] as int, + genesisTransaction: json['genesisTransaction'] as String, + location: json['location'] as String, + output: json['output'] as String, + outputValue: json['outputValue'] as int, + offset: json['offset'] as int, + ); + } +} diff --git a/lib/dto/ordinals/litescribe_response.dart b/lib/dto/ordinals/litescribe_response.dart new file mode 100644 index 000000000..bebd5ce10 --- /dev/null +++ b/lib/dto/ordinals/litescribe_response.dart @@ -0,0 +1,6 @@ +class LitescribeResponse<T> { + final T? data; + final String? error; + + LitescribeResponse({this.data, this.error}); +} diff --git a/lib/models/ordinal.dart b/lib/models/ordinal.dart index 1feb98b9d..66a69de94 100644 --- a/lib/models/ordinal.dart +++ b/lib/models/ordinal.dart @@ -1,26 +1,29 @@ -enum OrdCollection { - punks, - moonbirds, -} +import 'package:stackwallet/dto/ordinals/inscription_data.dart'; class Ordinal { - final String name; - final String inscription; - final String rank; - final OrdCollection collection; + final String inscriptionId; + final int inscriptionNumber; + final String content; // following two are used to look up the UTXO object in isar combined w/ walletId final String utxoTXID; final int utxoVOUT; - // TODO: make a proper Isar class instead of this placeholder - Ordinal({ - required this.name, - required this.inscription, - required this.rank, - required this.collection, + required this.inscriptionId, + required this.inscriptionNumber, + required this.content, required this.utxoTXID, required this.utxoVOUT, }); -} + + factory Ordinal.fromInscriptionData(InscriptionData data) { + return Ordinal( + inscriptionId: data.inscriptionId, + inscriptionNumber: data.inscriptionNumber, + content: data.content, + utxoTXID: data.output.split(':')[0], // "output": "062f32e21aa04246b8873b5d9a929576addd0339881e1ea478b406795d6b6c47:0" + utxoVOUT: int.parse(data.output.split(':')[1]), + ); + } +} \ No newline at end of file diff --git a/lib/pages/ordinals/ordinal_details_view.dart b/lib/pages/ordinals/ordinal_details_view.dart index 2057e8792..95cff734e 100644 --- a/lib/pages/ordinals/ordinal_details_view.dart +++ b/lib/pages/ordinals/ordinal_details_view.dart @@ -3,6 +3,7 @@ import 'dart:async'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_svg/flutter_svg.dart'; +import 'package:stackwallet/dto/ordinals/inscription_data.dart'; import 'package:stackwallet/models/ordinal.dart'; import 'package:stackwallet/notifications/show_flush_bar.dart'; import 'package:stackwallet/pages/ordinals/widgets/dialogs.dart'; @@ -17,10 +18,10 @@ import 'package:stackwallet/widgets/rounded_white_container.dart'; class OrdinalDetailsView extends StatefulWidget { const OrdinalDetailsView({ - super.key, + Key? key, required this.walletId, required this.ordinal, - }); + }) : super(key: key); final String walletId; final Ordinal ordinal; @@ -28,7 +29,7 @@ class OrdinalDetailsView extends StatefulWidget { static const routeName = "/ordinalDetailsView"; @override - State<OrdinalDetailsView> createState() => _OrdinalDetailsViewState(); + _OrdinalDetailsViewState createState() => _OrdinalDetailsViewState(); } class _OrdinalDetailsViewState extends State<OrdinalDetailsView> { @@ -40,10 +41,10 @@ class _OrdinalDetailsViewState extends State<OrdinalDetailsView> { child: SafeArea( child: Scaffold( backgroundColor: - Theme.of(context).extension<StackColors>()!.background, + Theme.of(context).extension<StackColors>()!.background, appBar: AppBar( backgroundColor: - Theme.of(context).extension<StackColors>()!.background, + Theme.of(context).extension<StackColors>()!.background, leading: const AppBarBackButton(), title: Text( "Ordinal details", @@ -67,14 +68,14 @@ class _OrdinalDetailsViewState extends State<OrdinalDetailsView> { ), _DetailsItemWCopy( title: "Inscription number", - data: widget.ordinal.inscription, + data: widget.ordinal.inscriptionNumber.toString(), ), const SizedBox( height: _spacing, ), _DetailsItemWCopy( - title: "Rank", - data: widget.ordinal.rank, + title: "ID", + data: widget.ordinal.inscriptionId, ), const SizedBox( height: _spacing, @@ -83,23 +84,23 @@ class _OrdinalDetailsViewState extends State<OrdinalDetailsView> { const SizedBox( height: _spacing, ), - _DetailsItemWCopy( + const _DetailsItemWCopy( title: "Amount", - data: "FIXME", + data: "TODO", // TODO infer from utxo utxoTXID:utxoVOUT ), const SizedBox( height: _spacing, ), - _DetailsItemWCopy( + const _DetailsItemWCopy( title: "Owner address", - data: "FIXME", + data: "TODO", // infer from address associated w utxoTXID ), const SizedBox( height: _spacing, ), _DetailsItemWCopy( title: "Transaction ID", - data: "FIXME", + data: widget.ordinal.utxoTXID, ), const SizedBox( height: _spacing, @@ -116,10 +117,10 @@ class _OrdinalDetailsViewState extends State<OrdinalDetailsView> { class _DetailsItemWCopy extends StatelessWidget { const _DetailsItemWCopy({ - super.key, + Key? key, required this.title, required this.data, - }); + }) : super(key: key); final String title; final String data; @@ -153,7 +154,7 @@ class _DetailsItemWCopy extends StatelessWidget { child: SvgPicture.asset( Assets.svg.copy, color: - Theme.of(context).extension<StackColors>()!.infoItemIcons, + Theme.of(context).extension<StackColors>()!.infoItemIcons, width: 12, ), ), @@ -174,10 +175,10 @@ class _DetailsItemWCopy extends StatelessWidget { class _OrdinalImageGroup extends StatelessWidget { const _OrdinalImageGroup({ - super.key, + Key? key, required this.walletId, required this.ordinal, - }); + }) : super(key: key); final String walletId; final Ordinal ordinal; @@ -190,17 +191,25 @@ class _OrdinalImageGroup extends StatelessWidget { mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.center, children: [ - Text( - ordinal.name, - style: STextStyles.w600_16(context), - ), - const SizedBox( - height: _spacing, - ), + // Text( + // "${ordinal.inscriptionId}", // Use any other property you want + // style: STextStyles.w600_16(context), + // ), + // const SizedBox( + // height: _spacing, + // ), AspectRatio( aspectRatio: 1, - child: Container( - color: Colors.red, + child: AspectRatio( + aspectRatio: 1, + child: Container( + color: Colors.red, + child: Image.network( + ordinal.content, // Use the preview URL as the image source + fit: BoxFit.cover, + filterQuality: FilterQuality.none, // Set the filter mode to nearest + ), + ), ), ), const SizedBox( diff --git a/lib/pages/ordinals/ordinals_view.dart b/lib/pages/ordinals/ordinals_view.dart index fe60b5e28..a4adfa019 100644 --- a/lib/pages/ordinals/ordinals_view.dart +++ b/lib/pages/ordinals/ordinals_view.dart @@ -14,6 +14,8 @@ import 'package:flutter_svg/svg.dart'; import 'package:stackwallet/models/ordinal.dart'; import 'package:stackwallet/pages/ordinals/ordinals_filter_view.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/constants.dart'; @@ -44,14 +46,24 @@ class _OrdinalsViewState extends ConsumerState<OrdinalsView> { late final FocusNode searchFocus; String _searchTerm = ""; + dynamic _manager; @override void initState() { searchController = TextEditingController(); searchFocus = FocusNode(); + super.initState(); } + @override + void didChangeDependencies() { + super.didChangeDependencies(); + // Set _manager here when the widget's dependencies change + _manager = ref.watch(walletsChangeNotifierProvider + .select((value) => value.getManager(widget.walletId))); + } + @override void dispose() { searchController.dispose(); @@ -87,8 +99,8 @@ class _OrdinalsViewState extends ConsumerState<OrdinalsView> { .extension<StackColors>()! .topNavIconPrimary, ), - onPressed: () { - // todo refresh + onPressed: () async { + (_manager.wallet as OrdinalsInterface).refreshInscriptions(); }, ), ), @@ -181,14 +193,7 @@ class _OrdinalsViewState extends ConsumerState<OrdinalsView> { Expanded( child: OrdinalsList( walletId: widget.walletId, - ordinals: [ - for (int i = 0; i < 13; i++) - Ordinal( - name: "dummy name $i", - inscription: "insc$i", - rank: "r$i", - ), - ], + ordinalsFuture: (_manager.wallet as OrdinalsInterface).getOrdinals(), ), ), ], diff --git a/lib/pages/ordinals/widgets/ordinal_card.dart b/lib/pages/ordinals/widgets/ordinal_card.dart index a3419ae87..4ac4fd877 100644 --- a/lib/pages/ordinals/widgets/ordinal_card.dart +++ b/lib/pages/ordinals/widgets/ordinal_card.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; + import 'package:stackwallet/models/ordinal.dart'; import 'package:stackwallet/pages/ordinals/ordinal_details_view.dart'; import 'package:stackwallet/utilities/text_styles.dart'; @@ -6,10 +7,10 @@ import 'package:stackwallet/widgets/rounded_white_container.dart'; class OrdinalCard extends StatelessWidget { const OrdinalCard({ - super.key, + Key? key, required this.walletId, required this.ordinal, - }); + }) : super(key: key); final String walletId; final Ordinal ordinal; @@ -27,27 +28,27 @@ class OrdinalCard extends StatelessWidget { child: Column( crossAxisAlignment: CrossAxisAlignment.center, children: [ - AspectRatio( - aspectRatio: 1, - child: Container( + AspectRatio( + aspectRatio: 1, + child: Container( color: Colors.red, - child: const Center( - child: Text( - "replace red container with image", - ), + child: Image.network( + ordinal.content, // Use the preview URL as the image source + fit: BoxFit.cover, + filterQuality: FilterQuality.none, // Set the filter mode to nearest ), ), ), const Spacer(), Text( - ordinal.name, + 'INSC. ${ordinal.inscriptionNumber}', // infer from address associated with utxoTXID style: STextStyles.w500_12(context), ), - const Spacer(), - Text( - "INSC. ${ordinal.inscription} RANK ${ordinal.rank}", - style: STextStyles.w500_8(context), - ), + // const Spacer(), + // Text( + // "ID ${ordinal.inscriptionId}", + // style: STextStyles.w500_8(context), + // ), ], ), ); diff --git a/lib/pages/ordinals/widgets/ordinals_list.dart b/lib/pages/ordinals/widgets/ordinals_list.dart index ca7c71446..62d620130 100644 --- a/lib/pages/ordinals/widgets/ordinals_list.dart +++ b/lib/pages/ordinals/widgets/ordinals_list.dart @@ -1,39 +1,49 @@ import 'package:flutter/material.dart'; import 'package:stackwallet/models/ordinal.dart'; + import 'package:stackwallet/pages/ordinals/widgets/ordinal_card.dart'; -class OrdinalsList extends StatefulWidget { +class OrdinalsList extends StatelessWidget { const OrdinalsList({ - super.key, + Key? key, required this.walletId, - required this.ordinals, - }); + required this.ordinalsFuture, + }) : super(key: key); final String walletId; - final List<Ordinal> ordinals; + final Future<List<Ordinal>> ordinalsFuture; - @override - State<OrdinalsList> createState() => _OrdinalsListState(); -} - -class _OrdinalsListState extends State<OrdinalsList> { - static const spacing = 10.0; + get spacing => 2.0; @override Widget build(BuildContext context) { - return GridView.builder( - shrinkWrap: true, - itemCount: widget.ordinals.length, - gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( - crossAxisSpacing: spacing, - mainAxisSpacing: spacing, - crossAxisCount: 2, - childAspectRatio: 3 / 4, - ), - itemBuilder: (_, i) => OrdinalCard( - walletId: widget.walletId, - ordinal: widget.ordinals[i], - ), + return FutureBuilder<List<Ordinal>>( + future: ordinalsFuture, + builder: (context, snapshot) { + if (snapshot.connectionState == ConnectionState.waiting) { + return const CircularProgressIndicator(); + } else if (snapshot.hasError) { + return Text('Error: ${snapshot.error}'); + } else if (snapshot.hasData) { + final List<Ordinal> ordinals = snapshot.data!; + return GridView.builder( + shrinkWrap: true, + itemCount: ordinals.length, + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( + crossAxisSpacing: spacing as double, + mainAxisSpacing: spacing as double, + crossAxisCount: 2, + childAspectRatio: 6 / 7, // was 3/4, less data displayed now + ), + itemBuilder: (_, i) => OrdinalCard( + walletId: walletId, + ordinal: ordinals[i], + ), + ); + } else { + return const Text('No data found.'); + } + }, ); } -} +} \ No newline at end of file diff --git a/lib/route_generator.dart b/lib/route_generator.dart index 6217cf201..7c0807caf 100644 --- a/lib/route_generator.dart +++ b/lib/route_generator.dart @@ -12,13 +12,15 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:isar/isar.dart'; +import 'package:stackwallet/dto/ordinals/inscription_data.dart'; import 'package:stackwallet/models/add_wallet_list_entity/add_wallet_list_entity.dart'; import 'package:stackwallet/models/add_wallet_list_entity/sub_classes/eth_token_entity.dart'; import 'package:stackwallet/models/buy/response_objects/quote.dart'; import 'package:stackwallet/models/exchange/incomplete_exchange.dart'; import 'package:stackwallet/models/exchange/response_objects/trade.dart'; +import 'package:stackwallet/models/isar/models/contact_entry.dart'; import 'package:stackwallet/models/isar/models/isar_models.dart'; -import 'package:stackwallet/models/ordinal.dart'; +import 'package:stackwallet/models/ordinal.dart'; // TODO generalize InscriptionData -> Ordinal import 'package:stackwallet/models/paynym/paynym_account_lite.dart'; import 'package:stackwallet/models/send_view_auto_fill_data.dart'; import 'package:stackwallet/pages/add_wallet_views/add_token_view/add_custom_token_view.dart'; @@ -168,8 +170,6 @@ import 'package:stackwallet/utilities/enums/coin_enum.dart'; import 'package:stackwallet/widgets/choose_coin_view.dart'; import 'package:tuple/tuple.dart'; -import 'models/isar/models/contact_entry.dart'; - /* * This file contains all the routes for the app. * To add a new route, add it to the switch statement in the generateRoute method. diff --git a/lib/services/coins/litecoin/litecoin_wallet.dart b/lib/services/coins/litecoin/litecoin_wallet.dart index 2edc32fc6..944182abd 100644 --- a/lib/services/coins/litecoin/litecoin_wallet.dart +++ b/lib/services/coins/litecoin/litecoin_wallet.dart @@ -136,6 +136,7 @@ class LitecoinWallet extends CoinServiceAPI _secureStore = secureStore; initCache(walletId, coin); initWalletDB(mockableOverride: mockableOverride); + initOrdinalsInterface(walletId:walletId, coin: coin, db: db); initCoinControlInterface( walletId: walletId, walletName: walletName, diff --git a/lib/services/litescribe_api.dart b/lib/services/litescribe_api.dart new file mode 100644 index 000000000..d5cd3d733 --- /dev/null +++ b/lib/services/litescribe_api.dart @@ -0,0 +1,68 @@ +import 'dart:convert'; +import 'package:http/http.dart' as http; + +import 'package:stackwallet/dto/ordinals/inscription_data.dart'; +import 'package:stackwallet/dto/ordinals/litescribe_response.dart'; + +class LitescribeAPI { + static final LitescribeAPI _instance = LitescribeAPI._internal(); + + factory LitescribeAPI({required String baseUrl}) { + _instance.baseUrl = baseUrl; + return _instance; + } + + LitescribeAPI._internal(); + + late String baseUrl; + + Future<LitescribeResponse> _getResponse(String endpoint) async { + final response = await http.get(Uri.parse('$baseUrl$endpoint')); + if (response.statusCode == 200) { + return LitescribeResponse(data: _validateJson(response.body)); + } else { + throw Exception('LitescribeAPI _getResponse exception: Failed to load data'); + } + } + + Map<String, dynamic> _validateJson(String responseBody) { + final parsed = jsonDecode(responseBody); + if (parsed is Map<String, dynamic>) { + return parsed; + } else { + throw const FormatException('LitescribeAPI _validateJson exception: Invalid JSON format'); + } + } + + Future<List<InscriptionData>> getInscriptionsByAddress(String address, {int cursor = 0, int size = 1000}) async { + // size param determines how many inscriptions are returned per response + // default of 1000 is used to cover most addresses (I assume) + // if the total number of inscriptions at the address exceeds the length of the list of inscriptions returned, another call with a higher size is made + final int defaultLimit = 1000; + final response = await _getResponse('/address/inscriptions?address=$address&cursor=$cursor&size=$size'); + + // Check if the number of returned inscriptions equals the limit + final list = response.data['result']['list']; + final int total = response.data['result']['total'] as int; + final int currentSize = list.length as int; + + if (currentSize == size && currentSize < total) { + // If the number of returned inscriptions equals the limit and there are more inscriptions available, + // increment the cursor and make the next API call to fetch the remaining inscriptions. + final int newCursor = cursor + size; + return getInscriptionsByAddress(address, cursor: newCursor, size: size); + + } else { + try { + // Iterate through the list and create InscriptionData objects from each element + final List<InscriptionData> inscriptions = (list as List<dynamic>) + .map((json) => InscriptionData.fromJson(json as Map<String, dynamic>)) + .toList(); + + return inscriptions; + } catch (e) { + throw const FormatException('LitescribeAPI getInscriptionsByAddress exception: AddressInscriptionResponse.fromJson failure'); + } + } + } +} \ No newline at end of file diff --git a/lib/services/mixins/ordinals_interface.dart b/lib/services/mixins/ordinals_interface.dart index 06f2377e9..a779f5b2e 100644 --- a/lib/services/mixins/ordinals_interface.dart +++ b/lib/services/mixins/ordinals_interface.dart @@ -1,3 +1,111 @@ +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/ordinal.dart'; +import 'package:stackwallet/services/litescribe_api.dart'; +import 'package:stackwallet/utilities/enums/coin_enum.dart'; + mixin OrdinalsInterface { - // TODO wallet ordinals functionality -} + late final String _walletId; + late final Coin _coin; + late final MainDB _db; + + void initOrdinalsInterface({ + required String walletId, + required Coin coin, + required MainDB db, + }) { + print('init'); + _walletId = walletId; + _coin = coin; + _db = db; + } + final LitescribeAPI litescribeAPI = LitescribeAPI(baseUrl: 'https://litescribe.io/api'); + + void refreshInscriptions() async { + List<dynamic> _inscriptions; + final utxos = await _db.getUTXOs(_walletId).findAll(); + final uniqueAddresses = getUniqueAddressesFromUTXOs(utxos); + _inscriptions = await getInscriptionDataFromAddresses(uniqueAddresses); + // TODO save inscriptions to isar which gets watched by a FutureBuilder/StreamBuilder + } + + Future<List<InscriptionData>> getInscriptionData() async { + try { + final utxos = await _db.getUTXOs(_walletId).findAll(); + final uniqueAddresses = getUniqueAddressesFromUTXOs(utxos); + return await getInscriptionDataFromAddresses(uniqueAddresses); + } catch (e) { + throw Exception('Error in OrdinalsInterface getInscriptions: $e'); + } + } + + Future<List<Ordinal>> getOrdinals() async { + try { + final utxos = await _db.getUTXOs(_walletId).findAll(); + final uniqueAddresses = getUniqueAddressesFromUTXOs(utxos); + return await getOrdinalsFromAddresses(uniqueAddresses); + } catch (e) { + throw Exception('Error in OrdinalsInterface getOrdinals: $e'); + } + } + + List<String> getUniqueAddressesFromUTXOs(List<UTXO> utxos) { + final Set<String> uniqueAddresses = <String>{}; + for (var utxo in utxos) { + if (utxo.address != null) { + uniqueAddresses.add(utxo.address!); + } + } + return uniqueAddresses.toList(); + } + + Future<List<InscriptionData>> getInscriptionDataFromAddress(String address) async { + List<InscriptionData> allInscriptions = []; + try { + var inscriptions = await litescribeAPI.getInscriptionsByAddress(address); + allInscriptions.addAll(inscriptions); + } catch (e) { + throw Exception('Error in OrdinalsInterface getInscriptionsByAddress: $e'); + } + return allInscriptions; + } + + 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) { + print("Error fetching inscriptions for address $address: $e"); + } + } + return allInscriptions; + } + + Future<List<Ordinal>> getOrdinalsFromAddress(String address) async { + try { + var inscriptions = await litescribeAPI.getInscriptionsByAddress(address); + return inscriptions.map((data) => Ordinal.fromInscriptionData(data)).toList(); + } catch (e) { + throw Exception('Error in OrdinalsInterface getOrdinalsFromAddress: $e'); + } + } + + Future<List<Ordinal>> getOrdinalsFromAddresses(List<String> addresses) async { + List<Ordinal> allOrdinals = []; + for (String address in addresses) { + try { + var inscriptions = await litescribeAPI.getInscriptionsByAddress(address); + allOrdinals.addAll(inscriptions.map((data) => Ordinal.fromInscriptionData(data))); + } catch (e) { + print("Error fetching inscriptions for address $address: $e"); + } + } + return allOrdinals; + } +} \ No newline at end of file diff --git a/lib/services/ordinals_api.dart b/lib/services/ordinals_api.dart deleted file mode 100644 index 97cc45834..000000000 --- a/lib/services/ordinals_api.dart +++ /dev/null @@ -1,9 +0,0 @@ -import 'package:stackwallet/models/ordinal.dart'; - -class OrdinalsAPI { - // dummy class with sample functions to be changed / filled out - - static Future<List<Ordinal>> fetch() async { - return []; - } -}