@relai-fi/x402 0.6.5 → 0.6.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.
Files changed (78) hide show
  1. package/README.md +251 -0
  2. package/dist/bridge.cjs +109 -0
  3. package/dist/bridge.cjs.map +1 -0
  4. package/dist/bridge.d.cts +78 -0
  5. package/dist/bridge.d.ts +78 -0
  6. package/dist/bridge.js +80 -0
  7. package/dist/bridge.js.map +1 -0
  8. package/dist/client.cjs +131 -1
  9. package/dist/client.cjs.map +1 -1
  10. package/dist/client.d.cts +13 -1
  11. package/dist/client.d.ts +13 -1
  12. package/dist/client.js +131 -1
  13. package/dist/client.js.map +1 -1
  14. package/dist/index.cjs +586 -105
  15. package/dist/index.cjs.map +1 -1
  16. package/dist/index.d.cts +291 -30
  17. package/dist/index.d.ts +291 -30
  18. package/dist/index.js +578 -105
  19. package/dist/index.js.map +1 -1
  20. package/dist/mpp/bridge-client.cjs +23922 -0
  21. package/dist/mpp/bridge-client.cjs.map +1 -0
  22. package/dist/mpp/bridge-client.d.cts +58 -0
  23. package/dist/mpp/bridge-client.d.ts +58 -0
  24. package/dist/mpp/bridge-client.js +23892 -0
  25. package/dist/mpp/bridge-client.js.map +1 -0
  26. package/dist/mpp/bridge-method.cjs +13202 -0
  27. package/dist/mpp/bridge-method.cjs.map +1 -0
  28. package/dist/mpp/bridge-method.d.cts +69 -0
  29. package/dist/mpp/bridge-method.d.ts +69 -0
  30. package/dist/mpp/bridge-method.js +13181 -0
  31. package/dist/mpp/bridge-method.js.map +1 -0
  32. package/dist/mpp/bridge-server.cjs +13887 -0
  33. package/dist/mpp/bridge-server.cjs.map +1 -0
  34. package/dist/mpp/bridge-server.d.cts +62 -0
  35. package/dist/mpp/bridge-server.d.ts +62 -0
  36. package/dist/mpp/bridge-server.js +13866 -0
  37. package/dist/mpp/bridge-server.js.map +1 -0
  38. package/dist/mpp/evm-server.cjs +49 -33
  39. package/dist/mpp/evm-server.cjs.map +1 -1
  40. package/dist/mpp/evm-server.js +49 -33
  41. package/dist/mpp/evm-server.js.map +1 -1
  42. package/dist/mpp/verify-erc20.cjs +71 -0
  43. package/dist/mpp/verify-erc20.cjs.map +1 -0
  44. package/dist/mpp/verify-erc20.d.cts +27 -0
  45. package/dist/mpp/verify-erc20.d.ts +27 -0
  46. package/dist/mpp/verify-erc20.js +46 -0
  47. package/dist/mpp/verify-erc20.js.map +1 -0
  48. package/dist/mpp/verify-spl.cjs +96 -0
  49. package/dist/mpp/verify-spl.cjs.map +1 -0
  50. package/dist/mpp/verify-spl.d.cts +30 -0
  51. package/dist/mpp/verify-spl.d.ts +30 -0
  52. package/dist/mpp/verify-spl.js +71 -0
  53. package/dist/mpp/verify-spl.js.map +1 -0
  54. package/dist/mpp/with-bridge.cjs +23956 -0
  55. package/dist/mpp/with-bridge.cjs.map +1 -0
  56. package/dist/mpp/with-bridge.d.cts +53 -0
  57. package/dist/mpp/with-bridge.d.ts +53 -0
  58. package/dist/mpp/with-bridge.js +23926 -0
  59. package/dist/mpp/with-bridge.js.map +1 -0
  60. package/dist/plugins.d.cts +2 -2
  61. package/dist/plugins.d.ts +2 -2
  62. package/dist/react/index.cjs +131 -1
  63. package/dist/react/index.cjs.map +1 -1
  64. package/dist/react/index.d.cts +1 -1
  65. package/dist/react/index.d.ts +1 -1
  66. package/dist/react/index.js +131 -1
  67. package/dist/react/index.js.map +1 -1
  68. package/dist/{server-DaySqG5H.d.ts → server-D9ZfrFFx.d.ts} +1 -1
  69. package/dist/{server-CBZ2RjEP.d.cts → server-DgMG2zhy.d.cts} +1 -1
  70. package/dist/server.cjs +6 -39
  71. package/dist/server.cjs.map +1 -1
  72. package/dist/server.d.cts +2 -2
  73. package/dist/server.d.ts +2 -2
  74. package/dist/server.js +6 -39
  75. package/dist/server.js.map +1 -1
  76. package/dist/{types-Y9ni5XwY.d.cts → types-DjEveKgt.d.cts} +1 -1
  77. package/dist/{types-Y9ni5XwY.d.ts → types-DjEveKgt.d.ts} +1 -1
  78. package/package.json +31 -1
@@ -1,3 +1,3 @@
1
- import './types-Y9ni5XwY.cjs';
2
- export { B as BridgePluginConfig, u as CircuitBreakerPluginConfig, C as CircuitState, j as FeedbackPluginConfig, m as FreeTierPlugin, F as FreeTierPluginConfig, n as FreeTierUsageExport, g as PluginContext, h as PluginResult, r as PreflightPluginConfig, x as RefundEvent, w as RefundPluginConfig, f as RelaiPlugin, i as ScorePluginConfig, p as ShieldPluginConfig, k as SolanaFeedbackPluginConfig, G as SolanaScorePluginConfig, l as bridge, v as circuitBreaker, A as feedback, o as freeTier, t as preflight, y as refund, z as score, q as shield, E as solanaFeedback, H as solanaScore } from './server-CBZ2RjEP.cjs';
1
+ import './types-DjEveKgt.cjs';
2
+ export { B as BridgePluginConfig, u as CircuitBreakerPluginConfig, C as CircuitState, j as FeedbackPluginConfig, m as FreeTierPlugin, F as FreeTierPluginConfig, n as FreeTierUsageExport, g as PluginContext, h as PluginResult, r as PreflightPluginConfig, x as RefundEvent, w as RefundPluginConfig, f as RelaiPlugin, i as ScorePluginConfig, p as ShieldPluginConfig, k as SolanaFeedbackPluginConfig, G as SolanaScorePluginConfig, l as bridge, v as circuitBreaker, A as feedback, o as freeTier, t as preflight, y as refund, z as score, q as shield, E as solanaFeedback, H as solanaScore } from './server-DgMG2zhy.cjs';
3
3
  export { RelayFeedbackConfig, submitRelayFeedback } from './relay-feedback.cjs';
package/dist/plugins.d.ts CHANGED
@@ -1,3 +1,3 @@
1
- import './types-Y9ni5XwY.js';
2
- export { B as BridgePluginConfig, u as CircuitBreakerPluginConfig, C as CircuitState, j as FeedbackPluginConfig, m as FreeTierPlugin, F as FreeTierPluginConfig, n as FreeTierUsageExport, g as PluginContext, h as PluginResult, r as PreflightPluginConfig, x as RefundEvent, w as RefundPluginConfig, f as RelaiPlugin, i as ScorePluginConfig, p as ShieldPluginConfig, k as SolanaFeedbackPluginConfig, G as SolanaScorePluginConfig, l as bridge, v as circuitBreaker, A as feedback, o as freeTier, t as preflight, y as refund, z as score, q as shield, E as solanaFeedback, H as solanaScore } from './server-DaySqG5H.js';
1
+ import './types-DjEveKgt.js';
2
+ export { B as BridgePluginConfig, u as CircuitBreakerPluginConfig, C as CircuitState, j as FeedbackPluginConfig, m as FreeTierPlugin, F as FreeTierPluginConfig, n as FreeTierUsageExport, g as PluginContext, h as PluginResult, r as PreflightPluginConfig, x as RefundEvent, w as RefundPluginConfig, f as RelaiPlugin, i as ScorePluginConfig, p as ShieldPluginConfig, k as SolanaFeedbackPluginConfig, G as SolanaScorePluginConfig, l as bridge, v as circuitBreaker, A as feedback, o as freeTier, t as preflight, y as refund, z as score, q as shield, E as solanaFeedback, H as solanaScore } from './server-D9ZfrFFx.js';
3
3
  export { RelayFeedbackConfig, submitRelayFeedback } from './relay-feedback.js';
@@ -268,6 +268,71 @@ function normalizeNetwork(network) {
268
268
  return null;
269
269
  }
270
270
 
271
+ // src/bridge.ts
272
+ var RELAI_API_BASE = "https://api.relai.fi";
273
+ var _cacheMap = /* @__PURE__ */ new Map();
274
+ var CACHE_TTL = 5 * 60 * 1e3;
275
+ async function getBridgeInfo(baseUrl = RELAI_API_BASE) {
276
+ const key = baseUrl.replace(/\/$/, "");
277
+ const now = Date.now();
278
+ const cached = _cacheMap.get(key);
279
+ if (cached && now - cached.time < CACHE_TTL) return cached.info;
280
+ const url = `${key}/bridge/info`;
281
+ const res = await fetch(url);
282
+ if (!res.ok) {
283
+ if (cached) return cached.info;
284
+ throw new Error(`[relai:bridge] Failed to fetch ${url}: ${res.status}`);
285
+ }
286
+ const data = await res.json();
287
+ const info = {
288
+ settleEndpoint: data.settleEndpoint,
289
+ supportedSourceChains: data.supportedSourceChains || [],
290
+ supportedSourceAssets: data.supportedSourceAssets || [],
291
+ payTo: data.payTo || {},
292
+ feePayerSvm: data.feePayerSvm ?? null,
293
+ feeBps: data.feeBps ?? 100,
294
+ paymentFacilitator: data.paymentFacilitator || "https://facilitator.x402.fi"
295
+ };
296
+ _cacheMap.set(key, { info, time: now });
297
+ return info;
298
+ }
299
+ async function settleBridge(settleEndpoint, body) {
300
+ const res = await fetch(settleEndpoint, {
301
+ method: "POST",
302
+ headers: { "Content-Type": "application/json" },
303
+ body: JSON.stringify(body)
304
+ });
305
+ if (!res.ok) {
306
+ const err = await res.json().catch(() => ({}));
307
+ throw new Error(`[relai:bridge] settle failed: ${err.error || res.status}${err.details ? " \u2014 " + err.details : ""}`);
308
+ }
309
+ return res.json();
310
+ }
311
+ function selectSourceChain(supportedChains, hasEvmWallet, hasSolanaWallet, preferredSourceChainId) {
312
+ if (preferredSourceChainId && hasEvmWallet) {
313
+ const preferred = `eip155:${preferredSourceChainId}`;
314
+ if (supportedChains.includes(preferred)) {
315
+ return { type: "evm", chain: preferred };
316
+ }
317
+ }
318
+ if (hasSolanaWallet) {
319
+ const sol = supportedChains.find((c) => c.startsWith("solana:"));
320
+ if (sol) return { type: "solana", chain: sol };
321
+ }
322
+ if (hasEvmWallet) {
323
+ for (const chain of supportedChains) {
324
+ if (chain.startsWith("eip155:")) {
325
+ return { type: "evm", chain };
326
+ }
327
+ }
328
+ }
329
+ return null;
330
+ }
331
+ function computeSourceAmount(targetAmount, feeBps) {
332
+ const fee = targetAmount * BigInt(feeBps) / 10000n;
333
+ return targetAmount + fee;
334
+ }
335
+
271
336
  // src/client.ts
272
337
  var PERMIT_NETWORKS = /* @__PURE__ */ new Set([]);
273
338
  var DEFAULT_EVM_RPC_URLS = {
@@ -294,7 +359,8 @@ function createX402Client(config) {
294
359
  integritas,
295
360
  verbose = false,
296
361
  defaultHeaders = {},
297
- mpp
362
+ mpp,
363
+ bridge: bridgeConfig
298
364
  } = config;
299
365
  const relayWsEnabled = relayWs?.enabled === true;
300
366
  const relayWsPreflightTimeoutMs = relayWs?.preflightTimeoutMs ?? 5e3;
@@ -1409,6 +1475,70 @@ function createX402Client(config) {
1409
1475
  headers: { ...requestHeaders, "X-PAYMENT": paymentHeader }
1410
1476
  });
1411
1477
  }
1478
+ if (bridgeConfig?.enabled) {
1479
+ log("No direct wallet match \u2014 attempting auto-bridge via RelAI API");
1480
+ try {
1481
+ const info = await getBridgeInfo(bridgeConfig.baseUrl);
1482
+ const targetAccept = accepts[0];
1483
+ const hasEvm = !!effectiveWallets.evm;
1484
+ const hasSol = !!hasSolanaWallet;
1485
+ const source = selectSourceChain(info.supportedSourceChains, hasEvm, hasSol);
1486
+ if (source) {
1487
+ const bridgePayTo = info.payTo[source.chain];
1488
+ if (bridgePayTo) {
1489
+ const targetAmount = targetAccept.amount || targetAccept.maxAmountRequired;
1490
+ const sourceAmount = computeSourceAmount(BigInt(targetAmount), info.feeBps).toString();
1491
+ const sourceChainIdx = info.supportedSourceChains.indexOf(source.chain);
1492
+ const sourceAsset = sourceChainIdx >= 0 && info.supportedSourceAssets[sourceChainIdx] || (source.type === "evm" ? info.supportedSourceAssets.find((a) => a.startsWith("0x")) || targetAccept.asset : info.supportedSourceAssets.find((a) => !a.startsWith("0x")) || "");
1493
+ let sourcePaymentHeader;
1494
+ const sourceAccept = {
1495
+ scheme: "exact",
1496
+ network: source.chain,
1497
+ asset: sourceAsset,
1498
+ payTo: bridgePayTo,
1499
+ amount: sourceAmount,
1500
+ extra: {
1501
+ ...targetAccept.extra || {},
1502
+ ...source.type === "solana" && info.feePayerSvm ? { feePayer: info.feePayerSvm } : {}
1503
+ }
1504
+ };
1505
+ if (source.type === "solana" && hasSolanaWallet) {
1506
+ sourcePaymentHeader = await buildSolanaPayment(sourceAccept, requirements, url);
1507
+ } else if (source.type === "evm") {
1508
+ const evmNetwork = normalizeNetwork(source.chain);
1509
+ const usePermit = evmNetwork && PERMIT_NETWORKS.has(evmNetwork);
1510
+ sourcePaymentHeader = usePermit ? await buildEvmPermitPayment(sourceAccept, requirements, url) : await buildEvmPayment(sourceAccept, requirements, url);
1511
+ } else {
1512
+ throw new Error(`[relai-x402] No wallet for source chain type: ${source.type}`);
1513
+ }
1514
+ const settleData = await settleBridge(info.settleEndpoint, {
1515
+ sourcePayment: sourcePaymentHeader,
1516
+ sourceChain: source.chain,
1517
+ targetAccept: {
1518
+ scheme: "exact",
1519
+ network: targetAccept.network,
1520
+ asset: targetAccept.asset,
1521
+ payTo: targetAccept.payTo,
1522
+ amount: targetAmount
1523
+ },
1524
+ requirements,
1525
+ resource: url,
1526
+ paymentFacilitator: info.paymentFacilitator
1527
+ });
1528
+ if (settleData.xPayment) {
1529
+ log(`Auto-bridge settled: target=${settleData.targetTxId}`);
1530
+ return fetch(input, {
1531
+ ...requestInitWithHeaders,
1532
+ headers: { ...requestHeaders, "X-PAYMENT": settleData.xPayment }
1533
+ });
1534
+ }
1535
+ throw new Error("[relai-x402] Bridge settle did not return xPayment");
1536
+ }
1537
+ }
1538
+ } catch (bridgeErr) {
1539
+ log(`Auto-bridge failed: ${bridgeErr instanceof Error ? bridgeErr.message : bridgeErr}`);
1540
+ }
1541
+ }
1412
1542
  throw new Error(buildNoWalletError(accepts, false));
1413
1543
  }
1414
1544
  const { accept, chain } = selected;