Skip to content

Commit 1d440a2

Browse files
authored
feat: async key exchange (#182)
* feat: async key exchange * update tests
1 parent dbbcba7 commit 1d440a2

File tree

6 files changed

+52
-38
lines changed

6 files changed

+52
-38
lines changed

Example/Tests/SocketClientTests.swift

+4-23
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ class SocketClientTests: XCTestCase {
111111
XCTAssertTrue(socketClient.deeplinkUrl.contains("metamask:/"))
112112
}
113113

114-
func testRequestAuthorisatio() {
114+
func testDeeplinkToMetaMask() {
115115
socketClient.useDeeplinks = true
116116

117117
let sessionId = "mockSessionId"
@@ -124,36 +124,17 @@ class SocketClientTests: XCTestCase {
124124
socketClient.requestAuthorisation()
125125

126126
let openedUrl = mockUrlOpener.openedURL?.absoluteString ?? ""
127+
let originatorInfoBase64 = socketClient.originatorInfo().originatorInfo.toJsonString()?.base64Encode() ?? ""
127128

128129
let expectedDeeplink = "metamask://connect?channelId="
129130
+ sessionId
130131
+ "&comm=socket"
131132
+ "&pubkey="
132133
+ pubkey
133134
+ "&v=2"
134-
XCTAssertEqual(openedUrl, expectedDeeplink)
135-
}
136-
137-
func testDeeplinkToMetaMask() {
138-
socketClient.useDeeplinks = true
139-
140-
let sessionId = "mockSessionId"
141-
let pubkey = "0x12345"
142-
143-
// force keyexchange = true
144-
mockKeyExchange.keysExchanged = true
145-
mockKeyExchange.pubkey = pubkey
146-
147-
socketClient.deeplinkToMetaMask()
135+
+ "&originatorInfo="
136+
+ originatorInfoBase64
148137

149-
let openedUrl = mockUrlOpener.openedURL?.absoluteString ?? ""
150-
151-
let expectedDeeplink = "metamask://connect?channelId="
152-
+ sessionId
153-
+ "&comm=socket"
154-
+ "&pubkey="
155-
+ pubkey
156-
+ "&v=2"
157138
XCTAssertEqual(openedUrl, expectedDeeplink)
158139
}
159140

Sources/metamask-ios-sdk/Classes/CommunicationLayer/SocketCommLayer/ClientEvent.swift

+4
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@ public struct ClientEvent {
1616
public static var message: String {
1717
"message"
1818
}
19+
20+
public static var terminate: String {
21+
"terminate"
22+
}
1923

2024
public static var joinChannel: String {
2125
"join_channel"

Sources/metamask-ios-sdk/Classes/CommunicationLayer/SocketCommLayer/SocketClient.swift

+31-3
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ public class SocketClient: CommClient {
4444
public var trackEvent: ((Event, [String: Any]) -> Void)?
4545

4646
var requestJobs: [RequestJob] = []
47+
48+
var connectRpc: String?
4749

4850
public var useDeeplinks: Bool = true
4951

@@ -52,12 +54,30 @@ public class SocketClient: CommClient {
5254
}
5355

5456
var deeplinkUrl: String {
55-
"\(_deeplinkUrl)/connect?channelId="
57+
let originatorInfo = OriginatorInfo(
58+
title: appMetadata?.name,
59+
url: appMetadata?.url,
60+
icon: appMetadata?.iconUrl ?? appMetadata?.base64Icon,
61+
dappId: SDKInfo.bundleIdentifier,
62+
platform: SDKInfo.platform,
63+
apiVersion: SDKInfo.version
64+
)
65+
let originatorInfoBase64 = originatorInfo.toJsonString()?.base64Encode() ?? ""
66+
let rpcBase64: String? = connectRpc?.base64Encode() ?? nil
67+
68+
var deeplink = "\(_deeplinkUrl)/connect?channelId="
5669
+ channelId
5770
+ "&comm=socket"
5871
+ "&pubkey="
5972
+ keyExchange.pubkey
6073
+ "&v=2"
74+
+ "&originatorInfo=\(originatorInfoBase64)"
75+
76+
if let requestBase64 = rpcBase64 {
77+
deeplink += "&rpc=\(requestBase64)"
78+
connectRpc = nil // reset rpc request
79+
}
80+
return deeplink
6181
}
6282

6383
private var isV2Protocol: Bool = false
@@ -90,6 +110,7 @@ public class SocketClient: CommClient {
90110

91111
public func connect(with request: String?) {
92112
if channel.isConnected { return }
113+
self.connectRpc = request
93114

94115
setupClient()
95116
if isReconnection {
@@ -112,6 +133,7 @@ public class SocketClient: CommClient {
112133
session.clear()
113134
disconnect()
114135
keyExchange.reset()
136+
channel.emit(ClientEvent.terminate, ["channelId": channelId,"clientType": "dapp"])
115137
}
116138

117139
private func initiateKeyExchange() {
@@ -201,11 +223,13 @@ extension SocketClient {
201223
channel.on(ClientEvent.config(on: channelId)) { [weak self] data in
202224
guard
203225
let self = self,
204-
let message = data.first as? [String: Bool],
205-
let persistence = message["persistence"]
226+
let message = data.first as? [String: Any],
227+
let persistence = message["persistence"] as? Bool,
228+
let walletKey = message["walletKey"] as? String
206229
else { return }
207230

208231
isV2Protocol = persistence
232+
keyExchange.setTheirPublicKey(walletKey)
209233

210234
if isV2Protocol {
211235
isReady = true
@@ -315,6 +339,7 @@ extension SocketClient {
315339
}
316340

317341
func handleMessage(_ msg: [String: Any]) {
342+
318343
if isKeyExchangeMessage(msg) {
319344
handleReceiveKeyExchange(msg)
320345
return
@@ -376,6 +401,9 @@ extension SocketClient {
376401
Logging.log("Received wallet info")
377402
isReady = true
378403
} else if let data = json["data"] as? [String: Any] {
404+
if let walletKey = data["walletKey"] as? String {
405+
keyExchange.setTheirPublicKey(walletKey)
406+
}
379407
handleResponse?(data)
380408
}
381409
}

Sources/metamask-ios-sdk/Classes/Crypto/KeyExchange.swift

+7-7
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,6 @@ public class KeyExchange {
144144
let publicKey = message.pubkey,
145145
!publicKey.isEmpty {
146146
setTheirPublicKey(publicKey)
147-
keysExchanged = true
148147

149148
if message.v == 2 {
150149
self.storage.save(string: privateKey, key: privateKeyStorageKey)
@@ -180,10 +179,12 @@ public class KeyExchange {
180179
}
181180

182181
public func setTheirPublicKey(_ publicKey: String?) {
183-
if let theirPubKey = publicKey {
184-
theirPublicKey = theirPubKey
185-
storage.save(string: theirPubKey, key: theirPubliKeyStorageKey)
186-
}
182+
guard let theirPubKey = publicKey else { return }
183+
184+
theirPublicKey = theirPubKey
185+
keysExchanged = true
186+
storage.save(string: theirPubKey, key: theirPubliKeyStorageKey)
187+
storage.save(string: privateKey, key: privateKeyStorageKey)
187188
}
188189

189190
public static func isHandshakeRestartMessage(_ message: [String: Any]) -> Bool {
@@ -234,11 +235,10 @@ public class KeyExchange {
234235
throw KeyExchangeError.keysNotExchanged
235236
}
236237

237-
let decryted = try encyption.decrypt(
238+
return try encyption.decrypt(
238239
message,
239240
privateKey: privateKey
240241
).trimEscapingChars()
241-
return decryted
242242
}
243243
}
244244

Sources/metamask-ios-sdk/Classes/Ethereum/Ethereum.swift

+5-4
Original file line numberDiff line numberDiff line change
@@ -207,18 +207,18 @@ public class Ethereum {
207207
params: [message]
208208
)
209209
connected = true
210+
211+
let requestJson = connectSignRequest.toJsonString() ?? ""
210212

211213
if commClient is SocketClient {
212-
commClient.connect(with: nil)
214+
commClient.connect(with: requestJson)
213215
return performRequest(connectSignRequest)
214216
}
215217

216218
let submittedRequest = SubmittedRequest(method: connectSignRequest.method)
217219
submittedRequests[connectSignRequest.id] = submittedRequest
218220
let publisher = submittedRequests[connectSignRequest.id]?.publisher
219221

220-
let requestJson = connectSignRequest.toJsonString() ?? ""
221-
222222
commClient.connect(with: requestJson)
223223

224224
return publisher
@@ -238,7 +238,6 @@ public class Ethereum {
238238

239239
switch transport {
240240
case .socket:
241-
commClient.connect(with: nil)
242241

243242
// React Native SDK has request params as Data
244243
if let paramsData = req.params as? Data {
@@ -255,8 +254,10 @@ public class Ethereum {
255254
method: connectWithRequest.method,
256255
params: connectWithParams
257256
)
257+
commClient.connect(with: connectRequest.toJsonString())
258258
return performRequest(connectRequest)
259259
} else {
260+
commClient.connect(with: connectWithRequest.toJsonString())
260261
return performRequest(connectWithRequest)
261262
}
262263
case .deeplinking:

Sources/metamask-ios-sdk/Classes/Models/OriginatorInfo.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
import Foundation
77

8-
public struct OriginatorInfo: CodableData {
8+
public struct OriginatorInfo: CodableData, Mappable {
99
public let title: String?
1010
public let url: String?
1111
public let icon: String?

0 commit comments

Comments
 (0)