@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,343 @@
1
+ export type RouteKind = 'x402' | 'mpp-charge' | 'mpp-session-open' | 'mpp-session-reuse';
2
+ export type PaymentExecutionMode = 'mock' | 'testnet';
3
+ export type PaymentExecutionStatus = 'mock-paid' | 'ready-for-testnet' | 'settled-testnet' | 'missing-config';
4
+ export type RouteContext = {
5
+ url: string;
6
+ method: string;
7
+ serviceId?: string;
8
+ projectedRequests?: number;
9
+ streaming?: boolean;
10
+ };
11
+ export type ServiceCatalogEntry = {
12
+ serviceId: string;
13
+ displayName: string;
14
+ description: string;
15
+ baseUrl: string;
16
+ source?: 'static' | 'discovered' | 'hybrid' | 'fallback';
17
+ capabilities: {
18
+ x402: boolean;
19
+ mppCharge: boolean;
20
+ mppSession: boolean;
21
+ };
22
+ pricing: {
23
+ x402PerCallUsd: number;
24
+ mppChargePerCallUsd: number;
25
+ mppSessionOpenUsd: number;
26
+ mppSessionPerCallUsd: number;
27
+ };
28
+ routingHints: {
29
+ breakEvenCalls: number;
30
+ streamingPreferred: boolean;
31
+ preferredSingleCall: Extract<RouteKind, 'x402' | 'mpp-charge'>;
32
+ };
33
+ };
34
+ export type RouteScoreBreakdown = {
35
+ route: RouteKind;
36
+ supported: boolean;
37
+ estimatedTotalUsd: number;
38
+ savingsVsNaiveUsd: number;
39
+ totalScore: number;
40
+ reasons: string[];
41
+ };
42
+ export type RouteDecision = {
43
+ route: RouteKind;
44
+ reason: string;
45
+ score: number;
46
+ projectedRequests?: number;
47
+ estimatedTotalUsd?: number;
48
+ savingsVsNaiveUsd?: number;
49
+ service?: ServiceCatalogEntry;
50
+ breakdown?: RouteScoreBreakdown[];
51
+ };
52
+ export type ChallengeKind = 'x402' | 'mpp-charge' | 'mpp-session';
53
+ export type PaymentChallenge = {
54
+ kind: ChallengeKind;
55
+ service: string;
56
+ amountUsd: number;
57
+ asset: 'USDC_TESTNET';
58
+ retryHeaderName: string;
59
+ retryHeaderValue: string;
60
+ sessionId?: string;
61
+ };
62
+ export type XmppFetchOptions = Omit<RouteContext, 'url' | 'method'> & {
63
+ agentId?: string;
64
+ maxAutoPayUsd?: number;
65
+ idempotencyKey?: string;
66
+ };
67
+ export type XmppAgentProfile = {
68
+ agentId: string;
69
+ displayName: string;
70
+ role: 'shared' | 'research' | 'market';
71
+ description: string;
72
+ dailyBudgetUsd: number;
73
+ allowedServices: string[];
74
+ preferredRoutes: RouteKind[];
75
+ autopayMethods: string[];
76
+ enabled?: boolean;
77
+ policySource?: 'local' | 'contract' | 'fallback' | 'merged';
78
+ };
79
+ export type XmppSignedReceipt = {
80
+ receiptId: string;
81
+ issuedAt: string;
82
+ network: string;
83
+ agent: string;
84
+ serviceId: string;
85
+ url: string;
86
+ method: string;
87
+ route: RouteKind;
88
+ amountUsd: number;
89
+ txHash?: string;
90
+ explorerUrl?: string;
91
+ paymentReference?: string;
92
+ signature: string;
93
+ };
94
+ export type XmppSmartAccountExecution = {
95
+ configured: boolean;
96
+ preferred: boolean;
97
+ supported: boolean;
98
+ used: boolean;
99
+ contractId?: string | null;
100
+ fallbackReason?: string;
101
+ };
102
+ export type PaymentExecutionMetadata = {
103
+ mode: PaymentExecutionMode;
104
+ status: PaymentExecutionStatus;
105
+ route: RouteKind;
106
+ receiptId: string;
107
+ missingConfig?: string[];
108
+ evidenceHeaders?: Record<string, string>;
109
+ signedReceipt?: XmppSignedReceipt;
110
+ settlementStrategy?: 'keypair' | 'smart-account' | 'keypair-fallback';
111
+ executionNote?: string;
112
+ feeSponsored?: boolean;
113
+ feeSponsorPublicKey?: string;
114
+ feeBumpPublicKey?: string;
115
+ smartAccount?: XmppSmartAccountExecution;
116
+ };
117
+ export type PolicyDecision = {
118
+ allowed: boolean;
119
+ reason: string;
120
+ code: 'allowed' | 'blocked-domain' | 'blocked-path' | 'blocked-method' | 'blocked-service' | 'blocked-agent' | 'blocked-budget' | 'blocked-idempotency' | 'paused';
121
+ source?: 'local' | 'contract' | 'fallback';
122
+ };
123
+ export type PaymentExecutionResult = {
124
+ response: Response;
125
+ metadata: PaymentExecutionMetadata;
126
+ };
127
+ export type XmppFetchMetadata = {
128
+ route: RouteKind;
129
+ challenge?: PaymentChallenge;
130
+ retried: boolean;
131
+ execution?: PaymentExecutionMetadata;
132
+ policy?: PolicyDecision;
133
+ budget?: XmppBudgetSnapshot;
134
+ idempotentReplay?: boolean;
135
+ };
136
+ export type XmppSessionRecord = {
137
+ sessionId: string;
138
+ serviceId: string;
139
+ agent: string;
140
+ channelContractId: string;
141
+ route: string;
142
+ status: string;
143
+ totalAmountUsdCents: number;
144
+ callCount: number;
145
+ lastReceiptId: string;
146
+ updatedAtLedger: number;
147
+ };
148
+ export type WorkflowEstimateStep = {
149
+ url: string;
150
+ method?: string;
151
+ serviceId?: string;
152
+ projectedRequests: number;
153
+ streaming?: boolean;
154
+ };
155
+ export type WorkflowEstimateLineItem = {
156
+ serviceId: string;
157
+ displayName: string;
158
+ route: RouteKind;
159
+ projectedRequests: number;
160
+ estimatedCostUsd: number;
161
+ savingsVsNaiveUsd: number;
162
+ reason: string;
163
+ };
164
+ export type WorkflowEstimateResult = {
165
+ totalEstimatedCostUsd: number;
166
+ naiveX402CostUsd: number;
167
+ savingsVsNaiveUsd: number;
168
+ breakdown: WorkflowEstimateLineItem[];
169
+ };
170
+ export type XmppBudgetSnapshot = {
171
+ agentId: string;
172
+ agentDisplayName: string;
173
+ agentSpentThisSessionUsd: number;
174
+ agentRemainingDailyBudgetUsd: number;
175
+ spentThisSessionUsd: number;
176
+ remainingDailyBudgetUsd: number;
177
+ callsThisService: number;
178
+ projectedCostIfRepeated5xUsd: number;
179
+ recommendation: string;
180
+ };
181
+ export type XmppRouteEvent = {
182
+ id: string;
183
+ timestamp: string;
184
+ agentId: string;
185
+ url: string;
186
+ method: string;
187
+ serviceId: string;
188
+ route: RouteKind;
189
+ status: 'settled' | 'denied' | 'preview';
190
+ amountUsd: number;
191
+ projectedRequests: number;
192
+ policyCode?: PolicyDecision['code'];
193
+ receiptId?: string;
194
+ txHash?: string;
195
+ explorerUrl?: string;
196
+ sessionId?: string;
197
+ signedReceipt?: XmppSignedReceipt;
198
+ feeSponsored?: boolean;
199
+ feeSponsorPublicKey?: string;
200
+ settlementStrategy?: PaymentExecutionMetadata['settlementStrategy'];
201
+ executionNote?: string;
202
+ };
203
+ export type XmppAgentStateSummary = {
204
+ agentId: string;
205
+ displayName: string;
206
+ role: XmppAgentProfile['role'];
207
+ description: string;
208
+ dailyBudgetUsd: number;
209
+ spentThisSessionUsd: number;
210
+ remainingDailyBudgetUsd: number;
211
+ routeCounts: Record<RouteKind, number>;
212
+ allowedServices: string[];
213
+ preferredRoutes: RouteKind[];
214
+ enabled?: boolean;
215
+ policySource?: XmppAgentProfile['policySource'];
216
+ autopayMethods?: string[];
217
+ };
218
+ export type XmppAgentPolicySnapshot = {
219
+ agentId: string;
220
+ enabled: boolean;
221
+ dailyBudgetUsd: number;
222
+ allowedServices: string[];
223
+ preferredRoutes: RouteKind[];
224
+ autopayMethods: string[];
225
+ source: 'contract' | 'local' | 'fallback';
226
+ };
227
+ export type XmppContractTreasurySnapshot = {
228
+ sharedTreasuryUsd: number;
229
+ totalSpentUsd: number;
230
+ remainingUsd: number;
231
+ paymentCount: number;
232
+ source: 'contract' | 'local' | 'fallback';
233
+ };
234
+ export type XmppContractAgentTreasuryState = {
235
+ agentId: string;
236
+ spentUsd: number;
237
+ paymentCount: number;
238
+ lastServiceId: string;
239
+ lastRoute: string;
240
+ source: 'contract' | 'local' | 'fallback';
241
+ };
242
+ export type XmppOperatorState = {
243
+ sharedTreasuryUsd: number;
244
+ sharedTreasuryRemainingUsd: number;
245
+ dailyBudgetUsd: number;
246
+ spentThisSessionUsd: number;
247
+ remainingDailyBudgetUsd: number;
248
+ sessionSavingsUsd: number;
249
+ routeCounts: Record<RouteKind, number>;
250
+ serviceSpendUsd: Record<string, number>;
251
+ serviceCallCounts: Record<string, number>;
252
+ agentProfiles: XmppAgentProfile[];
253
+ agentStates: XmppAgentStateSummary[];
254
+ contractAgentPolicies?: XmppAgentPolicySnapshot[];
255
+ contractTreasury?: XmppContractTreasurySnapshot | null;
256
+ contractAgentTreasuryStates?: XmppContractAgentTreasuryState[];
257
+ openSessions: Array<Pick<XmppSessionRecord, 'sessionId' | 'serviceId' | 'callCount'>>;
258
+ recentEvents: XmppRouteEvent[];
259
+ };
260
+ export type XmppReceiptVerificationResult = {
261
+ valid: boolean;
262
+ agent: string;
263
+ receiptId: string;
264
+ };
265
+ export type XmppWalletInfo = {
266
+ connected: boolean;
267
+ paymentExecutionMode: PaymentExecutionMode;
268
+ network: string;
269
+ rpcUrl: string;
270
+ agentPublicKey: string | null;
271
+ settlementStrategy: 'smart-account-ready' | 'smart-account-x402-preferred' | 'smart-account-partial-fallback' | 'keypair-live';
272
+ smartAccount: {
273
+ ready: boolean;
274
+ mode: 'inactive' | 'x402-only' | 'full';
275
+ routeCoverage: 'inactive' | 'x402-only';
276
+ demoReady: boolean;
277
+ guardedFallback: boolean;
278
+ contractId: string | null;
279
+ wasmHash: string;
280
+ webauthnVerifierAddress: string;
281
+ ed25519VerifierAddress: string;
282
+ spendingLimitPolicyAddress: string;
283
+ thresholdPolicyAddress: string;
284
+ preferredRoutes: RouteKind[];
285
+ fallbackRoutes: RouteKind[];
286
+ supportedRoutes: RouteKind[];
287
+ unsupportedRoutes: RouteKind[];
288
+ unsupportedReason: string | null;
289
+ configuredMaxTransactionFeeStroops: number;
290
+ effectiveMaxTransactionFeeStroops: number;
291
+ feeFloorApplied: boolean;
292
+ preflightFailures: string[];
293
+ coverageMessage: string;
294
+ message: string;
295
+ operatorNotes: string[];
296
+ };
297
+ feeSponsorship: {
298
+ enabled: boolean;
299
+ available: boolean;
300
+ mppChargeEnabled: boolean;
301
+ mppSessionEnabled: boolean;
302
+ sponsorPublicKey: string | null;
303
+ feeBumpPublicKey: string | null;
304
+ message: string;
305
+ };
306
+ missingSecrets: string[];
307
+ message: string;
308
+ };
309
+ export type XmppHealthStatus = {
310
+ ok: boolean;
311
+ service: string;
312
+ network: string;
313
+ paymentExecutionMode: PaymentExecutionMode;
314
+ services: Record<string, string>;
315
+ smartAccount: {
316
+ configured: boolean;
317
+ routeCoverage: 'inactive' | 'x402-only';
318
+ x402Preferred: boolean;
319
+ mppFallback: boolean;
320
+ demoReady: boolean;
321
+ guardedFallback: boolean;
322
+ unsupportedRoutes: RouteKind[];
323
+ unsupportedReason: string | null;
324
+ configuredMaxTransactionFeeStroops: number;
325
+ effectiveMaxTransactionFeeStroops: number;
326
+ feeFloorApplied: boolean;
327
+ preflightFailures: string[];
328
+ };
329
+ };
330
+ export type XmppCatalogResponse = {
331
+ services: ServiceCatalogEntry[];
332
+ };
333
+ export type XmppPolicyPreviewResponse = {
334
+ policy: PolicyDecision;
335
+ routePreview: RouteDecision;
336
+ };
337
+ export type XmppGatewayFetchResponse = {
338
+ status: number;
339
+ routePreview: RouteDecision;
340
+ payment?: XmppFetchMetadata;
341
+ responseHeaders: Record<string, string>;
342
+ body: unknown;
343
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,14 @@
1
+ import type { PaymentExecutionMetadata, RouteKind, XmppReceiptVerificationResult, XmppSignedReceipt, XmppSmartAccountExecution, XmppWalletInfo } from '@xmpp/types';
2
+ export declare const SMART_ACCOUNT_MIN_TRANSACTION_FEE_STROOPS = 2000000;
3
+ export declare function signXmppReceipt(input: Omit<XmppSignedReceipt, 'signature' | 'agent' | 'issuedAt' | 'network'> & {
4
+ issuedAt?: string;
5
+ network?: string;
6
+ }): XmppSignedReceipt | null;
7
+ export declare function verifyXmppReceipt(receipt: XmppSignedReceipt): XmppReceiptVerificationResult;
8
+ export declare function getEffectiveSmartAccountFeeCeiling(): number;
9
+ export declare function getRouteExecutionPlan(route: RouteKind): {
10
+ settlementStrategy: PaymentExecutionMetadata['settlementStrategy'];
11
+ executionNote: string;
12
+ smartAccount: XmppSmartAccountExecution;
13
+ };
14
+ export declare function getWalletInfo(): Promise<XmppWalletInfo>;
@@ -0,0 +1,250 @@
1
+ import { config } from '@xmpp/config';
2
+ import { Keypair } from '@stellar/stellar-sdk';
3
+ export const SMART_ACCOUNT_MIN_TRANSACTION_FEE_STROOPS = 2_000_000;
4
+ function stableReceiptPayload(receipt) {
5
+ return JSON.stringify({
6
+ receiptId: receipt.receiptId,
7
+ issuedAt: receipt.issuedAt,
8
+ network: receipt.network,
9
+ agent: receipt.agent,
10
+ serviceId: receipt.serviceId,
11
+ url: receipt.url,
12
+ method: receipt.method,
13
+ route: receipt.route,
14
+ amountUsd: receipt.amountUsd,
15
+ txHash: receipt.txHash ?? null,
16
+ explorerUrl: receipt.explorerUrl ?? null,
17
+ paymentReference: receipt.paymentReference ?? null,
18
+ });
19
+ }
20
+ export function signXmppReceipt(input) {
21
+ if (!config.wallet.agentSecretKey) {
22
+ return null;
23
+ }
24
+ const keypair = Keypair.fromSecret(config.wallet.agentSecretKey);
25
+ const receipt = {
26
+ ...input,
27
+ issuedAt: input.issuedAt ?? new Date().toISOString(),
28
+ network: input.network ?? config.network,
29
+ agent: keypair.publicKey(),
30
+ };
31
+ const payload = Buffer.from(stableReceiptPayload(receipt), 'utf8');
32
+ const signature = keypair.sign(payload).toString('base64');
33
+ return {
34
+ ...receipt,
35
+ signature,
36
+ };
37
+ }
38
+ export function verifyXmppReceipt(receipt) {
39
+ const keypair = Keypair.fromPublicKey(receipt.agent);
40
+ const payload = Buffer.from(stableReceiptPayload({
41
+ receiptId: receipt.receiptId,
42
+ issuedAt: receipt.issuedAt,
43
+ network: receipt.network,
44
+ agent: receipt.agent,
45
+ serviceId: receipt.serviceId,
46
+ url: receipt.url,
47
+ method: receipt.method,
48
+ route: receipt.route,
49
+ amountUsd: receipt.amountUsd,
50
+ txHash: receipt.txHash,
51
+ explorerUrl: receipt.explorerUrl,
52
+ paymentReference: receipt.paymentReference,
53
+ }), 'utf8');
54
+ return {
55
+ valid: keypair.verify(payload, Buffer.from(receipt.signature, 'base64')),
56
+ agent: receipt.agent,
57
+ receiptId: receipt.receiptId,
58
+ };
59
+ }
60
+ function smartAccountConfigured() {
61
+ return Boolean(config.wallet.smartAccountContractId);
62
+ }
63
+ export function getEffectiveSmartAccountFeeCeiling() {
64
+ if (!smartAccountConfigured()) {
65
+ return config.x402.maxTransactionFeeStroops;
66
+ }
67
+ return Math.max(config.x402.maxTransactionFeeStroops, SMART_ACCOUNT_MIN_TRANSACTION_FEE_STROOPS);
68
+ }
69
+ function smartAccountFeeFloorApplied() {
70
+ return smartAccountConfigured() &&
71
+ config.x402.maxTransactionFeeStroops < SMART_ACCOUNT_MIN_TRANSACTION_FEE_STROOPS;
72
+ }
73
+ function getSmartAccountPreflightFailures() {
74
+ if (!smartAccountConfigured()) {
75
+ return ['XMPP_SMART_ACCOUNT_CONTRACT_ID'];
76
+ }
77
+ return [
78
+ !config.wallet.agentSecretKey ? 'XMPP_AGENT_SECRET_KEY' : null,
79
+ !config.x402.facilitatorPrivateKey ? 'FACILITATOR_STELLAR_PRIVATE_KEY' : null,
80
+ ].filter((value) => value !== null);
81
+ }
82
+ function smartAccountPrimaryReady() {
83
+ return Boolean(config.wallet.smartAccountContractId &&
84
+ config.wallet.agentSecretKey &&
85
+ config.x402.facilitatorPrivateKey);
86
+ }
87
+ export function getRouteExecutionPlan(route) {
88
+ const configured = smartAccountConfigured();
89
+ const liveReady = smartAccountPrimaryReady();
90
+ if (route === 'x402') {
91
+ if (liveReady) {
92
+ return {
93
+ settlementStrategy: 'smart-account',
94
+ executionNote: 'x402 prefers the configured smart account, with an automatic fallback to keypair settlement if delegated auth becomes unavailable.',
95
+ smartAccount: {
96
+ configured: true,
97
+ preferred: true,
98
+ supported: true,
99
+ used: true,
100
+ contractId: config.wallet.smartAccountContractId ?? null,
101
+ },
102
+ };
103
+ }
104
+ return {
105
+ settlementStrategy: 'keypair',
106
+ executionNote: configured
107
+ ? 'Smart account is configured, but x402 is staying on the agent keypair until the smart-account demo preconditions are fully satisfied.'
108
+ : 'x402 is executing with the agent keypair.',
109
+ smartAccount: {
110
+ configured,
111
+ preferred: configured,
112
+ supported: true,
113
+ used: false,
114
+ contractId: config.wallet.smartAccountContractId ?? null,
115
+ fallbackReason: configured
116
+ ? 'Smart-account x402 is guarded until the delegated signer, facilitator, and fee-cap preconditions are all ready.'
117
+ : 'No smart account is configured.',
118
+ },
119
+ };
120
+ }
121
+ return {
122
+ settlementStrategy: configured ? 'keypair-fallback' : 'keypair',
123
+ executionNote: configured
124
+ ? 'MPP is using explicit keypair execution because the current MPP SDK requires Keypair signers.'
125
+ : 'MPP is executing with the configured keypair signer.',
126
+ smartAccount: {
127
+ configured,
128
+ preferred: configured,
129
+ supported: false,
130
+ used: false,
131
+ contractId: config.wallet.smartAccountContractId ?? null,
132
+ fallbackReason: configured
133
+ ? 'Current MPP client flows require Keypair signers.'
134
+ : 'No smart account is configured.',
135
+ },
136
+ };
137
+ }
138
+ export async function getWalletInfo() {
139
+ const agentKeypair = config.wallet.agentSecretKey
140
+ ? Keypair.fromSecret(config.wallet.agentSecretKey)
141
+ : null;
142
+ const feeSponsorSecret = config.mpp.feeSponsorSecretKey ??
143
+ ((config.mpp.feeSponsorship.chargeEnabled || config.mpp.feeSponsorship.sessionEnabled)
144
+ ? config.mpp.secretKey
145
+ : undefined);
146
+ const feeSponsorKeypair = feeSponsorSecret ? Keypair.fromSecret(feeSponsorSecret) : null;
147
+ const feeBumpKeypair = config.mpp.feeBumpSecretKey
148
+ ? Keypair.fromSecret(config.mpp.feeBumpSecretKey)
149
+ : null;
150
+ const smartAccountReady = smartAccountConfigured();
151
+ const smartAccountActive = smartAccountPrimaryReady();
152
+ const smartAccountPreflightFailures = getSmartAccountPreflightFailures();
153
+ const smartAccountEffectiveFeeCeiling = getEffectiveSmartAccountFeeCeiling();
154
+ const smartAccountFeeFloorWasApplied = smartAccountFeeFloorApplied();
155
+ const smartAccountMode = smartAccountActive
156
+ ? 'x402-only'
157
+ : smartAccountReady
158
+ ? 'x402-only'
159
+ : 'inactive';
160
+ const smartAccountRouteCoverage = smartAccountReady
161
+ ? 'x402-only'
162
+ : 'inactive';
163
+ const smartAccountOperatorNotes = smartAccountActive
164
+ ? [
165
+ 'Smart-account execution is enabled for x402 only.',
166
+ 'If delegated x402 settlement becomes unavailable, xMPP falls back to the stable keypair path instead of surfacing a smart-account-specific failure.',
167
+ 'MPP charge and session flows still use keypair execution because the current MPP client requires Keypair signers.',
168
+ smartAccountFeeFloorWasApplied
169
+ ? `The facilitator is enforcing a safe x402 fee ceiling of at least ${SMART_ACCOUNT_MIN_TRANSACTION_FEE_STROOPS.toLocaleString()} stroops for smart-account execution.`
170
+ : `The facilitator fee ceiling is set to ${smartAccountEffectiveFeeCeiling.toLocaleString()} stroops for smart-account x402 execution.`,
171
+ ]
172
+ : smartAccountReady
173
+ ? [
174
+ 'A smart-account contract id is configured, but x402 is still guarded behind the stable keypair path until all demo preconditions are satisfied.',
175
+ 'MPP charge and session flows remain explicit keypair routes.',
176
+ ]
177
+ : ['Smart-account execution is not configured yet.'];
178
+ const missingSecrets = [
179
+ !config.wallet.agentSecretKey ? 'XMPP_AGENT_SECRET_KEY' : null,
180
+ !config.x402.facilitatorPrivateKey ? 'FACILITATOR_STELLAR_PRIVATE_KEY' : null,
181
+ !config.mpp.secretKey ? 'MPP_SECRET_KEY' : null,
182
+ ].filter((value) => value !== null);
183
+ return {
184
+ connected: missingSecrets.length === 0,
185
+ paymentExecutionMode: config.paymentExecutionMode,
186
+ network: config.network,
187
+ rpcUrl: config.rpcUrl,
188
+ agentPublicKey: agentKeypair?.publicKey() ?? null,
189
+ settlementStrategy: smartAccountActive
190
+ ? 'smart-account-x402-preferred'
191
+ : smartAccountReady
192
+ ? 'smart-account-partial-fallback'
193
+ : 'keypair-live',
194
+ smartAccount: {
195
+ ready: smartAccountReady,
196
+ mode: smartAccountMode,
197
+ routeCoverage: smartAccountRouteCoverage,
198
+ demoReady: smartAccountActive,
199
+ guardedFallback: smartAccountReady,
200
+ contractId: config.wallet.smartAccountContractId ?? null,
201
+ wasmHash: config.wallet.smartAccountWasmHash,
202
+ webauthnVerifierAddress: config.wallet.webauthnVerifierAddress,
203
+ ed25519VerifierAddress: config.wallet.ed25519VerifierAddress,
204
+ spendingLimitPolicyAddress: config.wallet.spendingLimitPolicyAddress,
205
+ thresholdPolicyAddress: config.wallet.thresholdPolicyAddress,
206
+ preferredRoutes: smartAccountActive ? ['x402'] : [],
207
+ fallbackRoutes: smartAccountReady ? ['mpp-charge', 'mpp-session-open', 'mpp-session-reuse'] : [],
208
+ supportedRoutes: ['x402'],
209
+ unsupportedRoutes: ['mpp-charge', 'mpp-session-open', 'mpp-session-reuse'],
210
+ unsupportedReason: smartAccountReady
211
+ ? 'MPP charge and MPP session routes still require explicit Keypair signers in the current client stack.'
212
+ : null,
213
+ configuredMaxTransactionFeeStroops: config.x402.maxTransactionFeeStroops,
214
+ effectiveMaxTransactionFeeStroops: smartAccountEffectiveFeeCeiling,
215
+ feeFloorApplied: smartAccountFeeFloorWasApplied,
216
+ preflightFailures: smartAccountPreflightFailures,
217
+ coverageMessage: smartAccountReady
218
+ ? 'Smart-account execution is intentionally limited to x402. All MPP routes remain keypair-backed.'
219
+ : 'Smart-account execution is not configured.',
220
+ message: smartAccountActive
221
+ ? 'Smart-account execution is enabled for x402 only, with guarded fallback to the stable keypair path if the delegated route becomes unavailable.'
222
+ : smartAccountReady
223
+ ? 'Smart-account identifiers are configured, but x402 stays on the stable keypair path until the delegated flow is fully demo-ready.'
224
+ : 'Smart account execution is not configured yet.',
225
+ operatorNotes: smartAccountOperatorNotes,
226
+ },
227
+ feeSponsorship: {
228
+ enabled: config.mpp.feeSponsorship.chargeEnabled || config.mpp.feeSponsorship.sessionEnabled,
229
+ available: (config.mpp.feeSponsorship.chargeEnabled || config.mpp.feeSponsorship.sessionEnabled) &&
230
+ Boolean(feeSponsorKeypair),
231
+ mppChargeEnabled: config.mpp.feeSponsorship.chargeEnabled,
232
+ mppSessionEnabled: config.mpp.feeSponsorship.sessionEnabled,
233
+ sponsorPublicKey: feeSponsorKeypair?.publicKey() ?? null,
234
+ feeBumpPublicKey: feeBumpKeypair?.publicKey() ?? null,
235
+ message: feeSponsorKeypair
236
+ ? config.mpp.feeSponsorship.chargeEnabled && config.mpp.feeSponsorship.sessionEnabled
237
+ ? 'MPP charge and session services can sponsor gas for agent-side flows.'
238
+ : config.mpp.feeSponsorship.sessionEnabled
239
+ ? 'MPP session services can sponsor gas for agent-side flows; charge stays agent-funded.'
240
+ : config.mpp.feeSponsorship.chargeEnabled
241
+ ? 'MPP charge services can sponsor gas for agent-side flows; sessions stay agent-funded.'
242
+ : 'Fee sponsorship is disabled; the agent pays its own network fees.'
243
+ : 'Fee sponsorship is disabled; the agent pays its own network fees.',
244
+ },
245
+ missingSecrets,
246
+ message: missingSecrets.length === 0
247
+ ? 'xMPP has the core Stellar testnet secrets required to continue live payment integration.'
248
+ : 'xMPP is still missing the three core Stellar testnet secrets required for live payment execution.',
249
+ };
250
+ }
package/package.json ADDED
@@ -0,0 +1,69 @@
1
+ {
2
+ "name": "@vinaystwt/xmpp-mcp",
3
+ "version": "0.1.0",
4
+ "description": "Installable xMPP MCP server exposing paid-fetch, route explainability, receipts, and operator tools.",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "main": "dist/apps/mcp-server/src/server.js",
8
+ "types": "dist/apps/mcp-server/src/server.d.ts",
9
+ "files": [
10
+ "dist",
11
+ "README.md",
12
+ "LICENSE"
13
+ ],
14
+ "homepage": "https://github.com/Vinaystwt/xMPP#readme",
15
+ "repository": {
16
+ "type": "git",
17
+ "url": "git+https://github.com/Vinaystwt/xMPP.git",
18
+ "directory": "apps/mcp-server"
19
+ },
20
+ "bugs": {
21
+ "url": "https://github.com/Vinaystwt/xMPP/issues"
22
+ },
23
+ "keywords": [
24
+ "xmpp",
25
+ "mcp",
26
+ "stellar",
27
+ "x402",
28
+ "mpp",
29
+ "agents"
30
+ ],
31
+ "exports": {
32
+ ".": {
33
+ "types": "./dist/apps/mcp-server/src/server.d.ts",
34
+ "import": "./dist/apps/mcp-server/src/server.js",
35
+ "default": "./dist/apps/mcp-server/src/server.js"
36
+ },
37
+ "./cli": {
38
+ "types": "./dist/apps/mcp-server/src/index.d.ts",
39
+ "import": "./dist/apps/mcp-server/src/index.js",
40
+ "default": "./dist/apps/mcp-server/src/index.js"
41
+ }
42
+ },
43
+ "bin": {
44
+ "xmpp-mcp": "dist/apps/mcp-server/src/index.js"
45
+ },
46
+ "publishConfig": {
47
+ "access": "public"
48
+ },
49
+ "scripts": {
50
+ "dev": "node --import tsx src/index.ts",
51
+ "build": "tsc -p tsconfig.json",
52
+ "lint": "eslint src",
53
+ "typecheck": "tsc -p tsconfig.json --noEmit",
54
+ "test": "vitest run --passWithNoTests"
55
+ },
56
+ "dependencies": {
57
+ "@modelcontextprotocol/sdk": "^1.27.1",
58
+ "@vinaystwt/xmpp-config": "0.1.0",
59
+ "@vinaystwt/xmpp-contract-runtime": "0.1.0",
60
+ "@vinaystwt/xmpp-http-interceptor": "0.1.0",
61
+ "@vinaystwt/xmpp-router": "0.1.0",
62
+ "@vinaystwt/xmpp-types": "0.1.0",
63
+ "@vinaystwt/xmpp-wallet": "0.1.0",
64
+ "zod": "^4.3.6"
65
+ },
66
+ "devDependencies": {
67
+ "tsx": "^4.21.0"
68
+ }
69
+ }