@alexbosworth/blockchain 3.0.0 → 3.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +14 -0
- package/README.md +132 -0
- package/addresses/bech32_type.js +52 -0
- package/addresses/decode_bech32.js +79 -0
- package/addresses/decode_bech32_address.js +86 -0
- package/addresses/index.js +2 -1
- package/addresses/modify_bech32_accumulator.js +24 -0
- package/hashes/id_for_transaction_components.js +2 -0
- package/index.js +16 -0
- package/package.json +1 -1
- package/script/index.js +14 -1
- package/script/p2pkh_output_script.js +37 -0
- package/script/p2sh_output_script.js +35 -0
- package/script/p2tr_output_script.js +32 -0
- package/script/p2wpkh_output_script.js +32 -0
- package/script/p2wsh_output_script.js +32 -0
- package/script/script_elements_as_output.js +41 -0
- package/script/script_elements_as_script.js +3 -22
- package/test/addresses/test_bech32_type.js +29 -0
- package/test/addresses/test_decode_bech32.js +49 -0
- package/test/addresses/test_decode_bech32_address.js +188 -0
- package/test/script/test_p2pkh_output_script.js +41 -0
- package/test/script/test_p2sh_output_script.js +41 -0
- package/test/script/test_p2tr_output_script.js +43 -0
- package/test/script/test_p2wpkh_output_script.js +41 -0
- package/test/script/test_p2wsh_output_script.js +43 -0
- package/test/transactions/test_id_for_transaction.js +72 -0
- package/test/transactions/test_unsigned_tx_from_psbt.js +72 -0
- package/transactions/id_for_transaction.js +39 -0
- package/transactions/index.js +4 -0
- package/transactions/parse_transaction.js +9 -11
- package/transactions/unsigned_tx_from_psbt.js +47 -0
- /package/test/addresses/{decode_base58_address.js → test_decode_base58_address.js} +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# Versions
|
|
2
2
|
|
|
3
|
+
## 3.2.0
|
|
4
|
+
|
|
5
|
+
- `decode_bech32_address.js`: Add method to decode a bech32/bech32m address
|
|
6
|
+
- `id_for_transaction.js`: Add method to derive the standard tx id for a raw tx
|
|
7
|
+
|
|
8
|
+
## 3.1.0
|
|
9
|
+
|
|
10
|
+
- `p2pkhOutputScript`: Add method to get an output script for a p2wpkh hash
|
|
11
|
+
- `p2shOutputScript`: Add method to get an output script for a p2sh hash
|
|
12
|
+
- `p2trOutputScript`: Add method to get an output script for a p2tr hash
|
|
13
|
+
- `p2wpkhOutputScript`: Add method to get an output script for a p2wpkh hash
|
|
14
|
+
- `p2wshOutputScript`: Add method to get an output script for a p2wsh hash
|
|
15
|
+
- `unsignedTxFromPsbt`: Add method to get the unsigned tx out of a PSBT
|
|
16
|
+
|
|
3
17
|
## 3.0.0
|
|
4
18
|
|
|
5
19
|
- `decodeBase58Address`: Add method to convert b58 address to hash and version
|
package/README.md
CHANGED
|
@@ -73,6 +73,24 @@ Derive output hash and version data from a base58 address string
|
|
|
73
73
|
version: <Script Version Byte Number>
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
+
### decodeBech32Address
|
|
77
|
+
|
|
78
|
+
Decode a bech32 address string to derive the address details
|
|
79
|
+
|
|
80
|
+
{
|
|
81
|
+
address: <Bech32 Encoded Address String>
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
@throws
|
|
85
|
+
<Error>
|
|
86
|
+
|
|
87
|
+
@returns
|
|
88
|
+
{
|
|
89
|
+
data: <Output Data Buffer Object>
|
|
90
|
+
prefix: <Human Readable Prefix String>
|
|
91
|
+
version: <Witness Version Number>
|
|
92
|
+
}
|
|
93
|
+
|
|
76
94
|
### idForBlock
|
|
77
95
|
|
|
78
96
|
Get an id for a block: the double sha256 hash of the block header
|
|
@@ -89,10 +107,28 @@ Get an id for a block: the double sha256 hash of the block header
|
|
|
89
107
|
id: <Block Id Hex Encoded String>
|
|
90
108
|
}
|
|
91
109
|
|
|
110
|
+
### idForTransaction
|
|
111
|
+
|
|
112
|
+
Derive the standard transaction id for a raw serialized tx
|
|
113
|
+
|
|
114
|
+
{
|
|
115
|
+
transaction: <Hex Encoded Transaction String>
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
@throws
|
|
119
|
+
<Error>
|
|
120
|
+
|
|
121
|
+
@returns
|
|
122
|
+
{
|
|
123
|
+
id: <Transaction Id Hex Encoded String>
|
|
124
|
+
}
|
|
125
|
+
|
|
92
126
|
### idForTransactionComponents
|
|
93
127
|
|
|
94
128
|
Determine a transaction id from transaction components
|
|
95
129
|
|
|
130
|
+
Note: remember the input hash is the reversed byte order of a normal tx id
|
|
131
|
+
|
|
96
132
|
{
|
|
97
133
|
inputs: [{
|
|
98
134
|
hash: <Spending Internal Byte Order Transaction Id Buffer Object>
|
|
@@ -149,6 +185,86 @@ Convert a number to compact size integer serialization
|
|
|
149
185
|
encoded: <Serialized Compact Integer Buffer Object>
|
|
150
186
|
}
|
|
151
187
|
|
|
188
|
+
### p2pkhOutputScript
|
|
189
|
+
|
|
190
|
+
Get a Pay To Witness Public Key Hash Output Script
|
|
191
|
+
|
|
192
|
+
{
|
|
193
|
+
hash: <Public Key Hash Buffer Object>
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
@throws
|
|
197
|
+
<Error>
|
|
198
|
+
|
|
199
|
+
@returns
|
|
200
|
+
{
|
|
201
|
+
script: <Output Script Buffer Object>
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
### p2shOutputScript
|
|
205
|
+
|
|
206
|
+
Get a Pay To Script Hash Output Script
|
|
207
|
+
|
|
208
|
+
{
|
|
209
|
+
hash: <Script Hash Buffer Object>
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
@throws
|
|
213
|
+
<Error>
|
|
214
|
+
|
|
215
|
+
@returns
|
|
216
|
+
{
|
|
217
|
+
script: <Output Script Buffer Object>
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
### p2trOutputScript
|
|
221
|
+
|
|
222
|
+
Get a Pay To Taproot Output Script
|
|
223
|
+
|
|
224
|
+
{
|
|
225
|
+
hash: <Taproot Hash Buffer Object>
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
@throws
|
|
229
|
+
<Error>
|
|
230
|
+
|
|
231
|
+
@returns
|
|
232
|
+
{
|
|
233
|
+
script: <Output Script Buffer Object>
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
### p2wpkhOutputScript
|
|
237
|
+
|
|
238
|
+
Get a Pay To Witness Public Key Hash Output Script
|
|
239
|
+
|
|
240
|
+
{
|
|
241
|
+
hash: <Witness Public Key Hash Buffer Object>
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
@throws
|
|
245
|
+
<Error>
|
|
246
|
+
|
|
247
|
+
@returns
|
|
248
|
+
{
|
|
249
|
+
script: <Output Script Buffer Object>
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
### p2wshOutputScript
|
|
253
|
+
|
|
254
|
+
Get a Pay To Witness Script Hash Output Script
|
|
255
|
+
|
|
256
|
+
{
|
|
257
|
+
hash: <Witness Script Hash Buffer Object>
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
@throws
|
|
261
|
+
<Error>
|
|
262
|
+
|
|
263
|
+
@returns
|
|
264
|
+
{
|
|
265
|
+
script: <Output Script Buffer Object>
|
|
266
|
+
}
|
|
267
|
+
|
|
152
268
|
### previousBlockId
|
|
153
269
|
|
|
154
270
|
Given a raw block, return the previous block id
|
|
@@ -218,3 +334,19 @@ Map array of script buffer elements to a fully formed script
|
|
|
218
334
|
{
|
|
219
335
|
script: <Script Hex String>
|
|
220
336
|
}
|
|
337
|
+
|
|
338
|
+
### unsignedTxFromPsbt
|
|
339
|
+
|
|
340
|
+
Get the unsigned transaction out of a PSBT
|
|
341
|
+
|
|
342
|
+
{
|
|
343
|
+
psbt: <PSBT Hex String>
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
@throws
|
|
347
|
+
<Error>
|
|
348
|
+
|
|
349
|
+
@returns
|
|
350
|
+
{
|
|
351
|
+
transaction: <Unsigned Transaction Buffer Object>
|
|
352
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
const modifyBech32Accumulator = require('./modify_bech32_accumulator');
|
|
2
|
+
|
|
3
|
+
const codeForBech32 = 1;
|
|
4
|
+
const codeForBech32m = 0x2bc830a3;
|
|
5
|
+
const {from} = Array;
|
|
6
|
+
const separator = 0;
|
|
7
|
+
|
|
8
|
+
/** Determine the type of bech32 data being represented and verify checksum
|
|
9
|
+
|
|
10
|
+
{
|
|
11
|
+
prefix: <Lowercase Human Readable Prefix String>
|
|
12
|
+
words: [<Bech32 5-Bit Data Number>]
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
@throws
|
|
16
|
+
<Error>
|
|
17
|
+
|
|
18
|
+
@returns
|
|
19
|
+
{
|
|
20
|
+
type: <Bech32 Type String>
|
|
21
|
+
}
|
|
22
|
+
*/
|
|
23
|
+
module.exports = ({prefix, words}) => {
|
|
24
|
+
let accumulator = 1;
|
|
25
|
+
|
|
26
|
+
// Collect the high bits
|
|
27
|
+
const highBits = from(
|
|
28
|
+
{length: prefix.length},
|
|
29
|
+
(_, i) => prefix.charCodeAt(i) >> 5
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
// Collect the low bits
|
|
33
|
+
const lowBits = from(
|
|
34
|
+
{length: prefix.length},
|
|
35
|
+
(_, i) => prefix.charCodeAt(i) & 31
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
[...highBits, separator, ...lowBits, ...words].forEach(v => {
|
|
39
|
+
return accumulator = modifyBech32Accumulator(accumulator) ^ (v & 31);
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
switch (accumulator) {
|
|
43
|
+
case codeForBech32:
|
|
44
|
+
return {type: 'bech32'};
|
|
45
|
+
|
|
46
|
+
case codeForBech32m:
|
|
47
|
+
return {type: 'bech32m'};
|
|
48
|
+
|
|
49
|
+
default:
|
|
50
|
+
throw new Error('UnexpectedChecksumValueForBech32DataAndPrefix');
|
|
51
|
+
}
|
|
52
|
+
};
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
const bech32Type = require('./bech32_type');
|
|
2
|
+
|
|
3
|
+
const alphabet = 'qpzry9x8gf2tvdw0s3jn54khce6mua7l';
|
|
4
|
+
const knownPrefixes = ['bc', 'tb', 'bcrt'];
|
|
5
|
+
const lengthSeparator = 1;
|
|
6
|
+
const lengthChecksum = 6;
|
|
7
|
+
const prefixDividerCharacter = '1';
|
|
8
|
+
const maximumCharactersLength = 90;
|
|
9
|
+
const minimumCharactersLength = 8;
|
|
10
|
+
const minimumDividerPosition = 1;
|
|
11
|
+
const notFoundIndex = -1;
|
|
12
|
+
const removeChecksum = words => words.slice(0, -6);
|
|
13
|
+
const split = (str, index) => [str.slice(0, index), str.slice(index + 1)];
|
|
14
|
+
|
|
15
|
+
/** Decode a Bech32/Bech32m encoded string and validate/remove checksum
|
|
16
|
+
|
|
17
|
+
{
|
|
18
|
+
encoded: <Bech32/Bech32m Encoded String
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
@throws
|
|
22
|
+
<Error>
|
|
23
|
+
|
|
24
|
+
@returns
|
|
25
|
+
{
|
|
26
|
+
prefix: <Human Readable Part String>
|
|
27
|
+
type: <Bech32 Type String>
|
|
28
|
+
words: [<Data Words Number>]
|
|
29
|
+
}
|
|
30
|
+
*/
|
|
31
|
+
module.exports = ({encoded}) => {
|
|
32
|
+
if (typeof encoded !== 'string') {
|
|
33
|
+
throw new Error('ExpectedEncodedStringToDecodeBech32String');
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
if (encoded.length > maximumCharactersLength) {
|
|
37
|
+
throw new Error('ExpectedShorterBech32EncodedStringToDecode');
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if (encoded.length < minimumCharactersLength) {
|
|
41
|
+
throw new Error('ExpectedLongerBech32EncodedStringToDecode');
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const converted = encoded.toLowerCase();
|
|
45
|
+
|
|
46
|
+
if (encoded !== converted && encoded !== encoded.toUpperCase()) {
|
|
47
|
+
throw new Error('ExpectedSingleCasingStyleForBech32EncodedString');
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Find the last index of the prefix divider character
|
|
51
|
+
const dividerPosition = converted.lastIndexOf(prefixDividerCharacter);
|
|
52
|
+
|
|
53
|
+
if (dividerPosition < minimumDividerPosition) {
|
|
54
|
+
throw new Error('ExpectedLaterDividerPositionForBech32String');
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if (converted.length - dividerPosition < lengthSeparator + lengthChecksum) {
|
|
58
|
+
throw new Error('ExpectedChecksumDataForBech32String');
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Divide the data from the human readable prefix
|
|
62
|
+
const [prefix, data] = split(converted, dividerPosition);
|
|
63
|
+
|
|
64
|
+
// Make sure the prefix is a known one
|
|
65
|
+
if (!knownPrefixes.includes(prefix)) {
|
|
66
|
+
throw new Error('ExpectedKnownBech32AddressPrefixToDecodeBech32');
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Convert data part into bech32 words
|
|
70
|
+
const words = [...data].map(char => alphabet.indexOf(char));
|
|
71
|
+
|
|
72
|
+
if (words.includes(notFoundIndex)) {
|
|
73
|
+
throw new Error('ExpectedAllKnownCharactersForBech32EncodedString');
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const {type} = bech32Type({prefix, words});
|
|
77
|
+
|
|
78
|
+
return {prefix, type, words: removeChecksum(words)};
|
|
79
|
+
};
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
const decodeBech32 = require('./decode_bech32');
|
|
2
|
+
|
|
3
|
+
const bitsPerBech32Word = 5;
|
|
4
|
+
const bitsPerByte = 8;
|
|
5
|
+
const byteMask = 0xff;
|
|
6
|
+
const bytesArrayAsBuffer = arr => Buffer.from(arr);
|
|
7
|
+
const knownV0ProgramLengths = [20, 32];
|
|
8
|
+
const maxProgLength = 40;
|
|
9
|
+
const maximumSegwitVersion = 16;
|
|
10
|
+
const minimumProgLength = 2;
|
|
11
|
+
const typeBech32V1 = 'bech32m';
|
|
12
|
+
const typeInitialSegwit = 'bech32';
|
|
13
|
+
const versionInitialSegwit = 0;
|
|
14
|
+
|
|
15
|
+
/** Decode a bech32 address string to derive the address details
|
|
16
|
+
|
|
17
|
+
{
|
|
18
|
+
address: <Bech32 Encoded Address String>
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
@throws
|
|
22
|
+
<Error>
|
|
23
|
+
|
|
24
|
+
@returns
|
|
25
|
+
{
|
|
26
|
+
prefix: <Human Readable Prefix String>
|
|
27
|
+
program: <Output Data Buffer Object>
|
|
28
|
+
version: <Witness Version Number>
|
|
29
|
+
}
|
|
30
|
+
*/
|
|
31
|
+
module.exports = ({address}) => {
|
|
32
|
+
const {prefix, type, words} = decodeBech32({encoded: address});
|
|
33
|
+
|
|
34
|
+
if (!words.length) {
|
|
35
|
+
throw new Error('ExpectedNonEmptyWitnessCommitmentDataInBech32Address');
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const [version, ...data] = words;
|
|
39
|
+
|
|
40
|
+
if (version > maximumSegwitVersion) {
|
|
41
|
+
throw new Error('UnexpectedHighSegwitWitnessVersion');
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if (version === versionInitialSegwit && type !== typeInitialSegwit) {
|
|
45
|
+
throw new Error('ExpectedInitialSegwitTypeForInitialSegwitVersion');
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (version !== versionInitialSegwit && type !== typeBech32V1) {
|
|
49
|
+
throw new Error('ExpectedUseOfLaterVersionBech32PostInitialSegwit');
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
let bits = 0;
|
|
53
|
+
let carry = 0;
|
|
54
|
+
const program = [];
|
|
55
|
+
|
|
56
|
+
// Convert the 5 bit bech32 words into 8 bit (ie bytes) data
|
|
57
|
+
data.forEach(value => {
|
|
58
|
+
carry = (carry << bitsPerBech32Word) | value;
|
|
59
|
+
|
|
60
|
+
bits += bitsPerBech32Word;
|
|
61
|
+
|
|
62
|
+
while (bits >= bitsPerByte) {
|
|
63
|
+
bits -= bitsPerByte;
|
|
64
|
+
|
|
65
|
+
program.push((carry >> bits) & byteMask);
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
if (bits >= bitsPerBech32Word) {
|
|
70
|
+
throw new Error('ExpectedNoPaddingOnBech32Address');
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
if (((carry << (bitsPerByte - bits)) & byteMask) !== 0) {
|
|
74
|
+
throw new Error('UnexpectedNonZeroPadding');
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if (program.length < minimumProgLength || program.length > maxProgLength) {
|
|
78
|
+
throw new Error('UnexpectedSizeOfBech32AddressProgram');
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
if (version === 0 && !knownV0ProgramLengths.includes(program.length)) {
|
|
82
|
+
throw new Error('UnexpectedBech32AddressProgramSizeForV0Address')
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return {version, prefix, program: bytesArrayAsBuffer(program)};
|
|
86
|
+
};
|
package/addresses/index.js
CHANGED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
const generatedModifierValues = [[0x01, 0x3b6a57b2], [0x02, 0x26508e6d], [0x04, 0x1ea119fa], [0x08, 0x3d4233dd], [0x10, 0x2a1462b3]];
|
|
2
|
+
const lowerBitsBitMask = 0x1ffffff;
|
|
3
|
+
|
|
4
|
+
/** Update the 30 bit accumulator with Bech32 precomputed values
|
|
5
|
+
|
|
6
|
+
accumulator: <Current Accumulator 32-Bit Range Integer Number>
|
|
7
|
+
|
|
8
|
+
@returns
|
|
9
|
+
<Bech32 Generator Constants Modified Number>
|
|
10
|
+
*/
|
|
11
|
+
module.exports = accumulator => {
|
|
12
|
+
// Take the top 5 bits of the accumulator value (30 - 5 = 25)
|
|
13
|
+
const topBits = accumulator >> 25;
|
|
14
|
+
|
|
15
|
+
// Shift the lower 25 bits up by 5
|
|
16
|
+
let modified = ((accumulator & lowerBitsBitMask) << 5) >>> 0;
|
|
17
|
+
|
|
18
|
+
// Based on bit masks, apply the appropriate precomputed Bech32 values
|
|
19
|
+
generatedModifierValues
|
|
20
|
+
.filter(([mask]) => topBits & mask)
|
|
21
|
+
.forEach(([, modifier]) => modified ^= modifier);
|
|
22
|
+
|
|
23
|
+
return modified;
|
|
24
|
+
};
|
|
@@ -12,6 +12,8 @@ const sha256 = preimage => createHash('sha256').update(preimage).digest();
|
|
|
12
12
|
|
|
13
13
|
/** Determine a transaction id from transaction components
|
|
14
14
|
|
|
15
|
+
Note: remember the input hash is the reversed byte order of a normal tx id
|
|
16
|
+
|
|
15
17
|
{
|
|
16
18
|
inputs: [{
|
|
17
19
|
hash: <Spending Internal Byte Order Transaction Id Buffer Object>
|
package/index.js
CHANGED
|
@@ -1,25 +1,41 @@
|
|
|
1
1
|
const {compactIntAsNumber} = require('./numbers');
|
|
2
2
|
const {componentsOfTransaction} = require('./transactions');
|
|
3
3
|
const {decodeBase58Address} = require('./addresses');
|
|
4
|
+
const {decodeBech32Address} = require('./addresses');
|
|
4
5
|
const {idForBlock} = require('./hashes');
|
|
6
|
+
const {idForTransaction} = require('./transactions');
|
|
5
7
|
const {idForTransactionComponents} = require('./hashes');
|
|
6
8
|
const {noLocktimeIdForTransaction} = require('./transactions');
|
|
7
9
|
const {numberAsCompactInt} = require('./numbers');
|
|
10
|
+
const {p2pkhOutputScript} = require('./script');
|
|
11
|
+
const {p2shOutputScript} = require('./script');
|
|
12
|
+
const {p2trOutputScript} = require('./script');
|
|
13
|
+
const {p2wpkhOutputScript} = require('./script');
|
|
14
|
+
const {p2wshOutputScript} = require('./script');
|
|
8
15
|
const {previousBlockId} = require('./hashes');
|
|
9
16
|
const {queryTransactions} = require('./transactions');
|
|
10
17
|
const {scriptAsScriptElements} = require('./script');
|
|
11
18
|
const {scriptElementsAsScript} = require('./script');
|
|
19
|
+
const {unsignedTxFromPsbt} = require('./transactions');
|
|
12
20
|
|
|
13
21
|
module.exports = {
|
|
14
22
|
compactIntAsNumber,
|
|
15
23
|
componentsOfTransaction,
|
|
16
24
|
decodeBase58Address,
|
|
25
|
+
decodeBech32Address,
|
|
17
26
|
idForBlock,
|
|
27
|
+
idForTransaction,
|
|
18
28
|
idForTransactionComponents,
|
|
19
29
|
noLocktimeIdForTransaction,
|
|
20
30
|
numberAsCompactInt,
|
|
31
|
+
p2pkhOutputScript,
|
|
32
|
+
p2shOutputScript,
|
|
33
|
+
p2trOutputScript,
|
|
34
|
+
p2wpkhOutputScript,
|
|
35
|
+
p2wshOutputScript,
|
|
21
36
|
previousBlockId,
|
|
22
37
|
queryTransactions,
|
|
23
38
|
scriptAsScriptElements,
|
|
24
39
|
scriptElementsAsScript,
|
|
40
|
+
unsignedTxFromPsbt,
|
|
25
41
|
};
|
package/package.json
CHANGED
package/script/index.js
CHANGED
|
@@ -1,4 +1,17 @@
|
|
|
1
|
+
const p2pkhOutputScript = require('./p2pkh_output_script');
|
|
2
|
+
const p2shOutputScript = require('./p2sh_output_script');
|
|
3
|
+
const p2trOutputScript = require('./p2tr_output_script');
|
|
4
|
+
const p2wpkhOutputScript = require('./p2wpkh_output_script');
|
|
5
|
+
const p2wshOutputScript = require('./p2wsh_output_script');
|
|
1
6
|
const scriptAsScriptElements = require('./script_as_script_elements');
|
|
2
7
|
const scriptElementsAsScript = require('./script_elements_as_script');
|
|
3
8
|
|
|
4
|
-
module.exports = {
|
|
9
|
+
module.exports = {
|
|
10
|
+
p2pkhOutputScript,
|
|
11
|
+
p2shOutputScript,
|
|
12
|
+
p2trOutputScript,
|
|
13
|
+
p2wpkhOutputScript,
|
|
14
|
+
p2wshOutputScript,
|
|
15
|
+
scriptAsScriptElements,
|
|
16
|
+
scriptElementsAsScript,
|
|
17
|
+
};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
const scriptElementsAsOutput = require('./script_elements_as_output');
|
|
2
|
+
|
|
3
|
+
const expectedHashLength = 20;
|
|
4
|
+
const OP_CHECKSIG = 0xac;
|
|
5
|
+
const OP_DUP = 0x76;
|
|
6
|
+
const OP_EQUALVERIFY = 0x88;
|
|
7
|
+
const OP_HASH160 = 0xa9;
|
|
8
|
+
|
|
9
|
+
/** Get a Pay To Public Key Hash Output Script
|
|
10
|
+
|
|
11
|
+
{
|
|
12
|
+
hash: <Public Key Hash Buffer Object>
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
@throws
|
|
16
|
+
<Error>
|
|
17
|
+
|
|
18
|
+
@returns
|
|
19
|
+
{
|
|
20
|
+
script: <Output Script Buffer Object>
|
|
21
|
+
}
|
|
22
|
+
*/
|
|
23
|
+
module.exports = ({hash}) => {
|
|
24
|
+
if (!hash) {
|
|
25
|
+
throw new Error('ExpectedPublicKeyHashToDeriveOutputScript');
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
if (hash.length !== expectedHashLength) {
|
|
29
|
+
throw new Error('UnexpectedHashLengthForPublicKeyHashOutputScript');
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const {output} = scriptElementsAsOutput({
|
|
33
|
+
elements: [OP_DUP, OP_HASH160, hash, OP_EQUALVERIFY, OP_CHECKSIG],
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
return {script: output};
|
|
37
|
+
};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
const scriptElementsAsOutput = require('./script_elements_as_output');
|
|
2
|
+
|
|
3
|
+
const expectedHashLength = 20;
|
|
4
|
+
const OP_EQUAL = 0x87;
|
|
5
|
+
const OP_HASH160 = 0xa9;
|
|
6
|
+
|
|
7
|
+
/** Get a Pay To Script Hash Output Script
|
|
8
|
+
|
|
9
|
+
{
|
|
10
|
+
hash: <Script Hash Buffer Object>
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
@throws
|
|
14
|
+
<Error>
|
|
15
|
+
|
|
16
|
+
@returns
|
|
17
|
+
{
|
|
18
|
+
script: <Output Script Buffer Object>
|
|
19
|
+
}
|
|
20
|
+
*/
|
|
21
|
+
module.exports = ({hash}) => {
|
|
22
|
+
if (!hash) {
|
|
23
|
+
throw new Error('ExpectedScriptHashToDerivePayToScriptOutputScript');
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if (hash.length !== expectedHashLength) {
|
|
27
|
+
throw new Error('UnexpectedHashLengthForPayToScriptHashOutputScript');
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const {output} = scriptElementsAsOutput({
|
|
31
|
+
elements: [OP_HASH160, hash, OP_EQUAL],
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
return {script: output};
|
|
35
|
+
};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
const scriptElementsAsOutput = require('./script_elements_as_output');
|
|
2
|
+
|
|
3
|
+
const expectedHashLength = 32;
|
|
4
|
+
const OP_1 = 0x51;
|
|
5
|
+
|
|
6
|
+
/** Get a Pay To Taproot Output Script
|
|
7
|
+
|
|
8
|
+
{
|
|
9
|
+
hash: <Taproot Hash Buffer Object>
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
@throws
|
|
13
|
+
<Error>
|
|
14
|
+
|
|
15
|
+
@returns
|
|
16
|
+
{
|
|
17
|
+
script: <Output Script Buffer Object>
|
|
18
|
+
}
|
|
19
|
+
*/
|
|
20
|
+
module.exports = ({hash}) => {
|
|
21
|
+
if (!hash) {
|
|
22
|
+
throw new Error('ExpectedTaprootHashToDeriveOutputScript');
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
if (hash.length !== expectedHashLength) {
|
|
26
|
+
throw new Error('ExpectedKnownLengthTaprootHashForOutputScript');
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const {output} = scriptElementsAsOutput({elements: [OP_1, hash]});
|
|
30
|
+
|
|
31
|
+
return {script: output};
|
|
32
|
+
};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
const scriptElementsAsOutput = require('./script_elements_as_output');
|
|
2
|
+
|
|
3
|
+
const expectedHashLength = 20;
|
|
4
|
+
const OP_0 = 0x00;
|
|
5
|
+
|
|
6
|
+
/** Get a Pay To Witness Public Key Hash Output Script
|
|
7
|
+
|
|
8
|
+
{
|
|
9
|
+
hash: <Witness Public Key Hash Buffer Object>
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
@throws
|
|
13
|
+
<Error>
|
|
14
|
+
|
|
15
|
+
@returns
|
|
16
|
+
{
|
|
17
|
+
script: <Output Script Buffer Object>
|
|
18
|
+
}
|
|
19
|
+
*/
|
|
20
|
+
module.exports = ({hash}) => {
|
|
21
|
+
if (!hash) {
|
|
22
|
+
throw new Error('ExpectedWitnessPublicKeyHashToDeriveOutputScript');
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
if (hash.length !== expectedHashLength) {
|
|
26
|
+
throw new Error('ExpectedKnownLengthWitnessPublicKeyHashForOutputScript');
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const {output} = scriptElementsAsOutput({elements: [OP_0, hash]});
|
|
30
|
+
|
|
31
|
+
return {script: output};
|
|
32
|
+
};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
const scriptElementsAsOutput = require('./script_elements_as_output');
|
|
2
|
+
|
|
3
|
+
const expectedHashLength = 32;
|
|
4
|
+
const OP_0 = 0x00;
|
|
5
|
+
|
|
6
|
+
/** Get a Pay To Witness Script Hash Output Script
|
|
7
|
+
|
|
8
|
+
{
|
|
9
|
+
hash: <Witness Script Hash Buffer Object>
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
@throws
|
|
13
|
+
<Error>
|
|
14
|
+
|
|
15
|
+
@returns
|
|
16
|
+
{
|
|
17
|
+
script: <Output Script Buffer Object>
|
|
18
|
+
}
|
|
19
|
+
*/
|
|
20
|
+
module.exports = ({hash}) => {
|
|
21
|
+
if (!hash) {
|
|
22
|
+
throw new Error('ExpectedWitnessScriptHashToDeriveOutputScript');
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
if (hash.length !== expectedHashLength) {
|
|
26
|
+
throw new Error('ExpectedKnownLengthWitnessScriptHashForOutputScript');
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const {output} = scriptElementsAsOutput({elements: [OP_0, hash]});
|
|
30
|
+
|
|
31
|
+
return {script: output};
|
|
32
|
+
};
|