noah-clarity 0.3.6 → 0.3.8

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.
@@ -26,8 +26,7 @@ export declare class KYCContract {
26
26
  */
27
27
  getRevocationRoot(): Promise<string | null>;
28
28
  /**
29
- * Check if a commitment is revoked by checking the revocation root
30
- * Note: This is a simplified check. For full verification, non-membership proofs are needed.
29
+ * Check if a commitment is revoked by querying the attester service
31
30
  * @param commitment Commitment to check (hex string)
32
31
  * @returns true if revoked, false if not revoked or if revocation checking is unavailable
33
32
  */
package/dist/contract.js CHANGED
@@ -26,11 +26,6 @@ export class KYCContract {
26
26
  */
27
27
  async registerKYC(params, privateKey) {
28
28
  const senderAddress = getAddressFromPrivateKey(privateKey, this.network.version);
29
- // #region agent log
30
- console.log('Transaction sender address (derived from private key):', senderAddress);
31
- console.log('Network version:', this.network.version);
32
- fetch('http://127.0.0.1:7249/ingest/b239a7fb-669e-478f-b888-bd46beaadedf', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ location: 'contract.ts:50', 'message': 'registerKYC entry', 'data': { senderAddress, network: this.network.coreApiUrl, networkVersion: this.network.version, attesterId: params.attesterId, commitmentLength: params.commitment.length, signatureLength: params.signature.length }, timestamp: Date.now(), sessionId: 'debug-session', runId: 'run1', hypothesisId: 'A' }) }).catch(() => { });
33
- // #endregion agent log
34
29
  const { address, name } = this.parseContractAddress(this.config.kycRegistryAddress);
35
30
  // Ensure commitment is exactly 32 bytes (64 hex chars)
36
31
  const commitmentHex = params.commitment.replace('0x', '');
@@ -60,24 +55,8 @@ export class KYCContract {
60
55
  anchorMode: AnchorMode.Any,
61
56
  postConditionMode: PostConditionMode.Allow,
62
57
  };
63
- // #region agent log
64
- fetch('http://127.0.0.1:7249/ingest/b239a7fb-669e-478f-b888-bd46beaadedf', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ location: 'contract.ts:74', 'message': 'Transaction options before makeContractCall', 'data': { contractAddress: address, contractName: name, functionName: 'register-kyc', fee: txOptions.fee, anchorMode: txOptions.anchorMode, postConditionMode: txOptions.postConditionMode, networkUrl: this.network.coreApiUrl }, timestamp: Date.now(), sessionId: 'debug-session', runId: 'run1', hypothesisId: 'B' }) }).catch(() => { });
65
- // #endregion agent log
66
58
  try {
67
59
  const transaction = await makeContractCall(txOptions);
68
- // #region agent log
69
- const serializedTx = transaction.serialize();
70
- const nonceValue = transaction.auth?.spendingCondition?.nonce;
71
- const txData = {
72
- txId: transaction.txid(),
73
- nonce: typeof nonceValue === 'bigint' ? nonceValue.toString() : nonceValue,
74
- serializedTxLength: serializedTx.byteLength,
75
- };
76
- fetch('http://127.0.0.1:7249/ingest/b239a7fb-669e-478f-b888-bd46beaadedf', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ location: 'contract.ts:87', 'message': 'Transaction created, before broadcast', 'data': txData, timestamp: Date.now(), sessionId: 'debug-session', runId: 'run1', hypothesisId: 'A' }) }).catch(() => { });
77
- // #endregion agent log
78
- // #region agent log
79
- fetch('http://127.0.0.1:7249/ingest/b239a7fb-669e-478f-b888-bd46beaadedf', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ location: 'contract.ts:108', 'message': 'About to call broadcastTransaction', 'data': {}, timestamp: Date.now(), sessionId: 'debug-session', runId: 'run1', hypothesisId: 'D' }) }).catch(() => { });
80
- // #endregion agent log
81
60
  try {
82
61
  const broadcastResponse = await broadcastTransaction(transaction, this.network);
83
62
  return broadcastResponse.txid;
@@ -90,9 +69,6 @@ export class KYCContract {
90
69
  }
91
70
  }
92
71
  catch (error) {
93
- // #region agent log
94
- fetch('http://127.0.0.1:7249/ingest/b239a7fb-669e-478f-b888-bd46beaadedf', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ location: 'contract.ts:110', 'message': 'Caught error in registerKYC', 'data': { errorType: error?.constructor?.name, hasMessage: !!error?.message, message: error?.message?.substring(0, 200) }, timestamp: Date.now(), sessionId: 'debug-session', runId: 'run1', hypothesisId: 'C' }) }).catch(() => { });
95
- // #endregion agent log
96
72
  // Helper function to safely serialize data (handles BigInt)
97
73
  const safeStringify = (obj) => {
98
74
  try {
@@ -139,24 +115,6 @@ export class KYCContract {
139
115
  }
140
116
  return result;
141
117
  };
142
- // #region agent log
143
- const errorKeys = error ? Object.keys(error) : [];
144
- const errorStructure = {
145
- hasError: !!error,
146
- hasResponse: !!error?.response,
147
- hasData: !!error?.data,
148
- hasStatus: !!error?.status,
149
- hasStatusText: !!error?.statusText,
150
- hasReason: !!error?.reason,
151
- hasMessage: !!error?.message,
152
- errorKeys: errorKeys,
153
- errorType: error?.constructor?.name,
154
- status: error?.status,
155
- statusText: error?.statusText,
156
- message: error?.message,
157
- };
158
- fetch('http://127.0.0.1:7249/ingest/b239a7fb-669e-478f-b888-bd46beaadedf', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: safeStringify({ location: 'contract.ts:135', 'message': 'Error object structure', 'data': errorStructure, timestamp: Date.now(), sessionId: 'debug-session', runId: 'run1', hypothesisId: 'C' }) }).catch(() => { });
159
- // #endregion agent log
160
118
  // Capture detailed error information
161
119
  let errorMessage = 'Transaction failed';
162
120
  let errorDetails = {};
@@ -193,9 +151,6 @@ export class KYCContract {
193
151
  errorDetails.status = error.status;
194
152
  if (error?.statusText)
195
153
  errorDetails.statusText = error.statusText;
196
- // #region agent log
197
- fetch('http://127.0.0.1:7249/ingest/b239a7fb-669e-478f-b888-bd46beaadedf', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: safeStringify({ location: 'contract.ts:120', 'message': 'Error details captured', 'data': errorDetails, timestamp: Date.now(), sessionId: 'debug-session', runId: 'run1', hypothesisId: 'C' }) }).catch(() => { });
198
- // #endregion agent log
199
154
  // Try to extract response body if it exists
200
155
  let responseBody = null;
201
156
  if (error?.response?.data) {
@@ -204,11 +159,6 @@ export class KYCContract {
204
159
  else if (error?.data) {
205
160
  responseBody = typeof error.data === 'string' ? error.data : safeExtract(error.data);
206
161
  }
207
- // #region agent log
208
- if (responseBody) {
209
- fetch('http://127.0.0.1:7249/ingest/b239a7fb-669e-478f-b888-bd46beaadedf', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: safeStringify({ location: 'contract.ts:135', 'message': 'API response body', 'data': { responseBody: typeof responseBody === 'string' ? responseBody : safeStringify(responseBody) }, timestamp: Date.now(), sessionId: 'debug-session', runId: 'run1', hypothesisId: 'C' }) }).catch(() => { });
210
- }
211
- // #endregion agent log
212
162
  // Extract error details from response body for user-friendly messages
213
163
  let userFriendlyMessage = errorMessage;
214
164
  if (responseBody && typeof responseBody === 'object') {
@@ -239,9 +189,6 @@ export class KYCContract {
239
189
  */
240
190
  async hasKYC(userPrincipal) {
241
191
  const { address, name } = this.parseContractAddress(this.config.kycRegistryAddress);
242
- // #region agent log
243
- fetch('http://127.0.0.1:7249/ingest/b239a7fb-669e-478f-b888-bd46beaadedf', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ location: 'contract.ts:269', 'message': 'hasKYC called', 'data': { userPrincipal, contractAddress: this.config.kycRegistryAddress, parsedAddress: address, parsedName: name }, timestamp: Date.now(), sessionId: 'debug-session', runId: 'run1', hypothesisId: 'A' }) }).catch(() => { });
244
- // #endregion agent log
245
192
  try {
246
193
  const result = await callReadOnlyFunction({
247
194
  contractAddress: address,
@@ -251,21 +198,7 @@ export class KYCContract {
251
198
  network: this.network,
252
199
  senderAddress: address, // Use contract address as sender for read-only calls
253
200
  });
254
- // #region agent log
255
- console.log('hasKYC callReadOnlyFunction result (before cvToJSON):', result);
256
- console.log('hasKYC result type:', typeof result);
257
- console.log('hasKYC result constructor:', result?.constructor?.name);
258
- fetch('http://127.0.0.1:7249/ingest/b239a7fb-669e-478f-b888-bd46beaadedf', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ location: 'contract.ts:277', 'message': 'hasKYC callReadOnlyFunction result', 'data': { userPrincipal, resultType: typeof result, resultConstructor: result?.constructor?.name, resultString: String(result) }, timestamp: Date.now(), sessionId: 'debug-session', runId: 'run2', hypothesisId: 'A' }) }).catch(() => { });
259
- // #endregion agent log
260
201
  const jsonResult = cvToJSON(result);
261
- // #region agent log
262
- console.log('hasKYC raw result (after cvToJSON):', JSON.stringify(jsonResult, null, 2));
263
- console.log('hasKYC jsonResult.type:', jsonResult.type);
264
- console.log('hasKYC jsonResult.value:', jsonResult.value);
265
- console.log('hasKYC jsonResult.value type:', typeof jsonResult.value);
266
- console.log('hasKYC jsonResult.success:', jsonResult.success);
267
- fetch('http://127.0.0.1:7249/ingest/b239a7fb-669e-478f-b888-bd46beaadedf', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ location: 'contract.ts:290', 'message': 'hasKYC result after cvToJSON', 'data': { userPrincipal, resultType: jsonResult.type, resultValue: jsonResult.value, resultValueType: typeof jsonResult.value, resultSuccess: jsonResult.success, fullResult: JSON.stringify(jsonResult) }, timestamp: Date.now(), sessionId: 'debug-session', runId: 'run2', hypothesisId: 'B' }) }).catch(() => { });
268
- // #endregion agent log
269
202
  // Result is (ok bool), cvToJSON returns:
270
203
  // { type: '(response bool UnknownType)', value: { type: 'bool', value: true }, success: true }
271
204
  // Check success field or response type, then extract boolean from value.value
@@ -273,19 +206,13 @@ export class KYCContract {
273
206
  // Extract the boolean value from the nested structure
274
207
  const boolValue = jsonResult.value?.value;
275
208
  const hasKYC = boolValue === true;
276
- console.log('hasKYC final result:', hasKYC, 'jsonResult.value.value:', boolValue, 'type:', typeof boolValue);
277
209
  return { hasKYC };
278
210
  }
279
211
  else {
280
- console.log('hasKYC: response not ok, type:', jsonResult.type, 'success:', jsonResult.success, 'full result:', JSON.stringify(jsonResult));
281
212
  return { hasKYC: false };
282
213
  }
283
214
  }
284
215
  catch (error) {
285
- // #region agent log
286
- console.error('hasKYC exception:', error);
287
- fetch('http://127.0.0.1:7249/ingest/b239a7fb-669e-478f-b888-bd46beaadedf', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ location: 'contract.ts:294', 'message': 'hasKYC error', 'data': { userPrincipal, error: error instanceof Error ? error.message : String(error), errorStack: error instanceof Error ? error.stack : undefined }, timestamp: Date.now(), sessionId: 'debug-session', runId: 'run1', hypothesisId: 'A' }) }).catch(() => { });
288
- // #endregion agent log
289
216
  console.error('Error checking KYC status:', error);
290
217
  return { hasKYC: false };
291
218
  }
@@ -325,24 +252,32 @@ export class KYCContract {
325
252
  }
326
253
  }
327
254
  /**
328
- * Check if a commitment is revoked by checking the revocation root
329
- * Note: This is a simplified check. For full verification, non-membership proofs are needed.
255
+ * Check if a commitment is revoked by querying the attester service
330
256
  * @param commitment Commitment to check (hex string)
331
257
  * @returns true if revoked, false if not revoked or if revocation checking is unavailable
332
258
  */
333
259
  async isCommitmentRevoked(commitment) {
334
- const root = await this.getRevocationRoot();
335
- // If no revocation registry configured or root is zero (empty tree), nothing is revoked
336
- if (!root || root === '0x0000000000000000000000000000000000000000000000000000000000000000') {
260
+ // If no attester service URL configured, skip revocation check
261
+ if (!this.config.attesterServiceUrl) {
262
+ return false;
263
+ }
264
+ try {
265
+ // Query attester service for revocation status
266
+ const url = `${this.config.attesterServiceUrl}/revocation/check?commitment=${encodeURIComponent(commitment)}`;
267
+ const response = await fetch(url);
268
+ if (!response.ok) {
269
+ // If service unavailable, assume not revoked (fail open)
270
+ console.warn('Revocation check service unavailable, assuming not revoked');
271
+ return false;
272
+ }
273
+ const data = await response.json();
274
+ return data.revoked === true;
275
+ }
276
+ catch (error) {
277
+ // On error, assume not revoked (fail open)
278
+ console.error('Error checking revocation status:', error);
337
279
  return false;
338
280
  }
339
- // TODO: Full revocation checking requires non-membership proof verification
340
- // For now, we return false (not revoked) when root exists but we can't verify without proof
341
- // In production, you should:
342
- // 1. Request a non-membership proof from the attester service
343
- // 2. Verify the proof using Merkle tree verification
344
- // 3. Return true if proof verification fails or if commitment is in revocation tree
345
- return false;
346
281
  }
347
282
  /**
348
283
  * Check if KYC is valid
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "noah-clarity",
3
- "version": "0.3.6",
3
+ "version": "0.3.8",
4
4
  "description": "TypeScript SDK for Noah-v2 KYC system on Stacks",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",