@absol-labs/agent 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.
Files changed (83) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +196 -0
  3. package/dist/discovery/registry.d.ts +68 -0
  4. package/dist/discovery/registry.d.ts.map +1 -0
  5. package/dist/discovery/registry.js +148 -0
  6. package/dist/discovery/registry.js.map +1 -0
  7. package/dist/frameworks/agentkit.d.ts +158 -0
  8. package/dist/frameworks/agentkit.d.ts.map +1 -0
  9. package/dist/frameworks/agentkit.js +339 -0
  10. package/dist/frameworks/agentkit.js.map +1 -0
  11. package/dist/frameworks/crewai.d.ts +19 -0
  12. package/dist/frameworks/crewai.d.ts.map +1 -0
  13. package/dist/frameworks/crewai.js +73 -0
  14. package/dist/frameworks/crewai.js.map +1 -0
  15. package/dist/frameworks/eliza.d.ts +393 -0
  16. package/dist/frameworks/eliza.d.ts.map +1 -0
  17. package/dist/frameworks/eliza.js +542 -0
  18. package/dist/frameworks/eliza.js.map +1 -0
  19. package/dist/frameworks/langchain.d.ts +31 -0
  20. package/dist/frameworks/langchain.d.ts.map +1 -0
  21. package/dist/frameworks/langchain.js +206 -0
  22. package/dist/frameworks/langchain.js.map +1 -0
  23. package/dist/index.d.ts +14 -0
  24. package/dist/index.d.ts.map +1 -0
  25. package/dist/index.js +16 -0
  26. package/dist/index.js.map +1 -0
  27. package/dist/mandates/env.d.ts +51 -0
  28. package/dist/mandates/env.d.ts.map +1 -0
  29. package/dist/mandates/env.js +148 -0
  30. package/dist/mandates/env.js.map +1 -0
  31. package/dist/mandates/mandate.d.ts +214 -0
  32. package/dist/mandates/mandate.d.ts.map +1 -0
  33. package/dist/mandates/mandate.js +172 -0
  34. package/dist/mandates/mandate.js.map +1 -0
  35. package/dist/mcp/http-server.d.ts +2 -0
  36. package/dist/mcp/http-server.d.ts.map +1 -0
  37. package/dist/mcp/http-server.js +32 -0
  38. package/dist/mcp/http-server.js.map +1 -0
  39. package/dist/mcp/http.d.ts +114 -0
  40. package/dist/mcp/http.d.ts.map +1 -0
  41. package/dist/mcp/http.js +428 -0
  42. package/dist/mcp/http.js.map +1 -0
  43. package/dist/mcp/server.d.ts +119 -0
  44. package/dist/mcp/server.d.ts.map +1 -0
  45. package/dist/mcp/server.js +679 -0
  46. package/dist/mcp/server.js.map +1 -0
  47. package/dist/mcp/stdio.d.ts +2 -0
  48. package/dist/mcp/stdio.d.ts.map +1 -0
  49. package/dist/mcp/stdio.js +6 -0
  50. package/dist/mcp/stdio.js.map +1 -0
  51. package/dist/sdk/client.d.ts +78 -0
  52. package/dist/sdk/client.d.ts.map +1 -0
  53. package/dist/sdk/client.js +99 -0
  54. package/dist/sdk/client.js.map +1 -0
  55. package/dist/wallet/provider.d.ts +51 -0
  56. package/dist/wallet/provider.d.ts.map +1 -0
  57. package/dist/wallet/provider.js +107 -0
  58. package/dist/wallet/provider.js.map +1 -0
  59. package/dist/x402/facilitator.d.ts +315 -0
  60. package/dist/x402/facilitator.d.ts.map +1 -0
  61. package/dist/x402/facilitator.js +194 -0
  62. package/dist/x402/facilitator.js.map +1 -0
  63. package/dist/zktls/reclaim.d.ts +137 -0
  64. package/dist/zktls/reclaim.d.ts.map +1 -0
  65. package/dist/zktls/reclaim.js +245 -0
  66. package/dist/zktls/reclaim.js.map +1 -0
  67. package/package.json +86 -0
  68. package/src/discovery/registry.ts +255 -0
  69. package/src/frameworks/agentkit.ts +537 -0
  70. package/src/frameworks/crewai.ts +102 -0
  71. package/src/frameworks/eliza.ts +776 -0
  72. package/src/frameworks/langchain.ts +325 -0
  73. package/src/index.ts +179 -0
  74. package/src/mandates/env.ts +222 -0
  75. package/src/mandates/mandate.ts +280 -0
  76. package/src/mcp/http-server.ts +38 -0
  77. package/src/mcp/http.ts +620 -0
  78. package/src/mcp/server.ts +1006 -0
  79. package/src/mcp/stdio.ts +8 -0
  80. package/src/sdk/client.ts +222 -0
  81. package/src/wallet/provider.ts +197 -0
  82. package/src/x402/facilitator.ts +336 -0
  83. package/src/zktls/reclaim.ts +424 -0
@@ -0,0 +1,214 @@
1
+ import { z } from "zod";
2
+ export declare const spendMandateSchema: z.ZodObject<{
3
+ /** Max deposit for any single stream. */
4
+ maxPerStreamUsdc: z.ZodBigInt;
5
+ /** Cumulative cap across all streams opened under this mandate. */
6
+ maxTotalUsdc: z.ZodBigInt;
7
+ /** Max ratePerSecond an agent may agree to. */
8
+ maxRatePerSecondUsdc: z.ZodBigInt;
9
+ /** Max stream duration in seconds. */
10
+ maxDurationSeconds: z.ZodNumber;
11
+ /** Allowed operator addresses; empty/undefined = any operator. */
12
+ allowedOperators: z.ZodOptional<z.ZodArray<z.ZodEffects<z.ZodString, `0x${string}`, string>, "many">>;
13
+ /** Mandate expiry, unix seconds. */
14
+ expiresAt: z.ZodNumber;
15
+ }, "strip", z.ZodTypeAny, {
16
+ maxPerStreamUsdc: bigint;
17
+ maxTotalUsdc: bigint;
18
+ maxRatePerSecondUsdc: bigint;
19
+ maxDurationSeconds: number;
20
+ expiresAt: number;
21
+ allowedOperators?: `0x${string}`[] | undefined;
22
+ }, {
23
+ maxPerStreamUsdc: bigint;
24
+ maxTotalUsdc: bigint;
25
+ maxRatePerSecondUsdc: bigint;
26
+ maxDurationSeconds: number;
27
+ expiresAt: number;
28
+ allowedOperators?: string[] | undefined;
29
+ }>;
30
+ export type SpendMandate = z.infer<typeof spendMandateSchema>;
31
+ export declare const signedSpendMandateSchema: z.ZodObject<{
32
+ mandateId: z.ZodEffects<z.ZodString, string, string>;
33
+ owner: z.ZodEffects<z.ZodString, `0x${string}`, string>;
34
+ chainId: z.ZodNumber;
35
+ issuedAt: z.ZodNumber;
36
+ mandate: z.ZodObject<{
37
+ /** Max deposit for any single stream. */
38
+ maxPerStreamUsdc: z.ZodBigInt;
39
+ /** Cumulative cap across all streams opened under this mandate. */
40
+ maxTotalUsdc: z.ZodBigInt;
41
+ /** Max ratePerSecond an agent may agree to. */
42
+ maxRatePerSecondUsdc: z.ZodBigInt;
43
+ /** Max stream duration in seconds. */
44
+ maxDurationSeconds: z.ZodNumber;
45
+ /** Allowed operator addresses; empty/undefined = any operator. */
46
+ allowedOperators: z.ZodOptional<z.ZodArray<z.ZodEffects<z.ZodString, `0x${string}`, string>, "many">>;
47
+ /** Mandate expiry, unix seconds. */
48
+ expiresAt: z.ZodNumber;
49
+ }, "strip", z.ZodTypeAny, {
50
+ maxPerStreamUsdc: bigint;
51
+ maxTotalUsdc: bigint;
52
+ maxRatePerSecondUsdc: bigint;
53
+ maxDurationSeconds: number;
54
+ expiresAt: number;
55
+ allowedOperators?: `0x${string}`[] | undefined;
56
+ }, {
57
+ maxPerStreamUsdc: bigint;
58
+ maxTotalUsdc: bigint;
59
+ maxRatePerSecondUsdc: bigint;
60
+ maxDurationSeconds: number;
61
+ expiresAt: number;
62
+ allowedOperators?: string[] | undefined;
63
+ }>;
64
+ signature: z.ZodEffects<z.ZodString, string, string>;
65
+ }, "strip", z.ZodTypeAny, {
66
+ mandateId: string;
67
+ owner: `0x${string}`;
68
+ chainId: number;
69
+ issuedAt: number;
70
+ mandate: {
71
+ maxPerStreamUsdc: bigint;
72
+ maxTotalUsdc: bigint;
73
+ maxRatePerSecondUsdc: bigint;
74
+ maxDurationSeconds: number;
75
+ expiresAt: number;
76
+ allowedOperators?: `0x${string}`[] | undefined;
77
+ };
78
+ signature: string;
79
+ }, {
80
+ mandateId: string;
81
+ owner: string;
82
+ chainId: number;
83
+ issuedAt: number;
84
+ mandate: {
85
+ maxPerStreamUsdc: bigint;
86
+ maxTotalUsdc: bigint;
87
+ maxRatePerSecondUsdc: bigint;
88
+ maxDurationSeconds: number;
89
+ expiresAt: number;
90
+ allowedOperators?: string[] | undefined;
91
+ };
92
+ signature: string;
93
+ }>;
94
+ export type SignedSpendMandate = z.infer<typeof signedSpendMandateSchema>;
95
+ export interface HireRequest {
96
+ operator: `0x${string}`;
97
+ budgetUsdc: bigint;
98
+ ratePerSecondUsdc: bigint;
99
+ maxDurationSeconds: number;
100
+ }
101
+ export interface MandateDecision {
102
+ allowed: boolean;
103
+ /** Machine-readable denial reason; undefined when allowed. */
104
+ reason?: "invalid-signature" | "mandate-revoked" | "mandate-expired" | "exceeds-per-stream-cap" | "exceeds-total-cap" | "exceeds-rate-cap" | "exceeds-duration-cap" | "operator-not-allowed";
105
+ }
106
+ export interface MandateVerificationContext {
107
+ readonly nowSeconds: number;
108
+ readonly revokedMandateIds?: Iterable<`0x${string}`>;
109
+ }
110
+ export declare const spendMandateDomain: {
111
+ readonly name: "MetrikAgentMandate";
112
+ readonly version: "1";
113
+ };
114
+ export declare const spendMandateTypedData: {
115
+ readonly SpendMandate: readonly [{
116
+ readonly name: "mandateId";
117
+ readonly type: "bytes32";
118
+ }, {
119
+ readonly name: "owner";
120
+ readonly type: "address";
121
+ }, {
122
+ readonly name: "issuedAt";
123
+ readonly type: "uint64";
124
+ }, {
125
+ readonly name: "expiresAt";
126
+ readonly type: "uint64";
127
+ }, {
128
+ readonly name: "maxPerStreamUsdc";
129
+ readonly type: "uint256";
130
+ }, {
131
+ readonly name: "maxTotalUsdc";
132
+ readonly type: "uint256";
133
+ }, {
134
+ readonly name: "maxRatePerSecondUsdc";
135
+ readonly type: "uint256";
136
+ }, {
137
+ readonly name: "maxDurationSeconds";
138
+ readonly type: "uint64";
139
+ }, {
140
+ readonly name: "allowedOperatorsHash";
141
+ readonly type: "bytes32";
142
+ }];
143
+ };
144
+ export declare function createSpendMandateTypedData(input: Omit<SignedSpendMandate, "signature">): {
145
+ domain: {
146
+ chainId: number;
147
+ name: "MetrikAgentMandate";
148
+ version: "1";
149
+ };
150
+ primaryType: "SpendMandate";
151
+ types: {
152
+ readonly SpendMandate: readonly [{
153
+ readonly name: "mandateId";
154
+ readonly type: "bytes32";
155
+ }, {
156
+ readonly name: "owner";
157
+ readonly type: "address";
158
+ }, {
159
+ readonly name: "issuedAt";
160
+ readonly type: "uint64";
161
+ }, {
162
+ readonly name: "expiresAt";
163
+ readonly type: "uint64";
164
+ }, {
165
+ readonly name: "maxPerStreamUsdc";
166
+ readonly type: "uint256";
167
+ }, {
168
+ readonly name: "maxTotalUsdc";
169
+ readonly type: "uint256";
170
+ }, {
171
+ readonly name: "maxRatePerSecondUsdc";
172
+ readonly type: "uint256";
173
+ }, {
174
+ readonly name: "maxDurationSeconds";
175
+ readonly type: "uint64";
176
+ }, {
177
+ readonly name: "allowedOperatorsHash";
178
+ readonly type: "bytes32";
179
+ }];
180
+ };
181
+ message: {
182
+ mandateId: `0x${string}`;
183
+ owner: `0x${string}`;
184
+ issuedAt: bigint;
185
+ expiresAt: bigint;
186
+ maxPerStreamUsdc: bigint;
187
+ maxTotalUsdc: bigint;
188
+ maxRatePerSecondUsdc: bigint;
189
+ maxDurationSeconds: bigint;
190
+ allowedOperatorsHash: `0x${string}`;
191
+ };
192
+ };
193
+ export declare function verifySignedMandate(signedMandate: SignedSpendMandate, context: MandateVerificationContext): Promise<MandateDecision>;
194
+ /**
195
+ * Signature-only authorization for BUYER-RECOVERY actions (close / reclaim).
196
+ *
197
+ * Close and reclaim only ever return unspent funds to the buyer or stop further
198
+ * payment — they never move funds to a seller. Gating them on mandate expiry or
199
+ * revocation would let a lapsed/revoked mandate strand the buyer's OWN funds in
200
+ * escrow, defeating the auto-refund guarantee. So these actions verify only that
201
+ * the mandate is authentically owner-signed (proving buyer intent); they do NOT
202
+ * check expiry, revocation, or spend caps. Fail-closed on a bad signature.
203
+ */
204
+ export declare function verifyMandateOwnerSignature(signedMandate: SignedSpendMandate): Promise<MandateDecision>;
205
+ /**
206
+ * Full mandate authorization check. A mandate must be owner-signed, unrevoked,
207
+ * and unexpired before the policy engine runs. Fail-closed: any breach denies.
208
+ */
209
+ export declare function checkMandate(signedMandate: SignedSpendMandate, request: HireRequest, spentSoFarUsdc: bigint, context: MandateVerificationContext): Promise<MandateDecision>;
210
+ /**
211
+ * Pure policy check over an already-verified mandate.
212
+ */
213
+ export declare function checkMandatePolicy(mandate: SpendMandate, request: HireRequest, spentSoFarUsdc: bigint, nowSeconds: number): MandateDecision;
214
+ //# sourceMappingURL=mandate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mandate.d.ts","sourceRoot":"","sources":["../../src/mandates/mandate.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAwBxB,eAAO,MAAM,kBAAkB;IAC7B,yCAAyC;;IAEzC,mEAAmE;;IAEnE,+CAA+C;;IAE/C,sCAAsC;;IAEtC,kEAAkE;;IAElE,oCAAoC;;;;;;;;;;;;;;;;EAEpC,CAAC;AAEH,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAE9D,eAAO,MAAM,wBAAwB;;;;;;QAhBnC,yCAAyC;;QAEzC,mEAAmE;;QAEnE,+CAA+C;;QAE/C,sCAAsC;;QAEtC,kEAAkE;;QAElE,oCAAoC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAapC,CAAC;AAEH,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAE1E,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,KAAK,MAAM,EAAE,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,OAAO,CAAC;IACjB,8DAA8D;IAC9D,MAAM,CAAC,EACH,mBAAmB,GACnB,iBAAiB,GACjB,iBAAiB,GACjB,wBAAwB,GACxB,mBAAmB,GACnB,kBAAkB,GAClB,sBAAsB,GACtB,sBAAsB,CAAC;CAC5B;AAED,MAAM,WAAW,0BAA0B;IACzC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,iBAAiB,CAAC,EAAE,QAAQ,CAAC,KAAK,MAAM,EAAE,CAAC,CAAC;CACtD;AAED,eAAO,MAAM,kBAAkB;;;CAGrB,CAAC;AAEX,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAYxB,CAAC;AAIX,wBAAgB,2BAA2B,CACzC,KAAK,EAAE,IAAI,CAAC,kBAAkB,EAAE,WAAW,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;mBAcT,KAAK,MAAM,EAAE;;;;;;;;;;EAajD;AAED,wBAAsB,mBAAmB,CACvC,aAAa,EAAE,kBAAkB,EACjC,OAAO,EAAE,0BAA0B,GAClC,OAAO,CAAC,eAAe,CAAC,CA4B1B;AAED;;;;;;;;;GASG;AACH,wBAAsB,2BAA2B,CAC/C,aAAa,EAAE,kBAAkB,GAChC,OAAO,CAAC,eAAe,CAAC,CAe1B;AAED;;;GAGG;AACH,wBAAsB,YAAY,CAChC,aAAa,EAAE,kBAAkB,EACjC,OAAO,EAAE,WAAW,EACpB,cAAc,EAAE,MAAM,EACtB,OAAO,EAAE,0BAA0B,GAClC,OAAO,CAAC,eAAe,CAAC,CAY1B;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,YAAY,EACrB,OAAO,EAAE,WAAW,EACpB,cAAc,EAAE,MAAM,EACtB,UAAU,EAAE,MAAM,GACjB,eAAe,CAyBjB"}
@@ -0,0 +1,172 @@
1
+ import { encodeAbiParameters, getAddress, isAddress, isHex, keccak256, recoverTypedDataAddress, } from "viem";
2
+ import { z } from "zod";
3
+ /**
4
+ * Spend mandate — the guardrail that lets an AI agent transact autonomously while
5
+ * its owner stays in control. A signed mandate caps how much, how fast, for how
6
+ * long, and with whom an agent may open verified payment streams.
7
+ */
8
+ const addressSchema = z
9
+ .string()
10
+ .refine((value) => isAddress(value), "must be an EVM address");
11
+ const bytes32Schema = z
12
+ .string()
13
+ .refine((value) => isHex(value, { strict: true }) && value.length === 66, "must be bytes32 hex");
14
+ const signatureSchema = z
15
+ .string()
16
+ .refine((value) => isHex(value, { strict: true }) && value.length === 132, "must be a 65-byte signature");
17
+ export const spendMandateSchema = z.object({
18
+ /** Max deposit for any single stream. */
19
+ maxPerStreamUsdc: z.bigint().positive(),
20
+ /** Cumulative cap across all streams opened under this mandate. */
21
+ maxTotalUsdc: z.bigint().positive(),
22
+ /** Max ratePerSecond an agent may agree to. */
23
+ maxRatePerSecondUsdc: z.bigint().positive(),
24
+ /** Max stream duration in seconds. */
25
+ maxDurationSeconds: z.number().int().positive(),
26
+ /** Allowed operator addresses; empty/undefined = any operator. */
27
+ allowedOperators: z.array(addressSchema).optional(),
28
+ /** Mandate expiry, unix seconds. */
29
+ expiresAt: z.number().int().positive(),
30
+ });
31
+ export const signedSpendMandateSchema = z.object({
32
+ mandateId: bytes32Schema,
33
+ owner: addressSchema,
34
+ chainId: z.number().int().positive(),
35
+ issuedAt: z.number().int().nonnegative(),
36
+ mandate: spendMandateSchema,
37
+ signature: signatureSchema,
38
+ });
39
+ export const spendMandateDomain = {
40
+ name: "MetrikAgentMandate",
41
+ version: "1",
42
+ };
43
+ export const spendMandateTypedData = {
44
+ SpendMandate: [
45
+ { name: "mandateId", type: "bytes32" },
46
+ { name: "owner", type: "address" },
47
+ { name: "issuedAt", type: "uint64" },
48
+ { name: "expiresAt", type: "uint64" },
49
+ { name: "maxPerStreamUsdc", type: "uint256" },
50
+ { name: "maxTotalUsdc", type: "uint256" },
51
+ { name: "maxRatePerSecondUsdc", type: "uint256" },
52
+ { name: "maxDurationSeconds", type: "uint64" },
53
+ { name: "allowedOperatorsHash", type: "bytes32" },
54
+ ],
55
+ };
56
+ const ALLOW = { allowed: true };
57
+ export function createSpendMandateTypedData(input) {
58
+ const parsed = signedSpendMandateSchema
59
+ .omit({ signature: true })
60
+ .parse(input);
61
+ return {
62
+ domain: {
63
+ ...spendMandateDomain,
64
+ chainId: parsed.chainId,
65
+ },
66
+ primaryType: "SpendMandate",
67
+ types: spendMandateTypedData,
68
+ message: {
69
+ mandateId: parsed.mandateId,
70
+ owner: getAddress(parsed.owner),
71
+ issuedAt: BigInt(parsed.issuedAt),
72
+ expiresAt: BigInt(parsed.mandate.expiresAt),
73
+ maxPerStreamUsdc: parsed.mandate.maxPerStreamUsdc,
74
+ maxTotalUsdc: parsed.mandate.maxTotalUsdc,
75
+ maxRatePerSecondUsdc: parsed.mandate.maxRatePerSecondUsdc,
76
+ maxDurationSeconds: BigInt(parsed.mandate.maxDurationSeconds),
77
+ allowedOperatorsHash: hashAllowedOperators(parsed.mandate.allowedOperators),
78
+ },
79
+ };
80
+ }
81
+ export async function verifySignedMandate(signedMandate, context) {
82
+ const parsedMandate = signedSpendMandateSchema.parse(signedMandate);
83
+ const recovered = await recoverTypedDataAddress({
84
+ ...createSpendMandateTypedData(parsedMandate),
85
+ signature: parsedMandate.signature,
86
+ }).catch(() => null);
87
+ if (recovered === null ||
88
+ recovered.toLowerCase() !== parsedMandate.owner.toLowerCase()) {
89
+ return { allowed: false, reason: "invalid-signature" };
90
+ }
91
+ if (isRevoked(parsedMandate.mandateId, context.revokedMandateIds)) {
92
+ return { allowed: false, reason: "mandate-revoked" };
93
+ }
94
+ if (context.nowSeconds >= parsedMandate.mandate.expiresAt) {
95
+ return { allowed: false, reason: "mandate-expired" };
96
+ }
97
+ return ALLOW;
98
+ }
99
+ /**
100
+ * Signature-only authorization for BUYER-RECOVERY actions (close / reclaim).
101
+ *
102
+ * Close and reclaim only ever return unspent funds to the buyer or stop further
103
+ * payment — they never move funds to a seller. Gating them on mandate expiry or
104
+ * revocation would let a lapsed/revoked mandate strand the buyer's OWN funds in
105
+ * escrow, defeating the auto-refund guarantee. So these actions verify only that
106
+ * the mandate is authentically owner-signed (proving buyer intent); they do NOT
107
+ * check expiry, revocation, or spend caps. Fail-closed on a bad signature.
108
+ */
109
+ export async function verifyMandateOwnerSignature(signedMandate) {
110
+ const parsed = signedSpendMandateSchema.parse(signedMandate);
111
+ const recovered = await recoverTypedDataAddress({
112
+ ...createSpendMandateTypedData(parsed),
113
+ signature: parsed.signature,
114
+ }).catch(() => null);
115
+ if (recovered === null ||
116
+ recovered.toLowerCase() !== parsed.owner.toLowerCase()) {
117
+ return { allowed: false, reason: "invalid-signature" };
118
+ }
119
+ return ALLOW;
120
+ }
121
+ /**
122
+ * Full mandate authorization check. A mandate must be owner-signed, unrevoked,
123
+ * and unexpired before the policy engine runs. Fail-closed: any breach denies.
124
+ */
125
+ export async function checkMandate(signedMandate, request, spentSoFarUsdc, context) {
126
+ const signatureDecision = await verifySignedMandate(signedMandate, context);
127
+ if (!signatureDecision.allowed) {
128
+ return signatureDecision;
129
+ }
130
+ return checkMandatePolicy(signedMandate.mandate, request, spentSoFarUsdc, context.nowSeconds);
131
+ }
132
+ /**
133
+ * Pure policy check over an already-verified mandate.
134
+ */
135
+ export function checkMandatePolicy(mandate, request, spentSoFarUsdc, nowSeconds) {
136
+ if (nowSeconds >= mandate.expiresAt)
137
+ return { allowed: false, reason: "mandate-expired" };
138
+ if (request.budgetUsdc > mandate.maxPerStreamUsdc) {
139
+ return { allowed: false, reason: "exceeds-per-stream-cap" };
140
+ }
141
+ if (spentSoFarUsdc + request.budgetUsdc > mandate.maxTotalUsdc) {
142
+ return { allowed: false, reason: "exceeds-total-cap" };
143
+ }
144
+ if (request.ratePerSecondUsdc > mandate.maxRatePerSecondUsdc) {
145
+ return { allowed: false, reason: "exceeds-rate-cap" };
146
+ }
147
+ if (request.maxDurationSeconds > mandate.maxDurationSeconds) {
148
+ return { allowed: false, reason: "exceeds-duration-cap" };
149
+ }
150
+ if (mandate.allowedOperators &&
151
+ mandate.allowedOperators.length > 0 &&
152
+ !mandate.allowedOperators.some((operator) => operator.toLowerCase() === request.operator.toLowerCase())) {
153
+ return { allowed: false, reason: "operator-not-allowed" };
154
+ }
155
+ return ALLOW;
156
+ }
157
+ function hashAllowedOperators(operators) {
158
+ const normalized = (operators ?? []).map((operator) => getAddress(operator));
159
+ return keccak256(encodeAbiParameters([{ type: "address[]" }], [normalized]));
160
+ }
161
+ function isRevoked(mandateId, revokedMandateIds) {
162
+ if (revokedMandateIds === undefined) {
163
+ return false;
164
+ }
165
+ for (const revokedMandateId of revokedMandateIds) {
166
+ if (revokedMandateId.toLowerCase() === mandateId.toLowerCase()) {
167
+ return true;
168
+ }
169
+ }
170
+ return false;
171
+ }
172
+ //# sourceMappingURL=mandate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mandate.js","sourceRoot":"","sources":["../../src/mandates/mandate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=http-server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http-server.d.ts","sourceRoot":"","sources":["../../src/mcp/http-server.ts"],"names":[],"mappings":""}
@@ -0,0 +1,32 @@
1
+ import { startHostedMcpHttpServerFromEnv } from "./http.js";
2
+ /**
3
+ * Runnable entrypoint for the hosted, multi-tenant MCP server over Streamable
4
+ * HTTP. Reads all configuration from the environment (see
5
+ * {@link parseHostedMcpServerConfig}) and refuses to start when no tenant
6
+ * tokens are configured (fail-closed).
7
+ *
8
+ * Start with: `pnpm mcp:http` (or `node dist/mcp/http-server.js`).
9
+ */
10
+ async function main() {
11
+ const server = await startHostedMcpHttpServerFromEnv();
12
+ const path = process.env.METRIK_MCP_PATH ?? "/mcp";
13
+ const host = process.env.METRIK_MCP_HOST ?? "0.0.0.0";
14
+ // Config only — never log tokens or wallet secrets.
15
+ console.error(`[metrik-agent-mcp-http] listening on http://${host}:${server.boundPort}${path}`);
16
+ const shutdown = (signal) => {
17
+ console.error(`[metrik-agent-mcp-http] ${signal} received — shutting down`);
18
+ server
19
+ .close()
20
+ .then(() => process.exit(0))
21
+ .catch(() => process.exit(1));
22
+ };
23
+ process.on("SIGINT", () => shutdown("SIGINT"));
24
+ process.on("SIGTERM", () => shutdown("SIGTERM"));
25
+ }
26
+ main().catch((error) => {
27
+ console.error(error instanceof Error
28
+ ? error.message
29
+ : "failed to start hosted MCP server");
30
+ process.exit(1);
31
+ });
32
+ //# sourceMappingURL=http-server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http-server.js","sourceRoot":"","sources":["../../src/mcp/http-server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,+BAA+B,EAAE,MAAM,WAAW,CAAC;AAE5D;;;;;;;GAOG;AACH,KAAK,UAAU,IAAI;IACjB,MAAM,MAAM,GAAG,MAAM,+BAA+B,EAAE,CAAC;IACvD,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,MAAM,CAAC;IACnD,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,SAAS,CAAC;IACtD,oDAAoD;IACpD,OAAO,CAAC,KAAK,CACX,+CAA+C,IAAI,IAAI,MAAM,CAAC,SAAS,GAAG,IAAI,EAAE,CACjF,CAAC;IAEF,MAAM,QAAQ,GAAG,CAAC,MAAc,EAAE,EAAE;QAClC,OAAO,CAAC,KAAK,CAAC,2BAA2B,MAAM,2BAA2B,CAAC,CAAC;QAC5E,MAAM;aACH,KAAK,EAAE;aACP,IAAI,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;aAC3B,KAAK,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IAClC,CAAC,CAAC;IACF,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC/C,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC;AACnD,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACrB,OAAO,CAAC,KAAK,CACX,KAAK,YAAY,KAAK;QACpB,CAAC,CAAC,KAAK,CAAC,OAAO;QACf,CAAC,CAAC,mCAAmC,CACxC,CAAC;IACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
@@ -0,0 +1,114 @@
1
+ import { type Server } from "node:http";
2
+ import { type VerifiedStreamMcpServerOptions } from "./server.js";
3
+ /**
4
+ * A single authenticated tenant: a bearer token plus the wallet/mandate-scoped
5
+ * MCP server options used to build that tenant's server instances.
6
+ */
7
+ export interface HostedMcpTenant {
8
+ /** Stable, human-readable tenant identifier (used only for routing/logging). */
9
+ readonly id: string;
10
+ /** The tenant's secret bearer token. Never logged. */
11
+ readonly token: string;
12
+ /**
13
+ * The tenant's isolated MCP server options (its own agent client + registry).
14
+ * A fresh `McpServer` is built from these for each of the tenant's sessions.
15
+ */
16
+ readonly options: VerifiedStreamMcpServerOptions;
17
+ }
18
+ /** Resolves a presented bearer token to a tenant, or `null` when invalid. */
19
+ export interface TenantResolver {
20
+ authenticate(token: string): HostedMcpTenant | null;
21
+ }
22
+ /**
23
+ * Constant-time, env-backed tenant resolver.
24
+ *
25
+ * Tokens are pre-hashed with SHA-256 (fixed 32-byte width) so every comparison
26
+ * uses `timingSafeEqual` on equal-length buffers, and the loop always visits
27
+ * every tenant with no early exit — neither the presented token's length nor
28
+ * which tenant matched is observable via timing.
29
+ */
30
+ export declare class StaticTenantResolver implements TenantResolver {
31
+ private readonly entries;
32
+ constructor(tenants: readonly HostedMcpTenant[]);
33
+ authenticate(token: string): HostedMcpTenant | null;
34
+ }
35
+ export interface HostedMcpHttpServerOptions {
36
+ readonly resolver: TenantResolver;
37
+ /** HTTP path the MCP endpoint is served on. Default `/mcp`. */
38
+ readonly path?: string;
39
+ /**
40
+ * Allowed CORS origins. `["*"]` allows any origin. When omitted, no
41
+ * cross-origin `Access-Control-Allow-Origin` header is emitted (same-origin
42
+ * / non-browser clients only).
43
+ */
44
+ readonly allowedOrigins?: readonly string[];
45
+ /** Session id generator. Default: cryptographically-random UUID v4. */
46
+ readonly generateSessionId?: () => string;
47
+ }
48
+ export interface HostedMcpHttpServer {
49
+ readonly httpServer: Server;
50
+ /** Bind and start listening. Resolves with the actual bound address. */
51
+ listen(port: number, host?: string): Promise<{
52
+ port: number;
53
+ host: string;
54
+ }>;
55
+ /** Stop accepting requests and tear down all live sessions. */
56
+ close(): Promise<void>;
57
+ }
58
+ /**
59
+ * Creates (but does not start) a hosted multi-tenant MCP HTTP server.
60
+ *
61
+ * Use {@link HostedMcpHttpServer.listen} to bind it. The returned server is
62
+ * suitable for tests (bind to port 0 for an ephemeral port) and for
63
+ * deployment (bind to `0.0.0.0`/`PORT`).
64
+ */
65
+ export declare function createHostedMcpHttpServer(options: HostedMcpHttpServerOptions): HostedMcpHttpServer;
66
+ /**
67
+ * Per-tenant configuration parsed from the hosted server environment.
68
+ *
69
+ * Each tenant carries the environment slice (`METRIK_AGENT_*`, wallet vars,
70
+ * optional Reclaim vars) that builds its OWN wallet-backed agent client, so
71
+ * tenants are fully fund-isolated from one another.
72
+ */
73
+ export interface HostedMcpTenantConfig {
74
+ readonly id: string;
75
+ readonly token: string;
76
+ readonly env: Readonly<Record<string, string>>;
77
+ }
78
+ export interface HostedMcpServerConfig {
79
+ readonly host: string;
80
+ readonly port: number;
81
+ readonly path: string;
82
+ readonly allowedOrigins: readonly string[];
83
+ readonly tenants: readonly HostedMcpTenantConfig[];
84
+ }
85
+ /**
86
+ * Parses the hosted MCP server configuration from environment variables.
87
+ *
88
+ * Env contract:
89
+ * - `PORT` / `METRIK_MCP_PORT` — listen port (default 8080).
90
+ * - `METRIK_MCP_HOST` — bind host (default `0.0.0.0`).
91
+ * - `METRIK_MCP_PATH` — MCP endpoint path (default `/mcp`).
92
+ * - `METRIK_MCP_ALLOWED_ORIGINS` — comma-separated CORS origins, or `*`.
93
+ * - `METRIK_MCP_TENANTS` — JSON array of
94
+ * `{ "id": string, "token": string, "env"?: Record<string,string> }`.
95
+ * Each tenant's `env` is layered over the process environment and used to
96
+ * build that tenant's isolated, wallet-backed agent client.
97
+ *
98
+ * Throws (fail-closed) when no tenants/tokens are configured.
99
+ */
100
+ export declare function parseHostedMcpServerConfig(env?: NodeJS.ProcessEnv): HostedMcpServerConfig;
101
+ /**
102
+ * Builds fully-isolated {@link HostedMcpTenant}s from parsed config, resolving
103
+ * each tenant's wallet-backed agent client from its own environment slice.
104
+ */
105
+ export declare function createHostedMcpTenants(config: HostedMcpServerConfig, baseEnv?: NodeJS.ProcessEnv): Promise<HostedMcpTenant[]>;
106
+ /**
107
+ * Builds and starts a hosted MCP HTTP server entirely from the environment.
108
+ *
109
+ * Fail-closed: throws before binding if no tenants/tokens are configured.
110
+ */
111
+ export declare function startHostedMcpHttpServerFromEnv(env?: NodeJS.ProcessEnv): Promise<HostedMcpHttpServer & {
112
+ readonly boundPort: number;
113
+ }>;
114
+ //# sourceMappingURL=http.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../src/mcp/http.ts"],"names":[],"mappings":"AACA,OAAO,EAGL,KAAK,MAAM,EAEZ,MAAM,WAAW,CAAC;AAOnB,OAAO,EAGL,KAAK,8BAA8B,EAEpC,MAAM,aAAa,CAAC;AA4BrB;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,gFAAgF;IAChF,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,sDAAsD;IACtD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB;;;OAGG;IACH,QAAQ,CAAC,OAAO,EAAE,8BAA8B,CAAC;CAClD;AAED,6EAA6E;AAC7E,MAAM,WAAW,cAAc;IAC7B,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,eAAe,GAAG,IAAI,CAAC;CACrD;AAMD;;;;;;;GAOG;AACH,qBAAa,oBAAqB,YAAW,cAAc;IACzD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAGpB;gBAEQ,OAAO,EAAE,SAAS,eAAe,EAAE;IA+B/C,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,eAAe,GAAG,IAAI;CAYpD;AAED,MAAM,WAAW,0BAA0B;IACzC,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC;IAClC,+DAA+D;IAC/D,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB;;;;OAIG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5C,uEAAuE;IACvE,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,MAAM,CAAC;CAC3C;AAQD,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,wEAAwE;IACxE,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC7E,+DAA+D;IAC/D,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAED;;;;;;GAMG;AACH,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,0BAA0B,GAClC,mBAAmB,CAkDrB;AA6PD;;;;;;GAMG;AACH,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,GAAG,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CAChD;AAED,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,cAAc,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3C,QAAQ,CAAC,OAAO,EAAE,SAAS,qBAAqB,EAAE,CAAC;CACpD;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,0BAA0B,CACxC,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,qBAAqB,CAoEvB;AAED;;;GAGG;AACH,wBAAsB,sBAAsB,CAC1C,MAAM,EAAE,qBAAqB,EAC7B,OAAO,GAAE,MAAM,CAAC,UAAwB,GACvC,OAAO,CAAC,eAAe,EAAE,CAAC,CAc5B;AAED;;;;GAIG;AACH,wBAAsB,+BAA+B,CACnD,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,OAAO,CAAC,mBAAmB,GAAG;IAAE,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC,CAW/D"}