@scure/btc-signer 1.5.0 → 1.6.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 +5 -2
- package/_type_test.js +2 -2
- package/_type_test.js.map +1 -1
- package/esm/_type_test.js +2 -2
- package/esm/_type_test.js.map +1 -1
- package/esm/index.d.ts +8 -6
- package/esm/index.d.ts.map +1 -1
- package/esm/index.js +7 -10
- package/esm/index.js.map +1 -1
- package/esm/payment.d.ts +43 -76
- package/esm/payment.d.ts.map +1 -1
- package/esm/payment.js +15 -2
- package/esm/payment.js.map +1 -1
- package/esm/psbt.d.ts +1 -1
- package/esm/psbt.d.ts.map +1 -1
- package/esm/psbt.js +2 -3
- package/esm/psbt.js.map +1 -1
- package/esm/script.d.ts +3 -1
- package/esm/script.d.ts.map +1 -1
- package/esm/script.js.map +1 -1
- package/esm/transaction.d.ts +10 -121
- package/esm/transaction.d.ts.map +1 -1
- package/esm/transaction.js +5 -6
- package/esm/transaction.js.map +1 -1
- package/esm/utils.d.ts +17 -12
- package/esm/utils.d.ts.map +1 -1
- package/esm/utils.js +6 -4
- package/esm/utils.js.map +1 -1
- package/esm/utxo.d.ts +23 -21
- package/esm/utxo.d.ts.map +1 -1
- package/esm/utxo.js +5 -5
- package/esm/utxo.js.map +1 -1
- package/index.d.ts +8 -6
- package/index.d.ts.map +1 -1
- package/index.js +20 -22
- package/index.js.map +1 -1
- package/package.json +16 -12
- package/payment.d.ts +43 -76
- package/payment.d.ts.map +1 -1
- package/payment.js +14 -1
- package/payment.js.map +1 -1
- package/psbt.d.ts +1 -1
- package/psbt.d.ts.map +1 -1
- package/psbt.js +5 -6
- package/psbt.js.map +1 -1
- package/script.d.ts +3 -1
- package/script.d.ts.map +1 -1
- package/script.js.map +1 -1
- package/src/_type_test.ts +2 -2
- package/src/index.ts +25 -14
- package/src/payment.ts +74 -27
- package/src/psbt.ts +27 -11
- package/src/script.ts +5 -5
- package/src/transaction.ts +47 -34
- package/src/utils.ts +26 -16
- package/src/utxo.ts +29 -17
- package/transaction.d.ts +10 -121
- package/transaction.d.ts.map +1 -1
- package/transaction.js +14 -15
- package/transaction.js.map +1 -1
- package/utils.d.ts +17 -12
- package/utils.d.ts.map +1 -1
- package/utils.js +6 -4
- package/utils.js.map +1 -1
- package/utxo.d.ts +23 -21
- package/utxo.d.ts.map +1 -1
- package/utxo.js +3 -3
- package/utxo.js.map +1 -1
package/src/transaction.ts
CHANGED
|
@@ -1,12 +1,19 @@
|
|
|
1
|
-
import * as P from 'micro-packed';
|
|
2
1
|
import { hex } from '@scure/base';
|
|
3
|
-
import
|
|
2
|
+
import * as P from 'micro-packed';
|
|
3
|
+
import { Address, type CustomScript, OutScript, checkScript, tapLeafHash } from './payment.js';
|
|
4
4
|
import * as psbt from './psbt.js'; // circular
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
import {
|
|
6
|
+
CompactSizeLen,
|
|
7
|
+
RawOldTx,
|
|
8
|
+
RawOutput,
|
|
9
|
+
RawTx,
|
|
10
|
+
RawWitness,
|
|
11
|
+
Script,
|
|
12
|
+
VarBytes,
|
|
13
|
+
} from './script.js';
|
|
8
14
|
import * as u from './utils.js';
|
|
9
|
-
import {
|
|
15
|
+
import { type Bytes, NETWORK, concatBytes, equalBytes, isBytes } from './utils.js';
|
|
16
|
+
import { getInputType, getPrevOut, normalizeInput, toVsize } from './utxo.js'; // circular
|
|
10
17
|
|
|
11
18
|
const EMPTY32 = new Uint8Array(32);
|
|
12
19
|
const EMPTY_OUTPUT: P.UnwrapCoder<typeof RawOutput> = {
|
|
@@ -30,10 +37,10 @@ export const PRECISION = 8;
|
|
|
30
37
|
export const DEFAULT_VERSION = 2;
|
|
31
38
|
export const DEFAULT_LOCKTIME = 0;
|
|
32
39
|
export const DEFAULT_SEQUENCE = 4294967295;
|
|
33
|
-
export const Decimal = P.coders.decimal(PRECISION);
|
|
40
|
+
export const Decimal: P.Coder<bigint, string> = P.coders.decimal(PRECISION);
|
|
34
41
|
|
|
35
42
|
// Same as value || def, but doesn't overwrites zero ('0', 0, 0n, etc)
|
|
36
|
-
export const def = <T>(value: T | undefined, def: T) => (value === undefined ? def : value);
|
|
43
|
+
export const def = <T>(value: T | undefined, def: T): T => (value === undefined ? def : value);
|
|
37
44
|
|
|
38
45
|
export function cloneDeep<T>(obj: T): T {
|
|
39
46
|
if (Array.isArray(obj)) return obj.map((i) => cloneDeep(i)) as unknown as T;
|
|
@@ -166,7 +173,7 @@ function unpackSighash(hashType: number) {
|
|
|
166
173
|
};
|
|
167
174
|
}
|
|
168
175
|
|
|
169
|
-
function validateOpts(opts: TxOpts) {
|
|
176
|
+
function validateOpts(opts: TxOpts): Readonly<TxOpts> {
|
|
170
177
|
if (opts !== undefined && {}.toString.call(opts) !== '[object Object]')
|
|
171
178
|
throw new Error(`Wrong object type for transaction options: ${opts}`);
|
|
172
179
|
|
|
@@ -182,7 +189,8 @@ function validateOpts(opts: TxOpts) {
|
|
|
182
189
|
if (typeof _opts.allowUnknowOutput !== 'undefined')
|
|
183
190
|
opts.allowUnknownOutputs = _opts.allowUnknowOutput;
|
|
184
191
|
// 0 and -1 happens in tests
|
|
185
|
-
if (![-1, 0, 1, 2].includes(_opts.version))
|
|
192
|
+
if (![-1, 0, 1, 2, 3].includes(_opts.version))
|
|
193
|
+
throw new Error(`Unknown version: ${_opts.version}`);
|
|
186
194
|
if (typeof _opts.lockTime !== 'number') throw new Error('Transaction lock time should be number');
|
|
187
195
|
P.U32LE.encode(_opts.lockTime); // Additional range checks that lockTime
|
|
188
196
|
// There is no PSBT v1, and any new version will probably have fields which we don't know how to parse, which
|
|
@@ -233,7 +241,7 @@ export class Transaction {
|
|
|
233
241
|
}
|
|
234
242
|
|
|
235
243
|
// Import
|
|
236
|
-
static fromRaw(raw: Bytes, opts: TxOpts = {}) {
|
|
244
|
+
static fromRaw(raw: Bytes, opts: TxOpts = {}): Transaction {
|
|
237
245
|
const parsed = RawTx.decode(raw);
|
|
238
246
|
const tx = new Transaction({ ...opts, version: parsed.version, lockTime: parsed.lockTime });
|
|
239
247
|
for (const o of parsed.outputs) tx.addOutput(o);
|
|
@@ -246,7 +254,7 @@ export class Transaction {
|
|
|
246
254
|
return tx;
|
|
247
255
|
}
|
|
248
256
|
// PSBT
|
|
249
|
-
static fromPSBT(psbt_: Bytes, opts: TxOpts = {}) {
|
|
257
|
+
static fromPSBT(psbt_: Bytes, opts: TxOpts = {}): Transaction {
|
|
250
258
|
let parsed: P.UnwrapCoder<typeof psbt.RawPSBTV0>;
|
|
251
259
|
try {
|
|
252
260
|
parsed = psbt.RawPSBTV0.decode(psbt_);
|
|
@@ -281,7 +289,7 @@ export class Transaction {
|
|
|
281
289
|
if (lockTime !== DEFAULT_LOCKTIME) tx.global.fallbackLocktime = lockTime;
|
|
282
290
|
return tx;
|
|
283
291
|
}
|
|
284
|
-
toPSBT(PSBTVersion = this.opts.PSBTVersion) {
|
|
292
|
+
toPSBT(PSBTVersion: number | undefined = this.opts.PSBTVersion): Uint8Array {
|
|
285
293
|
if (PSBTVersion !== 0 && PSBTVersion !== 2)
|
|
286
294
|
throw new Error(`Wrong PSBT version=${PSBTVersion}`);
|
|
287
295
|
// if (PSBTVersion === 0 && this.inputs.length === 0) {
|
|
@@ -338,7 +346,7 @@ export class Transaction {
|
|
|
338
346
|
}
|
|
339
347
|
|
|
340
348
|
// BIP370 lockTime (https://github.com/bitcoin/bips/blob/master/bip-0370.mediawiki#determining-lock-time)
|
|
341
|
-
get lockTime() {
|
|
349
|
+
get lockTime(): number {
|
|
342
350
|
let height = DEFAULT_LOCKTIME;
|
|
343
351
|
let heightCnt = 0;
|
|
344
352
|
let time = DEFAULT_LOCKTIME;
|
|
@@ -358,7 +366,7 @@ export class Transaction {
|
|
|
358
366
|
return this.global.fallbackLocktime || DEFAULT_LOCKTIME;
|
|
359
367
|
}
|
|
360
368
|
|
|
361
|
-
get version() {
|
|
369
|
+
get version(): number {
|
|
362
370
|
// Should be not possible
|
|
363
371
|
if (this.global.txVersion === undefined) throw new Error('No global.txVersion');
|
|
364
372
|
return this.global.txVersion;
|
|
@@ -419,7 +427,7 @@ export class Transaction {
|
|
|
419
427
|
return { addInput, addOutput, inputs, outputs };
|
|
420
428
|
}
|
|
421
429
|
|
|
422
|
-
get isFinal() {
|
|
430
|
+
get isFinal(): boolean {
|
|
423
431
|
for (let idx = 0; idx < this.inputs.length; idx++)
|
|
424
432
|
if (this.inputStatus(idx) !== 'finalized') return false;
|
|
425
433
|
return true;
|
|
@@ -453,7 +461,7 @@ export class Transaction {
|
|
|
453
461
|
get vsize(): number {
|
|
454
462
|
return toVsize(this.weight);
|
|
455
463
|
}
|
|
456
|
-
toBytes(withScriptSig = false, withWitness = false) {
|
|
464
|
+
toBytes(withScriptSig = false, withWitness = false): Uint8Array {
|
|
457
465
|
return RawTx.encode({
|
|
458
466
|
version: this.version,
|
|
459
467
|
lockTime: this.lockTime,
|
|
@@ -469,15 +477,15 @@ export class Transaction {
|
|
|
469
477
|
get unsignedTx(): Bytes {
|
|
470
478
|
return this.toBytes(false, false);
|
|
471
479
|
}
|
|
472
|
-
get hex() {
|
|
480
|
+
get hex(): string {
|
|
473
481
|
return hex.encode(this.toBytes(true, this.hasWitnesses));
|
|
474
482
|
}
|
|
475
483
|
|
|
476
|
-
get hash() {
|
|
484
|
+
get hash(): string {
|
|
477
485
|
if (!this.isFinal) throw new Error('Transaction is not finalized');
|
|
478
486
|
return hex.encode(u.sha256x2(this.toBytes(true)));
|
|
479
487
|
}
|
|
480
|
-
get id() {
|
|
488
|
+
get id(): string {
|
|
481
489
|
if (!this.isFinal) throw new Error('Transaction is not finalized');
|
|
482
490
|
return hex.encode(u.sha256x2(this.toBytes(true)).reverse());
|
|
483
491
|
}
|
|
@@ -486,11 +494,11 @@ export class Transaction {
|
|
|
486
494
|
if (!Number.isSafeInteger(idx) || 0 > idx || idx >= this.inputs.length)
|
|
487
495
|
throw new Error(`Wrong input index=${idx}`);
|
|
488
496
|
}
|
|
489
|
-
getInput(idx: number) {
|
|
497
|
+
getInput(idx: number): psbt.TransactionInput {
|
|
490
498
|
this.checkInputIdx(idx);
|
|
491
499
|
return cloneDeep(this.inputs[idx]);
|
|
492
500
|
}
|
|
493
|
-
get inputsLength() {
|
|
501
|
+
get inputsLength(): number {
|
|
494
502
|
return this.inputs.length;
|
|
495
503
|
}
|
|
496
504
|
// Modification
|
|
@@ -500,7 +508,7 @@ export class Transaction {
|
|
|
500
508
|
this.inputs.push(normalizeInput(input, undefined, undefined, this.opts.disableScriptCheck));
|
|
501
509
|
return this.inputs.length - 1;
|
|
502
510
|
}
|
|
503
|
-
updateInput(idx: number, input: psbt.TransactionInputUpdate, _ignoreSignStatus = false) {
|
|
511
|
+
updateInput(idx: number, input: psbt.TransactionInputUpdate, _ignoreSignStatus = false): void {
|
|
504
512
|
this.checkInputIdx(idx);
|
|
505
513
|
let allowedFields = undefined;
|
|
506
514
|
if (!_ignoreSignStatus) {
|
|
@@ -520,17 +528,17 @@ export class Transaction {
|
|
|
520
528
|
if (!Number.isSafeInteger(idx) || 0 > idx || idx >= this.outputs.length)
|
|
521
529
|
throw new Error(`Wrong output index=${idx}`);
|
|
522
530
|
}
|
|
523
|
-
getOutput(idx: number) {
|
|
531
|
+
getOutput(idx: number): psbt.TransactionOutput {
|
|
524
532
|
this.checkOutputIdx(idx);
|
|
525
533
|
return cloneDeep(this.outputs[idx]);
|
|
526
534
|
}
|
|
527
|
-
getOutputAddress(idx: number, network = NETWORK): string | undefined {
|
|
535
|
+
getOutputAddress(idx: number, network: u.BTC_NETWORK = NETWORK): string | undefined {
|
|
528
536
|
const out = this.getOutput(idx);
|
|
529
537
|
if (!out.script) return;
|
|
530
538
|
return Address(network).encode(OutScript.decode(out.script));
|
|
531
539
|
}
|
|
532
540
|
|
|
533
|
-
get outputsLength() {
|
|
541
|
+
get outputsLength(): number {
|
|
534
542
|
return this.outputs.length;
|
|
535
543
|
}
|
|
536
544
|
private normalizeOutput(
|
|
@@ -568,7 +576,7 @@ export class Transaction {
|
|
|
568
576
|
this.outputs.push(this.normalizeOutput(o));
|
|
569
577
|
return this.outputs.length - 1;
|
|
570
578
|
}
|
|
571
|
-
updateOutput(idx: number, output: psbt.TransactionOutputUpdate, _ignoreSignStatus = false) {
|
|
579
|
+
updateOutput(idx: number, output: psbt.TransactionOutputUpdate, _ignoreSignStatus = false): void {
|
|
572
580
|
this.checkOutputIdx(idx);
|
|
573
581
|
let allowedFields = undefined;
|
|
574
582
|
if (!_ignoreSignStatus) {
|
|
@@ -578,7 +586,7 @@ export class Transaction {
|
|
|
578
586
|
}
|
|
579
587
|
this.outputs[idx] = this.normalizeOutput(output, this.outputs[idx], allowedFields);
|
|
580
588
|
}
|
|
581
|
-
addOutputAddress(address: string, amount: bigint, network = NETWORK): number {
|
|
589
|
+
addOutputAddress(address: string, amount: bigint, network: u.BTC_NETWORK = NETWORK): number {
|
|
582
590
|
return this.addOutput({ script: OutScript.encode(Address(network).decode(address)), amount });
|
|
583
591
|
}
|
|
584
592
|
// Utils
|
|
@@ -633,7 +641,12 @@ export class Transaction {
|
|
|
633
641
|
});
|
|
634
642
|
return u.sha256x2(tmpTx, P.I32LE.encode(hashType));
|
|
635
643
|
}
|
|
636
|
-
preimageWitnessV0(
|
|
644
|
+
preimageWitnessV0(
|
|
645
|
+
idx: number,
|
|
646
|
+
prevOutScript: Bytes,
|
|
647
|
+
hashType: number,
|
|
648
|
+
amount: bigint
|
|
649
|
+
): Uint8Array {
|
|
637
650
|
const { isAny, isNone, isSingle } = unpackSighash(hashType);
|
|
638
651
|
let inputHash = EMPTY32;
|
|
639
652
|
let sequenceHash = EMPTY32;
|
|
@@ -671,7 +684,7 @@ export class Transaction {
|
|
|
671
684
|
leafScript?: Bytes,
|
|
672
685
|
leafVer = 0xc0,
|
|
673
686
|
annex?: Bytes
|
|
674
|
-
) {
|
|
687
|
+
): Uint8Array {
|
|
675
688
|
if (!Array.isArray(amount) || this.inputs.length !== amount.length)
|
|
676
689
|
throw new Error(`Invalid amounts array=${amount}`);
|
|
677
690
|
if (!Array.isArray(prevOutScript) || this.inputs.length !== prevOutScript.length)
|
|
@@ -878,7 +891,7 @@ export class Transaction {
|
|
|
878
891
|
return num;
|
|
879
892
|
}
|
|
880
893
|
|
|
881
|
-
finalizeIdx(idx: number) {
|
|
894
|
+
finalizeIdx(idx: number): void {
|
|
882
895
|
this.checkInputIdx(idx);
|
|
883
896
|
if (this.fee < 0n) throw new Error('Outputs spends more than inputs amount');
|
|
884
897
|
const input = this.inputs[idx];
|
|
@@ -1027,10 +1040,10 @@ export class Transaction {
|
|
|
1027
1040
|
if (finalScriptWitness) input.finalScriptWitness = finalScriptWitness;
|
|
1028
1041
|
cleanFinalInput(input);
|
|
1029
1042
|
}
|
|
1030
|
-
finalize() {
|
|
1043
|
+
finalize(): void {
|
|
1031
1044
|
for (let i = 0; i < this.inputs.length; i++) this.finalizeIdx(i);
|
|
1032
1045
|
}
|
|
1033
|
-
extract() {
|
|
1046
|
+
extract(): Uint8Array {
|
|
1034
1047
|
if (!this.isFinal) throw new Error('Transaction has unfinalized inputs');
|
|
1035
1048
|
if (!this.outputs.length) throw new Error('Transaction has no outputs');
|
|
1036
1049
|
if (this.fee < 0n) throw new Error('Outputs spends more than inputs amount');
|
|
@@ -1062,7 +1075,7 @@ export class Transaction {
|
|
|
1062
1075
|
for (let i = 0; i < this.outputs.length; i++) this.updateOutput(i, other.outputs[i], true);
|
|
1063
1076
|
return this;
|
|
1064
1077
|
}
|
|
1065
|
-
clone() {
|
|
1078
|
+
clone(): Transaction {
|
|
1066
1079
|
// deepClone probably faster, but this enforces that encoding is valid
|
|
1067
1080
|
return Transaction.fromPSBT(this.toPSBT(this.opts.PSBTVersion), this.opts);
|
|
1068
1081
|
}
|
package/src/utils.ts
CHANGED
|
@@ -1,20 +1,24 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { schnorr, secp256k1 as secp } from '@noble/curves/secp256k1';
|
|
2
2
|
import { ripemd160 } from '@noble/hashes/ripemd160';
|
|
3
3
|
import { sha256 } from '@noble/hashes/sha256';
|
|
4
|
-
import {
|
|
4
|
+
import { utils as packedUtils, U32LE } from 'micro-packed';
|
|
5
5
|
|
|
6
|
+
export type Hex = string | Uint8Array;
|
|
6
7
|
export type Bytes = Uint8Array;
|
|
7
8
|
const Point = secp.ProjectivePoint;
|
|
8
9
|
const CURVE_ORDER = secp.CURVE.n;
|
|
9
10
|
|
|
10
|
-
const
|
|
11
|
-
|
|
11
|
+
const isBytes: (a: unknown) => a is Uint8Array = packedUtils.isBytes;
|
|
12
|
+
const concatBytes: (...arrays: Uint8Array[]) => Uint8Array = packedUtils.concatBytes;
|
|
13
|
+
const equalBytes: (a: Uint8Array, b: Uint8Array) => boolean = packedUtils.equalBytes;
|
|
14
|
+
export { concatBytes, equalBytes, isBytes, sha256 };
|
|
12
15
|
|
|
13
|
-
export const hash160 = (msg:
|
|
14
|
-
export const sha256x2 = (...msgs:
|
|
15
|
-
export const randomPrivateKeyBytes = schnorr.utils.randomPrivateKey;
|
|
16
|
+
export const hash160 = (msg: Uint8Array): Uint8Array => ripemd160(sha256(msg));
|
|
17
|
+
export const sha256x2 = (...msgs: Uint8Array[]): Uint8Array => sha256(sha256(concatBytes(...msgs)));
|
|
18
|
+
export const randomPrivateKeyBytes: () => Uint8Array = schnorr.utils.randomPrivateKey;
|
|
16
19
|
export const pubSchnorr = schnorr.getPublicKey as (priv: string | Uint8Array) => Uint8Array;
|
|
17
|
-
export const pubECDSA =
|
|
20
|
+
export const pubECDSA: (privateKey: string | Uint8Array, isCompressed?: boolean) => Uint8Array =
|
|
21
|
+
secp.getPublicKey;
|
|
18
22
|
|
|
19
23
|
// low-r signature grinding. Used to reduce tx size by 1 byte.
|
|
20
24
|
// noble/secp256k1 does not support the feature: it is not used outside of BTC.
|
|
@@ -35,8 +39,8 @@ export function signECDSA(hash: Bytes, privateKey: Bytes, lowR = false): Bytes {
|
|
|
35
39
|
return sig.toDERRawBytes();
|
|
36
40
|
}
|
|
37
41
|
|
|
38
|
-
export const signSchnorr = schnorr.sign;
|
|
39
|
-
export const tagSchnorr = schnorr.utils.taggedHash;
|
|
42
|
+
export const signSchnorr: typeof schnorr.sign = schnorr.sign;
|
|
43
|
+
export const tagSchnorr: typeof schnorr.utils.taggedHash = schnorr.utils.taggedHash;
|
|
40
44
|
|
|
41
45
|
export enum PubT {
|
|
42
46
|
ecdsa,
|
|
@@ -65,7 +69,7 @@ export function tapTweak(a: Bytes, b: Bytes): bigint {
|
|
|
65
69
|
return tn;
|
|
66
70
|
}
|
|
67
71
|
|
|
68
|
-
export function taprootTweakPrivKey(privKey:
|
|
72
|
+
export function taprootTweakPrivKey(privKey: Bytes, merkleRoot: Bytes = new Uint8Array()): Bytes {
|
|
69
73
|
const u = schnorr.utils;
|
|
70
74
|
const seckey0 = u.bytesToNumberBE(privKey); // seckey0 = int_from_bytes(seckey0)
|
|
71
75
|
const P = Point.fromPrivateKey(seckey0); // P = point_mul(G, seckey0)
|
|
@@ -78,7 +82,7 @@ export function taprootTweakPrivKey(privKey: Uint8Array, merkleRoot = new Uint8A
|
|
|
78
82
|
return u.numberToBytesBE(u.mod(seckey + t, CURVE_ORDER), 32);
|
|
79
83
|
}
|
|
80
84
|
|
|
81
|
-
export function taprootTweakPubkey(pubKey:
|
|
85
|
+
export function taprootTweakPubkey(pubKey: Bytes, h: Bytes): [Bytes, number] {
|
|
82
86
|
const u = schnorr.utils;
|
|
83
87
|
const t = tapTweak(pubKey, h); // t = int_from_bytes(tagged_hash("TapTweak", pubkey + h))
|
|
84
88
|
const P = u.lift_x(u.bytesToNumberBE(pubKey)); // P = lift_x(int_from_bytes(pubkey))
|
|
@@ -93,16 +97,22 @@ export function taprootTweakPubkey(pubKey: Uint8Array, h: Uint8Array): [Uint8Arr
|
|
|
93
97
|
// It is possible to switch SECP256K1_GENERATOR_POINT with some random point;
|
|
94
98
|
// but it's too complex to prove.
|
|
95
99
|
// Also used by bitcoin-core and bitcoinjs-lib
|
|
96
|
-
export const TAPROOT_UNSPENDABLE_KEY = sha256(Point.BASE.toRawBytes(false));
|
|
100
|
+
export const TAPROOT_UNSPENDABLE_KEY: Bytes = sha256(Point.BASE.toRawBytes(false));
|
|
97
101
|
|
|
98
|
-
export
|
|
102
|
+
export type BTC_NETWORK = {
|
|
103
|
+
bech32: string;
|
|
104
|
+
pubKeyHash: number;
|
|
105
|
+
scriptHash: number;
|
|
106
|
+
wif: number;
|
|
107
|
+
};
|
|
108
|
+
export const NETWORK: BTC_NETWORK = {
|
|
99
109
|
bech32: 'bc',
|
|
100
110
|
pubKeyHash: 0x00,
|
|
101
111
|
scriptHash: 0x05,
|
|
102
112
|
wif: 0x80,
|
|
103
113
|
};
|
|
104
114
|
|
|
105
|
-
export const TEST_NETWORK:
|
|
115
|
+
export const TEST_NETWORK: BTC_NETWORK = {
|
|
106
116
|
bech32: 'tb',
|
|
107
117
|
pubKeyHash: 0x6f,
|
|
108
118
|
scriptHash: 0xc4,
|
|
@@ -110,7 +120,7 @@ export const TEST_NETWORK: typeof NETWORK = {
|
|
|
110
120
|
};
|
|
111
121
|
|
|
112
122
|
// Exported for tests, internal method
|
|
113
|
-
export function compareBytes(a: Bytes, b: Bytes) {
|
|
123
|
+
export function compareBytes(a: Bytes, b: Bytes): number {
|
|
114
124
|
if (!isBytes(a) || !isBytes(b)) throw new Error(`cmp: wrong type a=${typeof a} b=${typeof b}`);
|
|
115
125
|
// -1 -> a<b, 0 -> a==b, 1 -> a>b
|
|
116
126
|
const len = Math.min(a.length, b.length);
|
package/src/utxo.ts
CHANGED
|
@@ -1,25 +1,28 @@
|
|
|
1
1
|
import { hex } from '@scure/base';
|
|
2
2
|
import * as P from 'micro-packed';
|
|
3
|
-
import { Address, CustomScript, OutScript, checkScript, tapLeafHash } from './payment.js';
|
|
3
|
+
import { Address, type CustomScript, OutScript, checkScript, tapLeafHash } from './payment.js';
|
|
4
4
|
import * as psbt from './psbt.js';
|
|
5
5
|
import { CompactSizeLen, RawOutput, RawTx, RawWitness, Script, VarBytes } from './script.js';
|
|
6
6
|
import {
|
|
7
7
|
DEFAULT_SEQUENCE,
|
|
8
|
-
TxOpts,
|
|
9
|
-
inputBeforeSign,
|
|
10
8
|
SignatureHash,
|
|
11
9
|
Transaction,
|
|
10
|
+
type TxOpts,
|
|
11
|
+
inputBeforeSign,
|
|
12
12
|
} from './transaction.js'; // circular
|
|
13
13
|
import {
|
|
14
|
+
type Bytes,
|
|
14
15
|
NETWORK,
|
|
15
|
-
|
|
16
|
+
PubT,
|
|
17
|
+
TAPROOT_UNSPENDABLE_KEY,
|
|
16
18
|
compareBytes,
|
|
17
19
|
equalBytes,
|
|
18
20
|
isBytes,
|
|
19
|
-
TAPROOT_UNSPENDABLE_KEY,
|
|
20
21
|
sha256,
|
|
22
|
+
validatePubkey,
|
|
21
23
|
} from './utils.js';
|
|
22
|
-
|
|
24
|
+
|
|
25
|
+
export type PSBTInputs = psbt.PSBTKeyMapKeys<typeof psbt.PSBTInput>;
|
|
23
26
|
|
|
24
27
|
// Normalizes input
|
|
25
28
|
export function getPrevOut(input: psbt.TransactionInput): P.UnwrapCoder<typeof RawOutput> {
|
|
@@ -48,7 +51,7 @@ export function normalizeInput(
|
|
|
48
51
|
if (typeof txid === 'string') txid = hex.decode(txid);
|
|
49
52
|
// TODO: if we have nonWitnessUtxo, we can extract txId from here
|
|
50
53
|
if (txid === undefined) txid = cur?.txid;
|
|
51
|
-
let res:
|
|
54
|
+
let res: PSBTInputs = { ...cur, ...i, nonWitnessUtxo, txid };
|
|
52
55
|
if (!('nonWitnessUtxo' in i) && res.nonWitnessUtxo === undefined) delete res.nonWitnessUtxo;
|
|
53
56
|
if (res.sequence === undefined) res.sequence = DEFAULT_SEQUENCE;
|
|
54
57
|
if (res.tapMerkleRoot === null) delete res.tapMerkleRoot;
|
|
@@ -122,9 +125,17 @@ export function getInputType(input: psbt.TransactionInput, allowLegacyWitnessUtx
|
|
|
122
125
|
}
|
|
123
126
|
}
|
|
124
127
|
|
|
125
|
-
export const toVsize = (weight: number) => Math.ceil(weight / 4);
|
|
128
|
+
export const toVsize = (weight: number): number => Math.ceil(weight / 4);
|
|
126
129
|
// UTXO Select
|
|
127
|
-
type Output = { address: string; amount: bigint } | { script: Uint8Array; amount: bigint };
|
|
130
|
+
export type Output = { address: string; amount: bigint } | { script: Uint8Array; amount: bigint };
|
|
131
|
+
export type Accumulated =
|
|
132
|
+
| {
|
|
133
|
+
indices: number[];
|
|
134
|
+
fee: bigint | undefined;
|
|
135
|
+
weight: number;
|
|
136
|
+
total: bigint;
|
|
137
|
+
}
|
|
138
|
+
| undefined;
|
|
128
139
|
type TapLeafScript = psbt.TransactionInput['tapLeafScript'];
|
|
129
140
|
type TB = Parameters<typeof psbt.TaprootControlBlock.encode>[0];
|
|
130
141
|
const encodeTapBlock = (item: TB) => psbt.TaprootControlBlock.encode(item);
|
|
@@ -252,7 +263,7 @@ function estimateInput(
|
|
|
252
263
|
}
|
|
253
264
|
|
|
254
265
|
// Exported for tests, internal method
|
|
255
|
-
export const _cmpBig = (a: bigint, b: bigint) => {
|
|
266
|
+
export const _cmpBig = (a: bigint, b: bigint): 0 | 1 | -1 => {
|
|
256
267
|
const n = a - b;
|
|
257
268
|
if (n < 0n) return -1;
|
|
258
269
|
else if (n > 0n) return 1;
|
|
@@ -442,27 +453,27 @@ export class _Estimator {
|
|
|
442
453
|
}
|
|
443
454
|
|
|
444
455
|
// Sort by value instead of amount
|
|
445
|
-
get biggest() {
|
|
456
|
+
get biggest(): number[] {
|
|
446
457
|
return this.normalizedInputs
|
|
447
458
|
.map((_i, j) => j)
|
|
448
459
|
.sort((a, b) => _cmpBig(this.normalizedInputs[b].value, this.normalizedInputs[a].value));
|
|
449
460
|
}
|
|
450
|
-
get smallest() {
|
|
461
|
+
get smallest(): number[] {
|
|
451
462
|
return this.biggest.reverse();
|
|
452
463
|
}
|
|
453
464
|
// These assume that UTXO array has historical order.
|
|
454
465
|
// Otherwise, we have no way to know which tx is oldest
|
|
455
466
|
// Explorers usually give UTXO in this order.
|
|
456
|
-
get oldest() {
|
|
467
|
+
get oldest(): number[] {
|
|
457
468
|
return this.normalizedInputs.map((_i, j) => j);
|
|
458
469
|
}
|
|
459
|
-
get newest() {
|
|
470
|
+
get newest(): number[] {
|
|
460
471
|
return this.oldest.reverse();
|
|
461
472
|
}
|
|
462
473
|
// exact - like blackjack from coinselect.
|
|
463
474
|
// exact(biggest) will select one big utxo which is closer to targetValue+dust, if possible.
|
|
464
475
|
// If not, it will accumulate largest utxo until value is close to targetValue+dust.
|
|
465
|
-
accumulate(indices: number[], exact = false, skipNegative = true, all = false) {
|
|
476
|
+
accumulate(indices: number[], exact = false, skipNegative = true, all = false): Accumulated {
|
|
466
477
|
// TODO: how to handle change addresses?
|
|
467
478
|
// - cost of input
|
|
468
479
|
// - cost of change output (if input requires change)
|
|
@@ -524,7 +535,7 @@ export class _Estimator {
|
|
|
524
535
|
}
|
|
525
536
|
|
|
526
537
|
// Works like coinselect default method
|
|
527
|
-
default() {
|
|
538
|
+
default(): Accumulated {
|
|
528
539
|
const { biggest } = this;
|
|
529
540
|
const exact = this.accumulate(biggest, true, false);
|
|
530
541
|
if (exact) return exact;
|
|
@@ -602,7 +613,8 @@ export class _Estimator {
|
|
|
602
613
|
for (const o of outputs)
|
|
603
614
|
tx.addOutput({ ...o, script: getScript(o, this.opts, this.opts.network) });
|
|
604
615
|
}
|
|
605
|
-
return
|
|
616
|
+
return Object.assign(res, { tx });
|
|
617
|
+
// return { ...res, tx: tx };
|
|
606
618
|
}
|
|
607
619
|
}
|
|
608
620
|
|
package/transaction.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import * as P from 'micro-packed';
|
|
2
|
-
import { CustomScript } from './payment.js';
|
|
2
|
+
import { type CustomScript } from './payment.js';
|
|
3
3
|
import * as psbt from './psbt.js';
|
|
4
|
-
import
|
|
4
|
+
import * as u from './utils.js';
|
|
5
|
+
import { type Bytes } from './utils.js';
|
|
5
6
|
interface HDKey {
|
|
6
7
|
publicKey: Bytes;
|
|
7
8
|
privateKey: Bytes;
|
|
@@ -15,10 +16,7 @@ export declare const PRECISION = 8;
|
|
|
15
16
|
export declare const DEFAULT_VERSION = 2;
|
|
16
17
|
export declare const DEFAULT_LOCKTIME = 0;
|
|
17
18
|
export declare const DEFAULT_SEQUENCE = 4294967295;
|
|
18
|
-
export declare const Decimal:
|
|
19
|
-
encode: (from: bigint) => string;
|
|
20
|
-
decode: (to: string) => bigint;
|
|
21
|
-
};
|
|
19
|
+
export declare const Decimal: P.Coder<bigint, string>;
|
|
22
20
|
export declare const def: <T>(value: T | undefined, def: T) => T;
|
|
23
21
|
export declare function cloneDeep<T>(obj: T): T;
|
|
24
22
|
export type TxOpts = {
|
|
@@ -65,22 +63,7 @@ export type TransactionInputRequired = {
|
|
|
65
63
|
finalScriptSig: Bytes;
|
|
66
64
|
};
|
|
67
65
|
export declare function inputBeforeSign(i: psbt.TransactionInput): TransactionInputRequired;
|
|
68
|
-
declare function validateOpts(opts: TxOpts): Readonly<
|
|
69
|
-
version: number;
|
|
70
|
-
lockTime: number;
|
|
71
|
-
PSBTVersion: number;
|
|
72
|
-
/** @deprecated Use `allowUnknownOutputs` */
|
|
73
|
-
allowUnknowOutput?: boolean;
|
|
74
|
-
allowUnknownOutputs?: boolean;
|
|
75
|
-
/** @deprecated Use `allowUnknownInputs` */
|
|
76
|
-
allowUnknowInput?: boolean;
|
|
77
|
-
allowUnknownInputs?: boolean;
|
|
78
|
-
disableScriptCheck?: boolean;
|
|
79
|
-
bip174jsCompat?: boolean;
|
|
80
|
-
allowLegacyWitnessUtxo?: boolean;
|
|
81
|
-
lowR?: boolean;
|
|
82
|
-
customScripts?: CustomScript[];
|
|
83
|
-
}>;
|
|
66
|
+
declare function validateOpts(opts: TxOpts): Readonly<TxOpts>;
|
|
84
67
|
export declare class Transaction {
|
|
85
68
|
private global;
|
|
86
69
|
private inputs;
|
|
@@ -89,7 +72,7 @@ export declare class Transaction {
|
|
|
89
72
|
constructor(opts?: TxOpts);
|
|
90
73
|
static fromRaw(raw: Bytes, opts?: TxOpts): Transaction;
|
|
91
74
|
static fromPSBT(psbt_: Bytes, opts?: TxOpts): Transaction;
|
|
92
|
-
toPSBT(PSBTVersion?: number): Uint8Array;
|
|
75
|
+
toPSBT(PSBTVersion?: number | undefined): Uint8Array;
|
|
93
76
|
get lockTime(): number;
|
|
94
77
|
get version(): number;
|
|
95
78
|
private inputStatus;
|
|
@@ -105,112 +88,18 @@ export declare class Transaction {
|
|
|
105
88
|
get hash(): string;
|
|
106
89
|
get id(): string;
|
|
107
90
|
private checkInputIdx;
|
|
108
|
-
getInput(idx: number): psbt.
|
|
109
|
-
readonly nonWitnessUtxo: readonly [0, false, P.CoderType<P.StructInput<{
|
|
110
|
-
version: number;
|
|
111
|
-
segwitFlag: boolean | undefined;
|
|
112
|
-
inputs: P.StructInput<{
|
|
113
|
-
txid: any;
|
|
114
|
-
index: any;
|
|
115
|
-
finalScriptSig: any;
|
|
116
|
-
sequence: any;
|
|
117
|
-
}>[];
|
|
118
|
-
outputs: P.StructInput<{
|
|
119
|
-
amount: any;
|
|
120
|
-
script: any;
|
|
121
|
-
}>[];
|
|
122
|
-
witnesses: P.Option<Uint8Array[][]>;
|
|
123
|
-
lockTime: number;
|
|
124
|
-
}>>, readonly [], readonly [0, 2], false];
|
|
125
|
-
readonly witnessUtxo: readonly [1, false, P.CoderType<P.StructInput<{
|
|
126
|
-
amount: bigint;
|
|
127
|
-
script: Uint8Array;
|
|
128
|
-
}>>, readonly [], readonly [0, 2], false];
|
|
129
|
-
readonly partialSig: readonly [2, P.CoderType<Uint8Array>, P.CoderType<Uint8Array>, readonly [], readonly [0, 2], false];
|
|
130
|
-
readonly sighashType: readonly [3, false, P.CoderType<number>, readonly [], readonly [0, 2], false];
|
|
131
|
-
readonly redeemScript: readonly [4, false, P.CoderType<Uint8Array>, readonly [], readonly [0, 2], false];
|
|
132
|
-
readonly witnessScript: readonly [5, false, P.CoderType<Uint8Array>, readonly [], readonly [0, 2], false];
|
|
133
|
-
readonly bip32Derivation: readonly [6, P.CoderType<Uint8Array>, P.CoderType<P.StructInput<{
|
|
134
|
-
fingerprint: number;
|
|
135
|
-
path: number[];
|
|
136
|
-
}>>, readonly [], readonly [0, 2], false];
|
|
137
|
-
readonly finalScriptSig: readonly [7, false, P.CoderType<Uint8Array>, readonly [], readonly [0, 2], false];
|
|
138
|
-
readonly finalScriptWitness: readonly [8, false, P.CoderType<Uint8Array[]>, readonly [], readonly [0, 2], false];
|
|
139
|
-
readonly porCommitment: readonly [9, false, P.CoderType<Uint8Array>, readonly [], readonly [0, 2], false];
|
|
140
|
-
readonly ripemd160: readonly [10, P.CoderType<Uint8Array>, P.CoderType<Uint8Array>, readonly [], readonly [0, 2], false];
|
|
141
|
-
readonly sha256: readonly [11, P.CoderType<Uint8Array>, P.CoderType<Uint8Array>, readonly [], readonly [0, 2], false];
|
|
142
|
-
readonly hash160: readonly [12, P.CoderType<Uint8Array>, P.CoderType<Uint8Array>, readonly [], readonly [0, 2], false];
|
|
143
|
-
readonly hash256: readonly [13, P.CoderType<Uint8Array>, P.CoderType<Uint8Array>, readonly [], readonly [0, 2], false];
|
|
144
|
-
readonly txid: readonly [14, false, P.CoderType<Uint8Array>, readonly [2], readonly [2], true];
|
|
145
|
-
readonly index: readonly [15, false, P.CoderType<number>, readonly [2], readonly [2], true];
|
|
146
|
-
readonly sequence: readonly [16, false, P.CoderType<number>, readonly [], readonly [2], true];
|
|
147
|
-
readonly requiredTimeLocktime: readonly [17, false, P.CoderType<number>, readonly [], readonly [2], false];
|
|
148
|
-
readonly requiredHeightLocktime: readonly [18, false, P.CoderType<number>, readonly [], readonly [2], false];
|
|
149
|
-
readonly tapKeySig: readonly [19, false, P.CoderType<Uint8Array>, readonly [], readonly [0, 2], false];
|
|
150
|
-
readonly tapScriptSig: readonly [20, P.CoderType<P.StructInput<{
|
|
151
|
-
pubKey: Uint8Array;
|
|
152
|
-
leafHash: Uint8Array;
|
|
153
|
-
}>>, P.CoderType<Uint8Array>, readonly [], readonly [0, 2], false];
|
|
154
|
-
readonly tapLeafScript: readonly [21, P.CoderType<P.StructInput<{
|
|
155
|
-
version: number;
|
|
156
|
-
internalKey: Uint8Array;
|
|
157
|
-
merklePath: Uint8Array[];
|
|
158
|
-
}>>, P.CoderType<Uint8Array>, readonly [], readonly [0, 2], false];
|
|
159
|
-
readonly tapBip32Derivation: readonly [22, P.CoderType<Uint8Array>, P.CoderType<P.StructInput<{
|
|
160
|
-
hashes: Uint8Array[];
|
|
161
|
-
der: P.StructInput<{
|
|
162
|
-
fingerprint: any;
|
|
163
|
-
path: any;
|
|
164
|
-
}>;
|
|
165
|
-
}>>, readonly [], readonly [0, 2], false];
|
|
166
|
-
readonly tapInternalKey: readonly [23, false, P.CoderType<Uint8Array>, readonly [], readonly [0, 2], false];
|
|
167
|
-
readonly tapMerkleRoot: readonly [24, false, P.CoderType<Uint8Array>, readonly [], readonly [0, 2], false];
|
|
168
|
-
readonly proprietary: readonly [252, P.CoderType<Uint8Array>, P.CoderType<Uint8Array>, readonly [], readonly [0, 2], false];
|
|
169
|
-
}>;
|
|
91
|
+
getInput(idx: number): psbt.TransactionInput;
|
|
170
92
|
get inputsLength(): number;
|
|
171
93
|
addInput(input: psbt.TransactionInputUpdate, _ignoreSignStatus?: boolean): number;
|
|
172
94
|
updateInput(idx: number, input: psbt.TransactionInputUpdate, _ignoreSignStatus?: boolean): void;
|
|
173
95
|
private checkOutputIdx;
|
|
174
|
-
getOutput(idx: number): psbt.
|
|
175
|
-
|
|
176
|
-
readonly witnessScript: readonly [1, false, P.CoderType<Uint8Array>, readonly [], readonly [0, 2], false];
|
|
177
|
-
readonly bip32Derivation: readonly [2, P.CoderType<Uint8Array>, P.CoderType<P.StructInput<{
|
|
178
|
-
fingerprint: number;
|
|
179
|
-
path: number[];
|
|
180
|
-
}>>, readonly [], readonly [0, 2], false];
|
|
181
|
-
readonly amount: readonly [3, false, P.CoderType<bigint>, readonly [2], readonly [2], true];
|
|
182
|
-
readonly script: readonly [4, false, P.CoderType<Uint8Array>, readonly [2], readonly [2], true];
|
|
183
|
-
readonly tapInternalKey: readonly [5, false, P.CoderType<Uint8Array>, readonly [], readonly [0, 2], false];
|
|
184
|
-
readonly tapTree: readonly [6, false, P.CoderType<P.StructInput<{
|
|
185
|
-
depth: number;
|
|
186
|
-
version: number;
|
|
187
|
-
script: Uint8Array;
|
|
188
|
-
}>[]>, readonly [], readonly [0, 2], false];
|
|
189
|
-
readonly tapBip32Derivation: readonly [7, P.CoderType<Uint8Array>, P.CoderType<P.StructInput<{
|
|
190
|
-
hashes: Uint8Array[];
|
|
191
|
-
der: P.StructInput<{
|
|
192
|
-
fingerprint: any;
|
|
193
|
-
path: any;
|
|
194
|
-
}>;
|
|
195
|
-
}>>, readonly [], readonly [0, 2], false];
|
|
196
|
-
readonly proprietary: readonly [252, P.CoderType<Uint8Array>, P.CoderType<Uint8Array>, readonly [], readonly [0, 2], false];
|
|
197
|
-
}>;
|
|
198
|
-
getOutputAddress(idx: number, network?: {
|
|
199
|
-
bech32: string;
|
|
200
|
-
pubKeyHash: number;
|
|
201
|
-
scriptHash: number;
|
|
202
|
-
wif: number;
|
|
203
|
-
}): string | undefined;
|
|
96
|
+
getOutput(idx: number): psbt.TransactionOutput;
|
|
97
|
+
getOutputAddress(idx: number, network?: u.BTC_NETWORK): string | undefined;
|
|
204
98
|
get outputsLength(): number;
|
|
205
99
|
private normalizeOutput;
|
|
206
100
|
addOutput(o: psbt.TransactionOutputUpdate, _ignoreSignStatus?: boolean): number;
|
|
207
101
|
updateOutput(idx: number, output: psbt.TransactionOutputUpdate, _ignoreSignStatus?: boolean): void;
|
|
208
|
-
addOutputAddress(address: string, amount: bigint, network?:
|
|
209
|
-
bech32: string;
|
|
210
|
-
pubKeyHash: number;
|
|
211
|
-
scriptHash: number;
|
|
212
|
-
wif: number;
|
|
213
|
-
}): number;
|
|
102
|
+
addOutputAddress(address: string, amount: bigint, network?: u.BTC_NETWORK): number;
|
|
214
103
|
get fee(): bigint;
|
|
215
104
|
private preimageLegacy;
|
|
216
105
|
preimageWitnessV0(idx: number, prevOutScript: Bytes, hashType: number, amount: bigint): Uint8Array;
|
package/transaction.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transaction.d.ts","sourceRoot":"","sources":["src/transaction.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"transaction.d.ts","sourceRoot":"","sources":["src/transaction.ts"],"names":[],"mappings":"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"}
|