signet-protocol 1.11.1 → 1.11.2
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/README.md +8 -1
- package/docs/bot-ownership-v1.md +43 -0
- package/docs/implementation-levels.md +235 -0
- package/docs/private-vault-v1.md +104 -0
- package/docs/signet-in-5-minutes.md +181 -0
- package/examples/full-flow.ts +260 -0
- package/examples/jurisdictions/brazil-lawyer.ts +186 -0
- package/examples/jurisdictions/eu-doctor.ts +160 -0
- package/examples/jurisdictions/india-doctor.ts +207 -0
- package/examples/jurisdictions/japan-notary.ts +157 -0
- package/examples/jurisdictions/multi-jurisdiction.ts +174 -0
- package/examples/jurisdictions/uae-professional.ts +190 -0
- package/examples/jurisdictions/uk-solicitor.ts +170 -0
- package/examples/jurisdictions/us-attorney.ts +161 -0
- package/examples/signet-me.ts +253 -0
- package/llms-full.txt +51 -20
- package/llms.txt +29 -11
- package/package.json +7 -1
- package/spec/protocol.md +2628 -0
- package/spec/voting.md +563 -0
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
// Signet Protocol — Indian Doctor Example
|
|
2
|
+
// Demonstrates identity verification under DPDPA 2023
|
|
3
|
+
// Jurisdiction: India (IN)
|
|
4
|
+
// Profession: Doctor regulated by the National Medical Commission (NMC)
|
|
5
|
+
// Features: DPDPA compliance, cross-border considerations, Hindi + English bilingual
|
|
6
|
+
|
|
7
|
+
import {
|
|
8
|
+
generateKeyPair,
|
|
9
|
+
getJurisdiction,
|
|
10
|
+
getProfessionalBodies,
|
|
11
|
+
getMutualRecognitionPartners,
|
|
12
|
+
createProfessionalCredential,
|
|
13
|
+
verifyCredential,
|
|
14
|
+
parseCredential,
|
|
15
|
+
checkCredentialCompliance,
|
|
16
|
+
checkCrossBorderCompliance,
|
|
17
|
+
checkChildCompliance,
|
|
18
|
+
getConsentRequirements,
|
|
19
|
+
setLanguage,
|
|
20
|
+
t,
|
|
21
|
+
getTierDescription,
|
|
22
|
+
formatLocalizedTrustScore,
|
|
23
|
+
computeTrustScore,
|
|
24
|
+
} from '../../src/index.js';
|
|
25
|
+
|
|
26
|
+
async function main() {
|
|
27
|
+
console.log('=== Signet Protocol — Indian Doctor Verification ===\n');
|
|
28
|
+
|
|
29
|
+
// --- 1. Jurisdiction and NMC lookup ---
|
|
30
|
+
const india = getJurisdiction('IN');
|
|
31
|
+
if (!india) throw new Error('IN jurisdiction not found');
|
|
32
|
+
|
|
33
|
+
// Hindi output first
|
|
34
|
+
setLanguage('hi');
|
|
35
|
+
console.log(`[Hindi] ${t('credential_professional')}`);
|
|
36
|
+
console.log(getTierDescription(3));
|
|
37
|
+
console.log();
|
|
38
|
+
|
|
39
|
+
// Switch to English for detailed output
|
|
40
|
+
setLanguage('en');
|
|
41
|
+
console.log(`Jurisdiction: ${india.name} (${india.nameLocal})`);
|
|
42
|
+
console.log(`Legal system: ${india.legalSystem}`);
|
|
43
|
+
console.log(`Data protection: ${india.dataProtection.name} - ${india.dataProtection.fullName}`);
|
|
44
|
+
console.log(`Year enacted: ${india.dataProtection.year}`);
|
|
45
|
+
console.log(`Supervisory authority: ${india.dataProtection.supervisoryAuthority}`);
|
|
46
|
+
if (india.dataProtection.notes) {
|
|
47
|
+
console.log(`Note: ${india.dataProtection.notes}`);
|
|
48
|
+
}
|
|
49
|
+
if (india.notes) {
|
|
50
|
+
console.log(`Additional: ${india.notes}`);
|
|
51
|
+
}
|
|
52
|
+
console.log();
|
|
53
|
+
|
|
54
|
+
// Look up the National Medical Commission
|
|
55
|
+
// NMC replaced the Medical Council of India in 2020
|
|
56
|
+
const medicalBodies = getProfessionalBodies('IN', 'medical');
|
|
57
|
+
console.log('Medical professional bodies in India:');
|
|
58
|
+
for (const body of medicalBodies) {
|
|
59
|
+
console.log(` - ${body.name}`);
|
|
60
|
+
console.log(` Website: ${body.website}`);
|
|
61
|
+
console.log(` Public register: ${body.hasPublicRegister}`);
|
|
62
|
+
if (body.registerUrl) {
|
|
63
|
+
console.log(` Register URL: ${body.registerUrl}`);
|
|
64
|
+
}
|
|
65
|
+
if (body.notes) {
|
|
66
|
+
console.log(` Note: ${body.notes}`);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
console.log();
|
|
70
|
+
|
|
71
|
+
// --- 2. Generate identities ---
|
|
72
|
+
const doctor = generateKeyPair(); // The verifying doctor
|
|
73
|
+
const patient = generateKeyPair(); // Person being verified
|
|
74
|
+
|
|
75
|
+
// --- 3. Create Tier 3 credential ---
|
|
76
|
+
// Under DPDPA 2023, explicit consent is required before processing personal data.
|
|
77
|
+
// India's Aadhaar system provides national digital identity infrastructure.
|
|
78
|
+
console.log('--- Tier 3: Professional Verification ---');
|
|
79
|
+
console.log(getTierDescription(3));
|
|
80
|
+
console.log();
|
|
81
|
+
|
|
82
|
+
const credential = await createProfessionalCredential(
|
|
83
|
+
doctor.privateKey,
|
|
84
|
+
patient.publicKey,
|
|
85
|
+
{
|
|
86
|
+
profession: 'doctor',
|
|
87
|
+
jurisdiction: 'IN',
|
|
88
|
+
}
|
|
89
|
+
);
|
|
90
|
+
|
|
91
|
+
const verification = await verifyCredential(credential);
|
|
92
|
+
const parsed = parseCredential(credential)!;
|
|
93
|
+
|
|
94
|
+
// English output
|
|
95
|
+
console.log(`[English] ${t('credential_professional')}: ${t('status_valid')}`);
|
|
96
|
+
console.log(` Signature valid: ${verification.signatureValid}`);
|
|
97
|
+
console.log(` Tier: ${parsed.tier}, Profession: ${parsed.profession}`);
|
|
98
|
+
console.log(` Jurisdiction: ${parsed.jurisdiction}`);
|
|
99
|
+
console.log();
|
|
100
|
+
|
|
101
|
+
// Hindi output
|
|
102
|
+
setLanguage('hi');
|
|
103
|
+
console.log(`[Hindi] ${t('credential_professional')}: ${t('status_valid')}`);
|
|
104
|
+
console.log(` ${t('msg_signature_valid')}`);
|
|
105
|
+
console.log();
|
|
106
|
+
|
|
107
|
+
setLanguage('en');
|
|
108
|
+
|
|
109
|
+
// --- 4. DPDPA 2023 compliance check ---
|
|
110
|
+
// The DPDPA 2023 replaces the IT Act 2000 data protection provisions.
|
|
111
|
+
// Full enforcement is still pending — rules are being phased in.
|
|
112
|
+
console.log('--- DPDPA 2023 Compliance Check ---');
|
|
113
|
+
const compliance = checkCredentialCompliance(credential, 'IN');
|
|
114
|
+
console.log(`Compliant: ${compliance.compliant}`);
|
|
115
|
+
|
|
116
|
+
for (const issue of compliance.issues) {
|
|
117
|
+
const prefix = issue.severity === 'error' ? '[ERROR]'
|
|
118
|
+
: issue.severity === 'warning' ? '[WARN]'
|
|
119
|
+
: '[INFO]';
|
|
120
|
+
console.log(` ${prefix} ${issue.message}`);
|
|
121
|
+
console.log(` Regulation: ${issue.regulation}`);
|
|
122
|
+
if (issue.remediation) {
|
|
123
|
+
console.log(` Remediation: ${issue.remediation}`);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
console.log();
|
|
127
|
+
|
|
128
|
+
// --- 5. Cross-border considerations ---
|
|
129
|
+
// DPDPA 2023 may restrict transfers to certain jurisdictions via government
|
|
130
|
+
// notification. India has mutual recognition with Singapore and the UK.
|
|
131
|
+
console.log('--- Cross-border: IN -> SG ---');
|
|
132
|
+
const inToSg = checkCrossBorderCompliance('IN', 'SG');
|
|
133
|
+
console.log(`Allowed: ${inToSg.allowed}`);
|
|
134
|
+
if (inToSg.mechanism) {
|
|
135
|
+
console.log(`Mechanism: ${inToSg.mechanism}`);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
for (const issue of inToSg.issues) {
|
|
139
|
+
console.log(` [${issue.severity.toUpperCase()}] ${issue.message}`);
|
|
140
|
+
if (issue.remediation) {
|
|
141
|
+
console.log(` Remediation: ${issue.remediation}`);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
console.log();
|
|
145
|
+
|
|
146
|
+
console.log('--- Cross-border: IN -> GB ---');
|
|
147
|
+
const inToGb = checkCrossBorderCompliance('IN', 'GB');
|
|
148
|
+
console.log(`Allowed: ${inToGb.allowed}`);
|
|
149
|
+
if (inToGb.mechanism) {
|
|
150
|
+
console.log(`Mechanism: ${inToGb.mechanism}`);
|
|
151
|
+
}
|
|
152
|
+
for (const issue of inToGb.issues) {
|
|
153
|
+
console.log(` [${issue.severity.toUpperCase()}] ${issue.message}`);
|
|
154
|
+
}
|
|
155
|
+
console.log();
|
|
156
|
+
|
|
157
|
+
// Mutual recognition partners
|
|
158
|
+
const partners = getMutualRecognitionPartners('IN');
|
|
159
|
+
console.log(`Mutual recognition partners: ${partners.join(', ')}`);
|
|
160
|
+
console.log();
|
|
161
|
+
|
|
162
|
+
// --- 6. Child compliance under DPDPA 2023 + POCSO ---
|
|
163
|
+
// India's digital consent age is 18 — the highest among major jurisdictions.
|
|
164
|
+
// This means ALL minors require parental consent for data processing.
|
|
165
|
+
console.log('--- Child Compliance (age 16, IN) ---');
|
|
166
|
+
const childCompliance = checkChildCompliance(16, 'IN');
|
|
167
|
+
console.log(`Compliant: ${childCompliance.compliant}`);
|
|
168
|
+
console.log(`Min consent age: ${childCompliance.minConsentAge} (one of the highest globally)`);
|
|
169
|
+
console.log(`Age of majority: ${childCompliance.ageOfMajority}`);
|
|
170
|
+
console.log(`Parental consent required: ${childCompliance.requiresParentalConsent}`);
|
|
171
|
+
|
|
172
|
+
for (const issue of childCompliance.issues) {
|
|
173
|
+
const prefix = issue.severity === 'error' ? '[ERROR]'
|
|
174
|
+
: issue.severity === 'warning' ? '[WARN]'
|
|
175
|
+
: '[INFO]';
|
|
176
|
+
console.log(` ${prefix} ${issue.message}`);
|
|
177
|
+
}
|
|
178
|
+
console.log();
|
|
179
|
+
|
|
180
|
+
// --- 7. Consent requirements ---
|
|
181
|
+
console.log('--- Consent Requirements ---');
|
|
182
|
+
const consent = getConsentRequirements('IN');
|
|
183
|
+
console.log(`Explicit consent required: ${consent.requiresExplicitConsent}`);
|
|
184
|
+
console.log(`Digital consent age: ${consent.consentAge}`);
|
|
185
|
+
console.log(`Data categories: ${consent.dataCategories.join(', ')}`);
|
|
186
|
+
console.log();
|
|
187
|
+
|
|
188
|
+
// --- 8. Signet IQ (bilingual) ---
|
|
189
|
+
setLanguage('en');
|
|
190
|
+
console.log(`--- [English] ${t('msg_signet_iq')} ---`);
|
|
191
|
+
const trustScore = computeTrustScore(
|
|
192
|
+
patient.publicKey,
|
|
193
|
+
[credential],
|
|
194
|
+
[],
|
|
195
|
+
Math.floor(Date.now() / 1000) - 365 * 24 * 60 * 60
|
|
196
|
+
);
|
|
197
|
+
console.log(formatLocalizedTrustScore(trustScore.score));
|
|
198
|
+
console.log();
|
|
199
|
+
|
|
200
|
+
setLanguage('hi');
|
|
201
|
+
console.log(`--- [Hindi] ${t('msg_signet_iq')} ---`);
|
|
202
|
+
console.log(formatLocalizedTrustScore(trustScore.score));
|
|
203
|
+
|
|
204
|
+
console.log('\n=== Indian Doctor Example Complete ===');
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
main().catch(console.error);
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
// Signet Protocol — Japanese Notary Example
|
|
2
|
+
// Demonstrates identity verification under APPI (Act on the Protection of Personal Information)
|
|
3
|
+
// Jurisdiction: Japan (JP)
|
|
4
|
+
// Profession: Notary regulated by the Japan National Notaries Association
|
|
5
|
+
// Features: APPI compliance, cross-border transfer to Korea (adequacy), Japanese output
|
|
6
|
+
|
|
7
|
+
import {
|
|
8
|
+
generateKeyPair,
|
|
9
|
+
getJurisdiction,
|
|
10
|
+
getProfessionalBodies,
|
|
11
|
+
getMutualRecognitionPartners,
|
|
12
|
+
createProfessionalCredential,
|
|
13
|
+
verifyCredential,
|
|
14
|
+
parseCredential,
|
|
15
|
+
checkCredentialCompliance,
|
|
16
|
+
checkCrossBorderCompliance,
|
|
17
|
+
checkChildCompliance,
|
|
18
|
+
getConsentRequirements,
|
|
19
|
+
setLanguage,
|
|
20
|
+
t,
|
|
21
|
+
getTierDescription,
|
|
22
|
+
formatLocalizedTrustScore,
|
|
23
|
+
computeTrustScore,
|
|
24
|
+
} from '../../src/index.js';
|
|
25
|
+
|
|
26
|
+
async function main() {
|
|
27
|
+
console.log('=== Signet Protocol -- Japanese Notary Verification ===\n');
|
|
28
|
+
|
|
29
|
+
// Set language to Japanese
|
|
30
|
+
setLanguage('ja');
|
|
31
|
+
|
|
32
|
+
// --- 1. Jurisdiction and professional body lookup ---
|
|
33
|
+
const jp = getJurisdiction('JP');
|
|
34
|
+
if (!jp) throw new Error('JP jurisdiction not found');
|
|
35
|
+
|
|
36
|
+
console.log(`[JP] ${jp.nameLocal} (${jp.name})`);
|
|
37
|
+
console.log(`Legal system: ${jp.legalSystem}`);
|
|
38
|
+
console.log(`Data protection: ${jp.dataProtection.name} - ${jp.dataProtection.fullName}`);
|
|
39
|
+
console.log(`Supervisory authority: ${jp.dataProtection.supervisoryAuthority}`);
|
|
40
|
+
if (jp.dataProtection.notes) {
|
|
41
|
+
console.log(`Note: ${jp.dataProtection.notes}`);
|
|
42
|
+
}
|
|
43
|
+
console.log();
|
|
44
|
+
|
|
45
|
+
// Look up the Japan National Notaries Association
|
|
46
|
+
const notaryBodies = getProfessionalBodies('JP', 'notary');
|
|
47
|
+
console.log('Notary professional bodies:');
|
|
48
|
+
for (const body of notaryBodies) {
|
|
49
|
+
console.log(` - ${body.name}`);
|
|
50
|
+
if (body.nameEn) console.log(` (${body.nameEn})`);
|
|
51
|
+
console.log(` Website: ${body.website}`);
|
|
52
|
+
console.log(` Public register: ${body.hasPublicRegister}`);
|
|
53
|
+
}
|
|
54
|
+
console.log();
|
|
55
|
+
|
|
56
|
+
// --- 2. Generate identities ---
|
|
57
|
+
const notary = generateKeyPair(); // The verifying notary
|
|
58
|
+
const subject = generateKeyPair(); // Person being verified
|
|
59
|
+
|
|
60
|
+
// --- 3. Create Tier 3 credential (Japanese output) ---
|
|
61
|
+
console.log(`--- ${t('tier_3')}: ${t('credential_professional')} ---`);
|
|
62
|
+
console.log(getTierDescription(3));
|
|
63
|
+
console.log();
|
|
64
|
+
|
|
65
|
+
const credential = await createProfessionalCredential(
|
|
66
|
+
notary.privateKey,
|
|
67
|
+
subject.publicKey,
|
|
68
|
+
{
|
|
69
|
+
profession: 'notary',
|
|
70
|
+
jurisdiction: 'JP',
|
|
71
|
+
}
|
|
72
|
+
);
|
|
73
|
+
|
|
74
|
+
const verification = await verifyCredential(credential);
|
|
75
|
+
const parsed = parseCredential(credential)!;
|
|
76
|
+
|
|
77
|
+
console.log(`${t('credential_professional')}: ${t('status_valid')}`);
|
|
78
|
+
console.log(` ${t('msg_signature_valid')}`);
|
|
79
|
+
console.log(` Tier: ${parsed.tier}, Profession: ${parsed.profession}`);
|
|
80
|
+
console.log(` Jurisdiction: ${parsed.jurisdiction}`);
|
|
81
|
+
console.log();
|
|
82
|
+
|
|
83
|
+
// --- 4. APPI compliance check ---
|
|
84
|
+
// Japan's APPI was significantly amended in 2022 with stricter cross-border
|
|
85
|
+
// transfer rules and mandatory breach notification within 72 hours.
|
|
86
|
+
console.log('--- APPI Compliance Check ---');
|
|
87
|
+
const compliance = checkCredentialCompliance(credential, 'JP');
|
|
88
|
+
console.log(`Compliant: ${compliance.compliant}`);
|
|
89
|
+
|
|
90
|
+
for (const issue of compliance.issues) {
|
|
91
|
+
const prefix = issue.severity === 'error' ? '[ERROR]'
|
|
92
|
+
: issue.severity === 'warning' ? '[WARN]'
|
|
93
|
+
: '[INFO]';
|
|
94
|
+
console.log(` ${prefix} ${issue.message}`);
|
|
95
|
+
console.log(` Regulation: ${issue.regulation}`);
|
|
96
|
+
if (issue.remediation) {
|
|
97
|
+
console.log(` Action: ${issue.remediation}`);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
console.log();
|
|
101
|
+
|
|
102
|
+
// --- 5. Cross-border transfer to South Korea ---
|
|
103
|
+
// Japan and South Korea both have EU adequacy decisions, and maintain mutual
|
|
104
|
+
// recognition for professional credentials and data transfers.
|
|
105
|
+
console.log('--- Cross-border transfer: JP -> KR ---');
|
|
106
|
+
const jpToKr = checkCrossBorderCompliance('JP', 'KR');
|
|
107
|
+
console.log(`Allowed: ${jpToKr.allowed}`);
|
|
108
|
+
if (jpToKr.mechanism) {
|
|
109
|
+
console.log(`Mechanism: ${jpToKr.mechanism}`);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
for (const issue of jpToKr.issues) {
|
|
113
|
+
console.log(` [${issue.severity.toUpperCase()}] ${issue.message}`);
|
|
114
|
+
}
|
|
115
|
+
console.log();
|
|
116
|
+
|
|
117
|
+
// Mutual recognition partners
|
|
118
|
+
const partners = getMutualRecognitionPartners('JP');
|
|
119
|
+
console.log(`Mutual recognition partners: ${partners.join(', ')}`);
|
|
120
|
+
console.log();
|
|
121
|
+
|
|
122
|
+
// --- 6. Child compliance under APPI + Child Welfare Act ---
|
|
123
|
+
// Japan's digital consent age is 15. Below that, parental consent is required.
|
|
124
|
+
console.log('--- Child compliance (age 12, JP) ---');
|
|
125
|
+
const childCompliance = checkChildCompliance(12, 'JP');
|
|
126
|
+
console.log(`Compliant: ${childCompliance.compliant}`);
|
|
127
|
+
console.log(`Min consent age: ${childCompliance.minConsentAge}`);
|
|
128
|
+
console.log(`Age of majority: ${childCompliance.ageOfMajority}`);
|
|
129
|
+
console.log(`Parental consent required: ${childCompliance.requiresParentalConsent}`);
|
|
130
|
+
|
|
131
|
+
for (const issue of childCompliance.issues) {
|
|
132
|
+
console.log(` [${issue.severity.toUpperCase()}] ${issue.message}`);
|
|
133
|
+
}
|
|
134
|
+
console.log();
|
|
135
|
+
|
|
136
|
+
// --- 7. Consent requirements ---
|
|
137
|
+
console.log('--- Consent requirements ---');
|
|
138
|
+
const consent = getConsentRequirements('JP');
|
|
139
|
+
console.log(`Explicit consent required: ${consent.requiresExplicitConsent}`);
|
|
140
|
+
console.log(`Digital consent age: ${consent.consentAge}`);
|
|
141
|
+
console.log(`Data categories: ${consent.dataCategories.join(', ')}`);
|
|
142
|
+
console.log();
|
|
143
|
+
|
|
144
|
+
// --- 8. Signet IQ (Japanese output) ---
|
|
145
|
+
console.log(`--- ${t('msg_signet_iq')} ---`);
|
|
146
|
+
const trustScore = computeTrustScore(
|
|
147
|
+
subject.publicKey,
|
|
148
|
+
[credential],
|
|
149
|
+
[],
|
|
150
|
+
Math.floor(Date.now() / 1000) - 365 * 24 * 60 * 60
|
|
151
|
+
);
|
|
152
|
+
console.log(formatLocalizedTrustScore(trustScore.score));
|
|
153
|
+
|
|
154
|
+
console.log('\n=== Japanese Notary Example Complete ===');
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
main().catch(console.error);
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
// Signet Protocol — Multi-Jurisdiction Example
|
|
2
|
+
// Demonstrates cross-border credential usage across multiple jurisdictions
|
|
3
|
+
// Scenario: A UK solicitor's credential is used in France, Germany, and Singapore
|
|
4
|
+
// Features: Cross-border compliance, most restrictive requirements, multi-language
|
|
5
|
+
|
|
6
|
+
import {
|
|
7
|
+
generateKeyPair,
|
|
8
|
+
getJurisdiction,
|
|
9
|
+
getMutualRecognitionPartners,
|
|
10
|
+
createProfessionalCredential,
|
|
11
|
+
verifyCredential,
|
|
12
|
+
parseCredential,
|
|
13
|
+
checkCredentialCompliance,
|
|
14
|
+
checkCrossBorderCompliance,
|
|
15
|
+
checkMultiJurisdictionCompliance,
|
|
16
|
+
getMostRestrictiveRequirements,
|
|
17
|
+
getConsentRequirements,
|
|
18
|
+
setLanguage,
|
|
19
|
+
t,
|
|
20
|
+
getTierDescription,
|
|
21
|
+
formatLocalizedTrustScore,
|
|
22
|
+
computeTrustScore,
|
|
23
|
+
} from '../../src/index.js';
|
|
24
|
+
|
|
25
|
+
async function main() {
|
|
26
|
+
console.log('=== Signet Protocol — Multi-Jurisdiction Verification ===\n');
|
|
27
|
+
|
|
28
|
+
// --- 1. Create a UK solicitor credential ---
|
|
29
|
+
const solicitor = generateKeyPair();
|
|
30
|
+
const subject = generateKeyPair();
|
|
31
|
+
|
|
32
|
+
setLanguage('en');
|
|
33
|
+
console.log('--- Step 1: Issue credential in UK ---');
|
|
34
|
+
|
|
35
|
+
const credential = await createProfessionalCredential(
|
|
36
|
+
solicitor.privateKey,
|
|
37
|
+
subject.publicKey,
|
|
38
|
+
{
|
|
39
|
+
profession: 'solicitor',
|
|
40
|
+
jurisdiction: 'GB',
|
|
41
|
+
}
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
const verification = await verifyCredential(credential);
|
|
45
|
+
const parsed = parseCredential(credential)!;
|
|
46
|
+
|
|
47
|
+
console.log(`Credential: ${t('credential_professional')}`);
|
|
48
|
+
console.log(` Tier: ${parsed.tier}, Profession: ${parsed.profession}`);
|
|
49
|
+
console.log(` Origin jurisdiction: ${parsed.jurisdiction}`);
|
|
50
|
+
console.log(` Signature valid: ${verification.signatureValid}`);
|
|
51
|
+
console.log();
|
|
52
|
+
|
|
53
|
+
// --- 2. Check compliance in each target jurisdiction ---
|
|
54
|
+
const targetJurisdictions = ['FR', 'DE', 'SG'];
|
|
55
|
+
const allJurisdictions = ['GB', ...targetJurisdictions];
|
|
56
|
+
|
|
57
|
+
console.log('--- Step 2: Multi-jurisdiction compliance check ---');
|
|
58
|
+
const complianceResults = checkMultiJurisdictionCompliance(credential, allJurisdictions);
|
|
59
|
+
|
|
60
|
+
for (const [code, result] of complianceResults) {
|
|
61
|
+
const j = getJurisdiction(code);
|
|
62
|
+
console.log(`\n[${code}] ${j?.name || code}: ${result.compliant ? 'COMPLIANT' : 'NON-COMPLIANT'}`);
|
|
63
|
+
|
|
64
|
+
for (const issue of result.issues) {
|
|
65
|
+
const prefix = issue.severity === 'error' ? 'ERROR'
|
|
66
|
+
: issue.severity === 'warning' ? 'WARN'
|
|
67
|
+
: 'INFO';
|
|
68
|
+
console.log(` [${prefix}] ${issue.message}`);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
console.log();
|
|
72
|
+
|
|
73
|
+
// --- 3. Cross-border compliance for each pair ---
|
|
74
|
+
console.log('--- Step 3: Cross-border transfer checks ---');
|
|
75
|
+
for (const target of targetJurisdictions) {
|
|
76
|
+
const targetJ = getJurisdiction(target);
|
|
77
|
+
const crossBorder = checkCrossBorderCompliance('GB', target);
|
|
78
|
+
|
|
79
|
+
console.log(`\nGB -> ${target} (${targetJ?.name}):`);
|
|
80
|
+
console.log(` Allowed: ${crossBorder.allowed}`);
|
|
81
|
+
if (crossBorder.mechanism) {
|
|
82
|
+
console.log(` Mechanism: ${crossBorder.mechanism}`);
|
|
83
|
+
}
|
|
84
|
+
for (const issue of crossBorder.issues) {
|
|
85
|
+
console.log(` [${issue.severity.toUpperCase()}] ${issue.message}`);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
console.log();
|
|
89
|
+
|
|
90
|
+
// --- 4. Most restrictive requirements ---
|
|
91
|
+
// When a credential is used across jurisdictions, the safest approach is
|
|
92
|
+
// to apply the most restrictive requirements from all jurisdictions.
|
|
93
|
+
console.log('--- Step 4: Most restrictive requirements ---');
|
|
94
|
+
const mostRestrictive = getMostRestrictiveRequirements(allJurisdictions);
|
|
95
|
+
|
|
96
|
+
console.log(`Jurisdictions considered: ${mostRestrictive.jurisdictions.join(', ')}`);
|
|
97
|
+
console.log(`Highest consent age: ${mostRestrictive.highestConsentAge}`);
|
|
98
|
+
console.log(`Highest age of majority: ${mostRestrictive.highestAgeOfMajority}`);
|
|
99
|
+
console.log(`Explicit consent required: ${mostRestrictive.requiresExplicitConsent}`);
|
|
100
|
+
console.log(`Shortest breach notification: ${mostRestrictive.shortestBreachNotification}h`);
|
|
101
|
+
console.log(`All require erasure: ${mostRestrictive.allRequireErasure}`);
|
|
102
|
+
console.log();
|
|
103
|
+
|
|
104
|
+
// Compare consent requirements across jurisdictions
|
|
105
|
+
console.log('--- Consent requirements by jurisdiction ---');
|
|
106
|
+
for (const code of allJurisdictions) {
|
|
107
|
+
const consent = getConsentRequirements(code);
|
|
108
|
+
const j = getJurisdiction(code);
|
|
109
|
+
console.log(` ${code} (${j?.name}): consent age=${consent.consentAge}, explicit=${consent.requiresExplicitConsent}`);
|
|
110
|
+
}
|
|
111
|
+
console.log();
|
|
112
|
+
|
|
113
|
+
// --- 5. Mutual recognition networks ---
|
|
114
|
+
console.log('--- Step 5: Mutual recognition partners ---');
|
|
115
|
+
for (const code of allJurisdictions) {
|
|
116
|
+
const partners = getMutualRecognitionPartners(code);
|
|
117
|
+
const j = getJurisdiction(code);
|
|
118
|
+
console.log(` ${code} (${j?.name}): ${partners.join(', ')}`);
|
|
119
|
+
}
|
|
120
|
+
console.log();
|
|
121
|
+
|
|
122
|
+
// --- 6. Multi-language output ---
|
|
123
|
+
// Demonstrate the same credential information in English, French, and German
|
|
124
|
+
console.log('--- Step 6: Multi-language credential display ---\n');
|
|
125
|
+
|
|
126
|
+
const trustScore = computeTrustScore(
|
|
127
|
+
subject.publicKey,
|
|
128
|
+
[credential],
|
|
129
|
+
[],
|
|
130
|
+
Math.floor(Date.now() / 1000) - 2 * 365 * 24 * 60 * 60
|
|
131
|
+
);
|
|
132
|
+
|
|
133
|
+
// English
|
|
134
|
+
setLanguage('en');
|
|
135
|
+
console.log(`[English]`);
|
|
136
|
+
console.log(` ${t('credential_professional')}: ${t('status_valid')}`);
|
|
137
|
+
console.log(` ${t('msg_signature_valid')}`);
|
|
138
|
+
console.log(` ${getTierDescription(3)}`);
|
|
139
|
+
console.log(` ${formatLocalizedTrustScore(trustScore.score)}`);
|
|
140
|
+
console.log();
|
|
141
|
+
|
|
142
|
+
// French
|
|
143
|
+
setLanguage('fr');
|
|
144
|
+
console.log(`[Francais]`);
|
|
145
|
+
console.log(` ${t('credential_professional')}: ${t('status_valid')}`);
|
|
146
|
+
console.log(` ${t('msg_signature_valid')}`);
|
|
147
|
+
console.log(` ${getTierDescription(3)}`);
|
|
148
|
+
console.log(` ${formatLocalizedTrustScore(trustScore.score)}`);
|
|
149
|
+
console.log();
|
|
150
|
+
|
|
151
|
+
// German
|
|
152
|
+
setLanguage('de');
|
|
153
|
+
console.log(`[Deutsch]`);
|
|
154
|
+
console.log(` ${t('credential_professional')}: ${t('status_valid')}`);
|
|
155
|
+
console.log(` ${t('msg_signature_valid')}`);
|
|
156
|
+
console.log(` ${getTierDescription(3)}`);
|
|
157
|
+
console.log(` ${formatLocalizedTrustScore(trustScore.score)}`);
|
|
158
|
+
console.log();
|
|
159
|
+
|
|
160
|
+
// --- 7. Summary ---
|
|
161
|
+
setLanguage('en');
|
|
162
|
+
console.log('--- Summary ---');
|
|
163
|
+
console.log('A UK solicitor credential can be used across jurisdictions with');
|
|
164
|
+
console.log('varying compliance requirements. Key considerations:');
|
|
165
|
+
console.log(' - GB->FR: EU adequacy (post-Brexit data bridge), GDPR alignment');
|
|
166
|
+
console.log(' - GB->DE: Strictest GDPR enforcement, 16+ consent age');
|
|
167
|
+
console.log(' - GB->SG: PDPA applies, different consent framework');
|
|
168
|
+
console.log(' - Most restrictive consent age across all: ' + mostRestrictive.highestConsentAge);
|
|
169
|
+
console.log(' - All require breach notification within ' + mostRestrictive.shortestBreachNotification + 'h');
|
|
170
|
+
|
|
171
|
+
console.log('\n=== Multi-Jurisdiction Example Complete ===');
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
main().catch(console.error);
|