@neus/sdk 1.1.0 → 1.1.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/sponsor.js ADDED
@@ -0,0 +1,95 @@
1
+ import { ValidationError, ApiError, NetworkError } from './errors.js';
2
+
3
+ /**
4
+ * Request short-lived billing authorization so verification usage bills the app owner.
5
+ * Requires a completed app registration (`sponsor-grants` delegation) on orgWallet.
6
+ */
7
+ export async function fetchSponsorGrant(params = {}) {
8
+ const {
9
+ apiUrl = 'https://api.neus.network',
10
+ appId,
11
+ orgWallet,
12
+ verifierIds = [],
13
+ targetChains = [],
14
+ origin,
15
+ expiresInSeconds = 900,
16
+ fetchImpl = fetch
17
+ } = params;
18
+
19
+ const normalizedAppId = typeof appId === 'string' ? appId.trim() : '';
20
+ const normalizedOrg = typeof orgWallet === 'string' ? orgWallet.trim().toLowerCase() : '';
21
+ if (!normalizedAppId) {
22
+ throw new ValidationError('appId is required for sponsor grant');
23
+ }
24
+ if (!normalizedOrg || !/^0x[a-f0-9]{40}$/.test(normalizedOrg)) {
25
+ throw new ValidationError('orgWallet must be a valid EVM address');
26
+ }
27
+
28
+ let base = String(apiUrl || 'https://api.neus.network').replace(/\/+$/, '');
29
+ try {
30
+ const url = new URL(base);
31
+ if (url.hostname.endsWith('neus.network') && url.protocol === 'http:') {
32
+ url.protocol = 'https:';
33
+ }
34
+ base = url.toString().replace(/\/+$/, '');
35
+ } catch {
36
+ void 0;
37
+ }
38
+
39
+ const headers = {
40
+ 'Content-Type': 'application/json',
41
+ Accept: 'application/json',
42
+ 'X-Neus-App': normalizedAppId,
43
+ 'X-Neus-Sdk': 'js'
44
+ };
45
+ if (typeof origin === 'string' && origin.trim()) {
46
+ headers.Origin = origin.trim();
47
+ }
48
+
49
+ const body = {
50
+ orgWallet: normalizedOrg,
51
+ scope: 'sponsored-verification',
52
+ expiresInSeconds,
53
+ ...(Array.isArray(verifierIds) && verifierIds.length > 0
54
+ ? { verifierIds: verifierIds.map((v) => String(v).trim()).filter(Boolean).slice(0, 25) }
55
+ : {}),
56
+ ...(Array.isArray(targetChains) && targetChains.length > 0
57
+ ? { targetChains: targetChains.filter((n) => Number.isFinite(Number(n))).slice(0, 25) }
58
+ : {})
59
+ };
60
+
61
+ let response;
62
+ try {
63
+ response = await fetchImpl(`${base}/api/v1/sponsor/grant`, {
64
+ method: 'POST',
65
+ headers,
66
+ body: JSON.stringify(body)
67
+ });
68
+ } catch (error) {
69
+ throw new NetworkError(`Sponsor grant request failed: ${error?.message || String(error)}`);
70
+ }
71
+
72
+ let payload;
73
+ try {
74
+ payload = await response.json();
75
+ } catch {
76
+ payload = { success: false, error: { message: 'Invalid JSON response' } };
77
+ }
78
+
79
+ if (!response.ok || payload?.success !== true) {
80
+ throw ApiError.fromResponse(response, payload);
81
+ }
82
+
83
+ const token = payload?.data?.sponsorGrant;
84
+ if (!token || typeof token !== 'string') {
85
+ throw new ApiError('Sponsor grant response missing sponsorGrant token', payload?.error);
86
+ }
87
+
88
+ return {
89
+ sponsorGrant: token,
90
+ exp: payload?.data?.exp,
91
+ orgWallet: payload?.data?.orgWallet || normalizedOrg,
92
+ appId: payload?.data?.appId || normalizedAppId,
93
+ maxCredits: payload?.data?.maxCredits
94
+ };
95
+ }
package/types.d.ts CHANGED
@@ -57,9 +57,18 @@ declare module '@neus/sdk' {
57
57
 
58
58
  export interface NeusClientConfig {
59
59
  apiUrl?: string;
60
+ /** Optional server profile key — MCP/CI only; not required for VerifyGate or gateCheck. */
60
61
  apiKey?: string;
62
+ /** Public app attribution id (non-secret). */
61
63
  appId?: string;
62
- /** Optional: only when using legacy `delegationQHash` on verify requests. App-linked servers rely on `appId` + Origin + stored delegation. */
64
+ /** Hub wallet that pays for user verification checks (your NEUS account). */
65
+ billingWallet?: string;
66
+ /** Alias for billingWallet. */
67
+ sponsorOrgWallet?: string;
68
+ orgWallet?: string;
69
+ /** Site origin used when issuing billing authorization (defaults to browser origin). */
70
+ appOrigin?: string;
71
+ /** @deprecated Advanced server path only — use appId + billingWallet for the default app flow. */
63
72
  appLinkQHash?: string;
64
73
  paymentSignature?: string;
65
74
  extraHeaders?: Record<string, string>;
@@ -68,6 +77,26 @@ declare module '@neus/sdk' {
68
77
  enableLogging?: boolean;
69
78
  }
70
79
 
80
+ export interface FetchSponsorGrantParams {
81
+ apiUrl?: string;
82
+ appId: string;
83
+ orgWallet: string;
84
+ verifierIds?: string[];
85
+ targetChains?: number[];
86
+ origin?: string;
87
+ expiresInSeconds?: number;
88
+ }
89
+
90
+ export interface FetchSponsorGrantResult {
91
+ sponsorGrant: string;
92
+ exp?: number;
93
+ orgWallet: string;
94
+ appId: string;
95
+ maxCredits?: number;
96
+ }
97
+
98
+ export function fetchSponsorGrant(params: FetchSponsorGrantParams): Promise<FetchSponsorGrantResult>;
99
+
71
100
  export interface VerificationOptions {
72
101
  privacyLevel?: PrivacyLevel;
73
102
  enableIpfs?: boolean;
package/utils.js CHANGED
@@ -1023,6 +1023,8 @@ export function getHostedCheckoutUrl(opts = {}) {
1023
1023
  if (opts.intent) params.set('intent', String(opts.intent));
1024
1024
  if (opts.origin) params.set('origin', String(opts.origin));
1025
1025
  if (opts.oauthProvider) params.set('oauthProvider', String(opts.oauthProvider));
1026
+ if (opts.appId) params.set('appId', String(opts.appId));
1027
+ if (opts.billingWallet) params.set('billingWallet', String(opts.billingWallet).trim().toLowerCase());
1026
1028
  const qs = params.toString();
1027
1029
  return qs ? `${base}?${qs}` : base;
1028
1030
  }
package/widgets/README.md CHANGED
@@ -35,7 +35,7 @@ export function Page() {
35
35
  ```jsx
36
36
  import { ProofBadge } from '@neus/sdk/widgets';
37
37
 
38
- <ProofBadge qHash="0x..." showChains />
38
+ <ProofBadge qHash={proof.qHash} showChains />
39
39
  ```
40
40
 
41
41
  ## Docs
@@ -13,13 +13,25 @@ function buildHostedCheckoutUrl({
13
13
  origin,
14
14
  oauthProvider,
15
15
  campaignTitle,
16
- campaignMessage
16
+ campaignMessage,
17
+ appId,
18
+ billingWallet,
19
+ gateId
17
20
  }) {
18
21
  const checkoutUrl = new URL(hostedCheckoutUrl);
19
22
  checkoutUrl.searchParams.set("verifiers", verifierList.join(","));
20
23
  checkoutUrl.searchParams.set("mode", "popup");
21
24
  checkoutUrl.searchParams.set("returnUrl", returnUrl);
22
25
  checkoutUrl.searchParams.set("origin", origin);
26
+ if (typeof appId === "string" && appId.trim()) {
27
+ checkoutUrl.searchParams.set("appId", appId.trim());
28
+ }
29
+ if (typeof billingWallet === "string" && billingWallet.trim()) {
30
+ checkoutUrl.searchParams.set("billingWallet", billingWallet.trim().toLowerCase());
31
+ }
32
+ if (typeof gateId === "string" && gateId.trim()) {
33
+ checkoutUrl.searchParams.set("gateId", gateId.trim());
34
+ }
23
35
  if (typeof oauthProvider === "string" && oauthProvider.trim()) {
24
36
  checkoutUrl.searchParams.set("oauthProvider", oauthProvider.trim());
25
37
  }
@@ -186,6 +198,7 @@ function VerifyGate({
186
198
  onVerified = void 0,
187
199
  apiUrl = void 0,
188
200
  appId = void 0,
201
+ billingWallet = void 0,
189
202
  paymentSignature = void 0,
190
203
  extraHeaders = void 0,
191
204
  hostedCheckoutUrl = void 0,
@@ -220,8 +233,8 @@ function VerifyGate({
220
233
  const [existingProofs, setExistingProofs] = useState(null);
221
234
  const [operation, setOperation] = useState("verify");
222
235
  const client = useMemo(
223
- () => new NeusClient({ apiUrl, appId, paymentSignature, extraHeaders }),
224
- [apiUrl, appId, paymentSignature, extraHeaders]
236
+ () => new NeusClient({ apiUrl, appId, billingWallet, paymentSignature, extraHeaders }),
237
+ [apiUrl, appId, billingWallet, paymentSignature, extraHeaders]
225
238
  );
226
239
  const verifierList = useMemo(() => {
227
240
  return Array.isArray(requiredVerifiers) && requiredVerifiers.length > 0 ? requiredVerifiers : ["ownership-basic"];
@@ -397,7 +410,9 @@ function VerifyGate({
397
410
  origin,
398
411
  oauthProvider,
399
412
  campaignTitle,
400
- campaignMessage
413
+ campaignMessage,
414
+ appId,
415
+ billingWallet
401
416
  });
402
417
  let expectedOrigin = null;
403
418
  try {
@@ -451,7 +466,7 @@ function VerifyGate({
451
466
  };
452
467
  window.addEventListener("message", onMessage);
453
468
  });
454
- }, [resolvedHostedCheckoutUrl, verifierList, oauthProvider, campaignTitle, campaignMessage]);
469
+ }, [resolvedHostedCheckoutUrl, verifierList, oauthProvider, campaignTitle, campaignMessage, appId, billingWallet]);
455
470
  useEffect(() => {
456
471
  onStateChange?.(state);
457
472
  }, [state, onStateChange]);
package/CHANGELOG.md DELETED
@@ -1,3 +0,0 @@
1
- # Changelog
2
-
3
- Release notes: [github.com/neus/network/blob/main/CHANGELOG.md](https://github.com/neus/network/blob/main/CHANGELOG.md)