@kynesyslabs/demosdk 4.0.9 → 4.0.11
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/build/abstraction/Identities.d.ts +70 -0
- package/build/abstraction/Identities.js +160 -0
- package/build/abstraction/Identities.js.map +1 -1
- package/build/identity/cci/claim.d.ts +47 -0
- package/build/identity/cci/claim.js +86 -0
- package/build/identity/cci/claim.js.map +1 -0
- package/build/identity/cci/index.d.ts +11 -0
- package/build/identity/cci/index.js +11 -0
- package/build/identity/cci/index.js.map +1 -0
- package/build/identity/cci/signing.d.ts +44 -0
- package/build/identity/cci/signing.js +83 -0
- package/build/identity/cci/signing.js.map +1 -0
- package/build/identity/cci/types.d.ts +14 -0
- package/build/identity/cci/types.js +10 -0
- package/build/identity/cci/types.js.map +1 -0
- package/build/identity/index.d.ts +2 -0
- package/build/identity/index.js +3 -0
- package/build/identity/index.js.map +1 -0
- package/build/l2ps/anchor/anchor.d.ts +92 -0
- package/build/l2ps/anchor/anchor.js +186 -0
- package/build/l2ps/anchor/anchor.js.map +1 -0
- package/build/l2ps/anchor/index.d.ts +10 -0
- package/build/l2ps/anchor/index.js +10 -0
- package/build/l2ps/anchor/index.js.map +1 -0
- package/build/l2ps/anchor/types.d.ts +36 -0
- package/build/l2ps/anchor/types.js +2 -0
- package/build/l2ps/anchor/types.js.map +1 -0
- package/build/l2ps/binding/binding.d.ts +72 -0
- package/build/l2ps/binding/binding.js +160 -0
- package/build/l2ps/binding/binding.js.map +1 -0
- package/build/l2ps/binding/canonical.d.ts +19 -0
- package/build/l2ps/binding/canonical.js +30 -0
- package/build/l2ps/binding/canonical.js.map +1 -0
- package/build/l2ps/binding/index.d.ts +10 -0
- package/build/l2ps/binding/index.js +10 -0
- package/build/l2ps/binding/index.js.map +1 -0
- package/build/l2ps/binding/types.d.ts +20 -0
- package/build/l2ps/binding/types.js +2 -0
- package/build/l2ps/binding/types.js.map +1 -0
- package/build/l2ps/channel/canonical.d.ts +24 -0
- package/build/l2ps/channel/canonical.js +44 -0
- package/build/l2ps/channel/canonical.js.map +1 -0
- package/build/l2ps/channel/channelIdRegistry.d.ts +19 -0
- package/build/l2ps/channel/channelIdRegistry.js +16 -0
- package/build/l2ps/channel/channelIdRegistry.js.map +1 -0
- package/build/l2ps/channel/envelope.d.ts +26 -0
- package/build/l2ps/channel/envelope.js +62 -0
- package/build/l2ps/channel/envelope.js.map +1 -0
- package/build/l2ps/channel/index.d.ts +14 -0
- package/build/l2ps/channel/index.js +14 -0
- package/build/l2ps/channel/index.js.map +1 -0
- package/build/l2ps/channel/session.d.ts +66 -0
- package/build/l2ps/channel/session.js +101 -0
- package/build/l2ps/channel/session.js.map +1 -0
- package/build/l2ps/channel/transcript.d.ts +48 -0
- package/build/l2ps/channel/transcript.js +120 -0
- package/build/l2ps/channel/transcript.js.map +1 -0
- package/build/l2ps/channel/types.d.ts +55 -0
- package/build/l2ps/channel/types.js +2 -0
- package/build/l2ps/channel/types.js.map +1 -0
- package/build/l2ps/index.d.ts +5 -2
- package/build/l2ps/index.js +3 -0
- package/build/l2ps/index.js.map +1 -1
- package/build/l2ps/l2ps.d.ts +32 -0
- package/build/l2ps/l2ps.js +60 -0
- package/build/l2ps/l2ps.js.map +1 -1
- package/build/l2ps/utils/hex.d.ts +26 -0
- package/build/l2ps/utils/hex.js +45 -0
- package/build/l2ps/utils/hex.js.map +1 -0
- package/build/types/abstraction/index.d.ts +17 -2
- package/build/websdk/Web2Calls.js +2 -0
- package/build/websdk/Web2Calls.js.map +1 -1
- package/build/websdk/demosclass.d.ts +15 -0
- package/build/websdk/demosclass.js +25 -0
- package/build/websdk/demosclass.js.map +1 -1
- package/package.json +4 -2
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { isSenderInMembers, signChannelMessage, verifyChannelMessage, } from "./envelope.js";
|
|
2
|
+
/**
|
|
3
|
+
* Per-channel session — owns the monotonic sequence counter and applies
|
|
4
|
+
* the four invariants from §8.3.3 / §8.12 on every message:
|
|
5
|
+
*
|
|
6
|
+
* 1. signature verifies under sender's CCI key
|
|
7
|
+
* 2. sender ∈ members (CH-1)
|
|
8
|
+
* 3. sequence is monotonic per channel (anti-replay)
|
|
9
|
+
* 4. channelId matches the session's channelId
|
|
10
|
+
*
|
|
11
|
+
* A single counter is shared across senders, as the brief specifies
|
|
12
|
+
* (`sequence: number // monotonic per channel, starts at 1`). Outgoing
|
|
13
|
+
* messages get `current + 1`; incoming messages must use a sequence
|
|
14
|
+
* strictly greater than every value already seen.
|
|
15
|
+
*/
|
|
16
|
+
export class ChannelSession {
|
|
17
|
+
constructor(opts) {
|
|
18
|
+
this.opened = false;
|
|
19
|
+
this.highestSeen = 0;
|
|
20
|
+
this.transcript = [];
|
|
21
|
+
if (!opts.channelId)
|
|
22
|
+
throw new Error("ChannelSession: channelId required");
|
|
23
|
+
if (!opts.members?.length)
|
|
24
|
+
throw new Error("ChannelSession: members required");
|
|
25
|
+
if (!opts.members.includes(opts.me))
|
|
26
|
+
throw new Error(`ChannelSession: me (${opts.me}) is not in members`);
|
|
27
|
+
this.channelId = opts.channelId;
|
|
28
|
+
this.members = [...opts.members];
|
|
29
|
+
this.me = opts.me;
|
|
30
|
+
this.demos = opts.demos;
|
|
31
|
+
this.registry = opts.channelIdRegistry;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Register the channelId (CH-6) and prepare for messaging. Idempotent
|
|
35
|
+
* within a session — calling twice throws via the registry.
|
|
36
|
+
*/
|
|
37
|
+
async open() {
|
|
38
|
+
if (this.opened)
|
|
39
|
+
throw new Error("ChannelSession: already opened");
|
|
40
|
+
if (this.registry)
|
|
41
|
+
await this.registry.register(this.channelId);
|
|
42
|
+
this.opened = true;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Build, sign, append-to-local-transcript, and return the next
|
|
46
|
+
* outgoing `ChannelMessage`. Sequence is `highestSeen + 1` so it is
|
|
47
|
+
* monotonic across both directions.
|
|
48
|
+
*/
|
|
49
|
+
async sendOutgoing(opts) {
|
|
50
|
+
this.assertOpened();
|
|
51
|
+
// Reserve the sequence slot SYNCHRONOUSLY before any await — two
|
|
52
|
+
// concurrent sendOutgoing() calls would otherwise read the same
|
|
53
|
+
// `highestSeen`, sign two messages with identical sequence
|
|
54
|
+
// numbers, and silently violate the anti-replay invariant on the
|
|
55
|
+
// receiver side.
|
|
56
|
+
const sequence = ++this.highestSeen;
|
|
57
|
+
const unsigned = {
|
|
58
|
+
channelId: this.channelId,
|
|
59
|
+
sequence,
|
|
60
|
+
sender: this.me,
|
|
61
|
+
sentAt: opts.sentAt ?? Date.now(),
|
|
62
|
+
type: opts.type,
|
|
63
|
+
body: opts.body,
|
|
64
|
+
...(opts.repliesTo !== undefined && {
|
|
65
|
+
refs: { repliesTo: opts.repliesTo },
|
|
66
|
+
}),
|
|
67
|
+
};
|
|
68
|
+
const signed = await signChannelMessage(unsigned, this.demos);
|
|
69
|
+
this.transcript.push(signed);
|
|
70
|
+
return signed;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Validate an incoming `ChannelMessage`. Throws with a precise reason
|
|
74
|
+
* on any failure — caller should treat throw as channel-fatal per
|
|
75
|
+
* §8.12 (a single tampered message invalidates the session's record).
|
|
76
|
+
*/
|
|
77
|
+
async receiveIncoming(msg) {
|
|
78
|
+
this.assertOpened();
|
|
79
|
+
if (msg.channelId !== this.channelId)
|
|
80
|
+
throw new Error(`ChannelSession: channelId mismatch (expected ${this.channelId}, got ${msg.channelId})`);
|
|
81
|
+
if (!isSenderInMembers(msg, this.members))
|
|
82
|
+
throw new Error(`ChannelSession: sender "${msg.sender}" not in members (CH-1)`);
|
|
83
|
+
if (!Number.isInteger(msg.sequence) || msg.sequence < 1)
|
|
84
|
+
throw new Error(`ChannelSession: invalid sequence ${msg.sequence}`);
|
|
85
|
+
if (msg.sequence <= this.highestSeen)
|
|
86
|
+
throw new Error(`ChannelSession: non-monotonic sequence ${msg.sequence} (highest seen ${this.highestSeen})`);
|
|
87
|
+
if (!verifyChannelMessage(msg))
|
|
88
|
+
throw new Error("ChannelSession: signature verification failed");
|
|
89
|
+
this.highestSeen = msg.sequence;
|
|
90
|
+
this.transcript.push(msg);
|
|
91
|
+
}
|
|
92
|
+
/** Read-only snapshot of all messages this session has signed or accepted. */
|
|
93
|
+
messages() {
|
|
94
|
+
return this.transcript;
|
|
95
|
+
}
|
|
96
|
+
assertOpened() {
|
|
97
|
+
if (!this.opened)
|
|
98
|
+
throw new Error("ChannelSession: call open() before sending or receiving");
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../../../src/l2ps/channel/session.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { type ClaimReference } from "../../identity/cci";
|
|
2
|
+
import { Demos } from "../../websdk/demosclass";
|
|
3
|
+
import type { ChannelMessage, ChannelTranscript, TranscriptSignature, UnsignedChannelTranscript } from "./types";
|
|
4
|
+
/**
|
|
5
|
+
* Build the unsigned transcript shell. Messages must already be in
|
|
6
|
+
* sequence order — typically `session.messages()`.
|
|
7
|
+
*/
|
|
8
|
+
export declare function buildUnsignedTranscript(opts: {
|
|
9
|
+
channelId: string;
|
|
10
|
+
members: ClaimReference[];
|
|
11
|
+
messages: ReadonlyArray<ChannelMessage>;
|
|
12
|
+
generatedAt?: number;
|
|
13
|
+
}): UnsignedChannelTranscript;
|
|
14
|
+
/**
|
|
15
|
+
* Produce one party's `TranscriptSignature` over the unsigned transcript.
|
|
16
|
+
* Domain-separated under `dacs-transcript:v1:` — cannot be confused with
|
|
17
|
+
* a channel-message or binding signature.
|
|
18
|
+
*/
|
|
19
|
+
export declare function signTranscript(unsigned: UnsignedChannelTranscript, signer: ClaimReference, demos: Demos): Promise<TranscriptSignature>;
|
|
20
|
+
/**
|
|
21
|
+
* Convenience: assemble the full transcript with one or more party
|
|
22
|
+
* signatures. Pass signers in the order their signatures should appear.
|
|
23
|
+
*/
|
|
24
|
+
export declare function exportTranscript(opts: {
|
|
25
|
+
channelId: string;
|
|
26
|
+
members: ClaimReference[];
|
|
27
|
+
messages: ReadonlyArray<ChannelMessage>;
|
|
28
|
+
signers: Array<{
|
|
29
|
+
claim: ClaimReference;
|
|
30
|
+
demos: Demos;
|
|
31
|
+
}>;
|
|
32
|
+
generatedAt?: number;
|
|
33
|
+
}): Promise<ChannelTranscript>;
|
|
34
|
+
export interface TranscriptVerificationResult {
|
|
35
|
+
ok: boolean;
|
|
36
|
+
errors: string[];
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Verify every claim about a transcript a non-member can check given only
|
|
40
|
+
* the public keys: (a) each `TranscriptSignature` is valid, (b) each
|
|
41
|
+
* `ChannelMessage` carries a valid signature, (c) every message's sender
|
|
42
|
+
* is in `members`, (d) sequences are strictly monotonic per channel,
|
|
43
|
+
* (e) every message's `channelId` matches the transcript.
|
|
44
|
+
*
|
|
45
|
+
* Returns a list of errors rather than throwing so auditors can collect
|
|
46
|
+
* every failure in one pass.
|
|
47
|
+
*/
|
|
48
|
+
export declare function verifyTranscript(t: ChannelTranscript): TranscriptVerificationResult;
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { isDemosClaim, signWithPrimaryClaim, verifyPrimaryClaimSignature, } from "../../identity/cci/index.js";
|
|
2
|
+
import { signatureFromHex, signatureToHex, stripTranscriptSignatures, transcriptSigningBytes, } from "./canonical.js";
|
|
3
|
+
import { isSenderInMembers, verifyChannelMessage } from "./envelope.js";
|
|
4
|
+
/**
|
|
5
|
+
* Build the unsigned transcript shell. Messages must already be in
|
|
6
|
+
* sequence order — typically `session.messages()`.
|
|
7
|
+
*/
|
|
8
|
+
export function buildUnsignedTranscript(opts) {
|
|
9
|
+
return {
|
|
10
|
+
transcriptVersion: "1",
|
|
11
|
+
channelId: opts.channelId,
|
|
12
|
+
members: [...opts.members],
|
|
13
|
+
messages: [...opts.messages],
|
|
14
|
+
generatedAt: opts.generatedAt ?? Date.now(),
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Produce one party's `TranscriptSignature` over the unsigned transcript.
|
|
19
|
+
* Domain-separated under `dacs-transcript:v1:` — cannot be confused with
|
|
20
|
+
* a channel-message or binding signature.
|
|
21
|
+
*/
|
|
22
|
+
export async function signTranscript(unsigned, signer, demos) {
|
|
23
|
+
if (!isDemosClaim(signer))
|
|
24
|
+
throw new Error(`signTranscript: signer must be a demos: ClaimReference, got "${signer}"`);
|
|
25
|
+
const payload = transcriptSigningBytes(unsigned);
|
|
26
|
+
const sigBytes = await signWithPrimaryClaim(signer, payload, demos);
|
|
27
|
+
return {
|
|
28
|
+
sigVersion: "1",
|
|
29
|
+
signer,
|
|
30
|
+
signature: signatureToHex(sigBytes),
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Convenience: assemble the full transcript with one or more party
|
|
35
|
+
* signatures. Pass signers in the order their signatures should appear.
|
|
36
|
+
*/
|
|
37
|
+
export async function exportTranscript(opts) {
|
|
38
|
+
const unsigned = buildUnsignedTranscript(opts);
|
|
39
|
+
const signatures = [];
|
|
40
|
+
for (const s of opts.signers) {
|
|
41
|
+
signatures.push(await signTranscript(unsigned, s.claim, s.demos));
|
|
42
|
+
}
|
|
43
|
+
return { ...unsigned, signatures };
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Verify every claim about a transcript a non-member can check given only
|
|
47
|
+
* the public keys: (a) each `TranscriptSignature` is valid, (b) each
|
|
48
|
+
* `ChannelMessage` carries a valid signature, (c) every message's sender
|
|
49
|
+
* is in `members`, (d) sequences are strictly monotonic per channel,
|
|
50
|
+
* (e) every message's `channelId` matches the transcript.
|
|
51
|
+
*
|
|
52
|
+
* Returns a list of errors rather than throwing so auditors can collect
|
|
53
|
+
* every failure in one pass.
|
|
54
|
+
*/
|
|
55
|
+
export function verifyTranscript(t) {
|
|
56
|
+
const errors = [];
|
|
57
|
+
if (t?.transcriptVersion !== "1") {
|
|
58
|
+
errors.push("transcriptVersion is not 1");
|
|
59
|
+
return { ok: false, errors };
|
|
60
|
+
}
|
|
61
|
+
if (!t.channelId)
|
|
62
|
+
errors.push("missing channelId");
|
|
63
|
+
if (!t.members?.length)
|
|
64
|
+
errors.push("missing members");
|
|
65
|
+
let unsigned;
|
|
66
|
+
try {
|
|
67
|
+
unsigned = stripTranscriptSignatures(t);
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
errors.push("could not strip signatures");
|
|
71
|
+
return { ok: false, errors };
|
|
72
|
+
}
|
|
73
|
+
if (!t.signatures?.length) {
|
|
74
|
+
errors.push("no transcript signatures");
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
const payload = transcriptSigningBytes(unsigned);
|
|
78
|
+
for (const s of t.signatures) {
|
|
79
|
+
if (s.sigVersion !== "1") {
|
|
80
|
+
errors.push(`transcript signature: unknown sigVersion ${s.sigVersion}`);
|
|
81
|
+
continue;
|
|
82
|
+
}
|
|
83
|
+
if (!t.members.includes(s.signer)) {
|
|
84
|
+
errors.push(`transcript signature signer "${s.signer}" not in members`);
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
try {
|
|
88
|
+
const ok = verifyPrimaryClaimSignature(s.signer, payload, signatureFromHex(s.signature));
|
|
89
|
+
if (!ok)
|
|
90
|
+
errors.push(`transcript signature by "${s.signer}" failed verification`);
|
|
91
|
+
}
|
|
92
|
+
catch (e) {
|
|
93
|
+
errors.push(`transcript signature by "${s.signer}" malformed: ${e.message}`);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
let highestSeen = 0;
|
|
98
|
+
for (const msg of t.messages ?? []) {
|
|
99
|
+
if (msg.channelId !== t.channelId) {
|
|
100
|
+
errors.push(`message seq=${msg.sequence}: channelId mismatch (${msg.channelId} vs ${t.channelId})`);
|
|
101
|
+
}
|
|
102
|
+
if (!isSenderInMembers(msg, t.members)) {
|
|
103
|
+
errors.push(`message seq=${msg.sequence}: sender "${msg.sender}" not in members`);
|
|
104
|
+
}
|
|
105
|
+
if (!Number.isInteger(msg.sequence) || msg.sequence < 1) {
|
|
106
|
+
errors.push(`message: invalid sequence ${msg.sequence}`);
|
|
107
|
+
}
|
|
108
|
+
else if (msg.sequence <= highestSeen) {
|
|
109
|
+
errors.push(`message seq=${msg.sequence}: non-monotonic (highest seen ${highestSeen})`);
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
highestSeen = msg.sequence;
|
|
113
|
+
}
|
|
114
|
+
if (!verifyChannelMessage(msg)) {
|
|
115
|
+
errors.push(`message seq=${msg.sequence}: signature verification failed`);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
return { ok: errors.length === 0, errors };
|
|
119
|
+
}
|
|
120
|
+
//# sourceMappingURL=transcript.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transcript.js","sourceRoot":"","sources":["../../../../src/l2ps/channel/transcript.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { ClaimReference } from "../../identity/cci";
|
|
2
|
+
/**
|
|
3
|
+
* Allowed message types — verbatim from DACS-3 §8.3.3. Closed union by
|
|
4
|
+
* design: the substrate enforces the conformance set; application bodies
|
|
5
|
+
* are carried in `body: unknown`.
|
|
6
|
+
*/
|
|
7
|
+
export type ChannelMessageType = "offer" | "counter" | "accept" | "reject" | "sealed-envelope-commit" | "sealed-envelope-reveal" | "abort";
|
|
8
|
+
/**
|
|
9
|
+
* Brief doesn't define the wire shape of the signature container. Versioned
|
|
10
|
+
* for forward compatibility (e.g. PQC swap-out) without breaking the
|
|
11
|
+
* envelope layout. Signature is hex-encoded over `channelMessageSigningBytes`.
|
|
12
|
+
*/
|
|
13
|
+
export interface ChannelMessageSignature {
|
|
14
|
+
sigVersion: "1";
|
|
15
|
+
signature: string;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* DACS-3 §8.3.3 envelope — verbatim. Transport-level fields may wrap this
|
|
19
|
+
* but MUST NOT change the bytes that the signature covers.
|
|
20
|
+
*/
|
|
21
|
+
export interface ChannelMessage {
|
|
22
|
+
channelId: string;
|
|
23
|
+
sequence: number;
|
|
24
|
+
sender: ClaimReference;
|
|
25
|
+
sentAt: number;
|
|
26
|
+
type: ChannelMessageType;
|
|
27
|
+
body: unknown;
|
|
28
|
+
refs?: {
|
|
29
|
+
repliesTo?: number;
|
|
30
|
+
};
|
|
31
|
+
signature: ChannelMessageSignature;
|
|
32
|
+
}
|
|
33
|
+
export type UnsignedChannelMessage = Omit<ChannelMessage, "signature">;
|
|
34
|
+
/**
|
|
35
|
+
* Per-signer transcript signature. Each member signs the full transcript
|
|
36
|
+
* (without `signatures`) — see WI-3 reference in the brief.
|
|
37
|
+
*/
|
|
38
|
+
export interface TranscriptSignature {
|
|
39
|
+
sigVersion: "1";
|
|
40
|
+
signer: ClaimReference;
|
|
41
|
+
signature: string;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* DACS-3 §8.7 — the ordered, member-signed record of a channel session.
|
|
45
|
+
* Consumed by WI-3 for encrypted-anchor flows.
|
|
46
|
+
*/
|
|
47
|
+
export interface ChannelTranscript {
|
|
48
|
+
transcriptVersion: "1";
|
|
49
|
+
channelId: string;
|
|
50
|
+
members: ClaimReference[];
|
|
51
|
+
messages: ChannelMessage[];
|
|
52
|
+
generatedAt: number;
|
|
53
|
+
signatures: TranscriptSignature[];
|
|
54
|
+
}
|
|
55
|
+
export type UnsignedChannelTranscript = Omit<ChannelTranscript, "signatures">;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../src/l2ps/channel/types.ts"],"names":[],"mappings":""}
|
package/build/l2ps/index.d.ts
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
1
|
import L2PS from "./l2ps";
|
|
2
|
-
import { L2PSConfig, L2PSEncryptedPayload } from "./l2ps";
|
|
3
|
-
export { L2PS, L2PSConfig, L2PSEncryptedPayload };
|
|
2
|
+
import { L2PSConfig, L2PSEncryptedBytes, L2PSEncryptedPayload } from "./l2ps";
|
|
3
|
+
export { L2PS, L2PSConfig, L2PSEncryptedBytes, L2PSEncryptedPayload };
|
|
4
|
+
export * as binding from "./binding";
|
|
5
|
+
export * as channel from "./channel";
|
|
6
|
+
export * as anchor from "./anchor";
|
package/build/l2ps/index.js
CHANGED
package/build/l2ps/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/l2ps/index.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,QAAQ,CAAA;AAGzB,OAAO,EAAE,IAAI,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/l2ps/index.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,QAAQ,CAAA;AAGzB,OAAO,EAAE,IAAI,EAAwD,CAAA;AAErE,OAAO,KAAK,OAAO,MAAM,WAAW,CAAA;AACpC,OAAO,KAAK,OAAO,MAAM,WAAW,CAAA;AACpC,OAAO,KAAK,MAAM,MAAM,UAAU,CAAA"}
|
package/build/l2ps/l2ps.d.ts
CHANGED
|
@@ -47,6 +47,21 @@ export interface L2PSEncryptedPayload {
|
|
|
47
47
|
*/
|
|
48
48
|
nonce?: string;
|
|
49
49
|
}
|
|
50
|
+
/**
|
|
51
|
+
* Payload shape for `L2PS.encryptBytes` / `L2PS.decryptBytes`. Used by
|
|
52
|
+
* SR-4 WI-3 to encrypt channel transcripts to the subnet member set
|
|
53
|
+
* without dragging the L2PS-transaction envelope into a non-tx context.
|
|
54
|
+
*/
|
|
55
|
+
export interface L2PSEncryptedBytes {
|
|
56
|
+
/** UID of the L2PS network that encrypted these bytes. */
|
|
57
|
+
l2ps_uid: string;
|
|
58
|
+
/** Base64-encoded AES-GCM ciphertext. */
|
|
59
|
+
ciphertext: string;
|
|
60
|
+
/** Base64-encoded AES-GCM authentication tag. */
|
|
61
|
+
tag: string;
|
|
62
|
+
/** Base64-encoded AES-GCM nonce (always 12 bytes, fresh per call). */
|
|
63
|
+
nonce: string;
|
|
64
|
+
}
|
|
50
65
|
/**
|
|
51
66
|
* L2PS (Layer 2 Private Subnets) class for encrypted transaction processing.
|
|
52
67
|
*
|
|
@@ -207,4 +222,21 @@ export default class L2PS {
|
|
|
207
222
|
* @returns Promise resolving to a 16-character fingerprint string
|
|
208
223
|
*/
|
|
209
224
|
getKeyFingerprint(): Promise<string>;
|
|
225
|
+
/**
|
|
226
|
+
* AES-GCM-encrypt arbitrary bytes under the subnet key.
|
|
227
|
+
*
|
|
228
|
+
* Mirrors the per-call-nonce + nonce-as-AAD pattern in `encryptTx`: a
|
|
229
|
+
* fresh 12-byte nonce per call, bound into the auth tag via AAD so an
|
|
230
|
+
* attacker cannot DoS specific ciphertexts by flipping the stored
|
|
231
|
+
* nonce. Used by SR-4 WI-3 to encrypt channel transcripts to the
|
|
232
|
+
* subnet member set; nothing in the payload shape is L2PS-transaction
|
|
233
|
+
* specific.
|
|
234
|
+
*/
|
|
235
|
+
encryptBytes(plaintext: Uint8Array): Promise<L2PSEncryptedBytes>;
|
|
236
|
+
/**
|
|
237
|
+
* Inverse of `encryptBytes`. Verifies the `l2ps_uid` matches this
|
|
238
|
+
* instance and that the AES-GCM auth tag (covering nonce + ciphertext)
|
|
239
|
+
* is intact; throws on either failure.
|
|
240
|
+
*/
|
|
241
|
+
decryptBytes(payload: L2PSEncryptedBytes): Promise<Uint8Array>;
|
|
210
242
|
}
|
package/build/l2ps/l2ps.js
CHANGED
|
@@ -309,6 +309,66 @@ class L2PS {
|
|
|
309
309
|
async getKeyFingerprint() {
|
|
310
310
|
return Hashing.sha256(this.privateKey).substring(0, 16);
|
|
311
311
|
}
|
|
312
|
+
/**
|
|
313
|
+
* AES-GCM-encrypt arbitrary bytes under the subnet key.
|
|
314
|
+
*
|
|
315
|
+
* Mirrors the per-call-nonce + nonce-as-AAD pattern in `encryptTx`: a
|
|
316
|
+
* fresh 12-byte nonce per call, bound into the auth tag via AAD so an
|
|
317
|
+
* attacker cannot DoS specific ciphertexts by flipping the stored
|
|
318
|
+
* nonce. Used by SR-4 WI-3 to encrypt channel transcripts to the
|
|
319
|
+
* subnet member set; nothing in the payload shape is L2PS-transaction
|
|
320
|
+
* specific.
|
|
321
|
+
*/
|
|
322
|
+
async encryptBytes(plaintext) {
|
|
323
|
+
const cipher = forge.cipher.createCipher('AES-GCM', this.privateKey);
|
|
324
|
+
const nonce = forge.random.getBytesSync(12);
|
|
325
|
+
cipher.start({ iv: nonce, additionalData: nonce });
|
|
326
|
+
cipher.update(forge.util.createBuffer(Buffer.from(plaintext).toString('binary'), 'binary'));
|
|
327
|
+
if (!cipher.finish()) {
|
|
328
|
+
throw new Error('L2PS.encryptBytes: AES-GCM finish() failed');
|
|
329
|
+
}
|
|
330
|
+
return {
|
|
331
|
+
l2ps_uid: this.config?.uid || this.id,
|
|
332
|
+
ciphertext: forge.util.encode64(cipher.output.getBytes()),
|
|
333
|
+
tag: forge.util.encode64(cipher.mode.tag.getBytes()),
|
|
334
|
+
nonce: forge.util.encode64(nonce),
|
|
335
|
+
};
|
|
336
|
+
}
|
|
337
|
+
/**
|
|
338
|
+
* Inverse of `encryptBytes`. Verifies the `l2ps_uid` matches this
|
|
339
|
+
* instance and that the AES-GCM auth tag (covering nonce + ciphertext)
|
|
340
|
+
* is intact; throws on either failure.
|
|
341
|
+
*/
|
|
342
|
+
async decryptBytes(payload) {
|
|
343
|
+
if (payload.l2ps_uid !== (this.config?.uid || this.id)) {
|
|
344
|
+
throw new Error('L2PS.decryptBytes: payload encrypted for different L2PS uid');
|
|
345
|
+
}
|
|
346
|
+
// Storage-loaded JSON can violate the L2PSEncryptedBytes shape at
|
|
347
|
+
// runtime; without an explicit shape check forge would throw a
|
|
348
|
+
// base64 error that does not tell the caller which field is wrong.
|
|
349
|
+
if (typeof payload.ciphertext !== 'string' ||
|
|
350
|
+
typeof payload.tag !== 'string' ||
|
|
351
|
+
typeof payload.nonce !== 'string') {
|
|
352
|
+
throw new Error('L2PS.decryptBytes: payload must include base64 strings for ciphertext, tag, and nonce');
|
|
353
|
+
}
|
|
354
|
+
const ciphertext = forge.util.createBuffer(forge.util.decode64(payload.ciphertext));
|
|
355
|
+
const tag = forge.util.createBuffer(forge.util.decode64(payload.tag));
|
|
356
|
+
const iv = forge.util.decode64(payload.nonce);
|
|
357
|
+
if (iv.length !== 12) {
|
|
358
|
+
throw new Error('L2PS.decryptBytes: invalid nonce (expected base64-encoded 12-byte value)');
|
|
359
|
+
}
|
|
360
|
+
const decipher = forge.cipher.createDecipher('AES-GCM', this.privateKey);
|
|
361
|
+
decipher.start({ iv, tag, additionalData: iv });
|
|
362
|
+
decipher.update(ciphertext);
|
|
363
|
+
if (!decipher.finish()) {
|
|
364
|
+
throw new Error('L2PS.decryptBytes: AES-GCM authentication failed');
|
|
365
|
+
}
|
|
366
|
+
const bin = decipher.output.getBytes();
|
|
367
|
+
const out = new Uint8Array(bin.length);
|
|
368
|
+
for (let i = 0; i < bin.length; i++)
|
|
369
|
+
out[i] = bin.charCodeAt(i) & 0xff;
|
|
370
|
+
return out;
|
|
371
|
+
}
|
|
312
372
|
}
|
|
313
373
|
/** Static map of all L2PS instances, keyed by instance ID */
|
|
314
374
|
L2PS.instances = new Map();
|
package/build/l2ps/l2ps.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"l2ps.js","sourceRoot":"","sources":["../../../src/l2ps/l2ps.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,KAAK,MAAM,YAAY,CAAC;AAC/B,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"l2ps.js","sourceRoot":"","sources":["../../../src/l2ps/l2ps.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hex encoding helpers shared across the SR-4 modules
|
|
3
|
+
* (binding / channel / anchor) so the signature wire format stays
|
|
4
|
+
* identical in every place that produces or consumes a hex string.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Encode raw bytes as a lowercase, unprefixed hex string. Used for hash
|
|
8
|
+
* digests carried in signing payloads (the wire signature wrappers use
|
|
9
|
+
* the `0x`-prefixed `signatureToHex` instead).
|
|
10
|
+
*/
|
|
11
|
+
export declare function bytesToHex(bytes: Uint8Array): string;
|
|
12
|
+
/**
|
|
13
|
+
* Wire encoding for an Ed25519 signature — lowercase `0x`-prefixed hex.
|
|
14
|
+
* Match for `signatureFromHex` on the verify side.
|
|
15
|
+
*/
|
|
16
|
+
export declare function signatureToHex(sig: Uint8Array): string;
|
|
17
|
+
/**
|
|
18
|
+
* Decode a hex string (with or without a `0x` / `0X` prefix) into a
|
|
19
|
+
* `Uint8Array`. Rejects odd-length input and non-hex characters so a
|
|
20
|
+
* malformed wire signature surfaces immediately instead of producing a
|
|
21
|
+
* silently truncated byte array.
|
|
22
|
+
*
|
|
23
|
+
* @throws {Error} If the cleaned hex string is odd-length or contains
|
|
24
|
+
* non-hex characters.
|
|
25
|
+
*/
|
|
26
|
+
export declare function signatureFromHex(hex: string): Uint8Array;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hex encoding helpers shared across the SR-4 modules
|
|
3
|
+
* (binding / channel / anchor) so the signature wire format stays
|
|
4
|
+
* identical in every place that produces or consumes a hex string.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Encode raw bytes as a lowercase, unprefixed hex string. Used for hash
|
|
8
|
+
* digests carried in signing payloads (the wire signature wrappers use
|
|
9
|
+
* the `0x`-prefixed `signatureToHex` instead).
|
|
10
|
+
*/
|
|
11
|
+
export function bytesToHex(bytes) {
|
|
12
|
+
let out = "";
|
|
13
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
14
|
+
out += bytes[i].toString(16).padStart(2, "0");
|
|
15
|
+
}
|
|
16
|
+
return out;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Wire encoding for an Ed25519 signature — lowercase `0x`-prefixed hex.
|
|
20
|
+
* Match for `signatureFromHex` on the verify side.
|
|
21
|
+
*/
|
|
22
|
+
export function signatureToHex(sig) {
|
|
23
|
+
return "0x" + bytesToHex(sig);
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Decode a hex string (with or without a `0x` / `0X` prefix) into a
|
|
27
|
+
* `Uint8Array`. Rejects odd-length input and non-hex characters so a
|
|
28
|
+
* malformed wire signature surfaces immediately instead of producing a
|
|
29
|
+
* silently truncated byte array.
|
|
30
|
+
*
|
|
31
|
+
* @throws {Error} If the cleaned hex string is odd-length or contains
|
|
32
|
+
* non-hex characters.
|
|
33
|
+
*/
|
|
34
|
+
export function signatureFromHex(hex) {
|
|
35
|
+
const h = hex.startsWith("0x") || hex.startsWith("0X") ? hex.slice(2) : hex;
|
|
36
|
+
if (h.length % 2 !== 0 || !/^[0-9a-fA-F]*$/.test(h)) {
|
|
37
|
+
throw new Error("signatureFromHex: not a valid hex string");
|
|
38
|
+
}
|
|
39
|
+
const out = new Uint8Array(h.length / 2);
|
|
40
|
+
for (let i = 0; i < h.length; i += 2) {
|
|
41
|
+
out[i / 2] = Number.parseInt(h.slice(i, i + 2), 16);
|
|
42
|
+
}
|
|
43
|
+
return out;
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=hex.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hex.js","sourceRoot":"","sources":["../../../../src/l2ps/utils/hex.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;GAIG;AACH,MAAM,UAAU,UAAU,CAAC,KAAiB;IACxC,IAAI,GAAG,GAAG,EAAE,CAAA;IACZ,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACpC,GAAG,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAA;IACjD,CAAC;IACD,OAAO,GAAG,CAAA;AACd,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,GAAe;IAC1C,OAAO,IAAI,GAAG,UAAU,CAAC,GAAG,CAAC,CAAA;AACjC,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,gBAAgB,CAAC,GAAW;IACxC,MAAM,CAAC,GAAG,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAA;IAC3E,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;QAClD,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAA;IAC/D,CAAC;IACD,MAAM,GAAG,GAAG,IAAI,UAAU,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;IACxC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QACnC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,CAAA;IACvD,CAAC;IACD,OAAO,GAAG,CAAA;AACd,CAAC"}
|
|
@@ -77,6 +77,21 @@ export interface InferFromGithubPayload extends Web2CoreTargetIdentityPayload {
|
|
|
77
77
|
context: "github";
|
|
78
78
|
proof: GithubProof;
|
|
79
79
|
}
|
|
80
|
+
/**
|
|
81
|
+
* A domain proof is the HTTPS URL of the well-known file the domain owner
|
|
82
|
+
* hosts to prove control: https://<host>/.well-known/demos-cci.txt
|
|
83
|
+
* The file body is the standard web2 proof payload produced by
|
|
84
|
+
* Identities.createDomainProofPayload (i.e. `demos:dw2p:<algorithm>:<signature>`).
|
|
85
|
+
*/
|
|
86
|
+
export type DomainProof = `https://${string}/.well-known/demos-cci.txt`;
|
|
87
|
+
export interface InferFromDomainPayload extends Web2CoreTargetIdentityPayload {
|
|
88
|
+
context: "domain";
|
|
89
|
+
proof: DomainProof;
|
|
90
|
+
/** The hostname being claimed (e.g. "example.com"). */
|
|
91
|
+
username: string;
|
|
92
|
+
/** Domains have no separate numeric id; mirrors `username`. */
|
|
93
|
+
userId: string;
|
|
94
|
+
}
|
|
80
95
|
export type XProof = `https://x.com/${string}/${string}`;
|
|
81
96
|
export type TwitterProof = XProof;
|
|
82
97
|
export type DiscordProof = `https://discord.com/channels/${string}/${string}/${string}` | `https://ptb.discord.com/channels/${string}/${string}/${string}` | `https://canary.discord.com/channels/${string}/${string}/${string}` | `https://discordapp.com/channels/${string}/${string}/${string}`;
|
|
@@ -130,7 +145,7 @@ export interface BaseWeb2IdentityPayload {
|
|
|
130
145
|
}
|
|
131
146
|
export interface Web2IdentityAssignPayload extends BaseWeb2IdentityPayload {
|
|
132
147
|
method: "web2_identity_assign";
|
|
133
|
-
payload: InferFromGithubPayload | InferFromTwitterPayload | InferFromTelegramPayload | InferFromDiscordPayload;
|
|
148
|
+
payload: InferFromGithubPayload | InferFromTwitterPayload | InferFromTelegramPayload | InferFromDiscordPayload | InferFromDomainPayload;
|
|
134
149
|
}
|
|
135
150
|
export interface Web2IdentityRemovePayload extends BaseWeb2IdentityPayload {
|
|
136
151
|
method: "web2_identity_remove";
|
|
@@ -443,7 +458,7 @@ export interface UserPoints {
|
|
|
443
458
|
}
|
|
444
459
|
export interface FindDemosIdByWeb2IdentityQuery {
|
|
445
460
|
type: "web2";
|
|
446
|
-
context: "twitter" | "telegram" | "github" | "discord";
|
|
461
|
+
context: "twitter" | "telegram" | "github" | "discord" | "domain";
|
|
447
462
|
username: string;
|
|
448
463
|
userId?: string;
|
|
449
464
|
}
|
|
@@ -134,6 +134,8 @@ export class Web2Proxy {
|
|
|
134
134
|
web2Tx.content.type = "web2Request";
|
|
135
135
|
web2Tx.content.data = ["web2Request", web2Payload];
|
|
136
136
|
web2Tx.content.timestamp = Date.now();
|
|
137
|
+
const nonce = await this._demos.getAddressNonce(await this._demos.getEd25519Address());
|
|
138
|
+
web2Tx.content.nonce = nonce + 1;
|
|
137
139
|
const signedWeb2Tx = await this._demos.sign(web2Tx);
|
|
138
140
|
const validityData = await this._demos.confirm(signedWeb2Tx);
|
|
139
141
|
const txHash = validityData.response.data.transaction.hash;
|