{"id":28920149,"url":"https://github.com/hyperledger-identus/neoprism","last_synced_at":"2026-02-05T11:01:22.956Z","repository":{"id":183096218,"uuid":"632010434","full_name":"hyperledger-identus/neoprism","owner":"hyperledger-identus","description":"The new PRISM node and VDR indexer with lesson learned","archived":false,"fork":false,"pushed_at":"2026-01-29T17:30:31.000Z","size":4523,"stargazers_count":12,"open_issues_count":13,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-01-29T22:22:07.681Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://hyperledger-identus.github.io/neoprism/","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/hyperledger-identus.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2023-04-24T14:21:04.000Z","updated_at":"2026-01-29T07:02:07.000Z","dependencies_parsed_at":"2024-09-10T19:11:35.197Z","dependency_job_id":"3d229de3-b444-4f9e-a96a-e129b81f1433","html_url":"https://github.com/hyperledger-identus/neoprism","commit_stats":null,"previous_names":["patextreme/prism-rs","hyperledger-identus/neoprism"],"tags_count":16,"template":false,"template_full_name":null,"purl":"pkg:github/hyperledger-identus/neoprism","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hyperledger-identus%2Fneoprism","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hyperledger-identus%2Fneoprism/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hyperledger-identus%2Fneoprism/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hyperledger-identus%2Fneoprism/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hyperledger-identus","download_url":"https://codeload.github.com/hyperledger-identus/neoprism/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hyperledger-identus%2Fneoprism/sbom","scorecard":{"id":1240168,"data":{"date":"2025-12-03T13:35:24Z","repo":{"name":"github.com/hyperledger-identus/neoprism","commit":"2aa3e37050e17399931b6302fea86ca8a88762f5"},"scorecard":{"version":"v5.1.1","commit":"cd152cb6742c5b8f2f3d2b5193b41d9c50905198"},"score":5.7,"checks":[{"name":"Maintained","score":10,"reason":"30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/cd152cb6742c5b8f2f3d2b5193b41d9c50905198/docs/checks.md#maintained"}},{"name":"Dependency-Update-Tool","score":10,"reason":"update tool detected","details":["Info: detected update tool: scala-steward: .scala-steward.conf:1"],"documentation":{"short":"Determines if the project uses a dependency update tool.","url":"https://github.com/ossf/scorecard/blob/cd152cb6742c5b8f2f3d2b5193b41d9c50905198/docs/checks.md#dependency-update-tool"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/checks.yml:1","Warn: no topLevel permission defined: .github/workflows/conformance-test.yml:1","Warn: no topLevel permission defined: .github/workflows/deploy-docs.yml:1","Info: topLevel 'pull-requests' permission set to 'read': .github/workflows/pr-lint.yml:11","Warn: no topLevel permission defined: .github/workflows/release.yml:1","Warn: topLevel 'contents' permission set to 'write': .github/workflows/scala-steward.yml:9","Info: topLevel permissions set to 'read-all': .github/workflows/scorecard.yml:18","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/cd152cb6742c5b8f2f3d2b5193b41d9c50905198/docs/checks.md#token-permissions"}},{"name":"Code-Review","score":3,"reason":"Found 11/30 approved changesets -- score normalized to 3","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/cd152cb6742c5b8f2f3d2b5193b41d9c50905198/docs/checks.md#code-review"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/cd152cb6742c5b8f2f3d2b5193b41d9c50905198/docs/checks.md#dangerous-workflow"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/cd152cb6742c5b8f2f3d2b5193b41d9c50905198/docs/checks.md#binary-artifacts"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/checks.yml:37: update your workflow using https://app.stepsecurity.io/secureworkflow/hyperledger-identus/neoprism/checks.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/checks.yml:40: update your workflow using https://app.stepsecurity.io/secureworkflow/hyperledger-identus/neoprism/checks.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/checks.yml:21: update your workflow using https://app.stepsecurity.io/secureworkflow/hyperledger-identus/neoprism/checks.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/checks.yml:24: update your workflow using https://app.stepsecurity.io/secureworkflow/hyperledger-identus/neoprism/checks.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/conformance-test.yml:23: update your workflow using https://app.stepsecurity.io/secureworkflow/hyperledger-identus/neoprism/conformance-test.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/conformance-test.yml:26: update your workflow using https://app.stepsecurity.io/secureworkflow/hyperledger-identus/neoprism/conformance-test.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/conformance-test.yml:32: update your workflow using https://app.stepsecurity.io/secureworkflow/hyperledger-identus/neoprism/conformance-test.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/conformance-test.yml:35: update your workflow using https://app.stepsecurity.io/secureworkflow/hyperledger-identus/neoprism/conformance-test.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/conformance-test.yml:46: update your workflow using https://app.stepsecurity.io/secureworkflow/hyperledger-identus/neoprism/conformance-test.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/deploy-docs.yml:14: update your workflow using https://app.stepsecurity.io/secureworkflow/hyperledger-identus/neoprism/deploy-docs.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/deploy-docs.yml:17: update your workflow using https://app.stepsecurity.io/secureworkflow/hyperledger-identus/neoprism/deploy-docs.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/deploy-docs.yml:23: update your workflow using https://app.stepsecurity.io/secureworkflow/hyperledger-identus/neoprism/deploy-docs.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/pr-lint.yml:18: update your workflow using https://app.stepsecurity.io/secureworkflow/hyperledger-identus/neoprism/pr-lint.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:20: update your workflow using https://app.stepsecurity.io/secureworkflow/hyperledger-identus/neoprism/release.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/release.yml:25: update your workflow using https://app.stepsecurity.io/secureworkflow/hyperledger-identus/neoprism/release.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/release.yml:31: update your workflow using https://app.stepsecurity.io/secureworkflow/hyperledger-identus/neoprism/release.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/release.yml:34: update your workflow using https://app.stepsecurity.io/secureworkflow/hyperledger-identus/neoprism/release.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/scala-steward.yml:19: update your workflow using https://app.stepsecurity.io/secureworkflow/hyperledger-identus/neoprism/scala-steward.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/scala-steward.yml:22: update your workflow using https://app.stepsecurity.io/secureworkflow/hyperledger-identus/neoprism/scala-steward.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/scala-steward.yml:28: update your workflow using https://app.stepsecurity.io/secureworkflow/hyperledger-identus/neoprism/scala-steward.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/scala-steward.yml:46: update your workflow using https://app.stepsecurity.io/secureworkflow/hyperledger-identus/neoprism/scala-steward.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/scorecard.yml:76: update your workflow using https://app.stepsecurity.io/secureworkflow/hyperledger-identus/neoprism/scorecard.yml/main?enable=pin","Info:   2 out of  10 GitHub-owned GitHubAction dependencies pinned","Info:   1 out of  15 third-party GitHubAction dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/cd152cb6742c5b8f2f3d2b5193b41d9c50905198/docs/checks.md#pinned-dependencies"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/cd152cb6742c5b8f2f3d2b5193b41d9c50905198/docs/checks.md#signed-releases"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/cd152cb6742c5b8f2f3d2b5193b41d9c50905198/docs/checks.md#cii-best-practices"}},{"name":"Vulnerabilities","score":1,"reason":"9 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: RUSTSEC-2021-0139","Warn: Project is vulnerable to: RUSTSEC-2021-0145 / GHSA-g98v-hv3f-hcfr","Warn: Project is vulnerable to: RUSTSEC-2024-0375","Warn: Project is vulnerable to: RUSTSEC-2021-0141","Warn: Project is vulnerable to: RUSTSEC-2020-0016","Warn: Project is vulnerable to: RUSTSEC-2024-0436","Warn: Project is vulnerable to: RUSTSEC-2024-0370","Warn: Project is vulnerable to: RUSTSEC-2023-0071","Warn: Project is vulnerable to: RUSTSEC-2024-0320"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/cd152cb6742c5b8f2f3d2b5193b41d9c50905198/docs/checks.md#vulnerabilities"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 30 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/cd152cb6742c5b8f2f3d2b5193b41d9c50905198/docs/checks.md#sast"}},{"name":"Packaging","score":10,"reason":"packaging workflow detected","details":["Info: Project packages its releases by way of GitHub Actions.: .github/workflows/release.yml:11"],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/cd152cb6742c5b8f2f3d2b5193b41d9c50905198/docs/checks.md#packaging"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: Apache License 2.0: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/cd152cb6742c5b8f2f3d2b5193b41d9c50905198/docs/checks.md#license"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/cd152cb6742c5b8f2f3d2b5193b41d9c50905198/docs/checks.md#fuzzing"}},{"name":"Security-Policy","score":10,"reason":"security policy file detected","details":["Info: security policy file detected: github.com/hyperledger-identus/.github/SECURITY.md:1","Info: Found linked content: github.com/hyperledger-identus/.github/SECURITY.md:1","Info: Found disclosure, vulnerability, and/or timelines in security policy: github.com/hyperledger-identus/.github/SECURITY.md:1","Info: Found text in security policy: github.com/hyperledger-identus/.github/SECURITY.md:1"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/cd152cb6742c5b8f2f3d2b5193b41d9c50905198/docs/checks.md#security-policy"}},{"name":"Branch-Protection","score":-1,"reason":"internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration","details":null,"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/cd152cb6742c5b8f2f3d2b5193b41d9c50905198/docs/checks.md#branch-protection"}},{"name":"Contributors","score":3,"reason":"project has 1 contributing companies or organizations -- score normalized to 3","details":["Info: found contributions from: hyperledger-labs"],"documentation":{"short":"Determines if the project has a set of contributors from multiple organizations (e.g., companies).","url":"https://github.com/ossf/scorecard/blob/cd152cb6742c5b8f2f3d2b5193b41d9c50905198/docs/checks.md#contributors"}},{"name":"CI-Tests","score":10,"reason":"30 out of 30 merged PRs checked by a CI test -- score normalized to 10","details":null,"documentation":{"short":"Determines if the project runs tests before pull requests are merged.","url":"https://github.com/ossf/scorecard/blob/cd152cb6742c5b8f2f3d2b5193b41d9c50905198/docs/checks.md#ci-tests"}}]},"last_synced_at":"2025-12-03T13:44:37.553Z","repository_id":183096218,"created_at":"2025-12-03T13:44:37.553Z","updated_at":"2025-12-03T13:44:37.553Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29120481,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-05T10:47:47.471Z","status":"ssl_error","status_checked_at":"2026-02-05T10:45:08.119Z","response_time":65,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-06-22T04:12:23.953Z","updated_at":"2026-02-05T11:01:22.919Z","avatar_url":"https://github.com/hyperledger-identus.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# NeoPRISM\n\n![Rust Edition](https://img.shields.io/badge/edition-2024-blue)\n[![Unit tests](https://github.com/hyperledger-identus/neoprism/actions/workflows/checks.yml/badge.svg)](https://github.com/hyperledger-identus/neoprism/actions)\n[![PRISM tests](https://github.com/hyperledger-identus/neoprism/actions/workflows/conformance-test.yml/badge.svg)](https://github.com/hyperledger-identus/neoprism/actions/workflows/conformance-test.yml)\n[![GitHub release](https://img.shields.io/github/release/hyperledger-identus/neoprism.svg)](https://github.com/hyperledger-identus/neoprism/releases)\n[![GitHub tag](https://img.shields.io/github/tag/hyperledger-identus/neoprism.svg)](https://github.com/hyperledger-identus/neoprism/tags)\n[![License](https://img.shields.io/github/license/hyperledger-identus/neoprism.svg)](./LICENSE)\n[![Docker Pulls](https://img.shields.io/docker/pulls/hyperledgeridentus/identus-neoprism)](https://hub.docker.com/r/hyperledgeridentus/identus-neoprism)\n[![Discord](https://img.shields.io/discord/905194001349627914?label=discord)](https://discord.com/channels/905194001349627914/1230596020790886490)\n\n---\n\n**📚 [Documentation](https://hyperledger-identus.github.io/neoprism/)**\n\n---\n\n# Overview\n\nNeoPRISM is an open-source implementation of a PRISM node, providing a robust and extensible platform for managing [PRISM Decentralized Identifiers (DIDs)](https://www.w3.org/TR/did-core/) anchored on the Cardano blockchain.\n\nA PRISM node continuously monitors the Cardano blockchain for DID operations, validates and indexes them, and enables efficient lookup of DID Documents.\nIt also allows users to create, update, or deactivate DIDs by submitting operations, ensuring all protocol rules and security checks are enforced.\nBy running a PRISM node, organizations and individuals can independently manage and verify DIDs, supporting a decentralized identity system without reliance on a central authority.\n\n## Features\n\n- **🛠️ Multiple Deployment Modes**\n  - Supports three operational modes:\n    - **Indexer:** Resolves and indexes DIDs for verification services.\n    - **Submitter:** Publishes DID operations to the Cardano blockchain.\n    - **Standalone:** Combines indexing and submission capabilities into a single process.\n\n- **🔗 Cardano Data Source Integration**\n  - Ingests DID operations from various Cardano data sources, including [Oura](https://github.com/txpipe/oura), [DBSync](https://github.com/input-output-hk/cardano-db-sync), and [Blockfrost](https://blockfrost.io/).\n\n- **🆔 W3C-Compliant DID Resolution**\n  - Provides a universal-resolver compatible HTTP endpoint.\n  - Resolves PRISM DIDs to DID Documents according to the W3C DID specification.\n\n- **📤 DID Operation Publishing**\n  - Publishes PRISM DID operations to the Cardano blockchain.\n  - Integrates with Cardano-wallet; future support for additional publishing methods.\n\n- **📚 OpenAPI Documentation**\n  - Documents all HTTP endpoints using the OpenAPI specification.\n\n- **🗄️ Verifiable Data Registry (VDR) Support**\n  - Enables reading and writing arbitrary data to the Cardano blockchain using transaction metadata.\n  - Supports indexing and retrieval of data from transaction metadata for verifiable data use cases.\n\n- **🦀 Rust Implementation**\n  - Developed in Rust for efficient resource usage and reliable performance.\n\n## Introduction to PRISM DID\n\nThe [PRISM DID method](https://github.com/input-output-hk/prism-did-method-spec) (`did:prism`) is a protocol for creating and managing Decentralized Identifiers (DIDs) built on the Cardano blockchain.\nThis specification defines the operations, serialization formats, and rules for managing the lifecycle of DIDs and their associated DID documents.\n\nAt its core, PRISM works by encoding identity operations (Create, Update, Deactivate) as Protocol Buffer messages that are signed, batched into blocks, and published as metadata in Cardano transactions.\nPRISM nodes continuously monitor the blockchain, processing these operations to maintain an up-to-date map of DIDs and their states.\nThe method requires a \"secure depth\" of 112 block confirmations before considering operations final.\nDuring this confirmation period, users can leverage long form DIDs immediately without waiting for on-chain anchoring, providing flexibility while maintaining the ability to later publish these DIDs to the blockchain.\n\nThe protocol defines clear rules for constructing and validating operations, translating internal state to W3C-compliant DID Documents, and resolving DIDs.\nSecurity is enforced through cryptographic signatures, with each DID having at least one master key for operation signing.\nPRISM is designed to be scalable and secure, with support for various verification methods, services, and key types including secp256k1, Ed25519, and X25519.\n\n**Examples:**\n\nShort-form DID:\n```\ndid:prism:9b5118411248d9663b6ab15128fba8106511230ff654e7514cdcc4ce919bde9b\n```\n\nLong-form DID:\n```\ndid:prism:9b5118411248d9663b6ab15128fba8106511230ff654e7514cdcc4ce919bde9b:Cj8KPRI7CgdtYXN0ZXIwEAFKLgoJc2VjcDI1NmsxEiEDHpf-yhIns-LP3tLvA8icC5FJ1ZlBwbllPtIdNZ3q0jU\n```\n\n# Quickstart\n\n## Try It Now\n\nQuickly experiment with NeoPRISM using an in-memory database and in-memory blockchain:\n\n```bash\ndocker run --rm -p 8080:8080 -e NPRISM_DB_URL=sqlite::memory: hyperledgeridentus/identus-neoprism:\u003cVERSION\u003e dev\n```\n\n\u003e **Note:** Replace `\u003cVERSION\u003e` with a specific release tag (e.g., `0.1.0`).\n\nThis command starts a NeoPRISM node in development mode with:\n- In-memory SQLite database (data is lost when container stops)\n- Mock Cardano data source (no real blockchain connection)\n- Web UI and API server on port 8080\n\nAccess the Web UI at [http://localhost:8080](http://localhost:8080) to explore the interface.\n\n\u003cdetails\u003e\n\u003csummary\u003eSubmit a sample DID operation (optional)\u003c/summary\u003e\n\nOnce the container is running, you can submit a sample DID operation from another terminal:\n\n\u003e **Note:** The hex string below is a pre-generated test signed operation for demonstration purposes.\n\n```bash\ncurl -X 'POST' \\\n  'http://localhost:8080/api/signed-operation-submissions' \\\n  -H 'accept: application/json' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n  \"signed_operations\": [\n    \"0a086d61737465722d3012473045022100d54e1b7ce250c6d1333348c21aa162703793809d8751f07f82f5f9584b91850902201b2b3b43013a8bac123d9e32531aa6d8a065c23ff3e4160d7f4f0ce8c84c44581a7e0a7c0a7a123c0a086d61737465722d3010014a2e0a09736563703235366b31122103b20404f350d87eec98982131c176acfea520f26f8901fe08b619a56a0dd9e417123a0a06617574682d3010044a2e0a09736563703235366b31122103868f518859c09aa1a045c215d3a141b042299f09157192f67bc5c8a97e175b4d\"\n  ]\n}'\n```\n\nThen navigate to [http://localhost:8080/explorer](http://localhost:8080/explorer) to see the DIDs on the in-memory blockchain.\n\n\u003c/details\u003e\n\n## Public Demo Instance\n\nTry NeoPRISM without any setup using these hosted instances connected to live Cardano networks:\n\n- Mainnet: [https://neoprism.patlo.dev](https://neoprism.patlo.dev)\n- Preprod: [https://neoprism-preprod.patlo.dev](https://neoprism-preprod.patlo.dev)\n\n## Docker Compose\n\nThis example setup runs a NeoPRISM node that connects to the Cardano mainnet public relay using Oura.\nIt fetches DID operations from the blockchain, synchronizes and indexes them into a local PostgreSQL database.\nOnce operations are indexed, you can browse them using the Explorer page in the Web UI.\n\n**Prerequisites:**\n- [Docker](https://docs.docker.com/get-docker/)\n\n**Supported Platforms:**\n- The official NeoPRISM Docker image supports both x86_64 and arm64 architectures.\n- Compatible with Linux, macOS, and Windows hosts that can run Docker.\n\n**Steps:**\n\n1. Clone the repository and navigate to the example directory:\n   ```bash\n   cd docker/mainnet-relay\n   ```\n2. Start the node and sync block metadata:\n   ```bash\n   docker-compose up\n   ```\n3. Access the Web UI at [http://localhost:8080](http://localhost:8080). The Explorer page allows you to browse indexed DID operations.\n4. Use the resolver endpoint to resolve DIDs:\n   ```bash\n   curl http://localhost:8080/api/dids/\u003cdid\u003e\n   ```\n\n# Development guide\n\nThis project uses Nix to provide a consistent local development environment and to package build artifacts.\nTo get started, install Nix by following the instructions [here](https://nixos.org/download/#download-nix).\n\n__Entering the development shell__\n\nIf you already have `cargo` and other required dependencies (such as `protoc`) installed, you can use your own environment.\nYou can review the [nix shell](./nix/devShells/development.nix) file to see the required dependencies and adapt them to your setup.\n\nWe recommend using the `nix develop` command to enter the development shell.\nThis ensures a consistent environment and uses the same library versions for building and testing.\n\n```bash\nnix develop\n\n# You can now run commands like \"cargo version\"\n```\nNote: You may need to enable experimental flake commands. Please follow the instructions [here](https://nixos.wiki/wiki/Flakes).\n\nYou can also use `--unset \u003cENV\u003e` to disable host environment variables and make the development shell more pure.\nFor example:\n\n```bash\nnix develop --unset PATH\n```\n\nThis disables all binaries available on the host `PATH`.\n\n\n## Development quickstart\n\nTo set up and run NeoPRISM for development, follow these steps:\n\n1. **Enter the development shell:**\n   ```bash\n   nix develop --unset PATH\n   ```\n2. **Install web UI dependencies** (only required the first time):\n   ```bash\n   just init\n   ```\n3. **Start the local PostgreSQL database** (required for NeoPRISM to store data):\n   ```bash\n   just postgres-up\n   ```\n4. **Run the NeoPRISM node** (this will automatically generate all required assets):\n   ```bash\n   just run\n   ```\n5. **Access the Web UI and API** at [http://localhost:8080](http://localhost:8080).\n\n**Cleaning up services**\n\n- To stop and remove the local database:\n  ```bash\n  just postgres-down\n  ```\n\n**Notes**\n- Default port used is `8080`.\n- No need to run `just build-assets` manually; `just run` handles asset generation automatically.\n- You can run `just build-assets` separately if you only want to generate web UI assets without starting the node.\n- All `docker/*/compose*.yml` files are auto-generated from Python sources in `tools/compose_gen/`. Do not edit these YAML files directly. Instead, modify the Python sources and run `just build-config` to regenerate them.\n\n## Running E2E Tests\n\nNeoPRISM includes end-to-end conformance tests that verify the PRISM DID protocol implementation. These tests validate DID operations (create, update, deactivate) against a local Cardano testnet.\n\n**Prerequisites:**\n- Nix with flakes enabled\n\n**Running the tests:**\n\n```bash\n# Enter the development shell\nnix develop\n\n# Run the full e2e test suite\njust e2e::run\n```\n\nThis command will:\n1. Build the NeoPRISM and Cardano testnet Docker images\n2. Start a local test environment with a Cardano node\n3. Run the Scala-based conformance test suite\n4. Tear down the test environment\n\n**Important notes:**\n- The first run may take several minutes to build all Docker images. Subsequent runs will be faster as images are cached.\n- The Docker images are built using Nix, which only includes files tracked by git. If you add new files to the codebase, make sure to stage them with `git add` before running the tests, otherwise they won't be included in the Docker image build.\n\n**Building tests only:**\n\nTo compile the test suite without running it:\n\n```bash\njust e2e::build\n```\n\n### Running specific E2E stacks\n\nThe e2e harness now ships four compose variants that differ by backend (PostgreSQL or SQLite) and target audience (developer-friendly vs CI-hardening). You can exercise any stack individually by combining the `up`, `down`, and `run` recipes:\n\n```bash\n# Start only the SQLite developer stack\njust e2e::up sqlite-dev\n# Run the Scala tests that target the running stack\n(cd tests/prism-test \u0026\u0026 sbt test)\n# Clean up once finished\njust e2e::down sqlite-dev\n```\n\n`just e2e::run` iterates over every stack in sequence—`sqlite-dev`, `ci`, and `ci-sqlite`—so that both backends are covered automatically.\n\n### Configuration matrix\n\n| Mode | Backend | Compose file | `just` target | Recommended usage | Pros | Trade-offs |\n|------|---------|--------------|---------------|-------------------|------|------------|\n| sqlite-dev | SQLite | `docker/prism-test/compose-sqlite-dev.yml` | `just e2e::up sqlite-dev` | Fast local iterations or laptop CI checks | Zero extra services, file-backed DB keeps resource usage low | Single-writer semantics; best for smoke tests |\n| ci | PostgreSQL | `docker/prism-test/compose-ci.yml` | `just e2e::up ci` | Full CI pipeline and release rehearsal | Mirrors production topology with stricter health checks | Pulls more images and runs longer |\n| ci | SQLite | `docker/prism-test/compose-ci-sqlite.yml` | `just e2e::up ci-sqlite` | CI shard that validates the embedded backend | Ensures SQLite stays first-class even under CI load | Cardano/I/O limits are similar to `ci`, so still slower than dev |\n\nPick the stack that matches your goal; for example, run `sqlite-dev` while iterating on backend logic, and keep `ci` or `ci-sqlite` in nightly pipelines for extra safety.\n\n### Full QA helper script\n\nThe justfile provides a `full-check` recipe that strings the common QA steps together:\n\n```bash\njust full-check\n```\n\nThis recipe performs `cargo clean`, `cargo build --all-features`, regenerates compose files, runs `just test`, builds the Docker artifacts, and executes `just e2e::run`. Use it right before sending a PR to replicate the checks we run manually.\n\n### SQLx schema checks\n\nThe development shell now bundles `sqlx-cli`, `sqlite`, and all required headers. Whenever you change migrations or entity definitions, run both backends to ensure they stay valid:\n\n```bash\n# Postgres schema (point to your local instance)\nnix develop -c 'DATABASE_URL=postgres://postgres:postgres@localhost:5432/postgres sqlx migrate run'\n\n# Embedded SQLite schema (creates a throwaway file)\nnix develop -c 'DATABASE_URL=sqlite://$(pwd)/.tmp/neoprism-dev.sqlite sqlx migrate run'\n```\n\nRemove the temporary SQLite file afterwards if you do not need it anymore.\n\n#### Offline sqlx metadata (optional)\n\nIf you rely on `cargo sqlx prepare` for offline builds, regenerate metadata for each backend:\n\n```bash\n# Postgres metadata\nDATABASE_URL=postgres://postgres:postgres@localhost:5432/postgres \\\n  cargo sqlx prepare --bin neoprism-node\n\n# SQLite metadata\nDATABASE_URL=sqlite://$(pwd)/.tmp/neoprism-dev.sqlite \\\n  cargo sqlx prepare --bin neoprism-node\n```\n\nThe generated `sqlx-data.json` reflects the currently enabled features, so keep both variants in sync if you commit the file.\n\n### Database backends\n\nNeoPRISM supports both PostgreSQL and embedded SQLite storage. The backend is inferred from `--db-url` / `NPRISM_DB_URL`: use a `postgres://` URL for Postgres or a `sqlite://` URL for SQLite. If you omit the flag entirely, the node falls back to an embedded SQLite file in your platform's application-data directory (for example `~/Library/Application Support/NeoPRISM/\u003cnetwork\u003e/neoprism.db` on macOS or `$XDG_DATA_HOME/NeoPRISM/\u003cnetwork\u003e/neoprism.db` on Linux).\n\nSQLite is great for local development, demos, and CI smoke tests, but remember:\n\n- It is effectively single-writer; keep the node as the only process touching the file.\n- WAL mode is enforced automatically to keep reads non-blocking.\n- Long running readers can delay checkpointing and grow the file; run `VACUUM` occasionally if you prune data manually.\n\n## Frequently used commands\n\nThese are commands you can run outside the development shell:\n\n| command                                                 | description                                                        |\n|---------------------------------------------------------|--------------------------------------------------------------------|\n| `nix build .#neoprism-docker`                           | Use nix to build the docker image (output available at `./result`) |\n| `nix build .#neoprism-docker \u0026\u0026 docker load \u003c ./result` | Use nix to build the docker image and load it using docker         |\n\nAssuming you are in the development shell, here are some frequently used commands:\n\n| command                          | description                                    |\n|----------------------------------|------------------------------------------------|\n| `just init`                      | Install the npm dependencies (first time only) |\n| `cargo build`                    | Build the cargo workspace                      |\n| `cargo clean`                    | Clean the cargo workspace                      |\n| `cargo r -p neoprism-node -- -h` | See `neoprism-node` service CLI options        |\n| `cargo test --all-features`      | Run tests that enable all crate features       |\n\nThe following justfile commands are available to automate the local development workflow:\n\n| command                                       | description                                                          |\n|-----------------------------------------------|----------------------------------------------------------------------|\n| `just format`                                 | Run the formatter on everything (Rust, Nix, TOML, Python, SQL, Hurl) |\n| `just build`                                  | Build the whole project (assets + cargo)                             |\n| `just build-assets`                           | Build the Web UI assets (CSS, JavaScript, static assets)             |\n| `just build-config`                           | Generate Docker Compose configs from the Python sources in `tools/`  |\n| `just test`                                   | Run all tests with all features enabled                              |\n| `just check`                                  | Run the full Nix checks suite (format, lint, test, clippy)           |\n| `just clean`                                  | Clean all build artifacts                                            |\n| `just postgres-up`                            | Spin up the local PostgreSQL database (Docker)                       |\n| `just postgres-down`                          | Tear down the local PostgreSQL database                              |\n| `just postgres-dump`                          | Dump the local PostgreSQL database to the `postgres.dump` file       |\n| `just postgres-restore`                       | Restore the local PostgreSQL database from the `postgres.dump` file  |\n| `just sqlite-init`                            | Create or migrate the embedded SQLite database (default path)        |\n| `just sqlite-clean`                           | Delete the embedded SQLite database file                             |\n| `just run indexer`                            | Run the indexer node, connecting to the local database               |\n| `just run indexer --cardano-addr \u003cADDR\u003e`      | Run the indexer node, connecting to the Cardano relay at `\u003cADDR\u003e`    |\n| `just run indexer --dbsync-url \u003cURL\u003e`         | Run the indexer node, connecting to the DB Sync instance at `\u003cURL\u003e`  |\n| `just run indexer --blockfrost-api-key \u003cKEY\u003e` | Run the indexer node, connecting to Blockfrost API with your API key |\n| `just tools format`                           | Format the Python code in `tools/`                                   |\n| `just tools check`                            | Type-check and validate the Python tooling code                      |\n| `just e2e::build`                             | Build the PRISM conformance (end-to-end) test suite                  |\n| `just e2e::run`                               | Run the PRISM conformance (end-to-end) test suite                    |\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhyperledger-identus%2Fneoprism","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhyperledger-identus%2Fneoprism","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhyperledger-identus%2Fneoprism/lists"}