@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.
@@ -15894,7 +15894,10 @@ var SendOptionsValidator = external_exports.object({
15894
15894
  webhookUrl: external_exports.string().url().optional().describe("Webhook URL to receive claim notifications"),
15895
15895
  suppressDelivery: external_exports.boolean().optional().describe("If true, returns claimUrl without sending email/SMS"),
15896
15896
  branding: SendBrandingOptionsValidator.optional().describe("Branding for email/SMS delivery"),
15897
- guardianEmail: external_exports.string().email().optional().describe("Guardian email that must approve before student can claim")
15897
+ guardianEmail: external_exports.string().email().optional().describe("Guardian email that must approve before student can claim"),
15898
+ expiresInDays: external_exports.number().int().min(1).max(720).optional().describe(
15899
+ "How many days the credential stays claimable in the Universal Inbox (default 30). Does not change the credential validity period."
15900
+ )
15898
15901
  });
15899
15902
  var SendBoostInputValidator = external_exports.object({
15900
15903
  type: external_exports.literal("boost"),
@@ -16189,7 +16192,8 @@ var LCNNotificationTypeEnumValidator = external_exports.enum([
16189
16192
  "APP_NOTIFICATION",
16190
16193
  "CREDENTIAL_REVOKED",
16191
16194
  "CREDENTIAL_SUSPENDED",
16192
- "CREDENTIAL_UNSUSPENDED"
16195
+ "CREDENTIAL_UNSUSPENDED",
16196
+ "CREDENTIAL_REFRESHED"
16193
16197
  ]);
16194
16198
  var LCNNotificationMessageValidator = external_exports.object({
16195
16199
  title: external_exports.string().optional(),
@@ -16321,12 +16325,16 @@ var CreateContactMethodSessionResponseValidator = external_exports.object({
16321
16325
  });
16322
16326
  var InboxCredentialValidator = external_exports.object({
16323
16327
  id: external_exports.string(),
16324
- credential: external_exports.string(),
16328
+ credential: external_exports.string().optional(),
16325
16329
  isSigned: external_exports.boolean(),
16326
16330
  currentStatus: LCNInboxStatusEnumValidator,
16327
16331
  isAccepted: external_exports.boolean().optional(),
16328
16332
  expiresAt: external_exports.string(),
16329
16333
  createdAt: external_exports.string(),
16334
+ finalizedAt: external_exports.string().optional(),
16335
+ expiredAt: external_exports.string().optional(),
16336
+ credentialName: external_exports.string().optional(),
16337
+ achievementType: external_exports.string().optional(),
16330
16338
  issuerDid: external_exports.string(),
16331
16339
  webhookUrl: external_exports.string().optional(),
16332
16340
  boostUri: external_exports.string().optional(),
@@ -16380,7 +16388,9 @@ var IssueInboxCredentialValidator = external_exports.object({
16380
16388
  "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."
16381
16389
  ),
16382
16390
  webhookUrl: external_exports.string().url().optional().describe("The webhook URL to receive credential issuance events."),
16383
- expiresInDays: external_exports.number().min(1).max(365).optional().describe("The number of days the credential will be valid for."),
16391
+ expiresInDays: external_exports.number().int().min(1).max(720).optional().describe(
16392
+ "How many days the encrypted inbox payload remains claimable. This does not change the credential validity period."
16393
+ ),
16384
16394
  templateData: external_exports.record(external_exports.string(), external_exports.unknown()).optional().describe(
16385
16395
  "Template data to render into the boost credential template using Mustache syntax. Only used when boostUri is provided."
16386
16396
  ),
@@ -16443,6 +16453,9 @@ var ClaimInboxCredentialValidator = external_exports.object({
16443
16453
  credential: VCValidator.or(VPValidator).or(UnsignedVCValidator).or(CredentialNameRefValidator).describe("The credential to issue, or a { name } reference to resolve a boost template."),
16444
16454
  configuration: external_exports.object({
16445
16455
  publishableKey: external_exports.string(),
16456
+ expiresInDays: external_exports.number().int().min(1).max(720).optional().describe(
16457
+ "Inbox claim window in days. Defaults to 720; use a shorter window for sensitive records."
16458
+ ),
16446
16459
  signingAuthorityName: external_exports.string().optional(),
16447
16460
  listingId: external_exports.string().optional(),
16448
16461
  listingSlug: external_exports.string().optional()
@@ -17069,6 +17082,191 @@ var inAppMessagesFlagValidator = external_exports.object({
17069
17082
  version: external_exports.number().default(1),
17070
17083
  messages: external_exports.array(inAppMessageValidator).default([])
17071
17084
  }).passthrough();
17085
+ var LearnCardRefreshAuthorizationValidator = external_exports.object({ type: external_exports.literal("LearnCardDIDAuth") }).catchall(external_exports.any());
17086
+ var ManagedCredentialRefreshServiceValidator = external_exports.object({
17087
+ id: external_exports.string().min(1),
17088
+ type: external_exports.literal("LearnCardCredentialRefresh2026"),
17089
+ authorization: LearnCardRefreshAuthorizationValidator.optional()
17090
+ }).catchall(external_exports.any());
17091
+ var StandardCredentialRefreshServiceValidator = external_exports.object({
17092
+ id: external_exports.string().min(1),
17093
+ type: external_exports.literal("1EdTechCredentialRefresh")
17094
+ }).catchall(external_exports.any());
17095
+ var SupportedCredentialRefreshServiceValidator = external_exports.union([
17096
+ ManagedCredentialRefreshServiceValidator,
17097
+ StandardCredentialRefreshServiceValidator
17098
+ ]);
17099
+ var AllocateCredentialRefreshInputValidator = external_exports.object({
17100
+ holder: external_exports.object({
17101
+ profileId: external_exports.string().optional(),
17102
+ did: external_exports.string().min(1)
17103
+ }),
17104
+ credentialId: external_exports.string().min(1)
17105
+ });
17106
+ var AllocateCredentialRefreshResultValidator = external_exports.object({
17107
+ refreshId: external_exports.string().min(1),
17108
+ refreshService: ManagedCredentialRefreshServiceValidator.extend({
17109
+ authorization: LearnCardRefreshAuthorizationValidator
17110
+ })
17111
+ });
17112
+ var CredentialRefreshSigningModeValidator = external_exports.enum(["issuer-signed", "signing-authority"]);
17113
+ var PublishCredentialRefreshBaseFields = {
17114
+ refreshId: external_exports.string().min(1),
17115
+ notifyHolder: external_exports.boolean().optional(),
17116
+ updateSummary: external_exports.string().optional(),
17117
+ idempotencyKey: external_exports.string().optional()
17118
+ };
17119
+ var PublishIssuerSignedRefreshValidator = external_exports.object({
17120
+ ...PublishCredentialRefreshBaseFields,
17121
+ mode: external_exports.literal("issuer-signed"),
17122
+ signedCredential: VCValidator
17123
+ });
17124
+ var PublishSigningAuthorityRefreshValidator = external_exports.object({
17125
+ ...PublishCredentialRefreshBaseFields,
17126
+ mode: external_exports.literal("signing-authority"),
17127
+ credential: UnsignedVCValidator,
17128
+ signingAuthority: external_exports.object({
17129
+ type: external_exports.string().min(1)
17130
+ }).catchall(external_exports.any())
17131
+ });
17132
+ var PublishCredentialRefreshInputValidator = external_exports.object({
17133
+ ...PublishCredentialRefreshBaseFields,
17134
+ mode: CredentialRefreshSigningModeValidator,
17135
+ signedCredential: VCValidator.optional(),
17136
+ credential: UnsignedVCValidator.optional(),
17137
+ signingAuthority: external_exports.object({
17138
+ type: external_exports.string().min(1)
17139
+ }).catchall(external_exports.any()).optional()
17140
+ }).superRefine((input, ctx) => {
17141
+ if (input.mode === "issuer-signed" && !input.signedCredential) {
17142
+ ctx.addIssue({
17143
+ code: "custom",
17144
+ path: ["signedCredential"],
17145
+ message: "signedCredential is required for issuer-signed publication"
17146
+ });
17147
+ }
17148
+ if (input.mode === "issuer-signed" && (input.credential !== void 0 || input.signingAuthority !== void 0)) {
17149
+ ctx.addIssue({
17150
+ code: "custom",
17151
+ path: ["mode"],
17152
+ message: "issuer-signed publication cannot include signing-authority fields"
17153
+ });
17154
+ }
17155
+ if (input.mode === "signing-authority") {
17156
+ if (input.signedCredential !== void 0) {
17157
+ ctx.addIssue({
17158
+ code: "custom",
17159
+ path: ["signedCredential"],
17160
+ message: "signing-authority publication cannot include signedCredential"
17161
+ });
17162
+ }
17163
+ if (!input.credential) {
17164
+ ctx.addIssue({
17165
+ code: "custom",
17166
+ path: ["credential"],
17167
+ message: "credential is required for signing-authority publication"
17168
+ });
17169
+ }
17170
+ if (!input.signingAuthority) {
17171
+ ctx.addIssue({
17172
+ code: "custom",
17173
+ path: ["signingAuthority"],
17174
+ message: "signingAuthority is required for signing-authority publication"
17175
+ });
17176
+ }
17177
+ }
17178
+ });
17179
+ var PublishCredentialRefreshNotificationValidator = external_exports.enum([
17180
+ "queued",
17181
+ "suppressed",
17182
+ "not-applicable",
17183
+ /** Publication succeeded, but the post-commit notification enqueue must be retried. */
17184
+ "delivery-failed"
17185
+ ]);
17186
+ var PublishCredentialRefreshResultValidator = external_exports.object({
17187
+ refreshId: external_exports.string().min(1),
17188
+ version: external_exports.number().int().positive(),
17189
+ publishedAt: external_exports.string().min(1),
17190
+ notification: PublishCredentialRefreshNotificationValidator
17191
+ });
17192
+ var CredentialRefreshVersionMetadataValidator = external_exports.object({
17193
+ version: external_exports.number().int().positive(),
17194
+ publishedAt: external_exports.string().min(1),
17195
+ effectiveAt: external_exports.string().optional(),
17196
+ etag: external_exports.string().optional(),
17197
+ signingMode: CredentialRefreshSigningModeValidator.optional(),
17198
+ updateSummary: external_exports.string().optional()
17199
+ });
17200
+ var GetCredentialRefreshHistoryInputValidator = external_exports.object({
17201
+ refreshId: external_exports.string().min(1),
17202
+ cursor: external_exports.string().optional(),
17203
+ limit: external_exports.number().int().positive().optional()
17204
+ });
17205
+ var GetCredentialRefreshHistoryResultValidator = external_exports.object({
17206
+ records: CredentialRefreshVersionMetadataValidator.array(),
17207
+ hasMore: external_exports.boolean(),
17208
+ cursor: external_exports.string().optional()
17209
+ });
17210
+ var CredentialRefreshChallengeValidator = external_exports.object({
17211
+ challenge: external_exports.string().min(1),
17212
+ expiresAt: external_exports.string().min(1),
17213
+ domain: external_exports.string().optional(),
17214
+ scheme: external_exports.literal("LearnCardDIDAuth").optional()
17215
+ });
17216
+ var PublicCredentialRefreshEnvelopeValidator = external_exports.object({
17217
+ format: external_exports.literal("vc"),
17218
+ credential: VCValidator,
17219
+ etag: external_exports.string().optional()
17220
+ });
17221
+ var JweCredentialRefreshEnvelopeValidator = external_exports.object({
17222
+ format: external_exports.literal("jwe"),
17223
+ jwe: JWEValidator,
17224
+ etag: external_exports.string().optional(),
17225
+ /** Present on LearnCard-managed endpoints; optional for interoperable JWE services. */
17226
+ version: external_exports.number().int().positive().optional()
17227
+ });
17228
+ var CredentialRefreshResponseEnvelopeValidator = external_exports.discriminatedUnion("format", [
17229
+ PublicCredentialRefreshEnvelopeValidator,
17230
+ JweCredentialRefreshEnvelopeValidator
17231
+ ]);
17232
+ var CredentialRefreshFailureCodeValidator = external_exports.enum([
17233
+ "UNAVAILABLE",
17234
+ "TIMEOUT",
17235
+ "UNSUPPORTED_SERVICE",
17236
+ "UNAUTHORIZED",
17237
+ "MALFORMED_RESPONSE",
17238
+ "INVALID_PROOF",
17239
+ "ISSUER_MISMATCH",
17240
+ "ID_MISMATCH",
17241
+ "ROLLBACK",
17242
+ "REVOKED",
17243
+ "UNSAFE_ENDPOINT"
17244
+ ]);
17245
+ var CredentialRefreshUpdatedResultValidator = external_exports.object({
17246
+ status: external_exports.literal("updated"),
17247
+ credential: VCValidator,
17248
+ etag: external_exports.string().optional(),
17249
+ managedVersion: external_exports.number().int().positive().optional()
17250
+ });
17251
+ var CredentialRefreshUnchangedResultValidator = external_exports.object({
17252
+ status: external_exports.literal("unchanged"),
17253
+ checkedAt: external_exports.string().min(1),
17254
+ etag: external_exports.string().optional()
17255
+ });
17256
+ var CredentialRefreshUnsupportedResultValidator = external_exports.object({
17257
+ status: external_exports.literal("unsupported")
17258
+ });
17259
+ var CredentialRefreshFailedResultValidator = external_exports.object({
17260
+ status: external_exports.literal("failed"),
17261
+ code: CredentialRefreshFailureCodeValidator,
17262
+ retryable: external_exports.boolean()
17263
+ });
17264
+ var CredentialRefreshResultValidator = external_exports.discriminatedUnion("status", [
17265
+ CredentialRefreshUpdatedResultValidator,
17266
+ CredentialRefreshUnchangedResultValidator,
17267
+ CredentialRefreshUnsupportedResultValidator,
17268
+ CredentialRefreshFailedResultValidator
17269
+ ]);
17072
17270
 
17073
17271
  // src/plugin.ts
17074
17272
  var import_helpers = require("@learncard/helpers");
@@ -17545,6 +17743,56 @@ mustache.Writer = Writer;
17545
17743
  var mustache_default = mustache;
17546
17744
 
17547
17745
  // src/plugin.ts
17746
+ var LEARNCARD_DOMAIN_SUFFIXES = [".learncard.com", ".learncard.app", ".learncard.ai"];
17747
+ var isLearnCardDomain = /* @__PURE__ */ __name((host) => {
17748
+ return LEARNCARD_DOMAIN_SUFFIXES.some(
17749
+ (suffix) => host === suffix.replace(/^\./, "") || host.endsWith(suffix)
17750
+ );
17751
+ }, "isLearnCardDomain");
17752
+ var isLocalhostHost = /* @__PURE__ */ __name((host) => {
17753
+ const lower = host.toLowerCase();
17754
+ return lower === "localhost" || lower === "127.0.0.1";
17755
+ }, "isLocalhostHost");
17756
+ var validateFederationUrl = /* @__PURE__ */ __name((userProvidedUrl, config2) => {
17757
+ let parsed;
17758
+ try {
17759
+ parsed = new URL(userProvidedUrl);
17760
+ } catch {
17761
+ throw new Error(`Invalid federation endpoint URL: ${userProvidedUrl}`);
17762
+ }
17763
+ if (config2.serviceOrigin) {
17764
+ const endpointOrigin = parsed.origin;
17765
+ if (endpointOrigin === config2.serviceOrigin) {
17766
+ return parsed.href;
17767
+ }
17768
+ }
17769
+ const host = parsed.hostname.toLowerCase();
17770
+ const isLocalhost = isLocalhostHost(host);
17771
+ if (isLocalhost) {
17772
+ if (!config2.allowLocalhostFederation) {
17773
+ throw new Error(
17774
+ `Localhost federation is disabled. Set allowLocalhostFederation: true for development.`
17775
+ );
17776
+ }
17777
+ if (parsed.protocol === "https:") {
17778
+ parsed.protocol = "http:";
17779
+ }
17780
+ return parsed.href;
17781
+ }
17782
+ if (parsed.protocol !== "https:") {
17783
+ throw new Error(`Federation requires HTTPS for non-localhost hosts: ${userProvidedUrl}`);
17784
+ }
17785
+ if (config2.trustedFederationHosts !== void 0) {
17786
+ const trustedHosts = new Set(config2.trustedFederationHosts);
17787
+ const allowAnyHost = trustedHosts.has("*");
17788
+ if (!allowAnyHost && !isLearnCardDomain(host) && !trustedHosts.has(host)) {
17789
+ throw new Error(
17790
+ `Federation host '${host}' is not trusted. Add it to trustedFederationHosts or use '*' to allow any host.`
17791
+ );
17792
+ }
17793
+ }
17794
+ return parsed.href;
17795
+ }, "validateFederationUrl");
17548
17796
  var uint8ArrayToBase64Url = /* @__PURE__ */ __name((bytes) => {
17549
17797
  let binary = "";
17550
17798
  for (let i = 0; i < bytes.length; i += 1) binary += String.fromCharCode(bytes[i]);
@@ -17636,10 +17884,43 @@ var issueCredentialWithNetworkStatus = /* @__PURE__ */ __name(async (learnCard,
17636
17884
  await appendNetworkCredentialStatus(client, credential, statusPurposes)
17637
17885
  );
17638
17886
  }, "issueCredentialWithNetworkStatus");
17887
+ var MANAGED_REFRESH_SERVICE_CONTEXT = {
17888
+ "LearnCardCredentialRefresh2026": "https://learncard.com/refresh#LearnCardCredentialRefresh2026",
17889
+ authorization: {
17890
+ "@id": "https://purl.imsglobal.org/spec/ob/v3p0#authorization",
17891
+ "@context": {
17892
+ LearnCardDIDAuth: "https://docs.learncard.com/definitions#LearnCardDIDAuth"
17893
+ }
17894
+ }
17895
+ };
17896
+ var injectManagedRefreshService = /* @__PURE__ */ __name((credential, refreshService) => {
17897
+ const existingContext = credential["@context"];
17898
+ const contextList = Array.isArray(existingContext) ? existingContext : [existingContext];
17899
+ const hasMapping = contextList.some(
17900
+ (entry) => !!entry && typeof entry === "object" && "LearnCardCredentialRefresh2026" in entry
17901
+ );
17902
+ return {
17903
+ ...credential,
17904
+ "@context": hasMapping ? contextList : [...contextList, MANAGED_REFRESH_SERVICE_CONTEXT],
17905
+ refreshService
17906
+ };
17907
+ }, "injectManagedRefreshService");
17639
17908
  async function getLearnCardNetworkPlugin(learnCard, url2, apiTokenOrOptions, options) {
17640
17909
  const apiToken = typeof apiTokenOrOptions === "string" ? apiTokenOrOptions : void 0;
17641
- const guardianApprovalGetter = (typeof apiTokenOrOptions === "object" ? apiTokenOrOptions?.guardianApprovalGetter : void 0) ?? options?.guardianApprovalGetter;
17642
- const extraHeaders = (typeof apiTokenOrOptions === "object" ? apiTokenOrOptions?.extraHeaders : void 0) ?? options?.extraHeaders;
17910
+ const resolvedOptions = (typeof apiTokenOrOptions === "object" ? apiTokenOrOptions : options) ?? {};
17911
+ const {
17912
+ guardianApprovalGetter,
17913
+ extraHeaders,
17914
+ trustedFederationHosts,
17915
+ allowLocalhostFederation
17916
+ } = resolvedOptions;
17917
+ const serviceUrl = new URL(url2);
17918
+ const serviceIsLocalhost = isLocalhostHost(serviceUrl.hostname);
17919
+ const federationConfig = {
17920
+ trustedFederationHosts,
17921
+ allowLocalhostFederation: allowLocalhostFederation ?? serviceIsLocalhost,
17922
+ serviceOrigin: serviceUrl.origin
17923
+ };
17643
17924
  let did = "";
17644
17925
  try {
17645
17926
  const idPlane = learnCard?.id;
@@ -17708,8 +17989,8 @@ async function getLearnCardNetworkPlugin(learnCard, url2, apiTokenOrOptions, opt
17708
17989
  }
17709
17990
  }, "getBoostTemplateForIssuance");
17710
17991
  const getInboxEndpointForDid = /* @__PURE__ */ __name(async (_learnCard, recipientDid) => {
17711
- const serviceUrl = new URL(url2);
17712
- const serviceDomain = `${serviceUrl.hostname}${serviceUrl.port ? `%3A${serviceUrl.port}` : ""}`;
17992
+ const serviceUrl2 = new URL(url2);
17993
+ const serviceDomain = `${serviceUrl2.hostname}${serviceUrl2.port ? `%3A${serviceUrl2.port}` : ""}`;
17713
17994
  const localServiceDid = `did:web:${serviceDomain}`;
17714
17995
  const getInferredServiceDid = /* @__PURE__ */ __name((did2) => {
17715
17996
  if (!did2.startsWith("did:web:")) return null;
@@ -17730,12 +18011,12 @@ async function getLearnCardNetworkPlugin(learnCard, url2, apiTokenOrOptions, opt
17730
18011
  }), "getInboxService");
17731
18012
  const inferredServiceDid = getInferredServiceDid(recipientDid);
17732
18013
  if (inferredServiceDid === localServiceDid) {
17733
- return `${serviceUrl.origin}/api/inbox/receive`;
18014
+ return `${serviceUrl2.origin}/api/inbox/receive`;
17734
18015
  }
17735
18016
  const didDoc = await _learnCard.invoke.resolveDid(recipientDid);
17736
18017
  const inboxService = getInboxService(didDoc);
17737
18018
  if ((inboxService?.serviceDid || inferredServiceDid) === localServiceDid) {
17738
- return `${serviceUrl.origin}/api/inbox/receive`;
18019
+ return `${serviceUrl2.origin}/api/inbox/receive`;
17739
18020
  }
17740
18021
  if (!inboxService?.serviceEndpoint) {
17741
18022
  throw new Error(
@@ -17897,7 +18178,8 @@ async function getLearnCardNetworkPlugin(learnCard, url2, apiTokenOrOptions, opt
17897
18178
  return client.profileManager.updateProfileManager.mutate(manager);
17898
18179
  }, "updateProfileManagerProfile"),
17899
18180
  deleteProfile: /* @__PURE__ */ __name(async () => {
17900
- if (!userData) throw new Error("Account does not exist!");
18181
+ await initialQuery;
18182
+ if (!apiToken) await ensureUser();
17901
18183
  const result = await client.profile.deleteProfile.mutate();
17902
18184
  if (result) {
17903
18185
  userData = void 0;
@@ -18048,11 +18330,10 @@ async function getLearnCardNetworkPlugin(learnCard, url2, apiTokenOrOptions, opt
18048
18330
  proofFormat: "jwt",
18049
18331
  challenge: `inbox-federation-${crypto.randomUUID()}`
18050
18332
  });
18051
- let receiveUrl = inboxEndpoint;
18052
- if (receiveUrl.includes("localhost")) {
18053
- receiveUrl = receiveUrl.replace("https://", "http://");
18054
- }
18333
+ const receiveUrl = validateFederationUrl(inboxEndpoint, federationConfig);
18055
18334
  const response = await fetch(receiveUrl, {
18335
+ // A redirect must not bypass endpoint validation or forward credentials.
18336
+ redirect: "error",
18056
18337
  method: "POST",
18057
18338
  headers: {
18058
18339
  "Content-Type": "application/json",
@@ -18385,6 +18666,27 @@ async function getLearnCardNetworkPlugin(learnCard, url2, apiTokenOrOptions, opt
18385
18666
  await ensureUser();
18386
18667
  return client.boost.allocateCredentialStatus.mutate(options2);
18387
18668
  }, "allocateCredentialStatus"),
18669
+ allocateCredentialRefresh: /* @__PURE__ */ __name(async (_learnCard, input) => {
18670
+ await ensureUser();
18671
+ return client.credentialRefresh.allocateCredentialRefresh.mutate(input);
18672
+ }, "allocateCredentialRefresh"),
18673
+ sendRefreshableCredential: /* @__PURE__ */ __name(async (_learnCard, refreshId, credential, boostUri, skipNotification) => {
18674
+ await ensureUser();
18675
+ return client.credentialRefresh.sendRefreshableCredential.mutate({
18676
+ refreshId,
18677
+ credential,
18678
+ boostUri,
18679
+ ...skipNotification ? { skipNotification: true } : {}
18680
+ });
18681
+ }, "sendRefreshableCredential"),
18682
+ publishCredentialRefresh: /* @__PURE__ */ __name(async (_learnCard, input) => {
18683
+ await ensureUser();
18684
+ return client.credentialRefresh.publishCredentialRefresh.mutate(input);
18685
+ }, "publishCredentialRefresh"),
18686
+ getCredentialRefreshHistory: /* @__PURE__ */ __name(async (_learnCard, input) => {
18687
+ await ensureUser();
18688
+ return client.credentialRefresh.getCredentialRefreshHistory.query(input);
18689
+ }, "getCredentialRefreshHistory"),
18388
18690
  revokeBoostRecipient: /* @__PURE__ */ __name(async (_learnCard, boostUri, recipientProfileId, credentialUri) => {
18389
18691
  await ensureUser();
18390
18692
  const input = { boostUri, recipientProfileId };
@@ -18451,6 +18753,17 @@ async function getLearnCardNetworkPlugin(learnCard, url2, apiTokenOrOptions, opt
18451
18753
  if (typeof options2 === "object" && options2.overideFn) {
18452
18754
  boost = options2.overideFn(boost);
18453
18755
  }
18756
+ const enableRefresh = typeof options2 === "object" && options2.enableRefresh === true;
18757
+ let managedRefreshId;
18758
+ if (enableRefresh) {
18759
+ if (!boost.id) boost.id = `urn:uuid:${crypto.randomUUID()}`;
18760
+ const allocation = await client.credentialRefresh.allocateCredentialRefresh.mutate({
18761
+ holder: { profileId, did: targetProfile.did },
18762
+ credentialId: boost.id
18763
+ });
18764
+ managedRefreshId = allocation.refreshId;
18765
+ boost = injectManagedRefreshService(boost, allocation.refreshService);
18766
+ }
18454
18767
  const statusPurposes = typeof options2 === "object" ? options2.statusPurposes : void 0;
18455
18768
  const vc = await issueCredentialWithNetworkStatus(
18456
18769
  _learnCard,
@@ -18458,6 +18771,14 @@ async function getLearnCardNetworkPlugin(learnCard, url2, apiTokenOrOptions, opt
18458
18771
  boost,
18459
18772
  statusPurposes
18460
18773
  );
18774
+ if (managedRefreshId) {
18775
+ return client.credentialRefresh.sendRefreshableCredential.mutate({
18776
+ refreshId: managedRefreshId,
18777
+ credential: vc,
18778
+ boostUri,
18779
+ ...typeof options2 === "object" && options2.skipNotification ? { skipNotification: true } : {}
18780
+ });
18781
+ }
18461
18782
  if (typeof options2 === "object" && !options2.encrypt || !options2) {
18462
18783
  return client.boost.sendBoost.mutate({
18463
18784
  profileId,
@@ -18527,8 +18848,8 @@ async function getLearnCardNetworkPlugin(learnCard, url2, apiTokenOrOptions, opt
18527
18848
  const isDid = recipient.startsWith("did:");
18528
18849
  const isEmail = /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(recipient);
18529
18850
  const isPhone = /^\+?[\d\s-]{10,}$/.test(recipient.replace(/[\s-]/g, ""));
18530
- const serviceUrl = new URL(url2);
18531
- const serviceDomain = `${serviceUrl.hostname}${serviceUrl.port ? `%3A${serviceUrl.port}` : ""}`;
18851
+ const serviceUrl2 = new URL(url2);
18852
+ const serviceDomain = `${serviceUrl2.hostname}${serviceUrl2.port ? `%3A${serviceUrl2.port}` : ""}`;
18532
18853
  const recipientDomain = recipient.startsWith("did:web:") ? recipient.split(":")[2] : void 0;
18533
18854
  const isRemoteDidWebRecipient = recipient.startsWith("did:web:") && recipientDomain !== serviceDomain;
18534
18855
  if (isRemoteDidWebRecipient && input.templateUri) {
@@ -18940,6 +19261,23 @@ async function getLearnCardNetworkPlugin(learnCard, url2, apiTokenOrOptions, opt
18940
19261
  await ensureUser();
18941
19262
  return client.inbox.finalize.mutate();
18942
19263
  }, "finalizeInboxCredentials"),
19264
+ recoverInboxCredentials: /* @__PURE__ */ __name(async (learnCard2, options2 = {}) => {
19265
+ const result = await client.inbox.getMyInboxDeliveries.query(options2);
19266
+ const results = await Promise.allSettled(
19267
+ result.records.map(async (record2) => ({
19268
+ ...record2,
19269
+ credential: VCValidator.parse(
19270
+ await learnCard2.invoke.decryptDagJwe(record2.credential, [
19271
+ learnCard2.id.keypair()
19272
+ ])
19273
+ )
19274
+ }))
19275
+ );
19276
+ const records = results.flatMap(
19277
+ (record2) => record2.status === "fulfilled" ? [record2.value] : []
19278
+ );
19279
+ return { ...result, records, failed: results.length - records.length };
19280
+ }, "recoverInboxCredentials"),
18943
19281
  sendGuardianApprovalEmail: /* @__PURE__ */ __name(async (_learnCard, options2) => {
18944
19282
  await ensureUser();
18945
19283
  return client.inbox.sendGuardianApprovalEmail.mutate(options2);