nostr-contact-card 0.2.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/LICENCE ADDED
@@ -0,0 +1,21 @@
1
+ MIT Licence
2
+
3
+ Copyright (c) 2026 ForgeSworn
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,115 @@
1
+ # nostr-contact-card
2
+
3
+ [![CI](https://github.com/forgesworn/nostr-contact-card/actions/workflows/ci.yml/badge.svg)](https://github.com/forgesworn/nostr-contact-card/actions/workflows/ci.yml)
4
+ [![npm](https://img.shields.io/npm/v/nostr-contact-card)](https://www.npmjs.com/package/nostr-contact-card)
5
+ [![licence: MIT](https://img.shields.io/badge/licence-MIT-blue.svg)](./LICENCE)
6
+ [![GitHub Sponsors](https://img.shields.io/github/sponsors/TheCryptoDonkey?logo=githubsponsors&color=ea4aaa&label=Sponsor)](https://github.com/sponsors/TheCryptoDonkey)
7
+
8
+ **One QR or link that makes a stranger a contact, names their box, and starts a bond.**
9
+
10
+ A contact card is a small signed JSON object carried after `#` in a link or
11
+ as the whole of a QR code. It holds a person's key and name, their public
12
+ relays, their box (a Link address card, carried opaquely, that the person's
13
+ signature endorses), a rendezvous key and a fresh ephemeral for deriving
14
+ private rendezvous material, an optional attestation pointer, and a bond
15
+ handshake so an in-person ceremony can start from the card.
16
+
17
+ Reading a card needs nothing from the network: five checks, in order, and
18
+ the result names the step that failed so the client can say why. What comes
19
+ back is rebuilt from the fields the draft names, each checked; an extra key
20
+ on the wire never reaches the caller under a verified signature. Dialling
21
+ the box afterwards is on the person's own word; a later fresh address from
22
+ the box is accepted only under the node id they endorsed, which the client
23
+ pins from the first read (the Link card inside a contact card lasts seven
24
+ days, the card itself thirty, so a client keeps the node id it read).
25
+
26
+ ```ts
27
+ import { buildCard, cardLink, readCard, refreshBox } from 'nostr-contact-card'
28
+
29
+ const card = buildCard({ identityPrivateKey, rz, ephemeralPrivateKey, name: 'Ada', relays, boxes: [box], bond })
30
+ const link = cardLink('https://your.app/join', card) // the server never sees the fragment
31
+
32
+ const r = readCard(scannedText, now())
33
+ if (!r.ok) show(r.step, r.reason)
34
+ else { addContact(r.card.p, r.card.name); for (const b of r.boxes) dial(b.link, b.box.p) }
35
+
36
+ const fresh = refreshBox(pinnedNodeId, freshLinkCardBytes, now(), highestSerialSeen)
37
+ ```
38
+
39
+ Vectors in `vectors/contact-card.json` are the draft's known-answer file:
40
+ cards failing at each step, extra-key, format-character, surrogate,
41
+ byte-order-mark, empty-field and expiry-window cases, and refresh cases
42
+ including a small-order node id and a nonce point carrying torsion. A
43
+ second implementation, written from the draft alone, must agree on every
44
+ one; the vectors carry the expected `ok` and step, and a verifier that
45
+ disagrees on either is wrong.
46
+
47
+ ## What a card carries
48
+
49
+ More than two keys: the person's key `p`, their rendezvous key `rz`, a
50
+ fresh ephemeral, each box's key and Link node id (and so its onion
51
+ address), a display name, and a bond nonce that is a bearer secret for the
52
+ card's life: whoever holds the link can start the ceremony. The fragment
53
+ never reaches the server, but it does sit in browser history, clipboards,
54
+ chat logs and photographs of QR codes. Hand a card to the person it is
55
+ for.
56
+
57
+ Whoever holds it cannot derive rendezvous material from it, because the
58
+ derivation (in nostr-deaddrop) needs the reader's own secret or the
59
+ ephemeral's private half, and a card carries neither. It is never
60
+ identity: the box still decides admission, and a bond still needs the
61
+ ceremony.
62
+
63
+ ## Security notes
64
+
65
+ - `readCard` returns only the named fields, every hex field lower-cased
66
+ (bond and persona keys included), bond canonicalised. Names, display
67
+ names and persona labels pass `isGoodName`: 1 to 100 code points, at
68
+ least one visible, no control, surrogate, unassigned or private-use
69
+ character, no separator but an ordinary space and none at the ends, no
70
+ invisible or direction-changing format character, no run of five
71
+ combining marks; the joiners and tag characters emoji need are allowed
72
+ only beside a pictographic character. Empty strings are refused, because
73
+ an empty name or attest would hash the same as none.
74
+ - The wire is decoded as strict UTF-8: a byte sequence that is not UTF-8,
75
+ or a leading byte-order mark, is not a card. Nothing decodes to U+FFFD.
76
+ - Link cards are verified as libsodium and ed25519-dalek's `verify_strict`
77
+ do: canonical encodings only (no ZIP-215), a node id or nonce point of
78
+ small order refused, `S` below the group order, and the cofactorless
79
+ equation `[S]B = R + [k]A`. noble's own `verify` multiplies by the
80
+ cofactor and would accept a node id or nonce carrying torsion that a
81
+ strict verifier refuses, so the check is done by hand (`verifyStrict`).
82
+ - Relay hints and card relays pass `isRelayUrl`: `wss://`, a URL with a
83
+ DNS name or IP literal as host, no credentials, no fragment, no comma, no
84
+ unprintable character, no byte-order mark. Onion hints are a 56-character
85
+ base32 host with a non-zero port. An ephemeral hint (kind 0x04) has a
86
+ compressed-point prefix. Kind 0x02 and unknown kinds come back in `hints`
87
+ exactly as the box wrote them; only `relays` and `onions` are checked
88
+ views. A serial above 2^53 is refused under rule 3, before the signature.
89
+ - `now` must be a finite number of seconds and `highestSerial` an integer
90
+ or absent. Anything else fails closed; it never switches a check off.
91
+ - Hex case is normalised and base64url padding tolerated, so one card has
92
+ several wire forms; so does any JSON re-serialisation. Anything that
93
+ caches or deduplicates on the encoded string must key on the card's
94
+ fields, not its bytes.
95
+ - The size cap applies to the card, not the link it rides on. A contact
96
+ card's `issued` may be up to 300 seconds ahead of `now`, and `expires`
97
+ must be after `issued`.
98
+ - Replay protection for a box's fresh Link cards is rule 8, and rule 8
99
+ needs the highest serial this client accepted for that node id. The
100
+ library pins nothing: persist `link.serial` per node id and pass it to
101
+ `refreshBox`; without it any unexpired old card of the same node is
102
+ accepted.
103
+
104
+ ## What remains
105
+
106
+ In the profile's own words, from its table of what remains: a card is
107
+ trusted on first use. An impostor who hands you a card is an impostor
108
+ you have a contact for; what narrows that is not in this library but in
109
+ how many independent channels confirm the key, shown as a count and never
110
+ as a score, and a bond ceremony spoken live. Whoever holds a card holds
111
+ its bond nonce, a bearer secret for the card's life.
112
+
113
+ ## Licence
114
+
115
+ MIT. ForgeSworn.
package/dist/card.d.ts ADDED
@@ -0,0 +1,128 @@
1
+ import { type LinkCard } from './link-card.js';
2
+ export declare const CARD_DOMAIN = "nostr-contact-card:v1";
3
+ export declare const MAX_CARD_BYTES: number;
4
+ export declare const MAX_AGE_SECONDS: number;
5
+ export declare const MAX_RELAYS = 8;
6
+ export declare const MAX_BOXES = 4;
7
+ /** Longest name, display name or persona label, in code points. */
8
+ export declare const MAX_NAME = 100;
9
+ export declare const MAX_PERSONAS = 16;
10
+ export interface BondHandshake {
11
+ v?: 1;
12
+ pubkey: string;
13
+ displayName?: string;
14
+ nonce: string;
15
+ personas?: {
16
+ pubkey: string;
17
+ label?: string;
18
+ }[];
19
+ }
20
+ export interface Box {
21
+ /** The box's own key, x-only hex. */
22
+ p: string;
23
+ /** The box's binding event id, where the box publishes one. */
24
+ claim: string;
25
+ /** FSL-CARD-1, base64url without padding, carried opaquely. */
26
+ card: string;
27
+ carriers?: string[];
28
+ }
29
+ export interface UnsignedCard {
30
+ v: 1;
31
+ p: string;
32
+ rz: string;
33
+ name?: string;
34
+ issued: number;
35
+ expires: number;
36
+ relays: string[];
37
+ boxes: Box[];
38
+ eph: string;
39
+ attest?: string;
40
+ bond?: BondHandshake;
41
+ }
42
+ export interface Card extends UnsignedCard {
43
+ sig: string;
44
+ }
45
+ /**
46
+ * A name, display name or persona label a person will see: 1 to 100 code
47
+ * points, at least one visible one, no control, surrogate, unassigned or
48
+ * private-use character, no separator other than an ordinary space and none
49
+ * of those at the ends, no invisible or direction-changing format character,
50
+ * no run of five combining marks. The format characters emoji sequences use
51
+ * (the zero-width joiner and the tag characters) are allowed only beside a
52
+ * pictographic character, so a family or a flag reads and a hidden joiner
53
+ * does not.
54
+ */
55
+ export declare function isGoodName(s: unknown): s is string;
56
+ /**
57
+ * A bond handshake with only the fields the draft names, each checked, in
58
+ * canonical key order. Throws with a `handshake:` message on anything else.
59
+ */
60
+ export declare function cleanBond(p: unknown): BondHandshake;
61
+ /** The canonical bytes of a bond handshake: fixed key order, no whitespace, absent keys omitted. */
62
+ export declare function handshakeBytes(p: BondHandshake): Uint8Array;
63
+ /**
64
+ * §2 of the draft: the digest the card's signature covers. Fields are
65
+ * colon-joined; every field that could carry a separator is constrained by
66
+ * `readCard` step 2 (relays no comma, box cards base64url, carriers a
67
+ * short token alphabet and never an empty list, attest no colon, and no
68
+ * empty name or attest, which would hash the same as absence) so no two
69
+ * well-formed cards share a digest.
70
+ */
71
+ export declare function cardDigest(c: UnsignedCard): Uint8Array;
72
+ export interface BuildOptions {
73
+ identityPrivateKey: Uint8Array;
74
+ /** The rendezvous public key, a child of the root, x-only hex. */
75
+ rz: string;
76
+ /** A fresh ephemeral secret for this card; its public half goes on the card. */
77
+ ephemeralPrivateKey: Uint8Array;
78
+ name?: string;
79
+ relays?: string[];
80
+ boxes?: Box[];
81
+ attest?: string;
82
+ bond?: Omit<BondHandshake, 'v'>;
83
+ /** Card lifetime in seconds, at most 30 days. */
84
+ ttlSeconds?: number;
85
+ now?: () => number;
86
+ }
87
+ /** Build and sign a card. Throws when it would not fit or would not verify. */
88
+ export declare function buildCard(o: BuildOptions): Card;
89
+ export declare function encodeCard(card: Card): string;
90
+ /** A link a person can send: the card rides after `#`, so no server sees it. */
91
+ export declare function cardLink(base: string, card: Card): string;
92
+ export interface ReadOk {
93
+ ok: true;
94
+ /** Only the fields the draft names, each checked; nothing else from the wire survives. */
95
+ card: Card;
96
+ /** Each box with its verified Link card; the node id is the one `p` endorsed. */
97
+ boxes: {
98
+ box: Box;
99
+ link: LinkCard;
100
+ }[];
101
+ }
102
+ export type ReadResult = ReadOk | {
103
+ ok: false;
104
+ step: 1 | 2 | 3 | 4 | 5;
105
+ reason: string;
106
+ };
107
+ /**
108
+ * §3 steps 1 to 5. The result names the step that failed, for the words a
109
+ * client shows. The card returned is rebuilt from the fields the draft
110
+ * names: an extra key on the wire, `__proto__` included, never reaches the
111
+ * caller under a verified signature.
112
+ */
113
+ export declare function readCard(encoded: string, now: number): ReadResult;
114
+ /**
115
+ * §3 step 6: accept a fresh Link card from a box only under the node id the
116
+ * person endorsed. Pass the highest serial previously accepted for that node
117
+ * id, persisted by the caller; without it any unexpired old card of the same
118
+ * node replays, which is rule 8's job to stop and this function cannot do
119
+ * alone.
120
+ */
121
+ export declare function refreshBox(pinnedNodeId: string | Uint8Array, freshCard: Uint8Array, now: number, highestSerial?: number): {
122
+ ok: true;
123
+ link: LinkCard;
124
+ } | {
125
+ ok: false;
126
+ reason: string;
127
+ };
128
+ //# sourceMappingURL=card.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"card.d.ts","sourceRoot":"","sources":["../src/card.ts"],"names":[],"mappings":"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"}
package/dist/card.js ADDED
@@ -0,0 +1,293 @@
1
+ import { schnorr } from '@noble/curves/secp256k1.js';
2
+ import { base64urlnopad } from '@scure/base';
3
+ import { sha256 } from '@noble/hashes/sha2.js';
4
+ import { bytesToHex, hexToBytes, utf8ToBytes } from '@noble/hashes/utils.js';
5
+ import { verifyLinkCard, isRelayUrl } from './link-card.js';
6
+ export const CARD_DOMAIN = 'nostr-contact-card:v1';
7
+ export const MAX_CARD_BYTES = 16 * 1024;
8
+ export const MAX_AGE_SECONDS = 30 * 24 * 3600;
9
+ export const MAX_RELAYS = 8;
10
+ export const MAX_BOXES = 4;
11
+ /** Longest name, display name or persona label, in code points. */
12
+ export const MAX_NAME = 100;
13
+ export const MAX_PERSONAS = 16;
14
+ const HEX64 = /^[0-9a-f]{64}$/, HEX128 = /^[0-9a-f]{128}$/, HEX32 = /^[0-9a-f]{32}$/;
15
+ const B64URL = /^[A-Za-z0-9_-]+$/;
16
+ const CARRIER = /^[A-Za-z0-9._-]{1,32}$/;
17
+ /** What no text field may carry: control, surrogate, unassigned, private-use, line and paragraph separators. */
18
+ const UNPRINTABLE = /[\p{Cc}\p{Cs}\p{Cn}\p{Co}\p{Zl}\p{Zp}]/u;
19
+ /** Invisible and direction-changing format characters that spoof a name; the format characters emoji need are handled apart. */
20
+ const INVISIBLE = /[\u200B\u200C\u200E\u200F\u202A-\u202E\u2060-\u2064\u2066-\u2069\uFEFF\u00AD\u061C\u180E]/u;
21
+ const VISIBLE = /[\p{L}\p{N}\p{S}\p{P}]/u;
22
+ const MARK_RUN = /\p{M}{5}/u;
23
+ const PICTOGRAPHIC = /\p{Extended_Pictographic}/u;
24
+ // base64url without padding, as the draft specifies; @scure/base is the
25
+ // same family as the curves and hashes and runs in a browser.
26
+ const b64url = {
27
+ encode: (b) => base64urlnopad.encode(b),
28
+ decode: (s) => base64urlnopad.decode(s.replace(/=+$/, '')),
29
+ };
30
+ const sha256hex = (b) => bytesToHex(sha256(b));
31
+ const utf8Strict = new TextDecoder('utf-8', { fatal: true, ignoreBOM: true });
32
+ /**
33
+ * A name, display name or persona label a person will see: 1 to 100 code
34
+ * points, at least one visible one, no control, surrogate, unassigned or
35
+ * private-use character, no separator other than an ordinary space and none
36
+ * of those at the ends, no invisible or direction-changing format character,
37
+ * no run of five combining marks. The format characters emoji sequences use
38
+ * (the zero-width joiner and the tag characters) are allowed only beside a
39
+ * pictographic character, so a family or a flag reads and a hidden joiner
40
+ * does not.
41
+ */
42
+ export function isGoodName(s) {
43
+ if (typeof s !== 'string')
44
+ return false;
45
+ const cps = [...s];
46
+ if (cps.length === 0 || cps.length > MAX_NAME)
47
+ return false;
48
+ if (UNPRINTABLE.test(s) || INVISIBLE.test(s) || MARK_RUN.test(s) || !VISIBLE.test(s))
49
+ return false;
50
+ if (s.startsWith(' ') || s.endsWith(' '))
51
+ return false;
52
+ for (let i = 0; i < cps.length; i++) {
53
+ const c = cps[i];
54
+ const code = c.codePointAt(0);
55
+ if (/\p{Zs}/u.test(c) && c !== ' ')
56
+ return false;
57
+ if (/\p{Cf}/u.test(c)) {
58
+ const near = (cps[i - 1] ?? '') + (cps[i + 1] ?? '');
59
+ if (code === 0x200d && PICTOGRAPHIC.test(near))
60
+ continue;
61
+ if (code >= 0xe0020 && code <= 0xe007f && PICTOGRAPHIC.test(cps.slice(Math.max(0, i - 8), i).join('')))
62
+ continue;
63
+ return false;
64
+ }
65
+ }
66
+ return true;
67
+ }
68
+ const goodText = isGoodName;
69
+ /**
70
+ * A bond handshake with only the fields the draft names, each checked, in
71
+ * canonical key order. Throws with a `handshake:` message on anything else.
72
+ */
73
+ export function cleanBond(p) {
74
+ if (!p || typeof p !== 'object' || Array.isArray(p))
75
+ throw new Error('handshake: not an object');
76
+ const h = p;
77
+ if (h.v !== undefined && h.v !== 1)
78
+ throw new Error('handshake: v must be 1');
79
+ const pubkey = typeof h.pubkey === 'string' ? h.pubkey.toLowerCase() : '';
80
+ const nonce = typeof h.nonce === 'string' ? h.nonce.toLowerCase() : '';
81
+ if (!HEX64.test(pubkey))
82
+ throw new Error('handshake: pubkey must be 64 hex chars');
83
+ if (!HEX32.test(nonce))
84
+ throw new Error('handshake: nonce must be 32 hex chars');
85
+ if (h.displayName !== undefined && !goodText(h.displayName))
86
+ throw new Error('handshake: displayName');
87
+ const out = { v: 1, pubkey, nonce };
88
+ if (h.displayName !== undefined)
89
+ out.displayName = h.displayName;
90
+ if (h.personas !== undefined) {
91
+ if (!Array.isArray(h.personas) || h.personas.length > MAX_PERSONAS)
92
+ throw new Error('handshake: personas');
93
+ out.personas = h.personas.map((x) => {
94
+ const pk = x && typeof x === 'object' && typeof x.pubkey === 'string' ? x.pubkey.toLowerCase() : '';
95
+ if (!HEX64.test(pk))
96
+ throw new Error('handshake: persona pubkey');
97
+ if (x.label !== undefined && !goodText(x.label))
98
+ throw new Error('handshake: persona label');
99
+ return x.label !== undefined ? { pubkey: pk, label: x.label } : { pubkey: pk };
100
+ });
101
+ }
102
+ return out;
103
+ }
104
+ /** The canonical bytes of a bond handshake: fixed key order, no whitespace, absent keys omitted. */
105
+ export function handshakeBytes(p) {
106
+ const c = cleanBond(p);
107
+ const o = { v: 1, pubkey: c.pubkey };
108
+ if (c.displayName !== undefined)
109
+ o.displayName = c.displayName;
110
+ o.nonce = c.nonce;
111
+ if (c.personas !== undefined)
112
+ o.personas = c.personas;
113
+ return utf8ToBytes(JSON.stringify(o));
114
+ }
115
+ /**
116
+ * §2 of the draft: the digest the card's signature covers. Fields are
117
+ * colon-joined; every field that could carry a separator is constrained by
118
+ * `readCard` step 2 (relays no comma, box cards base64url, carriers a
119
+ * short token alphabet and never an empty list, attest no colon, and no
120
+ * empty name or attest, which would hash the same as absence) so no two
121
+ * well-formed cards share a digest.
122
+ */
123
+ export function cardDigest(c) {
124
+ const box = (b) => `${b.p}/${b.claim}/${b.card}/${(b.carriers ?? []).join('+')}`;
125
+ const s = [CARD_DOMAIN, c.p, c.rz, String(c.issued), String(c.expires), c.eph,
126
+ c.relays.join(','), c.boxes.map(box).join(','), c.attest ?? '',
127
+ c.bond ? sha256hex(handshakeBytes(c.bond)) : '', sha256hex(utf8ToBytes(c.name ?? ''))].join(':');
128
+ return sha256(utf8ToBytes(s));
129
+ }
130
+ /** Build and sign a card. Throws when it would not fit or would not verify. */
131
+ export function buildCard(o) {
132
+ const now = (o.now ?? (() => Math.floor(Date.now() / 1000)))();
133
+ const ttl = o.ttlSeconds ?? MAX_AGE_SECONDS;
134
+ if (ttl <= 0 || ttl > MAX_AGE_SECONDS)
135
+ throw new Error('ttl must be within 30 days');
136
+ const unsigned = {
137
+ v: 1,
138
+ p: bytesToHex(schnorr.getPublicKey(o.identityPrivateKey)),
139
+ rz: o.rz,
140
+ ...(o.name !== undefined ? { name: o.name } : {}),
141
+ issued: now,
142
+ expires: now + ttl,
143
+ relays: o.relays ?? [],
144
+ boxes: o.boxes ?? [],
145
+ eph: bytesToHex(schnorr.getPublicKey(o.ephemeralPrivateKey)),
146
+ ...(o.attest !== undefined ? { attest: o.attest } : {}),
147
+ ...(o.bond !== undefined ? { bond: cleanBond({ v: 1, ...o.bond }) } : {}),
148
+ };
149
+ const card = { ...unsigned, sig: bytesToHex(schnorr.sign(cardDigest(unsigned), o.identityPrivateKey)) };
150
+ const encoded = encodeCard(card);
151
+ if (encoded.length > MAX_CARD_BYTES)
152
+ throw new Error('card exceeds 16 KiB; drop a box');
153
+ const r = readCard(encoded, now);
154
+ if (!r.ok)
155
+ throw new Error(`built a card that does not read: step ${r.step} ${r.reason}`);
156
+ return card;
157
+ }
158
+ export function encodeCard(card) {
159
+ return b64url.encode(utf8ToBytes(JSON.stringify(card)));
160
+ }
161
+ /** A link a person can send: the card rides after `#`, so no server sees it. */
162
+ export function cardLink(base, card) {
163
+ return `${base.replace(/#.*$/, '')}#${encodeCard(card)}`;
164
+ }
165
+ /**
166
+ * §3 steps 1 to 5. The result names the step that failed, for the words a
167
+ * client shows. The card returned is rebuilt from the fields the draft
168
+ * names: an extra key on the wire, `__proto__` included, never reaches the
169
+ * caller under a verified signature.
170
+ */
171
+ export function readCard(encoded, now) {
172
+ if (typeof encoded !== 'string')
173
+ return { ok: false, step: 1, reason: 'size' };
174
+ const body = encoded.slice(encoded.lastIndexOf('#') + 1);
175
+ if (body.length === 0 || body.length > MAX_CARD_BYTES)
176
+ return { ok: false, step: 1, reason: 'size' };
177
+ if (!Number.isFinite(now))
178
+ return { ok: false, step: 3, reason: 'clock' };
179
+ let c;
180
+ // Strict UTF-8: a byte sequence that is not UTF-8 is not a card, not a card with U+FFFD in it.
181
+ try {
182
+ c = JSON.parse(utf8Strict.decode(b64url.decode(body)));
183
+ }
184
+ catch {
185
+ return { ok: false, step: 1, reason: 'decode' };
186
+ }
187
+ if (!c || typeof c !== 'object' || Array.isArray(c) || c.v !== 1)
188
+ return { ok: false, step: 1, reason: 'version' };
189
+ const hex = { p: '', rz: '', eph: '' };
190
+ for (const f of ['p', 'rz', 'eph']) {
191
+ if (typeof c[f] !== 'string')
192
+ return { ok: false, step: 2, reason: f };
193
+ hex[f] = c[f].toLowerCase();
194
+ if (!HEX64.test(hex[f]))
195
+ return { ok: false, step: 2, reason: f };
196
+ }
197
+ if (typeof c.sig !== 'string')
198
+ return { ok: false, step: 2, reason: 'sig' };
199
+ const sig = c.sig.toLowerCase();
200
+ if (!HEX128.test(sig))
201
+ return { ok: false, step: 2, reason: 'sig' };
202
+ if (c.name !== undefined && !goodText(c.name))
203
+ return { ok: false, step: 2, reason: 'name' };
204
+ if (!Array.isArray(c.relays) || c.relays.length > MAX_RELAYS || c.relays.some((r) => !isRelayUrl(r)))
205
+ return { ok: false, step: 2, reason: 'relays' };
206
+ if (!Array.isArray(c.boxes) || c.boxes.length > MAX_BOXES)
207
+ return { ok: false, step: 2, reason: 'boxes' };
208
+ const boxesClean = [];
209
+ for (const b of c.boxes) {
210
+ if (!b || typeof b !== 'object' || Array.isArray(b))
211
+ return { ok: false, step: 2, reason: 'box' };
212
+ const p = typeof b.p === 'string' ? b.p.toLowerCase() : '';
213
+ const claim = typeof b.claim === 'string' ? b.claim.toLowerCase() : '';
214
+ if (!HEX64.test(p))
215
+ return { ok: false, step: 2, reason: 'box p' };
216
+ if (!HEX64.test(claim))
217
+ return { ok: false, step: 2, reason: 'box claim' };
218
+ if (typeof b.card !== 'string' || !B64URL.test(b.card))
219
+ return { ok: false, step: 2, reason: 'box card' };
220
+ if (b.carriers !== undefined && (!Array.isArray(b.carriers) || b.carriers.length === 0 || b.carriers.length > 8 || b.carriers.some((x) => typeof x !== 'string' || !CARRIER.test(x))))
221
+ return { ok: false, step: 2, reason: 'box carriers' };
222
+ boxesClean.push({ p, claim, card: b.card, ...(b.carriers !== undefined ? { carriers: [...b.carriers] } : {}) });
223
+ }
224
+ if (c.attest !== undefined && (typeof c.attest !== 'string' || c.attest.length === 0 || c.attest.includes(':') || UNPRINTABLE.test(c.attest) || INVISIBLE.test(c.attest) || /\p{Z}/u.test(c.attest) || c.attest.length > 512))
225
+ return { ok: false, step: 2, reason: 'attest' };
226
+ let bond;
227
+ if (c.bond !== undefined) {
228
+ try {
229
+ bond = cleanBond(c.bond);
230
+ }
231
+ catch {
232
+ return { ok: false, step: 2, reason: 'bond' };
233
+ }
234
+ }
235
+ if (!Number.isSafeInteger(c.issued) || !Number.isSafeInteger(c.expires))
236
+ return { ok: false, step: 3, reason: 'times' };
237
+ if (c.expires <= now)
238
+ return { ok: false, step: 3, reason: 'expired' };
239
+ if (c.expires <= c.issued || c.expires - c.issued > MAX_AGE_SECONDS)
240
+ return { ok: false, step: 3, reason: 'expiry window' };
241
+ if (c.issued > now + 300)
242
+ return { ok: false, step: 3, reason: 'issued in the future' };
243
+ const unsigned = {
244
+ v: 1,
245
+ p: hex.p,
246
+ rz: hex.rz,
247
+ ...(c.name !== undefined ? { name: c.name } : {}),
248
+ issued: c.issued,
249
+ expires: c.expires,
250
+ relays: [...c.relays],
251
+ boxes: boxesClean,
252
+ eph: hex.eph,
253
+ ...(c.attest !== undefined ? { attest: c.attest } : {}),
254
+ ...(bond ? { bond } : {}),
255
+ };
256
+ if (!schnorr.verify(hexToBytes(sig), cardDigest(unsigned), hexToBytes(unsigned.p)))
257
+ return { ok: false, step: 4, reason: 'signature' };
258
+ const card = { ...unsigned, sig };
259
+ const boxes = [];
260
+ for (const b of card.boxes) {
261
+ let bytes;
262
+ try {
263
+ bytes = b64url.decode(b.card);
264
+ }
265
+ catch {
266
+ return { ok: false, step: 5, reason: 'link: decode' };
267
+ }
268
+ const v = verifyLinkCard(bytes, now);
269
+ if (!v.ok)
270
+ return { ok: false, step: 5, reason: `link: ${v.reason}` };
271
+ boxes.push({ box: b, link: v.card });
272
+ }
273
+ return { ok: true, card, boxes };
274
+ }
275
+ /**
276
+ * §3 step 6: accept a fresh Link card from a box only under the node id the
277
+ * person endorsed. Pass the highest serial previously accepted for that node
278
+ * id, persisted by the caller; without it any unexpired old card of the same
279
+ * node replays, which is rule 8's job to stop and this function cannot do
280
+ * alone.
281
+ */
282
+ export function refreshBox(pinnedNodeId, freshCard, now, highestSerial) {
283
+ const pin = pinnedNodeId instanceof Uint8Array ? bytesToHex(pinnedNodeId) : typeof pinnedNodeId === 'string' ? pinnedNodeId.toLowerCase() : '';
284
+ if (!HEX64.test(pin))
285
+ return { ok: false, reason: 'pinned node id is not 32 bytes of hex' };
286
+ const v = verifyLinkCard(freshCard, now, highestSerial);
287
+ if (!v.ok)
288
+ return { ok: false, reason: v.reason };
289
+ if (v.card.nodeId !== pin)
290
+ return { ok: false, reason: 'node id is not the endorsed one' };
291
+ return { ok: true, link: v.card };
292
+ }
293
+ //# sourceMappingURL=card.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"card.js","sourceRoot":"","sources":["../src/card.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ export { CARD_DOMAIN, MAX_CARD_BYTES, MAX_AGE_SECONDS, MAX_RELAYS, MAX_BOXES, MAX_NAME, MAX_PERSONAS, isGoodName, cleanBond, handshakeBytes, cardDigest, buildCard, encodeCard, cardLink, readCard, refreshBox } from './card.js';
2
+ export type { BondHandshake, Box, UnsignedCard, Card, BuildOptions, ReadOk, ReadResult } from './card.js';
3
+ export { verifyLinkCard, verifyStrict, isRelayUrl, buildLinkCard, LINK_CARD_MAX, LINK_CARD_MIN, LINK_CARD_MAX_AGE } from './link-card.js';
4
+ export type { LinkCard, LinkHint, LinkVerdict } from './link-card.js';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,eAAe,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAE,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,cAAc,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,WAAW,CAAA;AACjO,YAAY,EAAE,aAAa,EAAE,GAAG,EAAE,YAAY,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,WAAW,CAAA;AACzG,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,UAAU,EAAE,aAAa,EAAE,aAAa,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAA;AACzI,YAAY,EAAE,QAAQ,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA"}
package/dist/index.js ADDED
@@ -0,0 +1,3 @@
1
+ export { CARD_DOMAIN, MAX_CARD_BYTES, MAX_AGE_SECONDS, MAX_RELAYS, MAX_BOXES, MAX_NAME, MAX_PERSONAS, isGoodName, cleanBond, handshakeBytes, cardDigest, buildCard, encodeCard, cardLink, readCard, refreshBox } from './card.js';
2
+ export { verifyLinkCard, verifyStrict, isRelayUrl, buildLinkCard, LINK_CARD_MAX, LINK_CARD_MIN, LINK_CARD_MAX_AGE } from './link-card.js';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,eAAe,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAE,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,cAAc,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,WAAW,CAAA;AAEjO,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,UAAU,EAAE,aAAa,EAAE,aAAa,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAA"}