From b60e3fbf1bc58554207f0b27c1b81f6feb47f194 Mon Sep 17 00:00:00 2001
From: sneurlax <sneurlax@gmail.com>
Date: Tue, 18 Jul 2023 16:36:26 -0500
Subject: [PATCH 01/31] add dtos for ord-litecoin documented endpoint responses

---
 lib/dto/ordinals/address_response.dart     | 48 +++++++++++
 lib/dto/ordinals/block_response.dart       | 58 +++++++++++++
 lib/dto/ordinals/content_response.dart     | 19 +++++
 lib/dto/ordinals/feed_response.dart        | 14 ++++
 lib/dto/ordinals/inscription_response.dart | 95 ++++++++++++++++++++++
 lib/dto/ordinals/output_response           | 42 ++++++++++
 lib/dto/ordinals/preview_response.dart     | 19 +++++
 lib/dto/ordinals/sat_response.dart         | 82 +++++++++++++++++++
 lib/dto/ordinals/transaction_response.dart | 78 ++++++++++++++++++
 9 files changed, 455 insertions(+)
 create mode 100644 lib/dto/ordinals/address_response.dart
 create mode 100644 lib/dto/ordinals/block_response.dart
 create mode 100644 lib/dto/ordinals/content_response.dart
 create mode 100644 lib/dto/ordinals/feed_response.dart
 create mode 100644 lib/dto/ordinals/inscription_response.dart
 create mode 100644 lib/dto/ordinals/output_response
 create mode 100644 lib/dto/ordinals/preview_response.dart
 create mode 100644 lib/dto/ordinals/sat_response.dart
 create mode 100644 lib/dto/ordinals/transaction_response.dart

diff --git a/lib/dto/ordinals/address_response.dart b/lib/dto/ordinals/address_response.dart
new file mode 100644
index 000000000..024543b92
--- /dev/null
+++ b/lib/dto/ordinals/address_response.dart
@@ -0,0 +1,48 @@
+class AddressResponse {
+  final AddressLinks links;
+  final String address;
+  final List<InscriptionLink> inscriptions;
+
+  AddressResponse({
+    required this.links,
+    required this.address,
+    required this.inscriptions,
+  });
+
+  factory AddressResponse.fromJson(Map<String, dynamic> json) {
+    final inscriptionsJson = json['inscriptions'] as List;
+    final inscriptions = inscriptionsJson
+        .map((inscriptionJson) => InscriptionLink.fromJson(inscriptionJson))
+        .toList();
+
+    return AddressResponse(
+      links: AddressLinks.fromJson(json['_links']),
+      address: json['address'],
+      inscriptions: inscriptions,
+    );
+  }
+}
+
+class AddressLinks {
+  final AddressLink? self;
+
+  AddressLinks({
+    this.self,
+  });
+
+  factory AddressLinks.fromJson(Map<String, dynamic> json) {
+    return AddressLinks(
+      self: AddressLink.fromJson(json['self']),
+    );
+  }
+}
+
+class AddressLink {
+  final String href;
+
+  AddressLink({required this.href});
+
+  factory AddressLink.fromJson(Map<String, dynamic> json) {
+    return AddressLink(href: json['href']);
+  }
+}
diff --git a/lib/dto/ordinals/block_response.dart b/lib/dto/ordinals/block_response.dart
new file mode 100644
index 000000000..365098594
--- /dev/null
+++ b/lib/dto/ordinals/block_response.dart
@@ -0,0 +1,58 @@
+class BlockResponse {
+  final BlockLinks links;
+  final String hash;
+  final String previousBlockhash;
+  final int size;
+  final String target;
+  final String timestamp;
+  final int weight;
+
+  BlockResponse({
+    required this.links,
+    required this.hash,
+    required this.previousBlockhash,
+    required this.size,
+    required this.target,
+    required this.timestamp,
+    required this.weight,
+  });
+
+  factory BlockResponse.fromJson(Map<String, dynamic> json) {
+    return BlockResponse(
+      links: BlockLinks.fromJson(json['_links']),
+      hash: json['hash'],
+      previousBlockhash: json['previous_blockhash'],
+      size: json['size'],
+      target: json['target'],
+      timestamp: json['timestamp'],
+      weight: json['weight'],
+    );
+  }
+}
+
+class BlockLinks {
+  final BlockLink? prev;
+  final BlockLink? self;
+
+  BlockLinks({
+    this.prev,
+    this.self,
+  });
+
+  factory BlockLinks.fromJson(Map<String, dynamic> json) {
+    return BlockLinks(
+      prev: BlockLink.fromJson(json['prev']),
+      self: BlockLink.fromJson(json['self']),
+    );
+  }
+}
+
+class BlockLink {
+  final String href;
+
+  BlockLink({required this.href});
+
+  factory BlockLink.fromJson(Map<String, dynamic> json) {
+    return BlockLink(href: json['href']);
+  }
+}
diff --git a/lib/dto/ordinals/content_response.dart b/lib/dto/ordinals/content_response.dart
new file mode 100644
index 000000000..35a2c8ef8
--- /dev/null
+++ b/lib/dto/ordinals/content_response.dart
@@ -0,0 +1,19 @@
+class ContentResponse {
+  final FileLink fileLink;
+
+  ContentResponse({required this.fileLink});
+
+  factory ContentResponse.fromJson(Map<String, dynamic> json) {
+    return ContentResponse(fileLink: FileLink.fromJson(json['_links']['file']));
+  }
+}
+
+class FileLink {
+  final String href;
+
+  FileLink({required this.href});
+
+  factory FileLink.fromJson(Map<String, dynamic> json) {
+    return FileLink(href: json['href']);
+  }
+}
diff --git a/lib/dto/ordinals/feed_response.dart b/lib/dto/ordinals/feed_response.dart
new file mode 100644
index 000000000..b6af1c1ca
--- /dev/null
+++ b/lib/dto/ordinals/feed_response.dart
@@ -0,0 +1,14 @@
+class FeedResponse {
+  final List<InscriptionLink> inscriptions;
+
+  FeedResponse(this.inscriptions);
+
+  factory FeedResponse.fromJson(Map<String, dynamic> json) {
+    final inscriptionsJson = json['_links']['inscriptions'] as List;
+    final inscriptions = inscriptionsJson
+        .map((inscriptionJson) => InscriptionLink.fromJson(inscriptionJson))
+        .toList();
+
+    return FeedResponse(inscriptions);
+  }
+}
diff --git a/lib/dto/ordinals/inscription_response.dart b/lib/dto/ordinals/inscription_response.dart
new file mode 100644
index 000000000..e06ddca6d
--- /dev/null
+++ b/lib/dto/ordinals/inscription_response.dart
@@ -0,0 +1,95 @@
+class InscriptionResponse {
+  final InscriptionLinks links;
+  final String address;
+  final int contentLength;
+  final String contentType;
+  final int genesisFee;
+  final int genesisHeight;
+  final String genesisTransaction;
+  final String location;
+  final int number;
+  final int offset;
+  final String output;
+  final dynamic sat; // Change to appropriate type if available
+  final String timestamp;
+
+  InscriptionResponse({
+    required this.links,
+    required this.address,
+    required this.contentLength,
+    required this.contentType,
+    required this.genesisFee,
+    required this.genesisHeight,
+    required this.genesisTransaction,
+    required this.location,
+    required this.number,
+    required this.offset,
+    required this.output,
+    required this.sat,
+    required this.timestamp,
+  });
+
+  factory InscriptionResponse.fromJson(Map<String, dynamic> json) {
+    return InscriptionResponse(
+      links: InscriptionLinks.fromJson(json['_links']),
+      address: json['address'],
+      contentLength: json['content_length'],
+      contentType: json['content_type'],
+      genesisFee: json['genesis_fee'],
+      genesisHeight: json['genesis_height'],
+      genesisTransaction: json['genesis_transaction'],
+      location: json['location'],
+      number: json['number'],
+      offset: json['offset'],
+      output: json['output'],
+      sat: json['sat'],
+      timestamp: json['timestamp'],
+    );
+  }
+}
+
+class InscriptionLinks {
+  final InscriptionLink? content;
+  final InscriptionLink? genesisTransaction;
+  final InscriptionLink? next;
+  final InscriptionLink? output;
+  final InscriptionLink? prev;
+  final InscriptionLink? preview;
+  final InscriptionLink? sat;
+  final InscriptionLink? self;
+
+  InscriptionLinks({
+    this.content,
+    this.genesisTransaction,
+    this.next,
+    this.output,
+    this.prev,
+    this.preview,
+    this.sat,
+    this.self,
+  });
+
+  factory InscriptionLinks.fromJson(Map<String, dynamic> json) {
+    return InscriptionLinks(
+      content: InscriptionLink.fromJson(json['content']),
+      genesisTransaction: InscriptionLink.fromJson(json['genesis_transaction']),
+      next: InscriptionLink.fromJson(json['next']),
+      output: InscriptionLink.fromJson(json['output']),
+      prev: InscriptionLink.fromJson(json['prev']),
+      preview: InscriptionLink.fromJson(json['preview']),
+      sat: InscriptionLink.fromJson(json['sat']),
+      self: InscriptionLink.fromJson(json['self']),
+    );
+  }
+}
+
+class InscriptionLink {
+  final String href;
+  final String title;
+
+  InscriptionLink({required this.href, required this.title});
+
+  factory InscriptionLink.fromJson(Map<String, dynamic> json) {
+    return InscriptionLink(href: json['href'], title: json['title']);
+  }
+}
diff --git a/lib/dto/ordinals/output_response b/lib/dto/ordinals/output_response
new file mode 100644
index 000000000..cd25fe961
--- /dev/null
+++ b/lib/dto/ordinals/output_response
@@ -0,0 +1,42 @@
+class OutputResponse {
+  final OutputLinks links;
+  final String address;
+  final String scriptPubkey;
+  final String transaction;
+  final int value;
+
+  OutputResponse({
+    required this.links,
+    required this.address,
+    required this.scriptPubkey,
+    required this.transaction,
+    required this.value,
+  });
+
+  factory OutputResponse.fromJson(Map<String, dynamic> json) {
+    return OutputResponse(
+      links: OutputLinks.fromJson(json['_links']),
+      address: json['address'],
+      scriptPubkey: json['script_pubkey'],
+      transaction: json['transaction'],
+      value: json['value'],
+    );
+  }
+}
+
+class OutputLinks {
+  final OutputLink? self;
+  final TransactionLink? transaction;
+
+  OutputLinks({
+    this.self,
+    this.transaction,
+  });
+
+  factory OutputLinks.fromJson(Map<String, dynamic> json) {
+    return OutputLinks(
+      self: OutputLink.fromJson(json['self']),
+      transaction: TransactionLink.fromJson(json['transaction']),
+    );
+  }
+}
\ No newline at end of file
diff --git a/lib/dto/ordinals/preview_response.dart b/lib/dto/ordinals/preview_response.dart
new file mode 100644
index 000000000..d7171702d
--- /dev/null
+++ b/lib/dto/ordinals/preview_response.dart
@@ -0,0 +1,19 @@
+class PreviewResponse {
+  final ImageLink imageLink;
+
+  PreviewResponse({required this.imageLink});
+
+  factory PreviewResponse.fromJson(Map<String, dynamic> json) {
+    return PreviewResponse(imageLink: ImageLink.fromJson(json['_links']['image']));
+  }
+}
+
+class ImageLink {
+  final String href;
+
+  ImageLink({required this.href});
+
+  factory ImageLink.fromJson(Map<String, dynamic> json) {
+    return ImageLink(href: json['href']);
+  }
+}
\ No newline at end of file
diff --git a/lib/dto/ordinals/sat_response.dart b/lib/dto/ordinals/sat_response.dart
new file mode 100644
index 000000000..0f88918f3
--- /dev/null
+++ b/lib/dto/ordinals/sat_response.dart
@@ -0,0 +1,82 @@
+class SatResponse {
+  final SatLinks links;
+  final int block;
+  final int cycle;
+  final String decimal;
+  final String degree;
+  final int epoch;
+  final String name;
+  final int offset;
+  final String percentile;
+  final int period;
+  final String rarity;
+  final String timestamp;
+
+  SatResponse({
+    required this.links,
+    required this.block,
+    required this.cycle,
+    required this.decimal,
+    required this.degree,
+    required this.epoch,
+    required this.name,
+    required this.offset,
+    required this.percentile,
+    required this.period,
+    required this.rarity,
+    required this.timestamp,
+  });
+
+  factory SatResponse.fromJson(Map<String, dynamic> json) {
+    return SatResponse(
+      links: SatLinks.fromJson(json['_links']),
+      block: json['block'],
+      cycle: json['cycle'],
+      decimal: json['decimal'],
+      degree: json['degree'],
+      epoch: json['epoch'],
+      name: json['name'],
+      offset: json['offset'],
+      percentile: json['percentile'],
+      period: json['period'],
+      rarity: json['rarity'],
+      timestamp: json['timestamp'],
+    );
+  }
+}
+
+class SatLinks {
+  final SatLink? block;
+  final SatLink? inscription;
+  final SatLink? next;
+  final SatLink? prev;
+  final SatLink? self;
+
+  SatLinks({
+    this.block,
+    this.inscription,
+    this.next,
+    this.prev,
+    this.self,
+  });
+
+  factory SatLinks.fromJson(Map<String, dynamic> json) {
+    return SatLinks(
+      block: SatLink.fromJson(json['block']),
+      inscription: SatLink.fromJson(json['inscription']),
+      next: SatLink.fromJson(json['next']),
+      prev: SatLink.fromJson(json['prev']),
+      self: SatLink.fromJson(json['self']),
+    );
+  }
+}
+
+class SatLink {
+  final String href;
+
+  SatLink({required this.href});
+
+  factory SatLink.fromJson(Map<String, dynamic> json) {
+    return SatLink(href: json['href']);
+  }
+}
diff --git a/lib/dto/ordinals/transaction_response.dart b/lib/dto/ordinals/transaction_response.dart
new file mode 100644
index 000000000..b030a1daa
--- /dev/null
+++ b/lib/dto/ordinals/transaction_response.dart
@@ -0,0 +1,78 @@
+class TransactionResponse {
+  final TransactionLinks links;
+  final List<OutputLink> inputs;
+  final InscriptionLink inscription;
+  final List<OutputLink> outputs;
+  final TransactionLink self;
+  final String transaction;
+
+  TransactionResponse({
+    required this.links,
+    required this.inputs,
+    required this.inscription,
+    required this.outputs,
+    required this.self,
+    required this.transaction,
+  });
+
+  factory TransactionResponse.fromJson(Map<String, dynamic> json) {
+    final inputsJson = json['_links']['inputs'] as List;
+    final inputs = inputsJson
+        .map((inputJson) => OutputLink.fromJson(inputJson))
+        .toList();
+
+    final outputsJson = json['_links']['outputs'] as List;
+    final outputs = outputsJson
+        .map((outputJson) => OutputLink.fromJson(outputJson))
+        .toList();
+
+    return TransactionResponse(
+      links: TransactionLinks.fromJson(json['_links']),
+      inputs: inputs,
+      inscription: InscriptionLink.fromJson(json['_links']['inscription']),
+      outputs: outputs,
+      self: TransactionLink.fromJson(json['_links']['self']),
+      transaction: json['transaction'],
+    );
+  }
+}
+
+class TransactionLinks {
+  final TransactionLink? block;
+  final InscriptionLink? inscription;
+  final TransactionLink? self;
+
+  TransactionLinks({
+    this.block,
+    this.inscription,
+    this.self,
+  });
+
+  factory TransactionLinks.fromJson(Map<String, dynamic> json) {
+    return TransactionLinks(
+      block: TransactionLink.fromJson(json['block']),
+      inscription: InscriptionLink.fromJson(json['inscription']),
+      self: TransactionLink.fromJson(json['self']),
+    );
+  }
+}
+
+class TransactionLink {
+  final String href;
+
+  TransactionLink({required this.href});
+
+  factory TransactionLink.fromJson(Map<String, dynamic> json) {
+    return TransactionLink(href: json['href']);
+  }
+}
+
+class OutputLink {
+  final String href;
+
+  OutputLink({required this.href});
+
+  factory OutputLink.fromJson(Map<String, dynamic> json) {
+    return OutputLink(href: json['href']);
+  }
+}

From 51155372d30ca33ccccd1b66c9370da9bb6e012c Mon Sep 17 00:00:00 2001
From: sneurlax <sneurlax@gmail.com>
Date: Wed, 19 Jul 2023 10:37:42 -0500
Subject: [PATCH 02/31] add inscription endpoint

---
 lib/dto/ordinals/feed_response.dart        |  24 +++-
 lib/dto/ordinals/inscription_response.dart | 123 ++++++++++-----------
 lib/services/ordinals_api.dart             |  38 ++++++-
 3 files changed, 112 insertions(+), 73 deletions(-)

diff --git a/lib/dto/ordinals/feed_response.dart b/lib/dto/ordinals/feed_response.dart
index b6af1c1ca..d958fbe4c 100644
--- a/lib/dto/ordinals/feed_response.dart
+++ b/lib/dto/ordinals/feed_response.dart
@@ -1,14 +1,28 @@
 class FeedResponse {
   final List<InscriptionLink> inscriptions;
 
-  FeedResponse(this.inscriptions);
+  FeedResponse({required this.inscriptions});
 
   factory FeedResponse.fromJson(Map<String, dynamic> json) {
-    final inscriptionsJson = json['_links']['inscriptions'] as List;
-    final inscriptions = inscriptionsJson
-        .map((inscriptionJson) => InscriptionLink.fromJson(inscriptionJson))
+    final List<dynamic> inscriptionsJson = json['_links']['inscriptions'] as List<dynamic>;
+    final List<InscriptionLink> inscriptions = inscriptionsJson
+        .map((json) => InscriptionLink.fromJson(json as Map<String, dynamic>))
         .toList();
 
-    return FeedResponse(inscriptions);
+    return FeedResponse(inscriptions: inscriptions);
+  }
+}
+
+class InscriptionLink {
+  final String href;
+  final String title;
+
+  InscriptionLink({required this.href, required this.title});
+
+  factory InscriptionLink.fromJson(Map<String, dynamic> json) {
+    return InscriptionLink(
+      href: json['href'] as String ?? '',
+      title: json['title'] as String ?? '',
+    );
   }
 }
diff --git a/lib/dto/ordinals/inscription_response.dart b/lib/dto/ordinals/inscription_response.dart
index e06ddca6d..ab093b750 100644
--- a/lib/dto/ordinals/inscription_response.dart
+++ b/lib/dto/ordinals/inscription_response.dart
@@ -1,17 +1,17 @@
 class InscriptionResponse {
-  final InscriptionLinks links;
-  final String address;
-  final int contentLength;
-  final String contentType;
-  final int genesisFee;
-  final int genesisHeight;
-  final String genesisTransaction;
-  final String location;
-  final int number;
-  final int offset;
-  final String output;
-  final dynamic sat; // Change to appropriate type if available
-  final String timestamp;
+  late final Links links;
+  late final String address;
+  late final int contentLength;
+  late final String contentType;
+  late final int genesisFee;
+  late final int genesisHeight;
+  late final String genesisTransaction;
+  late final String location;
+  late final int number;
+  late final int offset;
+  late final String output;
+  late final String? sat; // Make sure to update the type to allow null
+  late final String timestamp;
 
   InscriptionResponse({
     required this.links,
@@ -29,67 +29,62 @@ class InscriptionResponse {
     required this.timestamp,
   });
 
-  factory InscriptionResponse.fromJson(Map<String, dynamic> json) {
-    return InscriptionResponse(
-      links: InscriptionLinks.fromJson(json['_links']),
-      address: json['address'],
-      contentLength: json['content_length'],
-      contentType: json['content_type'],
-      genesisFee: json['genesis_fee'],
-      genesisHeight: json['genesis_height'],
-      genesisTransaction: json['genesis_transaction'],
-      location: json['location'],
-      number: json['number'],
-      offset: json['offset'],
-      output: json['output'],
-      sat: json['sat'],
-      timestamp: json['timestamp'],
-    );
+  InscriptionResponse.fromJson(Map<String, dynamic> json) {
+    links = Links.fromJson(json['_links'] as Map<String, dynamic>);
+    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;
   }
 }
 
-class InscriptionLinks {
-  final InscriptionLink? content;
-  final InscriptionLink? genesisTransaction;
-  final InscriptionLink? next;
-  final InscriptionLink? output;
-  final InscriptionLink? prev;
-  final InscriptionLink? preview;
-  final InscriptionLink? sat;
-  final InscriptionLink? self;
+class Links {
+  late final Link content;
+  late final Link genesisTransaction;
+  late final Link next;
+  late final Link output;
+  late final Link prev;
+  late final Link preview;
+  late final Link? sat; // Make sure to update the type to allow null
+  late final Link self;
 
-  InscriptionLinks({
-    this.content,
-    this.genesisTransaction,
-    this.next,
-    this.output,
-    this.prev,
-    this.preview,
+  Links({
+    required this.content,
+    required this.genesisTransaction,
+    required this.next,
+    required this.output,
+    required this.prev,
+    required this.preview,
     this.sat,
-    this.self,
+    required this.self,
   });
 
-  factory InscriptionLinks.fromJson(Map<String, dynamic> json) {
-    return InscriptionLinks(
-      content: InscriptionLink.fromJson(json['content']),
-      genesisTransaction: InscriptionLink.fromJson(json['genesis_transaction']),
-      next: InscriptionLink.fromJson(json['next']),
-      output: InscriptionLink.fromJson(json['output']),
-      prev: InscriptionLink.fromJson(json['prev']),
-      preview: InscriptionLink.fromJson(json['preview']),
-      sat: InscriptionLink.fromJson(json['sat']),
-      self: InscriptionLink.fromJson(json['self']),
-    );
+  Links.fromJson(Map<String, dynamic> json) {
+    content = Link.fromJson(json['content'] as Map<String, dynamic>);
+    genesisTransaction = Link.fromJson(json['genesis_transaction'] as Map<String, dynamic>);
+    next = Link.fromJson(json['next'] as Map<String, dynamic>);
+    output = Link.fromJson(json['output'] as Map<String, dynamic>);
+    prev = Link.fromJson(json['prev'] as Map<String, dynamic>);
+    preview = Link.fromJson(json['preview'] as Map<String, dynamic>);
+    sat = json['sat'] != null ? Link.fromJson(json['sat'] as Map<String, dynamic>) : null;
+    self = Link.fromJson(json['self'] as Map<String, dynamic>);
   }
 }
 
-class InscriptionLink {
-  final String href;
-  final String title;
+class Link {
+  late final String href;
 
-  InscriptionLink({required this.href, required this.title});
+  Link({required this.href});
 
-  factory InscriptionLink.fromJson(Map<String, dynamic> json) {
-    return InscriptionLink(href: json['href'], title: json['title']);
+  Link.fromJson(Map<String, dynamic> json) {
+    href = json['href'] as String;
   }
-}
+}
\ No newline at end of file
diff --git a/lib/services/ordinals_api.dart b/lib/services/ordinals_api.dart
index 97cc45834..a966988d7 100644
--- a/lib/services/ordinals_api.dart
+++ b/lib/services/ordinals_api.dart
@@ -1,9 +1,39 @@
-import 'package:stackwallet/models/ordinal.dart';
+import 'dart:convert';
+import 'package:http/http.dart' as http;
+
+import 'package:stackwallet/dto/ordinals/feed_response.dart';
+import 'package:stackwallet/dto/ordinals/inscription_response.dart';
 
 class OrdinalsAPI {
-  // dummy class with sample functions to be changed / filled out
+  final String baseUrl;
 
-  static Future<List<Ordinal>> fetch() async {
-    return [];
+  OrdinalsAPI({required this.baseUrl});
+
+  Future<Map<String, dynamic>> _getResponse(String endpoint) async {
+    final response = await http.get(Uri.parse('$baseUrl$endpoint'));
+    if (response.statusCode == 200) {
+      return _validateJson(response.body);
+    } else {
+      throw 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('Invalid JSON format');
+    }
+  }
+
+  Future<FeedResponse> getLatestInscriptions() async {
+    final response = await _getResponse('/feed');
+    return FeedResponse.fromJson(response);
+  }
+
+  Future<InscriptionResponse> getInscriptionDetails(String inscriptionId) async {
+    final response = await _getResponse('/inscription/$inscriptionId');
+    return InscriptionResponse.fromJson(response);
   }
 }

From 828782f00cd120125a9996cb9666aa8ed0c075f2 Mon Sep 17 00:00:00 2001
From: sneurlax <sneurlax@gmail.com>
Date: Wed, 19 Jul 2023 10:41:23 -0500
Subject: [PATCH 03/31] add sat endpoint

---
 lib/dto/ordinals/sat_response.dart | 36 +++++++++++++++---------------
 lib/services/ordinals_api.dart     |  6 +++++
 2 files changed, 24 insertions(+), 18 deletions(-)

diff --git a/lib/dto/ordinals/sat_response.dart b/lib/dto/ordinals/sat_response.dart
index 0f88918f3..b57ccb3cf 100644
--- a/lib/dto/ordinals/sat_response.dart
+++ b/lib/dto/ordinals/sat_response.dart
@@ -29,18 +29,18 @@ class SatResponse {
 
   factory SatResponse.fromJson(Map<String, dynamic> json) {
     return SatResponse(
-      links: SatLinks.fromJson(json['_links']),
-      block: json['block'],
-      cycle: json['cycle'],
-      decimal: json['decimal'],
-      degree: json['degree'],
-      epoch: json['epoch'],
-      name: json['name'],
-      offset: json['offset'],
-      percentile: json['percentile'],
-      period: json['period'],
-      rarity: json['rarity'],
-      timestamp: json['timestamp'],
+      links: SatLinks.fromJson(json['_links'] as Map<String, dynamic>),
+      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,
     );
   }
 }
@@ -62,11 +62,11 @@ class SatLinks {
 
   factory SatLinks.fromJson(Map<String, dynamic> json) {
     return SatLinks(
-      block: SatLink.fromJson(json['block']),
-      inscription: SatLink.fromJson(json['inscription']),
-      next: SatLink.fromJson(json['next']),
-      prev: SatLink.fromJson(json['prev']),
-      self: SatLink.fromJson(json['self']),
+      block: SatLink.fromJson(json['block'] as Map<String, dynamic>),
+      inscription: SatLink.fromJson(json['inscription'] as Map<String, dynamic>),
+      next: SatLink.fromJson(json['next'] as Map<String, dynamic>),
+      prev: SatLink.fromJson(json['prev'] as Map<String, dynamic>),
+      self: SatLink.fromJson(json['self'] as Map<String, dynamic>),
     );
   }
 }
@@ -77,6 +77,6 @@ class SatLink {
   SatLink({required this.href});
 
   factory SatLink.fromJson(Map<String, dynamic> json) {
-    return SatLink(href: json['href']);
+    return SatLink(href: json['href'] as String);
   }
 }
diff --git a/lib/services/ordinals_api.dart b/lib/services/ordinals_api.dart
index a966988d7..264223f8a 100644
--- a/lib/services/ordinals_api.dart
+++ b/lib/services/ordinals_api.dart
@@ -3,6 +3,7 @@ import 'package:http/http.dart' as http;
 
 import 'package:stackwallet/dto/ordinals/feed_response.dart';
 import 'package:stackwallet/dto/ordinals/inscription_response.dart';
+import 'package:stackwallet/dto/ordinals/sat_response.dart';
 
 class OrdinalsAPI {
   final String baseUrl;
@@ -36,4 +37,9 @@ class OrdinalsAPI {
     final response = await _getResponse('/inscription/$inscriptionId');
     return InscriptionResponse.fromJson(response);
   }
+
+  Future<SatResponse> getSatDetails(int satNumber) async {
+    final response = await _getResponse('/sat/$satNumber');
+    return SatResponse.fromJson(response);
+  }
 }

From 48e4f8c57790bd790fd194069f55f9e94d59e169 Mon Sep 17 00:00:00 2001
From: sneurlax <sneurlax@gmail.com>
Date: Wed, 19 Jul 2023 10:45:18 -0500
Subject: [PATCH 04/31] add output endpoint

---
 .../{output_response => output_response.dart}    | 16 +++++++++-------
 lib/services/ordinals_api.dart                   | 12 ++++++++++++
 2 files changed, 21 insertions(+), 7 deletions(-)
 rename lib/dto/ordinals/{output_response => output_response.dart} (57%)

diff --git a/lib/dto/ordinals/output_response b/lib/dto/ordinals/output_response.dart
similarity index 57%
rename from lib/dto/ordinals/output_response
rename to lib/dto/ordinals/output_response.dart
index cd25fe961..6faf40845 100644
--- a/lib/dto/ordinals/output_response
+++ b/lib/dto/ordinals/output_response.dart
@@ -1,3 +1,5 @@
+import 'package:stackwallet/dto/ordinals/transaction_response.dart';
+
 class OutputResponse {
   final OutputLinks links;
   final String address;
@@ -15,11 +17,11 @@ class OutputResponse {
 
   factory OutputResponse.fromJson(Map<String, dynamic> json) {
     return OutputResponse(
-      links: OutputLinks.fromJson(json['_links']),
-      address: json['address'],
-      scriptPubkey: json['script_pubkey'],
-      transaction: json['transaction'],
-      value: json['value'],
+      links: OutputLinks.fromJson(json['_links'] as Map<String, dynamic>),
+      address: json['address'] as String,
+      scriptPubkey: json['script_pubkey'] as String,
+      transaction: json['transaction'] as String,
+      value: json['value'] as int,
     );
   }
 }
@@ -35,8 +37,8 @@ class OutputLinks {
 
   factory OutputLinks.fromJson(Map<String, dynamic> json) {
     return OutputLinks(
-      self: OutputLink.fromJson(json['self']),
-      transaction: TransactionLink.fromJson(json['transaction']),
+      self: OutputLink.fromJson(json['self'] as Map<String, dynamic>),
+      transaction: TransactionLink.fromJson(json['transaction'] as Map<String, dynamic>),
     );
   }
 }
\ No newline at end of file
diff --git a/lib/services/ordinals_api.dart b/lib/services/ordinals_api.dart
index 264223f8a..e83e9eb9e 100644
--- a/lib/services/ordinals_api.dart
+++ b/lib/services/ordinals_api.dart
@@ -4,6 +4,8 @@ import 'package:http/http.dart' as http;
 import 'package:stackwallet/dto/ordinals/feed_response.dart';
 import 'package:stackwallet/dto/ordinals/inscription_response.dart';
 import 'package:stackwallet/dto/ordinals/sat_response.dart';
+import 'package:stackwallet/dto/ordinals/transaction_response.dart';
+import 'package:stackwallet/dto/ordinals/output_response.dart';
 
 class OrdinalsAPI {
   final String baseUrl;
@@ -42,4 +44,14 @@ class OrdinalsAPI {
     final response = await _getResponse('/sat/$satNumber');
     return SatResponse.fromJson(response);
   }
+
+  Future<TransactionResponse> getTransaction(String transactionId) async {
+    final response = await _getResponse('/tx/$transactionId');
+    return TransactionResponse.fromJson(response);
+  }
+
+  Future<OutputResponse> getTransactionOutputs(String transactionId) async {
+    final response = await _getResponse('/output/$transactionId');
+    return OutputResponse.fromJson(response);
+  }
 }

From f972c34dc4eb0a7f19627da3b4ecd0e375bce8a9 Mon Sep 17 00:00:00 2001
From: sneurlax <sneurlax@gmail.com>
Date: Wed, 19 Jul 2023 10:48:54 -0500
Subject: [PATCH 05/31] add address endpoint

---
 lib/dto/ordinals/address_response.dart | 23 ++++++++++++++++++-----
 lib/dto/ordinals/output_response.dart  |  2 +-
 lib/services/ordinals_api.dart         |  6 ++++++
 3 files changed, 25 insertions(+), 6 deletions(-)

diff --git a/lib/dto/ordinals/address_response.dart b/lib/dto/ordinals/address_response.dart
index 024543b92..7932d8ec7 100644
--- a/lib/dto/ordinals/address_response.dart
+++ b/lib/dto/ordinals/address_response.dart
@@ -1,3 +1,5 @@
+import 'package:stackwallet/dto/ordinals/inscription_response.dart';
+
 class AddressResponse {
   final AddressLinks links;
   final String address;
@@ -12,12 +14,12 @@ class AddressResponse {
   factory AddressResponse.fromJson(Map<String, dynamic> json) {
     final inscriptionsJson = json['inscriptions'] as List;
     final inscriptions = inscriptionsJson
-        .map((inscriptionJson) => InscriptionLink.fromJson(inscriptionJson))
+        .map((inscriptionJson) => InscriptionLink.fromJson(inscriptionJson as Map<String, dynamic>))
         .toList();
 
     return AddressResponse(
-      links: AddressLinks.fromJson(json['_links']),
-      address: json['address'],
+      links: AddressLinks.fromJson(json['_links'] as Map<String, dynamic>),
+      address: json['address'] as String,
       inscriptions: inscriptions,
     );
   }
@@ -32,7 +34,7 @@ class AddressLinks {
 
   factory AddressLinks.fromJson(Map<String, dynamic> json) {
     return AddressLinks(
-      self: AddressLink.fromJson(json['self']),
+      self: AddressLink.fromJson(json['self'] as Map<String, dynamic>),
     );
   }
 }
@@ -43,6 +45,17 @@ class AddressLink {
   AddressLink({required this.href});
 
   factory AddressLink.fromJson(Map<String, dynamic> json) {
-    return AddressLink(href: json['href']);
+    return AddressLink(href: json['href'] as String);
+  }
+}
+
+class InscriptionLink {
+  final String href;
+  final String title;
+
+  InscriptionLink(this.href, this.title);
+
+  factory InscriptionLink.fromJson(Map<String, dynamic> json) {
+    return InscriptionLink(json['href'] as String, json['title'] as String);
   }
 }
diff --git a/lib/dto/ordinals/output_response.dart b/lib/dto/ordinals/output_response.dart
index 6faf40845..cd4bde563 100644
--- a/lib/dto/ordinals/output_response.dart
+++ b/lib/dto/ordinals/output_response.dart
@@ -41,4 +41,4 @@ class OutputLinks {
       transaction: TransactionLink.fromJson(json['transaction'] as Map<String, dynamic>),
     );
   }
-}
\ No newline at end of file
+}
diff --git a/lib/services/ordinals_api.dart b/lib/services/ordinals_api.dart
index e83e9eb9e..a0586d1ec 100644
--- a/lib/services/ordinals_api.dart
+++ b/lib/services/ordinals_api.dart
@@ -6,6 +6,7 @@ import 'package:stackwallet/dto/ordinals/inscription_response.dart';
 import 'package:stackwallet/dto/ordinals/sat_response.dart';
 import 'package:stackwallet/dto/ordinals/transaction_response.dart';
 import 'package:stackwallet/dto/ordinals/output_response.dart';
+import 'package:stackwallet/dto/ordinals/address_response.dart';
 
 class OrdinalsAPI {
   final String baseUrl;
@@ -54,4 +55,9 @@ class OrdinalsAPI {
     final response = await _getResponse('/output/$transactionId');
     return OutputResponse.fromJson(response);
   }
+
+  Future<AddressResponse> getInscriptionsByAddress(String address) async {
+    final response = await _getResponse('/address/$address');
+    return AddressResponse.fromJson(response);
+  }
 }

From 6d772b0acdabdd19f0ed66663528a9a2912eb165 Mon Sep 17 00:00:00 2001
From: sneurlax <sneurlax@gmail.com>
Date: Wed, 19 Jul 2023 10:50:56 -0500
Subject: [PATCH 06/31] add block endpoint

---
 lib/dto/ordinals/block_response.dart | 20 ++++++++++----------
 lib/services/ordinals_api.dart       |  6 ++++++
 2 files changed, 16 insertions(+), 10 deletions(-)

diff --git a/lib/dto/ordinals/block_response.dart b/lib/dto/ordinals/block_response.dart
index 365098594..a3de1ee1c 100644
--- a/lib/dto/ordinals/block_response.dart
+++ b/lib/dto/ordinals/block_response.dart
@@ -19,13 +19,13 @@ class BlockResponse {
 
   factory BlockResponse.fromJson(Map<String, dynamic> json) {
     return BlockResponse(
-      links: BlockLinks.fromJson(json['_links']),
-      hash: json['hash'],
-      previousBlockhash: json['previous_blockhash'],
-      size: json['size'],
-      target: json['target'],
-      timestamp: json['timestamp'],
-      weight: json['weight'],
+      links: BlockLinks.fromJson(json['_links'] as Map<String, dynamic>),
+      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,
     );
   }
 }
@@ -41,8 +41,8 @@ class BlockLinks {
 
   factory BlockLinks.fromJson(Map<String, dynamic> json) {
     return BlockLinks(
-      prev: BlockLink.fromJson(json['prev']),
-      self: BlockLink.fromJson(json['self']),
+      prev: BlockLink.fromJson(json['prev'] as Map<String, dynamic>),
+      self: BlockLink.fromJson(json['self'] as Map<String, dynamic>),
     );
   }
 }
@@ -53,6 +53,6 @@ class BlockLink {
   BlockLink({required this.href});
 
   factory BlockLink.fromJson(Map<String, dynamic> json) {
-    return BlockLink(href: json['href']);
+    return BlockLink(href: json['href'] as String);
   }
 }
diff --git a/lib/services/ordinals_api.dart b/lib/services/ordinals_api.dart
index a0586d1ec..de9740554 100644
--- a/lib/services/ordinals_api.dart
+++ b/lib/services/ordinals_api.dart
@@ -7,6 +7,7 @@ import 'package:stackwallet/dto/ordinals/sat_response.dart';
 import 'package:stackwallet/dto/ordinals/transaction_response.dart';
 import 'package:stackwallet/dto/ordinals/output_response.dart';
 import 'package:stackwallet/dto/ordinals/address_response.dart';
+import 'package:stackwallet/dto/ordinals/block_response.dart';
 
 class OrdinalsAPI {
   final String baseUrl;
@@ -60,4 +61,9 @@ class OrdinalsAPI {
     final response = await _getResponse('/address/$address');
     return AddressResponse.fromJson(response);
   }
+
+  Future<BlockResponse> getBlock(int blockNumber) async {
+    final response = await _getResponse('/block/$blockNumber');
+    return BlockResponse.fromJson(response);
+  }
 }

From d623480a758ee0a1acdfdc707ea503be03f314d2 Mon Sep 17 00:00:00 2001
From: sneurlax <sneurlax@gmail.com>
Date: Wed, 19 Jul 2023 10:51:46 -0500
Subject: [PATCH 07/31] add content endpoint

---
 lib/dto/ordinals/content_response.dart | 4 ++--
 lib/services/ordinals_api.dart         | 6 ++++++
 2 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/lib/dto/ordinals/content_response.dart b/lib/dto/ordinals/content_response.dart
index 35a2c8ef8..d1131950b 100644
--- a/lib/dto/ordinals/content_response.dart
+++ b/lib/dto/ordinals/content_response.dart
@@ -4,7 +4,7 @@ class ContentResponse {
   ContentResponse({required this.fileLink});
 
   factory ContentResponse.fromJson(Map<String, dynamic> json) {
-    return ContentResponse(fileLink: FileLink.fromJson(json['_links']['file']));
+    return ContentResponse(fileLink: FileLink.fromJson(json['_links']['file'] as Map<String, dynamic>));
   }
 }
 
@@ -14,6 +14,6 @@ class FileLink {
   FileLink({required this.href});
 
   factory FileLink.fromJson(Map<String, dynamic> json) {
-    return FileLink(href: json['href']);
+    return FileLink(href: json['href'] as String);
   }
 }
diff --git a/lib/services/ordinals_api.dart b/lib/services/ordinals_api.dart
index de9740554..4228ddd72 100644
--- a/lib/services/ordinals_api.dart
+++ b/lib/services/ordinals_api.dart
@@ -8,6 +8,7 @@ import 'package:stackwallet/dto/ordinals/transaction_response.dart';
 import 'package:stackwallet/dto/ordinals/output_response.dart';
 import 'package:stackwallet/dto/ordinals/address_response.dart';
 import 'package:stackwallet/dto/ordinals/block_response.dart';
+import 'package:stackwallet/dto/ordinals/content_response.dart';
 
 class OrdinalsAPI {
   final String baseUrl;
@@ -66,4 +67,9 @@ class OrdinalsAPI {
     final response = await _getResponse('/block/$blockNumber');
     return BlockResponse.fromJson(response);
   }
+
+  Future<ContentResponse> getInscriptionContent(String inscriptionId) async {
+    final response = await _getResponse('/content/$inscriptionId');
+    return ContentResponse.fromJson(response);
+  }
 }

From 697f40fce1835e1e6cd494fb6a99a02bf319b11d Mon Sep 17 00:00:00 2001
From: sneurlax <sneurlax@gmail.com>
Date: Wed, 19 Jul 2023 10:55:46 -0500
Subject: [PATCH 08/31] add preview endpoint

---
 lib/dto/ordinals/preview_response.dart | 4 ++--
 lib/services/ordinals_api.dart         | 6 ++++++
 2 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/lib/dto/ordinals/preview_response.dart b/lib/dto/ordinals/preview_response.dart
index d7171702d..9eabd590a 100644
--- a/lib/dto/ordinals/preview_response.dart
+++ b/lib/dto/ordinals/preview_response.dart
@@ -4,7 +4,7 @@ class PreviewResponse {
   PreviewResponse({required this.imageLink});
 
   factory PreviewResponse.fromJson(Map<String, dynamic> json) {
-    return PreviewResponse(imageLink: ImageLink.fromJson(json['_links']['image']));
+    return PreviewResponse(imageLink: ImageLink.fromJson(json['_links']['image'] as Map<String, dynamic>));
   }
 }
 
@@ -14,6 +14,6 @@ class ImageLink {
   ImageLink({required this.href});
 
   factory ImageLink.fromJson(Map<String, dynamic> json) {
-    return ImageLink(href: json['href']);
+    return ImageLink(href: json['href'] as String);
   }
 }
\ No newline at end of file
diff --git a/lib/services/ordinals_api.dart b/lib/services/ordinals_api.dart
index 4228ddd72..4d8360e06 100644
--- a/lib/services/ordinals_api.dart
+++ b/lib/services/ordinals_api.dart
@@ -9,6 +9,7 @@ import 'package:stackwallet/dto/ordinals/output_response.dart';
 import 'package:stackwallet/dto/ordinals/address_response.dart';
 import 'package:stackwallet/dto/ordinals/block_response.dart';
 import 'package:stackwallet/dto/ordinals/content_response.dart';
+import 'package:stackwallet/dto/ordinals/preview_response.dart';
 
 class OrdinalsAPI {
   final String baseUrl;
@@ -72,4 +73,9 @@ class OrdinalsAPI {
     final response = await _getResponse('/content/$inscriptionId');
     return ContentResponse.fromJson(response);
   }
+
+  Future<PreviewResponse> getInscriptionPreview(String inscriptionId) async {
+    final response = await _getResponse('/preview/$inscriptionId');
+    return PreviewResponse.fromJson(response);
+  }
 }

From afbf818ab5815b07481bab41e1c1c27ffa704751 Mon Sep 17 00:00:00 2001
From: sneurlax <sneurlax@gmail.com>
Date: Wed, 19 Jul 2023 11:04:19 -0500
Subject: [PATCH 09/31] refactor InscriptionLink factory, casting

TODO replace casting throughout ordinals DTOs with refactored validation
---
 lib/dto/ordinals/address_response.dart     | 13 +-----------
 lib/dto/ordinals/feed_response.dart        | 16 ++-------------
 lib/dto/ordinals/inscription_link.dart     | 13 ++++++++++++
 lib/dto/ordinals/transaction_response.dart | 24 ++++++++++++----------
 4 files changed, 29 insertions(+), 37 deletions(-)
 create mode 100644 lib/dto/ordinals/inscription_link.dart

diff --git a/lib/dto/ordinals/address_response.dart b/lib/dto/ordinals/address_response.dart
index 7932d8ec7..5c1f66323 100644
--- a/lib/dto/ordinals/address_response.dart
+++ b/lib/dto/ordinals/address_response.dart
@@ -1,4 +1,4 @@
-import 'package:stackwallet/dto/ordinals/inscription_response.dart';
+import 'package:stackwallet/dto/ordinals/inscription_link.dart';
 
 class AddressResponse {
   final AddressLinks links;
@@ -48,14 +48,3 @@ class AddressLink {
     return AddressLink(href: json['href'] as String);
   }
 }
-
-class InscriptionLink {
-  final String href;
-  final String title;
-
-  InscriptionLink(this.href, this.title);
-
-  factory InscriptionLink.fromJson(Map<String, dynamic> json) {
-    return InscriptionLink(json['href'] as String, json['title'] as String);
-  }
-}
diff --git a/lib/dto/ordinals/feed_response.dart b/lib/dto/ordinals/feed_response.dart
index d958fbe4c..e29d2d334 100644
--- a/lib/dto/ordinals/feed_response.dart
+++ b/lib/dto/ordinals/feed_response.dart
@@ -1,3 +1,5 @@
+import 'package:stackwallet/dto/ordinals/inscription_link.dart';
+
 class FeedResponse {
   final List<InscriptionLink> inscriptions;
 
@@ -12,17 +14,3 @@ class FeedResponse {
     return FeedResponse(inscriptions: inscriptions);
   }
 }
-
-class InscriptionLink {
-  final String href;
-  final String title;
-
-  InscriptionLink({required this.href, required this.title});
-
-  factory InscriptionLink.fromJson(Map<String, dynamic> json) {
-    return InscriptionLink(
-      href: json['href'] as String ?? '',
-      title: json['title'] as String ?? '',
-    );
-  }
-}
diff --git a/lib/dto/ordinals/inscription_link.dart b/lib/dto/ordinals/inscription_link.dart
new file mode 100644
index 000000000..f23b63248
--- /dev/null
+++ b/lib/dto/ordinals/inscription_link.dart
@@ -0,0 +1,13 @@
+class InscriptionLink {
+  final String href;
+  final String title;
+
+  InscriptionLink({required this.href, required this.title});
+
+  factory InscriptionLink.fromJson(Map<String, dynamic> json) {
+    return InscriptionLink(
+      href: json['href'] as String ?? '',
+      title: json['title'] as String ?? '',
+    );
+  }
+}
diff --git a/lib/dto/ordinals/transaction_response.dart b/lib/dto/ordinals/transaction_response.dart
index b030a1daa..11912a3ad 100644
--- a/lib/dto/ordinals/transaction_response.dart
+++ b/lib/dto/ordinals/transaction_response.dart
@@ -1,3 +1,5 @@
+import 'package:stackwallet/dto/ordinals/inscription_link.dart';
+
 class TransactionResponse {
   final TransactionLinks links;
   final List<OutputLink> inputs;
@@ -18,21 +20,21 @@ class TransactionResponse {
   factory TransactionResponse.fromJson(Map<String, dynamic> json) {
     final inputsJson = json['_links']['inputs'] as List;
     final inputs = inputsJson
-        .map((inputJson) => OutputLink.fromJson(inputJson))
+        .map((inputJson) => OutputLink.fromJson(inputJson as Map<String, dynamic>))
         .toList();
 
     final outputsJson = json['_links']['outputs'] as List;
     final outputs = outputsJson
-        .map((outputJson) => OutputLink.fromJson(outputJson))
+        .map((outputJson) => OutputLink.fromJson(outputJson as Map<String, dynamic>))
         .toList();
 
     return TransactionResponse(
-      links: TransactionLinks.fromJson(json['_links']),
+      links: TransactionLinks.fromJson(json['_links'] as Map<String, dynamic>),
       inputs: inputs,
-      inscription: InscriptionLink.fromJson(json['_links']['inscription']),
+      inscription: InscriptionLink.fromJson(json['_links']['inscription'] as Map<String, dynamic>),
       outputs: outputs,
-      self: TransactionLink.fromJson(json['_links']['self']),
-      transaction: json['transaction'],
+      self: TransactionLink.fromJson(json['_links']['self'] as Map<String, dynamic>),
+      transaction: json['transaction'] as String,
     );
   }
 }
@@ -50,9 +52,9 @@ class TransactionLinks {
 
   factory TransactionLinks.fromJson(Map<String, dynamic> json) {
     return TransactionLinks(
-      block: TransactionLink.fromJson(json['block']),
-      inscription: InscriptionLink.fromJson(json['inscription']),
-      self: TransactionLink.fromJson(json['self']),
+      block: TransactionLink.fromJson(json['block'] as Map<String, dynamic>),
+      inscription: InscriptionLink.fromJson(json['inscription'] as Map<String, dynamic>),
+      self: TransactionLink.fromJson(json['self'] as Map<String, dynamic>),
     );
   }
 }
@@ -63,7 +65,7 @@ class TransactionLink {
   TransactionLink({required this.href});
 
   factory TransactionLink.fromJson(Map<String, dynamic> json) {
-    return TransactionLink(href: json['href']);
+    return TransactionLink(href: json['href'] as String);
   }
 }
 
@@ -73,6 +75,6 @@ class OutputLink {
   OutputLink({required this.href});
 
   factory OutputLink.fromJson(Map<String, dynamic> json) {
-    return OutputLink(href: json['href']);
+    return OutputLink(href: json['href'] as String);
   }
 }

From 8e17556e4128f00f915460f19eb7464c5ae54e16 Mon Sep 17 00:00:00 2001
From: sneurlax <sneurlax@gmail.com>
Date: Wed, 19 Jul 2023 13:03:17 -0500
Subject: [PATCH 10/31] 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<AddressResponse> {
   final AddressLinks links;
   final String address;
   final List<InscriptionLink> inscriptions;
@@ -11,15 +12,16 @@ class AddressResponse {
     required this.inscriptions,
   });
 
-  factory AddressResponse.fromJson(Map<String, dynamic> json) {
-    final inscriptionsJson = json['inscriptions'] as List;
+  factory AddressResponse.fromJson(OrdinalsResponse json) {
+    final data = json.data as Map<String, dynamic>;
+    final inscriptionsJson = data['inscriptions'] as List;
     final inscriptions = inscriptionsJson
         .map((inscriptionJson) => InscriptionLink.fromJson(inscriptionJson as Map<String, dynamic>))
         .toList();
 
     return AddressResponse(
-      links: AddressLinks.fromJson(json['_links'] as Map<String, dynamic>),
-      address: json['address'] as String,
+      links: AddressLinks.fromJson(data['_links'] as Map<String, dynamic>),
+      address: data['address'] as String,
       inscriptions: inscriptions,
     );
   }
@@ -34,7 +36,7 @@ class AddressLinks {
 
   factory AddressLinks.fromJson(Map<String, dynamic> json) {
     return AddressLinks(
-      self: AddressLink.fromJson(json['self'] as Map<String, dynamic>),
+      self: json['self'] != null ? AddressLink.fromJson(json['self'] as Map<String, dynamic>) : 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<BlockResponse> {
   final BlockLinks links;
   final String hash;
   final String previousBlockhash;
@@ -17,15 +19,16 @@ class BlockResponse {
     required this.weight,
   });
 
-  factory BlockResponse.fromJson(Map<String, dynamic> json) {
+  factory BlockResponse.fromJson(OrdinalsResponse json) {
+    final data = json.data as Map<String, dynamic>;
     return BlockResponse(
-      links: BlockLinks.fromJson(json['_links'] as Map<String, dynamic>),
-      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<String, dynamic>),
+      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<String, dynamic> json) {
     return BlockLinks(
-      prev: BlockLink.fromJson(json['prev'] as Map<String, dynamic>),
-      self: BlockLink.fromJson(json['self'] as Map<String, dynamic>),
+      prev: json['prev'] != null ? BlockLink.fromJson(json['prev'] as Map<String, dynamic>) : null,
+      self: json['self'] != null ? BlockLink.fromJson(json['self'] as Map<String, dynamic>) : 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<ContentResponse> {
   final FileLink fileLink;
 
   ContentResponse({required this.fileLink});
 
-  factory ContentResponse.fromJson(Map<String, dynamic> json) {
-    return ContentResponse(fileLink: FileLink.fromJson(json['_links']['file'] as Map<String, dynamic>));
+  factory ContentResponse.fromJson(OrdinalsResponse json) {
+    final data = json.data as Map<String, dynamic>;
+    return ContentResponse(fileLink: FileLink.fromJson(data['_links']['file'] as Map<String, dynamic>)); // TODO don't cast as Map<String, dynamic>
   }
 }
 
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<FeedResponse> {
   final List<InscriptionLink> inscriptions;
 
   FeedResponse({required this.inscriptions});
-
-  factory FeedResponse.fromJson(Map<String, dynamic> json) {
-    final List<dynamic> inscriptionsJson = json['_links']['inscriptions'] as List<dynamic>;
+  
+  factory FeedResponse.fromJson(OrdinalsResponse json) {
+    final List<dynamic> inscriptionsJson = json.data['_links']['inscriptions'] as List<dynamic>;
     final List<InscriptionLink> inscriptions = inscriptionsJson
         .map((json) => InscriptionLink.fromJson(json as Map<String, dynamic>))
         .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<InscriptionResponse> {
   late final Links links;
   late final String address;
   late final int contentLength;
@@ -29,20 +31,23 @@ class InscriptionResponse {
     required this.timestamp,
   });
 
-  InscriptionResponse.fromJson(Map<String, dynamic> json) {
-    links = Links.fromJson(json['_links'] as Map<String, dynamic>);
-    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<String, dynamic>;
+    return InscriptionResponse(
+      links: Links.fromJson(data['_links'] as Map<String, dynamic>),
+      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<String, dynamic> json) {
-    content = Link.fromJson(json['content'] as Map<String, dynamic>);
-    genesisTransaction = Link.fromJson(json['genesis_transaction'] as Map<String, dynamic>);
-    next = Link.fromJson(json['next'] as Map<String, dynamic>);
-    output = Link.fromJson(json['output'] as Map<String, dynamic>);
-    prev = Link.fromJson(json['prev'] as Map<String, dynamic>);
-    preview = Link.fromJson(json['preview'] as Map<String, dynamic>);
-    sat = json['sat'] != null ? Link.fromJson(json['sat'] as Map<String, dynamic>) : null;
-    self = Link.fromJson(json['self'] as Map<String, dynamic>);
+  factory Links.fromJson(Map<String, dynamic> json) {
+    return Links(
+      content: Link.fromJson(json['content'] as Map<String, dynamic>),
+      genesisTransaction: Link.fromJson(json['genesis_transaction'] as Map<String, dynamic>),
+      next: Link.fromJson(json['next'] as Map<String, dynamic>),
+      output: Link.fromJson(json['output'] as Map<String, dynamic>),
+      prev: Link.fromJson(json['prev'] as Map<String, dynamic>),
+      preview: Link.fromJson(json['preview'] as Map<String, dynamic>),
+      sat: json['sat'] != null ? Link.fromJson(json['sat'] as Map<String, dynamic>) : null,
+      self: Link.fromJson(json['self'] as Map<String, dynamic>),
+    );
   }
 }
 
@@ -84,7 +91,7 @@ class Link {
 
   Link({required this.href});
 
-  Link.fromJson(Map<String, dynamic> json) {
-    href = json['href'] as String;
+  factory Link.fromJson(Map<String, dynamic> 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<T> {
+  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<OutputResponse> {
   final OutputLinks links;
   final String address;
   final String scriptPubkey;
@@ -15,13 +16,15 @@ class OutputResponse {
     required this.value,
   });
 
-  factory OutputResponse.fromJson(Map<String, dynamic> json) {
+  factory OutputResponse.fromJson(OrdinalsResponse json) {
+    final data = json.data as Map<String, dynamic>;
+
     return OutputResponse(
-      links: OutputLinks.fromJson(json['_links'] as Map<String, dynamic>),
-      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<String, dynamic>),
+      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<String, dynamic> json) {
     return OutputLinks(
-      self: OutputLink.fromJson(json['self'] as Map<String, dynamic>),
-      transaction: TransactionLink.fromJson(json['transaction'] as Map<String, dynamic>),
+      self: json['self'] != null ? OutputLink.fromJson(json['self'] as Map<String, dynamic>) : null,
+      transaction: json['transaction'] != null ? TransactionLink.fromJson(json['transaction'] as Map<String, dynamic>) : 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<PreviewResponse> {
   final ImageLink imageLink;
 
   PreviewResponse({required this.imageLink});
 
-  factory PreviewResponse.fromJson(Map<String, dynamic> json) {
-    return PreviewResponse(imageLink: ImageLink.fromJson(json['_links']['image'] as Map<String, dynamic>));
+  factory PreviewResponse.fromJson(OrdinalsResponse json) {
+    final data = json.data as Map<String, dynamic>;
+    return PreviewResponse(imageLink: ImageLink.fromJson(data['_links']['image'] as Map<String, dynamic>));
   }
 }
 
@@ -16,4 +19,4 @@ class ImageLink {
   factory ImageLink.fromJson(Map<String, dynamic> 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<SatResponse> {
   final SatLinks links;
   final int block;
   final int cycle;
@@ -27,20 +29,21 @@ class SatResponse {
     required this.timestamp,
   });
 
-  factory SatResponse.fromJson(Map<String, dynamic> json) {
+  factory SatResponse.fromJson(OrdinalsResponse json) {
+    final data = json.data as Map<String, dynamic>;
     return SatResponse(
-      links: SatLinks.fromJson(json['_links'] as Map<String, dynamic>),
-      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<String, dynamic>),
+      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<String, dynamic> json) {
     return SatLinks(
-      block: SatLink.fromJson(json['block'] as Map<String, dynamic>),
-      inscription: SatLink.fromJson(json['inscription'] as Map<String, dynamic>),
-      next: SatLink.fromJson(json['next'] as Map<String, dynamic>),
-      prev: SatLink.fromJson(json['prev'] as Map<String, dynamic>),
-      self: SatLink.fromJson(json['self'] as Map<String, dynamic>),
+      block: json['block'] != null ? SatLink.fromJson(json['block'] as Map<String, dynamic>) : null,
+      inscription: json['inscription'] != null ? SatLink.fromJson(json['inscription'] as Map<String, dynamic>) : null,
+      next: json['next'] != null ? SatLink.fromJson(json['next'] as Map<String, dynamic>) : null,
+      prev: json['prev'] != null ? SatLink.fromJson(json['prev'] as Map<String, dynamic>) : null,
+      self: json['self'] != null ? SatLink.fromJson(json['self'] as Map<String, dynamic>) : 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<TransactionResponse> {
   final TransactionLinks links;
   final List<OutputLink> inputs;
   final InscriptionLink inscription;
@@ -17,24 +18,25 @@ class TransactionResponse {
     required this.transaction,
   });
 
-  factory TransactionResponse.fromJson(Map<String, dynamic> json) {
-    final inputsJson = json['_links']['inputs'] as List;
+  factory TransactionResponse.fromJson(OrdinalsResponse json) {
+    final data = json.data as Map<String, dynamic>;
+    final inputsJson = data['_links']['inputs'] as List;
     final inputs = inputsJson
         .map((inputJson) => OutputLink.fromJson(inputJson as Map<String, dynamic>))
         .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<String, dynamic>))
         .toList();
 
     return TransactionResponse(
-      links: TransactionLinks.fromJson(json['_links'] as Map<String, dynamic>),
+      links: TransactionLinks.fromJson(data['_links'] as Map<String, dynamic>),
       inputs: inputs,
-      inscription: InscriptionLink.fromJson(json['_links']['inscription'] as Map<String, dynamic>),
+      inscription: InscriptionLink.fromJson(data['_links']['inscription'] as Map<String, dynamic>),
       outputs: outputs,
-      self: TransactionLink.fromJson(json['_links']['self'] as Map<String, dynamic>),
-      transaction: json['transaction'] as String,
+      self: TransactionLink.fromJson(data['_links']['self'] as Map<String, dynamic>),
+      transaction: data['transaction'] as String,
     );
   }
 }
@@ -52,9 +54,9 @@ class TransactionLinks {
 
   factory TransactionLinks.fromJson(Map<String, dynamic> json) {
     return TransactionLinks(
-      block: TransactionLink.fromJson(json['block'] as Map<String, dynamic>),
-      inscription: InscriptionLink.fromJson(json['inscription'] as Map<String, dynamic>),
-      self: TransactionLink.fromJson(json['self'] as Map<String, dynamic>),
+      block: json['block'] != null ? TransactionLink.fromJson(json['block'] as Map<String, dynamic>) : null,
+      inscription: json['inscription'] != null ? InscriptionLink.fromJson(json['inscription'] as Map<String, dynamic>) : null,
+      self: json['self'] != null ? TransactionLink.fromJson(json['self'] as Map<String, dynamic>) : 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<FeedResponse> 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<Map<String, dynamic>> _getResponse(String endpoint) async {
+  Future<OrdinalsResponse> _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');
     }

From bc8f5ce8f93ba2d7163a7d47878c92522314ca69 Mon Sep 17 00:00:00 2001
From: sneurlax <sneurlax@gmail.com>
Date: Wed, 19 Jul 2023 15:58:26 -0500
Subject: [PATCH 11/31] update OrdinalsInterface to not need baseUrl declared
 by withee classes

---
 lib/services/mixins/ordinals_interface.dart | 10 ++++++----
 lib/services/ordinals_api.dart              | 15 ++++++++++++---
 2 files changed, 18 insertions(+), 7 deletions(-)

diff --git a/lib/services/mixins/ordinals_interface.dart b/lib/services/mixins/ordinals_interface.dart
index 57a76fbd6..1ab157b2c 100644
--- a/lib/services/mixins/ordinals_interface.dart
+++ b/lib/services/mixins/ordinals_interface.dart
@@ -1,8 +1,10 @@
-import 'package:stackwallet/services/ordinals_api.dart';
-import 'package:stackwallet/dto/ordinals/feed_response.dart';
+import 'package:stackwallet/dto/ordinals/feed_response.dart'; // Assuming this import is necessary
+import 'package:stackwallet/services/ordinals_api.dart'; // Assuming this import is necessary
 
 mixin OrdinalsInterface {
-  Future<FeedResponse> fetchLatestInscriptions(OrdinalsAPI ordinalsAPI) async {
+  final OrdinalsAPI ordinalsAPI = OrdinalsAPI(baseUrl: 'http://ord-litecoin.stackwallet.com');
+
+  Future<FeedResponse> fetchLatestInscriptions() async {
     try {
       final feedResponse = await ordinalsAPI.getLatestInscriptions();
       // Process the feedResponse data as needed
@@ -16,4 +18,4 @@ mixin OrdinalsInterface {
       throw Exception('Error in OrdinalsInterface: $e');
     }
   }
-}
+}
\ No newline at end of file
diff --git a/lib/services/ordinals_api.dart b/lib/services/ordinals_api.dart
index e9d734203..c1d3aad94 100644
--- a/lib/services/ordinals_api.dart
+++ b/lib/services/ordinals_api.dart
@@ -12,10 +12,19 @@ import 'package:stackwallet/dto/ordinals/block_response.dart';
 import 'package:stackwallet/dto/ordinals/content_response.dart';
 import 'package:stackwallet/dto/ordinals/preview_response.dart';
 
-class OrdinalsAPI {
-  final String baseUrl;
+import 'package:stackwallet/dto/ordinals/feed_response.dart'; // Assuming this import is necessary
 
-  OrdinalsAPI({required this.baseUrl});
+class OrdinalsAPI {
+  static final OrdinalsAPI _instance = OrdinalsAPI._internal();
+
+  factory OrdinalsAPI({required String baseUrl}) {
+    _instance.baseUrl = baseUrl;
+    return _instance;
+  }
+
+  OrdinalsAPI._internal();
+
+  late String baseUrl;
 
   Future<OrdinalsResponse> _getResponse(String endpoint) async {
     final response = await http.get(Uri.parse('$baseUrl$endpoint'));

From 2de8ffe5934d9534d79705a16e7d991c2c2369fe Mon Sep 17 00:00:00 2001
From: sneurlax <sneurlax@gmail.com>
Date: Wed, 19 Jul 2023 15:58:34 -0500
Subject: [PATCH 12/31] add test button

---
 lib/pages/ordinals/ordinals_view.dart | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/lib/pages/ordinals/ordinals_view.dart b/lib/pages/ordinals/ordinals_view.dart
index fe60b5e28..2d051b07a 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/services/ordinals_api.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';
@@ -39,7 +41,7 @@ class OrdinalsView extends ConsumerStatefulWidget {
   ConsumerState<OrdinalsView> createState() => _OrdinalsViewState();
 }
 
-class _OrdinalsViewState extends ConsumerState<OrdinalsView> {
+class _OrdinalsViewState extends ConsumerState<OrdinalsView> with OrdinalsInterface {
   late final TextEditingController searchController;
   late final FocusNode searchFocus;
 
@@ -49,6 +51,7 @@ class _OrdinalsViewState extends ConsumerState<OrdinalsView> {
   void initState() {
     searchController = TextEditingController();
     searchFocus = FocusNode();
+
     super.initState();
   }
 
@@ -178,6 +181,13 @@ class _OrdinalsViewState extends ConsumerState<OrdinalsView> {
                 const SizedBox(
                   height: 16,
                 ),
+                TextButton(onPressed: () async {
+                  await fetchLatestInscriptions();
+                }, child: Text(
+                  "Test",
+                  style: STextStyles.navBarTitle(context),
+                )
+                ),
                 Expanded(
                   child: OrdinalsList(
                     walletId: widget.walletId,

From 0284bb2951e362cc7c76309c0bd7683731e345bd Mon Sep 17 00:00:00 2001
From: sneurlax <sneurlax@gmail.com>
Date: Wed, 19 Jul 2023 17:13:54 -0500
Subject: [PATCH 13/31] use https api, implement other methods

---
 lib/pages/ordinals/ordinals_view.dart       |  2 +-
 lib/services/mixins/ordinals_interface.dart | 87 +++++++++++++++++++--
 2 files changed, 81 insertions(+), 8 deletions(-)

diff --git a/lib/pages/ordinals/ordinals_view.dart b/lib/pages/ordinals/ordinals_view.dart
index 2d051b07a..3dd8b7ae7 100644
--- a/lib/pages/ordinals/ordinals_view.dart
+++ b/lib/pages/ordinals/ordinals_view.dart
@@ -182,7 +182,7 @@ class _OrdinalsViewState extends ConsumerState<OrdinalsView> with OrdinalsInterf
                   height: 16,
                 ),
                 TextButton(onPressed: () async {
-                  await fetchLatestInscriptions();
+                  await getTransaction('ed5a5c4e555e204768ec54c049ae0b01c86fdcc8b126a9d100c4dff745e7d3ca');
                 }, child: Text(
                   "Test",
                   style: STextStyles.navBarTitle(context),
diff --git a/lib/services/mixins/ordinals_interface.dart b/lib/services/mixins/ordinals_interface.dart
index 1ab157b2c..92974c67d 100644
--- a/lib/services/mixins/ordinals_interface.dart
+++ b/lib/services/mixins/ordinals_interface.dart
@@ -1,21 +1,94 @@
-import 'package:stackwallet/dto/ordinals/feed_response.dart'; // Assuming this import is necessary
+import 'package:stackwallet/dto/ordinals/feed_response.dart';
+import 'package:stackwallet/dto/ordinals/inscription_response.dart';
+import 'package:stackwallet/dto/ordinals/sat_response.dart';
+import 'package:stackwallet/dto/ordinals/transaction_response.dart';
+import 'package:stackwallet/dto/ordinals/output_response.dart';
+import 'package:stackwallet/dto/ordinals/address_response.dart';
+import 'package:stackwallet/dto/ordinals/block_response.dart';
+import 'package:stackwallet/dto/ordinals/content_response.dart';
+import 'package:stackwallet/dto/ordinals/preview_response.dart';
 import 'package:stackwallet/services/ordinals_api.dart'; // Assuming this import is necessary
 
 mixin OrdinalsInterface {
-  final OrdinalsAPI ordinalsAPI = OrdinalsAPI(baseUrl: 'http://ord-litecoin.stackwallet.com');
+  final OrdinalsAPI ordinalsAPI = OrdinalsAPI(baseUrl: 'https://ord-litecoin.stackwallet.com');
 
   Future<FeedResponse> fetchLatestInscriptions() 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}');
-      }
+      // 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');
+      throw Exception('Error in OrdinalsInterface fetchLatestInscriptions: $e');
+    }
+  }
+
+  Future<InscriptionResponse> getInscriptionDetails(String inscriptionId) async {
+    try {
+      return await ordinalsAPI.getInscriptionDetails(inscriptionId);
+    } catch (e) {
+      throw Exception('Error in OrdinalsInterface getInscriptionDetails: $e');
+    }
+  }
+
+  Future<SatResponse> getSatDetails(int satNumber) async {
+    try {
+      return await ordinalsAPI.getSatDetails(satNumber);
+    } catch (e) {
+      throw Exception('Error in OrdinalsInterface getSatDetails: $e');
+    }
+  }
+
+  Future<TransactionResponse> getTransaction(String transactionId) async {
+    try {
+      print(1);
+      return await ordinalsAPI.getTransaction(transactionId);
+    } catch (e) {
+      throw Exception('Error in OrdinalsInterface getTransaction: $e');
+    }
+  }
+
+  Future<OutputResponse> getTransactionOutputs(String transactionId) async {
+    try {
+      return await ordinalsAPI.getTransactionOutputs(transactionId);
+    } catch (e) {
+      throw Exception('Error in OrdinalsInterface getTransactionOutputs: $e');
+    }
+  }
+
+  Future<AddressResponse> getInscriptionsByAddress(String address) async {
+    try {
+      return await ordinalsAPI.getInscriptionsByAddress(address);
+    } catch (e) {
+      throw Exception('Error in OrdinalsInterface getInscriptionsByAddress: $e');
+    }
+  }
+
+  Future<BlockResponse> getBlock(int blockNumber) async {
+    try {
+      return await ordinalsAPI.getBlock(blockNumber);
+    } catch (e) {
+      throw Exception('Error in OrdinalsInterface getBlock: $e');
+    }
+  }
+
+  Future<ContentResponse> getInscriptionContent(String inscriptionId) async {
+    try {
+      return await ordinalsAPI.getInscriptionContent(inscriptionId);
+    } catch (e) {
+      throw Exception('Error in OrdinalsInterface getInscriptionContent: $e');
+    }
+  }
+
+  Future<PreviewResponse> getInscriptionPreview(String inscriptionId) async {
+    try {
+      return await ordinalsAPI.getInscriptionPreview(inscriptionId);
+    } catch (e) {
+      throw Exception('Error in OrdinalsInterface getInscriptionPreview: $e');
     }
   }
 }
\ No newline at end of file

From d02b7f7ad4bbc4c5335fac7c0cce3f588760c580 Mon Sep 17 00:00:00 2001
From: sneurlax <sneurlax@gmail.com>
Date: Thu, 20 Jul 2023 14:05:51 -0500
Subject: [PATCH 14/31] formatting and model updates

---
 lib/pages/ordinals/ordinals_view.dart | 3 +++
 lib/services/ordinals_api.dart        | 2 --
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/lib/pages/ordinals/ordinals_view.dart b/lib/pages/ordinals/ordinals_view.dart
index 3dd8b7ae7..a60bf4226 100644
--- a/lib/pages/ordinals/ordinals_view.dart
+++ b/lib/pages/ordinals/ordinals_view.dart
@@ -197,6 +197,9 @@ class _OrdinalsViewState extends ConsumerState<OrdinalsView> with OrdinalsInterf
                           name: "dummy name $i",
                           inscription: "insc$i",
                           rank: "r$i",
+                          collection: OrdCollection.moonbirds,
+                          utxoTXID: 'txid',
+                          utxoVOUT: 1
                         ),
                     ],
                   ),
diff --git a/lib/services/ordinals_api.dart b/lib/services/ordinals_api.dart
index c1d3aad94..290b1c869 100644
--- a/lib/services/ordinals_api.dart
+++ b/lib/services/ordinals_api.dart
@@ -12,8 +12,6 @@ import 'package:stackwallet/dto/ordinals/block_response.dart';
 import 'package:stackwallet/dto/ordinals/content_response.dart';
 import 'package:stackwallet/dto/ordinals/preview_response.dart';
 
-import 'package:stackwallet/dto/ordinals/feed_response.dart'; // Assuming this import is necessary
-
 class OrdinalsAPI {
   static final OrdinalsAPI _instance = OrdinalsAPI._internal();
 

From f046912c89a2e64d28687f5d1631f0279659506d Mon Sep 17 00:00:00 2001
From: sneurlax <sneurlax@gmail.com>
Date: Thu, 20 Jul 2023 14:38:56 -0500
Subject: [PATCH 15/31] litescribe api and demo

---
 .../address_inscription_response.dart         | 91 +++++++++++++++++++
 lib/dto/ordinals/litescribe_response.dart     |  6 ++
 lib/pages/ordinals/ordinals_view.dart         |  5 +-
 lib/services/litescribe_api.dart              | 45 +++++++++
 lib/services/mixins/ordinals_interface.dart   | 38 ++++++--
 lib/services/ordinals_api.dart                |  4 +-
 6 files changed, 176 insertions(+), 13 deletions(-)
 create mode 100644 lib/dto/ordinals/address_inscription_response.dart
 create mode 100644 lib/dto/ordinals/litescribe_response.dart
 create mode 100644 lib/services/litescribe_api.dart

diff --git a/lib/dto/ordinals/address_inscription_response.dart b/lib/dto/ordinals/address_inscription_response.dart
new file mode 100644
index 000000000..c424d73e0
--- /dev/null
+++ b/lib/dto/ordinals/address_inscription_response.dart
@@ -0,0 +1,91 @@
+import 'package:stackwallet/dto/ordinals/litescribe_response.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<AddressInscription> 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) => AddressInscription.fromJson(item as Map<String, dynamic>)).toList(),
+      total: json['total'] as int,
+    );
+  }
+}
+
+class AddressInscription {
+  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;
+
+  AddressInscription({
+    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 AddressInscription.fromJson(Map<String, dynamic> json) {
+    return AddressInscription(
+      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/pages/ordinals/ordinals_view.dart b/lib/pages/ordinals/ordinals_view.dart
index a60bf4226..4bd7385d3 100644
--- a/lib/pages/ordinals/ordinals_view.dart
+++ b/lib/pages/ordinals/ordinals_view.dart
@@ -182,7 +182,10 @@ class _OrdinalsViewState extends ConsumerState<OrdinalsView> with OrdinalsInterf
                   height: 16,
                 ),
                 TextButton(onPressed: () async {
-                  await getTransaction('ed5a5c4e555e204768ec54c049ae0b01c86fdcc8b126a9d100c4dff745e7d3ca');
+                  // await fetchLatestInscriptions();
+                  // await getTransaction('ed5a5c4e555e204768ec54c049ae0b01c86fdcc8b126a9d100c4dff745e7d3ca');
+                  // await getBlock('31278055ba414fe6dbed75e4a77e841da4481972ac09bd2a214c445da1a44aad');
+                  await getInscriptionsByAddress('ltc1qk4e8hdq5w6rvk5xvkxajjak78v45pkul8a2cg9');
                 }, child: Text(
                   "Test",
                   style: STextStyles.navBarTitle(context),
diff --git a/lib/services/litescribe_api.dart b/lib/services/litescribe_api.dart
new file mode 100644
index 000000000..507492ee6
--- /dev/null
+++ b/lib/services/litescribe_api.dart
@@ -0,0 +1,45 @@
+import 'dart:convert';
+import 'package:http/http.dart' as http;
+
+import 'package:stackwallet/dto/ordinals/address_inscription_response.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<AddressInscriptionResponse> getInscriptionsByAddress(String address, {int cursor = 0, int size = 1000}) async { // size = 1000 = hardcoded limit as default limit to inscriptions returned from API call, TODO increase limit if returned inscriptions = limit
+    final response = await _getResponse('/address/inscriptions?address=$address&cursor=$cursor&size=$size');
+    try {
+      return AddressInscriptionResponse.fromJson(response.data as Map<String, dynamic>);
+    } 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 92974c67d..a9fbcbca6 100644
--- a/lib/services/mixins/ordinals_interface.dart
+++ b/lib/services/mixins/ordinals_interface.dart
@@ -1,15 +1,32 @@
-import 'package:stackwallet/dto/ordinals/feed_response.dart';
-import 'package:stackwallet/dto/ordinals/inscription_response.dart';
-import 'package:stackwallet/dto/ordinals/sat_response.dart';
-import 'package:stackwallet/dto/ordinals/transaction_response.dart';
-import 'package:stackwallet/dto/ordinals/output_response.dart';
-import 'package:stackwallet/dto/ordinals/address_response.dart';
-import 'package:stackwallet/dto/ordinals/block_response.dart';
-import 'package:stackwallet/dto/ordinals/content_response.dart';
-import 'package:stackwallet/dto/ordinals/preview_response.dart';
-import 'package:stackwallet/services/ordinals_api.dart'; // Assuming this import is necessary
+// ord-litecoin-specific imports
+// import 'package:stackwallet/dto/ordinals/feed_response.dart';
+// import 'package:stackwallet/dto/ordinals/inscription_response.dart';
+// import 'package:stackwallet/dto/ordinals/sat_response.dart';
+// import 'package:stackwallet/dto/ordinals/transaction_response.dart';
+// import 'package:stackwallet/dto/ordinals/output_response.dart';
+// import 'package:stackwallet/dto/ordinals/address_response.dart';
+// import 'package:stackwallet/dto/ordinals/block_response.dart';
+// import 'package:stackwallet/dto/ordinals/content_response.dart';
+// import 'package:stackwallet/dto/ordinals/preview_response.dart';
+// import 'package:stackwallet/services/ordinals_api.dart';
+
+import 'package:stackwallet/dto/ordinals/address_inscription_response.dart'; // verbose due to Litescribe being the 2nd API
+import 'package:stackwallet/services/litescribe_api.dart';
 
 mixin OrdinalsInterface {
+  final LitescribeAPI litescribeAPI = LitescribeAPI(baseUrl: 'https://litescribe.io/api');
+
+  Future<List<AddressInscription>> getInscriptionsByAddress(String address) async {
+    try {
+      var response = await litescribeAPI.getInscriptionsByAddress(address);
+      print("Found ${response.result.total} inscriptions at address $address"); // TODO disable (POC)
+      return response.result.list;
+    } catch (e) {
+      throw Exception('Error in OrdinalsInterface getInscriptionsByAddress: $e');
+    }
+  }
+
+  /* // ord-litecoin interface
   final OrdinalsAPI ordinalsAPI = OrdinalsAPI(baseUrl: 'https://ord-litecoin.stackwallet.com');
 
   Future<FeedResponse> fetchLatestInscriptions() async {
@@ -91,4 +108,5 @@ mixin OrdinalsInterface {
       throw Exception('Error in OrdinalsInterface getInscriptionPreview: $e');
     }
   }
+  */ // /ord-litecoin interface
 }
\ No newline at end of file
diff --git a/lib/services/ordinals_api.dart b/lib/services/ordinals_api.dart
index 290b1c869..e6df3c05e 100644
--- a/lib/services/ordinals_api.dart
+++ b/lib/services/ordinals_api.dart
@@ -72,8 +72,8 @@ class OrdinalsAPI {
     return AddressResponse.fromJson(response);
   }
 
-  Future<BlockResponse> getBlock(int blockNumber) async {
-    final response = await _getResponse('/block/$blockNumber');
+  Future<BlockResponse> getBlock(String blockHash) async {
+    final response = await _getResponse('/block/$blockHash');
     return BlockResponse.fromJson(response);
   }
 

From a322c1395432a18f1fc1f53eff53037ec7e3499b Mon Sep 17 00:00:00 2001
From: sneurlax <sneurlax@gmail.com>
Date: Thu, 20 Jul 2023 14:46:15 -0500
Subject: [PATCH 16/31] return inscriptions in batches of 1000

---
 lib/services/litescribe_api.dart | 27 ++++++++++++++++++++++-----
 1 file changed, 22 insertions(+), 5 deletions(-)

diff --git a/lib/services/litescribe_api.dart b/lib/services/litescribe_api.dart
index 507492ee6..edb46f1d2 100644
--- a/lib/services/litescribe_api.dart
+++ b/lib/services/litescribe_api.dart
@@ -34,12 +34,29 @@ class LitescribeAPI {
     }
   }
 
-  Future<AddressInscriptionResponse> getInscriptionsByAddress(String address, {int cursor = 0, int size = 1000}) async { // size = 1000 = hardcoded limit as default limit to inscriptions returned from API call, TODO increase limit if returned inscriptions = limit
+  Future<AddressInscriptionResponse> 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');
-    try {
-      return AddressInscriptionResponse.fromJson(response.data as Map<String, dynamic>);
-    } catch(e) {
-      throw const FormatException('LitescribeAPI getInscriptionsByAddress exception: AddressInscriptionResponse.fromJson failure');
+
+    // Check if the number of returned inscriptions equals the limit
+    final list = response.data['result']['list'] as List<dynamic>;
+    final int total = response.data['result']['total'] as int;
+    final int currentSize = list.length;
+
+    if (currentSize == size && currentSize < total) {
+      // If the number of returned inscriptions equals the limit and there are more inscriptions available,
+      // increase the size to fetch all inscriptions.
+      return getInscriptionsByAddress(address, cursor: cursor, size: total+1); // potential off-by-one error, but should be safe
+      // TODO don't re-request the same inscriptions previously returned; increment cursor (probably) by size and only request the rest. ex: cursor=0 size=1000 probably returns inscriptions 0-999, so set cursor=size (or size-1?) to get 1000-1999
+    } else {
+      try {
+        return AddressInscriptionResponse.fromJson(response.data as Map<String, dynamic>);
+      } catch (e) {
+        throw const FormatException('LitescribeAPI getInscriptionsByAddress exception: AddressInscriptionResponse.fromJson failure');
+      }
     }
   }
 }
\ No newline at end of file

From 22e222ffd6c0ea7bd1851a36ce2e64e9fc8f32cb Mon Sep 17 00:00:00 2001
From: sneurlax <sneurlax@gmail.com>
Date: Thu, 20 Jul 2023 14:48:12 -0500
Subject: [PATCH 17/31] paginate inscription responses

---
 lib/services/litescribe_api.dart | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/lib/services/litescribe_api.dart b/lib/services/litescribe_api.dart
index edb46f1d2..abc28123e 100644
--- a/lib/services/litescribe_api.dart
+++ b/lib/services/litescribe_api.dart
@@ -48,9 +48,10 @@ class LitescribeAPI {
 
     if (currentSize == size && currentSize < total) {
       // If the number of returned inscriptions equals the limit and there are more inscriptions available,
-      // increase the size to fetch all inscriptions.
-      return getInscriptionsByAddress(address, cursor: cursor, size: total+1); // potential off-by-one error, but should be safe
-      // TODO don't re-request the same inscriptions previously returned; increment cursor (probably) by size and only request the rest. ex: cursor=0 size=1000 probably returns inscriptions 0-999, so set cursor=size (or size-1?) to get 1000-1999
+      // 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);
+      // TODO test logic with smaller size "pagination"
     } else {
       try {
         return AddressInscriptionResponse.fromJson(response.data as Map<String, dynamic>);

From 4be7919e46c288668d28b18b1d2d19e5cd6a8eaf Mon Sep 17 00:00:00 2001
From: sneurlax <sneurlax@gmail.com>
Date: Thu, 20 Jul 2023 14:52:05 -0500
Subject: [PATCH 18/31] expand upon demo

TODO remove WIP, hook directly into StreamBuilder
---
 lib/pages/ordinals/ordinals_view.dart       | 9 ++++++++-
 lib/services/mixins/ordinals_interface.dart | 2 +-
 2 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/lib/pages/ordinals/ordinals_view.dart b/lib/pages/ordinals/ordinals_view.dart
index 4bd7385d3..d2b6a34d6 100644
--- a/lib/pages/ordinals/ordinals_view.dart
+++ b/lib/pages/ordinals/ordinals_view.dart
@@ -185,7 +185,14 @@ class _OrdinalsViewState extends ConsumerState<OrdinalsView> with OrdinalsInterf
                   // await fetchLatestInscriptions();
                   // await getTransaction('ed5a5c4e555e204768ec54c049ae0b01c86fdcc8b126a9d100c4dff745e7d3ca');
                   // await getBlock('31278055ba414fe6dbed75e4a77e841da4481972ac09bd2a214c445da1a44aad');
-                  await getInscriptionsByAddress('ltc1qk4e8hdq5w6rvk5xvkxajjak78v45pkul8a2cg9');
+                  var inscriptions = await getInscriptionsByAddress('ltc1qk4e8hdq5w6rvk5xvkxajjak78v45pkul8a2cg9');
+                  for (var inscription in inscriptions) {
+                    print(inscription);
+                    print(inscription.address);
+                    print(inscription.content);
+                    print(inscription.inscriptionId);
+                    print(inscription.inscriptionNumber);
+                  }
                 }, child: Text(
                   "Test",
                   style: STextStyles.navBarTitle(context),
diff --git a/lib/services/mixins/ordinals_interface.dart b/lib/services/mixins/ordinals_interface.dart
index a9fbcbca6..f39b2259f 100644
--- a/lib/services/mixins/ordinals_interface.dart
+++ b/lib/services/mixins/ordinals_interface.dart
@@ -19,7 +19,7 @@ mixin OrdinalsInterface {
   Future<List<AddressInscription>> getInscriptionsByAddress(String address) async {
     try {
       var response = await litescribeAPI.getInscriptionsByAddress(address);
-      print("Found ${response.result.total} inscriptions at address $address"); // TODO disable (POC)
+      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');

From ca8e930904cd9497f38fd13cc15d2f78b07d6b3a Mon Sep 17 00:00:00 2001
From: sneurlax <sneurlax@gmail.com>
Date: Thu, 20 Jul 2023 15:32:39 -0500
Subject: [PATCH 19/31] move demo into refresh button, add
 refreshInscriptions() stub w prev poc

---
 lib/pages/ordinals/ordinals_view.dart       | 22 +++------------------
 lib/services/mixins/ordinals_interface.dart | 12 +++++++++++
 2 files changed, 15 insertions(+), 19 deletions(-)

diff --git a/lib/pages/ordinals/ordinals_view.dart b/lib/pages/ordinals/ordinals_view.dart
index d2b6a34d6..7a0572c78 100644
--- a/lib/pages/ordinals/ordinals_view.dart
+++ b/lib/pages/ordinals/ordinals_view.dart
@@ -14,6 +14,7 @@ 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/services/litescribe_api.dart';
 import 'package:stackwallet/services/ordinals_api.dart';
 import 'package:stackwallet/services/mixins/ordinals_interface.dart';
 import 'package:stackwallet/themes/stack_colors.dart';
@@ -90,8 +91,8 @@ class _OrdinalsViewState extends ConsumerState<OrdinalsView> with OrdinalsInterf
                         .extension<StackColors>()!
                         .topNavIconPrimary,
                   ),
-                  onPressed: () {
-                    // todo refresh
+                  onPressed: () async {
+                    refreshInscriptions();
                   },
                 ),
               ),
@@ -181,23 +182,6 @@ class _OrdinalsViewState extends ConsumerState<OrdinalsView> with OrdinalsInterf
                 const SizedBox(
                   height: 16,
                 ),
-                TextButton(onPressed: () async {
-                  // await fetchLatestInscriptions();
-                  // await getTransaction('ed5a5c4e555e204768ec54c049ae0b01c86fdcc8b126a9d100c4dff745e7d3ca');
-                  // await getBlock('31278055ba414fe6dbed75e4a77e841da4481972ac09bd2a214c445da1a44aad');
-                  var inscriptions = await getInscriptionsByAddress('ltc1qk4e8hdq5w6rvk5xvkxajjak78v45pkul8a2cg9');
-                  for (var inscription in inscriptions) {
-                    print(inscription);
-                    print(inscription.address);
-                    print(inscription.content);
-                    print(inscription.inscriptionId);
-                    print(inscription.inscriptionNumber);
-                  }
-                }, child: Text(
-                  "Test",
-                  style: STextStyles.navBarTitle(context),
-                )
-                ),
                 Expanded(
                   child: OrdinalsList(
                     walletId: widget.walletId,
diff --git a/lib/services/mixins/ordinals_interface.dart b/lib/services/mixins/ordinals_interface.dart
index f39b2259f..d60786b4d 100644
--- a/lib/services/mixins/ordinals_interface.dart
+++ b/lib/services/mixins/ordinals_interface.dart
@@ -26,6 +26,18 @@ mixin OrdinalsInterface {
     }
   }
 
+  void refreshInscriptions() async {
+    // TODO get all inscriptions at all addresses in wallet
+    var inscriptions = await getInscriptionsByAddress('ltc1qk4e8hdq5w6rvk5xvkxajjak78v45pkul8a2cg9');
+    for (var inscription in inscriptions) {
+      print(inscription);
+      print(inscription.address);
+      print(inscription.content);
+      print(inscription.inscriptionId);
+      print(inscription.inscriptionNumber);
+    }
+  }
+
   /* // ord-litecoin interface
   final OrdinalsAPI ordinalsAPI = OrdinalsAPI(baseUrl: 'https://ord-litecoin.stackwallet.com');
 

From 06c433ff8565479860cbb3ddd2f7f18e389a83c6 Mon Sep 17 00:00:00 2001
From: sneurlax <sneurlax@gmail.com>
Date: Thu, 20 Jul 2023 15:56:11 -0500
Subject: [PATCH 20/31] add init method, build on poc

---
 lib/services/mixins/ordinals_interface.dart | 36 +++++++++++++++++++++
 1 file changed, 36 insertions(+)

diff --git a/lib/services/mixins/ordinals_interface.dart b/lib/services/mixins/ordinals_interface.dart
index d60786b4d..caac7a854 100644
--- a/lib/services/mixins/ordinals_interface.dart
+++ b/lib/services/mixins/ordinals_interface.dart
@@ -1,3 +1,8 @@
+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';
+
 // ord-litecoin-specific imports
 // import 'package:stackwallet/dto/ordinals/feed_response.dart';
 // import 'package:stackwallet/dto/ordinals/inscription_response.dart';
@@ -13,7 +18,21 @@
 import 'package:stackwallet/dto/ordinals/address_inscription_response.dart'; // verbose due to Litescribe being the 2nd API
 import 'package:stackwallet/services/litescribe_api.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<List<AddressInscription>> getInscriptionsByAddress(String address) async {
@@ -27,6 +46,13 @@ mixin OrdinalsInterface {
   }
 
   void refreshInscriptions() async {
+    List<dynamic> _inscriptions;
+    final utxos = await _db.getUTXOs(_walletId).findAll();
+    final uniqueAddresses = getUniqueAddressesFromUTXOs(utxos);
+    for (String address in uniqueAddresses) {
+      // TODO fetch all inscriptions from all addresses
+      // TODO save those inscriptions to isar, which a StreamBuilder will be "subscribed"-to
+    }
     // TODO get all inscriptions at all addresses in wallet
     var inscriptions = await getInscriptionsByAddress('ltc1qk4e8hdq5w6rvk5xvkxajjak78v45pkul8a2cg9');
     for (var inscription in inscriptions) {
@@ -38,6 +64,16 @@ mixin OrdinalsInterface {
     }
   }
 
+  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();
+  }
+
   /* // ord-litecoin interface
   final OrdinalsAPI ordinalsAPI = OrdinalsAPI(baseUrl: 'https://ord-litecoin.stackwallet.com');
 

From 4db0328c73a859f4550fedafd3486e508a599921 Mon Sep 17 00:00:00 2001
From: sneurlax <sneurlax@gmail.com>
Date: Thu, 20 Jul 2023 16:30:39 -0500
Subject: [PATCH 21/31] WIP _db not initialized, refresh on ordinals view for
 poc

---
 .../address_inscription_response.dart         | 58 +------------------
 lib/dto/ordinals/inscription_data.dart        | 53 +++++++++++++++++
 lib/pages/ordinals/ordinals_view.dart         |  6 +-
 .../coins/litecoin/litecoin_wallet.dart       |  1 +
 lib/services/litescribe_api.dart              |  8 +--
 lib/services/mixins/ordinals_interface.dart   | 52 +++++++++--------
 6 files changed, 93 insertions(+), 85 deletions(-)
 create mode 100644 lib/dto/ordinals/inscription_data.dart

diff --git a/lib/dto/ordinals/address_inscription_response.dart b/lib/dto/ordinals/address_inscription_response.dart
index c424d73e0..240374284 100644
--- a/lib/dto/ordinals/address_inscription_response.dart
+++ b/lib/dto/ordinals/address_inscription_response.dart
@@ -1,4 +1,5 @@
 import 'package:stackwallet/dto/ordinals/litescribe_response.dart';
+import 'package:stackwallet/dto/ordinals/inscription_data.dart';
 
 class AddressInscriptionResponse extends LitescribeResponse<AddressInscriptionResponse> {
   final int status;
@@ -21,7 +22,7 @@ class AddressInscriptionResponse extends LitescribeResponse<AddressInscriptionRe
 }
 
 class AddressInscriptionResult {
-  final List<AddressInscription> list;
+  final List<InscriptionData> list;
   final int total;
 
   AddressInscriptionResult({
@@ -31,61 +32,8 @@ class AddressInscriptionResult {
 
   factory AddressInscriptionResult.fromJson(Map<String, dynamic> json) {
     return AddressInscriptionResult(
-      list: (json['list'] as List).map((item) => AddressInscription.fromJson(item as Map<String, dynamic>)).toList(),
+      list: (json['list'] as List).map((item) => InscriptionData.fromJson(item as Map<String, dynamic>)).toList(),
       total: json['total'] as int,
     );
   }
 }
-
-class AddressInscription {
-  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;
-
-  AddressInscription({
-    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 AddressInscription.fromJson(Map<String, dynamic> json) {
-    return AddressInscription(
-      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/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/pages/ordinals/ordinals_view.dart b/lib/pages/ordinals/ordinals_view.dart
index 7a0572c78..f5f3ca23a 100644
--- a/lib/pages/ordinals/ordinals_view.dart
+++ b/lib/pages/ordinals/ordinals_view.dart
@@ -14,8 +14,9 @@ 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/services/litescribe_api.dart';
-import 'package:stackwallet/services/ordinals_api.dart';
+import 'package:stackwallet/providers/global/wallets_provider.dart';
+// import 'package:stackwallet/services/litescribe_api.dart';
+// import 'package:stackwallet/services/ordinals_api.dart';
 import 'package:stackwallet/services/mixins/ordinals_interface.dart';
 import 'package:stackwallet/themes/stack_colors.dart';
 import 'package:stackwallet/utilities/assets.dart';
@@ -28,6 +29,7 @@ import 'package:stackwallet/widgets/icon_widgets/x_icon.dart';
 import 'package:stackwallet/widgets/stack_text_field.dart';
 import 'package:stackwallet/widgets/textfield_icon_button.dart';
 
+
 class OrdinalsView extends ConsumerStatefulWidget {
   const OrdinalsView({
     super.key,
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
index abc28123e..f7634b387 100644
--- a/lib/services/litescribe_api.dart
+++ b/lib/services/litescribe_api.dart
@@ -1,7 +1,7 @@
 import 'dart:convert';
 import 'package:http/http.dart' as http;
 
-import 'package:stackwallet/dto/ordinals/address_inscription_response.dart';
+import 'package:stackwallet/dto/ordinals/inscription_data.dart';
 import 'package:stackwallet/dto/ordinals/litescribe_response.dart';
 
 class LitescribeAPI {
@@ -34,7 +34,7 @@ class LitescribeAPI {
     }
   }
 
-  Future<AddressInscriptionResponse> getInscriptionsByAddress(String address, {int cursor = 0, int size = 1000}) async {
+  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
@@ -42,7 +42,7 @@ class LitescribeAPI {
     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'] as List<dynamic>;
+    final list = response.data['result']['list'] as List<InscriptionData>;
     final int total = response.data['result']['total'] as int;
     final int currentSize = list.length;
 
@@ -54,7 +54,7 @@ class LitescribeAPI {
       // TODO test logic with smaller size "pagination"
     } else {
       try {
-        return AddressInscriptionResponse.fromJson(response.data as Map<String, dynamic>);
+        return list;
       } catch (e) {
         throw const FormatException('LitescribeAPI getInscriptionsByAddress exception: AddressInscriptionResponse.fromJson failure');
       }
diff --git a/lib/services/mixins/ordinals_interface.dart b/lib/services/mixins/ordinals_interface.dart
index caac7a854..fbd41d80b 100644
--- a/lib/services/mixins/ordinals_interface.dart
+++ b/lib/services/mixins/ordinals_interface.dart
@@ -15,8 +15,8 @@ import 'package:stackwallet/utilities/enums/coin_enum.dart';
 // import 'package:stackwallet/dto/ordinals/preview_response.dart';
 // import 'package:stackwallet/services/ordinals_api.dart';
 
-import 'package:stackwallet/dto/ordinals/address_inscription_response.dart'; // verbose due to Litescribe being the 2nd API
 import 'package:stackwallet/services/litescribe_api.dart';
+import 'package:stackwallet/dto/ordinals/inscription_data.dart';
 
 
 mixin OrdinalsInterface {
@@ -29,39 +29,29 @@ mixin OrdinalsInterface {
     required Coin coin,
     required MainDB db,
   }) {
+    print('init');
     _walletId = walletId;
     _coin = coin;
     _db = db;
   }
   final LitescribeAPI litescribeAPI = LitescribeAPI(baseUrl: 'https://litescribe.io/api');
 
-  Future<List<AddressInscription>> 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');
-    }
-  }
+  // Future<List<InscriptionData>> 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<dynamic> _inscriptions;
     final utxos = await _db.getUTXOs(_walletId).findAll();
     final uniqueAddresses = getUniqueAddressesFromUTXOs(utxos);
-    for (String address in uniqueAddresses) {
-      // TODO fetch all inscriptions from all addresses
-      // TODO save those inscriptions to isar, which a StreamBuilder will be "subscribed"-to
-    }
-    // TODO get all inscriptions at all addresses in wallet
-    var inscriptions = await getInscriptionsByAddress('ltc1qk4e8hdq5w6rvk5xvkxajjak78v45pkul8a2cg9');
-    for (var inscription in inscriptions) {
-      print(inscription);
-      print(inscription.address);
-      print(inscription.content);
-      print(inscription.inscriptionId);
-      print(inscription.inscriptionNumber);
-    }
+    _inscriptions = await getAllInscriptionsFromAddresses(uniqueAddresses);
+    // TODO save inscriptions to isar which gets watched by a StreamBuilder
   }
 
   List<String> getUniqueAddressesFromUTXOs(List<UTXO> utxos) {
@@ -74,7 +64,21 @@ mixin OrdinalsInterface {
     return uniqueAddresses.toList();
   }
 
-  /* // ord-litecoin interface
+  Future<List<InscriptionData>> getAllInscriptionsFromAddresses(List<String> addresses) async {
+    List<InscriptionData> 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");
+      }
+    }
+    return allInscriptions;
+  }
+
+/* // ord-litecoin interface
   final OrdinalsAPI ordinalsAPI = OrdinalsAPI(baseUrl: 'https://ord-litecoin.stackwallet.com');
 
   Future<FeedResponse> fetchLatestInscriptions() async {

From b773811eac6007dd878b4337711e7b2df963cdaa Mon Sep 17 00:00:00 2001
From: sneurlax <sneurlax@gmail.com>
Date: Thu, 20 Jul 2023 16:49:26 -0500
Subject: [PATCH 22/31] working proof of concept

---
 lib/pages/ordinals/ordinals_view.dart       | 10 +++++-----
 lib/services/litescribe_api.dart            | 11 ++++++++---
 lib/services/mixins/ordinals_interface.dart |  7 ++++---
 3 files changed, 17 insertions(+), 11 deletions(-)

diff --git a/lib/pages/ordinals/ordinals_view.dart b/lib/pages/ordinals/ordinals_view.dart
index f5f3ca23a..8993ed4e7 100644
--- a/lib/pages/ordinals/ordinals_view.dart
+++ b/lib/pages/ordinals/ordinals_view.dart
@@ -15,8 +15,6 @@ 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/litescribe_api.dart';
-// import 'package:stackwallet/services/ordinals_api.dart';
 import 'package:stackwallet/services/mixins/ordinals_interface.dart';
 import 'package:stackwallet/themes/stack_colors.dart';
 import 'package:stackwallet/utilities/assets.dart';
@@ -29,7 +27,6 @@ import 'package:stackwallet/widgets/icon_widgets/x_icon.dart';
 import 'package:stackwallet/widgets/stack_text_field.dart';
 import 'package:stackwallet/widgets/textfield_icon_button.dart';
 
-
 class OrdinalsView extends ConsumerStatefulWidget {
   const OrdinalsView({
     super.key,
@@ -44,7 +41,7 @@ class OrdinalsView extends ConsumerStatefulWidget {
   ConsumerState<OrdinalsView> createState() => _OrdinalsViewState();
 }
 
-class _OrdinalsViewState extends ConsumerState<OrdinalsView> with OrdinalsInterface {
+class _OrdinalsViewState extends ConsumerState<OrdinalsView> {
   late final TextEditingController searchController;
   late final FocusNode searchFocus;
 
@@ -94,7 +91,10 @@ class _OrdinalsViewState extends ConsumerState<OrdinalsView> with OrdinalsInterf
                         .topNavIconPrimary,
                   ),
                   onPressed: () async {
-                    refreshInscriptions();
+                    final manager = ref.watch(walletsChangeNotifierProvider
+                        .select((value) => value.getManager(widget.walletId)));
+
+                    (manager.wallet as OrdinalsInterface).refreshInscriptions();
                   },
                 ),
               ),
diff --git a/lib/services/litescribe_api.dart b/lib/services/litescribe_api.dart
index f7634b387..7fc92910d 100644
--- a/lib/services/litescribe_api.dart
+++ b/lib/services/litescribe_api.dart
@@ -42,7 +42,7 @@ class LitescribeAPI {
     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'] as List<InscriptionData>;
+    final list = response.data['result']['list'];
     final int total = response.data['result']['total'] as int;
     final int currentSize = list.length;
 
@@ -51,10 +51,15 @@ class LitescribeAPI {
       // 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);
-      // TODO test logic with smaller size "pagination"
+
     } else {
       try {
-        return list;
+        // 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');
       }
diff --git a/lib/services/mixins/ordinals_interface.dart b/lib/services/mixins/ordinals_interface.dart
index fbd41d80b..a04b6522c 100644
--- a/lib/services/mixins/ordinals_interface.dart
+++ b/lib/services/mixins/ordinals_interface.dart
@@ -1,3 +1,5 @@
+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';
@@ -18,7 +20,6 @@ import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/services/litescribe_api.dart';
 import 'package:stackwallet/dto/ordinals/inscription_data.dart';
 
-
 mixin OrdinalsInterface {
   late final String _walletId;
   late final Coin _coin;
@@ -50,7 +51,7 @@ mixin OrdinalsInterface {
     List<dynamic> _inscriptions;
     final utxos = await _db.getUTXOs(_walletId).findAll();
     final uniqueAddresses = getUniqueAddressesFromUTXOs(utxos);
-    _inscriptions = await getAllInscriptionsFromAddresses(uniqueAddresses);
+    _inscriptions = await getInscriptionsFromAddresses(uniqueAddresses);
     // TODO save inscriptions to isar which gets watched by a StreamBuilder
   }
 
@@ -64,7 +65,7 @@ mixin OrdinalsInterface {
     return uniqueAddresses.toList();
   }
 
-  Future<List<InscriptionData>> getAllInscriptionsFromAddresses(List<String> addresses) async {
+  Future<List<InscriptionData>> getInscriptionsFromAddresses(List<String> addresses) async {
     List<InscriptionData> allInscriptions = [];
     for (String address in addresses) {
       try {

From 20fdcf48174c8cb102e950fd3f8ed146be96998a Mon Sep 17 00:00:00 2001
From: sneurlax <sneurlax@gmail.com>
Date: Thu, 20 Jul 2023 17:15:25 -0500
Subject: [PATCH 23/31] refactor manager var out to _manager, comment update

---
 lib/pages/ordinals/ordinals_view.dart       | 9 +++++----
 lib/services/mixins/ordinals_interface.dart | 2 +-
 2 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/lib/pages/ordinals/ordinals_view.dart b/lib/pages/ordinals/ordinals_view.dart
index 8993ed4e7..bf0545d4c 100644
--- a/lib/pages/ordinals/ordinals_view.dart
+++ b/lib/pages/ordinals/ordinals_view.dart
@@ -46,12 +46,16 @@ class _OrdinalsViewState extends ConsumerState<OrdinalsView> {
   late final FocusNode searchFocus;
 
   String _searchTerm = "";
+  dynamic _manager;
 
   @override
   void initState() {
     searchController = TextEditingController();
     searchFocus = FocusNode();
 
+    _manager = ref.watch(walletsChangeNotifierProvider
+        .select((value) => value.getManager(widget.walletId)));
+
     super.initState();
   }
 
@@ -91,10 +95,7 @@ class _OrdinalsViewState extends ConsumerState<OrdinalsView> {
                         .topNavIconPrimary,
                   ),
                   onPressed: () async {
-                    final manager = ref.watch(walletsChangeNotifierProvider
-                        .select((value) => value.getManager(widget.walletId)));
-
-                    (manager.wallet as OrdinalsInterface).refreshInscriptions();
+                    (_manager.wallet as OrdinalsInterface).refreshInscriptions();
                   },
                 ),
               ),
diff --git a/lib/services/mixins/ordinals_interface.dart b/lib/services/mixins/ordinals_interface.dart
index a04b6522c..2d887bfcd 100644
--- a/lib/services/mixins/ordinals_interface.dart
+++ b/lib/services/mixins/ordinals_interface.dart
@@ -52,7 +52,7 @@ mixin OrdinalsInterface {
     final utxos = await _db.getUTXOs(_walletId).findAll();
     final uniqueAddresses = getUniqueAddressesFromUTXOs(utxos);
     _inscriptions = await getInscriptionsFromAddresses(uniqueAddresses);
-    // TODO save inscriptions to isar which gets watched by a StreamBuilder
+    // TODO save inscriptions to isar which gets watched by a FutureBuilder/StreamBuilder
   }
 
   List<String> getUniqueAddressesFromUTXOs(List<UTXO> utxos) {

From af30826e9e9fa33502a5ac583eba14d0d4ff8dcd Mon Sep 17 00:00:00 2001
From: sneurlax <sneurlax@gmail.com>
Date: Fri, 21 Jul 2023 10:03:05 -0500
Subject: [PATCH 24/31] remove ord-litecoin imports

---
 lib/dto/ordinals/address_response.dart      | 52 -----------
 lib/dto/ordinals/block_response.dart        | 61 -------------
 lib/dto/ordinals/content_response.dart      | 22 -----
 lib/dto/ordinals/feed_response.dart         | 17 ----
 lib/dto/ordinals/inscription_link.dart      | 13 ---
 lib/dto/ordinals/inscription_response.dart  | 97 ---------------------
 lib/dto/ordinals/ordinals_response.dart     |  6 --
 lib/dto/ordinals/output_response.dart       | 47 ----------
 lib/dto/ordinals/preview_response.dart      | 22 -----
 lib/dto/ordinals/sat_response.dart          | 85 ------------------
 lib/dto/ordinals/transaction_response.dart  | 82 -----------------
 lib/services/mixins/ordinals_interface.dart | 12 ---
 12 files changed, 516 deletions(-)
 delete mode 100644 lib/dto/ordinals/address_response.dart
 delete mode 100644 lib/dto/ordinals/block_response.dart
 delete mode 100644 lib/dto/ordinals/content_response.dart
 delete mode 100644 lib/dto/ordinals/feed_response.dart
 delete mode 100644 lib/dto/ordinals/inscription_link.dart
 delete mode 100644 lib/dto/ordinals/inscription_response.dart
 delete mode 100644 lib/dto/ordinals/ordinals_response.dart
 delete mode 100644 lib/dto/ordinals/output_response.dart
 delete mode 100644 lib/dto/ordinals/preview_response.dart
 delete mode 100644 lib/dto/ordinals/sat_response.dart
 delete mode 100644 lib/dto/ordinals/transaction_response.dart

diff --git a/lib/dto/ordinals/address_response.dart b/lib/dto/ordinals/address_response.dart
deleted file mode 100644
index 9136aa523..000000000
--- a/lib/dto/ordinals/address_response.dart
+++ /dev/null
@@ -1,52 +0,0 @@
-import 'package:stackwallet/dto/ordinals/inscription_link.dart';
-import 'package:stackwallet/dto/ordinals/ordinals_response.dart';
-
-class AddressResponse extends OrdinalsResponse<AddressResponse> {
-  final AddressLinks links;
-  final String address;
-  final List<InscriptionLink> inscriptions;
-
-  AddressResponse({
-    required this.links,
-    required this.address,
-    required this.inscriptions,
-  });
-
-  factory AddressResponse.fromJson(OrdinalsResponse json) {
-    final data = json.data as Map<String, dynamic>;
-    final inscriptionsJson = data['inscriptions'] as List;
-    final inscriptions = inscriptionsJson
-        .map((inscriptionJson) => InscriptionLink.fromJson(inscriptionJson as Map<String, dynamic>))
-        .toList();
-
-    return AddressResponse(
-      links: AddressLinks.fromJson(data['_links'] as Map<String, dynamic>),
-      address: data['address'] as String,
-      inscriptions: inscriptions,
-    );
-  }
-}
-
-class AddressLinks {
-  final AddressLink? self;
-
-  AddressLinks({
-    this.self,
-  });
-
-  factory AddressLinks.fromJson(Map<String, dynamic> json) {
-    return AddressLinks(
-      self: json['self'] != null ? AddressLink.fromJson(json['self'] as Map<String, dynamic>) : null,
-    );
-  }
-}
-
-class AddressLink {
-  final String href;
-
-  AddressLink({required this.href});
-
-  factory AddressLink.fromJson(Map<String, dynamic> json) {
-    return AddressLink(href: json['href'] as String);
-  }
-}
diff --git a/lib/dto/ordinals/block_response.dart b/lib/dto/ordinals/block_response.dart
deleted file mode 100644
index 0eef8d569..000000000
--- a/lib/dto/ordinals/block_response.dart
+++ /dev/null
@@ -1,61 +0,0 @@
-import 'package:stackwallet/dto/ordinals/ordinals_response.dart';
-
-class BlockResponse extends OrdinalsResponse<BlockResponse> {
-  final BlockLinks links;
-  final String hash;
-  final String previousBlockhash;
-  final int size;
-  final String target;
-  final String timestamp;
-  final int weight;
-
-  BlockResponse({
-    required this.links,
-    required this.hash,
-    required this.previousBlockhash,
-    required this.size,
-    required this.target,
-    required this.timestamp,
-    required this.weight,
-  });
-
-  factory BlockResponse.fromJson(OrdinalsResponse json) {
-    final data = json.data as Map<String, dynamic>;
-    return BlockResponse(
-      links: BlockLinks.fromJson(data['_links'] as Map<String, dynamic>),
-      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,
-    );
-  }
-}
-
-class BlockLinks {
-  final BlockLink? prev;
-  final BlockLink? self;
-
-  BlockLinks({
-    this.prev,
-    this.self,
-  });
-
-  factory BlockLinks.fromJson(Map<String, dynamic> json) {
-    return BlockLinks(
-      prev: json['prev'] != null ? BlockLink.fromJson(json['prev'] as Map<String, dynamic>) : null,
-      self: json['self'] != null ? BlockLink.fromJson(json['self'] as Map<String, dynamic>) : null,
-    );
-  }
-}
-
-class BlockLink {
-  final String href;
-
-  BlockLink({required this.href});
-
-  factory BlockLink.fromJson(Map<String, dynamic> json) {
-    return BlockLink(href: json['href'] as String);
-  }
-}
diff --git a/lib/dto/ordinals/content_response.dart b/lib/dto/ordinals/content_response.dart
deleted file mode 100644
index 7cfbaf9fd..000000000
--- a/lib/dto/ordinals/content_response.dart
+++ /dev/null
@@ -1,22 +0,0 @@
-import 'package:stackwallet/dto/ordinals/ordinals_response.dart';
-
-class ContentResponse extends OrdinalsResponse<ContentResponse> {
-  final FileLink fileLink;
-
-  ContentResponse({required this.fileLink});
-
-  factory ContentResponse.fromJson(OrdinalsResponse json) {
-    final data = json.data as Map<String, dynamic>;
-    return ContentResponse(fileLink: FileLink.fromJson(data['_links']['file'] as Map<String, dynamic>)); // TODO don't cast as Map<String, dynamic>
-  }
-}
-
-class FileLink {
-  final String href;
-
-  FileLink({required this.href});
-
-  factory FileLink.fromJson(Map<String, dynamic> json) {
-    return FileLink(href: json['href'] as String);
-  }
-}
diff --git a/lib/dto/ordinals/feed_response.dart b/lib/dto/ordinals/feed_response.dart
deleted file mode 100644
index 525a7f727..000000000
--- a/lib/dto/ordinals/feed_response.dart
+++ /dev/null
@@ -1,17 +0,0 @@
-import 'package:stackwallet/dto/ordinals/inscription_link.dart';
-import 'package:stackwallet/dto/ordinals/ordinals_response.dart';
-
-class FeedResponse extends OrdinalsResponse<FeedResponse> {
-  final List<InscriptionLink> inscriptions;
-
-  FeedResponse({required this.inscriptions});
-  
-  factory FeedResponse.fromJson(OrdinalsResponse json) {
-    final List<dynamic> inscriptionsJson = json.data['_links']['inscriptions'] as List<dynamic>;
-    final List<InscriptionLink> inscriptions = inscriptionsJson
-        .map((json) => InscriptionLink.fromJson(json as Map<String, dynamic>))
-        .toList();
-
-    return FeedResponse(inscriptions: inscriptions);
-  }
-}
\ No newline at end of file
diff --git a/lib/dto/ordinals/inscription_link.dart b/lib/dto/ordinals/inscription_link.dart
deleted file mode 100644
index f23b63248..000000000
--- a/lib/dto/ordinals/inscription_link.dart
+++ /dev/null
@@ -1,13 +0,0 @@
-class InscriptionLink {
-  final String href;
-  final String title;
-
-  InscriptionLink({required this.href, required this.title});
-
-  factory InscriptionLink.fromJson(Map<String, dynamic> json) {
-    return InscriptionLink(
-      href: json['href'] as String ?? '',
-      title: json['title'] as String ?? '',
-    );
-  }
-}
diff --git a/lib/dto/ordinals/inscription_response.dart b/lib/dto/ordinals/inscription_response.dart
deleted file mode 100644
index d45300aee..000000000
--- a/lib/dto/ordinals/inscription_response.dart
+++ /dev/null
@@ -1,97 +0,0 @@
-import 'package:stackwallet/dto/ordinals/ordinals_response.dart';
-
-class InscriptionResponse extends OrdinalsResponse<InscriptionResponse> {
-  late final Links links;
-  late final String address;
-  late final int contentLength;
-  late final String contentType;
-  late final int genesisFee;
-  late final int genesisHeight;
-  late final String genesisTransaction;
-  late final String location;
-  late final int number;
-  late final int offset;
-  late final String output;
-  late final String? sat; // Make sure to update the type to allow null
-  late final String timestamp;
-
-  InscriptionResponse({
-    required this.links,
-    required this.address,
-    required this.contentLength,
-    required this.contentType,
-    required this.genesisFee,
-    required this.genesisHeight,
-    required this.genesisTransaction,
-    required this.location,
-    required this.number,
-    required this.offset,
-    required this.output,
-    required this.sat,
-    required this.timestamp,
-  });
-
-  factory InscriptionResponse.fromJson(OrdinalsResponse json) {
-    final data = json.data as Map<String, dynamic>;
-    return InscriptionResponse(
-      links: Links.fromJson(data['_links'] as Map<String, dynamic>),
-      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,
-    );
-  }
-}
-
-class Links {
-  late final Link content;
-  late final Link genesisTransaction;
-  late final Link next;
-  late final Link output;
-  late final Link prev;
-  late final Link preview;
-  late final Link? sat; // Make sure to update the type to allow null
-  late final Link self;
-
-  Links({
-    required this.content,
-    required this.genesisTransaction,
-    required this.next,
-    required this.output,
-    required this.prev,
-    required this.preview,
-    this.sat,
-    required this.self,
-  });
-
-  factory Links.fromJson(Map<String, dynamic> json) {
-    return Links(
-      content: Link.fromJson(json['content'] as Map<String, dynamic>),
-      genesisTransaction: Link.fromJson(json['genesis_transaction'] as Map<String, dynamic>),
-      next: Link.fromJson(json['next'] as Map<String, dynamic>),
-      output: Link.fromJson(json['output'] as Map<String, dynamic>),
-      prev: Link.fromJson(json['prev'] as Map<String, dynamic>),
-      preview: Link.fromJson(json['preview'] as Map<String, dynamic>),
-      sat: json['sat'] != null ? Link.fromJson(json['sat'] as Map<String, dynamic>) : null,
-      self: Link.fromJson(json['self'] as Map<String, dynamic>),
-    );
-  }
-}
-
-class Link {
-  late final String href;
-
-  Link({required this.href});
-
-  factory Link.fromJson(Map<String, dynamic> json) {
-    return Link(href: json['href'] as String);
-  }
-}
diff --git a/lib/dto/ordinals/ordinals_response.dart b/lib/dto/ordinals/ordinals_response.dart
deleted file mode 100644
index bf57db46b..000000000
--- a/lib/dto/ordinals/ordinals_response.dart
+++ /dev/null
@@ -1,6 +0,0 @@
-class OrdinalsResponse<T> {
-  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
deleted file mode 100644
index cc7b2107f..000000000
--- a/lib/dto/ordinals/output_response.dart
+++ /dev/null
@@ -1,47 +0,0 @@
-import 'package:stackwallet/dto/ordinals/transaction_response.dart';
-import 'package:stackwallet/dto/ordinals/ordinals_response.dart';
-
-class OutputResponse extends OrdinalsResponse<OutputResponse> {
-  final OutputLinks links;
-  final String address;
-  final String scriptPubkey;
-  final String transaction;
-  final int value;
-
-  OutputResponse({
-    required this.links,
-    required this.address,
-    required this.scriptPubkey,
-    required this.transaction,
-    required this.value,
-  });
-
-  factory OutputResponse.fromJson(OrdinalsResponse json) {
-    final data = json.data as Map<String, dynamic>;
-
-    return OutputResponse(
-      links: OutputLinks.fromJson(data['_links'] as Map<String, dynamic>),
-      address: data['address'] as String,
-      scriptPubkey: data['script_pubkey'] as String,
-      transaction: data['transaction'] as String,
-      value: data['value'] as int,
-    );
-  }
-}
-
-class OutputLinks {
-  final OutputLink? self;
-  final TransactionLink? transaction;
-
-  OutputLinks({
-    this.self,
-    this.transaction,
-  });
-
-  factory OutputLinks.fromJson(Map<String, dynamic> json) {
-    return OutputLinks(
-      self: json['self'] != null ? OutputLink.fromJson(json['self'] as Map<String, dynamic>) : null,
-      transaction: json['transaction'] != null ? TransactionLink.fromJson(json['transaction'] as Map<String, dynamic>) : null,
-    );
-  }
-}
diff --git a/lib/dto/ordinals/preview_response.dart b/lib/dto/ordinals/preview_response.dart
deleted file mode 100644
index b3e184acd..000000000
--- a/lib/dto/ordinals/preview_response.dart
+++ /dev/null
@@ -1,22 +0,0 @@
-import 'package:stackwallet/dto/ordinals/ordinals_response.dart';
-
-class PreviewResponse extends OrdinalsResponse<PreviewResponse> {
-  final ImageLink imageLink;
-
-  PreviewResponse({required this.imageLink});
-
-  factory PreviewResponse.fromJson(OrdinalsResponse json) {
-    final data = json.data as Map<String, dynamic>;
-    return PreviewResponse(imageLink: ImageLink.fromJson(data['_links']['image'] as Map<String, dynamic>));
-  }
-}
-
-class ImageLink {
-  final String href;
-
-  ImageLink({required this.href});
-
-  factory ImageLink.fromJson(Map<String, dynamic> json) {
-    return ImageLink(href: json['href'] as String);
-  }
-}
diff --git a/lib/dto/ordinals/sat_response.dart b/lib/dto/ordinals/sat_response.dart
deleted file mode 100644
index 40efb1440..000000000
--- a/lib/dto/ordinals/sat_response.dart
+++ /dev/null
@@ -1,85 +0,0 @@
-import 'package:stackwallet/dto/ordinals/ordinals_response.dart';
-
-class SatResponse extends OrdinalsResponse<SatResponse> {
-  final SatLinks links;
-  final int block;
-  final int cycle;
-  final String decimal;
-  final String degree;
-  final int epoch;
-  final String name;
-  final int offset;
-  final String percentile;
-  final int period;
-  final String rarity;
-  final String timestamp;
-
-  SatResponse({
-    required this.links,
-    required this.block,
-    required this.cycle,
-    required this.decimal,
-    required this.degree,
-    required this.epoch,
-    required this.name,
-    required this.offset,
-    required this.percentile,
-    required this.period,
-    required this.rarity,
-    required this.timestamp,
-  });
-
-  factory SatResponse.fromJson(OrdinalsResponse json) {
-    final data = json.data as Map<String, dynamic>;
-    return SatResponse(
-      links: SatLinks.fromJson(data['_links'] as Map<String, dynamic>),
-      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,
-    );
-  }
-}
-
-class SatLinks {
-  final SatLink? block;
-  final SatLink? inscription;
-  final SatLink? next;
-  final SatLink? prev;
-  final SatLink? self;
-
-  SatLinks({
-    this.block,
-    this.inscription,
-    this.next,
-    this.prev,
-    this.self,
-  });
-
-  factory SatLinks.fromJson(Map<String, dynamic> json) {
-    return SatLinks(
-      block: json['block'] != null ? SatLink.fromJson(json['block'] as Map<String, dynamic>) : null,
-      inscription: json['inscription'] != null ? SatLink.fromJson(json['inscription'] as Map<String, dynamic>) : null,
-      next: json['next'] != null ? SatLink.fromJson(json['next'] as Map<String, dynamic>) : null,
-      prev: json['prev'] != null ? SatLink.fromJson(json['prev'] as Map<String, dynamic>) : null,
-      self: json['self'] != null ? SatLink.fromJson(json['self'] as Map<String, dynamic>) : null,
-    );
-  }
-}
-
-class SatLink {
-  final String href;
-
-  SatLink({required this.href});
-
-  factory SatLink.fromJson(Map<String, dynamic> json) {
-    return SatLink(href: json['href'] as String);
-  }
-}
diff --git a/lib/dto/ordinals/transaction_response.dart b/lib/dto/ordinals/transaction_response.dart
deleted file mode 100644
index c77e07914..000000000
--- a/lib/dto/ordinals/transaction_response.dart
+++ /dev/null
@@ -1,82 +0,0 @@
-import 'package:stackwallet/dto/ordinals/inscription_link.dart';
-import 'package:stackwallet/dto/ordinals/ordinals_response.dart';
-
-class TransactionResponse extends OrdinalsResponse<TransactionResponse> {
-  final TransactionLinks links;
-  final List<OutputLink> inputs;
-  final InscriptionLink inscription;
-  final List<OutputLink> outputs;
-  final TransactionLink self;
-  final String transaction;
-
-  TransactionResponse({
-    required this.links,
-    required this.inputs,
-    required this.inscription,
-    required this.outputs,
-    required this.self,
-    required this.transaction,
-  });
-
-  factory TransactionResponse.fromJson(OrdinalsResponse json) {
-    final data = json.data as Map<String, dynamic>;
-    final inputsJson = data['_links']['inputs'] as List;
-    final inputs = inputsJson
-        .map((inputJson) => OutputLink.fromJson(inputJson as Map<String, dynamic>))
-        .toList();
-
-    final outputsJson = data['_links']['outputs'] as List;
-    final outputs = outputsJson
-        .map((outputJson) => OutputLink.fromJson(outputJson as Map<String, dynamic>))
-        .toList();
-
-    return TransactionResponse(
-      links: TransactionLinks.fromJson(data['_links'] as Map<String, dynamic>),
-      inputs: inputs,
-      inscription: InscriptionLink.fromJson(data['_links']['inscription'] as Map<String, dynamic>),
-      outputs: outputs,
-      self: TransactionLink.fromJson(data['_links']['self'] as Map<String, dynamic>),
-      transaction: data['transaction'] as String,
-    );
-  }
-}
-
-class TransactionLinks {
-  final TransactionLink? block;
-  final InscriptionLink? inscription;
-  final TransactionLink? self;
-
-  TransactionLinks({
-    this.block,
-    this.inscription,
-    this.self,
-  });
-
-  factory TransactionLinks.fromJson(Map<String, dynamic> json) {
-    return TransactionLinks(
-      block: json['block'] != null ? TransactionLink.fromJson(json['block'] as Map<String, dynamic>) : null,
-      inscription: json['inscription'] != null ? InscriptionLink.fromJson(json['inscription'] as Map<String, dynamic>) : null,
-      self: json['self'] != null ? TransactionLink.fromJson(json['self'] as Map<String, dynamic>) : null,
-    );
-  }
-}
-
-class TransactionLink {
-  final String href;
-
-  TransactionLink({required this.href});
-
-  factory TransactionLink.fromJson(Map<String, dynamic> json) {
-    return TransactionLink(href: json['href'] as String);
-  }
-}
-
-class OutputLink {
-  final String href;
-
-  OutputLink({required this.href});
-
-  factory OutputLink.fromJson(Map<String, dynamic> json) {
-    return OutputLink(href: json['href'] as String);
-  }
-}
diff --git a/lib/services/mixins/ordinals_interface.dart b/lib/services/mixins/ordinals_interface.dart
index 2d887bfcd..c7bc5ff28 100644
--- a/lib/services/mixins/ordinals_interface.dart
+++ b/lib/services/mixins/ordinals_interface.dart
@@ -5,18 +5,6 @@ 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';
 
-// ord-litecoin-specific imports
-// import 'package:stackwallet/dto/ordinals/feed_response.dart';
-// import 'package:stackwallet/dto/ordinals/inscription_response.dart';
-// import 'package:stackwallet/dto/ordinals/sat_response.dart';
-// import 'package:stackwallet/dto/ordinals/transaction_response.dart';
-// import 'package:stackwallet/dto/ordinals/output_response.dart';
-// import 'package:stackwallet/dto/ordinals/address_response.dart';
-// import 'package:stackwallet/dto/ordinals/block_response.dart';
-// import 'package:stackwallet/dto/ordinals/content_response.dart';
-// import 'package:stackwallet/dto/ordinals/preview_response.dart';
-// import 'package:stackwallet/services/ordinals_api.dart';
-
 import 'package:stackwallet/services/litescribe_api.dart';
 import 'package:stackwallet/dto/ordinals/inscription_data.dart';
 

From 39eaa937fc83fb3aec9882ad1b6744ff1367abef Mon Sep 17 00:00:00 2001
From: sneurlax <sneurlax@gmail.com>
Date: Fri, 21 Jul 2023 10:06:34 -0500
Subject: [PATCH 25/31] add convenience method, remove ord-litecoin API file,
 cast dynamic->int

---
 lib/services/litescribe_api.dart            |  2 +-
 lib/services/mixins/ordinals_interface.dart |  6 ++
 lib/services/ordinals_api.dart              | 89 ---------------------
 3 files changed, 7 insertions(+), 90 deletions(-)
 delete mode 100644 lib/services/ordinals_api.dart

diff --git a/lib/services/litescribe_api.dart b/lib/services/litescribe_api.dart
index 7fc92910d..d5cd3d733 100644
--- a/lib/services/litescribe_api.dart
+++ b/lib/services/litescribe_api.dart
@@ -44,7 +44,7 @@ class LitescribeAPI {
     // 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;
+    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,
diff --git a/lib/services/mixins/ordinals_interface.dart b/lib/services/mixins/ordinals_interface.dart
index c7bc5ff28..51323fa0c 100644
--- a/lib/services/mixins/ordinals_interface.dart
+++ b/lib/services/mixins/ordinals_interface.dart
@@ -43,6 +43,12 @@ mixin OrdinalsInterface {
     // TODO save inscriptions to isar which gets watched by a FutureBuilder/StreamBuilder
   }
 
+  Future<List<InscriptionData>> getInscriptions() async {
+    final utxos = await _db.getUTXOs(_walletId).findAll();
+    final uniqueAddresses = getUniqueAddressesFromUTXOs(utxos);
+    return await getInscriptionsFromAddresses(uniqueAddresses);
+  }
+
   List<String> getUniqueAddressesFromUTXOs(List<UTXO> utxos) {
     final Set<String> uniqueAddresses = <String>{};
     for (var utxo in utxos) {
diff --git a/lib/services/ordinals_api.dart b/lib/services/ordinals_api.dart
deleted file mode 100644
index e6df3c05e..000000000
--- a/lib/services/ordinals_api.dart
+++ /dev/null
@@ -1,89 +0,0 @@
-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';
-import 'package:stackwallet/dto/ordinals/transaction_response.dart';
-import 'package:stackwallet/dto/ordinals/output_response.dart';
-import 'package:stackwallet/dto/ordinals/address_response.dart';
-import 'package:stackwallet/dto/ordinals/block_response.dart';
-import 'package:stackwallet/dto/ordinals/content_response.dart';
-import 'package:stackwallet/dto/ordinals/preview_response.dart';
-
-class OrdinalsAPI {
-  static final OrdinalsAPI _instance = OrdinalsAPI._internal();
-
-  factory OrdinalsAPI({required String baseUrl}) {
-    _instance.baseUrl = baseUrl;
-    return _instance;
-  }
-
-  OrdinalsAPI._internal();
-
-  late String baseUrl;
-
-  Future<OrdinalsResponse> _getResponse(String endpoint) async {
-    final response = await http.get(Uri.parse('$baseUrl$endpoint'));
-    if (response.statusCode == 200) {
-      return OrdinalsResponse(data: _validateJson(response.body));
-    } else {
-      throw 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('Invalid JSON format');
-    }
-  }
-
-  Future<FeedResponse> getLatestInscriptions() async {
-    final response = await _getResponse('/feed');
-    return FeedResponse.fromJson(response);
-  }
-
-  Future<InscriptionResponse> getInscriptionDetails(String inscriptionId) async {
-    final response = await _getResponse('/inscription/$inscriptionId');
-    return InscriptionResponse.fromJson(response);
-  }
-
-  Future<SatResponse> getSatDetails(int satNumber) async {
-    final response = await _getResponse('/sat/$satNumber');
-    return SatResponse.fromJson(response);
-  }
-
-  Future<TransactionResponse> getTransaction(String transactionId) async {
-    final response = await _getResponse('/tx/$transactionId');
-    return TransactionResponse.fromJson(response);
-  }
-
-  Future<OutputResponse> getTransactionOutputs(String transactionId) async {
-    final response = await _getResponse('/output/$transactionId');
-    return OutputResponse.fromJson(response);
-  }
-
-  Future<AddressResponse> getInscriptionsByAddress(String address) async {
-    final response = await _getResponse('/address/$address');
-    return AddressResponse.fromJson(response);
-  }
-
-  Future<BlockResponse> getBlock(String blockHash) async {
-    final response = await _getResponse('/block/$blockHash');
-    return BlockResponse.fromJson(response);
-  }
-
-  Future<ContentResponse> getInscriptionContent(String inscriptionId) async {
-    final response = await _getResponse('/content/$inscriptionId');
-    return ContentResponse.fromJson(response);
-  }
-
-  Future<PreviewResponse> getInscriptionPreview(String inscriptionId) async {
-    final response = await _getResponse('/preview/$inscriptionId');
-    return PreviewResponse.fromJson(response);
-  }
-}

From c295ca9a6f1c7146960b455c3bb428a82fe7de72 Mon Sep 17 00:00:00 2001
From: sneurlax <sneurlax@gmail.com>
Date: Fri, 21 Jul 2023 10:12:31 -0500
Subject: [PATCH 26/31] fix ordinal view crash

---
 lib/pages/ordinals/ordinals_view.dart | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/lib/pages/ordinals/ordinals_view.dart b/lib/pages/ordinals/ordinals_view.dart
index bf0545d4c..c340fa6c6 100644
--- a/lib/pages/ordinals/ordinals_view.dart
+++ b/lib/pages/ordinals/ordinals_view.dart
@@ -53,9 +53,6 @@ class _OrdinalsViewState extends ConsumerState<OrdinalsView> {
     searchController = TextEditingController();
     searchFocus = FocusNode();
 
-    _manager = ref.watch(walletsChangeNotifierProvider
-        .select((value) => value.getManager(widget.walletId)));
-
     super.initState();
   }
 
@@ -95,6 +92,8 @@ class _OrdinalsViewState extends ConsumerState<OrdinalsView> {
                         .topNavIconPrimary,
                   ),
                   onPressed: () async {
+                    _manager = ref.watch(walletsChangeNotifierProvider
+                        .select((value) => value.getManager(widget.walletId)));
                     (_manager.wallet as OrdinalsInterface).refreshInscriptions();
                   },
                 ),

From f750bbfe102239ec7d0f7ac195896ca23218693b Mon Sep 17 00:00:00 2001
From: sneurlax <sneurlax@gmail.com>
Date: Fri, 21 Jul 2023 10:30:47 -0500
Subject: [PATCH 27/31] hook OrdinalsList up to OrdinalsInterface

---
 lib/pages/ordinals/ordinals_view.dart         | 22 +++----
 lib/pages/ordinals/widgets/ordinal_card.dart  | 24 +++----
 lib/pages/ordinals/widgets/ordinals_list.dart | 62 +++++++++++--------
 3 files changed, 57 insertions(+), 51 deletions(-)

diff --git a/lib/pages/ordinals/ordinals_view.dart b/lib/pages/ordinals/ordinals_view.dart
index c340fa6c6..b12fb78c4 100644
--- a/lib/pages/ordinals/ordinals_view.dart
+++ b/lib/pages/ordinals/ordinals_view.dart
@@ -56,6 +56,14 @@ class _OrdinalsViewState extends ConsumerState<OrdinalsView> {
     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();
@@ -92,8 +100,6 @@ class _OrdinalsViewState extends ConsumerState<OrdinalsView> {
                         .topNavIconPrimary,
                   ),
                   onPressed: () async {
-                    _manager = ref.watch(walletsChangeNotifierProvider
-                        .select((value) => value.getManager(widget.walletId)));
                     (_manager.wallet as OrdinalsInterface).refreshInscriptions();
                   },
                 ),
@@ -187,17 +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",
-                          collection: OrdCollection.moonbirds,
-                          utxoTXID: 'txid',
-                          utxoVOUT: 1
-                        ),
-                    ],
+                    ordinalsFuture: (_manager.wallet as OrdinalsInterface).getInscriptions(),
                   ),
                 ),
               ],
diff --git a/lib/pages/ordinals/widgets/ordinal_card.dart b/lib/pages/ordinals/widgets/ordinal_card.dart
index a3419ae87..a4d58711e 100644
--- a/lib/pages/ordinals/widgets/ordinal_card.dart
+++ b/lib/pages/ordinals/widgets/ordinal_card.dart
@@ -1,18 +1,19 @@
 import 'package:flutter/material.dart';
-import 'package:stackwallet/models/ordinal.dart';
+import 'package:stackwallet/dto/ordinals/inscription_data.dart';
+import 'package:stackwallet/models/ordinal.dart'; // TODO generalize InscriptionData models -> Ordinal
 import 'package:stackwallet/pages/ordinals/ordinal_details_view.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
 
 class OrdinalCard extends StatelessWidget {
   const OrdinalCard({
-    super.key,
+    Key? key,
     required this.walletId,
-    required this.ordinal,
-  });
+    required this.inscriptionData,
+  }) : super(key: key);
 
   final String walletId;
-  final Ordinal ordinal;
+  final InscriptionData inscriptionData;
 
   @override
   Widget build(BuildContext context) {
@@ -21,7 +22,7 @@ class OrdinalCard extends StatelessWidget {
       onPressed: () {
         Navigator.of(context).pushNamed(
           OrdinalDetailsView.routeName,
-          arguments: (walletId: walletId, ordinal: ordinal),
+          arguments: (walletId: walletId, inscriptionData: inscriptionData),
         );
       },
       child: Column(
@@ -31,21 +32,20 @@ class OrdinalCard extends StatelessWidget {
             aspectRatio: 1,
             child: Container(
               color: Colors.red,
-              child: const Center(
-                child: Text(
-                  "replace red container with image",
-                ),
+              child: Image.network(
+                inscriptionData.preview, // Use the preview URL as the image source
+                fit: BoxFit.cover,
               ),
             ),
           ),
           const Spacer(),
           Text(
-            ordinal.name,
+            inscriptionData.address,
             style: STextStyles.w500_12(context),
           ),
           const Spacer(),
           Text(
-            "INSC. ${ordinal.inscription}   RANK ${ordinal.rank}",
+            "INSC. ${inscriptionData.inscriptionNumber}   ID ${inscriptionData.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..d161cafeb 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/dto/ordinals/inscription_data.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<InscriptionData>> 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<InscriptionData>>(
+      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<InscriptionData> inscriptions = snapshot.data!;
+          return GridView.builder(
+            shrinkWrap: true,
+            itemCount: inscriptions.length,
+            gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
+              crossAxisSpacing: spacing as double,
+              mainAxisSpacing: spacing as double,
+              crossAxisCount: 2,
+              childAspectRatio: 3 / 4,
+            ),
+            itemBuilder: (_, i) => OrdinalCard(
+              walletId: walletId,
+              inscriptionData: inscriptions[i],
+            ),
+          );
+        } else {
+          return Text('No data found.');
+        }
+      },
     );
   }
-}
+}
\ No newline at end of file

From 65e8c34e34fd33dabff5909d3ee0666a06e1f50b Mon Sep 17 00:00:00 2001
From: sneurlax <sneurlax@gmail.com>
Date: Fri, 21 Jul 2023 10:43:02 -0500
Subject: [PATCH 28/31] hook up details view to OrdinalsInterface

---
 lib/pages/ordinals/ordinal_details_view.dart | 47 ++++++++++----------
 lib/route_generator.dart                     | 10 ++---
 2 files changed, 29 insertions(+), 28 deletions(-)

diff --git a/lib/pages/ordinals/ordinal_details_view.dart b/lib/pages/ordinals/ordinal_details_view.dart
index 2057e8792..c1ca67500 100644
--- a/lib/pages/ordinals/ordinal_details_view.dart
+++ b/lib/pages/ordinals/ordinal_details_view.dart
@@ -3,7 +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/models/ordinal.dart';
+import 'package:stackwallet/dto/ordinals/inscription_data.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,20 +15,21 @@ 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({
-    super.key,
+    Key? key,
     required this.walletId,
-    required this.ordinal,
-  });
+    required this.inscriptionData,
+  }) : super(key: key);
 
   final String walletId;
-  final Ordinal ordinal;
+  final InscriptionData inscriptionData;
 
   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",
@@ -61,20 +62,20 @@ class _OrdinalDetailsViewState extends State<OrdinalDetailsView> {
                       horizontal: 39,
                     ),
                     child: _OrdinalImageGroup(
-                      ordinal: widget.ordinal,
+                      inscriptionData: widget.inscriptionData,
                       walletId: widget.walletId,
                     ),
                   ),
                   _DetailsItemWCopy(
                     title: "Inscription number",
-                    data: widget.ordinal.inscription,
+                    data: widget.inscriptionData.inscriptionNumber.toString(),
                   ),
                   const SizedBox(
                     height: _spacing,
                   ),
                   _DetailsItemWCopy(
-                    title: "Rank",
-                    data: widget.ordinal.rank,
+                    title: "ID",
+                    data: widget.inscriptionData.inscriptionId,
                   ),
                   const SizedBox(
                     height: _spacing,
@@ -85,21 +86,21 @@ class _OrdinalDetailsViewState extends State<OrdinalDetailsView> {
                   ),
                   _DetailsItemWCopy(
                     title: "Amount",
-                    data: "FIXME",
+                    data: "${widget.inscriptionData.outputValue}",
                   ),
                   const SizedBox(
                     height: _spacing,
                   ),
                   _DetailsItemWCopy(
                     title: "Owner address",
-                    data: "FIXME",
+                    data: widget.inscriptionData.address,
                   ),
                   const SizedBox(
                     height: _spacing,
                   ),
                   _DetailsItemWCopy(
                     title: "Transaction ID",
-                    data: "FIXME",
+                    data: widget.inscriptionData.genesisTransaction,
                   ),
                   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,13 +175,13 @@ class _DetailsItemWCopy extends StatelessWidget {
 
 class _OrdinalImageGroup extends StatelessWidget {
   const _OrdinalImageGroup({
-    super.key,
+    Key? key,
     required this.walletId,
-    required this.ordinal,
-  });
+    required this.inscriptionData,
+  }) : super(key: key);
 
   final String walletId;
-  final Ordinal ordinal;
+  final InscriptionData inscriptionData;
 
   static const _spacing = 12.0;
 
@@ -191,7 +192,7 @@ class _OrdinalImageGroup extends StatelessWidget {
       crossAxisAlignment: CrossAxisAlignment.center,
       children: [
         Text(
-          ordinal.name,
+          "${inscriptionData.inscriptionId}", // Use any other property you want
           style: STextStyles.w600_16(context),
         ),
         const SizedBox(
diff --git a/lib/route_generator.dart b/lib/route_generator.dart
index 6217cf201..e67254135 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.
@@ -423,12 +423,12 @@ class RouteGenerator {
         return _routeError("${settings.name} invalid args: ${args.toString()}");
 
       case OrdinalDetailsView.routeName:
-        if (args is ({Ordinal ordinal, String walletId})) {
+        if (args is ({InscriptionData inscriptionData, String walletId})) {
           return getRoute(
             shouldUseMaterialRoute: useMaterialPageRoute,
             builder: (_) => OrdinalDetailsView(
               walletId: args.walletId,
-              ordinal: args.ordinal,
+              inscriptionData: args.inscriptionData,
             ),
             settings: RouteSettings(
               name: settings.name,

From ddba1c54f76fcb82ede425cc6676813640b12295 Mon Sep 17 00:00:00 2001
From: sneurlax <sneurlax@gmail.com>
Date: Fri, 21 Jul 2023 10:49:30 -0500
Subject: [PATCH 29/31] show ordinal image

---
 lib/pages/ordinals/ordinal_details_view.dart | 12 ++++++++++--
 lib/pages/ordinals/widgets/ordinal_card.dart |  9 +++++----
 2 files changed, 15 insertions(+), 6 deletions(-)

diff --git a/lib/pages/ordinals/ordinal_details_view.dart b/lib/pages/ordinals/ordinal_details_view.dart
index c1ca67500..bd5b9a17e 100644
--- a/lib/pages/ordinals/ordinal_details_view.dart
+++ b/lib/pages/ordinals/ordinal_details_view.dart
@@ -200,8 +200,16 @@ class _OrdinalImageGroup extends StatelessWidget {
         ),
         AspectRatio(
           aspectRatio: 1,
-          child: Container(
-            color: Colors.red,
+          child: AspectRatio(
+            aspectRatio: 1,
+            child: Container(
+              color: Colors.red,
+              child: Image.network(
+                inscriptionData.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/widgets/ordinal_card.dart b/lib/pages/ordinals/widgets/ordinal_card.dart
index a4d58711e..0c05f686a 100644
--- a/lib/pages/ordinals/widgets/ordinal_card.dart
+++ b/lib/pages/ordinals/widgets/ordinal_card.dart
@@ -28,13 +28,14 @@ class OrdinalCard extends StatelessWidget {
       child: Column(
         crossAxisAlignment: CrossAxisAlignment.center,
         children: [
-          AspectRatio(
-            aspectRatio: 1,
-            child: Container(
+            AspectRatio(
+              aspectRatio: 1,
+              child: Container(
               color: Colors.red,
               child: Image.network(
-                inscriptionData.preview, // Use the preview URL as the image source
+                inscriptionData.content, // Use the preview URL as the image source
                 fit: BoxFit.cover,
+                filterQuality: FilterQuality.none, // Set the filter mode to nearest
               ),
             ),
           ),

From f46a37d4d4775cb9f8bc3feb825350e577d202f2 Mon Sep 17 00:00:00 2001
From: sneurlax <sneurlax@gmail.com>
Date: Fri, 21 Jul 2023 11:48:31 -0500
Subject: [PATCH 30/31] 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<OrdinalDetailsView> {
                       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<OrdinalDetailsView> {
                   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<OrdinalsView> {
                 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<List<InscriptionData>> ordinalsFuture;
+  final Future<List<Ordinal>> ordinalsFuture;
 
   get spacing => 2.0;
 
   @override
   Widget build(BuildContext context) {
-    return FutureBuilder<List<InscriptionData>>(
+    return FutureBuilder<List<Ordinal>>(
       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<InscriptionData> inscriptions = snapshot.data!;
+          final List<Ordinal> 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<List<InscriptionData>> 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<dynamic> _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<List<InscriptionData>> getInscriptions() async {
-    final utxos = await _db.getUTXOs(_walletId).findAll();
-    final uniqueAddresses = getUniqueAddressesFromUTXOs(utxos);
-    return await getInscriptionsFromAddresses(uniqueAddresses);
+  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) {
@@ -59,12 +63,22 @@ mixin OrdinalsInterface {
     return uniqueAddresses.toList();
   }
 
-  Future<List<InscriptionData>> getInscriptionsFromAddresses(List<String> addresses) async {
+  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);
-        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<FeedResponse> fetchLatestInscriptions() async {
+  Future<List<Ordinal>> 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<InscriptionResponse> getInscriptionDetails(String inscriptionId) async {
-    try {
-      return await ordinalsAPI.getInscriptionDetails(inscriptionId);
-    } catch (e) {
-      throw Exception('Error in OrdinalsInterface getInscriptionDetails: $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;
   }
-
-  Future<SatResponse> getSatDetails(int satNumber) async {
-    try {
-      return await ordinalsAPI.getSatDetails(satNumber);
-    } catch (e) {
-      throw Exception('Error in OrdinalsInterface getSatDetails: $e');
-    }
-  }
-
-  Future<TransactionResponse> getTransaction(String transactionId) async {
-    try {
-      print(1);
-      return await ordinalsAPI.getTransaction(transactionId);
-    } catch (e) {
-      throw Exception('Error in OrdinalsInterface getTransaction: $e');
-    }
-  }
-
-  Future<OutputResponse> getTransactionOutputs(String transactionId) async {
-    try {
-      return await ordinalsAPI.getTransactionOutputs(transactionId);
-    } catch (e) {
-      throw Exception('Error in OrdinalsInterface getTransactionOutputs: $e');
-    }
-  }
-
-  Future<AddressResponse> getInscriptionsByAddress(String address) async {
-    try {
-      return await ordinalsAPI.getInscriptionsByAddress(address);
-    } catch (e) {
-      throw Exception('Error in OrdinalsInterface getInscriptionsByAddress: $e');
-    }
-  }
-
-  Future<BlockResponse> getBlock(int blockNumber) async {
-    try {
-      return await ordinalsAPI.getBlock(blockNumber);
-    } catch (e) {
-      throw Exception('Error in OrdinalsInterface getBlock: $e');
-    }
-  }
-
-  Future<ContentResponse> getInscriptionContent(String inscriptionId) async {
-    try {
-      return await ordinalsAPI.getInscriptionContent(inscriptionId);
-    } catch (e) {
-      throw Exception('Error in OrdinalsInterface getInscriptionContent: $e');
-    }
-  }
-
-  Future<PreviewResponse> 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

From 5a845f866936bdc6e2f5b66e540cfb29878ed05c Mon Sep 17 00:00:00 2001
From: sneurlax <sneurlax@gmail.com>
Date: Fri, 21 Jul 2023 16:35:00 -0500
Subject: [PATCH 31/31] hide certain fields on ordinals views, change ordinal
 card aspect ratio

---
 lib/pages/ordinals/ordinal_details_view.dart  | 14 +++++++-------
 lib/pages/ordinals/widgets/ordinal_card.dart  | 12 ++++++------
 lib/pages/ordinals/widgets/ordinals_list.dart |  4 ++--
 3 files changed, 15 insertions(+), 15 deletions(-)

diff --git a/lib/pages/ordinals/ordinal_details_view.dart b/lib/pages/ordinals/ordinal_details_view.dart
index 6aab95586..95cff734e 100644
--- a/lib/pages/ordinals/ordinal_details_view.dart
+++ b/lib/pages/ordinals/ordinal_details_view.dart
@@ -191,13 +191,13 @@ class _OrdinalImageGroup extends StatelessWidget {
       mainAxisSize: MainAxisSize.min,
       crossAxisAlignment: CrossAxisAlignment.center,
       children: [
-        Text(
-          "${ordinal.inscriptionId}", // Use any other property you want
-          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: AspectRatio(
diff --git a/lib/pages/ordinals/widgets/ordinal_card.dart b/lib/pages/ordinals/widgets/ordinal_card.dart
index c9060b32e..4ac4fd877 100644
--- a/lib/pages/ordinals/widgets/ordinal_card.dart
+++ b/lib/pages/ordinals/widgets/ordinal_card.dart
@@ -41,14 +41,14 @@ class OrdinalCard extends StatelessWidget {
           ),
           const Spacer(),
           Text(
-            'TODO', // infer from address associated with utxoTXID
+            'INSC. ${ordinal.inscriptionNumber}', // infer from address associated with utxoTXID
             style: STextStyles.w500_12(context),
           ),
-          const Spacer(),
-          Text(
-            "INSC. ${ordinal.inscriptionNumber}   ID ${ordinal.inscriptionId}",
-            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 fe7618cd0..62d620130 100644
--- a/lib/pages/ordinals/widgets/ordinals_list.dart
+++ b/lib/pages/ordinals/widgets/ordinals_list.dart
@@ -33,7 +33,7 @@ class OrdinalsList extends StatelessWidget {
               crossAxisSpacing: spacing as double,
               mainAxisSpacing: spacing as double,
               crossAxisCount: 2,
-              childAspectRatio: 3 / 4,
+              childAspectRatio: 6 / 7, // was 3/4, less data displayed now
             ),
             itemBuilder: (_, i) => OrdinalCard(
               walletId: walletId,
@@ -41,7 +41,7 @@ class OrdinalsList extends StatelessWidget {
             ),
           );
         } else {
-          return Text('No data found.');
+          return const Text('No data found.');
         }
       },
     );