@dignetwork/chia-block-listener 0.1.15 → 0.1.17
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/Cargo.toml +1 -1
- package/DNS_DISCOVERY_USAGE.md +291 -0
- package/README.md +1030 -768
- package/crate/dns-discovery/Cargo.toml +16 -0
- package/crate/dns-discovery/README.md +151 -0
- package/crate/dns-discovery/examples/discover_peers.rs +84 -0
- package/crate/dns-discovery/package-lock.json +2382 -0
- package/crate/dns-discovery/src/lib.rs +325 -0
- package/dns-discovery.d.ts +84 -0
- package/examples/dns-discovery-example.js +165 -0
- package/index.d.ts +36 -22
- package/index.js +2 -1
- 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/src/dns_discovery_napi.rs +227 -0
- package/src/event_emitter.rs +2 -2
- package/src/lib.rs +2 -0
- package/src/peer.rs +4 -2
- package/src/peer_pool.rs +3 -3
package/Cargo.toml
CHANGED
|
@@ -26,7 +26,6 @@ native-tls = { version = "0.2", features = ["vendored"] }
|
|
|
26
26
|
|
|
27
27
|
# Serialization
|
|
28
28
|
serde = { version = "1", features = ["derive"] }
|
|
29
|
-
hex = "0.4"
|
|
30
29
|
|
|
31
30
|
# Utilities
|
|
32
31
|
thiserror = "1"
|
|
@@ -37,6 +36,7 @@ dirs = "5"
|
|
|
37
36
|
|
|
38
37
|
# Local crates
|
|
39
38
|
chia-generator-parser = { path = "./crate/chia-generator-parser" }
|
|
39
|
+
dns-discovery = { path = "./crate/dns-discovery" }
|
|
40
40
|
|
|
41
41
|
[build-dependencies]
|
|
42
42
|
napi-build = "2"
|
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
# DNS Discovery NAPI Interface
|
|
2
|
+
|
|
3
|
+
A comprehensive Node.js interface for discovering Chia network peers using DNS introducers with proper IPv4/IPv6 support.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
The DNS Discovery NAPI interface exposes the functionality of the isolated `dns-discovery` Rust crate to JavaScript/TypeScript applications. It provides separate IPv4 (A records) and IPv6 (AAAA records) lookups, returning well-structured results that can be used directly with the IPv6-capable peer connection system.
|
|
8
|
+
|
|
9
|
+
## Key Features
|
|
10
|
+
|
|
11
|
+
- ✅ **Dual Stack Support**: Separate IPv4 and IPv6 peer discovery
|
|
12
|
+
- ✅ **Proper DNS Lookups**: Uses A records for IPv4, AAAA records for IPv6
|
|
13
|
+
- ✅ **Built-in Networks**: Ready-to-use configurations for mainnet and testnet11
|
|
14
|
+
- ✅ **Custom Introducers**: Support for custom DNS introducers
|
|
15
|
+
- ✅ **Type Safety**: Full TypeScript definitions included
|
|
16
|
+
- ✅ **Multiple Interfaces**: Both class-based and functional APIs
|
|
17
|
+
- ✅ **IPv6 URL Formatting**: Automatic bracket formatting for IPv6 addresses
|
|
18
|
+
|
|
19
|
+
## Installation
|
|
20
|
+
|
|
21
|
+
The DNS discovery interface is included in the main chia-block-listener package:
|
|
22
|
+
|
|
23
|
+
```javascript
|
|
24
|
+
const {
|
|
25
|
+
DnsDiscoveryClient
|
|
26
|
+
} = require('chia-block-listener');
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## API Reference
|
|
30
|
+
|
|
31
|
+
### Class-Based Interface
|
|
32
|
+
|
|
33
|
+
#### `DnsDiscoveryClient`
|
|
34
|
+
|
|
35
|
+
Main class for DNS discovery operations:
|
|
36
|
+
|
|
37
|
+
```javascript
|
|
38
|
+
const client = new DnsDiscoveryClient();
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
**Methods:**
|
|
42
|
+
|
|
43
|
+
- `discoverMainnetPeers()` → `Promise<DiscoveryResultJS>`
|
|
44
|
+
- `discoverTestnet11Peers()` → `Promise<DiscoveryResultJS>`
|
|
45
|
+
- `discoverPeers(introducers: string[], port: number)` → `Promise<DiscoveryResultJS>`
|
|
46
|
+
- `resolveIpv4(hostname: string)` → `Promise<AddressResult>`
|
|
47
|
+
- `resolveIpv6(hostname: string)` → `Promise<AddressResult>`
|
|
48
|
+
- `resolveBoth(hostname: string, port: number)` → `Promise<DiscoveryResultJS>`
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
## Data Types
|
|
53
|
+
|
|
54
|
+
### `DiscoveryResultJS`
|
|
55
|
+
|
|
56
|
+
Main result type for peer discovery:
|
|
57
|
+
|
|
58
|
+
```typescript
|
|
59
|
+
interface DiscoveryResultJS {
|
|
60
|
+
ipv4Peers: PeerAddressJS[]; // IPv4 peer addresses
|
|
61
|
+
ipv6Peers: PeerAddressJS[]; // IPv6 peer addresses
|
|
62
|
+
totalCount: number; // Total peers found
|
|
63
|
+
}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### `PeerAddressJS`
|
|
67
|
+
|
|
68
|
+
Individual peer address:
|
|
69
|
+
|
|
70
|
+
```typescript
|
|
71
|
+
interface PeerAddressJS {
|
|
72
|
+
host: string; // IP address as string
|
|
73
|
+
port: number; // Port number
|
|
74
|
+
isIpv6: boolean; // Protocol indicator
|
|
75
|
+
displayAddress: string; // Formatted for display/URLs
|
|
76
|
+
}
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### `AddressResult`
|
|
80
|
+
|
|
81
|
+
Result for individual hostname resolution:
|
|
82
|
+
|
|
83
|
+
```typescript
|
|
84
|
+
interface AddressResult {
|
|
85
|
+
addresses: string[]; // List of IP addresses
|
|
86
|
+
count: number; // Number of addresses
|
|
87
|
+
}
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## Usage Examples
|
|
91
|
+
|
|
92
|
+
### Basic Peer Discovery
|
|
93
|
+
|
|
94
|
+
```javascript
|
|
95
|
+
const { DnsDiscoveryClient } = require('chia-block-listener');
|
|
96
|
+
|
|
97
|
+
async function discoverPeers() {
|
|
98
|
+
const client = new DnsDiscoveryClient();
|
|
99
|
+
|
|
100
|
+
// Discover mainnet peers
|
|
101
|
+
const result = await client.discoverMainnetPeers();
|
|
102
|
+
|
|
103
|
+
console.log(`Found ${result.totalCount} total peers:`);
|
|
104
|
+
console.log(` IPv4: ${result.ipv4Peers.length}`);
|
|
105
|
+
console.log(` IPv6: ${result.ipv6Peers.length}`);
|
|
106
|
+
|
|
107
|
+
// Use with peer connections
|
|
108
|
+
for (const peer of result.ipv4Peers) {
|
|
109
|
+
console.log(`IPv4 peer: ${peer.displayAddress}`);
|
|
110
|
+
// Connect using: peer.host, peer.port
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
for (const peer of result.ipv6Peers) {
|
|
114
|
+
console.log(`IPv6 peer: ${peer.displayAddress}`); // [2001:db8::1]:8444
|
|
115
|
+
// Connect using: peer.host, peer.port
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### Simple Discovery
|
|
121
|
+
|
|
122
|
+
```javascript
|
|
123
|
+
const { DnsDiscoveryClient } = require('chia-block-listener');
|
|
124
|
+
|
|
125
|
+
// Simple mainnet discovery
|
|
126
|
+
const client = new DnsDiscoveryClient();
|
|
127
|
+
const peers = await client.discoverMainnetPeers();
|
|
128
|
+
console.log(`Found ${peers.ipv4Peers.length + peers.ipv6Peers.length} peers`);
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### Custom Introducers
|
|
132
|
+
|
|
133
|
+
```javascript
|
|
134
|
+
const client = new DnsDiscoveryClient();
|
|
135
|
+
|
|
136
|
+
// Use custom introducers
|
|
137
|
+
const customIntroducers = [
|
|
138
|
+
'seeder.dexie.space',
|
|
139
|
+
'chia.hoffmang.com'
|
|
140
|
+
];
|
|
141
|
+
|
|
142
|
+
const result = await client.discoverPeers(customIntroducers, 8444);
|
|
143
|
+
console.log(`Custom discovery found ${result.totalCount} peers`);
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
### Individual DNS Resolution
|
|
147
|
+
|
|
148
|
+
```javascript
|
|
149
|
+
const client = new DnsDiscoveryClient();
|
|
150
|
+
|
|
151
|
+
// Resolve specific protocols
|
|
152
|
+
const hostname = 'dns-introducer.chia.net';
|
|
153
|
+
|
|
154
|
+
try {
|
|
155
|
+
const ipv4 = await client.resolveIpv4(hostname);
|
|
156
|
+
console.log(`IPv4 addresses: ${ipv4.addresses.join(', ')}`);
|
|
157
|
+
} catch (error) {
|
|
158
|
+
console.log(`IPv4 resolution failed: ${error.message}`);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
try {
|
|
162
|
+
const ipv6 = await client.resolveIpv6(hostname);
|
|
163
|
+
console.log(`IPv6 addresses: ${ipv6.addresses.join(', ')}`);
|
|
164
|
+
} catch (error) {
|
|
165
|
+
console.log(`IPv6 resolution failed: ${error.message}`);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// Or resolve both at once
|
|
169
|
+
const both = await client.resolveBoth(hostname, 8444);
|
|
170
|
+
console.log(`Combined: ${both.totalCount} addresses`);
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### Integration with Existing Peer Pool
|
|
174
|
+
|
|
175
|
+
```javascript
|
|
176
|
+
const { ChiaPeerPool, DnsDiscoveryClient } = require('chia-block-listener');
|
|
177
|
+
|
|
178
|
+
async function setupPeerPool() {
|
|
179
|
+
const pool = new ChiaPeerPool();
|
|
180
|
+
const discovery = new DnsDiscoveryClient();
|
|
181
|
+
|
|
182
|
+
// Discover peers
|
|
183
|
+
const peers = await discovery.discoverMainnetPeers();
|
|
184
|
+
|
|
185
|
+
// Add IPv4 peers to pool
|
|
186
|
+
for (const peer of peers.ipv4Peers.slice(0, 5)) {
|
|
187
|
+
await pool.addPeer(peer.host, peer.port, 'mainnet');
|
|
188
|
+
console.log(`Added IPv4 peer: ${peer.displayAddress}`);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// Add IPv6 peers to pool
|
|
192
|
+
for (const peer of peers.ipv6Peers.slice(0, 5)) {
|
|
193
|
+
await pool.addPeer(peer.host, peer.port, 'mainnet');
|
|
194
|
+
console.log(`Added IPv6 peer: ${peer.displayAddress}`);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
return pool;
|
|
198
|
+
}
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
### Error Handling
|
|
202
|
+
|
|
203
|
+
```javascript
|
|
204
|
+
const client = new DnsDiscoveryClient();
|
|
205
|
+
|
|
206
|
+
try {
|
|
207
|
+
const result = await client.discoverMainnetPeers();
|
|
208
|
+
// Handle success
|
|
209
|
+
} catch (error) {
|
|
210
|
+
console.error('Discovery failed:', error.message);
|
|
211
|
+
|
|
212
|
+
// Error types: 'ResolutionFailed', 'NoPeersFound', 'ResolverCreationFailed'
|
|
213
|
+
if (error.message.includes('NoPeersFound')) {
|
|
214
|
+
console.log('No peers found from any introducer');
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
### TypeScript Usage
|
|
220
|
+
|
|
221
|
+
```typescript
|
|
222
|
+
import {
|
|
223
|
+
DnsDiscoveryClient,
|
|
224
|
+
DiscoveryResultJS,
|
|
225
|
+
PeerAddressJS
|
|
226
|
+
} from 'chia-block-listener';
|
|
227
|
+
|
|
228
|
+
async function typedDiscovery(): Promise<void> {
|
|
229
|
+
const client = new DnsDiscoveryClient();
|
|
230
|
+
|
|
231
|
+
const result: DiscoveryResultJS = await client.discoverMainnetPeers();
|
|
232
|
+
|
|
233
|
+
// Type-safe access
|
|
234
|
+
result.ipv4Peers.forEach((peer: PeerAddressJS) => {
|
|
235
|
+
console.log(`IPv4: ${peer.host}:${peer.port}`);
|
|
236
|
+
});
|
|
237
|
+
|
|
238
|
+
result.ipv6Peers.forEach((peer: PeerAddressJS) => {
|
|
239
|
+
console.log(`IPv6: ${peer.displayAddress}`);
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
## Performance Considerations
|
|
245
|
+
|
|
246
|
+
- **Caching**: DNS results are not cached; implement your own caching if needed
|
|
247
|
+
- **Concurrency**: All DNS lookups are performed concurrently for maximum speed
|
|
248
|
+
- **Timeout**: DNS queries have built-in timeouts (configured in the Rust crate)
|
|
249
|
+
- **Randomization**: Peer lists are automatically shuffled for load distribution
|
|
250
|
+
|
|
251
|
+
## Troubleshooting
|
|
252
|
+
|
|
253
|
+
### Common Issues
|
|
254
|
+
|
|
255
|
+
1. **No peers found**: Check network connectivity and DNS resolution
|
|
256
|
+
2. **IPv6 resolution fails**: IPv6 may not be available in all environments
|
|
257
|
+
3. **Timeout errors**: Network or DNS server issues
|
|
258
|
+
|
|
259
|
+
### Debug Logging
|
|
260
|
+
|
|
261
|
+
Enable debug logging to see DNS resolution details:
|
|
262
|
+
|
|
263
|
+
```javascript
|
|
264
|
+
const { initTracing } = require('chia-block-listener');
|
|
265
|
+
|
|
266
|
+
// Initialize tracing for debug output
|
|
267
|
+
initTracing();
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
## Comparison with JavaScript Version
|
|
271
|
+
|
|
272
|
+
The Rust-based DNS discovery provides several advantages over the JavaScript version in `coin-monitor.js`:
|
|
273
|
+
|
|
274
|
+
| Feature | JavaScript Version | Rust NAPI Version |
|
|
275
|
+
|---------|-------------------|------------------|
|
|
276
|
+
| **DNS Lookups** | Generic `dns.lookup()` | Explicit A/AAAA records |
|
|
277
|
+
| **IPv6 Support** | Manual detection | Built-in IPv6 handling |
|
|
278
|
+
| **Type Safety** | Runtime checks | Compile-time guarantees |
|
|
279
|
+
| **Performance** | Single-threaded | Concurrent resolution |
|
|
280
|
+
| **Error Handling** | Basic try/catch | Detailed error types |
|
|
281
|
+
| **Address Formatting** | Manual brackets | Automatic formatting |
|
|
282
|
+
|
|
283
|
+
## Future Enhancements
|
|
284
|
+
|
|
285
|
+
Planned improvements:
|
|
286
|
+
|
|
287
|
+
- [ ] DNS caching with TTL support
|
|
288
|
+
- [ ] Custom DNS server configuration
|
|
289
|
+
- [ ] Peer health checking integration
|
|
290
|
+
- [ ] Metrics and monitoring hooks
|
|
291
|
+
- [ ] IPv6 preference configuration
|