@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 +110 -405
- package/bin/bitsage-demo.ts +0 -0
- package/dist/chunk-BHUXKNDT.mjs +206 -0
- package/dist/chunk-MDF4P52S.mjs +697 -0
- package/dist/chunk-Y6FXYEAI.mjs +10 -0
- package/dist/firewall/index.d.mts +166 -0
- package/dist/firewall/index.d.ts +166 -0
- package/dist/firewall/index.js +232 -0
- package/dist/firewall/index.mjs +7 -0
- package/dist/index.d.mts +54 -8
- package/dist/index.d.ts +54 -8
- package/dist/index.js +251 -6
- package/dist/index.mjs +52 -7
- package/dist/obelysk/index.mjs +4 -2
- package/dist/privacy/index.d.mts +1 -1
- package/dist/privacy/index.d.ts +1 -1
- package/dist/privacy/index.mjs +2 -1
- package/dist/react/index.d.mts +3 -3
- package/dist/react/index.d.ts +3 -3
- package/dist/react/index.mjs +2 -1
- package/package.json +11 -2
package/README.md
CHANGED
|
@@ -1,481 +1,186 @@
|
|
|
1
|
-
# @
|
|
1
|
+
# @obelyzk/sdk
|
|
2
2
|
|
|
3
|
-
|
|
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 @
|
|
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 {
|
|
16
|
+
import { createProverClient } from "@obelyzk/sdk";
|
|
31
17
|
|
|
32
|
-
const client =
|
|
33
|
-
network: 'sepolia', // or 'mainnet'
|
|
34
|
-
apiKey: 'your-api-key',
|
|
35
|
-
});
|
|
18
|
+
const client = createProverClient();
|
|
36
19
|
|
|
37
|
-
//
|
|
38
|
-
const
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
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(
|
|
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
|
-
|
|
75
|
-
const isValid = privacy.verifyEncryptionProof(proof, keyPair.publicKey, encrypted);
|
|
76
|
-
console.log('Proof valid:', isValid); // true
|
|
77
|
-
```
|
|
35
|
+
### `createProverClient(options?)`
|
|
78
36
|
|
|
79
|
-
|
|
37
|
+
Create a prover client instance.
|
|
80
38
|
|
|
81
39
|
```typescript
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
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
|
-
###
|
|
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
|
-
|
|
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
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
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
|
-
//
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
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
|
-
###
|
|
72
|
+
### `client.attest(request)`
|
|
162
73
|
|
|
163
|
-
|
|
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
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
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
|
-
###
|
|
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
|
-
|
|
86
|
+
List all available models on the prover.
|
|
208
87
|
|
|
209
88
|
```typescript
|
|
210
|
-
|
|
211
|
-
|
|
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
|
-
###
|
|
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
|
-
|
|
95
|
+
Check the status of an async proving job.
|
|
241
96
|
|
|
242
97
|
```typescript
|
|
243
|
-
|
|
244
|
-
|
|
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
|
-
|
|
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
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
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
|
-
//
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 {
|
|
145
|
+
import { RpcProvider } from "starknet";
|
|
418
146
|
|
|
419
|
-
const
|
|
420
|
-
|
|
147
|
+
const provider = new RpcProvider({
|
|
148
|
+
nodeUrl: "https://starknet-sepolia.g.alchemy.com/starknet/version/rpc/v0_8/demo",
|
|
421
149
|
});
|
|
422
150
|
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
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
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
const verifier = createStwoClient({ /* ... */ });
|
|
157
|
+
console.log("Verification count:", result[0]);
|
|
158
|
+
```
|
|
454
159
|
|
|
455
|
-
|
|
456
|
-
verifier.setZkmlVerifier('0x048070fbd531a0192f3d4a37eb019ae3174600cae15e08c737982fae5d929160');
|
|
160
|
+
## Environment Variables
|
|
457
161
|
|
|
458
|
-
|
|
459
|
-
|
|
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
|
-
|
|
462
|
-
const count = await verifier.getZkmlVerificationCount(model.modelId);
|
|
463
|
-
console.log('Verified', count, 'times');
|
|
464
|
-
```
|
|
169
|
+
## Self-Hosted Prover
|
|
465
170
|
|
|
466
|
-
|
|
171
|
+
Point the SDK at your own GPU prover instead of the hosted service:
|
|
467
172
|
|
|
468
173
|
```typescript
|
|
469
|
-
|
|
470
|
-
|
|
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
|
-
##
|
|
181
|
+
## Links
|
|
480
182
|
|
|
481
|
-
|
|
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)
|
package/bin/bitsage-demo.ts
CHANGED
|
File without changes
|