@obelyzk/sdk 1.0.1 → 1.2.0

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 CHANGED
@@ -1,481 +1,186 @@
1
- # @bitsage/sdk
1
+ # @obelyzk/sdk
2
2
 
3
- Official TypeScript SDK for the BitSage Network - Decentralized Compute with Privacy.
3
+ TypeScript SDK for ObelyZK -- verifiable ML inference on Starknet.
4
+
5
+ Prove any supported model and get an on-chain verification receipt in a single call. All proofs use full OODS + Merkle + FRI + PoW (trustless) verification.
4
6
 
5
7
  ## Installation
6
8
 
7
9
  ```bash
8
- npm install @bitsage/sdk
9
- # or
10
- yarn add @bitsage/sdk
11
- # or
12
- pnpm add @bitsage/sdk
10
+ npm install @obelyzk/sdk
13
11
  ```
14
12
 
15
- ## Features
16
-
17
- - **Obelysk Privacy Layer** - Client-side ElGamal encryption and Schnorr proofs for private payments
18
- - **STWO GPU Prover** - GPU-accelerated proof generation for batch operations
19
- - **Confidential Swaps** - Trade tokens privately with encrypted amounts
20
- - **Staking & Workers** - Manage stake and worker nodes
21
- - **React Hooks** - Ready-to-use hooks for React applications
22
-
23
- ---
24
-
25
13
  ## Quick Start
26
14
 
27
- ### Basic Setup
28
-
29
15
  ```typescript
30
- import { BitSageClient } from '@bitsage/sdk';
16
+ import { createProverClient } from "@obelyzk/sdk";
31
17
 
32
- const client = new BitSageClient({
33
- network: 'sepolia', // or 'mainnet'
34
- apiKey: 'your-api-key',
35
- });
18
+ const client = createProverClient();
36
19
 
37
- // Submit a compute job
38
- const job = await client.submitJob({
39
- job_type: { type: 'ai_inference', model_type: 'llama-7b', batch_size: 1 },
40
- input_data: btoa('Hello, BitSage!'),
41
- max_cost_sage: 100n,
42
- priority: 5,
20
+ // Prove a model and verify on-chain
21
+ const result = await client.prove({
22
+ model: "smollm2-135m",
23
+ input: [1.0, 2.0, 3.0],
24
+ onChain: true,
43
25
  });
44
26
 
45
- console.log('Job ID:', job.job_id);
27
+ console.log("Output:", result.output);
28
+ console.log("Proof hash:", result.proofHash);
29
+ console.log("TX hash:", result.txHash);
30
+ console.log("Verified:", result.verified);
46
31
  ```
47
32
 
48
- ---
49
-
50
- ## Obelysk Privacy Layer
51
-
52
- The Obelysk Privacy Layer enables fully private on-chain payments using ElGamal encryption and Schnorr zero-knowledge proofs. **All cryptography runs client-side** - no server ever sees your amounts.
53
-
54
- ### Private Payments
55
-
56
- ```typescript
57
- import { ObelyskPrivacy, ConfidentialSwapClient } from '@bitsage/sdk';
58
-
59
- // Initialize privacy module
60
- const privacy = new ObelyskPrivacy();
61
-
62
- // Generate your key pair (store securely!)
63
- const keyPair = privacy.generateKeyPair();
64
- console.log('Public Key:', keyPair.publicKey);
65
-
66
- // Encrypt an amount (only you and recipient can see it)
67
- const amount = 1000n; // 1000 SAGE
68
- const encrypted = privacy.encrypt(amount, recipientPublicKey);
69
- console.log('Encrypted:', encrypted.c1, encrypted.c2);
70
-
71
- // Create a proof that amount is valid (without revealing it)
72
- const proof = privacy.createEncryptionProof(amount, keyPair, encrypted);
33
+ ## API Reference
73
34
 
74
- // Verify proof (anyone can do this)
75
- const isValid = privacy.verifyEncryptionProof(proof, keyPair.publicKey, encrypted);
76
- console.log('Proof valid:', isValid); // true
77
- ```
35
+ ### `createProverClient(options?)`
78
36
 
79
- ### Confidential Swaps
37
+ Create a prover client instance.
80
38
 
81
39
  ```typescript
82
- import { ConfidentialSwapClient } from '@bitsage/sdk';
83
-
84
- const swapClient = new ConfidentialSwapClient({
85
- contractAddress: '0x...',
86
- proverUrl: 'https://prover.bitsage.network',
40
+ const client = createProverClient({
41
+ url: "https://api.obelysk.com", // default; or your own GPU prover
42
+ apiKey: "your-api-key", // optional, for rate limiting
43
+ timeout: 300_000, // request timeout in ms (default: 5 min)
87
44
  });
88
-
89
- // Create a private order (amounts hidden on-chain)
90
- const order = await swapClient.createPrivateOrder({
91
- giveAsset: 'SAGE',
92
- wantAsset: 'USDC',
93
- giveAmount: 1000n,
94
- wantAmount: 100n,
95
- });
96
-
97
- console.log('Order ID:', order.orderId);
98
- console.log('Encrypted amounts:', order.encryptedGive, order.encryptedWant);
99
45
  ```
100
46
 
101
- ### Privacy Operations Reference
102
-
103
- | Operation | Privacy | Speed | Cost |
104
- |-----------|---------|-------|------|
105
- | `encrypt()` | Full | < 1ms | Free |
106
- | `createEncryptionProof()` | Full | ~50ms | Free |
107
- | `createRangeProof()` | Full | ~100ms | Free |
108
- | `verifyProof()` | N/A | < 10ms | Free |
109
- | On-chain verification | Full | N/A | ~$0.03 |
110
-
111
- ---
112
-
113
- ## STWO GPU Prover
47
+ ### `client.prove(request)`
114
48
 
115
- For batch operations and complex computations, use the STWO GPU Prover to generate proofs efficiently.
116
-
117
- ### When to Use STWO GPU
118
-
119
- | Scenario | Recommendation | Savings |
120
- |----------|---------------|---------|
121
- | Single payment | Client-side Schnorr | - |
122
- | 100+ payments | STWO GPU batch | 95% |
123
- | AI/ML inference | STWO GPU | Required |
124
- | Cross-chain bridge | STWO GPU | 98% |
125
- | Gaming state | STWO GPU batch | 99% |
126
-
127
- ### Basic Usage
49
+ Prove an ML model execution and optionally verify on-chain.
128
50
 
129
51
  ```typescript
130
- import { createStwoProverClient, PROOF_TYPES, GPU_TIERS } from '@bitsage/sdk';
131
-
132
- const prover = createStwoProverClient({
133
- baseUrl: 'https://prover.bitsage.network',
134
- apiKey: 'your-api-key',
52
+ const result = await client.prove({
53
+ model: "smollm2-135m", // model name or HuggingFace ID
54
+ input: [1.0, 2.0, 3.0], // input tensor (flat array)
55
+ onChain: true, // submit to Starknet (default: false)
56
+ recursive: true, // use recursive STARK (default: true)
57
+ network: "sepolia", // Starknet network (default: "sepolia")
135
58
  });
136
59
 
137
- // Submit a proof generation job
138
- const job = await prover.submitProofJob({
139
- proofType: PROOF_TYPES.BATCH_PAYMENTS,
140
- publicInputs: [/* payment data */],
141
- priority: 'high',
142
- gpuTier: GPU_TIERS.H100,
143
- });
144
-
145
- console.log('Job ID:', job.jobId);
146
- console.log('Estimated cost:', job.estimatedCostUsdc, 'USDC');
147
- console.log('Estimated time:', job.estimatedTimeSecs, 'seconds');
148
-
149
- // Wait for completion with progress updates
150
- const result = await prover.waitForProof(job.jobId, {
151
- onProgress: (status) => {
152
- console.log(`Progress: ${status.progressBps / 100}%`);
153
- console.log(`Phase: ${status.currentPhase}`);
154
- },
155
- });
156
-
157
- console.log('Proof hash:', result.proofHash);
158
- console.log('Actual cost:', result.costUsdc, 'USDC');
60
+ // result: {
61
+ // output: number[], // model output tensor
62
+ // proofHash: string, // Poseidon hash of the proof
63
+ // txHash?: string, // Starknet TX hash (if onChain: true)
64
+ // verified?: boolean, // on-chain verification status
65
+ // proveTime: number, // proving time in seconds (~102s for SmolLM2)
66
+ // recursiveTime: number, // recursive STARK time (~3.55s)
67
+ // felts: number, // calldata size in felts (~942)
68
+ // modelId: string, // hex model identifier
69
+ // }
159
70
  ```
160
71
 
161
- ### Batch Operations (95-99% Cost Savings)
72
+ ### `client.attest(request)`
162
73
 
163
- ```typescript
164
- // Batch 1000 payments into a single proof
165
- const payments = [
166
- { sender: '0x...', recipient: '0x...', amount: 100n, asset: 'SAGE' },
167
- // ... 999 more payments
168
- ];
169
-
170
- const result = await prover.proveBatchPayments(payments, {
171
- priority: 'high',
172
- requireTee: true, // Use TEE for privacy
173
- });
174
-
175
- // Cost: ~$0.25 instead of $30 (99% savings!)
176
- console.log('Batch proof hash:', result.proofHash);
177
- ```
178
-
179
- ### AI/ML Inference Proofs
74
+ Prove and submit a full attestation with streaming verification.
180
75
 
181
76
  ```typescript
182
- // Prove AI inference was computed correctly
183
- const result = await prover.proveInference(
184
- 'llama-7b', // Model ID
185
- [/* input tokens */], // Inputs
186
- [/* output tokens */], // Outputs
187
- { requireTee: true } // Keep data private
188
- );
189
-
190
- console.log('Inference proof:', result.proofHash);
77
+ const attestation = await client.attest({
78
+ model: "smollm2-135m",
79
+ input: [1.0, 2.0, 3.0],
80
+ submitOnChain: true,
81
+ });
191
82
  ```
192
83
 
193
- ### Cross-Chain Bridge Proofs
194
-
195
- ```typescript
196
- // Prove a transaction occurred on another chain
197
- const result = await prover.proveBridge(
198
- 'ethereum', // Source chain
199
- '0xabc...def', // Transaction hash
200
- ['0x...', '0x...', '0x...'], // Block headers
201
- { priority: 'critical' }
202
- );
203
-
204
- console.log('Bridge proof:', result.proofHash);
205
- ```
84
+ ### `client.getModels()`
206
85
 
207
- ### Recursive Proof Aggregation
86
+ List all available models on the prover.
208
87
 
209
88
  ```typescript
210
- // Aggregate multiple proofs into one
211
- const proofHashes = [
212
- '0x111...',
213
- '0x222...',
214
- '0x333...',
215
- ];
216
-
217
- const aggregated = await prover.aggregateProofs(proofHashes);
218
- console.log('Aggregated proof:', aggregated.proofHash);
219
- // Verify once instead of 3 times!
89
+ const models = await client.getModels();
90
+ // [{ name: "smollm2-135m", params: "135M", layers: 30, ... }, ...]
220
91
  ```
221
92
 
222
- ### Cost Estimation
223
-
224
- ```typescript
225
- // Estimate cost before submitting
226
- const estimate = await prover.estimateCost({
227
- proofType: PROOF_TYPES.BATCH_PAYMENTS,
228
- publicInputs: new Array(1000).fill(0n),
229
- priority: 'high',
230
- requireTee: true,
231
- });
232
-
233
- console.log('Estimated cost:', estimate.costUsdc, 'USDC');
234
- console.log('Breakdown:');
235
- console.log(' Base:', estimate.breakdown.baseCost);
236
- console.log(' Priority:', estimate.breakdown.prioritySurcharge);
237
- console.log(' TEE:', estimate.breakdown.teeSurcharge);
238
- ```
93
+ ### `client.getJob(jobId)`
239
94
 
240
- ### Network Metrics
95
+ Check the status of an async proving job.
241
96
 
242
97
  ```typescript
243
- // Check network status
244
- const metrics = await prover.getMetrics();
245
-
246
- console.log('Available GPUs:');
247
- for (const gpu of metrics.availableGpus) {
248
- console.log(` ${gpu.tier}: ${gpu.count} (${gpu.teeEnabled} TEE)`);
249
- }
250
-
251
- console.log('Queue depth:', metrics.queueDepth);
252
- console.log('Avg wait time:', metrics.avgWaitTimeSecs, 'seconds');
253
- console.log('Utilization:', metrics.networkUtilization * 100, '%');
98
+ const job = await client.getJob("job-abc123");
99
+ // { status: "completed", progress: 100, result: { ... } }
254
100
  ```
255
101
 
256
- ---
102
+ ## Async Jobs
257
103
 
258
- ## Full Privacy Client
259
-
260
- For advanced privacy operations including steganographic transactions, ring signatures, and threshold decryption.
104
+ For large models, proving runs asynchronously:
261
105
 
262
106
  ```typescript
263
- import { createPrivacyClient } from '@bitsage/sdk';
264
-
265
- const privacy = createPrivacyClient({
266
- contractAddress: '0x...',
267
- httpUrl: 'https://api.bitsage.network',
107
+ const { jobId } = await client.prove({
108
+ model: "phi-3-mini",
109
+ input: data,
110
+ async: true,
268
111
  });
269
112
 
270
- // Register a private account
271
- const account = await privacy.registerAccount(keyPair);
272
-
273
- // Private transfer
274
- const tx = await privacy.privateTransfer({
275
- recipientPublicKey: recipient.publicKey,
276
- amount: 500n,
277
- asset: 'SAGE',
278
- });
279
-
280
- // Check encrypted balance
281
- const balance = await privacy.getEncryptedBalance(myAddress, 'SAGE');
282
-
283
- // Reveal balance (client-side decryption)
284
- const revealed = await privacy.revealBalance(keyPair, 'SAGE');
285
- console.log('My SAGE balance:', revealed);
286
- ```
287
-
288
- ---
289
-
290
- ## React Hooks
113
+ // Poll for completion
114
+ let job;
115
+ do {
116
+ await new Promise(r => setTimeout(r, 5000));
117
+ job = await client.getJob(jobId);
118
+ console.log(`Progress: ${job.progress}%`);
119
+ } while (job.status === "running");
291
120
 
292
- ```typescript
293
- import { useBitSage, usePrivacy, useStwoProver } from '@bitsage/sdk/react';
294
-
295
- function App() {
296
- const { client, isConnected } = useBitSage();
297
- const { privacy, keyPair, generateKeyPair } = usePrivacy();
298
- const { prover, submitJob, status } = useStwoProver();
299
-
300
- return (
301
- <div>
302
- <button onClick={generateKeyPair}>Generate Keys</button>
303
- <button onClick={() => submitJob({ ... })}>Submit Proof</button>
304
- {status && <p>Progress: {status.progressBps / 100}%</p>}
305
- </div>
306
- );
307
- }
308
- ```
309
-
310
- ---
311
-
312
- ## Contract Registry
313
-
314
- ```typescript
315
- import {
316
- SEPOLIA_CONTRACTS,
317
- MAINNET_CONTRACTS,
318
- getContractsForNetwork
319
- } from '@bitsage/sdk';
320
-
321
- // Get contracts for a network
322
- const contracts = getContractsForNetwork('sepolia');
323
-
324
- console.log('SAGE Token:', contracts.sageToken);
325
- console.log('Confidential Swap:', contracts.confidentialSwap);
326
- console.log('Privacy Router:', contracts.privacyRouter);
327
- console.log('STWO Verifier:', contracts.stwoVerifier);
121
+ console.log("Result:", job.result);
328
122
  ```
329
123
 
330
- ---
124
+ ## Supported Models
331
125
 
332
- ## Architecture
126
+ | Model | Params | Prove Time (GPU) | Recursive Felts |
127
+ |-------|--------|-------------------|-----------------|
128
+ | SmolLM2-135M | 135M | ~102s | 942 |
129
+ | Qwen2-0.5B | 500M | ~45s | ~900 |
130
+ | Phi-3-mini | 3.8B | ~180s | ~950 |
333
131
 
334
- ```
335
- ┌─────────────────────────────────────────────────────────────────────────────┐
336
- │ @bitsage/sdk │
337
- ├─────────────────────────────────────────────────────────────────────────────┤
338
- │ │
339
- │ OBELYSK PRIVACY (Client-Side) STWO GPU PROVER (Server-Side) │
340
- │ ───────────────────────────── ────────────────────────────── │
341
- │ • ElGamal encryption • Batch proof generation │
342
- │ • Schnorr proofs • GPU acceleration (H100/H200) │
343
- │ • Range proofs • TEE privacy (optional) │
344
- │ • Confidential swaps • Recursive aggregation │
345
- │ │
346
- │ import { ObelyskPrivacy } import { createStwoProverClient } │
347
- │ │
348
- ├─────────────────────────────────────────────────────────────────────────────┤
349
- │ │
350
- │ STARKNET L2 │
351
- │ • Proof verification │
352
- │ • Encrypted balances │
353
- │ • Atomic swaps │
354
- │ │
355
- └─────────────────────────────────────────────────────────────────────────────┘
356
- ```
132
+ ## On-Chain Verification
357
133
 
358
- ---
134
+ When `onChain: true`, the SDK submits the proof to the ObelyZK Recursive Verifier contract on Starknet Sepolia. Verification uses full OODS + Merkle + FRI + PoW (trustless).
359
135
 
360
- ## API Reference
136
+ - **Contract:** `0x707819dea6210ab58b358151419a604ffdb16809b568bf6f8933067c2a28715`
137
+ - **Method:** `verify_recursive(model_id, io_commitment, stark_proof_data)`
138
+ - **Verification:** Full OODS + Merkle + FRI + PoW (trustless)
139
+ - **Felts:** ~942 per proof (49x compression)
140
+ - **Cost:** ~$0.02 per verification on Sepolia
361
141
 
362
- ### ObelyskPrivacy
363
-
364
- | Method | Description |
365
- |--------|-------------|
366
- | `generateKeyPair()` | Generate ElGamal key pair |
367
- | `encrypt(amount, publicKey)` | Encrypt amount |
368
- | `decrypt(ciphertext, privateKey)` | Decrypt ciphertext |
369
- | `homomorphicAdd(c1, c2)` | Add encrypted values |
370
- | `createEncryptionProof()` | Create Schnorr proof |
371
- | `verifyEncryptionProof()` | Verify proof |
372
-
373
- ### StwoProverClient
374
-
375
- | Method | Description |
376
- |--------|-------------|
377
- | `submitProofJob(request)` | Submit proof generation job |
378
- | `getJobStatus(jobId)` | Get job status |
379
- | `waitForProof(jobId)` | Wait for completion |
380
- | `cancelJob(jobId)` | Cancel pending job |
381
- | `submitBatch(request)` | Submit batch of proofs |
382
- | `estimateCost(request)` | Estimate proof cost |
383
- | `getMetrics()` | Get network metrics |
384
- | `proveBatchPayments()` | Helper for batch payments |
385
- | `proveInference()` | Helper for AI inference |
386
- | `proveBridge()` | Helper for bridge proofs |
387
- | `aggregateProofs()` | Recursive aggregation |
388
- | `loadZkmlModel(req)` | Load ONNX model on prover server |
389
- | `submitZkmlProve(req)` | Submit ZKML proving job |
390
- | `getZkmlProveStatus(jobId)` | Get ZKML job progress |
391
- | `getZkmlProveResult(jobId)` | Get proof calldata + commitments |
392
- | `proveZkml(req, opts?)` | Full prove pipeline with progress callback |
393
-
394
- ### StwoClient (On-Chain Verification)
395
-
396
- | Method | Description |
397
- |--------|-------------|
398
- | `submitProof(data, hash)` | Submit proof for verification |
399
- | `verifyProof(hash)` | Verify proof via contract |
400
- | `submitGpuTeeProof(params)` | Submit GPU-TEE optimistic proof |
401
- | `registerZkmlModel(id, commitment)` | Register model on verifier contract |
402
- | `verifyZkmlModel(id, calldata)` | Verify ML model proof on-chain |
403
- | `isZkmlProofVerified(hash)` | Check if proof is verified |
404
- | `getZkmlVerificationCount(id)` | Get verification count for model |
405
- | `getZkmlModelCommitment(id)` | Get registered weight commitment |
406
- | `proveAndVerifyOnChain(prover, req)` | End-to-end: prove via API + verify on-chain |
407
-
408
- ---
409
-
410
- ## ZKML Proving
411
-
412
- End-to-end ML inference proving and on-chain verification.
413
-
414
- ### Prove a Model
142
+ You can verify independently:
415
143
 
416
144
  ```typescript
417
- import { createStwoProverClient } from '@bitsage/sdk';
145
+ import { RpcProvider } from "starknet";
418
146
 
419
- const prover = createStwoProverClient({
420
- baseUrl: 'http://your-gpu-server:8080',
147
+ const provider = new RpcProvider({
148
+ nodeUrl: "https://starknet-sepolia.g.alchemy.com/starknet/version/rpc/v0_8/demo",
421
149
  });
422
150
 
423
- // Load an ONNX model
424
- const model = await prover.loadZkmlModel({
425
- modelPath: '/path/to/model.onnx',
426
- description: 'Qwen3-14B block 0',
151
+ const result = await provider.callContract({
152
+ contractAddress: "0x707819dea6210ab58b358151419a604ffdb16809b568bf6f8933067c2a28715",
153
+ entrypoint: "get_recursive_verification_count",
154
+ calldata: [modelId],
427
155
  });
428
- console.log('Model ID:', model.modelId);
429
- console.log('Weight commitment:', model.weightCommitment);
430
-
431
- // Prove with progress tracking
432
- const result = await prover.proveZkml(
433
- { modelId: model.modelId, gpu: true },
434
- {
435
- onProgress: (status) => {
436
- console.log(`${(status.progressBps / 100).toFixed(1)}% — ${status.elapsedSecs.toFixed(1)}s`);
437
- },
438
- pollIntervalMs: 2000,
439
- timeoutMs: 300_000,
440
- }
441
- );
442
-
443
- console.log('Calldata:', result.calldataLength, 'felts');
444
- console.log('Gas estimate:', result.estimatedGas);
445
- console.log('Prove time:', (result.proveTimeMs / 1000).toFixed(1), 's');
446
- ```
447
-
448
- ### Verify On-Chain
449
156
 
450
- ```typescript
451
- import { createStwoClient } from '@bitsage/sdk';
452
-
453
- const verifier = createStwoClient({ /* ... */ });
157
+ console.log("Verification count:", result[0]);
158
+ ```
454
159
 
455
- // Set verifier contract (default: deployed v3 on Sepolia)
456
- verifier.setZkmlVerifier('0x048070fbd531a0192f3d4a37eb019ae3174600cae15e08c737982fae5d929160');
160
+ ## Environment Variables
457
161
 
458
- // Register model
459
- await verifier.registerZkmlModel(model.modelId, model.weightCommitment);
162
+ | Variable | Description | Required |
163
+ |----------|-------------|----------|
164
+ | `OBELYSK_API_KEY` | API key for hosted prover | For hosted |
165
+ | `OBELYSK_PROVER_URL` | Custom prover URL | For self-hosted |
166
+ | `STARKNET_ACCOUNT` | Starknet account address | For on-chain |
167
+ | `STARKNET_PRIVATE_KEY` | Starknet private key | For on-chain |
460
168
 
461
- // Check verification status
462
- const count = await verifier.getZkmlVerificationCount(model.modelId);
463
- console.log('Verified', count, 'times');
464
- ```
169
+ ## Self-Hosted Prover
465
170
 
466
- ### Full Pipeline
171
+ Point the SDK at your own GPU prover instead of the hosted service:
467
172
 
468
173
  ```typescript
469
- // Prove on GPU server + verify on Starknet in one call
470
- const tx = await verifier.proveAndVerifyOnChain(prover, {
471
- modelId: model.modelId,
472
- gpu: true,
174
+ const client = createProverClient({
175
+ url: "http://your-gpu-server:8080",
473
176
  });
474
- console.log('Transaction hash:', tx);
475
177
  ```
476
178
 
477
- ---
179
+ See the [Self-Hosting Guide](../../libs/stwo-ml/scripts/pipeline/GETTING_STARTED.md#option-3-self-host-a-gpu-prover) for setup instructions.
478
180
 
479
- ## License
181
+ ## Links
480
182
 
481
- MIT
183
+ - [GitHub](https://github.com/obelyzk/stwo-ml)
184
+ - [npm](https://www.npmjs.com/package/@obelyzk/sdk)
185
+ - [Getting Started](../../libs/stwo-ml/scripts/pipeline/GETTING_STARTED.md)
186
+ - [On-Chain Docs](../../libs/stwo-ml/docs/ON_CHAIN_VERIFICATION.md)
File without changes