Skip to content

Commit efbb77a

Browse files
Merge pull request #5 from AmeyParle/main
Improve JS examples and add HTTP DID resolution example
2 parents 427b517 + be5245d commit efbb77a

File tree

6 files changed

+130
-71
lines changed

6 files changed

+130
-71
lines changed

examples/README.md

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,36 @@
11
# TRAIL Protocol - Examples
22

3-
Working examples demonstrating how to use the `did:trail` DID method in practice.
3+
This directory contains practical examples for working with the `did:trail` DID method.
44

55
## Sample DID Documents
66

77
| File | Description |
88
|------|-------------|
9-
| `self-did-document.json` | Self-issued DID (Tier 0) - no registry, local trust only |
10-
| `org-did-document.json` | Organization DID with KYB attestation (Tier 1) |
11-
| `agent-did-document.json` | AI Agent DID with full trust chain (Tier 2) |
9+
| `self-did-document.json` | Example self-mode DID Document |
10+
| `org-did-document.json` | Example organization DID Document |
11+
| `agent-did-document.json` | Example agent DID Document |
1212

1313
## Code Examples
1414

15-
> Coming soon - contributions welcome! See [Issue #4](https://github.com/trailprotocol/trail-did-method/issues/4).
15+
The JavaScript examples live in [`examples/js/`](./js/) and demonstrate:
1616

17-
Planned examples:
17+
- DID generation in `self`, `org`, and `agent` modes
18+
- DID Document creation
19+
- local/offline resolution for `did:trail:self`
20+
- Verifiable Credential issuance and verification
21+
- tamper detection using `DataIntegrityProof`
1822

19-
- **JavaScript/Node.js** - DID resolution, VC verification
20-
- More languages welcome via PR
23+
See [`examples/js/README.md`](./js/README.md) for setup instructions and how to run the scripts.
2124

2225
## Reference Implementation
2326

24-
The [`@trailprotocol/core`](https://www.npmjs.com/package/@trailprotocol/core) npm package provides the full reference implementation:
27+
The [`@trailprotocol/core`](https://www.npmjs.com/package/@trailprotocol/core) npm package provides the reference implementation for:
2528

2629
- DID generation and resolution
2730
- JSON Canonicalization (JCS, RFC 8785)
2831
- DataIntegrityProof (`eddsa-jcs-2023`)
2932
- Verifiable Credential issuance and verification
3033

31-
```bash
32-
npm install @trailprotocol/core
33-
```
34-
3534
## Contributing
3635

37-
See [CONTRIBUTING.md](../CONTRIBUTING.md) for guidelines. `examples/` is a great entry point for first-time contributors.
36+
See [CONTRIBUTING.md](../CONTRIBUTING.md) for guidelines. The `examples/` directory is a good entry point for first-time contributors.

examples/js/README.md

Lines changed: 45 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,72 @@
11
# TRAIL Protocol - JavaScript Examples
22

3-
Working examples showing how to use `did:trail` with Node.js.
3+
This directory contains runnable JavaScript examples for the `did:trail` DID method using the `@trailprotocol/core` reference implementation.
44

55
## Prerequisites
66

7-
- Node.js 18+ (uses built-in `crypto` module)
7+
- Node.js 18 or newer
88
- npm
99

1010
## Setup
1111

12+
From this directory:
13+
1214
```bash
13-
cd examples/js
1415
npm install
1516
```
1617

17-
## Examples
18+
## Run the examples
19+
20+
### DID resolution example
1821

19-
### DID Resolution (`did-resolution.js`)
22+
```bash
23+
npm run did-resolution
24+
```
2025

21-
Creates DIDs in all three modes (self, org, agent), builds DID Documents, and resolves a self-issued DID offline.
26+
This script demonstrates:
27+
28+
- generating an Ed25519 keypair
29+
- creating `did:trail:self`, `did:trail:org`, and `did:trail:agent` identifiers
30+
- building DID Documents
31+
- resolving a `did:trail:self` DID locally, without contacting a registry
32+
33+
### Verifiable Credential example
2234

2335
```bash
24-
node did-resolution.js
36+
npm run vc-verification
2537
```
2638

27-
**What you'll learn:**
28-
- Ed25519 keypair generation
29-
- The three DID modes and their trust tiers
30-
- DID Document structure (W3C DID Core 1.0)
31-
- Offline resolution for self-mode DIDs
39+
This script demonstrates:
40+
41+
- issuing a self-signed Verifiable Credential
42+
- inspecting the `DataIntegrityProof`
43+
- verifying the credential signature
44+
- detecting tampering by modifying a signed field and verifying again
3245

33-
### VC Verification (`vc-verification.js`)
46+
Note: the tampered credential is expected to fail verification because the proof no longer matches the modified credential contents.
3447

35-
Issues a self-signed Verifiable Credential with a DataIntegrityProof, then verifies it - including a tamper detection test.
48+
### HTTP registry resolution example
3649

3750
```bash
38-
node vc-verification.js
51+
npm run resolve-http
3952
```
4053

41-
**What you'll learn:**
42-
- Verifiable Credentials 2.0 structure
43-
- DataIntegrityProof with `eddsa-jcs-2023` cryptosuite
44-
- JSON Canonicalization (JCS, RFC 8785)
45-
- Cryptographic verification and tamper detection
54+
Or with a custom DID:
55+
56+
```bash
57+
bash resolve-http.sh "did:trail:org:acme-corp-eu-a7f3b2c1e9d04f5a"
58+
```
59+
60+
This demonstrates the HTTP resolution pattern for registry-backed `did:trail` identifiers.
61+
62+
Note: The HTTP resolution example documents the expected API pattern. Live responses require a running TRAIL registry instance (public registry coming soon).
63+
64+
## Package metadata
65+
66+
The local `package.json` defines:
4667

47-
## Reference
68+
- `npm run did-resolution`
69+
- `npm run vc-verification`
70+
- `npm run resolve-http`
4871

49-
- [`@trailprotocol/core`](https://www.npmjs.com/package/@trailprotocol/core) - Full API reference
50-
- [TRAIL DID Method Spec](../../did-method-spec.md) - Specification v1.1.0
51-
- [CONTRIBUTING.md](../../CONTRIBUTING.md) - How to contribute
72+
and requires Node.js `>=18.0.0`.

examples/js/did-resolution.js

Lines changed: 22 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@
55
*
66
* Demonstrates how to:
77
* 1. Generate an Ed25519 keypair
8-
* 2. Create did:trail DIDs (self, org, agent)
8+
* 2. Create did:trail DIDs in self, org, and agent modes
99
* 3. Build DID Documents
10-
* 4. Resolve a did:trail DID offline (self-mode)
10+
* 4. Resolve a did:trail:self DID locally (offline)
1111
*
1212
* Prerequisites:
1313
* npm install @trailprotocol/core
@@ -29,42 +29,46 @@ async function main() {
2929
// -------------------------------------------------------
3030
// Step 1: Generate an Ed25519 keypair
3131
// -------------------------------------------------------
32+
// This keypair is the cryptographic root of the DID identity.
3233
const keys = generateKeyPair();
3334
console.log('=== Key Generation ===');
3435
console.log('Public key (multibase):', keys.publicKeyMultibase);
3536
console.log('Public key (JWK):', JSON.stringify(keys.publicKeyJwk, null, 2));
3637
console.log();
3738

3839
// -------------------------------------------------------
39-
// Step 2: Create DIDs in all three modes
40+
// Step 2: Create DIDs in all three TRAIL modes
4041
// -------------------------------------------------------
41-
42-
// Self DID (Tier 0) - no registry needed, local trust only
4342
const selfDid = createSelfDid(keys.publicKeyMultibase);
43+
const orgDid = createOrgDid('Acme Corporation', keys.publicKeyMultibase);
44+
const agentDid = createAgentDid('Sales Assistant', keys.publicKeyMultibase);
45+
4446
console.log('=== DID Creation ===');
4547
console.log('Self DID: ', selfDid);
46-
47-
// Org DID (Tier 1) - for organizations with KYB attestation
48-
const orgDid = createOrgDid('Acme Corporation', keys.publicKeyMultibase);
4948
console.log('Org DID: ', orgDid);
50-
51-
// Agent DID (Tier 2) - for AI agents with full trust chain
52-
const agentDid = createAgentDid('Sales Assistant', keys.publicKeyMultibase);
5349
console.log('Agent DID:', agentDid);
5450
console.log();
5551

52+
console.log('Mode summary:');
53+
console.log(' self -> local/offline identity using embedded public key');
54+
console.log(' org -> organization identifier format for registry-backed use');
55+
console.log(' agent -> agent/service identifier format, typically linked to a parent org');
56+
console.log();
57+
5658
// -------------------------------------------------------
5759
// Step 3: Build DID Documents
5860
// -------------------------------------------------------
61+
// A DID Document describes the public keys, verification methods,
62+
// and optional services associated with a DID.
5963
console.log('=== DID Documents ===');
6064

61-
// Self DID Document - simplest form
65+
// Self DID Document: simplest form, suitable for local/offline verification.
6266
const selfDoc = createDidDocument(selfDid, keys, { mode: 'self' });
6367
console.log('Self DID Document:');
6468
console.log(JSON.stringify(selfDoc, null, 2));
6569
console.log();
6670

67-
// Agent DID Document - with parent organization reference
71+
// Agent DID Document: includes a parent organization reference and registry service.
6872
const agentDoc = createDidDocument(agentDid, keys, {
6973
mode: 'agent',
7074
parentOrganization: orgDid,
@@ -77,8 +81,8 @@ async function main() {
7781
// -------------------------------------------------------
7882
// Step 4: Resolve a self DID (offline resolution)
7983
// -------------------------------------------------------
80-
// Self-mode DIDs can be resolved without a registry because
81-
// the public key is embedded in the DID itself.
84+
// Self-mode DIDs can be resolved without a registry because the
85+
// public key is embedded directly in the DID identifier.
8286
console.log('=== DID Resolution ===');
8387
const resolver = new TrailResolver();
8488
const result = await resolver.resolve(selfDid);
@@ -90,10 +94,9 @@ async function main() {
9094
console.log(' Trust Tier:', result.didDocument['trail:trailTrustTier']);
9195
console.log();
9296

93-
// TODO: Add registry-based resolution for org/agent DIDs
94-
// (requires a running TRAIL Registry instance)
95-
97+
// Registry-based resolution for org/agent DIDs is typically performed
98+
// via the TRAIL registry HTTP API rather than offline reconstruction.
9699
console.log('Done. All examples completed successfully.');
97100
}
98101

99-
main().catch(console.error);
102+
main().catch(console.error);

examples/js/package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,13 @@
55
"description": "TRAIL Protocol usage examples for Node.js",
66
"scripts": {
77
"did-resolution": "node did-resolution.js",
8-
"vc-verification": "node vc-verification.js"
8+
"vc-verification": "node vc-verification.js",
9+
"resolve-http": "bash resolve-http.sh"
910
},
1011
"dependencies": {
1112
"@trailprotocol/core": "^0.1.0"
1213
},
1314
"engines": {
1415
"node": ">=18.0.0"
1516
}
16-
}
17+
}

examples/js/resolve-http.sh

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
#!/usr/bin/env bash
2+
3+
# TRAIL Protocol - curl/HTTP DID Resolution Example
4+
#
5+
# Demonstrates the HTTP resolution pattern for registry-backed
6+
# did:trail identifiers (typically org/agent mode).
7+
#
8+
# Usage:
9+
# ./resolve-http.sh "did:trail:org:acme-corp-eu-a7f3b2c1e9d04f5a"
10+
11+
# Note:
12+
# This example demonstrates the expected HTTP request format for
13+
# registry-backed DID resolution. A successful live response depends
14+
# on the public registry endpoint being reachable from your environment.
15+
16+
17+
set -euo pipefail
18+
19+
DID="${1:-did:trail:org:acme-corp-eu-a7f3b2c1e9d04f5a}"
20+
BASE_URL="https://registry.trailprotocol.org/1.0/identifiers"
21+
22+
echo "Resolving DID via TRAIL registry API..."
23+
echo "DID: $DID"
24+
echo
25+
26+
curl -sS \
27+
-H "Accept: application/did+ld+json" \
28+
"${BASE_URL}/${DID}"
29+
30+
echo

examples/js/vc-verification.js

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* 1. Create a self-signed Verifiable Credential (VC 2.0)
88
* 2. Inspect the DataIntegrityProof (eddsa-jcs-2023)
99
* 3. Verify the credential cryptographically
10-
* 4. Detect tampering (negative test)
10+
* 4. Detect tampering with a negative test
1111
*
1212
* Prerequisites:
1313
* npm install @trailprotocol/core
@@ -39,12 +39,12 @@ async function main() {
3939
// -------------------------------------------------------
4040
// createSelfSignedCredential(issuerDid, subjectDid, claims, privateKeyBytes)
4141
//
42-
// This creates a VC 2.0 credential with a DataIntegrityProof
43-
// using the eddsa-jcs-2023 cryptosuite (Ed25519 + JCS RFC 8785).
44-
// For self-signed VCs, issuer and subject are the same DID.
42+
// This creates a VC with a DataIntegrityProof using the
43+
// eddsa-jcs-2023 cryptosuite (Ed25519 + JCS canonicalization).
44+
// In this example, issuer and subject are the same DID.
4545
const credential = createSelfSignedCredential(
4646
issuerDid,
47-
issuerDid, // subject = issuer (self-signed)
47+
issuerDid,
4848
{
4949
type: 'TrailTrustAttestation',
5050
aiSystemType: 'agent',
@@ -72,23 +72,28 @@ async function main() {
7272
// -------------------------------------------------------
7373
// Step 4: Verify the credential
7474
// -------------------------------------------------------
75-
// verifyCredential(vc, publicKeyBytes) checks:
76-
// - Required VC fields (@context, type, issuer, issuanceDate, credentialSubject)
77-
// - DataIntegrityProof signature validity
75+
// verifyCredential(vc, publicKeyBytes) checks required VC fields
76+
// and verifies the DataIntegrityProof signature.
7877
console.log('=== Verification ===');
7978
const result = verifyCredential(credential, issuerKeys.publicKeyBytes);
8079
console.log('Credential valid:', result.valid);
8180
console.log('Errors:', result.errors.length === 0 ? 'none' : result.errors);
8281
console.log();
8382

83+
console.log('Verification summary:');
84+
console.log(' A valid credential passes signature verification.');
85+
console.log(' Any change to signed content should invalidate the proof.');
86+
console.log();
87+
8488
// -------------------------------------------------------
8589
// Step 5: Tamper detection (negative test)
8690
// -------------------------------------------------------
87-
// Modify the credential and verify again - should fail
88-
// because the signature no longer matches the content.
91+
// This simulates someone modifying a signed field after issuance.
92+
// Because the proof was created over the original credential
93+
// contents, verification should now fail.
8994
console.log('=== Tamper Detection ===');
9095
const tampered = JSON.parse(JSON.stringify(credential));
91-
tampered.credentialSubject.trailTrustTier = 2; // Attacker tries to upgrade trust tier
96+
tampered.credentialSubject.trailTrustTier = 2;
9297

9398
const tamperedResult = verifyCredential(tampered, issuerKeys.publicKeyBytes);
9499
console.log('Tampered credential valid:', tamperedResult.valid, '(expected: false)');
@@ -98,4 +103,4 @@ async function main() {
98103
console.log('Done. All examples completed successfully.');
99104
}
100105

101-
main().catch(console.error);
106+
main().catch(console.error);

0 commit comments

Comments
 (0)