Skip to content

Commit

Permalink
Merge branch 'main' into add-cheqd-sdk
Browse files Browse the repository at this point in the history
  • Loading branch information
DaevMithran authored Mar 28, 2023
2 parents 9a5c107 + 50e877d commit 58e459a
Show file tree
Hide file tree
Showing 17 changed files with 366 additions and 100 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ describe('V1 Proofs - Connectionless - Indy', () => {
}
})

test('Faber starts with connection-less proof requests to Alice', async () => {
// new method to test the return route and mediator together
const connectionlessTest = async (returnRoute?: boolean) => {
const {
holderAgent: aliceAgent,
issuerAgent: faberAgent,
Expand Down Expand Up @@ -134,6 +135,7 @@ describe('V1 Proofs - Connectionless - Indy', () => {

await aliceAgent.proofs.acceptRequest({
proofRecordId: aliceProofExchangeRecord.id,
useReturnRoute: returnRoute,
proofFormats: { indy: requestedCredentials.proofFormats.indy },
})

Expand All @@ -143,6 +145,7 @@ describe('V1 Proofs - Connectionless - Indy', () => {
state: ProofState.PresentationReceived,
})

const sentPresentationMessage = aliceAgent.proofs.findPresentationMessage(aliceProofExchangeRecord.id)
// assert presentation is valid
expect(faberProofExchangeRecord.isVerified).toBe(true)

Expand All @@ -154,6 +157,11 @@ describe('V1 Proofs - Connectionless - Indy', () => {
threadId: aliceProofExchangeRecord.threadId,
state: ProofState.Done,
})
return sentPresentationMessage
}

test('Faber starts with connection-less proof requests to Alice', async () => {
await connectionlessTest()
})

test('Faber starts with connection-less proof requests to Alice with auto-accept enabled', async () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,5 +41,5 @@ export interface RegisterCredentialDefinitionReturn {
| RegisterCredentialDefinitionReturnStateFinished
| RegisterCredentialDefinitionReturnStateFailed
credentialDefinitionMetadata: Extensible
registrationMetadata: AnonCredsResolutionMetadata
registrationMetadata: Extensible
}
12 changes: 7 additions & 5 deletions packages/askar/tests/helpers.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { AskarWalletPostgresStorageConfig } from '../src/wallet'
import type { InitConfig } from '@aries-framework/core'

import { LogLevel } from '@aries-framework/core'
import { LogLevel, utils } from '@aries-framework/core'
import { ariesAskar } from '@hyperledger/aries-askar-nodejs'
import path from 'path'

Expand All @@ -23,10 +23,11 @@ export function getPostgresAgentOptions(
storageConfig: AskarWalletPostgresStorageConfig,
extraConfig: Partial<InitConfig> = {}
) {
const random = utils.uuid().slice(0, 4)
const config: InitConfig = {
label: `Agent: ${name} Postgres`,
label: `PostgresAgent: ${name} - ${random}`,
walletConfig: {
id: `Wallet${name}`,
id: `PostgresWallet${name}${random}`,
key: `Key${name}`,
storage: storageConfig,
},
Expand All @@ -43,10 +44,11 @@ export function getPostgresAgentOptions(
}

export function getSqliteAgentOptions(name: string, extraConfig: Partial<InitConfig> = {}) {
const random = utils.uuid().slice(0, 4)
const config: InitConfig = {
label: `Agent: ${name} SQLite`,
label: `SQLiteAgent: ${name} - ${random}`,
walletConfig: {
id: `Wallet${name}`,
id: `SQLiteWallet${name} - ${random}`,
key: `Key${name}`,
storage: { type: 'sqlite' },
},
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/modules/credentials/CredentialsApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -550,7 +550,7 @@ export class CredentialsApi<CPs extends CredentialProtocol[]> implements Credent
serviceParams: {
service: recipientService.resolvedDidCommService,
senderKey: ourService.resolvedDidCommService.recipientKeys[0],
returnRoute: true,
returnRoute: false, // hard wire to be false since it's the end of the protocol so not needed here
},
})
)
Expand Down
7 changes: 2 additions & 5 deletions packages/core/src/modules/proofs/ProofsApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -341,26 +341,23 @@ export class ProofsApi<PPs extends ProofProtocol[]> implements ProofsApi<PPs> {
autoAcceptProof: options.autoAcceptProof,
goalCode: options.goalCode,
})

// Set and save ~service decorator to record (to remember our verkey)
message.service = ourService
await this.didCommMessageRepository.saveOrUpdateAgentMessage(this.agentContext, {
agentMessage: message,
role: DidCommMessageRole.Sender,
associatedRecordId: proofRecord.id,
})

await this.messageSender.sendMessageToService(
new OutboundMessageContext(message, {
agentContext: this.agentContext,
serviceParams: {
service: recipientService.resolvedDidCommService,
senderKey: ourService.resolvedDidCommService.recipientKeys[0],
returnRoute: true,
returnRoute: options.useReturnRoute ?? true, // defaults to true if missing
},
})
)

return proofRecord
}
// Cannot send message without connectionId or ~service decorator
Expand Down Expand Up @@ -495,7 +492,7 @@ export class ProofsApi<PPs extends ProofProtocol[]> implements ProofsApi<PPs> {
serviceParams: {
service: recipientService.resolvedDidCommService,
senderKey: ourService.resolvedDidCommService.recipientKeys[0],
returnRoute: true,
returnRoute: false, // hard wire to be false since it's the end of the protocol so not needed here
},
})
)
Expand Down
6 changes: 6 additions & 0 deletions packages/core/src/modules/proofs/ProofsApiOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,12 @@ export interface RequestProofOptions<PPs extends ProofProtocol[] = ProofProtocol
*/
export interface AcceptProofRequestOptions<PPs extends ProofProtocol[] = ProofProtocol[]> extends BaseOptions {
proofRecordId: string

/**
* whether to enable return routing on the send presentation message. This value only
* has an effect for connectionless exchanges.
*/
useReturnRoute?: boolean
proofFormats?: ProofFormatPayload<ProofFormatsFromProtocols<PPs>, 'acceptRequest'>

goalCode?: string
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ describe('V2 Connectionless Proofs - Indy', () => {
}
})

test('Faber starts with connection-less proof requests to Alice', async () => {
const connectionlessTest = async (returnRoute?: boolean) => {
const {
issuerAgent: faberAgent,
issuerReplay: faberReplay,
Expand Down Expand Up @@ -128,8 +128,9 @@ describe('V2 Connectionless Proofs - Indy', () => {
proofRecordId: aliceProofExchangeRecord.id,
})

await aliceAgent.proofs.acceptRequest({
aliceProofExchangeRecord = await aliceAgent.proofs.acceptRequest({
proofRecordId: aliceProofExchangeRecord.id,
useReturnRoute: returnRoute,
proofFormats: { indy: requestedCredentials.proofFormats.indy },
})

Expand All @@ -139,17 +140,24 @@ describe('V2 Connectionless Proofs - Indy', () => {
state: ProofState.PresentationReceived,
})

const sentPresentationMessage = aliceAgent.proofs.findPresentationMessage(aliceProofExchangeRecord.id)

// assert presentation is valid
expect(faberProofExchangeRecord.isVerified).toBe(true)

// Faber accepts presentation
await faberAgent.proofs.acceptPresentation({ proofRecordId: faberProofExchangeRecord.id })

// Alice waits till it receives presentation ack
// Alice waits until it receives presentation ack
aliceProofExchangeRecord = await waitForProofExchangeRecordSubject(aliceReplay, {
threadId: aliceProofExchangeRecord.threadId,
state: ProofState.Done,
})
return sentPresentationMessage
}

test('Faber starts with connection-less proof requests to Alice', async () => {
await connectionlessTest()
})

test('Faber starts with connection-less proof requests to Alice with auto-accept enabled', async () => {
Expand Down
5 changes: 3 additions & 2 deletions packages/core/src/modules/vc/W3cCredentialService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,9 +103,10 @@ export class W3cCredentialService {
*/
public async verifyCredential(
agentContext: AgentContext,
options: VerifyCredentialOptions,
verifyRevocationState = true
options: VerifyCredentialOptions
): Promise<W3cVerifyCredentialResult> {
const verifyRevocationState = options.verifyRevocationState ?? true

const suites = this.getSignatureSuitesForCredential(agentContext, options.credential)

const verifyOptions: Record<string, unknown> = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export interface SignCredentialOptions {
export interface VerifyCredentialOptions {
credential: W3cVerifiableCredential
proofPurpose?: ProofPurpose
verifyRevocationState?: boolean
}

export interface StoreCredentialOptions {
Expand Down
5 changes: 3 additions & 2 deletions packages/core/tests/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,11 +94,12 @@ export function getPostgresAgentOptions<AgentModules extends AgentModulesInput |
extraConfig: Partial<InitConfig> = {},
modules?: AgentModules
) {
const random = uuid().slice(0, 4)
const config: InitConfig = {
label: `Agent: ${name}`,
label: `Agent: ${name} - ${random}`,
walletConfig: {
// NOTE: IndySDK Postgres database per wallet doesn't support special characters/spaces in the wallet name
id: `PostGresWallet${name}`,
id: `PostgresWallet${name}${random}`,
key: `Key${name}`,
storage: {
type: 'postgres_storage',
Expand Down
16 changes: 9 additions & 7 deletions packages/indy-sdk/src/ledger/IndySdkPoolService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,12 +93,14 @@ export class IndySdkPoolService {

if (pools.length === 0) {
throw new IndySdkPoolNotConfiguredError(
"No indy ledgers configured. Provide at least one pool configuration in the 'indyLedgers' agent configuration"
'No indy ledgers configured. Provide at least one pool configuration in IndySdkModuleConfigOptions.networks'
)
}

const cache = agentContext.dependencyManager.resolve(CacheModuleConfig).cache
const cachedNymResponse = await cache.get<CachedDidResponse>(agentContext, `IndySdkPoolService:${did}`)
const cacheKey = `IndySdkPoolService:${did}`

const cachedNymResponse = await cache.get<CachedDidResponse>(agentContext, cacheKey)
const pool = this.pools.find((pool) => pool.didIndyNamespace === cachedNymResponse?.indyNamespace)

// If we have the nym response with associated pool in the cache, we'll use that
Expand Down Expand Up @@ -127,7 +129,7 @@ export class IndySdkPoolService {

// If there are self certified DIDs we always prefer it over non self certified DIDs
// We take the first self certifying DID as we take the order in the
// indyLedgers config as the order of preference of ledgers
// IndySdkModuleConfigOptions.networks config as the order of preference of ledgers
let value = successful.find((response) =>
isLegacySelfCertifiedDid(response.value.did.did, response.value.did.verkey)
)?.value
Expand All @@ -140,12 +142,12 @@ export class IndySdkPoolService {
const nonProduction = successful.filter((s) => !s.value.pool.config.isProduction)
const productionOrNonProduction = production.length >= 1 ? production : nonProduction

// We take the first value as we take the order in the indyLedgers config as
// the order of preference of ledgers
// We take the first value as we take the order in the IndySdkModuleConfigOptions.networks
// config as the order of preference of ledgers
value = productionOrNonProduction[0].value
}

await cache.set(agentContext, `IndySdkPoolService:${did}`, {
await cache.set(agentContext, cacheKey, {
nymResponse: value.did,
indyNamespace: value.pool.didIndyNamespace,
} satisfies CachedDidResponse)
Expand Down Expand Up @@ -174,7 +176,7 @@ export class IndySdkPoolService {
public getPoolForNamespace(indyNamespace?: string) {
if (this.pools.length === 0) {
throw new IndySdkPoolNotConfiguredError(
"No indy ledgers configured. Provide at least one pool configuration in the 'indyLedgers' agent configuration"
'No indy ledgers configured. Provide at least one pool configuration in IndySdkModuleConfigOptions.networks'
)
}

Expand Down
17 changes: 9 additions & 8 deletions packages/indy-vdr/src/pool/IndyVdrPoolService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,13 +69,14 @@ export class IndyVdrPoolService {

if (pools.length === 0) {
throw new IndyVdrNotConfiguredError(
"No indy ledgers configured. Provide at least one pool configuration in the 'indyLedgers' agent configuration"
'No indy ledgers configured. Provide at least one pool configuration in IndyVdrModuleConfigOptions.networks'
)
}

const didCache = agentContext.dependencyManager.resolve(CacheModuleConfig).cache
const cache = agentContext.dependencyManager.resolve(CacheModuleConfig).cache
const cacheKey = `IndyVdrPoolService:${did}`

const cachedNymResponse = await didCache.get<CachedDidResponse>(agentContext, `IndyVdrPoolService:${did}`)
const cachedNymResponse = await cache.get<CachedDidResponse>(agentContext, cacheKey)
const pool = this.pools.find((pool) => pool.indyNamespace === cachedNymResponse?.indyNamespace)

// If we have the nym response with associated pool in the cache, we'll use that
Expand Down Expand Up @@ -104,7 +105,7 @@ export class IndyVdrPoolService {

// If there are self certified DIDs we always prefer it over non self certified DIDs
// We take the first self certifying DID as we take the order in the
// indyLedgers config as the order of preference of ledgers
// IndyVdrModuleConfigOptions.networks config as the order of preference of ledgers
let value = successful.find((response) =>
isSelfCertifiedDid(response.value.did.nymResponse.did, response.value.did.nymResponse.verkey)
)?.value
Expand All @@ -117,12 +118,12 @@ export class IndyVdrPoolService {
const nonProduction = successful.filter((s) => !s.value.pool.config.isProduction)
const productionOrNonProduction = production.length >= 1 ? production : nonProduction

// We take the first value as we take the order in the indyLedgers config as
// the order of preference of ledgers
// We take the first value as we take the order in the IndyVdrModuleConfigOptions.networks
// config as the order of preference of ledgers
value = productionOrNonProduction[0].value
}

await didCache.set(agentContext, did, {
await cache.set(agentContext, cacheKey, {
nymResponse: {
did: value.did.nymResponse.did,
verkey: value.did.nymResponse.verkey,
Expand Down Expand Up @@ -153,7 +154,7 @@ export class IndyVdrPoolService {
public getPoolForNamespace(indyNamespace: string) {
if (this.pools.length === 0) {
throw new IndyVdrNotConfiguredError(
"No indy ledgers configured. Provide at least one pool configuration in the 'indyLedgers' agent configuration"
'No indy ledgers configured. Provide at least one pool configuration in IndyVdrModuleConfigOptions.networks'
)
}

Expand Down
3 changes: 2 additions & 1 deletion packages/openid4vc-client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@
},
"dependencies": {
"@aries-framework/core": "0.3.3",
"@sphereon/openid4vci-client": "^0.3.6"
"@sphereon/openid4vci-client": "^0.4.0",
"@stablelib/random": "^1.0.2"
},
"devDependencies": {
"@aries-framework/node": "0.3.3",
Expand Down
37 changes: 26 additions & 11 deletions packages/openid4vc-client/src/OpenId4VcClientApi.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
import type {
GenerateAuthorizationUrlOptions,
PreAuthCodeFlowOptions,
AuthCodeFlowOptions,
} from './OpenId4VcClientService'
import type { W3cCredentialRecord } from '@aries-framework/core'

import { AgentContext, injectable } from '@aries-framework/core'

import { OpenId4VcClientService } from './OpenId4VcClientService'

interface PreAuthorizedOptions {
issuerUri: string
kid: string
checkRevocationState?: boolean // default = true
}
import { AuthFlowType, OpenId4VcClientService } from './OpenId4VcClientService'

/**
* @public
Expand All @@ -23,13 +22,29 @@ export class OpenId4VcClientApi {
this.openId4VcClientService = openId4VcClientService
}

public async requestCredentialPreAuthorized(options: PreAuthorizedOptions): Promise<W3cCredentialRecord> {
public async requestCredentialUsingPreAuthorizedCode(options: PreAuthCodeFlowOptions): Promise<W3cCredentialRecord> {
// set defaults
const verifyRevocationState = options.verifyRevocationState ?? true

return this.openId4VcClientService.requestCredential(this.agentContext, {
...options,
verifyRevocationState: verifyRevocationState,
flowType: AuthFlowType.PreAuthorizedCodeFlow,
})
}

public async requestCredentialUsingAuthorizationCode(options: AuthCodeFlowOptions): Promise<W3cCredentialRecord> {
// set defaults
const checkRevocationState = options.checkRevocationState ?? true
const checkRevocationState = options.verifyRevocationState ?? true

return this.openId4VcClientService.requestCredentialPreAuthorized(this.agentContext, {
return this.openId4VcClientService.requestCredential(this.agentContext, {
...options,
checkRevocationState: checkRevocationState,
verifyRevocationState: checkRevocationState,
flowType: AuthFlowType.AuthorizationCodeFlow,
})
}

public async generateAuthorizationUrl(options: GenerateAuthorizationUrlOptions) {
return this.openId4VcClientService.generateAuthorizationUrl(options)
}
}
Loading

0 comments on commit 58e459a

Please sign in to comment.