@t402/core 2.6.0 → 2.6.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/cjs/client/index.js.map +1 -1
- package/dist/cjs/http/index.d.ts +331 -2
- package/dist/cjs/http/index.js +250 -1
- package/dist/cjs/http/index.js.map +1 -1
- package/dist/cjs/server/index.d.ts +1 -1
- package/dist/cjs/server/index.js +5 -1
- package/dist/cjs/server/index.js.map +1 -1
- package/dist/cjs/{t402HTTPResourceServer-CGZh_p2c.d.ts → t402HTTPResourceServer-BIEvnbwL.d.ts} +9 -3
- package/dist/esm/{chunk-Z5HFSNZZ.mjs → chunk-4DIIUML6.mjs} +249 -2
- package/dist/esm/chunk-4DIIUML6.mjs.map +1 -0
- package/dist/esm/client/index.mjs +1 -1
- package/dist/esm/http/index.d.mts +331 -2
- package/dist/esm/http/index.mjs +5 -1
- package/dist/esm/server/index.d.mts +1 -1
- package/dist/esm/server/index.mjs +1 -1
- package/dist/esm/{t402HTTPResourceServer-DDxVMmS2.d.mts → t402HTTPResourceServer-Jmmvy9kc.d.mts} +9 -3
- package/package.json +1 -1
- package/dist/esm/chunk-Z5HFSNZZ.mjs.map +0 -1
|
@@ -1,8 +1,337 @@
|
|
|
1
1
|
import { c as PaymentRequired, S as SettleResponse, a as PaymentPayload, P as PaymentRequirements } from '../mechanisms-dYCiYgko.mjs';
|
|
2
|
-
export { C as CompiledRoute, D as DynamicPayTo, a as DynamicPrice, F as FacilitatorClient, b as FacilitatorConfig, H as HTTPAdapter, c as HTTPFacilitatorClient, d as HTTPProcessResult, e as HTTPRequestContext, f as HTTPResponseInstructions, P as PaymentOption, g as PaywallConfig, h as PaywallProvider, i as ProcessSettleFailureResponse, j as ProcessSettleResultResponse, k as ProcessSettleSuccessResponse, R as RouteConfig, l as RouteConfigurationError, m as RouteValidationError, n as RoutesConfig, U as UnpaidResponseBody, o as UnpaidResponseResult, t as t402HTTPResourceServer } from '../t402HTTPResourceServer-
|
|
2
|
+
export { C as CompiledRoute, D as DynamicPayTo, a as DynamicPrice, F as FacilitatorClient, b as FacilitatorConfig, H as HTTPAdapter, c as HTTPFacilitatorClient, d as HTTPProcessResult, e as HTTPRequestContext, f as HTTPResponseInstructions, P as PaymentOption, g as PaywallConfig, h as PaywallProvider, i as ProcessSettleFailureResponse, j as ProcessSettleResultResponse, k as ProcessSettleSuccessResponse, R as RouteConfig, l as RouteConfigurationError, m as RouteValidationError, n as RoutesConfig, S as SettleOptions, U as UnpaidResponseBody, o as UnpaidResponseResult, t as t402HTTPResourceServer } from '../t402HTTPResourceServer-Jmmvy9kc.mjs';
|
|
3
3
|
export { f as t402HTTPClient } from '../t402HTTPClient-DbIXpGXL.mjs';
|
|
4
4
|
import 'zod';
|
|
5
5
|
|
|
6
|
+
type StreamStatus = "pending" | "active" | "paused" | "closing" | "closed" | "cancelled" | "expired";
|
|
7
|
+
interface StreamMetadata {
|
|
8
|
+
resourceId?: string;
|
|
9
|
+
description?: string;
|
|
10
|
+
tags?: string[];
|
|
11
|
+
extra?: Record<string, string>;
|
|
12
|
+
}
|
|
13
|
+
interface Stream {
|
|
14
|
+
id: string;
|
|
15
|
+
network: string;
|
|
16
|
+
scheme: string;
|
|
17
|
+
payer: string;
|
|
18
|
+
payee: string;
|
|
19
|
+
asset: string;
|
|
20
|
+
maxAmount: string;
|
|
21
|
+
currentAmount: string;
|
|
22
|
+
settledAmount: string;
|
|
23
|
+
ratePerSecond: string;
|
|
24
|
+
status: StreamStatus;
|
|
25
|
+
createdAt: string;
|
|
26
|
+
activatedAt?: string;
|
|
27
|
+
lastUpdatedAt: string;
|
|
28
|
+
expiresAt?: string;
|
|
29
|
+
closedAt?: string;
|
|
30
|
+
depositTxHash: string;
|
|
31
|
+
settlementTxHash: string;
|
|
32
|
+
metadata: StreamMetadata;
|
|
33
|
+
}
|
|
34
|
+
interface StreamUpdate {
|
|
35
|
+
id: string;
|
|
36
|
+
streamId: string;
|
|
37
|
+
amount: string;
|
|
38
|
+
signature: string;
|
|
39
|
+
timestamp: string;
|
|
40
|
+
sequenceNum: number;
|
|
41
|
+
resourceUnits: number;
|
|
42
|
+
}
|
|
43
|
+
interface StreamStats {
|
|
44
|
+
totalUpdates: number;
|
|
45
|
+
averageRate: string;
|
|
46
|
+
duration: number;
|
|
47
|
+
resourcesUsed: number;
|
|
48
|
+
efficiencyScore: number;
|
|
49
|
+
}
|
|
50
|
+
interface OpenStreamRequest {
|
|
51
|
+
network: string;
|
|
52
|
+
scheme: string;
|
|
53
|
+
payer: string;
|
|
54
|
+
payee: string;
|
|
55
|
+
asset: string;
|
|
56
|
+
maxAmount: string;
|
|
57
|
+
ratePerSecond?: string;
|
|
58
|
+
expiresAt?: string;
|
|
59
|
+
signature: string;
|
|
60
|
+
metadata?: StreamMetadata;
|
|
61
|
+
}
|
|
62
|
+
interface UpdateStreamRequest {
|
|
63
|
+
streamId: string;
|
|
64
|
+
amount: string;
|
|
65
|
+
signature: string;
|
|
66
|
+
resourceUnits?: number;
|
|
67
|
+
}
|
|
68
|
+
interface CloseStreamRequest {
|
|
69
|
+
streamId: string;
|
|
70
|
+
finalAmount: string;
|
|
71
|
+
payerSignature: string;
|
|
72
|
+
payeeSignature?: string;
|
|
73
|
+
reason?: string;
|
|
74
|
+
}
|
|
75
|
+
interface ListStreamsParams {
|
|
76
|
+
network?: string;
|
|
77
|
+
payer?: string;
|
|
78
|
+
payee?: string;
|
|
79
|
+
status?: StreamStatus[];
|
|
80
|
+
limit?: number;
|
|
81
|
+
offset?: number;
|
|
82
|
+
orderBy?: string;
|
|
83
|
+
orderDesc?: boolean;
|
|
84
|
+
}
|
|
85
|
+
interface OpenStreamResponse {
|
|
86
|
+
stream: Stream;
|
|
87
|
+
depositAmount?: string;
|
|
88
|
+
depositTo?: string;
|
|
89
|
+
}
|
|
90
|
+
interface UpdateStreamResponse {
|
|
91
|
+
stream: Stream;
|
|
92
|
+
update: StreamUpdate;
|
|
93
|
+
remaining: string;
|
|
94
|
+
canContinue: boolean;
|
|
95
|
+
}
|
|
96
|
+
interface CloseStreamResponse {
|
|
97
|
+
stream: Stream;
|
|
98
|
+
settledAmount: string;
|
|
99
|
+
txHash: string;
|
|
100
|
+
refundAmount: string;
|
|
101
|
+
}
|
|
102
|
+
interface GetStreamResponse {
|
|
103
|
+
stream: Stream;
|
|
104
|
+
updates?: StreamUpdate[];
|
|
105
|
+
stats?: StreamStats;
|
|
106
|
+
}
|
|
107
|
+
interface ListStreamsResponse {
|
|
108
|
+
streams: Stream[];
|
|
109
|
+
total: number;
|
|
110
|
+
limit: number;
|
|
111
|
+
offset: number;
|
|
112
|
+
hasMore: boolean;
|
|
113
|
+
}
|
|
114
|
+
interface PauseResumeResponse {
|
|
115
|
+
status: string;
|
|
116
|
+
message: string;
|
|
117
|
+
}
|
|
118
|
+
interface StreamingClientConfig {
|
|
119
|
+
url?: string;
|
|
120
|
+
apiKey?: string;
|
|
121
|
+
requesterAddress?: string;
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* HTTP client for the t402 facilitator streaming API.
|
|
125
|
+
* Provides methods for managing payment streams.
|
|
126
|
+
*/
|
|
127
|
+
declare class StreamingClient {
|
|
128
|
+
readonly url: string;
|
|
129
|
+
private readonly apiKey?;
|
|
130
|
+
private readonly requesterAddress?;
|
|
131
|
+
constructor(config?: StreamingClientConfig);
|
|
132
|
+
/**
|
|
133
|
+
* Open a new payment stream
|
|
134
|
+
*/
|
|
135
|
+
openStream(params: OpenStreamRequest): Promise<OpenStreamResponse>;
|
|
136
|
+
/**
|
|
137
|
+
* Update a stream with a new cumulative amount
|
|
138
|
+
*/
|
|
139
|
+
updateStream(params: UpdateStreamRequest): Promise<UpdateStreamResponse>;
|
|
140
|
+
/**
|
|
141
|
+
* Close a stream and settle the final amount
|
|
142
|
+
*/
|
|
143
|
+
closeStream(params: CloseStreamRequest): Promise<CloseStreamResponse>;
|
|
144
|
+
/**
|
|
145
|
+
* Get stream details by ID
|
|
146
|
+
*/
|
|
147
|
+
getStream(id: string, options?: {
|
|
148
|
+
includeUpdates?: boolean;
|
|
149
|
+
includeStats?: boolean;
|
|
150
|
+
}): Promise<GetStreamResponse>;
|
|
151
|
+
/**
|
|
152
|
+
* Pause an active stream
|
|
153
|
+
*/
|
|
154
|
+
pauseStream(id: string): Promise<PauseResumeResponse>;
|
|
155
|
+
/**
|
|
156
|
+
* Resume a paused stream
|
|
157
|
+
*/
|
|
158
|
+
resumeStream(id: string): Promise<PauseResumeResponse>;
|
|
159
|
+
/**
|
|
160
|
+
* List streams with optional filters
|
|
161
|
+
*/
|
|
162
|
+
listStreams(filters?: ListStreamsParams): Promise<ListStreamsResponse>;
|
|
163
|
+
private buildHeaders;
|
|
164
|
+
private post;
|
|
165
|
+
private get;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
type IntentStatus = "pending" | "routed" | "executing" | "completed" | "failed" | "cancelled" | "expired";
|
|
169
|
+
type IntentPriority = "low" | "normal" | "high" | "urgent";
|
|
170
|
+
type RouteStepType = "transfer" | "swap" | "bridge" | "approve" | "wrap" | "unwrap";
|
|
171
|
+
interface RouteStep {
|
|
172
|
+
order: number;
|
|
173
|
+
type: RouteStepType;
|
|
174
|
+
network: string;
|
|
175
|
+
protocol?: string;
|
|
176
|
+
fromAsset: string;
|
|
177
|
+
toAsset: string;
|
|
178
|
+
fromAmount: string;
|
|
179
|
+
toAmount: string;
|
|
180
|
+
gasEstimate?: string;
|
|
181
|
+
data?: string;
|
|
182
|
+
}
|
|
183
|
+
interface Route {
|
|
184
|
+
id: string;
|
|
185
|
+
sourceNetwork: string;
|
|
186
|
+
targetNetwork: string;
|
|
187
|
+
sourceAsset: string;
|
|
188
|
+
targetAsset: string;
|
|
189
|
+
inputAmount: string;
|
|
190
|
+
outputAmount: string;
|
|
191
|
+
estimatedGas: string;
|
|
192
|
+
estimatedTime: number;
|
|
193
|
+
slippage: number;
|
|
194
|
+
score: number;
|
|
195
|
+
steps: RouteStep[];
|
|
196
|
+
requiresBridge: boolean;
|
|
197
|
+
bridgeProtocol?: string;
|
|
198
|
+
validUntil: string;
|
|
199
|
+
}
|
|
200
|
+
interface Intent {
|
|
201
|
+
id: string;
|
|
202
|
+
payer: string;
|
|
203
|
+
payee: string;
|
|
204
|
+
amount: string;
|
|
205
|
+
asset: string;
|
|
206
|
+
sourceNetworks?: string[];
|
|
207
|
+
targetNetwork?: string;
|
|
208
|
+
maxSlippage: number;
|
|
209
|
+
maxGasCost?: string;
|
|
210
|
+
priority: IntentPriority;
|
|
211
|
+
status: IntentStatus;
|
|
212
|
+
selectedRoute?: Route;
|
|
213
|
+
availableRoutes?: Route[];
|
|
214
|
+
createdAt: string;
|
|
215
|
+
expiresAt: string;
|
|
216
|
+
executedAt?: string;
|
|
217
|
+
txHashes?: string[];
|
|
218
|
+
errorMessage?: string;
|
|
219
|
+
metadata?: Record<string, string>;
|
|
220
|
+
}
|
|
221
|
+
interface CreateIntentRequest {
|
|
222
|
+
payer: string;
|
|
223
|
+
payee: string;
|
|
224
|
+
amount: string;
|
|
225
|
+
asset: string;
|
|
226
|
+
sourceNetworks?: string[];
|
|
227
|
+
targetNetwork?: string;
|
|
228
|
+
maxSlippage?: number;
|
|
229
|
+
maxGasCost?: string;
|
|
230
|
+
priority?: IntentPriority;
|
|
231
|
+
expiresIn?: number;
|
|
232
|
+
metadata?: Record<string, string>;
|
|
233
|
+
}
|
|
234
|
+
interface SelectRouteRequest {
|
|
235
|
+
routeId: string;
|
|
236
|
+
}
|
|
237
|
+
interface ExecuteIntentRequest {
|
|
238
|
+
signature: string;
|
|
239
|
+
routeId?: string;
|
|
240
|
+
}
|
|
241
|
+
interface CancelIntentRequest {
|
|
242
|
+
reason?: string;
|
|
243
|
+
}
|
|
244
|
+
interface ListIntentsParams {
|
|
245
|
+
payer?: string;
|
|
246
|
+
payee?: string;
|
|
247
|
+
status?: IntentStatus[];
|
|
248
|
+
limit?: number;
|
|
249
|
+
offset?: number;
|
|
250
|
+
}
|
|
251
|
+
interface CreateIntentResponse {
|
|
252
|
+
intent: Intent;
|
|
253
|
+
availableRoutes: Route[];
|
|
254
|
+
recommendedRoute?: Route;
|
|
255
|
+
}
|
|
256
|
+
interface SelectRouteResponse {
|
|
257
|
+
intent: Intent;
|
|
258
|
+
selectedRoute: Route;
|
|
259
|
+
}
|
|
260
|
+
interface ExecuteIntentResponse {
|
|
261
|
+
intent: Intent;
|
|
262
|
+
txHashes: string[];
|
|
263
|
+
status: string;
|
|
264
|
+
message?: string;
|
|
265
|
+
}
|
|
266
|
+
interface GetIntentResponse {
|
|
267
|
+
intent: Intent;
|
|
268
|
+
}
|
|
269
|
+
interface ListIntentsResponse {
|
|
270
|
+
intents: Intent[];
|
|
271
|
+
total: number;
|
|
272
|
+
limit: number;
|
|
273
|
+
offset: number;
|
|
274
|
+
hasMore: boolean;
|
|
275
|
+
}
|
|
276
|
+
interface CancelIntentResponse {
|
|
277
|
+
status: string;
|
|
278
|
+
message: string;
|
|
279
|
+
}
|
|
280
|
+
interface RefreshRoutesResponse {
|
|
281
|
+
intent: Intent;
|
|
282
|
+
availableRoutes: Route[];
|
|
283
|
+
recommendedRoute?: Route;
|
|
284
|
+
}
|
|
285
|
+
type IntentStats = Record<string, number>;
|
|
286
|
+
interface IntentClientConfig {
|
|
287
|
+
url?: string;
|
|
288
|
+
apiKey?: string;
|
|
289
|
+
}
|
|
290
|
+
/**
|
|
291
|
+
* HTTP client for the t402 facilitator intent API.
|
|
292
|
+
* Provides methods for creating and managing cross-chain payment intents.
|
|
293
|
+
*/
|
|
294
|
+
declare class IntentClient {
|
|
295
|
+
readonly url: string;
|
|
296
|
+
private readonly apiKey?;
|
|
297
|
+
constructor(config?: IntentClientConfig);
|
|
298
|
+
/**
|
|
299
|
+
* Create a new payment intent and get available routes
|
|
300
|
+
*/
|
|
301
|
+
createIntent(params: CreateIntentRequest): Promise<CreateIntentResponse>;
|
|
302
|
+
/**
|
|
303
|
+
* Get intent details by ID
|
|
304
|
+
*/
|
|
305
|
+
getIntent(id: string): Promise<GetIntentResponse>;
|
|
306
|
+
/**
|
|
307
|
+
* Select a route for an intent
|
|
308
|
+
*/
|
|
309
|
+
selectRoute(id: string, params: SelectRouteRequest): Promise<SelectRouteResponse>;
|
|
310
|
+
/**
|
|
311
|
+
* Execute an intent with a signed authorization
|
|
312
|
+
*/
|
|
313
|
+
executeIntent(id: string, params: ExecuteIntentRequest): Promise<ExecuteIntentResponse>;
|
|
314
|
+
/**
|
|
315
|
+
* Cancel a pending intent
|
|
316
|
+
*/
|
|
317
|
+
cancelIntent(id: string, params?: CancelIntentRequest): Promise<CancelIntentResponse>;
|
|
318
|
+
/**
|
|
319
|
+
* Refresh available routes for an intent
|
|
320
|
+
*/
|
|
321
|
+
refreshRoutes(id: string): Promise<RefreshRoutesResponse>;
|
|
322
|
+
/**
|
|
323
|
+
* List intents with optional filters
|
|
324
|
+
*/
|
|
325
|
+
listIntents(filters?: ListIntentsParams): Promise<ListIntentsResponse>;
|
|
326
|
+
/**
|
|
327
|
+
* Get intent statistics (counts by status)
|
|
328
|
+
*/
|
|
329
|
+
getIntentStats(): Promise<IntentStats>;
|
|
330
|
+
private buildHeaders;
|
|
331
|
+
private post;
|
|
332
|
+
private get;
|
|
333
|
+
}
|
|
334
|
+
|
|
6
335
|
type QueryParamMethods = "GET" | "HEAD" | "DELETE";
|
|
7
336
|
type BodyMethods = "POST" | "PUT" | "PATCH";
|
|
8
337
|
/**
|
|
@@ -56,4 +385,4 @@ declare function encodePaymentResponseHeader(paymentResponse: SettleResponse & {
|
|
|
56
385
|
*/
|
|
57
386
|
declare function decodePaymentResponseHeader(paymentResponseHeader: string): SettleResponse;
|
|
58
387
|
|
|
59
|
-
export { type BodyMethods, type QueryParamMethods, decodePaymentRequiredHeader, decodePaymentResponseHeader, decodePaymentSignatureHeader, encodePaymentRequiredHeader, encodePaymentResponseHeader, encodePaymentSignatureHeader };
|
|
388
|
+
export { type BodyMethods, type CancelIntentRequest, type CancelIntentResponse, type CloseStreamRequest, type CloseStreamResponse, type CreateIntentRequest, type CreateIntentResponse, type ExecuteIntentRequest, type ExecuteIntentResponse, type GetIntentResponse, type GetStreamResponse, type Intent, IntentClient, type IntentClientConfig, type IntentPriority, type IntentStats, type IntentStatus, type ListIntentsParams, type ListIntentsResponse, type ListStreamsParams, type ListStreamsResponse, type OpenStreamRequest, type OpenStreamResponse, type PauseResumeResponse, type QueryParamMethods, type RefreshRoutesResponse, type Route, type RouteStep, type RouteStepType, type SelectRouteRequest, type SelectRouteResponse, type Stream, type StreamMetadata, type StreamStats, type StreamStatus, type StreamUpdate, StreamingClient, type StreamingClientConfig, type UpdateStreamRequest, type UpdateStreamResponse, decodePaymentRequiredHeader, decodePaymentResponseHeader, decodePaymentSignatureHeader, encodePaymentRequiredHeader, encodePaymentResponseHeader, encodePaymentSignatureHeader };
|
package/dist/esm/http/index.mjs
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
2
|
HTTPFacilitatorClient,
|
|
3
|
+
IntentClient,
|
|
3
4
|
RouteConfigurationError,
|
|
5
|
+
StreamingClient,
|
|
4
6
|
decodePaymentRequiredHeader,
|
|
5
7
|
decodePaymentResponseHeader,
|
|
6
8
|
decodePaymentSignatureHeader,
|
|
@@ -9,14 +11,16 @@ import {
|
|
|
9
11
|
encodePaymentSignatureHeader,
|
|
10
12
|
t402HTTPClient,
|
|
11
13
|
t402HTTPResourceServer
|
|
12
|
-
} from "../chunk-
|
|
14
|
+
} from "../chunk-4DIIUML6.mjs";
|
|
13
15
|
import "../chunk-YM7W5RG3.mjs";
|
|
14
16
|
import "../chunk-STKQDKUH.mjs";
|
|
15
17
|
import "../chunk-LJ4M5Z5U.mjs";
|
|
16
18
|
import "../chunk-4W2Y3RJM.mjs";
|
|
17
19
|
export {
|
|
18
20
|
HTTPFacilitatorClient,
|
|
21
|
+
IntentClient,
|
|
19
22
|
RouteConfigurationError,
|
|
23
|
+
StreamingClient,
|
|
20
24
|
decodePaymentRequiredHeader,
|
|
21
25
|
decodePaymentResponseHeader,
|
|
22
26
|
decodePaymentSignatureHeader,
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { C as CompiledRoute, F as FacilitatorClient, b as FacilitatorConfig, H as HTTPAdapter, c as HTTPFacilitatorClient, d as HTTPProcessResult, e as HTTPRequestContext, f as HTTPResponseInstructions, g as PaywallConfig, h as PaywallProvider, i as ProcessSettleFailureResponse, j as ProcessSettleResultResponse, k as ProcessSettleSuccessResponse, p as ResourceConfig, q as ResourceInfo, R as RouteConfig, l as RouteConfigurationError, m as RouteValidationError, n as RoutesConfig, U as UnpaidResponseBody, o as UnpaidResponseResult, t as t402HTTPResourceServer, r as t402ResourceServer } from '../t402HTTPResourceServer-
|
|
1
|
+
export { C as CompiledRoute, F as FacilitatorClient, b as FacilitatorConfig, H as HTTPAdapter, c as HTTPFacilitatorClient, d as HTTPProcessResult, e as HTTPRequestContext, f as HTTPResponseInstructions, g as PaywallConfig, h as PaywallProvider, i as ProcessSettleFailureResponse, j as ProcessSettleResultResponse, k as ProcessSettleSuccessResponse, p as ResourceConfig, q as ResourceInfo, R as RouteConfig, l as RouteConfigurationError, m as RouteValidationError, n as RoutesConfig, S as SettleOptions, U as UnpaidResponseBody, o as UnpaidResponseResult, t as t402HTTPResourceServer, r as t402ResourceServer } from '../t402HTTPResourceServer-Jmmvy9kc.mjs';
|
|
2
2
|
import '../mechanisms-dYCiYgko.mjs';
|
|
3
3
|
import 'zod';
|
package/dist/esm/{t402HTTPResourceServer-DDxVMmS2.d.mts → t402HTTPResourceServer-Jmmvy9kc.d.mts}
RENAMED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import { a as PaymentPayload, P as PaymentRequirements, V as VerifyResponse, S as SettleResponse, e as SupportedResponse, N as Network, f as SchemeNetworkServer, R as ResourceServerExtension, g as SupportedKind, h as Price, c as PaymentRequired } from './mechanisms-dYCiYgko.mjs';
|
|
2
2
|
|
|
3
|
+
interface SettleOptions {
|
|
4
|
+
/** Optional idempotency key for replay protection */
|
|
5
|
+
idempotencyKey?: string;
|
|
6
|
+
}
|
|
3
7
|
interface FacilitatorConfig {
|
|
4
8
|
url?: string;
|
|
5
9
|
createAuthHeaders?: () => Promise<{
|
|
@@ -26,9 +30,10 @@ interface FacilitatorClient {
|
|
|
26
30
|
*
|
|
27
31
|
* @param paymentPayload - The payment to settle
|
|
28
32
|
* @param paymentRequirements - The requirements for settlement
|
|
33
|
+
* @param options - Optional settings including idempotency key
|
|
29
34
|
* @returns Settlement response
|
|
30
35
|
*/
|
|
31
|
-
settle(paymentPayload: PaymentPayload, paymentRequirements: PaymentRequirements): Promise<SettleResponse>;
|
|
36
|
+
settle(paymentPayload: PaymentPayload, paymentRequirements: PaymentRequirements, options?: SettleOptions): Promise<SettleResponse>;
|
|
32
37
|
/**
|
|
33
38
|
* Get supported payment kinds and extensions from the facilitator
|
|
34
39
|
*
|
|
@@ -62,9 +67,10 @@ declare class HTTPFacilitatorClient implements FacilitatorClient {
|
|
|
62
67
|
*
|
|
63
68
|
* @param paymentPayload - The payment to settle
|
|
64
69
|
* @param paymentRequirements - The requirements for settlement
|
|
70
|
+
* @param options - Optional settings including idempotency key
|
|
65
71
|
* @returns Settlement response
|
|
66
72
|
*/
|
|
67
|
-
settle(paymentPayload: PaymentPayload, paymentRequirements: PaymentRequirements): Promise<SettleResponse>;
|
|
73
|
+
settle(paymentPayload: PaymentPayload, paymentRequirements: PaymentRequirements, options?: SettleOptions): Promise<SettleResponse>;
|
|
68
74
|
/**
|
|
69
75
|
* Get supported payment kinds and extensions from the facilitator
|
|
70
76
|
*
|
|
@@ -715,4 +721,4 @@ declare class t402HTTPResourceServer {
|
|
|
715
721
|
private getDisplayAmount;
|
|
716
722
|
}
|
|
717
723
|
|
|
718
|
-
export { type CompiledRoute as C, type DynamicPayTo as D, type FacilitatorClient as F, type HTTPAdapter as H, type PaymentOption as P, type RouteConfig as R, type UnpaidResponseBody as U, type DynamicPrice as a, type FacilitatorConfig as b, HTTPFacilitatorClient as c, type HTTPProcessResult as d, type HTTPRequestContext as e, type HTTPResponseInstructions as f, type PaywallConfig as g, type PaywallProvider as h, type ProcessSettleFailureResponse as i, type ProcessSettleResultResponse as j, type ProcessSettleSuccessResponse as k, RouteConfigurationError as l, type RouteValidationError as m, type RoutesConfig as n, type UnpaidResponseResult as o, type ResourceConfig as p, type ResourceInfo as q, t402ResourceServer as r, t402HTTPResourceServer as t };
|
|
724
|
+
export { type CompiledRoute as C, type DynamicPayTo as D, type FacilitatorClient as F, type HTTPAdapter as H, type PaymentOption as P, type RouteConfig as R, type SettleOptions as S, type UnpaidResponseBody as U, type DynamicPrice as a, type FacilitatorConfig as b, HTTPFacilitatorClient as c, type HTTPProcessResult as d, type HTTPRequestContext as e, type HTTPResponseInstructions as f, type PaywallConfig as g, type PaywallProvider as h, type ProcessSettleFailureResponse as i, type ProcessSettleResultResponse as j, type ProcessSettleSuccessResponse as k, RouteConfigurationError as l, type RouteValidationError as m, type RoutesConfig as n, type UnpaidResponseResult as o, type ResourceConfig as p, type ResourceInfo as q, t402ResourceServer as r, t402HTTPResourceServer as t };
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/http/t402HTTPResourceServer.ts","../../src/http/httpFacilitatorClient.ts","../../src/http/t402HTTPClient.ts","../../src/http/index.ts"],"sourcesContent":["import { t402ResourceServer } from \"../server\";\nimport {\n decodePaymentSignatureHeader,\n encodePaymentRequiredHeader,\n encodePaymentResponseHeader,\n} from \".\";\nimport {\n PaymentPayload,\n PaymentRequired,\n SettleResponse,\n Price,\n Network,\n PaymentRequirements,\n} from \"../types\";\nimport { t402Version } from \"..\";\n\n/**\n * Framework-agnostic HTTP adapter interface\n * Implementations provide framework-specific HTTP operations\n */\nexport interface HTTPAdapter {\n getHeader(name: string): string | undefined;\n getMethod(): string;\n getPath(): string;\n getUrl(): string;\n getAcceptHeader(): string;\n getUserAgent(): string;\n\n /**\n * Get query parameters from the request URL\n *\n * @returns Record of query parameter key-value pairs\n */\n getQueryParams?(): Record<string, string | string[]>;\n\n /**\n * Get a specific query parameter by name\n *\n * @param name - The query parameter name\n * @returns The query parameter value(s) or undefined\n */\n getQueryParam?(name: string): string | string[] | undefined;\n\n /**\n * Get the parsed request body\n * Framework adapters should parse JSON/form data appropriately\n *\n * @returns The parsed request body\n */\n getBody?(): unknown;\n}\n\n/**\n * Paywall configuration for HTML responses\n */\nexport interface PaywallConfig {\n appName?: string;\n appLogo?: string;\n sessionTokenEndpoint?: string;\n currentUrl?: string;\n testnet?: boolean;\n}\n\n/**\n * Paywall provider interface for generating HTML\n */\nexport interface PaywallProvider {\n generateHtml(paymentRequired: PaymentRequired, config?: PaywallConfig): string;\n}\n\n/**\n * Dynamic payTo function that receives HTTP request context\n */\nexport type DynamicPayTo = (context: HTTPRequestContext) => string | Promise<string>;\n\n/**\n * Dynamic price function that receives HTTP request context\n */\nexport type DynamicPrice = (context: HTTPRequestContext) => Price | Promise<Price>;\n\n/**\n * Result of the unpaid response callback containing content type and body.\n */\nexport interface UnpaidResponseResult {\n /**\n * The content type for the response (e.g., 'application/json', 'text/plain').\n */\n contentType: string;\n\n /**\n * The response body to include in the 402 response.\n */\n body: unknown;\n}\n\n/**\n * Dynamic function to generate a custom response for unpaid requests.\n * Receives the HTTP request context and returns the content type and body to include in the 402 response.\n */\nexport type UnpaidResponseBody = (\n context: HTTPRequestContext,\n) => UnpaidResponseResult | Promise<UnpaidResponseResult>;\n\n/**\n * A single payment option for a route\n * Represents one way a client can pay for access to the resource\n */\nexport interface PaymentOption {\n scheme: string;\n payTo: string | DynamicPayTo;\n price: Price | DynamicPrice;\n network: Network;\n maxTimeoutSeconds?: number;\n extra?: Record<string, unknown>;\n}\n\n/**\n * Route configuration for HTTP endpoints\n *\n * The 'accepts' field defines payment options for the route.\n * Can be a single PaymentOption or an array of PaymentOptions for multiple payment methods.\n */\nexport interface RouteConfig {\n // Payment option(s): single or array\n accepts: PaymentOption | PaymentOption[];\n\n // HTTP-specific metadata\n resource?: string;\n description?: string;\n mimeType?: string;\n customPaywallHtml?: string;\n\n /**\n * Optional callback to generate a custom response for unpaid API requests.\n * This allows servers to return preview data, error messages, or other content\n * when a request lacks payment.\n *\n * For browser requests (Accept: text/html), the paywall HTML takes precedence.\n * This callback is only used for API clients.\n *\n * If not provided, defaults to { contentType: 'application/json', body: {} }.\n *\n * @returns An object containing both contentType and body for the 402 response\n */\n unpaidResponseBody?: UnpaidResponseBody;\n\n // Extensions\n extensions?: Record<string, unknown>;\n}\n\n/**\n * Routes configuration - maps path patterns to route configs\n */\nexport type RoutesConfig = Record<string, RouteConfig> | RouteConfig;\n\n/**\n * Compiled route for efficient matching\n */\nexport interface CompiledRoute {\n verb: string;\n regex: RegExp;\n config: RouteConfig;\n}\n\n/**\n * HTTP request context that encapsulates all request data\n */\nexport interface HTTPRequestContext {\n adapter: HTTPAdapter;\n path: string;\n method: string;\n paymentHeader?: string;\n}\n\n/**\n * HTTP response instructions for the framework middleware\n */\nexport interface HTTPResponseInstructions {\n status: number;\n headers: Record<string, string>;\n body?: unknown; // e.g. Paywall for web browser requests, but could be any other type\n isHtml?: boolean; // e.g. if body is a paywall, then isHtml is true\n}\n\n/**\n * Result of processing an HTTP request for payment\n */\nexport type HTTPProcessResult =\n | { type: \"no-payment-required\" }\n | {\n type: \"payment-verified\";\n paymentPayload: PaymentPayload;\n paymentRequirements: PaymentRequirements;\n }\n | { type: \"payment-error\"; response: HTTPResponseInstructions };\n\n/**\n * Result of processSettlement\n */\nexport type ProcessSettleSuccessResponse = SettleResponse & {\n success: true;\n headers: Record<string, string>;\n requirements: PaymentRequirements;\n};\n\nexport type ProcessSettleFailureResponse = SettleResponse & {\n success: false;\n errorReason: string;\n};\n\nexport type ProcessSettleResultResponse =\n | ProcessSettleSuccessResponse\n | ProcessSettleFailureResponse;\n\n/**\n * Represents a validation error for a specific route's payment configuration.\n */\nexport interface RouteValidationError {\n /** The route pattern (e.g., \"GET /api/weather\") */\n routePattern: string;\n /** The payment scheme that failed validation */\n scheme: string;\n /** The network that failed validation */\n network: Network;\n /** The type of validation failure */\n reason: \"missing_scheme\" | \"missing_facilitator\";\n /** Human-readable error message */\n message: string;\n}\n\n/**\n * Error thrown when route configuration validation fails.\n */\nexport class RouteConfigurationError extends Error {\n /** The validation errors that caused this exception */\n public readonly errors: RouteValidationError[];\n\n /**\n * Creates a new RouteConfigurationError with the given validation errors.\n *\n * @param errors - The validation errors that caused this exception.\n */\n constructor(errors: RouteValidationError[]) {\n const message = `t402 Route Configuration Errors:\\n${errors.map(e => ` - ${e.message}`).join(\"\\n\")}`;\n super(message);\n this.name = \"RouteConfigurationError\";\n this.errors = errors;\n }\n}\n\n/**\n * HTTP-enhanced t402 resource server\n * Provides framework-agnostic HTTP protocol handling\n */\nexport class t402HTTPResourceServer {\n private ResourceServer: t402ResourceServer;\n private compiledRoutes: CompiledRoute[] = [];\n private routesConfig: RoutesConfig;\n private paywallProvider?: PaywallProvider;\n\n /**\n * Creates a new t402HTTPResourceServer instance.\n *\n * @param ResourceServer - The core t402ResourceServer instance to use\n * @param routes - Route configuration for payment-protected endpoints\n */\n constructor(ResourceServer: t402ResourceServer, routes: RoutesConfig) {\n this.ResourceServer = ResourceServer;\n this.routesConfig = routes;\n\n // Handle both single route and multiple routes\n const normalizedRoutes =\n typeof routes === \"object\" && !(\"accepts\" in routes)\n ? (routes as Record<string, RouteConfig>)\n : { \"*\": routes as RouteConfig };\n\n for (const [pattern, config] of Object.entries(normalizedRoutes)) {\n const parsed = this.parseRoutePattern(pattern);\n this.compiledRoutes.push({\n verb: parsed.verb,\n regex: parsed.regex,\n config,\n });\n }\n }\n\n /**\n * Initialize the HTTP resource server.\n *\n * This method initializes the underlying resource server (fetching facilitator support)\n * and then validates that all route payment configurations have corresponding\n * registered schemes and facilitator support.\n *\n * @throws RouteConfigurationError if any route's payment options don't have\n * corresponding registered schemes or facilitator support\n *\n * @example\n * ```typescript\n * const httpServer = new t402HTTPResourceServer(server, routes);\n * await httpServer.initialize();\n * ```\n */\n async initialize(): Promise<void> {\n // First, initialize the underlying resource server (fetches facilitator support)\n await this.ResourceServer.initialize();\n\n // Then validate route configuration\n const errors = this.validateRouteConfiguration();\n if (errors.length > 0) {\n throw new RouteConfigurationError(errors);\n }\n }\n\n /**\n * Register a custom paywall provider for generating HTML\n *\n * @param provider - PaywallProvider instance\n * @returns This service instance for chaining\n */\n registerPaywallProvider(provider: PaywallProvider): this {\n this.paywallProvider = provider;\n return this;\n }\n\n /**\n * Process HTTP request and return response instructions\n * This is the main entry point for framework middleware\n *\n * @param context - HTTP request context\n * @param paywallConfig - Optional paywall configuration\n * @returns Process result indicating next action for middleware\n */\n async processHTTPRequest(\n context: HTTPRequestContext,\n paywallConfig?: PaywallConfig,\n ): Promise<HTTPProcessResult> {\n const { adapter, path, method } = context;\n\n // Find matching route\n const routeConfig = this.getRouteConfig(path, method);\n if (!routeConfig) {\n return { type: \"no-payment-required\" }; // No payment required for this route\n }\n\n // Normalize accepts field to array of payment options\n const paymentOptions = this.normalizePaymentOptions(routeConfig);\n\n // Check for payment header (v1 or v2)\n const paymentPayload = this.extractPayment(adapter);\n\n // Create resource info, using config override if provided\n const resourceInfo = {\n url: routeConfig.resource || context.adapter.getUrl(),\n description: routeConfig.description || \"\",\n mimeType: routeConfig.mimeType || \"\",\n };\n\n // Build requirements from all payment options\n // (this method handles resolving dynamic functions internally)\n const requirements = await this.ResourceServer.buildPaymentRequirementsFromOptions(\n paymentOptions,\n context,\n );\n\n let extensions = routeConfig.extensions;\n if (extensions) {\n extensions = this.ResourceServer.enrichExtensions(extensions, context);\n }\n\n const paymentRequired = this.ResourceServer.createPaymentRequiredResponse(\n requirements,\n resourceInfo,\n !paymentPayload ? \"Payment required\" : undefined,\n extensions,\n );\n\n // If no payment provided\n if (!paymentPayload) {\n // Resolve custom unpaid response body if provided\n const unpaidBody = routeConfig.unpaidResponseBody\n ? await routeConfig.unpaidResponseBody(context)\n : undefined;\n\n return {\n type: \"payment-error\",\n response: this.createHTTPResponse(\n paymentRequired,\n this.isWebBrowser(adapter),\n paywallConfig,\n routeConfig.customPaywallHtml,\n unpaidBody,\n ),\n };\n }\n\n // Verify payment\n try {\n const matchingRequirements = this.ResourceServer.findMatchingRequirements(\n paymentRequired.accepts,\n paymentPayload,\n );\n\n if (!matchingRequirements) {\n const errorResponse = this.ResourceServer.createPaymentRequiredResponse(\n requirements,\n resourceInfo,\n \"No matching payment requirements\",\n routeConfig.extensions,\n );\n return {\n type: \"payment-error\",\n response: this.createHTTPResponse(errorResponse, false, paywallConfig),\n };\n }\n\n const verifyResult = await this.ResourceServer.verifyPayment(\n paymentPayload,\n matchingRequirements,\n );\n\n if (!verifyResult.isValid) {\n const errorResponse = this.ResourceServer.createPaymentRequiredResponse(\n requirements,\n resourceInfo,\n verifyResult.invalidReason,\n routeConfig.extensions,\n );\n return {\n type: \"payment-error\",\n response: this.createHTTPResponse(errorResponse, false, paywallConfig),\n };\n }\n\n // Payment is valid, return data needed for settlement\n return {\n type: \"payment-verified\",\n paymentPayload,\n paymentRequirements: matchingRequirements,\n };\n } catch (error) {\n const errorResponse = this.ResourceServer.createPaymentRequiredResponse(\n requirements,\n resourceInfo,\n error instanceof Error ? error.message : \"Payment verification failed\",\n routeConfig.extensions,\n );\n return {\n type: \"payment-error\",\n response: this.createHTTPResponse(errorResponse, false, paywallConfig),\n };\n }\n }\n\n /**\n * Process settlement after successful response\n *\n * @param paymentPayload - The verified payment payload\n * @param requirements - The matching payment requirements\n * @returns ProcessSettleResultResponse - SettleResponse with headers if success or errorReason if failure\n */\n async processSettlement(\n paymentPayload: PaymentPayload,\n requirements: PaymentRequirements,\n ): Promise<ProcessSettleResultResponse> {\n try {\n const settleResponse = await this.ResourceServer.settlePayment(paymentPayload, requirements);\n\n if (!settleResponse.success) {\n return {\n ...settleResponse,\n success: false,\n errorReason: settleResponse.errorReason || \"Settlement failed\",\n };\n }\n\n return {\n ...settleResponse,\n success: true,\n headers: this.createSettlementHeaders(settleResponse, requirements),\n requirements,\n };\n } catch (error) {\n throw new Error(error instanceof Error ? error.message : \"Settlement failed\");\n }\n }\n\n /**\n * Check if a request requires payment based on route configuration\n *\n * @param context - HTTP request context\n * @returns True if the route requires payment, false otherwise\n */\n requiresPayment(context: HTTPRequestContext): boolean {\n const routeConfig = this.getRouteConfig(context.path, context.method);\n return routeConfig !== undefined;\n }\n\n /**\n * Normalizes a RouteConfig's accepts field into an array of PaymentOptions\n * Handles both single PaymentOption and array formats\n *\n * @param routeConfig - Route configuration\n * @returns Array of payment options\n */\n private normalizePaymentOptions(routeConfig: RouteConfig): PaymentOption[] {\n return Array.isArray(routeConfig.accepts) ? routeConfig.accepts : [routeConfig.accepts];\n }\n\n /**\n * Validates that all payment options in routes have corresponding registered schemes\n * and facilitator support.\n *\n * @returns Array of validation errors (empty if all routes are valid)\n */\n private validateRouteConfiguration(): RouteValidationError[] {\n const errors: RouteValidationError[] = [];\n\n // Normalize routes to array of [pattern, config] pairs\n const normalizedRoutes =\n typeof this.routesConfig === \"object\" && !(\"accepts\" in this.routesConfig)\n ? Object.entries(this.routesConfig as Record<string, RouteConfig>)\n : [[\"*\", this.routesConfig as RouteConfig] as [string, RouteConfig]];\n\n for (const [pattern, config] of normalizedRoutes) {\n const paymentOptions = this.normalizePaymentOptions(config);\n\n for (const option of paymentOptions) {\n // Check 1: Is scheme registered?\n if (!this.ResourceServer.hasRegisteredScheme(option.network, option.scheme)) {\n errors.push({\n routePattern: pattern,\n scheme: option.scheme,\n network: option.network,\n reason: \"missing_scheme\",\n message: `Route \"${pattern}\": No scheme implementation registered for \"${option.scheme}\" on network \"${option.network}\"`,\n });\n // Skip facilitator check if scheme isn't registered\n continue;\n }\n\n // Check 2: Does facilitator support this scheme/network combination?\n const supportedKind = this.ResourceServer.getSupportedKind(\n t402Version,\n option.network,\n option.scheme,\n );\n\n if (!supportedKind) {\n errors.push({\n routePattern: pattern,\n scheme: option.scheme,\n network: option.network,\n reason: \"missing_facilitator\",\n message: `Route \"${pattern}\": Facilitator does not support scheme \"${option.scheme}\" on network \"${option.network}\"`,\n });\n }\n }\n }\n\n return errors;\n }\n\n /**\n * Get route configuration for a request\n *\n * @param path - Request path\n * @param method - HTTP method\n * @returns Route configuration or undefined if no match\n */\n private getRouteConfig(path: string, method: string): RouteConfig | undefined {\n const normalizedPath = this.normalizePath(path);\n const upperMethod = method.toUpperCase();\n\n const matchingRoute = this.compiledRoutes.find(\n route =>\n route.regex.test(normalizedPath) && (route.verb === \"*\" || route.verb === upperMethod),\n );\n\n return matchingRoute?.config;\n }\n\n /**\n * Extract payment from HTTP headers (handles v1 and v2)\n *\n * @param adapter - HTTP adapter\n * @returns Decoded payment payload or null\n */\n private extractPayment(adapter: HTTPAdapter): PaymentPayload | null {\n // Check v2 header first (PAYMENT-SIGNATURE), then v1 fallback (X-PAYMENT)\n const header =\n adapter.getHeader(\"payment-signature\") ||\n adapter.getHeader(\"PAYMENT-SIGNATURE\") ||\n adapter.getHeader(\"x-payment\") ||\n adapter.getHeader(\"X-PAYMENT\");\n\n if (header) {\n try {\n return decodePaymentSignatureHeader(header);\n } catch (error) {\n console.warn(\"Failed to decode payment header:\", error);\n }\n }\n\n return null;\n }\n\n /**\n * Check if request is from a web browser\n *\n * @param adapter - HTTP adapter\n * @returns True if request appears to be from a browser\n */\n private isWebBrowser(adapter: HTTPAdapter): boolean {\n const accept = adapter.getAcceptHeader();\n const userAgent = adapter.getUserAgent();\n return accept.includes(\"text/html\") && userAgent.includes(\"Mozilla\");\n }\n\n /**\n * Create HTTP response instructions from payment required\n *\n * @param paymentRequired - Payment requirements\n * @param isWebBrowser - Whether request is from browser\n * @param paywallConfig - Paywall configuration\n * @param customHtml - Custom HTML template\n * @param unpaidResponse - Optional custom response (content type and body) for unpaid API requests\n * @returns Response instructions\n */\n private createHTTPResponse(\n paymentRequired: PaymentRequired,\n isWebBrowser: boolean,\n paywallConfig?: PaywallConfig,\n customHtml?: string,\n unpaidResponse?: UnpaidResponseResult,\n ): HTTPResponseInstructions {\n if (isWebBrowser) {\n const html = this.generatePaywallHTML(paymentRequired, paywallConfig, customHtml);\n return {\n status: 402,\n headers: { \"Content-Type\": \"text/html\" },\n body: html,\n isHtml: true,\n };\n }\n\n const response = this.createHTTPPaymentRequiredResponse(paymentRequired);\n\n // Use callback result if provided, otherwise default to JSON with empty object\n const contentType = unpaidResponse ? unpaidResponse.contentType : \"application/json\";\n const body = unpaidResponse ? unpaidResponse.body : {};\n\n return {\n status: 402,\n headers: {\n \"Content-Type\": contentType,\n ...response.headers,\n },\n body,\n };\n }\n\n /**\n * Create HTTP payment required response (v1 puts in body, v2 puts in header)\n *\n * @param paymentRequired - Payment required object\n * @returns Headers and body for the HTTP response\n */\n private createHTTPPaymentRequiredResponse(paymentRequired: PaymentRequired): {\n headers: Record<string, string>;\n } {\n return {\n headers: {\n \"PAYMENT-REQUIRED\": encodePaymentRequiredHeader(paymentRequired),\n },\n };\n }\n\n /**\n * Create settlement response headers\n *\n * @param settleResponse - Settlement response\n * @param requirements - Payment requirements that were settled\n * @returns Headers to add to response\n */\n private createSettlementHeaders(\n settleResponse: SettleResponse,\n requirements: PaymentRequirements,\n ): Record<string, string> {\n const encoded = encodePaymentResponseHeader({\n ...settleResponse,\n requirements,\n });\n return { \"PAYMENT-RESPONSE\": encoded };\n }\n\n /**\n * Parse route pattern into verb and regex\n *\n * @param pattern - Route pattern like \"GET /api/*\" or \"/api/[id]\"\n * @returns Parsed pattern with verb and regex\n */\n private parseRoutePattern(pattern: string): { verb: string; regex: RegExp } {\n const [verb, path] = pattern.includes(\" \") ? pattern.split(/\\s+/) : [\"*\", pattern];\n\n const regex = new RegExp(\n `^${\n path\n .replace(/[$()+.?^{|}]/g, \"\\\\$&\") // Escape regex special chars\n .replace(/\\*/g, \".*?\") // Wildcards\n .replace(/\\[([^\\]]+)\\]/g, \"[^/]+\") // Parameters\n .replace(/\\//g, \"\\\\/\") // Escape slashes\n }$`,\n \"i\",\n );\n\n return { verb: verb.toUpperCase(), regex };\n }\n\n /**\n * Normalize path for matching\n *\n * @param path - Raw path from request\n * @returns Normalized path\n */\n private normalizePath(path: string): string {\n try {\n const pathWithoutQuery = path.split(/[?#]/)[0];\n const decodedPath = decodeURIComponent(pathWithoutQuery);\n return decodedPath\n .replace(/\\\\/g, \"/\")\n .replace(/\\/+/g, \"/\")\n .replace(/(.+?)\\/+$/, \"$1\");\n } catch {\n return path;\n }\n }\n\n /**\n * Generate paywall HTML for browser requests\n *\n * @param paymentRequired - Payment required response\n * @param paywallConfig - Optional paywall configuration\n * @param customHtml - Optional custom HTML template\n * @returns HTML string\n */\n private generatePaywallHTML(\n paymentRequired: PaymentRequired,\n paywallConfig?: PaywallConfig,\n customHtml?: string,\n ): string {\n if (customHtml) {\n return customHtml;\n }\n\n // Use custom paywall provider if set\n if (this.paywallProvider) {\n return this.paywallProvider.generateHtml(paymentRequired, paywallConfig);\n }\n\n // Try to use @t402/paywall if available (optional dependency)\n try {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const paywall = require(\"@t402/paywall\");\n const displayAmount = this.getDisplayAmount(paymentRequired);\n const resource = paymentRequired.resource;\n\n return paywall.getPaywallHtml({\n amount: displayAmount,\n paymentRequired,\n currentUrl: resource?.url || paywallConfig?.currentUrl || \"\",\n testnet: paywallConfig?.testnet ?? true,\n appName: paywallConfig?.appName,\n appLogo: paywallConfig?.appLogo,\n sessionTokenEndpoint: paywallConfig?.sessionTokenEndpoint,\n });\n } catch {\n // @t402/paywall not installed, fall back to basic HTML\n }\n\n // Fallback: Basic HTML paywall\n const resource = paymentRequired.resource;\n const displayAmount = this.getDisplayAmount(paymentRequired);\n\n return `\n <!DOCTYPE html>\n <html>\n <head>\n <title>Payment Required</title>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n </head>\n <body>\n <div style=\"max-width: 600px; margin: 50px auto; padding: 20px; font-family: system-ui, -apple-system, sans-serif;\">\n ${paywallConfig?.appLogo ? `<img src=\"${paywallConfig.appLogo}\" alt=\"${paywallConfig.appName || \"App\"}\" style=\"max-width: 200px; margin-bottom: 20px;\">` : \"\"}\n <h1>Payment Required</h1>\n ${resource ? `<p><strong>Resource:</strong> ${resource.description || resource.url}</p>` : \"\"}\n <p><strong>Amount:</strong> $${displayAmount.toFixed(2)} USDC</p>\n <div id=\"payment-widget\" \n data-requirements='${JSON.stringify(paymentRequired)}'\n data-app-name=\"${paywallConfig?.appName || \"\"}\"\n data-testnet=\"${paywallConfig?.testnet || false}\">\n <!-- Install @t402/paywall for full wallet integration -->\n <p style=\"margin-top: 2rem; padding: 1rem; background: #fef3c7; border-radius: 0.5rem;\">\n <strong>Note:</strong> Install <code>@t402/paywall</code> for full wallet connection and payment UI.\n </p>\n </div>\n </div>\n </body>\n </html>\n `;\n }\n\n /**\n * Extract display amount from payment requirements.\n *\n * @param paymentRequired - The payment required object\n * @returns The display amount in decimal format\n */\n private getDisplayAmount(paymentRequired: PaymentRequired): number {\n const accepts = paymentRequired.accepts;\n if (accepts && accepts.length > 0) {\n const firstReq = accepts[0];\n if (\"amount\" in firstReq) {\n // V2 format\n return parseFloat(firstReq.amount) / 1000000; // Assuming USDC with 6 decimals\n }\n }\n return 0;\n }\n}\n","import { PaymentPayload, PaymentRequirements } from \"../types/payments\";\nimport { VerifyResponse, SettleResponse, SupportedResponse } from \"../types/facilitator\";\nimport { T402PaymentError } from \"../errors\";\n\nconst DEFAULT_FACILITATOR_URL = \"https://facilitator.t402.io\";\n\nexport interface FacilitatorConfig {\n url?: string;\n createAuthHeaders?: () => Promise<{\n verify: Record<string, string>;\n settle: Record<string, string>;\n supported: Record<string, string>;\n }>;\n}\n\n/**\n * Interface for facilitator clients\n * Can be implemented for HTTP-based or local facilitators\n */\nexport interface FacilitatorClient {\n /**\n * Verify a payment with the facilitator\n *\n * @param paymentPayload - The payment to verify\n * @param paymentRequirements - The requirements to verify against\n * @returns Verification response\n */\n verify(\n paymentPayload: PaymentPayload,\n paymentRequirements: PaymentRequirements,\n ): Promise<VerifyResponse>;\n\n /**\n * Settle a payment with the facilitator\n *\n * @param paymentPayload - The payment to settle\n * @param paymentRequirements - The requirements for settlement\n * @returns Settlement response\n */\n settle(\n paymentPayload: PaymentPayload,\n paymentRequirements: PaymentRequirements,\n ): Promise<SettleResponse>;\n\n /**\n * Get supported payment kinds and extensions from the facilitator\n *\n * @returns Supported payment kinds and extensions\n */\n getSupported(): Promise<SupportedResponse>;\n}\n\n/**\n * HTTP-based client for interacting with t402 facilitator services\n * Handles HTTP communication with facilitator endpoints\n */\nexport class HTTPFacilitatorClient implements FacilitatorClient {\n readonly url: string;\n private readonly _createAuthHeaders?: FacilitatorConfig[\"createAuthHeaders\"];\n\n /**\n * Creates a new HTTPFacilitatorClient instance.\n *\n * @param config - Configuration options for the facilitator client\n */\n constructor(config?: FacilitatorConfig) {\n this.url = config?.url || DEFAULT_FACILITATOR_URL;\n this._createAuthHeaders = config?.createAuthHeaders;\n }\n\n /**\n * Verify a payment with the facilitator\n *\n * @param paymentPayload - The payment to verify\n * @param paymentRequirements - The requirements to verify against\n * @returns Verification response\n */\n async verify(\n paymentPayload: PaymentPayload,\n paymentRequirements: PaymentRequirements,\n ): Promise<VerifyResponse> {\n let headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n };\n\n if (this._createAuthHeaders) {\n const authHeaders = await this.createAuthHeaders(\"verify\");\n headers = { ...headers, ...authHeaders.headers };\n }\n\n const response = await fetch(`${this.url}/verify`, {\n method: \"POST\",\n headers,\n body: JSON.stringify({\n t402Version: paymentPayload.t402Version,\n paymentPayload: this.toJsonSafe(paymentPayload),\n paymentRequirements: this.toJsonSafe(paymentRequirements),\n }),\n });\n\n if (!response.ok) {\n const errorText = await response.text().catch(() => response.statusText);\n throw new T402PaymentError(`Facilitator verify failed (${response.status}): ${errorText}`, {\n phase: \"verification\",\n code: response.status,\n retryable: response.status >= 500 || response.status === 429,\n });\n }\n\n return (await response.json()) as VerifyResponse;\n }\n\n /**\n * Settle a payment with the facilitator\n *\n * @param paymentPayload - The payment to settle\n * @param paymentRequirements - The requirements for settlement\n * @returns Settlement response\n */\n async settle(\n paymentPayload: PaymentPayload,\n paymentRequirements: PaymentRequirements,\n ): Promise<SettleResponse> {\n let headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n };\n\n if (this._createAuthHeaders) {\n const authHeaders = await this.createAuthHeaders(\"settle\");\n headers = { ...headers, ...authHeaders.headers };\n }\n\n const response = await fetch(`${this.url}/settle`, {\n method: \"POST\",\n headers,\n body: JSON.stringify({\n t402Version: paymentPayload.t402Version,\n paymentPayload: this.toJsonSafe(paymentPayload),\n paymentRequirements: this.toJsonSafe(paymentRequirements),\n }),\n });\n\n if (!response.ok) {\n const errorText = await response.text().catch(() => response.statusText);\n throw new T402PaymentError(`Facilitator settle failed (${response.status}): ${errorText}`, {\n phase: \"settlement\",\n code: response.status,\n retryable: response.status >= 500 || response.status === 429,\n });\n }\n\n return (await response.json()) as SettleResponse;\n }\n\n /**\n * Get supported payment kinds and extensions from the facilitator\n *\n * @returns Supported payment kinds and extensions\n */\n async getSupported(): Promise<SupportedResponse> {\n let headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n };\n\n if (this._createAuthHeaders) {\n const authHeaders = await this.createAuthHeaders(\"supported\");\n headers = { ...headers, ...authHeaders.headers };\n }\n\n const response = await fetch(`${this.url}/supported`, {\n method: \"GET\",\n headers,\n });\n\n if (!response.ok) {\n const errorText = await response.text().catch(() => response.statusText);\n throw new T402PaymentError(\n `Facilitator getSupported failed (${response.status}): ${errorText}`,\n {\n phase: \"unknown\",\n code: response.status,\n retryable: response.status >= 500 || response.status === 429,\n },\n );\n }\n\n return (await response.json()) as SupportedResponse;\n }\n\n /**\n * Creates authentication headers for a specific path.\n *\n * @param path - The path to create authentication headers for (e.g., \"verify\", \"settle\", \"supported\")\n * @returns An object containing the authentication headers for the specified path\n */\n async createAuthHeaders(path: string): Promise<{\n headers: Record<string, string>;\n }> {\n if (this._createAuthHeaders) {\n const authHeaders = (await this._createAuthHeaders()) as Record<\n string,\n Record<string, string>\n >;\n return {\n headers: authHeaders[path] ?? {},\n };\n }\n return {\n headers: {},\n };\n }\n\n /**\n * Helper to convert objects to JSON-safe format.\n * Handles BigInt and other non-JSON types.\n *\n * @param obj - The object to convert\n * @returns The JSON-safe representation of the object\n */\n private toJsonSafe(obj: unknown): unknown {\n return JSON.parse(\n JSON.stringify(obj, (_, value) => (typeof value === \"bigint\" ? value.toString() : value)),\n );\n }\n}\n","import {\n decodePaymentRequiredHeader,\n decodePaymentResponseHeader,\n encodePaymentSignatureHeader,\n} from \".\";\nimport { T402PaymentError } from \"../errors\";\nimport { SettleResponse } from \"../types\";\nimport { PaymentPayload, PaymentRequired } from \"../types/payments\";\nimport { t402Client } from \"../client/t402Client\";\n\n/**\n * HTTP-specific client for handling t402 payment protocol over HTTP.\n *\n * Wraps a t402Client to provide HTTP-specific encoding/decoding functionality\n * for payment headers and responses while maintaining the builder pattern.\n */\nexport class t402HTTPClient {\n /**\n * Creates a new t402HTTPClient instance.\n *\n * @param client - The underlying t402Client for payment logic\n */\n constructor(private readonly client: t402Client) {}\n\n /**\n * Encodes a payment payload into appropriate HTTP headers based on version.\n *\n * @param paymentPayload - The payment payload to encode\n * @returns HTTP headers containing the encoded payment signature\n */\n encodePaymentSignatureHeader(paymentPayload: PaymentPayload): Record<string, string> {\n switch (paymentPayload.t402Version) {\n case 2:\n return {\n \"PAYMENT-SIGNATURE\": encodePaymentSignatureHeader(paymentPayload),\n };\n case 1:\n return {\n \"X-PAYMENT\": encodePaymentSignatureHeader(paymentPayload),\n };\n default:\n throw new T402PaymentError(\n `Unsupported t402 version: ${(paymentPayload as PaymentPayload).t402Version}`,\n { phase: \"submission\" },\n );\n }\n }\n\n /**\n * Extracts payment required information from HTTP response.\n *\n * @param getHeader - Function to retrieve header value by name (case-insensitive)\n * @param body - Optional response body for v1 compatibility\n * @returns The payment required object\n */\n getPaymentRequiredResponse(\n getHeader: (name: string) => string | null | undefined,\n body?: unknown,\n ): PaymentRequired {\n // v2\n const paymentRequired = getHeader(\"PAYMENT-REQUIRED\");\n if (paymentRequired) {\n return decodePaymentRequiredHeader(paymentRequired);\n }\n\n // v1\n if (\n body &&\n body instanceof Object &&\n \"t402Version\" in body &&\n (body as PaymentRequired).t402Version === 1\n ) {\n return body as PaymentRequired;\n }\n\n throw new T402PaymentError(\"Invalid payment required response\", {\n phase: \"submission\",\n });\n }\n\n /**\n * Extracts payment settlement response from HTTP headers.\n *\n * @param getHeader - Function to retrieve header value by name (case-insensitive)\n * @returns The settlement response object\n */\n getPaymentSettleResponse(getHeader: (name: string) => string | null | undefined): SettleResponse {\n // v2\n const paymentResponse = getHeader(\"PAYMENT-RESPONSE\");\n if (paymentResponse) {\n return decodePaymentResponseHeader(paymentResponse);\n }\n\n // v1\n const xPaymentResponse = getHeader(\"X-PAYMENT-RESPONSE\");\n if (xPaymentResponse) {\n return decodePaymentResponseHeader(xPaymentResponse);\n }\n\n throw new T402PaymentError(\"Payment response header not found\", {\n phase: \"settlement\",\n });\n }\n\n /**\n * Creates a payment payload for the given payment requirements.\n * Delegates to the underlying t402Client.\n *\n * @param paymentRequired - The payment required response from the server\n * @returns Promise resolving to the payment payload\n */\n async createPaymentPayload(paymentRequired: PaymentRequired): Promise<PaymentPayload> {\n return this.client.createPaymentPayload(paymentRequired);\n }\n}\n","import { SettleResponse } from \"../types\";\nimport { PaymentPayload, PaymentRequired, PaymentRequirements } from \"../types/payments\";\nimport {\n PaymentPayloadSchema,\n PaymentRequiredSchema,\n SettleResponseSchema,\n} from \"../types/schemas\";\nimport { Base64EncodedRegex, safeBase64Decode, safeBase64Encode } from \"../utils\";\n\n// HTTP Methods that typically use query parameters\nexport type QueryParamMethods = \"GET\" | \"HEAD\" | \"DELETE\";\n\n// HTTP Methods that typically use request body\nexport type BodyMethods = \"POST\" | \"PUT\" | \"PATCH\";\n\n/**\n * Encodes a payment payload as a base64 header value.\n *\n * @param paymentPayload - The payment payload to encode\n * @returns Base64 encoded string representation of the payment payload\n */\nexport function encodePaymentSignatureHeader(paymentPayload: PaymentPayload): string {\n return safeBase64Encode(JSON.stringify(paymentPayload));\n}\n\n/**\n * Decodes a base64 payment signature header into a payment payload.\n * Validates the payload structure using Zod schema.\n *\n * @param paymentSignatureHeader - The base64 encoded payment signature header\n * @returns The decoded and validated payment payload\n * @throws Error if the header is invalid or fails schema validation\n */\nexport function decodePaymentSignatureHeader(paymentSignatureHeader: string): PaymentPayload {\n if (!Base64EncodedRegex.test(paymentSignatureHeader)) {\n throw new Error(\"Invalid payment signature header\");\n }\n const parsed = JSON.parse(safeBase64Decode(paymentSignatureHeader));\n // Validate structure with Zod, then cast to TypeScript type\n // (Zod validates the structure; TypeScript types add template literal constraints)\n PaymentPayloadSchema.parse(parsed);\n return parsed as PaymentPayload;\n}\n\n/**\n * Encodes a payment required object as a base64 header value.\n *\n * @param paymentRequired - The payment required object to encode\n * @returns Base64 encoded string representation of the payment required object\n */\nexport function encodePaymentRequiredHeader(paymentRequired: PaymentRequired): string {\n return safeBase64Encode(JSON.stringify(paymentRequired));\n}\n\n/**\n * Decodes a base64 payment required header into a payment required object.\n * Validates the structure using Zod schema.\n *\n * @param paymentRequiredHeader - The base64 encoded payment required header\n * @returns The decoded and validated payment required object\n * @throws Error if the header is invalid or fails schema validation\n */\nexport function decodePaymentRequiredHeader(paymentRequiredHeader: string): PaymentRequired {\n if (!Base64EncodedRegex.test(paymentRequiredHeader)) {\n throw new Error(\"Invalid payment required header\");\n }\n const parsed = JSON.parse(safeBase64Decode(paymentRequiredHeader));\n // Validate structure with Zod, then cast to TypeScript type\n PaymentRequiredSchema.parse(parsed);\n return parsed as PaymentRequired;\n}\n\n/**\n * Encodes a payment response as a base64 header value.\n *\n * @param paymentResponse - The payment response to encode\n * @returns Base64 encoded string representation of the payment response\n */\nexport function encodePaymentResponseHeader(\n paymentResponse: SettleResponse & { requirements: PaymentRequirements },\n): string {\n return safeBase64Encode(JSON.stringify(paymentResponse));\n}\n\n/**\n * Decodes a base64 payment response header into a settle response.\n * Validates the structure using Zod schema.\n *\n * @param paymentResponseHeader - The base64 encoded payment response header\n * @returns The decoded and validated settle response\n * @throws Error if the header is invalid or fails schema validation\n */\nexport function decodePaymentResponseHeader(paymentResponseHeader: string): SettleResponse {\n if (!Base64EncodedRegex.test(paymentResponseHeader)) {\n throw new Error(\"Invalid payment response header\");\n }\n const parsed = JSON.parse(safeBase64Decode(paymentResponseHeader));\n // Validate structure with Zod, then cast to TypeScript type\n SettleResponseSchema.parse(parsed);\n return parsed as SettleResponse;\n}\n\n// Export HTTP service classes (values)\nexport { t402HTTPResourceServer, RouteConfigurationError } from \"./t402HTTPResourceServer\";\nexport { HTTPFacilitatorClient } from \"./httpFacilitatorClient\";\nexport { t402HTTPClient } from \"./t402HTTPClient\";\n\n// Export HTTP types (type-only exports for isolatedModules compatibility)\nexport type {\n HTTPAdapter,\n HTTPRequestContext,\n HTTPResponseInstructions,\n HTTPProcessResult,\n PaywallConfig,\n PaywallProvider,\n PaymentOption,\n RouteConfig,\n RoutesConfig,\n CompiledRoute,\n DynamicPayTo,\n DynamicPrice,\n UnpaidResponseBody,\n UnpaidResponseResult,\n ProcessSettleResultResponse,\n ProcessSettleSuccessResponse,\n ProcessSettleFailureResponse,\n RouteValidationError,\n} from \"./t402HTTPResourceServer\";\nexport type { FacilitatorClient, FacilitatorConfig } from \"./httpFacilitatorClient\";\n"],"mappings":"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","names":["displayAmount","resource"]}
|