diff --git a/.github/ISSUE_TEMPLATE/documentation-request.yml b/.github/ISSUE_TEMPLATE/documentation-request.yml index 63df2ff2..56057d5d 100644 --- a/.github/ISSUE_TEMPLATE/documentation-request.yml +++ b/.github/ISSUE_TEMPLATE/documentation-request.yml @@ -1,5 +1,5 @@ name: Documentation Request -description: File a request to document a specific functionality in the Aries JavaScript ecosystem. +description: File a request to document a specific functionality in the Credo ecosystem. title: '[Request]: ' labels: ['request'] body: @@ -19,7 +19,7 @@ body: id: platform attributes: label: Version - description: Which version of Aries Framework JavaScript are you using? + description: Which version of Credo are you using? placeholder: 0.x.x validations: required: true diff --git a/.github/settings.yml b/.github/settings.yml new file mode 100644 index 00000000..6821b19b --- /dev/null +++ b/.github/settings.yml @@ -0,0 +1,18 @@ +# +# SPDX-License-Identifier: Apache-2.0 +# + +repository: + name: credo-ts-docs + description: Extension libraries for Credo + homepage: https://github.com/openwallet-foundation/credo-ts-docs + default_branch: main + has_downloads: false + has_issues: true + has_projects: false + has_wiki: false + archived: false + private: false + allow_squash_merge: true + allow_merge_commit: false + allow_rebase_merge: true diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index e91d930d..53d465db 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -32,7 +32,7 @@ jobs: github_token: ${{ secrets.GITHUB_TOKEN }} # Build output to publish to the `gh-pages` branch: publish_dir: ./build - cname: aries.js.org + cname: credo.js.org # The following lines assign commit authorship to the official # GH-Actions bot for deploys to `gh-pages` branch: # https://github.com/actions/checkout/issues/13#issuecomment-724415212 diff --git a/MAINTAINERS.md b/MAINTAINERS.md index 7eaaef86..2d020341 100644 --- a/MAINTAINERS.md +++ b/MAINTAINERS.md @@ -1,3 +1,3 @@ ## Maintainers -See [MAINTAINERS.md](https://github.com/hyperledger/aries-framework-javascript/blob/main/MAINTAINERS.md) in the Aries Framework JavaScript repository. +See [MAINTAINERS.md](https://github.com/openwallet-foundation/credo-ts/blob/main/MAINTAINERS.md) in the Credo repository. diff --git a/README.md b/README.md index 257c96a0..9ce38c06 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ height="250px" />

-

Aries JavaScript Documentation

+

Credo Documentation

Getting started  |  Contributing  |  - License + License

-Aries JavaScipt is an ecosystem of self-sovereign identity development tools, with [Aries Framework JavaScipt](https://github.com/hyperledger/aries-framework-javascript) at the center. This documentation site serves to make it as easy as possible for developers of any level to get started with building self-sovereign identity solutions. +Credo is an ecosystem of self-sovereign identity development tools, with [Credo](https://github.com/openwallet-foundation/credo-ts) at the center. This documentation site serves to make it as easy as possible for developers of any level to get started with building self-sovereign identity solutions. # Getting Started @@ -31,13 +31,13 @@ This website is built using [Docusaurus 2](https://docusaurus.io/), a modern sta ### Installation ``` -$ yarn +yarn ``` ### Local Development ``` -$ yarn start +yarn start ``` This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server. @@ -45,7 +45,7 @@ This command starts a local development server and opens up a browser window. Mo ### Build ``` -$ yarn build +yarn build ``` This command generates static content into the `build` directory and can be served using any static contents hosting service. @@ -55,23 +55,23 @@ This command generates static content into the `build` directory and can be serv Using SSH: ``` -$ USE_SSH=true yarn deploy +USE_SSH=true yarn deploy ``` Not using SSH: ``` -$ GIT_USER= yarn deploy +GIT_USER= yarn deploy ``` If you are using GitHub pages for hosting, this command is a convenient way to build the website and push to the `gh-pages` branch. ## Contributing -The docs are a work in progress, contributions are incredibly appreciated! If you're looking to contribute check out the [contribution guideline](https://github.com/hyperledger/aries-javascript-docs/blob/main/CONTRIBUTING.md). +The docs are a work in progress, contributions are incredibly appreciated! If you're looking to contribute check out the [contribution guideline](https://github.com/openwallet-foundation/credo-ts-docs/blob/main/CONTRIBUTING.md). Issues are also welcomed as it gives us a good idea of the work still needing to be done. ## Licence -Aries JavaScript Documentation is licensed under the [Apache License Version 2.0 (Apache-2.0)](/LICENSE). +Credo Documentation is licensed under the [Apache License Version 2.0 (Apache-2.0)](/LICENSE). diff --git a/docusaurus.config.js b/docusaurus.config.js index d6e699a3..f851b4c6 100644 --- a/docusaurus.config.js +++ b/docusaurus.config.js @@ -6,9 +6,9 @@ const darkCodeTheme = require('prism-react-renderer/themes/dracula') const remarkTabs = require('remark-docusaurus-tabs') /** @type {import('@docusaurus/types').Config} */ const config = { - title: 'Aries JavaScript Documentation', - tagline: 'Everything you need to know about the Aries JavaScript ecosystem.', - url: 'https://aries.js.org', + title: 'Credo', + tagline: 'Everything you need to know about the Credo TS ecosystem.', + url: 'https://credo.js.org', baseUrl: '/', onBrokenLinks: 'warn', onBrokenMarkdownLinks: 'warn', @@ -17,8 +17,8 @@ const config = { // GitHub pages deployment config. // If you aren't using GitHub pages, you don't need these. - organizationName: 'hyperledger', // Usually your GitHub org/user name. - projectName: 'aries-javascript-docs', // Usually your repo name. + organizationName: 'openwallet-foundation', // Usually your GitHub org/user name. + projectName: 'credo-ts-docs', // Usually your repo name. trailingSlash: false, // Even if you don't use internalization, you can use this field to set useful @@ -45,11 +45,15 @@ const config = { tag: ':::', keywords: ['note', 'tip', 'info', 'caution', 'danger', 'issuer', 'verifier', 'holder', 'bob', 'acme'], }, - lastVersion: 'current', + lastVersion: '0.4', versions: { current: { + label: 'v0.5.x', + path: '0.5', + banner: 'unreleased', + }, + 0.4: { label: 'v0.4.x', - path: '0.4', }, 0.3: { label: 'v0.3.x', @@ -68,7 +72,7 @@ const config = { ({ image: 'img/aries-social-preview-layered.png', navbar: { - title: 'Aries JavaScript Docs', + title: 'Credo Docs', logo: { alt: 'Hyperledger Aries Logo', src: 'img/aries-logo.png', @@ -108,11 +112,7 @@ const config = { items: [ { label: 'Discord', - href: 'https://discord.com/channels/905194001349627914/941708033434738768', - }, - { - label: 'Hyperledger Aries Mailing List', - href: 'https://lists.hyperledger.org/g/aries', + href: 'https://discord.com/channels/1022962884864643214/1179453305856991263', }, { label: 'Working Group Call Notes', @@ -128,16 +128,16 @@ const config = { title: 'Repositories', items: [ { - label: 'Aries Framework JavaScript', - href: 'https://github.com/hyperledger/aries-framework-javascript', + label: 'Credo', + href: 'https://github.com/openwallet-foundation/credo-ts', }, { - label: 'Aries Framework JavaScript Extensions', - href: 'https://github.com/hyperledger/aries-framework-javascript-ext', + label: 'Credo Extensions', + href: 'https://github.com/openwallet-foundation/credo-ts-ext', }, { - label: 'Aries JavaScript Docs (this site)', - href: 'https://github.com/hyperledger/aries-javascript-docs', + label: 'Credo Docs (this site)', + href: 'https://github.com/openwallet-foundation/credo-ts-docs', }, ], }, diff --git a/guides/concepts/agents.md b/guides/concepts/agents.md index 5f6c9b4d..1f6eb98c 100644 --- a/guides/concepts/agents.md +++ b/guides/concepts/agents.md @@ -1,13 +1,13 @@ # Agents -When working with any Aries implementation, you will interact with an Aries -agent. This will be either directly or via a REST API, like [the Aries +When working with any Credo implementation, you will interact with an Credo +agent. This will be either directly or via a REST API, like [the Credo framework REST -API](https://github.com/hyperledger/aries-framework-javascript-ext/tree/main/packages/rest). +API](https://github.com/openwallet-foundation/credo-ts-ext/tree/main/packages/rest). ### Characteristics -An Aries agent has three essential characteristics: +An Credo agent has three essential characteristics: 1. It acts as a fiduciary on behalf of a single identity owner (or, for agents of things like IoT devices, pets, and similar things, a single controller). @@ -15,27 +15,27 @@ An Aries agent has three essential characteristics: authorization. 1. It interacts using interoperable DIDComm protocols, more on that later. -What this means is that an Aries agent will act your behalf to issue create +What this means is that an Credo agent will act your behalf to issue create connections, issue credentials, send messages etc. It also have a cryptographic toolkit with which it can uniquely, securely and verifiably operate. And lastly it interacts with other entities, this could be another agent, via [DIDComm protocols](https://identity.foundation/didcomm-messaging/spec/) later on. The -Aries agent in the context of the Aries JavaScript ecosystem is your entry-point +Credo agent in the context of the Credo ecosystem is your entry-point to all of the functionality. ### Categories -There are many categories of Aries agents and we will group them into two +There are many categories of Credo agents and we will group them into two categories; a mobile agent and a cloud agent. These agents are grouped based on their "location", e.g. a mobile wallet or server. Some other categories are a -static, thin, thick and rich Aries agents. These agents are grouped based on -their complexity instead of their "location". The Aries JavaScript ecosystem +static, thin, thick and rich Credo agents. These agents are grouped based on +their complexity instead of their "location". The Credo ecosystem allows you to create a mobile agent and a cloud agent. It also allows any of the complexity categorized agents. ### Examples -Some examples of things that are Aries agent-like (since the definition can be +Some examples of things that are Credo agent-like (since the definition can be bit loose, these examples might help to get a clearer picture): **A mobile wallet** @@ -57,5 +57,3 @@ devices these can be used as a more central point for your data. - [Hyperledger Aries RFC - 004: Agents](https://github.com/hyperledger/aries-rfcs/blob/main/concepts/0004-agents/README.md) -- [Aries Framework JavaScript - Getting - Started](https://github.com/hyperledger/aries-framework-javascript/tree/main/docs/getting-started) diff --git a/guides/concepts/did-and-didcomm.md b/guides/concepts/did-and-didcomm.md index b18771b6..ecf69010 100644 --- a/guides/concepts/did-and-didcomm.md +++ b/guides/concepts/did-and-didcomm.md @@ -25,7 +25,7 @@ transport-agnostic, interoperable and much more. This means that you can securely send a message from as Alice to Bob securely via bluetooth, HTTP, WebSockets, etc. -When working with the tools available inside the Aries JavaScript ecosystem, +When working with the tools available inside the Credo ecosystem, deep knowledge of DIDComm is not required. ### Useful Resources diff --git a/guides/concepts/platform-and-environment.md b/guides/concepts/platform-and-environment.md index a8246027..d97d290d 100644 --- a/guides/concepts/platform-and-environment.md +++ b/guides/concepts/platform-and-environment.md @@ -1,3 +1,3 @@ # Platform and Environment -[Aries framework JavaScript](https://github.com/hyperledger/aries-framework-javascript) is developed to support a [Node.JS](https://nodejs.org) and [React Native](https://reactnative.dev) environment. With this it is entirely possible to build an entire SSI ecosystem with Aries Framework JavaScript. This would use Node.JS as an issuer as a verifier, and uses React Native as a holder. +[Credo](https://github.com/openwallet-foundation/credo-ts) is developed to support a [Node.JS](https://nodejs.org) and [React Native](https://reactnative.dev) environment. With this it is entirely possible to build an entire SSI ecosystem with Credo. This would use Node.JS as an issuer as a verifier, and uses React Native as a holder. diff --git a/guides/ecosystem/index.md b/guides/ecosystem/index.md index 00783c75..962c5a20 100644 --- a/guides/ecosystem/index.md +++ b/guides/ecosystem/index.md @@ -1,42 +1,40 @@ -# The Aries JavaScript Ecosystem +# The Credo Ecosystem -The Aries JavaScript ecosystem includes various components that are spread across multiple repositories. In this section we'll go over what these components are and how the relate to one another. +The Credo ecosystem includes various components that are spread across multiple repositories. In this section we'll go over what these components are and how the relate to one another. ## Repositories -Currently, Aries JavaScript is composed out of three separate repositories: +Currently, Credo is composed out of two separate repositories: -1. [Aries Framework JavaScript](https://github.com/hyperledger/aries-framework-javascript) -2. [Aries Framework JavaScript Extensions](https://github.com/hyperledger/aries-framework-javascript-ext) -3. [Aries Mobile Agent React Native (Bifold)](https://github.com/hyperledger/aries-mobile-agent-react-native) +1. [Credo](https://github.com/openwallet-foundation/credo-ts) +2. [Credo Extensions](https://github.com/openwallet-foundation/credo-ts-ext) + +In addition, there are several open-source applications and building blocks built on top of Credo. One example is [Aries Mobile Agent React Native (Bifold)](https://github.com/hyperledger/aries-mobile-agent-react-native), which is a white-label mobile wallet you can use to bootstrap your own custom wallet. ## Documentation You can find their documentation here: -1. [Aries Framework JavaScript](https://aries.js.org/guides) -2. [Aries Framework JavaScript Extensions](https://aries.js.org/guides/extensions) -3. [Aries Mobile Agent React Native (Bifold)](https://github.com/hyperledger/aries-mobile-agent-react-native/blob/main/README.md) +1. [Credo (core)](https://credo.js.org/guides) +2. [Credo Extensions](https://credo.js.org/guides/extensions) -### Aries Framework JavaScript +### Credo -Aries Framework JavaScript (AFJ) is at the core of the Aries JavaScript ecosystem. AFJ provides all the functionality related to cryptography, storage, messaging and more that is required +Credo (core) is at the core of the Credo ecosystem. Credo provides all the functionality related to cryptography, storage, messaging and more that is required -## Contributing in the Aries JS Ecosystem +## Contributing in the Credo Ecosystem Consider attending our weekly meetings to become aware of the current development cadence. -- [Aries Framework JS Meeting](https://wiki.hyperledger.org/display/ARIES/Framework+JS+Meetings) -- [Aries Bifold Meeting](https://wiki.hyperledger.org/display/ARIES/Aries+Bifold+User+Group) +- [Credo Working Group Meeting](https://github.com/openwallet-foundation/credo-ts/wiki/Meeting-Information) - [Aries Working Group Meeting](https://wiki.hyperledger.org/display/ARIES/Aries+Working+Group) ### Developer Contributions Each project maintains its own CONTRIBUTING guidance: -- [AFJ CONTRIBUTING.md](https://github.com/hyperledger/aries-framework-javascript/blob/main/CONTRIBUTING.md) -- [AFJ-Ext CONTRIBUTING.md](https://github.com/hyperledger/aries-framework-javascript-ext/blob/main/CONTRIBUTING.md) -- [Aries Bifold CONTRIBUTING](https://github.com/hyperledger/aries-mobile-agent-react-native/blob/main/CONTRIBUTING) +- [Credo CONTRIBUTING.md](https://github.com/openwallet-foundation/credo-ts/blob/main/CONTRIBUTING.md) +- [Credo Extensions CONTRIBUTING.md](https://github.com/openwallet-foundation/credo-ts-ext/blob/main/CONTRIBUTING.md) Each project has a significant set of developer conventions, checklists, templates, and actions to provide guidance and boundaries for a contribution. Consider looking at previous issues and their corresponding PRs to get a sense of the latest. diff --git a/guides/extensions/index.md b/guides/extensions/index.md index dd4e0569..84a906a4 100644 --- a/guides/extensions/index.md +++ b/guides/extensions/index.md @@ -2,15 +2,15 @@ import DocCardList from '@theme/DocCardList'; # Extensions -Aries Framework JavaScript Extensions is an extensions repository to Aries Framework JavaScript (AFJ). It hosts libraries built on top of Aries Framework JavaScript that don't necessarily belong to the core of the project. +Credo Extensions is an extensions repository to Credo. It hosts libraries built on top of Credo that don't necessarily belong to the core of the project. -Currently, there are four packages in the extension repository. Example extension libraries include React Hooks for AFJ and a REST API wrapper. +Currently, there are four packages in the extension repository. Example extension libraries include React Hooks for Credo and a REST API wrapper. -| Package | Version | Description | -| ---------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------- | -| [`@aries-framework/redux-store`](https://www.npmjs.com/package/@aries-framework/redux-store) | ![@aries-framework/redux-store version](https://img.shields.io/npm/v/@aries-framework/redux-store) | Redux toolkit wrapper around Aries Framework JavaScript | -| [`@aries-framework/rest`](https://www.npmjs.com/package/@aries-framework/rest) | ![@aries-framework/rest version](https://img.shields.io/npm/v/@aries-framework/rest) | Rest endpoint wrapper for using your agent over HTTP | -| [`@aries-framework/react-hooks`](https://www.npmjs.com/package/@aries-framework/react-hooks) | ![@aries-framework/react-hooks version](https://img.shields.io/npm/v/@aries-framework/react-hooks) | React Hooks for data handling and agent interaction | -| [`@aries-framework/push-notifications`](https://www.npmjs.com/package/@aries-framework/push-notifications) | ![@aries-framework/push-notifications version](https://img.shields.io/npm/v/@aries-framework/push-notifications) | Push notification plugin for Aries Framework JavaScript | +| Package | Version | Description | +| ---------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------- | +| [`@aries-framework/redux-store`](https://www.npmjs.com/package/@aries-framework/redux-store) | ![@aries-framework/redux-store version](https://img.shields.io/npm/v/@aries-framework/redux-store) | Redux toolkit wrapper around Credo | +| [`@aries-framework/rest`](https://www.npmjs.com/package/@aries-framework/rest) | ![@aries-framework/rest version](https://img.shields.io/npm/v/@aries-framework/rest) | Rest endpoint wrapper for using your agent over HTTP | +| [`@aries-framework/react-hooks`](https://www.npmjs.com/package/@aries-framework/react-hooks) | ![@aries-framework/react-hooks version](https://img.shields.io/npm/v/@aries-framework/react-hooks) | React Hooks for data handling and agent interaction | +| [`@aries-framework/push-notifications`](https://www.npmjs.com/package/@aries-framework/push-notifications) | ![@aries-framework/push-notifications version](https://img.shields.io/npm/v/@aries-framework/push-notifications) | Push notification plugin for Credo | diff --git a/guides/extensions/push-notifications.md b/guides/extensions/push-notifications.md index abf736e3..ffb99f82 100644 --- a/guides/extensions/push-notifications.md +++ b/guides/extensions/push-notifications.md @@ -1,6 +1,6 @@ # Push Notifications -The Push Notifications plugin package provides a way for you to register your APNs and Firebase push notification token at an agent, allowing you to use push notifications directly from AFJ. +The Push Notifications plugin package provides a way for you to register your APNs and Firebase push notification token at an agent, allowing you to use push notifications directly from Credo. :::note diff --git a/guides/extensions/react-hooks.md b/guides/extensions/react-hooks.md index c0592047..f8e16a0d 100644 --- a/guides/extensions/react-hooks.md +++ b/guides/extensions/react-hooks.md @@ -1,6 +1,6 @@ # React Hooks -The React Hooks package exposes useful React hooks that allow you to easily interact with AFJ from a React client application. +The React Hooks package exposes useful React hooks that allow you to easily interact with Credo from a React client application. These hooks provide a simple way to query agent data in a client application, allowing you to focus on the user interface. @@ -32,7 +32,7 @@ yarn add @aries-framework/react-hooks@^0.5 ## Usage -This package exposes useful React hooks that allow you to easily interact with AFJ. +This package exposes useful React hooks that allow you to easily interact with Credo. Everything exported from Hooks: diff --git a/guides/extensions/redux-store.md b/guides/extensions/redux-store.md index c0c42475..70ad2b11 100644 --- a/guides/extensions/redux-store.md +++ b/guides/extensions/redux-store.md @@ -1,8 +1,8 @@ # Redux Store -The Redux Store is an implementation of state management that can be used to build React & React Native SSI clients using AFJ. +The Redux Store is an implementation of state management that can be used to build React & React Native SSI clients using Credo. -The Redux Store allows you to integrate state management for the most important parts of using AFJ in a client application (mediation, connections, credentials and proofs), allowing you to sync UI state with the state of the agent as it interacts with other agents through the framework. +The Redux Store allows you to integrate state management for the most important parts of using Credo in a client application (mediation, connections, credentials and proofs), allowing you to sync UI state with the state of the agent as it interacts with other agents through the framework. :::note diff --git a/guides/extensions/rest.md b/guides/extensions/rest.md index 4614a54e..fb7b31a4 100644 --- a/guides/extensions/rest.md +++ b/guides/extensions/rest.md @@ -1,8 +1,8 @@ # REST API -The Aries Framework JavaScript (AFJ) REST API provides simple RESTful endpoints for AFJ methods, to allow you stand up an agent for communication over the internet instantly. You simply provide your agent configuration. The REST endpoints allow you to interact with your agent over HTTP and WebSockets. +The Credo REST API provides simple RESTful endpoints for Credo methods, to allow you stand up an agent for communication over the internet instantly. You simply provide your agent configuration. The REST endpoints allow you to interact with your agent over HTTP and WebSockets. -The AFJ REST API is the most convenient way for self-sovereign identity (SSI) developers to interact with SSI agents. +The Credo REST API is the most convenient way for self-sovereign identity (SSI) developers to interact with SSI agents. - ⭐ **Endpoints** to create connections, issue credentials, and request proofs. - 💻 **CLI** that makes it super easy to start an instance of the REST API. @@ -32,7 +32,7 @@ After installing and confirming that Libindy is installed, simply run: ```sh npx -p @aries-framework/rest afj-rest start \ - --label "AFJ Rest" \ + --label "Credo Rest" \ --wallet-id "walletId" \ --wallet-key "walletKey" \ --endpoint http://localhost:5000 \ diff --git a/guides/getting-started/index.md b/guides/getting-started/index.md index 2ab392dc..e736d81f 100644 --- a/guides/getting-started/index.md +++ b/guides/getting-started/index.md @@ -2,7 +2,7 @@ import DocCardList from '@theme/DocCardList'; # Getting started -In this section we will go over everything you need to get started on a technical level. First there are some general prerequisites for Node.JS and React Native. Aries Framework JavaScript works for creating both server-side applications (commonly but not always for creating issuer and verifier agents) and mobile applications (commonly holder agents). +In this section we will go over everything you need to get started on a technical level. First there are some general prerequisites for Node.JS and React Native. Credo works for creating both server-side applications (commonly but not always for creating issuer and verifier agents) and mobile applications (commonly holder agents). Based on the platform you want to work on, the installation guides you should follow are the same, but some steps may differ. diff --git a/guides/getting-started/prerequisites.md b/guides/getting-started/prerequisites.md index 975a599d..1758afe8 100644 --- a/guides/getting-started/prerequisites.md +++ b/guides/getting-started/prerequisites.md @@ -1,6 +1,6 @@ # Prerequisites -To work with [Aries Framework JavaScript](https://github.com/hyperledger/aries-framework-javascript) we need to install some dependencies and set-up our Node.JS environment. Even when creating a mobile app in React Native, we need Node.JS installed. We will go over the specific installation process for each platform. Go ahead and pick your system of choice to get started! +To work with [Credo](https://github.com/openwallet-foundation/credo-ts) we need to install some dependencies and set-up our Node.JS environment. Even when creating a mobile app in React Native, we need Node.JS installed. We will go over the specific installation process for each platform. Go ahead and pick your system of choice to get started! The specific items that we set-up: diff --git a/guides/getting-started/set-up/anoncreds-rs.md b/guides/getting-started/set-up/anoncreds-rs.md index 49b4e31c..86afde5a 100644 --- a/guides/getting-started/set-up/anoncreds-rs.md +++ b/guides/getting-started/set-up/anoncreds-rs.md @@ -4,7 +4,7 @@ :::caution -Support for the AnonCreds RS library in Aries Framework JavaScript is currently experimental. We recommend new projects to use AnonCreds RS from the start, and also to migrate existing projects to AnonCreds, from the Indy Sdk. However, projects may experience some issues. If you encounter any issues, please [open an issue](https://github.com/hyperledger/aries-framework-javascript/issues/new). +Support for the AnonCreds RS library in Credo is currently experimental. We recommend new projects to use AnonCreds RS from the start, and also to migrate existing projects to AnonCreds, from the Indy Sdk. However, projects may experience some issues. If you encounter any issues, please [open an issue](https://github.com/openwallet-foundation/credo-ts/issues/new). Currently, there are few limitations to using AnonCreds RS. @@ -15,7 +15,7 @@ Currently, there are few limitations to using AnonCreds RS. ### Installing AnonCreds RS -When using Aries Framework JavaScript with AnonCreds RS, there are a few extra dependencies that need to be installed. We need to install `@hyperledger/anoncreds` package, which contains the interfaces, and `@hyperledger/anoncreds-rs` package which is an implementation which depends on a wrapper of anoncreds-rs. Secondly, we need to add native bindings for the specific platform `@hyperledger/anoncreds-`. Currently there are bindings for Node.JS, as `@hyperledger/anoncreds-nodejs`, and React Native as `@hyperlegder/anoncreds-react-native`. +When using Credo with AnonCreds RS, there are a few extra dependencies that need to be installed. We need to install `@hyperledger/anoncreds` package, which contains the interfaces, and `@hyperledger/anoncreds-rs` package which is an implementation which depends on a wrapper of anoncreds-rs. Secondly, we need to add native bindings for the specific platform `@hyperledger/anoncreds-`. Currently there are bindings for Node.JS, as `@hyperledger/anoncreds-nodejs`, and React Native as `@hyperlegder/anoncreds-react-native`. diff --git a/guides/getting-started/set-up/aries-askar.md b/guides/getting-started/set-up/aries-askar.md index 627158e3..e6c97050 100644 --- a/guides/getting-started/set-up/aries-askar.md +++ b/guides/getting-started/set-up/aries-askar.md @@ -3,7 +3,7 @@ [Aries Askar](https://github.com/hyperledger/aries-askar) provides secure, encrypted storage and cryptographic support for encrypting, decrypting, signing and verifying data. It also provides both the `Wallet` and `StorageService` implementations for the agent. :::caution -Although Aries Askar is stable and already used in production in agents such as [Aries Cloud Agent Python](https://github.com/hyperledger/aries-cloudagent-python), support for Aries Askar in Aries Framework JavaScript is currently experimental. We recommend new projects to use Aries Askar from the start, and also to migrate existing projects to Aries Askar. However, projects may experience some issues. If you encounter any issues, please [open an issue](https://github.com/hyperledger/aries-framework-javascript/issues/new). +Although Aries Askar is stable and already used in production in agents such as [Aries Cloud Agent Python](https://github.com/hyperledger/aries-cloudagent-python), support for Aries Askar in Credo is currently experimental. We recommend new projects to use Aries Askar from the start, and also to migrate existing projects to Aries Askar. However, projects may experience some issues. If you encounter any issues, please [open an issue](https://github.com/openwallet-foundation/credo-ts/issues/new). Currently, there are few limitations to using Aries Askar. @@ -20,7 +20,7 @@ If you're upgrading from the Indy SDK to Aries Askar, see [Migrating from an Ind ### Installing Aries Askar -When using Aries Framework JavaScript with Aries Askar, there are a few extra dependencies that need to be installed. We need to install the `@aries-framework/askar` package, which implements the needed interfaces for the agent. Secondly, we need to add native bindings for the specific platform `@hyperledger/aries-askar-`. Currently there are bindings for Node.JS, as `@hyperledger/aries-askar-nodejs`, and React Native as `@hyperlegder/aries-askar-react-native`. +When using Credo with Aries Askar, there are a few extra dependencies that need to be installed. We need to install the `@aries-framework/askar` package, which implements the needed interfaces for the agent. Secondly, we need to add native bindings for the specific platform `@hyperledger/aries-askar-`. Currently there are bindings for Node.JS, as `@hyperledger/aries-askar-nodejs`, and React Native as `@hyperlegder/aries-askar-react-native`. diff --git a/guides/getting-started/set-up/cheqd/index.md b/guides/getting-started/set-up/cheqd/index.md index a08c21f7..a4354f66 100644 --- a/guides/getting-started/set-up/cheqd/index.md +++ b/guides/getting-started/set-up/cheqd/index.md @@ -10,7 +10,7 @@ cheqd also has a dedicated token, $CHEQ, used for identity writes to the network ### Installing cheqd -When using Aries Framework JavaScript with the cheqd, there's a few extra dependencies that need to be installed. We need to install the `@aries-framework/cheqd` package, which implements the needed interfaces for the agent. +When using Credo with the cheqd, there's a few extra dependencies that need to be installed. We need to install the `@aries-framework/cheqd` package, which implements the needed interfaces for the agent. #### React Native diff --git a/guides/getting-started/set-up/index.md b/guides/getting-started/set-up/index.md index 656c582b..f880360c 100644 --- a/guides/getting-started/set-up/index.md +++ b/guides/getting-started/set-up/index.md @@ -11,9 +11,9 @@ This guide assumes you have followed the [Prerequisites](./prerequisites), and y :::caution -Aries Framework JavaScript is still in **active development**, and as such some APIs are still experimental. **When using any experimental features, make sure to use an exact version of AFJ** (`0.4.0`) instead of a range (`^0.4.0`), to prevent accidental breaking changes. If you're not leveraging any experimental features, you can use a range (`^0.4.0`) to get the latest bugfixes and features. +Credo is still in **active development**, and as such some APIs are still experimental. **When using any experimental features, make sure to use an exact version of Credo** (`0.4.0`) instead of a range (`^0.4.0`), to prevent accidental breaking changes. If you're not leveraging any experimental features, you can use a range (`^0.4.0`) to get the latest bugfixes and features. -For AFJ `0.4.x`, **the following features are experimental**: +For Credo `0.4.x`, **the following features are experimental**: - Implementing your own `AnonCredsRegistry` and AnonCreds service implementation. - Using the shared component libraries from `@aries-framework/aries-askar`, `@aries-framework/indy-vdr` and `@aries-framework/anoncreds-rs` @@ -28,7 +28,7 @@ For AFJ `0.4.x`, **the following features are experimental**: ### Installing the required dependencies First we have to install the minimal amount of dependencies that are required -for configuring an Aries Framework JavaScript (AFJ) agent. +for configuring an Credo agent. @@ -67,7 +67,7 @@ of your application. + import 'react-native-get-random-values' ``` -In addition you need add support for resolving modules with the `.cjs` extension, as this is used by some of AFJ's dependencies and not automatically supported by React Native. +In addition you need add support for resolving modules with the `.cjs` extension, as this is used by some of Credo's dependencies and not automatically supported by React Native. ```js title="metro.config.js" showLineNumbers module.exports = { @@ -130,7 +130,7 @@ enough for your specific use cases. Please refer to the ### Adding a wallet and storage implementation -After creating the `Agent` instance, we need to provide the agent with a wallet and storage implementation. AFJ provides a few implementations out of the box, but you can also implement your own. Currently the following Wallet and Storage implementations are supported out of the box. Follow the specific guides to set up the wallet and storage implementation of your choice. +After creating the `Agent` instance, we need to provide the agent with a wallet and storage implementation. Credo provides a few implementations out of the box, but you can also implement your own. Currently the following Wallet and Storage implementations are supported out of the box. Follow the specific guides to set up the wallet and storage implementation of your choice. - [Aries Askar](./set-up/aries-askar) - Recommended. - [Indy SDK](./set-up/indy-sdk) - Legacy. Will be deprecated in the future. diff --git a/guides/getting-started/set-up/indy-sdk/index.md b/guides/getting-started/set-up/indy-sdk/index.md index 49fed153..10ae336d 100644 --- a/guides/getting-started/set-up/indy-sdk/index.md +++ b/guides/getting-started/set-up/indy-sdk/index.md @@ -5,16 +5,16 @@ import DocCardList from '@theme/DocCardList'; [Indy SDK](https://github.com/hyperledger/indy-sdk) provides a distributed ledger based foundation for self-sovereign identity. It can provide the `Wallet` and `StorageService` implementations for the agent, as well as a way to interact with Indy ledgers and an implementation of the legacy (v0.1) [AnonCreds Specification](https://hyperledger.github.io/anoncreds-spec/) :::caution -The Indy SDK integration in Aries Framework JavaScript is currently in maintenance mode. We recommend new projects to use [Aries Askar](../aries-askar) from the start, and also to migrate existing projects to Aries Askar. +The Indy SDK integration in Credo is currently in maintenance mode. We recommend new projects to use [Aries Askar](../aries-askar) from the start, and also to migrate existing projects to Aries Askar. ::: :::caution -The AnonCreds implementation from the Indy SDK only supports the [Hyperledger Indy Legacy AnonCreds Method](https://hyperledger.github.io/anoncreds-methods-registry/#hyperledger-indy-legacy-anoncreds-method) (the pre-standardized implementation), and doesn't support the new Ledger [Agnostic AnonCreds Specification (v1.0)](https://hyperledger.github.io/anoncreds-spec/). Use the new AnonCreds Rust implementation, which is also supported by Aries Framework JavaScript, in combination with [Aries Askar](../aries-askar) and Indy VDR to replace the bevhaviour of the Indy SDK, and support the new features these libraries have to offer. +The AnonCreds implementation from the Indy SDK only supports the [Hyperledger Indy Legacy AnonCreds Method](https://hyperledger.github.io/anoncreds-methods-registry/#hyperledger-indy-legacy-anoncreds-method) (the pre-standardized implementation), and doesn't support the new Ledger [Agnostic AnonCreds Specification (v1.0)](https://hyperledger.github.io/anoncreds-spec/). Use the new AnonCreds Rust implementation, which is also supported by Credo, in combination with [Aries Askar](../aries-askar) and Indy VDR to replace the bevhaviour of the Indy SDK, and support the new features these libraries have to offer. ::: ### Installing the Indy SDK -When using Aries Framework JavaScript with the Indy SDK, there's a few extra dependencies that need to be installed. We need to install the `@aries-framework/indy-sdk` package, which implements the needed interfaces for the agent. Secondly, we need to install the native Indy SDK library and the bindings for our specific platform. Currently there are bindings for Node.JS and React Native. +When using Credo with the Indy SDK, there's a few extra dependencies that need to be installed. We need to install the `@aries-framework/indy-sdk` package, which implements the needed interfaces for the agent. Secondly, we need to install the native Indy SDK library and the bindings for our specific platform. Currently there are bindings for Node.JS and React Native. To start off, install the native Indy SDK library. The setup for this depends on the platform you are using. Follow the instructions for your platform below. diff --git a/guides/getting-started/set-up/indy-vdr.md b/guides/getting-started/set-up/indy-vdr.md index 0ed40571..c4a0aecb 100644 --- a/guides/getting-started/set-up/indy-vdr.md +++ b/guides/getting-started/set-up/indy-vdr.md @@ -1,10 +1,10 @@ # Indy VDR -[Hyperledger Indy VDR](https://github.com/hyperledger/indy-vdr), Verifiable Data Registry, can be used to connect to one or more Indy Node ledger pools given sets of genesis transactions. Methods are provided to construct ledger requests and send them to the validators, collecting the results and ensuring that there is a consensus between the nodes. In the context of Aries Framework JavaScript, we mainly leverage it to register, and resolve, schemas, credential definitions and DIDs. +[Hyperledger Indy VDR](https://github.com/hyperledger/indy-vdr), Verifiable Data Registry, can be used to connect to one or more Indy Node ledger pools given sets of genesis transactions. Methods are provided to construct ledger requests and send them to the validators, collecting the results and ensuring that there is a consensus between the nodes. In the context of Credo, we mainly leverage it to register, and resolve, schemas, credential definitions and DIDs. :::caution -Support for Indy VDR in Aries Framework JavaScript is currently experimental. We recommend new projects to use Indy VDR from the start, and also to migrate existing projects to Indy VDR, from the indy-sdk. However, projects may experience some issues. If you encounter any issues, please [open an issue](https://github.com/hyperledger/aries-framework-javascript/issues/new). +Support for Indy VDR in Credo is currently experimental. We recommend new projects to use Indy VDR from the start, and also to migrate existing projects to Indy VDR, from the indy-sdk. However, projects may experience some issues. If you encounter any issues, please [open an issue](https://github.com/openwallet-foundation/credo-ts/issues/new). Currently, there are few limitations to using Indy VDR. @@ -15,7 +15,7 @@ Currently, there are few limitations to using Indy VDR. ### Installing Indy VDR -When using Aries Framework JavaScript with Indy VDR, there are a few extra dependencies that need to be installed. We need to install the `@hyperledger/indy-vdr`, which contains all the functionality to register objects on an Hyperledger Indy VDR. Secondly, we need to add native bindings for the specific platform `@hyperledger/indy-vdr-`. Currently there are bindings for Node.JS, as `@hyperledger/indy-vdr-nodejs`, and React Native as `@hyperlegder/indy-vdr-react-native`. +When using Credo with Indy VDR, there are a few extra dependencies that need to be installed. We need to install the `@hyperledger/indy-vdr`, which contains all the functionality to register objects on an Hyperledger Indy VDR. Secondly, we need to add native bindings for the specific platform `@hyperledger/indy-vdr-`. Currently there are bindings for Node.JS, as `@hyperledger/indy-vdr-nodejs`, and React Native as `@hyperlegder/indy-vdr-react-native`. diff --git a/guides/index.md b/guides/index.md index 4b1fb5a6..941231e1 100644 --- a/guides/index.md +++ b/guides/index.md @@ -1,10 +1,10 @@ # Intro -Welcome, to the Aries JavaScript community! +Welcome, to the Credo community! There's no way around it. Working with self-sovereign identity can be difficult. Luckily this documentation's main goal is to make it easy for you. Whether you have a lot of experience building with Aries or non-Aries SSI frameworks, or have never heard of terms like Verifiable Credential, [DID](./concepts/did-and-didcomm.md), or [Agent](./concepts/agents.md). This documentation will either help you create a JavaScript based SSI solution yourself, or help you find the right resources in the community to assist you! -So what is [Hyperledger Aries Framework JavaScript](https://github.com/hyperledger/aries-framework-javascript)? +So what is [Credo](https://github.com/openwallet-foundation/credo-ts)? > Hyperledger Aries provides a shared, reusable, interoperable tool kit designed for initiatives and solutions focused on creating, transmitting and storing verifiable digital credentials. > @@ -12,6 +12,6 @@ So what is [Hyperledger Aries Framework JavaScript](https://github.com/hyperledg There are [several](https://wiki.hyperledger.org/display/ARIES) Aries frameworks that help you build solutions using verifiable credentials. This one is written in TypeScript and is specifically well suited for Multi-Platform development as it supports Node.js and React Native. We, the community, like to view it as the most accessible framework mostly because it is written in TypeScript, and our maintainers and contributors work to keep developer user experience a top priority. -These docs are not just for the main framework, but also all that surround it. So you'll find [general explanations about the concepts used](./concepts/index.md), [specific tutorials for common use cases](./tutorials/index.md) and [relevant projects and related repositories](./ecosystem/index.md). Most of all you'll find solid documentation with lots of code examples and an enthousiastic community that wants to build great stuff together. +These docs are not just for the main framework, but also all that surround it. So you'll find [general explanations about the concepts used](./concepts/index.md), [specific tutorials for common use cases](./tutorials/index.md) and [relevant projects and related repositories](./ecosystem/index.md). Most of all you'll find solid documentation with lots of code examples and an enthusiastic community that wants to build great stuff together. Are you ready to get started? diff --git a/guides/tutorials/agent-config/index.md b/guides/tutorials/agent-config/index.md index e7878a65..9368bd40 100644 --- a/guides/tutorials/agent-config/index.md +++ b/guides/tutorials/agent-config/index.md @@ -1,7 +1,7 @@ # Agent Config The Aries agent provided by [Aries Framework -JavaScript](https://github.com/hyperledger/aries-framework-javascript) is very +JavaScript](https://github.com/openwallet-foundation/credo-ts) is very extensible. These are all the configuration options with a short description: ## `label`\* @@ -121,7 +121,7 @@ endpoints: ['https://example.org:3000'] ## `logger` A logger instance that implements the `Logger` interface. This can be extremely -helpful for debugging. Aries Framework JavaScript exposes a `ConsoleLogger` +helpful for debugging. Credo exposes a `ConsoleLogger` that can be used for simple logs. See [Logging](./logging) for more details on creating your own logger instance. **Type**: `Logger` @@ -208,7 +208,7 @@ connectionImageUrl: 'https://picsum.photos/200' Whether the storage should automatically be updated when a newer version of [Aries Framework -JavaScript](https://github.com/hyperledger/aries-framework-javascript) is used. +JavaScript](https://github.com/openwallet-foundation/credo-ts) is used. **Type**: `boolean` diff --git a/guides/tutorials/agent-config/logging.md b/guides/tutorials/agent-config/logging.md index f0df31e0..5bdc762d 100644 --- a/guides/tutorials/agent-config/logging.md +++ b/guides/tutorials/agent-config/logging.md @@ -68,7 +68,7 @@ The `setLogger` and `setDefaultLogger` methods have only been implemented in the ::: -The easiest way to do this from AFJ is through the `indy` property of `agentDependencies`. +The easiest way to do this from Credo is through the `indy` property of `agentDependencies`. ```ts import { agentDependencies } from '@aries-framework/node' @@ -84,4 +84,4 @@ agentDependencies.indy.setLogger((level, target, message, modulePath, file, line > WARNING: You can only set the logger once. Call indy_set_default_logger, indy_set_logger, not both. Once it's been set, libindy won't let you change it. You can also set the environment variable `RUST_LOG` to log at specified log levels. -See https://crates.io/crates/env_logger for more information. +See for more information. diff --git a/guides/tutorials/indy-sdk-postgres-database-nodejs/index.md b/guides/tutorials/indy-sdk-postgres-database-nodejs/index.md index 99cf0e9e..b640bff4 100644 --- a/guides/tutorials/indy-sdk-postgres-database-nodejs/index.md +++ b/guides/tutorials/indy-sdk-postgres-database-nodejs/index.md @@ -2,7 +2,7 @@ By default the Indy SDK will use an SQLite database for storage. In mobile environments this is sufficient and allows us to keep storage local to the device, but in server environments we oftentimes want a more scalable storage solution. By leveraging the PostgreSQL plugin for Indy SDK we can use PostgreSQL as a storage solution instead of SQLite. -This document describes the installation process of the Postgres plugin for IndySDK and how you need to configure AFJ to use it. +This document describes the installation process of the Postgres plugin for IndySDK and how you need to configure Credo to use it. ## Installation of the Postgres Plugin @@ -12,7 +12,7 @@ For installation of the Postgres plugin, please refer to the platform specific g - [Linux](./linux.md) - [Windows](./windows.md) -## Using the Postgres Plugin in AFJ +## Using the Postgres Plugin in Credo ```typescript showLineNumbers set-up-indy-sdk-postgres.ts section-1 diff --git a/guides/tutorials/registering-schema-and-credential-definition.md b/guides/tutorials/registering-schema-and-credential-definition.md index 60730ecd..d6b84ca9 100644 --- a/guides/tutorials/registering-schema-and-credential-definition.md +++ b/guides/tutorials/registering-schema-and-credential-definition.md @@ -1,6 +1,6 @@ # Registering a schema and credential definition on an AnonCreds Registry -In this tutorial we will register a schema and credential definition on an AnonCredsRegistry e.g. Hyperledger Indy ledger [indy-vdr](https://github.com/hyperledger/indy-vdr), [cheqd](https://github.com/hyperledger/aries-framework-javascript/packages/cheqd). +In this tutorial we will register a schema and credential definition on an AnonCredsRegistry e.g. Hyperledger Indy ledger [indy-vdr](https://github.com/hyperledger/indy-vdr), [cheqd](https://github.com/openwallet-foundation/credo-ts/packages/cheqd). :::info diff --git a/guides/updating/index.md b/guides/updating/index.md index 985e1c28..92addd48 100644 --- a/guides/updating/index.md +++ b/guides/updating/index.md @@ -1,33 +1,33 @@ import DocCardList from '@theme/DocCardList'; -# Updating AFJ +# Updating Credo -This section will cover everything you need to know about updating Aries Framework JavaScript to a newer version. +This section will cover everything you need to know about updating Credo to a newer version. ## Versioning -Aries Framework JavaScript follows [semantic versioning](https://semver.org/). This means that major version changes (**1**.0.0) are considered breaking changes. When features are added this is a minor version change (0.**1**.0). For bug fixes the patch version change is used (0.0.**1**). +Credo follows [semantic versioning](https://semver.org/). This means that major version changes (**1**.0.0) are considered breaking changes. When features are added this is a minor version change (0.**1**.0). For bug fixes the patch version change is used (0.0.**1**). -While AFJ is still in pre-1.0.0 version, the version change types are shifted to the right. This means a major version change is now a minor change (0.**1**.0) and a minor change is now a patch change (0.0.**1**). This is done to keep the version below 1.0.0, indicating the framework is still in early development and users can expect more breaking changes that when the version has already reached 1.0.0. +While Credo is still in pre-1.0.0 version, the version change types are shifted to the right. This means a major version change is now a minor change (0.**1**.0) and a minor change is now a patch change (0.0.**1**). This is done to keep the version below 1.0.0, indicating the framework is still in early development and users can expect more breaking changes that when the version has already reached 1.0.0. This means if the second number in the version (0.**1**.0) changes, you need to be careful with updating and always consult this page for update instructions. If only the third number changes (0.0.**1**), you can update without any issues. ## Types of breaking changes -Updates to AFJ bring new features and improvements to the framework. To better adapt the framework to new features we sometimes make breaking changes that will improve how AFJ works. There's two parts to updates with breaking changes: +Updates to Credo bring new features and improvements to the framework. To better adapt the framework to new features we sometimes make breaking changes that will improve how Credo works. There's two parts to updates with breaking changes: 1. Breaking code changes 2. Breaking storage changes ### Breaking Code Changes -Breaking changes to code means changes to how you interact with AFJ. This includes methods being renamed, moved to another module or extended to better integrate with new features. We'll try to cover all breaking changes in migration guides, so you know exactly what is needed to update to a new version and keep the same functionality. +Breaking changes to code means changes to how you interact with Credo. This includes methods being renamed, moved to another module or extended to better integrate with new features. We'll try to cover all breaking changes in migration guides, so you know exactly what is needed to update to a new version and keep the same functionality. :::info -If you encounter any breaking changes that aren't mentioned in the migration docs, please open an issue in the [Aries JavaScript Docs](https://github.com/hyperledger/aries-javascript-docs/issues) repository, or directly create a PR describing the change. +If you encounter any breaking changes that aren't mentioned in the migration docs, please open an issue in the [Credo Docs](https://github.com/openwallet-foundation/credo-ts-docs/issues) repository, or directly create a PR describing the change. ::: @@ -39,7 +39,7 @@ Breaking changes to storage are a bit more complex to deal with. While breaking Currently the following migration guides are available: -- [Migrating from AFJ 0.1.0 to 0.2.x](./versions/0.1-to-0.2.md) -- [Migrating from AFJ 0.2.x to 0.3.x](./versions/0.2-to-0.3.md) -- [Migrating from AFJ 0.3.x to 0.4.x](./versions/0.3-to-0.4.md) +- [Migrating from Credo 0.1.0 to 0.2.x](./versions/0.1-to-0.2.md) +- [Migrating from Credo 0.2.x to 0.3.x](./versions/0.2-to-0.3.md) +- [Migrating from Credo 0.3.x to 0.4.x](./versions/0.3-to-0.4.md) - [Migrating from an Indy SDK Wallet to Aries Askar](./update-indy-sdk-to-askar.md) diff --git a/guides/updating/update-assistant.md b/guides/updating/update-assistant.md index 33fb3ab6..81b98c59 100644 --- a/guides/updating/update-assistant.md +++ b/guides/updating/update-assistant.md @@ -1,6 +1,6 @@ # Update Assistant -The Update Assistant helps you update the storage objects from AFJ to newer versions. This documents describes the different ways you can leverage the Update Assistant from fully managed to more manual approaches. +The Update Assistant helps you update the storage objects from Credo to newer versions. This documents describes the different ways you can leverage the Update Assistant from fully managed to more manual approaches. - [Update Strategies](#update-strategies) - [Manually instantiating the update assistant on agent startup](#manually-instantiating-the-update-assistant-on-agent-startup) diff --git a/guides/updating/update-indy-sdk-to-askar.md b/guides/updating/update-indy-sdk-to-askar.md index c1c2a65a..1057ca7b 100644 --- a/guides/updating/update-indy-sdk-to-askar.md +++ b/guides/updating/update-indy-sdk-to-askar.md @@ -10,13 +10,13 @@ While the migration script technically works on node.js, it is strongly advised :::caution -Postgres is not supported. If you are using postgres with Indy SDK and need to update to Aries Askar, please open an issue on [GitHub](https://github.com/hyperledger/aries-framework-javascript). +Postgres is not supported. If you are using postgres with Indy SDK and need to update to Aries Askar, please open an issue on [GitHub](https://github.com/openwallet-foundation/credo-ts). ::: :::caution -The migration script is supported to run on 0.3.x before migrating from 0.3.x to 0.4.x. Please refer to [Migrating from AFJ 0.3.x to 0.4.x](./versions/0.3-to-0.4.md) to get to 0.4.x afterwards. +The migration script is supported to run on 0.3.x before migrating from 0.3.x to 0.4.x. Please refer to [Migrating from Credo 0.3.x to 0.4.x](./versions/0.3-to-0.4.md) to get to 0.4.x afterwards. It is important to note that this script must be ran before you update from 0.3.x to 0.4.x. @@ -28,7 +28,7 @@ The migration script does the following to make sure everything is migrated prop ### Create a backup -Because undefined behavior might occur, we create a backup in the new `tmp` directory from Aries Framework JavaScript. if some error occurs, it will be reverted back to the backed-up state and if no error occurs, it will delete the backup from the temporary directory. +Because undefined behavior might occur, we create a backup in the new `tmp` directory from Credo. if some error occurs, it will be reverted back to the backed-up state and if no error occurs, it will delete the backup from the temporary directory. ### Migrate the database to an Aries Askar structure @@ -46,7 +46,7 @@ Aries Askar has a specific way to store keys and every key, defined by the categ :::caution -This update script does not transform did records. This is fine for something like `did:peer`, but will cause issues with `indy` and `sov` DIDs. For more information, please check out the [Migrating from AFJ 0.3.x to 0.4.x](./versions/0.3-to-0.4.md#removal-of-publicdidseed-and-publicdid) +This update script does not transform did records. This is fine for something like `did:peer`, but will cause issues with `indy` and `sov` DIDs. For more information, please check out the [Migrating from Credo 0.3.x to 0.4.x](./versions/0.3-to-0.4.md#removal-of-publicdidseed-and-publicdid) ::: @@ -84,7 +84,7 @@ Updating does not require a lot of code, but must be done with caution. It is very important to note that the migration script only has to be run once. If it runs for a second time, it will error saying that the database is already migrated. Also, when the migration is finished, it is common practice to store this state in your persistent app storage. This script does not provide a way to detect if an update has happened, so storing this value will prevent the script from running every time. For more information regarding this topic, please check out [Update Assistant](./update-assistant.md#storing-the-agent-storage-version-outside-of-the-agent-storage). -### add the required dependencies: +### add the required dependencies ```sh yarn add @hyperledger/aries-askar-react-native @aries-framework/indy-sdk-to-askar-migration react-native-fs diff --git a/guides/updating/versions/0.1-to-0.2.md b/guides/updating/versions/0.1-to-0.2.md index 6e2f7fad..342b0a05 100644 --- a/guides/updating/versions/0.1-to-0.2.md +++ b/guides/updating/versions/0.1-to-0.2.md @@ -1,8 +1,8 @@ -# Migrating from AFJ 0.1.0 to 0.2.x +# Migrating from Credo 0.1.0 to 0.2.x -This document describes everything you need to know for updating AFJ 0.1.0 to 0.2.x. If you're not aware of how updating in AFJ works make sure to first read the guide on [Updating AFJ](/guides/updating/index.md). +This document describes everything you need to know for updating Credo 0.1.0 to 0.2.x. If you're not aware of how updating in Credo works make sure to first read the guide on [Updating Credo](/guides/updating/index.md). -First of all, update you dependencies to the 0.2.x versions. This will also update the needed peer depedencnies. **Extension packages are not updated with this command**. You need to update these manually, and make sure they're up to date with the latest version of AFJ. +First of all, update you dependencies to the 0.2.x versions. This will also update the needed peer depedencnies. **Extension packages are not updated with this command**. You need to update these manually, and make sure they're up to date with the latest version of Credo. @@ -28,7 +28,7 @@ npm install @aries-framework/node@^0.2.0 @aries-framework/core@^0.2.0 ## Breaking Code Changes -This section will list all breaking changes made to the public API of AFJ between version 0.1.0 and 0.2.0. +This section will list all breaking changes made to the public API of Credo between version 0.1.0 and 0.2.0. :::info @@ -90,7 +90,7 @@ await agent.credentials.offerCredential({ Previously when we received a message from another connection we would store the relevant data from the exchange in the credential record. The values we would store were the `credentialDefinitionId` and `schemaId` in the credential metadata, and the `credentialAttributes` field. -Starting with AFJ 0.2.0 the values are not stored in the credential record until after the message content has been accepted (in the case of an offer this means after sending the request message). This is to avoid ambiguity of the values in the credential record. If I have sent a proposal and then receive an offer, should the credential record contain the values from the proposal or the values from the offer? The first one reflects our view on what the data should be, the second one reflects the latest data. +Starting with Credo 0.2.0 the values are not stored in the credential record until after the message content has been accepted (in the case of an offer this means after sending the request message). This is to avoid ambiguity of the values in the credential record. If I have sent a proposal and then receive an offer, should the credential record contain the values from the proposal or the values from the offer? The first one reflects our view on what the data should be, the second one reflects the latest data. We decided to make the record properties always hold our view of what the data should be, and only update it after accepting the contents of a received message (either using auto accept, or by calling the `acceptXXX` methods on the credential module). @@ -183,7 +183,7 @@ const requestMessage = await agent.credentials.findRequestMessage('credentialRec const credentialMessage = await agent.credentials.findCredentialMessage('credentialRecordId') ``` -Because AFJ now also supports the issue credential v2 protocol, the return type of this protocol has been changed to `V1XXXMessage | V2XXXMessage | null`. Take this into account when working with the messages. +Because Credo now also supports the issue credential v2 protocol, the return type of this protocol has been changed to `V1XXXMessage | V2XXXMessage | null`. Take this into account when working with the messages. You can check if a message is a specific version by using the `instanceof` operator: @@ -199,11 +199,11 @@ Shared properties (e.g. the proposal messages for v1 and v2 both have the `crede ### Connections Module -Version 0.2.0 added support for the [Out of Band protocol](https://github.com/hyperledger/aries-rfcs/blob/main/features/0434-outofband/README.md) with support for the [DID Exchange protocol](https://github.com/hyperledger/aries-rfcs/tree/main/features/0023-did-exchange). Internally AFJ now uses out of band invitations for all connections, even if you're connecting using the old invitations from the [Connection protocol](https://github.com/hyperledger/aries-rfcs/tree/main/features/0160-connection-protocol). +Version 0.2.0 added support for the [Out of Band protocol](https://github.com/hyperledger/aries-rfcs/blob/main/features/0434-outofband/README.md) with support for the [DID Exchange protocol](https://github.com/hyperledger/aries-rfcs/tree/main/features/0023-did-exchange). Internally Credo now uses out of band invitations for all connections, even if you're connecting using the old invitations from the [Connection protocol](https://github.com/hyperledger/aries-rfcs/tree/main/features/0160-connection-protocol). #### Creating a Legacy Invitation -The `createInvitation` method on the connections module has been moved to the out of band module and renamed to `createLegacyInvitation`. The method is not planned to be removed in the near future, the legacy merely indicates this will create an RFC 0160 connection invitation. Internally AFJ creates an out of band invitation and transforms it into a legacy invitation. If you want to create an out of band invitation instead, you should use `oob.createInvitation`. +The `createInvitation` method on the connections module has been moved to the out of band module and renamed to `createLegacyInvitation`. The method is not planned to be removed in the near future, the legacy merely indicates this will create an RFC 0160 connection invitation. Internally Credo creates an out of band invitation and transforms it into a legacy invitation. If you want to create an out of band invitation instead, you should use `oob.createInvitation`. @@ -251,7 +251,7 @@ const connections = await agent.connections.findAllByOutOfBandId(outOfBandRecord #### Receiving a Legacy Invitation -The `receiveInvitation` and `receiveInvitationFromUrl` methods on the connections module have also been moved to the out of band module. Both methods support the new out of band invitations and the legacy RFC 0160 connection invitations. Internally AFJ converts the old invitations to out of band invitations. +The `receiveInvitation` and `receiveInvitationFromUrl` methods on the connections module have also been moved to the out of band module. Both methods support the new out of band invitations and the legacy RFC 0160 connection invitations. Internally Credo converts the old invitations to out of band invitations. @@ -313,7 +313,7 @@ If you still need to access the old `ConnectionState` you can do so by accessing ### Updating Custom Messages to the New Message Type Objects -Although this isn't a breaking change to the public API of the framework, it is something that you will need to take into account when creating custom modules. Starting from AFJ 0.2.0 we now support handling messages with different minor versions (e.g. receive a message with `@type` version 1.1 while we only support 1.0). With this change messages must now declare the message type as an `ParsedMessageType` object. We've added an `parseMessageType` util method that can help with this. +Although this isn't a breaking change to the public API of the framework, it is something that you will need to take into account when creating custom modules. Starting from Credo 0.2.0 we now support handling messages with different minor versions (e.g. receive a message with `@type` version 1.1 while we only support 1.0). With this change messages must now declare the message type as an `ParsedMessageType` object. We've added an `parseMessageType` util method that can help with this. diff --git a/guides/updating/versions/0.2-to-0.3.md b/guides/updating/versions/0.2-to-0.3.md index d231bb4f..f1a47066 100644 --- a/guides/updating/versions/0.2-to-0.3.md +++ b/guides/updating/versions/0.2-to-0.3.md @@ -1,8 +1,8 @@ -# Migrating from AFJ 0.2.x to 0.3.x +# Migrating from Credo 0.2.x to 0.3.x -This document describes everything you need to know for updating AFJ 0.2.x to 0.3.x. If you're not aware of how updating in AFJ works make sure to first read the guide on [Updating AFJ](/guides/updating/index.md). +This document describes everything you need to know for updating Credo 0.2.x to 0.3.x. If you're not aware of how updating in Credo works make sure to first read the guide on [Updating Credo](/guides/updating/index.md). -First of all, update you dependencies to the 0.3.x versions. This will also update the needed peer depedencnies. **Extension packages are not updated with this command**. You need to update these manually, and make sure they're up to date with the latest version of AFJ. +First of all, update you dependencies to the 0.3.x versions. This will also update the needed peer depedencnies. **Extension packages are not updated with this command**. You need to update these manually, and make sure they're up to date with the latest version of Credo. @@ -28,11 +28,11 @@ npm install @aries-framework/node@^0.3.0 @aries-framework/core@^0.3.0 ## Breaking Code Changes -This section will list all breaking changes made to the public API of AFJ between version 0.2.x and 0.3.0. +This section will list all breaking changes made to the public API of Credo between version 0.2.x and 0.3.0. :::info -If you have custom modules take into account there could be a lot more breaking changes that aren't documented here. We try to make sure that the biggest breaking changes to the internal API are also documented here (e.g. see [Updating Custom Modules to the Plugin API](#Updating-Custom-Modules-to-the-new-Plugin-API)), but it is possible some breaking changes are not documented here (feel free to open PRs). +If you have custom modules take into account there could be a lot more breaking changes that aren't documented here. We try to make sure that the biggest breaking changes to the internal API are also documented here (e.g. see [Updating Custom Modules to the Plugin API](#updating-custom-modules-to-the-new-plugin-api)), but it is possible some breaking changes are not documented here (feel free to open PRs). ::: @@ -70,7 +70,7 @@ Note that, if you are defining `indyLedgers` configuration, you should set the i In accordance with [Aries RFC 0360](https://github.com/hyperledger/aries-rfcs/tree/b3a3942ef052039e73cd23d847f42947f8287da2/features/0360-use-did-key), since 0.2.5 there is a configuration parameter called `useDidKeyInProtocols` which, when enabled, will encode keys in did:key instead of previous base58 format, unless the other party has started a protocol and is using base58. -This parameter was previously disabled by default and now it is enabled. If your agent only interacts with modern agents (e.g. AFJ 0.2.5 and newer) this will not represent any issue. Otherwise it is safer to explicitly set it to `false`. However, keep in mind that we expect this setting to be deprecated in the future, so we encourage you to update all your agents to use did:key. +This parameter was previously disabled by default and now it is enabled. If your agent only interacts with modern agents (e.g. Credo 0.2.5 and newer) this will not represent any issue. Otherwise it is safer to explicitly set it to `false`. However, keep in mind that we expect this setting to be deprecated in the future, so we encourage you to update all your agents to use did:key. ### Modules extracted from the core @@ -272,7 +272,7 @@ const requestMessage = await agent.proofs.findRequestMessage('proofRecordId') const presentationMessage = await agent.proofs.findPresentationMessage('proofRecordId') ``` -Because AFJ now also supports the present proof v2 protocol, the return type of this protocol has been changed to `V1XXXMessage | V2XXXMessage | null`. Take this into account when working with the messages. +Because Credo now also supports the present proof v2 protocol, the return type of this protocol has been changed to `V1XXXMessage | V2XXXMessage | null`. Take this into account when working with the messages. You can check if a message is a specific version by using the `instanceof` operator: @@ -344,7 +344,7 @@ const outOfBandRecord = await agent.oob.createInvitation({ }) const invitationUrl = outOfBandRecord.outOfBandInvitation.toUrl({ - domain: 'https://afj.com', + domain: 'https://Credo.com', }) ``` @@ -352,7 +352,7 @@ As you can see, there's now a lot more ways to use a message not tied to a conne ### Updating Custom Modules to the new Plugin API -Although this isn't a breaking change to the public API of the framework, it is something that you will need to take into account if you have custom modules and want to upgrade them to make compatible with AFJ 0.3.0. +Although this isn't a breaking change to the public API of the framework, it is something that you will need to take into account if you have custom modules and want to upgrade them to make compatible with Credo 0.3.0. #### Renaming handler classes diff --git a/guides/updating/versions/0.3-to-0.4.md b/guides/updating/versions/0.3-to-0.4.md index 034773a2..6f4abe0a 100644 --- a/guides/updating/versions/0.3-to-0.4.md +++ b/guides/updating/versions/0.3-to-0.4.md @@ -1,14 +1,14 @@ -# Migrating from AFJ 0.3.x to 0.4.x +# Migrating from Credo 0.3.x to 0.4.x -This document describes everything you need to know for updating AFJ 0.3.x to 0.4.x. If you're not aware of how updating in AFJ works make sure to first read the guide on [Updating AFJ](/guides/updating/index.md). +This document describes everything you need to know for updating Credo 0.3.x to 0.4.x. If you're not aware of how updating in Credo works make sure to first read the guide on [Updating Credo](/guides/updating/index.md). -First of all, update you dependencies to the 0.4.x versions. This will also update the needed peer dependencies. **Extension packages are not updated with this command**. You need to update these manually, and make sure they're up to date with the latest version of AFJ. +First of all, update you dependencies to the 0.4.x versions. This will also update the needed peer dependencies. **Extension packages are not updated with this command**. You need to update these manually, and make sure they're up to date with the latest version of Credo. -Aries Framework JavaScript 0.4.0 is a major release that introduces a lot of new features and changes to the public API. Specifically, this release removed the dependency on the Indy SDK from the `@aries-framework/core` package. Agent setup is more flexible, but it also means the setup is more complex. Follow the mentioned steps in this document carefully to make the upgrade as smooth as possible. +Credo 0.4.0 is a major release that introduces a lot of new features and changes to the public API. Specifically, this release removed the dependency on the Indy SDK from the `@aries-framework/core` package. Agent setup is more flexible, but it also means the setup is more complex. Follow the mentioned steps in this document carefully to make the upgrade as smooth as possible. :::caution -The migration guide only covers how to migrate from 0.3.x to 0.4.x while keeping the same behavior and dependencies. AFJ 0.4.0 introduced a lot of new features and adds support for [Aries Askar](https://github.com/hyperledger/aries-askar), [Indy VDR](https://github.com/hyperledger/indy-vdr) and [AnonCreds RS](https://github.com/hyperledger/anoncreds-rs) as a replacement for the Indy SDK. +The migration guide only covers how to migrate from 0.3.x to 0.4.x while keeping the same behavior and dependencies. Credo 0.4.0 introduced a lot of new features and adds support for [Aries Askar](https://github.com/hyperledger/aries-askar), [Indy VDR](https://github.com/hyperledger/indy-vdr) and [AnonCreds RS](https://github.com/hyperledger/anoncreds-rs) as a replacement for the Indy SDK. Migrating to these new components requires additional migration steps, which need to be closely followed to prevent loss of data. These can be found at the [Update Indy SDK to Askar guide](../update-indy-sdk-to-askar.md). @@ -18,13 +18,13 @@ As noted in the [Update Indy SDK to Askar guide](../update-indy-sdk-to-askar.md) :::caution -Multi-tenancy is not covered in the 0.3.x to 0.4.x migration guide. If you're using multi-tenancy in 0.3.x and want to migrate to 0.4.x, please open an issue on [Github](https://github.com/hyperledger/aries-framework-javascript). +Multi-tenancy is not covered in the 0.3.x to 0.4.x migration guide. If you're using multi-tenancy in 0.3.x and want to migrate to 0.4.x, please open an issue on [Github](https://github.com/openwallet-foundation/credo-ts). ::: :::caution -The following APIs, modules and features are experimental and therefore not covered by the semver versioning in Aries Framework JavaScript. If you're using any of these features, make sure to use an exact version of AFJ (`0.4.0`) instead of a range (`^0.4.0`): +The following APIs, modules and features are experimental and therefore not covered by the semver versioning in Credo. If you're using any of these features, make sure to use an exact version of Credo (`0.4.0`) instead of a range (`^0.4.0`): - Implementing your own `AnonCredsRegistry` and AnonCreds service implementation. Using the default implementations (Indy SDK, AnonCreds RS) is fine. - Using the shared component libraries from `@aries-framework/aries-askar`, `@aries-framework/indy-vdr` and `@aries-framework/anoncreds-rs` @@ -80,7 +80,7 @@ npm install --save-dev @types/indy-sdk ## Breaking Code Changes -This section will list all breaking changes made to the public API of AFJ between version 0.3.x and 0.4.0. +This section will list all breaking changes made to the public API of Credo between version 0.3.x and 0.4.0. :::info @@ -275,14 +275,14 @@ const agent = new Agent({ ### Removal of `publicDidSeed` and `publicDid` -To make AFJ more generic, and less focused on Hyperledger Indy, and Indy dids, the `publicDidSeed` and `publicDid` properties have been removed from the agent configuration, the agent class, and the `Wallet` interface. +To make Credo more generic, and less focused on Hyperledger Indy, and Indy dids, the `publicDidSeed` and `publicDid` properties have been removed from the agent configuration, the agent class, and the `Wallet` interface. The `publicDid` property was used as the did to register items in the ledger module. The approach had some limitations: - An agent could only have a single `publicDid` property. This means that if you wanted to write to multiple ledgers you would have to create multiple agents - The property assumed only Indy ledgers would be used, and didn't take into account the possibility of other ledgers. -AFJ now provides generic APIs that can work with any ledger, and thus the `publicDid` property is no longer needed. Different sections of this migration guide will explain the different parts of how to use the new APIs, this section just focuses on how to replace the `publicDid` property. +Credo now provides generic APIs that can work with any ledger, and thus the `publicDid` property is no longer needed. Different sections of this migration guide will explain the different parts of how to use the new APIs, this section just focuses on how to replace the `publicDid` property. The most common use case for the `publicDid` property was for registering an endorser did that can endorse (read: pay for) transactions on the ledger. This can now be done by importing the did into agent, after which it can be used by the AnonCreds module to register schemas and credential definitions, and the did registrar to register DIDs. @@ -364,9 +364,9 @@ await agent.dids.import({ ### More Granular Usage of Legacy `did:sov` Prefix in DIDComm Messages -AFJ 0.3.0 used the `useLegacyDidSovPrefix` to use the legacy `did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/` as the prefix in the `@type` of DIDComm message instead of the new `https://didcomm.org` prefix. Over time it has proven that this approach leads to undesired behavior as all messages (even protocols that were defined after the new prefix was the default) would use the legacy prefix. However, due to not all implementations having support for new prefix, disabling the legacy prefixes proved to be a problem. +Credo 0.3.0 used the `useLegacyDidSovPrefix` to use the legacy `did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/` as the prefix in the `@type` of DIDComm message instead of the new `https://didcomm.org` prefix. Over time it has proven that this approach leads to undesired behavior as all messages (even protocols that were defined after the new prefix was the default) would use the legacy prefix. However, due to not all implementations having support for new prefix, disabling the legacy prefixes proved to be a problem. -Therefore, in AFJ 0.4.0 the `useLegacyDidSovPrefix` property has been replaced with the `useDidSovPrefixWhereAllowed` property. This property will only use the legacy prefix for protocols that were defined before the new prefix was the default. This means that protocols that were defined after the new prefix was the default will use the new prefix independent of the value of the `useDidSovPrefixWhereAllowed` property. We hope this will allow us to slowly migrate away from the legacy prefix as new protocols are defined without breaking backwards compatibility. +Therefore, in Credo 0.4.0 the `useLegacyDidSovPrefix` property has been replaced with the `useDidSovPrefixWhereAllowed` property. This property will only use the legacy prefix for protocols that were defined before the new prefix was the default. This means that protocols that were defined after the new prefix was the default will use the new prefix independent of the value of the `useDidSovPrefixWhereAllowed` property. We hope this will allow us to slowly migrate away from the legacy prefix as new protocols are defined without breaking backwards compatibility. @@ -418,9 +418,9 @@ Accessing the connection on a transport session is an advanced case that is most ### Replacement of Ledger Module with new AnonCreds Module -The ledger module has been available in AFJ since the very beginning, and was due for a big overhaul. With the addition of the dids module a while ago we already had a replacement for the `registerPublicDid` and `getPublicDid` methods on the ledger module. The other methods of the ledger module have been replaced by the AnonCreds module. +The ledger module has been available in Credo since the very beginning, and was due for a big overhaul. With the addition of the dids module a while ago we already had a replacement for the `registerPublicDid` and `getPublicDid` methods on the ledger module. The other methods of the ledger module have been replaced by the AnonCreds module. -In AFJ 0.4.0 AnonCreds credential support is not part of the core framework anymore, and needs to be manually registered on the agent. The first part is enabling the AnonCreds module, which allows to manage AnonCreds objects, interact with the ledger, and issuer, hold and verify AnonCreds credentials and is explained in this section. The second part is actually allowing AnonCreds credentials to be exchanged in the Issue Credential and Present Proof protocols, which is explained in the [Manually Register AnonCreds Support in Credentials and Proofs Modules](#manually-register-anoncreds-support-in-credentials-and-proofs-modules) section. +In Credo 0.4.0 AnonCreds credential support is not part of the core framework anymore, and needs to be manually registered on the agent. The first part is enabling the AnonCreds module, which allows to manage AnonCreds objects, interact with the ledger, and issuer, hold and verify AnonCreds credentials and is explained in this section. The second part is actually allowing AnonCreds credentials to be exchanged in the Issue Credential and Present Proof protocols, which is explained in the [Manually Register AnonCreds Support in Credentials and Proofs Modules](#manually-register-anoncreds-support-in-credentials-and-proofs-modules) section. There's a few important takeaways based on the code example below: @@ -555,13 +555,13 @@ Changes to the Proofs module include: - `getRequestedCredentialsForProofRequest` has been renamed to `getCredentialsForRequest` - `autoSelectCredentialsForProofRequest` has been renamed to `selectCredentialsForRequest` - The `config` parameter for both methods has been removed and those have been replaced by proof format specific configuration options. In this case, the `config.filterByNonRevocationRequirements` has been added as `proofFormats.indy.filterByNonRevocationRequirements` (if the `indy` format is registered as explained in the next section). The `config.filterByPresentationPreview` has been removed as the presentation preview was only present in the present proof V1 protocol, and due to it's limited applicability (the holder starts with a proposal) we've decided to remove this method for now. You can still filter the credentials yourself by using the `getCredentialsForRequest` method. -- Interfaces have been renamed to be more consistent with the method names. Please refer to the [`CredentialsApiOptions`](https://github.com/hyperledger/aries-framework-javascript/blob/v0.4.0/packages/core/src/modules/credentials/CredentialsApiOptions.ts) and [`ProofsApiOptions`](https://github.com/hyperledger/aries-framework-javascript/blob/v0.4.0/packages/core/src/modules/proofs/ProofsApiOptions.ts) for the interface names that can be imported. +- Interfaces have been renamed to be more consistent with the method names. Please refer to the [`CredentialsApiOptions`](https://github.com/openwallet-foundation/credo-ts/blob/v0.4.0/packages/core/src/modules/credentials/CredentialsApiOptions.ts) and [`ProofsApiOptions`](https://github.com/openwallet-foundation/credo-ts/blob/v0.4.0/packages/core/src/modules/proofs/ProofsApiOptions.ts) for the interface names that can be imported. -If you encounter any other breaking changes in the Proofs and Credentials modules, please open an issue in the [Aries JavaScript Docs](https://github.com/hyperledger/aries-javascript-docs) repository. +If you encounter any other breaking changes in the Proofs and Credentials modules, please open an issue in the [Credo Docs](https://github.com/openwallet-foundation/credo-ts-docs) repository. ### Changes to the AnonCreds Credential and Proof Format -With the 0.4.0 release, AFJ now provides a pluggable AnonCreds interface, and requires support AnonCreds credentials to be explicitly registered on the agent. This is also the case for registering the credential and proof formats. +With the 0.4.0 release, Credo now provides a pluggable AnonCreds interface, and requires support AnonCreds credentials to be explicitly registered on the agent. This is also the case for registering the credential and proof formats. In 0.3.x, the `IndyProofFormatService` and `IndyCredentialFormatService` were registered by default. In 0.4.x, these services are no longer registered by default and they should be imported from the `@aries-framework/anoncreds` package as `LegacyIndyProofFormatService` and `LegacyIndyCredentialFormatService` and are based on [Aries RFC 0592](https://github.com/hyperledger/aries-rfcs/blob/main/features/0592-indy-attachments/README.md). In a future version the new `AnonCredsCredentialFormatService` and `AnonCredsProofFormatService` will be added to the AnonCreds package, which are based on [Aries RFC 0771](https://github.com/hyperledger/aries-rfcs/pull/771) and allow for AnonCreds credentials to be exchanged based on the new ledger agnostic [AnonCreds Specification](https://hyperledger.github.io/anoncreds-spec/). diff --git a/package.json b/package.json index 24f534a7..c9a0170a 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "name": "my-website", + "name": "credo-ts-docs", "version": "0.0.0", "private": true, "scripts": { diff --git a/snippets/0.4/package.json b/snippets/0.4/package.json new file mode 100644 index 00000000..c4531f9f --- /dev/null +++ b/snippets/0.4/package.json @@ -0,0 +1,39 @@ +{ + "name": "snippets-0.4", + "version": "1.0.0", + "license": "Apache-2.0", + "private": true, + "type": "module", + "scripts": { + "dev:mediator-setup": "ts-node --esm src/mediator-setup.ts", + "dev:mediation-recipient": "ts-node --esm src/mediation-recipient.ts", + "dev:connection": "ts-node --esm src/create-a-connection.ts", + "dev:credential": "ts-node --esm src/issue-a-credential.ts", + "dev:register-with-indy": "ts-node --esm src/register-schema-and-cred-def.ts", + "dev:set-up": "ts-node --esm src/set-up.ts" + }, + "dependencies": { + "@aries-framework/anoncreds": "^0.4.0", + "@aries-framework/anoncreds-rs": "^0.4.0", + "@aries-framework/askar": "^0.4.0", + "@aries-framework/core": "^0.4.0", + "@aries-framework/indy-sdk": "^0.4.0", + "@aries-framework/indy-vdr": "^0.4.0", + "@aries-framework/cheqd": "^0.4.0", + "@aries-framework/node": "^0.4.0", + "@aries-framework/react-native": "^0.4.0", + "@hyperledger/anoncreds-nodejs": "^0.1.0", + "@hyperledger/anoncreds-react-native": "^0.1.0", + "@hyperledger/aries-askar-nodejs": "^0.1.0", + "@hyperledger/aries-askar-react-native": "^0.1.0", + "@hyperledger/indy-vdr-nodejs": "^0.1.0", + "@hyperledger/indy-vdr-react-native": "^0.1.0", + "indy-sdk": "^1.16.0-dev-1655", + "indy-sdk-react-native": "^0.3.1", + "node-fetch": "2" + }, + "devDependencies": { + "@types/indy-sdk": "1.16.26", + "@types/indy-sdk-react-native": "npm:@types/indy-sdk@1.16.26" + } +} diff --git a/snippets/0.4/src/create-a-connection.ts b/snippets/0.4/src/create-a-connection.ts new file mode 100644 index 00000000..525ce92f --- /dev/null +++ b/snippets/0.4/src/create-a-connection.ts @@ -0,0 +1,161 @@ +import { AskarModule } from '@aries-framework/askar' +import { + Agent, + InitConfig, + ConnectionEventTypes, + ConnectionStateChangedEvent, + WsOutboundTransport, + HttpOutboundTransport, + DidExchangeState, + OutOfBandRecord, + ConnectionsModule, +} from '@aries-framework/core' +import { agentDependencies, HttpInboundTransport } from '@aries-framework/node' +import { ariesAskar } from '@hyperledger/aries-askar-nodejs' + +// start-section-1 +const initializeBobAgent = async () => { + // Simple agent configuration. This sets some basic fields like the wallet + // configuration and the label. It also sets the mediator invitation url, + // because this is most likely required in a mobile environment. + const config: InitConfig = { + label: 'demo-agent-bob', + walletConfig: { + id: 'mainBob', + key: 'demoagentbob00000000000000000000', + }, + } + + // A new instance of an agent is created here + // Askar can also be replaced by the indy-sdk if required + const agent = new Agent({ + config, + modules: { + askar: new AskarModule({ ariesAskar }), + connections: new ConnectionsModule({ autoAcceptConnections: true }), + }, + dependencies: agentDependencies, + }) + + // Register a simple `WebSocket` outbound transport + agent.registerOutboundTransport(new WsOutboundTransport()) + + // Register a simple `Http` outbound transport + agent.registerOutboundTransport(new HttpOutboundTransport()) + + // Initialize the agent + await agent.initialize() + + return agent +} +// end-section-1 + +// start-section-2 +const initializeAcmeAgent = async () => { + // Simple agent configuration. This sets some basic fields like the wallet + // configuration and the label. + const config: InitConfig = { + label: 'demo-agent-acme', + walletConfig: { + id: 'mainAcme', + key: 'demoagentacme0000000000000000000', + }, + endpoints: ['http://localhost:3001'], + } + + // A new instance of an agent is created here + // Askar can also be replaced by the indy-sdk if required + const agent = new Agent({ + config, + modules: { + askar: new AskarModule({ ariesAskar }), + connections: new ConnectionsModule({ autoAcceptConnections: true }), + }, + dependencies: agentDependencies, + }) + + // Register a simple `WebSocket` outbound transport + agent.registerOutboundTransport(new WsOutboundTransport()) + + // Register a simple `Http` outbound transport + agent.registerOutboundTransport(new HttpOutboundTransport()) + + // Register a simple `Http` inbound transport + agent.registerInboundTransport(new HttpInboundTransport({ port: 3001 })) + + // Initialize the agent + await agent.initialize() + + return agent +} +// end-section-2 + +// start-section-3 +const createNewInvitation = async (agent: Agent) => { + const outOfBandRecord = await agent.oob.createInvitation() + + return { + invitationUrl: outOfBandRecord.outOfBandInvitation.toUrl({ domain: 'https://example.org' }), + outOfBandRecord, + } +} +// end-section-3 + +// start-section-4 +const createLegacyInvitation = async (agent: Agent) => { + const { invitation } = await agent.oob.createLegacyInvitation() + + return invitation.toUrl({ domain: 'https://example.org' }) +} +// end-section-4 + +// start-section-5 +const receiveInvitation = async (agent: Agent, invitationUrl: string) => { + const { outOfBandRecord } = await agent.oob.receiveInvitationFromUrl(invitationUrl) + + return outOfBandRecord +} +// end-section-5 + +// start-section-6 +const setupConnectionListener = (agent: Agent, outOfBandRecord: OutOfBandRecord, cb: (...args: any) => void) => { + agent.events.on(ConnectionEventTypes.ConnectionStateChanged, ({ payload }) => { + if (payload.connectionRecord.outOfBandId !== outOfBandRecord.id) return + if (payload.connectionRecord.state === DidExchangeState.Completed) { + // the connection is now ready for usage in other protocols! + console.log(`Connection for out-of-band id ${outOfBandRecord.id} completed`) + + // Custom business logic can be included here + // In this example we can send a basic message to the connection, but + // anything is possible + cb() + + // We exit the flow + process.exit(0) + } + }) +} + +// end-section-6 + +const run = async () => { + console.log('Initializing Bob agent...') + const bobAgent = await initializeBobAgent() + console.log('Initializing Acme agent...') + const acmeAgent = await initializeAcmeAgent() + + console.log('Creating the invitation as Acme...') + const { outOfBandRecord, invitationUrl } = await createNewInvitation(acmeAgent) + + console.log('Listening for connection changes...') + setupConnectionListener(acmeAgent, outOfBandRecord, () => + console.log('We now have an active connection to use in the following tutorials') + ) + + console.log('Accepting the invitation as Bob...') + await receiveInvitation(bobAgent, invitationUrl) +} + +export default run + +void run() diff --git a/snippets/0.4/src/issue-a-credential.ts b/snippets/0.4/src/issue-a-credential.ts new file mode 100644 index 00000000..b1006aea --- /dev/null +++ b/snippets/0.4/src/issue-a-credential.ts @@ -0,0 +1,189 @@ +import { + CredentialEventTypes, + CredentialState, + CredentialStateChangedEvent, + DidsModule, + HttpOutboundTransport, + InitConfig, + WsOutboundTransport, + Agent, + CredentialsModule, + V2CredentialProtocol, +} from '@aries-framework/core' +import { agentDependencies, HttpInboundTransport } from '@aries-framework/node' +import { AskarModule } from '@aries-framework/askar' +import { ariesAskar } from '@hyperledger/aries-askar-nodejs' +import { + IndyVdrAnonCredsRegistry, + IndyVdrIndyDidRegistrar, + IndyVdrIndyDidResolver, + IndyVdrModule, +} from '@aries-framework/indy-vdr' +import { indyVdr } from '@hyperledger/indy-vdr-nodejs' +import { + AnonCredsCredentialFormatService, + AnonCredsModule, + LegacyIndyCredentialFormatService, +} from '@aries-framework/anoncreds' +import { AnonCredsRsModule } from '@aries-framework/anoncreds-rs' +import { anoncreds } from '@hyperledger/anoncreds-nodejs' + +const issuerConfig: InitConfig = { + label: 'docs-agent-nodejs-issue-a-credential-issuer', + walletConfig: { + id: 'wallet-id-issuer', + key: 'testkey0000000000000000000000000', + }, +} + +const holderConfig: InitConfig = { + label: 'docs-agent-nodejs-issue-a-credential-holder', + walletConfig: { + id: 'wallet-id-holder', + key: 'testkey0000000000000000000000000', + }, +} + +// start-section-1 +const issuer = new Agent({ + config: issuerConfig, + dependencies: agentDependencies, + modules: { + askar: new AskarModule({ + ariesAskar, + }), + anoncredsRs: new AnonCredsRsModule({ + anoncreds, + }), + indyVdr: new IndyVdrModule({ + indyVdr, + networks: [ + { + isProduction: false, + indyNamespace: 'bcovrin:test', + genesisTransactions: '', + connectOnStartup: true, + }, + ], + }), + anoncreds: new AnonCredsModule({ + registries: [new IndyVdrAnonCredsRegistry()], + }), + dids: new DidsModule({ + registrars: [new IndyVdrIndyDidRegistrar()], + resolvers: [new IndyVdrIndyDidResolver()], + }), + credentials: new CredentialsModule({ + credentialProtocols: [ + new V2CredentialProtocol({ + credentialFormats: [new LegacyIndyCredentialFormatService(), new AnonCredsCredentialFormatService()], + }), + ], + }), + }, +}) + +// Register a simple `WebSocket` outbound transport +issuer.registerOutboundTransport(new WsOutboundTransport()) + +// Register a simple `Http` outbound transport +issuer.registerOutboundTransport(new HttpOutboundTransport()) + +// Register a simple `Http` inbound transport +issuer.registerInboundTransport(new HttpInboundTransport({ port: 3002 })) +// end-section-1 + +// start-section-2 +const holder = new Agent({ + config: holderConfig, + dependencies: agentDependencies, + modules: { + askar: new AskarModule({ + ariesAskar, + }), + anoncredsRs: new AnonCredsRsModule({ + anoncreds, + }), + indyVdr: new IndyVdrModule({ + indyVdr, + networks: [ + { + isProduction: false, + indyNamespace: 'bcovrin:test', + genesisTransactions: '', + connectOnStartup: true, + }, + ], + }), + anoncreds: new AnonCredsModule({ + registries: [new IndyVdrAnonCredsRegistry()], + }), + dids: new DidsModule({ + resolvers: [new IndyVdrIndyDidResolver()], + }), + credentials: new CredentialsModule({ + credentialProtocols: [ + new V2CredentialProtocol({ + credentialFormats: [new LegacyIndyCredentialFormatService(), new AnonCredsCredentialFormatService()], + }), + ], + }), + }, +}) + +// Register a simple `WebSocket` outbound transport +holder.registerOutboundTransport(new WsOutboundTransport()) + +// Register a simple `Http` outbound transport +holder.registerOutboundTransport(new HttpOutboundTransport()) + +// Register a simple `Http` inbound transport +holder.registerInboundTransport(new HttpInboundTransport({ port: 3002 })) +// end-section-2 + +// start-section-3 +holder.events.on(CredentialEventTypes.CredentialStateChanged, async ({ payload }) => { + switch (payload.credentialRecord.state) { + case CredentialState.OfferReceived: + console.log('received a credential') + // custom logic here + await holder.credentials.acceptOffer({ credentialRecordId: payload.credentialRecord.id }) + case CredentialState.Done: + console.log(`Credential for credential id ${payload.credentialRecord.id} is accepted`) + // For demo purposes we exit the program here. + process.exit(0) + } +}) +// end-section-3 + +// start-section-4 +const indyCredentialExchangeRecord = await issuer.credentials.offerCredential({ + protocolVersion: 'v2', + connectionId: '', + credentialFormats: { + indy: { + credentialDefinitionId: '', + attributes: [ + { name: 'name', value: 'Jane Doe' }, + { name: 'age', value: '23' }, + ], + }, + }, +}) +// end-section-4 + +// start-section-5 +const anonCredsCredentialExchangeRecord = issuer.credentials.offerCredential({ + protocolVersion: 'v2', + connectionId: '', + credentialFormats: { + anoncreds: { + credentialDefinitionId: '', + attributes: [ + { name: 'name', value: 'Jane Doe' }, + { name: 'age', value: '23' }, + ], + }, + }, +}) +// end-section-5 diff --git a/snippets/0.4/src/mediation-recipient.ts b/snippets/0.4/src/mediation-recipient.ts new file mode 100644 index 00000000..917d47b5 --- /dev/null +++ b/snippets/0.4/src/mediation-recipient.ts @@ -0,0 +1,46 @@ +import { + Agent, + ConsoleLogger, + HttpOutboundTransport, + InitConfig, + LogLevel, + MediationRecipientModule, + WsOutboundTransport, +} from '@aries-framework/core' +import { IndySdkModule } from '@aries-framework/indy-sdk' +import { agentDependencies } from '@aries-framework/node' +import indySdk from 'indy-sdk' + +// start-section-1 +const name = 'alice' + +// paste your invitation url here +// or use the current invitation-url to connect to the public animo-mediator. +const mediatorInvitationUrl = + 'https://mediator.dev.animo.id/invite?oob=eyJAdHlwZSI6Imh0dHBzOi8vZGlkY29tbS5vcmcvb3V0LW9mLWJhbmQvMS4xL2ludml0YXRpb24iLCJAaWQiOiIyMDc1MDM4YS05ZGU3LTRiODItYWUxYi1jNzBmNDg4MjYzYTciLCJsYWJlbCI6IkFuaW1vIE1lZGlhdG9yIiwiYWNjZXB0IjpbImRpZGNvbW0vYWlwMSIsImRpZGNvbW0vYWlwMjtlbnY9cmZjMTkiXSwiaGFuZHNoYWtlX3Byb3RvY29scyI6WyJodHRwczovL2RpZGNvbW0ub3JnL2RpZGV4Y2hhbmdlLzEuMCIsImh0dHBzOi8vZGlkY29tbS5vcmcvY29ubmVjdGlvbnMvMS4wIl0sInNlcnZpY2VzIjpbeyJpZCI6IiNpbmxpbmUtMCIsInNlcnZpY2VFbmRwb2ludCI6Imh0dHBzOi8vbWVkaWF0b3IuZGV2LmFuaW1vLmlkIiwidHlwZSI6ImRpZC1jb21tdW5pY2F0aW9uIiwicmVjaXBpZW50S2V5cyI6WyJkaWQ6a2V5Ono2TWtvSG9RTUphdU5VUE5OV1pQcEw3RGs1SzNtQ0NDMlBpNDJGY3FwR25iampMcSJdLCJyb3V0aW5nS2V5cyI6W119LHsiaWQiOiIjaW5saW5lLTEiLCJzZXJ2aWNlRW5kcG9pbnQiOiJ3c3M6Ly9tZWRpYXRvci5kZXYuYW5pbW8uaWQiLCJ0eXBlIjoiZGlkLWNvbW11bmljYXRpb24iLCJyZWNpcGllbnRLZXlzIjpbImRpZDprZXk6ejZNa29Ib1FNSmF1TlVQTk5XWlBwTDdEazVLM21DQ0MyUGk0MkZjcXBHbmJqakxxIl0sInJvdXRpbmdLZXlzIjpbXX1dfQ' + +const agentConfig: InitConfig = { + label: `Aries Framework JavaScript ${name}`, + walletConfig: { + id: name, + key: name, + }, + logger: new ConsoleLogger(LogLevel.trace), +} + +const alice = new Agent({ + config: agentConfig, + dependencies: agentDependencies, + modules: { + mediationRecipient: new MediationRecipientModule({ + mediatorInvitationUrl, + }), + indySdk: new IndySdkModule({ indySdk }), + }, +}) + +alice.registerOutboundTransport(new HttpOutboundTransport()) +alice.registerOutboundTransport(new WsOutboundTransport()) + +await alice.initialize() +// end-section-1 diff --git a/snippets/0.4/src/mediator-setup.ts b/snippets/0.4/src/mediator-setup.ts new file mode 100644 index 00000000..86572a8b --- /dev/null +++ b/snippets/0.4/src/mediator-setup.ts @@ -0,0 +1,57 @@ +import { + Agent, + ConnectionsModule, + HttpOutboundTransport, + InitConfig, + MediationStateChangedEvent, + MediatorModule, + RoutingEventTypes, +} from '@aries-framework/core' +import { IndySdkModule } from '@aries-framework/indy-sdk' +import { HttpInboundTransport, agentDependencies } from '@aries-framework/node' +import indySdk from 'indy-sdk' + +// start-section-1 +const name = 'mediator' +const port = 3001 + +const agentConfig: InitConfig = { + label: `Aries Framework JavaScript ${name}`, + walletConfig: { + id: name, + key: name, + }, + endpoints: [`http://localhost:${port}`], +} + +const mediator = new Agent({ + config: agentConfig, + dependencies: agentDependencies, + modules: { + indySdk: new IndySdkModule({ indySdk }), + mediator: new MediatorModule({ + autoAcceptMediationRequests: true, + }), + connections: new ConnectionsModule({ + autoAcceptConnections: true, + }), + }, +}) + +mediator.registerOutboundTransport(new HttpOutboundTransport()) +mediator.registerInboundTransport(new HttpInboundTransport({ port })) + +await mediator.initialize() +const mediatorOutOfBandRecord = await mediator.oob.createInvitation({ multiUseInvitation: true }) + +const mediatiorInvitationUrl = mediatorOutOfBandRecord.outOfBandInvitation.toUrl({ + domain: `http://localhost:${port}`, +}) +console.log(mediatiorInvitationUrl) +// end-section-1 + +mediator.events + .observable(RoutingEventTypes.MediationStateChanged) + .subscribe(({ payload }) => { + console.log(`${name} mediation state: ${payload.mediationRecord.state}`) + }) diff --git a/snippets/0.4/src/register-schema-and-cred-def.ts b/snippets/0.4/src/register-schema-and-cred-def.ts new file mode 100644 index 00000000..fe9c8685 --- /dev/null +++ b/snippets/0.4/src/register-schema-and-cred-def.ts @@ -0,0 +1,140 @@ +import { DidsModule, InitConfig, KeyType, LogLevel, TypedArrayEncoder } from '@aries-framework/core' + +const config: InitConfig = { + label: 'docs-agent-nodejs-register-schema-and-cred-def', + walletConfig: { + id: 'wallet-id', + key: 'testkey0000000000000000000000000', + }, +} + +// start-section-1 +import { Agent } from '@aries-framework/core' +import { agentDependencies } from '@aries-framework/node' +import { AskarModule } from '@aries-framework/askar' +import { ariesAskar } from '@hyperledger/aries-askar-nodejs' +import { + IndyVdrAnonCredsRegistry, + IndyVdrIndyDidRegistrar, + IndyVdrIndyDidResolver, + IndyVdrModule, +} from '@aries-framework/indy-vdr' +import { indyVdr } from '@hyperledger/indy-vdr-nodejs' +import { AnonCredsModule } from '@aries-framework/anoncreds' +import { AnonCredsRsModule } from '@aries-framework/anoncreds-rs' +import { anoncreds } from '@hyperledger/anoncreds-nodejs' +import { + CheqdAnonCredsRegistry, + CheqdDidRegistrar, + CheqdDidResolver, + CheqdModule, + CheqdModuleConfig, +} from '@aries-framework/cheqd' + +const agent = new Agent({ + config, + dependencies: agentDependencies, + modules: { + // Register the Askar module on the agent + // We do this to have access to a wallet + askar: new AskarModule({ + ariesAskar, + }), + anoncredsRs: new AnonCredsRsModule({ + anoncreds, + }), + indyVdr: new IndyVdrModule({ + indyVdr, + networks: [ + { + isProduction: false, + indyNamespace: 'bcovrin:test', + genesisTransactions: '', + connectOnStartup: true, + }, + ], + }), + cheqd: new CheqdModule( + new CheqdModuleConfig({ + networks: [ + { + network: '', + cosmosPayerSeed: '', + }, + ], + }) + ), + anoncreds: new AnonCredsModule({ + registries: [new IndyVdrAnonCredsRegistry(), new CheqdAnonCredsRegistry()], + }), + dids: new DidsModule({ + registrars: [new IndyVdrIndyDidRegistrar(), new CheqdDidRegistrar()], + resolvers: [new IndyVdrIndyDidResolver(), new CheqdDidResolver()], + }), + }, +}) +// end-section-1 + +// start-section-2 +const seed = TypedArrayEncoder.fromString(``) // What you input on bcovrin. Should be kept secure in production! +const unqualifiedIndyDid = `` // will be returned after registering seed on bcovrin +const indyDid = `did:indy:bcovrin:test:${unqualifiedIndyDid}` + +const cheqdDid = await agent.dids.create({ + method: 'cheqd', + secret: { + verificationMethod: { + id: 'key-1', + type: 'Ed25519VerificationKey2020', + }, + }, + options: { + network: 'testnet', + methodSpecificIdAlgo: 'uuid', + }, +}) + +await agent.dids.import({ + did: '', + overwrite: true, + privateKeys: [ + { + privateKey: seed, + keyType: KeyType.Ed25519, + }, + ], +}) +// end-section-2 + +// start-section-3 +const schemaResult = await agent.modules.anoncreds.registerSchema({ + schema: { + attrNames: ['name'], + issuerId: '', + name: 'Example Schema to register', + version: '1.0.0', + }, + options: {}, +}) + +if (schemaResult.schemaState.state === 'failed') { + throw new Error(`Error creating schema: ${schemaResult.schemaState.reason}`) +} +// end-section-3 + +// start-section-4 +const credentialDefinitionResult = await agent.modules.anoncreds.registerCredentialDefinition({ + credentialDefinition: { + tag: 'default', + issuerId: '', + schemaId: schemaResult.schemaState.schemaId, + }, + options: {}, +}) + +if (credentialDefinitionResult.credentialDefinitionState.state === 'failed') { + throw new Error( + `Error creating credential definition: ${credentialDefinitionResult.credentialDefinitionState.reason}` + ) +} +// end-section-4 diff --git a/snippets/0.4/src/set-up-anoncreds-rs-rn.ts b/snippets/0.4/src/set-up-anoncreds-rs-rn.ts new file mode 100644 index 00000000..7322c7b0 --- /dev/null +++ b/snippets/0.4/src/set-up-anoncreds-rs-rn.ts @@ -0,0 +1,50 @@ +import type { InitConfig } from '@aries-framework/core' + +const config: InitConfig = { + label: 'docs-agent-react-native', + walletConfig: { + id: 'wallet-id', + key: 'testkey0000000000000000000000000', + }, +} + +// start-section-1 +import { Agent } from '@aries-framework/core' +import { agentDependencies } from '@aries-framework/react-native' +import { AskarModule } from '@aries-framework/askar' +import { ariesAskar } from '@hyperledger/aries-askar-react-native' + +import { anoncreds } from '@hyperledger/anoncreds-react-native' +import { AnonCredsModule } from '@aries-framework/anoncreds' +import { AnonCredsRsModule } from '@aries-framework/anoncreds-rs' +import { IndyVdrAnonCredsRegistry } from '@aries-framework/indy-vdr' + +const agent = new Agent({ + config, + dependencies: agentDependencies, + modules: { + // Register the Askar module on the agent + // This is included as we need a wallet on our agent + askar: new AskarModule({ + ariesAskar, + }), + anoncredsRs: new AnonCredsRsModule({ + anoncreds, + }), + anoncreds: new AnonCredsModule({ + // Here we add an Indy VDR registry as an example, any AnonCreds registry + // can be used + registries: [new IndyVdrAnonCredsRegistry()], + }), + }, +}) +// end-section-1 + +agent + .initialize() + .then(() => { + console.log('Agent initialized!') + }) + .catch((e) => { + console.error(`Something went wrong while setting up the agent! Message: ${e}`) + }) diff --git a/snippets/0.4/src/set-up-anoncreds-rs.ts b/snippets/0.4/src/set-up-anoncreds-rs.ts new file mode 100644 index 00000000..020fbe9d --- /dev/null +++ b/snippets/0.4/src/set-up-anoncreds-rs.ts @@ -0,0 +1,50 @@ +import type { InitConfig } from '@aries-framework/core' + +const config: InitConfig = { + label: 'docs-agent-nodejs', + walletConfig: { + id: 'wallet-id', + key: 'testkey0000000000000000000000000', + }, +} + +// start-section-1 +import { Agent } from '@aries-framework/core' +import { agentDependencies } from '@aries-framework/node' +import { AskarModule } from '@aries-framework/askar' +import { ariesAskar } from '@hyperledger/aries-askar-nodejs' + +import { anoncreds } from '@hyperledger/anoncreds-nodejs' +import { AnonCredsModule } from '@aries-framework/anoncreds' +import { AnonCredsRsModule } from '@aries-framework/anoncreds-rs' +import { IndyVdrAnonCredsRegistry } from '@aries-framework/indy-vdr' + +const agent = new Agent({ + config, + dependencies: agentDependencies, + modules: { + // Register the Askar module on the agent + // This is included as we need a wallet on our agent + askar: new AskarModule({ + ariesAskar, + }), + anoncredsRs: new AnonCredsRsModule({ + anoncreds, + }), + anoncreds: new AnonCredsModule({ + // Here we add an Indy VDR registry as an example, any AnonCreds registry + // can be used + registries: [new IndyVdrAnonCredsRegistry()], + }), + }, +}) +// end-section-1 + +agent + .initialize() + .then(() => { + console.log('Agent initialized!') + }) + .catch((e) => { + console.error(`Something went wrong while setting up the agent! Message: ${e}`) + }) diff --git a/snippets/0.4/src/set-up-askar-rn.ts b/snippets/0.4/src/set-up-askar-rn.ts new file mode 100644 index 00000000..abe5427e --- /dev/null +++ b/snippets/0.4/src/set-up-askar-rn.ts @@ -0,0 +1,36 @@ +import type { InitConfig } from '@aries-framework/core' + +const config: InitConfig = { + label: 'docs-agent-react-native', + walletConfig: { + id: 'wallet-id', + key: 'testkey0000000000000000000000000', + }, +} + +// start-section-1 +import { Agent } from '@aries-framework/core' +import { agentDependencies } from '@aries-framework/react-native' +import { AskarModule } from '@aries-framework/askar' +import { ariesAskar } from '@hyperledger/aries-askar-react-native' + +const agent = new Agent({ + config, + dependencies: agentDependencies, + modules: { + // Register the Askar module on the agent + askar: new AskarModule({ + ariesAskar, + }), + }, +}) +// end-section-1 + +agent + .initialize() + .then(() => { + console.log('Agent initialized!') + }) + .catch((e) => { + console.error(`Something went wrong while setting up the agent! Message: ${e}`) + }) diff --git a/snippets/0.4/src/set-up-askar.ts b/snippets/0.4/src/set-up-askar.ts new file mode 100644 index 00000000..0704dcd7 --- /dev/null +++ b/snippets/0.4/src/set-up-askar.ts @@ -0,0 +1,36 @@ +import type { InitConfig } from '@aries-framework/core' + +const config: InitConfig = { + label: 'docs-agent-nodejs', + walletConfig: { + id: 'wallet-id', + key: 'testkey0000000000000000000000000', + }, +} + +// start-section-1 +import { Agent } from '@aries-framework/core' +import { agentDependencies } from '@aries-framework/node' +import { AskarModule } from '@aries-framework/askar' +import { ariesAskar } from '@hyperledger/aries-askar-nodejs' + +const agent = new Agent({ + config, + dependencies: agentDependencies, + modules: { + // Register the Askar module on the agent + askar: new AskarModule({ + ariesAskar, + }), + }, +}) +// end-section-1 + +agent + .initialize() + .then(() => { + console.log('Agent initialized!') + }) + .catch((e) => { + console.error(`Something went wrong while setting up the agent! Message: ${e}`) + }) diff --git a/snippets/0.4/src/set-up-cheqd.ts b/snippets/0.4/src/set-up-cheqd.ts new file mode 100644 index 00000000..0ae0ad1a --- /dev/null +++ b/snippets/0.4/src/set-up-cheqd.ts @@ -0,0 +1,162 @@ +import { DidDocumentService, InitConfig } from '@aries-framework/core' + +const config: InitConfig = { + label: 'docs-agent-react-native', + walletConfig: { + id: 'wallet-id', + key: 'testkey0000000000000000000000000', + }, +} + +// start-section-1 +import { Agent, DidsModule, KeyType, DidDocument } from '@aries-framework/core' +import { agentDependencies } from '@aries-framework/react-native' +import { AskarModule } from '@aries-framework/askar' +import { ariesAskar } from '@hyperledger/aries-askar-react-native' + +import { + CheqdAnonCredsRegistry, + CheqdDidRegistrar, + CheqdDidResolver, + CheqdModule, + CheqdModuleConfig, + CheqdDidCreateOptions, +} from '@aries-framework/cheqd' +import { AnonCredsModule } from '@aries-framework/anoncreds' + +const agent = new Agent({ + config, + dependencies: agentDependencies, + modules: { + dids: new DidsModule({ + registrars: [new CheqdDidRegistrar()], + resolvers: [new CheqdDidResolver()], + }), + + // AnonCreds + anoncreds: new AnonCredsModule({ + registries: [new CheqdAnonCredsRegistry()], + }), + + // Add cheqd module + cheqd: new CheqdModule( + new CheqdModuleConfig({ + networks: [ + { + network: '', + cosmosPayerSeed: '', + }, + ], + }) + ), + // Indy VDR can optionally be used with Askar as wallet and storage implementation + askar: new AskarModule({ + ariesAskar, + }), + }, +}) +// end-section-1 + +agent + .initialize() + .then(() => { + console.log('Agent initialized!') + }) + .catch((e) => { + console.error(`Something went wrong while setting up the agent! Message: ${e}`) + }) + +// start-section-2 + +// create a key pair +const key = await agent.wallet.createKey({ + keyType: KeyType.Ed25519, +}) + +// encode public key according to the verification method +const ed25519PublicKeyBase58 = key.publicKeyBase58 + +// Create a DID +await agent.dids.create({ + method: 'cheqd', + secret: {}, + options: { + network: 'testnet', + }, + didDocument: new DidDocument({ + id: 'did:cheqd:testnet:92874297-d824-40ea-8ae5-364a1ec9237d', + controller: ['did:cheqd:testnet:92874297-d824-40ea-8ae5-364a1ec9237d'], + verificationMethod: [ + { + id: 'did:cheqd:testnet:92874297-d824-40ea-8ae5-364a1ec9237d#key-1', + type: 'Ed25519VerificationKey2018', + controller: 'did:cheqd:testnet:92874297-d824-40ea-8ae5-364a1ec9237d', + publicKeyBase58: ed25519PublicKeyBase58, + }, + ], + authentication: ['did:cheqd:testnet:92874297-d824-40ea-8ae5-364a1ec9237d#key-1'], + }), +}) +// end-section-2 + +// start-section-3 +await agent.dids.create({ + method: 'cheqd', + // the secret contains a the verification method type and id + secret: { + verificationMethod: { + id: 'key-1', + type: 'Ed25519VerificationKey2020', + }, + }, + // an optional methodSpecificIdAlgo parameter + options: { + network: 'testnet', + methodSpecificIdAlgo: 'uuid', + }, +}) +// end-section-3 + +// start-section-4 +await agent.dids.update({ + did: 'did:cheqd:testnet:b84817b8-43ee-4483-98c5-f03760816411', + // Updates DID Document with an additional verification method if provided + secret: { + verificationMethod: { + id: 'key-2', + type: 'JsonWebKey2020', + }, + }, + didDocument: { + id: 'did:cheqd:testnet:b84817b8-43ee-4483-98c5-f03760816411', + controller: ['did:cheqd:testnet:b84817b8-43ee-4483-98c5-f03760816411'], + verificationMethod: [ + { + id: 'did:cheqd:testnet:b84817b8-43ee-4483-98c5-f03760816411#key-1', + type: 'Ed25519VerificationKey2020', + controller: 'did:cheqd:testnet:b84817b8-43ee-4483-98c5-f03760816411', + publicKeyMultibase: 'z6MknkzLUEP5cxqqsaysNMWoh8NJRb3YsowTCj2D6yhwyEdj', + }, + ], + authentication: ['did:cheqd:testnet:b84817b8-43ee-4483-98c5-f03760816411#key-1'], + // updates did document with a service block + service: [ + new DidDocumentService({ + id: 'did:cheqd:testnet:b84817b8-43ee-4483-98c5-f03760816411#rand', + type: 'rand', + serviceEndpoint: 'https://rand.in', + }), + ], + }, +}) +// end-section-4 + +// start-section-5 +await agent.dids.deactivate({ + did: 'did:cheqd:testnet:b84817b8-43ee-4483-98c5-f03760816411', + // an optional versionId parameter + options: { + versionId: '3.0', + }, +}) +// end-section-5 diff --git a/snippets/0.4/src/set-up-indy-sdk-postgres.ts b/snippets/0.4/src/set-up-indy-sdk-postgres.ts new file mode 100644 index 00000000..8d574305 --- /dev/null +++ b/snippets/0.4/src/set-up-indy-sdk-postgres.ts @@ -0,0 +1,50 @@ +// start-section-1 +import { Agent, InitConfig } from '@aries-framework/core' +import { IndySdkModule } from '@aries-framework/indy-sdk' +import { + agentDependencies, + IndySdkPostgresStorageConfig, + loadIndySdkPostgresPlugin, + IndySdkPostgresWalletScheme, +} from '@aries-framework/node' +import indySdk from 'indy-sdk' + +// IndySdkPostgresStorageConfig defines interface for the Postgres plugin configuration. +const storageConfig = { + type: 'postgres_storage', + config: { + url: 'localhost:5432', + wallet_scheme: IndySdkPostgresWalletScheme.DatabasePerWallet, + }, + credentials: { + account: 'postgres', + password: 'postgres', + admin_account: 'postgres', + admin_password: 'postgres', + }, +} satisfies IndySdkPostgresStorageConfig + +// load the postgres wallet plugin before agent initialization +loadIndySdkPostgresPlugin(storageConfig.config, storageConfig.credentials) + +const agentConfig: InitConfig = { + label: 'My Agent', + // walletConfig.id and walletConfig.key are still required + walletConfig: { + id: 'walletId', + key: 'testKey0000000000000000000000000', + // storage is added and defines the postgres plugin configuration + storage: storageConfig, + }, +} + +const agent = new Agent({ + config: agentConfig, + dependencies: agentDependencies, + modules: { + indySdk: new IndySdkModule({ + indySdk, + }), + }, +}) +// end-section-1 diff --git a/snippets/0.4/src/set-up-indy-sdk-rn.ts b/snippets/0.4/src/set-up-indy-sdk-rn.ts new file mode 100644 index 00000000..38044685 --- /dev/null +++ b/snippets/0.4/src/set-up-indy-sdk-rn.ts @@ -0,0 +1,36 @@ +import type { InitConfig } from '@aries-framework/core' + +const config: InitConfig = { + label: 'docs-agent-react-native', + walletConfig: { + id: 'wallet-id', + key: 'testkey0000000000000000000000000', + }, +} + +// start-section-1 +import { Agent } from '@aries-framework/core' +import { agentDependencies } from '@aries-framework/react-native' +import { IndySdkModule } from '@aries-framework/indy-sdk' +import indySdk from 'indy-sdk-react-native' + +const agent = new Agent({ + config, + dependencies: agentDependencies, + modules: { + // Register the Indy SDK module on the agent + indySdk: new IndySdkModule({ + indySdk, + }), + }, +}) +// end-section-1 + +agent + .initialize() + .then(() => { + console.log('Agent initialized!') + }) + .catch((e) => { + console.error(`Something went wrong while setting up the agent! Message: ${e}`) + }) diff --git a/snippets/0.4/src/set-up-indy-sdk.ts b/snippets/0.4/src/set-up-indy-sdk.ts new file mode 100644 index 00000000..3dae9c2e --- /dev/null +++ b/snippets/0.4/src/set-up-indy-sdk.ts @@ -0,0 +1,36 @@ +import type { InitConfig } from '@aries-framework/core' + +const config: InitConfig = { + label: 'docs-agent-react-native', + walletConfig: { + id: 'wallet-id', + key: 'testkey0000000000000000000000000', + }, +} + +// start-section-1 +import { Agent } from '@aries-framework/core' +import { agentDependencies } from '@aries-framework/node' +import { IndySdkModule } from '@aries-framework/indy-sdk' +import indySdk from 'indy-sdk' + +const agent = new Agent({ + config, + dependencies: agentDependencies, + modules: { + // Register the Indy SDK module on the agent + indySdk: new IndySdkModule({ + indySdk, + }), + }, +}) +// end-section-1 + +await agent + .initialize() + .then(() => { + console.log('Agent initialized!') + }) + .catch((e) => { + console.error(`Something went wrong while setting up the agent! Message: ${e}`) + }) diff --git a/snippets/0.4/src/set-up-indy-vdr-config.ts b/snippets/0.4/src/set-up-indy-vdr-config.ts new file mode 100644 index 00000000..d99cf179 --- /dev/null +++ b/snippets/0.4/src/set-up-indy-vdr-config.ts @@ -0,0 +1,18 @@ +// start-section-1 +import { indyVdr } from '@hyperledger/indy-vdr-nodejs' +import { IndyVdrModule } from '@aries-framework/indy-vdr' + +const modules = { + indyVdr: new IndyVdrModule({ + indyVdr, + networks: [ + { + indyNamespace: 'bcovrin:test', + isProduction: false, + genesisTransactions: '', + connectOnStartup: true, + }, + ], + }), +} +// end-section-1 diff --git a/snippets/0.4/src/set-up-indy-vdr-rn.ts b/snippets/0.4/src/set-up-indy-vdr-rn.ts new file mode 100644 index 00000000..9cce84dd --- /dev/null +++ b/snippets/0.4/src/set-up-indy-vdr-rn.ts @@ -0,0 +1,54 @@ +import type { InitConfig } from '@aries-framework/core' + +const config: InitConfig = { + label: 'docs-agent-react-native', + walletConfig: { + id: 'wallet-id', + key: 'testkey0000000000000000000000000', + }, +} + +// start-section-1 +import { Agent } from '@aries-framework/core' +import { agentDependencies } from '@aries-framework/react-native' +import { AskarModule } from '@aries-framework/askar' +import { ariesAskar } from '@hyperledger/aries-askar-react-native' + +import { IndyVdrAnonCredsRegistry, IndyVdrModule } from '@aries-framework/indy-vdr' +import { indyVdr } from '@hyperledger/indy-vdr-react-native' +import { AnonCredsModule } from '@aries-framework/anoncreds' + +const agent = new Agent({ + config, + dependencies: agentDependencies, + modules: { + indyVdr: new IndyVdrModule({ + indyVdr, + networks: [ + { + isProduction: false, + indyNamespace: 'bcovrin:test', + genesisTransactions: '', + connectOnStartup: true, + }, + ], + }), + anoncreds: new AnonCredsModule({ + registries: [new IndyVdrAnonCredsRegistry()], + }), + // Indy VDR can optionally be used with Askar as wallet and storage implementation + askar: new AskarModule({ + ariesAskar, + }), + }, +}) +// end-section-1 + +agent + .initialize() + .then(() => { + console.log('Agent initialized!') + }) + .catch((e) => { + console.error(`Something went wrong while setting up the agent! Message: ${e}`) + }) diff --git a/snippets/0.4/src/set-up-indy-vdr.ts b/snippets/0.4/src/set-up-indy-vdr.ts new file mode 100644 index 00000000..e6779d31 --- /dev/null +++ b/snippets/0.4/src/set-up-indy-vdr.ts @@ -0,0 +1,54 @@ +import type { InitConfig } from '@aries-framework/core' + +const config: InitConfig = { + label: 'docs-agent-nodejs', + walletConfig: { + id: 'wallet-id', + key: 'testkey0000000000000000000000000', + }, +} + +// start-section-1 +import { Agent } from '@aries-framework/core' +import { agentDependencies } from '@aries-framework/node' +import { AskarModule } from '@aries-framework/askar' +import { ariesAskar } from '@hyperledger/aries-askar-nodejs' + +import { IndyVdrAnonCredsRegistry, IndyVdrModule } from '@aries-framework/indy-vdr' +import { indyVdr } from '@hyperledger/indy-vdr-nodejs' +import { AnonCredsModule } from '@aries-framework/anoncreds' + +const agent = new Agent({ + config, + dependencies: agentDependencies, + modules: { + indyVdr: new IndyVdrModule({ + indyVdr, + networks: [ + { + isProduction: false, + indyNamespace: 'bcovrin:test', + genesisTransactions: '', + connectOnStartup: true, + }, + ], + }), + anoncreds: new AnonCredsModule({ + registries: [new IndyVdrAnonCredsRegistry()], + }), + // Indy VDR can optionally be used with Askar as wallet and storage implementation + askar: new AskarModule({ + ariesAskar, + }), + }, +}) +// end-section-1 + +agent + .initialize() + .then(() => { + console.log('Agent initialized!') + }) + .catch((e) => { + console.error(`Something went wrong while setting up the agent! Message: ${e}`) + }) diff --git a/snippets/0.4/src/set-up-rn.ts b/snippets/0.4/src/set-up-rn.ts new file mode 100644 index 00000000..f9e10429 --- /dev/null +++ b/snippets/0.4/src/set-up-rn.ts @@ -0,0 +1,40 @@ +// start-section-1 +import type { InitConfig } from '@aries-framework/core' +import { Agent } from '@aries-framework/core' +import { agentDependencies } from '@aries-framework/react-native' + +const config: InitConfig = { + label: 'docs-agent-react-native', + walletConfig: { + id: 'wallet-id', + key: 'testkey0000000000000000000000000', + }, +} + +const agent = new Agent({ + config, + dependencies: agentDependencies, +}) +// end-section-1 + +// start-section-2 +import { HttpOutboundTransport, WsOutboundTransport } from '@aries-framework/core' + +// ... agent setup from prevous section ... + +agent.registerOutboundTransport(new HttpOutboundTransport()) +agent.registerOutboundTransport(new WsOutboundTransport()) +// end-section-2 + +// TODO: we probably want to make this more specific to React Native, +// so using it in a components and recommending to use the react hooks +// start-section-3 +agent + .initialize() + .then(() => { + console.log('Agent initialized!') + }) + .catch((e) => { + console.error(`Something went wrong while setting up the agent! Message: ${e}`) + }) +// end-section-3 diff --git a/snippets/0.4/src/set-up.ts b/snippets/0.4/src/set-up.ts new file mode 100644 index 00000000..21ca3a43 --- /dev/null +++ b/snippets/0.4/src/set-up.ts @@ -0,0 +1,40 @@ +// start-section-1 +import type { InitConfig } from '@aries-framework/core' +import { Agent } from '@aries-framework/core' +import { agentDependencies } from '@aries-framework/node' + +const config: InitConfig = { + label: 'docs-agent-nodejs', + walletConfig: { + id: 'wallet-id', + key: 'testkey0000000000000000000000000', + }, +} + +const agent = new Agent({ + config, + dependencies: agentDependencies, +}) +// end-section-1 + +// start-section-2 +import { HttpOutboundTransport, WsOutboundTransport } from '@aries-framework/core' +import { HttpInboundTransport } from '@aries-framework/node' + +// ... agent setup from prevous section ... + +agent.registerOutboundTransport(new HttpOutboundTransport()) +agent.registerOutboundTransport(new WsOutboundTransport()) +agent.registerInboundTransport(new HttpInboundTransport({ port: 3000 })) +// end-section-2 + +// start-section-3 +agent + .initialize() + .then(() => { + console.log('Agent initialized!') + }) + .catch((e) => { + console.error(`Something went wrong while setting up the agent! Message: ${e}`) + }) +// end-section-3 diff --git a/snippets/0.4/tsconfig.json b/snippets/0.4/tsconfig.json new file mode 100644 index 00000000..029c3013 --- /dev/null +++ b/snippets/0.4/tsconfig.json @@ -0,0 +1,3 @@ +{ + "extends": "../../tsconfig.snippets.json" +} diff --git a/snippets/current/package.json b/snippets/current/package.json index c4531f9f..cdc1b0b7 100644 --- a/snippets/current/package.json +++ b/snippets/current/package.json @@ -1,5 +1,5 @@ { - "name": "snippets-0.4", + "name": "snippets-0.5", "version": "1.0.0", "license": "Apache-2.0", "private": true, diff --git a/snippets/current/src/mediation-recipient.ts b/snippets/current/src/mediation-recipient.ts index 917d47b5..a91ebfa1 100644 --- a/snippets/current/src/mediation-recipient.ts +++ b/snippets/current/src/mediation-recipient.ts @@ -20,7 +20,7 @@ const mediatorInvitationUrl = 'https://mediator.dev.animo.id/invite?oob=eyJAdHlwZSI6Imh0dHBzOi8vZGlkY29tbS5vcmcvb3V0LW9mLWJhbmQvMS4xL2ludml0YXRpb24iLCJAaWQiOiIyMDc1MDM4YS05ZGU3LTRiODItYWUxYi1jNzBmNDg4MjYzYTciLCJsYWJlbCI6IkFuaW1vIE1lZGlhdG9yIiwiYWNjZXB0IjpbImRpZGNvbW0vYWlwMSIsImRpZGNvbW0vYWlwMjtlbnY9cmZjMTkiXSwiaGFuZHNoYWtlX3Byb3RvY29scyI6WyJodHRwczovL2RpZGNvbW0ub3JnL2RpZGV4Y2hhbmdlLzEuMCIsImh0dHBzOi8vZGlkY29tbS5vcmcvY29ubmVjdGlvbnMvMS4wIl0sInNlcnZpY2VzIjpbeyJpZCI6IiNpbmxpbmUtMCIsInNlcnZpY2VFbmRwb2ludCI6Imh0dHBzOi8vbWVkaWF0b3IuZGV2LmFuaW1vLmlkIiwidHlwZSI6ImRpZC1jb21tdW5pY2F0aW9uIiwicmVjaXBpZW50S2V5cyI6WyJkaWQ6a2V5Ono2TWtvSG9RTUphdU5VUE5OV1pQcEw3RGs1SzNtQ0NDMlBpNDJGY3FwR25iampMcSJdLCJyb3V0aW5nS2V5cyI6W119LHsiaWQiOiIjaW5saW5lLTEiLCJzZXJ2aWNlRW5kcG9pbnQiOiJ3c3M6Ly9tZWRpYXRvci5kZXYuYW5pbW8uaWQiLCJ0eXBlIjoiZGlkLWNvbW11bmljYXRpb24iLCJyZWNpcGllbnRLZXlzIjpbImRpZDprZXk6ejZNa29Ib1FNSmF1TlVQTk5XWlBwTDdEazVLM21DQ0MyUGk0MkZjcXBHbmJqakxxIl0sInJvdXRpbmdLZXlzIjpbXX1dfQ' const agentConfig: InitConfig = { - label: `Aries Framework JavaScript ${name}`, + label: `Credo ${name}`, walletConfig: { id: name, key: name, diff --git a/snippets/current/src/mediator-setup.ts b/snippets/current/src/mediator-setup.ts index 86572a8b..867ff4fe 100644 --- a/snippets/current/src/mediator-setup.ts +++ b/snippets/current/src/mediator-setup.ts @@ -16,7 +16,7 @@ const name = 'mediator' const port = 3001 const agentConfig: InitConfig = { - label: `Aries Framework JavaScript ${name}`, + label: `Credo ${name}`, walletConfig: { id: name, key: name, diff --git a/src/components/HomepageFeatures/index.tsx b/src/components/HomepageFeatures/index.tsx index 0d198c2a..ef846913 100644 --- a/src/components/HomepageFeatures/index.tsx +++ b/src/components/HomepageFeatures/index.tsx @@ -14,8 +14,8 @@ const FeatureList: FeatureItem[] = [ Svg: require('@site/static/img/easy-to-use.svg').default, description: ( <> - Aries JavaScript was designed with the mindset that building self-sovereign identity solutions should be easy - and straightforward. + Credo was designed with the mindset that building self-sovereign identity solutions should be easy and + straightforward. ), }, @@ -24,7 +24,7 @@ const FeatureList: FeatureItem[] = [ Svg: require('@site/static/img/multiplatform.svg').default, description: ( <> - With support for Node.js and React Native, Aries JavaScript allows you to reuse the same code base in different + With support for Node.js and React Native, Credo allows you to reuse the same code base in different environments. There is no need to implement the same functionality multiple times. ), @@ -32,7 +32,7 @@ const FeatureList: FeatureItem[] = [ { title: 'Based on the latest standards', Svg: require('@site/static/img/standards.svg').default, - description: <>By keeping up with the latest standards, we ensure Aries JavaScript is secure and interoperable., + description: <>By keeping up with the latest standards, we ensure Credo is secure and interoperable., }, ] diff --git a/src/pages/index.tsx b/src/pages/index.tsx index 6c7ecf69..30019fac 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -26,7 +26,7 @@ function HomepageHeader() { export default function Home(): JSX.Element { const { siteConfig } = useDocusaurusContext() return ( - +
diff --git a/versioned_docs/version-0.3/ecosystem/index.md b/versioned_docs/version-0.3/ecosystem/index.md index 00783c75..9457461f 100644 --- a/versioned_docs/version-0.3/ecosystem/index.md +++ b/versioned_docs/version-0.3/ecosystem/index.md @@ -14,8 +14,8 @@ Currently, Aries JavaScript is composed out of three separate repositories: You can find their documentation here: -1. [Aries Framework JavaScript](https://aries.js.org/guides) -2. [Aries Framework JavaScript Extensions](https://aries.js.org/guides/extensions) +1. [Aries Framework JavaScript](https://credo.js.org/guides) +2. [Aries Framework JavaScript Extensions](https://credo.js.org/guides/extensions) 3. [Aries Mobile Agent React Native (Bifold)](https://github.com/hyperledger/aries-mobile-agent-react-native/blob/main/README.md) ### Aries Framework JavaScript diff --git a/versioned_docs/version-0.4/concepts/agents.md b/versioned_docs/version-0.4/concepts/agents.md new file mode 100644 index 00000000..5f6c9b4d --- /dev/null +++ b/versioned_docs/version-0.4/concepts/agents.md @@ -0,0 +1,61 @@ +# Agents + +When working with any Aries implementation, you will interact with an Aries +agent. This will be either directly or via a REST API, like [the Aries +framework REST +API](https://github.com/hyperledger/aries-framework-javascript-ext/tree/main/packages/rest). + +### Characteristics + +An Aries agent has three essential characteristics: + +1. It acts as a fiduciary on behalf of a single identity owner (or, for agents + of things like IoT devices, pets, and similar things, a single controller). +1. It holds cryptographic keys that uniquely embody its delegated + authorization. +1. It interacts using interoperable DIDComm protocols, more on that later. + +What this means is that an Aries agent will act your behalf to issue create +connections, issue credentials, send messages etc. It also have a cryptographic +toolkit with which it can uniquely, securely and verifiably operate. And lastly +it interacts with other entities, this could be another agent, via [DIDComm +protocols](https://identity.foundation/didcomm-messaging/spec/) later on. The +Aries agent in the context of the Aries JavaScript ecosystem is your entry-point +to all of the functionality. + +### Categories + +There are many categories of Aries agents and we will group them into two +categories; a mobile agent and a cloud agent. These agents are grouped based on +their "location", e.g. a mobile wallet or server. Some other categories are a +static, thin, thick and rich Aries agents. These agents are grouped based on +their complexity instead of their "location". The Aries JavaScript ecosystem +allows you to create a mobile agent and a cloud agent. It also allows any of +the complexity categorized agents. + +### Examples + +Some examples of things that are Aries agent-like (since the definition can be +bit loose, these examples might help to get a clearer picture): + +**A mobile wallet** + +A mobile wallet, like +[aries-mobile-agent-react-native](https://github.com/hyperledger/aries-mobile-agent-react-native) +, can be used to create connections, send basic messages, hold credentials, +etc. In the real world this could be an application that contains data like an +official drivers license. + +**An Identity hub** + +An [Identity Hub](https://didproject.azurewebsites.net/docs/hub-overview.html) +is a personal data store that gives complete control to their owner. It allows +for secure sensitive data storage and sharing. Since everyone has multiple +devices these can be used as a more central point for your data. + +### Useful resources + +- [Hyperledger Aries RFC - 004: + Agents](https://github.com/hyperledger/aries-rfcs/blob/main/concepts/0004-agents/README.md) +- [Aries Framework JavaScript - Getting + Started](https://github.com/hyperledger/aries-framework-javascript/tree/main/docs/getting-started) diff --git a/versioned_docs/version-0.4/concepts/did-and-didcomm.md b/versioned_docs/version-0.4/concepts/did-and-didcomm.md new file mode 100644 index 00000000..b18771b6 --- /dev/null +++ b/versioned_docs/version-0.4/concepts/did-and-didcomm.md @@ -0,0 +1,34 @@ +# DIDs and DIDComm + +### DIDs + +[DIDs](https://www.w3.org/TR/did-core/), short for Decentralized identifiers, +are a type of identifier that enables verifiable, decentralized identity. A DID +can refer to any subject, a person, organization, etc. DIDs are decoupled from +centralized registries, identity providers and certificate authorities. + +### DID Documents + +A DID by itself does not contain a lot of information. So in order to get some +metadata we have to resolve the DID to get a [DID Document](https://www.w3.org/TR/did-core/#dfn-did-documents). With this +document we can get data such as their public key, proof mechanisms and their +service endpoints. This means that we can check the validity, encrypt +one-to-one messages and send it to their service endpoint. + +### DIDComm + +In the previous section sending a message to their service endpoint is +mentioned. This is a nice feature, but is lacking a definition of how it should +work. [DIDComm](https://identity.foundation/didcomm-messaging/spec/), we will +only discuss V1 here, defines this. DIDComm is designed to be private, secure, +transport-agnostic, interoperable and much more. This means that you can +securely send a message from as Alice to Bob securely via bluetooth, HTTP, +WebSockets, etc. + +When working with the tools available inside the Aries JavaScript ecosystem, +deep knowledge of DIDComm is not required. + +### Useful Resources + +- [DID spec](https://www.w3.org/TR/did-core/) +- [DIDComm spec](https://identity.foundation/didcomm-messaging/spec/) diff --git a/versioned_docs/version-0.4/concepts/index.md b/versioned_docs/version-0.4/concepts/index.md new file mode 100644 index 00000000..581483ab --- /dev/null +++ b/versioned_docs/version-0.4/concepts/index.md @@ -0,0 +1,9 @@ +import DocCardList from '@theme/DocCardList'; + +# Concepts + +In this section we will discuss the general concepts that are used inside the +aries-javascript ecosystem. These concepts will help you understand the basics +on a high level. + + diff --git a/versioned_docs/version-0.4/concepts/platform-and-environment.md b/versioned_docs/version-0.4/concepts/platform-and-environment.md new file mode 100644 index 00000000..a8246027 --- /dev/null +++ b/versioned_docs/version-0.4/concepts/platform-and-environment.md @@ -0,0 +1,3 @@ +# Platform and Environment + +[Aries framework JavaScript](https://github.com/hyperledger/aries-framework-javascript) is developed to support a [Node.JS](https://nodejs.org) and [React Native](https://reactnative.dev) environment. With this it is entirely possible to build an entire SSI ecosystem with Aries Framework JavaScript. This would use Node.JS as an issuer as a verifier, and uses React Native as a holder. diff --git a/versioned_docs/version-0.4/ecosystem/index.md b/versioned_docs/version-0.4/ecosystem/index.md new file mode 100644 index 00000000..9457461f --- /dev/null +++ b/versioned_docs/version-0.4/ecosystem/index.md @@ -0,0 +1,42 @@ +# The Aries JavaScript Ecosystem + +The Aries JavaScript ecosystem includes various components that are spread across multiple repositories. In this section we'll go over what these components are and how the relate to one another. + +## Repositories + +Currently, Aries JavaScript is composed out of three separate repositories: + +1. [Aries Framework JavaScript](https://github.com/hyperledger/aries-framework-javascript) +2. [Aries Framework JavaScript Extensions](https://github.com/hyperledger/aries-framework-javascript-ext) +3. [Aries Mobile Agent React Native (Bifold)](https://github.com/hyperledger/aries-mobile-agent-react-native) + +## Documentation + +You can find their documentation here: + +1. [Aries Framework JavaScript](https://credo.js.org/guides) +2. [Aries Framework JavaScript Extensions](https://credo.js.org/guides/extensions) +3. [Aries Mobile Agent React Native (Bifold)](https://github.com/hyperledger/aries-mobile-agent-react-native/blob/main/README.md) + +### Aries Framework JavaScript + +Aries Framework JavaScript (AFJ) is at the core of the Aries JavaScript ecosystem. AFJ provides all the functionality related to cryptography, storage, messaging and more that is required + +## Contributing in the Aries JS Ecosystem + +Consider attending our weekly meetings to become aware of the current development cadence. + +- [Aries Framework JS Meeting](https://wiki.hyperledger.org/display/ARIES/Framework+JS+Meetings) +- [Aries Bifold Meeting](https://wiki.hyperledger.org/display/ARIES/Aries+Bifold+User+Group) +- [Aries Working Group Meeting](https://wiki.hyperledger.org/display/ARIES/Aries+Working+Group) + +### Developer Contributions + +Each project maintains its own CONTRIBUTING guidance: + +- [AFJ CONTRIBUTING.md](https://github.com/hyperledger/aries-framework-javascript/blob/main/CONTRIBUTING.md) +- [AFJ-Ext CONTRIBUTING.md](https://github.com/hyperledger/aries-framework-javascript-ext/blob/main/CONTRIBUTING.md) +- [Aries Bifold CONTRIBUTING](https://github.com/hyperledger/aries-mobile-agent-react-native/blob/main/CONTRIBUTING) + +Each project has a significant set of developer conventions, checklists, templates, and actions to provide guidance and boundaries for a contribution. +Consider looking at previous issues and their corresponding PRs to get a sense of the latest. diff --git a/versioned_docs/version-0.4/extensions/index.md b/versioned_docs/version-0.4/extensions/index.md new file mode 100644 index 00000000..dd4e0569 --- /dev/null +++ b/versioned_docs/version-0.4/extensions/index.md @@ -0,0 +1,16 @@ +import DocCardList from '@theme/DocCardList'; + +# Extensions + +Aries Framework JavaScript Extensions is an extensions repository to Aries Framework JavaScript (AFJ). It hosts libraries built on top of Aries Framework JavaScript that don't necessarily belong to the core of the project. + +Currently, there are four packages in the extension repository. Example extension libraries include React Hooks for AFJ and a REST API wrapper. + +| Package | Version | Description | +| ---------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------- | +| [`@aries-framework/redux-store`](https://www.npmjs.com/package/@aries-framework/redux-store) | ![@aries-framework/redux-store version](https://img.shields.io/npm/v/@aries-framework/redux-store) | Redux toolkit wrapper around Aries Framework JavaScript | +| [`@aries-framework/rest`](https://www.npmjs.com/package/@aries-framework/rest) | ![@aries-framework/rest version](https://img.shields.io/npm/v/@aries-framework/rest) | Rest endpoint wrapper for using your agent over HTTP | +| [`@aries-framework/react-hooks`](https://www.npmjs.com/package/@aries-framework/react-hooks) | ![@aries-framework/react-hooks version](https://img.shields.io/npm/v/@aries-framework/react-hooks) | React Hooks for data handling and agent interaction | +| [`@aries-framework/push-notifications`](https://www.npmjs.com/package/@aries-framework/push-notifications) | ![@aries-framework/push-notifications version](https://img.shields.io/npm/v/@aries-framework/push-notifications) | Push notification plugin for Aries Framework JavaScript | + + diff --git a/versioned_docs/version-0.4/extensions/push-notifications.md b/versioned_docs/version-0.4/extensions/push-notifications.md new file mode 100644 index 00000000..abf736e3 --- /dev/null +++ b/versioned_docs/version-0.4/extensions/push-notifications.md @@ -0,0 +1,71 @@ +# Push Notifications + +The Push Notifications plugin package provides a way for you to register your APNs and Firebase push notification token at an agent, allowing you to use push notifications directly from AFJ. + +:::note + +This document is for version **`0.5.x`** of the `@aries-framework/push-notifications` package, that works with `@aries-framework/core` version **`0.4.x`**. Extension packages (such as Push Notifications) are versioned separately from the core packages. + +::: + +## Installation + +To add the Push Notifications plugin package to your existing project simply run: + + + +## npm + +```sh +npm i @aries-framework/push-notifications +``` + +## Yarn + +```sh +yarn add @aries-framework/push-notifications +``` + + + +## Usage + +```ts +import { PushNotificationsApnsModule, PushNotificationsFcmModule } from '@aries-framework/push-notifications' +import { } from '@aries-framework/core' + +const agent = new Agent({ + /** agent config... */, + // Register the modules + modules: { + pushNotificationsApns: new PushNotificationsApnsModule(), + pushNotificationsFcm: new PushNotificationsFcmModule(), + }, + } +}) + +await agent.initialize() + +/* -- iOS -- */ + +// To send apns device info to another agent you have to acquire the device token and send it. +await agent.modules.pushNotificationsApns.sendDeviceInfo( + 'a-valid-connection-id' + { deviceToken: '123' }, +) + +// To get the device info and the used service back from the other agent +await agent.modules.pushNotificationsApns.getDeviceInfo('a-valid-connection') + +/* -- fcm / Android -- */ + +// To send fcm, primarily Android, device info to another agent you have to acquire the device token and send it. +await agent.modules.pushNotificationsFcm.sendDeviceInfo( + 'a-valid-connection-id' + { deviceToken: '123' }, +) + +// To get the device info and the used service back from the other agent +await agent.modules.pushNotificationsFcm.getDeviceInfo('a-valid-connection') + +``` diff --git a/versioned_docs/version-0.4/extensions/react-hooks.md b/versioned_docs/version-0.4/extensions/react-hooks.md new file mode 100644 index 00000000..c0592047 --- /dev/null +++ b/versioned_docs/version-0.4/extensions/react-hooks.md @@ -0,0 +1,108 @@ +# React Hooks + +The React Hooks package exposes useful React hooks that allow you to easily interact with AFJ from a React client application. + +These hooks provide a simple way to query agent data in a client application, allowing you to focus on the user interface. + +:::note + +This document is for version **`0.5.x`** of the `@aries-framework/react-hooks` package, that works with `@aries-framework/core` version **`0.4.x`**. Extension packages (such as React Hooks) are versioned separately from the core packages. + +::: + +## Installation + +To add the React Hooks package to your existing project simply run: + + + +## npm + +```sh +npm i @aries-framework/react-hooks@^0.5 +``` + +## Yarn + +```sh +yarn add @aries-framework/react-hooks@^0.5 +``` + + + +## Usage + +This package exposes useful React hooks that allow you to easily interact with AFJ. + +Everything exported from Hooks: + +```ts +import AgentProvider, { + useAgent, + useConnections, + useConnectionById, + useCredentials, + useCredentialById, + useCredentialByState, + useProofs, + useProofById, + useProofByState, +} from '@aries-framework/react-hooks' +``` + +First step is to wrap your entire app in our ``. The provider takes an initialized agent. The base of your app should look something like this: + +```tsx +import AgentProvider from '@aries-framework/react-hooks' + +const App = () => { + const [agent, setAgent] = useState(undefined) + + const initializeAgent = async () => { + const appAgent = new Agent({ + /* agent options */ + }) + await appAgent.initialize() + setAgent(appAgent) + } + + useEffect(() => { + initializeAgent() + }, []) + + if (!agent) return + + return /* Your app here */ +} +``` + +And that's it! Your app should be set up to receive all the necessary data your app will need! Now let's see how we actually get that data to our components. + +The `useAgent` hook returns `{ agent, loading }` so anytime you need access to any of the methods tied to the agent, you can `useAgent()` anywhere. + +The following is an example of how you could use the `useConnections` hook to render a full list of all a user's connections. + +```ts +import { useConnections } from '@aries-framework/react-hooks' + +const MyConnectionsComponent = () => { + // all base hooks return an array of objects and a loading boolean + const { connections, loading } = useConnections() + + return } /> +} +``` + +The three base hooks: `useConnections`, `useCredentials`, and `useProofs` work just like the above! Just call the hook, destructure the data, and pass it through! + +Each base hook has a `ById` version that returns a singular record. For example if I wanted only a specific connectionRecord, I'd do this. + +```ts +const connection = useConnectionById(id) +``` + +More commonly, you'll want to get a filtered list of records based off of their state. Well, Hooray! We have a `ByState` version as well. For example, you can do this: + +```ts +const credentials = useCredentialByState(CredentialState.OfferReceived) +``` diff --git a/versioned_docs/version-0.4/extensions/redux-store.md b/versioned_docs/version-0.4/extensions/redux-store.md new file mode 100644 index 00000000..c0c42475 --- /dev/null +++ b/versioned_docs/version-0.4/extensions/redux-store.md @@ -0,0 +1,31 @@ +# Redux Store + +The Redux Store is an implementation of state management that can be used to build React & React Native SSI clients using AFJ. + +The Redux Store allows you to integrate state management for the most important parts of using AFJ in a client application (mediation, connections, credentials and proofs), allowing you to sync UI state with the state of the agent as it interacts with other agents through the framework. + +:::note + +This document is for version **`0.4.x`** of the `@aries-framework/redux-store` package, that works with `@aries-framework/core` version **`0.4.x`**. Extension packages (such as Redux Store) are versioned separately from the core packages. + +::: + +## Installation + +To add the Redux Store package to your existing project simply run: + + + +## npm + +```sh +npm i @aries-framework/redux-store +``` + +## Yarn + +```sh +yarn add @aries-framework/redux-store +``` + + diff --git a/versioned_docs/version-0.4/extensions/rest.md b/versioned_docs/version-0.4/extensions/rest.md new file mode 100644 index 00000000..4614a54e --- /dev/null +++ b/versioned_docs/version-0.4/extensions/rest.md @@ -0,0 +1,52 @@ +# REST API + +The Aries Framework JavaScript (AFJ) REST API provides simple RESTful endpoints for AFJ methods, to allow you stand up an agent for communication over the internet instantly. You simply provide your agent configuration. The REST endpoints allow you to interact with your agent over HTTP and WebSockets. + +The AFJ REST API is the most convenient way for self-sovereign identity (SSI) developers to interact with SSI agents. + +- ⭐ **Endpoints** to create connections, issue credentials, and request proofs. +- 💻 **CLI** that makes it super easy to start an instance of the REST API. +- 🌐 **Interoperable** with all major Aries implementations. + +:::danger + +The `@aries-framework/rest` package has not been updated to work with the latest version (**`0.4.x`**) of `@aries-framework/core`. The documentation in this section is for version **`0.9.x`** of the `@aries-framework/rest` package, that works with `@aries-framework/core` version **`0.2.x`**. Extension packages (such as REST API) are versioned separately from the core packages. + +::: + +## Quick Setup + +:::info + +This guide assumes you have followed the install guides for the framework (See [Getting Started](../../getting-started/index.md) section) for your platform and a valid [Node.js](https://nodejs.org) project setup. + +::: + +Using the CLI is the easiest way to get started with REST API. + +You can do this directly on your machine. + +### Directly on computer + +After installing and confirming that Libindy is installed, simply run: + +```sh +npx -p @aries-framework/rest afj-rest start \ + --label "AFJ Rest" \ + --wallet-id "walletId" \ + --wallet-key "walletKey" \ + --endpoint http://localhost:5000 \ + --admin-port 3000 \ + --outbound-transport http \ + --inbound-transport http 5000 +``` + +The REST API provides an OpenAPI schema that can easily be viewed using the SwaggerUI that is provided with the server. The endpoint documentation can be viewed at the `/docs` endpoint (e.g. ). + +### Configuration + +To find out all available configuration options from the CLI, you can run the CLI command with `--help`. This will print a full list of all available options. + +```sh +npx -p @aries-framework/rest afj-rest start --help +``` diff --git a/versioned_docs/version-0.4/getting-started/index.md b/versioned_docs/version-0.4/getting-started/index.md new file mode 100644 index 00000000..2ab392dc --- /dev/null +++ b/versioned_docs/version-0.4/getting-started/index.md @@ -0,0 +1,19 @@ +import DocCardList from '@theme/DocCardList'; + +# Getting started + +In this section we will go over everything you need to get started on a technical level. First there are some general prerequisites for Node.JS and React Native. Aries Framework JavaScript works for creating both server-side applications (commonly but not always for creating issuer and verifier agents) and mobile applications (commonly holder agents). + +Based on the platform you want to work on, the installation guides you should follow are the same, but some steps may differ. + +**Do you want to build a mobile app?** + +- Follow the [Prerequisites](./prerequisites.md). +- Follow the [Agent Setup](./set-up) guide. + +**Do you want to build a server-side app?** + +- Follow the [Prerequisites](./prerequisites.md). +- Follow the [Agent Setup](./set-up) guide. + + diff --git a/versioned_docs/version-0.4/getting-started/prerequisites.md b/versioned_docs/version-0.4/getting-started/prerequisites.md new file mode 100644 index 00000000..975a599d --- /dev/null +++ b/versioned_docs/version-0.4/getting-started/prerequisites.md @@ -0,0 +1,79 @@ +# Prerequisites + +To work with [Aries Framework JavaScript](https://github.com/hyperledger/aries-framework-javascript) we need to install some dependencies and set-up our Node.JS environment. Even when creating a mobile app in React Native, we need Node.JS installed. We will go over the specific installation process for each platform. Go ahead and pick your system of choice to get started! + +The specific items that we set-up: + +- [Node.JS](https://nodejs.org) - v16 or v18 +- [yarn](https://classic.yarnpkg.com/lang/en/docs/install) or [npm](https://www.npmjs.com/) +- Node.JS or React Native project. + +### Node.JS + +NodeJS is the most popular JavaScript runtime environment excluding browsers. It can run on your desktop or even a server. + + + +#### Windows + +You can download it from the [Node.JS Website](https://nodejs.org/en/download/) + +#### macOS + +Make sure you have [Homebrew](https://brew.sh/) installed. If not you can install it with the following command: + +```console +/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" +``` + +Then install Node.JS with the following command: + +```console +brew install nodejs +``` + +Alternatively, you can download it from the [Node.JS Website](https://nodejs.org/en/download/) + +#### Linux + +Either follow one of the specific steps for installing Node.JS on linux below, or you can download it directly from the [Node.JS Website](https://nodejs.org/en/download/) + +##### Arch Linux + +``` +pacman -S nodejs npm +``` + +##### Debian + +``` +curl -fsSL https://deb.nodesource.com/setup_18.x | bash - +apt-get install -y nodejs +``` + +##### Red Hat + +``` +curl -sL https://rpm.nodesource.com/setup_18.x | bash - +yum install nodejs +``` + + + +### NPM + +The Node Package Manager comes pre-bundled with the NodeJS installation from above. + +### Yarn + +> Only required when not using npm + +For every platform, the installation of yarn is the same. + +```console +npm install --global yarn +``` + +### Project Setup + +Finally, you need to make sure you have a project set-up using Node.JS or React Native. If you're not familiar with setting up a project, we suggest following the [Introduction to Node.JS](https://nodejs.dev/en/learn/) or [React Native Quickstart](https://reactnative.dev/docs/environment-setup) guides. diff --git a/versioned_docs/version-0.4/getting-started/set-up/anoncreds-rs.md b/versioned_docs/version-0.4/getting-started/set-up/anoncreds-rs.md new file mode 100644 index 00000000..49b4e31c --- /dev/null +++ b/versioned_docs/version-0.4/getting-started/set-up/anoncreds-rs.md @@ -0,0 +1,102 @@ +# AnonCreds RS + +[AnonCreds RS](https://github.com/hyperledger/anoncreds-rs) is a direct implementation of the [AnonCreds V1.0 specification](https://hyperledger.github.io/anoncreds-spec/) that provides functionality like; creating a schema object, creating a credential definition object, creating a credential, verifying a proof presentation and much more. + +:::caution + +Support for the AnonCreds RS library in Aries Framework JavaScript is currently experimental. We recommend new projects to use AnonCreds RS from the start, and also to migrate existing projects to AnonCreds, from the Indy Sdk. However, projects may experience some issues. If you encounter any issues, please [open an issue](https://github.com/hyperledger/aries-framework-javascript/issues/new). + +Currently, there are few limitations to using AnonCreds RS. + +- When running in Node.JS, only Node.JS 18 is supported for now. See [Supported Node.JS versions for AnonCreds RS](#supported-nodejs-versions-for-anoncreds-rs) +- Install scripts rely on bash command substitution to get the proper binaries for each system architecture and platform. Therefore, if you are under Windows, you must configure `npm` or `yarn` to use a bash-compliant shell (e.g. `npm config set script-shell "C:\\Program Files\\git\\bin\\bash.exe"`) + +::: + +### Installing AnonCreds RS + +When using Aries Framework JavaScript with AnonCreds RS, there are a few extra dependencies that need to be installed. We need to install `@hyperledger/anoncreds` package, which contains the interfaces, and `@hyperledger/anoncreds-rs` package which is an implementation which depends on a wrapper of anoncreds-rs. Secondly, we need to add native bindings for the specific platform `@hyperledger/anoncreds-`. Currently there are bindings for Node.JS, as `@hyperledger/anoncreds-nodejs`, and React Native as `@hyperlegder/anoncreds-react-native`. + + + +# Node.JS + +```console +yarn add @aries-framework/anoncreds@^0.4.0 @aries-framework/anoncreds-rs@^0.4.0 @hyperledger/anoncreds-nodejs@^0.1.0 +``` + +# React Native + +```console +yarn add @aries-framework/anoncreds@^0.4.0 @aries-framework/anoncreds-rs@^0.4.0 @hyperledger/anoncreds-react-native@^0.1.0 +``` + + + +### Adding AnonCreds RS to the agent + +After installing the dependencies, we should register both the `AnonCreds` and `AnonCredsRs` module on the agent. + + + +# Node.JS + +```typescript showLineNumbers set-up-anoncreds-rs.ts section-1 + +``` + +# React Native + +```typescript showLineNumbers set-up-anoncreds-rs-rn.ts section-1 + +``` + + + +### Configuration + +As you can see, the AnonCreds module takes a list of registry modules. These modules will be used to resolve the AnonCreds objects. We recommend [Indy VDR](./indy-vdr) as an AnonCreds registry for Hyperledger Indy networks, but [Indy SDK](./indy-sdk) can also be used. + +### Supported Node.JS versions for AnonCreds RS + +Due to an issue in `ref-napi` (which is used in the Node.JS bindings for AnonCreds RS), performance for AnonCreds RS in Node.JS is not as expected. A patched version for `ref-napi` has been published that fixes this issue, but this only works in Node.JS 18+. + +To use AnonCreds RS in Node.JS, make sure you're using Node.JS 18 and patch the `ref-napi` package to point towards `@2060.io/ref-napi` in your `package.json`: + + + +# NPM + +Using [NPM `overrides`](https://docs.npmjs.com/cli/v9/configuring-npm/package-json#overrides) we can point the `ref-napi` package to `@2060.io/ref-napi`. + +```json +{ + "overrides": { + "ref-napi": "npm:@2060.io/ref-napi" + } +} +``` + +# Yarn + +Using [Yarn `resolutions`](https://classic.yarnpkg.com/lang/en/docs/selective-version-resolutions/) we can point the `ref-napi` package to `@2060.io/ref-napi`. + +```json +{ + "resolutions": { + "ref-napi": "npm:@2060.io/ref-napi" + } +} +``` + + + +:::info + +See the following issues for more information on the performance botleneck + +- https://github.com/hyperledger/aries-askar/issues/76 +- https://github.com/node-ffi-napi/ref-napi/issues/72 +- https://github.com/node-ffi-napi/ref-napi/pull/73 + +::: diff --git a/versioned_docs/version-0.4/getting-started/set-up/aries-askar.md b/versioned_docs/version-0.4/getting-started/set-up/aries-askar.md new file mode 100644 index 00000000..627158e3 --- /dev/null +++ b/versioned_docs/version-0.4/getting-started/set-up/aries-askar.md @@ -0,0 +1,103 @@ +# Aries Askar + +[Aries Askar](https://github.com/hyperledger/aries-askar) provides secure, encrypted storage and cryptographic support for encrypting, decrypting, signing and verifying data. It also provides both the `Wallet` and `StorageService` implementations for the agent. + +:::caution +Although Aries Askar is stable and already used in production in agents such as [Aries Cloud Agent Python](https://github.com/hyperledger/aries-cloudagent-python), support for Aries Askar in Aries Framework JavaScript is currently experimental. We recommend new projects to use Aries Askar from the start, and also to migrate existing projects to Aries Askar. However, projects may experience some issues. If you encounter any issues, please [open an issue](https://github.com/hyperledger/aries-framework-javascript/issues/new). + +Currently, there are few limitations to using Aries Askar. + +- When running in Node.JS, only Node.JS 18 is supported for now. See [Supported Node.JS versions for Aries Askar](#supported-nodejs-versions-for-aries-askar) +- Install scripts rely on bash command substitution to get the proper binaries for each system architecture and platform. Therefore, if you are under Windows, you must configure `npm` or `yarn` to use a bash-compliant shell (e.g. `npm config set script-shell "C:\\Program Files\\git\\bin\\bash.exe"`) + +::: + +:::tip + +If you're upgrading from the Indy SDK to Aries Askar, see [Migrating from an Indy SDK Wallet to Aries Askar](../updating/update-indy-sdk-to-askar) + +::: + +### Installing Aries Askar + +When using Aries Framework JavaScript with Aries Askar, there are a few extra dependencies that need to be installed. We need to install the `@aries-framework/askar` package, which implements the needed interfaces for the agent. Secondly, we need to add native bindings for the specific platform `@hyperledger/aries-askar-`. Currently there are bindings for Node.JS, as `@hyperledger/aries-askar-nodejs`, and React Native as `@hyperlegder/aries-askar-react-native`. + + + +# Node.JS + +```console +yarn add @aries-framework/askar@^0.4.0 @hyperledger/aries-askar-nodejs@^0.1.0 +``` + +# React Native + +```console +yarn add @aries-framework/askar@^0.4.0 @hyperledger/aries-askar-react-native@^0.1.0 +``` + + + +### Adding Aries Askar to the Agent + +After installing the dependencies, we can register the Askar Module on the agent. + + + +# Node.JS + +```typescript showLineNumbers set-up-askar.ts section-1 + +``` + +# React Native + +```typescript showLineNumbers set-up-askar-rn.ts section-1 + +``` + + + +### Supported Node.JS versions for Aries Askar + +Due to an issue in `ref-napi` (which is used in the Node.JS bindings for Aries Askar), performance for Aries Askar in Node.JS is not as expected. A patched version for `ref-napi` has been published that fixes this issue, but this only works in Node.JS 18+. + +To use Aries Askar in Node.JS, make sure you're using Node.JS 18 and patch the `ref-napi` package to point towards `@2060.io/ref-napi` in your `package.json`: + + + +# NPM + +Using [NPM `overrides`](https://docs.npmjs.com/cli/v9/configuring-npm/package-json#overrides) we can point the `ref-napi` package to `@2060.io/ref-napi`. + +```json +{ + "overrides": { + "ref-napi": "npm:@2060.io/ref-napi" + } +} +``` + +# Yarn + +Using [Yarn `resolutions`](https://classic.yarnpkg.com/lang/en/docs/selective-version-resolutions/) we can point the `ref-napi` package to `@2060.io/ref-napi`. + +```json +{ + "resolutions": { + "ref-napi": "npm:@2060.io/ref-napi" + } +} +``` + + + +:::info + +See the following issues for more information on the performance bottleneck + +- https://github.com/hyperledger/aries-askar/issues/76 +- https://github.com/node-ffi-napi/ref-napi/issues/72 +- https://github.com/node-ffi-napi/ref-napi/pull/73 + +::: diff --git a/versioned_docs/version-0.4/getting-started/set-up/cheqd/index.md b/versioned_docs/version-0.4/getting-started/set-up/cheqd/index.md new file mode 100644 index 00000000..a08c21f7 --- /dev/null +++ b/versioned_docs/version-0.4/getting-started/set-up/cheqd/index.md @@ -0,0 +1,94 @@ +import DocCardList from '@theme/DocCardList'; + +# cheqd + +[cheqd](https://github.com/cheqd/sdk) is a blockchain network, built in the Cosmos ecosystem for Self-Sovereign Identity (SSI). The cheqd Network leverages the [cheqd DID method](https://docs.cheqd.io/identity/architecture/adr-list/adr-001-cheqd-did-method) and enables [DID-Linked Resources](https://docs.cheqd.io/identity/architecture/adr-list/adr-002-did-linked-resources) to be written to the network, associated with a DID and controlled using the verification methods in the DID Document. + +Through this approach, the cheqd Network is able to natively support the [Ledger Agnostic AnonCreds Specification (v1.0)](https://hyperledger.github.io/anoncreds-spec/) through its [AnonCreds Object Method](https://docs.cheqd.io/identity/guides/anoncreds) (as well as VC-JWT and JSON-LD). + +cheqd also has a dedicated token, $CHEQ, used for identity writes to the network, voting in a decentralised governance framework as well as for various payment flows between verifiers, holders and issuers of Verifiable Credentials. + +### Installing cheqd + +When using Aries Framework JavaScript with the cheqd, there's a few extra dependencies that need to be installed. We need to install the `@aries-framework/cheqd` package, which implements the needed interfaces for the agent. + +#### React Native + +To enable react-native support we need to follow the steps below + +In the package.json file add the below code snippet, which replaces the cosmjs dependencies witht he cosmjs-rn packages + + + +# NPM + +Using [NPM `overrides`](https://docs.npmjs.com/cli/v9/configuring-npm/package-json#overrides) we can point the `cosmjs` packages to `cosmjs-rn`. + +```json +{ + "overrides": { + "@cosmjs/amino": "npm:@cosmjs-rn/amino@^0.27.1", + "@cosmjs/encoding": "npm:@cosmjs-rn/encoding@^0.27.1", + "@cosmjs/math": "npm:@cosmjs-rn/math@^0.27.1", + "@cosmjs/stargate": "npm:@cosmjs-rn/stargate@^0.27.1", + "@cosmjs/tendermint-rpc": "npm:@cosmjs-rn/tendermint-rpc@^0.27.1", + "@cosmjs/utils": "npm:@cosmjs-rn/utils@^0.27.1", + "@cosmjs/proto-signing": "npm:@cosmjs-rn/proto-signing@^0.27.1", + "@cosmjs/crypto": "npm:@cosmjs-rn/crypto@^0.27.1" + } +} +``` + +# Yarn + +Using [Yarn `resolutions`](https://classic.yarnpkg.com/lang/en/docs/selective-version-resolutions/) we can point the `cosmjs` packages to `cosmjs-rn`. + +```json +{ + "resolutions": { + "@cosmjs/amino": "npm:@cosmjs-rn/amino@^0.27.1", + "@cosmjs/encoding": "npm:@cosmjs-rn/encoding@^0.27.1", + "@cosmjs/math": "npm:@cosmjs-rn/math@^0.27.1", + "@cosmjs/stargate": "npm:@cosmjs-rn/stargate@^0.27.1", + "@cosmjs/tendermint-rpc": "npm:@cosmjs-rn/tendermint-rpc@^0.27.1", + "@cosmjs/utils": "npm:@cosmjs-rn/utils@^0.27.1", + "@cosmjs/proto-signing": "npm:@cosmjs-rn/proto-signing@^0.27.1", + "@cosmjs/crypto": "npm:@cosmjs-rn/crypto@^0.27.1" + } +} +``` + + + +Following that we need to add a buffer polyfill + +```console +yarn add buffer +``` + +create a shim.js file with the below code snippet + +```typescript +import { Buffer } from 'buffer' +global.Buffer = Buffer +``` + +`import shim.js` file into your file where the App is imported + +### Adding the cheqd to the Agent + +After installing the dependencies, we can register the cheqd Module on the agent by adding the below code snippet to the agent constructor. + + + +```typescript showLineNumbers set-up-cheqd.ts section-1 + +``` + +The cosmosPayerSeed can be a 32-bit seed value or a mnemonic, which can be managed using Keplr wallet which can be installed on a mobile or as a browser extension in chrome or safari which allows user's to create accounts, exchange tokens etc. To setup keplr wallet for cheqd follow this [tutorial](https://learn.cheqd.io/getting-set-up-on-cheqd/cheqd-supported-wallets/keplr-wallet) + +### Tutorials + +- [Cheqd DID Module](../../../tutorials/cheqd/index.md) +- [Register Schema and Credential Definition](../../../tutorials/registering-schema-and-credential-definition.md) +- [Issue a Credential](../../../tutorials/issue-a-credential.md) diff --git a/versioned_docs/version-0.4/getting-started/set-up/index.md b/versioned_docs/version-0.4/getting-started/set-up/index.md new file mode 100644 index 00000000..656c582b --- /dev/null +++ b/versioned_docs/version-0.4/getting-started/set-up/index.md @@ -0,0 +1,204 @@ +import DocCardList from '@theme/DocCardList'; + +# Agent Setup + +:::info + +This guide assumes you have followed the [Prerequisites](./prerequisites), and you have a valid +[Node.JS](https://nodejs.org) or [React Native](https://reactnative.dev) project setup. + +::: + +:::caution + +Aries Framework JavaScript is still in **active development**, and as such some APIs are still experimental. **When using any experimental features, make sure to use an exact version of AFJ** (`0.4.0`) instead of a range (`^0.4.0`), to prevent accidental breaking changes. If you're not leveraging any experimental features, you can use a range (`^0.4.0`) to get the latest bugfixes and features. + +For AFJ `0.4.x`, **the following features are experimental**: + +- Implementing your own `AnonCredsRegistry` and AnonCreds service implementation. +- Using the shared component libraries from `@aries-framework/aries-askar`, `@aries-framework/indy-vdr` and `@aries-framework/anoncreds-rs` +- Using OpenID4VC from the `@aries-framework/openid4vc-client` module +- W3C JWT Verifiable Credentials +- Using multi-tenancy from the `@aries-framework/tenants` module +- Using BBS+ Signatures from the `@aries-framework/bbs-signatures` module +- Using the cheqd module from the `@aries-framework/cheqd` module + +::: + +### Installing the required dependencies + +First we have to install the minimal amount of dependencies that are required +for configuring an Aries Framework JavaScript (AFJ) agent. + + + +# Node.JS + +```console +yarn add @aries-framework/core@^0.4.0 @aries-framework/node@^0.4.0 +``` + +# React Native + +```console +yarn add @aries-framework/core@^0.4.0 @aries-framework/react-native@^0.4.0 react-native-fs react-native-get-random-values +``` + + + +### Additional setup + + + +# Node.js + +No additional setup is required for Node.JS + +# React Native + +Since [React Native](https://reactnative.dev) does not have an implementation +for +[`crypto.getRandomValues()`](https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues) +we have to setup a polyfill for this. We have to do this at the entrypoint of +the application. This could is most likely `index.(js|ts|jsx|tsx)` at the root +of your application. + +```diff title="index.tsx" showLineNumbers ++ import 'react-native-get-random-values' +``` + +In addition you need add support for resolving modules with the `.cjs` extension, as this is used by some of AFJ's dependencies and not automatically supported by React Native. + +```js title="metro.config.js" showLineNumbers +module.exports = { + // ... other Metro config options ... + resolver: { + // make sure this includes `cjs` (and other extensions you need) + sourceExts: ['js', 'json', 'ts', 'tsx', 'cjs'], + }, +} +``` + +Finally, if you're using [Expo](https://expo.dev) you need to add a custom resolution 'hack' that removes support for the legacy unimodules. + +**Yarn** + +For yarn we can replace the `@unimodules/react-native-adapter` and `@unimodules/core` dependencies with an empty directory. Make sure to create the `noop` directory in the root of your project and create a `.gitkeep` file in the directory so that the directory is committed to your repository. + +```json title="package.json" showLineNumbers +{ + // ... other package.json options ... + "resolutions": { + "@unimodules/react-native-adapter": "./noop", + "@unimodules/core": "./noop" + } +} +``` + +**NPM** + +Not supported at the moment. NPM overrides work different than Yarn resolutions, and thus we can't use the same trick. If you're using NPM, feel free to open a PR with a working solution. + + + +### Setting up the agent + +> this section does not assume any knowledge of the agent configuration. +> In the [Agent Config](../tutorials/agent-config) tutorial we will discuss in-depth what every +> field in the configuration does and when to set it. + +In order to use the agent in the application we have to configure and +initialize it. This following configuration is quite generic and possibly not +enough for your specific use cases. Please refer to the +[tutorials](../tutorials/index) for a more use-case-specific agent setup. + + + +# Node.JS + +```typescript showLineNumbers set-up.ts section-1 + +``` + +# React Native + +```typescript showLineNumbers set-up-rn.ts section-1 + +``` + + + +### Adding a wallet and storage implementation + +After creating the `Agent` instance, we need to provide the agent with a wallet and storage implementation. AFJ provides a few implementations out of the box, but you can also implement your own. Currently the following Wallet and Storage implementations are supported out of the box. Follow the specific guides to set up the wallet and storage implementation of your choice. + +- [Aries Askar](./set-up/aries-askar) - Recommended. +- [Indy SDK](./set-up/indy-sdk) - Legacy. Will be deprecated in the future. + + + +### Setting up the transports + +Finally, we have to set an outbound transport that +will handle traffic from the agent. It is also possible to set an inbound +transport in the same way as the outbound transport. + + + +# Node.js + +Sets up an WS outbound and HTTP inbound and outbound transport. + +```typescript showLineNumbers set-up.ts section-2 + +``` + +# React Native + +For mobile agents the WebSocket transport is often required. We will go into +more depth about the reasons for this in the [mediation](./../../tutorials/mediation.md) section. + +```typescript showLineNumbers set-up-rn.ts section-2 + +``` + + + +### Initializing the agent + +Finally, we can initialize the agent and it's ready for use. + + + +# Node.js + +```typescript showLineNumbers set-up.ts section-3 + +``` + +# React Native + +```typescript showLineNumbers set-up-rn.ts section-3 + +``` + + + +### Next Steps + +Now that you have your agent setup, it's time to start building your application. Head over to the tutorials page to get started. + + + + + +### Useful resources + +- [Hyperledger Aries RFC - 004: + Agents](https://github.com/hyperledger/aries-rfcs/blob/main/concepts/0004-agents/README.md) diff --git a/versioned_docs/version-0.4/getting-started/set-up/indy-sdk/index.md b/versioned_docs/version-0.4/getting-started/set-up/indy-sdk/index.md new file mode 100644 index 00000000..49fed153 --- /dev/null +++ b/versioned_docs/version-0.4/getting-started/set-up/indy-sdk/index.md @@ -0,0 +1,69 @@ +import DocCardList from '@theme/DocCardList'; + +# Indy SDK + +[Indy SDK](https://github.com/hyperledger/indy-sdk) provides a distributed ledger based foundation for self-sovereign identity. It can provide the `Wallet` and `StorageService` implementations for the agent, as well as a way to interact with Indy ledgers and an implementation of the legacy (v0.1) [AnonCreds Specification](https://hyperledger.github.io/anoncreds-spec/) + +:::caution +The Indy SDK integration in Aries Framework JavaScript is currently in maintenance mode. We recommend new projects to use [Aries Askar](../aries-askar) from the start, and also to migrate existing projects to Aries Askar. +::: + +:::caution +The AnonCreds implementation from the Indy SDK only supports the [Hyperledger Indy Legacy AnonCreds Method](https://hyperledger.github.io/anoncreds-methods-registry/#hyperledger-indy-legacy-anoncreds-method) (the pre-standardized implementation), and doesn't support the new Ledger [Agnostic AnonCreds Specification (v1.0)](https://hyperledger.github.io/anoncreds-spec/). Use the new AnonCreds Rust implementation, which is also supported by Aries Framework JavaScript, in combination with [Aries Askar](../aries-askar) and Indy VDR to replace the bevhaviour of the Indy SDK, and support the new features these libraries have to offer. +::: + +### Installing the Indy SDK + +When using Aries Framework JavaScript with the Indy SDK, there's a few extra dependencies that need to be installed. We need to install the `@aries-framework/indy-sdk` package, which implements the needed interfaces for the agent. Secondly, we need to install the native Indy SDK library and the bindings for our specific platform. Currently there are bindings for Node.JS and React Native. + +To start off, install the native Indy SDK library. The setup for this depends on the platform you are using. Follow the instructions for your platform below. + + + +After the native Indy SDK library is installed, we can add the Indy SDK libraries. + + + +# Node.JS + +```console +yarn add @aries-framework/indy-sdk@^0.4.0 indy-sdk +``` + +And install the needed types + +```console +yarn add --dev @types/indy-sdk +``` + +# React Native + +```console +yarn add @aries-framework/indy-sdk@^0.4.0 indy-sdk-react-native +``` + +And then install the needed types + +```console +yarn add --dev @types/indy-sdk-react-native@npm:@types/indy-sdk +``` + + + +### Adding the Indy SDK to the Agent + +After installing the dependencies, we can register the Indy SDK Module on the agent. + + + +# Node.JS + +```typescript showLineNumbers set-up-indy-sdk.ts section-1 + +``` + +# React Native + +```typescript showLineNumbers set-up-indy-sdk-rn.ts section-1 + +``` diff --git a/versioned_docs/version-0.4/getting-started/set-up/indy-sdk/linux.md b/versioned_docs/version-0.4/getting-started/set-up/indy-sdk/linux.md new file mode 100644 index 00000000..8cb4b770 --- /dev/null +++ b/versioned_docs/version-0.4/getting-started/set-up/indy-sdk/linux.md @@ -0,0 +1,105 @@ +# Linux + +To install [Indy SDK](https://github.com/hyperledger/indy-sdk) on Linux, a couple of dependencies are required. This guide covers the installation for the more popular Linux distributions. + +### Libsodium + +[Libsodium](https://github.com/jedisct1/libsodium) is used by the Indy SDK for encryption, decryption, hashing and signing. + + + +#### Arch Linux + +``` +pacman -S libsodium +``` + +#### Debian + +``` +apt-get install libsodium-dev +``` + +#### Red Hat + +``` +yum install libsodium libsodium-devel +``` + + + +### Libzmq + +[Libzmq](https://github.com/zeromq/libzmq) is a lightweight messaging queue used by the Indy SDK. + + + +#### Arch Linux + +``` +pacman -S zeromq +``` + +#### Debian + +``` +apt-get install libzmq3-dev +``` + +#### Red Hat + +``` +yum install libsodium zeromq-devel +``` + + + +### Indy SDK + +All the steps mentioned here are distribution independent. As the Indy SDK doesn't provide binaries for many releases, we will build it from source. This does mean that some additional requirements are necessary, like +[Rust](https://www.rust-lang.org). + +Downloading [Rust](https://www.rust-lang.org) is as easy as executing the +following command: + +```console +curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh +``` + +This will install [Rustup](https://rustup.rs) which is the installer for +[Rust](https://rust-lang.org). + +With [Rust](https://rust-lang.org), we can now build the +Indy SDK from source. + +First, clone the repository in a temporary directory: + +```console +git clone https://github.com/hyperledger/indy-sdk +``` + +Secondly, go to the correct directory + +```console +cd indy-sdk/libindy +``` + +Third, build the library + +```console +cargo build --release +``` + +Lastly, move the library to the correct location + +```console +sudo mv target/release/libindy.so /usr/lib/libindy.so +``` + +### Confirm installation + +To see whether the Indy SDK is correctly installed on your system, run the following command and it should not error. + +```console +npx -p @aries-framework/node@^0.3 is-indy-installed +``` diff --git a/versioned_docs/version-0.4/getting-started/set-up/indy-sdk/macos-arm.md b/versioned_docs/version-0.4/getting-started/set-up/indy-sdk/macos-arm.md new file mode 100644 index 00000000..3b150d2c --- /dev/null +++ b/versioned_docs/version-0.4/getting-started/set-up/indy-sdk/macos-arm.md @@ -0,0 +1,59 @@ +# macOS (ARM) + +To install [Indy SDK](https://github.com/hyperledger/indy-sdk) on macOS, a couple of dependencies are required. This guide covers the installation of the Indy SDK for macs with an ARM processor. For installing the Indy SDK on Intel based macs, please refer to the [Indy SDK macOS (Intel)](./macos-intel) guide. + +:::info + +This installation assumes that you have [brew](https://brew.sh) installed. If not, please install it via this command: + +``` +/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" +``` + +::: + +### Libsodium + +[Libsodium](https://github.com/jedisct1/libsodium) is used by the Indy SDK for encryption, decryption, hashing and signing. + +```console +brew install libsodium +``` + +### Libzmq + +[Libzmq](https://github.com/zeromq/libzmq) is a lightweight messaging queue used by the Indy SDK. + +```console +brew install zeromq +``` + +### Indy SDK + +The Indy SDK does not been distributed properly for macOS. We have a pre-built library available that can +be downloaded. If you prefer to build from source, you can follow the instructions in the [Indy SDK repository](https://github.com/hyperledger/indy-sdk#how-to-build-indy-sdk-from-source) + +First, download the pre-built library from [Google Drive](https://drive.google.com/file/d/1JaRqAEAyodjeh120YYZ0t42zfhN3wHiW/view). + +After this, open `Finder`, `control+click` on the library and click on `open`. +This is something that has to be done as the library is not properly signed. + +Lastly the library just has to be moved to the correct location. + +:::caution + +If you downloaded the file in another directory, please change the first part of this command + +::: + +```console +sudo mv ~/Downloads/libindy.dylib /usr/local/lib/ +``` + +### Confirm installation + +To see whether the Indy SDK is correctly installed on your system, run the following command and it should not error. + +```console +npx -p @aries-framework/node@^0.3 is-indy-installed +``` diff --git a/versioned_docs/version-0.4/getting-started/set-up/indy-sdk/macos-intel.md b/versioned_docs/version-0.4/getting-started/set-up/indy-sdk/macos-intel.md new file mode 100644 index 00000000..b0b926ca --- /dev/null +++ b/versioned_docs/version-0.4/getting-started/set-up/indy-sdk/macos-intel.md @@ -0,0 +1,29 @@ +# macOS (Intel) + +To install [Indy SDK](https://github.com/hyperledger/indy-sdk) on macOS a couple of dependencies are required. This guide covers the installation of the Indy SDK for macs with an Intel processor. For installing the Indy SDK on ARM based macs, please refer to the [Indy SDK macOS (ARM)](./macos-arm) guide. + +:::info + +This installation assumes that you have [brew](https://brew.sh) installed. If not, please install it via this command: + +``` +/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" +``` + +::: + +### Indy SDK + +The Indy SDK has not been distributed properly for macOS. We have made a [brew tap](https://docs.brew.sh/Taps) for `libindy` and it will also install all of the required dependencies. + +```console +brew install blu3beri/libindy/libindy +``` + +### Confirm installation + +To see whether the Indy SDK is correctly installed on your system, run the following command and it should not error. + +```console +npx -p @aries-framework/node@^0.3 is-indy-installed +``` diff --git a/versioned_docs/version-0.4/getting-started/set-up/indy-sdk/react-native.md b/versioned_docs/version-0.4/getting-started/set-up/indy-sdk/react-native.md new file mode 100644 index 00000000..0c01a73d --- /dev/null +++ b/versioned_docs/version-0.4/getting-started/set-up/indy-sdk/react-native.md @@ -0,0 +1,13 @@ +# React Native + +The setup of Indy SDK for React Native is rather different than Node.JS. We do not have to install dependencies on the host-platform, but for the build target. For React Native this would be the Indy SDK for Android & iOS. This guide covers both the Android and iOS setup, as in most React Native projects you will need both. + +## Expo + +If you're using [Expo](https://expo.dev), the recommended way to install the Indy SDK is by using the [Indy SDK Expo Plugin](https://github.com/animo/indy-sdk-expo-plugin). This will correclty set-up your project with the Indy SDK using an [Expo Config Plugin](https://docs.expo.dev/guides/config-plugins/) for both iOS and Android. + +Refer to the [Indy SDK Expo Plugin](https://github.com/animo/indy-sdk-expo-plugin) repository for installation instructions. + +## Without Expo + +When not using Expo, you will need to set-up the Indy SDK for both Android and iOS using the `indy-sdk-react-native` package directly. Refer to the [Indy SDK React Native](https://github.com/hyperledger/indy-sdk-react-native) repository for installation instructions. diff --git a/versioned_docs/version-0.4/getting-started/set-up/indy-sdk/windows.md b/versioned_docs/version-0.4/getting-started/set-up/indy-sdk/windows.md new file mode 100644 index 00000000..32174542 --- /dev/null +++ b/versioned_docs/version-0.4/getting-started/set-up/indy-sdk/windows.md @@ -0,0 +1,17 @@ +# Windows + +To install [Indy SDK](https://github.com/hyperledger/indy-sdk) on Windows, you can download the pre-built binary from the [Sovrin repository](https://repo.sovrin.org/windows/libindy/master/1.16.0-1636/libindy_1.16.0.zip). + +Once downloaded, extract the zip into a **permanent location**. + +Next, go to `environment variables` on your system and click on `new` at +`System Variables`. The name MUST be `LD_LIBRARY_PATH` and the value MUST be +the path to the extracted libraries. + +### Confirm installation + +To see whether the Indy SDK is correctly installed on your system, run the following command and it should not error. + +```console +npx -p @aries-framework/node@^0.3 is-indy-installed +``` diff --git a/versioned_docs/version-0.4/getting-started/set-up/indy-vdr.md b/versioned_docs/version-0.4/getting-started/set-up/indy-vdr.md new file mode 100644 index 00000000..0ed40571 --- /dev/null +++ b/versioned_docs/version-0.4/getting-started/set-up/indy-vdr.md @@ -0,0 +1,160 @@ +# Indy VDR + +[Hyperledger Indy VDR](https://github.com/hyperledger/indy-vdr), Verifiable Data Registry, can be used to connect to one or more Indy Node ledger pools given sets of genesis transactions. Methods are provided to construct ledger requests and send them to the validators, collecting the results and ensuring that there is a consensus between the nodes. In the context of Aries Framework JavaScript, we mainly leverage it to register, and resolve, schemas, credential definitions and DIDs. + +:::caution + +Support for Indy VDR in Aries Framework JavaScript is currently experimental. We recommend new projects to use Indy VDR from the start, and also to migrate existing projects to Indy VDR, from the indy-sdk. However, projects may experience some issues. If you encounter any issues, please [open an issue](https://github.com/hyperledger/aries-framework-javascript/issues/new). + +Currently, there are few limitations to using Indy VDR. + +- When running in Node.JS, only Node.JS 18 is supported for now. See [Supported Node.JS versions for Indy VDR](#supported-nodejs-versions-for-indy-vdr) +- Install scripts rely on bash command substitution to get the proper binaries for each system architecture and platform. Therefore, if you are under Windows, you must configure `npm` or `yarn` to use a bash-compliant shell (e.g. `npm config set script-shell "C:\\Program Files\\git\\bin\\bash.exe"`) + +::: + +### Installing Indy VDR + +When using Aries Framework JavaScript with Indy VDR, there are a few extra dependencies that need to be installed. We need to install the `@hyperledger/indy-vdr`, which contains all the functionality to register objects on an Hyperledger Indy VDR. Secondly, we need to add native bindings for the specific platform `@hyperledger/indy-vdr-`. Currently there are bindings for Node.JS, as `@hyperledger/indy-vdr-nodejs`, and React Native as `@hyperlegder/indy-vdr-react-native`. + + + +# Node.JS + +```console +yarn add @aries-framework/indy-vdr@^0.4.0 @hyperledger/indy-vdr-nodejs@^0.1.0 +``` + +# React Native + +```console +yarn add @aries-framework/indy-vdr@^0.4.0 @hyperledger/indy-vdr-react-native@^0.1.0 +``` + + + +### Adding Indy VDR to the agent + +After installing the dependencies, we can register the Indy VDR module on the agent. + + + +# Node.JS + +```typescript showLineNumbers set-up-indy-vdr.ts section-1 + +``` + +# React Native + +```typescript showLineNumbers set-up-indy-vdr-rn.ts section-1 + +``` + + + +### Configuration + +As you can see below, the Indy VDR module takes the native bindings and a list of networks. This list of networks will be used to resolve and register objects on. + +```typescript typescript showLineNumbers set-up-indy-vdr-config.ts section-1 + +``` + +#### indyVdr + +**Type**: `IndyVdr` + +the `indyVdr` key takes a class that implements all the native bindings for Indy VDR. This can be imoprted from the `@hyperledger/indy-vdr-nodejs` package or the `@hyperledger/indy-vdr-react-native` package. + +#### networks + +**Type**: `IndyVdrPoolConfig[]` + +An array of indy networks to connect to. The list can contain the following object and it must [`genesisTransactions`](#indyledgersgenesistransactions). + +##### indyNamespace + +**Type**: `string` + +The Indy namespace aka the name identifying the name of the network connecting to. See also [indy did method identifiers](https://hyperledger.github.io/indy-did-method/#indy-did-method-identifiers) + +##### `isProduction` + +**Type**: `boolean` + +Whether the ledger is a production ledger. This is used for detecting which ledger to use in case of unqualified identifiers as production ledgers have priority. + +##### `genesisTransactions` + +**Type**: `string` + +Stringified JSON object of the transaction. + +##### `connectOnStartup` + +**Type**: `boolean` + +Whether to connect to the ledger on startup. Defaults to `false`. + +##### `transactionAuthorAgreement` + +**Type**: `TransactionAuthorAgreement` + +JSON representation specifying the version and acceptance mechanism. The version is the unique version of the transaction author agreement acceptance mechanism list (AML). The acceptance mechanism refers to the acceptance mechanism label of the item in the AML. For more details you may consult the [indy-node docs on AML](https://github.com/hyperledger/indy-node/blob/master/docs/source/transactions.md#transaction_author_agreement_aml) + +##### `transactionAuthorAgreement.version` + +**Type**: `string` + +The version of the AML acceptance mechanism. This is a string representation of a version number e.g. '1' or '1.4' + +##### `transactionAuthorAgreement.acceptanceMechanism` + +**Type**: `string` + +The acceptance mechanism to choose. This _must_ be _one_ of the available labels of the acceptance mechanisms key-value pairs in the AML e.g. 'EULA'. + +### Supported Node.JS versions for Indy VDR + +Due to an issue in `ref-napi` (which is used in the Node.JS bindings for Indy VDR), performance for Indy VDR in Node.JS is not as expected. A patched version for `ref-napi` has been published that fixes this issue, but this only works in Node.JS 18+. + +To use Indy VDR in Node.JS, make sure you're using Node.JS 18 and patch the `ref-napi` package to point towards `@2060.io/ref-napi` in your `package.json`: + + + +# NPM + +Using [NPM `overrides`](https://docs.npmjs.com/cli/v9/configuring-npm/package-json#overrides) we can point the `ref-napi` package to `@2060.io/ref-napi`. + +```json +{ + "overrides": { + "ref-napi": "npm:@2060.io/ref-napi" + } +} +``` + +# Yarn + +Using [Yarn `resolutions`](https://classic.yarnpkg.com/lang/en/docs/selective-version-resolutions/) we can point the `ref-napi` package to `@2060.io/ref-napi`. + +```json +{ + "resolutions": { + "ref-napi": "npm:@2060.io/ref-napi" + } +} +``` + + + +:::info + +See the following issues for more information on the performance bottleneck + +- https://github.com/hyperledger/aries-askar/issues/76 +- https://github.com/node-ffi-napi/ref-napi/issues/72 +- https://github.com/node-ffi-napi/ref-napi/pull/73 + +::: diff --git a/versioned_docs/version-0.4/index.md b/versioned_docs/version-0.4/index.md new file mode 100644 index 00000000..4b1fb5a6 --- /dev/null +++ b/versioned_docs/version-0.4/index.md @@ -0,0 +1,17 @@ +# Intro + +Welcome, to the Aries JavaScript community! + +There's no way around it. Working with self-sovereign identity can be difficult. Luckily this documentation's main goal is to make it easy for you. Whether you have a lot of experience building with Aries or non-Aries SSI frameworks, or have never heard of terms like Verifiable Credential, [DID](./concepts/did-and-didcomm.md), or [Agent](./concepts/agents.md). This documentation will either help you create a JavaScript based SSI solution yourself, or help you find the right resources in the community to assist you! + +So what is [Hyperledger Aries Framework JavaScript](https://github.com/hyperledger/aries-framework-javascript)? + +> Hyperledger Aries provides a shared, reusable, interoperable tool kit designed for initiatives and solutions focused on creating, transmitting and storing verifiable digital credentials. +> +> — Hyperledger Foundation + +There are [several](https://wiki.hyperledger.org/display/ARIES) Aries frameworks that help you build solutions using verifiable credentials. This one is written in TypeScript and is specifically well suited for Multi-Platform development as it supports Node.js and React Native. We, the community, like to view it as the most accessible framework mostly because it is written in TypeScript, and our maintainers and contributors work to keep developer user experience a top priority. + +These docs are not just for the main framework, but also all that surround it. So you'll find [general explanations about the concepts used](./concepts/index.md), [specific tutorials for common use cases](./tutorials/index.md) and [relevant projects and related repositories](./ecosystem/index.md). Most of all you'll find solid documentation with lots of code examples and an enthousiastic community that wants to build great stuff together. + +Are you ready to get started? diff --git a/versioned_docs/version-0.4/tutorials/agent-config/index.md b/versioned_docs/version-0.4/tutorials/agent-config/index.md new file mode 100644 index 00000000..e7878a65 --- /dev/null +++ b/versioned_docs/version-0.4/tutorials/agent-config/index.md @@ -0,0 +1,221 @@ +# Agent Config + +The Aries agent provided by [Aries Framework +JavaScript](https://github.com/hyperledger/aries-framework-javascript) is very +extensible. These are all the configuration options with a short description: + +## `label`\* + +The label is seen by other users when creating a connection. This should not +be used as a base for authenticity, as it is entirely up to the user to +set this. + +**Type**: `string` + +```typescript title="example" +label: 'my-demo-agent' +``` + +--- + +## `walletConfig` + +Configuration for the setup of the wallet. Including this in the agent +configuration makes it possible that, when initializing the agent, the wallet +will also be initialized. When an application requires the agent without an +initialized wallet for any reason, this can be omitted and later on the wallet +can be initialized separately. + +**Type**: `WalletConfig` + +```typescript title="example" +import { KeyDerivationMethod } from '@aries-framework/core' + +walletConfig: { + id: 'foo', + key: 'testkey000000000000000000000', + keyDerivationMethod: KeyDerivationMethod.Argon2IMod, + storage: { + type: 'postgres_storage', + ... // depends on the storage type + } +} +``` + +### `walletConfig.id`\* + +Identifier string. Using another value here will open a new wallet. + +**Type**: `string` + +### `walletConfig.key`\* + +Key to unlock the wallet with. This value MUST be kept as a secret and should +be seem like a password. + +**Type**: `string` + +### `walletConfig.keyDerivationMethod` + +The method used for key derivation of the +[`walletConfig.key`](#walletconfigkey). + +When using `KeyDerivationMethod.Raw`, it is strongly recommended to get the raw +key via +[`indy_generate_wallet_key`](https://github.com/hyperledger/indy-sdk/blob/1c7096dd95d0fd53881070f66907df4b9e61b874/libindy/src/api/wallet.rs#L560). +If you really must implement your own key generation, it is required to be a +base58-encoded +[ChaCha20-Poly1305](https://en.wikipedia.org/wiki/ChaCha20-Poly1305) key. + +> For the advanced readers +> [here](https://www.password-hashing.net/argon2-specs.pdf) is the +> specification of Argon2. + +**Type**: `enum KeyDerivationMethod` + +**Default**: `KeyDerivationMethod.Argon2IMod` + +**Members**: + +**`KeyDerivationMethod.Argon2IMod`** + +    uses Argon2I modular (most secure option, but slower) + +**`KeyDerivationMethod.Argon2Int`** + +    uses Argon2 integer (less secure, but faster) + +**`KeyDerivationMethod.Raw`** + +    uses no derivation method. +It is recommended to use the +[`indy_generate_wallet_key`](https://github.com/hyperledger/indy-sdk/blob/1c7096dd95d0fd53881070f66907df4b9e61b874/libindy/src/api/wallet.rs#L560) +for key generation. + +### `walletConfig.storage` + +Specify which storage is being used for the wallet. The default is an SQLite +database, but a Postgres database could be used as well. + +**Type**: `object` + +**Default**: An SQLite database + +--- + +## `endpoints` + +A list of endpoints (schema + host + port) used for invitations and where other +agents might reach you. This could be used to host a website that would +redirect, for example with deep linking, to a wallet where the invitation can be +accepted. + +**Type**: `string` + +```typescript title="example" +endpoints: ['https://example.org:3000'] +``` + +--- + +## `logger` + +A logger instance that implements the `Logger` interface. This can be extremely +helpful for debugging. Aries Framework JavaScript exposes a `ConsoleLogger` +that can be used for simple logs. See [Logging](./logging) for more details on creating your own logger instance. + +**Type**: `Logger` + +```typescript title="example" +import { ConsoleLogger, LogLevel } from '@aries-framework/core' + +logger: new ConsoleLogger(LogLevel.info) +``` + +--- + +## `didCommMimeType` + +The mime-type used for sending and receiving messages. `application/jwe` and +`application/json` are used as fallback but are less desirable as they are +much more ambiguous in their specification. + +**Type**: `enum DidCommMimeType` + +**Default**: `DidCommMimeType.V1` + +**Members**: + +**`DidCommMimeType.V0`** + +    "application/ssi-agent-wire" + +**`DidCommMimeType.V1`** + +    "application/didcomm-envelope-enc" + +```typescript title="example" +import { DidCommMimeType } from '@aries-framework/core' + +didCommMimeType: DidCommMimeType.V1 +``` + +--- + +## `useDidSovPrefixWhereAllowed` + +Whether to emit the legacy did:sov prefix `did:sov:BzCbsNYhMrjHiqZDTUASHg;spec` in the `@type` of messages for messages that allow it. A message can allow emitting the legacy prefix by setting the `allowDidSovPrefix` on the message class. This is the case for all core messages that have been defined before the [Migration to `https://didcomm.org` message type](https://github.com/hyperledger/aries-rfcs/blob/main/features/0348-transition-msg-type-to-https/README.md), to allow for the best possible interoperability with other agents. + +**Type**: `boolean` + +**Default**: `false` + +```typescript title="example" +useDidSovPrefixWhereAllowed: true +``` + +--- + +## `useDidKeyInProtocols` + +Whether to use `did:key` in protocols by default as defined in [RFC 0360: did:key Usage](https://github.com/hyperledger/aries-rfcs/blob/main/features/0360-use-did-key/README.md). Adopting this RFC can break interop with agents that haven't adopted this RFC yet. The framework does it best to automatically detect whether the other agent supports `did:key`, however in some cases we can't determine this. In those cases this parameter can be used to force the framework to use `did:key` or not. + +**Type**: `boolean` + +**Default**: `true` + +```typescript title="example" +useDidKeyInProtocols: true +``` + +--- + +## `connectionImageUrl` + +A URL to an image used so that other agents can display this. Like the +[`Label`](#label) this is completely up to the user to define +this. It MUST not be used got any base of authenticity. + +**Type**: `string` + +```typescript title="example" +connectionImageUrl: 'https://picsum.photos/200' +``` + +--- + +## `autoUpdateStorageOnStartup` + +Whether the storage should automatically be updated when a newer version of +[Aries Framework +JavaScript](https://github.com/hyperledger/aries-framework-javascript) is used. + +**Type**: `boolean` + +**Default**: `false` + +```typescript title="example" +autoUpdateStorageOnStartup: true +``` + +--- diff --git a/versioned_docs/version-0.4/tutorials/agent-config/logging.md b/versioned_docs/version-0.4/tutorials/agent-config/logging.md new file mode 100644 index 00000000..f0df31e0 --- /dev/null +++ b/versioned_docs/version-0.4/tutorials/agent-config/logging.md @@ -0,0 +1,87 @@ +# Logging + +## Using the Default ConsoleLogger + +To enable logging inside the framework a logger must be passed to the agent config. A simple `ConsoleLogger` can be imported from the framework. + +```ts +import type { InitConfig } from '@aries-framework/core' +import { ConsoleLogger, LogLevel } from '@aries-framework/core' + +const agentConfig: InitConfig = { + // ... other config properties ... + logger: new ConsoleLogger(LogLevel.info), +} +``` + +## Creating your own Logger + +For more advanced use cases the `Logger` interface can be implemented. See the example below. + +```ts +import { Logger, LogLevel } from '@aries-framework/core' + +class MyCustomLogger implements Logger { + public logLevel: LogLevel + + public constructor(logLevel: LogLevel = LogLevel.off) { + this.logLevel = logLevel + } + + public test(message: string, data?: Record): void { + console.log(message, data) + } + + public trace(message: string, data?: Record): void { + console.log(message, data) + } + + public debug(message: string, data?: Record): void { + console.log(message, data) + } + + public info(message: string, data?: Record): void { + console.log(message, data) + } + + public warn(message: string, data?: Record): void { + console.log(message, data) + } + + public error(message: string, data?: Record): void { + console.log(message, data) + } + + public fatal(message: string, data?: Record): void { + console.log(message, data) + } +} +``` + +## Indy Logs + +To enable logging in the underlying Rust framework, either `setLogger` or `setDefaultLogger` must be called on the indy dependency, as seen [here](https://github.com/hyperledger/indy-sdk/tree/master/wrappers/nodejs#logger). + +:::caution + +The `setLogger` and `setDefaultLogger` methods have only been implemented in the Node.JS wrapper of the indy sdk. This won't work when importing from `@aries-framework/react-native` + +::: + +The easiest way to do this from AFJ is through the `indy` property of `agentDependencies`. + +```ts +import { agentDependencies } from '@aries-framework/node' +agentDependencies.indy.setDefaultLogger('trace') + +// OR + +agentDependencies.indy.setLogger((level, target, message, modulePath, file, line) => { + console.log('libindy said:', level, target, message, modulePath, file, line) +}) +``` + +> WARNING: You can only set the logger once. Call indy_set_default_logger, indy_set_logger, not both. Once it's been set, libindy won't let you change it. + +You can also set the environment variable `RUST_LOG` to log at specified log levels. +See https://crates.io/crates/env_logger for more information. diff --git a/versioned_docs/version-0.4/tutorials/cheqd/index.md b/versioned_docs/version-0.4/tutorials/cheqd/index.md new file mode 100644 index 00000000..2014f223 --- /dev/null +++ b/versioned_docs/version-0.4/tutorials/cheqd/index.md @@ -0,0 +1,137 @@ +# Cheqd Did Module + +In this tutorial we will see how to use the cheqd modules in detail + +:::info + +This section assumes that + +1. You have [set-up your develoment environment](../../getting-started). +2. You have setup the cheqd module [setup cheqd](../../getting-started/set-up/cheqd/index.md) + +::: + +## DID Module + +The cheqd DID module facilitates the Create, Read, Update, and Delete (CRUD) operations for did:cheqd identifiers. To learn more about "did:cheqd," please refer to the [specification](https://github.com/cheqd/identity-docs/blob/main/architecture/adr-list/adr-001-cheqd-did-method.md) + +### Create DID + +The DID can be created in two different ways + +#### Parameters + +1. `method`\*: `cheqd` +2. `secret` +3. `options`\* +4. `didDocument` + +##### Option 1 + +Provide a DID Document payload according to the w3c did core specification in the request body. This is possible when the keys corresponding to the verification methods provided in the DID Document are already created in the wallet + +```typescript showLineNumbers set-up-cheqd.ts section-2 + +``` + +##### Option 2 + +If a DID Document is not passed to the registrar, it requires the secret parameter with a verificationMethod to construct the DID Document. + +```typescript showLineNumbers set-up-cheqd.ts section-3 + +``` + +### Update DID + +To update a DID Document, fetch the body of the DID Document you want to change from the DID Resolver, make the relevant updates and pass it as the parameter + +#### Parameters + +1. `did`\* +2. `didDocument`\*: The updated DID Document +3. `options` +4. `secret` + +```typescript showLineNumbers set-up-cheqd.ts section-4 + +``` + +### Deactivate DID + +A DID can be deactivated, it can still be resolved + +#### Parameters + +1. `did`\* +2. `options` + +```typescript showLineNumbers set-up-cheqd.ts section-5 + +``` + +### Types + +--- + +#### `secret.verificationMethod` + +**Type**: `verificationMethod` + +##### `verificationMethod.id`\* + +**Type**: `string` + +##### `verificationMethod.type`\* + +**Type**: `string` + +**Default**: `Ed25519VerificationKey2020` + +**Members**: + +1. `Ed25519VerificationKey2020` +2. `Ed25519VerificationKey2018` +3. `JsonWebKey2020` + +##### `verificationMethod.privateKey` + +**Type**: `string` + +--- + +#### `options.methodSpecificIdAlgo` + +Specifies what type of method specific identifier is needed for your DID + +**Type**: `string` + +**Default**: `uuid` + +**Members**: + +1. `uuid` +2. `base58btc` + +--- + +#### `options.network`\* + +Specifies the cheqd network name to be published + +**Type**: `string` + +**Default**: `testnet` + +**Members**: + +1. `testnet` +2. `mainnet` + +--- + +#### `options.versionId` + +Specifies the version of the DID Document to be published + +**Type**: `string` diff --git a/versioned_docs/version-0.4/tutorials/create-a-connection.md b/versioned_docs/version-0.4/tutorials/create-a-connection.md new file mode 100644 index 00000000..06ca8209 --- /dev/null +++ b/versioned_docs/version-0.4/tutorials/create-a-connection.md @@ -0,0 +1,145 @@ +# Create a connection + +In this tutorial we will create a connection as _Acme Corp_ with _Bob_. We will +start with setting up both their agents with the minimal configuration required +to follow this tutorial. After the initialization we will then create an +invitation as _Acme Corp_ and send it over to _Bob_. _Bob_ will then accept +this invitation and at that point they have established a connection and they +know how to reach each other for sending a basic message, issuing a credential, +verifying a proof, etc. + +:::info + +This section assumes that + +1. You have [set-up your development environment](../getting-started). +1. You have basic knowledge of the required fields in the [Agent Config](./agent-config) + +::: + +### 1. Setting up the agents + +First for both agents we must setup and initialize an agent to work with. +Depending on your target, [React +Native](../getting-started/installation/react-native) or +[Node.js](../getting-started/installation/react-native), it might vary. + +In this tutorial _Bob_ will be in a [React Native +environment](../getting-started/installation/react-native) and _Acme Corp_ in +a [Node.js environment](../getting-started/installation/nodejs). + +#### Bob + +For bob we need to setup a basic agent with a wallet, mediator and outbound +transport. + +:::bob + +```typescript showLineNumbers create-a-connection.ts section-1 + +``` + +::: + +#### Acme + +For Acme we need to setup a basic agent with a wallet, inbound and outbound +transport. + +:::acme + +```typescript showLineNumbers create-a-connection.ts section-2 + +``` + +::: + +#### 2. Creating an invitation + +Now that we have setup both agents, we can create an invitation from _Acme Corp_. + + + +# New + +This method will create an invitation using the legacy method according to [0434: Out-of-Band Protocol 1.1](https://github.com/hyperledger/aries-rfcs/blob/main/features/0434-outofband/README.md). + +:::acme + +```typescript showLineNumbers create-a-connection.ts section-3 +const outOfBandRecord = await agent.oob.createInvitation() + +const serializedInvitation = outOfBandRecord.outOfBandInvitation.toUrl({ domain: 'https://example.org' }) +``` + +::: + +# Legacy + +This method will create an invitation using the legacy method according to [0160: Connection Protocol](https://github.com/hyperledger/aries-rfcs/blob/main/features/0160-connection-protocol/README.md). + +:::acme + +```typescript showLineNumbers create-a-connection.ts section-4 + +``` + +::: + + + +### 3. Receiving the invitation + +After we have created the invitation we have to transmit it to the other +agent. Common practise, when sending it to a holder, it to embed the url inside +a QR code. This QR code can then be scanned by the holder, in this case _Bob_. +After this, because both have set `autoAcceptConnections` to `true`, the +connection is established. + +:::bob + +```typescript create-a-connection.ts section-5 + +``` + +::: + +### 4. (additional) listen to incoming connection responses + +When you quickly want to use the event or the data of a response to a +connection request, you can start an [TODO: agent event +listener](https://example.org). + +Another use case for this would be to get the `connectionRecord` of the +connection as it is only created when the invitation has been received by the +other agent. The `connectionRecord` is very essential in processes like [TODO: +issuing a credential](https://example.org) or [TODO: verifying a +proof](https://example.org). + +The `connectionRecord` can also be retrieved with +`agent.connections.findAllByOutOfBandId(id)`, but with this method there is no +way of knowing if the invitation has been received. + +:::acme + +```typescript showLineNumbers create-a-connection.ts section-6 + +``` + +::: + +### 5. Full code snippets + +Below are both code snippets for each agent. These can be used as base but +should be edited to fit your use case. The +[`walletConfig.key`](./agent-config#walletconfigkey) must be changed as it can +lead to other people knowing your "password" to your wallet. + +```typescript showLineNumbers create-a-connection.ts + +``` + +### Useful resources + +- [0160: Connection Protocol](https://github.com/hyperledger/aries-rfcs/blob/main/features/0160-connection-protocol/README.md) +- [0434: Out-of-Band Protocol 1.1](https://github.com/hyperledger/aries-rfcs/blob/main/features/0434-outofband/README.md) diff --git a/versioned_docs/version-0.4/tutorials/index.md b/versioned_docs/version-0.4/tutorials/index.md new file mode 100644 index 00000000..596cfd60 --- /dev/null +++ b/versioned_docs/version-0.4/tutorials/index.md @@ -0,0 +1,9 @@ +import DocCardList from '@theme/DocCardList'; + +# Tutorials + +In this section we will explain some features that everyone will use. This +includes setting up your Aries agent, creating a connection between Aries +agents, issuing a credential and verifying a proof. + + diff --git a/versioned_docs/version-0.4/tutorials/indy-sdk-postgres-database-nodejs/index.md b/versioned_docs/version-0.4/tutorials/indy-sdk-postgres-database-nodejs/index.md new file mode 100644 index 00000000..99cf0e9e --- /dev/null +++ b/versioned_docs/version-0.4/tutorials/indy-sdk-postgres-database-nodejs/index.md @@ -0,0 +1,19 @@ +# Using PostgreSQL as Database for Indy SDK in Node.js + +By default the Indy SDK will use an SQLite database for storage. In mobile environments this is sufficient and allows us to keep storage local to the device, but in server environments we oftentimes want a more scalable storage solution. By leveraging the PostgreSQL plugin for Indy SDK we can use PostgreSQL as a storage solution instead of SQLite. + +This document describes the installation process of the Postgres plugin for IndySDK and how you need to configure AFJ to use it. + +## Installation of the Postgres Plugin + +For installation of the Postgres plugin, please refer to the platform specific guides: + +- [macOS](./macos.md) +- [Linux](./linux.md) +- [Windows](./windows.md) + +## Using the Postgres Plugin in AFJ + +```typescript showLineNumbers set-up-indy-sdk-postgres.ts section-1 + +``` diff --git a/versioned_docs/version-0.4/tutorials/indy-sdk-postgres-database-nodejs/linux.md b/versioned_docs/version-0.4/tutorials/indy-sdk-postgres-database-nodejs/linux.md new file mode 100644 index 00000000..ec5fdbef --- /dev/null +++ b/versioned_docs/version-0.4/tutorials/indy-sdk-postgres-database-nodejs/linux.md @@ -0,0 +1,49 @@ +# Postgres Setup for Linux + +## Prerequisites + +- A system package manager (like APT, Pacman, etc.) +- Cargo (We have to build Postgres plugin from source) +- git (to clone a repo, could also be done with downloading the zip from the GitHub page) + +## Step 1: installing the dependencies using apt + +### Debian based (Ubuntu, Mint, Kali, Deepin, etc.) + +```sh +sudo apt install libzmq3-dev libsodium-dev libssl-dev +``` + +## Step 2: Build Postgres plugin + +Building Postgres plugin from the indy-sdk repo with cargo. + +### Step 2.1: Cloning the indy-sdk + +```sh +git clone https://github.com/hyperledger/indy-sdk.git + +cd indy-sdk/experimental/plugins/postgres_storage +``` + +### Step 2.2: Building Postgres plugin + +If this step throws any errors, it might be because you miss some packages. Step 1 of this guide provided the dependencies that are required, but it also assumed that you have some basic development packages installed. If you are missing some packages, you can install them with your package manager. + +```sh +pwd + +# OUTPUT: .../indy-sdk/experimental/plugins/postgres_storage + +cargo build --release +``` + +### Step 2.3: Moving the file + +```sh +pwd + +# OUTPUT: .../indy-sdk/experimental/plugins/postgres_storage + +sudo mv ./target/release/libindystrgpostgres.so /usr/local/lib/libindystrgpostgres.so +``` diff --git a/versioned_docs/version-0.4/tutorials/indy-sdk-postgres-database-nodejs/macos.md b/versioned_docs/version-0.4/tutorials/indy-sdk-postgres-database-nodejs/macos.md new file mode 100644 index 00000000..6d80b01b --- /dev/null +++ b/versioned_docs/version-0.4/tutorials/indy-sdk-postgres-database-nodejs/macos.md @@ -0,0 +1,47 @@ +# Postgres Setup for macOS + +## Prerequisites + +- Homebrew +- Cargo (We have to build Postgres plugin from source) +- git (to clone a repo, could also be done with downloading the zip from the GitHub page) + +## Step 1: installing the dependencies using brew + +```sh +brew install libsodium zeromq +``` + +## Step 2: Build Postgres plugin + +Building Postgres plugin from the indy-sdk repo with cargo. + +### Step 2.1: Cloning the indy-sdk + +```sh +git clone https://github.com/hyperledger/indy-sdk.git + +cd indy-sdk/experimental/plugins/postgres_storage +``` + +### Step 2.2: Building Postgres plugin + +If this step throws any errors, it might be because you miss some packages. Step 1 of this guide provided the dependencies that are required, but it also assumed that you have some basic development packages installed. If you are missing some packages, you can install them with your package manager. + +```sh +pwd + +# OUTPUT: .../indy-sdk/experimental/plugins/postgres_storage + +cargo build --release +``` + +### Step 2.3: Moving the file + +```sh +pwd + +# OUTPUT: .../indy-sdk/experimental/plugins/postgres_storage + +sudo mv ./target/release/libindystrgpostgres.dylib /usr/local/lib/libindystrgpostgres.dylib +``` diff --git a/versioned_docs/version-0.4/tutorials/indy-sdk-postgres-database-nodejs/windows.md b/versioned_docs/version-0.4/tutorials/indy-sdk-postgres-database-nodejs/windows.md new file mode 100644 index 00000000..d7281bdb --- /dev/null +++ b/versioned_docs/version-0.4/tutorials/indy-sdk-postgres-database-nodejs/windows.md @@ -0,0 +1,49 @@ +# Postgres Setup for windows + +## Build Environment Prerequisites + +1. Download and install Visual Studio Community Edition 2022 +1. Install git for windows +1. Download rust for windows [here](https://www.rust-lang.org/en-US/install.html) +1. Make sure you have already setup libindy for windows from [here](../../getting-started/indy-sdk/windows) + +## Step 1: Getting dependencies + +- Download the prebuilt dependencies [here](https://repo.sovrin.org/windows/libindy/deps/) +- Extract them +- Point path to this directory using environment variables: + - `set INDY_PREBUILT_DEPS_DIR=C:\Users\{WINDOWS_USER}\Downloads\indy-sdk-deps` + - `set INDY_CRYPTO_PREBUILT_DEPS_DIR=C:\Users\{WINDOWS_USER}\Downloads\indy-sdk-deps` + - `set MILAGRO_DIR=C:\Users\{WINDOWS_USER}\Downloads\indy-sdk-deps` + - `set LIBZMQ_PREFIX=C:\Users\{WINDOWS_USER}\Downloads\indy-sdk-deps` + - `set SODIUM_LIB_DIR=C:\Users\{WINDOWS_USER}\Downloads\indy-sdk-deps` + - `set OPENSSL_DIR=C:\Users\{WINDOWS_USER}\Downloads\indy-sdk-deps` + - `set PATH=C:\Users\{WINDOWS_USER}\Downloads\indy-sdk-deps\lib` + +## Step 2: Build Postgres plugin + +Building Postgres plugin from the indy-sdk repo with cargo. + +### Step 2.1: Cloning the indy-sdk + +```sh +git clone https://github.com/hyperledger/indy-sdk.git + +cd indy-sdk\experimental\plugins\postgres_storage +``` + +### Step 2.2: Building Postgres plugin + +If this step throws any errors, it might be because of the environment. Step 1 of this guide provided the dependencies that are required. + +```sh +cargo build --release --target x86_64-pc-windows-msvc +``` + +The library **indystrgpostgres.dll** file will be located at `indy-sdk\experimental\plugins\postgres_storage\target\x86_64-pc-windows-msvc\release` + +### Step 2.3: Setting the file to PATH + +- `set LIB_INDY_STRG_POSTGRES=C:\Users\{WINDOWS_USER}\Downloads\indy-sdklexperimental\plugins\postgres_storage\target\x86_64-pc-windows-msvc\release` + +or Alternatively you can copy the **indystrgpostgres.dll** file to `c:\\windows\\system32\\` diff --git a/versioned_docs/version-0.4/tutorials/issue-a-credential.md b/versioned_docs/version-0.4/tutorials/issue-a-credential.md new file mode 100644 index 00000000..197c1a49 --- /dev/null +++ b/versioned_docs/version-0.4/tutorials/issue-a-credential.md @@ -0,0 +1,125 @@ +# Issue a credential + +In this tutorial we will issue a credential from the _Issuer_ to a _Holder_. We will start with setting up both their agents with the minimal configuration required to follow this tutorial. It is assumed that there is a connection between the _Issuer_ and the _Holder_ and the _Issuer_ also has a registered schema and credential definition. After initializing the _Issuer_ will send a credential to the _holder_, and will then accept this credential and automatically store it in their wallet. + +_Using [AnonCreds](https://anoncreds-wg.github.io/anoncreds-spec/) and the [Issue Credential V2 Protocol](https://github.com/hyperledger/aries-rfcs/blob/main/features/0453-issue-credential-v2/README.md) or the [Issue Credential V1 Protocol](https://github.com/hyperledger/aries-rfcs/blob/main/features/0036-issue-credential/README.md)._ + +:::info + +This section assumes that + +1. You have [set-up your develoment environment](../getting-started). +1. You have basic knowledge of the required fields in the [Agent Config](./agent-config) +1. You have completed the [Create a Connection tutorial](./create-a-connection) +1. You have a registered schema and credential definition. This can be done by following the [Registering on a AnonCreds Registry](./registering-schema-and-credential-definition) + +::: + +### 1. Setting up the agents + +First for both agents we must setup and initialize an agent to work with. Depending on your target, [React Native](../getting-started/installation/react-native) or [Node.js](../getting-started/installation/react-native), it might vary. + +In this tutorial the _Holder_ will be in a [Node.js environment](../getting-started/installation/nodejs) and the _Issuer_ also in a [Node.js environment](../getting-started/installation/nodejs). + +#### Issuer + +For the _Issuer_ the setup is commonly not the same as the _Holder_. In the example they both live in a server environment, meaning they do not need a mediator. More commonly, the _Holder_ is in a mobile environment where a mediator is required for receiving DIDComm messages. + +It is also very important for the _Issuer_ to have a public DID, for the binding with a credential definition, amongst other things. For this demo we will use [BCovrin Test](http://test.bcovrin.vonx.io). If you want to follow this tutorial, you have to register a public DID [here](http://test.bcovrin.vonx.io) via the Wallet seed field (this must be the same as the seed inside the config under the key [`publicDidSeed`](./agent-config#publicdidseed)). + +In order to reach the _Issuer_ we have to add a list of [`endpoints`](./agent-config#endpoints) of the agent that exposes the `inboundTransport` to the public. In the example below we add an `inboundTransport` and use port `3002`. For development purposes it is recommended to use a tunneling service for this, like [Ngrok](https://ngrok.com). Ngrok will allow you to reach your locally exposed endpoint from the public. If a tunneling service is used, make sure to use the `HTTPS` variant as mobile environments, by default, do not accept `HTTP` anymore. + +To install [Ngrok](https://ngrok.com) and expose the port to the public the following commands can be used: + + + +# yarn + +```console +yarn global add ngrok + +ngrok http +``` + +# npm + +```console +npm install --global ngrok + +ngrok http +``` + + + +:::issuer + +```typescript showLineNumbers issue-a-credential.ts section-1 + +``` + +::: + +#### Holder + +For the _Holder_ we need to setup a basic agent with a wallet, mediator, outbound transport and a ledger. + +> If you want to follow this tutorial in a mobile environment: +> +> 1. Use the `agentDependencies` from `@aries-framework/react-native` +> 1. It is very important to note that mobile agents do not support HTTP by default. It is recommended to do everything over HTTPS, but for development HTTP can be enabled for [iOS](https://stackoverflow.com/questions/30731785/how-do-i-load-an-http-url-with-app-transport-security-enabled-in-ios-9) and [Android](https://stackoverflow.com/questions/51902629/how-to-allow-all-network-connection-types-http-and-https-in-android-9-pie). + +:::holder + +```typescript showLineNumbers issue-a-credential.ts section-2 + +``` + +::: + +### 3. Listening for incoming credentials + +When we want to accept a credential, we have to listen to incoming credentials and handle accordingly. In this example we do not have any user interaction, but is likely that your application would have a user-interface which would display the credential. When receiving a credential offer you can get the values from `credentialExchangeRecord.credentialAttributes`. + +:::holder + +```typescript showLineNumbers issue-a-credential.ts section-3 + +``` + +::: + +### 4. Issuing a credential + +Now that everything is setup on both sides, the _Issuer_ can now offer a credential to the _Holder_. + +> In this example we do not instantiate a connection and assume that there is one. Please refer to this guide [Create a connection](./create-a-connection) to get a connection and connectionId. + + + +# Indy + +:::issuer + +```typescript showLineNumbers issue-a-credential.ts section-4 + +``` + +::: + +# AnonCreds + +:::issuer + +```typescript showLineNumbers issue-a-credential.ts section-5 + +``` + +::: + + + +### Useful resources + +- [AnonCreds](https://anoncreds-wg.github.io/anoncreds-spec/) +- [Issue Credential V1 Protocol](https://github.com/hyperledger/aries-rfcs/blob/main/features/0036-issue-credential/README.md) +- [Issue Credential V2 Protocol](https://github.com/hyperledger/aries-rfcs/blob/main/features/0453-issue-credential-v2/README.md) diff --git a/versioned_docs/version-0.4/tutorials/mediation.md b/versioned_docs/version-0.4/tutorials/mediation.md new file mode 100644 index 00000000..812445d6 --- /dev/null +++ b/versioned_docs/version-0.4/tutorials/mediation.md @@ -0,0 +1,97 @@ +# Mediation + +> This section assumes that you have: +> +> 1. Set up a [valid environment](../getting-started/installation) for development +> 2. Basic knowledge of the required fields in the [agent +> config](./agent-config) +> +> The agent setup varies depending on your target environment, React Native or Node.js. +> This tutorial assumes a Node.js environment for all agents (Alice, Bob, Meditator). + +This tutorial shows how to set up a mediator, how to configure an agent to use a mediator, and how agents exchange messages with a mediator in place. +Concepts are explained in isolation: + +- [First](./mediation.md#1-mediator-setup), it is shown how to set up a mediator. +- [Second](./mediation.md#2-recipient-alice-setup), it is demonstrated how to use a mediator. +- [Third](./mediation.md#3-message-exchange), the message exchange between agents with a mediator in place is explained. + +### What is a mediator, and Why should I use one? + +A mediator is just a special type of agent. + +:::info +"When we describe agent-to-agent communication, it is convenient to think of an interaction only in terms of Alice and Bob and their agents. We say things like: "Alice's agent sends a message to Bob's agent" -- or perhaps "Alice's edge agent sends a message to Bob's cloud agent, which forwards it to Bob's edge agent". + +Such statements adopt a useful level of abstraction--one that's highly recommended for most discussions. However, they make a number of simplifications. By modeling the roles of mediators and relays in routing, we can support routes that use multiple transports, routes that are not fully known (or knowable) to the sender, routes that pass through mix networks, and other advanced and powerful concepts."[Aries RFC 0046: Mediators and Relays](https://github.com/hyperledger/aries-rfcs/blob/main/concepts/0046-mediators-and-relays/README.md#aries-rfc-0046-mediators-and-relays) + +::: + +A practical example where the use of mediators is beneficial can be found in a mobile environment. A mobile agent, aka. your mobile wallet, receives messages from other agents. Technically, sending HTTP messages to a mobile agent is impossible because the agent does not have a public IP. As you have probably seen in previous examples, a workaround for this scenario is to use ngrok. Another option is to use a mediator. When an agent is configured to use a mediator, messages to that agent are routed through the mediator and from there to its destination. Thus, a mobile agent can use a "public" mediator to receive messages on its behalf and poll them from time to time. + +This is just one example of how a mediator can be used. Further resources about mediators can be found [here](./mediation.md#useful-resources). + +:::tip + +With mediators, WebSockets come in handy. In a production environment, it is recommendable to register a `WsInboundTransport()` for Alice and a `WsOutboundTransport()` for the mediator. These WebSocket transports allow the mediator to push messages to Alice instead of having Alice pull messages from the mediator repeatedly. +::: + +### 1. Mediator setup + +The first part shows how to set up a mediator agent. Generally, there are two ways to do that: deploying it from scratch or using a third-party mediator. This section focuses on the former approach, setting up the mediator from scratch. + +The mediator is set up on port 3001 and creates an Out-of-Band invitation that allows multiple other agents to connect to the mediator. Configuring an agent as a mediator demands utilizing the `MediatorModule`. In this example, the `autoAcceptMediationRequests` flag is set to true to accept mediation requests automatically. + +```typescript showLineNumbers mediator-setup.ts section-1 + +``` + +### 2. Recipient (Alice) setup + +The second part shows how to use a mediator. Becoming a recipient of a mediator requires using the `MediationRecipientModule`. The setup is the same whether you use your own or a third-party mediator. + +The easiest way to set everything up is by configuring the `MediationRecipientModule` to connect to the mediator on agent startup. This can be done by constructing the module with the `mediatorInvitationUrl`. You can get the mediatorInvitationUrl either from [part one](./mediation.md#1-mediator-setup) by running a mediator yourself or from a public mediator such as the Animo-mediator. The following snippet uses the latter approach. + +The `ConnectionsModule` used in this snippet serves the sole purpose of automatically accepting connections and thus simplifying setup. + +```typescript showLineNumbers mediation-recipient.ts section-1 + +``` + +:::info +In case you are using a third-party mediator and cannot create an invitationUrl, it is common practice for mediators to provide an endpoint from which the invitationUrl can be fetched. +::: + +### 3. Message exchange + +This section explains the message exchange between agents when a mediator is in place. The process is illustrated using the diagram below. Parts [one](./mediation.md#1-mediator-setup) and [two](./mediation.md#2-recipient-alice-setup) of this tutorial showed how to set up and use a mediator. If the `mediatorInvitationUrl` is specified when constructing the `MediationRecipientModule` (as in [Part two](./mediation.md#2-recipient-alice-setup)), the mediation request and grant _(1-2)_ between Alice and the mediator will be performed automatically when Alice's agent is started. + +If Alice establishes a connection with another fictional agent, say, Bob's agent, who is not using any mediators _(3-6)_. (Connection establishment is no different when a mediator is involved). Then, messages from Alice to Bob _(7)_ are routed directly to Bob, while messages from Bob to Alice _(8-9)_ are routed through the intermediary. + +```mermaid +sequenceDiagram + autonumber + participant Alice + participant Mediator + participant Bob + Note over Mediator: Start + Note over Alice: Start + Alice->>Mediator: Request Mediation + Mediator->>Alice: Grant Mediation + Note over Bob: Start + Alice->>Alice: CreateInvitation + Alice --> Bob: (Send Invitation to Bob) + Bob->>Bob: RecieveInvitation + Alice->>Bob: WaitForConnection + Alice->>Bob: SendMessage Alice->Bob + Bob->>Mediator: SendMessage Bob->Alice (Mediator) + Mediator->>Alice: ForwardMessage Bob->Alice (Mediator) +``` + +### Useful resources + +For more information about mediator refer to: + +- [Aries Mediator Coordination Protocol](https://github.com/hyperledger/aries-rfcs/tree/main/features/0211-route-coordination) +- [Hyperledger Aries Mediator Agent](https://aries-mediator.animo.id/#/) +- [Aries RFC 0046: Mediators and Relays](https://github.com/hyperledger/aries-rfcs/blob/main/concepts/0046-mediators-and-relays/README.md#aries-rfc-0046-mediators-and-relays) diff --git a/versioned_docs/version-0.4/tutorials/registering-schema-and-credential-definition.md b/versioned_docs/version-0.4/tutorials/registering-schema-and-credential-definition.md new file mode 100644 index 00000000..60730ecd --- /dev/null +++ b/versioned_docs/version-0.4/tutorials/registering-schema-and-credential-definition.md @@ -0,0 +1,84 @@ +# Registering a schema and credential definition on an AnonCreds Registry + +In this tutorial we will register a schema and credential definition on an AnonCredsRegistry e.g. Hyperledger Indy ledger [indy-vdr](https://github.com/hyperledger/indy-vdr), [cheqd](https://github.com/hyperledger/aries-framework-javascript/packages/cheqd). + +:::info + +This section assumes that + +1. You have [set-up your development environment](../getting-started). +1. You have basic knowledge of the required fields in the [Agent Config](./agent-config) + +::: + +### 1. Setting up the agent + +First, an agent must be setup with a wallet and an indy-vdr or cheqd module. For these code examples, we will use a Node.js environment. + +:::issuer + +```typescript showLineNumbers register-schema-and-cred-def.ts section-1 + +``` + +::: + +### 2. Importing a DID (optional) + +:::info + +There are many ledgers which can be used to register DIDs on for development. + +#### Indy VDR + +We recommend [bcovrin test net](http://test.bcovrin.vonx.io/). This network allows very easily to register a DID from a seed which can then be used as the `privateKey` in the snippet below. The seed is used as the private key for legacy compatibility with the Hyperledger Indy-SDK. The [genesis transactions](http://test.bcovrin.vonx.io/genesis) can also be retrieved for easy integration. + +#### Cheqd + +Follow the [cheqd setup](../getting-started//set-up/cheqd/index.md) and [cheqd DID module](./cheqd/index.md) to setup the network and create a DID. Cheqd supports a mainnet for production and a testnet for development purposes. + +::: + +In order to register a schema and credential definition, a DID must be added to the agent first. This can be done by calling `agent.dids.create()`, but this does require an endorser DID to be present as the `submitterDid`. For this tutorial a DID will already be registered on the ledger, but it will be imported, with the associated private key, to be used later when registering the schema and credential definition. + +This section can be omitted if your agent already has a DID in its wallet. + +:::issuer + +```typescript showLineNumbers register-schema-and-cred-def.ts section-2 + +``` + +::: + +### 3. Registering a schema + +When you have a registered DID on a network and in your wallet, you can register a schema. Registering a schema requires four fields: `issuerId`, `name`, `version` and `attrNames`. It is important to note that the `issuerId` must be the same as a DID in your wallet. + +:::issuer + +```typescript showLineNumbers register-schema-and-cred-def.ts section-3 + +``` + +::: + +### 3. Registering a credential definition + +After registering a schema, a credential definition can be registered based on the schema. The credential definition, amongst more things, binds the schema to a specific issuer. Schemas can be reused between issuers, but a credential definition is specific to an issuer. In a credential definition revocation can also be specified. This section will not go in-depth about revocation. + +:::issuer + +```typescript showLineNumbers register-schema-and-cred-def.ts section-4 + +``` + +::: + +### Using it + +After everything is registered on a AnonCredsRegistry, we can use it to issue credentials. The next tutorial is all about issuing an AnonCreds credential with this setup. + +### Useful Resources + +- [Cheqd AnonCreds Specification](https://docs.cheqd.io/identity/guides/anoncreds) diff --git a/versioned_docs/version-0.4/updating/index.md b/versioned_docs/version-0.4/updating/index.md new file mode 100644 index 00000000..985e1c28 --- /dev/null +++ b/versioned_docs/version-0.4/updating/index.md @@ -0,0 +1,45 @@ +import DocCardList from '@theme/DocCardList'; + +# Updating AFJ + +This section will cover everything you need to know about updating Aries Framework JavaScript to a newer version. + + + +## Versioning + +Aries Framework JavaScript follows [semantic versioning](https://semver.org/). This means that major version changes (**1**.0.0) are considered breaking changes. When features are added this is a minor version change (0.**1**.0). For bug fixes the patch version change is used (0.0.**1**). + +While AFJ is still in pre-1.0.0 version, the version change types are shifted to the right. This means a major version change is now a minor change (0.**1**.0) and a minor change is now a patch change (0.0.**1**). This is done to keep the version below 1.0.0, indicating the framework is still in early development and users can expect more breaking changes that when the version has already reached 1.0.0. + +This means if the second number in the version (0.**1**.0) changes, you need to be careful with updating and always consult this page for update instructions. If only the third number changes (0.0.**1**), you can update without any issues. + +## Types of breaking changes + +Updates to AFJ bring new features and improvements to the framework. To better adapt the framework to new features we sometimes make breaking changes that will improve how AFJ works. There's two parts to updates with breaking changes: + +1. Breaking code changes +2. Breaking storage changes + +### Breaking Code Changes + +Breaking changes to code means changes to how you interact with AFJ. This includes methods being renamed, moved to another module or extended to better integrate with new features. We'll try to cover all breaking changes in migration guides, so you know exactly what is needed to update to a new version and keep the same functionality. + +:::info + +If you encounter any breaking changes that aren't mentioned in the migration docs, please open an issue in the [Aries JavaScript Docs](https://github.com/hyperledger/aries-javascript-docs/issues) repository, or directly create a PR describing the change. + +::: + +### Breaking Storage Changes + +Breaking changes to storage are a bit more complex to deal with. While breaking changes to code only require you to update your code once, breaking changes to storage needs to be updated for every agent instance. Luckily, we've made the migration as easy as possible for you using the [Update Assistant](./update-assistant.md). The Update Assistant will update all storage objects to the storage model that is expected by the newest version. If a version made changes to the storage, this will be explicitly mentioned in the migration guide. See the [Update Assistant](/guides/updating/update-assistant.md) documentation for detailed instructions on how to use the update assistant. + +## Migration Guides + +Currently the following migration guides are available: + +- [Migrating from AFJ 0.1.0 to 0.2.x](./versions/0.1-to-0.2.md) +- [Migrating from AFJ 0.2.x to 0.3.x](./versions/0.2-to-0.3.md) +- [Migrating from AFJ 0.3.x to 0.4.x](./versions/0.3-to-0.4.md) +- [Migrating from an Indy SDK Wallet to Aries Askar](./update-indy-sdk-to-askar.md) diff --git a/versioned_docs/version-0.4/updating/update-assistant.md b/versioned_docs/version-0.4/updating/update-assistant.md new file mode 100644 index 00000000..33fb3ab6 --- /dev/null +++ b/versioned_docs/version-0.4/updating/update-assistant.md @@ -0,0 +1,138 @@ +# Update Assistant + +The Update Assistant helps you update the storage objects from AFJ to newer versions. This documents describes the different ways you can leverage the Update Assistant from fully managed to more manual approaches. + +- [Update Strategies](#update-strategies) + - [Manually instantiating the update assistant on agent startup](#manually-instantiating-the-update-assistant-on-agent-startup) + - [Storing the agent storage version outside of the agent storage](#storing-the-agent-storage-version-outside-of-the-agent-storage) + - [Automatically update on agent startup](#automatically-update-on-agent-startup) +- [Backups](#backups) + +## Update Strategies + +There are three options on how to leverage the update assistant on agent startup: + +1. Manually instantiating the update assistant on agent startup +2. Storing the agent storage version outside of the agent storage +3. Automatically update on agent startup + +### Manually instantiating the update assistant on agent startup + +When the version of the storage is stored inside the agent storage, it means we need to check if the agent needs to be updated on every agent startup. We'll initialize the update assistant and check whether the storage is up to date. The advantage of this approach is that you don't have to store anything yourself, and have full control over the workflow. + +```ts +import { UpdateAssistant, Agent } from '@aries-framework/core' + +// or @aries-framework/node +import { agentDependencies } from '@aries-framework/react-native' + +// First create the agent +const agent = new Agent({ + config, + dependencies: agentDependencies, +}) + +// Then initialize the update assistant with the update config +const updateAssistant = new UpdateAssistant(agent, { + v0_1ToV0_2: { + mediationRoleUpdateStrategy: 'allMediator', + }, +}) + +// Initialize the update assistant so we can read the current storage version +// from the wallet. If you manually initialize the wallet you should do this _before_ +// calling initialize on the update assistant +// await agent.wallet.initialize(walletConfig) +await updateAssistant.initialize() + +// Check if the agent is up to date, if not call update +if (!(await updateAssistant.isUpToDate())) { + await updateAssistant.update() +} + +// Once finished initialize the agent. You should do this on every launch of the agent +await agent.initialize() +``` + +### Storing the agent storage version outside of the agent storage + +When the version of the storage is stored outside of the agent storage, you don't have to initialize the `UpdateAssistant` on every agent agent startup. You can just check if the storage version is up to date and instantiate the `UpdateAssistant` if not. The advantage of this approach is that you don't have to instantiate the `UpdateAssistant` on every agent startup, but this does mean that you have to store the storage version yourself. + +When a wallet has been exported and later imported you don't always have the latest version available. If this is the case you can always rely on Method 1 or 2 for updating the wallet, and storing the version yourself afterwards. You can also get the current version by calling `await updateAssistant.getCurrentAgentStorageVersion()`. Do note the `UpdateAssistant` needs to be initialized before calling this method. + +```ts +import { UpdateAssistant, Agent } from '@aries-framework/core' + +// or @aries-framework/node +import { agentDependencies } from '@aries-framework/react-native' + +// The storage version will normally be stored in e.g. persistent storage on a mobile device +let currentStorageVersion: VersionString = '0.1' + +// First create the agent +const agent = new Agent({ + config, + dependencies: agentDependencies, +}) + +// We only initialize the update assistant if our stored version is not equal +// to the frameworkStorageVersion of the UpdateAssistant. The advantage of this +// is that we don't have to initialize the UpdateAssistant to retrieve the current +// storage version. +if (currentStorageVersion !== UpdateAssistant.frameworkStorageVersion) { + const updateAssistant = new UpdateAssistant(agent, { + v0_1ToV0_2: { + mediationRoleUpdateStrategy: 'recipientIfEndpoint', + }, + }) + + // Same as with the previous strategy, if you normally call agent.wallet.initialize() manually + // you need to call this before calling updateAssistant.initialize() + await updateAssistant.initialize() + + await updateAssistant.update() + + // Store the version so we can leverage it during the next agent startup and don't have + // to initialize the update assistant again until a new version is released + currentStorageVersion = UpdateAssistant.frameworkStorageVersion +} + +// Once finished initialize the agent. You should do this on every launch of the agent +await agent.initialize() +``` + +### Automatically update on agent startup + +This is by far the easiest way to update the agent, but has the least amount of flexibility and is not configurable. This means you will have to use the default update options to update the agent storage. You can find the default update config in the respective version migration guides (e.g. in [0.1-to-0.2](/guides/updating/versions/0.1-to-0.2.md)). + +```ts +import { UpdateAssistant, Agent } from '@aries-framework/core' + +// or @aries-framework/node +import { agentDependencies } from '@aries-framework/react-native' + +// First create the agent, setting the autoUpdateStorageOnStartup option to true +const agent = new Agent({ + config: { + ...config, + autoUpdateStorageOnStartup: true, + }, + dependencies: agentDependencies, +}) + +// Then we call initialize, which under the hood will call the update assistant if the storage is not update to date. +await agent.initialize() +``` + +## Backups + +Before starting the update, the update assistant will automatically create a backup of the wallet. If the migration succeeds the backup won't be used. If the backup fails, another backup will be made of the migrated wallet, after which the backup will be restored. + +The backups can be found at the following locations. The `backupIdentifier` is generated at the start of the update process and generated based on the current timestamp. + +- Backup path: `${agent.config.fileSystem.basePath}/afj/migration/backup/${backupIdentifier}` +- Migration backup: `${agent.config.fileSystem.basePath}/afj/migration/backup/${backupIdentifier}-error` + +> In the future the backup assistant will make a number of improvements to the recovery process. Namely: +> +> - Do not throw an error if the update fails, but rather return an object that contains the status, and include the backup paths and backup identifiers. diff --git a/versioned_docs/version-0.4/updating/update-indy-sdk-to-askar.md b/versioned_docs/version-0.4/updating/update-indy-sdk-to-askar.md new file mode 100644 index 00000000..c1c2a65a --- /dev/null +++ b/versioned_docs/version-0.4/updating/update-indy-sdk-to-askar.md @@ -0,0 +1,161 @@ +# Migrating from an Indy SDK Wallet to Aries Askar + +This documentation explains the process of migrating your Indy SDK wallet to [Aries Askar](https://github.com/hyperledger/aries-askar). + +:::danger + +While the migration script technically works on node.js, it is strongly advised not to use it, yet. The migration of issuer records (such as Schemas and Credential Definitions) is not implemented yet. When a credential definition is detected it will revert the migration process and no harm is done. + +::: + +:::caution + +Postgres is not supported. If you are using postgres with Indy SDK and need to update to Aries Askar, please open an issue on [GitHub](https://github.com/hyperledger/aries-framework-javascript). + +::: + +:::caution + +The migration script is supported to run on 0.3.x before migrating from 0.3.x to 0.4.x. Please refer to [Migrating from AFJ 0.3.x to 0.4.x](./versions/0.3-to-0.4.md) to get to 0.4.x afterwards. + +It is important to note that this script must be ran before you update from 0.3.x to 0.4.x. + +::: + +## What does the migration do internally? + +The migration script does the following to make sure everything is migrated properly, and if anything goes wrong, it will revert back to a working state. + +### Create a backup + +Because undefined behavior might occur, we create a backup in the new `tmp` directory from Aries Framework JavaScript. if some error occurs, it will be reverted back to the backed-up state and if no error occurs, it will delete the backup from the temporary directory. + +### Migrate the database to an Aries Askar structure + +The Indy-sdk and Aries Askar have different database structures. So first of all we need to change some table names, decrypt all the items with the old Indy keys, encrypt the items with the new Aries Askar keys and store them inside the new structure. + +### Try to open the wallet in the new Aries Askar structure + +When the wallet is correctly transformed, the wallet will be attempted to be opened. + +### Update the keys + +Aries Askar has a specific way to store keys and every key, defined by the category of `Indy::Key` will be migrated. + +### Update the DIDs + +:::caution + +This update script does not transform did records. This is fine for something like `did:peer`, but will cause issues with `indy` and `sov` DIDs. For more information, please check out the [Migrating from AFJ 0.3.x to 0.4.x](./versions/0.3-to-0.4.md#removal-of-publicdidseed-and-publicdid) + +::: + +### Update the credential definitions + +:::danger + +Updating of credential definitions is not yet supported. This is why it is strongly advised not to run this script in a node.js environment. + +::: + +### Update the link secret(s) (master secret) + +The link secrets, identified by the category `Indy::MasterSecret`, are updated next. They are stored inside a new `AnonCredsLinkSecretRecord`. + +:::caution + +Since we have to set a default link secret, some additional logic is added to detect this. You can either supply a `defaultLinkSercetId` as a constructor parameter or it will be based on your `walletId`. + +If there is no Indy record with the `defaultLinkSecretId` or the `walletId`, an error will be thrown and the migration will be restored. + +::: + +### Update the credentials + +The credentials, identified by the category `Indy::Credential` are updated last. They are stored in the new `AnonCredsCredentialRecord` as a one-to-one copy. This means that they now support more tags and will make querying a lot easier. + +### All the other records + +All the other records will be transferred without any updates as they are not Indy specific. + +## How to update + +Updating does not require a lot of code, but must be done with caution. + +It is very important to note that the migration script only has to be run once. If it runs for a second time, it will error saying that the database is already migrated. Also, when the migration is finished, it is common practice to store this state in your persistent app storage. This script does not provide a way to detect if an update has happened, so storing this value will prevent the script from running every time. For more information regarding this topic, please check out [Update Assistant](./update-assistant.md#storing-the-agent-storage-version-outside-of-the-agent-storage). + +### add the required dependencies: + +```sh +yarn add @hyperledger/aries-askar-react-native @aries-framework/indy-sdk-to-askar-migration react-native-fs +``` + +Below is the minimal code required for the migration to work. It is recommended to turn the logger on as it gives a lot of information regarding the migration. + +:::caution + +The agent is not allowed to be initialized to run this script. This makes sure nothing else happens during the migration. + +::: + +```typescript +import { agentDependencies } from '@aries-framework/react-native' +import { AskarModule } from '@aries-framework/askar' +import { IndySdkToAskarMigrationUpdater } from '@aries-framework/indy-sdk-to-askar-migration' +import { ariesAskar } from '@hyperledger/aries-askar-react-native' + +const oldAgent = new Agent({ + config: { + /* ... */ + }, + modules: { + ariesAskar: new AskarModule({ + ariesAskar, + }), + }, + dependencies: agentDependencies, +}) + +const dbPath = '' // see section below + +const updater = await IndySdkToAskarMigrationUpdater.initialize({ dbPath, agent }) +await updater.update() +``` + +### Getting the database path + +#### Android + +On android, the database is commonly located under the `ExternalDirectoryPath`. + +If you did not follow the default indy-sdk for React Native setup, your path might differ. Check out [step 5 of the Android setup for Indy SDK React Native](https://github.com/hyperledger/indy-sdk-react-native#5-load-indy-library) for the default behavior. + +```typescript +import fs from 'react-native-fs' + +const base = fs.ExternalDirectoryPath +const indyClient = '.indy_client' +const wallet = 'wallet' +const walletId = agent.config.walletConfig.id +const file = 'sqlite.db' + +const dbPath = `${base}/${indyClient}/${wallet}/${walletId}/${file}` +``` + +#### iOS + +On iOS, the database is commonly located under the `DocumentDirectoryPath`. + +For iOS this can only change if your phone does not have the `HOME` environment variable set. This is not usual behavior, and if `HOME` is not set, the `base` in the code section below will be `/home/indy/Documents`. + +```typescript +import fs from 'react-native-fs' + +const base = fs.DocumentDirectoryPath +const indyClient = '.indy_client' +const wallet = 'wallet' +const walletId = agent.config.walletConfig.id +const file = 'sqlite.db' + +const dbPath = `${base}/${indyClient}/${wallet}/${walletId}/${file}` +``` diff --git a/versioned_docs/version-0.4/updating/versions/0.1-to-0.2.md b/versioned_docs/version-0.4/updating/versions/0.1-to-0.2.md new file mode 100644 index 00000000..6e2f7fad --- /dev/null +++ b/versioned_docs/version-0.4/updating/versions/0.1-to-0.2.md @@ -0,0 +1,557 @@ +# Migrating from AFJ 0.1.0 to 0.2.x + +This document describes everything you need to know for updating AFJ 0.1.0 to 0.2.x. If you're not aware of how updating in AFJ works make sure to first read the guide on [Updating AFJ](/guides/updating/index.md). + +First of all, update you dependencies to the 0.2.x versions. This will also update the needed peer depedencnies. **Extension packages are not updated with this command**. You need to update these manually, and make sure they're up to date with the latest version of AFJ. + + + +#### React Native + +```sh +yarn add @aries-framework/react-native@^0.2.0 @aries-framework/core@^0.2.0 indy-sdk-react-native@^0.2.0 + +# or NPM +npn install @aries-framework/react-native@^0.2.0 @aries-framework/core@^0.2.0 indy-sdk-react-native@^0.2.0 +``` + +#### Node + +```sh +yarn add @aries-framework/node@^0.2.0 @aries-framework/core@^0.2.0 + +# or NPM +npm install @aries-framework/node@^0.2.0 @aries-framework/core@^0.2.0 +``` + + + +## Breaking Code Changes + +This section will list all breaking changes made to the public API of AFJ between version 0.1.0 and 0.2.0. + +:::info + +If you have custom modules take into account there could be a lot more breaking changes that aren't documented here. We try to make sure that the biggest breaking changes to the internal API are also documented here (e.g. see [Updating Custom Messages to the New Message Type Objects](#updating-custom-messages-to-the-new-message-type-objects)), but it is possible some breaking changes are not documented here (feel free to open PRs). + +::: + +### Credentials Module + +#### Module API Updates + +With the addition of the issue credential v2 protocol and the preparation for multiple attachment formats (to be added in a later release), we've made some big changes to the credentials module API. Most changes are related to structure, so updating your code to the new API should be straightforward. + +Basically for all methods in the credential module you should take the following steps to update your code: + +1. Move all function parameters into a single object. All module methods now take a single object that contain all properties. +2. For methods that initiate a protocol (starting from offer, proposal), you should pass `protocolVersion: 'v1'` to indicate we should use the v1 protocol. (v2 is also supported, but this focuses on the breaking changes, not the new features). +3. All indy specific attributes (e.g. credentialDefinitionId) should be passed in the `credentialFormats.indy` object. +4. The preview should now be passed as only the preview attributes (the the full preview) and provided in the `credentialFormats.indy` object. + + + +##### 0.1.0 + +```ts +await agent.credentials.offerCredential('connectionId', { + autoAcceptCredential: AutoAcceptCredential.Always, + comment: 'hello', + + credentialDefinitionId: 'credentialDefinitionId', + preview: new CredentialPreview({ + attributes: [new CredentialPreviewAttribute({ name: 'key', value: 'value' })], + }), +}) +``` + +##### 0.2.x + +```ts +await agent.credentials.offerCredential({ + connectionId: 'connectionId', + protocolVersion: 'v1', + + autoAcceptCredential: AutoAcceptCredential.Always, + comment: 'hello', + + credentialFormats: { + indy: { + credentialDefinitionId: 'credentialDefinitionId', + attributes: [{ name: 'key', value: 'value' }], + }, + }, +}) +``` + + + +#### Data from Received Messages only Stored in Record after Accepting + +Previously when we received a message from another connection we would store the relevant data from the exchange in the credential record. The values we would store were the `credentialDefinitionId` and `schemaId` in the credential metadata, and the `credentialAttributes` field. + +Starting with AFJ 0.2.0 the values are not stored in the credential record until after the message content has been accepted (in the case of an offer this means after sending the request message). This is to avoid ambiguity of the values in the credential record. If I have sent a proposal and then receive an offer, should the credential record contain the values from the proposal or the values from the offer? The first one reflects our view on what the data should be, the second one reflects the latest data. + +We decided to make the record properties always hold our view of what the data should be, and only update it after accepting the contents of a received message (either using auto accept, or by calling the `acceptXXX` methods on the credential module). + +This is an important change and requires some updates to how you extract the relevant data from the offer (or other messages such the proposal). We've added a new `getFormatData` method on the credentials module that allows you to retrieve the attributes and format data for all messages in an exchange. One of the advantages of this approach is that we don't have to store all relevant data in the credential record anymore, which helps when adding new formats that don't match with the attributes used for indy credentials. In addition, the return value for this method is the same whether v1 or v2 of the protocol is used. This means your code should only care about the credential format (indy in this case) and doesn't have to worry about the protocol version. + + + +##### 0.1.0 + +```ts +agent.events.on( + CredentialEventTypes.CredentialStateChanged, + ({ payload: { credentialRecord } }) => { + const indyCredentialMetadata = credentialRecord.metadata.get(CredentialMetadataKeys.IndyCredential) + + // Get credential definition id, schema id and attributes from offer + const credentialDefinitionId = indyCredentialMetadata?.credentialDefinitionId + const schemaId = indyCredentialMetadata?.schemaId + const attributes = credentialRecord.credentialAttributes + } +) +``` + +##### 0.2.x + +```ts +agent.events.on( + CredentialEventTypes.CredentialStateChanged, + async ({ payload: { credentialRecord } }) => { + const formatData = await agent.credentials.getFormatData(credentialRecord.id) + + // Get credential definition id, schema id and attributes from offer + const credentialDefinitionId = formatData.offer?.indy?.cred_def_id + const schemaId = formatData.offer?.indy?.schema_id + const attributes = formatData.offerAttributes + } +) +``` + +The return value of the `getFormatData` method is fully typed an directly returns the format data as encoded in the attachment. It also returns the `proposalAttributes` and `offerAttributes` values which contain the attributes for the indy credential. This is not part of the attachment data itself, but can be seen as the format data for the credential. + +```ts +{ + proposalAttributes: [{ name: 'key', value: 'value' mimeType: 'text/plain' }], + proposal: { + indy: { } // indy proposal as described in RFC 0592 + }, + offerAttributes: [{ name: 'key', value: 'value' mimeType: 'text/plain' }], + offer: { + indy: { } // indy offer as described in RFC 0592 + }, + request: { + indy: { } // indy request as described in RFC 0592 + } + credential: { + indy: { } // indy credential as described in RFC 0592 + } +} +``` + + + +#### Messages Extracted from Credential Record + +The DIDComm messages that were previously stored on the credential record, have been extracted to separate DIDComm message records. This makes it easier to work with multiple versions of the protocol internally, and keeps the credential exchange record agnostic of the protocol version. Instead of accessing the messages through the `proposalMessage`, `offerMessage`, `requestMessage` and `credentialMessage` parameters, we now expose dedicated methods on the credentials module to retrieve the message. + +With the addition of the v2 messages, all v1 messages have been prefixed with `V1` while v2 messages have been prefixed with `V2` (`V1ProposeCredentialMessage` and `V2ProposeCredentialMessage`). If you were using these messages classes throughout your codebase, update them to use the `V1` prefix. + + + +##### 0.1.0 + +```ts +const credentialRecord = await agent.credentials.getById('credentialRecordId') + +const proposalMessage = credentialRecord.proposalMessage +const offerMessage = credentialRecord.offerMessage +const requestMessage = credentialRecord.requestMessage +const credentialMessage = credentialRecord.credentialMessage +``` + +##### 0.2.x + +```ts +const credentialRecord = await agent.credentials.getById('credentialRecordId') + +const proposalMessage = await agent.credentials.findProposalMessage('credentialRecordId') +const offerMessage = await agent.credentials.findOfferMessage('credentialRecordId') +const requestMessage = await agent.credentials.findRequestMessage('credentialRecordId') +const credentialMessage = await agent.credentials.findCredentialMessage('credentialRecordId') +``` + +Because AFJ now also supports the issue credential v2 protocol, the return type of this protocol has been changed to `V1XXXMessage | V2XXXMessage | null`. Take this into account when working with the messages. + +You can check if a message is a specific version by using the `instanceof` operator: + +```ts +if (proposalMessage instanceof V1ProposeCredentialMessage) { + // do something +} +``` + +Shared properties (e.g. the proposal messages for v1 and v2 both have the `credentialPreview` property) can be accessed without doing an instance check. + + + +### Connections Module + +Version 0.2.0 added support for the [Out of Band protocol](https://github.com/hyperledger/aries-rfcs/blob/main/features/0434-outofband/README.md) with support for the [DID Exchange protocol](https://github.com/hyperledger/aries-rfcs/tree/main/features/0023-did-exchange). Internally AFJ now uses out of band invitations for all connections, even if you're connecting using the old invitations from the [Connection protocol](https://github.com/hyperledger/aries-rfcs/tree/main/features/0160-connection-protocol). + +#### Creating a Legacy Invitation + +The `createInvitation` method on the connections module has been moved to the out of band module and renamed to `createLegacyInvitation`. The method is not planned to be removed in the near future, the legacy merely indicates this will create an RFC 0160 connection invitation. Internally AFJ creates an out of band invitation and transforms it into a legacy invitation. If you want to create an out of band invitation instead, you should use `oob.createInvitation`. + + + +##### 0.1.0 + +```ts +const { connectionRecord, invitation } = await agent.connections.createInvitation({ + /* config */ +}) + +const invitationUrl = invitation.toUrl({ domain: 'https://example.com' }) +``` + +##### 0.2.x + +```ts +const { outOfBandRecord, invitation } = await agent.oob.createLegacyInvitation({ + /* config */ +}) + +const invitationUrl = invitation.toUrl({ domain: 'https://example.com' }) +``` + +Important thing to note here is that the `oob.createLegacyInvitation` does not return a connection record, but rather an out of band record. Because out of band also supports connection-less scenarios, a connection record is not created until a connection request is received (or sent in the case of the invitee role). + +You can listen for connection state change events that are associated with a specific out of band id. This allows you to link a connection to an invitation you created. + +```ts +// Listen for connection state changed events associated with the out of band record +agent.events.on(ConnectionEventTypes.ConnectionStateChanged, (event) => { + if (event.payload.connectionRecord.outOfBandId === outOfBandRecord.id) { + console.log(`Connection state changed for connection with out of band id ${outOfBandRecord.id}`) + } +}) +``` + +It is also possible to retrieve all connection records associated with an out of band invitation. Because of multi use invitations, there could be multiple connection records associated with a single out of band invitation. Instead of having a separate connection record that will always stay in the invited state, the out of band record will now handle the multi use capabilities of an invitation. + +```ts +// Retrieve all connections associated with an out of band id +const connections = await agent.connections.findAllByOutOfBandId(outOfBandRecord.id) +``` + + + +#### Receiving a Legacy Invitation + +The `receiveInvitation` and `receiveInvitationFromUrl` methods on the connections module have also been moved to the out of band module. Both methods support the new out of band invitations and the legacy RFC 0160 connection invitations. Internally AFJ converts the old invitations to out of band invitations. + + + +##### 0.1.0 + +```ts +const invitationUrl = 'https://example.com?c_i=eyXXX' + +// Receive invitation directly from url +const connectionRecord = await agent.connections.receiveInvitationFromUrl(invitationUrl, { + /* config */ +}) + +// Parse invitation and receive invitation +const parsedInvitation = await ConnectionInvitationMessage.fromUrl(invitationUrl) +const connectionRecord = await agent.connections.receiveInvitation(parsedInvitation, { + /* config */ +}) +``` + +##### 0.2.x + +```ts +const invitationUrl = 'https://example.com?c_i=eyXXX' + +// Receive invitation directly from url +const { outOfBandRecord, connectionRecord } = await agent.oob.receiveInvitationFromUrl(invitationUrl, { + /* config */ +}) + +// Parse invitation and receive invitation +const parsedInvitation = await agent.oob.parseInvitation(invitationUrl) +const secondConnectionRecord = await agent.oob.receiveInvitation(parsedInvitation, { + /* config */ +}) +``` + +The new receive invitation methods on the out of band module won't always return a connection record anymore. The out of band invitation may not contain any handshake protocols. In the case of receiving a connection invitation you will always receive a connection record though, as you can't use it for connection-less invitations. + + + +#### Updating to use `DidExchangeState` + +The `ConnectionState` that was previously used for the state of the `ConnectionRecord` has been changed to use the `DidExchangeState` for both connections made using the RFC 0160 Connection Protocol, as well as the RFC 0023 DID Exchange Protocol. + +The `DidExchangeState` has the following values: + +- `DidExchangeState.Start`, +- `DidExchangeState.InvitationSent`, +- `DidExchangeState.InvitationReceived`, +- `DidExchangeState.RequestSent`, +- `DidExchangeState.RequestReceived`, +- `DidExchangeState.ResponseSent`, +- `DidExchangeState.ResponseReceived`, +- `DidExchangeState.Abandoned`, +- `DidExchangeState.Completed` + +If you still need to access the old `ConnectionState` you can do so by accessing the computed `connectionRecord.rfc0160State` property. This will return the old `ConnectionState` value. + +### Updating Custom Messages to the New Message Type Objects + +Although this isn't a breaking change to the public API of the framework, it is something that you will need to take into account when creating custom modules. Starting from AFJ 0.2.0 we now support handling messages with different minor versions (e.g. receive a message with `@type` version 1.1 while we only support 1.0). With this change messages must now declare the message type as an `ParsedMessageType` object. We've added an `parseMessageType` util method that can help with this. + + + +#### 0.1.0 + +```ts +import { AgentMessage } from '@aries-framework/core' +import { Equals } from 'class-validator' + +class MyMessage extends AgentMessage { + @Equals(MyMessage.type) + public readonly type = MyMessage.type + public static readonly type = 'https://didcomm.org/my-protocol/1.0/my-type' +} +``` + +#### 0.2.x + +```ts +import { AgentMessage, IsValidMessageType, parseMessageType } from '@aries-framework/core' +import { Equals } from 'class-validator' + +class MyMessage extends AgentMessage { + // use IsValidMessageType instead of Equals + @IsValidMessageType(MyMessage.type) + // append .messageTypeUri to get the actual URI when instantiating a message + public readonly type = MyMessage.type.messageTypeUri + // use parseMessageType to get the message type object from a type. You can declare the object yourself, but this is the recommended way + public static readonly type = parseMessageType('https://didcomm.org/my-protocol/1.0/my-type') +} +``` + + + +## Breaking Storage Changes + +The 0.2.0 release is heavy on breaking changes to the storage format. This is not what we intend to do with every release. But as there's not that many people yet using the framework in production, and there were a lot of changes needed to keep the API straightforward, we decided to bundle a lot of breaking changes in this one release. + +Below all breaking storage changes are explained in as much detail as possible. The update assistant provides all tools to migrate without a hassle, but it is important to know what has changed. All examples only show the keys that have changed, unrelated keys in records have been omitted. + +See the [Update Assistant](/guides/updating/update-assistant.md) documentation for a guide on how to use the update assistant. + +The following config can be provided to the update assistant to migrate from 0.1.0 to 0.2.0: + +```json +{ + "v0_1ToV0_2": { + "mediationRoleUpdateStrategy": "" + } +} +``` + +### Credential Metadata + +The credential record had a custom `metadata` property in pre-0.1.0 storage that contained the `requestMetadata`, `schemaId` and `credentialDefinition` properties. Later a generic metadata API was added that only allows objects to be stored. Therefore the properties were moved into a different structure. + + + +#### 0.1.0 + +```json +{ + "requestMetadata": , + "schemaId": "", + "credentialDefinitionId": "" +} +``` + +#### 0.2.x + +```json +{ + "_internal/indyRequest": , + "_internal/indyCredential": { + "schemaId": "", + "credentialDefinitionId": "" + } +} +``` + +Accessing the `credentialDefinitionId` and `schemaId` properties will now be done by retrieving the `CredentialMetadataKeys.IndyCredential` metadata key. + +```ts +const indyCredential = credentialRecord.metadata.get(CredentialMetadataKeys.IndyCredential) + +// both properties are optional +indyCredential?.credentialDefinitionId +indyCredential?.schemaId +``` + + + +### Migrate Credential Record Properties + +In 0.2.0 the v1 DIDComm messages have been moved out of the credential record into separate records using the DidCommMessageRepository. The migration scripts extracts all messages (proposalMessage, offerMessage, requestMessage, credentialMessage) and moves them into the DidCommMessageRepository. + +With the addition of support for different protocol versions the credential record now stores the protocol version. With the addition of issue credential v2 support, other credential formats than indy can be used, and multiple credentials can be issued at once. To account for this the `credentialId` has been replaced by the `credentials` array. This is an array of objects containing the `credentialRecordId` and the `credentialRecordType`. For all current credentials the `credentialRecordType` will always be `indy`. + + + +#### 0.1.0 + +```json +{ + "credentialId": "09e46da9-a575-4909-b016-040e96c3c539", + "proposalMessage": { ... }, + "offerMessage": { ... }, + "requestMessage": { ... }, + "credentialMessage": { ... }, +} +``` + +#### 0.2.x + +```json +{ + "protocolVersion": "v1", + "credentials": [ + { + "credentialRecordId": "09e46da9-a575-4909-b016-040e96c3c539", + "credentialRecordType": "indy" + } + ] +} +``` + + + +### Mediation Record Role + +The role in the mediation record was always being set to `MediationRole.Mediator` for both mediators and recipients. This didn't cause any issues, but would return the wrong role for recipients. + +In 0.2 a check is added to make sure the role of a mediation record matches with actions (e.g. a recipient can't grant mediation), which means it will throw an error if the role is not set correctly. + +Because it's not always possible detect whether the role should actually be mediator or recipient, a number of configuration options are provided on how the role should be updated using the `v0_1ToV0_2.mediationRoleUpdateStrategy` option: + +- `allMediator`: The role is set to `MediationRole.Mediator` for both mediators and recipients +- `allRecipient`: The role is set to `MediationRole.Recipient` for both mediators and recipients +- `recipientIfEndpoint` (**default**): The role is set to `MediationRole.Recipient` if their is an `endpoint` configured on the record. The endpoint is not set when running as a mediator. There is one case where this could be problematic when the role should be recipient, if the mediation grant hasn't actually occurred (meaning the endpoint is not set). This is probably the best approach + otherwise it is set to `MediationRole.Mediator` +- `doNotChange`: The role is not changed + +Most agents only act as either the role of mediator or recipient, in which case the `allMediator` or `allRecipient` configuration is the most appropriate. If your agent acts as both a recipient and mediator, the `recipientIfEndpoint` configuration is the most appropriate. The `doNotChange` options is not recommended and can lead to errors if the role is not set correctly. + +### Extracting Did Documents to Did Repository + +The connection record previously stored both did documents from a connection in the connection record itself. Version 0.2.0 added a generic did storage that can be used for numerous usages, one of which is the storage of did documents for connection records. + +The migration script extracts the did documents from the `didDoc` and `theirDidDoc` properties from the connection record, updates them to did documents compliant with the did core spec, and stores them in the did repository. By doing so it also updates the unqualified dids in the `did` and `theirDid` fields generated by the indy-sdk to fully qualified `did:peer` dids compliant with the [Peer DID Method Specification](https://identity.foundation/peer-did-method-spec/). + +To account for the fact that the mechanism to migrate legacy did document to peer did documents is not defined yet, the legacy did and did document are stored in the did record metadata. This will be deleted later if we can be certain the did doc conversion to a `did:peer` did document is correct. + + + +#### 0.1.0 + +```json +{ + "did": "BBPoJqRKatdcfLEAFL7exC", + "theirDid": "UppcJ5APts7ot5WX25943F", + "verkey": "GAb4NUvpBcHVCvtP45vTVa5Bp74vFg3iXzdp1Gbd68Wf", + "didDoc": , + "theirDidDoc": , +} +``` + +#### 0.2.x + +```json +{ + "did": "did:peer:1zQmXUaPPhPCbUVZ3hGYmQmGxWTwyDfhqESXCpMFhKaF9Y2A", + "theirDid": "did:peer:1zQmZMygzYqNwU6Uhmewx5Xepf2VLp5S4HLSwwgf2aiKZuwa" +} +``` + + + +### Migrating to the Out of Band Record + +With the addition of the out of band protocol, invitations are now stored in the `OutOfBandRecord`. In addition a new field `invitationDid` is added to the connection record that is generated based on the invitation service or did. This allows to reuse existing connections. + +The migration script extracts the invitation and other relevant data into a separate `OutOfBandRecord`. By doing so it converts the old connection protocol invitation into the new Out of band invitation message. Based on the service or did of the invitation, the `invitationDid` is populated. + +Previously when creating a multi use invitation, a connection record would be created with the `multiUseInvitation` set to true. The connection record would always be in state `invited`. If a request for the multi use invitation came in, a new connection record would be created. With the addition of the out of band module, no connection records are created until a request is received. So for multi use invitation this means that the connection record with multiUseInvitation=true will be deleted, and instead all connections created using that out of band invitation will contain the `outOfBandId` of the multi use invitation. + + + +#### 0.1.0 + +```json +{ + "invitation": { + "@type": "https://didcomm.org/connections/1.0/invitation", + "@id": "04a2c382-999e-4de9-a1d2-9dec0b2fa5e4", + "recipientKeys": ["E6D1m3eERqCueX4ZgMCY14B4NceAr6XP2HyVqt55gDhu"], + "serviceEndpoint": "https://example.com", + "label": "test" + }, + "multiUseInvitation": "false" +} +``` + +#### 0.2.x + +```json +{ + "invitationDid": "did:peer:2.Ez6MksYU4MHtfmNhNm1uGMvANr9j4CBv2FymjiJtRgA36bSVH.SeyJzIjoiaHR0cHM6Ly9leGFtcGxlLmNvbSJ9", + "outOfBandId": "04a2c382-999e-4de9-a1d2-9dec0b2fa5e4" +} +``` + + + +### Unifying Connection States and Roles + +With the addition of the did exchange protocol there are now two states and roles related to the connection record; for the did exchange protocol and for the connection protocol. To keep it easy to work with the connection record, all state and role values are updated to those of the `DidExchangeRole` and `DidExchangeState` enums. + +The migration script transforms all connection record state and role values to their respective values of the `DidExchangeRole` and `DidExchangeState` enums. For convenience a getter +property `rfc0160ConnectionState` is added to the connection record which returns the `ConnectionState` value. + + + +#### 0.1.0 + +```json +{ + "state": "invited", + "role": "inviter" +} +``` + +#### 0.2.0 + +```json +{ + "state": "invitation-sent", + "role": "responder" +} +``` + + diff --git a/versioned_docs/version-0.4/updating/versions/0.2-to-0.3.md b/versioned_docs/version-0.4/updating/versions/0.2-to-0.3.md new file mode 100644 index 00000000..d231bb4f --- /dev/null +++ b/versioned_docs/version-0.4/updating/versions/0.2-to-0.3.md @@ -0,0 +1,676 @@ +# Migrating from AFJ 0.2.x to 0.3.x + +This document describes everything you need to know for updating AFJ 0.2.x to 0.3.x. If you're not aware of how updating in AFJ works make sure to first read the guide on [Updating AFJ](/guides/updating/index.md). + +First of all, update you dependencies to the 0.3.x versions. This will also update the needed peer depedencnies. **Extension packages are not updated with this command**. You need to update these manually, and make sure they're up to date with the latest version of AFJ. + + + +#### React Native + +```sh +yarn add @aries-framework/react-native@^0.3.0 @aries-framework/core@^0.3.0 indy-sdk-react-native@^0.3.0 + +# or NPM +npn install @aries-framework/react-native@^0.3.0 @aries-framework/core@^0.3.0 indy-sdk-react-native@^0.3.0 +``` + +#### Node + +```sh +yarn add @aries-framework/node@^0.3.0 @aries-framework/core@^0.3.0 + +# or NPM +npm install @aries-framework/node@^0.3.0 @aries-framework/core@^0.3.0 +``` + + + +## Breaking Code Changes + +This section will list all breaking changes made to the public API of AFJ between version 0.2.x and 0.3.0. + +:::info + +If you have custom modules take into account there could be a lot more breaking changes that aren't documented here. We try to make sure that the biggest breaking changes to the internal API are also documented here (e.g. see [Updating Custom Modules to the Plugin API](#Updating-Custom-Modules-to-the-new-Plugin-API)), but it is possible some breaking changes are not documented here (feel free to open PRs). + +::: + +### Agent creation + +The agent constructor has been updated to a single `AgentOptions` object that contains the config and dependencies properties. + + + +##### 0.2.x + +```ts +const agent = new Agent(agentConfig, agentDependencies) +``` + +##### 0.3.x + +```ts +const agent = new Agent({ config: agentConfig, dependencies: agentDependencies }) +``` + + + +This object contains: + +- config: Agent's initial configuration +- dependencies: platform-specific Agent dependencies +- modules: optional field for internal module configuration and custom module registration + +For easy migration, you can simply construct `AgentOptions` by putting current InitConfig into `config` key and agentDependencies into `dependencies` key. + +Note that, if you are defining `indyLedgers` configuration, you should set the indyNamespace for every ledger, as explained in [Agent Config tutorial](../../tutorials/agent-config/index.md#indyledgers). + +### did:key usage in protocols + +In accordance with [Aries RFC 0360](https://github.com/hyperledger/aries-rfcs/tree/b3a3942ef052039e73cd23d847f42947f8287da2/features/0360-use-did-key), since 0.2.5 there is a configuration parameter called `useDidKeyInProtocols` which, when enabled, will encode keys in did:key instead of previous base58 format, unless the other party has started a protocol and is using base58. + +This parameter was previously disabled by default and now it is enabled. If your agent only interacts with modern agents (e.g. AFJ 0.2.5 and newer) this will not represent any issue. Otherwise it is safer to explicitly set it to `false`. However, keep in mind that we expect this setting to be deprecated in the future, so we encourage you to update all your agents to use did:key. + +### Modules extracted from the core + +In this release two modules were extracted from the core and published as separate, optional packages: + +- actionMenu has been moved to @aries-framework/action-menu +- questionAnswer has been moved to @aries-framework/question-answer + +If you want to use them, you can integrate in an Agent instance by injecting them in constructor, as follows: + +```ts +import { ActionMenuModule } from '@aries-framework/action-menu' +import { QuestionAnswerModule } from '@aries-framework/question-answer' + +const agent = new Agent({ + config: { + /* config */ + }, + dependencies: agentDependencies, + modules: { + actionMenu: new ActionMenuModule(), + questionAnswer: new QuestionAnswerModule(), + /* other custom modules */ + }, +}) +``` + +As they are now considered custom modules, their API can be accessed in `modules` namespace, so you should add it to every call to them. + + + +##### 0.2.x + +```ts +await agent.questionAnswer.sendQuestion(connectionId, { + question: 'Do you want to play?', + validResponses: [{ text: 'Yes' }, { text: 'No' }], +}) + +await agent.questionAnswer.sendAnswer(questionAnswerRecordId, 'Yes') +``` + +##### 0.3.x + +```ts +await agent.modules.questionAnswer.sendQuestion(connectionId, { + question: 'Do you want to play?', + validResponses: [{ text: 'Yes' }, { text: 'No' }], +}) + +await agent.modules.questionAnswer.sendAnswer(questionAnswerRecordId, 'Yes') +``` + + + +### Discover Features Module + +This module now supports both Discover Features V1 and V2, and as it happened to other modules, `queryFeatures` method parameters have been unified to a single object and requires to specify the version of Discover Features protocol to be used. Note that `query` property has been replaced by the more general `queries` which accepts multiple features to be search for. To convert a query to this new format you simply need to create a single-object array whose unique object whose `featureType` field is 'protocol' and `match` field is the query itself. + + + +##### 0.2.x + +```ts +await agent.discovery.queryFeatures(connectionId, { + query: 'https://didcomm.org/messagepickup/2.0', + comment: 'Detect if protocol is supported', +}) +``` + +##### 0.3.x + +```ts +await agent.discovery.queryFeatures({ + connectionId, + protocolVersion: 'v1', + queries: [{ featureType: 'protocol', match: 'https://didcomm.org/messagepickup/2.0' }], + comment: 'Detect if protocol is supported', +}) +``` + + + +The convenience method **isProtocolSupported** has been replaced by the more general synchronous mode of queryFeatures, which works when awaitDisclosures in options is set. Instead of returning a boolean, it returns an object with matching features: + + + +##### 0.2.x + +```ts +const isPickUpV2Supported = await agent.discovery.isProtocolSupported(connectionId, StatusRequestMessage) +``` + +##### 0.3.x + +```ts +const discloseForPickupV2 = await agent.discovery.queryFeatures({ + connectionId: connectionId, + protocolVersion: 'v1', + queries: [{ featureType: 'protocol', match: StatusMessage.type.protocolUri }], + awaitDisclosures: true, + awaitDisclosuresTimeoutMs: 7000, +}) + +const isPickUpV2Supported = discloseForPickupV2.features?.length === 1 +``` + + + +:::info + +Discover Features module does not rely anymore on Agent `Dispatcher` to determine protocol support. Instead, it uses the new Feature Registry, where any custom modules implementing protocols must register them. + +This procedure can be done in module's `register(dependencyManager, featureRegistry)`. + +::: + +### Ledger Module + +Apart from the aforementioned indyLedgers configuration, you should also [note a slight change](../../tutorials/issue-a-credential.md#side-notes) in behaviour when attempting to register credential definitions that already exists on the ledger but not in the wallet. + +### Proofs Module + +#### Module API Updates + +Much in the same way as in 0.2.0 release when [Issue Credential V2 protocol](./0.1-to-0.2.md#module-api-updates) has been added, now that Present Proof V2 is supported, we introduced changes to proofs module. + +Basically, for all methods in the proofs module you should take the following steps to update your code: + +1. Move all function parameters into a single object. All module methods now take a single object that contain all properties. +2. For methods that initiate proposals, requests or presentations (`proposeProof`, `acceptProposal`, `requestProof`, `acceptPresentation`, etc.), you should pass `protocolVersion: 'v1'` to indicate we should use the v1 protocol +3. All indy specific attributes (e.g. Presentation Preview) should be passed in the `proofFormats.indy` object. +4. Some indy objects, as the preview should now be passed only as their attributes (i.e. no need of creating the object instance) and provided in the `proofFormats.indy` object. + + + +##### 0.2.x + +```ts +await agent.proofs.proposeProof( + 'connectionId', + new PresentationPreview({ + attributes: [new PresentationPreviewAttribute({ name: 'key', value: 'value' })], + predicates: [ + new PresentationPreviewPredicate({ + name: 'age', + credentialDefinitionId, + predicate: PredicateType.GreaterThanOrEqualTo, + threshold: 50, + }), + ], + }) +) +``` + +##### 0.3.x + +```ts +await agent.proofs.proposeProof({ + connectionId: connection.id, + protocolVersion: 'v1', + proofFormats: { + indy: { + attributes: [{ name: 'key', value: 'value' }], + predicates: [{name: 'age', credentialDefinitionId, predicate: PredicateType.GreaterThanOrEqualTo, threshold: 50, ] + }, + }, + comment: 'Propose proof comment', +}) +``` + + + +#### Messages Extracted from Proof Exchange Record + +The DIDComm messages that were previously stored on the proof record, have been extracted to separate DIDComm message records. This makes it easier to work with multiple versions of the protocol internally, and keeps the proof exchange record agnostic of the protocol version. Instead of accessing the messages through the `proposalMessage`, `requestMessage` and `presentationMessage` parameters, we now expose dedicated methods on the proofs module to retrieve the message. + +With the addition of the v2 messages, all v1 messages have been prefixed with `V1` while v2 messages have been prefixed with `V2` (`V1RequestPresentationMessage` and `V2RequestPresentationMessage`). If you were using these messages classes throughout your codebase, update them to use the `V1` prefix. + + + +##### 0.2.x + +```ts +const proofRecord = await agent.proofs.getById('proofRecordId') + +const proposalMessage = proofRecord.proposalMessage +const requestMessage = proofRecord.requestMessage +const presentationMessage = proofRecord.presentationMessage +``` + +##### 0.3.x + +```ts +const proofRecord = await agent.proofs.getById('proofRecordId') + +const proposalMessage = await agent.proofs.findProposalMessage('proofRecordId') +const requestMessage = await agent.proofs.findRequestMessage('proofRecordId') +const presentationMessage = await agent.proofs.findPresentationMessage('proofRecordId') +``` + +Because AFJ now also supports the present proof v2 protocol, the return type of this protocol has been changed to `V1XXXMessage | V2XXXMessage | null`. Take this into account when working with the messages. + +You can check if a message is a specific version by using the `instanceof` operator: + +```ts +if (proposalMessage instanceof V1RequestPresentationMessage) { + // do something +} +``` + + + +### Out Of Band Proofs and Credentials + +With the addition of the out of band module, the creation of connection-less messages has been split into two steps, allowing for better control and flexibility. The previous `agent.proofs.createOutOfBandRequest` has been replaced by the `agent.proofs.createRequest` method. This new method creates a proof request that is not tied to any connection. + +What you can now do is call `agent.oob.createLegacyConnectionlessInvitation` to attach the service decorator to the message and get a legacy connectionless message. + + + +#### 0.2.x + +```ts +const { requestMessage, proofRecord } = await agent.proofs.createOutOfBandRequest({ + requestedAttributes: { + group1: { + name: 'dateOfBirth', + restrictions: [{ schemaId: 'F72i3Y3Q4i466efjYJYCHM:2:aha_cert:4.1.1' }], + }, + }, +}) +``` + +#### 0.3.x + +```ts +const { message, proofRecord } = await agent.proofs.createRequest({ + protocolVersion: 'v1', + proofFormats: { + indy: { + requestedAttributes: { + group1: { + name: 'dateOfBirth', + restrictions: [ + { + schemaId: 'F72i3Y3Q4i466efjYJYCHM:2:aha_cert:4.1.1', + }, + ], + }, + }, + }, + }, +}) + +const { invitationUrl, message: messageWithServiceDecorator } = await agent.oob.createLegacyConnectionlessInvitation({ + recordId: proofRecord.id, + domain: 'https://google.com', + message, +}) +``` + + + +Out of band invitations are the new way to send messages out of band. You can use it for connection-less exchanges, but also for exchanges that you want to establish a connection for first. Here's an example on how to use the out of band module to create a connection-less invitation for a proof request: + +```ts +const outOfBandRecord = await agent.oob.createInvitation({ + handshake: false, // set to true if you want to create a connection + messages: [message], +}) + +const invitationUrl = outOfBandRecord.outOfBandInvitation.toUrl({ + domain: 'https://afj.com', +}) +``` + +As you can see, there's now a lot more ways to use a message not tied to a connection. By splitting the creation of the message from the creation of the invitation, we can now create a message not bound to a connection (at time of creation) for multiple use cases. + +### Updating Custom Modules to the new Plugin API + +Although this isn't a breaking change to the public API of the framework, it is something that you will need to take into account if you have custom modules and want to upgrade them to make compatible with AFJ 0.3.0. + +#### Renaming handler classes + +`Handler` has been have been renamed to `MessageHandler` to be be more descriptive, along with related types and methods. This means: + +- `Handler` is now `MessageHandler` +- `HandlerInboundMessage` is now `MessageHandlerInboundMessage` +- `Dispatcher.registerHandler` is now `Dispatcher.registerMessageHandler` and is marked as deprecated. The recommended way of registering handlers is by using the new `MessageHandlerRegistry` object by calling `MessageHandlerRegistry.registerMessageHandler`. + +If your custom module include message handlers, you must update them accordingly. + + + +##### 0.2.x + +```ts +export class MyHandler implements Handler { + public supportedMessages = [MyMessage] + + public async handle(inboundMessage: HandlerInboundMessage) { + ... + } +} +``` + +##### 0.3.x + +```ts +export class MyHandler implements MessageHandler { + public supportedMessages = [MyMessage] + + public async handle(inboundMessage: MessageHandlerInboundMessage) { + ... + } +} +``` + + + +#### Using AgentContext + +First of all, it's worth noting that now all services and repositories have been made stateless. A new `AgentContext` is introduced that holds the current context, which is passed to each method call. Therefore, you'll need to update every call to services, repositories and also eventEmitter methods to pass `AgentContext` object as first argument. + +AgentContext can be obtained from either: + +- MessageContext used by message handlers (accesed as messageContext.agentContext) +- Injected in your API constructor: you can store the instance and pass it to all your service and repository calls + + + +#### 0.2.x + +```ts + public async createRequest(options: CreateRequestOptions) { + const message = new RequestMessage({ + parentThreadId: options.parentThreadId, + }) + + const record = new MyRecord({ + connectionId: options.connectionRecord.id, + threadId: message.id, + parentThreadId: options.parentThreadId, + }) + + await this.myRecordRepository.save(record) + + this.eventEmitter.emit({ + type: MyRecordEventTypes.StateChanged, + payload: { + myRecord: record, + previousState: null, + }, + }) + + return { record, message } + } + + public async processRequest(messageContext: HandlerInboundMessage) { + const { message } = messageContext + + const record = new MyRecord({ + connectionId: connection.id, + threadId: messageContext.message.id, + parentThreadId: messageContext.message.thread?.parentThreadId, + }) + + await this.myRepository.save(record) + + return record + } +``` + +#### 0.3.x + +```ts + public async createRequest(agentContext: AgentContext, options: CreateRequestOptions) { + const message = new RequestMessage({ + parentThreadId: options.parentThreadId, + }) + + const record = new MyRecord({ + connectionId: options.connectionRecord.id, + threadId: message.id, + parentThreadId: options.parentThreadId, + }) + + await this.myRecordRepository.save(agentContext, record) + + this.eventEmitter.emit(agentContext, { + type: MyRecordEventTypes.StateChanged, + payload: { + myRecord: record, + previousState: null, + }, + }) + + return { record, message } + } + + public async processRequest(messageContext: MessageHandlerInboundMessage) { + const { message } = messageContext + + const record = new MyRecord({ + connectionId: connection.id, + threadId: messageContext.message.id, + parentThreadId: messageContext.message.thread?.parentThreadId, + }) + + await this.myRepository.save(messageContext.agentContext, record) + + return record + } +``` + + + +#### Using OutboundMessageContext + +If your module implements a protocol that sends messages to other agents, you will notice that Agent's `MessageSender` now receives the more generic `OutboundMessageContext` class, which replaces previous helper method `createOutboundMessage`. + +You can take advantage of this new mechanism to associate a record to the context, in order to do specific actions to it when outbound message state changes (e.g. a `MessageSendingError` is thrown or `AgentMessageSentEvent` is emitted). + + + +#### 0.2.x + +```ts +import { createOutboundMessage } from '@aries-framework/core' + +const outboundMessage = createOutboundMessage(connection, message) +await this.messageSender.sendMessage(outboundMessage) +``` + +#### 0.3.x + +```ts +import { OutboundMessageContext } from '@aries-framework/core' + +const outboundMessageContext = new OutboundMessageContext(message, { + agentContext: this.agentContext, + connection, + // optional, if you want to link the message to a related record + associatedRecord: record, +}) + +await this.messageSender.sendMessage(outboundMessageContext) +``` + + + +#### Updating module structure to register in new Plugin API + +Existing modules can benefit from the new Plugin API mechanism by doing the following modifications: + +1. Rename Module class (e.g. MyModule) to API class (MyApi) and add @injectable decorator. Inject AgentContext in order to pass it to any services or repositories it might call. For instance: + +```ts +import { injectable } from '@aries-framework/core' + +@injectable() // <-- Add this +export class MyApi { + private messageSender: MessageSender + private myService: MyService + private connectionService: ConnectionService + private agentContext: AgentContext // <-- Add this + + public constructor( + messageHandlerRegistry: MessageHandlerRegistry, // <-- use this instead of Dispatcher + messageSender: MessageSender, + myService: MyService, + connectionService: ConnectionService, + agentContext: AgentContext // <-- Add this + ) { + this.messageSender = messageSender + this.myService = myService + this.connectionService = connectionService + this.agentContext = agentContext // <-- Add this + this.registerHandlers(messageHandlerRegistry) // <-- use messageHandlerRegistry instead of dispatcher + } +``` + +2. Create a new Module class that implements Module interface and registers the dependencies and features. For instance: + +```ts +import type { DependencyManager, FeatureRegistry, Module } from '@aries-framework/core' + +import { Protocol } from '@aries-framework/core' + +export class MyModule implements Module { + public readonly api = MyApi // the one we've just renamed from MyModule + + public register(dependencyManager: DependencyManager, featureRegistry: FeatureRegistry) { + // Api + dependencyManager.registerContextScoped(MyApi) + + // Services + dependencyManager.registerSingleton(MyService) + + // Repositories + dependencyManager.registerSingleton(MyRepository) + + // Feature Registry: don't forget to register your protocols and other features your module may add + featureRegistry.register( + new Protocol({ + id: 'https://didcomm.org/my-protocol/1.0', + roles: [MyRole.Sender, MyRole.Receiver], + }) + ) + } +``` + +After doing this, you can add your module to agent constructor like this: + +```ts +const agent = new Agent({ + config: { + /* config */ + }, + dependencies: agentDependencies, + modules: { + myModule: new MyModule(), + /* other custom modules */ + }, +}) + +// MyModule API can be accessed in agent.modules namespace +await agent.modules.myModule.doSomething() + +await agent.modules.myModule.doAnotherThing() +``` + +## Breaking Storage Changes + +The 0.3.0 release introduces some breaking changes to the storage format, mainly related to Proof Exchanges. + +Below all breaking storage changes are explained in as much detail as possible. The update assistant provides all tools to migrate without a hassle, but it is important to know what has changed. All examples only show the keys that have changed, unrelated keys in records have been omitted. + +See the [Update Assistant](/guides/updating/update-assistant.md) documentation for a guide on how to use the update assistant. + +There are no config parameters to be provided to the update assistant to migrate from 0.2.x to 0.3.x. + + + +### Migrate Proof Record Properties + +In 0.3.0 the v1 DIDComm messages have been moved out of the proof record into separate records using the DidCommMessageRepository. The migration scripts extracts all messages (proposalMessage, requestMessage, presentationMessage) and moves them into the DidCommMessageRepository. With the addition of support for different protocol versions the proof record now stores the protocol version. + + + +#### 0.2.x + +```json +{ + "proposalMessage": { ... }, + "requestMessage": { ... }, + "presentationMessage": { ... }, +} +``` + +#### 0.3.x + +```json +{ + "protocolVersion": "v1" +} +``` + + + +### Migrate Connection Record properties + +The recently introduced `connectionType` tag has been pluralized to reflect the fact that more than a single connection type can be defined for a given connection. Also, it is now available as a direct record property (e.g. can be queried and set by using `connectionRecord.connectionTypes`) apart from the tag for efficient search. + +The migration script renames `connectionType` to `connectionTypes` in all connections, and also searches for any mediation connection and adds `ConnectionType.Mediator` as one of its types. + +### Migrate Did Record properties + +The `didRecord.id` was previously the did itself. However to allow for connecting with self, where multiple did records are created for the same did, the id property is now an uuid and a separate did property is added. + +The migration script generates a new ID for each did record and stores its did into didRecord.did property. + + + +#### 0.2.x + +```json +{ + "id": "did" +} +``` + +#### 0.3.x + +```json +{ + "id": "uuid", + "did": "did" +} +``` + + diff --git a/versioned_docs/version-0.4/updating/versions/0.3-to-0.4.md b/versioned_docs/version-0.4/updating/versions/0.3-to-0.4.md new file mode 100644 index 00000000..034773a2 --- /dev/null +++ b/versioned_docs/version-0.4/updating/versions/0.3-to-0.4.md @@ -0,0 +1,899 @@ +# Migrating from AFJ 0.3.x to 0.4.x + +This document describes everything you need to know for updating AFJ 0.3.x to 0.4.x. If you're not aware of how updating in AFJ works make sure to first read the guide on [Updating AFJ](/guides/updating/index.md). + +First of all, update you dependencies to the 0.4.x versions. This will also update the needed peer dependencies. **Extension packages are not updated with this command**. You need to update these manually, and make sure they're up to date with the latest version of AFJ. + +Aries Framework JavaScript 0.4.0 is a major release that introduces a lot of new features and changes to the public API. Specifically, this release removed the dependency on the Indy SDK from the `@aries-framework/core` package. Agent setup is more flexible, but it also means the setup is more complex. Follow the mentioned steps in this document carefully to make the upgrade as smooth as possible. + +:::caution + +The migration guide only covers how to migrate from 0.3.x to 0.4.x while keeping the same behavior and dependencies. AFJ 0.4.0 introduced a lot of new features and adds support for [Aries Askar](https://github.com/hyperledger/aries-askar), [Indy VDR](https://github.com/hyperledger/indy-vdr) and [AnonCreds RS](https://github.com/hyperledger/anoncreds-rs) as a replacement for the Indy SDK. + +Migrating to these new components requires additional migration steps, which need to be closely followed to prevent loss of data. These can be found at the [Update Indy SDK to Askar guide](../update-indy-sdk-to-askar.md). + +As noted in the [Update Indy SDK to Askar guide](../update-indy-sdk-to-askar.md), it is very important that the 0.3.x to 0.4.x update is started after migrating from the Indy SDK to Aries Askar. + +::: + +:::caution + +Multi-tenancy is not covered in the 0.3.x to 0.4.x migration guide. If you're using multi-tenancy in 0.3.x and want to migrate to 0.4.x, please open an issue on [Github](https://github.com/hyperledger/aries-framework-javascript). + +::: + +:::caution + +The following APIs, modules and features are experimental and therefore not covered by the semver versioning in Aries Framework JavaScript. If you're using any of these features, make sure to use an exact version of AFJ (`0.4.0`) instead of a range (`^0.4.0`): + +- Implementing your own `AnonCredsRegistry` and AnonCreds service implementation. Using the default implementations (Indy SDK, AnonCreds RS) is fine. +- Using the shared component libraries from `@aries-framework/aries-askar`, `@aries-framework/indy-vdr` and `@aries-framework/anoncreds-rs` +- Using OpenID4VC from the `@aries-framework/openid4vc-client` module +- W3C JWT Verifiable Credentials +- Using multi-tenancy from the `@aries-framework/tenants` module + +::: + + + +#### React Native + +First install the updated dependencies. Make sure to also install the new `@aries-framework/indy-sdk` package, which is a wrapper around the Indy SDK and install the `indy-sdk-react-native` package. + +```sh +yarn add @aries-framework/react-native@^0.4.0 @aries-framework/core@^0.4.0 @aries-framework/indy-sdk@^0.4.0 @aries-framework/anoncreds@^0.4.0 indy-sdk-react-native@^0.3.1 + +# or NPM +npn install @aries-framework/react-native@^0.4.0 @aries-framework/core@^0.4.0 @aries-framework/indy-sdk@^0.4.0 @aries-framework/anoncreds@^0.4.0 indy-sdk-react-native@^0.3.1 +``` + +We also need to install types for the `indy-sdk-react-native` package, which we take from the `@types/indy-sdk` package. + +```sh +yarn add --dev @types/indy-sdk-react-native@npm:@types/indy-sdk + +# or NPM +npm install --save-dev @types/indy-sdk-react-native@npm:@types/indy-sdk +``` + +#### Node + +First install the updated dependencies. Make sure to also install the new `@aries-framework/indy-sdk` package, which is a wrapper around the Indy SDK and install the `indy-sdk` package itself. + +```sh +yarn add @aries-framework/node@^0.4.0 @aries-framework/core@^0.4.0 @aries-framework/indy-sdk@^0.4.0 @aries-framework/anoncreds@^0.4.0 indy-sdk + +# or NPM +npm install @aries-framework/node@^0.4.0 @aries-framework/core@^0.4.0 @aries-framework/indy-sdk@^0.4.0 @aries-framework/anoncreds@^0.4.0 indy-sdk +``` + +We also need to install types for the `indy-sdk` package, which are available in the `@types/indy-sdk` package. + +```sh +yarn add --dev @types/indy-sdk + +# or NPM +npm install --save-dev @types/indy-sdk +``` + + + +## Breaking Code Changes + +This section will list all breaking changes made to the public API of AFJ between version 0.3.x and 0.4.0. + +:::info + +If you have custom modules take into account there could be a lot more breaking changes that aren't documented here. We try to make sure that the biggest breaking changes to the internal API are also documented here, but it is possible some breaking changes are not documented here (feel free to open a pull request). + +::: + +### Agent Creation + +With the dependency on the Indy SDK removed from the `@aries-framework/core` package, we now need to register the `IndySdkModule` to still leverage the functionality the Indy SDK provides. + + + +##### 0.3.x + +```ts +import { Agent } from '@aries-framework/core' + +// Import from @aries-framework/react-native in React Native +import { agentDependencies } from '@aries-framework/node' + +const agent = new Agent({ + config: { + /* ... */ + }, + dependencies: agentDependencies, +}) +``` + +##### 0.4.x + +```ts +import { Agent } from '@aries-framework/core' +import { IndySdkModule } from '@aries-framework/indy-sdk' + +// Import from @aries-framework/react-native in React Native +import { agentDependencies } from '@aries-framework/node' + +// Import from indy-sdk-react-native in React Native +import indySdk from 'indy-sdk' + +const agent = new Agent({ + config: { + /* ... */ + }, + dependencies: agentDependencies, + modules: { + // Register the IndySdkModule and provide the indySdk dependency + indySdk: new IndySdkModule({ + indySdk, + }), + }, +}) +``` + + + +### Indy Network Configuration + +With the Indy SDK being extracted out of core, the `indyLedger` configuration option is no longer available on the `AgentConfig` interface. Instead, the `networks` configuration option is now available on the `IndySdkModule` configuration. + +In addition the `connectToIndyLedgersOnStartup` property has been removed in favor of a per-network `connectOnStartup` property that allows more fine-grained control over which networks to connect to on startup. + + + +##### 0.3.x + +```ts +import { Agent } from '@aries-framework/core' + +// Import from @aries-framework/react-native in React Native +import { agentDependencies } from '@aries-framework/node' + +const agent = new Agent({ + config: { + connectToIndyLedgersOnStartup: true, + indyLedgers: [ + { + id: 'Sovrin Mainnet', + indyNamespace: 'sovrin', + isProduction: true, + genesisPath: './genesis/sovrin-genesis.txn', + }, + ], + }, + dependencies: agentDependencies, +}) +``` + +##### 0.4.x + +```ts +import { Agent } from '@aries-framework/core' +import { IndySdkModule } from '@aries-framework/indy-sdk' + +// Import from @aries-framework/react-native in React Native +import { agentDependencies } from '@aries-framework/node' + +// Import from indy-sdk-react-native in React Native +import indySdk from 'indy-sdk' + +const agent = new Agent({ + config: { + /* ... */ + }, + dependencies: agentDependencies, + modules: { + // Register the IndySdkModule and provide the indySdk dependency + indySdk: new IndySdkModule({ + indySdk, + + // add networks as a replacement for indyLedgers + networks: [ + { + id: 'Sovrin Mainnet', + indyNamespace: 'sovrin', + isProduction: true, + genesisPath: './genesis/sovrin-genesis.txn', + // new connectOnStartup property + connectOnStartup: true, + }, + ], + }), + }, +}) +``` + + + +### Changes to wallet + +Throughout the framework it was possible to provide a `seed` for deterministic key generation. Recently it was discovered that the `seed` property in the Indy SDK was not actually used as a seed, but directly as the private key. + +Therefore a new `privateKey` property was added to the `Wallet` interface in addition to the `seed` property. When using the `IndySdkModule` this now means you can **only** provide the `privateKey` property. The `seed` property is no longer supported **by the `IndySdkModule`**. + +The type of the `seed` property has also been changed to `Buffer` to make it more consistent with `privateKey` property, and remove the ambiguity of what the encoding of the string variant of the `seed` property should be. + +### Did Resolver and Registrar + +The `did:sov` resolver and registrar were registered by default in 0.3.x of the agent. In 0.4.0 they've been moved to the `@aries-framework/indy-sdk` package and are thus not registered by default on the DIDs module anymore. In addition, the `IndySdkSovDidRegistrar` has been replaced in favor of the `IndySdkIndyDidRegistrar` which provides similar behavior, but leverages the new [`did:indy` method](https://hyperledger.github.io/indy-did-method/#indy-did-method-identifiers), which removes ambiguity about which network to use. You can still use the `IndySdkSovDidResolver` to resolve `did:sov` DIDs. + +Note that the `IndySdkModule` MUST be registered when using the Indy SDK did resolvers and registrars (see [Agent Creation](#agent-creation)). The networks supported by the resolvers and registrar is determined by the `networks` registered on the `IndySdkModule` (see [Indy Network Configuration](#indy-network-configuration)). + +Also note that by default the `WebDidResolver`, `KeyDidResolver` and `PeerDidResolver` are registered, and setting the `resolvers` property on the `DidsModule` configuration will override the default resolvers (an exception is the `PeerDidResolver` as it is required for creating connections, and thus will always be registered). + +The same thing is true for the `registrars`, for which the `KeyDidRegistrar` and `PeerDidRegistrar` are registered by default. If defining the `resolvers` and `registrars`, make sure to include the default registrars if you want to keep the previous behavior. + + + +##### 0.3.x + +```ts +import { Agent } from '@aries-framework/core' + +// Import from @aries-framework/react-native in React Native +import { agentDependencies } from '@aries-framework/node' + +const agent = new Agent({ + config: { + /* ... */ + }, + dependencies: agentDependencies, +}) +``` + +##### 0.4.x + +```ts +import { Agent, DidsModule } from '@aries-framework/core' +import { IndySdkModule } from '@aries-framework/indy-sdk' + +// Import from @aries-framework/react-native in React Native +import { agentDependencies } from '@aries-framework/node' + +const agent = new Agent({ + config: { + /* ... */ + }, + dependencies: agentDependencies, + modules: { + // note that the IndySdkModule MUST be registered for the resolvers and registrars to work + // they are left out for brevity and can bee + dids: new DidsModule({ + registrars: [new IndySdkIndyDidRegistrar()], + resolvers: [new IndySdkSovDidResolver(), new IndySdkIndyDidResolver()], + }), + }, +}) +``` + + + +### Removal of `publicDidSeed` and `publicDid` + +To make AFJ more generic, and less focused on Hyperledger Indy, and Indy dids, the `publicDidSeed` and `publicDid` properties have been removed from the agent configuration, the agent class, and the `Wallet` interface. + +The `publicDid` property was used as the did to register items in the ledger module. The approach had some limitations: + +- An agent could only have a single `publicDid` property. This means that if you wanted to write to multiple ledgers you would have to create multiple agents +- The property assumed only Indy ledgers would be used, and didn't take into account the possibility of other ledgers. + +AFJ now provides generic APIs that can work with any ledger, and thus the `publicDid` property is no longer needed. Different sections of this migration guide will explain the different parts of how to use the new APIs, this section just focuses on how to replace the `publicDid` property. + +The most common use case for the `publicDid` property was for registering an endorser did that can endorse (read: pay for) transactions on the ledger. This can now be done by importing the did into agent, after which it can be used by the AnonCreds module to register schemas and credential definitions, and the did registrar to register DIDs. + +There's a **one-time import** that needs to be done to import the did into the agent using the `DidsApi.import` method. If you've previously used the `publicDidSeed` property, providing the private key is optional, as it is already stored in the wallet. Note that the `privateKey` is the same as the `publicDidSeed`, see [Changes to Wallet](#changes-to-wallet) for context). The `import` method will resolve the did passed to the `import` method (so make sure to register the `IndySdkIndyDidResolver`). It is recommended to import the endorser did as an `did:indy` did rather than a `did:sov` did, as the `did:sov` method is deprecated for creation. The `did:indy` did can be constructed by replacing `sov` with `indy:`, where `` should be replaced with a namespace as registered in the `networks` property of the `IndySdkModule` (see [Indy Network Configuration](#indy-network-configuration)). + +An initial list of namespace identifiers can be found in an [issue in the Indy Did Networks Repository](https://github.com/hyperledger/indy-did-networks/issues/3). In the future this list will be maintained in the [Indy DID Networks repository](https://github.com/hyperledger/indy-did-networks) itself. + + + +##### 0.3.x + +```ts +import { Agent } from '@aries-framework/core' + +// Import from @aries-framework/react-native in React Native +import { agentDependencies } from '@aries-framework/node' + +const agent = new Agent({ + config: { + publicDidSeed: '01eafa4de4e22ed4fc2ee522b6ce2731', + }, + dependencies: agentDependencies, +}) +``` + +##### 0.4.x + +```ts +import { Agent, DidsModule, KeyType, TypedArrayEncoder } from '@aries-framework/core' +import { IndySdkModule, IndySdkIndyDidResolver } from '@aries-framework/indy-sdk' + +// Import from @aries-framework/react-native in React Native +import { agentDependencies } from '@aries-framework/node' + +// Import from indy-sdk-react-native in React Native +import indySdk from 'indy-sdk' + +const agent = new Agent({ + config: { + /* ... */ + }, + dependencies: agentDependencies, + modules: { + indySdk: new IndySdkModule({ + indySdk, + networks: [ + { + id: 'Sovrin Mainnet', + // Important: make sure to pick the correct indy namespace for the network you're connecting to + // See: https://github.com/hyperledger/indy-did-networks/issues/3 + indyNamespace: 'sovrin', + isProduction: true, + genesisPath: './genesis/sovrin-genesis.txn', + }, + ], + }), + dids: new DidsModule({ + // Important: Make sure to register the IndySdkIndyDidResolver + resolvers: [new IndySdkIndyDidResolver()], + }), + }, +}) + +// Important: the `import` method only has to be called once, and the agent MUST be initialized before calling it. +// The private key is optional if you've used the publicDidSeed property before (as the key will already be in the wallet), +await agent.initialize() +await agent.dids.import({ + did: 'did:indy:sovrin:KEPUoXHcswsfsHkXGfmXB7', + privateKeys: [ + { + keyType: KeyType.Ed25519, + privateKey: TypedArrayEncoder.fromString('01eafa4de4e22ed4fc2ee522b6ce2731'), + }, + ], +}) +``` + + + +### More Granular Usage of Legacy `did:sov` Prefix in DIDComm Messages + +AFJ 0.3.0 used the `useLegacyDidSovPrefix` to use the legacy `did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/` as the prefix in the `@type` of DIDComm message instead of the new `https://didcomm.org` prefix. Over time it has proven that this approach leads to undesired behavior as all messages (even protocols that were defined after the new prefix was the default) would use the legacy prefix. However, due to not all implementations having support for new prefix, disabling the legacy prefixes proved to be a problem. + +Therefore, in AFJ 0.4.0 the `useLegacyDidSovPrefix` property has been replaced with the `useDidSovPrefixWhereAllowed` property. This property will only use the legacy prefix for protocols that were defined before the new prefix was the default. This means that protocols that were defined after the new prefix was the default will use the new prefix independent of the value of the `useDidSovPrefixWhereAllowed` property. We hope this will allow us to slowly migrate away from the legacy prefix as new protocols are defined without breaking backwards compatibility. + + + +##### 0.3.x + +```ts +import { Agent } from '@aries-framework/core' + +// Import from @aries-framework/react-native in React Native +import { agentDependencies } from '@aries-framework/node' + +const agent = new Agent({ + config: { + useLegacyDidSovPrefix: true, + }, + dependencies: agentDependencies, +}) +``` + +##### 0.4.x + +```ts +import { Agent } from '@aries-framework/core' + +// Import from @aries-framework/react-native in React Native +import { agentDependencies } from '@aries-framework/node' + +const agent = new Agent({ + config: { + useDidSovPrefixWhereAllowed: true, + }, + dependencies: agentDependencies, +}) +``` + + + +### Removal of `injectionContainer` property from the agent + +The `injectionContainer` property on the `Agent` has been replaced by the `dependencyManager` property. The `dependencyManager` property is an instance of the `DependencyManager` class and wraps the injection container from `tsyringe`. + +The `DependencyManager` _should_ provide all functionality that is needed, and it is recommended to not use the injection directly. If you need to use the injection container directly, you can access it via the `container` property on the `DependencyManager` instance, but please raise an issue to discuss if the functionality you need should be added to the `DependencyManager` class. + +### `connection` has been updated to `connectionId` in `TransportSession` + +The `connection` property on the `TransportSession` has been changed to `connectionId` and now only holds a reference to the connection id instead of the connection record itself. + +Accessing the connection on a transport session is an advanced case that is mostly only relevant when implementing a custom transport. If you are using the default transports, you should not be affected by this change. + +### Replacement of Ledger Module with new AnonCreds Module + +The ledger module has been available in AFJ since the very beginning, and was due for a big overhaul. With the addition of the dids module a while ago we already had a replacement for the `registerPublicDid` and `getPublicDid` methods on the ledger module. The other methods of the ledger module have been replaced by the AnonCreds module. + +In AFJ 0.4.0 AnonCreds credential support is not part of the core framework anymore, and needs to be manually registered on the agent. The first part is enabling the AnonCreds module, which allows to manage AnonCreds objects, interact with the ledger, and issuer, hold and verify AnonCreds credentials and is explained in this section. The second part is actually allowing AnonCreds credentials to be exchanged in the Issue Credential and Present Proof protocols, which is explained in the [Manually Register AnonCreds Support in Credentials and Proofs Modules](#manually-register-anoncreds-support-in-credentials-and-proofs-modules) section. + +There's a few important takeaways based on the code example below: + +- The `anoncreds` module can be accessed under the `agent.modules.anoncreds` property. +- The interfaces are set up as generically as possible based on the [DID Registration](https://identity.foundation/did-registration/) and [DID Resolution](https://w3c-ccg.github.io/did-resolution/) specifications. +- AnonCreds registries need to be manually registered so it's important to register the `IndySdkAnonCredsRegistry` on the `AnonCredsModule`. +- It is now required to pass an `issuerId` when registering AnonCreds objects, according to the [AnonCreds Specification](https://hyperledger.github.io/anoncreds-spec/). Only `did:indy` issuer identifiers are allowed (based on the [`did:indy` AnonCreds Method](https://hyperledger.github.io/anoncreds-methods-registry/#didindy-anoncreds-method)), so the network can be inferred from the issuer identifier. + +As will be explained in the [Manually Register AnonCreds Support in Credentials and Proofs Modules](#manually-register-anoncreds-support-in-credentials-and-proofs-modules), you can still use the unqualified issuer identifiers (best known as the [Hyperledger Indy Legacy AnonCreds Method](https://hyperledger.github.io/anoncreds-methods-registry/#hyperledger-indy-legacy-anoncreds-method)) in credential and proof exchanges. + + + +##### 0.3.x + +```ts +import { Agent } from '@aries-framework/core' + +// Import from @aries-framework/react-native in React Native +import { agentDependencies } from '@aries-framework/node' + +const agent = new Agent({ + config: { + /* ... */ + publicDidSeed: '01eafa4de4e22ed4fc2ee522b6ce2731', + indyLedgers: [ + { + id: 'Sovrin Mainnet', + indyNamespace: 'sovrin', + isProduction: true, + genesisPath: './genesis/sovrin-genesis.txn', + }, + ], + }, + dependencies: agentDependencies, +}) + +await agent.initialize() + +const schema = await agent.ledger.registerSchema({ + attributes: ['name'], + name: 'Example Schema', + version: '1.0.1', +}) + +const credentialDefinition = await agent.ledger.registerCredentialDefinition({ + schema, + supportRevocation: false, + tag: 'default', +}) +``` + +##### 0.4.x + +```ts +import { AnonCredsModule } from '@aries-framework/anoncreds' +import { Agent, DidsModule, KeyType, TypedArrayEncoder } from '@aries-framework/core' +import { IndySdkAnonCredsRegistry, IndySdkModule, IndySdkIndyDidResolver } from '@aries-framework/indy-sdk' + +// Import from @aries-framework/react-native in React Native +import { agentDependencies } from '@aries-framework/node' + +// Import from indy-sdk-react-native in React Native +import indySdk from 'indy-sdk' + +const agent = new Agent({ + config: { + /* ... */ + }, + dependencies: agentDependencies, + modules: { + indySdk: new IndySdkModule({ + indySdk, + networks: [ + { + id: 'Sovrin Mainnet', + indyNamespace: 'sovrin', + isProduction: true, + genesisPath: './genesis/sovrin-genesis.txn', + }, + ], + }), + // Important: register the IndySdkAnonCredsRegistry so that the anoncreds module can resolver/register anoncreds objects based on the networks configured in the IndySdkModule + anoncreds: new AnonCredsModule({ + registries: [new IndySdkAnonCredsRegistry()], + }), + // Important: register the IndySdkIndyDidResolver so that the anoncreds module can resolve DIDs based on the networks configured in the IndySdkModule + dids: new DidsModule({ + resolvers: [new IndySdkIndyDidResolver()], + }), + }, +}) + +// Agent MUST be initialized before the anoncreds module can be used +await agent.initialize() + +// Important: the issuerId (did) MUST be available to the dids module in the agent. You can either create the did using the dids module, or import it as described in this migration guide. +const schemaResult = await agent.modules.anoncreds.registerSchema({ + schema: { + attrNames: ['name'], + issuerId: 'did:indy:sovrin:KEPUoXHcswsfsHkXGfmXB7', + name: 'Example Schema', + version: '1.0.0', + }, + options: {}, +}) + +// The resolver and registrar follow the same pattern as the Did Registration +// and Did Resolver interfaces as used by the did module. +if (schemaResult.schemaState.state !== 'finished') { + console.error(schemaResult) + throw new Error(`Error creating schema`) +} + +const credentialDefinitionResult = await agent.modules.anoncreds.registerCredentialDefinition({ + credentialDefinition: { + issuerId: 'did:indy:sovrin:KEPUoXHcswsfsHkXGfmXB7', + schemaId: schemaResult.schemaState.schemaId, + tag: 'default', + }, + options: {}, +}) +``` + + + +### Changes to the Credentials and Proofs modules + +A lot of small, and some bigger changes have been made to the Credentials, and primarily, the Proofs modules. These changes have been made to make the modules more consistent and generic so that they can be used in a wider range of use cases, removing any focus on AnonCreds and Indy credentials. + +Changes to the Proofs module include: + +- `getRequestedCredentialsForProofRequest` has been renamed to `getCredentialsForRequest` +- `autoSelectCredentialsForProofRequest` has been renamed to `selectCredentialsForRequest` +- The `config` parameter for both methods has been removed and those have been replaced by proof format specific configuration options. In this case, the `config.filterByNonRevocationRequirements` has been added as `proofFormats.indy.filterByNonRevocationRequirements` (if the `indy` format is registered as explained in the next section). The `config.filterByPresentationPreview` has been removed as the presentation preview was only present in the present proof V1 protocol, and due to it's limited applicability (the holder starts with a proposal) we've decided to remove this method for now. You can still filter the credentials yourself by using the `getCredentialsForRequest` method. +- Interfaces have been renamed to be more consistent with the method names. Please refer to the [`CredentialsApiOptions`](https://github.com/hyperledger/aries-framework-javascript/blob/v0.4.0/packages/core/src/modules/credentials/CredentialsApiOptions.ts) and [`ProofsApiOptions`](https://github.com/hyperledger/aries-framework-javascript/blob/v0.4.0/packages/core/src/modules/proofs/ProofsApiOptions.ts) for the interface names that can be imported. + +If you encounter any other breaking changes in the Proofs and Credentials modules, please open an issue in the [Aries JavaScript Docs](https://github.com/hyperledger/aries-javascript-docs) repository. + +### Changes to the AnonCreds Credential and Proof Format + +With the 0.4.0 release, AFJ now provides a pluggable AnonCreds interface, and requires support AnonCreds credentials to be explicitly registered on the agent. This is also the case for registering the credential and proof formats. + +In 0.3.x, the `IndyProofFormatService` and `IndyCredentialFormatService` were registered by default. In 0.4.x, these services are no longer registered by default and they should be imported from the `@aries-framework/anoncreds` package as `LegacyIndyProofFormatService` and `LegacyIndyCredentialFormatService` and are based on [Aries RFC 0592](https://github.com/hyperledger/aries-rfcs/blob/main/features/0592-indy-attachments/README.md). In a future version the new `AnonCredsCredentialFormatService` and `AnonCredsProofFormatService` will be added to the AnonCreds package, which are based on [Aries RFC 0771](https://github.com/hyperledger/aries-rfcs/pull/771) and allow for AnonCreds credentials to be exchanged based on the new ledger agnostic [AnonCreds Specification](https://hyperledger.github.io/anoncreds-spec/). + +In addition, the `V1CredentialProtocol` and `V1ProofProtocol` have been extracted into the `@aries-framework/anoncreds` package, as they only support exchange of (legacy Indy) AnonCreds credentials. + + + +##### 0.3.x + +```ts +import { Agent } from '@aries-framework/core' + +// Import from @aries-framework/react-native in React Native +import { agentDependencies } from '@aries-framework/node' + +const agent = new Agent({ + config: { + /* ... */ + indyLedgers: [ + { + id: 'Sovrin Mainnet', + indyNamespace: 'sovrin', + isProduction: true, + genesisPath: './genesis/sovrin-genesis.txn', + }, + ], + }, + dependencies: agentDependencies, +}) +``` + +##### 0.4.x + +```ts +import { + AnonCredsModule, + LegacyIndyCredentialFormatService, + LegacyIndyProofFormatService, + V1CredentialProtocol, + V1ProofProtocol, +} from '@aries-framework/anoncreds' +import { Agent, CredentialsModule, ProofsModule, V2CredentialProtocol, V2ProofProtocol } from '@aries-framework/core' +import { IndySdkAnonCredsRegistry, IndySdkModule } from '@aries-framework/indy-sdk' + +// Import from @aries-framework/react-native in React Native +import { agentDependencies } from '@aries-framework/node' + +// Import from indy-sdk-react-native in React Native +import indySdk from 'indy-sdk' + +const legacyIndyCredentialFormat = new LegacyIndyCredentialFormatService() +const legacyIndyProofFormat = new LegacyIndyProofFormatService() + +const agent = new Agent({ + config: { + /* ... */ + }, + dependencies: agentDependencies, + modules: { + indySdk: new IndySdkModule({ + indySdk, + networks: [ + { + id: 'Sovrin Mainnet', + indyNamespace: 'sovrin', + isProduction: true, + genesisPath: './genesis/sovrin-genesis.txn', + }, + ], + }), + // Important: the AnonCreds module MUST be registered with a registry that can resolve + // legacy unqualified Indy anoncreds identifiers + anoncreds: new AnonCredsModule({ + registries: [new IndySdkAnonCredsRegistry()], + }), + // Define the proofs module with support for both v1 and v2 of the proof protocols + // both of which support the legacy Indy proof format + proofs: new ProofsModule({ + proofProtocols: [ + new V1ProofProtocol({ + indyProofFormat: legacyIndyProofFormat, + }), + new V2ProofProtocol({ + proofFormats: [legacyIndyProofFormat], + }), + ], + }), + // Define the credentials module with support for both v1 and v2 of the credential protocols + // both of which support the legacy Indy proof format + credentials: new CredentialsModule({ + credentialProtocols: [ + new V1CredentialProtocol({ + indyCredentialFormat: legacyIndyCredentialFormat, + }), + new V2CredentialProtocol({ + credentialFormats: [legacyIndyCredentialFormat], + }), + ], + }), + }, +}) +``` + + + +### Removal of AnonCreds Master Secret management from `Wallet` + +The `Wallet` class no longer manages the creation and deletion of AnonCreds master secrets (which are now called Link Secrets in AnonCreds module and specification). If you haven't provided a custom `masterSecretId` to the `walletConfig` before, the storage migration script should have automatically created an `AnonCredsLinkSecretRecord` for you based on the `walletConfig.id`. + +For new agents however, you now need to explicitly create a link secret before you can create requests for AnonCreds credential offers. You can do this using the `AnonCredsApi.createLinkSecret` method. + +:::caution + +If you previously used a custom `masterSecretId` in the `walletConfig` the migration script will have created an incorrect `AnonCredsLinkSecretRecord` based on the `walletConfig.id`. You will need to manually override the link secret record with the correct `linkSecretId`. + +You **ONLY** need to do this if you're not migrating from Indy SDK to Askar, as in that case the migration script will have created the correct `AnonCredsLinkSecretRecord` for you. + +```ts +import { AnonCredsLinkSecretRepository } from '@aries-framework/anoncreds' + +const linkSecretRepository = agent.dependencyManager.resolve(AnonCredsLinkSecretRepository) +const defaultLinkSecret = await linkSecretRepository.findDefault(agent.context) + +if (defaultLinkSecret) { + defaultLinkSecret.linkSecretId = 'my-custom-link-secret-id' + await linkSecretRepository.update(agent.context, defaultLinkSecret) +} +``` + +::: + +```ts +import { AnonCredsModule } from '@aries-framework/anoncreds' +import { Agent } from '@aries-framework/core' +import { IndySdkAnonCredsRegistry, IndySdkModule } from '@aries-framework/indy-sdk' + +// Import from @aries-framework/react-native in React Native +import { agentDependencies } from '@aries-framework/node' + +// Import from indy-sdk-react-native in React Native +import indySdk from 'indy-sdk' + +const agent = new Agent({ + config: { + /* ... */ + }, + dependencies: agentDependencies, + modules: { + indySdk: new IndySdkModule({ + indySdk, + }), + anoncreds: new AnonCredsModule({ + registries: [new IndySdkAnonCredsRegistry()], + }), + }, +}) + +// the agent MUST be initialized before calling it. +await agent.wallet.initialize({ + id: 'wallet-id', + key: 'wallet-key', +}) + +await agent.modules.anoncreds.createLinkSecret({ + // first one will be set to default automatically + setAsDefault: true, + + // will be generated if not provided. + // linkSecretId: 'link-secret-id' +}) +``` + +### Default Outbound DIDComm Content Type now `application/didcomm-envelope-enc` + +The default outbound DIDComm content type has been changed from `DidCommMimeType.V0` (`application/ssi-agent-wire`) to `DidCommMimeType.V1` (`application/didcomm-envelope-enc`). V1 is the default for DIDComm V1 (as [defined in Aries RFC 0044](https://github.com/hyperledger/aries-rfcs/blob/main/features/0044-didcomm-file-and-mime-types/README.md#detecting-didcomm-versions)). In the past, V0 resulted in better interoperability, but since it has been the default for so long it makes sense to change the default behavior. + +It is advised to use the default value as configured by the agent (V1). If you want to keep the old behavior, you can [configure the `didCommMimeType` property in the agent configuration](/guides/tutorials/agent-config#didcommmimetype). + + + +##### 0.3.x + +```ts +import { Agent } from '@aries-framework/core' + +// Import from @aries-framework/react-native in React Native +import { agentDependencies } from '@aries-framework/node' + +const agent = new Agent({ + config: { + /* ... */ + }, + dependencies: agentDependencies, +}) +``` + +##### 0.4.x + +```ts +import { Agent, DidCommMimeType } from '@aries-framework/core' + +// Import from @aries-framework/react-native in React Native +import { agentDependencies } from '@aries-framework/node' + +const agent = new Agent({ + config: { + didCommMimeType: DidCommMimeType.V0, + }, + dependencies: agentDependencies, +}) +``` + + + +### Generalizing Indy properties in `CredentialExchangeRecord` + +With AnonCreds credentials now being generalized to support multiple ledgers, the properties specific to Hyperledger Indy have now been generalized into a generic AnonCreds properties. + +#### `credentialRecordType` + +First off, the `credentialRecordType` that was used to reference stored AnonCreds credentials has been renamed from `indy` to `anoncreds`. The migration script takes care of the update to the storage, but you need to make sure to update all places that expect a `credentialRecordType` of `indy` to be defined. + + + +##### 0.3.x + +```json title="CredentialExchangeRecord" +{ + "credentials": [ + { + "credentialRecordType": "indy", + "credentialRecordId": "credential-id" + } + ] +} +``` + +##### 0.4.x + +```json title="CredentialExchangeRecord" +{ + "credentials": [ + { + "credentialRecordType": "anoncreds", + "credentialRecordId": "credential-id" + } + ] +} +``` + + + +#### Metadata + +Second, the metadata keys and values have been renamed to be AnonCreds specific rather than Indy specific. The `CredentialMetadataKeys` have been replaced by the `AnonCredsCredentialMetadataKey` and `AnonCredsCredentialRequestMetadataKey` constants which can be imported from the `@aries-framework/anoncreds` package. + + + +##### 0.3.x + +```json title="CredentialExchangeRecord" +{ + "metadata": { + "_internal/indyCredential": { + "schemaId": "schema-id", + "credentialDefinitionId": "cred-def-id", + "indyRevocationRegistryId": "rev-reg-id", + "indyCredentialRevocationId": "cred-rev-id" + }, + "_internal/indyRequest": { + "master_secret_blinding_data": { + "v_prime": "string", + "vr_prime": "string" + }, + "master_secret_name": "string", + "nonce": "string" + } + } +} +``` + +##### 0.4.x + +```json title="CredentialExchangeRecord" +{ + "metadata": { + "_anoncreds/credential": { + "schemaId": "schema-id", + "credentialDefinitionId": "cred-def-id", + "revocationRegistryId": "rev-reg-id", + "credentialRevocationId": "cred-rev-id" + }, + "_anoncreds/credentialRequest": { + "master_secret_blinding_data": { + "v_prime": "string", + "vr_prime": "string" + }, + "master_secret_name": "string", + "nonce": "string" + } + } +} +``` + + + +### More paths in `FileSystem` + +The `FileSystem` interface has been extended to support multiple base paths. The previous interface had a single `basePath` property which was used for storing of files across the framework. + +With the different lifetimes of different objects, the `FileSystem` interface has been extended to now support three different base paths: + +- `cachePath` - files used for caching purposes. It's okay if the files are cleared from time to time. +- `dataPath` - files that are used for long-term reliable storage purposes. These files will never be cleared. +- `tempPath` - files that are used for temporary storage purposes. It's okay if the files are cleared from time to time. + +If you're using the framework, you don't need to worry about this change. The agent may need to download some objects again after the update. If you've made a custom implementation of the `FileSystem`, make sure to support all three base paths, and make sure to correctly handle the life-cycle of the files. Items stored under the `dataPath` **should never be cleared**. + +:::caution + +Indy SDK SQLite wallets do not use the paths defined by the `FileSystem` interface, and thus will not be influenced by this change. When upgrading to Aries Askar, the `dataPath` will be used as the base path for storing the SQLite wallet data. + +::: + +## Breaking Storage Changes + +The 0.4.0 release introduces some breaking changes to the storage format. + +Below all breaking storage changes are explained in as much detail as possible. The update assistant provides all tools to migrate without a hassle, but it is important to know what has changed. All examples only show the keys that have changed, unrelated keys in records have been omitted. + +See the [Update Assistant](/guides/updating/update-assistant.md) documentation for a guide on how to use the update assistant. + +There are no configuration parameters to be provided to the update assistant to migrate from 0.3.x to 0.4.x. + +> TODO diff --git a/versioned_sidebars/version-0.4-sidebars.json b/versioned_sidebars/version-0.4-sidebars.json new file mode 100644 index 00000000..5faacdc5 --- /dev/null +++ b/versioned_sidebars/version-0.4-sidebars.json @@ -0,0 +1,137 @@ +{ + "tutorialSidebar": [ + "index", + { + "type": "category", + "label": "Getting started", + "link": { + "type": "doc", + "id": "getting-started/index" + }, + "items": [ + "getting-started/prerequisites", + { + "type": "category", + "label": "Agent Setup", + "link": { + "type": "doc", + "id": "getting-started/set-up/index" + }, + "items": [ + "getting-started/set-up/aries-askar", + { + "type": "category", + "label": "Indy SDK", + "link": { + "type": "doc", + "id": "getting-started/set-up/indy-sdk/index" + }, + "items": [ + "getting-started/set-up/indy-sdk/linux", + "getting-started/set-up/indy-sdk/windows", + "getting-started/set-up/indy-sdk/macos-intel", + "getting-started/set-up/indy-sdk/macos-arm", + "getting-started/set-up/indy-sdk/react-native" + ] + }, + "getting-started/set-up/anoncreds-rs", + "getting-started/set-up/indy-vdr", + "getting-started/set-up/cheqd/index" + ] + } + ] + }, + { + "type": "category", + "label": "Concepts", + "link": { + "type": "doc", + "id": "concepts/index" + }, + "items": ["concepts/agents", "concepts/did-and-didcomm", "concepts/platform-and-environment"] + }, + { + "type": "category", + "label": "Tutorials", + "link": { + "type": "doc", + "id": "tutorials/index" + }, + "items": [ + { + "type": "category", + "label": "Agent Config", + "link": { + "type": "doc", + "id": "tutorials/agent-config/index" + }, + "items": ["tutorials/agent-config/logging"] + }, + "tutorials/create-a-connection", + "tutorials/cheqd/index", + "tutorials/registering-schema-and-credential-definition", + "tutorials/issue-a-credential", + "tutorials/mediation", + { + "type": "category", + "label": "Using PostgreSQL with the Indy SDK", + "link": { + "type": "doc", + "id": "tutorials/indy-sdk-postgres-database-nodejs/index" + }, + "items": [ + "tutorials/indy-sdk-postgres-database-nodejs/linux", + "tutorials/indy-sdk-postgres-database-nodejs/macos", + "tutorials/indy-sdk-postgres-database-nodejs/windows" + ] + } + ] + }, + { + "type": "category", + "label": "Updating", + "link": { + "type": "doc", + "id": "updating/index" + }, + "items": [ + "updating/update-assistant", + "updating/update-indy-sdk-to-askar", + "updating/versions/0.1-to-0.2", + "updating/versions/0.2-to-0.3", + "updating/versions/0.3-to-0.4" + ] + }, + "ecosystem/index", + { + "type": "category", + "label": "Extensions", + "link": { + "type": "doc", + "id": "extensions/index" + }, + "items": [ + { + "type": "doc", + "label": "REST API", + "id": "extensions/rest" + }, + { + "type": "doc", + "label": "React Hooks", + "id": "extensions/react-hooks" + }, + { + "type": "doc", + "label": "Redux Store", + "id": "extensions/redux-store" + }, + { + "type": "doc", + "label": "Push Notifications", + "id": "extensions/push-notifications" + } + ] + } + ] +} diff --git a/versions.json b/versions.json index 325c996e..78759abb 100644 --- a/versions.json +++ b/versions.json @@ -1 +1 @@ -["0.3"] +["0.4", "0.3"]