diff --git a/Example/Tests/Tests.swift b/Example/Tests/Tests.swift index 370a541..c30e128 100644 --- a/Example/Tests/Tests.swift +++ b/Example/Tests/Tests.swift @@ -48,8 +48,8 @@ class Tests: XCTestCase { // Test VerfiableCredential,VerifiablePresentation sign/verify func testVcVp() { do { - let currentDate = Date.init(timeIntervalSince1970: 1565941504) - let expireDate = Date.init(timeIntervalSince1970: 1568533504) + let currentDate = Date() + let expireDate = Date() + 60*60 // Make vc let vc = try VerifiableCredential.init() @@ -66,12 +66,8 @@ class Tests: XCTestCase { print("publickey = "+hexString(data: publicKey)) // Signing vc - let verifiableSigner = VerifiableSignVerifier.init() let signer = ECDSASigner.init(privateKey: privateKey) - guard let signedVC = try verifiableSigner.sign(verifiable: vc, algorithm: .ES256K, kid: "did:meta:387834#ManagementKey#89349348", nonce: "nonce", signer: signer) else { - XCTAssert(false) - return - } + let signedVC = try vc.sign(kid: "did:meta:387834#ManagementKey#89349348", nonce: "nonce", signer: signer) // serialize signed vc let serializedVC = try signedVC.serialize() @@ -79,7 +75,15 @@ class Tests: XCTestCase { // verify serialized vc let verifier = ECDSAVerifier.init(publicKey: publicKey) - guard let verifiedVC = try verifiableSigner.verify(serializedVerifiable: serializedVC, verifier: verifier) as! VerifiableCredential? else { + let jws = try JWSObject.init(string: serializedVC) + guard try jws.verify(verifier: verifier) else { + XCTAssert(false) + return + } + + let verifiedVC = try VerifiableCredential.init(jws: jws) + // Check expiration + if verifiedVC.expirationDate != nil && verifiedVC.expirationDate! < Date() { XCTAssert(false) return } @@ -91,7 +95,10 @@ class Tests: XCTestCase { XCTAssertEqual(verifiedVC.expirationDate, vc.expirationDate) XCTAssertEqual((verifiedVC.credentialSubject as! [String: Any])["id"] as? String, (vc.credentialSubject as! [String: Any])["id"] as? String) XCTAssertEqual((verifiedVC.credentialSubject as! [String: Any])["name"] as? String, (vc.credentialSubject as! [String: Any])["name"] as? String) - + // check issuanceDate + let vcJWT = try JWT.init(jsonData: jws.payload) + XCTAssertEqual(vcJWT.notBeforeTime, vc.issuanceDate) + // Make VP let vp = try VerifiablePresentation.init() @@ -107,22 +114,34 @@ class Tests: XCTestCase { XCTAssertEqual(serializedVC, vp.verifiableCredentials()![0] as! String) XCTAssertEqual(serializedVC, vp.verifiableCredentials()![1] as! String) + // Add expiration date + let jwt = JWT.init() + jwt.expirationTime = expireDate + jwt.notBeforeTime = currentDate + // Sign vc - guard let signedVP = try verifiableSigner.sign(verifiable: vp, algorithm: .ES256K, kid: "did:meta:43894835", nonce: "vp nonce", signer: signer) else { - XCTAssert(false) - return - } + let signedVP = try vp.sign(kid: "did:meta:43894835", nonce: "vp nonce", signer: signer, baseClaims: jwt) // Serialize signed vp let vpString = try signedVP.serialize() print("vp = "+vpString) // Verify serialized vp - guard let verifiedVp = try verifiableSigner.verify(serializedVerifiable: vpString, verifier: verifier) as? VerifiablePresentation else { + let vpJws = try JWSObject.init(string: vpString) + guard try vpJws.verify(verifier: verifier) else { + XCTAssert(false) + return + } + // Check expiration + let vpJwt = try JWT.init(jsonData: vpJws.payload) + if vpJwt.expirationTime != nil && vpJwt.expirationTime! < Date() { XCTAssert(false) return } + XCTAssertEqual(UInt64(currentDate.timeIntervalSince1970), UInt64(vpJwt.notBeforeTime!.timeIntervalSince1970)) + XCTAssertEqual(UInt64(expireDate.timeIntervalSince1970), UInt64(vpJwt.expirationTime!.timeIntervalSince1970)) + let verifiedVp = try VerifiablePresentation.init(jws: vpJws) XCTAssertEqual(verifiedVp.id, vp.id) XCTAssertEqual(verifiedVp.holder, vp.holder) XCTAssertEqual(verifiedVp.verifiableCredentials()![0] as? String, vp.verifiableCredentials()![0] as? String) @@ -130,12 +149,12 @@ class Tests: XCTestCase { // Verify vc in vp for svc in verifiedVp.verifiableCredentials()! { - guard let _ = try verifiableSigner.verify(serializedVerifiable: svc as! String, verifier: verifier) else { + let vcJws = try JWSObject.init(string: svc as! String) + guard try vcJws.verify(verifier: verifier) else { XCTAssert(false) - continue + return } } - } catch { print(error.localizedDescription) @@ -148,15 +167,15 @@ class Tests: XCTestCase { let vcString = "eyJraWQiOiJkaWQ6bWV0YTowMDAwMDM0ODkzODQ5MzI4NTk0MjAjS2V5TWFuYWdlbWVudCM3Mzg3NTg5MjQ3NSIsInR5cCI6IkpXVCIsImFsZyI6IkVTMjU2SyJ9.eyJzdWIiOiJkaWQ6bWV0YToweDExMTExMTExMTIwIiwiaXNzIjoiZGlkOm1ldGE6MHgzNDg5Mzg0OTMyODU5NDIwIiwiZXhwIjoxNTc0OTExNTk4LCJpYXQiOjE1NjYyNzE1OTgsIm5vbmNlIjoiMGQ4bWYwMyIsInZjIjp7IkBjb250ZXh0IjpbImh0dHBzOlwvXC93M2lkLm9yZ1wvY3JlZGVudGlhbHNcL3YxIl0sInR5cGUiOlsiVmVyaWZpYWJsZUNyZWRlbnRpYWwiLCJOYW1lQ3JlZGVudGlhbCJdLCJjcmVkZW50aWFsU3ViamVjdCI6eyJuYW1lIjoibWFuc3VkIn19LCJqdGkiOiJodHRwOlwvXC9hYS5tZXRhZGl1bS5jb21cL2NyZWRlbnRpYWxcLzM0MyJ9.A9x_gdqPMG3hqzP7yPqouqz4y-HIx4wVjOSGh4oXxufkyQjvQD3uDDmviNv7Xk7F3GXxGg_1hu-nL4cAirjLvA" let publicKey = hexadecimal(hexString:"043696d164c46a63ff57498e3e0e6a3d698a2c4f130ea174afd0cfb38b92991e6286c2c3587efac3b9e3cf7e7d5f5af5a048de557d5e976d38e829545b549bcebe") + // Verify VC let verifier = ECDSAVerifier.init(publicKey: publicKey!) - let verifiableJwt = VerifiableSignVerifier.init() - - let vc = try verifiableJwt.verify(serializedVerifiable: vcString, verifier: verifier) as? VerifiableCredential - if vc == nil { + let vcJws = try JWSObject.init(string: vcString) + guard try vcJws.verify(verifier: verifier) else { XCTAssert(false) - return; + return } - let vcJsonString = vc!.jsonString() + let vc = try VerifiableCredential.init(jws: vcJws) + let vcJsonString = vc.jsonString() print("vc = "+vcJsonString!) } @@ -176,15 +195,23 @@ class Tests: XCTestCase { } let vp = "eyJraWQiOiJkaWQ6bWV0YToweDM0ODkzODQ5MzI4NTk0MjAjTWFuYWdlbWVudEtleSM0MzgyNzU4Mjk1IiwidHlwIjoiSldUIiwiYWxnIjoiRVMyNTZLIn0.eyJpc3MiOiJkaWQ6bWV0YToweDM0ODkzODQ5MzI4NTk0MjAiLCJ2cCI6eyJAY29udGV4dCI6WyJodHRwczpcL1wvdzNpZC5vcmdcL2NyZWRlbnRpYWxzXC92MSJdLCJ0eXBlIjpbIlZlcmlmaWFibGVQcmVzZW50YXRpb24iLCJUZXN0UHJlc2VudGF0aW9uIl0sInZlcmlmaWFibGVDcmVkZW50aWFsIjpbImV5SnJhV1FpT2lKa2FXUTZiV1YwWVRvd01EQXdNRE0wT0Rrek9EUTVNekk0TlRrME1qQWpTMlY1VFdGdVlXZGxiV1Z1ZENNM016ZzNOVGc1TWpRM05TSXNJblI1Y0NJNklrcFhWQ0lzSW1Gc1p5STZJa1ZUTWpVMlN5SjkuZXlKemRXSWlPaUprYVdRNmJXVjBZVG93ZURFeE1URXhNVEV4TVRJd0lpd2lhWE56SWpvaVpHbGtPbTFsZEdFNk1IZ3pORGc1TXpnME9UTXlPRFU1TkRJd0lpd2laWGh3SWpveE5UYzBPVE13TnpNMkxDSnBZWFFpT2pFMU5qWXlPVEEzTXpZc0ltNXZibU5sSWpvaU1HUTRiV1l3TXlJc0luWmpJanA3SWtCamIyNTBaWGgwSWpwYkltaDBkSEJ6T2x3dlhDOTNNMmxrTG05eVoxd3ZZM0psWkdWdWRHbGhiSE5jTDNZeElsMHNJblI1Y0dVaU9sc2lWbVZ5YVdacFlXSnNaVU55WldSbGJuUnBZV3dpTENKT1lXMWxRM0psWkdWdWRHbGhiQ0pkTENKamNtVmtaVzUwYVdGc1UzVmlhbVZqZENJNmV5SnVZVzFsSWpvaWJXRnVjM1ZrSW4xOUxDSnFkR2tpT2lKb2RIUndPbHd2WEM5aFlTNXRaWFJoWkdsMWJTNWpiMjFjTDJOeVpXUmxiblJwWVd4Y0x6TTBNeUo5Lnh2UzJzWk11SXJJZ0g3Rm1DYVVmbk51V3hUeW9YeFJUTFpwdjZNU0toNUxFUFV4M190RnZhOVVtZ2JrQ2xqQzctUloxY2NVUnpfRjJfeGM3UXBrdUZnIiwiZXlKcmFXUWlPaUprYVdRNmJXVjBZVG93TURBd01ETTBPRGt6T0RRNU16STROVGswTWpBalMyVjVUV0Z1WVdkbGJXVnVkQ00zTXpnM05UZzVNalEzTlNJc0luUjVjQ0k2SWtwWFZDSXNJbUZzWnlJNklrVlRNalUyU3lKOS5leUp6ZFdJaU9pSmthV1E2YldWMFlUb3dlREV4TVRFeE1URXhNVEl3SWl3aWFYTnpJam9pWkdsa09tMWxkR0U2TUhnek5EZzVNemcwT1RNeU9EVTVOREl3SWl3aVpYaHdJam94TlRjME9UTXdOelUzTENKcFlYUWlPakUxTmpZeU9UQTNOVGNzSW01dmJtTmxJam9pTUdRNGJXWXdNeUlzSW5aaklqcDdJa0JqYjI1MFpYaDBJanBiSW1oMGRIQnpPbHd2WEM5M00ybGtMbTl5WjF3dlkzSmxaR1Z1ZEdsaGJITmNMM1l4SWwwc0luUjVjR1VpT2xzaVZtVnlhV1pwWVdKc1pVTnlaV1JsYm5ScFlXd2lMQ0pPWVcxbFEzSmxaR1Z1ZEdsaGJDSmRMQ0pqY21Wa1pXNTBhV0ZzVTNWaWFtVmpkQ0k2ZXlKdVlXMWxJam9pYldGdWMzVmtJbjE5TENKcWRHa2lPaUpvZEhSd09sd3ZYQzloWVM1dFpYUmhaR2wxYlM1amIyMWNMMk55WldSbGJuUnBZV3hjTHpNME15SjkuSmtsU1hNMkJvT25kOTN0d3B5WEpuZkpZUmI4Vm1NU1FMNWtkNWNDS0RWdWYxdjNtU2NOeUQwRVhuZ25GX3pRT1dlVjItS2V3VHBQeURXcmhxUmwxTHciXX0sIm5vbmNlIjoiMGQ4bWYwMyIsImp0aSI6Imh0dHA6XC9cL2FhLm1ldGFkaXVtLmNvbVwvcHJlc2VudGF0aW9uXC8zNDMifQ.FW_nEPTRg18D2zaX3ACh1atqlJ1alPMGmNzalmUdloo_bG-DevmkcpMm5yPoKB0uaL_oQLYHb6xvFNNwCRSXig" + // Verify VP let verifier = ECDSAVerifier.init(publicKey: publicKey) + let vpJws = try JWSObject.init(string: vp) + guard try vpJws.verify(verifier: verifier) else { + XCTAssert(false) + return + } - let verifiableJwt = VerifiableSignVerifier.init() - - guard let verifiedVP = try verifiableJwt.verify(serializedVerifiable: vp, verifier: verifier) as! VerifiablePresentation? else { + // Check expiration of VP + let vpJwt = try JWT.init(jsonData: vpJws.payload) + if vpJwt.expirationTime != nil && vpJwt.expirationTime! < Date() { XCTAssert(false) return } + let verifiedVP = try VerifiablePresentation.init(jws: vpJws) + guard let vcList = verifiedVP.verifiableCredentials() else { XCTAssert(false) return @@ -192,13 +219,15 @@ class Tests: XCTestCase { XCTAssertEqual(vcList.count, 2) let verifier1 = ECDSAVerifier.init(publicKey: vc1PublciKey) - guard let _ = try verifiableJwt.verify(serializedVerifiable: vcList[0] as! String, verifier: verifier1) as! VerifiableCredential? else { + let vcJws1 = try JWSObject.init(string: vcList[0] as! String) + guard try vcJws1.verify(verifier: verifier1) else { XCTAssert(false) return } let verifier2 = ECDSAVerifier.init(publicKey: vc2PublicKey) - guard let _ = try verifiableJwt.verify(serializedVerifiable: vcList[1] as! String, verifier: verifier2) as! VerifiableCredential? else { + let vcJws2 = try JWSObject.init(string: vcList[1] as! String) + guard try vcJws2.verify(verifier: verifier2) else { XCTAssert(false) return } diff --git a/VerifiableSwift.podspec b/VerifiableSwift.podspec index 3dead07..1d37261 100644 --- a/VerifiableSwift.podspec +++ b/VerifiableSwift.podspec @@ -8,7 +8,7 @@ Pod::Spec.new do |s| s.name = 'VerifiableSwift' - s.version = '0.1.0' + s.version = '0.2.0' s.summary = 'Verifiable Credential and Presentation of Metadium.' # This description is used to generate tags and improve search results. diff --git a/VerifiableSwift/Classes/Verifiable.swift b/VerifiableSwift/Classes/Verifiable.swift index 153c3b8..5cd82ea 100644 --- a/VerifiableSwift/Classes/Verifiable.swift +++ b/VerifiableSwift/Classes/Verifiable.swift @@ -7,13 +7,24 @@ // import Foundation +import JWTsSwift +/// JWT 로 변환할 delegator +protocol VerifiableDelegator { + func toJWT(nonce: String?, claims: JWT?) throws -> JWT +} + /// Verifiable error /// /// - NullType: type is null. Need override func getType() +/// - InvalidCredential: invalid credentail +/// - InvalidCredential: invalid presentation enum VerifiableError: Error { case NullType + case InvalidCredential + case InvalidPresentation + case Unknown } @@ -23,6 +34,8 @@ public class Verifiable { /// verifiable data var jsonObject: [String: Any] + var delegator: VerifiableDelegator? + /// init /// @@ -135,4 +148,54 @@ public class Verifiable { public func getJson() -> [String: Any] { return jsonObject } + + + /// Sign credential or presentation + /// - Parameters: + /// - algorithm: signature algorithm + /// - kid: key id + /// - nonce: nonce + /// - signer: JWS signer + /// - baseClaims: base JWT claims. presentation 에 issuanceDate, expirationDate 추가사 사용 + /// - Throws: error to sign + /// - Returns: signed jws + public func sign(algorithm: SignatureAlgorithm, kid: String, nonce: String?, signer: JWSSigner, baseClaims: JWT?) throws -> JWSObject { + // To JWT + guard let jsonData = try delegator?.toJWT(nonce: nonce, claims: baseClaims).data() else { + throw VerifiableError.Unknown + } + + // Sign JWT + let header: JWSHeader = JWSHeader.init(algorithm: algorithm) + header.kid = kid + let jws:JWSObject = JWSObject.init(header: header, payload: jsonData) + try jws.sign(signer: signer) + + return jws + } + + + /// Sign credential or presentation. algorithm is ES256K + /// - Parameters: + /// - kid: key id + /// - nonce: nonce + /// - signer: JWS signer + /// - baseClaims: base JWT claims. presentation 에 issuanceDate, expirationDate 추가사 사용 + /// - Throws: error to sign + /// - Returns: signed jws + public func sign(kid: String, nonce: String?, signer: JWSSigner, baseClaims: JWT?) throws -> JWSObject { + return try sign(algorithm: .ES256K, kid: kid, nonce: nonce, signer: signer, baseClaims: baseClaims) + } + + /// Sign credential or presentation. . algorithm is ES256K + /// - Parameters: + /// - kid: key id + /// - nonce: nonce + /// - signer: JWS signer + /// - Throws: error to sign + /// - Returns: signed jws + public func sign(kid: String, nonce: String?, signer: JWSSigner) throws -> JWSObject { + return try sign(kid: kid, nonce: nonce, signer: signer, baseClaims: nil) + } + } diff --git a/VerifiableSwift/Classes/VerifiableCredential.swift b/VerifiableSwift/Classes/VerifiableCredential.swift index f0d12f3..1da8011 100644 --- a/VerifiableSwift/Classes/VerifiableCredential.swift +++ b/VerifiableSwift/Classes/VerifiableCredential.swift @@ -7,17 +7,16 @@ // import Foundation - +import JWTsSwift /// VerifiableCredential -public class VerifiableCredential : Verifiable { - - +public class VerifiableCredential : Verifiable, VerifiableDelegator { /// init /// /// - Throws: VerifiableError.NullType public override init() throws { try super.init() + super.delegator = self } @@ -27,6 +26,7 @@ public class VerifiableCredential : Verifiable { /// - Throws: VerifiableError.NullType public override init(json: String) throws { try super.init(json: json) + super.delegator = self } @@ -35,9 +35,48 @@ public class VerifiableCredential : Verifiable { /// - Parameter jsonObject: json dictionary public override init(jsonObject: [String: Any]) { super.init(jsonObject: jsonObject) + super.delegator = self } + /// Init with JWSObject + /// - Parameter jws: jws object of credentail + /// - Throws: VerifiableError.InvalidCredential + public convenience init(jws: JWSObject) throws { + try self.init() + + let jwt = try JWT.init(jsonData: jws.payload) + let id = jwt.jwtID + let expireDate = jwt.expirationTime + let issuer = jwt.issuer + let issuedTime = jwt.notBeforeTime + let subject = jwt.subject + guard let vcClaims: [String: Any] = jwt.claims["vc"] as? [String: Any] else { + throw VerifiableError.InvalidCredential + } + + self.jsonObject = vcClaims + if id != nil { + self.id = id + } + if expireDate != nil { + self.expirationDate = expireDate + } + if issuer != nil { + self.issuer = issuer?.absoluteString + } + if issuedTime != nil { + self.issuanceDate = issuedTime + } + if subject != nil { + if self.credentialSubject != nil && self.credentialSubject is [String: Any] { + var credentialSubject = self.credentialSubject as? [String: Any] + credentialSubject?["id"] = subject + self.credentialSubject = credentialSubject + } + } + } + /// Get Type. fixed "VerifiableCredential" /// /// - Returns: type @@ -101,6 +140,9 @@ public class VerifiableCredential : Verifiable { } } + public func getCredentialSubject() -> T? { + return credentialSubject as? T + } /// set credentialStatus /// @@ -153,4 +195,62 @@ public class VerifiableCredential : Verifiable { return nil; } } + + + /// VerifiableCredential to JWT + /// - Parameters: + /// - nonce: nonce + /// - claims: base JWT claims. + /// - Throws: + /// - Returns: JWT to formatting + func toJWT(nonce: String?, claims: JWT?) throws -> JWT { + let tmpData = try NSKeyedArchiver.archivedData(withRootObject: jsonObject, requiringSecureCoding: false) + var copiedDict = NSKeyedUnarchiver.unarchiveObject(with: tmpData) as! [String: Any] + + let jti: String? = id + let expireDate: Date? = expirationDate + let issuer = issuer + let issuedDate = issuanceDate + let credentialSubject = credentialSubject + var subject: String? = nil + if credentialSubject is [String: Any] { + let id = (credentialSubject as! [String: Any])["id"] as? String + if id != nil { + subject = id + var tmp: [String: Any] = copiedDict["credentialSubject"] as! [String: Any] + tmp.removeValue(forKey: "id") + copiedDict["credentialSubject"] = tmp + } + } + + let jwt = claims == nil ? JWT.init() : claims! + + if jti != nil { + copiedDict.removeValue(forKey: "id") + jwt.jwtID = jti! + } + if expireDate != nil { + copiedDict.removeValue(forKey: "expirationDate") + jwt.expirationTime = expireDate! + } + if issuer != nil { + copiedDict.removeValue(forKey: "issuer") + jwt.issuer = URL.init(string: issuer!) + } + if issuedDate != nil { + copiedDict.removeValue(forKey: "issuanceDate") + jwt.notBeforeTime = issuedDate! + } + if subject != nil { + jwt.subject = subject! + } + if nonce != nil { + jwt.claims["nonce"] = nonce + } + jwt.claims["vc"] = copiedDict + + + return jwt + } + } diff --git a/VerifiableSwift/Classes/VerifiablePresentation.swift b/VerifiableSwift/Classes/VerifiablePresentation.swift index dab0f1e..da92014 100644 --- a/VerifiableSwift/Classes/VerifiablePresentation.swift +++ b/VerifiableSwift/Classes/VerifiablePresentation.swift @@ -7,16 +7,18 @@ // import Foundation - +import JWTsSwift /// Verifiable Presentation -public class VerifiablePresentation : Verifiable { +public class VerifiablePresentation : Verifiable, VerifiableDelegator { + /// init /// /// - Throws: VerifiableError.NullType public override init() throws { try super.init() + super.delegator = self } @@ -26,6 +28,7 @@ public class VerifiablePresentation : Verifiable { /// - Throws: VerifiableError.NullType public override init(json: String) throws { try super.init(json: json) + super.delegator = self } /// init with json dictionary @@ -33,6 +36,31 @@ public class VerifiablePresentation : Verifiable { /// - Parameter jsonObject: json dictionary public override init(jsonObject: [String: Any]) { super.init(jsonObject: jsonObject) + super.delegator = self + } + + + /// Init with JWS object + /// - Parameter jws: JWS object of presentation + /// - Throws: VerifiableError.InvalidPresentation + public convenience init(jws: JWSObject) throws { + try self.init() + + let jwt = try JWT.init(jsonData: jws.payload) + let id = jwt.jwtID + let holder = jwt.issuer + guard let vpClaims: [String: Any] = jwt.claims["vp"] as? [String: Any] else { + throw VerifiableError.InvalidPresentation + } + + self.jsonObject = vpClaims + + if id != nil { + self.id = id + } + if holder != nil { + self.holder = holder?.absoluteString + } } /// Get Type. fixed "VerifiablePresentation" @@ -78,4 +106,36 @@ public class VerifiablePresentation : Verifiable { return jsonObject["holder"] as? String } } + + + /// Presentation to JWT + /// - Parameters: + /// - nonce: nonce + /// - claims: base claims + /// - Throws: + /// - Returns: JWT to formatting + func toJWT(nonce: String?, claims: JWT?) throws -> JWT { + let tmpData = try NSKeyedArchiver.archivedData(withRootObject: jsonObject, requiringSecureCoding: true) + var copiedDict = NSKeyedUnarchiver.unarchiveObject(with: tmpData) as! [String: Any] + + let jti = id + let holder = holder + + let jwt = claims == nil ? JWT.init() : claims! + if jti != nil { + copiedDict.removeValue(forKey: "id") + jwt.jwtID = jti! + } + if holder != nil { + copiedDict.removeValue(forKey: "holder") + jwt.issuer = URL.init(string: holder!) + } + if nonce != nil { + jwt.claims["nonce"] = nonce + } + jwt.claims["vp"] = copiedDict + + return jwt + } + } diff --git a/VerifiableSwift/Classes/VerifiableSignVerifier.swift b/VerifiableSwift/Classes/VerifiableSignVerifier.swift index c51ae70..bde4779 100644 --- a/VerifiableSwift/Classes/VerifiableSignVerifier.swift +++ b/VerifiableSwift/Classes/VerifiableSignVerifier.swift @@ -10,6 +10,7 @@ import Foundation import JWTsSwift /// Sign and verify Verifiable(Credential/Presentation) +@available(*, deprecated, message:"use Verifiable, VerifiableCredential, VerifiablePresentation instead") public class VerifiableSignVerifier { public init() {