@mcsherrylabs/evolver-mcp 0.13.0 → 0.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (118) hide show
  1. package/deploy/docker-compose.http.yml +45 -0
  2. package/deploy/docker-compose.yml +4 -1
  3. package/dist/application-signer.d.ts +1 -1
  4. package/dist/application-signer.d.ts.map +1 -1
  5. package/dist/attachments.d.ts +1 -1
  6. package/dist/attachments.d.ts.map +1 -1
  7. package/dist/attachments.js +2 -2
  8. package/dist/attachments.js.map +1 -1
  9. package/dist/bootstrap.d.ts +36 -4
  10. package/dist/bootstrap.d.ts.map +1 -1
  11. package/dist/bootstrap.js +35 -11
  12. package/dist/bootstrap.js.map +1 -1
  13. package/dist/content-file-tools.js +1 -1
  14. package/dist/content-file-tools.js.map +1 -1
  15. package/dist/content-files.d.ts +1 -1
  16. package/dist/content-files.d.ts.map +1 -1
  17. package/dist/content-files.js +1 -1
  18. package/dist/content-files.js.map +1 -1
  19. package/dist/content-ranges.d.ts +1 -1
  20. package/dist/content-ranges.d.ts.map +1 -1
  21. package/dist/group-crypto-tools.js +1 -1
  22. package/dist/group-crypto-tools.js.map +1 -1
  23. package/dist/group-crypto.d.ts +2 -2
  24. package/dist/group-crypto.d.ts.map +1 -1
  25. package/dist/group-crypto.js +1 -1
  26. package/dist/group-crypto.js.map +1 -1
  27. package/dist/http-transport.d.ts +87 -0
  28. package/dist/http-transport.d.ts.map +1 -0
  29. package/dist/http-transport.js +359 -0
  30. package/dist/http-transport.js.map +1 -0
  31. package/dist/inbox.d.ts +1 -1
  32. package/dist/inbox.d.ts.map +1 -1
  33. package/dist/inbox.js +1 -1
  34. package/dist/inbox.js.map +1 -1
  35. package/dist/index.d.ts.map +1 -1
  36. package/dist/index.js +254 -115
  37. package/dist/index.js.map +1 -1
  38. package/dist/install-http.d.ts +27 -0
  39. package/dist/install-http.d.ts.map +1 -0
  40. package/dist/install-http.js +192 -0
  41. package/dist/install-http.js.map +1 -0
  42. package/dist/install.d.ts +18 -0
  43. package/dist/install.d.ts.map +1 -1
  44. package/dist/install.js +128 -22
  45. package/dist/install.js.map +1 -1
  46. package/dist/login.d.ts +1 -1
  47. package/dist/login.d.ts.map +1 -1
  48. package/dist/mcp.d.ts +2 -2
  49. package/dist/mcp.d.ts.map +1 -1
  50. package/dist/p2p.d.ts +1 -1
  51. package/dist/p2p.d.ts.map +1 -1
  52. package/dist/p2p.js +1 -1
  53. package/dist/p2p.js.map +1 -1
  54. package/dist/processor.d.ts +1 -1
  55. package/dist/processor.d.ts.map +1 -1
  56. package/dist/processor.js +1 -1
  57. package/dist/processor.js.map +1 -1
  58. package/dist/signed-http.d.ts +1 -1
  59. package/dist/signed-http.d.ts.map +1 -1
  60. package/dist/tools.d.ts +5 -3
  61. package/dist/tools.d.ts.map +1 -1
  62. package/dist/tools.js +34 -34
  63. package/dist/tools.js.map +1 -1
  64. package/dist/transaction-interchange-tools.js +1 -1
  65. package/dist/transaction-interchange-tools.js.map +1 -1
  66. package/dist/transaction-interchange.d.ts +5 -2
  67. package/dist/transaction-interchange.d.ts.map +1 -1
  68. package/dist/transaction-interchange.js +10 -10
  69. package/dist/transaction-interchange.js.map +1 -1
  70. package/package.json +10 -16
  71. package/dist/amount.d.ts +0 -23
  72. package/dist/amount.d.ts.map +0 -1
  73. package/dist/amount.js +0 -53
  74. package/dist/amount.js.map +0 -1
  75. package/dist/channel.d.ts +0 -77
  76. package/dist/channel.d.ts.map +0 -1
  77. package/dist/channel.js +0 -287
  78. package/dist/channel.js.map +0 -1
  79. package/dist/claim.d.ts +0 -48
  80. package/dist/claim.d.ts.map +0 -1
  81. package/dist/claim.js +0 -81
  82. package/dist/claim.js.map +0 -1
  83. package/dist/content.d.ts +0 -94
  84. package/dist/content.d.ts.map +0 -1
  85. package/dist/content.js +0 -215
  86. package/dist/content.js.map +0 -1
  87. package/dist/group-ownership.d.ts +0 -78
  88. package/dist/group-ownership.d.ts.map +0 -1
  89. package/dist/group-ownership.js +0 -324
  90. package/dist/group-ownership.js.map +0 -1
  91. package/dist/group.d.ts +0 -60
  92. package/dist/group.d.ts.map +0 -1
  93. package/dist/group.js +0 -204
  94. package/dist/group.js.map +0 -1
  95. package/dist/identity.d.ts +0 -87
  96. package/dist/identity.d.ts.map +0 -1
  97. package/dist/identity.js +0 -236
  98. package/dist/identity.js.map +0 -1
  99. package/dist/node-transport.d.ts +0 -14
  100. package/dist/node-transport.d.ts.map +0 -1
  101. package/dist/node-transport.js +0 -54
  102. package/dist/node-transport.js.map +0 -1
  103. package/dist/read.d.ts +0 -252
  104. package/dist/read.d.ts.map +0 -1
  105. package/dist/read.js +0 -320
  106. package/dist/read.js.map +0 -1
  107. package/dist/result.d.ts +0 -110
  108. package/dist/result.d.ts.map +0 -1
  109. package/dist/result.js +0 -97
  110. package/dist/result.js.map +0 -1
  111. package/dist/signer.d.ts +0 -37
  112. package/dist/signer.d.ts.map +0 -1
  113. package/dist/signer.js +0 -76
  114. package/dist/signer.js.map +0 -1
  115. package/dist/write.d.ts +0 -214
  116. package/dist/write.d.ts.map +0 -1
  117. package/dist/write.js +0 -399
  118. package/dist/write.js.map +0 -1
@@ -1,324 +0,0 @@
1
- // Group OWNERSHIP transfer (issue #9) — a two-party prepare → consent → finalize → submit workflow.
2
- // NOT a credit transfer: `evolver_sign_transfer_many` moves credit; this hands a group to a new owner.
3
- //
4
- // The chain applies `TransferGroupOwnershipTxBody` only when the SignedTx carries an auth whose
5
- // `node_id` is the incoming owner (GroupLedgerOrchestrator.applyTransferOwnership), and admission
6
- // verifies EVERY auth against the named identity's REGISTERED (node_id, key_type, key_label) key
7
- // over the same auth-free digest (BlockPayloadValidator.admitFilter / resolveAuths). So:
8
- //
9
- // 1. PREPARE (outgoing owner's session) — composes the intent with the SDK body composer and the
10
- // SDK canonical digest. Signs NOTHING and records no bytes, so `evolver_submit` cannot find it.
11
- // 2. CONSENT (incoming owner's session, its own host-held key) — recomputes the digest from the
12
- // structured intent, refuses a mismatching txId, signs the digest with ITS signer and returns
13
- // one public auth. It never holds a submittable envelope.
14
- // 3. FINALIZE (outgoing owner's session) — re-reads the chain, verifies the consent signature
15
- // against the incoming owner's REGISTERED key, then signs as sender and assembles BOTH auths
16
- // with the SDK `encodeSignedTx`. Recorded once, strictly, by id.
17
- // 4. `evolver_submit` — the ordinary path and its guards, unchanged.
18
- //
19
- // ⚠️ THE txId IS AUTH-FREE. SDK `txId` = node `signingMaterial` = SHA-256 over the tx-auth tag,
20
- // ledger, sender, ttl, body hash and maxToll — no auths (SignedTxOps.txId, signed_tx.proto). So the
21
- // prepared id, the consented id and the submitted id are one value; finalize re-derives and checks
22
- // it rather than assuming.
23
- //
24
- // ⚠️ ONLY Ed25519 CONSENT IS ACCEPTED BY THIS WORKFLOW. Verifying before assembly is the point;
25
- // a BLS consent remains refused locally, never assembled blind or verified by a hand-rolled
26
- // pairing check. Published SDK 0.22.0 `edVerify` uses strict RFC 8032 verification (`zip215:false`),
27
- // matching the node's strict Ed25519 mode rather than the former permissive ZIP215 behavior.
28
- // This dependency update does not broaden accepted consent algorithms or remove local guards.
29
- //
30
- // ⚠️ KEY MATERIAL NEVER ENTERS OR LEAVES. Arguments and results carry names, the digest-bound
31
- // intent, key type/label and the single consent signature; never a private key or signed envelope.
32
- //
33
- // ⚠️ THE CONSENT IS SAFE TO HAND OVER ONLY ON A NODE THAT REQUIRES THE SENDER'S OWN AUTH. Before
34
- // the #9 node fix, admission/validation/apply accepted ANY verified auth, so the incoming owner's
35
- // consent alone was a submittable transfer "from" the outgoing owner: a bearer artefact that seized
36
- // the group and charged a sender who never signed. Every step therefore refuses unless the
37
- // connected node's /status says `senderAuthorizationRequired: true` (SDK `nodeStatus`). That is
38
- // the connected node's assertion only: the whole chain must run compatible nodes (a deployment
39
- // prerequisite, not something this process can verify), and the canonical digest has no chain id,
40
- // so a consent remains replayable on another chain with the same names/keys until it expires.
41
- import { LEDGER, encodeSignedTx, txId as txDigest, transferGroupOwnershipBody, isValidGroupName, isValidNodeId, hexToBytes, edVerify, edSpkiToRaw, } from "@mcsherrylabs/evolver-client";
42
- import { recordAssembledOnce, recordPendingOwnership, pendingOwnershipById, dropPendingOwnership, pruneExpiredPendingOwnership, recordedById, namedInRefusal, MAX_PENDING_OWNERSHIP, } from "./write.js";
43
- /** Rounds of life for a two-party transfer. Longer than `DEFAULT_TTL_OFFSET` (50, sized for no
44
- * human wait) because a second party must act, but never beyond the node's default
45
- * `max-ttl-offset` (RoutingConfig.DefaultMaxTtlOffset = 100): a longer ttl is `ttl_too_far`, and
46
- * a long-lived co-signed envelope is a bearer artefact. The default stays 10 rounds inside that
47
- * bound so the two parties' nodes may disagree slightly about the tip. Expiry is final. */
48
- export const OWNERSHIP_TTL_MAX = 100;
49
- export const OWNERSHIP_TTL_DEFAULT = 90;
50
- /** The one key type whose consent can be verified with a published SDK primitive. */
51
- export const CONSENT_KEY_TYPE = "Ed25519";
52
- export const INTENT_KIND = "evolver.group_ownership_intent.v1";
53
- export const CONSENT_KIND = "evolver.group_ownership_consent.v1";
54
- const PURPOSE = "AUTHORIZE"; // TxAuth.purpose default; encodeSignedTx writes no other.
55
- const MAX_LABEL = 128;
56
- const refuse = (what, cause) => ({ kind: "partial", what, cause });
57
- const unreachable = (e) => ({ kind: "unreachable", chain: "", cause: e instanceof Error ? e.message : String(e) });
58
- const hex = (b) => Buffer.from(b).toString("hex");
59
- const str = (v) => (typeof v === "string" ? v.trim() : "");
60
- /** The canonical digest (== txId) for one transfer intent, from the SDK composer and SDK digest.
61
- * maxToll is 0: the groups ledger charges no toll and this workflow consents to none. */
62
- function digestFor(outgoing, groupName, incoming, ttl) {
63
- const body = transferGroupOwnershipBody({ groupName, newOwnerNodeId: incoming });
64
- return { body, digest: txDigest(LEDGER.groups, outgoing, ttl, body, 0n) };
65
- }
66
- /** Refusals shared by every step, before any read: names and the outgoing/incoming distinction. */
67
- function validNames(groupName, outgoing, incoming) {
68
- if (!isValidGroupName(groupName))
69
- return refuse("groupName", "not a valid group name");
70
- if (!isValidNodeId(outgoing))
71
- return refuse("outgoingOwner", "not a valid identity id");
72
- if (!isValidNodeId(incoming))
73
- return refuse("incomingOwner", "not a valid identity id");
74
- if (outgoing === incoming)
75
- return refuse("incomingOwner", "the incoming owner equals the outgoing owner — the chain fines that rather than refusing it");
76
- return null;
77
- }
78
- /** Chain facts the chain will itself enforce at apply (a mismatch is a FINE, too late to refuse):
79
- * the group's committed owner, and that the incoming owner is an existing identity, not a group. */
80
- async function checkChainFacts(reads, groupName, outgoing, incoming) {
81
- try {
82
- const listed = (await reads.listGroups()).find((g) => g.ledgerId === groupName);
83
- if (listed === undefined)
84
- return { kind: "not_found", what: `group "${groupName}"` };
85
- if (listed.owner !== outgoing)
86
- return refuse("outgoingOwner", `group "${groupName}" is owned by "${listed.owner}" at the node's applied state, not "${outgoing}"`);
87
- if ((await reads.getGroup(incoming)) !== null)
88
- return refuse("incomingOwner", `"${incoming}" is a group; only an identity can own a group`);
89
- if ((await reads.getIdentity(incoming)) === null)
90
- return { kind: "not_found", what: `identity "${incoming}" (incoming owner)` };
91
- }
92
- catch (e) {
93
- return unreachable(e);
94
- }
95
- return null;
96
- }
97
- /** Freshness under the chain's own admit rule: `tip < ttl <= tip + max-ttl-offset`. */
98
- function checkFresh(tip, expiresAtRound) {
99
- if (expiresAtRound <= tip)
100
- return refuse("expiresAtRound", `expired: round ${expiresAtRound} is not after the current round ${tip}. Expiry is final; prepare a NEW transfer (a new txId) rather than reusing this one`);
101
- if (expiresAtRound - tip > OWNERSHIP_TTL_MAX)
102
- return refuse("expiresAtRound", `round ${expiresAtRound} is more than ${OWNERSHIP_TTL_MAX} rounds after the current round ${tip}; refused as over-long`);
103
- return null;
104
- }
105
- /** The incoming owner's REGISTERED key for (identity, Ed25519, label), raw 32 bytes. Knowing a
106
- * public key is not authority; only the chain's registration of it for this identity is. */
107
- async function registeredEdKey(reads, who, keyLabel) {
108
- let rows;
109
- try {
110
- rows = await reads.getIdentityKeys(who);
111
- }
112
- catch (e) {
113
- return unreachable(e);
114
- }
115
- if (rows === null)
116
- return { kind: "not_found", what: `identity "${who}"` };
117
- const match = rows.filter((r) => r.keyType === CONSENT_KEY_TYPE && r.label === keyLabel);
118
- if (match.length !== 1)
119
- return refuse("consent.auth", `"${who}" has no single registered ${CONSENT_KEY_TYPE} key labelled "${keyLabel}" at the node's applied state (unknown_key on chain)`);
120
- try {
121
- return edSpkiToRaw(hexToBytes(match[0].publicKeyHex));
122
- }
123
- catch {
124
- return refuse("consent.auth", `the registered ${CONSENT_KEY_TYPE} key for "${who}" is not a recognisable Ed25519 public key`);
125
- }
126
- }
127
- /** Fail closed unless the CONNECTED node states it requires the sender's own AUTHORIZE auth.
128
- * Absent/null/false/non-boolean is unsupported (`partial`); a failed read is `unreachable`. */
129
- async function requireSenderAuthorizationNode(reads) {
130
- let flag;
131
- try {
132
- flag = (await reads.nodeStatus()).senderAuthorizationRequired;
133
- }
134
- catch (e) {
135
- return unreachable(e);
136
- }
137
- if (flag === true)
138
- return null;
139
- return refuse("node", "the connected node does not advertise senderAuthorizationRequired: true. On such a node the " +
140
- "incoming owner's consent alone could be submitted as a transfer the outgoing owner never signed, " +
141
- "so nothing is prepared, signed or returned. Use a node (and a chain) running the sender-authorization fix.");
142
- }
143
- async function tip(reads) {
144
- try {
145
- return await reads.currentRound();
146
- }
147
- catch (e) {
148
- return unreachable(e);
149
- }
150
- }
151
- /**
152
- * PREPARE (outgoing owner). Signs nothing; returns the public intent for the incoming owner.
153
- */
154
- export async function prepareOwnershipTransfer(deps, params) {
155
- const groupName = str(params.groupName), incoming = str(params.incomingOwner), outgoing = deps.identity;
156
- const bad = validNames(groupName, outgoing, incoming);
157
- if (bad)
158
- return bad;
159
- const ttlRounds = params.ttlRounds === undefined ? OWNERSHIP_TTL_DEFAULT : params.ttlRounds;
160
- if (typeof ttlRounds !== "number" || !Number.isSafeInteger(ttlRounds) || ttlRounds < 1 || ttlRounds > OWNERSHIP_TTL_MAX)
161
- return refuse("ttlRounds", `must be an integer 1..${OWNERSHIP_TTL_MAX} (the node's default max-ttl-offset)`);
162
- const policy = await requireSenderAuthorizationNode(deps.reads);
163
- if (policy)
164
- return policy;
165
- const facts = await checkChainFacts(deps.reads, groupName, outgoing, incoming);
166
- if (facts)
167
- return facts;
168
- const now = await tip(deps.reads);
169
- if (typeof now !== "number")
170
- return now;
171
- const expiresAtRound = now + ttlRounds;
172
- const id = hex(digestFor(outgoing, groupName, incoming, expiresAtRound).digest);
173
- const fields = { ledgerId: LEDGER.groups, groupName, outgoingOwner: outgoing, incomingOwner: incoming, maxToll: "0" };
174
- const pending = {
175
- txId: id, expiresAtRound, preparedAtRound: now, verb: "group_ownership_transfer_pending", fields,
176
- summary: { sender: outgoing, ...fields },
177
- status: "awaiting incoming-owner consent: NOT signed by this session and NOT submittable",
178
- };
179
- if (recordedById(id) !== undefined || pendingOwnershipById(id) !== undefined)
180
- return refuse("txId", `transfer ${id} is already prepared or finalized in this session`);
181
- pruneExpiredPendingOwnership(now);
182
- if (!recordPendingOwnership(pending))
183
- return refuse("pending", `at most ${MAX_PENDING_OWNERSHIP} prepared transfers may await consent per session`);
184
- return {
185
- kind: "ok",
186
- value: {
187
- kind: INTENT_KIND, txId: id, ...fields, maxToll: "0", expiresAtRound, preparedAtRound: now,
188
- next: `Send these public fields to "${incoming}". Their own MCP session calls evolver_group_ownership_consent ` +
189
- `with them; then call evolver_group_ownership_finalize here with the returned consent before round ${expiresAtRound}.`,
190
- },
191
- };
192
- }
193
- /**
194
- * CONSENT (incoming owner). Recomputes the intent's txId and signs it with THIS session's key.
195
- */
196
- export async function consentOwnershipTransfer(deps, params) {
197
- const groupName = str(params.groupName), outgoing = str(params.outgoingOwner), incoming = str(params.incomingOwner);
198
- const claimedId = str(params.txId).toLowerCase();
199
- const expiresAtRound = params.expiresAtRound;
200
- if (incoming !== deps.identity)
201
- return refuse("incomingOwner", `this session signs as "${deps.identity}", not "${incoming || "(empty)"}"; only the incoming owner's own session can consent`);
202
- const bad = validNames(groupName, outgoing, incoming);
203
- if (bad)
204
- return bad;
205
- if (typeof expiresAtRound !== "number" || !Number.isSafeInteger(expiresAtRound) || expiresAtRound < 1)
206
- return refuse("expiresAtRound", "must be a positive integer round");
207
- if (!/^[0-9a-f]{64}$/.test(claimedId))
208
- return refuse("txId", "must be the 64-character hex txId from the intent");
209
- if (deps.signer.keyType !== CONSENT_KEY_TYPE)
210
- return refuse("signer", `this session's key is ${deps.signer.keyType}; the outgoing owner can verify only ${CONSENT_KEY_TYPE} consent ` +
211
- `(SDK 0.21.0 exports no BLS verify). Use a session configured with this identity's registered Ed25519 key (EVOLVER_KEY_TYPE=ed25519). Nothing was signed.`);
212
- const { digest } = digestFor(outgoing, groupName, incoming, expiresAtRound);
213
- if (hex(digest) !== claimedId)
214
- return refuse("txId", `the intent's txId ${namedInRefusal(claimedId)} does not match the transfer these fields describe; nothing was signed`);
215
- // Before signing: an old node would let this consent stand alone as the sender's transfer.
216
- const policy = await requireSenderAuthorizationNode(deps.reads);
217
- if (policy)
218
- return policy;
219
- const now = await tip(deps.reads);
220
- if (typeof now !== "number")
221
- return now;
222
- const stale = checkFresh(now, expiresAtRound);
223
- if (stale)
224
- return stale;
225
- const facts = await checkChainFacts(deps.reads, groupName, outgoing, incoming);
226
- if (facts)
227
- return facts;
228
- // The configured key must be the one the chain will verify against: sign, then check our own
229
- // signature against the registered key, so a wrong key file fails here rather than at admit.
230
- const pub = await registeredEdKey(deps.reads, incoming, deps.signer.keyLabel);
231
- if (!(pub instanceof Uint8Array))
232
- return pub;
233
- const signature = deps.signer.sign(digest);
234
- if (!edVerify(digest, signature, pub))
235
- return refuse("signer", `this session's Ed25519 key is not the key registered for "${incoming}"; the consent was discarded`);
236
- return {
237
- kind: "ok",
238
- value: {
239
- kind: CONSENT_KIND, txId: claimedId, ledgerId: LEDGER.groups, groupName, outgoingOwner: outgoing,
240
- incomingOwner: incoming, expiresAtRound, maxToll: "0",
241
- auth: { nodeId: incoming, keyType: deps.signer.keyType, keyLabel: deps.signer.keyLabel, purpose: PURPOSE, signatureHex: hex(signature) },
242
- next: `Return this consent to "${outgoing}". It authorizes ONLY txId ${claimedId}, which expires at round ` +
243
- `${expiresAtRound}; it does not submit anything and cannot be used for any other operation.`,
244
- },
245
- };
246
- }
247
- /**
248
- * FINALIZE (outgoing owner). Verifies the consent, signs as sender, assembles both auths, records.
249
- */
250
- export async function finalizeOwnershipTransfer(deps, params) {
251
- const id = str(params.txId).toLowerCase();
252
- if (recordedById(id) !== undefined)
253
- return refuse("txId", `transfer ${namedInRefusal(id)} is already finalized in this session; submit or reconcile that id, never finalize again`);
254
- const pending = pendingOwnershipById(id);
255
- if (pending === undefined)
256
- return refuse("txId", `no transfer ${namedInRefusal(id)} was prepared by this session; only a transfer prepared here can be finalized`);
257
- const f = pending.fields;
258
- if (f.outgoingOwner !== deps.identity)
259
- return refuse("txId", "prepared for a different sender");
260
- // The consent must describe exactly the prepared intent — every field, not just the id.
261
- const c = (typeof params.consent === "object" && params.consent !== null ? params.consent : {});
262
- const a = (typeof c["auth"] === "object" && c["auth"] !== null ? c["auth"] : {});
263
- if (c["kind"] !== CONSENT_KIND)
264
- return refuse("consent.kind", `must be "${CONSENT_KIND}"`);
265
- // Hex case carries no meaning; compare the canonical lowercase form (the id is already lowercase).
266
- const consentId = typeof c["txId"] === "string" ? c["txId"].trim().toLowerCase() : c["txId"];
267
- const mismatch = [
268
- ["txId", consentId, id], ["ledgerId", c["ledgerId"], f.ledgerId], ["groupName", c["groupName"], f.groupName],
269
- ["outgoingOwner", c["outgoingOwner"], f.outgoingOwner], ["incomingOwner", c["incomingOwner"], f.incomingOwner],
270
- ["expiresAtRound", c["expiresAtRound"], pending.expiresAtRound], ["maxToll", c["maxToll"], f.maxToll],
271
- ["auth.nodeId", a["nodeId"], f.incomingOwner], ["auth.purpose", a["purpose"], PURPOSE],
272
- ].find(([, got, want]) => got !== want);
273
- if (mismatch)
274
- return refuse(`consent.${mismatch[0]}`, "does not match the prepared transfer (wrong intent, principal or purpose); nothing was signed");
275
- const keyType = a["keyType"], keyLabel = a["keyLabel"], sigHex = a["signatureHex"];
276
- if (keyType !== CONSENT_KEY_TYPE)
277
- return refuse("consent.auth.keyType", `only ${CONSENT_KEY_TYPE} consent can be verified (SDK 0.21.0 exports no BLS verify); nothing was signed`);
278
- if (typeof keyLabel !== "string" || keyLabel.length > MAX_LABEL)
279
- return refuse("consent.auth.keyLabel", "must be a string of at most 128 characters");
280
- if (typeof sigHex !== "string" || !/^[0-9a-f]{128}$/.test(sigHex))
281
- return refuse("consent.auth.signatureHex", "must be a 64-byte Ed25519 signature as lowercase hex");
282
- // Re-derive the digest from the prepared fields with the SDK: the id must still be the intent.
283
- const { body, digest } = digestFor(f.outgoingOwner, f.groupName, f.incomingOwner, pending.expiresAtRound);
284
- if (hex(digest) !== id)
285
- return refuse("txId", "the prepared fields no longer derive this txId; refused");
286
- // Rechecked at finalization: the session may now be pointed at (or answered by) an older node.
287
- const policy = await requireSenderAuthorizationNode(deps.reads);
288
- if (policy)
289
- return policy;
290
- const now = await tip(deps.reads);
291
- if (typeof now !== "number")
292
- return now;
293
- const stale = checkFresh(now, pending.expiresAtRound);
294
- if (stale)
295
- return stale;
296
- const facts = await checkChainFacts(deps.reads, f.groupName, f.outgoingOwner, f.incomingOwner);
297
- if (facts)
298
- return facts;
299
- const pub = await registeredEdKey(deps.reads, f.incomingOwner, keyLabel);
300
- if (!(pub instanceof Uint8Array))
301
- return pub;
302
- if (!edVerify(digest, hexToBytes(sigHex), pub))
303
- return refuse("consent.auth.signatureHex", `does not verify for txId ${id} under "${f.incomingOwner}"'s registered ${CONSENT_KEY_TYPE} key; nothing was signed`);
304
- // Verified. Sign as sender (empty node_id ⇒ the sender) and assemble with the SDK encoder.
305
- const auths = [
306
- { keyType: deps.signer.keyType, keyLabel: deps.signer.keyLabel, nodeId: "", signature: deps.signer.sign(digest) },
307
- { keyType: CONSENT_KEY_TYPE, keyLabel, nodeId: f.incomingOwner, signature: hexToBytes(sigHex) },
308
- ];
309
- const bytes = encodeSignedTx({ ledgerId: LEDGER.groups, senderNodeId: f.outgoingOwner, body, ttlRound: pending.expiresAtRound, auths, maxToll: 0n });
310
- const fields = {
311
- groupName: f.groupName, outgoingOwner: f.outgoingOwner, incomingOwner: f.incomingOwner, maxToll: "0",
312
- outgoingAuth: `${f.outgoingOwner} ${deps.signer.keyType} label="${deps.signer.keyLabel}"`,
313
- incomingAuth: `${f.incomingOwner} ${CONSENT_KEY_TYPE} label="${keyLabel}" (verified against registered key at round ${now})`,
314
- };
315
- const signed = {
316
- txId: id, expiresAtRound: pending.expiresAtRound, signedAtRound: now, verb: "group_ownership_transfer",
317
- fields, summary: { sender: f.outgoingOwner, ...fields },
318
- };
319
- if (!recordAssembledOnce(signed, bytes))
320
- return refuse("txId", `transfer ${id} is already recorded in this session; nothing was replaced`);
321
- dropPendingOwnership(id);
322
- return { kind: "ok", value: signed };
323
- }
324
- //# sourceMappingURL=group-ownership.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"group-ownership.js","sourceRoot":"","sources":["../src/group-ownership.ts"],"names":[],"mappings":"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"}
package/dist/group.d.ts DELETED
@@ -1,60 +0,0 @@
1
- import type { Signer } from "@mcsherrylabs/evolver-client";
2
- import type { ChainReads } from "./read.js";
3
- import type { SignedGroup } from "./write.js";
4
- import type { ToolResult } from "./result.js";
5
- /** What the group verbs need from the world. NO `submitTx` — deliberately: the signing verbs submit
6
- * nothing, so the capability is not present to reach for (zero-submit is structural). */
7
- export interface GroupOpsDeps {
8
- readonly identity: string;
9
- readonly signer: Signer;
10
- readonly ttlOffset?: number;
11
- readonly reads: ChainReads;
12
- }
13
- /** A signed groups-ledger operation, as returned by a signing verb. */
14
- export type GroupSignResult = ToolResult<SignedGroup>;
15
- /**
16
- * Create a new group (SIGN-09), signed for `deps.identity`. The name is validated STRUCTURALLY before
17
- * anything is signed — the chain FINES an invalid name rather than refusing it.
18
- */
19
- export declare function signCreateGroup(deps: GroupOpsDeps, params: {
20
- name: string;
21
- }): Promise<GroupSignResult>;
22
- /**
23
- * Delete a group (SIGN-10). The name is validated structurally before anything is signed. Ownership
24
- * is NOT checked locally — a delete by a non-owner is chain-enforced and surfaces as an
25
- * `invalid_group_body` fine via `classifySubmit`, not as a local refusal.
26
- */
27
- export declare function signDeleteGroup(deps: GroupOpsDeps, params: {
28
- name: string;
29
- }): Promise<GroupSignResult>;
30
- /**
31
- * Add a member to a group (SIGN-11). Refusals fire FIRST, in order: invalid group name, empty member
32
- * id, self-add, invalid node id — then the chain read, then compose.
33
- */
34
- export declare function signAddMember(deps: GroupOpsDeps, params: {
35
- groupName: string;
36
- memberNodeId: string;
37
- }): Promise<GroupSignResult>;
38
- /**
39
- * Remove a member from a group (SIGN-12). Same refusal order as add-member (invalid name, empty id,
40
- * self-add, invalid id) BEFORE the chain read.
41
- */
42
- export declare function signRemoveMember(deps: GroupOpsDeps, params: {
43
- groupName: string;
44
- memberNodeId: string;
45
- }): Promise<GroupSignResult>;
46
- /**
47
- * Multi-recipient credit transfer (SIGN-02): move credit from the signing identity to 1..20
48
- * recipients. This is the plain `transferBody` on `LEDGER.identity` — NOT a group-membership encoder
49
- * and NOT an ownership transfer (that needs the incoming owner's co-signature and lives in
50
- * `src/group-ownership.ts`). "One verb = one tx"; the multi-entry array is the ONE thing that
51
- * distinguishes it from the singleton `evolver_sign_transfer`. Order is significant — it decides
52
- * which transfer survives a short-balance apply.
53
- */
54
- export declare function signGroupTransfer(deps: GroupOpsDeps, params: {
55
- entries: Array<{
56
- recipient: string;
57
- amount: string;
58
- }>;
59
- }): Promise<GroupSignResult>;
60
- //# sourceMappingURL=group.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"group.d.ts","sourceRoot":"","sources":["../src/group.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,8BAA8B,CAAC;AAE3D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAE5C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C;0FAC0F;AAC1F,MAAM,WAAW,YAAY;IAC3B,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,uEAAuE;AACvE,MAAM,MAAM,eAAe,GAAG,UAAU,CAAC,WAAW,CAAC,CAAC;AAetD;;;GAGG;AACH,wBAAsB,eAAe,CACnC,IAAI,EAAE,YAAY,EAClB,MAAM,EAAE;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GACvB,OAAO,CAAC,eAAe,CAAC,CAqB1B;AAkCD;;;;GAIG;AACH,wBAAsB,eAAe,CACnC,IAAI,EAAE,YAAY,EAClB,MAAM,EAAE;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GACvB,OAAO,CAAC,eAAe,CAAC,CAgB1B;AAED;;;GAGG;AACH,wBAAsB,aAAa,CACjC,IAAI,EAAE,YAAY,EAClB,MAAM,EAAE;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,GAClD,OAAO,CAAC,eAAe,CAAC,CAkB1B;AAED;;;GAGG;AACH,wBAAsB,gBAAgB,CACpC,IAAI,EAAE,YAAY,EAClB,MAAM,EAAE;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,GAClD,OAAO,CAAC,eAAe,CAAC,CAkB1B;AAED;;;;;;;GAOG;AACH,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,YAAY,EAClB,MAAM,EAAE;IAAE,OAAO,EAAE,KAAK,CAAC;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAAE,GAChE,OAAO,CAAC,eAAe,CAAC,CA2C1B"}
package/dist/group.js DELETED
@@ -1,204 +0,0 @@
1
- // Groups-ledger signing verbs (SIGN-09..12) plus the multi-recipient group credit transfer
2
- // (SIGN-02). Each is a compose→sign→record→return-txId operation with ZERO submit, mirroring the
3
- // identity verbs in `src/identity.ts` and resolving in the SAME `submitSigned`/`inspectSigned` path.
4
- //
5
- // The ledger is pinned to `LEDGER.groups` for the four membership verbs (never a caller-chosen id),
6
- // and to `LEDGER.identity` for the credit transfer (credit lives on identities; a group holds no
7
- // balance). Nothing here can reach a node before `evolver_submit`. The costly local refusals —
8
- // invalid group name, empty/invalid member id, self-add, a bad transfer entry — fire BEFORE anything
9
- // is signed, because the chain's answer for a malformed body arrives as a FINE, too late to refuse
10
- // (Pitfalls 4/5).
11
- //
12
- // ⚠️ KEY MATERIAL NEVER REACHES A RECORD OR A REFUSAL. Records carry the group name and member node
13
- // id and decimal amount strings only; refusals name the FIELD/PATH, never the bytes.
14
- import { LEDGER, createGroupBody, deleteGroupBody, addMemberBody, removeMemberBody, transferBody } from "@mcsherrylabs/evolver-client";
15
- import { isValidGroupName, isValidNodeId } from "@mcsherrylabs/evolver-client";
16
- import { parseAmount, formatAmount } from "./amount.js";
17
- import { DEFAULT_TTL_OFFSET, composeAndSign } from "./write.js";
18
- /** Read the chain tip to bound a transaction's life; an unreachable chain is `unreachable`, never a
19
- * submit. */
20
- async function tipOrUnreachable(deps) {
21
- try {
22
- return await deps.reads.currentRound();
23
- }
24
- catch (e) {
25
- return { kind: "unreachable", chain: "", cause: e instanceof Error ? e.message : String(e) };
26
- }
27
- }
28
- /** The maximum number of recipients an on-chain credit transfer carries (the node's own 1..20 rule). */
29
- const MAX_TRANSFER_ENTRIES = 20;
30
- /**
31
- * Create a new group (SIGN-09), signed for `deps.identity`. The name is validated STRUCTURALLY before
32
- * anything is signed — the chain FINES an invalid name rather than refusing it.
33
- */
34
- export async function signCreateGroup(deps, params) {
35
- const name = String(params.name ?? "").trim();
36
- if (!isValidGroupName(name))
37
- return {
38
- kind: "partial",
39
- what: "name",
40
- cause: `"${name}" is not a valid group name — the chain fines an invalid name rather than refusing it, so it is refused here`,
41
- };
42
- const tip = await tipOrUnreachable(deps);
43
- if (typeof tip !== "number")
44
- return tip;
45
- const expiresAtRound = tip + (deps.ttlOffset ?? DEFAULT_TTL_OFFSET);
46
- return composeAndSign(deps, {
47
- ledgerId: LEDGER.groups, // hard-pinned, never caller-chosen
48
- body: createGroupBody(name),
49
- ttlRound: expiresAtRound,
50
- signedAtRound: tip,
51
- verb: "create_group",
52
- fields: { groupName: name },
53
- });
54
- }
55
- /** The refusal shared by the three member/file verbs: validate the group name BEFORE anything is
56
- * read or signed (the chain fines, it does not refuse, an invalid name). */
57
- function validGroupName(name) {
58
- if (!isValidGroupName(name))
59
- return {
60
- kind: "partial",
61
- what: "name",
62
- cause: `"${name}" is not a valid group name — the chain fines an invalid name rather than refusing it, so it is refused here`,
63
- };
64
- return name;
65
- }
66
- /** The refusal shared by add/remove-member: the member id must be non-empty, not the sender, and a
67
- * syntactically valid node id — all refused BEFORE the chain read (the chain fines these). */
68
- function validMemberId(memberNodeId, identity) {
69
- if (memberNodeId.length === 0)
70
- return { kind: "partial", what: "memberNodeId", cause: "no member id given" };
71
- if (memberNodeId === identity)
72
- return {
73
- kind: "partial",
74
- what: "memberNodeId",
75
- cause: `adding or removing "${identity}" (this agent) is a semantic no-op worth refusing cheaply — a group's owner is not its own member`,
76
- };
77
- if (!isValidNodeId(memberNodeId))
78
- return {
79
- kind: "partial",
80
- what: "memberNodeId",
81
- cause: `"${memberNodeId}" is not a valid node id — the chain fines an invalid id rather than refusing it, so it is refused here`,
82
- };
83
- return memberNodeId;
84
- }
85
- /**
86
- * Delete a group (SIGN-10). The name is validated structurally before anything is signed. Ownership
87
- * is NOT checked locally — a delete by a non-owner is chain-enforced and surfaces as an
88
- * `invalid_group_body` fine via `classifySubmit`, not as a local refusal.
89
- */
90
- export async function signDeleteGroup(deps, params) {
91
- const groupName = validGroupName(String(params.name ?? "").trim());
92
- if (typeof groupName !== "string")
93
- return groupName;
94
- const tip = await tipOrUnreachable(deps);
95
- if (typeof tip !== "number")
96
- return tip;
97
- const expiresAtRound = tip + (deps.ttlOffset ?? DEFAULT_TTL_OFFSET);
98
- return composeAndSign(deps, {
99
- ledgerId: LEDGER.groups,
100
- body: deleteGroupBody(groupName),
101
- ttlRound: expiresAtRound,
102
- signedAtRound: tip,
103
- verb: "delete_group",
104
- fields: { groupName },
105
- });
106
- }
107
- /**
108
- * Add a member to a group (SIGN-11). Refusals fire FIRST, in order: invalid group name, empty member
109
- * id, self-add, invalid node id — then the chain read, then compose.
110
- */
111
- export async function signAddMember(deps, params) {
112
- const groupName = validGroupName(String(params.groupName ?? "").trim());
113
- if (typeof groupName !== "string")
114
- return groupName;
115
- const member = validMemberId(String(params.memberNodeId ?? "").trim(), deps.identity);
116
- if (typeof member !== "string")
117
- return member;
118
- const tip = await tipOrUnreachable(deps);
119
- if (typeof tip !== "number")
120
- return tip;
121
- const expiresAtRound = tip + (deps.ttlOffset ?? DEFAULT_TTL_OFFSET);
122
- return composeAndSign(deps, {
123
- ledgerId: LEDGER.groups,
124
- body: addMemberBody(groupName, member),
125
- ttlRound: expiresAtRound,
126
- signedAtRound: tip,
127
- verb: "add_member",
128
- fields: { groupName, memberNodeId: member },
129
- });
130
- }
131
- /**
132
- * Remove a member from a group (SIGN-12). Same refusal order as add-member (invalid name, empty id,
133
- * self-add, invalid id) BEFORE the chain read.
134
- */
135
- export async function signRemoveMember(deps, params) {
136
- const groupName = validGroupName(String(params.groupName ?? "").trim());
137
- if (typeof groupName !== "string")
138
- return groupName;
139
- const member = validMemberId(String(params.memberNodeId ?? "").trim(), deps.identity);
140
- if (typeof member !== "string")
141
- return member;
142
- const tip = await tipOrUnreachable(deps);
143
- if (typeof tip !== "number")
144
- return tip;
145
- const expiresAtRound = tip + (deps.ttlOffset ?? DEFAULT_TTL_OFFSET);
146
- return composeAndSign(deps, {
147
- ledgerId: LEDGER.groups,
148
- body: removeMemberBody(groupName, member),
149
- ttlRound: expiresAtRound,
150
- signedAtRound: tip,
151
- verb: "remove_member",
152
- fields: { groupName, memberNodeId: member },
153
- });
154
- }
155
- /**
156
- * Multi-recipient credit transfer (SIGN-02): move credit from the signing identity to 1..20
157
- * recipients. This is the plain `transferBody` on `LEDGER.identity` — NOT a group-membership encoder
158
- * and NOT an ownership transfer (that needs the incoming owner's co-signature and lives in
159
- * `src/group-ownership.ts`). "One verb = one tx"; the multi-entry array is the ONE thing that
160
- * distinguishes it from the singleton `evolver_sign_transfer`. Order is significant — it decides
161
- * which transfer survives a short-balance apply.
162
- */
163
- export async function signGroupTransfer(deps, params) {
164
- const entries = Array.isArray(params.entries) ? params.entries : [];
165
- if (entries.length === 0)
166
- return { kind: "partial", what: "entries", cause: "at least one transfer entry is required" };
167
- if (entries.length > MAX_TRANSFER_ENTRIES)
168
- return {
169
- kind: "partial",
170
- what: "entries",
171
- cause: `at most ${MAX_TRANSFER_ENTRIES} entries are allowed (the node's own limit) — got ${entries.length}`,
172
- };
173
- // Validate every entry BEFORE anything is signed: a bad amount or a missing recipient is refused
174
- // here (naming the entry index, never the bytes) rather than fined on-chain.
175
- const parsed = [];
176
- for (let i = 0; i < entries.length; i++) {
177
- const e = entries[i];
178
- const recipient = String(e.recipient ?? "").trim();
179
- if (recipient.length === 0)
180
- return { kind: "partial", what: `entries.${i}.recipient`, cause: "no recipient given" };
181
- const amount = parseAmount(String(e.amount ?? ""));
182
- if (!amount.ok)
183
- return { kind: "partial", what: `entries.${i}.amount`, cause: amount.error };
184
- parsed.push({ recipient, amount: amount.value });
185
- }
186
- const tip = await tipOrUnreachable(deps);
187
- if (typeof tip !== "number")
188
- return tip;
189
- const expiresAtRound = tip + (deps.ttlOffset ?? DEFAULT_TTL_OFFSET);
190
- const fields = {};
191
- for (let i = 0; i < parsed.length; i++) {
192
- fields[`recipient.${i}`] = parsed[i].recipient;
193
- fields[`amount.${i}`] = formatAmount(parsed[i].amount);
194
- }
195
- return composeAndSign(deps, {
196
- ledgerId: LEDGER.identity, // NOT groups — credit lives on identities (ownership: src/group-ownership.ts)
197
- body: transferBody(parsed.map((e) => ({ recipient: e.recipient, amount: e.amount }))),
198
- ttlRound: expiresAtRound,
199
- signedAtRound: tip,
200
- verb: "group_transfer",
201
- fields,
202
- });
203
- }
204
- //# sourceMappingURL=group.js.map
package/dist/group.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"group.js","sourceRoot":"","sources":["../src/group.ts"],"names":[],"mappings":"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"}