@learncard/network-plugin 2.10.15 → 2.11.3

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.
@@ -13479,6 +13479,42 @@ var UnsignedAchievementCredentialValidator = UnsignedVCValidator.extend({
13479
13479
  var AchievementCredentialValidator = UnsignedAchievementCredentialValidator.extend({
13480
13480
  proof: ProofValidator.or(ProofValidator.array())
13481
13481
  });
13482
+ var AssociationTypeValidator = external_exports.enum([
13483
+ "exactMatchOf",
13484
+ "extends",
13485
+ "isChildOf",
13486
+ "isParentOf",
13487
+ "isPartOf",
13488
+ "isPeerOf",
13489
+ "isRelatedTo",
13490
+ "precedes",
13491
+ "replacedBy"
13492
+ ]).or(external_exports.string());
13493
+ var AssociationValidator = external_exports.object({
13494
+ type: external_exports.string().array().nonempty(),
13495
+ associationType: AssociationTypeValidator,
13496
+ sourceId: external_exports.string().optional(),
13497
+ targetId: external_exports.string()
13498
+ }).catchall(external_exports.any());
13499
+ var ClrSubjectValidator = external_exports.object({
13500
+ id: external_exports.string().optional(),
13501
+ type: external_exports.string().array().nonempty(),
13502
+ identifier: external_exports.any().array().optional(),
13503
+ achievement: AchievementValidator.array().optional(),
13504
+ association: AssociationValidator.array().optional(),
13505
+ verifiableCredential: external_exports.any().array().optional()
13506
+ }).catchall(external_exports.any());
13507
+ var UnsignedClrCredentialValidator = UnsignedVCValidator.extend({
13508
+ name: external_exports.string().optional(),
13509
+ description: external_exports.string().optional(),
13510
+ image: ImageValidator.optional(),
13511
+ credentialSubject: ClrSubjectValidator.or(ClrSubjectValidator.array()),
13512
+ endorsement: EndorsementCredentialValidator.array().optional(),
13513
+ partial: external_exports.boolean().optional()
13514
+ });
13515
+ var ClrCredentialValidator = UnsignedClrCredentialValidator.extend({
13516
+ proof: ProofValidator.or(ProofValidator.array())
13517
+ });
13482
13518
  var VerificationCheckValidator = external_exports.object({
13483
13519
  checks: external_exports.string().array(),
13484
13520
  warnings: external_exports.string().array(),
@@ -13830,10 +13866,16 @@ var SendBrandingOptionsValidator = external_exports.object({
13830
13866
  credentialName: external_exports.string().optional().describe("Display name for the credential"),
13831
13867
  recipientName: external_exports.string().optional().describe("Name of the recipient for personalization")
13832
13868
  });
13869
+ var GuardianStatusValidator = external_exports.enum([
13870
+ "AWAITING_GUARDIAN",
13871
+ "GUARDIAN_APPROVED",
13872
+ "GUARDIAN_REJECTED"
13873
+ ]);
13833
13874
  var SendOptionsValidator = external_exports.object({
13834
13875
  webhookUrl: external_exports.string().url().optional().describe("Webhook URL to receive claim notifications"),
13835
13876
  suppressDelivery: external_exports.boolean().optional().describe("If true, returns claimUrl without sending email/SMS"),
13836
- branding: SendBrandingOptionsValidator.optional().describe("Branding for email/SMS delivery")
13877
+ branding: SendBrandingOptionsValidator.optional().describe("Branding for email/SMS delivery"),
13878
+ guardianEmail: external_exports.string().email().optional().describe("Guardian email that must approve before student can claim")
13837
13879
  });
13838
13880
  var SendBoostInputValidator = external_exports.object({
13839
13881
  type: external_exports.literal("boost"),
@@ -13850,11 +13892,25 @@ var SendBoostInputValidator = external_exports.object({
13850
13892
  }).refine((data) => data.templateUri || data.template || data.signedCredential, {
13851
13893
  message: "Either templateUri, template, or signedCredential must be provided.",
13852
13894
  path: ["templateUri"]
13853
- });
13895
+ }).refine(
13896
+ (data) => {
13897
+ if (data.options?.guardianEmail) {
13898
+ return data.options.guardianEmail.toLowerCase() !== data.recipient.toLowerCase();
13899
+ }
13900
+ return true;
13901
+ },
13902
+ {
13903
+ message: "guardianEmail must differ from recipient (self-approval not allowed)",
13904
+ path: ["options", "guardianEmail"]
13905
+ }
13906
+ );
13854
13907
  var SendInboxResponseValidator = external_exports.object({
13855
13908
  issuanceId: external_exports.string(),
13856
13909
  status: external_exports.enum(["PENDING", "ISSUED", "EXPIRED", "DELIVERED", "CLAIMED"]),
13857
- claimUrl: external_exports.string().url().optional().describe("Present when suppressDelivery=true")
13910
+ claimUrl: external_exports.string().url().optional().describe("Present when suppressDelivery=true"),
13911
+ guardianStatus: GuardianStatusValidator.optional().describe(
13912
+ "Present when guardianEmail was specified"
13913
+ )
13858
13914
  });
13859
13915
  var SendBoostResponseValidator = external_exports.object({
13860
13916
  type: external_exports.literal("boost"),
@@ -14091,7 +14147,11 @@ var LCNNotificationTypeEnumValidator = external_exports.enum([
14091
14147
  "APP_LISTING_APPROVED",
14092
14148
  "APP_LISTING_REJECTED",
14093
14149
  "APP_LISTING_WITHDRAWN",
14094
- "DEVICE_LINK_REQUEST"
14150
+ "DEVICE_LINK_REQUEST",
14151
+ "GUARDIAN_APPROVAL_PENDING",
14152
+ "GUARDIAN_APPROVED",
14153
+ "GUARDIAN_REJECTED",
14154
+ "APP_NOTIFICATION"
14095
14155
  ]);
14096
14156
  var LCNNotificationMessageValidator = external_exports.object({
14097
14157
  title: external_exports.string().optional(),
@@ -14129,7 +14189,10 @@ var LCNNotificationDataValidator = external_exports.object({
14129
14189
  var LCNNotificationValidator = external_exports.object({
14130
14190
  type: LCNNotificationTypeEnumValidator,
14131
14191
  to: LCNProfileValidator.partial().and(external_exports.object({ did: external_exports.string() })),
14132
- from: LCNProfileValidator.partial().and(external_exports.object({ did: external_exports.string() })),
14192
+ from: external_exports.union([
14193
+ external_exports.string(),
14194
+ LCNProfileValidator.partial().and(external_exports.object({ did: external_exports.string() }))
14195
+ ]),
14133
14196
  message: LCNNotificationMessageValidator.optional(),
14134
14197
  data: LCNNotificationDataValidator.optional(),
14135
14198
  sent: external_exports.iso.datetime().optional(),
@@ -14234,7 +14297,12 @@ var InboxCredentialValidator = external_exports.object({
14234
14297
  signingAuthority: external_exports.object({
14235
14298
  endpoint: external_exports.string().optional(),
14236
14299
  name: external_exports.string().optional()
14237
- }).optional()
14300
+ }).optional(),
14301
+ // Guardian gate fields (all optional — absent on pre-existing credentials)
14302
+ guardianEmail: external_exports.string().email().optional(),
14303
+ guardianStatus: GuardianStatusValidator.optional(),
14304
+ guardianApprovedAt: external_exports.string().optional(),
14305
+ guardianApprovedByDid: external_exports.string().optional()
14238
14306
  });
14239
14307
  var PaginatedInboxCredentialsValidator = external_exports.object({
14240
14308
  hasMore: external_exports.boolean(),
@@ -14702,11 +14770,84 @@ var GetTemplateRecipientsEventValidator = external_exports.object({
14702
14770
  }).refine((input) => Boolean(input.templateAlias) !== Boolean(input.boostUri), {
14703
14771
  message: "Exactly one of templateAlias or boostUri is required"
14704
14772
  });
14773
+ var RequestLearnerContextEventValidator = external_exports.object({
14774
+ type: external_exports.literal("request-learner-context"),
14775
+ includeCredentials: external_exports.boolean().optional().default(true),
14776
+ includePersonalData: external_exports.boolean().optional().default(false),
14777
+ format: external_exports.enum(["prompt", "structured"]).optional().default("prompt"),
14778
+ instructions: external_exports.string().optional(),
14779
+ detailLevel: external_exports.enum(["compact", "expanded"]).optional().default("compact")
14780
+ });
14781
+ var SummaryCredentialKeywordValidator = external_exports.object({
14782
+ occupations: external_exports.array(external_exports.string()).nullable(),
14783
+ careers: external_exports.array(external_exports.string()).nullable(),
14784
+ jobs: external_exports.array(external_exports.string()).nullable(),
14785
+ skills: external_exports.array(external_exports.string()).nullable(),
14786
+ fieldOfStudy: external_exports.string().nullable()
14787
+ });
14788
+ var SummaryCredentialDataValidator = external_exports.object({
14789
+ title: external_exports.string().describe("Short, concise title for the learning session or credential"),
14790
+ summary: external_exports.string().describe("Comprehensive summary of what happened during the session"),
14791
+ learned: external_exports.array(external_exports.string()).describe("Bullet points of key knowledge gained"),
14792
+ skills: external_exports.array(
14793
+ external_exports.object({
14794
+ title: external_exports.string().describe("Name of the skill category"),
14795
+ description: external_exports.string().describe("Detailed description of what this skill category involves")
14796
+ })
14797
+ ).describe("Categorized skills learned during the session"),
14798
+ nextSteps: external_exports.array(
14799
+ external_exports.object({
14800
+ title: external_exports.string().describe("Title of the suggested next step"),
14801
+ description: external_exports.string().describe("Description explaining why this next step is recommended"),
14802
+ keywords: SummaryCredentialKeywordValidator
14803
+ })
14804
+ ).describe("Recommended follow-up activities or learning modules"),
14805
+ reflections: external_exports.array(
14806
+ external_exports.object({
14807
+ title: external_exports.string().describe("Title of the reflection"),
14808
+ description: external_exports.string().describe("Detailed description of what this reflection involves")
14809
+ })
14810
+ ).describe("Reflections on the learning experience")
14811
+ });
14812
+ var SendAiSessionCredentialEventValidator = external_exports.object({
14813
+ type: external_exports.literal("send-ai-session-credential"),
14814
+ sessionTitle: external_exports.string(),
14815
+ summaryData: SummaryCredentialDataValidator,
14816
+ metadata: external_exports.record(external_exports.string(), external_exports.unknown()).optional()
14817
+ });
14818
+ var SendNotificationEventValidator = external_exports.object({
14819
+ type: external_exports.literal("send-notification"),
14820
+ title: external_exports.string().optional(),
14821
+ body: external_exports.string().optional(),
14822
+ actionPath: external_exports.string().optional(),
14823
+ category: external_exports.string().optional(),
14824
+ priority: external_exports.enum(["normal", "high"]).optional()
14825
+ });
14826
+ var counterKeyValidator = external_exports.string().min(1).max(64).regex(/^[a-zA-Z0-9_-]+$/, "Key must be alphanumeric with _ or -");
14827
+ var IncrementCounterEventValidator = external_exports.object({
14828
+ type: external_exports.literal("increment-counter"),
14829
+ key: counterKeyValidator,
14830
+ amount: external_exports.number().int().finite()
14831
+ });
14832
+ var GetCounterEventValidator = external_exports.object({
14833
+ type: external_exports.literal("get-counter"),
14834
+ key: counterKeyValidator
14835
+ });
14836
+ var GetCountersEventValidator = external_exports.object({
14837
+ type: external_exports.literal("get-counters"),
14838
+ keys: external_exports.array(counterKeyValidator).min(1).max(50).optional()
14839
+ });
14705
14840
  var AppEventValidator = external_exports.discriminatedUnion("type", [
14706
14841
  SendCredentialEventValidator,
14707
14842
  CheckCredentialEventValidator,
14708
14843
  CheckIssuanceStatusEventValidator,
14709
- GetTemplateRecipientsEventValidator
14844
+ GetTemplateRecipientsEventValidator,
14845
+ RequestLearnerContextEventValidator,
14846
+ SendAiSessionCredentialEventValidator,
14847
+ SendNotificationEventValidator,
14848
+ IncrementCounterEventValidator,
14849
+ GetCounterEventValidator,
14850
+ GetCountersEventValidator
14710
14851
  ]);
14711
14852
  var AppEventInputValidator = external_exports.object({
14712
14853
  listingId: external_exports.string(),
@@ -14737,7 +14878,7 @@ var CredentialActivityValidator = external_exports.object({
14737
14878
  activityId: external_exports.string(),
14738
14879
  eventType: CredentialActivityEventTypeValidator,
14739
14880
  timestamp: external_exports.string(),
14740
- actorProfileId: external_exports.string(),
14881
+ actorProfileId: external_exports.string().optional(),
14741
14882
  recipientType: CredentialActivityRecipientTypeValidator,
14742
14883
  recipientIdentifier: external_exports.string(),
14743
14884
  boostUri: external_exports.string().optional(),
@@ -15258,24 +15399,63 @@ var escapeJsonStringValue = /* @__PURE__ */ __name((value) => {
15258
15399
  if (value === null || value === void 0) return "";
15259
15400
  return String(value).replace(/\\/g, "\\\\").replace(/"/g, '\\"').replace(/\n/g, "\\n").replace(/\r/g, "\\r").replace(/\t/g, "\\t").replace(/\f/g, "\\f").replace(/[\b]/g, "\\b");
15260
15401
  }, "escapeJsonStringValue");
15402
+ var prepareTemplateValue = /* @__PURE__ */ __name((value) => {
15403
+ if (value === null || value === void 0) return "";
15404
+ if (Array.isArray(value)) return value.map(prepareTemplateValue);
15405
+ if (typeof value === "object") {
15406
+ return Object.fromEntries(
15407
+ Object.entries(value).map(([key, nestedValue]) => [
15408
+ key,
15409
+ prepareTemplateValue(nestedValue)
15410
+ ])
15411
+ );
15412
+ }
15413
+ if (typeof value === "string") return escapeJsonStringValue(value);
15414
+ return value;
15415
+ }, "prepareTemplateValue");
15261
15416
  var prepareTemplateData = /* @__PURE__ */ __name((templateData) => {
15262
15417
  const prepared = {};
15263
15418
  for (const [key, value] of Object.entries(templateData)) {
15264
- prepared[key] = escapeJsonStringValue(value);
15419
+ prepared[key] = prepareTemplateValue(value);
15265
15420
  }
15266
15421
  return prepared;
15267
15422
  }, "prepareTemplateData");
15268
15423
  var renderTemplateJson = /* @__PURE__ */ __name((jsonString, templateData) => {
15269
15424
  const preparedData = prepareTemplateData(templateData);
15270
- const unescapedTemplate = jsonString.replace(/\{\{([^{}]+)\}\}/g, "{{{$1}}}");
15425
+ const unescapedTemplate = jsonString.replace(/\{\{\s*([^{}]+?)\s*\}\}/g, (match, tag) => {
15426
+ const trimmedTag = tag.trim();
15427
+ return /^[#^/!>&=]/.test(trimmedTag) ? match : `{{{${trimmedTag}}}}`;
15428
+ });
15271
15429
  return mustache_default.render(unescapedTemplate, preparedData);
15272
15430
  }, "renderTemplateJson");
15431
+ var hasDynamicEvidenceTemplate = /* @__PURE__ */ __name((jsonString) => {
15432
+ return /\{\{\s*[#^/]?\s*evidence(?:[.\s}]|$)/.test(jsonString);
15433
+ }, "hasDynamicEvidenceTemplate");
15434
+ var appendTemplateEvidence = /* @__PURE__ */ __name((boost, templateData, allowAutoAppend = true) => {
15435
+ if (!allowAutoAppend) return boost;
15436
+ const templateEvidence = templateData?.evidence;
15437
+ if (!templateEvidence) return boost;
15438
+ const normalizedTemplateEvidence = (Array.isArray(templateEvidence) ? templateEvidence : [templateEvidence]).map((evidenceItem) => {
15439
+ if (evidenceItem && typeof evidenceItem === "object" && "last" in evidenceItem) {
15440
+ const { last, ...rest } = evidenceItem;
15441
+ return rest;
15442
+ }
15443
+ return evidenceItem;
15444
+ });
15445
+ if (normalizedTemplateEvidence.length === 0) return boost;
15446
+ const existingEvidence = boost.evidence ? Array.isArray(boost.evidence) ? boost.evidence : [boost.evidence] : [];
15447
+ return {
15448
+ ...boost,
15449
+ evidence: [...existingEvidence, ...normalizedTemplateEvidence]
15450
+ };
15451
+ }, "appendTemplateEvidence");
15273
15452
  var hasDid = /* @__PURE__ */ __name((profile) => {
15274
15453
  return !!profile && "did" in profile && typeof profile.did === "string" && profile.did.length > 0;
15275
15454
  }, "hasDid");
15276
15455
  async function getLearnCardNetworkPlugin(learnCard, url2, apiTokenOrOptions, options) {
15277
15456
  const apiToken = typeof apiTokenOrOptions === "string" ? apiTokenOrOptions : void 0;
15278
15457
  const guardianApprovalGetter = (typeof apiTokenOrOptions === "object" ? apiTokenOrOptions?.guardianApprovalGetter : void 0) ?? options?.guardianApprovalGetter;
15458
+ const extraHeaders = (typeof apiTokenOrOptions === "object" ? apiTokenOrOptions?.extraHeaders : void 0) ?? options?.extraHeaders;
15279
15459
  let did = "";
15280
15460
  try {
15281
15461
  const idPlane = learnCard?.id;
@@ -15286,7 +15466,7 @@ async function getLearnCardNetworkPlugin(learnCard, url2, apiTokenOrOptions, opt
15286
15466
  learnCard?.debug?.("LCN: no local DID available at init; will fetch from profile");
15287
15467
  }
15288
15468
  learnCard?.debug?.("Adding LearnCardNetwork Plugin");
15289
- const client = apiToken ? await getApiTokenClient(url2, apiToken, guardianApprovalGetter) : await getClient(
15469
+ const client = apiToken ? await getApiTokenClient(url2, apiToken, guardianApprovalGetter, extraHeaders) : await getClient(
15290
15470
  url2,
15291
15471
  async (challenge) => {
15292
15472
  const jwt2 = await learnCard.invoke.getDidAuthVp({
@@ -15296,7 +15476,8 @@ async function getLearnCardNetworkPlugin(learnCard, url2, apiTokenOrOptions, opt
15296
15476
  if (typeof jwt2 !== "string") throw new Error("Error getting DID-Auth-JWT!");
15297
15477
  return jwt2;
15298
15478
  },
15299
- guardianApprovalGetter
15479
+ guardianApprovalGetter,
15480
+ extraHeaders
15300
15481
  );
15301
15482
  let userData;
15302
15483
  learnCard?.debug?.("LCN: initial getProfile query starting", { apiToken: !!apiToken });
@@ -15340,6 +15521,43 @@ async function getLearnCardNetworkPlugin(learnCard, url2, apiTokenOrOptions, opt
15340
15521
  return _learnCard.invoke.resolveFromLCN(boostUri);
15341
15522
  }
15342
15523
  }, "getBoostTemplateForIssuance");
15524
+ const getInboxEndpointForDid = /* @__PURE__ */ __name(async (_learnCard, recipientDid) => {
15525
+ const serviceUrl = new URL(url2);
15526
+ const serviceDomain = `${serviceUrl.hostname}${serviceUrl.port ? `%3A${serviceUrl.port}` : ""}`;
15527
+ const localServiceDid = `did:web:${serviceDomain}`;
15528
+ const getInferredServiceDid = /* @__PURE__ */ __name((did2) => {
15529
+ if (!did2.startsWith("did:web:")) return null;
15530
+ const parts = did2.split(":");
15531
+ if (parts.length < 3) return null;
15532
+ const pathMarkerIndex = parts.findIndex((part, index) => {
15533
+ if (index < 3) return false;
15534
+ return part === "users" || part === "app" || part === "manager";
15535
+ });
15536
+ if (pathMarkerIndex === -1) {
15537
+ return did2;
15538
+ }
15539
+ return `did:web:${parts.slice(2, pathMarkerIndex).join(":")}`;
15540
+ }, "getInferredServiceDid");
15541
+ const getInboxService = /* @__PURE__ */ __name((didDoc2) => didDoc2.service?.find((service) => {
15542
+ const type = Array.isArray(service.type) ? service.type[0] : service.type;
15543
+ return type === "UniversalInboxService" || type === "LearnCardInboxService";
15544
+ }), "getInboxService");
15545
+ const inferredServiceDid = getInferredServiceDid(recipientDid);
15546
+ if (inferredServiceDid === localServiceDid) {
15547
+ return `${serviceUrl.origin}/api/inbox/receive`;
15548
+ }
15549
+ const didDoc = await _learnCard.invoke.resolveDid(recipientDid);
15550
+ const inboxService = getInboxService(didDoc);
15551
+ if ((inboxService?.serviceDid || inferredServiceDid) === localServiceDid) {
15552
+ return `${serviceUrl.origin}/api/inbox/receive`;
15553
+ }
15554
+ if (!inboxService?.serviceEndpoint) {
15555
+ throw new Error(
15556
+ `Recipient DID ${recipientDid} does not have a UniversalInboxService endpoint in its DID document`
15557
+ );
15558
+ }
15559
+ return inboxService.serviceEndpoint;
15560
+ }, "getInboxEndpointForDid");
15343
15561
  return {
15344
15562
  name: "LearnCard Network",
15345
15563
  displayName: "LearnCard Network",
@@ -15397,7 +15615,11 @@ async function getLearnCardNetworkPlugin(learnCard, url2, apiTokenOrOptions, opt
15397
15615
  }
15398
15616
  const jwe = await _learnCard.invoke.createDagJwe(credential, recipientsList);
15399
15617
  return client.storage.store.mutate({ item: jwe });
15400
- }, "uploadEncrypted")
15618
+ }, "uploadEncrypted"),
15619
+ delete: /* @__PURE__ */ __name(async (_learnCard, uri) => {
15620
+ await ensureUser();
15621
+ return client.credential.deleteCredential.mutate({ uri });
15622
+ }, "delete")
15401
15623
  },
15402
15624
  methods: {
15403
15625
  createProfile: /* @__PURE__ */ __name(async (_learnCard, profile) => {
@@ -15450,6 +15672,22 @@ async function getLearnCardNetworkPlugin(learnCard, url2, apiTokenOrOptions, opt
15450
15672
  getManagedProfiles: /* @__PURE__ */ __name(async (_learnCard, options2 = {}) => {
15451
15673
  return client.profileManager.getManagedProfiles.query(options2);
15452
15674
  }, "getManagedProfiles"),
15675
+ claimPendingGuardianLinks: /* @__PURE__ */ __name(async () => {
15676
+ await ensureUser();
15677
+ return client.inbox.claimPendingGuardianLinks.mutate({});
15678
+ }, "claimPendingGuardianLinks"),
15679
+ getMyManagedChildren: /* @__PURE__ */ __name(async () => {
15680
+ await ensureUser();
15681
+ return client.profileManager.getMyManagedChildren.query();
15682
+ }, "getMyManagedChildren"),
15683
+ getMyGuardians: /* @__PURE__ */ __name(async () => {
15684
+ await ensureUser();
15685
+ return client.profileManager.getMyGuardians.query();
15686
+ }, "getMyGuardians"),
15687
+ removeManagesRelationship: /* @__PURE__ */ __name(async (_learnCard, profileId) => {
15688
+ await ensureUser();
15689
+ return client.profileManager.removeManagesRelationship.mutate({ profileId });
15690
+ }, "removeManagesRelationship"),
15453
15691
  getManagedServiceProfiles: /* @__PURE__ */ __name(async (_learnCard, options2 = {}) => {
15454
15692
  await ensureUser();
15455
15693
  return client.profile.getManagedServiceProfiles.query(options2);
@@ -15584,6 +15822,49 @@ async function getLearnCardNetworkPlugin(learnCard, url2, apiTokenOrOptions, opt
15584
15822
  }, "getBlockedProfiles"),
15585
15823
  sendCredential: /* @__PURE__ */ __name(async (_learnCard, profileId, vc, metadataOrEncrypt, encrypt) => {
15586
15824
  await ensureUser();
15825
+ if (profileId.startsWith("did:web:")) {
15826
+ const inboxEndpoint = await getInboxEndpointForDid(_learnCard, profileId);
15827
+ let metadata2;
15828
+ if (typeof metadataOrEncrypt === "object") {
15829
+ metadata2 = metadataOrEncrypt;
15830
+ }
15831
+ const myProfile = await client.profile.getProfile.query();
15832
+ const issuerDid = myProfile?.did || await client.utilities.getDid.query();
15833
+ const issuerDisplayName = myProfile?.displayName || "Unknown Issuer";
15834
+ const signedCredential = await _learnCard.invoke.issueCredential(vc);
15835
+ const didAuthJwt = await _learnCard.invoke.getDidAuthVp({
15836
+ proofFormat: "jwt",
15837
+ challenge: `inbox-federation-${crypto.randomUUID()}`
15838
+ });
15839
+ let receiveUrl = inboxEndpoint;
15840
+ if (receiveUrl.includes("localhost")) {
15841
+ receiveUrl = receiveUrl.replace("https://", "http://");
15842
+ }
15843
+ const response = await fetch(receiveUrl, {
15844
+ method: "POST",
15845
+ headers: {
15846
+ "Content-Type": "application/json",
15847
+ "Authorization": `Bearer ${didAuthJwt}`
15848
+ },
15849
+ body: JSON.stringify({
15850
+ recipientDid: profileId,
15851
+ credential: signedCredential,
15852
+ issuerDid,
15853
+ issuerDisplayName,
15854
+ configuration: {
15855
+ ...metadata2,
15856
+ federatedFrom: issuerDid
15857
+ }
15858
+ }),
15859
+ signal: AbortSignal.timeout(3e4)
15860
+ });
15861
+ if (!response.ok) {
15862
+ const error46 = await response.text();
15863
+ throw new Error(`Federation failed: ${error46}`);
15864
+ }
15865
+ const result = await response.json();
15866
+ return result.issuanceId;
15867
+ }
15587
15868
  let metadata;
15588
15869
  let shouldEncrypt = true;
15589
15870
  if (typeof metadataOrEncrypt === "boolean") {
@@ -15921,10 +16202,16 @@ async function getLearnCardNetworkPlugin(learnCard, url2, apiTokenOrOptions, opt
15921
16202
  }
15922
16203
  if (boost?.type?.includes("BoostCredential")) boost.boostId = boostUri;
15923
16204
  if (typeof options2 === "object" && options2.templateData && Object.keys(options2.templateData).length > 0) {
16205
+ const boostString = JSON.stringify(boost);
16206
+ const allowAutoAppendEvidence = !hasDynamicEvidenceTemplate(boostString);
15924
16207
  try {
15925
- const boostString = JSON.stringify(boost);
15926
16208
  const rendered = renderTemplateJson(boostString, options2.templateData);
15927
16209
  boost = JSON.parse(rendered);
16210
+ boost = appendTemplateEvidence(
16211
+ boost,
16212
+ options2.templateData,
16213
+ allowAutoAppendEvidence
16214
+ );
15928
16215
  } catch (error46) {
15929
16216
  throw new Error(
15930
16217
  `Template substitution failed: ${error46 instanceof Error ? error46.message : "Unknown error"}. Please check your templateData variables and ensure the rendered output is valid JSON.`
@@ -16004,6 +16291,61 @@ async function getLearnCardNetworkPlugin(learnCard, url2, apiTokenOrOptions, opt
16004
16291
  const isDid = recipient.startsWith("did:");
16005
16292
  const isEmail = /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(recipient);
16006
16293
  const isPhone = /^\+?[\d\s-]{10,}$/.test(recipient.replace(/[\s-]/g, ""));
16294
+ const serviceUrl = new URL(url2);
16295
+ const serviceDomain = `${serviceUrl.hostname}${serviceUrl.port ? `%3A${serviceUrl.port}` : ""}`;
16296
+ const recipientDomain = recipient.startsWith("did:web:") ? recipient.split(":")[2] : void 0;
16297
+ const isRemoteDidWebRecipient = recipient.startsWith("did:web:") && recipientDomain !== serviceDomain;
16298
+ if (isRemoteDidWebRecipient && input.templateUri) {
16299
+ const boostRecord = await _learnCard.invoke.getBoost(input.templateUri);
16300
+ let boost = boostRecord.boost;
16301
+ const boostString = JSON.stringify(boost);
16302
+ const allowAutoAppendEvidence = !hasDynamicEvidenceTemplate(boostString);
16303
+ if (input.templateData && Object.keys(input.templateData).length > 0) {
16304
+ const rendered = renderTemplateJson(boostString, input.templateData);
16305
+ boost = JSON.parse(rendered);
16306
+ boost = appendTemplateEvidence(
16307
+ boost,
16308
+ input.templateData,
16309
+ allowAutoAppendEvidence
16310
+ );
16311
+ }
16312
+ if (isVC2Format(boost)) {
16313
+ boost.validFrom = (/* @__PURE__ */ new Date()).toISOString();
16314
+ } else {
16315
+ boost.issuanceDate = (/* @__PURE__ */ new Date()).toISOString();
16316
+ }
16317
+ boost.issuer = _learnCard.id.did();
16318
+ if (Array.isArray(boost.credentialSubject)) {
16319
+ boost.credentialSubject = boost.credentialSubject.map((subject) => ({
16320
+ ...subject,
16321
+ id: recipient
16322
+ }));
16323
+ } else {
16324
+ boost.credentialSubject = {
16325
+ ...boost.credentialSubject,
16326
+ id: recipient
16327
+ };
16328
+ }
16329
+ if (boost.type?.includes("BoostCredential")) {
16330
+ boost.boostId = input.templateUri;
16331
+ }
16332
+ const signedCredential = await _learnCard.invoke.issueCredential(boost);
16333
+ const credentialUri = await _learnCard.invoke.sendCredential(
16334
+ recipient,
16335
+ signedCredential,
16336
+ {
16337
+ boostUri: input.templateUri,
16338
+ templateData: input.templateData,
16339
+ integrationId: input.integrationId
16340
+ }
16341
+ );
16342
+ return {
16343
+ type: "boost",
16344
+ credentialUri,
16345
+ uri: input.templateUri,
16346
+ activityId: ""
16347
+ };
16348
+ }
16007
16349
  const canIssueLocally = "issueCredential" in _learnCard.invoke;
16008
16350
  const isDirectRecipient = isDid || !isEmail && !isPhone;
16009
16351
  if (canIssueLocally && isDirectRecipient && input.templateUri) {
@@ -16018,19 +16360,24 @@ async function getLearnCardNetworkPlugin(learnCard, url2, apiTokenOrOptions, opt
16018
16360
  targetDid = recipient;
16019
16361
  } else {
16020
16362
  const targetProfile = await _learnCard.invoke.getProfile(recipient);
16021
- if (!hasDid(targetProfile))
16022
- return client.boost.send.mutate(input);
16363
+ if (!hasDid(targetProfile)) return client.boost.send.mutate(input);
16023
16364
  targetDid = targetProfile.did;
16024
16365
  }
16025
16366
  let boost = data.data;
16367
+ const boostString = JSON.stringify(boost);
16368
+ const allowAutoAppendEvidence = !hasDynamicEvidenceTemplate(boostString);
16026
16369
  if (input.templateData && Object.keys(input.templateData).length > 0) {
16027
16370
  try {
16028
- const boostString = JSON.stringify(boost);
16029
16371
  const rendered = renderTemplateJson(
16030
16372
  boostString,
16031
16373
  input.templateData
16032
16374
  );
16033
16375
  boost = JSON.parse(rendered);
16376
+ boost = appendTemplateEvidence(
16377
+ boost,
16378
+ input.templateData,
16379
+ allowAutoAppendEvidence
16380
+ );
16034
16381
  } catch (error46) {
16035
16382
  throw new Error(
16036
16383
  `Failed to apply template data: ${error46 instanceof Error ? error46.message : "Unknown error"}`
@@ -16057,6 +16404,23 @@ async function getLearnCardNetworkPlugin(learnCard, url2, apiTokenOrOptions, opt
16057
16404
  if (boost?.type?.includes("BoostCredential"))
16058
16405
  boost.boostId = input.templateUri;
16059
16406
  const signedCredential = await _learnCard.invoke.issueCredential(boost);
16407
+ if (isDid && recipient.startsWith("did:web:")) {
16408
+ const credentialUri = await _learnCard.invoke.sendCredential(
16409
+ recipient,
16410
+ signedCredential,
16411
+ {
16412
+ boostUri: input.templateUri,
16413
+ templateData: input.templateData,
16414
+ integrationId: input.integrationId
16415
+ }
16416
+ );
16417
+ return {
16418
+ type: "boost",
16419
+ credentialUri,
16420
+ uri: input.templateUri,
16421
+ activityId: ""
16422
+ };
16423
+ }
16060
16424
  return client.boost.send.mutate({
16061
16425
  ...input,
16062
16426
  signedCredential
@@ -16332,6 +16696,26 @@ async function getLearnCardNetworkPlugin(learnCard, url2, apiTokenOrOptions, opt
16332
16696
  approveGuardianRequestByPath: /* @__PURE__ */ __name(async (_learnCard, token) => {
16333
16697
  return client.inbox.approveGuardianRequestByPath.query({ token });
16334
16698
  }, "approveGuardianRequestByPath"),
16699
+ getGuardianPendingCredential: /* @__PURE__ */ __name(async (_learnCard, token) => {
16700
+ return client.inbox.getGuardianPendingCredential.query({ token });
16701
+ }, "getGuardianPendingCredential"),
16702
+ sendGuardianChallenge: /* @__PURE__ */ __name(async (_learnCard, token) => {
16703
+ return client.inbox.sendGuardianChallenge.mutate({ token });
16704
+ }, "sendGuardianChallenge"),
16705
+ approveGuardianCredential: /* @__PURE__ */ __name(async (_learnCard, token, otpCode) => {
16706
+ return client.inbox.approveGuardianCredential.mutate({ token, otpCode });
16707
+ }, "approveGuardianCredential"),
16708
+ rejectGuardianCredential: /* @__PURE__ */ __name(async (_learnCard, token, otpCode) => {
16709
+ return client.inbox.rejectGuardianCredential.mutate({ token, otpCode });
16710
+ }, "rejectGuardianCredential"),
16711
+ approveGuardianCredentialInApp: /* @__PURE__ */ __name(async (_learnCard, inboxCredentialId) => {
16712
+ await ensureUser();
16713
+ return client.inbox.approveGuardianCredentialInApp.mutate({ inboxCredentialId });
16714
+ }, "approveGuardianCredentialInApp"),
16715
+ rejectGuardianCredentialInApp: /* @__PURE__ */ __name(async (_learnCard, inboxCredentialId) => {
16716
+ await ensureUser();
16717
+ return client.inbox.rejectGuardianCredentialInApp.mutate({ inboxCredentialId });
16718
+ }, "rejectGuardianCredentialInApp"),
16335
16719
  addContactMethod: /* @__PURE__ */ __name(async (_learnCard, contactMethod) => {
16336
16720
  await ensureUser();
16337
16721
  return client.contactMethods.addContactMethod.mutate(contactMethod);
@@ -16542,6 +16926,10 @@ async function getLearnCardNetworkPlugin(learnCard, url2, apiTokenOrOptions, opt
16542
16926
  await ensureUser();
16543
16927
  return client.appStore.getListingSigningAuthority.query({ listingId });
16544
16928
  }, "getListingSigningAuthority"),
16929
+ getIntegrationForListing: /* @__PURE__ */ __name(async (_learnCard, listingId) => {
16930
+ await ensureUser();
16931
+ return client.appStore.getIntegrationForListing.query({ listingId });
16932
+ }, "getIntegrationForListing"),
16545
16933
  getAppStoreListing: /* @__PURE__ */ __name(async (_learnCard, listingId) => {
16546
16934
  await ensureUser();
16547
16935
  return client.appStore.getListing.query({ listingId });
@@ -16637,6 +17025,14 @@ async function getLearnCardNetworkPlugin(learnCard, url2, apiTokenOrOptions, opt
16637
17025
  templateAlias
16638
17026
  });
16639
17027
  }, "addBoostToApp"),
17028
+ associateBoostWithListing: /* @__PURE__ */ __name(async (_learnCard, listingId, boostUri, templateAlias) => {
17029
+ await ensureUser();
17030
+ return client.appStore.addBoostToListing.mutate({
17031
+ listingId,
17032
+ boostUri,
17033
+ templateAlias
17034
+ });
17035
+ }, "associateBoostWithListing"),
16640
17036
  removeBoostFromApp: /* @__PURE__ */ __name(async (_learnCard, listingId, templateAlias) => {
16641
17037
  await ensureUser();
16642
17038
  return client.appStore.removeBoostFromListing.mutate({ listingId, templateAlias });
@@ -16671,7 +17067,14 @@ async function getLearnCardNetworkPlugin(learnCard, url2, apiTokenOrOptions, opt
16671
17067
  getActivityChain: /* @__PURE__ */ __name(async (_learnCard, options2) => {
16672
17068
  await ensureUser();
16673
17069
  return client.activity.getActivityChain.query(options2);
16674
- }, "getActivityChain")
17070
+ }, "getActivityChain"),
17071
+ isServiceTrusted: /* @__PURE__ */ __name(async (_learnCard, serviceDid) => {
17072
+ const trustedServices = await client.federation.getTrustedServices.query({});
17073
+ return trustedServices.some((s) => s.did === serviceDid);
17074
+ }, "isServiceTrusted"),
17075
+ getTrustedServices: /* @__PURE__ */ __name(async () => {
17076
+ return client.federation.getTrustedServices.query({});
17077
+ }, "getTrustedServices")
16675
17078
  }
16676
17079
  };
16677
17080
  }