Documentation
¶
Index ¶
- Constants
- func CachingJSONLDLoader() *ld.CachingDocumentLoader
- type Constraints
- type Field
- type Filter
- type Format
- type Holder
- type InputDescriptor
- type InputDescriptorMapping
- type JwtType
- type LdpType
- type MatchOption
- type MatchOptions
- type Preference
- type PresentationDefinition
- func (pd *PresentationDefinition) CreateVP(credentials []*verifiable.Credential, opts ...verifiable.CredentialOpt) (*verifiable.Presentation, error)
- func (pd *PresentationDefinition) Match(vp *verifiable.Presentation, options ...MatchOption) (map[string]*verifiable.Credential, error)
- func (pd *PresentationDefinition) ValidateSchema() error
- type PresentationSubmission
- type Schema
- type Selection
- type StrOrInt
- type SubmissionRequirement
Examples ¶
Constants ¶
const ( // PresentationSubmissionJSONLDContext is the JSONLD context of presentation submissions. PresentationSubmissionJSONLDContext = "https://identity.foundation/presentation-exchange/submission/v1" // PresentationSubmissionJSONLDType is the JSONLD type of presentation submissions. PresentationSubmissionJSONLDType = "PresentationSubmission" )
const ( // All rule`s value. All Selection = "all" // Pick rule`s value. Pick Selection = "pick" // Required predicate`s value. Required Preference = "required" // Preferred predicate`s value. Preferred Preference = "preferred" )
Variables ¶
This section is empty.
Functions ¶
func CachingJSONLDLoader ¶ added in v0.1.6
func CachingJSONLDLoader() *ld.CachingDocumentLoader
CachingJSONLDLoader creates JSON_LD CachingDocumentLoader with preloaded base JSON-LD document. TODO: this needs to be removed in followup PR.
Types ¶
type Constraints ¶ added in v0.1.6
type Constraints struct {
LimitDisclosure bool `json:"limit_disclosure,omitempty"`
SubjectIsIssuer *Preference `json:"subject_is_issuer,omitempty"`
IsHolder []*Holder `json:"is_holder,omitempty"`
Fields []*Field `json:"fields,omitempty"`
}
Constraints describes InputDescriptor`s Constraints field.
type Field ¶ added in v0.1.6
type Field struct {
Path []string `json:"path,omitempty"`
ID string `json:"id,omitempty"`
Purpose string `json:"purpose,omitempty"`
Filter *Filter `json:"filter,omitempty"`
Predicate *Preference `json:"predicate,omitempty"`
}
Field describes Constraints`s Fields field.
type Filter ¶ added in v0.1.6
type Filter struct {
Type *string `json:"type,omitempty"`
Format string `json:"format,omitempty"`
Pattern string `json:"pattern,omitempty"`
Minimum StrOrInt `json:"minimum,omitempty"`
Maximum StrOrInt `json:"maximum,omitempty"`
MinLength int `json:"minLength,omitempty"`
MaxLength int `json:"maxLength,omitempty"`
ExclusiveMinimum StrOrInt `json:"exclusiveMinimum,omitempty"`
ExclusiveMaximum StrOrInt `json:"exclusiveMaximum,omitempty"`
Const StrOrInt `json:"const,omitempty"`
Enum []StrOrInt `json:"enum,omitempty"`
Not map[string]interface{} `json:"not,omitempty"`
}
Filter describes filter.
type Format ¶ added in v0.1.6
type Format struct {
Jwt *JwtType `json:"jwt,omitempty"`
JwtVC *JwtType `json:"jwt_vc,omitempty"`
JwtVP *JwtType `json:"jwt_vp,omitempty"`
Ldp *LdpType `json:"ldp,omitempty"`
LdpVC *LdpType `json:"ldp_vc,omitempty"`
LdpVP *LdpType `json:"ldp_vp,omitempty"`
}
Format describes PresentationDefinition`s Format field.
type Holder ¶ added in v0.1.6
type Holder struct {
FieldID []string `json:"field_id,omitempty"`
Directive *Preference `json:"directive,omitempty"`
}
Holder describes Constraints`s holder object.
type InputDescriptor ¶
type InputDescriptor struct {
ID string `json:"id,omitempty"`
Group []string `json:"group,omitempty"`
Name string `json:"name,omitempty"`
Purpose string `json:"purpose,omitempty"`
Metadata map[string]interface{} `json:"metadata,omitempty"`
Schema []*Schema `json:"schema,omitempty"`
Constraints *Constraints `json:"constraints,omitempty"`
}
InputDescriptor input descriptors.
type InputDescriptorMapping ¶
type InputDescriptorMapping struct {
ID string `json:"id,omitempty"`
Format string `json:"format,omitempty"`
Path string `json:"path,omitempty"`
PathNested *InputDescriptorMapping `json:"path_nested,omitempty"`
}
InputDescriptorMapping maps an InputDescriptor to a verifiable credential pointed to by the JSONPath in `Path`.
type JwtType ¶ added in v0.1.6
type JwtType struct {
Alg []string `json:"alg,omitempty"`
}
JwtType contains alg.
type LdpType ¶ added in v0.1.6
type LdpType struct {
ProofType []string `json:"proof_type,omitempty"`
}
LdpType contains proof_type.
type MatchOption ¶
type MatchOption func(*MatchOptions)
MatchOption is an option that sets an option for when matching.
func WithJSONLDDocumentLoader ¶
func WithJSONLDDocumentLoader(l ld.DocumentLoader) MatchOption
WithJSONLDDocumentLoader sets the loader to use when parsing the embedded verifiable credentials.
type MatchOptions ¶
type MatchOptions struct {
JSONLDDocumentLoader ld.DocumentLoader
}
MatchOptions is a holder of options that can set when matching a submission against definitions.
type Preference ¶ added in v0.1.6
type Preference string
Preference can be "required" or "preferred".
type PresentationDefinition ¶ added in v0.1.6
type PresentationDefinition struct {
// ID unique resource identifier.
ID string `json:"id,omitempty"`
// Name human-friendly name that describes what the Presentation Definition pertains to.
Name string `json:"name,omitempty"`
// Purpose describes the purpose for which the Presentation Definition’s inputs are being requested.
Purpose string `json:"purpose,omitempty"`
Locale string `json:"locale,omitempty"`
// Format is an object with one or more properties matching the registered Claim Format Designations
// (jwt, jwt_vc, jwt_vp, etc.) to inform the Holder of the claim format configurations the Verifier can process.
Format *Format `json:"format,omitempty"`
// SubmissionRequirements must conform to the Submission Requirement Format.
// If not present, all inputs listed in the InputDescriptors array are required for submission.
SubmissionRequirements []*SubmissionRequirement `json:"submission_requirements,omitempty"`
InputDescriptors []*InputDescriptor `json:"input_descriptors,omitempty"`
}
PresentationDefinition presentation definitions (https://identity.foundation/presentation-exchange/).
func (*PresentationDefinition) CreateVP ¶ added in v0.1.6
func (pd *PresentationDefinition) CreateVP(credentials []*verifiable.Credential, opts ...verifiable.CredentialOpt) (*verifiable.Presentation, error)
CreateVP creates verifiable presentation.
Example ¶
predicate := Required
pd := &PresentationDefinition{
ID: "c1b88ce1-8460-4baf-8f16-4759a2f055fd",
Purpose: "To sell you a drink we need to know that you are an adult.",
InputDescriptors: []*InputDescriptor{{
ID: "age_descriptor",
Purpose: "Your age should be greater or equal to 18.",
Schema: []*Schema{{
URI: schemaURI,
}},
Constraints: &Constraints{
LimitDisclosure: true,
Fields: []*Field{{
Path: []string{"$.age"},
Predicate: &predicate,
Filter: &Filter{
Type: &intFilterType,
Minimum: 18,
},
}},
},
}},
}
vp, err := pd.CreateVP([]*verifiable.Credential{
{
ID: "http://example.edu/credentials/777",
Context: []string{"https://www.w3.org/2018/credentials/v1"},
Types: []string{"VerifiableCredential"},
Issuer: verifiable.Issuer{
ID: "did:example:76e12ec712ebc6f1c221ebfeb1f",
},
Issued: &util.TimeWithTrailingZeroMsec{
Time: time.Time{},
},
Subject: "did:example:76e12ec712ebc6f1c221ebfeb1f",
Schemas: []verifiable.TypedID{{
ID: schemaURI,
Type: "JsonSchemaValidator2018",
}},
CustomFields: map[string]interface{}{
"first_name": "Jesse",
"last_name": "Pinkman",
"age": 21,
},
},
})
vp.CustomFields["presentation_submission"].(*PresentationSubmission).ID = dummy
vp.Credentials()[0].(*verifiable.Credential).Schemas[0].ID = dummy
if err != nil {
panic(err)
}
vpBytes, err := json.MarshalIndent(vp, "", "\t")
if err != nil {
panic(err)
}
fmt.Println(string(vpBytes))
Output: { "@context": [ "https://www.w3.org/2018/credentials/v1", "https://identity.foundation/presentation-exchange/submission/v1" ], "presentation_submission": { "id": "DUMMY", "definition_id": "c1b88ce1-8460-4baf-8f16-4759a2f055fd", "descriptor_map": [ { "id": "age_descriptor", "format": "ldp_vp", "path": "$.verifiableCredential[0]" } ] }, "type": [ "VerifiablePresentation", "PresentationSubmission" ], "verifiableCredential": [ { "@context": [ "https://www.w3.org/2018/credentials/v1" ], "age": true, "credentialSchema": [ { "id": "DUMMY", "type": "JsonSchemaValidator2018" } ], "credentialSubject": "did:example:76e12ec712ebc6f1c221ebfeb1f", "id": "http://example.edu/credentials/777", "issuanceDate": "0001-01-01T00:00:00Z", "issuer": "did:example:76e12ec712ebc6f1c221ebfeb1f", "type": "VerifiableCredential" } ] }
Example (MultipleMatches) ¶
pd := &PresentationDefinition{
ID: "c1b88ce1-8460-4baf-8f16-4759a2f055fd",
Purpose: "To sell you a drink we need to know that you are an adult.",
InputDescriptors: []*InputDescriptor{{
ID: "age_descriptor",
Purpose: "Your age should be greater or equal to 18.",
Schema: []*Schema{{
URI: schemaURI,
}},
Constraints: &Constraints{
Fields: []*Field{{
Path: []string{"$.age"},
Filter: &Filter{
Type: &intFilterType,
Minimum: 18,
},
}},
},
}, {
ID: "first_name_descriptor",
Purpose: "First name must be either Andrew or Jesse",
Schema: []*Schema{{
URI: schemaURI,
}},
Constraints: &Constraints{
Fields: []*Field{{
Path: []string{"$.first_name"},
Filter: &Filter{
Type: &strFilterType,
Pattern: "Andrew|Jesse",
},
}},
},
}},
}
vp, err := pd.CreateVP([]*verifiable.Credential{
{
ID: "http://example.edu/credentials/777",
Context: []string{"https://www.w3.org/2018/credentials/v1"},
Types: []string{"VerifiableCredential"},
Issuer: verifiable.Issuer{
ID: "did:example:777",
},
Issued: &util.TimeWithTrailingZeroMsec{
Time: time.Time{},
},
Subject: "did:example:777",
Schemas: []verifiable.TypedID{{
ID: schemaURI,
Type: "JsonSchemaValidator2018",
}},
CustomFields: map[string]interface{}{
"first_name": "Andrew",
"last_name": "Hanks",
"age": 25,
},
},
{
ID: "http://example.edu/credentials/888",
Context: []string{"https://www.w3.org/2018/credentials/v1"},
Types: []string{"VerifiableCredential"},
Issuer: verifiable.Issuer{
ID: "did:example:888",
},
Issued: &util.TimeWithTrailingZeroMsec{
Time: time.Time{},
},
Subject: "did:example:888",
Schemas: []verifiable.TypedID{{
ID: schemaURI,
Type: "JsonSchemaValidator2018",
}},
CustomFields: map[string]interface{}{
"first_name": "Jesse",
"last_name": "Pinkman",
"age": 21,
},
},
})
vp.CustomFields["presentation_submission"].(*PresentationSubmission).ID = dummy
for _, credential := range vp.Credentials() {
credential.(*verifiable.Credential).Schemas[0].ID = dummy
}
if err != nil {
panic(err)
}
vpBytes, err := json.MarshalIndent(vp, "", "\t")
if err != nil {
panic(err)
}
fmt.Println(string(vpBytes))
Output: { "@context": [ "https://www.w3.org/2018/credentials/v1", "https://identity.foundation/presentation-exchange/submission/v1" ], "presentation_submission": { "id": "DUMMY", "definition_id": "c1b88ce1-8460-4baf-8f16-4759a2f055fd", "descriptor_map": [ { "id": "age_descriptor", "format": "ldp_vp", "path": "$.verifiableCredential[0]" }, { "id": "age_descriptor", "format": "ldp_vp", "path": "$.verifiableCredential[1]" }, { "id": "first_name_descriptor", "format": "ldp_vp", "path": "$.verifiableCredential[0]" }, { "id": "first_name_descriptor", "format": "ldp_vp", "path": "$.verifiableCredential[1]" } ] }, "type": [ "VerifiablePresentation", "PresentationSubmission" ], "verifiableCredential": [ { "@context": [ "https://www.w3.org/2018/credentials/v1" ], "age": 25, "credentialSchema": [ { "id": "DUMMY", "type": "JsonSchemaValidator2018" } ], "credentialSubject": "did:example:777", "first_name": "Andrew", "id": "http://example.edu/credentials/777", "issuanceDate": "0001-01-01T00:00:00Z", "issuer": "did:example:777", "last_name": "Hanks", "type": "VerifiableCredential" }, { "@context": [ "https://www.w3.org/2018/credentials/v1" ], "age": 21, "credentialSchema": [ { "id": "DUMMY", "type": "JsonSchemaValidator2018" } ], "credentialSubject": "did:example:888", "first_name": "Jesse", "id": "http://example.edu/credentials/888", "issuanceDate": "0001-01-01T00:00:00Z", "issuer": "did:example:888", "last_name": "Pinkman", "type": "VerifiableCredential" } ] }
Example (MultipleMatchesDisclosure) ¶
pd := &PresentationDefinition{
ID: "c1b88ce1-8460-4baf-8f16-4759a2f055fd",
Purpose: "To sell you a drink we need to know that you are an adult.",
InputDescriptors: []*InputDescriptor{{
ID: "age_descriptor",
Purpose: "Your age should be greater or equal to 18.",
Schema: []*Schema{{
URI: schemaURI,
}},
Constraints: &Constraints{
Fields: []*Field{{
Path: []string{"$.age"},
Filter: &Filter{
Type: &intFilterType,
Minimum: 18,
},
}},
},
}, {
ID: "first_name_descriptor",
Purpose: "First name must be either Andrew or Jesse",
Schema: []*Schema{{
URI: schemaURI,
}},
Constraints: &Constraints{
LimitDisclosure: true,
Fields: []*Field{{
Path: []string{"$.first_name"},
Filter: &Filter{
Type: &strFilterType,
Pattern: "Andrew|Jesse",
},
}},
},
}},
}
vp, err := pd.CreateVP([]*verifiable.Credential{
{
ID: "http://example.edu/credentials/777",
Context: []string{"https://www.w3.org/2018/credentials/v1"},
Types: []string{"VerifiableCredential"},
Issuer: verifiable.Issuer{
ID: "did:example:777",
},
Issued: &util.TimeWithTrailingZeroMsec{
Time: time.Time{},
},
Subject: "did:example:777",
Schemas: []verifiable.TypedID{{
ID: schemaURI,
Type: "JsonSchemaValidator2018",
}},
CustomFields: map[string]interface{}{
"first_name": "Andrew",
"last_name": "Hanks",
"age": 25,
},
},
{
ID: "http://example.edu/credentials/888",
Context: []string{"https://www.w3.org/2018/credentials/v1"},
Types: []string{"VerifiableCredential"},
Issuer: verifiable.Issuer{
ID: "did:example:888",
},
Issued: &util.TimeWithTrailingZeroMsec{
Time: time.Time{},
},
Subject: "did:example:888",
Schemas: []verifiable.TypedID{{
ID: schemaURI,
Type: "JsonSchemaValidator2018",
}},
CustomFields: map[string]interface{}{
"first_name": "Jesse",
"last_name": "Pinkman",
"age": 21,
},
},
})
if err != nil {
panic(err)
}
vp.CustomFields["presentation_submission"].(*PresentationSubmission).ID = dummy
for _, credential := range vp.Credentials() {
credential.(*verifiable.Credential).Schemas[0].ID = dummy
}
vpBytes, err := json.MarshalIndent(vp, "", "\t")
if err != nil {
panic(err)
}
fmt.Println(string(vpBytes))
Output: { "@context": [ "https://www.w3.org/2018/credentials/v1", "https://identity.foundation/presentation-exchange/submission/v1" ], "presentation_submission": { "id": "DUMMY", "definition_id": "c1b88ce1-8460-4baf-8f16-4759a2f055fd", "descriptor_map": [ { "id": "age_descriptor", "format": "ldp_vp", "path": "$.verifiableCredential[0]" }, { "id": "age_descriptor", "format": "ldp_vp", "path": "$.verifiableCredential[1]" }, { "id": "first_name_descriptor", "format": "ldp_vp", "path": "$.verifiableCredential[2]" }, { "id": "first_name_descriptor", "format": "ldp_vp", "path": "$.verifiableCredential[3]" } ] }, "type": [ "VerifiablePresentation", "PresentationSubmission" ], "verifiableCredential": [ { "@context": [ "https://www.w3.org/2018/credentials/v1" ], "age": 25, "credentialSchema": [ { "id": "DUMMY", "type": "JsonSchemaValidator2018" } ], "credentialSubject": "did:example:777", "first_name": "Andrew", "id": "http://example.edu/credentials/777", "issuanceDate": "0001-01-01T00:00:00Z", "issuer": "did:example:777", "last_name": "Hanks", "type": "VerifiableCredential" }, { "@context": [ "https://www.w3.org/2018/credentials/v1" ], "age": 21, "credentialSchema": [ { "id": "DUMMY", "type": "JsonSchemaValidator2018" } ], "credentialSubject": "did:example:888", "first_name": "Jesse", "id": "http://example.edu/credentials/888", "issuanceDate": "0001-01-01T00:00:00Z", "issuer": "did:example:888", "last_name": "Pinkman", "type": "VerifiableCredential" }, { "@context": [ "https://www.w3.org/2018/credentials/v1" ], "credentialSchema": [ { "id": "DUMMY", "type": "JsonSchemaValidator2018" } ], "credentialSubject": "did:example:777", "first_name": "Andrew", "id": "http://example.edu/credentials/777", "issuanceDate": "0001-01-01T00:00:00Z", "issuer": "did:example:777", "type": "VerifiableCredential" }, { "@context": [ "https://www.w3.org/2018/credentials/v1" ], "credentialSchema": [ { "id": "DUMMY", "type": "JsonSchemaValidator2018" } ], "credentialSubject": "did:example:888", "first_name": "Jesse", "id": "http://example.edu/credentials/888", "issuanceDate": "0001-01-01T00:00:00Z", "issuer": "did:example:888", "type": "VerifiableCredential" } ] }
Example (SubmissionRequirements) ¶
pd := &PresentationDefinition{
ID: "c1b88ce1-8460-4baf-8f16-4759a2f055fd",
Purpose: "To sell you a drink we need to know that you are an adult.",
SubmissionRequirements: []*SubmissionRequirement{
{
Rule: "all",
From: "A",
},
{
Rule: "pick",
Purpose: "We need your photo to identify you.",
Count: 1,
FromNested: []*SubmissionRequirement{
{
Rule: "all",
From: "drivers_license_image",
},
{
Rule: "all",
From: "passport_image",
},
},
},
},
InputDescriptors: []*InputDescriptor{{
ID: "age_descriptor",
Group: []string{"A"},
Purpose: "Your age should be greater or equal to 18.",
Schema: []*Schema{{
URI: schemaURI,
}},
Constraints: &Constraints{
Fields: []*Field{{
Path: []string{"$.age"},
Filter: &Filter{
Type: &intFilterType,
Minimum: 18,
},
}},
},
}, {
ID: "drivers_license_image_descriptor",
Group: []string{"drivers_license_image"},
Purpose: "We need your photo to identify you",
Schema: []*Schema{{
URI: schemaURI,
}},
Constraints: &Constraints{
Fields: []*Field{{
Path: []string{"$.photo"},
Filter: &Filter{
Type: &strFilterType,
Format: "uri",
},
}},
},
}, {
ID: "passport_image_descriptor",
Group: []string{"passport_image"},
Purpose: "We need your image to identify you",
Schema: []*Schema{{
URI: schemaURI,
}},
Constraints: &Constraints{
Fields: []*Field{{
Path: []string{"$.image"},
Filter: &Filter{
Type: &strFilterType,
Format: "uri",
},
}},
},
}},
}
vp, err := pd.CreateVP([]*verifiable.Credential{
{
ID: "http://example.edu/credentials/777",
Context: []string{"https://www.w3.org/2018/credentials/v1"},
Types: []string{"VerifiableCredential"},
Issuer: verifiable.Issuer{
ID: "did:example:777",
},
Issued: &util.TimeWithTrailingZeroMsec{
Time: time.Time{},
},
Subject: "did:example:777",
Schemas: []verifiable.TypedID{{
ID: schemaURI,
Type: "JsonSchemaValidator2018",
}},
CustomFields: map[string]interface{}{
"first_name": "Andrew",
"last_name": "Hanks",
"image": "http://image.com/user777",
"age": 25,
},
},
{
ID: "http://example.edu/credentials/888",
Context: []string{"https://www.w3.org/2018/credentials/v1"},
Types: []string{"VerifiableCredential"},
Issuer: verifiable.Issuer{
ID: "did:example:888",
},
Issued: &util.TimeWithTrailingZeroMsec{
Time: time.Time{},
},
Subject: "did:example:888",
Schemas: []verifiable.TypedID{{
ID: schemaURI,
Type: "JsonSchemaValidator2018",
}},
CustomFields: map[string]interface{}{
"first_name": "Jesse",
"last_name": "Pinkman",
"photo": "http://image.com/user777",
"age": 21,
},
},
})
if err != nil {
panic(err)
}
vp.CustomFields["presentation_submission"].(*PresentationSubmission).ID = dummy
for _, credential := range vp.Credentials() {
credential.(*verifiable.Credential).Schemas[0].ID = dummy
}
vpBytes, err := json.MarshalIndent(vp, "", "\t")
if err != nil {
panic(err)
}
fmt.Println(string(vpBytes))
Output: { "@context": [ "https://www.w3.org/2018/credentials/v1", "https://identity.foundation/presentation-exchange/submission/v1" ], "presentation_submission": { "id": "DUMMY", "definition_id": "c1b88ce1-8460-4baf-8f16-4759a2f055fd", "descriptor_map": [ { "id": "age_descriptor", "format": "ldp_vp", "path": "$.verifiableCredential[0]" }, { "id": "age_descriptor", "format": "ldp_vp", "path": "$.verifiableCredential[1]" }, { "id": "drivers_license_image_descriptor", "format": "ldp_vp", "path": "$.verifiableCredential[1]" }, { "id": "passport_image_descriptor", "format": "ldp_vp", "path": "$.verifiableCredential[0]" } ] }, "type": [ "VerifiablePresentation", "PresentationSubmission" ], "verifiableCredential": [ { "@context": [ "https://www.w3.org/2018/credentials/v1" ], "age": 25, "credentialSchema": [ { "id": "DUMMY", "type": "JsonSchemaValidator2018" } ], "credentialSubject": "did:example:777", "first_name": "Andrew", "id": "http://example.edu/credentials/777", "image": "http://image.com/user777", "issuanceDate": "0001-01-01T00:00:00Z", "issuer": "did:example:777", "last_name": "Hanks", "type": "VerifiableCredential" }, { "@context": [ "https://www.w3.org/2018/credentials/v1" ], "age": 21, "credentialSchema": [ { "id": "DUMMY", "type": "JsonSchemaValidator2018" } ], "credentialSubject": "did:example:888", "first_name": "Jesse", "id": "http://example.edu/credentials/888", "issuanceDate": "0001-01-01T00:00:00Z", "issuer": "did:example:888", "last_name": "Pinkman", "photo": "http://image.com/user777", "type": "VerifiableCredential" } ] }
Example (SubmissionRequirementsLimitDisclosure) ¶
pd := &PresentationDefinition{
ID: "c1b88ce1-8460-4baf-8f16-4759a2f055fd",
Purpose: "To sell you a drink we need to know that you are an adult.",
SubmissionRequirements: []*SubmissionRequirement{
{
Rule: "all",
From: "A",
},
{
Rule: "pick",
Purpose: "We need your photo to identify you",
Count: 1,
FromNested: []*SubmissionRequirement{
{
Rule: "all",
From: "drivers_license_image",
},
{
Rule: "all",
From: "passport_image",
},
},
},
},
InputDescriptors: []*InputDescriptor{{
ID: "age_descriptor",
Group: []string{"A"},
Purpose: "Your age should be greater or equal to 18.",
Schema: []*Schema{{
URI: schemaURI,
}},
Constraints: &Constraints{
Fields: []*Field{{
Path: []string{"$.age"},
Filter: &Filter{
Type: &intFilterType,
Minimum: 18,
},
}},
},
}, {
ID: "drivers_license_image_descriptor",
Group: []string{"drivers_license_image"},
Purpose: "We need your photo to identify you",
Schema: []*Schema{{
URI: schemaURI,
}},
Constraints: &Constraints{
LimitDisclosure: true,
Fields: []*Field{{
Path: []string{"$.photo"},
Filter: &Filter{
Type: &strFilterType,
Format: "uri",
},
}},
},
}, {
ID: "passport_image_descriptor",
Group: []string{"passport_image"},
Purpose: "We need your image to identify you",
Schema: []*Schema{{
URI: schemaURI,
}},
Constraints: &Constraints{
LimitDisclosure: true,
Fields: []*Field{{
Path: []string{"$.image"},
Filter: &Filter{
Type: &strFilterType,
Format: "uri",
},
}},
},
}},
}
vp, err := pd.CreateVP([]*verifiable.Credential{
{
ID: "http://example.edu/credentials/777",
Context: []string{"https://www.w3.org/2018/credentials/v1"},
Types: []string{"VerifiableCredential"},
Issuer: verifiable.Issuer{
ID: "did:example:777",
},
Issued: &util.TimeWithTrailingZeroMsec{
Time: time.Time{},
},
Subject: "did:example:777",
Schemas: []verifiable.TypedID{{
ID: schemaURI,
Type: "JsonSchemaValidator2018",
}},
CustomFields: map[string]interface{}{
"first_name": "Andrew",
"last_name": "Hanks",
"image": "http://image.com/user777",
"age": 25,
},
},
{
ID: "http://example.edu/credentials/888",
Context: []string{"https://www.w3.org/2018/credentials/v1"},
Types: []string{"VerifiableCredential"},
Issuer: verifiable.Issuer{
ID: "did:example:888",
},
Issued: &util.TimeWithTrailingZeroMsec{
Time: time.Time{},
},
Subject: "did:example:888",
Schemas: []verifiable.TypedID{{
ID: schemaURI,
Type: "JsonSchemaValidator2018",
}},
CustomFields: map[string]interface{}{
"first_name": "Jesse",
"last_name": "Pinkman",
"photo": "http://image.com/user777",
"age": 21,
},
},
})
if err != nil {
panic(err)
}
vp.CustomFields["presentation_submission"].(*PresentationSubmission).ID = dummy
for _, credential := range vp.Credentials() {
credential.(*verifiable.Credential).Schemas[0].ID = dummy
}
vpBytes, err := json.MarshalIndent(vp, "", "\t")
if err != nil {
panic(err)
}
fmt.Println(string(vpBytes))
Output: { "@context": [ "https://www.w3.org/2018/credentials/v1", "https://identity.foundation/presentation-exchange/submission/v1" ], "presentation_submission": { "id": "DUMMY", "definition_id": "c1b88ce1-8460-4baf-8f16-4759a2f055fd", "descriptor_map": [ { "id": "age_descriptor", "format": "ldp_vp", "path": "$.verifiableCredential[0]" }, { "id": "age_descriptor", "format": "ldp_vp", "path": "$.verifiableCredential[1]" }, { "id": "drivers_license_image_descriptor", "format": "ldp_vp", "path": "$.verifiableCredential[2]" }, { "id": "passport_image_descriptor", "format": "ldp_vp", "path": "$.verifiableCredential[3]" } ] }, "type": [ "VerifiablePresentation", "PresentationSubmission" ], "verifiableCredential": [ { "@context": [ "https://www.w3.org/2018/credentials/v1" ], "age": 25, "credentialSchema": [ { "id": "DUMMY", "type": "JsonSchemaValidator2018" } ], "credentialSubject": "did:example:777", "first_name": "Andrew", "id": "http://example.edu/credentials/777", "image": "http://image.com/user777", "issuanceDate": "0001-01-01T00:00:00Z", "issuer": "did:example:777", "last_name": "Hanks", "type": "VerifiableCredential" }, { "@context": [ "https://www.w3.org/2018/credentials/v1" ], "age": 21, "credentialSchema": [ { "id": "DUMMY", "type": "JsonSchemaValidator2018" } ], "credentialSubject": "did:example:888", "first_name": "Jesse", "id": "http://example.edu/credentials/888", "issuanceDate": "0001-01-01T00:00:00Z", "issuer": "did:example:888", "last_name": "Pinkman", "photo": "http://image.com/user777", "type": "VerifiableCredential" }, { "@context": [ "https://www.w3.org/2018/credentials/v1" ], "credentialSchema": [ { "id": "DUMMY", "type": "JsonSchemaValidator2018" } ], "credentialSubject": "did:example:888", "id": "http://example.edu/credentials/888", "issuanceDate": "0001-01-01T00:00:00Z", "issuer": "did:example:888", "photo": "http://image.com/user777", "type": "VerifiableCredential" }, { "@context": [ "https://www.w3.org/2018/credentials/v1" ], "credentialSchema": [ { "id": "DUMMY", "type": "JsonSchemaValidator2018" } ], "credentialSubject": "did:example:777", "id": "http://example.edu/credentials/777", "image": "http://image.com/user777", "issuanceDate": "0001-01-01T00:00:00Z", "issuer": "did:example:777", "type": "VerifiableCredential" } ] }
func (*PresentationDefinition) Match ¶ added in v0.1.6
func (pd *PresentationDefinition) Match(vp *verifiable.Presentation, options ...MatchOption) (map[string]*verifiable.Credential, error)
Match returns the credentials matched against the InputDescriptors ids.
Example ¶
Example of a Verifier verifying the presentation submission of a Holder.
// verifier sends their presentation definitions to the holder
verifierDefinitions := &PresentationDefinition{
InputDescriptors: []*InputDescriptor{
{
ID: "banking",
Schema: []*Schema{{
URI: "https://example.context.jsonld/account",
}},
},
{
ID: "residence",
Schema: []*Schema{{
URI: "https://example.context.jsonld/address",
}},
},
},
}
// holder fetches their credentials
accountCredential := newVC([]string{"https://example.context.jsonld/account"})
addressCredential := newVC([]string{"https://example.context.jsonld/address"})
// holder builds their presentation submission against the verifier's definitions
vp, err := newPresentationSubmission(
&PresentationSubmission{DescriptorMap: []*InputDescriptorMapping{
{
ID: "banking",
Path: "$.verifiableCredential[0]",
},
{
ID: "residence",
Path: "$.verifiableCredential[1]",
},
}},
accountCredential, addressCredential,
)
if err != nil {
panic(err)
}
// holder sends VP over the wire to the verifier
vpBytes, err := json.Marshal(vp)
if err != nil {
panic(err)
}
// load json-ld context
loader := cachedJSONLDContextLoader(map[string]string{
"https://example.context.jsonld/account": exampleJSONLDContext,
"https://example.context.jsonld/address": exampleJSONLDContext,
})
// verifier parses the vp
// note: parsing this VP without verifying the proof just for example purposes.
// Always verify proofs in production!
receivedVP, err := verifiable.ParsePresentation(vpBytes,
verifiable.WithPresDisabledProofCheck(),
verifiable.WithPresJSONLDDocumentLoader(loader))
if err != nil {
panic(err)
}
// verifier matches the received VP against their definitions
matched, err := verifierDefinitions.Match(
receivedVP,
WithJSONLDDocumentLoader(loader),
)
if err != nil {
panic(fmt.Errorf("presentation submission did not match definitions: %w", err))
}
for _, descriptor := range verifierDefinitions.InputDescriptors {
receivedCred := matched[descriptor.ID]
fmt.Printf(
"verifier received the '%s' credential for the input descriptor id '%s'\n",
receivedCred.Context[1], descriptor.ID)
}
Output: verifier received the 'https://example.context.jsonld/account' credential for the input descriptor id 'banking' verifier received the 'https://example.context.jsonld/address' credential for the input descriptor id 'residence'
func (*PresentationDefinition) ValidateSchema ¶ added in v0.1.6
func (pd *PresentationDefinition) ValidateSchema() error
ValidateSchema validates presentation definition.
type PresentationSubmission ¶
type PresentationSubmission struct {
// ID unique resource identifier.
ID string `json:"id,omitempty"`
Locale string `json:"locale,omitempty"`
// DefinitionID links the submission to its definition and must be the id value of a valid Presentation Definition.
DefinitionID string `json:"definition_id,omitempty"`
DescriptorMap []*InputDescriptorMapping `json:"descriptor_map"`
}
PresentationSubmission is the container for the descriptor_map: https://identity.foundation/presentation-exchange/#presentation-submission.
type StrOrInt ¶ added in v0.1.6
type StrOrInt interface{}
StrOrInt type that defines string or integer.
type SubmissionRequirement ¶ added in v0.1.6
type SubmissionRequirement struct {
Name string `json:"name,omitempty"`
Purpose string `json:"purpose,omitempty"`
Rule Selection `json:"rule,omitempty"`
Count int `json:"count,omitempty"`
Min int `json:"min,omitempty"`
Max int `json:"max,omitempty"`
From string `json:"from,omitempty"`
FromNested []*SubmissionRequirement `json:"from_nested,omitempty"`
}
SubmissionRequirement describes input that must be submitted via a Presentation Submission to satisfy Verifier demands.