This guide is for iOS applications. Building for Android? Look here: Accept a W3C VC
Accept a Credential over OID4VCI
This page will not go over how OpenID for Verifiable Credential issuance works, but we do encourage you to read the specification. The example code below shows a particular profile of OID4VCI, which you are not necessarily required to implement, but does illustrate that you can i.e. generate a Proof of Possession with the SpruceKit Core Rust functionality.
// Import the SpruceID Mobile SDK
import SpruceIDMobileSdk
import SpruceIDMobileSdkRs
import SwiftUI
// The value for credentialOffer should be a compliant OID4VCI CredentialOffer
func getCredential(credentialOffer: String) {
// Instantiate an OID4VCI client
let client = Oid4vciAsyncHttpClient()
// Start a new OID4VCI session
let oid4vciSession = Oid4vci.newWithAsyncClient(client: client)
Task {
do {
try await oid4vciSession.initiateWithOffer(
credentialOffer: credentialOffer,
// Replace the clientId with your own
clientId: "skit-demo-wallet",
// Replace the redirectUrl with your own
redirectUrl: "https://spruceid.com"
)
let nonce = try await oid4vciSession.exchangeToken()
let metadata = try oid4vciSession.getMetadata()
// Create key material for the Proof of Possession (PoP)
_ = KeyManager.generateSigningKey(
id: "ExampleKeyID")
let jwk = KeyManager.getJwk(id: "ExampleKeyID")
//Prepare the Proof of Possession
let signingInput =
try await SpruceIDMobileSdkRs.generatePopPrepare(
audience: metadata.issuer(),
nonce: nonce,
didMethod: .jwk,
publicJwk: jwk!,
durationInSecs: nil
)
// Create a signature
let signature = KeyManager.signPayload(
id: "ExampleKeyID",
payload: [UInt8](signingInput))
// Finalize the PoP
let pop = try SpruceIDMobileSdkRs.generatePopComplete(
signingInput: signingInput,
signature: Data(Data(signature!).base64EncodedUrlSafe.utf8)
)
// Set your Json-LD context maps.
// This example uses a function that loads in VC Playground contexts.
try oid4vciSession.setContextMap(
values: getVCPlaygroundOID4VCIContext())
self.credentialPack = CredentialPack()
// Acquire Credentials
let credentials = try await oid4vciSession.exchangeCredential(
proofsOfPossession: [pop],
options: Oid4vciExchangeOptions(verifyAfterExchange: true)
)
// Add your credential to a CredentialPack
try credentials.forEach {
let cred = String(decoding: Data($0.payload), as: UTF8.self)
_ = try self.credentialPack?.addJsonVc(
jsonVc: JsonVc.newFromJson(utf8JsonString: cred))
self.credential = cred
}
} catch {
err = error.localizedDescription
print(error)
}
}
}
There is a lot of optionality in the OID4VCI protocol, and this code example only reflects one profile. Be sure to use the OID4VCI protocol in the way you want by studying the specification
Storing Credentials
There are multiple ways to store Credentials, but the most straight forward way is to use a CredentialPack. Even if you intend to store only a single credential in a CredentialPack, the component offers the most convenient API for interactions with other SpruceKit components.
// Store a Credential by adding your credential to a CredentialPack
let credentialPack = CredentialPack()
// Use the tryAddRawCredential API to store any supported credential format
_ = try credentialPack.tryAddRawCredential(rawCredential: rawCredential)
try credentialPack.save(storageManager: StorageManager())