feat: add CEP-8 explicit payment gating to cvmi call#5
Conversation
|
Solid design — the wrapper + 🔴 1. Pins
|
0.13.4 makes withClientPayments `handlers` optional, enabling a PMI-agnostic client that advertises no PMIs and lets the server send payment_required for whatever rail it supports. Verified end-to-end against the live paid server.
Drop the bolt11-locked CliPaymentHandler and advertise no PMIs, so the
server sends notifications/payment_required for whatever rail it supports
(CEP-8 no-client-PMI path). Render the invoice via an upstream
client.setNotificationHandler instead of a PaymentHandler.handle() that
only fired on an exact-PMI match.
This fixes a silent timeout against any non-bolt11 server: previously the
exact-PMI lookup missed, the notification was forwarded but never
rendered, and the request hung until -32001.
Side benefit: the two client-payments info logs that bracketed the invoice
("processing payment_required" / "payment handler completed successfully")
only fired on the handler-execution path we no longer take, so they no
longer appear. The no-op process.env.LOG_ENABLED assignment (import-time
singleton — never worked) is removed.
- Remove PMI_BITCOIN_LIGHTNING_BOLT11 + CliPaymentHandler class
- withClientPayments(transport, {}) + setNotificationHandler renderer
- cli.ts: narrow via instanceof ExplicitGatingError
- cli-payment-handler.test.ts: test renderPaymentRequired directly
2b7541f to
034448a
Compare
|
Pushed two commits on top of
|
|
Thanks for jumping in with those commits! The PMI-agnostic approach using setNotificationHandler is significantly cleaner than locking into Bolt11, and relying on the CEP-8 no-client-PMI fallback makes total sense to avoid those silent timeouts on other rails like Cashu. Also, good catch on the LOG_ENABLED import-time singleton issue, it's great that bypassing the handler path organically killed the log pollution anyway. I've pulled the commits locally, audited the changes, and everything (including the tests) is perfectly green on my end. This looks ready to merge whenever you are! |
Update @contextvm/sdk to version 0.13.6 and nostr-tools to version 2.23.9, with corresponding lockfile updates.
Display per-tool prices and payment method indicators when server provides pricing data. This helps users evaluate costs before invoking tools.
|
hi, @ContextVM-org! Pulled and reviewed the four commits. Pricing module is clean and the Negative price range parsing in
Repeated The same block appears three times: const pricing = parseCapabilityPricing(
remote.transport.getServerToolsListEvent() ?? remote.transport.getServerInitializeEvent()
);Could be a small helper like getPricing(remote) to keep things DRY.
The template literal now chains name + signature + description + price in one expression and it is getting hard to scan. Breaking it into parts would help: const parts = [` ${CYAN}•${RESET} ${tool.name}`];
if (signature) parts.push(` ${DIM}${signature}${RESET}`);
if (tool.description) parts.push(` ${DIM}— ${tool.description}${RESET}`);
if (price) parts.push(` ${YELLOW}(${formatPrice(price)})${RESET}`);
console.log(parts.join(''));Everything else looks solid. Tests pass locally (189/189). |
- Upgrade @contextvm/sdk dependency to ^0.13.7 - Add `ServePaymentsConfig` type for CEP-8 server-side payment configuration - Extend `ServeConfig` with optional `payments` field - Include payments config in `getServeConfig` loader - Document `--payment-mode` flag in call command help text - Add `.mcp.json` to `.gitignore` for local MCP client configs
Add CEP-8 Payment Lifecycle Support to
cvmi callDescription
This PR brings full CEP-8 payment handling to the
cvmi callcommand, bringing it up to parity with thecontextvm-siteclient. Previously, calling a paid MCP endpoint via the CLI would fail or hang because the CLI had no awareness ofnotifications/payment_required.This update upgrades
@contextvm/sdkto0.13.0and utilizes its nativewithClientPaymentsmiddleware to handle all the heavy lifting (PMI capability advertisement, NIP-47 heartbeats, and waiting for server settlement).Changes
@contextvm/sdkto0.13.0NostrClientTransportincreateRemoteClientwithwithClientPaymentsmiddleware.CliPaymentHandler(mirroringUiOnlyPaymentHandlerincontextvm-site). Instead of auto-paying, this handler simply prints the parsed lightning invoice to the terminal using standard UI tokens (BOLD,CYAN,DIM), and waits for human payment out-of-band while the SDK background loop awaitspayment_accepted.--payment-modeflag.transparent(Default): Pauses execution, prints the invoice to the terminal, and waits for settlement.explicit_gating: Designed for AI agents. If the server throws a-32042 Payment Requirederror, the CLI immediately outputs the raw payment schema as structured JSON tostdoutand throws an exit code 2.Usage Example
Human Usage (Transparent):
Agentic Usage (Explicit Gating):