@interop/wallet-core 0.94.0 → 0.96.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.
Files changed (100) hide show
  1. package/README.md +21 -20
  2. package/dist/clientAnnex/mend.js +4 -1
  3. package/dist/clientAnnex/mend.js.map +1 -1
  4. package/dist/clients/index.d.ts +3 -2
  5. package/dist/clients/index.d.ts.map +1 -1
  6. package/dist/clients/index.js +3 -2
  7. package/dist/clients/index.js.map +1 -1
  8. package/dist/clients/listing.d.ts +19 -12
  9. package/dist/clients/listing.d.ts.map +1 -1
  10. package/dist/clients/listing.js +69 -22
  11. package/dist/clients/listing.js.map +1 -1
  12. package/dist/connections/didKey.d.ts +25 -0
  13. package/dist/connections/didKey.d.ts.map +1 -0
  14. package/dist/connections/didKey.js +49 -0
  15. package/dist/connections/didKey.js.map +1 -0
  16. package/dist/connections/entry.d.ts +226 -0
  17. package/dist/connections/entry.d.ts.map +1 -0
  18. package/dist/connections/entry.js +287 -0
  19. package/dist/connections/entry.js.map +1 -0
  20. package/dist/connections/errors.d.ts +33 -0
  21. package/dist/connections/errors.d.ts.map +1 -0
  22. package/dist/connections/errors.js +36 -0
  23. package/dist/connections/errors.js.map +1 -0
  24. package/dist/connections/grants.d.ts +94 -0
  25. package/dist/connections/grants.d.ts.map +1 -0
  26. package/dist/connections/grants.js +120 -0
  27. package/dist/connections/grants.js.map +1 -0
  28. package/dist/connections/index.d.ts +47 -0
  29. package/dist/connections/index.d.ts.map +1 -0
  30. package/dist/connections/index.js +40 -0
  31. package/dist/connections/index.js.map +1 -0
  32. package/dist/connections/read.d.ts +82 -0
  33. package/dist/connections/read.d.ts.map +1 -0
  34. package/dist/connections/read.js +100 -0
  35. package/dist/connections/read.js.map +1 -0
  36. package/dist/connections/resourceId.d.ts +36 -0
  37. package/dist/connections/resourceId.d.ts.map +1 -0
  38. package/dist/connections/resourceId.js +49 -0
  39. package/dist/connections/resourceId.js.map +1 -0
  40. package/dist/connections/store.d.ts +103 -0
  41. package/dist/connections/store.d.ts.map +1 -0
  42. package/dist/connections/store.js +67 -0
  43. package/dist/connections/store.js.map +1 -0
  44. package/dist/connections/upsert.d.ts +220 -0
  45. package/dist/connections/upsert.d.ts.map +1 -0
  46. package/dist/connections/upsert.js +478 -0
  47. package/dist/connections/upsert.js.map +1 -0
  48. package/dist/connections/writers.d.ts +217 -0
  49. package/dist/connections/writers.d.ts.map +1 -0
  50. package/dist/connections/writers.js +485 -0
  51. package/dist/connections/writers.js.map +1 -0
  52. package/dist/enrollment/onboardingResponse.d.ts +3 -3
  53. package/dist/enrollment/onboardingResponse.d.ts.map +1 -1
  54. package/dist/enrollment/onboardingResponse.js +17 -13
  55. package/dist/enrollment/onboardingResponse.js.map +1 -1
  56. package/dist/keys/index.d.ts +0 -7
  57. package/dist/keys/index.d.ts.map +1 -1
  58. package/dist/keys/index.js +0 -6
  59. package/dist/keys/index.js.map +1 -1
  60. package/dist/labelText.d.ts +30 -3
  61. package/dist/labelText.d.ts.map +1 -1
  62. package/dist/labelText.js +35 -3
  63. package/dist/labelText.js.map +1 -1
  64. package/dist/menders/ids.d.ts +1 -1
  65. package/dist/menders/ids.d.ts.map +1 -1
  66. package/dist/menders/ids.js +7 -2
  67. package/dist/menders/ids.js.map +1 -1
  68. package/dist/space/collections.d.ts +15 -25
  69. package/dist/space/collections.d.ts.map +1 -1
  70. package/dist/space/collections.js +19 -29
  71. package/dist/space/collections.js.map +1 -1
  72. package/dist/space/index.d.ts +4 -3
  73. package/dist/space/index.d.ts.map +1 -1
  74. package/dist/space/index.js +4 -3
  75. package/dist/space/index.js.map +1 -1
  76. package/package.json +8 -8
  77. package/dist/keys/clientLabels.d.ts +0 -85
  78. package/dist/keys/clientLabels.d.ts.map +0 -1
  79. package/dist/keys/clientLabels.js +0 -96
  80. package/dist/keys/clientLabels.js.map +0 -1
  81. package/dist/keys/wasLabelsStore.d.ts +0 -33
  82. package/dist/keys/wasLabelsStore.d.ts.map +0 -1
  83. package/dist/keys/wasLabelsStore.js +0 -35
  84. package/dist/keys/wasLabelsStore.js.map +0 -1
  85. package/dist/writers/entry.d.ts +0 -95
  86. package/dist/writers/entry.d.ts.map +0 -1
  87. package/dist/writers/entry.js +0 -90
  88. package/dist/writers/entry.js.map +0 -1
  89. package/dist/writers/index.d.ts +0 -17
  90. package/dist/writers/index.d.ts.map +0 -1
  91. package/dist/writers/index.js +0 -14
  92. package/dist/writers/index.js.map +0 -1
  93. package/dist/writers/roster.d.ts +0 -152
  94. package/dist/writers/roster.d.ts.map +0 -1
  95. package/dist/writers/roster.js +0 -365
  96. package/dist/writers/roster.js.map +0 -1
  97. package/dist/writers/store.d.ts +0 -71
  98. package/dist/writers/store.d.ts.map +0 -1
  99. package/dist/writers/store.js +0 -55
  100. package/dist/writers/store.js.map +0 -1
@@ -0,0 +1,478 @@
1
+ /*!
2
+ * Copyright (c) 2026 Interop Alliance. All rights reserved.
3
+ */
4
+ /**
5
+ * The upsert helpers every flow writes a party's entry through:
6
+ * `recordGrants` at consent, `removeGrants` at an unshare or a torn
7
+ * consent's rollback, `retireConnection` when a relationship ends, and
8
+ * `setConnectionLabel` for the user's rename and the enrollment-time name.
9
+ *
10
+ * Each runs `writeConnection`, the one bounded compare-and-swap loop at a
11
+ * party's resource id, which the writer arm (`writers.ts`) runs too. It reads
12
+ * the entry, applies its change to the stored body, and writes under
13
+ * `ifMatch` (or creates under `ifNoneMatch`). A lost race re-reads and
14
+ * re-applies, up to three attempts, after which the last
15
+ * `PreconditionFailedError` is thrown. A helper changes only the members it
16
+ * owns, so a member a newer build added, on the entry or on a grant wrapper,
17
+ * is written back verbatim. A helper that finds a body it cannot parse, one
18
+ * whose `version` is above this build's, or one that does not belong at the
19
+ * id refuses to write, rather than treating the body as absent: overwriting
20
+ * it would wipe a newer build's grants.
21
+ */
22
+ import { NotSupportedError } from '@interop/was-client';
23
+ import { errorNameOf } from '../errorName.js';
24
+ import { normalizeDisplayName } from '../labelText.js';
25
+ import { signingKeyMultibaseOfDid } from './didKey.js';
26
+ import { CONNECTION_ENTRY_VERSION, GRANT_KINDS, isWritableConnectionEntry, newConnectionEntry, parseConnectionEntry, parseConnectionZcap } from './entry.js';
27
+ import { ConnectionKindMismatchError } from './errors.js';
28
+ import { connectionGrants, isTargetInSpace } from './grants.js';
29
+ import { claimedResourceId } from './read.js';
30
+ import { connectionResourceId } from './resourceId.js';
31
+ const PRECONDITION_FAILED_ERROR_NAME = 'PreconditionFailedError';
32
+ const WRITE_ATTEMPTS = 3;
33
+ /**
34
+ * Whether a store write lost a race. Matched by name, since the store is an
35
+ * injected seam that may raise from a second copy of was-client.
36
+ *
37
+ * @param err {unknown}
38
+ * @returns {boolean}
39
+ */
40
+ export function isLostConnectionRace(err) {
41
+ return errorNameOf(err) === PRECONDITION_FAILED_ERROR_NAME;
42
+ }
43
+ /**
44
+ * The ETag a write over an existing resource pins to. A read that carried
45
+ * none would send the write unconditionally, so it is refused instead.
46
+ *
47
+ * @param options {object}
48
+ * @param options.resourceId {string}
49
+ * @param [options.etag] {string}
50
+ * @returns {string}
51
+ */
52
+ function requireConnectionEtag({ resourceId, etag }) {
53
+ if (etag === undefined) {
54
+ throw new NotSupportedError(`Cannot update connections entry "${resourceId}": its read returned ` +
55
+ 'no ETag, so the write would go out unconditionally. A browser ' +
56
+ "client needs `ETag` in the server's `Access-Control-Expose-Headers`.");
57
+ }
58
+ return etag;
59
+ }
60
+ /**
61
+ * Reads a stored body as an entry this build may write over, or throws. The
62
+ * body must sit at the id its own members derive to, parse, and carry this
63
+ * build's `version`.
64
+ *
65
+ * @param options {object}
66
+ * @param options.resourceId {string}
67
+ * @param options.stored {object} the store's `get` result
68
+ * @param options.hmacKey {ConnectionIdKey}
69
+ * @returns {Promise<WritableConnection>}
70
+ */
71
+ async function writableConnection({ resourceId, stored, hmacKey }) {
72
+ const claimed = await claimedResourceId({ body: stored.body, hmacKey });
73
+ const entry = parseConnectionEntry(stored.body);
74
+ if (claimed !== resourceId || entry === undefined) {
75
+ throw new Error(`The connections entry at "${resourceId}" cannot be parsed as the ` +
76
+ 'entry for this id; this build refuses to write over it.');
77
+ }
78
+ if (!isWritableConnectionEntry(entry)) {
79
+ throw new Error(`The connections entry at "${resourceId}" carries version ` +
80
+ `${entry.version}, newer than this build's ` +
81
+ `${CONNECTION_ENTRY_VERSION}; this build refuses to write over it.`);
82
+ }
83
+ return {
84
+ entry,
85
+ body: stored.body,
86
+ ...(stored.etag !== undefined && { etag: stored.etag })
87
+ };
88
+ }
89
+ /**
90
+ * The bounded compare-and-swap loop every directory write runs at one
91
+ * resource id: the upsert helpers here and the writer arm in `writers.ts`.
92
+ * Each attempt reads the resource, hands `change` the writable entry (or
93
+ * `undefined` when none stands), and writes the body it returns under
94
+ * `ifMatch` (or creates it under `ifNoneMatch`). A `stop` ends the loop with
95
+ * that outcome and no write. A lost race re-reads and re-applies, and after
96
+ * the last attempt the last `PreconditionFailedError` is thrown. `change`
97
+ * may throw a refusal, which ends the loop the same way.
98
+ *
99
+ * A stored body this build cannot write over (unparseable, misplaced, or
100
+ * from a newer build) throws, unless `unwritable` names the outcome to
101
+ * resolve with instead.
102
+ *
103
+ * @param options {object}
104
+ * @param options.store {ConnectionsStore}
105
+ * @param options.hmacKey {ConnectionIdKey}
106
+ * @param options.resourceId {string}
107
+ * @param options.change {Function}
108
+ * @param [options.unwritable] {Stop} the outcome for a body this build
109
+ * cannot write over; omitted, such a body throws
110
+ * @returns {Promise<object>} the id and the outcome: `created`, `updated`,
111
+ * or the `stop` the callback returned
112
+ */
113
+ export async function writeConnection({ store, hmacKey, resourceId, change, unwritable }) {
114
+ let lastRace;
115
+ for (let attempt = 0; attempt < WRITE_ATTEMPTS; attempt++) {
116
+ const stored = await store.get({ resourceId });
117
+ let current;
118
+ if (stored !== undefined) {
119
+ try {
120
+ current = await writableConnection({ resourceId, stored, hmacKey });
121
+ }
122
+ catch (err) {
123
+ if (unwritable === undefined) {
124
+ throw err;
125
+ }
126
+ return { resourceId, outcome: unwritable };
127
+ }
128
+ }
129
+ const next = change(current);
130
+ if ('stop' in next) {
131
+ return { resourceId, outcome: next.stop };
132
+ }
133
+ try {
134
+ if (current === undefined) {
135
+ await store.put({ resourceId, body: next.body, ifNoneMatch: true });
136
+ return { resourceId, outcome: 'created' };
137
+ }
138
+ await store.put({
139
+ resourceId,
140
+ body: next.body,
141
+ ifMatch: requireConnectionEtag({ resourceId, etag: current.etag })
142
+ });
143
+ return { resourceId, outcome: 'updated' };
144
+ }
145
+ catch (err) {
146
+ if (!isLostConnectionRace(err)) {
147
+ throw err;
148
+ }
149
+ lastRace = err;
150
+ }
151
+ }
152
+ throw lastRace;
153
+ }
154
+ /**
155
+ * {@link writeConnection} for the helpers here, keyed by the party's DID. A
156
+ * helper with nothing to write stops with `absent` (no entry at the id) or
157
+ * `unchanged`.
158
+ *
159
+ * @param options {object}
160
+ * @param options.store {ConnectionsStore}
161
+ * @param options.hmacKey {ConnectionIdKey}
162
+ * @param options.did {string} the party's DID
163
+ * @param options.change {Function}
164
+ * @returns {Promise<ConnectionWriteResult>}
165
+ */
166
+ async function writePartyConnection({ store, hmacKey, did, change }) {
167
+ return writeConnection({
168
+ store,
169
+ hmacKey,
170
+ resourceId: await connectionResourceId({ hmacKey, did }),
171
+ change
172
+ });
173
+ }
174
+ /**
175
+ * Refuses a stored entry of another kind than the writing flow's.
176
+ *
177
+ * @param options {object}
178
+ * @param options.entry {ConnectionEntry}
179
+ * @param options.kind {string}
180
+ */
181
+ function assertKind({ entry, kind }) {
182
+ if (entry.kind !== kind) {
183
+ throw new ConnectionKindMismatchError({
184
+ expectedKind: kind,
185
+ foundKind: entry.kind
186
+ });
187
+ }
188
+ }
189
+ /**
190
+ * The capability of one grant to record, checked strictly: its known members
191
+ * well-formed, its `controller` the party's DID, its `invocationTarget` under
192
+ * this Space, its kind one this build writes. The target check is the same
193
+ * one every reader applies, so a grant that is stored is a grant the
194
+ * revocation index will see.
195
+ *
196
+ * @param options {object}
197
+ * @param options.did {string}
198
+ * @param options.spaceUrl {string}
199
+ * @param options.grant {object}
200
+ * @returns {ConnectionZcap}
201
+ */
202
+ function checkedGrant({ did, spaceUrl, grant }) {
203
+ const zcap = parseConnectionZcap(grant.zcap);
204
+ if (zcap === undefined) {
205
+ throw new TypeError('A grant to record must carry a capability with an id, a controller, ' +
206
+ 'and an invocation target.');
207
+ }
208
+ if (zcap.controller !== did) {
209
+ throw new TypeError(`A grant to record must be delegated to the party "${did}"; its ` +
210
+ `controller is "${zcap.controller}".`);
211
+ }
212
+ if (!isTargetInSpace({ target: zcap.invocationTarget, spaceUrl })) {
213
+ throw new TypeError('A grant to record must target this Space; its invocation target is ' +
214
+ `"${zcap.invocationTarget}".`);
215
+ }
216
+ if (!GRANT_KINDS.includes(grant.grantKind)) {
217
+ throw new TypeError(`Unknown grant kind "${grant.grantKind}".`);
218
+ }
219
+ return zcap;
220
+ }
221
+ /**
222
+ * Records a consent on the party's entry: creates the entry, or merges into
223
+ * it. Each new grant is added by its capability id (one already recorded is
224
+ * left as stored), `name` is set when it passes the display-name rule (left
225
+ * as it was otherwise), `origin`, `url`, and `appKey` are set when given,
226
+ * `retired` is cleared, and `lastSeen` moves to `now`. `firstSeen` is set
227
+ * only on create, and `label` is never touched. A zero-grant consent writes
228
+ * too, so an App Connect app with no grants is indexed by its key.
229
+ *
230
+ * Refuses an entry of another kind with {@link ConnectionKindMismatchError},
231
+ * and a grant delegated to another party or targeting another Space with a
232
+ * `TypeError`, before anything is written. Without `spaceUrl` (a session with
233
+ * no Space, which delegates nothing) only a zero-grant write proceeds, and a
234
+ * call carrying any grant throws a `TypeError`.
235
+ *
236
+ * @param options {object}
237
+ * @param options.store {ConnectionsStore}
238
+ * @param options.hmacKey {ConnectionIdKey}
239
+ * @param options.did {string} the party's DID, every grant's controller
240
+ * @param options.kind {ConnectionKind} the kind this flow writes
241
+ * @param [options.spaceUrl] {string} this Space's container URL, every
242
+ * grant's target prefix; absent on a session with no Space
243
+ * @param options.grants {Array<object>} `{ zcap, grantKind }` per grant
244
+ * @param [options.name] {string} the party's self-declared name
245
+ * @param [options.origin] {string} the attested Web origin (App Connect)
246
+ * @param [options.url] {string} the canonical app URL (App Connect)
247
+ * @param [options.appKey] {string} the app-key Resource id (App Connect)
248
+ * @param [options.now] {Date}
249
+ * @returns {Promise<ConnectionWriteResult>}
250
+ */
251
+ export async function recordGrants({ store, hmacKey, did, kind, spaceUrl, grants, name, origin, url, appKey, now = new Date() }) {
252
+ const stamp = now.toISOString();
253
+ const recorded = [];
254
+ const seen = new Set();
255
+ for (const grant of grants) {
256
+ if (spaceUrl === undefined) {
257
+ throw new TypeError("A grant to record needs this Space's container URL; a write with " +
258
+ 'no Space records no grants.');
259
+ }
260
+ const zcap = checkedGrant({ did, spaceUrl, grant });
261
+ if (!seen.has(zcap.id)) {
262
+ seen.add(zcap.id);
263
+ recorded.push({ zcap, grantKind: grant.grantKind, grantedAt: stamp });
264
+ }
265
+ }
266
+ const normalizedName = name === undefined ? undefined : normalizeDisplayName({ value: name });
267
+ const declared = {
268
+ ...(normalizedName !== undefined && { name: normalizedName }),
269
+ ...(origin !== undefined && { origin }),
270
+ ...(url !== undefined && { url }),
271
+ ...(appKey !== undefined && { appKey })
272
+ };
273
+ return writePartyConnection({
274
+ store,
275
+ hmacKey,
276
+ did,
277
+ change(current) {
278
+ if (current === undefined) {
279
+ return {
280
+ body: {
281
+ ...newConnectionEntry({ kind, did, now }),
282
+ ...declared,
283
+ grants: recorded
284
+ }
285
+ };
286
+ }
287
+ assertKind({ entry: current.entry, kind });
288
+ const held = new Set(current.entry.grants.map(grant => grant.zcap.id));
289
+ const body = {
290
+ ...current.body,
291
+ ...declared,
292
+ lastSeen: stamp,
293
+ grants: [
294
+ ...current.entry.grants,
295
+ ...recorded.filter(grant => !held.has(grant.zcap.id))
296
+ ]
297
+ };
298
+ delete body.retired;
299
+ return { body };
300
+ }
301
+ });
302
+ }
303
+ /**
304
+ * Removes grants from the party's entry by capability id, whatever the
305
+ * entry's kind. Used by an unshare after its revocation, and by a torn
306
+ * consent's rollback. An absent entry, or one holding none of the ids,
307
+ * writes nothing.
308
+ *
309
+ * @param options {object}
310
+ * @param options.store {ConnectionsStore}
311
+ * @param options.hmacKey {ConnectionIdKey}
312
+ * @param options.did {string} the party's DID
313
+ * @param options.zcapIds {Iterable<string>} the capability ids to remove
314
+ * @returns {Promise<ConnectionWriteResult>}
315
+ */
316
+ export async function removeGrants({ store, hmacKey, did, zcapIds }) {
317
+ const removing = new Set(zcapIds);
318
+ return writePartyConnection({
319
+ store,
320
+ hmacKey,
321
+ did,
322
+ change(current) {
323
+ if (current === undefined) {
324
+ return { stop: 'absent' };
325
+ }
326
+ const kept = current.entry.grants.filter(grant => !removing.has(grant.zcap.id));
327
+ if (kept.length === current.entry.grants.length) {
328
+ return { stop: 'unchanged' };
329
+ }
330
+ return { body: { ...current.body, grants: kept } };
331
+ }
332
+ });
333
+ }
334
+ /**
335
+ * Retires the party's entry, of any kind, once a revocation has handled its
336
+ * grants: empties `grants`, drops `appKey`, and stamps `retired`. `name`,
337
+ * `label`, `origin`, `url`, `firstSeen`, `lastSeen`, and `writers` stay, so a
338
+ * departed party keeps resolving. An entry already retired with nothing left
339
+ * to empty writes nothing, and an absent entry writes nothing.
340
+ *
341
+ * Throws when a read finds a grant that passes the reader checks and is not
342
+ * among `handledZcapIds`: a concurrent consent merged it, and the revocation
343
+ * must run again before the entry may retire. A grant that fails the reader
344
+ * checks (another party's controller, a target outside this Space) is not
345
+ * the party's, and the retirement empties it with the rest. Without
346
+ * `spaceUrl` (a session with no Space, which delegates nothing) no grant can
347
+ * be the party's, so none counts as unhandled and the retirement empties
348
+ * them all.
349
+ *
350
+ * @param options {object}
351
+ * @param options.store {ConnectionsStore}
352
+ * @param options.hmacKey {ConnectionIdKey}
353
+ * @param options.did {string} the party's DID
354
+ * @param options.handledZcapIds {Iterable<string>} the capability ids the
355
+ * revocation POSTed
356
+ * @param [options.spaceUrl] {string} this Space's container URL, every
357
+ * session with a Space passes it
358
+ * @param [options.now] {Date}
359
+ * @returns {Promise<ConnectionWriteResult>}
360
+ */
361
+ export async function retireConnection({ store, hmacKey, did, handledZcapIds, spaceUrl, now = new Date() }) {
362
+ const handled = new Set(handledZcapIds);
363
+ return writePartyConnection({
364
+ store,
365
+ hmacKey,
366
+ did,
367
+ change(current) {
368
+ if (current === undefined) {
369
+ return { stop: 'absent' };
370
+ }
371
+ const partyGrants = spaceUrl === undefined
372
+ ? []
373
+ : connectionGrants({ entry: current.entry, spaceUrl });
374
+ const unhandled = partyGrants.filter(grant => !handled.has(grant.zcapId));
375
+ if (unhandled.length > 0) {
376
+ throw new Error(`The connections entry carries ${unhandled.length} grant(s) this ` +
377
+ 'revocation did not handle (a consent merged them since); the ' +
378
+ 'revocation must run again before the entry retires.');
379
+ }
380
+ const { entry } = current;
381
+ if (entry.retired !== undefined &&
382
+ entry.grants.length === 0 &&
383
+ entry.appKey === undefined) {
384
+ return { stop: 'unchanged' };
385
+ }
386
+ const body = {
387
+ ...current.body,
388
+ grants: [],
389
+ retired: entry.retired ?? now.toISOString()
390
+ };
391
+ delete body.appKey;
392
+ return { body };
393
+ }
394
+ });
395
+ }
396
+ /**
397
+ * Sets the user's `label` on the party's entry, and its `name` when given.
398
+ * A blank `label` removes the member; an omitted one leaves it, and one
399
+ * outside the display-name rule is refused with a `TypeError`, since the
400
+ * user typed it and can shorten it. A `name` outside the rule is ignored. The enrollment approval writes
401
+ * the code's suggested label as `name` and passes `label` only when the
402
+ * approver edited it.
403
+ *
404
+ * Creates an absent entry only for a wallet client the verified account
405
+ * document lists (`kind: 'wallet-client'`, its did:key's signing-key
406
+ * multibase in `enrolledSigningKeys`), and throws for any other absent
407
+ * party. Refuses an entry of another kind with
408
+ * {@link ConnectionKindMismatchError}.
409
+ *
410
+ * @param options {object}
411
+ * @param options.store {ConnectionsStore}
412
+ * @param options.hmacKey {ConnectionIdKey}
413
+ * @param options.did {string} the party's DID
414
+ * @param options.kind {ConnectionKind} the kind the calling surface lists
415
+ * the party as
416
+ * @param [options.label] {string} the user's name for the party
417
+ * @param [options.name] {string} the party's name (a client's default
418
+ * platform label, or an enrollee's suggested label)
419
+ * @param [options.enrolledSigningKeys] {ReadonlySet<string>} the enrolled
420
+ * clients' signing-key multibases in the verified account document; needed
421
+ * to create a wallet client's entry
422
+ * @param [options.now] {Date}
423
+ * @returns {Promise<ConnectionWriteResult>}
424
+ */
425
+ export async function setConnectionLabel({ store, hmacKey, did, kind, label, name, enrolledSigningKeys, now = new Date() }) {
426
+ const trimmedLabel = label?.trim();
427
+ const normalizedLabel = trimmedLabel
428
+ ? normalizeDisplayName({ value: trimmedLabel })
429
+ : undefined;
430
+ if (trimmedLabel && normalizedLabel === undefined) {
431
+ throw new TypeError('A label is 1 to 64 code points once control and bidi characters are ' +
432
+ 'stripped.');
433
+ }
434
+ const normalizedName = name === undefined ? undefined : normalizeDisplayName({ value: name });
435
+ return writePartyConnection({
436
+ store,
437
+ hmacKey,
438
+ did,
439
+ change(current) {
440
+ if (current === undefined) {
441
+ const multibase = signingKeyMultibaseOfDid({ did });
442
+ if (kind !== 'wallet-client' ||
443
+ multibase === undefined ||
444
+ enrolledSigningKeys?.has(multibase) !== true) {
445
+ throw new Error('No connections entry stands for this party, and one is created ' +
446
+ 'here only for a wallet client the verified account document ' +
447
+ 'lists.');
448
+ }
449
+ return {
450
+ body: {
451
+ ...newConnectionEntry({ kind, did, now }),
452
+ ...(normalizedName !== undefined && { name: normalizedName }),
453
+ ...(normalizedLabel !== undefined && { label: normalizedLabel })
454
+ }
455
+ };
456
+ }
457
+ assertKind({ entry: current.entry, kind });
458
+ const body = { ...current.body };
459
+ if (trimmedLabel !== undefined) {
460
+ if (normalizedLabel !== undefined) {
461
+ body.label = normalizedLabel;
462
+ }
463
+ else {
464
+ delete body.label;
465
+ }
466
+ }
467
+ if (normalizedName !== undefined) {
468
+ body.name = normalizedName;
469
+ }
470
+ if (body.label === current.body.label &&
471
+ body.name === current.body.name) {
472
+ return { stop: 'unchanged' };
473
+ }
474
+ return { body };
475
+ }
476
+ });
477
+ }
478
+ //# sourceMappingURL=upsert.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"upsert.js","sourceRoot":"","sources":["../../src/connections/upsert.ts"],"names":[],"mappings":"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"}