Skip to content

Commit

Permalink
feat: Proof Negotiation
Browse files Browse the repository at this point in the history
Signed-off-by: Łukasz Przytuła <lprzytula@gmail.com>
  • Loading branch information
Przytua committed Nov 29, 2022
1 parent d82ad01 commit 669b2c1
Show file tree
Hide file tree
Showing 3 changed files with 902 additions and 0 deletions.
87 changes: 87 additions & 0 deletions packages/core/src/modules/proofs/ProofsApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import type {
ProposeProofOptions,
RequestProofOptions,
ProofServiceMap,
ProposeProofAsResponseOptions,
RequestProofAsResponseOptions,
} from './ProofsApiOptions'
import type { ProofFormat } from './formats/ProofFormat'
import type { IndyProofFormat } from './formats/indy/IndyProofFormat'
Expand All @@ -28,6 +30,7 @@ import type {
FormatRetrievedCredentialOptions,
DeleteProofOptions,
GetFormatDataReturn,
CreateProposalAsResponseOptions,
} from './models/ProofServiceOptions'
import type { ProofExchangeRecord } from './repository/ProofExchangeRecord'

Expand Down Expand Up @@ -56,10 +59,12 @@ import { ProofRepository } from './repository/ProofRepository'
export interface ProofsApi<PFs extends ProofFormat[], PSs extends ProofService<PFs>[]> {
// Proposal methods
proposeProof(options: ProposeProofOptions<PFs, PSs>): Promise<ProofExchangeRecord>
proposeProofAsResponse(options: ProposeProofAsResponseOptions<PFs>): Promise<ProofExchangeRecord>
acceptProposal(options: AcceptProofProposalOptions): Promise<ProofExchangeRecord>

// Request methods
requestProof(options: RequestProofOptions<PFs, PSs>): Promise<ProofExchangeRecord>
requestProofAsResponse(options: RequestProofAsResponseOptions<PFs>): Promise<ProofExchangeRecord>
acceptRequest(options: AcceptProofPresentationOptions<PFs>): Promise<ProofExchangeRecord>
declineRequest(proofRecordId: string): Promise<ProofExchangeRecord>

Expand Down Expand Up @@ -191,6 +196,47 @@ export class ProofsApi<
return proofRecord
}

/**
* Answer with a new presentation proposal in response to received presentation request message
* to the connection associated with the proof record.
*
* @param options multiple properties like proof record id, proof format (indy/ presentation exchange)
* to include in the message
* @returns Proof record associated with the sent proposal message
*/
public async proposeProofAsResponse(options: ProposeProofAsResponseOptions<PFs>): Promise<ProofExchangeRecord> {
const { proofRecordId } = options
const proofRecord = await this.getById(proofRecordId)

const service = this.getService(proofRecord.protocolVersion)

if (!proofRecord.connectionId) {
throw new AriesFrameworkError(
`No connectionId found for credential record '${proofRecord.id}'. Connection-less issuance does not support presentation proposal or negotiation.`
)
}

const connection = await this.connectionService.getById(this.agentContext, proofRecord.connectionId)

// Assert
connection.assertReady()

const proposalOptions: CreateProposalAsResponseOptions<PFs> = {
proofRecord,
proofFormats: options.proofFormats,
autoAcceptProof: options.autoAcceptProof,
goalCode: options.goalCode,
comment: options.comment,
}

const { message } = await service.createProposalAsResponse(this.agentContext, proposalOptions)

const outbound = createOutboundMessage(connection, message)
await this.messageSender.sendMessage(this.agentContext, outbound)

return proofRecord
}

/**
* Accept a presentation proposal as verifier (by sending a presentation request message) to the connection
* associated with the proof record.
Expand All @@ -200,6 +246,7 @@ export class ProofsApi<
*/
public async acceptProposal(options: AcceptProofProposalOptions): Promise<ProofExchangeRecord> {
const { proofRecordId } = options

const proofRecord = await this.getById(proofRecordId)

const service = this.getService(proofRecord.protocolVersion)
Expand Down Expand Up @@ -270,6 +317,46 @@ export class ProofsApi<
return proofRecord
}

/**
* Answer with a new presentation request in response to received presentation proposal message
* to the connection associated with the proof record.
*
* @param options multiple properties like proof record id, proof formats to accept requested credentials object
* specifying which credentials to use for the proof
* @returns Proof record associated with the sent request message
*/
public async requestProofAsResponse(options: RequestProofAsResponseOptions<PFs>): Promise<ProofExchangeRecord> {
const { proofRecordId } = options

const proofRecord = await this.getById(proofRecordId)

const service = this.getService(proofRecord.protocolVersion)

if (!proofRecord.connectionId) {
throw new AriesFrameworkError(
`No connectionId found for credential record '${proofRecord.id}'. Connection-less issuance does not support negotiation.`
)
}

const connection = await this.connectionService.getById(this.agentContext, proofRecord.connectionId)

// Assert
connection.assertReady()

const requestOptions: CreateRequestAsResponseOptions<PFs> = {
proofRecord,
proofFormats: options.proofFormats,
autoAcceptProof: options.autoAcceptProof,
comment: options.comment,
}
const { message } = await service.createRequestAsResponse(this.agentContext, requestOptions)

const outbound = createOutboundMessage(connection, message)
await this.messageSender.sendMessage(this.agentContext, outbound)

return proofRecord
}

/**
* Accept a presentation request as prover (by sending a presentation message) to the connection
* associated with the proof record.
Expand Down
17 changes: 17 additions & 0 deletions packages/core/src/modules/proofs/ProofsApiOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,15 @@ export interface ProposeProofOptions<
autoAcceptProof?: AutoAcceptProof
parentThreadId?: string
}

export interface ProposeProofAsResponseOptions<PFs extends ProofFormat[] = ProofFormat[]> {
proofRecordId: string
proofFormats: ProofFormatPayload<PFs, 'createProposalAsResponse'>
comment?: string
goalCode?: string
autoAcceptProof?: AutoAcceptProof
}

export interface AcceptProofPresentationOptions<PFs extends ProofFormat[] = ProofFormat[]> {
proofRecordId: string
comment?: string
Expand All @@ -68,6 +77,14 @@ export interface RequestProofOptions<
parentThreadId?: string
}

export interface RequestProofAsResponseOptions<PFs extends ProofFormat[] = ProofFormat[]> {
proofRecordId: string
proofFormats: ProofFormatPayload<PFs, 'createRequestAsResponse'>
comment?: string
autoAcceptProof?: AutoAcceptProof
parentThreadId?: string
}

export interface CreateProofRequestOptions<
PFs extends ProofFormat[] = ProofFormat[],
PSs extends ProofService[] = ProofService[]
Expand Down
Loading

0 comments on commit 669b2c1

Please sign in to comment.