@intentsolutionsio/mempool-analyzer 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/plugin.json +22 -0
- package/LICENSE +21 -0
- package/README.md +97 -0
- package/agents/mempool-agent.md +158 -0
- package/package.json +43 -0
- package/skills/analyzing-mempool/ARD.md +146 -0
- package/skills/analyzing-mempool/PRD.md +71 -0
- package/skills/analyzing-mempool/SKILL.md +110 -0
- package/skills/analyzing-mempool/config/settings.yaml +43 -0
- package/skills/analyzing-mempool/references/errors.md +122 -0
- package/skills/analyzing-mempool/references/examples.md +189 -0
- package/skills/analyzing-mempool/references/implementation.md +67 -0
- package/skills/analyzing-mempool/scripts/formatters.py +244 -0
- package/skills/analyzing-mempool/scripts/gas_analyzer.py +299 -0
- package/skills/analyzing-mempool/scripts/mempool_analyzer.py +320 -0
- package/skills/analyzing-mempool/scripts/mev_detector.py +387 -0
- package/skills/analyzing-mempool/scripts/rpc_client.py +311 -0
- package/skills/analyzing-mempool/scripts/tx_decoder.py +273 -0
- package/skills/skill-adapter/assets/README.md +6 -0
- package/skills/skill-adapter/assets/config-template.json +32 -0
- package/skills/skill-adapter/assets/skill-schema.json +28 -0
- package/skills/skill-adapter/assets/test-data.json +27 -0
- package/skills/skill-adapter/references/README.md +4 -0
- package/skills/skill-adapter/references/best-practices.md +69 -0
- package/skills/skill-adapter/references/examples.md +73 -0
- package/skills/skill-adapter/scripts/README.md +8 -0
- package/skills/skill-adapter/scripts/helper-template.sh +42 -0
- package/skills/skill-adapter/scripts/validation.sh +32 -0
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Transaction Decoder
|
|
4
|
+
|
|
5
|
+
Decode Ethereum transaction input data using known ABIs.
|
|
6
|
+
|
|
7
|
+
Author: Jeremy Longshore <jeremy@intentsolutions.io>
|
|
8
|
+
Version: 1.0.0
|
|
9
|
+
License: MIT
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
from typing import Any, Dict, Optional
|
|
13
|
+
from dataclasses import dataclass
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
# Common DEX method signatures (first 4 bytes of keccak256)
|
|
17
|
+
METHOD_SIGNATURES = {
|
|
18
|
+
# Uniswap V2 Router
|
|
19
|
+
"0x38ed1739": {"name": "swapExactTokensForTokens", "type": "swap"},
|
|
20
|
+
"0x8803dbee": {"name": "swapTokensForExactTokens", "type": "swap"},
|
|
21
|
+
"0x7ff36ab5": {"name": "swapExactETHForTokens", "type": "swap"},
|
|
22
|
+
"0x4a25d94a": {"name": "swapTokensForExactETH", "type": "swap"},
|
|
23
|
+
"0x18cbafe5": {"name": "swapExactTokensForETH", "type": "swap"},
|
|
24
|
+
"0xfb3bdb41": {"name": "swapETHForExactTokens", "type": "swap"},
|
|
25
|
+
"0xe8e33700": {"name": "addLiquidity", "type": "liquidity"},
|
|
26
|
+
"0xf305d719": {"name": "addLiquidityETH", "type": "liquidity"},
|
|
27
|
+
"0xbaa2abde": {"name": "removeLiquidity", "type": "liquidity"},
|
|
28
|
+
"0x02751cec": {"name": "removeLiquidityETH", "type": "liquidity"},
|
|
29
|
+
|
|
30
|
+
# Uniswap V3 Router
|
|
31
|
+
"0x414bf389": {"name": "exactInputSingle", "type": "swap"},
|
|
32
|
+
"0xc04b8d59": {"name": "exactInput", "type": "swap"},
|
|
33
|
+
"0xdb3e2198": {"name": "exactOutputSingle", "type": "swap"},
|
|
34
|
+
"0xf28c0498": {"name": "exactOutput", "type": "swap"},
|
|
35
|
+
"0x5ae401dc": {"name": "multicall", "type": "multicall"},
|
|
36
|
+
"0xac9650d8": {"name": "multicall", "type": "multicall"},
|
|
37
|
+
|
|
38
|
+
# ERC20
|
|
39
|
+
"0xa9059cbb": {"name": "transfer", "type": "transfer"},
|
|
40
|
+
"0x23b872dd": {"name": "transferFrom", "type": "transfer"},
|
|
41
|
+
"0x095ea7b3": {"name": "approve", "type": "approval"},
|
|
42
|
+
|
|
43
|
+
# Common
|
|
44
|
+
"0x": {"name": "ETH Transfer", "type": "transfer"},
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
# Known contract addresses
|
|
48
|
+
KNOWN_CONTRACTS = {
|
|
49
|
+
# Ethereum Mainnet
|
|
50
|
+
"0x7a250d5630b4cf539739df2c5dacb4c659f2488d": "Uniswap V2 Router",
|
|
51
|
+
"0xe592427a0aece92de3edee1f18e0157c05861564": "Uniswap V3 Router",
|
|
52
|
+
"0x68b3465833fb72a70ecdf485e0e4c7bd8665fc45": "Uniswap Universal Router",
|
|
53
|
+
"0xd9e1ce17f2641f24ae83637ab66a2cca9c378b9f": "SushiSwap Router",
|
|
54
|
+
"0x1111111254fb6c44bac0bed2854e76f90643097d": "1inch Router",
|
|
55
|
+
"0xdef1c0ded9bec7f1a1670819833240f027b25eff": "0x Exchange Proxy",
|
|
56
|
+
"0x881d40237659c251811cec9c364ef91dc08d300c": "Metamask Swap Router",
|
|
57
|
+
|
|
58
|
+
# Tokens
|
|
59
|
+
"0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2": "WETH",
|
|
60
|
+
"0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48": "USDC",
|
|
61
|
+
"0xdac17f958d2ee523a2206206994597c13d831ec7": "USDT",
|
|
62
|
+
"0x6b175474e89094c44da98b954eedeac495271d0f": "DAI",
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
@dataclass
|
|
67
|
+
class DecodedCall:
|
|
68
|
+
"""Decoded function call."""
|
|
69
|
+
method_name: str
|
|
70
|
+
method_type: str # swap, transfer, approval, liquidity, multicall, unknown
|
|
71
|
+
contract_name: Optional[str]
|
|
72
|
+
raw_signature: str
|
|
73
|
+
params: Dict[str, Any]
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
@dataclass
|
|
77
|
+
class SwapInfo:
|
|
78
|
+
"""Detected swap information."""
|
|
79
|
+
dex: str
|
|
80
|
+
method: str
|
|
81
|
+
token_in: Optional[str]
|
|
82
|
+
token_out: Optional[str]
|
|
83
|
+
amount_in: Optional[int]
|
|
84
|
+
amount_out_min: Optional[int]
|
|
85
|
+
is_exact_input: bool
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
class TransactionDecoder:
|
|
89
|
+
"""Decode Ethereum transaction input data."""
|
|
90
|
+
|
|
91
|
+
def __init__(self, verbose: bool = False):
|
|
92
|
+
"""Initialize decoder."""
|
|
93
|
+
self.verbose = verbose
|
|
94
|
+
|
|
95
|
+
def decode_input(self, input_data: str, to_address: str = None) -> DecodedCall:
|
|
96
|
+
"""Decode transaction input data.
|
|
97
|
+
|
|
98
|
+
Args:
|
|
99
|
+
input_data: Transaction input (hex string)
|
|
100
|
+
to_address: Destination contract address
|
|
101
|
+
|
|
102
|
+
Returns:
|
|
103
|
+
DecodedCall with decoded information
|
|
104
|
+
"""
|
|
105
|
+
if not input_data or input_data == "0x":
|
|
106
|
+
return DecodedCall(
|
|
107
|
+
method_name="ETH Transfer",
|
|
108
|
+
method_type="transfer",
|
|
109
|
+
contract_name=self._get_contract_name(to_address) if to_address else None,
|
|
110
|
+
raw_signature="0x",
|
|
111
|
+
params={},
|
|
112
|
+
)
|
|
113
|
+
|
|
114
|
+
# Get method signature (first 4 bytes)
|
|
115
|
+
signature = input_data[:10].lower()
|
|
116
|
+
|
|
117
|
+
method_info = METHOD_SIGNATURES.get(signature, {
|
|
118
|
+
"name": "Unknown",
|
|
119
|
+
"type": "unknown",
|
|
120
|
+
})
|
|
121
|
+
|
|
122
|
+
contract_name = self._get_contract_name(to_address) if to_address else None
|
|
123
|
+
|
|
124
|
+
return DecodedCall(
|
|
125
|
+
method_name=method_info["name"],
|
|
126
|
+
method_type=method_info["type"],
|
|
127
|
+
contract_name=contract_name,
|
|
128
|
+
raw_signature=signature,
|
|
129
|
+
params=self._decode_params(input_data, signature),
|
|
130
|
+
)
|
|
131
|
+
|
|
132
|
+
def _get_contract_name(self, address: str) -> Optional[str]:
|
|
133
|
+
"""Get known contract name."""
|
|
134
|
+
if not address:
|
|
135
|
+
return None
|
|
136
|
+
return KNOWN_CONTRACTS.get(address.lower())
|
|
137
|
+
|
|
138
|
+
def _decode_params(self, input_data: str, signature: str) -> Dict[str, Any]:
|
|
139
|
+
"""Decode function parameters (simplified)."""
|
|
140
|
+
if len(input_data) < 10:
|
|
141
|
+
return {}
|
|
142
|
+
|
|
143
|
+
# Remove signature
|
|
144
|
+
data = input_data[10:]
|
|
145
|
+
if not data:
|
|
146
|
+
return {}
|
|
147
|
+
|
|
148
|
+
params = {}
|
|
149
|
+
|
|
150
|
+
# Parse 32-byte chunks
|
|
151
|
+
chunks = [data[i:i+64] for i in range(0, len(data), 64)]
|
|
152
|
+
|
|
153
|
+
# For swaps, try to extract amounts
|
|
154
|
+
if signature in ["0x38ed1739", "0x8803dbee"]:
|
|
155
|
+
# swapExactTokensForTokens / swapTokensForExactTokens
|
|
156
|
+
if len(chunks) >= 2:
|
|
157
|
+
params["amountIn"] = int(chunks[0], 16) if chunks[0] else 0
|
|
158
|
+
params["amountOutMin"] = int(chunks[1], 16) if chunks[1] else 0
|
|
159
|
+
|
|
160
|
+
elif signature in ["0x7ff36ab5", "0xfb3bdb41"]:
|
|
161
|
+
# swapExactETHForTokens / swapETHForExactTokens
|
|
162
|
+
if len(chunks) >= 1:
|
|
163
|
+
params["amountOutMin"] = int(chunks[0], 16) if chunks[0] else 0
|
|
164
|
+
|
|
165
|
+
elif signature == "0xa9059cbb":
|
|
166
|
+
# transfer(address, uint256)
|
|
167
|
+
if len(chunks) >= 2:
|
|
168
|
+
params["to"] = "0x" + chunks[0][-40:]
|
|
169
|
+
params["amount"] = int(chunks[1], 16) if chunks[1] else 0
|
|
170
|
+
|
|
171
|
+
elif signature == "0x095ea7b3":
|
|
172
|
+
# approve(address, uint256)
|
|
173
|
+
if len(chunks) >= 2:
|
|
174
|
+
params["spender"] = "0x" + chunks[0][-40:]
|
|
175
|
+
params["amount"] = int(chunks[1], 16) if chunks[1] else 0
|
|
176
|
+
|
|
177
|
+
return params
|
|
178
|
+
|
|
179
|
+
def identify_dex_swap(self, input_data: str, to_address: str) -> Optional[SwapInfo]:
|
|
180
|
+
"""Identify if transaction is a DEX swap.
|
|
181
|
+
|
|
182
|
+
Args:
|
|
183
|
+
input_data: Transaction input data
|
|
184
|
+
to_address: Destination address
|
|
185
|
+
|
|
186
|
+
Returns:
|
|
187
|
+
SwapInfo if swap detected, None otherwise
|
|
188
|
+
"""
|
|
189
|
+
decoded = self.decode_input(input_data, to_address)
|
|
190
|
+
|
|
191
|
+
if decoded.method_type != "swap":
|
|
192
|
+
return None
|
|
193
|
+
|
|
194
|
+
dex = decoded.contract_name or "Unknown DEX"
|
|
195
|
+
is_exact_input = "exact" in decoded.method_name.lower() and "input" in decoded.method_name.lower()
|
|
196
|
+
|
|
197
|
+
return SwapInfo(
|
|
198
|
+
dex=dex,
|
|
199
|
+
method=decoded.method_name,
|
|
200
|
+
token_in=None, # Would need path decoding
|
|
201
|
+
token_out=None,
|
|
202
|
+
amount_in=decoded.params.get("amountIn"),
|
|
203
|
+
amount_out_min=decoded.params.get("amountOutMin"),
|
|
204
|
+
is_exact_input=is_exact_input,
|
|
205
|
+
)
|
|
206
|
+
|
|
207
|
+
def classify_transaction(self, tx: Dict) -> str:
|
|
208
|
+
"""Classify transaction type.
|
|
209
|
+
|
|
210
|
+
Args:
|
|
211
|
+
tx: Transaction dict with 'input' and 'to' fields
|
|
212
|
+
|
|
213
|
+
Returns:
|
|
214
|
+
Transaction type string
|
|
215
|
+
"""
|
|
216
|
+
input_data = tx.get("input_data", "") or tx.get("input", "")
|
|
217
|
+
to_address = tx.get("to_address", "") or tx.get("to", "")
|
|
218
|
+
|
|
219
|
+
decoded = self.decode_input(input_data, to_address)
|
|
220
|
+
return decoded.method_type
|
|
221
|
+
|
|
222
|
+
def estimate_attached_eth_usd_value(
|
|
223
|
+
self,
|
|
224
|
+
tx: Dict,
|
|
225
|
+
eth_price: float = 3000.0
|
|
226
|
+
) -> float:
|
|
227
|
+
"""Estimate USD value of ETH attached to transaction (msg.value).
|
|
228
|
+
|
|
229
|
+
Note: This only calculates the USD value of ETH sent with the transaction.
|
|
230
|
+
For token swaps, the actual value is in the tokens being exchanged,
|
|
231
|
+
not the attached ETH (which is often zero). Use this for ETH transfers
|
|
232
|
+
or transactions that include ETH payment.
|
|
233
|
+
|
|
234
|
+
Args:
|
|
235
|
+
tx: Transaction dict with 'value' field (in wei)
|
|
236
|
+
eth_price: Current ETH price in USD
|
|
237
|
+
|
|
238
|
+
Returns:
|
|
239
|
+
USD value of attached ETH (not the full transaction value for swaps)
|
|
240
|
+
"""
|
|
241
|
+
value_wei = tx.get("value", 0)
|
|
242
|
+
if isinstance(value_wei, str):
|
|
243
|
+
value_wei = int(value_wei, 16) if value_wei.startswith("0x") else int(value_wei)
|
|
244
|
+
|
|
245
|
+
value_eth = value_wei / 10**18
|
|
246
|
+
return value_eth * eth_price
|
|
247
|
+
|
|
248
|
+
# Backward compatibility alias
|
|
249
|
+
estimate_usd_value = estimate_attached_eth_usd_value
|
|
250
|
+
|
|
251
|
+
|
|
252
|
+
def main():
|
|
253
|
+
"""CLI entry point for testing."""
|
|
254
|
+
decoder = TransactionDecoder(verbose=True)
|
|
255
|
+
|
|
256
|
+
# Test decode
|
|
257
|
+
test_cases = [
|
|
258
|
+
("0x38ed1739" + "0" * 256, "0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D"),
|
|
259
|
+
("0xa9059cbb" + "0" * 128, "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"),
|
|
260
|
+
("0x", None),
|
|
261
|
+
]
|
|
262
|
+
|
|
263
|
+
print("=== Transaction Decoding Tests ===")
|
|
264
|
+
for input_data, to_addr in test_cases:
|
|
265
|
+
decoded = decoder.decode_input(input_data, to_addr)
|
|
266
|
+
print(f"\nInput: {input_data[:20]}...")
|
|
267
|
+
print(f" Method: {decoded.method_name}")
|
|
268
|
+
print(f" Type: {decoded.method_type}")
|
|
269
|
+
print(f" Contract: {decoded.contract_name or 'Unknown'}")
|
|
270
|
+
|
|
271
|
+
|
|
272
|
+
if __name__ == "__main__":
|
|
273
|
+
main()
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
"skill": {
|
|
3
|
+
"name": "skill-name",
|
|
4
|
+
"version": "1.0.0",
|
|
5
|
+
"enabled": true,
|
|
6
|
+
"settings": {
|
|
7
|
+
"verbose": false,
|
|
8
|
+
"autoActivate": true,
|
|
9
|
+
"toolRestrictions": true
|
|
10
|
+
}
|
|
11
|
+
},
|
|
12
|
+
"triggers": {
|
|
13
|
+
"keywords": [
|
|
14
|
+
"example-trigger-1",
|
|
15
|
+
"example-trigger-2"
|
|
16
|
+
],
|
|
17
|
+
"patterns": []
|
|
18
|
+
},
|
|
19
|
+
"tools": {
|
|
20
|
+
"allowed": [
|
|
21
|
+
"Read",
|
|
22
|
+
"Grep",
|
|
23
|
+
"Bash"
|
|
24
|
+
],
|
|
25
|
+
"restricted": []
|
|
26
|
+
},
|
|
27
|
+
"metadata": {
|
|
28
|
+
"author": "Plugin Author",
|
|
29
|
+
"category": "general",
|
|
30
|
+
"tags": []
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
+
"title": "Claude Skill Configuration",
|
|
4
|
+
"type": "object",
|
|
5
|
+
"required": ["name", "description"],
|
|
6
|
+
"properties": {
|
|
7
|
+
"name": {
|
|
8
|
+
"type": "string",
|
|
9
|
+
"pattern": "^[a-z0-9-]+$",
|
|
10
|
+
"maxLength": 64,
|
|
11
|
+
"description": "Skill identifier (lowercase, hyphens only)"
|
|
12
|
+
},
|
|
13
|
+
"description": {
|
|
14
|
+
"type": "string",
|
|
15
|
+
"maxLength": 1024,
|
|
16
|
+
"description": "What the skill does and when to use it"
|
|
17
|
+
},
|
|
18
|
+
"allowed-tools": {
|
|
19
|
+
"type": "string",
|
|
20
|
+
"description": "Comma-separated list of allowed tools"
|
|
21
|
+
},
|
|
22
|
+
"version": {
|
|
23
|
+
"type": "string",
|
|
24
|
+
"pattern": "^\\d+\\.\\d+\\.\\d+$",
|
|
25
|
+
"description": "Semantic version (x.y.z)"
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"testCases": [
|
|
3
|
+
{
|
|
4
|
+
"name": "Basic activation test",
|
|
5
|
+
"input": "trigger phrase example",
|
|
6
|
+
"expected": {
|
|
7
|
+
"activated": true,
|
|
8
|
+
"toolsUsed": ["Read", "Grep"],
|
|
9
|
+
"success": true
|
|
10
|
+
}
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
"name": "Complex workflow test",
|
|
14
|
+
"input": "multi-step trigger example",
|
|
15
|
+
"expected": {
|
|
16
|
+
"activated": true,
|
|
17
|
+
"steps": 3,
|
|
18
|
+
"toolsUsed": ["Read", "Write", "Bash"],
|
|
19
|
+
"success": true
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
],
|
|
23
|
+
"fixtures": {
|
|
24
|
+
"sampleInput": "example data",
|
|
25
|
+
"expectedOutput": "processed result"
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# Skill Best Practices
|
|
2
|
+
|
|
3
|
+
Guidelines for optimal skill usage and development.
|
|
4
|
+
|
|
5
|
+
## For Users
|
|
6
|
+
|
|
7
|
+
### Activation Best Practices
|
|
8
|
+
|
|
9
|
+
1. **Use Clear Trigger Phrases**
|
|
10
|
+
- Match phrases from skill description
|
|
11
|
+
- Be specific about intent
|
|
12
|
+
- Provide necessary context
|
|
13
|
+
|
|
14
|
+
2. **Provide Sufficient Context**
|
|
15
|
+
- Include relevant file paths
|
|
16
|
+
- Specify scope of analysis
|
|
17
|
+
- Mention any constraints
|
|
18
|
+
|
|
19
|
+
3. **Understand Tool Permissions**
|
|
20
|
+
- Check allowed-tools in frontmatter
|
|
21
|
+
- Know what the skill can/cannot do
|
|
22
|
+
- Request appropriate actions
|
|
23
|
+
|
|
24
|
+
### Workflow Optimization
|
|
25
|
+
|
|
26
|
+
- Start with simple requests
|
|
27
|
+
- Build up to complex workflows
|
|
28
|
+
- Verify each step before proceeding
|
|
29
|
+
- Use skill consistently for related tasks
|
|
30
|
+
|
|
31
|
+
## For Developers
|
|
32
|
+
|
|
33
|
+
### Skill Development Guidelines
|
|
34
|
+
|
|
35
|
+
1. **Clear Descriptions**
|
|
36
|
+
- Include explicit trigger phrases
|
|
37
|
+
- Document all capabilities
|
|
38
|
+
- Specify limitations
|
|
39
|
+
|
|
40
|
+
2. **Proper Tool Permissions**
|
|
41
|
+
- Use minimal necessary tools
|
|
42
|
+
- Document security implications
|
|
43
|
+
- Test with restricted tools
|
|
44
|
+
|
|
45
|
+
3. **Comprehensive Documentation**
|
|
46
|
+
- Provide usage examples
|
|
47
|
+
- Document common pitfalls
|
|
48
|
+
- Include troubleshooting guide
|
|
49
|
+
|
|
50
|
+
### Maintenance
|
|
51
|
+
|
|
52
|
+
- Keep version updated
|
|
53
|
+
- Test after tool updates
|
|
54
|
+
- Monitor user feedback
|
|
55
|
+
- Iterate on descriptions
|
|
56
|
+
|
|
57
|
+
## Performance Tips
|
|
58
|
+
|
|
59
|
+
- Scope skills to specific domains
|
|
60
|
+
- Avoid overlapping trigger phrases
|
|
61
|
+
- Keep descriptions under 1024 chars
|
|
62
|
+
- Test activation reliability
|
|
63
|
+
|
|
64
|
+
## Security Considerations
|
|
65
|
+
|
|
66
|
+
- Never include secrets in skill files
|
|
67
|
+
- Validate all inputs
|
|
68
|
+
- Use read-only tools when possible
|
|
69
|
+
- Document security requirements
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# Skill Usage Examples
|
|
2
|
+
|
|
3
|
+
This document provides practical examples of how to use this skill effectively.
|
|
4
|
+
|
|
5
|
+
## Basic Usage
|
|
6
|
+
|
|
7
|
+
### Example 1: Simple Activation
|
|
8
|
+
|
|
9
|
+
**User Request:**
|
|
10
|
+
```
|
|
11
|
+
[Describe trigger phrase here]
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
**Skill Response:**
|
|
15
|
+
1. Analyzes the request
|
|
16
|
+
2. Performs the required action
|
|
17
|
+
3. Returns results
|
|
18
|
+
|
|
19
|
+
### Example 2: Complex Workflow
|
|
20
|
+
|
|
21
|
+
**User Request:**
|
|
22
|
+
```
|
|
23
|
+
[Describe complex scenario]
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
**Workflow:**
|
|
27
|
+
1. Step 1: Initial analysis
|
|
28
|
+
2. Step 2: Data processing
|
|
29
|
+
3. Step 3: Result generation
|
|
30
|
+
4. Step 4: Validation
|
|
31
|
+
|
|
32
|
+
## Advanced Patterns
|
|
33
|
+
|
|
34
|
+
### Pattern 1: Chaining Operations
|
|
35
|
+
|
|
36
|
+
Combine this skill with other tools:
|
|
37
|
+
```
|
|
38
|
+
Step 1: Use this skill for [purpose]
|
|
39
|
+
Step 2: Chain with [other tool]
|
|
40
|
+
Step 3: Finalize with [action]
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### Pattern 2: Error Handling
|
|
44
|
+
|
|
45
|
+
If issues occur:
|
|
46
|
+
- Check trigger phrase matches
|
|
47
|
+
- Verify context is available
|
|
48
|
+
- Review allowed-tools permissions
|
|
49
|
+
|
|
50
|
+
## Tips & Best Practices
|
|
51
|
+
|
|
52
|
+
- ✅ Be specific with trigger phrases
|
|
53
|
+
- ✅ Provide necessary context
|
|
54
|
+
- ✅ Check tool permissions match needs
|
|
55
|
+
- ❌ Avoid vague requests
|
|
56
|
+
- ❌ Don't mix unrelated tasks
|
|
57
|
+
|
|
58
|
+
## Common Issues
|
|
59
|
+
|
|
60
|
+
**Issue:** Skill doesn't activate
|
|
61
|
+
**Solution:** Use exact trigger phrases from description
|
|
62
|
+
|
|
63
|
+
**Issue:** Unexpected results
|
|
64
|
+
**Solution:** Check input format and context
|
|
65
|
+
|
|
66
|
+
## See Also
|
|
67
|
+
|
|
68
|
+
- Main SKILL.md for full documentation
|
|
69
|
+
- scripts/ for automation helpers
|
|
70
|
+
- assets/ for configuration examples
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
*[Tons of Skills](https://tonsofskills.com) by [Intent Solutions](https://intentsolutions.io) | [jeremylongshore.com](https://jeremylongshore.com)*
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
# Scripts
|
|
2
|
+
|
|
3
|
+
Bundled resources for mempool-analyzer skill
|
|
4
|
+
|
|
5
|
+
- [ ] gas_price_optimizer.py: Script to calculate optimal gas prices based on mempool data and EIP-1559.
|
|
6
|
+
- [ ] mev_detector.py: Script to identify and analyze MEV opportunities (sandwich attacks, arbitrage, liquidations).
|
|
7
|
+
- [ ] transaction_decoder.py: Script to decode transaction calldata and simulate transaction execution.
|
|
8
|
+
- [ ] alert_manager.py: Script to manage and send alerts based on configured thresholds (large transfers, high gas prices, MEV opportunities).
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Helper script template for skill automation
|
|
3
|
+
# Customize this for your skill's specific needs
|
|
4
|
+
|
|
5
|
+
set -e
|
|
6
|
+
|
|
7
|
+
function show_usage() {
|
|
8
|
+
echo "Usage: $0 [options]"
|
|
9
|
+
echo ""
|
|
10
|
+
echo "Options:"
|
|
11
|
+
echo " -h, --help Show this help message"
|
|
12
|
+
echo " -v, --verbose Enable verbose output"
|
|
13
|
+
echo ""
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
# Parse arguments
|
|
17
|
+
VERBOSE=false
|
|
18
|
+
|
|
19
|
+
while [[ $# -gt 0 ]]; do
|
|
20
|
+
case $1 in
|
|
21
|
+
-h|--help)
|
|
22
|
+
show_usage
|
|
23
|
+
exit 0
|
|
24
|
+
;;
|
|
25
|
+
-v|--verbose)
|
|
26
|
+
VERBOSE=true
|
|
27
|
+
shift
|
|
28
|
+
;;
|
|
29
|
+
*)
|
|
30
|
+
echo "Unknown option: $1"
|
|
31
|
+
show_usage
|
|
32
|
+
exit 1
|
|
33
|
+
;;
|
|
34
|
+
esac
|
|
35
|
+
done
|
|
36
|
+
|
|
37
|
+
# Your skill logic here
|
|
38
|
+
if [ "$VERBOSE" = true ]; then
|
|
39
|
+
echo "Running skill automation..."
|
|
40
|
+
fi
|
|
41
|
+
|
|
42
|
+
echo "✅ Complete"
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Skill validation helper
|
|
3
|
+
# Validates skill activation and functionality
|
|
4
|
+
|
|
5
|
+
set -e
|
|
6
|
+
|
|
7
|
+
echo "🔍 Validating skill..."
|
|
8
|
+
|
|
9
|
+
# Check if SKILL.md exists
|
|
10
|
+
if [ ! -f "../SKILL.md" ]; then
|
|
11
|
+
echo "❌ Error: SKILL.md not found"
|
|
12
|
+
exit 1
|
|
13
|
+
fi
|
|
14
|
+
|
|
15
|
+
# Validate frontmatter
|
|
16
|
+
if ! grep -q "^---$" "../SKILL.md"; then
|
|
17
|
+
echo "❌ Error: No frontmatter found"
|
|
18
|
+
exit 1
|
|
19
|
+
fi
|
|
20
|
+
|
|
21
|
+
# Check required fields
|
|
22
|
+
if ! grep -q "^name:" "../SKILL.md"; then
|
|
23
|
+
echo "❌ Error: Missing 'name' field"
|
|
24
|
+
exit 1
|
|
25
|
+
fi
|
|
26
|
+
|
|
27
|
+
if ! grep -q "^description:" "../SKILL.md"; then
|
|
28
|
+
echo "❌ Error: Missing 'description' field"
|
|
29
|
+
exit 1
|
|
30
|
+
fi
|
|
31
|
+
|
|
32
|
+
echo "✅ Skill validation passed"
|