signet-protocol 1.11.0 → 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.
@@ -0,0 +1,260 @@
1
+ // Signet Protocol — Full Flow Example
2
+ // Demonstrates all 4 tiers, Signet IQ, policy enforcement, and verifier lifecycle
3
+
4
+ import {
5
+ generateKeyPair,
6
+ // Credentials
7
+ createSelfDeclaredCredential,
8
+ createPeerVouchedCredential,
9
+ createProfessionalCredential,
10
+ createChildSafetyCredential,
11
+ verifyCredential,
12
+ parseCredential,
13
+ // Vouches
14
+ createVouch,
15
+ hasEnoughVouches,
16
+ // Signet IQ
17
+ computeTrustScore,
18
+ formatTrustDisplay,
19
+ // Policies
20
+ createPolicy,
21
+ PolicyChecker,
22
+ // Verifiers
23
+ createVerifierCredential,
24
+ checkCrossVerification,
25
+ isVerifierRevoked,
26
+ // Challenges
27
+ createChallenge,
28
+ createRevocation,
29
+ // Merkle
30
+ MerkleTree,
31
+ verifySelectiveDisclosure,
32
+ } from '../src/index.js';
33
+
34
+ async function main() {
35
+ console.log('=== Signet Protocol — Full Flow Demo ===\n');
36
+
37
+ // --- 1. Generate identities ---
38
+ const alice = generateKeyPair(); // Regular user
39
+ const bob = generateKeyPair(); // Regular user
40
+ const carol = generateKeyPair(); // Regular user
41
+ const dave = generateKeyPair(); // Regular user
42
+ const emma = generateKeyPair(); // Parent
43
+ const lawyer = generateKeyPair(); // Professional verifier (solicitor)
44
+ const doctor = generateKeyPair(); // Professional verifier (doctor)
45
+ const notary = generateKeyPair(); // Professional verifier (notary)
46
+ const operator = generateKeyPair(); // Community operator
47
+
48
+ console.log('--- Tier 1: Self-Declared ---');
49
+ const aliceSelfCred = await createSelfDeclaredCredential(alice.privateKey);
50
+ const verification = await verifyCredential(aliceSelfCred);
51
+ console.log(`Alice self-declares: sig=${verification.signatureValid}, valid=${verification.structureValid}`);
52
+ console.log(` Tier: ${parseCredential(aliceSelfCred)!.tier}, Type: ${parseCredential(aliceSelfCred)!.type}\n`);
53
+
54
+ // --- 2. Web-of-Trust Vouching (Tier 2) ---
55
+ console.log('--- Tier 2: Web-of-Trust ---');
56
+
57
+ // Bob, Carol, Dave vouch for Alice (met at a Bitcoin meetup)
58
+ const vouches = await Promise.all([
59
+ createVouch(bob.privateKey, {
60
+ subjectPubkey: alice.publicKey,
61
+ method: 'in-person',
62
+ context: 'bitcoin-meetup-london',
63
+ voucherTier: 2,
64
+ voucherScore: 60,
65
+ }),
66
+ createVouch(carol.privateKey, {
67
+ subjectPubkey: alice.publicKey,
68
+ method: 'in-person',
69
+ context: 'bitcoin-meetup-london',
70
+ voucherTier: 2,
71
+ voucherScore: 55,
72
+ }),
73
+ createVouch(dave.privateKey, {
74
+ subjectPubkey: alice.publicKey,
75
+ method: 'online',
76
+ voucherTier: 2,
77
+ voucherScore: 45,
78
+ }),
79
+ ]);
80
+
81
+ const enough = hasEnoughVouches(vouches, alice.publicKey);
82
+ console.log(`Alice has enough vouches for Tier 2: ${enough}`); // true (3 vouches, threshold = 3)
83
+
84
+ // Issue Tier 2 credential
85
+ const aliceTier2 = await createPeerVouchedCredential(operator.privateKey, alice.publicKey);
86
+ console.log(`Alice promoted to Tier 2: ${parseCredential(aliceTier2)!.tier}\n`);
87
+
88
+ // --- 3. Professional Verifier Setup ---
89
+ console.log('--- Verifier Registration ---');
90
+
91
+ const lawyerCred = await createVerifierCredential(lawyer.privateKey, {
92
+ profession: 'solicitor',
93
+ jurisdiction: 'UK',
94
+ licenceHash: 'sha256_of_sra_number_12345',
95
+ professionalBody: 'Law Society of England and Wales',
96
+ statement: 'Available for Signet identity verification in London',
97
+ });
98
+
99
+ const doctorCred = await createVerifierCredential(doctor.privateKey, {
100
+ profession: 'doctor',
101
+ jurisdiction: 'UK',
102
+ licenceHash: 'sha256_of_gmc_number_67890',
103
+ professionalBody: 'General Medical Council',
104
+ });
105
+
106
+ const notaryCred = await createVerifierCredential(notary.privateKey, {
107
+ profession: 'notary',
108
+ jurisdiction: 'UK',
109
+ licenceHash: 'sha256_of_notary_commission_11111',
110
+ professionalBody: 'Notaries Society',
111
+ });
112
+
113
+ // Cross-verify: doctor and notary both vouch for the lawyer (2 different professions)
114
+ const crossVouches = await Promise.all([
115
+ createVouch(doctor.privateKey, {
116
+ subjectPubkey: lawyer.publicKey,
117
+ method: 'in-person',
118
+ voucherTier: 3,
119
+ voucherScore: 90,
120
+ }),
121
+ createVouch(notary.privateKey, {
122
+ subjectPubkey: lawyer.publicKey,
123
+ method: 'in-person',
124
+ voucherTier: 3,
125
+ voucherScore: 85,
126
+ }),
127
+ ]);
128
+
129
+ const lawyerActivation = checkCrossVerification(
130
+ lawyer.publicKey,
131
+ crossVouches,
132
+ [lawyerCred, doctorCred, notaryCred]
133
+ );
134
+ console.log(`Lawyer activated: ${lawyerActivation.activated}`);
135
+ console.log(` Vouches: ${lawyerActivation.vouchCount}, Professions: ${lawyerActivation.professions.join(', ')}\n`);
136
+
137
+ // --- 4. Professional Verification (Tier 3) ---
138
+ console.log('--- Tier 3: Professional Verification ---');
139
+
140
+ const aliceTier3 = await createProfessionalCredential(lawyer.privateKey, alice.publicKey, {
141
+ profession: 'solicitor',
142
+ jurisdiction: 'UK',
143
+ proofBlob: '(ZKP proof would go here)',
144
+ });
145
+
146
+ const tier3Result = await verifyCredential(aliceTier3);
147
+ console.log(`Alice Tier 3: sig=${tier3Result.signatureValid}, valid=${tier3Result.structureValid}`);
148
+ console.log(` Parsed: tier=${parseCredential(aliceTier3)!.tier}, profession=${parseCredential(aliceTier3)!.profession}\n`);
149
+
150
+ // --- 5. Child Safety (Tier 4) ---
151
+ console.log('--- Tier 4: Child Safety ---');
152
+
153
+ const emmaTier4 = await createChildSafetyCredential(lawyer.privateKey, emma.publicKey, {
154
+ profession: 'solicitor',
155
+ jurisdiction: 'UK',
156
+ ageRange: '8-12',
157
+ proofBlob: '(Bulletproof range proof would go here)',
158
+ });
159
+
160
+ const tier4Result = await verifyCredential(emmaTier4);
161
+ const parsed4 = parseCredential(emmaTier4)!;
162
+ console.log(`Emma Tier 4: sig=${tier4Result.signatureValid}, valid=${tier4Result.structureValid}`);
163
+ console.log(` Scope: ${parsed4.scope}, Age range: ${parsed4.ageRange}\n`);
164
+
165
+ // --- 6. Signet IQ ---
166
+ console.log('--- Signet IQ ---');
167
+
168
+ const oneYearAgo = Math.floor(Date.now() / 1000) - 365 * 24 * 60 * 60;
169
+ const aliceScore = computeTrustScore(
170
+ alice.publicKey,
171
+ [aliceSelfCred, aliceTier2, aliceTier3],
172
+ vouches,
173
+ oneYearAgo
174
+ );
175
+
176
+ console.log(formatTrustDisplay(aliceScore));
177
+ console.log();
178
+
179
+ // --- 7. Selective Disclosure (Merkle) ---
180
+ console.log('--- Selective Disclosure ---');
181
+
182
+ const tree = new MerkleTree({
183
+ tier: '3',
184
+ type: 'professional',
185
+ scope: 'adult',
186
+ profession: 'solicitor',
187
+ jurisdiction: 'UK',
188
+ method: 'in-person-id',
189
+ subject: alice.publicKey,
190
+ });
191
+
192
+ // Alice only reveals tier and jurisdiction
193
+ const disclosure = tree.disclose(['tier', 'jurisdiction']);
194
+ console.log(`Merkle root: ${tree.getRoot().slice(0, 16)}...`);
195
+ console.log(`Revealed: ${JSON.stringify(disclosure.revealedAttributes)}`);
196
+ console.log(`Disclosure valid: ${verifySelectiveDisclosure(disclosure)}\n`);
197
+
198
+ // --- 8. Community Policy ---
199
+ console.log('--- Policy Enforcement ---');
200
+
201
+ const policyEvent = await createPolicy(operator.privateKey, {
202
+ communityId: 'safe-kids-learning',
203
+ adultMinTier: 3,
204
+ childMinTier: 4,
205
+ enforcement: 'both',
206
+ minScore: 50,
207
+ modMinTier: 3,
208
+ verifierBond: 100000,
209
+ revocationThreshold: 5,
210
+ description: 'Maximum safety space for children',
211
+ });
212
+
213
+ const checker = new PolicyChecker(policyEvent);
214
+
215
+ console.log(`Alice (Tier 3, score ${aliceScore.score}) as adult: ${checker.checkAdult(3, aliceScore.score).allowed}`);
216
+ console.log(`Emma (Tier 4, score 60) as child account: ${checker.checkChild(4, 60).allowed}`);
217
+ console.log(`Bob (Tier 2, score 40) as adult: ${checker.checkAdult(2, 40).allowed}`);
218
+
219
+ const bobResult = checker.checkAdult(2, 40);
220
+ if (!bobResult.allowed) {
221
+ console.log(` Reason: ${bobResult.reason}`);
222
+ }
223
+ console.log();
224
+
225
+ // --- 9. Challenge & Revocation ---
226
+ console.log('--- Challenge & Revocation ---');
227
+
228
+ const rogue = generateKeyPair();
229
+ const rogueCred = await createVerifierCredential(rogue.privateKey, {
230
+ profession: 'solicitor',
231
+ jurisdiction: 'UK',
232
+ licenceHash: 'fake_licence',
233
+ professionalBody: 'Law Society',
234
+ });
235
+
236
+ const challenge = await createChallenge(alice.privateKey, {
237
+ verifierPubkey: rogue.publicKey,
238
+ reason: 'registry-mismatch',
239
+ evidenceType: 'registry-screenshot',
240
+ reporterTier: 3,
241
+ evidence: 'SRA lookup: licence number not found in registry',
242
+ });
243
+ console.log(`Challenge filed against rogue verifier`);
244
+
245
+ const revocation = await createRevocation(operator.privateKey, {
246
+ verifierPubkey: rogue.publicKey,
247
+ challengeEventId: challenge.id,
248
+ confirmations: 7,
249
+ bondAction: 'slashed',
250
+ scope: 'full',
251
+ effectiveAt: Math.floor(Date.now() / 1000),
252
+ summary: 'Licence number confirmed fake via SRA registry check',
253
+ });
254
+ console.log(`Revocation issued: ${isVerifierRevoked(rogue.publicKey, [revocation])}`);
255
+ console.log();
256
+
257
+ console.log('=== Demo Complete ===');
258
+ }
259
+
260
+ main().catch(console.error);
@@ -0,0 +1,186 @@
1
+ // Signet Protocol — Brazilian Lawyer Example
2
+ // Demonstrates identity verification under LGPD (Lei Geral de Protecao de Dados)
3
+ // Jurisdiction: Brazil (BR)
4
+ // Profession: Lawyer regulated by the OAB (Ordem dos Advogados do Brasil)
5
+ // Features: LGPD compliance, digital credential support, child protection under Art. 14
6
+
7
+ import {
8
+ generateKeyPair,
9
+ getJurisdiction,
10
+ getProfessionalBodies,
11
+ createProfessionalCredential,
12
+ createChildSafetyCredential,
13
+ verifyCredential,
14
+ parseCredential,
15
+ checkCredentialCompliance,
16
+ checkChildCompliance,
17
+ getConsentRequirements,
18
+ getRetentionGuidance,
19
+ setLanguage,
20
+ t,
21
+ getTierDescription,
22
+ formatLocalizedTrustScore,
23
+ computeTrustScore,
24
+ } from '../../src/index.js';
25
+
26
+ async function main() {
27
+ console.log('=== Protocolo Signet — Verificacao de Advogado Brasileiro ===\n');
28
+
29
+ // Set language to Portuguese
30
+ setLanguage('pt');
31
+
32
+ // --- 1. Jurisdiction and OAB lookup ---
33
+ const br = getJurisdiction('BR');
34
+ if (!br) throw new Error('BR jurisdiction not found');
35
+
36
+ console.log(`Jurisdicao: ${br.name} (${br.nameLocal})`);
37
+ console.log(`Sistema juridico: ${br.legalSystem}`);
38
+ console.log(`Protecao de dados: ${br.dataProtection.name} - ${br.dataProtection.fullName}`);
39
+ console.log(`Autoridade supervisora: ${br.dataProtection.supervisoryAuthority}`);
40
+ if (br.dataProtection.notes) {
41
+ console.log(`Nota: ${br.dataProtection.notes}`);
42
+ }
43
+ console.log();
44
+
45
+ // Look up the OAB — notably, it issues digital credentials via ICP-Brasil
46
+ const legalBodies = getProfessionalBodies('BR', 'legal');
47
+ console.log('Entidades profissionais juridicas no Brasil:');
48
+ for (const body of legalBodies) {
49
+ console.log(` - ${body.name}`);
50
+ if (body.nameEn) console.log(` (${body.nameEn})`);
51
+ console.log(` Website: ${body.website}`);
52
+ console.log(` Registro publico: ${body.hasPublicRegister}`);
53
+ if (body.registerUrl) {
54
+ console.log(` URL do registro: ${body.registerUrl}`);
55
+ }
56
+ // OAB issues digital certificates via ICP-Brasil PKI
57
+ console.log(` Credenciais digitais: ${body.issuesDigitalCredentials}`);
58
+ if (body.notes) {
59
+ console.log(` Nota: ${body.notes}`);
60
+ }
61
+ }
62
+ console.log();
63
+
64
+ // --- 2. Generate identities ---
65
+ const advogado = generateKeyPair(); // The verifying lawyer (advogado)
66
+ const subject = generateKeyPair(); // Person being verified
67
+ const parent = generateKeyPair(); // Parent (for child credential)
68
+
69
+ // --- 3. Create Tier 3 credential (Portuguese output) ---
70
+ console.log(`--- ${t('tier_3')}: ${t('credential_professional')} ---`);
71
+ console.log(getTierDescription(3));
72
+ console.log();
73
+
74
+ const credential = await createProfessionalCredential(
75
+ advogado.privateKey,
76
+ subject.publicKey,
77
+ {
78
+ profession: 'lawyer',
79
+ jurisdiction: 'BR',
80
+ }
81
+ );
82
+
83
+ const verification = await verifyCredential(credential);
84
+ const parsed = parseCredential(credential)!;
85
+
86
+ console.log(`${t('credential_professional')}: ${t('status_valid')}`);
87
+ console.log(` ${t('msg_signature_valid')}`);
88
+ console.log(` Tier: ${parsed.tier}, Profissao: ${parsed.profession}`);
89
+ console.log(` Jurisdicao: ${parsed.jurisdiction}`);
90
+ console.log();
91
+
92
+ // --- 4. LGPD compliance check ---
93
+ // Brazil's LGPD is modelled on the GDPR and requires explicit consent.
94
+ // ICP-Brasil provides the PKI infrastructure for digital signatures.
95
+ console.log('--- Verificacao de conformidade LGPD ---');
96
+ const compliance = checkCredentialCompliance(credential, 'BR');
97
+ console.log(`Em conformidade: ${compliance.compliant}`);
98
+
99
+ for (const issue of compliance.issues) {
100
+ const prefix = issue.severity === 'error' ? '[ERRO]'
101
+ : issue.severity === 'warning' ? '[AVISO]'
102
+ : '[INFO]';
103
+ console.log(` ${prefix} ${issue.message}`);
104
+ console.log(` Regulamento: ${issue.regulation}`);
105
+ if (issue.remediation) {
106
+ console.log(` Acao: ${issue.remediation}`);
107
+ }
108
+ }
109
+ console.log();
110
+
111
+ // --- 5. LGPD consent requirements ---
112
+ // LGPD treats biometric data as sensitive personal data requiring specific legal basis.
113
+ console.log('--- Requisitos de consentimento ---');
114
+ const consent = getConsentRequirements('BR');
115
+ console.log(`Consentimento explicito: ${consent.requiresExplicitConsent}`);
116
+ console.log(`Idade de consentimento digital: ${consent.consentAge}`);
117
+ console.log(`Categorias de dados: ${consent.dataCategories.join(', ')}`);
118
+ if (consent.specialCategories.length > 0) {
119
+ console.log(`Categorias especiais: ${consent.specialCategories.join(', ')}`);
120
+ }
121
+ if (consent.notes) {
122
+ console.log(`Nota: ${consent.notes}`);
123
+ }
124
+ console.log();
125
+
126
+ // --- 6. Child protection under LGPD Art. 14 ---
127
+ // LGPD Art. 14 provides specific rules for processing children's data.
128
+ // Brazil's digital consent age is 12 (one of the lowest globally).
129
+ // The ECA (Estatuto da Crianca e do Adolescente) provides additional protections.
130
+ console.log('--- Protecao infantil — LGPD Art. 14 + ECA ---');
131
+
132
+ const childCredential = await createChildSafetyCredential(
133
+ advogado.privateKey,
134
+ parent.publicKey,
135
+ {
136
+ profession: 'lawyer',
137
+ jurisdiction: 'BR',
138
+ ageRange: '8-12',
139
+ }
140
+ );
141
+
142
+ const childVerification = await verifyCredential(childCredential);
143
+ const childParsed = parseCredential(childCredential)!;
144
+
145
+ console.log(`${t('credential_professional_child')}: ${t('status_valid')}`);
146
+ console.log(` Escopo: ${childParsed.scope}, Faixa etaria: ${childParsed.ageRange}`);
147
+ console.log(` Assinatura valida: ${childVerification.signatureValid}`);
148
+ console.log();
149
+
150
+ // Check child compliance for a 10-year-old
151
+ console.log('--- Conformidade infantil (idade 10, BR) ---');
152
+ const childCompliance = checkChildCompliance(10, 'BR');
153
+ console.log(`Em conformidade: ${childCompliance.compliant}`);
154
+ console.log(`Idade minima de consentimento: ${childCompliance.minConsentAge}`);
155
+ console.log(`Maioridade: ${childCompliance.ageOfMajority}`);
156
+ console.log(`Consentimento parental necessario: ${childCompliance.requiresParentalConsent}`);
157
+
158
+ for (const issue of childCompliance.issues) {
159
+ const prefix = issue.severity === 'error' ? '[ERRO]'
160
+ : issue.severity === 'warning' ? '[AVISO]'
161
+ : '[INFO]';
162
+ console.log(` ${prefix} ${issue.message}`);
163
+ }
164
+ console.log();
165
+
166
+ // --- 7. Data retention ---
167
+ console.log('--- Retencao de dados ---');
168
+ const retention = getRetentionGuidance('BR');
169
+ console.log(`Orientacao: ${retention.guidance}`);
170
+ console.log(`Regulamento: ${retention.regulation}`);
171
+ console.log();
172
+
173
+ // --- 8. Signet IQ (Portuguese output) ---
174
+ console.log(`--- ${t('msg_signet_iq')} ---`);
175
+ const trustScore = computeTrustScore(
176
+ subject.publicKey,
177
+ [credential],
178
+ [],
179
+ Math.floor(Date.now() / 1000) - 2 * 365 * 24 * 60 * 60
180
+ );
181
+ console.log(formatLocalizedTrustScore(trustScore.score));
182
+
183
+ console.log('\n=== Exemplo de Advogado Brasileiro Concluido ===');
184
+ }
185
+
186
+ main().catch(console.error);
@@ -0,0 +1,160 @@
1
+ // Signet Protocol — German Doctor (EU) Example
2
+ // Demonstrates identity verification under GDPR with cross-border EU transfers
3
+ // Jurisdiction: Germany (DE)
4
+ // Profession: Doctor (Arzt) regulated by the Bundesaerztekammer
5
+ // Features: GDPR compliance, eIDAS recognition, cross-border to France
6
+
7
+ import {
8
+ generateKeyPair,
9
+ getJurisdiction,
10
+ getProfessionalBodies,
11
+ getMutualRecognitionPartners,
12
+ createProfessionalCredential,
13
+ verifyCredential,
14
+ parseCredential,
15
+ checkCredentialCompliance,
16
+ checkCrossBorderCompliance,
17
+ getConsentRequirements,
18
+ getRetentionGuidance,
19
+ setLanguage,
20
+ t,
21
+ getTierDescription,
22
+ formatLocalizedTrustScore,
23
+ computeTrustScore,
24
+ } from '../../src/index.js';
25
+
26
+ async function main() {
27
+ console.log('=== Signet-Protokoll — Deutsche Arztverifizierung ===\n');
28
+
29
+ // Set language to German
30
+ setLanguage('de');
31
+
32
+ // --- 1. Jurisdiction and professional body lookup ---
33
+ const de = getJurisdiction('DE');
34
+ if (!de) throw new Error('DE jurisdiction not found');
35
+
36
+ console.log(`Gerichtsbarkeit: ${de.name} (${de.nameLocal})`);
37
+ console.log(`Rechtssystem: ${de.legalSystem}`);
38
+ console.log(`Datenschutz: ${de.dataProtection.name}`);
39
+ console.log(`Aufsichtsbehoerde: ${de.dataProtection.supervisoryAuthority}`);
40
+ console.log(`Hinweis: ${de.dataProtection.notes}`);
41
+ console.log();
42
+
43
+ // Look up the Bundesaerztekammer (German Medical Association)
44
+ const medicalBodies = getProfessionalBodies('DE', 'medical');
45
+ console.log('Medizinische Berufskoerperschaften in DE:');
46
+ for (const body of medicalBodies) {
47
+ console.log(` - ${body.name}`);
48
+ if (body.nameEn) console.log(` (${body.nameEn})`);
49
+ console.log(` Oeffentliches Register: ${body.hasPublicRegister}`);
50
+ console.log(` Digitale Nachweise: ${body.issuesDigitalCredentials}`);
51
+ }
52
+ console.log();
53
+
54
+ // --- 2. Generate identities ---
55
+ const arzt = generateKeyPair(); // The verifying doctor (Arzt)
56
+ const patient = generateKeyPair(); // Person being verified
57
+
58
+ // --- 3. Create Tier 3 credential (German output) ---
59
+ console.log(`--- ${t('tier_3')}: ${t('credential_professional')} ---`);
60
+ console.log(getTierDescription(3));
61
+ console.log();
62
+
63
+ const credential = await createProfessionalCredential(
64
+ arzt.privateKey,
65
+ patient.publicKey,
66
+ {
67
+ profession: 'doctor',
68
+ jurisdiction: 'DE',
69
+ }
70
+ );
71
+
72
+ const verification = await verifyCredential(credential);
73
+ const parsed = parseCredential(credential)!;
74
+
75
+ console.log(`${t('credential_professional')}: ${t('status_valid')}`);
76
+ console.log(` ${t('msg_signature_valid')}`);
77
+ console.log(` ${t('tier_3')}: ${parsed.profession}, ${parsed.jurisdiction}`);
78
+ console.log();
79
+
80
+ // --- 4. GDPR compliance check ---
81
+ // Germany has the strictest GDPR enforcement in the EU, with both federal
82
+ // and 16 state-level DPAs (Datenschutzbehoerden).
83
+ console.log(`--- DSGVO-Konformitaetspruefung ---`);
84
+ const compliance = checkCredentialCompliance(credential, 'DE');
85
+ console.log(`Konform: ${compliance.compliant}`);
86
+
87
+ for (const issue of compliance.issues) {
88
+ const prefix = issue.severity === 'error' ? '[FEHLER]'
89
+ : issue.severity === 'warning' ? '[WARNUNG]'
90
+ : '[INFO]';
91
+ console.log(` ${prefix} ${issue.message}`);
92
+ console.log(` Verordnung: ${issue.regulation}`);
93
+ if (issue.remediation) {
94
+ console.log(` Massnahme: ${issue.remediation}`);
95
+ }
96
+ }
97
+ console.log();
98
+
99
+ // --- 5. Cross-border transfer to France (EU internal) ---
100
+ // Under GDPR, intra-EU transfers are generally permitted as all member states
101
+ // are subject to the same regulation. However, national implementations may differ.
102
+ console.log('--- Grenzueberschreitende Uebermittlung: DE -> FR ---');
103
+ const crossBorder = checkCrossBorderCompliance('DE', 'FR');
104
+ console.log(`Erlaubt: ${crossBorder.allowed}`);
105
+ if (crossBorder.mechanism) {
106
+ console.log(`Mechanismus: ${crossBorder.mechanism}`);
107
+ }
108
+
109
+ for (const issue of crossBorder.issues) {
110
+ console.log(` [${issue.severity.toUpperCase()}] ${issue.message}`);
111
+ }
112
+ console.log();
113
+
114
+ // --- 6. eIDAS electronic signature recognition ---
115
+ // The eIDAS regulation (EU 910/2014) provides mutual recognition of electronic
116
+ // signatures across EU member states. German beA (besonderes elektronisches
117
+ // Anwaltspostfach) is an example of qualified electronic signature infrastructure.
118
+ console.log('--- eIDAS Anerkennung ---');
119
+ const fr = getJurisdiction('FR');
120
+ console.log(`DE e-Signatur anerkannt: ${de.eSignatureRecognised}`);
121
+ console.log(`FR e-Signatur anerkannt: ${fr?.eSignatureRecognised}`);
122
+ console.log('eIDAS ermoeglicht die gegenseitige Anerkennung qualifizierter');
123
+ console.log('elektronischer Signaturen zwischen EU-Mitgliedstaaten.');
124
+ console.log();
125
+
126
+ // --- 7. Mutual recognition partners ---
127
+ const partners = getMutualRecognitionPartners('DE');
128
+ console.log(`Gegenseitige Anerkennung: ${partners.join(', ')}`);
129
+ console.log();
130
+
131
+ // --- 8. Consent and retention requirements ---
132
+ console.log('--- Einwilligungsanforderungen ---');
133
+ const consent = getConsentRequirements('DE');
134
+ console.log(`${t('legal_consent')} erforderlich: ${consent.requiresExplicitConsent}`);
135
+ console.log(`Digitales Einwilligungsalter: ${consent.consentAge}`);
136
+ if (consent.notes) {
137
+ console.log(`Hinweis: ${consent.notes}`);
138
+ }
139
+ console.log();
140
+
141
+ console.log('--- Aufbewahrungsrichtlinien ---');
142
+ const retention = getRetentionGuidance('DE');
143
+ console.log(`Richtlinie: ${retention.guidance}`);
144
+ console.log(`Verordnung: ${retention.regulation}`);
145
+ console.log();
146
+
147
+ // --- 9. Signet IQ (German output) ---
148
+ console.log(`--- ${t('msg_signet_iq')} ---`);
149
+ const trustScore = computeTrustScore(
150
+ patient.publicKey,
151
+ [credential],
152
+ [],
153
+ Math.floor(Date.now() / 1000) - 3 * 365 * 24 * 60 * 60
154
+ );
155
+ console.log(formatLocalizedTrustScore(trustScore.score));
156
+
157
+ console.log('\n=== Deutsche Arztverifizierung abgeschlossen ===');
158
+ }
159
+
160
+ main().catch(console.error);