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