@neus/sdk 1.0.7 → 1.0.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/README.md +0 -23
- package/SECURITY.md +38 -38
- package/client.js +1837 -1837
- package/package.json +136 -136
- package/types.d.ts +915 -915
- package/widgets/README.md +45 -45
- package/widgets/verify-gate/dist/VerifyGate.js +88 -21
package/widgets/README.md
CHANGED
|
@@ -1,45 +1,45 @@
|
|
|
1
|
-
# NEUS Widgets
|
|
2
|
-
|
|
3
|
-
**Proof-aware React components** (VerifyGate, ProofBadge) so your UI can show verified state and gate content **using the same checks your server already trusts** - avoid re-implementing verifier rules only in the browser.
|
|
4
|
-
|
|
5
|
-
## Install
|
|
6
|
-
|
|
7
|
-
```bash
|
|
8
|
-
npm install @neus/sdk react react-dom
|
|
9
|
-
```
|
|
10
|
-
|
|
11
|
-
## VerifyGate
|
|
12
|
-
|
|
13
|
-
Create mode defaults to **private**. Override `proofOptions` only when you intentionally need public visibility for link-based or public checks.
|
|
14
|
-
|
|
15
|
-
```jsx
|
|
16
|
-
import { VerifyGate } from '@neus/sdk/widgets';
|
|
17
|
-
|
|
18
|
-
export function Page() {
|
|
19
|
-
return (
|
|
20
|
-
<VerifyGate
|
|
21
|
-
appId="your-app-id"
|
|
22
|
-
requiredVerifiers={['nft-ownership']}
|
|
23
|
-
verifierData={{
|
|
24
|
-
'nft-ownership': { contractAddress: '0x...', tokenId: '1', chainId: 8453 }
|
|
25
|
-
}}
|
|
26
|
-
>
|
|
27
|
-
<div>Unlocked</div>
|
|
28
|
-
</VerifyGate>
|
|
29
|
-
);
|
|
30
|
-
}
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
## ProofBadge
|
|
34
|
-
|
|
35
|
-
```jsx
|
|
36
|
-
import { ProofBadge } from '@neus/sdk/widgets';
|
|
37
|
-
|
|
38
|
-
<ProofBadge proofId="0x..." showChains />
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
## Docs
|
|
42
|
-
|
|
43
|
-
- [Widgets Overview](https://docs.neus.network/widgets/overview)
|
|
44
|
-
- [Verify Component](https://docs.neus.network/widgets/verifygate)
|
|
45
|
-
- [Quickstart](https://docs.neus.network/quickstart)
|
|
1
|
+
# NEUS Widgets
|
|
2
|
+
|
|
3
|
+
**Proof-aware React components** (VerifyGate, ProofBadge) so your UI can show verified state and gate content **using the same checks your server already trusts** - avoid re-implementing verifier rules only in the browser.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @neus/sdk react react-dom
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## VerifyGate
|
|
12
|
+
|
|
13
|
+
Create mode defaults to **private**. Override `proofOptions` only when you intentionally need public visibility for link-based or public checks.
|
|
14
|
+
|
|
15
|
+
```jsx
|
|
16
|
+
import { VerifyGate } from '@neus/sdk/widgets';
|
|
17
|
+
|
|
18
|
+
export function Page() {
|
|
19
|
+
return (
|
|
20
|
+
<VerifyGate
|
|
21
|
+
appId="your-app-id"
|
|
22
|
+
requiredVerifiers={['nft-ownership']}
|
|
23
|
+
verifierData={{
|
|
24
|
+
'nft-ownership': { contractAddress: '0x...', tokenId: '1', chainId: 8453 }
|
|
25
|
+
}}
|
|
26
|
+
>
|
|
27
|
+
<div>Unlocked</div>
|
|
28
|
+
</VerifyGate>
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## ProofBadge
|
|
34
|
+
|
|
35
|
+
```jsx
|
|
36
|
+
import { ProofBadge } from '@neus/sdk/widgets';
|
|
37
|
+
|
|
38
|
+
<ProofBadge proofId="0x..." showChains />
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Docs
|
|
42
|
+
|
|
43
|
+
- [Widgets Overview](https://docs.neus.network/widgets/overview)
|
|
44
|
+
- [Verify Component](https://docs.neus.network/widgets/verifygate)
|
|
45
|
+
- [Quickstart](https://docs.neus.network/quickstart)
|
|
@@ -4,6 +4,39 @@
|
|
|
4
4
|
import { useCallback, useMemo, useState, useEffect } from "react";
|
|
5
5
|
import { NeusClient } from "@neus/sdk/client";
|
|
6
6
|
|
|
7
|
+
// widgets/verify-gate/hostedCheckout.js
|
|
8
|
+
var HOSTED_CHECKOUT_MESSAGE_TYPE = "neus_checkout_done";
|
|
9
|
+
function buildHostedCheckoutUrl({
|
|
10
|
+
hostedCheckoutUrl,
|
|
11
|
+
verifierList,
|
|
12
|
+
returnUrl,
|
|
13
|
+
origin,
|
|
14
|
+
oauthProvider,
|
|
15
|
+
campaignTitle,
|
|
16
|
+
campaignMessage
|
|
17
|
+
}) {
|
|
18
|
+
const checkoutUrl = new URL(hostedCheckoutUrl);
|
|
19
|
+
checkoutUrl.searchParams.set("verifiers", verifierList.join(","));
|
|
20
|
+
checkoutUrl.searchParams.set("mode", "popup");
|
|
21
|
+
checkoutUrl.searchParams.set("returnUrl", returnUrl);
|
|
22
|
+
checkoutUrl.searchParams.set("origin", origin);
|
|
23
|
+
if (typeof oauthProvider === "string" && oauthProvider.trim()) {
|
|
24
|
+
checkoutUrl.searchParams.set("oauthProvider", oauthProvider.trim());
|
|
25
|
+
}
|
|
26
|
+
if (typeof campaignTitle === "string" && campaignTitle.trim()) {
|
|
27
|
+
checkoutUrl.searchParams.set("presetLabel", campaignTitle.trim().slice(0, 200));
|
|
28
|
+
}
|
|
29
|
+
if (typeof campaignMessage === "string" && campaignMessage.trim()) {
|
|
30
|
+
checkoutUrl.searchParams.set("message", campaignMessage.trim().slice(0, 200));
|
|
31
|
+
}
|
|
32
|
+
return checkoutUrl.toString();
|
|
33
|
+
}
|
|
34
|
+
function buildHostedCheckoutRedirectUrl(popupCheckoutUrl) {
|
|
35
|
+
const checkoutUrl = new URL(popupCheckoutUrl);
|
|
36
|
+
checkoutUrl.searchParams.delete("mode");
|
|
37
|
+
return checkoutUrl.toString();
|
|
38
|
+
}
|
|
39
|
+
|
|
7
40
|
// widgets/verify-gate/mergeCreateProofOptions.js
|
|
8
41
|
function mergeVerifyGateCreateProofOptions(proofOptions, verifierOptions) {
|
|
9
42
|
return {
|
|
@@ -37,7 +70,7 @@ if (typeof document !== "undefined") {
|
|
|
37
70
|
if (!document.getElementById(sid)) {
|
|
38
71
|
const el = document.createElement("style");
|
|
39
72
|
el.id = sid;
|
|
40
|
-
el.textContent = "button.neus-vg__primary{ color: #0a0a0a !important; -webkit-text-fill-color: #0a0a0a; }button.neus-vg__primary .neus-vg__label,button.neus-vg__primary span.neus-vg__label{ color: inherit !important; -webkit-text-fill-color: inherit; }";
|
|
73
|
+
el.textContent = "@keyframes neus-vg-spin{to{transform:rotate(360deg)}}button.neus-vg__primary{ color: #0a0a0a !important; -webkit-text-fill-color: #0a0a0a; }button.neus-vg__primary .neus-vg__label,button.neus-vg__primary span.neus-vg__label{ color: inherit !important; -webkit-text-fill-color: inherit; }";
|
|
41
74
|
document.head.appendChild(el);
|
|
42
75
|
}
|
|
43
76
|
}
|
|
@@ -73,7 +106,6 @@ var INTERACTIVE_VERIFIERS = /* @__PURE__ */ new Set([
|
|
|
73
106
|
]);
|
|
74
107
|
var HOSTED_WHEN_INCOMPLETE = /* @__PURE__ */ new Set(["wallet-link"]);
|
|
75
108
|
var DEFAULT_HOSTED_CHECKOUT_URL = "https://neus.network/verify";
|
|
76
|
-
var HOSTED_CHECKOUT_MESSAGE_TYPE = "neus_checkout_done";
|
|
77
109
|
var VERIFY_GATE_DEFAULT_ERROR = "Something went wrong. Please try again.";
|
|
78
110
|
function getVerifyGateUserError(err) {
|
|
79
111
|
const c = err && err.code;
|
|
@@ -111,6 +143,44 @@ function dispatchNeusProofCreatedForHost({ qHash, proofId, walletAddress }) {
|
|
|
111
143
|
} catch (_err) {
|
|
112
144
|
}
|
|
113
145
|
}
|
|
146
|
+
function VerifyGateInlineSpinner({ size = 16 }) {
|
|
147
|
+
return /* @__PURE__ */ jsxs(
|
|
148
|
+
"svg",
|
|
149
|
+
{
|
|
150
|
+
width: size,
|
|
151
|
+
height: size,
|
|
152
|
+
viewBox: "0 0 24 24",
|
|
153
|
+
"aria-hidden": "true",
|
|
154
|
+
style: { animation: "neus-vg-spin 0.8s linear infinite" },
|
|
155
|
+
children: [
|
|
156
|
+
/* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "9", fill: "none", stroke: "currentColor", strokeWidth: "3", opacity: "0.25" }),
|
|
157
|
+
/* @__PURE__ */ jsx("path", { d: "M21 12a9 9 0 0 0-9-9", fill: "none", stroke: "currentColor", strokeWidth: "3", strokeLinecap: "round" })
|
|
158
|
+
]
|
|
159
|
+
}
|
|
160
|
+
);
|
|
161
|
+
}
|
|
162
|
+
function NeusLogo({ size = 16, onPrimaryFill = false }) {
|
|
163
|
+
return /* @__PURE__ */ jsx(
|
|
164
|
+
"span",
|
|
165
|
+
{
|
|
166
|
+
"aria-hidden": "true",
|
|
167
|
+
style: {
|
|
168
|
+
display: "inline-flex",
|
|
169
|
+
alignItems: "center",
|
|
170
|
+
justifyContent: "center",
|
|
171
|
+
width: `${size}px`,
|
|
172
|
+
height: `${size}px`,
|
|
173
|
+
borderRadius: "4px",
|
|
174
|
+
border: `1px solid ${onPrimaryFill ? "rgba(10, 10, 10, 0.35)" : "currentColor"}`,
|
|
175
|
+
color: onPrimaryFill ? "#0a0a0a" : "currentColor",
|
|
176
|
+
fontSize: `${Math.max(9, Math.round(size * 0.55))}px`,
|
|
177
|
+
fontWeight: 700,
|
|
178
|
+
lineHeight: 1
|
|
179
|
+
},
|
|
180
|
+
children: "N"
|
|
181
|
+
}
|
|
182
|
+
);
|
|
183
|
+
}
|
|
114
184
|
function VerifyGate({
|
|
115
185
|
requiredVerifiers = ["ownership-basic"],
|
|
116
186
|
onVerified = void 0,
|
|
@@ -322,20 +392,15 @@ function VerifyGate({
|
|
|
322
392
|
}
|
|
323
393
|
const origin = window.location.origin;
|
|
324
394
|
const returnUrl = window.location.href;
|
|
325
|
-
const checkoutUrl =
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
checkoutUrl.searchParams.set("presetLabel", campaignTitle.trim().slice(0, 200));
|
|
335
|
-
}
|
|
336
|
-
if (typeof campaignMessage === "string" && campaignMessage.trim()) {
|
|
337
|
-
checkoutUrl.searchParams.set("message", campaignMessage.trim().slice(0, 200));
|
|
338
|
-
}
|
|
395
|
+
const checkoutUrl = buildHostedCheckoutUrl({
|
|
396
|
+
hostedCheckoutUrl: resolvedHostedCheckoutUrl,
|
|
397
|
+
verifierList,
|
|
398
|
+
returnUrl,
|
|
399
|
+
origin,
|
|
400
|
+
oauthProvider,
|
|
401
|
+
campaignTitle,
|
|
402
|
+
campaignMessage
|
|
403
|
+
});
|
|
339
404
|
let expectedOrigin = "*";
|
|
340
405
|
try {
|
|
341
406
|
expectedOrigin = new URL(resolvedHostedCheckoutUrl).origin;
|
|
@@ -343,14 +408,14 @@ function VerifyGate({
|
|
|
343
408
|
expectedOrigin = "*";
|
|
344
409
|
}
|
|
345
410
|
return await new Promise((resolve, reject) => {
|
|
346
|
-
const url = checkoutUrl
|
|
411
|
+
const url = checkoutUrl;
|
|
347
412
|
const popup = window.open(
|
|
348
413
|
url,
|
|
349
414
|
"neus_checkout",
|
|
350
415
|
"width=600,height=700,scrollbars=yes,resizable=yes"
|
|
351
416
|
);
|
|
352
417
|
if (!popup) {
|
|
353
|
-
window.location.assign(url);
|
|
418
|
+
window.location.assign(buildHostedCheckoutRedirectUrl(url));
|
|
354
419
|
return;
|
|
355
420
|
}
|
|
356
421
|
let completed = false;
|
|
@@ -388,7 +453,7 @@ function VerifyGate({
|
|
|
388
453
|
};
|
|
389
454
|
window.addEventListener("message", onMessage);
|
|
390
455
|
});
|
|
391
|
-
}, [resolvedHostedCheckoutUrl, verifierList, oauthProvider]);
|
|
456
|
+
}, [resolvedHostedCheckoutUrl, verifierList, oauthProvider, campaignTitle, campaignMessage]);
|
|
392
457
|
useEffect(() => {
|
|
393
458
|
onStateChange?.(state);
|
|
394
459
|
}, [state, onStateChange]);
|
|
@@ -480,6 +545,7 @@ function VerifyGate({
|
|
|
480
545
|
setOperation("verify");
|
|
481
546
|
setIsProcessing(true);
|
|
482
547
|
setState("interactive-checkout");
|
|
548
|
+
onStateChange?.("interactive-checkout");
|
|
483
549
|
const checkoutResult = await launchHostedCheckout();
|
|
484
550
|
const checkoutProofId = checkoutResult?.proofId || checkoutResult?.qHash || null;
|
|
485
551
|
const handoffWallet = typeof checkoutResult?.walletAddress === "string" && checkoutResult.walletAddress.trim() || walletAddress && String(walletAddress).trim() || "";
|
|
@@ -617,6 +683,7 @@ function VerifyGate({
|
|
|
617
683
|
launchHostedCheckout,
|
|
618
684
|
onVerified,
|
|
619
685
|
onError,
|
|
686
|
+
onStateChange,
|
|
620
687
|
shouldCheckExisting,
|
|
621
688
|
walletAddress,
|
|
622
689
|
existingProofs,
|
|
@@ -743,7 +810,7 @@ function VerifyGate({
|
|
|
743
810
|
className: primaryCtaClass,
|
|
744
811
|
style: getButtonStyle(),
|
|
745
812
|
children: [
|
|
746
|
-
(state === "signing" || state === "verifying" || state === "interactive-checkout") && /* @__PURE__ */ jsx(
|
|
813
|
+
(state === "signing" || state === "verifying" || state === "interactive-checkout") && /* @__PURE__ */ jsx(VerifyGateInlineSpinner, { size: 16 }),
|
|
747
814
|
showBrand && state === "idle" && /* @__PURE__ */ jsx(NeusLogo, { size: 16, onPrimaryFill: true }),
|
|
748
815
|
state === "verified" && /* @__PURE__ */ jsx("svg", { width: "16", height: "16", viewBox: "0 0 20 20", fill: "currentColor", children: /* @__PURE__ */ jsx("path", { fillRule: "evenodd", d: "M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z", clipRule: "evenodd" }) }),
|
|
749
816
|
/* @__PURE__ */ jsx("span", { className: "neus-vg__label", style: { color: "inherit" }, children: getLabel() })
|
|
@@ -800,7 +867,7 @@ function VerifyGate({
|
|
|
800
867
|
style: { ...getButtonStyle(), ...style },
|
|
801
868
|
disabled: disabled || isProcessing,
|
|
802
869
|
children: [
|
|
803
|
-
(state === "signing" || state === "verifying" || state === "interactive-checkout") && /* @__PURE__ */ jsx(
|
|
870
|
+
(state === "signing" || state === "verifying" || state === "interactive-checkout") && /* @__PURE__ */ jsx(VerifyGateInlineSpinner, { size: 16 }),
|
|
804
871
|
showBrand && state === "idle" && /* @__PURE__ */ jsx(NeusLogo, { size: 16, onPrimaryFill: true }),
|
|
805
872
|
state === "verified" && /* @__PURE__ */ jsx("svg", { width: "16", height: "16", viewBox: "0 0 20 20", fill: "currentColor", children: /* @__PURE__ */ jsx("path", { fillRule: "evenodd", d: "M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z", clipRule: "evenodd" }) }),
|
|
806
873
|
/* @__PURE__ */ jsx("span", { className: "neus-vg__label", style: { color: "inherit" }, children: getLabel() }),
|