web3-agent-kit 0.6.0__tar.gz → 0.8.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 (62) hide show
  1. {web3_agent_kit-0.6.0/web3_agent_kit.egg-info → web3_agent_kit-0.8.0}/PKG-INFO +115 -2
  2. {web3_agent_kit-0.6.0 → web3_agent_kit-0.8.0}/README.md +114 -1
  3. {web3_agent_kit-0.6.0 → web3_agent_kit-0.8.0}/pyproject.toml +1 -1
  4. web3_agent_kit-0.8.0/src/airdrop/__init__.py +65 -0
  5. web3_agent_kit-0.8.0/src/airdrop/base.py +268 -0
  6. web3_agent_kit-0.8.0/src/airdrop/galxe.py +327 -0
  7. web3_agent_kit-0.8.0/src/airdrop/gleam.py +208 -0
  8. web3_agent_kit-0.8.0/src/airdrop/multi_wallet.py +264 -0
  9. web3_agent_kit-0.8.0/src/airdrop/social.py +430 -0
  10. web3_agent_kit-0.8.0/src/airdrop/tracker.py +339 -0
  11. web3_agent_kit-0.8.0/src/airdrop/zealy.py +234 -0
  12. web3_agent_kit-0.8.0/src/api/__init__.py +138 -0
  13. web3_agent_kit-0.8.0/src/api/models.py +162 -0
  14. web3_agent_kit-0.8.0/src/api/routes/__init__.py +25 -0
  15. web3_agent_kit-0.8.0/src/api/routes/approval.py +80 -0
  16. web3_agent_kit-0.8.0/src/api/routes/bridge.py +59 -0
  17. web3_agent_kit-0.8.0/src/api/routes/dca.py +111 -0
  18. web3_agent_kit-0.8.0/src/api/routes/gas.py +46 -0
  19. web3_agent_kit-0.8.0/src/api/routes/portfolio.py +45 -0
  20. web3_agent_kit-0.8.0/src/api/routes/swap.py +63 -0
  21. web3_agent_kit-0.8.0/src/api/routes/wallet.py +54 -0
  22. web3_agent_kit-0.8.0/src/api/routes/watcher.py +89 -0
  23. web3_agent_kit-0.8.0/src/api/routes/yield_opt.py +72 -0
  24. web3_agent_kit-0.8.0/tests/test_airdrop.py +439 -0
  25. web3_agent_kit-0.8.0/tests/test_api.py +420 -0
  26. {web3_agent_kit-0.6.0 → web3_agent_kit-0.8.0}/tests/test_new_features.py +14 -7
  27. {web3_agent_kit-0.6.0 → web3_agent_kit-0.8.0/web3_agent_kit.egg-info}/PKG-INFO +115 -2
  28. {web3_agent_kit-0.6.0 → web3_agent_kit-0.8.0}/web3_agent_kit.egg-info/SOURCES.txt +22 -0
  29. {web3_agent_kit-0.6.0 → web3_agent_kit-0.8.0}/LICENSE +0 -0
  30. {web3_agent_kit-0.6.0 → web3_agent_kit-0.8.0}/setup.cfg +0 -0
  31. {web3_agent_kit-0.6.0 → web3_agent_kit-0.8.0}/setup.py +0 -0
  32. {web3_agent_kit-0.6.0 → web3_agent_kit-0.8.0}/src/__init__.py +0 -0
  33. {web3_agent_kit-0.6.0 → web3_agent_kit-0.8.0}/src/agent.py +0 -0
  34. {web3_agent_kit-0.6.0 → web3_agent_kit-0.8.0}/src/approval_manager.py +0 -0
  35. {web3_agent_kit-0.6.0 → web3_agent_kit-0.8.0}/src/bridge.py +0 -0
  36. {web3_agent_kit-0.6.0 → web3_agent_kit-0.8.0}/src/chain.py +0 -0
  37. {web3_agent_kit-0.6.0 → web3_agent_kit-0.8.0}/src/dca_bot.py +0 -0
  38. {web3_agent_kit-0.6.0 → web3_agent_kit-0.8.0}/src/defi/__init__.py +0 -0
  39. {web3_agent_kit-0.6.0 → web3_agent_kit-0.8.0}/src/gas_optimizer.py +0 -0
  40. {web3_agent_kit-0.6.0 → web3_agent_kit-0.8.0}/src/llm.py +0 -0
  41. {web3_agent_kit-0.6.0 → web3_agent_kit-0.8.0}/src/multi_wallet.py +0 -0
  42. {web3_agent_kit-0.6.0 → web3_agent_kit-0.8.0}/src/plugins/__init__.py +0 -0
  43. {web3_agent_kit-0.6.0 → web3_agent_kit-0.8.0}/src/plugins/examples/gas_tracker.py +0 -0
  44. {web3_agent_kit-0.6.0 → web3_agent_kit-0.8.0}/src/portfolio.py +0 -0
  45. {web3_agent_kit-0.6.0 → web3_agent_kit-0.8.0}/src/sniper.py +0 -0
  46. {web3_agent_kit-0.6.0 → web3_agent_kit-0.8.0}/src/utils/__init__.py +0 -0
  47. {web3_agent_kit-0.6.0 → web3_agent_kit-0.8.0}/src/wallet.py +0 -0
  48. {web3_agent_kit-0.6.0 → web3_agent_kit-0.8.0}/src/wallet_watcher.py +0 -0
  49. {web3_agent_kit-0.6.0 → web3_agent_kit-0.8.0}/src/yield_optimizer.py +0 -0
  50. {web3_agent_kit-0.6.0 → web3_agent_kit-0.8.0}/tests/test_bridge.py +0 -0
  51. {web3_agent_kit-0.6.0 → web3_agent_kit-0.8.0}/tests/test_core.py +0 -0
  52. {web3_agent_kit-0.6.0 → web3_agent_kit-0.8.0}/tests/test_dca_bot.py +0 -0
  53. {web3_agent_kit-0.6.0 → web3_agent_kit-0.8.0}/tests/test_defi.py +0 -0
  54. {web3_agent_kit-0.6.0 → web3_agent_kit-0.8.0}/tests/test_llm.py +0 -0
  55. {web3_agent_kit-0.6.0 → web3_agent_kit-0.8.0}/tests/test_multi_wallet.py +0 -0
  56. {web3_agent_kit-0.6.0 → web3_agent_kit-0.8.0}/tests/test_plugins.py +0 -0
  57. {web3_agent_kit-0.6.0 → web3_agent_kit-0.8.0}/tests/test_portfolio.py +0 -0
  58. {web3_agent_kit-0.6.0 → web3_agent_kit-0.8.0}/tests/test_sniper.py +0 -0
  59. {web3_agent_kit-0.6.0 → web3_agent_kit-0.8.0}/tests/test_yield_optimizer.py +0 -0
  60. {web3_agent_kit-0.6.0 → web3_agent_kit-0.8.0}/web3_agent_kit.egg-info/dependency_links.txt +0 -0
  61. {web3_agent_kit-0.6.0 → web3_agent_kit-0.8.0}/web3_agent_kit.egg-info/requires.txt +0 -0
  62. {web3_agent_kit-0.6.0 → web3_agent_kit-0.8.0}/web3_agent_kit.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: web3-agent-kit
3
- Version: 0.6.0
3
+ Version: 0.8.0
4
4
  Summary: Open-source framework for building autonomous AI agents that interact with blockchain networks
5
5
  Author-email: Maulana <khasbim240803@gmail.com>
6
6
  License: MIT
@@ -68,6 +68,7 @@ Building AI agents that interact with blockchains is **hard**. You need to juggl
68
68
  | **Security** | Manual approval checks | Auto-scan & revoke risky approvals |
69
69
  | **Alerts** | Manual whale tracking | Auto-monitor wallets, instant alerts |
70
70
  | **Multi-wallet** | Manage keys manually | Batch ops, consolidated portfolio, wallet groups |
71
+ | **Airdrops** | Manual quest hunting | Auto-track campaigns, multi-wallet farming, Sybil-safe |
71
72
  | **Extensibility** | Hard-coded logic | Plugin system — community can extend anything |
72
73
  | **Error Handling** | Manual retry logic | Auto-fallback across LLM providers & RPCs |
73
74
 
@@ -141,6 +142,7 @@ Building AI agents that interact with blockchains is **hard**. You need to juggl
141
142
  | **Wallet Watcher** | ✅ | ❌ | ❌ | ❌ |
142
143
  | **Yield Optimizer** | ✅ | ❌ | ❌ | ❌ |
143
144
  | **Multi-Wallet** | ✅ | ❌ | ❌ | ❌ |
145
+ | **Airdrops** | ✅ | ❌ | ❌ | ❌ |
144
146
  | **Plugin System** | ✅ | ❌ | ❌ | ❌ |
145
147
  | **Safety Rails** | ✅ Governor | ❌ | ❌ | ❌ |
146
148
  | **Natural Language** | ✅ | Partial | ❌ | ❌ |
@@ -236,6 +238,55 @@ python my_agent.py
236
238
 
237
239
  ---
238
240
 
241
+ ## 🌐 REST API
242
+
243
+ Full HTTP API for all modules — use from any language (JavaScript, curl, etc):
244
+
245
+ ```bash
246
+ # Start the API server
247
+ python -m src.api
248
+
249
+ # Or with API key
250
+ WEB3_API_KEY=your-secret python -m src.api
251
+ ```
252
+
253
+ **Endpoints:**
254
+
255
+ | Endpoint | Method | Description |
256
+ |----------|--------|-------------|
257
+ | `/wallet/info` | GET | Wallet info + balance |
258
+ | `/swap/quote` | GET | Get swap quote |
259
+ | `/swap/execute` | POST | Execute token swap |
260
+ | `/portfolio/` | GET | Portfolio dashboard |
261
+ | `/gas/estimate` | GET | Gas estimates (EIP-1559) |
262
+ | `/gas/recommendation` | GET | Gas timing recommendation |
263
+ | `/watcher/list` | GET | List watched wallets |
264
+ | `/watcher/add` | POST | Add wallet to watch |
265
+ | `/approval/scan` | GET | Scan token approvals |
266
+ | `/approval/risk` | GET | Risk report |
267
+ | `/dca/orders` | GET/POST | List/create DCA orders |
268
+ | `/yield/opportunities` | GET | Scan yield opportunities |
269
+ | `/yield/best` | GET | Find best yield |
270
+ | `/bridge/quote` | GET | Get bridge quote |
271
+ | `/bridge/execute` | POST | Execute bridge |
272
+ | `/health` | GET | Health check |
273
+ | `/docs` | GET | Swagger UI |
274
+ | `/redoc` | GET | ReDoc documentation |
275
+
276
+ **Example:**
277
+ ```bash
278
+ # Get gas estimate
279
+ curl http://localhost:8000/gas/estimate?chain=ethereum
280
+
281
+ # Get swap quote
282
+ curl "http://localhost:8000/swap/quote?token_in=ETH&token_out=USDC&amount_in=1.0"
283
+
284
+ # Scan approvals
285
+ curl http://localhost:8000/approval/scan?chain=ethereum
286
+ ```
287
+
288
+ ---
289
+
239
290
  ## 🎯 Showcase
240
291
 
241
292
  ### Telegram Bot
@@ -267,6 +318,7 @@ Features: balance check, token swap, portfolio tracking, token sniper, cross-cha
267
318
  | `examples/multi_wallet.py` | Multi-wallet management + batch ops |
268
319
  | `examples/plugin_system.py` | Plugin system usage + custom plugins |
269
320
  | `examples/dca_bot.py` | Dollar-cost averaging bot with intervals & limits |
321
+ | `examples/api_server.py` | REST API server with Swagger docs |
270
322
  | `examples/airdrop_farmer.py` | Multi-chain airdrop farming |
271
323
  | `examples/sniper_bot.py` | Token launch sniper |
272
324
  | `examples/portfolio_tracker.py` | Portfolio tracking & reporting |
@@ -353,6 +405,54 @@ print(summary)
353
405
 
354
406
  ---
355
407
 
408
+ ## 🪂 Airdrop Automation
409
+
410
+ Discover, track, and complete airdrop campaigns across multiple platforms:
411
+
412
+ ```python
413
+ from web3_agent_kit.airdrop import (
414
+ GalxePlatform, ZealyPlatform, GleamCampaign,
415
+ AirdropTracker, AirdropFarmer, SocialTaskManager,
416
+ PlatformConfig, TaskType, SybilAvoidanceConfig,
417
+ )
418
+
419
+ # Track campaigns across platforms
420
+ tracker = AirdropTracker()
421
+
422
+ # Galxe integration
423
+ galxe = GalxePlatform(config=PlatformConfig(api_key="your_key"))
424
+ galxe.login({"api_key": "your_key"})
425
+ tasks = galxe.get_tasks("campaign_id")
426
+ for task in tasks:
427
+ galxe.complete_task(task)
428
+
429
+ # Social task automation
430
+ social = SocialTaskManager()
431
+ social.complete_social_task(TaskType.SOCIAL_TWITTER_FOLLOW, "defi_project")
432
+ social.complete_social_task(TaskType.SOCIAL_DISCORD_JOIN, "https://discord.gg/invite")
433
+
434
+ # Multi-wallet farming with Sybil avoidance
435
+ farmer = AirdropFarmer(
436
+ wallet_manager=manager,
437
+ group="airdrop",
438
+ config=SybilAvoidanceConfig(
439
+ min_delay_between_wallets=60,
440
+ max_delay_between_wallets=600,
441
+ max_tasks_per_wallet_per_day=10,
442
+ ),
443
+ )
444
+ results = farmer.farm_campaign(campaign, execute=True)
445
+
446
+ # Export report
447
+ tracker.export_json("./airdrop_report.json")
448
+ tracker.export_csv("./airdrop_report.csv")
449
+ ```
450
+
451
+ **Supported platforms:** Gleam.io, Zealy (Crew3), Galxe (Project Galaxy)
452
+ **Social tasks:** Twitter, Discord, Telegram, YouTube, GitHub
453
+
454
+ ---
455
+
356
456
  ## 🌉 Bridge Agent
357
457
 
358
458
  Cross-chain transfers via Li.Fi and Socket:
@@ -483,13 +583,26 @@ web3-agent-kit/
483
583
  │ ├── bridge.py # Cross-chain bridge agent
484
584
  │ ├── yield_optimizer.py # Yield optimizer + auto-compound
485
585
  │ ├── multi_wallet.py # Multi-wallet manager + batch ops
586
+ │ ├── airdrop/ # Airdrop automation module
587
+ │ │ ├── __init__.py # Package exports
588
+ │ │ ├── base.py # Base platform abstraction
589
+ │ │ ├── gleam.py # Gleam.io automation
590
+ │ │ ├── zealy.py # Zealy quest automation
591
+ │ │ ├── galxe.py # Galxe campaign automation
592
+ │ │ ├── social.py # Social task helpers
593
+ │ │ ├── tracker.py # Airdrop tracker
594
+ │ │ └── multi_wallet.py # Multi-wallet farming
486
595
  │ ├── plugins/
487
596
  │ │ ├── __init__.py # Plugin system (base, registry, manager)
488
597
  │ │ └── examples/
489
598
  │ │ └── gas_tracker.py
599
+ │ ├── api/
600
+ │ │ ├── __init__.py # FastAPI REST API server
601
+ │ │ ├── models.py # Pydantic request/response models
602
+ │ │ └── routes/ # API route handlers
490
603
  │ └── defi/
491
604
  │ └── __init__.py # Uniswap, Aerodrome, Aave, Curve
492
- ├── examples/ # 13 ready-to-use examples
605
+ ├── examples/ # 15 ready-to-use examples
493
606
  ├── tests/ # Test suite
494
607
  └── docs/ # Documentation
495
608
  ```
@@ -34,6 +34,7 @@ Building AI agents that interact with blockchains is **hard**. You need to juggl
34
34
  | **Security** | Manual approval checks | Auto-scan & revoke risky approvals |
35
35
  | **Alerts** | Manual whale tracking | Auto-monitor wallets, instant alerts |
36
36
  | **Multi-wallet** | Manage keys manually | Batch ops, consolidated portfolio, wallet groups |
37
+ | **Airdrops** | Manual quest hunting | Auto-track campaigns, multi-wallet farming, Sybil-safe |
37
38
  | **Extensibility** | Hard-coded logic | Plugin system — community can extend anything |
38
39
  | **Error Handling** | Manual retry logic | Auto-fallback across LLM providers & RPCs |
39
40
 
@@ -107,6 +108,7 @@ Building AI agents that interact with blockchains is **hard**. You need to juggl
107
108
  | **Wallet Watcher** | ✅ | ❌ | ❌ | ❌ |
108
109
  | **Yield Optimizer** | ✅ | ❌ | ❌ | ❌ |
109
110
  | **Multi-Wallet** | ✅ | ❌ | ❌ | ❌ |
111
+ | **Airdrops** | ✅ | ❌ | ❌ | ❌ |
110
112
  | **Plugin System** | ✅ | ❌ | ❌ | ❌ |
111
113
  | **Safety Rails** | ✅ Governor | ❌ | ❌ | ❌ |
112
114
  | **Natural Language** | ✅ | Partial | ❌ | ❌ |
@@ -202,6 +204,55 @@ python my_agent.py
202
204
 
203
205
  ---
204
206
 
207
+ ## 🌐 REST API
208
+
209
+ Full HTTP API for all modules — use from any language (JavaScript, curl, etc):
210
+
211
+ ```bash
212
+ # Start the API server
213
+ python -m src.api
214
+
215
+ # Or with API key
216
+ WEB3_API_KEY=your-secret python -m src.api
217
+ ```
218
+
219
+ **Endpoints:**
220
+
221
+ | Endpoint | Method | Description |
222
+ |----------|--------|-------------|
223
+ | `/wallet/info` | GET | Wallet info + balance |
224
+ | `/swap/quote` | GET | Get swap quote |
225
+ | `/swap/execute` | POST | Execute token swap |
226
+ | `/portfolio/` | GET | Portfolio dashboard |
227
+ | `/gas/estimate` | GET | Gas estimates (EIP-1559) |
228
+ | `/gas/recommendation` | GET | Gas timing recommendation |
229
+ | `/watcher/list` | GET | List watched wallets |
230
+ | `/watcher/add` | POST | Add wallet to watch |
231
+ | `/approval/scan` | GET | Scan token approvals |
232
+ | `/approval/risk` | GET | Risk report |
233
+ | `/dca/orders` | GET/POST | List/create DCA orders |
234
+ | `/yield/opportunities` | GET | Scan yield opportunities |
235
+ | `/yield/best` | GET | Find best yield |
236
+ | `/bridge/quote` | GET | Get bridge quote |
237
+ | `/bridge/execute` | POST | Execute bridge |
238
+ | `/health` | GET | Health check |
239
+ | `/docs` | GET | Swagger UI |
240
+ | `/redoc` | GET | ReDoc documentation |
241
+
242
+ **Example:**
243
+ ```bash
244
+ # Get gas estimate
245
+ curl http://localhost:8000/gas/estimate?chain=ethereum
246
+
247
+ # Get swap quote
248
+ curl "http://localhost:8000/swap/quote?token_in=ETH&token_out=USDC&amount_in=1.0"
249
+
250
+ # Scan approvals
251
+ curl http://localhost:8000/approval/scan?chain=ethereum
252
+ ```
253
+
254
+ ---
255
+
205
256
  ## 🎯 Showcase
206
257
 
207
258
  ### Telegram Bot
@@ -233,6 +284,7 @@ Features: balance check, token swap, portfolio tracking, token sniper, cross-cha
233
284
  | `examples/multi_wallet.py` | Multi-wallet management + batch ops |
234
285
  | `examples/plugin_system.py` | Plugin system usage + custom plugins |
235
286
  | `examples/dca_bot.py` | Dollar-cost averaging bot with intervals & limits |
287
+ | `examples/api_server.py` | REST API server with Swagger docs |
236
288
  | `examples/airdrop_farmer.py` | Multi-chain airdrop farming |
237
289
  | `examples/sniper_bot.py` | Token launch sniper |
238
290
  | `examples/portfolio_tracker.py` | Portfolio tracking & reporting |
@@ -319,6 +371,54 @@ print(summary)
319
371
 
320
372
  ---
321
373
 
374
+ ## 🪂 Airdrop Automation
375
+
376
+ Discover, track, and complete airdrop campaigns across multiple platforms:
377
+
378
+ ```python
379
+ from web3_agent_kit.airdrop import (
380
+ GalxePlatform, ZealyPlatform, GleamCampaign,
381
+ AirdropTracker, AirdropFarmer, SocialTaskManager,
382
+ PlatformConfig, TaskType, SybilAvoidanceConfig,
383
+ )
384
+
385
+ # Track campaigns across platforms
386
+ tracker = AirdropTracker()
387
+
388
+ # Galxe integration
389
+ galxe = GalxePlatform(config=PlatformConfig(api_key="your_key"))
390
+ galxe.login({"api_key": "your_key"})
391
+ tasks = galxe.get_tasks("campaign_id")
392
+ for task in tasks:
393
+ galxe.complete_task(task)
394
+
395
+ # Social task automation
396
+ social = SocialTaskManager()
397
+ social.complete_social_task(TaskType.SOCIAL_TWITTER_FOLLOW, "defi_project")
398
+ social.complete_social_task(TaskType.SOCIAL_DISCORD_JOIN, "https://discord.gg/invite")
399
+
400
+ # Multi-wallet farming with Sybil avoidance
401
+ farmer = AirdropFarmer(
402
+ wallet_manager=manager,
403
+ group="airdrop",
404
+ config=SybilAvoidanceConfig(
405
+ min_delay_between_wallets=60,
406
+ max_delay_between_wallets=600,
407
+ max_tasks_per_wallet_per_day=10,
408
+ ),
409
+ )
410
+ results = farmer.farm_campaign(campaign, execute=True)
411
+
412
+ # Export report
413
+ tracker.export_json("./airdrop_report.json")
414
+ tracker.export_csv("./airdrop_report.csv")
415
+ ```
416
+
417
+ **Supported platforms:** Gleam.io, Zealy (Crew3), Galxe (Project Galaxy)
418
+ **Social tasks:** Twitter, Discord, Telegram, YouTube, GitHub
419
+
420
+ ---
421
+
322
422
  ## 🌉 Bridge Agent
323
423
 
324
424
  Cross-chain transfers via Li.Fi and Socket:
@@ -449,13 +549,26 @@ web3-agent-kit/
449
549
  │ ├── bridge.py # Cross-chain bridge agent
450
550
  │ ├── yield_optimizer.py # Yield optimizer + auto-compound
451
551
  │ ├── multi_wallet.py # Multi-wallet manager + batch ops
552
+ │ ├── airdrop/ # Airdrop automation module
553
+ │ │ ├── __init__.py # Package exports
554
+ │ │ ├── base.py # Base platform abstraction
555
+ │ │ ├── gleam.py # Gleam.io automation
556
+ │ │ ├── zealy.py # Zealy quest automation
557
+ │ │ ├── galxe.py # Galxe campaign automation
558
+ │ │ ├── social.py # Social task helpers
559
+ │ │ ├── tracker.py # Airdrop tracker
560
+ │ │ └── multi_wallet.py # Multi-wallet farming
452
561
  │ ├── plugins/
453
562
  │ │ ├── __init__.py # Plugin system (base, registry, manager)
454
563
  │ │ └── examples/
455
564
  │ │ └── gas_tracker.py
565
+ │ ├── api/
566
+ │ │ ├── __init__.py # FastAPI REST API server
567
+ │ │ ├── models.py # Pydantic request/response models
568
+ │ │ └── routes/ # API route handlers
456
569
  │ └── defi/
457
570
  │ └── __init__.py # Uniswap, Aerodrome, Aave, Curve
458
- ├── examples/ # 13 ready-to-use examples
571
+ ├── examples/ # 15 ready-to-use examples
459
572
  ├── tests/ # Test suite
460
573
  └── docs/ # Documentation
461
574
  ```
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "web3-agent-kit"
7
- version = "0.6.0"
7
+ version = "0.8.0"
8
8
  description = "Open-source framework for building autonomous AI agents that interact with blockchain networks"
9
9
  readme = "README.md"
10
10
  license = {text = "MIT"}
@@ -0,0 +1,65 @@
1
+ """Airdrop automation module — discover, track, and complete airdrop campaigns."""
2
+
3
+ from .base import (
4
+ BaseAirdropPlatform,
5
+ PlatformConfig,
6
+ AirdropTask,
7
+ AirdropCampaign,
8
+ TaskType,
9
+ TaskStatus,
10
+ )
11
+ from .gleam import GleamCampaign
12
+ from .zealy import ZealyPlatform, ZealyQuest, ZealyLeaderboardEntry
13
+ from .galxe import GalxePlatform, GalxeCredential, GalxePoints
14
+ from .social import (
15
+ SocialTaskManager,
16
+ SocialAccount,
17
+ SocialPlatform,
18
+ SocialTaskResult,
19
+ TwitterHelper,
20
+ DiscordHelper,
21
+ TelegramHelper,
22
+ YouTubeHelper,
23
+ GitHubHelper,
24
+ )
25
+ from .tracker import AirdropTracker, AirdropReward, AirdropSummary
26
+ from .multi_wallet import AirdropFarmer, SybilAvoidanceConfig, FarmResult, WalletFarmProgress
27
+
28
+ __all__ = [
29
+ # Base
30
+ "BaseAirdropPlatform",
31
+ "PlatformConfig",
32
+ "AirdropTask",
33
+ "AirdropCampaign",
34
+ "TaskType",
35
+ "TaskStatus",
36
+ # Gleam
37
+ "GleamCampaign",
38
+ # Zealy
39
+ "ZealyPlatform",
40
+ "ZealyQuest",
41
+ "ZealyLeaderboardEntry",
42
+ # Galxe
43
+ "GalxePlatform",
44
+ "GalxeCredential",
45
+ "GalxePoints",
46
+ # Social
47
+ "SocialTaskManager",
48
+ "SocialAccount",
49
+ "SocialPlatform",
50
+ "SocialTaskResult",
51
+ "TwitterHelper",
52
+ "DiscordHelper",
53
+ "TelegramHelper",
54
+ "YouTubeHelper",
55
+ "GitHubHelper",
56
+ # Tracker
57
+ "AirdropTracker",
58
+ "AirdropReward",
59
+ "AirdropSummary",
60
+ # Multi-wallet farming
61
+ "AirdropFarmer",
62
+ "SybilAvoidanceConfig",
63
+ "FarmResult",
64
+ "WalletFarmProgress",
65
+ ]
@@ -0,0 +1,268 @@
1
+ """Base airdrop platform abstraction — common interface for all platforms."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import logging
6
+ import time
7
+ from abc import ABC, abstractmethod
8
+ from dataclasses import dataclass, field
9
+ from enum import Enum
10
+ from typing import Optional
11
+
12
+ import requests
13
+
14
+ logger = logging.getLogger(__name__)
15
+
16
+
17
+ class TaskType(Enum):
18
+ """Types of airdrop tasks."""
19
+ SOCIAL_TWITTER_FOLLOW = "twitter_follow"
20
+ SOCIAL_TWITTER_RETWEET = "twitter_retweet"
21
+ SOCIAL_TWITTER_LIKE = "twitter_like"
22
+ SOCIAL_TWITTER_COMMENT = "twitter_comment"
23
+ SOCIAL_DISCORD_JOIN = "discord_join"
24
+ SOCIAL_DISCORD_VERIFY = "discord_verify"
25
+ SOCIAL_TELEGRAM_JOIN = "telegram_join"
26
+ SOCIAL_YOUTUBE_SUBSCRIBE = "youtube_subscribe"
27
+ SOCIAL_GITHUB_STAR = "github_star"
28
+ SOCIAL_GITHUB_FORK = "github_fork"
29
+ ON_CHAIN_TX = "on_chain_tx"
30
+ ON_CHAIN_SWAP = "on_chain_swap"
31
+ ON_CHAIN_BRIDGE = "on_chain_bridge"
32
+ ON_CHAIN_STAKE = "on_chain_stake"
33
+ QUIZ = "quiz"
34
+ VISIT_URL = "visit_url"
35
+ WALLET_CONNECT = "wallet_connect"
36
+ REFERRAL = "referral"
37
+ CUSTOM = "custom"
38
+
39
+
40
+ class TaskStatus(Enum):
41
+ """Status of a task."""
42
+ PENDING = "pending"
43
+ IN_PROGRESS = "in_progress"
44
+ COMPLETED = "completed"
45
+ VERIFIED = "verified"
46
+ FAILED = "failed"
47
+ SKIPPED = "skipped"
48
+
49
+
50
+ @dataclass
51
+ class AirdropTask:
52
+ """A single airdrop task."""
53
+ task_id: str
54
+ platform: str
55
+ task_type: TaskType
56
+ title: str
57
+ description: str = ""
58
+ url: str = ""
59
+ points: float = 0
60
+ status: TaskStatus = TaskStatus.PENDING
61
+ completed_at: Optional[float] = None
62
+ metadata: dict = field(default_factory=dict)
63
+
64
+ @property
65
+ def is_social(self) -> bool:
66
+ return self.task_type.name.startswith("SOCIAL_")
67
+
68
+ @property
69
+ def is_on_chain(self) -> bool:
70
+ return self.task_type.name.startswith("ON_CHAIN_")
71
+
72
+
73
+ @dataclass
74
+ class AirdropCampaign:
75
+ """An airdrop campaign listing."""
76
+ campaign_id: str
77
+ platform: str
78
+ name: str
79
+ description: str = ""
80
+ url: str = ""
81
+ total_points: float = 0
82
+ earned_points: float = 0
83
+ deadline: Optional[float] = None
84
+ tasks: list[AirdropTask] = field(default_factory=list)
85
+ is_active: bool = True
86
+ metadata: dict = field(default_factory=dict)
87
+
88
+ @property
89
+ def progress(self) -> float:
90
+ if self.total_points == 0:
91
+ return 0.0
92
+ return self.earned_points / self.total_points
93
+
94
+ @property
95
+ def is_expired(self) -> bool:
96
+ if self.deadline is None:
97
+ return False
98
+ return time.time() > self.deadline
99
+
100
+
101
+ @dataclass
102
+ class PlatformConfig:
103
+ """Configuration for an airdrop platform."""
104
+ api_key: Optional[str] = None
105
+ session_cookie: Optional[str] = None
106
+ user_agent: str = (
107
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
108
+ "AppleWebKit/537.36 (KHTML, like Gecko) "
109
+ "Chrome/120.0.0.0 Safari/537.36"
110
+ )
111
+ rate_limit_delay: float = 2.0
112
+ max_retries: int = 3
113
+ retry_delay: float = 5.0
114
+ timeout: int = 30
115
+ proxy: Optional[str] = None
116
+
117
+
118
+ class BaseAirdropPlatform(ABC):
119
+ """Abstract base class for all airdrop platform integrations.
120
+
121
+ Provides common functionality: session management, rate limiting,
122
+ retry logic, and the standard interface every platform must implement.
123
+
124
+ Example::
125
+
126
+ class MyPlatform(BaseAirdropPlatform):
127
+ platform_name = "my_platform"
128
+
129
+ def login(self, credentials):
130
+ ...
131
+
132
+ def get_tasks(self, campaign_id):
133
+ ...
134
+
135
+ def complete_task(self, task):
136
+ ...
137
+
138
+ def verify_completion(self, task):
139
+ ...
140
+ """
141
+
142
+ platform_name: str = "unknown"
143
+
144
+ def __init__(self, config: Optional[PlatformConfig] = None):
145
+ self.config = config or PlatformConfig()
146
+ self.session = requests.Session()
147
+ self.session.headers.update({
148
+ "User-Agent": self.config.user_agent,
149
+ })
150
+ if self.config.session_cookie:
151
+ self.session.cookies.set("session", self.config.session_cookie)
152
+ if self.config.proxy:
153
+ self.session.proxies = {"http": self.config.proxy, "https": self.config.proxy}
154
+ self._last_request_time: float = 0
155
+ self._authenticated: bool = False
156
+ logger.info(f"Initialized {self.platform_name} platform")
157
+
158
+ @abstractmethod
159
+ def login(self, credentials: dict) -> bool:
160
+ """Authenticate with the platform.
161
+
162
+ Args:
163
+ credentials: Platform-specific credentials.
164
+
165
+ Returns:
166
+ True if login succeeded.
167
+ """
168
+ ...
169
+
170
+ @abstractmethod
171
+ def get_tasks(self, campaign_id: str) -> list[AirdropTask]:
172
+ """Get available tasks for a campaign.
173
+
174
+ Args:
175
+ campaign_id: Platform-specific campaign identifier.
176
+
177
+ Returns:
178
+ List of AirdropTask objects.
179
+ """
180
+ ...
181
+
182
+ @abstractmethod
183
+ def complete_task(self, task: AirdropTask) -> bool:
184
+ """Attempt to complete a task.
185
+
186
+ Args:
187
+ task: The task to complete.
188
+
189
+ Returns:
190
+ True if task was completed successfully.
191
+ """
192
+ ...
193
+
194
+ @abstractmethod
195
+ def verify_completion(self, task: AirdropTask) -> bool:
196
+ """Verify that a task is completed.
197
+
198
+ Args:
199
+ task: The task to verify.
200
+
201
+ Returns:
202
+ True if verified as completed.
203
+ """
204
+ ...
205
+
206
+ def discover_campaigns(self) -> list[AirdropCampaign]:
207
+ """Discover available campaigns. Override in subclasses.
208
+
209
+ Returns:
210
+ List of AirdropCampaign objects.
211
+ """
212
+ return []
213
+
214
+ def _rate_limit(self):
215
+ """Enforce rate limiting between requests."""
216
+ elapsed = time.time() - self._last_request_time
217
+ if elapsed < self.config.rate_limit_delay:
218
+ sleep_time = self.config.rate_limit_delay - elapsed
219
+ logger.debug(f"Rate limiting: sleeping {sleep_time:.1f}s")
220
+ time.sleep(sleep_time)
221
+ self._last_request_time = time.time()
222
+
223
+ def _request(
224
+ self,
225
+ method: str,
226
+ url: str,
227
+ **kwargs,
228
+ ) -> requests.Response:
229
+ """Make an HTTP request with rate limiting and retry logic.
230
+
231
+ Args:
232
+ method: HTTP method (GET, POST, etc.).
233
+ url: Request URL.
234
+ **kwargs: Passed to requests.
235
+
236
+ Returns:
237
+ Response object.
238
+
239
+ Raises:
240
+ requests.RequestException: After all retries exhausted.
241
+ """
242
+ kwargs.setdefault("timeout", self.config.timeout)
243
+ last_error = None
244
+
245
+ for attempt in range(self.config.max_retries):
246
+ self._rate_limit()
247
+ try:
248
+ response = self.session.request(method, url, **kwargs)
249
+ if response.status_code == 429:
250
+ retry_after = int(response.headers.get("Retry-After", self.config.retry_delay))
251
+ logger.warning(f"Rate limited, waiting {retry_after}s")
252
+ time.sleep(retry_after)
253
+ continue
254
+ response.raise_for_status()
255
+ return response
256
+ except requests.RequestException as e:
257
+ last_error = e
258
+ logger.warning(f"Request failed (attempt {attempt + 1}): {e}")
259
+ if attempt < self.config.max_retries - 1:
260
+ time.sleep(self.config.retry_delay * (attempt + 1))
261
+
262
+ raise last_error # type: ignore[misc]
263
+
264
+ def _get(self, url: str, **kwargs) -> requests.Response:
265
+ return self._request("GET", url, **kwargs)
266
+
267
+ def _post(self, url: str, **kwargs) -> requests.Response:
268
+ return self._request("POST", url, **kwargs)