@relai-fi/x402 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.
@@ -0,0 +1,171 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/server.ts
31
+ var server_exports = {};
32
+ __export(server_exports, {
33
+ Relai: () => Relai,
34
+ default: () => server_default
35
+ });
36
+ module.exports = __toCommonJS(server_exports);
37
+ var import_axios = __toESM(require("axios"), 1);
38
+
39
+ // src/types.ts
40
+ var RELAI_FACILITATOR_URL = "https://facilitator.x402.fi";
41
+ var NETWORK_CAIP2 = {
42
+ "solana": "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp",
43
+ "base": "eip155:8453",
44
+ "avalanche": "eip155:43114",
45
+ "skale-base": "eip155:1187947933"
46
+ };
47
+ var CAIP2_TO_NETWORK = Object.fromEntries(
48
+ Object.entries(NETWORK_CAIP2).map(([k, v]) => [v, k])
49
+ );
50
+ var USDC_ADDRESSES = {
51
+ "solana": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
52
+ "base": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
53
+ "avalanche": "0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E",
54
+ "skale-base": "0x85889c8c714505E0c94b30fcfcF64fE3Ac8FCb20"
55
+ };
56
+ var SOLANA_MAINNET_NETWORK = NETWORK_CAIP2["solana"];
57
+ var BASE_MAINNET_NETWORK = NETWORK_CAIP2["base"];
58
+ var USDC_SOLANA = USDC_ADDRESSES["solana"];
59
+ var USDC_BASE = USDC_ADDRESSES["base"];
60
+
61
+ // src/server.ts
62
+ var Relai = class {
63
+ constructor(config) {
64
+ this.config = {
65
+ network: "solana",
66
+ apiBaseUrl: "https://relai.fi/api",
67
+ facilitatorUrl: RELAI_FACILITATOR_URL,
68
+ ...config
69
+ };
70
+ if (!this.config.apiKey || typeof this.config.apiKey !== "string") {
71
+ throw new Error("[Relai] Missing required apiKey in configuration");
72
+ }
73
+ this.client = import_axios.default.create({
74
+ baseURL: this.config.apiBaseUrl,
75
+ timeout: 1e4,
76
+ headers: {
77
+ "Authorization": `Bearer ${this.config.apiKey}`,
78
+ "Content-Type": "application/json"
79
+ }
80
+ });
81
+ }
82
+ /**
83
+ * Express middleware to protect an endpoint with x402 micropayments.
84
+ * Returns a 402 with `accepts` for the configured network.
85
+ * Supports: Solana, Base, Avalanche, SKALE Base.
86
+ */
87
+ protect(options) {
88
+ return async (req, res, next) => {
89
+ try {
90
+ const resolvedPrice = typeof options.price === "function" ? await options.price(req) : options.price;
91
+ if (typeof resolvedPrice !== "number" || !isFinite(resolvedPrice) || resolvedPrice <= 0) {
92
+ return res.status(400).json({ error: "Invalid price configuration", code: "INVALID_PRICE" });
93
+ }
94
+ const paymentSignature = req.headers["x-payment-signature"] || req.headers["x-relai-payment"];
95
+ if (!paymentSignature) {
96
+ const network = this.config.network;
97
+ const caip2 = NETWORK_CAIP2[network] || NETWORK_CAIP2["solana"];
98
+ const asset = USDC_ADDRESSES[network] || USDC_ADDRESSES["solana"];
99
+ return res.status(402).json({
100
+ x402Version: 2,
101
+ error: "Payment required",
102
+ resource: {
103
+ url: `${req.protocol}://${req.get("host")}${req.originalUrl}`,
104
+ description: options.description || "API access",
105
+ mimeType: "application/json"
106
+ },
107
+ accepts: [{
108
+ scheme: "exact",
109
+ network: caip2,
110
+ maxAmountRequired: String(Math.floor(resolvedPrice * 1e6)),
111
+ asset,
112
+ payTo: options.payTo,
113
+ maxTimeoutSeconds: 60,
114
+ extra: {
115
+ name: "USD Coin",
116
+ version: "2",
117
+ decimals: 6,
118
+ facilitatorUrl: this.config.facilitatorUrl
119
+ }
120
+ }]
121
+ });
122
+ }
123
+ const verification = await this.verifyPayment(paymentSignature, resolvedPrice, options.maxTimeout);
124
+ if (!verification.verified) {
125
+ return res.status(402).json({
126
+ error: "Payment verification failed",
127
+ code: "PAYMENT_INVALID",
128
+ details: verification.error
129
+ });
130
+ }
131
+ req.payment = verification;
132
+ if (options.customRules) {
133
+ const customValid = await options.customRules(req);
134
+ if (!customValid) {
135
+ return res.status(403).json({ error: "Custom validation failed", code: "VALIDATION_FAILED" });
136
+ }
137
+ }
138
+ next();
139
+ } catch (error) {
140
+ console.error("Relai protection error:", error);
141
+ res.status(500).json({ error: "Internal server error", code: "SERVER_ERROR" });
142
+ }
143
+ };
144
+ }
145
+ async verifyPayment(signature, expectedPrice, timeoutMs) {
146
+ try {
147
+ const response = await this.client.post(
148
+ "/verify-payment",
149
+ { signature, expectedPrice, network: this.config.network },
150
+ { timeout: typeof timeoutMs === "number" ? Math.max(1, timeoutMs) : void 0 }
151
+ );
152
+ return response.data;
153
+ } catch (error) {
154
+ return { verified: false, error: error.response?.data?.error || "Verification failed" };
155
+ }
156
+ }
157
+ async getStats(apiId) {
158
+ const params = apiId ? { apiId } : {};
159
+ const response = await this.client.get("/stats", { params });
160
+ return response.data;
161
+ }
162
+ createProtectedEndpoint(options) {
163
+ return this.protect(options);
164
+ }
165
+ };
166
+ var server_default = Relai;
167
+ // Annotate the CommonJS export names for ESM import in node:
168
+ 0 && (module.exports = {
169
+ Relai
170
+ });
171
+ //# sourceMappingURL=server.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/server.ts","../src/types.ts"],"sourcesContent":["// src/server.ts\nimport axios, { AxiosInstance } from 'axios';\nimport {\n RelaiConfig,\n ProtectOptions,\n PaymentResult,\n NETWORK_CAIP2,\n USDC_ADDRESSES,\n RELAI_FACILITATOR_URL,\n type RelaiNetwork,\n} from './types';\n\nexport class Relai {\n private config: Required<Pick<RelaiConfig, 'network' | 'facilitatorUrl' | 'apiBaseUrl'>> & RelaiConfig;\n private client: AxiosInstance;\n\n constructor(config: RelaiConfig) {\n this.config = {\n network: 'solana',\n apiBaseUrl: 'https://relai.fi/api',\n facilitatorUrl: RELAI_FACILITATOR_URL,\n ...config,\n };\n\n if (!this.config.apiKey || typeof this.config.apiKey !== 'string') {\n throw new Error('[Relai] Missing required apiKey in configuration');\n }\n\n this.client = axios.create({\n baseURL: this.config.apiBaseUrl,\n timeout: 10000,\n headers: {\n 'Authorization': `Bearer ${this.config.apiKey}`,\n 'Content-Type': 'application/json',\n },\n });\n }\n\n /**\n * Express middleware to protect an endpoint with x402 micropayments.\n * Returns a 402 with `accepts` for the configured network.\n * Supports: Solana, Base, Avalanche, SKALE Base.\n */\n protect(options: ProtectOptions) {\n return async (req: any, res: any, next: any) => {\n try {\n const resolvedPrice = typeof options.price === 'function'\n ? await options.price(req)\n : options.price;\n\n if (typeof resolvedPrice !== 'number' || !isFinite(resolvedPrice) || resolvedPrice <= 0) {\n return res.status(400).json({ error: 'Invalid price configuration', code: 'INVALID_PRICE' });\n }\n\n // Check for payment header\n const paymentSignature = req.headers['x-payment-signature'] || req.headers['x-relai-payment'];\n\n if (!paymentSignature) {\n const network = this.config.network as RelaiNetwork;\n const caip2 = NETWORK_CAIP2[network] || NETWORK_CAIP2['solana'];\n const asset = USDC_ADDRESSES[network] || USDC_ADDRESSES['solana'];\n\n return res.status(402).json({\n x402Version: 2,\n error: 'Payment required',\n resource: {\n url: `${req.protocol}://${req.get('host')}${req.originalUrl}`,\n description: options.description || 'API access',\n mimeType: 'application/json',\n },\n accepts: [{\n scheme: 'exact',\n network: caip2,\n maxAmountRequired: String(Math.floor(resolvedPrice * 1_000_000)),\n asset,\n payTo: options.payTo,\n maxTimeoutSeconds: 60,\n extra: {\n name: 'USD Coin',\n version: '2',\n decimals: 6,\n facilitatorUrl: this.config.facilitatorUrl,\n },\n }],\n });\n }\n\n // Verify payment\n const verification = await this.verifyPayment(paymentSignature, resolvedPrice, options.maxTimeout);\n\n if (!verification.verified) {\n return res.status(402).json({\n error: 'Payment verification failed',\n code: 'PAYMENT_INVALID',\n details: verification.error,\n });\n }\n\n req.payment = verification;\n\n if (options.customRules) {\n const customValid = await options.customRules(req);\n if (!customValid) {\n return res.status(403).json({ error: 'Custom validation failed', code: 'VALIDATION_FAILED' });\n }\n }\n\n next();\n } catch (error) {\n console.error('Relai protection error:', error);\n res.status(500).json({ error: 'Internal server error', code: 'SERVER_ERROR' });\n }\n };\n }\n\n private async verifyPayment(signature: string, expectedPrice: number, timeoutMs?: number): Promise<PaymentResult> {\n try {\n const response = await this.client.post(\n '/verify-payment',\n { signature, expectedPrice, network: this.config.network },\n { timeout: typeof timeoutMs === 'number' ? Math.max(1, timeoutMs) : undefined },\n );\n return response.data;\n } catch (error: any) {\n return { verified: false, error: error.response?.data?.error || 'Verification failed' };\n }\n }\n\n async getStats(apiId?: string) {\n const params = apiId ? { apiId } : {};\n const response = await this.client.get('/stats', { params });\n return response.data;\n }\n\n createProtectedEndpoint(options: ProtectOptions) {\n return this.protect(options);\n }\n}\n\nexport default Relai;\n","// src/types.ts\n\n// ============================================================================\n// Constants\n// ============================================================================\n\n/** RelAI Facilitator URL */\nexport const RELAI_FACILITATOR_URL = 'https://facilitator.x402.fi';\n\n// ============================================================================\n// Supported Networks\n// ============================================================================\n\n/** All networks supported by RelAI facilitator */\nexport type RelaiNetwork = 'solana' | 'base' | 'avalanche' | 'skale-base';\n\n/** CAIP-2 network identifiers */\nexport const NETWORK_CAIP2: Record<RelaiNetwork, string> = {\n 'solana': 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp',\n 'base': 'eip155:8453',\n 'avalanche': 'eip155:43114',\n 'skale-base': 'eip155:1187947933',\n};\n\n/** Reverse lookup: CAIP-2 → simple network name */\nexport const CAIP2_TO_NETWORK: Record<string, RelaiNetwork> = Object.fromEntries(\n Object.entries(NETWORK_CAIP2).map(([k, v]) => [v, k as RelaiNetwork])\n) as Record<string, RelaiNetwork>;\n\n/** Chain IDs for EVM networks */\nexport const CHAIN_IDS: Record<string, number> = {\n 'base': 8453,\n 'avalanche': 43114,\n 'skale-base': 1187947933,\n};\n\n/** USDC contract addresses per network */\nexport const USDC_ADDRESSES: Record<RelaiNetwork, string> = {\n 'solana': 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v',\n 'base': '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',\n 'avalanche': '0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E',\n 'skale-base': '0x85889c8c714505E0c94b30fcfcF64fE3Ac8FCb20',\n};\n\n/** Explorer URLs per network */\nexport const EXPLORER_TX_URL: Record<RelaiNetwork, (tx: string) => string> = {\n 'solana': (tx) => `https://solscan.io/tx/${tx}`,\n 'base': (tx) => `https://basescan.org/tx/${tx}`,\n 'avalanche': (tx) => `https://snowtrace.io/tx/${tx}`,\n 'skale-base': (tx) => `https://skale-base-explorer.skalenodes.com/tx/${tx}`,\n};\n\n/** Human-readable network labels */\nexport const NETWORK_LABELS: Record<RelaiNetwork, string> = {\n 'solana': 'Solana',\n 'base': 'Base',\n 'avalanche': 'Avalanche',\n 'skale-base': 'SKALE Base',\n};\n\n/** Legacy CAIP-2 exports for backward compatibility */\nexport const SOLANA_MAINNET_NETWORK = NETWORK_CAIP2['solana'];\nexport const BASE_MAINNET_NETWORK = NETWORK_CAIP2['base'];\n\n/** Legacy USDC exports for backward compatibility */\nexport const USDC_SOLANA = USDC_ADDRESSES['solana'];\nexport const USDC_BASE = USDC_ADDRESSES['base'];\n\n/** All supported RelAI networks list */\nexport const RELAI_NETWORKS: RelaiNetwork[] = ['solana', 'base', 'avalanche', 'skale-base'];\n\n/** Check if a network is Solana-based */\nexport function isSolana(network: string): boolean {\n return network === 'solana' || network.startsWith('solana:');\n}\n\n/** Check if a network is EVM-based */\nexport function isEvm(network: string): boolean {\n return ['base', 'avalanche', 'skale-base'].includes(network) || network.startsWith('eip155:');\n}\n\n/** Normalize CAIP-2 or simple name to RelaiNetwork */\nexport function normalizeNetwork(network: string): RelaiNetwork | null {\n if (RELAI_NETWORKS.includes(network as RelaiNetwork)) return network as RelaiNetwork;\n const fromCaip2 = CAIP2_TO_NETWORK[network];\n if (fromCaip2) return fromCaip2;\n // Partial match\n if (network.startsWith('solana:')) return 'solana';\n if (network.startsWith('eip155:')) {\n const chainId = parseInt(network.split(':')[1]);\n const entry = Object.entries(CHAIN_IDS).find(([, id]) => id === chainId);\n if (entry) return entry[0] as RelaiNetwork;\n }\n return null;\n}\n\n// ============================================================================\n// Wallet Types\n// ============================================================================\n\n/** Solana wallet interface */\nexport interface SolanaWallet {\n publicKey: { toString(): string } | null;\n signTransaction: ((tx: unknown) => Promise<unknown>) | null;\n signAllTransactions?: ((txs: unknown[]) => Promise<unknown[]>) | null;\n}\n\n/** EVM wallet interface (viem-compatible) */\nexport interface EvmWallet {\n address: string;\n signTypedData: (params: unknown) => Promise<string>;\n chain?: { id: number };\n}\n\n/** Wallet set for multi-chain support */\nexport interface WalletSet {\n solana?: SolanaWallet;\n evm?: EvmWallet;\n}\n\n// ============================================================================\n// Payment Types\n// ============================================================================\n\n/** Extra fields in payment requirements */\nexport interface AcceptsExtra {\n feePayer?: string;\n decimals?: number;\n name?: string;\n version?: string;\n [key: string]: unknown;\n}\n\n/** A single payment option */\nexport interface PaymentAccept {\n x402Version?: 1 | 2;\n scheme: string;\n network: string;\n maxAmountRequired?: string;\n amount?: string;\n asset: string;\n payTo: string;\n maxTimeoutSeconds?: number;\n extra?: AcceptsExtra;\n resource?: string;\n description?: string;\n mimeType?: string;\n outputSchema?: unknown;\n}\n\n/** Resource info for v2 */\nexport interface ResourceInfo {\n url: string;\n description?: string;\n mimeType?: string;\n}\n\n/** Payment requirements (402 response) */\nexport interface PaymentRequired {\n x402Version: 1 | 2;\n error?: string;\n accepts: PaymentAccept[];\n resource?: ResourceInfo;\n extensions?: Record<string, unknown>;\n}\n\n// ============================================================================\n// Config Types\n// ============================================================================\n\nexport interface RelaiConfig {\n apiKey?: string;\n network?: RelaiNetwork;\n facilitatorUrl?: string;\n apiBaseUrl?: string;\n}\n\nexport type DynamicPrice = number | ((req: unknown) => number | Promise<number>);\n\nexport interface ProtectOptions {\n /** Price in USD (e.g., 0.01 for 1 cent) */\n price: DynamicPrice;\n /** Wallet address to receive payments */\n payTo: string;\n /** Description shown to payer */\n description?: string;\n /** Maximum timeout in seconds */\n maxTimeout?: number;\n /** Custom validation rules */\n customRules?: (req: unknown) => boolean | Promise<boolean>;\n onPaymentRequired?: (\n req: unknown,\n info: { price: number; description?: string; facilitatorUrl?: string }\n ) => void;\n onPaymentVerified?: (req: unknown, result: PaymentResult) => void;\n onError?: (req: unknown, error: unknown) => void;\n}\n\nexport interface PaymentResult {\n verified: boolean;\n transactionId?: string;\n amount?: number;\n currency?: string;\n error?: string;\n}\n"],"mappings":"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","names":["axios"]}
@@ -0,0 +1,18 @@
1
+ import { m as RelaiConfig, o as ProtectOptions } from './types-DGRfrYd3.cjs';
2
+
3
+ declare class Relai {
4
+ private config;
5
+ private client;
6
+ constructor(config: RelaiConfig);
7
+ /**
8
+ * Express middleware to protect an endpoint with x402 micropayments.
9
+ * Returns a 402 with `accepts` for the configured network.
10
+ * Supports: Solana, Base, Avalanche, SKALE Base.
11
+ */
12
+ protect(options: ProtectOptions): (req: any, res: any, next: any) => Promise<any>;
13
+ private verifyPayment;
14
+ getStats(apiId?: string): Promise<any>;
15
+ createProtectedEndpoint(options: ProtectOptions): (req: any, res: any, next: any) => Promise<any>;
16
+ }
17
+
18
+ export { Relai, Relai as default };
@@ -0,0 +1,18 @@
1
+ import { m as RelaiConfig, o as ProtectOptions } from './types-DGRfrYd3.js';
2
+
3
+ declare class Relai {
4
+ private config;
5
+ private client;
6
+ constructor(config: RelaiConfig);
7
+ /**
8
+ * Express middleware to protect an endpoint with x402 micropayments.
9
+ * Returns a 402 with `accepts` for the configured network.
10
+ * Supports: Solana, Base, Avalanche, SKALE Base.
11
+ */
12
+ protect(options: ProtectOptions): (req: any, res: any, next: any) => Promise<any>;
13
+ private verifyPayment;
14
+ getStats(apiId?: string): Promise<any>;
15
+ createProtectedEndpoint(options: ProtectOptions): (req: any, res: any, next: any) => Promise<any>;
16
+ }
17
+
18
+ export { Relai, Relai as default };
package/dist/server.js ADDED
@@ -0,0 +1,136 @@
1
+ // src/server.ts
2
+ import axios from "axios";
3
+
4
+ // src/types.ts
5
+ var RELAI_FACILITATOR_URL = "https://facilitator.x402.fi";
6
+ var NETWORK_CAIP2 = {
7
+ "solana": "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp",
8
+ "base": "eip155:8453",
9
+ "avalanche": "eip155:43114",
10
+ "skale-base": "eip155:1187947933"
11
+ };
12
+ var CAIP2_TO_NETWORK = Object.fromEntries(
13
+ Object.entries(NETWORK_CAIP2).map(([k, v]) => [v, k])
14
+ );
15
+ var USDC_ADDRESSES = {
16
+ "solana": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
17
+ "base": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
18
+ "avalanche": "0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E",
19
+ "skale-base": "0x85889c8c714505E0c94b30fcfcF64fE3Ac8FCb20"
20
+ };
21
+ var SOLANA_MAINNET_NETWORK = NETWORK_CAIP2["solana"];
22
+ var BASE_MAINNET_NETWORK = NETWORK_CAIP2["base"];
23
+ var USDC_SOLANA = USDC_ADDRESSES["solana"];
24
+ var USDC_BASE = USDC_ADDRESSES["base"];
25
+
26
+ // src/server.ts
27
+ var Relai = class {
28
+ constructor(config) {
29
+ this.config = {
30
+ network: "solana",
31
+ apiBaseUrl: "https://relai.fi/api",
32
+ facilitatorUrl: RELAI_FACILITATOR_URL,
33
+ ...config
34
+ };
35
+ if (!this.config.apiKey || typeof this.config.apiKey !== "string") {
36
+ throw new Error("[Relai] Missing required apiKey in configuration");
37
+ }
38
+ this.client = axios.create({
39
+ baseURL: this.config.apiBaseUrl,
40
+ timeout: 1e4,
41
+ headers: {
42
+ "Authorization": `Bearer ${this.config.apiKey}`,
43
+ "Content-Type": "application/json"
44
+ }
45
+ });
46
+ }
47
+ /**
48
+ * Express middleware to protect an endpoint with x402 micropayments.
49
+ * Returns a 402 with `accepts` for the configured network.
50
+ * Supports: Solana, Base, Avalanche, SKALE Base.
51
+ */
52
+ protect(options) {
53
+ return async (req, res, next) => {
54
+ try {
55
+ const resolvedPrice = typeof options.price === "function" ? await options.price(req) : options.price;
56
+ if (typeof resolvedPrice !== "number" || !isFinite(resolvedPrice) || resolvedPrice <= 0) {
57
+ return res.status(400).json({ error: "Invalid price configuration", code: "INVALID_PRICE" });
58
+ }
59
+ const paymentSignature = req.headers["x-payment-signature"] || req.headers["x-relai-payment"];
60
+ if (!paymentSignature) {
61
+ const network = this.config.network;
62
+ const caip2 = NETWORK_CAIP2[network] || NETWORK_CAIP2["solana"];
63
+ const asset = USDC_ADDRESSES[network] || USDC_ADDRESSES["solana"];
64
+ return res.status(402).json({
65
+ x402Version: 2,
66
+ error: "Payment required",
67
+ resource: {
68
+ url: `${req.protocol}://${req.get("host")}${req.originalUrl}`,
69
+ description: options.description || "API access",
70
+ mimeType: "application/json"
71
+ },
72
+ accepts: [{
73
+ scheme: "exact",
74
+ network: caip2,
75
+ maxAmountRequired: String(Math.floor(resolvedPrice * 1e6)),
76
+ asset,
77
+ payTo: options.payTo,
78
+ maxTimeoutSeconds: 60,
79
+ extra: {
80
+ name: "USD Coin",
81
+ version: "2",
82
+ decimals: 6,
83
+ facilitatorUrl: this.config.facilitatorUrl
84
+ }
85
+ }]
86
+ });
87
+ }
88
+ const verification = await this.verifyPayment(paymentSignature, resolvedPrice, options.maxTimeout);
89
+ if (!verification.verified) {
90
+ return res.status(402).json({
91
+ error: "Payment verification failed",
92
+ code: "PAYMENT_INVALID",
93
+ details: verification.error
94
+ });
95
+ }
96
+ req.payment = verification;
97
+ if (options.customRules) {
98
+ const customValid = await options.customRules(req);
99
+ if (!customValid) {
100
+ return res.status(403).json({ error: "Custom validation failed", code: "VALIDATION_FAILED" });
101
+ }
102
+ }
103
+ next();
104
+ } catch (error) {
105
+ console.error("Relai protection error:", error);
106
+ res.status(500).json({ error: "Internal server error", code: "SERVER_ERROR" });
107
+ }
108
+ };
109
+ }
110
+ async verifyPayment(signature, expectedPrice, timeoutMs) {
111
+ try {
112
+ const response = await this.client.post(
113
+ "/verify-payment",
114
+ { signature, expectedPrice, network: this.config.network },
115
+ { timeout: typeof timeoutMs === "number" ? Math.max(1, timeoutMs) : void 0 }
116
+ );
117
+ return response.data;
118
+ } catch (error) {
119
+ return { verified: false, error: error.response?.data?.error || "Verification failed" };
120
+ }
121
+ }
122
+ async getStats(apiId) {
123
+ const params = apiId ? { apiId } : {};
124
+ const response = await this.client.get("/stats", { params });
125
+ return response.data;
126
+ }
127
+ createProtectedEndpoint(options) {
128
+ return this.protect(options);
129
+ }
130
+ };
131
+ var server_default = Relai;
132
+ export {
133
+ Relai,
134
+ server_default as default
135
+ };
136
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/server.ts","../src/types.ts"],"sourcesContent":["// src/server.ts\nimport axios, { AxiosInstance } from 'axios';\nimport {\n RelaiConfig,\n ProtectOptions,\n PaymentResult,\n NETWORK_CAIP2,\n USDC_ADDRESSES,\n RELAI_FACILITATOR_URL,\n type RelaiNetwork,\n} from './types';\n\nexport class Relai {\n private config: Required<Pick<RelaiConfig, 'network' | 'facilitatorUrl' | 'apiBaseUrl'>> & RelaiConfig;\n private client: AxiosInstance;\n\n constructor(config: RelaiConfig) {\n this.config = {\n network: 'solana',\n apiBaseUrl: 'https://relai.fi/api',\n facilitatorUrl: RELAI_FACILITATOR_URL,\n ...config,\n };\n\n if (!this.config.apiKey || typeof this.config.apiKey !== 'string') {\n throw new Error('[Relai] Missing required apiKey in configuration');\n }\n\n this.client = axios.create({\n baseURL: this.config.apiBaseUrl,\n timeout: 10000,\n headers: {\n 'Authorization': `Bearer ${this.config.apiKey}`,\n 'Content-Type': 'application/json',\n },\n });\n }\n\n /**\n * Express middleware to protect an endpoint with x402 micropayments.\n * Returns a 402 with `accepts` for the configured network.\n * Supports: Solana, Base, Avalanche, SKALE Base.\n */\n protect(options: ProtectOptions) {\n return async (req: any, res: any, next: any) => {\n try {\n const resolvedPrice = typeof options.price === 'function'\n ? await options.price(req)\n : options.price;\n\n if (typeof resolvedPrice !== 'number' || !isFinite(resolvedPrice) || resolvedPrice <= 0) {\n return res.status(400).json({ error: 'Invalid price configuration', code: 'INVALID_PRICE' });\n }\n\n // Check for payment header\n const paymentSignature = req.headers['x-payment-signature'] || req.headers['x-relai-payment'];\n\n if (!paymentSignature) {\n const network = this.config.network as RelaiNetwork;\n const caip2 = NETWORK_CAIP2[network] || NETWORK_CAIP2['solana'];\n const asset = USDC_ADDRESSES[network] || USDC_ADDRESSES['solana'];\n\n return res.status(402).json({\n x402Version: 2,\n error: 'Payment required',\n resource: {\n url: `${req.protocol}://${req.get('host')}${req.originalUrl}`,\n description: options.description || 'API access',\n mimeType: 'application/json',\n },\n accepts: [{\n scheme: 'exact',\n network: caip2,\n maxAmountRequired: String(Math.floor(resolvedPrice * 1_000_000)),\n asset,\n payTo: options.payTo,\n maxTimeoutSeconds: 60,\n extra: {\n name: 'USD Coin',\n version: '2',\n decimals: 6,\n facilitatorUrl: this.config.facilitatorUrl,\n },\n }],\n });\n }\n\n // Verify payment\n const verification = await this.verifyPayment(paymentSignature, resolvedPrice, options.maxTimeout);\n\n if (!verification.verified) {\n return res.status(402).json({\n error: 'Payment verification failed',\n code: 'PAYMENT_INVALID',\n details: verification.error,\n });\n }\n\n req.payment = verification;\n\n if (options.customRules) {\n const customValid = await options.customRules(req);\n if (!customValid) {\n return res.status(403).json({ error: 'Custom validation failed', code: 'VALIDATION_FAILED' });\n }\n }\n\n next();\n } catch (error) {\n console.error('Relai protection error:', error);\n res.status(500).json({ error: 'Internal server error', code: 'SERVER_ERROR' });\n }\n };\n }\n\n private async verifyPayment(signature: string, expectedPrice: number, timeoutMs?: number): Promise<PaymentResult> {\n try {\n const response = await this.client.post(\n '/verify-payment',\n { signature, expectedPrice, network: this.config.network },\n { timeout: typeof timeoutMs === 'number' ? Math.max(1, timeoutMs) : undefined },\n );\n return response.data;\n } catch (error: any) {\n return { verified: false, error: error.response?.data?.error || 'Verification failed' };\n }\n }\n\n async getStats(apiId?: string) {\n const params = apiId ? { apiId } : {};\n const response = await this.client.get('/stats', { params });\n return response.data;\n }\n\n createProtectedEndpoint(options: ProtectOptions) {\n return this.protect(options);\n }\n}\n\nexport default Relai;\n","// src/types.ts\n\n// ============================================================================\n// Constants\n// ============================================================================\n\n/** RelAI Facilitator URL */\nexport const RELAI_FACILITATOR_URL = 'https://facilitator.x402.fi';\n\n// ============================================================================\n// Supported Networks\n// ============================================================================\n\n/** All networks supported by RelAI facilitator */\nexport type RelaiNetwork = 'solana' | 'base' | 'avalanche' | 'skale-base';\n\n/** CAIP-2 network identifiers */\nexport const NETWORK_CAIP2: Record<RelaiNetwork, string> = {\n 'solana': 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp',\n 'base': 'eip155:8453',\n 'avalanche': 'eip155:43114',\n 'skale-base': 'eip155:1187947933',\n};\n\n/** Reverse lookup: CAIP-2 → simple network name */\nexport const CAIP2_TO_NETWORK: Record<string, RelaiNetwork> = Object.fromEntries(\n Object.entries(NETWORK_CAIP2).map(([k, v]) => [v, k as RelaiNetwork])\n) as Record<string, RelaiNetwork>;\n\n/** Chain IDs for EVM networks */\nexport const CHAIN_IDS: Record<string, number> = {\n 'base': 8453,\n 'avalanche': 43114,\n 'skale-base': 1187947933,\n};\n\n/** USDC contract addresses per network */\nexport const USDC_ADDRESSES: Record<RelaiNetwork, string> = {\n 'solana': 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v',\n 'base': '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',\n 'avalanche': '0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E',\n 'skale-base': '0x85889c8c714505E0c94b30fcfcF64fE3Ac8FCb20',\n};\n\n/** Explorer URLs per network */\nexport const EXPLORER_TX_URL: Record<RelaiNetwork, (tx: string) => string> = {\n 'solana': (tx) => `https://solscan.io/tx/${tx}`,\n 'base': (tx) => `https://basescan.org/tx/${tx}`,\n 'avalanche': (tx) => `https://snowtrace.io/tx/${tx}`,\n 'skale-base': (tx) => `https://skale-base-explorer.skalenodes.com/tx/${tx}`,\n};\n\n/** Human-readable network labels */\nexport const NETWORK_LABELS: Record<RelaiNetwork, string> = {\n 'solana': 'Solana',\n 'base': 'Base',\n 'avalanche': 'Avalanche',\n 'skale-base': 'SKALE Base',\n};\n\n/** Legacy CAIP-2 exports for backward compatibility */\nexport const SOLANA_MAINNET_NETWORK = NETWORK_CAIP2['solana'];\nexport const BASE_MAINNET_NETWORK = NETWORK_CAIP2['base'];\n\n/** Legacy USDC exports for backward compatibility */\nexport const USDC_SOLANA = USDC_ADDRESSES['solana'];\nexport const USDC_BASE = USDC_ADDRESSES['base'];\n\n/** All supported RelAI networks list */\nexport const RELAI_NETWORKS: RelaiNetwork[] = ['solana', 'base', 'avalanche', 'skale-base'];\n\n/** Check if a network is Solana-based */\nexport function isSolana(network: string): boolean {\n return network === 'solana' || network.startsWith('solana:');\n}\n\n/** Check if a network is EVM-based */\nexport function isEvm(network: string): boolean {\n return ['base', 'avalanche', 'skale-base'].includes(network) || network.startsWith('eip155:');\n}\n\n/** Normalize CAIP-2 or simple name to RelaiNetwork */\nexport function normalizeNetwork(network: string): RelaiNetwork | null {\n if (RELAI_NETWORKS.includes(network as RelaiNetwork)) return network as RelaiNetwork;\n const fromCaip2 = CAIP2_TO_NETWORK[network];\n if (fromCaip2) return fromCaip2;\n // Partial match\n if (network.startsWith('solana:')) return 'solana';\n if (network.startsWith('eip155:')) {\n const chainId = parseInt(network.split(':')[1]);\n const entry = Object.entries(CHAIN_IDS).find(([, id]) => id === chainId);\n if (entry) return entry[0] as RelaiNetwork;\n }\n return null;\n}\n\n// ============================================================================\n// Wallet Types\n// ============================================================================\n\n/** Solana wallet interface */\nexport interface SolanaWallet {\n publicKey: { toString(): string } | null;\n signTransaction: ((tx: unknown) => Promise<unknown>) | null;\n signAllTransactions?: ((txs: unknown[]) => Promise<unknown[]>) | null;\n}\n\n/** EVM wallet interface (viem-compatible) */\nexport interface EvmWallet {\n address: string;\n signTypedData: (params: unknown) => Promise<string>;\n chain?: { id: number };\n}\n\n/** Wallet set for multi-chain support */\nexport interface WalletSet {\n solana?: SolanaWallet;\n evm?: EvmWallet;\n}\n\n// ============================================================================\n// Payment Types\n// ============================================================================\n\n/** Extra fields in payment requirements */\nexport interface AcceptsExtra {\n feePayer?: string;\n decimals?: number;\n name?: string;\n version?: string;\n [key: string]: unknown;\n}\n\n/** A single payment option */\nexport interface PaymentAccept {\n x402Version?: 1 | 2;\n scheme: string;\n network: string;\n maxAmountRequired?: string;\n amount?: string;\n asset: string;\n payTo: string;\n maxTimeoutSeconds?: number;\n extra?: AcceptsExtra;\n resource?: string;\n description?: string;\n mimeType?: string;\n outputSchema?: unknown;\n}\n\n/** Resource info for v2 */\nexport interface ResourceInfo {\n url: string;\n description?: string;\n mimeType?: string;\n}\n\n/** Payment requirements (402 response) */\nexport interface PaymentRequired {\n x402Version: 1 | 2;\n error?: string;\n accepts: PaymentAccept[];\n resource?: ResourceInfo;\n extensions?: Record<string, unknown>;\n}\n\n// ============================================================================\n// Config Types\n// ============================================================================\n\nexport interface RelaiConfig {\n apiKey?: string;\n network?: RelaiNetwork;\n facilitatorUrl?: string;\n apiBaseUrl?: string;\n}\n\nexport type DynamicPrice = number | ((req: unknown) => number | Promise<number>);\n\nexport interface ProtectOptions {\n /** Price in USD (e.g., 0.01 for 1 cent) */\n price: DynamicPrice;\n /** Wallet address to receive payments */\n payTo: string;\n /** Description shown to payer */\n description?: string;\n /** Maximum timeout in seconds */\n maxTimeout?: number;\n /** Custom validation rules */\n customRules?: (req: unknown) => boolean | Promise<boolean>;\n onPaymentRequired?: (\n req: unknown,\n info: { price: number; description?: string; facilitatorUrl?: string }\n ) => void;\n onPaymentVerified?: (req: unknown, result: PaymentResult) => void;\n onError?: (req: unknown, error: unknown) => void;\n}\n\nexport interface PaymentResult {\n verified: boolean;\n transactionId?: string;\n amount?: number;\n currency?: string;\n error?: string;\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,124 @@
1
+ /** RelAI Facilitator URL */
2
+ declare const RELAI_FACILITATOR_URL = "https://facilitator.x402.fi";
3
+ /** All networks supported by RelAI facilitator */
4
+ type RelaiNetwork = 'solana' | 'base' | 'avalanche' | 'skale-base';
5
+ /** CAIP-2 network identifiers */
6
+ declare const NETWORK_CAIP2: Record<RelaiNetwork, string>;
7
+ /** Reverse lookup: CAIP-2 → simple network name */
8
+ declare const CAIP2_TO_NETWORK: Record<string, RelaiNetwork>;
9
+ /** Chain IDs for EVM networks */
10
+ declare const CHAIN_IDS: Record<string, number>;
11
+ /** USDC contract addresses per network */
12
+ declare const USDC_ADDRESSES: Record<RelaiNetwork, string>;
13
+ /** Explorer URLs per network */
14
+ declare const EXPLORER_TX_URL: Record<RelaiNetwork, (tx: string) => string>;
15
+ /** Human-readable network labels */
16
+ declare const NETWORK_LABELS: Record<RelaiNetwork, string>;
17
+ /** Legacy CAIP-2 exports for backward compatibility */
18
+ declare const SOLANA_MAINNET_NETWORK: string;
19
+ declare const BASE_MAINNET_NETWORK: string;
20
+ /** Legacy USDC exports for backward compatibility */
21
+ declare const USDC_SOLANA: string;
22
+ declare const USDC_BASE: string;
23
+ /** All supported RelAI networks list */
24
+ declare const RELAI_NETWORKS: RelaiNetwork[];
25
+ /** Check if a network is Solana-based */
26
+ declare function isSolana(network: string): boolean;
27
+ /** Check if a network is EVM-based */
28
+ declare function isEvm(network: string): boolean;
29
+ /** Normalize CAIP-2 or simple name to RelaiNetwork */
30
+ declare function normalizeNetwork(network: string): RelaiNetwork | null;
31
+ /** Solana wallet interface */
32
+ interface SolanaWallet {
33
+ publicKey: {
34
+ toString(): string;
35
+ } | null;
36
+ signTransaction: ((tx: unknown) => Promise<unknown>) | null;
37
+ signAllTransactions?: ((txs: unknown[]) => Promise<unknown[]>) | null;
38
+ }
39
+ /** EVM wallet interface (viem-compatible) */
40
+ interface EvmWallet {
41
+ address: string;
42
+ signTypedData: (params: unknown) => Promise<string>;
43
+ chain?: {
44
+ id: number;
45
+ };
46
+ }
47
+ /** Wallet set for multi-chain support */
48
+ interface WalletSet {
49
+ solana?: SolanaWallet;
50
+ evm?: EvmWallet;
51
+ }
52
+ /** Extra fields in payment requirements */
53
+ interface AcceptsExtra {
54
+ feePayer?: string;
55
+ decimals?: number;
56
+ name?: string;
57
+ version?: string;
58
+ [key: string]: unknown;
59
+ }
60
+ /** A single payment option */
61
+ interface PaymentAccept {
62
+ x402Version?: 1 | 2;
63
+ scheme: string;
64
+ network: string;
65
+ maxAmountRequired?: string;
66
+ amount?: string;
67
+ asset: string;
68
+ payTo: string;
69
+ maxTimeoutSeconds?: number;
70
+ extra?: AcceptsExtra;
71
+ resource?: string;
72
+ description?: string;
73
+ mimeType?: string;
74
+ outputSchema?: unknown;
75
+ }
76
+ /** Resource info for v2 */
77
+ interface ResourceInfo {
78
+ url: string;
79
+ description?: string;
80
+ mimeType?: string;
81
+ }
82
+ /** Payment requirements (402 response) */
83
+ interface PaymentRequired {
84
+ x402Version: 1 | 2;
85
+ error?: string;
86
+ accepts: PaymentAccept[];
87
+ resource?: ResourceInfo;
88
+ extensions?: Record<string, unknown>;
89
+ }
90
+ interface RelaiConfig {
91
+ apiKey?: string;
92
+ network?: RelaiNetwork;
93
+ facilitatorUrl?: string;
94
+ apiBaseUrl?: string;
95
+ }
96
+ type DynamicPrice = number | ((req: unknown) => number | Promise<number>);
97
+ interface ProtectOptions {
98
+ /** Price in USD (e.g., 0.01 for 1 cent) */
99
+ price: DynamicPrice;
100
+ /** Wallet address to receive payments */
101
+ payTo: string;
102
+ /** Description shown to payer */
103
+ description?: string;
104
+ /** Maximum timeout in seconds */
105
+ maxTimeout?: number;
106
+ /** Custom validation rules */
107
+ customRules?: (req: unknown) => boolean | Promise<boolean>;
108
+ onPaymentRequired?: (req: unknown, info: {
109
+ price: number;
110
+ description?: string;
111
+ facilitatorUrl?: string;
112
+ }) => void;
113
+ onPaymentVerified?: (req: unknown, result: PaymentResult) => void;
114
+ onError?: (req: unknown, error: unknown) => void;
115
+ }
116
+ interface PaymentResult {
117
+ verified: boolean;
118
+ transactionId?: string;
119
+ amount?: number;
120
+ currency?: string;
121
+ error?: string;
122
+ }
123
+
124
+ export { type AcceptsExtra as A, BASE_MAINNET_NETWORK as B, CAIP2_TO_NETWORK as C, type DynamicPrice as D, EXPLORER_TX_URL as E, NETWORK_CAIP2 as N, type PaymentAccept as P, RELAI_FACILITATOR_URL as R, SOLANA_MAINNET_NETWORK as S, USDC_ADDRESSES as U, type WalletSet as W, type RelaiNetwork as a, CHAIN_IDS as b, NETWORK_LABELS as c, USDC_SOLANA as d, USDC_BASE as e, RELAI_NETWORKS as f, isEvm as g, type SolanaWallet as h, isSolana as i, type EvmWallet as j, type ResourceInfo as k, type PaymentRequired as l, type RelaiConfig as m, normalizeNetwork as n, type ProtectOptions as o, type PaymentResult as p };
@@ -0,0 +1,124 @@
1
+ /** RelAI Facilitator URL */
2
+ declare const RELAI_FACILITATOR_URL = "https://facilitator.x402.fi";
3
+ /** All networks supported by RelAI facilitator */
4
+ type RelaiNetwork = 'solana' | 'base' | 'avalanche' | 'skale-base';
5
+ /** CAIP-2 network identifiers */
6
+ declare const NETWORK_CAIP2: Record<RelaiNetwork, string>;
7
+ /** Reverse lookup: CAIP-2 → simple network name */
8
+ declare const CAIP2_TO_NETWORK: Record<string, RelaiNetwork>;
9
+ /** Chain IDs for EVM networks */
10
+ declare const CHAIN_IDS: Record<string, number>;
11
+ /** USDC contract addresses per network */
12
+ declare const USDC_ADDRESSES: Record<RelaiNetwork, string>;
13
+ /** Explorer URLs per network */
14
+ declare const EXPLORER_TX_URL: Record<RelaiNetwork, (tx: string) => string>;
15
+ /** Human-readable network labels */
16
+ declare const NETWORK_LABELS: Record<RelaiNetwork, string>;
17
+ /** Legacy CAIP-2 exports for backward compatibility */
18
+ declare const SOLANA_MAINNET_NETWORK: string;
19
+ declare const BASE_MAINNET_NETWORK: string;
20
+ /** Legacy USDC exports for backward compatibility */
21
+ declare const USDC_SOLANA: string;
22
+ declare const USDC_BASE: string;
23
+ /** All supported RelAI networks list */
24
+ declare const RELAI_NETWORKS: RelaiNetwork[];
25
+ /** Check if a network is Solana-based */
26
+ declare function isSolana(network: string): boolean;
27
+ /** Check if a network is EVM-based */
28
+ declare function isEvm(network: string): boolean;
29
+ /** Normalize CAIP-2 or simple name to RelaiNetwork */
30
+ declare function normalizeNetwork(network: string): RelaiNetwork | null;
31
+ /** Solana wallet interface */
32
+ interface SolanaWallet {
33
+ publicKey: {
34
+ toString(): string;
35
+ } | null;
36
+ signTransaction: ((tx: unknown) => Promise<unknown>) | null;
37
+ signAllTransactions?: ((txs: unknown[]) => Promise<unknown[]>) | null;
38
+ }
39
+ /** EVM wallet interface (viem-compatible) */
40
+ interface EvmWallet {
41
+ address: string;
42
+ signTypedData: (params: unknown) => Promise<string>;
43
+ chain?: {
44
+ id: number;
45
+ };
46
+ }
47
+ /** Wallet set for multi-chain support */
48
+ interface WalletSet {
49
+ solana?: SolanaWallet;
50
+ evm?: EvmWallet;
51
+ }
52
+ /** Extra fields in payment requirements */
53
+ interface AcceptsExtra {
54
+ feePayer?: string;
55
+ decimals?: number;
56
+ name?: string;
57
+ version?: string;
58
+ [key: string]: unknown;
59
+ }
60
+ /** A single payment option */
61
+ interface PaymentAccept {
62
+ x402Version?: 1 | 2;
63
+ scheme: string;
64
+ network: string;
65
+ maxAmountRequired?: string;
66
+ amount?: string;
67
+ asset: string;
68
+ payTo: string;
69
+ maxTimeoutSeconds?: number;
70
+ extra?: AcceptsExtra;
71
+ resource?: string;
72
+ description?: string;
73
+ mimeType?: string;
74
+ outputSchema?: unknown;
75
+ }
76
+ /** Resource info for v2 */
77
+ interface ResourceInfo {
78
+ url: string;
79
+ description?: string;
80
+ mimeType?: string;
81
+ }
82
+ /** Payment requirements (402 response) */
83
+ interface PaymentRequired {
84
+ x402Version: 1 | 2;
85
+ error?: string;
86
+ accepts: PaymentAccept[];
87
+ resource?: ResourceInfo;
88
+ extensions?: Record<string, unknown>;
89
+ }
90
+ interface RelaiConfig {
91
+ apiKey?: string;
92
+ network?: RelaiNetwork;
93
+ facilitatorUrl?: string;
94
+ apiBaseUrl?: string;
95
+ }
96
+ type DynamicPrice = number | ((req: unknown) => number | Promise<number>);
97
+ interface ProtectOptions {
98
+ /** Price in USD (e.g., 0.01 for 1 cent) */
99
+ price: DynamicPrice;
100
+ /** Wallet address to receive payments */
101
+ payTo: string;
102
+ /** Description shown to payer */
103
+ description?: string;
104
+ /** Maximum timeout in seconds */
105
+ maxTimeout?: number;
106
+ /** Custom validation rules */
107
+ customRules?: (req: unknown) => boolean | Promise<boolean>;
108
+ onPaymentRequired?: (req: unknown, info: {
109
+ price: number;
110
+ description?: string;
111
+ facilitatorUrl?: string;
112
+ }) => void;
113
+ onPaymentVerified?: (req: unknown, result: PaymentResult) => void;
114
+ onError?: (req: unknown, error: unknown) => void;
115
+ }
116
+ interface PaymentResult {
117
+ verified: boolean;
118
+ transactionId?: string;
119
+ amount?: number;
120
+ currency?: string;
121
+ error?: string;
122
+ }
123
+
124
+ export { type AcceptsExtra as A, BASE_MAINNET_NETWORK as B, CAIP2_TO_NETWORK as C, type DynamicPrice as D, EXPLORER_TX_URL as E, NETWORK_CAIP2 as N, type PaymentAccept as P, RELAI_FACILITATOR_URL as R, SOLANA_MAINNET_NETWORK as S, USDC_ADDRESSES as U, type WalletSet as W, type RelaiNetwork as a, CHAIN_IDS as b, NETWORK_LABELS as c, USDC_SOLANA as d, USDC_BASE as e, RELAI_NETWORKS as f, isEvm as g, type SolanaWallet as h, isSolana as i, type EvmWallet as j, type ResourceInfo as k, type PaymentRequired as l, type RelaiConfig as m, normalizeNetwork as n, type ProtectOptions as o, type PaymentResult as p };