@learncard/network-plugin 2.14.1 → 3.0.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.
- package/README.md +12 -0
- package/dist/inbox-batch.d.ts +5 -0
- package/dist/inbox-batch.d.ts.map +1 -0
- package/dist/inbox-batch.test.d.ts +2 -0
- package/dist/inbox-batch.test.d.ts.map +1 -0
- package/dist/lcn-plugin.cjs.development.cjs +600 -218
- package/dist/lcn-plugin.cjs.development.cjs.map +4 -4
- package/dist/lcn-plugin.cjs.production.min.cjs +36 -36
- package/dist/lcn-plugin.cjs.production.min.cjs.map +4 -4
- package/dist/lcn-plugin.esm.js +602 -218
- package/dist/lcn-plugin.esm.js.map +4 -4
- package/dist/plugin.d.ts +11 -0
- package/dist/plugin.d.ts.map +1 -1
- package/dist/test/act-as.test.d.ts +2 -0
- package/dist/test/act-as.test.d.ts.map +1 -0
- package/dist/test/refresh-send.test-d.d.ts +2 -0
- package/dist/test/refresh-send.test-d.d.ts.map +1 -0
- package/dist/test/refresh-send.test.d.ts +2 -0
- package/dist/test/refresh-send.test.d.ts.map +1 -0
- package/dist/types.d.ts +93 -19
- package/dist/types.d.ts.map +1 -1
- package/package.json +8 -8
- package/src/inbox-batch.test.ts +105 -0
- package/src/inbox-batch.ts +66 -0
- package/src/plugin.ts +332 -52
- package/src/test/act-as.test.ts +323 -0
- package/src/test/index.test.ts +161 -10
- package/src/test/refresh-send.test-d.ts +152 -0
- package/src/test/refresh-send.test.ts +646 -0
- package/src/types.ts +118 -22
package/src/types.ts
CHANGED
|
@@ -53,6 +53,9 @@ import {
|
|
|
53
53
|
AuthGrantType,
|
|
54
54
|
AuthGrantQuery,
|
|
55
55
|
IssueInboxCredentialType,
|
|
56
|
+
IssueInboxCredentialBatch,
|
|
57
|
+
InboxBatchReceipt,
|
|
58
|
+
InboxBatchStatus,
|
|
56
59
|
InboxCredentialType,
|
|
57
60
|
PaginatedInboxCredentialsType,
|
|
58
61
|
PaginatedSkillFrameworksType,
|
|
@@ -113,17 +116,68 @@ import {
|
|
|
113
116
|
BitstringCredentialStatusEntry,
|
|
114
117
|
AllocateCredentialRefreshInput,
|
|
115
118
|
AllocateCredentialRefreshResult,
|
|
119
|
+
ManagedCredentialRefreshReceipt,
|
|
116
120
|
PublishCredentialRefreshInput,
|
|
117
121
|
PublishCredentialRefreshResult,
|
|
118
122
|
GetCredentialRefreshHistoryInput,
|
|
119
123
|
GetCredentialRefreshHistoryResult,
|
|
120
124
|
} from '@learncard/types';
|
|
121
|
-
import { Plugin } from '@learncard/core';
|
|
125
|
+
import { LearnCard, Plugin } from '@learncard/core';
|
|
122
126
|
import { ProofOptions } from '@learncard/didkit-plugin';
|
|
123
127
|
import { VerifyExtension } from '@learncard/vc-plugin';
|
|
124
128
|
|
|
125
129
|
export type { BitstringCredentialStatusPurpose, BitstringCredentialStatusEntry };
|
|
126
130
|
|
|
131
|
+
/** Object-form options for the network plugin's `sendBoost` */
|
|
132
|
+
export type SendBoostNetworkOptions = {
|
|
133
|
+
encrypt?: boolean;
|
|
134
|
+
overideFn?: (boost: UnsignedVC) => UnsignedVC;
|
|
135
|
+
skipNotification?: boolean;
|
|
136
|
+
templateData?: Record<string, unknown>;
|
|
137
|
+
statusPurposes?: BitstringCredentialStatusPurpose[];
|
|
138
|
+
/**
|
|
139
|
+
* Opt into a managed refresh service. When true, a stable UUID credential ID is
|
|
140
|
+
* generated if the boost template has none, a refresh service is allocated BEFORE
|
|
141
|
+
* signing and injected into the signed credential, and the credential is sent via
|
|
142
|
+
* the dedicated managed-send procedure (holder-encrypted storage only) instead of
|
|
143
|
+
* legacy credential storage. The `encrypt` option is ignored in this mode —
|
|
144
|
+
* managed storage is always holder-only.
|
|
145
|
+
*/
|
|
146
|
+
enableRefresh?: boolean;
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
/** Result of a refresh-enabled `sendBoost` call (opt-in via `enableRefresh: true`) */
|
|
150
|
+
export type SendBoostRefreshResult = {
|
|
151
|
+
/** URI of the issued (managed, holder-encrypted) credential */
|
|
152
|
+
credentialUri: string;
|
|
153
|
+
/** Issuance metadata the issuer keeps in order to publish future updates */
|
|
154
|
+
refresh: ManagedCredentialRefreshReceipt;
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
/** The `enableRefresh` type carried by `sendBoost` options (`undefined` when absent). */
|
|
158
|
+
type EnableRefreshOf<Options> = Options extends object
|
|
159
|
+
? 'enableRefresh' extends keyof Options
|
|
160
|
+
? Options extends { enableRefresh?: infer Enabled }
|
|
161
|
+
? Enabled
|
|
162
|
+
: undefined
|
|
163
|
+
: undefined
|
|
164
|
+
: undefined;
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Resolves the `sendBoost` return type from the (const-inferred) options type.
|
|
168
|
+
*
|
|
169
|
+
* - legacy `boolean` options, omitted options, and object options without
|
|
170
|
+
* `enableRefresh` keep the historical `string` result.
|
|
171
|
+
* - literal `enableRefresh: true` returns the refreshable-issuance result.
|
|
172
|
+
* - anything that may be `true` at runtime (a `boolean`, an optional property, or a
|
|
173
|
+
* union of option shapes) degrades to the union of both shapes.
|
|
174
|
+
*/
|
|
175
|
+
export type SendBoostResultFor<Options> = [EnableRefreshOf<Options>] extends [true]
|
|
176
|
+
? SendBoostRefreshResult
|
|
177
|
+
: true extends EnableRefreshOf<Options>
|
|
178
|
+
? string | SendBoostRefreshResult
|
|
179
|
+
: string;
|
|
180
|
+
|
|
127
181
|
/** @group LearnCardNetwork Plugin */
|
|
128
182
|
export type LearnCardNetworkPluginDependentMethods = {
|
|
129
183
|
getDidAuthVp: (options?: ProofOptions) => Promise<VP | string>;
|
|
@@ -160,6 +214,14 @@ export type LearnCardNetworkPluginMethods = {
|
|
|
160
214
|
getManagedProfiles: (
|
|
161
215
|
options?: Partial<PaginationOptionsType> & { query?: LCNProfileQuery }
|
|
162
216
|
) => Promise<PaginatedLCNProfiles>;
|
|
217
|
+
/**
|
|
218
|
+
* Returns a new LearnCard instance whose network plugin sends every request with the
|
|
219
|
+
* `X-LearnCard-Act-As` header set to `profileId`, asking the server to swap the acting
|
|
220
|
+
* profile for the duration of each request. Token scope is unchanged; the server responds
|
|
221
|
+
* `403` if the caller doesn't manage `profileId`, or if an API token's grant doesn't cover
|
|
222
|
+
* it. The original instance (and its headers) is left untouched.
|
|
223
|
+
*/
|
|
224
|
+
actAs: (profileId: string) => Promise<ActingLearnCard>;
|
|
163
225
|
claimPendingGuardianLinks: () => Promise<
|
|
164
226
|
Array<{ childProfileId: string; childDisplayName: string; managerId: string | null }>
|
|
165
227
|
>;
|
|
@@ -473,29 +535,23 @@ export type LearnCardNetworkPluginMethods = {
|
|
|
473
535
|
recipientProfileId: string,
|
|
474
536
|
credentialUri?: string
|
|
475
537
|
) => Promise<boolean>;
|
|
476
|
-
|
|
538
|
+
/**
|
|
539
|
+
* Sends a boost credential to a recipient profile.
|
|
540
|
+
*
|
|
541
|
+
* **Return shape (opt-in):** legacy callers (boolean options, omitted options, or
|
|
542
|
+
* object options without `enableRefresh`) receive the issued credential URI as a
|
|
543
|
+
* `string`, exactly as before. Passing literal `{ enableRefresh: true }` opts into
|
|
544
|
+
* managed refresh and returns `{ credentialUri, refresh }` instead, where `refresh`
|
|
545
|
+
* is the issuance receipt needed to publish future versions (see
|
|
546
|
+
* `publishCredentialRefresh`). Options whose `enableRefresh` may be `true` at runtime
|
|
547
|
+
* (a `boolean`, or a variable typed `SendBoostNetworkOptions`) degrade the result to
|
|
548
|
+
* `string | { credentialUri, refresh }`.
|
|
549
|
+
*/
|
|
550
|
+
sendBoost: <const Options extends boolean | SendBoostNetworkOptions | undefined = undefined>(
|
|
477
551
|
profileId: string,
|
|
478
552
|
boostUri: string,
|
|
479
|
-
options?:
|
|
480
|
-
|
|
481
|
-
| {
|
|
482
|
-
encrypt?: boolean;
|
|
483
|
-
overideFn?: (boost: UnsignedVC) => UnsignedVC;
|
|
484
|
-
skipNotification?: boolean;
|
|
485
|
-
templateData?: Record<string, unknown>;
|
|
486
|
-
statusPurposes?: BitstringCredentialStatusPurpose[];
|
|
487
|
-
/**
|
|
488
|
-
* Opt into a managed refresh service. When true, a stable UUID
|
|
489
|
-
* credential ID is generated if the boost template has none, a
|
|
490
|
-
* refresh service is allocated BEFORE signing and injected into the
|
|
491
|
-
* signed credential, and the credential is sent via the dedicated
|
|
492
|
-
* managed-send procedure (holder-encrypted storage only) instead of
|
|
493
|
-
* legacy credential storage. The `encrypt` option is ignored in this
|
|
494
|
-
* mode — managed storage is always holder-only.
|
|
495
|
-
*/
|
|
496
|
-
enableRefresh?: boolean;
|
|
497
|
-
}
|
|
498
|
-
) => Promise<string>;
|
|
553
|
+
options?: Options
|
|
554
|
+
) => Promise<SendBoostResultFor<Options>>;
|
|
499
555
|
|
|
500
556
|
registerSigningAuthority: (endpoint: string, name: string, did: string) => Promise<boolean>;
|
|
501
557
|
getRegisteredSigningAuthorities: () => Promise<LCNSigningAuthorityForUserType[]>;
|
|
@@ -679,6 +735,27 @@ export type LearnCardNetworkPluginMethods = {
|
|
|
679
735
|
revokeAuthGrant: (id: string) => Promise<boolean>;
|
|
680
736
|
getAPITokenForAuthGrant: (id: string) => Promise<string>;
|
|
681
737
|
|
|
738
|
+
/** Queue 1–100 credentials; workers may start up to a minute later. Use sendCredentialViaInbox for immediate single issuance. */
|
|
739
|
+
sendCredentialsViaInbox: (batch: IssueInboxCredentialBatch) => Promise<InboxBatchReceipt>;
|
|
740
|
+
/** Explicit batch alias for sendCredentialsViaInbox. Returns a durable receipt. */
|
|
741
|
+
sendCredentialBatchViaInbox: (batch: IssueInboxCredentialBatch) => Promise<InboxBatchReceipt>;
|
|
742
|
+
/** Ordered results and disjoint success/failure/unconfirmed counts. `done` includes unconfirmed outcomes.
|
|
743
|
+
* @see https://docs.learncard.com/sdks/learncard-network/universal-inbox-api
|
|
744
|
+
*/
|
|
745
|
+
getInboxCredentialBatch: (batchId: string) => Promise<InboxBatchStatus>;
|
|
746
|
+
/** Poll until done with bounded backoff. Abort/timeout stops waiting, not processing. */
|
|
747
|
+
waitForInboxCredentialBatch: (
|
|
748
|
+
batchId: string,
|
|
749
|
+
options?: WaitForInboxCredentialBatchOptions
|
|
750
|
+
) => Promise<InboxBatchStatus>;
|
|
751
|
+
/** Submit once and wait; persist the receipt with onSubmitted for recovery after timeout. */
|
|
752
|
+
sendCredentialsViaInboxAndWait: (
|
|
753
|
+
batch: IssueInboxCredentialBatch,
|
|
754
|
+
options?: WaitForInboxCredentialBatchOptions & {
|
|
755
|
+
onSubmitted?: (receipt: InboxBatchReceipt) => void | Promise<void>;
|
|
756
|
+
}
|
|
757
|
+
) => Promise<InboxBatchStatus>;
|
|
758
|
+
/** Issue one credential synchronously, without waiting for the batch dispatcher. */
|
|
682
759
|
sendCredentialViaInbox: (
|
|
683
760
|
issueInboxCredential: IssueInboxCredentialType
|
|
684
761
|
) => Promise<IssueInboxCredentialResponseType>;
|
|
@@ -971,6 +1048,16 @@ export type LearnCardNetworkPluginMethods = {
|
|
|
971
1048
|
};
|
|
972
1049
|
|
|
973
1050
|
/** @group LearnCardNetwork Plugin */
|
|
1051
|
+
/**
|
|
1052
|
+
* The wallet returned by `invoke.actAs`: the caller's existing plugins with a network
|
|
1053
|
+
* plugin bound to the target profile appended. The caller's plugin list cannot be named
|
|
1054
|
+
* from inside the plugin's own method map, hence the open tuple.
|
|
1055
|
+
*/
|
|
1056
|
+
export type ActingLearnCard = LearnCard<
|
|
1057
|
+
[...Plugin[], LearnCardNetworkPlugin],
|
|
1058
|
+
'id' | 'read' | 'store'
|
|
1059
|
+
>;
|
|
1060
|
+
|
|
974
1061
|
export type LearnCardNetworkPlugin = Plugin<
|
|
975
1062
|
'LearnCard Network',
|
|
976
1063
|
'id' | 'read' | 'store',
|
|
@@ -988,3 +1075,12 @@ export type TrustedBoostRegistryEntry = {
|
|
|
988
1075
|
url: string;
|
|
989
1076
|
did: string;
|
|
990
1077
|
};
|
|
1078
|
+
|
|
1079
|
+
export interface WaitForInboxCredentialBatchOptions {
|
|
1080
|
+
/** Overall polling deadline; defaults to ten minutes. */
|
|
1081
|
+
timeoutMs?: number;
|
|
1082
|
+
/** Initial interval; increases by 1.5x up to ten seconds (or this interval if larger). */
|
|
1083
|
+
intervalMs?: number;
|
|
1084
|
+
signal?: AbortSignal;
|
|
1085
|
+
onProgress?: (status: InboxBatchStatus) => void;
|
|
1086
|
+
}
|