@dcentralab/d402-client 0.3.5 → 0.3.7

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.
package/dist/index.mjs CHANGED
@@ -297,6 +297,7 @@ __export(signer_exports, {
297
297
  async function signD402Payment(params) {
298
298
  const {
299
299
  operatorAccount,
300
+ walletClient,
300
301
  paymentRequirement,
301
302
  iatpWalletAddress,
302
303
  requestPath,
@@ -328,17 +329,29 @@ async function signD402Payment(params) {
328
329
  deadline: BigInt(validBefore),
329
330
  requestPath: finalRequestPath
330
331
  };
331
- if (!operatorAccount.signTypedData) {
332
- throw new Error("Account does not support signTypedData");
332
+ let signature;
333
+ if (walletClient) {
334
+ signature = await walletClient.signTypedData({
335
+ account: operatorAccount,
336
+ domain,
337
+ types: {
338
+ PullFundsForSettlement: EIP712_TYPES.PullFundsForSettlement
339
+ },
340
+ primaryType: "PullFundsForSettlement",
341
+ message
342
+ });
343
+ } else if (operatorAccount.signTypedData) {
344
+ signature = await operatorAccount.signTypedData({
345
+ domain,
346
+ types: {
347
+ PullFundsForSettlement: EIP712_TYPES.PullFundsForSettlement
348
+ },
349
+ primaryType: "PullFundsForSettlement",
350
+ message
351
+ });
352
+ } else {
353
+ throw new Error("Account does not support signTypedData. Pass walletClient for wagmi support.");
333
354
  }
334
- const signature = await operatorAccount.signTypedData({
335
- domain,
336
- types: {
337
- PullFundsForSettlement: EIP712_TYPES.PullFundsForSettlement
338
- },
339
- primaryType: "PullFundsForSettlement",
340
- message
341
- });
342
355
  const signedPayment = {
343
356
  d402Version,
344
357
  scheme: paymentRequirement.scheme,
@@ -405,6 +418,131 @@ var init_encoder = __esm({
405
418
  }
406
419
  });
407
420
 
421
+ // src/mcp/session.ts
422
+ var session_exports = {};
423
+ __export(session_exports, {
424
+ DEFAULT_JSONRPC_VERSION: () => DEFAULT_JSONRPC_VERSION,
425
+ DEFAULT_REQUEST_ID: () => DEFAULT_REQUEST_ID,
426
+ initMcpSession: () => initMcpSession
427
+ });
428
+ async function initMcpSession(endpoint) {
429
+ const response = await fetch(endpoint, {
430
+ method: "POST",
431
+ headers: {
432
+ "Content-Type": "application/json",
433
+ "Accept": "application/json, text/event-stream"
434
+ },
435
+ body: JSON.stringify({
436
+ jsonrpc: DEFAULT_JSONRPC_VERSION,
437
+ id: DEFAULT_REQUEST_ID,
438
+ method: "initialize",
439
+ params: {
440
+ protocolVersion: "2024-11-05",
441
+ capabilities: {},
442
+ clientInfo: { name: "d402-client", version: "1.0" }
443
+ }
444
+ })
445
+ });
446
+ if (!response.ok) {
447
+ throw new Error(`MCP init failed: ${response.status} ${response.statusText}`);
448
+ }
449
+ return response.headers.get("mcp-session-id");
450
+ }
451
+ var DEFAULT_REQUEST_ID, DEFAULT_JSONRPC_VERSION;
452
+ var init_session = __esm({
453
+ "src/mcp/session.ts"() {
454
+ DEFAULT_REQUEST_ID = "init-1";
455
+ DEFAULT_JSONRPC_VERSION = "2.0";
456
+ }
457
+ });
458
+
459
+ // src/mcp/payload.ts
460
+ var payload_exports = {};
461
+ __export(payload_exports, {
462
+ buildMcpHeaders: () => buildMcpHeaders,
463
+ buildToolCallPayload: () => buildToolCallPayload
464
+ });
465
+ function buildToolCallPayload(toolName, args, requestId = DEFAULT_REQUEST_ID) {
466
+ return {
467
+ jsonrpc: DEFAULT_JSONRPC_VERSION,
468
+ id: requestId,
469
+ method: "tools/call",
470
+ params: {
471
+ name: toolName,
472
+ arguments: args
473
+ }
474
+ };
475
+ }
476
+ function buildMcpHeaders(sessionId) {
477
+ const headers = {
478
+ "Content-Type": "application/json",
479
+ "Accept": "application/json, text/event-stream"
480
+ };
481
+ if (sessionId) {
482
+ headers["mcp-session-id"] = sessionId;
483
+ }
484
+ return headers;
485
+ }
486
+ var init_payload = __esm({
487
+ "src/mcp/payload.ts"() {
488
+ init_session();
489
+ }
490
+ });
491
+
492
+ // src/mcp/response.ts
493
+ var response_exports = {};
494
+ __export(response_exports, {
495
+ extractToolResult: () => extractToolResult,
496
+ parseMcpResponse: () => parseMcpResponse
497
+ });
498
+ async function parseMcpResponse(response) {
499
+ const contentType = response.headers.get("content-type") || "";
500
+ if (contentType.includes("text/event-stream")) {
501
+ return parseSSEResponse(await response.text());
502
+ } else {
503
+ return await response.json();
504
+ }
505
+ }
506
+ function parseSSEResponse(text) {
507
+ const lines = text.split("\n");
508
+ for (const line of lines) {
509
+ if (line.startsWith("data: ")) {
510
+ const jsonStr = line.substring(6);
511
+ try {
512
+ return JSON.parse(jsonStr);
513
+ } catch {
514
+ continue;
515
+ }
516
+ }
517
+ }
518
+ return {
519
+ id: "unknown",
520
+ result: { raw: text },
521
+ error: {
522
+ code: -32700,
523
+ message: "Could not parse SSE response",
524
+ data: text
525
+ }
526
+ };
527
+ }
528
+ function extractToolResult(response) {
529
+ if (response.error) {
530
+ throw new Error(`MCP error ${response.error.code}: ${response.error.message}`);
531
+ }
532
+ if (response.result && typeof response.result === "object") {
533
+ const result = response.result;
534
+ if (result.structuredContent) {
535
+ return result.structuredContent;
536
+ }
537
+ return result;
538
+ }
539
+ return response.result;
540
+ }
541
+ var init_response = __esm({
542
+ "src/mcp/response.ts"() {
543
+ }
544
+ });
545
+
408
546
  // src/payment/selector.ts
409
547
  init_errors();
410
548
  function selectPaymentRequirement(requirements, options = {}) {
@@ -5038,7 +5176,7 @@ function getContractConfig(contractName, network = "sepolia") {
5038
5176
 
5039
5177
  // src/wallet/creation.ts
5040
5178
  async function createIATPWallet(params) {
5041
- const { ownerAccount, network = "sepolia", rpcUrl } = params;
5179
+ const { ownerAccount, walletClient: externalWalletClient, network = "sepolia", rpcUrl } = params;
5042
5180
  const factoryConfig = getContractConfig("IATPWalletFactory" /* IATP_WALLET_FACTORY */, network);
5043
5181
  if (!factoryConfig) {
5044
5182
  throw new Error(`IATPWalletFactory not found for network: ${network}`);
@@ -5050,7 +5188,7 @@ async function createIATPWallet(params) {
5050
5188
  chain,
5051
5189
  transport
5052
5190
  });
5053
- const walletClient = createWalletClient({
5191
+ const walletClient = externalWalletClient ?? createWalletClient({
5054
5192
  account: ownerAccount,
5055
5193
  chain,
5056
5194
  transport
@@ -5059,14 +5197,14 @@ async function createIATPWallet(params) {
5059
5197
  if (balance === 0n) {
5060
5198
  throw new Error("Owner has no ETH for gas. Please fund the account.");
5061
5199
  }
5062
- const { request } = await publicClient.simulateContract({
5200
+ const hash = await walletClient.writeContract({
5063
5201
  account: ownerAccount,
5064
5202
  address: factoryConfig.address,
5065
5203
  abi: factoryConfig.abi,
5066
5204
  functionName: "createWallet",
5067
- args: [operatorAddress, 0, "", ""]
5205
+ args: [operatorAddress, 0, "", ""],
5206
+ chain
5068
5207
  });
5069
- const hash = await walletClient.writeContract(request);
5070
5208
  const receipt = await publicClient.waitForTransactionReceipt({
5071
5209
  hash,
5072
5210
  timeout: 3e5
@@ -5244,6 +5382,7 @@ var D402Client = class {
5244
5382
  */
5245
5383
  constructor(config) {
5246
5384
  this.operatorAccount = config.operatorAccount;
5385
+ this.walletClient = config.walletClient;
5247
5386
  this.iatpWalletAddress = config.iatpWalletAddress;
5248
5387
  this.maxValue = config.maxValue;
5249
5388
  this.networkFilter = config.networkFilter;
@@ -5404,6 +5543,7 @@ var D402Client = class {
5404
5543
  const selectedRequirement = this.selectPaymentRequirement(requirements);
5405
5544
  const signedPayment = await signD402Payment2({
5406
5545
  operatorAccount: this.operatorAccount,
5546
+ walletClient: this.walletClient,
5407
5547
  paymentRequirement: selectedRequirement,
5408
5548
  iatpWalletAddress: this.iatpWalletAddress
5409
5549
  });
@@ -5421,6 +5561,63 @@ var D402Client = class {
5421
5561
  throw error;
5422
5562
  }
5423
5563
  }
5564
+ // ========================================================================
5565
+ // MCP Methods - Simplified API for MCP tool calls
5566
+ // ========================================================================
5567
+ /**
5568
+ * Call an MCP tool with automatic session initialization and payment handling.
5569
+ *
5570
+ * This is the simplest way to call an MCP tool. It handles:
5571
+ * - MCP session initialization
5572
+ * - JSON-RPC payload construction
5573
+ * - HTTP 402 payment flow
5574
+ * - SSE/JSON response parsing
5575
+ *
5576
+ * @param endpoint - MCP server endpoint URL
5577
+ * @param toolName - Name of the tool to call
5578
+ * @param input - Tool arguments
5579
+ * @param options - Optional configuration
5580
+ * @returns The tool's result data
5581
+ *
5582
+ * @example
5583
+ * ```ts
5584
+ * const client = new D402Client({
5585
+ * operatorAccount: walletClient.account,
5586
+ * walletClient,
5587
+ * iatpWalletAddress,
5588
+ * })
5589
+ *
5590
+ * // Simple one-liner!
5591
+ * const result = await client.mcpCall(
5592
+ * 'https://my-mcp.example.com/mcp',
5593
+ * 'google_search',
5594
+ * { q: 'test search' }
5595
+ * )
5596
+ *
5597
+ * console.log(result) // { searchResults: [...] }
5598
+ * ```
5599
+ */
5600
+ async mcpCall(endpoint, toolName, input, options) {
5601
+ const { initMcpSession: initMcpSession2 } = await Promise.resolve().then(() => (init_session(), session_exports));
5602
+ const { buildToolCallPayload: buildToolCallPayload2, buildMcpHeaders: buildMcpHeaders2 } = await Promise.resolve().then(() => (init_payload(), payload_exports));
5603
+ const { parseMcpResponse: parseMcpResponse2, extractToolResult: extractToolResult2 } = await Promise.resolve().then(() => (init_response(), response_exports));
5604
+ let sessionId = null;
5605
+ if (!options?.skipInit) {
5606
+ try {
5607
+ sessionId = await initMcpSession2(endpoint);
5608
+ } catch {
5609
+ }
5610
+ }
5611
+ const headers = buildMcpHeaders2(sessionId);
5612
+ const payload = buildToolCallPayload2(toolName, input, options?.requestId);
5613
+ const response = await this.fetch(endpoint, {
5614
+ method: "POST",
5615
+ headers,
5616
+ body: JSON.stringify(payload)
5617
+ });
5618
+ const parsed = await parseMcpResponse2(response);
5619
+ return extractToolResult2(parsed);
5620
+ }
5424
5621
  };
5425
5622
 
5426
5623
  // src/index.ts
@@ -5428,6 +5625,11 @@ init_signer();
5428
5625
  init_parser();
5429
5626
  init_encoder();
5430
5627
 
5628
+ // src/mcp/index.ts
5629
+ init_session();
5630
+ init_payload();
5631
+ init_response();
5632
+
5431
5633
  // src/settlement/queries.ts
5432
5634
  async function getLockedBalanceForProvider(params) {
5433
5635
  const { publicClient, providerAddress, tokenAddress, network = "sepolia" } = params;
@@ -5500,6 +5702,6 @@ async function withdrawAllAvailableEpochs(params) {
5500
5702
  init_utils();
5501
5703
  init_errors();
5502
5704
 
5503
- export { ContractName, D402Client, Invalid402ResponseError, MissingRequestConfigError, PaymentAlreadyAttemptedError, PaymentAmountExceededError, PaymentError, PaymentVerificationError, UnsupportedNetworkError, UnsupportedSchemeError, createIATPWallet, createPaymentSelector, decodePayment, decodePaymentResponse, encodePayment, executeWithdrawal, findMatchingPaymentRequirement, formatMoney, generateNonce, getAvailableBalance, getChainId, getContractAbi, getContractAddress, getContractConfig, getCurrentTimestamp, getLockedBalanceForProvider, getUnlockedBalanceForProvider, getUsdcAddress, getWalletsByOwner, getWithdrawalRequest, isValidAddress, normalizeAddress, parseAllPaymentRequirements, parseMoney, parsePaymentRequirement, requestWithdrawal, selectPaymentRequirement, signD402Payment, sortPaymentRequirements, usdToUsdc, withdrawAllAvailableEpochs };
5705
+ export { ContractName, D402Client, Invalid402ResponseError, MissingRequestConfigError, PaymentAlreadyAttemptedError, PaymentAmountExceededError, PaymentError, PaymentVerificationError, UnsupportedNetworkError, UnsupportedSchemeError, buildMcpHeaders, buildToolCallPayload, createIATPWallet, createPaymentSelector, decodePayment, decodePaymentResponse, encodePayment, executeWithdrawal, extractToolResult, findMatchingPaymentRequirement, formatMoney, generateNonce, getAvailableBalance, getChainId, getContractAbi, getContractAddress, getContractConfig, getCurrentTimestamp, getLockedBalanceForProvider, getUnlockedBalanceForProvider, getUsdcAddress, getWalletsByOwner, getWithdrawalRequest, initMcpSession, isValidAddress, normalizeAddress, parseAllPaymentRequirements, parseMcpResponse, parseMoney, parsePaymentRequirement, requestWithdrawal, selectPaymentRequirement, signD402Payment, sortPaymentRequirements, usdToUsdc, withdrawAllAvailableEpochs };
5504
5706
  //# sourceMappingURL=index.mjs.map
5505
5707
  //# sourceMappingURL=index.mjs.map