forked from openwallet-foundation/acapy-plugins
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: plugin for cheqd method support (openwallet-foundation#1307)
* 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
1 parent
d5ac7e1
commit e340f94
Showing
53 changed files
with
11,144 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 . |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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.
Oops, something went wrong.