Skip to content

Commit

Permalink
feat: plugin for cheqd method support (openwallet-foundation#1307)
Browse files Browse the repository at this point in the history
* feat: plugin for did:cheqd method support

Signed-off-by: Sownak Roy <[email protected]>

* * Plugin support

Signed-off-by: Sownak Roy <[email protected]>

* feat: Add anoncreds issuance support for did:cheqd

Signed-off-by: DaevMithran <[email protected]>

* Add unit and integration tests

Signed-off-by: Radosław Kamiński <[email protected]>

* fixed tests and added postman collection

Signed-off-by: Sownak Roy <[email protected]>

* Add get_schema_info

Signed-off-by: DaevMithran <[email protected]>

* DCO Remediation Commit for DaevMithran <[email protected]>

I, DaevMithran <[email protected]>, hereby add my Signed-off-by to this commit: ef1ec51
I, DaevMithran <[email protected]>, hereby add my Signed-off-by to this commit: a22c710

Signed-off-by: DaevMithran <[email protected]>
---------

Signed-off-by: Sownak Roy <[email protected]>
Signed-off-by: DaevMithran <[email protected]>
Signed-off-by: DaevMithran <[email protected]>
Co-authored-by: DaevMithran <[email protected]>
Co-authored-by: Radoslaw Kaminski <[email protected]>
Co-authored-by: Radosław Kamiński <[email protected]>
Co-authored-by: DaevMithran <[email protected]>

* Renamed files as per review comment

Signed-off-by: Sownak Roy <[email protected]>

---------

Signed-off-by: Sownak Roy <[email protected]>
Signed-off-by: DaevMithran <[email protected]>
Signed-off-by: DaevMithran <[email protected]>
Co-authored-by: DaevMithran <[email protected]>
Co-authored-by: Radoslaw Kaminski <[email protected]>
Co-authored-by: Radosław Kamiński <[email protected]>
Co-authored-by: DaevMithran <[email protected]>
  • Loading branch information
5 people authored Dec 24, 2024
1 parent d5ac7e1 commit e340f94
Show file tree
Hide file tree
Showing 53 changed files with 11,144 additions and 0 deletions.
21 changes: 21 additions & 0 deletions cheqd/.devcontainer/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# See here for image contents: https://github.com/microsoft/vscode-dev-containers/tree/v0.134.0/containers/python-3/.devcontainer/base.Dockerfile
ARG VARIANT="3.12"
FROM mcr.microsoft.com/devcontainers/python:${VARIANT}

ARG POETRY_VERSION="1.8.3"
ENV POETRY_HOME="/opt/poetry" \
POETRY_VERSION=${POETRY_VERSION}

RUN curl -sSL https://install.python-poetry.org | python3 - \
&& update-alternatives --install /usr/local/bin/poetry poetry /opt/poetry/bin/poetry 900 \
# Enable tab completion for bash
&& poetry completions bash >> /home/vscode/.bash_completion \
# Enable tab completion for Zsh
&& mkdir -p /home/vscode/.zfunc/ \
&& poetry completions zsh > /home/vscode/.zfunc/_poetry \
&& echo "fpath+=~/.zfunc\nautoload -Uz compinit && compinit" >> /home/vscode/.zshrc

COPY pyproject.toml poetry.lock ./
RUN poetry config virtualenvs.create false \
&& poetry install --no-root --no-interaction --with integration --extras "aca-py" \
&& rm -rf /root/.cache/pypoetry
58 changes: 58 additions & 0 deletions cheqd/.devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
// README at: https://github.com/devcontainers/templates/tree/main/src/python
{
"name": "cheqd",
"build": {
"dockerfile": "Dockerfile",
"context": "..",
"args": {
"VARIANT": "3.12-bullseye",
"POETRY_VERSION": "1.8.3"
}
},
"customizations": {
"vscode": {
"extensions": ["ms-python.python", "ms-python.vscode-pylance", "charliermarsh.ruff"],
"settings": {
"python.testing.pytestArgs": ["./cheqd", "--no-cov"],
"python.testing.unittestEnabled": false,
"python.testing.pytestEnabled": true,
"python.testing.pytestPath": "pytest",
"python.linting.enabled": true,
"python.linting.pylintEnabled": false,
"editor.defaultFormatter": null,
"editor.formatOnSave": false, // enable per language
"[python]": {
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.fixAll": "always",
"source.organizeImports": "always"
},
"python.linting.ruffEnabled": true,
"editor.defaultFormatter": "charliermarsh.ruff",
"ruff.organizeImports": true
},
"ruff.codeAction.fixViolation": {
"enable": true
},
"ruff.fixAll": true,
"ruff.format.args": ["--config=./pyproject.toml"],
"ruff.lint.args": ["--config=./pyproject.toml"]
}
}
},
"features": {
"ghcr.io/devcontainers/features/docker-in-docker:2": {
"moby": false
}
},
// Comment out to connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root.
"remoteUser": "vscode",
"remoteEnv": {
"RUST_LOG": "aries-askar::log::target=error"
},
"mounts": [],
// Use 'forwardPorts' to make a list of ports inside the container available locally.
"forwardPorts": [8020, 8021, 5432, 8080, 3000],
"postCreateCommand": "bash ./.devcontainer/post-install.sh"
}
14 changes: 14 additions & 0 deletions cheqd/.devcontainer/post-install.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#!/bin/bash
set -ex

# Convenience workspace directory for later use
WORKSPACE_DIR=$(pwd)

# install all ACA-Py requirements
python -m pip install --upgrade pip

# install black and ruff for formatting
pip install black ruff

# install this plugin
pip install -e .
119 changes: 119 additions & 0 deletions cheqd/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
# did:cheqd Plugin

## Description

This plugin contains the components needed for ACA-Py to use [did:cheqd](https://cheqd.io) method for did creation and Anoncreds issuance, presentation and revocation. It also contains the Base class definitions for `DIDRegistrar` and `DIDManager`.

### Operations

The did:cheqd Manager plugin supports following new endpoints:

1. POST /did/cheqd/create
1. POST /did/cheqd/update
1. POST /did/cheqd/deactivate

The did:cheqd Manager plugin supports `did:cheqd` for the following existing endpoints:

1. POST /anoncreds/schema
1. POST /anoncreds/credential-definition
1. POST /anoncreds/revocation/revoke
1. GET /resolver/resolve/{did}
1. GET /wallet/did
1. GET /wallet/did/public

## Developer Notes

The best way to develop and test this plugin is to use the DevContainer configured in this repository (configurations provided in the `.devcontainer` folder).

- Open devcontainer in VS Code.
- Python and all dependencies will be loaded.
- Poetry will be loaded and configured, dependencies will be installed.
- Docker and Docker Compose will be available.

## Configuration

- The plugin expects a DID Registrar and a DID Resolver URL to be provided. It is recommended that the registrar and resolver are run locally. The URLs can be passed via `plugin-config.yml`.
- The plugin works only with `askar-anoncreds` wallet type.
- Using a Postgres DB as wallet storage type is also recommended.

### Running with the configuration

An example configuration for the plugin can be found in [default.yml](./docker/default.yml)

#### Pre-requisites
```bash
# Install the plugin locally
pip install -e .

# If using local Cheqd DID registrar, set the environment variables
export FEE_PAYER_TESTNET_MNEMONIC="..."
export FEE_PAYER_MAINNET_MNEMONIC="..."
# start the registrar, resolver and postgres-db services locally, if needed
docker-compose -f ./docker/docker-compose.yml up -d

# For first time only, provision the wallet
aca-py provision --arg-file ./docker/provision.yml
```

#### Running the plugin

- If you are using your own DID registrar and resolver, update the urls in [plugin-config.yml](./docker/plugin-config.yml) file.

```bash
# Then start with same wallet config
aca-py start --arg-file ./docker/default.yml
```

## Testing

### Unit Tests

```bash
# Run the tests using following
poetry run pytest
```
A coverage report is created when ran from the devcontainer.

### Integration Tests

All integrations tests and configurations are in `integration` folder.
To run the integration tests:

```shell
cd integration
./run_integration_tests.sh
```

## Deploy

For production use, this plugin should be installed as libraries to an ACA-Py image.

This requires having a Dockerfile and a config file for your agent.

Example Dockerfile:

```Dockerfile
FROM ghcr.io/openwallet-foundation/acapy:py3.12-1.1.0

USER root

# install plugins as binaries
RUN pip install git+https://github.com/openwallet-foundation/acapy-plugins@main#subdirectory=cheqd

USER $user
COPY ./configs configs

ENTRYPOINT ["aca-py"]

```

An example config file is provided [here](./docker/default.yml).

Now you can deploy a agent with as many plugins as you want as long as they are declared in your build config file and installed.

``` bash

docker build -f <Dockerfile> --tag cheqd .
docker run -it -p 8020:8020 -p 8021:8021 --rm cheqd start --arg-file=<config-file> -->

```
Empty file added cheqd/__init__.py
Empty file.
50 changes: 50 additions & 0 deletions cheqd/cheqd/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import logging

from acapy_agent.anoncreds.registry import AnonCredsRegistry
from acapy_agent.config.injection_context import InjectionContext
from acapy_agent.config.provider import ClassProvider
from acapy_agent.resolver.did_resolver import DIDResolver
from acapy_agent.wallet.did_method import DIDMethods

from .did_method import CHEQD
from .resolver.resolver import CheqdDIDResolver

LOGGER = logging.getLogger(__name__)


async def setup(context: InjectionContext):
"""Setup the plugin."""

LOGGER.info("< cheqd plugin setup...")
config = context.settings.get("plugin_config")
resolver_url = None
registrar_url = None
if config:
resolver_url = config.get("resolver_url")
registrar_url = config.get("registrar_url")

# Register Cheqd DID Resolver
resolver_registry = context.inject_or(DIDResolver)
if not resolver_registry:
LOGGER.warning("No DID Resolver instance found in context")
return
resolver_registry.register_resolver(CheqdDIDResolver(resolver_url))

# Register Anoncreds provider
anoncreds_registry = context.inject_or(AnonCredsRegistry)
if not anoncreds_registry:
LOGGER.warning("No Anoncreds Registry instance found in context")
return
cheqd_registry = ClassProvider(
"cheqd.anoncreds.registry.DIDCheqdRegistry",
# supported_identifiers=[],
# method_name="did:cheqd",
).provide(context.settings, context.injector)
await cheqd_registry.setup(context, registrar_url, resolver_url)
anoncreds_registry.register(cheqd_registry)

# Register Cheqd DID Method
did_methods = context.inject_or(DIDMethods)
did_methods.register(CHEQD)

LOGGER.info("< cheqd plugin setup.")
Empty file.
Loading

0 comments on commit e340f94

Please sign in to comment.