@learncard/create-http-bridge 1.1.248 → 1.1.250
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +17 -0
- package/README.md +58 -0
- package/dist/index.js +8 -6
- package/package.json +10 -8
- package/project.json +5 -1
- package/scripts/sync-didkit.ts +22 -0
- package/serverless.yml +4 -1
- package/src/app.ts +31 -18
- package/src/didkit_wasm_bg.wasm +0 -0
- package/src/learn-card.ts +21 -2
- package/src/server.ts +10 -0
- package/src/validators.ts +32 -22
- package/w3c-localConfig.cjs +35 -0
- package/esbuildWasmPlugin.cjs +0 -31
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,22 @@
|
|
|
1
1
|
# @learncard/create-http-bridge
|
|
2
2
|
|
|
3
|
+
## 1.1.250
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies []:
|
|
8
|
+
- @learncard/init@2.4.11
|
|
9
|
+
|
|
10
|
+
## 1.1.249
|
|
11
|
+
|
|
12
|
+
### Patch Changes
|
|
13
|
+
|
|
14
|
+
- [#1444](https://github.com/learningeconomy/LearnCard/pull/1444) [`5489866631ce3b19709a3685c56ff68e2d817af4`](https://github.com/learningeconomy/LearnCard/commit/5489866631ce3b19709a3685c56ff68e2d817af4) Thanks [@TaylorBeeston](https://github.com/TaylorBeeston)! - [LC-1958] Fix W3C EdDSA Data Integrity interoperability and ship rebuilt native and WASM DIDKit artifacts.
|
|
15
|
+
|
|
16
|
+
- Updated dependencies [[`5489866631ce3b19709a3685c56ff68e2d817af4`](https://github.com/learningeconomy/LearnCard/commit/5489866631ce3b19709a3685c56ff68e2d817af4)]:
|
|
17
|
+
- @learncard/types@5.18.1
|
|
18
|
+
- @learncard/init@2.4.10
|
|
19
|
+
|
|
3
20
|
## 1.1.248
|
|
4
21
|
|
|
5
22
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -20,6 +20,64 @@ https://docs.learncard.com
|
|
|
20
20
|
- Add a .env file exporting a wallet seed (e.g. `WALLET_SEED=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa`)
|
|
21
21
|
- Run `bun run serverless-deploy`
|
|
22
22
|
|
|
23
|
+
## Local VC-API conformance testing
|
|
24
|
+
|
|
25
|
+
The bridge uses a source-controlled DIDKit WASM copied from the current plugin build. Every
|
|
26
|
+
build and start command verifies the canonical plugin artifact's SHA-256 before refreshing the
|
|
27
|
+
bridge copy, so local, CLI, and serverless execution cannot silently use different binaries.
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
cd lib/didkit/lib/web
|
|
31
|
+
wasm-pack build --target=web && cd pkg && wasm-opt -Oz -o tmp.wasm didkit_wasm_bg.wasm && mv tmp.wasm didkit_wasm_bg.wasm && cp didkit* ../../../../../packages/plugins/didkit/src/didkit/pkg/ && cd ..
|
|
32
|
+
bun --cwd ../../../../packages/plugins/didkit run build
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Stop and restart any running bridge after rebuilding; it loads the DIDKit WASM during
|
|
36
|
+
initialization.
|
|
37
|
+
When intentionally rebuilding DIDKit, review the new binary and update
|
|
38
|
+
`EXPECTED_DIDKIT_SHA256` in `scripts/sync-didkit.ts`. To test an unreviewed local artifact
|
|
39
|
+
without changing that pin, set `LOCAL_DIDKIT_PATH` as described below.
|
|
40
|
+
|
|
41
|
+
Start the LearnCard HTTP bridge in the first terminal:
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
cd packages/learn-card-bridge-http
|
|
45
|
+
WALLET_SEED=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa \
|
|
46
|
+
bun run start:local
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Set `LOCAL_DIDKIT_PATH=/absolute/path/to/didkit_wasm_bg.wasm` only to override the
|
|
50
|
+
package-provided WASM. The test seed must match the issuer DID in `w3c-localConfig.cjs`.
|
|
51
|
+
|
|
52
|
+
Run the current W3C EdDSA Data Integrity suite in a second terminal:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
git clone --depth 1 https://github.com/w3c/vc-di-eddsa-test-suite.git
|
|
56
|
+
cd vc-di-eddsa-test-suite
|
|
57
|
+
npm install
|
|
58
|
+
cp "$LEARN_CARD_REPO/packages/learn-card-bridge-http/w3c-localConfig.cjs" localConfig.cjs
|
|
59
|
+
npx mocha tests/05-di-rdfc-create.js --timeout 30000
|
|
60
|
+
npx mocha tests/15-di-rdfc-verify.js --timeout 30000
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Set `LEARN_CARD_REPO` to the absolute path of this monorepo. Set `BASE_URL` when the
|
|
64
|
+
bridge is not listening at `http://127.0.0.1:3100`.
|
|
65
|
+
|
|
66
|
+
## URL issuer verification policy
|
|
67
|
+
|
|
68
|
+
When a credential names an HTTPS issuer but its proof uses a DID verification method, a
|
|
69
|
+
successful `proof` check establishes signature integrity only. DIDKit cannot establish that the
|
|
70
|
+
named URL issuer authorized that DID key because there is no issuer DID document to supply the
|
|
71
|
+
assertion-method relationship. The raw verification result therefore includes this
|
|
72
|
+
security-relevant warning:
|
|
73
|
+
|
|
74
|
+
```text
|
|
75
|
+
Issuer authorization was not checked because the credential issuer is not a DID
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Consumers must surface or enforce this warning according to their trust policy; they must not
|
|
79
|
+
interpret `checks: ["proof"]` by itself as issuer authorization.
|
|
80
|
+
|
|
23
81
|
## Contributing
|
|
24
82
|
|
|
25
83
|
Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.
|
package/dist/index.js
CHANGED
|
@@ -416,14 +416,16 @@ const App = ({ name = "LearnCardHTTPBridge" }) => {
|
|
|
416
416
|
};
|
|
417
417
|
|
|
418
418
|
var name = "@learncard/create-http-bridge";
|
|
419
|
-
var version = "1.1.
|
|
419
|
+
var version = "1.1.250";
|
|
420
420
|
var description = "Instantly create and deploy a Learn Card Bridge HTTP API via AWS Lambda!";
|
|
421
421
|
var main = "dist/index.js";
|
|
422
422
|
var bin = "dist/index.js";
|
|
423
423
|
var scripts = {
|
|
424
|
-
"
|
|
425
|
-
|
|
426
|
-
|
|
424
|
+
"sync-didkit": "bun scripts/sync-didkit.ts",
|
|
425
|
+
"serverless-deploy": "bun run sync-didkit && serverless deploy",
|
|
426
|
+
start: "bun run sync-didkit && rollup -c && node dist/index.js",
|
|
427
|
+
"start:local": "bun run sync-didkit && bun src/server.ts",
|
|
428
|
+
build: "bun run sync-didkit && rollup -c"
|
|
427
429
|
};
|
|
428
430
|
var author = "Learning Economy Foundation (www.learningeconomy.io)";
|
|
429
431
|
var license = "MIT";
|
|
@@ -451,7 +453,8 @@ var dependencies = {
|
|
|
451
453
|
"serverless-http": "^3.0.1",
|
|
452
454
|
"serverless-plugin-warmup": "^8.1.0",
|
|
453
455
|
"simple-git": "^3.36.0",
|
|
454
|
-
"use-immer": "^0.7.0"
|
|
456
|
+
"use-immer": "^0.7.0",
|
|
457
|
+
zod: "4.1.13"
|
|
455
458
|
};
|
|
456
459
|
var devDependencies = {
|
|
457
460
|
"@types/aws-lambda": "^8.10.106",
|
|
@@ -464,7 +467,6 @@ var devDependencies = {
|
|
|
464
467
|
"@types/react": "^17.0.2",
|
|
465
468
|
nodemon: "^2.0.16",
|
|
466
469
|
"serverless-plugin-typescript": "^2.1.0",
|
|
467
|
-
shx: "^0.3.4",
|
|
468
470
|
"ts-node": "^10.8.1"
|
|
469
471
|
};
|
|
470
472
|
var repository = {
|
package/package.json
CHANGED
|
@@ -1,19 +1,21 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@learncard/create-http-bridge",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.250",
|
|
4
4
|
"description": "Instantly create and deploy a Learn Card Bridge HTTP API via AWS Lambda!",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": "dist/index.js",
|
|
7
7
|
"scripts": {
|
|
8
|
-
"
|
|
9
|
-
"
|
|
10
|
-
"
|
|
8
|
+
"sync-didkit": "bun scripts/sync-didkit.ts",
|
|
9
|
+
"serverless-deploy": "bun run sync-didkit && serverless deploy",
|
|
10
|
+
"start": "bun run sync-didkit && rollup -c && node dist/index.js",
|
|
11
|
+
"start:local": "bun run sync-didkit && bun src/server.ts",
|
|
12
|
+
"build": "bun run sync-didkit && rollup -c"
|
|
11
13
|
},
|
|
12
14
|
"author": "Learning Economy Foundation (www.learningeconomy.io)",
|
|
13
15
|
"license": "MIT",
|
|
14
16
|
"dependencies": {
|
|
15
|
-
"@learncard/init": "2.4.
|
|
16
|
-
"@learncard/types": "5.18.
|
|
17
|
+
"@learncard/init": "2.4.11",
|
|
18
|
+
"@learncard/types": "5.18.1",
|
|
17
19
|
"@rollup/plugin-json": "^4.1.0",
|
|
18
20
|
"commander": "^9.3.0",
|
|
19
21
|
"cors": "^2.8.5",
|
|
@@ -35,7 +37,8 @@
|
|
|
35
37
|
"serverless-http": "^3.0.1",
|
|
36
38
|
"serverless-plugin-warmup": "^8.1.0",
|
|
37
39
|
"simple-git": "^3.36.0",
|
|
38
|
-
"use-immer": "^0.7.0"
|
|
40
|
+
"use-immer": "^0.7.0",
|
|
41
|
+
"zod": "4.1.13"
|
|
39
42
|
},
|
|
40
43
|
"devDependencies": {
|
|
41
44
|
"@types/aws-lambda": "^8.10.106",
|
|
@@ -48,7 +51,6 @@
|
|
|
48
51
|
"@types/react": "^17.0.2",
|
|
49
52
|
"nodemon": "^2.0.16",
|
|
50
53
|
"serverless-plugin-typescript": "^2.1.0",
|
|
51
|
-
"shx": "^0.3.4",
|
|
52
54
|
"ts-node": "^10.8.1"
|
|
53
55
|
},
|
|
54
56
|
"repository": {
|
package/project.json
CHANGED
|
@@ -7,7 +7,11 @@
|
|
|
7
7
|
"tags": [],
|
|
8
8
|
"implicitDependencies": ["types", "init"],
|
|
9
9
|
"namedInputs": {
|
|
10
|
-
"source": [
|
|
10
|
+
"source": [
|
|
11
|
+
"{projectRoot}/src/**/*",
|
|
12
|
+
"{projectRoot}/scripts/sync-didkit.ts",
|
|
13
|
+
"{workspaceRoot}/packages/plugins/didkit/src/didkit/pkg/didkit_wasm_bg.wasm"
|
|
14
|
+
],
|
|
11
15
|
"dist": ["{projectRoot}/dist/**/*"]
|
|
12
16
|
},
|
|
13
17
|
"targets": {
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { createHash } from 'crypto';
|
|
2
|
+
import { readFile, writeFile } from 'fs/promises';
|
|
3
|
+
|
|
4
|
+
const EXPECTED_DIDKIT_SHA256 = '60efb6027699fda135db0d817f7a541bbd660ae88bec9cbec9796feeb3740b96';
|
|
5
|
+
const sourceUrl = new URL(
|
|
6
|
+
'../../plugins/didkit/src/didkit/pkg/didkit_wasm_bg.wasm',
|
|
7
|
+
import.meta.url
|
|
8
|
+
);
|
|
9
|
+
const destinationUrl = new URL('../src/didkit_wasm_bg.wasm', import.meta.url);
|
|
10
|
+
if (!process.env.LOCAL_DIDKIT_PATH) {
|
|
11
|
+
const didkit = await readFile(sourceUrl);
|
|
12
|
+
const actualHash = createHash('sha256').update(didkit).digest('hex');
|
|
13
|
+
|
|
14
|
+
if (actualHash !== EXPECTED_DIDKIT_SHA256) {
|
|
15
|
+
throw new Error(
|
|
16
|
+
`DIDKit WASM hash changed: expected ${EXPECTED_DIDKIT_SHA256}, received ${actualHash}. ` +
|
|
17
|
+
'Review the rebuilt artifact and update EXPECTED_DIDKIT_SHA256 intentionally.'
|
|
18
|
+
);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
await writeFile(destinationUrl, didkit);
|
|
22
|
+
}
|
package/serverless.yml
CHANGED
|
@@ -11,7 +11,6 @@ plugins:
|
|
|
11
11
|
custom:
|
|
12
12
|
esbuild:
|
|
13
13
|
packager: bun
|
|
14
|
-
plugins: esbuildWasmPlugin.cjs
|
|
15
14
|
warmup:
|
|
16
15
|
default:
|
|
17
16
|
enabled: true
|
|
@@ -27,6 +26,10 @@ provider:
|
|
|
27
26
|
environment:
|
|
28
27
|
WALLET_SEED: ${env:WALLET_SEED}
|
|
29
28
|
|
|
29
|
+
package:
|
|
30
|
+
patterns:
|
|
31
|
+
- src/didkit_wasm_bg.wasm
|
|
32
|
+
|
|
30
33
|
functions:
|
|
31
34
|
api:
|
|
32
35
|
handler: lambda.handler
|
package/src/app.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import express from 'express';
|
|
2
2
|
import cors from 'cors';
|
|
3
|
-
import {
|
|
3
|
+
import { VCValidator, VPValidator, type UnsignedVC, type VP } from '@learncard/types';
|
|
4
4
|
|
|
5
5
|
import { TypedRequest } from './types.helpers';
|
|
6
6
|
import {
|
|
@@ -19,6 +19,9 @@ const router = express.Router();
|
|
|
19
19
|
|
|
20
20
|
const app = express();
|
|
21
21
|
|
|
22
|
+
const W3C_V1_CREDENTIALS_CONTEXT = 'https://www.w3.org/2018/credentials/v1';
|
|
23
|
+
const W3C_ALT_V1_CREDENTIALS_CONTEXT = 'https://w3.org/2018/credentials/v1';
|
|
24
|
+
|
|
22
25
|
app.use(cors());
|
|
23
26
|
app.use(express.json());
|
|
24
27
|
|
|
@@ -48,11 +51,6 @@ app.delete('/credentials/:id', async (_req: TypedRequest<{}>, res) => {
|
|
|
48
51
|
|
|
49
52
|
app.post('/credentials/issue', async (req: TypedRequest<IssueEndpoint>, res) => {
|
|
50
53
|
try {
|
|
51
|
-
// If incoming credential doesn't have an issuanceDate, default it to right now
|
|
52
|
-
if (req.body?.credential && !('issuanceDate' in (req.body?.credential ?? {}))) {
|
|
53
|
-
req.body.credential.issuanceDate = new Date().toISOString();
|
|
54
|
-
}
|
|
55
|
-
|
|
56
54
|
const validationResult = await IssueEndpointValidator.spa(req.body);
|
|
57
55
|
|
|
58
56
|
if (!validationResult.success) {
|
|
@@ -67,13 +65,28 @@ app.post('/credentials/issue', async (req: TypedRequest<IssueEndpoint>, res) =>
|
|
|
67
65
|
}
|
|
68
66
|
|
|
69
67
|
const validatedBody = validationResult.data;
|
|
68
|
+
const credential = validatedBody.credential as UnsignedVC | undefined;
|
|
69
|
+
|
|
70
|
+
if (!credential) {
|
|
71
|
+
return res.status(400).json('Invalid input: credential is required');
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const context = credential['@context'];
|
|
75
|
+
const isV1Credential = Array.isArray(context)
|
|
76
|
+
? context.some(
|
|
77
|
+
contextEntry =>
|
|
78
|
+
contextEntry === W3C_V1_CREDENTIALS_CONTEXT ||
|
|
79
|
+
contextEntry === W3C_ALT_V1_CREDENTIALS_CONTEXT
|
|
80
|
+
)
|
|
81
|
+
: context === W3C_V1_CREDENTIALS_CONTEXT || context === W3C_ALT_V1_CREDENTIALS_CONTEXT;
|
|
82
|
+
const credentialToIssue =
|
|
83
|
+
isV1Credential && !('issuanceDate' in credential)
|
|
84
|
+
? { ...credential, issuanceDate: new Date().toISOString() }
|
|
85
|
+
: credential;
|
|
70
86
|
const learnCard = await getLearnCard();
|
|
71
87
|
const { credentialStatus, ...options } = validatedBody.options ?? {};
|
|
72
88
|
|
|
73
|
-
const issuedCredential = await learnCard.invoke.issueCredential(
|
|
74
|
-
validatedBody.credential,
|
|
75
|
-
options
|
|
76
|
-
);
|
|
89
|
+
const issuedCredential = await learnCard.invoke.issueCredential(credentialToIssue, options);
|
|
77
90
|
|
|
78
91
|
return res.status(201).json(issuedCredential);
|
|
79
92
|
} catch (error) {
|
|
@@ -119,11 +132,6 @@ app.post('/credentials/verify', async (req: TypedRequest<VerifyCredentialEndpoin
|
|
|
119
132
|
return res.status(400).json(verificationResult);
|
|
120
133
|
}
|
|
121
134
|
|
|
122
|
-
// Pass a test for interop 🙃
|
|
123
|
-
verificationResult.checks = verificationResult.checks.filter(
|
|
124
|
-
check => check !== 'expiration'
|
|
125
|
-
);
|
|
126
|
-
|
|
127
135
|
return res.status(200).json(verificationResult);
|
|
128
136
|
} catch (error) {
|
|
129
137
|
console.error('[/credentials/verify] Caught error: ', error, '(received: ', req.body);
|
|
@@ -265,7 +273,11 @@ app.post('/exchanges/:uri', async (req: TypedRequest<VP, { challenge?: string }>
|
|
|
265
273
|
|
|
266
274
|
const subject = validatedBody.holder;
|
|
267
275
|
|
|
268
|
-
const
|
|
276
|
+
const credentialResult = VCValidator.safeParse(await learnCard.read.get(req.params.uri));
|
|
277
|
+
|
|
278
|
+
if (!credentialResult.success) return res.status(404).json('Credential not found');
|
|
279
|
+
|
|
280
|
+
const credential = credentialResult.data;
|
|
269
281
|
|
|
270
282
|
credential.issuer = {
|
|
271
283
|
...(typeof credential.issuer === 'string' ? {} : credential.issuer),
|
|
@@ -277,9 +289,10 @@ app.post('/exchanges/:uri', async (req: TypedRequest<VP, { challenge?: string }>
|
|
|
277
289
|
credential.credentialSubject.id = subject;
|
|
278
290
|
}
|
|
279
291
|
|
|
280
|
-
|
|
292
|
+
const { proof, ...unsignedCredential } = credential;
|
|
293
|
+
void proof;
|
|
281
294
|
|
|
282
|
-
const newVc = await learnCard.invoke.issueCredential(
|
|
295
|
+
const newVc = await learnCard.invoke.issueCredential(unsignedCredential);
|
|
283
296
|
|
|
284
297
|
return res.status(201).json(newVc);
|
|
285
298
|
} catch (error) {
|
package/src/didkit_wasm_bg.wasm
CHANGED
|
Binary file
|
package/src/learn-card.ts
CHANGED
|
@@ -1,13 +1,32 @@
|
|
|
1
1
|
import fs from 'fs/promises';
|
|
2
|
+
import { existsSync } from 'fs';
|
|
3
|
+
import path from 'path';
|
|
2
4
|
import { initLearnCard, LearnCardFromSeed } from '@learncard/init';
|
|
3
|
-
|
|
5
|
+
|
|
6
|
+
const getBundledDidkitPath = (): string => {
|
|
7
|
+
const siblingPath = path.join(__dirname, 'didkit_wasm_bg.wasm');
|
|
8
|
+
|
|
9
|
+
if (existsSync(siblingPath)) return siblingPath;
|
|
10
|
+
|
|
11
|
+
return path.join(__dirname, 'src', 'didkit_wasm_bg.wasm');
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
let learnCardPromise: Promise<LearnCardFromSeed['returnValue']> | undefined;
|
|
4
15
|
|
|
5
16
|
export const getLearnCard = async (): Promise<LearnCardFromSeed['returnValue']> => {
|
|
17
|
+
if (learnCardPromise) return learnCardPromise;
|
|
18
|
+
|
|
6
19
|
const seed = process.env.WALLET_SEED;
|
|
7
20
|
|
|
8
21
|
if (!seed) {
|
|
9
22
|
throw new Error('No seed set! Please make a .env file and set WALLET_SEED to your seed!');
|
|
10
23
|
}
|
|
11
24
|
|
|
12
|
-
|
|
25
|
+
const didkit = process.env.LOCAL_DIDKIT_PATH
|
|
26
|
+
? fs.readFile(process.env.LOCAL_DIDKIT_PATH)
|
|
27
|
+
: fs.readFile(getBundledDidkitPath());
|
|
28
|
+
|
|
29
|
+
learnCardPromise = initLearnCard({ seed, didkit });
|
|
30
|
+
|
|
31
|
+
return learnCardPromise;
|
|
13
32
|
};
|
package/src/server.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import app from './app';
|
|
2
|
+
|
|
3
|
+
const port = Number(process.env.PORT ?? 3100);
|
|
4
|
+
|
|
5
|
+
const server = app.listen(port, '127.0.0.1', () => {
|
|
6
|
+
console.log(`LearnCard VC API listening at http://127.0.0.1:${port}`);
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
process.on('SIGTERM', () => server.close());
|
|
10
|
+
process.on('SIGINT', () => server.close());
|
package/src/validators.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { z } from 'zod';
|
|
1
|
+
import { z } from 'zod/v4';
|
|
2
2
|
import {
|
|
3
3
|
UnsignedVCValidator,
|
|
4
4
|
UnsignedVPValidator,
|
|
@@ -6,28 +6,42 @@ import {
|
|
|
6
6
|
VPValidator,
|
|
7
7
|
} from '@learncard/types';
|
|
8
8
|
|
|
9
|
+
const ProofOptionsValidator = z
|
|
10
|
+
.object({
|
|
11
|
+
type: z.string().optional(),
|
|
12
|
+
verificationMethod: z.string().optional(),
|
|
13
|
+
proofPurpose: z.string().optional(),
|
|
14
|
+
proofFormat: z.string().optional(),
|
|
15
|
+
created: z.string().optional(),
|
|
16
|
+
challenge: z.string().optional(),
|
|
17
|
+
domain: z.string().optional(),
|
|
18
|
+
cryptosuite: z
|
|
19
|
+
.enum([
|
|
20
|
+
'eddsa-rdfc-2022',
|
|
21
|
+
'eddsa-2022',
|
|
22
|
+
'json-eddsa-2022',
|
|
23
|
+
'ecdsa-2019',
|
|
24
|
+
'jcs-ecdsa-2019',
|
|
25
|
+
])
|
|
26
|
+
.optional(),
|
|
27
|
+
})
|
|
28
|
+
.strict();
|
|
29
|
+
|
|
30
|
+
const VerificationProofOptionsValidator = ProofOptionsValidator.extend({
|
|
31
|
+
checks: z.enum(['proof', 'JWS', 'credentialStatus', 'credentialSchema']).array().optional(),
|
|
32
|
+
});
|
|
33
|
+
|
|
9
34
|
export const IssueEndpointValidator = z.object({
|
|
10
35
|
credential: UnsignedVCValidator,
|
|
11
|
-
options:
|
|
12
|
-
.object({
|
|
13
|
-
|
|
14
|
-
challenge: z.string().optional(),
|
|
15
|
-
domain: z.string().optional(),
|
|
16
|
-
credentialStatus: z.object({ type: z.string() }).optional(),
|
|
17
|
-
})
|
|
18
|
-
.optional(),
|
|
36
|
+
options: ProofOptionsValidator.extend({
|
|
37
|
+
credentialStatus: z.object({ type: z.string() }).optional(),
|
|
38
|
+
}).optional(),
|
|
19
39
|
});
|
|
20
40
|
export type IssueEndpoint = z.infer<typeof IssueEndpointValidator>;
|
|
21
41
|
|
|
22
42
|
export const IssuePresentationEndpointValidator = z.object({
|
|
23
43
|
presentation: UnsignedVPValidator,
|
|
24
|
-
options:
|
|
25
|
-
.object({
|
|
26
|
-
created: z.string().optional(),
|
|
27
|
-
challenge: z.string().optional(),
|
|
28
|
-
domain: z.string().optional(),
|
|
29
|
-
})
|
|
30
|
-
.optional(),
|
|
44
|
+
options: ProofOptionsValidator.optional(),
|
|
31
45
|
});
|
|
32
46
|
export type IssuePresentationEndpoint = z.infer<typeof IssuePresentationEndpointValidator>;
|
|
33
47
|
|
|
@@ -42,18 +56,14 @@ export type UpdateStatusEndpoint = z.infer<typeof UpdateStatusEndpointValidator>
|
|
|
42
56
|
|
|
43
57
|
export const VerifyCredentialEndpointValidator = z.object({
|
|
44
58
|
verifiableCredential: VCValidator,
|
|
45
|
-
options:
|
|
46
|
-
.object({ challenge: z.string().optional(), domain: z.string().optional() })
|
|
47
|
-
.optional(),
|
|
59
|
+
options: VerificationProofOptionsValidator.optional(),
|
|
48
60
|
});
|
|
49
61
|
export type VerifyCredentialEndpoint = z.infer<typeof VerifyCredentialEndpointValidator>;
|
|
50
62
|
|
|
51
63
|
export const VerifyPresentationEndpointValidator = z
|
|
52
64
|
.object({
|
|
53
65
|
verifiablePresentation: VPValidator,
|
|
54
|
-
options:
|
|
55
|
-
.object({ challenge: z.string().optional(), domain: z.string().optional() })
|
|
56
|
-
.optional(),
|
|
66
|
+
options: VerificationProofOptionsValidator.optional(),
|
|
57
67
|
})
|
|
58
68
|
.or(z.object({ presentation: UnsignedVPValidator }));
|
|
59
69
|
export type VerifyPresentationEndpoint = z.infer<typeof VerifyPresentationEndpointValidator>;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
const baseUrl = process.env.BASE_URL || 'http://127.0.0.1:3100';
|
|
2
|
+
|
|
3
|
+
module.exports = {
|
|
4
|
+
settings: {
|
|
5
|
+
enableInteropTests: false,
|
|
6
|
+
testAllImplementations: false,
|
|
7
|
+
},
|
|
8
|
+
implementations: [
|
|
9
|
+
{
|
|
10
|
+
name: 'Learning Economy Foundation',
|
|
11
|
+
implementation: 'LearnCard DIDKit',
|
|
12
|
+
issuers: [
|
|
13
|
+
{
|
|
14
|
+
id: 'did:key:z6Mkv1o2GEgtXjFdEMfLtupcKhGRydM8V7VHzii7Uh4aHoqH',
|
|
15
|
+
endpoint: `${baseUrl}/credentials/issue`,
|
|
16
|
+
options: {
|
|
17
|
+
type: 'DataIntegrityProof',
|
|
18
|
+
cryptosuite: 'eddsa-rdfc-2022',
|
|
19
|
+
},
|
|
20
|
+
supports: {
|
|
21
|
+
vc: ['1.1', '2.0'],
|
|
22
|
+
},
|
|
23
|
+
tags: ['eddsa-rdfc-2022', 'localhost'],
|
|
24
|
+
},
|
|
25
|
+
],
|
|
26
|
+
verifiers: [
|
|
27
|
+
{
|
|
28
|
+
id: 'did:key:z6Mkv1o2GEgtXjFdEMfLtupcKhGRydM8V7VHzii7Uh4aHoqH',
|
|
29
|
+
endpoint: `${baseUrl}/credentials/verify`,
|
|
30
|
+
tags: ['eddsa-rdfc-2022', 'localhost'],
|
|
31
|
+
},
|
|
32
|
+
],
|
|
33
|
+
},
|
|
34
|
+
],
|
|
35
|
+
};
|
package/esbuildWasmPlugin.cjs
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
const wasmPlugin = {
|
|
2
|
-
name: 'wasm',
|
|
3
|
-
setup(build) {
|
|
4
|
-
let path = require('path');
|
|
5
|
-
let fs = require('fs');
|
|
6
|
-
|
|
7
|
-
// Resolve ".wasm" files to a path with a namespace
|
|
8
|
-
build.onResolve({ filter: /\.wasm$/ }, args => {
|
|
9
|
-
if (args.resolveDir === '') {
|
|
10
|
-
return; // Ignore unresolvable paths
|
|
11
|
-
}
|
|
12
|
-
return {
|
|
13
|
-
path: path.isAbsolute(args.path)
|
|
14
|
-
? args.path
|
|
15
|
-
: path.join(args.resolveDir, args.path),
|
|
16
|
-
namespace: 'wasm-binary',
|
|
17
|
-
};
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
// Virtual modules in the "wasm-binary" namespace contain the
|
|
21
|
-
// actual bytes of the WebAssembly file. This uses esbuild's
|
|
22
|
-
// built-in "binary" loader instead of manually embedding the
|
|
23
|
-
// binary data inside JavaScript code ourselves.
|
|
24
|
-
build.onLoad({ filter: /.*/, namespace: 'wasm-binary' }, async args => ({
|
|
25
|
-
contents: await fs.promises.readFile(args.path),
|
|
26
|
-
loader: 'binary',
|
|
27
|
-
}));
|
|
28
|
-
},
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
module.exports = [wasmPlugin];
|