@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/README.md +206 -206
- package/cjs/client.cjs +141 -2
- package/cjs/errors.cjs +2 -35
- package/cjs/gates.cjs +1 -21
- package/cjs/index.cjs +153 -2
- package/cjs/utils.cjs +2 -0
- package/cli/neus.mjs +18 -10
- package/client.js +91 -2
- package/errors.js +154 -189
- package/gates.js +0 -20
- package/index.js +2 -0
- package/package.json +142 -143
- package/sponsor.js +95 -0
- package/types.d.ts +30 -1
- package/utils.js +2 -0
- package/widgets/README.md +1 -1
- package/widgets/verify-gate/dist/VerifyGate.js +20 -5
- package/CHANGELOG.md +0 -3
- package/neus-logo.svg +0 -3
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
|
-
/**
|
|
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
|
@@ -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