@vinaystwt/xmpp-mcp 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 (31) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +10 -0
  3. package/dist/apps/mcp-server/src/index.d.ts +2 -0
  4. package/dist/apps/mcp-server/src/index.js +10 -0
  5. package/dist/apps/mcp-server/src/server.d.ts +9 -0
  6. package/dist/apps/mcp-server/src/server.js +232 -0
  7. package/dist/packages/config/src/index.d.ts +49 -0
  8. package/dist/packages/config/src/index.js +117 -0
  9. package/dist/packages/contract-runtime/src/index.d.ts +44 -0
  10. package/dist/packages/contract-runtime/src/index.js +364 -0
  11. package/dist/packages/http-interceptor/src/agents.d.ts +5 -0
  12. package/dist/packages/http-interceptor/src/agents.js +88 -0
  13. package/dist/packages/http-interceptor/src/idempotency.d.ts +68 -0
  14. package/dist/packages/http-interceptor/src/idempotency.js +149 -0
  15. package/dist/packages/http-interceptor/src/index.d.ts +10 -0
  16. package/dist/packages/http-interceptor/src/index.js +870 -0
  17. package/dist/packages/http-interceptor/src/state.d.ts +17 -0
  18. package/dist/packages/http-interceptor/src/state.js +188 -0
  19. package/dist/packages/logger/src/index.d.ts +2 -0
  20. package/dist/packages/logger/src/index.js +18 -0
  21. package/dist/packages/payment-adapters/src/index.d.ts +27 -0
  22. package/dist/packages/payment-adapters/src/index.js +512 -0
  23. package/dist/packages/policy-engine/src/index.d.ts +8 -0
  24. package/dist/packages/policy-engine/src/index.js +90 -0
  25. package/dist/packages/router/src/index.d.ts +23 -0
  26. package/dist/packages/router/src/index.js +432 -0
  27. package/dist/packages/types/src/index.d.ts +343 -0
  28. package/dist/packages/types/src/index.js +1 -0
  29. package/dist/packages/wallet/src/index.d.ts +14 -0
  30. package/dist/packages/wallet/src/index.js +250 -0
  31. package/package.json +69 -0
@@ -0,0 +1,17 @@
1
+ import type { XmppAgentProfile, RouteKind, XmppAgentStateSummary, XmppBudgetSnapshot, XmppOperatorState, XmppRouteEvent, XmppSessionRecord } from '@xmpp/types';
2
+ export declare function recordXmppEvent(input: Omit<XmppRouteEvent, 'id' | 'timestamp'>): XmppRouteEvent;
3
+ export declare function upsertLocalSession(sessionId: string, serviceId: string, callCount: number): void;
4
+ export declare function listLocalSessions(): Pick<XmppSessionRecord, "serviceId" | "sessionId" | "callCount">[];
5
+ export declare function buildBudgetSnapshot(input: {
6
+ agentId?: string;
7
+ agentProfile?: XmppAgentProfile;
8
+ url: string;
9
+ method: string;
10
+ serviceId?: string;
11
+ route: RouteKind;
12
+ projectedRequests?: number;
13
+ hasReusableSession?: boolean;
14
+ }): XmppBudgetSnapshot;
15
+ export declare function buildAgentStates(profiles?: XmppAgentProfile[]): XmppAgentStateSummary[];
16
+ export declare function getXmppOperatorState(agentProfiles?: XmppAgentProfile[]): XmppOperatorState;
17
+ export declare function resetXmppOperatorState(): void;
@@ -0,0 +1,188 @@
1
+ import { config } from '@xmpp/config';
2
+ import { createRouter, estimateRouteCost, resolveCatalogEntry } from '@xmpp/router';
3
+ import { getXmppAgentProfile, listXmppAgentProfiles } from './agents.js';
4
+ const router = createRouter();
5
+ const recentEvents = [];
6
+ const serviceSpendUsd = new Map();
7
+ const serviceCallCounts = new Map();
8
+ const agentSpendUsd = new Map();
9
+ const agentServiceCallCounts = new Map();
10
+ const agentRouteCounts = new Map();
11
+ const routeCounts = {
12
+ x402: 0,
13
+ 'mpp-charge': 0,
14
+ 'mpp-session-open': 0,
15
+ 'mpp-session-reuse': 0,
16
+ };
17
+ const openSessions = new Map();
18
+ let sessionSavingsUsd = 0;
19
+ function roundUsd(value) {
20
+ return Math.round(value * 1000) / 1000;
21
+ }
22
+ function pushEvent(event) {
23
+ recentEvents.unshift(event);
24
+ if (recentEvents.length > 25) {
25
+ recentEvents.length = 25;
26
+ }
27
+ }
28
+ function emptyRouteCounts() {
29
+ return {
30
+ x402: 0,
31
+ 'mpp-charge': 0,
32
+ 'mpp-session-open': 0,
33
+ 'mpp-session-reuse': 0,
34
+ };
35
+ }
36
+ function getAgentRouteCounter(agentId) {
37
+ const existing = agentRouteCounts.get(agentId);
38
+ if (existing) {
39
+ return existing;
40
+ }
41
+ const created = emptyRouteCounts();
42
+ agentRouteCounts.set(agentId, created);
43
+ return created;
44
+ }
45
+ export function recordXmppEvent(input) {
46
+ const event = {
47
+ id: `evt_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`,
48
+ timestamp: new Date().toISOString(),
49
+ ...input,
50
+ amountUsd: roundUsd(input.amountUsd),
51
+ };
52
+ pushEvent(event);
53
+ if (event.status === 'settled' && event.amountUsd > 0) {
54
+ routeCounts[event.route] += 1;
55
+ getAgentRouteCounter(event.agentId)[event.route] += 1;
56
+ serviceSpendUsd.set(event.serviceId, roundUsd((serviceSpendUsd.get(event.serviceId) ?? 0) + event.amountUsd));
57
+ serviceCallCounts.set(event.serviceId, (serviceCallCounts.get(event.serviceId) ?? 0) + 1);
58
+ agentSpendUsd.set(event.agentId, roundUsd((agentSpendUsd.get(event.agentId) ?? 0) + event.amountUsd));
59
+ agentServiceCallCounts.set(`${event.agentId}:${event.serviceId}`, (agentServiceCallCounts.get(`${event.agentId}:${event.serviceId}`) ?? 0) + 1);
60
+ const naiveCost = estimateRouteCost({
61
+ route: 'x402',
62
+ url: event.url,
63
+ method: event.method,
64
+ serviceId: event.serviceId,
65
+ projectedRequests: 1,
66
+ });
67
+ sessionSavingsUsd = roundUsd(sessionSavingsUsd + Math.max(0, naiveCost - event.amountUsd));
68
+ }
69
+ return event;
70
+ }
71
+ export function upsertLocalSession(sessionId, serviceId, callCount) {
72
+ openSessions.set(sessionId, {
73
+ sessionId,
74
+ serviceId,
75
+ callCount,
76
+ });
77
+ }
78
+ export function listLocalSessions() {
79
+ return [...openSessions.values()];
80
+ }
81
+ export function buildBudgetSnapshot(input) {
82
+ const agent = input.agentProfile ?? getXmppAgentProfile(input.agentId);
83
+ const serviceId = input.serviceId ?? resolveCatalogEntry(input).serviceId;
84
+ const callsThisService = agentServiceCallCounts.get(`${agent.agentId}:${serviceId}`) ?? 0;
85
+ const agentSpentThisSessionUsd = roundUsd(agentSpendUsd.get(agent.agentId) ?? 0);
86
+ const agentRemainingDailyBudgetUsd = roundUsd(Math.max(0, agent.dailyBudgetUsd - agentSpentThisSessionUsd));
87
+ const spentThisSessionUsd = roundUsd([...serviceSpendUsd.values()].reduce((sum, value) => sum + value, 0));
88
+ const remainingDailyBudgetUsd = roundUsd(Math.max(0, config.dailyBudgetUsd - spentThisSessionUsd));
89
+ const projectedCostIfRepeated5xUsd = roundUsd(estimateRouteCost({
90
+ route: input.route,
91
+ url: input.url,
92
+ method: input.method,
93
+ serviceId,
94
+ projectedRequests: 5,
95
+ hasReusableSession: input.hasReusableSession,
96
+ }));
97
+ const catalog = resolveCatalogEntry({
98
+ url: input.url,
99
+ method: input.method,
100
+ serviceId,
101
+ projectedRequests: input.projectedRequests,
102
+ streaming: false,
103
+ });
104
+ const repeatDecision = router.explain({
105
+ url: input.url,
106
+ method: input.method,
107
+ serviceId,
108
+ projectedRequests: Math.max(callsThisService + 1, catalog.routingHints.breakEvenCalls),
109
+ streaming: catalog.routingHints.streamingPreferred,
110
+ hasReusableSession: input.hasReusableSession,
111
+ });
112
+ let recommendation = `${repeatDecision.service?.displayName ?? serviceId} stays on ${repeatDecision.route} under the current usage forecast.`;
113
+ if (input.route === 'x402' &&
114
+ catalog.capabilities.mppSession &&
115
+ callsThisService < catalog.routingHints.breakEvenCalls) {
116
+ const remainingCalls = catalog.routingHints.breakEvenCalls - callsThisService;
117
+ recommendation = `Switch to MPP session after ${remainingCalls} more calls to amortize channel setup.`;
118
+ }
119
+ else if (input.route === 'mpp-session-open' || input.route === 'mpp-session-reuse') {
120
+ recommendation = 'Keep reusing the current MPP session to compress repeat spend into one channel lifecycle.';
121
+ }
122
+ else if (input.route === 'mpp-charge') {
123
+ recommendation = 'MPP charge remains the cleanest path for premium one-shot calls on this service.';
124
+ }
125
+ return {
126
+ agentId: agent.agentId,
127
+ agentDisplayName: agent.displayName,
128
+ agentSpentThisSessionUsd,
129
+ agentRemainingDailyBudgetUsd,
130
+ spentThisSessionUsd,
131
+ remainingDailyBudgetUsd,
132
+ callsThisService,
133
+ projectedCostIfRepeated5xUsd,
134
+ recommendation,
135
+ };
136
+ }
137
+ export function buildAgentStates(profiles = listXmppAgentProfiles()) {
138
+ return profiles.map((profile) => {
139
+ const spentThisSessionUsd = roundUsd(agentSpendUsd.get(profile.agentId) ?? 0);
140
+ return {
141
+ agentId: profile.agentId,
142
+ displayName: profile.displayName,
143
+ role: profile.role,
144
+ description: profile.description,
145
+ dailyBudgetUsd: profile.dailyBudgetUsd,
146
+ spentThisSessionUsd,
147
+ remainingDailyBudgetUsd: roundUsd(Math.max(0, profile.dailyBudgetUsd - spentThisSessionUsd)),
148
+ routeCounts: { ...getAgentRouteCounter(profile.agentId) },
149
+ allowedServices: [...profile.allowedServices],
150
+ preferredRoutes: [...profile.preferredRoutes],
151
+ enabled: profile.enabled ?? true,
152
+ policySource: profile.policySource ?? 'local',
153
+ autopayMethods: [...profile.autopayMethods],
154
+ };
155
+ });
156
+ }
157
+ export function getXmppOperatorState(agentProfiles = listXmppAgentProfiles()) {
158
+ const spentThisSessionUsd = roundUsd([...serviceSpendUsd.values()].reduce((sum, value) => sum + value, 0));
159
+ return {
160
+ sharedTreasuryUsd: config.dailyBudgetUsd,
161
+ sharedTreasuryRemainingUsd: roundUsd(Math.max(0, config.dailyBudgetUsd - spentThisSessionUsd)),
162
+ dailyBudgetUsd: config.dailyBudgetUsd,
163
+ spentThisSessionUsd,
164
+ remainingDailyBudgetUsd: roundUsd(Math.max(0, config.dailyBudgetUsd - spentThisSessionUsd)),
165
+ sessionSavingsUsd,
166
+ routeCounts: { ...routeCounts },
167
+ serviceSpendUsd: Object.fromEntries(serviceSpendUsd),
168
+ serviceCallCounts: Object.fromEntries(serviceCallCounts),
169
+ agentProfiles,
170
+ agentStates: buildAgentStates(agentProfiles),
171
+ openSessions: listLocalSessions(),
172
+ recentEvents: [...recentEvents],
173
+ };
174
+ }
175
+ export function resetXmppOperatorState() {
176
+ recentEvents.length = 0;
177
+ serviceSpendUsd.clear();
178
+ serviceCallCounts.clear();
179
+ agentSpendUsd.clear();
180
+ agentServiceCallCounts.clear();
181
+ agentRouteCounts.clear();
182
+ openSessions.clear();
183
+ sessionSavingsUsd = 0;
184
+ routeCounts.x402 = 0;
185
+ routeCounts['mpp-charge'] = 0;
186
+ routeCounts['mpp-session-open'] = 0;
187
+ routeCounts['mpp-session-reuse'] = 0;
188
+ }
@@ -0,0 +1,2 @@
1
+ import pino from 'pino';
2
+ export declare const logger: pino.Logger<never, boolean>;
@@ -0,0 +1,18 @@
1
+ import pino from 'pino';
2
+ export const logger = pino({
3
+ name: 'xmpp',
4
+ level: process.env.LOG_LEVEL ?? 'info',
5
+ redact: {
6
+ paths: [
7
+ 'req.headers.authorization',
8
+ 'req.headers.x-api-key',
9
+ 'req.headers.cookie',
10
+ 'req.body.headers.authorization',
11
+ 'req.body.headers.x-api-key',
12
+ 'req.body.options.idempotencyKey',
13
+ 'err.config.headers.authorization',
14
+ 'err.config.headers.x-api-key',
15
+ ],
16
+ censor: '[REDACTED]',
17
+ },
18
+ });
@@ -0,0 +1,27 @@
1
+ import { Keypair, xdr } from '@stellar/stellar-sdk';
2
+ import type { PaymentChallenge, PaymentExecutionMetadata, PaymentExecutionResult, RouteKind } from '@xmpp/types';
3
+ import { XLM_SAC_TESTNET } from '@stellar/mpp';
4
+ declare function createClassicSignatureScVal(keypair: Keypair, payload: Buffer): xdr.ScVal;
5
+ declare function createDelegatedSignerScVal(publicKey: string): xdr.ScVal;
6
+ declare function createDelegatedAuthPayload(publicKey: string, contextRuleIds: number[]): xdr.ScVal;
7
+ declare function buildSmartAccountSignaturePayload(entry: xdr.SorobanAuthorizationEntry, networkPassphrase: string): Buffer<ArrayBufferLike>;
8
+ declare function buildSmartAccountAuthDigest(signaturePayload: Buffer, contextRuleIds: number[]): Buffer<ArrayBufferLike>;
9
+ declare function signDelegatedSmartAccountAuth(authEntries: xdr.SorobanAuthorizationEntry[], smartAccountContractId: string, delegatedSigner: Keypair, expiration: number, networkPassphrase: string, contextRuleIds?: number[]): xdr.SorobanAuthorizationEntry[];
10
+ export declare const __smartAccountTestUtils: {
11
+ createClassicSignatureScVal: typeof createClassicSignatureScVal;
12
+ createDelegatedSignerScVal: typeof createDelegatedSignerScVal;
13
+ createDelegatedAuthPayload: typeof createDelegatedAuthPayload;
14
+ buildSmartAccountSignaturePayload: typeof buildSmartAccountSignaturePayload;
15
+ buildSmartAccountAuthDigest: typeof buildSmartAccountAuthDigest;
16
+ signDelegatedSmartAccountAuth: typeof signDelegatedSmartAccountAuth;
17
+ };
18
+ export declare function buildRetryHeaders(challenge: PaymentChallenge, route: RouteKind): {
19
+ [challenge.retryHeaderName]: string;
20
+ 'x-xmpp-route': RouteKind;
21
+ };
22
+ export declare function preparePaymentExecution(challenge: PaymentChallenge, route: RouteKind): {
23
+ headers: Record<string, string>;
24
+ metadata: PaymentExecutionMetadata;
25
+ };
26
+ export declare function executePaymentRoute(route: RouteKind, input: RequestInfo | URL, init?: RequestInit): Promise<PaymentExecutionResult>;
27
+ export { XLM_SAC_TESTNET };