moltspay 1.4.1 → 1.6.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/README.md +187 -0
- package/dist/cli/index.js +486 -152
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/index.mjs +483 -149
- package/dist/cli/index.mjs.map +1 -1
- package/dist/client/index.d.mts +5 -0
- package/dist/client/index.d.ts +5 -0
- package/dist/client/index.js +245 -116
- package/dist/client/index.js.map +1 -1
- package/dist/client/index.mjs +241 -114
- package/dist/client/index.mjs.map +1 -1
- package/dist/client/web/index.d.mts +418 -0
- package/dist/client/web/index.mjs +1289 -0
- package/dist/client/web/index.mjs.map +1 -0
- package/dist/facilitators/index.d.mts +24 -2
- package/dist/facilitators/index.d.ts +24 -2
- package/dist/facilitators/index.js +127 -13
- package/dist/facilitators/index.js.map +1 -1
- package/dist/facilitators/index.mjs +127 -13
- package/dist/facilitators/index.mjs.map +1 -1
- package/dist/index.js +463 -149
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +460 -146
- package/dist/index.mjs.map +1 -1
- package/dist/mcp/index.d.mts +1 -0
- package/dist/mcp/index.d.ts +1 -0
- package/dist/mcp/index.js +1623 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp/index.mjs +1617 -0
- package/dist/mcp/index.mjs.map +1 -0
- package/dist/server/index.d.mts +43 -1
- package/dist/server/index.d.ts +43 -1
- package/dist/server/index.js +205 -18
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +205 -18
- package/dist/server/index.mjs.map +1 -1
- package/package.json +19 -4
package/README.md
CHANGED
|
@@ -27,6 +27,7 @@ MoltsPay enables agent-to-agent commerce using the [x402 protocol](https://www.x
|
|
|
27
27
|
- **Multi-chain** - Base, Polygon, Solana, BNB, Tempo (mainnet & testnet)
|
|
28
28
|
- **Agent-to-Agent** - Complete A2A payment flow support
|
|
29
29
|
- **Multi-VM** - EVM chains + Solana (SVM) with unified API
|
|
30
|
+
- **MCP Server** - Expose wallet + payments to Claude Desktop, Cursor, and other MCP hosts
|
|
30
31
|
|
|
31
32
|
## Installation
|
|
32
33
|
|
|
@@ -133,6 +134,192 @@ npx moltspay pay https://server.com service-id \
|
|
|
133
134
|
--chain tempo_moderato --prompt "test"
|
|
134
135
|
```
|
|
135
136
|
|
|
137
|
+
### For Web Apps (Browser)
|
|
138
|
+
|
|
139
|
+
`moltspay@1.6.0` adds a browser client. Connect any EIP-1193 wallet (MetaMask, Rainbow, Frame, …) for EVM or a `@solana/wallet-adapter` wallet (Phantom, Solflare, Backpack, …) for Solana and pay for x402 services directly from the page — no private key ever in browser memory, no CLI wrapper.
|
|
140
|
+
|
|
141
|
+
**Install:**
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
npm install moltspay
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
**Pay with MetaMask:**
|
|
148
|
+
|
|
149
|
+
```ts
|
|
150
|
+
import { MoltsPayWebClient, eip1193Signer } from 'moltspay/web';
|
|
151
|
+
|
|
152
|
+
const client = new MoltsPayWebClient({
|
|
153
|
+
signer: eip1193Signer(window.ethereum),
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
// Discover what the provider accepts
|
|
157
|
+
const { provider, services } = await client.getServices('https://provider.example.com');
|
|
158
|
+
|
|
159
|
+
// Run a paid call — user sees one wallet signature prompt
|
|
160
|
+
const result = await client.pay(
|
|
161
|
+
'https://provider.example.com',
|
|
162
|
+
'text-to-video',
|
|
163
|
+
{ prompt: 'a cat dancing' },
|
|
164
|
+
{ chain: 'base' }
|
|
165
|
+
);
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
**Pay with Phantom (Solana):**
|
|
169
|
+
|
|
170
|
+
```ts
|
|
171
|
+
import { MoltsPayWebClient, solanaSigner } from 'moltspay/web';
|
|
172
|
+
import { useWallet } from '@solana/wallet-adapter-react';
|
|
173
|
+
|
|
174
|
+
const wallet = useWallet();
|
|
175
|
+
const client = new MoltsPayWebClient({ signer: solanaSigner(wallet) });
|
|
176
|
+
|
|
177
|
+
await client.pay(serverUrl, 'text-to-video', params, { chain: 'solana_devnet' });
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
**EVM + Solana in one client** — use `composeSigners` so the same `MoltsPayWebClient` instance routes to whichever signer matches the picked chain:
|
|
181
|
+
|
|
182
|
+
```ts
|
|
183
|
+
import { MoltsPayWebClient, composeSigners, eip1193Signer, solanaSigner } from 'moltspay/web';
|
|
184
|
+
|
|
185
|
+
const client = new MoltsPayWebClient({
|
|
186
|
+
signer: composeSigners(
|
|
187
|
+
eip1193Signer(window.ethereum),
|
|
188
|
+
solanaSigner(phantomAdapter),
|
|
189
|
+
),
|
|
190
|
+
});
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
**Chain coverage.** All 8 chains the CLI supports work from the browser with one signature prompt each:
|
|
194
|
+
|
|
195
|
+
| Chain | Scheme | User gas? | Notes |
|
|
196
|
+
|---|---|---|---|
|
|
197
|
+
| `base` / `polygon` / `base_sepolia` | EIP-3009 `transferWithAuthorization` | No (gasless) | Provider submits on success |
|
|
198
|
+
| `tempo_moderato` | EIP-2612 `permit` | No (gasless) | Browser never switches to Tempo; server's settler submits permit + transferFrom |
|
|
199
|
+
| `bnb` / `bnb_testnet` | MoltsPay `PaymentIntent` | One-time approve | Call `client.approveBnb({ chain, spender, token })` once, then intent signatures are gasless |
|
|
200
|
+
| `solana` / `solana_devnet` | SPL transfer | No if provider sets a fee payer | `wallet.signTransaction` signs, provider submits |
|
|
201
|
+
|
|
202
|
+
**BNB approval flow.** The first payment on BNB throws `NeedsApprovalError` with the details needed to approve — catch it, call `approveBnb()`, and retry:
|
|
203
|
+
|
|
204
|
+
```ts
|
|
205
|
+
try {
|
|
206
|
+
await client.pay(url, service, params, { chain: 'bnb' });
|
|
207
|
+
} catch (err) {
|
|
208
|
+
if (err instanceof NeedsApprovalError) {
|
|
209
|
+
await client.approveBnb({
|
|
210
|
+
chain: 'bnb',
|
|
211
|
+
spender: err.details.spender,
|
|
212
|
+
token: err.details.token,
|
|
213
|
+
});
|
|
214
|
+
// User paid ~0.001 BNB gas for the approve. Retry now succeeds without further approve.
|
|
215
|
+
await client.pay(url, service, params, { chain: 'bnb' });
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
**Tempo note.** Tempo Moderato pathUSD is a native precompile that implements EIP-2612 permit but **not** EIP-3009. The web client dispatches to the permit path automatically when the server advertises `scheme: "permit"`. The user signs typed data; the provider's settler submits the `permit()` + `transferFrom()` transactions on-chain. MetaMask never prompts for a chain switch because the browser wallet doesn't touch Tempo at all.
|
|
221
|
+
|
|
222
|
+
**Solana mainnet RPC.** The public `api.mainnet-beta.solana.com` endpoint returns 403 to browser requests, so any Solana-mainnet traffic needs an authenticated RPC. Supply one via `solanaRpc`:
|
|
223
|
+
|
|
224
|
+
```ts
|
|
225
|
+
const client = new MoltsPayWebClient({
|
|
226
|
+
signer: composeSigners(
|
|
227
|
+
eip1193Signer(window.ethereum),
|
|
228
|
+
solanaSigner(phantomAdapter),
|
|
229
|
+
),
|
|
230
|
+
solanaRpc: {
|
|
231
|
+
solana: 'https://mainnet.helius-rpc.com/?api-key=YOUR_KEY',
|
|
232
|
+
// solana_devnet falls back to `api.devnet.solana.com` automatically
|
|
233
|
+
},
|
|
234
|
+
});
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
Accepts any Helius / QuickNode / Alchemy / Triton / self-hosted URL. Per-chain — override only `solana` if you only use mainnet. Devnet (`api.devnet.solana.com`) still serves browsers and does not need an override.
|
|
238
|
+
|
|
239
|
+
**Error classes** — every error exposes a `code` field so you can branch without string-matching:
|
|
240
|
+
|
|
241
|
+
```ts
|
|
242
|
+
import {
|
|
243
|
+
NeedsApprovalError, // code: 'NEEDS_APPROVAL' — BNB, call approveBnb()
|
|
244
|
+
UnsupportedChainError, // code: 'UNSUPPORTED_CHAIN' — user picked a chain the server doesn't accept
|
|
245
|
+
PaymentRejectedError, // code: 'PAYMENT_REJECTED' — user cancelled in the wallet
|
|
246
|
+
InsufficientBalanceError, // code: 'INSUFFICIENT_BALANCE' — not enough native gas for BNB approve
|
|
247
|
+
SpendingLimitExceededError,// code: 'SPENDING_LIMIT_EXCEEDED' — only when you opt in to SpendingLedger
|
|
248
|
+
ServerError, // code: 'SERVER_ERROR' — provider returned non-2xx
|
|
249
|
+
MoltsPayError, // base class
|
|
250
|
+
} from 'moltspay/web';
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
**Spending limits (opt-in).** Off by default. External wallets already prompt per-signature; per-browser localStorage limits don't sync across devices. If you want a session-level cap anyway:
|
|
254
|
+
|
|
255
|
+
```ts
|
|
256
|
+
const client = new MoltsPayWebClient({
|
|
257
|
+
signer: eip1193Signer(window.ethereum),
|
|
258
|
+
spendingLimits: { maxPerTx: 5, maxPerDay: 50 },
|
|
259
|
+
});
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
**Provider CORS.** Providers must enable CORS on `MoltsPayServer` for browser callers — without it the 402 challenge header is invisible to the browser:
|
|
263
|
+
|
|
264
|
+
```ts
|
|
265
|
+
new MoltsPayServer({
|
|
266
|
+
// ...
|
|
267
|
+
cors: true, // allow all origins, or
|
|
268
|
+
cors: ['https://myapp.example.com'], // explicit allowlist, or
|
|
269
|
+
cors: { origins: [...], maxAge: 86400 }, // fine-grained
|
|
270
|
+
});
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
Servers advertising for the web need `cors` enabled; CLI callers are unaffected either way.
|
|
274
|
+
|
|
275
|
+
**Security posture.** No private key ever enters browser memory. No filesystem access, no `~/.moltspay/` — the wallet is always external. The `signer` object the client receives only has permission to sign typed data and (for BNB) submit one `approve` transaction, which the user explicitly confirms in the wallet UI.
|
|
276
|
+
|
|
277
|
+
**Reference demo.** `examples/web/` is a runnable React + Vite app that exercises every path above. `cd examples/web && npm install && npm run dev` — it connects to `https://moltspay.com/a/zen7` by default. See [`examples/web/README.md`](examples/web/README.md) for the full matrix of tested wallets + chains.
|
|
278
|
+
|
|
279
|
+
## MCP Server (For AI Assistants)
|
|
280
|
+
|
|
281
|
+
MoltsPay ships an [MCP (Model Context Protocol)](https://modelcontextprotocol.io) stdio server that lets MCP-compatible hosts (Cursor, Windsurf, Claude Code, Zed, etc.) browse services, check wallet status, and pay for x402 services on your behalf.
|
|
282
|
+
|
|
283
|
+
It is a thin wrapper around `MoltsPayClient` — wallet custody, spending limits, and all payment protocols (x402, MPP, Solana, BNB) are reused from the SDK.
|
|
284
|
+
|
|
285
|
+
### Setup
|
|
286
|
+
|
|
287
|
+
**1. Create a wallet and set spending limits** (the MCP server refuses to start without a wallet):
|
|
288
|
+
|
|
289
|
+
```bash
|
|
290
|
+
npx moltspay init
|
|
291
|
+
npx moltspay config --max-per-tx 2 --max-per-day 10
|
|
292
|
+
npx moltspay fund 5 # or: npx moltspay faucet for testnet
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
**2. Point your MCP host at the `moltspay-mcp` binary over stdio:**
|
|
296
|
+
|
|
297
|
+
```bash
|
|
298
|
+
npx -y moltspay-mcp # normal mode
|
|
299
|
+
npx -y moltspay-mcp --dry-run # preview payments without signing
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
Each host has its own config file for registering stdio MCP servers — check your host's docs for the exact location. For a safer first run, use `--dry-run` so `moltspay_pay` returns a preview instead of spending real funds.
|
|
303
|
+
|
|
304
|
+
### Tools
|
|
305
|
+
|
|
306
|
+
| Tool | What it does | Destructive? |
|
|
307
|
+
|---|---|---|
|
|
308
|
+
| `moltspay_status` | Wallet address, balances across all supported chains, spending limits | No |
|
|
309
|
+
| `moltspay_services` | Fetch services manifest from a provider URL; optional `query`/`maxPrice` filter | No |
|
|
310
|
+
| `moltspay_pay` | Execute an x402/MPP/SOL/BNB payment and return the service result | **Yes** |
|
|
311
|
+
| `moltspay_config` | Read or update `maxPerTx` / `maxPerDay` limits | Updates config file |
|
|
312
|
+
|
|
313
|
+
### Safety Layers
|
|
314
|
+
|
|
315
|
+
`moltspay_pay` is the only tool that moves money. Three guards stack on top of the MCP host's own tool-approval prompt:
|
|
316
|
+
|
|
317
|
+
1. **SDK spending limits** — `maxPerTx` / `maxPerDay` enforced before signing.
|
|
318
|
+
2. **Dry-run mode** — launch with `--dry-run` and payments return a preview instead of signing.
|
|
319
|
+
3. **Confirmation gate** — set `MOLTSPAY_MCP_REQUIRE_CONFIRM=1` to require a second tool call (`confirmed: true`) for any payment exceeding `maxPerTx / 10`.
|
|
320
|
+
|
|
321
|
+
Private keys and mnemonics are never exposed over MCP — wallet creation stays on the CLI (`npx moltspay init`) by design. See [`docs/MCP-USAGE.md`](docs/MCP-USAGE.md) for full tool arguments and troubleshooting.
|
|
322
|
+
|
|
136
323
|
## Payment Protocols
|
|
137
324
|
|
|
138
325
|
MoltsPay supports multiple payment protocols, each optimized for different chains:
|