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.
- package/README.md +22 -10
- 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 +3775 -0
- package/llms.txt +152 -0
- package/package.json +14 -3
- package/spec/protocol.md +2628 -0
- package/spec/voting.md +563 -0
|
@@ -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);
|