From f46a37d4d4775cb9f8bc3feb825350e577d202f2 Mon Sep 17 00:00:00 2001 From: sneurlax Date: Fri, 21 Jul 2023 11:48:31 -0500 Subject: [PATCH] convert/map/cast InscriptionData->Ordinal --- lib/models/ordinal.dart | 33 ++-- lib/pages/ordinals/ordinal_details_view.dart | 30 ++-- lib/pages/ordinals/ordinals_view.dart | 2 +- lib/pages/ordinals/widgets/ordinal_card.dart | 16 +- lib/pages/ordinals/widgets/ordinals_list.dart | 12 +- lib/route_generator.dart | 4 +- lib/services/mixins/ordinals_interface.dart | 146 ++++++------------ 7 files changed, 99 insertions(+), 144 deletions(-) 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 bd5b9a17e..6aab95586 100644 --- a/lib/pages/ordinals/ordinal_details_view.dart +++ b/lib/pages/ordinals/ordinal_details_view.dart @@ -4,6 +4,7 @@ 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'; import 'package:stackwallet/themes/stack_colors.dart'; @@ -15,16 +16,15 @@ import 'package:stackwallet/widgets/desktop/primary_button.dart'; import 'package:stackwallet/widgets/desktop/secondary_button.dart'; import 'package:stackwallet/widgets/rounded_white_container.dart'; - class OrdinalDetailsView extends StatefulWidget { const OrdinalDetailsView({ Key? key, required this.walletId, - required this.inscriptionData, + required this.ordinal, }) : super(key: key); final String walletId; - final InscriptionData inscriptionData; + final Ordinal ordinal; static const routeName = "/ordinalDetailsView"; @@ -62,20 +62,20 @@ class _OrdinalDetailsViewState extends State { horizontal: 39, ), child: _OrdinalImageGroup( - inscriptionData: widget.inscriptionData, + ordinal: widget.ordinal, walletId: widget.walletId, ), ), _DetailsItemWCopy( title: "Inscription number", - data: widget.inscriptionData.inscriptionNumber.toString(), + data: widget.ordinal.inscriptionNumber.toString(), ), const SizedBox( height: _spacing, ), _DetailsItemWCopy( title: "ID", - data: widget.inscriptionData.inscriptionId, + data: widget.ordinal.inscriptionId, ), const SizedBox( height: _spacing, @@ -84,23 +84,23 @@ class _OrdinalDetailsViewState extends State { const SizedBox( height: _spacing, ), - _DetailsItemWCopy( + const _DetailsItemWCopy( title: "Amount", - data: "${widget.inscriptionData.outputValue}", + data: "TODO", // TODO infer from utxo utxoTXID:utxoVOUT ), const SizedBox( height: _spacing, ), - _DetailsItemWCopy( + const _DetailsItemWCopy( title: "Owner address", - data: widget.inscriptionData.address, + data: "TODO", // infer from address associated w utxoTXID ), const SizedBox( height: _spacing, ), _DetailsItemWCopy( title: "Transaction ID", - data: widget.inscriptionData.genesisTransaction, + data: widget.ordinal.utxoTXID, ), const SizedBox( height: _spacing, @@ -177,11 +177,11 @@ class _OrdinalImageGroup extends StatelessWidget { const _OrdinalImageGroup({ Key? key, required this.walletId, - required this.inscriptionData, + required this.ordinal, }) : super(key: key); final String walletId; - final InscriptionData inscriptionData; + final Ordinal ordinal; static const _spacing = 12.0; @@ -192,7 +192,7 @@ class _OrdinalImageGroup extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.center, children: [ Text( - "${inscriptionData.inscriptionId}", // Use any other property you want + "${ordinal.inscriptionId}", // Use any other property you want style: STextStyles.w600_16(context), ), const SizedBox( @@ -205,7 +205,7 @@ class _OrdinalImageGroup extends StatelessWidget { child: Container( color: Colors.red, child: Image.network( - inscriptionData.content, // Use the preview URL as the image source + ordinal.content, // Use the preview URL as the image source fit: BoxFit.cover, filterQuality: FilterQuality.none, // Set the filter mode to nearest ), diff --git a/lib/pages/ordinals/ordinals_view.dart b/lib/pages/ordinals/ordinals_view.dart index b12fb78c4..a4adfa019 100644 --- a/lib/pages/ordinals/ordinals_view.dart +++ b/lib/pages/ordinals/ordinals_view.dart @@ -193,7 +193,7 @@ class _OrdinalsViewState extends ConsumerState { Expanded( child: OrdinalsList( walletId: widget.walletId, - ordinalsFuture: (_manager.wallet as OrdinalsInterface).getInscriptions(), + 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 0c05f686a..c9060b32e 100644 --- a/lib/pages/ordinals/widgets/ordinal_card.dart +++ b/lib/pages/ordinals/widgets/ordinal_card.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; -import 'package:stackwallet/dto/ordinals/inscription_data.dart'; -import 'package:stackwallet/models/ordinal.dart'; // TODO generalize InscriptionData models -> Ordinal + +import 'package:stackwallet/models/ordinal.dart'; import 'package:stackwallet/pages/ordinals/ordinal_details_view.dart'; import 'package:stackwallet/utilities/text_styles.dart'; import 'package:stackwallet/widgets/rounded_white_container.dart'; @@ -9,11 +9,11 @@ class OrdinalCard extends StatelessWidget { const OrdinalCard({ Key? key, required this.walletId, - required this.inscriptionData, + required this.ordinal, }) : super(key: key); final String walletId; - final InscriptionData inscriptionData; + final Ordinal ordinal; @override Widget build(BuildContext context) { @@ -22,7 +22,7 @@ class OrdinalCard extends StatelessWidget { onPressed: () { Navigator.of(context).pushNamed( OrdinalDetailsView.routeName, - arguments: (walletId: walletId, inscriptionData: inscriptionData), + arguments: (walletId: walletId, ordinal: ordinal), ); }, child: Column( @@ -33,7 +33,7 @@ class OrdinalCard extends StatelessWidget { child: Container( color: Colors.red, child: Image.network( - inscriptionData.content, // Use the preview URL as the image source + ordinal.content, // Use the preview URL as the image source fit: BoxFit.cover, filterQuality: FilterQuality.none, // Set the filter mode to nearest ), @@ -41,12 +41,12 @@ class OrdinalCard extends StatelessWidget { ), const Spacer(), Text( - inscriptionData.address, + 'TODO', // infer from address associated with utxoTXID style: STextStyles.w500_12(context), ), const Spacer(), Text( - "INSC. ${inscriptionData.inscriptionNumber} ID ${inscriptionData.inscriptionId}", + "INSC. ${ordinal.inscriptionNumber} 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 d161cafeb..fe7618cd0 100644 --- a/lib/pages/ordinals/widgets/ordinals_list.dart +++ b/lib/pages/ordinals/widgets/ordinals_list.dart @@ -1,5 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:stackwallet/dto/ordinals/inscription_data.dart'; +import 'package:stackwallet/models/ordinal.dart'; import 'package:stackwallet/pages/ordinals/widgets/ordinal_card.dart'; @@ -11,13 +11,13 @@ class OrdinalsList extends StatelessWidget { }) : super(key: key); final String walletId; - final Future> ordinalsFuture; + final Future> ordinalsFuture; get spacing => 2.0; @override Widget build(BuildContext context) { - return FutureBuilder>( + return FutureBuilder>( future: ordinalsFuture, builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.waiting) { @@ -25,10 +25,10 @@ class OrdinalsList extends StatelessWidget { } else if (snapshot.hasError) { return Text('Error: ${snapshot.error}'); } else if (snapshot.hasData) { - final List inscriptions = snapshot.data!; + final List ordinals = snapshot.data!; return GridView.builder( shrinkWrap: true, - itemCount: inscriptions.length, + itemCount: ordinals.length, gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( crossAxisSpacing: spacing as double, mainAxisSpacing: spacing as double, @@ -37,7 +37,7 @@ class OrdinalsList extends StatelessWidget { ), itemBuilder: (_, i) => OrdinalCard( walletId: walletId, - inscriptionData: inscriptions[i], + ordinal: ordinals[i], ), ); } else { diff --git a/lib/route_generator.dart b/lib/route_generator.dart index e67254135..7c0807caf 100644 --- a/lib/route_generator.dart +++ b/lib/route_generator.dart @@ -423,12 +423,12 @@ class RouteGenerator { return _routeError("${settings.name} invalid args: ${args.toString()}"); case OrdinalDetailsView.routeName: - if (args is ({InscriptionData inscriptionData, String walletId})) { + if (args is ({Ordinal ordinal, String walletId})) { return getRoute( shouldUseMaterialRoute: useMaterialPageRoute, builder: (_) => OrdinalDetailsView( walletId: args.walletId, - inscriptionData: args.inscriptionData, + ordinal: args.ordinal, ), settings: RouteSettings( name: settings.name, diff --git a/lib/services/mixins/ordinals_interface.dart b/lib/services/mixins/ordinals_interface.dart index 51323fa0c..a779f5b2e 100644 --- a/lib/services/mixins/ordinals_interface.dart +++ b/lib/services/mixins/ordinals_interface.dart @@ -2,11 +2,11 @@ import 'dart:async'; import 'package:isar/isar.dart'; import 'package:stackwallet/db/isar/main_db.dart'; -import 'package:stackwallet/models/isar/models/blockchain_data/utxo.dart'; -import 'package:stackwallet/utilities/enums/coin_enum.dart'; - -import 'package:stackwallet/services/litescribe_api.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 { late final String _walletId; @@ -25,28 +25,32 @@ mixin OrdinalsInterface { } final LitescribeAPI litescribeAPI = LitescribeAPI(baseUrl: 'https://litescribe.io/api'); - // Future> getInscriptionsByAddress(String address) async { - // try { - // var response = await litescribeAPI.getInscriptionsByAddress(address); - // // print("Found ${response.result.total} inscription${response.result.total > 1 ? 's' : ''} at address $address"); // TODO disable (POC) - // return response.result.list; - // } catch (e) { - // throw Exception('Error in OrdinalsInterface getInscriptionsByAddress: $e'); - // } - // } - void refreshInscriptions() async { List _inscriptions; final utxos = await _db.getUTXOs(_walletId).findAll(); final uniqueAddresses = getUniqueAddressesFromUTXOs(utxos); - _inscriptions = await getInscriptionsFromAddresses(uniqueAddresses); + _inscriptions = await getInscriptionDataFromAddresses(uniqueAddresses); // TODO save inscriptions to isar which gets watched by a FutureBuilder/StreamBuilder } - Future> getInscriptions() async { - final utxos = await _db.getUTXOs(_walletId).findAll(); - final uniqueAddresses = getUniqueAddressesFromUTXOs(utxos); - return await getInscriptionsFromAddresses(uniqueAddresses); + Future> 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> 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 getUniqueAddressesFromUTXOs(List utxos) { @@ -59,12 +63,22 @@ mixin OrdinalsInterface { return uniqueAddresses.toList(); } - Future> getInscriptionsFromAddresses(List addresses) async { + Future> getInscriptionDataFromAddress(String address) async { + List allInscriptions = []; + try { + var inscriptions = await litescribeAPI.getInscriptionsByAddress(address); + allInscriptions.addAll(inscriptions); + } catch (e) { + throw Exception('Error in OrdinalsInterface getInscriptionsByAddress: $e'); + } + return allInscriptions; + } + + Future> getInscriptionDataFromAddresses(List addresses) async { List allInscriptions = []; for (String address in addresses) { try { var inscriptions = await litescribeAPI.getInscriptionsByAddress(address); - print("Found ${inscriptions.length} inscription${inscriptions.length > 1 ? 's' : ''} at address $address"); allInscriptions.addAll(inscriptions); } catch (e) { print("Error fetching inscriptions for address $address: $e"); @@ -73,87 +87,25 @@ mixin OrdinalsInterface { return allInscriptions; } -/* // ord-litecoin interface - final OrdinalsAPI ordinalsAPI = OrdinalsAPI(baseUrl: 'https://ord-litecoin.stackwallet.com'); - - Future fetchLatestInscriptions() async { + Future> getOrdinalsFromAddress(String address) async { try { - final feedResponse = await ordinalsAPI.getLatestInscriptions(); - // Process the feedResponse data as needed - // print('Latest Inscriptions:'); - // for (var inscription in feedResponse.inscriptions) { - // print('Title: ${inscription.title}, Href: ${inscription.href}'); - // } - return feedResponse; + var inscriptions = await litescribeAPI.getInscriptionsByAddress(address); + return inscriptions.map((data) => Ordinal.fromInscriptionData(data)).toList(); } catch (e) { - // Handle errors - throw Exception('Error in OrdinalsInterface fetchLatestInscriptions: $e'); + throw Exception('Error in OrdinalsInterface getOrdinalsFromAddress: $e'); } } - Future getInscriptionDetails(String inscriptionId) async { - try { - return await ordinalsAPI.getInscriptionDetails(inscriptionId); - } catch (e) { - throw Exception('Error in OrdinalsInterface getInscriptionDetails: $e'); + Future> getOrdinalsFromAddresses(List addresses) async { + List 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; } - - Future getSatDetails(int satNumber) async { - try { - return await ordinalsAPI.getSatDetails(satNumber); - } catch (e) { - throw Exception('Error in OrdinalsInterface getSatDetails: $e'); - } - } - - Future getTransaction(String transactionId) async { - try { - print(1); - return await ordinalsAPI.getTransaction(transactionId); - } catch (e) { - throw Exception('Error in OrdinalsInterface getTransaction: $e'); - } - } - - Future getTransactionOutputs(String transactionId) async { - try { - return await ordinalsAPI.getTransactionOutputs(transactionId); - } catch (e) { - throw Exception('Error in OrdinalsInterface getTransactionOutputs: $e'); - } - } - - Future getInscriptionsByAddress(String address) async { - try { - return await ordinalsAPI.getInscriptionsByAddress(address); - } catch (e) { - throw Exception('Error in OrdinalsInterface getInscriptionsByAddress: $e'); - } - } - - Future getBlock(int blockNumber) async { - try { - return await ordinalsAPI.getBlock(blockNumber); - } catch (e) { - throw Exception('Error in OrdinalsInterface getBlock: $e'); - } - } - - Future getInscriptionContent(String inscriptionId) async { - try { - return await ordinalsAPI.getInscriptionContent(inscriptionId); - } catch (e) { - throw Exception('Error in OrdinalsInterface getInscriptionContent: $e'); - } - } - - Future getInscriptionPreview(String inscriptionId) async { - try { - return await ordinalsAPI.getInscriptionPreview(inscriptionId); - } catch (e) { - throw Exception('Error in OrdinalsInterface getInscriptionPreview: $e'); - } - } - */ // /ord-litecoin interface } \ No newline at end of file