@agentcash/router 1.2.0 → 1.2.1

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.cjs CHANGED
@@ -626,6 +626,8 @@ function resolveMaxPrice(pricing) {
626
626
 
627
627
  // src/orchestrate.ts
628
628
  var import_mppx2 = require("mppx");
629
+ var import_actions = require("viem/actions");
630
+ var import_tempo = require("viem/tempo");
629
631
  var import_viem2 = require("viem");
630
632
 
631
633
  // src/protocols/x402.ts
@@ -1364,6 +1366,122 @@ function createRequestHandler(routeEntry, handler, deps) {
1364
1366
  console.error(`[router] ${routeEntry.key}: ${reason}`);
1365
1367
  return fail(500, reason, meta, pluginCtx, body.data);
1366
1368
  }
1369
+ const mppCredential = import_mppx2.Credential.fromRequest(request);
1370
+ const rawSource = mppCredential?.source ?? "";
1371
+ const didParts = rawSource.split(":");
1372
+ const lastPart = didParts[didParts.length - 1];
1373
+ const wallet = normalizeWalletAddress((0, import_viem2.isAddress)(lastPart) ? (0, import_viem2.getAddress)(lastPart) : rawSource);
1374
+ const payloadType = mppCredential?.payload?.type;
1375
+ if (payloadType === "transaction" && deps.tempoClient) {
1376
+ try {
1377
+ const serializedTx = mppCredential.payload.signature;
1378
+ const transaction = import_tempo.Transaction.deserialize(serializedTx);
1379
+ await (0, import_actions.call)(deps.tempoClient, {
1380
+ ...transaction,
1381
+ account: transaction.from,
1382
+ calls: transaction.calls ?? []
1383
+ });
1384
+ } catch (err) {
1385
+ const message = err instanceof Error ? err.message : String(err);
1386
+ console.warn(`[router] ${routeEntry.key}: MPP simulation failed \u2014 ${message}`);
1387
+ firePluginHook(deps.plugin, "onAlert", pluginCtx, {
1388
+ level: "warn",
1389
+ message: `MPP simulation failed: ${message}`,
1390
+ route: routeEntry.key
1391
+ });
1392
+ return await build402(request, routeEntry, deps, meta, pluginCtx, body.data);
1393
+ }
1394
+ pluginCtx.setVerifiedWallet(wallet);
1395
+ firePluginHook(deps.plugin, "onPaymentVerified", pluginCtx, {
1396
+ protocol: "mpp",
1397
+ payer: wallet,
1398
+ amount: price,
1399
+ network: "tempo:4217"
1400
+ });
1401
+ const { response: response2, rawResult: rawResult2 } = await invoke(
1402
+ request,
1403
+ meta,
1404
+ pluginCtx,
1405
+ wallet,
1406
+ account,
1407
+ body.data
1408
+ );
1409
+ if (response2.status < 400) {
1410
+ let mppResult2;
1411
+ try {
1412
+ mppResult2 = await deps.mppx.charge({ amount: price })(request);
1413
+ } catch (err) {
1414
+ const message = err instanceof Error ? err.message : String(err);
1415
+ console.error(
1416
+ `[router] ${routeEntry.key}: MPP broadcast failed after handler: ${message}`
1417
+ );
1418
+ firePluginHook(deps.plugin, "onAlert", pluginCtx, {
1419
+ level: "critical",
1420
+ message: `MPP broadcast failed after handler: ${message}`,
1421
+ route: routeEntry.key
1422
+ });
1423
+ return fail(
1424
+ 500,
1425
+ `MPP payment processing failed: ${message}`,
1426
+ meta,
1427
+ pluginCtx,
1428
+ body.data
1429
+ );
1430
+ }
1431
+ if (mppResult2.status === 402) {
1432
+ let rejectReason = "";
1433
+ try {
1434
+ const problemBody = await mppResult2.challenge.clone().text();
1435
+ if (problemBody) {
1436
+ const problem = JSON.parse(problemBody);
1437
+ rejectReason = problem.detail || problem.title || "";
1438
+ }
1439
+ } catch {
1440
+ }
1441
+ const detail = rejectReason || "transaction reverted on-chain after handler execution";
1442
+ console.error(
1443
+ `[router] ${routeEntry.key}: MPP payment failed after handler \u2014 ${detail}`
1444
+ );
1445
+ firePluginHook(deps.plugin, "onAlert", pluginCtx, {
1446
+ level: "critical",
1447
+ message: `MPP payment failed after handler: ${detail}`,
1448
+ route: routeEntry.key
1449
+ });
1450
+ return fail(500, `MPP payment failed: ${detail}`, meta, pluginCtx, body.data);
1451
+ }
1452
+ const receiptResponse = mppResult2.withReceipt(response2);
1453
+ receiptResponse.headers.set("Cache-Control", "private");
1454
+ let txHash2 = "";
1455
+ const receiptHeader2 = receiptResponse.headers.get("Payment-Receipt");
1456
+ if (receiptHeader2) {
1457
+ try {
1458
+ txHash2 = import_mppx2.Receipt.deserialize(receiptHeader2).reference;
1459
+ } catch {
1460
+ }
1461
+ }
1462
+ if (routeEntry.siwxEnabled) {
1463
+ try {
1464
+ await deps.entitlementStore.grant(routeEntry.key, wallet);
1465
+ } catch (error) {
1466
+ firePluginHook(deps.plugin, "onAlert", pluginCtx, {
1467
+ level: "warn",
1468
+ message: `Entitlement grant failed: ${error instanceof Error ? error.message : String(error)}`,
1469
+ route: routeEntry.key
1470
+ });
1471
+ }
1472
+ }
1473
+ firePluginHook(deps.plugin, "onPaymentSettled", pluginCtx, {
1474
+ protocol: "mpp",
1475
+ payer: wallet,
1476
+ transaction: txHash2,
1477
+ network: "tempo:4217"
1478
+ });
1479
+ finalize(receiptResponse, rawResult2, meta, pluginCtx, body.data);
1480
+ return receiptResponse;
1481
+ }
1482
+ finalize(response2, rawResult2, meta, pluginCtx, body.data);
1483
+ return response2;
1484
+ }
1367
1485
  let mppResult;
1368
1486
  try {
1369
1487
  mppResult = await deps.mppx.charge({ amount: price })(request);
@@ -1396,11 +1514,16 @@ function createRequestHandler(routeEntry, handler, deps) {
1396
1514
  });
1397
1515
  return await build402(request, routeEntry, deps, meta, pluginCtx, body.data);
1398
1516
  }
1399
- const credential = import_mppx2.Credential.fromRequest(request);
1400
- const rawSource = credential?.source ?? "";
1401
- const didParts = rawSource.split(":");
1402
- const lastPart = didParts[didParts.length - 1];
1403
- const wallet = normalizeWalletAddress((0, import_viem2.isAddress)(lastPart) ? (0, import_viem2.getAddress)(lastPart) : rawSource);
1517
+ let txHash = "";
1518
+ const receiptHeader = mppResult.withReceipt(new Response()).headers.get(
1519
+ "Payment-Receipt"
1520
+ );
1521
+ if (receiptHeader) {
1522
+ try {
1523
+ txHash = import_mppx2.Receipt.deserialize(receiptHeader).reference;
1524
+ } catch {
1525
+ }
1526
+ }
1404
1527
  pluginCtx.setVerifiedWallet(wallet);
1405
1528
  firePluginHook(deps.plugin, "onPaymentVerified", pluginCtx, {
1406
1529
  protocol: "mpp",
@@ -1430,6 +1553,12 @@ function createRequestHandler(routeEntry, handler, deps) {
1430
1553
  }
1431
1554
  const receiptResponse = mppResult.withReceipt(response);
1432
1555
  receiptResponse.headers.set("Cache-Control", "private");
1556
+ firePluginHook(deps.plugin, "onPaymentSettled", pluginCtx, {
1557
+ protocol: "mpp",
1558
+ payer: wallet,
1559
+ transaction: txHash,
1560
+ network: "tempo:4217"
1561
+ });
1433
1562
  finalize(receiptResponse, rawResult, meta, pluginCtx, body.data);
1434
1563
  return receiptResponse;
1435
1564
  }
@@ -2291,7 +2420,8 @@ function createRouter(config) {
2291
2420
  network,
2292
2421
  x402FacilitatorsByNetwork: void 0,
2293
2422
  x402Accepts,
2294
- mppx: null
2423
+ mppx: null,
2424
+ tempoClient: null
2295
2425
  };
2296
2426
  deps.initPromise = (async () => {
2297
2427
  if (x402ConfigError) {
@@ -2314,11 +2444,10 @@ function createRouter(config) {
2314
2444
  try {
2315
2445
  const { Mppx, tempo } = await import("mppx/server");
2316
2446
  const rpcUrl = config.mpp.rpcUrl ?? process.env.TEMPO_RPC_URL;
2317
- const getClient = async () => {
2318
- const { createClient, http } = await import("viem");
2319
- const { tempo: tempoChain } = await import("viem/chains");
2320
- return createClient({ chain: tempoChain, transport: http(rpcUrl) });
2321
- };
2447
+ const { createClient, http } = await import("viem");
2448
+ const { tempo: tempoChain } = await import("viem/chains");
2449
+ deps.tempoClient = createClient({ chain: tempoChain, transport: http(rpcUrl) });
2450
+ const getClient = async () => deps.tempoClient;
2322
2451
  let feePayerAccount;
2323
2452
  if (config.mpp.feePayerKey) {
2324
2453
  const { Account } = await import("viem/tempo");
package/dist/index.d.cts CHANGED
@@ -2,6 +2,7 @@ import { FacilitatorConfig } from '@x402/core/http';
2
2
  import { NextRequest, NextResponse } from 'next/server';
3
3
  import { ZodType } from 'zod';
4
4
  import { PaymentRequirements, PaymentRequired, SettleResponse, Network } from '@x402/core/types';
5
+ import * as viem from 'viem';
5
6
  export { S as SIWX_ERROR_MESSAGES, a as SiwxErrorCode } from './siwx-BMlja_nt.cjs';
6
7
 
7
8
  interface EntitlementStore {
@@ -423,6 +424,7 @@ interface OrchestrateDeps {
423
424
  withReceipt: (response: Response) => Response;
424
425
  }>;
425
426
  } | null;
427
+ tempoClient?: viem.Client | null;
426
428
  }
427
429
 
428
430
  type True = true;
package/dist/index.d.ts CHANGED
@@ -2,6 +2,7 @@ import { FacilitatorConfig } from '@x402/core/http';
2
2
  import { NextRequest, NextResponse } from 'next/server';
3
3
  import { ZodType } from 'zod';
4
4
  import { PaymentRequirements, PaymentRequired, SettleResponse, Network } from '@x402/core/types';
5
+ import * as viem from 'viem';
5
6
  export { S as SIWX_ERROR_MESSAGES, a as SiwxErrorCode } from './siwx-BMlja_nt.js';
6
7
 
7
8
  interface EntitlementStore {
@@ -423,6 +424,7 @@ interface OrchestrateDeps {
423
424
  withReceipt: (response: Response) => Response;
424
425
  }>;
425
426
  } | null;
427
+ tempoClient?: viem.Client | null;
426
428
  }
427
429
 
428
430
  type True = true;
package/dist/index.js CHANGED
@@ -586,7 +586,9 @@ function resolveMaxPrice(pricing) {
586
586
  }
587
587
 
588
588
  // src/orchestrate.ts
589
- import { Credential as Credential2 } from "mppx";
589
+ import { Credential as Credential2, Receipt } from "mppx";
590
+ import { call as viemCall } from "viem/actions";
591
+ import { Transaction as TempoTransaction } from "viem/tempo";
590
592
  import { isAddress as isAddress2, getAddress as getAddress2 } from "viem";
591
593
 
592
594
  // src/protocols/x402.ts
@@ -1325,6 +1327,122 @@ function createRequestHandler(routeEntry, handler, deps) {
1325
1327
  console.error(`[router] ${routeEntry.key}: ${reason}`);
1326
1328
  return fail(500, reason, meta, pluginCtx, body.data);
1327
1329
  }
1330
+ const mppCredential = Credential2.fromRequest(request);
1331
+ const rawSource = mppCredential?.source ?? "";
1332
+ const didParts = rawSource.split(":");
1333
+ const lastPart = didParts[didParts.length - 1];
1334
+ const wallet = normalizeWalletAddress(isAddress2(lastPart) ? getAddress2(lastPart) : rawSource);
1335
+ const payloadType = mppCredential?.payload?.type;
1336
+ if (payloadType === "transaction" && deps.tempoClient) {
1337
+ try {
1338
+ const serializedTx = mppCredential.payload.signature;
1339
+ const transaction = TempoTransaction.deserialize(serializedTx);
1340
+ await viemCall(deps.tempoClient, {
1341
+ ...transaction,
1342
+ account: transaction.from,
1343
+ calls: transaction.calls ?? []
1344
+ });
1345
+ } catch (err) {
1346
+ const message = err instanceof Error ? err.message : String(err);
1347
+ console.warn(`[router] ${routeEntry.key}: MPP simulation failed \u2014 ${message}`);
1348
+ firePluginHook(deps.plugin, "onAlert", pluginCtx, {
1349
+ level: "warn",
1350
+ message: `MPP simulation failed: ${message}`,
1351
+ route: routeEntry.key
1352
+ });
1353
+ return await build402(request, routeEntry, deps, meta, pluginCtx, body.data);
1354
+ }
1355
+ pluginCtx.setVerifiedWallet(wallet);
1356
+ firePluginHook(deps.plugin, "onPaymentVerified", pluginCtx, {
1357
+ protocol: "mpp",
1358
+ payer: wallet,
1359
+ amount: price,
1360
+ network: "tempo:4217"
1361
+ });
1362
+ const { response: response2, rawResult: rawResult2 } = await invoke(
1363
+ request,
1364
+ meta,
1365
+ pluginCtx,
1366
+ wallet,
1367
+ account,
1368
+ body.data
1369
+ );
1370
+ if (response2.status < 400) {
1371
+ let mppResult2;
1372
+ try {
1373
+ mppResult2 = await deps.mppx.charge({ amount: price })(request);
1374
+ } catch (err) {
1375
+ const message = err instanceof Error ? err.message : String(err);
1376
+ console.error(
1377
+ `[router] ${routeEntry.key}: MPP broadcast failed after handler: ${message}`
1378
+ );
1379
+ firePluginHook(deps.plugin, "onAlert", pluginCtx, {
1380
+ level: "critical",
1381
+ message: `MPP broadcast failed after handler: ${message}`,
1382
+ route: routeEntry.key
1383
+ });
1384
+ return fail(
1385
+ 500,
1386
+ `MPP payment processing failed: ${message}`,
1387
+ meta,
1388
+ pluginCtx,
1389
+ body.data
1390
+ );
1391
+ }
1392
+ if (mppResult2.status === 402) {
1393
+ let rejectReason = "";
1394
+ try {
1395
+ const problemBody = await mppResult2.challenge.clone().text();
1396
+ if (problemBody) {
1397
+ const problem = JSON.parse(problemBody);
1398
+ rejectReason = problem.detail || problem.title || "";
1399
+ }
1400
+ } catch {
1401
+ }
1402
+ const detail = rejectReason || "transaction reverted on-chain after handler execution";
1403
+ console.error(
1404
+ `[router] ${routeEntry.key}: MPP payment failed after handler \u2014 ${detail}`
1405
+ );
1406
+ firePluginHook(deps.plugin, "onAlert", pluginCtx, {
1407
+ level: "critical",
1408
+ message: `MPP payment failed after handler: ${detail}`,
1409
+ route: routeEntry.key
1410
+ });
1411
+ return fail(500, `MPP payment failed: ${detail}`, meta, pluginCtx, body.data);
1412
+ }
1413
+ const receiptResponse = mppResult2.withReceipt(response2);
1414
+ receiptResponse.headers.set("Cache-Control", "private");
1415
+ let txHash2 = "";
1416
+ const receiptHeader2 = receiptResponse.headers.get("Payment-Receipt");
1417
+ if (receiptHeader2) {
1418
+ try {
1419
+ txHash2 = Receipt.deserialize(receiptHeader2).reference;
1420
+ } catch {
1421
+ }
1422
+ }
1423
+ if (routeEntry.siwxEnabled) {
1424
+ try {
1425
+ await deps.entitlementStore.grant(routeEntry.key, wallet);
1426
+ } catch (error) {
1427
+ firePluginHook(deps.plugin, "onAlert", pluginCtx, {
1428
+ level: "warn",
1429
+ message: `Entitlement grant failed: ${error instanceof Error ? error.message : String(error)}`,
1430
+ route: routeEntry.key
1431
+ });
1432
+ }
1433
+ }
1434
+ firePluginHook(deps.plugin, "onPaymentSettled", pluginCtx, {
1435
+ protocol: "mpp",
1436
+ payer: wallet,
1437
+ transaction: txHash2,
1438
+ network: "tempo:4217"
1439
+ });
1440
+ finalize(receiptResponse, rawResult2, meta, pluginCtx, body.data);
1441
+ return receiptResponse;
1442
+ }
1443
+ finalize(response2, rawResult2, meta, pluginCtx, body.data);
1444
+ return response2;
1445
+ }
1328
1446
  let mppResult;
1329
1447
  try {
1330
1448
  mppResult = await deps.mppx.charge({ amount: price })(request);
@@ -1357,11 +1475,16 @@ function createRequestHandler(routeEntry, handler, deps) {
1357
1475
  });
1358
1476
  return await build402(request, routeEntry, deps, meta, pluginCtx, body.data);
1359
1477
  }
1360
- const credential = Credential2.fromRequest(request);
1361
- const rawSource = credential?.source ?? "";
1362
- const didParts = rawSource.split(":");
1363
- const lastPart = didParts[didParts.length - 1];
1364
- const wallet = normalizeWalletAddress(isAddress2(lastPart) ? getAddress2(lastPart) : rawSource);
1478
+ let txHash = "";
1479
+ const receiptHeader = mppResult.withReceipt(new Response()).headers.get(
1480
+ "Payment-Receipt"
1481
+ );
1482
+ if (receiptHeader) {
1483
+ try {
1484
+ txHash = Receipt.deserialize(receiptHeader).reference;
1485
+ } catch {
1486
+ }
1487
+ }
1365
1488
  pluginCtx.setVerifiedWallet(wallet);
1366
1489
  firePluginHook(deps.plugin, "onPaymentVerified", pluginCtx, {
1367
1490
  protocol: "mpp",
@@ -1391,6 +1514,12 @@ function createRequestHandler(routeEntry, handler, deps) {
1391
1514
  }
1392
1515
  const receiptResponse = mppResult.withReceipt(response);
1393
1516
  receiptResponse.headers.set("Cache-Control", "private");
1517
+ firePluginHook(deps.plugin, "onPaymentSettled", pluginCtx, {
1518
+ protocol: "mpp",
1519
+ payer: wallet,
1520
+ transaction: txHash,
1521
+ network: "tempo:4217"
1522
+ });
1394
1523
  finalize(receiptResponse, rawResult, meta, pluginCtx, body.data);
1395
1524
  return receiptResponse;
1396
1525
  }
@@ -2252,7 +2381,8 @@ function createRouter(config) {
2252
2381
  network,
2253
2382
  x402FacilitatorsByNetwork: void 0,
2254
2383
  x402Accepts,
2255
- mppx: null
2384
+ mppx: null,
2385
+ tempoClient: null
2256
2386
  };
2257
2387
  deps.initPromise = (async () => {
2258
2388
  if (x402ConfigError) {
@@ -2275,11 +2405,10 @@ function createRouter(config) {
2275
2405
  try {
2276
2406
  const { Mppx, tempo } = await import("mppx/server");
2277
2407
  const rpcUrl = config.mpp.rpcUrl ?? process.env.TEMPO_RPC_URL;
2278
- const getClient = async () => {
2279
- const { createClient, http } = await import("viem");
2280
- const { tempo: tempoChain } = await import("viem/chains");
2281
- return createClient({ chain: tempoChain, transport: http(rpcUrl) });
2282
- };
2408
+ const { createClient, http } = await import("viem");
2409
+ const { tempo: tempoChain } = await import("viem/chains");
2410
+ deps.tempoClient = createClient({ chain: tempoChain, transport: http(rpcUrl) });
2411
+ const getClient = async () => deps.tempoClient;
2283
2412
  let feePayerAccount;
2284
2413
  if (config.mpp.feePayerKey) {
2285
2414
  const { Account } = await import("viem/tempo");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agentcash/router",
3
- "version": "1.2.0",
3
+ "version": "1.2.1",
4
4
  "description": "Unified route builder for Next.js App Router APIs with x402, MPP, SIWX, and API key auth",
5
5
  "type": "module",
6
6
  "exports": {