@predge/whale-data-mcp 0.1.5 → 0.1.6
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/README.md +13 -3
- package/dist/config.js +74 -6
- package/dist/config.js.map +1 -1
- package/dist/pay.js +41 -21
- package/dist/pay.js.map +1 -1
- package/package.json +3 -1
package/README.md
CHANGED
|
@@ -69,14 +69,24 @@ ingest is enabled; raw x402/HTTP already reaches them.
|
|
|
69
69
|
|
|
70
70
|
## Config (env)
|
|
71
71
|
|
|
72
|
+
Paid tools need a funded key for **at least one rail** — Base (`BUYER_PRIVATE_KEY`)
|
|
73
|
+
and/or Solana (`SOLANA_BUYER_SECRET`). Every paid route's 402 offers both networks;
|
|
74
|
+
the client pays on whichever it holds a key for (cheapest when both). The
|
|
75
|
+
facilitator pays the network fee on either rail — the wallet needs USDC only.
|
|
76
|
+
|
|
72
77
|
| Var | Default | Notes |
|
|
73
78
|
|---|---|---|
|
|
74
|
-
| `BUYER_PRIVATE_KEY` | — | **
|
|
75
|
-
| `
|
|
76
|
-
| `
|
|
79
|
+
| `BUYER_PRIVATE_KEY` | — | Funded **Base**-mainnet EVM key (`0x…`) for the Base rail. |
|
|
80
|
+
| `SOLANA_BUYER_SECRET` | — | Optional. Funded **Solana**-mainnet key (64-number JSON array or base58) for the Solana rail. |
|
|
81
|
+
| `X402_NETWORK` | `base` | Base network: `base` = mainnet (real USDC), `base-sepolia` only against a testnet deployment. |
|
|
82
|
+
| `X402_SOLANA_NETWORK` | matches `X402_NETWORK` | `solana` (mainnet) or `solana-devnet`. |
|
|
83
|
+
| `SOLANA_RPC_URL` | @x402/svm default | Optional custom Solana RPC (public mainnet-beta is rate-limited). |
|
|
84
|
+
| `PREDGE_BASE_URL` | prod API | `https://x402-api-production-266e.up.railway.app`. Override to point at another deployment. |
|
|
77
85
|
| `MAX_PRICE_USD` | `0.05` | Any call priced above this is refused **before** paying. |
|
|
78
86
|
| `PREDGE_MCP_USER_AGENT` | `predge-whale-data-mcp/0.1.1` | Sent on every request (lets the API attribute MCP traffic). |
|
|
79
87
|
|
|
88
|
+
> The free `predge_list_endpoints` tool works without any key.
|
|
89
|
+
|
|
80
90
|
### Testnet
|
|
81
91
|
|
|
82
92
|
To exercise the payment path without real money, point `PREDGE_BASE_URL` at a
|
package/dist/config.js
CHANGED
|
@@ -11,6 +11,65 @@ function caip2(raw) {
|
|
|
11
11
|
throw new Error(`Unsupported X402_NETWORK "${raw}" (use base-sepolia | base | eip155:<id>)`);
|
|
12
12
|
return m;
|
|
13
13
|
}
|
|
14
|
+
// --- Solana rail (optional, additive) ------------------------------------
|
|
15
|
+
const SOLANA_NETWORK_ALIASES = {
|
|
16
|
+
// Human name → CAIP-2 (reference = first 32 chars of the genesis hash, case-sensitive).
|
|
17
|
+
solana: "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp",
|
|
18
|
+
"solana-devnet": "solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1",
|
|
19
|
+
};
|
|
20
|
+
function solanaCaip2(raw) {
|
|
21
|
+
const v = raw.trim();
|
|
22
|
+
if (v.toLowerCase().startsWith("solana:"))
|
|
23
|
+
return `solana:${v.slice("solana:".length)}`;
|
|
24
|
+
const m = SOLANA_NETWORK_ALIASES[v.toLowerCase()];
|
|
25
|
+
if (!m)
|
|
26
|
+
throw new Error(`Unsupported X402_SOLANA_NETWORK "${raw}" (use solana | solana-devnet | solana:<genesis>)`);
|
|
27
|
+
return m;
|
|
28
|
+
}
|
|
29
|
+
const BASE58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
|
|
30
|
+
function decodeBase58(s) {
|
|
31
|
+
let n = 0n;
|
|
32
|
+
for (const ch of s) {
|
|
33
|
+
const i = BASE58.indexOf(ch);
|
|
34
|
+
if (i < 0)
|
|
35
|
+
throw new Error(`SOLANA_BUYER_SECRET: invalid base58 character "${ch}"`);
|
|
36
|
+
n = n * 58n + BigInt(i);
|
|
37
|
+
}
|
|
38
|
+
const out = [];
|
|
39
|
+
for (let m = n; m > 0n; m >>= 8n)
|
|
40
|
+
out.unshift(Number(m & 0xffn));
|
|
41
|
+
for (const ch of s) {
|
|
42
|
+
if (ch !== "1")
|
|
43
|
+
break;
|
|
44
|
+
out.unshift(0); // leading '1' → leading zero byte
|
|
45
|
+
}
|
|
46
|
+
return Uint8Array.from(out);
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Parse a Solana buyer secret from either a 64-number JSON array (Solana CLI
|
|
50
|
+
* keypair file format) or a base58 string (e.g. a Phantom export). Must decode
|
|
51
|
+
* to exactly 64 bytes (ed25519 secret key). Returns undefined when unset so the
|
|
52
|
+
* Solana rail is purely opt-in.
|
|
53
|
+
*/
|
|
54
|
+
function parseSolanaSecret(raw) {
|
|
55
|
+
const t = raw?.trim();
|
|
56
|
+
if (!t)
|
|
57
|
+
return undefined;
|
|
58
|
+
let bytes;
|
|
59
|
+
if (t.startsWith("[")) {
|
|
60
|
+
const arr = JSON.parse(t);
|
|
61
|
+
if (!Array.isArray(arr))
|
|
62
|
+
throw new Error("SOLANA_BUYER_SECRET JSON must be an array of 64 numbers");
|
|
63
|
+
bytes = Uint8Array.from(arr);
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
bytes = decodeBase58(t);
|
|
67
|
+
}
|
|
68
|
+
if (bytes.length !== 64) {
|
|
69
|
+
throw new Error(`SOLANA_BUYER_SECRET must decode to a 64-byte Solana secret key, got ${bytes.length} bytes`);
|
|
70
|
+
}
|
|
71
|
+
return bytes;
|
|
72
|
+
}
|
|
14
73
|
function numEnv(name, def) {
|
|
15
74
|
const raw = process.env[name]?.trim();
|
|
16
75
|
if (!raw)
|
|
@@ -20,16 +79,25 @@ function numEnv(name, def) {
|
|
|
20
79
|
throw new Error(`${name} must be a positive number, got "${raw}"`);
|
|
21
80
|
return n;
|
|
22
81
|
}
|
|
82
|
+
const network = caip2(process.env.X402_NETWORK ?? "base");
|
|
23
83
|
export const config = {
|
|
24
84
|
baseUrl: (process.env.PREDGE_BASE_URL ?? "https://x402-api-production-266e.up.railway.app").replace(/\/+$/, ""),
|
|
25
|
-
// Optional so the server + free discovery tool work without
|
|
26
|
-
// tools fail clearly if
|
|
85
|
+
// EVM (Base) buyer. Optional so the server + free discovery tool work without
|
|
86
|
+
// a key; paid tools fail clearly if NO key (EVM or Solana) is set.
|
|
27
87
|
buyerKey: process.env.BUYER_PRIVATE_KEY,
|
|
28
88
|
// Default to Base MAINNET: the live Predge API is mainnet-only, so a
|
|
29
|
-
// one-command install must default here
|
|
30
|
-
//
|
|
31
|
-
|
|
32
|
-
|
|
89
|
+
// one-command install must default here. Override X402_NETWORK=base-sepolia
|
|
90
|
+
// only against a testnet deployment. MAX_PRICE_USD bounds spend either way.
|
|
91
|
+
network,
|
|
92
|
+
// Solana rail — ADDITIVE and opt-in. Set SOLANA_BUYER_SECRET (a funded Solana
|
|
93
|
+
// key, 64-number JSON array or base58) to ALSO be able to pay on Solana; every
|
|
94
|
+
// paid route's 402 offers both Base and Solana, and the client picks whichever
|
|
95
|
+
// network it holds a key for (cheapest when it holds both). The facilitator
|
|
96
|
+
// pays the network fee on Solana too — the buyer needs USDC only.
|
|
97
|
+
solanaBuyerSecret: parseSolanaSecret(process.env.SOLANA_BUYER_SECRET),
|
|
98
|
+
solanaNetwork: solanaCaip2(process.env.X402_SOLANA_NETWORK ?? (network === "eip155:8453" ? "solana" : "solana-devnet")),
|
|
99
|
+
// Optional custom Solana RPC (the public mainnet-beta endpoint is rate-limited).
|
|
100
|
+
solanaRpcUrl: process.env.SOLANA_RPC_URL?.trim() || undefined,
|
|
33
101
|
maxPriceUsd: numEnv("MAX_PRICE_USD", 0.05),
|
|
34
102
|
userAgent: process.env.PREDGE_MCP_USER_AGENT ?? "predge-whale-data-mcp/0.1.1",
|
|
35
103
|
};
|
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,MAAM,eAAe,GAA2B;IAC9C,cAAc,EAAE,cAAc;IAC9B,IAAI,EAAE,aAAa;CACpB,CAAC;AAEF,SAAS,KAAK,CAAC,GAAW;IACxB,MAAM,CAAC,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACnC,IAAI,CAAC,CAAC,UAAU,CAAC,SAAS,CAAC;QAAE,OAAO,CAAC,CAAC;IACtC,MAAM,CAAC,GAAG,eAAe,CAAC,CAAC,CAAC,CAAC;IAC7B,IAAI,CAAC,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,6BAA6B,GAAG,2CAA2C,CAAC,CAAC;IACrG,OAAO,CAAC,CAAC;AACX,CAAC;AAED,SAAS,MAAM,CAAC,IAAY,EAAE,GAAW;IACvC,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,CAAC;IACtC,IAAI,CAAC,GAAG;QAAE,OAAO,GAAG,CAAC;IACrB,MAAM,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;IACtB,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,GAAG,IAAI,oCAAoC,GAAG,GAAG,CAAC,CAAC;IACtG,OAAO,CAAC,CAAC;AACX,CAAC;AAED,MAAM,CAAC,MAAM,MAAM,GAAG;IACpB,OAAO,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,iDAAiD,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;IAC/G,
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
package/dist/pay.js
CHANGED
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* x402-paying HTTP layer for the MCP tools. One shared client signs
|
|
3
|
-
*
|
|
4
|
-
* on
|
|
5
|
-
*
|
|
2
|
+
* x402-paying HTTP layer for the MCP tools. One shared client signs payments
|
|
3
|
+
* with the operator's key(s); the facilitator settles on-chain (no gas token
|
|
4
|
+
* needed on either rail). Two rails, both opt-in via env:
|
|
5
|
+
* - Base — BUYER_PRIVATE_KEY (EVM, EIP-3009)
|
|
6
|
+
* - Solana — SOLANA_BUYER_SECRET (ed25519, SPL-USDC transfer)
|
|
7
|
+
* Every paid route's 402 offers both; the selector pays on whichever network a
|
|
8
|
+
* key is registered for (cheapest when both). Two guards fire in the selector
|
|
9
|
+
* BEFORE any money moves and cost no extra request:
|
|
6
10
|
* - price cap (MAX_PRICE_USD) — refuse calls priced above the cap
|
|
7
|
-
* - network — only pay
|
|
8
|
-
*
|
|
11
|
+
* - network — only pay a network we hold a key for (won't accidentally pay
|
|
12
|
+
* a mainnet requirement while in testnet mode)
|
|
9
13
|
*
|
|
10
14
|
* Every request carries a recognizable User-Agent so MCP-originated calls
|
|
11
15
|
* are attributable in the API's discovery-funnel analytics.
|
|
@@ -13,6 +17,8 @@
|
|
|
13
17
|
import { privateKeyToAccount } from "viem/accounts";
|
|
14
18
|
import { wrapFetchWithPayment, x402Client, decodePaymentResponseHeader } from "@x402/fetch";
|
|
15
19
|
import { ExactEvmScheme } from "@x402/evm/exact/client";
|
|
20
|
+
import { ExactSvmScheme } from "@x402/svm/exact/client";
|
|
21
|
+
import { createKeyPairSignerFromBytes } from "@solana/kit";
|
|
16
22
|
import { config } from "./config.js";
|
|
17
23
|
export class PaymentError extends Error {
|
|
18
24
|
}
|
|
@@ -28,37 +34,51 @@ function amountUsd(r) {
|
|
|
28
34
|
}
|
|
29
35
|
}
|
|
30
36
|
let cachedFetch = null;
|
|
31
|
-
function payingFetch() {
|
|
37
|
+
async function payingFetch() {
|
|
32
38
|
if (cachedFetch)
|
|
33
39
|
return cachedFetch;
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
"The
|
|
40
|
+
const hasEvm = Boolean(config.buyerKey);
|
|
41
|
+
const hasSvm = Boolean(config.solanaBuyerSecret);
|
|
42
|
+
if (!hasEvm && !hasSvm) {
|
|
43
|
+
throw new PaymentError("No buyer key set. Paid tools need a funded key for at least one rail: " +
|
|
44
|
+
"BUYER_PRIVATE_KEY (a Base-mainnet EVM key) and/or SOLANA_BUYER_SECRET (a Solana-mainnet key; " +
|
|
45
|
+
"64-number JSON array or base58). The facilitator pays the network fee on either rail — the " +
|
|
46
|
+
"wallet needs USDC only. Set one in the MCP server env. The free tool predge_list_endpoints " +
|
|
47
|
+
"works without a key.");
|
|
40
48
|
}
|
|
41
|
-
|
|
49
|
+
// Networks we can actually pay on — one per registered scheme.
|
|
50
|
+
const payable = new Set();
|
|
51
|
+
if (hasEvm)
|
|
52
|
+
payable.add(config.network); // eip155:… (config.network)
|
|
53
|
+
if (hasSvm)
|
|
54
|
+
payable.add(config.solanaNetwork); // solana:…
|
|
42
55
|
const client = new x402Client((_v, reqs) => {
|
|
43
|
-
const
|
|
44
|
-
if (
|
|
45
|
-
throw new PaymentError(`no
|
|
56
|
+
const options = reqs.filter((r) => (r.scheme ?? "exact") === "exact" && !!r.network && payable.has(r.network));
|
|
57
|
+
if (options.length === 0) {
|
|
58
|
+
throw new PaymentError(`no payable option: server offered [${reqs.map((r) => r.network).join(", ") || "none"}], ` +
|
|
59
|
+
`we hold a key for [${[...payable].join(", ") || "none"}] — set BUYER_PRIVATE_KEY / ` +
|
|
60
|
+
"SOLANA_BUYER_SECRET for the network you want to pay on");
|
|
46
61
|
}
|
|
47
|
-
// Cheapest
|
|
48
|
-
const chosen =
|
|
62
|
+
// Cheapest payable requirement (Base and Solana are the same price today).
|
|
63
|
+
const chosen = options.reduce((a, b) => ((amountUsd(a) ?? Infinity) <= (amountUsd(b) ?? Infinity) ? a : b));
|
|
49
64
|
const price = amountUsd(chosen);
|
|
50
65
|
if (price !== null && price > config.maxPriceUsd) {
|
|
51
66
|
throw new PaymentError(`price $${price.toFixed(3)} exceeds MAX_PRICE_USD $${config.maxPriceUsd.toFixed(3)} — refusing to pay`);
|
|
52
67
|
}
|
|
53
68
|
return chosen;
|
|
54
69
|
});
|
|
55
|
-
|
|
70
|
+
if (hasEvm)
|
|
71
|
+
client.register("eip155:*", new ExactEvmScheme(privateKeyToAccount(config.buyerKey)));
|
|
72
|
+
if (hasSvm) {
|
|
73
|
+
const solanaSigner = await createKeyPairSignerFromBytes(config.solanaBuyerSecret);
|
|
74
|
+
client.register("solana:*", new ExactSvmScheme(solanaSigner, config.solanaRpcUrl ? { rpcUrl: config.solanaRpcUrl } : undefined));
|
|
75
|
+
}
|
|
56
76
|
cachedFetch = wrapFetchWithPayment(fetch, client);
|
|
57
77
|
return cachedFetch;
|
|
58
78
|
}
|
|
59
79
|
/** GET a paid route, paying under the hood. Returns parsed JSON + settle info. */
|
|
60
80
|
export async function payGet(path) {
|
|
61
|
-
const f = payingFetch();
|
|
81
|
+
const f = await payingFetch();
|
|
62
82
|
const res = await f(`${config.baseUrl}${path}`, {
|
|
63
83
|
method: "GET",
|
|
64
84
|
headers: { "user-agent": config.userAgent },
|
package/dist/pay.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pay.js","sourceRoot":"","sources":["../src/pay.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"pay.js","sourceRoot":"","sources":["../src/pay.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@predge/whale-data-mcp",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.6",
|
|
4
4
|
"description": "MCP server exposing the Predge Whale Data x402 API (Polymarket whale trades + smart-money signals) as tools. Pays USDC per call under the hood via an x402 client; the operator supplies a funded buyer key.",
|
|
5
5
|
"mcpName": "io.github.predgeAI/whale-data-mcp",
|
|
6
6
|
"type": "module",
|
|
@@ -49,9 +49,11 @@
|
|
|
49
49
|
},
|
|
50
50
|
"dependencies": {
|
|
51
51
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
52
|
+
"@solana/kit": "^5.5.1",
|
|
52
53
|
"@x402/core": "~2.19.0",
|
|
53
54
|
"@x402/evm": "~2.19.0",
|
|
54
55
|
"@x402/fetch": "~2.19.0",
|
|
56
|
+
"@x402/svm": "~2.19.0",
|
|
55
57
|
"viem": "^2.55.0",
|
|
56
58
|
"zod": "^4.4.0"
|
|
57
59
|
},
|