noah-clarity 0.3.2 → 0.3.3
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/dist/config.js +5 -10
- package/dist/contract.js +60 -32
- package/dist/index.js +12 -33
- package/dist/proof.js +1 -5
- package/dist/types.js +1 -2
- package/dist/wallet.js +1 -5
- package/package.json +1 -1
package/dist/config.js
CHANGED
|
@@ -1,21 +1,16 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
/**
|
|
3
2
|
* Configuration loader for contract addresses
|
|
4
3
|
*/
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.TESTNET_CONTRACTS = void 0;
|
|
7
|
-
exports.loadContractAddresses = loadContractAddresses;
|
|
8
|
-
exports.createSDKConfig = createSDKConfig;
|
|
9
4
|
/**
|
|
10
5
|
* Default testnet contract addresses (deployed)
|
|
11
6
|
*/
|
|
12
|
-
|
|
7
|
+
export const TESTNET_CONTRACTS = {
|
|
13
8
|
network: 'testnet',
|
|
14
9
|
deployer: 'STVAH96MR73TP2FZG2W4X220MEB4NEMJHPMVYQNS',
|
|
15
10
|
contracts: {
|
|
16
11
|
'attester-registry': 'STVAH96MR73TP2FZG2W4X220MEB4NEMJHPMVYQNS.attester-registry',
|
|
17
12
|
'attester-registry-trait': 'STVAH96MR73TP2FZG2W4X220MEB4NEMJHPMVYQNS.attester-registry-trait',
|
|
18
|
-
'kyc-registry': 'STVAH96MR73TP2FZG2W4X220MEB4NEMJHPMVYQNS.
|
|
13
|
+
'kyc-registry': 'STVAH96MR73TP2FZG2W4X220MEB4NEMJHPMVYQNS.kycs-registry',
|
|
19
14
|
'revocation': 'STVAH96MR73TP2FZG2W4X220MEB4NEMJHPMVYQNS.revocation',
|
|
20
15
|
},
|
|
21
16
|
deployment_date: '2025-01-17',
|
|
@@ -26,14 +21,14 @@ exports.TESTNET_CONTRACTS = {
|
|
|
26
21
|
* In browser environments, this can load from a static JSON file
|
|
27
22
|
* In Node.js, can use fs to read the JSON file
|
|
28
23
|
*/
|
|
29
|
-
function loadContractAddresses(network = 'testnet') {
|
|
24
|
+
export function loadContractAddresses(network = 'testnet') {
|
|
30
25
|
// For now, return hardcoded testnet addresses
|
|
31
26
|
// In production, you might want to:
|
|
32
27
|
// 1. Load from a JSON file
|
|
33
28
|
// 2. Fetch from a registry/API
|
|
34
29
|
// 3. Use environment variables
|
|
35
30
|
if (network === 'testnet') {
|
|
36
|
-
return
|
|
31
|
+
return TESTNET_CONTRACTS;
|
|
37
32
|
}
|
|
38
33
|
// TODO: Add mainnet addresses when deployed
|
|
39
34
|
throw new Error(`Contract addresses for ${network} not yet configured`);
|
|
@@ -41,7 +36,7 @@ function loadContractAddresses(network = 'testnet') {
|
|
|
41
36
|
/**
|
|
42
37
|
* Create SDK config from contract addresses
|
|
43
38
|
*/
|
|
44
|
-
function createSDKConfig(addresses, options) {
|
|
39
|
+
export function createSDKConfig(addresses, options) {
|
|
45
40
|
return {
|
|
46
41
|
kycRegistryAddress: addresses.contracts['kyc-registry'],
|
|
47
42
|
attesterRegistryAddress: addresses.contracts['attester-registry'],
|
package/dist/contract.js
CHANGED
|
@@ -1,12 +1,9 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
/**
|
|
3
2
|
* Clarity contract interaction helpers
|
|
4
3
|
*/
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
const network_1 = require("@stacks/network");
|
|
9
|
-
class KYCContract {
|
|
4
|
+
import { makeContractCall, broadcastTransaction, AnchorMode, PostConditionMode, bufferCV, uintCV, principalCV, getAddressFromPrivateKey, cvToJSON, callReadOnlyFunction, } from '@stacks/transactions';
|
|
5
|
+
import { StacksTestnet, StacksMainnet } from '@stacks/network';
|
|
6
|
+
export class KYCContract {
|
|
10
7
|
constructor(config) {
|
|
11
8
|
this.config = config;
|
|
12
9
|
this.network = this.getNetwork();
|
|
@@ -14,11 +11,11 @@ class KYCContract {
|
|
|
14
11
|
getNetwork() {
|
|
15
12
|
switch (this.config.network) {
|
|
16
13
|
case 'mainnet':
|
|
17
|
-
return new
|
|
14
|
+
return new StacksMainnet();
|
|
18
15
|
case 'testnet':
|
|
19
|
-
return new
|
|
16
|
+
return new StacksTestnet();
|
|
20
17
|
default:
|
|
21
|
-
return new
|
|
18
|
+
return new StacksTestnet();
|
|
22
19
|
}
|
|
23
20
|
}
|
|
24
21
|
/**
|
|
@@ -28,9 +25,11 @@ class KYCContract {
|
|
|
28
25
|
* @returns Transaction ID
|
|
29
26
|
*/
|
|
30
27
|
async registerKYC(params, privateKey) {
|
|
31
|
-
const senderAddress =
|
|
28
|
+
const senderAddress = getAddressFromPrivateKey(privateKey, this.network.version);
|
|
32
29
|
// #region agent log
|
|
33
|
-
|
|
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(() => { });
|
|
34
33
|
// #endregion agent log
|
|
35
34
|
const { address, name } = this.parseContractAddress(this.config.kycRegistryAddress);
|
|
36
35
|
// Ensure commitment is exactly 32 bytes (64 hex chars)
|
|
@@ -39,16 +38,16 @@ class KYCContract {
|
|
|
39
38
|
if (commitmentBuffer.length !== 32) {
|
|
40
39
|
throw new Error(`Invalid commitment length: expected 32 bytes, got ${commitmentBuffer.length}. Hex: ${commitmentHex.substring(0, 20)}...`);
|
|
41
40
|
}
|
|
42
|
-
// Ensure signature is
|
|
41
|
+
// Ensure signature is 64 or 65 bytes (128 or 130 hex chars)
|
|
43
42
|
const signatureHex = params.signature.replace('0x', '');
|
|
44
43
|
const signatureBuffer = Buffer.from(signatureHex, 'hex');
|
|
45
|
-
if (signatureBuffer.length !== 65) {
|
|
46
|
-
throw new Error(`Invalid signature length: expected 65 bytes, got ${signatureBuffer.length}. Hex: ${signatureHex.substring(0, 20)}...`);
|
|
44
|
+
if (signatureBuffer.length !== 64 && signatureBuffer.length !== 65) {
|
|
45
|
+
throw new Error(`Invalid signature length: expected 64 or 65 bytes, got ${signatureBuffer.length}. Hex: ${signatureHex.substring(0, 20)}...`);
|
|
47
46
|
}
|
|
48
47
|
const functionArgs = [
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
48
|
+
bufferCV(commitmentBuffer),
|
|
49
|
+
bufferCV(signatureBuffer),
|
|
50
|
+
uintCV(params.attesterId),
|
|
52
51
|
];
|
|
53
52
|
const txOptions = {
|
|
54
53
|
contractAddress: address,
|
|
@@ -58,14 +57,14 @@ class KYCContract {
|
|
|
58
57
|
senderKey: privateKey,
|
|
59
58
|
fee: 5000, // Increased from 1000 to 5000 microSTX (0.005 STX) for better reliability
|
|
60
59
|
network: this.network,
|
|
61
|
-
anchorMode:
|
|
62
|
-
postConditionMode:
|
|
60
|
+
anchorMode: AnchorMode.Any,
|
|
61
|
+
postConditionMode: PostConditionMode.Allow,
|
|
63
62
|
};
|
|
64
63
|
// #region agent log
|
|
65
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(() => { });
|
|
66
65
|
// #endregion agent log
|
|
67
66
|
try {
|
|
68
|
-
const transaction = await
|
|
67
|
+
const transaction = await makeContractCall(txOptions);
|
|
69
68
|
// #region agent log
|
|
70
69
|
const serializedTx = transaction.serialize();
|
|
71
70
|
const nonceValue = transaction.auth?.spendingCondition?.nonce;
|
|
@@ -76,10 +75,24 @@ class KYCContract {
|
|
|
76
75
|
};
|
|
77
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(() => { });
|
|
78
77
|
// #endregion agent log
|
|
79
|
-
|
|
80
|
-
|
|
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
|
+
try {
|
|
82
|
+
const broadcastResponse = await broadcastTransaction(transaction, this.network);
|
|
83
|
+
return broadcastResponse.txid;
|
|
84
|
+
}
|
|
85
|
+
catch (broadcastError) {
|
|
86
|
+
// Log the error immediately with console.error to ensure we see it
|
|
87
|
+
console.error('broadcastTransaction error:', broadcastError);
|
|
88
|
+
// Re-throw to be caught by outer catch block
|
|
89
|
+
throw broadcastError;
|
|
90
|
+
}
|
|
81
91
|
}
|
|
82
92
|
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
|
|
83
96
|
// Helper function to safely serialize data (handles BigInt)
|
|
84
97
|
const safeStringify = (obj) => {
|
|
85
98
|
try {
|
|
@@ -140,8 +153,9 @@ class KYCContract {
|
|
|
140
153
|
errorType: error?.constructor?.name,
|
|
141
154
|
status: error?.status,
|
|
142
155
|
statusText: error?.statusText,
|
|
156
|
+
message: error?.message,
|
|
143
157
|
};
|
|
144
|
-
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:
|
|
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(() => { });
|
|
145
159
|
// #endregion agent log
|
|
146
160
|
// Capture detailed error information
|
|
147
161
|
let errorMessage = 'Transaction failed';
|
|
@@ -195,12 +209,27 @@ class KYCContract {
|
|
|
195
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(() => { });
|
|
196
210
|
}
|
|
197
211
|
// #endregion agent log
|
|
212
|
+
// Extract error details from response body for user-friendly messages
|
|
213
|
+
let userFriendlyMessage = errorMessage;
|
|
214
|
+
if (responseBody && typeof responseBody === 'object') {
|
|
215
|
+
if (responseBody.reason === 'NotEnoughFunds') {
|
|
216
|
+
const expected = responseBody.reason_data?.expected;
|
|
217
|
+
const expectedStx = expected ? (parseInt(expected, 16) / 1000000).toFixed(6) : '0.005';
|
|
218
|
+
userFriendlyMessage = `Insufficient STX balance. You need at least ${expectedStx} STX to pay for the transaction fee. Please fund your account with STX and try again.`;
|
|
219
|
+
}
|
|
220
|
+
else if (responseBody.reason) {
|
|
221
|
+
userFriendlyMessage = `Transaction rejected: ${responseBody.reason}${responseBody.error ? ' - ' + responseBody.error : ''}`;
|
|
222
|
+
}
|
|
223
|
+
else if (responseBody.error) {
|
|
224
|
+
userFriendlyMessage = responseBody.error;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
198
227
|
// Log the full error for debugging (using safe extraction)
|
|
199
228
|
const safeErrorDetails = safeExtract(errorDetails);
|
|
200
229
|
console.error('Transaction broadcast error:', safeErrorDetails);
|
|
201
230
|
// Provide detailed error message
|
|
202
|
-
const detailedMessage = typeof responseBody === 'string' ? responseBody : (errorDetails.response || errorDetails.reason || errorDetails.apiError || errorDetails.data || errorMessage);
|
|
203
|
-
throw new Error(
|
|
231
|
+
const detailedMessage = userFriendlyMessage || (typeof responseBody === 'string' ? responseBody : (errorDetails.response || errorDetails.reason || errorDetails.apiError || errorDetails.data || errorMessage));
|
|
232
|
+
throw new Error(detailedMessage);
|
|
204
233
|
}
|
|
205
234
|
}
|
|
206
235
|
/**
|
|
@@ -211,15 +240,15 @@ class KYCContract {
|
|
|
211
240
|
async hasKYC(userPrincipal) {
|
|
212
241
|
const { address, name } = this.parseContractAddress(this.config.kycRegistryAddress);
|
|
213
242
|
try {
|
|
214
|
-
const result = await
|
|
243
|
+
const result = await callReadOnlyFunction({
|
|
215
244
|
contractAddress: address,
|
|
216
245
|
contractName: name,
|
|
217
246
|
functionName: 'has-kyc?',
|
|
218
|
-
functionArgs: [
|
|
247
|
+
functionArgs: [principalCV(userPrincipal)],
|
|
219
248
|
network: this.network,
|
|
220
249
|
senderAddress: address, // Use contract address as sender for read-only calls
|
|
221
250
|
});
|
|
222
|
-
const jsonResult =
|
|
251
|
+
const jsonResult = cvToJSON(result);
|
|
223
252
|
// Result is (ok bool), so check if it's ok and the value is true
|
|
224
253
|
if (jsonResult.type === 'responseOk') {
|
|
225
254
|
const hasKYC = jsonResult.value.value === true;
|
|
@@ -252,15 +281,15 @@ class KYCContract {
|
|
|
252
281
|
async getKYC(userPrincipal) {
|
|
253
282
|
const { address, name } = this.parseContractAddress(this.config.kycRegistryAddress);
|
|
254
283
|
try {
|
|
255
|
-
const result = await
|
|
284
|
+
const result = await callReadOnlyFunction({
|
|
256
285
|
contractAddress: address,
|
|
257
286
|
contractName: name,
|
|
258
287
|
functionName: 'get-kyc',
|
|
259
|
-
functionArgs: [
|
|
288
|
+
functionArgs: [principalCV(userPrincipal)],
|
|
260
289
|
network: this.network,
|
|
261
290
|
senderAddress: address,
|
|
262
291
|
});
|
|
263
|
-
const jsonResult =
|
|
292
|
+
const jsonResult = cvToJSON(result);
|
|
264
293
|
// Result is (ok (some kyc-record)) or (ok none)
|
|
265
294
|
if (jsonResult.type === 'responseOk' && jsonResult.value.type === 'optionalSome') {
|
|
266
295
|
const record = jsonResult.value.value.value;
|
|
@@ -294,4 +323,3 @@ class KYCContract {
|
|
|
294
323
|
};
|
|
295
324
|
}
|
|
296
325
|
}
|
|
297
|
-
exports.KYCContract = KYCContract;
|
package/dist/index.js
CHANGED
|
@@ -1,42 +1,22 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
/**
|
|
3
2
|
* Noah-v2 SDK
|
|
4
3
|
* Main entry point for protocol integration
|
|
5
4
|
*/
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
}) : (function(o, m, k, k2) {
|
|
14
|
-
if (k2 === undefined) k2 = k;
|
|
15
|
-
o[k2] = m[k];
|
|
16
|
-
}));
|
|
17
|
-
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
18
|
-
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
19
|
-
};
|
|
20
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
21
|
-
exports.NoahSDK = exports.WalletHelper = exports.ProofService = exports.KYCContract = void 0;
|
|
22
|
-
var contract_1 = require("./contract");
|
|
23
|
-
Object.defineProperty(exports, "KYCContract", { enumerable: true, get: function () { return contract_1.KYCContract; } });
|
|
24
|
-
var proof_1 = require("./proof");
|
|
25
|
-
Object.defineProperty(exports, "ProofService", { enumerable: true, get: function () { return proof_1.ProofService; } });
|
|
26
|
-
var wallet_1 = require("./wallet");
|
|
27
|
-
Object.defineProperty(exports, "WalletHelper", { enumerable: true, get: function () { return wallet_1.WalletHelper; } });
|
|
28
|
-
__exportStar(require("./types"), exports);
|
|
29
|
-
const contract_2 = require("./contract");
|
|
30
|
-
const proof_2 = require("./proof");
|
|
31
|
-
const wallet_2 = require("./wallet");
|
|
5
|
+
export { KYCContract } from './contract';
|
|
6
|
+
export { ProofService } from './proof';
|
|
7
|
+
export { WalletHelper } from './wallet';
|
|
8
|
+
export * from './types';
|
|
9
|
+
import { KYCContract } from './contract';
|
|
10
|
+
import { ProofService } from './proof';
|
|
11
|
+
import { WalletHelper } from './wallet';
|
|
32
12
|
/**
|
|
33
13
|
* Main SDK class
|
|
34
14
|
*/
|
|
35
|
-
class NoahSDK {
|
|
15
|
+
export class NoahSDK {
|
|
36
16
|
constructor(config, walletConfig) {
|
|
37
|
-
this.contract = new
|
|
38
|
-
this.proof = new
|
|
39
|
-
this.wallet = new
|
|
17
|
+
this.contract = new KYCContract(config);
|
|
18
|
+
this.proof = new ProofService(config);
|
|
19
|
+
this.wallet = new WalletHelper(walletConfig);
|
|
40
20
|
}
|
|
41
21
|
/**
|
|
42
22
|
* Complete KYC registration flow
|
|
@@ -69,6 +49,5 @@ class NoahSDK {
|
|
|
69
49
|
return txId;
|
|
70
50
|
}
|
|
71
51
|
}
|
|
72
|
-
exports.NoahSDK = NoahSDK;
|
|
73
52
|
// Default export
|
|
74
|
-
|
|
53
|
+
export default NoahSDK;
|
package/dist/proof.js
CHANGED
|
@@ -1,10 +1,7 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
/**
|
|
3
2
|
* Proof generation and verification utilities
|
|
4
3
|
*/
|
|
5
|
-
|
|
6
|
-
exports.ProofService = void 0;
|
|
7
|
-
class ProofService {
|
|
4
|
+
export class ProofService {
|
|
8
5
|
constructor(config) {
|
|
9
6
|
this.proverServiceUrl = config.proverServiceUrl || 'http://localhost:8080';
|
|
10
7
|
this.attesterServiceUrl = config.attesterServiceUrl || 'http://localhost:8081';
|
|
@@ -92,4 +89,3 @@ class ProofService {
|
|
|
92
89
|
return await this.generateProof(proofRequest);
|
|
93
90
|
}
|
|
94
91
|
}
|
|
95
|
-
exports.ProofService = ProofService;
|
package/dist/types.js
CHANGED
package/dist/wallet.js
CHANGED
|
@@ -1,10 +1,7 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
/**
|
|
3
2
|
* Wallet integration helpers
|
|
4
3
|
*/
|
|
5
|
-
|
|
6
|
-
exports.WalletHelper = void 0;
|
|
7
|
-
class WalletHelper {
|
|
4
|
+
export class WalletHelper {
|
|
8
5
|
constructor(config) {
|
|
9
6
|
this.config = config;
|
|
10
7
|
}
|
|
@@ -31,4 +28,3 @@ class WalletHelper {
|
|
|
31
28
|
return userData.profile.stxAddress.mainnet || userData.profile.stxAddress.testnet;
|
|
32
29
|
}
|
|
33
30
|
}
|
|
34
|
-
exports.WalletHelper = WalletHelper;
|