Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 20 additions & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,23 @@ jobs:
uses: coverallsapp/github-action@v2
with:
github-token: ${{ github.token }}


docker-build-push:
runs-on: ubuntu-latest
needs: test-node
if: github.ref == 'refs/heads/main'
steps:
- uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to Docker Hub
uses: docker/login-action@v3
with:
username: skybridgeskills
password: ${{ secrets.DOCKERHUB_PAT }}
- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
context: .
push: true
tags: skybridgeskills/dcc-transaction-service:${{ github.sha }}
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ lerna-debug.log*

package-lock.json
yarn.lock
pnpm-lock.yaml

# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
Expand Down Expand Up @@ -75,6 +76,7 @@ types/
# dotenv environment variables file
.env
.env.test
test-fixtures/.env.testing

# parcel-bundler cache (https://parceljs.org/)
.cache
Expand Down
6 changes: 1 addition & 5 deletions .husky/pre-commit
Original file line number Diff line number Diff line change
@@ -1,5 +1 @@
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

npx lint-staged
npm test
npm test
1 change: 1 addition & 0 deletions .nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
lts/iron
7 changes: 4 additions & 3 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
FROM node:18-alpine
FROM node:20-alpine
WORKDIR /app
COPY . .
RUN npm install
CMD ["node", "server.js"]
EXPOSE 4004
RUN npm run build
CMD ["node", "dist/server.js"]
EXPOSE 4004
261 changes: 167 additions & 94 deletions README.md

Large diffs are not rendered by default.

5 changes: 5 additions & 0 deletions nodemon.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"watch": ["src"],
"ext": "ts",
"exec": "ts-node -r dotenv/config src/server.ts"
}
47 changes: 33 additions & 14 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,49 +1,68 @@
{
"name": "@digitalcredentials/transaction-service",
"description": "An express app for managing challenges in a DIDAuth exchange.",
"description": "A hono app for managing DID Auth and VC-API exchanges.",
"version": "0.3.0",
"type": "module",
"scripts": {
"start": "node -r dotenv/config server.js",
"dev": "nodemon -r dotenv/config server.js",
"dev-noenv": "nodemon server.js",
"test": "NODE_OPTIONS=--experimental-vm-modules npx c8 mocha --timeout 10000 -r dotenv/config dotenv_config_path=src/test-fixtures/.env.testing src/app.test.js ",
"coveralls": "npm run test; npx c8 report --reporter=text-lcov > ./coverage/lcov.info",
"prepare": "test -d node_modules/husky && husky install || echo \"husky is not installed\"",
"build": "tsc",
"start": "node -r dotenv/config dist/server.js",
"dev": "nodemon -r dotenv/config --exec tsx src/server.ts",
"dev-noenv": "nodemon --exec tsx src/server.ts",
"test": "dotenvx run -f src/test-fixtures/.env.testing -- vitest run",
"coverage": "dotenvx run -f src/test-fixtures/.env.testing -- vitest run --coverage",
"prepare": "husky",
"lint": "eslint",
"lint-fix": "eslint --fix"
},
"dependencies": {
"@digitalbazaar/data-integrity": "^2.5.0",
"@digitalbazaar/ecdsa-rdfc-2019-cryptosuite": "^1.2.0",
"@digitalbazaar/ed25519-multikey": "^1.3.1",
"@digitalbazaar/ed25519-signature-2020": "^5.4.0",
"@digitalbazaar/ed25519-verification-key-2020": "^4.1.0",
"@digitalbazaar/eddsa-rdfc-2022-cryptosuite": "^1.2.0",
"@digitalbazaar/vc": "^7.0.0",
"@digitalcredentials/security-document-loader": "^6.0.0",
"@hono/node-server": "^1.14.4",
"@keyv/redis": "^4.4.0",
"axios": "^1.7.7",
"cookie-parser": "~1.4.4",
"cors": "^2.8.5",
"debug": "~2.6.9",
"dotenv": "^16.0.3",
"express": "~4.16.1",
"keyv": "^4.5.2",
"keyv-file": "^0.2.0",
"express": "^5.1.0",
"handlebars": "^4.7.8",
"hono": "^4.7.11",
"keyv": "^5.3.3",
"keyv-file": "^5.1.2",
"morgan": "~1.9.1",
"nodemailer": "^6.9.14"
"nodemailer": "^6.9.14",
"tsx": "^4.20.1",
"zod": "^3.25.56"
},
"devDependencies": {
"@dotenvx/dotenvx": "^1.44.1",
"@eslint/js": "^9.3.0",
"@types/chai": "^5.2.2",
"@types/cors": "^2.8.19",
"@types/express": "^5.0.3",
"@types/morgan": "^1.9.10",
"@types/node": "^22.15.30",
"@types/supertest": "^6.0.3",
"@vitest/coverage-v8": "^3.2.3",
"chai": "^4.3.7",
"coveralls": "^3.1.1",
"eslint": "^9.3.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-mocha": "^10.4.3",
"globals": "^15.3.0",
"husky": "^9.0.11",
"lint-staged": "^15.2.5",
"mocha": "^10.2.0",
"nock": "^13.5.4",
"nodemon": "^2.0.21",
"prettier": "3.2.5",
"supertest": "^6.3.3"
"supertest": "^6.3.3",
"typescript": "^5.8.3",
"vitest": "^3.2.3"
},
"keywords": [
"dcc"
Expand Down
15 changes: 0 additions & 15 deletions server.js

This file was deleted.

6 changes: 0 additions & 6 deletions src/TransactionException.js

This file was deleted.

128 changes: 128 additions & 0 deletions src/app.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
declare global {
namespace App {
interface Config {
port: number
exchangeHost: string
exchangeTtl: number
statusService: string
signingService: string
defaultWorkflow: string
defaultTenantName: string
keyvFilePath?: string
redisUri?: string
keyvWriteDelayMs: number
keyvExpiredCheckDelayMs: number
}

interface ErrorResponseBody {
code: number
message: string
details?: Array<{
code: string
message: string
path: Array<string>
}>
}

interface Credential extends Record<string, unknown> {
credentialSubject: Record<string, unknown> & {
id: string
}
}

interface ExchangeBatch {
data: Array<{
vc: string // JSON template string
subjectData?: Record<string, unknown>
retrievalId?: string // Optional for later retrieval/correlation of this record
metadata?: Record<string, unknown> // Additional data to store related to the exchange
redirectUrl?: string
}>
batchId?: string
exchangeHost: string
tenantName: string
workflowId?: string
}

interface ExchangeCreateInput {
expires?: string
variables: Record<string, unknown> & {
vc?: string
redirectUrl?: string
exchangeHost: string
tenantName: string
challenge?: string
}
}

interface ExchangeDetail {
// Local metadata
tenantName: string
workflowId: string

// VC-API metadata
exchangeId: string
expires: string
state: 'pending' | 'active' | 'completed' | 'invalid'
variables: {
vc?: string
redirectUrl?: string
retrievalId?: string
exchangeHost: string
metadata?: Record<string, unknown>
challenge: string // Used to authenticate presentations
}
}

interface WorkflowStep {
createChallenge: boolean
verifiablePresentationRequest: {
query: Array<{ type: string } & Record<string, any>> // Simplistic for now
}
}

interface Workflow {
id: string
steps: Record<string, WorkflowStep>
initialStep: string
credentialTemplates?: Array<{
id: string
type: 'handlebars' // TODO: add 'jsonata'
template: string
}>
}

interface VPR {
query: {
type: 'DIDAuthentication' | 'QueryByExample'
} & Record<string, unknown>
interact: {
service: Array<{
type:
| 'VerifiableCredentialApiExchangeService'
| 'UnmediatedPresentationService2021'
| 'CredentialHandlerService'
serviceEndpoint?: string
}>
}
challenge: string
domain: string
}

interface Protocols {
vcapi?: string
verifiablePresentationRequest: VPR
lcw?: string
}

interface DCCWalletQuery {
retrievalId: string
directDeepLink: string
vprDeepLink: string
chapiVPR?: VPR
metadata?: Record<string, unknown>
}
}
}

export {}
Loading