@interop/wallet-core 0.13.0 → 0.15.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 +13 -4
- package/dist/clients/index.d.ts +32 -0
- package/dist/clients/index.d.ts.map +1 -0
- package/dist/clients/index.js +28 -0
- package/dist/clients/index.js.map +1 -0
- package/dist/clients/listing.d.ts +82 -0
- package/dist/clients/listing.d.ts.map +1 -0
- package/dist/clients/listing.js +73 -0
- package/dist/clients/listing.js.map +1 -0
- package/dist/clients/policy.d.ts +79 -0
- package/dist/clients/policy.d.ts.map +1 -0
- package/dist/clients/policy.js +55 -0
- package/dist/clients/policy.js.map +1 -0
- package/dist/clients/revocation.d.ts +156 -0
- package/dist/clients/revocation.d.ts.map +1 -0
- package/dist/clients/revocation.js +142 -0
- package/dist/clients/revocation.js.map +1 -0
- package/dist/clients/rosterPolicy.d.ts +124 -0
- package/dist/clients/rosterPolicy.d.ts.map +1 -0
- package/dist/clients/rosterPolicy.js +125 -0
- package/dist/clients/rosterPolicy.js.map +1 -0
- package/dist/enrollment/connectCode.d.ts +29 -0
- package/dist/enrollment/connectCode.d.ts.map +1 -0
- package/dist/enrollment/connectCode.js +31 -0
- package/dist/enrollment/connectCode.js.map +1 -0
- package/dist/enrollment/enrollment.d.ts.map +1 -1
- package/dist/enrollment/enrollment.js +1 -5
- package/dist/enrollment/enrollment.js.map +1 -1
- package/dist/enrollment/index.d.ts +3 -0
- package/dist/enrollment/index.d.ts.map +1 -1
- package/dist/enrollment/index.js +3 -0
- package/dist/enrollment/index.js.map +1 -1
- package/dist/keys/clientKeyRecord.d.ts +124 -0
- package/dist/keys/clientKeyRecord.d.ts.map +1 -0
- package/dist/keys/clientKeyRecord.js +265 -0
- package/dist/keys/clientKeyRecord.js.map +1 -0
- package/dist/keys/index.d.ts +5 -0
- package/dist/keys/index.d.ts.map +1 -1
- package/dist/keys/index.js +4 -0
- package/dist/keys/index.js.map +1 -1
- package/dist/request/index.d.ts +4 -0
- package/dist/request/index.d.ts.map +1 -1
- package/dist/request/index.js +4 -0
- package/dist/request/index.js.map +1 -1
- package/dist/request/walletInput.d.ts +93 -0
- package/dist/request/walletInput.d.ts.map +1 -0
- package/dist/request/walletInput.js +182 -0
- package/dist/request/walletInput.js.map +1 -0
- package/dist/sync/contactsConflict.d.ts +76 -0
- package/dist/sync/contactsConflict.d.ts.map +1 -0
- package/dist/sync/contactsConflict.js +95 -0
- package/dist/sync/contactsConflict.js.map +1 -0
- package/dist/sync/index.d.ts +5 -0
- package/dist/sync/index.d.ts.map +1 -1
- package/dist/sync/index.js +4 -0
- package/dist/sync/index.js.map +1 -1
- package/dist/webvh/revokeClient.d.ts +6 -0
- package/dist/webvh/revokeClient.d.ts.map +1 -1
- package/dist/webvh/revokeClient.js +6 -0
- package/dist/webvh/revokeClient.js.map +1 -1
- package/package.json +16 -3
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) 2026 Interop Alliance. All rights reserved.
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* The universal wallet-input classifier: one ordered discrimination for every
|
|
6
|
+
* place a wallet accepts arbitrary text -- a QR scan, a paste box, a file
|
|
7
|
+
* drop, an opened deep link. Each wallet had grown its own ladder, so a
|
|
8
|
+
* grammar one wallet routed the other silently mis-handled (a connect code
|
|
9
|
+
* read as a credential URL, a connection payload read as nothing at all).
|
|
10
|
+
*
|
|
11
|
+
* Classification only: nothing here fetches, navigates, or stores. The caller
|
|
12
|
+
* supplies the handlers ({@link handleWalletInput}) or switches on the
|
|
13
|
+
* discriminated result itself.
|
|
14
|
+
*
|
|
15
|
+
* The order is the whole design, because several grammars are subsets of
|
|
16
|
+
* others. Most specific first:
|
|
17
|
+
*
|
|
18
|
+
* 1. **`was-link`** -- the wallet-connection QR payload, a non-URL JSON blob
|
|
19
|
+
* (deliberately not a link, so no OS handler ever routes it). Checked first
|
|
20
|
+
* because it is JSON that would otherwise fall through to the credential
|
|
21
|
+
* branch.
|
|
22
|
+
* 2. **`connect-code`** -- a `freewallet-connect:` client-enrollment code,
|
|
23
|
+
* recognized by prefix.
|
|
24
|
+
* 3. **`legacy-request`** -- the legacy credential-request link: a registered
|
|
25
|
+
* deep link carrying both `vc_request_url` and `issuer`. Necessarily ahead
|
|
26
|
+
* of the generic deep-link branch, which it would otherwise be swallowed by.
|
|
27
|
+
* 4. **`interaction-url`** -- a VCALM interaction URL (`interaction:` scheme,
|
|
28
|
+
* or `iuv=1`), the indirection that resolves to a protocols map.
|
|
29
|
+
* 5. **`deep-link`** -- any other link on one of the app's registered schemes,
|
|
30
|
+
* routed by the app's own link handling.
|
|
31
|
+
* 6. **`wallet-api-message`** -- a wallet API message, either as raw JSON or
|
|
32
|
+
* carried in a `request` query parameter of a link that is NOT on a
|
|
33
|
+
* registered scheme (a plain `https:` QR from a site that has one). The
|
|
34
|
+
* parameter form is checked before the raw-JSON form so the message is
|
|
35
|
+
* handed back parsed either way.
|
|
36
|
+
* 7. **`credentials`** -- the fallback: raw VC/VP JSON, or a URL to fetch one
|
|
37
|
+
* from. Deliberately last, since it is the only branch that cannot be
|
|
38
|
+
* recognized positively.
|
|
39
|
+
*
|
|
40
|
+
* Nothing is classified as "unrecognized": the credential branch is where
|
|
41
|
+
* unrecognized text lands, and the resolver a caller runs there is what
|
|
42
|
+
* produces the honest error message.
|
|
43
|
+
*/
|
|
44
|
+
import { isConnectCode } from '../enrollment/connectCode.js';
|
|
45
|
+
import { isInteractionUrl } from './interactionUrl.js';
|
|
46
|
+
import { isWalletApiMessage, parseWalletApiMessage, parseWalletApiUrl } from './parse.js';
|
|
47
|
+
/**
|
|
48
|
+
* The `t` member every `was-link` connection payload carries. Matched
|
|
49
|
+
* structurally here rather than by calling the parser, so an unrelated JSON
|
|
50
|
+
* blob is not refused with a connection-code error message.
|
|
51
|
+
*/
|
|
52
|
+
const WAS_LINK_TYPE = 'was-link';
|
|
53
|
+
/**
|
|
54
|
+
* The query parameters of a link, whatever its scheme. Uses the substring
|
|
55
|
+
* after the first `?` rather than `new URL`, so a custom-protocol link parses
|
|
56
|
+
* the same way an `https:` one does.
|
|
57
|
+
*
|
|
58
|
+
* @param text {string}
|
|
59
|
+
* @returns {URLSearchParams}
|
|
60
|
+
*/
|
|
61
|
+
function queryParamsOf(text) {
|
|
62
|
+
const start = text.indexOf('?');
|
|
63
|
+
return new URLSearchParams(start === -1 ? '' : text.slice(start + 1));
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Whether the text parses as a `was-link` connection payload's JSON shape.
|
|
67
|
+
*
|
|
68
|
+
* @param text {string}
|
|
69
|
+
* @returns {boolean}
|
|
70
|
+
*/
|
|
71
|
+
function isWasLinkPayload(text) {
|
|
72
|
+
if (!text.startsWith('{')) {
|
|
73
|
+
return false;
|
|
74
|
+
}
|
|
75
|
+
let parsed;
|
|
76
|
+
try {
|
|
77
|
+
parsed = JSON.parse(text);
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
return false;
|
|
81
|
+
}
|
|
82
|
+
return (parsed !== null &&
|
|
83
|
+
typeof parsed === 'object' &&
|
|
84
|
+
parsed.t === WAS_LINK_TYPE);
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Classifies one piece of wallet input. See the module doc for the order and
|
|
88
|
+
* why each branch sits where it does.
|
|
89
|
+
*
|
|
90
|
+
* @param text {string} the scanned, pasted, or opened text
|
|
91
|
+
* @param [options] {object}
|
|
92
|
+
* @param [options.deepLinkSchemes] {string[]} the link prefixes this app has
|
|
93
|
+
* registered (custom protocols and universal app links). Empty, the
|
|
94
|
+
* deep-link and legacy-request branches never match -- a wallet with no
|
|
95
|
+
* registered links has nothing to route them to
|
|
96
|
+
* @returns {WalletInput}
|
|
97
|
+
*/
|
|
98
|
+
export function classifyWalletInput(text, { deepLinkSchemes = [] } = {}) {
|
|
99
|
+
const trimmed = text.trim();
|
|
100
|
+
if (isWasLinkPayload(trimmed)) {
|
|
101
|
+
return { kind: 'was-link', text: trimmed };
|
|
102
|
+
}
|
|
103
|
+
if (isConnectCode(trimmed)) {
|
|
104
|
+
return { kind: 'connect-code', text: trimmed };
|
|
105
|
+
}
|
|
106
|
+
const isDeepLink = deepLinkSchemes.some(scheme => trimmed.startsWith(scheme));
|
|
107
|
+
if (isDeepLink) {
|
|
108
|
+
const params = queryParamsOf(trimmed);
|
|
109
|
+
if (params.has('vc_request_url') && params.has('issuer')) {
|
|
110
|
+
return {
|
|
111
|
+
kind: 'legacy-request',
|
|
112
|
+
text: trimmed,
|
|
113
|
+
params: Object.fromEntries(params.entries())
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
if (isInteractionUrl(trimmed)) {
|
|
118
|
+
return { kind: 'interaction-url', text: trimmed };
|
|
119
|
+
}
|
|
120
|
+
if (isDeepLink) {
|
|
121
|
+
return { kind: 'deep-link', text: trimmed };
|
|
122
|
+
}
|
|
123
|
+
// A link on an unregistered scheme can still carry a wallet API message in
|
|
124
|
+
// its `request` parameter (a site's own QR code).
|
|
125
|
+
const carried = parseWalletApiUrl({ url: trimmed });
|
|
126
|
+
const message = carried
|
|
127
|
+
? parseWalletApiMessage({ messageObject: carried })
|
|
128
|
+
: isWalletApiMessage(trimmed)
|
|
129
|
+
? parseWalletApiMessage({
|
|
130
|
+
messageObject: JSON.parse(trimmed)
|
|
131
|
+
})
|
|
132
|
+
: undefined;
|
|
133
|
+
if (message) {
|
|
134
|
+
return { kind: 'wallet-api-message', text: trimmed, message };
|
|
135
|
+
}
|
|
136
|
+
return { kind: 'credentials', text: trimmed };
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Classifies input and dispatches it to the matching handler.
|
|
140
|
+
*
|
|
141
|
+
* @param options {object}
|
|
142
|
+
* @param options.text {string} the scanned, pasted, or opened text
|
|
143
|
+
* @param [options.deepLinkSchemes] {string[]} this app's registered link
|
|
144
|
+
* prefixes
|
|
145
|
+
* @param options.handlers {WalletInputHandlers} the injected handlers
|
|
146
|
+
* @returns {Promise<*>} whatever the matching handler resolves to
|
|
147
|
+
*/
|
|
148
|
+
export async function handleWalletInput({ text, deepLinkSchemes, handlers }) {
|
|
149
|
+
const input = classifyWalletInput(text, { deepLinkSchemes });
|
|
150
|
+
switch (input.kind) {
|
|
151
|
+
case 'was-link':
|
|
152
|
+
return dispatch({ handler: handlers.wasLink, input });
|
|
153
|
+
case 'connect-code':
|
|
154
|
+
return dispatch({ handler: handlers.connectCode, input });
|
|
155
|
+
case 'legacy-request':
|
|
156
|
+
return dispatch({ handler: handlers.legacyRequest, input });
|
|
157
|
+
case 'interaction-url':
|
|
158
|
+
return dispatch({ handler: handlers.interactionUrl, input });
|
|
159
|
+
case 'deep-link':
|
|
160
|
+
return dispatch({ handler: handlers.deepLink, input });
|
|
161
|
+
case 'wallet-api-message':
|
|
162
|
+
return dispatch({ handler: handlers.walletApiMessage, input });
|
|
163
|
+
default:
|
|
164
|
+
return dispatch({ handler: handlers.credentials, input });
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Runs one handler, or refuses because this wallet does not implement the
|
|
169
|
+
* grammar the input turned out to be.
|
|
170
|
+
*
|
|
171
|
+
* @param options {object}
|
|
172
|
+
* @param [options.handler] {Function}
|
|
173
|
+
* @param options.input {WalletInput}
|
|
174
|
+
* @returns {Promise<*>}
|
|
175
|
+
*/
|
|
176
|
+
async function dispatch({ handler, input }) {
|
|
177
|
+
if (!handler) {
|
|
178
|
+
throw new Error(`Unhandled wallet input of kind "${input.kind}".`);
|
|
179
|
+
}
|
|
180
|
+
return handler(input);
|
|
181
|
+
}
|
|
182
|
+
//# sourceMappingURL=walletInput.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"walletInput.js","sourceRoot":"","sources":["../../src/request/walletInput.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) 2026 Interop Alliance. All rights reserved.
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* The last-write-wins conflict rule for the mutable `contacts` head
|
|
6
|
+
* collection. Every other synced collection is immutable and content-addressed,
|
|
7
|
+
* so a write-write conflict is impossible there. A contact head document is
|
|
8
|
+
* genuinely overwritten in place under a stable row id, so two replicas CAN
|
|
9
|
+
* race on the same row -- and a remote-master-always default would silently
|
|
10
|
+
* drop one side's edit.
|
|
11
|
+
*
|
|
12
|
+
* The rule lives here rather than in `@interop/social-core` because deciding
|
|
13
|
+
* it means DECRYPTING both sides: a head payload rides inside an encrypted
|
|
14
|
+
* envelope, and the `updatedAt` / writer pair the rule compares is sealed
|
|
15
|
+
* inside it. The comparison itself is still social-core's
|
|
16
|
+
* (`remotePayloadWins`), and both replicas run the same one, so they converge
|
|
17
|
+
* with no duplicates and no round trips.
|
|
18
|
+
*
|
|
19
|
+
* **Fail-safe to remote.** Whenever the fields the rule needs are unreachable
|
|
20
|
+
* -- a tombstone on either side, a missing cipher, an envelope that will not
|
|
21
|
+
* decrypt, a body that is not a valid head payload -- the remote master wins.
|
|
22
|
+
* That is the always-converging default, so a malformed side simply loses: a
|
|
23
|
+
* valid local over a malformed remote re-pushes and repairs the server copy, a
|
|
24
|
+
* valid remote over a malformed local is adopted, and two malformed sides adopt
|
|
25
|
+
* the server version rather than re-fighting the conflict forever. A delete is
|
|
26
|
+
* in the same class deliberately: a tombstone carries no fresher stamp (a
|
|
27
|
+
* delete does not rewrite the head payload), so deletion wins.
|
|
28
|
+
*
|
|
29
|
+
* Everything imported here is crypto-free: the envelope predicate and the
|
|
30
|
+
* `DocCipher` seam come from was-client's plain `sync` module (the same one the
|
|
31
|
+
* replication engine uses), never from its `edv` module, and the comparison
|
|
32
|
+
* comes from zero-dependency social-core. That keeps the `sync` subpath loadable
|
|
33
|
+
* in a plain test runner -- the EDV graph is the app's to pull in, at the point
|
|
34
|
+
* where it builds the cipher it passes down.
|
|
35
|
+
*/
|
|
36
|
+
import { type DocCipher, type Json } from '@interop/was-client/sync';
|
|
37
|
+
import { type ContactHeadPayload } from '@interop/social-core';
|
|
38
|
+
/**
|
|
39
|
+
* Which side of a contact-head conflict wins.
|
|
40
|
+
*/
|
|
41
|
+
export type ContactConflictWinner = 'remote' | 'local';
|
|
42
|
+
/**
|
|
43
|
+
* Recovers a validated head payload from a stored row body: decrypts an
|
|
44
|
+
* envelope, passes plaintext through, and resolves `undefined` when the
|
|
45
|
+
* payload (and so the fields the rule compares) cannot be reached.
|
|
46
|
+
*
|
|
47
|
+
* @param options {object}
|
|
48
|
+
* @param options.data {Json} the stored body: an encrypted envelope or a
|
|
49
|
+
* plaintext payload
|
|
50
|
+
* @param [options.cipher] {DocCipher} the collection's document cipher;
|
|
51
|
+
* absent for a plaintext store, in which case an envelope is unreachable
|
|
52
|
+
* @returns {Promise<ContactHeadPayload | undefined>}
|
|
53
|
+
*/
|
|
54
|
+
export declare function contactHeadPayloadOf({ data, cipher }: {
|
|
55
|
+
data: Json | undefined;
|
|
56
|
+
cipher?: DocCipher;
|
|
57
|
+
}): Promise<ContactHeadPayload | undefined>;
|
|
58
|
+
/**
|
|
59
|
+
* Decides a contact-head conflict. See the module doc for the fail-safe rule.
|
|
60
|
+
*
|
|
61
|
+
* @param options {object}
|
|
62
|
+
* @param options.remote {Json} the remote (master) row body
|
|
63
|
+
* @param options.local {Json} the local row body
|
|
64
|
+
* @param [options.cipher] {DocCipher} the collection's document cipher
|
|
65
|
+
* @param [options.remoteDeleted] {boolean} the remote side is a tombstone
|
|
66
|
+
* @param [options.localDeleted] {boolean} the local side is a tombstone
|
|
67
|
+
* @returns {Promise<ContactConflictWinner>}
|
|
68
|
+
*/
|
|
69
|
+
export declare function resolveContactHeadConflict({ remote, local, cipher, remoteDeleted, localDeleted }: {
|
|
70
|
+
remote: Json | undefined;
|
|
71
|
+
local: Json | undefined;
|
|
72
|
+
cipher?: DocCipher;
|
|
73
|
+
remoteDeleted?: boolean;
|
|
74
|
+
localDeleted?: boolean;
|
|
75
|
+
}): Promise<ContactConflictWinner>;
|
|
76
|
+
//# sourceMappingURL=contactsConflict.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contactsConflict.d.ts","sourceRoot":"","sources":["../../src/sync/contactsConflict.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,OAAO,EAEL,KAAK,SAAS,EACd,KAAK,IAAI,EACV,MAAM,0BAA0B,CAAA;AACjC,OAAO,EAGL,KAAK,kBAAkB,EACxB,MAAM,sBAAsB,CAAA;AAE7B;;GAEG;AACH,MAAM,MAAM,qBAAqB,GAAG,QAAQ,GAAG,OAAO,CAAA;AAEtD;;;;;;;;;;;GAWG;AACH,wBAAsB,oBAAoB,CAAC,EACzC,IAAI,EACJ,MAAM,EACP,EAAE;IACD,IAAI,EAAE,IAAI,GAAG,SAAS,CAAA;IACtB,MAAM,CAAC,EAAE,SAAS,CAAA;CACnB,GAAG,OAAO,CAAC,kBAAkB,GAAG,SAAS,CAAC,CAgB1C;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,0BAA0B,CAAC,EAC/C,MAAM,EACN,KAAK,EACL,MAAM,EACN,aAAqB,EACrB,YAAoB,EACrB,EAAE;IACD,MAAM,EAAE,IAAI,GAAG,SAAS,CAAA;IACxB,KAAK,EAAE,IAAI,GAAG,SAAS,CAAA;IACvB,MAAM,CAAC,EAAE,SAAS,CAAA;IAClB,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,YAAY,CAAC,EAAE,OAAO,CAAA;CACvB,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAejC"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) 2026 Interop Alliance. All rights reserved.
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* The last-write-wins conflict rule for the mutable `contacts` head
|
|
6
|
+
* collection. Every other synced collection is immutable and content-addressed,
|
|
7
|
+
* so a write-write conflict is impossible there. A contact head document is
|
|
8
|
+
* genuinely overwritten in place under a stable row id, so two replicas CAN
|
|
9
|
+
* race on the same row -- and a remote-master-always default would silently
|
|
10
|
+
* drop one side's edit.
|
|
11
|
+
*
|
|
12
|
+
* The rule lives here rather than in `@interop/social-core` because deciding
|
|
13
|
+
* it means DECRYPTING both sides: a head payload rides inside an encrypted
|
|
14
|
+
* envelope, and the `updatedAt` / writer pair the rule compares is sealed
|
|
15
|
+
* inside it. The comparison itself is still social-core's
|
|
16
|
+
* (`remotePayloadWins`), and both replicas run the same one, so they converge
|
|
17
|
+
* with no duplicates and no round trips.
|
|
18
|
+
*
|
|
19
|
+
* **Fail-safe to remote.** Whenever the fields the rule needs are unreachable
|
|
20
|
+
* -- a tombstone on either side, a missing cipher, an envelope that will not
|
|
21
|
+
* decrypt, a body that is not a valid head payload -- the remote master wins.
|
|
22
|
+
* That is the always-converging default, so a malformed side simply loses: a
|
|
23
|
+
* valid local over a malformed remote re-pushes and repairs the server copy, a
|
|
24
|
+
* valid remote over a malformed local is adopted, and two malformed sides adopt
|
|
25
|
+
* the server version rather than re-fighting the conflict forever. A delete is
|
|
26
|
+
* in the same class deliberately: a tombstone carries no fresher stamp (a
|
|
27
|
+
* delete does not rewrite the head payload), so deletion wins.
|
|
28
|
+
*
|
|
29
|
+
* Everything imported here is crypto-free: the envelope predicate and the
|
|
30
|
+
* `DocCipher` seam come from was-client's plain `sync` module (the same one the
|
|
31
|
+
* replication engine uses), never from its `edv` module, and the comparison
|
|
32
|
+
* comes from zero-dependency social-core. That keeps the `sync` subpath loadable
|
|
33
|
+
* in a plain test runner -- the EDV graph is the app's to pull in, at the point
|
|
34
|
+
* where it builds the cipher it passes down.
|
|
35
|
+
*/
|
|
36
|
+
import { isEncryptedEnvelope } from '@interop/was-client/sync';
|
|
37
|
+
import { isContactHeadPayload, remotePayloadWins } from '@interop/social-core';
|
|
38
|
+
/**
|
|
39
|
+
* Recovers a validated head payload from a stored row body: decrypts an
|
|
40
|
+
* envelope, passes plaintext through, and resolves `undefined` when the
|
|
41
|
+
* payload (and so the fields the rule compares) cannot be reached.
|
|
42
|
+
*
|
|
43
|
+
* @param options {object}
|
|
44
|
+
* @param options.data {Json} the stored body: an encrypted envelope or a
|
|
45
|
+
* plaintext payload
|
|
46
|
+
* @param [options.cipher] {DocCipher} the collection's document cipher;
|
|
47
|
+
* absent for a plaintext store, in which case an envelope is unreachable
|
|
48
|
+
* @returns {Promise<ContactHeadPayload | undefined>}
|
|
49
|
+
*/
|
|
50
|
+
export async function contactHeadPayloadOf({ data, cipher }) {
|
|
51
|
+
if (data === null || data === undefined) {
|
|
52
|
+
return undefined;
|
|
53
|
+
}
|
|
54
|
+
let body = data;
|
|
55
|
+
if (isEncryptedEnvelope(data)) {
|
|
56
|
+
if (!cipher) {
|
|
57
|
+
return undefined;
|
|
58
|
+
}
|
|
59
|
+
try {
|
|
60
|
+
body = await cipher.decrypt({ envelope: data });
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
return undefined;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return isContactHeadPayload(body) ? body : undefined;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Decides a contact-head conflict. See the module doc for the fail-safe rule.
|
|
70
|
+
*
|
|
71
|
+
* @param options {object}
|
|
72
|
+
* @param options.remote {Json} the remote (master) row body
|
|
73
|
+
* @param options.local {Json} the local row body
|
|
74
|
+
* @param [options.cipher] {DocCipher} the collection's document cipher
|
|
75
|
+
* @param [options.remoteDeleted] {boolean} the remote side is a tombstone
|
|
76
|
+
* @param [options.localDeleted] {boolean} the local side is a tombstone
|
|
77
|
+
* @returns {Promise<ContactConflictWinner>}
|
|
78
|
+
*/
|
|
79
|
+
export async function resolveContactHeadConflict({ remote, local, cipher, remoteDeleted = false, localDeleted = false }) {
|
|
80
|
+
if (remoteDeleted || localDeleted) {
|
|
81
|
+
return 'remote';
|
|
82
|
+
}
|
|
83
|
+
const remoteHead = await contactHeadPayloadOf({ data: remote, cipher });
|
|
84
|
+
const localHead = await contactHeadPayloadOf({ data: local, cipher });
|
|
85
|
+
if (remoteHead && localHead) {
|
|
86
|
+
return remotePayloadWins(remoteHead, localHead) ? 'remote' : 'local';
|
|
87
|
+
}
|
|
88
|
+
// Exactly one usable side wins on its own; neither usable falls back to the
|
|
89
|
+
// always-converging default.
|
|
90
|
+
if (localHead && !remoteHead) {
|
|
91
|
+
return 'local';
|
|
92
|
+
}
|
|
93
|
+
return 'remote';
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=contactsConflict.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contactsConflict.js","sourceRoot":"","sources":["../../src/sync/contactsConflict.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,OAAO,EACL,mBAAmB,EAGpB,MAAM,0BAA0B,CAAA;AACjC,OAAO,EACL,oBAAoB,EACpB,iBAAiB,EAElB,MAAM,sBAAsB,CAAA;AAO7B;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,EACzC,IAAI,EACJ,MAAM,EAIP;IACC,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACxC,OAAO,SAAS,CAAA;IAClB,CAAC;IACD,IAAI,IAAI,GAAY,IAAI,CAAA;IACxB,IAAI,mBAAmB,CAAC,IAAI,CAAC,EAAE,CAAC;QAC9B,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO,SAAS,CAAA;QAClB,CAAC;QACD,IAAI,CAAC;YACH,IAAI,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAA;QACjD,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,SAAS,CAAA;QAClB,CAAC;IACH,CAAC;IACD,OAAO,oBAAoB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAA;AACtD,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,0BAA0B,CAAC,EAC/C,MAAM,EACN,KAAK,EACL,MAAM,EACN,aAAa,GAAG,KAAK,EACrB,YAAY,GAAG,KAAK,EAOrB;IACC,IAAI,aAAa,IAAI,YAAY,EAAE,CAAC;QAClC,OAAO,QAAQ,CAAA;IACjB,CAAC;IACD,MAAM,UAAU,GAAG,MAAM,oBAAoB,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAA;IACvE,MAAM,SAAS,GAAG,MAAM,oBAAoB,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAA;IACrE,IAAI,UAAU,IAAI,SAAS,EAAE,CAAC;QAC5B,OAAO,iBAAiB,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAA;IACtE,CAAC;IACD,4EAA4E;IAC5E,6BAA6B;IAC7B,IAAI,SAAS,IAAI,CAAC,UAAU,EAAE,CAAC;QAC7B,OAAO,OAAO,CAAA;IAChB,CAAC;IACD,OAAO,QAAQ,CAAA;AACjB,CAAC"}
|
package/dist/sync/index.d.ts
CHANGED
|
@@ -16,6 +16,9 @@
|
|
|
16
16
|
* push, and orchestration algorithms.
|
|
17
17
|
* - `SyncedCollectionSpec` is the generic per-collection spec shape a concrete
|
|
18
18
|
* registry implements.
|
|
19
|
+
* - `resolveContactHeadConflict` / `contactHeadPayloadOf` are the
|
|
20
|
+
* last-write-wins rule for the one mutable collection (`contacts`), which
|
|
21
|
+
* needs a `DocCipher` to reach the fields it compares.
|
|
19
22
|
*
|
|
20
23
|
* The RxDB adapter (the web wallet's driver) is intentionally not part of this
|
|
21
24
|
* subpath in v0: that app keeps its own `replicateRxCollection` driver, and its
|
|
@@ -30,4 +33,6 @@ export { runPush, formatEtag } from './push.js';
|
|
|
30
33
|
export { SyncEngine } from './engine.js';
|
|
31
34
|
export type { SyncEngineDeps, SyncStatus } from './engine.js';
|
|
32
35
|
export type { SyncedCollectionSpec } from './collections.js';
|
|
36
|
+
export { contactHeadPayloadOf, resolveContactHeadConflict } from './contactsConflict.js';
|
|
37
|
+
export type { ContactConflictWinner } from './contactsConflict.js';
|
|
33
38
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/sync/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/sync/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/sync/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EACrB,MAAM,0BAA0B,CAAA;AACjC,YAAY,EACV,IAAI,EACJ,cAAc,EACd,OAAO,EACP,WAAW,EACX,WAAW,EACX,SAAS,EACV,MAAM,0BAA0B,CAAA;AAEjC,YAAY,EACV,SAAS,EACT,SAAS,EACT,gBAAgB,EAChB,eAAe,EAChB,MAAM,YAAY,CAAA;AAEnB,OAAO,EAAE,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAA;AACrD,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAA;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AACxC,YAAY,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAC7D,YAAY,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAA;AAE5D,OAAO,EACL,oBAAoB,EACpB,0BAA0B,EAC3B,MAAM,uBAAuB,CAAA;AAC9B,YAAY,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAA"}
|
package/dist/sync/index.js
CHANGED
|
@@ -16,6 +16,9 @@
|
|
|
16
16
|
* push, and orchestration algorithms.
|
|
17
17
|
* - `SyncedCollectionSpec` is the generic per-collection spec shape a concrete
|
|
18
18
|
* registry implements.
|
|
19
|
+
* - `resolveContactHeadConflict` / `contactHeadPayloadOf` are the
|
|
20
|
+
* last-write-wins rule for the one mutable collection (`contacts`), which
|
|
21
|
+
* needs a `DocCipher` to reach the fields it compares.
|
|
19
22
|
*
|
|
20
23
|
* The RxDB adapter (the web wallet's driver) is intentionally not part of this
|
|
21
24
|
* subpath in v0: that app keeps its own `replicateRxCollection` driver, and its
|
|
@@ -26,4 +29,5 @@ export { WasSyncConflictError, WasSyncNotFoundError } from '@interop/was-client/
|
|
|
26
29
|
export { runPull, projectionForDoc } from './pull.js';
|
|
27
30
|
export { runPush, formatEtag } from './push.js';
|
|
28
31
|
export { SyncEngine } from './engine.js';
|
|
32
|
+
export { contactHeadPayloadOf, resolveContactHeadConflict } from './contactsConflict.js';
|
|
29
33
|
//# sourceMappingURL=index.js.map
|
package/dist/sync/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/sync/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/sync/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EACrB,MAAM,0BAA0B,CAAA;AAiBjC,OAAO,EAAE,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAA;AACrD,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAA;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAIxC,OAAO,EACL,oBAAoB,EACpB,0BAA0B,EAC3B,MAAM,uBAAuB,CAAA"}
|
|
@@ -15,6 +15,12 @@ export interface RevokedClientKeys extends WebvhClientKeys {
|
|
|
15
15
|
* known latent (recovery-code) hashes are excluded. Refusing beats guessing:
|
|
16
16
|
* see the module doc. The fix is to pass the standing recovery codes' update-
|
|
17
17
|
* key hashes as `knownLatentHashes`.
|
|
18
|
+
*
|
|
19
|
+
* **`name` is a stable contract.** It is always the string
|
|
20
|
+
* `'StagedCommitmentAmbiguousError'`, and a consumer should match on that
|
|
21
|
+
* rather than on `instanceof`: a wallet app that links this package (or holds
|
|
22
|
+
* two copies of it through a dependency tree) gets a different class object for
|
|
23
|
+
* the same error, so `instanceof` silently fails there while the name does not.
|
|
18
24
|
*/
|
|
19
25
|
export declare class StagedCommitmentAmbiguousError extends Error {
|
|
20
26
|
candidates: string[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"revokeClient.d.ts","sourceRoot":"","sources":["../../src/webvh/revokeClient.ts"],"names":[],"mappings":"AAmCA,OAAO,KAAK,EACV,MAAM,EAGP,MAAM,2BAA2B,CAAA;AAUlC,OAAO,KAAK,EACV,qBAAqB,EACrB,eAAe,EACf,YAAY,EACb,MAAM,eAAe,CAAA;AAEtB;;;;;GAKG;AACH,MAAM,WAAW,iBAAkB,SAAQ,eAAe;IACxD,kBAAkB,EAAE,MAAM,CAAA;CAC3B;AAED
|
|
1
|
+
{"version":3,"file":"revokeClient.d.ts","sourceRoot":"","sources":["../../src/webvh/revokeClient.ts"],"names":[],"mappings":"AAmCA,OAAO,KAAK,EACV,MAAM,EAGP,MAAM,2BAA2B,CAAA;AAUlC,OAAO,KAAK,EACV,qBAAqB,EACrB,eAAe,EACf,YAAY,EACb,MAAM,eAAe,CAAA;AAEtB;;;;;GAKG;AACH,MAAM,WAAW,iBAAkB,SAAQ,eAAe;IACxD,kBAAkB,EAAE,MAAM,CAAA;CAC3B;AAED;;;;;;;;;;;;GAYG;AACH,qBAAa,8BAA+B,SAAQ,KAAK;IACvD,UAAU,EAAE,MAAM,EAAE,CAAA;gBACR,EAAE,UAAU,EAAE,EAAE;QAAE,UAAU,EAAE,MAAM,EAAE,CAAA;KAAE;CASrD;AA6FD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,wBAAsB,iBAAiB,CAAC,EACtC,OAAO,EACP,UAAU,EACV,aAAa,EACb,iBAAsB,EACvB,EAAE;IACD,OAAO,EAAE,YAAY,CAAA;IACrB,UAAU,EAAE,qBAAqB,CAAA;IACjC,aAAa,EAAE,iBAAiB,CAAA;IAChC,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAA;CAC7B,GAAG,OAAO,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC,CA2FxC"}
|
|
@@ -40,6 +40,12 @@ import { assertCarryOverCommitments, effectiveParameters, publishWebvhLog, readP
|
|
|
40
40
|
* known latent (recovery-code) hashes are excluded. Refusing beats guessing:
|
|
41
41
|
* see the module doc. The fix is to pass the standing recovery codes' update-
|
|
42
42
|
* key hashes as `knownLatentHashes`.
|
|
43
|
+
*
|
|
44
|
+
* **`name` is a stable contract.** It is always the string
|
|
45
|
+
* `'StagedCommitmentAmbiguousError'`, and a consumer should match on that
|
|
46
|
+
* rather than on `instanceof`: a wallet app that links this package (or holds
|
|
47
|
+
* two copies of it through a dependency tree) gets a different class object for
|
|
48
|
+
* the same error, so `instanceof` silently fails there while the name does not.
|
|
43
49
|
*/
|
|
44
50
|
export class StagedCommitmentAmbiguousError extends Error {
|
|
45
51
|
candidates;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"revokeClient.js","sourceRoot":"","sources":["../../src/webvh/revokeClient.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,OAAO,EAAE,iBAAiB,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAA;AAMxE,OAAO,EACL,0BAA0B,EAC1B,mBAAmB,EACnB,eAAe,EACf,gBAAgB,EAChB,WAAW,EACX,kBAAkB,EAClB,eAAe,EAChB,MAAM,eAAe,CAAA;AAiBtB
|
|
1
|
+
{"version":3,"file":"revokeClient.js","sourceRoot":"","sources":["../../src/webvh/revokeClient.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@interop/wallet-core",
|
|
3
3
|
"description": "Shared wallet-domain logic (WAS sync engine core and wallet Space layout contracts) for Interop wallet apps.",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.15.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"build": "pnpm run clear && tsc",
|
|
@@ -90,12 +90,24 @@
|
|
|
90
90
|
"import": "./dist/keys/index.js",
|
|
91
91
|
"default": "./dist/keys/index.js"
|
|
92
92
|
},
|
|
93
|
+
"./keys/clientKeyRecord": {
|
|
94
|
+
"types": "./dist/keys/clientKeyRecord.d.ts",
|
|
95
|
+
"react-native": "./dist/keys/clientKeyRecord.js",
|
|
96
|
+
"import": "./dist/keys/clientKeyRecord.js",
|
|
97
|
+
"default": "./dist/keys/clientKeyRecord.js"
|
|
98
|
+
},
|
|
93
99
|
"./keyring": {
|
|
94
100
|
"types": "./dist/keyring/index.d.ts",
|
|
95
101
|
"react-native": "./dist/keyring/index.js",
|
|
96
102
|
"import": "./dist/keyring/index.js",
|
|
97
103
|
"default": "./dist/keyring/index.js"
|
|
98
104
|
},
|
|
105
|
+
"./clients": {
|
|
106
|
+
"types": "./dist/clients/index.d.ts",
|
|
107
|
+
"react-native": "./dist/clients/index.js",
|
|
108
|
+
"import": "./dist/clients/index.js",
|
|
109
|
+
"default": "./dist/clients/index.js"
|
|
110
|
+
},
|
|
99
111
|
"./enrollment": {
|
|
100
112
|
"types": "./dist/enrollment/index.d.ts",
|
|
101
113
|
"react-native": "./dist/enrollment/index.js",
|
|
@@ -109,14 +121,15 @@
|
|
|
109
121
|
"sideEffects": false,
|
|
110
122
|
"dependencies": {
|
|
111
123
|
"@interop/data-integrity-core": "^8.4.0",
|
|
112
|
-
"@interop/data-integrity-proof": "^3.4.
|
|
124
|
+
"@interop/data-integrity-proof": "^3.4.3",
|
|
113
125
|
"@interop/did-method-webvh": "^5.0.0",
|
|
114
126
|
"@interop/ed25519-signature": "^7.1.4",
|
|
115
127
|
"@interop/ed25519-verification-key": "^8.0.3",
|
|
116
128
|
"@interop/ezcap": "^7.4.1",
|
|
117
129
|
"@interop/security-document-loader": "^9.5.1",
|
|
130
|
+
"@interop/social-core": "^0.7.0",
|
|
118
131
|
"@interop/vc": "^11.0.6",
|
|
119
|
-
"@interop/was-client": "^0.
|
|
132
|
+
"@interop/was-client": "^0.26.0",
|
|
120
133
|
"@interop/webkms-client": "^14.7.1",
|
|
121
134
|
"@interop/x25519-key-agreement-key": "^5.2.1",
|
|
122
135
|
"@noble/hashes": "^2.2.0",
|