0g-inference-sdk 0.2.0__tar.gz

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.
Files changed (38) hide show
  1. 0g_inference_sdk-0.2.0/0g_inference_sdk.egg-info/PKG-INFO +1115 -0
  2. 0g_inference_sdk-0.2.0/0g_inference_sdk.egg-info/SOURCES.txt +36 -0
  3. 0g_inference_sdk-0.2.0/0g_inference_sdk.egg-info/dependency_links.txt +1 -0
  4. 0g_inference_sdk-0.2.0/0g_inference_sdk.egg-info/not-zip-safe +1 -0
  5. 0g_inference_sdk-0.2.0/0g_inference_sdk.egg-info/requires.txt +13 -0
  6. 0g_inference_sdk-0.2.0/0g_inference_sdk.egg-info/top_level.txt +1 -0
  7. 0g_inference_sdk-0.2.0/LICENSE +21 -0
  8. 0g_inference_sdk-0.2.0/MANIFEST.in +6 -0
  9. 0g_inference_sdk-0.2.0/PKG-INFO +1115 -0
  10. 0g_inference_sdk-0.2.0/README.md +1064 -0
  11. 0g_inference_sdk-0.2.0/requirements.txt +11 -0
  12. 0g_inference_sdk-0.2.0/setup.cfg +4 -0
  13. 0g_inference_sdk-0.2.0/setup.py +63 -0
  14. 0g_inference_sdk-0.2.0/tests/test_crypto.py +297 -0
  15. 0g_inference_sdk-0.2.0/zerog_py_sdk/__init__.py +185 -0
  16. 0g_inference_sdk-0.2.0/zerog_py_sdk/auth.py +276 -0
  17. 0g_inference_sdk-0.2.0/zerog_py_sdk/broker.py +285 -0
  18. 0g_inference_sdk-0.2.0/zerog_py_sdk/cache.py +343 -0
  19. 0g_inference_sdk-0.2.0/zerog_py_sdk/constants.py +160 -0
  20. 0g_inference_sdk-0.2.0/zerog_py_sdk/contracts/__init__.py +25 -0
  21. 0g_inference_sdk-0.2.0/zerog_py_sdk/contracts/abis.py +94 -0
  22. 0g_inference_sdk-0.2.0/zerog_py_sdk/crypto/__init__.py +87 -0
  23. 0g_inference_sdk-0.2.0/zerog_py_sdk/crypto/babyjub.py +294 -0
  24. 0g_inference_sdk-0.2.0/zerog_py_sdk/crypto/eddsa.py +283 -0
  25. 0g_inference_sdk-0.2.0/zerog_py_sdk/crypto/field.py +93 -0
  26. 0g_inference_sdk-0.2.0/zerog_py_sdk/crypto/pedersen.py +180 -0
  27. 0g_inference_sdk-0.2.0/zerog_py_sdk/crypto/pedersen_bases.py +135 -0
  28. 0g_inference_sdk-0.2.0/zerog_py_sdk/exceptions.py +156 -0
  29. 0g_inference_sdk-0.2.0/zerog_py_sdk/extractors.py +295 -0
  30. 0g_inference_sdk-0.2.0/zerog_py_sdk/inference.py +797 -0
  31. 0g_inference_sdk-0.2.0/zerog_py_sdk/ledger.py +464 -0
  32. 0g_inference_sdk-0.2.0/zerog_py_sdk/models.py +274 -0
  33. 0g_inference_sdk-0.2.0/zerog_py_sdk/py.typed +0 -0
  34. 0g_inference_sdk-0.2.0/zerog_py_sdk/read_only.py +315 -0
  35. 0g_inference_sdk-0.2.0/zerog_py_sdk/session.py +338 -0
  36. 0g_inference_sdk-0.2.0/zerog_py_sdk/setup.py +63 -0
  37. 0g_inference_sdk-0.2.0/zerog_py_sdk/utils.py +146 -0
  38. 0g_inference_sdk-0.2.0/zerog_py_sdk/verifier.py +291 -0
@@ -0,0 +1,1115 @@
1
+ Metadata-Version: 2.4
2
+ Name: 0g-inference-sdk
3
+ Version: 0.2.0
4
+ Summary: Python SDK for the 0G Compute Network - AI inference services on decentralized infrastructure
5
+ Home-page: https://github.com/mandatedisrael/0g-py-sdk
6
+ Author: notMartin
7
+ Author-email: damiclone@example.com
8
+ Project-URL: Documentation, https://docs.0g.ai/developer-hub/building-on-0g/compute-network/sdk
9
+ Project-URL: Source, https://github.com/mandatedisrael/0g-py-sdk
10
+ Project-URL: Bug Reports, https://github.com/mandatedisrael/0g-py-sdk/issues
11
+ Keywords: 0g blockchain ai inference decentralized llm crypto web3
12
+ Classifier: Development Status :: 3 - Alpha
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
15
+ Classifier: Topic :: System :: Distributed Computing
16
+ Classifier: License :: OSI Approved :: MIT License
17
+ Classifier: Programming Language :: Python :: 3
18
+ Classifier: Programming Language :: Python :: 3.8
19
+ Classifier: Programming Language :: Python :: 3.9
20
+ Classifier: Programming Language :: Python :: 3.10
21
+ Classifier: Programming Language :: Python :: 3.11
22
+ Classifier: Programming Language :: Python :: 3.12
23
+ Requires-Python: >=3.8
24
+ Description-Content-Type: text/markdown
25
+ License-File: LICENSE
26
+ Requires-Dist: web3>=6.0.0
27
+ Requires-Dist: eth-account>=0.10.0
28
+ Requires-Dist: eth-utils>=2.0.0
29
+ Requires-Dist: requests>=2.31.0
30
+ Requires-Dist: python-dotenv>=1.0.0
31
+ Requires-Dist: typing-extensions>=4.0.0
32
+ Provides-Extra: dev
33
+ Requires-Dist: pytest>=7.0.0; extra == "dev"
34
+ Requires-Dist: pytest-asyncio>=0.21.0; extra == "dev"
35
+ Requires-Dist: black>=23.0.0; extra == "dev"
36
+ Requires-Dist: flake8>=6.0.0; extra == "dev"
37
+ Requires-Dist: mypy>=1.0.0; extra == "dev"
38
+ Dynamic: author
39
+ Dynamic: author-email
40
+ Dynamic: classifier
41
+ Dynamic: description
42
+ Dynamic: description-content-type
43
+ Dynamic: home-page
44
+ Dynamic: keywords
45
+ Dynamic: license-file
46
+ Dynamic: project-url
47
+ Dynamic: provides-extra
48
+ Dynamic: requires-dist
49
+ Dynamic: requires-python
50
+ Dynamic: summary
51
+
52
+ # 0G Compute Network Python SDK
53
+
54
+ [![Python 3.8+](https://img.shields.io/badge/python-3.8+-blue.svg)](https://www.python.org/downloads/)
55
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
56
+
57
+ Python SDK for interacting with the 0G Compute Network - a decentralized AI inference marketplace where you pay for AI model access using blockchain tokens.
58
+
59
+ > **✅ Available on PyPI:** `pip install 0g-py-sdk`
60
+
61
+ ## What is 0G Compute Network?
62
+
63
+ 0G Compute Network is a **blockchain-based marketplace** for AI inference services:
64
+ - **Providers** offer AI models (LLMs) with TEE-verified compute
65
+ - **Users** pay per request using 0G tokens (ERC-20)
66
+ - **Smart contracts** handle billing, accounts, and cryptographic verification
67
+ - **Decentralized** - no central authority, fully on-chain payment settlement
68
+
69
+ ## Features
70
+
71
+ - ✅ **Session Token Auth**: New simplified authorization system (no complex headers)
72
+ - ✅ **Account Management**: Fund and manage prepaid accounts for AI services
73
+ - ✅ **Service Discovery**: List and query available AI providers on-chain
74
+ - ✅ **Read-Only Mode**: Browse services without wallet connection
75
+ - ✅ **Multi-Network Support**: Mainnet and testnet with auto-detection
76
+ - ✅ **API Key Management**: Create persistent, revocable API keys
77
+ - ✅ **Provider Integration**: OpenAI-compatible API interface
78
+ - ✅ **Verifiable Computing**: TEE (Trusted Execution Environment) attestation support
79
+ - ✅ **Response Verification**: Verify TEE-signed responses
80
+ - ✅ **Caching System**: Built-in caching for performance
81
+
82
+ ## How It Works
83
+
84
+ ```
85
+ ┌─────────────┐ ┌──────────────┐ ┌─────────────┐
86
+ │ Your App │ │ 0G Network │ │ AI Provider│
87
+ │ (Python) │ │ (Blockchain) │ │ (TEE) │
88
+ └──────┬──────┘ └──────┬───────┘ └──────┬──────┘
89
+ │ │ │
90
+ │ 1. Fund account │ │
91
+ ├───────────────────────────────>│ │
92
+ │ (deposit 0G tokens) │ │
93
+ │ │ │
94
+ │ 2. Acknowledge provider │ │
95
+ ├───────────────────────────────>│<───────────────────────────────┤
96
+ │ (verify TEE signer) │ (get TEE attestation) │
97
+ │ │ │
98
+ │ 3. Get session token │ │
99
+ │ (auto-generated & cached) │ │
100
+ │ │ │
101
+ │ 4. Make inference request │ │
102
+ ├────────────────────────────────┼───────────────────────────────>│
103
+ │ (with Authorization header) │ │
104
+ │ │ │
105
+ │ 5. Get AI response │ │
106
+ │<────────────────────────────────────────────────────────────────┤
107
+ │ │ │
108
+ │ 6. Provider settles billing │ │
109
+ │ │<───────────────────────────────┤
110
+ │ │ (deduct tokens on-chain) │
111
+ └────────────────────────────────┴────────────────────────────────┘
112
+ ```
113
+
114
+ ## System Requirements
115
+
116
+ - **Python**: 3.8 or higher
117
+
118
+ ## Installation
119
+
120
+ > **Quick Start:** For a condensed setup guide, see [SETUP.md](SETUP.md)
121
+
122
+ ### Install from PyPI (Recommended)
123
+
124
+ ```bash
125
+ pip install 0g-py-sdk
126
+ ```
127
+
128
+ ### Development Setup (Optional)
129
+
130
+ If you want to contribute or modify the SDK:
131
+
132
+ ```bash
133
+ # Clone the repository
134
+ git clone https://github.com/mandatedisrael/0g-py-sdk.git
135
+ cd 0g-py-sdk/0g_py_inference
136
+
137
+ # Create virtual environment
138
+ python3 -m venv venv
139
+ source venv/bin/activate # macOS/Linux
140
+ # OR
141
+ venv\Scripts\activate # Windows
142
+
143
+ # Install in development mode
144
+ pip install -e .
145
+ ```
146
+
147
+ ### Configure Environment Variables
148
+
149
+ Create a `.env` file in your project directory:
150
+
151
+ ```bash
152
+ PRIVATE_KEY=your_private_key_without_0x_prefix
153
+ RPC_URL=https://evmrpc-testnet.0g.ai
154
+ ```
155
+
156
+ **⚠️ Important:** Never commit your `.env` file to version control!
157
+
158
+ ## Quick Start
159
+
160
+ After following the installation steps, create a script or use the provided `test.py`:
161
+
162
+ ```python
163
+ from zerog_py_sdk import create_broker
164
+ from zerog_py_sdk.utils import og_to_wei
165
+ import requests
166
+ import json
167
+ import os
168
+ from dotenv import load_dotenv
169
+
170
+ # Load environment variables from .env file
171
+ load_dotenv()
172
+
173
+ # 1. Initialize broker with your private key
174
+ broker = create_broker(
175
+ private_key=os.getenv('PRIVATE_KEY'),
176
+ rpc_url=os.getenv('RPC_URL', 'https://evmrpc-testnet.0g.ai')
177
+ )
178
+
179
+ # 2. Discover available AI services
180
+ services = broker.inference.list_service()
181
+ provider_address = services[0].provider
182
+
183
+ print(f"Provider: {provider_address}")
184
+ print(f"Model: {services[0].model}")
185
+
186
+ # 3. Fund your account (one-time setup)
187
+ # Skip if you already have funds
188
+ account = broker.ledger.get_ledger()
189
+ if account.balance < 0.1:
190
+ broker.ledger.deposit_fund("2") # Add 2 OG tokens
191
+ print(f"✓ Added funds. New balance: {broker.ledger.get_ledger().balance} OG")
192
+
193
+ # 4. Acknowledge provider (one-time per provider)
194
+ broker.inference.acknowledge_provider_signer(provider_address)
195
+ print("✓ Provider acknowledged")
196
+
197
+ # 5. Transfer funds to provider sub-account
198
+ broker.ledger.transfer_fund(provider_address, "inference", og_to_wei("0.5"))
199
+ print("✓ Transferred 0.5 OG to provider")
200
+
201
+ # 6. Get service metadata
202
+ metadata = broker.inference.get_service_metadata(provider_address)
203
+ endpoint = metadata['endpoint'] # Automatically appends /v1/proxy
204
+ model = metadata['model']
205
+
206
+ # 7. Get authentication headers (NEW: simplified session token auth)
207
+ headers = broker.inference.get_request_headers(provider_address)
208
+ # Returns: {"Authorization": "Bearer app-sk-..."}
209
+
210
+ # 8. Make inference request
211
+ messages = [{"role": "user", "content": "What is 2+2?"}]
212
+ response = requests.post(
213
+ f"{endpoint}/chat/completions",
214
+ headers={"Content-Type": "application/json", **headers},
215
+ json={"messages": messages, "model": model}
216
+ )
217
+
218
+ # 9. Get the answer
219
+ if response.status_code == 200:
220
+ answer = response.json()['choices'][0]['message']['content']
221
+ print(f"Answer: {answer}")
222
+ else:
223
+ print(f"Error: {response.status_code} - {response.text}")
224
+ ```
225
+
226
+ **Output:**
227
+ ```
228
+ Provider: 0xf07240Efa67755B5311bc75784a061eDB47165Dd
229
+ Model: qwen/qwen-2.5-7b-instruct
230
+ ✓ Added funds. New balance: 2.0 OG
231
+ ✓ Provider acknowledged
232
+ ✓ Transferred 0.5 OG to provider
233
+ Answer: 2 + 2 = 4.
234
+ ```
235
+
236
+ ---
237
+
238
+ ## Browse Services Without Wallet (Read-Only Mode)
239
+
240
+ You can list available AI providers without connecting a wallet:
241
+
242
+ ```python
243
+ from zerog_py_sdk import create_read_only_broker
244
+
245
+ # Create read-only broker (no private key needed)
246
+ broker = create_read_only_broker()
247
+
248
+ # List all available services
249
+ services = broker.list_service()
250
+ for svc in services:
251
+ print(f"{svc.model} - {svc.provider}")
252
+ print(f" URL: {svc.url}")
253
+ print(f" Input: {svc.input_price} wei/token")
254
+ print(f" Output: {svc.output_price} wei/token")
255
+
256
+ # Get services with health metrics
257
+ detailed = broker.list_service_with_detail()
258
+ for svc in detailed:
259
+ if svc.health_metrics:
260
+ print(f"{svc.model}: {svc.health_metrics.uptime}% uptime")
261
+
262
+ # Use mainnet instead of testnet
263
+ mainnet_broker = create_read_only_broker(network="mainnet")
264
+ ```
265
+
266
+ ---
267
+
268
+ ## Network Configuration
269
+
270
+ The SDK supports multiple networks with auto-detection:
271
+
272
+ ```python
273
+ from zerog_py_sdk import (
274
+ create_broker,
275
+ get_contract_addresses,
276
+ get_rpc_url,
277
+ MAINNET_CHAIN_ID, # 16661
278
+ TESTNET_CHAIN_ID, # 16602
279
+ )
280
+
281
+ # Testnet (default)
282
+ broker = create_broker(
283
+ private_key="0x...",
284
+ rpc_url="https://evmrpc-testnet.0g.ai"
285
+ )
286
+
287
+ # Mainnet
288
+ broker = create_broker(
289
+ private_key="0x...",
290
+ rpc_url="https://evmrpc.0g.ai"
291
+ )
292
+
293
+ # Get contract addresses for a network
294
+ addrs = get_contract_addresses("mainnet")
295
+ print(f"Inference: {addrs.inference}")
296
+ print(f"Ledger: {addrs.ledger}")
297
+
298
+ # Auto-detect from chain ID
299
+ addrs = get_contract_addresses(chain_id=16661)
300
+ ```
301
+
302
+ ## SDK Architecture
303
+
304
+ ### High-Level Structure
305
+
306
+ ```
307
+ zerog_py_sdk/
308
+ ├── broker.py # Main entry point - ZGServingBroker class
309
+ ├── ledger.py # Account & balance management (LedgerManager)
310
+ ├── inference.py # Service discovery & request signing (InferenceManager)
311
+ ├── session.py # Session token management (NEW)
312
+ ├── read_only.py # Read-only broker for wallet-less operations (NEW)
313
+ ├── constants.py # Network constants & contract addresses (NEW)
314
+ ├── extractors.py # Service type extractors (chatbot, image, etc.) (NEW)
315
+ ├── cache.py # Built-in caching system (NEW)
316
+ ├── verifier.py # Response verification for TEE (NEW)
317
+ ├── auth.py # Cryptographic operations (native Python)
318
+ ├── models.py # Data structures (ServiceMetadata, LedgerAccount, etc.)
319
+ ├── exceptions.py # Custom error types
320
+ ├── utils.py # Helper functions (og_to_wei, parse receipts, etc.)
321
+ └── crypto/ # Native Python crypto (no Node.js dependency)
322
+ ├── eddsa.py # EdDSA signatures on Baby JubJub curve
323
+ ├── pedersen.py # Pedersen hash function
324
+ └── baby_jubjub.py # Baby JubJub elliptic curve
325
+ ```
326
+
327
+ ### Component Breakdown
328
+
329
+ #### 1. **Broker** (`broker.py`)
330
+
331
+ The main orchestrator that initializes and connects all components.
332
+
333
+ ```python
334
+ class ZGServingBroker:
335
+ """
336
+ Main broker class that coordinates:
337
+ - Blockchain connection (Web3)
338
+ - Smart contract instances
339
+ - Ledger operations
340
+ - Inference operations
341
+ """
342
+
343
+ def __init__(self, private_key, rpc_url, contract_address):
344
+ self.web3 = Web3(HTTPProvider(rpc_url))
345
+ self.account = Account.from_key(private_key)
346
+
347
+ # Initialize smart contracts
348
+ self.ledger_contract = self._load_contract("LedgerManager")
349
+ self.inference_contract = self._load_contract("InferenceServing")
350
+
351
+ # Initialize managers
352
+ self.ledger = LedgerManager(...) # For payments
353
+ self.inference = InferenceManager(...) # For AI requests
354
+ ```
355
+
356
+ **Key methods:**
357
+ - `create_broker(private_key, rpc_url)` - Factory function
358
+ - `create_broker_from_env()` - Load from .env file
359
+ - `get_address()` - Get your wallet address
360
+
361
+ ---
362
+
363
+ #### 2. **LedgerManager** (`ledger.py`)
364
+
365
+ Handles all on-chain account and payment operations.
366
+
367
+ ```python
368
+ class LedgerManager:
369
+ """
370
+ Manages your prepaid account on the blockchain.
371
+ Think of it as your "wallet" for AI services.
372
+ """
373
+
374
+ def add_ledger(amount: str):
375
+ """
376
+ Create account or add funds to main ledger.
377
+ Sends 0G tokens to smart contract.
378
+
379
+ Args:
380
+ amount: OG tokens (e.g., "0.1")
381
+ """
382
+
383
+ def deposit_fund(amount: str):
384
+ """
385
+ Add more funds to existing account.
386
+ """
387
+
388
+ def transfer_fund(provider_address, service_type, amount_wei):
389
+ """
390
+ Allocate funds to specific provider's sub-account.
391
+ Must be done before making inference requests.
392
+ """
393
+
394
+ def get_ledger() -> LedgerAccount:
395
+ """
396
+ Check your balance.
397
+ Returns: balance, locked, total_balance (in OG)
398
+ """
399
+
400
+ def retrieve_fund(service_type):
401
+ """
402
+ Withdraw unused funds from provider sub-accounts.
403
+ """
404
+ ```
405
+
406
+ **Account Model:**
407
+ ```
408
+ Main Ledger (Your Account)
409
+ ├── Available Balance: 2.0 OG
410
+ ├── Locked Balance: 0.5 OG (allocated to providers)
411
+ └── Total Balance: 2.5 OG
412
+
413
+ Provider Sub-Accounts
414
+ ├── Provider A: 0.3 OG (for inference)
415
+ └── Provider B: 0.2 OG (for inference)
416
+ ```
417
+
418
+ ---
419
+
420
+ #### 3. **InferenceManager** (`inference.py`)
421
+
422
+ Discovers AI services and generates authenticated request headers.
423
+
424
+ ```python
425
+ class InferenceManager:
426
+ """
427
+ Handles AI inference operations:
428
+ - Finding available providers
429
+ - Verifying TEE attestations
430
+ - Generating session tokens for authentication
431
+ """
432
+
433
+ def list_service() -> List[ServiceMetadata]:
434
+ """
435
+ Query blockchain for all registered AI providers.
436
+ Returns list of available models with pricing.
437
+ """
438
+
439
+ def get_service(provider_address) -> ServiceMetadata:
440
+ """
441
+ Get specific provider's service details.
442
+ """
443
+
444
+ def acknowledge_provider_signer(provider_address):
445
+ """
446
+ One-time setup per provider:
447
+ 1. Gets TEE attestation from provider
448
+ 2. Verifies quote (optional)
449
+ 3. Records TEE signer on-chain
450
+
451
+ This links the provider's TEE to their blockchain address.
452
+ """
453
+
454
+ def get_service_metadata(provider_address) -> dict:
455
+ """
456
+ Get inference endpoint and model name.
457
+ Automatically appends /v1/proxy to URL.
458
+
459
+ Returns:
460
+ {
461
+ "endpoint": "http://provider.com:8080/v1/proxy",
462
+ "model": "qwen/qwen-2.5-7b-instruct"
463
+ }
464
+ """
465
+
466
+ def get_request_headers(provider_address) -> dict:
467
+ """
468
+ Generate session token auth headers for request.
469
+
470
+ NEW: No content parameter needed! Session tokens are
471
+ provider-scoped and auto-cached for 24 hours.
472
+
473
+ Returns headers like:
474
+ {
475
+ "Authorization": "Bearer app-sk-..."
476
+ }
477
+ """
478
+ ```
479
+
480
+ **Service Discovery Flow:**
481
+ ```python
482
+ # 1. List all services
483
+ services = broker.inference.list_service()
484
+ # Returns: [ServiceMetadata, ServiceMetadata, ...]
485
+
486
+ # 2. ServiceMetadata object contains:
487
+ service = services[0]
488
+ service.provider # "0xf07240..."
489
+ service.model # "qwen/qwen-2.5-7b-instruct"
490
+ service.url # "http://50.145.48.92:30081"
491
+ service.input_price # 100000000000 (wei per token)
492
+ service.output_price # 400000000000 (wei per token)
493
+ service.verifiability # "TeeML"
494
+ service.is_verifiable() # True
495
+ ```
496
+
497
+ ---
498
+
499
+ #### 4. **SessionManager** (`session.py`) - NEW
500
+
501
+ Manages session tokens for the new authorization system.
502
+
503
+ ```python
504
+ from zerog_py_sdk import SessionManager, SessionMode
505
+
506
+ class SessionManager:
507
+ """
508
+ Manages session tokens for the 0G Compute Network.
509
+
510
+ Replaces the old header-based authentication with the new
511
+ session token system. Supports both ephemeral (SDK usage)
512
+ and persistent (API keys) tokens.
513
+ """
514
+
515
+ def get_request_headers(provider_address) -> dict:
516
+ """
517
+ Get request headers with session token authorization.
518
+ Auto-generates and caches ephemeral tokens (24h).
519
+
520
+ Returns:
521
+ {"Authorization": "Bearer app-sk-..."}
522
+ """
523
+
524
+ def create_api_key(provider_address, expires_in=None) -> ApiKeyInfo:
525
+ """
526
+ Create a persistent API key (tokenId 0-254).
527
+ Can be individually revoked. Great for server applications.
528
+
529
+ Args:
530
+ provider_address: Provider's wallet address
531
+ expires_in: Expiration in milliseconds (0 = never)
532
+
533
+ Returns:
534
+ ApiKeyInfo with raw_token for use in requests
535
+ """
536
+ ```
537
+
538
+ **Token Types:**
539
+ - **Ephemeral (tokenId=255)**: Auto-generated, 24h max, can't be individually revoked
540
+ - **Persistent (tokenId 0-254)**: Manually created, individually revocable API keys
541
+
542
+ ---
543
+
544
+ #### 5. **Native Crypto** (`crypto/`) - No Node.js Required!
545
+
546
+ The SDK now includes pure Python implementations of ZK-friendly cryptography:
547
+
548
+ ```python
549
+ # Internally used - you don't need to call these directly
550
+ from zerog_py_sdk.crypto import (
551
+ eddsa_sign, # EdDSA signatures on Baby JubJub
552
+ pedersen_hash, # Pedersen hash function
553
+ BabyJubJubPoint, # Baby JubJub curve operations
554
+ )
555
+ ```
556
+
557
+ **Why native Python?**
558
+ - No Node.js/npm dependency
559
+ - Easier installation
560
+ - Works in any Python environment
561
+ - Same cryptographic guarantees as TypeScript SDK
562
+
563
+ ---
564
+
565
+ #### 6. **Models** (`models.py`)
566
+
567
+ Data structures for type safety.
568
+
569
+ ```python
570
+ @dataclass
571
+ class ServiceMetadata:
572
+ provider: str # Wallet address
573
+ service_type: str # "chatbot"
574
+ url: str # Provider endpoint
575
+ input_price: int # Wei per input token
576
+ output_price: int # Wei per output token
577
+ updated_at: int # Timestamp
578
+ model: str # Model identifier
579
+ verifiability: str # "TeeML"
580
+
581
+ @dataclass
582
+ class LedgerAccount:
583
+ balance: float # Available OG
584
+ locked: float # Locked in provider accounts
585
+ total_balance: float # balance + locked
586
+
587
+ @dataclass
588
+ class RequestHeaders:
589
+ # Cryptographic auth headers for inference
590
+ ...
591
+ ```
592
+
593
+ ---
594
+
595
+ #### 7. **Utilities** (`utils.py`)
596
+
597
+ Helper functions for common operations.
598
+
599
+ ```python
600
+ def og_to_wei(amount: str) -> int:
601
+ """Convert OG tokens to wei (10^18)"""
602
+ return int(float(amount) * 10**18)
603
+
604
+ def wei_to_og(wei: int) -> float:
605
+ """Convert wei to OG tokens"""
606
+ return wei / 10**18
607
+
608
+ def parse_transaction_receipt(receipt):
609
+ """Extract useful info from blockchain receipt"""
610
+ return {
611
+ "transaction_hash": receipt.transactionHash.hex(),
612
+ "block_number": receipt.blockNumber,
613
+ "gas_used": receipt.gasUsed,
614
+ "status": receipt.status
615
+ }
616
+ ```
617
+
618
+ ---
619
+
620
+ ### Request Flow (Detailed)
621
+
622
+ Here's what happens when you make an inference request with the new session token system:
623
+
624
+ ```python
625
+ # Step 1: Get session token headers
626
+ headers = broker.inference.get_request_headers(provider)
627
+ # Returns: {"Authorization": "Bearer app-sk-..."}
628
+
629
+ # Internally:
630
+ # 1.1: Check session cache for valid token
631
+ cached = session_cache.get(provider)
632
+ if cached and cached.expires_at > now + 1_hour:
633
+ return cached.headers
634
+
635
+ # 1.2: Create session token
636
+ token = {
637
+ "address": user_address,
638
+ "provider": provider,
639
+ "timestamp": current_time_ms,
640
+ "expiresAt": current_time_ms + 24_hours,
641
+ "nonce": random_hex(16),
642
+ "generation": account.generation,
643
+ "tokenId": 255 # Ephemeral
644
+ }
645
+
646
+ # 1.3: Sign token (native Python EdDSA)
647
+ message_hash = keccak256(json.dumps(token))
648
+ signature = eth_sign(private_key, message_hash)
649
+
650
+ # 1.4: Encode as Authorization header
651
+ encoded = base64(json.dumps(token) + "|" + signature)
652
+ return {"Authorization": f"Bearer app-sk-{encoded}"}
653
+
654
+ # Step 2: Make HTTP request to provider
655
+ response = requests.post(
656
+ f"{endpoint}/chat/completions",
657
+ headers={"Content-Type": "application/json", **headers},
658
+ json={"messages": [...], "model": model}
659
+ )
660
+
661
+ # Step 3: Provider validates session token
662
+ # Provider checks:
663
+ # ✓ Signature matches address in token
664
+ # ✓ Token not expired
665
+ # ✓ Token generation matches account (not batch-revoked)
666
+ # ✓ TokenId not individually revoked (for persistent tokens)
667
+ # ✓ User has balance in contract
668
+
669
+ # Step 4: Provider processes request
670
+ # ✓ Runs LLM inference
671
+ # ✓ Returns response
672
+
673
+ # Step 5: Provider settles billing (async)
674
+ # ✓ Calls contract.settleAccounts([user_address])
675
+ # ✓ Deducts actual tokens used from user balance
676
+ ```
677
+
678
+ ---
679
+
680
+ ## Complete Working Example
681
+
682
+ See `test.py` for a full working example that:
683
+
684
+ 1. ✅ Initializes broker
685
+ 2. ✅ Discovers providers
686
+ 3. ✅ Checks & adds funds
687
+ 4. ✅ Acknowledges provider
688
+ 5. ✅ Transfers funds to provider
689
+ 6. ✅ Makes inference request
690
+ 7. ✅ Receives AI response
691
+
692
+ Run it:
693
+ ```bash
694
+ # Make sure you're in the project directory
695
+ cd og-py-sdk
696
+
697
+ # Activate virtual environment
698
+ source venv/bin/activate
699
+
700
+ # Run the test
701
+ python3 test.py
702
+ ```
703
+
704
+ **Expected output:**
705
+ ```
706
+ Testing broker initialization...
707
+ ✓ Broker initialized
708
+ ✓ Address: 0xB3AD3a10d187cbc4ca3e8c3EDED62F8286F8e16E
709
+
710
+ Testing service discovery...
711
+ ✓ Found 4 services
712
+
713
+ Querying provider for 'Highest World Cup Holder'...
714
+ ✓ Using provider: 0xf07240Efa67755B5311bc75784a061eDB47165Dd
715
+ ✓ Model: phala/gpt-oss-120b
716
+ ✓ Main ledger balance: 2.0 OG
717
+ ✓ Provider acknowledged
718
+ ✓ Transferred funds
719
+
720
+ ==================================================
721
+ Question: Who owns the largest number of football World Cups?
722
+ Answer: Brazil owns the largest number of football World Cups with 5 titles.
723
+ ==================================================
724
+
725
+ ✅ All tests passed!
726
+ ```
727
+
728
+ ---
729
+
730
+ ## API Reference
731
+
732
+ ### Broker Initialization
733
+
734
+ ```python
735
+ from zerog_py_sdk import create_broker
736
+
737
+ broker = create_broker(
738
+ private_key="0x...",
739
+ rpc_url="https://evmrpc-testnet.0g.ai",
740
+ contract_address=None # Optional, uses default if not provided
741
+ )
742
+ ```
743
+
744
+ ### Ledger Operations
745
+
746
+ ```python
747
+ # Add funds to create account or top up
748
+ receipt = broker.ledger.add_ledger("0.1")
749
+
750
+ # Deposit more funds
751
+ receipt = broker.ledger.deposit_fund("0.5")
752
+
753
+ # Transfer to provider sub-account
754
+ from zerog_py_sdk.utils import og_to_wei
755
+ broker.ledger.transfer_fund(provider_address, "inference", og_to_wei("0.5"))
756
+
757
+ # Check balance
758
+ account = broker.ledger.get_ledger()
759
+ print(f"Balance: {account.balance} OG")
760
+ print(f"Total: {account.total_balance} OG")
761
+
762
+ # Request refund from all providers
763
+ receipt = broker.ledger.retrieve_fund("inference")
764
+ ```
765
+
766
+ ### Service Discovery
767
+
768
+ ```python
769
+ # List all services
770
+ services = broker.inference.list_service()
771
+
772
+ for service in services:
773
+ print(f"Provider: {service.provider}")
774
+ print(f"Model: {service.model}")
775
+ print(f"URL: {service.url}")
776
+ print(f"Input Price: {service.input_price} wei/token")
777
+ print(f"Output Price: {service.output_price} wei/token")
778
+ print(f"Verifiable: {service.is_verifiable()}")
779
+
780
+ # Get specific service
781
+ service = broker.inference.get_service(provider_address)
782
+ ```
783
+
784
+ ### Making Requests
785
+
786
+ ```python
787
+ import requests
788
+ import json
789
+
790
+ # 1. Acknowledge provider (once per provider)
791
+ broker.inference.acknowledge_provider_signer(provider_address)
792
+
793
+ # 2. Get service info
794
+ metadata = broker.inference.get_service_metadata(provider_address)
795
+ endpoint = metadata['endpoint'] # Already includes /v1/proxy
796
+ model = metadata['model']
797
+
798
+ # 3. Get auth headers (NEW: no content parameter needed!)
799
+ headers = broker.inference.get_request_headers(provider_address)
800
+
801
+ # 4. Make request
802
+ messages = [{"role": "user", "content": "What is the capital of France?"}]
803
+ response = requests.post(
804
+ f"{endpoint}/chat/completions",
805
+ headers={"Content-Type": "application/json", **headers},
806
+ json={"messages": messages, "model": model}
807
+ )
808
+
809
+ # 5. Parse response
810
+ if response.status_code == 200:
811
+ answer = response.json()['choices'][0]['message']['content']
812
+ print(f"Answer: {answer}")
813
+ ```
814
+
815
+ ### Creating Persistent API Keys
816
+
817
+ For server applications that need long-lived credentials:
818
+
819
+ ```python
820
+ from zerog_py_sdk import SessionMode
821
+
822
+ # Create an API key that never expires
823
+ api_key_info = broker.inference.session_manager.create_api_key(
824
+ provider_address,
825
+ expires_in=0 # 0 = never expires
826
+ )
827
+
828
+ print(f"API Key: {api_key_info.raw_token}")
829
+ print(f"Token ID: {api_key_info.token_id}")
830
+
831
+ # Use the API key in requests
832
+ headers = {"Authorization": f"Bearer {api_key_info.raw_token}"}
833
+ response = requests.post(
834
+ f"{endpoint}/chat/completions",
835
+ headers={"Content-Type": "application/json", **headers},
836
+ json={"messages": messages, "model": model}
837
+ )
838
+ ```
839
+
840
+ ### Using with OpenAI SDK
841
+
842
+ ```python
843
+ from openai import OpenAI
844
+
845
+ # Get metadata
846
+ metadata = broker.inference.get_service_metadata(provider_address)
847
+
848
+ # Get session token headers (NEW: no content needed!)
849
+ headers = broker.inference.get_request_headers(provider_address)
850
+
851
+ # Create client with Authorization header
852
+ client = OpenAI(
853
+ base_url=metadata['endpoint'],
854
+ api_key="not-used", # Auth via headers
855
+ default_headers=headers
856
+ )
857
+
858
+ # Make request
859
+ completion = client.chat.completions.create(
860
+ model=metadata['model'],
861
+ messages=[{"role": "user", "content": "Hello!"}]
862
+ )
863
+
864
+ print(completion.choices[0].message.content)
865
+ ```
866
+
867
+ ---
868
+
869
+ ## Available Providers (Testnet)
870
+
871
+ Query live providers dynamically:
872
+
873
+ ```python
874
+ services = broker.inference.list_service()
875
+ for s in services:
876
+ print(f"{s.model} - {s.provider}")
877
+ ```
878
+
879
+ **Example providers (as of Feb 2026):**
880
+ - `qwen/qwen-2.5-7b-instruct` - Qwen 2.5 7B chat model
881
+ - `openai/gpt-oss-20b` - GPT-compatible 20B model
882
+ - `google/gemma-3-27b-it` - Gemma 3 27B instruction-tuned
883
+ - `qwen/qwen-image-edit-2511` - Image editing model
884
+
885
+ All providers use **TeeML** (TEE-verified compute) for security.
886
+
887
+ ---
888
+
889
+ ## Error Handling
890
+
891
+ ```python
892
+ from zerog_py_sdk import (
893
+ ZGServingBrokerError,
894
+ InsufficientBalanceError,
895
+ ProviderNotAcknowledgedError,
896
+ ContractError,
897
+ NetworkError
898
+ )
899
+
900
+ try:
901
+ broker.ledger.add_ledger("0.1")
902
+ except InsufficientBalanceError as e:
903
+ print(f"Not enough OG tokens in wallet: {e}")
904
+ except ContractError as e:
905
+ print(f"Smart contract error: {e}")
906
+ except NetworkError as e:
907
+ print(f"RPC connection failed: {e}")
908
+ ```
909
+
910
+ ---
911
+
912
+ ## Troubleshooting
913
+
914
+ ### "Transaction failed" when acknowledging provider
915
+ **Cause:** Account doesn't exist yet.
916
+ **Fix:** The SDK now auto-creates accounts. Update to latest version.
917
+
918
+ ### "403 Forbidden" from provider
919
+ **Cause:** Missing `/v1/proxy` in endpoint URL.
920
+ **Fix:** Use `get_service_metadata()` - it adds the proxy path automatically.
921
+
922
+ ### "401 Unauthorized" from provider
923
+ **Cause:** Invalid or expired session token.
924
+ **Fix:** Session tokens are auto-refreshed. If using API keys, check expiration.
925
+
926
+ ### "Insufficient balance"
927
+ **Cause:** No funds in account or not transferred to provider.
928
+ **Fix:**
929
+ ```python
930
+ # Add to main ledger
931
+ broker.ledger.deposit_fund("2")
932
+
933
+ # Transfer to provider
934
+ from zerog_py_sdk.utils import og_to_wei
935
+ broker.ledger.transfer_fund(provider, "inference", og_to_wei("0.5"))
936
+ ```
937
+
938
+ ### "Provider not found" or empty service list
939
+ **Cause:** Wrong network or no providers registered.
940
+ **Fix:** Ensure you're connected to the correct network (testnet vs mainnet).
941
+
942
+ ```python
943
+ # Check which network you're on
944
+ chain_id = broker.web3.eth.chain_id
945
+ print(f"Chain ID: {chain_id}") # 16602 = testnet, 16661 = mainnet
946
+ ```
947
+
948
+ ---
949
+
950
+ ## Architecture Deep Dive
951
+
952
+ ### Pure Python Implementation
953
+
954
+ The SDK is now 100% Python with native cryptographic implementations:
955
+
956
+ **Python Benefits:**
957
+ - ✅ No Node.js/npm dependency
958
+ - ✅ Rich ML/AI ecosystem
959
+ - ✅ Web3.py for Ethereum
960
+ - ✅ Easy HTTP requests
961
+ - ✅ Familiar to AI engineers
962
+
963
+ **Native Crypto:**
964
+ - ✅ Baby JubJub elliptic curve
965
+ - ✅ EdDSA signatures
966
+ - ✅ Pedersen hash
967
+ - ✅ Compatible with TypeScript SDK
968
+
969
+ **Architecture:**
970
+ ```
971
+ Python SDK
972
+
973
+ ├── Web3.py ────────> Blockchain (RPC)
974
+ │ │
975
+ │ ├── LedgerManager contract
976
+ │ └── InferenceServing contract
977
+
978
+ ├── Requests ───────> AI Provider (HTTP)
979
+ │ │
980
+ │ └── OpenAI-compatible API
981
+
982
+ └── crypto/ ────────> Native Python
983
+
984
+ ├── EdDSA signatures
985
+ └── Pedersen hash
986
+ ```
987
+
988
+ ### Smart Contract Interaction
989
+
990
+ The SDK interacts with two main contracts:
991
+
992
+ **1. LedgerManager** (`0x5e583B...`)
993
+ - Manages user accounts and balances
994
+ - Handles deposits, withdrawals, transfers
995
+ - Tracks provider allocations
996
+
997
+ **2. InferenceServing** (`0x8e893C...`)
998
+ - Registers AI providers
999
+ - Stores service metadata (models, pricing, URLs)
1000
+ - Verifies TEE signers
1001
+ - Settles usage-based billing
1002
+
1003
+ ---
1004
+
1005
+ ## Get Testnet Tokens
1006
+
1007
+ Need 0G tokens for testing?
1008
+
1009
+ 1. Get wallet address: `broker.get_address()`
1010
+ 2. Visit faucet: https://faucet.0g.ai
1011
+ 3. Paste your address and request tokens
1012
+
1013
+ ---
1014
+
1015
+ ## Contributing
1016
+
1017
+ Contributions welcome! Please:
1018
+
1019
+ 1. Fork the repository
1020
+ 2. Create a feature branch
1021
+ 3. Make your changes
1022
+ 4. Add tests
1023
+ 5. Submit a pull request
1024
+
1025
+ ### Development Setup
1026
+
1027
+ Follow the installation steps above, then:
1028
+
1029
+ ```bash
1030
+ # Make your changes to the SDK files
1031
+ # The SDK is in zerog_py_sdk/ directory
1032
+
1033
+ # Test your changes
1034
+ python3 test.py
1035
+
1036
+ # Or create your own test script
1037
+ python3 your_script.py
1038
+ ```
1039
+
1040
+ ### Project Structure
1041
+
1042
+ ```
1043
+ 0g_py_inference/
1044
+ ├── zerog_py_sdk/ # Main SDK package
1045
+ │ ├── __init__.py # Public API exports
1046
+ │ ├── broker.py # Broker implementation
1047
+ │ ├── ledger.py # Ledger manager
1048
+ │ ├── inference.py # Inference manager
1049
+ │ ├── session.py # Session token management (NEW)
1050
+ │ ├── read_only.py # Read-only broker (NEW)
1051
+ │ ├── constants.py # Network constants (NEW)
1052
+ │ ├── extractors.py # Service type extractors (NEW)
1053
+ │ ├── cache.py # Caching system (NEW)
1054
+ │ ├── verifier.py # Response verification (NEW)
1055
+ │ ├── auth.py # Authentication utilities
1056
+ │ ├── models.py # Data models
1057
+ │ ├── exceptions.py # Custom exceptions
1058
+ │ ├── utils.py # Helper functions
1059
+ │ ├── crypto/ # Native Python crypto (NEW)
1060
+ │ │ ├── eddsa.py # EdDSA signatures
1061
+ │ │ ├── pedersen.py # Pedersen hash
1062
+ │ │ └── baby_jubjub.py # Baby JubJub curve
1063
+ │ └── contracts/ # Contract ABIs
1064
+ │ └── abis.py # Updated ABI definitions
1065
+ ├── test.py # Working example script
1066
+ ├── requirements.txt # Python dependencies
1067
+ ├── .env # Environment variables (create this)
1068
+ └── README.md # This file
1069
+ ```
1070
+
1071
+ ---
1072
+
1073
+ ## License
1074
+
1075
+ MIT License - see LICENSE file for details.
1076
+
1077
+ ---
1078
+
1079
+ ## Links
1080
+
1081
+ - [0G Documentation](https://docs.0g.ai/)
1082
+ - [TypeScript SDK](https://github.com/0glabs/0g-serving-broker)
1083
+ - [Compute Network Docs](https://docs.0g.ai/developer-hub/building-on-0g/compute-network/sdk)
1084
+ - [Author Twitter/X](https://x.com/damiclone)
1085
+
1086
+ ---
1087
+
1088
+ ## Support
1089
+
1090
+ For issues and questions:
1091
+ - **GitHub Issues**: [Report a bug](https://github.com/0glabs/0g-compute-sdk-python/issues)
1092
+ - **Discord**: [0G Labs Community](https://discord.gg/0glabs)
1093
+ - **Documentation**: [docs.0g.ai](https://docs.0g.ai/)
1094
+
1095
+ ---
1096
+
1097
+ ## Changelog
1098
+
1099
+ ### v0.2.0 (Latest - Feb 2026)
1100
+ - ✅ **Session Token Auth**: New simplified authorization system (no content parameter needed)
1101
+ - ✅ **No Node.js Dependency**: Native Python crypto implementation
1102
+ - ✅ **Read-Only Broker**: Browse services without wallet connection
1103
+ - ✅ **Multi-Network Support**: Mainnet/testnet with auto-detection
1104
+ - ✅ **API Key Management**: Create persistent, revocable API keys
1105
+ - ✅ **Response Verification**: Verify TEE-signed responses
1106
+ - ✅ **Caching System**: Built-in caching for performance
1107
+ - ✅ **Service Extractors**: Support for chatbot, image, speech services
1108
+ - ✅ **Updated ABIs**: Compatible with latest 0G contracts
1109
+
1110
+ ### v0.1.0
1111
+ - ✅ Fixed endpoint URL - now correctly appends `/v1/proxy`
1112
+ - ✅ Auto-creates accounts when acknowledging providers
1113
+ - ✅ Improved error handling
1114
+ - ✅ Added complete working example
1115
+ - ✅ Full documentation with architecture details