opencode-froggy 0.2.0 → 0.4.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/README.md +250 -25
- package/command/commit-push.md +1 -1
- package/command/diff-summary.md +19 -0
- package/command/doc-changes.md +1 -1
- package/command/review-changes.md +15 -1
- package/command/review-pr.md +17 -2
- package/command/simplify-changes.md +1 -1
- package/dist/index.js +12 -3
- package/dist/tools/blockchain/eth-address-balance.d.ts +20 -0
- package/dist/tools/blockchain/eth-address-balance.js +37 -0
- package/dist/tools/blockchain/eth-address-txs.d.ts +23 -0
- package/dist/tools/blockchain/eth-address-txs.js +41 -0
- package/dist/tools/blockchain/eth-token-transfers.d.ts +23 -0
- package/dist/tools/blockchain/eth-token-transfers.js +41 -0
- package/dist/tools/blockchain/eth-transaction.d.ts +34 -0
- package/dist/tools/blockchain/eth-transaction.js +203 -0
- package/dist/tools/blockchain/etherscan-client.d.ts +26 -0
- package/dist/tools/blockchain/etherscan-client.js +174 -0
- package/dist/tools/blockchain/etherscan-client.test.d.ts +1 -0
- package/dist/tools/blockchain/etherscan-client.test.js +211 -0
- package/dist/tools/blockchain/event-decoder.d.ts +14 -0
- package/dist/tools/blockchain/event-decoder.js +96 -0
- package/dist/tools/blockchain/event-decoder.test.d.ts +1 -0
- package/dist/tools/blockchain/event-decoder.test.js +197 -0
- package/dist/tools/blockchain/formatters.d.ts +10 -0
- package/dist/tools/blockchain/formatters.js +147 -0
- package/dist/tools/blockchain/index.d.ts +10 -0
- package/dist/tools/blockchain/index.js +10 -0
- package/dist/tools/blockchain/tools.test.d.ts +1 -0
- package/dist/tools/blockchain/tools.test.js +208 -0
- package/dist/tools/blockchain/types.d.ts +154 -0
- package/dist/tools/blockchain/types.js +8 -0
- package/dist/tools/blockchain/viem-client.d.ts +9 -0
- package/dist/tools/blockchain/viem-client.js +98 -0
- package/dist/tools/index.d.ts +1 -1
- package/dist/tools/index.js +1 -1
- package/package.json +3 -2
- package/skill/code-simplify/SKILL.md +6 -0
- package/dist/tools/diff-summary.d.ts +0 -20
- package/dist/tools/diff-summary.js +0 -111
- package/dist/tools/reply-child.d.ts +0 -19
- package/dist/tools/reply-child.js +0 -42
package/README.md
CHANGED
|
@@ -21,6 +21,12 @@ Plugin providing Claude Code–style hooks, specialized agents (doc-writer, code
|
|
|
21
21
|
- [diff-summary](#diff-summary)
|
|
22
22
|
- [prompt-session](#prompt-session)
|
|
23
23
|
- [list-child-sessions](#list-child-sessions)
|
|
24
|
+
- [Blockchain](#blockchain)
|
|
25
|
+
- [Configuration](#configuration)
|
|
26
|
+
- [eth-transaction](#eth-transaction)
|
|
27
|
+
- [eth-address-balance](#eth-address-balance)
|
|
28
|
+
- [eth-address-txs](#eth-address-txs)
|
|
29
|
+
- [eth-token-transfers](#eth-token-transfers)
|
|
24
30
|
- [Hooks](#hooks)
|
|
25
31
|
- [Configuration Locations](#configuration-locations)
|
|
26
32
|
- [Configuration File Format](#configuration-file-format)
|
|
@@ -135,38 +141,26 @@ gitingest({
|
|
|
135
141
|
|
|
136
142
|
### diff-summary
|
|
137
143
|
|
|
138
|
-
|
|
144
|
+
**Command** that displays a structured summary of git working tree changes (staged, unstaged, and untracked files). Injects git diff output directly into the prompt using bash commands.
|
|
139
145
|
|
|
140
|
-
####
|
|
146
|
+
#### Usage
|
|
141
147
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
| `target` | `string` | No | `main` | Target branch to compare against |
|
|
146
|
-
| `remote` | `string` | No | `origin` | Git remote name |
|
|
148
|
+
```bash
|
|
149
|
+
/diff-summary
|
|
150
|
+
```
|
|
147
151
|
|
|
148
|
-
####
|
|
152
|
+
#### What it shows
|
|
149
153
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
154
|
+
- Git status (porcelain format)
|
|
155
|
+
- Staged changes (stats and full diff)
|
|
156
|
+
- Unstaged changes (stats and full diff)
|
|
157
|
+
- Untracked files content (first 50 lines of each file)
|
|
153
158
|
|
|
154
|
-
|
|
155
|
-
diffSummary({ source: "feature-branch" })
|
|
159
|
+
#### Implementation
|
|
156
160
|
|
|
157
|
-
|
|
158
|
-
diffSummary({
|
|
159
|
-
source: "feature-branch",
|
|
160
|
-
target: "develop"
|
|
161
|
-
})
|
|
161
|
+
This command uses OpenCode's `!`\`...\`` syntax to inject bash command output directly into the prompt, avoiding the 2000-line truncation limit that affects tools.
|
|
162
162
|
|
|
163
|
-
|
|
164
|
-
diffSummary({
|
|
165
|
-
source: "feature-branch",
|
|
166
|
-
target: "main",
|
|
167
|
-
remote: "upstream"
|
|
168
|
-
})
|
|
169
|
-
```
|
|
163
|
+
See `command/diff-summary.md` for the full implementation.
|
|
170
164
|
|
|
171
165
|
#### Output Structure
|
|
172
166
|
|
|
@@ -256,6 +250,237 @@ Child sessions (2):
|
|
|
256
250
|
|
|
257
251
|
---
|
|
258
252
|
|
|
253
|
+
### Blockchain
|
|
254
|
+
|
|
255
|
+
Tools for querying Ethereum and EVM-compatible blockchains via Etherscan APIs.
|
|
256
|
+
|
|
257
|
+
All blockchain tools support multiple chains via the `chainId` parameter:
|
|
258
|
+
|
|
259
|
+
| Chain ID | Network |
|
|
260
|
+
|----------|---------|
|
|
261
|
+
| `1` | Ethereum (default) |
|
|
262
|
+
| `137` | Polygon |
|
|
263
|
+
| `56` | BSC |
|
|
264
|
+
| `42161` | Arbitrum |
|
|
265
|
+
| `10` | Optimism |
|
|
266
|
+
| `8453` | Base |
|
|
267
|
+
| `43114` | Avalanche |
|
|
268
|
+
| `250` | Fantom |
|
|
269
|
+
| `324` | zkSync |
|
|
270
|
+
|
|
271
|
+
#### Configuration
|
|
272
|
+
|
|
273
|
+
The blockchain tools use Etherscan-compatible APIs. An API key is optional but recommended.
|
|
274
|
+
|
|
275
|
+
**Environment Variable:**
|
|
276
|
+
|
|
277
|
+
| Variable | Required | Description |
|
|
278
|
+
|----------|----------|-------------|
|
|
279
|
+
| `ETHERSCAN_API_KEY` | No | API key for Etherscan and compatible explorers |
|
|
280
|
+
|
|
281
|
+
**Without an API key:** Requests are rate-limited (typically 1 request per 5 seconds).
|
|
282
|
+
|
|
283
|
+
**With an API key:** Higher rate limits and more reliable access.
|
|
284
|
+
|
|
285
|
+
**Getting an API key:**
|
|
286
|
+
|
|
287
|
+
1. Create a free account at [etherscan.io](https://etherscan.io/register)
|
|
288
|
+
2. Navigate to API Keys in your account settings
|
|
289
|
+
3. Generate a new API key
|
|
290
|
+
|
|
291
|
+
**Setting the environment variable:**
|
|
292
|
+
|
|
293
|
+
```bash
|
|
294
|
+
export ETHERSCAN_API_KEY="your-api-key-here"
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
#### eth-transaction
|
|
298
|
+
|
|
299
|
+
Get Ethereum transaction details by transaction hash. Returns status, block, addresses, gas costs in JSON format. Use optional parameters to include internal transactions, token transfers, and decoded event logs.
|
|
300
|
+
|
|
301
|
+
##### Parameters
|
|
302
|
+
|
|
303
|
+
| Parameter | Type | Required | Default | Description |
|
|
304
|
+
|-----------|------|----------|---------|-------------|
|
|
305
|
+
| `hash` | `string` | Yes | - | Transaction hash (0x...) |
|
|
306
|
+
| `chainId` | `string` | No | `"1"` | Chain ID (see table above) |
|
|
307
|
+
| `includeInternalTxs` | `boolean` | No | `false` | Include internal transactions (ETH transfers between contracts) |
|
|
308
|
+
| `includeTokenTransfers` | `boolean` | No | `false` | Include ERC-20 token transfers |
|
|
309
|
+
| `decodeLogs` | `boolean` | No | `false` | Decode event logs (Transfer, Approval, Deposit, Withdrawal) |
|
|
310
|
+
|
|
311
|
+
##### Usage Examples
|
|
312
|
+
|
|
313
|
+
```typescript
|
|
314
|
+
// Get basic transaction details on Ethereum mainnet
|
|
315
|
+
ethTransaction({ hash: "0x123abc..." })
|
|
316
|
+
|
|
317
|
+
// Get transaction on Polygon
|
|
318
|
+
ethTransaction({
|
|
319
|
+
hash: "0x123abc...",
|
|
320
|
+
chainId: "137"
|
|
321
|
+
})
|
|
322
|
+
|
|
323
|
+
// Get transaction with internal transactions and token transfers
|
|
324
|
+
ethTransaction({
|
|
325
|
+
hash: "0x123abc...",
|
|
326
|
+
includeInternalTxs: true,
|
|
327
|
+
includeTokenTransfers: true
|
|
328
|
+
})
|
|
329
|
+
|
|
330
|
+
// Get full transaction details with decoded event logs
|
|
331
|
+
ethTransaction({
|
|
332
|
+
hash: "0x123abc...",
|
|
333
|
+
includeInternalTxs: true,
|
|
334
|
+
includeTokenTransfers: true,
|
|
335
|
+
decodeLogs: true
|
|
336
|
+
})
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
##### Output Structure
|
|
340
|
+
|
|
341
|
+
The tool returns JSON with labeled addresses (contract names resolved via Etherscan):
|
|
342
|
+
|
|
343
|
+
```json
|
|
344
|
+
{
|
|
345
|
+
"hash": "0x123...",
|
|
346
|
+
"status": "success",
|
|
347
|
+
"block": 12345678,
|
|
348
|
+
"from": { "address": "0xabc...", "label": "Uniswap V3: Router" },
|
|
349
|
+
"to": { "address": "0xdef...", "label": "WETH" },
|
|
350
|
+
"value": "0",
|
|
351
|
+
"gas": { "used": 150000, "price": "20000000000", "cost": "0.003" }
|
|
352
|
+
}
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
With `includeInternalTxs: true`:
|
|
356
|
+
```json
|
|
357
|
+
{
|
|
358
|
+
"internalTransactions": [
|
|
359
|
+
{
|
|
360
|
+
"from": { "address": "0x...", "label": "Uniswap V3: Router" },
|
|
361
|
+
"to": { "address": "0x...", "label": null },
|
|
362
|
+
"value": "1.5",
|
|
363
|
+
"type": "call"
|
|
364
|
+
}
|
|
365
|
+
]
|
|
366
|
+
}
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
With `includeTokenTransfers: true`:
|
|
370
|
+
```json
|
|
371
|
+
{
|
|
372
|
+
"tokenTransfers": [
|
|
373
|
+
{
|
|
374
|
+
"token": { "address": "0x...", "name": "Wrapped Ether", "symbol": "WETH", "decimals": 18 },
|
|
375
|
+
"from": { "address": "0x...", "label": null },
|
|
376
|
+
"to": { "address": "0x...", "label": "Uniswap V3: Router" },
|
|
377
|
+
"value": "1.5"
|
|
378
|
+
}
|
|
379
|
+
]
|
|
380
|
+
}
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
With `decodeLogs: true`:
|
|
384
|
+
```json
|
|
385
|
+
{
|
|
386
|
+
"decodedEvents": [
|
|
387
|
+
{
|
|
388
|
+
"name": "Transfer",
|
|
389
|
+
"address": { "address": "0x...", "label": "WETH" },
|
|
390
|
+
"params": { "from": "0x...", "to": "0x...", "value": "1500000000000000000" }
|
|
391
|
+
}
|
|
392
|
+
],
|
|
393
|
+
"undecodedEventsCount": 2
|
|
394
|
+
}
|
|
395
|
+
```
|
|
396
|
+
|
|
397
|
+
##### Supported Decoded Events
|
|
398
|
+
|
|
399
|
+
| Event | Description |
|
|
400
|
+
|-------|-------------|
|
|
401
|
+
| `Transfer` | ERC-20 token transfer |
|
|
402
|
+
| `Approval` | ERC-20 approval for spending |
|
|
403
|
+
| `Deposit` | WETH deposit (ETH → WETH) |
|
|
404
|
+
| `Withdrawal` | WETH withdrawal (WETH → ETH) |
|
|
405
|
+
|
|
406
|
+
#### eth-address-balance
|
|
407
|
+
|
|
408
|
+
Get the ETH balance of an Ethereum address. Returns balance in both ETH and Wei.
|
|
409
|
+
|
|
410
|
+
##### Parameters
|
|
411
|
+
|
|
412
|
+
| Parameter | Type | Required | Default | Description |
|
|
413
|
+
|-----------|------|----------|---------|-------------|
|
|
414
|
+
| `address` | `string` | Yes | - | Ethereum address (0x...) |
|
|
415
|
+
| `chainId` | `string` | No | `"1"` | Chain ID (see table above) |
|
|
416
|
+
|
|
417
|
+
##### Usage Examples
|
|
418
|
+
|
|
419
|
+
```typescript
|
|
420
|
+
// Get balance on Ethereum mainnet
|
|
421
|
+
ethAddressBalance({ address: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045" })
|
|
422
|
+
|
|
423
|
+
// Get balance on Arbitrum
|
|
424
|
+
ethAddressBalance({
|
|
425
|
+
address: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045",
|
|
426
|
+
chainId: "42161"
|
|
427
|
+
})
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
#### eth-address-txs
|
|
431
|
+
|
|
432
|
+
List Ethereum transactions for an address. Shows incoming and outgoing transactions with values, timestamps, and status.
|
|
433
|
+
|
|
434
|
+
##### Parameters
|
|
435
|
+
|
|
436
|
+
| Parameter | Type | Required | Default | Description |
|
|
437
|
+
|-----------|------|----------|---------|-------------|
|
|
438
|
+
| `address` | `string` | Yes | - | Ethereum address (0x...) |
|
|
439
|
+
| `limit` | `number` | No | `20` | Maximum number of transactions to return |
|
|
440
|
+
| `chainId` | `string` | No | `"1"` | Chain ID (see table above) |
|
|
441
|
+
|
|
442
|
+
##### Usage Examples
|
|
443
|
+
|
|
444
|
+
```typescript
|
|
445
|
+
// List recent transactions on Ethereum mainnet
|
|
446
|
+
ethAddressTxs({ address: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045" })
|
|
447
|
+
|
|
448
|
+
// List last 50 transactions on Base
|
|
449
|
+
ethAddressTxs({
|
|
450
|
+
address: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045",
|
|
451
|
+
limit: 50,
|
|
452
|
+
chainId: "8453"
|
|
453
|
+
})
|
|
454
|
+
```
|
|
455
|
+
|
|
456
|
+
#### eth-token-transfers
|
|
457
|
+
|
|
458
|
+
List ERC-20 token transfers for an Ethereum address. Shows token names, symbols, values, and transaction details.
|
|
459
|
+
|
|
460
|
+
##### Parameters
|
|
461
|
+
|
|
462
|
+
| Parameter | Type | Required | Default | Description |
|
|
463
|
+
|-----------|------|----------|---------|-------------|
|
|
464
|
+
| `address` | `string` | Yes | - | Ethereum address (0x...) |
|
|
465
|
+
| `limit` | `number` | No | `20` | Maximum number of transfers to return |
|
|
466
|
+
| `chainId` | `string` | No | `"1"` | Chain ID (see table above) |
|
|
467
|
+
|
|
468
|
+
##### Usage Examples
|
|
469
|
+
|
|
470
|
+
```typescript
|
|
471
|
+
// List recent token transfers on Ethereum mainnet
|
|
472
|
+
ethTokenTransfers({ address: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045" })
|
|
473
|
+
|
|
474
|
+
// List last 100 token transfers on Optimism
|
|
475
|
+
ethTokenTransfers({
|
|
476
|
+
address: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045",
|
|
477
|
+
limit: 100,
|
|
478
|
+
chainId: "10"
|
|
479
|
+
})
|
|
480
|
+
```
|
|
481
|
+
|
|
482
|
+
---
|
|
483
|
+
|
|
259
484
|
## Hooks
|
|
260
485
|
|
|
261
486
|
Hooks run actions on session events. Configuration is loaded from standard OpenCode configuration directories.
|
package/command/commit-push.md
CHANGED
|
@@ -9,7 +9,7 @@ agent: build
|
|
|
9
9
|
|
|
10
10
|
## Your task
|
|
11
11
|
|
|
12
|
-
1.
|
|
12
|
+
1. Run `/diff-summary` to analyze all working tree changes
|
|
13
13
|
2. Present a summary to the user:
|
|
14
14
|
- Files modified/added/deleted with stats
|
|
15
15
|
- Proposed commit message based on the changes
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Show working tree changes (staged, unstaged, untracked)
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Diff Summary: Working Tree → HEAD
|
|
6
|
+
|
|
7
|
+
## Status
|
|
8
|
+
!`git status --porcelain`
|
|
9
|
+
|
|
10
|
+
## Staged Changes
|
|
11
|
+
!`git diff --cached --stat`
|
|
12
|
+
!`git diff --cached`
|
|
13
|
+
|
|
14
|
+
## Unstaged Changes
|
|
15
|
+
!`git diff --stat`
|
|
16
|
+
!`git diff`
|
|
17
|
+
|
|
18
|
+
## Untracked Files Content
|
|
19
|
+
!`bash -c 'git ls-files --others --exclude-standard | while read f; do [ -f "$f" ] && echo "=== $f ===" && sed -n "1,50p" "$f" && sed -n "51p" "$f" | grep -q . && echo "... (truncated)"; done'`
|
package/command/doc-changes.md
CHANGED
|
@@ -5,7 +5,7 @@ agent: doc-writer
|
|
|
5
5
|
|
|
6
6
|
## Analysis Phase
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
Run `/diff-summary` to get the working tree changes, then:
|
|
9
9
|
|
|
10
10
|
1. **Identify new features** in the changes:
|
|
11
11
|
- New public APIs, functions, or methods
|
|
@@ -5,4 +5,18 @@ agent: code-reviewer
|
|
|
5
5
|
|
|
6
6
|
# Review: Working Tree → HEAD
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
## Status
|
|
9
|
+
!`git status --porcelain`
|
|
10
|
+
|
|
11
|
+
## Staged Changes
|
|
12
|
+
!`git diff --cached --stat`
|
|
13
|
+
!`git diff --cached`
|
|
14
|
+
|
|
15
|
+
## Unstaged Changes
|
|
16
|
+
!`git diff --stat`
|
|
17
|
+
!`git diff`
|
|
18
|
+
|
|
19
|
+
## Untracked Files Content
|
|
20
|
+
!`bash -c 'git ls-files --others --exclude-standard | while read f; do [ -f "$f" ] && echo "=== $f ===" && sed -n "1,50p" "$f" && sed -n "51p" "$f" | grep -q . && echo "... (truncated)"; done'`
|
|
21
|
+
|
|
22
|
+
Review the above changes for quality, correctness, and adherence to project guidelines.
|
package/command/review-pr.md
CHANGED
|
@@ -3,6 +3,21 @@ description: Review changes from source branch into target branch
|
|
|
3
3
|
agent: code-reviewer
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
# Review:
|
|
6
|
+
# Review: $1 → $2
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
## Fetch latest
|
|
9
|
+
!`git fetch --all --prune 2>/dev/null || true`
|
|
10
|
+
|
|
11
|
+
## Stats Overview
|
|
12
|
+
!`git diff --stat $2...$1`
|
|
13
|
+
|
|
14
|
+
## Commits to Review
|
|
15
|
+
!`git log --oneline --no-merges $2..$1`
|
|
16
|
+
|
|
17
|
+
## Files Changed
|
|
18
|
+
!`git diff --name-only $2...$1`
|
|
19
|
+
|
|
20
|
+
## Full Diff
|
|
21
|
+
!`git diff -U5 --function-context $2...$1`
|
|
22
|
+
|
|
23
|
+
Review the above changes for quality, correctness, and adherence to project guidelines.
|
package/dist/index.js
CHANGED
|
@@ -5,7 +5,7 @@ import { getGlobalHookDir, getProjectHookDir } from "./config-paths";
|
|
|
5
5
|
import { hasCodeExtension } from "./code-files";
|
|
6
6
|
import { log } from "./logger";
|
|
7
7
|
import { executeBashAction, DEFAULT_BASH_TIMEOUT, } from "./bash-executor";
|
|
8
|
-
import { gitingestTool,
|
|
8
|
+
import { gitingestTool, createPromptSessionTool, createListChildSessionsTool, ethTransactionTool, ethAddressTxsTool, ethAddressBalanceTool, ethTokenTransfersTool, } from "./tools";
|
|
9
9
|
export { parseFrontmatter, loadAgents, loadCommands } from "./loaders";
|
|
10
10
|
// ============================================================================
|
|
11
11
|
// CONSTANTS
|
|
@@ -30,7 +30,13 @@ const SmartfrogPlugin = async (ctx) => {
|
|
|
30
30
|
agents: Object.keys(agents),
|
|
31
31
|
commands: Object.keys(commands),
|
|
32
32
|
hooks: Array.from(hooks.keys()),
|
|
33
|
-
tools: [
|
|
33
|
+
tools: [
|
|
34
|
+
"gitingest",
|
|
35
|
+
"eth-transaction",
|
|
36
|
+
"eth-address-txs",
|
|
37
|
+
"eth-address-balance",
|
|
38
|
+
"eth-token-transfers",
|
|
39
|
+
],
|
|
34
40
|
});
|
|
35
41
|
async function executeHookActions(hook, sessionID, extraLog, options) {
|
|
36
42
|
const prefix = `[hook:${hook.event}]`;
|
|
@@ -176,9 +182,12 @@ const SmartfrogPlugin = async (ctx) => {
|
|
|
176
182
|
},
|
|
177
183
|
tool: {
|
|
178
184
|
gitingest: gitingestTool,
|
|
179
|
-
"diff-summary": createDiffSummaryTool(ctx.directory),
|
|
180
185
|
"prompt-session": createPromptSessionTool(ctx.client),
|
|
181
186
|
"list-child-sessions": createListChildSessionsTool(ctx.client),
|
|
187
|
+
"eth-transaction": ethTransactionTool,
|
|
188
|
+
"eth-address-txs": ethAddressTxsTool,
|
|
189
|
+
"eth-address-balance": ethAddressBalanceTool,
|
|
190
|
+
"eth-token-transfers": ethTokenTransfersTool,
|
|
182
191
|
},
|
|
183
192
|
"tool.execute.before": async (input, output) => {
|
|
184
193
|
const sessionID = input.sessionID;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool to get Ethereum address balance
|
|
3
|
+
*/
|
|
4
|
+
import { type ToolContext } from "@opencode-ai/plugin";
|
|
5
|
+
export interface EthAddressBalanceArgs {
|
|
6
|
+
address: string;
|
|
7
|
+
chainId?: string;
|
|
8
|
+
}
|
|
9
|
+
export declare function getAddressBalance(address: string, chainId?: string): Promise<string>;
|
|
10
|
+
export declare const ethAddressBalanceTool: {
|
|
11
|
+
description: string;
|
|
12
|
+
args: {
|
|
13
|
+
address: import("zod").ZodString;
|
|
14
|
+
chainId: import("zod").ZodOptional<import("zod").ZodString>;
|
|
15
|
+
};
|
|
16
|
+
execute(args: {
|
|
17
|
+
address: string;
|
|
18
|
+
chainId?: string | undefined;
|
|
19
|
+
}, context: ToolContext): Promise<string>;
|
|
20
|
+
};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool to get Ethereum address balance
|
|
3
|
+
*/
|
|
4
|
+
import { tool } from "@opencode-ai/plugin";
|
|
5
|
+
import { EtherscanClient, EtherscanClientError, validateAddress } from "./etherscan-client";
|
|
6
|
+
import { formatBalance } from "./formatters";
|
|
7
|
+
import { CHAIN_ID_DESCRIPTION } from "./types";
|
|
8
|
+
export async function getAddressBalance(address, chainId) {
|
|
9
|
+
validateAddress(address);
|
|
10
|
+
const client = new EtherscanClient(undefined, chainId);
|
|
11
|
+
const balanceWei = await client.getBalance(address);
|
|
12
|
+
return formatBalance(address, balanceWei);
|
|
13
|
+
}
|
|
14
|
+
export const ethAddressBalanceTool = tool({
|
|
15
|
+
description: "Get the ETH balance of an Ethereum address. " +
|
|
16
|
+
"Returns balance in both ETH and Wei.",
|
|
17
|
+
args: {
|
|
18
|
+
address: tool.schema
|
|
19
|
+
.string()
|
|
20
|
+
.describe("Ethereum address (0x...)"),
|
|
21
|
+
chainId: tool.schema
|
|
22
|
+
.string()
|
|
23
|
+
.optional()
|
|
24
|
+
.describe(CHAIN_ID_DESCRIPTION),
|
|
25
|
+
},
|
|
26
|
+
async execute(args, _context) {
|
|
27
|
+
try {
|
|
28
|
+
return await getAddressBalance(args.address, args.chainId);
|
|
29
|
+
}
|
|
30
|
+
catch (error) {
|
|
31
|
+
if (error instanceof EtherscanClientError) {
|
|
32
|
+
return `Error: ${error.message}`;
|
|
33
|
+
}
|
|
34
|
+
throw error;
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
});
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool to list Ethereum transactions for an address
|
|
3
|
+
*/
|
|
4
|
+
import { type ToolContext } from "@opencode-ai/plugin";
|
|
5
|
+
export interface EthAddressTxsArgs {
|
|
6
|
+
address: string;
|
|
7
|
+
limit?: number;
|
|
8
|
+
chainId?: string;
|
|
9
|
+
}
|
|
10
|
+
export declare function getAddressTransactions(address: string, limit?: number, chainId?: string): Promise<string>;
|
|
11
|
+
export declare const ethAddressTxsTool: {
|
|
12
|
+
description: string;
|
|
13
|
+
args: {
|
|
14
|
+
address: import("zod").ZodString;
|
|
15
|
+
limit: import("zod").ZodOptional<import("zod").ZodNumber>;
|
|
16
|
+
chainId: import("zod").ZodOptional<import("zod").ZodString>;
|
|
17
|
+
};
|
|
18
|
+
execute(args: {
|
|
19
|
+
address: string;
|
|
20
|
+
limit?: number | undefined;
|
|
21
|
+
chainId?: string | undefined;
|
|
22
|
+
}, context: ToolContext): Promise<string>;
|
|
23
|
+
};
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool to list Ethereum transactions for an address
|
|
3
|
+
*/
|
|
4
|
+
import { tool } from "@opencode-ai/plugin";
|
|
5
|
+
import { EtherscanClient, EtherscanClientError, validateAddress } from "./etherscan-client";
|
|
6
|
+
import { formatTransactionList } from "./formatters";
|
|
7
|
+
import { DEFAULT_TRANSACTION_LIMIT, CHAIN_ID_DESCRIPTION } from "./types";
|
|
8
|
+
export async function getAddressTransactions(address, limit = DEFAULT_TRANSACTION_LIMIT, chainId) {
|
|
9
|
+
validateAddress(address);
|
|
10
|
+
const client = new EtherscanClient(undefined, chainId);
|
|
11
|
+
const transactions = await client.getTransactions(address, limit);
|
|
12
|
+
return formatTransactionList(address, transactions);
|
|
13
|
+
}
|
|
14
|
+
export const ethAddressTxsTool = tool({
|
|
15
|
+
description: "List Ethereum transactions for an address. " +
|
|
16
|
+
"Shows incoming and outgoing transactions with values, timestamps, and status.",
|
|
17
|
+
args: {
|
|
18
|
+
address: tool.schema
|
|
19
|
+
.string()
|
|
20
|
+
.describe("Ethereum address (0x...)"),
|
|
21
|
+
limit: tool.schema
|
|
22
|
+
.number()
|
|
23
|
+
.optional()
|
|
24
|
+
.describe(`Maximum number of transactions to return (default: ${DEFAULT_TRANSACTION_LIMIT})`),
|
|
25
|
+
chainId: tool.schema
|
|
26
|
+
.string()
|
|
27
|
+
.optional()
|
|
28
|
+
.describe(CHAIN_ID_DESCRIPTION),
|
|
29
|
+
},
|
|
30
|
+
async execute(args, _context) {
|
|
31
|
+
try {
|
|
32
|
+
return await getAddressTransactions(args.address, args.limit, args.chainId);
|
|
33
|
+
}
|
|
34
|
+
catch (error) {
|
|
35
|
+
if (error instanceof EtherscanClientError) {
|
|
36
|
+
return `Error: ${error.message}`;
|
|
37
|
+
}
|
|
38
|
+
throw error;
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
});
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool to list ERC-20 token transfers for an address
|
|
3
|
+
*/
|
|
4
|
+
import { type ToolContext } from "@opencode-ai/plugin";
|
|
5
|
+
export interface EthTokenTransfersArgs {
|
|
6
|
+
address: string;
|
|
7
|
+
limit?: number;
|
|
8
|
+
chainId?: string;
|
|
9
|
+
}
|
|
10
|
+
export declare function getTokenTransfers(address: string, limit?: number, chainId?: string): Promise<string>;
|
|
11
|
+
export declare const ethTokenTransfersTool: {
|
|
12
|
+
description: string;
|
|
13
|
+
args: {
|
|
14
|
+
address: import("zod").ZodString;
|
|
15
|
+
limit: import("zod").ZodOptional<import("zod").ZodNumber>;
|
|
16
|
+
chainId: import("zod").ZodOptional<import("zod").ZodString>;
|
|
17
|
+
};
|
|
18
|
+
execute(args: {
|
|
19
|
+
address: string;
|
|
20
|
+
limit?: number | undefined;
|
|
21
|
+
chainId?: string | undefined;
|
|
22
|
+
}, context: ToolContext): Promise<string>;
|
|
23
|
+
};
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool to list ERC-20 token transfers for an address
|
|
3
|
+
*/
|
|
4
|
+
import { tool } from "@opencode-ai/plugin";
|
|
5
|
+
import { EtherscanClient, EtherscanClientError, validateAddress } from "./etherscan-client";
|
|
6
|
+
import { formatTokenTransferList } from "./formatters";
|
|
7
|
+
import { DEFAULT_TRANSACTION_LIMIT, CHAIN_ID_DESCRIPTION } from "./types";
|
|
8
|
+
export async function getTokenTransfers(address, limit = DEFAULT_TRANSACTION_LIMIT, chainId) {
|
|
9
|
+
validateAddress(address);
|
|
10
|
+
const client = new EtherscanClient(undefined, chainId);
|
|
11
|
+
const transfers = await client.getTokenTransfers(address, limit);
|
|
12
|
+
return formatTokenTransferList(address, transfers);
|
|
13
|
+
}
|
|
14
|
+
export const ethTokenTransfersTool = tool({
|
|
15
|
+
description: "List ERC-20 token transfers for an Ethereum address. " +
|
|
16
|
+
"Shows token names, symbols, values, and transaction details.",
|
|
17
|
+
args: {
|
|
18
|
+
address: tool.schema
|
|
19
|
+
.string()
|
|
20
|
+
.describe("Ethereum address (0x...)"),
|
|
21
|
+
limit: tool.schema
|
|
22
|
+
.number()
|
|
23
|
+
.optional()
|
|
24
|
+
.describe(`Maximum number of transfers to return (default: ${DEFAULT_TRANSACTION_LIMIT})`),
|
|
25
|
+
chainId: tool.schema
|
|
26
|
+
.string()
|
|
27
|
+
.optional()
|
|
28
|
+
.describe(CHAIN_ID_DESCRIPTION),
|
|
29
|
+
},
|
|
30
|
+
async execute(args, _context) {
|
|
31
|
+
try {
|
|
32
|
+
return await getTokenTransfers(args.address, args.limit, args.chainId);
|
|
33
|
+
}
|
|
34
|
+
catch (error) {
|
|
35
|
+
if (error instanceof EtherscanClientError) {
|
|
36
|
+
return `Error: ${error.message}`;
|
|
37
|
+
}
|
|
38
|
+
throw error;
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
});
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool to get Ethereum transaction details by hash
|
|
3
|
+
*/
|
|
4
|
+
import { type ToolContext } from "@opencode-ai/plugin";
|
|
5
|
+
import { type TransactionDetails } from "./types";
|
|
6
|
+
export interface EthTransactionArgs {
|
|
7
|
+
hash: string;
|
|
8
|
+
chainId?: string;
|
|
9
|
+
includeInternalTxs?: boolean;
|
|
10
|
+
includeTokenTransfers?: boolean;
|
|
11
|
+
decodeLogs?: boolean;
|
|
12
|
+
}
|
|
13
|
+
export declare function getTransactionDetails(hash: string, chainId?: string, options?: {
|
|
14
|
+
includeInternalTxs?: boolean;
|
|
15
|
+
includeTokenTransfers?: boolean;
|
|
16
|
+
decodeLogs?: boolean;
|
|
17
|
+
}): Promise<TransactionDetails>;
|
|
18
|
+
export declare const ethTransactionTool: {
|
|
19
|
+
description: string;
|
|
20
|
+
args: {
|
|
21
|
+
hash: import("zod").ZodString;
|
|
22
|
+
chainId: import("zod").ZodOptional<import("zod").ZodString>;
|
|
23
|
+
includeInternalTxs: import("zod").ZodOptional<import("zod").ZodBoolean>;
|
|
24
|
+
includeTokenTransfers: import("zod").ZodOptional<import("zod").ZodBoolean>;
|
|
25
|
+
decodeLogs: import("zod").ZodOptional<import("zod").ZodBoolean>;
|
|
26
|
+
};
|
|
27
|
+
execute(args: {
|
|
28
|
+
hash: string;
|
|
29
|
+
chainId?: string | undefined;
|
|
30
|
+
includeInternalTxs?: boolean | undefined;
|
|
31
|
+
includeTokenTransfers?: boolean | undefined;
|
|
32
|
+
decodeLogs?: boolean | undefined;
|
|
33
|
+
}, context: ToolContext): Promise<string>;
|
|
34
|
+
};
|