Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add anoncreds package #1118

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions packages/anoncreds/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<p align="center">
<br />
<img
alt="Hyperledger Aries logo"
src="https://raw.githubusercontent.com/hyperledger/aries-framework-javascript/aa31131825e3331dc93694bc58414d955dcb1129/images/aries-logo.png"
height="250px"
/>
</p>
<h1 align="center"><b>Aries Framework JavaScript AnonCreds Interfaces</b></h1>
<p align="center">
<a
href="https://raw.githubusercontent.com/hyperledger/aries-framework-javascript/main/LICENSE"
><img
alt="License"
src="https://img.shields.io/badge/License-Apache%202.0-blue.svg"
/></a>
<a href="https://www.typescriptlang.org/"
><img
alt="typescript"
src="https://img.shields.io/badge/%3C%2F%3E-TypeScript-%230074c1.svg"
/></a>
<a href="https://www.npmjs.com/package/@aries-framework/anoncreds"
><img
alt="@aries-framework/anoncreds version"
src="https://img.shields.io/npm/v/@aries-framework/anoncreds"
/></a>

</p>
<br />

### Installation

### Quick start

### Example of usage
14 changes: 14 additions & 0 deletions packages/anoncreds/jest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import type { Config } from '@jest/types'

import base from '../../jest.config.base'

import packageJson from './package.json'

const config: Config.InitialOptions = {
...base,
name: packageJson.name,
displayName: packageJson.name,
// setupFilesAfterEnv: ['./tests/setup.ts'],
}

export default config
34 changes: 34 additions & 0 deletions packages/anoncreds/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
"name": "@aries-framework/anoncreds",
"main": "build/index",
"types": "build/index",
"version": "0.2.5",
"files": [
"build"
],
"private": true,
"license": "Apache-2.0",
"publishConfig": {
"access": "public"
},
"homepage": "https://github.com/hyperledger/aries-framework-javascript/tree/main/packages/anoncreds",
"repository": {
"type": "git",
"url": "https://github.com/hyperledger/aries-framework-javascript",
"directory": "packages/anoncreds"
},
"scripts": {
"build": "yarn run clean && yarn run compile",
"clean": "rimraf -rf ./build",
"compile": "tsc -p tsconfig.build.json",
"prepublishOnly": "yarn run build",
"test": "jest"
},
"dependencies": {
"@aries-framework/core": "*"
},
"peerDependencies": {},
"devDependencies": {
"typescript": "~4.3.0"
}
}
2 changes: 2 additions & 0 deletions packages/anoncreds/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './models'
export * from './services'
110 changes: 110 additions & 0 deletions packages/anoncreds/src/models/exchange.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
// TODO: Maybe we can make this a bit more specific?
export type WalletQuery = Record<string, unknown>

export interface ReferentWalletQuery {
[key: string]: WalletQuery
}

export interface NonRevokedInterval {
from?: number
to?: number
}

export interface AnonCredsCredentialOffer {
schema_id: string
cred_def_id: string
nonce: string
key_correctness_proof: Record<string, unknown>
}

export interface AnonCredsCredentialRequest {
// TODO: Why is this needed? It is just used as context in Ursa, can be any string. Should we remove it?
// Should we not make it did related?
prover_did: string
cred_def_id: string
blinded_ms: Record<string, unknown>
blinded_ms_correctness_proof: Record<string, unknown>
nonce: string
}

export interface CredValue {
raw: string
encoded: string // Raw value as number in string
}

export interface AnonCredsCredential {
schema_id: string
cred_def_id: string
rev_reg_id?: string
values: Record<string, CredValue>
signature: unknown
signature_correctness_proof: unknown
}

export interface AnonCredsProof {
requested_proof: {
revealed_attrs: Record<
string,
{
sub_proof_index: number
raw: string
encoded: string
}
>
revealed_attr_groups: Record<
string,
{
sub_proof_index: number
values: {
[key: string]: {
raw: string
encoded: string
}
}
}
>
unrevealed_attrs: Record<
string,
{
sub_proof_index: number
}
>
self_attested_attrs: Record<string, string>

requested_predicates: Record<string, { sub_proof_index: number }>
}
proof: any
identifiers: Array<{
schema_id: string
cred_def_id: string
rev_reg_id?: string
timestamp?: number
}>
}

export interface AnonCredsProofRequest {
name: string
version: string
nonce: string
requested_attributes: Record<
string,
{
name?: string
names?: string
restrictions?: WalletQuery[]
non_revoked?: NonRevokedInterval
}
>
requested_predicates: Record<
string,
{
name: string
p_type: '>=' | '>' | '<=' | '<'
p_value: number
restrictions?: WalletQuery[]
non_revoked?: NonRevokedInterval
}
>
non_revoked?: NonRevokedInterval
ver?: '1.0' | '2.0'
}
3 changes: 3 additions & 0 deletions packages/anoncreds/src/models/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export * from './internal'
export * from './exchange'
export * from './registry'
31 changes: 31 additions & 0 deletions packages/anoncreds/src/models/internal.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
export interface CredentialInfo {
referent: string
attributes: {
[key: string]: string
}
schemaId: string
credentialDefinitionId: string
revocationRegistryId?: number | undefined
credentialRevocationId?: string | undefined
}

export interface RequestedAttribute {
credentialId: string
timestamp?: number
revealed: boolean
credentialInfo?: CredentialInfo
revoked?: boolean
}

export interface RequestedPredicate {
credentialId: string
timestamp?: number
credentialInfo?: CredentialInfo
revoked?: boolean
}

export interface RequestedCredentials {
requestedAttributes?: Record<string, RequestedAttribute>
requestedPredicates?: Record<string, RequestedPredicate>
selfAttestedAttributes: Record<string, string>
}
38 changes: 38 additions & 0 deletions packages/anoncreds/src/models/registry.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
export interface AnonCredsSchema {
name: string
version: string
attrNames: string[]
}

export interface AnonCredsCredentialDefinition {
schemaId: string
type: 'CL'
tag: string
// TODO: work out in more detail
value: {
primary: Record<string, unknown>
revocation?: unknown
}
}

export interface AnonCredsRevocationRegistryDefinition {
type: 'CL_ACCUM'
credDefId: string
tag: string
publicKeys: {
accumKey: {
z: string
}
}
maxCredNum: number
tailsLocation: string
tailsHash: string
}

export interface AnonCredsRevocationList {
// TODO: this is a new property, but do we keep abbreviation or not?
revRegId: string
revocationList: number[]
currentAccumulator: string
timestamp: number
}
40 changes: 40 additions & 0 deletions packages/anoncreds/src/services/AnonCredsHolderService.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import type { CredentialInfo } from '../models'
import type { AnonCredsProof } from '../models/exchange'
import type {
CreateCredentialRequestOptions,
CreateCredentialRequestReturn,
CreateProofOptions,
GetCredentialOptions,
StoreCredentialOptions,
GetCredentialsForProofRequestOptions,
GetCredentialsForProofRequestReturn,
} from './AnonCredsHolderServiceOptions'
import type { AgentContext } from '@aries-framework/core'

export interface AnonCredsHolderService {
createProof(
agentContext: AgentContext,
options: CreateProofOptions,
metadata?: Record<string, unknown>
): Promise<AnonCredsProof>
storeCredential(
agentContext: AgentContext,
options: StoreCredentialOptions,
metadata?: Record<string, unknown>
): Promise<string>

// TODO: indy has different return types for the credential
getCredential(agentContext: AgentContext, options: GetCredentialOptions): Promise<CredentialInfo>

createCredentialRequest(
agentContext: AgentContext,
options: CreateCredentialRequestOptions,
metadata?: Record<string, unknown>
): Promise<CreateCredentialRequestReturn>

deleteCredential(agentContext: AgentContext, credentialId: string): Promise<void>
getCredentialsForProofRequest(
agentContext: AgentContext,
options: GetCredentialsForProofRequestOptions
): Promise<GetCredentialsForProofRequestReturn[]>
}
80 changes: 80 additions & 0 deletions packages/anoncreds/src/services/AnonCredsHolderServiceOptions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import type { CredentialInfo, RequestedCredentials } from '../models'
import type {
AnonCredsCredential,
AnonCredsCredentialOffer,
AnonCredsCredentialRequest,
AnonCredsProofRequest,
NonRevokedInterval,
ReferentWalletQuery,
} from '../models/exchange'
import type {
AnonCredsCredentialDefinition,
AnonCredsRevocationList,
AnonCredsRevocationRegistryDefinition,
AnonCredsSchema,
} from '../models/registry'

export interface AttributeInfo {
name?: string
names?: string[]
}

export interface CreateProofOptions {
proofRequest: AnonCredsProofRequest
requestedCredentials: RequestedCredentials
schemas: {
[schemaId: string]: AnonCredsSchema
}
credentialDefinitions: {
[credentialDefinitionId: string]: AnonCredsCredentialDefinition
}
revocationStates: {
[revocationRegistryDefinitionId: string]: {
definition: AnonCredsRevocationRegistryDefinition
revocationLists: {
[timestamp: string]: AnonCredsRevocationList
}
}
}
}

export interface StoreCredentialOptions {
// TODO: what is in credential request metadata?
credentialRequestMetadata: Record<string, unknown>
credential: AnonCredsCredential
credentialDefinition: AnonCredsCredentialDefinition
credentialDefinitionId: string
credentialId?: string
revocationRegistryDefinition?: AnonCredsRevocationRegistryDefinition
revocationRegistryDefinitionId: string
}

export interface GetCredentialOptions {
credentialId: string
}

export interface GetCredentialsForProofRequestOptions {
proofRequest: AnonCredsProofRequest
attributeReferent: string
start?: number
limit?: number
extraQuery?: ReferentWalletQuery
}

export interface GetCredentialsForProofRequestReturn {
credentialInfo: CredentialInfo
interval?: NonRevokedInterval
}

export interface CreateCredentialRequestOptions {
// TODO: Why is this needed? It is just used as context in Ursa, can be any string. Should we remove it?
// Should we not make it did related? (related to comment in AnonCredsCredentialRequest)
holderDid: string
credentialOffer: AnonCredsCredentialOffer
credentialDefinition: AnonCredsCredentialDefinition
}

export interface CreateCredentialRequestReturn {
credentialRequest: AnonCredsCredentialRequest
credentialRequestMetadata: Record<string, unknown>
}
Loading