Skip to content

Commit 16d62c6

Browse files
committed
Merge branch 'master' of github.com:bitcoinjs/bitcoinjs-lib
2 parents 8bf16e9 + 0b0130d commit 16d62c6

File tree

22 files changed

+405
-75
lines changed

22 files changed

+405
-75
lines changed

src/cjs/index.cjs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ Object.defineProperty(exports, '__esModule', { value: true });
4747
exports.initEccLib =
4848
exports.Transaction =
4949
exports.opcodes =
50+
exports.toXOnly =
5051
exports.Psbt =
5152
exports.Block =
5253
exports.script =
@@ -79,6 +80,12 @@ Object.defineProperty(exports, 'Psbt', {
7980
return psbt_js_1.Psbt;
8081
},
8182
});
83+
Object.defineProperty(exports, 'toXOnly', {
84+
enumerable: true,
85+
get: function () {
86+
return psbt_js_1.toXOnly;
87+
},
88+
});
8289
/** @hidden */
8390
var ops_js_1 = require('./ops.cjs');
8491
Object.defineProperty(exports, 'opcodes', {

src/cjs/index.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ export { address, crypto, networks, payments, script };
77
export { Block } from './block.js';
88
/** @hidden */
99
export { TaggedHashPrefix } from './crypto.js';
10-
export { Psbt, PsbtTxInput, PsbtTxOutput, Signer, SignerAsync, HDSigner, HDSignerAsync, } from './psbt.js';
10+
export { Psbt, PsbtTxInput, PsbtTxOutput, Signer, SignerAsync, HDSigner, HDSignerAsync, toXOnly, } from './psbt.js';
1111
/** @hidden */
1212
export { OPS as opcodes } from './ops.js';
1313
export { Transaction } from './transaction.js';

src/cjs/networks.cjs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11
'use strict';
2-
// https://en.bitcoin.it/wiki/List_of_address_prefixes
3-
// Dogecoin BIP32 is a proposed standard: https://bitcointalk.org/index.php?topic=409731
42
Object.defineProperty(exports, '__esModule', { value: true });
53
exports.testnet = exports.regtest = exports.bitcoin = void 0;
64
/**

src/cjs/networks.d.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
/**
2-
* Represents a Bitcoin network configuration,including messagePrefix, bech32, bip32, pubKeyHash, scriptHash, wif.
3-
* Support bitcoin、bitcoin testnet and bitcoin regtest.
2+
* This module defines the network configurations for Bitcoin and its variants, including message prefixes,
3+
* Bech32 address format, BIP32 key derivation prefixes, and other address-related configurations.
4+
* It supports Bitcoin, Bitcoin testnet, and Bitcoin regtest networks.
5+
*
6+
* Additional information on address prefixes can be found here:
7+
* - https://en.bitcoin.it/wiki/List_of_address_prefixes
8+
*
49
* @packageDocumentation
510
*/
611
export interface Network {

src/cjs/payments/index.d.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,15 @@
11
/**
2-
* Represents a payment object, which is used to create a payment.
2+
* Provides functionality for creating and managing Bitcoin payment objects.
33
*
4-
* Supports P2PKH、P2SH、P2WPKH、P2WSH、P2TR and so on
4+
* This module supports multiple Bitcoin address types for payments, including:
5+
* - P2PKH (Pay-to-PubKey-Hash)
6+
* - P2SH (Pay-to-Script-Hash)
7+
* - P2WPKH (Pay-to-Witness-PubKey-Hash)
8+
* - P2WSH (Pay-to-Witness-Script-Hash)
9+
* - P2TR (Taproot)
10+
*
11+
* The `Payment` interface defines the structure of a payment object used for constructing various
12+
* payment types, with fields for signatures, public keys, redeem scripts, and more.
513
*
614
* @packageDocumentation
715
*/

src/cjs/psbt.cjs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ var __importStar =
4444
return result;
4545
};
4646
Object.defineProperty(exports, '__esModule', { value: true });
47-
exports.Psbt = void 0;
47+
exports.Psbt = exports.toXOnly = void 0;
4848
const bip174_1 = require('bip174');
4949
const varuint = __importStar(require('varuint-bitcoin'));
5050
const bip174_2 = require('bip174');
@@ -56,6 +56,12 @@ const bip341_js_1 = require('./payments/bip341.cjs');
5656
const bscript = __importStar(require('./script.cjs'));
5757
const transaction_js_1 = require('./transaction.cjs');
5858
const bip371_js_1 = require('./psbt/bip371.cjs');
59+
Object.defineProperty(exports, 'toXOnly', {
60+
enumerable: true,
61+
get: function () {
62+
return bip371_js_1.toXOnly;
63+
},
64+
});
5965
const psbtutils_js_1 = require('./psbt/psbtutils.cjs');
6066
const tools = __importStar(require('uint8array-tools'));
6167
/**

src/cjs/psbt.d.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ import { Psbt as PsbtBase } from 'bip174';
22
import { KeyValue, PsbtGlobalUpdate, PsbtInput, PsbtInputUpdate, PsbtOutput, PsbtOutputUpdate } from 'bip174';
33
import { Network } from './networks.js';
44
import { Transaction } from './transaction.js';
5+
import { toXOnly } from './psbt/bip371.js';
6+
export { toXOnly };
57
export interface TransactionInput {
68
hash: string | Uint8Array;
79
index: number;
@@ -202,4 +204,3 @@ tapLeafHashToFinalize?: Uint8Array) => {
202204
finalScriptWitness: Uint8Array | undefined;
203205
};
204206
type AllScriptType = 'witnesspubkeyhash' | 'pubkeyhash' | 'multisig' | 'pubkey' | 'nonstandard' | 'p2sh-witnesspubkeyhash' | 'p2sh-pubkeyhash' | 'p2sh-multisig' | 'p2sh-pubkey' | 'p2sh-nonstandard' | 'p2wsh-pubkeyhash' | 'p2wsh-multisig' | 'p2wsh-pubkey' | 'p2wsh-nonstandard' | 'p2sh-p2wsh-pubkeyhash' | 'p2sh-p2wsh-multisig' | 'p2sh-p2wsh-pubkey' | 'p2sh-p2wsh-nonstandard';
205-
export {};

src/cjs/psbt/bip371.cjs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,7 @@ function extractTaprootSigs(input) {
283283
if (input.tapScriptSig)
284284
sigs.push(...input.tapScriptSig.map(s => s.signature));
285285
if (!sigs.length) {
286-
const finalTapKeySig = getTapKeySigFromWithness(input.finalScriptWitness);
286+
const finalTapKeySig = getTapKeySigFromWitness(input.finalScriptWitness);
287287
if (finalTapKeySig) sigs.push(finalTapKeySig);
288288
}
289289
return sigs;
@@ -293,7 +293,7 @@ function extractTaprootSigs(input) {
293293
* @param finalScriptWitness The final script witness.
294294
* @returns The taproot signature, or undefined if not found.
295295
*/
296-
function getTapKeySigFromWithness(finalScriptWitness) {
296+
function getTapKeySigFromWitness(finalScriptWitness) {
297297
if (!finalScriptWitness) return;
298298
const witness = finalScriptWitness.slice(2);
299299
// todo: add schnorr signature validation

src/cjs/script.cjs

Lines changed: 91 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,11 @@
11
'use strict';
2+
/**
3+
* Script tools module for working with Bitcoin scripts.
4+
* Provides utilities such as decompiling, compiling, converting to/from ASM, stack manipulation,
5+
* and script validation functions.
6+
*
7+
* @packageDocumentation
8+
*/
29
var __createBinding =
310
(this && this.__createBinding) ||
411
(Object.create
@@ -55,10 +62,6 @@ exports.toStack = toStack;
5562
exports.isCanonicalPubKey = isCanonicalPubKey;
5663
exports.isDefinedHashType = isDefinedHashType;
5764
exports.isCanonicalScriptSignature = isCanonicalScriptSignature;
58-
/**
59-
* Script tools, including decompile, compile, toASM, fromASM, toStack, isCanonicalPubKey, isCanonicalScriptSignature
60-
* @packageDocumentation
61-
*/
6265
const bip66 = __importStar(require('./bip66.cjs'));
6366
const ops_js_1 = require('./ops.cjs');
6467
Object.defineProperty(exports, 'OPS', {
@@ -73,8 +76,16 @@ const scriptSignature = __importStar(require('./script_signature.cjs'));
7376
const types = __importStar(require('./types.cjs'));
7477
const tools = __importStar(require('uint8array-tools'));
7578
const v = __importStar(require('valibot'));
79+
/** Base opcode for OP_INT values. */
7680
const OP_INT_BASE = ops_js_1.OPS.OP_RESERVED; // OP_1 - 1
81+
/** Validation schema for a Bitcoin script stack. */
7782
const StackSchema = v.array(v.union([v.instance(Uint8Array), v.number()]));
83+
/**
84+
* Determines if a value corresponds to an OP_INT opcode.
85+
*
86+
* @param value - The opcode to check.
87+
* @returns True if the value is an OP_INT, false otherwise.
88+
*/
7889
function isOPInt(value) {
7990
return (
8091
v.is(v.number(), value) &&
@@ -83,57 +94,95 @@ function isOPInt(value) {
8394
value === ops_js_1.OPS.OP_1NEGATE)
8495
);
8596
}
97+
/**
98+
* Checks if a script chunk is push-only (contains only data or OP_INT opcodes).
99+
*
100+
* @param value - The chunk to check.
101+
* @returns True if the chunk is push-only, false otherwise.
102+
*/
86103
function isPushOnlyChunk(value) {
87104
return v.is(types.BufferSchema, value) || isOPInt(value);
88105
}
106+
/**
107+
* Determines if a stack consists of only push operations.
108+
*
109+
* @param value - The stack to check.
110+
* @returns True if all elements in the stack are push-only, false otherwise.
111+
*/
89112
function isPushOnly(value) {
90113
return v.is(v.pipe(v.any(), v.everyItem(isPushOnlyChunk)), value);
91114
}
115+
/**
116+
* Counts the number of non-push-only opcodes in a stack.
117+
*
118+
* @param value - The stack to analyze.
119+
* @returns The count of non-push-only opcodes.
120+
*/
92121
function countNonPushOnlyOPs(value) {
93122
return value.length - value.filter(isPushOnlyChunk).length;
94123
}
124+
/**
125+
* Converts a minimal script buffer to its corresponding opcode, if applicable.
126+
*
127+
* @param buffer - The buffer to check.
128+
* @returns The corresponding opcode or undefined if not minimal.
129+
*/
95130
function asMinimalOP(buffer) {
96131
if (buffer.length === 0) return ops_js_1.OPS.OP_0;
97132
if (buffer.length !== 1) return;
98133
if (buffer[0] >= 1 && buffer[0] <= 16) return OP_INT_BASE + buffer[0];
99134
if (buffer[0] === 0x81) return ops_js_1.OPS.OP_1NEGATE;
100135
}
136+
/**
137+
* Determines if a buffer or stack is a Uint8Array.
138+
*
139+
* @param buf - The buffer or stack to check.
140+
* @returns True if the input is a Uint8Array, false otherwise.
141+
*/
101142
function chunksIsBuffer(buf) {
102143
return buf instanceof Uint8Array;
103144
}
145+
/**
146+
* Determines if a buffer or stack is a valid stack.
147+
*
148+
* @param buf - The buffer or stack to check.
149+
* @returns True if the input is a stack, false otherwise.
150+
*/
104151
function chunksIsArray(buf) {
105152
return v.is(StackSchema, buf);
106153
}
154+
/**
155+
* Determines if a single chunk is a Uint8Array.
156+
*
157+
* @param buf - The chunk to check.
158+
* @returns True if the chunk is a Uint8Array, false otherwise.
159+
*/
107160
function singleChunkIsBuffer(buf) {
108161
return buf instanceof Uint8Array;
109162
}
110163
/**
111-
* Compiles an array of chunks into a Buffer.
164+
* Compiles an array of script chunks into a Uint8Array.
112165
*
113-
* @param chunks - The array of chunks to compile.
114-
* @returns The compiled Buffer.
115-
* @throws Error if the compilation fails.
166+
* @param chunks - The chunks to compile.
167+
* @returns The compiled script as a Uint8Array.
168+
* @throws Error if compilation fails.
116169
*/
117170
function compile(chunks) {
118-
// TODO: remove me
119171
if (chunksIsBuffer(chunks)) return chunks;
120172
v.parse(StackSchema, chunks);
121173
const bufferSize = chunks.reduce((accum, chunk) => {
122-
// data chunk
123174
if (singleChunkIsBuffer(chunk)) {
124175
// adhere to BIP62.3, minimal push policy
125176
if (chunk.length === 1 && asMinimalOP(chunk) !== undefined) {
126177
return accum + 1;
127178
}
128179
return accum + pushdata.encodingLength(chunk.length) + chunk.length;
129180
}
130-
// opcode
131181
return accum + 1;
132-
}, 0.0);
182+
}, 0);
133183
const buffer = new Uint8Array(bufferSize);
134184
let offset = 0;
135185
chunks.forEach(chunk => {
136-
// data chunk
137186
if (singleChunkIsBuffer(chunk)) {
138187
// adhere to BIP62.3, minimal push policy
139188
const opcode = asMinimalOP(chunk);
@@ -154,15 +203,19 @@ function compile(chunks) {
154203
if (offset !== buffer.length) throw new Error('Could not decode chunks');
155204
return buffer;
156205
}
206+
/**
207+
* Decompiles a script buffer into an array of chunks.
208+
*
209+
* @param buffer - The script buffer to decompile.
210+
* @returns The decompiled chunks or null if decompilation fails.
211+
*/
157212
function decompile(buffer) {
158-
// TODO: remove me
159213
if (chunksIsArray(buffer)) return buffer;
160214
v.parse(types.BufferSchema, buffer);
161215
const chunks = [];
162216
let i = 0;
163217
while (i < buffer.length) {
164218
const opcode = buffer[i];
165-
// data chunk
166219
if (opcode > ops_js_1.OPS.OP_0 && opcode <= ops_js_1.OPS.OP_PUSHDATA4) {
167220
const d = pushdata.decode(buffer, i);
168221
// did reading a pushDataInt fail?
@@ -179,7 +232,6 @@ function decompile(buffer) {
179232
} else {
180233
chunks.push(data);
181234
}
182-
// opcode
183235
} else {
184236
chunks.push(opcode);
185237
i += 1;
@@ -202,7 +254,6 @@ function toASM(chunks) {
202254
}
203255
return chunks
204256
.map(chunk => {
205-
// data?
206257
if (singleChunkIsBuffer(chunk)) {
207258
const op = asMinimalOP(chunk);
208259
if (op === undefined) return tools.toHex(chunk);
@@ -249,13 +300,36 @@ function toStack(chunks) {
249300
return scriptNumber.encode(op - OP_INT_BASE);
250301
});
251302
}
303+
/**
304+
* Checks if the provided buffer is a canonical public key.
305+
*
306+
* @param buffer - The buffer to check, expected to be a Uint8Array.
307+
* @returns A boolean indicating whether the buffer is a canonical public key.
308+
*/
252309
function isCanonicalPubKey(buffer) {
253310
return types.isPoint(buffer);
254311
}
312+
/**
313+
* Checks if the provided hash type is defined.
314+
*
315+
* A hash type is considered defined if its modified value (after masking with ~0x80)
316+
* is greater than 0x00 and less than 0x04.
317+
*
318+
* @param hashType - The hash type to check.
319+
* @returns True if the hash type is defined, false otherwise.
320+
*/
255321
function isDefinedHashType(hashType) {
256322
const hashTypeMod = hashType & ~0x80;
257323
return hashTypeMod > 0x00 && hashTypeMod < 0x04;
258324
}
325+
/**
326+
* Checks if the provided buffer is a canonical script signature.
327+
*
328+
* A canonical script signature is a valid DER-encoded signature followed by a valid hash type byte.
329+
*
330+
* @param buffer - The buffer to check.
331+
* @returns `true` if the buffer is a canonical script signature, `false` otherwise.
332+
*/
259333
function isCanonicalScriptSignature(buffer) {
260334
if (!(buffer instanceof Uint8Array)) return false;
261335
if (!isDefinedHashType(buffer[buffer.length - 1])) return false;

0 commit comments

Comments
 (0)