Skip to content
This repository was archived by the owner on Oct 10, 2025. It is now read-only.

Commit 347be41

Browse files
authored
* Create P256 keypairs for dpop (#29)
* * Create P256 keypairs for dpop * Create jwt * code clean up * code clean up
1 parent 744d07a commit 347be41

File tree

5 files changed

+255
-79
lines changed

5 files changed

+255
-79
lines changed

Sources/MagicSDK/Core/Provider/RpcProvider.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ public class RpcProvider: NetworkClient, Web3Provider {
4949
let newRequest = RPCRequest(method: request.method, params: request.params)
5050

5151
// construct message data
52-
let eventMessage = RequestData(msgType: "\(msgType.rawValue)-\(urlBuilder.encodedParams)", payload: newRequest)
52+
let eventMessage = MagicRequestData(msgType: "\(msgType.rawValue)-\(urlBuilder.encodedParams)", payload: newRequest, rt: nil, jwt: createJwt())
5353

5454
// encode to JSON
5555
firstly {
@@ -66,7 +66,7 @@ public class RpcProvider: NetworkClient, Web3Provider {
6666

6767
// Decode JSON string into string
6868
do {
69-
let rpcResponse = try self.decoder.decode(ResponseData<RPCResponse<Result>>.self, from: jsonData)
69+
let rpcResponse = try self.decoder.decode(MagicResponseData<RPCResponse<Result>>.self, from: jsonData)
7070
let result = Web3Response<Result>(rpcResponse: rpcResponse.response)
7171
response(result)
7272
} catch {

Sources/MagicSDK/Core/Relayer/Types/BasicTypes.swift

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,17 @@ enum OutboundMessageType: String, CaseIterable {
2020
case MAGIC_HANDLE_REQUEST
2121
}
2222

23-
struct RequestData<T: Codable>: Codable {
23+
struct MagicRequestData<T: Codable>: Codable {
2424

2525
let msgType: String
2626
let payload: T
27+
let rt: String?
28+
let jwt: String?
2729
}
2830

29-
struct ResponseData<T: Codable>: Codable {
31+
struct MagicResponseData<T: Codable>: Codable {
3032

3133
let msgType: String
3234
let response: T
35+
let rt: String?
3336
}
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
//
2+
// File.swift
3+
//
4+
//
5+
// Created by Wentao Liu on 7/11/23.
6+
//
7+
8+
import Foundation
9+
import CryptoKit
10+
11+
12+
func base64UrlEncoded(_ data: Data) -> String {
13+
var b64 = data.base64EncodedString()
14+
b64 = b64.replacingOccurrences(of: "+", with: "-")
15+
b64 = b64.replacingOccurrences(of: "/", with: "_")
16+
b64 = b64.replacingOccurrences(of: "=", with: "")
17+
return b64
18+
}
19+
20+
func createJwt() -> String?{
21+
var error: Unmanaged<CFError>?
22+
23+
do {
24+
let privateKey = try retrieveKeyFromKeyChain()
25+
26+
// Get the public key.
27+
let publicKey = privateKey.publicKey
28+
29+
// Get the raw representation of the public key.
30+
let rawPublicKey = publicKey.rawRepresentation
31+
32+
// Extract the x and y coordinates.
33+
let xCoordinateData = rawPublicKey[1..<33]
34+
let yCoordinateData = rawPublicKey[33..<65]
35+
36+
// If you need base64-encoded strings for JWK:
37+
let xCoordinateBase64 = base64UrlEncoded(xCoordinateData)
38+
let yCoordinateBase64 = base64UrlEncoded(yCoordinateData)
39+
// Convert the public key to JWK format.
40+
// construct headers
41+
var headers: [String: Any] = ["typ": "dpop+jwt", "alg": "ES256"]
42+
headers["jwk"] = [
43+
"kty": "EC",
44+
"crv": "P-256",
45+
"x": xCoordinateBase64,
46+
"y": yCoordinateBase64
47+
] as [String : Any]
48+
49+
let headersData = try JSONSerialization.data(withJSONObject: headers)
50+
let headersB64 = base64UrlEncoded(headersData)
51+
52+
53+
// construct claims
54+
let iat = Int(Date().timeIntervalSince1970)
55+
let jti = UUID().uuidString.lowercased()
56+
57+
let claims: [String: Any] = ["iat": iat, "jti": jti]
58+
let claimsData = try JSONSerialization.data(withJSONObject: claims)
59+
let claimsB64 = base64UrlEncoded(claimsData)
60+
61+
/// sign
62+
let signingInput = headersB64 + "." + claimsB64
63+
let signingInputData = signingInput.data(using: .utf8)!
64+
65+
let signature = try! privateKey.signature(for: signingInputData)
66+
67+
let signatureB64 = base64UrlEncoded(signature.rawRepresentation)
68+
69+
let jwt = signingInput + "." + signatureB64
70+
71+
return jwt
72+
73+
} catch {
74+
// silently handled error
75+
return nil
76+
}
77+
78+
}
79+

0 commit comments

Comments
 (0)