-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Move vc-util here and reanme it to ic-verifiable-credentials
This copies over `vc-util` from the internet identity repository and renames it to `ic-verifiable-credentials`. The metadata is updated as well.
- Loading branch information
Frederik Rothenberger
committed
Jun 17, 2024
1 parent
c581fe7
commit a55d75b
Showing
8 changed files
with
1,799 additions
and
27 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
[package] | ||
name = "ic-verifiable-credentials" | ||
description = "Verifiable credentials issuing and verification for IC canisters." | ||
version = "0.1.0" | ||
keywords = ["internet-computer", "verifiable", "credentials", "icp", "dfinity"] | ||
categories = ["api-bindings", "data-structures", "no-std"] | ||
edition = "2021" | ||
|
||
[dependencies] | ||
# ic dependencies | ||
candid.workspace = true | ||
ic-certification.workspace = true | ||
canister_sig_util.workspace = true | ||
|
||
# vc dependencies | ||
ic-crypto-standalone-sig-verifier = { git = "https://github.com/dfinity/ic", rev = "e69bcc7b319cbb3ebc22ec55af35287741244db6" } | ||
ic-types = { git = "https://github.com/dfinity/ic", rev = "e69bcc7b319cbb3ebc22ec55af35287741244db6" } | ||
identity_core = { git = "https://github.com/dfinity/identity.rs.git", rev = "aa510ef7f441848d6c78058fe51ad4ad1d9bd5d8", default-features = false, features = ["ic-wasm"] } | ||
identity_credential = { git = "https://github.com/dfinity/identity.rs.git", rev = "aa510ef7f441848d6c78058fe51ad4ad1d9bd5d8", default-features = false , features = ["ic-wasm", "validator"] } | ||
identity_jose = { git = "https://github.com/dfinity/identity.rs.git", rev = "aa510ef7f441848d6c78058fe51ad4ad1d9bd5d8", default-features = false} | ||
|
||
# other dependencies | ||
serde.workspace = true | ||
serde_bytes.workspace = true | ||
serde_cbor.workspace = true | ||
serde_json = "1" | ||
sha2.workspace = true | ||
|
||
[dev-dependencies] | ||
assert_matches = "1.5" |
213 changes: 213 additions & 0 deletions
213
rust-packages/ic-verifiable-credentials/src/issuer_api.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,213 @@ | ||
use candid::{CandidType, Deserialize, Nat}; | ||
use serde_bytes::ByteBuf; | ||
use serde_json::{Number, Value}; | ||
use std::collections::HashMap; | ||
use std::fmt::{Display, Formatter}; | ||
|
||
/// API to be implemented by an issuer of verifiable credentials. | ||
/// (cf. https://github.com/dfinity/internet-identity/blob/main/docs/vc-spec.md) | ||
#[derive(Clone, Debug, CandidType, Deserialize, Eq, PartialEq)] | ||
pub struct SignedIdAlias { | ||
pub credential_jws: String, | ||
} | ||
|
||
#[derive(Clone, Debug, CandidType, Deserialize, Eq, PartialEq)] | ||
pub struct PrepareCredentialRequest { | ||
pub signed_id_alias: SignedIdAlias, | ||
pub credential_spec: CredentialSpec, | ||
} | ||
|
||
#[derive(Clone, Debug, CandidType, Deserialize, Eq, PartialEq)] | ||
pub enum IssueCredentialError { | ||
UnknownSubject(String), | ||
UnauthorizedSubject(String), | ||
InvalidIdAlias(String), | ||
SignatureNotFound(String), | ||
Internal(String), | ||
UnsupportedCredentialSpec(String), | ||
} | ||
|
||
#[derive(Clone, Debug, CandidType, Deserialize, Eq, PartialEq)] | ||
pub struct GetCredentialRequest { | ||
pub signed_id_alias: SignedIdAlias, | ||
pub credential_spec: CredentialSpec, | ||
pub prepared_context: Option<ByteBuf>, | ||
} | ||
|
||
#[derive(Clone, Debug, CandidType, Deserialize, Eq, PartialEq)] | ||
pub struct PreparedCredentialData { | ||
pub prepared_context: Option<ByteBuf>, | ||
} | ||
|
||
#[derive(Clone, Debug, CandidType, Deserialize, Eq, PartialEq)] | ||
pub struct IssuedCredentialData { | ||
pub vc_jws: String, | ||
} | ||
|
||
#[derive(Eq, PartialEq, Clone, Debug, CandidType, Deserialize)] | ||
pub enum ArgumentValue { | ||
String(String), | ||
Int(i32), | ||
} | ||
|
||
impl Display for ArgumentValue { | ||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { | ||
match &self { | ||
ArgumentValue::String(s) => write!(f, "'{}'", s), | ||
ArgumentValue::Int(i) => write!(f, "{}", i), | ||
} | ||
} | ||
} | ||
|
||
impl From<ArgumentValue> for Value { | ||
fn from(argument_value: ArgumentValue) -> Self { | ||
match argument_value { | ||
ArgumentValue::String(s) => Value::String(s), | ||
ArgumentValue::Int(i) => Value::Number(Number::from(i)), | ||
} | ||
} | ||
} | ||
|
||
impl PartialEq<serde_json::Value> for ArgumentValue { | ||
fn eq(&self, other: &Value) -> bool { | ||
match self { | ||
ArgumentValue::String(ls) => { | ||
if let Some(rs) = other.as_str() { | ||
ls.eq(rs) | ||
} else { | ||
false | ||
} | ||
} | ||
ArgumentValue::Int(li) => { | ||
if let Some(ri) = other.as_i64() { | ||
(*li as i64) == ri | ||
} else { | ||
false | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
#[derive(Clone, Debug, CandidType, Deserialize, Eq, PartialEq)] | ||
pub struct CredentialSpec { | ||
pub credential_type: String, | ||
pub arguments: Option<HashMap<String, ArgumentValue>>, | ||
} | ||
|
||
#[derive(Clone, Debug, CandidType, Deserialize, Eq, PartialEq)] | ||
pub struct ManifestRequest {} | ||
|
||
#[derive(Clone, Debug, CandidType, Deserialize, Eq, PartialEq)] | ||
pub enum ManifestResponse { | ||
Ok(ManifestData), | ||
Err(String), | ||
} | ||
|
||
#[derive(Clone, Debug, CandidType, Deserialize, Eq, PartialEq)] | ||
pub struct ManifestData {} | ||
|
||
#[derive(Clone, Debug, CandidType, Deserialize, Eq, PartialEq)] | ||
pub struct Icrc21VcConsentMessageRequest { | ||
pub credential_spec: CredentialSpec, | ||
pub preferences: Icrc21ConsentPreferences, | ||
} | ||
|
||
#[derive(Clone, Debug, CandidType, Deserialize, Eq, PartialEq)] | ||
pub struct Icrc21ConsentPreferences { | ||
pub language: String, | ||
} | ||
|
||
#[derive(Clone, Debug, CandidType, Deserialize, Eq, PartialEq)] | ||
pub struct Icrc21ErrorInfo { | ||
pub description: String, | ||
} | ||
|
||
#[derive(Clone, Debug, CandidType, Deserialize, Eq, PartialEq)] | ||
pub enum Icrc21Error { | ||
UnsupportedCanisterCall(Icrc21ErrorInfo), | ||
ConsentMessageUnavailable(Icrc21ErrorInfo), | ||
GenericError { | ||
error_code: Nat, | ||
description: String, | ||
}, | ||
} | ||
|
||
#[derive(Clone, Debug, CandidType, Deserialize, Eq, PartialEq)] | ||
pub struct Icrc21ConsentInfo { | ||
pub consent_message: String, | ||
pub language: String, | ||
} | ||
|
||
#[derive(Clone, Debug, CandidType, Deserialize, Eq, PartialEq)] | ||
pub struct DerivationOriginRequest { | ||
pub frontend_hostname: String, | ||
} | ||
|
||
#[derive(Clone, Debug, CandidType, Deserialize, Eq, PartialEq)] | ||
pub struct DerivationOriginData { | ||
pub origin: String, | ||
} | ||
|
||
#[derive(Clone, Debug, CandidType, Deserialize, Eq, PartialEq)] | ||
pub enum DerivationOriginError { | ||
UnsupportedOrigin(String), | ||
Internal(String), | ||
} | ||
|
||
#[cfg(test)] | ||
mod tests { | ||
use super::*; | ||
|
||
#[test] | ||
fn should_display_argument_values() { | ||
assert_eq!("42", format!("{}", ArgumentValue::Int(42))); | ||
assert_eq!("0", format!("{}", ArgumentValue::Int(0))); | ||
assert_eq!("-7", format!("{}", ArgumentValue::Int(-7))); | ||
assert_eq!("''", format!("{}", ArgumentValue::String("".to_string()))); | ||
assert_eq!( | ||
"'some string'", | ||
format!("{}", ArgumentValue::String("some string".to_string())) | ||
); | ||
} | ||
|
||
#[test] | ||
fn should_correctly_compare_argument_values() { | ||
assert_eq!(ArgumentValue::Int(42), Value::from(42)); | ||
assert_eq!(ArgumentValue::Int(123456789), Value::from(123456789)); | ||
assert_eq!(ArgumentValue::Int(0), Value::from(0)); | ||
|
||
assert_ne!(ArgumentValue::Int(42), Value::from(11)); | ||
assert_ne!(ArgumentValue::Int(42), Value::from("some string")); | ||
assert_ne!(ArgumentValue::Int(42), Value::from(true)); | ||
assert_ne!(ArgumentValue::Int(42), Value::from(vec![1, 2, 3])); | ||
|
||
assert_eq!( | ||
ArgumentValue::String("same string".to_string()), | ||
Value::from("same string") | ||
); | ||
let long_string = "this is a bit longer string just for testing purposes"; | ||
assert_eq!( | ||
ArgumentValue::String(long_string.to_string()), | ||
Value::from(long_string) | ||
); | ||
assert_eq!(ArgumentValue::String("".to_string()), Value::from("")); | ||
|
||
assert_ne!( | ||
ArgumentValue::String("some string".to_string()), | ||
Value::from("different") | ||
); | ||
assert_ne!( | ||
ArgumentValue::String("a string".to_string()), | ||
Value::from(42) | ||
); | ||
assert_ne!( | ||
ArgumentValue::String("a string".to_string()), | ||
Value::from(true) | ||
); | ||
assert_ne!( | ||
ArgumentValue::String("a string".to_string()), | ||
Value::from(vec![1, 2, 3]) | ||
); | ||
} | ||
} |
Oops, something went wrong.