From 8e17556e4128f00f915460f19eb7464c5ae54e16 Mon Sep 17 00:00:00 2001 From: sneurlax Date: Wed, 19 Jul 2023 13:03:17 -0500 Subject: [PATCH] use an OrdinalsResponse response type which can return an error --- lib/dto/ordinals/address_response.dart | 14 +++-- lib/dto/ordinals/block_response.dart | 25 +++++---- lib/dto/ordinals/content_response.dart | 9 ++- lib/dto/ordinals/feed_response.dart | 11 ++-- lib/dto/ordinals/inscription_response.dart | 61 ++++++++++++--------- lib/dto/ordinals/ordinals_response.dart | 6 ++ lib/dto/ordinals/output_response.dart | 21 ++++--- lib/dto/ordinals/preview_response.dart | 11 ++-- lib/dto/ordinals/sat_response.dart | 41 +++++++------- lib/dto/ordinals/transaction_response.dart | 24 ++++---- lib/services/mixins/ordinals_interface.dart | 18 +++++- lib/services/ordinals_api.dart | 5 +- 12 files changed, 148 insertions(+), 98 deletions(-) create mode 100644 lib/dto/ordinals/ordinals_response.dart diff --git a/lib/dto/ordinals/address_response.dart b/lib/dto/ordinals/address_response.dart index 5c1f66323..9136aa523 100644 --- a/lib/dto/ordinals/address_response.dart +++ b/lib/dto/ordinals/address_response.dart @@ -1,6 +1,7 @@ import 'package:stackwallet/dto/ordinals/inscription_link.dart'; +import 'package:stackwallet/dto/ordinals/ordinals_response.dart'; -class AddressResponse { +class AddressResponse extends OrdinalsResponse { final AddressLinks links; final String address; final List inscriptions; @@ -11,15 +12,16 @@ class AddressResponse { required this.inscriptions, }); - factory AddressResponse.fromJson(Map json) { - final inscriptionsJson = json['inscriptions'] as List; + factory AddressResponse.fromJson(OrdinalsResponse json) { + final data = json.data as Map; + final inscriptionsJson = data['inscriptions'] as List; final inscriptions = inscriptionsJson .map((inscriptionJson) => InscriptionLink.fromJson(inscriptionJson as Map)) .toList(); return AddressResponse( - links: AddressLinks.fromJson(json['_links'] as Map), - address: json['address'] as String, + links: AddressLinks.fromJson(data['_links'] as Map), + address: data['address'] as String, inscriptions: inscriptions, ); } @@ -34,7 +36,7 @@ class AddressLinks { factory AddressLinks.fromJson(Map json) { return AddressLinks( - self: AddressLink.fromJson(json['self'] as Map), + self: json['self'] != null ? AddressLink.fromJson(json['self'] as Map) : null, ); } } diff --git a/lib/dto/ordinals/block_response.dart b/lib/dto/ordinals/block_response.dart index a3de1ee1c..0eef8d569 100644 --- a/lib/dto/ordinals/block_response.dart +++ b/lib/dto/ordinals/block_response.dart @@ -1,4 +1,6 @@ -class BlockResponse { +import 'package:stackwallet/dto/ordinals/ordinals_response.dart'; + +class BlockResponse extends OrdinalsResponse { final BlockLinks links; final String hash; final String previousBlockhash; @@ -17,15 +19,16 @@ class BlockResponse { required this.weight, }); - factory BlockResponse.fromJson(Map json) { + factory BlockResponse.fromJson(OrdinalsResponse json) { + final data = json.data as Map; return BlockResponse( - links: BlockLinks.fromJson(json['_links'] as Map), - hash: json['hash'] as String, - previousBlockhash: json['previous_blockhash'] as String, - size: json['size'] as int, - target: json['target'] as String, - timestamp: json['timestamp'] as String, - weight: json['weight'] as int, + links: BlockLinks.fromJson(data['_links'] as Map), + hash: data['hash'] as String, + previousBlockhash: data['previous_blockhash'] as String, + size: data['size'] as int, + target: data['target'] as String, + timestamp: data['timestamp'] as String, + weight: data['weight'] as int, ); } } @@ -41,8 +44,8 @@ class BlockLinks { factory BlockLinks.fromJson(Map json) { return BlockLinks( - prev: BlockLink.fromJson(json['prev'] as Map), - self: BlockLink.fromJson(json['self'] as Map), + prev: json['prev'] != null ? BlockLink.fromJson(json['prev'] as Map) : null, + self: json['self'] != null ? BlockLink.fromJson(json['self'] as Map) : null, ); } } diff --git a/lib/dto/ordinals/content_response.dart b/lib/dto/ordinals/content_response.dart index d1131950b..7cfbaf9fd 100644 --- a/lib/dto/ordinals/content_response.dart +++ b/lib/dto/ordinals/content_response.dart @@ -1,10 +1,13 @@ -class ContentResponse { +import 'package:stackwallet/dto/ordinals/ordinals_response.dart'; + +class ContentResponse extends OrdinalsResponse { final FileLink fileLink; ContentResponse({required this.fileLink}); - factory ContentResponse.fromJson(Map json) { - return ContentResponse(fileLink: FileLink.fromJson(json['_links']['file'] as Map)); + factory ContentResponse.fromJson(OrdinalsResponse json) { + final data = json.data as Map; + return ContentResponse(fileLink: FileLink.fromJson(data['_links']['file'] as Map)); // TODO don't cast as Map } } diff --git a/lib/dto/ordinals/feed_response.dart b/lib/dto/ordinals/feed_response.dart index e29d2d334..525a7f727 100644 --- a/lib/dto/ordinals/feed_response.dart +++ b/lib/dto/ordinals/feed_response.dart @@ -1,16 +1,17 @@ import 'package:stackwallet/dto/ordinals/inscription_link.dart'; +import 'package:stackwallet/dto/ordinals/ordinals_response.dart'; -class FeedResponse { +class FeedResponse extends OrdinalsResponse { final List inscriptions; FeedResponse({required this.inscriptions}); - - factory FeedResponse.fromJson(Map json) { - final List inscriptionsJson = json['_links']['inscriptions'] as List; + + factory FeedResponse.fromJson(OrdinalsResponse json) { + final List inscriptionsJson = json.data['_links']['inscriptions'] as List; final List inscriptions = inscriptionsJson .map((json) => InscriptionLink.fromJson(json as Map)) .toList(); return FeedResponse(inscriptions: inscriptions); } -} +} \ No newline at end of file diff --git a/lib/dto/ordinals/inscription_response.dart b/lib/dto/ordinals/inscription_response.dart index ab093b750..d45300aee 100644 --- a/lib/dto/ordinals/inscription_response.dart +++ b/lib/dto/ordinals/inscription_response.dart @@ -1,4 +1,6 @@ -class InscriptionResponse { +import 'package:stackwallet/dto/ordinals/ordinals_response.dart'; + +class InscriptionResponse extends OrdinalsResponse { late final Links links; late final String address; late final int contentLength; @@ -29,20 +31,23 @@ class InscriptionResponse { required this.timestamp, }); - InscriptionResponse.fromJson(Map json) { - links = Links.fromJson(json['_links'] as Map); - address = json['address'] as String; - contentLength = json['content_length'] as int; - contentType = json['content_type'] as String; - genesisFee = json['genesis_fee'] as int; - genesisHeight = json['genesis_height'] as int; - genesisTransaction = json['genesis_transaction'] as String; - location = json['location'] as String; - number = json['number'] as int; - offset = json['offset'] as int; - output = json['output'] as String; - sat = json['sat'] as String?; - timestamp = json['timestamp'] as String; + factory InscriptionResponse.fromJson(OrdinalsResponse json) { + final data = json.data as Map; + return InscriptionResponse( + links: Links.fromJson(data['_links'] as Map), + address: data['address'] as String, + contentLength: data['content_length'] as int, + contentType: data['content_type'] as String, + genesisFee: data['genesis_fee'] as int, + genesisHeight: data['genesis_height'] as int, + genesisTransaction: data['genesis_transaction'] as String, + location: data['location'] as String, + number: data['number'] as int, + offset: data['offset'] as int, + output: data['output'] as String, + sat: data['sat'] as String?, + timestamp: data['timestamp'] as String, + ); } } @@ -67,15 +72,17 @@ class Links { required this.self, }); - Links.fromJson(Map json) { - content = Link.fromJson(json['content'] as Map); - genesisTransaction = Link.fromJson(json['genesis_transaction'] as Map); - next = Link.fromJson(json['next'] as Map); - output = Link.fromJson(json['output'] as Map); - prev = Link.fromJson(json['prev'] as Map); - preview = Link.fromJson(json['preview'] as Map); - sat = json['sat'] != null ? Link.fromJson(json['sat'] as Map) : null; - self = Link.fromJson(json['self'] as Map); + factory Links.fromJson(Map json) { + return Links( + content: Link.fromJson(json['content'] as Map), + genesisTransaction: Link.fromJson(json['genesis_transaction'] as Map), + next: Link.fromJson(json['next'] as Map), + output: Link.fromJson(json['output'] as Map), + prev: Link.fromJson(json['prev'] as Map), + preview: Link.fromJson(json['preview'] as Map), + sat: json['sat'] != null ? Link.fromJson(json['sat'] as Map) : null, + self: Link.fromJson(json['self'] as Map), + ); } } @@ -84,7 +91,7 @@ class Link { Link({required this.href}); - Link.fromJson(Map json) { - href = json['href'] as String; + factory Link.fromJson(Map json) { + return Link(href: json['href'] as String); } -} \ No newline at end of file +} diff --git a/lib/dto/ordinals/ordinals_response.dart b/lib/dto/ordinals/ordinals_response.dart new file mode 100644 index 000000000..bf57db46b --- /dev/null +++ b/lib/dto/ordinals/ordinals_response.dart @@ -0,0 +1,6 @@ +class OrdinalsResponse { + final T? data; + final String? error; + + OrdinalsResponse({this.data, this.error}); +} diff --git a/lib/dto/ordinals/output_response.dart b/lib/dto/ordinals/output_response.dart index cd4bde563..cc7b2107f 100644 --- a/lib/dto/ordinals/output_response.dart +++ b/lib/dto/ordinals/output_response.dart @@ -1,6 +1,7 @@ import 'package:stackwallet/dto/ordinals/transaction_response.dart'; +import 'package:stackwallet/dto/ordinals/ordinals_response.dart'; -class OutputResponse { +class OutputResponse extends OrdinalsResponse { final OutputLinks links; final String address; final String scriptPubkey; @@ -15,13 +16,15 @@ class OutputResponse { required this.value, }); - factory OutputResponse.fromJson(Map json) { + factory OutputResponse.fromJson(OrdinalsResponse json) { + final data = json.data as Map; + return OutputResponse( - links: OutputLinks.fromJson(json['_links'] as Map), - address: json['address'] as String, - scriptPubkey: json['script_pubkey'] as String, - transaction: json['transaction'] as String, - value: json['value'] as int, + links: OutputLinks.fromJson(data['_links'] as Map), + address: data['address'] as String, + scriptPubkey: data['script_pubkey'] as String, + transaction: data['transaction'] as String, + value: data['value'] as int, ); } } @@ -37,8 +40,8 @@ class OutputLinks { factory OutputLinks.fromJson(Map json) { return OutputLinks( - self: OutputLink.fromJson(json['self'] as Map), - transaction: TransactionLink.fromJson(json['transaction'] as Map), + self: json['self'] != null ? OutputLink.fromJson(json['self'] as Map) : null, + transaction: json['transaction'] != null ? TransactionLink.fromJson(json['transaction'] as Map) : null, ); } } diff --git a/lib/dto/ordinals/preview_response.dart b/lib/dto/ordinals/preview_response.dart index 9eabd590a..b3e184acd 100644 --- a/lib/dto/ordinals/preview_response.dart +++ b/lib/dto/ordinals/preview_response.dart @@ -1,10 +1,13 @@ -class PreviewResponse { +import 'package:stackwallet/dto/ordinals/ordinals_response.dart'; + +class PreviewResponse extends OrdinalsResponse { final ImageLink imageLink; PreviewResponse({required this.imageLink}); - factory PreviewResponse.fromJson(Map json) { - return PreviewResponse(imageLink: ImageLink.fromJson(json['_links']['image'] as Map)); + factory PreviewResponse.fromJson(OrdinalsResponse json) { + final data = json.data as Map; + return PreviewResponse(imageLink: ImageLink.fromJson(data['_links']['image'] as Map)); } } @@ -16,4 +19,4 @@ class ImageLink { factory ImageLink.fromJson(Map json) { return ImageLink(href: json['href'] as String); } -} \ No newline at end of file +} diff --git a/lib/dto/ordinals/sat_response.dart b/lib/dto/ordinals/sat_response.dart index b57ccb3cf..40efb1440 100644 --- a/lib/dto/ordinals/sat_response.dart +++ b/lib/dto/ordinals/sat_response.dart @@ -1,4 +1,6 @@ -class SatResponse { +import 'package:stackwallet/dto/ordinals/ordinals_response.dart'; + +class SatResponse extends OrdinalsResponse { final SatLinks links; final int block; final int cycle; @@ -27,20 +29,21 @@ class SatResponse { required this.timestamp, }); - factory SatResponse.fromJson(Map json) { + factory SatResponse.fromJson(OrdinalsResponse json) { + final data = json.data as Map; return SatResponse( - links: SatLinks.fromJson(json['_links'] as Map), - block: json['block'] as int, - cycle: json['cycle'] as int, - decimal: json['decimal'] as String, - degree: json['degree'] as String, - epoch: json['epoch'] as int, - name: json['name'] as String, - offset: json['offset'] as int, - percentile: json['percentile'] as String, - period: json['period'] as int, - rarity: json['rarity'] as String, - timestamp: json['timestamp'] as String, + links: SatLinks.fromJson(data['_links'] as Map), + block: data['block'] as int, + cycle: data['cycle'] as int, + decimal: data['decimal'] as String, + degree: data['degree'] as String, + epoch: data['epoch'] as int, + name: data['name'] as String, + offset: data['offset'] as int, + percentile: data['percentile'] as String, + period: data['period'] as int, + rarity: data['rarity'] as String, + timestamp: data['timestamp'] as String, ); } } @@ -62,11 +65,11 @@ class SatLinks { factory SatLinks.fromJson(Map json) { return SatLinks( - block: SatLink.fromJson(json['block'] as Map), - inscription: SatLink.fromJson(json['inscription'] as Map), - next: SatLink.fromJson(json['next'] as Map), - prev: SatLink.fromJson(json['prev'] as Map), - self: SatLink.fromJson(json['self'] as Map), + block: json['block'] != null ? SatLink.fromJson(json['block'] as Map) : null, + inscription: json['inscription'] != null ? SatLink.fromJson(json['inscription'] as Map) : null, + next: json['next'] != null ? SatLink.fromJson(json['next'] as Map) : null, + prev: json['prev'] != null ? SatLink.fromJson(json['prev'] as Map) : null, + self: json['self'] != null ? SatLink.fromJson(json['self'] as Map) : null, ); } } diff --git a/lib/dto/ordinals/transaction_response.dart b/lib/dto/ordinals/transaction_response.dart index 11912a3ad..c77e07914 100644 --- a/lib/dto/ordinals/transaction_response.dart +++ b/lib/dto/ordinals/transaction_response.dart @@ -1,6 +1,7 @@ import 'package:stackwallet/dto/ordinals/inscription_link.dart'; +import 'package:stackwallet/dto/ordinals/ordinals_response.dart'; -class TransactionResponse { +class TransactionResponse extends OrdinalsResponse { final TransactionLinks links; final List inputs; final InscriptionLink inscription; @@ -17,24 +18,25 @@ class TransactionResponse { required this.transaction, }); - factory TransactionResponse.fromJson(Map json) { - final inputsJson = json['_links']['inputs'] as List; + factory TransactionResponse.fromJson(OrdinalsResponse json) { + final data = json.data as Map; + final inputsJson = data['_links']['inputs'] as List; final inputs = inputsJson .map((inputJson) => OutputLink.fromJson(inputJson as Map)) .toList(); - final outputsJson = json['_links']['outputs'] as List; + final outputsJson = data['_links']['outputs'] as List; final outputs = outputsJson .map((outputJson) => OutputLink.fromJson(outputJson as Map)) .toList(); return TransactionResponse( - links: TransactionLinks.fromJson(json['_links'] as Map), + links: TransactionLinks.fromJson(data['_links'] as Map), inputs: inputs, - inscription: InscriptionLink.fromJson(json['_links']['inscription'] as Map), + inscription: InscriptionLink.fromJson(data['_links']['inscription'] as Map), outputs: outputs, - self: TransactionLink.fromJson(json['_links']['self'] as Map), - transaction: json['transaction'] as String, + self: TransactionLink.fromJson(data['_links']['self'] as Map), + transaction: data['transaction'] as String, ); } } @@ -52,9 +54,9 @@ class TransactionLinks { factory TransactionLinks.fromJson(Map json) { return TransactionLinks( - block: TransactionLink.fromJson(json['block'] as Map), - inscription: InscriptionLink.fromJson(json['inscription'] as Map), - self: TransactionLink.fromJson(json['self'] as Map), + block: json['block'] != null ? TransactionLink.fromJson(json['block'] as Map) : null, + inscription: json['inscription'] != null ? InscriptionLink.fromJson(json['inscription'] as Map) : null, + self: json['self'] != null ? TransactionLink.fromJson(json['self'] as Map) : null, ); } } diff --git a/lib/services/mixins/ordinals_interface.dart b/lib/services/mixins/ordinals_interface.dart index 06f2377e9..57a76fbd6 100644 --- a/lib/services/mixins/ordinals_interface.dart +++ b/lib/services/mixins/ordinals_interface.dart @@ -1,3 +1,19 @@ +import 'package:stackwallet/services/ordinals_api.dart'; +import 'package:stackwallet/dto/ordinals/feed_response.dart'; + mixin OrdinalsInterface { - // TODO wallet ordinals functionality + Future fetchLatestInscriptions(OrdinalsAPI ordinalsAPI) 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; + } catch (e) { + // Handle errors + throw Exception('Error in OrdinalsInterface: $e'); + } + } } diff --git a/lib/services/ordinals_api.dart b/lib/services/ordinals_api.dart index 4d8360e06..e9d734203 100644 --- a/lib/services/ordinals_api.dart +++ b/lib/services/ordinals_api.dart @@ -1,6 +1,7 @@ import 'dart:convert'; import 'package:http/http.dart' as http; +import 'package:stackwallet/dto/ordinals/ordinals_response.dart'; import 'package:stackwallet/dto/ordinals/feed_response.dart'; import 'package:stackwallet/dto/ordinals/inscription_response.dart'; import 'package:stackwallet/dto/ordinals/sat_response.dart'; @@ -16,10 +17,10 @@ class OrdinalsAPI { OrdinalsAPI({required this.baseUrl}); - Future> _getResponse(String endpoint) async { + Future _getResponse(String endpoint) async { final response = await http.get(Uri.parse('$baseUrl$endpoint')); if (response.statusCode == 200) { - return _validateJson(response.body); + return OrdinalsResponse(data: _validateJson(response.body)); } else { throw Exception('Failed to load data'); }