@real-life/trust-protocol 0.7.0 → 0.8.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/CHANGELOG.md +69 -0
- package/README.md +41 -3
- package/dist/adapters/vti-mediator.d.ts +32 -0
- package/dist/adapters/vti-mediator.d.ts.map +1 -1
- package/dist/adapters/vti-mediator.js +91 -3
- package/dist/adapters/vti-mediator.js.map +1 -1
- package/dist/encounter/ceremony.d.ts +10 -0
- package/dist/encounter/ceremony.d.ts.map +1 -1
- package/dist/encounter/ceremony.js +70 -13
- package/dist/encounter/ceremony.js.map +1 -1
- package/dist/encounter.d.ts +4 -0
- package/dist/encounter.d.ts.map +1 -1
- package/dist/encounter.js +3 -1
- package/dist/encounter.js.map +1 -1
- package/dist/holder-api.d.ts +18 -2
- package/dist/holder-api.d.ts.map +1 -1
- package/dist/holder-api.js +16 -4
- package/dist/holder-api.js.map +1 -1
- package/dist/identity-state.d.ts +13 -1
- package/dist/identity-state.d.ts.map +1 -1
- package/dist/identity-state.js +36 -1
- package/dist/identity-state.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/results.d.ts +4 -0
- package/dist/results.d.ts.map +1 -1
- package/dist/results.js.map +1 -1
- package/dist/views.d.ts +14 -0
- package/dist/views.d.ts.map +1 -1
- package/dist/views.js +34 -5
- package/dist/views.js.map +1 -1
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,74 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.8.0
|
|
4
|
+
|
|
5
|
+
Takes up the VTI Mediator Adapter Profile 0.25 (§1b, the delivery hint)
|
|
6
|
+
and Encounter 0.31.1: a card carries the hints by which its side is
|
|
7
|
+
reachable in the relationship the card opens. A minor version: the
|
|
8
|
+
public API grows (`CarrierOffer`, a new `ActError` member, new
|
|
9
|
+
`RelationshipView` fields, three adapter exports); the storage format
|
|
10
|
+
does not change.
|
|
11
|
+
|
|
12
|
+
- **The carrier offer** of `show` and `scan`: `carrier: {nonce,
|
|
13
|
+
deliveryHints}` (new type `CarrierOffer`). `nonce` is the
|
|
14
|
+
relationship's carrier nonce N, 32 bytes the app draws fresh (Identity
|
|
15
|
+
§7a.3); `deliveryHints` are the hints the app built from the wire
|
|
16
|
+
identities its adapter derives from N. The displayed card (`show`) or
|
|
17
|
+
the scanner's sent card (`scan`) carries the hints under its proof.
|
|
18
|
+
The library interprets no hint. The offer is act input: bound and
|
|
19
|
+
journaled with the act, so a repeat under the same actId answers the
|
|
20
|
+
same card and another offer under it is `actid-conflict`.
|
|
21
|
+
- **N in the register** (`register.carriers`, generation 1) under the
|
|
22
|
+
relationship the card opens: at `show` already, as the card's pair
|
|
23
|
+
label enters the register before display (Encounter 4110); a card that
|
|
24
|
+
ages unscanned leaves its entry, as it leaves its label. At `scan`
|
|
25
|
+
under the scanner's fresh relationship. The storage format is
|
|
26
|
+
unchanged (codec 3).
|
|
27
|
+
- **Refusals**: more than eight hints or a hint over 512 characters
|
|
28
|
+
(Encounter RLTP-ENC-6090) is `card-invalid` with `ref`
|
|
29
|
+
`RLTP-ENC-6090`; an offer without a hint, or with a hint that is no
|
|
30
|
+
string, is `card-invalid` without a `ref` (an empty offer announces
|
|
31
|
+
nothing; a card without hints needs no offer, 6080); a nonce that is not 32 bytes in canonical base64url,
|
|
32
|
+
or that the register already holds as a carrier or pair nonce, is the
|
|
33
|
+
new code `carrier-nonce-invalid`. Nothing commits on a refusal.
|
|
34
|
+
- **The view**: each `RelationshipView` names the relationship's
|
|
35
|
+
canonical carrier-nonce entry (`carrierNonce: {nonce, generation}`) and
|
|
36
|
+
the counterpart's hints from the card of the enactment that opened it
|
|
37
|
+
(`counterpartDeliveryHints`), as signed. A re-encounter chained into
|
|
38
|
+
the relationship changes neither (profile RLTP-VTI-1230). Without an
|
|
39
|
+
offer both are absent.
|
|
40
|
+
- `cardBody` takes `deliveryHints`.
|
|
41
|
+
- **The adapter builds and reads the hint** (`./adapters/vti-mediator`,
|
|
42
|
+
below the port line): `deliveryHint(rootIkm, C, N)` derives this
|
|
43
|
+
side's connection DID and egress identity from (root, `C`, `N`), as
|
|
44
|
+
the factory derives the instance's trio (derived, not supplied), and
|
|
45
|
+
gives its hint (RLTP-VTI-1210: the JCS form of the `TSPTransport`
|
|
46
|
+
entry);
|
|
47
|
+
`readDeliveryHint(hint, C)` reads one hint strictly (1210, 1220: JSON,
|
|
48
|
+
byte-equal to its JCS form, exactly the four members, both identities
|
|
49
|
+
canonical Ed25519 `did:key` that decode to `0xed01` and 32 bytes,
|
|
50
|
+
`serviceEndpoint` = `C`) into `{connectionDid, egressDid, carrier}` or null;
|
|
51
|
+
`readDeliveryHints(hints, C, self)` reads a card's list as the side
|
|
52
|
+
`self` (its own connection DID and egress identity): a hint naming one
|
|
53
|
+
of them is ignored (RLTP-VTI-1227), then exactly one hint for `C`
|
|
54
|
+
(1225), else null. Both readers are total (RLTP-VTI-1220): any input
|
|
55
|
+
answers null or the complete identities, nothing throws — a hint that
|
|
56
|
+
parses but has no JCS form (a lone surrogate) included; tested over the
|
|
57
|
+
vector's corpus and 20 000 seeded mutations. The app passes the
|
|
58
|
+
identities to the wire (`peerDid`, `peerEgressDid` of the binding),
|
|
59
|
+
which refuses a counterpart identity that is one of its own.
|
|
60
|
+
- **No change of N.** The library offers no rotation of a carrier nonce
|
|
61
|
+
(Identity §7a.3, `generation + 1`) and no replacement after loss:
|
|
62
|
+
`register.carriers` is written once per relationship, at `show` or
|
|
63
|
+
`scan`. The profile carries none either (RLTP-VTI-1245). With one
|
|
64
|
+
writer of the register per holder, as in this library, `carrierNonce`
|
|
65
|
+
is the `N` whose identities the counterpart saw; two devices writing a
|
|
66
|
+
first `N` apart would make that untrue (profile Open Issue 13). A
|
|
67
|
+
relationship chained into another is no `RelationshipView` of its own
|
|
68
|
+
(only an id in `chainedFrom`) and shows no `carrierNonce`: the app
|
|
69
|
+
closes the adapter instance of a relationship once its id appears in
|
|
70
|
+
another relationship's `chainedFrom` (RLTP-VTI-1230).
|
|
71
|
+
|
|
3
72
|
## 0.7.0
|
|
4
73
|
|
|
5
74
|
Takes up the VTI Mediator Adapter Profile 0.24: the sending form of §3a.
|
package/README.md
CHANGED
|
@@ -146,6 +146,44 @@ human: `receive`, `report`, `resume`, `tick`, `recover`, `takeMessages`.
|
|
|
146
146
|
Reads: `contacts`, `contact`, `groups`, `profile`, `prompts`, `inbox`,
|
|
147
147
|
`deliveryStatus`, `deviceKey`, `replay`, `snapshot`, `subscribe`.
|
|
148
148
|
|
|
149
|
+
**Delivery hints** (Encounter RLTP-ENC-6080, 6090; Identity §7a.3; VTI
|
|
150
|
+
Mediator Adapter Profile 0.25 §1b). `show` and `scan` take a carrier
|
|
151
|
+
offer, `carrier: {nonce, deliveryHints}`: the relationship's carrier
|
|
152
|
+
nonce N (32 bytes the app draws fresh) and the hints the app built from
|
|
153
|
+
the wire identities its adapter derives from N. The card (the displayed
|
|
154
|
+
card, or the scanner's sent card) carries the hints under its proof, and
|
|
155
|
+
N enters the register under the relationship the card opens — at `show`
|
|
156
|
+
already, as the card's pair label does. More than eight hints or a hint
|
|
157
|
+
over 512 characters is `card-invalid` with `ref` `RLTP-ENC-6090`; an
|
|
158
|
+
offer without a hint, or with a hint that is no string, is
|
|
159
|
+
`card-invalid` without a `ref`; a nonce
|
|
160
|
+
that is not 32 bytes or that the register already holds is
|
|
161
|
+
`carrier-nonce-invalid`. The offer is act input, journaled with the act.
|
|
162
|
+
The library interprets no hint. Each relationship of a contact view names
|
|
163
|
+
the own canonical carrier-nonce entry (`carrierNonce: {nonce,
|
|
164
|
+
generation}`) and the counterpart's hints from the card of the enactment
|
|
165
|
+
that opened it (`counterpartDeliveryHints`); a re-encounter chained into
|
|
166
|
+
the relationship changes neither, and the chained relationship shows no
|
|
167
|
+
`carrierNonce`: the app closes the adapter instance of a relationship
|
|
168
|
+
once its id appears in another relationship's `chainedFrom`. The
|
|
169
|
+
library offers no rotation or replacement of N (profile RLTP-VTI-1245);
|
|
170
|
+
with its one writer per holder, `carrierNonce` is the N the counterpart
|
|
171
|
+
saw. The VTI adapter module builds and reads the hint:
|
|
172
|
+
`deliveryHint(rootIkm, C, N)` (derived like the adapter's trio),
|
|
173
|
+
`readDeliveryHint(hint, C)`, `readDeliveryHints(hints, C, self)` (profile
|
|
174
|
+
§1b; total readers, a hint naming `self`'s identities ignored).
|
|
175
|
+
|
|
176
|
+
```ts
|
|
177
|
+
import { deliveryHint } from '@real-life/trust-protocol/adapters/vti-mediator'
|
|
178
|
+
|
|
179
|
+
// rootIkm and C: the same inputs the app gives MediatorCarrierAdapter.create
|
|
180
|
+
const nonce = crypto.getRandomValues(new Uint8Array(32))
|
|
181
|
+
const hint = await deliveryHint(rootIkm, C, nonce)
|
|
182
|
+
const shown = await holder.show({ when: Date.now(), actId: crypto.randomUUID(), carrier: { nonce, deliveryHints: [hint] } })
|
|
183
|
+
const [rel] = (await holder.contacts())[0]?.relationships ?? []
|
|
184
|
+
// rel?.carrierNonce: this side's N; rel?.counterpartDeliveryHints: the counterpart's hints, as signed
|
|
185
|
+
```
|
|
186
|
+
|
|
149
187
|
One actId, one result: every human act is journaled under its actId with
|
|
150
188
|
its result. A repeat under the same actId answers the journaled events
|
|
151
189
|
(for `sendMessage` the same `mid`) at any clock and across a lock and a
|
|
@@ -167,7 +205,7 @@ journal, and acting anew is the human's decision. Custody:
|
|
|
167
205
|
|
|
168
206
|
## What the root exports
|
|
169
207
|
|
|
170
|
-
- `createHolder` and its types (`Holder`, `HolderOptions`, `HumanActOptions`,
|
|
208
|
+
- `createHolder` and its types (`Holder`, `HolderOptions`, `HumanActOptions`, `CarrierOffer`,
|
|
171
209
|
`HolderSnapshot`).
|
|
172
210
|
- The ports: `Store`, `KeyProvider`, `Entropy`, `Log`, `Access`,
|
|
173
211
|
`RetryPolicy`, `DeliveryReport`, `Outbound`; `seedKeys(seed)` is the
|
|
@@ -194,7 +232,7 @@ Other entry points:
|
|
|
194
232
|
|---|---|
|
|
195
233
|
| `./testing` | `InMemoryStore`, `memoryLog`, `scriptedEntropy`, `storeContract`, `emptyState`, `stateBuilder`, `freezeDeep`, `sampleState`, `openPromptModule`, the invariant checks, `forgeMapping` (deniability, Trust 6.1), `SCHEMAS` and the generated `wire` types. For tests, vectors and adapter authors; not for production holders. |
|
|
196
234
|
| `./internal` | The structural `HolderState`, `encodeState` and the codec chain, the engine's module types, the pure view functions, the modules' factories and pure reads. For the library's own modules and tests; not an app contract. |
|
|
197
|
-
| `./adapters/vti-mediator` | The VTI mediator as a transport adapter (profile 0.
|
|
235
|
+
| `./adapters/vti-mediator` | The VTI mediator as a transport adapter (profile 0.25): its submission states as `DeliveryReport`, collection and ack handling, the selective conclusion of a collection (`conclude(c, now, {keep})`, `concludable(result)`: a `failed(rate-limited)` item stays with the carrier), the sending form of §3a: every deposit names its `SendMode` (`routed`, or `egress-session` after the one-way switch of RLTP-VTI-3130), the send state (mode, open routed deposits) travels in `AckState.send` (a `submit()` without a digest opens nothing), a `WireError('routed-refused')` switches at once, a wire without `queueEmpty()` never completes a collection and so never switches, `answered(digest, now)` carries the holder's answers to a later instance, `depositAddressing(mode, self, peerConnection, carrier)` gives both layers' addressing, and `deliveryHint(rootIkm, C, N)`, `readDeliveryHint(hint, C)`, `readDeliveryHints(hints, C, self)` build and read the delivery hint of §1b (total readers). |
|
|
198
236
|
|
|
199
237
|
## The modules and the rules they implement
|
|
200
238
|
|
|
@@ -314,7 +352,7 @@ This package uses its own semver; the specification uses castings.
|
|
|
314
352
|
| membership | Membership Tasks 0.20, Access 0.57 | the Access envelope (Membership 3.3: `access-operation/0.1` with `member.add` and the sealed welcome; this library sends its own `x-membership-welcome/0.1`); an admission prompt after the bound of RLTP-MT-3282; roster replication: a holder knows the members it admitted and the roster its welcome carried |
|
|
315
353
|
| introduction | Trust 0.31 §8 | how a requester learns the mediator's designator (8.3): this library's mediator sends `x-introduction-offer/0.1` |
|
|
316
354
|
| delivery | Delivery 0.83 | transport adapters beyond `./adapters/vti-mediator`; the block of the Trust Layer's types (Message Tasks 6240: their treatments wait for the next casting of the Trust Layer) |
|
|
317
|
-
| transport adapter | VTI Mediator Adapter Profile 0.
|
|
355
|
+
| transport adapter | VTI Mediator Adapter Profile 0.25 | a change of the carrier nonce N (RLTP-VTI-1245; profile Open Issue 13); the TSP framing, which is the wire binding's (profile §7; `binding/` in the repository); a return from `egress-session` to `routed` (profile Open Issue 7) |
|
|
318
356
|
| message | Message Tasks 0.1 | holding a message unsent until its tuple is ready (5020): `sendMessage` answers `not-ready` and the app keeps the message; checking `replyTo` against the relationship's history (5120), which is the app's; multi-device (§9); `failed(task-expired)` for a message: reachable only with a retry horizon beyond P179D, which the engine does not admit (at most P90D), so an undelivered message ends as `failed(expired-by-adapter-policy)` |
|
|
319
357
|
| devices | Identity §5.5 | multi-device production: one writer per holder |
|
|
320
358
|
|
|
@@ -12,6 +12,38 @@ export declare const DECLARED: Readonly<{
|
|
|
12
12
|
readonly duplicateWindowMs: number;
|
|
13
13
|
readonly routedAckDeadlineMs: number;
|
|
14
14
|
}>;
|
|
15
|
+
/** The counterpart's wire identities at one carrier, as its hint names them. */
|
|
16
|
+
export interface DeliveryHintIdentities {
|
|
17
|
+
connectionDid: string;
|
|
18
|
+
egressDid: string;
|
|
19
|
+
carrier: string;
|
|
20
|
+
}
|
|
21
|
+
/** This side's hint for carrier `C` in the relationship of carrier nonce
|
|
22
|
+
* `N` (RLTP-VTI-1210, 1215): the connection DID and the egress identity
|
|
23
|
+
* derived here from (root, `C`, `N`), exactly as the factory derives the
|
|
24
|
+
* instance's trio — derived, not supplied, so the two cannot come from
|
|
25
|
+
* different relationships — as the JCS form of the TSPTransport service
|
|
26
|
+
* entry naming the connection DID (`id`, with `#tsp`), `C`
|
|
27
|
+
* (`serviceEndpoint`) and the egress identity (`rltpEgress`). */
|
|
28
|
+
export declare function deliveryHint(rootIkm: Uint8Array, carrier: string, nonce: Uint8Array): Promise<string>;
|
|
29
|
+
/** One hint read strictly (RLTP-VTI-1210, 1220) for carrier `C`: JSON,
|
|
30
|
+
* byte-equal to its JCS form, exactly the four members, type
|
|
31
|
+
* TSPTransport, an `id` ending in `#tsp`, both identities distinct
|
|
32
|
+
* canonical Ed25519 did:key, `serviceEndpoint` byte-equal to `C`.
|
|
33
|
+
* Total (RLTP-VTI-1220): any other input — not a string, not JSON, no JCS
|
|
34
|
+
* form (a lone surrogate), any other shape — is null, ignored; it never
|
|
35
|
+
* throws. */
|
|
36
|
+
export declare function readDeliveryHint(hint: unknown, carrier: unknown): DeliveryHintIdentities | null;
|
|
37
|
+
/** The counterpart's wire identities at `C` from the hints of the card
|
|
38
|
+
* that opened the relationship, read by the side `self` (its own
|
|
39
|
+
* connection DID and egress identity of this relationship and carrier):
|
|
40
|
+
* every hint read as readDeliveryHint does; a hint naming one of `self`'s
|
|
41
|
+
* identities is ignored (RLTP-VTI-1227); of what remains, the one hint
|
|
42
|
+
* for `C` (RLTP-VTI-1225, 1240) — none, or more than one, is null: the
|
|
43
|
+
* relationship is not carried at `C` (RLTP-VTI-1235). Total: any input
|
|
44
|
+
* answers null or the identities, never a throw; without a well-formed
|
|
45
|
+
* `self` nothing is read. */
|
|
46
|
+
export declare function readDeliveryHints(hints: unknown, carrier: unknown, self: unknown): DeliveryHintIdentities | null;
|
|
15
47
|
/** How a deposit reaches the mediator (RLTP-VTI-3110, 3120). */
|
|
16
48
|
export type SendMode = 'routed' | 'egress-session';
|
|
17
49
|
/** One TSP layer's addressing (no keys, no bytes: those are the wire's). */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vti-mediator.d.ts","sourceRoot":"","sources":["../../src/adapters/vti-mediator.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"vti-mediator.d.ts","sourceRoot":"","sources":["../../src/adapters/vti-mediator.ts"],"names":[],"mappings":"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"}
|
|
@@ -20,9 +20,14 @@
|
|
|
20
20
|
// about transport; the holder's receive core verifies the delivery-ack
|
|
21
21
|
// itself.
|
|
22
22
|
//
|
|
23
|
-
// Profile: spec/adapter-vti-mediator.md v0.
|
|
23
|
+
// Profile: spec/adapter-vti-mediator.md v0.25 (twenty-fifth casting;
|
|
24
24
|
// round journals under design/adapter-review*). A
|
|
25
|
-
// transport adapter contract — NOT a carrier at the port.
|
|
25
|
+
// transport adapter contract — NOT a carrier at the port. The
|
|
26
|
+
// counterpart's connection DID and egress identity the wire needs come
|
|
27
|
+
// from the counterpart's delivery hint in the card that opened the
|
|
28
|
+
// relationship (profile §1b); the holder hands the hints on uninterpreted
|
|
29
|
+
// (RelationshipView.counterpartDeliveryHints) and this adapter derives its
|
|
30
|
+
// own trio from the relationship's carrier nonce (RelationshipView.carrierNonce).
|
|
26
31
|
//
|
|
27
32
|
// Sending form (profile §3a, lib 0.7.0): every deposit names its mode to
|
|
28
33
|
// the wire. Mode `routed` (the mode of every instance from construction):
|
|
@@ -82,7 +87,7 @@
|
|
|
82
87
|
// · A retired instance mutates nothing and refuses everything
|
|
83
88
|
// except reading its ack state.
|
|
84
89
|
import { jcs } from '../core.js';
|
|
85
|
-
import { sha } from '../crypto.js';
|
|
90
|
+
import { anchorOfEd, edRawOfAnchor, sha } from '../crypto.js';
|
|
86
91
|
import { carrierPrincipal, carrierScopedIdentity } from '../carrier-identity.js';
|
|
87
92
|
// ── Declared constants (profile §2) — promises of THIS casting ──────
|
|
88
93
|
// frozen: the declared promises cannot be changed at run time either
|
|
@@ -95,6 +100,89 @@ export const DECLARED = Object.freeze({
|
|
|
95
100
|
duplicateWindowMs: 30 * 86_400_000,
|
|
96
101
|
routedAckDeadlineMs: 72 * 3_600_000,
|
|
97
102
|
});
|
|
103
|
+
const HINT_MEMBERS = jcs(['id', 'rltpEgress', 'serviceEndpoint', 'type']);
|
|
104
|
+
/** An Ed25519 did:key in the form RLTP-VTI-1210 fixes: `did:key:z` and the
|
|
105
|
+
* base58btc of multicodec 0xed01 followed by the 32-byte key, rendered
|
|
106
|
+
* canonically (decoding and re-encoding gives the same string). */
|
|
107
|
+
const edDidKey = (x) => {
|
|
108
|
+
// the canonical form has exactly 56 characters; checked first, so no long input reaches the base58 decoder
|
|
109
|
+
if (typeof x !== 'string' || x.length !== 56)
|
|
110
|
+
return false;
|
|
111
|
+
const raw = edRawOfAnchor(x);
|
|
112
|
+
return raw !== null && anchorOfEd(raw) === x;
|
|
113
|
+
};
|
|
114
|
+
/** This side's hint for carrier `C` in the relationship of carrier nonce
|
|
115
|
+
* `N` (RLTP-VTI-1210, 1215): the connection DID and the egress identity
|
|
116
|
+
* derived here from (root, `C`, `N`), exactly as the factory derives the
|
|
117
|
+
* instance's trio — derived, not supplied, so the two cannot come from
|
|
118
|
+
* different relationships — as the JCS form of the TSPTransport service
|
|
119
|
+
* entry naming the connection DID (`id`, with `#tsp`), `C`
|
|
120
|
+
* (`serviceEndpoint`) and the egress identity (`rltpEgress`). */
|
|
121
|
+
export async function deliveryHint(rootIkm, carrier, nonce) {
|
|
122
|
+
// snapshot at entry, as create does (R8-B2): a caller's buffer changed
|
|
123
|
+
// between the two derivations must not couple two relationships
|
|
124
|
+
const ikm = new Uint8Array(rootIkm);
|
|
125
|
+
const n = new Uint8Array(nonce);
|
|
126
|
+
const connection = await carrierScopedIdentity(ikm, carrier, n, 'connection');
|
|
127
|
+
const egress = await carrierScopedIdentity(ikm, carrier, n, 'egress');
|
|
128
|
+
return jcs({ id: connection.did + '#tsp', type: 'TSPTransport', serviceEndpoint: carrier, rltpEgress: egress.did });
|
|
129
|
+
}
|
|
130
|
+
/** One hint read strictly (RLTP-VTI-1210, 1220) for carrier `C`: JSON,
|
|
131
|
+
* byte-equal to its JCS form, exactly the four members, type
|
|
132
|
+
* TSPTransport, an `id` ending in `#tsp`, both identities distinct
|
|
133
|
+
* canonical Ed25519 did:key, `serviceEndpoint` byte-equal to `C`.
|
|
134
|
+
* Total (RLTP-VTI-1220): any other input — not a string, not JSON, no JCS
|
|
135
|
+
* form (a lone surrogate), any other shape — is null, ignored; it never
|
|
136
|
+
* throws. */
|
|
137
|
+
export function readDeliveryHint(hint, carrier) {
|
|
138
|
+
try {
|
|
139
|
+
return readStrict(hint, carrier);
|
|
140
|
+
}
|
|
141
|
+
catch {
|
|
142
|
+
return null;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
function readStrict(hint, carrier) {
|
|
146
|
+
if (typeof hint !== 'string' || typeof carrier !== 'string' || carrier.length === 0)
|
|
147
|
+
return null;
|
|
148
|
+
const o = JSON.parse(hint);
|
|
149
|
+
if (o === null || typeof o !== 'object' || Array.isArray(o) || jcs(o) !== hint)
|
|
150
|
+
return null;
|
|
151
|
+
const e = o;
|
|
152
|
+
if (jcs(Object.keys(e).sort()) !== HINT_MEMBERS || e.type !== 'TSPTransport' || e.serviceEndpoint !== carrier)
|
|
153
|
+
return null;
|
|
154
|
+
if (typeof e.id !== 'string' || !e.id.endsWith('#tsp'))
|
|
155
|
+
return null;
|
|
156
|
+
const connectionDid = e.id.slice(0, -'#tsp'.length);
|
|
157
|
+
if (!edDidKey(connectionDid) || !edDidKey(e.rltpEgress) || connectionDid === e.rltpEgress)
|
|
158
|
+
return null;
|
|
159
|
+
return { connectionDid, egressDid: e.rltpEgress, carrier };
|
|
160
|
+
}
|
|
161
|
+
/** The counterpart's wire identities at `C` from the hints of the card
|
|
162
|
+
* that opened the relationship, read by the side `self` (its own
|
|
163
|
+
* connection DID and egress identity of this relationship and carrier):
|
|
164
|
+
* every hint read as readDeliveryHint does; a hint naming one of `self`'s
|
|
165
|
+
* identities is ignored (RLTP-VTI-1227); of what remains, the one hint
|
|
166
|
+
* for `C` (RLTP-VTI-1225, 1240) — none, or more than one, is null: the
|
|
167
|
+
* relationship is not carried at `C` (RLTP-VTI-1235). Total: any input
|
|
168
|
+
* answers null or the identities, never a throw; without a well-formed
|
|
169
|
+
* `self` nothing is read. */
|
|
170
|
+
export function readDeliveryHints(hints, carrier, self) {
|
|
171
|
+
try {
|
|
172
|
+
if (!Array.isArray(hints))
|
|
173
|
+
return null;
|
|
174
|
+
const me = self;
|
|
175
|
+
if (me === null || typeof me !== 'object' || !edDidKey(me.connection) || !edDidKey(me.egress))
|
|
176
|
+
return null;
|
|
177
|
+
const own = new Set([me.connection, me.egress]);
|
|
178
|
+
const read = hints.map((h) => readDeliveryHint(h, carrier))
|
|
179
|
+
.filter((x) => x !== null && !own.has(x.connectionDid) && !own.has(x.egressDid));
|
|
180
|
+
return read.length === 1 ? read[0] : null;
|
|
181
|
+
}
|
|
182
|
+
catch {
|
|
183
|
+
return null;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
98
186
|
const SEND_MODES = new Set(['routed', 'egress-session']);
|
|
99
187
|
/** The addressing of a deposit in `mode` (RLTP-VTI-1110, 1120, 3110,
|
|
100
188
|
* 3115, 3120): the inner `direct` message from this side's egress
|