beignet 0.3.0 → 0.5.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 +22 -0
- package/dist/cli/auth.js +335 -0
- package/dist/cli/auth.js.map +1 -0
- package/dist/cli/beignet-node.js +35 -16
- package/dist/cli/beignet-node.js.map +1 -1
- package/dist/cli/cli.js +112 -9
- package/dist/cli/cli.js.map +1 -1
- package/dist/cli/config.js +30 -1
- package/dist/cli/config.js.map +1 -1
- package/dist/cli/daemon.js +110 -24
- package/dist/cli/daemon.js.map +1 -1
- package/dist/cli/index.js +6 -1
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/openapi.js +102 -4
- package/dist/cli/openapi.js.map +1 -1
- package/dist/electrum/index.js +2 -2
- package/dist/electrum/index.js.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/lightning/backup/scb.js.map +1 -1
- package/dist/lightning/chain/chain-monitor.js.map +1 -1
- package/dist/lightning/chain/output-resolver.js +11 -9
- package/dist/lightning/chain/output-resolver.js.map +1 -1
- package/dist/lightning/channel/channel-manager.js +30 -24
- package/dist/lightning/channel/channel-manager.js.map +1 -1
- package/dist/lightning/channel/channel-state.js +2 -0
- package/dist/lightning/channel/channel-state.js.map +1 -1
- package/dist/lightning/channel/channel.js +126 -19
- package/dist/lightning/channel/channel.js.map +1 -1
- package/dist/lightning/channel/commitment-builder.js +82 -23
- package/dist/lightning/channel/commitment-builder.js.map +1 -1
- package/dist/lightning/channel/splice-tx.js.map +1 -1
- package/dist/lightning/channel/types.js.map +1 -1
- package/dist/lightning/keys/signer.js +24 -3
- package/dist/lightning/keys/signer.js.map +1 -1
- package/dist/lightning/node/lightning-node.js +34 -4
- package/dist/lightning/node/lightning-node.js.map +1 -1
- package/dist/lightning/node/types.js.map +1 -1
- package/dist/lightning/storage/serialization.js +40 -0
- package/dist/lightning/storage/serialization.js.map +1 -1
- package/dist/lightning/storage/sqlite-storage.js +28 -10
- package/dist/lightning/storage/sqlite-storage.js.map +1 -1
- package/dist/lightning/transport/duplex-transport.js +3 -0
- package/dist/lightning/transport/duplex-transport.js.map +1 -0
- package/dist/lightning/transport/index.js +6 -0
- package/dist/lightning/transport/index.js.map +1 -1
- package/dist/lightning/transport/peer-manager.js +65 -10
- package/dist/lightning/transport/peer-manager.js.map +1 -1
- package/dist/lightning/transport/peer-uri.js +36 -0
- package/dist/lightning/transport/peer-uri.js.map +1 -0
- package/dist/lightning/transport/peer.js.map +1 -1
- package/dist/lightning/transport/websocket-frame.js +199 -0
- package/dist/lightning/transport/websocket-frame.js.map +1 -0
- package/dist/lightning/transport/websocket-node-client.js +299 -0
- package/dist/lightning/transport/websocket-node-client.js.map +1 -0
- package/dist/lightning/transport/websocket-server.js +271 -0
- package/dist/lightning/transport/websocket-server.js.map +1 -0
- package/dist/lightning/transport/websocket.js +270 -0
- package/dist/lightning/transport/websocket.js.map +1 -0
- package/dist/lightning/watchtower/blob.js +92 -6
- package/dist/lightning/watchtower/blob.js.map +1 -1
- package/dist/lightning/watchtower/index.js +1 -1
- package/dist/lightning/watchtower/index.js.map +1 -1
- package/dist/lightning/watchtower/justice.js +120 -30
- package/dist/lightning/watchtower/justice.js.map +1 -1
- package/dist/lightning/watchtower/watchtower-client.js +188 -118
- package/dist/lightning/watchtower/watchtower-client.js.map +1 -1
- package/dist/logger.js +41 -0
- package/dist/logger.js.map +1 -0
- package/dist/types/cli/auth.d.ts +59 -0
- package/dist/types/cli/beignet-node.d.ts +8 -2
- package/dist/types/cli/daemon.d.ts +3 -0
- package/dist/types/cli/index.d.ts +1 -0
- package/dist/types/cli/types.d.ts +10 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/lightning/channel/channel-manager.d.ts +4 -0
- package/dist/types/lightning/channel/channel-state.d.ts +3 -0
- package/dist/types/lightning/channel/channel.d.ts +8 -5
- package/dist/types/lightning/channel/commitment-builder.d.ts +9 -7
- package/dist/types/lightning/channel/splice-tx.d.ts +2 -2
- package/dist/types/lightning/channel/types.d.ts +5 -0
- package/dist/types/lightning/keys/signer.d.ts +18 -1
- package/dist/types/lightning/node/lightning-node.d.ts +8 -1
- package/dist/types/lightning/node/types.d.ts +6 -0
- package/dist/types/lightning/storage/serialization.d.ts +8 -0
- package/dist/types/lightning/storage/sqlite-storage.d.ts +1 -1
- package/dist/types/lightning/transport/duplex-transport.d.ts +16 -0
- package/dist/types/lightning/transport/index.d.ts +6 -0
- package/dist/types/lightning/transport/peer-manager.d.ts +10 -1
- package/dist/types/lightning/transport/peer-uri.d.ts +8 -0
- package/dist/types/lightning/transport/peer.d.ts +3 -4
- package/dist/types/lightning/transport/websocket-frame.d.ts +52 -0
- package/dist/types/lightning/transport/websocket-node-client.d.ts +39 -0
- package/dist/types/lightning/transport/websocket-server.d.ts +48 -0
- package/dist/types/lightning/transport/websocket.d.ts +72 -0
- package/dist/types/lightning/watchtower/blob.d.ts +14 -0
- package/dist/types/lightning/watchtower/justice.d.ts +2 -1
- package/dist/types/lightning/watchtower/types.d.ts +3 -1
- package/dist/types/lightning/watchtower/watchtower-client.d.ts +3 -2
- package/dist/types/logger.d.ts +17 -0
- package/dist/types/types/wallet.d.ts +2 -0
- package/dist/types/wallet/index.d.ts +2 -0
- package/dist/types/wallet.js.map +1 -1
- package/dist/utils/electrum.js +4 -2
- package/dist/utils/electrum.js.map +1 -1
- package/dist/wallet/index.js +24 -22
- package/dist/wallet/index.js.map +1 -1
- package/docs/ROADMAP.md +144 -21
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -13,6 +13,7 @@ Beignet provides two layers of Bitcoin wallet functionality:
|
|
|
13
13
|
|
|
14
14
|
1. [Getting Started](#getting-started)
|
|
15
15
|
2. [On-Chain Wallet](#on-chain-wallet)
|
|
16
|
+
- [Leveled Logging](#leveled-logging)
|
|
16
17
|
3. [Lightning Network](#lightning-network)
|
|
17
18
|
- [Lightning Quick Start (BeignetNode)](#lightning-quick-start-beignetnode)
|
|
18
19
|
- [Decision-Support APIs](#decision-support-apis)
|
|
@@ -341,6 +342,27 @@ const wallet = await Wallet.create({
|
|
|
341
342
|
});
|
|
342
343
|
```
|
|
343
344
|
|
|
345
|
+
### Leveled Logging
|
|
346
|
+
|
|
347
|
+
Diagnostic output (debug/info/warn/error) flows through a small injectable logger, kept separate from the Lightning node's persisted structured action log (`getActionLog`). The `ILogger` interface is four methods, `debug`/`info`/`warn`/`error`(`message: string, meta?: unknown`), with level filtering `debug < info < warn < error` plus `'silent'`:
|
|
348
|
+
|
|
349
|
+
```typescript
|
|
350
|
+
import { Wallet, createConsoleLogger, noopLogger } from 'beignet';
|
|
351
|
+
|
|
352
|
+
const wallet = await Wallet.create({
|
|
353
|
+
mnemonic,
|
|
354
|
+
logger: createConsoleLogger('warn'), // only warn + error reach the console
|
|
355
|
+
// logger: noopLogger, // fully silent
|
|
356
|
+
// logger: myLogger, // any ILogger: route into your own stack
|
|
357
|
+
// ...
|
|
358
|
+
});
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
- **`Wallet.create({ logger })`** defaults to `createConsoleLogger('info')`, which preserves the wallet's historical console output. `disableMessages` is independent and keeps its existing meaning: it only gates `onMessage` callbacks.
|
|
362
|
+
- **`LightningNode`** accepts `logger` in `INodeConfig` / `fromMnemonic` options and defaults to `noopLogger` (the node prints nothing, as before). Every structured action-log entry is additionally mirrored to `logger.debug('category:action', data)`.
|
|
363
|
+
- **`BeignetNode.create({ logger, logLevel })`**: log entries that pass `logLevel` are forwarded to the injected logger (in addition to the `'log'` event), and the logger is injected into the underlying `Wallet` and `LightningNode`. Without `logger`, behavior is unchanged (events only).
|
|
364
|
+
- **Daemon:** `beignet start --log-level <debug|info|warn|error|silent>` (or `BEIGNET_LOG_LEVEL`, or `logLevel` in `~/.beignet/config.json`) prints leveled diagnostics to stderr. Unset keeps the daemon silent (the default); stdout stays reserved for command output.
|
|
365
|
+
|
|
344
366
|
## Lightning Network
|
|
345
367
|
|
|
346
368
|
### Lightning Quick Start (BeignetNode)
|
package/dist/cli/auth.js
ADDED
|
@@ -0,0 +1,335 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ApiKeyAuthenticator = exports.scopesAllowRoute = exports.getRouteScopes = exports.ROUTE_SCOPES = exports.AUTH_KEY_OVERRIDES_STORAGE_KEY = exports.API_SCOPES = void 0;
|
|
4
|
+
const crypto_1 = require("crypto");
|
|
5
|
+
const errors_1 = require("./errors");
|
|
6
|
+
exports.API_SCOPES = new Set([
|
|
7
|
+
'readonly',
|
|
8
|
+
'invoice',
|
|
9
|
+
'admin'
|
|
10
|
+
]);
|
|
11
|
+
exports.AUTH_KEY_OVERRIDES_STORAGE_KEY = 'daemon:auth-key-overrides:v1';
|
|
12
|
+
exports.ROUTE_SCOPES = {
|
|
13
|
+
'GET /info': ['readonly'],
|
|
14
|
+
'GET /balance': ['readonly'],
|
|
15
|
+
'GET /peers': ['readonly'],
|
|
16
|
+
'GET /channels': ['readonly'],
|
|
17
|
+
'GET /channels/ready': ['readonly'],
|
|
18
|
+
'GET /payments': ['readonly'],
|
|
19
|
+
'GET /payment': ['readonly'],
|
|
20
|
+
'GET /payment/proof': ['readonly'],
|
|
21
|
+
'GET /payment/verify-proof': ['readonly'],
|
|
22
|
+
'GET /forwards': ['readonly'],
|
|
23
|
+
'GET /forwards/summary': ['readonly'],
|
|
24
|
+
'GET /readiness': ['readonly'],
|
|
25
|
+
'GET /stats': ['readonly'],
|
|
26
|
+
'GET /spend-limit': ['readonly'],
|
|
27
|
+
'GET /liquidity': ['readonly'],
|
|
28
|
+
'GET /watchtowers': ['readonly'],
|
|
29
|
+
'GET /advisor/recommendations': ['readonly'],
|
|
30
|
+
'GET /fees': ['readonly'],
|
|
31
|
+
'GET /fees/estimates': ['readonly'],
|
|
32
|
+
'GET /transactions': ['readonly'],
|
|
33
|
+
'GET /transactions/boostable': ['readonly'],
|
|
34
|
+
'GET /utxos': ['readonly'],
|
|
35
|
+
'GET /address/labels': ['readonly'],
|
|
36
|
+
'GET /wallet/descriptors': ['readonly'],
|
|
37
|
+
'GET /channel': ['readonly'],
|
|
38
|
+
'GET /channel/health': ['readonly'],
|
|
39
|
+
'GET /channel/policy': ['readonly'],
|
|
40
|
+
'GET /channel/diagnostics': ['readonly'],
|
|
41
|
+
'GET /channel/suggestions': ['readonly'],
|
|
42
|
+
'GET /logs': ['readonly'],
|
|
43
|
+
'GET /node/uri': ['readonly'],
|
|
44
|
+
'GET /trusted-peers': ['readonly'],
|
|
45
|
+
'GET /can-send': ['readonly'],
|
|
46
|
+
'GET /graph/info': ['readonly'],
|
|
47
|
+
'GET /graph/node': ['readonly'],
|
|
48
|
+
'GET /graph/channel': ['readonly'],
|
|
49
|
+
'GET /graph/describe': ['readonly'],
|
|
50
|
+
'GET /backup/scb': ['readonly'],
|
|
51
|
+
'GET /backup/peer-retrieved': ['readonly'],
|
|
52
|
+
'GET /queue': ['readonly'],
|
|
53
|
+
'POST /route/estimate': ['readonly'],
|
|
54
|
+
'POST /route/query': ['readonly'],
|
|
55
|
+
'POST /payment/estimate': ['readonly'],
|
|
56
|
+
'POST /message/verify': ['readonly'],
|
|
57
|
+
'POST /address/validate': ['readonly'],
|
|
58
|
+
'POST /node/wait-ready': ['readonly'],
|
|
59
|
+
'POST /channel/wait-ready': ['readonly'],
|
|
60
|
+
'GET /invoices': ['readonly', 'invoice'],
|
|
61
|
+
'GET /invoice': ['readonly', 'invoice'],
|
|
62
|
+
'GET /invoices/held': ['readonly', 'invoice'],
|
|
63
|
+
'GET /offers': ['readonly', 'invoice'],
|
|
64
|
+
'GET /can-receive': ['readonly', 'invoice'],
|
|
65
|
+
'GET /events': ['readonly', 'invoice'],
|
|
66
|
+
'POST /invoice/decode': ['readonly', 'invoice'],
|
|
67
|
+
'POST /invoice/validate': ['readonly', 'invoice'],
|
|
68
|
+
'POST /offer/decode': ['readonly', 'invoice'],
|
|
69
|
+
'POST /payment/wait': ['readonly', 'invoice'],
|
|
70
|
+
'POST /invoice/create': ['invoice'],
|
|
71
|
+
'POST /invoice/create-hold': ['invoice'],
|
|
72
|
+
'POST /invoice/settle-hold': ['invoice'],
|
|
73
|
+
'POST /invoice/cancel-hold': ['invoice'],
|
|
74
|
+
'POST /offer/create': ['invoice'],
|
|
75
|
+
'POST /address/new': ['invoice'],
|
|
76
|
+
'GET /mnemonic': [],
|
|
77
|
+
'GET /webhooks': [],
|
|
78
|
+
'POST /send': [],
|
|
79
|
+
'POST /send-max': [],
|
|
80
|
+
'POST /tx/bump-fee': [],
|
|
81
|
+
'POST /tx/boost': [],
|
|
82
|
+
'POST /consolidate': [],
|
|
83
|
+
'POST /invoice/pay': [],
|
|
84
|
+
'POST /invoice/pay-safe': [],
|
|
85
|
+
'POST /invoice/pay-async': [],
|
|
86
|
+
'POST /invoice/pay-retry': [],
|
|
87
|
+
'POST /keysend': [],
|
|
88
|
+
'POST /keysend/safe': [],
|
|
89
|
+
'POST /offer/pay': [],
|
|
90
|
+
'POST /payment/send-to-route': [],
|
|
91
|
+
'POST /payment/cancel': [],
|
|
92
|
+
'POST /queue/add': [],
|
|
93
|
+
'POST /queue/cancel': [],
|
|
94
|
+
'POST /rebalance': [],
|
|
95
|
+
'POST /advisor/execute-rebalances': [],
|
|
96
|
+
'POST /recover-fallback-funds': [],
|
|
97
|
+
'POST /utxo/freeze': [],
|
|
98
|
+
'POST /utxo/unfreeze': [],
|
|
99
|
+
'POST /address/label': [],
|
|
100
|
+
'POST /wallet/refresh': [],
|
|
101
|
+
'POST /psbt/build': [],
|
|
102
|
+
'POST /psbt/import-signed': [],
|
|
103
|
+
'POST /psbt/combine': [],
|
|
104
|
+
'POST /peer/connect': [],
|
|
105
|
+
'POST /peer/disconnect': [],
|
|
106
|
+
'POST /peers/bootstrap': [],
|
|
107
|
+
'POST /peers/connect-seeds': [],
|
|
108
|
+
'POST /trusted-peer/add': [],
|
|
109
|
+
'POST /trusted-peer/remove': [],
|
|
110
|
+
'POST /channel/open': [],
|
|
111
|
+
'POST /channel/open-zeroconf': [],
|
|
112
|
+
'POST /channel/open-v2': [],
|
|
113
|
+
'POST /channel/open-and-wait': [],
|
|
114
|
+
'POST /channel/connect-and-open': [],
|
|
115
|
+
'POST /channels/ensure-minimum': [],
|
|
116
|
+
'POST /channel/close': [],
|
|
117
|
+
'POST /channel/forceclose': [],
|
|
118
|
+
'POST /channel/splice-in': [],
|
|
119
|
+
'POST /channel/splice-out': [],
|
|
120
|
+
'POST /channel/update-commitment-feerate': [],
|
|
121
|
+
'POST /channel/update-fee': [],
|
|
122
|
+
'POST /channel/update-policy': [],
|
|
123
|
+
'POST /message/sign': [],
|
|
124
|
+
'POST /gossip/sync': [],
|
|
125
|
+
'POST /gossip/sync-rapid': [],
|
|
126
|
+
'POST /route/probe': [],
|
|
127
|
+
'POST /payment/metadata': [],
|
|
128
|
+
'POST /backup': [],
|
|
129
|
+
'POST /backup/trigger': [],
|
|
130
|
+
'POST /restore/scb': [],
|
|
131
|
+
'POST /watchtower/add': [],
|
|
132
|
+
'DELETE /watchtower/remove': [],
|
|
133
|
+
'POST /webhooks/register': [],
|
|
134
|
+
'DELETE /webhooks/unregister': [],
|
|
135
|
+
'POST /stop': [],
|
|
136
|
+
'GET /auth/keys': [],
|
|
137
|
+
'POST /auth/keys/revoke': [],
|
|
138
|
+
'POST /auth/keys/rotate': []
|
|
139
|
+
};
|
|
140
|
+
function getRouteScopes(routeKey) {
|
|
141
|
+
return exports.ROUTE_SCOPES[routeKey] ?? [];
|
|
142
|
+
}
|
|
143
|
+
exports.getRouteScopes = getRouteScopes;
|
|
144
|
+
function scopesAllowRoute(scopes, routeKey) {
|
|
145
|
+
if (scopes.has('admin'))
|
|
146
|
+
return true;
|
|
147
|
+
return getRouteScopes(routeKey).some((s) => scopes.has(s));
|
|
148
|
+
}
|
|
149
|
+
exports.scopesAllowRoute = scopesAllowRoute;
|
|
150
|
+
function sha256(input) {
|
|
151
|
+
return (0, crypto_1.createHash)('sha256').update(input, 'utf8').digest();
|
|
152
|
+
}
|
|
153
|
+
const SHA256_HEX_RE = /^[0-9a-f]{64}$/;
|
|
154
|
+
class ApiKeyAuthenticator {
|
|
155
|
+
constructor(apiToken, apiKeys) {
|
|
156
|
+
this.candidates = [];
|
|
157
|
+
this.revoked = new Set();
|
|
158
|
+
this.keyNames = [];
|
|
159
|
+
this.overrides = {};
|
|
160
|
+
this.store = null;
|
|
161
|
+
if (apiToken) {
|
|
162
|
+
this.candidates.push({
|
|
163
|
+
name: null,
|
|
164
|
+
digest: sha256(apiToken),
|
|
165
|
+
scopes: new Set(['admin'])
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
for (const def of apiKeys ?? []) {
|
|
169
|
+
this.addKeyDefinition(def, apiToken);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
addKeyDefinition(def, apiToken) {
|
|
173
|
+
if (!def || typeof def.name !== 'string' || def.name.trim() === '') {
|
|
174
|
+
throw new errors_1.BeignetError('INVALID_PARAMS', 'apiKeys entries require a non-empty name');
|
|
175
|
+
}
|
|
176
|
+
if (typeof def.key !== 'string' || def.key === '') {
|
|
177
|
+
throw new errors_1.BeignetError('INVALID_PARAMS', `apiKeys entry "${def.name}" requires a non-empty key`);
|
|
178
|
+
}
|
|
179
|
+
if (!Array.isArray(def.scopes) ||
|
|
180
|
+
def.scopes.length === 0 ||
|
|
181
|
+
def.scopes.some((s) => !exports.API_SCOPES.has(s))) {
|
|
182
|
+
throw new errors_1.BeignetError('INVALID_PARAMS', `apiKeys entry "${def.name}" requires scopes from: readonly, invoice, admin`);
|
|
183
|
+
}
|
|
184
|
+
if (this.keyNames.includes(def.name)) {
|
|
185
|
+
throw new errors_1.BeignetError('INVALID_PARAMS', `Duplicate apiKeys name "${def.name}"`);
|
|
186
|
+
}
|
|
187
|
+
if (apiToken !== undefined && def.key === apiToken) {
|
|
188
|
+
throw new errors_1.BeignetError('INVALID_PARAMS', `apiKeys entry "${def.name}" duplicates the legacy apiToken value`);
|
|
189
|
+
}
|
|
190
|
+
let expiresAtMs;
|
|
191
|
+
if (def.expiresAt !== undefined) {
|
|
192
|
+
expiresAtMs =
|
|
193
|
+
typeof def.expiresAt === 'string' ? Date.parse(def.expiresAt) : NaN;
|
|
194
|
+
if (!Number.isFinite(expiresAtMs)) {
|
|
195
|
+
throw new errors_1.BeignetError('INVALID_PARAMS', `apiKeys entry "${def.name}" has an unparseable expiresAt ` +
|
|
196
|
+
`(use ISO 8601, e.g. "2027-01-01T00:00:00Z")`);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
const digest = sha256(def.key);
|
|
200
|
+
for (const existing of this.candidates) {
|
|
201
|
+
if (existing.name !== null && (0, crypto_1.timingSafeEqual)(existing.digest, digest)) {
|
|
202
|
+
throw new errors_1.BeignetError('INVALID_PARAMS', `apiKeys entry "${def.name}" duplicates the key of "${existing.name}"`);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
this.keyNames.push(def.name);
|
|
206
|
+
this.candidates.push({
|
|
207
|
+
name: def.name,
|
|
208
|
+
digest,
|
|
209
|
+
scopes: new Set(def.scopes),
|
|
210
|
+
configDigestHex: digest.toString('hex'),
|
|
211
|
+
expiresAt: def.expiresAt,
|
|
212
|
+
expiresAtMs
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
get enabled() {
|
|
216
|
+
return this.candidates.length > 0;
|
|
217
|
+
}
|
|
218
|
+
isExpired(candidate) {
|
|
219
|
+
return (candidate.expiresAtMs !== undefined && Date.now() >= candidate.expiresAtMs);
|
|
220
|
+
}
|
|
221
|
+
attachOverrideStore(store) {
|
|
222
|
+
this.store = store;
|
|
223
|
+
const loaded = store.load();
|
|
224
|
+
const kept = {};
|
|
225
|
+
let pruned = false;
|
|
226
|
+
for (const [name, override] of Object.entries(loaded ?? {})) {
|
|
227
|
+
const candidate = this.candidates.find((c) => c.name === name);
|
|
228
|
+
if (!candidate ||
|
|
229
|
+
typeof override !== 'object' ||
|
|
230
|
+
override === null ||
|
|
231
|
+
typeof override.configDigest !== 'string' ||
|
|
232
|
+
override.configDigest !== candidate.configDigestHex ||
|
|
233
|
+
(override.keyDigest !== undefined &&
|
|
234
|
+
!SHA256_HEX_RE.test(override.keyDigest))) {
|
|
235
|
+
pruned = true;
|
|
236
|
+
continue;
|
|
237
|
+
}
|
|
238
|
+
kept[name] = override;
|
|
239
|
+
if (override.keyDigest !== undefined) {
|
|
240
|
+
candidate.digest = Buffer.from(override.keyDigest, 'hex');
|
|
241
|
+
candidate.rotatedAt = override.rotatedAt;
|
|
242
|
+
}
|
|
243
|
+
if (override.revoked === true) {
|
|
244
|
+
this.revoked.add(name);
|
|
245
|
+
}
|
|
246
|
+
if (override.expiresAt !== undefined) {
|
|
247
|
+
const ms = typeof override.expiresAt === 'string'
|
|
248
|
+
? Date.parse(override.expiresAt)
|
|
249
|
+
: NaN;
|
|
250
|
+
if (Number.isFinite(ms)) {
|
|
251
|
+
candidate.expiresAt = override.expiresAt;
|
|
252
|
+
candidate.expiresAtMs = ms;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
this.overrides = kept;
|
|
257
|
+
if (pruned)
|
|
258
|
+
store.save(kept);
|
|
259
|
+
}
|
|
260
|
+
authenticate(header) {
|
|
261
|
+
if (!header)
|
|
262
|
+
return { ok: false };
|
|
263
|
+
const match = header.match(/^bearer\s+(.+)$/i);
|
|
264
|
+
if (!match)
|
|
265
|
+
return { ok: false };
|
|
266
|
+
const presented = sha256(match[1]);
|
|
267
|
+
let matched = null;
|
|
268
|
+
for (const candidate of this.candidates) {
|
|
269
|
+
const equal = (0, crypto_1.timingSafeEqual)(candidate.digest, presented);
|
|
270
|
+
if (equal &&
|
|
271
|
+
matched === null &&
|
|
272
|
+
(candidate.name === null || !this.revoked.has(candidate.name)) &&
|
|
273
|
+
!this.isExpired(candidate)) {
|
|
274
|
+
matched = candidate;
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
if (!matched)
|
|
278
|
+
return { ok: false };
|
|
279
|
+
return { ok: true, keyName: matched.name, scopes: matched.scopes };
|
|
280
|
+
}
|
|
281
|
+
revoke(name) {
|
|
282
|
+
const candidate = this.candidates.find((c) => c.name === name);
|
|
283
|
+
if (!candidate || candidate.name === null)
|
|
284
|
+
return false;
|
|
285
|
+
this.revoked.add(name);
|
|
286
|
+
this.overrides = {
|
|
287
|
+
...this.overrides,
|
|
288
|
+
[name]: {
|
|
289
|
+
...(this.overrides[name] ?? {
|
|
290
|
+
configDigest: candidate.configDigestHex ?? ''
|
|
291
|
+
}),
|
|
292
|
+
revoked: true
|
|
293
|
+
}
|
|
294
|
+
};
|
|
295
|
+
this.store?.save(this.overrides);
|
|
296
|
+
return true;
|
|
297
|
+
}
|
|
298
|
+
rotate(name) {
|
|
299
|
+
const candidate = this.candidates.find((c) => c.name === name);
|
|
300
|
+
if (!candidate || candidate.name === null)
|
|
301
|
+
return null;
|
|
302
|
+
const newKey = (0, crypto_1.randomBytes)(32).toString('hex');
|
|
303
|
+
const newDigest = sha256(newKey);
|
|
304
|
+
const rotatedAt = new Date().toISOString();
|
|
305
|
+
const override = {
|
|
306
|
+
...(this.overrides[name] ?? {
|
|
307
|
+
configDigest: candidate.configDigestHex ?? ''
|
|
308
|
+
}),
|
|
309
|
+
keyDigest: newDigest.toString('hex'),
|
|
310
|
+
rotatedAt
|
|
311
|
+
};
|
|
312
|
+
delete override.revoked;
|
|
313
|
+
const next = { ...this.overrides, [name]: override };
|
|
314
|
+
this.store?.save(next);
|
|
315
|
+
this.overrides = next;
|
|
316
|
+
candidate.digest = newDigest;
|
|
317
|
+
candidate.rotatedAt = rotatedAt;
|
|
318
|
+
this.revoked.delete(name);
|
|
319
|
+
return { name, key: newKey, rotatedAt };
|
|
320
|
+
}
|
|
321
|
+
listKeys() {
|
|
322
|
+
return this.candidates
|
|
323
|
+
.filter((c) => c.name !== null)
|
|
324
|
+
.map((c) => ({
|
|
325
|
+
name: c.name,
|
|
326
|
+
scopes: [...c.scopes],
|
|
327
|
+
revoked: this.revoked.has(c.name),
|
|
328
|
+
expired: this.isExpired(c),
|
|
329
|
+
...(c.expiresAt !== undefined ? { expiresAt: c.expiresAt } : {}),
|
|
330
|
+
...(c.rotatedAt !== undefined ? { rotatedAt: c.rotatedAt } : {})
|
|
331
|
+
}));
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
exports.ApiKeyAuthenticator = ApiKeyAuthenticator;
|
|
335
|
+
//# sourceMappingURL=auth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/cli/auth.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/beignet-node.js
CHANGED
|
@@ -33,6 +33,7 @@ const instance_lock_1 = require("./instance-lock");
|
|
|
33
33
|
const crypto = __importStar(require("crypto"));
|
|
34
34
|
const events_1 = require("events");
|
|
35
35
|
const wallet_1 = require("../wallet");
|
|
36
|
+
const logger_1 = require("../logger");
|
|
36
37
|
const helpers_1 = require("../utils/helpers");
|
|
37
38
|
const conversion_1 = require("../utils/conversion");
|
|
38
39
|
const wallet_2 = require("../types/wallet");
|
|
@@ -145,13 +146,6 @@ async function resolveHostToIPv4(host) {
|
|
|
145
146
|
return host;
|
|
146
147
|
}
|
|
147
148
|
}
|
|
148
|
-
const LOG_PRIORITY = {
|
|
149
|
-
debug: 0,
|
|
150
|
-
info: 1,
|
|
151
|
-
warn: 2,
|
|
152
|
-
error: 3,
|
|
153
|
-
silent: 4
|
|
154
|
-
};
|
|
155
149
|
class BeignetNode extends events_1.EventEmitter {
|
|
156
150
|
on(event, listener) {
|
|
157
151
|
return super.on(event, listener);
|
|
@@ -187,10 +181,13 @@ class BeignetNode extends events_1.EventEmitter {
|
|
|
187
181
|
this.dataDir = dataDir;
|
|
188
182
|
}
|
|
189
183
|
log(level, message, data) {
|
|
190
|
-
if (
|
|
184
|
+
if (logger_1.LOG_LEVEL_PRIORITY[level] < logger_1.LOG_LEVEL_PRIORITY[this.logLevel])
|
|
191
185
|
return;
|
|
192
186
|
const entry = { level, message, data, timestamp: Date.now() };
|
|
193
187
|
this.emit('log', entry);
|
|
188
|
+
if (this.logger && level !== 'silent') {
|
|
189
|
+
this.logger[level](message, data);
|
|
190
|
+
}
|
|
194
191
|
}
|
|
195
192
|
static async create(opts = {}) {
|
|
196
193
|
const mnemonic = opts.mnemonic || (0, helpers_1.generateMnemonic)();
|
|
@@ -204,6 +201,8 @@ class BeignetNode extends events_1.EventEmitter {
|
|
|
204
201
|
async init(opts) {
|
|
205
202
|
if (opts.logLevel)
|
|
206
203
|
this.logLevel = opts.logLevel;
|
|
204
|
+
if (opts.logger)
|
|
205
|
+
this.logger = opts.logger;
|
|
207
206
|
this.autoGossipSync = opts.autoGossipSync ?? true;
|
|
208
207
|
this.peerStorageEnabled = opts.peerStorageEnabled ?? true;
|
|
209
208
|
this.rapidGossipSync = opts.rapidGossipSync ?? true;
|
|
@@ -247,9 +246,13 @@ class BeignetNode extends events_1.EventEmitter {
|
|
|
247
246
|
if (!opts.dataDir) {
|
|
248
247
|
const legacyDb = path.join(DEFAULT_DATA_DIR, `${networkName}.db`);
|
|
249
248
|
if (fs.existsSync(legacyDb) && !fs.existsSync(dbPath)) {
|
|
250
|
-
|
|
249
|
+
const legacyMsg = `[beignet] Found a legacy shared database at ${legacyDb}. ` +
|
|
251
250
|
`Storage is now per-wallet (${dbPath}), so it is no longer auto-loaded. ` +
|
|
252
|
-
`If it held this wallet's channels, re-run with dataDir set to "${DEFAULT_DATA_DIR}" to use it
|
|
251
|
+
`If it held this wallet's channels, re-run with dataDir set to "${DEFAULT_DATA_DIR}" to use it.`;
|
|
252
|
+
this.log('warn', legacyMsg);
|
|
253
|
+
if (!this.logger) {
|
|
254
|
+
console.warn(legacyMsg);
|
|
255
|
+
}
|
|
253
256
|
}
|
|
254
257
|
}
|
|
255
258
|
let encryptionKey;
|
|
@@ -280,6 +283,7 @@ class BeignetNode extends events_1.EventEmitter {
|
|
|
280
283
|
servers: electrumServer
|
|
281
284
|
},
|
|
282
285
|
disableMessagesOnCreate: true,
|
|
286
|
+
...(this.logger ? { logger: this.logger } : {}),
|
|
283
287
|
rbf: true,
|
|
284
288
|
storage: (0, wallet_storage_1.createWalletStorage)(this.storage)
|
|
285
289
|
});
|
|
@@ -383,6 +387,7 @@ class BeignetNode extends events_1.EventEmitter {
|
|
|
383
387
|
largeChannels: opts.largeChannels,
|
|
384
388
|
chainBackend: electrumBackend,
|
|
385
389
|
feeEstimator: electrumBackend,
|
|
390
|
+
logger: this.logger,
|
|
386
391
|
sweepDestinationScript,
|
|
387
392
|
socks5Proxy,
|
|
388
393
|
peerStorageEnabled: this.peerStorageEnabled,
|
|
@@ -566,6 +571,14 @@ class BeignetNode extends events_1.EventEmitter {
|
|
|
566
571
|
catch {
|
|
567
572
|
}
|
|
568
573
|
}
|
|
574
|
+
if (opts.websocketPort) {
|
|
575
|
+
try {
|
|
576
|
+
await this.node.listenWebSocket(opts.websocketPort);
|
|
577
|
+
this._websocketPort = opts.websocketPort;
|
|
578
|
+
}
|
|
579
|
+
catch {
|
|
580
|
+
}
|
|
581
|
+
}
|
|
569
582
|
if (opts.connectTimeoutMs !== undefined && opts.connectTimeoutMs > 0) {
|
|
570
583
|
this._connectTimeoutMs = opts.connectTimeoutMs;
|
|
571
584
|
}
|
|
@@ -634,7 +647,7 @@ class BeignetNode extends events_1.EventEmitter {
|
|
|
634
647
|
getInfo() {
|
|
635
648
|
const info = this.node.getNodeInfo();
|
|
636
649
|
const lightningBalance = this.getLightningBalanceSats();
|
|
637
|
-
|
|
650
|
+
const result = {
|
|
638
651
|
nodeId: info.nodeId,
|
|
639
652
|
alias: info.alias,
|
|
640
653
|
network: this.networkName,
|
|
@@ -647,6 +660,10 @@ class BeignetNode extends events_1.EventEmitter {
|
|
|
647
660
|
peerCount: info.peerCount,
|
|
648
661
|
listening: this.node.isListening()
|
|
649
662
|
};
|
|
663
|
+
if (this._websocketPort !== undefined) {
|
|
664
|
+
result.websocketPort = this._websocketPort;
|
|
665
|
+
}
|
|
666
|
+
return result;
|
|
650
667
|
}
|
|
651
668
|
getMnemonic() {
|
|
652
669
|
return this.mnemonic;
|
|
@@ -1150,12 +1167,14 @@ class BeignetNode extends events_1.EventEmitter {
|
|
|
1150
1167
|
getWallet() {
|
|
1151
1168
|
return this.wallet;
|
|
1152
1169
|
}
|
|
1153
|
-
async connectPeer(pubkey, host, port) {
|
|
1154
|
-
const target =
|
|
1155
|
-
?
|
|
1156
|
-
:
|
|
1170
|
+
async connectPeer(pubkey, host, port, transport) {
|
|
1171
|
+
const target = transport?.type === 'ws' && transport.url !== undefined
|
|
1172
|
+
? transport.url
|
|
1173
|
+
: host !== undefined && port !== undefined
|
|
1174
|
+
? `${host}:${port}`
|
|
1175
|
+
: 'resolved address (gossip graph / DNS bootstrap)';
|
|
1157
1176
|
let timer;
|
|
1158
|
-
const connectPromise = this.node.connectPeer(pubkey, host, port);
|
|
1177
|
+
const connectPromise = this.node.connectPeer(pubkey, host, port, transport);
|
|
1159
1178
|
const timeoutPromise = new Promise((_, reject) => {
|
|
1160
1179
|
timer = setTimeout(() => reject(new errors_1.BeignetError('CONNECT_TIMEOUT', `connectPeer timed out after ${this._connectTimeoutMs}ms (is ${target} the peer's P2P address?)`)), this._connectTimeoutMs);
|
|
1161
1180
|
});
|