@usemilkyway/agent-sdk 0.1.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.
@@ -0,0 +1,12 @@
1
+ import { Express } from "express";
2
+ import { AgentConfig, Handlers } from "./types";
3
+ interface CreateAgentOptions {
4
+ devMode?: boolean;
5
+ }
6
+ interface AgentInstance {
7
+ app: Express;
8
+ listen: (port: number, callback?: () => void) => void;
9
+ }
10
+ export declare function createAgent(config: AgentConfig, handlers: Handlers, options?: CreateAgentOptions): AgentInstance;
11
+ export {};
12
+ //# sourceMappingURL=agent.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"AAAA,OAAgB,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAG3C,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAiB,MAAM,SAAS,CAAC;AAE/D,UAAU,kBAAkB;IAC1B,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,UAAU,aAAa;IACrB,GAAG,EAAK,OAAO,CAAC;IAChB,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,IAAI,KAAK,IAAI,CAAC;CACvD;AAED,wBAAgB,WAAW,CACzB,MAAM,EAAI,WAAW,EACrB,QAAQ,EAAE,QAAQ,EAClB,OAAO,GAAG,kBAAuB,GAChC,aAAa,CA4Df"}
package/dist/agent.js ADDED
@@ -0,0 +1,58 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.createAgent = createAgent;
7
+ const express_1 = __importDefault(require("express"));
8
+ const x402_1 = require("./x402");
9
+ const router_1 = require("./router");
10
+ function createAgent(config, handlers, options = {}) {
11
+ const app = (0, express_1.default)();
12
+ app.use(express_1.default.json());
13
+ const devMode = options.devMode ?? process.env.MILKYWAY_DEV_MODE === "true";
14
+ app.get("/health", (_, res) => {
15
+ res.json({
16
+ name: config.name,
17
+ version: "1.0.0",
18
+ status: "ok",
19
+ ...(devMode && { devMode: true })
20
+ });
21
+ });
22
+ app.get("/about", (_, res) => {
23
+ const about = {
24
+ milkyway_version: "1.0",
25
+ name: config.name,
26
+ description: config.description,
27
+ wallet: config.wallet,
28
+ max_deadline_seconds: config.max_deadline_seconds || 30,
29
+ capabilities: config.capabilities
30
+ };
31
+ res.json(about);
32
+ });
33
+ app.post("/execute", async (req, res) => {
34
+ const capabilityName = req.body?.task?.capability ||
35
+ Object.keys(config.capabilities)[0];
36
+ const capability = config.capabilities[capabilityName];
37
+ if (!capability) {
38
+ return (0, router_1.buildExecuteHandler)(config, handlers)(req, res);
39
+ }
40
+ (0, x402_1.requirePayment)(config.wallet, capability.pricing, devMode)(req, res, () => (0, router_1.buildExecuteHandler)(config, handlers)(req, res));
41
+ });
42
+ return {
43
+ app,
44
+ listen: (port, callback) => {
45
+ app.listen(port, callback || (() => {
46
+ console.log(`\nāœ“ ${config.name} running on port ${port}`);
47
+ if (devMode) {
48
+ console.log("āœ“ Dev mode: payment verification bypassed");
49
+ }
50
+ console.log("\nEndpoints:");
51
+ console.log(` GET http://localhost:${port}/health`);
52
+ console.log(` GET http://localhost:${port}/about`);
53
+ console.log(` POST http://localhost:${port}/execute\n`);
54
+ }));
55
+ }
56
+ };
57
+ }
58
+ //# sourceMappingURL=agent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent.js","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ export declare class MilkyWayError extends Error {
2
+ readonly type: string;
3
+ readonly statusCode: number;
4
+ constructor(message: string, type: string, statusCode?: number);
5
+ }
6
+ export declare class ValidationError extends MilkyWayError {
7
+ constructor(message: string);
8
+ }
9
+ export declare class PaymentError extends MilkyWayError {
10
+ constructor(message: string);
11
+ }
12
+ export declare class DeadlineError extends MilkyWayError {
13
+ constructor();
14
+ }
15
+ export declare class CapabilityError extends MilkyWayError {
16
+ constructor(name: string, available: string[]);
17
+ }
18
+ export declare class InternalError extends MilkyWayError {
19
+ constructor(message: string);
20
+ }
21
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,qBAAa,aAAc,SAAQ,KAAK;aAGpB,IAAI,EAAE,MAAM;aACZ,UAAU,EAAE,MAAM;gBAFlC,OAAO,EAAE,MAAM,EACC,IAAI,EAAE,MAAM,EACZ,UAAU,GAAE,MAAY;CAK3C;AAED,qBAAa,eAAgB,SAAQ,aAAa;gBACpC,OAAO,EAAE,MAAM;CAI5B;AAED,qBAAa,YAAa,SAAQ,aAAa;gBACjC,OAAO,EAAE,MAAM;CAI5B;AAED,qBAAa,aAAc,SAAQ,aAAa;;CAK/C;AAED,qBAAa,eAAgB,SAAQ,aAAa;gBACpC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE;CAQ9C;AAED,qBAAa,aAAc,SAAQ,aAAa;gBAClC,OAAO,EAAE,MAAM;CAI5B"}
package/dist/errors.js ADDED
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.InternalError = exports.CapabilityError = exports.DeadlineError = exports.PaymentError = exports.ValidationError = exports.MilkyWayError = void 0;
4
+ class MilkyWayError extends Error {
5
+ constructor(message, type, statusCode = 400) {
6
+ super(message);
7
+ this.type = type;
8
+ this.statusCode = statusCode;
9
+ this.name = "MilkyWayError";
10
+ }
11
+ }
12
+ exports.MilkyWayError = MilkyWayError;
13
+ class ValidationError extends MilkyWayError {
14
+ constructor(message) {
15
+ super(message, "validation", 400);
16
+ this.name = "ValidationError";
17
+ }
18
+ }
19
+ exports.ValidationError = ValidationError;
20
+ class PaymentError extends MilkyWayError {
21
+ constructor(message) {
22
+ super(message, "payment", 402);
23
+ this.name = "PaymentError";
24
+ }
25
+ }
26
+ exports.PaymentError = PaymentError;
27
+ class DeadlineError extends MilkyWayError {
28
+ constructor() {
29
+ super("Deadline has passed", "deadline", 408);
30
+ this.name = "DeadlineError";
31
+ }
32
+ }
33
+ exports.DeadlineError = DeadlineError;
34
+ class CapabilityError extends MilkyWayError {
35
+ constructor(name, available) {
36
+ super(`Unknown capability: "${name}". Available: ${available.join(", ")}`, "capability", 400);
37
+ this.name = "CapabilityError";
38
+ }
39
+ }
40
+ exports.CapabilityError = CapabilityError;
41
+ class InternalError extends MilkyWayError {
42
+ constructor(message) {
43
+ super(message, "internal", 500);
44
+ this.name = "InternalError";
45
+ }
46
+ }
47
+ exports.InternalError = InternalError;
48
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":";;;AAAA,MAAa,aAAc,SAAQ,KAAK;IACtC,YACE,OAAe,EACC,IAAY,EACZ,aAAqB,GAAG;QAExC,KAAK,CAAC,OAAO,CAAC,CAAC;QAHC,SAAI,GAAJ,IAAI,CAAQ;QACZ,eAAU,GAAV,UAAU,CAAc;QAGxC,IAAI,CAAC,IAAI,GAAG,eAAe,CAAC;IAC9B,CAAC;CACF;AATD,sCASC;AAED,MAAa,eAAgB,SAAQ,aAAa;IAChD,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,EAAE,YAAY,EAAE,GAAG,CAAC,CAAC;QAClC,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;IAChC,CAAC;CACF;AALD,0CAKC;AAED,MAAa,YAAa,SAAQ,aAAa;IAC7C,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,EAAE,SAAS,EAAE,GAAG,CAAC,CAAC;QAC/B,IAAI,CAAC,IAAI,GAAG,cAAc,CAAC;IAC7B,CAAC;CACF;AALD,oCAKC;AAED,MAAa,aAAc,SAAQ,aAAa;IAC9C;QACE,KAAK,CAAC,qBAAqB,EAAE,UAAU,EAAE,GAAG,CAAC,CAAC;QAC9C,IAAI,CAAC,IAAI,GAAG,eAAe,CAAC;IAC9B,CAAC;CACF;AALD,sCAKC;AAED,MAAa,eAAgB,SAAQ,aAAa;IAChD,YAAY,IAAY,EAAE,SAAmB;QAC3C,KAAK,CACH,wBAAwB,IAAI,iBAAiB,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EACnE,YAAY,EACZ,GAAG,CACJ,CAAC;QACF,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;IAChC,CAAC;CACF;AATD,0CASC;AAED,MAAa,aAAc,SAAQ,aAAa;IAC9C,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,EAAE,UAAU,EAAE,GAAG,CAAC,CAAC;QAChC,IAAI,CAAC,IAAI,GAAG,eAAe,CAAC;IAC9B,CAAC;CACF;AALD,sCAKC"}
@@ -0,0 +1,7 @@
1
+ export { createAgent } from "./agent";
2
+ export { requirePayment } from "./x402";
3
+ export { verifyPayment } from "./verify";
4
+ export { validateInput } from "./validator";
5
+ export { MilkyWayError, ValidationError, PaymentError, DeadlineError, CapabilityError, InternalError } from "./errors";
6
+ export * from "./types";
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAS,SAAS,CAAC;AACzC,OAAO,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAC;AACxC,OAAO,EAAE,aAAa,EAAE,MAAO,UAAU,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAO,aAAa,CAAC;AAC7C,OAAO,EACL,aAAa,EACb,eAAe,EACf,YAAY,EACZ,aAAa,EACb,eAAe,EACf,aAAa,EACd,MAAM,UAAU,CAAC;AAClB,cAAc,SAAS,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.InternalError = exports.CapabilityError = exports.DeadlineError = exports.PaymentError = exports.ValidationError = exports.MilkyWayError = exports.validateInput = exports.verifyPayment = exports.requirePayment = exports.createAgent = void 0;
18
+ var agent_1 = require("./agent");
19
+ Object.defineProperty(exports, "createAgent", { enumerable: true, get: function () { return agent_1.createAgent; } });
20
+ var x402_1 = require("./x402");
21
+ Object.defineProperty(exports, "requirePayment", { enumerable: true, get: function () { return x402_1.requirePayment; } });
22
+ var verify_1 = require("./verify");
23
+ Object.defineProperty(exports, "verifyPayment", { enumerable: true, get: function () { return verify_1.verifyPayment; } });
24
+ var validator_1 = require("./validator");
25
+ Object.defineProperty(exports, "validateInput", { enumerable: true, get: function () { return validator_1.validateInput; } });
26
+ var errors_1 = require("./errors");
27
+ Object.defineProperty(exports, "MilkyWayError", { enumerable: true, get: function () { return errors_1.MilkyWayError; } });
28
+ Object.defineProperty(exports, "ValidationError", { enumerable: true, get: function () { return errors_1.ValidationError; } });
29
+ Object.defineProperty(exports, "PaymentError", { enumerable: true, get: function () { return errors_1.PaymentError; } });
30
+ Object.defineProperty(exports, "DeadlineError", { enumerable: true, get: function () { return errors_1.DeadlineError; } });
31
+ Object.defineProperty(exports, "CapabilityError", { enumerable: true, get: function () { return errors_1.CapabilityError; } });
32
+ Object.defineProperty(exports, "InternalError", { enumerable: true, get: function () { return errors_1.InternalError; } });
33
+ __exportStar(require("./types"), exports);
34
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,iCAAyC;AAAhC,oGAAA,WAAW,OAAA;AACpB,+BAAwC;AAA/B,sGAAA,cAAc,OAAA;AACvB,mCAA0C;AAAjC,uGAAA,aAAa,OAAA;AACtB,yCAA6C;AAApC,0GAAA,aAAa,OAAA;AACtB,mCAOkB;AANhB,uGAAA,aAAa,OAAA;AACb,yGAAA,eAAe,OAAA;AACf,sGAAA,YAAY,OAAA;AACZ,uGAAA,aAAa,OAAA;AACb,yGAAA,eAAe,OAAA;AACf,uGAAA,aAAa,OAAA;AAEf,0CAAwB"}
@@ -0,0 +1,4 @@
1
+ import { Request, Response } from "express";
2
+ import { AgentConfig, Handlers } from "./types";
3
+ export declare function buildExecuteHandler(config: AgentConfig, handlers: Handlers): (req: Request, res: Response) => Promise<Response<any, Record<string, any>> | undefined>;
4
+ //# sourceMappingURL=router.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../src/router.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAkB,MAAM,SAAS,CAAC;AAQhE,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,WAAW,EACnB,QAAQ,EAAE,QAAQ,IAEJ,KAAK,OAAO,EAAE,KAAK,QAAQ,6DAgG1C"}
package/dist/router.js ADDED
@@ -0,0 +1,87 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.buildExecuteHandler = buildExecuteHandler;
4
+ const validator_1 = require("./validator");
5
+ const errors_1 = require("./errors");
6
+ function buildExecuteHandler(config, handlers) {
7
+ return async (req, res) => {
8
+ const body = req.body;
9
+ if (body.milkyway_version !== "1.0") {
10
+ return res.status(400).json({
11
+ error: `Unsupported protocol version: ${body.milkyway_version}`
12
+ });
13
+ }
14
+ const now = Math.floor(Date.now() / 1000);
15
+ if (body.deadline && now > body.deadline) {
16
+ return res.status(408).json({
17
+ milkyway_version: "1.0",
18
+ job_id: body.job_id,
19
+ status: "expired",
20
+ error: "Deadline has passed",
21
+ error_type: "deadline"
22
+ });
23
+ }
24
+ try {
25
+ const capabilityNames = Object.keys(config.capabilities);
26
+ let capabilityName;
27
+ let handler;
28
+ if (typeof handlers === "function") {
29
+ if (capabilityNames.length > 1) {
30
+ throw new errors_1.CapabilityError("multiple capabilities require named handlers", capabilityNames);
31
+ }
32
+ capabilityName = capabilityNames[0];
33
+ handler = handlers;
34
+ }
35
+ else {
36
+ capabilityName = body.task?.capability || capabilityNames[0];
37
+ if (!handlers[capabilityName]) {
38
+ throw new errors_1.CapabilityError(capabilityName, Object.keys(handlers));
39
+ }
40
+ handler = handlers[capabilityName];
41
+ }
42
+ const capabilityDef = config.capabilities[capabilityName];
43
+ if (!capabilityDef) {
44
+ throw new errors_1.CapabilityError(capabilityName, capabilityNames);
45
+ }
46
+ const validatedInput = (0, validator_1.validateInput)(body.task?.input || {}, capabilityDef.input_schema);
47
+ const output = await handler(validatedInput);
48
+ res.json({
49
+ milkyway_version: "1.0",
50
+ job_id: body.job_id,
51
+ status: "completed",
52
+ output,
53
+ completed_at: Math.floor(Date.now() / 1000)
54
+ });
55
+ }
56
+ catch (err) {
57
+ if (err instanceof errors_1.DeadlineError) {
58
+ return res.status(408).json({
59
+ milkyway_version: "1.0",
60
+ job_id: body.job_id,
61
+ status: "expired",
62
+ error: err.message,
63
+ error_type: err.type
64
+ });
65
+ }
66
+ if (err instanceof errors_1.MilkyWayError) {
67
+ return res.status(err.statusCode).json({
68
+ milkyway_version: "1.0",
69
+ job_id: body.job_id,
70
+ status: "failed",
71
+ error: err.message,
72
+ error_type: err.type
73
+ });
74
+ }
75
+ console.error("Agent handler error:", err);
76
+ const message = err instanceof Error ? err.message : String(err);
77
+ res.status(500).json({
78
+ milkyway_version: "1.0",
79
+ job_id: body.job_id,
80
+ status: "failed",
81
+ error: message,
82
+ error_type: "internal"
83
+ });
84
+ }
85
+ };
86
+ }
87
+ //# sourceMappingURL=router.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"router.js","sourceRoot":"","sources":["../src/router.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,60 @@
1
+ export type FieldType = "string" | "number" | "boolean" | "array" | "object";
2
+ export interface FieldDef {
3
+ type: FieldType;
4
+ required?: boolean;
5
+ description?: string;
6
+ default?: unknown;
7
+ min?: number;
8
+ max?: number;
9
+ minLength?: number;
10
+ maxLength?: number;
11
+ enum?: unknown[];
12
+ }
13
+ export interface AgentSchema {
14
+ [field: string]: FieldDef;
15
+ }
16
+ export interface AgentPricing {
17
+ model: "per_job" | "per_day" | "per_month" | "free";
18
+ amount: string;
19
+ currency: "USDC";
20
+ }
21
+ export interface CapabilityDef {
22
+ description: string;
23
+ pricing: AgentPricing;
24
+ input_schema: AgentSchema;
25
+ output_schema: AgentSchema;
26
+ }
27
+ export interface AgentConfig {
28
+ milkyway_version: string;
29
+ name: string;
30
+ description: string;
31
+ wallet: string;
32
+ max_deadline_seconds?: number;
33
+ capabilities: {
34
+ [capabilityName: string]: CapabilityDef;
35
+ };
36
+ }
37
+ export type MilkyWayAbout = AgentConfig;
38
+ export interface ExecuteRequest {
39
+ milkyway_version: string;
40
+ job_id: string;
41
+ task: {
42
+ capability?: string;
43
+ input: Record<string, unknown>;
44
+ };
45
+ deadline: number;
46
+ }
47
+ export interface ExecuteResponse {
48
+ milkyway_version: string;
49
+ job_id: string;
50
+ status: "completed" | "failed" | "expired";
51
+ output?: Record<string, unknown>;
52
+ error?: string;
53
+ error_type?: "validation" | "payment" | "deadline" | "capability" | "internal";
54
+ completed_at?: number;
55
+ }
56
+ export type HandlerFn = (input: Record<string, unknown>) => Promise<Record<string, unknown>>;
57
+ export type Handlers = HandlerFn | {
58
+ [capabilityName: string]: HandlerFn;
59
+ };
60
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,SAAS,GACjB,QAAQ,GACR,QAAQ,GACR,SAAS,GACT,OAAO,GACP,QAAQ,CAAC;AAEb,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAU,SAAS,CAAC;IACxB,QAAQ,CAAC,EAAK,OAAO,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAM,OAAO,CAAC;IACtB,GAAG,CAAC,EAAU,MAAM,CAAC;IACrB,GAAG,CAAC,EAAU,MAAM,CAAC;IACrB,SAAS,CAAC,EAAI,MAAM,CAAC;IACrB,SAAS,CAAC,EAAI,MAAM,CAAC;IACrB,IAAI,CAAC,EAAS,OAAO,EAAE,CAAC;CACzB;AAED,MAAM,WAAW,WAAW;IAC1B,CAAC,KAAK,EAAE,MAAM,GAAG,QAAQ,CAAC;CAC3B;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAK,SAAS,GAAG,SAAS,GAAG,WAAW,GAAG,MAAM,CAAC;IACvD,MAAM,EAAI,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,aAAa;IAC5B,WAAW,EAAI,MAAM,CAAC;IACtB,OAAO,EAAQ,YAAY,CAAC;IAC5B,YAAY,EAAG,WAAW,CAAC;IAC3B,aAAa,EAAE,WAAW,CAAC;CAC5B;AAED,MAAM,WAAW,WAAW;IAC1B,gBAAgB,EAAO,MAAM,CAAC;IAC9B,IAAI,EAAmB,MAAM,CAAC;IAC9B,WAAW,EAAY,MAAM,CAAC;IAC9B,MAAM,EAAiB,MAAM,CAAC;IAC9B,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,YAAY,EAAE;QACZ,CAAC,cAAc,EAAE,MAAM,GAAG,aAAa,CAAC;KACzC,CAAC;CACH;AAED,MAAM,MAAM,aAAa,GAAG,WAAW,CAAC;AAExC,MAAM,WAAW,cAAc;IAC7B,gBAAgB,EAAE,MAAM,CAAC;IACzB,MAAM,EAAY,MAAM,CAAC;IACzB,IAAI,EAAE;QACJ,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,KAAK,EAAQ,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;KACtC,CAAC;IACF,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,eAAe;IAC9B,gBAAgB,EAAE,MAAM,CAAC;IACzB,MAAM,EAAY,MAAM,CAAC;IACzB,MAAM,EAAY,WAAW,GAAG,QAAQ,GAAG,SAAS,CAAC;IACrD,MAAM,CAAC,EAAW,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC1C,KAAK,CAAC,EAAY,MAAM,CAAC;IACzB,UAAU,CAAC,EAAO,YAAY,GAAG,SAAS,GAAG,UAAU,GAAG,YAAY,GAAG,UAAU,CAAC;IACpF,YAAY,CAAC,EAAK,MAAM,CAAC;CAC1B;AAED,MAAM,MAAM,SAAS,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;AAE7F,MAAM,MAAM,QAAQ,GAChB,SAAS,GACT;IAAE,CAAC,cAAc,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,CAAC"}
package/dist/types.js ADDED
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,3 @@
1
+ import { AgentSchema } from "./types";
2
+ export declare function validateInput(input: Record<string, unknown>, schema: AgentSchema): Record<string, unknown>;
3
+ //# sourceMappingURL=validator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validator.d.ts","sourceRoot":"","sources":["../src/validator.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAY,MAAM,SAAS,CAAC;AAgDhD,wBAAgB,aAAa,CAC3B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,MAAM,EAAE,WAAW,GAClB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAYzB"}
@@ -0,0 +1,61 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.validateInput = validateInput;
4
+ const zod_1 = require("zod");
5
+ const errors_1 = require("./errors");
6
+ function buildZodType(def) {
7
+ switch (def.type) {
8
+ case "string": {
9
+ if (def.enum)
10
+ return zod_1.z.enum(def.enum);
11
+ let t = zod_1.z.string();
12
+ if (def.minLength !== undefined)
13
+ t = t.min(def.minLength);
14
+ if (def.maxLength !== undefined)
15
+ t = t.max(def.maxLength);
16
+ return t;
17
+ }
18
+ case "number": {
19
+ let t = zod_1.z.number();
20
+ if (def.min !== undefined)
21
+ t = t.min(def.min);
22
+ if (def.max !== undefined)
23
+ t = t.max(def.max);
24
+ return t;
25
+ }
26
+ case "boolean":
27
+ return zod_1.z.boolean();
28
+ case "array":
29
+ return zod_1.z.array(zod_1.z.unknown());
30
+ case "object":
31
+ return zod_1.z.record(zod_1.z.unknown());
32
+ default:
33
+ return zod_1.z.unknown();
34
+ }
35
+ }
36
+ function buildZodSchema(schema) {
37
+ const shape = {};
38
+ for (const [field, def] of Object.entries(schema)) {
39
+ let zodType = buildZodType(def);
40
+ if (!def.required) {
41
+ zodType = zodType.optional();
42
+ if (def.default !== undefined) {
43
+ zodType = zodType.default(def.default);
44
+ }
45
+ }
46
+ shape[field] = zodType;
47
+ }
48
+ return zod_1.z.object(shape);
49
+ }
50
+ function validateInput(input, schema) {
51
+ const zodSchema = buildZodSchema(schema);
52
+ const result = zodSchema.safeParse(input);
53
+ if (!result.success) {
54
+ const issues = result.error.issues
55
+ .map(i => `${i.path.join(".")}: ${i.message}`)
56
+ .join(", ");
57
+ throw new errors_1.ValidationError(issues);
58
+ }
59
+ return result.data;
60
+ }
61
+ //# sourceMappingURL=validator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validator.js","sourceRoot":"","sources":["../src/validator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function verifyPayment(paymentHeader: string, _resource: string, amountUsdc: string): Promise<void>;
2
+ //# sourceMappingURL=verify.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verify.d.ts","sourceRoot":"","sources":["../src/verify.ts"],"names":[],"mappings":"AAmCA,wBAAsB,aAAa,CACjC,aAAa,EAAE,MAAM,EACrB,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,IAAI,CAAC,CAqEf"}
package/dist/verify.js ADDED
@@ -0,0 +1,83 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.verifyPayment = verifyPayment;
4
+ const ethers_1 = require("ethers");
5
+ const errors_js_1 = require("./errors.js");
6
+ const USDC_ADDRESS = "0xaf88d065e77c8cC2239327C5EDb3A432268e5831";
7
+ const ARBITRUM_RPC = process.env.ARBITRUM_RPC || "https://arb1.arbitrum.io/rpc";
8
+ const CHAIN_ID = 42161;
9
+ const EIP_3009_TYPES = {
10
+ TransferWithAuthorization: [
11
+ { name: "from", type: "address" },
12
+ { name: "to", type: "address" },
13
+ { name: "value", type: "uint256" },
14
+ { name: "validAfter", type: "uint256" },
15
+ { name: "validBefore", type: "uint256" },
16
+ { name: "nonce", type: "bytes32" },
17
+ ],
18
+ };
19
+ const DOMAIN = {
20
+ name: "USD Coin",
21
+ version: "2",
22
+ chainId: CHAIN_ID,
23
+ verifyingContract: USDC_ADDRESS,
24
+ };
25
+ async function verifyPayment(paymentHeader, _resource, amountUsdc) {
26
+ const rawAmount = BigInt(Math.round(parseFloat(amountUsdc) * 1000000));
27
+ let payload;
28
+ try {
29
+ payload = JSON.parse(Buffer.from(paymentHeader, "base64").toString("utf8"));
30
+ }
31
+ catch {
32
+ throw new errors_js_1.PaymentError("Invalid payment header format");
33
+ }
34
+ // Verify amount is sufficient
35
+ if (BigInt(payload.value) < rawAmount) {
36
+ throw new errors_js_1.PaymentError(`Insufficient payment: got ${payload.value} raw units, need ${rawAmount}`);
37
+ }
38
+ // Verify deadline
39
+ const now = Math.floor(Date.now() / 1000);
40
+ if (now < Number(payload.validAfter)) {
41
+ throw new errors_js_1.PaymentError("Payment not yet valid");
42
+ }
43
+ if (now > Number(payload.validBefore)) {
44
+ throw new errors_js_1.PaymentError("Payment authorization expired");
45
+ }
46
+ // Recover signer from EIP-712 signature
47
+ try {
48
+ const recovered = ethers_1.ethers.verifyTypedData(DOMAIN, EIP_3009_TYPES, {
49
+ from: payload.from,
50
+ to: payload.to,
51
+ value: payload.value,
52
+ validAfter: payload.validAfter,
53
+ validBefore: payload.validBefore,
54
+ nonce: payload.nonce,
55
+ }, payload.signature);
56
+ if (recovered.toLowerCase() !== payload.from.toLowerCase()) {
57
+ throw new errors_js_1.PaymentError("Signature does not match payer address");
58
+ }
59
+ }
60
+ catch (err) {
61
+ if (err instanceof errors_js_1.PaymentError)
62
+ throw err;
63
+ const message = err instanceof Error ? err.message : String(err);
64
+ throw new errors_js_1.PaymentError(`Signature verification failed: ${message}`);
65
+ }
66
+ // Optionally verify on-chain that the USDC balance exists
67
+ if (process.env.VERIFY_ONCHAIN === "true") {
68
+ try {
69
+ const provider = new ethers_1.ethers.JsonRpcProvider(ARBITRUM_RPC);
70
+ const usdc = new ethers_1.ethers.Contract(USDC_ADDRESS, ["function balanceOf(address) view returns (uint256)"], provider);
71
+ const balance = await usdc.balanceOf(payload.from);
72
+ if (balance < rawAmount) {
73
+ throw new errors_js_1.PaymentError("Payer has insufficient USDC balance on-chain");
74
+ }
75
+ }
76
+ catch (err) {
77
+ if (err instanceof errors_js_1.PaymentError)
78
+ throw err;
79
+ // RPC errors are non-fatal — trust the signature
80
+ }
81
+ }
82
+ }
83
+ //# sourceMappingURL=verify.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verify.js","sourceRoot":"","sources":["../src/verify.ts"],"names":[],"mappings":"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"}
package/dist/x402.d.ts ADDED
@@ -0,0 +1,4 @@
1
+ import { Request, Response, NextFunction } from "express";
2
+ import { AgentPricing } from "./types";
3
+ export declare function requirePayment(walletAddress: string, pricing: AgentPricing, devMode?: boolean): (req: Request, res: Response, next: NextFunction) => Promise<void | Response<any, Record<string, any>>>;
4
+ //# sourceMappingURL=x402.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"x402.d.ts","sourceRoot":"","sources":["../src/x402.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAE1D,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAIvC,wBAAgB,cAAc,CAC5B,aAAa,EAAE,MAAM,EACrB,OAAO,EAAE,YAAY,EACrB,OAAO,GAAE,OAAe,IAEV,KAAK,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,YAAY,wDA0C9D"}
package/dist/x402.js ADDED
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.requirePayment = requirePayment;
4
+ const verify_1 = require("./verify");
5
+ const USDC_ADDRESS = "0xaf88d065e77c8cC2239327C5EDb3A432268e5831";
6
+ function requirePayment(walletAddress, pricing, devMode = false) {
7
+ return async (req, res, next) => {
8
+ if (pricing.model === "free" || pricing.amount === "0") {
9
+ return next();
10
+ }
11
+ if (devMode) {
12
+ console.log("[dev mode] payment verification bypassed");
13
+ return next();
14
+ }
15
+ const paymentHeader = req.headers["payment-signature"] ||
16
+ req.headers["x-payment"];
17
+ if (!paymentHeader) {
18
+ return res.status(402).json({
19
+ x402Version: 1,
20
+ accepts: [{
21
+ scheme: "exact",
22
+ network: "eip155:42161",
23
+ maxAmountRequired: String(Math.round(parseFloat(pricing.amount) * 1000000)),
24
+ payTo: walletAddress,
25
+ asset: USDC_ADDRESS,
26
+ description: `${pricing.amount} ${pricing.currency} per job`,
27
+ maxTimeoutSeconds: 60,
28
+ extra: { name: "USD Coin", version: "2" }
29
+ }]
30
+ });
31
+ }
32
+ try {
33
+ const resource = `${req.protocol}://${req.get("host")}${req.path}`;
34
+ await (0, verify_1.verifyPayment)(paymentHeader, resource, pricing.amount);
35
+ next();
36
+ }
37
+ catch (err) {
38
+ const message = err instanceof Error ? err.message : String(err);
39
+ res.status(402).json({
40
+ x402Version: 1,
41
+ error: message
42
+ });
43
+ }
44
+ };
45
+ }
46
+ //# sourceMappingURL=x402.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"x402.js","sourceRoot":"","sources":["../src/x402.ts"],"names":[],"mappings":";;AAMA,wCA+CC;AApDD,qCAAyC;AAGzC,MAAM,YAAY,GAAG,4CAA4C,CAAC;AAElE,SAAgB,cAAc,CAC5B,aAAqB,EACrB,OAAqB,EACrB,UAAmB,KAAK;IAExB,OAAO,KAAK,EAAE,GAAY,EAAE,GAAa,EAAE,IAAkB,EAAE,EAAE;QAC/D,IAAI,OAAO,CAAC,KAAK,KAAK,MAAM,IAAI,OAAO,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;YACvD,OAAO,IAAI,EAAE,CAAC;QAChB,CAAC;QAED,IAAI,OAAO,EAAE,CAAC;YACZ,OAAO,CAAC,GAAG,CAAC,0CAA0C,CAAC,CAAC;YACxD,OAAO,IAAI,EAAE,CAAC;QAChB,CAAC;QAED,MAAM,aAAa,GAChB,GAAG,CAAC,OAAO,CAAC,mBAAmB,CAAY;YAC3C,GAAG,CAAC,OAAO,CAAC,WAAW,CAAY,CAAC;QAEvC,IAAI,CAAC,aAAa,EAAE,CAAC;YACnB,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;gBAC1B,WAAW,EAAE,CAAC;gBACd,OAAO,EAAE,CAAC;wBACR,MAAM,EAAa,OAAO;wBAC1B,OAAO,EAAY,cAAc;wBACjC,iBAAiB,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,OAAS,CAAC,CAAC;wBAC7E,KAAK,EAAc,aAAa;wBAChC,KAAK,EAAc,YAAY;wBAC/B,WAAW,EAAQ,GAAG,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,QAAQ,UAAU;wBAClE,iBAAiB,EAAE,EAAE;wBACrB,KAAK,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,GAAG,EAAE;qBAC1C,CAAC;aACH,CAAC,CAAC;QACL,CAAC;QAED,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,GAAG,GAAG,CAAC,QAAQ,MAAM,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;YACnE,MAAM,IAAA,sBAAa,EAAC,aAAa,EAAE,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;YAC7D,IAAI,EAAE,CAAC;QACT,CAAC;QAAC,OAAO,GAAY,EAAE,CAAC;YACtB,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACjE,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;gBACnB,WAAW,EAAE,CAAC;gBACd,KAAK,EAAE,OAAO;aACf,CAAC,CAAC;QACL,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
package/package.json ADDED
@@ -0,0 +1,27 @@
1
+ {
2
+ "name": "@usemilkyway/agent-sdk",
3
+ "version": "0.1.0",
4
+ "description": "Build and monetize AI agents on MilkyWay",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "files": ["dist"],
8
+ "publishConfig": {
9
+ "access": "public"
10
+ },
11
+ "scripts": {
12
+ "build": "tsc",
13
+ "dev": "tsc --watch",
14
+ "clean": "rm -rf dist"
15
+ },
16
+ "dependencies": {
17
+ "@coinbase/x402": "^0.4.0",
18
+ "express": "^4.18.0",
19
+ "ethers": "^6.0.0",
20
+ "zod": "^3.22.0"
21
+ },
22
+ "devDependencies": {
23
+ "typescript": "^5.0.0",
24
+ "@types/express": "^4.17.0",
25
+ "@types/node": "^20.0.0"
26
+ }
27
+ }