# Connection Exchanges

A connection exchange, represented by `AIPConnectionExchange`, is an encapsulation of the cloud agent's progress in establishing a new DIDComm connection. A connection exchange starts with a connection invitation, then follows a relevant Aries protocol to communicate with the connecting party (a foreign agent) until either the connection is established or the protocol is aborted.

## Connection Exchange Roles & States

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

### Role

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

Role is either:

`INVITER` or `INVITEE`

### State

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

State transitions to success:

`INVITATION` -> `REQUEST` -> `RESPONSE` -> `DONE`

### Summary

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

| Role      | State        | Description                                                                                   |
| --------- | ------------ | --------------------------------------------------------------------------------------------- |
| `INVITER` |              | The connection exchange was initiated by the cloud agent.                                     |
|           | `INVITATION` | The cloud agent sent a connection invitation.                                                 |
|           | `REQUEST`    | The cloud agent received a connection request.                                                |
|           | `RESPONSE`   | The cloud agent sent a response to a connection request.                                      |
|           | `DONE`       | Terminal state for a successful connection exchange. A `Connection` was created.              |
|           | `ABANDONED`  | Terminal state for an unsuccessful connection exchange. A `Connection` was ***not*** created. |
| `INVITEE` |              | The connection exchange was initiated by a foreign agent.                                     |
|           | `INVITATION` | The cloud agent received a connection invitation.                                             |
|           | `REQUEST`    | The cloud agent sent a connection request.                                                    |
|           | `RESPONSE`   | The cloud agent received a response to its connection request.                                |
|           | `DONE`       | Terminal state for a successful connection exchange. A `Connection` was created.              |
|           | `ABANDONED`  | Terminal state for an unsuccessful connection exchange. A `Connection` was ***not*** created. |

## Create connection exchange

The cloud agent creates a new `AIPConnectionExchange` with a single-use invitation embedded within. The generated `invitationUrl` must be sent to its intended recipient out-of-band, for instance, via a QR code for the recipient to scan with their DI wallet. The connection exchange will be visible to the cloud agent under the `alias` "Bob". Any foreign agent who views the invitation will see that it was created by "Alice" (this is an unverifiable, self-attested label). Once a foreign agent has responded to the invitation, the invitation will be invalidated. In this scenario, the cloud agent has role `INVITER`.

```graphql
mutation MyMutation {
  createAipConnectionInvitation(
    invitation: {
      alias: "Bob"
      myLabel: "Alice"
    }
  ) {
    id
    myRole
    state
    alias
    theirLabel
    invitation {
      invitationUrl
    }
  }
}
```

## Accept connection invitation

The cloud agent receives the connection invitation, creates a new `AIPConnectionExchange` and then accepts the invitation in a single operation. The received `invitationUrl` is stored for future reference. The connection exchange will be visible to the cloud agent under the `alias` "Alice". In communications with the foreign agent, the cloud agent will present itself as "Bob" (this is an unverifiable, self-attested label). In this scenario, the cloud agent has role `INVITEE`.

```graphql
mutation MyMutation {
  acceptAipConnectionInvitation(
    invitation: {
      invitationUrl: "https://example.com?c_i=<base64_encoded_invitation>"
      alias: "Alice"
      myLabel: "Bob"
    }
  ) {
    id
    myRole
    state
    alias
    theirLabel
    invitation {
      invitationUrl
    }
  }
}
```

## View connection exchanges

View connection 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.

```graphql
query MyQuery {
  aipConnectionExchanges(
    page: {
      nextToken: null
    }
    filter: {}
  ) {
    items {
      id
      myRole
      state
      alias
      theirLabel
    }
    nextToken
  }
}
```

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

```graphql
query MyQuery {
  aipConnectionExchange(
    connExId: "001fe530-3562-41d6-a631-3df9c7ae1f38"
  ) {
    id
    myRole
    state
    alias
    theirLabel
  }
}
```

## Delete a connection exchange

Delete a connection exchange along with its embedded invitation. Note that if the connection exchange is in the `DONE` state, the resultant `Connection` is ***not*** deleted by this operation.

```graphql
mutation MyMutation {
  deleteAipConnectionExchange(
    connExId: "001fe530-3562-41d6-a631-3df9c7ae1f38"
  )
}
```
