chia-explorer 0.1.5 → 0.2.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 +172 -10
- package/dist/chia/offer.d.ts +58 -0
- package/dist/chia/offer.js +356 -0
- package/dist/chia/offer.js.map +1 -0
- package/dist/chips/index.d.ts +68 -0
- package/dist/chips/index.js +214 -0
- package/dist/chips/index.js.map +1 -0
- package/dist/chips/parser.d.ts +30 -0
- package/dist/chips/parser.js +208 -0
- package/dist/chips/parser.js.map +1 -0
- package/dist/github/cache.d.ts +3 -0
- package/dist/github/cache.js +18 -0
- package/dist/github/cache.js.map +1 -0
- package/dist/github/client.d.ts +5 -0
- package/dist/github/client.js +68 -0
- package/dist/github/client.js.map +1 -0
- package/dist/schemas/chips.d.ts +8 -0
- package/dist/schemas/chips.js +39 -0
- package/dist/schemas/chips.js.map +1 -0
- package/dist/server.js +24 -2
- package/dist/server.js.map +1 -1
- package/dist/tools/chips/get-chip.d.ts +2 -0
- package/dist/tools/chips/get-chip.js +30 -0
- package/dist/tools/chips/get-chip.js.map +1 -0
- package/dist/tools/chips/list-chip-drafts.d.ts +2 -0
- package/dist/tools/chips/list-chip-drafts.js +19 -0
- package/dist/tools/chips/list-chip-drafts.js.map +1 -0
- package/dist/tools/chips/list-chips.d.ts +2 -0
- package/dist/tools/chips/list-chips.js +33 -0
- package/dist/tools/chips/list-chips.js.map +1 -0
- package/dist/tools/chips/search-chips.d.ts +2 -0
- package/dist/tools/chips/search-chips.js +31 -0
- package/dist/tools/chips/search-chips.js.map +1 -0
- package/dist/tools/coins/get-puzzle-and-solution.js +23 -3
- package/dist/tools/coins/get-puzzle-and-solution.js.map +1 -1
- package/dist/tools/mempool/estimate-fee.d.ts +2 -0
- package/dist/tools/mempool/estimate-fee.js +73 -0
- package/dist/tools/mempool/estimate-fee.js.map +1 -0
- package/dist/tools/mempool/get-mempool.d.ts +2 -0
- package/dist/tools/mempool/get-mempool.js +51 -0
- package/dist/tools/mempool/get-mempool.js.map +1 -0
- package/dist/tools/mempool/is-in-mempool.d.ts +2 -0
- package/dist/tools/mempool/is-in-mempool.js +37 -0
- package/dist/tools/mempool/is-in-mempool.js.map +1 -0
- package/dist/tools/offers/decode-offer.d.ts +2 -0
- package/dist/tools/offers/decode-offer.js +20 -0
- package/dist/tools/offers/decode-offer.js.map +1 -0
- package/dist/tools/offers/decode-spend-bundle.d.ts +2 -0
- package/dist/tools/offers/decode-spend-bundle.js +20 -0
- package/dist/tools/offers/decode-spend-bundle.js.map +1 -0
- package/dist/tools/offers/decompile-puzzle.d.ts +2 -0
- package/dist/tools/offers/decompile-puzzle.js +62 -0
- package/dist/tools/offers/decompile-puzzle.js.map +1 -0
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -2,38 +2,66 @@
|
|
|
2
2
|
|
|
3
3
|
MCP server that answers questions about the Chia blockchain. Read-only, no keys, no signing.
|
|
4
4
|
|
|
5
|
-
Backed by the public [coinset.org](https://www.coinset.org) full-node API. Supports mainnet (default) and testnet11. Auto-detects network from `xch` or `txch` address prefixes.
|
|
5
|
+
Backed by the public [coinset.org](https://www.coinset.org) full-node API for chain data and [CoinGecko](https://www.coingecko.com) for XCH price. Offer strings and CLVM puzzles are decoded locally via the [chia-wallet-sdk](https://github.com/xch-dev/chia-wallet-sdk) native module — no extra services. Supports mainnet (default) and testnet11. Auto-detects network from `xch` or `txch` address prefixes.
|
|
6
6
|
|
|
7
7
|
## What it can answer
|
|
8
8
|
|
|
9
9
|
- What is the current netspace? Peak height? Sync status?
|
|
10
|
-
- What is the header hash of block N? How many transactions in that block?
|
|
10
|
+
- What is the header hash of block N? How many transactions in that block? What coins were created or destroyed?
|
|
11
11
|
- What is the balance of `xch1...` (or `txch1...`, or a raw puzzle hash)?
|
|
12
|
-
- Look up a coin by name. Calculate a coin name from its fields.
|
|
12
|
+
- Look up a coin by name. Calculate a coin name from its fields. Find the children produced by spending a coin.
|
|
13
|
+
- Fetch the CLVM puzzle reveal and solution for a spent coin, plus an automatic classification (xch / cat / nft / did) and parsed conditions.
|
|
14
|
+
- Decode a Chia `offer1...` string locally and tell you what's being traded. Same for any raw spend bundle.
|
|
15
|
+
- Decompile any puzzle reveal and identify its kind (CAT with asset_id, NFT with launcher_id, settlement-payments, plain p2, etc.).
|
|
16
|
+
- What's currently in the mempool? Is my specific transaction pending? What fee should I pay for inclusion in 1/5/15 minutes?
|
|
13
17
|
- Convert between addresses and puzzle hashes in either direction.
|
|
14
18
|
- What is XCH worth in USD (or EUR, GBP, BTC, ...) right now? What's this balance worth?
|
|
19
|
+
- How much XCH is left in the strategic reserve? Where has it been sent? Which destinations are known partners, market makers, or exchanges?
|
|
15
20
|
|
|
16
21
|
## Install
|
|
17
22
|
|
|
23
|
+
The server is a single npm package. No global install needed — every config below uses `npx` so it stays up to date.
|
|
24
|
+
|
|
18
25
|
```bash
|
|
19
|
-
|
|
26
|
+
npx chia-explorer
|
|
20
27
|
```
|
|
21
28
|
|
|
22
|
-
|
|
29
|
+
If you want it on your PATH:
|
|
23
30
|
|
|
24
31
|
```bash
|
|
25
|
-
|
|
32
|
+
npm install -g chia-explorer
|
|
26
33
|
```
|
|
27
34
|
|
|
28
|
-
|
|
35
|
+
Requires Node.js 20+.
|
|
36
|
+
|
|
37
|
+
## Use it with your AI client
|
|
38
|
+
|
|
39
|
+
### Claude Code
|
|
29
40
|
|
|
30
41
|
```bash
|
|
31
42
|
claude mcp add chia-explorer -- npx chia-explorer
|
|
32
43
|
```
|
|
33
44
|
|
|
34
|
-
|
|
45
|
+
### Claude Desktop
|
|
46
|
+
|
|
47
|
+
Edit `claude_desktop_config.json` (Settings → Developer → Edit Config):
|
|
48
|
+
|
|
49
|
+
```json
|
|
50
|
+
{
|
|
51
|
+
"mcpServers": {
|
|
52
|
+
"chia-explorer": {
|
|
53
|
+
"command": "npx",
|
|
54
|
+
"args": ["chia-explorer"]
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Restart Claude Desktop.
|
|
35
61
|
|
|
36
|
-
|
|
62
|
+
### Cursor
|
|
63
|
+
|
|
64
|
+
Create or edit `~/.cursor/mcp.json` (global) or `.cursor/mcp.json` inside a project:
|
|
37
65
|
|
|
38
66
|
```json
|
|
39
67
|
{
|
|
@@ -46,6 +74,122 @@ Add to your `claude_desktop_config.json`:
|
|
|
46
74
|
}
|
|
47
75
|
```
|
|
48
76
|
|
|
77
|
+
Restart Cursor and enable the server under Settings → MCP.
|
|
78
|
+
|
|
79
|
+
### Codex CLI
|
|
80
|
+
|
|
81
|
+
Edit `~/.codex/config.toml`:
|
|
82
|
+
|
|
83
|
+
```toml
|
|
84
|
+
[mcp_servers.chia-explorer]
|
|
85
|
+
command = "npx"
|
|
86
|
+
args = ["chia-explorer"]
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### VS Code (native MCP)
|
|
90
|
+
|
|
91
|
+
Create `.vscode/mcp.json` in your workspace:
|
|
92
|
+
|
|
93
|
+
```json
|
|
94
|
+
{
|
|
95
|
+
"servers": {
|
|
96
|
+
"chia-explorer": {
|
|
97
|
+
"command": "npx",
|
|
98
|
+
"args": ["chia-explorer"]
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### Windsurf
|
|
105
|
+
|
|
106
|
+
Edit `~/.codeium/windsurf/mcp_config.json`:
|
|
107
|
+
|
|
108
|
+
```json
|
|
109
|
+
{
|
|
110
|
+
"mcpServers": {
|
|
111
|
+
"chia-explorer": {
|
|
112
|
+
"command": "npx",
|
|
113
|
+
"args": ["chia-explorer"]
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
### Anything else that speaks MCP
|
|
120
|
+
|
|
121
|
+
It's a standard stdio MCP server. The recipe is always the same: `command = npx`, `args = ["chia-explorer"]`. Set `COINGECKO_API_KEY` as an env var if you have one.
|
|
122
|
+
|
|
123
|
+
## Example prompts
|
|
124
|
+
|
|
125
|
+
Drop these into a chat once the server is wired up.
|
|
126
|
+
|
|
127
|
+
**Offers**
|
|
128
|
+
|
|
129
|
+
> Decode this offer and tell me what's being traded: `offer1qqr83wcuu2rykcmqvpsxgfgqmqys...`
|
|
130
|
+
|
|
131
|
+
> I just got sent this `offer1...` string in Discord. Is it safe to take? What do I give and what do I get?
|
|
132
|
+
|
|
133
|
+
**Smart-coin inspection**
|
|
134
|
+
|
|
135
|
+
> What kind of coin is `0xabc...123`? Pull its puzzle reveal at height 6500000 and tell me if it's a CAT, NFT, DID, or plain XCH.
|
|
136
|
+
|
|
137
|
+
> Walk the children of coin `0xabc...` for two hops. Classify each child.
|
|
138
|
+
|
|
139
|
+
**Mempool and fees**
|
|
140
|
+
|
|
141
|
+
> Is `0xdeadbeef...` (my tx) currently in the mempool?
|
|
142
|
+
|
|
143
|
+
> How many transactions are pending right now? What does the fee market look like for inclusion in the next minute?
|
|
144
|
+
|
|
145
|
+
> What fee should I attach to a take_offer spend to get included in the next 5 minutes?
|
|
146
|
+
|
|
147
|
+
**Balances and pricing**
|
|
148
|
+
|
|
149
|
+
> What's the XCH balance of `xch1yxqsmyuyjdlgxw4sqjg4vqlqv5ms2qzex00586nu643jqemmarwslh08yl`? How much is that in USD and EUR right now?
|
|
150
|
+
|
|
151
|
+
> Convert 1.5 XCH to GBP, EUR, BTC, and SAT.
|
|
152
|
+
|
|
153
|
+
**Chain state**
|
|
154
|
+
|
|
155
|
+
> What block was Chia at one hour ago — height, header hash, transaction count?
|
|
156
|
+
|
|
157
|
+
> Is the network synced? What's the current netspace in EiB?
|
|
158
|
+
|
|
159
|
+
**Strategic reserve**
|
|
160
|
+
|
|
161
|
+
> How much of the 21M XCH strategic reserve has been spent? Where did the most recent five outflows go — partners, market makers, or exchanges?
|
|
162
|
+
|
|
163
|
+
> Show me every spend from the Swiss cold wallet, with the destination labelled.
|
|
164
|
+
|
|
165
|
+
**Identifier glue**
|
|
166
|
+
|
|
167
|
+
> Convert this puzzle hash to a mainnet address: `4bf5122f344554c53bde2ebb8cd2b7e3d1600ad631c385a5d7cce23c7785459a`.
|
|
168
|
+
|
|
169
|
+
> What's the coin name for parent `0xaaa...`, puzzle hash `0xbbb...`, amount 1000000000000?
|
|
170
|
+
|
|
171
|
+
## Pre-built workflows: chia-skills
|
|
172
|
+
|
|
173
|
+
[**chia-skills**](https://github.com/Spacetime-Technology/chia-skills) is a companion package of Claude Code skills built on top of this MCP. It turns the read-only tools below into finished workflows you can actually schedule and get notified about: deposit alerts, price triggers, offer safety checks, NFT provenance, invoice watching.
|
|
174
|
+
|
|
175
|
+
```bash
|
|
176
|
+
npx chia-skills install
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
What's in the box:
|
|
180
|
+
|
|
181
|
+
- `watch-address` — push notification when XCH, a CAT, or an NFT lands at (or leaves) an address
|
|
182
|
+
- `watch-tx-confirmation` — ping when a specific tx_id moves from mempool to confirmed
|
|
183
|
+
- `watch-xch-price` — alert when XCH crosses a threshold in any CoinGecko currency
|
|
184
|
+
- `watch-fee-market` — catch cheap fee windows to broadcast
|
|
185
|
+
- `watch-prefarm-spend` — flag new strategic-reserve outflows with destinations labelled
|
|
186
|
+
- `address-daily-digest` — daily summary of one or more addresses with USD values
|
|
187
|
+
- `offer-safety-check` — decode an `offer1...` and check both sides against market prices
|
|
188
|
+
- `coin-lineage` / `nft-provenance` — walk coin or NFT history N hops in either direction
|
|
189
|
+
- `invoice-watch` — generate an invoice, watch for the matching deposit, emit a paid receipt
|
|
190
|
+
|
|
191
|
+
Skills are read-only and idempotent, persist state between runs, and accept structured inputs so other skills or agents can chain them. If you want to see what's possible with chia-explorer beyond ad-hoc prompts, start there. If you want to write your own, the skills repo is the reference.
|
|
192
|
+
|
|
49
193
|
## Tools
|
|
50
194
|
|
|
51
195
|
| Tool | What it does |
|
|
@@ -56,26 +200,44 @@ Add to your `claude_desktop_config.json`:
|
|
|
56
200
|
| `get_block_by_height` | Block record + header hash for a height |
|
|
57
201
|
| `get_block_by_hash` | Block record for a header hash |
|
|
58
202
|
| `count_block_transactions` | Coin spends, additions, removals counts for a block |
|
|
203
|
+
| `get_block_additions_and_removals` | Every coin created and destroyed in a block (full lists, not just counts) |
|
|
59
204
|
| `get_balance` | Balance of an address or puzzle hash (paginated, unspent coins) |
|
|
60
205
|
| `get_coin_records_by_puzzle_hash` | Raw coin records for a puzzle hash or address |
|
|
206
|
+
| `get_coin_records_by_parent_ids` | Children of one or more spent coins (the usual coin-lineage step) |
|
|
61
207
|
| `get_coin_by_name` | Coin record by coin name |
|
|
62
208
|
| `calculate_coin_name` | sha256(parent_coin_info \|\| puzzle_hash \|\| amount) — no RPC |
|
|
209
|
+
| `get_puzzle_and_solution` | CLVM puzzle reveal + solution for a spent coin, plus automatic puzzle classification and parsed conditions |
|
|
210
|
+
| `decode_offer` | Decode a `offer1...` string locally into offered / requested assets (XCH, CATs with asset_id, NFTs with launcher_id) |
|
|
211
|
+
| `decode_spend_bundle` | Same trade-summary shape as `decode_offer` but for any raw hex spend bundle (e.g. a mempool item) |
|
|
212
|
+
| `decompile_puzzle` | Classify any CLVM puzzle reveal (or fetch via coin_id+height) and optionally parse the conditions a spend emits |
|
|
213
|
+
| `get_mempool` | List tx_ids currently in the mempool (paginated, with optional full items) |
|
|
214
|
+
| `is_in_mempool` | Check whether a specific tx_id is sitting in the mempool right now |
|
|
215
|
+
| `estimate_fee` | Recommended mojo fee for inclusion in 1/5/15 minutes (configurable target_times + spend_type bias) |
|
|
63
216
|
| `address_to_puzzle_hash` | bech32m decode — no RPC |
|
|
64
217
|
| `puzzle_hash_to_address` | bech32m encode — no RPC |
|
|
65
218
|
| `get_xch_price` | Current XCH spot price in one or more currencies (CoinGecko) |
|
|
66
219
|
| `convert_xch_to_fiat` | Convert a mojo amount to fiat using the current XCH price |
|
|
220
|
+
| `get_prefarm_status` | Live per-wallet balances of the 21M XCH strategic reserve, plus total spent |
|
|
221
|
+
| `get_prefarm_spends` | Outflows from the reserve, with destinations labelled when known (partners / market makers / exchanges). Filter by wallet, height, or count |
|
|
222
|
+
| `list_prefarm_addresses` | The hardcoded registry: custody wallets and known destination addresses. No network call |
|
|
223
|
+
| `list_chips` | Merged Chia Improvement Proposals on `main`, parsed front matter + abstract. Filter by status or category |
|
|
224
|
+
| `get_chip` | One CHIP by number. Returns the merged version (if any), any open PR drafts proposing the same number, and optionally the full markdown |
|
|
225
|
+
| `list_chip_drafts` | Open PRs against `Chia-Network/chips` that add or modify a CHIP, with parsed front matter and PR context (author, reviewers, draft flag) |
|
|
226
|
+
| `search_chips` | Keyword search across merged CHIPs and open PR drafts (title, description, abstract, authors) |
|
|
67
227
|
|
|
68
|
-
Blockchain tools take an optional `network: "mainnet" | "testnet11"` (default `mainnet`). The price tools
|
|
228
|
+
Blockchain tools take an optional `network: "mainnet" | "testnet11"` (default `mainnet`). The price and CHIPs tools take no network arg. The prefarm tools are mainnet only.
|
|
69
229
|
|
|
70
230
|
## Optional config
|
|
71
231
|
|
|
72
232
|
- `COINGECKO_API_KEY` — if set, sent as `x-cg-demo-api-key` to lift the free-tier rate limit. The price tools work without it.
|
|
233
|
+
- `GITHUB_TOKEN` — if set, sent as `Authorization: Bearer …` to the GitHub API. Lifts the unauthenticated 60/hr limit to 5000/hr for CHIPs listings. Raw file fetches don't need it. The CHIPs tools work without it.
|
|
73
234
|
|
|
74
235
|
## Prompts
|
|
75
236
|
|
|
76
237
|
- `network_status` — quick snapshot of current chain state
|
|
77
238
|
- `address_summary` — balance and recent activity for an address
|
|
78
239
|
- `block_summary` — block details plus transaction counts
|
|
240
|
+
- `prefarm_summary` — strategic reserve balances, recent outflows, and known destinations
|
|
79
241
|
|
|
80
242
|
## What it isn't
|
|
81
243
|
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
export type AssetKind = 'xch' | 'cat' | 'nft' | 'singleton' | 'did' | 'unknown';
|
|
2
|
+
export interface OfferedAsset {
|
|
3
|
+
asset_kind: AssetKind;
|
|
4
|
+
asset_id?: string | undefined;
|
|
5
|
+
nft_launcher_id?: string | undefined;
|
|
6
|
+
amount_mojo: string;
|
|
7
|
+
amount_xch?: string | undefined;
|
|
8
|
+
source_puzzle_hash: string;
|
|
9
|
+
source_coin_id: string;
|
|
10
|
+
}
|
|
11
|
+
export interface RequestedAsset {
|
|
12
|
+
asset_kind: AssetKind;
|
|
13
|
+
asset_id?: string | undefined;
|
|
14
|
+
nft_launcher_id?: string | undefined;
|
|
15
|
+
amount_mojo: string;
|
|
16
|
+
amount_xch?: string | undefined;
|
|
17
|
+
destination_puzzle_hash: string;
|
|
18
|
+
nonce: string;
|
|
19
|
+
}
|
|
20
|
+
export interface TradeSummary {
|
|
21
|
+
offered: OfferedAsset[];
|
|
22
|
+
requested: RequestedAsset[];
|
|
23
|
+
fee_mojo: string;
|
|
24
|
+
coin_spends_count: number;
|
|
25
|
+
aggregated_signature: string;
|
|
26
|
+
}
|
|
27
|
+
export interface ClassifiedSpend {
|
|
28
|
+
kind: AssetKind;
|
|
29
|
+
asset_id?: string | undefined;
|
|
30
|
+
launcher_id?: string | undefined;
|
|
31
|
+
inner_puzzle_hash?: string | undefined;
|
|
32
|
+
puzzle_hash: string;
|
|
33
|
+
/** True when the inner puzzle is the settlement-payments mod (i.e. this coin holds requested payments). */
|
|
34
|
+
is_settlement: boolean;
|
|
35
|
+
}
|
|
36
|
+
export interface ParsedCondition {
|
|
37
|
+
opcode: string;
|
|
38
|
+
data: Record<string, unknown>;
|
|
39
|
+
}
|
|
40
|
+
export interface ParsedConditions {
|
|
41
|
+
create_coins: Array<{
|
|
42
|
+
puzzle_hash: string;
|
|
43
|
+
amount: string;
|
|
44
|
+
memos: string[];
|
|
45
|
+
}>;
|
|
46
|
+
reserve_fee_mojo: string;
|
|
47
|
+
agg_sigs_count: number;
|
|
48
|
+
announcements: Array<{
|
|
49
|
+
kind: 'create_coin' | 'create_puzzle';
|
|
50
|
+
message: string;
|
|
51
|
+
}>;
|
|
52
|
+
asserts: ParsedCondition[];
|
|
53
|
+
other: ParsedCondition[];
|
|
54
|
+
}
|
|
55
|
+
export declare function classifyPuzzle(puzzleRevealHex: string): ClassifiedSpend;
|
|
56
|
+
export declare function parseConditions(puzzleRevealHex: string, solutionHex: string): ParsedConditions;
|
|
57
|
+
export declare function decodeOfferString(offer: string): TradeSummary;
|
|
58
|
+
export declare function summarizeSpendBundleHex(bundleHex: string): TradeSummary;
|
|
@@ -0,0 +1,356 @@
|
|
|
1
|
+
import { Clvm, Constants, SpendBundle, bytesEqual, decodeOffer, toHex, } from 'chia-wallet-sdk';
|
|
2
|
+
import { hexToBytes, stripHexPrefix } from './hex.js';
|
|
3
|
+
import { mojoToXch } from './amounts.js';
|
|
4
|
+
function memosToStrings(memos) {
|
|
5
|
+
if (!memos)
|
|
6
|
+
return [];
|
|
7
|
+
const list = memos.toList();
|
|
8
|
+
if (!list)
|
|
9
|
+
return [];
|
|
10
|
+
const out = [];
|
|
11
|
+
for (const m of list) {
|
|
12
|
+
const atom = m.toAtom();
|
|
13
|
+
if (atom)
|
|
14
|
+
out.push(toHex(atom));
|
|
15
|
+
}
|
|
16
|
+
return out;
|
|
17
|
+
}
|
|
18
|
+
function classifyProgram(clvm, puzzleProgram) {
|
|
19
|
+
const puzzle = puzzleProgram.puzzle();
|
|
20
|
+
const puzzleHash = toHex(puzzle.puzzleHash);
|
|
21
|
+
const settlementHash = Constants.settlementPaymentHash();
|
|
22
|
+
if (bytesEqual(puzzle.puzzleHash, settlementHash)) {
|
|
23
|
+
return {
|
|
24
|
+
kind: 'xch',
|
|
25
|
+
is_settlement_outer: true,
|
|
26
|
+
is_settlement_inner: false,
|
|
27
|
+
puzzle_hash: puzzleHash,
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
const catInfo = puzzle.parseCatInfo();
|
|
31
|
+
if (catInfo) {
|
|
32
|
+
const inner = catInfo.info.p2PuzzleHash;
|
|
33
|
+
const inner_puzzle_hash = toHex(inner);
|
|
34
|
+
return {
|
|
35
|
+
kind: 'cat',
|
|
36
|
+
asset_id: toHex(catInfo.info.assetId),
|
|
37
|
+
inner_puzzle_hash,
|
|
38
|
+
is_settlement_outer: false,
|
|
39
|
+
is_settlement_inner: bytesEqual(inner, settlementHash),
|
|
40
|
+
puzzle_hash: puzzleHash,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
const nftInfo = puzzle.parseNftInfo();
|
|
44
|
+
if (nftInfo) {
|
|
45
|
+
const inner = nftInfo.info.p2PuzzleHash;
|
|
46
|
+
return {
|
|
47
|
+
kind: 'nft',
|
|
48
|
+
launcher_id: toHex(nftInfo.info.launcherId),
|
|
49
|
+
inner_puzzle_hash: toHex(inner),
|
|
50
|
+
is_settlement_outer: false,
|
|
51
|
+
is_settlement_inner: bytesEqual(inner, settlementHash),
|
|
52
|
+
puzzle_hash: puzzleHash,
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
const didInfo = puzzle.parseDidInfo();
|
|
56
|
+
if (didInfo) {
|
|
57
|
+
return {
|
|
58
|
+
kind: 'did',
|
|
59
|
+
launcher_id: toHex(didInfo.info.launcherId),
|
|
60
|
+
inner_puzzle_hash: toHex(didInfo.info.p2PuzzleHash),
|
|
61
|
+
is_settlement_outer: false,
|
|
62
|
+
is_settlement_inner: false,
|
|
63
|
+
puzzle_hash: puzzleHash,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
// Singleton-shaped puzzles without a recognised inner layer.
|
|
67
|
+
if (bytesEqual(puzzle.modHash, Constants.singletonTopLayerHash())) {
|
|
68
|
+
return {
|
|
69
|
+
kind: 'singleton',
|
|
70
|
+
is_settlement_outer: false,
|
|
71
|
+
is_settlement_inner: false,
|
|
72
|
+
puzzle_hash: puzzleHash,
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
return {
|
|
76
|
+
kind: 'unknown',
|
|
77
|
+
is_settlement_outer: false,
|
|
78
|
+
is_settlement_inner: false,
|
|
79
|
+
puzzle_hash: puzzleHash,
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
export function classifyPuzzle(puzzleRevealHex) {
|
|
83
|
+
const bytes = hexToBytes(stripHexPrefix(puzzleRevealHex));
|
|
84
|
+
const clvm = new Clvm();
|
|
85
|
+
const program = clvm.deserialize(bytes);
|
|
86
|
+
const c = classifyProgram(clvm, program);
|
|
87
|
+
return {
|
|
88
|
+
kind: c.kind,
|
|
89
|
+
asset_id: c.asset_id,
|
|
90
|
+
launcher_id: c.launcher_id,
|
|
91
|
+
inner_puzzle_hash: c.inner_puzzle_hash,
|
|
92
|
+
puzzle_hash: c.puzzle_hash,
|
|
93
|
+
is_settlement: c.is_settlement_outer || c.is_settlement_inner,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
function safeCall(fn) {
|
|
97
|
+
try {
|
|
98
|
+
return fn();
|
|
99
|
+
}
|
|
100
|
+
catch {
|
|
101
|
+
return null;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
export function parseConditions(puzzleRevealHex, solutionHex) {
|
|
105
|
+
const clvm = new Clvm();
|
|
106
|
+
const puzzle = clvm.deserialize(hexToBytes(stripHexPrefix(puzzleRevealHex)));
|
|
107
|
+
const solution = clvm.deserialize(hexToBytes(stripHexPrefix(solutionHex)));
|
|
108
|
+
const output = puzzle.run(solution, 11000000000n, false);
|
|
109
|
+
const conditions = output.value.toList() ?? [];
|
|
110
|
+
const create_coins = [];
|
|
111
|
+
let reserve_fee = 0n;
|
|
112
|
+
let agg_sigs_count = 0;
|
|
113
|
+
const announcements = [];
|
|
114
|
+
const asserts = [];
|
|
115
|
+
const other = [];
|
|
116
|
+
for (const cond of conditions) {
|
|
117
|
+
const cc = safeCall(() => cond.parseCreateCoin());
|
|
118
|
+
if (cc) {
|
|
119
|
+
create_coins.push({
|
|
120
|
+
puzzle_hash: toHex(cc.puzzleHash),
|
|
121
|
+
amount: cc.amount.toString(),
|
|
122
|
+
memos: memosToStrings(cc.memos),
|
|
123
|
+
});
|
|
124
|
+
continue;
|
|
125
|
+
}
|
|
126
|
+
const rf = safeCall(() => cond.parseReserveFee());
|
|
127
|
+
if (rf) {
|
|
128
|
+
reserve_fee += rf.amount;
|
|
129
|
+
continue;
|
|
130
|
+
}
|
|
131
|
+
const cca = safeCall(() => cond.parseCreateCoinAnnouncement());
|
|
132
|
+
if (cca) {
|
|
133
|
+
announcements.push({ kind: 'create_coin', message: toHex(cca.message) });
|
|
134
|
+
continue;
|
|
135
|
+
}
|
|
136
|
+
const cpa = safeCall(() => cond.parseCreatePuzzleAnnouncement());
|
|
137
|
+
if (cpa) {
|
|
138
|
+
announcements.push({ kind: 'create_puzzle', message: toHex(cpa.message) });
|
|
139
|
+
continue;
|
|
140
|
+
}
|
|
141
|
+
if (safeCall(() => cond.parseAggSigMe()) ||
|
|
142
|
+
safeCall(() => cond.parseAggSigParent()) ||
|
|
143
|
+
safeCall(() => cond.parseAggSigPuzzle()) ||
|
|
144
|
+
safeCall(() => cond.parseAggSigAmount()) ||
|
|
145
|
+
safeCall(() => cond.parseAggSigParentAmount()) ||
|
|
146
|
+
safeCall(() => cond.parseAggSigParentPuzzle()) ||
|
|
147
|
+
safeCall(() => cond.parseAggSigPuzzleAmount()) ||
|
|
148
|
+
safeCall(() => cond.parseAggSigUnsafe())) {
|
|
149
|
+
agg_sigs_count++;
|
|
150
|
+
continue;
|
|
151
|
+
}
|
|
152
|
+
const opcodeProgram = safeCall(() => cond.first());
|
|
153
|
+
const opcode = opcodeProgram?.toInt() ?? null;
|
|
154
|
+
const opcodeStr = opcode === null ? 'unknown' : opcode.toString();
|
|
155
|
+
const assertParsers = [
|
|
156
|
+
() => cond.parseAssertMyCoinId(),
|
|
157
|
+
() => cond.parseAssertMyParentId(),
|
|
158
|
+
() => cond.parseAssertMyPuzzleHash(),
|
|
159
|
+
() => cond.parseAssertMyAmount(),
|
|
160
|
+
() => cond.parseAssertCoinAnnouncement(),
|
|
161
|
+
() => cond.parseAssertPuzzleAnnouncement(),
|
|
162
|
+
() => cond.parseAssertSecondsRelative(),
|
|
163
|
+
() => cond.parseAssertSecondsAbsolute(),
|
|
164
|
+
() => cond.parseAssertHeightRelative(),
|
|
165
|
+
() => cond.parseAssertHeightAbsolute(),
|
|
166
|
+
() => cond.parseAssertBeforeSecondsRelative(),
|
|
167
|
+
() => cond.parseAssertBeforeSecondsAbsolute(),
|
|
168
|
+
() => cond.parseAssertBeforeHeightRelative(),
|
|
169
|
+
() => cond.parseAssertBeforeHeightAbsolute(),
|
|
170
|
+
];
|
|
171
|
+
let matchedAssert = false;
|
|
172
|
+
for (const p of assertParsers) {
|
|
173
|
+
if (safeCall(p)) {
|
|
174
|
+
asserts.push({ opcode: opcodeStr, data: {} });
|
|
175
|
+
matchedAssert = true;
|
|
176
|
+
break;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
if (matchedAssert)
|
|
180
|
+
continue;
|
|
181
|
+
other.push({ opcode: opcodeStr, data: {} });
|
|
182
|
+
}
|
|
183
|
+
return {
|
|
184
|
+
create_coins,
|
|
185
|
+
reserve_fee_mojo: reserve_fee.toString(),
|
|
186
|
+
agg_sigs_count,
|
|
187
|
+
announcements,
|
|
188
|
+
asserts,
|
|
189
|
+
other,
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
function extractNotarizedPayments(solution) {
|
|
193
|
+
const list = solution.toList();
|
|
194
|
+
if (!list)
|
|
195
|
+
return [];
|
|
196
|
+
const rows = [];
|
|
197
|
+
for (const item of list) {
|
|
198
|
+
const np = safeCall(() => item.parseNotarizedPayment());
|
|
199
|
+
if (!np)
|
|
200
|
+
continue;
|
|
201
|
+
const nonceHex = toHex(np.nonce);
|
|
202
|
+
for (const p of np.payments) {
|
|
203
|
+
rows.push({
|
|
204
|
+
nonce: nonceHex,
|
|
205
|
+
puzzle_hash: toHex(p.puzzleHash),
|
|
206
|
+
amount: p.amount,
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
return rows;
|
|
211
|
+
}
|
|
212
|
+
function summarizeBundle(bundle) {
|
|
213
|
+
const clvm = new Clvm();
|
|
214
|
+
const offered = [];
|
|
215
|
+
const requested = [];
|
|
216
|
+
let fee = 0n;
|
|
217
|
+
for (const cs of bundle.coinSpends) {
|
|
218
|
+
let puzzleProgram;
|
|
219
|
+
let solutionProgram;
|
|
220
|
+
try {
|
|
221
|
+
puzzleProgram = clvm.deserialize(cs.puzzleReveal);
|
|
222
|
+
solutionProgram = clvm.deserialize(cs.solution);
|
|
223
|
+
}
|
|
224
|
+
catch {
|
|
225
|
+
// Unparseable spend — record it as unknown offered and continue.
|
|
226
|
+
offered.push({
|
|
227
|
+
asset_kind: 'unknown',
|
|
228
|
+
amount_mojo: cs.coin.amount.toString(),
|
|
229
|
+
source_puzzle_hash: toHex(cs.coin.puzzleHash),
|
|
230
|
+
source_coin_id: toHex(cs.coin.coinId()),
|
|
231
|
+
});
|
|
232
|
+
continue;
|
|
233
|
+
}
|
|
234
|
+
const c = classifyProgram(clvm, puzzleProgram);
|
|
235
|
+
if (c.is_settlement_outer) {
|
|
236
|
+
// Pure XCH settlement-payments coin → requested XCH payments.
|
|
237
|
+
for (const row of extractNotarizedPayments(solutionProgram)) {
|
|
238
|
+
requested.push({
|
|
239
|
+
asset_kind: 'xch',
|
|
240
|
+
amount_mojo: row.amount.toString(),
|
|
241
|
+
amount_xch: mojoToXch(row.amount),
|
|
242
|
+
destination_puzzle_hash: row.puzzle_hash,
|
|
243
|
+
nonce: row.nonce,
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
continue;
|
|
247
|
+
}
|
|
248
|
+
if (c.is_settlement_inner) {
|
|
249
|
+
// Settlement wrapped in CAT/NFT — requested CAT or NFT side.
|
|
250
|
+
// The CAT/NFT solution contains the inner (settlement) solution as one of its members.
|
|
251
|
+
// For CAT: solution = (inner_puzzle_reveal inner_solution ...). We extract the second.
|
|
252
|
+
// For NFT: solution = (inner_solution ...). For a singleton-layer NFT the inner_solution is the first.
|
|
253
|
+
// Robust strategy: walk the solution looking for any sub-program that parses as a list of notarized payments.
|
|
254
|
+
const candidates = [];
|
|
255
|
+
const stack = [solutionProgram];
|
|
256
|
+
while (stack.length) {
|
|
257
|
+
const node = stack.pop();
|
|
258
|
+
candidates.push(node);
|
|
259
|
+
if (node.isPair()) {
|
|
260
|
+
const f = safeCall(() => node.first());
|
|
261
|
+
const r = safeCall(() => node.rest());
|
|
262
|
+
if (f)
|
|
263
|
+
stack.push(f);
|
|
264
|
+
if (r)
|
|
265
|
+
stack.push(r);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
let found = [];
|
|
269
|
+
for (const cand of candidates) {
|
|
270
|
+
const rows = extractNotarizedPayments(cand);
|
|
271
|
+
if (rows.length > 0) {
|
|
272
|
+
found = rows;
|
|
273
|
+
break;
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
for (const row of found) {
|
|
277
|
+
requested.push({
|
|
278
|
+
asset_kind: c.kind,
|
|
279
|
+
asset_id: c.asset_id,
|
|
280
|
+
nft_launcher_id: c.kind === 'nft' ? c.launcher_id : undefined,
|
|
281
|
+
amount_mojo: row.amount.toString(),
|
|
282
|
+
amount_xch: c.kind === 'xch' ? mojoToXch(row.amount) : undefined,
|
|
283
|
+
destination_puzzle_hash: row.puzzle_hash,
|
|
284
|
+
nonce: row.nonce,
|
|
285
|
+
});
|
|
286
|
+
}
|
|
287
|
+
if (found.length === 0) {
|
|
288
|
+
// Couldn't extract — still record the requested-side kind with a 0 amount placeholder
|
|
289
|
+
// so the caller knows something was requested. Use the coin's amount as a best-effort.
|
|
290
|
+
requested.push({
|
|
291
|
+
asset_kind: c.kind,
|
|
292
|
+
asset_id: c.asset_id,
|
|
293
|
+
nft_launcher_id: c.kind === 'nft' ? c.launcher_id : undefined,
|
|
294
|
+
amount_mojo: cs.coin.amount.toString(),
|
|
295
|
+
destination_puzzle_hash: toHex(cs.coin.puzzleHash),
|
|
296
|
+
nonce: '',
|
|
297
|
+
});
|
|
298
|
+
}
|
|
299
|
+
continue;
|
|
300
|
+
}
|
|
301
|
+
// Non-settlement spend → maker's offered asset.
|
|
302
|
+
offered.push({
|
|
303
|
+
asset_kind: c.kind,
|
|
304
|
+
asset_id: c.asset_id,
|
|
305
|
+
nft_launcher_id: c.kind === 'nft' ? c.launcher_id : undefined,
|
|
306
|
+
amount_mojo: cs.coin.amount.toString(),
|
|
307
|
+
amount_xch: c.kind === 'xch' ? mojoToXch(cs.coin.amount) : undefined,
|
|
308
|
+
source_puzzle_hash: toHex(cs.coin.puzzleHash),
|
|
309
|
+
source_coin_id: toHex(cs.coin.coinId()),
|
|
310
|
+
});
|
|
311
|
+
// Best-effort reserve-fee extraction from this spend's conditions.
|
|
312
|
+
try {
|
|
313
|
+
const out = puzzleProgram.run(solutionProgram, 11000000000n, false);
|
|
314
|
+
const conds = out.value.toList() ?? [];
|
|
315
|
+
for (const cond of conds) {
|
|
316
|
+
const rf = safeCall(() => cond.parseReserveFee());
|
|
317
|
+
if (rf)
|
|
318
|
+
fee += rf.amount;
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
catch {
|
|
322
|
+
// ignore — running an offer's maker spend can fail without full chain context
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
return {
|
|
326
|
+
offered,
|
|
327
|
+
requested,
|
|
328
|
+
fee_mojo: fee.toString(),
|
|
329
|
+
coin_spends_count: bundle.coinSpends.length,
|
|
330
|
+
aggregated_signature: toHex(bundle.aggregatedSignature.toBytes()),
|
|
331
|
+
};
|
|
332
|
+
}
|
|
333
|
+
export function decodeOfferString(offer) {
|
|
334
|
+
let bundle;
|
|
335
|
+
try {
|
|
336
|
+
bundle = decodeOffer(offer);
|
|
337
|
+
}
|
|
338
|
+
catch (err) {
|
|
339
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
340
|
+
throw new Error(`invalid offer string: ${msg}`, { cause: err });
|
|
341
|
+
}
|
|
342
|
+
return summarizeBundle(bundle);
|
|
343
|
+
}
|
|
344
|
+
export function summarizeSpendBundleHex(bundleHex) {
|
|
345
|
+
const bytes = hexToBytes(stripHexPrefix(bundleHex));
|
|
346
|
+
let bundle;
|
|
347
|
+
try {
|
|
348
|
+
bundle = SpendBundle.fromBytes(bytes);
|
|
349
|
+
}
|
|
350
|
+
catch (err) {
|
|
351
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
352
|
+
throw new Error(`invalid spend bundle hex: ${msg}`, { cause: err });
|
|
353
|
+
}
|
|
354
|
+
return summarizeBundle(bundle);
|
|
355
|
+
}
|
|
356
|
+
//# sourceMappingURL=offer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"offer.js","sourceRoot":"","sources":["../../src/chia/offer.ts"],"names":[],"mappings":"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"}
|