Skip to content

Commit

Permalink
feat(pollux): add anoncreds issuance
Browse files Browse the repository at this point in the history
As didcomm swift repo has changed this also updates the breaking changes
  • Loading branch information
goncalo-frade-iohk committed Aug 28, 2023
1 parent dfe4697 commit f6e3540
Show file tree
Hide file tree
Showing 39 changed files with 791 additions and 303 deletions.
4 changes: 4 additions & 0 deletions AtalaPrismSDK/Apollo/Sources/ApolloImpl+Public.swift
Original file line number Diff line number Diff line change
Expand Up @@ -142,4 +142,8 @@ returns random mnemonics nerver returns invalid mnemonics
throw ApolloError.invalidKeyType(invalid: keyType, valid: ValidCryptographicTypes.allCases.map(\.rawValue))
}
}

public func createNewLinkSecret() -> String {
CreateLinkSecretOperation().create()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import AnoncredsSwift
import Foundation

struct CreateLinkSecretOperation {
func create() -> String {
Prover().createLinkSecret().getBigNumber()
}
}
15 changes: 2 additions & 13 deletions AtalaPrismSDK/Builders/Sources/PolluxBuilder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,10 @@ import Domain
import Pollux

public struct PolluxBuilder {
let apollo: Apollo
let castor: Castor

public init(
apollo: Apollo,
castor: Castor
) {
self.apollo = apollo
self.castor = castor
}
public init() {}

public func build() -> Pollux {
PolluxImpl(
apollo: apollo,
castor: castor
)
PolluxImpl()
}
}
2 changes: 2 additions & 0 deletions AtalaPrismSDK/Domain/Sources/BBs/Apollo.swift
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,6 @@ public protocol Apollo {
/// - Parameter compressedData: The compressed public key data
/// - Returns: The decompressed public key
func uncompressedPublicKey(compressedData: Data) -> PublicKey

func createNewLinkSecret() -> String
}
4 changes: 4 additions & 0 deletions AtalaPrismSDK/Domain/Sources/BBs/Pluto.swift
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ public protocol Pluto {
func storeCredential(
credential: StorableCredential
) -> AnyPublisher<Void, Error>

func storeLinkSecret(secret: String) -> AnyPublisher<Void, Error>

/// Returns all stored PRISM DIDs, along with their associated key pair indices and aliases (if any).
/// - Returns: A publisher that emits an array of tuples representing the stored PRISM DIDs, along with their associated key pair indices and aliases (if any).
Expand Down Expand Up @@ -214,4 +216,6 @@ public protocol Pluto {
/// Returns all stored verifiable credentials.
/// - Returns: A publisher that emits an array of stored verifiable credentials.
func getAllCredentials() -> AnyPublisher<[StorableCredential], Error>

func getLinkSecret() -> AnyPublisher<[String], Error>
}
12 changes: 8 additions & 4 deletions AtalaPrismSDK/Domain/Sources/BBs/Pollux.swift
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
import Combine
import Foundation

/// Options that can be passed into various operations.
public enum CredentialOperationsOptions {
case schema(json: Data) // The JSON schema.
case link_secret(id: String, secret: String) // A secret link.
case schema(id: String, json: String) // The JSON schema.
case schemasStream(stream: AnyPublisher<[(id: String, json: String)], Error>) // Stream of schemas, only the first batch is considered
case credentialDefinition(id: String, json: String) // The JSON Credential Definition
case credentialDefinitionsStream(stream: AnyPublisher<[(id: String, json: String)], Error>) // Stream of credential definitions, only the first batch is considered
case linkSecret(id: String, secret: String) // A secret link.
case subjectDID(DID) // The decentralized identifier of the subject.
case entropy(String) // Entropy for any randomization operation.
case signableKey(SignableKey) // A key that can be used for signing.
Expand All @@ -17,7 +21,7 @@ public protocol Pollux {
/// - Parameter data: The encoded item to parse.
/// - Throws: An error if the item cannot be parsed or decoded.
/// - Returns: An object representing the parsed item.
func parseCredential(data: Data) throws -> Credential
func parseCredential(issuedCredential: Message) throws -> Credential

/// Restores a previously stored item using the provided restoration identifier and data.
/// - Parameters:
Expand All @@ -36,7 +40,7 @@ public protocol Pollux {
func processCredentialRequest(
offerMessage: Message,
options: [CredentialOperationsOptions]
) throws -> String
) async throws -> String
}

public extension Pollux {
Expand Down
7 changes: 7 additions & 0 deletions AtalaPrismSDK/Domain/Sources/Models/Errors.swift
Original file line number Diff line number Diff line change
Expand Up @@ -648,6 +648,9 @@ public enum PolluxError: KnownPrismError {
/// An error case when the offer doesnt present enough information like Domain or Challenge
case offerDoesntProvideEnoughInformation

/// An error case when the issued credential message doesnt present enough information or unsupported attachment
case unsupportedIssuedMessage

/// An error case there is missing an `ExportableKey`
case requiresExportableKeyForOperation(operation: String)

Expand All @@ -666,6 +669,8 @@ public enum PolluxError: KnownPrismError {
return 55
case .requiresExportableKeyForOperation:
return 56
case .unsupportedIssuedMessage:
return 57
}
}

Expand All @@ -690,6 +695,8 @@ public enum PolluxError: KnownPrismError {
return "Offer provided doesnt have challenge or domain in the attachments, or there is no Json Attachment"
case .requiresExportableKeyForOperation(let operation):
return "Operation \(operation) requires an ExportableKey"
case .unsupportedIssuedMessage:
return "Issue message provided doesnt have a valid attachment"
}
}
}
Expand Down
7 changes: 7 additions & 0 deletions AtalaPrismSDK/Domain/Sources/Models/MessageAttachment.swift
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,13 @@ public struct AttachmentBase64: AttachmentData {
public init(base64: String) {
self.base64 = base64
}

public func decoded() throws -> Data {
guard let decode = Data(base64Encoded: base64) else {
throw CommonError.invalidCoding(message: "Could not decode base64 message attchment")
}
return decode
}
}

/// The `AttachmentLinkData` struct represents a DIDComm attachment containing a link to external data.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ extension DidDoc {
id: $0.id.string,
type: .jsonWebKey2020,
controller: $0.controller.string,
verificationMaterial: .jwk(value: jsonKeys)
verificationMaterial: .jwk(publicKeyJwk: jsonKeys)
)
}

Expand All @@ -93,9 +93,9 @@ extension DidDoc {
return service.serviceEndpoint.first.map {
Service(
id: service.id,
kind: .didCommMessaging(
serviceEndpoint: .didCommMessaging(
value: .init(
serviceEndpoint: $0.uri,
uri: $0.uri,
accept: $0.accept,
routingKeys: $0.routingKeys
)
Expand All @@ -106,17 +106,17 @@ extension DidDoc {
return service.serviceEndpoint.first.map {
Service(
id: service.id,
kind: .other(value: $0.uri)
serviceEndpoint: .other(value: $0.uri)
)
}
}
}
self.init(
did: did,
keyAgreements: keyAgreements,
authentications: authentications,
verificationMethods: verificationMethods,
services: services
id: did,
keyAgreement: keyAgreements,
authentication: authentications,
verificationMethod: verificationMethods,
service: services
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ extension DIDCommxSwift.Secret {

switch from.secretMaterial {
case let .jwk(value):
material = .jwk(value: value)
material = .jwk(privateKeyJwk: value)
}
self.init(
id: from.id,
Expand Down
3 changes: 0 additions & 3 deletions AtalaPrismSDK/Mercury/Sources/MercuryImpl.swift
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,3 @@ public struct MercuryImpl {
)
}
}

extension ExampleDidResolver: DidResolver {}
extension ExampleSecretsResolver: SecretsResolver {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import Combine
import Foundation

protocol LinkSecretProvider {
func getAll() -> AnyPublisher<[String], Error>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import Combine
import Foundation

protocol LinkSecretStore {
func addLinkSecret(_ linkSecret: String) -> AnyPublisher<Void, Error>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import Combine
import Foundation

extension CDLinkSecretDAO: LinkSecretProvider {
func getAll() -> AnyPublisher<[String], Error> {
fetchController(context: readContext)
.map { $0.map(\.secret) }
.eraseToAnyPublisher()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import Combine
import CoreData
import Domain

extension CDLinkSecretDAO: LinkSecretStore {
func addLinkSecret(_ linkSecret: String) -> AnyPublisher<Void, Error> {
updateOrCreate(linkSecret, context: writeContext) { cdobj, context in
cdobj.secret = linkSecret
}
.map { _ in }
.eraseToAnyPublisher()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import Combine
import CoreData

struct CDLinkSecretDAO: CoreDataDAO {
typealias CoreDataObject = CDLinkSecret
let readContext: NSManagedObjectContext
let writeContext: NSManagedObjectContext
let identifierKey: String? = "secret"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import CoreData
import Foundation

@objc(CDLinkSecret)
class CDLinkSecret: NSManagedObject {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import CoreData
import Foundation

extension CDLinkSecret {
@nonobjc class func fetchRequest() -> NSFetchRequest<CDLinkSecret> {
return NSFetchRequest<CDLinkSecret>(entityName: "CDLinkSecret")
}

@NSManaged var secret: String
}

extension CDLinkSecret: Identifiable {
var id: String { secret }
}
8 changes: 8 additions & 0 deletions AtalaPrismSDK/Pluto/Sources/PlutoImpl+Public.swift
Original file line number Diff line number Diff line change
Expand Up @@ -166,4 +166,12 @@ extension PlutoImpl: Pluto {
public func getAllCredentials() -> AnyPublisher<[StorableCredential], Error> {
credentialsDAO.getAll()
}

public func storeLinkSecret(secret: String) -> AnyPublisher<Void, Error> {
linkSecretDao.addLinkSecret(secret)
}

public func getLinkSecret() -> AnyPublisher<[String], Error> {
linkSecretDao.getAll()
}
}
5 changes: 5 additions & 0 deletions AtalaPrismSDK/Pluto/Sources/PlutoImpl.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ public struct PlutoImpl {
let messageDao: CDMessageDAO
let mediatorDAO: CDMediatorDIDDAO
let credentialsDAO: CDCredentialDAO
let linkSecretDao: CDLinkSecretDAO
private let coreDataManager: CoreDataManager
private let keyRestoration: KeyRestoration

Expand Down Expand Up @@ -64,5 +65,9 @@ public struct PlutoImpl {
readContext: manager.mainContext,
writeContext: manager.editContext
)
self.linkSecretDao = CDLinkSecretDAO(
readContext: manager.mainContext,
writeContext: manager.editContext
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@
<attribute name="privateKeyKeyAgreement" optional="YES" attributeType="Binary"/>
<relationship name="pair" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="CDDIDPair" inverseName="holderDID" inverseEntity="CDDIDPair"/>
</entity>
<entity name="CDLinkSecret" representedClassName="CDLinkSecret" syncable="YES">
<attribute name="secret" optional="YES" attributeType="String"/>
</entity>
<entity name="CDMediatorDID" representedClassName="CDMediatorDID" syncable="YES">
<attribute name="mediatorId" optional="YES" attributeType="String"/>
<relationship name="mediatorDID" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="CDDID"/>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import Domain
import Foundation
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import Domain
import Foundation

extension AnonCredential: StorableCredential {
var storingId: String {
id
}

var recoveryId: String {
"anon+credential"
}

var credentialData: Data {
(try? JSONEncoder().encode(self)) ?? Data()
}

var queryIssuer: String? {
issuer
}

var querySubject: String? {
subject
}

var queryCredentialCreated: Date? {
nil
}

var queryCredentialUpdated: Date? {
nil
}

var queryCredentialSchema: String? {
schemaId
}

var queryValidUntil: Date? {
nil
}

var queryRevoked: Bool? {
nil
// revocationRegistryId != nil
}

var queryAvailableClaims: [String] {
claims.map(\.key)
}
}
Loading

0 comments on commit f6e3540

Please sign in to comment.