Skip to content

Commit dea00b2

Browse files
fix: issues with interoperability with other sdks
Signed-off-by: goncalo-frade-iohk <[email protected]>
1 parent afca01b commit dea00b2

File tree

8 files changed

+312
-29
lines changed

8 files changed

+312
-29
lines changed

EdgeAgentSDK/Apollo/Sources/Model/Secp256k1Key.swift

-1
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,6 @@ struct Secp256k1PublicKey: PublicKey {
8888
self.keySpecifications = specs
8989
self.size = internalKey.raw.toData().count
9090
self.raw = internalKey.raw.toData()
91-
9291
}
9392

9493
init(x: Data, y: Data) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
import Foundation
2+
3+
struct AnyCodable {
4+
let value: Any
5+
6+
init<T: Codable>(_ value: T) {
7+
self.value = value
8+
}
9+
10+
init(_ value: Any) {
11+
self.value = value
12+
}
13+
14+
func get<T>() -> T? {
15+
value as? T
16+
}
17+
18+
func get() -> Any {
19+
value
20+
}
21+
}
22+
23+
extension AnyCodable: Codable {
24+
init(from decoder: Decoder) throws {
25+
let container = try decoder.singleValueContainer()
26+
27+
if container.decodeNil() {
28+
self.init(())
29+
} else if let bool = try? container.decode(Bool.self) {
30+
self.init(bool)
31+
} else if let int = try? container.decode(Int.self) {
32+
self.init(int)
33+
} else if let uint = try? container.decode(UInt.self) {
34+
self.init(uint)
35+
} else if let double = try? container.decode(Double.self) {
36+
self.init(double)
37+
} else if let string = try? container.decode(String.self) {
38+
self.init(string)
39+
} else if let array = try? container.decode([AnyCodable].self) {
40+
self.init(array.map { $0.value })
41+
} else if let dictionary = try? container.decode([String: AnyCodable].self) {
42+
self.init(dictionary.mapValues { $0.value })
43+
} else {
44+
throw DecodingError.dataCorruptedError(
45+
in: container,
46+
debugDescription: "Not a known JSON Primitive"
47+
)
48+
}
49+
}
50+
51+
func encode(to encoder: Encoder) throws {
52+
var container = encoder.singleValueContainer()
53+
54+
switch self.value {
55+
case is Void:
56+
try container.encodeNil()
57+
case let bool as Bool:
58+
try container.encode(bool)
59+
case let int as Int:
60+
try container.encode(int)
61+
case let int8 as Int8:
62+
try container.encode(int8)
63+
case let int16 as Int16:
64+
try container.encode(int16)
65+
case let int32 as Int32:
66+
try container.encode(int32)
67+
case let int64 as Int64:
68+
try container.encode(int64)
69+
case let uint as UInt:
70+
try container.encode(uint)
71+
case let uint8 as UInt8:
72+
try container.encode(uint8)
73+
case let uint16 as UInt16:
74+
try container.encode(uint16)
75+
case let uint32 as UInt32:
76+
try container.encode(uint32)
77+
case let uint64 as UInt64:
78+
try container.encode(uint64)
79+
case let float as Float:
80+
try container.encode(float)
81+
case let double as Double:
82+
try container.encode(double)
83+
case let string as String:
84+
try container.encode(string)
85+
case let date as Date:
86+
try container.encode(date)
87+
case let url as URL:
88+
try container.encode(url)
89+
case let array as [Any]:
90+
try container.encode(array.map { AnyCodable($0) })
91+
case let dictionary as [String: Any]:
92+
try container.encode(dictionary.mapValues { AnyCodable($0) })
93+
default:
94+
let context = EncodingError.Context(
95+
codingPath: container.codingPath,
96+
debugDescription: "Value is not codable"
97+
)
98+
throw EncodingError.invalidValue(self.value, context)
99+
}
100+
}
101+
}
102+
103+
extension AnyCodable: Equatable {
104+
static func ==(lhs: AnyCodable, rhs: AnyCodable) -> Bool {
105+
switch (lhs.value, rhs.value) {
106+
case is (Void, Void):
107+
return true
108+
case let (lhs as Bool, rhs as Bool):
109+
return lhs == rhs
110+
case let (lhs as Int, rhs as Int):
111+
return lhs == rhs
112+
case let (lhs as Int8, rhs as Int8):
113+
return lhs == rhs
114+
case let (lhs as Int16, rhs as Int16):
115+
return lhs == rhs
116+
case let (lhs as Int32, rhs as Int32):
117+
return lhs == rhs
118+
case let (lhs as Int64, rhs as Int64):
119+
return lhs == rhs
120+
case let (lhs as UInt, rhs as UInt):
121+
return lhs == rhs
122+
case let (lhs as UInt8, rhs as UInt8):
123+
return lhs == rhs
124+
case let (lhs as UInt16, rhs as UInt16):
125+
return lhs == rhs
126+
case let (lhs as UInt32, rhs as UInt32):
127+
return lhs == rhs
128+
case let (lhs as UInt64, rhs as UInt64):
129+
return lhs == rhs
130+
case let (lhs as Float, rhs as Float):
131+
return lhs == rhs
132+
case let (lhs as Double, rhs as Double):
133+
return lhs == rhs
134+
case let (lhs as String, rhs as String):
135+
return lhs == rhs
136+
case (let lhs as [String: AnyCodable], let rhs as [String: AnyCodable]):
137+
return lhs == rhs
138+
case (let lhs as [AnyCodable], let rhs as [AnyCodable]):
139+
return lhs == rhs
140+
default:
141+
return false
142+
}
143+
}
144+
}
145+
146+
extension AnyCodable: CustomStringConvertible {
147+
var description: String {
148+
switch value {
149+
case is Void:
150+
return String(describing: nil as Any?)
151+
case let value as CustomStringConvertible:
152+
return value.description
153+
default:
154+
return String(describing: value)
155+
}
156+
}
157+
}
158+
159+
extension AnyCodable: CustomDebugStringConvertible {
160+
var debugDescription: String {
161+
switch value {
162+
case let value as CustomDebugStringConvertible:
163+
return "AnyCodable(\(value.debugDescription))"
164+
default:
165+
return "AnyCodable(\(self.description))"
166+
}
167+
}
168+
}
169+
170+
extension AnyCodable: ExpressibleByNilLiteral, ExpressibleByBooleanLiteral, ExpressibleByIntegerLiteral, ExpressibleByFloatLiteral, ExpressibleByStringLiteral, ExpressibleByArrayLiteral, ExpressibleByDictionaryLiteral {
171+
172+
init(nilLiteral: ()) {
173+
self.init(nil ?? ())
174+
}
175+
176+
init(booleanLiteral value: Bool) {
177+
self.init(value)
178+
}
179+
180+
init(integerLiteral value: Int) {
181+
self.init(value)
182+
}
183+
184+
init(floatLiteral value: Double) {
185+
self.init(value)
186+
}
187+
188+
init(extendedGraphemeClusterLiteral value: String) {
189+
self.init(value)
190+
}
191+
192+
init(stringLiteral value: String) {
193+
self.init(value)
194+
}
195+
196+
init(arrayLiteral elements: Any...) {
197+
self.init(elements)
198+
}
199+
200+
init(dictionaryLiteral elements: (AnyHashable, Any)...) {
201+
self.init(Dictionary<AnyHashable, Any>(elements, uniquingKeysWith: { (first, _) in first }))
202+
}
203+
}

EdgeAgentSDK/Domain/Sources/Models/Message+Codable.swift

+17-2
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,11 @@ extension Message: Codable {
2222
var container = encoder.container(keyedBy: CodingKeys.self)
2323
try container.encode(id, forKey: .id)
2424
try container.encode(piuri, forKey: .piuri)
25-
try container.encode(body, forKey: .body)
25+
if let dic = try? JSONSerialization.jsonObject(with: body) as? [String: Any] {
26+
try container.encode(AnyCodable(dic), forKey: .body)
27+
} else {
28+
try container.encode(body, forKey: .body)
29+
}
2630
try container.encode(extraHeaders, forKey: .extraHeaders)
2731
try container.encode(createdTime, forKey: .createdTime)
2832
try container.encode(expiresTimePlus, forKey: .expiresTimePlus)
@@ -40,7 +44,18 @@ extension Message: Codable {
4044
let container = try decoder.container(keyedBy: CodingKeys.self)
4145
let id = try container.decode(String.self, forKey: .id)
4246
let piuri = try container.decode(String.self, forKey: .piuri)
43-
let body = try container.decodeIfPresent(Data.self, forKey: .body)
47+
let body: Data?
48+
if
49+
let bodyCodable = try? container.decodeIfPresent(AnyCodable.self, forKey: .body),
50+
(bodyCodable.value is [String: Any] || bodyCodable.value is [String]),
51+
let bodyData = try? JSONSerialization.data(withJSONObject: bodyCodable.value)
52+
{
53+
body = bodyData
54+
} else if let bodyData = try? container.decodeIfPresent(Data.self, forKey: .body) {
55+
body = bodyData
56+
} else {
57+
body = nil
58+
}
4459
let extraHeaders = try container.decodeIfPresent([String: String].self, forKey: .extraHeaders)
4560
let createdTime = try container.decodeIfPresent(Date.self, forKey: .createdTime)
4661
let expiresTimePlus = try container.decodeIfPresent(Date.self, forKey: .expiresTimePlus)

EdgeAgentSDK/EdgeAgent/Sources/EdgeAgent+Backup.swift

+22-16
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ extension EdgeAgent {
99
struct Key: Codable {
1010
let key: String
1111
let did: String?
12-
let recoveryType: String
12+
let index: Int?
13+
let recoveryId: String?
1314
}
1415

1516
struct Credential: Codable {
@@ -19,7 +20,7 @@ extension EdgeAgent {
1920

2021
struct Pair: Codable {
2122
let holder: String
22-
let receiver: String
23+
let recipient: String
2324
let alias: String?
2425
}
2526

@@ -144,7 +145,8 @@ extension EdgeAgent {
144145
return Backup.Key(
145146
key: keyStr,
146147
did: did.did.string,
147-
recoveryType: key.restorationIdentifier
148+
index: key.index,
149+
recoveryId: key.restorationIdentifier
148150
)
149151
}
150152
}.flatMap { $0 }
@@ -159,7 +161,8 @@ extension EdgeAgent {
159161
return Backup.Key(
160162
key: keyStr,
161163
did: nil,
162-
recoveryType: key.restorationIdentifier
164+
index: key.index,
165+
recoveryId: key.restorationIdentifier
163166
)
164167
}
165168
return backupKeys + backupDIDKeys
@@ -168,15 +171,18 @@ extension EdgeAgent {
168171
func recoverDidsWithKeys(dids: [Backup.DIDs], keys: [Backup.Key]) async throws {
169172
try await dids.asyncForEach { [weak self] did in
170173
let storableKeys = try await keys
171-
.filter { $0.did == did.did }
172-
.compactMap {
173-
return Data(base64URLEncoded: $0.key)
174+
.filter {
175+
let didurl = $0.did.flatMap { try? DIDUrl(string: $0) }?.did.string
176+
return didurl == did.did
177+
}
178+
.compactMap { key in
179+
return Data(base64URLEncoded: key.key).map { ($0, key.index) }
174180
}
175181
.asyncCompactMap {
176182
guard let self else {
177183
throw UnknownError.somethingWentWrongError(customMessage: nil, underlyingErrors: nil)
178184
}
179-
return try await jwkToKey(key: $0, restoration: self.apollo)
185+
return try await jwkToKey(key: $0, restoration: self.apollo, index: $1)
180186
}
181187

182188
try await self?.pluto.storeDID(
@@ -193,7 +199,7 @@ extension EdgeAgent {
193199
try await pairs.asyncForEach { [weak self] in
194200
try await self?.pluto.storeDIDPair(pair: .init(
195201
holder: DID(string: $0.holder),
196-
other: DID(string: $0.receiver),
202+
other: DID(string: $0.recipient),
197203
name: $0.alias
198204
))
199205
.first()
@@ -202,13 +208,13 @@ extension EdgeAgent {
202208
}
203209

204210
func recoverMessages(messages: [String]) async throws {
205-
let messages = messages.compactMap { messageStr -> (Message, Message.Direction)? in
211+
let messages = try messages.compactMap { messageStr -> (Message, Message.Direction)? in
206212
guard
207-
let messageData = Data(base64URLEncoded: messageStr),
208-
let message = try? JSONDecoder.didComm().decode(Message.self, from: messageData)
213+
let messageData = Data(base64URLEncoded: messageStr)
209214
else {
210215
return nil
211216
}
217+
let message = try JSONDecoder.didComm().decode(Message.self, from: messageData)
212218

213219
return (message, message.direction)
214220
}
@@ -228,7 +234,7 @@ extension EdgeAgent {
228234
else {
229235
return nil
230236
}
231-
return try? await pollux.importCredential(
237+
return try await pollux.importCredential(
232238
credentialData: data,
233239
restorationType: bakCredential.recoveryId,
234240
options: [
@@ -285,7 +291,7 @@ extension EdgeAgent {
285291
.first()
286292
.await()
287293
.map {
288-
Backup.Pair(holder: $0.holder.string, receiver: $0.other.string, alias: $0.name)
294+
Backup.Pair(holder: $0.holder.string, recipient: $0.other.string, alias: $0.name)
289295
}
290296
}
291297

@@ -350,8 +356,8 @@ private func keyToJWK(key: StorableKey, restoration: KeyRestoration) async throw
350356
return try JSONEncoder().encode(exportable.jwk).base64UrlEncodedString()
351357
}
352358

353-
private func jwkToKey(key: Data, restoration: KeyRestoration) async throws -> StorableKey? {
359+
private func jwkToKey(key: Data, restoration: KeyRestoration, index: Int?) async throws -> StorableKey? {
354360
let jwk = try JSONDecoder().decode(Domain.JWK.self, from: key)
355-
let key = try await restoration.restoreKey(jwk, index: nil)
361+
let key = try await restoration.restoreKey(jwk, index: index)
356362
return key.storable
357363
}

0 commit comments

Comments
 (0)