@scure/btc-signer 1.5.0 → 1.7.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 +146 -25
- 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/musig2.d.ts +148 -0
- package/esm/musig2.d.ts.map +1 -0
- package/esm/musig2.js +405 -0
- package/esm/musig2.js.map +1 -0
- 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 +463 -463
- package/esm/psbt.d.ts.map +1 -1
- package/esm/psbt.js +10 -7
- package/esm/psbt.js.map +1 -1
- package/esm/script.d.ts +19 -17
- package/esm/script.d.ts.map +1 -1
- package/esm/script.js.map +1 -1
- package/esm/transaction.d.ts +13 -123
- package/esm/transaction.d.ts.map +1 -1
- package/esm/transaction.js +8 -9
- 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 +96 -94
- package/esm/utxo.d.ts.map +1 -1
- package/esm/utxo.js +19 -15
- 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/musig2.d.ts +148 -0
- package/musig2.d.ts.map +1 -0
- package/musig2.js +417 -0
- package/musig2.js.map +1 -0
- package/package.json +22 -14
- 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 +463 -463
- package/psbt.d.ts.map +1 -1
- package/psbt.js +13 -10
- package/psbt.js.map +1 -1
- package/script.d.ts +19 -17
- 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/musig2.ts +517 -0
- package/src/payment.ts +74 -27
- package/src/psbt.ts +36 -14
- package/src/script.ts +5 -5
- package/src/transaction.ts +61 -39
- package/src/utils.ts +26 -16
- package/src/utxo.ts +52 -31
- package/transaction.d.ts +13 -123
- package/transaction.d.ts.map +1 -1
- package/transaction.js +17 -18
- 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 +96 -94
- package/utxo.d.ts.map +1 -1
- package/utxo.js +17 -13
- package/utxo.js.map +1 -1
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> {
|
|
@@ -34,7 +37,8 @@ export function normalizeInput(
|
|
|
34
37
|
i: psbt.TransactionInputUpdate,
|
|
35
38
|
cur?: psbt.TransactionInput,
|
|
36
39
|
allowedFields?: (keyof psbt.TransactionInput)[],
|
|
37
|
-
disableScriptCheck = false
|
|
40
|
+
disableScriptCheck = false,
|
|
41
|
+
allowUnknown = false
|
|
38
42
|
): psbt.TransactionInput {
|
|
39
43
|
let { nonWitnessUtxo, txid } = i;
|
|
40
44
|
// String support for common fields. We usually prefer Uint8Array to avoid errors
|
|
@@ -48,11 +52,11 @@ export function normalizeInput(
|
|
|
48
52
|
if (typeof txid === 'string') txid = hex.decode(txid);
|
|
49
53
|
// TODO: if we have nonWitnessUtxo, we can extract txId from here
|
|
50
54
|
if (txid === undefined) txid = cur?.txid;
|
|
51
|
-
let res:
|
|
55
|
+
let res: PSBTInputs = { ...cur, ...i, nonWitnessUtxo, txid };
|
|
52
56
|
if (!('nonWitnessUtxo' in i) && res.nonWitnessUtxo === undefined) delete res.nonWitnessUtxo;
|
|
53
57
|
if (res.sequence === undefined) res.sequence = DEFAULT_SEQUENCE;
|
|
54
58
|
if (res.tapMerkleRoot === null) delete res.tapMerkleRoot;
|
|
55
|
-
res = psbt.mergeKeyMap(psbt.PSBTInput, res, cur, allowedFields);
|
|
59
|
+
res = psbt.mergeKeyMap(psbt.PSBTInput, res, cur, allowedFields, allowUnknown);
|
|
56
60
|
psbt.PSBTInputCoder.encode(res); // Validates that everything is correct at this point
|
|
57
61
|
|
|
58
62
|
let prevOut;
|
|
@@ -122,9 +126,17 @@ export function getInputType(input: psbt.TransactionInput, allowLegacyWitnessUtx
|
|
|
122
126
|
}
|
|
123
127
|
}
|
|
124
128
|
|
|
125
|
-
export const toVsize = (weight: number) => Math.ceil(weight / 4);
|
|
129
|
+
export const toVsize = (weight: number): number => Math.ceil(weight / 4);
|
|
126
130
|
// UTXO Select
|
|
127
|
-
type Output = { address: string; amount: bigint } | { script: Uint8Array; amount: bigint };
|
|
131
|
+
export type Output = { address: string; amount: bigint } | { script: Uint8Array; amount: bigint };
|
|
132
|
+
export type Accumulated =
|
|
133
|
+
| {
|
|
134
|
+
indices: number[];
|
|
135
|
+
fee: bigint | undefined;
|
|
136
|
+
weight: number;
|
|
137
|
+
total: bigint;
|
|
138
|
+
}
|
|
139
|
+
| undefined;
|
|
128
140
|
type TapLeafScript = psbt.TransactionInput['tapLeafScript'];
|
|
129
141
|
type TB = Parameters<typeof psbt.TaprootControlBlock.encode>[0];
|
|
130
142
|
const encodeTapBlock = (item: TB) => psbt.TaprootControlBlock.encode(item);
|
|
@@ -252,7 +264,7 @@ function estimateInput(
|
|
|
252
264
|
}
|
|
253
265
|
|
|
254
266
|
// Exported for tests, internal method
|
|
255
|
-
export const _cmpBig = (a: bigint, b: bigint) => {
|
|
267
|
+
export const _cmpBig = (a: bigint, b: bigint): 0 | 1 | -1 => {
|
|
256
268
|
const n = a - b;
|
|
257
269
|
if (n < 0n) return -1;
|
|
258
270
|
else if (n > 0n) return 1;
|
|
@@ -330,11 +342,11 @@ export class _Estimator {
|
|
|
330
342
|
// - change address: can be smaller for segwit
|
|
331
343
|
// - accumExact: ???
|
|
332
344
|
private dust: bigint; // total dust limit (3||opts.dustRelayFeeRate * 182||opts.dust). Default: 546
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
345
|
+
private outputs: Output[];
|
|
346
|
+
private opts: EstimatorOpts;
|
|
347
|
+
constructor(inputs: psbt.TransactionInputUpdate[], outputs: Output[], opts: EstimatorOpts) {
|
|
348
|
+
this.outputs = outputs;
|
|
349
|
+
this.opts = opts;
|
|
338
350
|
if (typeof opts.feePerByte !== 'bigint')
|
|
339
351
|
throw new Error(
|
|
340
352
|
`Estimator: wrong feePerByte=${
|
|
@@ -399,7 +411,13 @@ export class _Estimator {
|
|
|
399
411
|
}
|
|
400
412
|
const inputKeys = new Set();
|
|
401
413
|
this.normalizedInputs = allInputs.map((i) => {
|
|
402
|
-
const normalized = normalizeInput(
|
|
414
|
+
const normalized = normalizeInput(
|
|
415
|
+
i,
|
|
416
|
+
undefined,
|
|
417
|
+
undefined,
|
|
418
|
+
opts.disableScriptCheck,
|
|
419
|
+
opts.allowUnknown
|
|
420
|
+
);
|
|
403
421
|
inputBeforeSign(normalized); // check fields
|
|
404
422
|
const key = `${hex.encode(normalized.txid!)}:${normalized.index}`;
|
|
405
423
|
if (!opts.allowSameUtxo && inputKeys.has(key))
|
|
@@ -442,27 +460,27 @@ export class _Estimator {
|
|
|
442
460
|
}
|
|
443
461
|
|
|
444
462
|
// Sort by value instead of amount
|
|
445
|
-
get biggest() {
|
|
463
|
+
get biggest(): number[] {
|
|
446
464
|
return this.normalizedInputs
|
|
447
465
|
.map((_i, j) => j)
|
|
448
466
|
.sort((a, b) => _cmpBig(this.normalizedInputs[b].value, this.normalizedInputs[a].value));
|
|
449
467
|
}
|
|
450
|
-
get smallest() {
|
|
468
|
+
get smallest(): number[] {
|
|
451
469
|
return this.biggest.reverse();
|
|
452
470
|
}
|
|
453
471
|
// These assume that UTXO array has historical order.
|
|
454
472
|
// Otherwise, we have no way to know which tx is oldest
|
|
455
473
|
// Explorers usually give UTXO in this order.
|
|
456
|
-
get oldest() {
|
|
474
|
+
get oldest(): number[] {
|
|
457
475
|
return this.normalizedInputs.map((_i, j) => j);
|
|
458
476
|
}
|
|
459
|
-
get newest() {
|
|
477
|
+
get newest(): number[] {
|
|
460
478
|
return this.oldest.reverse();
|
|
461
479
|
}
|
|
462
480
|
// exact - like blackjack from coinselect.
|
|
463
481
|
// exact(biggest) will select one big utxo which is closer to targetValue+dust, if possible.
|
|
464
482
|
// If not, it will accumulate largest utxo until value is close to targetValue+dust.
|
|
465
|
-
accumulate(indices: number[], exact = false, skipNegative = true, all = false) {
|
|
483
|
+
accumulate(indices: number[], exact = false, skipNegative = true, all = false): Accumulated {
|
|
466
484
|
// TODO: how to handle change addresses?
|
|
467
485
|
// - cost of input
|
|
468
486
|
// - cost of change output (if input requires change)
|
|
@@ -476,10 +494,11 @@ export class _Estimator {
|
|
|
476
494
|
let num = 0;
|
|
477
495
|
let inputsAmount = 0n;
|
|
478
496
|
const targetAmount = this.amount;
|
|
479
|
-
const res =
|
|
497
|
+
const res: Set<number> = new Set();
|
|
480
498
|
let fee;
|
|
481
499
|
for (const idx of this.requiredIndices) {
|
|
482
500
|
this.checkInputIdx(idx);
|
|
501
|
+
if (res.has(idx)) throw new Error('required input encountered multiple times'); // should not happen
|
|
483
502
|
const { estimate, amount } = this.normalizedInputs[idx];
|
|
484
503
|
let newWeight = weight + estimate.weight;
|
|
485
504
|
if (!hasWitnesses && estimate.hasWitnesses) newWeight += 2; // enable witness if needed
|
|
@@ -489,13 +508,14 @@ export class _Estimator {
|
|
|
489
508
|
if (estimate.hasWitnesses) hasWitnesses = true;
|
|
490
509
|
num++;
|
|
491
510
|
inputsAmount += amount;
|
|
492
|
-
res.
|
|
511
|
+
res.add(idx);
|
|
493
512
|
// inputsAmount is enough to cover cost of tx
|
|
494
513
|
if (!all && targetAmount + fee <= inputsAmount)
|
|
495
|
-
return { indices: res, fee, weight: totalWeight, total: inputsAmount };
|
|
514
|
+
return { indices: Array.from(res), fee, weight: totalWeight, total: inputsAmount };
|
|
496
515
|
}
|
|
497
516
|
for (const idx of indices) {
|
|
498
517
|
this.checkInputIdx(idx);
|
|
518
|
+
if (res.has(idx)) continue; // skip required inputs
|
|
499
519
|
const { estimate, amount, value } = this.normalizedInputs[idx];
|
|
500
520
|
let newWeight = weight + estimate.weight;
|
|
501
521
|
if (!hasWitnesses && estimate.hasWitnesses) newWeight += 2; // enable witness if needed
|
|
@@ -511,20 +531,20 @@ export class _Estimator {
|
|
|
511
531
|
if (estimate.hasWitnesses) hasWitnesses = true;
|
|
512
532
|
num++;
|
|
513
533
|
inputsAmount += amount;
|
|
514
|
-
res.
|
|
534
|
+
res.add(idx);
|
|
515
535
|
// inputsAmount is enough to cover cost of tx
|
|
516
536
|
if (!all && targetAmount + fee <= inputsAmount)
|
|
517
|
-
return { indices: res, fee, weight: totalWeight, total: inputsAmount };
|
|
537
|
+
return { indices: Array.from(res), fee, weight: totalWeight, total: inputsAmount };
|
|
518
538
|
}
|
|
519
539
|
if (all) {
|
|
520
540
|
const newWeight = weight + 4 * CompactSizeLen.encode(num).length;
|
|
521
|
-
return { indices: res, fee, weight: newWeight, total: inputsAmount };
|
|
541
|
+
return { indices: Array.from(res), fee, weight: newWeight, total: inputsAmount };
|
|
522
542
|
}
|
|
523
543
|
return undefined;
|
|
524
544
|
}
|
|
525
545
|
|
|
526
546
|
// Works like coinselect default method
|
|
527
|
-
default() {
|
|
547
|
+
default(): Accumulated {
|
|
528
548
|
const { biggest } = this;
|
|
529
549
|
const exact = this.accumulate(biggest, true, false);
|
|
530
550
|
if (exact) return exact;
|
|
@@ -602,7 +622,8 @@ export class _Estimator {
|
|
|
602
622
|
for (const o of outputs)
|
|
603
623
|
tx.addOutput({ ...o, script: getScript(o, this.opts, this.opts.network) });
|
|
604
624
|
}
|
|
605
|
-
return
|
|
625
|
+
return Object.assign(res, { tx });
|
|
626
|
+
// return { ...res, tx: tx };
|
|
606
627
|
}
|
|
607
628
|
}
|
|
608
629
|
|
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,13 +16,10 @@ 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
|
-
export
|
|
22
|
+
export interface TxOpts {
|
|
25
23
|
version?: number;
|
|
26
24
|
lockTime?: number;
|
|
27
25
|
PSBTVersion?: number;
|
|
@@ -36,7 +34,8 @@ export type TxOpts = {
|
|
|
36
34
|
allowLegacyWitnessUtxo?: boolean;
|
|
37
35
|
lowR?: boolean;
|
|
38
36
|
customScripts?: CustomScript[];
|
|
39
|
-
|
|
37
|
+
allowUnknown?: boolean;
|
|
38
|
+
}
|
|
40
39
|
/**
|
|
41
40
|
* Internal, exported only for backwards-compat. Use `SigHash` instead.
|
|
42
41
|
* @deprecated
|
|
@@ -65,22 +64,7 @@ export type TransactionInputRequired = {
|
|
|
65
64
|
finalScriptSig: Bytes;
|
|
66
65
|
};
|
|
67
66
|
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
|
-
}>;
|
|
67
|
+
declare function validateOpts(opts: TxOpts): Readonly<TxOpts>;
|
|
84
68
|
export declare class Transaction {
|
|
85
69
|
private global;
|
|
86
70
|
private inputs;
|
|
@@ -89,7 +73,7 @@ export declare class Transaction {
|
|
|
89
73
|
constructor(opts?: TxOpts);
|
|
90
74
|
static fromRaw(raw: Bytes, opts?: TxOpts): Transaction;
|
|
91
75
|
static fromPSBT(psbt_: Bytes, opts?: TxOpts): Transaction;
|
|
92
|
-
toPSBT(PSBTVersion?: number): Uint8Array;
|
|
76
|
+
toPSBT(PSBTVersion?: number | undefined): Uint8Array;
|
|
93
77
|
get lockTime(): number;
|
|
94
78
|
get version(): number;
|
|
95
79
|
private inputStatus;
|
|
@@ -105,112 +89,18 @@ export declare class Transaction {
|
|
|
105
89
|
get hash(): string;
|
|
106
90
|
get id(): string;
|
|
107
91
|
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
|
-
}>;
|
|
92
|
+
getInput(idx: number): psbt.TransactionInput;
|
|
170
93
|
get inputsLength(): number;
|
|
171
94
|
addInput(input: psbt.TransactionInputUpdate, _ignoreSignStatus?: boolean): number;
|
|
172
95
|
updateInput(idx: number, input: psbt.TransactionInputUpdate, _ignoreSignStatus?: boolean): void;
|
|
173
96
|
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;
|
|
97
|
+
getOutput(idx: number): psbt.TransactionOutput;
|
|
98
|
+
getOutputAddress(idx: number, network?: u.BTC_NETWORK): string | undefined;
|
|
204
99
|
get outputsLength(): number;
|
|
205
100
|
private normalizeOutput;
|
|
206
101
|
addOutput(o: psbt.TransactionOutputUpdate, _ignoreSignStatus?: boolean): number;
|
|
207
102
|
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;
|
|
103
|
+
addOutputAddress(address: string, amount: bigint, network?: u.BTC_NETWORK): number;
|
|
214
104
|
get fee(): bigint;
|
|
215
105
|
private preimageLegacy;
|
|
216
106
|
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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"}
|
package/transaction.js
CHANGED
|
@@ -5,14 +5,13 @@ exports.cloneDeep = cloneDeep;
|
|
|
5
5
|
exports.inputBeforeSign = inputBeforeSign;
|
|
6
6
|
exports.PSBTCombine = PSBTCombine;
|
|
7
7
|
exports.bip32Path = bip32Path;
|
|
8
|
-
const P = require("micro-packed");
|
|
9
8
|
const base_1 = require("@scure/base");
|
|
9
|
+
const P = require("micro-packed");
|
|
10
10
|
const payment_js_1 = require("./payment.js");
|
|
11
11
|
const psbt = require("./psbt.js"); // circular
|
|
12
12
|
const script_js_1 = require("./script.js");
|
|
13
|
-
const script_js_2 = require("./script.js");
|
|
14
|
-
const utils_js_1 = require("./utils.js");
|
|
15
13
|
const u = require("./utils.js");
|
|
14
|
+
const utils_js_1 = require("./utils.js");
|
|
16
15
|
const utxo_js_1 = require("./utxo.js"); // circular
|
|
17
16
|
const EMPTY32 = new Uint8Array(32);
|
|
18
17
|
const EMPTY_OUTPUT = {
|
|
@@ -129,7 +128,7 @@ function validateOpts(opts) {
|
|
|
129
128
|
if (typeof _opts.allowUnknowOutput !== 'undefined')
|
|
130
129
|
opts.allowUnknownOutputs = _opts.allowUnknowOutput;
|
|
131
130
|
// 0 and -1 happens in tests
|
|
132
|
-
if (![-1, 0, 1, 2].includes(_opts.version))
|
|
131
|
+
if (![-1, 0, 1, 2, 3].includes(_opts.version))
|
|
133
132
|
throw new Error(`Unknown version: ${_opts.version}`);
|
|
134
133
|
if (typeof _opts.lockTime !== 'number')
|
|
135
134
|
throw new Error('Transaction lock time should be number');
|
|
@@ -180,7 +179,7 @@ class Transaction {
|
|
|
180
179
|
}
|
|
181
180
|
// Import
|
|
182
181
|
static fromRaw(raw, opts = {}) {
|
|
183
|
-
const parsed =
|
|
182
|
+
const parsed = script_js_1.RawTx.decode(raw);
|
|
184
183
|
const tx = new Transaction({ ...opts, version: parsed.version, lockTime: parsed.lockTime });
|
|
185
184
|
for (const o of parsed.outputs)
|
|
186
185
|
tx.addOutput(o);
|
|
@@ -258,7 +257,7 @@ class Transaction {
|
|
|
258
257
|
- Parsing of PSBTv0 depends on unsignedTx (it looks for input count here)
|
|
259
258
|
- BIP-174 requires old serialization format (without witnesses) inside global, which solves this
|
|
260
259
|
*/
|
|
261
|
-
global.unsignedTx =
|
|
260
|
+
global.unsignedTx = script_js_1.RawOldTx.decode(script_js_1.RawOldTx.encode({
|
|
262
261
|
version: this.version,
|
|
263
262
|
lockTime: this.lockTime,
|
|
264
263
|
inputs: this.inputs.map(inputBeforeSign).map((i) => ({
|
|
@@ -413,7 +412,7 @@ class Transaction {
|
|
|
413
412
|
for (const i of this.inputs) {
|
|
414
413
|
out += 160 + 4 * script_js_1.VarBytes.encode(i.finalScriptSig || P.EMPTY).length;
|
|
415
414
|
if (this.hasWitnesses && i.finalScriptWitness)
|
|
416
|
-
out +=
|
|
415
|
+
out += script_js_1.RawWitness.encode(i.finalScriptWitness).length;
|
|
417
416
|
}
|
|
418
417
|
return out;
|
|
419
418
|
}
|
|
@@ -421,7 +420,7 @@ class Transaction {
|
|
|
421
420
|
return (0, utxo_js_1.toVsize)(this.weight);
|
|
422
421
|
}
|
|
423
422
|
toBytes(withScriptSig = false, withWitness = false) {
|
|
424
|
-
return
|
|
423
|
+
return script_js_1.RawTx.encode({
|
|
425
424
|
version: this.version,
|
|
426
425
|
lockTime: this.lockTime,
|
|
427
426
|
inputs: this.inputs.map(inputBeforeSign).map((i) => ({
|
|
@@ -476,7 +475,7 @@ class Transaction {
|
|
|
476
475
|
if (!status.addInput || status.inputs.includes(idx))
|
|
477
476
|
allowedFields = psbt.PSBTInputUnsignedKeys;
|
|
478
477
|
}
|
|
479
|
-
this.inputs[idx] = (0, utxo_js_1.normalizeInput)(input, this.inputs[idx], allowedFields, this.opts.disableScriptCheck);
|
|
478
|
+
this.inputs[idx] = (0, utxo_js_1.normalizeInput)(input, this.inputs[idx], allowedFields, this.opts.disableScriptCheck, this.opts.allowUnknown);
|
|
480
479
|
}
|
|
481
480
|
// Output stuff
|
|
482
481
|
checkOutputIdx(idx) {
|
|
@@ -509,7 +508,7 @@ class Transaction {
|
|
|
509
508
|
let res = { ...cur, ...o, amount, script };
|
|
510
509
|
if (res.amount === undefined)
|
|
511
510
|
delete res.amount;
|
|
512
|
-
res = psbt.mergeKeyMap(psbt.PSBTOutput, res, cur, allowedFields);
|
|
511
|
+
res = psbt.mergeKeyMap(psbt.PSBTOutput, res, cur, allowedFields, this.opts.allowUnknown);
|
|
513
512
|
psbt.PSBTOutputCoder.encode(res);
|
|
514
513
|
if (res.script &&
|
|
515
514
|
!this.opts.allowUnknownOutputs &&
|
|
@@ -584,7 +583,7 @@ class Transaction {
|
|
|
584
583
|
else if (isSingle) {
|
|
585
584
|
outputs = outputs.slice(0, idx).fill(EMPTY_OUTPUT).concat([outputs[idx]]);
|
|
586
585
|
}
|
|
587
|
-
const tmpTx =
|
|
586
|
+
const tmpTx = script_js_1.RawTx.encode({
|
|
588
587
|
lockTime: this.lockTime,
|
|
589
588
|
version: this.version,
|
|
590
589
|
segwitFlag: false,
|
|
@@ -605,10 +604,10 @@ class Transaction {
|
|
|
605
604
|
if (!isAny && !isSingle && !isNone)
|
|
606
605
|
sequenceHash = u.sha256x2(...inputs.map((i) => P.U32LE.encode(i.sequence)));
|
|
607
606
|
if (!isSingle && !isNone) {
|
|
608
|
-
outputHash = u.sha256x2(...outputs.map(
|
|
607
|
+
outputHash = u.sha256x2(...outputs.map(script_js_1.RawOutput.encode));
|
|
609
608
|
}
|
|
610
609
|
else if (isSingle && idx < outputs.length)
|
|
611
|
-
outputHash = u.sha256x2(
|
|
610
|
+
outputHash = u.sha256x2(script_js_1.RawOutput.encode(outputs[idx]));
|
|
612
611
|
const input = inputs[idx];
|
|
613
612
|
return u.sha256x2(P.I32LE.encode(this.version), inputHash, sequenceHash, P.bytes(32, true).encode(input.txid), P.U32LE.encode(input.index), script_js_1.VarBytes.encode(prevOutScript), P.U64LE.encode(amount), P.U32LE.encode(input.sequence), outputHash, P.U32LE.encode(this.lockTime), P.U32LE.encode(hashType));
|
|
614
613
|
}
|
|
@@ -636,7 +635,7 @@ class Transaction {
|
|
|
636
635
|
].map((i) => u.sha256((0, utils_js_1.concatBytes)(...i))));
|
|
637
636
|
}
|
|
638
637
|
if (outType === SignatureHash.ALL) {
|
|
639
|
-
out.push(u.sha256((0, utils_js_1.concatBytes)(...outputs.map(
|
|
638
|
+
out.push(u.sha256((0, utils_js_1.concatBytes)(...outputs.map(script_js_1.RawOutput.encode))));
|
|
640
639
|
}
|
|
641
640
|
const spendType = (annex ? 1 : 0) | (leafScript ? 2 : 0);
|
|
642
641
|
out.push(new Uint8Array([spendType]));
|
|
@@ -649,7 +648,7 @@ class Transaction {
|
|
|
649
648
|
if (spendType & 1)
|
|
650
649
|
out.push(u.sha256(script_js_1.VarBytes.encode(annex || P.EMPTY)));
|
|
651
650
|
if (outType === SignatureHash.SINGLE)
|
|
652
|
-
out.push(idx < outputs.length ? u.sha256(
|
|
651
|
+
out.push(idx < outputs.length ? u.sha256(script_js_1.RawOutput.encode(outputs[idx])) : EMPTY32);
|
|
653
652
|
if (leafScript)
|
|
654
653
|
out.push((0, payment_js_1.tapLeafHash)(leafScript, leafVer), P.U8.encode(0), P.I32LE.encode(codeSeparator));
|
|
655
654
|
return u.tagSchnorr('TapSighash', ...out);
|
|
@@ -996,13 +995,13 @@ class Transaction {
|
|
|
996
995
|
throw new Error(`Transaction/combine: different ${k} length this=${this[k].length} other=${other[k].length}`);
|
|
997
996
|
}
|
|
998
997
|
}
|
|
999
|
-
const thisUnsigned = this.global.unsignedTx ?
|
|
998
|
+
const thisUnsigned = this.global.unsignedTx ? script_js_1.RawOldTx.encode(this.global.unsignedTx) : P.EMPTY;
|
|
1000
999
|
const otherUnsigned = other.global.unsignedTx
|
|
1001
|
-
?
|
|
1000
|
+
? script_js_1.RawOldTx.encode(other.global.unsignedTx)
|
|
1002
1001
|
: P.EMPTY;
|
|
1003
1002
|
if (!(0, utils_js_1.equalBytes)(thisUnsigned, otherUnsigned))
|
|
1004
1003
|
throw new Error(`Transaction/combine: different unsigned tx`);
|
|
1005
|
-
this.global = psbt.mergeKeyMap(psbt.PSBTGlobal, this.global, other.global);
|
|
1004
|
+
this.global = psbt.mergeKeyMap(psbt.PSBTGlobal, this.global, other.global, undefined, this.opts.allowUnknown);
|
|
1006
1005
|
for (let i = 0; i < this.inputs.length; i++)
|
|
1007
1006
|
this.updateInput(i, other.inputs[i], true);
|
|
1008
1007
|
for (let i = 0; i < this.outputs.length; i++)
|