@learncard/network-plugin 2.13.16 → 2.14.0

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.
@@ -15873,7 +15873,10 @@ var SendOptionsValidator = external_exports.object({
15873
15873
  webhookUrl: external_exports.string().url().optional().describe("Webhook URL to receive claim notifications"),
15874
15874
  suppressDelivery: external_exports.boolean().optional().describe("If true, returns claimUrl without sending email/SMS"),
15875
15875
  branding: SendBrandingOptionsValidator.optional().describe("Branding for email/SMS delivery"),
15876
- guardianEmail: external_exports.string().email().optional().describe("Guardian email that must approve before student can claim")
15876
+ guardianEmail: external_exports.string().email().optional().describe("Guardian email that must approve before student can claim"),
15877
+ expiresInDays: external_exports.number().int().min(1).max(720).optional().describe(
15878
+ "How many days the credential stays claimable in the Universal Inbox (default 30). Does not change the credential validity period."
15879
+ )
15877
15880
  });
15878
15881
  var SendBoostInputValidator = external_exports.object({
15879
15882
  type: external_exports.literal("boost"),
@@ -16168,7 +16171,8 @@ var LCNNotificationTypeEnumValidator = external_exports.enum([
16168
16171
  "APP_NOTIFICATION",
16169
16172
  "CREDENTIAL_REVOKED",
16170
16173
  "CREDENTIAL_SUSPENDED",
16171
- "CREDENTIAL_UNSUSPENDED"
16174
+ "CREDENTIAL_UNSUSPENDED",
16175
+ "CREDENTIAL_REFRESHED"
16172
16176
  ]);
16173
16177
  var LCNNotificationMessageValidator = external_exports.object({
16174
16178
  title: external_exports.string().optional(),
@@ -16300,12 +16304,16 @@ var CreateContactMethodSessionResponseValidator = external_exports.object({
16300
16304
  });
16301
16305
  var InboxCredentialValidator = external_exports.object({
16302
16306
  id: external_exports.string(),
16303
- credential: external_exports.string(),
16307
+ credential: external_exports.string().optional(),
16304
16308
  isSigned: external_exports.boolean(),
16305
16309
  currentStatus: LCNInboxStatusEnumValidator,
16306
16310
  isAccepted: external_exports.boolean().optional(),
16307
16311
  expiresAt: external_exports.string(),
16308
16312
  createdAt: external_exports.string(),
16313
+ finalizedAt: external_exports.string().optional(),
16314
+ expiredAt: external_exports.string().optional(),
16315
+ credentialName: external_exports.string().optional(),
16316
+ achievementType: external_exports.string().optional(),
16309
16317
  issuerDid: external_exports.string(),
16310
16318
  webhookUrl: external_exports.string().optional(),
16311
16319
  boostUri: external_exports.string().optional(),
@@ -16359,7 +16367,9 @@ var IssueInboxCredentialValidator = external_exports.object({
16359
16367
  "The signing authority to use for the credential. If not provided, the users default signing authority will be used if the credential is not signed."
16360
16368
  ),
16361
16369
  webhookUrl: external_exports.string().url().optional().describe("The webhook URL to receive credential issuance events."),
16362
- expiresInDays: external_exports.number().min(1).max(365).optional().describe("The number of days the credential will be valid for."),
16370
+ expiresInDays: external_exports.number().int().min(1).max(720).optional().describe(
16371
+ "How many days the encrypted inbox payload remains claimable. This does not change the credential validity period."
16372
+ ),
16363
16373
  templateData: external_exports.record(external_exports.string(), external_exports.unknown()).optional().describe(
16364
16374
  "Template data to render into the boost credential template using Mustache syntax. Only used when boostUri is provided."
16365
16375
  ),
@@ -16422,6 +16432,9 @@ var ClaimInboxCredentialValidator = external_exports.object({
16422
16432
  credential: VCValidator.or(VPValidator).or(UnsignedVCValidator).or(CredentialNameRefValidator).describe("The credential to issue, or a { name } reference to resolve a boost template."),
16423
16433
  configuration: external_exports.object({
16424
16434
  publishableKey: external_exports.string(),
16435
+ expiresInDays: external_exports.number().int().min(1).max(720).optional().describe(
16436
+ "Inbox claim window in days. Defaults to 720; use a shorter window for sensitive records."
16437
+ ),
16425
16438
  signingAuthorityName: external_exports.string().optional(),
16426
16439
  listingId: external_exports.string().optional(),
16427
16440
  listingSlug: external_exports.string().optional()
@@ -17048,6 +17061,191 @@ var inAppMessagesFlagValidator = external_exports.object({
17048
17061
  version: external_exports.number().default(1),
17049
17062
  messages: external_exports.array(inAppMessageValidator).default([])
17050
17063
  }).passthrough();
17064
+ var LearnCardRefreshAuthorizationValidator = external_exports.object({ type: external_exports.literal("LearnCardDIDAuth") }).catchall(external_exports.any());
17065
+ var ManagedCredentialRefreshServiceValidator = external_exports.object({
17066
+ id: external_exports.string().min(1),
17067
+ type: external_exports.literal("LearnCardCredentialRefresh2026"),
17068
+ authorization: LearnCardRefreshAuthorizationValidator.optional()
17069
+ }).catchall(external_exports.any());
17070
+ var StandardCredentialRefreshServiceValidator = external_exports.object({
17071
+ id: external_exports.string().min(1),
17072
+ type: external_exports.literal("1EdTechCredentialRefresh")
17073
+ }).catchall(external_exports.any());
17074
+ var SupportedCredentialRefreshServiceValidator = external_exports.union([
17075
+ ManagedCredentialRefreshServiceValidator,
17076
+ StandardCredentialRefreshServiceValidator
17077
+ ]);
17078
+ var AllocateCredentialRefreshInputValidator = external_exports.object({
17079
+ holder: external_exports.object({
17080
+ profileId: external_exports.string().optional(),
17081
+ did: external_exports.string().min(1)
17082
+ }),
17083
+ credentialId: external_exports.string().min(1)
17084
+ });
17085
+ var AllocateCredentialRefreshResultValidator = external_exports.object({
17086
+ refreshId: external_exports.string().min(1),
17087
+ refreshService: ManagedCredentialRefreshServiceValidator.extend({
17088
+ authorization: LearnCardRefreshAuthorizationValidator
17089
+ })
17090
+ });
17091
+ var CredentialRefreshSigningModeValidator = external_exports.enum(["issuer-signed", "signing-authority"]);
17092
+ var PublishCredentialRefreshBaseFields = {
17093
+ refreshId: external_exports.string().min(1),
17094
+ notifyHolder: external_exports.boolean().optional(),
17095
+ updateSummary: external_exports.string().optional(),
17096
+ idempotencyKey: external_exports.string().optional()
17097
+ };
17098
+ var PublishIssuerSignedRefreshValidator = external_exports.object({
17099
+ ...PublishCredentialRefreshBaseFields,
17100
+ mode: external_exports.literal("issuer-signed"),
17101
+ signedCredential: VCValidator
17102
+ });
17103
+ var PublishSigningAuthorityRefreshValidator = external_exports.object({
17104
+ ...PublishCredentialRefreshBaseFields,
17105
+ mode: external_exports.literal("signing-authority"),
17106
+ credential: UnsignedVCValidator,
17107
+ signingAuthority: external_exports.object({
17108
+ type: external_exports.string().min(1)
17109
+ }).catchall(external_exports.any())
17110
+ });
17111
+ var PublishCredentialRefreshInputValidator = external_exports.object({
17112
+ ...PublishCredentialRefreshBaseFields,
17113
+ mode: CredentialRefreshSigningModeValidator,
17114
+ signedCredential: VCValidator.optional(),
17115
+ credential: UnsignedVCValidator.optional(),
17116
+ signingAuthority: external_exports.object({
17117
+ type: external_exports.string().min(1)
17118
+ }).catchall(external_exports.any()).optional()
17119
+ }).superRefine((input, ctx) => {
17120
+ if (input.mode === "issuer-signed" && !input.signedCredential) {
17121
+ ctx.addIssue({
17122
+ code: "custom",
17123
+ path: ["signedCredential"],
17124
+ message: "signedCredential is required for issuer-signed publication"
17125
+ });
17126
+ }
17127
+ if (input.mode === "issuer-signed" && (input.credential !== void 0 || input.signingAuthority !== void 0)) {
17128
+ ctx.addIssue({
17129
+ code: "custom",
17130
+ path: ["mode"],
17131
+ message: "issuer-signed publication cannot include signing-authority fields"
17132
+ });
17133
+ }
17134
+ if (input.mode === "signing-authority") {
17135
+ if (input.signedCredential !== void 0) {
17136
+ ctx.addIssue({
17137
+ code: "custom",
17138
+ path: ["signedCredential"],
17139
+ message: "signing-authority publication cannot include signedCredential"
17140
+ });
17141
+ }
17142
+ if (!input.credential) {
17143
+ ctx.addIssue({
17144
+ code: "custom",
17145
+ path: ["credential"],
17146
+ message: "credential is required for signing-authority publication"
17147
+ });
17148
+ }
17149
+ if (!input.signingAuthority) {
17150
+ ctx.addIssue({
17151
+ code: "custom",
17152
+ path: ["signingAuthority"],
17153
+ message: "signingAuthority is required for signing-authority publication"
17154
+ });
17155
+ }
17156
+ }
17157
+ });
17158
+ var PublishCredentialRefreshNotificationValidator = external_exports.enum([
17159
+ "queued",
17160
+ "suppressed",
17161
+ "not-applicable",
17162
+ /** Publication succeeded, but the post-commit notification enqueue must be retried. */
17163
+ "delivery-failed"
17164
+ ]);
17165
+ var PublishCredentialRefreshResultValidator = external_exports.object({
17166
+ refreshId: external_exports.string().min(1),
17167
+ version: external_exports.number().int().positive(),
17168
+ publishedAt: external_exports.string().min(1),
17169
+ notification: PublishCredentialRefreshNotificationValidator
17170
+ });
17171
+ var CredentialRefreshVersionMetadataValidator = external_exports.object({
17172
+ version: external_exports.number().int().positive(),
17173
+ publishedAt: external_exports.string().min(1),
17174
+ effectiveAt: external_exports.string().optional(),
17175
+ etag: external_exports.string().optional(),
17176
+ signingMode: CredentialRefreshSigningModeValidator.optional(),
17177
+ updateSummary: external_exports.string().optional()
17178
+ });
17179
+ var GetCredentialRefreshHistoryInputValidator = external_exports.object({
17180
+ refreshId: external_exports.string().min(1),
17181
+ cursor: external_exports.string().optional(),
17182
+ limit: external_exports.number().int().positive().optional()
17183
+ });
17184
+ var GetCredentialRefreshHistoryResultValidator = external_exports.object({
17185
+ records: CredentialRefreshVersionMetadataValidator.array(),
17186
+ hasMore: external_exports.boolean(),
17187
+ cursor: external_exports.string().optional()
17188
+ });
17189
+ var CredentialRefreshChallengeValidator = external_exports.object({
17190
+ challenge: external_exports.string().min(1),
17191
+ expiresAt: external_exports.string().min(1),
17192
+ domain: external_exports.string().optional(),
17193
+ scheme: external_exports.literal("LearnCardDIDAuth").optional()
17194
+ });
17195
+ var PublicCredentialRefreshEnvelopeValidator = external_exports.object({
17196
+ format: external_exports.literal("vc"),
17197
+ credential: VCValidator,
17198
+ etag: external_exports.string().optional()
17199
+ });
17200
+ var JweCredentialRefreshEnvelopeValidator = external_exports.object({
17201
+ format: external_exports.literal("jwe"),
17202
+ jwe: JWEValidator,
17203
+ etag: external_exports.string().optional(),
17204
+ /** Present on LearnCard-managed endpoints; optional for interoperable JWE services. */
17205
+ version: external_exports.number().int().positive().optional()
17206
+ });
17207
+ var CredentialRefreshResponseEnvelopeValidator = external_exports.discriminatedUnion("format", [
17208
+ PublicCredentialRefreshEnvelopeValidator,
17209
+ JweCredentialRefreshEnvelopeValidator
17210
+ ]);
17211
+ var CredentialRefreshFailureCodeValidator = external_exports.enum([
17212
+ "UNAVAILABLE",
17213
+ "TIMEOUT",
17214
+ "UNSUPPORTED_SERVICE",
17215
+ "UNAUTHORIZED",
17216
+ "MALFORMED_RESPONSE",
17217
+ "INVALID_PROOF",
17218
+ "ISSUER_MISMATCH",
17219
+ "ID_MISMATCH",
17220
+ "ROLLBACK",
17221
+ "REVOKED",
17222
+ "UNSAFE_ENDPOINT"
17223
+ ]);
17224
+ var CredentialRefreshUpdatedResultValidator = external_exports.object({
17225
+ status: external_exports.literal("updated"),
17226
+ credential: VCValidator,
17227
+ etag: external_exports.string().optional(),
17228
+ managedVersion: external_exports.number().int().positive().optional()
17229
+ });
17230
+ var CredentialRefreshUnchangedResultValidator = external_exports.object({
17231
+ status: external_exports.literal("unchanged"),
17232
+ checkedAt: external_exports.string().min(1),
17233
+ etag: external_exports.string().optional()
17234
+ });
17235
+ var CredentialRefreshUnsupportedResultValidator = external_exports.object({
17236
+ status: external_exports.literal("unsupported")
17237
+ });
17238
+ var CredentialRefreshFailedResultValidator = external_exports.object({
17239
+ status: external_exports.literal("failed"),
17240
+ code: CredentialRefreshFailureCodeValidator,
17241
+ retryable: external_exports.boolean()
17242
+ });
17243
+ var CredentialRefreshResultValidator = external_exports.discriminatedUnion("status", [
17244
+ CredentialRefreshUpdatedResultValidator,
17245
+ CredentialRefreshUnchangedResultValidator,
17246
+ CredentialRefreshUnsupportedResultValidator,
17247
+ CredentialRefreshFailedResultValidator
17248
+ ]);
17051
17249
 
17052
17250
  // src/plugin.ts
17053
17251
  import {
@@ -17528,6 +17726,56 @@ mustache.Writer = Writer;
17528
17726
  var mustache_default = mustache;
17529
17727
 
17530
17728
  // src/plugin.ts
17729
+ var LEARNCARD_DOMAIN_SUFFIXES = [".learncard.com", ".learncard.app", ".learncard.ai"];
17730
+ var isLearnCardDomain = /* @__PURE__ */ __name((host) => {
17731
+ return LEARNCARD_DOMAIN_SUFFIXES.some(
17732
+ (suffix) => host === suffix.replace(/^\./, "") || host.endsWith(suffix)
17733
+ );
17734
+ }, "isLearnCardDomain");
17735
+ var isLocalhostHost = /* @__PURE__ */ __name((host) => {
17736
+ const lower = host.toLowerCase();
17737
+ return lower === "localhost" || lower === "127.0.0.1";
17738
+ }, "isLocalhostHost");
17739
+ var validateFederationUrl = /* @__PURE__ */ __name((userProvidedUrl, config2) => {
17740
+ let parsed;
17741
+ try {
17742
+ parsed = new URL(userProvidedUrl);
17743
+ } catch {
17744
+ throw new Error(`Invalid federation endpoint URL: ${userProvidedUrl}`);
17745
+ }
17746
+ if (config2.serviceOrigin) {
17747
+ const endpointOrigin = parsed.origin;
17748
+ if (endpointOrigin === config2.serviceOrigin) {
17749
+ return parsed.href;
17750
+ }
17751
+ }
17752
+ const host = parsed.hostname.toLowerCase();
17753
+ const isLocalhost = isLocalhostHost(host);
17754
+ if (isLocalhost) {
17755
+ if (!config2.allowLocalhostFederation) {
17756
+ throw new Error(
17757
+ `Localhost federation is disabled. Set allowLocalhostFederation: true for development.`
17758
+ );
17759
+ }
17760
+ if (parsed.protocol === "https:") {
17761
+ parsed.protocol = "http:";
17762
+ }
17763
+ return parsed.href;
17764
+ }
17765
+ if (parsed.protocol !== "https:") {
17766
+ throw new Error(`Federation requires HTTPS for non-localhost hosts: ${userProvidedUrl}`);
17767
+ }
17768
+ if (config2.trustedFederationHosts !== void 0) {
17769
+ const trustedHosts = new Set(config2.trustedFederationHosts);
17770
+ const allowAnyHost = trustedHosts.has("*");
17771
+ if (!allowAnyHost && !isLearnCardDomain(host) && !trustedHosts.has(host)) {
17772
+ throw new Error(
17773
+ `Federation host '${host}' is not trusted. Add it to trustedFederationHosts or use '*' to allow any host.`
17774
+ );
17775
+ }
17776
+ }
17777
+ return parsed.href;
17778
+ }, "validateFederationUrl");
17531
17779
  var uint8ArrayToBase64Url = /* @__PURE__ */ __name((bytes) => {
17532
17780
  let binary = "";
17533
17781
  for (let i = 0; i < bytes.length; i += 1) binary += String.fromCharCode(bytes[i]);
@@ -17619,10 +17867,43 @@ var issueCredentialWithNetworkStatus = /* @__PURE__ */ __name(async (learnCard,
17619
17867
  await appendNetworkCredentialStatus(client, credential, statusPurposes)
17620
17868
  );
17621
17869
  }, "issueCredentialWithNetworkStatus");
17870
+ var MANAGED_REFRESH_SERVICE_CONTEXT = {
17871
+ "LearnCardCredentialRefresh2026": "https://learncard.com/refresh#LearnCardCredentialRefresh2026",
17872
+ authorization: {
17873
+ "@id": "https://purl.imsglobal.org/spec/ob/v3p0#authorization",
17874
+ "@context": {
17875
+ LearnCardDIDAuth: "https://docs.learncard.com/definitions#LearnCardDIDAuth"
17876
+ }
17877
+ }
17878
+ };
17879
+ var injectManagedRefreshService = /* @__PURE__ */ __name((credential, refreshService) => {
17880
+ const existingContext = credential["@context"];
17881
+ const contextList = Array.isArray(existingContext) ? existingContext : [existingContext];
17882
+ const hasMapping = contextList.some(
17883
+ (entry) => !!entry && typeof entry === "object" && "LearnCardCredentialRefresh2026" in entry
17884
+ );
17885
+ return {
17886
+ ...credential,
17887
+ "@context": hasMapping ? contextList : [...contextList, MANAGED_REFRESH_SERVICE_CONTEXT],
17888
+ refreshService
17889
+ };
17890
+ }, "injectManagedRefreshService");
17622
17891
  async function getLearnCardNetworkPlugin(learnCard, url2, apiTokenOrOptions, options) {
17623
17892
  const apiToken = typeof apiTokenOrOptions === "string" ? apiTokenOrOptions : void 0;
17624
- const guardianApprovalGetter = (typeof apiTokenOrOptions === "object" ? apiTokenOrOptions?.guardianApprovalGetter : void 0) ?? options?.guardianApprovalGetter;
17625
- const extraHeaders = (typeof apiTokenOrOptions === "object" ? apiTokenOrOptions?.extraHeaders : void 0) ?? options?.extraHeaders;
17893
+ const resolvedOptions = (typeof apiTokenOrOptions === "object" ? apiTokenOrOptions : options) ?? {};
17894
+ const {
17895
+ guardianApprovalGetter,
17896
+ extraHeaders,
17897
+ trustedFederationHosts,
17898
+ allowLocalhostFederation
17899
+ } = resolvedOptions;
17900
+ const serviceUrl = new URL(url2);
17901
+ const serviceIsLocalhost = isLocalhostHost(serviceUrl.hostname);
17902
+ const federationConfig = {
17903
+ trustedFederationHosts,
17904
+ allowLocalhostFederation: allowLocalhostFederation ?? serviceIsLocalhost,
17905
+ serviceOrigin: serviceUrl.origin
17906
+ };
17626
17907
  let did = "";
17627
17908
  try {
17628
17909
  const idPlane = learnCard?.id;
@@ -17691,8 +17972,8 @@ async function getLearnCardNetworkPlugin(learnCard, url2, apiTokenOrOptions, opt
17691
17972
  }
17692
17973
  }, "getBoostTemplateForIssuance");
17693
17974
  const getInboxEndpointForDid = /* @__PURE__ */ __name(async (_learnCard, recipientDid) => {
17694
- const serviceUrl = new URL(url2);
17695
- const serviceDomain = `${serviceUrl.hostname}${serviceUrl.port ? `%3A${serviceUrl.port}` : ""}`;
17975
+ const serviceUrl2 = new URL(url2);
17976
+ const serviceDomain = `${serviceUrl2.hostname}${serviceUrl2.port ? `%3A${serviceUrl2.port}` : ""}`;
17696
17977
  const localServiceDid = `did:web:${serviceDomain}`;
17697
17978
  const getInferredServiceDid = /* @__PURE__ */ __name((did2) => {
17698
17979
  if (!did2.startsWith("did:web:")) return null;
@@ -17713,12 +17994,12 @@ async function getLearnCardNetworkPlugin(learnCard, url2, apiTokenOrOptions, opt
17713
17994
  }), "getInboxService");
17714
17995
  const inferredServiceDid = getInferredServiceDid(recipientDid);
17715
17996
  if (inferredServiceDid === localServiceDid) {
17716
- return `${serviceUrl.origin}/api/inbox/receive`;
17997
+ return `${serviceUrl2.origin}/api/inbox/receive`;
17717
17998
  }
17718
17999
  const didDoc = await _learnCard.invoke.resolveDid(recipientDid);
17719
18000
  const inboxService = getInboxService(didDoc);
17720
18001
  if ((inboxService?.serviceDid || inferredServiceDid) === localServiceDid) {
17721
- return `${serviceUrl.origin}/api/inbox/receive`;
18002
+ return `${serviceUrl2.origin}/api/inbox/receive`;
17722
18003
  }
17723
18004
  if (!inboxService?.serviceEndpoint) {
17724
18005
  throw new Error(
@@ -17880,7 +18161,8 @@ async function getLearnCardNetworkPlugin(learnCard, url2, apiTokenOrOptions, opt
17880
18161
  return client.profileManager.updateProfileManager.mutate(manager);
17881
18162
  }, "updateProfileManagerProfile"),
17882
18163
  deleteProfile: /* @__PURE__ */ __name(async () => {
17883
- if (!userData) throw new Error("Account does not exist!");
18164
+ await initialQuery;
18165
+ if (!apiToken) await ensureUser();
17884
18166
  const result = await client.profile.deleteProfile.mutate();
17885
18167
  if (result) {
17886
18168
  userData = void 0;
@@ -18031,11 +18313,10 @@ async function getLearnCardNetworkPlugin(learnCard, url2, apiTokenOrOptions, opt
18031
18313
  proofFormat: "jwt",
18032
18314
  challenge: `inbox-federation-${crypto.randomUUID()}`
18033
18315
  });
18034
- let receiveUrl = inboxEndpoint;
18035
- if (receiveUrl.includes("localhost")) {
18036
- receiveUrl = receiveUrl.replace("https://", "http://");
18037
- }
18316
+ const receiveUrl = validateFederationUrl(inboxEndpoint, federationConfig);
18038
18317
  const response = await fetch(receiveUrl, {
18318
+ // A redirect must not bypass endpoint validation or forward credentials.
18319
+ redirect: "error",
18039
18320
  method: "POST",
18040
18321
  headers: {
18041
18322
  "Content-Type": "application/json",
@@ -18368,6 +18649,27 @@ async function getLearnCardNetworkPlugin(learnCard, url2, apiTokenOrOptions, opt
18368
18649
  await ensureUser();
18369
18650
  return client.boost.allocateCredentialStatus.mutate(options2);
18370
18651
  }, "allocateCredentialStatus"),
18652
+ allocateCredentialRefresh: /* @__PURE__ */ __name(async (_learnCard, input) => {
18653
+ await ensureUser();
18654
+ return client.credentialRefresh.allocateCredentialRefresh.mutate(input);
18655
+ }, "allocateCredentialRefresh"),
18656
+ sendRefreshableCredential: /* @__PURE__ */ __name(async (_learnCard, refreshId, credential, boostUri, skipNotification) => {
18657
+ await ensureUser();
18658
+ return client.credentialRefresh.sendRefreshableCredential.mutate({
18659
+ refreshId,
18660
+ credential,
18661
+ boostUri,
18662
+ ...skipNotification ? { skipNotification: true } : {}
18663
+ });
18664
+ }, "sendRefreshableCredential"),
18665
+ publishCredentialRefresh: /* @__PURE__ */ __name(async (_learnCard, input) => {
18666
+ await ensureUser();
18667
+ return client.credentialRefresh.publishCredentialRefresh.mutate(input);
18668
+ }, "publishCredentialRefresh"),
18669
+ getCredentialRefreshHistory: /* @__PURE__ */ __name(async (_learnCard, input) => {
18670
+ await ensureUser();
18671
+ return client.credentialRefresh.getCredentialRefreshHistory.query(input);
18672
+ }, "getCredentialRefreshHistory"),
18371
18673
  revokeBoostRecipient: /* @__PURE__ */ __name(async (_learnCard, boostUri, recipientProfileId, credentialUri) => {
18372
18674
  await ensureUser();
18373
18675
  const input = { boostUri, recipientProfileId };
@@ -18434,6 +18736,17 @@ async function getLearnCardNetworkPlugin(learnCard, url2, apiTokenOrOptions, opt
18434
18736
  if (typeof options2 === "object" && options2.overideFn) {
18435
18737
  boost = options2.overideFn(boost);
18436
18738
  }
18739
+ const enableRefresh = typeof options2 === "object" && options2.enableRefresh === true;
18740
+ let managedRefreshId;
18741
+ if (enableRefresh) {
18742
+ if (!boost.id) boost.id = `urn:uuid:${crypto.randomUUID()}`;
18743
+ const allocation = await client.credentialRefresh.allocateCredentialRefresh.mutate({
18744
+ holder: { profileId, did: targetProfile.did },
18745
+ credentialId: boost.id
18746
+ });
18747
+ managedRefreshId = allocation.refreshId;
18748
+ boost = injectManagedRefreshService(boost, allocation.refreshService);
18749
+ }
18437
18750
  const statusPurposes = typeof options2 === "object" ? options2.statusPurposes : void 0;
18438
18751
  const vc = await issueCredentialWithNetworkStatus(
18439
18752
  _learnCard,
@@ -18441,6 +18754,14 @@ async function getLearnCardNetworkPlugin(learnCard, url2, apiTokenOrOptions, opt
18441
18754
  boost,
18442
18755
  statusPurposes
18443
18756
  );
18757
+ if (managedRefreshId) {
18758
+ return client.credentialRefresh.sendRefreshableCredential.mutate({
18759
+ refreshId: managedRefreshId,
18760
+ credential: vc,
18761
+ boostUri,
18762
+ ...typeof options2 === "object" && options2.skipNotification ? { skipNotification: true } : {}
18763
+ });
18764
+ }
18444
18765
  if (typeof options2 === "object" && !options2.encrypt || !options2) {
18445
18766
  return client.boost.sendBoost.mutate({
18446
18767
  profileId,
@@ -18510,8 +18831,8 @@ async function getLearnCardNetworkPlugin(learnCard, url2, apiTokenOrOptions, opt
18510
18831
  const isDid = recipient.startsWith("did:");
18511
18832
  const isEmail = /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(recipient);
18512
18833
  const isPhone = /^\+?[\d\s-]{10,}$/.test(recipient.replace(/[\s-]/g, ""));
18513
- const serviceUrl = new URL(url2);
18514
- const serviceDomain = `${serviceUrl.hostname}${serviceUrl.port ? `%3A${serviceUrl.port}` : ""}`;
18834
+ const serviceUrl2 = new URL(url2);
18835
+ const serviceDomain = `${serviceUrl2.hostname}${serviceUrl2.port ? `%3A${serviceUrl2.port}` : ""}`;
18515
18836
  const recipientDomain = recipient.startsWith("did:web:") ? recipient.split(":")[2] : void 0;
18516
18837
  const isRemoteDidWebRecipient = recipient.startsWith("did:web:") && recipientDomain !== serviceDomain;
18517
18838
  if (isRemoteDidWebRecipient && input.templateUri) {
@@ -18923,6 +19244,23 @@ async function getLearnCardNetworkPlugin(learnCard, url2, apiTokenOrOptions, opt
18923
19244
  await ensureUser();
18924
19245
  return client.inbox.finalize.mutate();
18925
19246
  }, "finalizeInboxCredentials"),
19247
+ recoverInboxCredentials: /* @__PURE__ */ __name(async (learnCard2, options2 = {}) => {
19248
+ const result = await client.inbox.getMyInboxDeliveries.query(options2);
19249
+ const results = await Promise.allSettled(
19250
+ result.records.map(async (record2) => ({
19251
+ ...record2,
19252
+ credential: VCValidator.parse(
19253
+ await learnCard2.invoke.decryptDagJwe(record2.credential, [
19254
+ learnCard2.id.keypair()
19255
+ ])
19256
+ )
19257
+ }))
19258
+ );
19259
+ const records = results.flatMap(
19260
+ (record2) => record2.status === "fulfilled" ? [record2.value] : []
19261
+ );
19262
+ return { ...result, records, failed: results.length - records.length };
19263
+ }, "recoverInboxCredentials"),
18926
19264
  sendGuardianApprovalEmail: /* @__PURE__ */ __name(async (_learnCard, options2) => {
18927
19265
  await ensureUser();
18928
19266
  return client.inbox.sendGuardianApprovalEmail.mutate(options2);