@learncard/lca-api-plugin 1.2.16 → 1.2.17

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/src/plugin.ts ADDED
@@ -0,0 +1,721 @@
1
+ import { getClient, Client } from '@learncard/lca-api-client';
2
+ import { LearnCard } from '@learncard/core';
3
+ import pbkdf2Hmac from 'pbkdf2-hmac';
4
+
5
+ import { ThemeEnum } from './types';
6
+
7
+ import { LCAPluginDependentMethods, LCAPlugin } from './types';
8
+ import { JWKWithPrivateKey } from '@learncard/types';
9
+ import { toUint8Array } from 'hex-lite';
10
+ export * from './types';
11
+
12
+ const getNewClient = async (
13
+ url: string,
14
+ learnCard: LearnCard<any, 'id', LCAPluginDependentMethods>,
15
+ extraHeaders?: Record<string, string>
16
+ ) => {
17
+ return getClient(url, async challenge => {
18
+ const jwt = await learnCard.invoke.getDidAuthVp({ proofFormat: 'jwt', challenge });
19
+
20
+ if (typeof jwt !== 'string') throw new Error('Error getting DID-Auth-JWT!');
21
+
22
+ return jwt;
23
+ }, extraHeaders);
24
+ };
25
+
26
+ const getEncryptionJwk = async (
27
+ client: Client,
28
+ learnCard: LearnCard<any, 'id', LCAPluginDependentMethods>
29
+ ): Promise<JWKWithPrivateKey> => {
30
+ const key = await client.utilities.getEncryptionKey.query();
31
+ return learnCard.invoke.generateEd25519KeyFromBytes(toUint8Array(key));
32
+ };
33
+
34
+ const ensureKeyAgreement = async (
35
+ jwk: JWKWithPrivateKey,
36
+ learnCard: LearnCard<any, 'id', LCAPluginDependentMethods>
37
+ ) => {
38
+ if (!learnCard.id.did().includes('did:web')) return; // did is not LCN Profile
39
+
40
+ const encryptionDid = learnCard.invoke.keyToDid('key', jwk);
41
+ const encryptionDidDoc = await learnCard.invoke.resolveDid(encryptionDid);
42
+
43
+ const userDidDoc = await learnCard.invoke.resolveDid(learnCard.id.did());
44
+
45
+ if (
46
+ userDidDoc.keyAgreement?.some(keyAgreement => {
47
+ return encryptionDidDoc.keyAgreement?.some(eKeyAgreement => {
48
+ if (typeof eKeyAgreement === 'string' || typeof keyAgreement === 'string')
49
+ return false;
50
+
51
+ return eKeyAgreement.publicKeyBase58 === keyAgreement.publicKeyBase58;
52
+ });
53
+ })
54
+ ) {
55
+ return; // Profile has already added this encryption key
56
+ }
57
+
58
+ await learnCard.invoke.addDidMetadata({
59
+ verificationMethod: encryptionDidDoc.verificationMethod,
60
+ keyAgreement: encryptionDidDoc.keyAgreement,
61
+ });
62
+ };
63
+
64
+ /**
65
+ * @group Plugins
66
+ */
67
+ export const getLCAPlugin = async (
68
+ initialLearnCard: LearnCard<any, 'id', LCAPluginDependentMethods>,
69
+ url: string,
70
+ useCustomHash = false,
71
+ extraHeaders?: Record<string, string>
72
+ ): Promise<LCAPlugin> => {
73
+ let learnCard = initialLearnCard;
74
+ let oldDid = learnCard.id.did();
75
+ let encryptionJwk: JWKWithPrivateKey;
76
+
77
+ // Don't break whole wallet if connection to LCA API can't be made.
78
+ try {
79
+ let client = await getNewClient(url, learnCard, extraHeaders);
80
+
81
+ const updateLearnCard = async (
82
+ _learnCard: LearnCard<any, 'id', LCAPluginDependentMethods>
83
+ ) => {
84
+ const newDid = _learnCard.id.did();
85
+
86
+ if (oldDid !== newDid) {
87
+ client = await getNewClient(url, _learnCard, extraHeaders);
88
+ oldDid = newDid;
89
+ encryptionJwk = await getEncryptionJwk(client, _learnCard);
90
+ await ensureKeyAgreement(encryptionJwk, _learnCard);
91
+ }
92
+
93
+ learnCard = _learnCard;
94
+ };
95
+
96
+ const initialized = learnCard.invoke
97
+ .getProfile()
98
+ .then(async profile => {
99
+ if (profile) await updateLearnCard(learnCard);
100
+ encryptionJwk = await getEncryptionJwk(
101
+ await getNewClient(url, learnCard, extraHeaders),
102
+ learnCard
103
+ );
104
+ })
105
+ .catch(error => {
106
+ console.warn('[LCA Plugin] Initialization warning:', error);
107
+ // Continue without encryption JWK if initialization fails
108
+ // This allows the plugin methods to still work even if initial setup has issues
109
+ });
110
+
111
+ return {
112
+ name: 'LearnCard App',
113
+ displayName: 'LearnCard App Plugin',
114
+ description: 'Adds bespoke logic to the LearnCard App.',
115
+ methods: {
116
+ registerDeviceForPushNotifications: async (_learnCard, token) => {
117
+ await initialized;
118
+ await updateLearnCard(_learnCard);
119
+
120
+ return client.notifications.registerDeviceForPushNotifications.mutate({
121
+ token,
122
+ });
123
+ },
124
+ unregisterDeviceForPushNotifications: async (_learnCard, token) => {
125
+ await initialized;
126
+ await updateLearnCard(_learnCard);
127
+
128
+ return client.notifications.unregisterDeviceForPushNotifications.mutate({
129
+ token,
130
+ });
131
+ },
132
+ getNotifications: async (_learnCard, options, filters) => {
133
+ await initialized;
134
+ await updateLearnCard(_learnCard);
135
+
136
+ return client.notifications.notifications.query({
137
+ options,
138
+ filters,
139
+ }) as any;
140
+ },
141
+ queryNotifications: async (_learnCard, query, options = {}) => {
142
+ await initialized;
143
+ await updateLearnCard(_learnCard);
144
+
145
+ return client.notifications.queryNotifications.query({
146
+ query,
147
+ options: {
148
+ limit: options.limit ?? 20,
149
+ cursor: options.cursor,
150
+ sort: options.sort ?? 'REVERSE_CHRONOLOGICAL',
151
+ },
152
+ }) as any;
153
+ },
154
+ markAllNotificationsRead: async _learnCard => {
155
+ await initialized;
156
+ await updateLearnCard(_learnCard);
157
+
158
+ return client.notifications.markAllNotificationsRead.mutate();
159
+ },
160
+ updateNotificationMeta: async (_learnCard, _id, meta) => {
161
+ await initialized;
162
+ await updateLearnCard(_learnCard);
163
+
164
+ return client.notifications.updateNotificationMeta.mutate({
165
+ _id,
166
+ meta,
167
+ });
168
+ },
169
+ createSigningAuthority: async (_learnCard, name, ownerDid) => {
170
+ await initialized;
171
+ await updateLearnCard(_learnCard);
172
+
173
+ return client.signingAuthority.createSigningAuthority.mutate({
174
+ name,
175
+ ownerDid,
176
+ });
177
+ },
178
+ getSigningAuthorities: async _learnCard => {
179
+ await initialized;
180
+ await updateLearnCard(_learnCard);
181
+
182
+ return client.signingAuthority.signingAuthorities.query();
183
+ },
184
+ authorizeSigningAuthority: async (_learnCard, name, authorization) => {
185
+ await initialized;
186
+ await updateLearnCard(_learnCard);
187
+
188
+ return client.signingAuthority.authorizeSigningAuthority.mutate({
189
+ name,
190
+ authorization,
191
+ });
192
+ },
193
+ resetLCAClient: async _learnCard => {
194
+ await initialized;
195
+ client = await getNewClient(url, _learnCard);
196
+ learnCard = _learnCard;
197
+ },
198
+ generateBoostInfo: async (_learnCard, description) => {
199
+ await initialized;
200
+ await updateLearnCard(_learnCard);
201
+
202
+ const result = await client.ai.generateBoostInfo.query({ description });
203
+
204
+ return {
205
+ title: result.title,
206
+ description: result.description,
207
+ category: result.category,
208
+ type: result.type,
209
+ skills: (result as any).skills,
210
+ narrative: result.narrative ?? '',
211
+ };
212
+ },
213
+ generateImage: async (_learnCard, prompt) => {
214
+ await initialized;
215
+ await updateLearnCard(_learnCard);
216
+
217
+ return (await client.ai.generateImage.query({ prompt })).url;
218
+ },
219
+ generateBoostSkills: async (_learnCard, description: string) => {
220
+ await initialized;
221
+ await updateLearnCard(_learnCard);
222
+
223
+ const result = await client.ai.generateBoostSkills.query({ description });
224
+
225
+ return result;
226
+ },
227
+ generateSkillIcons: async (_learnCard, names: string[]) => {
228
+ await initialized;
229
+ await updateLearnCard(_learnCard);
230
+
231
+ const result = await client.ai.generateSkillIcons.query({ names });
232
+
233
+ return result;
234
+ },
235
+ createPin: async (_learnCard, pin) => {
236
+ await initialized;
237
+ await updateLearnCard(_learnCard);
238
+
239
+ const result = await client.pins.createPin.mutate({ pin });
240
+
241
+ return result;
242
+ },
243
+ hasPin: async (_learnCard, did) => {
244
+ await initialized;
245
+ await updateLearnCard(_learnCard);
246
+
247
+ const result = await client.pins.hasPin.query({ did });
248
+
249
+ return result;
250
+ },
251
+ verifyPin: async (_learnCard, pin, did) => {
252
+ await initialized;
253
+ await updateLearnCard(_learnCard);
254
+
255
+ const result = await client.pins.verifyPin.query({ pin, did });
256
+
257
+ return result;
258
+ },
259
+ updatePin: async (_learnCard, currentPin, newPin) => {
260
+ await initialized;
261
+ await updateLearnCard(_learnCard);
262
+
263
+ const result = await client.pins.updatePin.mutate({ currentPin, newPin });
264
+
265
+ return result;
266
+ },
267
+ generatePinUpdateToken: async _learnCard => {
268
+ await initialized;
269
+ await updateLearnCard(_learnCard);
270
+
271
+ const result = await client.pins.generatePinUpdateToken.mutate();
272
+
273
+ if (result?.token && result?.tokenExpire) {
274
+ return {
275
+ token: result.token,
276
+ tokenExpire: new Date(result.tokenExpire),
277
+ };
278
+ }
279
+
280
+ return null;
281
+ },
282
+ validatePinUpdateToken: async (_learnCard, token) => {
283
+ await initialized;
284
+ await updateLearnCard(_learnCard);
285
+
286
+ const result = await client.pins.validatePinUpdateToken.query({ token });
287
+
288
+ return result;
289
+ },
290
+ updatePinWithToken: async (_learnCard, token, newPin) => {
291
+ await initialized;
292
+ await updateLearnCard(_learnCard);
293
+
294
+ const result = await client.pins.updatePinWithToken.mutate({ token, newPin });
295
+
296
+ return result;
297
+ },
298
+ generateAnalyticsAccessToken: async (_learnCard, payload) => {
299
+ await initialized;
300
+ await updateLearnCard(_learnCard);
301
+
302
+ const result = await client.analytics.generateAnalyticsAccessToken.mutate(
303
+ payload
304
+ );
305
+
306
+ return result;
307
+ },
308
+ decryptDagJwe: async (_learnCard, jwe, jwks = []) => {
309
+ await initialized;
310
+ await updateLearnCard(_learnCard);
311
+
312
+ return initialLearnCard.invoke.decryptDagJwe(
313
+ jwe,
314
+ encryptionJwk ? [encryptionJwk, ...jwks] : jwks
315
+ );
316
+ },
317
+ hash: async (_learnCard, message, algorithm = 'PBKDF2-HMAC-SHA256') => {
318
+ await initialized;
319
+ await updateLearnCard(_learnCard);
320
+
321
+ if (!useCustomHash || algorithm !== 'PBKDF2-HMAC-SHA256' || !encryptionJwk) {
322
+ return undefined;
323
+ }
324
+
325
+ const crypto = learnCard.invoke.crypto();
326
+
327
+ const uint8Message = new TextEncoder().encode(message);
328
+
329
+ const pk = encryptionJwk.d;
330
+ const hmacKey = await pbkdf2Hmac(pk, 'salt', 1000, 32);
331
+ const cryptoKey = await crypto.subtle.importKey(
332
+ 'raw',
333
+ hmacKey,
334
+ { name: 'HMAC', hash: 'SHA-256' },
335
+ false,
336
+ ['sign']
337
+ );
338
+
339
+ const digestBuffer = await crypto.subtle.sign('HMAC', cryptoKey, uint8Message);
340
+
341
+ const digestArray = Array.from(new Uint8Array(digestBuffer));
342
+
343
+ return digestArray
344
+ .map(byte => (byte as any).toString(16).padStart(2, '0'))
345
+ .join('');
346
+ },
347
+ getFirebaseUserByEmail: async (_learnCard, email) => {
348
+ await initialized;
349
+ await updateLearnCard(_learnCard);
350
+
351
+ const result = await client.firebase.getFirebaseUserByEmail.query({ email });
352
+
353
+ return result?.userRecord || null;
354
+ },
355
+ authenticateWithKeycloak: async (_learnCard, token) => {
356
+ await initialized;
357
+ await updateLearnCard(_learnCard);
358
+
359
+ const result = await client.firebase.authenticateWithKeycloak.mutate({
360
+ keycloakToken: token,
361
+ });
362
+
363
+ return result;
364
+ },
365
+ authenticateWithScoutsSSO: async (_learnCard, username, password) => {
366
+ await initialized;
367
+ await updateLearnCard(_learnCard);
368
+
369
+ const result = await client.firebase.authenticateWithScoutsSSO.mutate({
370
+ username,
371
+ password,
372
+ });
373
+
374
+ return result || null;
375
+ },
376
+ sendLoginVerificationCode: async (_learnCard, email) => {
377
+ await initialized;
378
+ await updateLearnCard(_learnCard);
379
+
380
+ const result = await client.firebase.sendLoginVerificationCode.mutate({
381
+ email,
382
+ });
383
+
384
+ return result;
385
+ },
386
+ verifyLoginCode: async (_learnCard, email, code) => {
387
+ await initialized;
388
+ await updateLearnCard(_learnCard);
389
+
390
+ const result = await client.firebase.verifyLoginCode.mutate({ email, code });
391
+
392
+ return result;
393
+ },
394
+ verifyNetworkHandoffToken: async (_learnCard, token) => {
395
+ await initialized;
396
+ await updateLearnCard(_learnCard);
397
+
398
+ const result = await client.firebase.verifyNetworkHandoffToken.mutate({
399
+ token,
400
+ });
401
+
402
+ return result;
403
+ },
404
+ getProofOfLoginVp: async (_learnCard, token) => {
405
+ await initialized;
406
+ await updateLearnCard(_learnCard);
407
+
408
+ const result = await client.firebase.getProofOfLoginVp.mutate({ token });
409
+
410
+ return result;
411
+ },
412
+ createPreferences: async (_learnCard, preferences) => {
413
+ await initialized;
414
+ await updateLearnCard(_learnCard);
415
+
416
+ const result = await client.preferences.createPreferences.mutate(preferences);
417
+
418
+ return result;
419
+ },
420
+ getPreferencesForDid: async _learnCard => {
421
+ await initialized;
422
+ await updateLearnCard(_learnCard);
423
+
424
+ const result = await client.preferences.getPreferencesForDid.query();
425
+
426
+ return result;
427
+ },
428
+ updatePreferences: async (_learnCard, preferences) => {
429
+ await initialized;
430
+ await updateLearnCard(_learnCard);
431
+
432
+ const result = await client.preferences.updatePreferences.mutate(preferences);
433
+
434
+ return result;
435
+ },
436
+ sendEndorsementShareLink: async (
437
+ _learnCard,
438
+ email,
439
+ shareLink,
440
+ issuer,
441
+ credential,
442
+ message
443
+ ) => {
444
+ await initialized;
445
+ await updateLearnCard(_learnCard);
446
+
447
+ const result = await client.credentials.sendEndorsementShareLink.mutate({
448
+ email,
449
+ shareLink,
450
+ issuer,
451
+ credential,
452
+ message,
453
+ });
454
+
455
+ return result;
456
+ },
457
+
458
+ // SSS Key Management Methods
459
+ getAuthShare: async (_learnCard, authToken, providerType) => {
460
+ await initialized;
461
+ await updateLearnCard(_learnCard);
462
+
463
+ return client.keys.getAuthShare.mutate({ authToken, providerType });
464
+ },
465
+
466
+ storeAuthShare: async (
467
+ _learnCard,
468
+ authToken,
469
+ providerType,
470
+ authShare,
471
+ primaryDid,
472
+ securityLevel
473
+ ) => {
474
+ await initialized;
475
+ await updateLearnCard(_learnCard);
476
+
477
+ return client.keys.storeAuthShare.mutate({
478
+ authToken,
479
+ providerType,
480
+ authShare,
481
+ primaryDid,
482
+ securityLevel,
483
+ });
484
+ },
485
+
486
+ addRecoveryMethod: async (
487
+ _learnCard,
488
+ authToken,
489
+ providerType,
490
+ type,
491
+ encryptedShare,
492
+ credentialId
493
+ ) => {
494
+ await initialized;
495
+ await updateLearnCard(_learnCard);
496
+
497
+ return client.keys.addRecoveryMethod.mutate({
498
+ authToken,
499
+ providerType,
500
+ type,
501
+ encryptedShare,
502
+ credentialId,
503
+ });
504
+ },
505
+
506
+ getRecoveryShare: async (
507
+ _learnCard,
508
+ authToken,
509
+ providerType,
510
+ type,
511
+ credentialId
512
+ ) => {
513
+ await initialized;
514
+ await updateLearnCard(_learnCard);
515
+
516
+ return client.keys.getRecoveryShare.query({
517
+ authToken,
518
+ providerType,
519
+ type,
520
+ credentialId,
521
+ });
522
+ },
523
+
524
+ markMigrated: async (_learnCard, authToken, providerType) => {
525
+ await initialized;
526
+ await updateLearnCard(_learnCard);
527
+
528
+ return client.keys.markMigrated.mutate({ authToken, providerType });
529
+ },
530
+
531
+ deleteUserKey: async (_learnCard, authToken, providerType) => {
532
+ await initialized;
533
+ await updateLearnCard(_learnCard);
534
+
535
+ return client.keys.deleteUserKey.mutate({ authToken, providerType });
536
+ },
537
+ },
538
+ };
539
+ } catch (e) {
540
+ console.error(
541
+ 'Unable to initialize LCA API Connection. Starting plugin in offline mode...',
542
+ e
543
+ );
544
+ return {
545
+ name: 'LearnCard App',
546
+ displayName: 'LearnCard App Plugin (Offline)',
547
+ description: 'Adds bespoke logic to the LearnCard App. (Unable to connect to LCA API)',
548
+ methods: {
549
+ registerDeviceForPushNotifications: async () => {
550
+ console.error('Unable to connect to LCA API. Plugin must be re-added.');
551
+ return false;
552
+ },
553
+ unregisterDeviceForPushNotifications: async () => {
554
+ console.error('Unable to connect to LCA API. Plugin must be re-added.');
555
+ return false;
556
+ },
557
+ getNotifications: async () => {
558
+ console.error('Unable to connect to LCA API. Plugin must be re-added.');
559
+ return false;
560
+ },
561
+ queryNotifications: async () => {
562
+ console.error('Unable to connect to LCA API. Plugin must be re-added.');
563
+ return false;
564
+ },
565
+ markAllNotificationsRead: async () => {
566
+ console.error('Unable to connect to LCA API. Plugin must be re-added.');
567
+ return false;
568
+ },
569
+ updateNotificationMeta: async () => {
570
+ console.error('Unable to connect to LCA API. Plugin must be re-added.');
571
+ return false;
572
+ },
573
+ createSigningAuthority: async () => {
574
+ console.error('Unable to connect to LCA API. Plugin must be re-added.');
575
+ return false;
576
+ },
577
+ getSigningAuthorities: async () => {
578
+ console.error('Unable to connect to LCA API. Plugin must be re-added.');
579
+ return false;
580
+ },
581
+ authorizeSigningAuthority: async () => {
582
+ console.error('Unable to connect to LCA API. Plugin must be re-added.');
583
+ return false;
584
+ },
585
+ resetLCAClient: async () => {
586
+ console.error('Unable to connect to LCA API. Plugin must be re-added.');
587
+ },
588
+ generateBoostInfo: async () => {
589
+ console.error('Unable to connect to LCA API. Plugin must be re-added.');
590
+ return {
591
+ title: '',
592
+ description: '',
593
+ category: '',
594
+ type: '',
595
+ skills: [],
596
+ narrative: '',
597
+ };
598
+ },
599
+ generateImage: async () => {
600
+ console.error('Unable to connect to LCA API. Plugin must be re-added.');
601
+ return '';
602
+ },
603
+ generateBoostSkills: async () => {
604
+ console.error('Unable to connect to LCA API. Plugin must be re-added.');
605
+ return [];
606
+ },
607
+ generateSkillIcons: async () => {
608
+ console.error('Unable to connect to LCA API. Plugin must be re-added.');
609
+ return {};
610
+ },
611
+ createPin: async () => {
612
+ console.error('Unable to connect to LCA API. Plugin must be re-added.');
613
+ return false;
614
+ },
615
+ hasPin: async () => {
616
+ console.error('Unable to connect to LCA API. Plugin must be re-added.');
617
+ return false;
618
+ },
619
+ verifyPin: async () => {
620
+ console.error('Unable to connect to LCA API. Plugin must be re-added.');
621
+ return false;
622
+ },
623
+ updatePin: async () => {
624
+ console.error('Unable to connect to LCA API. Plugin must be re-added.');
625
+ return false;
626
+ },
627
+ generatePinUpdateToken: async () => {
628
+ console.error('Unable to connect to LCA API. Plugin must be re-added.');
629
+ return null;
630
+ },
631
+ validatePinUpdateToken: async () => {
632
+ console.error('Unable to connect to LCA API. Plugin must be re-added.');
633
+ return false;
634
+ },
635
+ updatePinWithToken: async () => {
636
+ console.error('Unable to connect to LCA API. Plugin must be re-added.');
637
+ return false;
638
+ },
639
+ generateAnalyticsAccessToken: async () => {
640
+ console.error('Unable to connect to LCA API. Plugin must be re-added.');
641
+ return null;
642
+ },
643
+ decryptDagJwe: async (_learnCard, jwe, jwks = []) =>
644
+ initialLearnCard.invoke.decryptDagJwe(jwe, jwks),
645
+ hash: async () => undefined,
646
+
647
+ getFirebaseUserByEmail: async () => {
648
+ console.error('Unable to connect to LCA API. Plugin must be re-added.');
649
+ return null;
650
+ },
651
+
652
+ authenticateWithKeycloak: async () => {
653
+ console.error('Unable to connect to LCA API. Plugin must be re-added.');
654
+ return { firebaseToken: '' };
655
+ },
656
+ authenticateWithScoutsSSO: async () => {
657
+ console.error('Unable to connect to LCA API. Plugin must be re-added.');
658
+ return null;
659
+ },
660
+ sendLoginVerificationCode: async () => {
661
+ console.error('Unable to connect to LCA API. Plugin must be re-added.');
662
+ return { success: false, message: '' };
663
+ },
664
+ verifyLoginCode: async () => {
665
+ console.error('Unable to connect to LCA API. Plugin must be re-added.');
666
+ return { success: false, message: '' };
667
+ },
668
+ verifyNetworkHandoffToken: async () => {
669
+ console.error('Unable to connect to LCA API. Plugin must be re-added.');
670
+ return { success: false, message: '' };
671
+ },
672
+ getProofOfLoginVp: async () => {
673
+ console.error('Unable to connect to LCA API. Plugin must be re-added.');
674
+ return { success: false, error: 'Offline' };
675
+ },
676
+ createPreferences: async () => {
677
+ console.error('Unable to connect to LCA API. Plugin must be re-added.');
678
+ return false;
679
+ },
680
+ updatePreferences: async () => {
681
+ console.error('Unable to connect to LCA API. Plugin must be re-added.');
682
+ return false;
683
+ },
684
+ getPreferencesForDid: async () => {
685
+ console.error('Unable to connect to LCA API. Plugin must be re-added.');
686
+ return { theme: ThemeEnum.Colorful };
687
+ },
688
+ sendEndorsementShareLink: async () => {
689
+ console.error('Unable to connect to LCA API. Plugin must be re-added.');
690
+ return false;
691
+ },
692
+
693
+ // SSS Key Management Methods (Offline)
694
+ getAuthShare: async () => {
695
+ console.error('Unable to connect to LCA API. Plugin must be re-added.');
696
+ return null;
697
+ },
698
+ storeAuthShare: async () => {
699
+ console.error('Unable to connect to LCA API. Plugin must be re-added.');
700
+ return { success: false };
701
+ },
702
+ addRecoveryMethod: async () => {
703
+ console.error('Unable to connect to LCA API. Plugin must be re-added.');
704
+ return { success: false };
705
+ },
706
+ getRecoveryShare: async () => {
707
+ console.error('Unable to connect to LCA API. Plugin must be re-added.');
708
+ return null;
709
+ },
710
+ markMigrated: async () => {
711
+ console.error('Unable to connect to LCA API. Plugin must be re-added.');
712
+ return { success: false };
713
+ },
714
+ deleteUserKey: async () => {
715
+ console.error('Unable to connect to LCA API. Plugin must be re-added.');
716
+ return { success: false };
717
+ },
718
+ },
719
+ };
720
+ }
721
+ };