web3-agent-kit 0.7.0__tar.gz → 0.9.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 (69) hide show
  1. {web3_agent_kit-0.7.0/web3_agent_kit.egg-info → web3_agent_kit-0.9.0}/PKG-INFO +60 -1
  2. {web3_agent_kit-0.7.0 → web3_agent_kit-0.9.0}/README.md +59 -0
  3. {web3_agent_kit-0.7.0 → web3_agent_kit-0.9.0}/pyproject.toml +1 -1
  4. web3_agent_kit-0.9.0/src/airdrop/__init__.py +65 -0
  5. web3_agent_kit-0.9.0/src/airdrop/base.py +268 -0
  6. web3_agent_kit-0.9.0/src/airdrop/executor/__init__.py +33 -0
  7. web3_agent_kit-0.9.0/src/airdrop/executor/browser.py +435 -0
  8. web3_agent_kit-0.9.0/src/airdrop/executor/cli.py +402 -0
  9. web3_agent_kit-0.9.0/src/airdrop/executor/gleam_exec.py +664 -0
  10. web3_agent_kit-0.9.0/src/airdrop/executor/social_exec.py +789 -0
  11. web3_agent_kit-0.9.0/src/airdrop/executor/zealy_exec.py +535 -0
  12. web3_agent_kit-0.9.0/src/airdrop/galxe.py +327 -0
  13. web3_agent_kit-0.9.0/src/airdrop/gleam.py +208 -0
  14. web3_agent_kit-0.9.0/src/airdrop/multi_wallet.py +264 -0
  15. web3_agent_kit-0.9.0/src/airdrop/social.py +430 -0
  16. web3_agent_kit-0.9.0/src/airdrop/tracker.py +339 -0
  17. web3_agent_kit-0.9.0/src/airdrop/zealy.py +234 -0
  18. {web3_agent_kit-0.7.0 → web3_agent_kit-0.9.0}/src/api/__init__.py +3 -3
  19. web3_agent_kit-0.9.0/tests/test_airdrop.py +439 -0
  20. {web3_agent_kit-0.7.0 → web3_agent_kit-0.9.0}/tests/test_api.py +1 -1
  21. web3_agent_kit-0.9.0/tests/test_executor.py +250 -0
  22. {web3_agent_kit-0.7.0 → web3_agent_kit-0.9.0}/tests/test_new_features.py +14 -7
  23. {web3_agent_kit-0.7.0 → web3_agent_kit-0.9.0/web3_agent_kit.egg-info}/PKG-INFO +60 -1
  24. {web3_agent_kit-0.7.0 → web3_agent_kit-0.9.0}/web3_agent_kit.egg-info/SOURCES.txt +16 -0
  25. {web3_agent_kit-0.7.0 → web3_agent_kit-0.9.0}/LICENSE +0 -0
  26. {web3_agent_kit-0.7.0 → web3_agent_kit-0.9.0}/setup.cfg +0 -0
  27. {web3_agent_kit-0.7.0 → web3_agent_kit-0.9.0}/setup.py +0 -0
  28. {web3_agent_kit-0.7.0 → web3_agent_kit-0.9.0}/src/__init__.py +0 -0
  29. {web3_agent_kit-0.7.0 → web3_agent_kit-0.9.0}/src/agent.py +0 -0
  30. {web3_agent_kit-0.7.0 → web3_agent_kit-0.9.0}/src/api/models.py +0 -0
  31. {web3_agent_kit-0.7.0 → web3_agent_kit-0.9.0}/src/api/routes/__init__.py +0 -0
  32. {web3_agent_kit-0.7.0 → web3_agent_kit-0.9.0}/src/api/routes/approval.py +0 -0
  33. {web3_agent_kit-0.7.0 → web3_agent_kit-0.9.0}/src/api/routes/bridge.py +0 -0
  34. {web3_agent_kit-0.7.0 → web3_agent_kit-0.9.0}/src/api/routes/dca.py +0 -0
  35. {web3_agent_kit-0.7.0 → web3_agent_kit-0.9.0}/src/api/routes/gas.py +0 -0
  36. {web3_agent_kit-0.7.0 → web3_agent_kit-0.9.0}/src/api/routes/portfolio.py +0 -0
  37. {web3_agent_kit-0.7.0 → web3_agent_kit-0.9.0}/src/api/routes/swap.py +0 -0
  38. {web3_agent_kit-0.7.0 → web3_agent_kit-0.9.0}/src/api/routes/wallet.py +0 -0
  39. {web3_agent_kit-0.7.0 → web3_agent_kit-0.9.0}/src/api/routes/watcher.py +0 -0
  40. {web3_agent_kit-0.7.0 → web3_agent_kit-0.9.0}/src/api/routes/yield_opt.py +0 -0
  41. {web3_agent_kit-0.7.0 → web3_agent_kit-0.9.0}/src/approval_manager.py +0 -0
  42. {web3_agent_kit-0.7.0 → web3_agent_kit-0.9.0}/src/bridge.py +0 -0
  43. {web3_agent_kit-0.7.0 → web3_agent_kit-0.9.0}/src/chain.py +0 -0
  44. {web3_agent_kit-0.7.0 → web3_agent_kit-0.9.0}/src/dca_bot.py +0 -0
  45. {web3_agent_kit-0.7.0 → web3_agent_kit-0.9.0}/src/defi/__init__.py +0 -0
  46. {web3_agent_kit-0.7.0 → web3_agent_kit-0.9.0}/src/gas_optimizer.py +0 -0
  47. {web3_agent_kit-0.7.0 → web3_agent_kit-0.9.0}/src/llm.py +0 -0
  48. {web3_agent_kit-0.7.0 → web3_agent_kit-0.9.0}/src/multi_wallet.py +0 -0
  49. {web3_agent_kit-0.7.0 → web3_agent_kit-0.9.0}/src/plugins/__init__.py +0 -0
  50. {web3_agent_kit-0.7.0 → web3_agent_kit-0.9.0}/src/plugins/examples/gas_tracker.py +0 -0
  51. {web3_agent_kit-0.7.0 → web3_agent_kit-0.9.0}/src/portfolio.py +0 -0
  52. {web3_agent_kit-0.7.0 → web3_agent_kit-0.9.0}/src/sniper.py +0 -0
  53. {web3_agent_kit-0.7.0 → web3_agent_kit-0.9.0}/src/utils/__init__.py +0 -0
  54. {web3_agent_kit-0.7.0 → web3_agent_kit-0.9.0}/src/wallet.py +0 -0
  55. {web3_agent_kit-0.7.0 → web3_agent_kit-0.9.0}/src/wallet_watcher.py +0 -0
  56. {web3_agent_kit-0.7.0 → web3_agent_kit-0.9.0}/src/yield_optimizer.py +0 -0
  57. {web3_agent_kit-0.7.0 → web3_agent_kit-0.9.0}/tests/test_bridge.py +0 -0
  58. {web3_agent_kit-0.7.0 → web3_agent_kit-0.9.0}/tests/test_core.py +0 -0
  59. {web3_agent_kit-0.7.0 → web3_agent_kit-0.9.0}/tests/test_dca_bot.py +0 -0
  60. {web3_agent_kit-0.7.0 → web3_agent_kit-0.9.0}/tests/test_defi.py +0 -0
  61. {web3_agent_kit-0.7.0 → web3_agent_kit-0.9.0}/tests/test_llm.py +0 -0
  62. {web3_agent_kit-0.7.0 → web3_agent_kit-0.9.0}/tests/test_multi_wallet.py +0 -0
  63. {web3_agent_kit-0.7.0 → web3_agent_kit-0.9.0}/tests/test_plugins.py +0 -0
  64. {web3_agent_kit-0.7.0 → web3_agent_kit-0.9.0}/tests/test_portfolio.py +0 -0
  65. {web3_agent_kit-0.7.0 → web3_agent_kit-0.9.0}/tests/test_sniper.py +0 -0
  66. {web3_agent_kit-0.7.0 → web3_agent_kit-0.9.0}/tests/test_yield_optimizer.py +0 -0
  67. {web3_agent_kit-0.7.0 → web3_agent_kit-0.9.0}/web3_agent_kit.egg-info/dependency_links.txt +0 -0
  68. {web3_agent_kit-0.7.0 → web3_agent_kit-0.9.0}/web3_agent_kit.egg-info/requires.txt +0 -0
  69. {web3_agent_kit-0.7.0 → web3_agent_kit-0.9.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.7.0
3
+ Version: 0.9.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 | ❌ | ❌ |
@@ -403,6 +405,54 @@ print(summary)
403
405
 
404
406
  ---
405
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
+
406
456
  ## 🌉 Bridge Agent
407
457
 
408
458
  Cross-chain transfers via Li.Fi and Socket:
@@ -533,6 +583,15 @@ web3-agent-kit/
533
583
  │ ├── bridge.py # Cross-chain bridge agent
534
584
  │ ├── yield_optimizer.py # Yield optimizer + auto-compound
535
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
536
595
  │ ├── plugins/
537
596
  │ │ ├── __init__.py # Plugin system (base, registry, manager)
538
597
  │ │ └── examples/
@@ -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 | ❌ | ❌ |
@@ -369,6 +371,54 @@ print(summary)
369
371
 
370
372
  ---
371
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
+
372
422
  ## 🌉 Bridge Agent
373
423
 
374
424
  Cross-chain transfers via Li.Fi and Socket:
@@ -499,6 +549,15 @@ web3-agent-kit/
499
549
  │ ├── bridge.py # Cross-chain bridge agent
500
550
  │ ├── yield_optimizer.py # Yield optimizer + auto-compound
501
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
502
561
  │ ├── plugins/
503
562
  │ │ ├── __init__.py # Plugin system (base, registry, manager)
504
563
  │ │ └── examples/
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "web3-agent-kit"
7
- version = "0.7.0"
7
+ version = "0.9.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)
@@ -0,0 +1,33 @@
1
+ """Executor layer — browser automation for airdrop task completion.
2
+
3
+ Provides real browser-based automation for Gleam.io, Zealy, and social
4
+ platform tasks using Playwright with anti-detect capabilities.
5
+ """
6
+
7
+ from .browser import BrowserManager, BrowserConfig
8
+ from .gleam_exec import GleamExecutor, GleamResult, GleamTaskEntry
9
+ from .social_exec import (
10
+ TwitterExecutor,
11
+ DiscordExecutor,
12
+ TelegramExecutor,
13
+ SocialExecutorConfig,
14
+ )
15
+ from .zealy_exec import ZealyExecutor, ZealyResult
16
+
17
+ __all__ = [
18
+ # Browser
19
+ "BrowserManager",
20
+ "BrowserConfig",
21
+ # Gleam
22
+ "GleamExecutor",
23
+ "GleamResult",
24
+ "GleamTaskEntry",
25
+ # Social
26
+ "TwitterExecutor",
27
+ "DiscordExecutor",
28
+ "TelegramExecutor",
29
+ "SocialExecutorConfig",
30
+ # Zealy
31
+ "ZealyExecutor",
32
+ "ZealyResult",
33
+ ]