@dignetwork/chia-block-listener 0.1.6 → 0.1.8
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/.github/workflows/CI.yml +42 -10
- package/README.md +286 -242
- package/index.d.ts +0 -16
- package/npm/darwin-arm64/package.json +1 -1
- package/npm/darwin-x64/package.json +1 -1
- package/npm/linux-arm64-gnu/package.json +1 -1
- package/npm/linux-x64-gnu/package.json +1 -1
- package/npm/win32-x64-msvc/package.json +1 -1
- package/package.json +6 -6
- package/scripts/post-build.js +15 -1
- package/src/event_emitter.rs +31 -29
package/.github/workflows/CI.yml
CHANGED
|
@@ -53,19 +53,20 @@ jobs:
|
|
|
53
53
|
settings:
|
|
54
54
|
- host: macos-latest
|
|
55
55
|
target: x86_64-apple-darwin
|
|
56
|
-
build: npm run build -- --target x86_64-apple-darwin
|
|
56
|
+
build: npm run build -- --target x86_64-apple-darwin && node scripts/post-build.js
|
|
57
57
|
- host: windows-latest
|
|
58
|
-
build: npm run build -- --target x86_64-pc-windows-msvc
|
|
58
|
+
build: npm run build -- --target x86_64-pc-windows-msvc && node scripts/post-build.js
|
|
59
59
|
target: x86_64-pc-windows-msvc
|
|
60
60
|
- host: ubuntu-latest
|
|
61
61
|
target: x86_64-unknown-linux-gnu
|
|
62
62
|
build: |
|
|
63
63
|
set -e &&
|
|
64
64
|
npm run build -- --target x86_64-unknown-linux-gnu &&
|
|
65
|
+
node scripts/post-build.js &&
|
|
65
66
|
strip *.node
|
|
66
67
|
- host: macos-latest
|
|
67
68
|
target: aarch64-apple-darwin
|
|
68
|
-
build: npm run build -- --target aarch64-apple-darwin
|
|
69
|
+
build: npm run build -- --target aarch64-apple-darwin && node scripts/post-build.js
|
|
69
70
|
- host: ubuntu-latest
|
|
70
71
|
target: aarch64-unknown-linux-gnu
|
|
71
72
|
setup: |
|
|
@@ -74,7 +75,8 @@ jobs:
|
|
|
74
75
|
build: |
|
|
75
76
|
set -e &&
|
|
76
77
|
export CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER=aarch64-linux-gnu-gcc &&
|
|
77
|
-
npm run build -- --target aarch64-unknown-linux-gnu
|
|
78
|
+
npm run build -- --target aarch64-unknown-linux-gnu &&
|
|
79
|
+
node scripts/post-build.js
|
|
78
80
|
name: stable - ${{ matrix.settings.target }} - node@22
|
|
79
81
|
runs-on: ${{ matrix.settings.host }}
|
|
80
82
|
steps:
|
|
@@ -191,7 +193,7 @@ jobs:
|
|
|
191
193
|
node:
|
|
192
194
|
- '20'
|
|
193
195
|
- '22'
|
|
194
|
-
runs-on: ubuntu-
|
|
196
|
+
runs-on: ubuntu-24.04
|
|
195
197
|
steps:
|
|
196
198
|
- uses: actions/checkout@v4
|
|
197
199
|
- name: Setup node
|
|
@@ -250,18 +252,48 @@ jobs:
|
|
|
250
252
|
uses: addnab/docker-run-action@v3
|
|
251
253
|
with:
|
|
252
254
|
image: ubuntu:24.04
|
|
253
|
-
options: '--platform linux/arm64 -v ${{ github.workspace }}:/
|
|
255
|
+
options: '--platform linux/arm64 -v ${{ github.workspace }}:/workspace -w /workspace'
|
|
254
256
|
run: |
|
|
255
257
|
set -e
|
|
258
|
+
export DEBIAN_FRONTEND=noninteractive
|
|
256
259
|
apt-get update
|
|
257
|
-
apt-get install -y curl
|
|
258
|
-
|
|
259
|
-
|
|
260
|
+
apt-get install -y curl ca-certificates xz-utils
|
|
261
|
+
|
|
262
|
+
# Install Node.js using a different approach - download pre-built binary directly
|
|
263
|
+
NODE_VERSION="${{ matrix.node }}"
|
|
264
|
+
case "$NODE_VERSION" in
|
|
265
|
+
"20")
|
|
266
|
+
FULL_VERSION="20.18.0"
|
|
267
|
+
;;
|
|
268
|
+
"22")
|
|
269
|
+
FULL_VERSION="22.11.0" # Use slightly older version of 22 for stability
|
|
270
|
+
;;
|
|
271
|
+
*)
|
|
272
|
+
echo "Unsupported Node version: $NODE_VERSION"
|
|
273
|
+
exit 1
|
|
274
|
+
;;
|
|
275
|
+
esac
|
|
276
|
+
|
|
277
|
+
# Download and install Node.js binary
|
|
278
|
+
cd /tmp
|
|
279
|
+
curl -fsSL "https://nodejs.org/dist/v${FULL_VERSION}/node-v${FULL_VERSION}-linux-arm64.tar.xz" -o node.tar.xz
|
|
280
|
+
tar -xf node.tar.xz
|
|
281
|
+
cp -r "node-v${FULL_VERSION}-linux-arm64"/* /usr/local/
|
|
282
|
+
rm -rf node.tar.xz "node-v${FULL_VERSION}-linux-arm64"
|
|
283
|
+
|
|
284
|
+
# Return to workspace
|
|
285
|
+
cd /workspace
|
|
286
|
+
|
|
287
|
+
# Verify we're in the right directory and have the required files
|
|
288
|
+
pwd
|
|
289
|
+
ls -la
|
|
290
|
+
echo "Looking for package-lock.json:"
|
|
291
|
+
ls -la package-lock.json || echo "package-lock.json not found"
|
|
292
|
+
|
|
260
293
|
node --version
|
|
261
294
|
npm --version
|
|
262
295
|
npm ci
|
|
263
296
|
npm test
|
|
264
|
-
ls -la
|
|
265
297
|
|
|
266
298
|
publish:
|
|
267
299
|
name: Publish
|
package/README.md
CHANGED
|
@@ -1,22 +1,17 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Chia Block Listener
|
|
2
2
|
|
|
3
|
-
A high-performance
|
|
3
|
+
A high-performance Chia blockchain listener for Node.js, built with Rust and NAPI bindings. This library provides real-time monitoring of the Chia blockchain with efficient peer connections and block parsing capabilities.
|
|
4
4
|
|
|
5
5
|
## Features
|
|
6
6
|
|
|
7
|
-
- **
|
|
8
|
-
- **
|
|
9
|
-
- **
|
|
10
|
-
- **
|
|
11
|
-
- **
|
|
12
|
-
- **
|
|
13
|
-
- **
|
|
14
|
-
- **
|
|
15
|
-
- **Difficulty Analysis**: Calculate difficulty levels from hash values
|
|
16
|
-
- **Security Features**: Tamper-resistant verification with algorithm immutability
|
|
17
|
-
- **Cross-platform Support**: Builds for Windows, macOS, and Linux
|
|
18
|
-
- **Multiple Architectures**: Supports x64 and ARM64 architectures
|
|
19
|
-
- **TypeScript Support**: Full TypeScript definitions included
|
|
7
|
+
- **Real-time Block Monitoring**: Listen for new blocks as they're produced on the Chia network
|
|
8
|
+
- **Peer Management**: Connect to multiple Chia full nodes simultaneously
|
|
9
|
+
- **Efficient Parsing**: Fast extraction of coin spends, additions, and removals from blocks
|
|
10
|
+
- **Event-Driven Architecture**: TypeScript-friendly event system with full type safety
|
|
11
|
+
- **Transaction Analysis**: Parse CLVM puzzles and solutions from coin spends
|
|
12
|
+
- **Historical Block Access**: Retrieve blocks by height or ranges
|
|
13
|
+
- **Cross-platform Support**: Works on Windows, macOS, and Linux (x64 and ARM64)
|
|
14
|
+
- **TypeScript Support**: Complete TypeScript definitions with IntelliSense
|
|
20
15
|
|
|
21
16
|
## Installation
|
|
22
17
|
|
|
@@ -27,311 +22,348 @@ npm install @dignetwork/chia-block-listener
|
|
|
27
22
|
## Quick Start
|
|
28
23
|
|
|
29
24
|
```javascript
|
|
30
|
-
const {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
})
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
25
|
+
const { ChiaBlockListener, initTracing } = require('@dignetwork/chia-block-listener')
|
|
26
|
+
|
|
27
|
+
// Initialize tracing for debugging (optional)
|
|
28
|
+
initTracing()
|
|
29
|
+
|
|
30
|
+
// Create a new listener instance
|
|
31
|
+
const listener = new ChiaBlockListener()
|
|
32
|
+
|
|
33
|
+
// Listen for block events
|
|
34
|
+
listener.on('blockReceived', (block) => {
|
|
35
|
+
console.log(`New block received: ${block.height}`)
|
|
36
|
+
console.log(`Header hash: ${block.header_hash}`)
|
|
37
|
+
console.log(`Timestamp: ${new Date(block.timestamp * 1000)}`)
|
|
38
|
+
console.log(`Coin additions: ${block.coin_additions.length}`)
|
|
39
|
+
console.log(`Coin removals: ${block.coin_removals.length}`)
|
|
40
|
+
console.log(`Coin spends: ${block.coin_spends.length}`)
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
// Listen for peer connection events
|
|
44
|
+
listener.on('peerConnected', (peer) => {
|
|
45
|
+
console.log(`Connected to peer: ${peer.peerId} (${peer.host}:${peer.port})`)
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
listener.on('peerDisconnected', (peer) => {
|
|
49
|
+
console.log(`Disconnected from peer: ${peer.peerId}`)
|
|
50
|
+
if (peer.message) {
|
|
51
|
+
console.log(`Reason: ${peer.message}`)
|
|
50
52
|
}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
mine().catch(console.error)
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
// Connect to a Chia full node
|
|
56
|
+
const peerId = listener.addPeer('localhost', 8444, 'mainnet')
|
|
57
|
+
console.log(`Added peer: ${peerId}`)
|
|
58
|
+
|
|
59
|
+
// Keep the process running
|
|
60
|
+
process.on('SIGINT', () => {
|
|
61
|
+
console.log('Shutting down...')
|
|
62
|
+
listener.disconnectAllPeers()
|
|
63
|
+
process.exit(0)
|
|
64
|
+
})
|
|
65
65
|
```
|
|
66
66
|
|
|
67
67
|
## API Reference
|
|
68
68
|
|
|
69
|
-
###
|
|
69
|
+
### ChiaBlockListener Class
|
|
70
70
|
|
|
71
|
-
####
|
|
71
|
+
#### Constructor
|
|
72
72
|
|
|
73
|
-
|
|
73
|
+
```javascript
|
|
74
|
+
const listener = new ChiaBlockListener()
|
|
75
|
+
```
|
|
74
76
|
|
|
75
|
-
|
|
76
|
-
- `entropySeed` (Buffer): The entropy seed (plotId) to bind the work to
|
|
77
|
-
- `difficulty` (number): Bitcoin-style difficulty level (1.0 = easiest, higher = harder)
|
|
78
|
-
- `maxAttempts` (number, optional): Maximum attempts before giving up (default: unlimited)
|
|
79
|
-
- `logAttempts` (boolean, optional): Whether to log each hash attempt (default: false)
|
|
80
|
-
- `doubleSha` (boolean, optional): Whether to use double SHA-256 like Bitcoin (default: true)
|
|
77
|
+
Creates a new Chia block listener instance.
|
|
81
78
|
|
|
82
|
-
|
|
79
|
+
#### Methods
|
|
83
80
|
|
|
84
|
-
|
|
81
|
+
##### `addPeer(host, port, networkId): string`
|
|
85
82
|
|
|
86
|
-
|
|
83
|
+
Connects to a Chia full node and starts listening for blocks.
|
|
87
84
|
|
|
88
85
|
**Parameters:**
|
|
89
|
-
- `
|
|
90
|
-
- `
|
|
91
|
-
- `
|
|
92
|
-
- `doubleSha` (boolean, optional): Whether to use double SHA-256 (default: true)
|
|
86
|
+
- `host` (string): The hostname or IP address of the Chia node
|
|
87
|
+
- `port` (number): The port number (typically 8444 for mainnet)
|
|
88
|
+
- `networkId` (string): The network identifier ('mainnet', 'testnet', etc.)
|
|
93
89
|
|
|
94
|
-
**Returns:**
|
|
90
|
+
**Returns:** A unique peer ID string for this connection
|
|
95
91
|
|
|
96
|
-
|
|
92
|
+
##### `disconnectPeer(peerId): boolean`
|
|
97
93
|
|
|
98
|
-
|
|
94
|
+
Disconnects from a specific peer.
|
|
99
95
|
|
|
100
96
|
**Parameters:**
|
|
101
|
-
- `
|
|
102
|
-
- `nonce` (number): The nonce to verify
|
|
103
|
-
- `difficulty` (number): The required difficulty level
|
|
104
|
-
- `expectedVersion` (number, optional): Expected algorithm version (default: current)
|
|
105
|
-
- `doubleSha` (boolean, optional): Whether to use double SHA-256 (default: true)
|
|
97
|
+
- `peerId` (string): The peer ID returned by `addPeer()`
|
|
106
98
|
|
|
107
|
-
**Returns:** `true` if the
|
|
99
|
+
**Returns:** `true` if the peer was successfully disconnected, `false` otherwise
|
|
108
100
|
|
|
109
|
-
|
|
101
|
+
##### `disconnectAllPeers(): void`
|
|
110
102
|
|
|
111
|
-
|
|
103
|
+
Disconnects from all connected peers.
|
|
112
104
|
|
|
113
|
-
|
|
105
|
+
##### `getConnectedPeers(): string[]`
|
|
114
106
|
|
|
115
|
-
|
|
107
|
+
Returns an array of currently connected peer IDs.
|
|
116
108
|
|
|
117
|
-
|
|
118
|
-
- `difficulty` (number): The difficulty level
|
|
109
|
+
##### `getBlockByHeight(peerId, height): BlockReceivedEvent`
|
|
119
110
|
|
|
120
|
-
|
|
111
|
+
Retrieves a specific block by its height from a connected peer.
|
|
121
112
|
|
|
122
|
-
|
|
113
|
+
**Parameters:**
|
|
114
|
+
- `peerId` (string): The peer ID to query
|
|
115
|
+
- `height` (number): The block height to retrieve
|
|
123
116
|
|
|
124
|
-
|
|
117
|
+
**Returns:** A `BlockReceivedEvent` object containing the block data
|
|
125
118
|
|
|
126
|
-
|
|
127
|
-
- `hash` (Buffer): The hash to analyze (32 bytes)
|
|
119
|
+
##### `getBlocksRange(peerId, startHeight, endHeight): BlockReceivedEvent[]`
|
|
128
120
|
|
|
129
|
-
|
|
121
|
+
Retrieves a range of blocks from a connected peer.
|
|
130
122
|
|
|
131
|
-
|
|
123
|
+
**Parameters:**
|
|
124
|
+
- `peerId` (string): The peer ID to query
|
|
125
|
+
- `startHeight` (number): The starting block height (inclusive)
|
|
126
|
+
- `endHeight` (number): The ending block height (inclusive)
|
|
132
127
|
|
|
133
|
-
|
|
128
|
+
**Returns:** An array of `BlockReceivedEvent` objects
|
|
134
129
|
|
|
135
|
-
|
|
130
|
+
### Events
|
|
136
131
|
|
|
137
|
-
|
|
132
|
+
The `ChiaBlockListener` emits the following events:
|
|
138
133
|
|
|
139
|
-
#### `
|
|
134
|
+
#### `blockReceived`
|
|
140
135
|
|
|
141
|
-
|
|
136
|
+
Fired when a new block is received from any connected peer.
|
|
142
137
|
|
|
143
|
-
**
|
|
138
|
+
**Callback:** `(event: BlockReceivedEvent) => void`
|
|
144
139
|
|
|
145
|
-
#### `
|
|
140
|
+
#### `peerConnected`
|
|
146
141
|
|
|
147
|
-
|
|
142
|
+
Fired when a connection to a peer is established.
|
|
148
143
|
|
|
149
|
-
**
|
|
150
|
-
- `version` (number): Algorithm version number
|
|
151
|
-
- `specHash` (string): Algorithm specification hash
|
|
152
|
-
- `baseZeroBits` (number): Base number of zero bits for difficulty 1.0
|
|
153
|
-
- `logMultiplier` (number): Logarithmic multiplier for difficulty scaling
|
|
154
|
-
- `maxZeroBits` (number): Maximum allowed zero bits
|
|
144
|
+
**Callback:** `(event: PeerConnectedEvent) => void`
|
|
155
145
|
|
|
156
|
-
|
|
146
|
+
#### `peerDisconnected`
|
|
157
147
|
|
|
158
|
-
|
|
148
|
+
Fired when a peer connection is lost.
|
|
159
149
|
|
|
160
|
-
|
|
161
|
-
Cancels the running proof of work computation.
|
|
150
|
+
**Callback:** `(event: PeerDisconnectedEvent) => void`
|
|
162
151
|
|
|
163
|
-
|
|
164
|
-
Returns `true` if the computation has been cancelled.
|
|
152
|
+
### Event Data Types
|
|
165
153
|
|
|
166
|
-
#### `
|
|
167
|
-
Returns `true` if the computation has found a valid solution.
|
|
154
|
+
#### `BlockReceivedEvent`
|
|
168
155
|
|
|
169
|
-
|
|
170
|
-
|
|
156
|
+
```typescript
|
|
157
|
+
interface BlockReceivedEvent {
|
|
158
|
+
peerId: string // IP address of the peer that sent this block
|
|
159
|
+
height: number // Block height
|
|
160
|
+
weight: string // Block weight as string
|
|
161
|
+
headerHash: string // Block header hash (hex)
|
|
162
|
+
timestamp: number // Block timestamp (Unix time)
|
|
163
|
+
coinAdditions: CoinRecord[] // New coins created in this block
|
|
164
|
+
coinRemovals: CoinRecord[] // Coins spent in this block
|
|
165
|
+
coinSpends: CoinSpend[] // Detailed spend information
|
|
166
|
+
coinCreations: CoinRecord[] // Coins created by puzzles
|
|
167
|
+
hasTransactionsGenerator: boolean // Whether block has a generator
|
|
168
|
+
generatorSize: number // Size of the generator bytecode
|
|
169
|
+
}
|
|
170
|
+
```
|
|
171
171
|
|
|
172
|
-
#### `
|
|
173
|
-
Returns the error message if there was an error, or `null` if no error.
|
|
172
|
+
#### `PeerConnectedEvent`
|
|
174
173
|
|
|
175
|
-
|
|
176
|
-
|
|
174
|
+
```typescript
|
|
175
|
+
interface PeerConnectedEvent {
|
|
176
|
+
peerId: string // Peer IP address
|
|
177
|
+
host: string // Peer hostname/IP
|
|
178
|
+
port: number // Peer port number
|
|
179
|
+
}
|
|
180
|
+
```
|
|
177
181
|
|
|
178
|
-
#### `
|
|
179
|
-
Returns the current number of attempts made (approximate).
|
|
182
|
+
#### `PeerDisconnectedEvent`
|
|
180
183
|
|
|
181
|
-
|
|
182
|
-
|
|
184
|
+
```typescript
|
|
185
|
+
interface PeerDisconnectedEvent {
|
|
186
|
+
peerId: string // Peer IP address
|
|
187
|
+
host: string // Peer hostname/IP
|
|
188
|
+
port: number // Peer port number
|
|
189
|
+
message?: string // Optional disconnection reason
|
|
190
|
+
}
|
|
191
|
+
```
|
|
183
192
|
|
|
184
|
-
#### `
|
|
185
|
-
Returns the difficulty level for this computation.
|
|
193
|
+
#### `CoinRecord`
|
|
186
194
|
|
|
187
|
-
|
|
195
|
+
```typescript
|
|
196
|
+
interface CoinRecord {
|
|
197
|
+
parentCoinInfo: string // Parent coin ID (hex)
|
|
198
|
+
puzzleHash: string // Puzzle hash (hex)
|
|
199
|
+
amount: string // Coin amount as string
|
|
200
|
+
}
|
|
201
|
+
```
|
|
188
202
|
|
|
189
|
-
#### `
|
|
190
|
-
- `nonce` (bigint): The nonce that was found
|
|
191
|
-
- `hash` (string): The resulting hash as hex string
|
|
192
|
-
- `attempts` (bigint): Number of attempts made
|
|
193
|
-
- `time_ms` (number): Time taken in milliseconds
|
|
194
|
-
- `difficulty` (number): The difficulty that was satisfied
|
|
195
|
-
- `target` (string): The target that was used (as hex string)
|
|
203
|
+
#### `CoinSpend`
|
|
196
204
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
205
|
+
```typescript
|
|
206
|
+
interface CoinSpend {
|
|
207
|
+
coin: CoinRecord // The coin being spent
|
|
208
|
+
puzzleReveal: string // CLVM puzzle bytecode (hex)
|
|
209
|
+
solution: string // CLVM solution bytecode (hex)
|
|
210
|
+
offset: number // Offset in the generator bytecode
|
|
211
|
+
}
|
|
212
|
+
```
|
|
202
213
|
|
|
203
214
|
## TypeScript Usage
|
|
204
215
|
|
|
205
216
|
```typescript
|
|
206
217
|
import {
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
AlgorithmParameters
|
|
218
|
+
ChiaBlockListener,
|
|
219
|
+
BlockReceivedEvent,
|
|
220
|
+
PeerConnectedEvent,
|
|
221
|
+
PeerDisconnectedEvent,
|
|
222
|
+
CoinRecord,
|
|
223
|
+
CoinSpend,
|
|
224
|
+
initTracing,
|
|
225
|
+
getEventTypes
|
|
216
226
|
} from '@dignetwork/chia-block-listener'
|
|
217
227
|
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
228
|
+
// Initialize tracing for debugging
|
|
229
|
+
initTracing()
|
|
230
|
+
|
|
231
|
+
// Create listener with proper typing
|
|
232
|
+
const listener = new ChiaBlockListener()
|
|
233
|
+
|
|
234
|
+
// Type-safe event handlers
|
|
235
|
+
listener.on('blockReceived', (block: BlockReceivedEvent) => {
|
|
236
|
+
console.log(`Block ${block.height} from peer ${block.peerId}`)
|
|
221
237
|
|
|
222
|
-
|
|
238
|
+
// Process coin additions
|
|
239
|
+
block.coin_additions.forEach((coin: CoinRecord) => {
|
|
240
|
+
console.log(`New coin: ${coin.amount} mojos`)
|
|
241
|
+
})
|
|
223
242
|
|
|
224
|
-
//
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
243
|
+
// Process coin spends
|
|
244
|
+
block.coin_spends.forEach((spend: CoinSpend) => {
|
|
245
|
+
console.log(`Spend: ${spend.coin.amount} mojos`)
|
|
246
|
+
console.log(`Puzzle: ${spend.puzzle_reveal}`)
|
|
247
|
+
console.log(`Solution: ${spend.solution}`)
|
|
248
|
+
})
|
|
249
|
+
})
|
|
250
|
+
|
|
251
|
+
listener.on('peerConnected', (peer: PeerConnectedEvent) => {
|
|
252
|
+
console.log(`Connected: ${peer.peerId} at ${peer.host}:${peer.port}`)
|
|
253
|
+
})
|
|
254
|
+
|
|
255
|
+
listener.on('peerDisconnected', (peer: PeerDisconnectedEvent) => {
|
|
256
|
+
console.log(`Disconnected: ${peer.peerId}`)
|
|
257
|
+
if (peer.message) {
|
|
258
|
+
console.log(`Reason: ${peer.message}`)
|
|
259
|
+
}
|
|
260
|
+
})
|
|
261
|
+
|
|
262
|
+
// Connect to peers
|
|
263
|
+
const mainnetPeer = listener.addPeer('localhost', 8444, 'mainnet')
|
|
264
|
+
const testnetPeer = listener.addPeer('testnet-node.chia.net', 58444, 'testnet')
|
|
265
|
+
|
|
266
|
+
// Get historical blocks
|
|
267
|
+
async function getHistoricalBlocks() {
|
|
268
|
+
try {
|
|
269
|
+
const block = listener.getBlockByHeight(mainnetPeer, 1000000)
|
|
270
|
+
console.log(`Block 1000000 hash: ${block.header_hash}`)
|
|
238
271
|
|
|
239
|
-
|
|
272
|
+
const blocks = listener.getBlocksRange(mainnetPeer, 1000000, 1000010)
|
|
273
|
+
console.log(`Retrieved ${blocks.length} blocks`)
|
|
274
|
+
} catch (error) {
|
|
275
|
+
console.error('Error getting blocks:', error)
|
|
240
276
|
}
|
|
241
|
-
|
|
242
|
-
const result: ProofOfWorkResult = await waitForCompletion(handle)
|
|
243
|
-
|
|
244
|
-
// Standard verification
|
|
245
|
-
const isValid: boolean = verifyProofOfWork(
|
|
246
|
-
entropySeed,
|
|
247
|
-
Number(result.nonce),
|
|
248
|
-
difficulty
|
|
249
|
-
)
|
|
250
|
-
|
|
251
|
-
// Standardized verification (recommended for networks)
|
|
252
|
-
const isStandardValid: boolean = verifyProofOfWorkStandardized(
|
|
253
|
-
entropySeed,
|
|
254
|
-
Number(result.nonce),
|
|
255
|
-
difficulty
|
|
256
|
-
)
|
|
257
|
-
|
|
258
|
-
// Check algorithm parameters
|
|
259
|
-
const params: AlgorithmParameters = getAlgorithmParameters()
|
|
260
|
-
console.log(`Algorithm version: ${params.version}`)
|
|
261
|
-
console.log(`Algorithm spec: ${params.specHash}`)
|
|
262
|
-
|
|
263
|
-
console.log('Mining completed, valid:', isValid)
|
|
264
|
-
console.log('Consensus valid:', isStandardValid)
|
|
265
277
|
}
|
|
266
|
-
```
|
|
267
278
|
|
|
268
|
-
|
|
279
|
+
// Get event type constants
|
|
280
|
+
const eventTypes = getEventTypes()
|
|
281
|
+
console.log('Available events:', eventTypes)
|
|
282
|
+
```
|
|
269
283
|
|
|
270
|
-
|
|
284
|
+
## Advanced Usage
|
|
271
285
|
|
|
272
|
-
|
|
273
|
-
- **Difficulty 2.0**: Requires 12 leading zero bits
|
|
274
|
-
- **Difficulty 4.0**: Requires 16 leading zero bits (2 zero bytes)
|
|
275
|
-
- **Higher difficulties**: Exponentially more difficult
|
|
286
|
+
### Monitoring Specific Transactions
|
|
276
287
|
|
|
277
|
-
|
|
288
|
+
```javascript
|
|
289
|
+
// Monitor all coin spends for a specific puzzle hash
|
|
290
|
+
listener.on('blockReceived', (block) => {
|
|
291
|
+
const targetPuzzleHash = '0x1234...' // Your puzzle hash
|
|
292
|
+
|
|
293
|
+
block.coin_spends.forEach((spend) => {
|
|
294
|
+
if (spend.coin.puzzle_hash === targetPuzzleHash) {
|
|
295
|
+
console.log('Found spend for our puzzle!')
|
|
296
|
+
console.log('Amount:', spend.coin.amount)
|
|
297
|
+
console.log('Solution:', spend.solution)
|
|
298
|
+
}
|
|
299
|
+
})
|
|
300
|
+
})
|
|
301
|
+
```
|
|
278
302
|
|
|
279
|
-
|
|
303
|
+
### Multiple Network Monitoring
|
|
280
304
|
|
|
281
|
-
|
|
305
|
+
```javascript
|
|
306
|
+
// Monitor both mainnet and testnet
|
|
307
|
+
const mainnetPeer = listener.addPeer('localhost', 8444, 'mainnet')
|
|
308
|
+
const testnetPeer = listener.addPeer('localhost', 58444, 'testnet')
|
|
309
|
+
|
|
310
|
+
listener.on('blockReceived', (block) => {
|
|
311
|
+
if (block.peerId === mainnetPeer) {
|
|
312
|
+
console.log(`Mainnet block ${block.height}`)
|
|
313
|
+
} else if (block.peerId === testnetPeer) {
|
|
314
|
+
console.log(`Testnet block ${block.height}`)
|
|
315
|
+
}
|
|
316
|
+
})
|
|
317
|
+
```
|
|
282
318
|
|
|
283
|
-
###
|
|
319
|
+
### Connection Management
|
|
284
320
|
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
321
|
+
```javascript
|
|
322
|
+
// Automatic reconnection
|
|
323
|
+
listener.on('peerDisconnected', (peer) => {
|
|
324
|
+
console.log(`Lost connection to ${peer.peerId}, reconnecting...`)
|
|
325
|
+
|
|
326
|
+
// Reconnect after 5 seconds
|
|
327
|
+
setTimeout(() => {
|
|
328
|
+
try {
|
|
329
|
+
listener.addPeer(peer.host, peer.port, 'mainnet')
|
|
330
|
+
console.log('Reconnected successfully')
|
|
331
|
+
} catch (error) {
|
|
332
|
+
console.error('Reconnection failed:', error)
|
|
333
|
+
}
|
|
334
|
+
}, 5000)
|
|
335
|
+
})
|
|
336
|
+
```
|
|
289
337
|
|
|
290
|
-
|
|
338
|
+
## Utility Functions
|
|
291
339
|
|
|
292
|
-
|
|
293
|
-
2. **Version Enforcement**: Mismatched versions are rejected automatically
|
|
294
|
-
3. **Consensus Compliance**: All parameters are immutable constants
|
|
295
|
-
4. **Network Compatibility**: Ensures identical verification across nodes
|
|
296
|
-
5. **Upgrade Safety**: Algorithm changes require coordinated hard forks
|
|
340
|
+
### `initTracing(): void`
|
|
297
341
|
|
|
298
|
-
|
|
342
|
+
Initializes the Rust tracing system for debugging purposes. Call this before creating any `ChiaBlockListener` instances if you want to see debug output.
|
|
299
343
|
|
|
300
|
-
|
|
301
|
-
// For production networks: Always use standardized verification
|
|
302
|
-
const isValid = verifyProofOfWorkStandardized(entropySeed, nonce, difficulty)
|
|
344
|
+
### `getEventTypes(): EventTypes`
|
|
303
345
|
|
|
304
|
-
|
|
305
|
-
const version = getAlgorithmVersion() // Returns: 1
|
|
306
|
-
const spec = getAlgorithmSpec() // Returns: "DIG_POW_V1_SMOOTH_LOG_DIFFICULTY_2024"
|
|
346
|
+
Returns an object containing the event type constants:
|
|
307
347
|
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
}
|
|
348
|
+
```javascript
|
|
349
|
+
const eventTypes = getEventTypes()
|
|
350
|
+
console.log(eventTypes)
|
|
351
|
+
// Output: { blockReceived: "blockReceived", peerConnected: "peerConnected", peerDisconnected: "peerDisconnected" }
|
|
312
352
|
```
|
|
313
353
|
|
|
314
|
-
### Network Upgrade Process
|
|
315
|
-
|
|
316
|
-
To change the difficulty algorithm:
|
|
317
|
-
1. Define new algorithm version (e.g., version 2)
|
|
318
|
-
2. Update consensus parameters and spec hash
|
|
319
|
-
3. Coordinate hard fork across all network participants
|
|
320
|
-
4. Validate version compatibility on peer connections
|
|
321
|
-
|
|
322
354
|
## Performance Tips
|
|
323
355
|
|
|
324
|
-
1. **Use
|
|
325
|
-
2. **
|
|
326
|
-
3. **
|
|
327
|
-
4. **Handle
|
|
356
|
+
1. **Use specific event handlers**: Only listen for the events you need
|
|
357
|
+
2. **Process blocks efficiently**: Avoid heavy computation in event handlers
|
|
358
|
+
3. **Manage connections**: Don't create too many peer connections simultaneously
|
|
359
|
+
4. **Handle errors gracefully**: Always wrap peer operations in try-catch blocks
|
|
328
360
|
|
|
329
361
|
## Development
|
|
330
362
|
|
|
331
363
|
### Prerequisites
|
|
332
364
|
|
|
333
365
|
- [Rust](https://rustup.rs/) (latest stable)
|
|
334
|
-
- [Node.js](https://nodejs.org/) (
|
|
366
|
+
- [Node.js](https://nodejs.org/) (20 or later)
|
|
335
367
|
- [npm](https://www.npmjs.com/)
|
|
336
368
|
|
|
337
369
|
### Setup
|
|
@@ -353,15 +385,20 @@ npm test
|
|
|
353
385
|
|
|
354
386
|
```
|
|
355
387
|
chia-block-listener/
|
|
356
|
-
├── src/
|
|
357
|
-
│
|
|
358
|
-
├──
|
|
359
|
-
│
|
|
360
|
-
├──
|
|
361
|
-
|
|
362
|
-
├──
|
|
363
|
-
|
|
364
|
-
|
|
388
|
+
├── src/ # Rust source code
|
|
389
|
+
│ ├── lib.rs # Main NAPI bindings
|
|
390
|
+
│ ├── peer.rs # Peer connection management
|
|
391
|
+
│ ├── protocol.rs # Chia protocol implementation
|
|
392
|
+
│ ├── event_emitter.rs # Event system
|
|
393
|
+
│ └── tls.rs # TLS connection handling
|
|
394
|
+
├── crate/ # Additional Rust crates
|
|
395
|
+
│ └── chia-generator-parser/ # CLVM parser
|
|
396
|
+
├── __test__/ # Test suite
|
|
397
|
+
├── npm/ # Platform-specific binaries
|
|
398
|
+
├── .github/workflows/ # CI/CD pipeline
|
|
399
|
+
├── Cargo.toml # Rust configuration
|
|
400
|
+
├── package.json # Node.js configuration
|
|
401
|
+
└── index.d.ts # TypeScript definitions
|
|
365
402
|
```
|
|
366
403
|
|
|
367
404
|
## CI/CD & Publishing
|
|
@@ -369,8 +406,8 @@ chia-block-listener/
|
|
|
369
406
|
This project uses GitHub Actions for:
|
|
370
407
|
- Cross-platform builds (Windows, macOS, Linux)
|
|
371
408
|
- Multiple architectures (x64, ARM64)
|
|
372
|
-
- Automated testing
|
|
373
|
-
- npm publishing based on
|
|
409
|
+
- Automated testing on all platforms
|
|
410
|
+
- npm publishing based on git tags
|
|
374
411
|
|
|
375
412
|
## License
|
|
376
413
|
|
|
@@ -385,3 +422,10 @@ MIT
|
|
|
385
422
|
5. Commit your changes (`git commit -m 'Add some amazing feature'`)
|
|
386
423
|
6. Push to the branch (`git push origin feature/amazing-feature`)
|
|
387
424
|
7. Open a Pull Request
|
|
425
|
+
|
|
426
|
+
## Support
|
|
427
|
+
|
|
428
|
+
For issues and questions:
|
|
429
|
+
- GitHub Issues: [Report bugs or request features](https://github.com/DIG-Network/chia-block-listener/issues)
|
|
430
|
+
- Documentation: Check the TypeScript definitions in `index.d.ts`
|
|
431
|
+
- Examples: See the `examples/` directory for more usage examples
|
package/index.d.ts
CHANGED
|
@@ -42,8 +42,6 @@ export interface CoinSpend {
|
|
|
42
42
|
coin: CoinRecord
|
|
43
43
|
puzzleReveal: string
|
|
44
44
|
solution: string
|
|
45
|
-
realData: boolean
|
|
46
|
-
parsingMethod: string
|
|
47
45
|
offset: number
|
|
48
46
|
}
|
|
49
47
|
export declare function initTracing(): void
|
|
@@ -53,21 +51,7 @@ export declare class ChiaBlockListener {
|
|
|
53
51
|
disconnectPeer(peerId: string): boolean
|
|
54
52
|
disconnectAllPeers(): void
|
|
55
53
|
getConnectedPeers(): Array<string>
|
|
56
|
-
// Typed event method overloads
|
|
57
|
-
|
|
58
|
-
on(event: 'blockReceived', callback: (event: BlockReceivedEvent) => void): void
|
|
59
|
-
|
|
60
|
-
on(event: 'peerConnected', callback: (event: PeerConnectedEvent) => void): void
|
|
61
|
-
|
|
62
|
-
on(event: 'peerDisconnected', callback: (event: PeerDisconnectedEvent) => void): void
|
|
63
|
-
|
|
64
54
|
on(event: string, callback: (...args: any[]) => any): void
|
|
65
|
-
off(event: 'blockReceived', callback: (event: BlockReceivedEvent) => void): void
|
|
66
|
-
|
|
67
|
-
off(event: 'peerConnected', callback: (event: PeerConnectedEvent) => void): void
|
|
68
|
-
|
|
69
|
-
off(event: 'peerDisconnected', callback: (event: PeerDisconnectedEvent) => void): void
|
|
70
|
-
|
|
71
55
|
off(event: string, callback: (...args: any[]) => any): void
|
|
72
56
|
getBlockByHeight(peerId: string, height: number): BlockReceivedEvent
|
|
73
57
|
getBlocksRange(peerId: string, startHeight: number, endHeight: number): Array<BlockReceivedEvent>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dignetwork/chia-block-listener",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.8",
|
|
4
4
|
"main": "index.js",
|
|
5
5
|
"types": "index.d.ts",
|
|
6
6
|
"repository": {
|
|
@@ -58,10 +58,10 @@
|
|
|
58
58
|
},
|
|
59
59
|
"packageManager": "yarn@1.22.22",
|
|
60
60
|
"optionalDependencies": {
|
|
61
|
-
"@dignetwork/chia-block-listener-win32-x64-msvc": "0.1.
|
|
62
|
-
"@dignetwork/chia-block-listener-darwin-x64": "0.1.
|
|
63
|
-
"@dignetwork/chia-block-listener-linux-x64-gnu": "0.1.
|
|
64
|
-
"@dignetwork/chia-block-listener-darwin-arm64": "0.1.
|
|
65
|
-
"@dignetwork/chia-block-listener-linux-arm64-gnu": "0.1.
|
|
61
|
+
"@dignetwork/chia-block-listener-win32-x64-msvc": "0.1.8",
|
|
62
|
+
"@dignetwork/chia-block-listener-darwin-x64": "0.1.8",
|
|
63
|
+
"@dignetwork/chia-block-listener-linux-x64-gnu": "0.1.8",
|
|
64
|
+
"@dignetwork/chia-block-listener-darwin-arm64": "0.1.8",
|
|
65
|
+
"@dignetwork/chia-block-listener-linux-arm64-gnu": "0.1.8"
|
|
66
66
|
}
|
|
67
67
|
}
|
package/scripts/post-build.js
CHANGED
|
@@ -3,11 +3,25 @@ const path = require('path');
|
|
|
3
3
|
|
|
4
4
|
const indexDtsPath = path.join(__dirname, '..', 'index.d.ts');
|
|
5
5
|
|
|
6
|
-
function
|
|
6
|
+
function fixFieldNames() {
|
|
7
7
|
try {
|
|
8
8
|
// Read the auto-generated index.d.ts file
|
|
9
9
|
let content = fs.readFileSync(indexDtsPath, 'utf8');
|
|
10
10
|
|
|
11
|
+
console.log('✅ Field names should now be camelCase from NAPI js_name attributes');
|
|
12
|
+
return content;
|
|
13
|
+
|
|
14
|
+
} catch (error) {
|
|
15
|
+
console.error('❌ Error fixing field names:', error.message);
|
|
16
|
+
process.exit(1);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function addTypedOverloads() {
|
|
21
|
+
try {
|
|
22
|
+
// Read the auto-generated index.d.ts file (or use fixed content from field name correction)
|
|
23
|
+
let content = fixFieldNames();
|
|
24
|
+
|
|
11
25
|
// Check if typed overloads are already present (avoid duplicates)
|
|
12
26
|
if (content.includes('Typed event method overloads')) {
|
|
13
27
|
console.log('✅ Typed event method overloads already present in index.d.ts');
|
package/src/event_emitter.rs
CHANGED
|
@@ -83,6 +83,7 @@ enum PeerEventType {
|
|
|
83
83
|
#[napi(object)]
|
|
84
84
|
#[derive(Clone)]
|
|
85
85
|
pub struct PeerConnectedEvent {
|
|
86
|
+
#[napi(js_name = "peerId")]
|
|
86
87
|
pub peer_id: String,
|
|
87
88
|
pub host: String,
|
|
88
89
|
pub port: u32,
|
|
@@ -92,6 +93,7 @@ pub struct PeerConnectedEvent {
|
|
|
92
93
|
#[napi(object)]
|
|
93
94
|
#[derive(Clone)]
|
|
94
95
|
pub struct PeerDisconnectedEvent {
|
|
96
|
+
#[napi(js_name = "peerId")]
|
|
95
97
|
pub peer_id: String,
|
|
96
98
|
pub host: String,
|
|
97
99
|
pub port: u32,
|
|
@@ -102,23 +104,33 @@ pub struct PeerDisconnectedEvent {
|
|
|
102
104
|
#[napi(object)]
|
|
103
105
|
#[derive(Clone)]
|
|
104
106
|
pub struct BlockReceivedEvent {
|
|
107
|
+
#[napi(js_name = "peerId")]
|
|
105
108
|
pub peer_id: String,
|
|
106
109
|
pub height: u32,
|
|
107
110
|
pub weight: String,
|
|
111
|
+
#[napi(js_name = "headerHash")]
|
|
108
112
|
pub header_hash: String,
|
|
109
113
|
pub timestamp: u32,
|
|
114
|
+
#[napi(js_name = "coinAdditions")]
|
|
110
115
|
pub coin_additions: Vec<CoinRecord>,
|
|
116
|
+
#[napi(js_name = "coinRemovals")]
|
|
111
117
|
pub coin_removals: Vec<CoinRecord>,
|
|
118
|
+
#[napi(js_name = "coinSpends")]
|
|
112
119
|
pub coin_spends: Vec<CoinSpend>,
|
|
120
|
+
#[napi(js_name = "coinCreations")]
|
|
113
121
|
pub coin_creations: Vec<CoinRecord>,
|
|
122
|
+
#[napi(js_name = "hasTransactionsGenerator")]
|
|
114
123
|
pub has_transactions_generator: bool,
|
|
124
|
+
#[napi(js_name = "generatorSize")]
|
|
115
125
|
pub generator_size: u32,
|
|
116
126
|
}
|
|
117
127
|
|
|
118
128
|
#[napi(object)]
|
|
119
129
|
#[derive(Clone)]
|
|
120
130
|
pub struct CoinRecord {
|
|
131
|
+
#[napi(js_name = "parentCoinInfo")]
|
|
121
132
|
pub parent_coin_info: String,
|
|
133
|
+
#[napi(js_name = "puzzleHash")]
|
|
122
134
|
pub puzzle_hash: String,
|
|
123
135
|
pub amount: String,
|
|
124
136
|
}
|
|
@@ -127,10 +139,9 @@ pub struct CoinRecord {
|
|
|
127
139
|
#[derive(Clone)]
|
|
128
140
|
pub struct CoinSpend {
|
|
129
141
|
pub coin: CoinRecord,
|
|
142
|
+
#[napi(js_name = "puzzleReveal")]
|
|
130
143
|
pub puzzle_reveal: String,
|
|
131
144
|
pub solution: String,
|
|
132
|
-
pub real_data: bool,
|
|
133
|
-
pub parsing_method: String,
|
|
134
145
|
pub offset: u32,
|
|
135
146
|
}
|
|
136
147
|
|
|
@@ -241,7 +252,7 @@ impl ChiaBlockListener {
|
|
|
241
252
|
|
|
242
253
|
let peer_id = rt.block_on(async {
|
|
243
254
|
let mut guard = inner.write().await;
|
|
244
|
-
let peer_id =
|
|
255
|
+
let peer_id = host.clone();
|
|
245
256
|
|
|
246
257
|
guard.peers.insert(
|
|
247
258
|
peer_id.clone(),
|
|
@@ -331,7 +342,7 @@ impl ChiaBlockListener {
|
|
|
331
342
|
obj.set_named_property("height", ctx.env.create_uint32(event.height)?)?;
|
|
332
343
|
obj.set_named_property("weight", ctx.env.create_string(&event.weight)?)?;
|
|
333
344
|
obj.set_named_property(
|
|
334
|
-
"
|
|
345
|
+
"headerHash",
|
|
335
346
|
ctx.env.create_string(&event.header_hash)?,
|
|
336
347
|
)?;
|
|
337
348
|
obj.set_named_property("timestamp", ctx.env.create_uint32(event.timestamp)?)?;
|
|
@@ -343,11 +354,11 @@ impl ChiaBlockListener {
|
|
|
343
354
|
for (i, coin) in event.coin_additions.iter().enumerate() {
|
|
344
355
|
let mut coin_obj = ctx.env.create_object()?;
|
|
345
356
|
coin_obj.set_named_property(
|
|
346
|
-
"
|
|
357
|
+
"parentCoinInfo",
|
|
347
358
|
ctx.env.create_string(&coin.parent_coin_info)?,
|
|
348
359
|
)?;
|
|
349
360
|
coin_obj.set_named_property(
|
|
350
|
-
"
|
|
361
|
+
"puzzleHash",
|
|
351
362
|
ctx.env.create_string(&coin.puzzle_hash)?,
|
|
352
363
|
)?;
|
|
353
364
|
coin_obj.set_named_property(
|
|
@@ -356,7 +367,7 @@ impl ChiaBlockListener {
|
|
|
356
367
|
)?;
|
|
357
368
|
additions_array.set_element(i as u32, coin_obj)?;
|
|
358
369
|
}
|
|
359
|
-
obj.set_named_property("
|
|
370
|
+
obj.set_named_property("coinAdditions", additions_array)?;
|
|
360
371
|
|
|
361
372
|
// Coin removals array
|
|
362
373
|
let mut removals_array = ctx
|
|
@@ -365,11 +376,11 @@ impl ChiaBlockListener {
|
|
|
365
376
|
for (i, coin) in event.coin_removals.iter().enumerate() {
|
|
366
377
|
let mut coin_obj = ctx.env.create_object()?;
|
|
367
378
|
coin_obj.set_named_property(
|
|
368
|
-
"
|
|
379
|
+
"parentCoinInfo",
|
|
369
380
|
ctx.env.create_string(&coin.parent_coin_info)?,
|
|
370
381
|
)?;
|
|
371
382
|
coin_obj.set_named_property(
|
|
372
|
-
"
|
|
383
|
+
"puzzleHash",
|
|
373
384
|
ctx.env.create_string(&coin.puzzle_hash)?,
|
|
374
385
|
)?;
|
|
375
386
|
coin_obj.set_named_property(
|
|
@@ -378,7 +389,7 @@ impl ChiaBlockListener {
|
|
|
378
389
|
)?;
|
|
379
390
|
removals_array.set_element(i as u32, coin_obj)?;
|
|
380
391
|
}
|
|
381
|
-
obj.set_named_property("
|
|
392
|
+
obj.set_named_property("coinRemovals", removals_array)?;
|
|
382
393
|
|
|
383
394
|
// Coin spends array
|
|
384
395
|
let mut spends_array =
|
|
@@ -389,11 +400,11 @@ impl ChiaBlockListener {
|
|
|
389
400
|
// Create coin object
|
|
390
401
|
let mut coin_obj = ctx.env.create_object()?;
|
|
391
402
|
coin_obj.set_named_property(
|
|
392
|
-
"
|
|
403
|
+
"parentCoinInfo",
|
|
393
404
|
ctx.env.create_string(&spend.coin.parent_coin_info)?,
|
|
394
405
|
)?;
|
|
395
406
|
coin_obj.set_named_property(
|
|
396
|
-
"
|
|
407
|
+
"puzzleHash",
|
|
397
408
|
ctx.env.create_string(&spend.coin.puzzle_hash)?,
|
|
398
409
|
)?;
|
|
399
410
|
coin_obj.set_named_property(
|
|
@@ -403,27 +414,20 @@ impl ChiaBlockListener {
|
|
|
403
414
|
spend_obj.set_named_property("coin", coin_obj)?;
|
|
404
415
|
|
|
405
416
|
spend_obj.set_named_property(
|
|
406
|
-
"
|
|
417
|
+
"puzzleReveal",
|
|
407
418
|
ctx.env.create_string(&spend.puzzle_reveal)?,
|
|
408
419
|
)?;
|
|
409
420
|
spend_obj.set_named_property(
|
|
410
421
|
"solution",
|
|
411
422
|
ctx.env.create_string(&spend.solution)?,
|
|
412
423
|
)?;
|
|
413
|
-
|
|
414
|
-
"real_data",
|
|
415
|
-
ctx.env.get_boolean(spend.real_data)?,
|
|
416
|
-
)?;
|
|
417
|
-
spend_obj.set_named_property(
|
|
418
|
-
"parsing_method",
|
|
419
|
-
ctx.env.create_string(&spend.parsing_method)?,
|
|
420
|
-
)?;
|
|
424
|
+
|
|
421
425
|
spend_obj
|
|
422
426
|
.set_named_property("offset", ctx.env.create_uint32(spend.offset)?)?;
|
|
423
427
|
|
|
424
428
|
spends_array.set_element(i as u32, spend_obj)?;
|
|
425
429
|
}
|
|
426
|
-
obj.set_named_property("
|
|
430
|
+
obj.set_named_property("coinSpends", spends_array)?;
|
|
427
431
|
|
|
428
432
|
// Coin creations array
|
|
429
433
|
let mut creations_array = ctx
|
|
@@ -432,25 +436,25 @@ impl ChiaBlockListener {
|
|
|
432
436
|
for (i, coin) in event.coin_creations.iter().enumerate() {
|
|
433
437
|
let mut coin_obj = ctx.env.create_object()?;
|
|
434
438
|
coin_obj.set_named_property(
|
|
435
|
-
"
|
|
439
|
+
"parentCoinInfo",
|
|
436
440
|
ctx.env.create_string(&coin.parent_coin_info)?,
|
|
437
441
|
)?;
|
|
438
442
|
coin_obj.set_named_property(
|
|
439
|
-
"
|
|
443
|
+
"puzzleHash",
|
|
440
444
|
ctx.env.create_string(&coin.puzzle_hash)?,
|
|
441
445
|
)?;
|
|
442
446
|
coin_obj
|
|
443
447
|
.set_named_property("amount", ctx.env.create_string(&coin.amount)?)?;
|
|
444
448
|
creations_array.set_element(i as u32, coin_obj)?;
|
|
445
449
|
}
|
|
446
|
-
obj.set_named_property("
|
|
450
|
+
obj.set_named_property("coinCreations", creations_array)?;
|
|
447
451
|
|
|
448
452
|
obj.set_named_property(
|
|
449
|
-
"
|
|
453
|
+
"hasTransactionsGenerator",
|
|
450
454
|
ctx.env.get_boolean(event.has_transactions_generator)?,
|
|
451
455
|
)?;
|
|
452
456
|
obj.set_named_property(
|
|
453
|
-
"
|
|
457
|
+
"generatorSize",
|
|
454
458
|
ctx.env.create_uint32(event.generator_size)?,
|
|
455
459
|
)?;
|
|
456
460
|
|
|
@@ -734,8 +738,6 @@ impl ChiaBlockListener {
|
|
|
734
738
|
},
|
|
735
739
|
puzzle_reveal: hex::encode(&spend.puzzle_reveal),
|
|
736
740
|
solution: hex::encode(&spend.solution),
|
|
737
|
-
real_data: spend.real_data,
|
|
738
|
-
parsing_method: spend.parsing_method.clone(),
|
|
739
741
|
offset: spend.offset,
|
|
740
742
|
})
|
|
741
743
|
.collect(),
|