@0xwh1sker/mantle-mcp 0.1.3
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/LICENSE +21 -0
- package/README.md +39 -0
- package/SERVER_INSTRUCTIONS.md +33 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/skills-path.d.ts +8 -0
- package/dist/lib/skills-path.d.ts.map +1 -0
- package/dist/lib/skills-path.js +50 -0
- package/dist/lib/skills-path.js.map +1 -0
- package/dist/prompts.d.ts +20 -0
- package/dist/prompts.d.ts.map +1 -0
- package/dist/prompts.js +133 -0
- package/dist/prompts.js.map +1 -0
- package/dist/resources.d.ts +8 -0
- package/dist/resources.d.ts.map +1 -0
- package/dist/resources.js +138 -0
- package/dist/resources.js.map +1 -0
- package/dist/server.d.ts +4 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +102 -0
- package/dist/server.js.map +1 -0
- package/package.json +47 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Mantle
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# @0xwh1sker/mantle-mcp
|
|
2
|
+
|
|
3
|
+
MCP server for AI-driven Mantle L2 development — chain reads, simulation, and unsigned transaction building.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @0xwh1sker/mantle-mcp
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
Run the MCP server over stdio:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npx @0xwh1sker/mantle-mcp
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Or add to your Claude Desktop / MCP client configuration:
|
|
20
|
+
|
|
21
|
+
```json
|
|
22
|
+
{
|
|
23
|
+
"mcpServers": {
|
|
24
|
+
"mantle": {
|
|
25
|
+
"command": "npx",
|
|
26
|
+
"args": ["@0xwh1sker/mantle-mcp"]
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Related packages
|
|
33
|
+
|
|
34
|
+
- [`@0xwh1sker/mantle-core`](https://www.npmjs.com/package/@0xwh1sker/mantle-core) — shared Mantle L2 business logic
|
|
35
|
+
- [`@0xwh1sker/mantle-cli`](https://www.npmjs.com/package/@0xwh1sker/mantle-cli) — CLI for Mantle chain reads, DeFi queries, and transaction building
|
|
36
|
+
|
|
37
|
+
## License
|
|
38
|
+
|
|
39
|
+
MIT
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# mantle-mcp Server Instructions
|
|
2
|
+
|
|
3
|
+
Mantle L2 tools for AI agents. Read chain state, simulate transactions, and build unsigned payloads.
|
|
4
|
+
|
|
5
|
+
## Rules
|
|
6
|
+
|
|
7
|
+
### 1. Never Hold Private Keys
|
|
8
|
+
|
|
9
|
+
`mantle-mcp` never signs and never broadcasts transactions. All build tools return unsigned payloads only.
|
|
10
|
+
|
|
11
|
+
### 2. Verify Addresses Through Registry/Token Resolution
|
|
12
|
+
|
|
13
|
+
Before any transaction-building path, resolve/validate addresses with:
|
|
14
|
+
|
|
15
|
+
- `mantle_resolveAddress`
|
|
16
|
+
- `mantle_validateAddress`
|
|
17
|
+
- `mantle_resolveToken` (with canonical token-list cross-check)
|
|
18
|
+
|
|
19
|
+
### 3. Simulate Before Presenting
|
|
20
|
+
|
|
21
|
+
Always present a fresh simulation result before any signing step.
|
|
22
|
+
|
|
23
|
+
### 4. Present `human_summary` Before Signing
|
|
24
|
+
|
|
25
|
+
Every transaction-building tool must return and display `human_summary` prior to user confirmation/signing.
|
|
26
|
+
|
|
27
|
+
### 5. MNT is the Gas Token
|
|
28
|
+
|
|
29
|
+
Mantle gas estimates and native balances are denominated in MNT (not ETH).
|
|
30
|
+
|
|
31
|
+
### 6. Never Fabricate Data
|
|
32
|
+
|
|
33
|
+
If price/address/simulation data cannot be trusted, return typed errors or explicit null/low-confidence outputs instead of guessed values.
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
async function main() {
|
|
3
|
+
const { runServer } = await import("./server.js");
|
|
4
|
+
await runServer();
|
|
5
|
+
}
|
|
6
|
+
main().catch((error) => {
|
|
7
|
+
// stderr logging only, so MCP stdio payload remains clean.
|
|
8
|
+
console.error("Fatal:", error);
|
|
9
|
+
process.exit(1);
|
|
10
|
+
});
|
|
11
|
+
export {};
|
|
12
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,KAAK,UAAU,IAAI;IACjB,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,CAAC;IAClD,MAAM,SAAS,EAAE,CAAC;AACpB,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACrB,2DAA2D;IAC3D,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;IAC/B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Check whether the skills submodule checkout is reachable.
|
|
3
|
+
* Returns true when running inside the monorepo with skills initialized,
|
|
4
|
+
* false for standalone npm consumers.
|
|
5
|
+
*/
|
|
6
|
+
export declare function isSkillsCheckoutAvailable(baseDir?: string): boolean;
|
|
7
|
+
export declare function readSkillsReference(relativePath: string, baseDir?: string): string;
|
|
8
|
+
//# sourceMappingURL=skills-path.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skills-path.d.ts","sourceRoot":"","sources":["../../src/lib/skills-path.ts"],"names":[],"mappings":"AAgCA;;;;GAIG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,SAAY,GAAG,OAAO,CAEtE;AAED,wBAAgB,mBAAmB,CAAC,YAAY,EAAE,MAAM,EAAE,OAAO,SAAY,GAAG,MAAM,CAqBrF"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
/**
|
|
5
|
+
* Resolve the monorepo root where the skills/ submodule lives.
|
|
6
|
+
* Walk up from this module's compiled location until we find a directory
|
|
7
|
+
* containing a skills/ folder or .gitmodules, falling back to cwd.
|
|
8
|
+
*/
|
|
9
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
10
|
+
function findRepoRoot() {
|
|
11
|
+
let dir = path.resolve(__dirname);
|
|
12
|
+
const { root } = path.parse(dir);
|
|
13
|
+
while (dir !== root) {
|
|
14
|
+
if (existsSync(path.join(dir, "skills")) || existsSync(path.join(dir, ".gitmodules"))) {
|
|
15
|
+
return dir;
|
|
16
|
+
}
|
|
17
|
+
dir = path.dirname(dir);
|
|
18
|
+
}
|
|
19
|
+
// skills/ not found in any ancestor — likely running from an npm install
|
|
20
|
+
// rather than the monorepo checkout. Fall back to cwd but warn.
|
|
21
|
+
console.error("[mantle-mcp] Could not locate the skills/ submodule. " +
|
|
22
|
+
"If running from the monorepo, run `npm run skills:init`. " +
|
|
23
|
+
"Falling back to process.cwd().");
|
|
24
|
+
return process.cwd();
|
|
25
|
+
}
|
|
26
|
+
const REPO_ROOT = findRepoRoot();
|
|
27
|
+
/**
|
|
28
|
+
* Check whether the skills submodule checkout is reachable.
|
|
29
|
+
* Returns true when running inside the monorepo with skills initialized,
|
|
30
|
+
* false for standalone npm consumers.
|
|
31
|
+
*/
|
|
32
|
+
export function isSkillsCheckoutAvailable(baseDir = REPO_ROOT) {
|
|
33
|
+
return existsSync(path.resolve(baseDir, "skills"));
|
|
34
|
+
}
|
|
35
|
+
export function readSkillsReference(relativePath, baseDir = REPO_ROOT) {
|
|
36
|
+
const absolutePath = path.resolve(baseDir, relativePath);
|
|
37
|
+
if (existsSync(absolutePath)) {
|
|
38
|
+
return readFileSync(absolutePath, "utf8");
|
|
39
|
+
}
|
|
40
|
+
const skillsRoot = path.resolve(baseDir, "skills");
|
|
41
|
+
const nestedSkillsPath = path.resolve(baseDir, "skills", relativePath);
|
|
42
|
+
if (existsSync(nestedSkillsPath)) {
|
|
43
|
+
return readFileSync(nestedSkillsPath, "utf8");
|
|
44
|
+
}
|
|
45
|
+
if (!existsSync(skillsRoot)) {
|
|
46
|
+
throw new Error(`Missing skills checkout at ${skillsRoot}. Run \`npm run skills:init\` to initialize the mantle-skills submodule.`);
|
|
47
|
+
}
|
|
48
|
+
throw new Error(`Missing skills reference file: ${relativePath}`);
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=skills-path.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skills-path.js","sourceRoot":"","sources":["../../src/lib/skills-path.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC;;;;GAIG;AACH,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAE/D,SAAS,YAAY;IACnB,IAAI,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAClC,MAAM,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACjC,OAAO,GAAG,KAAK,IAAI,EAAE,CAAC;QACpB,IAAI,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC,IAAI,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC;YACtF,OAAO,GAAG,CAAC;QACb,CAAC;QACD,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAC1B,CAAC;IACD,yEAAyE;IACzE,iEAAiE;IACjE,OAAO,CAAC,KAAK,CACX,uDAAuD;QACvD,2DAA2D;QAC3D,gCAAgC,CACjC,CAAC;IACF,OAAO,OAAO,CAAC,GAAG,EAAE,CAAC;AACvB,CAAC;AAED,MAAM,SAAS,GAAG,YAAY,EAAE,CAAC;AAEjC;;;;GAIG;AACH,MAAM,UAAU,yBAAyB,CAAC,OAAO,GAAG,SAAS;IAC3D,OAAO,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC;AACrD,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,YAAoB,EAAE,OAAO,GAAG,SAAS;IAC3E,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;IAEzD,IAAI,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QAC7B,OAAO,YAAY,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;IAC5C,CAAC;IAED,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IACnD,MAAM,gBAAgB,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,QAAQ,EAAE,YAAY,CAAC,CAAC;IAEvE,IAAI,UAAU,CAAC,gBAAgB,CAAC,EAAE,CAAC;QACjC,OAAO,YAAY,CAAC,gBAAgB,EAAE,MAAM,CAAC,CAAC;IAChD,CAAC;IAED,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC5B,MAAM,IAAI,KAAK,CACb,8BAA8B,UAAU,0EAA0E,CACnH,CAAC;IACJ,CAAC;IAED,MAAM,IAAI,KAAK,CAAC,kCAAkC,YAAY,EAAE,CAAC,CAAC;AACpE,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export interface PromptDefinition {
|
|
2
|
+
name: string;
|
|
3
|
+
description: string;
|
|
4
|
+
arguments?: Array<{
|
|
5
|
+
name: string;
|
|
6
|
+
description: string;
|
|
7
|
+
required?: boolean;
|
|
8
|
+
}>;
|
|
9
|
+
}
|
|
10
|
+
interface PromptMessage {
|
|
11
|
+
role: "user" | "assistant";
|
|
12
|
+
content: {
|
|
13
|
+
type: "text";
|
|
14
|
+
text: string;
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
export declare const prompts: PromptDefinition[];
|
|
18
|
+
export declare function getPromptMessages(name: string): PromptMessage[] | null;
|
|
19
|
+
export {};
|
|
20
|
+
//# sourceMappingURL=prompts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../src/prompts.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;CAC9E;AAED,UAAU,aAAa;IACrB,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IAC3B,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;CACzC;AAED,eAAO,MAAM,OAAO,EAAE,gBAAgB,EAoBrC,CAAC;AASF,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,EAAE,GAAG,IAAI,CAiHtE"}
|
package/dist/prompts.js
ADDED
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
export const prompts = [
|
|
2
|
+
{
|
|
3
|
+
name: "mantle_portfolioAudit",
|
|
4
|
+
description: "Guide through a complete Mantle wallet audit: balances, allowances, and risk exposure.",
|
|
5
|
+
arguments: [
|
|
6
|
+
{ name: "wallet_address", description: "Wallet address to audit.", required: true },
|
|
7
|
+
{ name: "network", description: "mainnet or sepolia (default mainnet).", required: false },
|
|
8
|
+
{ name: "scope", description: "full, balances_only, or allowances_only.", required: false }
|
|
9
|
+
]
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
name: "mantle_mantleBasics",
|
|
13
|
+
description: "Mantle network fundamentals for agents new to the ecosystem. Covers chain architecture, key tokens, and protocol landscape.",
|
|
14
|
+
arguments: []
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
name: "mantle_gasConfiguration",
|
|
18
|
+
description: "CRITICAL: MNT gas token guidance, fee estimation, and RPC configuration for Mantle.",
|
|
19
|
+
arguments: []
|
|
20
|
+
}
|
|
21
|
+
];
|
|
22
|
+
function prompt(user, assistant) {
|
|
23
|
+
return [
|
|
24
|
+
{ role: "user", content: { type: "text", text: user } },
|
|
25
|
+
{ role: "assistant", content: { type: "text", text: assistant } }
|
|
26
|
+
];
|
|
27
|
+
}
|
|
28
|
+
export function getPromptMessages(name) {
|
|
29
|
+
switch (name) {
|
|
30
|
+
case "mantle_portfolioAudit":
|
|
31
|
+
return prompt("How do I audit a wallet's portfolio on Mantle?", `# Mantle Portfolio Audit Workflow
|
|
32
|
+
|
|
33
|
+
## Step 1: Confirm Network
|
|
34
|
+
Call mantle_getChainInfo and mantle_getChainStatus first so chain id, RPC health, and gas context are explicit.
|
|
35
|
+
|
|
36
|
+
## Step 2: Read Native Balance
|
|
37
|
+
Use mantle_getBalance({ address: "<wallet>", network: "mainnet" })
|
|
38
|
+
|
|
39
|
+
## Step 3: Read ERC-20 Balances
|
|
40
|
+
Use mantle_getTokenBalances with curated symbols from mantle://registry/tokens.
|
|
41
|
+
|
|
42
|
+
## Step 4: Read Allowance Exposure
|
|
43
|
+
Use mantle_getAllowances({ owner: "<wallet>", pairs: [...] }) against known routers/spenders from mantle://registry/protocols.
|
|
44
|
+
|
|
45
|
+
## Step 5: Price and Valuation
|
|
46
|
+
Call mantle_getTokenPrices for each held token. Never fabricate missing prices.
|
|
47
|
+
|
|
48
|
+
## Step 6: Risk Classification
|
|
49
|
+
| Risk Level | Condition |
|
|
50
|
+
|------------|-----------|
|
|
51
|
+
| low | No unlimited allowances + diversified holdings |
|
|
52
|
+
| medium | One or more high notional allowances |
|
|
53
|
+
| high | Unlimited approval to core spenders or concentrated volatile holdings |
|
|
54
|
+
|
|
55
|
+
## Step 7: Final Report
|
|
56
|
+
Output: native balance, token balances, allowances, USD valuation totals, and explicit data gaps.
|
|
57
|
+
|
|
58
|
+
## Common Mistakes
|
|
59
|
+
| Mistake | Fix |
|
|
60
|
+
|---------|-----|
|
|
61
|
+
| Ignoring allowances | Always include token+spender allowance matrix |
|
|
62
|
+
| Fabricating USD values | Keep value null when price missing |
|
|
63
|
+
| Mixing networks | Normalize to mainnet/sepolia before tool calls |
|
|
64
|
+
`);
|
|
65
|
+
case "mantle_mantleBasics":
|
|
66
|
+
return prompt("What is Mantle and how does it work?", `# Mantle Network Fundamentals
|
|
67
|
+
|
|
68
|
+
## Architecture
|
|
69
|
+
Mantle is an Ethereum L2 built with OP Stack and data availability optimizations.
|
|
70
|
+
|
|
71
|
+
## Key Facts
|
|
72
|
+
| Property | Value |
|
|
73
|
+
|----------|-------|
|
|
74
|
+
| Chain ID | 5000 (mainnet), 5003 (sepolia) |
|
|
75
|
+
| Gas Token | MNT |
|
|
76
|
+
| Block Time | ~2 seconds |
|
|
77
|
+
| Finality | L1 confirmation dependent |
|
|
78
|
+
|
|
79
|
+
## Core Tokens
|
|
80
|
+
| Token | Address (mainnet) |
|
|
81
|
+
|-------|-------------------|
|
|
82
|
+
| WMNT | 0x78c1b0C915c4FAA5FffA6CAbf0219DA63d7f4cb8 |
|
|
83
|
+
| USDC | 0x09Bc4E0D864854c6aFB6eB9A9cdF58aC190D0dF9 |
|
|
84
|
+
| USDT | 0x201EBa5CC46D216Ce6DC03F6a759e8E766e956aE |
|
|
85
|
+
|
|
86
|
+
## DeFi Landscape
|
|
87
|
+
| Protocol | Category | Status |
|
|
88
|
+
|----------|----------|--------|
|
|
89
|
+
| Agni | DEX | enabled |
|
|
90
|
+
| Merchant Moe | DEX | enabled |
|
|
91
|
+
| Aave v3 | lending | enabled |
|
|
92
|
+
| Ondo | RWA | planned post-v1 |
|
|
93
|
+
|
|
94
|
+
## Getting Started
|
|
95
|
+
1. mantle_getChainInfo({ network: "mainnet" })
|
|
96
|
+
2. mantle_getChainStatus({ network: "mainnet" })
|
|
97
|
+
3. Read mantle://registry/tokens and mantle://registry/protocols
|
|
98
|
+
`);
|
|
99
|
+
case "mantle_gasConfiguration":
|
|
100
|
+
return prompt("How does gas work on Mantle?", `# Mantle Gas Configuration
|
|
101
|
+
|
|
102
|
+
## CRITICAL: Gas Token is MNT, Not ETH
|
|
103
|
+
All gas estimates and native balances are denominated in MNT.
|
|
104
|
+
|
|
105
|
+
## Gas Costs (Very Cheap)
|
|
106
|
+
| Operation | Typical Gas | Approx MNT Cost |
|
|
107
|
+
|-----------|-------------|------------------|
|
|
108
|
+
| MNT transfer | 21,000 | ~0.0002 |
|
|
109
|
+
| ERC-20 transfer | 65,000 | ~0.0006 |
|
|
110
|
+
| DEX swap | 180,000 | ~0.0016 |
|
|
111
|
+
| Contract deployment | 1M-3M | ~0.01-0.03 |
|
|
112
|
+
|
|
113
|
+
## Checking Live Gas
|
|
114
|
+
Use mantle_getChainStatus({ network: "mainnet" }) and report gas_price_gwei + block_number.
|
|
115
|
+
|
|
116
|
+
## RPC Endpoints
|
|
117
|
+
| Network | URL |
|
|
118
|
+
|---------|-----|
|
|
119
|
+
| Mainnet | https://rpc.mantle.xyz |
|
|
120
|
+
| Sepolia | https://rpc.sepolia.mantle.xyz |
|
|
121
|
+
|
|
122
|
+
## Common Mistakes
|
|
123
|
+
| Mistake | Fix |
|
|
124
|
+
|---------|-----|
|
|
125
|
+
| Assuming ETH is gas token | Use MNT for all fee math |
|
|
126
|
+
| Reusing Ethereum gas assumptions | Recalculate on Mantle chain status |
|
|
127
|
+
| Ignoring RPC fallback | Configure dedicated RPC + fallback endpoint |
|
|
128
|
+
`);
|
|
129
|
+
default:
|
|
130
|
+
return null;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
//# sourceMappingURL=prompts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompts.js","sourceRoot":"","sources":["../src/prompts.ts"],"names":[],"mappings":"AAWA,MAAM,CAAC,MAAM,OAAO,GAAuB;IACzC;QACE,IAAI,EAAE,uBAAuB;QAC7B,WAAW,EAAE,wFAAwF;QACrG,SAAS,EAAE;YACT,EAAE,IAAI,EAAE,gBAAgB,EAAE,WAAW,EAAE,0BAA0B,EAAE,QAAQ,EAAE,IAAI,EAAE;YACnF,EAAE,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,uCAAuC,EAAE,QAAQ,EAAE,KAAK,EAAE;YAC1F,EAAE,IAAI,EAAE,OAAO,EAAE,WAAW,EAAE,0CAA0C,EAAE,QAAQ,EAAE,KAAK,EAAE;SAC5F;KACF;IACD;QACE,IAAI,EAAE,qBAAqB;QAC3B,WAAW,EAAE,6HAA6H;QAC1I,SAAS,EAAE,EAAE;KACd;IACD;QACE,IAAI,EAAE,yBAAyB;QAC/B,WAAW,EAAE,qFAAqF;QAClG,SAAS,EAAE,EAAE;KACd;CACF,CAAC;AAEF,SAAS,MAAM,CAAC,IAAY,EAAE,SAAiB;IAC7C,OAAO;QACL,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE;QACvD,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE;KAClE,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,IAAY;IAC5C,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,uBAAuB;YAC1B,OAAO,MAAM,CACX,gDAAgD,EAChD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAiCP,CACM,CAAC;QACJ,KAAK,qBAAqB;YACxB,OAAO,MAAM,CACX,sCAAsC,EACtC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgCP,CACM,CAAC;QACJ,KAAK,yBAAyB;YAC5B,OAAO,MAAM,CACX,8BAA8B,EAC9B;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4BP,CACM,CAAC;QACJ;YACE,OAAO,IAAI,CAAC;IAChB,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Resource } from "@0xwh1sker/mantle-core/types.js";
|
|
2
|
+
export declare function listResources(): Resource[];
|
|
3
|
+
export declare function readResource(uri: string): {
|
|
4
|
+
content: string;
|
|
5
|
+
mimeType: string;
|
|
6
|
+
} | null;
|
|
7
|
+
export declare function prefetchResources(): Promise<void>;
|
|
8
|
+
//# sourceMappingURL=resources.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resources.d.ts","sourceRoot":"","sources":["../src/resources.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iCAAiC,CAAC;AAwDhE,wBAAgB,aAAa,IAAI,QAAQ,EAAE,CAE1C;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAgFtF;AAED,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC,CAEvD"}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import { CHAIN_CONFIGS } from "@0xwh1sker/mantle-core/config/chains.js";
|
|
2
|
+
import { getRegistryData } from "@0xwh1sker/mantle-core/lib/registry.js";
|
|
3
|
+
import { readSkillsReference } from "./lib/skills-path.js";
|
|
4
|
+
import { MANTLE_TOKENS } from "@0xwh1sker/mantle-core/config/tokens.js";
|
|
5
|
+
import { MANTLE_PROTOCOLS } from "@0xwh1sker/mantle-core/config/protocols.js";
|
|
6
|
+
import { capabilityCatalog } from "@0xwh1sker/mantle-core/capability-catalog.js";
|
|
7
|
+
const RESOURCES = [
|
|
8
|
+
{
|
|
9
|
+
uri: "mantle://chain/mainnet",
|
|
10
|
+
name: "Mantle Mainnet Configuration",
|
|
11
|
+
description: "Static chain configuration for Mantle mainnet.",
|
|
12
|
+
mimeType: "application/json"
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
uri: "mantle://chain/sepolia",
|
|
16
|
+
name: "Mantle Sepolia Testnet Configuration",
|
|
17
|
+
description: "Static chain configuration for Mantle Sepolia.",
|
|
18
|
+
mimeType: "application/json"
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
uri: "mantle://registry/contracts",
|
|
22
|
+
name: "Mantle Verified Contract Registry",
|
|
23
|
+
description: "Curated contract registry for address resolution workflows.",
|
|
24
|
+
mimeType: "application/json"
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
uri: "mantle://registry/tokens",
|
|
28
|
+
name: "Mantle Token Registry",
|
|
29
|
+
description: "Embedded quick-reference token list for Mantle networks.",
|
|
30
|
+
mimeType: "application/json"
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
uri: "mantle://registry/protocols",
|
|
34
|
+
name: "Mantle DeFi Protocol Registry",
|
|
35
|
+
description: "Protocol metadata for enabled and planned Mantle integrations.",
|
|
36
|
+
mimeType: "application/json"
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
uri: "mantle://docs/network-basics",
|
|
40
|
+
name: "Mantle Network Basics",
|
|
41
|
+
description: "Network fundamentals from mantle-network-primer references.",
|
|
42
|
+
mimeType: "text/markdown"
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
uri: "mantle://docs/risk-checklist",
|
|
46
|
+
name: "Transaction Risk Checklist",
|
|
47
|
+
description: "Pre-execution risk checklist from mantle-risk-evaluator references.",
|
|
48
|
+
mimeType: "text/markdown"
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
uri: "mantle://registry/capabilities",
|
|
52
|
+
name: "Mantle Tool Capability Catalog",
|
|
53
|
+
description: "Structured catalog of all MCP tools with semantic classification (query/analyze/execute), " +
|
|
54
|
+
"read/write nature, wallet requirements, and usage examples. " +
|
|
55
|
+
"Use this to quickly find the right tool for a task.",
|
|
56
|
+
mimeType: "application/json"
|
|
57
|
+
}
|
|
58
|
+
];
|
|
59
|
+
export function listResources() {
|
|
60
|
+
return RESOURCES;
|
|
61
|
+
}
|
|
62
|
+
export function readResource(uri) {
|
|
63
|
+
if (uri === "mantle://chain/mainnet") {
|
|
64
|
+
return {
|
|
65
|
+
content: JSON.stringify(CHAIN_CONFIGS.mainnet, null, 2),
|
|
66
|
+
mimeType: "application/json"
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
if (uri === "mantle://chain/sepolia") {
|
|
70
|
+
return {
|
|
71
|
+
content: JSON.stringify(CHAIN_CONFIGS.sepolia, null, 2),
|
|
72
|
+
mimeType: "application/json"
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
if (uri === "mantle://registry/contracts") {
|
|
76
|
+
return {
|
|
77
|
+
content: JSON.stringify(getRegistryData(), null, 2),
|
|
78
|
+
mimeType: "application/json"
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
if (uri === "mantle://registry/tokens") {
|
|
82
|
+
return {
|
|
83
|
+
content: JSON.stringify(MANTLE_TOKENS, null, 2),
|
|
84
|
+
mimeType: "application/json"
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
if (uri === "mantle://registry/protocols") {
|
|
88
|
+
return {
|
|
89
|
+
content: JSON.stringify(MANTLE_PROTOCOLS, null, 2),
|
|
90
|
+
mimeType: "application/json"
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
if (uri === "mantle://docs/network-basics") {
|
|
94
|
+
try {
|
|
95
|
+
return {
|
|
96
|
+
content: readSkillsReference("skills/mantle-network-primer/references/mantle-network-basics.md"),
|
|
97
|
+
mimeType: "text/markdown"
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
catch {
|
|
101
|
+
return {
|
|
102
|
+
content: "<!-- mantle-mcp: skills submodule not available -->\n" +
|
|
103
|
+
"# Mantle Network Basics\n\n" +
|
|
104
|
+
"This resource requires the `skills/` submodule which is not available in a standalone npm install.\n" +
|
|
105
|
+
"If you are running from the monorepo, run `npm run skills:init` to initialize it.\n",
|
|
106
|
+
mimeType: "text/markdown"
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
if (uri === "mantle://docs/risk-checklist") {
|
|
111
|
+
try {
|
|
112
|
+
return {
|
|
113
|
+
content: readSkillsReference("skills/mantle-risk-evaluator/references/risk-checklist.md"),
|
|
114
|
+
mimeType: "text/markdown"
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
catch {
|
|
118
|
+
return {
|
|
119
|
+
content: "<!-- mantle-mcp: skills submodule not available -->\n" +
|
|
120
|
+
"# Transaction Risk Checklist\n\n" +
|
|
121
|
+
"This resource requires the `skills/` submodule which is not available in a standalone npm install.\n" +
|
|
122
|
+
"If you are running from the monorepo, run `npm run skills:init` to initialize it.\n",
|
|
123
|
+
mimeType: "text/markdown"
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
if (uri === "mantle://registry/capabilities") {
|
|
128
|
+
return {
|
|
129
|
+
content: JSON.stringify(capabilityCatalog(), null, 2),
|
|
130
|
+
mimeType: "application/json"
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
return null;
|
|
134
|
+
}
|
|
135
|
+
export async function prefetchResources() {
|
|
136
|
+
return Promise.resolve();
|
|
137
|
+
}
|
|
138
|
+
//# sourceMappingURL=resources.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resources.js","sourceRoot":"","sources":["../src/resources.ts"],"names":[],"mappings":"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"}
|
package/dist/server.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AAmBnE,wBAAgB,YAAY,IAAI,MAAM,CA0FrC;AAED,wBAAsB,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC,CAkB/C"}
|
package/dist/server.js
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
3
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
4
|
+
import { CallToolRequestSchema, GetPromptRequestSchema, ListPromptsRequestSchema, ListResourcesRequestSchema, ListToolsRequestSchema, ReadResourceRequestSchema } from "@modelcontextprotocol/sdk/types.js";
|
|
5
|
+
import { MantleMcpError, toErrorPayload } from "@0xwh1sker/mantle-core/errors.js";
|
|
6
|
+
import { getPromptMessages, prompts } from "./prompts.js";
|
|
7
|
+
import { listResources, prefetchResources, readResource } from "./resources.js";
|
|
8
|
+
import { allTools } from "@0xwh1sker/mantle-core/tools/index.js";
|
|
9
|
+
const pkg = JSON.parse(readFileSync(new URL("../package.json", import.meta.url), "utf-8"));
|
|
10
|
+
export function createServer() {
|
|
11
|
+
const server = new Server({ name: "mantle-mcp", version: pkg.version }, {
|
|
12
|
+
capabilities: {
|
|
13
|
+
tools: {},
|
|
14
|
+
resources: {},
|
|
15
|
+
prompts: {}
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
19
|
+
tools: Object.values(allTools).map((tool) => ({
|
|
20
|
+
name: tool.name,
|
|
21
|
+
description: tool.description,
|
|
22
|
+
inputSchema: tool.inputSchema
|
|
23
|
+
}))
|
|
24
|
+
}));
|
|
25
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
26
|
+
const name = request.params.name;
|
|
27
|
+
const args = (request.params.arguments ?? {});
|
|
28
|
+
const tool = allTools[name];
|
|
29
|
+
if (!tool) {
|
|
30
|
+
return {
|
|
31
|
+
content: [
|
|
32
|
+
{
|
|
33
|
+
type: "text",
|
|
34
|
+
text: JSON.stringify({
|
|
35
|
+
error: true,
|
|
36
|
+
code: "UNKNOWN_TOOL",
|
|
37
|
+
message: `Unknown tool: ${name}`,
|
|
38
|
+
suggestion: "Call ListTools first to discover available tool names.",
|
|
39
|
+
details: null
|
|
40
|
+
})
|
|
41
|
+
}
|
|
42
|
+
],
|
|
43
|
+
isError: true
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
try {
|
|
47
|
+
const result = await tool.handler(args);
|
|
48
|
+
return {
|
|
49
|
+
content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
catch (error) {
|
|
53
|
+
return {
|
|
54
|
+
content: [{ type: "text", text: JSON.stringify(toErrorPayload(error)) }],
|
|
55
|
+
isError: true
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
server.setRequestHandler(ListResourcesRequestSchema, async () => ({
|
|
60
|
+
resources: listResources()
|
|
61
|
+
}));
|
|
62
|
+
server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
|
|
63
|
+
const uri = request.params.uri;
|
|
64
|
+
const resource = readResource(uri);
|
|
65
|
+
if (!resource) {
|
|
66
|
+
return {
|
|
67
|
+
contents: [{ uri, mimeType: "text/plain", text: `Resource not found: ${uri}` }]
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
return {
|
|
71
|
+
contents: [{ uri, mimeType: resource.mimeType, text: resource.content }]
|
|
72
|
+
};
|
|
73
|
+
});
|
|
74
|
+
server.setRequestHandler(ListPromptsRequestSchema, async () => ({
|
|
75
|
+
prompts: prompts
|
|
76
|
+
}));
|
|
77
|
+
server.setRequestHandler(GetPromptRequestSchema, async (request) => {
|
|
78
|
+
const messages = getPromptMessages(request.params.name);
|
|
79
|
+
if (!messages) {
|
|
80
|
+
throw new MantleMcpError("PROMPT_NOT_FOUND", `Prompt not found: ${request.params.name}`, "Call ListPrompts to discover available prompt names.", { name: request.params.name });
|
|
81
|
+
}
|
|
82
|
+
return { messages };
|
|
83
|
+
});
|
|
84
|
+
return server;
|
|
85
|
+
}
|
|
86
|
+
export async function runServer() {
|
|
87
|
+
const transportMode = process.env.MANTLE_MCP_TRANSPORT ?? "stdio";
|
|
88
|
+
if (transportMode !== "stdio") {
|
|
89
|
+
throw new Error("Only stdio transport is currently supported. Set MANTLE_MCP_TRANSPORT=stdio.");
|
|
90
|
+
}
|
|
91
|
+
const server = createServer();
|
|
92
|
+
await prefetchResources();
|
|
93
|
+
const transport = new StdioServerTransport();
|
|
94
|
+
await server.connect(transport);
|
|
95
|
+
const shutdown = async () => {
|
|
96
|
+
await server.close();
|
|
97
|
+
process.exit(0);
|
|
98
|
+
};
|
|
99
|
+
process.on("SIGINT", shutdown);
|
|
100
|
+
process.on("SIGTERM", shutdown);
|
|
101
|
+
}
|
|
102
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@0xwh1sker/mantle-mcp",
|
|
3
|
+
"version": "0.1.3",
|
|
4
|
+
"license": "MIT",
|
|
5
|
+
"description": "MCP server for AI-driven Mantle L2 development — chain reads, simulation, and unsigned transaction building",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"main": "dist/index.js",
|
|
8
|
+
"types": "dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"default": "./dist/index.js"
|
|
13
|
+
},
|
|
14
|
+
"./*.js": {
|
|
15
|
+
"types": "./dist/*.d.ts",
|
|
16
|
+
"default": "./dist/*.js"
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
"bin": {
|
|
20
|
+
"mantle-mcp": "dist/index.js"
|
|
21
|
+
},
|
|
22
|
+
"files": [
|
|
23
|
+
"dist",
|
|
24
|
+
"LICENSE",
|
|
25
|
+
"SERVER_INSTRUCTIONS.md",
|
|
26
|
+
"README.md"
|
|
27
|
+
],
|
|
28
|
+
"publishConfig": {
|
|
29
|
+
"access": "public"
|
|
30
|
+
},
|
|
31
|
+
"mcp": {
|
|
32
|
+
"serverUseInstructions": "Mantle L2 chain tools. Gas token is MNT, not ETH. CRITICAL RULES: (1) NEVER hold or request private keys - all transaction tools return unsigned payloads only. (2) ALWAYS call mantle_resolveAddress or mantle_resolveToken to verify addresses before using them in transaction-building tools; for token symbols, mantle_resolveToken must double-check against https://token-list.mantle.xyz. (3) ALWAYS ensure a fresh simulation result before presenting a transaction for signing (for mantle_build*Tx, use the returned simulation field; use mantle_simulateTx for custom calldata or re-simulation). (4) ALWAYS present the human_summary field to the user and obtain explicit confirmation before any signing step. (5) Gas estimates and native balances are in MNT. (6) When an address cannot be resolved through the registry, STOP and ask the user rather than proceeding with an unverified address."
|
|
33
|
+
},
|
|
34
|
+
"scripts": {
|
|
35
|
+
"build": "tsc && chmod +x dist/index.js",
|
|
36
|
+
"typecheck": "tsc --noEmit",
|
|
37
|
+
"prepack": "npm run build",
|
|
38
|
+
"start": "node dist/index.js"
|
|
39
|
+
},
|
|
40
|
+
"dependencies": {
|
|
41
|
+
"@0xwh1sker/mantle-core": "0.1.3",
|
|
42
|
+
"@modelcontextprotocol/sdk": "~1.27.1"
|
|
43
|
+
},
|
|
44
|
+
"engines": {
|
|
45
|
+
"node": ">=20.0.0"
|
|
46
|
+
}
|
|
47
|
+
}
|