@nibgate/sdk 0.2.6 → 0.2.8
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 +33 -19
- package/dist/nibgate.js +42 -6
- package/dist/nibgate.js.map +2 -2
- package/dist/nibgate.min.js +2 -2
- package/dist/nibgate.min.js.map +3 -3
- package/package.json +1 -1
- package/src/browser/evm-gateway.js +19 -2
- package/src/browser/gateway.js +30 -4
- package/src/browser/index.js +1 -1
- package/src/core/resource.js +1 -1
- package/src/index.d.ts +3 -0
package/SKILL.md
CHANGED
|
@@ -42,37 +42,51 @@ If the widget loads after app code, the SDK queues events and flushes them when
|
|
|
42
42
|
|
|
43
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
44
|
|
|
45
|
+
**Hosted mode (zero backend code):** If you don't want to run your own access route, mark premium content with a data attribute and the widget handles everything:
|
|
46
|
+
|
|
47
|
+
```html
|
|
48
|
+
<div data-nibgate-premium="0.01" data-nibgate-recipient="0xYourWallet">
|
|
49
|
+
<p>Teaser text shown to everyone...</p>
|
|
50
|
+
<div data-nibgate-unlock-card>
|
|
51
|
+
<span data-nibgate-wallet-label>No wallet</span>
|
|
52
|
+
<button data-nibgate-connect>Connect</button>
|
|
53
|
+
<button data-nibgate-unlock-btn>Unlock for 0.01 USDC</button>
|
|
54
|
+
<p data-nibgate-status></p>
|
|
55
|
+
</div>
|
|
56
|
+
<div data-nibgate-unlocked hidden>
|
|
57
|
+
Full premium content here...
|
|
58
|
+
</div>
|
|
59
|
+
</div>
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
No SDK import, no server access route, no env vars. The default wallet is set once in the Nibgate dashboard — or override per-post with `data-nibgate-recipient`. Custom price per-post: change `data-nibgate-premium="0.05"`.
|
|
63
|
+
|
|
45
64
|
---
|
|
46
65
|
|
|
47
|
-
## 2. Resource Shape
|
|
66
|
+
## 2. Resource Shape (Minimal)
|
|
48
67
|
|
|
49
|
-
|
|
68
|
+
The SDK auto-derives most fields from meta tags and defaults. You only need:
|
|
50
69
|
|
|
51
70
|
```ts
|
|
52
71
|
const resource = {
|
|
53
72
|
id: post.id,
|
|
54
|
-
title: post.title,
|
|
55
|
-
description: post.excerpt,
|
|
56
|
-
type: 'article',
|
|
57
|
-
price: '0.01',
|
|
58
|
-
currency: 'USDC',
|
|
59
|
-
recipient: post.creatorWallet,
|
|
73
|
+
title: post.title, // auto-fallsback to og:title → document.title
|
|
60
74
|
path: `/posts/${post.slug}`,
|
|
61
|
-
|
|
62
|
-
tags: ['essay', 'research'],
|
|
63
|
-
access: { humans: 'paid', agents: 'paid' },
|
|
64
|
-
unlock: { mode: 'one_time' }
|
|
75
|
+
price: '0.01' // sets access: { humans: 'paid', agents: 'paid' } automatically
|
|
65
76
|
}
|
|
66
77
|
```
|
|
67
78
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
- `
|
|
72
|
-
- `
|
|
73
|
-
- `
|
|
79
|
+
The rest fills in automatically from your page's HTML:
|
|
80
|
+
- `url` from `window.location.origin + path`
|
|
81
|
+
- `type` from `<meta property="og:type">` (defaults to `article`)
|
|
82
|
+
- `imageUrl` from `<meta property="og:image">`
|
|
83
|
+
- `description` from `<meta property="og:description">` → `<meta name="description">`
|
|
84
|
+
- `tags` from `<meta name="keywords">`
|
|
85
|
+
- `currency` defaults to `USDC`
|
|
86
|
+
- `access` defaults to `paid` when `price > 0`, otherwise `free`
|
|
87
|
+
- `recipient` is optional (server's 402 challenge provides the real wallet)
|
|
74
88
|
|
|
75
|
-
|
|
89
|
+
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.
|
|
76
90
|
|
|
77
91
|
**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.
|
|
78
92
|
|
package/dist/nibgate.js
CHANGED
|
@@ -38,6 +38,27 @@ var Nibgate = (() => {
|
|
|
38
38
|
__export(gateway_exports, {
|
|
39
39
|
createCircleGatewayBrowserAdapter: () => createCircleGatewayBrowserAdapter
|
|
40
40
|
});
|
|
41
|
+
async function getCircleClient(options = {}) {
|
|
42
|
+
if (cachedCircleModule) return cachedCircleModule;
|
|
43
|
+
if (options.clientModule) {
|
|
44
|
+
cachedCircleModule = options.clientModule;
|
|
45
|
+
return cachedCircleModule;
|
|
46
|
+
}
|
|
47
|
+
const moduleUrl = options.clientModuleUrl || "@circle-fin/x402-batching/client";
|
|
48
|
+
try {
|
|
49
|
+
cachedCircleModule = await import(moduleUrl);
|
|
50
|
+
return cachedCircleModule;
|
|
51
|
+
} catch (error) {
|
|
52
|
+
if (!options.clientModuleUrl) {
|
|
53
|
+
throw new Error(
|
|
54
|
+
`Could not load @circle-fin/x402-batching/client from node_modules. Provide a clientModuleUrl option (e.g. "https://esm.sh/@circle-fin/x402-batching@3.2.0/client?bundle") to load from CDN. Original error: ${error.message}`
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
throw new Error(
|
|
58
|
+
`Could not load Circle Gateway client from CDN: ${error.message}. Check that ${options.clientModuleUrl} is reachable.`
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
41
62
|
function encodeBase64(value) {
|
|
42
63
|
const text = typeof value === "string" ? value : stringifyJson(value);
|
|
43
64
|
if (typeof Buffer !== "undefined") return Buffer.from(text).toString("base64");
|
|
@@ -52,7 +73,7 @@ var Nibgate = (() => {
|
|
|
52
73
|
if (!signer?.address || typeof signer.signTypedData !== "function") {
|
|
53
74
|
throw new Error("Circle Gateway browser adapter requires an EVM signer with address and signTypedData.");
|
|
54
75
|
}
|
|
55
|
-
const circleClientModule =
|
|
76
|
+
const circleClientModule = await getCircleClient(options);
|
|
56
77
|
const { BatchEvmScheme } = circleClientModule;
|
|
57
78
|
const scheme = new BatchEvmScheme(signer);
|
|
58
79
|
const network = options.network || options.chainId && `eip155:${options.chainId}` || "eip155:5042002";
|
|
@@ -110,11 +131,11 @@ var Nibgate = (() => {
|
|
|
110
131
|
}
|
|
111
132
|
};
|
|
112
133
|
}
|
|
113
|
-
var
|
|
134
|
+
var cachedCircleModule;
|
|
114
135
|
var init_gateway = __esm({
|
|
115
136
|
"src/browser/gateway.js"() {
|
|
116
137
|
init_json();
|
|
117
|
-
|
|
138
|
+
cachedCircleModule = null;
|
|
118
139
|
}
|
|
119
140
|
});
|
|
120
141
|
|
|
@@ -137,6 +158,7 @@ var Nibgate = (() => {
|
|
|
137
158
|
createCircleGatewayBrowserAdapter: () => createCircleGatewayBrowserAdapter2,
|
|
138
159
|
createEvmGatewayUnlock: () => createEvmGatewayUnlock,
|
|
139
160
|
createGate: () => createGate,
|
|
161
|
+
createHostedUnlock: () => createHostedUnlock,
|
|
140
162
|
createNibgate: () => createNibgate,
|
|
141
163
|
createNibgateContentSettings: () => createNibgateContentSettings,
|
|
142
164
|
createOnchainRating: () => createOnchainRating,
|
|
@@ -314,7 +336,7 @@ var Nibgate = (() => {
|
|
|
314
336
|
const normalized = normalizeResource(resource);
|
|
315
337
|
const warnings = [];
|
|
316
338
|
const errors = [];
|
|
317
|
-
const required = options.required || ["id"];
|
|
339
|
+
const required = options.required || ["id", "type"];
|
|
318
340
|
const recommended = options.recommended || ["title", "url", "description", "imageUrl", "tags"];
|
|
319
341
|
for (const field of required) {
|
|
320
342
|
if (!hasValue(normalized[field])) errors.push(`Missing required content metadata: ${field}`);
|
|
@@ -782,10 +804,16 @@ var Nibgate = (() => {
|
|
|
782
804
|
const gateway = await Promise.resolve().then(() => (init_gateway(), gateway_exports));
|
|
783
805
|
return gateway.createCircleGatewayBrowserAdapter(options);
|
|
784
806
|
}
|
|
807
|
+
var DEFAULT_CIRCLE_CDN = "https://esm.sh/@circle-fin/x402-batching@3.2.0/client?bundle";
|
|
808
|
+
var HOSTED_PAY_URL = "https://api.nibgate.xyz/api/hub/pay";
|
|
809
|
+
function resolveAccessPath(resource, options) {
|
|
810
|
+
if (options.hosted || options.accessPath === "hosted") return HOSTED_PAY_URL;
|
|
811
|
+
return options.accessPath || resource.accessPath || "/api/nibgate/access";
|
|
812
|
+
}
|
|
785
813
|
function createEvmGatewayUnlock(resource, options = {}) {
|
|
786
814
|
const item = createGate(resource, options.gateOptions || {});
|
|
787
815
|
const win = browserWindow();
|
|
788
|
-
const accessPath =
|
|
816
|
+
const accessPath = resolveAccessPath(item.resource, options);
|
|
789
817
|
const source = options.source || "nibgate-evm-gateway";
|
|
790
818
|
const network = options.network || "eip155:5042002";
|
|
791
819
|
const statusTarget = typeof options.status === "string" ? win?.document.querySelector(options.status) : options.status;
|
|
@@ -876,7 +904,7 @@ var Nibgate = (() => {
|
|
|
876
904
|
signTypedData: (typedData) => evm.request({ method: "eth_signTypedData_v4", params: [walletAddress, stringifyJson(typedData)] })
|
|
877
905
|
},
|
|
878
906
|
clientModule: options.circleClientModule,
|
|
879
|
-
clientModuleUrl: options.circleClientModuleUrl
|
|
907
|
+
clientModuleUrl: options.circleClientModuleUrl || DEFAULT_CIRCLE_CDN
|
|
880
908
|
});
|
|
881
909
|
return gatewayWallet.pay(input);
|
|
882
910
|
}
|
|
@@ -938,6 +966,14 @@ var Nibgate = (() => {
|
|
|
938
966
|
if (options.autoMount !== false) mount();
|
|
939
967
|
return controller;
|
|
940
968
|
}
|
|
969
|
+
function createHostedUnlock(resource, options = {}) {
|
|
970
|
+
return createEvmGatewayUnlock(resource, {
|
|
971
|
+
...options,
|
|
972
|
+
hosted: true,
|
|
973
|
+
circleClientModuleUrl: options.circleClientModuleUrl || DEFAULT_CIRCLE_CDN,
|
|
974
|
+
noWalletMessage: options.noWalletMessage || "Install MetaMask or another EVM wallet to unlock premium content."
|
|
975
|
+
});
|
|
976
|
+
}
|
|
941
977
|
|
|
942
978
|
// src/browser/reputation.js
|
|
943
979
|
var RATE_CONTENT_SELECTOR = "0xc62fad09";
|