noah-avalanche-sdk 0.1.2
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 +892 -0
- package/dist/core/APIClient.d.ts +71 -0
- package/dist/core/APIClient.d.ts.map +1 -0
- package/dist/core/APIClient.js +92 -0
- package/dist/core/APIClient.js.map +1 -0
- package/dist/core/ContractClient.d.ts +38 -0
- package/dist/core/ContractClient.d.ts.map +1 -0
- package/dist/core/ContractClient.js +209 -0
- package/dist/core/ContractClient.js.map +1 -0
- package/dist/core/NoahSDK.d.ts +43 -0
- package/dist/core/NoahSDK.d.ts.map +1 -0
- package/dist/core/NoahSDK.js +93 -0
- package/dist/core/NoahSDK.js.map +1 -0
- package/dist/core/WalletAdapter.d.ts +188 -0
- package/dist/core/WalletAdapter.d.ts.map +1 -0
- package/dist/core/WalletAdapter.js +425 -0
- package/dist/core/WalletAdapter.js.map +1 -0
- package/dist/hooks/index.d.ts +18 -0
- package/dist/hooks/index.d.ts.map +1 -0
- package/dist/hooks/index.js +15 -0
- package/dist/hooks/index.js.map +1 -0
- package/dist/hooks/useCredentials.d.ts +136 -0
- package/dist/hooks/useCredentials.d.ts.map +1 -0
- package/dist/hooks/useCredentials.js +217 -0
- package/dist/hooks/useCredentials.js.map +1 -0
- package/dist/hooks/useProtocol.d.ts +117 -0
- package/dist/hooks/useProtocol.d.ts.map +1 -0
- package/dist/hooks/useProtocol.js +165 -0
- package/dist/hooks/useProtocol.js.map +1 -0
- package/dist/hooks/useUser.d.ts +159 -0
- package/dist/hooks/useUser.d.ts.map +1 -0
- package/dist/hooks/useUser.js +188 -0
- package/dist/hooks/useUser.js.map +1 -0
- package/dist/index.d.ts +28 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +26 -0
- package/dist/index.js.map +1 -0
- package/dist/issuer/IssuerClient.d.ts +98 -0
- package/dist/issuer/IssuerClient.d.ts.map +1 -0
- package/dist/issuer/IssuerClient.js +159 -0
- package/dist/issuer/IssuerClient.js.map +1 -0
- package/dist/protocol/ProtocolClient.d.ts +124 -0
- package/dist/protocol/ProtocolClient.d.ts.map +1 -0
- package/dist/protocol/ProtocolClient.js +265 -0
- package/dist/protocol/ProtocolClient.js.map +1 -0
- package/dist/protocol/RequirementsManager.d.ts +9 -0
- package/dist/protocol/RequirementsManager.d.ts.map +1 -0
- package/dist/protocol/RequirementsManager.js +9 -0
- package/dist/protocol/RequirementsManager.js.map +1 -0
- package/dist/user/ProofGenerator.d.ts +49 -0
- package/dist/user/ProofGenerator.d.ts.map +1 -0
- package/dist/user/ProofGenerator.js +80 -0
- package/dist/user/ProofGenerator.js.map +1 -0
- package/dist/user/UserClient.d.ts +191 -0
- package/dist/user/UserClient.d.ts.map +1 -0
- package/dist/user/UserClient.js +338 -0
- package/dist/user/UserClient.js.map +1 -0
- package/dist/utils/credentials.d.ts +47 -0
- package/dist/utils/credentials.d.ts.map +1 -0
- package/dist/utils/credentials.js +99 -0
- package/dist/utils/credentials.js.map +1 -0
- package/dist/utils/identity.d.ts +22 -0
- package/dist/utils/identity.d.ts.map +1 -0
- package/dist/utils/identity.js +35 -0
- package/dist/utils/identity.js.map +1 -0
- package/dist/utils/jurisdiction.d.ts +21 -0
- package/dist/utils/jurisdiction.d.ts.map +1 -0
- package/dist/utils/jurisdiction.js +64 -0
- package/dist/utils/jurisdiction.js.map +1 -0
- package/dist/utils/mrz.d.ts +16 -0
- package/dist/utils/mrz.d.ts.map +1 -0
- package/dist/utils/mrz.js +91 -0
- package/dist/utils/mrz.js.map +1 -0
- package/dist/utils/ocr.d.ts +31 -0
- package/dist/utils/ocr.d.ts.map +1 -0
- package/dist/utils/ocr.js +69 -0
- package/dist/utils/ocr.js.map +1 -0
- package/dist/utils/types.d.ts +122 -0
- package/dist/utils/types.d.ts.map +1 -0
- package/dist/utils/types.js +2 -0
- package/dist/utils/types.js.map +1 -0
- package/package.json +53 -0
- package/src/core/APIClient.ts +165 -0
- package/src/core/ContractClient.ts +266 -0
- package/src/core/NoahSDK.ts +123 -0
- package/src/core/WalletAdapter.ts +546 -0
- package/src/hooks/index.ts +31 -0
- package/src/hooks/types.d.ts +18 -0
- package/src/hooks/useCredentials.ts +359 -0
- package/src/hooks/useProtocol.ts +284 -0
- package/src/hooks/useUser.ts +331 -0
- package/src/index.ts +80 -0
- package/src/issuer/IssuerClient.ts +209 -0
- package/src/protocol/ProtocolClient.ts +330 -0
- package/src/protocol/RequirementsManager.ts +16 -0
- package/src/user/ProofGenerator.ts +113 -0
- package/src/user/UserClient.ts +440 -0
- package/src/utils/credentials.ts +122 -0
- package/src/utils/identity.ts +46 -0
- package/src/utils/jurisdiction.ts +83 -0
- package/src/utils/mrz.ts +113 -0
- package/src/utils/ocr.ts +84 -0
- package/src/utils/types.ts +144 -0
package/README.md
ADDED
|
@@ -0,0 +1,892 @@
|
|
|
1
|
+
# @noah-protocol/sdk
|
|
2
|
+
|
|
3
|
+
**NOAH SDK** - Privacy-Preserving KYC with Selective Disclosure for DeFi
|
|
4
|
+
|
|
5
|
+
A TypeScript/JavaScript SDK that enables DeFi protocols and developers to easily integrate NOAH's privacy-preserving KYC functionality into their applications. The SDK provides high-level APIs for protocols, users, and issuers to interact with the NOAH smart contracts and backend services.
|
|
6
|
+
|
|
7
|
+
## Table of Contents
|
|
8
|
+
|
|
9
|
+
- [Overview](#overview)
|
|
10
|
+
- [Installation](#installation)
|
|
11
|
+
- [Quick Start](#quick-start)
|
|
12
|
+
- [API Reference](#api-reference)
|
|
13
|
+
- [ProtocolClient](#protocolclient)
|
|
14
|
+
- [UserClient](#userclient)
|
|
15
|
+
- [ContractClient](#contractclient)
|
|
16
|
+
- [APIClient](#apiclient)
|
|
17
|
+
- [IssuerClient](#issuerclient)
|
|
18
|
+
- [Utilities](#utilities)
|
|
19
|
+
- [React Hooks](#react-hooks)
|
|
20
|
+
- [Usage Examples](#usage-examples)
|
|
21
|
+
- [Type Definitions](#type-definitions)
|
|
22
|
+
- [Migration Guide](#migration-guide)
|
|
23
|
+
- [Advanced Usage](#advanced-usage)
|
|
24
|
+
- [Troubleshooting](#troubleshooting)
|
|
25
|
+
- [License](#license)
|
|
26
|
+
|
|
27
|
+
## Overview
|
|
28
|
+
|
|
29
|
+
The NOAH SDK provides a clean, type-safe interface for interacting with the NOAH protocol. It abstracts away the complexity of smart contract interactions and proof generation, making it easy to:
|
|
30
|
+
|
|
31
|
+
- **For DeFi Protocols**: Set KYC requirements and verify user access
|
|
32
|
+
- **For End Users**: Generate ZK proofs and verify access to protocols
|
|
33
|
+
- **For Issuers**: Register and manage KYC credentials
|
|
34
|
+
|
|
35
|
+
### Key Features
|
|
36
|
+
|
|
37
|
+
- 🔒 **Privacy-Preserving**: Personal data never leaves the user's device
|
|
38
|
+
- ✅ **Type-Safe**: Full TypeScript support with comprehensive type definitions
|
|
39
|
+
- 🚀 **Easy Integration**: Simple, high-level APIs for common operations
|
|
40
|
+
- 🔌 **Wallet Agnostic**: Works with any ethers.js-compatible wallet
|
|
41
|
+
- 📦 **Modular**: Import only what you need
|
|
42
|
+
- ⚛️ **React Support**: Optional React hooks for easy integration
|
|
43
|
+
|
|
44
|
+
## Installation
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
npm install @noah-protocol/sdk ethers
|
|
48
|
+
# or
|
|
49
|
+
yarn add @noah-protocol/sdk ethers
|
|
50
|
+
# or
|
|
51
|
+
pnpm add @noah-protocol/sdk ethers
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### Peer Dependencies
|
|
55
|
+
|
|
56
|
+
- `ethers` (^6.9.0) - Required for blockchain interactions
|
|
57
|
+
- `react` (^18.0.0) - Optional, only needed for React hooks
|
|
58
|
+
|
|
59
|
+
## Quick Start
|
|
60
|
+
|
|
61
|
+
### For DeFi Protocols
|
|
62
|
+
|
|
63
|
+
```typescript
|
|
64
|
+
import { ProtocolClient } from '@noah-protocol/sdk';
|
|
65
|
+
import { ethers } from 'ethers';
|
|
66
|
+
|
|
67
|
+
// Connect wallet
|
|
68
|
+
const provider = new ethers.BrowserProvider(window.ethereum);
|
|
69
|
+
const signer = await provider.getSigner();
|
|
70
|
+
|
|
71
|
+
// Initialize protocol client
|
|
72
|
+
const protocol = new ProtocolClient(signer);
|
|
73
|
+
|
|
74
|
+
// Set KYC requirements
|
|
75
|
+
await protocol.setRequirements({
|
|
76
|
+
minAge: 21,
|
|
77
|
+
jurisdictions: ['US', 'UK', 'CA'],
|
|
78
|
+
requireAccredited: true
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
// Check if a user has access
|
|
82
|
+
const hasAccess = await protocol.checkUserAccess(
|
|
83
|
+
await signer.getAddress(), // protocol address
|
|
84
|
+
'0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb' // user address
|
|
85
|
+
);
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### For End Users
|
|
89
|
+
|
|
90
|
+
```typescript
|
|
91
|
+
import { UserClient } from '@noah-protocol/sdk';
|
|
92
|
+
import { ethers } from 'ethers';
|
|
93
|
+
|
|
94
|
+
// Connect wallet
|
|
95
|
+
const provider = new ethers.BrowserProvider(window.ethereum);
|
|
96
|
+
const signer = await provider.getSigner();
|
|
97
|
+
|
|
98
|
+
// Initialize user client
|
|
99
|
+
const user = new UserClient(signer, {
|
|
100
|
+
apiBaseUrl: 'https://api.noah.xyz'
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
// Get protocol requirements
|
|
104
|
+
const requirements = await user.getProtocolRequirements(protocolAddress);
|
|
105
|
+
|
|
106
|
+
// Generate proof (requires credential data)
|
|
107
|
+
const proof = await user.generateProof({
|
|
108
|
+
credential: {
|
|
109
|
+
age: 25,
|
|
110
|
+
jurisdiction: 'US',
|
|
111
|
+
accredited: true,
|
|
112
|
+
credentialHash: '0x...'
|
|
113
|
+
},
|
|
114
|
+
requirements
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
// Verify and grant access
|
|
118
|
+
await user.verifyAndGrantAccess({
|
|
119
|
+
proof,
|
|
120
|
+
protocolAddress,
|
|
121
|
+
credentialHash: '0x...'
|
|
122
|
+
});
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
## API Reference
|
|
126
|
+
|
|
127
|
+
### ProtocolClient
|
|
128
|
+
|
|
129
|
+
High-level API for DeFi protocols to manage KYC requirements and verify user access.
|
|
130
|
+
|
|
131
|
+
#### Constructor
|
|
132
|
+
|
|
133
|
+
```typescript
|
|
134
|
+
new ProtocolClient(signer: Signer, config?: ProtocolClientConfig)
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
**Parameters:**
|
|
138
|
+
- `signer: Signer` - An ethers.js Signer instance (from wallet)
|
|
139
|
+
- `config?: ProtocolClientConfig` - Optional configuration
|
|
140
|
+
- `protocolAccessControlAddress?: string` - Custom contract address
|
|
141
|
+
- `provider?: Provider` - Custom provider for read operations
|
|
142
|
+
|
|
143
|
+
#### Methods
|
|
144
|
+
|
|
145
|
+
##### `setRequirements(params: SetRequirementsParams): Promise<TransactionResult>`
|
|
146
|
+
|
|
147
|
+
Set KYC requirements for the protocol.
|
|
148
|
+
|
|
149
|
+
```typescript
|
|
150
|
+
await protocol.setRequirements({
|
|
151
|
+
minAge: 21,
|
|
152
|
+
jurisdictions: ['US', 'UK', 'CA'], // or jurisdiction hashes
|
|
153
|
+
requireAccredited: true
|
|
154
|
+
});
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
**Parameters:**
|
|
158
|
+
- `minAge: number` - Minimum age required
|
|
159
|
+
- `jurisdictions: string[] | number[]` - Array of allowed jurisdictions (country codes or hashes)
|
|
160
|
+
- `requireAccredited: boolean` - Whether accredited investor status is required
|
|
161
|
+
|
|
162
|
+
**Returns:** `Promise<TransactionResult>` - Transaction hash and receipt
|
|
163
|
+
|
|
164
|
+
##### `getRequirements(protocolAddress: string): Promise<Requirements>`
|
|
165
|
+
|
|
166
|
+
Get the requirements for a protocol.
|
|
167
|
+
|
|
168
|
+
```typescript
|
|
169
|
+
const requirements = await protocol.getRequirements(protocolAddress);
|
|
170
|
+
// Returns: { minAge: 21, allowedJurisdictions: [...], requireAccredited: true }
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
**Parameters:**
|
|
174
|
+
- `protocolAddress: string` - The protocol contract address
|
|
175
|
+
|
|
176
|
+
**Returns:** `Promise<Requirements>` - Protocol requirements
|
|
177
|
+
|
|
178
|
+
##### `checkUserAccess(protocolAddress: string, userAddress: string): Promise<boolean>`
|
|
179
|
+
|
|
180
|
+
Check if a user has access to a protocol.
|
|
181
|
+
|
|
182
|
+
```typescript
|
|
183
|
+
const hasAccess = await protocol.checkUserAccess(protocolAddress, userAddress);
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
**Parameters:**
|
|
187
|
+
- `protocolAddress: string` - The protocol contract address
|
|
188
|
+
- `userAddress: string` - The user's wallet address
|
|
189
|
+
|
|
190
|
+
**Returns:** `Promise<boolean>` - True if user has access
|
|
191
|
+
|
|
192
|
+
##### `verifyAndGrantAccess(params: VerifyUserAccessParams): Promise<TransactionResult>`
|
|
193
|
+
|
|
194
|
+
Verify a ZK proof and grant access to a user.
|
|
195
|
+
|
|
196
|
+
```typescript
|
|
197
|
+
await protocol.verifyAndGrantAccess({
|
|
198
|
+
userAddress: '0x...',
|
|
199
|
+
proof: { a: [...], b: [...], c: [...] },
|
|
200
|
+
publicSignals: [...],
|
|
201
|
+
credentialHash: '0x...'
|
|
202
|
+
});
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
**Parameters:**
|
|
206
|
+
- `userAddress: string` - User's wallet address
|
|
207
|
+
- `proof: Proof` - ZK proof object
|
|
208
|
+
- `publicSignals: string[] | number[]` - Public signals from proof
|
|
209
|
+
- `credentialHash: string` - Credential hash (bytes32)
|
|
210
|
+
|
|
211
|
+
**Returns:** `Promise<TransactionResult>` - Transaction hash and receipt
|
|
212
|
+
|
|
213
|
+
### UserClient
|
|
214
|
+
|
|
215
|
+
High-level API for end-users to interact with protocols and generate proofs.
|
|
216
|
+
|
|
217
|
+
#### Constructor
|
|
218
|
+
|
|
219
|
+
```typescript
|
|
220
|
+
new UserClient(signer: Signer, config?: UserClientConfig)
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
**Parameters:**
|
|
224
|
+
- `signer: Signer` - An ethers.js Signer instance
|
|
225
|
+
- `config?: UserClientConfig` - Optional configuration
|
|
226
|
+
- `apiBaseUrl?: string` - Backend API base URL (default: 'http://localhost:3000/api/v1')
|
|
227
|
+
- `protocolAccessControlAddress?: string` - Custom contract address
|
|
228
|
+
- `provider?: Provider` - Custom provider for read operations
|
|
229
|
+
|
|
230
|
+
#### Methods
|
|
231
|
+
|
|
232
|
+
##### `generateProof(proofData: ProofGenerationData): Promise<ProofResult>`
|
|
233
|
+
|
|
234
|
+
Generate a ZK proof for credential verification.
|
|
235
|
+
|
|
236
|
+
```typescript
|
|
237
|
+
const proof = await user.generateProof({
|
|
238
|
+
credential: {
|
|
239
|
+
age: 25,
|
|
240
|
+
jurisdiction: 'US',
|
|
241
|
+
accredited: true,
|
|
242
|
+
credentialHash: '0x...'
|
|
243
|
+
},
|
|
244
|
+
requirements: {
|
|
245
|
+
minAge: 21,
|
|
246
|
+
allowedJurisdictions: ['US', 'UK'],
|
|
247
|
+
requireAccredited: true
|
|
248
|
+
}
|
|
249
|
+
});
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
**Parameters:**
|
|
253
|
+
- `credential: Credential` - User's credential data
|
|
254
|
+
- `requirements: Requirements` - Protocol requirements
|
|
255
|
+
|
|
256
|
+
**Returns:** `Promise<ProofResult>` - Generated proof and public signals
|
|
257
|
+
|
|
258
|
+
##### `verifyAndGrantAccess(params: VerifyAndGrantAccessParams): Promise<TransactionResult>`
|
|
259
|
+
|
|
260
|
+
Verify proof and grant access to a protocol.
|
|
261
|
+
|
|
262
|
+
```typescript
|
|
263
|
+
await user.verifyAndGrantAccess({
|
|
264
|
+
proof: { a: [...], b: [...], c: [...] },
|
|
265
|
+
publicSignals: [...],
|
|
266
|
+
protocolAddress: '0x...',
|
|
267
|
+
credentialHash: '0x...'
|
|
268
|
+
});
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
**Parameters:**
|
|
272
|
+
- `proof: Proof` - ZK proof object
|
|
273
|
+
- `publicSignals: string[] | number[]` - Public signals
|
|
274
|
+
- `protocolAddress: string` - Protocol contract address
|
|
275
|
+
- `credentialHash: string` - Credential hash
|
|
276
|
+
|
|
277
|
+
**Returns:** `Promise<TransactionResult>` - Transaction hash and receipt
|
|
278
|
+
|
|
279
|
+
##### `checkCredentialValidity(credentialHash: string): Promise<boolean>`
|
|
280
|
+
|
|
281
|
+
Check if a credential is valid (exists and not revoked).
|
|
282
|
+
|
|
283
|
+
```typescript
|
|
284
|
+
const isValid = await user.checkCredentialValidity(credentialHash);
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
**Parameters:**
|
|
288
|
+
- `credentialHash: string` - Credential hash to check
|
|
289
|
+
|
|
290
|
+
**Returns:** `Promise<boolean>` - True if credential is valid
|
|
291
|
+
|
|
292
|
+
##### `getProtocolRequirements(protocolAddress: string): Promise<Requirements>`
|
|
293
|
+
|
|
294
|
+
Get requirements for a protocol.
|
|
295
|
+
|
|
296
|
+
```typescript
|
|
297
|
+
const requirements = await user.getProtocolRequirements(protocolAddress);
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
**Parameters:**
|
|
301
|
+
- `protocolAddress: string` - Protocol contract address
|
|
302
|
+
|
|
303
|
+
**Returns:** `Promise<Requirements>` - Protocol requirements
|
|
304
|
+
|
|
305
|
+
### ContractClient
|
|
306
|
+
|
|
307
|
+
Low-level client for direct smart contract interactions.
|
|
308
|
+
|
|
309
|
+
#### Constructor
|
|
310
|
+
|
|
311
|
+
```typescript
|
|
312
|
+
new ContractClient(provider?: Provider, config?: ContractClientConfig)
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
**Parameters:**
|
|
316
|
+
- `provider?: Provider` - Optional provider (defaults to RPC provider)
|
|
317
|
+
- `config?: ContractClientConfig` - Optional configuration with contract addresses
|
|
318
|
+
|
|
319
|
+
#### Methods
|
|
320
|
+
|
|
321
|
+
##### `isCredentialValid(credentialHash: string): Promise<boolean>`
|
|
322
|
+
|
|
323
|
+
Check if a credential is valid.
|
|
324
|
+
|
|
325
|
+
##### `hasAccess(protocolAddress: string, userAddress: string): Promise<boolean>`
|
|
326
|
+
|
|
327
|
+
Check if user has access to a protocol.
|
|
328
|
+
|
|
329
|
+
##### `getRequirements(protocolAddress: string): Promise<Requirements>`
|
|
330
|
+
|
|
331
|
+
Get protocol requirements.
|
|
332
|
+
|
|
333
|
+
##### `getUserCredential(protocolAddress: string, userAddress: string): Promise<string>`
|
|
334
|
+
|
|
335
|
+
Get user's credential hash for a protocol.
|
|
336
|
+
|
|
337
|
+
##### `getIssuerInfo(issuerAddress: string): Promise<IssuerInfo>`
|
|
338
|
+
|
|
339
|
+
Get issuer information.
|
|
340
|
+
|
|
341
|
+
##### `setRequirements(signer: Signer, minAge: number, allowedJurisdictions: string[] | number[], requireAccredited: boolean): Promise<TransactionResult>`
|
|
342
|
+
|
|
343
|
+
Set protocol requirements (requires signer).
|
|
344
|
+
|
|
345
|
+
##### `registerCredential(signer: Signer, credentialHash: string, userAddress: string): Promise<TransactionResult>`
|
|
346
|
+
|
|
347
|
+
Register a credential (requires issuer signer).
|
|
348
|
+
|
|
349
|
+
##### `revokeCredential(signer: Signer, credentialHash: string): Promise<TransactionResult>`
|
|
350
|
+
|
|
351
|
+
Revoke a credential (requires issuer signer).
|
|
352
|
+
|
|
353
|
+
##### `verifyAndGrantAccess(signer: Signer, proof: Proof, publicSignals: string[] | number[], credentialHash: string, userAddress: string): Promise<TransactionResult>`
|
|
354
|
+
|
|
355
|
+
Verify proof and grant access (requires protocol signer).
|
|
356
|
+
|
|
357
|
+
### APIClient
|
|
358
|
+
|
|
359
|
+
Client for interacting with the NOAH backend API.
|
|
360
|
+
|
|
361
|
+
#### Constructor
|
|
362
|
+
|
|
363
|
+
```typescript
|
|
364
|
+
new APIClient(config?: APIClientConfig)
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
**Parameters:**
|
|
368
|
+
- `config?: APIClientConfig` - Optional configuration
|
|
369
|
+
- `baseURL?: string` - API base URL
|
|
370
|
+
- `timeout?: number` - Request timeout in ms
|
|
371
|
+
- `authToken?: string` - Authentication token
|
|
372
|
+
|
|
373
|
+
#### Methods
|
|
374
|
+
|
|
375
|
+
##### `generateProof(proofData: ProofGenerationData): Promise<ProofResult>`
|
|
376
|
+
|
|
377
|
+
Generate a ZK proof via the backend API.
|
|
378
|
+
|
|
379
|
+
##### `getProtocolRequirements(protocolAddress: string): Promise<Requirements>`
|
|
380
|
+
|
|
381
|
+
Get protocol requirements from API.
|
|
382
|
+
|
|
383
|
+
##### `checkAccess(protocolAddress: string, userAddress: string): Promise<AccessStatus>`
|
|
384
|
+
|
|
385
|
+
Check user access status from API.
|
|
386
|
+
|
|
387
|
+
##### `registerCredential(credentialHash: string, userAddress: string): Promise<TransactionResult>`
|
|
388
|
+
|
|
389
|
+
Register a credential via API (issuer only).
|
|
390
|
+
|
|
391
|
+
##### `revokeCredential(credentialHash: string): Promise<TransactionResult>`
|
|
392
|
+
|
|
393
|
+
Revoke a credential via API (issuer only).
|
|
394
|
+
|
|
395
|
+
### IssuerClient
|
|
396
|
+
|
|
397
|
+
High-level API for credential issuers.
|
|
398
|
+
|
|
399
|
+
#### Constructor
|
|
400
|
+
|
|
401
|
+
```typescript
|
|
402
|
+
new IssuerClient(signer: Signer, config?: IssuerClientConfig)
|
|
403
|
+
```
|
|
404
|
+
|
|
405
|
+
#### Methods
|
|
406
|
+
|
|
407
|
+
##### `registerCredential(credentialHash: string, userAddress: string): Promise<TransactionResult>`
|
|
408
|
+
|
|
409
|
+
Register a credential on-chain.
|
|
410
|
+
|
|
411
|
+
##### `revokeCredential(credentialHash: string): Promise<TransactionResult>`
|
|
412
|
+
|
|
413
|
+
Revoke a credential.
|
|
414
|
+
|
|
415
|
+
##### `checkCredential(credentialHash: string): Promise<CredentialStatus>`
|
|
416
|
+
|
|
417
|
+
Check credential status.
|
|
418
|
+
|
|
419
|
+
### Utilities
|
|
420
|
+
|
|
421
|
+
#### Jurisdiction Utilities
|
|
422
|
+
|
|
423
|
+
```typescript
|
|
424
|
+
import { jurisdictionStringToHash, jurisdictionStringsToHashes, parseJurisdictions } from '@noah-protocol/sdk';
|
|
425
|
+
|
|
426
|
+
// Convert single jurisdiction
|
|
427
|
+
const hash = jurisdictionStringToHash('US'); // Returns hash as string
|
|
428
|
+
|
|
429
|
+
// Convert multiple jurisdictions
|
|
430
|
+
const hashes = jurisdictionStringsToHashes(['US', 'UK', 'CA']);
|
|
431
|
+
|
|
432
|
+
// Parse comma-separated string
|
|
433
|
+
const hashes = parseJurisdictions('US, UK, CA');
|
|
434
|
+
```
|
|
435
|
+
|
|
436
|
+
#### Credential Utilities
|
|
437
|
+
|
|
438
|
+
```typescript
|
|
439
|
+
import { computeCredentialHash } from '@noah-protocol/sdk';
|
|
440
|
+
|
|
441
|
+
// Compute credential hash from credential data
|
|
442
|
+
const hash = computeCredentialHash({
|
|
443
|
+
age: 25,
|
|
444
|
+
jurisdiction: 'US',
|
|
445
|
+
accredited: true
|
|
446
|
+
});
|
|
447
|
+
```
|
|
448
|
+
|
|
449
|
+
### React Hooks
|
|
450
|
+
|
|
451
|
+
Optional React hooks for easy integration in React applications.
|
|
452
|
+
|
|
453
|
+
#### `useProtocol(signer: Signer | null)`
|
|
454
|
+
|
|
455
|
+
Hook for protocol operations.
|
|
456
|
+
|
|
457
|
+
```typescript
|
|
458
|
+
import { useProtocol } from '@noah-protocol/sdk';
|
|
459
|
+
|
|
460
|
+
function ProtocolComponent() {
|
|
461
|
+
const { setRequirements, checkUserAccess, isLoading } = useProtocol(signer);
|
|
462
|
+
|
|
463
|
+
// Use the methods...
|
|
464
|
+
}
|
|
465
|
+
```
|
|
466
|
+
|
|
467
|
+
#### `useUser(signer: Signer | null, config?: UserClientConfig)`
|
|
468
|
+
|
|
469
|
+
Hook for user operations.
|
|
470
|
+
|
|
471
|
+
```typescript
|
|
472
|
+
import { useUser } from '@noah-protocol/sdk';
|
|
473
|
+
|
|
474
|
+
function UserComponent() {
|
|
475
|
+
const { generateProof, verifyAndGrantAccess, isLoading } = useUser(signer);
|
|
476
|
+
|
|
477
|
+
// Use the methods...
|
|
478
|
+
}
|
|
479
|
+
```
|
|
480
|
+
|
|
481
|
+
#### `useCredentials()`
|
|
482
|
+
|
|
483
|
+
Hook for credential management.
|
|
484
|
+
|
|
485
|
+
```typescript
|
|
486
|
+
import { useCredentials } from '@noah-protocol/sdk';
|
|
487
|
+
|
|
488
|
+
function CredentialComponent() {
|
|
489
|
+
const { checkValidity, getCredential } = useCredentials();
|
|
490
|
+
|
|
491
|
+
// Use the methods...
|
|
492
|
+
}
|
|
493
|
+
```
|
|
494
|
+
|
|
495
|
+
## Usage Examples
|
|
496
|
+
|
|
497
|
+
### Example 1: DeFi Protocol Integration
|
|
498
|
+
|
|
499
|
+
```typescript
|
|
500
|
+
import { ProtocolClient } from '@noah-protocol/sdk';
|
|
501
|
+
import { ethers } from 'ethers';
|
|
502
|
+
|
|
503
|
+
async function setupProtocol() {
|
|
504
|
+
// Connect wallet
|
|
505
|
+
const provider = new ethers.BrowserProvider(window.ethereum);
|
|
506
|
+
const signer = await provider.getSigner();
|
|
507
|
+
|
|
508
|
+
// Initialize client
|
|
509
|
+
const protocol = new ProtocolClient(signer);
|
|
510
|
+
|
|
511
|
+
// Set requirements
|
|
512
|
+
const tx = await protocol.setRequirements({
|
|
513
|
+
minAge: 21,
|
|
514
|
+
jurisdictions: ['US', 'UK', 'CA'],
|
|
515
|
+
requireAccredited: false
|
|
516
|
+
});
|
|
517
|
+
|
|
518
|
+
console.log('Requirements set:', tx.transactionHash);
|
|
519
|
+
|
|
520
|
+
// Check user access
|
|
521
|
+
const userAddress = '0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb';
|
|
522
|
+
const hasAccess = await protocol.checkUserAccess(
|
|
523
|
+
await signer.getAddress(),
|
|
524
|
+
userAddress
|
|
525
|
+
);
|
|
526
|
+
|
|
527
|
+
console.log('User has access:', hasAccess);
|
|
528
|
+
}
|
|
529
|
+
```
|
|
530
|
+
|
|
531
|
+
### Example 2: User Access Flow
|
|
532
|
+
|
|
533
|
+
```typescript
|
|
534
|
+
import { UserClient } from '@noah-protocol/sdk';
|
|
535
|
+
import { ethers } from 'ethers';
|
|
536
|
+
|
|
537
|
+
async function requestAccess() {
|
|
538
|
+
// Connect wallet
|
|
539
|
+
const provider = new ethers.BrowserProvider(window.ethereum);
|
|
540
|
+
const signer = await provider.getSigner();
|
|
541
|
+
|
|
542
|
+
// Initialize user client
|
|
543
|
+
const user = new UserClient(signer, {
|
|
544
|
+
apiBaseUrl: 'https://api.noah.xyz'
|
|
545
|
+
});
|
|
546
|
+
|
|
547
|
+
const protocolAddress = '0x...';
|
|
548
|
+
|
|
549
|
+
// Get protocol requirements
|
|
550
|
+
const requirements = await user.getProtocolRequirements(protocolAddress);
|
|
551
|
+
console.log('Protocol requires:', requirements);
|
|
552
|
+
|
|
553
|
+
// Check if credential is valid
|
|
554
|
+
const credentialHash = '0x...';
|
|
555
|
+
const isValid = await user.checkCredentialValidity(credentialHash);
|
|
556
|
+
if (!isValid) {
|
|
557
|
+
throw new Error('Credential is invalid or revoked');
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
// Generate proof
|
|
561
|
+
const proofResult = await user.generateProof({
|
|
562
|
+
credential: {
|
|
563
|
+
age: 25,
|
|
564
|
+
jurisdiction: 'US',
|
|
565
|
+
accredited: true,
|
|
566
|
+
credentialHash
|
|
567
|
+
},
|
|
568
|
+
requirements
|
|
569
|
+
});
|
|
570
|
+
|
|
571
|
+
// Verify and grant access
|
|
572
|
+
const tx = await user.verifyAndGrantAccess({
|
|
573
|
+
proof: proofResult.proof,
|
|
574
|
+
publicSignals: proofResult.publicSignals,
|
|
575
|
+
protocolAddress,
|
|
576
|
+
credentialHash
|
|
577
|
+
});
|
|
578
|
+
|
|
579
|
+
console.log('Access granted:', tx.transactionHash);
|
|
580
|
+
}
|
|
581
|
+
```
|
|
582
|
+
|
|
583
|
+
### Example 3: Issuer Credential Management
|
|
584
|
+
|
|
585
|
+
```typescript
|
|
586
|
+
import { IssuerClient } from '@noah-protocol/sdk';
|
|
587
|
+
import { ethers } from 'ethers';
|
|
588
|
+
|
|
589
|
+
async function manageCredentials() {
|
|
590
|
+
// Connect issuer wallet
|
|
591
|
+
const provider = new ethers.BrowserProvider(window.ethereum);
|
|
592
|
+
const signer = await provider.getSigner();
|
|
593
|
+
|
|
594
|
+
// Initialize issuer client
|
|
595
|
+
const issuer = new IssuerClient(signer);
|
|
596
|
+
|
|
597
|
+
// Register credential
|
|
598
|
+
const credentialHash = '0x...';
|
|
599
|
+
const userAddress = '0x...';
|
|
600
|
+
|
|
601
|
+
const tx = await issuer.registerCredential(credentialHash, userAddress);
|
|
602
|
+
console.log('Credential registered:', tx.transactionHash);
|
|
603
|
+
|
|
604
|
+
// Later, revoke credential if needed
|
|
605
|
+
const revokeTx = await issuer.revokeCredential(credentialHash);
|
|
606
|
+
console.log('Credential revoked:', revokeTx.transactionHash);
|
|
607
|
+
}
|
|
608
|
+
```
|
|
609
|
+
|
|
610
|
+
### Example 4: React Integration
|
|
611
|
+
|
|
612
|
+
```typescript
|
|
613
|
+
import { useProtocol, useUser } from '@noah-protocol/sdk';
|
|
614
|
+
import { ethers } from 'ethers';
|
|
615
|
+
import { useState, useEffect } from 'react';
|
|
616
|
+
|
|
617
|
+
function ProtocolDashboard() {
|
|
618
|
+
const [signer, setSigner] = useState<ethers.Signer | null>(null);
|
|
619
|
+
const { setRequirements, checkUserAccess, isLoading } = useProtocol(signer);
|
|
620
|
+
const { generateProof, verifyAndGrantAccess } = useUser(signer);
|
|
621
|
+
|
|
622
|
+
useEffect(() => {
|
|
623
|
+
async function connectWallet() {
|
|
624
|
+
const provider = new ethers.BrowserProvider(window.ethereum);
|
|
625
|
+
const s = await provider.getSigner();
|
|
626
|
+
setSigner(s);
|
|
627
|
+
}
|
|
628
|
+
connectWallet();
|
|
629
|
+
}, []);
|
|
630
|
+
|
|
631
|
+
const handleSetRequirements = async () => {
|
|
632
|
+
await setRequirements({
|
|
633
|
+
minAge: 21,
|
|
634
|
+
jurisdictions: ['US', 'UK'],
|
|
635
|
+
requireAccredited: false
|
|
636
|
+
});
|
|
637
|
+
};
|
|
638
|
+
|
|
639
|
+
return (
|
|
640
|
+
<div>
|
|
641
|
+
<button onClick={handleSetRequirements} disabled={isLoading}>
|
|
642
|
+
Set Requirements
|
|
643
|
+
</button>
|
|
644
|
+
</div>
|
|
645
|
+
);
|
|
646
|
+
}
|
|
647
|
+
```
|
|
648
|
+
|
|
649
|
+
## Type Definitions
|
|
650
|
+
|
|
651
|
+
### Core Types
|
|
652
|
+
|
|
653
|
+
```typescript
|
|
654
|
+
// Protocol requirements
|
|
655
|
+
interface Requirements {
|
|
656
|
+
minAge: number;
|
|
657
|
+
allowedJurisdictions: string[] | number[];
|
|
658
|
+
requireAccredited: boolean;
|
|
659
|
+
isSet?: boolean;
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
// ZK Proof (Groth16 format)
|
|
663
|
+
interface Proof {
|
|
664
|
+
a: [string, string];
|
|
665
|
+
b: [[string, string], [string, string]];
|
|
666
|
+
c: [string, string];
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
// Transaction result
|
|
670
|
+
interface TransactionResult {
|
|
671
|
+
transactionHash: string;
|
|
672
|
+
receipt: ContractTransactionReceipt | null;
|
|
673
|
+
}
|
|
674
|
+
|
|
675
|
+
// Credential data
|
|
676
|
+
interface Credential {
|
|
677
|
+
age: number;
|
|
678
|
+
jurisdiction: string;
|
|
679
|
+
accredited: boolean;
|
|
680
|
+
credentialHash: string;
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
// Proof generation data
|
|
684
|
+
interface ProofGenerationData {
|
|
685
|
+
credential: Credential;
|
|
686
|
+
requirements: Requirements;
|
|
687
|
+
}
|
|
688
|
+
|
|
689
|
+
// Proof result
|
|
690
|
+
interface ProofResult {
|
|
691
|
+
proof: Proof;
|
|
692
|
+
publicSignals: string[];
|
|
693
|
+
}
|
|
694
|
+
```
|
|
695
|
+
|
|
696
|
+
## Migration Guide
|
|
697
|
+
|
|
698
|
+
If you're currently using the frontend services directly (`contractClient.js`, `apiClient.js`), here's how to migrate to the SDK:
|
|
699
|
+
|
|
700
|
+
### Before (Direct Service Usage)
|
|
701
|
+
|
|
702
|
+
```javascript
|
|
703
|
+
// Old way - using services directly
|
|
704
|
+
import contractClient from './services/contractClient.js';
|
|
705
|
+
import { proofService } from './services/apiClient.js';
|
|
706
|
+
|
|
707
|
+
// Set requirements
|
|
708
|
+
await contractClient.setRequirements(
|
|
709
|
+
signer,
|
|
710
|
+
21,
|
|
711
|
+
['US', 'UK'],
|
|
712
|
+
true
|
|
713
|
+
);
|
|
714
|
+
|
|
715
|
+
// Generate proof
|
|
716
|
+
const proof = await proofService.generateProof({
|
|
717
|
+
credential: { ... },
|
|
718
|
+
requirements: { ... }
|
|
719
|
+
});
|
|
720
|
+
```
|
|
721
|
+
|
|
722
|
+
### After (Using SDK)
|
|
723
|
+
|
|
724
|
+
```typescript
|
|
725
|
+
// New way - using SDK
|
|
726
|
+
import { ProtocolClient, UserClient } from '@noah-protocol/sdk';
|
|
727
|
+
|
|
728
|
+
// Initialize clients
|
|
729
|
+
const protocol = new ProtocolClient(signer);
|
|
730
|
+
const user = new UserClient(signer, { apiBaseUrl: '...' });
|
|
731
|
+
|
|
732
|
+
// Set requirements (cleaner API)
|
|
733
|
+
await protocol.setRequirements({
|
|
734
|
+
minAge: 21,
|
|
735
|
+
jurisdictions: ['US', 'UK'],
|
|
736
|
+
requireAccredited: true
|
|
737
|
+
});
|
|
738
|
+
|
|
739
|
+
// Generate proof (same API, but typed)
|
|
740
|
+
const proofResult = await user.generateProof({
|
|
741
|
+
credential: { ... },
|
|
742
|
+
requirements: { ... }
|
|
743
|
+
});
|
|
744
|
+
```
|
|
745
|
+
|
|
746
|
+
### Key Changes
|
|
747
|
+
|
|
748
|
+
1. **Type Safety**: All methods are now fully typed with TypeScript
|
|
749
|
+
2. **Cleaner API**: Methods use object parameters instead of positional arguments
|
|
750
|
+
3. **Better Error Handling**: Consistent error types across all methods
|
|
751
|
+
4. **Wallet Agnostic**: Works with any ethers.js-compatible wallet
|
|
752
|
+
5. **Modular**: Import only what you need
|
|
753
|
+
|
|
754
|
+
### Migration Steps
|
|
755
|
+
|
|
756
|
+
1. **Install SDK**: `npm install @noah-protocol/sdk`
|
|
757
|
+
2. **Replace Imports**: Replace service imports with SDK imports
|
|
758
|
+
3. **Update Method Calls**: Update to use new API signatures
|
|
759
|
+
4. **Add Types**: Add TypeScript types if using TypeScript
|
|
760
|
+
5. **Test**: Test all functionality to ensure compatibility
|
|
761
|
+
|
|
762
|
+
## Advanced Usage
|
|
763
|
+
|
|
764
|
+
### Custom Contract Addresses
|
|
765
|
+
|
|
766
|
+
```typescript
|
|
767
|
+
const protocol = new ProtocolClient(signer, {
|
|
768
|
+
protocolAccessControlAddress: '0xCustomAddress...'
|
|
769
|
+
});
|
|
770
|
+
```
|
|
771
|
+
|
|
772
|
+
### Custom Provider
|
|
773
|
+
|
|
774
|
+
```typescript
|
|
775
|
+
import { ethers } from 'ethers';
|
|
776
|
+
|
|
777
|
+
const customProvider = new ethers.JsonRpcProvider('https://custom-rpc.com');
|
|
778
|
+
const protocol = new ProtocolClient(signer, {
|
|
779
|
+
provider: customProvider
|
|
780
|
+
});
|
|
781
|
+
```
|
|
782
|
+
|
|
783
|
+
### Event Listeners
|
|
784
|
+
|
|
785
|
+
```typescript
|
|
786
|
+
import { ContractClient } from '@noah-protocol/sdk';
|
|
787
|
+
|
|
788
|
+
const contractClient = new ContractClient();
|
|
789
|
+
|
|
790
|
+
// Listen for credential issued events
|
|
791
|
+
contractClient.onCredentialIssued((user, credentialHash, issuer, timestamp) => {
|
|
792
|
+
console.log('Credential issued:', { user, credentialHash, issuer });
|
|
793
|
+
});
|
|
794
|
+
|
|
795
|
+
// Listen for access granted events
|
|
796
|
+
contractClient.onAccessGranted((user, protocol, credentialHash, timestamp) => {
|
|
797
|
+
console.log('Access granted:', { user, protocol, credentialHash });
|
|
798
|
+
});
|
|
799
|
+
```
|
|
800
|
+
|
|
801
|
+
### Error Handling
|
|
802
|
+
|
|
803
|
+
```typescript
|
|
804
|
+
import { ProtocolClient } from '@noah-protocol/sdk';
|
|
805
|
+
|
|
806
|
+
try {
|
|
807
|
+
await protocol.setRequirements({ ... });
|
|
808
|
+
} catch (error) {
|
|
809
|
+
if (error.code === 'ACTION_REJECTED') {
|
|
810
|
+
console.error('User rejected transaction');
|
|
811
|
+
} else if (error.code === 'INSUFFICIENT_FUNDS') {
|
|
812
|
+
console.error('Insufficient funds');
|
|
813
|
+
} else {
|
|
814
|
+
console.error('Unknown error:', error);
|
|
815
|
+
}
|
|
816
|
+
}
|
|
817
|
+
```
|
|
818
|
+
|
|
819
|
+
## Troubleshooting
|
|
820
|
+
|
|
821
|
+
### Common Issues
|
|
822
|
+
|
|
823
|
+
#### 1. "Signer is required" Error
|
|
824
|
+
|
|
825
|
+
**Problem**: You're trying to call a write operation without a signer.
|
|
826
|
+
|
|
827
|
+
**Solution**: Make sure you pass a signer to the client constructor:
|
|
828
|
+
|
|
829
|
+
```typescript
|
|
830
|
+
const provider = new ethers.BrowserProvider(window.ethereum);
|
|
831
|
+
const signer = await provider.getSigner();
|
|
832
|
+
const protocol = new ProtocolClient(signer); // ✅ Pass signer
|
|
833
|
+
```
|
|
834
|
+
|
|
835
|
+
#### 2. "Requirements not set" Error
|
|
836
|
+
|
|
837
|
+
**Problem**: Trying to verify access before setting requirements.
|
|
838
|
+
|
|
839
|
+
**Solution**: Set requirements first:
|
|
840
|
+
|
|
841
|
+
```typescript
|
|
842
|
+
await protocol.setRequirements({ ... });
|
|
843
|
+
// Then verify access
|
|
844
|
+
```
|
|
845
|
+
|
|
846
|
+
#### 3. "Invalid or revoked credential" Error
|
|
847
|
+
|
|
848
|
+
**Problem**: The credential hash doesn't exist or has been revoked.
|
|
849
|
+
|
|
850
|
+
**Solution**: Check credential validity first:
|
|
851
|
+
|
|
852
|
+
```typescript
|
|
853
|
+
const isValid = await user.checkCredentialValidity(credentialHash);
|
|
854
|
+
if (!isValid) {
|
|
855
|
+
// Handle invalid credential
|
|
856
|
+
}
|
|
857
|
+
```
|
|
858
|
+
|
|
859
|
+
#### 4. Network/Provider Issues
|
|
860
|
+
|
|
861
|
+
**Problem**: Cannot connect to blockchain.
|
|
862
|
+
|
|
863
|
+
**Solution**: Check your provider configuration:
|
|
864
|
+
|
|
865
|
+
```typescript
|
|
866
|
+
const provider = new ethers.BrowserProvider(window.ethereum);
|
|
867
|
+
// Or use custom RPC
|
|
868
|
+
const provider = new ethers.JsonRpcProvider('https://rpc.example.com');
|
|
869
|
+
```
|
|
870
|
+
|
|
871
|
+
#### 5. API Connection Issues
|
|
872
|
+
|
|
873
|
+
**Problem**: Cannot connect to backend API.
|
|
874
|
+
|
|
875
|
+
**Solution**: Check API base URL and network:
|
|
876
|
+
|
|
877
|
+
```typescript
|
|
878
|
+
const user = new UserClient(signer, {
|
|
879
|
+
apiBaseUrl: 'https://api.noah.xyz' // Make sure this is correct
|
|
880
|
+
});
|
|
881
|
+
```
|
|
882
|
+
|
|
883
|
+
### Getting Help
|
|
884
|
+
|
|
885
|
+
- Check the [main NOAH README](../../README.md) for more information
|
|
886
|
+
- Review the [API documentation](#api-reference) for method signatures
|
|
887
|
+
- Check contract addresses in `deployments.json`
|
|
888
|
+
- Verify your network configuration matches the deployed contracts
|
|
889
|
+
|
|
890
|
+
## License
|
|
891
|
+
|
|
892
|
+
MIT
|