@andrewkimjoseph/celina 0.2.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/LICENSE +21 -0
- package/README.md +225 -0
- package/bin/cli.js +2 -0
- package/build/clients/celo-client.d.ts +14 -0
- package/build/clients/celo-client.js +58 -0
- package/build/clients/celo-client.js.map +1 -0
- package/build/config/chains.d.ts +932 -0
- package/build/config/chains.js +236 -0
- package/build/config/chains.js.map +1 -0
- package/build/config/env.d.ts +5 -0
- package/build/config/env.js +7 -0
- package/build/config/env.js.map +1 -0
- package/build/context/app-context.d.ts +16 -0
- package/build/context/app-context.js +17 -0
- package/build/context/app-context.js.map +1 -0
- package/build/crypto/wallet-key-crypto.d.ts +11 -0
- package/build/crypto/wallet-key-crypto.js +57 -0
- package/build/crypto/wallet-key-crypto.js.map +1 -0
- package/build/http.d.ts +2 -0
- package/build/http.js +14 -0
- package/build/http.js.map +1 -0
- package/build/index.d.ts +2 -0
- package/build/index.js +14 -0
- package/build/index.js.map +1 -0
- package/build/schemas/common.d.ts +4 -0
- package/build/schemas/common.js +16 -0
- package/build/schemas/common.js.map +1 -0
- package/build/server/create-http-app.d.ts +1 -0
- package/build/server/create-http-app.js +134 -0
- package/build/server/create-http-app.js.map +1 -0
- package/build/server/create-server.d.ts +2 -0
- package/build/server/create-server.js +21 -0
- package/build/server/create-server.js.map +1 -0
- package/build/server/instructions.d.ts +1 -0
- package/build/server/instructions.js +13 -0
- package/build/server/instructions.js.map +1 -0
- package/build/services/account.service.d.ts +13 -0
- package/build/services/account.service.js +23 -0
- package/build/services/account.service.js.map +1 -0
- package/build/services/blockchain.service.d.ts +40 -0
- package/build/services/blockchain.service.js +81 -0
- package/build/services/blockchain.service.js.map +1 -0
- package/build/services/token.service.d.ts +54 -0
- package/build/services/token.service.js +147 -0
- package/build/services/token.service.js.map +1 -0
- package/build/services/transaction.service.d.ts +33 -0
- package/build/services/transaction.service.js +126 -0
- package/build/services/transaction.service.js.map +1 -0
- package/build/tools/blockchain.tools.d.ts +3 -0
- package/build/tools/blockchain.tools.js +88 -0
- package/build/tools/blockchain.tools.js.map +1 -0
- package/build/tools/helpers.d.ts +3 -0
- package/build/tools/helpers.js +16 -0
- package/build/tools/helpers.js.map +1 -0
- package/build/tools/index.d.ts +5 -0
- package/build/tools/index.js +17 -0
- package/build/tools/index.js.map +1 -0
- package/build/tools/token.tools.d.ts +2 -0
- package/build/tools/token.tools.js +62 -0
- package/build/tools/token.tools.js.map +1 -0
- package/build/tools/transaction.tools.d.ts +2 -0
- package/build/tools/transaction.tools.js +68 -0
- package/build/tools/transaction.tools.js.map +1 -0
- package/build/tools/types.d.ts +5 -0
- package/build/tools/types.js +2 -0
- package/build/tools/types.js.map +1 -0
- package/build/tools/wallet.tools.d.ts +2 -0
- package/build/tools/wallet.tools.js +23 -0
- package/build/tools/wallet.tools.js.map +1 -0
- package/package.json +54 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Andrew Kim Joseph
|
|
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,225 @@
|
|
|
1
|
+
# Celina — Celo MCP Server
|
|
2
|
+
|
|
3
|
+
**Celina** is an open-source [Model Context Protocol](https://modelcontextprotocol.io) server that gives LLMs read + write access to **Celo mainnet** — balances, stablecoins, sends, swaps (quote stub), and chain reads.
|
|
4
|
+
|
|
5
|
+
Website: [celina.andrewkimjoseph.com](https://celina.andrewkimjoseph.com)
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm i @andrewkimjoseph/celina
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
npm: [@andrewkimjoseph/celina](https://www.npmjs.com/package/@andrewkimjoseph/celina)
|
|
14
|
+
|
|
15
|
+
## Quick start
|
|
16
|
+
|
|
17
|
+
**From npm** (stdio MCP server):
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npx @andrewkimjoseph/celina
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
**From source** (development):
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
npm install
|
|
27
|
+
npm run build
|
|
28
|
+
npm start
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Deploy to Render
|
|
32
|
+
|
|
33
|
+
This project includes a [Render Blueprint](render.yaml) for one-click deployment as a public Streamable HTTP MCP server.
|
|
34
|
+
|
|
35
|
+
### 1. Generate an RSA key pair
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
openssl genpkey -algorithm RSA -out private.pem -pkeyopt rsa_keygen_bits:2048
|
|
39
|
+
openssl rsa -pubout -in private.pem -out public.pem
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### 2. Deploy
|
|
43
|
+
|
|
44
|
+
1. Push this repo to GitHub
|
|
45
|
+
2. Render Dashboard → **New → Blueprint** → connect the repo
|
|
46
|
+
3. Set `WALLET_ENCRYPTION_PRIVATE_KEY` in the Render Environment tab (paste contents of `private.pem`)
|
|
47
|
+
4. Your MCP endpoint will be at `https://celina.onrender.com/mcp`
|
|
48
|
+
|
|
49
|
+
> **Note:** Free Render services spin down after ~15 minutes of inactivity. Cold starts can take 30–60 seconds and may cause MCP client timeouts. Use a Starter plan for always-on hosting.
|
|
50
|
+
|
|
51
|
+
## Cursor / Claude Desktop config
|
|
52
|
+
|
|
53
|
+
### Remote (Render — recommended)
|
|
54
|
+
|
|
55
|
+
```json
|
|
56
|
+
{
|
|
57
|
+
"mcpServers": {
|
|
58
|
+
"celina": {
|
|
59
|
+
"command": "npx",
|
|
60
|
+
"args": [
|
|
61
|
+
"-y",
|
|
62
|
+
"mcp-remote",
|
|
63
|
+
"https://celina.onrender.com/mcp",
|
|
64
|
+
"--transport",
|
|
65
|
+
"http-only"
|
|
66
|
+
]
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Or with streamable HTTP directly:
|
|
73
|
+
|
|
74
|
+
```json
|
|
75
|
+
{
|
|
76
|
+
"mcpServers": {
|
|
77
|
+
"celina": {
|
|
78
|
+
"type": "streamable-http",
|
|
79
|
+
"url": "https://celina.onrender.com/mcp"
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### Local stdio (npm)
|
|
86
|
+
|
|
87
|
+
```json
|
|
88
|
+
{
|
|
89
|
+
"mcpServers": {
|
|
90
|
+
"celina": {
|
|
91
|
+
"command": "npx",
|
|
92
|
+
"args": ["-y", "@andrewkimjoseph/celina"]
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### Local stdio (from source)
|
|
99
|
+
|
|
100
|
+
```json
|
|
101
|
+
{
|
|
102
|
+
"mcpServers": {
|
|
103
|
+
"celina": {
|
|
104
|
+
"command": "node",
|
|
105
|
+
"args": ["/absolute/path/to/celina/build/index.js"]
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
For local write tools, add a funded mainnet wallet:
|
|
112
|
+
|
|
113
|
+
```json
|
|
114
|
+
"env": {
|
|
115
|
+
"CELO_PRIVATE_KEY": "0x..."
|
|
116
|
+
}
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
Never commit private keys. Use env vars only.
|
|
120
|
+
|
|
121
|
+
## Write tools (hosted mode)
|
|
122
|
+
|
|
123
|
+
Write tools (`send_token`, `estimate_send`) accept an RSA-encrypted private key per request — never plaintext.
|
|
124
|
+
|
|
125
|
+
### Flow
|
|
126
|
+
|
|
127
|
+
1. Fetch the server's public key:
|
|
128
|
+
- MCP tool: `get_wallet_encryption_public_key`
|
|
129
|
+
- HTTP: `GET https://celina.onrender.com/public-key`
|
|
130
|
+
2. Encrypt your key locally:
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
npm run encrypt-key -- --url https://celina.onrender.com --key 0xYOUR_PRIVATE_KEY
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
3. Give the agent the encrypted blob (base64 output) along with your transaction details
|
|
137
|
+
4. The agent calls `send_token` with the `encryptedPrivateKey` parameter
|
|
138
|
+
|
|
139
|
+
The server decrypts the key ephemerally to sign the transaction — it is not stored.
|
|
140
|
+
|
|
141
|
+
## Environment variables
|
|
142
|
+
|
|
143
|
+
| Variable | Default | Description |
|
|
144
|
+
|----------|---------|-------------|
|
|
145
|
+
| `CELO_RPC_URL_MAINNET` | Forno public RPC | Override mainnet RPC |
|
|
146
|
+
| `CELO_PRIVATE_KEY` | — | Local stdio write tools only |
|
|
147
|
+
| `WALLET_ENCRYPTION_PRIVATE_KEY` | — | RSA private key PEM for HTTP write tools |
|
|
148
|
+
| `PORT` | `10000` | HTTP server port (set by Render) |
|
|
149
|
+
|
|
150
|
+
Copy `.env.example` to `.env` for local development.
|
|
151
|
+
|
|
152
|
+
## Known tokens
|
|
153
|
+
|
|
154
|
+
All supported tokens live in a single registry (`src/config/chains.ts`):
|
|
155
|
+
|
|
156
|
+
| Category | Symbols |
|
|
157
|
+
|----------|---------|
|
|
158
|
+
| Native | `CELO` |
|
|
159
|
+
| Mento stablecoins | `USDm`, `EURm`, `BRLm`, `XOFm`, `KESm`, `PHPm`, `COPm`, `GBPm`, `CADm`, `AUDm`, `ZARm`, `GHSm`, `NGNm`, `JPYm`, `CHFm` |
|
|
160
|
+
| Bridged / third-party | `USDT`, `USDC`, `vEUR`, `vGBP`, `vCHF`, `USDM`, `USDA`, `EURA`, `USDGLO`, `BRLA`, `COPM` |
|
|
161
|
+
| GoodDollar | `GoodDollar`, `G$` (`0x62B8B11039FcfE5aB0C56E502b1C372A3d2a9c7A`) |
|
|
162
|
+
|
|
163
|
+
Token symbols are resolved case-insensitively. Legacy aliases `cUSD` and `cEUR` map to `USDm` and `EURm`. You can also pass any ERC-20 contract address directly.
|
|
164
|
+
|
|
165
|
+
- `get_celo_balances` — check specific tokens (defaults to `CELO` + `USDm`)
|
|
166
|
+
- `get_stablecoin_balances` — scan all registry stablecoins in one call (omits zero balances by default)
|
|
167
|
+
|
|
168
|
+
## Tools (v0.2)
|
|
169
|
+
|
|
170
|
+
| Tool | Type | Description |
|
|
171
|
+
|------|------|-------------|
|
|
172
|
+
| `get_network_status` | read | Mainnet chain ID, block, gas price |
|
|
173
|
+
| `get_block` | read | Block by number/hash/latest |
|
|
174
|
+
| `get_latest_blocks` | read | Recent blocks |
|
|
175
|
+
| `get_transaction` | read | Tx + receipt |
|
|
176
|
+
| `get_account` | read | CELO balance, nonce |
|
|
177
|
+
| `get_celo_balances` | read | CELO + ERC-20 balances (default: CELO + USDm) |
|
|
178
|
+
| `get_stablecoin_balances` | read | All registry stablecoins including GoodDollar |
|
|
179
|
+
| `get_token_info` | read | Token metadata |
|
|
180
|
+
| `get_wallet_encryption_public_key` | read | RSA public key for encrypting private keys |
|
|
181
|
+
| `estimate_send` | read* | Gas estimate (*needs encrypted or env key) |
|
|
182
|
+
| `send_token` | write | Send CELO or ERC-20 |
|
|
183
|
+
| `get_swap_quote` | read | Swap preview (routing stub) |
|
|
184
|
+
|
|
185
|
+
## Adding a new tool
|
|
186
|
+
|
|
187
|
+
1. Create `src/tools/my-feature.tools.ts` implementing `ToolModule`:
|
|
188
|
+
|
|
189
|
+
```typescript
|
|
190
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
191
|
+
import type { AppContext } from "../context/app-context.js";
|
|
192
|
+
import type { ToolModule } from "./types.js";
|
|
193
|
+
|
|
194
|
+
export const myFeatureTools: ToolModule = {
|
|
195
|
+
register(server, ctx) {
|
|
196
|
+
server.registerTool("my_tool", { /* ... */ }, async (args) => { /* ... */ });
|
|
197
|
+
},
|
|
198
|
+
};
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
2. Append to `toolModules` in `src/tools/index.ts`.
|
|
202
|
+
3. Add domain logic in `src/services/` if needed.
|
|
203
|
+
4. Rebuild: `npm run build`.
|
|
204
|
+
|
|
205
|
+
No changes to `src/index.ts` or server bootstrap required.
|
|
206
|
+
|
|
207
|
+
## Roadmap
|
|
208
|
+
|
|
209
|
+
- [ ] Mento / DEX swap routing (`execute_swap`)
|
|
210
|
+
- [ ] Aave lending tools
|
|
211
|
+
- [ ] Self proof verification (`ai.self.xyz`)
|
|
212
|
+
- [ ] Self Agent ID check
|
|
213
|
+
|
|
214
|
+
## Development
|
|
215
|
+
|
|
216
|
+
```bash
|
|
217
|
+
npm run dev # watch TypeScript
|
|
218
|
+
npm run inspect # MCP Inspector UI (stdio)
|
|
219
|
+
npm run start:http # HTTP server on PORT (default 10000)
|
|
220
|
+
npm run encrypt-key # encrypt a private key for write tools
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
## License
|
|
224
|
+
|
|
225
|
+
MIT
|
package/bin/cli.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { type PublicClient, type WalletClient } from "viem";
|
|
2
|
+
import type { AppConfig } from "../config/env.js";
|
|
3
|
+
export interface CeloClients {
|
|
4
|
+
public: PublicClient;
|
|
5
|
+
wallet?: WalletClient;
|
|
6
|
+
accountAddress?: `0x${string}`;
|
|
7
|
+
}
|
|
8
|
+
export declare class CeloClientFactory {
|
|
9
|
+
private readonly config;
|
|
10
|
+
private clients;
|
|
11
|
+
constructor(config: AppConfig);
|
|
12
|
+
getClients(): CeloClients;
|
|
13
|
+
getClientsForAccount(privateKey: `0x${string}`): CeloClients;
|
|
14
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { createPublicClient, createWalletClient, http, } from "viem";
|
|
2
|
+
import { privateKeyToAccount } from "viem/accounts";
|
|
3
|
+
import { CHAIN, DEFAULT_RPC_URL } from "../config/chains.js";
|
|
4
|
+
export class CeloClientFactory {
|
|
5
|
+
config;
|
|
6
|
+
clients = null;
|
|
7
|
+
constructor(config) {
|
|
8
|
+
this.config = config;
|
|
9
|
+
}
|
|
10
|
+
getClients() {
|
|
11
|
+
if (this.clients) {
|
|
12
|
+
return this.clients;
|
|
13
|
+
}
|
|
14
|
+
const rpcUrl = this.config.rpcUrl ?? DEFAULT_RPC_URL;
|
|
15
|
+
const transport = http(rpcUrl);
|
|
16
|
+
const publicClient = createPublicClient({
|
|
17
|
+
chain: CHAIN,
|
|
18
|
+
transport,
|
|
19
|
+
});
|
|
20
|
+
let wallet;
|
|
21
|
+
let accountAddress;
|
|
22
|
+
if (this.config.privateKey) {
|
|
23
|
+
const account = privateKeyToAccount(this.config.privateKey);
|
|
24
|
+
accountAddress = account.address;
|
|
25
|
+
wallet = createWalletClient({
|
|
26
|
+
account,
|
|
27
|
+
chain: CHAIN,
|
|
28
|
+
transport,
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
this.clients = {
|
|
32
|
+
public: publicClient,
|
|
33
|
+
wallet,
|
|
34
|
+
accountAddress,
|
|
35
|
+
};
|
|
36
|
+
return this.clients;
|
|
37
|
+
}
|
|
38
|
+
getClientsForAccount(privateKey) {
|
|
39
|
+
const rpcUrl = this.config.rpcUrl ?? DEFAULT_RPC_URL;
|
|
40
|
+
const transport = http(rpcUrl);
|
|
41
|
+
const publicClient = createPublicClient({
|
|
42
|
+
chain: CHAIN,
|
|
43
|
+
transport,
|
|
44
|
+
});
|
|
45
|
+
const account = privateKeyToAccount(privateKey);
|
|
46
|
+
const wallet = createWalletClient({
|
|
47
|
+
account,
|
|
48
|
+
chain: CHAIN,
|
|
49
|
+
transport,
|
|
50
|
+
});
|
|
51
|
+
return {
|
|
52
|
+
public: publicClient,
|
|
53
|
+
wallet,
|
|
54
|
+
accountAddress: account.address,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=celo-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"celo-client.js","sourceRoot":"","sources":["../../src/clients/celo-client.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,EAClB,kBAAkB,EAClB,IAAI,GAGL,MAAM,MAAM,CAAC;AACd,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAEpD,OAAO,EAAE,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAQ7D,MAAM,OAAO,iBAAiB;IAGC;IAFrB,OAAO,GAAuB,IAAI,CAAC;IAE3C,YAA6B,MAAiB;QAAjB,WAAM,GAAN,MAAM,CAAW;IAAG,CAAC;IAElD,UAAU;QACR,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACjB,OAAO,IAAI,CAAC,OAAO,CAAC;QACtB,CAAC;QAED,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,IAAI,eAAe,CAAC;QACrD,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC;QAC/B,MAAM,YAAY,GAAG,kBAAkB,CAAC;YACtC,KAAK,EAAE,KAAK;YACZ,SAAS;SACV,CAAiB,CAAC;QAEnB,IAAI,MAAgC,CAAC;QACrC,IAAI,cAAyC,CAAC;QAE9C,IAAI,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC;YAC3B,MAAM,OAAO,GAAG,mBAAmB,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;YAC5D,cAAc,GAAG,OAAO,CAAC,OAAO,CAAC;YACjC,MAAM,GAAG,kBAAkB,CAAC;gBAC1B,OAAO;gBACP,KAAK,EAAE,KAAK;gBACZ,SAAS;aACV,CAAC,CAAC;QACL,CAAC;QAED,IAAI,CAAC,OAAO,GAAG;YACb,MAAM,EAAE,YAAY;YACpB,MAAM;YACN,cAAc;SACf,CAAC;QAEF,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;IAED,oBAAoB,CAAC,UAAyB;QAC5C,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,IAAI,eAAe,CAAC;QACrD,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC;QAC/B,MAAM,YAAY,GAAG,kBAAkB,CAAC;YACtC,KAAK,EAAE,KAAK;YACZ,SAAS;SACV,CAAiB,CAAC;QACnB,MAAM,OAAO,GAAG,mBAAmB,CAAC,UAAU,CAAC,CAAC;QAEhD,MAAM,MAAM,GAAG,kBAAkB,CAAC;YAChC,OAAO;YACP,KAAK,EAAE,KAAK;YACZ,SAAS;SACV,CAAC,CAAC;QAEH,OAAO;YACL,MAAM,EAAE,YAAY;YACpB,MAAM;YACN,cAAc,EAAE,OAAO,CAAC,OAAO;SAChC,CAAC;IACJ,CAAC;CACF"}
|