Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions typescript/packages/http/mnemopay/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# @x402/mnemopay Changelog

## 2.8.0

### Minor Changes

- Initial release: MnemoPay middleware for x402 payment protocol
- `withMnemoPay()` wrapper adds economic memory to any x402-enabled fetch
- `recallEndpointInsight()` queries agent memory for endpoint cost/reliability data
- `rememberPaymentOutcome()` stores payment results for future reference
- Automatic settle/refund flow based on payment success/failure
159 changes: 159 additions & 0 deletions typescript/packages/http/mnemopay/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
# @x402/mnemopay

MnemoPay middleware for x402 — turns "pay and forget" into "pay and learn."

Standard x402 handles payments mechanically: see a 402, pay, get the resource. The agent never learns. It pays the same price to unreliable endpoints, never discovers cheaper alternatives, and has no memory of what worked.

This package layers **economic memory** on top of x402. After each payment, the AI agent remembers the cost, the endpoint, and whether it succeeded. Before each request, it recalls past experiences — surfacing cheaper alternatives, flagging unreliable endpoints, and building a reputation score that reflects real payment outcomes.

## Installation

```bash
pnpm install @x402/mnemopay @mnemopay/sdk
```

## Quick Start

```typescript
import { wrapFetchWithPayment, x402Client } from "@x402/fetch";
import { ExactEvmScheme } from "@x402/evm";
import { MnemoPayLite } from "@mnemopay/sdk";
import { withMnemoPay } from "@x402/mnemopay";
import { privateKeyToAccount } from "viem/accounts";

// 1. Set up x402 payment as usual
const account = privateKeyToAccount("0xYourPrivateKey");
const client = new x402Client().register("eip155:8453", new ExactEvmScheme(account));
const payFetch = wrapFetchWithPayment(fetch, client);

// 2. Add MnemoPay memory layer
const agent = new MnemoPayLite("my-agent", 0.05);
const smartFetch = withMnemoPay(payFetch, { agent });

// 3. Use it — the agent now remembers every payment
const response = await smartFetch("https://api.example.com/paid-endpoint");
// Agent stored: "x402 payment to https://api.example.com/paid-endpoint: success, cost: $0.02"

// Next time, it recalls that memory before paying
const response2 = await smartFetch("https://api.example.com/paid-endpoint");
// Agent recalled: 1 memory, success rate: 100%, avg cost: $0.02
```

## How It Works

The middleware wraps any fetch function (ideally one already wrapped with `@x402/fetch`) and adds four memory operations around each request:

| Phase | What happens | MnemoPay API |
|-------|-------------|--------------|
| **Before request** | Recall past payment experiences with this endpoint | `agent.recall()` |
| **After 402 payment** | Record the charge amount and endpoint | `agent.charge()` |
| **On success** | Settle the transaction, reinforcing the positive memory | `agent.settle()` |
| **On failure** | Refund the transaction, docking reputation | `agent.refund()` |

Over time, the agent builds a knowledge base of:
- Which endpoints are cheap vs. expensive
- Which endpoints are reliable vs. flaky
- How costs change over time
- Which alternatives exist for the same resource

## API

### `withMnemoPay(fetchFn, config)`

The primary wrapper. Layers memory on top of an existing fetch function.

```typescript
const smartFetch = withMnemoPay(payFetch, {
agent: mnemoPayAgent, // Required: MnemoPay agent instance
recallLimit: 5, // Optional: max memories to recall per request (default: 5)
reliabilityThreshold: 0.3, // Optional: warn below this success rate (default: 0.3)
debug: false, // Optional: log memory events to console (default: false)
});
```

### `withMnemoPayAgent(fetchFn, agent)`

Convenience wrapper with default configuration.

```typescript
const smartFetch = withMnemoPayAgent(payFetch, agent);
```

### `recallEndpointInsight(agent, endpoint, limit?)`

Manually query the agent's memory about a specific endpoint.

```typescript
import { recallEndpointInsight } from "@x402/mnemopay";

const insight = await recallEndpointInsight(agent, "https://api.example.com/paid");
if (insight) {
console.log(`Success rate: ${insight.successRate}`);
console.log(`Average cost: $${insight.averageCost}`);
console.log(`Interactions: ${insight.interactionCount}`);
}
```

### `rememberPaymentOutcome(agent, result, debug?)`

Manually record a payment outcome (useful for custom payment flows).

```typescript
import { rememberPaymentOutcome } from "@x402/mnemopay";

await rememberPaymentOutcome(agent, {
success: true,
transactionId: "tx-123",
endpoint: "https://api.example.com/paid",
cost: 0.05,
});
```

## Custom MnemoPay Agent

You don't need the full `@mnemopay/sdk`. Any object implementing the `MnemoPayAgent` interface works:

```typescript
import type { MnemoPayAgent } from "@x402/mnemopay";

const myAgent: MnemoPayAgent = {
async remember(content, options) { /* store in your DB */ },
async recall(query, limit) { /* search your DB */ return []; },
async charge(amount, description) { /* record payment */ return "tx-id"; },
async settle(txId) { /* mark as settled */ },
async refund(txId) { /* mark as refunded */ },
balance() { return { wallet: 100, reputation: 0.9 }; },
};

const smartFetch = withMnemoPay(payFetch, { agent: myAgent });
```

## Debug Mode

Enable debug logging to see the agent's memory operations:

```typescript
const smartFetch = withMnemoPay(payFetch, {
agent,
debug: true,
});

// Console output:
// [mnemopay] recalled 3 memories for https://api.example.com/paid, success rate: 67%, avg cost: $0.04
// [mnemopay] WARNING: https://api.example.com/flaky has low reliability (20%). Consider alternatives.
// [mnemopay] settled tx tx-123 for https://api.example.com/paid
```

## Why This Matters for AI Agents

AI agents making API calls through x402 today are stateless — they pay whatever is asked, every time, with no memory of past outcomes. This is like a human who forgets the price of groceries every time they walk into a store.

With MnemoPay integration, x402 agents develop **economic intelligence**:

- **Cost awareness**: "This endpoint usually costs $0.02, but today it's asking for $0.10 — something changed"
- **Reliability tracking**: "This endpoint fails 40% of the time — I should prefer the alternative"
- **Reputation building**: Agents that consistently make good payment decisions build higher reputation scores, which other agents and services can use as a trust signal

## License

Apache-2.0
77 changes: 77 additions & 0 deletions typescript/packages/http/mnemopay/eslint.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import js from "@eslint/js";
import ts from "@typescript-eslint/eslint-plugin";
import tsParser from "@typescript-eslint/parser";
import prettier from "eslint-plugin-prettier";
import jsdoc from "eslint-plugin-jsdoc";
import importPlugin from "eslint-plugin-import";

export default [
{
ignores: ["dist/**", "node_modules/**"],
},
{
files: ["**/*.ts"],
languageOptions: {
parser: tsParser,
sourceType: "module",
ecmaVersion: 2020,
globals: {
process: "readonly",
__dirname: "readonly",
module: "readonly",
require: "readonly",
Buffer: "readonly",
RequestInfo: "readonly",
RequestInit: "readonly",
Response: "readonly",
Headers: "readonly",
exports: "readonly",
setTimeout: "readonly",
clearTimeout: "readonly",
setInterval: "readonly",
clearInterval: "readonly",
console: "readonly",
},
},
plugins: {
"@typescript-eslint": ts,
prettier: prettier,
jsdoc: jsdoc,
import: importPlugin,
},
rules: {
...ts.configs.recommended.rules,
"import/first": "error",
"prettier/prettier": "error",
"@typescript-eslint/member-ordering": "error",
"@typescript-eslint/no-unused-vars": ["error", { argsIgnorePattern: "^_$" }],
"jsdoc/tag-lines": ["error", "any", { startLines: 1 }],
"jsdoc/check-alignment": "error",
"jsdoc/no-undefined-types": "off",
"jsdoc/check-param-names": "error",
"jsdoc/check-tag-names": "error",
"jsdoc/check-types": "error",
"jsdoc/implements-on-classes": "error",
"jsdoc/require-description": "error",
"jsdoc/require-jsdoc": [
"error",
{
require: {
FunctionDeclaration: true,
MethodDefinition: true,
ClassDeclaration: true,
ArrowFunctionExpression: false,
FunctionExpression: false,
},
},
],
"jsdoc/require-param": "error",
"jsdoc/require-param-description": "error",
"jsdoc/require-param-type": "off",
"jsdoc/require-returns": "error",
"jsdoc/require-returns-description": "error",
"jsdoc/require-returns-type": "off",
"jsdoc/require-hyphen-before-param-description": ["error", "always"],
},
},
];
74 changes: 74 additions & 0 deletions typescript/packages/http/mnemopay/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
{
"name": "@x402/mnemopay",
"version": "2.8.0",
"main": "./dist/cjs/index.js",
"module": "./dist/esm/index.js",
"types": "./dist/index.d.ts",
"scripts": {
"start": "tsx --env-file=.env index.ts",
"test": "vitest run",
"test:watch": "vitest",
"build": "tsup",
"watch": "tsc --watch",
"format": "prettier -c .prettierrc --write \"**/*.{ts,js,cjs,json,md}\"",
"format:check": "prettier -c .prettierrc --check \"**/*.{ts,js,cjs,json,md}\"",
"lint": "eslint . --ext .ts --fix",
"lint:check": "eslint . --ext .ts"
},
"keywords": [
"x402",
"payment",
"protocol",
"mnemopay",
"ai",
"agent",
"memory"
],
"license": "Apache-2.0",
"author": "Coinbase Inc.",
"repository": "https://github.com/coinbase/x402",
"description": "x402 MnemoPay middleware — AI agents that remember payment outcomes and learn from them",
"devDependencies": {
"@eslint/js": "^9.24.0",
"@types/node": "^22.13.4",
"@typescript-eslint/eslint-plugin": "^8.29.1",
"@typescript-eslint/parser": "^8.29.1",
"eslint": "^9.24.0",
"eslint-plugin-import": "^2.31.0",
"eslint-plugin-jsdoc": "^50.6.9",
"eslint-plugin-prettier": "^5.2.6",
"prettier": "3.5.2",
"tsup": "^8.4.0",
"tsx": "^4.19.2",
"typescript": "^5.7.3",
"vite": "^6.2.6",
"vite-tsconfig-paths": "^5.1.4",
"vitest": "^3.0.5"
},
"dependencies": {
"@x402/core": "workspace:~"
},
"peerDependencies": {
"@mnemopay/sdk": ">=0.1.0"
},
"peerDependenciesMeta": {
"@mnemopay/sdk": {
"optional": false
}
},
"exports": {
".": {
"import": {
"types": "./dist/esm/index.d.mts",
"default": "./dist/esm/index.mjs"
},
"require": {
"types": "./dist/cjs/index.d.ts",
"default": "./dist/cjs/index.js"
}
}
},
"files": [
"dist"
]
}
24 changes: 24 additions & 0 deletions typescript/packages/http/mnemopay/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
export { withMnemoPay, withMnemoPayAgent, recallEndpointInsight, rememberPaymentOutcome } from "./middleware";
export type {
MnemoPayAgent,
MnemoPayMiddlewareConfig,
MnemoPayMemory,
MnemoPayPaymentResult,
EndpointInsight,
} from "./types";

// Re-export x402 core types for convenience
export { x402Client, x402HTTPClient } from "@x402/core/client";
export type {
PaymentPolicy,
SchemeRegistration,
SelectPaymentRequirements,
x402ClientConfig,
} from "@x402/core/client";
export type {
Network,
PaymentPayload,
PaymentRequired,
PaymentRequirements,
SchemeNetworkClient,
} from "@x402/core/types";
Loading
Loading