@nibgate/sdk 0.2.1 → 0.2.4

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/SKILL.md CHANGED
@@ -40,6 +40,8 @@ Paste the dashboard widget into the verified site layout:
40
40
 
41
41
  If the widget loads after app code, the SDK queues events and flushes them when the widget is ready.
42
42
 
43
+ **Adblocker bypass:** The widget now sends events to `/api/hub/evt` instead of `/api/hub/track` to avoid adblocker filter lists that target the word "track". The old `/api/hub/track` endpoint is preserved for backward compatibility. If you self-host the backend, ensure both routes are registered.
44
+
43
45
  ---
44
46
 
45
47
  ## 2. Resource Shape
@@ -65,6 +67,13 @@ const resource = {
65
67
 
66
68
  Allowed types: `article`, `image`, `music`, `video` (aliases like `audio→music`, `photo→image` are normalized). Use stable IDs — changing IDs breaks continuity for Explore, receipts, and reputation.
67
69
 
70
+ **Auto-derived fields:** When running in a browser, the SDK auto-fills:
71
+ - `url` from `window.location.origin + path` if `path` is provided but `url` is not
72
+ - `imageUrl` from `<meta property="og:image">` if not explicitly set
73
+ - `recipient` is **not required client-side** — the server's 402 payment challenge provides the canonical wallet address. Missing it generates a warning, not an error.
74
+
75
+ So a minimal client-side resource only needs `id`, `title`, `path`, and `price` — the rest is filled in automatically.
76
+
68
77
  **Important:** The `image`, `description`, and `title` fields become the public thumbnail and card copy on the Explore page. Use a teaser preview, not the actual paid file.
69
78
 
70
79
  ---
@@ -119,6 +128,8 @@ export function GET(request: Request) {
119
128
 
120
129
  **The `accessPath` is queried exactly as-is.** The SDK does not auto-append `?id=` or route params. If your access route needs a content identifier, include it in the path (e.g., `/api/nibgate/access/my-content-id`) or pass it as a query param in the resource's `accessPath` field.
121
130
 
131
+ **After successful gateway payment, `accessResponse` automatically emits `payment_completed` and `unlock_completed` events to the Hub** (via `emitHubEvent`). This requires `NIBGATE_SITE_ID`, `NIBGATE_SITE_TOKEN`, and `NIBGATE_API_BASE` to be set — see [Required Env Vars](#11-required-env-vars). Without those, the payment still processes and the unlock proof is returned, but unlock counts and revenue on the Hub will not update.
132
+
122
133
  **Custom backends:** If you build your own access route instead of using `accessResponse()`, your route must:
123
134
  - Return 402 with the challenge JSON when no payment proof is present
124
135
  - Check for `payment-signature` header — if present and valid, return 200 with `{ ok: true, unlockProof: "...", payment: {...} }`
@@ -348,7 +359,128 @@ Some smart contract wallets (Gnosis Safe, Argent, etc.) may not support `eth_sig
348
359
 
349
360
  ---
350
361
 
351
- ## 9. Onchain Reputation & Ratings
362
+ ## 9. AI Agent Content Discovery & Purchase (x402)
363
+
364
+ AI agents can discover and purchase content on Nibgate through the same x402 protocol used by browser wallets — no browser, HTML, or widget needed.
365
+
366
+ ### Agent Flow
367
+
368
+ 1. **Discover** — agent hits the Hub's explore API or polls creator `/nibgate.json` manifests:
369
+
370
+ ```bash
371
+ GET https://nibgate.xyz/api/hub/explore/content?type=article&limit=100
372
+ Accept: application/json
373
+ ```
374
+
375
+ Response includes content with `price`, `currency`, `access` policy, `websiteDomain`, and the creator's `recipientWallet`.
376
+
377
+ 2. **Access** — agent hits the content's access URL identifying as an agent:
378
+
379
+ ```bash
380
+ GET https://creator.example/api/nibgate/access?slug=my-article
381
+ x-nibgate-actor: agent
382
+ Accept: application/json
383
+ ```
384
+
385
+ 3. **402 Challenge** — if payment is required, server returns HTTP 402 with a `PAYMENT-REQUIRED` header containing a base64-encoded x402 v2 challenge with the `extra.verifyingContract` field (Gateway Wallet address).
386
+
387
+ 4. **Sign Payment** — agent signs an EIP-3009 `TransferWithAuthorization` using an EVM wallet with USDC in Circle Gateway:
388
+
389
+ ```ts
390
+ import { BatchEvmScheme } from '@circle-fin/x402-batching/client'
391
+ import { privateKeyToAccount } from 'viem/accounts'
392
+
393
+ const wallet = privateKeyToAccount('0x...')
394
+ const scheme = new BatchEvmScheme(wallet)
395
+ const payload = await scheme.createPaymentPayload(2, gatewayOption)
396
+ ```
397
+
398
+ 5. **Retry** — agent retries the request with the signed payment:
399
+
400
+ ```bash
401
+ GET https://creator.example/api/nibgate/access?slug=my-article
402
+ payment-signature: <base64 payload>
403
+ Accept: application/json
404
+ ```
405
+
406
+ 6. **Unlocked** — server returns `200` with `{ ok: true, unlockProof, payment, resource }`.
407
+
408
+ ### Headless GatewayClient (Full Auto Flow)
409
+
410
+ The `GatewayClient` from `@circle-fin/x402-batching/client` handles steps 3-5 automatically:
411
+
412
+ ```ts
413
+ import { GatewayClient } from '@circle-fin/x402-batching/client'
414
+
415
+ const agent = new GatewayClient({
416
+ chain: 'arcTestnet',
417
+ privateKey: '0x...',
418
+ rpcUrl: 'https://rpc.testnet.arc.network'
419
+ })
420
+
421
+ const result = await agent.pay('https://creator.example/api/nibgate/access?slug=my-article', {
422
+ headers: { 'x-nibgate-actor': 'agent' }
423
+ })
424
+ // { data: { ok: true, unlockProof, ... }, formattedAmount: '0.01', transaction: '0x...' }
425
+ ```
426
+
427
+ ### Agent Wallet Requirements
428
+
429
+ - **USDC in Circle Gateway** on Arc Testnet (chain ID 5042002) — `agent.deposit('10')` moves USDC from wallet → Gateway
430
+ - **Gas** — on Arc Testnet the native token IS USDC, so the wallet needs USDC for both Gateway deposits and transaction fees
431
+ - **Private key** — must be accessible to the agent process (env var, secure store, or derived from a mnemonic)
432
+
433
+ ### Agent Identification
434
+
435
+ Agents identify themselves via headers (in priority order):
436
+
437
+ | Header | Value | Detected When |
438
+ |--------|-------|---------------|
439
+ | `x-nibgate-actor` | `agent` | Explicit agent declaration |
440
+ | `Accept` + `x402` | `application/json` + `true` | Accept header includes JSON and x402 is set |
441
+ | `User-Agent` | bot pattern | Matches `/bot|agent|llm|gpt|claude|perplexity/i` |
442
+
443
+ ### Agent-Specific Pricing
444
+
445
+ Creators can set different prices for humans and agents in the resource's `access` policy:
446
+
447
+ ```ts
448
+ const resource = {
449
+ access: { humans: 'free', agents: 'paid' }, // agents pay, humans free
450
+ price: '0.002',
451
+ // or
452
+ access: { humans: 'paid', agents: 'paid' }, // both pay
453
+ // or
454
+ access: { humans: 'paid', agents: 'blocked' }, // agents blocked entirely
455
+ }
456
+ ```
457
+
458
+ ### Stress Test Script
459
+
460
+ The repo includes a stress test script at `demo/stress-test-agents.mjs` that simulates N agents discovering content from the Hub and purchasing via x402:
461
+
462
+ ```bash
463
+ node demo/stress-test-agents.mjs \
464
+ --mnemonic "twelve word seed phrase here" \
465
+ --agents 50 --concurrency 10 \
466
+ --hub-url "https://nibgate.xyz" \
467
+ --access-template "https://{origin}/api/nibgate/access?slug={slug}" \
468
+ --fund --fund-amount 5 \
469
+ --loop --interval 300
470
+ ```
471
+
472
+ The script:
473
+ - Derives deterministic wallets from the mnemonic (wallet[0] = master, wallet[1..N-1] = agents)
474
+ - Discovers content from the Hub explore API or from manifests
475
+ - Filters for agent-purchasable content (paid, not blocked, valid recipient)
476
+ - Funds agents from master via native USDC transfer + Gateway deposit (`--fund`)
477
+ - Purchases content via `GatewayClient.pay()` (full x402 auto flow)
478
+ - Reports per-agent results with aggregate stats
479
+ - Continues on loop with configurable interval
480
+
481
+ ---
482
+
483
+ ## 10. Onchain Reputation & Ratings
352
484
 
353
485
  After a verified unlock, users can rate content onchain via the `NibgateReputation.sol` contract deployed on Arc Testnet.
354
486
 
@@ -382,7 +514,7 @@ Or buttons with `data-nibgate-rating-value="4"` attributes. Ratings are 1-5.
382
514
 
383
515
  ---
384
516
 
385
- ## 10. Hardcoded Or File-Based Content
517
+ ## 11. Hardcoded Or File-Based Content
386
518
 
387
519
  Hardcoded content, MDX files, Markdown files, static JSON files, and repo-local media can be gated when the protected payload stays server-side until access is allowed.
388
520
 
@@ -399,37 +531,40 @@ Hardcoded content, MDX files, Markdown files, static JSON files, and repo-local
399
531
 
400
532
  ---
401
533
 
402
- ## 11. Required Env Vars
534
+ ## 12. Required Env Vars
403
535
 
404
536
  ```bash
405
537
  NIBGATE_SITE_ORIGIN=https://creator.example
406
- NIBGATE_SITE_ID=site_...
407
- NIBGATE_SITE_TOKEN=ngv_...
408
- NIBGATE_API_BASE=https://api.nibgate.xyz
538
+ NIBGATE_SITE_ID=site_... # Hub website UUID — required for emitHubEvent to report unlocks
539
+ NIBGATE_SITE_TOKEN=ngv_... # Hub website verify token — required for emitHubEvent
540
+ NIBGATE_API_BASE=https://nibgate.xyz # Hub API base — required for emitHubEvent
409
541
  NIBGATE_SECRET=server_only_unlock_secret
410
542
  NIBGATE_PAYMENT_MODE=circle-gateway
411
543
  NIBGATE_PAYMENT_NETWORK=eip155:5042002
412
544
  NIBGATE_SELLER_ADDRESS=0xCreatorReceiver
413
545
  ```
414
546
 
547
+ **Without `NIBGATE_SITE_ID` and `NIBGATE_SITE_TOKEN`**, `accessResponse()` still processes x402 payments and returns unlock proofs, but `payment_completed` and `unlock_completed` events are NOT sent to the Hub. Unlock counts, revenue, and volume on Explore and leaderboards will not update. Set these to enable automatic event reporting after every successful gateway purchase.
548
+
415
549
  Only expose values with `NEXT_PUBLIC_` or client-side env names when they are intentionally public (site id, public token, API base, reputation contract address). Never ship `NIBGATE_SECRET`, private keys, R2 credentials, Resend keys, database URLs, or privileged payment credentials to browser code.
416
550
 
417
551
  ---
418
552
 
419
- ## 12. Common Gotchas
553
+ ## 13. Common Gotchas
420
554
 
421
555
  - **Widget is only for analytics.** It does not pop up wallets or handle checkout. Use the SDK browser helpers for that.
422
556
  - **accessPath is literal.** The SDK does not append `?id=` or route params. Include identifiers in the path or query string manually.
423
557
  - **Custom backends must handle `payment-signature` header.** If you build your own access route without `accessResponse()`, your route must detect `payment-signature` header and return 200 on valid proof, not 402.
424
558
  - **Cookie `[object Object]` bug.** The unlock proof must be a string (the token from `createUnlockToken`), not an object. `storePaymentProof` now handles both, but ensure your server returns `unlockProof` as a string.
425
559
  - **Secrets must match.** `NIBGATE_SECRET` must be the same in `createNibgateServer()`, the access route, and the pay route. Mismatch causes unlock tokens to fail verification silently.
560
+ - **Unlock events need three env vars.** `accessResponse()` emits `payment_completed` and `unlock_completed` to the Hub after gateway payment, but only if `NIBGATE_SITE_ID`, `NIBGATE_SITE_TOKEN`, and `NIBGATE_API_BASE` are set. Without them, the x402 payment still works and the unlock proof is returned, but unlock counts and volume on Explore will not update.
426
561
  - **Smart contract wallets** may not support `eth_signTypedData_v4`. Use an EOA or the server-side pay route.
427
562
  - **Wallet extension conflicts** can cause signature corruption if multiple wallets are installed. Advise users to disable other wallet extensions when testing.
428
563
  - **Deposit before testing locally.** Run `npx nibgate deposit 10` to fund the Gateway facilitator balance.
429
564
 
430
565
  ---
431
566
 
432
- ## 13. Webhooks (Server-to-Server Notifications)
567
+ ## 14. Webhooks (Server-to-Server Notifications)
433
568
 
434
569
  Receive notifications when payments, unlocks, or ratings happen — without polling.
435
570
 
@@ -470,7 +605,7 @@ Events emitted automatically by `createNibgateServer`: `payment_completed`, `unl
470
605
 
471
606
  ---
472
607
 
473
- ## 14. Never Do These
608
+ ## 15. Never Do These
474
609
 
475
610
  - Do not hide paid HTML with CSS or client state after rendering it publicly
476
611
  - Do not fake payment IDs, receipts, unlocks, or successful access
@@ -481,7 +616,7 @@ Events emitted automatically by `createNibgateServer`: `payment_completed`, `unl
481
616
 
482
617
  ---
483
618
 
484
- ## 14. Framework Notes
619
+ ## 16. Framework Notes
485
620
 
486
621
  - **Next.js**: Use route handlers for `/nibgate.json` and `/api/nibgate/access`. Protect content before rendering paid payloads. Use `server-only` for private modules.
487
622
  - **Express/NestJS**: Use middleware, controllers, or guards around protected routes. Mount the admin router at `/admin/nibgate`.