---
# System prepended metadata

title: Actors

---

# Actors

## Query Service

Query service implements [upload protocol][] and is basically a request router responsible for decoding requests _(that arrive in [CAR][] format)_ into [UCAN invocation][]s and route enclosed operations to a relevant subservice.

:::info
CAR payload MAY contain multiple UCANs, which in turn MAY contain multiple [operations][] defined by a protocol
:::

:::warning
💭 I wonder we should limit one UCAN per one operation instead, we still can deduplicate using [CID][]s and share blocks by including them in the same [CAR][].
:::

Additionally service is also responsible for awaiting / listening on all operations to combine them back into a response _(which can be in form of event)_.

:::info
It is similar to [GraphQL][] intreface except queries are sent as [IPLD][] encoded [UCAN][]s in [CAR][] format. And responses are associated with queries by their [CID][].
:::



```ts
interface Writer<T> {
  add(T): Promise<void>
}

// UCAN represents 
interface UCAN<
  Capabilities extends Array<{can:string, with:string}> = {can:string, with:string}[],
  To extends DID = DID,
  From extends = DID,
  Proofs = UCAN<Capabilities, From, DID>[]
> {
  issuer: From
  audience: To
  expiry: Time
  notBefore?: Time
  capabilities: Capabilities
  proofs: Proofs
}

interface Revoke<ID extends CID<UCAN>> {
  issuer: DID
  revoke: ID
  challenge: Signature<PrivateKey<DID>, `REVOKE:${ID}`>
}

type Signature <PirvateKey, Message> = Uint8Array & Phantom
    


interface QueryService {
  query(query:CAR<Query>):unknown
}


type Query =
  | UCAN<[Identify]>
  | UCAN<[Authorize], DID, DID, [UCAN<[Identify]>]>
  | 
  
  
/**
 * Incoming requests are CAR encoded set of queries that
 * client may pack together for deduplication pursposes.
 */
export interface Request {
  cid: CID<CAR>
  body: CAR
}

/**
 * Queries are represented as IPLD encoded UCANs. Each
 * query may contain multiple operations encoded as
 * capabilities.
 */
export interface Query {
  cid: CID<UCAN>
  query: UCAN
}

/**
 *
 */
export type Capability =
 | Identify
 | Authorize
 | Revoke
 | Add
 | Remove
 
export interface Identify {
  can: "access/identify"
  with: DID
  as: Email
}

type DID = string
type Email = string

export interface Authorize {
  can: "access/authorize"
  with: DID
  capabilities?: Capability[]
}

export interface Revoke {
  can: "access/revoke"
  with: DID
  access:   
}

// Service saves every incoming (CAR encoded)
// request keyed by it's CID.
export type Requests = StoreWriter<{
  cid: CID<CAR>
  car: CAR
}>

// Service saves each (UCAN encoded) query from
// the car keyed by it's CID
export type Queries extends Writer<{
 cid: CID<UCAN>
 query: UCAN
 group: CID<CAR>
}>

export type Operations extends Writer<{
  cid: CID<Operation>
  // Operation Add / Remove MAY depend on
  // Identify
  requires?: CID<Identify>
  query: UCAN
}>

interface IO {
  /**
   *  Stores incoming (CAR encoded) request and returns correspnoding CID.
   */
  storeCAR(request:CAR): Promise<void>
  /**
   *
   */
  storeUCAN(request: UCAN): Promise<void>
}
```

## Store service

Store service is responsible for handling `{ can: "store/*" }"` capabilities of [upload protocol] service.





## Access service

Access service is responsible for handling `{ can: "access/*" }` capabilities of [upload protocol] service.


[upload protocol]:https://hackmd.io/@gozala/upload-protocol
[UCAN]:https://whitepaper.fission.codes/access-control/ucan
[did:key]:https://w3c-ccg.github.io/did-method-key/
[CAR]:https://ipld.io/specs/transport/car/carv1/
[UCAN invocation]:https://github.com/ucan-wg/spec#521-invocation-recipient-validation
[operations]:https://hackmd.io/@gozala/upload-protocol
[CID]:https://docs.ipfs.io/concepts/content-addressing/
[GraphQL]:https://graphql.org/
[IPLD]:https://ipld.io/