@btc-vision/bitcoin 6.4.5 → 6.4.7
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/browser/address.d.ts +9 -0
- package/browser/index.js +1 -1
- package/browser/psbt.d.ts +4 -2
- package/browser/transaction.d.ts +3 -0
- package/build/address.d.ts +9 -0
- package/build/address.js +25 -8
- package/build/psbt.d.ts +4 -2
- package/build/psbt.js +34 -10
- package/build/transaction.d.ts +3 -0
- package/build/transaction.js +3 -0
- package/package.json +1 -1
- package/src/address.ts +28 -8
- package/src/payments/p2op.ts +195 -195
- package/src/psbt.ts +2227 -2190
- package/src/transaction.ts +5 -0
package/browser/psbt.d.ts
CHANGED
|
@@ -43,6 +43,7 @@ export declare class Psbt {
|
|
|
43
43
|
clone(): Psbt;
|
|
44
44
|
setMaximumFeeRate(satoshiPerByte: number): void;
|
|
45
45
|
setVersion(version: number): this;
|
|
46
|
+
setVersionTRUC(): this;
|
|
46
47
|
setLocktime(locktime: number): this;
|
|
47
48
|
setInputSequence(inputIndex: number, sequence: number): this;
|
|
48
49
|
addInputs(inputDatas: PsbtInputExtended[], checkPartialSigs?: boolean): this;
|
|
@@ -98,6 +99,7 @@ export declare class Psbt {
|
|
|
98
99
|
export interface PsbtOptsOptional {
|
|
99
100
|
network?: Network;
|
|
100
101
|
maximumFeeRate?: number;
|
|
102
|
+
version?: 1 | 2 | 3;
|
|
101
103
|
}
|
|
102
104
|
export interface PsbtOpts {
|
|
103
105
|
network: Network;
|
|
@@ -155,11 +157,11 @@ type FinalScriptsFunc = (inputIndex: number, input: PsbtInput, script: Buffer, i
|
|
|
155
157
|
type FinalTaprootScriptsFunc = (inputIndex: number, input: PsbtInput, tapLeafHashToFinalize?: Buffer) => {
|
|
156
158
|
finalScriptWitness: Buffer | undefined;
|
|
157
159
|
};
|
|
158
|
-
export declare function getFinalScripts(inputIndex: number, input: PsbtInput, script: Buffer, isSegwit: boolean, isP2SH: boolean, isP2WSH: boolean, canRunChecks?: boolean): {
|
|
160
|
+
export declare function getFinalScripts(inputIndex: number, input: PsbtInput, script: Buffer, isSegwit: boolean, isP2SH: boolean, isP2WSH: boolean, canRunChecks?: boolean, solution?: Buffer[]): {
|
|
159
161
|
finalScriptSig: Buffer | undefined;
|
|
160
162
|
finalScriptWitness: Buffer | undefined;
|
|
161
163
|
};
|
|
162
|
-
export declare function prepareFinalScripts(script: Buffer, scriptType: string, partialSig: PartialSig[], isSegwit: boolean, isP2SH: boolean, isP2WSH: boolean): {
|
|
164
|
+
export declare function prepareFinalScripts(script: Buffer, scriptType: string, partialSig: PartialSig[], isSegwit: boolean, isP2SH: boolean, isP2WSH: boolean, solution?: Buffer[]): {
|
|
163
165
|
finalScriptSig: Buffer | undefined;
|
|
164
166
|
finalScriptWitness: Buffer | undefined;
|
|
165
167
|
};
|
package/browser/transaction.d.ts
CHANGED
|
@@ -20,6 +20,9 @@ export declare class Transaction {
|
|
|
20
20
|
static readonly SIGHASH_INPUT_MASK = 128;
|
|
21
21
|
static readonly ADVANCED_TRANSACTION_MARKER = 0;
|
|
22
22
|
static readonly ADVANCED_TRANSACTION_FLAG = 1;
|
|
23
|
+
static readonly TRUC_VERSION = 3;
|
|
24
|
+
static readonly TRUC_MAX_VSIZE = 10000;
|
|
25
|
+
static readonly TRUC_CHILD_MAX_VSIZE = 1000;
|
|
23
26
|
version: number;
|
|
24
27
|
locktime: number;
|
|
25
28
|
ins: Input[];
|
package/build/address.d.ts
CHANGED
|
@@ -8,7 +8,16 @@ export interface Bech32Result {
|
|
|
8
8
|
prefix: string;
|
|
9
9
|
data: Buffer;
|
|
10
10
|
}
|
|
11
|
+
export declare const FUTURE_SEGWIT_MAX_SIZE: number;
|
|
12
|
+
export declare const FUTURE_SEGWIT_MIN_SIZE: number;
|
|
13
|
+
export declare const FUTURE_SEGWIT_MAX_VERSION: number;
|
|
14
|
+
export declare const FUTURE_MAX_VERSION: number;
|
|
15
|
+
export declare const FUTURE_OPNET_VERSION: number;
|
|
16
|
+
export declare const FUTURE_SEGWIT_MIN_VERSION: number;
|
|
17
|
+
export declare const FUTURE_SEGWIT_VERSION_DIFF: number;
|
|
18
|
+
export declare const isUnknownSegwitVersion: (output: Buffer) => boolean;
|
|
11
19
|
export declare function toFutureOPNetAddress(output: Buffer, network: Network): string;
|
|
20
|
+
export declare function _toFutureSegwitAddress(output: Buffer, network: Network): string;
|
|
12
21
|
export declare function fromBase58Check(address: string): Base58CheckResult;
|
|
13
22
|
export declare function fromBech32(address: string): Bech32Result;
|
|
14
23
|
export declare function toBase58Check(hash: Buffer, version: number): string;
|
package/build/address.js
CHANGED
|
@@ -4,17 +4,34 @@ import { opcodes, payments } from './index.js';
|
|
|
4
4
|
import * as networks from './networks.js';
|
|
5
5
|
import * as bscript from './script.js';
|
|
6
6
|
import { Hash160bit, tuple, typeforce, UInt8 } from './types.js';
|
|
7
|
-
const FUTURE_SEGWIT_MAX_SIZE = 40;
|
|
8
|
-
const FUTURE_SEGWIT_MIN_SIZE = 2;
|
|
9
|
-
const FUTURE_SEGWIT_MAX_VERSION = 15;
|
|
10
|
-
const FUTURE_MAX_VERSION = 16;
|
|
11
|
-
const FUTURE_OPNET_VERSION = 16;
|
|
12
|
-
const FUTURE_SEGWIT_MIN_VERSION = 2;
|
|
13
|
-
const FUTURE_SEGWIT_VERSION_DIFF = 0x50;
|
|
7
|
+
export const FUTURE_SEGWIT_MAX_SIZE = 40;
|
|
8
|
+
export const FUTURE_SEGWIT_MIN_SIZE = 2;
|
|
9
|
+
export const FUTURE_SEGWIT_MAX_VERSION = 15;
|
|
10
|
+
export const FUTURE_MAX_VERSION = 16;
|
|
11
|
+
export const FUTURE_OPNET_VERSION = 16;
|
|
12
|
+
export const FUTURE_SEGWIT_MIN_VERSION = 2;
|
|
13
|
+
export const FUTURE_SEGWIT_VERSION_DIFF = 0x50;
|
|
14
14
|
const FUTURE_SEGWIT_VERSION_WARNING = 'WARNING: Sending to a future segwit version address can lead to loss of funds. ' +
|
|
15
15
|
'End users MUST be warned carefully in the GUI and asked if they wish to proceed ' +
|
|
16
16
|
'with caution. Wallets should verify the segwit version from the output of fromBech32, ' +
|
|
17
17
|
'then decide when it is safe to use which version of segwit.';
|
|
18
|
+
export const isUnknownSegwitVersion = (output) => {
|
|
19
|
+
try {
|
|
20
|
+
const data = output.subarray(2);
|
|
21
|
+
if (data.length < FUTURE_SEGWIT_MIN_SIZE || data.length > FUTURE_SEGWIT_MAX_SIZE) {
|
|
22
|
+
throw new TypeError('Invalid program length for segwit address');
|
|
23
|
+
}
|
|
24
|
+
const version = output[0] - FUTURE_SEGWIT_VERSION_DIFF;
|
|
25
|
+
if (version < FUTURE_SEGWIT_MIN_VERSION || version > FUTURE_SEGWIT_MAX_VERSION + 1) {
|
|
26
|
+
throw new TypeError('Invalid version for segwit address');
|
|
27
|
+
}
|
|
28
|
+
if (version === 1)
|
|
29
|
+
throw new TypeError('taproot');
|
|
30
|
+
return true;
|
|
31
|
+
}
|
|
32
|
+
catch (e) { }
|
|
33
|
+
return false;
|
|
34
|
+
};
|
|
18
35
|
export function toFutureOPNetAddress(output, network) {
|
|
19
36
|
if (!Buffer.isBuffer(output))
|
|
20
37
|
throw new TypeError('output must be a Buffer');
|
|
@@ -46,7 +63,7 @@ export function toFutureOPNetAddress(output, network) {
|
|
|
46
63
|
const words = [version, ...bech32m.toWords(program)];
|
|
47
64
|
return bech32m.encode(network.bech32Opnet, words);
|
|
48
65
|
}
|
|
49
|
-
function _toFutureSegwitAddress(output, network) {
|
|
66
|
+
export function _toFutureSegwitAddress(output, network) {
|
|
50
67
|
const data = output.subarray(2);
|
|
51
68
|
if (data.length < FUTURE_SEGWIT_MIN_SIZE || data.length > FUTURE_SEGWIT_MAX_SIZE) {
|
|
52
69
|
throw new TypeError('Invalid program length for segwit address');
|
package/build/psbt.d.ts
CHANGED
|
@@ -43,6 +43,7 @@ export declare class Psbt {
|
|
|
43
43
|
clone(): Psbt;
|
|
44
44
|
setMaximumFeeRate(satoshiPerByte: number): void;
|
|
45
45
|
setVersion(version: number): this;
|
|
46
|
+
setVersionTRUC(): this;
|
|
46
47
|
setLocktime(locktime: number): this;
|
|
47
48
|
setInputSequence(inputIndex: number, sequence: number): this;
|
|
48
49
|
addInputs(inputDatas: PsbtInputExtended[], checkPartialSigs?: boolean): this;
|
|
@@ -98,6 +99,7 @@ export declare class Psbt {
|
|
|
98
99
|
export interface PsbtOptsOptional {
|
|
99
100
|
network?: Network;
|
|
100
101
|
maximumFeeRate?: number;
|
|
102
|
+
version?: 1 | 2 | 3;
|
|
101
103
|
}
|
|
102
104
|
export interface PsbtOpts {
|
|
103
105
|
network: Network;
|
|
@@ -155,11 +157,11 @@ type FinalScriptsFunc = (inputIndex: number, input: PsbtInput, script: Buffer, i
|
|
|
155
157
|
type FinalTaprootScriptsFunc = (inputIndex: number, input: PsbtInput, tapLeafHashToFinalize?: Buffer) => {
|
|
156
158
|
finalScriptWitness: Buffer | undefined;
|
|
157
159
|
};
|
|
158
|
-
export declare function getFinalScripts(inputIndex: number, input: PsbtInput, script: Buffer, isSegwit: boolean, isP2SH: boolean, isP2WSH: boolean, canRunChecks?: boolean): {
|
|
160
|
+
export declare function getFinalScripts(inputIndex: number, input: PsbtInput, script: Buffer, isSegwit: boolean, isP2SH: boolean, isP2WSH: boolean, canRunChecks?: boolean, solution?: Buffer[]): {
|
|
159
161
|
finalScriptSig: Buffer | undefined;
|
|
160
162
|
finalScriptWitness: Buffer | undefined;
|
|
161
163
|
};
|
|
162
|
-
export declare function prepareFinalScripts(script: Buffer, scriptType: string, partialSig: PartialSig[], isSegwit: boolean, isP2SH: boolean, isP2WSH: boolean): {
|
|
164
|
+
export declare function prepareFinalScripts(script: Buffer, scriptType: string, partialSig: PartialSig[], isSegwit: boolean, isP2SH: boolean, isP2WSH: boolean, solution?: Buffer[]): {
|
|
163
165
|
finalScriptSig: Buffer | undefined;
|
|
164
166
|
finalScriptWitness: Buffer | undefined;
|
|
165
167
|
};
|
package/build/psbt.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Psbt as PsbtBase } from 'bip174';
|
|
2
2
|
import * as varuint from 'bip174/src/lib/converter/varint.js';
|
|
3
3
|
import { checkForInput, checkForOutput } from 'bip174/src/lib/utils.js';
|
|
4
|
-
import { fromOutputScript, toOutputScript } from './address.js';
|
|
4
|
+
import { fromOutputScript, isUnknownSegwitVersion, toOutputScript } from './address.js';
|
|
5
5
|
import { cloneBuffer, reverseBuffer } from './bufferutils.js';
|
|
6
6
|
import { payments } from './index.js';
|
|
7
7
|
import { bitcoin as btcNetwork } from './networks.js';
|
|
@@ -25,7 +25,10 @@ export class Psbt {
|
|
|
25
25
|
__TX: this.data.globalMap.unsignedTx.tx,
|
|
26
26
|
__UNSAFE_SIGN_NONSEGWIT: false,
|
|
27
27
|
};
|
|
28
|
-
if (
|
|
28
|
+
if (opts.version === 3) {
|
|
29
|
+
this.setVersionTRUC();
|
|
30
|
+
}
|
|
31
|
+
else if (this.data.inputs.length === 0)
|
|
29
32
|
this.setVersion(2);
|
|
30
33
|
const dpew = (obj, attr, enumerable, writable) => {
|
|
31
34
|
Object.defineProperty(obj, attr, {
|
|
@@ -105,6 +108,9 @@ export class Psbt {
|
|
|
105
108
|
c.__EXTRACTED_TX = undefined;
|
|
106
109
|
return this;
|
|
107
110
|
}
|
|
111
|
+
setVersionTRUC() {
|
|
112
|
+
return this.setVersion(Transaction.TRUC_VERSION);
|
|
113
|
+
}
|
|
108
114
|
setLocktime(locktime) {
|
|
109
115
|
check32Bit(locktime);
|
|
110
116
|
checkInputsForPartialSig(this.data.inputs, 'setLocktime');
|
|
@@ -818,14 +824,14 @@ function getTxCacheValue(key, name, inputs, c, disableOutputChecks = false) {
|
|
|
818
824
|
else if (key === '__FEE')
|
|
819
825
|
return c.__FEE;
|
|
820
826
|
}
|
|
821
|
-
export function getFinalScripts(inputIndex, input, script, isSegwit, isP2SH, isP2WSH, canRunChecks = true) {
|
|
827
|
+
export function getFinalScripts(inputIndex, input, script, isSegwit, isP2SH, isP2WSH, canRunChecks = true, solution) {
|
|
822
828
|
const scriptType = classifyScript(script);
|
|
823
829
|
if (!canFinalize(input, script, scriptType) && canRunChecks) {
|
|
824
830
|
throw new Error(`Can not finalize input #${inputIndex}`);
|
|
825
831
|
}
|
|
826
|
-
return prepareFinalScripts(script, scriptType, input.partialSig, isSegwit, isP2SH, isP2WSH);
|
|
832
|
+
return prepareFinalScripts(script, scriptType, input.partialSig, isSegwit, isP2SH, isP2WSH, solution);
|
|
827
833
|
}
|
|
828
|
-
export function prepareFinalScripts(script, scriptType, partialSig, isSegwit, isP2SH, isP2WSH) {
|
|
834
|
+
export function prepareFinalScripts(script, scriptType, partialSig, isSegwit, isP2SH, isP2WSH, solution) {
|
|
829
835
|
let finalScriptSig;
|
|
830
836
|
let finalScriptWitness;
|
|
831
837
|
const payment = getPayment(script, scriptType, partialSig);
|
|
@@ -835,19 +841,28 @@ export function prepareFinalScripts(script, scriptType, partialSig, isSegwit, is
|
|
|
835
841
|
if (p2wsh) {
|
|
836
842
|
finalScriptWitness = witnessStackToScriptWitness(p2wsh.witness);
|
|
837
843
|
}
|
|
838
|
-
else {
|
|
844
|
+
else if (payment) {
|
|
839
845
|
finalScriptWitness = witnessStackToScriptWitness(payment.witness);
|
|
840
846
|
}
|
|
847
|
+
else {
|
|
848
|
+
finalScriptWitness = witnessStackToScriptWitness(solution ?? [Buffer.from([0x00])]);
|
|
849
|
+
}
|
|
841
850
|
if (p2sh) {
|
|
842
|
-
finalScriptSig = p2sh
|
|
851
|
+
finalScriptSig = p2sh?.input;
|
|
843
852
|
}
|
|
844
853
|
}
|
|
845
854
|
else {
|
|
846
855
|
if (p2sh) {
|
|
847
|
-
finalScriptSig = p2sh
|
|
856
|
+
finalScriptSig = p2sh?.input;
|
|
848
857
|
}
|
|
849
858
|
else {
|
|
850
|
-
|
|
859
|
+
if (!payment) {
|
|
860
|
+
finalScriptSig =
|
|
861
|
+
Array.isArray(solution) && solution[0] ? solution[0] : Buffer.from([0x01]);
|
|
862
|
+
}
|
|
863
|
+
else {
|
|
864
|
+
finalScriptSig = payment.input;
|
|
865
|
+
}
|
|
851
866
|
}
|
|
852
867
|
}
|
|
853
868
|
return {
|
|
@@ -1043,6 +1058,15 @@ function getScriptFromInput(inputIndex, input, cache) {
|
|
|
1043
1058
|
if (input.witnessScript || isP2WPKH(res.script)) {
|
|
1044
1059
|
res.isSegwit = true;
|
|
1045
1060
|
}
|
|
1061
|
+
else {
|
|
1062
|
+
try {
|
|
1063
|
+
const output = res.script;
|
|
1064
|
+
if (!output)
|
|
1065
|
+
throw new TypeError('Invalid script for segwit address');
|
|
1066
|
+
res.isSegwit = isUnknownSegwitVersion(output);
|
|
1067
|
+
}
|
|
1068
|
+
catch (e) { }
|
|
1069
|
+
}
|
|
1046
1070
|
return res;
|
|
1047
1071
|
}
|
|
1048
1072
|
function getSignersFromHD(inputIndex, inputs, hdKeyPair) {
|
|
@@ -1167,7 +1191,7 @@ function inputFinalizeGetAmts(inputs, tx, cache, mustFinalize, disableOutputChec
|
|
|
1167
1191
|
const fee = inputAmount - outputAmount;
|
|
1168
1192
|
if (!disableOutputChecks) {
|
|
1169
1193
|
if (fee < 0) {
|
|
1170
|
-
throw new Error(
|
|
1194
|
+
throw new Error(`Outputs are spending more than Inputs ${inputAmount} < ${outputAmount}`);
|
|
1171
1195
|
}
|
|
1172
1196
|
}
|
|
1173
1197
|
const bytes = tx.virtualSize();
|
package/build/transaction.d.ts
CHANGED
|
@@ -20,6 +20,9 @@ export declare class Transaction {
|
|
|
20
20
|
static readonly SIGHASH_INPUT_MASK = 128;
|
|
21
21
|
static readonly ADVANCED_TRANSACTION_MARKER = 0;
|
|
22
22
|
static readonly ADVANCED_TRANSACTION_FLAG = 1;
|
|
23
|
+
static readonly TRUC_VERSION = 3;
|
|
24
|
+
static readonly TRUC_MAX_VSIZE = 10000;
|
|
25
|
+
static readonly TRUC_CHILD_MAX_VSIZE = 1000;
|
|
23
26
|
version: number;
|
|
24
27
|
locktime: number;
|
|
25
28
|
ins: Input[];
|
package/build/transaction.js
CHANGED
|
@@ -443,3 +443,6 @@ Transaction.SIGHASH_OUTPUT_MASK = 0x03;
|
|
|
443
443
|
Transaction.SIGHASH_INPUT_MASK = 0x80;
|
|
444
444
|
Transaction.ADVANCED_TRANSACTION_MARKER = 0x00;
|
|
445
445
|
Transaction.ADVANCED_TRANSACTION_FLAG = 0x01;
|
|
446
|
+
Transaction.TRUC_VERSION = 3;
|
|
447
|
+
Transaction.TRUC_MAX_VSIZE = 10000;
|
|
448
|
+
Transaction.TRUC_CHILD_MAX_VSIZE = 1000;
|
package/package.json
CHANGED
package/src/address.ts
CHANGED
|
@@ -33,19 +33,39 @@ export interface Bech32Result {
|
|
|
33
33
|
data: Buffer;
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
const FUTURE_SEGWIT_MAX_SIZE: number = 40;
|
|
37
|
-
const FUTURE_SEGWIT_MIN_SIZE: number = 2;
|
|
38
|
-
const FUTURE_SEGWIT_MAX_VERSION: number = 15;
|
|
39
|
-
const FUTURE_MAX_VERSION: number = 16;
|
|
40
|
-
const FUTURE_OPNET_VERSION: number = 16;
|
|
41
|
-
const FUTURE_SEGWIT_MIN_VERSION: number = 2;
|
|
42
|
-
const FUTURE_SEGWIT_VERSION_DIFF: number = 0x50;
|
|
36
|
+
export const FUTURE_SEGWIT_MAX_SIZE: number = 40;
|
|
37
|
+
export const FUTURE_SEGWIT_MIN_SIZE: number = 2;
|
|
38
|
+
export const FUTURE_SEGWIT_MAX_VERSION: number = 15;
|
|
39
|
+
export const FUTURE_MAX_VERSION: number = 16;
|
|
40
|
+
export const FUTURE_OPNET_VERSION: number = 16;
|
|
41
|
+
export const FUTURE_SEGWIT_MIN_VERSION: number = 2;
|
|
42
|
+
export const FUTURE_SEGWIT_VERSION_DIFF: number = 0x50;
|
|
43
43
|
const FUTURE_SEGWIT_VERSION_WARNING: string =
|
|
44
44
|
'WARNING: Sending to a future segwit version address can lead to loss of funds. ' +
|
|
45
45
|
'End users MUST be warned carefully in the GUI and asked if they wish to proceed ' +
|
|
46
46
|
'with caution. Wallets should verify the segwit version from the output of fromBech32, ' +
|
|
47
47
|
'then decide when it is safe to use which version of segwit.';
|
|
48
48
|
|
|
49
|
+
export const isUnknownSegwitVersion = (output: Buffer): boolean => {
|
|
50
|
+
try {
|
|
51
|
+
const data = output.subarray(2);
|
|
52
|
+
if (data.length < FUTURE_SEGWIT_MIN_SIZE || data.length > FUTURE_SEGWIT_MAX_SIZE) {
|
|
53
|
+
throw new TypeError('Invalid program length for segwit address');
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const version = output[0] - FUTURE_SEGWIT_VERSION_DIFF;
|
|
57
|
+
if (version < FUTURE_SEGWIT_MIN_VERSION || version > FUTURE_SEGWIT_MAX_VERSION + 1) {
|
|
58
|
+
throw new TypeError('Invalid version for segwit address');
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
if (version === 1) throw new TypeError('taproot');
|
|
62
|
+
|
|
63
|
+
return true;
|
|
64
|
+
} catch (e) {}
|
|
65
|
+
|
|
66
|
+
return false;
|
|
67
|
+
};
|
|
68
|
+
|
|
49
69
|
/**
|
|
50
70
|
* Encode a future Taproot-style segwit address (SegWit v2 - v16) using bech32m.
|
|
51
71
|
* Only for versions not yet assigned specific meanings (future use).
|
|
@@ -92,7 +112,7 @@ export function toFutureOPNetAddress(output: Buffer, network: Network): string {
|
|
|
92
112
|
return bech32m.encode(network.bech32Opnet, words);
|
|
93
113
|
}
|
|
94
114
|
|
|
95
|
-
function _toFutureSegwitAddress(output: Buffer, network: Network): string {
|
|
115
|
+
export function _toFutureSegwitAddress(output: Buffer, network: Network): string {
|
|
96
116
|
const data = output.subarray(2);
|
|
97
117
|
if (data.length < FUTURE_SEGWIT_MIN_SIZE || data.length > FUTURE_SEGWIT_MAX_SIZE) {
|
|
98
118
|
throw new TypeError('Invalid program length for segwit address');
|