@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 CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  [![npm](https://img.shields.io/npm/v/%40neus%2Fsdk?logo=npm&label=%40neus%2Fsdk&color=98C0EF)](https://www.npmjs.com/package/@neus/sdk)
4
4
 
5
- **Portable trust, shipped as APIs and widgets.** The JavaScript SDK runs NEUS verification, polling, and **`gateCheck`**. Store **`proofId`** (your **proof ID**) once, then reuse. NEUS runs the checks; you do not fork verifier logic into your repo.
5
+ **Portable trust, shipped as APIs and widgets.** The JavaScript SDK runs NEUS verification, polling, and **`gateCheck`**. Store **`proofId`**, then reuse it. NEUS runs the checks; you do not fork verifier logic into your repo.
6
6
 
7
7
  ## Install
8
8
 
@@ -16,7 +16,22 @@ npm install @neus/sdk
16
16
  npx -y -p @neus/sdk neus init
17
17
  ```
18
18
 
19
- Prints the hosted MCP URL and documentation links in your terminal - fast setup in IDEs and agent clients.
19
+ Configures supported MCP clients automatically. By default the command installs NEUS into user-level Claude Code, Cursor, and VS Code MCP config when those clients are detected.
20
+
21
+ ## CLI
22
+
23
+ ```bash
24
+ # Autopilot setup for detected clients
25
+ npx -y -p @neus/sdk neus init
26
+
27
+ # Enable personal account tools such as neus_me and private reads
28
+ npx -y -p @neus/sdk neus auth --access-key <npk_...>
29
+
30
+ # Inspect current NEUS MCP setup
31
+ npx -y -p @neus/sdk neus status --json
32
+ ```
33
+
34
+ Use `neus init --project` when you want shared repo config instead of personal user-scope setup. Access keys stay user-scope only so secrets do not land in checked-in config.
20
35
 
21
36
  ## Minimal working example
22
37
 
@@ -51,10 +66,11 @@ const check = await client.gateCheck({
51
66
  | `client.gateCheck()` | **Server eligibility** (use for real gates) |
52
67
  | `client.checkGate()` | Local preview only |
53
68
  | `getHostedCheckoutUrl()` | Hosted verify URL |
69
+ | `client.createWalletLinkData()` | Build advanced direct wallet-link payload |
54
70
 
55
71
  ## VerifyGate (React)
56
72
 
57
- Defaults: unlisted public create (`privacyLevel: 'public'`, `publicDisplay: false`). Set `proofOptions` for other visibility.
73
+ Defaults: private create (`privacyLevel: 'private'`, `publicDisplay: false`). Set `proofOptions` only when you intentionally need public visibility.
58
74
 
59
75
  ```jsx
60
76
  import { VerifyGate } from '@neus/sdk/widgets';
@@ -79,8 +95,9 @@ const client = new NeusClient({
79
95
  ## Docs
80
96
 
81
97
  - [Quickstart](https://docs.neus.network/quickstart)
98
+ - [Examples](https://docs.neus.network/examples) — start with the [trust receipts showcase](https://github.com/neus/network/tree/main/examples/trust-receipts-showcase) locally; [live demo](https://neus.network/demo) on the product site
82
99
  - [SDK](https://docs.neus.network/sdks/javascript)
83
- - [MCP](https://docs.neus.network/mcp/overview) (IDEs and assistants)
100
+ - [MCP](https://docs.neus.network/mcp/overview) for IDEs and assistants
84
101
  - [Widgets](https://docs.neus.network/widgets/overview)
85
102
  - [API](https://docs.neus.network/api/overview)
86
103
  - [Hosted Verify](https://docs.neus.network/cookbook/auth-hosted-verify)
package/SECURITY.md CHANGED
@@ -16,18 +16,23 @@ Treat **wallet signatures** and **API keys** as secrets. Do not log them, expose
16
16
 
17
17
  ## Privacy defaults
18
18
 
19
- **`client.verify()`** defaults to **private** stored results with **original content stored** (owner-authenticated reads).
19
+ **`client.verify()`** defaults to **private**.
20
20
 
21
- **`VerifyGate`** create mode defaults to **unlisted public** (`privacyLevel: 'public'`, `publicDisplay: false`, `storeOriginalContent: true`) so gates and `gateCheck` work without extra options.
21
+ **`VerifyGate`** create mode also defaults to **private**.
22
22
 
23
- For raw SDK flows that must power **`gateCheck`** without owner-authenticated access, set **unlisted public** explicitly (`privacyLevel: 'public'`, `publicDisplay: false`). Anyone with the proof id can resolve public proofs. Do not treat unlisted as secret.
23
+ Use public visibility only when you intentionally need proof reuse without owner-authenticated access:
24
24
 
25
- **Hide original content** (metadata/hash only): set `storeOriginalContent: false` when your product must not persist original bytes.
25
+ - unlisted public: `privacyLevel: 'public'`, `publicDisplay: false`
26
+ - listed public: `privacyLevel: 'public'`, `publicDisplay: true`
27
+
28
+ Do not treat unlisted public proofs as secret.
29
+
30
+ `storeOriginalContent` is an advanced storage control. Most integrations should leave the default as-is.
26
31
 
27
32
  Controls:
28
33
 
29
- - `privacyLevel` - private (vaulted to the wallet) vs public (eligible for policy checks without proving owner identity)
34
+ - `privacyLevel` - private by default; switch to public only for intentional public reuse
30
35
  - `publicDisplay` - discovery vs unlisted
31
- - `storeOriginalContent` - retain original content vs hash/metadata only
36
+ - `storeOriginalContent` - advanced content-storage control
32
37
 
33
38
  Discoverable listings require **`privacyLevel: 'public'`** and **`publicDisplay: true`**.
package/cjs/client.cjs CHANGED
@@ -364,9 +364,7 @@ async function signMessage({ provider, message, walletAddress, chain } = {}) {
364
364
  throw new SDKError("Unable to sign message with provided wallet/provider", "SIGNER_UNAVAILABLE");
365
365
  }
366
366
  var NEUS_CONSTANTS = {
367
- /** Default EVM chain id for NEUS protocol signing context (`HUB_CHAIN_ID` name kept for compatibility). */
368
367
  HUB_CHAIN_ID: 84532,
369
- // Supported target chains for cross-chain propagation
370
368
  TESTNET_CHAINS: [
371
369
  11155111,
372
370
  // Ethereum Sepolia
@@ -377,15 +375,12 @@ var NEUS_CONSTANTS = {
377
375
  80002
378
376
  // Polygon Amoy
379
377
  ],
380
- // API endpoints
381
378
  API_BASE_URL: "https://api.neus.network",
382
379
  API_VERSION: "v1",
383
- // Timeouts and limits
384
380
  SIGNATURE_MAX_AGE_MS: 5 * 60 * 1e3,
385
381
  // 5 minutes
386
382
  REQUEST_TIMEOUT_MS: 30 * 1e3,
387
383
  // 30 seconds
388
- // Default verifier set for quick starts
389
384
  DEFAULT_VERIFIERS: [
390
385
  "ownership-basic",
391
386
  "nft-ownership",
@@ -411,6 +406,21 @@ var FALLBACK_PUBLIC_VERIFIER_CATALOG = {
411
406
  "ai-content-moderation": { supportsDirectApi: true }
412
407
  };
413
408
  var EVM_ADDRESS_RE = /^0x[a-fA-F0-9]{40}$/;
409
+ var WALLET_LINK_RELATIONSHIP_TYPES = /* @__PURE__ */ new Set(["primary", "personal", "org", "affiliate", "agent", "linked"]);
410
+ function normalizeWalletLinkRelationshipType(value) {
411
+ const normalized = String(value || "").trim().toLowerCase();
412
+ return WALLET_LINK_RELATIONSHIP_TYPES.has(normalized) ? normalized : "linked";
413
+ }
414
+ function normalizeBrowserSignerString(raw) {
415
+ if (raw === null || raw === void 0) {
416
+ return null;
417
+ }
418
+ if (typeof raw === "string") {
419
+ const t = raw.trim();
420
+ return t.length > 0 ? t : null;
421
+ }
422
+ return null;
423
+ }
414
424
  var validateVerifierData = (verifierId, data) => {
415
425
  if (!data || typeof data !== "object") {
416
426
  return { valid: false, error: "Data object is required" };
@@ -739,26 +749,49 @@ var NeusClient = class {
739
749
  if (!wallet) {
740
750
  throw new ConfigurationError("No wallet provider available");
741
751
  }
742
- if (wallet.address) {
743
- return { signerWalletAddress: wallet.address, provider: wallet };
752
+ if (wallet.address !== null && wallet.address !== void 0) {
753
+ const s = normalizeBrowserSignerString(
754
+ typeof wallet.address === "string" ? wallet.address : null
755
+ );
756
+ if (s) {
757
+ return { signerWalletAddress: s, provider: wallet };
758
+ }
744
759
  }
745
760
  if (wallet.publicKey && typeof wallet.publicKey.toBase58 === "function") {
746
- return { signerWalletAddress: wallet.publicKey.toBase58(), provider: wallet };
761
+ const b58 = wallet.publicKey.toBase58();
762
+ const s = normalizeBrowserSignerString(typeof b58 === "string" ? b58 : null);
763
+ if (s) {
764
+ return { signerWalletAddress: s, provider: wallet };
765
+ }
747
766
  }
748
767
  if (typeof wallet.getAddress === "function") {
749
- const signerWalletAddress = await wallet.getAddress().catch(() => null);
750
- return { signerWalletAddress, provider: wallet };
768
+ const got = await wallet.getAddress().catch(() => null);
769
+ const s = normalizeBrowserSignerString(
770
+ got === null || got === void 0 ? null : typeof got === "string" ? got : null
771
+ );
772
+ if (s) {
773
+ return { signerWalletAddress: s, provider: wallet };
774
+ }
751
775
  }
752
776
  if (wallet.selectedAddress || wallet.request) {
753
777
  const provider = wallet;
754
778
  if (wallet.selectedAddress) {
755
- return { signerWalletAddress: wallet.selectedAddress, provider };
779
+ const s2 = normalizeBrowserSignerString(
780
+ typeof wallet.selectedAddress === "string" ? wallet.selectedAddress : null
781
+ );
782
+ if (s2) {
783
+ return { signerWalletAddress: s2, provider };
784
+ }
756
785
  }
757
786
  const accounts = await provider.request({ method: "eth_accounts" });
758
787
  if (!accounts || accounts.length === 0) {
759
788
  throw new ConfigurationError("No wallet accounts available");
760
789
  }
761
- return { signerWalletAddress: accounts[0], provider };
790
+ const s = normalizeBrowserSignerString(accounts[0]);
791
+ if (!s) {
792
+ throw new ConfigurationError("No wallet accounts available");
793
+ }
794
+ return { signerWalletAddress: s, provider };
762
795
  }
763
796
  throw new ConfigurationError("Invalid wallet provider");
764
797
  }
@@ -821,47 +854,74 @@ var NeusClient = class {
821
854
  signatureMethod: params.signatureMethod
822
855
  });
823
856
  }
824
- /**
825
- * Create a verification proof.
826
- *
827
- * Supports two paths:
828
- * - **Auto:** Supply `verifier`, `content`, and/or `data` with an optional
829
- * `wallet` provider. The SDK performs signing in the client.
830
- * - **Manual:** Supply pre-signed `verifierIds`, `data`, `walletAddress`,
831
- * `signature`, and `signedTimestamp`.
832
- *
833
- * @param {Object} params - Verification parameters
834
- * @param {string} [params.verifier] - Verifier ID (auto path, e.g. 'ownership-basic')
835
- * @param {string} [params.content] - Content to verify (auto path)
836
- * @param {Object} [params.data] - Structured verification data
837
- * @param {Object} [params.wallet] - Wallet provider (auto path)
838
- * @param {Object} [params.options] - Additional options
839
- * @param {Array<string>} [params.verifierIds] - Array of verifier IDs (manual path)
840
- * @param {string} [params.walletAddress] - Wallet address that signed the request (manual path)
841
- * @param {string} [params.signature] - EIP-191 signature (manual path)
842
- * @param {number} [params.signedTimestamp] - Unix timestamp when signature was created (manual path)
843
- * @param {number} [params.chainId] - EVM signing-context hint; when omitted, resolved to the NEUS protocol primary chain for signing
844
- * @returns {Promise<Object>} Verification result with proofId
845
- *
846
- * @example
847
- * // Auto path
848
- * const proof = await client.verify({
849
- * verifier: 'ownership-basic',
850
- * content: 'Hello World',
851
- * wallet: window.ethereum
852
- * });
853
- *
854
- * @example
855
- * // Manual path
856
- * const proof = await client.verify({
857
- * verifierIds: ['ownership-basic'],
858
- * data: { content: "My content", owner: walletAddress },
859
- * walletAddress: '0x...',
860
- * signature: '0x...',
861
- * signedTimestamp: Date.now(),
862
- * options: { targetChains: [421614, 11155111] }
863
- * });
864
- */
857
+ async createWalletLinkData(params = {}) {
858
+ const normalizedPrimary = this._normalizeIdentity(params.primaryWalletAddress);
859
+ const normalizedSecondary = this._normalizeIdentity(params.secondaryWalletAddress);
860
+ if (!EVM_ADDRESS_RE.test(normalizedPrimary)) {
861
+ throw new ValidationError("wallet-link requires a valid primaryWalletAddress");
862
+ }
863
+ if (!EVM_ADDRESS_RE.test(normalizedSecondary)) {
864
+ throw new ValidationError("wallet-link requires a valid secondaryWalletAddress");
865
+ }
866
+ if (normalizedPrimary === normalizedSecondary) {
867
+ throw new ValidationError("wallet-link secondaryWalletAddress must differ from primaryWalletAddress");
868
+ }
869
+ const providerWallet = params.wallet || this._getDefaultBrowserWallet();
870
+ const { signerWalletAddress, provider } = await this._resolveWalletSigner(providerWallet);
871
+ const normalizedSigner = this._normalizeIdentity(signerWalletAddress);
872
+ if (!EVM_ADDRESS_RE.test(normalizedSigner)) {
873
+ throw new ValidationError("wallet-link requires an EVM wallet/provider for the secondary wallet");
874
+ }
875
+ if (normalizedSigner !== normalizedSecondary) {
876
+ throw new ValidationError("wallet-link wallet/provider must be connected to secondaryWalletAddress");
877
+ }
878
+ const resolvedChain = (() => {
879
+ const raw = String(params.chain || "").trim();
880
+ if (!raw) return `eip155:${this._getHubChainId()}`;
881
+ if (!/^eip155:\d+$/.test(raw)) {
882
+ throw new ValidationError("wallet-link requires chain in the form eip155:<chainId>");
883
+ }
884
+ return raw;
885
+ })();
886
+ const signedTimestamp = Number.isFinite(Number(params.signedTimestamp)) && Number(params.signedTimestamp) > 0 ? Number(params.signedTimestamp) : Date.now();
887
+ const linkData = {
888
+ primaryAccountId: `${resolvedChain}:${normalizedPrimary}`,
889
+ secondaryAccountId: `${resolvedChain}:${normalizedSecondary}`,
890
+ primaryWalletAddress: normalizedPrimary,
891
+ secondaryWalletAddress: normalizedSecondary
892
+ };
893
+ const message = constructVerificationMessage({
894
+ walletAddress: normalizedSecondary,
895
+ signedTimestamp,
896
+ data: linkData,
897
+ verifierIds: ["wallet-link"],
898
+ chain: resolvedChain
899
+ });
900
+ let signature;
901
+ try {
902
+ signature = await signMessage({
903
+ provider,
904
+ message,
905
+ walletAddress: signerWalletAddress
906
+ });
907
+ } catch (error) {
908
+ if (error?.code === 4001) {
909
+ throw new ValidationError("User rejected wallet-link signature request");
910
+ }
911
+ throw new ValidationError(`Failed to sign wallet-link message: ${error?.message || String(error)}`);
912
+ }
913
+ const label = String(params.label || "").trim().slice(0, 64);
914
+ return {
915
+ primaryWalletAddress: normalizedPrimary,
916
+ secondaryWalletAddress: normalizedSecondary,
917
+ signature,
918
+ chain: resolvedChain,
919
+ signatureMethod: "eip191",
920
+ signedTimestamp,
921
+ relationshipType: normalizeWalletLinkRelationshipType(params.relationshipType),
922
+ ...label ? { label } : {}
923
+ };
924
+ }
865
925
  async verify(params) {
866
926
  if ((!params?.signature || !params?.walletAddress) && (params?.verifier || params?.content || params?.data)) {
867
927
  const { content, verifier = "ownership-basic", data: data2 = null, wallet = null, options: options2 = {} } = params;
@@ -903,11 +963,16 @@ var NeusClient = class {
903
963
  }
904
964
  let walletAddress2, provider;
905
965
  if (wallet) {
906
- walletAddress2 = wallet.address || wallet.selectedAddress || wallet.walletAddress || (typeof wallet.getAddress === "function" ? await wallet.getAddress() : null);
966
+ walletAddress2 = wallet.address || wallet.selectedAddress || wallet.walletAddress || (typeof wallet.getAddress === "function" ? await wallet.getAddress().catch(() => null) : null);
907
967
  provider = wallet.provider || wallet;
908
968
  if (!walletAddress2 && provider && typeof provider.request === "function") {
909
- const accounts = await provider.request({ method: "eth_accounts" });
910
- walletAddress2 = Array.isArray(accounts) ? accounts[0] : null;
969
+ let accounts = await provider.request({ method: "eth_accounts" });
970
+ walletAddress2 = Array.isArray(accounts) && accounts.length > 0 ? accounts[0] : null;
971
+ if (!walletAddress2) {
972
+ await provider.request({ method: "eth_requestAccounts" });
973
+ accounts = await provider.request({ method: "eth_accounts" });
974
+ walletAddress2 = Array.isArray(accounts) && accounts.length > 0 ? accounts[0] : null;
975
+ }
911
976
  }
912
977
  } else {
913
978
  if (typeof window === "undefined" || !window.ethereum) {
@@ -918,6 +983,15 @@ var NeusClient = class {
918
983
  const accounts = await provider.request({ method: "eth_accounts" });
919
984
  walletAddress2 = accounts[0];
920
985
  }
986
+ {
987
+ const normalized = normalizeBrowserSignerString(
988
+ typeof walletAddress2 === "string" ? walletAddress2 : null
989
+ );
990
+ if (!normalized) {
991
+ throw new ConfigurationError("No wallet accounts available. Connect a wallet to continue.");
992
+ }
993
+ walletAddress2 = normalized;
994
+ }
921
995
  let verificationData;
922
996
  if (verifier === "ownership-basic") {
923
997
  if (data2 && typeof data2 === "object") {
@@ -1069,8 +1143,6 @@ var NeusClient = class {
1069
1143
  verificationData = {
1070
1144
  walletAddress: data2?.walletAddress || walletAddress2,
1071
1145
  ...data2?.provider && { provider: data2.provider },
1072
- // Mainnet-first semantics: if caller doesn't provide chainId, default to Ethereum mainnet (1).
1073
- // This avoids accidental testnet semantics for risk providers.
1074
1146
  chainId: typeof data2?.chainId === "number" && Number.isFinite(data2.chainId) ? data2.chainId : 1,
1075
1147
  ...data2?.includeDetails !== void 0 && { includeDetails: data2.includeDetails }
1076
1148
  };
@@ -1092,7 +1164,6 @@ var NeusClient = class {
1092
1164
  data: verificationData,
1093
1165
  verifierIds: verifierIds2,
1094
1166
  chainId: this._getHubChainId()
1095
- // Protocol-managed chain
1096
1167
  });
1097
1168
  let signature2;
1098
1169
  try {
@@ -1128,6 +1199,7 @@ var NeusClient = class {
1128
1199
  const hexMsg = toHexUtf82(message);
1129
1200
  signature2 = await provider.request({ method: "personal_sign", params: [hexMsg, walletAddress2] });
1130
1201
  } catch (e) {
1202
+ void e;
1131
1203
  }
1132
1204
  }
1133
1205
  if (!signature2) {
@@ -1237,7 +1309,6 @@ ${bytes.length}`;
1237
1309
  const optionsPayload = {
1238
1310
  ...options && typeof options === "object" ? options : {},
1239
1311
  targetChains: Array.isArray(options?.targetChains) ? options.targetChains : [],
1240
- // Privacy and storage options (defaults)
1241
1312
  privacyLevel: options?.privacyLevel || "private",
1242
1313
  publicDisplay: options?.publicDisplay || false,
1243
1314
  storeOriginalContent: typeof options?.storeOriginalContent === "boolean" ? options.storeOriginalContent : true
@@ -1260,16 +1331,6 @@ ${bytes.length}`;
1260
1331
  }
1261
1332
  return this._formatResponse(response);
1262
1333
  }
1263
- /**
1264
- * Get proof record by proof receipt id.
1265
- *
1266
- * @param {string} proofId - Proof receipt ID (0x + 64 hex).
1267
- * @returns {Promise<Object>} Proof record and verification state
1268
- *
1269
- * @example
1270
- * const result = await client.getProof('0x...');
1271
- * console.log('Status:', result.status);
1272
- */
1273
1334
  async getProof(proofId) {
1274
1335
  if (!proofId || typeof proofId !== "string") {
1275
1336
  throw new ValidationError("proofId is required");
@@ -1280,16 +1341,6 @@ ${bytes.length}`;
1280
1341
  }
1281
1342
  return this._formatResponse(response);
1282
1343
  }
1283
- /**
1284
- * Get private proof record with wallet signature
1285
- *
1286
- * @param {string} proofId - Proof receipt ID.
1287
- * @param {Object} wallet - Wallet provider (window.ethereum or ethers Wallet)
1288
- * @returns {Promise<Object>} Private proof record and verification state
1289
- *
1290
- * @example
1291
- * const privateData = await client.getPrivateProof(proofId, window.ethereum);
1292
- */
1293
1344
  async getPrivateProof(proofId, wallet = null) {
1294
1345
  if (!proofId || typeof proofId !== "string") {
1295
1346
  throw new ValidationError("proofId is required");
@@ -1357,11 +1408,6 @@ ${bytes.length}`;
1357
1408
  }
1358
1409
  return this._formatResponse(response);
1359
1410
  }
1360
- /**
1361
- * Check API health
1362
- *
1363
- * @returns {Promise<boolean>} True if API is healthy
1364
- */
1365
1411
  async isHealthy() {
1366
1412
  try {
1367
1413
  const response = await this._makeRequest("GET", "/api/v1/health");
@@ -1370,19 +1416,10 @@ ${bytes.length}`;
1370
1416
  return false;
1371
1417
  }
1372
1418
  }
1373
- /**
1374
- * List available verifiers
1375
- *
1376
- * @returns {Promise<string[]>} Array of verifier IDs
1377
- */
1378
1419
  async getVerifiers() {
1379
1420
  const catalog = await this.getVerifierCatalog();
1380
1421
  return Array.isArray(catalog?.data) ? catalog.data : [];
1381
1422
  }
1382
- /**
1383
- * Get the public verifier catalog with per-verifier capabilities.
1384
- * @returns {Promise<{data: string[], metadata: Record<string, { supportsDirectApi?: boolean }>, meta?: object}>}
1385
- */
1386
1423
  async getVerifierCatalog() {
1387
1424
  const response = await this._makeRequest("GET", "/api/v1/verification/verifiers");
1388
1425
  if (!response.success) {
@@ -1394,31 +1431,6 @@ ${bytes.length}`;
1394
1431
  meta: response.meta && typeof response.meta === "object" && !Array.isArray(response.meta) ? response.meta : {}
1395
1432
  };
1396
1433
  }
1397
- /**
1398
- * POLL PROOF STATUS - Wait for verification completion
1399
- *
1400
- * Polls the verification status until it reaches a terminal state (completed or failed).
1401
- * Useful for providing real-time feedback to users during verification.
1402
- *
1403
- * @param {string} proofId - Proof ID to poll.
1404
- * @param {Object} [options] - Polling options
1405
- * @param {number} [options.interval=5000] - Polling interval in ms
1406
- * @param {number} [options.timeout=120000] - Total timeout in ms
1407
- * @param {Function} [options.onProgress] - Progress callback function
1408
- * @returns {Promise<Object>} Final verification status
1409
- *
1410
- * @example
1411
- * const finalStatus = await client.pollProofStatus(proofId, {
1412
- * interval: 3000,
1413
- * timeout: 60000,
1414
- * onProgress: (status) => {
1415
- * console.log('Current status:', status.status);
1416
- * if (status.crosschain) {
1417
- * console.log(`Cross-chain: ${status.crosschain.finalized}/${status.crosschain.totalChains}`);
1418
- * }
1419
- * }
1420
- * });
1421
- */
1422
1434
  async pollProofStatus(proofId, options = {}) {
1423
1435
  const {
1424
1436
  interval = 5e3,
@@ -1463,11 +1475,6 @@ ${bytes.length}`;
1463
1475
  }
1464
1476
  throw new NetworkError(`Polling timeout after ${timeout}ms`, "POLLING_TIMEOUT");
1465
1477
  }
1466
- /**
1467
- * DETECT CHAIN ID - Get current wallet chain
1468
- *
1469
- * @returns {Promise<number>} Current chain ID
1470
- */
1471
1478
  async detectChainId() {
1472
1479
  if (typeof window === "undefined" || !window.ethereum) {
1473
1480
  throw new ConfigurationError("No Web3 wallet detected");
@@ -1479,7 +1486,6 @@ ${bytes.length}`;
1479
1486
  throw new NetworkError(`Failed to detect chain ID: ${error.message}`);
1480
1487
  }
1481
1488
  }
1482
- /** Revoke your own proof (owner-signed) */
1483
1489
  async revokeOwnProof(proofId, wallet) {
1484
1490
  if (!proofId || typeof proofId !== "string") {
1485
1491
  throw new ValidationError("proofId is required");
@@ -1530,22 +1536,6 @@ ${bytes.length}`;
1530
1536
  }
1531
1537
  return true;
1532
1538
  }
1533
- /**
1534
- * GET PROOFS BY WALLET - Fetch proofs for a wallet address
1535
- *
1536
- * @param {string} walletAddress - Wallet identity (EVM/Solana/DID)
1537
- * @param {Object} [options] - Filter options
1538
- * @param {number} [options.limit] - Max results (default: 50; higher limits require owner access)
1539
- * @param {number} [options.offset] - Pagination offset (default: 0)
1540
- * @param {string} [options.qHash] - Filter to single proof by qHash
1541
- * @returns {Promise<Object>} Proofs result
1542
- *
1543
- * @example
1544
- * const result = await client.getProofsByWallet('0x...', {
1545
- * limit: 50,
1546
- * offset: 0
1547
- * });
1548
- */
1549
1539
  async getProofsByWallet(walletAddress, options = {}) {
1550
1540
  if (!walletAddress || typeof walletAddress !== "string") {
1551
1541
  throw new ValidationError("walletAddress is required");
@@ -1573,18 +1563,6 @@ ${bytes.length}`;
1573
1563
  nextOffset: response.data?.nextOffset ?? null
1574
1564
  };
1575
1565
  }
1576
- /**
1577
- * Get proofs by wallet (owner access)
1578
- *
1579
- * Signs an owner-access intent and requests private proofs via signature headers.
1580
- *
1581
- * @param {string} walletAddress - Wallet identity (EVM/Solana/DID)
1582
- * @param {Object} [options]
1583
- * @param {number} [options.limit] - Max results (server enforces caps)
1584
- * @param {number} [options.offset] - Pagination offset
1585
- * @param {string} [options.qHash] - Filter to single proof by qHash
1586
- * @param {Object} [wallet] - Optional injected wallet/provider (MetaMask/ethers Wallet)
1587
- */
1588
1566
  async getPrivateProofsByWallet(walletAddress, options = {}, wallet = null) {
1589
1567
  if (!walletAddress || typeof walletAddress !== "string") {
1590
1568
  throw new ValidationError("walletAddress is required");
@@ -1655,31 +1633,6 @@ ${bytes.length}`;
1655
1633
  nextOffset: response.data?.nextOffset ?? null
1656
1634
  };
1657
1635
  }
1658
- /**
1659
- * Gate check (HTTP API) — minimal eligibility response.
1660
- *
1661
- * Calls the gate endpoint and returns a **minimal** yes/no response.
1662
- * By default this checks **public + unlisted** proofs.
1663
- *
1664
- * When `includePrivate=true`, this can perform owner-signed private checks
1665
- * (no full proof payloads returned) by providing a wallet/provider.
1666
- *
1667
- * Prefer this over `checkGate()` when you need the smallest, most stable
1668
- * response shape and do not need full proof payloads.
1669
- *
1670
- * @param {Object} params - Gate check query params
1671
- * @param {string} params.address - Wallet identity to check (EVM/Solana/DID)
1672
- * @param {Array<string>|string} [params.verifierIds] - Verifier IDs to match (array or comma-separated)
1673
- * @param {boolean} [params.requireAll] - Require all verifierIds on a single proof
1674
- * @param {number} [params.minCount] - Minimum number of matching proofs
1675
- * @param {number} [params.sinceDays] - Optional time window in days
1676
- * @param {number} [params.since] - Optional unix timestamp in ms (lower bound)
1677
- * @param {number} [params.limit] - Max rows to scan (server may clamp)
1678
- * @param {boolean} [params.includePrivate] - Include private proofs for owner-authenticated requests
1679
- * @param {boolean} [params.includeQHashes] - Include matched qHashes in response (minimal IDs only)
1680
- * @param {Object} [params.wallet] - Optional wallet/provider used to sign includePrivate owner checks
1681
- * @returns {Promise<Object>} API response ({ success, data })
1682
- */
1683
1636
  async gateCheck(params = {}) {
1684
1637
  const address = (params.address || "").toString();
1685
1638
  if (!validateUniversalAddress(address, params.chain)) {
@@ -1751,8 +1704,7 @@ ${bytes.length}`;
1751
1704
  });
1752
1705
  }
1753
1706
  }
1754
- if (!auth) {
1755
- } else {
1707
+ if (auth) {
1756
1708
  const normalizedAuthWallet = this._normalizeIdentity(auth.walletAddress);
1757
1709
  const normalizedAddress = this._normalizeIdentity(address);
1758
1710
  if (!normalizedAuthWallet || normalizedAuthWallet !== normalizedAddress) {
@@ -1775,45 +1727,6 @@ ${bytes.length}`;
1775
1727
  }
1776
1728
  return response;
1777
1729
  }
1778
- /**
1779
- * CHECK GATE — Local preview against proofs you already have in memory or from `getProofsByWallet`.
1780
- *
1781
- * **Not authoritative for access control.** For production allow/deny, use {@link NeusClient#gateCheck}
1782
- * (`GET /api/v1/proofs/check`), which applies the same rules as the NEUS API. This method is useful for
1783
- * UI previews, offline-ish flows, or when you already fetched proofs and want a quick match without
1784
- * another round trip — but it can disagree with the server (e.g. `contentHash` matching uses a local
1785
- * approximation when proof data only has inline `content`; the API uses the standard server-side hash).
1786
- *
1787
- * Gate-first verification: checks if wallet has valid proofs satisfying requirements.
1788
- * Returns which requirements are missing/expired.
1789
- *
1790
- * @param {Object} params - Gate check parameters
1791
- * @param {string} params.walletAddress - Target wallet
1792
- * @param {Array<Object>} params.requirements - Array of gate requirements
1793
- * @param {string} params.requirements[].verifierId - Required verifier ID
1794
- * @param {number} [params.requirements[].maxAgeMs] - Max proof age in ms (TTL)
1795
- * @param {boolean} [params.requirements[].optional] - If true, not required for gate satisfaction
1796
- * @param {number} [params.requirements[].minCount] - Minimum proofs needed (default: 1)
1797
- * @param {Object} [params.requirements[].match] - Verifier data match criteria
1798
- * Supports nested fields: 'reference.type', 'reference.id', 'content', 'contentHash', 'input.*', 'license.*'
1799
- * Supports verifier-specific:
1800
- * - NFT/Token: 'contractAddress', 'tokenId', 'chainId', 'ownerAddress', 'minBalance'
1801
- * - DNS: 'domain', 'walletAddress'
1802
- * - Wallet-link: 'primaryWalletAddress', 'secondaryWalletAddress', 'chain', 'signatureMethod'
1803
- * - Contract-ownership: 'contractAddress', 'chainId', 'owner', 'verificationMethod'
1804
- * Note: contentHash matching uses approximation in SDK; for exact SHA-256 matching, use backend API
1805
- * @param {Array} [params.proofs] - Pre-fetched proofs (skip API call)
1806
- * @returns {Promise<Object>} Gate result with satisfied, missing, existing
1807
- *
1808
- * @example
1809
- * // Basic gate check
1810
- * const result = await client.checkGate({
1811
- * walletAddress: '0x...',
1812
- * requirements: [
1813
- * { verifierId: 'nft-ownership', match: { contractAddress: '0x...' } }
1814
- * ]
1815
- * });
1816
- */
1817
1730
  async checkGate(params) {
1818
1731
  const { walletAddress, requirements, proofs: preloadedProofs } = params;
1819
1732
  if (!validateUniversalAddress(walletAddress)) {
@@ -2045,7 +1958,6 @@ ${bytes.length}`;
2045
1958
  ];
2046
1959
  return typeof status === "string" && terminalStates.some((state) => status.includes(state));
2047
1960
  }
2048
- /** SDK logging (opt-in via config.enableLogging) */
2049
1961
  _log(message, data = {}) {
2050
1962
  if (this.config.enableLogging) {
2051
1963
  try {