dcr-ts 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.
@@ -0,0 +1,955 @@
1
+ /**
2
+ * Typed errors.
3
+ *
4
+ * Everything this library throws is a {@link DcrError} carrying a stable
5
+ * {@link DcrErrorCode}. Without one, the only way to tell a mistyped address from
6
+ * a right-address-wrong-network paste is to match on prose — which is not part of
7
+ * any API, breaks the moment a message is reworded, and cannot express the cases
8
+ * that share wording. The tests in this repository had exactly that problem.
9
+ *
10
+ * ```ts
11
+ * try {
12
+ * addressToScript(pasted, mainnet);
13
+ * } catch (e) {
14
+ * if (hasErrorCode(e, "bad-checksum")) showTypoHelp();
15
+ * else if (hasErrorCode(e, "wrong-network")) showWrongNetworkHelp();
16
+ * else throw e;
17
+ * }
18
+ * ```
19
+ *
20
+ * Codes are the stable part; messages are for humans and may be reworded.
21
+ */
22
+ /**
23
+ * What went wrong, as a value rather than a sentence.
24
+ *
25
+ * Grouped by concern. New codes may be added in a minor release, so treat an
26
+ * unrecognised one as a generic failure rather than assuming the set is closed.
27
+ */
28
+ type DcrErrorCode =
29
+ /** A character outside the base58 alphabet. */
30
+ "invalid-base58"
31
+ /** base58check or WIF checksum did not match. Usually a typo. */
32
+ | "bad-checksum"
33
+ /** Input longer than the format allows; rejected before the quadratic decode. */
34
+ | "input-too-long"
35
+ /** A field or payload was not the required size. */
36
+ | "bad-length"
37
+ /** A varint that could have been encoded in fewer bytes (dcrd's ErrNonCanonicalVarInt). */
38
+ | "non-canonical-varint"
39
+ /** Ran off the end of the input while reading. */
40
+ | "unexpected-end"
41
+ /** Input parsed, but bytes remained after it. */
42
+ | "trailing-bytes"
43
+ /** Not a valid private scalar (zero, or out of range for the suite's group order). */
44
+ | "invalid-private-key"
45
+ /** Wrong length or prefix, or not a point on the curve. */
46
+ | "invalid-public-key"
47
+ /** The two-byte version prefix belongs to no known network and kind. */
48
+ | "unknown-prefix"
49
+ /** Well-formed, but for a different network than the one required. */
50
+ | "wrong-network"
51
+ /** A signature-suite identifier this library does not support. */
52
+ | "unsupported-signature-type"
53
+ /** Cannot derive a hardened child from a public key. */
54
+ | "hardened-from-public"
55
+ /** The derived child is invalid; retry the next index (BIP32 says this is ~2^-127). */
56
+ | "invalid-child"
57
+ /** Refused to derive past the depth a single byte can serialize. */
58
+ | "max-depth"
59
+ /** A derivation path that does not parse. */
60
+ | "invalid-path"
61
+ /** A private-key operation was asked of a public (neutered) key. */
62
+ | "not-a-private-key"
63
+ /** Extended-key version bytes matching no known network. */
64
+ | "unknown-version"
65
+ /** Mnemonic failed its checksum, or used a word outside the wordlist. */
66
+ | "invalid-mnemonic"
67
+ /** A script whose data pushes do not tokenize (dcrd's checkScriptParses). */
68
+ | "malformed-script"
69
+ /** A signature hash type dcrd would not accept, or one wider than a byte. */
70
+ | "invalid-hash-type"
71
+ /** A push above MaxScriptElementSize, which dcrd can never execute. */
72
+ | "element-too-large"
73
+ /** A numeric argument outside its permitted range. */
74
+ | "out-of-range"
75
+ /** A numeric argument that was not an integer (includes NaN and Infinity). */
76
+ | "not-an-integer"
77
+ /** A malformed or unrepresentable amount. */
78
+ | "invalid-amount"
79
+ /** A required argument was missing or of the wrong shape. */
80
+ | "invalid-argument";
81
+ /** Every error this library throws. */
82
+ declare class DcrError extends Error {
83
+ /** Stable, machine-readable. Branch on this, not on {@link message}. */
84
+ readonly code: DcrErrorCode;
85
+ readonly name = "DcrError";
86
+ constructor(
87
+ /** Stable, machine-readable. Branch on this, not on {@link message}. */
88
+ code: DcrErrorCode, message: string, options?: {
89
+ cause?: unknown;
90
+ });
91
+ }
92
+ /**
93
+ * True when `e` is a {@link DcrError}, including one thrown by another copy of
94
+ * this package loaded into the same process.
95
+ */
96
+ declare function isDcrError(e: unknown): e is DcrError;
97
+ /**
98
+ * True when `e` is a {@link DcrError} with this code.
99
+ *
100
+ * Safe on an `unknown` from a `catch`, so it needs no type guard at the call site.
101
+ */
102
+ declare function hasErrorCode(e: unknown, code: DcrErrorCode): boolean;
103
+
104
+ /** The BLAKE-256 digest length in bytes. */
105
+ declare const BLAKE256_DIGEST_LENGTH = 32;
106
+ /** The BLAKE-256 block length in bytes. */
107
+ declare const BLAKE256_BLOCK_LENGTH = 64;
108
+ /** Incremental BLAKE-256 hasher. */
109
+ declare class Blake256 {
110
+ private readonly h;
111
+ private readonly buf;
112
+ private buflen;
113
+ /** Total message bytes fed in (used for the final length encoding). */
114
+ private total;
115
+ /** Message bytes already absorbed by the compression function. */
116
+ private compressed;
117
+ private finished;
118
+ update(data: Uint8Array): this;
119
+ digest(): Uint8Array;
120
+ }
121
+ /** One-shot BLAKE-256. Returns the 32-byte digest. */
122
+ declare function blake256(data: Uint8Array): Uint8Array;
123
+
124
+ /** Double BLAKE-256: `blake256(blake256(data))`. */
125
+ declare function hash256(data: Uint8Array): Uint8Array;
126
+ /** RIPEMD-160 of BLAKE-256: `ripemd160(blake256(data))`. The address hash. */
127
+ declare function hash160(data: Uint8Array): Uint8Array;
128
+
129
+ /** Encode raw bytes as base58 (no checksum). */
130
+ declare function base58Encode(bytes: Uint8Array): string;
131
+ /**
132
+ * Longest base58 string that can decode to `decodedLen` bytes.
133
+ *
134
+ * base58 expands by at most log_58(256) ≈ 1.37 bytes of output per input byte,
135
+ * which is how dcrd derives its own bounds (`stdaddr.DecodeAddressV0`'s
136
+ * `maxV0AddrLen`, `hdkeychain.NewKeyFromString`'s `maxKeyLen`). Callers must cap
137
+ * untrusted input *before* decoding: {@link base58Decode} accumulates one BigInt
138
+ * digit at a time and is therefore quadratic, so an unbounded string is a cheap
139
+ * way to stall the event loop.
140
+ */
141
+ declare function maxBase58Length(decodedLen: number): number;
142
+ /**
143
+ * Decode a base58 string to raw bytes. Throws on invalid characters.
144
+ *
145
+ * Cost is **quadratic** in the length of `str`. There is deliberately no length
146
+ * cap here, because the function is general-purpose; every decoder in this
147
+ * library bounds its input first via {@link maxBase58Length}, and anything
148
+ * calling this directly on untrusted input must do the same.
149
+ */
150
+ declare function base58Decode(str: string): Uint8Array;
151
+ /** base58check-encode: append the 4-byte double-BLAKE-256 checksum. */
152
+ declare function checkEncode(data: Uint8Array): string;
153
+ /**
154
+ * base58check-decode and verify the checksum, returning the payload without the
155
+ * trailing 4 checksum bytes. Throws if the checksum does not match.
156
+ *
157
+ * Inherits {@link base58Decode}'s **quadratic** cost and its lack of a length
158
+ * cap, and the checksum does not change that: the whole string is decoded before
159
+ * there is anything to check. Cap untrusted input with {@link maxBase58Length}
160
+ * first, exactly as `decodeAddress`, `decodeWif` and `ExtendedKey.fromString`
161
+ * do before they call this — the bound is in each of those callers, not in here.
162
+ */
163
+ declare function checkDecode(str: string): Uint8Array;
164
+
165
+ /**
166
+ * Copy `n` bytes out of `src` starting at `off`, always into a fresh buffer.
167
+ *
168
+ * Deliberately not `src.slice(off, off + n)`. `Uint8Array.prototype.slice`
169
+ * copies, but Node's `Buffer` overrides it to return a *view* over the same
170
+ * memory (deprecated, still the behaviour). Since `Buffer` is what
171
+ * `fs.readFileSync`, `Buffer.from(hex, "hex")`, sockets and database drivers all
172
+ * hand back, a `slice()` here would silently alias the caller's memory for the
173
+ * most common input type: reusing or zeroing that buffer afterwards would mutate
174
+ * an already-parsed transaction or key.
175
+ */
176
+ declare function copyOf(src: Uint8Array, off: number, n: number): Uint8Array;
177
+ /** Growable little-endian byte writer. */
178
+ declare class Writer {
179
+ private buf;
180
+ private view;
181
+ private len;
182
+ private ensure;
183
+ u8(v: number): this;
184
+ u16(v: number): this;
185
+ u32(v: number): this;
186
+ u64(v: bigint): this;
187
+ /** Signed 64-bit little-endian (two's complement). Used for atom amounts. */
188
+ i64(v: bigint): this;
189
+ bytes(b: Uint8Array): this;
190
+ /** Compact-size varint. */
191
+ varInt(v: number | bigint): this;
192
+ /** A varint length prefix followed by the bytes themselves. */
193
+ varBytes(b: Uint8Array): this;
194
+ finish(): Uint8Array;
195
+ }
196
+ /** Little-endian byte reader. */
197
+ declare class Reader {
198
+ private readonly data;
199
+ private off;
200
+ private readonly view;
201
+ constructor(data: Uint8Array);
202
+ get offset(): number;
203
+ get remaining(): number;
204
+ private need;
205
+ u8(): number;
206
+ u16(): number;
207
+ u32(): number;
208
+ u64(): bigint;
209
+ /** Signed 64-bit little-endian (two's complement). */
210
+ i64(): bigint;
211
+ bytes(n: number): Uint8Array;
212
+ /**
213
+ * Compact-size varint. Rejects non-canonical encodings (a value that could
214
+ * have been encoded in fewer bytes), matching dcrd's `ErrNonCanonicalVarInt`.
215
+ * Without this check two distinct byte strings could parse to the same
216
+ * transaction while hashing to different ids.
217
+ */
218
+ varInt(): number;
219
+ varBytes(): Uint8Array;
220
+ }
221
+
222
+ /**
223
+ * Decred network parameters.
224
+ *
225
+ * The magic prefix bytes, private-key IDs, extended-key version bytes and coin
226
+ * types are taken verbatim from dcrd's `chaincfg` package for the four
227
+ * networks. They are what make an address human-readable as `Ds…`/`Ts…`/`Ss…`
228
+ * and what bind a key to a specific network.
229
+ */
230
+ /** Two-byte address version prefixes and related per-network identifiers. */
231
+ interface Network {
232
+ /** Human name, e.g. "mainnet". */
233
+ readonly name: string;
234
+ /** Network magic (wire protocol identifier). */
235
+ readonly net: number;
236
+ /** Leading character(s) of every address on this network (informational). */
237
+ readonly addressPrefix: string;
238
+ /** Version prefix for pay-to-pubkey (secp256k1 ECDSA) addresses. */
239
+ readonly pubKeyAddrId: readonly [number, number];
240
+ /** Version prefix for pay-to-pubkey-hash (secp256k1 ECDSA) addresses. */
241
+ readonly pubKeyHashAddrId: readonly [number, number];
242
+ /** Version prefix for pay-to-pubkey-hash (Ed25519) addresses. */
243
+ readonly pubKeyHashEdwardsAddrId: readonly [number, number];
244
+ /** Version prefix for pay-to-pubkey-hash (secp256k1 Schnorr) addresses. */
245
+ readonly pubKeyHashSchnorrAddrId: readonly [number, number];
246
+ /** Version prefix for pay-to-script-hash addresses. */
247
+ readonly scriptHashAddrId: readonly [number, number];
248
+ /** Version prefix for WIF private keys. */
249
+ readonly privateKeyId: readonly [number, number];
250
+ /** BIP32 extended private key version bytes (`dprv`/`tprv`/…). */
251
+ readonly hdPrivateKeyId: readonly [number, number, number, number];
252
+ /** BIP32 extended public key version bytes (`dpub`/`tpub`/…). */
253
+ readonly hdPublicKeyId: readonly [number, number, number, number];
254
+ /** SLIP-0044 registered coin type used in BIP44 derivation paths. */
255
+ readonly slip44: number;
256
+ }
257
+ declare const mainnet: Network;
258
+ declare const testnet3: Network;
259
+ declare const simnet: Network;
260
+ declare const regnet: Network;
261
+ /** All networks keyed by name. */
262
+ declare const networks: {
263
+ readonly mainnet: Network;
264
+ readonly testnet3: Network;
265
+ readonly simnet: Network;
266
+ readonly regnet: Network;
267
+ };
268
+ type NetworkName = keyof typeof networks;
269
+
270
+ /** The secp256k1 group order. */
271
+ declare const CURVE_ORDER: bigint;
272
+ /** True when `key` is a valid secp256k1 private scalar (0 < key < n). */
273
+ declare function isValidPrivateKey(key: Uint8Array): boolean;
274
+ /**
275
+ * Throw unless `key` is a usable secp256k1 private scalar.
276
+ *
277
+ * Everything that signs, or turns a private key into a public one, goes through
278
+ * this. `@noble` checks the same two conditions itself but throws its own plain
279
+ * `Error`, which escapes the typed-error contract — a caller branching on
280
+ * `hasErrorCode` cannot classify a zeroed or wrong-length key buffer, which is
281
+ * exactly the mistake worth classifying.
282
+ *
283
+ * Deliberately stricter than dcrd, which cannot express this failure at all:
284
+ * `secp256k1.PrivKeyFromBytes` reduces mod n and left-pads a short slice, so a
285
+ * zero key there signs under an all-zero-X public key and a 31-byte key is
286
+ * silently padded. Rejecting is the safer contract for a signing API.
287
+ */
288
+ declare function assertPrivateKey(key: Uint8Array, who: string): void;
289
+ /** Compressed (33-byte) public key for a private key. */
290
+ declare function publicKeyFromPrivate(privateKey: Uint8Array, compressed?: boolean): Uint8Array;
291
+ /** True when `key` is a valid serialized secp256k1 point (compressed or not). */
292
+ declare function isValidPublicKey(key: Uint8Array): boolean;
293
+ /**
294
+ * True when `key` is a valid 32-byte Ed25519 public key.
295
+ *
296
+ * Decred's alternative signature suites are recognised on decode even though this
297
+ * library cannot sign for them, and an address whose key is not on the curve is
298
+ * unspendable — so it should not decode as valid. Ed25519 comes from the same
299
+ * `@noble/curves` package already in use, so this adds no dependency.
300
+ */
301
+ declare function isValidEd25519PublicKey(key: Uint8Array): boolean;
302
+ /**
303
+ * Throw unless `key` is a 33-byte compressed secp256k1 point.
304
+ *
305
+ * Anything that turns a public key into an address or an output script must go
306
+ * through this. Length alone is not enough, and length is not even checked in the
307
+ * common mistake: passing a 32-byte private key where the public key was meant
308
+ * type-checks fine, since both are `Uint8Array`. The resulting address or script
309
+ * is well-formed and permanently unspendable, because no key hashes to it.
310
+ */
311
+ declare function assertCompressedPubKey(key: Uint8Array, who: string): void;
312
+ /**
313
+ * Throw unless `key` is a serialized secp256k1 point — 33-byte compressed or
314
+ * 65-byte uncompressed.
315
+ *
316
+ * For hashing a key into a P2PKH address, where both serializations are
317
+ * legitimate and produce *different* addresses (dcrd hashes whichever form the
318
+ * caller holds; see `dcrutil/util.go`). Use {@link assertCompressedPubKey}
319
+ * wherever the format itself requires 33 bytes, such as the pay-to-pubkey address
320
+ * payload or a bare-P2PK script.
321
+ */
322
+ declare function assertPubKey(key: Uint8Array, who: string): void;
323
+
324
+ type AddressKind = "pubkeyhash-ecdsa" | "pubkeyhash-ed25519" | "pubkeyhash-schnorr" | "scripthash" | "pubkey-ecdsa" | "pubkey-ed25519" | "pubkey-schnorr";
325
+ /** The hash-based address kinds, which carry a 20-byte `hash`. */
326
+ type HashAddressKind = "pubkeyhash-ecdsa" | "pubkeyhash-ed25519" | "pubkeyhash-schnorr" | "scripthash";
327
+ /** The pay-to-pubkey kinds, which carry a serialized `pubKey`. */
328
+ type PubKeyAddressKind = "pubkey-ecdsa" | "pubkey-ed25519" | "pubkey-schnorr";
329
+ /**
330
+ * A decoded address.
331
+ *
332
+ * A discriminated union on `kind`, so `hash` and `pubKey` are present exactly
333
+ * where they exist — narrowing on `kind` (or on `"hash" in decoded`) replaces
334
+ * what would otherwise be a non-null assertion at every use.
335
+ */
336
+ type DecodedAddress = {
337
+ readonly network: Network;
338
+ readonly kind: HashAddressKind;
339
+ /** 20-byte hash. */
340
+ readonly hash: Uint8Array;
341
+ /** The original address string. */
342
+ readonly address: string;
343
+ } | {
344
+ readonly network: Network;
345
+ readonly kind: PubKeyAddressKind;
346
+ /**
347
+ * The serialized public key: 33-byte compressed secp256k1 for
348
+ * `pubkey-ecdsa` and `pubkey-schnorr`, 32-byte Ed25519 for
349
+ * `pubkey-ed25519`.
350
+ */
351
+ readonly pubKey: Uint8Array;
352
+ readonly address: string;
353
+ };
354
+ /**
355
+ * Longest a version-0 address can be: a 33-byte payload (the pay-to-pubkey kind)
356
+ * plus a 2-byte version prefix and a 4-byte checksum. Matches dcrd's
357
+ * `maxV0AddrLen`.
358
+ */
359
+ declare const MAX_ADDRESS_LENGTH: number;
360
+ /** Encode a 20-byte pubkey hash as a P2PKH (secp256k1 ECDSA) address. */
361
+ declare function pubKeyHashAddress(hash: Uint8Array, network: Network): string;
362
+ /** Encode a 20-byte script hash as a P2SH address. */
363
+ declare function scriptHashAddress(hash: Uint8Array, network: Network): string;
364
+ /** Encode a 20-byte pubkey hash as a P2PKH (Ed25519) address. */
365
+ declare function pubKeyHashEd25519Address(hash: Uint8Array, network: Network): string;
366
+ /** Encode a 20-byte pubkey hash as a P2PKH (secp256k1 Schnorr) address. */
367
+ declare function pubKeyHashSchnorrAddress(hash: Uint8Array, network: Network): string;
368
+ /** Encode a compressed public key as a pay-to-pubkey (secp256k1 ECDSA) address. */
369
+ declare function pubKeyAddress(compressedPubKey: Uint8Array, network: Network): string;
370
+ /** Encode a 32-byte Ed25519 public key as a pay-to-pubkey address. */
371
+ declare function pubKeyEd25519Address(pubKey: Uint8Array, network: Network): string;
372
+ /** Encode a compressed public key as a pay-to-pubkey (secp256k1 Schnorr) address. */
373
+ declare function pubKeySchnorrAddress(compressedPubKey: Uint8Array, network: Network): string;
374
+ /**
375
+ * Derive the standard P2PKH address for a public key (`hash160` of the key).
376
+ *
377
+ * Accepts **either** serialization: 33-byte compressed or 65-byte uncompressed.
378
+ * They hash to different addresses, and both are legitimate — dcrd hashes
379
+ * whichever form the caller holds — so refusing the uncompressed form would break
380
+ * the only address a signature script built with
381
+ * `signatureScript(..., compressed = false)` can ever satisfy.
382
+ *
383
+ * The key is validated as a real curve point. Without that, any byte string
384
+ * hashes to something and produces a well-formed, valid-checksum address that no
385
+ * key can ever spend from — and the way to hit it is mundane: passing
386
+ * `privateKeyBytes()` where `publicKey()` was meant type-checks silently, because
387
+ * both are `Uint8Array`, and 32 vs 33 bytes is invisible at the call site.
388
+ */
389
+ declare function addressFromPubKey(pubKey: Uint8Array, network: Network): string;
390
+ /** Derive the P2SH address that pays to `redeemScript`. */
391
+ declare function addressFromScript(redeemScript: Uint8Array, network: Network): string;
392
+ /**
393
+ * Decode and validate an address. When `network` is given the address must
394
+ * belong to it; otherwise the network is inferred from the version prefix.
395
+ */
396
+ declare function decodeAddress(address: string, network?: Network): DecodedAddress;
397
+ /** True when `address` is a well-formed address (optionally for `network`). */
398
+ declare function isValidAddress(address: string, network?: Network): boolean;
399
+ /**
400
+ * Build the pkScript that pays to `address`.
401
+ *
402
+ * `network` is **required**, and deliberately so. A payment script commits only
403
+ * to the 20-byte hash, not to the network, so `addressToScript` on a testnet
404
+ * address produces bytes byte-identical to the mainnet address for the same hash
405
+ * — a pasted testnet address would quietly pay whoever controls that hash on
406
+ * mainnet. Naming the expected network here is the only thing that catches it.
407
+ *
408
+ * Use {@link decodeAddress} without a network when you genuinely want to inspect
409
+ * an address of unknown origin; it returns the network it found.
410
+ */
411
+ declare function addressToScript(address: string, network: Network): Uint8Array;
412
+
413
+ /** Decred signature suites, matching dcrd's `dcrec.SignatureType`. */
414
+ declare enum SignatureType {
415
+ Ecdsa = 0,
416
+ Ed25519 = 1,
417
+ SchnorrSecp256k1 = 2
418
+ }
419
+ interface DecodedWif {
420
+ readonly privateKey: Uint8Array;
421
+ readonly network: Network;
422
+ readonly signatureType: SignatureType;
423
+ }
424
+ /** Encode a 32-byte private key as WIF. */
425
+ declare function encodeWif(privateKey: Uint8Array, network: Network, signatureType?: SignatureType): string;
426
+ /**
427
+ * Longest a WIF string can be: 2 prefix + 1 suite + 32 key + 4 checksum bytes.
428
+ */
429
+ declare const MAX_WIF_LENGTH: number;
430
+ /** Decode and validate a WIF string. */
431
+ declare function decodeWif(wif: string): DecodedWif;
432
+
433
+ declare const OP: {
434
+ readonly OP_0: 0;
435
+ readonly DATA_20: 20;
436
+ readonly DATA_32: 32;
437
+ readonly DATA_33: 33;
438
+ readonly PUSHDATA1: 76;
439
+ readonly PUSHDATA2: 77;
440
+ readonly PUSHDATA4: 78;
441
+ readonly OP_1NEGATE: 79;
442
+ readonly OP_1: 81;
443
+ readonly OP_2: 82;
444
+ readonly OP_16: 96;
445
+ readonly DUP: 118;
446
+ readonly EQUAL: 135;
447
+ readonly EQUALVERIFY: 136;
448
+ readonly HASH160: 169;
449
+ readonly CHECKSIG: 172;
450
+ readonly CHECKSIGALT: 190;
451
+ };
452
+ /**
453
+ * Largest a single stack element may be (dcrd `txscript.MaxScriptElementSize`).
454
+ * dcrd rejects a bigger push both when building and at execution, so anything
455
+ * over this can never run.
456
+ */
457
+ declare const MAX_SCRIPT_ELEMENT_SIZE = 2048;
458
+ /**
459
+ * Encode a canonical data push — the smallest valid encoding for `data`.
460
+ *
461
+ * "Smallest" includes the small-integer opcodes, which is a consensus rule and
462
+ * not a policy one: dcrd's script engine applies `checkMinimalDataPush` to every
463
+ * executed push with no verification flag gating it, so `OP_DATA_1 0x05` fails
464
+ * where `OP_5` succeeds. A script built with a non-minimal push is unspendable.
465
+ */
466
+ declare function pushData(data: Uint8Array): Uint8Array;
467
+ /**
468
+ * True when `script` tokenizes cleanly as a version-0 script — i.e. every data
469
+ * push declares a length that actually fits.
470
+ *
471
+ * The equivalent of dcrd's `checkScriptParses`, which its exported
472
+ * `CalcSignatureHash` runs before hashing. Signing against a script that does
473
+ * not parse produces a signature over a message dcrd would refuse to compute,
474
+ * so the resulting transaction can never be spent.
475
+ *
476
+ * This is a structural check only, not an execution one: it says nothing about
477
+ * whether the opcodes are valid or the script would succeed.
478
+ */
479
+ declare function scriptParses(script: Uint8Array): boolean;
480
+ /** Build a P2PKH script: `OP_DUP OP_HASH160 <20-byte hash> OP_EQUALVERIFY OP_CHECKSIG`. */
481
+ declare function payToPubKeyHashScript(hash160: Uint8Array): Uint8Array;
482
+ /**
483
+ * Build a P2PKH script for an alternative signature suite (Ed25519 = 1,
484
+ * secp256k1 Schnorr = 2): `OP_DUP OP_HASH160 <20-byte hash> OP_EQUALVERIFY
485
+ * <OP_1|OP_2> OP_CHECKSIGALT`. The signature type is pushed as a small integer.
486
+ */
487
+ declare function payToPubKeyHashAltScript(hash160: Uint8Array, sigType: 1 | 2): Uint8Array;
488
+ /** Build a P2SH script: `OP_HASH160 <20-byte hash> OP_EQUAL`. */
489
+ declare function payToScriptHashScript(hash160: Uint8Array): Uint8Array;
490
+ /**
491
+ * Build a bare P2PK script: `<33-byte compressed pubkey> OP_CHECKSIG`.
492
+ *
493
+ * The key is validated as an actual curve point, not just measured. This is an
494
+ * *output* script: paying to one built around arbitrary 33 bytes burns the coins,
495
+ * because no signature can ever satisfy an `OP_CHECKSIG` whose key does not
496
+ * parse. dcrd cannot express this — its constructor takes a parsed public key.
497
+ */
498
+ declare function payToPubKeyScript(compressedPubKey: Uint8Array): Uint8Array;
499
+ /**
500
+ * Build a pay-to-pubkey script for an alternative signature suite.
501
+ *
502
+ * Ed25519 takes a 32-byte key: `<32-byte pubkey> OP_1 OP_CHECKSIGALT`.
503
+ * secp256k1 Schnorr takes a 33-byte compressed key:
504
+ * `<33-byte pubkey> OP_2 OP_CHECKSIGALT`.
505
+ *
506
+ * The suite is pushed as a small integer, exactly as in
507
+ * {@link payToPubKeyHashAltScript}.
508
+ */
509
+ declare function payToPubKeyAltScript(pubKey: Uint8Array, sigType: 1 | 2): Uint8Array;
510
+ /** True when `script` is a canonical version-0 P2PKH template. */
511
+ declare function isPayToPubKeyHash(script: Uint8Array): boolean;
512
+ /** True when `script` is a canonical version-0 P2SH template. */
513
+ declare function isPayToScriptHash(script: Uint8Array): boolean;
514
+ /**
515
+ * Extract the 20-byte hash from a P2PKH or P2SH script, or `null`.
516
+ *
517
+ * Note this deliberately loses *which* template matched, and the two need
518
+ * different addresses — use {@link classifyScript} when that matters, or the
519
+ * hash will be encoded as the wrong address kind.
520
+ */
521
+ declare function extractHash160(script: Uint8Array): Uint8Array | null;
522
+ /** What {@link classifyScript} recognises. */
523
+ type ScriptKind = "pubkeyhash-ecdsa" | "pubkeyhash-ed25519" | "pubkeyhash-schnorr" | "scripthash";
524
+ /**
525
+ * Classify a version-0 payment script and return its 20-byte hash.
526
+ *
527
+ * {@link extractHash160} returns a bare hash for either the P2PKH or the P2SH
528
+ * template, so a caller labelling outputs by address has no way to tell which
529
+ * encoder to use — and picking wrong produces a completely different, valid
530
+ * address for the same script. This keeps the kind attached. Also recognises the
531
+ * two `OP_CHECKSIGALT` templates the library can build, which nothing could
532
+ * classify before.
533
+ */
534
+ declare function classifyScript(script: Uint8Array): {
535
+ kind: ScriptKind;
536
+ hash: Uint8Array;
537
+ } | null;
538
+
539
+ /** Index of the first hardened child (2^31). */
540
+ declare const HARDENED_OFFSET = 2147483648;
541
+ /**
542
+ * Longest a `dprv`/`dpub` string can be: the 78-byte serialization plus a 4-byte
543
+ * checksum. Matches dcrd's `maxKeyLen` in `NewKeyFromString`.
544
+ */
545
+ declare const MAX_EXTENDED_KEY_LENGTH: number;
546
+ /**
547
+ * Mark a BIP44 child index as hardened.
548
+ *
549
+ * Rejects anything outside `0..2^31-1`: adding the offset to an already-hardened
550
+ * or out-of-range index wraps, and the result would be a *non*-hardened index
551
+ * silently derived from the wrong branch.
552
+ */
553
+ declare function hardened(index: number): number;
554
+ /** A BIP32 extended key with Decred version bytes. */
555
+ declare class ExtendedKey {
556
+ readonly network: Network;
557
+ readonly isPrivate: boolean;
558
+ /** 32-byte private scalar, or `null` for a public (neutered) key. */
559
+ private readonly privateKey;
560
+ /** 33-byte compressed public key. */
561
+ private readonly compressedPublicKey;
562
+ private readonly chainCodeBytes;
563
+ readonly depth: number;
564
+ private readonly parentFingerprintBytes;
565
+ readonly childNumber: number;
566
+ /**
567
+ * Whether dcrd would be holding this scalar with its leading zero bytes
568
+ * stripped, which changes the hardened HMAC input of its children (see the
569
+ * module docs). True only for keys produced by {@link derive} — dcrd strips
570
+ * in `child` alone, so a master key from `fromSeed` and a key parsed by
571
+ * `fromSerialized` are both held at full width, exactly as `NewMaster` and
572
+ * `NewKeyFromString` do. The scalar itself is always stored padded to 32
573
+ * bytes here; only the HMAC input is narrowed.
574
+ */
575
+ private readonly scalarStripped;
576
+ private constructor();
577
+ /** Memoized hash160 of the public key; see {@link identifier}. */
578
+ private cachedIdentifier;
579
+ /**
580
+ * Memoized decompression of {@link compressedPublicKey}, so deriving a chain of
581
+ * public children does the modular square root once instead of per step. Only
582
+ * populated on the public-derivation path.
583
+ */
584
+ private cachedPoint;
585
+ /** Derive a master key from a BIP32 seed (16–64 bytes). */
586
+ static fromSeed(seed: Uint8Array, network: Network): ExtendedKey;
587
+ /** The compressed public key (33 bytes). */
588
+ publicKey(): Uint8Array;
589
+ /** The 32-byte private scalar. Throws for a public key. */
590
+ privateKeyBytes(): Uint8Array;
591
+ /**
592
+ * The 32-byte chain code. A copy: the key's own derivation reads the internal
593
+ * bytes, so handing out a live view would let a caller change what this key
594
+ * derives.
595
+ */
596
+ get chainCode(): Uint8Array;
597
+ /** The parent's 4-byte fingerprint, or four zero bytes for a master key. A copy. */
598
+ get parentFingerprint(): Uint8Array;
599
+ /**
600
+ * Identifier = hash160(compressed pubkey); the fingerprint is its first 4 bytes.
601
+ *
602
+ * Memoized, because `derive` needs the parent fingerprint for every child and
603
+ * would otherwise recompute a BLAKE-256 plus a RIPEMD-160 of the same key at
604
+ * every step. Both accessors return copies: the memo turned what used to be a
605
+ * per-call throwaway digest into long-lived shared state, so handing out a view
606
+ * would let one caller's write corrupt the cache, this key's own fingerprint,
607
+ * every sibling's `parentFingerprint` and every child derived afterwards.
608
+ */
609
+ identifier(): Uint8Array;
610
+ fingerprint(): Uint8Array;
611
+ /** The memoized digest itself. Never escapes this class. */
612
+ private identifierBytes;
613
+ /**
614
+ * Derive a child key by index, the **Decred way** — the equivalent of dcrd
615
+ * `hdkeychain.Child`, and what dcrwallet and Decrediton derive with for the
616
+ * whole wallet path. Use {@link hardened} for hardened indices.
617
+ *
618
+ * This is the default because it is what the Decred ecosystem derives; see
619
+ * {@link deriveBip32Std} for the strict form and the module docs for why they
620
+ * differ.
621
+ */
622
+ derive(index: number): ExtendedKey;
623
+ /**
624
+ * Derive a child key by **strict BIP32** — the equivalent of dcrd
625
+ * `hdkeychain.ChildBIP32Std`, retaining the leading zero bytes of the parent
626
+ * private key that {@link derive} strips.
627
+ *
628
+ * Produces different hardened children from {@link derive} for any parent
629
+ * scalar with a leading zero byte, which is about 1 key in 256 at each
630
+ * hardened step. Use it only when strict BIP32 is what you want; anything that
631
+ * has to agree with a dcrwallet or Decrediton seed must not.
632
+ */
633
+ deriveBip32Std(index: number): ExtendedKey;
634
+ private deriveInner;
635
+ /**
636
+ * Derive along a path like `m/44'/42'/0'/0/0`, the **Decred way** (see
637
+ * {@link derive}). An apostrophe or `h` marks a hardened index.
638
+ */
639
+ derivePath(path: string): ExtendedKey;
640
+ /**
641
+ * Derive along a path using **strict BIP32** (see {@link deriveBip32Std}).
642
+ * Diverges from {@link derivePath} below any hardened step whose parent scalar
643
+ * has a leading zero byte, so do not use it to reproduce a wallet seed.
644
+ */
645
+ derivePathBip32Std(path: string): ExtendedKey;
646
+ private derivePathInner;
647
+ /** Return the public (watch-only) version of this key. */
648
+ neuter(): ExtendedKey;
649
+ /** The standard P2PKH address for this key on its network. */
650
+ address(network?: Network): string;
651
+ /** Serialize to the 78-byte BIP32 form (without the base58check checksum). */
652
+ serialize(): Uint8Array;
653
+ /** Encode as a `dprv`/`dpub` (or per-network) base58check string. */
654
+ toString(): string;
655
+ /** Parse an extended key string, validating the checksum and version. */
656
+ static fromString(str: string): ExtendedKey;
657
+ /**
658
+ * Parse a raw 78-byte serialization (checksum already verified/absent).
659
+ *
660
+ * Every field is copied out of `data`, so the returned key does not alias the
661
+ * caller's buffer — which matters most here, because a caller doing the right
662
+ * thing and wiping the serialization after parsing would otherwise destroy the
663
+ * key it just parsed. See {@link copyOf}.
664
+ */
665
+ static fromSerialized(data: Uint8Array): ExtendedKey;
666
+ }
667
+
668
+ /** A BIP39 wordlist: 2048 words. Defaults to English throughout this module. */
669
+ type Wordlist = readonly string[];
670
+ /** The English BIP39 wordlist, used wherever `wordlist` is omitted. */
671
+ declare const englishWordlist: Wordlist;
672
+ /** Generate a new mnemonic. `strength` is entropy bits (128–256, default 128). */
673
+ declare function generateMnemonic(strength?: number, wordlist?: Wordlist): string;
674
+ /** Validate a mnemonic's checksum and wordlist membership. */
675
+ declare function validateMnemonic(mnemonic: string, wordlist?: Wordlist): boolean;
676
+ /** Recover the raw entropy behind a mnemonic. */
677
+ declare function mnemonicToEntropy(mnemonic: string, wordlist?: Wordlist): Uint8Array;
678
+ /** Encode entropy (16–32 bytes, multiple of 4) as a mnemonic. */
679
+ declare function entropyToMnemonic(entropy: Uint8Array, wordlist?: Wordlist): string;
680
+ /**
681
+ * Expand a mnemonic (with optional passphrase) into the 64-byte BIP39 seed.
682
+ *
683
+ * Checksum-unchecked, by design: derivation does not consult a wordlist, so any
684
+ * phrase of a legal length expands whether or not its words are in a list and
685
+ * whether or not its checksum holds. Use {@link mnemonicToMasterKey} to get the
686
+ * checksum verified first. The word count *is* enforced: BIP39 is defined only
687
+ * for 12, 15, 18, 21 or 24 words.
688
+ *
689
+ * Both failures are checked here rather than caught from `@scure`, and the two
690
+ * checks are exhaustive: `mnemonicToSeedSync` reaches the caller's input only
691
+ * through `nfkd`, which rejects a non-string, and `normalize`, which rejects a
692
+ * word count outside the five. Its salt is `"mnemonic" + passphrase`, a
693
+ * concatenation that always yields a string, and its PBKDF2 parameters are
694
+ * constants — so nothing else in it can throw. Catching instead would report
695
+ * `invalid-mnemonic` for a future `@scure` failure that has nothing to do with
696
+ * the mnemonic, which is the one direction that wastes the most debugging time.
697
+ */
698
+ declare function mnemonicToSeed(mnemonic: string, passphrase?: string): Uint8Array;
699
+ /**
700
+ * Expand a mnemonic straight into a Decred master {@link ExtendedKey}.
701
+ *
702
+ * The mnemonic's checksum is verified first, against `wordlist` (English by
703
+ * default). Because seed derivation consults no wordlist, a typo'd or
704
+ * mis-transcribed phrase of the right length would otherwise expand happily into
705
+ * a different, valid-looking wallet — one of the classic ways to lose funds while
706
+ * every operation appears to succeed.
707
+ *
708
+ * Pass the matching `wordlist` for a non-English phrase; validating a Spanish
709
+ * mnemonic against the English list would reject a perfectly good one. Use
710
+ * {@link mnemonicToSeed} directly if you specifically want the unchecked
711
+ * primitive.
712
+ */
713
+ declare function mnemonicToMasterKey(mnemonic: string, network: Network, passphrase?: string, wordlist?: Wordlist): ExtendedKey;
714
+
715
+ /** Transaction serialization selectors (encoded in the version word). */
716
+ declare enum TxSerializeType {
717
+ Full = 0,
718
+ NoWitness = 1,
719
+ OnlyWitness = 2
720
+ }
721
+ /** Output tree: regular spends vs. the stake tree. */
722
+ declare enum TxTree {
723
+ Regular = 0,
724
+ Stake = 1
725
+ }
726
+ declare const DEFAULT_TX_VERSION = 1;
727
+ declare const MAX_SEQUENCE = 4294967295;
728
+ /**
729
+ * Sentinel "unknown" input amount / block position used for unsigned inputs,
730
+ * matching dcrd's `wire.NullValueIn` / `NullBlockHeight` / `NullBlockIndex`.
731
+ *
732
+ * Note the asymmetry, which is dcrd's and not a typo here: the null block
733
+ * *height* is `0` ("it references the genesis block") while the null block
734
+ * *index* is `0xffffffff`.
735
+ */
736
+ declare const NULL_VALUE_IN = -1n;
737
+ declare const NULL_BLOCK_HEIGHT = 0;
738
+ declare const NULL_BLOCK_INDEX = 4294967295;
739
+ interface OutPoint {
740
+ /** 32-byte transaction hash in internal (serialized) byte order. */
741
+ hash: Uint8Array;
742
+ index: number;
743
+ tree: number;
744
+ }
745
+ interface TxInput {
746
+ previousOutPoint: OutPoint;
747
+ sequence: number;
748
+ valueIn: bigint;
749
+ blockHeight: number;
750
+ blockIndex: number;
751
+ signatureScript: Uint8Array;
752
+ }
753
+ interface TxOutput {
754
+ value: bigint;
755
+ version: number;
756
+ pkScript: Uint8Array;
757
+ }
758
+ /** A mutable Decred transaction. */
759
+ declare class Transaction {
760
+ version: number;
761
+ inputs: TxInput[];
762
+ outputs: TxOutput[];
763
+ lockTime: number;
764
+ expiry: number;
765
+ /**
766
+ * Add an input. Witness fields default to the "unsigned/unknown" sentinels.
767
+ *
768
+ * The outpoint and signature script are copied, so a caller that reuses or
769
+ * scrubs its own buffers afterwards cannot silently rewrite this transaction's
770
+ * bytes — which would change its txid and invalidate every signature already
771
+ * computed over it, with nothing to detect the change.
772
+ */
773
+ addInput(previousOutPoint: OutPoint, opts?: Partial<Omit<TxInput, "previousOutPoint">>): this;
774
+ /** Add an output. The script is copied; see {@link addInput}. */
775
+ addOutput(value: bigint, pkScript: Uint8Array, version?: number): this;
776
+ private writeVersion;
777
+ private writePrefixBody;
778
+ private writeWitnessBody;
779
+ /** Serialize as prefix ‖ witness (the full form). */
780
+ serialize(): Uint8Array;
781
+ /** Serialize the prefix only (no witness). This is what the txid hashes. */
782
+ serializePrefix(): Uint8Array;
783
+ /** Serialize the witness only. */
784
+ serializeWitness(): Uint8Array;
785
+ /** Raw 32-byte prefix hash (internal byte order). */
786
+ hash(): Uint8Array;
787
+ /** The transaction id (reversed-hex display form of the prefix hash). */
788
+ txid(): string;
789
+ /** The witness hash id (display form). */
790
+ witnessTxid(): string;
791
+ /** The full hash id: `blake256(prefixHash ‖ witnessHash)`, display form. */
792
+ fullTxid(): string;
793
+ /**
794
+ * Parse a full (prefix ‖ witness) serialization.
795
+ *
796
+ * The declared input and output counts are deliberately **not** capped, where
797
+ * dcrd's `decodePrefix` and `decodeWitness` reject anything above
798
+ * `maxTxInPerMessage` (780336) or `maxTxOutPerMessage` (3728271) — the counts
799
+ * that could fit a 32 MiB `MaxMessagePayload`. Those bounds exist because dcrd
800
+ * decodes from an `io.Reader` of unknown length and sizes `make([]TxIn, count)`
801
+ * from the count *before* reading an input; here the argument is a `Uint8Array`
802
+ * whose length is already the bound, and nothing is sized from a count —
803
+ * `Reader` checks every read against the bytes that remain, so an inflated
804
+ * count fails at the first short read having allocated nothing. The only
805
+ * observable difference is that a blob of ~43 MiB or larger declaring more than
806
+ * 780336 inputs parses here and does not in dcrd; such a transaction is neither
807
+ * relayable (over `MaxMessagePayload`) nor valid (mainnet `MaxTxSize` is 393216
808
+ * bytes, 115x smaller). On a *truncated* blob both reject, only with different
809
+ * errors: dcrd's `ErrTooManyTxs` against this library's `unexpected-end`.
810
+ *
811
+ * Cost is still linear in `bytes.length`, so cap the size of untrusted input at
812
+ * the call site. dcrd's count limits would not help with that: 32 MiB holds
813
+ * 818400 minimal prefix inputs and the cap is 780336, so a buffer at the wire
814
+ * maximum stays under it.
815
+ */
816
+ static fromBytes(bytes: Uint8Array): Transaction;
817
+ }
818
+ /** Build an OutPoint from a txid *string* (reverses to internal byte order). */
819
+ declare function outPointFromTxid(txid: string, index: number, tree?: TxTree): OutPoint;
820
+
821
+ declare enum SigHashType {
822
+ All = 1,
823
+ None = 2,
824
+ Single = 3,
825
+ AnyOneCanPay = 128
826
+ }
827
+ /**
828
+ * True when `hashType` is one dcrd's script engine will accept, i.e. the six
829
+ * values `CheckHashTypeEncoding` permits: All/None/Single, each optionally
830
+ * OR'ed with AnyOneCanPay.
831
+ *
832
+ * Note {@link calcSignatureHash} deliberately still computes a hash for other
833
+ * byte values, because dcrd's `calcSignatureHash` does — undefined types hash as
834
+ * if they were All. Validation belongs at the point a signature is *produced*,
835
+ * which is where {@link assertSignableSigHashType} is applied.
836
+ */
837
+ declare function isSignableSigHashType(hashType: number): boolean;
838
+ /** Throw unless `hashType` is one dcrd's engine accepts. */
839
+ declare function assertSignableSigHashType(hashType: number): void;
840
+ /**
841
+ * The reusable prefix hash for `SigHashAll` without `AnyOneCanPay`.
842
+ *
843
+ * Under that hash type the prefix half of the signature hash does not depend on
844
+ * which input is being signed, and its serialization is byte-identical to the
845
+ * transaction's own prefix serialization — `SigHashSerializePrefix` and
846
+ * `TxSerializeNoWitness` are both `1`, and the bodies are the same. So this is
847
+ * exactly `tx.hash()`, and passing it to {@link calcSignatureHash} as
848
+ * `cachedPrefix` removes the dominant per-input cost when signing.
849
+ *
850
+ * It does **not** make signing linear. The witness half still walks every input
851
+ * on each call (one varint apiece), so signing N inputs stays O(N²) — but the
852
+ * prefix half is the expensive one, since it re-serializes every outpoint and
853
+ * every output script, so the constant drops by more than an order of magnitude.
854
+ * Measured on the hashing alone: 12x at 50 inputs, 26x at 500.
855
+ *
856
+ * This is what dcrd's `cachedPrefix` parameter exists for.
857
+ */
858
+ declare function sigHashPrefixAll(tx: Transaction): Uint8Array;
859
+ /**
860
+ * Compute the signature hash for input `idx` of `tx` under `hashType`, with
861
+ * `subScript` as the script being satisfied (the prevout pkScript for P2PKH, or
862
+ * the redeem script for P2SH). Returns the 32-byte hash to be signed.
863
+ *
864
+ * `cachedPrefix` is an optional pre-computed prefix hash from
865
+ * {@link sigHashPrefixAll}, honoured only for `SigHashAll` without
866
+ * `AnyOneCanPay` — the one case where the prefix half is input-independent. It is
867
+ * ignored for every other hash type rather than trusted, so it is safe to pass
868
+ * for *any hash type*.
869
+ *
870
+ * It is **not** checked against `tx`, because a 32-byte hash carries nothing to
871
+ * check it with: it must be this transaction's current prefix hash. Passing a
872
+ * stale one — taken before the prefix was changed, or from a different
873
+ * transaction — silently produces a signature over the wrong message. Take it
874
+ * from the transaction you are about to sign, after the prefix is final, or use
875
+ * {@link signP2PKHInputs}, which does that for you.
876
+ */
877
+ declare function calcSignatureHash(subScript: Uint8Array, hashType: SigHashType | number, tx: Transaction, idx: number, cachedPrefix?: Uint8Array): Uint8Array;
878
+
879
+ /** DER-encode a deterministic low-S ECDSA signature over a 32-byte hash. */
880
+ declare function signHash(hash: Uint8Array, privateKey: Uint8Array): Uint8Array;
881
+ /**
882
+ * Verify a **DER** signature over a 32-byte hash against a public key.
883
+ *
884
+ * Strictly DER, and low-S. `@noble`'s `verify` falls back to the 64-byte compact
885
+ * `r ‖ s` encoding when DER parsing fails, so without parsing the DER ourselves
886
+ * first this would accept a signature encoding dcrd's script engine rejects — a
887
+ * co-signer or hardware device emitting compact signatures would pass local
888
+ * validation and then fail consensus.
889
+ */
890
+ declare function verifyHash(hash: Uint8Array, derSignature: Uint8Array, publicKey: Uint8Array): boolean;
891
+ /**
892
+ * Produce the raw signature for input `idx`: the DER signature over the Decred
893
+ * signature hash with the one-byte hash type appended (as it appears in a
894
+ * signature script and in a signature stack element).
895
+ */
896
+ declare function rawTxInSignature(tx: Transaction, idx: number, subScript: Uint8Array, hashType: SigHashType | number, privateKey: Uint8Array, cachedPrefix?: Uint8Array): Uint8Array;
897
+ /**
898
+ * Build the full P2PKH signature script for input `idx`:
899
+ * `push(<DER-sig ‖ hashType>) push(<pubkey>)`.
900
+ */
901
+ declare function signatureScript(tx: Transaction, idx: number, subScript: Uint8Array, hashType: SigHashType | number, privateKey: Uint8Array, compressed?: boolean, cachedPrefix?: Uint8Array): Uint8Array;
902
+ /**
903
+ * Sign input `idx` in place: compute and assign its P2PKH signature script.
904
+ * Returns the signed transaction for chaining.
905
+ *
906
+ * For a transaction with several inputs prefer {@link signP2PKHInputs}, which
907
+ * reuses one prefix hash instead of recomputing it per input.
908
+ */
909
+ declare function signP2PKHInput(tx: Transaction, idx: number, subScript: Uint8Array, privateKey: Uint8Array, hashType?: SigHashType | number, compressed?: boolean): Transaction;
910
+ /** One input to sign, for {@link signP2PKHInputs}. */
911
+ interface P2PKHInputToSign {
912
+ /** Index into `tx.inputs`. */
913
+ idx: number;
914
+ /** The script being satisfied — the prevout pkScript for P2PKH. */
915
+ subScript: Uint8Array;
916
+ privateKey: Uint8Array;
917
+ /** Serialize the public key compressed (the default). */
918
+ compressed?: boolean;
919
+ }
920
+ /**
921
+ * Sign several P2PKH inputs in place, reusing one prefix hash.
922
+ *
923
+ * `calcSignatureHash` re-serializes and re-hashes the whole transaction prefix on
924
+ * every call — every outpoint and every output script — which is the dominant
925
+ * cost for a transaction with many inputs. Under `SigHashAll` without
926
+ * `AnyOneCanPay` that half is input-independent, so it is computed once here and
927
+ * reused, which is what dcrd's `cachedPrefix` parameter is for.
928
+ *
929
+ * This lowers the constant, not the exponent: the witness half still walks every
930
+ * input per call, so signing stays O(N²). On the hashing alone it measured 12x at
931
+ * 50 inputs and 26x at 500; end to end the gain is smaller (1.7x at 250) because
932
+ * ECDSA dominates.
933
+ *
934
+ * The prefix hash is taken **before** any signature script is assigned, which is
935
+ * also why this is correct: the prefix commits to no witness data, so writing
936
+ * signature scripts cannot invalidate it. For other hash types the cache is
937
+ * ignored and each input is hashed independently, so passing one is always safe.
938
+ */
939
+ declare function signP2PKHInputs(tx: Transaction, toSign: readonly P2PKHInputToSign[], hashType?: SigHashType | number): Transaction;
940
+
941
+ /** Atoms in one DCR. */
942
+ declare const ATOMS_PER_COIN = 100000000n;
943
+ /** Decimal places in a DCR amount. */
944
+ declare const COIN_DECIMALS = 8;
945
+ /**
946
+ * Parse a decimal DCR string (e.g. "1.5", "-0.00000001") into atoms.
947
+ * Accepts up to 8 fractional digits; more is an error.
948
+ */
949
+ declare function dcrToAtoms(dcr: string): bigint;
950
+ /**
951
+ * Format atoms as a fixed 8-decimal DCR string (e.g. 150000000n → "1.50000000").
952
+ */
953
+ declare function atomsToDcr(atoms: bigint): string;
954
+
955
+ export { ATOMS_PER_COIN, type AddressKind, BLAKE256_BLOCK_LENGTH, BLAKE256_DIGEST_LENGTH, Blake256, COIN_DECIMALS, CURVE_ORDER, DEFAULT_TX_VERSION, DcrError, type DcrErrorCode, type DecodedAddress, type DecodedWif, ExtendedKey, HARDENED_OFFSET, type HashAddressKind, MAX_ADDRESS_LENGTH, MAX_EXTENDED_KEY_LENGTH, MAX_SCRIPT_ELEMENT_SIZE, MAX_SEQUENCE, MAX_WIF_LENGTH, NULL_BLOCK_HEIGHT, NULL_BLOCK_INDEX, NULL_VALUE_IN, type Network, type NetworkName, OP, type OutPoint, type P2PKHInputToSign, type PubKeyAddressKind, Reader, type ScriptKind, SigHashType, SignatureType, Transaction, type TxInput, type TxOutput, TxSerializeType, TxTree, type Wordlist, Writer, addressFromPubKey, addressFromScript, addressToScript, assertCompressedPubKey, assertPrivateKey, assertPubKey, assertSignableSigHashType, atomsToDcr, base58Decode, base58Encode, blake256, calcSignatureHash, checkDecode, checkEncode, classifyScript, copyOf, dcrToAtoms, decodeAddress, decodeWif, encodeWif, englishWordlist, entropyToMnemonic, extractHash160, generateMnemonic, hardened, hasErrorCode, hash160, hash256, isDcrError, isPayToPubKeyHash, isPayToScriptHash, isSignableSigHashType, isValidAddress, isValidEd25519PublicKey, isValidPrivateKey, isValidPublicKey, mainnet, maxBase58Length, mnemonicToEntropy, mnemonicToMasterKey, mnemonicToSeed, networks, outPointFromTxid, payToPubKeyAltScript, payToPubKeyHashAltScript, payToPubKeyHashScript, payToPubKeyScript, payToScriptHashScript, pubKeyAddress, pubKeyEd25519Address, pubKeyHashAddress, pubKeyHashEd25519Address, pubKeyHashSchnorrAddress, pubKeySchnorrAddress, publicKeyFromPrivate, pushData, rawTxInSignature, regnet, scriptHashAddress, scriptParses, sigHashPrefixAll, signHash, signP2PKHInput, signP2PKHInputs, signatureScript, simnet, testnet3, validateMnemonic, verifyHash };