@nibgate/sdk 0.2.5 → 0.2.7

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.
@@ -1,6 +1,34 @@
1
1
  import { stringifyJson } from './json.js';
2
2
 
3
- const runtimeImport = new Function('specifier', 'return import(specifier)');
3
+ let cachedCircleModule = null;
4
+
5
+ async function getCircleClient(options = {}) {
6
+ if (cachedCircleModule) return cachedCircleModule;
7
+
8
+ if (options.clientModule) {
9
+ cachedCircleModule = options.clientModule;
10
+ return cachedCircleModule;
11
+ }
12
+
13
+ const moduleUrl = options.clientModuleUrl || '@circle-fin/x402-batching/client';
14
+
15
+ try {
16
+ cachedCircleModule = await import(moduleUrl);
17
+ return cachedCircleModule;
18
+ } catch (error) {
19
+ if (!options.clientModuleUrl) {
20
+ throw new Error(
21
+ `Could not load @circle-fin/x402-batching/client from node_modules. ` +
22
+ `Provide a clientModuleUrl option (e.g. "https://esm.sh/@circle-fin/x402-batching@3.2.0/client?bundle") ` +
23
+ `to load from CDN. Original error: ${error.message}`
24
+ );
25
+ }
26
+ throw new Error(
27
+ `Could not load Circle Gateway client from CDN: ${error.message}. ` +
28
+ `Check that ${options.clientModuleUrl} is reachable.`
29
+ );
30
+ }
31
+ }
4
32
 
5
33
  function encodeBase64(value) {
6
34
  const text = typeof value === 'string' ? value : stringifyJson(value);
@@ -19,9 +47,7 @@ export async function createCircleGatewayBrowserAdapter(options = {}) {
19
47
  throw new Error('Circle Gateway browser adapter requires an EVM signer with address and signTypedData.');
20
48
  }
21
49
 
22
- const circleClientModule = options.clientModule || (options.clientModuleUrl
23
- ? await runtimeImport(options.clientModuleUrl)
24
- : await runtimeImport('@circle-fin/x402-batching/client'));
50
+ const circleClientModule = await getCircleClient(options);
25
51
  const { BatchEvmScheme } = circleClientModule;
26
52
  const scheme = new BatchEvmScheme(signer);
27
53
  const network = options.network || options.chainId && `eip155:${options.chainId}` || 'eip155:5042002';
@@ -70,6 +70,38 @@ function autoDeriveImage() {
70
70
  return metaContent('og:image') || undefined;
71
71
  }
72
72
 
73
+ function autoDeriveDescription() {
74
+ return metaContent('og:description') || metaContent('description') || undefined;
75
+ }
76
+
77
+ function autoDeriveTitle() {
78
+ const win = browserEnv();
79
+ return metaContent('og:title') || metaContent('twitter:title') || (win ? win.document.title : '') || undefined;
80
+ }
81
+
82
+ function autoDeriveType() {
83
+ const ogType = metaContent('og:type').toLowerCase();
84
+ if (ogType.includes('music') || ogType.includes('audio') || ogType.includes('song')) return 'music';
85
+ if (ogType.includes('video') || ogType.includes('movie')) return 'video';
86
+ if (ogType.includes('image') || ogType.includes('photo')) return 'image';
87
+ return 'article';
88
+ }
89
+
90
+ function autoDeriveTags() {
91
+ const kw = metaContent('keywords');
92
+ if (!kw) return undefined;
93
+ return kw.split(',').map((t) => t.trim().toLowerCase()).filter(Boolean).slice(0, 8);
94
+ }
95
+
96
+ function accessForPrice(price, explicitAccess) {
97
+ if (explicitAccess && typeof explicitAccess === 'object' && Object.keys(explicitAccess).length > 0) {
98
+ return normalizeAccessPolicy(explicitAccess);
99
+ }
100
+ const hasPrice = price !== undefined && price !== null && price !== '' && Number.parseFloat(price) > 0;
101
+ if (hasPrice) return { humans: 'paid', agents: 'paid' };
102
+ return { humans: 'free', agents: 'free' };
103
+ }
104
+
73
105
  export function normalizeResource(resource = {}) {
74
106
  const input = typeof resource === 'string' ? { id: resource } : (resource || {});
75
107
  const {
@@ -87,21 +119,25 @@ export function normalizeResource(resource = {}) {
87
119
 
88
120
  const path = input.path || input.route || undefined;
89
121
  const url = input.url || autoDeriveUrl(path) || undefined;
122
+ const explicitAccess = input.access;
123
+ const price = input.price ?? input.amount ?? '';
90
124
 
91
125
  return {
92
126
  ...v1Input,
93
127
  id: String(input.id || input.contentId || input.slug || '').trim(),
94
- title: String(input.title || input.name || '').trim(),
95
- type: normalizeContentType(input.type || input.contentType),
96
- price: input.price ?? input.amount ?? '',
128
+ title: String(input.title || input.name || autoDeriveTitle() || 'Untitled').trim(),
129
+ type: normalizeContentType(input.type || input.contentType || autoDeriveType()),
130
+ price,
131
+ currency: input.currency || 'USDC',
97
132
  paymentRail: normalizePaymentRail(input.paymentRail || input.paymentMode || input.rail),
98
133
  recipient: input.recipient || input.receiver || input.receiverAddress || input.payTo || input.creatorWallet || undefined,
99
134
  payTo: input.payTo || input.recipient || input.receiver || input.receiverAddress || input.creatorWallet || undefined,
100
135
  path,
101
136
  url,
102
137
  imageUrl: input.imageUrl || input.image || autoDeriveImage() || undefined,
103
- tags: input.tags || undefined,
104
- access: normalizeAccessPolicy(input.access),
138
+ description: input.description || input.summary || autoDeriveDescription() || undefined,
139
+ tags: input.tags || autoDeriveTags() || undefined,
140
+ access: accessForPrice(price, explicitAccess),
105
141
  unlock: normalizeUnlockPolicy(input.unlock),
106
142
  ratingsEnabled: input.ratingsEnabled ?? input.enableRatings ?? input.reputation?.ratingsEnabled ?? true,
107
143
  reputation: {
@@ -125,8 +161,8 @@ export function validateResourceMetadata(resource = {}, options = {}) {
125
161
  const normalized = normalizeResource(resource);
126
162
  const warnings = [];
127
163
  const errors = [];
128
- const required = options.required || ['id', 'title', 'url', 'type'];
129
- const recommended = options.recommended || ['description', 'imageUrl', 'tags'];
164
+ const required = options.required || ['id', 'type'];
165
+ const recommended = options.recommended || ['title', 'url', 'description', 'imageUrl', 'tags'];
130
166
 
131
167
  for (const field of required) {
132
168
  if (!hasValue(normalized[field])) errors.push(`Missing required content metadata: ${field}`);
@@ -168,6 +204,5 @@ export function normalizeServerResource(resource = {}) {
168
204
  title: normalized.title || String((typeof resource === 'object' && (resource.name || resource.id)) || 'Untitled content').trim(),
169
205
  price: normalized.price || '0',
170
206
  path: normalized.path || '/',
171
- currency: normalized.currency || 'USDC'
172
207
  };
173
208
  }