@neus/sdk 1.0.5 → 1.0.7
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 +5 -25
- package/SECURITY.md +11 -6
- package/cjs/client.cjs +59 -220
- package/cjs/gates.cjs +10 -33
- package/cjs/index.cjs +69 -251
- package/cjs/utils.cjs +0 -6
- package/cli/neus.mjs +100 -15
- package/client.js +1742 -1945
- package/errors.js +0 -34
- package/gates.js +73 -175
- package/index.js +0 -9
- package/package.json +5 -4
- package/types.d.ts +4 -463
- 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 +57 -77
- package/widgets/verify-gate/index.js +0 -4
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
[](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
|
|
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
|
|
|
@@ -31,7 +31,7 @@ npx -y -p @neus/sdk neus auth --access-key <npk_...>
|
|
|
31
31
|
npx -y -p @neus/sdk neus status --json
|
|
32
32
|
```
|
|
33
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.
|
|
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. Use `--client claude`, `--client cursor`, or `--client vscode` when you want to target one editor directly.
|
|
35
35
|
|
|
36
36
|
## Minimal working example
|
|
37
37
|
|
|
@@ -70,7 +70,7 @@ const check = await client.gateCheck({
|
|
|
70
70
|
|
|
71
71
|
## VerifyGate (React)
|
|
72
72
|
|
|
73
|
-
Defaults:
|
|
73
|
+
Defaults: private create (`privacyLevel: 'private'`, `publicDisplay: false`). Set `proofOptions` only when you intentionally need public visibility.
|
|
74
74
|
|
|
75
75
|
```jsx
|
|
76
76
|
import { VerifyGate } from '@neus/sdk/widgets';
|
|
@@ -92,32 +92,12 @@ const client = new NeusClient({
|
|
|
92
92
|
});
|
|
93
93
|
```
|
|
94
94
|
|
|
95
|
-
## Wallet-link
|
|
96
|
-
|
|
97
|
-
For user-facing browser flows, prefer Hosted Verify so the user can select a secondary wallet, sign once, see the linked state, and only then continue to proof creation.
|
|
98
|
-
|
|
99
|
-
Use `client.createWalletLinkData()` only for advanced direct/API flows where your app already controls the secondary-wallet provider:
|
|
100
|
-
|
|
101
|
-
```javascript
|
|
102
|
-
const walletLinkData = await client.createWalletLinkData({
|
|
103
|
-
primaryWalletAddress: '0xprimary...',
|
|
104
|
-
secondaryWalletAddress: '0xsecondary...',
|
|
105
|
-
wallet: window.ethereum,
|
|
106
|
-
relationshipType: 'linked',
|
|
107
|
-
label: 'ops-wallet'
|
|
108
|
-
});
|
|
109
|
-
|
|
110
|
-
await client.verify({
|
|
111
|
-
verifier: 'wallet-link',
|
|
112
|
-
data: walletLinkData
|
|
113
|
-
});
|
|
114
|
-
```
|
|
115
|
-
|
|
116
95
|
## Docs
|
|
117
96
|
|
|
118
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
|
|
119
99
|
- [SDK](https://docs.neus.network/sdks/javascript)
|
|
120
|
-
- [MCP](https://docs.neus.network/mcp/overview)
|
|
100
|
+
- [MCP](https://docs.neus.network/mcp/overview) for IDEs and assistants
|
|
121
101
|
- [Widgets](https://docs.neus.network/widgets/overview)
|
|
122
102
|
- [API](https://docs.neus.network/api/overview)
|
|
123
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
|
|
19
|
+
**`client.verify()`** defaults to **private**.
|
|
20
20
|
|
|
21
|
-
**`VerifyGate`** create mode defaults to **
|
|
21
|
+
**`VerifyGate`** create mode also defaults to **private**.
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
Use public visibility only when you intentionally need proof reuse without owner-authenticated access:
|
|
24
24
|
|
|
25
|
-
|
|
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
|
|
34
|
+
- `privacyLevel` - private by default; switch to public only for intentional public reuse
|
|
30
35
|
- `publicDisplay` - discovery vs unlisted
|
|
31
|
-
- `storeOriginalContent` -
|
|
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",
|
|
@@ -416,6 +411,16 @@ function normalizeWalletLinkRelationshipType(value) {
|
|
|
416
411
|
const normalized = String(value || "").trim().toLowerCase();
|
|
417
412
|
return WALLET_LINK_RELATIONSHIP_TYPES.has(normalized) ? normalized : "linked";
|
|
418
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
|
+
}
|
|
419
424
|
var validateVerifierData = (verifierId, data) => {
|
|
420
425
|
if (!data || typeof data !== "object") {
|
|
421
426
|
return { valid: false, error: "Data object is required" };
|
|
@@ -744,26 +749,49 @@ var NeusClient = class {
|
|
|
744
749
|
if (!wallet) {
|
|
745
750
|
throw new ConfigurationError("No wallet provider available");
|
|
746
751
|
}
|
|
747
|
-
if (wallet.address) {
|
|
748
|
-
|
|
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
|
+
}
|
|
749
759
|
}
|
|
750
760
|
if (wallet.publicKey && typeof wallet.publicKey.toBase58 === "function") {
|
|
751
|
-
|
|
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
|
+
}
|
|
752
766
|
}
|
|
753
767
|
if (typeof wallet.getAddress === "function") {
|
|
754
|
-
const
|
|
755
|
-
|
|
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
|
+
}
|
|
756
775
|
}
|
|
757
776
|
if (wallet.selectedAddress || wallet.request) {
|
|
758
777
|
const provider = wallet;
|
|
759
778
|
if (wallet.selectedAddress) {
|
|
760
|
-
|
|
779
|
+
const s2 = normalizeBrowserSignerString(
|
|
780
|
+
typeof wallet.selectedAddress === "string" ? wallet.selectedAddress : null
|
|
781
|
+
);
|
|
782
|
+
if (s2) {
|
|
783
|
+
return { signerWalletAddress: s2, provider };
|
|
784
|
+
}
|
|
761
785
|
}
|
|
762
786
|
const accounts = await provider.request({ method: "eth_accounts" });
|
|
763
787
|
if (!accounts || accounts.length === 0) {
|
|
764
788
|
throw new ConfigurationError("No wallet accounts available");
|
|
765
789
|
}
|
|
766
|
-
|
|
790
|
+
const s = normalizeBrowserSignerString(accounts[0]);
|
|
791
|
+
if (!s) {
|
|
792
|
+
throw new ConfigurationError("No wallet accounts available");
|
|
793
|
+
}
|
|
794
|
+
return { signerWalletAddress: s, provider };
|
|
767
795
|
}
|
|
768
796
|
throw new ConfigurationError("Invalid wallet provider");
|
|
769
797
|
}
|
|
@@ -894,47 +922,6 @@ var NeusClient = class {
|
|
|
894
922
|
...label ? { label } : {}
|
|
895
923
|
};
|
|
896
924
|
}
|
|
897
|
-
/**
|
|
898
|
-
* Create a verification proof.
|
|
899
|
-
*
|
|
900
|
-
* Supports two paths:
|
|
901
|
-
* - **Auto:** Supply `verifier`, `content`, and/or `data` with an optional
|
|
902
|
-
* `wallet` provider. The SDK performs signing in the client.
|
|
903
|
-
* - **Manual:** Supply pre-signed `verifierIds`, `data`, `walletAddress`,
|
|
904
|
-
* `signature`, and `signedTimestamp`.
|
|
905
|
-
*
|
|
906
|
-
* @param {Object} params - Verification parameters
|
|
907
|
-
* @param {string} [params.verifier] - Verifier ID (auto path, e.g. 'ownership-basic')
|
|
908
|
-
* @param {string} [params.content] - Content to verify (auto path)
|
|
909
|
-
* @param {Object} [params.data] - Structured verification data
|
|
910
|
-
* @param {Object} [params.wallet] - Wallet provider (auto path)
|
|
911
|
-
* @param {Object} [params.options] - Additional options
|
|
912
|
-
* @param {Array<string>} [params.verifierIds] - Array of verifier IDs (manual path)
|
|
913
|
-
* @param {string} [params.walletAddress] - Wallet address that signed the request (manual path)
|
|
914
|
-
* @param {string} [params.signature] - EIP-191 signature (manual path)
|
|
915
|
-
* @param {number} [params.signedTimestamp] - Unix timestamp when signature was created (manual path)
|
|
916
|
-
* @param {number} [params.chainId] - EVM signing-context hint; when omitted, resolved to the NEUS protocol primary chain for signing
|
|
917
|
-
* @returns {Promise<Object>} Verification result with proofId
|
|
918
|
-
*
|
|
919
|
-
* @example
|
|
920
|
-
* // Auto path
|
|
921
|
-
* const proof = await client.verify({
|
|
922
|
-
* verifier: 'ownership-basic',
|
|
923
|
-
* content: 'Hello World',
|
|
924
|
-
* wallet: window.ethereum
|
|
925
|
-
* });
|
|
926
|
-
*
|
|
927
|
-
* @example
|
|
928
|
-
* // Manual path
|
|
929
|
-
* const proof = await client.verify({
|
|
930
|
-
* verifierIds: ['ownership-basic'],
|
|
931
|
-
* data: { content: "My content", owner: walletAddress },
|
|
932
|
-
* walletAddress: '0x...',
|
|
933
|
-
* signature: '0x...',
|
|
934
|
-
* signedTimestamp: Date.now(),
|
|
935
|
-
* options: { targetChains: [421614, 11155111] }
|
|
936
|
-
* });
|
|
937
|
-
*/
|
|
938
925
|
async verify(params) {
|
|
939
926
|
if ((!params?.signature || !params?.walletAddress) && (params?.verifier || params?.content || params?.data)) {
|
|
940
927
|
const { content, verifier = "ownership-basic", data: data2 = null, wallet = null, options: options2 = {} } = params;
|
|
@@ -976,11 +963,16 @@ var NeusClient = class {
|
|
|
976
963
|
}
|
|
977
964
|
let walletAddress2, provider;
|
|
978
965
|
if (wallet) {
|
|
979
|
-
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);
|
|
980
967
|
provider = wallet.provider || wallet;
|
|
981
968
|
if (!walletAddress2 && provider && typeof provider.request === "function") {
|
|
982
|
-
|
|
983
|
-
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
|
+
}
|
|
984
976
|
}
|
|
985
977
|
} else {
|
|
986
978
|
if (typeof window === "undefined" || !window.ethereum) {
|
|
@@ -991,6 +983,15 @@ var NeusClient = class {
|
|
|
991
983
|
const accounts = await provider.request({ method: "eth_accounts" });
|
|
992
984
|
walletAddress2 = accounts[0];
|
|
993
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
|
+
}
|
|
994
995
|
let verificationData;
|
|
995
996
|
if (verifier === "ownership-basic") {
|
|
996
997
|
if (data2 && typeof data2 === "object") {
|
|
@@ -1142,8 +1143,6 @@ var NeusClient = class {
|
|
|
1142
1143
|
verificationData = {
|
|
1143
1144
|
walletAddress: data2?.walletAddress || walletAddress2,
|
|
1144
1145
|
...data2?.provider && { provider: data2.provider },
|
|
1145
|
-
// Mainnet-first semantics: if caller doesn't provide chainId, default to Ethereum mainnet (1).
|
|
1146
|
-
// This avoids accidental testnet semantics for risk providers.
|
|
1147
1146
|
chainId: typeof data2?.chainId === "number" && Number.isFinite(data2.chainId) ? data2.chainId : 1,
|
|
1148
1147
|
...data2?.includeDetails !== void 0 && { includeDetails: data2.includeDetails }
|
|
1149
1148
|
};
|
|
@@ -1165,7 +1164,6 @@ var NeusClient = class {
|
|
|
1165
1164
|
data: verificationData,
|
|
1166
1165
|
verifierIds: verifierIds2,
|
|
1167
1166
|
chainId: this._getHubChainId()
|
|
1168
|
-
// Protocol-managed chain
|
|
1169
1167
|
});
|
|
1170
1168
|
let signature2;
|
|
1171
1169
|
try {
|
|
@@ -1201,6 +1199,7 @@ var NeusClient = class {
|
|
|
1201
1199
|
const hexMsg = toHexUtf82(message);
|
|
1202
1200
|
signature2 = await provider.request({ method: "personal_sign", params: [hexMsg, walletAddress2] });
|
|
1203
1201
|
} catch (e) {
|
|
1202
|
+
void e;
|
|
1204
1203
|
}
|
|
1205
1204
|
}
|
|
1206
1205
|
if (!signature2) {
|
|
@@ -1310,7 +1309,6 @@ ${bytes.length}`;
|
|
|
1310
1309
|
const optionsPayload = {
|
|
1311
1310
|
...options && typeof options === "object" ? options : {},
|
|
1312
1311
|
targetChains: Array.isArray(options?.targetChains) ? options.targetChains : [],
|
|
1313
|
-
// Privacy and storage options (defaults)
|
|
1314
1312
|
privacyLevel: options?.privacyLevel || "private",
|
|
1315
1313
|
publicDisplay: options?.publicDisplay || false,
|
|
1316
1314
|
storeOriginalContent: typeof options?.storeOriginalContent === "boolean" ? options.storeOriginalContent : true
|
|
@@ -1333,16 +1331,6 @@ ${bytes.length}`;
|
|
|
1333
1331
|
}
|
|
1334
1332
|
return this._formatResponse(response);
|
|
1335
1333
|
}
|
|
1336
|
-
/**
|
|
1337
|
-
* Get proof record by proof receipt id.
|
|
1338
|
-
*
|
|
1339
|
-
* @param {string} proofId - Proof receipt ID (0x + 64 hex).
|
|
1340
|
-
* @returns {Promise<Object>} Proof record and verification state
|
|
1341
|
-
*
|
|
1342
|
-
* @example
|
|
1343
|
-
* const result = await client.getProof('0x...');
|
|
1344
|
-
* console.log('Status:', result.status);
|
|
1345
|
-
*/
|
|
1346
1334
|
async getProof(proofId) {
|
|
1347
1335
|
if (!proofId || typeof proofId !== "string") {
|
|
1348
1336
|
throw new ValidationError("proofId is required");
|
|
@@ -1353,16 +1341,6 @@ ${bytes.length}`;
|
|
|
1353
1341
|
}
|
|
1354
1342
|
return this._formatResponse(response);
|
|
1355
1343
|
}
|
|
1356
|
-
/**
|
|
1357
|
-
* Get private proof record with wallet signature
|
|
1358
|
-
*
|
|
1359
|
-
* @param {string} proofId - Proof receipt ID.
|
|
1360
|
-
* @param {Object} wallet - Wallet provider (window.ethereum or ethers Wallet)
|
|
1361
|
-
* @returns {Promise<Object>} Private proof record and verification state
|
|
1362
|
-
*
|
|
1363
|
-
* @example
|
|
1364
|
-
* const privateData = await client.getPrivateProof(proofId, window.ethereum);
|
|
1365
|
-
*/
|
|
1366
1344
|
async getPrivateProof(proofId, wallet = null) {
|
|
1367
1345
|
if (!proofId || typeof proofId !== "string") {
|
|
1368
1346
|
throw new ValidationError("proofId is required");
|
|
@@ -1430,11 +1408,6 @@ ${bytes.length}`;
|
|
|
1430
1408
|
}
|
|
1431
1409
|
return this._formatResponse(response);
|
|
1432
1410
|
}
|
|
1433
|
-
/**
|
|
1434
|
-
* Check API health
|
|
1435
|
-
*
|
|
1436
|
-
* @returns {Promise<boolean>} True if API is healthy
|
|
1437
|
-
*/
|
|
1438
1411
|
async isHealthy() {
|
|
1439
1412
|
try {
|
|
1440
1413
|
const response = await this._makeRequest("GET", "/api/v1/health");
|
|
@@ -1443,19 +1416,10 @@ ${bytes.length}`;
|
|
|
1443
1416
|
return false;
|
|
1444
1417
|
}
|
|
1445
1418
|
}
|
|
1446
|
-
/**
|
|
1447
|
-
* List available verifiers
|
|
1448
|
-
*
|
|
1449
|
-
* @returns {Promise<string[]>} Array of verifier IDs
|
|
1450
|
-
*/
|
|
1451
1419
|
async getVerifiers() {
|
|
1452
1420
|
const catalog = await this.getVerifierCatalog();
|
|
1453
1421
|
return Array.isArray(catalog?.data) ? catalog.data : [];
|
|
1454
1422
|
}
|
|
1455
|
-
/**
|
|
1456
|
-
* Get the public verifier catalog with per-verifier capabilities.
|
|
1457
|
-
* @returns {Promise<{data: string[], metadata: Record<string, { supportsDirectApi?: boolean }>, meta?: object}>}
|
|
1458
|
-
*/
|
|
1459
1423
|
async getVerifierCatalog() {
|
|
1460
1424
|
const response = await this._makeRequest("GET", "/api/v1/verification/verifiers");
|
|
1461
1425
|
if (!response.success) {
|
|
@@ -1467,31 +1431,6 @@ ${bytes.length}`;
|
|
|
1467
1431
|
meta: response.meta && typeof response.meta === "object" && !Array.isArray(response.meta) ? response.meta : {}
|
|
1468
1432
|
};
|
|
1469
1433
|
}
|
|
1470
|
-
/**
|
|
1471
|
-
* POLL PROOF STATUS - Wait for verification completion
|
|
1472
|
-
*
|
|
1473
|
-
* Polls the verification status until it reaches a terminal state (completed or failed).
|
|
1474
|
-
* Useful for providing real-time feedback to users during verification.
|
|
1475
|
-
*
|
|
1476
|
-
* @param {string} proofId - Proof ID to poll.
|
|
1477
|
-
* @param {Object} [options] - Polling options
|
|
1478
|
-
* @param {number} [options.interval=5000] - Polling interval in ms
|
|
1479
|
-
* @param {number} [options.timeout=120000] - Total timeout in ms
|
|
1480
|
-
* @param {Function} [options.onProgress] - Progress callback function
|
|
1481
|
-
* @returns {Promise<Object>} Final verification status
|
|
1482
|
-
*
|
|
1483
|
-
* @example
|
|
1484
|
-
* const finalStatus = await client.pollProofStatus(proofId, {
|
|
1485
|
-
* interval: 3000,
|
|
1486
|
-
* timeout: 60000,
|
|
1487
|
-
* onProgress: (status) => {
|
|
1488
|
-
* console.log('Current status:', status.status);
|
|
1489
|
-
* if (status.crosschain) {
|
|
1490
|
-
* console.log(`Cross-chain: ${status.crosschain.finalized}/${status.crosschain.totalChains}`);
|
|
1491
|
-
* }
|
|
1492
|
-
* }
|
|
1493
|
-
* });
|
|
1494
|
-
*/
|
|
1495
1434
|
async pollProofStatus(proofId, options = {}) {
|
|
1496
1435
|
const {
|
|
1497
1436
|
interval = 5e3,
|
|
@@ -1536,11 +1475,6 @@ ${bytes.length}`;
|
|
|
1536
1475
|
}
|
|
1537
1476
|
throw new NetworkError(`Polling timeout after ${timeout}ms`, "POLLING_TIMEOUT");
|
|
1538
1477
|
}
|
|
1539
|
-
/**
|
|
1540
|
-
* DETECT CHAIN ID - Get current wallet chain
|
|
1541
|
-
*
|
|
1542
|
-
* @returns {Promise<number>} Current chain ID
|
|
1543
|
-
*/
|
|
1544
1478
|
async detectChainId() {
|
|
1545
1479
|
if (typeof window === "undefined" || !window.ethereum) {
|
|
1546
1480
|
throw new ConfigurationError("No Web3 wallet detected");
|
|
@@ -1552,7 +1486,6 @@ ${bytes.length}`;
|
|
|
1552
1486
|
throw new NetworkError(`Failed to detect chain ID: ${error.message}`);
|
|
1553
1487
|
}
|
|
1554
1488
|
}
|
|
1555
|
-
/** Revoke your own proof (owner-signed) */
|
|
1556
1489
|
async revokeOwnProof(proofId, wallet) {
|
|
1557
1490
|
if (!proofId || typeof proofId !== "string") {
|
|
1558
1491
|
throw new ValidationError("proofId is required");
|
|
@@ -1603,22 +1536,6 @@ ${bytes.length}`;
|
|
|
1603
1536
|
}
|
|
1604
1537
|
return true;
|
|
1605
1538
|
}
|
|
1606
|
-
/**
|
|
1607
|
-
* GET PROOFS BY WALLET - Fetch proofs for a wallet address
|
|
1608
|
-
*
|
|
1609
|
-
* @param {string} walletAddress - Wallet identity (EVM/Solana/DID)
|
|
1610
|
-
* @param {Object} [options] - Filter options
|
|
1611
|
-
* @param {number} [options.limit] - Max results (default: 50; higher limits require owner access)
|
|
1612
|
-
* @param {number} [options.offset] - Pagination offset (default: 0)
|
|
1613
|
-
* @param {string} [options.qHash] - Filter to single proof by qHash
|
|
1614
|
-
* @returns {Promise<Object>} Proofs result
|
|
1615
|
-
*
|
|
1616
|
-
* @example
|
|
1617
|
-
* const result = await client.getProofsByWallet('0x...', {
|
|
1618
|
-
* limit: 50,
|
|
1619
|
-
* offset: 0
|
|
1620
|
-
* });
|
|
1621
|
-
*/
|
|
1622
1539
|
async getProofsByWallet(walletAddress, options = {}) {
|
|
1623
1540
|
if (!walletAddress || typeof walletAddress !== "string") {
|
|
1624
1541
|
throw new ValidationError("walletAddress is required");
|
|
@@ -1646,18 +1563,6 @@ ${bytes.length}`;
|
|
|
1646
1563
|
nextOffset: response.data?.nextOffset ?? null
|
|
1647
1564
|
};
|
|
1648
1565
|
}
|
|
1649
|
-
/**
|
|
1650
|
-
* Get proofs by wallet (owner access)
|
|
1651
|
-
*
|
|
1652
|
-
* Signs an owner-access intent and requests private proofs via signature headers.
|
|
1653
|
-
*
|
|
1654
|
-
* @param {string} walletAddress - Wallet identity (EVM/Solana/DID)
|
|
1655
|
-
* @param {Object} [options]
|
|
1656
|
-
* @param {number} [options.limit] - Max results (server enforces caps)
|
|
1657
|
-
* @param {number} [options.offset] - Pagination offset
|
|
1658
|
-
* @param {string} [options.qHash] - Filter to single proof by qHash
|
|
1659
|
-
* @param {Object} [wallet] - Optional injected wallet/provider (MetaMask/ethers Wallet)
|
|
1660
|
-
*/
|
|
1661
1566
|
async getPrivateProofsByWallet(walletAddress, options = {}, wallet = null) {
|
|
1662
1567
|
if (!walletAddress || typeof walletAddress !== "string") {
|
|
1663
1568
|
throw new ValidationError("walletAddress is required");
|
|
@@ -1728,31 +1633,6 @@ ${bytes.length}`;
|
|
|
1728
1633
|
nextOffset: response.data?.nextOffset ?? null
|
|
1729
1634
|
};
|
|
1730
1635
|
}
|
|
1731
|
-
/**
|
|
1732
|
-
* Gate check (HTTP API) — minimal eligibility response.
|
|
1733
|
-
*
|
|
1734
|
-
* Calls the gate endpoint and returns a **minimal** yes/no response.
|
|
1735
|
-
* By default this checks **public + unlisted** proofs.
|
|
1736
|
-
*
|
|
1737
|
-
* When `includePrivate=true`, this can perform owner-signed private checks
|
|
1738
|
-
* (no full proof payloads returned) by providing a wallet/provider.
|
|
1739
|
-
*
|
|
1740
|
-
* Prefer this over `checkGate()` when you need the smallest, most stable
|
|
1741
|
-
* response shape and do not need full proof payloads.
|
|
1742
|
-
*
|
|
1743
|
-
* @param {Object} params - Gate check query params
|
|
1744
|
-
* @param {string} params.address - Wallet identity to check (EVM/Solana/DID)
|
|
1745
|
-
* @param {Array<string>|string} [params.verifierIds] - Verifier IDs to match (array or comma-separated)
|
|
1746
|
-
* @param {boolean} [params.requireAll] - Require all verifierIds on a single proof
|
|
1747
|
-
* @param {number} [params.minCount] - Minimum number of matching proofs
|
|
1748
|
-
* @param {number} [params.sinceDays] - Optional time window in days
|
|
1749
|
-
* @param {number} [params.since] - Optional unix timestamp in ms (lower bound)
|
|
1750
|
-
* @param {number} [params.limit] - Max rows to scan (server may clamp)
|
|
1751
|
-
* @param {boolean} [params.includePrivate] - Include private proofs for owner-authenticated requests
|
|
1752
|
-
* @param {boolean} [params.includeQHashes] - Include matched qHashes in response (minimal IDs only)
|
|
1753
|
-
* @param {Object} [params.wallet] - Optional wallet/provider used to sign includePrivate owner checks
|
|
1754
|
-
* @returns {Promise<Object>} API response ({ success, data })
|
|
1755
|
-
*/
|
|
1756
1636
|
async gateCheck(params = {}) {
|
|
1757
1637
|
const address = (params.address || "").toString();
|
|
1758
1638
|
if (!validateUniversalAddress(address, params.chain)) {
|
|
@@ -1824,8 +1704,7 @@ ${bytes.length}`;
|
|
|
1824
1704
|
});
|
|
1825
1705
|
}
|
|
1826
1706
|
}
|
|
1827
|
-
if (
|
|
1828
|
-
} else {
|
|
1707
|
+
if (auth) {
|
|
1829
1708
|
const normalizedAuthWallet = this._normalizeIdentity(auth.walletAddress);
|
|
1830
1709
|
const normalizedAddress = this._normalizeIdentity(address);
|
|
1831
1710
|
if (!normalizedAuthWallet || normalizedAuthWallet !== normalizedAddress) {
|
|
@@ -1848,45 +1727,6 @@ ${bytes.length}`;
|
|
|
1848
1727
|
}
|
|
1849
1728
|
return response;
|
|
1850
1729
|
}
|
|
1851
|
-
/**
|
|
1852
|
-
* CHECK GATE — Local preview against proofs you already have in memory or from `getProofsByWallet`.
|
|
1853
|
-
*
|
|
1854
|
-
* **Not authoritative for access control.** For production allow/deny, use {@link NeusClient#gateCheck}
|
|
1855
|
-
* (`GET /api/v1/proofs/check`), which applies the same rules as the NEUS API. This method is useful for
|
|
1856
|
-
* UI previews, offline-ish flows, or when you already fetched proofs and want a quick match without
|
|
1857
|
-
* another round trip — but it can disagree with the server (e.g. `contentHash` matching uses a local
|
|
1858
|
-
* approximation when proof data only has inline `content`; the API uses the standard server-side hash).
|
|
1859
|
-
*
|
|
1860
|
-
* Gate-first verification: checks if wallet has valid proofs satisfying requirements.
|
|
1861
|
-
* Returns which requirements are missing/expired.
|
|
1862
|
-
*
|
|
1863
|
-
* @param {Object} params - Gate check parameters
|
|
1864
|
-
* @param {string} params.walletAddress - Target wallet
|
|
1865
|
-
* @param {Array<Object>} params.requirements - Array of gate requirements
|
|
1866
|
-
* @param {string} params.requirements[].verifierId - Required verifier ID
|
|
1867
|
-
* @param {number} [params.requirements[].maxAgeMs] - Max proof age in ms (TTL)
|
|
1868
|
-
* @param {boolean} [params.requirements[].optional] - If true, not required for gate satisfaction
|
|
1869
|
-
* @param {number} [params.requirements[].minCount] - Minimum proofs needed (default: 1)
|
|
1870
|
-
* @param {Object} [params.requirements[].match] - Verifier data match criteria
|
|
1871
|
-
* Supports nested fields: 'reference.type', 'reference.id', 'content', 'contentHash', 'input.*', 'license.*'
|
|
1872
|
-
* Supports verifier-specific:
|
|
1873
|
-
* - NFT/Token: 'contractAddress', 'tokenId', 'chainId', 'ownerAddress', 'minBalance'
|
|
1874
|
-
* - DNS: 'domain', 'walletAddress'
|
|
1875
|
-
* - Wallet-link: 'primaryWalletAddress', 'secondaryWalletAddress', 'chain', 'signatureMethod'
|
|
1876
|
-
* - Contract-ownership: 'contractAddress', 'chainId', 'owner', 'verificationMethod'
|
|
1877
|
-
* Note: contentHash matching uses approximation in SDK; for exact SHA-256 matching, use backend API
|
|
1878
|
-
* @param {Array} [params.proofs] - Pre-fetched proofs (skip API call)
|
|
1879
|
-
* @returns {Promise<Object>} Gate result with satisfied, missing, existing
|
|
1880
|
-
*
|
|
1881
|
-
* @example
|
|
1882
|
-
* // Basic gate check
|
|
1883
|
-
* const result = await client.checkGate({
|
|
1884
|
-
* walletAddress: '0x...',
|
|
1885
|
-
* requirements: [
|
|
1886
|
-
* { verifierId: 'nft-ownership', match: { contractAddress: '0x...' } }
|
|
1887
|
-
* ]
|
|
1888
|
-
* });
|
|
1889
|
-
*/
|
|
1890
1730
|
async checkGate(params) {
|
|
1891
1731
|
const { walletAddress, requirements, proofs: preloadedProofs } = params;
|
|
1892
1732
|
if (!validateUniversalAddress(walletAddress)) {
|
|
@@ -2118,7 +1958,6 @@ ${bytes.length}`;
|
|
|
2118
1958
|
];
|
|
2119
1959
|
return typeof status === "string" && terminalStates.some((state) => status.includes(state));
|
|
2120
1960
|
}
|
|
2121
|
-
/** SDK logging (opt-in via config.enableLogging) */
|
|
2122
1961
|
_log(message, data = {}) {
|
|
2123
1962
|
if (this.config.enableLogging) {
|
|
2124
1963
|
try {
|
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
|
};
|