A user interface for Veritable that allows to manage connections across supply chain and perform queries in relation to the supply chain. Utilizing TSOA, HTMX and @kitajs/html for JSX templates.
- Setup
- Getting Started
- Development Mode/Local dev
- Environment Variables
- Testing
- Database
- Establishing connection
veritable-ui depends on a few external services:
- veritable-cloudagent - APIs for managing connections, credentials and messages.
- IPFS - a distributed file server for storing credential schemas
- Keycloak - runs as a docker image for each node that handles authentication and users.
- smtp4dev - runs as a docker image for exchanging emails during onboarding workflows
- WireMock - runs as a docker image for
integrationande2etests to mock an official national company register
β οΈ last updated: 08/07/2025
- docker v28.1.1 (later versions currently have issues)
- npm 11.0.0+
- node 24.0.0+
- postgresql 17.5+
Install dependencies using:
npm installAfter all packages have been installed run the below command which will create two files: src/routes.ts, ./build/swagger.json and run the typescript compiler
npm run buildThe service requires a Companies House API key:
- Register a developer account.
- Create an application set to
Liveenvironment. - Within the new application create a
RESTAPI key. - Add an
.envfile at the root of the project containingCOMPANY_PROFILE_API_KEY=apikey.
Bring up all the required services for local development:
docker compose up -d --buildDatabase migration for Alice.
npm run db:migrateAssert the presence of issuance records (DID, schema and credential definition) via the Alice cloudagent. Specifically, the script asserts any valid DID, the COMPANY_DETAILS schema and a credential definition based on that schema.
{
"COMPANY_DETAILS": {
"version": "1.0.0",
"attrNames": ["company_number", "company_name"]
}
}These issuance records are required to form connections between personas. Behaviour of init depends on configuration of ISSUANCE_ envs, which default to use existing records or create new records if none exist.
npm run dev:initFinally, start the service and enjoy local development:
npm run devπ‘ When service is running, it can be accessed on
http://localhost:3000/. Api Docs are available onhttp://localhost:3000/api-docsand swaggerhttp://localhost:3000/swagger/. If you have opted to useSMTP_EMAILforEMAIL_TRANSPORTenv you'll find the server onhttp://localhost:5001/.
This is the list of all environment variables including brief description
| variable name | required | default | description |
|---|---|---|---|
| PORT | y | 3000 | Port number of the service |
| LOG_LEVEL | n | info | Logging level. Valid values are [ trace , debug , info , warn , error , fatal ] |
| DB_HOST | y | localhost | The database hostname / host |
| DB_NAME | y | veritable-ui | The port for the database |
| DB_USERNAME | y | postgres | The database username |
| DB_PASSWORD | y | postgres | The database password |
| DB_PORT | y | 5432 | The database port number |
| COOKIE_SESSION_KEYS | y | ['secret'] | Session cookies |
| PUBLIC_URL | y | http://localhost:3000 | URL that UI can be accessed |
| API_SWAGGER_BG_COLOR | n | #fafafa | Swagger background color |
| API_SWAGGER_TITLE | n | Veritable | Title for swagger interface |
| API_SWAGGER_HEADING | n | Veritable | Heading for swagger interface |
| IDP_CLIENT_ID | y | veritable-ui | Client ID required for Keycloak |
| IDP_PUBLIC_URL_PREFIX | y | http://localhost:3080/realms/veritable/protocol/openid-connect | Public authentication URL |
| IDP_INTERNAL_URL_PREFIX | y | http://localhost:3080/realms/veritable/protocol/openid-connect | Internal authentication URL |
| IDP_AUTH_PATH | y | /auth | Auth path for keycloak |
| IDP_TOKEN_PATH | y | /token | Tokens path for keycloak |
| IDP_JWKS_PATH | y | /certs | Certificates path for keycloak |
| COMPANY_HOUSE_API_URL | y | https://api.company-information.service.gov.uk | An external service that contain list of all UK companies, look ups |
| COMPANY_PROFILE_API_KEY | y | - | An API KEY required to access the company-information service |
| EMAIL_TRANSPORT | y | STREAM | Nodemailer transport for sending emails which can be STREAM or SMTP_EMAIL. If SMTP_EMAIL additional configuration of the transport will be needed and is described below |
| EMAIL_FROM_ADDRESS | y | [email protected] | Email address that will appear "send from" in an automated emails |
| EMAIL_ADMIN_ADDRESS | y | [email protected] | Admin's email address that will receive a copy of all comms |
| CLOUDAGENT_ADMIN_ORIGIN | y | http://localhost:3100 | veritabler-cloudagent url |
| CLOUDAGENT_ADMIN_WS_ORIGIN | y | ws://localhost:3100 | veritable-cloudagent web socker address/url |
| CLOUDAGENT_ADMIN_PING_TIMEOUT_MS | n | 30000 | Timeout waiting for the next ping from the websocket server |
| INVITATION_PIN_SECRET | y | Buffer.from('secret', 'utf8') | an encoded array of utf-8 format |
| INVITATION_PIN_ATTEMPT_LIMIT | y | 5 | number of allowed pin validation attempts |
| INVITATION_FROM_COMPANY_NUMBER | n | 07964699 | default company number, currently is us |
| ISSUANCE_DID_POLICY | y | EXISTING_OR_NEW | DID and either create or use existing: [CREATE_NEW, FIND_EXIStING, EXISTING_OR_NEW, did:somedid] |
| ISSUANCE_SCHEMA_POLICY | y | EXISTING_OR_NEW | Same as above but for credential schema |
| ISSUANCE_CRED_DEF_POLICY | y | EXISTING_OR_NEW | Same as above but this is for credential definitions |
| DEMO_MODE | y | true | Enables or disables the /reset endpoint |
| IPID_API_URL | n | https://sandbox.ipid.works | URL for iPiD service. See iPiD |
| IPID_API_KEY | y | - | API key for iPiD service. See iPiD |
| IPID_CUSTOMER_ID | n | digicatapult-uat | Customer ID provided by iPiD with API key. See iPiD |
| NY_STATE_API_URL | y | https://dev.socrata.com/foundry/data.ny.gov/p66s-i79p | External service containing list of companies in NY definitions |
| LOCAL_REGISTRY_TO_USE | y | company_house | Defines which registry to use to look up info about the local instance |
| LOCAL_REGISTRY_COUNTRY_CODE | y | GB | Defines which country local instance is based in |
| OPEN_CORPORATES_API_URL | y | https://api.opencorporates.com/v0.4 | External service containing list of companies in GB, NL and Japan |
| OPEN_CORPORATES_API_KEY | y | - | Api key for Open Corporates registry |
If using the SMTP_EMAIL value for EMAIL_TRANSPORT the following additional configuration applies
| variable name | required | default | description |
|---|---|---|---|
| SMTP_HOST | y | Specifies the hostname of the SMTP server | |
| SMTP_PORT | y | Defines the port number on which the SMTP server is listening | |
| SMTP_SECURE | n | true | A boolean indicating whether the connection to the SMTP server should be secure (i.e., use TLS/SSL) |
| SMTP_USER | y | Specifies the username for authenticating with the SMTP server, default is empty string. No authentication is required for local development environments | |
| SMTP_PASS | y | Specifies the password for authenticating with the SMTP server, default is empty string. No authentication is required for local development environments |
This repository consists of three test types: [unit, integration, e2e], using a combination of mocha, chai, sinon and playwright frameworks.
Unit tests in this repository are done per service/module or class, and follow the below pattern. In tests directories collated with the units they test.
# example
βββ __tests__
β βββ example.test.ts
β βββ __tests__
β β βββ index.test.ts
βββ __tests__
....Unit tests can be executed by running:
npm run test:unitIntegration tests are located in test/integration along with mock services and helpers and a test environment variables in ./test/test.env.
Integration tests can be run locally using Testcontainers (it is recommended to add debugging so you can follow the logs in the console, refer to testcontainers section)
npm run test:integrationRun integration tests without tearing down all containers on completion. UI containers are always rebuilt:
npm run test:integration:reuseEnd-to-end tests are located in test/e2e. They run by default in a Testcontainers environment.
Install dependencies for playwright with:
npx playwright installThen run:
npm run test:e2eThis will run the tests without the ui. It is recommended to add debugging so you can follow the logs in the console, refer to testcontainers section.
Alternatively you can run:
npm run test:playwrightA browser window will pop up where you can run tests and follow their progress.
Then you'll find the test results in directory playwright-report at root level.
See logs from a container e.g. if it is dying on startup add:
.withLogConsumer((stream) => {
stream.on('data', (line) => console.log(line))
stream.on('err', (line) => console.error(line))
stream.on('end', () => console.log('Stream closed'))
})
and run with
DEBUG=testcontainers* npm run test:integration
or
DEBUG=testcontainers* npm run test:e2e
Normally the containers are removed after a run, however you can keep them for further inspection by adding this:
await container.stop({ remove: false })
veritable-ui and cloudagent are each dependent on their own instances of PostgreSQL. knex wrapper is used for database queries. To ensure database integrity, zod is used to validate types of inserted and returned data at runtime. Configured in src/models/db/types.ts.
Main knex configuration file is knexfile.js, other files such as migrations can be found in src/models/db.
For migrations, do not update an existing file, always create a new one using
knex. New migrations will appear insrc/models/db/migrations/directory.
# creating a new migration
npm run db:cmd -- migrate:make migration_name -x ts
# running migrations
npm run db:migrate- Bring up as per getting started (docker compose, run migrations and init, then
npm run dev) to start Alice's UI. - Alice: http://localhost:3000.
- Bob: http://localhost:3001.
- Go to Bob's Invite New Connection and enter
07964699(default Companies House Number for Alice) for theCompanies House Number. Enter any valid email and submit. The list of Bob's connections now contains a new connection withInvite Sentstate. - Go to the dev email server and copy the invitation text from bottom of the email sent to the email address entered in the previous step.
- Paste the invitation text into Alice's Add from Invitation. The right hand box should update to show Bob's registered address (set by the
INVITATION_FROM_COMPANY_NUMBERenv). Submit. - Search
Verification Code:in the logs of the terminal for the running Alice server. Copy this code. SelectComplete Verificationon Bob's side of the connection, paste the code and continue. - The connection will now show as
Connectedfor both personas, and queries can be sent.
iPiD provide a 'Know Your Payee' API for validating bank account information from various countries. One of the available queries in Veritable UI is a 'Beneficiary Account Validation' query, where one member requests the bank details of another. After receiving a response, the requester can choose to validate the bank details using the iPiD API, assuming the service has been configured with iPiD environment variables (URL, api key and customer ID). Credentials are available from iPiD directly. They offer a sandbox for free testing.
We currently support:
Companies House: which requires an API KEY. (COMPANY_PROFILE_API_KEY)
NY State Registry: which does not require an API KEY. (Requests are rate-limited without an api-key)
Open Corporates: which requires an API Key. In dev mode we develop against wiremock which has a company with an identifier 00102498 that you can test against.
- if you want e.g. Charlie to pose as a company registered with NY State Registry - set
LOCAL_REGISTRY_TO_USEtony_stateandINVITATION_FROM_COMPANY_NUMBERto3211809(company number we use to test NY State Registry functionality). - if you want e.g. Charlie to pose as a company registered with Open Corporates - set
LOCAL_REGISTRY_TO_USEtoopen_corporatesandINVITATION_FROM_COMPANY_NUMBERto00102498(company number we use to test Open Corporates functionality).