From 1754dd69acf8df01580fc9fc2cc177c494b85d66 Mon Sep 17 00:00:00 2001
From: Leo Ribeiro <leordev@gmail.com>
Date: Fri, 3 Nov 2023 09:19:47 -0400
Subject: [PATCH] Install `tbdocs` for the `@web5/api` package (#251)

* Install tbdocs for @web5/api

---------

Co-authored-by: Frank Hinek <frankhinek@users.noreply.github.com>
---
 .github/workflows/tests-ci.yml   |  33 ++++++++++
 packages/api/src/did-api.ts      |   6 ++
 packages/api/src/dwn-api.ts      | 106 +++++++++++++++++++++++++----
 packages/api/src/index.ts        |  29 +++++++-
 packages/api/src/protocol.ts     |  29 ++++++++
 packages/api/src/record.ts       | 110 ++++++++++++++++++++++++++-----
 packages/api/src/tech-preview.ts |   2 +
 packages/api/src/utils.ts        |   2 +
 packages/api/src/vc-api.ts       |   8 +++
 packages/api/src/web5.ts         |  39 +++++++++--
 10 files changed, 327 insertions(+), 37 deletions(-)

diff --git a/.github/workflows/tests-ci.yml b/.github/workflows/tests-ci.yml
index cf98b6b5f..04c379a58 100644
--- a/.github/workflows/tests-ci.yml
+++ b/.github/workflows/tests-ci.yml
@@ -107,3 +107,36 @@ jobs:
         run: npm run test:browser --ws -- --color
         env:
           TEST_DWN_URL: http://localhost:3000
+
+  tbdocs-reporter:
+    runs-on: ubuntu-latest
+    steps:
+      - name: Checkout source
+        uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2
+
+      - name: Set up Node.js
+        uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # v3.6.0
+        with:
+          node-version: 18
+          registry-url: https://registry.npmjs.org/
+
+      - name: Install latest npm
+        run: npm install -g npm@latest
+
+      - name: Install dependencies
+        run: npm ci
+
+      - name: Build all workspace packages
+        run: npm run build
+
+      - name: TBDocs Reporter
+        id: tbdocs-reporter-protocol
+        uses: TBD54566975/tbdocs@main
+        with:
+          token: ${{ secrets.GITHUB_TOKEN }}
+          report_changed_scope_only: false
+          fail_on_error: false
+          entry_points: |
+            - file: packages/api/src/index.ts
+              docsReporter: api-extractor
+              docsGenerator: typedoc-markdown
diff --git a/packages/api/src/did-api.ts b/packages/api/src/did-api.ts
index d28474556..ab51e3f87 100644
--- a/packages/api/src/did-api.ts
+++ b/packages/api/src/did-api.ts
@@ -28,6 +28,12 @@ import type { Web5Agent } from '@web5/agent';
 //   didMethodApis: DidMethodApi[];
 //   cache?: DidResolverCache;
 // }
+
+/**
+ * The DID API is used to create and resolve DIDs.
+ *
+ * @beta
+ */
 export class DidApi {
   // private didResolver: DidResolver;
   // private methodCreatorMap: Map<string, DidMethodCreator> = new Map();
diff --git a/packages/api/src/dwn-api.ts b/packages/api/src/dwn-api.ts
index 11bccc120..8ce82ec0f 100644
--- a/packages/api/src/dwn-api.ts
+++ b/packages/api/src/dwn-api.ts
@@ -20,33 +20,73 @@ import { Record } from './record.js';
 import { Protocol } from './protocol.js';
 import { dataToBlob } from './utils.js';
 
+/**
+ * Request to setup a protocol with its definitions
+ *
+ * @beta
+ */
 export type ProtocolsConfigureRequest = {
   message: Omit<ProtocolsConfigureOptions, 'authorizationSigner'>;
 }
 
+/**
+ * Response for the protocol configure request
+ *
+ * @beta
+ */
 export type ProtocolsConfigureResponse = {
   status: UnionMessageReply['status'];
   protocol?: Protocol;
 }
 
+/**
+ * Represents each entry on the protocols query reply
+ *
+ * @beta
+ */
 export type ProtocolsQueryReplyEntry = {
   descriptor: ProtocolsConfigureDescriptor;
 };
 
+/**
+ * Request to query protocols
+ *
+ * @beta
+ */
 export type ProtocolsQueryRequest = {
   from?: string;
   message: Omit<ProtocolsQueryOptions, 'authorizationSigner'>
 }
 
+/**
+ * Response with the retrieved protocols
+ *
+ * @beta
+ */
 export type ProtocolsQueryResponse = {
   protocols: Protocol[];
   status: UnionMessageReply['status'];
 }
 
+/**
+ * Type alias for {@link RecordsWriteRequest}
+ *
+ * @beta
+ */
 export type RecordsCreateRequest = RecordsWriteRequest;
 
+/**
+ * Type alias for {@link RecordsWriteResponse}
+ *
+ * @beta
+ */
 export type RecordsCreateResponse = RecordsWriteResponse;
 
+/**
+ * Request to create a record from an existing one (useful for updating an existing record)
+ *
+ * @beta
+ */
 export type RecordsCreateFromRequest = {
   author: string;
   data: unknown;
@@ -54,50 +94,92 @@ export type RecordsCreateFromRequest = {
   record: Record;
 }
 
+/**
+ * Request to delete a record from the DWN
+ *
+ * @beta
+ */
 export type RecordsDeleteRequest = {
   from?: string;
   message: Omit<RecordsDeleteOptions, 'authorizationSigner'>;
 }
 
+/**
+ * Response for the delete request
+ *
+ * @beta
+ */
 export type RecordsDeleteResponse = {
   status: UnionMessageReply['status'];
 };
 
+/**
+ * Request to query records from the DWN
+ *
+ * @beta
+ */
 export type RecordsQueryRequest = {
   /** The from property indicates the DID to query from and return results. */
   from?: string;
   message: Omit<RecordsQueryOptions, 'authorizationSigner'>;
 }
 
+/**
+ * Response for the query request
+ *
+ * @beta
+ */
 export type RecordsQueryResponse = {
   status: UnionMessageReply['status'];
   records?: Record[]
 };
 
+/**
+ * Request to read a record from the DWN
+ *
+ * @beta
+ */
 export type RecordsReadRequest = {
   /** The from property indicates the DID to read from and return results fro. */
   from?: string;
   message: Omit<RecordsReadOptions, 'authorizationSigner'>;
 }
 
+/**
+ * Response for the read request
+ *
+ * @beta
+ */
 export type RecordsReadResponse = {
   status: UnionMessageReply['status'];
   record: Record;
 };
 
+/**
+ * Request to write a record to the DWN
+ *
+ * @beta
+ */
 export type RecordsWriteRequest = {
   data: unknown;
   message?: Omit<Partial<RecordsWriteOptions>, 'authorizationSigner'>;
   store?: boolean;
 }
 
+/**
+ * Response for the write request
+ *
+ * @beta
+ */
 export type RecordsWriteResponse = {
   status: UnionMessageReply['status'];
   record?: Record
 };
 
 /**
- * TODO: Document class.
+ * Interface to interact with DWN Records and Protocols
+ *
+ * @beta
  */
 export class DwnApi {
   private agent: Web5Agent;
@@ -109,12 +191,12 @@ export class DwnApi {
   }
 
   /**
- * TODO: Document namespace.
- */
+   * API to interact with DWN protocols (e.g., `dwn.protocols.configure()`).
+   */
   get protocols() {
     return {
       /**
-       * TODO: Document method.
+       * Configure method, used to setup a new protocol (or update) with the passed definitions
        */
       configure: async (request: ProtocolsConfigureRequest): Promise<ProtocolsConfigureResponse> => {
         const agentResponse = await this.agent.processDwnRequest({
@@ -136,7 +218,7 @@ export class DwnApi {
       },
 
       /**
-       * TODO: Document method.
+       * Query the available protocols
        */
       query: async (request: ProtocolsQueryRequest): Promise<ProtocolsQueryResponse> => {
         const agentRequest = {
@@ -171,19 +253,19 @@ export class DwnApi {
   }
 
   /**
-   * TODO: Document namespace.
+   * API to interact with DWN records (e.g., `dwn.records.create()`).
    */
   get records() {
     return {
       /**
-       * TODO: Document method.
+       * Alias for the `write` method
        */
       create: async (request: RecordsCreateRequest): Promise<RecordsCreateResponse> => {
         return this.records.write(request);
       },
 
       /**
-       * TODO: Document method.
+       * Write a record based on an existing one (useful for updating an existing record)
        */
       createFrom: async (request: RecordsCreateFromRequest): Promise<RecordsWriteResponse> => {
         const { author: inheritedAuthor, ...inheritedProperties } = request.record.toJSON();
@@ -221,7 +303,7 @@ export class DwnApi {
       },
 
       /**
-       * TODO: Document method.
+       * Delete a record
        */
       delete: async (request: RecordsDeleteRequest): Promise<RecordsDeleteResponse> => {
         const agentRequest = {
@@ -253,7 +335,7 @@ export class DwnApi {
       },
 
       /**
-       * TODO: Document method.
+       * Query a single or multiple records based on the given filter
        */
       query: async (request: RecordsQueryRequest): Promise<RecordsQueryResponse> => {
         const agentRequest = {
@@ -287,7 +369,7 @@ export class DwnApi {
       },
 
       /**
-       * TODO: Document method.
+       * Read a single record based on the given filter
        */
       read: async (request: RecordsReadRequest): Promise<RecordsReadResponse> => {
         const agentRequest = {
@@ -331,7 +413,7 @@ export class DwnApi {
       },
 
       /**
-       * TODO: Document method.
+       * Writes a record to the DWN
        *
        * As a convenience, the Record instance returned will cache a copy of the data if the
        * data size, in bytes, is less than the DWN 'max data size allowed to be encoded'
diff --git a/packages/api/src/index.ts b/packages/api/src/index.ts
index 7d4221c35..9c420aba6 100644
--- a/packages/api/src/index.ts
+++ b/packages/api/src/index.ts
@@ -1,8 +1,33 @@
+/**
+ * Making developing with Web5 components at least 5 times easier to work with.
+ *
+ * Web5 consists of the following components:
+ * - Decentralized Identifiers
+ * - Verifiable Credentials
+ * - DWeb Node personal datastores
+ *
+ * The SDK sets out to gather the most oft used functionality from all three of
+ * these pillar technologies to provide a simple library that is as close to
+ * effortless as possible.
+ *
+ * The SDK is currently still under active development, but having entered the
+ * Tech Preview phase there is now a drive to avoid unnecessary changes unless
+ * backwards compatibility is provided. Additional functionality will be added
+ * in the lead up to 1.0 final, and modifications will be made to address
+ * issues and community feedback.
+ *
+ * [Link to GitHub Repo](https://github.com/TBD54566975/web5-js)
+ *
+ * @packageDocumentation
+ */
+
 export * from './did-api.js';
 export * from './dwn-api.js';
 export * from './protocol.js';
 export * from './record.js';
-export * as utils from './utils.js';
 export * from './vc-api.js';
 export * from './web5.js';
-export * from './tech-preview.js';
\ No newline at end of file
+export * from './tech-preview.js';
+
+import * as utils from './utils.js';
+export { utils };
\ No newline at end of file
diff --git a/packages/api/src/protocol.ts b/packages/api/src/protocol.ts
index c22181eb3..8d15f5c82 100644
--- a/packages/api/src/protocol.ts
+++ b/packages/api/src/protocol.ts
@@ -2,17 +2,38 @@ import type { Web5Agent } from '@web5/agent';
 import type { ProtocolsConfigure } from '@tbd54566975/dwn-sdk-js';
 
 // TODO: export ProtocolsConfigureMessage from dwn-sdk-js
+/**
+ * The protocol configure message carries the protocol definition and is used
+ * to setup the protocol.
+ *
+ * @beta
+ */
 export type ProtocolsConfigureMessage = ProtocolsConfigure['message'];
+
+/**
+ * Metadata of the protocol
+ *
+ * @beta
+ */
 type ProtocolMetadata = {
   author: string;
   messageCid?: string;
 };
 
+/**
+ * The Protocol API abstraction class. It's used to represent and retrieve a protocol and
+ * also to install (send) protocols to other DIDs.
+ *
+ * @beta
+ */
 export class Protocol {
   private _agent: Web5Agent;
   private _metadata: ProtocolMetadata;
   private _protocolsConfigureMessage: ProtocolsConfigureMessage;
 
+  /**
+   * The protocol definition: types, structure and publish status
+   */
   get definition() {
     return this._protocolsConfigureMessage.descriptor.definition;
   }
@@ -23,10 +44,18 @@ export class Protocol {
     this._protocolsConfigureMessage = protocolsConfigureMessage;
   }
 
+  /**
+   * Returns the protocol as a JSON object.
+   */
   toJSON() {
     return this._protocolsConfigureMessage;
   }
 
+  /**
+   * Sends the protocol to a remote DWN by specifying their DID
+   * @param target - the DID to send the protocol to
+   * @returns the status of the send protocols request
+   */
   async send(target: string) {
     const { reply } = await this._agent.sendDwnRequest({
       author      : this._metadata.author,
diff --git a/packages/api/src/record.ts b/packages/api/src/record.ts
index a3a72e8fa..2ef88634c 100644
--- a/packages/api/src/record.ts
+++ b/packages/api/src/record.ts
@@ -8,6 +8,11 @@ import { DataStream, DwnInterfaceName, DwnMethodName, Encoder } from '@tbd545669
 import { dataToBlob } from './utils.js';
 import type { RecordsDeleteResponse } from './dwn-api.js';
 
+/**
+ * Options that are passed to Record constructor.
+ *
+ * @beta
+ */
 export type RecordOptions = RecordsWriteMessage & {
   author: string;
   target: string;
@@ -15,6 +20,12 @@ export type RecordOptions = RecordsWriteMessage & {
   data?: Readable | ReadableStream;
 };
 
+/**
+ * Represents the record data model, without the auxiliary properties such as
+ * the `descriptor` and the `authorization`
+ *
+ * @beta
+ */
 export type RecordModel = RecordsWriteDescriptor
   & Omit<RecordsWriteMessage, 'descriptor' | 'recordId' | 'authorization'>
   & {
@@ -23,6 +34,11 @@ export type RecordModel = RecordsWriteDescriptor
     target: string;
   }
 
+/**
+ * Options that are passed to update the record on the DWN
+ *
+ * @beta
+ */
 export type RecordUpdateOptions = {
   data?: unknown;
   dataCid?: RecordsWriteDescriptor['dataCid'];
@@ -33,19 +49,28 @@ export type RecordUpdateOptions = {
 }
 
 /**
-   * TODO: Document class.
-   *
-   * Note: The `messageTimestamp` of the most recent RecordsWrite message is
-   *       logically equivalent to the date/time at which a Record was most
-   *       recently modified.  Since this Record class implementation is
-   *       intended to simplify the developer experience of working with
-   *       logical records (and not individual DWN messages) the
-   *       `messageTimestamp` is mapped to `dateModified`.
-   */
+ * Record wrapper class with convenience methods to send, update,
+ * and delete itself, aside from manipulating and reading the record data.
+ *
+ * Note: The `messageTimestamp` of the most recent RecordsWrite message is
+ *       logically equivalent to the date/time at which a Record was most
+ *       recently modified.  Since this Record class implementation is
+ *       intended to simplify the developer experience of working with
+ *       logical records (and not individual DWN messages) the
+ *       `messageTimestamp` is mapped to `dateModified`.
+ *
+ * @beta
+ */
 export class Record implements RecordModel {
   // mutable properties
+
+  /** Record's author */
   author: string;
+
+  /** Record's target (for sent records) */
   target: string;
+
+  /** Record deleted status */
   isDeleted = false;
 
   private _agent: Web5Agent;
@@ -58,26 +83,64 @@ export class Record implements RecordModel {
   private _recordId: string;
 
   // Immutable DWN Record properties.
+
+  /** Record's signatures attestation */
   get attestation(): RecordsWriteMessage['attestation'] { return this._attestation; }
+
+  /** Record's context ID */
   get contextId() { return this._contextId; }
+
+  /** Record's data format */
   get dataFormat() { return this._descriptor.dataFormat; }
+
+  /** Record's creation date */
   get dateCreated() { return this._descriptor.dateCreated; }
+
+  /** Record's encryption */
   get encryption(): RecordsWriteMessage['encryption'] { return this._encryption; }
+
+  /** Record's ID */
   get id() { return this._recordId; }
+
+  /** Interface is always `Records` */
   get interface() { return this._descriptor.interface; }
+
+  /** Method is always `Write` */
   get method() { return this._descriptor.method; }
+
+  /** Record's parent ID */
   get parentId() { return this._descriptor.parentId; }
+
+  /** Record's protocol */
   get protocol() { return this._descriptor.protocol; }
+
+  /** Record's protocol path */
   get protocolPath() { return this._descriptor.protocolPath; }
+
+  /** Record's recipient */
   get recipient() { return this._descriptor.recipient; }
+
+  /** Record's schema */
   get schema() { return this._descriptor.schema; }
 
   // Mutable DWN Record properties.
+
+  /** Record's CID */
   get dataCid() { return this._descriptor.dataCid; }
+
+  /** Record's data size */
   get dataSize() { return this._descriptor.dataSize; }
+
+  /** Record's modified date */
   get dateModified() { return this._descriptor.messageTimestamp; }
+
+  /** Record's published date */
   get datePublished() { return this._descriptor.datePublished; }
+
+  /** Record's published status */
   get messageTimestamp() { return this._descriptor.messageTimestamp; }
+
+  /** Record's published status (true/false) */
   get published() { return this._descriptor.published; }
 
   constructor(agent: Web5Agent, options: RecordOptions) {
@@ -107,7 +170,11 @@ export class Record implements RecordModel {
   }
 
   /**
-   * TODO: Document method.
+   * Returns the data of the current record.
+   * If the record data is not available, it attempts to fetch the data from the DWN.
+   * @returns a data stream with convenience methods such as `blob()`, `json()`, `text()`, and `stream()`, similar to the fetch API response
+   * @throws `Error` if the record has already been deleted.
+   *
    */
   get data() {
     if (this.isDeleted) throw new Error('Operation failed: Attempted to access `data` of a record that has already been deleted.');
@@ -172,7 +239,9 @@ export class Record implements RecordModel {
   }
 
   /**
-   * TODO: Document method.
+   * Delete the current record from the DWN.
+   * @returns the status of the delete request
+   * @throws `Error` if the record has already been deleted.
    */
   async delete(): Promise<RecordsDeleteResponse> {
     if (this.isDeleted) throw new Error('Operation failed: Attempted to call `delete()` on a record that has already been deleted.');
@@ -196,7 +265,11 @@ export class Record implements RecordModel {
   }
 
   /**
-   * TODO: Document method.
+   * Send the current record to a remote DWN by specifying their DID
+   * (vs waiting for the regular DWN sync)
+   * @param target - the DID to send the record to
+   * @returns the status of the send record request
+   * @throws `Error` if the record has already been deleted.
    */
   async send(target: string): Promise<any> {
     if (this.isDeleted) throw new Error('Operation failed: Attempted to call `send()` on a record that has already been deleted.');
@@ -213,9 +286,8 @@ export class Record implements RecordModel {
   }
 
   /**
-   * TODO: Document method.
-   *
-   * Called by `JSON.stringify(...)` automatically.
+   * Returns a JSON representation of the Record instance.
+   * It's called by `JSON.stringify(...)` automatically.
    */
   toJSON(): RecordModel {
     return {
@@ -243,8 +315,7 @@ export class Record implements RecordModel {
   }
 
   /**
-   * TODO: Document method.
-   *
+   * Convenience method to return the string representation of the Record instance.
    * Called automatically in string concatenation, String() type conversion, and template literals.
    */
   toString() {
@@ -263,7 +334,10 @@ export class Record implements RecordModel {
   }
 
   /**
-   * TODO: Document method.
+   * Update the current record on the DWN.
+   * @param options - options to update the record, including the new data
+   * @returns the status of the update request
+   * @throws `Error` if the record has already been deleted.
    */
   async update(options: RecordUpdateOptions = {}) {
     if (this.isDeleted) throw new Error('Operation failed: Attempted to call `update()` on a record that has already been deleted.');
diff --git a/packages/api/src/tech-preview.ts b/packages/api/src/tech-preview.ts
index 071636f3d..227c4a9f0 100644
--- a/packages/api/src/tech-preview.ts
+++ b/packages/api/src/tech-preview.ts
@@ -3,6 +3,8 @@ import * as didUtils from '@web5/dids/utils';
 /**
  * Dynamically selects up to 2 DWN endpoints that are provided
  * by default during the Tech Preview period.
+ *
+ * @beta
  */
 export async function getTechPreviewDwnEndpoints(): Promise<string[]> {
   let response: Response;
diff --git a/packages/api/src/utils.ts b/packages/api/src/utils.ts
index 18048903f..bb8c3d8e5 100644
--- a/packages/api/src/utils.ts
+++ b/packages/api/src/utils.ts
@@ -2,6 +2,8 @@ import { Convert, universalTypeOf } from '@web5/common';
 
 /**
  * Set/detect the media type and return the data as bytes.
+ *
+ * @beta
  */
 export const dataToBlob = (data: any, dataFormat?: string) => {
   let dataBlob: Blob;
diff --git a/packages/api/src/vc-api.ts b/packages/api/src/vc-api.ts
index 7dd6620e1..ccf346be2 100644
--- a/packages/api/src/vc-api.ts
+++ b/packages/api/src/vc-api.ts
@@ -1,5 +1,10 @@
 import type { Web5Agent } from '@web5/agent';
 
+/**
+ * The VC API is used to issue, present and verify VCs
+ *
+ * @beta
+ */
 export class VcApi {
   private agent: Web5Agent;
   private connectedDid: string;
@@ -9,6 +14,9 @@ export class VcApi {
     this.connectedDid = options.connectedDid;
   }
 
+  /**
+   * Issues a VC (Not implemented yet)
+   */
   async create() {
     // TODO: implement
     throw new Error('Not implemented.');
diff --git a/packages/api/src/web5.ts b/packages/api/src/web5.ts
index ee32880bc..1431e0d4a 100644
--- a/packages/api/src/web5.ts
+++ b/packages/api/src/web5.ts
@@ -11,6 +11,8 @@ import { DidIonMethod } from '@web5/dids';
 
 /**
  * Override defaults configured during the technical preview phase.
+ *
+ * @beta
  */
 export type TechPreviewOptions = {
   // Override default dwnEndpoints provided for technical preview.
@@ -19,16 +21,22 @@ export type TechPreviewOptions = {
 
 /**
  * Optional overrides that can be provided when calling {@link Web5.connect}.
+ *
+ * @beta
  */
 export type Web5ConnectOptions = {
-  /** Provide a {@link Web5Agent} implementation. Defaults to creating a local
-   * {@link Web5UserAgent} if one isn't provided */
+  /**
+   * Provide a {@link @web5/agent#Web5Agent} implementation. Defaults to creating a local
+   * {@link @web5/user-agent#Web5UserAgent} if one isn't provided
+   **/
   agent?: Web5Agent;
 
-  /** Provide an instance of a {@link AppDataStore} implementation. Defaults to
+  /**
+   * Provide an instance of a {@link @web5/agent#AppDataStore} implementation. Defaults to
    * a LevelDB-backed store with an insecure, static unlock passphrase if one
    * isn't provided. To allow the app user to enter a secure passphrase of
-   * their choosing, provide an initialized {@link AppDataStore} instance. */
+   * their choosing, provide an initialized {@link @web5/agent#AppDataStore} instance.
+   **/
   appData?: AppDataStore;
 
   // Specify an existing DID to connect to.
@@ -45,18 +53,39 @@ export type Web5ConnectOptions = {
 }
 
 /**
+ * Options that are passed to Web5 constructor.
+ *
  * @see {@link Web5ConnectOptions}
+ * @beta
  */
 type Web5Options = {
   agent: Web5Agent;
   connectedDid: string;
 };
 
+/**
+ * The main Web5 API interface. It manages the creation of a DID if needed, the
+ * connection to the local DWN and all the web5 main foundational APIs such as VC,
+ * syncing, etc.
+ *
+ * @beta
+ */
 export class Web5 {
+  /**
+   * Web5 Agent knows how to handle DIDs, DWNs and VCs requests. The agent manages the
+   * user keys and identities, and is responsible to sign and verify messages.
+   */
   agent: Web5Agent;
+
+  /** Exposed instance to the DID APIs, allow users to create and resolve DIDs  */
   did: DidApi;
+
+  /** Exposed instance to the DWN APIs, allow users to read/write records */
   dwn: DwnApi;
+
+  /** Exposed instance to the VC APIs, allow users to issue, present and verify VCs */
   vc: VcApi;
+
   private connectedDid: string;
 
   constructor(options: Web5Options) {
@@ -69,7 +98,7 @@ export class Web5 {
   }
 
   /**
-   * Connects to a {@link Web5Agent}. Defaults to creating a local {@link Web5UserAgent}
+   * Connects to a {@link @web5/agent#Web5Agent}. Defaults to creating a local {@link @web5/user-agent#Web5UserAgent}
    * if one isn't provided.
    *
    * @param options - optional overrides