Skip to content

Commit

Permalink
Merge pull request #58 from XYOracleNetwork/feature/meta-signatures
Browse files Browse the repository at this point in the history
Meta Signatures
  • Loading branch information
JoelBCarter authored Nov 26, 2024
2 parents d553470 + e8de3ee commit 0053fdd
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 22 deletions.
9 changes: 6 additions & 3 deletions Sources/XyoClient/BoundWitness/BoundWitness.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ public class BoundWitness: Payload, BoundWitnessBody, BoundWitnessMeta,

public var _hash: String? = nil

public var _signatures: [String]? = nil
public var signatures: [String]? = nil

public var addresses: [String] = []

Expand All @@ -29,8 +29,8 @@ public class BoundWitness: Payload, BoundWitnessBody, BoundWitnessMeta,
enum CodingKeys: String, CodingKey {
case _client
case _hash
case _signatures
case addresses
case meta = "$meta"
case payload_hashes
case payload_schemas
case previous_hashes
Expand All @@ -51,7 +51,10 @@ public class BoundWitness: Payload, BoundWitnessBody, BoundWitnessMeta,
func encodeMetaFields(_ container: inout KeyedEncodingContainer<CodingKeys>) throws {
try container.encodeIfPresent(_client, forKey: ._client)
try container.encodeIfPresent(_hash, forKey: ._hash)
try container.encodeIfPresent(_signatures, forKey: ._signatures)
let meta = [
"signatures": signatures
]
try container.encode(meta, forKey: .meta)
}

func encodeBodyFields(_ container: inout KeyedEncodingContainer<CodingKeys>) throws {
Expand Down
37 changes: 24 additions & 13 deletions Sources/XyoClient/BoundWitness/BoundWitnessBuilder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ public class BoundWitnessBuilder {
let bw = BoundWitness()
let hashable = hashableFields()
let hash = try BoundWitnessBuilder.hash(hashable)
bw._signatures = try self.sign(hash: hash)
bw.signatures = try self.sign(hash: hash)
bw._hash = hash
bw._client = "swift"
bw.addresses = _accounts.map { witness in witness.address }
Expand All @@ -83,20 +83,28 @@ public class BoundWitnessBuilder {
}
return (bw, _payloads)
}

private static func filterUnderscoreKeys(_ jsonObject: Any) -> Any {

private static func isDataField(_ key: String) -> Bool {
// Remove keys starting with "_"
return !key.hasPrefix("_")
// Remove keys starting with "$"
&& !key.hasPrefix("$")
}

private static func dataHashableFields(_ jsonObject: Any) -> Any {
if let dictionary = jsonObject as? [String: Any] {
// Process dictionaries: filter keys, sort, and recurse
let filteredDictionary = dictionary
.filter { !$0.key.hasPrefix("_") } // Remove keys starting with "_"
.sorted { $0.key < $1.key } // Sort keys lexicographically
let filteredDictionary =
dictionary
.filter { isDataField($0.key) } // Filter meta fields
.sorted { $0.key < $1.key } // Sort keys lexicographically
.reduce(into: [String: Any]()) { result, pair in
result[pair.key] = filterUnderscoreKeys(pair.value) // Recurse on values
result[pair.key] = dataHashableFields(pair.value) // Recurse on values
}
return filteredDictionary
} else if let array = jsonObject as? [Any] {
// Process arrays: recursively process each element
return array.map { filterUnderscoreKeys($0) }
return array.map { dataHashableFields($0) }
} else {
// Return primitives (String, Number, etc.)
return jsonObject
Expand All @@ -115,25 +123,28 @@ public class BoundWitnessBuilder {
return data.sha256().toHex()
}
}

// NOTE: Temporary fix until we have a custom JSON Serializer
// this method currently has issues with round tripping of floating
// point numbers as precision doesn't round trip
static private func hashWithoutUnderscores<T: Encodable>(_ json: T) throws -> String {

let encoder = JSONEncoder()
encoder.outputFormatting = .sortedKeys

// Encode the object to JSON data
let data = try encoder.encode(json)

// Decode the JSON into a dictionary, array, or primitive
guard let jsonObject = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] else {
guard
let jsonObject = try JSONSerialization.jsonObject(with: data, options: [])
as? [String: Any]
else {
throw BoundWitnessBuilderError.encodingError
}

// Recursively filter keys starting with "_"
let filteredJSON = filterUnderscoreKeys(jsonObject)
// Recursively filter keys that are data hashable
let filteredJSON = dataHashableFields(jsonObject)

// Encode the filtered JSON back to data
let filteredData = try JSONSerialization.data(
Expand Down
9 changes: 6 additions & 3 deletions Sources/XyoClient/BoundWitness/BoundWitnessJson.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ public class XyoBoundWitnessJson: BoundWitnessBodyJson, BoundWitnessMeta {
enum CodingKeys: String, CodingKey {
case _client
case _hash
case _signatures
case addresses
case meta = "$meta"
case payload_hashes
case payload_schemas
case previous_hashes
Expand All @@ -15,13 +15,16 @@ public class XyoBoundWitnessJson: BoundWitnessBodyJson, BoundWitnessMeta {

public var _client: String?
public var _hash: String?
public var _signatures: [String]?
public var signatures: [String]?
public var _query: String?

func encodeMetaFields(_ container: inout KeyedEncodingContainer<CodingKeys>) throws {
try container.encode(_client, forKey: ._client)
try container.encode(_hash, forKey: ._hash)
try container.encode(_signatures, forKey: ._signatures)
let meta = [
"signatures": signatures
]
try container.encode(meta, forKey: .meta)
}

func encodeBodyFields(_ container: inout KeyedEncodingContainer<CodingKeys>) throws {
Expand Down
4 changes: 1 addition & 3 deletions Sources/XyoClient/BoundWitness/Meta/BoundWitnessMeta.swift
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import Foundation

public protocol BoundWitnessMeta {
var _client: String? { get set }
var _hash: String? { get set }
var _signatures: [String]? { get set }
var signatures: [String]? { get set }
}

0 comments on commit 0053fdd

Please sign in to comment.