@mcsherrylabs/evolver-mcp 0.0.0-stage → 0.8.1
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/dist/amount.d.ts +20 -0
- package/dist/amount.d.ts.map +1 -0
- package/dist/amount.js +44 -0
- package/dist/amount.js.map +1 -0
- package/dist/bootstrap.d.ts +264 -0
- package/dist/bootstrap.d.ts.map +1 -0
- package/dist/bootstrap.js +901 -0
- package/dist/bootstrap.js.map +1 -0
- package/dist/channel.d.ts +78 -0
- package/dist/channel.d.ts.map +1 -0
- package/dist/channel.js +288 -0
- package/dist/channel.js.map +1 -0
- package/dist/claim.d.ts +48 -0
- package/dist/claim.d.ts.map +1 -0
- package/dist/claim.js +81 -0
- package/dist/claim.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +35 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +39 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +77 -0
- package/dist/config.js.map +1 -0
- package/dist/content.d.ts +51 -0
- package/dist/content.d.ts.map +1 -0
- package/dist/content.js +60 -0
- package/dist/content.js.map +1 -0
- package/dist/group.d.ts +60 -0
- package/dist/group.d.ts.map +1 -0
- package/dist/group.js +204 -0
- package/dist/group.js.map +1 -0
- package/dist/identity.d.ts +87 -0
- package/dist/identity.d.ts.map +1 -0
- package/dist/identity.js +230 -0
- package/dist/identity.js.map +1 -0
- package/dist/inbox.d.ts +30 -0
- package/dist/inbox.d.ts.map +1 -0
- package/dist/inbox.js +95 -0
- package/dist/inbox.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +206 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp.d.ts +39 -0
- package/dist/mcp.d.ts.map +1 -0
- package/dist/mcp.js +83 -0
- package/dist/mcp.js.map +1 -0
- package/dist/read.d.ts +175 -0
- package/dist/read.d.ts.map +1 -0
- package/dist/read.js +219 -0
- package/dist/read.js.map +1 -0
- package/dist/result.d.ts +110 -0
- package/dist/result.d.ts.map +1 -0
- package/dist/result.js +97 -0
- package/dist/result.js.map +1 -0
- package/dist/signer.d.ts +37 -0
- package/dist/signer.d.ts.map +1 -0
- package/dist/signer.js +76 -0
- package/dist/signer.js.map +1 -0
- package/dist/tools.d.ts +44 -0
- package/dist/tools.d.ts.map +1 -0
- package/dist/tools.js +642 -0
- package/dist/tools.js.map +1 -0
- package/dist/write.d.ts +173 -0
- package/dist/write.d.ts.map +1 -0
- package/dist/write.js +322 -0
- package/dist/write.js.map +1 -0
- package/package.json +55 -4
- package/README.md +0 -3
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import type { Signer } from "@mcsherrylabs/evolver-client";
|
|
2
|
+
import type { ChainReads } from "./read.js";
|
|
3
|
+
import type { SignedIdentity, SignedGroup, SignedChannel, SignedRecord } from "./write.js";
|
|
4
|
+
import type { ToolResult } from "./result.js";
|
|
5
|
+
/** What the identity verbs need from the world. NO `submitTx` — deliberately: the five signing
|
|
6
|
+
* verbs submit nothing, so the capability is not present to reach for (SIGN-20 is structural). */
|
|
7
|
+
export interface IdentityOpsDeps {
|
|
8
|
+
readonly identity: string;
|
|
9
|
+
readonly signer: Signer;
|
|
10
|
+
readonly ttlOffset?: number;
|
|
11
|
+
readonly reads: ChainReads;
|
|
12
|
+
}
|
|
13
|
+
/** A signed identity operation, as returned by a signing verb. Always `ok` once composed. */
|
|
14
|
+
export type IdentitySignResult = ToolResult<SignedIdentity>;
|
|
15
|
+
/** Decode a starting credit from a decimal string, refusing `< 1`, non-integers, and negative/hex
|
|
16
|
+
* forms. The chain FINES a zero- or negative-credit creation rather than refusing it, so the whole
|
|
17
|
+
* point is this refusal happening BEFORE anything is signed (Pitfall 4). */
|
|
18
|
+
export declare function parseInitialCredit(input: string): {
|
|
19
|
+
ok: true;
|
|
20
|
+
value: bigint;
|
|
21
|
+
} | {
|
|
22
|
+
ok: false;
|
|
23
|
+
error: string;
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* Compose a body into a signed identity transaction and record it — in ONE call. Mirrors
|
|
27
|
+
* `signTransfer`'s inline compose→sign→record: `buildSignedTx` → `txIdHex` → record into the two
|
|
28
|
+
* session stores via `recordSigned`. It SUBMITS NOTHING.
|
|
29
|
+
*
|
|
30
|
+
* This is the single compose implementation, re-exported from `src/write.ts` as `composeAndSign`
|
|
31
|
+
* (one compose path, never two). The `ledgerId` is always `LEDGER.identity` at the call sites.
|
|
32
|
+
*/
|
|
33
|
+
export declare function composeIdentityTx(deps: IdentityOpsDeps, args: {
|
|
34
|
+
ledgerId: string;
|
|
35
|
+
body: Uint8Array;
|
|
36
|
+
ttlRound: number;
|
|
37
|
+
signedAtRound: number;
|
|
38
|
+
verb: SignedIdentity["verb"] | SignedGroup["verb"] | SignedChannel["verb"];
|
|
39
|
+
fields: Record<string, string>;
|
|
40
|
+
maxToll?: bigint;
|
|
41
|
+
}): ToolResult<SignedRecord>;
|
|
42
|
+
/**
|
|
43
|
+
* Sponsor a new identity, paid for by this agent — signed for `deps.identity`, the configured host
|
|
44
|
+
* identity as `senderNodeId` (never a caller-chosen node id).
|
|
45
|
+
*
|
|
46
|
+
* ⚠️ THE CHAIN'S KEY RULES ARE ENFORCED HERE, not left to it, because its answer arrives too late
|
|
47
|
+
* to help: a body with the wrong keys is ORDERED and FINED 100, not refused. Exactly one
|
|
48
|
+
* BLS12-381-G1 and one Ed25519, each at label "", a starting credit >= 1, and both keys carrying a
|
|
49
|
+
* proof of possession from their holder.
|
|
50
|
+
*/
|
|
51
|
+
export declare function signCreateIdentity(deps: IdentityOpsDeps, params: {
|
|
52
|
+
keys: Array<{
|
|
53
|
+
keyType: string;
|
|
54
|
+
keyLabel: string;
|
|
55
|
+
publicKey: string;
|
|
56
|
+
popSignature: string;
|
|
57
|
+
}>;
|
|
58
|
+
initialCredit: string;
|
|
59
|
+
}): Promise<ToolResult<SignedRecord>>;
|
|
60
|
+
/**
|
|
61
|
+
* Delete the identity this agent signs as. SELF-DELETION ONLY (Pitfall 5): `confirmName` must match
|
|
62
|
+
* `deps.identity`, else the chain would fine a deletion naming another identity.
|
|
63
|
+
*/
|
|
64
|
+
export declare function signDeleteIdentity(deps: IdentityOpsDeps, params: {
|
|
65
|
+
confirmName: string;
|
|
66
|
+
}): Promise<ToolResult<SignedRecord>>;
|
|
67
|
+
export declare const signAddKey: (deps: IdentityOpsDeps, p: {
|
|
68
|
+
keyType: string;
|
|
69
|
+
keyLabel: string;
|
|
70
|
+
publicKey: string;
|
|
71
|
+
popSignature: string;
|
|
72
|
+
}) => Promise<ToolResult<SignedRecord>>;
|
|
73
|
+
export declare const signReplaceKey: (deps: IdentityOpsDeps, p: {
|
|
74
|
+
keyType: string;
|
|
75
|
+
keyLabel: string;
|
|
76
|
+
publicKey: string;
|
|
77
|
+
popSignature: string;
|
|
78
|
+
}) => Promise<ToolResult<SignedRecord>>;
|
|
79
|
+
/**
|
|
80
|
+
* Remove one of this identity's own keys. ⚠️ THE CHAIN WILL NOT STOP YOU LOCKING YOURSELF OUT — its
|
|
81
|
+
* only guard refuses a committee member deleting its default consensus key.
|
|
82
|
+
*/
|
|
83
|
+
export declare function signDeleteKey(deps: IdentityOpsDeps, p: {
|
|
84
|
+
keyType: string;
|
|
85
|
+
keyLabel: string;
|
|
86
|
+
}): Promise<ToolResult<SignedRecord>>;
|
|
87
|
+
//# sourceMappingURL=identity.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"identity.d.ts","sourceRoot":"","sources":["../src/identity.ts"],"names":[],"mappings":"AA0BA,OAAO,KAAK,EAAE,MAAM,EAAY,MAAM,8BAA8B,CAAC;AACrE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAE5C,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC3F,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C;mGACmG;AACnG,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC;CAC5B;AAED,6FAA6F;AAC7F,MAAM,MAAM,kBAAkB,GAAG,UAAU,CAAC,cAAc,CAAC,CAAC;AAE5D;;6EAE6E;AAC7E,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAU5G;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,eAAe,EACrB,IAAI,EAAE;IACJ,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,UAAU,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,IAAI,EAAE,cAAc,CAAC,MAAM,CAAC,GAAG,WAAW,CAAC,MAAM,CAAC,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;IAC3E,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,GACA,UAAU,CAAC,YAAY,CAAC,CAoB1B;AAYD;;;;;;;;GAQG;AACH,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,eAAe,EACrB,MAAM,EAAE;IAAE,IAAI,EAAE,KAAK,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE,GAC7H,OAAO,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC,CA6DnC;AAED;;;GAGG;AACH,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,eAAe,EACrB,MAAM,EAAE;IAAE,WAAW,EAAE,MAAM,CAAA;CAAE,GAC9B,OAAO,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC,CAuBnC;AAmDD,eAAO,MAAM,UAAU,GAAI,MAAM,eAAe,EAAE,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,sCACpG,CAAC;AAEhC,eAAO,MAAM,cAAc,GAAI,MAAM,eAAe,EAAE,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,sCACpG,CAAC;AAEpC;;;GAGG;AACH,wBAAsB,aAAa,CACjC,IAAI,EAAE,eAAe,EACrB,CAAC,EAAE;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GACvC,OAAO,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC,CAiBnC"}
|
package/dist/identity.js
ADDED
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
// Identity-lifecycle signing verbs (SIGN-03..07): sign create/delete identity and add/replace/delete
|
|
2
|
+
// key. Each is a compose→sign→record→return-txId operation with ZERO submit, mirroring Phase 2's
|
|
3
|
+
// `signTransfer` (SIGN-20) and resolving in the SAME `submitSigned`/`inspectSigned` path (SIGN-19).
|
|
4
|
+
//
|
|
5
|
+
// The ledger is pinned to `LEDGER.identity` (never a caller-chosen channel or core-ledger id), so
|
|
6
|
+
// nothing here can reach a node before `evolver_submit`. The costly local refusals — create-identity
|
|
7
|
+
// key rules, delete-identity self-check, empty-PoP refusal — fire BEFORE anything is signed, because
|
|
8
|
+
// the chain's answer for a malformed body arrives as a FINE, too late to refuse (Pitfalls 4/5).
|
|
9
|
+
//
|
|
10
|
+
// ⚠️ KEY MATERIAL NEVER REACHES A RECORD OR A REFUSAL. Records carry key `type`/`label` and the txId
|
|
11
|
+
// only; the caller supplies the holder-produced `popSignature` bytes, which are folded into the
|
|
12
|
+
// composed body by the SDK encoder — this process never computes a PoP digest and never signs for a
|
|
13
|
+
// key it does not hold.
|
|
14
|
+
import { LEDGER, buildSignedTx, txIdHex, hexToBytes, createIdentityInner, createIdentityBody, deleteIdentityBody, addKeyBody, replaceKeyBody, deleteKeyBody, } from "@mcsherrylabs/evolver-client";
|
|
15
|
+
import { DEFAULT_TTL_OFFSET, recordSigned } from "./write.js";
|
|
16
|
+
/** Decode a starting credit from a decimal string, refusing `< 1`, non-integers, and negative/hex
|
|
17
|
+
* forms. The chain FINES a zero- or negative-credit creation rather than refusing it, so the whole
|
|
18
|
+
* point is this refusal happening BEFORE anything is signed (Pitfall 4). */
|
|
19
|
+
export function parseInitialCredit(input) {
|
|
20
|
+
const s = String(input ?? "").trim();
|
|
21
|
+
if (!/^[1-9][0-9]*$/.test(s))
|
|
22
|
+
return {
|
|
23
|
+
ok: false,
|
|
24
|
+
error: `initialCredit "${s}" is not a positive decimal integer — it must be at least 1, because ` +
|
|
25
|
+
`a zero- or negative-credit creation is ordered and FINED rather than refused`,
|
|
26
|
+
};
|
|
27
|
+
return { ok: true, value: BigInt(s) };
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Compose a body into a signed identity transaction and record it — in ONE call. Mirrors
|
|
31
|
+
* `signTransfer`'s inline compose→sign→record: `buildSignedTx` → `txIdHex` → record into the two
|
|
32
|
+
* session stores via `recordSigned`. It SUBMITS NOTHING.
|
|
33
|
+
*
|
|
34
|
+
* This is the single compose implementation, re-exported from `src/write.ts` as `composeAndSign`
|
|
35
|
+
* (one compose path, never two). The `ledgerId` is always `LEDGER.identity` at the call sites.
|
|
36
|
+
*/
|
|
37
|
+
export function composeIdentityTx(deps, args) {
|
|
38
|
+
const bytes = buildSignedTx({
|
|
39
|
+
ledgerId: args.ledgerId,
|
|
40
|
+
senderNodeId: deps.identity,
|
|
41
|
+
body: args.body,
|
|
42
|
+
ttlRound: args.ttlRound,
|
|
43
|
+
signers: [deps.signer],
|
|
44
|
+
maxToll: args.maxToll,
|
|
45
|
+
});
|
|
46
|
+
const id = txIdHex(args.ledgerId, deps.identity, args.ttlRound, args.body, args.maxToll);
|
|
47
|
+
const signed = {
|
|
48
|
+
txId: id,
|
|
49
|
+
expiresAtRound: args.ttlRound,
|
|
50
|
+
signedAtRound: args.signedAtRound,
|
|
51
|
+
verb: args.verb,
|
|
52
|
+
fields: { ...args.fields },
|
|
53
|
+
summary: { sender: deps.identity, ...args.fields },
|
|
54
|
+
};
|
|
55
|
+
recordSigned(signed, bytes);
|
|
56
|
+
return { kind: "ok", value: signed };
|
|
57
|
+
}
|
|
58
|
+
/** Read the chain tip to bound a transaction's life; an unreachable chain is `unreachable`, never a
|
|
59
|
+
* submit. */
|
|
60
|
+
async function tipOrUnreachable(deps) {
|
|
61
|
+
try {
|
|
62
|
+
return await deps.reads.currentRound();
|
|
63
|
+
}
|
|
64
|
+
catch (e) {
|
|
65
|
+
return { kind: "unreachable", chain: "", cause: e instanceof Error ? e.message : String(e) };
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Sponsor a new identity, paid for by this agent — signed for `deps.identity`, the configured host
|
|
70
|
+
* identity as `senderNodeId` (never a caller-chosen node id).
|
|
71
|
+
*
|
|
72
|
+
* ⚠️ THE CHAIN'S KEY RULES ARE ENFORCED HERE, not left to it, because its answer arrives too late
|
|
73
|
+
* to help: a body with the wrong keys is ORDERED and FINED 100, not refused. Exactly one
|
|
74
|
+
* BLS12-381-G1 and one Ed25519, each at label "", a starting credit >= 1, and both keys carrying a
|
|
75
|
+
* proof of possession from their holder.
|
|
76
|
+
*/
|
|
77
|
+
export async function signCreateIdentity(deps, params) {
|
|
78
|
+
const credit = parseInitialCredit(params.initialCredit);
|
|
79
|
+
if (!credit.ok)
|
|
80
|
+
return { kind: "partial", what: "initialCredit", cause: credit.error };
|
|
81
|
+
const keys = Array.isArray(params.keys) ? params.keys : [];
|
|
82
|
+
const bls = keys.filter((k) => k.keyType === "BLS12-381-G1");
|
|
83
|
+
const ed = keys.filter((k) => k.keyType === "Ed25519");
|
|
84
|
+
if (bls.length !== 1 || ed.length !== 1 || keys.length !== 2)
|
|
85
|
+
return {
|
|
86
|
+
kind: "partial",
|
|
87
|
+
what: "keys",
|
|
88
|
+
cause: "exactly one BLS12-381-G1 and one Ed25519 are required, each at the default label. " +
|
|
89
|
+
"A body without both is ordered and FINED 100 rather than refused, so it is refused here.",
|
|
90
|
+
};
|
|
91
|
+
if (keys.some((k) => String(k.keyLabel ?? "") !== ""))
|
|
92
|
+
return {
|
|
93
|
+
kind: "partial",
|
|
94
|
+
what: "keys",
|
|
95
|
+
cause: "both keys must be at the default (empty) label — a non-empty label is refused here rather than fined on-chain",
|
|
96
|
+
};
|
|
97
|
+
// Empty-PoP refusal: this agent signs for NO key it does not hold (T-03-01). Named by field, never bytes.
|
|
98
|
+
const empty = keys.findIndex((k) => !k.popSignature || String(k.popSignature).length === 0);
|
|
99
|
+
if (empty !== -1)
|
|
100
|
+
return {
|
|
101
|
+
kind: "partial",
|
|
102
|
+
what: `keys.${empty}.popSignature`,
|
|
103
|
+
cause: "each key needs a proof of possession from its holder — this agent signs for no key it does not hold",
|
|
104
|
+
};
|
|
105
|
+
// Hex-decode each key, refusing (naming the PATH) on non-hex/odd-length input (T-03-07). The
|
|
106
|
+
// refusal names the field, never echoes the bytes.
|
|
107
|
+
const decoded = [];
|
|
108
|
+
for (let i = 0; i < keys.length; i++) {
|
|
109
|
+
const k = keys[i];
|
|
110
|
+
try {
|
|
111
|
+
const publicKey = hexToBytes(String(k.publicKey ?? ""));
|
|
112
|
+
// Empty-publicKey refusal: zero bytes, not an error — refused for free rather than fined.
|
|
113
|
+
if (publicKey.length === 0)
|
|
114
|
+
return { kind: "partial", what: `keys.${i}.publicKey`, cause: "a key is needed" };
|
|
115
|
+
const popSig = hexToBytes(String(k.popSignature ?? ""));
|
|
116
|
+
decoded.push({ keyType: k.keyType, publicKey, keyLabel: String(k.keyLabel ?? ""), popSig });
|
|
117
|
+
}
|
|
118
|
+
catch (e) {
|
|
119
|
+
return { kind: "partial", what: `keys.${i}`, cause: e instanceof Error ? e.message : String(e) };
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
const tip = await tipOrUnreachable(deps);
|
|
123
|
+
if (typeof tip !== "number")
|
|
124
|
+
return tip;
|
|
125
|
+
const expiresAtRound = tip + (deps.ttlOffset ?? DEFAULT_TTL_OFFSET);
|
|
126
|
+
const body = createIdentityBody(createIdentityInner(deps.identity, credit.value, decoded, true));
|
|
127
|
+
return composeIdentityTx(deps, {
|
|
128
|
+
ledgerId: LEDGER.identity,
|
|
129
|
+
body,
|
|
130
|
+
ttlRound: expiresAtRound,
|
|
131
|
+
signedAtRound: tip,
|
|
132
|
+
verb: "create_identity",
|
|
133
|
+
fields: { initialCredit: credit.value.toString() },
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Delete the identity this agent signs as. SELF-DELETION ONLY (Pitfall 5): `confirmName` must match
|
|
138
|
+
* `deps.identity`, else the chain would fine a deletion naming another identity.
|
|
139
|
+
*/
|
|
140
|
+
export async function signDeleteIdentity(deps, params) {
|
|
141
|
+
const confirmName = String(params.confirmName ?? "").trim();
|
|
142
|
+
if (confirmName !== deps.identity)
|
|
143
|
+
return {
|
|
144
|
+
kind: "partial",
|
|
145
|
+
what: "confirmName",
|
|
146
|
+
cause: `this deletes THIS identity and nothing else — the chain fines a deletion naming another. ` +
|
|
147
|
+
`Pass "${deps.identity}" to mean it.`,
|
|
148
|
+
};
|
|
149
|
+
const tip = await tipOrUnreachable(deps);
|
|
150
|
+
if (typeof tip !== "number")
|
|
151
|
+
return tip;
|
|
152
|
+
const expiresAtRound = tip + (deps.ttlOffset ?? DEFAULT_TTL_OFFSET);
|
|
153
|
+
return composeIdentityTx(deps, {
|
|
154
|
+
ledgerId: LEDGER.identity,
|
|
155
|
+
body: deleteIdentityBody(deps.identity),
|
|
156
|
+
ttlRound: expiresAtRound,
|
|
157
|
+
signedAtRound: tip,
|
|
158
|
+
verb: "delete_identity",
|
|
159
|
+
fields: { target: deps.identity },
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
/** Add/replace share one shape, differing only by verb tag and encoder. The SDK encoders keep them
|
|
163
|
+
* distinct (a shared hand-rolled digest would make an AddKey proof valid for a ReplaceKey). */
|
|
164
|
+
async function signKeyOp(deps, verb, p) {
|
|
165
|
+
const keyType = String(p.keyType ?? "").trim();
|
|
166
|
+
const keyLabel = String(p.keyLabel ?? "");
|
|
167
|
+
let publicKey, popSignature;
|
|
168
|
+
try {
|
|
169
|
+
publicKey = hexToBytes(String(p.publicKey ?? ""));
|
|
170
|
+
}
|
|
171
|
+
catch (e) {
|
|
172
|
+
return { kind: "partial", what: "publicKey", cause: e instanceof Error ? e.message : String(e) };
|
|
173
|
+
}
|
|
174
|
+
// Empty-publicKey refusal: `hexToBytes("")` is zero bytes, not an error — a body carrying an
|
|
175
|
+
// empty key would be ordered and fined on-chain, so it is refused for free before anything is
|
|
176
|
+
// signed (reference: admin.ts signKeyOp refuses `publicKey.length === 0`).
|
|
177
|
+
if (publicKey.length === 0)
|
|
178
|
+
return { kind: "partial", what: "publicKey", cause: "a key is needed" };
|
|
179
|
+
try {
|
|
180
|
+
popSignature = hexToBytes(String(p.popSignature ?? ""));
|
|
181
|
+
}
|
|
182
|
+
catch (e) {
|
|
183
|
+
return { kind: "partial", what: "popSignature", cause: e instanceof Error ? e.message : String(e) };
|
|
184
|
+
}
|
|
185
|
+
// Empty-PoP refusal: this agent signs for NO key it does not hold.
|
|
186
|
+
if (popSignature.length === 0)
|
|
187
|
+
return {
|
|
188
|
+
kind: "partial",
|
|
189
|
+
what: "popSignature",
|
|
190
|
+
cause: "the key's holder must prove possession — this agent cannot sign for a key it does not hold",
|
|
191
|
+
};
|
|
192
|
+
const tip = await tipOrUnreachable(deps);
|
|
193
|
+
if (typeof tip !== "number")
|
|
194
|
+
return tip;
|
|
195
|
+
const expiresAtRound = tip + (deps.ttlOffset ?? DEFAULT_TTL_OFFSET);
|
|
196
|
+
const args = { publicKey, keyType, keyLabel, popSignature };
|
|
197
|
+
return composeIdentityTx(deps, {
|
|
198
|
+
ledgerId: LEDGER.identity,
|
|
199
|
+
body: verb === "add_key" ? addKeyBody(args) : replaceKeyBody(args),
|
|
200
|
+
ttlRound: expiresAtRound,
|
|
201
|
+
signedAtRound: tip,
|
|
202
|
+
verb,
|
|
203
|
+
fields: { keyType, keyLabel },
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
export const signAddKey = (deps, p) => signKeyOp(deps, "add_key", p);
|
|
207
|
+
export const signReplaceKey = (deps, p) => signKeyOp(deps, "replace_key", p);
|
|
208
|
+
/**
|
|
209
|
+
* Remove one of this identity's own keys. ⚠️ THE CHAIN WILL NOT STOP YOU LOCKING YOURSELF OUT — its
|
|
210
|
+
* only guard refuses a committee member deleting its default consensus key.
|
|
211
|
+
*/
|
|
212
|
+
export async function signDeleteKey(deps, p) {
|
|
213
|
+
const keyType = String(p.keyType ?? "").trim();
|
|
214
|
+
if (keyType.length === 0)
|
|
215
|
+
return { kind: "partial", what: "keyType", cause: "which key?" };
|
|
216
|
+
const keyLabel = String(p.keyLabel ?? "");
|
|
217
|
+
const tip = await tipOrUnreachable(deps);
|
|
218
|
+
if (typeof tip !== "number")
|
|
219
|
+
return tip;
|
|
220
|
+
const expiresAtRound = tip + (deps.ttlOffset ?? DEFAULT_TTL_OFFSET);
|
|
221
|
+
return composeIdentityTx(deps, {
|
|
222
|
+
ledgerId: LEDGER.identity,
|
|
223
|
+
body: deleteKeyBody({ keyType, keyLabel }),
|
|
224
|
+
ttlRound: expiresAtRound,
|
|
225
|
+
signedAtRound: tip,
|
|
226
|
+
verb: "delete_key",
|
|
227
|
+
fields: { keyType, keyLabel },
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
//# sourceMappingURL=identity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"identity.js","sourceRoot":"","sources":["../src/identity.ts"],"names":[],"mappings":"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"}
|
package/dist/inbox.d.ts
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { ToolResult } from "./result.js";
|
|
2
|
+
export declare const INBOX_DEFAULT_LIMIT = 10;
|
|
3
|
+
/** Lower than the route's own 100 (MAX_PAGE), mirroring the other read tools' `MAX_LIMIT < node
|
|
4
|
+
* clamp` convention: a page is context the model keeps, not a dump it loses. */
|
|
5
|
+
export declare const INBOX_MAX_LIMIT = 50;
|
|
6
|
+
/** What the inbox verbs need from the world: the processor endpoint, plus the fetch seam so the
|
|
7
|
+
* whole flow is exercisable against a structural fake (the same pattern as `ChainReads` /
|
|
8
|
+
* `ContentDeps`). `fetchImpl` defaults to the global `fetch`. */
|
|
9
|
+
export interface InboxDeps {
|
|
10
|
+
readonly processorUrl: string;
|
|
11
|
+
readonly fetchImpl?: typeof fetch;
|
|
12
|
+
}
|
|
13
|
+
/** Which channels have entries (or an inbox refusal), with counts and bounds. */
|
|
14
|
+
export declare function inboxSummary(deps: InboxDeps): Promise<ToolResult<unknown>>;
|
|
15
|
+
/**
|
|
16
|
+
* One page of a channel's entries after `after`, with each body ALSO as hex.
|
|
17
|
+
*
|
|
18
|
+
* Hex because service protocols document their bodies in hex bytes (the LLM proxy's worked
|
|
19
|
+
* example is hex), and a model decoding base64 by eye gets bytes wrong. A malformed `after` is a
|
|
20
|
+
* refusal of the argument (`partial`), carrying the route's own statement of the expected form —
|
|
21
|
+
* never `unreachable`, which would say "retry" (the processor DID answer; it refused the
|
|
22
|
+
* argument).
|
|
23
|
+
*
|
|
24
|
+
* Intent and bytes stay SEPARATE: `txId`/`round`/`index`/`ledgerId`/`sender`/`receivedAt` are the
|
|
25
|
+
* intent (who wrote, where, when), `body` is the raw bytes as the processor returned them, and
|
|
26
|
+
* `bodyHex` is the additive hex re-encode of `body` — never a fusion of the two. `body` is dropped
|
|
27
|
+
* only if the processor omitted it; it is never merged into intent.
|
|
28
|
+
*/
|
|
29
|
+
export declare function inboxPage(deps: InboxDeps, ledgerId: string, after: string | undefined, limit: number | undefined): Promise<ToolResult<unknown>>;
|
|
30
|
+
//# sourceMappingURL=inbox.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inbox.d.ts","sourceRoot":"","sources":["../src/inbox.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C,eAAO,MAAM,mBAAmB,KAAK,CAAC;AACtC;iFACiF;AACjF,eAAO,MAAM,eAAe,KAAK,CAAC;AAMlC;;kEAEkE;AAClE,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;CACnC;AAQD,iFAAiF;AACjF,wBAAsB,YAAY,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAahF;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,SAAS,CAC7B,IAAI,EAAE,SAAS,EACf,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,GAAG,SAAS,EACzB,KAAK,EAAE,MAAM,GAAG,SAAS,GACxB,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAkC9B"}
|
package/dist/inbox.js
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
// The read-only channel-consumer surface: the event processor's inbox.
|
|
2
|
+
//
|
|
3
|
+
// ⚠️ THE INBOX IS NOT ON THE NODE. It is a local queue owned by the Meerkat event processor — a
|
|
4
|
+
// SEPARATE process from the node the MCP's `config.url` points at, with its OWN HTTP read server.
|
|
5
|
+
// The processor is the one-and-only drainer of the node's ordered channel stream (Constitution V),
|
|
6
|
+
// and every delivery whose channel has no registered handler is written to a local `inbox` table
|
|
7
|
+
// the MCP reads over `GET /inbox` and `GET /inbox/<ledgerId>`. Because the endpoint is a different
|
|
8
|
+
// process, this is a thin `fetch` wrapper driven by `config.processorUrl` — NOT a `NodeClient`
|
|
9
|
+
// method, and NOT a drainer: the MCP only ever GETs, so it cannot split the stream the processor
|
|
10
|
+
// is walking.
|
|
11
|
+
//
|
|
12
|
+
// ⚠️ AN ENTRY WAS WRITTEN BY WHOEVER COULD WRITE TO THE CHANNEL. The processor proved nothing
|
|
13
|
+
// about it except that it was ordered on that channel; `sender` is the only provenance. Every
|
|
14
|
+
// tool description and non-ok prose string repeats that; the body bytes are surfaced verbatim
|
|
15
|
+
// (base64 AND hex) so a model can decode them by whatever convention it keeps, never interpreted.
|
|
16
|
+
import { ok, misconfigured, partial, unreachableFrom } from "./result.js";
|
|
17
|
+
export const INBOX_DEFAULT_LIMIT = 10;
|
|
18
|
+
/** Lower than the route's own 100 (MAX_PAGE), mirroring the other read tools' `MAX_LIMIT < node
|
|
19
|
+
* clamp` convention: a page is context the model keeps, not a dump it loses. */
|
|
20
|
+
export const INBOX_MAX_LIMIT = 50;
|
|
21
|
+
/** The read deadline on every inbox fetch. A hung processor surfaces as `unreachable`, never an
|
|
22
|
+
* indefinite hang (T-6-04). */
|
|
23
|
+
const DEADLINE_MS = 15_000;
|
|
24
|
+
const fix = () => "set `processorUrl` to the event processor's read server (e.g. http://127.0.0.1:8090); it is " +
|
|
25
|
+
"a separate process from the node, so it cannot be derived from the node `url`";
|
|
26
|
+
const jsonHeaders = { Accept: "application/json" };
|
|
27
|
+
/** Which channels have entries (or an inbox refusal), with counts and bounds. */
|
|
28
|
+
export async function inboxSummary(deps) {
|
|
29
|
+
if (!deps.processorUrl)
|
|
30
|
+
return misconfigured("the event inbox", fix());
|
|
31
|
+
const f = deps.fetchImpl ?? fetch;
|
|
32
|
+
try {
|
|
33
|
+
const res = await f(`${deps.processorUrl}/inbox`, {
|
|
34
|
+
headers: jsonHeaders,
|
|
35
|
+
signal: AbortSignal.timeout(DEADLINE_MS),
|
|
36
|
+
});
|
|
37
|
+
if (!res.ok)
|
|
38
|
+
throw new Error(`GET /inbox: HTTP ${res.status}`);
|
|
39
|
+
return ok(await res.json());
|
|
40
|
+
}
|
|
41
|
+
catch (e) {
|
|
42
|
+
return unreachableFrom(e, deps.processorUrl);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* One page of a channel's entries after `after`, with each body ALSO as hex.
|
|
47
|
+
*
|
|
48
|
+
* Hex because service protocols document their bodies in hex bytes (the LLM proxy's worked
|
|
49
|
+
* example is hex), and a model decoding base64 by eye gets bytes wrong. A malformed `after` is a
|
|
50
|
+
* refusal of the argument (`partial`), carrying the route's own statement of the expected form —
|
|
51
|
+
* never `unreachable`, which would say "retry" (the processor DID answer; it refused the
|
|
52
|
+
* argument).
|
|
53
|
+
*
|
|
54
|
+
* Intent and bytes stay SEPARATE: `txId`/`round`/`index`/`ledgerId`/`sender`/`receivedAt` are the
|
|
55
|
+
* intent (who wrote, where, when), `body` is the raw bytes as the processor returned them, and
|
|
56
|
+
* `bodyHex` is the additive hex re-encode of `body` — never a fusion of the two. `body` is dropped
|
|
57
|
+
* only if the processor omitted it; it is never merged into intent.
|
|
58
|
+
*/
|
|
59
|
+
export async function inboxPage(deps, ledgerId, after, limit) {
|
|
60
|
+
if (!deps.processorUrl)
|
|
61
|
+
return misconfigured("the event inbox", fix());
|
|
62
|
+
const f = deps.fetchImpl ?? fetch;
|
|
63
|
+
const n = Math.trunc(Number(limit));
|
|
64
|
+
const bounded = Number.isNaN(n) || n < 1 ? INBOX_DEFAULT_LIMIT : Math.min(n, INBOX_MAX_LIMIT);
|
|
65
|
+
const q = new URLSearchParams({ ...(after ? { after } : {}), limit: String(bounded) });
|
|
66
|
+
try {
|
|
67
|
+
const res = await f(`${deps.processorUrl}/inbox/${encodeURIComponent(ledgerId)}?${q.toString()}`, {
|
|
68
|
+
headers: jsonHeaders,
|
|
69
|
+
signal: AbortSignal.timeout(DEADLINE_MS),
|
|
70
|
+
});
|
|
71
|
+
if (res.status === 400) {
|
|
72
|
+
const b = (await res.json().catch(() => ({})));
|
|
73
|
+
return b.error === "bad_position"
|
|
74
|
+
? partial("after", `expected ${b.expected ?? "<round>:<index>"} — pass the \`next\` of the previous page`)
|
|
75
|
+
: partial("arguments", b.message ?? "the processor refused the request");
|
|
76
|
+
}
|
|
77
|
+
if (!res.ok)
|
|
78
|
+
throw new Error(`GET /inbox/${ledgerId}: HTTP ${res.status}`);
|
|
79
|
+
const page = (await res.json());
|
|
80
|
+
return ok({
|
|
81
|
+
...page,
|
|
82
|
+
// Intent vs bytes (never fused): `txId`/`round`/`index`/`sender` say who wrote, where, when;
|
|
83
|
+
// `body` is the raw base64 the processor stored; `bodyHex` is the additive hex re-encode of
|
|
84
|
+
// the SAME bytes. `body` is never dropped and never merged into the intent fields.
|
|
85
|
+
entries: (page.entries ?? []).map((e) => ({
|
|
86
|
+
...e,
|
|
87
|
+
bodyHex: Buffer.from(e.body ?? "", "base64").toString("hex"),
|
|
88
|
+
})),
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
catch (e) {
|
|
92
|
+
return unreachableFrom(e, deps.processorUrl);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=inbox.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inbox.js","sourceRoot":"","sources":["../src/inbox.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/** Resolve the content-listener endpoint from the environment (D-08 analog for content).
|
|
2
|
+
*
|
|
3
|
+
* ⚠️ THE CONTENT LISTENER IS A SEPARATE PORT from the chain API (`ce.evolver.content.http-port`),
|
|
4
|
+
* and it can NEVER be derived from `config.url` — that would 404 against the wrong listener, or
|
|
5
|
+
* worse, silently "work" against the wrong one. `contentUrl` is a FORBIDDEN config key for
|
|
6
|
+
* exactly this reason, so the single source is the `EVOLVER_CONTENT_URL` environment variable,
|
|
7
|
+
* read once at startup. */
|
|
8
|
+
export declare function contentUrlFromEnv(env: NodeJS.ProcessEnv): string | undefined;
|
|
9
|
+
export declare function main(): Promise<void>;
|
|
10
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAqBA;;;;;;4BAM4B;AAC5B,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,CAAC,UAAU,GAAG,MAAM,GAAG,SAAS,CAI5E;AAyFD,wBAAsB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAuG1C"}
|