@neus/sdk 1.0.4 → 1.0.6
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 +21 -4
- package/SECURITY.md +11 -6
- package/cjs/client.cjs +132 -220
- package/cjs/gates.cjs +10 -33
- package/cjs/index.cjs +143 -252
- package/cjs/utils.cjs +0 -6
- package/cli/neus.mjs +589 -41
- package/client.js +1834 -1955
- package/errors.js +0 -34
- package/gates.js +73 -175
- package/index.js +0 -9
- package/package.json +5 -4
- package/types.d.ts +14 -459
- package/utils.js +1 -265
- package/widgets/README.md +45 -45
- package/widgets/index.js +0 -8
- package/widgets/verify-gate/dist/ProofBadge.js +0 -3
- package/widgets/verify-gate/dist/VerifyGate.js +58 -78
- package/widgets/verify-gate/index.js +0 -4
package/cjs/gates.cjs
CHANGED
|
@@ -45,36 +45,16 @@ var DAY = 24 * HOUR;
|
|
|
45
45
|
var WEEK = 7 * DAY;
|
|
46
46
|
var MONTH = 30 * DAY;
|
|
47
47
|
var YEAR = 365 * DAY;
|
|
48
|
-
var GATE_NFT_HOLDER = [
|
|
49
|
-
|
|
50
|
-
];
|
|
51
|
-
var
|
|
52
|
-
|
|
53
|
-
];
|
|
54
|
-
var
|
|
55
|
-
|
|
56
|
-
];
|
|
57
|
-
var
|
|
58
|
-
{ verifierId: "ownership-dns-txt" }
|
|
59
|
-
];
|
|
60
|
-
var GATE_LINKED_WALLETS = [
|
|
61
|
-
{ verifierId: "wallet-link" }
|
|
62
|
-
];
|
|
63
|
-
var GATE_AGENT_IDENTITY = [
|
|
64
|
-
{ verifierId: "agent-identity" }
|
|
65
|
-
];
|
|
66
|
-
var GATE_AGENT_DELEGATION = [
|
|
67
|
-
{ verifierId: "agent-delegation", maxAgeMs: 7 * DAY }
|
|
68
|
-
];
|
|
69
|
-
var GATE_CONTENT_MODERATION = [
|
|
70
|
-
{ verifierId: "ai-content-moderation" }
|
|
71
|
-
];
|
|
72
|
-
var GATE_WALLET_RISK = [
|
|
73
|
-
{ verifierId: "wallet-risk" }
|
|
74
|
-
];
|
|
75
|
-
var GATE_PSEUDONYM = [
|
|
76
|
-
{ verifierId: "ownership-pseudonym" }
|
|
77
|
-
];
|
|
48
|
+
var GATE_NFT_HOLDER = [{ verifierId: "nft-ownership" }];
|
|
49
|
+
var GATE_TOKEN_HOLDER = [{ verifierId: "token-holding" }];
|
|
50
|
+
var GATE_CONTRACT_ADMIN = [{ verifierId: "contract-ownership", maxAgeMs: HOUR }];
|
|
51
|
+
var GATE_DOMAIN_OWNER = [{ verifierId: "ownership-dns-txt" }];
|
|
52
|
+
var GATE_LINKED_WALLETS = [{ verifierId: "wallet-link" }];
|
|
53
|
+
var GATE_AGENT_IDENTITY = [{ verifierId: "agent-identity" }];
|
|
54
|
+
var GATE_AGENT_DELEGATION = [{ verifierId: "agent-delegation", maxAgeMs: 7 * DAY }];
|
|
55
|
+
var GATE_CONTENT_MODERATION = [{ verifierId: "ai-content-moderation" }];
|
|
56
|
+
var GATE_WALLET_RISK = [{ verifierId: "wallet-risk" }];
|
|
57
|
+
var GATE_PSEUDONYM = [{ verifierId: "ownership-pseudonym" }];
|
|
78
58
|
function createGate(requirements) {
|
|
79
59
|
return requirements.map((req) => {
|
|
80
60
|
if (typeof req === "string") {
|
|
@@ -98,13 +78,11 @@ function combineGates(...gates) {
|
|
|
98
78
|
return combined;
|
|
99
79
|
}
|
|
100
80
|
var gates_default = {
|
|
101
|
-
// Time constants
|
|
102
81
|
HOUR,
|
|
103
82
|
DAY,
|
|
104
83
|
WEEK,
|
|
105
84
|
MONTH,
|
|
106
85
|
YEAR,
|
|
107
|
-
// Recipe gates
|
|
108
86
|
GATE_NFT_HOLDER,
|
|
109
87
|
GATE_TOKEN_HOLDER,
|
|
110
88
|
GATE_CONTRACT_ADMIN,
|
|
@@ -115,7 +93,6 @@ var gates_default = {
|
|
|
115
93
|
GATE_CONTENT_MODERATION,
|
|
116
94
|
GATE_WALLET_RISK,
|
|
117
95
|
GATE_PSEUDONYM,
|
|
118
|
-
// Helpers
|
|
119
96
|
createGate,
|
|
120
97
|
combineGates
|
|
121
98
|
};
|
package/cjs/index.cjs
CHANGED
|
@@ -322,7 +322,6 @@ function createVerificationData(content, owner, reference = null) {
|
|
|
322
322
|
content,
|
|
323
323
|
owner: validateWalletAddress(owner) ? owner.toLowerCase() : owner,
|
|
324
324
|
reference: reference || {
|
|
325
|
-
// Must be a valid backend enum value; 'content' is not supported.
|
|
326
325
|
type: "other",
|
|
327
326
|
id: stableRefId(content)
|
|
328
327
|
}
|
|
@@ -1034,9 +1033,7 @@ var init_utils = __esm({
|
|
|
1034
1033
|
}
|
|
1035
1034
|
};
|
|
1036
1035
|
NEUS_CONSTANTS = {
|
|
1037
|
-
/** Default EVM chain id for NEUS protocol signing context (`HUB_CHAIN_ID` name kept for compatibility). */
|
|
1038
1036
|
HUB_CHAIN_ID: 84532,
|
|
1039
|
-
// Supported target chains for cross-chain propagation
|
|
1040
1037
|
TESTNET_CHAINS: [
|
|
1041
1038
|
11155111,
|
|
1042
1039
|
// Ethereum Sepolia
|
|
@@ -1047,15 +1044,12 @@ var init_utils = __esm({
|
|
|
1047
1044
|
80002
|
|
1048
1045
|
// Polygon Amoy
|
|
1049
1046
|
],
|
|
1050
|
-
// API endpoints
|
|
1051
1047
|
API_BASE_URL: "https://api.neus.network",
|
|
1052
1048
|
API_VERSION: "v1",
|
|
1053
|
-
// Timeouts and limits
|
|
1054
1049
|
SIGNATURE_MAX_AGE_MS: 5 * 60 * 1e3,
|
|
1055
1050
|
// 5 minutes
|
|
1056
1051
|
REQUEST_TIMEOUT_MS: 30 * 1e3,
|
|
1057
1052
|
// 30 seconds
|
|
1058
|
-
// Default verifier set for quick starts
|
|
1059
1053
|
DEFAULT_VERIFIERS: [
|
|
1060
1054
|
"ownership-basic",
|
|
1061
1055
|
"nft-ownership",
|
|
@@ -1073,7 +1067,21 @@ __export(client_exports, {
|
|
|
1073
1067
|
PORTABLE_PROOF_SIGNER_HEADER: () => PORTABLE_PROOF_SIGNER_HEADER,
|
|
1074
1068
|
constructVerificationMessage: () => constructVerificationMessage
|
|
1075
1069
|
});
|
|
1076
|
-
|
|
1070
|
+
function normalizeWalletLinkRelationshipType(value) {
|
|
1071
|
+
const normalized = String(value || "").trim().toLowerCase();
|
|
1072
|
+
return WALLET_LINK_RELATIONSHIP_TYPES.has(normalized) ? normalized : "linked";
|
|
1073
|
+
}
|
|
1074
|
+
function normalizeBrowserSignerString(raw) {
|
|
1075
|
+
if (raw === null || raw === void 0) {
|
|
1076
|
+
return null;
|
|
1077
|
+
}
|
|
1078
|
+
if (typeof raw === "string") {
|
|
1079
|
+
const t = raw.trim();
|
|
1080
|
+
return t.length > 0 ? t : null;
|
|
1081
|
+
}
|
|
1082
|
+
return null;
|
|
1083
|
+
}
|
|
1084
|
+
var FALLBACK_PUBLIC_VERIFIER_CATALOG, EVM_ADDRESS_RE, WALLET_LINK_RELATIONSHIP_TYPES, validateVerifierData, NeusClient;
|
|
1077
1085
|
var init_client = __esm({
|
|
1078
1086
|
"client.js"() {
|
|
1079
1087
|
"use strict";
|
|
@@ -1096,6 +1104,7 @@ var init_client = __esm({
|
|
|
1096
1104
|
"ai-content-moderation": { supportsDirectApi: true }
|
|
1097
1105
|
};
|
|
1098
1106
|
EVM_ADDRESS_RE = /^0x[a-fA-F0-9]{40}$/;
|
|
1107
|
+
WALLET_LINK_RELATIONSHIP_TYPES = /* @__PURE__ */ new Set(["primary", "personal", "org", "affiliate", "agent", "linked"]);
|
|
1099
1108
|
validateVerifierData = (verifierId, data) => {
|
|
1100
1109
|
if (!data || typeof data !== "object") {
|
|
1101
1110
|
return { valid: false, error: "Data object is required" };
|
|
@@ -1424,26 +1433,49 @@ var init_client = __esm({
|
|
|
1424
1433
|
if (!wallet) {
|
|
1425
1434
|
throw new ConfigurationError("No wallet provider available");
|
|
1426
1435
|
}
|
|
1427
|
-
if (wallet.address) {
|
|
1428
|
-
|
|
1436
|
+
if (wallet.address !== null && wallet.address !== void 0) {
|
|
1437
|
+
const s = normalizeBrowserSignerString(
|
|
1438
|
+
typeof wallet.address === "string" ? wallet.address : null
|
|
1439
|
+
);
|
|
1440
|
+
if (s) {
|
|
1441
|
+
return { signerWalletAddress: s, provider: wallet };
|
|
1442
|
+
}
|
|
1429
1443
|
}
|
|
1430
1444
|
if (wallet.publicKey && typeof wallet.publicKey.toBase58 === "function") {
|
|
1431
|
-
|
|
1445
|
+
const b58 = wallet.publicKey.toBase58();
|
|
1446
|
+
const s = normalizeBrowserSignerString(typeof b58 === "string" ? b58 : null);
|
|
1447
|
+
if (s) {
|
|
1448
|
+
return { signerWalletAddress: s, provider: wallet };
|
|
1449
|
+
}
|
|
1432
1450
|
}
|
|
1433
1451
|
if (typeof wallet.getAddress === "function") {
|
|
1434
|
-
const
|
|
1435
|
-
|
|
1452
|
+
const got = await wallet.getAddress().catch(() => null);
|
|
1453
|
+
const s = normalizeBrowserSignerString(
|
|
1454
|
+
got === null || got === void 0 ? null : typeof got === "string" ? got : null
|
|
1455
|
+
);
|
|
1456
|
+
if (s) {
|
|
1457
|
+
return { signerWalletAddress: s, provider: wallet };
|
|
1458
|
+
}
|
|
1436
1459
|
}
|
|
1437
1460
|
if (wallet.selectedAddress || wallet.request) {
|
|
1438
1461
|
const provider = wallet;
|
|
1439
1462
|
if (wallet.selectedAddress) {
|
|
1440
|
-
|
|
1463
|
+
const s2 = normalizeBrowserSignerString(
|
|
1464
|
+
typeof wallet.selectedAddress === "string" ? wallet.selectedAddress : null
|
|
1465
|
+
);
|
|
1466
|
+
if (s2) {
|
|
1467
|
+
return { signerWalletAddress: s2, provider };
|
|
1468
|
+
}
|
|
1441
1469
|
}
|
|
1442
1470
|
const accounts = await provider.request({ method: "eth_accounts" });
|
|
1443
1471
|
if (!accounts || accounts.length === 0) {
|
|
1444
1472
|
throw new ConfigurationError("No wallet accounts available");
|
|
1445
1473
|
}
|
|
1446
|
-
|
|
1474
|
+
const s = normalizeBrowserSignerString(accounts[0]);
|
|
1475
|
+
if (!s) {
|
|
1476
|
+
throw new ConfigurationError("No wallet accounts available");
|
|
1477
|
+
}
|
|
1478
|
+
return { signerWalletAddress: s, provider };
|
|
1447
1479
|
}
|
|
1448
1480
|
throw new ConfigurationError("Invalid wallet provider");
|
|
1449
1481
|
}
|
|
@@ -1506,47 +1538,74 @@ var init_client = __esm({
|
|
|
1506
1538
|
signatureMethod: params.signatureMethod
|
|
1507
1539
|
});
|
|
1508
1540
|
}
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1541
|
+
async createWalletLinkData(params = {}) {
|
|
1542
|
+
const normalizedPrimary = this._normalizeIdentity(params.primaryWalletAddress);
|
|
1543
|
+
const normalizedSecondary = this._normalizeIdentity(params.secondaryWalletAddress);
|
|
1544
|
+
if (!EVM_ADDRESS_RE.test(normalizedPrimary)) {
|
|
1545
|
+
throw new ValidationError("wallet-link requires a valid primaryWalletAddress");
|
|
1546
|
+
}
|
|
1547
|
+
if (!EVM_ADDRESS_RE.test(normalizedSecondary)) {
|
|
1548
|
+
throw new ValidationError("wallet-link requires a valid secondaryWalletAddress");
|
|
1549
|
+
}
|
|
1550
|
+
if (normalizedPrimary === normalizedSecondary) {
|
|
1551
|
+
throw new ValidationError("wallet-link secondaryWalletAddress must differ from primaryWalletAddress");
|
|
1552
|
+
}
|
|
1553
|
+
const providerWallet = params.wallet || this._getDefaultBrowserWallet();
|
|
1554
|
+
const { signerWalletAddress, provider } = await this._resolveWalletSigner(providerWallet);
|
|
1555
|
+
const normalizedSigner = this._normalizeIdentity(signerWalletAddress);
|
|
1556
|
+
if (!EVM_ADDRESS_RE.test(normalizedSigner)) {
|
|
1557
|
+
throw new ValidationError("wallet-link requires an EVM wallet/provider for the secondary wallet");
|
|
1558
|
+
}
|
|
1559
|
+
if (normalizedSigner !== normalizedSecondary) {
|
|
1560
|
+
throw new ValidationError("wallet-link wallet/provider must be connected to secondaryWalletAddress");
|
|
1561
|
+
}
|
|
1562
|
+
const resolvedChain = (() => {
|
|
1563
|
+
const raw = String(params.chain || "").trim();
|
|
1564
|
+
if (!raw) return `eip155:${this._getHubChainId()}`;
|
|
1565
|
+
if (!/^eip155:\d+$/.test(raw)) {
|
|
1566
|
+
throw new ValidationError("wallet-link requires chain in the form eip155:<chainId>");
|
|
1567
|
+
}
|
|
1568
|
+
return raw;
|
|
1569
|
+
})();
|
|
1570
|
+
const signedTimestamp = Number.isFinite(Number(params.signedTimestamp)) && Number(params.signedTimestamp) > 0 ? Number(params.signedTimestamp) : Date.now();
|
|
1571
|
+
const linkData = {
|
|
1572
|
+
primaryAccountId: `${resolvedChain}:${normalizedPrimary}`,
|
|
1573
|
+
secondaryAccountId: `${resolvedChain}:${normalizedSecondary}`,
|
|
1574
|
+
primaryWalletAddress: normalizedPrimary,
|
|
1575
|
+
secondaryWalletAddress: normalizedSecondary
|
|
1576
|
+
};
|
|
1577
|
+
const message = constructVerificationMessage({
|
|
1578
|
+
walletAddress: normalizedSecondary,
|
|
1579
|
+
signedTimestamp,
|
|
1580
|
+
data: linkData,
|
|
1581
|
+
verifierIds: ["wallet-link"],
|
|
1582
|
+
chain: resolvedChain
|
|
1583
|
+
});
|
|
1584
|
+
let signature;
|
|
1585
|
+
try {
|
|
1586
|
+
signature = await signMessage({
|
|
1587
|
+
provider,
|
|
1588
|
+
message,
|
|
1589
|
+
walletAddress: signerWalletAddress
|
|
1590
|
+
});
|
|
1591
|
+
} catch (error) {
|
|
1592
|
+
if (error?.code === 4001) {
|
|
1593
|
+
throw new ValidationError("User rejected wallet-link signature request");
|
|
1594
|
+
}
|
|
1595
|
+
throw new ValidationError(`Failed to sign wallet-link message: ${error?.message || String(error)}`);
|
|
1596
|
+
}
|
|
1597
|
+
const label = String(params.label || "").trim().slice(0, 64);
|
|
1598
|
+
return {
|
|
1599
|
+
primaryWalletAddress: normalizedPrimary,
|
|
1600
|
+
secondaryWalletAddress: normalizedSecondary,
|
|
1601
|
+
signature,
|
|
1602
|
+
chain: resolvedChain,
|
|
1603
|
+
signatureMethod: "eip191",
|
|
1604
|
+
signedTimestamp,
|
|
1605
|
+
relationshipType: normalizeWalletLinkRelationshipType(params.relationshipType),
|
|
1606
|
+
...label ? { label } : {}
|
|
1607
|
+
};
|
|
1608
|
+
}
|
|
1550
1609
|
async verify(params) {
|
|
1551
1610
|
if ((!params?.signature || !params?.walletAddress) && (params?.verifier || params?.content || params?.data)) {
|
|
1552
1611
|
const { content, verifier = "ownership-basic", data: data2 = null, wallet = null, options: options2 = {} } = params;
|
|
@@ -1588,11 +1647,16 @@ var init_client = __esm({
|
|
|
1588
1647
|
}
|
|
1589
1648
|
let walletAddress2, provider;
|
|
1590
1649
|
if (wallet) {
|
|
1591
|
-
walletAddress2 = wallet.address || wallet.selectedAddress || wallet.walletAddress || (typeof wallet.getAddress === "function" ? await wallet.getAddress() : null);
|
|
1650
|
+
walletAddress2 = wallet.address || wallet.selectedAddress || wallet.walletAddress || (typeof wallet.getAddress === "function" ? await wallet.getAddress().catch(() => null) : null);
|
|
1592
1651
|
provider = wallet.provider || wallet;
|
|
1593
1652
|
if (!walletAddress2 && provider && typeof provider.request === "function") {
|
|
1594
|
-
|
|
1595
|
-
walletAddress2 = Array.isArray(accounts) ? accounts[0] : null;
|
|
1653
|
+
let accounts = await provider.request({ method: "eth_accounts" });
|
|
1654
|
+
walletAddress2 = Array.isArray(accounts) && accounts.length > 0 ? accounts[0] : null;
|
|
1655
|
+
if (!walletAddress2) {
|
|
1656
|
+
await provider.request({ method: "eth_requestAccounts" });
|
|
1657
|
+
accounts = await provider.request({ method: "eth_accounts" });
|
|
1658
|
+
walletAddress2 = Array.isArray(accounts) && accounts.length > 0 ? accounts[0] : null;
|
|
1659
|
+
}
|
|
1596
1660
|
}
|
|
1597
1661
|
} else {
|
|
1598
1662
|
if (typeof window === "undefined" || !window.ethereum) {
|
|
@@ -1603,6 +1667,15 @@ var init_client = __esm({
|
|
|
1603
1667
|
const accounts = await provider.request({ method: "eth_accounts" });
|
|
1604
1668
|
walletAddress2 = accounts[0];
|
|
1605
1669
|
}
|
|
1670
|
+
{
|
|
1671
|
+
const normalized = normalizeBrowserSignerString(
|
|
1672
|
+
typeof walletAddress2 === "string" ? walletAddress2 : null
|
|
1673
|
+
);
|
|
1674
|
+
if (!normalized) {
|
|
1675
|
+
throw new ConfigurationError("No wallet accounts available. Connect a wallet to continue.");
|
|
1676
|
+
}
|
|
1677
|
+
walletAddress2 = normalized;
|
|
1678
|
+
}
|
|
1606
1679
|
let verificationData;
|
|
1607
1680
|
if (verifier === "ownership-basic") {
|
|
1608
1681
|
if (data2 && typeof data2 === "object") {
|
|
@@ -1754,8 +1827,6 @@ var init_client = __esm({
|
|
|
1754
1827
|
verificationData = {
|
|
1755
1828
|
walletAddress: data2?.walletAddress || walletAddress2,
|
|
1756
1829
|
...data2?.provider && { provider: data2.provider },
|
|
1757
|
-
// Mainnet-first semantics: if caller doesn't provide chainId, default to Ethereum mainnet (1).
|
|
1758
|
-
// This avoids accidental testnet semantics for risk providers.
|
|
1759
1830
|
chainId: typeof data2?.chainId === "number" && Number.isFinite(data2.chainId) ? data2.chainId : 1,
|
|
1760
1831
|
...data2?.includeDetails !== void 0 && { includeDetails: data2.includeDetails }
|
|
1761
1832
|
};
|
|
@@ -1777,7 +1848,6 @@ var init_client = __esm({
|
|
|
1777
1848
|
data: verificationData,
|
|
1778
1849
|
verifierIds: verifierIds2,
|
|
1779
1850
|
chainId: this._getHubChainId()
|
|
1780
|
-
// Protocol-managed chain
|
|
1781
1851
|
});
|
|
1782
1852
|
let signature2;
|
|
1783
1853
|
try {
|
|
@@ -1813,6 +1883,7 @@ var init_client = __esm({
|
|
|
1813
1883
|
const hexMsg = toHexUtf82(message);
|
|
1814
1884
|
signature2 = await provider.request({ method: "personal_sign", params: [hexMsg, walletAddress2] });
|
|
1815
1885
|
} catch (e) {
|
|
1886
|
+
void e;
|
|
1816
1887
|
}
|
|
1817
1888
|
}
|
|
1818
1889
|
if (!signature2) {
|
|
@@ -1922,7 +1993,6 @@ ${bytes.length}`;
|
|
|
1922
1993
|
const optionsPayload = {
|
|
1923
1994
|
...options && typeof options === "object" ? options : {},
|
|
1924
1995
|
targetChains: Array.isArray(options?.targetChains) ? options.targetChains : [],
|
|
1925
|
-
// Privacy and storage options (defaults)
|
|
1926
1996
|
privacyLevel: options?.privacyLevel || "private",
|
|
1927
1997
|
publicDisplay: options?.publicDisplay || false,
|
|
1928
1998
|
storeOriginalContent: typeof options?.storeOriginalContent === "boolean" ? options.storeOriginalContent : true
|
|
@@ -1945,16 +2015,6 @@ ${bytes.length}`;
|
|
|
1945
2015
|
}
|
|
1946
2016
|
return this._formatResponse(response);
|
|
1947
2017
|
}
|
|
1948
|
-
/**
|
|
1949
|
-
* Get proof record by proof receipt id.
|
|
1950
|
-
*
|
|
1951
|
-
* @param {string} proofId - Proof receipt ID (0x + 64 hex).
|
|
1952
|
-
* @returns {Promise<Object>} Proof record and verification state
|
|
1953
|
-
*
|
|
1954
|
-
* @example
|
|
1955
|
-
* const result = await client.getProof('0x...');
|
|
1956
|
-
* console.log('Status:', result.status);
|
|
1957
|
-
*/
|
|
1958
2018
|
async getProof(proofId) {
|
|
1959
2019
|
if (!proofId || typeof proofId !== "string") {
|
|
1960
2020
|
throw new ValidationError("proofId is required");
|
|
@@ -1965,16 +2025,6 @@ ${bytes.length}`;
|
|
|
1965
2025
|
}
|
|
1966
2026
|
return this._formatResponse(response);
|
|
1967
2027
|
}
|
|
1968
|
-
/**
|
|
1969
|
-
* Get private proof record with wallet signature
|
|
1970
|
-
*
|
|
1971
|
-
* @param {string} proofId - Proof receipt ID.
|
|
1972
|
-
* @param {Object} wallet - Wallet provider (window.ethereum or ethers Wallet)
|
|
1973
|
-
* @returns {Promise<Object>} Private proof record and verification state
|
|
1974
|
-
*
|
|
1975
|
-
* @example
|
|
1976
|
-
* const privateData = await client.getPrivateProof(proofId, window.ethereum);
|
|
1977
|
-
*/
|
|
1978
2028
|
async getPrivateProof(proofId, wallet = null) {
|
|
1979
2029
|
if (!proofId || typeof proofId !== "string") {
|
|
1980
2030
|
throw new ValidationError("proofId is required");
|
|
@@ -2042,11 +2092,6 @@ ${bytes.length}`;
|
|
|
2042
2092
|
}
|
|
2043
2093
|
return this._formatResponse(response);
|
|
2044
2094
|
}
|
|
2045
|
-
/**
|
|
2046
|
-
* Check API health
|
|
2047
|
-
*
|
|
2048
|
-
* @returns {Promise<boolean>} True if API is healthy
|
|
2049
|
-
*/
|
|
2050
2095
|
async isHealthy() {
|
|
2051
2096
|
try {
|
|
2052
2097
|
const response = await this._makeRequest("GET", "/api/v1/health");
|
|
@@ -2055,19 +2100,10 @@ ${bytes.length}`;
|
|
|
2055
2100
|
return false;
|
|
2056
2101
|
}
|
|
2057
2102
|
}
|
|
2058
|
-
/**
|
|
2059
|
-
* List available verifiers
|
|
2060
|
-
*
|
|
2061
|
-
* @returns {Promise<string[]>} Array of verifier IDs
|
|
2062
|
-
*/
|
|
2063
2103
|
async getVerifiers() {
|
|
2064
2104
|
const catalog = await this.getVerifierCatalog();
|
|
2065
2105
|
return Array.isArray(catalog?.data) ? catalog.data : [];
|
|
2066
2106
|
}
|
|
2067
|
-
/**
|
|
2068
|
-
* Get the public verifier catalog with per-verifier capabilities.
|
|
2069
|
-
* @returns {Promise<{data: string[], metadata: Record<string, { supportsDirectApi?: boolean }>, meta?: object}>}
|
|
2070
|
-
*/
|
|
2071
2107
|
async getVerifierCatalog() {
|
|
2072
2108
|
const response = await this._makeRequest("GET", "/api/v1/verification/verifiers");
|
|
2073
2109
|
if (!response.success) {
|
|
@@ -2079,31 +2115,6 @@ ${bytes.length}`;
|
|
|
2079
2115
|
meta: response.meta && typeof response.meta === "object" && !Array.isArray(response.meta) ? response.meta : {}
|
|
2080
2116
|
};
|
|
2081
2117
|
}
|
|
2082
|
-
/**
|
|
2083
|
-
* POLL PROOF STATUS - Wait for verification completion
|
|
2084
|
-
*
|
|
2085
|
-
* Polls the verification status until it reaches a terminal state (completed or failed).
|
|
2086
|
-
* Useful for providing real-time feedback to users during verification.
|
|
2087
|
-
*
|
|
2088
|
-
* @param {string} proofId - Proof ID to poll.
|
|
2089
|
-
* @param {Object} [options] - Polling options
|
|
2090
|
-
* @param {number} [options.interval=5000] - Polling interval in ms
|
|
2091
|
-
* @param {number} [options.timeout=120000] - Total timeout in ms
|
|
2092
|
-
* @param {Function} [options.onProgress] - Progress callback function
|
|
2093
|
-
* @returns {Promise<Object>} Final verification status
|
|
2094
|
-
*
|
|
2095
|
-
* @example
|
|
2096
|
-
* const finalStatus = await client.pollProofStatus(proofId, {
|
|
2097
|
-
* interval: 3000,
|
|
2098
|
-
* timeout: 60000,
|
|
2099
|
-
* onProgress: (status) => {
|
|
2100
|
-
* console.log('Current status:', status.status);
|
|
2101
|
-
* if (status.crosschain) {
|
|
2102
|
-
* console.log(`Cross-chain: ${status.crosschain.finalized}/${status.crosschain.totalChains}`);
|
|
2103
|
-
* }
|
|
2104
|
-
* }
|
|
2105
|
-
* });
|
|
2106
|
-
*/
|
|
2107
2118
|
async pollProofStatus(proofId, options = {}) {
|
|
2108
2119
|
const {
|
|
2109
2120
|
interval = 5e3,
|
|
@@ -2148,11 +2159,6 @@ ${bytes.length}`;
|
|
|
2148
2159
|
}
|
|
2149
2160
|
throw new NetworkError(`Polling timeout after ${timeout}ms`, "POLLING_TIMEOUT");
|
|
2150
2161
|
}
|
|
2151
|
-
/**
|
|
2152
|
-
* DETECT CHAIN ID - Get current wallet chain
|
|
2153
|
-
*
|
|
2154
|
-
* @returns {Promise<number>} Current chain ID
|
|
2155
|
-
*/
|
|
2156
2162
|
async detectChainId() {
|
|
2157
2163
|
if (typeof window === "undefined" || !window.ethereum) {
|
|
2158
2164
|
throw new ConfigurationError("No Web3 wallet detected");
|
|
@@ -2164,7 +2170,6 @@ ${bytes.length}`;
|
|
|
2164
2170
|
throw new NetworkError(`Failed to detect chain ID: ${error.message}`);
|
|
2165
2171
|
}
|
|
2166
2172
|
}
|
|
2167
|
-
/** Revoke your own proof (owner-signed) */
|
|
2168
2173
|
async revokeOwnProof(proofId, wallet) {
|
|
2169
2174
|
if (!proofId || typeof proofId !== "string") {
|
|
2170
2175
|
throw new ValidationError("proofId is required");
|
|
@@ -2215,22 +2220,6 @@ ${bytes.length}`;
|
|
|
2215
2220
|
}
|
|
2216
2221
|
return true;
|
|
2217
2222
|
}
|
|
2218
|
-
/**
|
|
2219
|
-
* GET PROOFS BY WALLET - Fetch proofs for a wallet address
|
|
2220
|
-
*
|
|
2221
|
-
* @param {string} walletAddress - Wallet identity (EVM/Solana/DID)
|
|
2222
|
-
* @param {Object} [options] - Filter options
|
|
2223
|
-
* @param {number} [options.limit] - Max results (default: 50; higher limits require owner access)
|
|
2224
|
-
* @param {number} [options.offset] - Pagination offset (default: 0)
|
|
2225
|
-
* @param {string} [options.qHash] - Filter to single proof by qHash
|
|
2226
|
-
* @returns {Promise<Object>} Proofs result
|
|
2227
|
-
*
|
|
2228
|
-
* @example
|
|
2229
|
-
* const result = await client.getProofsByWallet('0x...', {
|
|
2230
|
-
* limit: 50,
|
|
2231
|
-
* offset: 0
|
|
2232
|
-
* });
|
|
2233
|
-
*/
|
|
2234
2223
|
async getProofsByWallet(walletAddress, options = {}) {
|
|
2235
2224
|
if (!walletAddress || typeof walletAddress !== "string") {
|
|
2236
2225
|
throw new ValidationError("walletAddress is required");
|
|
@@ -2258,18 +2247,6 @@ ${bytes.length}`;
|
|
|
2258
2247
|
nextOffset: response.data?.nextOffset ?? null
|
|
2259
2248
|
};
|
|
2260
2249
|
}
|
|
2261
|
-
/**
|
|
2262
|
-
* Get proofs by wallet (owner access)
|
|
2263
|
-
*
|
|
2264
|
-
* Signs an owner-access intent and requests private proofs via signature headers.
|
|
2265
|
-
*
|
|
2266
|
-
* @param {string} walletAddress - Wallet identity (EVM/Solana/DID)
|
|
2267
|
-
* @param {Object} [options]
|
|
2268
|
-
* @param {number} [options.limit] - Max results (server enforces caps)
|
|
2269
|
-
* @param {number} [options.offset] - Pagination offset
|
|
2270
|
-
* @param {string} [options.qHash] - Filter to single proof by qHash
|
|
2271
|
-
* @param {Object} [wallet] - Optional injected wallet/provider (MetaMask/ethers Wallet)
|
|
2272
|
-
*/
|
|
2273
2250
|
async getPrivateProofsByWallet(walletAddress, options = {}, wallet = null) {
|
|
2274
2251
|
if (!walletAddress || typeof walletAddress !== "string") {
|
|
2275
2252
|
throw new ValidationError("walletAddress is required");
|
|
@@ -2340,31 +2317,6 @@ ${bytes.length}`;
|
|
|
2340
2317
|
nextOffset: response.data?.nextOffset ?? null
|
|
2341
2318
|
};
|
|
2342
2319
|
}
|
|
2343
|
-
/**
|
|
2344
|
-
* Gate check (HTTP API) — minimal eligibility response.
|
|
2345
|
-
*
|
|
2346
|
-
* Calls the gate endpoint and returns a **minimal** yes/no response.
|
|
2347
|
-
* By default this checks **public + unlisted** proofs.
|
|
2348
|
-
*
|
|
2349
|
-
* When `includePrivate=true`, this can perform owner-signed private checks
|
|
2350
|
-
* (no full proof payloads returned) by providing a wallet/provider.
|
|
2351
|
-
*
|
|
2352
|
-
* Prefer this over `checkGate()` when you need the smallest, most stable
|
|
2353
|
-
* response shape and do not need full proof payloads.
|
|
2354
|
-
*
|
|
2355
|
-
* @param {Object} params - Gate check query params
|
|
2356
|
-
* @param {string} params.address - Wallet identity to check (EVM/Solana/DID)
|
|
2357
|
-
* @param {Array<string>|string} [params.verifierIds] - Verifier IDs to match (array or comma-separated)
|
|
2358
|
-
* @param {boolean} [params.requireAll] - Require all verifierIds on a single proof
|
|
2359
|
-
* @param {number} [params.minCount] - Minimum number of matching proofs
|
|
2360
|
-
* @param {number} [params.sinceDays] - Optional time window in days
|
|
2361
|
-
* @param {number} [params.since] - Optional unix timestamp in ms (lower bound)
|
|
2362
|
-
* @param {number} [params.limit] - Max rows to scan (server may clamp)
|
|
2363
|
-
* @param {boolean} [params.includePrivate] - Include private proofs for owner-authenticated requests
|
|
2364
|
-
* @param {boolean} [params.includeQHashes] - Include matched qHashes in response (minimal IDs only)
|
|
2365
|
-
* @param {Object} [params.wallet] - Optional wallet/provider used to sign includePrivate owner checks
|
|
2366
|
-
* @returns {Promise<Object>} API response ({ success, data })
|
|
2367
|
-
*/
|
|
2368
2320
|
async gateCheck(params = {}) {
|
|
2369
2321
|
const address = (params.address || "").toString();
|
|
2370
2322
|
if (!validateUniversalAddress(address, params.chain)) {
|
|
@@ -2436,8 +2388,7 @@ ${bytes.length}`;
|
|
|
2436
2388
|
});
|
|
2437
2389
|
}
|
|
2438
2390
|
}
|
|
2439
|
-
if (
|
|
2440
|
-
} else {
|
|
2391
|
+
if (auth) {
|
|
2441
2392
|
const normalizedAuthWallet = this._normalizeIdentity(auth.walletAddress);
|
|
2442
2393
|
const normalizedAddress = this._normalizeIdentity(address);
|
|
2443
2394
|
if (!normalizedAuthWallet || normalizedAuthWallet !== normalizedAddress) {
|
|
@@ -2460,45 +2411,6 @@ ${bytes.length}`;
|
|
|
2460
2411
|
}
|
|
2461
2412
|
return response;
|
|
2462
2413
|
}
|
|
2463
|
-
/**
|
|
2464
|
-
* CHECK GATE — Local preview against proofs you already have in memory or from `getProofsByWallet`.
|
|
2465
|
-
*
|
|
2466
|
-
* **Not authoritative for access control.** For production allow/deny, use {@link NeusClient#gateCheck}
|
|
2467
|
-
* (`GET /api/v1/proofs/check`), which applies the same rules as the NEUS API. This method is useful for
|
|
2468
|
-
* UI previews, offline-ish flows, or when you already fetched proofs and want a quick match without
|
|
2469
|
-
* another round trip — but it can disagree with the server (e.g. `contentHash` matching uses a local
|
|
2470
|
-
* approximation when proof data only has inline `content`; the API uses the standard server-side hash).
|
|
2471
|
-
*
|
|
2472
|
-
* Gate-first verification: checks if wallet has valid proofs satisfying requirements.
|
|
2473
|
-
* Returns which requirements are missing/expired.
|
|
2474
|
-
*
|
|
2475
|
-
* @param {Object} params - Gate check parameters
|
|
2476
|
-
* @param {string} params.walletAddress - Target wallet
|
|
2477
|
-
* @param {Array<Object>} params.requirements - Array of gate requirements
|
|
2478
|
-
* @param {string} params.requirements[].verifierId - Required verifier ID
|
|
2479
|
-
* @param {number} [params.requirements[].maxAgeMs] - Max proof age in ms (TTL)
|
|
2480
|
-
* @param {boolean} [params.requirements[].optional] - If true, not required for gate satisfaction
|
|
2481
|
-
* @param {number} [params.requirements[].minCount] - Minimum proofs needed (default: 1)
|
|
2482
|
-
* @param {Object} [params.requirements[].match] - Verifier data match criteria
|
|
2483
|
-
* Supports nested fields: 'reference.type', 'reference.id', 'content', 'contentHash', 'input.*', 'license.*'
|
|
2484
|
-
* Supports verifier-specific:
|
|
2485
|
-
* - NFT/Token: 'contractAddress', 'tokenId', 'chainId', 'ownerAddress', 'minBalance'
|
|
2486
|
-
* - DNS: 'domain', 'walletAddress'
|
|
2487
|
-
* - Wallet-link: 'primaryWalletAddress', 'secondaryWalletAddress', 'chain', 'signatureMethod'
|
|
2488
|
-
* - Contract-ownership: 'contractAddress', 'chainId', 'owner', 'verificationMethod'
|
|
2489
|
-
* Note: contentHash matching uses approximation in SDK; for exact SHA-256 matching, use backend API
|
|
2490
|
-
* @param {Array} [params.proofs] - Pre-fetched proofs (skip API call)
|
|
2491
|
-
* @returns {Promise<Object>} Gate result with satisfied, missing, existing
|
|
2492
|
-
*
|
|
2493
|
-
* @example
|
|
2494
|
-
* // Basic gate check
|
|
2495
|
-
* const result = await client.checkGate({
|
|
2496
|
-
* walletAddress: '0x...',
|
|
2497
|
-
* requirements: [
|
|
2498
|
-
* { verifierId: 'nft-ownership', match: { contractAddress: '0x...' } }
|
|
2499
|
-
* ]
|
|
2500
|
-
* });
|
|
2501
|
-
*/
|
|
2502
2414
|
async checkGate(params) {
|
|
2503
2415
|
const { walletAddress, requirements, proofs: preloadedProofs } = params;
|
|
2504
2416
|
if (!validateUniversalAddress(walletAddress)) {
|
|
@@ -2730,7 +2642,6 @@ ${bytes.length}`;
|
|
|
2730
2642
|
];
|
|
2731
2643
|
return typeof status === "string" && terminalStates.some((state) => status.includes(state));
|
|
2732
2644
|
}
|
|
2733
|
-
/** SDK logging (opt-in via config.enableLogging) */
|
|
2734
2645
|
_log(message, data = {}) {
|
|
2735
2646
|
if (this.config.enableLogging) {
|
|
2736
2647
|
try {
|
|
@@ -2819,36 +2730,16 @@ var DAY = 24 * HOUR;
|
|
|
2819
2730
|
var WEEK = 7 * DAY;
|
|
2820
2731
|
var MONTH = 30 * DAY;
|
|
2821
2732
|
var YEAR = 365 * DAY;
|
|
2822
|
-
var GATE_NFT_HOLDER = [
|
|
2823
|
-
|
|
2824
|
-
];
|
|
2825
|
-
var
|
|
2826
|
-
|
|
2827
|
-
];
|
|
2828
|
-
var
|
|
2829
|
-
|
|
2830
|
-
];
|
|
2831
|
-
var
|
|
2832
|
-
{ verifierId: "ownership-dns-txt" }
|
|
2833
|
-
];
|
|
2834
|
-
var GATE_LINKED_WALLETS = [
|
|
2835
|
-
{ verifierId: "wallet-link" }
|
|
2836
|
-
];
|
|
2837
|
-
var GATE_AGENT_IDENTITY = [
|
|
2838
|
-
{ verifierId: "agent-identity" }
|
|
2839
|
-
];
|
|
2840
|
-
var GATE_AGENT_DELEGATION = [
|
|
2841
|
-
{ verifierId: "agent-delegation", maxAgeMs: 7 * DAY }
|
|
2842
|
-
];
|
|
2843
|
-
var GATE_CONTENT_MODERATION = [
|
|
2844
|
-
{ verifierId: "ai-content-moderation" }
|
|
2845
|
-
];
|
|
2846
|
-
var GATE_WALLET_RISK = [
|
|
2847
|
-
{ verifierId: "wallet-risk" }
|
|
2848
|
-
];
|
|
2849
|
-
var GATE_PSEUDONYM = [
|
|
2850
|
-
{ verifierId: "ownership-pseudonym" }
|
|
2851
|
-
];
|
|
2733
|
+
var GATE_NFT_HOLDER = [{ verifierId: "nft-ownership" }];
|
|
2734
|
+
var GATE_TOKEN_HOLDER = [{ verifierId: "token-holding" }];
|
|
2735
|
+
var GATE_CONTRACT_ADMIN = [{ verifierId: "contract-ownership", maxAgeMs: HOUR }];
|
|
2736
|
+
var GATE_DOMAIN_OWNER = [{ verifierId: "ownership-dns-txt" }];
|
|
2737
|
+
var GATE_LINKED_WALLETS = [{ verifierId: "wallet-link" }];
|
|
2738
|
+
var GATE_AGENT_IDENTITY = [{ verifierId: "agent-identity" }];
|
|
2739
|
+
var GATE_AGENT_DELEGATION = [{ verifierId: "agent-delegation", maxAgeMs: 7 * DAY }];
|
|
2740
|
+
var GATE_CONTENT_MODERATION = [{ verifierId: "ai-content-moderation" }];
|
|
2741
|
+
var GATE_WALLET_RISK = [{ verifierId: "wallet-risk" }];
|
|
2742
|
+
var GATE_PSEUDONYM = [{ verifierId: "ownership-pseudonym" }];
|
|
2852
2743
|
function createGate(requirements) {
|
|
2853
2744
|
return requirements.map((req) => {
|
|
2854
2745
|
if (typeof req === "string") {
|