From a56b7f1e9a958041a9322504cdf1411fa144c13a Mon Sep 17 00:00:00 2001
From: Dariusz Rybicki <dariusz@elixxir.io>
Date: Wed, 24 Aug 2022 13:19:01 +0100
Subject: [PATCH 1/3] Add UDSearchResult model

---
 Sources/XXClient/Models/UDSearchResult.swift  | 39 ++++++++++++++++
 .../Models/UDSearchResultTests.swift          | 45 +++++++++++++++++++
 2 files changed, 84 insertions(+)
 create mode 100644 Sources/XXClient/Models/UDSearchResult.swift
 create mode 100644 Tests/XXClientTests/Models/UDSearchResultTests.swift

diff --git a/Sources/XXClient/Models/UDSearchResult.swift b/Sources/XXClient/Models/UDSearchResult.swift
new file mode 100644
index 00000000..26e6bf4d
--- /dev/null
+++ b/Sources/XXClient/Models/UDSearchResult.swift
@@ -0,0 +1,39 @@
+import Foundation
+
+public struct UDSearchResult: Equatable {
+  public init(
+    id: Data,
+    facts: [Fact]
+  ) {
+    self.id = id
+    self.facts = facts
+  }
+
+  public var id: Data
+  public var facts: [Fact]
+}
+
+extension UDSearchResult: Codable {
+  enum CodingKeys: String, CodingKey {
+    case id = "ID"
+    case facts = "Facts"
+  }
+
+  public static func decode(_ data: Data) throws -> Self {
+    try JSONDecoder().decode(Self.self, from: data)
+  }
+
+  public func encode() throws -> Data {
+    try JSONEncoder().encode(self)
+  }
+}
+
+extension Array where Element == UDSearchResult {
+  public static func decode(_ data: Data) throws -> Self {
+    try JSONDecoder().decode(Self.self, from: data)
+  }
+
+  public func encode() throws -> Data {
+    try JSONEncoder().encode(self)
+  }
+}
diff --git a/Tests/XXClientTests/Models/UDSearchResultTests.swift b/Tests/XXClientTests/Models/UDSearchResultTests.swift
new file mode 100644
index 00000000..3037e773
--- /dev/null
+++ b/Tests/XXClientTests/Models/UDSearchResultTests.swift
@@ -0,0 +1,45 @@
+import CustomDump
+import XCTest
+@testable import XXClient
+
+final class UDSearchResultTests: XCTestCase {
+  func testCoding() throws {
+    let idB64 = "pYIpRwPy+FnOkl5tndkG8RC93W/t5b1lszqPpMDynlUD"
+    let facts: [Fact] = [
+      Fact(fact: "carlos_arimateias", type: 0),
+    ]
+    let jsonString = """
+    {
+      "ID": "\(idB64)",
+      "Facts": \(String(data: try! facts.encode(), encoding: .utf8)!)
+    }
+    """
+    let jsonData = jsonString.data(using: .utf8)!
+    let model = try UDSearchResult.decode(jsonData)
+
+    XCTAssertNoDifference(model, UDSearchResult(
+      id: Data(base64Encoded: idB64)!,
+      facts: facts
+    ))
+
+    let encodedModel = try model.encode()
+    let decodedModel = try UDSearchResult.decode(encodedModel)
+
+    XCTAssertNoDifference(decodedModel, model)
+  }
+
+  func testCodingArray() throws {
+    let models: [UDSearchResult] = [
+      UDSearchResult(
+        id: Data(base64Encoded: "pYIpRwPy+FnOkl5tndkG8RC93W/t5b1lszqPpMDynlUD")!,
+        facts: [
+          Fact(fact: "carlos_arimateias", type: 0),
+        ]
+      ),
+    ]
+    let encodedModels = try models.encode()
+    let decodedModels = try [UDSearchResult].decode(encodedModels)
+
+    XCTAssertNoDifference(decodedModels, models)
+  }
+}
-- 
GitLab


From 9a3e5d90461a995198be4da14f92aae348fa3fb8 Mon Sep 17 00:00:00 2001
From: Dariusz Rybicki <dariusz@elixxir.io>
Date: Wed, 24 Aug 2022 13:19:17 +0100
Subject: [PATCH 2/3] Use UDSearchResult model in UdSearchCallback

---
 Sources/XXClient/Callbacks/UdSearchCallback.swift | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/Sources/XXClient/Callbacks/UdSearchCallback.swift b/Sources/XXClient/Callbacks/UdSearchCallback.swift
index d836dcb3..252c6546 100644
--- a/Sources/XXClient/Callbacks/UdSearchCallback.swift
+++ b/Sources/XXClient/Callbacks/UdSearchCallback.swift
@@ -2,11 +2,11 @@ import Bindings
 import XCTestDynamicOverlay
 
 public struct UdSearchCallback {
-  public init(handle: @escaping (Result<[Data], NSError>) -> Void) {
+  public init(handle: @escaping (Result<[UDSearchResult], NSError>) -> Void) {
     self.handle = handle
   }
 
-  public var handle: (Result<[Data], NSError>) -> Void
+  public var handle: (Result<[UDSearchResult], NSError>) -> Void
 }
 
 extension UdSearchCallback {
@@ -29,7 +29,7 @@ extension UdSearchCallback {
           callback.handle(.failure(error as NSError))
         } else if let data = contactListJSON {
           do {
-            callback.handle(.success(try JSONDecoder().decode([Data].self, from: data)))
+            callback.handle(.success(try [UDSearchResult].decode(data)))
           } catch {
             callback.handle(.failure(error as NSError))
           }
-- 
GitLab


From a0437bc31910ad92c0369e0a36e1fc327efca619 Mon Sep 17 00:00:00 2001
From: Dariusz Rybicki <dariusz@elixxir.io>
Date: Wed, 24 Aug 2022 18:37:58 +0100
Subject: [PATCH 3/3] Convert big ints in UdSearchResult JSON to strings

---
 Sources/XXClient/Models/UDSearchResult.swift  | 21 +++++++++++++--
 .../Models/UDSearchResultTests.swift          | 26 +++++++++++++++++++
 2 files changed, 45 insertions(+), 2 deletions(-)

diff --git a/Sources/XXClient/Models/UDSearchResult.swift b/Sources/XXClient/Models/UDSearchResult.swift
index 26e6bf4d..84bdcccd 100644
--- a/Sources/XXClient/Models/UDSearchResult.swift
+++ b/Sources/XXClient/Models/UDSearchResult.swift
@@ -20,7 +20,8 @@ extension UDSearchResult: Codable {
   }
 
   public static func decode(_ data: Data) throws -> Self {
-    try JSONDecoder().decode(Self.self, from: data)
+    let data = convertBigIntsToStrings(jsonData: data)
+    return try JSONDecoder().decode(Self.self, from: data)
   }
 
   public func encode() throws -> Data {
@@ -30,10 +31,26 @@ extension UDSearchResult: Codable {
 
 extension Array where Element == UDSearchResult {
   public static func decode(_ data: Data) throws -> Self {
-    try JSONDecoder().decode(Self.self, from: data)
+    let data = convertBigIntsToStrings(jsonData: data)
+    return try JSONDecoder().decode(Self.self, from: data)
   }
 
   public func encode() throws -> Data {
     try JSONEncoder().encode(self)
   }
 }
+
+private func convertBigIntsToStrings(jsonData input: Data) -> Data {
+  guard var string = String(data: input, encoding: .utf8) else {
+    return input
+  }
+  string = string.replacingOccurrences(
+    of: #":\s*([0-9]{19,})\s*,"#,
+    with: #": "$1","#,
+    options: [.regularExpression]
+  )
+  guard let output = string.data(using: .utf8) else {
+    return input
+  }
+  return output
+}
diff --git a/Tests/XXClientTests/Models/UDSearchResultTests.swift b/Tests/XXClientTests/Models/UDSearchResultTests.swift
index 3037e773..1ac94da2 100644
--- a/Tests/XXClientTests/Models/UDSearchResultTests.swift
+++ b/Tests/XXClientTests/Models/UDSearchResultTests.swift
@@ -42,4 +42,30 @@ final class UDSearchResultTests: XCTestCase {
 
     XCTAssertNoDifference(decodedModels, models)
   }
+
+  func testEncodeWithBigInt() throws {
+    let idB64 = "pYIpRwPy+FnOkl5tndkG8RC93W/t5b1lszqPpMDynlUD"
+    let facts: [Fact] = [
+      Fact(fact: "carlos_arimateias", type: 0),
+    ]
+    let jsonString = """
+    {
+      "ID": "\(idB64)",
+      "DhPubKey": {
+        "Value": 1759426033802606996617132861414734059978289057332806031357800676138355264622676606691435603603751978195460163638145821347601916259127578968570412642641025630452893097179266022832268525346700655861033031712000288680395716922501450233258587788020541937373196899001184700899008948530359980753630443486308876999029238453979779103124291315202352475056237021681172884599194016245219278368648568458514708567045834427853469072638665888791358582182353417065794210125797368093469194927663862565508608719835557592421245749381164023134450699040591219966988201315627676532245052123725278573237006510683695959381015415110970848376498637637944431576313526294020390694483472829278364602405292767170719547347485307956614210210673321959886410245334772057212077704024337636501108566655549055129066343309591274727538343075929837698653965640646190405582788894021694347212874155979958144038307500444865955516612526623220973497735316081265793063949,
+        "Fingerprint": 15989433043166758754
+      },
+      "OwnershipProof": null,
+      "Facts": \(String(data: try! facts.encode(), encoding: .utf8)!)
+    }
+    """
+    let jsonData = jsonString.data(using: .utf8)!
+
+    let decodedModel = try UDSearchResult.decode(jsonData)
+
+    XCTAssertNoDifference(decodedModel, UDSearchResult(
+      id: Data(base64Encoded: idB64)!,
+      facts: facts
+    ))
+  }
 }
-- 
GitLab