@nibgate/sdk 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.
package/src/index.d.ts ADDED
@@ -0,0 +1,423 @@
1
+ export type NibgateContentType = 'music' | 'video' | 'article' | 'image';
2
+ export type NibgateAccessMode = 'free' | 'paid' | 'blocked';
3
+ export type NibgateUnlockMode = 'one_time' | 'metered_stream' | 'metered_read' | 'time_pass' | 'agent_quota';
4
+ export type NibgatePaymentRail = 'gateway' | 'transfer';
5
+ export type NibgateAccessPolicy = {
6
+ humans?: NibgateAccessMode;
7
+ human?: NibgateAccessMode;
8
+ agents?: NibgateAccessMode;
9
+ agent?: NibgateAccessMode;
10
+ default?: NibgateAccessMode;
11
+ };
12
+ export type NibgateUnlockPolicy = {
13
+ mode?: NibgateUnlockMode | string;
14
+ type?: NibgateUnlockMode | string;
15
+ unit?: string;
16
+ pricePerUnit?: string | number;
17
+ duration?: string | number;
18
+ maxReads?: number;
19
+ [key: string]: unknown;
20
+ };
21
+
22
+ export type NibgateResource = {
23
+ id: string;
24
+ title?: string;
25
+ type?: NibgateContentType | string;
26
+ contentType?: NibgateContentType | string;
27
+ price?: string | number;
28
+ paymentRail?: NibgatePaymentRail | string;
29
+ amount?: string | number;
30
+ recipient?: string;
31
+ receiver?: string;
32
+ receiverAddress?: string;
33
+ payTo?: string;
34
+ creatorWallet?: string;
35
+ path?: string;
36
+ route?: string;
37
+ url?: string;
38
+ imageUrl?: string;
39
+ image?: string;
40
+ description?: string;
41
+ summary?: string;
42
+ tags?: string[] | string;
43
+ access?: NibgateAccessMode | NibgateAccessPolicy;
44
+ unlock?: NibgateUnlockMode | NibgateUnlockPolicy;
45
+ [key: string]: unknown;
46
+ };
47
+
48
+ export type NibgateMetadataValidation = {
49
+ ok: boolean;
50
+ score: number;
51
+ errors: string[];
52
+ warnings: string[];
53
+ resource: NibgateResource;
54
+ };
55
+
56
+ export type NibgatePayment = {
57
+ revenue?: number;
58
+ amount?: number;
59
+ currency?: string;
60
+ paymentId?: string;
61
+ paymentProvider?: 'circle-gateway' | 'arc-testnet' | 'x402' | string;
62
+ receiptUrl?: string;
63
+ txHash?: string;
64
+ chainId?: string | number;
65
+ chainExplorerUrl?: string;
66
+ payer?: string;
67
+ recipient?: string;
68
+ [key: string]: unknown;
69
+ };
70
+
71
+ export type NibgateRating = {
72
+ rating?: number;
73
+ stars?: number;
74
+ ratingValue?: number;
75
+ score?: number;
76
+ walletAddress?: string;
77
+ payer?: string;
78
+ actor?: 'human' | 'agent' | string;
79
+ paymentId?: string;
80
+ txHash?: string;
81
+ reviewHash?: string;
82
+ message?: string;
83
+ ratingMessage?: string;
84
+ signature?: string;
85
+ ratingSignature?: string;
86
+ proofType?: 'onchain' | 'attested' | string;
87
+ proof?: string;
88
+ [key: string]: unknown;
89
+ };
90
+
91
+ export type NibgateClient = {
92
+ gate(resource: NibgateResource | string, options?: NibgateGateOptions): NibgateGate;
93
+ content(resource: NibgateResource | string, extra?: Record<string, unknown>): boolean;
94
+ registerContent(resource: NibgateResource | string, extra?: Record<string, unknown>): boolean;
95
+ view(resource: NibgateResource | string, extra?: Record<string, unknown>): boolean;
96
+ track(eventName: string, payload?: Record<string, unknown>): boolean;
97
+ unlockStarted(resource: NibgateResource | string, extra?: Record<string, unknown>): boolean;
98
+ unlockCompleted(resource: NibgateResource | string, payment?: NibgatePayment): boolean;
99
+ paymentCompleted(resource: NibgateResource | string, payment?: NibgatePayment): boolean;
100
+ rateResource(resource: NibgateResource | string, rating?: NibgateRating | number, extra?: Record<string, unknown>): boolean;
101
+ trackResourcePage(resource: NibgateResource | string, options?: NibgatePageOptions): NibgateGate;
102
+ checkResourceAccess(resource: NibgateResource | string, options?: NibgateAccessCheckOptions): Promise<NibgateAccessCheckResult>;
103
+ payWithPaymentSignature(resource: NibgateResource | string, options?: NibgatePaymentSignatureOptions): Promise<NibgatePaymentSignatureResult>;
104
+ createWalletCheckout(resource: NibgateResource | string, options: NibgateWalletCheckoutOptions): NibgateWalletCheckoutController;
105
+ createCircleGatewayBrowserAdapter(options: NibgateCircleGatewayBrowserAdapterOptions): Promise<NibgateCircleGatewayBrowserAdapter>;
106
+ createTransferCheckout(resource: NibgateResource | string, options: NibgateTransferCheckoutOptions): NibgateTransferCheckout;
107
+ payWithTransfer(resource: NibgateResource | string, options: NibgateTransferCheckoutOptions & NibgateAccessCheckOptions): Promise<NibgateAccessCheckResult>;
108
+ createEvmGatewayUnlock(resource: NibgateResource | string, options?: NibgateEvmGatewayUnlockOptions): NibgateEvmGatewayUnlockController;
109
+ rateContentOnchain(resource: NibgateResource | string, options: NibgateOnchainRatingOptions): Promise<NibgateOnchainRatingResult>;
110
+ createOnchainRating(resource: NibgateResource | string, options?: NibgateOnchainRatingUiOptions): NibgateOnchainRatingController;
111
+ payAndUnlockResource(resource: NibgateResource | string, options?: NibgatePaymentOptions): Promise<NibgatePaymentResult>;
112
+ setupResourcePage(resource: NibgateResource | string, options?: NibgatePageSetupOptions): NibgateGate;
113
+ ratingMessage(resource: NibgateResource | string, rating?: NibgateRating | number, options?: Record<string, unknown>): string;
114
+ normalizeResource(resource: NibgateResource | string): NibgateResource;
115
+ validateResourceMetadata(resource: NibgateResource | string, options?: Record<string, unknown>): NibgateMetadataValidation;
116
+ normalizeContentType(type?: string): NibgateContentType;
117
+ flush(): boolean;
118
+ };
119
+
120
+ export type NibgateGateOptions = {
121
+ client?: NibgateClient;
122
+ };
123
+
124
+ export type NibgateGate = {
125
+ resource: NibgateResource;
126
+ content(extra?: Record<string, unknown>): boolean;
127
+ view(extra?: Record<string, unknown>): boolean;
128
+ track(eventName: string, payload?: Record<string, unknown>): boolean;
129
+ unlockStarted(extra?: Record<string, unknown>): boolean;
130
+ unlockCompleted(payment?: NibgatePayment): boolean;
131
+ paymentCompleted(payment?: NibgatePayment): boolean;
132
+ isUnlocked(): boolean;
133
+ markUnlocked(payment?: NibgatePayment): boolean;
134
+ unlock(handlerOrPayment?: NibgatePayment | ((resource: NibgateResource) => Promise<NibgatePayment> | NibgatePayment)): Promise<{ unlocked: true; resource: NibgateResource; payment: NibgatePayment }>;
135
+ rate(rating?: NibgateRating | number, extra?: Record<string, unknown>): boolean;
136
+ };
137
+
138
+ export type NibgatePageOptions = {
139
+ source?: string;
140
+ path?: string;
141
+ referrer?: string;
142
+ content?: Record<string, unknown>;
143
+ view?: Record<string, unknown>;
144
+ gateOptions?: NibgateGateOptions;
145
+ };
146
+
147
+ export type NibgateAccessCheckOptions = {
148
+ source?: string;
149
+ accessPath?: string;
150
+ payPath?: string;
151
+ autoPay?: boolean;
152
+ retryAfterPay?: boolean;
153
+ paymentSignature?: string;
154
+ paymentRequiredHeader?: string;
155
+ memo?: string;
156
+ checkout?: NibgateCheckoutHandler;
157
+ createPaymentSignature?: NibgateCheckoutHandler;
158
+ method?: string;
159
+ headers?: Record<string, string>;
160
+ body?: BodyInit | null;
161
+ payment?: NibgatePayment;
162
+ paymentProvider?: string;
163
+ checkingMessage?: string;
164
+ challengeMessage?: string;
165
+ successMessage?: string;
166
+ errorMessage?: string;
167
+ gateOptions?: NibgateGateOptions;
168
+ onStatus?: (message: string) => void;
169
+ };
170
+
171
+ export type NibgateCheckoutInput = {
172
+ resource: NibgateResource;
173
+ challenge?: Record<string, unknown> | null;
174
+ paymentRequiredHeader?: string;
175
+ accessPath?: string;
176
+ };
177
+
178
+ export type NibgateCheckoutResult = {
179
+ paymentSignature?: string;
180
+ signature?: string;
181
+ payment?: string | NibgatePayment;
182
+ memo?: string;
183
+ paymentMemo?: string;
184
+ metadata?: NibgatePayment;
185
+ paymentMetadata?: NibgatePayment;
186
+ [key: string]: unknown;
187
+ };
188
+
189
+ export type NibgateCheckoutHandler = (input: NibgateCheckoutInput) => Promise<NibgateCheckoutResult> | NibgateCheckoutResult;
190
+
191
+ export type NibgateEvmTypedDataSigner = {
192
+ address: `0x${string}` | string;
193
+ signTypedData(params: {
194
+ domain: {
195
+ name: string;
196
+ version: string;
197
+ chainId: number;
198
+ verifyingContract: `0x${string}` | string;
199
+ };
200
+ types: Record<string, Array<{ name: string; type: string }>>;
201
+ primaryType: string;
202
+ message: Record<string, unknown>;
203
+ }): Promise<`0x${string}` | string>;
204
+ };
205
+
206
+ export type NibgateCircleGatewayBrowserAdapterOptions = {
207
+ signer?: NibgateEvmTypedDataSigner;
208
+ getSigner?: () => Promise<NibgateEvmTypedDataSigner> | NibgateEvmTypedDataSigner;
209
+ network?: string;
210
+ chainId?: number | string;
211
+ clientModule?: Record<string, unknown>;
212
+ clientModuleUrl?: string;
213
+ };
214
+
215
+ export type NibgateCircleGatewayBrowserAdapter = {
216
+ signer: NibgateEvmTypedDataSigner;
217
+ network: string;
218
+ pay(input: NibgateCheckoutInput): Promise<NibgateCheckoutResult>;
219
+ };
220
+
221
+ export type NibgateEvmGatewayUnlockOptions = {
222
+ source?: string;
223
+ accessPath?: string;
224
+ network?: string;
225
+ paymentProvider?: string;
226
+ circleClientModule?: Record<string, unknown>;
227
+ circleClientModuleUrl?: string;
228
+ provider?: {
229
+ request(args: { method: string; params?: unknown[] }): Promise<unknown>;
230
+ };
231
+ connectButton?: string | Element | null;
232
+ disconnectButton?: string | Element | null;
233
+ unlockButton?: string | Element | null;
234
+ clearButton?: string | Element | null;
235
+ walletLabel?: string | Element | null;
236
+ status?: string | Element | null;
237
+ unlockedTarget?: string | Element | null;
238
+ noWalletMessage?: string;
239
+ challengeMessage?: string;
240
+ paymentMessage?: string;
241
+ successMessage?: string;
242
+ disconnectMessage?: string;
243
+ autoMount?: boolean;
244
+ gateOptions?: NibgateGateOptions;
245
+ onStatus?: (message: string) => void;
246
+ onUnlock?: (result: NibgateAccessCheckResult) => void;
247
+ };
248
+
249
+ export type NibgateEvmGatewayUnlockController = {
250
+ resource: NibgateResource;
251
+ connect(): Promise<string>;
252
+ disconnect(): Promise<boolean>;
253
+ unlock(): Promise<NibgateAccessCheckResult | { ok: false; status: number; error: string; resource: NibgateResource }>;
254
+ clear(): void;
255
+ hydrate(): Promise<void>;
256
+ mount(): NibgateEvmGatewayUnlockController;
257
+ getWalletAddress(): string;
258
+ };
259
+
260
+ export type NibgateWalletCheckoutOptions = NibgateAccessCheckOptions & {
261
+ button?: string | HTMLButtonElement | null;
262
+ status?: string | HTMLElement | null;
263
+ pay?: NibgateCheckoutHandler;
264
+ };
265
+
266
+ export type NibgateWalletCheckoutController = {
267
+ resource: NibgateResource;
268
+ unlock(extra?: Partial<NibgateWalletCheckoutOptions>): Promise<NibgateAccessCheckResult | NibgatePaymentSignatureResult>;
269
+ mount(): { unlock(extra?: Partial<NibgateWalletCheckoutOptions>): Promise<NibgateAccessCheckResult | NibgatePaymentSignatureResult> };
270
+ };
271
+
272
+ export type NibgatePaymentSignatureOptions = NibgateAccessCheckOptions & {
273
+ challenge?: Record<string, unknown> | null;
274
+ payment?: NibgatePayment;
275
+ };
276
+
277
+ export type NibgatePaymentOptions = {
278
+ source?: string;
279
+ payPath?: string;
280
+ payMethod?: string;
281
+ payHeaders?: Record<string, string>;
282
+ payPayload?: Record<string, unknown>;
283
+ paymentProvider?: string;
284
+ paymentMessage?: string;
285
+ paymentSuccessMessage?: string;
286
+ paymentErrorMessage?: string;
287
+ gateOptions?: NibgateGateOptions;
288
+ onStatus?: (message: string) => void;
289
+ };
290
+
291
+ export type NibgatePageSetupOptions = NibgatePageOptions & NibgateAccessCheckOptions & {
292
+ button?: string | HTMLButtonElement | null;
293
+ status?: string | HTMLElement | null;
294
+ };
295
+
296
+ export type NibgateAccessCheckResult =
297
+ | { ok: true; status: number; payload: Record<string, unknown>; payment: NibgatePayment | null; resource: NibgateResource; response: Response }
298
+ | { ok: false; status: number; challenge?: Record<string, unknown>; error?: string; payload?: Record<string, unknown>; resource: NibgateResource; response: Response };
299
+
300
+ export type NibgatePaymentResult =
301
+ | { ok: true; status: number; payload: Record<string, unknown>; payment: NibgatePayment; resource: NibgateResource; response: Response }
302
+ | { ok: false; status: number; payload?: Record<string, unknown>; resource: NibgateResource; response: Response };
303
+
304
+ export type NibgatePaymentSignatureResult =
305
+ | { ok: true; status: number; payload: Record<string, unknown>; payment: NibgatePayment; resource: NibgateResource; response: Response }
306
+ | { ok: false; status: number; error?: string; payload?: Record<string, unknown>; resource: NibgateResource; response?: Response };
307
+
308
+ export type NibgateOnchainRatingOptions = NibgateRating & {
309
+ provider?: {
310
+ request(args: { method: string; params?: unknown[] }): Promise<unknown>;
311
+ };
312
+ contractAddress?: string;
313
+ reputationContract?: string;
314
+ siteDomain?: string;
315
+ domain?: string;
316
+ url?: string;
317
+ contentId?: `0x${string}` | string;
318
+ unlockRef?: string;
319
+ review?: string;
320
+ reviewHash?: string;
321
+ paymentId?: string;
322
+ actor?: 'human' | 'agent' | string;
323
+ source?: string;
324
+ prepareUrl?: string;
325
+ indexUrl?: string;
326
+ indexHeaders?: Record<string, string>;
327
+ siteId?: string;
328
+ token?: string;
329
+ };
330
+
331
+ export type NibgateOnchainRatingResult = {
332
+ txHash: string;
333
+ walletAddress: string;
334
+ contentId: string;
335
+ ratingValue: number;
336
+ reviewHash: string;
337
+ };
338
+
339
+ export type NibgateOnchainRatingUiOptions = NibgateOnchainRatingOptions & {
340
+ status?: string | HTMLElement | null;
341
+ ratingTarget?: string | HTMLElement | null;
342
+ ratingButtons?: string;
343
+ buttons?: string | HTMLElement | HTMLElement[] | null;
344
+ payment?: NibgatePayment | null;
345
+ visible?: boolean;
346
+ autoMount?: boolean;
347
+ pendingMessage?: string;
348
+ successMessage?: string;
349
+ errorMessage?: string;
350
+ gateOptions?: NibgateGateOptions;
351
+ getPaymentId?: () => string | undefined | null;
352
+ getUnlockRef?: () => string | undefined | null;
353
+ onStatus?: (message: string) => void;
354
+ onRated?: (result: NibgateOnchainRatingResult) => void;
355
+ onError?: (error: unknown) => void;
356
+ };
357
+
358
+ export type NibgateOnchainRatingController = {
359
+ resource: NibgateResource;
360
+ rate(input?: Partial<NibgateOnchainRatingOptions> & { value?: number | string }): Promise<NibgateOnchainRatingResult>;
361
+ mount(): NibgateOnchainRatingController;
362
+ setPayment(payment?: NibgatePayment | null): NibgatePayment | null;
363
+ setVisible(isVisible: boolean): boolean;
364
+ };
365
+
366
+ export type NibgateContentSettingField = {
367
+ name: string;
368
+ label: string;
369
+ type: 'boolean' | 'select' | 'text' | 'wallet' | 'textarea' | string;
370
+ options?: readonly string[];
371
+ defaultValue?: string | boolean;
372
+ };
373
+ export type NibgateContentSettings = {
374
+ publishToNibgate: boolean;
375
+ type: NibgateContentType;
376
+ humanAccess: NibgateAccessMode;
377
+ agentAccess: NibgateAccessMode;
378
+ unlockMode: NibgateUnlockMode | string;
379
+ paymentRail: NibgatePaymentRail | string;
380
+ price: string;
381
+ currency: string;
382
+ recipient: string;
383
+ license: string;
384
+ };
385
+ export declare const NIBGATE_CONTENT_SETTING_FIELDS: readonly NibgateContentSettingField[];
386
+ export declare function createNibgateContentSettings(input?: Record<string, unknown>): NibgateContentSettings;
387
+ export declare function settingsToAccessPolicy(settings?: Partial<NibgateContentSettings>): Required<Pick<NibgateAccessPolicy, 'humans' | 'agents'>>;
388
+ export declare function settingsToUnlockPolicy(settings?: Partial<NibgateContentSettings>): Required<Pick<NibgateUnlockPolicy, 'mode'>> & NibgateUnlockPolicy;
389
+
390
+ export declare const PAYMENT_RAILS: readonly ['gateway', 'transfer'];
391
+ export declare function normalizePaymentRail(value?: string, fallback?: NibgatePaymentRail): NibgatePaymentRail;
392
+ export declare const CONTENT_TYPES: readonly ['music', 'video', 'article', 'image'];
393
+ export declare const ACCESS_MODES: readonly ['free', 'paid', 'blocked'];
394
+ export declare const UNLOCK_MODES: readonly ['one_time', 'metered_stream', 'metered_read', 'time_pass', 'agent_quota'];
395
+ export declare function normalizeContentType(type?: string): NibgateContentType;
396
+ export declare function normalizeResource(resource?: NibgateResource | string): NibgateResource;
397
+ export declare function validateResourceMetadata(resource?: NibgateResource | string, options?: Record<string, unknown>): NibgateMetadataValidation;
398
+ export declare function normalizeAccessPolicy(access?: NibgateAccessMode | NibgateAccessPolicy): Required<Pick<NibgateAccessPolicy, 'humans' | 'agents'>>;
399
+ export declare function normalizeUnlockPolicy(unlock?: NibgateUnlockMode | NibgateUnlockPolicy): Required<Pick<NibgateUnlockPolicy, 'mode'>> & NibgateUnlockPolicy;
400
+ export declare function createGate(resource: NibgateResource | string, options?: NibgateGateOptions): NibgateGate;
401
+ export declare const gate: typeof createGate;
402
+ export declare function trackResourcePage(resource: NibgateResource | string, options?: NibgatePageOptions): NibgateGate;
403
+ export declare function checkResourceAccess(resource: NibgateResource | string, options?: NibgateAccessCheckOptions): Promise<NibgateAccessCheckResult>;
404
+ export declare function clearPaymentProof(resource: NibgateResource | string): boolean;
405
+ export declare function payWithPaymentSignature(resource: NibgateResource | string, options?: NibgatePaymentSignatureOptions): Promise<NibgatePaymentSignatureResult>;
406
+ export declare function createWalletCheckout(resource: NibgateResource | string, options: NibgateWalletCheckoutOptions): NibgateWalletCheckoutController;
407
+ export declare function createCircleGatewayBrowserAdapter(options: NibgateCircleGatewayBrowserAdapterOptions): Promise<NibgateCircleGatewayBrowserAdapter>;
408
+ export declare function createEvmGatewayUnlock(resource: NibgateResource | string, options?: NibgateEvmGatewayUnlockOptions): NibgateEvmGatewayUnlockController;
409
+ export declare function payAndUnlockResource(resource: NibgateResource | string, options?: NibgatePaymentOptions): Promise<NibgatePaymentResult>;
410
+ export declare function setupResourcePage(resource: NibgateResource | string, options?: NibgatePageSetupOptions): NibgateGate;
411
+ export declare function rateResource(resource: NibgateResource | string, rating?: NibgateRating | number, extra?: Record<string, unknown>): boolean;
412
+ export declare const NIBGATE_REPUTATION_ABI: readonly unknown[];
413
+ export declare const NIBGATE_CONTENT_HASH_NAMESPACE: 'nibgate:content:v1';
414
+ export declare function contentRatingHash(resource: NibgateResource | string, options?: Record<string, unknown>): string;
415
+ export declare function reviewTextHash(review?: string): string;
416
+ export declare function rateContentOnchain(resource: NibgateResource | string, options: NibgateOnchainRatingOptions): Promise<NibgateOnchainRatingResult>;
417
+ export declare function createOnchainRating(resource: NibgateResource | string, options?: NibgateOnchainRatingUiOptions): NibgateOnchainRatingController;
418
+ export declare function ratingMessage(resource: NibgateResource | string, rating?: NibgateRating | number, options?: Record<string, unknown>): string;
419
+ export declare function createNibgate(defaults?: { resource?: NibgateResource }): NibgateClient;
420
+ export declare const nibgate: NibgateClient;
421
+
422
+ export declare function createTransferCheckout(resource: NibgateResource | string, options: NibgateTransferCheckoutOptions): NibgateTransferCheckout;
423
+ export declare function payWithTransfer(resource: NibgateResource | string, options: NibgateTransferCheckoutOptions & NibgateAccessCheckOptions): Promise<NibgateAccessCheckResult>;
package/src/index.js ADDED
@@ -0,0 +1 @@
1
+ export * from './browser/index.js';
@@ -0,0 +1,217 @@
1
+ import { normalizePaymentRail } from '../core/payment.js';
2
+ import { normalizeServerResource as normalizeResource } from '../core/resource.js';
3
+ import { actorFromRequest, accessModeFor } from './actor.js';
4
+ import { createPaymentChallenge } from './challenge.js';
5
+ import { jsonResponse } from './response.js';
6
+ import { DEFAULT_UNLOCK_SECONDS, createUnlockToken, verifyUnlockToken } from './proof.js';
7
+ import { createManifest, manifestResponse } from './manifest.js';
8
+ import { emitHubEvent } from './hub.js';
9
+ import { depositToGateway, getGatewayBalances, payWithGateway, runCircleGatewayRequirement, withdrawFromGateway } from './gateway.js';
10
+ import { serverEnv } from './env.js';
11
+
12
+ export function createNibgateServer(options = {}) {
13
+ const secret = options.secret || serverEnv('NIBGATE_SECRET') || serverEnv('NIBGATE_UNLOCK_SECRET') || 'nibgate-dev-secret';
14
+ const verifyPayment = options.verifyPayment || null;
15
+ const verifyTransfer = options.verifyTransfer || null;
16
+
17
+ async function unlock(resourceInput, payment = {}) {
18
+ const resource = normalizeResource(resourceInput);
19
+ if (verifyPayment) {
20
+ const verified = await verifyPayment({ resource, payment });
21
+ if (!verified) {
22
+ return { ok: false, status: 402, error: 'Payment verification failed', challenge: createPaymentChallenge(resource, options) };
23
+ }
24
+ }
25
+
26
+ const unlockProof = createUnlockToken(resource, {
27
+ secret,
28
+ paymentId: payment.paymentId || payment.id || '',
29
+ payment,
30
+ actor: payment.actor || 'human',
31
+ expiresInSeconds: payment.expiresInSeconds || options.expiresInSeconds
32
+ });
33
+
34
+ return {
35
+ ok: true,
36
+ unlockProof,
37
+ expiresInSeconds: payment.expiresInSeconds || options.expiresInSeconds || DEFAULT_UNLOCK_SECONDS,
38
+ resource,
39
+ payment
40
+ };
41
+ }
42
+
43
+ function isUnlocked(request, resourceInput, checkOptions = {}) {
44
+ const resource = normalizeResource(resourceInput);
45
+ const token = request?.headers?.get?.('x-nibgate-payment-proof') || '';
46
+ const payload = verifyUnlockToken(token, resource, { secret });
47
+ if (!payload) return false;
48
+ if (checkOptions.actor && payload.actor && payload.actor !== checkOptions.actor) return false;
49
+ return true;
50
+ }
51
+
52
+ function accessFor(request, resourceInput, accessOptions = {}) {
53
+ const resource = normalizeResource(resourceInput);
54
+ const actor = accessOptions.actor || actorFromRequest(request, accessOptions.defaultActor || 'human');
55
+ const mode = accessModeFor(resource, actor);
56
+ const unlocked = isUnlocked(request, resource, { actor });
57
+ return {
58
+ actor,
59
+ mode,
60
+ unlocked,
61
+ allowed: mode === 'free' || unlocked,
62
+ blocked: mode === 'blocked',
63
+ paid: mode === 'paid',
64
+ resource
65
+ };
66
+ }
67
+
68
+ function protect(resourceInput, handler, routeOptions = {}) {
69
+ const resource = normalizeResource(resourceInput);
70
+ return async function protectedHandler(request, context) {
71
+ const access = accessFor(request, resource, routeOptions);
72
+ if (access.allowed) {
73
+ return handler(request, context);
74
+ }
75
+
76
+ if (access.blocked) {
77
+ return jsonResponse({
78
+ status: 403,
79
+ error: `${access.actor} access is blocked for this resource`,
80
+ nibgate: {
81
+ contentId: resource.id,
82
+ actor: access.actor,
83
+ access: resource.access
84
+ }
85
+ }, { status: 403 });
86
+ }
87
+
88
+ const challenge = createPaymentChallenge(resource, { ...options, ...routeOptions, actor: access.actor });
89
+ return jsonResponse(challenge, { status: 402 });
90
+ };
91
+ }
92
+
93
+ async function accessResponse(request, resourceInput, allowedBody = null, routeOptions = {}) {
94
+ const resource = normalizeResource(resourceInput);
95
+ const access = accessFor(request, resource, routeOptions);
96
+
97
+ if (!access.allowed) {
98
+ if (access.blocked) {
99
+ return jsonResponse({
100
+ status: 403,
101
+ error: `${access.actor} access is blocked for this resource`,
102
+ resource
103
+ }, { status: 403 });
104
+ }
105
+
106
+ const rail = normalizePaymentRail(resource.paymentRail || routeOptions.paymentRail || options.paymentRail || routeOptions.paymentMode || options.paymentMode);
107
+ if (rail === 'gateway' && (routeOptions.paymentMode || options.paymentMode || serverEnv('NIBGATE_PAYMENT_MODE')) === 'circle-gateway') {
108
+ const gateway = await runCircleGatewayRequirement(request, resource, { ...options, ...routeOptions });
109
+ if (gateway.handled) return gateway.response;
110
+ const result = await unlock(resource, gateway.payment);
111
+ if (result.ok) {
112
+ return jsonResponse({ ok: true, resource, payment: gateway.payment, unlockProof: result.unlockProof, expiresInSeconds: result.expiresInSeconds });
113
+ }
114
+ }
115
+
116
+ if (rail === 'transfer') {
117
+ const txHash = request.headers?.get?.('x-nibgate-transfer-tx') || request.headers?.get?.('x-transfer-tx') || '';
118
+ if (txHash) {
119
+ if (!verifyTransfer) {
120
+ return jsonResponse({ error: 'Transfer verification is not configured', detail: 'Pass verifyTransfer({ resource, txHash, request }) to createNibgateServer/createCircleGatewayServer before using paymentRail: transfer.' }, { status: 501 });
121
+ }
122
+ const transferPayment = {
123
+ paymentProvider: 'direct-transfer',
124
+ paymentId: txHash,
125
+ txHash,
126
+ amount: Number(resource.price || 0),
127
+ revenue: Number(resource.price || 0),
128
+ currency: resource.currency || 'USDC',
129
+ recipient: resource.recipient || resource.payTo || routeOptions.recipient || options.recipient || serverEnv('NIBGATE_SELLER_ADDRESS') || '',
130
+ network: routeOptions.network || options.network || serverEnv('NIBGATE_PAYMENT_NETWORK') || 'eip155:5042002'
131
+ };
132
+ const verified = await verifyTransfer({ resource, txHash, payment: transferPayment, request });
133
+ if (!verified) return jsonResponse({ error: 'Transfer verification failed' }, { status: 402 });
134
+ const result = await unlock(resource, { ...transferPayment, verified: true });
135
+ if (result.ok) return jsonResponse({ ok: true, resource, payment: { ...transferPayment, verified: true }, unlockProof: result.unlockProof, expiresInSeconds: result.expiresInSeconds });
136
+ }
137
+ }
138
+
139
+ return jsonResponse(createPaymentChallenge(resource, { ...options, ...routeOptions, actor: access.actor, paymentRail: rail }), { status: 402 });
140
+ }
141
+
142
+ const body = typeof allowedBody === 'function'
143
+ ? allowedBody({ access, resource })
144
+ : (allowedBody || { ok: true, resource });
145
+
146
+ return body instanceof Response ? body : jsonResponse(body);
147
+ }
148
+
149
+ async function payAndUnlockResponse(request, resourceInput, routeOptions = {}) {
150
+ const resource = normalizeResource(resourceInput);
151
+ const origin = routeOptions.origin || options.origin || serverEnv('NIBGATE_SITE_ORIGIN') || '';
152
+ const accessUrl = routeOptions.accessUrl || `${origin.replace(/\/$/, '')}${routeOptions.accessPath || resource.path || '/'}`;
153
+
154
+ let payment;
155
+ if ((routeOptions.paymentMode || options.paymentMode || serverEnv('NIBGATE_PAYMENT_MODE') || 'circle-gateway') === 'circle-gateway') {
156
+ const gatewayResult = await payWithGateway(resource, { ...options, ...routeOptions, origin, accessUrl });
157
+ if (!gatewayResult.ok) return jsonResponse(gatewayResult, { status: gatewayResult.status || 500 });
158
+ payment = gatewayResult.payment;
159
+ } else {
160
+ return jsonResponse({
161
+ success: false,
162
+ error: 'Real payments are required',
163
+ detail: 'Set NIBGATE_PAYMENT_MODE=circle-gateway for real local payment tests.'
164
+ }, { status: 400 });
165
+ }
166
+
167
+ const result = await unlock(resource, payment);
168
+ if (!result.ok) return jsonResponse({ success: false, ...result }, { status: result.status || 402 });
169
+
170
+ const response = jsonResponse({
171
+ success: true,
172
+ unlockProof: result.unlockProof,
173
+ expiresInSeconds: result.expiresInSeconds,
174
+ payment,
175
+ resource: result.resource
176
+ });
177
+
178
+ emitHubEvent('payment_completed', resource, {
179
+ ...options,
180
+ ...routeOptions,
181
+ origin,
182
+ payload: payment
183
+ }).catch(() => {});
184
+ emitHubEvent('unlock_completed', resource, {
185
+ ...options,
186
+ ...routeOptions,
187
+ origin,
188
+ payload: payment
189
+ }).catch(() => {});
190
+
191
+ return response;
192
+ }
193
+
194
+ return {
195
+ unlock,
196
+ isUnlocked,
197
+ accessFor,
198
+ protect,
199
+ accessResponse,
200
+ payAndUnlockResponse,
201
+ manifest: (input = {}) => createManifest({ ...input, origin: input.origin || options.origin }),
202
+ manifestResponse: (input = {}) => manifestResponse({ ...input, origin: input.origin || options.origin }),
203
+ emitHubEvent: (event, resource, eventOptions = {}) => emitHubEvent(event, resource, { ...options, ...eventOptions }),
204
+ getGatewayBalances: (balanceOptions = {}) => getGatewayBalances({ ...options, ...balanceOptions }),
205
+ depositToGateway: (amount, depositOptions = {}) => depositToGateway(amount, { ...options, ...depositOptions }),
206
+ withdrawFromGateway: (amount, withdrawOptions = {}) => withdrawFromGateway(amount, { ...options, ...withdrawOptions }),
207
+ createPaymentChallenge: (resource, challengeOptions = {}) => createPaymentChallenge(resource, { ...options, ...challengeOptions }),
208
+ createUnlockToken: (resource, tokenOptions = {}) => createUnlockToken(resource, { ...tokenOptions, secret }),
209
+ verifyUnlockToken: (token, resource) => verifyUnlockToken(token, resource, { secret }),
210
+ actorFromRequest,
211
+ accessModeFor
212
+ };
213
+ }
214
+
215
+ export function protect(resource, handler, options = {}) {
216
+ return createNibgateServer(options).protect(resource, handler);
217
+ }
@@ -0,0 +1,23 @@
1
+ import { normalizeAccessPolicy, normalizeServerResource as normalizeResource } from '../core/resource.js';
2
+
3
+ export function actorFromRequest(request, fallback = 'human') {
4
+ const explicit = request?.headers?.get?.('x-nibgate-actor') || request?.headers?.get?.('x-actor');
5
+ if (explicit && String(explicit).toLowerCase() === 'agent') return 'agent';
6
+ if (explicit && String(explicit).toLowerCase() === 'human') return 'human';
7
+
8
+ const accept = request?.headers?.get?.('accept') || '';
9
+ if (accept.includes('application/json') && request?.headers?.get?.('x402') === 'true') return 'agent';
10
+
11
+ const userAgent = (request?.headers?.get?.('user-agent') || '').toLowerCase();
12
+ if (/(bot|crawler|spider|agent|llm|gpt|claude|perplexity|anthropic|openai|mistral|gemini|firecrawl)/i.test(userAgent)) {
13
+ return 'agent';
14
+ }
15
+
16
+ return fallback;
17
+ }
18
+
19
+ export function accessModeFor(resourceInput, actor = 'human') {
20
+ const resource = normalizeResource(resourceInput);
21
+ const access = normalizeAccessPolicy(resource.access);
22
+ return actor === 'agent' ? access.agents : access.humans;
23
+ }