Skip to content
Draft
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
42 changes: 42 additions & 0 deletions examples/with-mpp/aixyz-both.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import type { AixyzConfig } from "aixyz/config";

/**
* Example: Both x402 and MPP configured simultaneously
*
* When both are present, aixyz serves both payment protocols at once.
* Clients that send `Authorization: Payment ...` → MPP path
* Clients that send `X-Payment: ...` → x402 path
* Clients with no credential → 402 with both challenges
*
* Useful when you want to maximise payment method compatibility.
*/
const config: AixyzConfig = {
name: "Unit Conversion Agent",
description: "AI agent that converts values between metric, imperial, and other measurement systems.",
version: "0.1.0",

// x402: EVM/Base payments (existing clients)
x402: {
payTo: process.env.X402_PAY_TO ?? "0x0799872E07EA7a63c79357694504FE66EDfE4a0A",
network: process.env.NODE_ENV === "production" ? "eip155:8453" : "eip155:84532",
},

// mpp: Tempo / Stripe / Lightning (new clients)
mpp: {
recipient: process.env.MPP_RECIPIENT ?? "0x0799872E07EA7a63c79357694504FE66EDfE4a0A",
methods: ["tempo", "stripe"],
stripeSecretKey: process.env.MPP_STRIPE_SECRET_KEY,
},

skills: [
{
id: "convert-length",
name: "Convert Length",
description: "Convert length and distance values between metric and imperial units",
tags: ["length", "distance", "metric", "imperial"],
examples: ["Convert 100 meters to feet"],
},
],
};

export default config;
40 changes: 40 additions & 0 deletions examples/with-mpp/aixyz.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import type { AixyzConfig } from "aixyz/config";

/**
* Example: MPP-only payment configuration
*
* This agent accepts payments via the Machine Payments Protocol (MPP),
* supporting Tempo stablecoins, Stripe cards, and Lightning Bitcoin.
*
* Install mppx to enable: bun add mppx
*
* @see https://mpp.dev
*/
const config: AixyzConfig = {
name: "Unit Conversion Agent",
description: "AI agent that converts values between metric, imperial, and other measurement systems.",
version: "0.1.0",

mpp: {
// EVM address to receive Tempo stablecoin payments
recipient: process.env.MPP_RECIPIENT ?? "0x0799872E07EA7a63c79357694504FE66EDfE4a0A",
// pathUSD on Tempo mainnet (default)
currency: "0x20c0000000000000000000000000000000000000",
// Accept Tempo stablecoins and Stripe cards
methods: ["tempo", "stripe"],
// Stripe secret key (required when "stripe" is in methods)
stripeSecretKey: process.env.MPP_STRIPE_SECRET_KEY,
},

skills: [
{
id: "convert-length",
name: "Convert Length",
description: "Convert length and distance values between metric and imperial units",
tags: ["length", "distance", "metric", "imperial"],
examples: ["Convert 100 meters to feet", "How many miles is 10 kilometers?"],
},
],
};

export default config;
23 changes: 19 additions & 4 deletions packages/aixyz-cli/build/AixyzConfigPlugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@ import boxen from "boxen";
import chalk from "chalk";

function label(text: string): string {
return chalk.dim(text.padEnd(14));
return chalk.dim(text.padEnd(16));
}

function logConfig(materialized: ReturnType<typeof getAixyzConfig>): void {
const maxLen = Math.max(materialized.url.length, materialized.x402.payTo.length);
const refLen = materialized.url?.length ?? 0;
const payLen = materialized.x402?.payTo?.length ?? materialized.mpp?.recipient?.length ?? 0;
const maxLen = Math.max(refLen, payLen);
const description =
materialized.description.length > maxLen
? materialized.description.slice(0, maxLen - 1) + "…"
Expand All @@ -19,9 +21,22 @@ function logConfig(materialized: ReturnType<typeof getAixyzConfig>): void {
`${label("Description")}${description}`,
`${label("URL")}${materialized.url}`,
`${label("Version")}${materialized.version}`,
`${label("x402 PayTo")}${materialized.x402.payTo}`,
`${label("x402 Network")}${materialized.x402.network}`,
];

if (materialized.x402) {
lines.push(
`${label("x402 PayTo")}${materialized.x402.payTo}`,
`${label("x402 Network")}${materialized.x402.network}`,
);
}

if (materialized.mpp) {
lines.push(
`${label("MPP Recipient")}${materialized.mpp.recipient}`,
`${label("MPP Methods")}${(materialized.mpp.methods ?? ["tempo"]).join(", ")}`,
);
}

console.log(
boxen(lines.join("\n"), {
padding: { left: 1, right: 1, top: 0, bottom: 0 },
Expand Down
84 changes: 78 additions & 6 deletions packages/aixyz-config/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import { z } from "zod";

export type Network = `${string}:${string}`;

export type MppMethod = "tempo" | "stripe" | "lightning";

export type AixyzConfig = {
/**
* The name of the agent will be used in the agent card.
Expand All @@ -23,7 +25,12 @@ export type AixyzConfig = {
* Defaults to `process.env.VERCEL_URL` for Vercel deployments.
*/
url?: string;
x402: {
/**
* x402 payment configuration.
* When present, the agent will accept x402 payments (HTTP 402 with X-Payment headers).
* Can be configured alongside `mpp` to accept both protocols simultaneously.
*/
x402?: {
/**
* The address that will receive the payment from the agent.
* Defaults to `process.env.X402_PAY_TO` if not set.
Expand All @@ -35,6 +42,50 @@ export type AixyzConfig = {
*/
network: string;
};
/**
* MPP (Machine Payments Protocol) configuration.
* When present, the agent will accept MPP payments (HTTP 402 with WWW-Authenticate: Payment headers).
* Supports Tempo stablecoins, Stripe cards, and Lightning Bitcoin.
* Can be configured alongside `x402` to accept both protocols simultaneously.
*
* @see https://mpp.dev
*/
mpp?: {
/**
* The EVM address that will receive payments.
* Used as the `recipient` in Tempo payment methods.
* Defaults to `process.env.MPP_RECIPIENT` if not set.
*/
recipient: string;
/**
* The Tempo currency contract address.
* Defaults to pathUSD on Tempo mainnet: `process.env.MPP_CURRENCY`
* @default "0x20c0000000000000000000000000000000000000"
*/
currency?: string;
/**
* Payment methods to accept.
* @default ["tempo"]
*/
methods?: MppMethod[];
/**
* Stripe secret key for Stripe payment method support.
* Required when "stripe" is included in methods.
* Defaults to `process.env.MPP_STRIPE_SECRET_KEY`.
*/
stripeSecretKey?: string;
/**
* Fee payer account private key for sponsoring gas on Tempo pull-mode transactions.
* Defaults to `process.env.MPP_FEE_PAYER_KEY`.
*/
feePayerKey?: string;
/**
* Use optimistic verification (do not wait for on-chain confirmation).
* Reduces latency at the cost of slightly higher risk.
* @default false
*/
optimistic?: boolean;
};
build?: {
/**
* Output format for `aixyz build`.
Expand Down Expand Up @@ -116,10 +167,25 @@ const AixyzConfigSchema = z.object({
return `http://localhost:${port}/`;
})
.pipe(z.url()),
x402: z.object({
payTo: z.string(),
network: NetworkSchema,
}),
x402: z
.object({
payTo: z.string(),
network: NetworkSchema,
})
.optional(),
mpp: z
.object({
recipient: z.string(),
currency: z.string().optional().default("0x20c0000000000000000000000000000000000000"),
methods: z
.array(z.enum(["tempo", "stripe", "lightning"]))
.optional()
.default(["tempo"]),
stripeSecretKey: z.string().optional(),
feePayerKey: z.string().optional(),
optimistic: z.boolean().optional().default(false),
})
.optional(),
build: z
.object({
output: z.enum(["standalone", "vercel", "executable"]).optional(),
Expand Down Expand Up @@ -158,7 +224,13 @@ const AixyzConfigSchema = z.object({
}),
)
.default(defaultConfig.skills),
});
}).refine(
(data) => data.x402 !== undefined || data.mpp !== undefined,
{
message: "At least one of `x402` or `mpp` must be configured",
path: ["x402"],
},
);

type InferredAixyzConfig = z.infer<typeof AixyzConfigSchema>;

Expand Down
Loading
Loading