dero-mcp-server 0.1.2 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/POSITIONING.md +94 -0
- package/README.md +132 -31
- package/SKILL.md +264 -0
- package/data/docs-index.json +276 -264
- package/dist/bn254.d.ts +74 -0
- package/dist/bn254.d.ts.map +1 -0
- package/dist/bn254.js +205 -0
- package/dist/bn254.js.map +1 -0
- package/dist/citations.d.ts +140 -0
- package/dist/citations.d.ts.map +1 -0
- package/dist/citations.js +322 -0
- package/dist/citations.js.map +1 -0
- package/dist/composites/_shared.d.ts +119 -0
- package/dist/composites/_shared.d.ts.map +1 -0
- package/dist/composites/_shared.js +152 -0
- package/dist/composites/_shared.js.map +1 -0
- package/dist/composites/audit-chain-artifact-claim.d.ts +128 -0
- package/dist/composites/audit-chain-artifact-claim.d.ts.map +1 -0
- package/dist/composites/audit-chain-artifact-claim.js +305 -0
- package/dist/composites/audit-chain-artifact-claim.js.map +1 -0
- package/dist/composites/diagnose-chain-health.d.ts +64 -0
- package/dist/composites/diagnose-chain-health.d.ts.map +1 -0
- package/dist/composites/diagnose-chain-health.js +144 -0
- package/dist/composites/diagnose-chain-health.js.map +1 -0
- package/dist/composites/estimate-deploy-cost.d.ts +83 -0
- package/dist/composites/estimate-deploy-cost.d.ts.map +1 -0
- package/dist/composites/estimate-deploy-cost.js +116 -0
- package/dist/composites/estimate-deploy-cost.js.map +1 -0
- package/dist/composites/explain-smart-contract.d.ts +64 -0
- package/dist/composites/explain-smart-contract.d.ts.map +1 -0
- package/dist/composites/explain-smart-contract.js +149 -0
- package/dist/composites/explain-smart-contract.js.map +1 -0
- package/dist/composites/forge-demo-proof.d.ts +81 -0
- package/dist/composites/forge-demo-proof.d.ts.map +1 -0
- package/dist/composites/forge-demo-proof.js +204 -0
- package/dist/composites/forge-demo-proof.js.map +1 -0
- package/dist/composites/recommend-docs-path.d.ts +97 -0
- package/dist/composites/recommend-docs-path.d.ts.map +1 -0
- package/dist/composites/recommend-docs-path.js +149 -0
- package/dist/composites/recommend-docs-path.js.map +1 -0
- package/dist/composites/trace-transaction-with-context.d.ts +107 -0
- package/dist/composites/trace-transaction-with-context.d.ts.map +1 -0
- package/dist/composites/trace-transaction-with-context.js +217 -0
- package/dist/composites/trace-transaction-with-context.js.map +1 -0
- package/dist/daemon-base.d.ts +28 -0
- package/dist/daemon-base.d.ts.map +1 -0
- package/dist/daemon-base.js +62 -0
- package/dist/daemon-base.js.map +1 -0
- package/dist/dero-curve.d.ts +79 -0
- package/dist/dero-curve.d.ts.map +1 -0
- package/dist/dero-curve.js +79 -0
- package/dist/dero-curve.js.map +1 -0
- package/dist/docs-parse.d.ts.map +1 -1
- package/dist/docs-parse.js +18 -2
- package/dist/docs-parse.js.map +1 -1
- package/dist/http-server.d.ts +37 -0
- package/dist/http-server.d.ts.map +1 -0
- package/dist/http-server.js +132 -0
- package/dist/http-server.js.map +1 -0
- package/dist/index.js +18 -11
- package/dist/index.js.map +1 -1
- package/dist/proof-decode.d.ts +125 -0
- package/dist/proof-decode.d.ts.map +1 -0
- package/dist/proof-decode.js +619 -0
- package/dist/proof-decode.js.map +1 -0
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +414 -114
- package/dist/server.js.map +1 -1
- package/dist/tool-descriptions.d.ts +53 -0
- package/dist/tool-descriptions.d.ts.map +1 -0
- package/dist/tool-descriptions.js +285 -0
- package/dist/tool-descriptions.js.map +1 -0
- package/dist/tx-parse.d.ts +63 -0
- package/dist/tx-parse.d.ts.map +1 -0
- package/dist/tx-parse.js +183 -0
- package/dist/tx-parse.js.map +1 -0
- package/package.json +27 -2
|
@@ -0,0 +1,322 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Citation helper for DERO MCP tool responses.
|
|
3
|
+
*
|
|
4
|
+
* The wedge for this server is the combination of live chain reads and the
|
|
5
|
+
* in-process bundled docs index (145+ pages across derod, tela, hologram,
|
|
6
|
+
* deropay). Citations let agents link their responses back to authoritative
|
|
7
|
+
* docs without a second tool call, and they give downstream composite tools
|
|
8
|
+
* a uniform shape to compose.
|
|
9
|
+
*
|
|
10
|
+
* Design contract:
|
|
11
|
+
* - One shape, used by primitives and composites alike.
|
|
12
|
+
* - URLs are produced by the same builder used by `dero_docs_*` so the
|
|
13
|
+
* citation always points at the same canonical page the agent would
|
|
14
|
+
* reach via dero_docs_get_page.
|
|
15
|
+
* - The slug is duplicated as `page_id` to give composites a stable join
|
|
16
|
+
* key across tools (mirrors the FoodNearMe COMPOSITES.md citation pattern).
|
|
17
|
+
* - The map of related docs per tool is hand-maintained and validated by
|
|
18
|
+
* `scripts/check-citations.ts` (added alongside this helper) so a docs
|
|
19
|
+
* reorganization cannot silently produce 404 citations in production.
|
|
20
|
+
*/
|
|
21
|
+
import { DOC_BASE_URLS } from './docs-parse.js';
|
|
22
|
+
function buildCanonicalUrl(product, slug) {
|
|
23
|
+
const trimmed = slug.replace(/^\/+|\/+$/g, '');
|
|
24
|
+
if (!trimmed)
|
|
25
|
+
return `${DOC_BASE_URLS[product]}/`;
|
|
26
|
+
// .md mirror suffix points agents at the LLM-canonical Markdown surface.
|
|
27
|
+
// All four ecosystem sites (derod, tela, hologram, deropay) now ship the
|
|
28
|
+
// App Router .md mirror route, so the suffix applies universally.
|
|
29
|
+
return `${DOC_BASE_URLS[product]}/${trimmed}.md`;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Build a DeroCitation pointing at one bundled docs page.
|
|
33
|
+
*
|
|
34
|
+
* The title is required (not derived from the bundled index) so this helper
|
|
35
|
+
* stays synchronous and zero-IO. It must match the docs page title; the
|
|
36
|
+
* citation guard validates this against the bundled index in CI.
|
|
37
|
+
*/
|
|
38
|
+
export function buildDeroCitation(product, slug, title) {
|
|
39
|
+
return {
|
|
40
|
+
source: 'dero_docs',
|
|
41
|
+
product,
|
|
42
|
+
slug,
|
|
43
|
+
title,
|
|
44
|
+
canonical_url: buildCanonicalUrl(product, slug),
|
|
45
|
+
page_id: slug,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
export const RELATED_DOCS_BY_TOOL = {
|
|
49
|
+
dero_get_info: [
|
|
50
|
+
{
|
|
51
|
+
product: 'derod',
|
|
52
|
+
slug: 'rpc-api/daemon-rpc-api',
|
|
53
|
+
title: 'DERO Daemon RPC API: Complete Reference Guide | DERO Blockchain',
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
product: 'derod',
|
|
57
|
+
slug: 'basics/daemon',
|
|
58
|
+
title: 'DERO Daemon: Backbone of the Privacy Blockchain | DERO Blockchain',
|
|
59
|
+
},
|
|
60
|
+
],
|
|
61
|
+
dero_get_sc: [
|
|
62
|
+
{
|
|
63
|
+
product: 'derod',
|
|
64
|
+
slug: 'dvm/smart-contract-fundamentals',
|
|
65
|
+
title: 'Smart Contract Fundamentals: Understanding DERO Contracts | DERO Blockchain',
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
product: 'derod',
|
|
69
|
+
slug: 'dvm/dero-virtual-machine',
|
|
70
|
+
title: 'DERO Virtual Machine (DVM): Private Smart Contract Platform | DERO Blockchain',
|
|
71
|
+
},
|
|
72
|
+
],
|
|
73
|
+
dero_get_gas_estimate: [
|
|
74
|
+
{
|
|
75
|
+
product: 'derod',
|
|
76
|
+
slug: 'rpc-api/daemon-rpc-api',
|
|
77
|
+
title: 'DERO Daemon RPC API: Complete Reference Guide | DERO Blockchain',
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
product: 'derod',
|
|
81
|
+
slug: 'dvm/create-deploy-use-smart-contract',
|
|
82
|
+
title: 'Create, Deploy & Use a Smart Contract on DERO | Step-by-Step Tutorial',
|
|
83
|
+
},
|
|
84
|
+
],
|
|
85
|
+
diagnose_chain_health: [
|
|
86
|
+
{
|
|
87
|
+
product: 'derod',
|
|
88
|
+
slug: 'basics/daemon',
|
|
89
|
+
title: 'DERO Daemon: Backbone of the Privacy Blockchain | DERO Blockchain',
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
product: 'derod',
|
|
93
|
+
slug: 'rpc-api/daemon-rpc-api',
|
|
94
|
+
title: 'DERO Daemon RPC API: Complete Reference Guide | DERO Blockchain',
|
|
95
|
+
},
|
|
96
|
+
],
|
|
97
|
+
trace_transaction_with_context: [
|
|
98
|
+
{
|
|
99
|
+
product: 'derod',
|
|
100
|
+
slug: 'rpc-api/daemon-rpc-api',
|
|
101
|
+
title: 'DERO Daemon RPC API: Complete Reference Guide | DERO Blockchain',
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
product: 'derod',
|
|
105
|
+
slug: 'dvm/smart-contract-fundamentals',
|
|
106
|
+
title: 'Smart Contract Fundamentals: Understanding DERO Contracts | DERO Blockchain',
|
|
107
|
+
},
|
|
108
|
+
],
|
|
109
|
+
estimate_deploy_cost: [
|
|
110
|
+
{
|
|
111
|
+
product: 'derod',
|
|
112
|
+
slug: 'dvm/create-deploy-use-smart-contract',
|
|
113
|
+
title: 'Create, Deploy & Use a Smart Contract on DERO | Step-by-Step Tutorial',
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
product: 'derod',
|
|
117
|
+
slug: 'dvm/dvm-basic',
|
|
118
|
+
title: "DVM-BASIC: DERO's Smart Contract Language Guide | DERO Blockchain",
|
|
119
|
+
},
|
|
120
|
+
],
|
|
121
|
+
dero_decode_proof_string: [
|
|
122
|
+
{
|
|
123
|
+
product: 'derod',
|
|
124
|
+
slug: 'integrity/payload-vs-transaction-proofs',
|
|
125
|
+
title: 'Proof Types Explained: Transaction vs. Payload Proofs | DERO Blockchain',
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
product: 'derod',
|
|
129
|
+
slug: 'integrity/negative-transfer-protection',
|
|
130
|
+
title: 'Negative Transfer Protection: Cryptographic Impossibility | DERO Blockchain',
|
|
131
|
+
},
|
|
132
|
+
],
|
|
133
|
+
audit_chain_artifact_claim: [
|
|
134
|
+
{
|
|
135
|
+
product: 'derod',
|
|
136
|
+
slug: 'integrity/payload-vs-transaction-proofs',
|
|
137
|
+
title: 'Proof Types Explained: Transaction vs. Payload Proofs | DERO Blockchain',
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
product: 'derod',
|
|
141
|
+
slug: 'integrity/negative-transfer-protection',
|
|
142
|
+
title: 'Negative Transfer Protection: Cryptographic Impossibility | DERO Blockchain',
|
|
143
|
+
},
|
|
144
|
+
],
|
|
145
|
+
dero_forge_demo_proof: [
|
|
146
|
+
{
|
|
147
|
+
product: 'derod',
|
|
148
|
+
slug: 'integrity/payload-vs-transaction-proofs',
|
|
149
|
+
title: 'Proof Types Explained: Transaction vs. Payload Proofs | DERO Blockchain',
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
product: 'derod',
|
|
153
|
+
slug: 'integrity/negative-transfer-protection',
|
|
154
|
+
title: 'Negative Transfer Protection: Cryptographic Impossibility | DERO Blockchain',
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
product: 'derod',
|
|
158
|
+
slug: 'integrity/range-proof-integrity',
|
|
159
|
+
title: "Range Proof Integrity: How DERO's Bulletproof Binds Amounts | DERO Blockchain",
|
|
160
|
+
},
|
|
161
|
+
],
|
|
162
|
+
// Composite #2 (`explain_smart_contract`) curates all four DVM docs so its
|
|
163
|
+
// heuristic can elevate whichever page best matches the detected surface
|
|
164
|
+
// (token / registry / minimal / generic). The composite re-orders this
|
|
165
|
+
// array at runtime; the static ordering here is the fallback when the
|
|
166
|
+
// heuristic returns the same slug already at index 0 (the universal
|
|
167
|
+
// "fundamentals" default).
|
|
168
|
+
explain_smart_contract: [
|
|
169
|
+
{
|
|
170
|
+
product: 'derod',
|
|
171
|
+
slug: 'dvm/smart-contract-fundamentals',
|
|
172
|
+
title: 'Smart Contract Fundamentals: Understanding DERO Contracts | DERO Blockchain',
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
product: 'derod',
|
|
176
|
+
slug: 'dvm/dvm-basic',
|
|
177
|
+
title: "DVM-BASIC: DERO's Smart Contract Language Guide | DERO Blockchain",
|
|
178
|
+
},
|
|
179
|
+
{
|
|
180
|
+
product: 'derod',
|
|
181
|
+
slug: 'dvm/dero-virtual-machine',
|
|
182
|
+
title: 'DERO Virtual Machine (DVM): Private Smart Contract Platform | DERO Blockchain',
|
|
183
|
+
},
|
|
184
|
+
{
|
|
185
|
+
product: 'derod',
|
|
186
|
+
slug: 'dvm/create-deploy-use-smart-contract',
|
|
187
|
+
title: 'Create, Deploy & Use a Smart Contract on DERO | Step-by-Step Tutorial',
|
|
188
|
+
},
|
|
189
|
+
],
|
|
190
|
+
};
|
|
191
|
+
/**
|
|
192
|
+
* Resolve the hand-curated related docs list for a tool name and return it
|
|
193
|
+
* as fully-built `DeroCitation` objects. Returns `undefined` when the tool
|
|
194
|
+
* has no related docs configured.
|
|
195
|
+
*
|
|
196
|
+
* Use in tool handlers like:
|
|
197
|
+
* const related_docs = relatedDocsFor('dero_get_sc')
|
|
198
|
+
* return { ...rpcResult, ...(related_docs ? { related_docs } : {}) }
|
|
199
|
+
*/
|
|
200
|
+
export function relatedDocsFor(toolName) {
|
|
201
|
+
const entries = RELATED_DOCS_BY_TOOL[toolName];
|
|
202
|
+
if (!entries || entries.length === 0)
|
|
203
|
+
return undefined;
|
|
204
|
+
return entries.map((entry) => buildDeroCitation(entry.product, entry.slug, entry.title));
|
|
205
|
+
}
|
|
206
|
+
export const FLAGGED_CHAIN_ARTIFACTS = [
|
|
207
|
+
{
|
|
208
|
+
id: '2022-inflation-claim',
|
|
209
|
+
matchers: [
|
|
210
|
+
{ kind: 'topoheight', value: 1_081_893 },
|
|
211
|
+
{ kind: 'block_hash', value: 'b6bd914f7fb1c79788fe8676c277e58e7bb5a904317afb096b1d2793af9aed13' },
|
|
212
|
+
{ kind: 'tx_hash', value: '5bbe1b7eecfe3447cb045b1197a07a214b456968eda8a3d5a90f5fae9ce57e55' },
|
|
213
|
+
{
|
|
214
|
+
kind: 'proof_string',
|
|
215
|
+
value: 'deroproof1qyyj0cgu3htmkumr79sgca75vwsx8kx7zkrjg0nfez46w36qyx4kwq9zvfyyskpqvdpcfhkhk4m7y9d77ehyj7yhnnrv9z0tjr9m5fqe2yx9t27dwtdxy4j4r0llll7vcmaxwjcl8jzfq',
|
|
216
|
+
},
|
|
217
|
+
],
|
|
218
|
+
context_note: 'This block/transaction/proof string appears in publicly circulated 2022 inflation claims. The cited payload proof is a user-supplied display object — not a consensus record — and the alleged negative-transfer mechanism cannot produce a verifying range proof. See related_docs for the technical rebuttal.',
|
|
219
|
+
demo_amount_dero: '-2200000.00181',
|
|
220
|
+
// TODO: once `integrity/inflation-claim` ships and the bundled docs index
|
|
221
|
+
// refreshes, prepend it as the primary citation:
|
|
222
|
+
// { product: 'derod', slug: 'integrity/inflation-claim', title: '<exact bundled title>' }
|
|
223
|
+
related_docs: [
|
|
224
|
+
{
|
|
225
|
+
product: 'derod',
|
|
226
|
+
slug: 'integrity/negative-transfer-protection',
|
|
227
|
+
title: 'Negative Transfer Protection: Cryptographic Impossibility | DERO Blockchain',
|
|
228
|
+
},
|
|
229
|
+
{
|
|
230
|
+
product: 'derod',
|
|
231
|
+
slug: 'integrity/payload-vs-transaction-proofs',
|
|
232
|
+
title: 'Proof Types Explained: Transaction vs. Payload Proofs | DERO Blockchain',
|
|
233
|
+
},
|
|
234
|
+
{
|
|
235
|
+
product: 'derod',
|
|
236
|
+
slug: 'integrity/ring-member-behavior',
|
|
237
|
+
title: 'Ring Member Behavior: Understanding Decoy Participation | DERO Blockchain',
|
|
238
|
+
},
|
|
239
|
+
],
|
|
240
|
+
},
|
|
241
|
+
];
|
|
242
|
+
/** Normalize a hex value for case-insensitive comparison. Non-hex strings pass through unchanged. */
|
|
243
|
+
function normalizeHex(value) {
|
|
244
|
+
return value.trim().toLowerCase();
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Return all flagged artifacts whose matchers fire against the given inputs.
|
|
248
|
+
*
|
|
249
|
+
* Multiple matches return multiple artifacts (rare today; would happen if the
|
|
250
|
+
* same TX got cited in multiple false claims). Tool handlers should merge all
|
|
251
|
+
* matches into a single response.
|
|
252
|
+
*/
|
|
253
|
+
export function flaggedArtifactsForInput(query) {
|
|
254
|
+
const matches = [];
|
|
255
|
+
const queryBlockHash = query.block_hash ? normalizeHex(query.block_hash) : undefined;
|
|
256
|
+
const queryTxHashes = [];
|
|
257
|
+
if (query.tx_hash)
|
|
258
|
+
queryTxHashes.push(normalizeHex(query.tx_hash));
|
|
259
|
+
if (query.tx_hashes)
|
|
260
|
+
for (const h of query.tx_hashes)
|
|
261
|
+
queryTxHashes.push(normalizeHex(h));
|
|
262
|
+
const queryProof = query.proof_string?.trim();
|
|
263
|
+
for (const artifact of FLAGGED_CHAIN_ARTIFACTS) {
|
|
264
|
+
const hit = artifact.matchers.some((m) => {
|
|
265
|
+
switch (m.kind) {
|
|
266
|
+
case 'topoheight':
|
|
267
|
+
return query.topoheight !== undefined && query.topoheight === m.value;
|
|
268
|
+
case 'block_hash':
|
|
269
|
+
return queryBlockHash !== undefined && queryBlockHash === normalizeHex(m.value);
|
|
270
|
+
case 'tx_hash':
|
|
271
|
+
return queryTxHashes.includes(normalizeHex(m.value));
|
|
272
|
+
case 'proof_string':
|
|
273
|
+
return queryProof !== undefined && queryProof === m.value;
|
|
274
|
+
}
|
|
275
|
+
});
|
|
276
|
+
if (hit)
|
|
277
|
+
matches.push(artifact);
|
|
278
|
+
}
|
|
279
|
+
return matches;
|
|
280
|
+
}
|
|
281
|
+
/**
|
|
282
|
+
* Build the response-side enrichment for matched artifacts: a context note
|
|
283
|
+
* (joined if multiple match) plus prepended citations for each match.
|
|
284
|
+
*
|
|
285
|
+
* `baseRelatedDocs` is the tool's existing relatedDocsFor() output (or undefined).
|
|
286
|
+
* Returns `undefined` when no artifacts match — caller should noop in that case.
|
|
287
|
+
*
|
|
288
|
+
* Usage in a tool handler:
|
|
289
|
+
* const enrichment = enrichWithFlaggedArtifacts(
|
|
290
|
+
* { topoheight: args.topoheight },
|
|
291
|
+
* relatedDocsFor('dero_get_block_header_by_topo_height'),
|
|
292
|
+
* )
|
|
293
|
+
* return { ...result, ...(enrichment ?? {}) }
|
|
294
|
+
*/
|
|
295
|
+
export function enrichWithFlaggedArtifacts(query, baseRelatedDocs) {
|
|
296
|
+
const matches = flaggedArtifactsForInput(query);
|
|
297
|
+
if (matches.length === 0)
|
|
298
|
+
return undefined;
|
|
299
|
+
const context_note = matches.map((a) => a.context_note).join('\n\n');
|
|
300
|
+
// Prepend artifact citations (de-duped against baseline by canonical_url).
|
|
301
|
+
const seen = new Set();
|
|
302
|
+
const merged = [];
|
|
303
|
+
for (const artifact of matches) {
|
|
304
|
+
for (const entry of artifact.related_docs) {
|
|
305
|
+
const cite = buildDeroCitation(entry.product, entry.slug, entry.title);
|
|
306
|
+
if (!seen.has(cite.canonical_url)) {
|
|
307
|
+
merged.push(cite);
|
|
308
|
+
seen.add(cite.canonical_url);
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
if (baseRelatedDocs) {
|
|
313
|
+
for (const cite of baseRelatedDocs) {
|
|
314
|
+
if (!seen.has(cite.canonical_url)) {
|
|
315
|
+
merged.push(cite);
|
|
316
|
+
seen.add(cite.canonical_url);
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
return { context_note, related_docs: merged };
|
|
321
|
+
}
|
|
322
|
+
//# sourceMappingURL=citations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"citations.js","sourceRoot":"","sources":["../src/citations.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared utilities for DERO MCP composite tools.
|
|
3
|
+
*
|
|
4
|
+
* A composite tool stitches several primitives (daemon RPC reads + bundled
|
|
5
|
+
* docs lookups) into one intent-shaped response. These utilities exist so
|
|
6
|
+
* every composite handles failures, latency tracking, and citation
|
|
7
|
+
* attachment the same way.
|
|
8
|
+
*
|
|
9
|
+
* Anything reused by more than one composite belongs here. Composite-local
|
|
10
|
+
* helpers (e.g. narrative builders specific to one composite's response
|
|
11
|
+
* shape) should live next to that composite, not in this file.
|
|
12
|
+
*
|
|
13
|
+
* See the composite design contract for which
|
|
14
|
+
* utilities live here and the gate every composite must satisfy before it
|
|
15
|
+
* lands on main.
|
|
16
|
+
*/
|
|
17
|
+
import { type DeroCitation } from '../citations.js';
|
|
18
|
+
/**
|
|
19
|
+
* One step in a composite's internal chain.
|
|
20
|
+
*
|
|
21
|
+
* `required: true` aborts the chain if the step throws (use for liveness
|
|
22
|
+
* gates like `DERO.Ping`). `required: false` lets the chain continue with
|
|
23
|
+
* a degraded payload (use for enrichments like a mempool snapshot).
|
|
24
|
+
*/
|
|
25
|
+
export type ChainStep<T = unknown> = {
|
|
26
|
+
name: string;
|
|
27
|
+
required?: boolean;
|
|
28
|
+
fn: () => Promise<T>;
|
|
29
|
+
};
|
|
30
|
+
export type ChainStepResult = {
|
|
31
|
+
name: string;
|
|
32
|
+
ok: boolean;
|
|
33
|
+
value?: unknown;
|
|
34
|
+
error?: {
|
|
35
|
+
message: string;
|
|
36
|
+
};
|
|
37
|
+
latencyMs: number;
|
|
38
|
+
};
|
|
39
|
+
export type ChainResult = {
|
|
40
|
+
results: ChainStepResult[];
|
|
41
|
+
haltedAt: string | null;
|
|
42
|
+
totalMs: number;
|
|
43
|
+
};
|
|
44
|
+
/**
|
|
45
|
+
* Run a chain of named primitive calls sequentially. Required-step
|
|
46
|
+
* failures halt the chain and record `haltedAt`; non-required failures
|
|
47
|
+
* are recorded and the chain continues. Step latencies are captured so
|
|
48
|
+
* composites can attach diagnostics to a degraded response.
|
|
49
|
+
*/
|
|
50
|
+
export declare function runChain(steps: readonly ChainStep[]): Promise<ChainResult>;
|
|
51
|
+
/**
|
|
52
|
+
* Extract a single step's successful return value from a ChainResult.
|
|
53
|
+
* Returns null when the step was skipped (chain halted earlier), failed,
|
|
54
|
+
* or simply was not part of the chain.
|
|
55
|
+
*/
|
|
56
|
+
export declare function stepValue<T = unknown>(chain: ChainResult, name: string): T | null;
|
|
57
|
+
/**
|
|
58
|
+
* Per-step latency map suitable for embedding in a composite's response
|
|
59
|
+
* under a `_diagnostics` field. Lets agents and operators see which step
|
|
60
|
+
* was slow without needing to instrument the host.
|
|
61
|
+
*/
|
|
62
|
+
export declare function stepLatencies(chain: ChainResult): Record<string, number>;
|
|
63
|
+
/**
|
|
64
|
+
* Attach curated `related_docs` citations to a composite's payload.
|
|
65
|
+
* Mirrors how primitives attach citations so the response shape stays
|
|
66
|
+
* uniform across primitives and composites. Returns the payload
|
|
67
|
+
* unchanged when no curated docs are configured for the tool name.
|
|
68
|
+
*/
|
|
69
|
+
export declare function attachCitations<T extends Record<string, unknown>>(payload: T, toolName: string): T & {
|
|
70
|
+
related_docs?: DeroCitation[];
|
|
71
|
+
};
|
|
72
|
+
/**
|
|
73
|
+
* Shape used by the JSON-RPC `rpc` closure created in `src/server.ts`.
|
|
74
|
+
* Re-declared here so composites can take it as a dependency without
|
|
75
|
+
* importing from the server module (keeps the composite layer free of
|
|
76
|
+
* `McpServer` coupling).
|
|
77
|
+
*/
|
|
78
|
+
export type DeroDaemonRpc = <T = unknown>(method: string, params?: unknown) => Promise<T>;
|
|
79
|
+
/**
|
|
80
|
+
* Loose representation of a `DERO.GetSC` response. Field names match the
|
|
81
|
+
* daemon's actual JSON keys observed on the public node. `uint64keys` is
|
|
82
|
+
* frequently absent (the daemon omits empty maps), so it is optional.
|
|
83
|
+
*/
|
|
84
|
+
export type DeroGetScResult = {
|
|
85
|
+
code?: string;
|
|
86
|
+
status?: string;
|
|
87
|
+
balance?: number;
|
|
88
|
+
balances?: Record<string, number>;
|
|
89
|
+
stringkeys?: Record<string, unknown>;
|
|
90
|
+
uint64keys?: Record<string, unknown>;
|
|
91
|
+
[k: string]: unknown;
|
|
92
|
+
};
|
|
93
|
+
export type DvmFunctionSignature = {
|
|
94
|
+
name: string;
|
|
95
|
+
args: string[];
|
|
96
|
+
returns: string;
|
|
97
|
+
};
|
|
98
|
+
export type DeroScSurface = {
|
|
99
|
+
functions: DvmFunctionSignature[];
|
|
100
|
+
stringkeys: string[];
|
|
101
|
+
uint64keys: string[];
|
|
102
|
+
balances: Record<string, number | string>;
|
|
103
|
+
raw_code_length: number;
|
|
104
|
+
has_code: boolean;
|
|
105
|
+
};
|
|
106
|
+
/**
|
|
107
|
+
* Convert a raw DERO.GetSC payload into a stable, agent-friendly surface.
|
|
108
|
+
*
|
|
109
|
+
* Behavior:
|
|
110
|
+
* - Returns `functions: []` when `code` is missing or the regex finds
|
|
111
|
+
* no Function declarations. Never throws on malformed code.
|
|
112
|
+
* - Sorts `stringkeys` / `uint64keys` alphabetically for deterministic
|
|
113
|
+
* output across invocations.
|
|
114
|
+
* - `balances` is passed through unchanged so callers can render asset
|
|
115
|
+
* balances; native DERO balance lives under `balance` on the raw
|
|
116
|
+
* payload and is left for callers to decide whether to surface.
|
|
117
|
+
*/
|
|
118
|
+
export declare function extractScSurface(raw: DeroGetScResult | null | undefined): DeroScSurface;
|
|
119
|
+
//# sourceMappingURL=_shared.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"_shared.d.ts","sourceRoot":"","sources":["../../src/composites/_shared.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAkB,KAAK,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAEnE;;;;;;GAMG;AACH,MAAM,MAAM,SAAS,CAAC,CAAC,GAAG,OAAO,IAAI;IACnC,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,CAAA;CACrB,CAAA;AAED,MAAM,MAAM,eAAe,GAAG;IAC5B,IAAI,EAAE,MAAM,CAAA;IACZ,EAAE,EAAE,OAAO,CAAA;IACX,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,KAAK,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,CAAA;IAC3B,SAAS,EAAE,MAAM,CAAA;CAClB,CAAA;AAED,MAAM,MAAM,WAAW,GAAG;IACxB,OAAO,EAAE,eAAe,EAAE,CAAA;IAC1B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;IACvB,OAAO,EAAE,MAAM,CAAA;CAChB,CAAA;AAED;;;;;GAKG;AACH,wBAAsB,QAAQ,CAAC,KAAK,EAAE,SAAS,SAAS,EAAE,GAAG,OAAO,CAAC,WAAW,CAAC,CAkChF;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,CAAC,GAAG,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,GAAG,CAAC,GAAG,IAAI,CAIjF;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAIxE;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/D,OAAO,EAAE,CAAC,EACV,QAAQ,EAAE,MAAM,GACf,CAAC,GAAG;IAAE,YAAY,CAAC,EAAE,YAAY,EAAE,CAAA;CAAE,CAIvC;AAED;;;;;GAKG;AACH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,GAAG,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,KAAK,OAAO,CAAC,CAAC,CAAC,CAAA;AAUzF;;;;GAIG;AACH,MAAM,MAAM,eAAe,GAAG;IAC5B,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACjC,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IACpC,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IACpC,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;CACrB,CAAA;AAED,MAAM,MAAM,oBAAoB,GAAG;IACjC,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,EAAE,CAAA;IACd,OAAO,EAAE,MAAM,CAAA;CAChB,CAAA;AAED,MAAM,MAAM,aAAa,GAAG;IAC1B,SAAS,EAAE,oBAAoB,EAAE,CAAA;IACjC,UAAU,EAAE,MAAM,EAAE,CAAA;IACpB,UAAU,EAAE,MAAM,EAAE,CAAA;IACpB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,CAAA;IACzC,eAAe,EAAE,MAAM,CAAA;IACvB,QAAQ,EAAE,OAAO,CAAA;CAClB,CAAA;AA+BD;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,eAAe,GAAG,IAAI,GAAG,SAAS,GAAG,aAAa,CAqBvF"}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared utilities for DERO MCP composite tools.
|
|
3
|
+
*
|
|
4
|
+
* A composite tool stitches several primitives (daemon RPC reads + bundled
|
|
5
|
+
* docs lookups) into one intent-shaped response. These utilities exist so
|
|
6
|
+
* every composite handles failures, latency tracking, and citation
|
|
7
|
+
* attachment the same way.
|
|
8
|
+
*
|
|
9
|
+
* Anything reused by more than one composite belongs here. Composite-local
|
|
10
|
+
* helpers (e.g. narrative builders specific to one composite's response
|
|
11
|
+
* shape) should live next to that composite, not in this file.
|
|
12
|
+
*
|
|
13
|
+
* See the composite design contract for which
|
|
14
|
+
* utilities live here and the gate every composite must satisfy before it
|
|
15
|
+
* lands on main.
|
|
16
|
+
*/
|
|
17
|
+
import { relatedDocsFor } from '../citations.js';
|
|
18
|
+
/**
|
|
19
|
+
* Run a chain of named primitive calls sequentially. Required-step
|
|
20
|
+
* failures halt the chain and record `haltedAt`; non-required failures
|
|
21
|
+
* are recorded and the chain continues. Step latencies are captured so
|
|
22
|
+
* composites can attach diagnostics to a degraded response.
|
|
23
|
+
*/
|
|
24
|
+
export async function runChain(steps) {
|
|
25
|
+
const results = [];
|
|
26
|
+
const startedAt = performance.now();
|
|
27
|
+
let haltedAt = null;
|
|
28
|
+
for (const step of steps) {
|
|
29
|
+
const stepStart = performance.now();
|
|
30
|
+
try {
|
|
31
|
+
const value = await step.fn();
|
|
32
|
+
results.push({
|
|
33
|
+
name: step.name,
|
|
34
|
+
ok: true,
|
|
35
|
+
value,
|
|
36
|
+
latencyMs: Math.round(performance.now() - stepStart),
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
catch (error) {
|
|
40
|
+
results.push({
|
|
41
|
+
name: step.name,
|
|
42
|
+
ok: false,
|
|
43
|
+
error: { message: error instanceof Error ? error.message : String(error) },
|
|
44
|
+
latencyMs: Math.round(performance.now() - stepStart),
|
|
45
|
+
});
|
|
46
|
+
if (step.required) {
|
|
47
|
+
haltedAt = step.name;
|
|
48
|
+
break;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return {
|
|
53
|
+
results,
|
|
54
|
+
haltedAt,
|
|
55
|
+
totalMs: Math.round(performance.now() - startedAt),
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Extract a single step's successful return value from a ChainResult.
|
|
60
|
+
* Returns null when the step was skipped (chain halted earlier), failed,
|
|
61
|
+
* or simply was not part of the chain.
|
|
62
|
+
*/
|
|
63
|
+
export function stepValue(chain, name) {
|
|
64
|
+
const entry = chain.results.find((r) => r.name === name);
|
|
65
|
+
if (!entry || !entry.ok)
|
|
66
|
+
return null;
|
|
67
|
+
return entry.value;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Per-step latency map suitable for embedding in a composite's response
|
|
71
|
+
* under a `_diagnostics` field. Lets agents and operators see which step
|
|
72
|
+
* was slow without needing to instrument the host.
|
|
73
|
+
*/
|
|
74
|
+
export function stepLatencies(chain) {
|
|
75
|
+
const out = {};
|
|
76
|
+
for (const r of chain.results)
|
|
77
|
+
out[r.name] = r.latencyMs;
|
|
78
|
+
return out;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Attach curated `related_docs` citations to a composite's payload.
|
|
82
|
+
* Mirrors how primitives attach citations so the response shape stays
|
|
83
|
+
* uniform across primitives and composites. Returns the payload
|
|
84
|
+
* unchanged when no curated docs are configured for the tool name.
|
|
85
|
+
*/
|
|
86
|
+
export function attachCitations(payload, toolName) {
|
|
87
|
+
const related_docs = relatedDocsFor(toolName);
|
|
88
|
+
if (!related_docs || related_docs.length === 0)
|
|
89
|
+
return payload;
|
|
90
|
+
return { ...payload, related_docs };
|
|
91
|
+
}
|
|
92
|
+
// DVM-BASIC function declaration:
|
|
93
|
+
// Function Name(arg Type, ...) Uint64|String
|
|
94
|
+
//
|
|
95
|
+
// Anchored with `/m` so each line of source is examined independently.
|
|
96
|
+
// Tolerant of leading whitespace and varied spacing inside the parens.
|
|
97
|
+
const DVM_FUNCTION_REGEX = /^[ \t]*Function[ \t]+([A-Za-z_][A-Za-z0-9_]*)[ \t]*\(([^)]*)\)[ \t]*(Uint64|String)\b/gm;
|
|
98
|
+
function parseDvmFunctions(code) {
|
|
99
|
+
const out = [];
|
|
100
|
+
const seen = new Set();
|
|
101
|
+
for (const match of code.matchAll(DVM_FUNCTION_REGEX)) {
|
|
102
|
+
const name = match[1];
|
|
103
|
+
if (seen.has(name))
|
|
104
|
+
continue;
|
|
105
|
+
seen.add(name);
|
|
106
|
+
const argsRaw = (match[2] ?? '').trim();
|
|
107
|
+
const returns = match[3] ?? '';
|
|
108
|
+
const args = argsRaw.length === 0
|
|
109
|
+
? []
|
|
110
|
+
: argsRaw
|
|
111
|
+
.split(',')
|
|
112
|
+
.map((s) => s.trim())
|
|
113
|
+
.filter((s) => s.length > 0);
|
|
114
|
+
out.push({ name, args, returns });
|
|
115
|
+
}
|
|
116
|
+
return out;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Convert a raw DERO.GetSC payload into a stable, agent-friendly surface.
|
|
120
|
+
*
|
|
121
|
+
* Behavior:
|
|
122
|
+
* - Returns `functions: []` when `code` is missing or the regex finds
|
|
123
|
+
* no Function declarations. Never throws on malformed code.
|
|
124
|
+
* - Sorts `stringkeys` / `uint64keys` alphabetically for deterministic
|
|
125
|
+
* output across invocations.
|
|
126
|
+
* - `balances` is passed through unchanged so callers can render asset
|
|
127
|
+
* balances; native DERO balance lives under `balance` on the raw
|
|
128
|
+
* payload and is left for callers to decide whether to surface.
|
|
129
|
+
*/
|
|
130
|
+
export function extractScSurface(raw) {
|
|
131
|
+
const code = typeof raw?.code === 'string' ? raw.code : '';
|
|
132
|
+
const functions = code.length > 0 ? parseDvmFunctions(code) : [];
|
|
133
|
+
const stringkeys = raw?.stringkeys ? Object.keys(raw.stringkeys).sort() : [];
|
|
134
|
+
const uint64keys = raw?.uint64keys ? Object.keys(raw.uint64keys).sort() : [];
|
|
135
|
+
const balances = {};
|
|
136
|
+
if (raw?.balances && typeof raw.balances === 'object') {
|
|
137
|
+
for (const [scid, amount] of Object.entries(raw.balances)) {
|
|
138
|
+
if (typeof amount === 'number' || typeof amount === 'string') {
|
|
139
|
+
balances[scid] = amount;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
return {
|
|
144
|
+
functions,
|
|
145
|
+
stringkeys,
|
|
146
|
+
uint64keys,
|
|
147
|
+
balances,
|
|
148
|
+
raw_code_length: code.length,
|
|
149
|
+
has_code: code.length > 0,
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
//# sourceMappingURL=_shared.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"_shared.js","sourceRoot":"","sources":["../../src/composites/_shared.ts"],"names":[],"mappings":"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"}
|