clawskill 1.0.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.
- clawskill-1.0.0/LICENSE +21 -0
- clawskill-1.0.0/PKG-INFO +98 -0
- clawskill-1.0.0/README.md +75 -0
- clawskill-1.0.0/clawskill/__init__.py +3 -0
- clawskill-1.0.0/clawskill/cli.py +495 -0
- clawskill-1.0.0/clawskill.egg-info/PKG-INFO +98 -0
- clawskill-1.0.0/clawskill.egg-info/SOURCES.txt +11 -0
- clawskill-1.0.0/clawskill.egg-info/dependency_links.txt +1 -0
- clawskill-1.0.0/clawskill.egg-info/entry_points.txt +2 -0
- clawskill-1.0.0/clawskill.egg-info/requires.txt +1 -0
- clawskill-1.0.0/clawskill.egg-info/top_level.txt +1 -0
- clawskill-1.0.0/pyproject.toml +34 -0
- clawskill-1.0.0/setup.cfg +4 -0
clawskill-1.0.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025-2026 Elyan Labs
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
clawskill-1.0.0/PKG-INFO
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: clawskill
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: ClawSkill — Let your AI agent mine RTC tokens on any modern hardware. 1x multiplier, built-in wallet, VM-penalized.
|
|
5
|
+
Author-email: Elyan Labs <scott@elyanlabs.ai>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://bottube.ai
|
|
8
|
+
Project-URL: Repository, https://github.com/Scottcjn/Rustchain
|
|
9
|
+
Project-URL: Issues, https://github.com/Scottcjn/Rustchain/issues
|
|
10
|
+
Keywords: clawskill,ai-agent,miner,rustchain,rtc,openclaw,proof-of-antiquity
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
15
|
+
Classifier: Operating System :: MacOS
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
18
|
+
Requires-Python: >=3.8
|
|
19
|
+
Description-Content-Type: text/markdown
|
|
20
|
+
License-File: LICENSE
|
|
21
|
+
Requires-Dist: requests>=2.25
|
|
22
|
+
Dynamic: license-file
|
|
23
|
+
|
|
24
|
+
# ClawSkill — Mine RTC Tokens With Your AI Agent
|
|
25
|
+
|
|
26
|
+
Your Claw agent can earn **RTC (RustChain Tokens)** by proving it runs on **real hardware**. One command to install, automatic attestation, built-in wallet.
|
|
27
|
+
|
|
28
|
+
## Quick Start
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
pip install clawskill
|
|
32
|
+
clawskill install --wallet my-agent-miner
|
|
33
|
+
clawskill start
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
That's it. Your agent is now mining RTC.
|
|
37
|
+
|
|
38
|
+
## How It Works
|
|
39
|
+
|
|
40
|
+
1. **Hardware Fingerprinting** — 6 cryptographic checks prove your machine is real hardware (clock drift, cache timing, SIMD identity, thermal drift, instruction jitter, anti-emulation)
|
|
41
|
+
2. **Attestation** — Your agent automatically attests to the RustChain network every few minutes
|
|
42
|
+
3. **Rewards** — RTC tokens accumulate in your wallet each epoch (~10 minutes)
|
|
43
|
+
4. **VM Detection** — Virtual machines are detected and receive effectively zero rewards. **Real iron only.**
|
|
44
|
+
|
|
45
|
+
## Multipliers
|
|
46
|
+
|
|
47
|
+
| Hardware | Multiplier | Notes |
|
|
48
|
+
|----------|-----------|-------|
|
|
49
|
+
| Modern x86/ARM | **1.0x** | Standard reward rate |
|
|
50
|
+
| Apple Silicon (M1/M2/M3) | **1.2x** | Slight bonus |
|
|
51
|
+
| PowerPC G5 | **2.0x** | Vintage bonus |
|
|
52
|
+
| PowerPC G4 | **2.5x** | Maximum vintage bonus |
|
|
53
|
+
| **VM/Emulator** | **~0x** | **Detected and penalized** |
|
|
54
|
+
|
|
55
|
+
## Commands
|
|
56
|
+
|
|
57
|
+
| Command | Description |
|
|
58
|
+
|---------|-------------|
|
|
59
|
+
| `clawskill install` | Download miner, create wallet, set up service |
|
|
60
|
+
| `clawskill start` | Start mining in background |
|
|
61
|
+
| `clawskill stop` | Stop mining |
|
|
62
|
+
| `clawskill status` | Check miner + network status |
|
|
63
|
+
| `clawskill logs` | View miner output |
|
|
64
|
+
| `clawskill uninstall` | Remove everything |
|
|
65
|
+
|
|
66
|
+
## What Gets Installed
|
|
67
|
+
|
|
68
|
+
- Miner scripts from [RustChain repo](https://github.com/Scottcjn/Rustchain)
|
|
69
|
+
- Python virtual environment with `requests` dependency
|
|
70
|
+
- Systemd user service (Linux) or LaunchAgent (macOS)
|
|
71
|
+
- All files in `~/.clawskill/`
|
|
72
|
+
|
|
73
|
+
## VM Warning
|
|
74
|
+
|
|
75
|
+
RustChain uses **Proof-of-Antiquity (PoA)** consensus. The hardware fingerprint system detects:
|
|
76
|
+
|
|
77
|
+
- QEMU / KVM / VMware / VirtualBox / Xen / Hyper-V
|
|
78
|
+
- Hypervisor CPU flags
|
|
79
|
+
- DMI vendor strings
|
|
80
|
+
- Flattened timing distributions
|
|
81
|
+
|
|
82
|
+
If you're running in a VM, the miner will install and attest, but your rewards will be effectively zero. This is by design — RTC rewards machines that bring real compute to the network.
|
|
83
|
+
|
|
84
|
+
## Requirements
|
|
85
|
+
|
|
86
|
+
- Python 3.8+
|
|
87
|
+
- Linux or macOS (Windows installer coming soon)
|
|
88
|
+
- Real hardware (not a VM)
|
|
89
|
+
|
|
90
|
+
## Links
|
|
91
|
+
|
|
92
|
+
- [RustChain Network](https://bottube.ai)
|
|
93
|
+
- [Block Explorer](https://50.28.86.131/explorer)
|
|
94
|
+
- [GitHub](https://github.com/Scottcjn/Rustchain)
|
|
95
|
+
|
|
96
|
+
## License
|
|
97
|
+
|
|
98
|
+
MIT — Elyan Labs
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# ClawSkill — Mine RTC Tokens With Your AI Agent
|
|
2
|
+
|
|
3
|
+
Your Claw agent can earn **RTC (RustChain Tokens)** by proving it runs on **real hardware**. One command to install, automatic attestation, built-in wallet.
|
|
4
|
+
|
|
5
|
+
## Quick Start
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pip install clawskill
|
|
9
|
+
clawskill install --wallet my-agent-miner
|
|
10
|
+
clawskill start
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
That's it. Your agent is now mining RTC.
|
|
14
|
+
|
|
15
|
+
## How It Works
|
|
16
|
+
|
|
17
|
+
1. **Hardware Fingerprinting** — 6 cryptographic checks prove your machine is real hardware (clock drift, cache timing, SIMD identity, thermal drift, instruction jitter, anti-emulation)
|
|
18
|
+
2. **Attestation** — Your agent automatically attests to the RustChain network every few minutes
|
|
19
|
+
3. **Rewards** — RTC tokens accumulate in your wallet each epoch (~10 minutes)
|
|
20
|
+
4. **VM Detection** — Virtual machines are detected and receive effectively zero rewards. **Real iron only.**
|
|
21
|
+
|
|
22
|
+
## Multipliers
|
|
23
|
+
|
|
24
|
+
| Hardware | Multiplier | Notes |
|
|
25
|
+
|----------|-----------|-------|
|
|
26
|
+
| Modern x86/ARM | **1.0x** | Standard reward rate |
|
|
27
|
+
| Apple Silicon (M1/M2/M3) | **1.2x** | Slight bonus |
|
|
28
|
+
| PowerPC G5 | **2.0x** | Vintage bonus |
|
|
29
|
+
| PowerPC G4 | **2.5x** | Maximum vintage bonus |
|
|
30
|
+
| **VM/Emulator** | **~0x** | **Detected and penalized** |
|
|
31
|
+
|
|
32
|
+
## Commands
|
|
33
|
+
|
|
34
|
+
| Command | Description |
|
|
35
|
+
|---------|-------------|
|
|
36
|
+
| `clawskill install` | Download miner, create wallet, set up service |
|
|
37
|
+
| `clawskill start` | Start mining in background |
|
|
38
|
+
| `clawskill stop` | Stop mining |
|
|
39
|
+
| `clawskill status` | Check miner + network status |
|
|
40
|
+
| `clawskill logs` | View miner output |
|
|
41
|
+
| `clawskill uninstall` | Remove everything |
|
|
42
|
+
|
|
43
|
+
## What Gets Installed
|
|
44
|
+
|
|
45
|
+
- Miner scripts from [RustChain repo](https://github.com/Scottcjn/Rustchain)
|
|
46
|
+
- Python virtual environment with `requests` dependency
|
|
47
|
+
- Systemd user service (Linux) or LaunchAgent (macOS)
|
|
48
|
+
- All files in `~/.clawskill/`
|
|
49
|
+
|
|
50
|
+
## VM Warning
|
|
51
|
+
|
|
52
|
+
RustChain uses **Proof-of-Antiquity (PoA)** consensus. The hardware fingerprint system detects:
|
|
53
|
+
|
|
54
|
+
- QEMU / KVM / VMware / VirtualBox / Xen / Hyper-V
|
|
55
|
+
- Hypervisor CPU flags
|
|
56
|
+
- DMI vendor strings
|
|
57
|
+
- Flattened timing distributions
|
|
58
|
+
|
|
59
|
+
If you're running in a VM, the miner will install and attest, but your rewards will be effectively zero. This is by design — RTC rewards machines that bring real compute to the network.
|
|
60
|
+
|
|
61
|
+
## Requirements
|
|
62
|
+
|
|
63
|
+
- Python 3.8+
|
|
64
|
+
- Linux or macOS (Windows installer coming soon)
|
|
65
|
+
- Real hardware (not a VM)
|
|
66
|
+
|
|
67
|
+
## Links
|
|
68
|
+
|
|
69
|
+
- [RustChain Network](https://bottube.ai)
|
|
70
|
+
- [Block Explorer](https://50.28.86.131/explorer)
|
|
71
|
+
- [GitHub](https://github.com/Scottcjn/Rustchain)
|
|
72
|
+
|
|
73
|
+
## License
|
|
74
|
+
|
|
75
|
+
MIT — Elyan Labs
|
|
@@ -0,0 +1,495 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""ClawSkill — RustChain miner for AI agents on modern hardware.
|
|
3
|
+
|
|
4
|
+
Your Claw agent earns RTC tokens by proving it runs on real hardware.
|
|
5
|
+
Modern machines get 1x multiplier. Vintage hardware gets bonus multipliers.
|
|
6
|
+
VMs are detected and penalized — real iron only.
|
|
7
|
+
|
|
8
|
+
Usage:
|
|
9
|
+
pip install clawskill
|
|
10
|
+
clawskill install --wallet my-agent-miner
|
|
11
|
+
clawskill start
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
import argparse
|
|
15
|
+
import os
|
|
16
|
+
import platform
|
|
17
|
+
import shutil
|
|
18
|
+
import subprocess
|
|
19
|
+
import sys
|
|
20
|
+
import textwrap
|
|
21
|
+
import time
|
|
22
|
+
import urllib.request
|
|
23
|
+
import ssl
|
|
24
|
+
import json
|
|
25
|
+
|
|
26
|
+
REPO_BASE = "https://raw.githubusercontent.com/Scottcjn/Rustchain/main"
|
|
27
|
+
INSTALL_DIR = os.path.join(os.path.expanduser("~"), ".clawskill")
|
|
28
|
+
VENV_DIR = os.path.join(INSTALL_DIR, "venv")
|
|
29
|
+
NODE_URL = "https://50.28.86.131"
|
|
30
|
+
|
|
31
|
+
# ANSI colors
|
|
32
|
+
CYAN = "\033[36m"
|
|
33
|
+
GREEN = "\033[32m"
|
|
34
|
+
RED = "\033[31m"
|
|
35
|
+
YELLOW = "\033[33m"
|
|
36
|
+
BOLD = "\033[1m"
|
|
37
|
+
DIM = "\033[2m"
|
|
38
|
+
NC = "\033[0m"
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def log(msg):
|
|
42
|
+
print(f"{CYAN}[clawskill]{NC} {msg}")
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def success(msg):
|
|
46
|
+
print(f"{GREEN}[OK]{NC} {msg}")
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def warn(msg):
|
|
50
|
+
print(f"{YELLOW}[WARN]{NC} {msg}")
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def error(msg):
|
|
54
|
+
print(f"{RED}[ERROR]{NC} {msg}", file=sys.stderr)
|
|
55
|
+
sys.exit(1)
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def download_file(url, dest):
|
|
59
|
+
"""Download a file from URL to dest path."""
|
|
60
|
+
ctx = ssl.create_default_context()
|
|
61
|
+
ctx.check_hostname = False
|
|
62
|
+
ctx.verify_mode = ssl.CERT_NONE
|
|
63
|
+
try:
|
|
64
|
+
urllib.request.urlretrieve(url, dest)
|
|
65
|
+
size = os.path.getsize(dest)
|
|
66
|
+
if size < 100:
|
|
67
|
+
raise Exception(f"File too small ({size} bytes)")
|
|
68
|
+
return size
|
|
69
|
+
except Exception as e:
|
|
70
|
+
raise Exception(f"Download failed for {url}: {e}")
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def run_cmd(cmd, check=True, capture=False):
|
|
74
|
+
"""Run a shell command."""
|
|
75
|
+
try:
|
|
76
|
+
result = subprocess.run(
|
|
77
|
+
cmd, shell=True, check=check,
|
|
78
|
+
capture_output=capture, text=True
|
|
79
|
+
)
|
|
80
|
+
return result.stdout.strip() if capture else None
|
|
81
|
+
except subprocess.CalledProcessError:
|
|
82
|
+
if check:
|
|
83
|
+
raise
|
|
84
|
+
return None
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def _detect_vm():
|
|
88
|
+
"""Quick VM detection — warns the user upfront."""
|
|
89
|
+
indicators = []
|
|
90
|
+
system = platform.system()
|
|
91
|
+
|
|
92
|
+
if system == "Linux":
|
|
93
|
+
# Check /sys/class/dmi
|
|
94
|
+
dmi_paths = [
|
|
95
|
+
"/sys/class/dmi/id/sys_vendor",
|
|
96
|
+
"/sys/class/dmi/id/product_name",
|
|
97
|
+
"/sys/class/dmi/id/board_vendor",
|
|
98
|
+
]
|
|
99
|
+
vm_vendors = ["qemu", "vmware", "virtualbox", "xen", "kvm", "microsoft", "parallels", "bhyve"]
|
|
100
|
+
for p in dmi_paths:
|
|
101
|
+
try:
|
|
102
|
+
with open(p) as f:
|
|
103
|
+
val = f.read().strip().lower()
|
|
104
|
+
if any(v in val for v in vm_vendors):
|
|
105
|
+
indicators.append(f"{p}: {val}")
|
|
106
|
+
except (OSError, IOError):
|
|
107
|
+
pass
|
|
108
|
+
|
|
109
|
+
# Check /proc/cpuinfo for hypervisor flag
|
|
110
|
+
try:
|
|
111
|
+
with open("/proc/cpuinfo") as f:
|
|
112
|
+
if "hypervisor" in f.read().lower():
|
|
113
|
+
indicators.append("cpuinfo: hypervisor flag")
|
|
114
|
+
except (OSError, IOError):
|
|
115
|
+
pass
|
|
116
|
+
|
|
117
|
+
elif system == "Darwin":
|
|
118
|
+
try:
|
|
119
|
+
out = subprocess.run(
|
|
120
|
+
["sysctl", "-n", "machdep.cpu.features"],
|
|
121
|
+
capture_output=True, text=True
|
|
122
|
+
).stdout.lower()
|
|
123
|
+
if "vmm" in out:
|
|
124
|
+
indicators.append("sysctl: VMM flag")
|
|
125
|
+
except Exception:
|
|
126
|
+
pass
|
|
127
|
+
|
|
128
|
+
return indicators
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
def cmd_install(args):
|
|
132
|
+
"""Install and configure ClawSkill miner for your AI agent."""
|
|
133
|
+
print(textwrap.dedent(f"""
|
|
134
|
+
{CYAN}{BOLD}
|
|
135
|
+
██████╗██╗ █████╗ ██╗ ██╗███████╗██╗ ██╗██╗██╗ ██╗
|
|
136
|
+
██╔════╝██║ ██╔══██╗██║ ██║██╔════╝██║ ██╔╝██║██║ ██║
|
|
137
|
+
██║ ██║ ███████║██║ █╗ ██║███████╗█████╔╝ ██║██║ ██║
|
|
138
|
+
██║ ██║ ██╔══██║██║███╗██║╚════██║██╔═██╗ ██║██║ ██║
|
|
139
|
+
╚██████╗███████╗██║ ██║╚███╔███╔╝███████║██║ ██╗██║███████╗███████╗
|
|
140
|
+
╚═════╝╚══════╝╚═╝ ╚═╝ ╚══╝╚══╝ ╚══════╝╚═╝ ╚═╝╚═╝╚══════╝╚══════╝
|
|
141
|
+
{NC}
|
|
142
|
+
{DIM} Mine RTC tokens with your AI agent on real hardware{NC}
|
|
143
|
+
{DIM} Modern x86/ARM = 1x | Vintage PowerPC = up to 2.5x | VM = ~0x{NC}
|
|
144
|
+
"""))
|
|
145
|
+
|
|
146
|
+
system = platform.system()
|
|
147
|
+
machine = platform.machine()
|
|
148
|
+
log(f"Platform: {system} | Arch: {machine}")
|
|
149
|
+
|
|
150
|
+
if system not in ("Linux", "Darwin"):
|
|
151
|
+
error(f"Unsupported platform: {system}. Use Linux or macOS.")
|
|
152
|
+
|
|
153
|
+
# VM check — warn upfront, don't block
|
|
154
|
+
vm_hints = _detect_vm()
|
|
155
|
+
if vm_hints:
|
|
156
|
+
print(textwrap.dedent(f"""
|
|
157
|
+
{RED}{BOLD} ╔══════════════════════════════════════════════════════════╗
|
|
158
|
+
║ ⚠ VM DETECTED — READ THIS ⚠ ║
|
|
159
|
+
╠══════════════════════════════════════════════════════════╣
|
|
160
|
+
║ ║
|
|
161
|
+
║ This machine appears to be a virtual machine. ║
|
|
162
|
+
║ RustChain's hardware fingerprint system WILL detect ║
|
|
163
|
+
║ VMs and assigns near-zero mining weight. ║
|
|
164
|
+
║ ║
|
|
165
|
+
║ Your miner will attest, but earn effectively nothing. ║
|
|
166
|
+
║ This is by design — RTC rewards real hardware only. ║
|
|
167
|
+
║ ║
|
|
168
|
+
║ VM indicators found: ║{NC}"""))
|
|
169
|
+
for h in vm_hints[:4]:
|
|
170
|
+
print(f" {RED} • {h}{NC}")
|
|
171
|
+
print(f""" {RED}{BOLD}║ ║
|
|
172
|
+
║ To earn RTC, run on bare-metal hardware. ║
|
|
173
|
+
╚══════════════════════════════════════════════════════════╝{NC}
|
|
174
|
+
""")
|
|
175
|
+
|
|
176
|
+
# Wallet setup
|
|
177
|
+
wallet = args.wallet
|
|
178
|
+
if not wallet:
|
|
179
|
+
try:
|
|
180
|
+
wallet = input(f"{CYAN}[clawskill]{NC} Enter agent wallet name (e.g. my-claw-agent): ").strip()
|
|
181
|
+
except (EOFError, KeyboardInterrupt):
|
|
182
|
+
wallet = ""
|
|
183
|
+
|
|
184
|
+
if not wallet:
|
|
185
|
+
hostname = platform.node().split(".")[0] or "agent"
|
|
186
|
+
wallet = f"claw-{hostname}-{int(time.time()) % 100000}"
|
|
187
|
+
warn(f"No wallet name provided. Auto-generated: {wallet}")
|
|
188
|
+
|
|
189
|
+
# Create install dir
|
|
190
|
+
log(f"Installing to {INSTALL_DIR}")
|
|
191
|
+
os.makedirs(INSTALL_DIR, exist_ok=True)
|
|
192
|
+
|
|
193
|
+
# Save wallet
|
|
194
|
+
with open(os.path.join(INSTALL_DIR, ".wallet"), "w") as f:
|
|
195
|
+
f.write(wallet)
|
|
196
|
+
|
|
197
|
+
# Create venv
|
|
198
|
+
if not os.path.isdir(VENV_DIR):
|
|
199
|
+
log("Creating Python environment...")
|
|
200
|
+
run_cmd(f'"{sys.executable}" -m venv "{VENV_DIR}"')
|
|
201
|
+
|
|
202
|
+
# Install deps
|
|
203
|
+
log("Installing dependencies...")
|
|
204
|
+
pip = os.path.join(VENV_DIR, "bin", "pip")
|
|
205
|
+
run_cmd(f'"{pip}" install --upgrade pip -q')
|
|
206
|
+
run_cmd(f'"{pip}" install requests -q')
|
|
207
|
+
success("Dependencies ready")
|
|
208
|
+
|
|
209
|
+
# Download miner files
|
|
210
|
+
log("Downloading miner from RustChain repo...")
|
|
211
|
+
|
|
212
|
+
downloads = [
|
|
213
|
+
(f"{REPO_BASE}/miners/linux/fingerprint_checks.py", "fingerprint_checks.py"),
|
|
214
|
+
]
|
|
215
|
+
|
|
216
|
+
if system == "Linux":
|
|
217
|
+
downloads.append((f"{REPO_BASE}/miners/linux/rustchain_linux_miner.py", "miner.py"))
|
|
218
|
+
elif system == "Darwin":
|
|
219
|
+
downloads.append((f"{REPO_BASE}/miners/macos/rustchain_mac_miner_v2.4.py", "miner.py"))
|
|
220
|
+
|
|
221
|
+
for url, filename in downloads:
|
|
222
|
+
dest = os.path.join(INSTALL_DIR, filename)
|
|
223
|
+
size = download_file(url, dest)
|
|
224
|
+
log(f" {filename} ({size / 1024:.1f} KB)")
|
|
225
|
+
|
|
226
|
+
success("Miner files downloaded")
|
|
227
|
+
|
|
228
|
+
# Setup service
|
|
229
|
+
if system == "Linux":
|
|
230
|
+
_setup_systemd(wallet)
|
|
231
|
+
elif system == "Darwin":
|
|
232
|
+
_setup_launchd(wallet)
|
|
233
|
+
|
|
234
|
+
# Check network
|
|
235
|
+
log("Checking RustChain network...")
|
|
236
|
+
try:
|
|
237
|
+
ctx = ssl.create_default_context()
|
|
238
|
+
ctx.check_hostname = False
|
|
239
|
+
ctx.verify_mode = ssl.CERT_NONE
|
|
240
|
+
req = urllib.request.Request(f"{NODE_URL}/api/miners")
|
|
241
|
+
with urllib.request.urlopen(req, context=ctx, timeout=10) as resp:
|
|
242
|
+
miners = json.loads(resp.read())
|
|
243
|
+
log(f"Active miners on network: {len(miners)}")
|
|
244
|
+
except Exception:
|
|
245
|
+
warn("Could not reach network (node may be temporarily unavailable)")
|
|
246
|
+
|
|
247
|
+
print(textwrap.dedent(f"""
|
|
248
|
+
{GREEN}{BOLD}═══════════════════════════════════════════════════════════
|
|
249
|
+
ClawSkill installed! Your agent is ready to mine RTC.
|
|
250
|
+
|
|
251
|
+
Wallet: {wallet}
|
|
252
|
+
Location: {INSTALL_DIR}
|
|
253
|
+
Reward: 1x multiplier (modern hardware)
|
|
254
|
+
|
|
255
|
+
Commands:
|
|
256
|
+
clawskill start Start mining in background
|
|
257
|
+
clawskill stop Stop mining
|
|
258
|
+
clawskill status Check miner + network status
|
|
259
|
+
clawskill logs View miner output
|
|
260
|
+
|
|
261
|
+
How it works:
|
|
262
|
+
• Your agent proves real hardware via 6 fingerprint checks
|
|
263
|
+
• Attestation happens automatically every few minutes
|
|
264
|
+
• RTC tokens accumulate in your wallet each epoch (~10 min)
|
|
265
|
+
• Check balance: clawskill status
|
|
266
|
+
|
|
267
|
+
Multipliers:
|
|
268
|
+
Modern x86/ARM → 1.0x (you are here)
|
|
269
|
+
Apple Silicon → 1.2x
|
|
270
|
+
PowerPC G5 → 2.0x
|
|
271
|
+
PowerPC G4 → 2.5x
|
|
272
|
+
VM/Emulator → ~0x (detected & penalized)
|
|
273
|
+
═══════════════════════════════════════════════════════════{NC}
|
|
274
|
+
"""))
|
|
275
|
+
|
|
276
|
+
|
|
277
|
+
def _setup_systemd(wallet):
|
|
278
|
+
"""Set up systemd user service on Linux."""
|
|
279
|
+
service_dir = os.path.expanduser("~/.config/systemd/user")
|
|
280
|
+
os.makedirs(service_dir, exist_ok=True)
|
|
281
|
+
service_file = os.path.join(service_dir, "clawskill-miner.service")
|
|
282
|
+
python_bin = os.path.join(VENV_DIR, "bin", "python")
|
|
283
|
+
miner_py = os.path.join(INSTALL_DIR, "miner.py")
|
|
284
|
+
|
|
285
|
+
with open(service_file, "w") as f:
|
|
286
|
+
f.write(textwrap.dedent(f"""\
|
|
287
|
+
[Unit]
|
|
288
|
+
Description=ClawSkill RTC Miner — AI Agent Mining
|
|
289
|
+
After=network-online.target
|
|
290
|
+
Wants=network-online.target
|
|
291
|
+
|
|
292
|
+
[Service]
|
|
293
|
+
ExecStart={python_bin} {miner_py} --wallet {wallet}
|
|
294
|
+
Restart=always
|
|
295
|
+
RestartSec=30
|
|
296
|
+
WorkingDirectory={INSTALL_DIR}
|
|
297
|
+
Environment=PYTHONUNBUFFERED=1
|
|
298
|
+
|
|
299
|
+
[Install]
|
|
300
|
+
WantedBy=default.target
|
|
301
|
+
"""))
|
|
302
|
+
|
|
303
|
+
try:
|
|
304
|
+
run_cmd("systemctl --user daemon-reload")
|
|
305
|
+
run_cmd("systemctl --user enable clawskill-miner")
|
|
306
|
+
run_cmd("systemctl --user start clawskill-miner")
|
|
307
|
+
success("Service installed and started")
|
|
308
|
+
except Exception:
|
|
309
|
+
warn("Systemd user services not available. Use: clawskill start")
|
|
310
|
+
|
|
311
|
+
|
|
312
|
+
def _setup_launchd(wallet):
|
|
313
|
+
"""Set up launchd agent on macOS."""
|
|
314
|
+
plist_dir = os.path.expanduser("~/Library/LaunchAgents")
|
|
315
|
+
os.makedirs(plist_dir, exist_ok=True)
|
|
316
|
+
plist_file = os.path.join(plist_dir, "com.clawskill.miner.plist")
|
|
317
|
+
python_bin = os.path.join(VENV_DIR, "bin", "python")
|
|
318
|
+
miner_py = os.path.join(INSTALL_DIR, "miner.py")
|
|
319
|
+
|
|
320
|
+
with open(plist_file, "w") as f:
|
|
321
|
+
f.write(textwrap.dedent(f"""\
|
|
322
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
323
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
|
|
324
|
+
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
325
|
+
<plist version="1.0">
|
|
326
|
+
<dict>
|
|
327
|
+
<key>Label</key>
|
|
328
|
+
<string>com.clawskill.miner</string>
|
|
329
|
+
<key>ProgramArguments</key>
|
|
330
|
+
<array>
|
|
331
|
+
<string>{python_bin}</string>
|
|
332
|
+
<string>{miner_py}</string>
|
|
333
|
+
<string>--wallet</string>
|
|
334
|
+
<string>{wallet}</string>
|
|
335
|
+
</array>
|
|
336
|
+
<key>WorkingDirectory</key>
|
|
337
|
+
<string>{INSTALL_DIR}</string>
|
|
338
|
+
<key>RunAtLoad</key>
|
|
339
|
+
<true/>
|
|
340
|
+
<key>KeepAlive</key>
|
|
341
|
+
<true/>
|
|
342
|
+
<key>StandardOutPath</key>
|
|
343
|
+
<string>{os.path.join(INSTALL_DIR, "miner.log")}</string>
|
|
344
|
+
<key>StandardErrorPath</key>
|
|
345
|
+
<string>{os.path.join(INSTALL_DIR, "miner.err")}</string>
|
|
346
|
+
</dict>
|
|
347
|
+
</plist>
|
|
348
|
+
"""))
|
|
349
|
+
|
|
350
|
+
try:
|
|
351
|
+
run_cmd(f'launchctl unload "{plist_file}" 2>/dev/null', check=False)
|
|
352
|
+
run_cmd(f'launchctl load "{plist_file}"')
|
|
353
|
+
success("LaunchAgent installed and loaded")
|
|
354
|
+
except Exception:
|
|
355
|
+
warn("Could not load LaunchAgent. Use: clawskill start")
|
|
356
|
+
|
|
357
|
+
|
|
358
|
+
def cmd_start(args):
|
|
359
|
+
"""Start the ClawSkill miner."""
|
|
360
|
+
system = platform.system()
|
|
361
|
+
if system == "Linux":
|
|
362
|
+
run_cmd("systemctl --user start clawskill-miner")
|
|
363
|
+
success("Miner started")
|
|
364
|
+
elif system == "Darwin":
|
|
365
|
+
pf = os.path.expanduser("~/Library/LaunchAgents/com.clawskill.miner.plist")
|
|
366
|
+
run_cmd(f'launchctl load "{pf}"', check=False)
|
|
367
|
+
success("Miner started")
|
|
368
|
+
else:
|
|
369
|
+
wallet_file = os.path.join(INSTALL_DIR, ".wallet")
|
|
370
|
+
wallet = open(wallet_file).read().strip() if os.path.exists(wallet_file) else ""
|
|
371
|
+
w_arg = f"--wallet {wallet}" if wallet else ""
|
|
372
|
+
log(f"Run: cd {INSTALL_DIR} && source venv/bin/activate && python miner.py {w_arg}")
|
|
373
|
+
|
|
374
|
+
|
|
375
|
+
def cmd_stop(args):
|
|
376
|
+
"""Stop the ClawSkill miner."""
|
|
377
|
+
system = platform.system()
|
|
378
|
+
if system == "Linux":
|
|
379
|
+
run_cmd("systemctl --user stop clawskill-miner", check=False)
|
|
380
|
+
elif system == "Darwin":
|
|
381
|
+
pf = os.path.expanduser("~/Library/LaunchAgents/com.clawskill.miner.plist")
|
|
382
|
+
run_cmd(f'launchctl unload "{pf}"', check=False)
|
|
383
|
+
success("Miner stopped")
|
|
384
|
+
|
|
385
|
+
|
|
386
|
+
def cmd_status(args):
|
|
387
|
+
"""Check miner and network status."""
|
|
388
|
+
system = platform.system()
|
|
389
|
+
|
|
390
|
+
# Service status
|
|
391
|
+
if system == "Linux":
|
|
392
|
+
run_cmd("systemctl --user status clawskill-miner", check=False)
|
|
393
|
+
elif system == "Darwin":
|
|
394
|
+
run_cmd("launchctl list | grep clawskill", check=False)
|
|
395
|
+
|
|
396
|
+
# Wallet info
|
|
397
|
+
wallet_file = os.path.join(INSTALL_DIR, ".wallet")
|
|
398
|
+
if os.path.exists(wallet_file):
|
|
399
|
+
wallet = open(wallet_file).read().strip()
|
|
400
|
+
log(f"Wallet: {wallet}")
|
|
401
|
+
|
|
402
|
+
# Network check
|
|
403
|
+
try:
|
|
404
|
+
ctx = ssl.create_default_context()
|
|
405
|
+
ctx.check_hostname = False
|
|
406
|
+
ctx.verify_mode = ssl.CERT_NONE
|
|
407
|
+
req = urllib.request.Request(f"{NODE_URL}/health")
|
|
408
|
+
with urllib.request.urlopen(req, context=ctx, timeout=10) as resp:
|
|
409
|
+
health = json.loads(resp.read())
|
|
410
|
+
status = "online" if health.get("ok") else "offline"
|
|
411
|
+
log(f"Network: {status} (v{health.get('version', '?')})")
|
|
412
|
+
except Exception:
|
|
413
|
+
warn("Could not reach network")
|
|
414
|
+
|
|
415
|
+
|
|
416
|
+
def cmd_logs(args):
|
|
417
|
+
"""View miner logs."""
|
|
418
|
+
system = platform.system()
|
|
419
|
+
if system == "Linux":
|
|
420
|
+
os.execlp("journalctl", "journalctl", "--user", "-u", "clawskill-miner", "-f", "--no-pager", "-n", "50")
|
|
421
|
+
elif system == "Darwin":
|
|
422
|
+
log_file = os.path.join(INSTALL_DIR, "miner.log")
|
|
423
|
+
if os.path.exists(log_file):
|
|
424
|
+
os.execlp("tail", "tail", "-f", log_file)
|
|
425
|
+
else:
|
|
426
|
+
warn("No log file found")
|
|
427
|
+
|
|
428
|
+
|
|
429
|
+
def cmd_uninstall(args):
|
|
430
|
+
"""Remove ClawSkill miner and all files."""
|
|
431
|
+
log("Stopping miner...")
|
|
432
|
+
cmd_stop(args)
|
|
433
|
+
|
|
434
|
+
system = platform.system()
|
|
435
|
+
if system == "Linux":
|
|
436
|
+
run_cmd("systemctl --user disable clawskill-miner", check=False)
|
|
437
|
+
sf = os.path.expanduser("~/.config/systemd/user/clawskill-miner.service")
|
|
438
|
+
if os.path.exists(sf):
|
|
439
|
+
os.unlink(sf)
|
|
440
|
+
elif system == "Darwin":
|
|
441
|
+
pf = os.path.expanduser("~/Library/LaunchAgents/com.clawskill.miner.plist")
|
|
442
|
+
if os.path.exists(pf):
|
|
443
|
+
os.unlink(pf)
|
|
444
|
+
|
|
445
|
+
if os.path.isdir(INSTALL_DIR):
|
|
446
|
+
shutil.rmtree(INSTALL_DIR)
|
|
447
|
+
|
|
448
|
+
success("ClawSkill miner uninstalled")
|
|
449
|
+
|
|
450
|
+
|
|
451
|
+
def main():
|
|
452
|
+
parser = argparse.ArgumentParser(
|
|
453
|
+
prog="clawskill",
|
|
454
|
+
description="ClawSkill — Mine RTC tokens with your AI agent on real hardware",
|
|
455
|
+
epilog=textwrap.dedent("""\
|
|
456
|
+
Your Claw agent earns RTC by proving it runs on real hardware.
|
|
457
|
+
Modern x86/ARM gets 1x multiplier. VMs are detected and penalized.
|
|
458
|
+
Vintage hardware (PowerPC, etc.) earns bonus multipliers up to 2.5x.
|
|
459
|
+
"""),
|
|
460
|
+
)
|
|
461
|
+
sub = parser.add_subparsers(dest="command")
|
|
462
|
+
|
|
463
|
+
p_install = sub.add_parser("install", help="Install miner and configure wallet")
|
|
464
|
+
p_install.add_argument("--wallet", help="Agent wallet name for mining rewards")
|
|
465
|
+
|
|
466
|
+
sub.add_parser("start", help="Start mining in background")
|
|
467
|
+
sub.add_parser("stop", help="Stop mining")
|
|
468
|
+
sub.add_parser("status", help="Check miner + network status")
|
|
469
|
+
sub.add_parser("logs", help="View miner output logs")
|
|
470
|
+
sub.add_parser("uninstall", help="Remove miner and all files")
|
|
471
|
+
|
|
472
|
+
args = parser.parse_args()
|
|
473
|
+
|
|
474
|
+
commands = {
|
|
475
|
+
"install": cmd_install,
|
|
476
|
+
"start": cmd_start,
|
|
477
|
+
"stop": cmd_stop,
|
|
478
|
+
"status": cmd_status,
|
|
479
|
+
"logs": cmd_logs,
|
|
480
|
+
"uninstall": cmd_uninstall,
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
if not args.command:
|
|
484
|
+
args.command = "install"
|
|
485
|
+
args.wallet = None
|
|
486
|
+
|
|
487
|
+
func = commands.get(args.command)
|
|
488
|
+
if func:
|
|
489
|
+
func(args)
|
|
490
|
+
else:
|
|
491
|
+
parser.print_help()
|
|
492
|
+
|
|
493
|
+
|
|
494
|
+
if __name__ == "__main__":
|
|
495
|
+
main()
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: clawskill
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: ClawSkill — Let your AI agent mine RTC tokens on any modern hardware. 1x multiplier, built-in wallet, VM-penalized.
|
|
5
|
+
Author-email: Elyan Labs <scott@elyanlabs.ai>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://bottube.ai
|
|
8
|
+
Project-URL: Repository, https://github.com/Scottcjn/Rustchain
|
|
9
|
+
Project-URL: Issues, https://github.com/Scottcjn/Rustchain/issues
|
|
10
|
+
Keywords: clawskill,ai-agent,miner,rustchain,rtc,openclaw,proof-of-antiquity
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
15
|
+
Classifier: Operating System :: MacOS
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
18
|
+
Requires-Python: >=3.8
|
|
19
|
+
Description-Content-Type: text/markdown
|
|
20
|
+
License-File: LICENSE
|
|
21
|
+
Requires-Dist: requests>=2.25
|
|
22
|
+
Dynamic: license-file
|
|
23
|
+
|
|
24
|
+
# ClawSkill — Mine RTC Tokens With Your AI Agent
|
|
25
|
+
|
|
26
|
+
Your Claw agent can earn **RTC (RustChain Tokens)** by proving it runs on **real hardware**. One command to install, automatic attestation, built-in wallet.
|
|
27
|
+
|
|
28
|
+
## Quick Start
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
pip install clawskill
|
|
32
|
+
clawskill install --wallet my-agent-miner
|
|
33
|
+
clawskill start
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
That's it. Your agent is now mining RTC.
|
|
37
|
+
|
|
38
|
+
## How It Works
|
|
39
|
+
|
|
40
|
+
1. **Hardware Fingerprinting** — 6 cryptographic checks prove your machine is real hardware (clock drift, cache timing, SIMD identity, thermal drift, instruction jitter, anti-emulation)
|
|
41
|
+
2. **Attestation** — Your agent automatically attests to the RustChain network every few minutes
|
|
42
|
+
3. **Rewards** — RTC tokens accumulate in your wallet each epoch (~10 minutes)
|
|
43
|
+
4. **VM Detection** — Virtual machines are detected and receive effectively zero rewards. **Real iron only.**
|
|
44
|
+
|
|
45
|
+
## Multipliers
|
|
46
|
+
|
|
47
|
+
| Hardware | Multiplier | Notes |
|
|
48
|
+
|----------|-----------|-------|
|
|
49
|
+
| Modern x86/ARM | **1.0x** | Standard reward rate |
|
|
50
|
+
| Apple Silicon (M1/M2/M3) | **1.2x** | Slight bonus |
|
|
51
|
+
| PowerPC G5 | **2.0x** | Vintage bonus |
|
|
52
|
+
| PowerPC G4 | **2.5x** | Maximum vintage bonus |
|
|
53
|
+
| **VM/Emulator** | **~0x** | **Detected and penalized** |
|
|
54
|
+
|
|
55
|
+
## Commands
|
|
56
|
+
|
|
57
|
+
| Command | Description |
|
|
58
|
+
|---------|-------------|
|
|
59
|
+
| `clawskill install` | Download miner, create wallet, set up service |
|
|
60
|
+
| `clawskill start` | Start mining in background |
|
|
61
|
+
| `clawskill stop` | Stop mining |
|
|
62
|
+
| `clawskill status` | Check miner + network status |
|
|
63
|
+
| `clawskill logs` | View miner output |
|
|
64
|
+
| `clawskill uninstall` | Remove everything |
|
|
65
|
+
|
|
66
|
+
## What Gets Installed
|
|
67
|
+
|
|
68
|
+
- Miner scripts from [RustChain repo](https://github.com/Scottcjn/Rustchain)
|
|
69
|
+
- Python virtual environment with `requests` dependency
|
|
70
|
+
- Systemd user service (Linux) or LaunchAgent (macOS)
|
|
71
|
+
- All files in `~/.clawskill/`
|
|
72
|
+
|
|
73
|
+
## VM Warning
|
|
74
|
+
|
|
75
|
+
RustChain uses **Proof-of-Antiquity (PoA)** consensus. The hardware fingerprint system detects:
|
|
76
|
+
|
|
77
|
+
- QEMU / KVM / VMware / VirtualBox / Xen / Hyper-V
|
|
78
|
+
- Hypervisor CPU flags
|
|
79
|
+
- DMI vendor strings
|
|
80
|
+
- Flattened timing distributions
|
|
81
|
+
|
|
82
|
+
If you're running in a VM, the miner will install and attest, but your rewards will be effectively zero. This is by design — RTC rewards machines that bring real compute to the network.
|
|
83
|
+
|
|
84
|
+
## Requirements
|
|
85
|
+
|
|
86
|
+
- Python 3.8+
|
|
87
|
+
- Linux or macOS (Windows installer coming soon)
|
|
88
|
+
- Real hardware (not a VM)
|
|
89
|
+
|
|
90
|
+
## Links
|
|
91
|
+
|
|
92
|
+
- [RustChain Network](https://bottube.ai)
|
|
93
|
+
- [Block Explorer](https://50.28.86.131/explorer)
|
|
94
|
+
- [GitHub](https://github.com/Scottcjn/Rustchain)
|
|
95
|
+
|
|
96
|
+
## License
|
|
97
|
+
|
|
98
|
+
MIT — Elyan Labs
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
LICENSE
|
|
2
|
+
README.md
|
|
3
|
+
pyproject.toml
|
|
4
|
+
clawskill/__init__.py
|
|
5
|
+
clawskill/cli.py
|
|
6
|
+
clawskill.egg-info/PKG-INFO
|
|
7
|
+
clawskill.egg-info/SOURCES.txt
|
|
8
|
+
clawskill.egg-info/dependency_links.txt
|
|
9
|
+
clawskill.egg-info/entry_points.txt
|
|
10
|
+
clawskill.egg-info/requires.txt
|
|
11
|
+
clawskill.egg-info/top_level.txt
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
requests>=2.25
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
clawskill
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=64", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "clawskill"
|
|
7
|
+
version = "1.0.0"
|
|
8
|
+
description = "ClawSkill — Let your AI agent mine RTC tokens on any modern hardware. 1x multiplier, built-in wallet, VM-penalized."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = {text = "MIT"}
|
|
11
|
+
authors = [{name = "Elyan Labs", email = "scott@elyanlabs.ai"}]
|
|
12
|
+
requires-python = ">=3.8"
|
|
13
|
+
dependencies = ["requests>=2.25"]
|
|
14
|
+
keywords = ["clawskill", "ai-agent", "miner", "rustchain", "rtc", "openclaw", "proof-of-antiquity"]
|
|
15
|
+
classifiers = [
|
|
16
|
+
"Development Status :: 4 - Beta",
|
|
17
|
+
"Intended Audience :: Developers",
|
|
18
|
+
"License :: OSI Approved :: MIT License",
|
|
19
|
+
"Operating System :: POSIX :: Linux",
|
|
20
|
+
"Operating System :: MacOS",
|
|
21
|
+
"Programming Language :: Python :: 3",
|
|
22
|
+
"Topic :: Software Development :: Libraries",
|
|
23
|
+
]
|
|
24
|
+
|
|
25
|
+
[project.urls]
|
|
26
|
+
Homepage = "https://bottube.ai"
|
|
27
|
+
Repository = "https://github.com/Scottcjn/Rustchain"
|
|
28
|
+
Issues = "https://github.com/Scottcjn/Rustchain/issues"
|
|
29
|
+
|
|
30
|
+
[project.scripts]
|
|
31
|
+
clawskill = "clawskill.cli:main"
|
|
32
|
+
|
|
33
|
+
[tool.setuptools.packages.find]
|
|
34
|
+
include = ["clawskill*"]
|