# Proof Exchanges

A proof exchange, represented by `AIPProofExchange`, is an encapsulation of the cloud agent's progress in either sending or receiving a credential presentation over an established DIDComm connection.

## Proof Exchange Roles & States

An `AIPProofExchange` has a role (known as `myRole`) and a `state` associated with it.

### Role

The role indicates which role the cloud agent plays in the proof exchange protocol. The role is fixed for the lifetime of the proof exchange.

Role is either:

`VERIFIER` or `PROVER`

### State

The state indicates the current state of the cloud agent in the proof exchange protocol. The state transitions over time in a forward direction and cannot transition to previous states.

State transitions to success:

`REQUEST` -> `PRESENTED` -> `DONE`

`PROPOSAL` -> `REQUEST` -> `PRESENTED` -> `DONE`

### Summary

The following table provides a description of each role and each role+state combination.

| Role       | State       | Description                                                                                                                                                                                                                                                                                                                    |
| ---------- | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `VERIFIER` |             | The cloud agent is acting as the verifier of the credential presentation.                                                                                                                                                                                                                                                      |
|            | `PROPOSAL`  | The connection proposed that it send a presentation to the cloud agent for verification.                                                                                                                                                                                                                                       |
|            | `REQUEST`   | The cloud agent sent a proof request (also known as a presentation request) to the connection. If this state was preceded by `PROPOSAL`, then the request may be based on the connection's proposal.                                                                                                                           |
|            | `PRESENTED` | The cloud agent received the presentation from the connection.                                                                                                                                                                                                                                                                 |
|            | `DONE`      | Terminal state for a successful proof exchange. The received presentation has undergone verification. Note that this state does not indicate the result of the verification. To check the verification result, see `verificationResult` on the `AIPProofPresentation` message which is embedded within the `AIPProofExchange`. |
|            | `ABANDONED` | Terminal state for an unsuccessful proof exchange. The cloud agent did ***not*** receive a presentation from the connection.                                                                                                                                                                                                   |
| `PROVER`   |             | The cloud agent is acting as the prover (also known as the holder or the presenter). The cloud agent will generate and send a verifiable presentation using one or more of its held credentials as a base.                                                                                                                     |
|            | `PROPOSAL`  | The cloud agent proposed that it send a presentation to a connection for verification.                                                                                                                                                                                                                                         |
|            | `REQUEST`   | The cloud agent received a proof request (also known as a presentation request) from the connection. If this state was preceded by `PROPOSAL`, then the request may be based on the cloud agent's proposal.                                                                                                                    |
|            | `PRESENTED` | The cloud agent sent the presentation to the connection.                                                                                                                                                                                                                                                                       |
|            | `DONE`      | Terminal state for a successful proof exchange. Note that the cloud agent with the role of `PROVER` does not receive any indication of the verification result.                                                                                                                                                                |
|            | `ABANDONED` | Terminal state for an unsuccessful proof exchange. The cloud agent did ***not*** send a presentation to the connection.                                                                                                                                                                                                        |

## Supported credential presentation formats

The cloud agent supports proof exchanges for both Anoncreds Verifiable Presentations and W3C Verifiable Presentations. The credential presentation format for the specific proof exchange is specified using the `format` nested object.

## Request proof

The cloud agent creates a new `AIPProofExchange` with role `VERIFIER` and send a proof request to the specified `connectionId`. The `format` input object must be filled with the details of the presentation to request.

A `referent` must be included for each set of attributes requested. The referent acts as an identifier for a set of attributes, and the prover must reference it in their subsequent presentation. If more than one referent appears in the same proof request, the prover will be able to present a different credential per referent.

```graphql
mutation MyMutation {
  sendAipProofRequest(
    connectionId: "001fe530-3562-41d6-a631-3df9c7ae1f38"
    request: {
      format: {
        # INSERT DETAILS OF THE PRESENTATION TO REQUEST
      }
    }
  ) {
    id
    myRole
    state
    connectionId
  }
}
```

If instead the cloud agent *receives* a proof request, a new `AIPProofExchange` is created with role `PROVER`.

## View received proof requests

View proof exchanges in any state, with pagination and filtering options. Returns a `nextToken` which can be passed into the same query in order to fetch subsequent pages.

As an example, the filter options can be used to find received proof requests, even from a specific connection.

```graphql
query MyQuery {
  aipProofExchanges(
    page: {
      nextToken: null
    }
    filter: {
      myProofExRole: PROVER
      proofExStates: [REQUEST]
      connectionIds: ["001fe530-3562-41d6-a631-3df9c7ae1f38"]
    }
  ) {
    items {
      id
      myRole
      state
      messages {
        request {
          comment
          format {
            __typename
            ... on AnoncredsProofRequest {
              attributeGroups {
                referent
                attributeNames
                restrictions {
                  schemaId
                  schemaIssuerId
                  schemaName
                  schemaVersion
                  credDefId
                  issuerId
                  attributeNames
                  attributeValues {
                    name
                    value
                  }
                  nonRevoked {
                    from
                    to
                  }
                  predicate {
                    operator
                    threshold
                  }
                }
              }
            }
            ... on W3CProofNegotiation {
              attributeGroups {
                referent
                attributes {
                  attributePaths
                  valueRestrictions {
                    dataFormat
                    pattern
                    inSet
                    notInSet
                    equal
                    notEqual
                    minLength
                    maxLength
                    lessThan
                    lessThanOrEqual
                    greaterThan
                    greaterThanOrEqual
                  }
                  isHolderSubject
                  presentationType
                }
              }
              submissionRequirementJsons
            }
          }
        }
      }
      connectionId
    }
    nextToken
  }
}
```

Alternatively, view a single proof exchange, referenced by its unique ID.

```graphql
query MyQuery {
  aipProofExchange(
    proofExId: "44269eb7-0288-46ad-ab59-e646ad010202"
  ) {
    id
    myRole
    state
    connectionId
  }
}
```

## Accept a proof request

Before accepting the proof request, the cloud agent must select which credentials to use in the presentation. The following call can be used to quickly identify held [credentials](https://docs.sudoplatform.com/guides/decentralized-identity/cloud-agent/cloud-agent-admin-api/credentials) which are valid for selection. The returned `referent` maps each set of credential IDs to a `referent` in the proof request. The array of returned `credentialIds` will be empty if the cloud agent does not possess any valid credential for that referent.

```graphql
mutation MyMutation {
  credentialsForAipProofExchange(
    proofExId: "44269eb7-0288-46ad-ab59-e646ad010202"
  ) {
    credentialsForReferents {
      referent
      credentialIds
    }
  }
}
```

The cloud agent accepts the request by generating the presentation and sending it to the connection. The input param `proofExId` must match the ID of an `AIPProofExchange` which has the `PROVER` role and is in the `REQUEST` state. Once the cloud agent with `PROVER` role has accepted a proof request, there is nothing left for it to do in the exchange.

```graphql
mutation MyMutation {
  acceptAipProofRequest(
    proofExId: "44269eb7-0288-46ad-ab59-e646ad010202"
    presentation: {
      format: {
        # INSERT DETAILS OF THE PRESENTATION TO SEND
      }
    }
  ) {
    id
    myRole
    state
    connectionId
  }
}
```

## Delete a proof exchange

Delete a proof exchange. This will send a "problem report" to the associated connection to inform them that the cloud agent has abandoned the proof exchange.

```graphql
mutation MyMutation {
  deleteAipProofExchange(
    credExId: "44269eb7-0288-46ad-ab59-e646ad010202"
  )
}
```
