@neus/sdk 1.0.0 → 1.0.1

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/errors.js CHANGED
@@ -1,228 +1,223 @@
1
- /**
2
- * NEUS SDK Error Classes
3
- * @license Apache-2.0
4
- */
5
-
6
- /**
7
- * Base SDK Error Class
8
- */
9
- export class SDKError extends Error {
10
- constructor(message, code = 'SDK_ERROR', details = {}) {
11
- super(message);
12
- this.name = 'SDKError';
13
- this.code = code;
14
- this.details = details;
15
- this.timestamp = Date.now();
16
-
17
- // Ensure proper prototype chain
18
- if (Error.captureStackTrace) {
19
- Error.captureStackTrace(this, SDKError);
20
- }
21
- }
22
-
23
- toJSON() {
24
- return {
25
- name: this.name,
26
- message: this.message,
27
- code: this.code,
28
- details: this.details,
29
- timestamp: this.timestamp
30
- };
31
- }
32
- }
33
-
34
- /**
35
- * API-related errors (server responses, HTTP issues)
36
- */
37
- export class ApiError extends SDKError {
38
- constructor(message, statusCode = 500, code = 'API_ERROR', response = null) {
39
- super(message, code);
40
- this.name = 'ApiError';
41
- this.statusCode = statusCode;
42
- this.response = response;
43
-
44
- // Additional classification
45
- this.isClientError = statusCode >= 400 && statusCode < 500;
46
- this.isServerError = statusCode >= 500;
47
- this.isRetryable = this.isServerError || statusCode === 429; // Server errors or rate limit
48
- }
49
-
50
- static fromResponse(response, responseData) {
51
- const statusCode = response.status;
52
- const message =
53
- responseData?.error?.message ||
54
- responseData?.message ||
55
- `API request failed with status ${statusCode}`;
56
- const code = responseData?.error?.code || 'API_ERROR';
57
-
58
- return new ApiError(message, statusCode, code, responseData);
59
- }
60
-
61
- toJSON() {
62
- return {
63
- ...super.toJSON(),
64
- statusCode: this.statusCode,
65
- isClientError: this.isClientError,
66
- isServerError: this.isServerError,
67
- isRetryable: this.isRetryable
68
- };
69
- }
70
- }
71
-
72
- /**
73
- * Client-side validation errors (invalid parameters, missing required fields)
74
- */
75
- export class ValidationError extends SDKError {
76
- constructor(message, field = null, value = null) {
77
- super(message, 'VALIDATION_ERROR');
78
- this.name = 'ValidationError';
79
- this.field = field;
80
- this.value = value;
81
- this.isRetryable = false; // Validation errors are not retryable
82
- }
83
-
84
- toJSON() {
85
- return {
86
- ...super.toJSON(),
87
- field: this.field,
88
- value: this.value,
89
- isRetryable: this.isRetryable
90
- };
91
- }
92
- }
93
-
94
- /**
95
- * Network-related errors (connectivity, timeouts, DNS issues)
96
- */
97
- export class NetworkError extends SDKError {
98
- constructor(message, code = 'NETWORK_ERROR', originalError = null) {
99
- super(message, code);
100
- this.name = 'NetworkError';
101
- this.originalError = originalError;
102
- this.isRetryable = true; // Network errors are typically retryable
103
- }
104
-
105
- static isNetworkError(error) {
106
- return (
107
- error instanceof NetworkError ||
108
- (error.name === 'TypeError' && error.message.includes('fetch')) ||
109
- error.name === 'AbortError' ||
110
- error.code === 'ENOTFOUND' ||
111
- error.code === 'ECONNREFUSED' ||
112
- error.code === 'ETIMEDOUT'
113
- );
114
- }
115
-
116
- toJSON() {
117
- return {
118
- ...super.toJSON(),
119
- isRetryable: this.isRetryable,
120
- originalError: this.originalError
121
- ? {
122
- name: this.originalError.name,
123
- message: this.originalError.message,
124
- code: this.originalError.code
125
- }
126
- : null
127
- };
128
- }
129
- }
130
-
131
- /**
132
- * Configuration-related errors (missing configuration, invalid settings)
133
- */
134
- export class ConfigurationError extends SDKError {
135
- constructor(message, configKey = null) {
136
- super(message, 'CONFIGURATION_ERROR');
137
- this.name = 'ConfigurationError';
138
- this.configKey = configKey;
139
- this.isRetryable = false; // Config errors require user intervention
140
- }
141
-
142
- toJSON() {
143
- return {
144
- ...super.toJSON(),
145
- configKey: this.configKey,
146
- isRetryable: this.isRetryable
147
- };
148
- }
149
- }
150
-
151
- /**
152
- * Verification-specific errors (verifier failures, invalid proofs)
153
- */
154
- export class VerificationError extends SDKError {
155
- constructor(message, verifierId = null, code = 'VERIFICATION_ERROR') {
156
- super(message, code);
157
- this.name = 'VerificationError';
158
- this.verifierId = verifierId;
159
- this.isRetryable = true; // Some verification errors might be retryable
160
- }
161
-
162
- toJSON() {
163
- return {
164
- ...super.toJSON(),
165
- verifierId: this.verifierId,
166
- isRetryable: this.isRetryable
167
- };
168
- }
169
- }
170
-
171
- /**
172
- * Authentication-related errors (signature validation, wallet connection)
173
- */
174
- export class AuthenticationError extends SDKError {
175
- constructor(message, code = 'AUTHENTICATION_ERROR') {
176
- super(message, code);
177
- this.name = 'AuthenticationError';
178
- this.isRetryable = false; // Auth errors require user intervention
179
- }
180
-
181
- toJSON() {
182
- return {
183
- ...super.toJSON(),
184
- isRetryable: this.isRetryable
185
- };
186
- }
187
- }
188
-
189
- /**
190
- * Utility function to create appropriate error from generic error
191
- */
192
- export function createErrorFromGeneric(error, context = {}) {
193
- if (error instanceof SDKError) {
194
- return error;
195
- }
196
-
197
- // Network-related errors
198
- if (NetworkError.isNetworkError(error)) {
199
- return new NetworkError(
200
- error.message || 'Network error occurred',
201
- error.code || 'NETWORK_ERROR',
202
- error
203
- );
204
- }
205
-
206
- // Timeout errors
207
- if (error.name === 'AbortError' || error.message.includes('timeout')) {
208
- return new NetworkError('Request timeout', 'TIMEOUT', error);
209
- }
210
-
211
- // Generic error wrapper
212
- return new SDKError(error.message || 'Unknown error occurred', error.code || 'UNKNOWN_ERROR', {
213
- originalError: error,
214
- context
215
- });
216
- }
217
-
218
- // Export all error classes as default
219
- export default {
220
- SDKError,
221
- ApiError,
222
- ValidationError,
223
- NetworkError,
224
- ConfigurationError,
225
- VerificationError,
226
- AuthenticationError,
227
- createErrorFromGeneric
228
- };
1
+ /**
2
+ * NEUS SDK Error Classes
3
+ */
4
+
5
+ /**
6
+ * Base SDK Error Class
7
+ */
8
+ export class SDKError extends Error {
9
+ constructor(message, code = 'SDK_ERROR', details = {}) {
10
+ super(message);
11
+ this.name = 'SDKError';
12
+ this.code = code;
13
+ this.details = details;
14
+ this.timestamp = Date.now();
15
+
16
+ // Ensure proper prototype chain
17
+ if (Error.captureStackTrace) {
18
+ Error.captureStackTrace(this, SDKError);
19
+ }
20
+ }
21
+
22
+ toJSON() {
23
+ return {
24
+ name: this.name,
25
+ message: this.message,
26
+ code: this.code,
27
+ details: this.details,
28
+ timestamp: this.timestamp
29
+ };
30
+ }
31
+ }
32
+
33
+ /**
34
+ * API-related errors (server responses, HTTP issues)
35
+ */
36
+ export class ApiError extends SDKError {
37
+ constructor(message, statusCode = 500, code = 'API_ERROR', response = null) {
38
+ super(message, code);
39
+ this.name = 'ApiError';
40
+ this.statusCode = statusCode;
41
+ this.response = response;
42
+
43
+ // Additional classification
44
+ this.isClientError = statusCode >= 400 && statusCode < 500;
45
+ this.isServerError = statusCode >= 500;
46
+ this.isRetryable = this.isServerError || statusCode === 429; // Server errors or rate limit
47
+ }
48
+
49
+ static fromResponse(response, responseData) {
50
+ const statusCode = response.status;
51
+ const message = responseData?.error?.message ||
52
+ responseData?.message ||
53
+ `API request failed with status ${statusCode}`;
54
+ const code = responseData?.error?.code || 'API_ERROR';
55
+
56
+ return new ApiError(message, statusCode, code, responseData);
57
+ }
58
+
59
+ toJSON() {
60
+ return {
61
+ ...super.toJSON(),
62
+ statusCode: this.statusCode,
63
+ isClientError: this.isClientError,
64
+ isServerError: this.isServerError,
65
+ isRetryable: this.isRetryable
66
+ };
67
+ }
68
+ }
69
+
70
+ /**
71
+ * Client-side validation errors (invalid parameters, missing required fields)
72
+ */
73
+ export class ValidationError extends SDKError {
74
+ constructor(message, field = null, value = null) {
75
+ super(message, 'VALIDATION_ERROR');
76
+ this.name = 'ValidationError';
77
+ this.field = field;
78
+ this.value = value;
79
+ this.isRetryable = false; // Validation errors are not retryable
80
+ }
81
+
82
+ toJSON() {
83
+ return {
84
+ ...super.toJSON(),
85
+ field: this.field,
86
+ value: this.value,
87
+ isRetryable: this.isRetryable
88
+ };
89
+ }
90
+ }
91
+
92
+ /**
93
+ * Network-related errors (connectivity, timeouts, DNS issues)
94
+ */
95
+ export class NetworkError extends SDKError {
96
+ constructor(message, code = 'NETWORK_ERROR', originalError = null) {
97
+ super(message, code);
98
+ this.name = 'NetworkError';
99
+ this.originalError = originalError;
100
+ this.isRetryable = true; // Network errors are typically retryable
101
+ }
102
+
103
+ static isNetworkError(error) {
104
+ return error instanceof NetworkError ||
105
+ error.name === 'TypeError' && error.message.includes('fetch') ||
106
+ error.name === 'AbortError' ||
107
+ error.code === 'ENOTFOUND' ||
108
+ error.code === 'ECONNREFUSED' ||
109
+ error.code === 'ETIMEDOUT';
110
+ }
111
+
112
+ toJSON() {
113
+ return {
114
+ ...super.toJSON(),
115
+ isRetryable: this.isRetryable,
116
+ originalError: this.originalError ? {
117
+ name: this.originalError.name,
118
+ message: this.originalError.message,
119
+ code: this.originalError.code
120
+ } : null
121
+ };
122
+ }
123
+ }
124
+
125
+ /**
126
+ * Configuration-related errors (missing configuration, invalid settings)
127
+ */
128
+ export class ConfigurationError extends SDKError {
129
+ constructor(message, configKey = null) {
130
+ super(message, 'CONFIGURATION_ERROR');
131
+ this.name = 'ConfigurationError';
132
+ this.configKey = configKey;
133
+ this.isRetryable = false; // Config errors require user intervention
134
+ }
135
+
136
+ toJSON() {
137
+ return {
138
+ ...super.toJSON(),
139
+ configKey: this.configKey,
140
+ isRetryable: this.isRetryable
141
+ };
142
+ }
143
+ }
144
+
145
+ /**
146
+ * Verification-specific errors (verifier failures, invalid proofs)
147
+ */
148
+ export class VerificationError extends SDKError {
149
+ constructor(message, verifierId = null, code = 'VERIFICATION_ERROR') {
150
+ super(message, code);
151
+ this.name = 'VerificationError';
152
+ this.verifierId = verifierId;
153
+ this.isRetryable = true; // Some verification errors might be retryable
154
+ }
155
+
156
+ toJSON() {
157
+ return {
158
+ ...super.toJSON(),
159
+ verifierId: this.verifierId,
160
+ isRetryable: this.isRetryable
161
+ };
162
+ }
163
+ }
164
+
165
+ /**
166
+ * Authentication-related errors (signature validation, wallet connection)
167
+ */
168
+ export class AuthenticationError extends SDKError {
169
+ constructor(message, code = 'AUTHENTICATION_ERROR') {
170
+ super(message, code);
171
+ this.name = 'AuthenticationError';
172
+ this.isRetryable = false; // Auth errors require user intervention
173
+ }
174
+
175
+ toJSON() {
176
+ return {
177
+ ...super.toJSON(),
178
+ isRetryable: this.isRetryable
179
+ };
180
+ }
181
+ }
182
+
183
+ /**
184
+ * Utility function to create appropriate error from generic error
185
+ */
186
+ export function createErrorFromGeneric(error, context = {}) {
187
+ if (error instanceof SDKError) {
188
+ return error;
189
+ }
190
+
191
+ // Network-related errors
192
+ if (NetworkError.isNetworkError(error)) {
193
+ return new NetworkError(
194
+ error.message || 'Network error occurred',
195
+ error.code || 'NETWORK_ERROR',
196
+ error
197
+ );
198
+ }
199
+
200
+ // Timeout errors
201
+ if (error.name === 'AbortError' || error.message.includes('timeout')) {
202
+ return new NetworkError('Request timeout', 'TIMEOUT', error);
203
+ }
204
+
205
+ // Generic error wrapper
206
+ return new SDKError(
207
+ error.message || 'Unknown error occurred',
208
+ error.code || 'UNKNOWN_ERROR',
209
+ { originalError: error, context }
210
+ );
211
+ }
212
+
213
+ // Export all error classes as default
214
+ export default {
215
+ SDKError,
216
+ ApiError,
217
+ ValidationError,
218
+ NetworkError,
219
+ ConfigurationError,
220
+ VerificationError,
221
+ AuthenticationError,
222
+ createErrorFromGeneric
223
+ };
package/gates.js ADDED
@@ -0,0 +1,175 @@
1
+ /**
2
+ * NEUS SDK Gate Recipes
3
+ *
4
+ * These are EXAMPLES, not defaults.
5
+ * Pick or copy-paste what fits your use case.
6
+ *
7
+ * @license Apache-2.0
8
+ */
9
+
10
+ // Time constants (milliseconds)
11
+ export const HOUR = 60 * 60 * 1000;
12
+ export const DAY = 24 * HOUR;
13
+ export const WEEK = 7 * DAY;
14
+ export const MONTH = 30 * DAY;
15
+ export const YEAR = 365 * DAY;
16
+
17
+ // ============================================================================
18
+ // RECIPE GATES - Use case specific examples
19
+ // ============================================================================
20
+
21
+ /**
22
+ * NFT holder gate
23
+ * Integrator should add match: { contractAddress: '0x...' } when using
24
+ */
25
+ export const GATE_NFT_HOLDER = [
26
+ { verifierId: 'nft-ownership' },
27
+ ];
28
+
29
+ /**
30
+ * Token holder gate
31
+ * Integrator should add match: { contractAddress: '0x...', minBalance: '...' }
32
+ */
33
+ export const GATE_TOKEN_HOLDER = [
34
+ { verifierId: 'token-holding' },
35
+ ];
36
+
37
+ /**
38
+ * Contract admin gate: requires recent contract ownership verification
39
+ * Short TTL (1h) because ownership can transfer (point-in-time proof)
40
+ */
41
+ export const GATE_CONTRACT_ADMIN = [
42
+ { verifierId: 'contract-ownership', maxAgeMs: HOUR },
43
+ ];
44
+
45
+ /**
46
+ * Domain owner gate: requires DNS TXT verification
47
+ * For verified organization badges, creator platforms
48
+ */
49
+ export const GATE_DOMAIN_OWNER = [
50
+ { verifierId: 'ownership-dns-txt' },
51
+ ];
52
+
53
+ /**
54
+ * Linked wallets gate: requires wallet linking
55
+ * For multi-wallet identity features
56
+ */
57
+ export const GATE_LINKED_WALLETS = [
58
+ { verifierId: 'wallet-link' },
59
+ ];
60
+
61
+ /**
62
+ * Agent identity gate: requires verified agent identity
63
+ * For agent/bot verification features
64
+ */
65
+ export const GATE_AGENT_IDENTITY = [
66
+ { verifierId: 'agent-identity' },
67
+ ];
68
+
69
+ /**
70
+ * Agent delegation gate: requires delegation proof
71
+ * With recommended 7-day TTL for security
72
+ */
73
+ export const GATE_AGENT_DELEGATION = [
74
+ { verifierId: 'agent-delegation', maxAgeMs: 7 * DAY },
75
+ ];
76
+
77
+ /**
78
+ * Content moderation gate: requires a moderation proof for the exact contentHash.
79
+ * Proof is permanent (policy snapshot); re-run only if your policy/provider requirements change.
80
+ */
81
+ export const GATE_CONTENT_MODERATION = [
82
+ { verifierId: 'ai-content-moderation' },
83
+ ];
84
+
85
+ /**
86
+ * Wallet risk gate: requires wallet risk assessment
87
+ * Provider-backed risk signal
88
+ */
89
+ export const GATE_WALLET_RISK = [
90
+ { verifierId: 'wallet-risk' },
91
+ ];
92
+
93
+ /**
94
+ * Pseudonym gate: requires pseudonymous identity proof
95
+ * For anonymous reputation systems
96
+ */
97
+ export const GATE_PSEUDONYM = [
98
+ { verifierId: 'ownership-pseudonym' },
99
+ ];
100
+
101
+ // ============================================================================
102
+ // HELPER FUNCTIONS
103
+ // ============================================================================
104
+
105
+ /**
106
+ * Create a custom gate from verifier IDs
107
+ * @param {Array<string|Object>} requirements - Array of verifier IDs or requirement objects
108
+ * @returns {Array} Gate requirements array
109
+ *
110
+ * @example
111
+ * // Simple: just verifier IDs
112
+ * const gate = createGate(['nft-ownership', 'token-holding']);
113
+ *
114
+ * // With options
115
+ * const gate = createGate([
116
+ * { verifierId: 'nft-ownership', match: { contractAddress: '0x...' } },
117
+ * { verifierId: 'token-holding', maxAgeMs: 7 * DAY },
118
+ * ]);
119
+ */
120
+ export function createGate(requirements) {
121
+ return requirements.map(req => {
122
+ if (typeof req === 'string') {
123
+ return { verifierId: req };
124
+ }
125
+ return req;
126
+ });
127
+ }
128
+
129
+ /**
130
+ * Combine multiple gates (union of requirements)
131
+ * @param {...Array} gates - Gate arrays to combine
132
+ * @returns {Array} Combined gate requirements
133
+ *
134
+ * @example
135
+ * const strictGate = combineGates(GATE_NFT_HOLDER, GATE_TOKEN_HOLDER);
136
+ */
137
+ export function combineGates(...gates) {
138
+ const combined = [];
139
+ const seen = new Set();
140
+
141
+ for (const gate of gates) {
142
+ for (const req of gate) {
143
+ const key = req.verifierId + JSON.stringify(req.match || {});
144
+ if (!seen.has(key)) {
145
+ seen.add(key);
146
+ combined.push(req);
147
+ }
148
+ }
149
+ }
150
+
151
+ return combined;
152
+ }
153
+
154
+ export default {
155
+ // Time constants
156
+ HOUR,
157
+ DAY,
158
+ WEEK,
159
+ MONTH,
160
+ YEAR,
161
+ // Recipe gates
162
+ GATE_NFT_HOLDER,
163
+ GATE_TOKEN_HOLDER,
164
+ GATE_CONTRACT_ADMIN,
165
+ GATE_DOMAIN_OWNER,
166
+ GATE_LINKED_WALLETS,
167
+ GATE_AGENT_IDENTITY,
168
+ GATE_AGENT_DELEGATION,
169
+ GATE_CONTENT_MODERATION,
170
+ GATE_WALLET_RISK,
171
+ GATE_PSEUDONYM,
172
+ // Helpers
173
+ createGate,
174
+ combineGates,
175
+ };