@neus/sdk 1.0.8 → 1.0.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +139 -46
- package/SECURITY.md +1 -1
- package/cjs/client.cjs +40 -44
- package/cjs/index.cjs +40 -44
- package/client.js +36 -53
- package/package.json +3 -4
- package/types.d.ts +13 -24
- package/widgets/README.md +1 -1
- package/widgets/verify-gate/dist/ProofBadge.js +41 -37
- package/widgets/verify-gate/dist/VerifyGate.js +54 -49
package/README.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# @neus/sdk
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Create, check, and reuse NEUS trust receipts from apps.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
NEUS turns signed claims, ownership checks, account links, access rules, and verification results into portable receipts your app can store, display, and check later.
|
|
6
6
|
|
|
7
7
|
## Install
|
|
8
8
|
|
|
@@ -10,75 +10,168 @@
|
|
|
10
10
|
npm install @neus/sdk
|
|
11
11
|
```
|
|
12
12
|
|
|
13
|
-
##
|
|
13
|
+
## What you can build
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
- Issue a proof that a user, wallet, org, app, file, release, profile, or result belongs to someone
|
|
16
|
+
- Store the returned `qHash` as a durable trust receipt ID
|
|
17
|
+
- Check receipts later for access, eligibility, provenance, or display
|
|
18
|
+
- Add proof-gated UX with React widgets
|
|
19
|
+
- Connect IDEs and agents through optional MCP
|
|
17
20
|
|
|
18
|
-
|
|
21
|
+
## Fastest path: Hosted Verify
|
|
19
22
|
|
|
20
|
-
|
|
21
|
-
verifier: 'ownership-basic',
|
|
22
|
-
content: 'Hello NEUS',
|
|
23
|
-
wallet: window.ethereum,
|
|
24
|
-
});
|
|
23
|
+
Use Hosted Verify when you want NEUS to handle the signing/verification flow outside your app UI.
|
|
25
24
|
|
|
26
|
-
|
|
25
|
+
```js
|
|
26
|
+
import { getHostedCheckoutUrl } from '@neus/sdk';
|
|
27
27
|
|
|
28
|
-
const
|
|
29
|
-
|
|
30
|
-
|
|
28
|
+
const url = getHostedCheckoutUrl({
|
|
29
|
+
verifiers: ['ownership-basic'],
|
|
30
|
+
returnUrl: 'https://yourapp.com/neus/callback'
|
|
31
31
|
});
|
|
32
|
+
|
|
33
|
+
window.location.assign(url);
|
|
32
34
|
```
|
|
33
35
|
|
|
34
|
-
|
|
36
|
+
After completion, NEUS redirects back with a `qHash`.
|
|
35
37
|
|
|
36
|
-
|
|
38
|
+
Store that `qHash` in your database next to your user, workspace, project, claim, listing, or record.
|
|
39
|
+
|
|
40
|
+
## Create a signed receipt directly
|
|
41
|
+
|
|
42
|
+
Use this when your app already controls the signing flow.
|
|
43
|
+
|
|
44
|
+
```js
|
|
45
|
+
import { NeusClient } from '@neus/sdk';
|
|
37
46
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
| `client.getProof()` | Fetch by `proofId` |
|
|
42
|
-
| `client.pollProofStatus()` | Wait for async completion |
|
|
43
|
-
| `client.gateCheck()` | **Server eligibility** (use for real gates) |
|
|
44
|
-
| `client.checkGate()` | Local preview only |
|
|
45
|
-
| `getHostedCheckoutUrl()` | Hosted verify URL |
|
|
46
|
-
| `client.createWalletLinkData()` | Build advanced direct wallet-link payload |
|
|
47
|
+
const client = new NeusClient({
|
|
48
|
+
appId: 'your-app-id'
|
|
49
|
+
});
|
|
47
50
|
|
|
48
|
-
|
|
51
|
+
const proof = await client.verify({
|
|
52
|
+
verifier: 'ownership-basic',
|
|
53
|
+
data: {
|
|
54
|
+
owner: '0x...',
|
|
55
|
+
contentType: 'application/json',
|
|
56
|
+
content: JSON.stringify({
|
|
57
|
+
title: 'Verified claim',
|
|
58
|
+
type: 'project-update',
|
|
59
|
+
summary: 'Public summary of what is being proven.'
|
|
60
|
+
}),
|
|
61
|
+
reference: {
|
|
62
|
+
type: 'url',
|
|
63
|
+
id: 'https://example.com/source',
|
|
64
|
+
title: 'Source record'
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
wallet: window.ethereum
|
|
68
|
+
});
|
|
49
69
|
|
|
50
|
-
|
|
70
|
+
console.log(proof.qHash);
|
|
71
|
+
console.log(proof.proofUrl);
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## React widget
|
|
75
|
+
|
|
76
|
+
Use `VerifyGate` when you want a drop-in verification flow in React.
|
|
51
77
|
|
|
52
78
|
```jsx
|
|
53
79
|
import { VerifyGate } from '@neus/sdk/widgets';
|
|
54
80
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
81
|
+
export function Page() {
|
|
82
|
+
return (
|
|
83
|
+
<VerifyGate
|
|
84
|
+
appId="your-app-id"
|
|
85
|
+
requiredVerifiers={['ownership-basic']}
|
|
86
|
+
verifierData={{
|
|
87
|
+
'ownership-basic': {
|
|
88
|
+
owner: '0x...',
|
|
89
|
+
contentType: 'application/json',
|
|
90
|
+
content: JSON.stringify({
|
|
91
|
+
title: 'Verified claim',
|
|
92
|
+
summary: 'Public summary of what is being proven.'
|
|
93
|
+
}),
|
|
94
|
+
reference: {
|
|
95
|
+
type: 'url',
|
|
96
|
+
id: 'https://example.com/source'
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}}
|
|
100
|
+
onVerified={(result) => {
|
|
101
|
+
console.log(result.qHash || result.qHashes);
|
|
102
|
+
}}
|
|
103
|
+
/>
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## Check receipts
|
|
109
|
+
|
|
110
|
+
Use `gateCheck` from trusted server code when you need allow/deny or eligibility checks.
|
|
111
|
+
|
|
112
|
+
```js
|
|
113
|
+
import { NeusClient } from '@neus/sdk';
|
|
114
|
+
|
|
115
|
+
const client = new NeusClient({
|
|
116
|
+
appId: 'your-app-id'
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
const result = await client.gateCheck({
|
|
120
|
+
address: '0x...',
|
|
121
|
+
verifierIds: ['ownership-basic']
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
if (!result.data?.eligible) {
|
|
125
|
+
throw new Error('Access denied');
|
|
126
|
+
}
|
|
58
127
|
```
|
|
59
128
|
|
|
60
|
-
|
|
129
|
+
Access keys are only for trusted server, IDE, or agent environments. Never ship access keys in browser code.
|
|
130
|
+
|
|
131
|
+
## Core methods
|
|
132
|
+
|
|
133
|
+
| Method | Use it for |
|
|
134
|
+
| ------------------------------- | ------------------------------------------- |
|
|
135
|
+
| `getHostedCheckoutUrl()` | Send a user to Hosted Verify |
|
|
136
|
+
| `client.verify()` | Create a proof |
|
|
137
|
+
| `client.getProof()` | Fetch a proof by `qHash` |
|
|
138
|
+
| `client.pollProofStatus()` | Wait for async completion |
|
|
139
|
+
| `client.gateCheck()` | Server-side eligibility checks |
|
|
140
|
+
| `client.checkGate()` | Local preview against already-loaded proofs |
|
|
141
|
+
| `client.createWalletLinkData()` | Advanced wallet-link payloads |
|
|
61
142
|
|
|
62
|
-
##
|
|
143
|
+
## Configuration
|
|
63
144
|
|
|
64
|
-
```
|
|
145
|
+
```js
|
|
65
146
|
const client = new NeusClient({
|
|
66
147
|
apiUrl: 'https://api.neus.network',
|
|
67
|
-
appId: '
|
|
68
|
-
timeout: 30000
|
|
148
|
+
appId: 'your-app-id',
|
|
149
|
+
timeout: 30000
|
|
69
150
|
});
|
|
70
151
|
```
|
|
71
152
|
|
|
72
|
-
|
|
153
|
+
`appId` is public attribution for your app.
|
|
154
|
+
`apiKey` / `npk_*` is optional and server-side only.
|
|
155
|
+
|
|
156
|
+
## Optional MCP setup
|
|
73
157
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
-
|
|
78
|
-
|
|
79
|
-
- [API](https://docs.neus.network/api/overview)
|
|
80
|
-
- [Hosted Verify](https://docs.neus.network/cookbook/auth-hosted-verify)
|
|
158
|
+
Use MCP when you want IDEs, assistants, or agents to inspect receipts, check proof state, or work with NEUS tools.
|
|
159
|
+
|
|
160
|
+
```bash
|
|
161
|
+
npx -y -p @neus/sdk neus init
|
|
162
|
+
```
|
|
81
163
|
|
|
82
|
-
|
|
164
|
+
Add account-aware/private access only when needed:
|
|
165
|
+
|
|
166
|
+
```bash
|
|
167
|
+
npx -y -p @neus/sdk neus auth --access-key <npk_...>
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
## Docs
|
|
83
171
|
|
|
84
|
-
|
|
172
|
+
- Quickstart: https://docs.neus.network/quickstart
|
|
173
|
+
- JavaScript SDK: https://docs.neus.network/sdks/javascript
|
|
174
|
+
- Ownership Basic: https://docs.neus.network/verification/ownership-basic
|
|
175
|
+
- Widgets: https://docs.neus.network/widgets/overview
|
|
176
|
+
- MCP: https://docs.neus.network/mcp/overview
|
|
177
|
+
- API: https://docs.neus.network/api/overview
|
package/SECURITY.md
CHANGED
|
@@ -5,7 +5,7 @@ Treat **wallet signatures** and **API keys** as secrets. Do not log them, expose
|
|
|
5
5
|
## Authentication model
|
|
6
6
|
|
|
7
7
|
- **Verification requests** are authenticated with a wallet signature over the **CAIP-380 Portable Proof** six-line signing string. Never roll your own message format in production—use the SDK or the hosted preparation step documented for HTTP integrations.
|
|
8
|
-
- **Proof lookups by `
|
|
8
|
+
- **Proof lookups by `qHash`** are safe for public proofs. Private proofs return a minimal payload unless the caller proves ownership (authenticated owner or signed request).
|
|
9
9
|
- **Owner-only reads** of private proof payloads require an extra owner-signed request. The SDK attaches the required signed headers for you.
|
|
10
10
|
|
|
11
11
|
## Do not
|
package/cjs/client.cjs
CHANGED
|
@@ -1225,19 +1225,15 @@ ${bytes.length}`;
|
|
|
1225
1225
|
for (let i = 0; i < full.length; i++) payloadHex += full[i].toString(16).padStart(2, "0");
|
|
1226
1226
|
try {
|
|
1227
1227
|
if (typeof window !== "undefined") window.__NEUS_ALLOW_ETH_SIGN__ = true;
|
|
1228
|
-
|
|
1229
|
-
}
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1228
|
+
signature2 = await provider.request({ method: "eth_sign", params: [walletAddress2, payloadHex], neusAllowEthSign: true });
|
|
1229
|
+
} finally {
|
|
1230
|
+
try {
|
|
1231
|
+
if (typeof window !== "undefined") delete window.__NEUS_ALLOW_ETH_SIGN__;
|
|
1232
|
+
} catch {
|
|
1233
|
+
}
|
|
1234
1234
|
}
|
|
1235
1235
|
} catch (fallbackErr) {
|
|
1236
1236
|
this._log("eth_sign fallback failed", { message: fallbackErr?.message || String(fallbackErr) });
|
|
1237
|
-
try {
|
|
1238
|
-
if (typeof window !== "undefined") delete window.__NEUS_ALLOW_ETH_SIGN__;
|
|
1239
|
-
} catch {
|
|
1240
|
-
}
|
|
1241
1237
|
throw e;
|
|
1242
1238
|
}
|
|
1243
1239
|
} else if (needsHex) {
|
|
@@ -1331,19 +1327,21 @@ ${bytes.length}`;
|
|
|
1331
1327
|
}
|
|
1332
1328
|
return this._formatResponse(response);
|
|
1333
1329
|
}
|
|
1334
|
-
async getProof(
|
|
1335
|
-
|
|
1336
|
-
|
|
1330
|
+
async getProof(qHash) {
|
|
1331
|
+
const resolvedQHash = qHash;
|
|
1332
|
+
if (!resolvedQHash || typeof resolvedQHash !== "string") {
|
|
1333
|
+
throw new ValidationError("qHash is required");
|
|
1337
1334
|
}
|
|
1338
|
-
const response = await this._makeRequest("GET", `/api/v1/proofs/${
|
|
1335
|
+
const response = await this._makeRequest("GET", `/api/v1/proofs/${resolvedQHash}`);
|
|
1339
1336
|
if (!response.success) {
|
|
1340
1337
|
throw new ApiError(`Failed to get proof: ${response.error?.message || "Unknown error"}`, response.error);
|
|
1341
1338
|
}
|
|
1342
1339
|
return this._formatResponse(response);
|
|
1343
1340
|
}
|
|
1344
|
-
async getPrivateProof(
|
|
1345
|
-
|
|
1346
|
-
|
|
1341
|
+
async getPrivateProof(qHash, wallet = null) {
|
|
1342
|
+
const resolvedQHash = qHash;
|
|
1343
|
+
if (!resolvedQHash || typeof resolvedQHash !== "string") {
|
|
1344
|
+
throw new ValidationError("qHash is required");
|
|
1347
1345
|
}
|
|
1348
1346
|
const isPreSignedAuth = wallet && typeof wallet === "object" && typeof wallet.walletAddress === "string" && typeof wallet.signature === "string" && typeof wallet.signedTimestamp === "number";
|
|
1349
1347
|
if (isPreSignedAuth) {
|
|
@@ -1355,7 +1353,7 @@ ${bytes.length}`;
|
|
|
1355
1353
|
...typeof auth.chain === "string" && auth.chain.trim() ? { "x-chain": auth.chain.trim() } : {},
|
|
1356
1354
|
...typeof auth.signatureMethod === "string" && auth.signatureMethod.trim() ? { "x-signature-method": auth.signatureMethod.trim() } : {}
|
|
1357
1355
|
};
|
|
1358
|
-
const response2 = await this._makeRequest("GET", `/api/v1/proofs/${
|
|
1356
|
+
const response2 = await this._makeRequest("GET", `/api/v1/proofs/${resolvedQHash}`, null, headers);
|
|
1359
1357
|
if (!response2.success) {
|
|
1360
1358
|
throw new ApiError(
|
|
1361
1359
|
`Failed to access private proof: ${response2.error?.message || "Unauthorized"}`,
|
|
@@ -1376,7 +1374,7 @@ ${bytes.length}`;
|
|
|
1376
1374
|
const message = constructVerificationMessage({
|
|
1377
1375
|
walletAddress,
|
|
1378
1376
|
signedTimestamp,
|
|
1379
|
-
data: { action: "access_private_proof", qHash:
|
|
1377
|
+
data: { action: "access_private_proof", qHash: resolvedQHash },
|
|
1380
1378
|
verifierIds: ["ownership-basic"],
|
|
1381
1379
|
...signerIsEvm ? { chainId: this._getHubChainId() } : { chain }
|
|
1382
1380
|
});
|
|
@@ -1394,7 +1392,7 @@ ${bytes.length}`;
|
|
|
1394
1392
|
}
|
|
1395
1393
|
throw new ValidationError(`Failed to sign message: ${error.message}`);
|
|
1396
1394
|
}
|
|
1397
|
-
const response = await this._makeRequest("GET", `/api/v1/proofs/${
|
|
1395
|
+
const response = await this._makeRequest("GET", `/api/v1/proofs/${resolvedQHash}`, null, {
|
|
1398
1396
|
"x-wallet-address": walletAddress,
|
|
1399
1397
|
"x-signature": signature,
|
|
1400
1398
|
"x-signed-timestamp": signedTimestamp.toString(),
|
|
@@ -1431,20 +1429,21 @@ ${bytes.length}`;
|
|
|
1431
1429
|
meta: response.meta && typeof response.meta === "object" && !Array.isArray(response.meta) ? response.meta : {}
|
|
1432
1430
|
};
|
|
1433
1431
|
}
|
|
1434
|
-
async pollProofStatus(
|
|
1432
|
+
async pollProofStatus(qHash, options = {}) {
|
|
1433
|
+
const resolvedQHash = qHash;
|
|
1435
1434
|
const {
|
|
1436
1435
|
interval = 5e3,
|
|
1437
1436
|
timeout = 12e4,
|
|
1438
1437
|
onProgress
|
|
1439
1438
|
} = options;
|
|
1440
|
-
if (!
|
|
1441
|
-
throw new ValidationError("
|
|
1439
|
+
if (!resolvedQHash || typeof resolvedQHash !== "string") {
|
|
1440
|
+
throw new ValidationError("qHash is required");
|
|
1442
1441
|
}
|
|
1443
1442
|
const startTime = Date.now();
|
|
1444
1443
|
let consecutiveRateLimits = 0;
|
|
1445
1444
|
while (Date.now() - startTime < timeout) {
|
|
1446
1445
|
try {
|
|
1447
|
-
const status = await this.getProof(
|
|
1446
|
+
const status = await this.getProof(resolvedQHash);
|
|
1448
1447
|
consecutiveRateLimits = 0;
|
|
1449
1448
|
if (onProgress && typeof onProgress === "function") {
|
|
1450
1449
|
onProgress(status.data || status);
|
|
@@ -1486,9 +1485,10 @@ ${bytes.length}`;
|
|
|
1486
1485
|
throw new NetworkError(`Failed to detect chain ID: ${error.message}`);
|
|
1487
1486
|
}
|
|
1488
1487
|
}
|
|
1489
|
-
async revokeOwnProof(
|
|
1490
|
-
|
|
1491
|
-
|
|
1488
|
+
async revokeOwnProof(qHash, wallet) {
|
|
1489
|
+
const resolvedQHash = qHash;
|
|
1490
|
+
if (!resolvedQHash || typeof resolvedQHash !== "string") {
|
|
1491
|
+
throw new ValidationError("qHash is required");
|
|
1492
1492
|
}
|
|
1493
1493
|
const providerWallet = wallet || this._getDefaultBrowserWallet();
|
|
1494
1494
|
const { signerWalletAddress: address, provider } = await this._resolveWalletSigner(providerWallet);
|
|
@@ -1502,7 +1502,7 @@ ${bytes.length}`;
|
|
|
1502
1502
|
const message = constructVerificationMessage({
|
|
1503
1503
|
walletAddress: address,
|
|
1504
1504
|
signedTimestamp,
|
|
1505
|
-
data: { action: "revoke_proof", qHash:
|
|
1505
|
+
data: { action: "revoke_proof", qHash: resolvedQHash },
|
|
1506
1506
|
verifierIds: ["ownership-basic"],
|
|
1507
1507
|
...signerIsEvm ? { chainId: this._getHubChainId() } : { chain }
|
|
1508
1508
|
});
|
|
@@ -1520,15 +1520,11 @@ ${bytes.length}`;
|
|
|
1520
1520
|
}
|
|
1521
1521
|
throw new ValidationError(`Failed to sign revocation: ${error.message}`);
|
|
1522
1522
|
}
|
|
1523
|
-
const res = await
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
signature,
|
|
1529
|
-
signedTimestamp,
|
|
1530
|
-
...signerIsEvm ? {} : { chain, signatureMethod }
|
|
1531
|
-
})
|
|
1523
|
+
const res = await this._makeRequest("POST", `/api/v1/proofs/revoke-self/${resolvedQHash}`, {
|
|
1524
|
+
walletAddress: address,
|
|
1525
|
+
signature,
|
|
1526
|
+
signedTimestamp,
|
|
1527
|
+
...signerIsEvm ? {} : { chain, signatureMethod }
|
|
1532
1528
|
});
|
|
1533
1529
|
const json = await res.json();
|
|
1534
1530
|
if (!json.success) {
|
|
@@ -1689,6 +1685,7 @@ ${bytes.length}`;
|
|
|
1689
1685
|
setIfPresent("primaryWalletAddress", params.primaryWalletAddress);
|
|
1690
1686
|
setIfPresent("secondaryWalletAddress", params.secondaryWalletAddress);
|
|
1691
1687
|
setIfPresent("verificationMethod", params.verificationMethod);
|
|
1688
|
+
setIfPresent("neusPersonhoodId", params.neusPersonhoodId);
|
|
1692
1689
|
let headersOverride = null;
|
|
1693
1690
|
if (params.includePrivate === true) {
|
|
1694
1691
|
const provided = params.privateAuth && typeof params.privateAuth === "object" ? params.privateAuth : null;
|
|
@@ -1930,20 +1927,19 @@ ${bytes.length}`;
|
|
|
1930
1927
|
}
|
|
1931
1928
|
}
|
|
1932
1929
|
_formatResponse(response) {
|
|
1933
|
-
const
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
|
|
1930
|
+
const qHash = response?.data?.qHash || response?.qHash || response?.data?.resource?.qHash || response?.data?.proofId || // Legacy input compatibility only. Do not expose or store proofId.
|
|
1931
|
+
response?.proofId || // Legacy input compatibility only. Do not expose or store proofId.
|
|
1932
|
+
response?.data?.resource?.proofId || // Legacy input compatibility only. Do not expose or store proofId.
|
|
1933
|
+
response?.data?.id;
|
|
1937
1934
|
const status = response?.data?.status || response?.status || response?.data?.resource?.status || (response?.success ? "completed" : "unknown");
|
|
1938
1935
|
return {
|
|
1939
1936
|
success: response.success,
|
|
1940
|
-
|
|
1941
|
-
qHash: finalQHash,
|
|
1937
|
+
qHash,
|
|
1942
1938
|
status,
|
|
1943
1939
|
data: response.data,
|
|
1944
1940
|
message: response.message,
|
|
1945
1941
|
timestamp: Date.now(),
|
|
1946
|
-
proofUrl:
|
|
1942
|
+
proofUrl: qHash ? `${this.baseUrl}/api/v1/proofs/${qHash}` : null
|
|
1947
1943
|
};
|
|
1948
1944
|
}
|
|
1949
1945
|
_isTerminalStatus(status) {
|
package/cjs/index.cjs
CHANGED
|
@@ -1909,19 +1909,15 @@ ${bytes.length}`;
|
|
|
1909
1909
|
for (let i = 0; i < full.length; i++) payloadHex += full[i].toString(16).padStart(2, "0");
|
|
1910
1910
|
try {
|
|
1911
1911
|
if (typeof window !== "undefined") window.__NEUS_ALLOW_ETH_SIGN__ = true;
|
|
1912
|
-
|
|
1913
|
-
}
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
|
|
1912
|
+
signature2 = await provider.request({ method: "eth_sign", params: [walletAddress2, payloadHex], neusAllowEthSign: true });
|
|
1913
|
+
} finally {
|
|
1914
|
+
try {
|
|
1915
|
+
if (typeof window !== "undefined") delete window.__NEUS_ALLOW_ETH_SIGN__;
|
|
1916
|
+
} catch {
|
|
1917
|
+
}
|
|
1918
1918
|
}
|
|
1919
1919
|
} catch (fallbackErr) {
|
|
1920
1920
|
this._log("eth_sign fallback failed", { message: fallbackErr?.message || String(fallbackErr) });
|
|
1921
|
-
try {
|
|
1922
|
-
if (typeof window !== "undefined") delete window.__NEUS_ALLOW_ETH_SIGN__;
|
|
1923
|
-
} catch {
|
|
1924
|
-
}
|
|
1925
1921
|
throw e;
|
|
1926
1922
|
}
|
|
1927
1923
|
} else if (needsHex) {
|
|
@@ -2015,19 +2011,21 @@ ${bytes.length}`;
|
|
|
2015
2011
|
}
|
|
2016
2012
|
return this._formatResponse(response);
|
|
2017
2013
|
}
|
|
2018
|
-
async getProof(
|
|
2019
|
-
|
|
2020
|
-
|
|
2014
|
+
async getProof(qHash) {
|
|
2015
|
+
const resolvedQHash = qHash;
|
|
2016
|
+
if (!resolvedQHash || typeof resolvedQHash !== "string") {
|
|
2017
|
+
throw new ValidationError("qHash is required");
|
|
2021
2018
|
}
|
|
2022
|
-
const response = await this._makeRequest("GET", `/api/v1/proofs/${
|
|
2019
|
+
const response = await this._makeRequest("GET", `/api/v1/proofs/${resolvedQHash}`);
|
|
2023
2020
|
if (!response.success) {
|
|
2024
2021
|
throw new ApiError(`Failed to get proof: ${response.error?.message || "Unknown error"}`, response.error);
|
|
2025
2022
|
}
|
|
2026
2023
|
return this._formatResponse(response);
|
|
2027
2024
|
}
|
|
2028
|
-
async getPrivateProof(
|
|
2029
|
-
|
|
2030
|
-
|
|
2025
|
+
async getPrivateProof(qHash, wallet = null) {
|
|
2026
|
+
const resolvedQHash = qHash;
|
|
2027
|
+
if (!resolvedQHash || typeof resolvedQHash !== "string") {
|
|
2028
|
+
throw new ValidationError("qHash is required");
|
|
2031
2029
|
}
|
|
2032
2030
|
const isPreSignedAuth = wallet && typeof wallet === "object" && typeof wallet.walletAddress === "string" && typeof wallet.signature === "string" && typeof wallet.signedTimestamp === "number";
|
|
2033
2031
|
if (isPreSignedAuth) {
|
|
@@ -2039,7 +2037,7 @@ ${bytes.length}`;
|
|
|
2039
2037
|
...typeof auth.chain === "string" && auth.chain.trim() ? { "x-chain": auth.chain.trim() } : {},
|
|
2040
2038
|
...typeof auth.signatureMethod === "string" && auth.signatureMethod.trim() ? { "x-signature-method": auth.signatureMethod.trim() } : {}
|
|
2041
2039
|
};
|
|
2042
|
-
const response2 = await this._makeRequest("GET", `/api/v1/proofs/${
|
|
2040
|
+
const response2 = await this._makeRequest("GET", `/api/v1/proofs/${resolvedQHash}`, null, headers);
|
|
2043
2041
|
if (!response2.success) {
|
|
2044
2042
|
throw new ApiError(
|
|
2045
2043
|
`Failed to access private proof: ${response2.error?.message || "Unauthorized"}`,
|
|
@@ -2060,7 +2058,7 @@ ${bytes.length}`;
|
|
|
2060
2058
|
const message = constructVerificationMessage({
|
|
2061
2059
|
walletAddress,
|
|
2062
2060
|
signedTimestamp,
|
|
2063
|
-
data: { action: "access_private_proof", qHash:
|
|
2061
|
+
data: { action: "access_private_proof", qHash: resolvedQHash },
|
|
2064
2062
|
verifierIds: ["ownership-basic"],
|
|
2065
2063
|
...signerIsEvm ? { chainId: this._getHubChainId() } : { chain }
|
|
2066
2064
|
});
|
|
@@ -2078,7 +2076,7 @@ ${bytes.length}`;
|
|
|
2078
2076
|
}
|
|
2079
2077
|
throw new ValidationError(`Failed to sign message: ${error.message}`);
|
|
2080
2078
|
}
|
|
2081
|
-
const response = await this._makeRequest("GET", `/api/v1/proofs/${
|
|
2079
|
+
const response = await this._makeRequest("GET", `/api/v1/proofs/${resolvedQHash}`, null, {
|
|
2082
2080
|
"x-wallet-address": walletAddress,
|
|
2083
2081
|
"x-signature": signature,
|
|
2084
2082
|
"x-signed-timestamp": signedTimestamp.toString(),
|
|
@@ -2115,20 +2113,21 @@ ${bytes.length}`;
|
|
|
2115
2113
|
meta: response.meta && typeof response.meta === "object" && !Array.isArray(response.meta) ? response.meta : {}
|
|
2116
2114
|
};
|
|
2117
2115
|
}
|
|
2118
|
-
async pollProofStatus(
|
|
2116
|
+
async pollProofStatus(qHash, options = {}) {
|
|
2117
|
+
const resolvedQHash = qHash;
|
|
2119
2118
|
const {
|
|
2120
2119
|
interval = 5e3,
|
|
2121
2120
|
timeout = 12e4,
|
|
2122
2121
|
onProgress
|
|
2123
2122
|
} = options;
|
|
2124
|
-
if (!
|
|
2125
|
-
throw new ValidationError("
|
|
2123
|
+
if (!resolvedQHash || typeof resolvedQHash !== "string") {
|
|
2124
|
+
throw new ValidationError("qHash is required");
|
|
2126
2125
|
}
|
|
2127
2126
|
const startTime = Date.now();
|
|
2128
2127
|
let consecutiveRateLimits = 0;
|
|
2129
2128
|
while (Date.now() - startTime < timeout) {
|
|
2130
2129
|
try {
|
|
2131
|
-
const status = await this.getProof(
|
|
2130
|
+
const status = await this.getProof(resolvedQHash);
|
|
2132
2131
|
consecutiveRateLimits = 0;
|
|
2133
2132
|
if (onProgress && typeof onProgress === "function") {
|
|
2134
2133
|
onProgress(status.data || status);
|
|
@@ -2170,9 +2169,10 @@ ${bytes.length}`;
|
|
|
2170
2169
|
throw new NetworkError(`Failed to detect chain ID: ${error.message}`);
|
|
2171
2170
|
}
|
|
2172
2171
|
}
|
|
2173
|
-
async revokeOwnProof(
|
|
2174
|
-
|
|
2175
|
-
|
|
2172
|
+
async revokeOwnProof(qHash, wallet) {
|
|
2173
|
+
const resolvedQHash = qHash;
|
|
2174
|
+
if (!resolvedQHash || typeof resolvedQHash !== "string") {
|
|
2175
|
+
throw new ValidationError("qHash is required");
|
|
2176
2176
|
}
|
|
2177
2177
|
const providerWallet = wallet || this._getDefaultBrowserWallet();
|
|
2178
2178
|
const { signerWalletAddress: address, provider } = await this._resolveWalletSigner(providerWallet);
|
|
@@ -2186,7 +2186,7 @@ ${bytes.length}`;
|
|
|
2186
2186
|
const message = constructVerificationMessage({
|
|
2187
2187
|
walletAddress: address,
|
|
2188
2188
|
signedTimestamp,
|
|
2189
|
-
data: { action: "revoke_proof", qHash:
|
|
2189
|
+
data: { action: "revoke_proof", qHash: resolvedQHash },
|
|
2190
2190
|
verifierIds: ["ownership-basic"],
|
|
2191
2191
|
...signerIsEvm ? { chainId: this._getHubChainId() } : { chain }
|
|
2192
2192
|
});
|
|
@@ -2204,15 +2204,11 @@ ${bytes.length}`;
|
|
|
2204
2204
|
}
|
|
2205
2205
|
throw new ValidationError(`Failed to sign revocation: ${error.message}`);
|
|
2206
2206
|
}
|
|
2207
|
-
const res = await
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
signature,
|
|
2213
|
-
signedTimestamp,
|
|
2214
|
-
...signerIsEvm ? {} : { chain, signatureMethod }
|
|
2215
|
-
})
|
|
2207
|
+
const res = await this._makeRequest("POST", `/api/v1/proofs/revoke-self/${resolvedQHash}`, {
|
|
2208
|
+
walletAddress: address,
|
|
2209
|
+
signature,
|
|
2210
|
+
signedTimestamp,
|
|
2211
|
+
...signerIsEvm ? {} : { chain, signatureMethod }
|
|
2216
2212
|
});
|
|
2217
2213
|
const json = await res.json();
|
|
2218
2214
|
if (!json.success) {
|
|
@@ -2373,6 +2369,7 @@ ${bytes.length}`;
|
|
|
2373
2369
|
setIfPresent("primaryWalletAddress", params.primaryWalletAddress);
|
|
2374
2370
|
setIfPresent("secondaryWalletAddress", params.secondaryWalletAddress);
|
|
2375
2371
|
setIfPresent("verificationMethod", params.verificationMethod);
|
|
2372
|
+
setIfPresent("neusPersonhoodId", params.neusPersonhoodId);
|
|
2376
2373
|
let headersOverride = null;
|
|
2377
2374
|
if (params.includePrivate === true) {
|
|
2378
2375
|
const provided = params.privateAuth && typeof params.privateAuth === "object" ? params.privateAuth : null;
|
|
@@ -2614,20 +2611,19 @@ ${bytes.length}`;
|
|
|
2614
2611
|
}
|
|
2615
2612
|
}
|
|
2616
2613
|
_formatResponse(response) {
|
|
2617
|
-
const
|
|
2618
|
-
|
|
2619
|
-
|
|
2620
|
-
|
|
2614
|
+
const qHash = response?.data?.qHash || response?.qHash || response?.data?.resource?.qHash || response?.data?.proofId || // Legacy input compatibility only. Do not expose or store proofId.
|
|
2615
|
+
response?.proofId || // Legacy input compatibility only. Do not expose or store proofId.
|
|
2616
|
+
response?.data?.resource?.proofId || // Legacy input compatibility only. Do not expose or store proofId.
|
|
2617
|
+
response?.data?.id;
|
|
2621
2618
|
const status = response?.data?.status || response?.status || response?.data?.resource?.status || (response?.success ? "completed" : "unknown");
|
|
2622
2619
|
return {
|
|
2623
2620
|
success: response.success,
|
|
2624
|
-
|
|
2625
|
-
qHash: finalQHash,
|
|
2621
|
+
qHash,
|
|
2626
2622
|
status,
|
|
2627
2623
|
data: response.data,
|
|
2628
2624
|
message: response.message,
|
|
2629
2625
|
timestamp: Date.now(),
|
|
2630
|
-
proofUrl:
|
|
2626
|
+
proofUrl: qHash ? `${this.baseUrl}/api/v1/proofs/${qHash}` : null
|
|
2631
2627
|
};
|
|
2632
2628
|
}
|
|
2633
2629
|
_isTerminalStatus(status) {
|