@neus/sdk 1.0.8 → 1.0.10
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 +139 -46
- package/SECURITY.md +1 -1
- package/cjs/client.cjs +40 -44
- package/cjs/index.cjs +40 -44
- package/client.js +36 -53
- package/package.json +3 -4
- package/types.d.ts +13 -24
- package/widgets/README.md +1 -1
- package/widgets/verify-gate/dist/ProofBadge.js +41 -37
- package/widgets/verify-gate/dist/VerifyGate.js +54 -49
|
@@ -124,10 +124,11 @@ function getVerifyGateUserError(err) {
|
|
|
124
124
|
}
|
|
125
125
|
return null;
|
|
126
126
|
}
|
|
127
|
-
function dispatchNeusProofCreatedForHost({ qHash,
|
|
127
|
+
function dispatchNeusProofCreatedForHost({ qHash, walletAddress, ...legacyInput }) {
|
|
128
128
|
try {
|
|
129
129
|
if (typeof window === "undefined") return;
|
|
130
|
-
const raw = typeof qHash === "string" && qHash.trim() || typeof proofId === "string" && proofId.trim() ||
|
|
130
|
+
const raw = typeof qHash === "string" && qHash.trim() || typeof legacyInput.proofId === "string" && legacyInput.proofId.trim() || // Legacy input compatibility only. Do not expose or store proofId.
|
|
131
|
+
"";
|
|
131
132
|
if (!raw) return;
|
|
132
133
|
const w = typeof walletAddress === "string" ? walletAddress.trim() : "";
|
|
133
134
|
const normalizedWallet = w && /^0x[a-fA-F0-9]{40}$/.test(w) ? w.toLowerCase() : w;
|
|
@@ -199,8 +200,7 @@ function VerifyGate({
|
|
|
199
200
|
disabled = false,
|
|
200
201
|
buttonText = void 0,
|
|
201
202
|
mode = "create",
|
|
202
|
-
|
|
203
|
-
qHash = null,
|
|
203
|
+
qHash: qHashProp = null,
|
|
204
204
|
strategy = "reuse-or-create",
|
|
205
205
|
checkExisting = true,
|
|
206
206
|
maxProofAgeMs = void 0,
|
|
@@ -211,7 +211,8 @@ function VerifyGate({
|
|
|
211
211
|
onError = void 0,
|
|
212
212
|
wallet = void 0,
|
|
213
213
|
chain = void 0,
|
|
214
|
-
signatureMethod = void 0
|
|
214
|
+
signatureMethod = void 0,
|
|
215
|
+
...legacyProps
|
|
215
216
|
}) {
|
|
216
217
|
const [state, setState] = useState("idle");
|
|
217
218
|
const [error, setError] = useState(null);
|
|
@@ -228,7 +229,8 @@ function VerifyGate({
|
|
|
228
229
|
return Array.isArray(requiredVerifiers) && requiredVerifiers.length > 0 ? requiredVerifiers : ["ownership-basic"];
|
|
229
230
|
}, [requiredVerifiers]);
|
|
230
231
|
const primaryVerifier = verifierList[0];
|
|
231
|
-
const
|
|
232
|
+
const qHash = qHashProp || legacyProps.proofId || null;
|
|
233
|
+
const resolvedQHash = qHash;
|
|
232
234
|
const hasInteractiveVerifier = useMemo(
|
|
233
235
|
() => verifierList.some((verifierId) => {
|
|
234
236
|
if (INTERACTIVE_VERIFIERS.has(verifierId)) return true;
|
|
@@ -275,16 +277,15 @@ function VerifyGate({
|
|
|
275
277
|
setExistingProofs(gateResult);
|
|
276
278
|
const existingProof = gateResult.existing?.[primaryVerifier];
|
|
277
279
|
if (existingProof && onVerified) {
|
|
278
|
-
const
|
|
280
|
+
const existingQHash = existingProof.qHash || existingProof.proofId || null;
|
|
279
281
|
onVerified({
|
|
280
|
-
|
|
281
|
-
qHash: proofId2,
|
|
282
|
+
qHash: existingQHash,
|
|
282
283
|
address: existingProof.walletAddress || address,
|
|
283
284
|
verifierIds: verifierList,
|
|
284
285
|
verifiedVerifiers: existingProof.verifiedVerifiers || [],
|
|
285
286
|
existing: true,
|
|
286
287
|
proofsByVerifierId: gateResult.existing || {},
|
|
287
|
-
proofUrl:
|
|
288
|
+
proofUrl: existingQHash ? `${apiUrl || "https://api.neus.network"}/api/v1/proofs/${existingQHash}` : null
|
|
288
289
|
});
|
|
289
290
|
}
|
|
290
291
|
return true;
|
|
@@ -370,7 +371,6 @@ function VerifyGate({
|
|
|
370
371
|
}
|
|
371
372
|
if (result.qHash) {
|
|
372
373
|
existing[result.verifierId] = {
|
|
373
|
-
proofId: result.qHash,
|
|
374
374
|
qHash: result.qHash,
|
|
375
375
|
walletAddress: address,
|
|
376
376
|
verifiedVerifiers: [{ verifierId: result.verifierId, verified: true }]
|
|
@@ -401,13 +401,13 @@ function VerifyGate({
|
|
|
401
401
|
campaignTitle,
|
|
402
402
|
campaignMessage
|
|
403
403
|
});
|
|
404
|
-
let expectedOrigin =
|
|
404
|
+
let expectedOrigin = null;
|
|
405
405
|
try {
|
|
406
406
|
expectedOrigin = new URL(resolvedHostedCheckoutUrl).origin;
|
|
407
407
|
} catch (_err) {
|
|
408
|
-
expectedOrigin =
|
|
408
|
+
expectedOrigin = null;
|
|
409
409
|
}
|
|
410
|
-
return
|
|
410
|
+
return new Promise((resolve, reject) => {
|
|
411
411
|
const url = checkoutUrl;
|
|
412
412
|
const popup = window.open(
|
|
413
413
|
url,
|
|
@@ -440,7 +440,7 @@ function VerifyGate({
|
|
|
440
440
|
}
|
|
441
441
|
};
|
|
442
442
|
const onMessage = (event) => {
|
|
443
|
-
if (expectedOrigin
|
|
443
|
+
if (!expectedOrigin || event.origin !== expectedOrigin) return;
|
|
444
444
|
const payload = event?.data;
|
|
445
445
|
if (!payload || payload.type !== HOSTED_CHECKOUT_MESSAGE_TYPE) return;
|
|
446
446
|
completed = true;
|
|
@@ -473,7 +473,7 @@ function VerifyGate({
|
|
|
473
473
|
});
|
|
474
474
|
setExistingProofs(gateResult);
|
|
475
475
|
applySatisfiedGateResult(gateResult, address);
|
|
476
|
-
} catch (
|
|
476
|
+
} catch (_err) {
|
|
477
477
|
}
|
|
478
478
|
};
|
|
479
479
|
checkExistingProofs();
|
|
@@ -503,7 +503,7 @@ function VerifyGate({
|
|
|
503
503
|
requirements: buildGateRequirements()
|
|
504
504
|
});
|
|
505
505
|
if (applySatisfiedGateResult(gateResult, walletAddress)) return;
|
|
506
|
-
} catch (
|
|
506
|
+
} catch (_err) {
|
|
507
507
|
}
|
|
508
508
|
}
|
|
509
509
|
try {
|
|
@@ -511,18 +511,17 @@ function VerifyGate({
|
|
|
511
511
|
setOperation("access");
|
|
512
512
|
setIsProcessing(true);
|
|
513
513
|
setState("signing");
|
|
514
|
-
if (!
|
|
515
|
-
throw new Error("
|
|
514
|
+
if (!resolvedQHash) {
|
|
515
|
+
throw new Error("qHash is required for access mode");
|
|
516
516
|
}
|
|
517
517
|
setState("verifying");
|
|
518
518
|
const privateData = await client.getPrivateProof(
|
|
519
|
-
|
|
519
|
+
resolvedQHash,
|
|
520
520
|
wallet || (typeof window !== "undefined" ? window.ethereum : null)
|
|
521
521
|
);
|
|
522
522
|
setState("verified");
|
|
523
523
|
onVerified?.({
|
|
524
|
-
|
|
525
|
-
qHash: resolvedProofId,
|
|
524
|
+
qHash: resolvedQHash,
|
|
526
525
|
data: privateData.data,
|
|
527
526
|
mode: "access",
|
|
528
527
|
proofUrl: privateData.proofUrl
|
|
@@ -547,22 +546,20 @@ function VerifyGate({
|
|
|
547
546
|
setState("interactive-checkout");
|
|
548
547
|
onStateChange?.("interactive-checkout");
|
|
549
548
|
const checkoutResult = await launchHostedCheckout();
|
|
550
|
-
const
|
|
549
|
+
const checkoutQHash = checkoutResult?.qHash || checkoutResult?.proofId || null;
|
|
551
550
|
const handoffWallet = typeof checkoutResult?.walletAddress === "string" && checkoutResult.walletAddress.trim() || walletAddress && String(walletAddress).trim() || "";
|
|
552
551
|
setState("verified");
|
|
553
552
|
dispatchNeusProofCreatedForHost({
|
|
554
|
-
qHash:
|
|
555
|
-
proofId: checkoutProofId,
|
|
553
|
+
qHash: checkoutQHash,
|
|
556
554
|
walletAddress: handoffWallet
|
|
557
555
|
});
|
|
558
556
|
onVerified?.({
|
|
559
|
-
|
|
560
|
-
qHash: checkoutProofId,
|
|
557
|
+
qHash: checkoutQHash,
|
|
561
558
|
verifierIds: verifierList,
|
|
562
559
|
existing: false,
|
|
563
560
|
mode: "create",
|
|
564
561
|
eligible: checkoutResult?.eligible !== false,
|
|
565
|
-
proofUrl: checkoutResult?.proofUrl || (
|
|
562
|
+
proofUrl: checkoutResult?.proofUrl || (checkoutQHash ? `${apiUrl || "https://api.neus.network"}/api/v1/proofs/${checkoutQHash}` : null)
|
|
566
563
|
});
|
|
567
564
|
return;
|
|
568
565
|
}
|
|
@@ -575,7 +572,9 @@ function VerifyGate({
|
|
|
575
572
|
);
|
|
576
573
|
const buildDataForVerifier = (verifierId) => {
|
|
577
574
|
if (!CREATABLE_VERIFIERS.has(verifierId)) {
|
|
578
|
-
throw new Error(
|
|
575
|
+
throw new Error(
|
|
576
|
+
`${verifierId} cannot be created via the wallet flow. It requires hosted checkout or a server integration.`
|
|
577
|
+
);
|
|
579
578
|
}
|
|
580
579
|
const explicit = verifierData && verifierData[verifierId];
|
|
581
580
|
if (explicit && typeof explicit === "object") return explicit;
|
|
@@ -612,8 +611,8 @@ function VerifyGate({
|
|
|
612
611
|
wallet: wallet || (typeof window !== "undefined" ? window.ethereum : void 0)
|
|
613
612
|
});
|
|
614
613
|
setState("verifying");
|
|
615
|
-
const
|
|
616
|
-
const final = await client.pollProofStatus(
|
|
614
|
+
const qHashToCheck = created.qHash || created.proofId || created?.data?.qHash || created?.data?.proofId;
|
|
615
|
+
const final = await client.pollProofStatus(qHashToCheck, { interval: 3e3, timeout: 6e4 });
|
|
617
616
|
const verifiedVerifiers = final?.data?.verifiedVerifiers || [];
|
|
618
617
|
const verifierResult = verifiedVerifiers.find((v) => v.verifierId === verifierId);
|
|
619
618
|
if (!verifierResult || verifierResult.verified !== true) {
|
|
@@ -622,11 +621,10 @@ function VerifyGate({
|
|
|
622
621
|
const hubTx = final?.data?.hubTransaction || {};
|
|
623
622
|
const crosschain = final?.data?.crosschain || {};
|
|
624
623
|
const txHash = hubTx?.txHash || crosschain?.hubTxHash || null;
|
|
625
|
-
const
|
|
624
|
+
const finalQHash = final?.qHash || final?.proofId || qHashToCheck;
|
|
626
625
|
return {
|
|
627
626
|
verifierId,
|
|
628
|
-
|
|
629
|
-
qHash: finalProofId,
|
|
627
|
+
qHash: finalQHash,
|
|
630
628
|
address: final?.data?.walletAddress,
|
|
631
629
|
txHash,
|
|
632
630
|
verifiedVerifiers,
|
|
@@ -639,18 +637,15 @@ function VerifyGate({
|
|
|
639
637
|
}
|
|
640
638
|
setState("verified");
|
|
641
639
|
const last = results[results.length - 1];
|
|
642
|
-
const
|
|
640
|
+
const lastQHash = last?.qHash || null;
|
|
643
641
|
const handoffAddr = last?.address && String(last.address).trim() || walletAddress && String(walletAddress).trim() || "";
|
|
644
642
|
dispatchNeusProofCreatedForHost({
|
|
645
|
-
qHash:
|
|
646
|
-
proofId: lastProofId,
|
|
643
|
+
qHash: lastQHash,
|
|
647
644
|
walletAddress: handoffAddr
|
|
648
645
|
});
|
|
649
646
|
onVerified?.({
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
proofIds: results.map((r) => r.proofId || r.qHash).filter(Boolean),
|
|
653
|
-
qHashes: results.map((r) => r.proofId || r.qHash).filter(Boolean),
|
|
647
|
+
qHash: lastQHash,
|
|
648
|
+
qHashes: results.map((r) => r.qHash).filter(Boolean),
|
|
654
649
|
address: last?.address,
|
|
655
650
|
txHash: last?.txHash,
|
|
656
651
|
verifierIds: verifierList,
|
|
@@ -662,7 +657,7 @@ function VerifyGate({
|
|
|
662
657
|
} catch (err) {
|
|
663
658
|
const userMsg = getVerifyGateUserError(err);
|
|
664
659
|
const fallback = mode === "access" ? "Access failed" : VERIFY_GATE_DEFAULT_ERROR;
|
|
665
|
-
setError(userMsg
|
|
660
|
+
setError(userMsg !== null ? userMsg : fallback);
|
|
666
661
|
setState("error");
|
|
667
662
|
onError?.(err);
|
|
668
663
|
} finally {
|
|
@@ -672,7 +667,7 @@ function VerifyGate({
|
|
|
672
667
|
disabled,
|
|
673
668
|
isProcessing,
|
|
674
669
|
mode,
|
|
675
|
-
|
|
670
|
+
resolvedQHash,
|
|
676
671
|
verifierList,
|
|
677
672
|
hasInteractiveVerifier,
|
|
678
673
|
client,
|
|
@@ -712,13 +707,23 @@ function VerifyGate({
|
|
|
712
707
|
setNotice("No matching proof was found. Verify to create a proof.");
|
|
713
708
|
} catch (err) {
|
|
714
709
|
const userMsg = getVerifyGateUserError(err);
|
|
715
|
-
setError(userMsg
|
|
710
|
+
setError(userMsg !== null ? userMsg : "Unable to access private proofs");
|
|
716
711
|
setState("error");
|
|
717
712
|
onError?.(err);
|
|
718
713
|
} finally {
|
|
719
714
|
setIsProcessing(false);
|
|
720
715
|
}
|
|
721
|
-
}, [
|
|
716
|
+
}, [
|
|
717
|
+
disabled,
|
|
718
|
+
isProcessing,
|
|
719
|
+
mode,
|
|
720
|
+
allowPrivateReuse,
|
|
721
|
+
walletAddress,
|
|
722
|
+
getOrRequestWalletAddress,
|
|
723
|
+
tryPrivateReuse,
|
|
724
|
+
applySatisfiedGateResult,
|
|
725
|
+
onError
|
|
726
|
+
]);
|
|
722
727
|
const primaryCtaClass = state === "idle" || state === "interactive-checkout" ? "neus-vg__primary" : "";
|
|
723
728
|
const getLabel = () => {
|
|
724
729
|
if (buttonText && state === "idle") return buttonText;
|
|
@@ -775,17 +780,17 @@ function VerifyGate({
|
|
|
775
780
|
if (state === "error") {
|
|
776
781
|
return {
|
|
777
782
|
...buttonBaseStyle,
|
|
778
|
-
background:
|
|
783
|
+
background: "rgba(239, 68, 68, 0.15)",
|
|
779
784
|
color: THEME.error,
|
|
780
|
-
border:
|
|
785
|
+
border: "1px solid rgba(239, 68, 68, 0.3)"
|
|
781
786
|
};
|
|
782
787
|
}
|
|
783
788
|
if (state === "signing" || state === "verifying") {
|
|
784
789
|
return {
|
|
785
790
|
...buttonBaseStyle,
|
|
786
|
-
background:
|
|
791
|
+
background: "rgba(61, 114, 201, 0.15)",
|
|
787
792
|
color: "var(--neus-accent, #98C0EF)",
|
|
788
|
-
border:
|
|
793
|
+
border: "1px solid rgba(61, 114, 201, 0.3)"
|
|
789
794
|
};
|
|
790
795
|
}
|
|
791
796
|
return {
|